From 50bff99fdd758ead34489814b8e40695e712b0dd Mon Sep 17 00:00:00 2001 From: Ian C Date: Tue, 3 Jan 2012 22:45:48 +0000 Subject: First pass of single byte opcodes done. --- .../Z80CpuDecodeByte.cs | 983 ++++++++++++++++++++- 1 file changed, 981 insertions(+), 2 deletions(-) (limited to 'src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs') diff --git a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs index 4a747e1..65de984 100644 --- a/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs +++ b/src/Noddybox.Emulation.EightBit.Z80/Z80CpuDecodeByte.cs @@ -11,7 +11,7 @@ namespace Noddybox.Emulation.EightBit.Z80 /// Decode and execute an opcode. /// /// The opcode. - private void Decode(byte opcode) + private void DecodeByte(byte opcode) { // Check for shifted opcodes // @@ -372,7 +372,7 @@ namespace Noddybox.Emulation.EightBit.Z80 INC8(ref A); break; - case 0x2d: // DEC A + case 0x3d: // DEC A clock.Add(4); DEC8(ref A); break; @@ -399,6 +399,985 @@ namespace Noddybox.Emulation.EightBit.Z80 SetFlag(H35table[A]); break; + case 0x40: // LD B,B + clock.Add(4); + break; + + case 0x41: // LD B,C + clock.Add(4); + BC.high = BC.low; + break; + + case 0x42: // LD B,D + clock.Add(4); + BC.high = DE.high; + break; + + case 0x43: // LD B,E + clock.Add(4); + BC.high = DE.low; + break; + + case 0x44: // LD B,H + clock.Add(4); + BC.high = hl.high; + break; + + case 0x45: // LD B,L + clock.Add(4); + BC.high = hl.low; + break; + + case 0x46: // LD B,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + BC.high = memory.Read(addr); + break; + + case 0x47: // LD B,A + clock.Add(4); + BC.high = A; + break; + + case 0x48: // LD C,B + clock.Add(4); + BC.low = BC.high; + break; + + case 0x49: // LD C,C + clock.Add(4); + break; + + case 0x4a: // LD C,D + clock.Add(4); + BC.low = DE.high; + break; + + case 0x4b: // LD C,E + clock.Add(4); + BC.low = DE.low; + break; + + case 0x4c: // LD C,H + clock.Add(4); + BC.low = hl.high; + break; + + case 0x4d: // LD C,L + clock.Add(4); + BC.low = hl.low; + break; + + case 0x4e: // LD C,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + BC.low = memory.Read(addr); + break; + + case 0x4f: // LD C,A + clock.Add(4); + BC.low = A; + break; + + case 0x50: // LD D,B + clock.Add(4); + DE.high = BC.high; + break; + + case 0x51: // LD D,C + clock.Add(4); + DE.high = BC.low; + break; + + case 0x52: // LD D,D + clock.Add(4); + break; + + case 0x53: // LD D,E + clock.Add(4); + DE.high = DE.low; + break; + + case 0x54: // LD D,H + clock.Add(4); + DE.high = hl.high; + break; + + case 0x55: // LD D,L + clock.Add(4); + DE.high = hl.low; + break; + + case 0x56: // LD D,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + DE.high = memory.Read(addr); + break; + + case 0x57: // LD D,A + clock.Add(4); + DE.high = A; + break; + + case 0x58: // LD E,B + clock.Add(4); + DE.low = BC.high; + break; + + case 0x59: // LD E,C + clock.Add(4); + DE.low = BC.low; + break; + + case 0x5a: // LD E,D + clock.Add(4); + DE.low = DE.high; + break; + + case 0x5b: // LD E,E + clock.Add(4); + break; + + case 0x5c: // LD E,H + clock.Add(4); + DE.low = hl.high; + break; + + case 0x5d: // LD E,L + clock.Add(4); + DE.low = hl.low; + break; + + case 0x5e: // LD E,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + DE.low = memory.Read(addr); + break; + + case 0x5f: // LD E,A + clock.Add(4); + DE.low = A; + break; + + case 0x60: // LD H,B + clock.Add(4); + hl.high = BC.high; + break; + + case 0x61: // LD H,C + clock.Add(4); + hl.high = BC.low; + break; + + case 0x62: // LD H,D + clock.Add(4); + hl.high = DE.high; + break; + + case 0x63: // LD H,E + clock.Add(4); + hl.high = DE.low; + break; + + case 0x64: // LD H,H + clock.Add(4); + break; + + case 0x65: // LD H,L + clock.Add(4); + hl.high = hl.low; + break; + + case 0x66: // LD H,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + HL.high = memory.Read(addr); + break; + + case 0x67: // LD H,A + clock.Add(4); + hl.high = A; + break; + + case 0x68: // LD L,B + clock.Add(4); + hl.low = BC.high; + break; + + case 0x69: // LD L,C + clock.Add(4); + hl.low = BC.low; + break; + + case 0x6a: // LD L,D + clock.Add(4); + hl.low = DE.high; + break; + + case 0x6b: // LD L,E + clock.Add(4); + hl.low = DE.low; + break; + + case 0x6c: // LD L,H + clock.Add(4); + hl.low = hl.high; + break; + + case 0x6d: // LD L,L + clock.Add(4); + break; + + case 0x6e: // LD L,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + HL.low = memory.Read(addr); + break; + + case 0x6f: // LD L,A + clock.Add(4); + hl.low = A; + break; + + case 0x70: // LD (HL),B + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + memory.Write(addr, BC.high); + break; + + case 0x71: // LD (HL),C + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + memory.Write(addr, BC.low); + break; + + case 0x72: // LD (HL),D + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + memory.Write(addr, DE.high); + break; + + case 0x73: // LD (HL),E + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + memory.Write(addr, DE.low); + break; + + case 0x74: // LD (HL),H + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + memory.Write(addr, HL.high); + break; + + case 0x75: // LD (HL),L + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + memory.Write(addr, HL.low); + break; + + case 0x76: // HALT + clock.Add(4); + PC--; + HALT = true; + break; + + case 0x77: // LD (HL),A + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + memory.Write(addr, A); + break; + + case 0x78: // LD A,B + clock.Add(4); + A = BC.high; + break; + + case 0x79: // LD A,C + clock.Add(4); + A = BC.low; + break; + + case 0x7a: // LD A,D + clock.Add(4); + A = DE.high; + break; + + case 0x7b: // LD A,E + clock.Add(4); + A = DE.low; + break; + + case 0x7c: // LD A,H + clock.Add(4); + A = hl.high; + break; + + case 0x7d: // LD A,L + clock.Add(4); + A = hl.low; + break; + + case 0x7e: // LD A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + HL.low = memory.Read(addr); + break; + + case 0x7f: // LD A,A + clock.Add(4); + break; + + case 0x80: // ADD A,B + clock.Add(4); + ADD8(BC.high); + break; + + case 0x81: // ADD A,C + clock.Add(4); + ADD8(BC.low); + break; + + case 0x82: // ADD A,D + clock.Add(4); + ADD8(DE.high); + break; + + case 0x83: // ADD A,E + clock.Add(4); + ADD8(DE.low); + break; + + case 0x84: // ADD A,H + clock.Add(4); + ADD8(hl.high); + break; + + case 0x85: // ADD A,L + clock.Add(4); + ADD8(hl.low); + break; + + case 0x86: // ADD A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + ADD8(memory.Read(addr)); + break; + + case 0x87: // ADD A,A + clock.Add(4); + ADD8(A); + break; + + case 0x88: // ADC A,B + clock.Add(4); + ADC8(BC.high); + break; + + case 0x89: // ADC A,C + clock.Add(4); + ADC8(BC.low); + break; + + case 0x8a: // ADC A,D + clock.Add(4); + ADC8(DE.high); + break; + + case 0x8b: // ADC A,E + clock.Add(4); + ADC8(DE.low); + break; + + case 0x8c: // ADC A,H + clock.Add(4); + ADC8(hl.high); + break; + + case 0x8d: // ADC A,L + clock.Add(4); + ADC8(hl.low); + break; + + case 0x8e: // ADC A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + ADC8(memory.Read(addr)); + break; + + case 0x8f: // ADC A,A + clock.Add(4); + ADC8(A); + break; + + case 0x90: // SUB A,B + clock.Add(4); + SUB8(BC.high); + break; + + case 0x91: // SUB A,C + clock.Add(4); + SUB8(BC.low); + break; + + case 0x92: // SUB A,D + clock.Add(4); + SUB8(DE.high); + break; + + case 0x93: // SUB A,E + clock.Add(4); + SUB8(DE.low); + break; + + case 0x94: // SUB A,H + clock.Add(4); + SUB8(hl.high); + break; + + case 0x95: // SUB A,L + clock.Add(4); + SUB8(hl.low); + break; + + case 0x96: // SUB A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + SUB8(memory.Read(addr)); + break; + + case 0x97: // SUB A,A + clock.Add(4); + SUB8(A); + break; + + case 0x98: // SBC A,B + clock.Add(4); + SBC8(BC.high); + break; + + case 0x99: // SBC A,C + clock.Add(4); + SBC8(BC.low); + break; + + case 0x9a: // SBC A,D + clock.Add(4); + SBC8(DE.high); + break; + + case 0x9b: // SBC A,E + clock.Add(4); + SBC8(DE.low); + break; + + case 0x9c: // SBC A,H + clock.Add(4); + SBC8(hl.high); + break; + + case 0x9d: // SBC A,L + clock.Add(4); + SBC8(hl.low); + break; + + case 0x9e: // SBC A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + SBC8(memory.Read(addr)); + break; + + case 0x9f: // SBC A,A + clock.Add(4); + SBC8(A); + break; + + case 0xa0: // AND A,B + clock.Add(4); + AND(BC.high); + break; + + case 0xa1: // AND A,C + clock.Add(4); + AND(BC.low); + break; + + case 0xa2: // AND A,D + clock.Add(4); + AND(DE.high); + break; + + case 0xa3: // AND A,E + clock.Add(4); + AND(DE.low); + break; + + case 0xa4: // AND A,H + clock.Add(4); + AND(hl.high); + break; + + case 0xa5: // AND A,L + clock.Add(4); + AND(hl.low); + break; + + case 0xa6: // AND A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + AND(memory.Read(addr)); + break; + + case 0xa7: // AND A,A + clock.Add(4); + AND(A); + break; + + case 0xa8: // XOR A,B + clock.Add(4); + XOR(BC.high); + break; + + case 0xa9: // XOR A,C + clock.Add(4); + XOR(BC.low); + break; + + case 0xaa: // XOR A,D + clock.Add(4); + XOR(DE.high); + break; + + case 0xab: // XOR A,E + clock.Add(4); + XOR(DE.low); + break; + + case 0xac: // XOR A,H + clock.Add(4); + XOR(hl.high); + break; + + case 0xad: // XOR A,L + clock.Add(4); + XOR(hl.low); + break; + + case 0xae: // XOR A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + XOR(memory.Read(addr)); + break; + + case 0xaf: // XOR A,A + clock.Add(4); + XOR(A); + break; + + case 0xb0: // OR A,B + clock.Add(4); + OR(BC.high); + break; + + case 0xb1: // OR A,C + clock.Add(4); + OR(BC.low); + break; + + case 0xb2: // OR A,D + clock.Add(4); + OR(DE.high); + break; + + case 0xb3: // OR A,E + clock.Add(4); + OR(DE.low); + break; + + case 0xb4: // OR A,H + clock.Add(4); + OR(hl.high); + break; + + case 0xb5: // OR A,L + clock.Add(4); + OR(hl.low); + break; + + case 0xb6: // OR A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + OR(memory.Read(addr)); + break; + + case 0xb7: // OR A,A + clock.Add(4); + OR(A); + break; + + case 0xb8: // CP A,B + clock.Add(4); + CP(BC.high); + break; + + case 0xb9: // CP A,C + clock.Add(4); + CP(BC.low); + break; + + case 0xba: // CP A,D + clock.Add(4); + CP(DE.high); + break; + + case 0xbb: // CP A,E + clock.Add(4); + CP(DE.low); + break; + + case 0xbc: // CP A,H + clock.Add(4); + CP(hl.high); + break; + + case 0xbd: // CP A,L + clock.Add(4); + CP(hl.low); + break; + + case 0xbe: // CP A,(HL) + clock.Add(7); + addr = (ushort)(hl.reg + Offset()); + CP(memory.Read(addr)); + break; + + case 0xbf: // CP A,A + clock.Add(4); + CP(A); + break; + + case 0xc0: // RET NZ + RET_COND(Z80Flags.Zero, Z80Flags.None); + break; + + case 0xc1: // POP BC + clock.Add(10); + BC.reg = POP(); + break; + + case 0xc2: // JP NZ,nnnn + JP_COND(Z80Flags.Zero, Z80Flags.None); + break; + + case 0xc3: // JP nnnn + clock.Add(10); + JP(); + break; + + case 0xc4: // CALL NZ,nnnn + CALL_COND(Z80Flags.Zero, Z80Flags.None); + break; + + case 0xc5: // PUSH BC + clock.Add(10); + PUSH(BC.reg); + break; + + case 0xc6: // ADD A,n + clock.Add(7); + ADD8(memory.Read(PC++)); + break; + + case 0xc7: // RST 0 + RST(0); + break; + + case 0xc8: // RET Z + RET_COND(Z80Flags.Zero, Z80Flags.Zero); + break; + + case 0xc9: // RET + clock.Add(10); + SP = POP(); + break; + + case 0xca: // JP Z,nnnn + JP_COND(Z80Flags.Zero, Z80Flags.Zero); + break; + + case 0xcb: // CB shift + AddR(1); + + // Check for IX/IY shift + // + if (shift != 0) + { + if (shift == 0xdd) + { + addr = (ushort)(IX.reg + Offset()); + } + else + { + addr = (ushort)(IY.reg + Offset()); + } + + DecodeShiftedCB(memory.Read(PC++), addr); + } + else + { + DecodeCB(memory.Read(PC++)); + } + break; + + case 0xcc: // CALL Z,nnnn + CALL_COND(Z80Flags.Zero, Z80Flags.Zero); + break; + + case 0xcd: // CALL nnnn + clock.Add(17); + CALL(); + break; + + case 0xce: // ADC A,n + clock.Add(7); + ADC8(memory.Read(PC++)); + break; + + case 0xcf: // RST 8 + RST(8); + break; + + case 0xd0: // RET NC + RET_COND(Z80Flags.Carry, Z80Flags.None); + break; + + case 0xd1: // POP DE + clock.Add(10); + DE.reg = POP(); + break; + + case 0xd2: // JP NC,nnnn + JP_COND(Z80Flags.Carry, Z80Flags.None); + break; + + case 0xd3: // OUT(n),A + clock.Add(11); + addr = memory.Read(PC++); + addr |= (ushort)(A << 8); + device.Write(addr, A); + break; + + case 0xd4: // CALL NC,nnnn + CALL_COND(Z80Flags.Carry, Z80Flags.None); + break; + + case 0xd5: // PUSH DE + clock.Add(10); + PUSH(DE.reg); + break; + + case 0xd6: // SUB A,n + clock.Add(7); + SUB8(memory.Read(PC++)); + break; + + case 0xd7: // RST 10 + RST(0x10); + break; + + case 0xd8: // RET C + RET_COND(Z80Flags.Carry, Z80Flags.Carry); + break; + + case 0xd9: // EXX + clock.Add(4); + Swap(ref BC, ref BC_); + Swap(ref DE, ref DE_); + Swap(ref HL, ref HL_); + break; + + case 0xda: // JP C,nnnn + JP_COND(Z80Flags.Carry, Z80Flags.Carry); + break; + + case 0xdb: // IN A,(n) + clock.Add(11); + addr = memory.Read(PC++); + addr |= (ushort)(A << 8); + A = device.Read(addr); + break; + + case 0xdc: // CALL C,nnnn + CALL_COND(Z80Flags.Carry, Z80Flags.Carry); + break; + + case 0xdd: // DD (IX) PREFIX + AddR(1); + clock.Add(4); + shift = opcode; + DecodeByte(memory.Read(PC++)); + break; + + case 0xde: // SBC A,n + clock.Add(7); + SBC8(memory.Read(PC++)); + break; + + case 0xdf: // RST 18 + RST(0x18); + break; + + case 0xe0: // RET PO + RET_COND(Z80Flags.PV, Z80Flags.None); + break; + + case 0xe1: // POP HL + clock.Add(10); + hl.reg = POP(); + break; + + case 0xe2: // JP PO,nnnn + JP_COND(Z80Flags.PV, Z80Flags.None); + break; + + case 0xe3: // EX (SP),HL + clock.Add(19); + addr = POP(); + PUSH(hl.reg); + hl.reg = addr; + break; + + case 0xe4: // CALL PO,nnnn + CALL_COND(Z80Flags.PV, Z80Flags.None); + break; + + case 0xe5: // PUSH HL + clock.Add(10); + PUSH(hl.reg); + break; + + case 0xe6: // AND A,n + clock.Add(7); + AND(memory.Read(PC++)); + break; + + case 0xe7: // RST 20 + RST(0x20); + break; + + case 0xe8: // RET PE + RET_COND(Z80Flags.PV, Z80Flags.PV); + break; + + case 0xe9: // JP (HL) + clock.Add(4); + PC = hl.reg; + break; + + case 0xea: // JP PE,nnnn + JP_COND(Z80Flags.PV, Z80Flags.PV); + break; + + case 0xeb: // EX DE,HL + clock.Add(4); + Swap(ref DE, ref hl); + break; + + case 0xec: // CALL PE,nnnn + CALL_COND(Z80Flags.PV, Z80Flags.PV); + break; + + case 0xed: // ED PREFIX + AddR(1); + DecodeED(memory.Read(PC++)); + break; + + case 0xee: // XOR A,n + clock.Add(7); + XOR(memory.Read(PC++)); + break; + + case 0xef: // RST 28 + RST(0x28); + break; + + case 0xf0: // RET P + RET_COND(Z80Flags.Sign, Z80Flags.None); + break; + + case 0xf1: // POP AF + clock.Add(10); + addr = POP(); + A = (byte)(addr >> 8); + F = (Z80Flags)(addr & 0xff); + break; + + case 0xf2: // JP P,nnnn + JP_COND(Z80Flags.Sign, Z80Flags.None); + break; + + case 0xf3: // DI + clock.Add(4); + IFF1 = false; + IFF2 = false; + break; + + case 0xf4: // CALL P,nnnn + CALL_COND(Z80Flags.Sign, Z80Flags.None); + break; + + case 0xf5: // PUSH AF + clock.Add(10); + PUSH((ushort)((A << 8) | (int)(F))); + break; + + case 0xf6: // OR A,n + clock.Add(7); + OR(memory.Read(PC++)); + break; + + case 0xf7: // RST 30 + RST(0x30); + break; + + case 0xf8: // RET M + RET_COND(Z80Flags.Sign, Z80Flags.Sign); + break; + + case 0xf9: // LD SP,HL + clock.Add(6); + SP = hl.reg; + break; + + case 0xfa: // JP N,nnnn + JP_COND(Z80Flags.Sign, Z80Flags.Sign); + break; + + case 0xfb: // EI + clock.Add(4); + IFF1 = true; + IFF2 = true; + break; + + case 0xfc: // CALL M,nnnn + CALL_COND(Z80Flags.Sign, Z80Flags.Sign); + break; + + case 0xfd: // DD (IY) PREFIX + AddR(1); + clock.Add(4); + shift = opcode; + DecodeByte(memory.Read(PC++)); + break; + + case 0xfe: // CP A,n + clock.Add(7); + CP(memory.Read(PC++)); + break; + + case 0xff: // RST 38 + RST(0x18); + break; + default: break; } -- cgit v1.3