From 8b0292cccf768efdd5295fe0b662488cbc671079 Mon Sep 17 00:00:00 2001 From: crecher Date: Mon, 12 Oct 2026 04:07:09 +0200 Subject: added cart package, more tests, tests are now at ./tests and added .gitignore --- cpu/nestest_test.go | 139 ---------------------------------------------------- 1 file changed, 139 deletions(-) delete mode 100644 cpu/nestest_test.go (limited to 'cpu/nestest_test.go') diff --git a/cpu/nestest_test.go b/cpu/nestest_test.go deleted file mode 100644 index 4786c5b..0000000 --- a/cpu/nestest_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package cpu - -import ( - "bufio" - "os" - "regexp" - "strconv" - "testing" -) - -type nestestBus struct { - ram [0x0800]uint8 - prg []uint8 -} - -func (b *nestestBus) Read(addr uint16) uint8 { - switch { - case addr < 0x2000: - return b.ram[addr%0x0800] - case addr >= 0x8000: - return b.prg[int(addr-0x8000)%len(b.prg)] - default: - return 0 - } -} - -func (b *nestestBus) Write(addr uint16, v uint8) { - if addr < 0x2000 { - b.ram[addr%0x0800] = v - } -} - -func loadNestestPRG(path string) ([]uint8, error) { - data, err := os.ReadFile(path) - if err != nil { - return nil, err - } - prgBanks := int(data[4]) - prgSize := prgBanks * 16 * 1024 - hasTrainer := data[6]&0x04 != 0 - offset := 16 - if hasTrainer { - offset += 512 - } - return data[offset : offset+prgSize], nil -} - -type cpuState struct { - pc uint16 - a, x, y, p, sp uint8 - cyc uint64 -} - -var nestestLogRE = regexp.MustCompile( - `^([0-9A-F]{4}).*A:([0-9A-F]{2}) X:([0-9A-F]{2}) Y:([0-9A-F]{2}) P:([0-9A-F]{2}) SP:([0-9A-F]{2}).*CYC:\s*(\d+)`) - -func loadNestestLog(path string) ([]cpuState, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - - var lines []cpuState - scanner := bufio.NewScanner(f) - for scanner.Scan() { - m := nestestLogRE.FindStringSubmatch(scanner.Text()) - if m == nil { - continue - } - parseHex8 := func(s string) uint8 { - v, _ := strconv.ParseUint(s, 16, 8) - return uint8(v) - } - pc, _ := strconv.ParseUint(m[1], 16, 16) - cyc, _ := strconv.ParseUint(m[7], 10, 64) - lines = append(lines, cpuState{ - pc: uint16(pc), - a: parseHex8(m[2]), - x: parseHex8(m[3]), - y: parseHex8(m[4]), - p: parseHex8(m[5]), - sp: parseHex8(m[6]), - cyc: cyc, - }) - } - return lines, scanner.Err() -} - -// TestNestest runs nestest.nes and diffs the state against a known good log before each instruction -func TestNestest(t *testing.T) { - const romPath = "testdata/nestest.nes" - const logPath = "testdata/nestest.log" - - if _, err := os.Stat(romPath); err != nil { - t.Skip("testdata/nestest.nes not present; add it and testdata/nestest.log to run this test") - } - - prg, err := loadNestestPRG(romPath) - if err != nil { - t.Fatalf("loading ROM: %v", err) - } - want, err := loadNestestLog(logPath) - if err != nil { - t.Fatalf("loading log: %v", err) - } - if len(want) == 0 { - t.Fatal("no log lines parsed") - } - - bus := &nestestBus{prg: prg} - c := NewCPU(bus) - c.PC = 0xC000 - c.SP = 0xFD - c.Status = 0x24 - c.Cycles = want[0].cyc - - for i, w := range want { - got := cpuState{c.PC, c.A, c.X, c.Y, c.Status, c.SP, c.Cycles} - if got != w { - t.Fatalf("line %d: got %+v, want %+v", i+1, got, w) - } - - stopped := func() (panicked bool) { - defer func() { - if r := recover(); r != nil { - t.Logf("stopped at line %d: %v", i+1, r) - panicked = true - } - }() - c.Step() - return false - }() - if stopped { - t.Logf("matched %d instructions before stopping", i+1) - return - } - } -} -- cgit v1.2.3