// Load a game func (deck *ControlDeck) Load(filename string) (err string, success bool) { defer func() { if r := recover(); r != nil { err = fmt.Sprintf("Failed to load %s: %s", filename, r) success = false } }() deck.InsertedCartridge = cartridge.LoadFile(filename) // Check ROM against known hashes, and set deck.InsertedCartridge.SHA1 // TODO: maybe this should be in nesfile, or in controldeck? matches := cartdb.Identify(cartdb.Load(), deck.InsertedCartridge) fmt.Printf("Cartridge SHA-1 = %s\n", deck.InsertedCartridge.SHA1) if len(matches) != 0 { fmt.Printf("cartdb: found %d matching cartridges:\n", len(matches)) } for i, match := range matches { fmt.Printf("%d. ", i) cartdb.DumpMatch(match) } // TODO: use info here, to display title/image, or use mapper deck.InsertedCartridge.LoadPRG(deck.CPU) deck.InsertedCartridge.LoadCHR(deck.PPU) // nestest.nes (TODO: better way to have local additions to cartdb!) if deck.InsertedCartridge.SHA1 == "4131307F0F69F2A5C54B7D438328C5B2A5ED0820" { // TODO: only do this when running in automated mode, still want GUI mode unaffected fmt.Printf("Identified nestest; mapping for automation\n") deck.CPU.MapOver(0xc66e, // The known-correct log http://nickmass.com/images/nestest.log ends at $C66E, on RTS func(address uint16)(value uint8) { // http://nesdev.com/bbs/viewtopic.php?t=7130 result := deck.CPU.ReadFrom(2) << 8 | deck.CPU.ReadFrom(3) if result == 0 { fmt.Printf("Nestest automation: Pass\n") } else { fmt.Printf("Nestest automation: FAIL with code %.4x\n", result) } // Signal to stop CPU (KIL instruction) // TODO: find a better way to quit the program. Could quit here, but // then last instruction trace wouldn't match expected log. deck.InternalRAM[0x0001] = 0x02 return 0x60 }, func(address uint16, value uint8) { }, "nestest-automation") } return err, true }
// Read a bunch of files from a directory func (deck *ControlDeck) LoadDir(dirname string) { filenames, err := ioutil.ReadDir(dirname) if err != nil { panic(fmt.Sprintf("LoadDir(%s) failed: %s", dirname, err)) } mapperUsage := make(map[string]int) // Show information about each file for _, fileInfo := range filenames { path := fmt.Sprintf("%s/%s", dirname, fileInfo.Name) fmt.Printf("%s\n", path) cart := cartridge.LoadFile(path) fmt.Printf("%s\t%s\n", cart.MapperName, fileInfo.Name) mapperUsage[cart.MapperName] += 1 } // Show mapper usage frequency fmt.Printf("\n") for mapper, count := range mapperUsage { fmt.Printf("%d\t%s\n", count, mapper) } }