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 --- cart/cart.go | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 cart/cart.go (limited to 'cart/cart.go') diff --git a/cart/cart.go b/cart/cart.go new file mode 100644 index 0000000..2438c1b --- /dev/null +++ b/cart/cart.go @@ -0,0 +1,83 @@ +package cart + +import ( + "bytes" + "errors" + "fmt" + "os" +) + +type Cartridge struct { + PRG []uint8 + CHR []uint8 + CHRIsRAM bool + MapperID uint8 + Mirroring Mirroring + Battery bool + + Mapper Mapper +} + +func Load(path string) (*Cartridge, error) { + data, err := os.ReadFile(path) + if err != nil { + return nil, err + } + return Parse(data) +} + +func Parse(data []byte) (*Cartridge, error) { + if len(data) < 16 || !bytes.Equal(data[:4], []byte("NES\x1A")) { + return nil, errors.New("cart: not an iNES file") + } + + prgSize := int(data[4]) * 16 * 1024 + chrSize := int(data[5]) * 8 * 1024 + flags6, flags7 := data[6], data[7] + + isNES2 := flags7&0x0C == 0x08 + mapperID := flags6 >> 4 + if isNES2 || bytes.Equal(data[12:16], []byte{0, 0, 0, 0}) { + mapperID |= flags7 & 0xF0 + } + + c := &Cartridge{ + MapperID: mapperID, + Battery: flags6&0x02 != 0, + } + + switch { + case flags6&0x08 != 0: + c.Mirroring = FourScreen + case flags6&0x01 != 0: + c.Mirroring = Vertical + default: + c.Mirroring = Horizontal + } + + offset := 16 + if flags6&0x04 != 0 { + offset += 512 + } + if len(data) < offset+prgSize+chrSize { + return nil, fmt.Errorf("cart: file truncated: need %d bytes, have %d", + offset+prgSize+chrSize, len(data)) + } + + c.PRG = data[offset : offset+prgSize] + offset += prgSize + + if chrSize == 0 { + c.CHR = make([]uint8, 8*1024) + c.CHRIsRAM = true + } else { + c.CHR = data[offset : offset+chrSize] + } + + m, err := newMapper(c) + if err != nil { + return nil, err + } + c.Mapper = m + return c, nil +} -- cgit v1.2.3