z80go: v1.0.0

This commit is contained in:
Роман Бойков 2026-04-01 20:06:51 +03:00
parent d05db31cd2
commit ff2e10afdb
6 changed files with 39 additions and 34 deletions

View File

@ -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)

View File

@ -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 := ""

View File

@ -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)
}
}

5
go.mod
View File

@ -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

8
go.sum
View File

@ -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=

View File

@ -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: