Skip to content

Commit

Permalink
chore(cartridge): Change PRG to public visibility and keep INES hea…
Browse files Browse the repository at this point in the history
…der in memory
  • Loading branch information
gabe565 committed Jan 28, 2025
1 parent 7c2d1df commit a1a3150
Show file tree
Hide file tree
Showing 16 changed files with 63 additions and 65 deletions.
2 changes: 1 addition & 1 deletion cmd/gones/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func newConsole(conf *config.Config, path string) (*console.Console, error) {
}
}

cart, err := cartridge.FromiNesFile(path)
cart, err := cartridge.FromINESFile(path)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/gones/console_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func newConsole(conf *config.Config, _ string) (*console.Console, error) {

r := bytes.NewReader(goData)

cart, err := cartridge.FromiNes(r)
cart, err := cartridge.FromINES(r)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/nesutil/ls/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func loadPaths(paths []string) ([]*entry, bool) {
go func() {
defer wg.Done()

cart, err := cartridge.FromiNesFile(path)
cart, err := cartridge.FromINESFile(path)
if err != nil {
slog.Error("Invalid ROM", "path", path, "error", err)
failed = true
Expand Down
2 changes: 1 addition & 1 deletion cmd/nesutil/ls/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ func newEntry(file string, cart *cartridge.Cartridge) *entry {
return &entry{
Path: file,
Name: cart.Name(),
Mapper: cart.Mapper,
Mapper: cart.Header.Mapper(),
Mirror: cart.Mirror.String(),
Battery: cart.Battery,
Hash: cart.Hash(),
Expand Down
25 changes: 12 additions & 13 deletions internal/cartridge/cartridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@ import (
)

type Cartridge struct {
hash string
name string
hash string
name string
Header INESFileHeader `msgpack:"-"`

prg []byte
CHR []byte `msgpack:"alias:Chr"`
SRAM []byte `msgpack:"alias:Sram"`
Mapper uint8 `msgpack:"-"`
Submapper uint8 `msgpack:"-"`
Mirror Mirror
Battery bool `msgpack:"-"`
PRG []byte `msgpack:"-"`
CHR []byte `msgpack:"alias:Chr"`
SRAM []byte `msgpack:"alias:Sram"`
Mirror Mirror
Battery bool `msgpack:"-"`
}

func New() *Cartridge {
Expand All @@ -38,10 +37,10 @@ func FromBytes(b []byte) *Cartridge {
cart.name, _ = database.FindNameByHash(cart.hash)
}

cart.prg = make([]byte, consts.PRGROMAddr, consts.PRGChunkSize*2)
cart.prg = append(cart.prg, b...)
cart.prg = cart.prg[:cap(cart.prg)]
cart.prg[interrupt.ResetVector+1-consts.PRGChunkSize*2] = 0x86
cart.PRG = make([]byte, consts.PRGROMAddr, consts.PRGChunkSize*2)
cart.PRG = append(cart.PRG, b...)
cart.PRG = cart.PRG[:cap(cart.PRG)]
cart.PRG[interrupt.ResetVector+1-consts.PRGChunkSize*2] = 0x86

cart.CHR = make([]byte, consts.CHRChunkSize)

Expand Down
37 changes: 18 additions & 19 deletions internal/cartridge/ines.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,43 @@ import (
"gabe565.com/gones/internal/database"
)

type iNESFileHeader struct {
type INESFileHeader struct {
Magic [4]byte
PRGCount byte
CHRCount byte
Control [3]byte
_ [7]byte
}

func (i iNESFileHeader) Mapper() uint8 {
func (i INESFileHeader) Mapper() uint8 {
return i.Control[1]&0xF0 | i.Control[0]>>4
}

func (i iNESFileHeader) Mirror() Mirror {
func (i INESFileHeader) Mirror() Mirror {
if i.Control[0]&0x8 != 0 {
return FourScreen
}
return Mirror(i.Control[0] & 1)
}

func (i iNESFileHeader) Battery() bool {
func (i INESFileHeader) Battery() bool {
return i.Control[0]&0x2 != 0
}

func (i iNESFileHeader) NESv2() bool {
func (i INESFileHeader) NESv2() bool {
return i.Control[1]&0xC == 0x8
}

func (i iNESFileHeader) Submapper() uint8 {
return i.Control[2] >> 4
func (i INESFileHeader) Submapper() uint8 {
if i.NESv2() {
return i.Control[2] >> 4
}
return 0
}

var ErrInvalidROM = errors.New("invalid ROM file")

func FromiNesFile(path string) (*Cartridge, error) {
func FromINESFile(path string) (*Cartridge, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
Expand All @@ -58,7 +61,7 @@ func FromiNesFile(path string) (*Cartridge, error) {
_ = f.Close()
}(f)

cartridge, err := FromiNes(f)
cartridge, err := FromINES(f)
if err != nil {
return nil, err
}
Expand All @@ -69,11 +72,11 @@ func FromiNesFile(path string) (*Cartridge, error) {
return cartridge, nil
}

func FromiNes(r io.Reader) (*Cartridge, error) {
func FromINES(r io.Reader) (*Cartridge, error) {
hasher := md5.New()
tr := io.TeeReader(r, hasher)

var header iNESFileHeader
var header INESFileHeader
if err := binary.Read(tr, binary.LittleEndian, &header); err != nil {
return nil, err
}
Expand All @@ -83,24 +86,20 @@ func FromiNes(r io.Reader) (*Cartridge, error) {
}

cartridge := New()
cartridge.Mapper = header.Mapper()
cartridge.Header = header
cartridge.Mirror = header.Mirror()
cartridge.Battery = header.Battery()

if header.NESv2() {
cartridge.Submapper = header.Submapper()
}

slog.Debug("Loaded iNES header",
"battery", cartridge.Battery,
"mapper", cartridge.Mapper,
"mapper", header.Mapper(),
"mirror", cartridge.Mirror,
"prg", header.PRGCount,
"chr", header.CHRCount,
)

cartridge.prg = make([]byte, int(header.PRGCount)*consts.PRGChunkSize)
if _, err := io.ReadFull(tr, cartridge.prg); err != nil {
cartridge.PRG = make([]byte, int(header.PRGCount)*consts.PRGChunkSize)
if _, err := io.ReadFull(tr, cartridge.PRG); err != nil {
return nil, err
}

Expand Down
12 changes: 6 additions & 6 deletions internal/cartridge/ines_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package cartridge

import "testing"

func Test_iNESFileHeader_Battery(t *testing.T) {
func Test_INESFileHeader_Battery(t *testing.T) {
t.Parallel()

type fields struct {
Expand All @@ -21,7 +21,7 @@ func Test_iNESFileHeader_Battery(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
i := iNESFileHeader{
i := INESFileHeader{
Control: tt.fields.Control,
}
if got := i.Battery(); got != tt.want {
Expand All @@ -31,7 +31,7 @@ func Test_iNESFileHeader_Battery(t *testing.T) {
}
}

func Test_iNESFileHeader_Mirror(t *testing.T) {
func Test_INESFileHeader_Mirror(t *testing.T) {
t.Parallel()

type fields struct {
Expand All @@ -49,7 +49,7 @@ func Test_iNESFileHeader_Mirror(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
i := iNESFileHeader{
i := INESFileHeader{
Control: tt.fields.Control,
}
if got := i.Mirror(); got != tt.want {
Expand All @@ -59,7 +59,7 @@ func Test_iNESFileHeader_Mirror(t *testing.T) {
}
}

func Test_iNESFileHeader_Mapper(t *testing.T) {
func Test_INESFileHeader_Mapper(t *testing.T) {
t.Parallel()

type fields struct {
Expand All @@ -78,7 +78,7 @@ func Test_iNESFileHeader_Mapper(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
i := iNESFileHeader{
i := INESFileHeader{
Control: tt.fields.Control,
}
if got := i.Mapper(); got != tt.want {
Expand Down
4 changes: 2 additions & 2 deletions internal/cartridge/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type MapperIRQ interface {
var ErrUnsupportedMapper = errors.New("unsupported mapper")

func NewMapper(cartridge *Cartridge) (Mapper, error) { //nolint:ireturn,nolintlint
switch cartridge.Mapper {
switch cartridge.Header.Mapper() {
case 0, 2:
return NewMapper2(cartridge), nil
case 1:
Expand All @@ -49,6 +49,6 @@ func NewMapper(cartridge *Cartridge) (Mapper, error) { //nolint:ireturn,nolintli
case 71:
return NewMapper71(cartridge), nil
default:
return nil, fmt.Errorf("%w: %d", ErrUnsupportedMapper, cartridge.Mapper)
return nil, fmt.Errorf("%w: %d", ErrUnsupportedMapper, cartridge.Header.Mapper())
}
}
6 changes: 3 additions & 3 deletions internal/cartridge/mapper_1.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (m *Mapper1) ReadMem(addr uint16) byte {
addr -= 0x8000
bank := addr / consts.PRGChunkSize
offset := int(addr % consts.PRGChunkSize)
return m.cartridge.prg[m.PRGOffsets[bank]+offset]
return m.cartridge.PRG[m.PRGOffsets[bank]+offset]
default:
slog.Error("Invalid mapper 1 read", "addr", log.HexAddr(addr))
return 0
Expand Down Expand Up @@ -114,10 +114,10 @@ func (m *Mapper1) prgBankOffset(i int) int {
if i >= 0x80 {
i -= 0x100
}
i %= len(m.cartridge.prg) / consts.PRGChunkSize
i %= len(m.cartridge.PRG) / consts.PRGChunkSize
offset := i * consts.PRGChunkSize
if offset < 0 {
offset += len(m.cartridge.prg)
offset += len(m.cartridge.PRG)
}
return offset
}
Expand Down
6 changes: 3 additions & 3 deletions internal/cartridge/mapper_2.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func NewMapper2(cartridge *Cartridge) *Mapper2 {
prgBanks := uint(len(cartridge.prg) / consts.PRGChunkSize)
prgBanks := uint(len(cartridge.PRG) / consts.PRGChunkSize)
mapper := &Mapper2{
cartridge: cartridge,
PRGBanks: prgBanks,
Expand Down Expand Up @@ -39,12 +39,12 @@ func (m *Mapper2) ReadMem(addr uint16) byte {
addr := uint(addr)
addr -= 0x8000
addr += m.PRGBank1 * consts.PRGChunkSize
return m.cartridge.prg[addr]
return m.cartridge.PRG[addr]
case 0xC000 <= addr:
addr := uint(addr)
addr -= 0xC000
addr += m.PRGBank2 * consts.PRGChunkSize
return m.cartridge.prg[addr]
return m.cartridge.PRG[addr]
default:
slog.Error("Invalid mapper 2 read", "addr", log.HexAddr(addr))
return 0
Expand Down
6 changes: 3 additions & 3 deletions internal/cartridge/mapper_3.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func NewMapper3(cartridge *Cartridge) *Mapper3 {
prgBanks := uint(len(cartridge.prg) / consts.PRGChunkSize)
prgBanks := uint(len(cartridge.PRG) / consts.PRGChunkSize)
mapper := &Mapper3{
cartridge: cartridge,
PRGBank2: prgBanks - 1,
Expand Down Expand Up @@ -40,12 +40,12 @@ func (m *Mapper3) ReadMem(addr uint16) byte {
addr := uint(addr)
addr -= 0x8000
addr += m.PRGBank1 * consts.PRGChunkSize
return m.cartridge.prg[addr]
return m.cartridge.PRG[addr]
case 0xC000 <= addr:
addr := uint(addr)
addr -= 0xC000
addr += m.PRGBank2 * consts.PRGChunkSize
return m.cartridge.prg[addr]
return m.cartridge.PRG[addr]
default:
slog.Error("Invalid mapper 3 read", "addr", log.HexAddr(addr))
return 0
Expand Down
8 changes: 4 additions & 4 deletions internal/cartridge/mapper_4.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (m *Mapper4) IRQ() bool { return m.IRQPending }

func (m *Mapper4) OnVRAMAddr(addr registers.Address) {
curr := addr.FineY&1 == 1
switch m.cartridge.Submapper {
switch m.cartridge.Header.Submapper() {
case SubmapperMcAcc:
if m.PrevA12 && !curr {
m.OnScanline()
Expand All @@ -76,7 +76,7 @@ func (m *Mapper4) ReadMem(addr uint16) byte {
addr -= 0x8000
bank := addr / 0x2000
offset := int(addr % 0x2000)
return m.cartridge.prg[m.PRGOffsets[bank]+offset]
return m.cartridge.PRG[m.PRGOffsets[bank]+offset]
default:
slog.Error("Invalid mapper 4 read", "addr", log.HexAddr(addr))
return 0
Expand Down Expand Up @@ -136,10 +136,10 @@ func (m *Mapper4) prgBankOffset(i int) int {
if i >= 0x80 {
i -= 0x100
}
i %= len(m.cartridge.prg) / 0x2000
i %= len(m.cartridge.PRG) / 0x2000
offset := i * 0x2000
if offset < 0 {
offset += len(m.cartridge.prg)
offset += len(m.cartridge.PRG)
}
return offset
}
Expand Down
4 changes: 2 additions & 2 deletions internal/cartridge/mapper_69.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

func NewMapper69(cartridge *Cartridge) *Mapper69 {
prgCount := len(cartridge.prg) / 0x2000
prgCount := len(cartridge.PRG) / 0x2000
mapper := &Mapper69{
cartridge: cartridge,
PRGCount: byte(prgCount),
Expand Down Expand Up @@ -72,7 +72,7 @@ func (m *Mapper69) ReadMem(addr uint16) byte {
bank := addr / 0x2000
offset := int(addr % 0x2000)
addr := m.PRGBanks[bank]*0x2000 + offset
return m.cartridge.prg[addr%len(m.cartridge.prg)]
return m.cartridge.PRG[addr%len(m.cartridge.PRG)]
default:
slog.Error("Invalid mapper 69 read", "addr", log.HexAddr(addr))
return 0
Expand Down
4 changes: 2 additions & 2 deletions internal/cartridge/mapper_7.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func (m *Mapper7) ReadMem(addr uint16) byte {
addr := uint(addr)
addr -= 0x8000
addr += m.PRGBank * 2 * consts.PRGChunkSize
addr %= uint(len(m.cartridge.prg))
return m.cartridge.prg[addr]
addr %= uint(len(m.cartridge.PRG))
return m.cartridge.PRG[addr]
default:
slog.Error("Invalid mapper 7 read", "addr", log.HexAddr(addr))
return 0
Expand Down
Loading

0 comments on commit a1a3150

Please sign in to comment.