From 57b18ccda02e730d8a28259d19f659146fbc1054 Mon Sep 17 00:00:00 2001 From: Roman Boykov Date: Thu, 23 Apr 2026 22:41:11 +0300 Subject: [PATCH] try to fix reti --- cpu.go | 27 ++++++++++++--------- helper.go | 6 ++--- opcodes.go | 66 +++++++++++++++++++++----------------------------- opcodesCB.go | 10 ++++---- opcodesDDFD.go | 2 +- opcodesED.go | 18 +++++++------- z80go.go | 17 ++++++++----- z80go_test.go | 4 +-- 8 files changed, 71 insertions(+), 79 deletions(-) diff --git a/cpu.go b/cpu.go index ccf8218..f14f832 100644 --- a/cpu.go +++ b/cpu.go @@ -14,7 +14,7 @@ func NewCPU(core MemIoRW) *CPU { z := CPU{} z.Reset() z.core = core - z.cycleCount = 0 + z.TStates = 0 z.codeCoverageEnabled = false // z.memAccess = z.codeCoverageEnabled = false @@ -31,7 +31,7 @@ func (z *CPU) RunInstruction() (uint32, *map[uint16]byte) { if z.codeCoverageEnabled { z.codeCoverage[z.PC] = true } - pre := z.cycleCount + pre := z.TStates if z.Halted { z.execOpcode(0x00) } else { @@ -39,7 +39,7 @@ func (z *CPU) RunInstruction() (uint32, *map[uint16]byte) { z.execOpcode(opcode) } z.processInterrupts() - return z.cycleCount - pre, &z.memAccess + return z.TStates - pre, &z.memAccess } // SetState set current CPU state @@ -71,14 +71,18 @@ func (z *CPU) SetState(state *CPU) { z.Flags = state.Flags z.FlagsAlt = state.FlagsAlt + z.TStates = state.TStates + z.TStatesPart = state.TStatesPart z.MemPtr = state.MemPtr z.IMode = state.IMode z.Iff1 = state.Iff1 z.Iff2 = state.Iff2 z.Halted = state.Halted - z.IntOccurred = state.IntOccurred - z.NmiOccurred = false + z.intData = state.intData + z.intPending = state.intPending + z.nmiPending = state.nmiPending } + func (z *CPU) GetState() *CPU { return &CPU{ A: z.A, @@ -109,17 +113,16 @@ func (z *CPU) GetState() *CPU { Iff1: z.Iff1, Iff2: z.Iff2, Halted: z.Halted, - CycleCount: z.cycleCount, - IntOccurred: z.IntOccurred, - NmiOccurred: z.NmiOccurred, + TStatesPart: z.TStatesPart, + TStates: z.TStates, MemPtr: z.MemPtr, + + intData: z.intData, + intPending: z.intPending, + nmiPending: z.nmiPending, } } -//func (z *CPU) PC() uint16 { -// return z.PC -//} - // ClearCodeCoverage - clears code coverage journal func (z *CPU) ClearCodeCoverage() { clear(z.codeCoverage) diff --git a/helper.go b/helper.go index 335fb07..50485d1 100644 --- a/helper.go +++ b/helper.go @@ -183,11 +183,11 @@ func (z *CPU) DebugOutput() { 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), - z.rb(z.PC+2), z.rb(z.PC+3), z.cycleCount) + z.rb(z.PC+2), z.rb(z.PC+3), z.TStates) } func (z *CPU) Reset() { - z.cycleCount = 0 + z.TStates = 0 z.PC = 0 z.SP = 0xFFFF z.IX = 0 @@ -221,7 +221,5 @@ func (z *CPU) Reset() { z.Iff1 = false z.Iff2 = false z.Halted = false - z.IntOccurred = false - z.NmiOccurred = false z.intData = 0 } diff --git a/opcodes.go b/opcodes.go index 3581c3d..5d25fe0 100644 --- a/opcodes.go +++ b/opcodes.go @@ -30,7 +30,7 @@ func (z *CPU) condCall(condition bool) { addr := z.nextW() if condition { z.call(addr) - z.cycleCount += 7 + z.TStates += 7 } z.MemPtr = addr } @@ -45,7 +45,7 @@ func (z *CPU) ret() { func (z *CPU) condRet(condition bool) { if condition { z.ret() - z.cycleCount += 6 + z.TStates += 6 } } @@ -62,7 +62,7 @@ func (z *CPU) condJr(condition bool) { b := z.nextB() if condition { z.jr(b) - z.cycleCount += 5 + z.TStates += 5 } } @@ -99,16 +99,17 @@ func (z *CPU) subB(a byte, b byte, cy bool) byte { func (z *CPU) addW(a uint16, b uint16, cy bool) uint16 { lsb := z.addB(byte(a), byte(b), cy) msb := z.addB(byte(a>>8), byte(b>>8), z.Flags.C) - result := (uint16(msb) << 8) | uint16(lsb) - z.Flags.Z = result == 0 - z.MemPtr = a + 1 - return result + return z.addSubRes(a, msb, lsb) } // subW Subtracts two words (with optional carry) func (z *CPU) subW(a uint16, b uint16, cy bool) uint16 { lsb := z.subB(byte(a), byte(b), cy) msb := z.subB(byte(a>>8), byte(b>>8), z.Flags.C) + return z.addSubRes(a, msb, lsb) +} + +func (z *CPU) addSubRes(a uint16, msb uint8, lsb uint8) uint16 { result := (uint16(msb) << 8) | uint16(lsb) z.Flags.Z = result == 0 z.MemPtr = a + 1 @@ -174,39 +175,25 @@ func (z *CPU) dec(a byte) byte { // executes A logic "and" between register A and A byte, then stores the // result in register A func (z *CPU) lAnd(val byte) { - result := z.A & val - z.Flags.S = result&0x80 != 0 - z.Flags.Z = result == 0 - z.Flags.H = true - z.Flags.P = parity(result) - z.Flags.N = false - z.Flags.C = false - z.updateXY(result) - z.A = result + z.lCmn(z.A&val, true) } // executes A logic "xor" between register A and A byte, then stores the // result in register A func (z *CPU) lXor(val byte) { - result := z.A ^ val - z.Flags.S = result&0x80 != 0 - z.Flags.Z = result == 0 - z.Flags.H = false - z.Flags.P = parity(result) - z.Flags.N = false - z.Flags.C = false - z.updateXY(result) - z.A = result + z.lCmn(z.A^val, false) } // executes A logic "or" between register A and A byte, then stores the // result in register A func (z *CPU) lOr(val byte) { - result := z.A | val + z.lCmn(z.A|val, false) +} +func (z *CPU) lCmn(result byte, hf bool) { z.Flags.S = result&0x80 != 0 z.Flags.Z = result == 0 - z.Flags.H = false + z.Flags.H = hf z.Flags.P = parity(result) z.Flags.N = false z.Flags.C = false @@ -217,11 +204,6 @@ func (z *CPU) lOr(val byte) { // compares A value with register A func (z *CPU) cp(val byte) { z.subB(z.A, val, false) - - // the only difference between cp and sub is that - // the xf/yf are taken from the value to be subtracted, - // not the result - z.updateXY(val) } @@ -538,31 +520,37 @@ func (z *CPU) processInterrupts() { if z.nmiPending { z.nmiPending = false - z.Halted = false + if z.Halted { + z.PC++ + z.Halted = false + } z.Iff1 = false z.incR() - z.cycleCount += 11 + z.TStates += 11 z.call(0x0066) return } if z.intPending && z.Iff1 { z.intPending = false - z.Halted = false + if z.Halted { + z.PC++ + z.Halted = false + } z.Iff1 = false z.Iff2 = false z.incR() switch z.IMode { case 0: - z.cycleCount += 11 + z.TStates += 11 z.execOpcode(z.intData) case 1: - z.cycleCount += 13 + z.TStates += 13 z.call(0x38) case 2: - z.cycleCount += 19 + z.TStates += 19 z.call(z.rw((uint16(z.I) << 8) | uint16(z.intData))) default: log.Errorf("Unsupported interrupt mode %d\n", z.IMode) @@ -584,7 +572,7 @@ func (z *CPU) GenINT(data byte) { // executes A non-prefixed opcode func (z *CPU) execOpcode(opcode byte) { - z.cycleCount += uint32(cycles00[opcode]) + z.TStates += uint32(cycles00[opcode]) z.incR() switch opcode { diff --git a/opcodesCB.go b/opcodesCB.go index 4f9ed67..bc3ddf4 100644 --- a/opcodesCB.go +++ b/opcodesCB.go @@ -4,7 +4,7 @@ import log "github.com/sirupsen/logrus" // executes A CB opcode func (z *CPU) execOpcodeCB(opcode byte) { - z.cycleCount += 8 + z.TStates += 8 z.incR() // decoding instructions from http://z80.info/decoding.htm#cb @@ -64,7 +64,7 @@ func (z *CPU) execOpcodeCB(opcode byte) { // in bit (hl), x/y flags are handled differently: if z_ == 6 { z.updateXY(byte(z.MemPtr >> 8)) - z.cycleCount += 4 + z.TStates += 4 } case 2: @@ -74,7 +74,7 @@ func (z *CPU) execOpcodeCB(opcode byte) { } if (x_ == 0 || x_ == 2 || x_ == 3) && z_ == 6 { - z.cycleCount += 7 + z.TStates += 7 } if reg == &hl { @@ -154,9 +154,9 @@ func (z *CPU) execOpcodeDcb(opcode byte, addr uint16) { if x_ == 1 { // bit instructions take 20 cycles, others take 23 - z.cycleCount += 20 + z.TStates += 20 } else { z.wb(addr, result) - z.cycleCount += 23 + z.TStates += 23 } } diff --git a/opcodesDDFD.go b/opcodesDDFD.go index 813be87..88b3fbf 100644 --- a/opcodesDDFD.go +++ b/opcodesDDFD.go @@ -2,7 +2,7 @@ package z80go // executes A DD/FD opcode (IZ = IX or IY) func (z *CPU) execOpcodeDDFD(opcode byte, iz *uint16) { - z.cycleCount += uint32(cyclesDDFD[opcode]) + z.TStates += uint32(cyclesDDFD[opcode]) z.incR() switch opcode { diff --git a/opcodesED.go b/opcodesED.go index 6bfa948..3f43c1c 100644 --- a/opcodesED.go +++ b/opcodesED.go @@ -4,7 +4,7 @@ import log "github.com/sirupsen/logrus" // executes A ED opcode func (z *CPU) execOpcodeED(opcode byte) { - z.cycleCount += uint32(cyclesED[opcode]) + z.TStates += uint32(cyclesED[opcode]) z.incR() switch opcode { case 0x47: @@ -43,7 +43,7 @@ func (z *CPU) execOpcodeED(opcode byte) { if z.GetBC() != 0 { z.PC -= 2 - z.cycleCount += 5 + z.TStates += 5 z.MemPtr = z.PC + 1 } } // ldir @@ -56,7 +56,7 @@ func (z *CPU) execOpcodeED(opcode byte) { if z.GetBC() != 0 { z.PC -= 2 - z.cycleCount += 5 + z.TStates += 5 z.MemPtr = z.PC + 1 } } // lddr @@ -70,7 +70,7 @@ func (z *CPU) execOpcodeED(opcode byte) { z.cpi() if z.GetBC() != 0 && !z.Flags.Z { z.PC -= 2 - z.cycleCount += 5 + z.TStates += 5 z.MemPtr = z.PC + 1 } else { //z.mem_ptr++ @@ -81,7 +81,7 @@ func (z *CPU) execOpcodeED(opcode byte) { z.cpd() if z.GetBC() != 0 && !z.Flags.Z { z.PC -= 2 - z.cycleCount += 5 + z.TStates += 5 z.MemPtr = z.PC + 1 } else { //z.mem_ptr++ @@ -128,7 +128,7 @@ func (z *CPU) execOpcodeED(opcode byte) { z.ini() if z.B > 0 { z.PC -= 2 - z.cycleCount += 5 + z.TStates += 5 } case 0xAA: // ind @@ -138,7 +138,7 @@ func (z *CPU) execOpcodeED(opcode byte) { z.ind() if z.B > 0 { z.PC -= 2 - z.cycleCount += 5 + z.TStates += 5 } case 0x41: z.core.IOWrite(z.GetBC(), z.B) // out (c), b @@ -172,7 +172,7 @@ func (z *CPU) execOpcodeED(opcode byte) { z.outi() if z.B > 0 { z.PC -= 2 - z.cycleCount += 5 + z.TStates += 5 } case 0xAB: z.outd() // outd @@ -180,7 +180,7 @@ func (z *CPU) execOpcodeED(opcode byte) { // otdr z.outd() if z.B > 0 { - z.cycleCount += 5 + z.TStates += 5 z.PC -= 2 } diff --git a/z80go.go b/z80go.go index 5075cff..2380154 100644 --- a/z80go.go +++ b/z80go.go @@ -106,17 +106,19 @@ type CPU struct { Iff1 bool `json:"iff1,omitempty"` Iff2 bool `json:"iff2,omitempty"` Halted bool `json:"halted,omitempty"` - CycleCount uint32 `json:"cycleCount,omitempty"` - IntOccurred bool `json:"intOccurred,omitempty"` - NmiOccurred bool `json:"interruptOccurred,omitempty"` + TStatesPart uint32 `json:"TStatesPart,omitempty"` + // mw hidden register MemPtr uint16 // methods to access CPU to memory and IO ports of computer - core MemIoRW + core MemIoRW + + // Data-Bus state for IM2 INT intData byte // Total CPU cycle count (t-states) - cycleCount uint32 + TStates uint32 + // map of memory access memAccess map[uint16]byte // enable or disable code coverage marking @@ -128,8 +130,11 @@ type CPU struct { // map of stack data marking extendedStack map[uint16]PushValueType - iffDelay byte + iffDelay byte + // intPending is true if Interrupt is pending intPending bool + + // nmiPending is true if Interrupt is pending nmiPending bool } diff --git a/z80go_test.go b/z80go_test.go index 08a5e9c..4feca21 100644 --- a/z80go_test.go +++ b/z80go_test.go @@ -438,9 +438,7 @@ func setComputerState(test Z80TestIn) { Iff1: test.state.IFF1, Iff2: test.state.IFF2, Halted: test.state.isHalted, - CycleCount: 0, - IntOccurred: false, - NmiOccurred: false, + TStatesPart: 0, MemPtr: test.registers.MemPtr, }