Compare commits

..

No commits in common. "792c2457111bf9ab25761f3975f0b20541a81612" and "5387152a21ba507d31311b06dfeac3956d6946a0" have entirely different histories.

19 changed files with 33 additions and 45 deletions

View File

@ -3,7 +3,8 @@ package main
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"log"
"os"
)
@ -214,7 +215,6 @@ var oldLicensees = map[byte]string{
}
type ROMHeader struct {
_ [256]byte
EntryPoint [4]byte
Logo [48]byte
// NOTE(m): Assuming "old" cartridges here. This may cause problems with newer cartridges.
@ -228,7 +228,7 @@ type ROMHeader struct {
DestinationCode byte
OldLicenseeCode byte
MaskROMVersionNumber byte
Checksum byte
HeaderChecksum byte
GlobalChecksum [2]byte
}
@ -242,23 +242,32 @@ type Cartridge struct {
RAMSize string
Destination string
Version int
Checksum byte
}
func Insert(filename string) (Cartridge, error) {
cartridge := Cartridge{Filename: filename}
rom, err := os.ReadFile(filename)
func Insert(filename string) Cartridge {
file, err := os.Open(filename)
if err != nil {
return cartridge, err
log.Fatal(err)
}
defer file.Close()
cartridge := Cartridge{Filename: file.Name()}
// Jump to start of header
_, err = file.Seek(0x0100, io.SeekStart)
if err != nil {
log.Fatal(err)
}
// Read header
var header ROMHeader
buffer := bytes.NewReader(rom)
err = binary.Read(buffer, binary.LittleEndian, &header)
err = binary.Read(file, binary.LittleEndian, &header)
if err != nil {
return cartridge, nil
log.Fatal(err)
}
// Validate the ROM by checking presence of the Nintendo logo
if header.Logo != expectedLogo {
log.Fatal("Invalid ROM file: No valid logo found!")
}
// Convert some header values
@ -283,16 +292,10 @@ func Insert(filename string) (Cartridge, error) {
}
cartridge.Version = int(header.MaskROMVersionNumber)
// Calculate and verify checksum
for address := uint16(0x0134); address <= uint16(0x014C); address++ {
cartridge.Checksum = cartridge.Checksum - rom[address] - 1
}
if cartridge.Checksum != header.Checksum {
return cartridge, fmt.Errorf("ROM checksum failed: %X does not equal %X", cartridge.Checksum, header.Checksum)
}
// TODO(m): Verify header checksum
// NOTE(m): Ignoring global checksum which is not used, except by one emulator.
// See https://gbdev.io/pandocs/The_Cartridge_Header.html#014e-014f--global-checksum
return cartridge, nil
return cartridge
}

View File

@ -6,26 +6,16 @@ import (
"github.com/stretchr/testify/assert"
)
func TestInsert(t *testing.T) {
cartridge, err := Insert("./roms/dmg-acid2.gb")
func TestInsertCartridge(t *testing.T) {
cartridge := Insert("rom.gb")
assert := assert.New(t)
assert.Nil(err)
assert.Equal(cartridge.Filename, "./roms/dmg-acid2.gb")
assert.Equal(cartridge.Title, "DMG-ACID2")
assert.Equal(cartridge.Mapper, "ROM ONLY")
assert.Equal(cartridge.Licensee, "None")
assert.Equal(cartridge.Title, "SEIKEN DENSETSU")
assert.Equal(cartridge.Mapper, "MBC2+BATTERY")
assert.Equal(cartridge.Licensee, "Square")
assert.False(cartridge.SGBSupport, "SGB support should be false")
assert.Equal(cartridge.ROMSize, 32)
assert.Equal(cartridge.ROMSize, 256)
assert.Equal(cartridge.RAMSize, "0 - No RAM")
assert.Equal(cartridge.Destination, "Japan (and possibly overseas)")
assert.Equal(cartridge.Destination, "Overseas only")
assert.Equal(cartridge.Version, 0)
assert.Equal(cartridge.Checksum, byte(0x9F))
}
func TestFailedChecksum(t *testing.T) {
_, err := Insert("./roms/failed-checksum.gb")
assert.EqualError(t, err, "ROM checksum failed: 9F does not equal 41")
}

View File

@ -10,7 +10,7 @@ func main() {
// log.Fatalln("No rom file specified")
// }
// romPath := os.Args[1]
romPath := "./roms/dmg-acid2.gb"
romPath := "rom.gb"
ui.Run(romPath)
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -51,15 +51,10 @@ func (c *Controller) Run() {
running := true
for running {
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch e := event.(type) {
switch event.(type) {
case *sdl.QuitEvent:
println("Quit")
running = false
case *sdl.KeyboardEvent:
if e.Type == sdl.KEYDOWN {
if e.Keysym.Sym == sdl.K_ESCAPE {
running = false
}
}
}
}