func (c *Cartridge) String() string { startingString := "Gameboy" if c.IsColourGB { startingString += " Color" } var destinationRegion string if c.IsJapanese { destinationRegion = "Japanese" } else { destinationRegion = "Non-Japanese" } var header []string = []string{ fmt.Sprintf(utils.PadRight("Title:", 19, " ")+"%s", c.Title), fmt.Sprintf(utils.PadRight("Type:", 19, " ")+"%s %s", c.Type.Description, utils.ByteToString(c.Type.ID)), fmt.Sprintf(utils.PadRight("Destination code:", 19, " ")+"%s", destinationRegion), fmt.Sprintf(utils.PadRight("File:", 19, " ")+"%s", c.Filename), } return fmt.Sprintln("\n"+startingString, "Cartridge") + fmt.Sprintln(strings.Repeat("-", 50)) + fmt.Sprintln(strings.Join(header, "\n")) + fmt.Sprintln(c.MBC) + fmt.Sprintln(strings.Repeat("-", 50)) }
func (c *Cartridge) Init(rom []byte) error { if size := len(rom); size < 32768 { return errors.New(fmt.Sprintf("ROM size %d is too small", size)) } c.Title = strings.TrimSpace(string(rom[0x0134:0x0142])) c.IsColourGB = (rom[0x0143] == 0x80) || (rom[0x0143] == 0xC0) ctype := rom[0x0147] //validate if v, ok := CartridgeTypes[ctype]; !ok { return errors.New(fmt.Sprintf("Unknown cartridge type: %X for ROM", ctype)) } else { c.Type = v } if romSize := rom[0x0148]; romSize > 0x06 { return errors.New(fmt.Sprintf("Handling for ROM size id: 0x%X is currently unimplemented", romSize)) } else { c.ROMSize = 0x8000 << romSize } switch rom[0x0149] { case 0x00: c.RAMSize = 0 case 0x01: c.RAMSize = 2048 case 0x02: c.RAMSize = 8192 case 0x03: c.RAMSize = 32768 case 0x04: c.RAMSize = 131072 } c.IsJapanese = (rom[0x014A] == 0x00) switch c.Type.ID { case MBC_0: c.MBC = NewMBC0(rom) case MBC_1, MBC_1_RAM: c.MBC = NewMBC1(rom, c.ROMSize, c.RAMSize, false) case MBC_1_RAM_BATT: c.MBC = NewMBC1(rom, c.ROMSize, c.RAMSize, true) case MBC_3_RAM_BATT: c.MBC = NewMBC3(rom, c.ROMSize, c.RAMSize, true, false) case MBC_3_RAM_BATT_TIMER: c.MBC = NewMBC3(rom, c.ROMSize, c.RAMSize, true, true) case MBC_5, MBC_5_RAM, MBC_5_RUMBLE, MBC_5_RAM_RUMBLE: c.MBC = NewMBC5(rom, c.ROMSize, c.RAMSize, false) case MBC_5_RAM_BATT, MBC_5_RAM_BATT_RUMBLE: c.MBC = NewMBC5(rom, c.ROMSize, c.RAMSize, true) default: return errors.New("Error: Cartridge type " + utils.ByteToString(c.Type.ID) + " is currently unsupported") } return nil }
func AssertTimings(c *GbcCPU, t *testing.T, instr byte, expectedTiming int, isCB bool) { tick := c.Step() if isCB { log.Println("0xCB "+utils.ByteToString(instr)+" ("+c.CurrentInstruction.Description+")", "testing that instruction runs for", expectedTiming, "cycles") } else { log.Println(utils.ByteToString(instr)+" ("+c.CurrentInstruction.Description+")", "testing that instruction runs for", expectedTiming, "cycles") } if tick != expectedTiming { if isCB { t.Log("-----> For instruction 0xCB", utils.ByteToString(instr)+" ("+c.CurrentInstruction.Description+")", "Expected", expectedTiming, "but got", tick) } else { t.Log("-----> For instruction", utils.ByteToString(instr)+" ("+c.CurrentInstruction.Description+")", "Expected", expectedTiming, "but got", tick) } t.FailNow() } }
func getTimingFromInstructionServer(instr byte) int { conn, err := net.Dial("tcp", "localhost:8012") if err != nil { log.Println("error!") } var writer *bufio.Writer = bufio.NewWriter(conn) var reader *bufio.Reader = bufio.NewReader(conn) instrString := utils.ByteToString(instr) writer.WriteString(instrString + "\n") writer.Flush() result, _ := reader.ReadString('\n') conn.Close() i, _ := strconv.Atoi(result) return int(i) }
func (i Instruction) String() string { return fmt.Sprintf("%s %s %s %s", utils.ByteToString(i.Opcode), utils.ByteToString(i.Operands[0]), utils.ByteToString(i.Operands[1]), i.Description) }