Public Access
1
0
Files
emuz80disasmgo/dd_test.go
2025-09-25 14:18:22 +03:00

824 lines
15 KiB
Go

// Package disasm provides tests for the Z80 disassembler implementation
package disasm
import (
"testing"
)
// TestDecodeDD tests decoding of DD-prefixed Z80 instructions
func TestDecodeDD(t *testing.T) {
d := New()
tests := []struct {
name string
data []byte
expected Instruction
hasError bool
}{
{
name: "LD IX, nn",
data: []byte{0xDD, 0x21, 0x34, 0x12},
expected: Instruction{
Mnemonic: "LD IX, $1234",
Length: 4,
Address: 0x1234,
},
},
{
name: "ADD IX, BC",
data: []byte{0xDD, 0x09},
expected: Instruction{
Mnemonic: "ADD IX, BC",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "ADD IX, DE",
data: []byte{0xDD, 0x19},
expected: Instruction{
Mnemonic: "ADD IX, DE",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD (nn), IX",
data: []byte{0xDD, 0x22, 0x12, 0x34},
expected: Instruction{
Mnemonic: "LD ($3412), IX",
Length: 4,
Address: 0x3412,
},
},
{
name: "INC IX",
data: []byte{0xDD, 0x23},
expected: Instruction{
Mnemonic: "INC IX",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "INC IXH",
data: []byte{0xDD, 0x24},
expected: Instruction{
Mnemonic: "INC IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "DEC IXH",
data: []byte{0xDD, 0x25},
expected: Instruction{
Mnemonic: "DEC IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXH, n",
data: []byte{0xDD, 0x26, 0x42},
expected: Instruction{
Mnemonic: "LD IXH, $42",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "ADD IX, IX",
data: []byte{0xDD, 0x29},
expected: Instruction{
Mnemonic: "ADD IX, IX",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IX, (nn)",
data: []byte{0xDD, 0x2A, 0x12, 0x34},
expected: Instruction{
Mnemonic: "LD IX, ($3412)",
Length: 4,
Address: 0x3412,
},
},
{
name: "DEC IX",
data: []byte{0xDD, 0x2B},
expected: Instruction{
Mnemonic: "DEC IX",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "INC IXL",
data: []byte{0xDD, 0x2C},
expected: Instruction{
Mnemonic: "INC IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "DEC IXL",
data: []byte{0xDD, 0x2D},
expected: Instruction{
Mnemonic: "DEC IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXL, n",
data: []byte{0xDD, 0x2E, 0x42},
expected: Instruction{
Mnemonic: "LD IXL, $42",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "INC (IX+d)",
data: []byte{0xDD, 0x34, 0x05},
expected: Instruction{
Mnemonic: "INC (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "DEC (IX+d)",
data: []byte{0xDD, 0x35, 0x05},
expected: Instruction{
Mnemonic: "DEC (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD (IX+d), n",
data: []byte{0xDD, 0x36, 0x05, 0x42},
expected: Instruction{
Mnemonic: "LD (IX+$05), $42",
Length: 4,
Address: 0xFFFF,
},
},
{
name: "ADD IX, SP",
data: []byte{0xDD, 0x39},
expected: Instruction{
Mnemonic: "ADD IX, SP",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD B, IXH",
data: []byte{0xDD, 0x44},
expected: Instruction{
Mnemonic: "LD B, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD B, IXL",
data: []byte{0xDD, 0x45},
expected: Instruction{
Mnemonic: "LD B, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD B, (IX+d)",
data: []byte{0xDD, 0x46, 0x05},
expected: Instruction{
Mnemonic: "LD B, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD C, IXH",
data: []byte{0xDD, 0x4C},
expected: Instruction{
Mnemonic: "LD C, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD C, IXL",
data: []byte{0xDD, 0x4D},
expected: Instruction{
Mnemonic: "LD C, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD C, (IX+d)",
data: []byte{0xDD, 0x4E, 0x05},
expected: Instruction{
Mnemonic: "LD C, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD D, IXH",
data: []byte{0xDD, 0x54},
expected: Instruction{
Mnemonic: "LD D, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD D, IXL",
data: []byte{0xDD, 0x55},
expected: Instruction{
Mnemonic: "LD D, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD D, (IX+d)",
data: []byte{0xDD, 0x56, 0x05},
expected: Instruction{
Mnemonic: "LD D, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD E, IXH",
data: []byte{0xDD, 0x5C},
expected: Instruction{
Mnemonic: "LD E, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD E, IXL",
data: []byte{0xDD, 0x5D},
expected: Instruction{
Mnemonic: "LD E, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD E, (IX+d)",
data: []byte{0xDD, 0x5E, 0x05},
expected: Instruction{
Mnemonic: "LD E, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD IXH, B",
data: []byte{0xDD, 0x60},
expected: Instruction{
Mnemonic: "LD IXH, B",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXH, C",
data: []byte{0xDD, 0x61},
expected: Instruction{
Mnemonic: "LD IXH, C",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXH, D",
data: []byte{0xDD, 0x62},
expected: Instruction{
Mnemonic: "LD IXH, D",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXH, E",
data: []byte{0xDD, 0x63},
expected: Instruction{
Mnemonic: "LD IXH, E",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXH, IXH",
data: []byte{0xDD, 0x64},
expected: Instruction{
Mnemonic: "LD IXH, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXH, IXL",
data: []byte{0xDD, 0x65},
expected: Instruction{
Mnemonic: "LD IXH, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD H, (IX+d)",
data: []byte{0xDD, 0x66, 0x05},
expected: Instruction{
Mnemonic: "LD H, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD IXH, A",
data: []byte{0xDD, 0x67},
expected: Instruction{
Mnemonic: "LD IXH, A",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXL, B",
data: []byte{0xDD, 0x68},
expected: Instruction{
Mnemonic: "LD IXL, B",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXL, C",
data: []byte{0xDD, 0x69},
expected: Instruction{
Mnemonic: "LD IXL, C",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXL, D",
data: []byte{0xDD, 0x6A},
expected: Instruction{
Mnemonic: "LD IXL, D",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXL, E",
data: []byte{0xDD, 0x6B},
expected: Instruction{
Mnemonic: "LD IXL, E",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXL, IXH",
data: []byte{0xDD, 0x6C},
expected: Instruction{
Mnemonic: "LD IXL, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD IXL, IXL",
data: []byte{0xDD, 0x6D},
expected: Instruction{
Mnemonic: "LD IXL, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD L, (IX+d)",
data: []byte{0xDD, 0x6E, 0x05},
expected: Instruction{
Mnemonic: "LD L, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD IXL, A",
data: []byte{0xDD, 0x6F},
expected: Instruction{
Mnemonic: "LD IXL, A",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD (IX+d), B",
data: []byte{0xDD, 0x70, 0x05},
expected: Instruction{
Mnemonic: "LD (IX+$05), B",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD (IX+d), C",
data: []byte{0xDD, 0x71, 0x05},
expected: Instruction{
Mnemonic: "LD (IX+$05), C",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD (IX+d), D",
data: []byte{0xDD, 0x72, 0x05},
expected: Instruction{
Mnemonic: "LD (IX+$05), D",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD (IX+d), E",
data: []byte{0xDD, 0x73, 0x05},
expected: Instruction{
Mnemonic: "LD (IX+$05), E",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD (IX+d), H",
data: []byte{0xDD, 0x74, 0x05},
expected: Instruction{
Mnemonic: "LD (IX+$05), H",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD (IX+d), L",
data: []byte{0xDD, 0x75, 0x05},
expected: Instruction{
Mnemonic: "LD (IX+$05), L",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD (IX+d), A",
data: []byte{0xDD, 0x77, 0x05},
expected: Instruction{
Mnemonic: "LD (IX+$05), A",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "LD A, IXH",
data: []byte{0xDD, 0x7C},
expected: Instruction{
Mnemonic: "LD A, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD A, IXL",
data: []byte{0xDD, 0x7D},
expected: Instruction{
Mnemonic: "LD A, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD A, (IX+d)",
data: []byte{0xDD, 0x7E, 0x05},
expected: Instruction{
Mnemonic: "LD A, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "ADD A, IXH",
data: []byte{0xDD, 0x84},
expected: Instruction{
Mnemonic: "ADD A, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "ADD A, IXL",
data: []byte{0xDD, 0x85},
expected: Instruction{
Mnemonic: "ADD A, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "ADD A, (IX+d)",
data: []byte{0xDD, 0x86, 0x05},
expected: Instruction{
Mnemonic: "ADD A, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "ADC A, IXH",
data: []byte{0xDD, 0x8C},
expected: Instruction{
Mnemonic: "ADC A, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "ADC A, IXL",
data: []byte{0xDD, 0x8D},
expected: Instruction{
Mnemonic: "ADC A, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "ADC A, (IX+d)",
data: []byte{0xDD, 0x8E, 0x05},
expected: Instruction{
Mnemonic: "ADC A, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "SUB IXH",
data: []byte{0xDD, 0x94},
expected: Instruction{
Mnemonic: "SUB IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "SUB IXL",
data: []byte{0xDD, 0x95},
expected: Instruction{
Mnemonic: "SUB IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "SUB (IX+d)",
data: []byte{0xDD, 0x96, 0x05},
expected: Instruction{
Mnemonic: "SUB (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "SBC A, IXH",
data: []byte{0xDD, 0x9C},
expected: Instruction{
Mnemonic: "SBC A, IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "SBC A, IXL",
data: []byte{0xDD, 0x9D},
expected: Instruction{
Mnemonic: "SBC A, IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "SBC A, (IX+d)",
data: []byte{0xDD, 0x9E, 0x05},
expected: Instruction{
Mnemonic: "SBC A, (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "AND IXH",
data: []byte{0xDD, 0xA4},
expected: Instruction{
Mnemonic: "AND IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "AND IXL",
data: []byte{0xDD, 0xA5},
expected: Instruction{
Mnemonic: "AND IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "AND (IX+d)",
data: []byte{0xDD, 0xA6, 0x05},
expected: Instruction{
Mnemonic: "AND (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "XOR IXH",
data: []byte{0xDD, 0xAC},
expected: Instruction{
Mnemonic: "XOR IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "XOR IXL",
data: []byte{0xDD, 0xAD},
expected: Instruction{
Mnemonic: "XOR IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "XOR (IX+d)",
data: []byte{0xDD, 0xAE, 0x05},
expected: Instruction{
Mnemonic: "XOR (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "OR IXH",
data: []byte{0xDD, 0xB4},
expected: Instruction{
Mnemonic: "OR IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "OR IXL",
data: []byte{0xDD, 0xB5},
expected: Instruction{
Mnemonic: "OR IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "OR (IX+d)",
data: []byte{0xDD, 0xB6, 0x05},
expected: Instruction{
Mnemonic: "OR (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "CP IXH",
data: []byte{0xDD, 0xBC},
expected: Instruction{
Mnemonic: "CP IXH",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "CP IXL",
data: []byte{0xDD, 0xBD},
expected: Instruction{
Mnemonic: "CP IXL",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "CP (IX+d)",
data: []byte{0xDD, 0xBE, 0x05},
expected: Instruction{
Mnemonic: "CP (IX+$05)",
Length: 3,
Address: 0xFFFF,
},
},
{
name: "POP IX",
data: []byte{0xDD, 0xE1},
expected: Instruction{
Mnemonic: "POP IX",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "EX (SP), IX",
data: []byte{0xDD, 0xE3},
expected: Instruction{
Mnemonic: "EX (SP), IX",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "PUSH IX",
data: []byte{0xDD, 0xE5},
expected: Instruction{
Mnemonic: "PUSH IX",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "JP (IX)",
data: []byte{0xDD, 0xE9},
expected: Instruction{
Mnemonic: "JP (IX)",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD SP, IX",
data: []byte{0xDD, 0xF9},
expected: Instruction{
Mnemonic: "LD SP, IX",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "Insufficient data for DD prefix",
data: []byte{0xDD},
hasError: true,
},
{
name: "Insufficient data for LD IX, nn",
data: []byte{0xDD, 0x21, 0x34},
hasError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := d.Decode(tt.data)
if tt.hasError {
if err == nil {
t.Errorf("expected error but got none")
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if result.Mnemonic != tt.expected.Mnemonic {
t.Errorf("mnemonic mismatch: got %q, want %q", result.Mnemonic, tt.expected.Mnemonic)
}
if result.Length != tt.expected.Length {
t.Errorf("length mismatch: got %d, want %d", result.Length, tt.expected.Length)
}
if result.Address != tt.expected.Address {
t.Errorf("address mismatch: got 0x%04X, want 0x%04X", result.Address, tt.expected.Address)
}
})
}
}