rlm@1: case 0x00: rlm@1: // NOP rlm@1: break; rlm@1: case 0x01: rlm@1: // LD BC, NNNN rlm@1: BC.B.B0=gbReadMemory(PC.W++); rlm@1: BC.B.B1=gbReadMemory(PC.W++); rlm@1: break; rlm@1: case 0x02: rlm@1: // LD (BC),A rlm@1: gbWriteMemory(BC.W,AF.B.B1); rlm@1: break; rlm@1: case 0x03: rlm@1: // INC BC rlm@1: BC.W++; rlm@1: break; rlm@1: case 0x04: rlm@1: // INC B rlm@1: BC.B.B1++; rlm@1: AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[BC.B.B1]| (BC.B.B1&0x0F? 0:H_FLAG); rlm@1: break; rlm@1: case 0x05: rlm@1: // DEC B rlm@1: BC.B.B1--; rlm@1: AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[BC.B.B1]| rlm@1: ((BC.B.B1&0x0F)==0x0F? H_FLAG:0); rlm@1: break; rlm@1: case 0x06: rlm@1: // LD B, NN rlm@1: BC.B.B1=gbReadOpcode(PC.W++); rlm@1: break; rlm@1: case 0x07: rlm@1: // RLCA rlm@1: tempValue=AF.B.B1&0x80? C_FLAG:0; rlm@1: AF.B.B1=((AF.B.B1<<1)|(AF.B.B1>>7)) & 0xFF; rlm@1: AF.B.B0=tempValue; rlm@1: break; rlm@1: case 0x08: rlm@1: // LD (NNNN), SP rlm@1: tempRegister.B.B0=gbReadOpcode(PC.W++); rlm@1: tempRegister.B.B1=gbReadOpcode(PC.W++); rlm@1: gbWriteMemory(tempRegister.W++,SP.B.B0); rlm@1: gbWriteMemory(tempRegister.W,SP.B.B1); rlm@1: break; rlm@1: case 0x09: rlm@1: // ADD HL,BC rlm@1: tempRegister.W=(HL.W+BC.W)&0xFFFF; rlm@1: AF.B.B0= (AF.B.B0 & Z_FLAG)| ((HL.W^BC.W^tempRegister.W)&0x1000? H_FLAG:0)| rlm@1: (((long)HL.W+(long)BC.W)&0x10000? C_FLAG:0); rlm@1: HL.W=tempRegister.W; rlm@1: break; rlm@1: case 0x0a: rlm@1: // LD A,(BC) rlm@1: AF.B.B1=gbReadMemory(BC.W); rlm@1: break; rlm@1: case 0x0b: rlm@1: // DEC BC rlm@1: BC.W--; rlm@1: break; rlm@1: case 0x0c: rlm@1: // INC C rlm@1: BC.B.B0++; rlm@1: AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[BC.B.B0]| (BC.B.B0&0x0F? 0:H_FLAG); rlm@1: break; rlm@1: case 0x0d: rlm@1: // DEC C rlm@1: BC.B.B0--; rlm@1: AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[BC.B.B0]| rlm@1: ((BC.B.B0&0x0F)==0x0F? H_FLAG:0); rlm@1: break; rlm@1: case 0x0e: rlm@1: // LD C, NN rlm@1: BC.B.B0=gbReadOpcode(PC.W++); rlm@1: break; rlm@1: case 0x0f: rlm@1: // RRCA rlm@1: tempValue=AF.B.B1&0x01; rlm@1: AF.B.B1=(AF.B.B1>>1)|(tempValue? 0x80:0); rlm@1: AF.B.B0=(tempValue<<4); rlm@1: break; rlm@1: case 0x10: rlm@1: // STOP rlm@1: opcode = gbReadOpcode(PC.W++); rlm@1: if(gbCgbMode) { rlm@1: if(gbReadMemoryQuick(0xff4d) & 1) { rlm@1: gbSpeedSwitch(); rlm@1: rlm@1: if(gbSpeed == 0) rlm@1: gbWriteMemoryQuick(0xff4d, 0x00); rlm@1: else rlm@1: gbWriteMemoryQuick(0xff4d, 0x80); rlm@1: } rlm@1: } rlm@1: break; rlm@1: case 0x11: rlm@1: // LD DE, NNNN rlm@1: DE.B.B0=gbReadMemory(PC.W++); rlm@1: DE.B.B1=gbReadMemory(PC.W++); rlm@1: break; rlm@1: case 0x12: rlm@1: // LD (DE),A rlm@1: gbWriteMemory(DE.W,AF.B.B1); rlm@1: break; rlm@1: case 0x13: rlm@1: // INC DE rlm@1: DE.W++; rlm@1: break; rlm@1: case 0x14: rlm@1: // INC D rlm@1: DE.B.B1++; rlm@1: AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[DE.B.B1]| (DE.B.B1&0x0F? 0:H_FLAG); rlm@1: break; rlm@1: case 0x15: rlm@1: // DEC D rlm@1: DE.B.B1--; rlm@1: AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[DE.B.B1]| rlm@1: ((DE.B.B1&0x0F)==0x0F? H_FLAG:0); rlm@1: break; rlm@1: case 0x16: rlm@1: // LD D,NN rlm@1: DE.B.B1=gbReadOpcode(PC.W++); rlm@1: break; rlm@1: case 0x17: rlm@1: // RLA rlm@1: tempValue=AF.B.B1&0x80? C_FLAG:0; rlm@1: AF.B.B1=((AF.B.B1<<1)|((AF.B.B0&C_FLAG)>>4)) & 0xFF; rlm@1: AF.B.B0=tempValue; rlm@1: break; rlm@1: case 0x18: rlm@1: // JR NN rlm@1: PC.W+=(s8)gbReadMemory(PC.W)+1; rlm@1: break; rlm@1: case 0x19: rlm@1: // ADD HL,DE rlm@1: tempRegister.W=(HL.W+DE.W)&0xFFFF; rlm@1: AF.B.B0= (AF.B.B0 & Z_FLAG)| ((HL.W^DE.W^tempRegister.W)&0x1000? H_FLAG:0)| rlm@1: (((long)HL.W+(long)DE.W)&0x10000? C_FLAG:0); rlm@1: HL.W=tempRegister.W; rlm@1: break; rlm@1: case 0x1a: rlm@1: // LD A,(DE) rlm@1: AF.B.B1=gbReadMemory(DE.W); rlm@1: break; rlm@1: case 0x1b: rlm@1: // DEC DE rlm@1: DE.W--; rlm@1: break; rlm@1: case 0x1c: rlm@1: // INC E rlm@1: DE.B.B0++; rlm@1: AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[DE.B.B0]| (DE.B.B0&0x0F? 0:H_FLAG); rlm@1: break; rlm@1: case 0x1d: rlm@1: // DEC E rlm@1: DE.B.B0--; rlm@1: AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[DE.B.B0]| rlm@1: ((DE.B.B0&0x0F)==0x0F? H_FLAG:0); rlm@1: break; rlm@1: case 0x1e: rlm@1: // LD E,NN rlm@1: DE.B.B0=gbReadOpcode(PC.W++); rlm@1: break; rlm@1: case 0x1f: rlm@1: // RRA rlm@1: tempValue=AF.B.B1&0x01; rlm@1: AF.B.B1=(AF.B.B1>>1)|(AF.B.B0&C_FLAG? 0x80:0); rlm@1: AF.B.B0=(tempValue<<4); rlm@1: break; rlm@1: case 0x20: rlm@1: // JR NZ,NN rlm@1: if(AF.B.B0&Z_FLAG) rlm@1: PC.W++; rlm@1: else { rlm@1: PC.W+=(s8)gbReadMemory(PC.W)+1; rlm@1: clockTicks++; rlm@1: } rlm@1: break; rlm@1: case 0x21: rlm@1: // LD HL,NNNN rlm@1: HL.B.B0=gbReadMemory(PC.W++); rlm@1: HL.B.B1=gbReadMemory(PC.W++); rlm@1: break; rlm@1: case 0x22: rlm@1: // LDI (HL),A rlm@1: gbWriteMemory(HL.W++,AF.B.B1); rlm@1: break; rlm@1: case 0x23: rlm@1: // INC HL rlm@1: HL.W++; rlm@1: break; rlm@1: case 0x24: rlm@1: // INC H rlm@1: HL.B.B1++; rlm@1: AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[HL.B.B1]| (HL.B.B1&0x0F? 0:H_FLAG); rlm@1: break; rlm@1: case 0x25: rlm@1: // DEC H rlm@1: HL.B.B1--; rlm@1: AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[HL.B.B1]| rlm@1: ((HL.B.B1&0x0F)==0x0F? H_FLAG:0); rlm@1: break; rlm@1: case 0x26: rlm@1: // LD H,NN rlm@1: HL.B.B1=gbReadOpcode(PC.W++); rlm@1: break; rlm@1: case 0x27: rlm@1: // DAA rlm@1: tempRegister.W=AF.B.B1; rlm@1: if(AF.B.B0&C_FLAG) tempRegister.W|=256; rlm@1: if(AF.B.B0&H_FLAG) tempRegister.W|=512; rlm@1: if(AF.B.B0&N_FLAG) tempRegister.W|=1024; rlm@1: AF.W=DAATable[tempRegister.W]; rlm@1: break; rlm@1: case 0x28: rlm@1: // JR Z,NN rlm@1: if(AF.B.B0&Z_FLAG) { rlm@1: PC.W+=(s8)gbReadMemory(PC.W)+1; rlm@1: clockTicks++; rlm@1: } else rlm@1: PC.W++; rlm@1: break; rlm@1: case 0x29: rlm@1: // ADD HL,HL rlm@1: tempRegister.W=(HL.W+HL.W)&0xFFFF; AF.B.B0= (AF.B.B0 & Z_FLAG)| rlm@1: ((HL.W^HL.W^tempRegister.W)&0x1000? H_FLAG:0)| rlm@1: (((long)HL.W+(long)HL.W)&0x10000? C_FLAG:0); rlm@1: HL.W=tempRegister.W; rlm@1: break; rlm@1: case 0x2a: rlm@1: // LDI A,(HL) rlm@1: AF.B.B1 = gbReadMemory(HL.W++); rlm@1: break; rlm@1: case 0x2b: rlm@1: // DEC HL rlm@1: HL.W--; rlm@1: break; rlm@1: case 0x2c: rlm@1: // INC L rlm@1: HL.B.B0++; rlm@1: AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[HL.B.B0]| (HL.B.B0&0x0F? 0:H_FLAG); rlm@1: break; rlm@1: case 0x2d: rlm@1: // DEC L rlm@1: HL.B.B0--; rlm@1: AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[HL.B.B0]| rlm@1: ((HL.B.B0&0x0F)==0x0F? H_FLAG:0); rlm@1: break; rlm@1: case 0x2e: rlm@1: // LD L,NN rlm@1: HL.B.B0=gbReadOpcode(PC.W++); rlm@1: break; rlm@1: case 0x2f: rlm@1: // CPL rlm@1: AF.B.B1 ^= 255; rlm@1: AF.B.B0|=N_FLAG|H_FLAG; rlm@1: break; rlm@1: case 0x30: rlm@1: // JR NC,NN rlm@1: if(AF.B.B0&C_FLAG) rlm@1: PC.W++; rlm@1: else { rlm@1: PC.W+=(s8)gbReadMemory(PC.W)+1; rlm@1: clockTicks++; rlm@1: } rlm@1: break; rlm@1: case 0x31: rlm@1: // LD SP,NNNN rlm@1: SP.B.B0=gbReadMemory(PC.W++); rlm@1: SP.B.B1=gbReadMemory(PC.W++); rlm@1: break; rlm@1: case 0x32: rlm@1: // LDD (HL),A rlm@1: gbWriteMemory(HL.W--,AF.B.B1); rlm@1: break; rlm@1: case 0x33: rlm@1: // INC SP rlm@1: SP.W++; rlm@1: break; rlm@1: case 0x34: rlm@1: // INC (HL) rlm@1: tempValue=(gbReadMemory(HL.W)+1) & 0xFF; rlm@1: AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[tempValue]| (tempValue&0x0F? 0:H_FLAG); rlm@1: gbWriteMemory(HL.W,tempValue); rlm@1: break; rlm@1: case 0x35: rlm@1: // DEC (HL) rlm@1: tempValue=(gbReadMemory(HL.W)-1) & 0xFF; rlm@1: AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[tempValue]| rlm@1: ((tempValue&0x0F)==0x0F? H_FLAG:0);gbWriteMemory(HL.W,tempValue); rlm@1: break; rlm@1: case 0x36: rlm@1: // LD (HL),NN rlm@1: gbWriteMemory(HL.W,gbReadOpcode(PC.W++)); rlm@1: break; rlm@1: case 0x37: rlm@1: // SCF rlm@1: AF.B.B0 = AF.B.B0 & Z_FLAG | C_FLAG; rlm@1: break; rlm@1: case 0x38: rlm@1: // JR C,NN rlm@1: if(AF.B.B0&C_FLAG) { rlm@1: PC.W+=(s8)gbReadMemory(PC.W)+1; rlm@1: clockTicks ++; rlm@1: } else rlm@1: PC.W++; rlm@1: break; rlm@1: case 0x39: rlm@1: // ADD HL,SP rlm@1: tempRegister.W=(HL.W+SP.W)&0xFFFF; rlm@1: AF.B.B0= (AF.B.B0 & Z_FLAG)| ((HL.W^SP.W^tempRegister.W)&0x1000? H_FLAG:0)| rlm@1: (((long)HL.W+(long)SP.W)&0x10000? C_FLAG:0); rlm@1: HL.W=tempRegister.W; rlm@1: break; rlm@1: case 0x3a: rlm@1: // LDD A,(HL) rlm@1: AF.B.B1 = gbReadMemory(HL.W--); rlm@1: break; rlm@1: case 0x3b: rlm@1: // DEC SP rlm@1: SP.W--; rlm@1: break; rlm@1: case 0x3c: rlm@1: // INC A rlm@1: AF.B.B1++; rlm@1: AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[AF.B.B1]| (AF.B.B1&0x0F? 0:H_FLAG); rlm@1: break; rlm@1: case 0x3d: rlm@1: // DEC A rlm@1: AF.B.B1--; rlm@1: AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[AF.B.B1]| rlm@1: ((AF.B.B1&0x0F)==0x0F? H_FLAG:0); rlm@1: break; rlm@1: case 0x3e: rlm@1: // LD A,NN rlm@1: AF.B.B1=gbReadOpcode(PC.W++); rlm@1: break; rlm@1: case 0x3f: rlm@1: // CCF rlm@1: AF.B.B0^=C_FLAG;AF.B.B0&=~(N_FLAG|H_FLAG); rlm@1: break; rlm@1: case 0x40: rlm@1: // LD B,B rlm@1: BC.B.B1=BC.B.B1; rlm@1: break; rlm@1: case 0x41: rlm@1: // LD B,C rlm@1: BC.B.B1=BC.B.B0; rlm@1: break; rlm@1: case 0x42: rlm@1: // LD B,D rlm@1: BC.B.B1=DE.B.B1; rlm@1: break; rlm@1: case 0x43: rlm@1: // LD B,E rlm@1: BC.B.B1=DE.B.B0; rlm@1: break; rlm@1: case 0x44: rlm@1: // LD B,H rlm@1: BC.B.B1=HL.B.B1; rlm@1: break; rlm@1: case 0x45: rlm@1: // LD B,L rlm@1: BC.B.B1=HL.B.B0; rlm@1: break; rlm@1: case 0x46: rlm@1: // LD B,(HL) rlm@1: BC.B.B1=gbReadMemory(HL.W); rlm@1: break; rlm@1: case 0x47: rlm@1: // LD B,A rlm@1: BC.B.B1=AF.B.B1; rlm@1: break; rlm@1: case 0x48: rlm@1: // LD C,B rlm@1: BC.B.B0=BC.B.B1; rlm@1: break; rlm@1: case 0x49: rlm@1: // LD C,C rlm@1: BC.B.B0=BC.B.B0; rlm@1: break; rlm@1: case 0x4a: rlm@1: // LD C,D rlm@1: BC.B.B0=DE.B.B1; rlm@1: break; rlm@1: case 0x4b: rlm@1: // LD C,E rlm@1: BC.B.B0=DE.B.B0; rlm@1: break; rlm@1: case 0x4c: rlm@1: // LD C,H rlm@1: BC.B.B0=HL.B.B1; rlm@1: break; rlm@1: case 0x4d: rlm@1: // LD C,L rlm@1: BC.B.B0=HL.B.B0; rlm@1: break; rlm@1: case 0x4e: rlm@1: // LD C,(HL) rlm@1: BC.B.B0=gbReadMemory(HL.W); rlm@1: break; rlm@1: case 0x4f: rlm@1: // LD C,A rlm@1: BC.B.B0=AF.B.B1; rlm@1: break; rlm@1: case 0x50: rlm@1: // LD D,B rlm@1: DE.B.B1=BC.B.B1; rlm@1: break; rlm@1: case 0x51: rlm@1: // LD D,C rlm@1: DE.B.B1=BC.B.B0; rlm@1: break; rlm@1: case 0x52: rlm@1: // LD D,D rlm@1: DE.B.B1=DE.B.B1; rlm@1: break; rlm@1: case 0x53: rlm@1: // LD D,E rlm@1: DE.B.B1=DE.B.B0; rlm@1: break; rlm@1: case 0x54: rlm@1: // LD D,H rlm@1: DE.B.B1=HL.B.B1; rlm@1: break; rlm@1: case 0x55: rlm@1: // LD D,L rlm@1: DE.B.B1=HL.B.B0; rlm@1: break; rlm@1: case 0x56: rlm@1: // LD D,(HL) rlm@1: DE.B.B1=gbReadMemory(HL.W); rlm@1: break; rlm@1: case 0x57: rlm@1: // LD D,A rlm@1: DE.B.B1=AF.B.B1; rlm@1: break; rlm@1: case 0x58: rlm@1: // LD E,B rlm@1: DE.B.B0=BC.B.B1; rlm@1: break; rlm@1: case 0x59: rlm@1: // LD E,C rlm@1: DE.B.B0=BC.B.B0; rlm@1: break; rlm@1: case 0x5a: rlm@1: // LD E,D rlm@1: DE.B.B0=DE.B.B1; rlm@1: break; rlm@1: case 0x5b: rlm@1: // LD E,E rlm@1: DE.B.B0=DE.B.B0; rlm@1: break; rlm@1: case 0x5c: rlm@1: // LD E,H rlm@1: DE.B.B0=HL.B.B1; rlm@1: break; rlm@1: case 0x5d: rlm@1: // LD E,L rlm@1: DE.B.B0=HL.B.B0; rlm@1: break; rlm@1: case 0x5e: rlm@1: // LD E,(HL) rlm@1: DE.B.B0=gbReadMemory(HL.W); rlm@1: break; rlm@1: case 0x5f: rlm@1: // LD E,A rlm@1: DE.B.B0=AF.B.B1; rlm@1: break; rlm@1: case 0x60: rlm@1: // LD H,B rlm@1: HL.B.B1=BC.B.B1; rlm@1: break; rlm@1: case 0x61: rlm@1: // LD H,C rlm@1: HL.B.B1=BC.B.B0; rlm@1: break; rlm@1: case 0x62: rlm@1: // LD H,D rlm@1: HL.B.B1=DE.B.B1; rlm@1: break; rlm@1: case 0x63: rlm@1: // LD H,E rlm@1: HL.B.B1=DE.B.B0; rlm@1: break; rlm@1: case 0x64: rlm@1: // LD H,H rlm@1: HL.B.B1=HL.B.B1; rlm@1: break; rlm@1: case 0x65: rlm@1: // LD H,L rlm@1: HL.B.B1=HL.B.B0; rlm@1: break; rlm@1: case 0x66: rlm@1: // LD H,(HL) rlm@1: HL.B.B1=gbReadMemory(HL.W); rlm@1: break; rlm@1: case 0x67: rlm@1: // LD H,A rlm@1: HL.B.B1=AF.B.B1; rlm@1: break; rlm@1: case 0x68: rlm@1: // LD L,B rlm@1: HL.B.B0=BC.B.B1; rlm@1: break; rlm@1: case 0x69: rlm@1: // LD L,C rlm@1: HL.B.B0=BC.B.B0; rlm@1: break; rlm@1: case 0x6a: rlm@1: // LD L,D rlm@1: HL.B.B0=DE.B.B1; rlm@1: break; rlm@1: case 0x6b: rlm@1: // LD L,E rlm@1: HL.B.B0=DE.B.B0; rlm@1: break; rlm@1: case 0x6c: rlm@1: // LD L,H rlm@1: HL.B.B0=HL.B.B1; rlm@1: break; rlm@1: case 0x6d: rlm@1: // LD L,L rlm@1: HL.B.B0=HL.B.B0; rlm@1: break; rlm@1: case 0x6e: rlm@1: // LD L,(HL) rlm@1: HL.B.B0=gbReadMemory(HL.W); rlm@1: break; rlm@1: case 0x6f: rlm@1: // LD L,A rlm@1: HL.B.B0=AF.B.B1; rlm@1: break; rlm@1: case 0x70: rlm@1: // LD (HL),B rlm@1: gbWriteMemory(HL.W,BC.B.B1); rlm@1: break; rlm@1: case 0x71: rlm@1: // LD (HL),C rlm@1: gbWriteMemory(HL.W,BC.B.B0); rlm@1: break; rlm@1: case 0x72: rlm@1: // LD (HL),D rlm@1: gbWriteMemory(HL.W,DE.B.B1); rlm@1: break; rlm@1: case 0x73: rlm@1: // LD (HL),E rlm@1: gbWriteMemory(HL.W,DE.B.B0); rlm@1: break; rlm@1: case 0x74: rlm@1: // LD (HL),H rlm@1: gbWriteMemory(HL.W,HL.B.B1); rlm@1: break; rlm@1: case 0x75: rlm@1: // LD (HL),L rlm@1: gbWriteMemory(HL.W,HL.B.B0); rlm@1: break; rlm@1: case 0x76: rlm@1: // HALT rlm@1: if(IFF & 1) { rlm@1: PC.W--; rlm@1: IFF |= 0x80; rlm@1: } else { rlm@1: if((register_IE & register_IF) > 0) rlm@1: IFF |= 0x100; rlm@1: else { rlm@1: PC.W--; rlm@1: IFF |= 0x81; rlm@1: } rlm@1: } rlm@1: break; rlm@1: case 0x77: rlm@1: // LD (HL),A rlm@1: gbWriteMemory(HL.W,AF.B.B1); rlm@1: break; rlm@1: case 0x78: rlm@1: // LD A,B rlm@1: AF.B.B1=BC.B.B1; rlm@1: break; rlm@1: case 0x79: rlm@1: // LD A,C rlm@1: AF.B.B1=BC.B.B0; rlm@1: break; rlm@1: case 0x7a: rlm@1: // LD A,D rlm@1: AF.B.B1=DE.B.B1; rlm@1: break; rlm@1: case 0x7b: rlm@1: // LD A,E rlm@1: AF.B.B1=DE.B.B0; rlm@1: break; rlm@1: case 0x7c: rlm@1: // LD A,H rlm@1: AF.B.B1=HL.B.B1; rlm@1: break; rlm@1: case 0x7d: rlm@1: // LD A,L rlm@1: AF.B.B1=HL.B.B0; rlm@1: break; rlm@1: case 0x7e: rlm@1: // LD A,(HL) rlm@1: AF.B.B1=gbReadMemory(HL.W); rlm@1: break; rlm@1: case 0x7f: rlm@1: // LD A,A rlm@1: AF.B.B1=AF.B.B1; rlm@1: break; rlm@1: case 0x80: rlm@1: // ADD B rlm@1: tempRegister.W=AF.B.B1+BC.B.B1; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x81: rlm@1: // ADD C rlm@1: tempRegister.W=AF.B.B1+BC.B.B0; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x82: rlm@1: // ADD D rlm@1: tempRegister.W=AF.B.B1+DE.B.B1; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x83: rlm@1: // ADD E rlm@1: tempRegister.W=AF.B.B1+DE.B.B0; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x84: rlm@1: // ADD H rlm@1: tempRegister.W=AF.B.B1+HL.B.B1; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x85: rlm@1: // ADD L rlm@1: tempRegister.W=AF.B.B1+HL.B.B0; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x86: rlm@1: // ADD (HL) rlm@1: tempValue=gbReadMemory(HL.W); rlm@1: tempRegister.W=AF.B.B1+tempValue; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x87: rlm@1: // ADD A rlm@1: tempRegister.W=AF.B.B1+AF.B.B1; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^AF.B.B1^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x88: rlm@1: // ADC B: rlm@1: tempRegister.W=AF.B.B1+BC.B.B1+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x89: rlm@1: // ADC C rlm@1: tempRegister.W=AF.B.B1+BC.B.B0+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x8a: rlm@1: // ADC D rlm@1: tempRegister.W=AF.B.B1+DE.B.B1+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x8b: rlm@1: // ADC E rlm@1: tempRegister.W=AF.B.B1+DE.B.B0+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x8c: rlm@1: // ADC H rlm@1: tempRegister.W=AF.B.B1+HL.B.B1+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x8d: rlm@1: // ADC L rlm@1: tempRegister.W=AF.B.B1+HL.B.B0+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x8e: rlm@1: // ADC (HL) rlm@1: tempValue=gbReadMemory(HL.W); rlm@1: tempRegister.W=AF.B.B1+tempValue+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x8f: rlm@1: // ADC A rlm@1: tempRegister.W=AF.B.B1+AF.B.B1+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^AF.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x90: rlm@1: // SUB B rlm@1: tempRegister.W=AF.B.B1-BC.B.B1; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x91: rlm@1: // SUB C rlm@1: tempRegister.W=AF.B.B1-BC.B.B0; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x92: rlm@1: // SUB D rlm@1: tempRegister.W=AF.B.B1-DE.B.B1; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x93: rlm@1: // SUB E rlm@1: tempRegister.W=AF.B.B1-DE.B.B0; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x94: rlm@1: // SUB H rlm@1: tempRegister.W=AF.B.B1-HL.B.B1; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x95: rlm@1: // SUB L rlm@1: tempRegister.W=AF.B.B1-HL.B.B0; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x96: rlm@1: // SUB (HL) rlm@1: tempValue=gbReadMemory(HL.W); rlm@1: tempRegister.W=AF.B.B1-tempValue; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x97: rlm@1: // SUB A rlm@1: AF.B.B1=0; rlm@1: AF.B.B0=N_FLAG|Z_FLAG; rlm@1: break; rlm@1: case 0x98: rlm@1: // SBC B rlm@1: tempRegister.W=AF.B.B1-BC.B.B1-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x99: rlm@1: // SBC C rlm@1: tempRegister.W=AF.B.B1-BC.B.B0-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x9a: rlm@1: // SBC D rlm@1: tempRegister.W=AF.B.B1-DE.B.B1-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x9b: rlm@1: // SBC E rlm@1: tempRegister.W=AF.B.B1-DE.B.B0-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x9c: rlm@1: // SBC H rlm@1: tempRegister.W=AF.B.B1-HL.B.B1-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x9d: rlm@1: // SBC L rlm@1: tempRegister.W=AF.B.B1-HL.B.B0-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x9e: rlm@1: // SBC (HL) rlm@1: tempValue=gbReadMemory(HL.W); rlm@1: tempRegister.W=AF.B.B1-tempValue-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0x9f: rlm@1: // SBC A rlm@1: tempRegister.W=AF.B.B1-AF.B.B1-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^AF.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0xa0: rlm@1: // AND B rlm@1: AF.B.B1&=BC.B.B1; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa1: rlm@1: // AND C rlm@1: AF.B.B1&=BC.B.B0; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa2: rlm@1: // AND_D rlm@1: AF.B.B1&=DE.B.B1; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa3: rlm@1: // AND E rlm@1: AF.B.B1&=DE.B.B0; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa4: rlm@1: // AND H rlm@1: AF.B.B1&=HL.B.B1; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa5: rlm@1: // AND L rlm@1: AF.B.B1&=HL.B.B0; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa6: rlm@1: // AND (HL) rlm@1: tempValue=gbReadMemory(HL.W); rlm@1: AF.B.B1&=tempValue; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa7: rlm@1: // AND A rlm@1: AF.B.B1&=AF.B.B1; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa8: rlm@1: // XOR B rlm@1: AF.B.B1^=BC.B.B1; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xa9: rlm@1: // XOR C rlm@1: AF.B.B1^=BC.B.B0; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xaa: rlm@1: // XOR D rlm@1: AF.B.B1^=DE.B.B1; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xab: rlm@1: // XOR E rlm@1: AF.B.B1^=DE.B.B0; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xac: rlm@1: // XOR H rlm@1: AF.B.B1^=HL.B.B1; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xad: rlm@1: // XOR L rlm@1: AF.B.B1^=HL.B.B0; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xae: rlm@1: // XOR (HL) rlm@1: tempValue=gbReadMemory(HL.W); rlm@1: AF.B.B1^=tempValue; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xaf: rlm@1: // XOR A rlm@1: AF.B.B1=0; rlm@1: AF.B.B0=Z_FLAG; rlm@1: break; rlm@1: case 0xb0: rlm@1: // OR B rlm@1: AF.B.B1|=BC.B.B1; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xb1: rlm@1: // OR C rlm@1: AF.B.B1|=BC.B.B0; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xb2: rlm@1: // OR D rlm@1: AF.B.B1|=DE.B.B1; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xb3: rlm@1: // OR E rlm@1: AF.B.B1|=DE.B.B0; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xb4: rlm@1: // OR H rlm@1: AF.B.B1|=HL.B.B1; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xb5: rlm@1: // OR L rlm@1: AF.B.B1|=HL.B.B0; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xb6: rlm@1: // OR (HL) rlm@1: tempValue=gbReadMemory(HL.W); rlm@1: AF.B.B1|=tempValue; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xb7: rlm@1: // OR A rlm@1: AF.B.B1|=AF.B.B1; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xb8: rlm@1: // CP B: rlm@1: tempRegister.W=AF.B.B1-BC.B.B1; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: break; rlm@1: case 0xb9: rlm@1: // CP C rlm@1: tempRegister.W=AF.B.B1-BC.B.B0; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: break; rlm@1: case 0xba: rlm@1: // CP D rlm@1: tempRegister.W=AF.B.B1-DE.B.B1; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: break; rlm@1: case 0xbb: rlm@1: // CP E rlm@1: tempRegister.W=AF.B.B1-DE.B.B0; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: break; rlm@1: case 0xbc: rlm@1: // CP H rlm@1: tempRegister.W=AF.B.B1-HL.B.B1; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: break; rlm@1: case 0xbd: rlm@1: // CP L rlm@1: tempRegister.W=AF.B.B1-HL.B.B0; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: break; rlm@1: case 0xbe: rlm@1: // CP (HL) rlm@1: tempValue=gbReadMemory(HL.W); rlm@1: tempRegister.W=AF.B.B1-tempValue; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: break; rlm@1: case 0xbf: rlm@1: // CP A rlm@1: AF.B.B0=N_FLAG|Z_FLAG; rlm@1: break; rlm@1: case 0xc0: rlm@1: // RET NZ rlm@1: if(!(AF.B.B0&Z_FLAG)) { rlm@1: PC.B.B0=gbReadMemory(SP.W++); rlm@1: PC.B.B1=gbReadMemory(SP.W++); rlm@1: clockTicks += 3; rlm@1: } rlm@1: break; rlm@1: case 0xc1: rlm@1: // POP BC rlm@1: BC.B.B0=gbReadMemory(SP.W++); rlm@1: BC.B.B1=gbReadMemory(SP.W++); rlm@1: break; rlm@1: case 0xc2: rlm@1: // JP NZ,NNNN rlm@1: if(AF.B.B0&Z_FLAG) rlm@1: PC.W+=2; rlm@1: else { rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W); rlm@1: PC.W=tempRegister.W; rlm@1: clockTicks++; rlm@1: } rlm@1: break; rlm@1: case 0xc3: rlm@1: // JP NNNN rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W); rlm@1: PC.W=tempRegister.W; rlm@1: break; rlm@1: case 0xc4: rlm@1: // CALL NZ,NNNN rlm@1: if(AF.B.B0&Z_FLAG) rlm@1: PC.W+=2; rlm@1: else { rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W++); rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=tempRegister.W; rlm@1: clockTicks += 3; rlm@1: } rlm@1: break; rlm@1: case 0xc5: rlm@1: // PUSH BC rlm@1: gbWriteMemory(--SP.W,BC.B.B1); rlm@1: gbWriteMemory(--SP.W,BC.B.B0); rlm@1: break; rlm@1: case 0xc6: rlm@1: // ADD NN rlm@1: tempValue=gbReadOpcode(PC.W++); rlm@1: tempRegister.W=AF.B.B1+tempValue; rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10 ? H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0xc7: rlm@1: // RST 00 rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=0x0000; rlm@1: break; rlm@1: case 0xc8: rlm@1: // RET Z rlm@1: if(AF.B.B0&Z_FLAG) { rlm@1: PC.B.B0=gbReadMemory(SP.W++); rlm@1: PC.B.B1=gbReadMemory(SP.W++); rlm@1: clockTicks += 3; rlm@1: } rlm@1: break; rlm@1: case 0xc9: rlm@1: // RET rlm@1: PC.B.B0=gbReadMemory(SP.W++); rlm@1: PC.B.B1=gbReadMemory(SP.W++); rlm@1: break; rlm@1: case 0xca: rlm@1: // JP Z,NNNN rlm@1: if(AF.B.B0&Z_FLAG) { rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W); rlm@1: PC.W=tempRegister.W; rlm@1: clockTicks++; rlm@1: } else rlm@1: PC.W+=2; rlm@1: break; rlm@1: // CB done outside rlm@1: case 0xcc: rlm@1: // CALL Z,NNNN rlm@1: if(AF.B.B0&Z_FLAG) { rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W++); rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=tempRegister.W; rlm@1: clockTicks += 3; rlm@1: } else rlm@1: PC.W+=2; rlm@1: break; rlm@1: case 0xcd: rlm@1: // CALL NNNN rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W++); rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=tempRegister.W; rlm@1: break; rlm@1: case 0xce: rlm@1: // ADC NN rlm@1: tempValue=gbReadOpcode(PC.W++); rlm@1: tempRegister.W=AF.B.B1+tempValue+(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0xcf: rlm@1: // RST 08 rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=0x0008; rlm@1: break; rlm@1: case 0xd0: rlm@1: // RET NC rlm@1: if(!(AF.B.B0&C_FLAG)) { rlm@1: PC.B.B0=gbReadMemory(SP.W++); rlm@1: PC.B.B1=gbReadMemory(SP.W++); rlm@1: clockTicks += 3; rlm@1: } rlm@1: break; rlm@1: case 0xd1: rlm@1: // POP DE rlm@1: DE.B.B0=gbReadMemory(SP.W++); rlm@1: DE.B.B1=gbReadMemory(SP.W++); rlm@1: break; rlm@1: case 0xd2: rlm@1: // JP NC,NNNN rlm@1: if(AF.B.B0&C_FLAG) rlm@1: PC.W+=2; rlm@1: else { rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W); rlm@1: PC.W=tempRegister.W; rlm@1: clockTicks++; rlm@1: } rlm@1: break; rlm@1: // D3 illegal rlm@1: case 0xd4: rlm@1: // CALL NC,NNNN rlm@1: if(AF.B.B0&C_FLAG) rlm@1: PC.W+=2; rlm@1: else { rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W++); rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=tempRegister.W; rlm@1: clockTicks += 3; rlm@1: } rlm@1: break; rlm@1: case 0xd5: rlm@1: // PUSH DE rlm@1: gbWriteMemory(--SP.W,DE.B.B1); rlm@1: gbWriteMemory(--SP.W,DE.B.B0); rlm@1: break; rlm@1: case 0xd6: rlm@1: // SUB NN rlm@1: tempValue=gbReadOpcode(PC.W++); rlm@1: tempRegister.W=AF.B.B1-tempValue; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0xd7: rlm@1: // RST 10 rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=0x0010; rlm@1: break; rlm@1: case 0xd8: rlm@1: // RET C rlm@1: if(AF.B.B0&C_FLAG) { rlm@1: PC.B.B0=gbReadMemory(SP.W++); rlm@1: PC.B.B1=gbReadMemory(SP.W++); rlm@1: clockTicks += 4; rlm@1: } rlm@1: break; rlm@1: case 0xd9: rlm@1: // RETI rlm@1: PC.B.B0=gbReadMemory(SP.W++); rlm@1: PC.B.B1=gbReadMemory(SP.W++); rlm@1: IFF |= 0x01; rlm@1: break; rlm@1: case 0xda: rlm@1: // JP C,NNNN rlm@1: if(AF.B.B0&C_FLAG) { rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W); rlm@1: PC.W=tempRegister.W; rlm@1: clockTicks++; rlm@1: } else rlm@1: PC.W+=2; rlm@1: break; rlm@1: // DB illegal rlm@1: case 0xdc: rlm@1: // CALL C,NNNN rlm@1: if(AF.B.B0&C_FLAG) { rlm@1: tempRegister.B.B0=gbReadMemory(PC.W++); rlm@1: tempRegister.B.B1=gbReadMemory(PC.W++); rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=tempRegister.W; rlm@1: clockTicks += 3; rlm@1: } else rlm@1: PC.W+=2; rlm@1: break; rlm@1: // DD illegal rlm@1: case 0xde: rlm@1: // SBC NN rlm@1: tempValue=gbReadOpcode(PC.W++); rlm@1: tempRegister.W=AF.B.B1-tempValue-(AF.B.B0&C_FLAG ? 1 : 0); rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: AF.B.B1=tempRegister.B.B0; rlm@1: break; rlm@1: case 0xdf: rlm@1: // RST 18 rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=0x0018; rlm@1: break; rlm@1: case 0xe0: rlm@1: // LD (FF00+NN),A rlm@1: gbWriteMemory(0xff00 + gbReadOpcode(PC.W++),AF.B.B1); rlm@1: break; rlm@1: case 0xe1: rlm@1: // POP HL rlm@1: HL.B.B0=gbReadMemory(SP.W++); rlm@1: HL.B.B1=gbReadMemory(SP.W++); rlm@1: break; rlm@1: case 0xe2: rlm@1: // LD (FF00+C),A rlm@1: gbWriteMemory(0xff00 + BC.B.B0,AF.B.B1); rlm@1: break; rlm@1: // E3 illegal rlm@1: // E4 illegal rlm@1: case 0xe5: rlm@1: // PUSH HL rlm@1: gbWriteMemory(--SP.W,HL.B.B1); rlm@1: gbWriteMemory(--SP.W,HL.B.B0); rlm@1: break; rlm@1: case 0xe6: rlm@1: // AND NN rlm@1: tempValue=gbReadOpcode(PC.W++); rlm@1: AF.B.B1&=tempValue; rlm@1: AF.B.B0=H_FLAG|ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xe7: rlm@1: // RST 20 rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=0x0020; rlm@1: break; rlm@1: case 0xe8: rlm@1: // ADD SP,NN rlm@1: offset = (s8)gbReadOpcode(PC.W++); rlm@1: rlm@1: if(offset >= 0) { rlm@1: tempRegister.W = SP.W + offset; rlm@1: AF.B.B0 = (SP.W > tempRegister.W ? C_FLAG : 0) | rlm@1: ((SP.W^offset^tempRegister.W)&0x1000? H_FLAG:0); rlm@1: SP.W = tempRegister.W; rlm@1: } else { rlm@1: tempRegister.W = SP.W + offset; rlm@1: AF.B.B0 = (SP.W < tempRegister.W ? C_FLAG : 0) | rlm@1: ((SP.W^offset^tempRegister.W)&0x1000?H_FLAG:0); rlm@1: SP.W = tempRegister.W; rlm@1: } rlm@1: break; rlm@1: case 0xe9: rlm@1: // LD PC,HL rlm@1: PC.W=HL.W; rlm@1: break; rlm@1: case 0xea: rlm@1: // LD (NNNN),A rlm@1: tempRegister.B.B0=gbReadOpcode(PC.W++); rlm@1: tempRegister.B.B1=gbReadOpcode(PC.W++); rlm@1: gbWriteMemory(tempRegister.W,AF.B.B1); rlm@1: break; rlm@1: // EB illegal rlm@1: // EC illegal rlm@1: // ED illegal rlm@1: case 0xee: rlm@1: // XOR NN rlm@1: tempValue=gbReadOpcode(PC.W++); rlm@1: AF.B.B1^=tempValue; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xef: rlm@1: // RST 28 rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=0x0028; rlm@1: break; rlm@1: case 0xf0: rlm@1: // LD A,(FF00+NN) rlm@1: AF.B.B1 = gbReadMemory(0xff00+gbReadOpcode(PC.W++)); rlm@1: break; rlm@1: case 0xf1: rlm@1: // POP AF rlm@1: AF.B.B0=gbReadMemory(SP.W++); rlm@1: AF.B.B1=gbReadMemory(SP.W++); rlm@1: break; rlm@1: case 0xf2: rlm@1: // LD A,(FF00+C) rlm@1: AF.B.B1 = gbReadMemory(0xff00+BC.B.B0); rlm@1: break; rlm@1: case 0xf3: rlm@1: // DI rlm@1: // IFF&=0xFE; rlm@1: IFF&=(~0x21); rlm@1: break; rlm@1: // F4 illegal rlm@1: case 0xf5: rlm@1: // PUSH AF rlm@1: gbWriteMemory(--SP.W,AF.B.B1); rlm@1: gbWriteMemory(--SP.W,AF.B.B0); rlm@1: break; rlm@1: case 0xf6: rlm@1: // OR NN rlm@1: tempValue=gbReadOpcode(PC.W++); rlm@1: AF.B.B1|=tempValue; rlm@1: AF.B.B0=ZeroTable[AF.B.B1]; rlm@1: break; rlm@1: case 0xf7: rlm@1: // RST 30 rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=0x0030; rlm@1: break; rlm@1: case 0xf8: rlm@1: // LD HL,SP+NN rlm@1: offset = (s8)gbReadOpcode(PC.W++); rlm@1: if(offset >= 0) { rlm@1: tempRegister.W = SP.W + offset; rlm@1: AF.B.B0 = (SP.W > tempRegister.W ? C_FLAG : 0) | rlm@1: ((SP.W^offset^tempRegister.W)&0x1000? H_FLAG:0); rlm@1: HL.W = tempRegister.W; rlm@1: } else { rlm@1: tempRegister.W = SP.W + offset; rlm@1: AF.B.B0 = (SP.W < tempRegister.W ? C_FLAG : 0) | rlm@1: ((SP.W^offset^tempRegister.W)&0x1000?H_FLAG:0); rlm@1: HL.W = tempRegister.W; rlm@1: } rlm@1: break; rlm@1: case 0xf9: rlm@1: // LD SP,HL rlm@1: SP.W=HL.W; rlm@1: break; rlm@1: case 0xfa: rlm@1: // LD A,(NNNN) rlm@1: tempRegister.B.B0=gbReadOpcode(PC.W++); rlm@1: tempRegister.B.B1=gbReadOpcode(PC.W++); rlm@1: AF.B.B1=gbReadMemory(tempRegister.W); rlm@1: break; rlm@1: case 0xfb: rlm@1: // EI rlm@1: IFF|=0x20; rlm@1: break; rlm@1: // FC illegal rlm@1: // FD illegal rlm@1: case 0xfe: rlm@1: // CP NN rlm@1: tempValue=gbReadOpcode(PC.W++); rlm@1: tempRegister.W=AF.B.B1-tempValue; rlm@1: AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]| rlm@1: ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0); rlm@1: break; rlm@1: case 0xff: rlm@1: // RST 38 rlm@1: gbWriteMemory(--SP.W,PC.B.B1); rlm@1: gbWriteMemory(--SP.W,PC.B.B0); rlm@1: PC.W=0x0038; rlm@1: break; rlm@1: default: rlm@1: systemMessage(0, N_("Unknown opcode %02x at %04x"), rlm@1: gbReadOpcode(PC.W-1),PC.W-1); rlm@1: emulating = false; rlm@92: return 1;