Files
emuz80go/alu_test.go

63 lines
2.2 KiB
Go

package z80
import "testing"
// Test ADD A,n sets all flags correctly including undocumented X/Y.
func TestADD_A_n_Flags(t *testing.T) {
cpu, mem, _ := testCPU()
// 3E 7F = LD A,0x7F; C6 01 = ADD A,0x01
loadProgram(cpu, mem, 0x0000, 0x3E, 0x7F, 0xC6, 0x01)
mustStep(t, cpu) // LD A,7F
c := mustStep(t, cpu) // ADD A,01
assertEq(t, cpu.A, byte(0x80), "A after ADD")
assertFlag(t, cpu, FLAG_S, true, "S")
assertFlag(t, cpu, FLAG_Z, false, "Z")
assertFlag(t, cpu, FLAG_H, true, "H half-carry")
assertFlag(t, cpu, FLAG_PV, true, "P/V overflow")
assertFlag(t, cpu, FLAG_N, false, "N")
assertFlag(t, cpu, FLAG_C, false, "C")
// X and Y from result
assertFlag(t, cpu, FLAG_X, (cpu.A&FLAG_X) != 0, "X from result")
assertFlag(t, cpu, FLAG_Y, (cpu.A&FLAG_Y) != 0, "Y from result")
// Quick timing smoke-check (not strict because conditional)
assertEq(t, c, 7, "cycles for ADD A,n should be 7")
}
// CP n sets X/Y from the OPERAND per implementation fixes.
func TestCP_n_XYFromOperand(t *testing.T) {
cpu, mem, _ := testCPU()
// A=0x20; FE 08 = CP 0x08 -> result 0x18 (not stored). X/Y should copy from operand 0x08.
loadProgram(cpu, mem, 0x0000, 0x3E, 0x20, 0xFE, 0x08)
mustStep(t, cpu) // LD A,20
mustStep(t, cpu) // CP 08
// For CP, X/Y come from the operand (0x08 has X=1, Y=0).
assertFlag(t, cpu, FLAG_X, true, "CP X from operand")
assertFlag(t, cpu, FLAG_Y, false, "CP Y from operand")
// N must be set for CP
assertFlag(t, cpu, FLAG_N, true, "N set for CP")
}
// INC/DEC r affect flags and preserve C; X/Y come from result.
func TestINC_DEC_r_Flags(t *testing.T) {
cpu, mem, _ := testCPU()
// Set C flag first to ensure INC/DEC don't change it.
cpu.SetFlag(FLAG_C, true)
// 06 7F = LD B,7F; 04 = INC B; 05 = DEC B
loadProgram(cpu, mem, 0x0000, 0x06, 0x7F, 0x04, 0x05)
mustStep(t, cpu) // LD B,7F
mustStep(t, cpu) // INC B -> 0x80
assertEq(t, cpu.B, byte(0x80), "INC B result")
assertFlag(t, cpu, FLAG_PV, true, "INC overflow at 7F->80")
assertFlag(t, cpu, FLAG_C, true, "C preserved across INC")
mustStep(t, cpu) // DEC B -> 0x7F
assertEq(t, cpu.B, byte(0x7F), "DEC B result")
assertFlag(t, cpu, FLAG_PV, true, "DEC overflow at 80->7F")
assertFlag(t, cpu, FLAG_C, true, "C preserved across DEC")
}