diff --git a/helper.go b/helper.go index 7fea54c..335fb07 100644 --- a/helper.go +++ b/helper.go @@ -58,6 +58,7 @@ func (z *CPU) pushW(val uint16) { } func (z *CPU) popW() uint16 { + z.extendedStack[z.SP] = PushValueTypeDefault z.SP += 2 return z.rw(z.SP - 2) } @@ -74,17 +75,17 @@ func (z *CPU) nextW() uint16 { return w } -func (z *CPU) bc() uint16 { - return (uint16(z.B) << 8) | uint16(z.C) -} - -func (z *CPU) de() uint16 { - return (uint16(z.D) << 8) | uint16(z.E) -} - -func (z *CPU) hl() uint16 { - return (uint16(z.H) << 8) | uint16(z.L) -} +//func (z *CPU) BC() uint16 { +// return (uint16(z.B) << 8) | uint16(z.C) +//} +// +//func (z *CPU) DE() uint16 { +// return (uint16(z.D) << 8) | uint16(z.E) +//} +// +//func (z *CPU) HL() uint16 { +// return (uint16(z.H) << 8) | uint16(z.L) +//} func (z *CPU) setBC(val uint16) { z.B = byte(val >> 8) @@ -178,7 +179,7 @@ func (z *CPU) updateXY(result byte) { func (z *CPU) DebugOutput() { log.Debugf("PC: %04X, AF: %04X, BC: %04X, DE: %04X, HL: %04X, SP: %04X, IX: %04X, IY: %04X, I: %02X, R: %02X", - z.PC, (uint16(z.A)<<8)|uint16(z.f()), z.bc(), z.de(), z.hl(), z.SP, + z.PC, (uint16(z.A)<<8)|uint16(z.f()), z.GetBC(), z.GetDE(), z.GetHL(), z.SP, z.IX, z.IY, z.I, z.R) log.Debugf("\t(%02X %02X %02X %02X), cycleCount: %d\n", z.rb(z.PC), z.rb(z.PC+1), diff --git a/opcodes.go b/opcodes.go index fdb15ae..3581c3d 100644 --- a/opcodes.go +++ b/opcodes.go @@ -66,16 +66,16 @@ func (z *CPU) condJr(condition bool) { } } -func bToByte(cond bool) byte { +func BToByte(cond bool) byte { if cond { - return byte(1) + return 1 } - return byte(0) + return 0 } // ADD Byte: adds two bytes together func (z *CPU) addB(a byte, b byte, cy bool) byte { - result := a + b + bToByte(cy) + result := a + b + BToByte(cy) z.Flags.S = result&0x80 != 0 z.Flags.Z = result == 0 z.Flags.H = carry(4, uint16(a), uint16(b), cy) @@ -120,7 +120,7 @@ func (z *CPU) addHL(val uint16) { sf := z.Flags.S zf := z.Flags.Z pf := z.Flags.P - result := z.addW(z.hl(), val, false) + result := z.addW(z.GetHL(), val, false) z.setHL(result) z.Flags.S = sf z.Flags.Z = zf @@ -141,7 +141,7 @@ func (z *CPU) addIZ(reg *uint16, val uint16) { // adcHL adds A word (+ carry) to HL func (z *CPU) adcHL(val uint16) { - result := z.addW(z.hl(), val, z.Flags.C) + result := z.addW(z.GetHL(), val, z.Flags.C) z.Flags.S = result&0x8000 != 0 z.Flags.Z = result == 0 z.setHL(result) @@ -149,7 +149,7 @@ func (z *CPU) adcHL(val uint16) { // sbcHL subtracts A word (+ carry) to HL func (z *CPU) sbcHL(val uint16) { - result := z.subW(z.hl(), val, z.Flags.C) + result := z.subW(z.GetHL(), val, z.Flags.C) z.Flags.S = result&0x8000 != 0 z.Flags.Z = result == 0 z.setHL(result) @@ -258,7 +258,7 @@ func (z *CPU) cbRrc(val byte) byte { func (z *CPU) cbRl(val byte) byte { cf := z.Flags.C z.Flags.C = val>>7 != 0 - val = (val << 1) | bToByte(cf) + val = (val << 1) | BToByte(cf) z.Flags.S = val&0x80 != 0 z.Flags.Z = val == 0 z.Flags.N = false @@ -272,7 +272,7 @@ func (z *CPU) cbRl(val byte) byte { func (z *CPU) cbRr(val byte) byte { c := z.Flags.C z.Flags.C = (val & 1) != 0 - val = (val >> 1) | (bToByte(c) << 7) + val = (val >> 1) | (BToByte(c) << 7) z.Flags.S = val&0x80 != 0 z.Flags.Z = val == 0 z.Flags.N = false @@ -348,14 +348,14 @@ func (z *CPU) cbBit(val byte, n byte) byte { } func (z *CPU) ldi() { - de := z.de() - hl := z.hl() + de := z.GetDE() + hl := z.GetHL() val := z.rb(hl) z.wb(de, val) - z.setHL(z.hl() + 1) - z.setDE(z.de() + 1) - z.setBC(z.bc() - 1) + z.setHL(z.GetHL() + 1) + z.setDE(z.GetDE() + 1) + z.setBC(z.GetBC() - 1) // see https://wikiti.brandonw.net/index.php?title=Z80_Instruction_Set // for the calculation of xf/yf on LDI @@ -366,27 +366,27 @@ func (z *CPU) ldi() { z.Flags.N = false z.Flags.H = false - z.Flags.P = z.bc() > 0 + z.Flags.P = z.GetBC() > 0 } func (z *CPU) ldd() { z.ldi() // same as ldi but HL and DE are decremented instead of incremented - z.setHL(z.hl() - 2) - z.setDE(z.de() - 2) + z.setHL(z.GetHL() - 2) + z.setDE(z.GetDE() - 2) } func (z *CPU) cpi() { cf := z.Flags.C - result := z.subB(z.A, z.rb(z.hl()), false) - z.setHL(z.hl() + 1) - z.setBC(z.bc() - 1) + result := z.subB(z.A, z.rb(z.GetHL()), false) + z.setHL(z.GetHL() + 1) + z.setBC(z.GetBC() - 1) - val := result - bToByte(z.Flags.H) + val := result - BToByte(z.Flags.H) z.Flags.X = val&0x08 != 0 z.Flags.Y = val&0x02 != 0 - z.Flags.P = z.bc() != 0 + z.Flags.P = z.GetBC() != 0 z.Flags.C = cf z.MemPtr += 1 } @@ -394,12 +394,12 @@ func (z *CPU) cpi() { func (z *CPU) cpd() { z.cpi() // same as cpi but HL is decremented instead of incremented - z.setHL(z.hl() - 2) + z.setHL(z.GetHL() - 2) z.MemPtr -= 2 } func (z *CPU) inRC(r *byte) { - *r = z.core.IORead(z.bc()) + *r = z.core.IORead(z.GetBC()) z.Flags.Z = *r == 0 z.Flags.S = *r&0x80 != 0 z.Flags.P = parity(*r) @@ -408,9 +408,9 @@ func (z *CPU) inRC(r *byte) { } func (z *CPU) ini() { - val := z.core.IORead(z.bc()) - z.wb(z.hl(), val) - z.MemPtr = z.bc() + 1 + val := z.core.IORead(z.GetBC()) + z.wb(z.GetHL(), val) + z.MemPtr = z.GetBC() + 1 z.B-- other := val + z.C + 1 @@ -426,13 +426,13 @@ func (z *CPU) ini() { z.Flags.S = z.B&0x80 != 0 z.Flags.Z = z.B == 0 z.updateXY(z.B) - z.setHL(z.hl() + 1) + z.setHL(z.GetHL() + 1) } func (z *CPU) ind() { - val := z.core.IORead(z.bc()) - z.wb(z.hl(), val) - z.MemPtr = z.bc() - 1 + val := z.core.IORead(z.GetBC()) + z.wb(z.GetHL(), val) + z.MemPtr = z.GetBC() - 1 z.B-- other := val + z.C - 1 @@ -449,7 +449,7 @@ func (z *CPU) ind() { z.Flags.S = z.B&0x80 != 0 z.Flags.Z = z.B == 0 z.updateXY(z.B) - z.setHL(z.hl() - 1) + z.setHL(z.GetHL() - 1) } func (z *CPU) outCmnFlags(val uint8) { other := val + z.L @@ -468,20 +468,20 @@ func (z *CPU) outCmnFlags(val uint8) { } func (z *CPU) outi() { - val := z.rb(z.hl()) + val := z.rb(z.GetHL()) z.B-- - z.MemPtr = z.bc() + 1 - z.core.IOWrite(z.bc(), val) - z.setHL(z.hl() + 1) + z.MemPtr = z.GetBC() + 1 + z.core.IOWrite(z.GetBC(), val) + z.setHL(z.GetHL() + 1) z.outCmnFlags(val) } func (z *CPU) outd() { - val := z.rb(z.hl()) + val := z.rb(z.GetHL()) z.B-- - z.MemPtr = z.bc() - 1 - z.core.IOWrite(z.bc(), val) - z.setHL(z.hl() - 1) + z.MemPtr = z.GetBC() - 1 + z.core.IOWrite(z.GetBC(), val) + z.setHL(z.GetHL() - 1) z.outCmnFlags(val) } @@ -694,34 +694,34 @@ func (z *CPU) execOpcode(opcode byte) { //z.l = z.l // ld l,l case 0x7E: - z.A = z.rb(z.hl()) // ld a,(hl) + z.A = z.rb(z.GetHL()) // ld a,(hl) case 0x46: - z.B = z.rb(z.hl()) // ld b,(hl) + z.B = z.rb(z.GetHL()) // ld b,(hl) case 0x4E: - z.C = z.rb(z.hl()) // ld c,(hl) + z.C = z.rb(z.GetHL()) // ld c,(hl) case 0x56: - z.D = z.rb(z.hl()) // ld d,(hl) + z.D = z.rb(z.GetHL()) // ld d,(hl) case 0x5E: - z.E = z.rb(z.hl()) // ld e,(hl) + z.E = z.rb(z.GetHL()) // ld e,(hl) case 0x66: - z.H = z.rb(z.hl()) // ld h,(hl) + z.H = z.rb(z.GetHL()) // ld h,(hl) case 0x6E: - z.L = z.rb(z.hl()) // ld l,(hl) + z.L = z.rb(z.GetHL()) // ld l,(hl) case 0x77: - z.wb(z.hl(), z.A) // ld (hl),a + z.wb(z.GetHL(), z.A) // ld (hl),a case 0x70: - z.wb(z.hl(), z.B) // ld (hl),b + z.wb(z.GetHL(), z.B) // ld (hl),b case 0x71: - z.wb(z.hl(), z.C) // ld (hl),c + z.wb(z.GetHL(), z.C) // ld (hl),c case 0x72: - z.wb(z.hl(), z.D) // ld (hl),d + z.wb(z.GetHL(), z.D) // ld (hl),d case 0x73: - z.wb(z.hl(), z.E) // ld (hl),e + z.wb(z.GetHL(), z.E) // ld (hl),e case 0x74: - z.wb(z.hl(), z.H) // ld (hl),h + z.wb(z.GetHL(), z.H) // ld (hl),h case 0x75: - z.wb(z.hl(), z.L) // ld (hl),l + z.wb(z.GetHL(), z.L) // ld (hl),l case 0x3E: z.A = z.nextB() // ld a,* @@ -738,15 +738,15 @@ func (z *CPU) execOpcode(opcode byte) { case 0x2E: z.L = z.nextB() // ld l,* case 0x36: - z.wb(z.hl(), z.nextB()) // ld (hl),* + z.wb(z.GetHL(), z.nextB()) // ld (hl),* case 0x0A: // ld a,(bc) - z.A = z.rb(z.bc()) - z.MemPtr = z.bc() + 1 + z.A = z.rb(z.GetBC()) + z.MemPtr = z.GetBC() + 1 case 0x1A: // ld a,(de) - z.A = z.rb(z.de()) - z.MemPtr = z.de() + 1 + z.A = z.rb(z.GetDE()) + z.MemPtr = z.GetDE() + 1 case 0x3A: // ld a,(**) addr := z.nextW() @@ -754,12 +754,12 @@ func (z *CPU) execOpcode(opcode byte) { z.MemPtr = addr + 1 case 0x02: // ld (bc),a - z.wb(z.bc(), z.A) - z.MemPtr = (uint16(z.A) << 8) | ((z.bc() + 1) & 0xFF) + z.wb(z.GetBC(), z.A) + z.MemPtr = (uint16(z.A) << 8) | ((z.GetBC() + 1) & 0xFF) case 0x12: // ld (de),a - z.wb(z.de(), z.A) - z.MemPtr = (uint16(z.A) << 8) | ((z.de() + 1) & 0xFF) + z.wb(z.GetDE(), z.A) + z.MemPtr = (uint16(z.A) << 8) | ((z.GetDE() + 1) & 0xFF) case 0x32: // ld (**),a addr := z.nextW() @@ -782,20 +782,20 @@ func (z *CPU) execOpcode(opcode byte) { case 0x22: // ld (**),hl addr := z.nextW() - z.ww(addr, z.hl()) + z.ww(addr, z.GetHL()) z.MemPtr = addr + 1 case 0xF9: - z.SP = z.hl() // ld sp,hl + z.SP = z.GetHL() // ld sp,hl case 0xEB: // ex de,hl - de := z.de() - z.setDE(z.hl()) + de := z.GetDE() + z.setDE(z.GetHL()) z.setHL(de) case 0xE3: // ex (sp),hl val := z.rw(z.SP) - z.ww(z.SP, z.hl()) + z.ww(z.SP, z.GetHL()) z.setHL(val) z.MemPtr = val case 0x87: @@ -813,7 +813,7 @@ func (z *CPU) execOpcode(opcode byte) { case 0x85: z.A = z.addB(z.A, z.L, false) // add a,l case 0x86: - z.A = z.addB(z.A, z.rb(z.hl()), false) // add a,(hl) + z.A = z.addB(z.A, z.rb(z.GetHL()), false) // add a,(hl) case 0xC6: z.A = z.addB(z.A, z.nextB(), false) // add a,* @@ -832,7 +832,7 @@ func (z *CPU) execOpcode(opcode byte) { case 0x8D: z.A = z.addB(z.A, z.L, z.Flags.C) // adc a,l case 0x8E: - z.A = z.addB(z.A, z.rb(z.hl()), z.Flags.C) // adc a,(hl) + z.A = z.addB(z.A, z.rb(z.GetHL()), z.Flags.C) // adc a,(hl) case 0xCE: z.A = z.addB(z.A, z.nextB(), z.Flags.C) // adc a,* @@ -851,7 +851,7 @@ func (z *CPU) execOpcode(opcode byte) { case 0x95: z.A = z.subB(z.A, z.L, false) // sub a,l case 0x96: - z.A = z.subB(z.A, z.rb(z.hl()), false) // sub a,(hl) + z.A = z.subB(z.A, z.rb(z.GetHL()), false) // sub a,(hl) case 0xD6: z.A = z.subB(z.A, z.nextB(), false) // sub a,* @@ -870,16 +870,16 @@ func (z *CPU) execOpcode(opcode byte) { case 0x9D: z.A = z.subB(z.A, z.L, z.Flags.C) // sbc a,l case 0x9E: - z.A = z.subB(z.A, z.rb(z.hl()), z.Flags.C) // sbc a,(hl) + z.A = z.subB(z.A, z.rb(z.GetHL()), z.Flags.C) // sbc a,(hl) case 0xDE: z.A = z.subB(z.A, z.nextB(), z.Flags.C) // sbc a,* case 0x09: - z.addHL(z.bc()) // add hl,bc + z.addHL(z.GetBC()) // add hl,bc case 0x19: - z.addHL(z.de()) // add hl,de + z.addHL(z.GetDE()) // add hl,de case 0x29: - z.addHL(z.hl()) // add hl,hl + z.addHL(z.GetHL()) // add hl,hl case 0x39: z.addHL(z.SP) // add hl,sp @@ -908,8 +908,8 @@ func (z *CPU) execOpcode(opcode byte) { z.L = z.inc(z.L) case 0x34: // inc (hl) - result := z.inc(z.rb(z.hl())) - z.wb(z.hl(), result) + result := z.inc(z.rb(z.GetHL())) + z.wb(z.GetHL(), result) case 0x3D: z.A = z.dec(z.A) // dec a case 0x05: @@ -926,22 +926,22 @@ func (z *CPU) execOpcode(opcode byte) { z.L = z.dec(z.L) // dec l case 0x35: // dec (hl) - result := z.dec(z.rb(z.hl())) - z.wb(z.hl(), result) + result := z.dec(z.rb(z.GetHL())) + z.wb(z.GetHL(), result) case 0x03: - z.setBC(z.bc() + 1) // inc bc + z.setBC(z.GetBC() + 1) // inc bc case 0x13: - z.setDE(z.de() + 1) // inc de + z.setDE(z.GetDE() + 1) // inc de case 0x23: - z.setHL(z.hl() + 1) // inc hl + z.setHL(z.GetHL() + 1) // inc hl case 0x33: z.SP = z.SP + 1 // inc sp case 0x0B: - z.setBC(z.bc() - 1) // dec bc + z.setBC(z.GetBC() - 1) // dec bc case 0x1B: - z.setDE(z.de() - 1) // dec de + z.setDE(z.GetDE() - 1) // dec de case 0x2B: - z.setHL(z.hl() - 1) // dec hl + z.setHL(z.GetHL() - 1) // dec hl case 0x3B: z.SP = z.SP - 1 // dec sp case 0x27: @@ -967,20 +967,20 @@ func (z *CPU) execOpcode(opcode byte) { case 0x07: // Rotate left z.Flags.C = z.A&0x80 != 0 - z.A = (z.A << 1) | bToByte(z.Flags.C) + z.A = (z.A << 1) | BToByte(z.Flags.C) z.Flags.N = false z.Flags.H = false z.updateXY(z.A) case 0x0F: // Rotate right z.Flags.C = z.A&1 != 0 - z.A = (z.A >> 1) | (bToByte(z.Flags.C) << 7) + z.A = (z.A >> 1) | (BToByte(z.Flags.C) << 7) z.Flags.N = false z.Flags.H = false z.updateXY(z.A) case 0x17: // rla - cy := bToByte(z.Flags.C) + cy := BToByte(z.Flags.C) z.Flags.C = z.A&0x80 != 0 z.A = (z.A << 1) | cy z.Flags.N = false @@ -988,7 +988,7 @@ func (z *CPU) execOpcode(opcode byte) { z.updateXY(z.A) case 0x1F: // rra - cy := bToByte(z.Flags.C) + cy := BToByte(z.Flags.C) z.Flags.C = z.A&1 != 0 z.A = (z.A >> 1) | (cy << 7) z.Flags.N = false @@ -1009,7 +1009,7 @@ func (z *CPU) execOpcode(opcode byte) { case 0xA5: z.lAnd(z.L) // and l case 0xA6: - z.lAnd(z.rb(z.hl())) // and (hl) + z.lAnd(z.rb(z.GetHL())) // and (hl) case 0xE6: z.lAnd(z.nextB()) // and * @@ -1028,7 +1028,7 @@ func (z *CPU) execOpcode(opcode byte) { case 0xAD: z.lXor(z.L) // xor l case 0xAE: - z.lXor(z.rb(z.hl())) // xor (hl) + z.lXor(z.rb(z.GetHL())) // xor (hl) case 0xEE: z.lXor(z.nextB()) // xor * @@ -1047,7 +1047,7 @@ func (z *CPU) execOpcode(opcode byte) { case 0xB5: z.lOr(z.L) // or l case 0xB6: - z.lOr(z.rb(z.hl())) // or (hl) + z.lOr(z.rb(z.GetHL())) // or (hl) case 0xF6: z.lOr(z.nextB()) // or * @@ -1066,7 +1066,7 @@ func (z *CPU) execOpcode(opcode byte) { case 0xBD: z.cp(z.L) case 0xBE: - z.cp(z.rb(z.hl())) // cp (hl) + z.cp(z.rb(z.GetHL())) // cp (hl) case 0xFE: z.cp(z.nextB()) // cp * @@ -1111,7 +1111,7 @@ func (z *CPU) execOpcode(opcode byte) { z.condJr(z.Flags.C) // jr c, * case 0xE9: - z.PC = z.hl() // jp (hl) + z.PC = z.GetHL() // jp (hl) case 0xCD: z.call(z.nextW()) // call @@ -1176,11 +1176,11 @@ func (z *CPU) execOpcode(opcode byte) { z.call(0x38) // rst 7 z.extendedStack[z.SP] = PushValueTypeRst case 0xC5: - z.pushW(z.bc()) // push bc + z.pushW(z.GetBC()) // push bc case 0xD5: - z.pushW(z.de()) // push de + z.pushW(z.GetDE()) // push de case 0xE5: - z.pushW(z.hl()) // push hl + z.pushW(z.GetHL()) // push hl case 0xF5: z.pushW((uint16(z.A) << 8) | uint16(z.f())) // push af diff --git a/opcodesCB.go b/opcodesCB.go index f478d9c..4f9ed67 100644 --- a/opcodesCB.go +++ b/opcodesCB.go @@ -29,7 +29,7 @@ func (z *CPU) execOpcodeCB(opcode byte) { case 5: reg = &z.L case 6: - hl = z.rb(z.hl()) + hl = z.rb(z.GetHL()) reg = &hl case 7: reg = &z.A @@ -78,7 +78,7 @@ func (z *CPU) execOpcodeCB(opcode byte) { } if reg == &hl { - z.wb(z.hl(), hl) + z.wb(z.GetHL(), hl) } } @@ -146,7 +146,7 @@ func (z *CPU) execOpcodeDcb(opcode byte, addr uint16) { z.L = result // always false //case 6: - // z.wb(z.hl(), result) + // z.wb(z.GetHL(), result) case 7: z.A = result } diff --git a/opcodesDDFD.go b/opcodesDDFD.go index 07d6937..813be87 100644 --- a/opcodesDDFD.go +++ b/opcodesDDFD.go @@ -15,9 +15,9 @@ func (z *CPU) execOpcodeDDFD(opcode byte, iz *uint16) { z.PC = *iz //z.jump(*iz) case 0x09: - z.addIZ(iz, z.bc()) // add iz,bc + z.addIZ(iz, z.GetBC()) // add iz,bc case 0x19: - z.addIZ(iz, z.de()) // add iz,de + z.addIZ(iz, z.GetDE()) // add iz,de case 0x29: z.addIZ(iz, *iz) // add iz,iz case 0x39: diff --git a/opcodesED.go b/opcodesED.go index 635b055..6bfa948 100644 --- a/opcodesED.go +++ b/opcodesED.go @@ -41,7 +41,7 @@ func (z *CPU) execOpcodeED(opcode byte) { { z.ldi() - if z.bc() != 0 { + if z.GetBC() != 0 { z.PC -= 2 z.cycleCount += 5 z.MemPtr = z.PC + 1 @@ -54,7 +54,7 @@ func (z *CPU) execOpcodeED(opcode byte) { { z.ldd() - if z.bc() != 0 { + if z.GetBC() != 0 { z.PC -= 2 z.cycleCount += 5 z.MemPtr = z.PC + 1 @@ -68,7 +68,7 @@ func (z *CPU) execOpcodeED(opcode byte) { case 0xB1: // cpir z.cpi() - if z.bc() != 0 && !z.Flags.Z { + if z.GetBC() != 0 && !z.Flags.Z { z.PC -= 2 z.cycleCount += 5 z.MemPtr = z.PC + 1 @@ -79,7 +79,7 @@ func (z *CPU) execOpcodeED(opcode byte) { case 0xB9: // cpdr z.cpd() - if z.bc() != 0 && !z.Flags.Z { + if z.GetBC() != 0 && !z.Flags.Z { z.PC -= 2 z.cycleCount += 5 z.MemPtr = z.PC + 1 @@ -88,9 +88,9 @@ func (z *CPU) execOpcodeED(opcode byte) { } case 0x40: z.inRC(&z.B) // in b, (c) - z.MemPtr = z.bc() + 1 + z.MemPtr = z.GetBC() + 1 case 0x48: - z.MemPtr = z.bc() + 1 + z.MemPtr = z.GetBC() + 1 z.inRC(&z.C) // in c, (c) z.updateXY(z.C) //case 0x4e: @@ -98,28 +98,28 @@ func (z *CPU) execOpcodeED(opcode byte) { case 0x50: z.inRC(&z.D) // in d, (c) - z.MemPtr = z.bc() + 1 + z.MemPtr = z.GetBC() + 1 case 0x58: // in e, (c) z.inRC(&z.E) - z.MemPtr = z.bc() + 1 + z.MemPtr = z.GetBC() + 1 z.updateXY(z.E) case 0x60: z.inRC(&z.H) // in h, (c) - z.MemPtr = z.bc() + 1 + z.MemPtr = z.GetBC() + 1 case 0x68: z.inRC(&z.L) // in l, (c) - z.MemPtr = z.bc() + 1 + z.MemPtr = z.GetBC() + 1 z.updateXY(z.L) case 0x70: // in (c) var val byte z.inRC(&val) - z.MemPtr = z.bc() + 1 + z.MemPtr = z.GetBC() + 1 case 0x78: // in a, (c) z.inRC(&z.A) - z.MemPtr = z.bc() + 1 + z.MemPtr = z.GetBC() + 1 z.updateXY(z.A) case 0xA2: z.ini() // ini @@ -141,30 +141,30 @@ func (z *CPU) execOpcodeED(opcode byte) { z.cycleCount += 5 } case 0x41: - z.core.IOWrite(z.bc(), z.B) // out (c), b - z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.GetBC(), z.B) // out (c), b + z.MemPtr = z.GetBC() + 1 case 0x49: - z.core.IOWrite(z.bc(), z.C) // out (c), c - z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.GetBC(), z.C) // out (c), c + z.MemPtr = z.GetBC() + 1 case 0x51: - z.core.IOWrite(z.bc(), z.D) // out (c), d - z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.GetBC(), z.D) // out (c), d + z.MemPtr = z.GetBC() + 1 case 0x59: - z.core.IOWrite(z.bc(), z.E) // out (c), e - z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.GetBC(), z.E) // out (c), e + z.MemPtr = z.GetBC() + 1 case 0x61: - z.core.IOWrite(z.bc(), z.H) // out (c), h - z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.GetBC(), z.H) // out (c), h + z.MemPtr = z.GetBC() + 1 case 0x69: - z.core.IOWrite(z.bc(), z.L) // out (c), l - z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.GetBC(), z.L) // out (c), l + z.MemPtr = z.GetBC() + 1 case 0x71: - z.core.IOWrite(z.bc(), 0) // out (c), 0 - z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.GetBC(), 0) // out (c), 0 + z.MemPtr = z.GetBC() + 1 case 0x79: // out (c), a - z.core.IOWrite(z.bc(), z.A) - z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.GetBC(), z.A) + z.MemPtr = z.GetBC() + 1 case 0xA3: z.outi() // outi case 0xB3: @@ -185,35 +185,35 @@ func (z *CPU) execOpcodeED(opcode byte) { } case 0x42: - z.sbcHL(z.bc()) // sbc hl,bc + z.sbcHL(z.GetBC()) // sbc hl,bc case 0x52: - z.sbcHL(z.de()) // sbc hl,de + z.sbcHL(z.GetDE()) // sbc hl,de case 0x62: - z.sbcHL(z.hl()) // sbc hl,hl + z.sbcHL(z.GetHL()) // sbc hl,hl case 0x72: z.sbcHL(z.SP) // sbc hl,sp case 0x4A: - z.adcHL(z.bc()) // adc hl,bc + z.adcHL(z.GetBC()) // adc hl,bc case 0x5A: - z.adcHL(z.de()) // adc hl,de + z.adcHL(z.GetDE()) // adc hl,de case 0x6A: - z.adcHL(z.hl()) // adc hl,hl + z.adcHL(z.GetHL()) // adc hl,hl case 0x7A: z.adcHL(z.SP) // adc hl,sp case 0x43: // ld (**), bc addr := z.nextW() - z.ww(addr, z.bc()) + z.ww(addr, z.GetBC()) z.MemPtr = addr + 1 case 0x53: // ld (**), de addr := z.nextW() - z.ww(addr, z.de()) + z.ww(addr, z.GetDE()) z.MemPtr = addr + 1 case 0x63: // ld (**), hl addr := z.nextW() - z.ww(addr, z.hl()) + z.ww(addr, z.GetHL()) z.MemPtr = addr + 1 case 0x73: // ld (**), hl @@ -251,9 +251,9 @@ func (z *CPU) execOpcodeED(opcode byte) { case 0x67: // rrd a := z.A - val := z.rb(z.hl()) + val := z.rb(z.GetHL()) z.A = (a & 0xF0) | (val & 0xF) - z.wb(z.hl(), (val>>4)|(a<<4)) + z.wb(z.GetHL(), (val>>4)|(a<<4)) z.Flags.N = false z.Flags.H = false @@ -261,20 +261,20 @@ func (z *CPU) execOpcodeED(opcode byte) { z.Flags.Z = z.A == 0 z.Flags.S = z.A&0x80 != 0 z.Flags.P = parity(z.A) - z.MemPtr = z.hl() + 1 + z.MemPtr = z.GetHL() + 1 case 0x6F: // rld a := z.A - val := z.rb(z.hl()) + val := z.rb(z.GetHL()) z.A = (a & 0xF0) | (val >> 4) - z.wb(z.hl(), (val<<4)|(a&0xF)) + z.wb(z.GetHL(), (val<<4)|(a&0xF)) z.Flags.N = false z.Flags.H = false z.updateXY(z.A) z.Flags.Z = z.A == 0 z.Flags.S = z.A&0x80 != 0 z.Flags.P = parity(z.A) - z.MemPtr = z.hl() + 1 + z.MemPtr = z.GetHL() + 1 default: log.Errorf("Unknown ED opcode: %02X\n", opcode) } diff --git a/z80go.go b/z80go.go index 8fee9d6..5075cff 100644 --- a/z80go.go +++ b/z80go.go @@ -43,6 +43,11 @@ type CPUInterface interface { SetState(state *CPU) // DebugOutput out current CPU state DebugOutput() + // GenNMI Generate NMI + GenNMI() + // GenINT Generate INT, + // data - data bus low address for IM2 mode + GenINT(data byte) } // FlagsType - Processor flags @@ -231,3 +236,23 @@ func (f *FlagsType) SetFlags(flags byte) { func (z *CPU) GetPC() uint16 { return z.PC } + +// GetSP - return stack pointer +func (z *CPU) GetSP() uint16 { + return z.SP +} + +// GetBC - return BC register pair +func (z *CPU) GetBC() uint16 { + return (uint16(z.B) << 8) | uint16(z.C) +} + +// GetDE - return DE register pair +func (z *CPU) GetDE() uint16 { + return (uint16(z.D) << 8) | uint16(z.E) +} + +// GetHL - return HL register pair +func (z *CPU) GetHL() uint16 { + return (uint16(z.H) << 8) | uint16(z.L) +} diff --git a/z80go_test.go b/z80go_test.go index 16bcfdb..08a5e9c 100644 --- a/z80go_test.go +++ b/z80go_test.go @@ -613,3 +613,34 @@ func TestZ80_JR_mnn(t *testing.T) { t.Errorf("Error JR -nn, result PC=0x%04X, expected: 0x%04X", computer.cpu.PC, expected) } } + +var testEXSPHL = []byte{0x21, 0x55, 0x44, 0xE3, 0xC9} + +func TestZ80_EXSPHL(t *testing.T) { + setMemory(0x0000, testEXSPHL) + state := computer.cpu.GetState() + state.SP = 0x1122 + state.PC = 0x0000 + computer.MemWrite(state.SP, 0x88) + computer.MemWrite(state.SP+1, 0x99) + + computer.cpu.SetState(state) + // Step 1: LD HL,0x4455 + computer.cpu.RunInstruction() + expected := uint16(0x4455) + if computer.cpu.GetHL() != expected { + t.Errorf("Error LD HL,nnnn, result HL=0x%04X, expected: 0x%04X", computer.cpu.GetHL(), expected) + } + // Step 2: EX (SP), HL + computer.cpu.RunInstruction() + expected = uint16(0x9988) + if computer.cpu.GetHL() != expected { + t.Errorf("Error EX (SP),HL, result HL=0x%04X, expected: 0x%04X", computer.cpu.GetHL(), expected) + } + expected = uint16(0x4455) + mem := uint16(computer.MemRead(state.SP)) | (uint16(computer.MemRead(state.SP+1)) << 8) + if mem != expected { + t.Errorf("Error EX (SP),HL, result (SP)=0x%04X, expected: 0x%04X", mem, expected) + } + +}