From ff2e10afdb1656c0579bb7990e634fbd11a03cf0 Mon Sep 17 00:00:00 2001 From: Roman Boykov Date: Wed, 1 Apr 2026 20:06:51 +0300 Subject: [PATCH] z80go: v1.0.0 --- README.md | 5 +++-- dis/z80disasm.go | 3 ++- dis/z80disasm_test.go | 12 ++++++------ go.mod | 5 +---- go.sum | 8 +++++++- opcodes.go | 40 ++++++++++++++++++++-------------------- 6 files changed, 39 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index ad113b0..4a76335 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Z80 processor emulator and disassembler -Pass ZEXALL tests. Undocumented instructions supported. +CPU emulator pass all ZEXALL test and Fuse Z80 test suite. +Undocumented instructions and flags supported. -Based on ideas of [Superzazu Z80 emulator](https://github.com/superzazu/z80) \ No newline at end of file +Based on ideas of [Superzazu Z80 emulator](https://github.com/superzazu/z80) diff --git a/dis/z80disasm.go b/dis/z80disasm.go index 08b3578..8de81de 100644 --- a/dis/z80disasm.go +++ b/dis/z80disasm.go @@ -354,7 +354,6 @@ func (d *Disassembler) getRel() string { } var shiftOps = []string{"RLC", "RRC", "RL", "RR", "SLA", "SRA", "SLL", "SRL"} -var bitOps = []string{"BIT", "RES", "SET"} // opocodeCB disassemble Z80 Opcodes, with CB first byte func (d *Disassembler) opocodeCB() string { @@ -470,6 +469,8 @@ func (d *Disassembler) opocodeDD(op byte) string { return strings.ReplaceAll(result, "ii", reg) } +//var bitOps = []string{"BIT", "RES", "SET"} + func (d *Disassembler) opocodeDDCB(op1 byte, op2 byte) string { opcode := d.getByte() result := "" diff --git a/dis/z80disasm_test.go b/dis/z80disasm_test.go index 47b86da..c3dd5cb 100644 --- a/dis/z80disasm_test.go +++ b/dis/z80disasm_test.go @@ -24,7 +24,7 @@ func (t *TestComp) IORead(port uint16) byte { } func (t *TestComp) IOWrite(port uint16, val byte) { - // + print("PORT[0x%04X]=0x%04X\n", port, val) } var testComp *TestComp @@ -51,7 +51,7 @@ func Test_LD_SP_nn(t *testing.T) { setMemory(0x100, test) res := disasm.Disassm(0x100) if res != expected { - t.Errorf("Error disasm LD SP, nn, result '%s', expected '%s'", res, expected) + t.Errorf("Error disassm LD SP, nn, result '%s', expected '%s'", res, expected) } } @@ -60,7 +60,7 @@ func Test_LD_DE_nn(t *testing.T) { setMemory(0x100, test) res := disasm.Disassm(0x103) if res != expected { - t.Errorf("Error disasm LD DE, nn, result '%s', expected '%s'", res, expected) + t.Errorf("Error disassm LD DE, nn, result '%s', expected '%s'", res, expected) } } @@ -69,7 +69,7 @@ func Test_LD_C_n(t *testing.T) { setMemory(0x100, test) res := disasm.Disassm(0x106) if res != expected { - t.Errorf("Error disasm LD C, n, result '%s', expected '%s'", res, expected) + t.Errorf("Error disassm LD C, n, result '%s', expected '%s'", res, expected) } } @@ -78,7 +78,7 @@ func Test_CALL_nn(t *testing.T) { setMemory(0x100, test) res := disasm.Disassm(0x108) if res != expected { - t.Errorf("Error disasm CALL nn, result '%s', expected '%s'", res, expected) + t.Errorf("Error disassm CALL nn, result '%s', expected '%s'", res, expected) } } @@ -87,6 +87,6 @@ func Test_JP_nn(t *testing.T) { setMemory(0x100, test) res := disasm.Disassm(0x10b) if res != expected { - t.Errorf("Error disasm JP nn, result '%s', expected '%s'", res, expected) + t.Errorf("Error disassm JP nn, result '%s', expected '%s'", res, expected) } } diff --git a/go.mod b/go.mod index 88dd69f..0933cae 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,6 @@ module github.com/romychs/z80go go 1.25 -require ( - github.com/sirupsen/logrus v1.9.4 - gopkg.in/yaml.v3 v3.0.1 -) +require github.com/sirupsen/logrus v1.9.4 require golang.org/x/sys v0.13.0 // indirect diff --git a/go.sum b/go.sum index f545959..9e91db8 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,12 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/opcodes.go b/opcodes.go index 462bd28..1e2e0d1 100644 --- a/opcodes.go +++ b/opcodes.go @@ -86,7 +86,7 @@ func (z *CPU) addB(a byte, b byte, cy bool) byte { return result } -// SUBtract Byte: subtracts two bytes (with optional carry) +// subB Subtract two bytes (with optional carry) func (z *CPU) subB(a byte, b byte, cy bool) byte { val := z.addB(a, ^b, !cy) z.Flags.C = !z.Flags.C @@ -95,7 +95,7 @@ func (z *CPU) subB(a byte, b byte, cy bool) byte { return val } -// ADD Word: adds two words together +// addW Adds two words together 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) @@ -105,7 +105,7 @@ func (z *CPU) addW(a uint16, b uint16, cy bool) uint16 { return result } -// SUBtract Word: subtracts two words (with optional carry) +// 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) @@ -115,7 +115,7 @@ func (z *CPU) subW(a uint16, b uint16, cy bool) uint16 { return result } -// Adds A word to HL +// addHL Adds A word to HL func (z *CPU) addHL(val uint16) { sf := z.Flags.S zf := z.Flags.Z @@ -893,19 +893,19 @@ func (z *CPU) execOpcode(opcode byte) { z.Halted = true // halt z.PC-- case 0x3C: - z.A = z.inc(z.A) // inc a + z.A = z.inc(z.A) case 0x04: - z.B = z.inc(z.B) // inc b + z.B = z.inc(z.B) case 0x0C: - z.C = z.inc(z.C) // inc c + z.C = z.inc(z.C) case 0x14: - z.D = z.inc(z.D) // inc d + z.D = z.inc(z.D) case 0x1C: - z.E = z.inc(z.E) // inc e + z.E = z.inc(z.E) case 0x24: - z.H = z.inc(z.H) // inc h + z.H = z.inc(z.H) case 0x2C: - z.L = z.inc(z.L) // inc l + z.L = z.inc(z.L) case 0x34: // inc (hl) result := z.inc(z.rb(z.hl())) @@ -965,14 +965,14 @@ func (z *CPU) execOpcode(opcode byte) { z.Flags.N = false z.updateXY(z.A | z.f()) case 0x07: - // rlca (rotate left) + // Rotate left z.Flags.C = z.A&0x80 != 0 z.A = (z.A << 1) | bToByte(z.Flags.C) z.Flags.N = false z.Flags.H = false z.updateXY(z.A) case 0x0F: - // rrca (rotate right) + // Rotate right z.Flags.C = z.A&1 != 0 z.A = (z.A >> 1) | (bToByte(z.Flags.C) << 7) z.Flags.N = false @@ -1052,19 +1052,19 @@ func (z *CPU) execOpcode(opcode byte) { z.lOr(z.nextB()) // or * case 0xBF: - z.cp(z.A) // cp a + z.cp(z.A) case 0xB8: - z.cp(z.B) // cp b + z.cp(z.B) case 0xB9: - z.cp(z.C) // cp c + z.cp(z.C) case 0xBA: - z.cp(z.D) // cp d + z.cp(z.D) case 0xBB: - z.cp(z.E) // cp e + z.cp(z.E) case 0xBC: - z.cp(z.H) // cp h + z.cp(z.H) case 0xBD: - z.cp(z.L) // cp l + z.cp(z.L) case 0xBE: z.cp(z.rb(z.hl())) // cp (hl) case 0xFE: