From 73ca1c81956343ec058b4509dd4a6a8dfebc92f6 Mon Sep 17 00:00:00 2001 From: Zellyn Hunter Date: Sun, 7 Apr 2013 21:20:15 -0700 Subject: [PATCH] moved memory testing out to separate file --- docs/visual.org | 1 + tests/compare_test.go | 76 +------------------------------ tests/memory.go | 103 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 74 deletions(-) create mode 100644 tests/memory.go diff --git a/docs/visual.org b/docs/visual.org index d4ac6e2..bda1d16 100644 --- a/docs/visual.org +++ b/docs/visual.org @@ -2,3 +2,4 @@ - Keep group state in a single mask, and index into a precomputed array of groupvalues. - Don't use a bitmap for transistor values. - Don't recompute in SetNode if nothing changed. +- Clear out the group membership bitmask as we go (one whole uint32 at a time) diff --git a/tests/compare_test.go b/tests/compare_test.go index 30293cd..acb7b52 100644 --- a/tests/compare_test.go +++ b/tests/compare_test.go @@ -5,7 +5,6 @@ Tests for the 6502 CPU emulator, comparing it with the transistor-level simulati package tests import ( - "fmt" "io/ioutil" "testing" @@ -13,77 +12,6 @@ import ( "github.com/zellyn/go6502/visual" ) -type memOp struct { - read bool - address uint16 - data byte -} - -func (op memOp) String() string { - rw := "W" - if op.read { - rw = "R" - } - return fmt.Sprintf("{%s $%04X: %02X}", rw, op.address, op.data) -} - -// Memory for the tests. Satisfies the cpu.Memory interface. -type memorizer struct { - mem1 [65536]byte - mem2 [65536]byte - ops []memOp - verify bool - errors []string -} - -func (m *memorizer) Reset() { - m.verify = false - m.errors = m.errors[:0] - m.ops = m.ops[:0] -} - -func (m *memorizer) Record() { - m.verify = false -} - -func (m *memorizer) Verify() { - m.verify = true -} - -func (m *memorizer) checkOp(newOp memOp) { - oldOp := m.ops[0] - m.ops = m.ops[1:] - if oldOp != newOp { - // fmt.Println(newOp, "expected:", oldOp) - m.errors = append(m.errors, fmt.Sprintf("Bad op: %v, expected %v", newOp, oldOp)) - } else { - // fmt.Println(newOp) - } -} - -func (m *memorizer) Read(address uint16) byte { - if !m.verify { // recording - data := m.mem1[address] - newOp := memOp{true, address, data} - m.ops = append(m.ops, newOp) - return data - } - data := m.mem2[address] - m.checkOp(memOp{true, address, data}) - return data -} - -func (m *memorizer) Write(address uint16, value byte) { - newOp := memOp{false, address, value} - if !m.verify { // recording - m.ops = append(m.ops, newOp) - m.mem1[address] = value - return - } - m.checkOp(newOp) - m.mem2[address] = value -} - // Run the first few thousand steps of Klaus Dormann's comprehensive // test against the instruction- and gate-level CPU emulations, making // sure they have the same memory access patterns. @@ -106,7 +34,7 @@ func TestFunctionalTestCompare(t *testing.T) { if err != nil { panic("Cannot read file") } - var m memorizer + var m Memorizer OFFSET := 0xa copy(m.mem1[OFFSET:len(bytes)+OFFSET], bytes) copy(m.mem2[OFFSET:len(bytes)+OFFSET], bytes) @@ -126,7 +54,7 @@ func TestFunctionalTestCompare(t *testing.T) { c := cpu.NewCPU(&m, &cc, cpu.VERSION_6502) c.Reset() - m.Reset() + m.Reset(MODE_RECORD) v.Step() v.Step() m.Verify() diff --git a/tests/memory.go b/tests/memory.go new file mode 100644 index 0000000..a9a23ec --- /dev/null +++ b/tests/memory.go @@ -0,0 +1,103 @@ +package tests + +import ( + "fmt" +) + +type MemOp struct { + read bool + address uint16 + data byte +} + +func (op MemOp) String() string { + rw := "W" + if op.read { + rw = "R" + } + return fmt.Sprintf("{%s $%04X: %02X}", rw, op.address, op.data) +} + +type Mode int + +const ( + MODE_SAVE_LAST Mode = iota // Just hold the last action + MODE_RECORD // Record all memory actions + MODE_VERIFY // Verify that the recorded actions match +) + +// Memory for the tests. Satisfies the cpu.Memory interface. +type Memorizer struct { + mem1 [65536]byte + mem2 [65536]byte + ops []MemOp + mode Mode + errors []string + last MemOp +} + +func (m *Memorizer) Reset(mode Mode) { + m.mode = mode + m.errors = m.errors[:0] + m.ops = m.ops[:0] +} + +func (m *Memorizer) Record() { + m.mode = MODE_RECORD +} + +func (m *Memorizer) Verify() { + m.mode = MODE_VERIFY +} + +func (m *Memorizer) SaveLast() { + m.mode = MODE_SAVE_LAST +} + +func (m *Memorizer) checkOp(newOp MemOp) { + oldOp := m.ops[0] + m.ops = m.ops[1:] + if oldOp != newOp { + // fmt.Println(newOp, "expected:", oldOp) + m.errors = append(m.errors, fmt.Sprintf("Bad op: %v, expected %v", newOp, oldOp)) + } else { + // fmt.Println(newOp) + } +} + +func (m *Memorizer) Read(address uint16) byte { + switch m.mode { + case MODE_RECORD: + data := m.mem1[address] + m.ops = append(m.ops, MemOp{true, address, data}) + return data + case MODE_VERIFY: + data := m.mem2[address] + m.checkOp(MemOp{true, address, data}) + return data + case MODE_SAVE_LAST: + data := m.mem1[address] + m.last = MemOp{true, address, data} + return data + } + panic("Unknown MODE") +} + +func (m *Memorizer) Write(address uint16, value byte) { + newOp := MemOp{false, address, value} + switch m.mode { + case MODE_RECORD: + m.ops = append(m.ops, newOp) + m.mem1[address] = value + return + case MODE_VERIFY: + m.checkOp(newOp) + m.mem2[address] = value + return + case MODE_SAVE_LAST: + m.last = newOp + m.mem1[address] = value + return + } + panic("Unknown MODE") +}