first public release
This commit is contained in:
67
flow_conditionals_simple_test.go
Normal file
67
flow_conditionals_simple_test.go
Normal 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")
|
||||
}
|
||||
Reference in New Issue
Block a user