Skip to content

Commit

Permalink
refactor panics to error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
cornelk committed Dec 11, 2024
1 parent 2657203 commit f1e5b7d
Show file tree
Hide file tree
Showing 24 changed files with 117 additions and 79 deletions.
2 changes: 1 addition & 1 deletion internal/testroms/nestest/nestest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestNestest(t *testing.T) {
nes.WithDisabledGUI(),
nes.WithTracingTarget(trace),
}
nes.Start(options...)
assert.NoError(t, nes.Start(options...))

assert.NoError(t, trace.Flush())

Expand Down
4 changes: 3 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ func emulateFile(options optionFlags) error {
opts = append(opts, nes.WithDisabledGUI())
}

nes.Start(opts...)
if err := nes.Start(opts...); err != nil {
return fmt.Errorf("starting emulator: %w", err)
}
return nil
}
7 changes: 5 additions & 2 deletions pkg/mapper/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/retroenv/nesgoemu/pkg/mapper/mapperdb"
)

type mapperInitializer func(base mapperdb.Base) bus.Mapper
type mapperInitializer func(base mapperdb.Base) (bus.Mapper, error)

var mappers = map[byte]mapperInitializer{
0: mapperdb.NewNROM,
Expand All @@ -33,6 +33,9 @@ func New(bus *bus.Bus) (bus.Mapper, error) {
}

base := mapperbase.New(bus)
mapper := initializer(base)
mapper, err := initializer(base)
if err != nil {
return nil, err
}
return mapper, nil
}
9 changes: 7 additions & 2 deletions pkg/mapper/mapperbase/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ func (b *Base) Read(address uint16) uint8 {

for _, hook := range b.readHooks {
if address >= hook.startAddress && address <= hook.endAddress {
value = hook.hookFunc(address)
value, err := hook.hookFunc(address)
if err != nil {
panic(fmt.Sprintf("read hook error: %v", err))
}
if !hook.onlyProxy {
return value
}
Expand Down Expand Up @@ -128,7 +131,9 @@ func (b *Base) Read(address uint16) uint8 {
func (b *Base) Write(address uint16, value uint8) {
for _, hook := range b.writeHooks {
if address >= hook.startAddress && address <= hook.endAddress {
hook.hookFunc(address, value)
if err := hook.hookFunc(address, value); err != nil {
panic(fmt.Errorf("write hook error: %w", err))
}
if !hook.onlyProxy {
return
}
Expand Down
12 changes: 8 additions & 4 deletions pkg/mapper/mapperbase/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ type Hook interface {
SetProxyOnly(proxy bool)
}

type ReadHookFunc func(address uint16) (uint8, error)

type WriteHookFunc func(address uint16, value uint8) error

type hook struct {
startAddress uint16
endAddress uint16
Expand All @@ -15,21 +19,21 @@ type hook struct {
type readHook struct {
hook

hookFunc func(address uint16) uint8
hookFunc ReadHookFunc
}

type writeHook struct {
hook

hookFunc func(address uint16, value uint8)
hookFunc WriteHookFunc
}

func (h *hook) SetProxyOnly(proxy bool) {
h.onlyProxy = proxy
}

// AddReadHook adds an address range read hook that gets called when a read from given range is made.
func (b *Base) AddReadHook(startAddress, endAddress uint16, hookFunc func(address uint16) uint8) Hook {
func (b *Base) AddReadHook(startAddress, endAddress uint16, hookFunc ReadHookFunc) Hook {
hook := readHook{
hook: hook{
startAddress: startAddress,
Expand All @@ -42,7 +46,7 @@ func (b *Base) AddReadHook(startAddress, endAddress uint16, hookFunc func(addres
}

// AddWriteHook adds an address range write hook that gets called when a write into the given range is made.
func (b *Base) AddWriteHook(startAddress, endAddress uint16, hookFunc func(address uint16, value uint8)) Hook {
func (b *Base) AddWriteHook(startAddress, endAddress uint16, hookFunc WriteHookFunc) Hook {
hook := writeHook{
hook: hook{
startAddress: startAddress,
Expand Down
8 changes: 5 additions & 3 deletions pkg/mapper/mapperbase/nametable.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ func (b *Base) NameTable(bank int) []byte {
}

// SetNameTableMirrorMode sets the nametable mirror mode.
func (b *Base) SetNameTableMirrorMode(mirrorMode cartridge.MirrorMode) {
func (b *Base) SetNameTableMirrorMode(mirrorMode cartridge.MirrorMode) error {
b.bus.NameTable.SetMirrorMode(mirrorMode)
return nil
}

// MirrorMode returns the set mirror mode.
Expand All @@ -59,10 +60,11 @@ func (b *Base) SetMirrorModeTranslation(translation MirrorModeTranslation) {

// SetNameTableMirrorModeIndex sets the nametable mirror mode based on the value of the mapper based
// translation map from index to mirror mode.
func (b *Base) SetNameTableMirrorModeIndex(index uint8) {
func (b *Base) SetNameTableMirrorModeIndex(index uint8) error {
mode, ok := b.mirrorModeTranslation[index]
if !ok {
panic(fmt.Sprintf("invalid nametable mirror mode index %d", index))
return fmt.Errorf("invalid nametable mirror mode index %d", index)
}
b.bus.NameTable.SetMirrorMode(mode)
return nil
}
8 changes: 4 additions & 4 deletions pkg/mapper/mapperdb/axrom.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type mapperAxROM struct {
}

// NewAxROM returns a new mapper instance.
func NewAxROM(base Base) bus.Mapper {
func NewAxROM(base Base) (bus.Mapper, error) {
m := &mapperAxROM{
Base: base,
}
Expand All @@ -33,13 +33,13 @@ func NewAxROM(base Base) bus.Mapper {
m.SetMirrorModeTranslation(translation)

m.AddWriteHook(0x8000, 0xFFFF, m.setPrgWindow)
return m
return m, nil
}

func (m *mapperAxROM) setPrgWindow(_ uint16, value uint8) {
func (m *mapperAxROM) setPrgWindow(_ uint16, value uint8) error {
value &= 0b0000_0111
m.SetPrgWindow(0, int(value)) // select 32 KB PRG ROM bank for CPU $8000-$FFFF

mirrorMode := (value >> 4) & 1
m.SetNameTableMirrorModeIndex(mirrorMode)
return m.SetNameTableMirrorModeIndex(mirrorMode)
}
3 changes: 2 additions & 1 deletion pkg/mapper/mapperdb/axrom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ func TestMapperAxROM(t *testing.T) {
},
NameTable: nametable.New(cartridge.MirrorHorizontal),
})
m := NewAxROM(base)
m, err := NewAxROM(base)
assert.NoError(t, err)

prg[0x0010] = 0x03 // bank 0
prg[0x8010] = 0x04 // bank 1
Expand Down
8 changes: 4 additions & 4 deletions pkg/mapper/mapperdb/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ type Base interface {
NameTable(bank int) []byte
SetMirrorModeTranslation(translation mapperbase.MirrorModeTranslation)
SetNameTableCount(count int)
SetNameTableMirrorMode(mirrorMode cartridge.MirrorMode)
SetNameTableMirrorModeIndex(index uint8)
SetNameTableMirrorMode(mirrorMode cartridge.MirrorMode) error
SetNameTableMirrorModeIndex(index uint8) error
SetNameTableWindow(bank int)

AddReadHook(startAddress, endAddress uint16, hookFunc func(address uint16) uint8) mapperbase.Hook
AddWriteHook(startAddress, endAddress uint16, hookFunc func(address uint16, value uint8)) mapperbase.Hook
AddReadHook(startAddress, endAddress uint16, hookFunc mapperbase.ReadHookFunc) mapperbase.Hook
AddWriteHook(startAddress, endAddress uint16, hookFunc mapperbase.WriteHookFunc) mapperbase.Hook
Cartridge() *cartridge.Cartridge
Initialize()
SetName(name string)
Expand Down
7 changes: 4 additions & 3 deletions pkg/mapper/mapperdb/cnrom.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,18 @@ type mapperCNROM struct {
}

// NewCNROM returns a new mapper instance.
func NewCNROM(base Base) bus.Mapper {
func NewCNROM(base Base) (bus.Mapper, error) {
m := &mapperCNROM{
Base: base,
}
m.SetName("CNROM")
m.Initialize()

m.AddWriteHook(0x8000, 0xFFFF, m.setChrWindow)
return m
return m, nil
}

func (m *mapperCNROM) setChrWindow(_ uint16, value uint8) {
func (m *mapperCNROM) setChrWindow(_ uint16, value uint8) error {
m.SetChrWindow(0, int(value)) // select 8 KB CHR ROM bank for PPU $0000-$1FFF
return nil
}
3 changes: 2 additions & 1 deletion pkg/mapper/mapperdb/cnrom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ func TestMapperCNROM(t *testing.T) {
},
NameTable: nametable.New(cartridge.MirrorHorizontal),
})
m := NewCNROM(base)
m, err := NewCNROM(base)
assert.NoError(t, err)

chr[0x0010] = 0x03 // bank 0
chr[0x2010] = 0x04 // bank 1
Expand Down
11 changes: 6 additions & 5 deletions pkg/mapper/mapperdb/gtrom.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type mapperGTROM struct {
}

// NewGTROM returns a new mapper instance.
func NewGTROM(base Base) bus.Mapper {
func NewGTROM(base Base) (bus.Mapper, error) {
m := &mapperGTROM{
Base: base,
}
Expand All @@ -34,14 +34,14 @@ func NewGTROM(base Base) bus.Mapper {
m.AddWriteHook(0x5000, 0x5FFF, m.setBanks)
m.AddWriteHook(0x7000, 0x7FFF, m.setBanks)

return m
return m, nil
}

func (m *mapperGTROM) getControl(_ uint16) uint8 {
return 0 // TODO should return open bus value
func (m *mapperGTROM) getControl(_ uint16) (uint8, error) {
return 0, nil // TODO should return open bus value
}

func (m *mapperGTROM) setBanks(_ uint16, value uint8) {
func (m *mapperGTROM) setBanks(_ uint16, value uint8) error {
prgBank := value & 0b0000_1111

m.SetPrgWindow(0, int(prgBank)) // select 32 KB PRG ROM bank for CPU $8000-$FFFF
Expand All @@ -51,4 +51,5 @@ func (m *mapperGTROM) setBanks(_ uint16, value uint8) {

nameTableBank := int(value>>5) & 1
m.SetNameTableWindow(nameTableBank)
return nil
}
3 changes: 2 additions & 1 deletion pkg/mapper/mapperdb/gtrom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ func TestMapperGTROM(t *testing.T) {
},
NameTable: nameTable,
})
m := NewGTROM(base)
m, err := NewGTROM(base)
assert.NoError(t, err)

chr := make([]byte, 0x4000)
base.SetChrRAM(chr)
Expand Down
27 changes: 16 additions & 11 deletions pkg/mapper/mapperdb/mmc1.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type mapperMMC1 struct {
}

// NewMMC1 returns a new mapper instance.
func NewMMC1(base Base) bus.Mapper {
func NewMMC1(base Base) (bus.Mapper, error) {
m := &mapperMMC1{
Base: base,
ram: make([]byte, 0x8000), // 32K
Expand All @@ -55,20 +55,22 @@ func NewMMC1(base Base) bus.Mapper {

// TODO support mmc1 variants

return m
return m, nil
}

func (m *mapperMMC1) resetShift() {
func (m *mapperMMC1) resetShift() error {
m.shiftCount = 0
m.shiftRegister = 0
m.applyControl()
if err := m.applyControl(); err != nil {
return err
}
m.control |= 0x0C
return nil
}

func (m *mapperMMC1) writeShiftBit(address uint16, value uint8) {
func (m *mapperMMC1) writeShiftBit(address uint16, value uint8) error {
if value&0x80 != 0 {
m.resetShift()
return
return m.resetShift()
}

// the shift register gets written from lowest to highest bit
Expand All @@ -77,7 +79,7 @@ func (m *mapperMMC1) writeShiftBit(address uint16, value uint8) {

m.shiftCount++
if m.shiftCount < 5 {
return
return nil
}

switch {
Expand All @@ -94,12 +96,14 @@ func (m *mapperMMC1) writeShiftBit(address uint16, value uint8) {
m.prgBank = int(m.shiftRegister) & 0b0000_1111
}

m.resetShift()
return m.resetShift()
}

func (m *mapperMMC1) applyControl() {
func (m *mapperMMC1) applyControl() error {
mirrorMode := m.control & 0b0000_0011
m.SetNameTableMirrorModeIndex(mirrorMode)
if err := m.SetNameTableMirrorModeIndex(mirrorMode); err != nil {
return err
}

prgMode := (m.control >> 2) & 0b0000_0011
switch prgMode {
Expand Down Expand Up @@ -129,4 +133,5 @@ func (m *mapperMMC1) applyControl() {
// switch two separate 4 KB banks
m.SetChrWindow(1, m.chrBank1)
}
return nil
}
3 changes: 2 additions & 1 deletion pkg/mapper/mapperdb/mmc1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ func TestMapperMMC1(t *testing.T) {
},
NameTable: nametable.New(cartridge.MirrorHorizontal),
})
m := NewMMC1(base)
m, err := NewMMC1(base)
assert.NoError(t, err)

chr[0x0000] = 0x01
chr[0x2000] = 0x02
Expand Down
4 changes: 2 additions & 2 deletions pkg/mapper/mapperdb/nrom.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ type mapperNROM struct {
}

// NewNROM returns a new mapper instance.
func NewNROM(base Base) bus.Mapper {
func NewNROM(base Base) (bus.Mapper, error) {
m := &mapperNROM{
Base: base,
}
m.SetName("NROM")
m.Initialize()
return m
return m, nil
}
6 changes: 4 additions & 2 deletions pkg/mapper/mapperdb/nrom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ func TestMapperNROMPrg16k(t *testing.T) {
},
NameTable: nametable.New(cartridge.MirrorHorizontal),
})
m := NewNROM(base)
m, err := NewNROM(base)
assert.NoError(t, err)

chr[0x0001] = 0x02 // bank 0
assert.Equal(t, 0x02, m.Read(0x0001))
Expand All @@ -42,7 +43,8 @@ func TestMapperNROMPrg32k(t *testing.T) {
},
NameTable: nametable.New(cartridge.MirrorHorizontal),
})
m := NewNROM(base)
m, err := NewNROM(base)
assert.NoError(t, err)

chr[0x0001] = 0x02 // bank 0
assert.Equal(t, 0x02, m.Read(0x0001))
Expand Down
Loading

0 comments on commit f1e5b7d

Please sign in to comment.