diff --git a/cpu.go b/cpu.go index 2c77d5d..f5d201b 100644 --- a/cpu.go +++ b/cpu.go @@ -22,6 +22,7 @@ func NewCPU(core MemIoRW) *CPU { // z.codeCoverage map[uint16]bool z.extendedStackEnabled = false //z.extendedStack [65536]uint8 + z.extendedStack = map[uint16]PushValueType{} return &z } @@ -68,15 +69,10 @@ func (z *CPU) SetState(state *CPU) { z.I = state.I z.R = state.R - z.Flags.S = state.Flags.S - z.Flags.Z = state.Flags.Z - z.Flags.Y = state.Flags.Y - z.Flags.H = state.Flags.H - z.Flags.X = state.Flags.X - z.Flags.P = state.Flags.P - z.Flags.N = state.Flags.N - z.Flags.C = state.Flags.C + z.Flags = state.Flags + z.FlagsAlt = state.FlagsAlt + z.MemPtr = state.MemPtr z.IMode = state.IMode z.Iff1 = state.Iff1 z.Iff2 = state.Iff2 @@ -108,8 +104,8 @@ func (z *CPU) GetState() *CPU { SP: z.SP, PC: z.PC, - Flags: z.flags(), - FlagsAlt: z.altFlags(), + Flags: z.Flags, + FlagsAlt: z.FlagsAlt, IMode: z.IMode, Iff1: z.Iff1, Iff2: z.Iff2, @@ -117,7 +113,7 @@ func (z *CPU) GetState() *CPU { CycleCount: z.cycleCount, IntOccurred: z.IntOccurred, NmiOccurred: z.NmiOccurred, - memPtr: z.memPtr, + MemPtr: z.MemPtr, } } @@ -147,17 +143,18 @@ func (z *CPU) CodeCoverage() map[uint16]bool { func (z *CPU) SetExtendedStack(enabled bool) { z.extendedStackEnabled = enabled if enabled { - for addr := 0; addr < 65536; addr++ { - z.extendedStack[addr] = PushValueTypeDefault - } + clear(z.extendedStack) + //for addr := 0; addr < 65536; addr++ { + // z.extendedStack[uint16(addr)] = PushValueTypeDefault + //} } } // ExtendedStack - return array with markers of PushValueType* for each byte of memory -func (z *CPU) ExtendedStack() ([]byte, error) { +func (z *CPU) ExtendedStack() (map[uint16]PushValueType, error) { var err error if !z.extendedStackEnabled { err = errors.New("error, z80: ExtendedStack disabled") } - return z.extendedStack[:], err + return z.extendedStack, err } diff --git a/dis/z80disasm.go b/dis/z80disasm.go index 45f9653..08b3578 100644 --- a/dis/z80disasm.go +++ b/dis/z80disasm.go @@ -2,20 +2,21 @@ package dis import ( "fmt" - "okemu/z80" "strings" + + "github.com/romychs/z80go" ) type Disassembler struct { pc uint16 - core z80.MemIoRW + core z80go.MemIoRW } type Disassembly interface { Disassm(pc uint16) string } -func NewDisassembler(core z80.MemIoRW) *Disassembler { +func NewDisassembler(core z80go.MemIoRW) *Disassembler { d := Disassembler{ pc: 0, core: core, diff --git a/dis/z80disasm_test.go b/dis/z80disasm_test.go index a904da5..47b86da 100644 --- a/dis/z80disasm_test.go +++ b/dis/z80disasm_test.go @@ -46,6 +46,7 @@ func setMemory(addr uint16, value []byte) { var test = []byte{0x31, 0x2c, 0x05, 0x11, 0x0e, 0x01, 0x0e, 0x09, 0xcd, 0x05, 0x00, 0xc3, 0x00, 0x00} func Test_LD_SP_nn(t *testing.T) { + t.Logf("Disassembler Z80 test") expected := " 0100 LD SP, 0x052C" setMemory(0x100, test) res := disasm.Disassm(0x100) diff --git a/go.mod b/go.mod index 28abe3a..88dd69f 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,7 @@ go 1.25 require ( github.com/sirupsen/logrus v1.9.4 - gopkg.in/yaml.v3 v3.0.1 + gopkg.in/yaml.v3 v3.0.1 ) + +require golang.org/x/sys v0.13.0 // indirect diff --git a/go.sum b/go.sum index 8d3097c..f545959 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,6 @@ +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/helper.go b/helper.go index 3878f0b..7fea54c 100644 --- a/helper.go +++ b/helper.go @@ -191,7 +191,7 @@ func (z *CPU) Reset() { z.SP = 0xFFFF z.IX = 0 z.IY = 0 - z.memPtr = 0 + z.MemPtr = 0 z.A = 0xFF z.B = 0 @@ -213,7 +213,7 @@ func (z *CPU) Reset() { z.R = 0 z.Flags.SetFlags(0xff) - z.FlagsAlt.SetFlags(0xff) + z.FlagsAlt.SetFlags(0x00) z.iffDelay = 0 z.IMode = 0 diff --git a/opcodes.go b/opcodes.go index 44f8073..462bd28 100644 --- a/opcodes.go +++ b/opcodes.go @@ -5,7 +5,7 @@ import log "github.com/sirupsen/logrus" // jumps to an address func (z *CPU) jump(addr uint16) { z.PC = addr - z.memPtr = addr + z.MemPtr = addr } // jumps to next word in memory if condition is true @@ -14,7 +14,7 @@ func (z *CPU) condJump(condition bool) { if condition { z.jump(addr) } - z.memPtr = addr + z.MemPtr = addr } // calls to next word in memory @@ -22,7 +22,7 @@ func (z *CPU) call(addr uint16) { z.pushW(z.PC) z.extendedStack[z.SP] = PushValueTypeCall z.PC = addr - z.memPtr = addr + z.MemPtr = addr } // calls to next word in memory if condition is true @@ -32,13 +32,13 @@ func (z *CPU) condCall(condition bool) { z.call(addr) z.cycleCount += 7 } - z.memPtr = addr + z.MemPtr = addr } // returns from subroutine func (z *CPU) ret() { z.PC = z.popW() - z.memPtr = z.PC + z.MemPtr = z.PC } // returns from subroutine if condition is true @@ -55,7 +55,7 @@ func (z *CPU) jr(offset byte) { } else { z.PC += uint16(offset) } - z.memPtr = z.PC + z.MemPtr = z.PC } func (z *CPU) condJr(condition bool) { @@ -101,7 +101,7 @@ func (z *CPU) addW(a uint16, b uint16, cy bool) uint16 { 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 + z.MemPtr = a + 1 return result } @@ -111,7 +111,7 @@ func (z *CPU) subW(a uint16, b uint16, cy bool) uint16 { msb := z.subB(byte(a>>8), byte(b>>8), z.Flags.C) result := (uint16(msb) << 8) | uint16(lsb) z.Flags.Z = result == 0 - z.memPtr = a + 1 + z.MemPtr = a + 1 return result } @@ -388,14 +388,14 @@ func (z *CPU) cpi() { z.Flags.Y = val&0x02 != 0 z.Flags.P = z.bc() != 0 z.Flags.C = cf - z.memPtr += 1 + z.MemPtr += 1 } func (z *CPU) cpd() { z.cpi() // same as cpi but HL is decremented instead of incremented z.setHL(z.hl() - 2) - z.memPtr -= 2 + z.MemPtr -= 2 } func (z *CPU) inRC(r *byte) { @@ -410,7 +410,7 @@ 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 + z.MemPtr = z.bc() + 1 z.B-- other := val + z.C + 1 @@ -432,7 +432,7 @@ func (z *CPU) ini() { func (z *CPU) ind() { val := z.core.IORead(z.bc()) z.wb(z.hl(), val) - z.memPtr = z.bc() - 1 + z.MemPtr = z.bc() - 1 z.B-- other := val + z.C - 1 @@ -451,13 +451,7 @@ func (z *CPU) ind() { z.updateXY(z.B) z.setHL(z.hl() - 1) } - -func (z *CPU) outi() { - val := z.rb(z.hl()) - z.B-- - z.memPtr = z.bc() + 1 - z.core.IOWrite(z.bc(), val) - z.setHL(z.hl() + 1) +func (z *CPU) outCmnFlags(val uint8) { other := val + z.L z.Flags.N = val&0x80 != 0 if other < val { @@ -473,25 +467,22 @@ func (z *CPU) outi() { z.updateXY(z.B) } +func (z *CPU) outi() { + val := z.rb(z.hl()) + z.B-- + z.MemPtr = z.bc() + 1 + z.core.IOWrite(z.bc(), val) + z.setHL(z.hl() + 1) + z.outCmnFlags(val) +} + func (z *CPU) outd() { val := z.rb(z.hl()) z.B-- - z.memPtr = z.bc() - 1 + z.MemPtr = z.bc() - 1 z.core.IOWrite(z.bc(), val) z.setHL(z.hl() - 1) - other := val + z.L - z.Flags.N = val&0x80 != 0 - if other < val { - z.Flags.H = true - z.Flags.C = true - } else { - z.Flags.H = false - z.Flags.C = false - } - z.Flags.P = parity((other & 0x07) ^ z.B) - z.Flags.Z = z.B == 0 - z.Flags.S = z.B&0x80 != 0 - z.updateXY(z.B) + z.outCmnFlags(val) } func (z *CPU) daa() { @@ -529,7 +520,7 @@ func (z *CPU) displace(baseAddr uint16, offset byte) uint16 { addr += uint16(offset) } //addr := baseAddr + uint16(displacement) - z.memPtr = addr + z.MemPtr = addr return addr } @@ -751,29 +742,29 @@ func (z *CPU) execOpcode(opcode byte) { case 0x0A: // ld a,(bc) z.A = z.rb(z.bc()) - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x1A: // ld a,(de) z.A = z.rb(z.de()) - z.memPtr = z.de() + 1 + z.MemPtr = z.de() + 1 case 0x3A: // ld a,(**) addr := z.nextW() z.A = z.rb(addr) - z.memPtr = addr + 1 + 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.MemPtr = (uint16(z.A) << 8) | ((z.bc() + 1) & 0xFF) case 0x12: // ld (de),a z.wb(z.de(), z.A) - z.memPtr = (uint16(z.A) << 8) | ((z.de() + 1) & 0xFF) + z.MemPtr = (uint16(z.A) << 8) | ((z.de() + 1) & 0xFF) case 0x32: // ld (**),a addr := z.nextW() z.wb(addr, z.A) - z.memPtr = (uint16(z.A) << 8) | ((addr + 1) & 0xFF) + z.MemPtr = (uint16(z.A) << 8) | ((addr + 1) & 0xFF) case 0x01: z.setBC(z.nextW()) // ld bc,** case 0x11: @@ -787,12 +778,12 @@ func (z *CPU) execOpcode(opcode byte) { // ld hl,(**) addr := z.nextW() z.setHL(z.rw(addr)) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x22: // ld (**),hl addr := z.nextW() z.ww(addr, z.hl()) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0xF9: z.SP = z.hl() // ld sp,hl @@ -806,7 +797,7 @@ func (z *CPU) execOpcode(opcode byte) { val := z.rw(z.SP) z.ww(z.SP, z.hl()) z.setHL(val) - z.memPtr = val + z.MemPtr = val case 0x87: z.A = z.addB(z.A, z.A, false) // add a,a case 0x80: @@ -1103,7 +1094,7 @@ func (z *CPU) execOpcode(opcode byte) { z.condJr(z.B != 0) // djnz * case 0x18: z.PC += uint16(z.nextB()) // jr * - z.memPtr = z.PC + z.MemPtr = z.PC case 0x20: z.condJr(!z.Flags.Z) // jr nz, * case 0x28: @@ -1202,19 +1193,19 @@ func (z *CPU) execOpcode(opcode byte) { // in a,(n) port := (uint16(z.A) << 8) | uint16(z.nextB()) z.A = z.core.IORead(port) - z.memPtr = port + 1 // (uint16(a) << 8) | (uint16(z.a+1) & 0x00ff) + z.MemPtr = port + 1 // (uint16(a) << 8) | (uint16(z.a+1) & 0x00ff) case 0xD3: // out (n), a port := uint16(z.nextB()) z.core.IOWrite(port, z.A) - z.memPtr = ((port + 1) & 0x00ff) | (uint16(z.A) << 8) + z.MemPtr = ((port + 1) & 0x00ff) | (uint16(z.A) << 8) case 0x08: // ex af,af' a := z.A - f := z.Flags.Flags() + f := z.Flags.AsByte() z.A = z.AAlt - z.Flags.SetFlags(z.FlagsAlt.Flags()) + z.Flags.SetFlags(z.FlagsAlt.AsByte()) z.AAlt = a z.FlagsAlt.SetFlags(f) diff --git a/opcodesCB.go b/opcodesCB.go index 5131b06..f478d9c 100644 --- a/opcodesCB.go +++ b/opcodesCB.go @@ -63,7 +63,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.updateXY(byte(z.MemPtr >> 8)) z.cycleCount += 4 } diff --git a/opcodesDDFD.go b/opcodesDDFD.go index 36e8aa6..07d6937 100644 --- a/opcodesDDFD.go +++ b/opcodesDDFD.go @@ -96,11 +96,11 @@ func (z *CPU) execOpcodeDDFD(opcode byte, iz *uint16) { case 0x2A: addr := z.nextW() *iz = z.rw(addr) // ld iz,(**) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x22: addr := z.nextW() z.ww(addr, *iz) // ld (**),iz - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x21: *iz = z.nextW() // ld iz,** case 0x36: @@ -192,7 +192,7 @@ func (z *CPU) execOpcodeDDFD(opcode byte, iz *uint16) { val := z.rw(z.SP) z.ww(z.SP, *iz) *iz = val - z.memPtr = val + z.MemPtr = val case 0xCB: addr := z.displace(*iz, z.nextB()) op := z.nextB() diff --git a/opcodesED.go b/opcodesED.go index c4e294d..635b055 100644 --- a/opcodesED.go +++ b/opcodesED.go @@ -44,7 +44,7 @@ func (z *CPU) execOpcodeED(opcode byte) { if z.bc() != 0 { z.PC -= 2 z.cycleCount += 5 - z.memPtr = z.PC + 1 + z.MemPtr = z.PC + 1 } } // ldir @@ -57,7 +57,7 @@ func (z *CPU) execOpcodeED(opcode byte) { if z.bc() != 0 { z.PC -= 2 z.cycleCount += 5 - z.memPtr = z.PC + 1 + z.MemPtr = z.PC + 1 } } // lddr @@ -71,7 +71,7 @@ func (z *CPU) execOpcodeED(opcode byte) { if z.bc() != 0 && !z.Flags.Z { z.PC -= 2 z.cycleCount += 5 - z.memPtr = z.PC + 1 + z.MemPtr = z.PC + 1 } else { //z.mem_ptr++ } @@ -82,15 +82,15 @@ func (z *CPU) execOpcodeED(opcode byte) { if z.bc() != 0 && !z.Flags.Z { z.PC -= 2 z.cycleCount += 5 - z.memPtr = z.PC + 1 + z.MemPtr = z.PC + 1 } else { //z.mem_ptr++ } case 0x40: z.inRC(&z.B) // in b, (c) - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x48: - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 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.bc() + 1 case 0x58: // in e, (c) z.inRC(&z.E) - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 z.updateXY(z.E) case 0x60: z.inRC(&z.H) // in h, (c) - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x68: z.inRC(&z.L) // in l, (c) - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 z.updateXY(z.L) case 0x70: // in (c) var val byte z.inRC(&val) - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x78: // in a, (c) z.inRC(&z.A) - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 z.updateXY(z.A) case 0xA2: z.ini() // ini @@ -142,29 +142,29 @@ func (z *CPU) execOpcodeED(opcode byte) { } case 0x41: z.core.IOWrite(z.bc(), z.B) // out (c), b - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x49: z.core.IOWrite(z.bc(), z.C) // out (c), c - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x51: z.core.IOWrite(z.bc(), z.D) // out (c), d - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x59: z.core.IOWrite(z.bc(), z.E) // out (c), e - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x61: z.core.IOWrite(z.bc(), z.H) // out (c), h - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x69: z.core.IOWrite(z.bc(), z.L) // out (c), l - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x71: z.core.IOWrite(z.bc(), 0) // out (c), 0 - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0x79: // out (c), a z.core.IOWrite(z.bc(), z.A) - z.memPtr = z.bc() + 1 + z.MemPtr = z.bc() + 1 case 0xA3: z.outi() // outi case 0xB3: @@ -204,42 +204,42 @@ func (z *CPU) execOpcodeED(opcode byte) { // ld (**), bc addr := z.nextW() z.ww(addr, z.bc()) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x53: // ld (**), de addr := z.nextW() z.ww(addr, z.de()) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x63: // ld (**), hl addr := z.nextW() z.ww(addr, z.hl()) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x73: // ld (**), hl addr := z.nextW() z.ww(addr, z.SP) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x4B: // ld bc, (**) addr := z.nextW() z.setBC(z.rw(addr)) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x5B: // ld de, (**) addr := z.nextW() z.setDE(z.rw(addr)) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x6B: // ld hl, (**) addr := z.nextW() z.setHL(z.rw(addr)) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x7B: // ld sp,(**) addr := z.nextW() z.SP = z.rw(addr) - z.memPtr = addr + 1 + z.MemPtr = addr + 1 case 0x44, 0x54, 0x64, 0x74, 0x4C, 0x5C, 0x6C, 0x7C: z.A = z.subB(0, z.A, false) // neg case 0x46, 0x4e, 0x66, 0x6e: @@ -261,7 +261,7 @@ 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.hl() + 1 case 0x6F: // rld a := z.A @@ -274,7 +274,7 @@ 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.hl() + 1 default: log.Errorf("Unknown ED opcode: %02X\n", opcode) } diff --git a/z80go.go b/z80go.go index faf135f..8fee9d6 100644 --- a/z80go.go +++ b/z80go.go @@ -59,52 +59,78 @@ type FlagsType struct { // CPU - Processor state type CPU struct { - A byte `json:"a,omitempty"` - B byte `json:"b,omitempty"` - C byte `json:"c,omitempty"` - D byte `json:"d,omitempty"` - E byte `json:"e,omitempty"` - H byte `json:"h,omitempty"` - L byte `json:"l,omitempty"` - AAlt byte `json:"AAlt,omitempty"` - BAlt byte `json:"BAlt,omitempty"` - CAlt byte `json:"CAlt,omitempty"` - DAlt byte `json:"DAlt,omitempty"` - EAlt byte `json:"EAlt,omitempty"` - HAlt byte `json:"HAlt,omitempty"` - LAlt byte `json:"LAlt,omitempty"` - IX uint16 `json:"IX,omitempty"` - IY uint16 `json:"IY,omitempty"` - I byte `json:"i,omitempty"` - R byte `json:"r,omitempty"` - SP uint16 `json:"SP,omitempty"` - PC uint16 `json:"PC,omitempty"` - Flags FlagsType `json:"flags"` - FlagsAlt FlagsType `json:"flagsAlt"` - IMode byte `json:"IMode,omitempty"` - 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"` - memPtr uint16 - core MemIoRW - intData byte - cycleCount uint32 // cycle count (t-states) - memAccess map[uint16]byte - codeCoverageEnabled bool - codeCoverage map[uint16]bool + // base register set + A byte `json:"a,omitempty"` + B byte `json:"b,omitempty"` + C byte `json:"c,omitempty"` + D byte `json:"d,omitempty"` + E byte `json:"e,omitempty"` + H byte `json:"h,omitempty"` + L byte `json:"l,omitempty"` + // alternate register set + AAlt byte `json:"AAlt,omitempty"` + BAlt byte `json:"BAlt,omitempty"` + CAlt byte `json:"CAlt,omitempty"` + DAlt byte `json:"DAlt,omitempty"` + EAlt byte `json:"EAlt,omitempty"` + HAlt byte `json:"HAlt,omitempty"` + LAlt byte `json:"LAlt,omitempty"` + // index registers + IX uint16 `json:"IX,omitempty"` + IY uint16 `json:"IY,omitempty"` + + I byte `json:"i,omitempty"` + + // memory refresh register + R byte `json:"r,omitempty"` + + // stack pointer + SP uint16 `json:"SP,omitempty"` + + // program counter + PC uint16 `json:"PC,omitempty"` + + // cpu flags + Flags FlagsType `json:"flags"` + + // alternate cpu flags + FlagsAlt FlagsType `json:"flagsAlt"` + + // Interrupt mode + IMode byte `json:"IMode,omitempty"` + 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"` + // mw hidden register + MemPtr uint16 + + // methods to access CPU to memory and IO ports of computer + core MemIoRW + intData byte + // Total CPU cycle count (t-states) + cycleCount uint32 + // map of memory access + memAccess map[uint16]byte + // enable or disable code coverage marking + codeCoverageEnabled bool + // map of code coverage + codeCoverage map[uint16]bool + // enable of disable stack data marking extendedStackEnabled bool - extendedStack map[uint16]PushValueType - iffDelay byte - intPending bool - nmiPending bool + // map of stack data marking + extendedStack map[uint16]PushValueType + + iffDelay byte + intPending bool + nmiPending bool } -// Flags - return flags as byte value +// AsByte - return flags as byte value // Used to simplify manipulations with AF register from debugger -func (f *FlagsType) Flags() byte { +func (f *FlagsType) AsByte() byte { var flags byte = 0 if f.S { flags |= 0x80 @@ -174,19 +200,19 @@ func (z *CPU) IIFStr() string { return string(flags) } -//// Flags - return state of CPU flags -//func Flags(f byte) FlagsType { -// return FlagsType{ -// S: f&0x80 != 0, -// Z: f&0x40 != 0, -// Y: f&0x20 != 0, -// H: f&0x10 != 0, -// X: f&0x08 != 0, -// P: f&0x04 != 0, -// N: f&0x02 != 0, -// C: f&0x01 != 0, -// } -//} +// NewFlags build new object of FlagsType from byte +func NewFlags(f byte) *FlagsType { + return &FlagsType{ + S: f&0x80 != 0, + Z: f&0x40 != 0, + Y: f&0x20 != 0, + H: f&0x10 != 0, + X: f&0x08 != 0, + P: f&0x04 != 0, + N: f&0x02 != 0, + C: f&0x01 != 0, + } +} // SetFlags - set CPU flags by flags byte. // Used to simplify manipulations with AF register from debugger diff --git a/z80go_test.go b/z80go_test.go index 54612e1..96026bf 100644 --- a/z80go_test.go +++ b/z80go_test.go @@ -4,12 +4,11 @@ import ( "bufio" "bytes" _ "embed" - "okemu/z80" - "okemu/z80/c99" "strconv" "strings" "testing" + "github.com/romychs/z80go" log "github.com/sirupsen/logrus" ) @@ -82,7 +81,7 @@ var testIn []byte var testExpected []byte type Computer struct { - cpu *c99.Z80 + cpu *z80go.CPU memory [65536]byte ports [256]byte } @@ -94,8 +93,6 @@ var computer Computer var testNames []string -//var z80 *c99.Z80 - func init() { z80TestsIn = make(map[string]Z80TestIn) z80TestsExpected = make(map[string]Expect) @@ -107,7 +104,7 @@ func init() { for addr := 0; addr < 255; addr++ { computer.ports[addr] = 0 } - computer.cpu = c99.New(&computer) + computer.cpu = z80go.NewCPU(&computer) } func (c *Computer) M1MemRead(addr uint16) byte { @@ -403,7 +400,8 @@ func TestZ80Fuse(t *testing.T) { } cy := uint32(0) for { - cy += computer.cpu.RunInstruction() + c, _ := computer.cpu.RunInstruction() + cy += c if cy >= uint32(exp.state.tStates) { break } @@ -413,38 +411,37 @@ func TestZ80Fuse(t *testing.T) { } func setComputerState(test Z80TestIn) { - state := z80.CPU{ - A: byte(test.registers.AF >> 8), - B: byte(test.registers.BC >> 8), - C: byte(test.registers.BC), - D: byte(test.registers.DE >> 8), - E: byte(test.registers.DE), - H: byte(test.registers.HL >> 8), - L: byte(test.registers.HL), - AAlt: byte(test.registers.AFa >> 8), - BAlt: byte(test.registers.BCa >> 8), - CAlt: byte(test.registers.BCa), - DAlt: byte(test.registers.DEa >> 8), - EAlt: byte(test.registers.DEa), - HAlt: byte(test.registers.HLa >> 8), - LAlt: byte(test.registers.HLa), - IX: test.registers.IX, - IY: test.registers.IY, - I: test.state.I, - R: test.state.R, - SP: test.registers.SP, - PC: test.registers.PC, - Flags: z80.GetFlags(byte(test.registers.AF)), - FlagsAlt: z80.GetFlags(byte(test.registers.AFa)), - IMode: test.state.IM, - Iff1: test.state.IFF1, - Iff2: test.state.IFF2, - Halted: test.state.isHalted, - DoDelayedDI: false, - DoDelayedEI: false, - CycleCount: 0, - InterruptOccurred: false, - MemPtr: test.registers.MemPtr, + state := z80go.CPU{ + A: byte(test.registers.AF >> 8), + B: byte(test.registers.BC >> 8), + C: byte(test.registers.BC), + D: byte(test.registers.DE >> 8), + E: byte(test.registers.DE), + H: byte(test.registers.HL >> 8), + L: byte(test.registers.HL), + AAlt: byte(test.registers.AFa >> 8), + BAlt: byte(test.registers.BCa >> 8), + CAlt: byte(test.registers.BCa), + DAlt: byte(test.registers.DEa >> 8), + EAlt: byte(test.registers.DEa), + HAlt: byte(test.registers.HLa >> 8), + LAlt: byte(test.registers.HLa), + IX: test.registers.IX, + IY: test.registers.IY, + I: test.state.I, + R: test.state.R, + SP: test.registers.SP, + PC: test.registers.PC, + Flags: *z80go.NewFlags(byte(test.registers.AF)), + FlagsAlt: *z80go.NewFlags(byte(test.registers.AFa)), + IMode: test.state.IM, + Iff1: test.state.IFF1, + Iff2: test.state.IFF2, + Halted: test.state.isHalted, + CycleCount: 0, + IntOccurred: false, + NmiOccurred: false, + MemPtr: test.registers.MemPtr, } // Setup CPU @@ -577,12 +574,12 @@ func checkComputerState(t *testing.T, name string) { } // FLAGS - if lo(exp.registers.AF) != state.Flags.GetFlags() { - t.Errorf("%s: Expected Flags to be %08b, got %08b", name, lo(exp.registers.AF), state.Flags.GetFlags()) + if lo(exp.registers.AF) != state.Flags.AsByte() { + t.Errorf("%s: Expected Flags to be %08b, got %08b", name, lo(exp.registers.AF), state.Flags.AsByte()) } - if lo(exp.registers.AFa) != state.FlagsAlt.GetFlags() { - t.Errorf("%s: Expected Flags' to be %08b, got %08b", name, lo(exp.registers.AFa), state.FlagsAlt.GetFlags()) + if lo(exp.registers.AFa) != state.FlagsAlt.AsByte() { + t.Errorf("%s: Expected Flags' to be %08b, got %08b", name, lo(exp.registers.AFa), state.FlagsAlt.AsByte()) } // Check memory