aboutsummaryrefslogtreecommitdiff
path: root/tests/dma_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'tests/dma_test.go')
-rw-r--r--tests/dma_test.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/tests/dma_test.go b/tests/dma_test.go
new file mode 100644
index 0000000..db38d9e
--- /dev/null
+++ b/tests/dma_test.go
@@ -0,0 +1,78 @@
+package tests
+
+import (
+ "testing"
+
+ "crecher.net/gones/v2/nes"
+)
+
+func fillPage(n *nes.Console, page uint8) {
+ for i := 0; i < 256; i++ {
+ n.Write(uint16(page)<<8|uint16(i), uint8(i))
+ }
+}
+
+func TestOAMDMACopiesPage(t *testing.T) {
+ n := newTestConsole(t)
+ fillPage(n, 0x02)
+ n.Write(0x4014, 0x02)
+
+ for i := 0; i < 256; i++ {
+ if n.PPU.OAM[i] != uint8(i) {
+ t.Fatalf("OAM[%d] = %d, want %d", i, n.PPU.OAM[i], i)
+ }
+ }
+}
+
+func TestOAMDMAStartsAtOAMAddr(t *testing.T) {
+ n := newTestConsole(t)
+ fillPage(n, 0x03)
+ n.Write(0x2003, 0x10)
+ n.Write(0x4014, 0x03)
+
+ // source byte 0 lands at OAM[0x10], and the copy wraps around
+ for _, i := range []int{0, 1, 0xF0, 0xFF} {
+ if got := n.PPU.OAM[(0x10+i)&0xFF]; got != uint8(i) {
+ t.Errorf("OAM[0x%02X] = %d, want %d", (0x10+i)&0xFF, got, i)
+ }
+ }
+}
+
+// runs `lda ; sta $4014` from RAM and returns the cycles the sta step took
+func dmaStepCycles(t *testing.T, lda []uint8) int {
+ t.Helper()
+ n := newTestConsole(t)
+ prog := append(lda, 0x8D, 0x14, 0x40) // sta $4014
+ for i, b := range prog {
+ n.Write(0x0200+uint16(i), b)
+ }
+ n.Write(0x0000, 0x02) // for the zero page lda
+ n.CPU.PC = 0x0200
+ n.Step()
+ return n.Step()
+}
+
+func TestOAMDMAStallCycles(t *testing.T) {
+ // reset leaves the cpu at 7 cycles
+ // lda #imm (2): sta ends on cycle 13, odd -> 4 + 514
+ if got := dmaStepCycles(t, []uint8{0xA9, 0x02}); got != 518 {
+ t.Errorf("odd start: sta step = %d cycles, want 518", got)
+ }
+ // lda zp (3): sta ends on cycle 14, even -> 4 + 513
+ if got := dmaStepCycles(t, []uint8{0xA5, 0x00}); got != 517 {
+ t.Errorf("even start: sta step = %d cycles, want 517", got)
+ }
+}
+
+func TestOAMDMAAdvancesCPUCycles(t *testing.T) {
+ n := newTestConsole(t)
+ for i, b := range []uint8{0xA9, 0x02, 0x8D, 0x14, 0x40} {
+ n.Write(0x0200+uint16(i), b)
+ }
+ n.CPU.PC = 0x0200
+ n.Step()
+ n.Step()
+ if n.CPU.Cycles != 7+2+4+514 {
+ t.Errorf("CPU.Cycles = %d, want %d", n.CPU.Cycles, 7+2+4+514)
+ }
+}