first public release

This commit is contained in:
2025-09-25 15:29:49 +03:00
parent 6f90fda7a7
commit 24702e4419
41 changed files with 34202 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
package z80
import "testing"
// Basic conditional flow timing: JR cc, RET cc, CALL cc
func TestJRcc_RETcc_CALLcc_Timing_Basics(t *testing.T) {
cpu, mem, _ := testCPU()
// Make a small program space
// OR A (keeps Z=0), then JR Z,+2 (not taken), then XOR A (Z=1), JR NZ,+2 (not taken), JR Z,+2 (taken)
loadProgram(cpu, mem, 0x0000,
0xB7, // OR A (A starts FF; Z=0)
0x28, 0x02, // JR Z, +2 -> not taken (7)
0xAF, // XOR A -> A=0 Z=1
0x20, 0x02, // JR NZ, +2 -> not taken now (7)
0x28, 0x02, // JR Z, +2 -> taken (12)
0x00, 0x00,
)
cpu.A = 0xff // HUMAN: my cpu not set A to FF
mustStep(t, cpu)
assertEq(t, mustStep(t, cpu), 7, "JR Z not taken")
mustStep(t, cpu)
assertEq(t, mustStep(t, cpu), 7, "JR NZ not taken")
assertEq(t, mustStep(t, cpu), 12, "JR Z taken")
// RET cc: make a simple CALL, then set flags so condition is false/true
cpu, mem, _ = testCPU()
cpu.SP = 0xFFFE
// CALL next; place RET C (D8) and RET NC (D0) in two spots and test both timings
loadProgram(cpu, mem, 0x0000, 0xCD, 0x06, 0x00) // CALL 0006
mem.WriteByte(0x0006, 0xD8) // RET C
cpu.SetFlag(FLAG_C, false)
mustStep(t, cpu) // CALL
// RET C (not taken): 5 cycles
assertEq(t, mustStep(t, cpu), 5, "RET C not taken")
// Put RET NC; set C so taken path triggers
loadProgram(cpu, mem, cpu.PC, 0xCD, 0x06, 0x00)
mem.WriteByte(0x0006, 0xD0) // RET NC
cpu.SetFlag(FLAG_C, false)
pcBefore := cpu.PC
mustStep(t, cpu) // CALL
// RET NC (taken): 11 cycles
c := mustStep(t, cpu)
assertEq(t, c, 11, "RET NC taken")
assertEq(t, cpu.PC, pcBefore+3, "Returned to next instruction after CALL")
}
func TestDJNZ_Taken(t *testing.T) {
cpu, mem, _ := testCPU()
loadProgram(cpu, mem, 0x0000,
0x06, 0x02, // LD B,2
0x10, 0x02, // DJNZ +2 (B->1, taken)
)
mustStep(t, cpu) // LD B,2
assertEq(t, mustStep(t, cpu), 13, "DJNZ taken")
}
func TestDJNZ_NotTaken(t *testing.T) {
cpu, mem, _ := testCPU()
loadProgram(cpu, mem, 0x0000,
0x06, 0x01, // LD B,1
0x10, 0x02, // DJNZ +2 (B->0, not taken)
)
mustStep(t, cpu) // LD B,1
assertEq(t, mustStep(t, cpu), 8, "DJNZ not taken")
}