diff --git a/Makefile b/Makefile index 97de449..0fe4f8a 100644 --- a/Makefile +++ b/Makefile @@ -41,10 +41,4 @@ clean: zexdoc: $(MAKE) -C cmd/zexdoc run -switch.go: op_*.go gen_switch.go ./cmd/gen_switch/*.go - rm -f switch.go switch.go.new - cp switch.go.dummy switch.go - go run ./cmd/gen_switch | goimports > switch.go.new - mv switch.go.new switch.go - # based on: github.com/koron-go/_skeleton/Makefile diff --git a/cmd/dumpdecodelayer/main.go b/cmd/dumpdecodelayer/main.go index c2a15ef..b376f1f 100644 --- a/cmd/dumpdecodelayer/main.go +++ b/cmd/dumpdecodelayer/main.go @@ -4,11 +4,11 @@ import ( "log" "os" - "github.com/koron-go/z80" + "github.com/koron-go/z80/internal/opcode" ) func main() { - err := z80.DumpDecodeLayer(os.Stdout) + err := opcode.DumpDecodeLayer(os.Stdout) if err != nil { log.Fatal(err) } diff --git a/cmd/gen_switch/main.go b/cmd/gen_switch/main.go index 1c46ae6..f64f567 100644 --- a/cmd/gen_switch/main.go +++ b/cmd/gen_switch/main.go @@ -1,15 +1,49 @@ package main import ( + "bytes" + "flag" + "io" "log" "os" - "github.com/koron-go/z80" + "github.com/koron-go/z80/internal/opcode" + "golang.org/x/tools/imports" ) +var name string +var nofmt bool + func main() { - err := z80.GenerateSwitchDecoder(os.Stdout) + flag.StringVar(&name, "name", "", "filename to output") + flag.BoolVar(&nofmt, "nofmt", false, "suppress to format") + flag.Parse() + + bb := &bytes.Buffer{} + err := opcode.WriteSwitchDecoder(bb) + if err != nil { + log.Fatalf("failed to generate: %s", err) + } + b := bb.Bytes() + + if !nofmt { + b, err = imports.Process(name, b, nil) + if err != nil { + log.Fatalf("failed to formatting: %s", err) + } + } + + var w io.Writer = os.Stdout + if name != "" { + f, err := os.Create(name) + if err != nil { + log.Fatalf("failed to create a file: %s", err) + } + defer f.Close() + w = f + } + _, err = w.Write(b) if err != nil { - log.Fatal(err) + log.Fatalf("failed to write: %s", err) } } diff --git a/go.mod b/go.mod index 2e1bb1f..27c8221 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/koron-go/z80 go 1.13 -require github.com/google/go-cmp v0.3.1 +require ( + github.com/google/go-cmp v0.3.1 + golang.org/x/tools v0.0.0-20200823205832-c024452afbcd +) diff --git a/go.sum b/go.sum index a6ddb1d..15c7cd5 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,24 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200823205832-c024452afbcd h1:KNSumuk5eGuQV7zbOrDDZ3MIkwsQr0n5oKiH4oE0/hU= +golang.org/x/tools v0.0.0-20200823205832-c024452afbcd/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/opcode/arith16.go b/internal/opcode/arith16.go new file mode 100644 index 0000000..d5f4ba5 --- /dev/null +++ b/internal/opcode/arith16.go @@ -0,0 +1,100 @@ +package opcode + +var arith16 = []*OPCode{ + + { + N: "ADD HL, ss", + C: []Code{ + {0x09, 0x30, vReg16_4}, + }, + T: []int{4, 4, 3}, + }, + + { + N: "ADC HL, ss", + C: []Code{ + {0xed, 0x00, nil}, + {0x4a, 0x30, vReg16_4}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "SBC HL, ss", + C: []Code{ + {0xed, 0x00, nil}, + {0x42, 0x30, vReg16_4}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "ADD IX, pp", + C: []Code{ + {0xdd, 0x00, nil}, + {0x09, 0x30, vReg16_4}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "ADD IY, rr", + C: []Code{ + {0xfd, 0x00, nil}, + {0x09, 0x30, vReg16_4}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "INC ss", + C: []Code{ + {0x03, 0x30, vReg16_4}, + }, + T: []int{6}, + }, + + { + N: "INC IX", + C: []Code{ + {0xdd, 0x00, nil}, + {0x23, 0x00, nil}, + }, + T: []int{4, 6}, + }, + + { + N: "INC IY", + C: []Code{ + {0xfd, 0x00, nil}, + {0x23, 0x00, nil}, + }, + T: []int{4, 6}, + }, + + { + N: "DEC ss", + C: []Code{ + {0x0b, 0x30, vReg16_4}, + }, + T: []int{6}, + }, + + { + N: "DEC IX", + C: []Code{ + {0xdd, 0x00, nil}, + {0x2b, 0x00, nil}, + }, + T: []int{4, 6}, + }, + + { + N: "DEC IY", + C: []Code{ + {0xfd, 0x00, nil}, + {0x2b, 0x00, nil}, + }, + T: []int{4, 6}, + }, +} diff --git a/internal/opcode/arith8.go b/internal/opcode/arith8.go new file mode 100644 index 0000000..3edc794 --- /dev/null +++ b/internal/opcode/arith8.go @@ -0,0 +1,436 @@ +package opcode + +var arith8 = []*OPCode{ + + { + N: "ADD A, r", + C: []Code{ + {0x80, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "ADD A, n", + C: []Code{ + {0xc6, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "ADD A, (HL)", + C: []Code{ + {0x86, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "ADD A, (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0x86, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "ADD A, (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0x86, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "ADC A, r", + C: []Code{ + {0x88, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "ADC A, n", + C: []Code{ + {0xce, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "ADC A, (HL)", + C: []Code{ + {0x8e, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "ADC A, (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0x8e, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "ADC A, (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0x8e, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "SUB A, r", + C: []Code{ + {0x90, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "SUB A, n", + C: []Code{ + {0xd6, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "SUB A, (HL)", + C: []Code{ + {0x96, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "SUB A, (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0x96, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "SUB A, (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0x96, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "SBC A, r", + C: []Code{ + {0x98, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "SBC A, n", + C: []Code{ + {0xde, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "SBC A, (HL)", + C: []Code{ + {0x9e, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "SBC A, (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0x9e, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "SBC A, (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0x9e, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "AND r", + C: []Code{ + {0xa0, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "AND n", + C: []Code{ + {0xe6, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "AND (HL)", + C: []Code{ + {0xa6, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "AND (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xa6, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "AND (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xa6, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "OR r", + C: []Code{ + {0xb0, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "OR n", + C: []Code{ + {0xf6, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "OR (HL)", + C: []Code{ + {0xb6, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "OR (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xb6, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "OR (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xb6, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "XOR r", + C: []Code{ + {0xa8, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "XOR n", + C: []Code{ + {0xee, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "XOR (HL)", + C: []Code{ + {0xae, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "XOR (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xae, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "XOR (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xae, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "CP r", + C: []Code{ + {0xb8, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "CP n", + C: []Code{ + {0xfe, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "CP (HL)", + C: []Code{ + {0xbe, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "CP (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xbe, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "CP (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xbe, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "INC r", + C: []Code{ + {0x04, 0x38, vReg8_3}, + }, + T: []int{4}, + }, + + { + N: "INC (HL)", + C: []Code{ + {0x34, 0x00, nil}, + }, + T: []int{4, 4, 3}, + }, + + { + N: "INC (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0x34, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "INC (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0x34, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "DEC r", + C: []Code{ + {0x05, 0x38, vReg8_3}, + }, + T: []int{4}, + }, + + { + N: "DEC (HL)", + C: []Code{ + {0x35, 0x00, nil}, + }, + T: []int{4, 4, 3}, + }, + + { + N: "DEC (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0x35, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "DEC (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0x35, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, +} diff --git a/internal/opcode/bitop.go b/internal/opcode/bitop.go new file mode 100644 index 0000000..be694da --- /dev/null +++ b/internal/opcode/bitop.go @@ -0,0 +1,124 @@ +package opcode + +var bitop = []*OPCode{ + + { + N: "BIT b, r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x40, 0x3f, vBit3Reg8}, + }, + T: []int{4, 4}, + }, + + { + N: "BIT b, (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x46, 0x38, vBit3_3}, + }, + T: []int{4, 4, 4}, + }, + + { + N: "BIT b, (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x46, 0x38, vBit3_3}, + }, + T: []int{4, 4, 3, 5, 4}, + }, + + { + N: "BIT b, (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x46, 0x38, vBit3_3}, + }, + T: []int{4, 4, 3, 5, 4}, + }, + + { + N: "SET b, r", + C: []Code{ + {0xcb, 0x00, nil}, + {0xc0, 0x3f, vBit3Reg8}, + }, + T: []int{4, 4}, + }, + + { + N: "SET b, (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0xc6, 0x38, vBit3_3}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "SET b, (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0xc6, 0x38, vBit3_3}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "SET b, (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0xc6, 0x38, vBit3_3}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RES b, r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x80, 0x3f, vBit3Reg8}, + }, + T: []int{4, 4}, + }, + + { + N: "RES b, (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x86, 0x38, vBit3_3}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "RES b, (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x86, 0x38, vBit3_3}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RES b, (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x86, 0x38, vBit3_3}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, +} diff --git a/internal/opcode/callret.go b/internal/opcode/callret.go new file mode 100644 index 0000000..ad54738 --- /dev/null +++ b/internal/opcode/callret.go @@ -0,0 +1,72 @@ +package opcode + +var opcRETI = &OPCode{ + N: "RETI", + C: []Code{ + {0xed, 0x00, nil}, + {0x4d, 0x00, nil}, + }, + T: []int{4, 4, 3, 3}, +} + +var opcRETN = &OPCode{ + N: "RETN", + C: []Code{ + {0xed, 0x00, nil}, + {0x45, 0x00, nil}, + }, + T: []int{4, 4, 3, 3}, +} + +var callret = []*OPCode{ + + { + N: "CALL nn", + C: []Code{ + {0xcd, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 4, 3, 3}, + }, + + { + N: "CALL cc, nn", + C: []Code{ + {0xc4, 0x38, vCC3_3}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 4, 3, 3}, + T2: []int{4, 3, 3}, + }, + + { + N: "RET", + C: []Code{ + {0xc9, 0x00, nil}, + }, + T: []int{4, 3, 3}, + }, + + { + N: "RET cc", + C: []Code{ + {0xc0, 0x38, vCC3_3}, + }, + T: []int{5, 3, 3}, + T2: []int{5}, + }, + + opcRETI, + + opcRETN, + + { + N: "RST p", + C: []Code{ + {0xc7, 0x38, vRSTp3_3}, + }, + T: []int{5, 3, 3}, + }, +} diff --git a/internal/opcode/ctrl.go b/internal/opcode/ctrl.go new file mode 100644 index 0000000..c95c0e2 --- /dev/null +++ b/internal/opcode/ctrl.go @@ -0,0 +1,108 @@ +package opcode + +var opcHALT = &OPCode{ + N: "HALT", + C: []Code{ + {0x76, 0x00, nil}, + }, + T: []int{4}, +} + +var opcEI = &OPCode{ + N: "EI", + C: []Code{ + {0xfb, 0x00, nil}, + }, + T: []int{4}, +} + +var ctrl = []*OPCode{ + + { + N: "DAA", + C: []Code{ + {0x27, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "CPL", + C: []Code{ + {0x2F, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "NEG", + C: []Code{ + {0xed, 0x00, nil}, + {0x44, 0x00, nil}, + }, + T: []int{4, 4}, + }, + + { + N: "CCF", + C: []Code{ + {0x3f, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "SCF", + C: []Code{ + {0x37, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "NOP", + C: []Code{ + {0x00, 0x00, nil}, + }, + T: []int{4}, + }, + + opcHALT, + + { + N: "DI", + C: []Code{ + {0xf3, 0x00, nil}, + }, + T: []int{4}, + }, + + opcEI, + + { + N: "IM 0", + C: []Code{ + {0xed, 0x00, nil}, + {0x46, 0x00, nil}, + }, + T: []int{4, 4}, + }, + + { + N: "IM 1", + C: []Code{ + {0xed, 0x00, nil}, + {0x56, 0x00, nil}, + }, + T: []int{4, 4}, + }, + + { + N: "IM 2", + C: []Code{ + {0xed, 0x00, nil}, + {0x5e, 0x00, nil}, + }, + T: []int{4, 4}, + }, +} diff --git a/decode.go b/internal/opcode/decode.go similarity index 97% rename from decode.go rename to internal/opcode/decode.go index 0a8ebbe..9b4f078 100644 --- a/decode.go +++ b/internal/opcode/decode.go @@ -1,4 +1,4 @@ -package z80 +package opcode import ( "encoding/json" @@ -19,7 +19,7 @@ var decoderOnce sync.Once func defaultDecodeLayer() *decodeLayer { decoderOnce.Do(func() { - defaultDecoder = newDecodeLayer(0, allOPCodes...) + defaultDecoder = newDecodeLayer(0, AllOPCodes...) }) return defaultDecoder } diff --git a/decode_test.go b/internal/opcode/decode_test.go similarity index 92% rename from decode_test.go rename to internal/opcode/decode_test.go index 06064b7..34866aa 100644 --- a/decode_test.go +++ b/internal/opcode/decode_test.go @@ -1,4 +1,4 @@ -package z80 +package opcode import ( "testing" @@ -9,7 +9,7 @@ func TestDecodeLayer_CheckAllOPCodes(t *testing.T) { l := defaultDecodeLayer() m := map[string]int{} - for _, cc := range allOPCodes { + for _, cc := range AllOPCodes { for _, c := range cc { k := c.String() if _, ok := m[k]; ok { diff --git a/internal/opcode/exbtsg.go b/internal/opcode/exbtsg.go new file mode 100644 index 0000000..0a62c8d --- /dev/null +++ b/internal/opcode/exbtsg.go @@ -0,0 +1,130 @@ +package opcode + +var exbtsg = []*OPCode{ + + { + N: "EX DE, HL", + C: []Code{ + {0xeb, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "EX AF, AF'", + C: []Code{ + {0x08, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "EXX", + C: []Code{ + {0xd9, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "EX (SP), HL", + C: []Code{ + {0xe3, 0x00, nil}, + }, + T: []int{4, 3, 4, 3, 5}, + }, + + { + N: "EX (SP), IX", + C: []Code{ + {0xdd, 0x00, nil}, + {0xe3, 0x00, nil}, + }, + T: []int{4, 4, 3, 4, 3, 5}, + }, + + { + N: "EX (SP), IY", + C: []Code{ + {0xfd, 0x00, nil}, + {0xe3, 0x00, nil}, + }, + T: []int{4, 4, 3, 4, 3, 5}, + }, + + { + N: "LDI", + C: []Code{ + {0xed, 0x00, nil}, + {0xa0, 0x00, nil}, + }, + T: []int{4, 4, 3, 5}, + }, + + { + N: "LDIR", + C: []Code{ + {0xed, 0x00, nil}, + {0xb0, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 5}, + T2: []int{4, 4, 3, 5}, + }, + + { + N: "LDD", + C: []Code{ + {0xed, 0x00, nil}, + {0xa8, 0x00, nil}, + }, + T: []int{4, 4, 3, 5}, + }, + + { + N: "LDDR", + C: []Code{ + {0xed, 0x00, nil}, + {0xb8, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 5}, + T2: []int{4, 4, 3, 5}, + }, + + { + N: "CPI", + C: []Code{ + {0xed, 0x00, nil}, + {0xa1, 0x00, nil}, + }, + T: []int{4, 4, 3, 5}, + }, + + { + N: "CPIR", + C: []Code{ + {0xed, 0x00, nil}, + {0xb1, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 5}, + T2: []int{4, 4, 3, 5}, + }, + + { + N: "CPD", + C: []Code{ + {0xed, 0x00, nil}, + {0xa9, 0x00, nil}, + }, + T: []int{4, 4, 3, 5}, + }, + + { + N: "CPDR", + C: []Code{ + {0xed, 0x00, nil}, + {0xb9, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 5}, + T2: []int{4, 4, 3, 5}, + }, +} diff --git a/gen_switch.go b/internal/opcode/gen_switch.go similarity index 94% rename from gen_switch.go rename to internal/opcode/gen_switch.go index d47362e..6cd1e4c 100644 --- a/gen_switch.go +++ b/internal/opcode/gen_switch.go @@ -1,4 +1,4 @@ -package z80 +package opcode import ( "bufio" @@ -8,8 +8,8 @@ import ( "github.com/koron-go/z80/internal/opname" ) -// GenerateSwitchDecoder generate decoder `switch` statements. -func GenerateSwitchDecoder(w io.Writer) error { +// WriteSwitchDecoder writes codes for decoder "switch" statements. +func WriteSwitchDecoder(w io.Writer) error { bw := bufio.NewWriter(w) _, err := bw.WriteString(`package z80 diff --git a/internal/opcode/inout.go b/internal/opcode/inout.go new file mode 100644 index 0000000..5eb3a9d --- /dev/null +++ b/internal/opcode/inout.go @@ -0,0 +1,116 @@ +package opcode + +var inout = []*OPCode{ + + { + N: "IN A, (n)", + C: []Code{ + {0xdb, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 4}, + }, + + { + N: "IN r (C)", + C: []Code{ + {0xed, 0x00, nil}, + {0x40, 0x38, vReg8_3}, + }, + T: []int{4, 4, 4}, + }, + + { + N: "INI", + C: []Code{ + {0xed, 0x00, nil}, + {0xa2, 0x00, nil}, + }, + T: []int{4, 5, 3, 4}, + }, + + { + N: "INIR", + C: []Code{ + {0xed, 0x00, nil}, + {0xb2, 0x00, nil}, + }, + T: []int{4, 5, 3, 4, 5}, + T2: []int{4, 5, 3, 4}, + }, + + { + N: "IND", + C: []Code{ + {0xed, 0x00, nil}, + {0xaa, 0x00, nil}, + }, + T: []int{4, 5, 3, 4}, + }, + + { + N: "INDR", + C: []Code{ + {0xed, 0x00, nil}, + {0xba, 0x00, nil}, + }, + T: []int{4, 5, 3, 4, 5}, + T2: []int{4, 5, 3, 4}, + }, + + { + N: "OUT (n), A", + C: []Code{ + {0xd3, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 4}, + }, + + { + N: "OUT (C), r", + C: []Code{ + {0xed, 0x00, nil}, + {0x41, 0x38, vReg8_3}, + }, + T: []int{4, 4, 4}, + }, + + { + N: "OUTI", + C: []Code{ + {0xed, 0x00, nil}, + {0xa3, 0x00, nil}, + }, + T: []int{4, 5, 3, 4}, + }, + + { + N: "OTIR", + C: []Code{ + {0xed, 0x00, nil}, + {0xb3, 0x00, nil}, + }, + T: []int{4, 5, 3, 4, 5}, + T2: []int{4, 5, 3, 4}, + }, + + { + N: "OUTD", + C: []Code{ + {0xed, 0x00, nil}, + {0xab, 0x00, nil}, + }, + T: []int{4, 5, 3, 4}, + }, + + { + N: "OTDR", + C: []Code{ + {0xed, 0x00, nil}, + {0xbb, 0x00, nil}, + }, + T: []int{4, 5, 3, 4, 5}, + T2: []int{4, 5, 3, 4}, + }, +} diff --git a/internal/opcode/jump.go b/internal/opcode/jump.go new file mode 100644 index 0000000..7f4f119 --- /dev/null +++ b/internal/opcode/jump.go @@ -0,0 +1,110 @@ +package opcode + +var jump = []*OPCode{ + + { + N: "JP nn", + C: []Code{ + {0xc3, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 3}, + }, + + { + N: "JP cc, nn", + C: []Code{ + {0xc2, 0x38, vCC3_3}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 4, 3, 3}, + T2: []int{4, 3, 3}, + }, + + { + N: "JR e", + C: []Code{ + {0x18, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 5}, + }, + + { + N: "JR C, e", + C: []Code{ + {0x38, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 5}, + T2: []int{4, 3}, + }, + + { + N: "JR NC, e", + C: []Code{ + {0x30, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 5}, + T2: []int{4, 3}, + }, + + { + N: "JR Z, e", + C: []Code{ + {0x28, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 5}, + T2: []int{4, 3}, + }, + + { + N: "JR NZ, e", + C: []Code{ + {0x20, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 5}, + T2: []int{4, 3}, + }, + + { + N: "JP (HL)", + C: []Code{ + {0xe9, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "JP (IX)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xe9, 0x00, nil}, + }, + T: []int{4, 4}, + }, + + { + N: "JP (IY)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xe9, 0x00, nil}, + }, + T: []int{4, 4}, + }, + + { + N: "DJNZ e", + C: []Code{ + {0x10, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{5, 3, 5}, + T2: []int{5, 3}, + }, +} diff --git a/internal/opcode/load16.go b/internal/opcode/load16.go new file mode 100644 index 0000000..eeb1e55 --- /dev/null +++ b/internal/opcode/load16.go @@ -0,0 +1,200 @@ +package opcode + +var load16 = []*OPCode{ + + { + N: "LD dd, nn", + C: []Code{ + {0x01, 0x30, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 3}, + }, + + { + N: "LD IX, nn", + C: []Code{ + {0xdd, 0x00, nil}, + {0x21, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 3}, + }, + + { + N: "LD IY, nn", + C: []Code{ + {0xfd, 0x00, nil}, + {0x21, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 3}, + }, + + { + N: "LD HL, (nn)", + C: []Code{ + {0x2a, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 3, 3, 3}, + }, + + { + N: "LD dd, (nn)", + C: []Code{ + {0xed, 0x00, nil}, + {0x4b, 0x30, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 3, 3, 3}, + }, + + { + N: "LD IX, (nn)", + C: []Code{ + {0xdd, 0x00, nil}, + {0x2a, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 3, 3, 3}, + }, + + { + N: "LD IY, (nn)", + C: []Code{ + {0xfd, 0x00, nil}, + {0x2a, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 3, 3, 3}, + }, + + { + N: "LD (nn), HL", + C: []Code{ + {0x22, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 3, 3, 3}, + }, + + { + N: "LD (nn), dd", + C: []Code{ + {0xed, 0x00, nil}, + {0x43, 0x30, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 3, 3, 3}, + }, + + { + N: "LD (nn), IX", + C: []Code{ + {0xdd, 0x00, nil}, + {0x22, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 3, 3, 3}, + }, + + { + N: "LD (nn), IY", + C: []Code{ + {0xfd, 0x00, nil}, + {0x22, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 3, 3, 3}, + }, + + { + N: "LD SP, HL", + C: []Code{ + {0xf9, 0x00, nil}, + }, + T: []int{6}, + }, + + { + N: "LD SP, IX", + C: []Code{ + {0xdd, 0x00, nil}, + {0xf9, 0x00, nil}, + }, + T: []int{4, 6}, + }, + + { + N: "LD SP, IY", + C: []Code{ + {0xfd, 0x00, nil}, + {0xf9, 0x00, nil}, + }, + T: []int{4, 6}, + }, + + { + N: "PUSH qq", + C: []Code{ + {0xc5, 0x30, nil}, + }, + T: []int{5, 3, 3}, + }, + + { + N: "PUSH IX", + C: []Code{ + {0xdd, 0x00, nil}, + {0xe5, 0x00, nil}, + }, + T: []int{4, 5, 3, 3}, + }, + + { + N: "PUSH IY", + C: []Code{ + {0xfd, 0x00, nil}, + {0xe5, 0x00, nil}, + }, + T: []int{4, 5, 3, 3}, + }, + + { + N: "POP qq", + C: []Code{ + {0xc1, 0x30, nil}, + }, + T: []int{4, 3, 3}, + }, + + { + N: "POP IX", + C: []Code{ + {0xdd, 0x00, nil}, + {0xe1, 0x00, nil}, + }, + T: []int{4, 4, 3, 3}, + }, + + { + N: "POP IY", + C: []Code{ + {0xfd, 0x00, nil}, + {0xe1, 0x00, nil}, + }, + T: []int{4, 4, 3, 3}, + }, +} diff --git a/internal/opcode/load8.go b/internal/opcode/load8.go new file mode 100644 index 0000000..5cd8f4d --- /dev/null +++ b/internal/opcode/load8.go @@ -0,0 +1,196 @@ +package opcode + +var load8 = []*OPCode{ + + { + N: "LD r1, r2", + C: []Code{ + {0x40, 0x3f, vReg88}, + }, + T: []int{4}, + }, + + { + N: "LD r, n", + C: []Code{ + {0x06, 0x38, vReg88}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "LD r, (HL)", + C: []Code{ + {0x46, 0x38, vReg8_3}, + }, + T: []int{4, 3}, + }, + + { + N: "LD r, (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0x46, 0x38, vReg8_3}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "LD r, (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0x46, 0x38, vReg8_3}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "LD (HL), r", + C: []Code{ + {0x70, 0x07, vReg8}, + }, + T: []int{4, 3}, + }, + + { + N: "LD (IX+d), r", + C: []Code{ + {0xdd, 0x00, nil}, + {0x70, 0x07, vReg8}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "LD (IY+d), r", + C: []Code{ + {0xfd, 0x00, nil}, + {0x70, 0x07, vReg8}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "LD (HL), n", + C: []Code{ + {0x36, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 3}, + }, + + { + N: "LD (IX+d), n", + C: []Code{ + {0xdd, 0x00, nil}, + {0x36, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "LD (IY+d), n", + C: []Code{ + {0xfd, 0x00, nil}, + {0x36, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 4, 3, 5, 3}, + }, + + { + N: "LD A, (BC)", + C: []Code{ + {0x0a, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "LD A, (DE)", + C: []Code{ + {0x1a, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "LD A, (nn)", + C: []Code{ + {0x3a, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 3, 3}, + }, + + { + N: "LD (BC), A", + C: []Code{ + {0x02, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "LD (DE), A", + C: []Code{ + {0x12, 0x00, nil}, + }, + T: []int{4, 3}, + }, + + { + N: "LD (nn), A", + C: []Code{ + {0x32, 0x00, nil}, + {0x00, 0xff, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3, 3, 3}, + }, + + { + N: "LD A, I", + C: []Code{ + {0xed, 0x00, nil}, + {0x57, 0x00, nil}, + }, + T: []int{4, 5}, + }, + + { + N: "LD A, R", + C: []Code{ + {0xed, 0x00, nil}, + {0x5f, 0x00, nil}, + }, + T: []int{4, 5}, + }, + + { + N: "LD I, A", + C: []Code{ + {0xed, 0x00, nil}, + {0x47, 0x00, nil}, + }, + T: []int{4, 5}, + }, + + { + N: "LD R, A", + C: []Code{ + {0xed, 0x00, nil}, + {0x4f, 0x00, nil}, + }, + T: []int{4, 5}, + }, +} diff --git a/opcode.go b/internal/opcode/opcode.go similarity index 81% rename from opcode.go rename to internal/opcode/opcode.go index d1d7cb3..b5e0ee6 100644 --- a/opcode.go +++ b/internal/opcode/opcode.go @@ -1,4 +1,4 @@ -package z80 +package opcode import "fmt" @@ -79,9 +79,6 @@ type OPCode struct { // T2 is T cycle for the special conditions. T2 []int - - // F is the function of opcode. - F func(*CPU, []uint8) } func (op *OPCode) String() string { @@ -96,20 +93,8 @@ func (op *OPCode) mapTo() map[string]interface{} { return m } -// addrOff apply offset to address. -func addrOff(addr uint16, off uint8) uint16 { - return addr + uint16(int16(int8(off))) -} - -func toU16(l, h uint8) uint16 { - return (uint16(h) << 8) | uint16(l) -} - -func fromU16(v uint16) (l, h uint8) { - return uint8(v & 0xff), uint8(v >> 8) -} - -var allOPCodes = [][]*OPCode{ +// AllOPCodes includes all operations of Z80. +var AllOPCodes = [][]*OPCode{ load8, load16, exbtsg, diff --git a/internal/opcode/rotateshift.go b/internal/opcode/rotateshift.go new file mode 100644 index 0000000..9043a6f --- /dev/null +++ b/internal/opcode/rotateshift.go @@ -0,0 +1,334 @@ +package opcode + +var rotateshift = []*OPCode{ + + { + N: "RLCA", + C: []Code{ + {0x07, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "RLA", + C: []Code{ + {0x17, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "RRCA", + C: []Code{ + {0x0f, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "RRA", + C: []Code{ + {0x1f, 0x00, nil}, + }, + T: []int{4}, + }, + + { + N: "RLC r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x00, 0x07, vReg8}, + }, + T: []int{4, 4}, + }, + + { + N: "RLC (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x06, 0x00, nil}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "RLC (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x06, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RLC (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x06, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RL r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x10, 0x07, vReg8}, + }, + T: []int{4, 4}, + }, + + { + N: "RL (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x16, 0x00, nil}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "RL (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x16, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RL (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x16, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RRC r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x08, 0x07, vReg8}, + }, + T: []int{4, 4}, + }, + + { + N: "RRC (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x0e, 0x00, nil}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "RRC (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x0e, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RRC (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x0e, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RR r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x18, 0x07, vReg8}, + }, + T: []int{4, 4}, + }, + + { + N: "RR (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x1e, 0x00, nil}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "RR (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x1e, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RR (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x1e, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "SLA r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x20, 0x07, vReg8}, + }, + T: []int{4, 4}, + }, + + { + N: "SLA (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x26, 0x00, nil}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "SLA (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x26, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "SLA (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x26, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "SRA r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x28, 0x07, vReg8}, + }, + T: []int{4, 4}, + }, + + { + N: "SRA (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x2e, 0x00, nil}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "SRA (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x2e, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "SRA (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x2e, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "SRL r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x38, 0x07, vReg8}, + }, + T: []int{4, 4}, + }, + + { + N: "SRL (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x3e, 0x00, nil}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "SRL (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x3e, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "SRL (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x3e, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, + }, + + { + N: "RLD", + C: []Code{ + {0xed, 0x00, nil}, + {0x6f, 0x00, nil}, + }, + T: []int{4, 4, 3, 4, 3}, + }, + + { + N: "RRD", + C: []Code{ + {0xed, 0x00, nil}, + {0x67, 0x00, nil}, + }, + T: []int{4, 4, 3, 4, 3}, + }, +} diff --git a/internal/opcode/undoc.go b/internal/opcode/undoc.go new file mode 100644 index 0000000..7eff556 --- /dev/null +++ b/internal/opcode/undoc.go @@ -0,0 +1,317 @@ +package opcode + +var undoc = []*OPCode{ + { + N: "INC IXH", + C: []Code{ + {0xdd, 0x00, nil}, + {0x24, 0x00, nil}, + }, + T: []int{4, 6}, // not verified + }, + + { + N: "DEC IXH", + C: []Code{ + {0xdd, 0x00, nil}, + {0x25, 0x00, nil}, + }, + T: []int{4, 6}, // not verified + }, + + { + N: "INC IXL", + C: []Code{ + {0xdd, 0x00, nil}, + {0x2c, 0x00, nil}, + }, + T: []int{4, 6}, // not verified + }, + + { + N: "DEC IXL", + C: []Code{ + {0xdd, 0x00, nil}, + {0x2d, 0x00, nil}, + }, + T: []int{4, 6}, // not verified + }, + + { + N: "INC IYH", + C: []Code{ + {0xfd, 0x00, nil}, + {0x24, 0x00, nil}, + }, + T: []int{4, 6}, // not verified + }, + + { + N: "DEC IYH", + C: []Code{ + {0xfd, 0x00, nil}, + {0x25, 0x00, nil}, + }, + T: []int{4, 6}, // not verified + }, + + { + N: "INC IYL", + C: []Code{ + {0xfd, 0x00, nil}, + {0x2c, 0x00, nil}, + }, + T: []int{4, 6}, // not verified + }, + + { + N: "DEC IYL", + C: []Code{ + {0xfd, 0x00, nil}, + {0x2d, 0x00, nil}, + }, + T: []int{4, 6}, // not verified + }, + + { + N: "LD IXH, n", + C: []Code{ + {0xdd, 0x00, nil}, + {0x26, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, // not verified + }, + + { + N: "LD IXL, n", + C: []Code{ + {0xdd, 0x00, nil}, + {0x2e, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, // not verified + }, + + { + N: "LD IYH, n", + C: []Code{ + {0xfd, 0x00, nil}, + {0x26, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, // not verified + }, + + { + N: "LD IYL, n", + C: []Code{ + {0xfd, 0x00, nil}, + {0x2e, 0x00, nil}, + {0x00, 0xff, nil}, + }, + T: []int{4, 3}, // not verified + }, + + { + N: "SL1 (IX+d)", + C: []Code{ + {0xdd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x36, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, // not verified + }, + + { + N: "SL1 (IY+d)", + C: []Code{ + {0xfd, 0x00, nil}, + {0xcb, 0x00, nil}, + {0x00, 0xff, nil}, + {0x36, 0x00, nil}, + }, + T: []int{4, 4, 3, 5, 4, 3}, // not verified + }, + + { + N: "SL1 r", + C: []Code{ + {0xcb, 0x00, nil}, + {0x30, 0x07, vReg8}, + }, + T: []int{4, 4}, + }, + + { + N: "SL1 (HL)", + C: []Code{ + {0xcb, 0x00, nil}, + {0x36, 0x00, nil}, + }, + T: []int{4, 4, 4, 3}, + }, + + { + N: "LD rx1, rx2", + C: []Code{ + {0xdd, 0x00, nil}, + {0x40, 0x3f, vReg88}, + }, + T: []int{4}, + }, + + { + N: "LD ry1, ry2", + C: []Code{ + {0xfd, 0x00, nil}, + {0x40, 0x3f, vReg88}, + }, + T: []int{4}, + }, + + { + N: "ADD A, rx", + C: []Code{ + {0xdd, 0x00, nil}, + {0x80, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "ADD A, ry", + C: []Code{ + {0xfd, 0x00, nil}, + {0x80, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "ADC A, rx", + C: []Code{ + {0xdd, 0x00, nil}, + {0x88, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "ADC A, ry", + C: []Code{ + {0xfd, 0x00, nil}, + {0x88, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "SUB A, rx", + C: []Code{ + {0xdd, 0x00, nil}, + {0x90, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "SUB A, ry", + C: []Code{ + {0xfd, 0x00, nil}, + {0x90, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "SBC A, rx", + C: []Code{ + {0xdd, 0x00, nil}, + {0x98, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "SBC A, ry", + C: []Code{ + {0xfd, 0x00, nil}, + {0x98, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "AND rx", + C: []Code{ + {0xdd, 0x00, nil}, + {0xa0, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "AND ry", + C: []Code{ + {0xfd, 0x00, nil}, + {0xa0, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "XOR rx", + C: []Code{ + {0xdd, 0x00, nil}, + {0xa8, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "XOR ry", + C: []Code{ + {0xfd, 0x00, nil}, + {0xa8, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "OR rx", + C: []Code{ + {0xdd, 0x00, nil}, + {0xb0, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "OR ry", + C: []Code{ + {0xfd, 0x00, nil}, + {0xb0, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "CP rx", + C: []Code{ + {0xdd, 0x00, nil}, + {0xb8, 0x07, vReg8}, + }, + T: []int{4}, + }, + + { + N: "CP ry", + C: []Code{ + {0xfd, 0x00, nil}, + {0xb8, 0x07, vReg8}, + }, + T: []int{4}, + }, +} diff --git a/op.go b/op.go new file mode 100644 index 0000000..b8f3313 --- /dev/null +++ b/op.go @@ -0,0 +1,14 @@ +package z80 + +// addrOff apply offset to address. +func addrOff(addr uint16, off uint8) uint16 { + return addr + uint16(int16(int8(off))) +} + +func toU16(l, h uint8) uint16 { + return (uint16(h) << 8) | uint16(l) +} + +func fromU16(v uint16) (l, h uint8) { + return uint8(v & 0xff), uint8(v >> 8) +} diff --git a/op_arith16.go b/op_arith16.go index 200a1b4..dde2c2b 100644 --- a/op_arith16.go +++ b/op_arith16.go @@ -1,115 +1,5 @@ package z80 -var arith16 = []*OPCode{ - - { - N: "ADD HL, ss", - C: []Code{ - {0x09, 0x30, vReg16_4}, - }, - T: []int{4, 4, 3}, - F: opADDHLss, - }, - - { - N: "ADC HL, ss", - C: []Code{ - {0xed, 0x00, nil}, - {0x4a, 0x30, vReg16_4}, - }, - T: []int{4, 4, 4, 3}, - F: opADCHLss, - }, - - { - N: "SBC HL, ss", - C: []Code{ - {0xed, 0x00, nil}, - {0x42, 0x30, vReg16_4}, - }, - T: []int{4, 4, 4, 3}, - F: opSBCHLss, - }, - - { - N: "ADD IX, pp", - C: []Code{ - {0xdd, 0x00, nil}, - {0x09, 0x30, vReg16_4}, - }, - T: []int{4, 4, 4, 3}, - F: opADDIXpp, - }, - - { - N: "ADD IY, rr", - C: []Code{ - {0xfd, 0x00, nil}, - {0x09, 0x30, vReg16_4}, - }, - T: []int{4, 4, 4, 3}, - F: opADDIYrr, - }, - - { - N: "INC ss", - C: []Code{ - {0x03, 0x30, vReg16_4}, - }, - T: []int{6}, - F: opINCss, - }, - - { - N: "INC IX", - C: []Code{ - {0xdd, 0x00, nil}, - {0x23, 0x00, nil}, - }, - T: []int{4, 6}, - F: opINCIX, - }, - - { - N: "INC IY", - C: []Code{ - {0xfd, 0x00, nil}, - {0x23, 0x00, nil}, - }, - T: []int{4, 6}, - F: opINCIY, - }, - - { - N: "DEC ss", - C: []Code{ - {0x0b, 0x30, vReg16_4}, - }, - T: []int{6}, - F: opDECss, - }, - - { - N: "DEC IX", - C: []Code{ - {0xdd, 0x00, nil}, - {0x2b, 0x00, nil}, - }, - T: []int{4, 6}, - F: opDECIX, - }, - - { - N: "DEC IY", - C: []Code{ - {0xfd, 0x00, nil}, - {0x2b, 0x00, nil}, - }, - T: []int{4, 6}, - F: opDECIY, - }, -} - func opADDHLss(cpu *CPU, codes []uint8) { a := cpu.HL.U16() x := cpu.reg16ss(codes[0] >> 4).U16() diff --git a/op_arith8.go b/op_arith8.go index 490b920..feab11f 100644 --- a/op_arith8.go +++ b/op_arith8.go @@ -1,488 +1,5 @@ package z80 -var arith8 = []*OPCode{ - - { - N: "ADD A, r", - C: []Code{ - {0x80, 0x07, vReg8}, - }, - T: []int{4}, - F: opADDAr, - }, - - { - N: "ADD A, n", - C: []Code{ - {0xc6, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opADDAn, - }, - - { - N: "ADD A, (HL)", - C: []Code{ - {0x86, 0x00, nil}, - }, - T: []int{4, 3}, - F: opADDAHLP, - }, - - { - N: "ADD A, (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0x86, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opADDAIXdP, - }, - - { - N: "ADD A, (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0x86, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opADDAIYdP, - }, - - { - N: "ADC A, r", - C: []Code{ - {0x88, 0x07, vReg8}, - }, - T: []int{4}, - F: opADCAr, - }, - - { - N: "ADC A, n", - C: []Code{ - {0xce, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opADCAn, - }, - - { - N: "ADC A, (HL)", - C: []Code{ - {0x8e, 0x00, nil}, - }, - T: []int{4, 3}, - F: opADCAHLP, - }, - - { - N: "ADC A, (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0x8e, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opADCAIXdP, - }, - - { - N: "ADC A, (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0x8e, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opADCAIYdP, - }, - - { - N: "SUB A, r", - C: []Code{ - {0x90, 0x07, vReg8}, - }, - T: []int{4}, - F: opSUBAr, - }, - - { - N: "SUB A, n", - C: []Code{ - {0xd6, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opSUBAn, - }, - - { - N: "SUB A, (HL)", - C: []Code{ - {0x96, 0x00, nil}, - }, - T: []int{4, 3}, - F: opSUBAHLP, - }, - - { - N: "SUB A, (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0x96, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opSUBAIXdP, - }, - - { - N: "SUB A, (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0x96, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opSUBAIYdP, - }, - - { - N: "SBC A, r", - C: []Code{ - {0x98, 0x07, vReg8}, - }, - T: []int{4}, - F: opSBCAr, - }, - - { - N: "SBC A, n", - C: []Code{ - {0xde, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opSBCAn, - }, - - { - N: "SBC A, (HL)", - C: []Code{ - {0x9e, 0x00, nil}, - }, - T: []int{4, 3}, - F: opSBCAHLP, - }, - - { - N: "SBC A, (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0x9e, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opSBCAIXdP, - }, - - { - N: "SBC A, (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0x9e, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opSBCAIYdP, - }, - - { - N: "AND r", - C: []Code{ - {0xa0, 0x07, vReg8}, - }, - T: []int{4}, - F: opANDr, - }, - - { - N: "AND n", - C: []Code{ - {0xe6, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opANDn, - }, - - { - N: "AND (HL)", - C: []Code{ - {0xa6, 0x00, nil}, - }, - T: []int{4, 3}, - F: opANDHLP, - }, - - { - N: "AND (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xa6, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opANDIXdP, - }, - - { - N: "AND (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xa6, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opANDIYdP, - }, - - { - N: "OR r", - C: []Code{ - {0xb0, 0x07, vReg8}, - }, - T: []int{4}, - F: opORr, - }, - - { - N: "OR n", - C: []Code{ - {0xf6, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opORn, - }, - - { - N: "OR (HL)", - C: []Code{ - {0xb6, 0x00, nil}, - }, - T: []int{4, 3}, - F: opORHLP, - }, - - { - N: "OR (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xb6, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opORIXdP, - }, - - { - N: "OR (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xb6, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opORIYdP, - }, - - { - N: "XOR r", - C: []Code{ - {0xa8, 0x07, vReg8}, - }, - T: []int{4}, - F: opXORr, - }, - - { - N: "XOR n", - C: []Code{ - {0xee, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opXORn, - }, - - { - N: "XOR (HL)", - C: []Code{ - {0xae, 0x00, nil}, - }, - T: []int{4, 3}, - F: opXORHLP, - }, - - { - N: "XOR (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xae, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opXORIXdP, - }, - - { - N: "XOR (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xae, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opXORIYdP, - }, - - { - N: "CP r", - C: []Code{ - {0xb8, 0x07, vReg8}, - }, - T: []int{4}, - F: opCPr, - }, - - { - N: "CP n", - C: []Code{ - {0xfe, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opCPn, - }, - - { - N: "CP (HL)", - C: []Code{ - {0xbe, 0x00, nil}, - }, - T: []int{4, 3}, - F: opCPHLP, - }, - - { - N: "CP (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xbe, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opCPIXdP, - }, - - { - N: "CP (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xbe, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opCPIYdP, - }, - - { - N: "INC r", - C: []Code{ - {0x04, 0x38, vReg8_3}, - }, - T: []int{4}, - F: opINCr, - }, - - { - N: "INC (HL)", - C: []Code{ - {0x34, 0x00, nil}, - }, - T: []int{4, 4, 3}, - F: opINCHLP, - }, - - { - N: "INC (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0x34, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opINCIXdP, - }, - - { - N: "INC (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0x34, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opINCIYdP, - }, - - { - N: "DEC r", - C: []Code{ - {0x05, 0x38, vReg8_3}, - }, - T: []int{4}, - F: opDECr, - }, - - { - N: "DEC (HL)", - C: []Code{ - {0x35, 0x00, nil}, - }, - T: []int{4, 4, 3}, - F: opDECHLP, - }, - - { - N: "DEC (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0x35, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opDECIXdP, - }, - - { - N: "DEC (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0x35, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opDECIYdP, - }, -} - func opADDAr(cpu *CPU, codes []uint8) { a := cpu.AF.Hi x := *cpu.regP(codes[0]) diff --git a/op_bitop.go b/op_bitop.go index 0057bdb..fd48399 100644 --- a/op_bitop.go +++ b/op_bitop.go @@ -1,140 +1,5 @@ package z80 -var bitop = []*OPCode{ - - { - N: "BIT b, r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x40, 0x3f, vBit3Reg8}, - }, - T: []int{4, 4}, - F: opBITbr, - }, - - { - N: "BIT b, (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x46, 0x38, vBit3_3}, - }, - T: []int{4, 4, 4}, - F: opBITbHLP, - }, - - { - N: "BIT b, (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x46, 0x38, vBit3_3}, - }, - T: []int{4, 4, 3, 5, 4}, - F: opBITbIXdP, - }, - - { - N: "BIT b, (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x46, 0x38, vBit3_3}, - }, - T: []int{4, 4, 3, 5, 4}, - F: opBITbIYdP, - }, - - { - N: "SET b, r", - C: []Code{ - {0xcb, 0x00, nil}, - {0xc0, 0x3f, vBit3Reg8}, - }, - T: []int{4, 4}, - F: opSETbr, - }, - - { - N: "SET b, (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0xc6, 0x38, vBit3_3}, - }, - T: []int{4, 4, 4, 3}, - F: opSETbHLP, - }, - - { - N: "SET b, (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0xc6, 0x38, vBit3_3}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opSETbIXdP, - }, - - { - N: "SET b, (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0xc6, 0x38, vBit3_3}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opSETbIYdP, - }, - - { - N: "RES b, r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x80, 0x3f, vBit3Reg8}, - }, - T: []int{4, 4}, - F: opRESbr, - }, - - { - N: "RES b, (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x86, 0x38, vBit3_3}, - }, - T: []int{4, 4, 4, 3}, - F: opRESbHLP, - }, - - { - N: "RES b, (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x86, 0x38, vBit3_3}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRESbIXdP, - }, - - { - N: "RES b, (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x86, 0x38, vBit3_3}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRESbIYdP, - }, -} - func opBITbr(cpu *CPU, codes []uint8) { b := (codes[1] >> 3) & 0x07 r := cpu.regP(codes[1]) diff --git a/op_callret.go b/op_callret.go index 90ab38e..ab60072 100644 --- a/op_callret.go +++ b/op_callret.go @@ -1,83 +1,5 @@ package z80 -var opcRETI = &OPCode{ - N: "RETI", - C: []Code{ - {0xed, 0x00, nil}, - {0x4d, 0x00, nil}, - }, - T: []int{4, 4, 3, 3}, - F: opRETI, -} - -var opcRETN = &OPCode{ - N: "RETN", - C: []Code{ - {0xed, 0x00, nil}, - {0x45, 0x00, nil}, - }, - T: []int{4, 4, 3, 3}, - F: opRETN, -} - -var callret = []*OPCode{ - - { - N: "CALL nn", - C: []Code{ - {0xcd, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 4, 3, 3}, - F: opCALLnn, - }, - - { - N: "CALL cc, nn", - C: []Code{ - {0xc4, 0x38, vCC3_3}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 4, 3, 3}, - T2: []int{4, 3, 3}, - F: opCALLccnn, - }, - - { - N: "RET", - C: []Code{ - {0xc9, 0x00, nil}, - }, - T: []int{4, 3, 3}, - F: opRET, - }, - - { - N: "RET cc", - C: []Code{ - {0xc0, 0x38, vCC3_3}, - }, - T: []int{5, 3, 3}, - T2: []int{5}, - F: opRETcc, - }, - - opcRETI, - - opcRETN, - - { - N: "RST p", - C: []Code{ - {0xc7, 0x38, vRSTp3_3}, - }, - T: []int{5, 3, 3}, - F: opRSTp, - }, -} - func opRETI(cpu *CPU, codes []uint8) { cpu.PC = cpu.readU16(cpu.SP) cpu.SP += 2 diff --git a/op_ctrl.go b/op_ctrl.go index 04d8ac9..d0b59ba 100644 --- a/op_ctrl.go +++ b/op_ctrl.go @@ -2,125 +2,6 @@ package z80 import "math/bits" -var opcHALT = &OPCode{ - N: "HALT", - C: []Code{ - {0x76, 0x00, nil}, - }, - T: []int{4}, - F: opHALT, -} - -var opcEI = &OPCode{ - N: "EI", - C: []Code{ - {0xfb, 0x00, nil}, - }, - T: []int{4}, - F: opEI, -} - -var ctrl = []*OPCode{ - - { - N: "DAA", - C: []Code{ - {0x27, 0x00, nil}, - }, - T: []int{4}, - F: opDAA, - }, - - { - N: "CPL", - C: []Code{ - {0x2F, 0x00, nil}, - }, - T: []int{4}, - F: opCPL, - }, - - { - N: "NEG", - C: []Code{ - {0xed, 0x00, nil}, - {0x44, 0x00, nil}, - }, - T: []int{4, 4}, - F: opNEG, - }, - - { - N: "CCF", - C: []Code{ - {0x3f, 0x00, nil}, - }, - T: []int{4}, - F: opCCF, - }, - - { - N: "SCF", - C: []Code{ - {0x37, 0x00, nil}, - }, - T: []int{4}, - F: opSCF, - }, - - { - N: "NOP", - C: []Code{ - {0x00, 0x00, nil}, - }, - T: []int{4}, - F: opNOP, - }, - - opcHALT, - - { - N: "DI", - C: []Code{ - {0xf3, 0x00, nil}, - }, - T: []int{4}, - F: opDI, - }, - - opcEI, - - { - N: "IM 0", - C: []Code{ - {0xed, 0x00, nil}, - {0x46, 0x00, nil}, - }, - T: []int{4, 4}, - F: opIM0, - }, - - { - N: "IM 1", - C: []Code{ - {0xed, 0x00, nil}, - {0x56, 0x00, nil}, - }, - T: []int{4, 4}, - F: opIM1, - }, - - { - N: "IM 2", - C: []Code{ - {0xed, 0x00, nil}, - {0x5e, 0x00, nil}, - }, - T: []int{4, 4}, - F: opIM2, - }, -} - // port from WebMSX. // See https://github.com/ppeccin/WebMSX/blob/654e3aa303e84404fba4a89d5fa21fae32753cf5/src/main/msx/cpu/CPU.js#L1010-L1030 func opDAA(cpu *CPU, codes []uint8) { diff --git a/op_exbtsg.go b/op_exbtsg.go index c1733d8..4cbb012 100644 --- a/op_exbtsg.go +++ b/op_exbtsg.go @@ -1,148 +1,5 @@ package z80 -var exbtsg = []*OPCode{ - - { - N: "EX DE, HL", - C: []Code{ - {0xeb, 0x00, nil}, - }, - T: []int{4}, - F: opEXDEHL, - }, - - { - N: "EX AF, AF'", - C: []Code{ - {0x08, 0x00, nil}, - }, - T: []int{4}, - F: opEXAFAF, - }, - - { - N: "EXX", - C: []Code{ - {0xd9, 0x00, nil}, - }, - T: []int{4}, - F: opEXX, - }, - - { - N: "EX (SP), HL", - C: []Code{ - {0xe3, 0x00, nil}, - }, - T: []int{4, 3, 4, 3, 5}, - F: opEXSPPHL, - }, - - { - N: "EX (SP), IX", - C: []Code{ - {0xdd, 0x00, nil}, - {0xe3, 0x00, nil}, - }, - T: []int{4, 4, 3, 4, 3, 5}, - F: opEXSPPIX, - }, - - { - N: "EX (SP), IY", - C: []Code{ - {0xfd, 0x00, nil}, - {0xe3, 0x00, nil}, - }, - T: []int{4, 4, 3, 4, 3, 5}, - F: opEXSPPIY, - }, - - { - N: "LDI", - C: []Code{ - {0xed, 0x00, nil}, - {0xa0, 0x00, nil}, - }, - T: []int{4, 4, 3, 5}, - F: opLDI, - }, - - { - N: "LDIR", - C: []Code{ - {0xed, 0x00, nil}, - {0xb0, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 5}, - T2: []int{4, 4, 3, 5}, - F: opLDIR, - }, - - { - N: "LDD", - C: []Code{ - {0xed, 0x00, nil}, - {0xa8, 0x00, nil}, - }, - T: []int{4, 4, 3, 5}, - F: opLDD, - }, - - { - N: "LDDR", - C: []Code{ - {0xed, 0x00, nil}, - {0xb8, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 5}, - T2: []int{4, 4, 3, 5}, - F: opLDDR, - }, - - { - N: "CPI", - C: []Code{ - {0xed, 0x00, nil}, - {0xa1, 0x00, nil}, - }, - T: []int{4, 4, 3, 5}, - F: opCPI, - }, - - { - N: "CPIR", - C: []Code{ - {0xed, 0x00, nil}, - {0xb1, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 5}, - T2: []int{4, 4, 3, 5}, - F: opCPIR, - }, - - { - N: "CPD", - C: []Code{ - {0xed, 0x00, nil}, - {0xa9, 0x00, nil}, - }, - T: []int{4, 4, 3, 5}, - F: opCPD, - }, - - { - N: "CPDR", - C: []Code{ - {0xed, 0x00, nil}, - {0xb9, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 5}, - T2: []int{4, 4, 3, 5}, - F: opCPDR, - }, -} - func opEXDEHL(cpu *CPU, codes []uint8) { cpu.HL, cpu.DE = cpu.DE, cpu.HL } diff --git a/op_inout.go b/op_inout.go index 0216710..1539248 100644 --- a/op_inout.go +++ b/op_inout.go @@ -2,133 +2,6 @@ package z80 import "math/bits" -var inout = []*OPCode{ - - { - N: "IN A, (n)", - C: []Code{ - {0xdb, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 4}, - F: opINAnP, - }, - - { - N: "IN r (C)", - C: []Code{ - {0xed, 0x00, nil}, - {0x40, 0x38, vReg8_3}, - }, - T: []int{4, 4, 4}, - F: opINrCP, - }, - - { - N: "INI", - C: []Code{ - {0xed, 0x00, nil}, - {0xa2, 0x00, nil}, - }, - T: []int{4, 5, 3, 4}, - F: opINI, - }, - - { - N: "INIR", - C: []Code{ - {0xed, 0x00, nil}, - {0xb2, 0x00, nil}, - }, - T: []int{4, 5, 3, 4, 5}, - T2: []int{4, 5, 3, 4}, - F: opINIR, - }, - - { - N: "IND", - C: []Code{ - {0xed, 0x00, nil}, - {0xaa, 0x00, nil}, - }, - T: []int{4, 5, 3, 4}, - F: opIND, - }, - - { - N: "INDR", - C: []Code{ - {0xed, 0x00, nil}, - {0xba, 0x00, nil}, - }, - T: []int{4, 5, 3, 4, 5}, - T2: []int{4, 5, 3, 4}, - F: opINDR, - }, - - { - N: "OUT (n), A", - C: []Code{ - {0xd3, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 4}, - F: opOUTnPA, - }, - - { - N: "OUT (C), r", - C: []Code{ - {0xed, 0x00, nil}, - {0x41, 0x38, vReg8_3}, - }, - T: []int{4, 4, 4}, - F: opOUTCPr, - }, - - { - N: "OUTI", - C: []Code{ - {0xed, 0x00, nil}, - {0xa3, 0x00, nil}, - }, - T: []int{4, 5, 3, 4}, - F: opOUTI, - }, - - { - N: "OTIR", - C: []Code{ - {0xed, 0x00, nil}, - {0xb3, 0x00, nil}, - }, - T: []int{4, 5, 3, 4, 5}, - T2: []int{4, 5, 3, 4}, - F: opOTIR, - }, - - { - N: "OUTD", - C: []Code{ - {0xed, 0x00, nil}, - {0xab, 0x00, nil}, - }, - T: []int{4, 5, 3, 4}, - F: opOUTD, - }, - - { - N: "OTDR", - C: []Code{ - {0xed, 0x00, nil}, - {0xbb, 0x00, nil}, - }, - T: []int{4, 5, 3, 4, 5}, - T2: []int{4, 5, 3, 4}, - F: opOTDR, - }, -} - func opINAnP(cpu *CPU, codes []uint8) { cpu.AF.Hi = cpu.ioIn(codes[1]) } diff --git a/op_jump.go b/op_jump.go index 609f8e3..fbea06f 100644 --- a/op_jump.go +++ b/op_jump.go @@ -1,125 +1,5 @@ package z80 -var jump = []*OPCode{ - - { - N: "JP nn", - C: []Code{ - {0xc3, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 3}, - F: opJPnn, - }, - - { - N: "JP cc, nn", - C: []Code{ - {0xc2, 0x38, vCC3_3}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 4, 3, 3}, - T2: []int{4, 3, 3}, - F: opJPccnn, - }, - - { - N: "JR e", - C: []Code{ - {0x18, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 5}, - F: opJRe, - }, - - { - N: "JR C, e", - C: []Code{ - {0x38, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 5}, - T2: []int{4, 3}, - F: opJRCe, - }, - - { - N: "JR NC, e", - C: []Code{ - {0x30, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 5}, - T2: []int{4, 3}, - F: opJRNCe, - }, - - { - N: "JR Z, e", - C: []Code{ - {0x28, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 5}, - T2: []int{4, 3}, - F: opJRZe, - }, - - { - N: "JR NZ, e", - C: []Code{ - {0x20, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 5}, - T2: []int{4, 3}, - F: opJRNZe, - }, - - { - N: "JP (HL)", - C: []Code{ - {0xe9, 0x00, nil}, - }, - T: []int{4}, - F: opJPHLP, - }, - - { - N: "JP (IX)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xe9, 0x00, nil}, - }, - T: []int{4, 4}, - F: opJPIXP, - }, - - { - N: "JP (IY)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xe9, 0x00, nil}, - }, - T: []int{4, 4}, - F: opJPIYP, - }, - - { - N: "DJNZ e", - C: []Code{ - {0x10, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{5, 3, 5}, - T2: []int{5, 3}, - F: opDJNZe, - }, -} - func opJPnn(cpu *CPU, codes []uint8) { cpu.PC = toU16(codes[1], codes[2]) } diff --git a/op_load16.go b/op_load16.go index b385cde..13edf35 100644 --- a/op_load16.go +++ b/op_load16.go @@ -1,224 +1,5 @@ package z80 -var load16 = []*OPCode{ - - { - N: "LD dd, nn", - C: []Code{ - {0x01, 0x30, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 3}, - F: opLDddnn, - }, - - { - N: "LD IX, nn", - C: []Code{ - {0xdd, 0x00, nil}, - {0x21, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 3}, - F: opLDIXnn, - }, - - { - N: "LD IY, nn", - C: []Code{ - {0xfd, 0x00, nil}, - {0x21, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 3}, - F: opLDIYnn, - }, - - { - N: "LD HL, (nn)", - C: []Code{ - {0x2a, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 3, 3, 3}, - F: opLDHLnnP, - }, - - { - N: "LD dd, (nn)", - C: []Code{ - {0xed, 0x00, nil}, - {0x4b, 0x30, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 3, 3, 3}, - F: opLDddnnP, - }, - - { - N: "LD IX, (nn)", - C: []Code{ - {0xdd, 0x00, nil}, - {0x2a, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 3, 3, 3}, - F: opLDIXnnP, - }, - - { - N: "LD IY, (nn)", - C: []Code{ - {0xfd, 0x00, nil}, - {0x2a, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 3, 3, 3}, - F: opLDIYnnP, - }, - - { - N: "LD (nn), HL", - C: []Code{ - {0x22, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 3, 3, 3}, - F: opLDnnPHL, - }, - - { - N: "LD (nn), dd", - C: []Code{ - {0xed, 0x00, nil}, - {0x43, 0x30, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 3, 3, 3}, - F: opLDnnPdd, - }, - - { - N: "LD (nn), IX", - C: []Code{ - {0xdd, 0x00, nil}, - {0x22, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 3, 3, 3}, - F: opLDnnPIX, - }, - - { - N: "LD (nn), IY", - C: []Code{ - {0xfd, 0x00, nil}, - {0x22, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 3, 3, 3}, - F: opLDnnPIY, - }, - - { - N: "LD SP, HL", - C: []Code{ - {0xf9, 0x00, nil}, - }, - T: []int{6}, - F: opLDSPHL, - }, - - { - N: "LD SP, IX", - C: []Code{ - {0xdd, 0x00, nil}, - {0xf9, 0x00, nil}, - }, - T: []int{4, 6}, - F: opLDSPIX, - }, - - { - N: "LD SP, IY", - C: []Code{ - {0xfd, 0x00, nil}, - {0xf9, 0x00, nil}, - }, - T: []int{4, 6}, - F: opLDSPIY, - }, - - { - N: "PUSH qq", - C: []Code{ - {0xc5, 0x30, nil}, - }, - T: []int{5, 3, 3}, - F: opPUSHqq, - }, - - { - N: "PUSH IX", - C: []Code{ - {0xdd, 0x00, nil}, - {0xe5, 0x00, nil}, - }, - T: []int{4, 5, 3, 3}, - F: opPUSHIX, - }, - - { - N: "PUSH IY", - C: []Code{ - {0xfd, 0x00, nil}, - {0xe5, 0x00, nil}, - }, - T: []int{4, 5, 3, 3}, - F: opPUSHIY, - }, - - { - N: "POP qq", - C: []Code{ - {0xc1, 0x30, nil}, - }, - T: []int{4, 3, 3}, - F: opPOPqq, - }, - - { - N: "POP IX", - C: []Code{ - {0xdd, 0x00, nil}, - {0xe1, 0x00, nil}, - }, - T: []int{4, 4, 3, 3}, - F: opPOPIX, - }, - - { - N: "POP IY", - C: []Code{ - {0xfd, 0x00, nil}, - {0xe1, 0x00, nil}, - }, - T: []int{4, 4, 3, 3}, - F: opPOPIY, - }, -} - func opLDddnn(cpu *CPU, codes []uint8) { dd := cpu.reg16dd(codes[0] >> 4) nn := toU16(codes[1], codes[2]) diff --git a/op_load8.go b/op_load8.go index c45dca2..f6a8714 100644 --- a/op_load8.go +++ b/op_load8.go @@ -1,221 +1,5 @@ package z80 -var load8 = []*OPCode{ - - { - N: "LD r1, r2", - C: []Code{ - {0x40, 0x3f, vReg88}, - }, - T: []int{4}, - F: opLDr1r2, - }, - - { - N: "LD r, n", - C: []Code{ - {0x06, 0x38, vReg88}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, - F: opLDrn, - }, - - { - N: "LD r, (HL)", - C: []Code{ - {0x46, 0x38, vReg8_3}, - }, - T: []int{4, 3}, - F: opLDrHLP, - }, - - { - N: "LD r, (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0x46, 0x38, vReg8_3}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opLDrIXdP, - }, - - { - N: "LD r, (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0x46, 0x38, vReg8_3}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opLDrIYdP, - }, - - { - N: "LD (HL), r", - C: []Code{ - {0x70, 0x07, vReg8}, - }, - T: []int{4, 3}, - F: opLDHLPr, - }, - - { - N: "LD (IX+d), r", - C: []Code{ - {0xdd, 0x00, nil}, - {0x70, 0x07, vReg8}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opLDIXdPr, - }, - - { - N: "LD (IY+d), r", - C: []Code{ - {0xfd, 0x00, nil}, - {0x70, 0x07, vReg8}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opLDIYdPr, - }, - - { - N: "LD (HL), n", - C: []Code{ - {0x36, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 3}, - F: opLDHLPn, - }, - - { - N: "LD (IX+d), n", - C: []Code{ - {0xdd, 0x00, nil}, - {0x36, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opLDIXdPn, - }, - - { - N: "LD (IY+d), n", - C: []Code{ - {0xfd, 0x00, nil}, - {0x36, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 4, 3, 5, 3}, - F: opLDIYdPn, - }, - - { - N: "LD A, (BC)", - C: []Code{ - {0x0a, 0x00, nil}, - }, - T: []int{4, 3}, - F: opLDABCP, - }, - - { - N: "LD A, (DE)", - C: []Code{ - {0x1a, 0x00, nil}, - }, - T: []int{4, 3}, - F: opLDADEP, - }, - - { - N: "LD A, (nn)", - C: []Code{ - {0x3a, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 3, 3}, - F: opLDAnnP, - }, - - { - N: "LD (BC), A", - C: []Code{ - {0x02, 0x00, nil}, - }, - T: []int{4, 3}, - F: opLDBCPA, - }, - - { - N: "LD (DE), A", - C: []Code{ - {0x12, 0x00, nil}, - }, - T: []int{4, 3}, - F: opLDDEPA, - }, - - { - N: "LD (nn), A", - C: []Code{ - {0x32, 0x00, nil}, - {0x00, 0xff, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3, 3, 3}, - F: opLDnnPA, - }, - - { - N: "LD A, I", - C: []Code{ - {0xed, 0x00, nil}, - {0x57, 0x00, nil}, - }, - T: []int{4, 5}, - F: opLDAI, - }, - - { - N: "LD A, R", - C: []Code{ - {0xed, 0x00, nil}, - {0x5f, 0x00, nil}, - }, - T: []int{4, 5}, - F: opLDAR, - }, - - { - N: "LD I, A", - C: []Code{ - {0xed, 0x00, nil}, - {0x47, 0x00, nil}, - }, - T: []int{4, 5}, - F: opLDIA, - }, - - { - N: "LD R, A", - C: []Code{ - {0xed, 0x00, nil}, - {0x4f, 0x00, nil}, - }, - T: []int{4, 5}, - F: opLDRA, - }, -} - func opLDr1r2(cpu *CPU, codes []uint8) { *cpu.regP(codes[0] >> 3) = *cpu.regP(codes[0]) } diff --git a/op_rotateshift.go b/op_rotateshift.go index 70f309f..351385f 100644 --- a/op_rotateshift.go +++ b/op_rotateshift.go @@ -2,373 +2,6 @@ package z80 import "math/bits" -var rotateshift = []*OPCode{ - - { - N: "RLCA", - C: []Code{ - {0x07, 0x00, nil}, - }, - T: []int{4}, - F: opRLCA, - }, - - { - N: "RLA", - C: []Code{ - {0x17, 0x00, nil}, - }, - T: []int{4}, - F: opRLA, - }, - - { - N: "RRCA", - C: []Code{ - {0x0f, 0x00, nil}, - }, - T: []int{4}, - F: opRRCA, - }, - - { - N: "RRA", - C: []Code{ - {0x1f, 0x00, nil}, - }, - T: []int{4}, - F: opRRA, - }, - - { - N: "RLC r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x00, 0x07, vReg8}, - }, - T: []int{4, 4}, - F: opRLCr, - }, - - { - N: "RLC (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x06, 0x00, nil}, - }, - T: []int{4, 4, 4, 3}, - F: opRLCHLP, - }, - - { - N: "RLC (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x06, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRLCIXdP, - }, - - { - N: "RLC (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x06, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRLCIYdP, - }, - - { - N: "RL r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x10, 0x07, vReg8}, - }, - T: []int{4, 4}, - F: opRLr, - }, - - { - N: "RL (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x16, 0x00, nil}, - }, - T: []int{4, 4, 4, 3}, - F: opRLHLP, - }, - - { - N: "RL (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x16, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRLIXdP, - }, - - { - N: "RL (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x16, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRLIYdP, - }, - - { - N: "RRC r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x08, 0x07, vReg8}, - }, - T: []int{4, 4}, - F: opRRCr, - }, - - { - N: "RRC (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x0e, 0x00, nil}, - }, - T: []int{4, 4, 4, 3}, - F: opRRCHLP, - }, - - { - N: "RRC (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x0e, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRRCIXdP, - }, - - { - N: "RRC (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x0e, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRRCIYdP, - }, - - { - N: "RR r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x18, 0x07, vReg8}, - }, - T: []int{4, 4}, - F: opRRr, - }, - - { - N: "RR (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x1e, 0x00, nil}, - }, - T: []int{4, 4, 4, 3}, - F: opRRHLP, - }, - - { - N: "RR (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x1e, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRRIXdP, - }, - - { - N: "RR (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x1e, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opRRIYdP, - }, - - { - N: "SLA r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x20, 0x07, vReg8}, - }, - T: []int{4, 4}, - F: opSLAr, - }, - - { - N: "SLA (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x26, 0x00, nil}, - }, - T: []int{4, 4, 4, 3}, - F: opSLAHLP, - }, - - { - N: "SLA (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x26, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opSLAIXdP, - }, - - { - N: "SLA (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x26, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opSLAIYdP, - }, - - { - N: "SRA r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x28, 0x07, vReg8}, - }, - T: []int{4, 4}, - F: opSRAr, - }, - - { - N: "SRA (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x2e, 0x00, nil}, - }, - T: []int{4, 4, 4, 3}, - F: opSRAHLP, - }, - - { - N: "SRA (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x2e, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opSRAIXdP, - }, - - { - N: "SRA (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x2e, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opSRAIYdP, - }, - - { - N: "SRL r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x38, 0x07, vReg8}, - }, - T: []int{4, 4}, - F: opSRLr, - }, - - { - N: "SRL (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x3e, 0x00, nil}, - }, - T: []int{4, 4, 4, 3}, - F: opSRLHLP, - }, - - { - N: "SRL (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x3e, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opSRLIXdP, - }, - - { - N: "SRL (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x3e, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, - F: opSRLIYdP, - }, - - { - N: "RLD", - C: []Code{ - {0xed, 0x00, nil}, - {0x6f, 0x00, nil}, - }, - T: []int{4, 4, 3, 4, 3}, - F: opRLD, - }, - - { - N: "RRD", - C: []Code{ - {0xed, 0x00, nil}, - {0x67, 0x00, nil}, - }, - T: []int{4, 4, 3, 4, 3}, - F: opRRD, - }, -} - func opRLCA(cpu *CPU, codes []uint8) { a := cpu.AF.Hi a2 := a<<1 | a>>7 diff --git a/opcode_test.go b/op_test.go similarity index 100% rename from opcode_test.go rename to op_test.go diff --git a/op_undoc.go b/op_undoc.go index 8db0e58..386ff6e 100644 --- a/op_undoc.go +++ b/op_undoc.go @@ -86,356 +86,6 @@ func (cpu *CPU) setRY(n uint8, v uint8) { } } -var undoc = []*OPCode{ - { - N: "INC IXH", - C: []Code{ - {0xdd, 0x00, nil}, - {0x24, 0x00, nil}, - }, - T: []int{4, 6}, // not verified - F: opINCIXH, - }, - - { - N: "DEC IXH", - C: []Code{ - {0xdd, 0x00, nil}, - {0x25, 0x00, nil}, - }, - T: []int{4, 6}, // not verified - F: opDECIXH, - }, - - { - N: "INC IXL", - C: []Code{ - {0xdd, 0x00, nil}, - {0x2c, 0x00, nil}, - }, - T: []int{4, 6}, // not verified - F: opINCIXL, - }, - - { - N: "DEC IXL", - C: []Code{ - {0xdd, 0x00, nil}, - {0x2d, 0x00, nil}, - }, - T: []int{4, 6}, // not verified - F: opDECIXL, - }, - - { - N: "INC IYH", - C: []Code{ - {0xfd, 0x00, nil}, - {0x24, 0x00, nil}, - }, - T: []int{4, 6}, // not verified - F: opINCIYH, - }, - - { - N: "DEC IYH", - C: []Code{ - {0xfd, 0x00, nil}, - {0x25, 0x00, nil}, - }, - T: []int{4, 6}, // not verified - F: opDECIYH, - }, - - { - N: "INC IYL", - C: []Code{ - {0xfd, 0x00, nil}, - {0x2c, 0x00, nil}, - }, - T: []int{4, 6}, // not verified - F: opINCIYL, - }, - - { - N: "DEC IYL", - C: []Code{ - {0xfd, 0x00, nil}, - {0x2d, 0x00, nil}, - }, - T: []int{4, 6}, // not verified - F: opDECIYL, - }, - - { - N: "LD IXH, n", - C: []Code{ - {0xdd, 0x00, nil}, - {0x26, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, // not verified - F: opLDIXHn, - }, - - { - N: "LD IXL, n", - C: []Code{ - {0xdd, 0x00, nil}, - {0x2e, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, // not verified - F: opLDIXLn, - }, - - { - N: "LD IYH, n", - C: []Code{ - {0xfd, 0x00, nil}, - {0x26, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, // not verified - F: opLDIYHn, - }, - - { - N: "LD IYL, n", - C: []Code{ - {0xfd, 0x00, nil}, - {0x2e, 0x00, nil}, - {0x00, 0xff, nil}, - }, - T: []int{4, 3}, // not verified - F: opLDIYLn, - }, - - { - N: "SL1 (IX+d)", - C: []Code{ - {0xdd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x36, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, // not verified - F: opSL1IXdP, - }, - - { - N: "SL1 (IY+d)", - C: []Code{ - {0xfd, 0x00, nil}, - {0xcb, 0x00, nil}, - {0x00, 0xff, nil}, - {0x36, 0x00, nil}, - }, - T: []int{4, 4, 3, 5, 4, 3}, // not verified - F: opSL1IYdP, - }, - - { - N: "SL1 r", - C: []Code{ - {0xcb, 0x00, nil}, - {0x30, 0x07, vReg8}, - }, - T: []int{4, 4}, - F: opSL1r, - }, - - { - N: "SL1 (HL)", - C: []Code{ - {0xcb, 0x00, nil}, - {0x36, 0x00, nil}, - }, - T: []int{4, 4, 4, 3}, - F: opSL1HLP, - }, - - { - N: "LD rx1, rx2", - C: []Code{ - {0xdd, 0x00, nil}, - {0x40, 0x3f, vReg88}, - }, - T: []int{4}, - F: opLDrx1rx2, - }, - - { - N: "LD ry1, ry2", - C: []Code{ - {0xfd, 0x00, nil}, - {0x40, 0x3f, vReg88}, - }, - T: []int{4}, - F: opLDry1ry2, - }, - - { - N: "ADD A, rx", - C: []Code{ - {0xdd, 0x00, nil}, - {0x80, 0x07, vReg8}, - }, - T: []int{4}, - F: opADDArx, - }, - - { - N: "ADD A, ry", - C: []Code{ - {0xfd, 0x00, nil}, - {0x80, 0x07, vReg8}, - }, - T: []int{4}, - F: opADDAry, - }, - - { - N: "ADC A, rx", - C: []Code{ - {0xdd, 0x00, nil}, - {0x88, 0x07, vReg8}, - }, - T: []int{4}, - F: opADCArx, - }, - - { - N: "ADC A, ry", - C: []Code{ - {0xfd, 0x00, nil}, - {0x88, 0x07, vReg8}, - }, - T: []int{4}, - F: opADCAry, - }, - - { - N: "SUB A, rx", - C: []Code{ - {0xdd, 0x00, nil}, - {0x90, 0x07, vReg8}, - }, - T: []int{4}, - F: opSUBArx, - }, - - { - N: "SUB A, ry", - C: []Code{ - {0xfd, 0x00, nil}, - {0x90, 0x07, vReg8}, - }, - T: []int{4}, - F: opSUBAry, - }, - - { - N: "SBC A, rx", - C: []Code{ - {0xdd, 0x00, nil}, - {0x98, 0x07, vReg8}, - }, - T: []int{4}, - F: opSBCArx, - }, - - { - N: "SBC A, ry", - C: []Code{ - {0xfd, 0x00, nil}, - {0x98, 0x07, vReg8}, - }, - T: []int{4}, - F: opSBCAry, - }, - - { - N: "AND rx", - C: []Code{ - {0xdd, 0x00, nil}, - {0xa0, 0x07, vReg8}, - }, - T: []int{4}, - F: opANDrx, - }, - - { - N: "AND ry", - C: []Code{ - {0xfd, 0x00, nil}, - {0xa0, 0x07, vReg8}, - }, - T: []int{4}, - F: opANDry, - }, - - { - N: "XOR rx", - C: []Code{ - {0xdd, 0x00, nil}, - {0xa8, 0x07, vReg8}, - }, - T: []int{4}, - F: opXORrx, - }, - - { - N: "XOR ry", - C: []Code{ - {0xfd, 0x00, nil}, - {0xa8, 0x07, vReg8}, - }, - T: []int{4}, - F: opXORry, - }, - - { - N: "OR rx", - C: []Code{ - {0xdd, 0x00, nil}, - {0xb0, 0x07, vReg8}, - }, - T: []int{4}, - F: opORrx, - }, - - { - N: "OR ry", - C: []Code{ - {0xfd, 0x00, nil}, - {0xb0, 0x07, vReg8}, - }, - T: []int{4}, - F: opORry, - }, - - { - N: "CP rx", - C: []Code{ - {0xdd, 0x00, nil}, - {0xb8, 0x07, vReg8}, - }, - T: []int{4}, - F: opCPrx, - }, - - { - N: "CP ry", - C: []Code{ - {0xfd, 0x00, nil}, - {0xb8, 0x07, vReg8}, - }, - T: []int{4}, - F: opCPry, - }, -} - func opINCIXH(cpu *CPU, codes []uint8) { v := cpu.incU8(uint8(cpu.IX >> 8)) cpu.IX = uint16(v)<<8 | cpu.IX&0xff diff --git a/step.go b/step.go index 2730033..ca3e5a5 100644 --- a/step.go +++ b/step.go @@ -2,6 +2,8 @@ package z80 import "fmt" +//go:generate go run ./cmd/gen_switch/ -name switch.go + func (cpu *CPU) step(f fetcher, enableInt bool) error { afterEI := false if !cpu.HALT { diff --git a/switch.go.dummy b/switch.go.dummy deleted file mode 100644 index 20bd0d9..0000000 --- a/switch.go.dummy +++ /dev/null @@ -1,5 +0,0 @@ -package z80 - -func decodeExec(cpu *CPU, f fetcher) error { - return nil -} diff --git a/z80.go b/z80.go index 4f4e0ca..2035741 100644 --- a/z80.go +++ b/z80.go @@ -284,13 +284,6 @@ func (cpu *CPU) flagCC(n uint8) bool { } } -func (cpu *CPU) exec(op *OPCode, args []uint8) { - for i, c := range op.C { - args[i] &= c.M - } - op.F(cpu, args) -} - // Run executes instructions till HALT or error. func (cpu *CPU) Run(ctx context.Context) error { var ctxErr error