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

513 lines
8.8 KiB
Go

// Package disasm provides tests for the Z80 disassembler implementation
package disasm
import (
"testing"
)
// TestDecodeUnprefixed tests decoding of unprefixed Z80 instructions
func TestDecodeUnprefixed(t *testing.T) {
d := New()
tests := []struct {
name string
data []byte
expected Instruction
hasError bool
}{
{
name: "NOP",
data: []byte{0x00},
expected: Instruction{
Mnemonic: "NOP",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "LD BC, nn",
data: []byte{0x01, 0x34, 0x12},
expected: Instruction{
Mnemonic: "LD BC, $1234",
Length: 3,
Address: 0x1234,
},
},
{
name: "LD (BC), A",
data: []byte{0x02},
expected: Instruction{
Mnemonic: "LD (BC), A",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "INC BC",
data: []byte{0x03},
expected: Instruction{
Mnemonic: "INC BC",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "INC B",
data: []byte{0x04},
expected: Instruction{
Mnemonic: "INC B",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "DEC B",
data: []byte{0x05},
expected: Instruction{
Mnemonic: "DEC B",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "LD B, n",
data: []byte{0x06, 0x42},
expected: Instruction{
Mnemonic: "LD B, $42",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "RLCA",
data: []byte{0x07},
expected: Instruction{
Mnemonic: "RLCA",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "EX AF, AF'",
data: []byte{0x08},
expected: Instruction{
Mnemonic: "EX AF, AF'",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "ADD HL, BC",
data: []byte{0x09},
expected: Instruction{
Mnemonic: "ADD HL, BC",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "LD A, (BC)",
data: []byte{0x0A},
expected: Instruction{
Mnemonic: "LD A, (BC)",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "DEC BC",
data: []byte{0x0B},
expected: Instruction{
Mnemonic: "DEC BC",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "INC C",
data: []byte{0x0C},
expected: Instruction{
Mnemonic: "INC C",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "DEC C",
data: []byte{0x0D},
expected: Instruction{
Mnemonic: "DEC C",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "LD C, n",
data: []byte{0x0E, 0xAB},
expected: Instruction{
Mnemonic: "LD C, $AB",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "RRCA",
data: []byte{0x0F},
expected: Instruction{
Mnemonic: "RRCA",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "DJNZ e",
data: []byte{0x10, 0x05},
expected: Instruction{
Mnemonic: "DJNZ $05",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "JR e",
data: []byte{0x18, 0x0A},
expected: Instruction{
Mnemonic: "JR $0A",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "JR NZ, e",
data: []byte{0x20, 0x05},
expected: Instruction{
Mnemonic: "JR NZ, $05",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "JR Z, e",
data: []byte{0x28, 0x05},
expected: Instruction{
Mnemonic: "JR Z, $05",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "JR NC, e",
data: []byte{0x30, 0x05},
expected: Instruction{
Mnemonic: "JR NC, $05",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "JR C, e",
data: []byte{0x38, 0x05},
expected: Instruction{
Mnemonic: "JR C, $05",
Length: 2,
Address: 0xFFFF,
},
},
{
name: "LD HL, nn",
data: []byte{0x21, 0xCD, 0xAB},
expected: Instruction{
Mnemonic: "LD HL, $ABCD",
Length: 3,
Address: 0xABCD,
},
},
{
name: "LD (nn), HL",
data: []byte{0x22, 0x12, 0x34},
expected: Instruction{
Mnemonic: "LD ($3412), HL",
Length: 3,
Address: 0x3412,
},
},
{
name: "LD HL, (nn)",
data: []byte{0x2A, 0x12, 0x34},
expected: Instruction{
Mnemonic: "LD HL, ($3412)",
Length: 3,
Address: 0x3412,
},
},
{
name: "INC DE",
data: []byte{0x13},
expected: Instruction{
Mnemonic: "INC DE",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "INC HL",
data: []byte{0x23},
expected: Instruction{
Mnemonic: "INC HL",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "INC SP",
data: []byte{0x33},
expected: Instruction{
Mnemonic: "INC SP",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "DEC DE",
data: []byte{0x1B},
expected: Instruction{
Mnemonic: "DEC DE",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "DEC HL",
data: []byte{0x2B},
expected: Instruction{
Mnemonic: "DEC HL",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "DEC SP",
data: []byte{0x3B},
expected: Instruction{
Mnemonic: "DEC SP",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "JP nn",
data: []byte{0xC3, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "JP NZ, nn",
data: []byte{0xC2, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP NZ, $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "JP Z, nn",
data: []byte{0xCA, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP Z, $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "JP NC, nn",
data: []byte{0xD2, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP NC, $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "JP C, nn",
data: []byte{0xDA, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP C, $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "JP PO, nn",
data: []byte{0xE2, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP PO, $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "JP PE, nn",
data: []byte{0xEA, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP PE, $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "JP P, nn",
data: []byte{0xF2, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP P, $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "JP M, nn",
data: []byte{0xFA, 0x12, 0x34},
expected: Instruction{
Mnemonic: "JP M, $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "CALL nn",
data: []byte{0xCD, 0x12, 0x34},
expected: Instruction{
Mnemonic: "CALL $3412",
Length: 3,
Address: 0x3412,
},
},
{
name: "RET",
data: []byte{0xC9},
expected: Instruction{
Mnemonic: "RET",
Length: 1,
Address: 0xFFFF,
},
},
{
name: "RST 00H",
data: []byte{0xC7},
expected: Instruction{
Mnemonic: "RST 00H",
Length: 1,
Address: 0x0000,
},
},
{
name: "RST 08H",
data: []byte{0xCF},
expected: Instruction{
Mnemonic: "RST 08H",
Length: 1,
Address: 0x0008,
},
},
{
name: "RST 10H",
data: []byte{0xD7},
expected: Instruction{
Mnemonic: "RST 10H",
Length: 1,
Address: 0x0010,
},
},
{
name: "RST 18H",
data: []byte{0xDF},
expected: Instruction{
Mnemonic: "RST 18H",
Length: 1,
Address: 0x0018,
},
},
{
name: "RST 20H",
data: []byte{0xE7},
expected: Instruction{
Mnemonic: "RST 20H",
Length: 1,
Address: 0x0020,
},
},
{
name: "RST 28H",
data: []byte{0xEF},
expected: Instruction{
Mnemonic: "RST 28H",
Length: 1,
Address: 0x0028,
},
},
{
name: "RST 30H",
data: []byte{0xF7},
expected: Instruction{
Mnemonic: "RST 30H",
Length: 1,
Address: 0x0030,
},
},
{
name: "RST 38H",
data: []byte{0xFF},
expected: Instruction{
Mnemonic: "RST 38H",
Length: 1,
Address: 0x0038,
},
},
{
name: "Insufficient data for LD BC, nn",
data: []byte{0x01, 0x34},
hasError: true,
},
{
name: "Unknown opcode",
data: []byte{0xFF},
expected: Instruction{
Mnemonic: "RST 38H",
Length: 1,
Address: 0x0038,
},
},
}
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)
}
})
}
}