Compare commits

...

6 commits

Author SHA1 Message Date
JetSetIlly 545caefbfa corrected 1d40869
thumbMode test must happen before expectedPC test. the other way around and some strongarm
functions do not work as expected
2024-04-30 18:35:26 +01:00
JetSetIlly ed8f7d6318 fixed loading of ELF and ACE wrapped ELF files 2024-04-30 18:35:26 +01:00
JetSetIlly 96ad0797b4 NewVCS() expects environment.Label on instantiation
this helps force the environment.Label to be set to something meaningful
2024-04-30 18:34:35 +01:00
JetSetIlly a196b21a93 logging functions called with real env instances from the hardware package
logger package will no longer create new log entires for environments
other than the main emulation (or the logging.Always shim)
2024-04-30 17:48:46 +01:00
JetSetIlly cd2a00d4ba logger.Log() and logger.Logf() now require a logger.Permission instance
the logger.Permission interface indicates whether the environment making
the logging request is allowed to create new log entries. the
environment.Environment type satisifies the Permission interface

logger.Allow is provided as a convienient way of indicating the the log
entry should always be created
2024-04-30 11:23:40 +01:00
JetSetIlly 505661e3cf simplified/corrected string output for player, missile, ball sprites 2024-04-30 09:06:21 +01:00
92 changed files with 571 additions and 531 deletions

View file

@ -90,7 +90,7 @@ func NewUCI(pathToEngine string, diagnostic chan bots.Diagnostic) (*UCI, error)
err = cmd.Wait()
if err != nil {
logger.Logf("uci", err.Error())
logger.Logf(logger.Allow, "uci", err.Error())
return
}
}()
@ -170,7 +170,7 @@ func (uci *UCI) Start() error {
_, err = uci.stdin.Write([]byte("go depth 10\n"))
if err != nil {
logger.Logf("uci", err.Error())
logger.Logf(logger.Allow, "uci", err.Error())
return
}
@ -180,7 +180,7 @@ func (uci *UCI) Start() error {
n, err = uci.stdout.Read(buf)
if err != nil {
logger.Logf("uci", err.Error())
logger.Logf(logger.Allow, "uci", err.Error())
return
}

View file

@ -55,7 +55,7 @@ func (b *Bots) ActivateBot(cartHash string) (*bots.Feedback, error) {
if err != nil {
return nil, fmt.Errorf("bots: %w", err)
}
logger.Logf("bots", "%s started", b.running.BotID())
logger.Logf(logger.Allow, "bots", "%s started", b.running.BotID())
case "5bdd8af54020fa43065750bd4239a497695d403b":
// NTSC version of SpaceJockey
@ -63,7 +63,7 @@ func (b *Bots) ActivateBot(cartHash string) (*bots.Feedback, error) {
if err != nil {
return nil, fmt.Errorf("bots: %w", err)
}
logger.Logf("bots", "%s started", b.running.BotID())
logger.Logf(logger.Allow, "bots", "%s started", b.running.BotID())
default:
return nil, nil
@ -76,7 +76,7 @@ func (b *Bots) ActivateBot(cartHash string) (*bots.Feedback, error) {
func (b *Bots) Quit() {
if b.running != nil {
b.running.Quit()
logger.Logf("bots", "%s finished", b.running.BotID())
logger.Logf(logger.Allow, "bots", "%s finished", b.running.BotID())
b.running = nil
}
}

View file

@ -56,7 +56,7 @@ type Comparison struct {
driver driver
}
const comparisonEnv = environment.Label("comparison")
const comparisonLabel = environment.Label("comparison")
// NewComparison is the preferred method of initialisation for the Comparison type.
func NewComparison(driverVCS *hardware.VCS) (*Comparison, error) {
@ -79,11 +79,10 @@ func NewComparison(driverVCS *hardware.VCS) (*Comparison, error) {
tv.SetFPSCap(true)
// create a new VCS emulation
cmp.VCS, err = hardware.NewVCS(tv, cmp, driverVCS.Env.Prefs)
cmp.VCS, err = hardware.NewVCS(comparisonLabel, tv, cmp, driverVCS.Env.Prefs)
if err != nil {
return nil, fmt.Errorf("comparison: %w", err)
}
cmp.VCS.Env.Label = comparisonEnv
cmp.img = image.NewRGBA(image.Rect(0, 0, specification.ClksScanline, specification.AbsoluteMaxScanlines))
cmp.diffImg = image.NewRGBA(image.Rect(0, 0, specification.ClksScanline, specification.AbsoluteMaxScanlines))

View file

@ -156,7 +156,7 @@ func (dev *Developer) AttachCartridge(cart Cartridge, romFile string, elfFile st
if err != nil {
return fmt.Errorf("developer: %w", err)
} else {
logger.Logf("developer", "DWARF loaded in %s", time.Since(t))
logger.Logf(logger.Allow, "developer", "DWARF loaded in %s", time.Since(t))
}
return nil

View file

@ -563,7 +563,7 @@ func (bld *build) buildVariables(src *Source, ef *elf.File,
lexStackTop--
if lexStackTop < 0 {
// this should never happen unless the DWARF file is corrupt in some way
logger.Logf("dwarf", "trying to end a lexical block without one being opened")
logger.Logf(logger.Allow, "dwarf", "trying to end a lexical block without one being opened")
lexStackTop = 0
}
}
@ -772,7 +772,7 @@ func (bld *build) buildVariables(src *Source, ef *elf.File,
// eg. a float value
varb.constantValue = bld.debug_loc.byteOrder.Uint32(constfld.Val.([]uint8))
default:
logger.Logf("dwarf", "unhandled DW_AT_const_value type %T", constfld.Val)
logger.Logf(logger.Allow, "dwarf", "unhandled DW_AT_const_value type %T", constfld.Val)
continue // for loop
}
@ -806,7 +806,7 @@ func (bld *build) buildVariables(src *Source, ef *elf.File,
if errors.Is(err, UnsupportedDWARF) {
return err
}
logger.Logf("dwarf", "%s: %v", varb.Name, err)
logger.Logf(logger.Allow, "dwarf", "%s: %v", varb.Name, err)
}
// I don't believe variables with the class of location
@ -857,7 +857,7 @@ func (bld *build) buildVariables(src *Source, ef *elf.File,
return err
}
if n == 0 {
logger.Logf("dwarf", "unhandled expression operator %02x", expr[0])
logger.Logf(logger.Allow, "dwarf", "unhandled expression operator %02x", expr[0])
}
varb.loclist = bld.debug_loc.newLoclistJustContext(varb)
@ -948,7 +948,7 @@ func (bld *build) buildFunctions(src *Source, addressAdjustment uint64) error {
// attribute. for those functions we can resolve it later
framebase, err := resolveFramebase(e)
if err != nil {
logger.Logf("dwarf", "framebase for %s will be unreliable: %v", name, err)
logger.Logf(logger.Allow, "dwarf", "framebase for %s will be unreliable: %v", name, err)
}
// filename from file number
@ -980,8 +980,8 @@ func (bld *build) buildFunctions(src *Source, addressAdjustment uint64) error {
// assign function to declaration line
if !fn.DeclLine.Function.IsStub() && fn.DeclLine.Function.Name != fn.Name {
logger.Logf("dwarf", "contentious function ownership for source line (%s)", fn.DeclLine)
logger.Logf("dwarf", "%s and %s", fn.DeclLine.Function.Name, fn.Name)
logger.Logf(logger.Allow, "dwarf", "contentious function ownership for source line (%s)", fn.DeclLine)
logger.Logf(logger.Allow, "dwarf", "%s and %s", fn.DeclLine.Function.Name, fn.Name)
}
fn.DeclLine.Function = fn
}
@ -1056,7 +1056,7 @@ func (bld *build) buildFunctions(src *Source, addressAdjustment uint64) error {
fn, err := resolve(av)
if err != nil {
logger.Logf("dwarf", err.Error())
logger.Logf(logger.Allow, "dwarf", err.Error())
continue // build order loop
}
@ -1072,10 +1072,10 @@ func (bld *build) buildFunctions(src *Source, addressAdjustment uint64) error {
if fn.framebaseLoclist == nil {
fn.framebaseLoclist, err = resolveFramebase(e)
if err != nil {
logger.Logf("dwarf", "framebase for %s will be unreliable: %v", fn.Name, err)
logger.Logf(logger.Allow, "dwarf", "framebase for %s will be unreliable: %v", fn.Name, err)
}
} else {
logger.Logf("dwarf", "%s: concrete defintion for abstract function already has a framebase defintion!?", fn.Name)
logger.Logf(logger.Allow, "dwarf", "%s: concrete defintion for abstract function already has a framebase defintion!?", fn.Name)
}
// note framebase so that we can use it for inlined functions
@ -1086,7 +1086,7 @@ func (bld *build) buildFunctions(src *Source, addressAdjustment uint64) error {
} else {
fn, err := resolve(e)
if err != nil {
logger.Logf("dwarf", err.Error())
logger.Logf(logger.Allow, "dwarf", err.Error())
continue // build order loop
}
@ -1167,7 +1167,7 @@ func (bld *build) buildFunctions(src *Source, addressAdjustment uint64) error {
err := commitInlinedSubroutine(low, high)
if err != nil {
logger.Logf("dwarf", err.Error())
logger.Logf(logger.Allow, "dwarf", err.Error())
continue // build order loop
}
@ -1180,7 +1180,7 @@ func (bld *build) buildFunctions(src *Source, addressAdjustment uint64) error {
commitRange := func(low uint64, high uint64) {
err := commitInlinedSubroutine(low, high)
if err != nil {
logger.Logf("dwarf", err.Error())
logger.Logf(logger.Allow, "dwarf", err.Error())
}
}

View file

@ -326,7 +326,7 @@ func (loc *loclist) resolve() (loclistResult, error) {
// stack should only have one entry in it
if len(loc.stack) > 1 {
logger.Logf("dwarf", "loclist stack has more than one entry after resolve [%x]", loc.loclistPtr)
logger.Logf(logger.Allow, "dwarf", "loclist stack has more than one entry after resolve [%x]", loc.loclistPtr)
}
// top of stack is the result

View file

@ -288,13 +288,13 @@ func NewSource(romFile string, cart Cartridge, elfFile string) (*Source, error)
data, _, _ := c.ELFSection(".debug_frame")
src.debugFrame, err = newFrameSection(data, ef.ByteOrder, src.cart.GetCoProcBus().GetCoProc(), nil)
if err != nil {
logger.Logf("dwarf", err.Error())
logger.Logf(logger.Allow, "dwarf", err.Error())
}
data, _, _ = c.ELFSection(".debug_loc")
src.debugLoc, err = newLoclistSection(data, ef.ByteOrder, src.cart.GetCoProcBus().GetCoProc())
if err != nil {
logger.Logf("dwarf", err.Error())
logger.Logf(logger.Allow, "dwarf", err.Error())
}
} else {
c, adjust := bus.(coprocessor.CartCoProcOrigin)
@ -308,13 +308,13 @@ func NewSource(romFile string, cart Cartridge, elfFile string) (*Source, error)
}
src.debugFrame, err = newFrameSectionFromFile(ef, src.cart.GetCoProcBus().GetCoProc(), &rel)
if err != nil {
logger.Logf("dwarf", err.Error())
logger.Logf(logger.Allow, "dwarf", err.Error())
}
// create loclist section from the raw ELF section
src.debugLoc, err = newLoclistSectionFromFile(ef, src.cart.GetCoProcBus().GetCoProc())
if err != nil {
logger.Logf("dwarf", err.Error())
logger.Logf(logger.Allow, "dwarf", err.Error())
}
if adjust {
@ -332,9 +332,9 @@ func NewSource(romFile string, cart Cartridge, elfFile string) (*Source, error)
// log address adjustment value. how the value was arrived at is slightly
// different depending on whether the ELF file relocatable or not
if addressAdjustment == 0 {
logger.Logf("dwarf", "address adjustment not required")
logger.Logf(logger.Allow, "dwarf", "address adjustment not required")
} else {
logger.Logf("dwarf", "using address adjustment: %#x", int(addressAdjustment))
logger.Logf(logger.Allow, "dwarf", "using address adjustment: %#x", int(addressAdjustment))
}
// disassemble every word in the ELF file using the cartridge coprocessor interface
@ -426,7 +426,7 @@ func NewSource(romFile string, cart Cartridge, elfFile string) (*Source, error)
if _, ok := src.Files[f.Name]; !ok {
sf, err := readSourceFile(f.Name, src.path, &src.AllLines)
if err != nil {
logger.Logf("dwarf", "%v", err)
logger.Logf(logger.Allow, "dwarf", "%v", err)
} else {
src.Files[sf.Filename] = sf
src.Filenames = append(src.Filenames, sf.Filename)
@ -458,7 +458,7 @@ func NewSource(romFile string, cart Cartridge, elfFile string) (*Source, error)
// log optimisation message as appropriate
if src.Optimised {
logger.Logf("dwarf", "source compiled with optimisation")
logger.Logf(logger.Allow, "dwarf", "source compiled with optimisation")
}
// build functions from DWARF data
@ -561,10 +561,10 @@ func NewSource(romFile string, cart Cartridge, elfFile string) (*Source, error)
findEntryFunction(src)
// log summary
logger.Logf("dwarf", "identified %d functions in %d compile units", len(src.Functions), len(src.compileUnits))
logger.Logf("dwarf", "%d global variables", len(src.SortedGlobals.Variables))
logger.Logf("dwarf", "%d local variable (loclists)", len(src.SortedLocals.Variables))
logger.Logf("dwarf", "high address (%08x)", src.HighAddress)
logger.Logf(logger.Allow, "dwarf", "identified %d functions in %d compile units", len(src.Functions), len(src.compileUnits))
logger.Logf(logger.Allow, "dwarf", "%d global variables", len(src.SortedGlobals.Variables))
logger.Logf(logger.Allow, "dwarf", "%d local variable (loclists)", len(src.SortedLocals.Variables))
logger.Logf(logger.Allow, "dwarf", "high address (%08x)", src.HighAddress)
return src, nil
}
@ -601,11 +601,11 @@ func allocateSourceLines(src *Source, dwrf *dwarf.Data, addressAdjustment uint64
// check that source file has been loaded
if src.Files[le.File.Name] == nil {
logger.Logf("dwarf", "file not available for linereader: %s", le.File.Name)
logger.Logf(logger.Allow, "dwarf", "file not available for linereader: %s", le.File.Name)
break // line entry for loop. will continue with compile unit loop
}
if le.Line-1 > src.Files[le.File.Name].Content.Len() {
logger.Logf("dwarf", "current source is unrelated to ELF/DWARF data (number of lines)")
logger.Logf(logger.Allow, "dwarf", "current source is unrelated to ELF/DWARF data (number of lines)")
break // line entry for loop. will continue with compile unit loop
}

View file

@ -354,11 +354,10 @@ func NewDebugger(opts CommandLineOptions, create CreateUserInterface) (*Debugger
}
// create a new VCS instance
dbg.vcs, err = hardware.NewVCS(tv, dbg, nil)
dbg.vcs, err = hardware.NewVCS(environment.MainEmulation, tv, dbg, nil)
if err != nil {
return nil, fmt.Errorf("debugger: %w", err)
}
dbg.vcs.Env.Label = environment.MainEmulation
// create userinput/controllers handler
dbg.controllers = userinput.NewControllers(dbg.vcs.Input)
@ -369,7 +368,7 @@ func NewDebugger(opts CommandLineOptions, create CreateUserInterface) (*Debugger
// stella.pro support
dbg.pro, err = properties.Load()
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
// create preview emulation
@ -559,7 +558,7 @@ func (dbg *Debugger) setState(state govern.State, subState govern.SubState) {
err := dbg.vcs.TV.SetEmulationState(state)
if err != nil {
logger.Log("debugger", err.Error())
logger.Log(logger.Allow, "debugger", err.Error())
}
if dbg.ref != nil {
dbg.ref.SetEmulationState(state)
@ -679,13 +678,13 @@ func (dbg *Debugger) end() {
// set ending state
err := dbg.gui.SetFeature(gui.ReqEnd)
if err != nil {
logger.Log("debugger", err.Error())
logger.Log(logger.Allow, "debugger", err.Error())
}
// save preferences
err = dbg.Prefs.Save()
if err != nil {
logger.Log("debugger", err.Error())
logger.Log(logger.Allow, "debugger", err.Error())
}
}
@ -939,7 +938,7 @@ func (dbg *Debugger) run() error {
defer func() {
err := dbg.scriptScribe.EndSession()
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
}()
@ -948,7 +947,7 @@ func (dbg *Debugger) run() error {
if dbg.cartload != nil {
err := dbg.cartload.Close()
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
}
}()
@ -970,7 +969,7 @@ func (dbg *Debugger) run() error {
} else if errors.Is(err, terminal.UserReload) {
err = dbg.reloadCartridge()
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
} else {
return fmt.Errorf("debugger: %w", err)
@ -1129,7 +1128,7 @@ func (dbg *Debugger) Notify(notice notifications.Notice) error {
case notifications.NotifyMovieCartStarted:
return dbg.vcs.TV.Reset(true)
default:
logger.Logf("debugger", "unhandled notification for plusrom (%v)", notice)
logger.Logf(logger.Allow, "debugger", "unhandled notification for plusrom (%v)", notice)
}
return nil
@ -1180,7 +1179,7 @@ func (dbg *Debugger) attachCartridge(cartload cartridgeloader.Loader) (e error)
if dbg.cartload != nil {
err := dbg.cartload.Close()
if err != nil {
logger.Logf("debuger", err.Error())
logger.Logf(logger.Allow, "debuger", err.Error())
}
}
dbg.cartload = &cartload
@ -1188,7 +1187,7 @@ func (dbg *Debugger) attachCartridge(cartload cartridgeloader.Loader) (e error)
// reset of vcs is implied with attach cartridge
err := setup.AttachCartridge(dbg.vcs, cartload, false)
if err != nil && !errors.Is(err, cartridge.Ejected) {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
// an error has occurred so attach the ejected cartridge
//
// !TODO: a special error cartridge to make it more obvious what has happened
@ -1213,17 +1212,17 @@ func (dbg *Debugger) attachCartridge(cartload cartridgeloader.Loader) (e error)
err = dbg.Disasm.FromMemory()
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
dbg.CoProcDisasm.AttachCartridge(dbg)
err = dbg.CoProcDev.AttachCartridge(dbg, cartload.Filename, dbg.opts.ELF)
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
if errors.Is(err, coproc_dwarf.UnsupportedDWARF) {
err = dbg.gui.SetFeature(gui.ReqNotification, notifications.NotifyUnsupportedDWARF)
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
}
}
@ -1247,7 +1246,7 @@ func (dbg *Debugger) attachCartridge(cartload cartridgeloader.Loader) (e error)
// activate bot if possible
feedback, err := dbg.bots.ActivateBot(dbg.vcs.Mem.Cart.Hash)
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
// always ReqBotFeedback. if feedback is nil then the bot features will be disbaled
@ -1287,7 +1286,7 @@ func (dbg *Debugger) endRecording() {
err := dbg.recorder.End()
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
}
@ -1366,7 +1365,7 @@ func (dbg *Debugger) startComparison(comparisonROM string, comparisonPrefs strin
// check use of comparison prefs
comparisonPrefs = prefs.PopCommandLineStack()
if comparisonPrefs != "" {
logger.Logf("debugger", "%s unused for comparison emulation", comparisonPrefs)
logger.Logf(logger.Allow, "debugger", "%s unused for comparison emulation", comparisonPrefs)
}
return nil
@ -1381,7 +1380,7 @@ func (dbg *Debugger) endComparison() {
dbg.comparison = nil
err := dbg.gui.SetFeature(gui.ReqComparison, nil, nil)
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
}
@ -1429,7 +1428,7 @@ func (dbg *Debugger) Plugged(port plugging.PortID, peripheral plugging.Periphera
}
err := dbg.gui.SetFeature(gui.ReqPeripheralPlugged, port, peripheral)
if err != nil {
logger.Log("debugger", err.Error())
logger.Log(logger.Allow, "debugger", err.Error())
}
}

View file

@ -38,7 +38,7 @@ func (dbg *Debugger) PushDeepPoke(addr uint16, value uint8, newValue uint8, valu
doDeepPoke := func() error {
err := dbg.doDeepPoke(searchState, addr, value, newValue, valueMask)
if err != nil {
logger.Logf("deeppoke", "%v", err)
logger.Logf(logger.Allow, "deeppoke", "%v", err)
}
if done != nil {
done()
@ -294,6 +294,6 @@ func deepPoke(mem *memory.Memory, poke deepPoking, value uint8, valueMask uint8)
return err
}
v = (v & (valueMask ^ 0xff)) | (value & valueMask)
logger.Log("deeppoke", fmt.Sprintf("changing %#04x (%s) to %#02x", poke.addr, poke.area, value))
logger.Log(logger.Allow, "deeppoke", fmt.Sprintf("changing %#04x (%s) to %#02x", poke.addr, poke.area, value))
return mem.Poke(poke.addr, v)
}

View file

@ -320,7 +320,7 @@ func (dbg *Debugger) inputLoop(inputter terminal.Input, nonInstructionQuantum bo
if nonInstructionQuantum {
return nil
} else {
logger.Log("debugger", "asked to 'step out of nonInstructionQuantum step input loop' inappropriately")
logger.Log(logger.Allow, "debugger", "asked to 'step out of nonInstructionQuantum step input loop' inappropriately")
}
}
@ -585,7 +585,7 @@ func (dbg *Debugger) handleInterrupt(inputter terminal.Input) {
// end script scribe (if one is running)
err := dbg.scriptScribe.EndSession()
if err != nil {
logger.Logf("debugger", err.Error())
logger.Logf(logger.Allow, "debugger", err.Error())
}
// exit immediately if inputter is not a real terminal

View file

@ -28,7 +28,7 @@ func (dbg *Debugger) PushFunction(f func()) {
select {
case dbg.events.PushedFunction <- f:
default:
logger.Log("debugger", "dropped raw event push")
logger.Log(logger.Allow, "debugger", "dropped raw event push")
}
}
@ -38,7 +38,7 @@ func (dbg *Debugger) PushFunctionImmediate(f func()) {
select {
case dbg.events.PushedFunctionImmediate <- f:
default:
logger.Log("debugger", "dropped raw event push (to return channel)")
logger.Log(logger.Allow, "debugger", "dropped raw event push (to return channel)")
}
}
@ -61,7 +61,7 @@ func (dbg *Debugger) PushSetPause(paused bool) {
}
})
case govern.ModeDebugger:
logger.Logf("debugger", "not reacting to SetPause() in debugger mode (use terminal input instead)")
logger.Logf(logger.Allow, "debugger", "not reacting to SetPause() in debugger mode (use terminal input instead)")
}
}

View file

@ -255,7 +255,7 @@ func (dsm *Disassembly) blessSequence(bank int, addr uint16, commit bool) bool {
// break if address has looped around
if next > next&memorymap.CartridgeBits {
if hasCommitted {
logger.Logf("disassembly", "blessSequence has blessed an instruction in a false sequence. discovered at bank %d: %s", bank, instruction.String())
logger.Logf(logger.Allow, "disassembly", "blessSequence has blessed an instruction in a false sequence. discovered at bank %d: %s", bank, instruction.String())
}
return false
}
@ -265,7 +265,7 @@ func (dsm *Disassembly) blessSequence(bank int, addr uint16, commit bool) bool {
for i := a + 1; i < next; i++ {
if instruction.Level == EntryLevelBlessed {
if hasCommitted {
logger.Logf("disassembly", "blessSequence has blessed an instruction in a false sequence. discovered at bank %d: %s", bank, instruction.String())
logger.Logf(logger.Allow, "disassembly", "blessSequence has blessed an instruction in a false sequence. discovered at bank %d: %s", bank, instruction.String())
}
return false
}
@ -274,7 +274,7 @@ func (dsm *Disassembly) blessSequence(bank int, addr uint16, commit bool) bool {
// do not bless decoded instructions that look like fill characters
if instruction.Result.Defn.OpCode == 0xff && instruction.Result.InstructionData == 0xffff {
if hasCommitted {
logger.Logf("disassembly", "blessSequence has blessed an instruction in a false sequence. discovered at bank %d: %s", bank, instruction.String())
logger.Logf(logger.Allow, "disassembly", "blessSequence has blessed an instruction in a false sequence. discovered at bank %d: %s", bank, instruction.String())
}
return false
}

View file

@ -22,6 +22,7 @@ import (
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/disassembly/symbols"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/cpu"
"github.com/jetsetilly/gopher2600/hardware/cpu/execution"
@ -77,6 +78,8 @@ func NewDisassembly(vcs *hardware.VCS) (*Disassembly, *symbols.Symbols, error) {
return dsm, &dsm.Sym, nil
}
const disassemblyLabel = environment.Label("disassembly")
// FromCartridge initialises a new partial emulation and returns a disassembly
// from the supplied cartridge filename. Useful for one-shot disassemblies,
// like the gopher2600 "disasm" mode.
@ -88,7 +91,7 @@ func FromCartridge(cartload cartridgeloader.Loader) (*Disassembly, error) {
return nil, fmt.Errorf("disassembly: %w", err)
}
vcs, err := hardware.NewVCS(tv, nil, nil)
vcs, err := hardware.NewVCS(disassemblyLabel, tv, nil, nil)
if err != nil {
return nil, fmt.Errorf("disassembly: %w", err)
}

View file

@ -68,7 +68,7 @@ func (sym *Symbols) canonise(cart *cartridge.Cartridge) {
for k, v := range hb.ReadHotspots() {
ma, area := memorymap.MapAddress(k, true)
if area != memorymap.Cartridge {
logger.Logf("symbols", "%s reporting hotspot (%s) outside of cartridge address space", cart.ID(), v.Symbol)
logger.Logf(logger.Allow, "symbols", "%s reporting hotspot (%s) outside of cartridge address space", cart.ID(), v.Symbol)
}
sym.read.add(SourceCartridge, ma, v.Symbol)
}
@ -76,7 +76,7 @@ func (sym *Symbols) canonise(cart *cartridge.Cartridge) {
for k, v := range hb.WriteHotspots() {
ma, area := memorymap.MapAddress(k, false)
if area != memorymap.Cartridge {
logger.Logf("symbols", "%s reporting hotspot (%s) outside of cartridge address space", cart.ID(), v.Symbol)
logger.Logf(logger.Allow, "symbols", "%s reporting hotspot (%s) outside of cartridge address space", cart.ID(), v.Symbol)
}
sym.write.add(SourceCartridge, ma, v.Symbol)
}

View file

@ -72,7 +72,7 @@ func (sym *Symbols) fromDasm(cart *cartridge.Cartridge) error {
sf, err := os.Open(symFilename)
if err != nil {
logger.Logf("symbols", "dasm .sym file not available (%s)", cart.Filename)
logger.Logf(logger.Allow, "symbols", "dasm .sym file not available (%s)", cart.Filename)
return nil
}
defer sf.Close()

View file

@ -25,6 +25,9 @@ import (
// Label is used to name the environment
type Label string
// MainEmulation is the label used for the main emulation
const MainEmulation = Label("main")
// Television interface exposing a minimum amount of the real television
// implementation
type Television interface {
@ -57,8 +60,9 @@ type Environment struct {
//
// The Notify and Preferences can be nil. If prefs is nil then a new instance of
// the system wide preferences will be created.
func NewEnvironment(tv Television, notify notifications.Notify, prefs *preferences.Preferences) (*Environment, error) {
func NewEnvironment(label Label, tv Television, notify notifications.Notify, prefs *preferences.Preferences) (*Environment, error) {
env := &Environment{
Label: label,
TV: tv,
Notifications: notify,
Prefs: prefs,
@ -91,14 +95,16 @@ func (env *Environment) Normalise() {
env.Prefs.PlusROM.SetDefaults()
}
// MainEmulation is the label used for the main emulation
const MainEmulation = Label("main")
// IsEmulation checks the emulation label and returns true if it matches
func (env *Environment) IsEmulation(label Label) bool {
return env.Label == label
}
// AllowLogging returns true if environment is permitted to create new log entries
func (env *Environment) AllowLogging() bool {
return env.IsEmulation(MainEmulation)
}
// stub implementation of the notification interface
type notificationStub struct{}

View file

@ -212,7 +212,7 @@ func main() {
// indicate gui creation and to quit.
func launch(sync *mainSync, args []string) {
logger.Log("runtime", fmt.Sprintf("number of cores being used: %d", runtime.NumCPU()))
logger.Log(logger.Allow, "runtime", fmt.Sprintf("number of cores being used: %d", runtime.NumCPU()))
// use flag set to provide the --help flag for top level command line.
// that's all we want it to do
@ -404,8 +404,8 @@ func emulate(mode string, sync *mainSync, args []string) error {
if term == nil {
switch strings.ToUpper(opts.TermType) {
default:
logger.Logf("terminal", "unknown terminal: %s", opts.TermType)
logger.Logf("terminal", "defaulting to plain")
logger.Logf(logger.Allow, "terminal", "unknown terminal: %s", opts.TermType)
logger.Logf(logger.Allow, "terminal", "defaulting to plain")
term = &plainterm.PlainTerminal{}
case "PLAIN":
term = &plainterm.PlainTerminal{}

View file

@ -100,13 +100,13 @@ func NewAudio() (*Audio, error) {
aud.spec = actualSpec
logger.Logf("sdl: audio", "frequency: %d samples/sec", aud.spec.Freq)
logger.Logf("sdl: audio", "format: %d", aud.spec.Format)
logger.Logf("sdl: audio", "channels: %d", aud.spec.Channels)
logger.Logf("sdl: audio", "buffer size: %d samples", bufferLength)
logger.Logf("sdl: audio", "realtime demand: %d samples", realtimeDemand)
logger.Logf("sdl: audio", "max samples: %d samples", maxQueueLength)
logger.Logf("sdl: audio", "silence: %d", aud.spec.Silence)
logger.Logf(logger.Allow, "sdl: audio", "frequency: %d samples/sec", aud.spec.Freq)
logger.Logf(logger.Allow, "sdl: audio", "format: %d", aud.spec.Format)
logger.Logf(logger.Allow, "sdl: audio", "channels: %d", aud.spec.Channels)
logger.Logf(logger.Allow, "sdl: audio", "buffer size: %d samples", bufferLength)
logger.Logf(logger.Allow, "sdl: audio", "realtime demand: %d samples", realtimeDemand)
logger.Logf(logger.Allow, "sdl: audio", "max samples: %d samples", maxQueueLength)
logger.Logf(logger.Allow, "sdl: audio", "silence: %d", aud.spec.Silence)
sdl.PauseAudioDevice(aud.id, false)

View file

@ -83,7 +83,7 @@ func (wm *manager) drawMenu() {
// wm.img.dbg.PushFunction(func() {
// _, err := wm.img.dbg.VCS().(*hardware.VCS).Mem.Cart.ROMDump()
// if err != nil {
// logger.Log("save rom", err.Error())
// logger.Log(logger.Allow, "save rom", err.Error())
// }
// })
// }

View file

@ -46,11 +46,11 @@ func (img *SdlImgui) modalDrawPlusROMFirstInstallation() {
if imguiTextInput("##nick", plusnet.MaxNickLength, &nick, true) {
err := img.dbg.VCS().Env.Prefs.PlusROM.Nick.Set(nick)
if err != nil {
logger.Logf("sdlimgui", "could not set plusrom nick: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not set plusrom nick: %v", err)
}
err = img.dbg.VCS().Env.Prefs.PlusROM.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save preferences: %v", err)
}
}
@ -67,11 +67,11 @@ func (img *SdlImgui) modalDrawPlusROMFirstInstallation() {
if imgui.Button("I'm happy with my nick") {
err := img.dbg.VCS().Env.Prefs.PlusROM.Nick.Set(nick)
if err != nil {
logger.Logf("sdlimgui", "could not set preference value: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not set preference value: %v", err)
}
err = img.dbg.VCS().Env.Prefs.PlusROM.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save preferences: %v", err)
}
imgui.CloseCurrentPopup()

View file

@ -141,8 +141,8 @@ func newPlatform(img *SdlImgui) (*platform, error) {
var sdlVersion sdl.Version
sdl.VERSION(&sdlVersion)
logger.Logf("sdl", "version %d.%d.%d", sdlVersion.Major, sdlVersion.Minor, sdlVersion.Patch)
logger.Logf("sdl", "using GL version %d.%d%s", major, minor, profile_s)
logger.Logf(logger.Allow, "sdl", "version %d.%d.%d", sdlVersion.Major, sdlVersion.Minor, sdlVersion.Patch)
logger.Logf(logger.Allow, "sdl", "using GL version %d.%d%s", major, minor, profile_s)
plt := &platform{
img: img,
@ -153,7 +153,7 @@ func newPlatform(img *SdlImgui) (*platform, error) {
sdl.Quit()
return nil, fmt.Errorf("sdl: %w", err)
}
logger.Logf("sdl", "refresh rate: %dHz", plt.mode.RefreshRate)
logger.Logf(logger.Allow, "sdl", "refresh rate: %dHz", plt.mode.RefreshRate)
// map sdl key codes to imgui codes
plt.setKeyMapping()
@ -186,12 +186,12 @@ func newPlatform(img *SdlImgui) (*platform, error) {
pad = sdl.GameControllerOpen(i)
}
if supportGamepads && pad.Attached() {
logger.Logf("sdl", "gamepad: %s", pad.Joystick().Name())
logger.Logf(logger.Allow, "sdl", "gamepad: %s", pad.Joystick().Name())
plt.joysticks = append(plt.joysticks, controller{closeController: pad})
} else {
joy := sdl.JoystickOpen(i)
if joy.Attached() {
logger.Logf("sdl", "joystick: %s", joy.Name())
logger.Logf(logger.Allow, "sdl", "joystick: %s", joy.Name())
plt.joysticks = append(plt.joysticks, controller{
closeController: joy,
isStelladaptor: strings.Contains(strings.ToLower(joy.Name()), "stelladaptor"),
@ -201,7 +201,7 @@ func newPlatform(img *SdlImgui) (*platform, error) {
}
if len(plt.joysticks) == 0 {
logger.Log("sdl", "no joysticks/gamepads found")
logger.Log(logger.Allow, "sdl", "no joysticks/gamepads found")
}
return plt, nil
@ -233,7 +233,7 @@ func (plt *platform) setSwapInterval(i int) {
err := sdl.GLSetSwapInterval(i)
if err != nil {
logger.Logf("sdl", "GLSetSwapInterval(%d): %s", i, err.Error())
logger.Logf(logger.Allow, "sdl", "GLSetSwapInterval(%d): %s", i, err.Error())
}
}

View file

@ -38,7 +38,7 @@ func (img *SdlImgui) screenshot(mode screenshotMode, filenameSuffix string) {
// wait for result and log any errors
res := <-finish
if res.err != nil {
logger.Log("screenshot", res.err.Error())
logger.Log(logger.Allow, "screenshot", res.err.Error())
return
}
@ -61,23 +61,23 @@ func (img *SdlImgui) screenshot(mode screenshotMode, filenameSuffix string) {
func saveJPEG(rgba *image.RGBA, path string) {
f, err := os.Create(path)
if err != nil {
logger.Logf("screenshot", "save failed: %v", err.Error())
logger.Logf(logger.Allow, "screenshot", "save failed: %v", err.Error())
return
}
err = jpeg.Encode(f, rgba, &jpeg.Options{Quality: 100})
if err != nil {
logger.Logf("screenshot", "save failed: %v", err.Error())
logger.Logf(logger.Allow, "screenshot", "save failed: %v", err.Error())
_ = f.Close()
return
}
err = f.Close()
if err != nil {
logger.Logf("screenshot", "save failed: %v", err.Error())
logger.Logf(logger.Allow, "screenshot", "save failed: %v", err.Error())
return
}
// indicate success
logger.Logf("screenshot", "saved: %s", path)
logger.Logf(logger.Allow, "screenshot", "saved: %s", path)
}

View file

@ -258,36 +258,36 @@ func NewSdlImgui(dbg *debugger.Debugger) (*SdlImgui, error) {
func (img *SdlImgui) Destroy() {
err := img.prefs.saveOnExitDsk.Save()
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
err = img.audio.EndMixing()
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
err = img.wm.saveManagerState()
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
err = img.wm.saveManagerHotkeys()
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
img.wm.destroy()
err = img.plt.destroy()
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
img.rnd.destroy()
ctx, err := imgui.CurrentContext()
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
ctx.Destroy()
}
@ -307,7 +307,7 @@ func (img *SdlImgui) quit() {
select {
case img.dbg.UserInput() <- userinput.EventQuit{}:
default:
logger.Log("sdlimgui", "dropped quit event")
logger.Log(logger.Allow, "sdlimgui", "dropped quit event")
}
}
@ -479,12 +479,12 @@ func (img *SdlImgui) cursorVisibility(hidden bool) {
if hidden {
_, err := sdl.ShowCursor(sdl.DISABLE)
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
} else {
_, err := sdl.ShowCursor(sdl.ENABLE)
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
}
}

View file

@ -85,7 +85,7 @@ func (img *SdlImgui) Service() {
for peeping {
peepCt, err := sdl.PeepEvents(img.polling.pumpedEvents[additionalEvents:], sdl.GETEVENT, sdl.FIRSTEVENT, sdl.LASTEVENT)
if err != nil {
logger.Log("sdlimgui", err.Error())
logger.Log(logger.Allow, "sdlimgui", err.Error())
}
// adjust the peepCt by the number of additionalEvents in the queue
@ -188,9 +188,9 @@ func (img *SdlImgui) Service() {
Down: ev.Type == sdl.MOUSEBUTTONDOWN}:
default:
if ev.Type == sdl.MOUSEBUTTONDOWN {
logger.Log("sdlimgui", "dropped mouse down event")
logger.Log(logger.Allow, "sdlimgui", "dropped mouse down event")
} else {
logger.Log("sdlimgui", "dropped mouse up event")
logger.Log(logger.Allow, "sdlimgui", "dropped mouse up event")
}
}
}
@ -236,7 +236,7 @@ func (img *SdlImgui) Service() {
Mod: getKeyMod(),
}:
default:
logger.Log("sdlimgui", "dropped mouse wheel event")
logger.Log(logger.Allow, "sdlimgui", "dropped mouse wheel event")
}
} else {
imgui.CurrentIO().AddMouseWheelDelta(-deltaX/4, deltaY/4)
@ -272,7 +272,7 @@ func (img *SdlImgui) Service() {
Down: ev.State == 1,
}:
default:
logger.Log("sdlimgui", "dropped gamepad button event")
logger.Log(logger.Allow, "sdlimgui", "dropped gamepad button event")
}
}
@ -308,7 +308,7 @@ func (img *SdlImgui) Service() {
Direction: dir,
}:
default:
logger.Log("sdlimgui", "dropped gamepad dpad event")
logger.Log(logger.Allow, "sdlimgui", "dropped gamepad dpad event")
}
}
@ -322,7 +322,7 @@ func (img *SdlImgui) Service() {
Vert: joy.Axis(1),
}:
default:
logger.Log("sdlimgui", "dropped stelladaptor event")
logger.Log(logger.Allow, "sdlimgui", "dropped stelladaptor event")
}
} else {
pad := sdl.GameControllerFromInstanceID(ev.Which)
@ -345,7 +345,7 @@ func (img *SdlImgui) Service() {
Vert: pad.Axis(1),
}:
default:
logger.Log("sdlimgui", "dropped gamepad axis event")
logger.Log(logger.Allow, "sdlimgui", "dropped gamepad axis event")
}
case 3:
fallthrough
@ -358,7 +358,7 @@ func (img *SdlImgui) Service() {
Vert: pad.Axis(4),
}:
default:
logger.Log("sdlimgui", "dropped gamepad axis event")
logger.Log(logger.Allow, "sdlimgui", "dropped gamepad axis event")
}
default:
}
@ -379,7 +379,7 @@ func (img *SdlImgui) Service() {
Amount: ev.Value,
}:
default:
logger.Log("sdlimgui", "dropped gamepad axis event")
logger.Log(logger.Allow, "sdlimgui", "dropped gamepad axis event")
}
}
}
@ -393,7 +393,7 @@ func (img *SdlImgui) Service() {
X: int16(mouseMotionX), Y: int16(mouseMotionY),
}:
default:
logger.Log("sdlimgui", "dropped mouse motion event")
logger.Log(logger.Allow, "sdlimgui", "dropped mouse motion event")
}
}
}

View file

@ -265,7 +265,7 @@ func (img *SdlImgui) serviceKeyboard(ev *sdl.KeyboardEvent) {
Mod: getKeyMod(),
}:
default:
logger.Log("sdlimgui", "dropped keyboard event")
logger.Log(logger.Allow, "sdlimgui", "dropped keyboard event")
}
}
}

View file

@ -93,7 +93,7 @@ func (trm *term) TermPrintLine(style terminal.Style, s string) {
if trm.sideChanLast.Load().(bool) {
trm.sideChanLast.Store(false)
if style == terminal.StyleError || style == terminal.StyleLog {
logger.Log("term", s)
logger.Log(logger.Allow, "term", s)
}
return
}
@ -179,6 +179,6 @@ func (trm *term) pushCommand(input string) {
// in most instances a depth of one is sufficient but occasionally it
// is not (eg. the HALT/RUN commands sent by the rewind slider in
// win_control)
logger.Logf("term", "dropping from side channel (%s)", input)
logger.Logf(logger.Allow, "term", "dropping from side channel (%s)", input)
}
}

View file

@ -504,13 +504,13 @@ func (win *winCoProcGlobals) saveToCSV(src *dwarf.Source) {
fn = fmt.Sprintf("%s.csv", fn)
f, err := os.Create(fn)
if err != nil {
logger.Logf("sdlimgui", "could not save globals CSV: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save globals CSV: %v", err)
return
}
defer func() {
err := f.Close()
if err != nil {
logger.Logf("sdlimgui", "error saving globals CSV: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "error saving globals CSV: %v", err)
}
}()

View file

@ -337,13 +337,13 @@ func (win *winCoProcSource) saveToCSV(src *dwarf.Source) {
fn = fmt.Sprintf("%s.csv", fn)
f, err := os.Create(fn)
if err != nil {
logger.Logf("sdlimgui", "could not save source CSV: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save source CSV: %v", err)
return
}
defer func() {
err := f.Close()
if err != nil {
logger.Logf("sdlimgui", "error saving source CSV: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "error saving source CSV: %v", err)
}
}()

View file

@ -53,7 +53,7 @@ func (win *winDbgScr) paintDragAndDrop() {
target.offset = mouse.offset
ff.build(target)
logger.Logf("paint", "flood fill starting at %s", target.coord)
logger.Logf(logger.Allow, "paint", "flood fill starting at %s", target.coord)
ff.resolve(0)
}
}

View file

@ -73,7 +73,7 @@ func (win *winPlusROMNick) draw() {
if drawPlusROMNick(win.img) {
err := win.img.dbg.VCS().Env.Prefs.PlusROM.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save preferences: %v", err)
}
}
}
@ -97,7 +97,7 @@ func drawPlusROMNick(img *SdlImgui) bool {
if imguiTextInput("##nick", plusnet.MaxNickLength, &nick, false) {
err := img.dbg.VCS().Env.Prefs.PlusROM.Nick.Set(nick)
if err != nil {
logger.Logf("sdlimgui", "could not set plusrom nick: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not set plusrom nick: %v", err)
}
changed = true
}

View file

@ -301,7 +301,7 @@ func (win *winPrefs) drawDebuggerTab() {
if imgui.Checkbox("Open Terminal on Error", &termOnError) {
err := win.img.prefs.terminalOnError.Set(termOnError)
if err != nil {
logger.Logf("sdlimgui", "could not set preference value: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not set preference value: %v", err)
}
}
@ -707,45 +707,45 @@ func (win *winPrefs) drawDiskButtons() {
if imgui.Button("Save All") {
err := win.img.prefs.save()
if err != nil {
logger.Logf("sdlimgui", "could not save (imgui debugger) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (imgui debugger) preferences: %v", err)
}
err = win.img.crtPrefs.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (crt) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (crt) preferences: %v", err)
}
err = win.img.audio.Prefs.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (sdlaudio) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (sdlaudio) preferences: %v", err)
}
win.img.dbg.PushFunction(func() {
err = win.img.dbg.VCS().Env.Prefs.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (vcs) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (vcs) preferences: %v", err)
}
err = win.img.dbg.VCS().Env.Prefs.ARM.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (arm) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (arm) preferences: %v", err)
}
err = win.img.dbg.VCS().Env.Prefs.AtariVox.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (atarivox) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (atarivox) preferences: %v", err)
}
err = win.img.dbg.VCS().Env.Prefs.PlusROM.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (plusrom) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (plusrom) preferences: %v", err)
}
err = win.img.dbg.VCS().Env.Prefs.Revision.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (tia revisions) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (tia revisions) preferences: %v", err)
}
err = win.img.dbg.Rewind.Prefs.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (rewind) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (rewind) preferences: %v", err)
}
if win.img.mode.Load().(govern.Mode) == govern.ModeDebugger {
err = win.img.dbg.Disasm.Prefs.Save()
if err != nil {
logger.Logf("sdlimgui", "could not save (disasm) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save (disasm) preferences: %v", err)
}
}
})
@ -755,45 +755,45 @@ func (win *winPrefs) drawDiskButtons() {
if imgui.Button("Restore All") {
err := win.img.prefs.load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (imgui debugger) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (imgui debugger) preferences: %v", err)
}
err = win.img.crtPrefs.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (crt) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (crt) preferences: %v", err)
}
err = win.img.audio.Prefs.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (sdlaudio) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (sdlaudio) preferences: %v", err)
}
win.img.dbg.PushFunction(func() {
err = win.img.dbg.VCS().Env.Prefs.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (vcs) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (vcs) preferences: %v", err)
}
err = win.img.dbg.VCS().Env.Prefs.ARM.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (arm) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (arm) preferences: %v", err)
}
err = win.img.dbg.VCS().Env.Prefs.AtariVox.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (atarivox) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (atarivox) preferences: %v", err)
}
err = win.img.dbg.VCS().Env.Prefs.PlusROM.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (plusrom) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (plusrom) preferences: %v", err)
}
err = win.img.dbg.VCS().Env.Prefs.Revision.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (tia revisions) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (tia revisions) preferences: %v", err)
}
err = win.img.dbg.Rewind.Prefs.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (rewind) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (rewind) preferences: %v", err)
}
if win.img.mode.Load().(govern.Mode) == govern.ModeDebugger {
err = win.img.dbg.Disasm.Prefs.Load()
if err != nil {
logger.Logf("sdlimgui", "could not restore (disasm) preferences: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not restore (disasm) preferences: %v", err)
}
}
})

View file

@ -116,11 +116,11 @@ func newSelectROM(img *SdlImgui) (window, error) {
// load and normalise box art names
boxartPath, err := resources.JoinPath(namedBoxarts)
if err != nil {
logger.Logf("sdlimgui", err.Error())
logger.Logf(logger.Allow, "sdlimgui", err.Error())
} else {
boxartFiles, err := os.ReadDir(boxartPath)
if err != nil {
logger.Logf("sdlimgui", err.Error())
logger.Logf(logger.Allow, "sdlimgui", err.Error())
} else {
for _, n := range boxartFiles {
win.boxart = append(win.boxart, n.Name())
@ -253,7 +253,7 @@ func (win *winSelectROM) render() {
func (win *winSelectROM) draw() {
err := win.path.Process()
if err != nil {
logger.Logf("sdlimgui", err.Error())
logger.Logf(logger.Allow, "sdlimgui", err.Error())
}
imgui.BeginGroup()
@ -274,7 +274,7 @@ func (win *winSelectROM) draw() {
// find box art as best we can
err := win.findBoxart()
if err != nil {
logger.Logf("sdlimgui", err.Error())
logger.Logf(logger.Allow, "sdlimgui", err.Error())
}
default:
}
@ -635,7 +635,7 @@ func (win *winSelectROM) SetSelectedFilename(filename string) {
// create cartridge loader and start thumbnail emulation
cartload, err := cartridgeloader.NewLoaderFromFilename(filename, "AUTO")
if err != nil {
logger.Logf("ROM Select", err.Error())
logger.Logf(logger.Allow, "ROM Select", err.Error())
return
}

View file

@ -274,7 +274,7 @@ func (win *winTerm) saveOutput() {
defer func() {
err := f.Close()
if err != nil {
logger.Logf("sdlimgui", "error saving terminal contents: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "error saving terminal contents: %v", err)
}
}()

View file

@ -576,13 +576,13 @@ func (win *winTimeline) saveToCSV() {
fn = fmt.Sprintf("%s.csv", fn)
f, err := os.Create(fn)
if err != nil {
logger.Logf("sdlimgui", "could not save timeline CSV: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "could not save timeline CSV: %v", err)
return
}
defer func() {
err := f.Close()
if err != nil {
logger.Logf("sdlimgui", "error saving timeline CSV: %v", err)
logger.Logf(logger.Allow, "sdlimgui", "error saving timeline CSV: %v", err)
}
}()

View file

@ -133,9 +133,10 @@ func (mc *CPU) Reset() {
mc.Interrupted = true
mc.Killed = false
// checking for env == nil because it's possible for NewCPU to be
// called with a nil environment (test package)
if mc.env != nil && mc.env.Prefs.RandomState.Get().(bool) {
// nil checks because it's possibel for NewCPU to be called with a nil
// environment (disassembly) or with nil Prefs instance in the environment
// (test package)
if mc.env != nil && mc.env.Prefs != nil && mc.env.Prefs.RandomState.Get().(bool) {
mc.PC.Load(uint16(mc.env.Random.NoRewind(0xffff)))
mc.A.Load(uint8(mc.env.Random.NoRewind(0xff)))
mc.X.Load(uint8(mc.env.Random.NoRewind(0xff)))
@ -1711,7 +1712,7 @@ func (mc *CPU) ExecuteInstruction(cycleCallback func() error) error {
case instructions.KIL:
if !mc.NoFlowControl {
mc.Killed = true
logger.Logf("CPU", "KIL instruction (%#04x)", mc.PC.Address())
logger.Logf(mc.env, "CPU", "KIL instruction (%#04x)", mc.PC.Address())
}
default:

View file

@ -19,6 +19,7 @@ import (
"fmt"
"testing"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/cpu"
rtest "github.com/jetsetilly/gopher2600/hardware/cpu/registers/test"
"github.com/jetsetilly/gopher2600/test"
@ -620,7 +621,7 @@ func testKIL(t *testing.T, mc *cpu.CPU, mem *testMem) {
func TestCPU(t *testing.T) {
mem := newTestMem()
mc := cpu.NewCPU(nil, mem)
mc := cpu.NewCPU(&environment.Environment{}, mem)
testStatusInstructions(t, mc, mem)
testRegsiterArithmetic(t, mc, mem)

View file

@ -55,18 +55,18 @@ func NewAce(env *environment.Environment, loader cartridgeloader.Loader) (mapper
yieldHook: coprocessor.StubCartYieldHook{},
}
cart.mem, err = newAceMemory(data, cart.env.Prefs.ARM)
cart.mem, err = newAceMemory(env, data, cart.env.Prefs.ARM)
if err != nil {
return nil, err
}
cart.arm = arm.NewARM(cart.mem.model, cart.env.Prefs.ARM, cart.mem, cart)
cart.arm = arm.NewARM(cart.env, cart.mem.model, cart.mem, cart)
cart.mem.Plumb(cart.arm)
logger.Logf("ACE", "ccm: %08x to %08x", cart.mem.ccmOrigin, cart.mem.ccmMemtop)
logger.Logf("ACE", "flash: %08x to %08x", cart.mem.downloadOrigin, cart.mem.downloadMemtop)
logger.Logf("ACE", "buffer: %08x to %08x", cart.mem.bufferOrigin, cart.mem.bufferMemtop)
logger.Logf("ACE", "gpio: %08x to %08x", cart.mem.gpioOrigin, cart.mem.gpioMemtop)
logger.Logf(env, "ACE", "ccm: %08x to %08x", cart.mem.ccmOrigin, cart.mem.ccmMemtop)
logger.Logf(env, "ACE", "flash: %08x to %08x", cart.mem.downloadOrigin, cart.mem.downloadMemtop)
logger.Logf(env, "ACE", "buffer: %08x to %08x", cart.mem.bufferOrigin, cart.mem.bufferMemtop)
logger.Logf(env, "ACE", "gpio: %08x to %08x", cart.mem.gpioOrigin, cart.mem.gpioMemtop)
return cart, nil
}
@ -104,7 +104,7 @@ func (cart *Ace) PlumbFromDifferentEmulation(env *environment.Environment) {
if cart.armState == nil {
panic("cannot plumb this ACE instance because the ARM state is nil")
}
cart.arm = arm.NewARM(cart.mem.model, cart.env.Prefs.ARM, cart.mem, cart)
cart.arm = arm.NewARM(cart.env, cart.mem.model, cart.mem, cart)
cart.mem.Plumb(cart.arm)
cart.arm.Plumb(cart.armState, cart.mem, cart)
cart.armState = nil

View file

@ -20,6 +20,7 @@ import (
"fmt"
"github.com/jetsetilly/gopher2600/coprocessor"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm/architecture"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
@ -51,6 +52,8 @@ const (
)
type aceMemory struct {
env *environment.Environment
header aceHeader
model architecture.Map
@ -117,8 +120,9 @@ func (mem *aceMemory) setDataMode(out bool) {
}
}
func newAceMemory(data []byte, armPrefs *preferences.ARMPreferences) (*aceMemory, error) {
func newAceMemory(env *environment.Environment, data []byte, armPrefs *preferences.ARMPreferences) (*aceMemory, error) {
mem := &aceMemory{
env: env,
model: architecture.NewMap(architecture.PlusCart),
}
@ -129,41 +133,41 @@ func newAceMemory(data []byte, armPrefs *preferences.ARMPreferences) (*aceMemory
// read header
mem.header.version = string(data[:aceHeaderDriverName])
logger.Logf("ACE", "header: version name: %s", mem.header.version)
logger.Logf(mem.env, "ACE", "header: version name: %s", mem.header.version)
mem.header.driverName = string(data[aceHeaderDriverName:aceHeaderDriverVersion])
logger.Logf("ACE", "header: driver name: %s", mem.header.driverName)
logger.Logf(mem.env, "ACE", "header: driver name: %s", mem.header.driverName)
mem.header.driverVersion = (uint32(data[aceHeaderDriverVersion])) |
(uint32(data[aceHeaderDriverVersion+1]) << 8) |
(uint32(data[aceHeaderDriverVersion+2]) << 16) |
(uint32(data[aceHeaderDriverVersion+3]) << 24)
logger.Logf("ACE", "header: driver version: %08x", mem.header.driverVersion)
logger.Logf(mem.env, "ACE", "header: driver version: %08x", mem.header.driverVersion)
mem.header.romSize = (uint32(data[aceHeaderROMSize])) |
(uint32(data[aceHeaderROMSize+1]) << 8) |
(uint32(data[aceHeaderROMSize+2]) << 16) |
(uint32(data[aceHeaderROMSize+3]) << 24)
logger.Logf("ACE", "header: romsize: %08x", mem.header.romSize)
logger.Logf(mem.env, "ACE", "header: romsize: %08x", mem.header.romSize)
mem.header.checksum = (uint32(data[aceHeaderROMChecksum])) |
(uint32(data[aceHeaderROMChecksum+1]) << 8) |
(uint32(data[aceHeaderROMChecksum+2]) << 16) |
(uint32(data[aceHeaderROMChecksum+3]) << 24)
logger.Logf("ACE", "header: checksum: %08x", mem.header.checksum)
logger.Logf(mem.env, "ACE", "header: checksum: %08x", mem.header.checksum)
mem.header.entry = (uint32(data[aceHeaderEntryPoint])) |
(uint32(data[aceHeaderEntryPoint+1]) << 8) |
(uint32(data[aceHeaderEntryPoint+2]) << 16) |
(uint32(data[aceHeaderEntryPoint+3]) << 24)
logger.Logf("ACE", "header: entrypoint: %08x", mem.header.entry)
logger.Logf(mem.env, "ACE", "header: entrypoint: %08x", mem.header.entry)
mem.download = data[:]
switch mem.header.version {
case "ACE-PC00":
mem.downloadOrigin = 0x08020000
mem.header.entry = 0x1028
logger.Logf("ACE", "header: entrypoint adjusted to: %08x", mem.header.entry)
logger.Logf(mem.env, "ACE", "header: entrypoint adjusted to: %08x", mem.header.entry)
case "ACE-UF00":
mem.downloadOrigin = 0x08020000
case "ACE-2600":
@ -179,7 +183,7 @@ func newAceMemory(data []byte, armPrefs *preferences.ARMPreferences) (*aceMemory
mem.resetSP = mem.ccmMemtop - 3
// note the real entry point
logger.Logf("ACE", "actual entrypoint: %08x", mem.resetPC)
logger.Logf(mem.env, "ACE", "actual entrypoint: %08x", mem.resetPC)
// define the Thumb-2 bytecode for a function whose only purpose is to jump
// back to where it came from bytecode is for instruction "BX LR" with a
@ -194,7 +198,7 @@ func newAceMemory(data []byte, armPrefs *preferences.ARMPreferences) (*aceMemory
// the code location of the null function must not be on a 16bit boundary
if arm.IsAlignedTo16bits(nullFunctionAddress) {
logger.Logf("ACE", "correcting alignment at end of ARM program")
logger.Logf(mem.env, "ACE", "correcting alignment at end of ARM program")
mem.download = append(mem.download, 0x00)
mem.downloadMemtop++
nullFunctionAddress++
@ -213,7 +217,7 @@ func newAceMemory(data []byte, armPrefs *preferences.ARMPreferences) (*aceMemory
// setting the program counter
nullFunctionAddress |= 0x01
logger.Logf("ACE", "null function place at %08x", nullFunctionAddress)
logger.Logf(mem.env, "ACE", "null function place at %08x", nullFunctionAddress)
// choose size for the remainder of the flash memory and place at the flash
// origin value for architecture

View file

@ -17,10 +17,6 @@
// differences in cartridge and ARM archtectures.
package architecture
import (
"github.com/jetsetilly/gopher2600/logger"
)
// CartArchitecture defines the memory map for the ARM.
type CartArchitecture string
@ -113,7 +109,7 @@ func NewMap(cart CartArchitecture) Map {
switch mmap.CartArchitecture {
default:
logger.Logf("ARM Architecture", "unknown cartridge architecture (%s) defaulting to Harmony", cart)
// logger.Logf(env, "ARM Architecture", "unknown cartridge architecture (%s) defaulting to Harmony", cart)
mmap.CartArchitecture = Harmony
fallthrough
@ -175,9 +171,9 @@ func NewMap(cart CartArchitecture) Map {
mmap.ClkDiv = 0.5
}
logger.Logf("ARM Architecture", "using %s/%s", mmap.CartArchitecture, mmap.ARMArchitecture)
logger.Logf("ARM Architecture", "flash origin: %#08x", mmap.FlashOrigin)
logger.Logf("ARM Architecture", "sram origin: %#08x", mmap.SRAMOrigin)
// logger.Logf(env, "ARM Architecture", "using %s/%s", mmap.CartArchitecture, mmap.ARMArchitecture)
// logger.Logf(env, "ARM Architecture", "flash origin: %#08x", mmap.FlashOrigin)
// logger.Logf(env, "ARM Architecture", "sram origin: %#08x", mmap.SRAMOrigin)
return mmap
}

View file

@ -24,10 +24,10 @@ import (
"github.com/jetsetilly/gopher2600/coprocessor"
"github.com/jetsetilly/gopher2600/coprocessor/developer/faults"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm/architecture"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm/fpu"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm/peripherals"
"github.com/jetsetilly/gopher2600/hardware/preferences"
"github.com/jetsetilly/gopher2600/logger"
)
@ -198,10 +198,10 @@ func (s *ARMState) Snapshot() *ARMState {
// ARM implements the ARM7TDMI-S LPC2103 processor.
type ARM struct {
prefs *preferences.ARMPreferences
mmap architecture.Map
mem SharedMemory
hook CartridgeHook
env *environment.Environment
mmap architecture.Map
mem SharedMemory
hook CartridgeHook
// the binary interface for reading data returned by SharedMemory interface.
// defaults to LittleEndian
@ -286,9 +286,9 @@ type ARM struct {
}
// NewARM is the preferred method of initialisation for the ARM type.
func NewARM(mmap architecture.Map, prefs *preferences.ARMPreferences, mem SharedMemory, hook CartridgeHook) *ARM {
func NewARM(env *environment.Environment, mmap architecture.Map, mem SharedMemory, hook CartridgeHook) *ARM {
arm := &ARM{
prefs: prefs,
env: env,
mmap: mmap,
mem: mem,
hook: hook,
@ -319,8 +319,8 @@ func NewARM(mmap architecture.Map, prefs *preferences.ARMPreferences, mem Shared
panic(fmt.Sprintf("unhandled ARM architecture: cannot set %s", arm.mmap.ARMArchitecture))
}
arm.state.mam = newMam(arm.prefs, arm.mmap)
arm.state.rng = peripherals.NewRNG(arm.mmap)
arm.state.mam = newMam(arm.env, arm.mmap)
arm.state.rng = peripherals.NewRNG(arm.env, arm.mmap)
arm.state.timer = peripherals.NewTimer(arm.mmap)
arm.state.timer2 = peripherals.NewTimer2(arm.mmap)
@ -440,12 +440,12 @@ func (arm *ARM) resetRegisters() {
// prefsPulse ticker
func (arm *ARM) updatePrefs() {
// update clock value from preferences
arm.Clk = float32(arm.prefs.Clock.Get().(float64))
arm.Clk = float32(arm.env.Prefs.ARM.Clock.Get().(float64))
arm.state.mam.updatePrefs()
// set cycle counting functions
arm.immediateMode = arm.prefs.Immediate.Get().(bool)
arm.immediateMode = arm.env.Prefs.ARM.Immediate.Get().(bool)
if arm.immediateMode {
arm.Icycle = arm.iCycleStub
arm.Scycle = arm.sCycleStub
@ -456,8 +456,8 @@ func (arm *ARM) updatePrefs() {
arm.Ncycle = arm.nCycle
}
arm.abortOnMemoryFault = arm.prefs.AbortOnMemoryFault.Get().(bool)
arm.misalignedAccessIsFault = arm.prefs.MisalignedAccessIsFault.Get().(bool)
arm.abortOnMemoryFault = arm.env.Prefs.ARM.AbortOnMemoryFault.Get().(bool)
arm.misalignedAccessIsFault = arm.env.Prefs.ARM.MisalignedAccessIsFault.Get().(bool)
}
func (arm *ARM) String() string {
@ -516,14 +516,14 @@ func (arm *ARM) logYield() {
return
}
if arm.state.yield.Error != nil {
logger.Logf("ARM7", "%s: %s", arm.state.yield.Type.String(), arm.state.yield.Error.Error())
logger.Logf(arm.env, "ARM7", "%s: %s", arm.state.yield.Type.String(), arm.state.yield.Error.Error())
} else {
logger.Logf("ARM7", "%s: no specific error", arm.state.yield.Type.String())
logger.Logf(arm.env, "ARM7", "%s: no specific error", arm.state.yield.Type.String())
}
// extended memory logging
if arm.prefs.ExtendedMemoryFaultLogging.Get().(bool) == false {
if arm.env.Prefs.ARM.ExtendedMemoryFaultLogging.Get().(bool) == false {
return
}
@ -543,8 +543,8 @@ func (arm *ARM) logYield() {
entry := arm.decodeInstruction(df)
if entry != nil {
logger.Logf("ARM7", "%s", entry.String())
logger.Logf("ARM7", "%s", arm.disasmVerbose(*entry))
logger.Logf(arm.env, "ARM7", "%s", entry.String())
logger.Logf(arm.env, "ARM7", "%s", arm.disasmVerbose(*entry))
}
}
@ -898,13 +898,13 @@ func (arm *ARM) run() (coprocessor.CoProcYield, float32) {
// limit the number of cycles used by the ARM program
if arm.state.cyclesTotal >= cycleLimit {
logger.Logf("ARM7", "reached cycle limit of %d", cycleLimit)
logger.Logf(arm.env, "ARM7", "reached cycle limit of %d", cycleLimit)
panic("cycle limit")
}
} else {
iterations++
if iterations > instructionsLimit {
logger.Logf("ARM7", "reached instructions limit of %d", instructionsLimit)
logger.Logf(arm.env, "ARM7", "reached instructions limit of %d", instructionsLimit)
panic("instruction limit")
}
}

View file

@ -16,6 +16,7 @@
package arm
import (
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm/architecture"
"github.com/jetsetilly/gopher2600/hardware/preferences"
"github.com/jetsetilly/gopher2600/logger"
@ -24,8 +25,8 @@ import (
// MAM implements the memory addressing module as found in the LPC20000. Not
// fully implemented but good enough for most Harmony games
type mam struct {
prefs *preferences.ARMPreferences
mmap architecture.Map
env *environment.Environment
mmap architecture.Map
// valid values for mamcr are 0, 1 or 2 are valid. we can think of these
// respectively, as "disable", "partial" and "full"
@ -51,10 +52,10 @@ type mam struct {
prefectchAborted bool
}
func newMam(prefs *preferences.ARMPreferences, mmap architecture.Map) mam {
func newMam(env *environment.Environment, mmap architecture.Map) mam {
return mam{
prefs: prefs,
mmap: mmap,
env: env,
mmap: mmap,
}
}
@ -62,7 +63,7 @@ func (m *mam) Reset() {
}
func (m *mam) updatePrefs() {
m.pref = m.prefs.MAM.Get().(int)
m.pref = m.env.Prefs.ARM.MAM.Get().(int)
if m.pref == preferences.MAMDriver {
m.mamcr = m.mmap.PreferredMAMCR
m.mamtim = 4.0
@ -83,7 +84,7 @@ func (m *mam) Write(addr uint32, val uint32) bool {
if m.mamcr == 0 {
m.mamtim = val
} else {
logger.Logf("ARM7", "trying to write to MAMTIM while MAMCR is active")
logger.Logf(m.env, "ARM7", "trying to write to MAMTIM while MAMCR is active")
}
}
default:
@ -111,6 +112,6 @@ func (m *mam) Read(addr uint32) (uint32, bool) {
func (m *mam) setMAMCR(val architecture.MAMCR) {
m.mamcr = val
if m.mamcr > 2 {
logger.Logf("ARM7", "setting MAMCR to a value greater than 2 (%#08x)", m.mamcr)
logger.Logf(m.env, "ARM7", "setting MAMCR to a value greater than 2 (%#08x)", m.mamcr)
}
}

View file

@ -18,6 +18,7 @@ package peripherals
import (
"math/rand"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm/architecture"
"github.com/jetsetilly/gopher2600/logger"
)
@ -33,6 +34,7 @@ import (
// purposes it's probably okay. It basically returns a random 32bit number
// whenever the data register is read
type RNG struct {
env *environment.Environment
mmap architecture.Map
// control register value
@ -48,8 +50,9 @@ type RNG struct {
interruptEnabled bool
}
func NewRNG(mmap architecture.Map) RNG {
func NewRNG(env *environment.Environment, mmap architecture.Map) RNG {
return RNG{
env: env,
mmap: mmap,
}
}
@ -67,10 +70,10 @@ func (r *RNG) Write(addr uint32, val uint32) bool {
r.interruptEnabled = r.control&0b1000 == 0b1000
case r.mmap.RNGSR:
// status register
logger.Logf("ARM7", "ignoring write to RNG status register (value of %08x)", val)
logger.Logf(r.env, "ARM7", "ignoring write to RNG status register (value of %08x)", val)
case r.mmap.RNGDR:
// data register
logger.Logf("ARM7", "ignoring write to RNG data register (value of %08x)", val)
logger.Logf(r.env, "ARM7", "ignoring write to RNG data register (value of %08x)", val)
default:
return false
}

View file

@ -211,7 +211,7 @@ func (arm *ARM) decodeThumbMoveShiftedRegister(opcode uint16) decodeFunction {
}
if destReg == rPC {
logger.Log("ARM7", "shift and store in PC is not possible in thumb mode")
logger.Log(arm.env, "ARM7", "shift and store in PC is not possible in thumb mode")
}
// "7.6 Data Operations" in "ARM7TDMI-S Technical Reference Manual r4p3"
@ -763,7 +763,7 @@ func (arm *ARM) decodeThumbALUoperations(opcode uint16) decodeFunction {
// page 7-11 in "ARM7TDMI-S Technical Reference Manual r4p3"
if shift > 0 && destReg == rPC {
logger.Log("ARM7", "shift and store in PC is not possible in thumb mode")
logger.Log(arm.env, "ARM7", "shift and store in PC is not possible in thumb mode")
}
if mul {
@ -957,6 +957,18 @@ func (arm *ARM) decodeThumbHiRegisterOps(opcode uint16) decodeFunction {
}
}
// if we're still in thumb mode the instruction has ended
//
// the position of this test is important, particularly for ELF
// binaries and how the BLX instruction at the end of strongarm
// functions have been constructed
if thumbMode {
// "7.6 Data Operations" in "ARM7TDMI-S Technical Reference Manual r4p3"
// - fillPipeline() will be called if necessary
arm.state.registers[rPC] = newPC
return nil
}
// if the PC is now the same as the expected return address then the
// ARM program has ended and we can yield with the YieldProgramEnded
// type
@ -970,14 +982,6 @@ func (arm *ARM) decodeThumbHiRegisterOps(opcode uint16) decodeFunction {
return nil
}
// if we're still in thumb mode the instruction has ended
if thumbMode {
// "7.6 Data Operations" in "ARM7TDMI-S Technical Reference Manual r4p3"
// - fillPipeline() will be called if necessary
arm.state.registers[rPC] = newPC
return nil
}
// NOTE: the remainder of the instruction handles ARM interrupts.
// note that this hasn't been tested with ARMv7_M processor types.
// this type of processor does not have 32bit instructions so may

View file

@ -230,7 +230,7 @@ func (arm *ARM) decodeThumb2ChangeProcessorState(opcode uint16) decodeFunction {
Operator: "CPSID",
}
}
logger.Logf("ARM7", "CPSID instruction does nothing")
logger.Logf(arm.env, "ARM7", "CPSID instruction does nothing")
return nil
}
}

View file

@ -26,6 +26,7 @@ import (
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/ace"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/cdf"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/dpcplus"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/elf"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/moviecart"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/plusrom"
@ -208,7 +209,7 @@ func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
cart.coprocBus, cart.hasCoProcBus = cart.mapper.(coprocessor.CartCoProcBus)
if _, ok := cart.mapper.(*ejected); !ok {
logger.Logf("cartridge", "inserted %s", cart.mapper.ID())
logger.Logf(cart.env, "cartridge", "inserted %s", cart.mapper.ID())
}
}()
@ -294,8 +295,6 @@ func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
cart.mapper, err = newSuperbank(cart.env, cartload)
case "WD":
cart.mapper, err = newWicksteadDesign(cart.env, cartload)
case "ACE":
cart.mapper, err = ace.NewAce(cart.env, cartload)
case "DPC":
cart.mapper, err = newDPC(cart.env, cartload)
case "DPC+":
@ -314,6 +313,15 @@ func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
case "MVC":
cart.mapper, err = moviecart.NewMoviecart(cart.env, cartload)
case "ACE":
cart.mapper, err = ace.NewAce(cart.env, cartload)
case "ACE_wrapped_ELF":
cart.mapper, err = elf.NewElf(cart.env, cartload, true)
case "ELF":
cart.mapper, err = elf.NewElf(cart.env, cartload, false)
}
if err != nil {
return fmt.Errorf("cartridge: %w", err)
@ -326,7 +334,7 @@ func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
if superchip, ok := cart.mapper.(mapper.OptionalSuperchip); ok {
superchip.AddSuperchip(true)
} else {
logger.Logf("cartridge", "cannot add superchip to %s mapper", cart.ID())
logger.Logf(cart.env, "cartridge", "cannot add superchip to %s mapper", cart.ID())
}
} else if superchip, ok := cart.mapper.(mapper.OptionalSuperchip); ok {
superchip.AddSuperchip(false)
@ -345,17 +353,17 @@ func (cart *Cartridge) Attach(cartload cartridgeloader.Loader) error {
if err != nil {
if errors.Is(err, plusrom.NotAPlusROM) {
logger.Log("cartridge", err.Error())
logger.Log(cart.env, "cartridge", err.Error())
return nil
}
if errors.Is(err, plusrom.CannotAdoptROM) {
logger.Log("cartridge", err.Error())
logger.Log(cart.env, "cartridge", err.Error())
return nil
}
return fmt.Errorf("cartridge: %w", err)
}
logger.Logf("cartridge", "%s cartridge contained in PlusROM", cart.ID())
logger.Logf(cart.env, "cartridge", "%s cartridge contained in PlusROM", cart.ID())
// we've wrapped the main cartridge mapper inside the PlusROM
// mapper and we need to point the mapper field to the the new

View file

@ -132,7 +132,7 @@ func NewCDF(env *environment.Environment, loader cartridgeloader.Loader, version
//
// if bank0 has any ARM code then it will start at offset 0x08. first eight
// bytes are the ARM header
cart.arm = arm.NewARM(cart.version.mmap, cart.env.Prefs.ARM, cart.state.static, cart)
cart.arm = arm.NewARM(cart.env, cart.version.mmap, cart.state.static, cart)
return cart, nil
}
@ -180,7 +180,7 @@ func (cart *cdf) PlumbFromDifferentEmulation(env *environment.Environment) {
if cart.armState == nil {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.arm = arm.NewARM(cart.version.mmap, cart.env.Prefs.ARM, cart.state.static, cart)
cart.arm = arm.NewARM(cart.env, cart.version.mmap, cart.state.static, cart)
cart.arm.Plumb(cart.armState, cart.state.static, cart)
cart.armState = nil
cart.yieldHook = &coprocessor.StubCartYieldHook{}

View file

@ -117,7 +117,7 @@ func NewDPCplus(env *environment.Environment, loader cartridgeloader.Loader) (ma
//
// if bank0 has any ARM code then it will start at offset 0x08. first eight
// bytes are the ARM header
cart.arm = arm.NewARM(cart.version.mmap, env.Prefs.ARM, cart.state.static, cart)
cart.arm = arm.NewARM(cart.env, cart.version.mmap, cart.state.static, cart)
return cart, nil
}
@ -165,7 +165,7 @@ func (cart *dpcPlus) PlumbFromDifferentEmulation(env *environment.Environment) {
if cart.armState == nil {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.arm = arm.NewARM(cart.version.mmap, cart.env.Prefs.ARM, cart.state.static, cart)
cart.arm = arm.NewARM(cart.env, cart.version.mmap, cart.state.static, cart)
cart.arm.Plumb(cart.armState, cart.state.static, cart)
cart.armState = nil
cart.yieldHook = &coprocessor.StubCartYieldHook{}
@ -487,7 +487,7 @@ func (cart *dpcPlus) AccessVolatile(addr uint16, data uint8, poke bool) error {
case 1:
// copy rom to fetcher
if len(cart.state.parameters) != 4 {
logger.Logf("DPC+", "wrong number of parameters for function call [%02x]", data)
logger.Logf(cart.env, "DPC+", "wrong number of parameters for function call [%02x]", data)
break // switch data
}
@ -504,7 +504,7 @@ func (cart *dpcPlus) AccessVolatile(addr uint16, data uint8, poke bool) error {
case 2:
// copy value to fetcher
if len(cart.state.parameters) != 4 {
logger.Logf("DPC+", "wrong number of parameters for function call [%02x]", data)
logger.Logf(cart.env, "DPC+", "wrong number of parameters for function call [%02x]", data)
break // switch data
}

View file

@ -22,6 +22,7 @@ import (
"io"
"os"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/coprocessor"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/arm"
@ -32,10 +33,9 @@ import (
// Elf implements the mapper.CartMapper interface.
type Elf struct {
env *environment.Environment
version string
pathToROM string
env *environment.Environment
loader cartridgeloader.Loader
version string
arm *arm.ARM
mem *elfMemory
@ -75,12 +75,12 @@ func (r *elfReaderAt) ReadAt(p []byte, start int64) (n int, err error) {
}
// NewElf is the preferred method of initialisation for the Elf type.
func NewElf(env *environment.Environment, pathToROM string, inACE bool) (mapper.CartMapper, error) {
func NewElf(env *environment.Environment, loader cartridgeloader.Loader, inACE bool) (mapper.CartMapper, error) {
r := &elfReaderAt{}
// open file in the normal way and read all data. close the file
// immediately once all data is rad
o, err := os.Open(pathToROM)
o, err := os.Open(loader.Filename)
if err != nil {
return nil, fmt.Errorf("ELF: %w", err)
}
@ -131,12 +131,12 @@ func NewElf(env *environment.Environment, pathToROM string, inACE bool) (mapper.
cart := &Elf{
env: env,
pathToROM: pathToROM,
loader: loader,
yieldHook: coprocessor.StubCartYieldHook{},
}
cart.mem = newElfMemory(env)
cart.arm = arm.NewARM(cart.mem.model, cart.env.Prefs.ARM, cart.mem, cart)
cart.mem = newElfMemory(cart.env)
cart.arm = arm.NewARM(cart.env, cart.mem.model, cart.mem, cart)
cart.mem.Plumb(cart.arm)
err = cart.mem.decode(ef)
if err != nil {
@ -191,7 +191,7 @@ func (cart *Elf) PlumbFromDifferentEmulation(env *environment.Environment) {
if cart.armState == nil {
panic("cannot plumb this ELF instance because the ARM state is nil")
}
cart.arm = arm.NewARM(cart.mem.model, cart.env.Prefs.ARM, cart.mem, cart)
cart.arm = arm.NewARM(cart.env, cart.mem.model, cart.mem, cart)
cart.arm.Plumb(cart.armState, cart.mem, cart)
cart.armState = nil
cart.mem.Plumb(cart.arm)

View file

@ -214,13 +214,13 @@ func (mem *elfMemory) decode(ef *elf.File) error {
section.memtop += section.trailingBytes - 1
}
logger.Logf("ELF", "%s: %08x to %08x (%d) [%d trailing bytes]",
logger.Logf(mem.env, "ELF", "%s: %08x to %08x (%d) [%d trailing bytes]",
section.name, section.origin, section.memtop, len(section.data), section.trailingBytes)
if section.readOnly() {
logger.Logf("ELF", "%s: is readonly", section.name)
logger.Logf(mem.env, "ELF", "%s: is readonly", section.name)
}
if section.executable() {
logger.Logf("ELF", "%s: is executable", section.name)
logger.Logf(mem.env, "ELF", "%s: is executable", section.name)
}
}
@ -271,10 +271,10 @@ func (mem *elfMemory) decode(ef *elf.File) error {
// value will be out of range according to the MapAddress check (2) the
// offset value can go beyond the end of the .debug_macro data slice
if secBeingRelocated.name == ".debug_macro" {
logger.Logf("ELF", "not relocating %s", secBeingRelocated.name)
logger.Logf(mem.env, "ELF", "not relocating %s", secBeingRelocated.name)
continue
} else {
logger.Logf("ELF", "relocating %s", secBeingRelocated.name)
logger.Logf(mem.env, "ELF", "relocating %s", secBeingRelocated.name)
}
// relocation data. we walk over the data and extract the relocation
@ -507,7 +507,7 @@ func (mem *elfMemory) decode(ef *elf.File) error {
if sym.Section == elf.SHN_UNDEF {
// for R_ARM_ABS32 type symbols we create a stub function and use it to
// generate a memory fault when it's accessed
logger.Logf("ELF", "using stub for %s (will cause memory fault when called)", sym.Name)
logger.Logf(mem.env, "ELF", "using stub for %s (will cause memory fault when called)", sym.Name)
tgt, err = mem.relocateStrongArmFunction(strongArmFunctionSpec{
function: func(mem *elfMemory) {
mem.arm.MemoryFault(sym.Name, faults.UndefinedSymbol)
@ -548,7 +548,7 @@ func (mem *elfMemory) decode(ef *elf.File) error {
if name == "" {
name = "anonymous"
}
logger.Logf("ELF", "relocate %s (%08x) => %08x", name, secBeingRelocated.origin+offset, tgt)
logger.Logf(mem.env, "ELF", "relocate %s (%08x) => %08x", name, secBeingRelocated.origin+offset, tgt)
case elf.R_ARM_THM_PC22:
// this value is labelled R_ARM_THM_CALL in objdump output
@ -606,7 +606,7 @@ func (mem *elfMemory) decode(ef *elf.File) error {
if name == "" {
name = "anonymous"
}
logger.Logf("ELF", "relocate %s (%08x) => opcode %08x", name, secBeingRelocated.origin+offset, opcode)
logger.Logf(mem.env, "ELF", "relocate %s (%08x) => opcode %08x", name, secBeingRelocated.origin+offset, opcode)
default:
return fmt.Errorf("ELF: unhandled ARM relocation type (%v)", relType)
@ -618,7 +618,7 @@ func (mem *elfMemory) decode(ef *elf.File) error {
mem.strongArmMemtop -= 1
// strongarm address information
logger.Logf("ELF", "strongarm: %08x to %08x (%d)",
logger.Logf(mem.env, "ELF", "strongarm: %08x to %08x (%d)",
mem.strongArmOrigin, mem.strongArmMemtop, len(mem.strongArmProgram))
// SRAM creation
@ -660,7 +660,7 @@ func (mem *elfMemory) runInitialisation(arm *arm.ARM) error {
}
mem.resetPC &= 0xfffffffe
logger.Logf("ELF", "running %s at %08x", sec.name, mem.resetPC)
logger.Logf(mem.env, "ELF", "running %s at %08x", sec.name, mem.resetPC)
_, _ = arm.Run()
}
}
@ -814,7 +814,7 @@ func (mem *elfMemory) MapAddress(addr uint32, write bool) (*[]byte, uint32) {
func (mem *elfMemory) mapAddress(addr uint32, write bool) (*[]byte, uint32) {
if addr >= mem.gpio.dataOrigin && addr <= mem.gpio.dataMemtop {
if mem.stream.active {
logger.Log("ELF", "disabling byte streaming")
logger.Log(mem.env, "ELF", "disabling byte streaming")
mem.stream.active = false
}
if !write && addr == mem.gpio.dataOrigin|ADDR_IDR {

View file

@ -382,7 +382,9 @@ func (cart *Cartridge) fingerprint(cartload cartridgeloader.Loader) (string, err
}
if ok, wrappedElf := fingerprintAce(cartload); ok {
_ = wrappedElf
if wrappedElf {
return "ACE_wrapped_ELF", nil
}
return "ACE", nil
}

View file

@ -121,7 +121,7 @@ func (cart *atari) ROMDump(filename string) error {
defer func() {
err := f.Close()
if err != nil {
logger.Logf("%s", cart.mappingID, err.Error())
logger.Logf(cart.env, "%s", cart.mappingID, err.Error())
}
}()

View file

@ -73,10 +73,10 @@ func newCommaVid(env *environment.Environment, loader cartridgeloader.Loader) (m
if len(data) < 2048 {
// place undersized binaries at the end of memory
copy(cart.bankData[4096-len(data):], data)
logger.Logf("CV", "placing undersized commavid data at end of cartridge memory")
logger.Logf(env, "CV", "placing undersized commavid data at end of cartridge memory")
} else if len(data) == 2048 {
copy(cart.bankData[2048:], data[:2048])
logger.Logf("CV", "placing 2k commavid data at end of cartridge memory")
logger.Logf(env, "CV", "placing 2k commavid data at end of cartridge memory")
} else {
return nil, fmt.Errorf("CV: unhandled size for commavid cartridges (%d)", len(data))
}

View file

@ -71,7 +71,7 @@ func newUA(env *environment.Environment, loader cartridgeloader.Loader) (mapper.
// only one cartridge dump is known to have swapped hotspots
if fmt.Sprintf("%0x", sha1.Sum(data)) == "6d4a94c2348bbd8e9c73b73d8f3389196d42fd54" {
cart.swappedHotspots = true
logger.Logf("UA", "swapping hotspot address for this cartridge (Sorcerer's Apprentice)")
logger.Logf(env, "UA", "swapping hotspot address for this cartridge (Sorcerer's Apprentice)")
}
return cart, nil

View file

@ -415,7 +415,7 @@ func (cart *Moviecart) processAddress(addr uint16) {
defer func() {
if r := recover(); r != nil {
cart.state.streamFail = true
logger.Logf("MVC", "serious data error in moviecart stream")
logger.Logf(cart.env, "MVC", "serious data error in moviecart stream")
}
}()
@ -443,7 +443,7 @@ func (cart *Moviecart) processAddress(addr uint16) {
err := cart.env.Notifications.Notify(notifications.NotifyMovieCartStarted)
if err != nil {
logger.Logf("moviecart", err.Error())
logger.Logf(cart.env, "moviecart", err.Error())
}
} else if cart.state.totalCycles > titleCycles {
@ -971,12 +971,12 @@ func (cart *Moviecart) nextField() {
dataOffset := cart.state.streamChunk * chunkSize
_, err := cart.data.Seek(int64(dataOffset), io.SeekStart)
if err != nil {
logger.Logf("MVC", "error seeking field: %v", err)
logger.Logf(cart.env, "MVC", "error seeking field: %v", err)
}
n, err := cart.data.Read(cart.state.streamBuffer[cart.state.streamIndex])
if err != nil {
if !errors.Is(err, io.EOF) {
logger.Logf("MVC", "error reading field: %v", err)
logger.Logf(cart.env, "MVC", "error reading field: %v", err)
}
}
cart.state.endOfStream = n < fieldSize
@ -994,11 +994,11 @@ func (cart *Moviecart) nextField() {
dataOffset := cart.state.streamChunk * chunkSize
_, err := cart.data.Seek(int64(dataOffset), io.SeekStart)
if err != nil {
logger.Logf("MVC", "error reading field: %v", err)
logger.Logf(cart.env, "MVC", "error reading field: %v", err)
}
_, err = cart.data.Read(cart.state.streamBuffer[fld])
if err != nil {
logger.Logf("MVC", "error reading field: %v", err)
logger.Logf(cart.env, "MVC", "error reading field: %v", err)
}
}
}
@ -1008,7 +1008,7 @@ func (cart *Moviecart) nextField() {
cart.state.streamBuffer[cart.state.streamIndex][1] != 'V' ||
cart.state.streamBuffer[cart.state.streamIndex][2] != 'C' ||
cart.state.streamBuffer[cart.state.streamIndex][3] != 0x00 {
logger.Logf("MVC", "unrecognised version string in chunk %d", cart.state.streamChunk)
logger.Logf(cart.env, "MVC", "unrecognised version string in chunk %d", cart.state.streamChunk)
return
}

View file

@ -115,11 +115,11 @@ func (n *network) transmit() {
n.sendLock.Lock()
defer n.sendLock.Unlock()
logger.Logf("plusrom [net]", "sending to %s", addr.String())
logger.Logf(n.env, "plusrom [net]", "sending to %s", addr.String())
req, err := http.NewRequest("POST", addr.String(), &send)
if err != nil {
logger.Log("plusrom [net]", err.Error())
logger.Log(n.env, "plusrom [net]", err.Error())
return
}
@ -146,7 +146,7 @@ func (n *network) transmit() {
n.env.Prefs.PlusROM.Nick.String(),
)
req.Header.Set("PlusROM-Info", id)
logger.Logf("plusrom [net]", "PlusROM-Info: %s", id)
logger.Logf(n.env, "plusrom [net]", "PlusROM-Info: %s", id)
// -----------------------------------------------
// PlusCart firmware earlier han v2.1.1
@ -158,7 +158,7 @@ func (n *network) transmit() {
//
// id := fmt.Sprintf("%s WE%s", n.env.Prefs.PlusROM.Nick.String(), n.env.Prefs.PlusROM.ID.String())
// req.Header.Set("PlusStore-ID", id)
// logger.Logf("plusrom [net]", "PlusStore-ID: %s", id)
// logger.Logf(env, "plusrom [net]", "PlusStore-ID: %s", id)
// -----------------------------------------------
// whether to log HTTP transactions taken from the global preferences
@ -167,13 +167,13 @@ func (n *network) transmit() {
// log of complete request
if httpLogging {
s, _ := httputil.DumpRequest(req, true)
logger.Logf("plusrom [net]", "request: %q", s)
logger.Logf(n.env, "plusrom [net]", "request: %q", s)
}
// send response over network
resp, err := http.DefaultClient.Do(req)
if err != nil {
logger.Log("plusrom [net]", err.Error())
logger.Log(n.env, "plusrom [net]", err.Error())
return
}
defer resp.Body.Close()
@ -181,20 +181,20 @@ func (n *network) transmit() {
// log of complete response
if httpLogging {
s, _ := httputil.DumpResponse(resp, true)
logger.Logf("plusrom [net]", "response: %q", s)
logger.Logf(n.env, "plusrom [net]", "response: %q", s)
}
// pass response to main goroutine
var r bytes.Buffer
_, err = r.ReadFrom(resp.Body)
if err != nil {
logger.Logf("plusrom [net]", "response: %v", err)
logger.Logf(n.env, "plusrom [net]", "response: %v", err)
}
n.respChan <- r
}(sendBuffer, n.ai)
// log send buffer
logger.Log("plusrom [net] sent", fmt.Sprintf("% 02x", n.send.Buffer[:n.send.SendLen]))
logger.Log(n.env, "plusrom [net] sent", fmt.Sprintf("% 02x", n.send.Buffer[:n.send.SendLen]))
// a copy of the sendBuffer has been passed to the new goroutine so we
// can now clear the references buffer
@ -206,16 +206,16 @@ func (n *network) transmit() {
func (n *network) getResponse() {
select {
case r := <-n.respChan:
logger.Logf("plusrom [net]", "received %d bytes", r.Len())
logger.Logf(n.env, "plusrom [net]", "received %d bytes", r.Len())
l, err := r.ReadByte()
if err != nil {
logger.Log("plusrom", err.Error())
logger.Log(n.env, "plusrom", err.Error())
return
}
if int(l) != r.Len() {
logger.Log("plusrom [net]", "unexpected length received")
logger.Log(n.env, "plusrom [net]", "unexpected length received")
}
// from http://pluscart.firmaplus.de/pico/?PlusROM
@ -228,12 +228,12 @@ func (n *network) getResponse() {
// header of the response.
_, err = n.recvBuffer.ReadFrom(&r)
if err != nil {
logger.Log("plusrom", err.Error())
logger.Log(n.env, "plusrom", err.Error())
return
}
if n.recvBuffer.Len() > recvBufferCap {
logger.Log("plusrom", "receive buffer is full")
logger.Log(n.env, "plusrom", "receive buffer is full")
n.recvBuffer.Truncate(recvBufferCap)
}
@ -257,7 +257,7 @@ func (n *network) recv() uint8 {
b, err := n.recvBuffer.ReadByte()
if err != nil {
logger.Log("plusrom", err.Error())
logger.Log(n.env, "plusrom", err.Error())
}
return b
}

View file

@ -137,7 +137,7 @@ func NewPlusROM(env *environment.Environment, child mapper.CartMapper) (mapper.C
}
// log success
logger.Logf("plusrom", "will connect to %s", cart.net.ai.String())
logger.Logf(env, "plusrom", "will connect to %s", cart.net.ai.String())
if cart.env.Prefs.PlusROM.NewInstallation {
err := cart.env.Notifications.Notify(notifications.NotifyPlusROMNewInstall)

View file

@ -20,6 +20,7 @@ import (
"os"
"path/filepath"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/logger"
"github.com/jetsetilly/gopher2600/resources"
)
@ -39,7 +40,7 @@ const biosLogTag = "supercharger: bios"
// - current working directory
// - the same directory as the tape/bin file
// - the emulator's resource path
func loadBIOS(path string) ([]uint8, error) {
func loadBIOS(env *environment.Environment, path string) ([]uint8, error) {
// current working directory
for _, b := range biosFile {
d, err := _loadBIOS(b)
@ -52,7 +53,7 @@ func loadBIOS(path string) ([]uint8, error) {
return nil, fmt.Errorf("bios: file (%s) is not 2k", b)
}
logger.Logf(biosLogTag, "using %s (from current working directory)", b)
logger.Logf(env, biosLogTag, "using %s (from current working directory)", b)
return d, nil
}
@ -69,7 +70,7 @@ func loadBIOS(path string) ([]uint8, error) {
return nil, fmt.Errorf("bios: file (%s) is not 2k", p)
}
logger.Logf(biosLogTag, "using %s (from the same path as the game ROM)", p)
logger.Logf(env, biosLogTag, "using %s (from the same path as the game ROM)", p)
return d, nil
}
@ -90,7 +91,7 @@ func loadBIOS(path string) ([]uint8, error) {
return nil, fmt.Errorf("bios: file (%s) is not 2k", p)
}
logger.Logf(biosLogTag, "using %s (from the resource path)", p)
logger.Logf(env, biosLogTag, "using %s (from the resource path)", p)
return d, nil
}

View file

@ -20,6 +20,7 @@ import (
"io"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/cpu"
"github.com/jetsetilly/gopher2600/hardware/memory/vcs"
"github.com/jetsetilly/gopher2600/hardware/riot/timer"
@ -39,6 +40,7 @@ import (
// From: Eckhard Stolberg
// Date: Fri, 08 Jan 1999.
type FastLoad struct {
env *environment.Environment
cart *Supercharger
// fastload binaries have a header which controls how the binary is read
@ -83,12 +85,13 @@ type fastloadBlock struct {
}
// newFastLoad is the preferred method of initialisation for the FastLoad type.
func newFastLoad(cart *Supercharger, loader cartridgeloader.Loader) (tape, error) {
func newFastLoad(env *environment.Environment, cart *Supercharger, loader cartridgeloader.Loader) (tape, error) {
if loader.Size()%fastLoadBlockLen != 0 {
return nil, fmt.Errorf("fastload: wrong number of bytes in cartridge data")
}
fl := &FastLoad{
env: env,
cart: cart,
}
@ -112,13 +115,13 @@ func newFastLoad(cart *Supercharger, loader cartridgeloader.Loader) (tape, error
fl.blocks[i].progressSpeed = (uint16(gameHeader[7]) << 8) | uint16(gameHeader[6])
fl.blocks[i].pageTable = gameHeader[0x10:0x28]
logger.Logf("supercharger: fastload", "block %d: start address: %#04x", i, fl.blocks[i].startAddress)
logger.Logf("supercharger: fastload", "block %d: config byte: %#08b", i, fl.blocks[i].configByte)
logger.Logf("supercharger: fastload", "block %d: num pages: %d", i, fl.blocks[i].numPages)
logger.Logf("supercharger: fastload", "block %d: checksum: %#02x", i, fl.blocks[i].checksum)
logger.Logf("supercharger: fastload", "block %d: multiload: %#02x", i, fl.blocks[i].multiload)
logger.Logf("supercharger: fastload", "block %d: progress speed: %#02x", i, fl.blocks[i].progressSpeed)
logger.Logf("supercharger: fastload", "block %d: page-table: %v", i, fl.blocks[i].pageTable)
logger.Logf(fl.env, "supercharger: fastload", "block %d: start address: %#04x", i, fl.blocks[i].startAddress)
logger.Logf(fl.env, "supercharger: fastload", "block %d: config byte: %#08b", i, fl.blocks[i].configByte)
logger.Logf(fl.env, "supercharger: fastload", "block %d: num pages: %d", i, fl.blocks[i].numPages)
logger.Logf(fl.env, "supercharger: fastload", "block %d: checksum: %#02x", i, fl.blocks[i].checksum)
logger.Logf(fl.env, "supercharger: fastload", "block %d: multiload: %#02x", i, fl.blocks[i].multiload)
logger.Logf(fl.env, "supercharger: fastload", "block %d: progress speed: %#02x", i, fl.blocks[i].progressSpeed)
logger.Logf(fl.env, "supercharger: fastload", "block %d: page-table: %v", i, fl.blocks[i].pageTable)
}
@ -168,7 +171,7 @@ func (fl *FastLoad) Fastload(mc *cpu.CPU, ram *vcs.RAM, tmr *timer.Timer) error
fl.blockIdx = 0
}
if fl.blockIdx == startBlockIdx {
logger.Logf("supercharger: fastload", "cannot find multiload %d", m)
logger.Logf(fl.env, "supercharger: fastload", "cannot find multiload %d", m)
fl.blockIdx = 0
break // for loop
}
@ -176,7 +179,7 @@ func (fl *FastLoad) Fastload(mc *cpu.CPU, ram *vcs.RAM, tmr *timer.Timer) error
// log loading of multiload for non-zero multiload values
if m != 0 {
logger.Logf("supercharger: fastload", "loading multiload %d", fl.blocks[fl.blockIdx].multiload)
logger.Logf(fl.env, "supercharger: fastload", "loading multiload %d", fl.blocks[fl.blockIdx].multiload)
}
// copy data to RAM banks

View file

@ -20,6 +20,7 @@ import (
"math"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/memory/cartridge/mapper"
"github.com/jetsetilly/gopher2600/logger"
"github.com/jetsetilly/gopher2600/notifications"
@ -56,6 +57,7 @@ const soundloadLogTag = "supercharger: soundload"
// Compared to FastLoad this method is more 'authentic' and uses the BIOS
// correctly.
type SoundLoad struct {
env *environment.Environment
cart *Supercharger
// sound data and format information
@ -86,15 +88,16 @@ type SoundLoad struct {
}
// newSoundLoad is the preferred method of initialisation for the SoundLoad type.
func newSoundLoad(cart *Supercharger, loader cartridgeloader.Loader) (tape, error) {
func newSoundLoad(env *environment.Environment, cart *Supercharger, loader cartridgeloader.Loader) (tape, error) {
tap := &SoundLoad{
env: env,
cart: cart,
}
var err error
// get PCM data from data loaded from file
tap.pcm, err = getPCM(loader)
tap.pcm, err = getPCM(env, loader)
if err != nil {
return nil, fmt.Errorf("soundload: %w", err)
}
@ -105,13 +108,13 @@ func newSoundLoad(cart *Supercharger, loader cartridgeloader.Loader) (tape, erro
// the length of time of each sample in microseconds
timePerSample := 1000000.0 / tap.pcm.sampleRate
logger.Logf(soundloadLogTag, "time per sample: %.02fus", timePerSample)
logger.Logf(tap.env, soundloadLogTag, "time per sample: %.02fus", timePerSample)
// number of samples in a cycle for it to be interpreted as a zero or a one
// values taken from "Atari 2600 Mappers" document by Kevin Horton
logger.Log(soundloadLogTag, fmt.Sprintf("min/opt/max samples for zero-bit: %d/%d/%d",
logger.Log(tap.env, soundloadLogTag, fmt.Sprintf("min/opt/max samples for zero-bit: %d/%d/%d",
int(158.0/timePerSample), int(227.0/timePerSample), int(317.0/timePerSample)))
logger.Log(soundloadLogTag, fmt.Sprintf("min/opt/max samples for one-bit: %d/%d/%d",
logger.Log(tap.env, soundloadLogTag, fmt.Sprintf("min/opt/max samples for one-bit: %d/%d/%d",
int(317.0/timePerSample), int(340.0/timePerSample), int(2450.0/timePerSample)))
// calculate tape regulator speed. 1190000 is the frequency at which step() is called (1.19MHz)
@ -120,7 +123,7 @@ func newSoundLoad(cart *Supercharger, loader cartridgeloader.Loader) (tape, erro
// different but it doesn't appear to have any effect on loading success so
// we won't complicate the code by allowing the regulator to change
tap.regulator = int(math.Round(1190000.0 / tap.pcm.sampleRate))
logger.Logf(soundloadLogTag, "tape regulator: %d", tap.regulator)
logger.Logf(tap.env, soundloadLogTag, "tape regulator: %d", tap.regulator)
// threshold value is the average value in the PCM data
var total float32
@ -152,7 +155,7 @@ func (tap *SoundLoad) load() (uint8, error) {
tap.cart.env.Notifications.Notify(notifications.NotifySuperchargerSoundloadStarted)
tap.playing = true
tap.playDelay = 0
logger.Log(soundloadLogTag, "tape playing")
logger.Log(tap.env, soundloadLogTag, "tape playing")
}
if tap.pcm.data[tap.idx] > tap.threshold {
@ -202,7 +205,7 @@ func (tap *SoundLoad) Rewind() {
// rewinding happens instantaneously
tap.cart.env.Notifications.Notify(notifications.NotifySuperchargerSoundloadRewind)
tap.idx = 0
logger.Log(soundloadLogTag, "tape rewound")
logger.Log(tap.env, soundloadLogTag, "tape rewound")
tap.stepLimiter = 0
}

View file

@ -25,6 +25,7 @@ import (
"github.com/hajimehoshi/go-mp3"
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/logger"
)
@ -37,7 +38,7 @@ type pcmData struct {
data []float32
}
func getPCM(cl cartridgeloader.Loader) (pcmData, error) {
func getPCM(env *environment.Environment, cl cartridgeloader.Loader) (pcmData, error) {
p := pcmData{
data: make([]float32, 0),
}
@ -53,7 +54,7 @@ func getPCM(cl cartridgeloader.Loader) (pcmData, error) {
return p, fmt.Errorf("wav: not a valid wav file")
}
logger.Log(soundloadLogTag, "loading from wav file")
logger.Log(env, soundloadLogTag, "loading from wav file")
// load all data at once
buf, err := dec.FullPCMBuffer()
@ -84,7 +85,7 @@ func getPCM(cl cartridgeloader.Loader) (pcmData, error) {
return p, fmt.Errorf("mp3: %w", err)
}
logger.Log(soundloadLogTag, "loading from mp3 file")
logger.Log(env, soundloadLogTag, "loading from mp3 file")
err = nil
chunk := make([]byte, 4096)
@ -125,8 +126,8 @@ func getPCM(cl cartridgeloader.Loader) (pcmData, error) {
p.totalTime = float64(len(p.data)) / p.sampleRate
}
logger.Logf(soundloadLogTag, "sample rate: %0.2fHz", p.sampleRate)
logger.Logf(soundloadLogTag, "total time: %.02fs", p.totalTime)
logger.Logf(env, soundloadLogTag, "sample rate: %0.2fHz", p.sampleRate)
logger.Logf(env, soundloadLogTag, "total time: %.02fs", p.totalTime)
return p, nil
}

View file

@ -72,16 +72,16 @@ func NewSupercharger(env *environment.Environment, cartload cartridgeloader.Load
var err error
// load bios and activate
cart.bios, err = loadBIOS(filepath.Dir(cartload.Filename))
cart.bios, err = loadBIOS(env, filepath.Dir(cartload.Filename))
if err != nil {
return nil, fmt.Errorf("supercharger: %w", err)
}
// set up tape
if cartload.IsSoundData {
cart.state.tape, err = newSoundLoad(cart, cartload)
cart.state.tape, err = newSoundLoad(env, cart, cartload)
} else {
cart.state.tape, err = newFastLoad(cart, cartload)
cart.state.tape, err = newFastLoad(env, cart, cartload)
}
if err != nil {
return nil, fmt.Errorf("supercharger: %w", err)

View file

@ -106,7 +106,7 @@ func NewAtariVox(env *environment.Environment, port plugging.PortID, bus ports.P
}
vox.activateFestival()
logger.Logf("atarivox", "attached [%v]", vox.port)
logger.Logf(env, "atarivox", "attached [%v]", vox.port)
// attach savekey to same port
vox.SaveKey = savekey.NewSaveKey(env, port, bus)
@ -127,9 +127,9 @@ func (vox *AtariVox) activateFestival() {
if vox.env.Prefs.AtariVox.FestivalEnabled.Get().(bool) {
var err error
vox.Engine, err = atarivoxengines.NewFestival(vox.env.Prefs.AtariVox.FestivalBinary.Get().(string))
vox.Engine, err = atarivoxengines.NewFestival(vox.env)
if err != nil {
logger.Logf("atarivox", err.Error())
logger.Logf(vox.env, "atarivox", err.Error())
}
}
}
@ -294,7 +294,7 @@ func (vox *AtariVox) Step() {
if vox.SpeakJetDATA.Lo() {
vox.State = AtariVoxData
} else {
logger.Log("atarivox", "unexpected start bit of 1. should be 0")
logger.Log(vox.env, "atarivox", "unexpected start bit of 1. should be 0")
vox.State = AtariVoxStopped
}
case AtariVoxData:
@ -308,7 +308,7 @@ func (vox *AtariVox) Step() {
vox.Engine.SpeakJet(vox.Bits)
}
} else {
logger.Log("atarivox", "unexpected end bit of 0. should be 1")
logger.Log(vox.env, "atarivox", "unexpected end bit of 0. should be 1")
vox.State = AtariVoxStopped
}
}

View file

@ -21,6 +21,7 @@ import (
"os/exec"
"strings"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/logger"
)
@ -34,15 +35,18 @@ const (
)
type phonemes struct {
env *environment.Environment
strings.Builder
}
func (p *phonemes) WriteString(s string) (int, error) {
logger.Logf("festival", "phoneme: %s", s)
logger.Logf(p.env, "festival", "phoneme: %s", s)
return p.Builder.WriteString(s)
}
type festival struct {
env *environment.Environment
stdin io.WriteCloser
stdout io.ReadCloser
@ -61,13 +65,18 @@ type festival struct {
// NewFestival creats a new festival instance and starts a new festival process
// which we'll communicate with via a stdin pipe.
func NewFestival(executablePath string) (AtariVoxEngine, error) {
func NewFestival(env *environment.Environment) (AtariVoxEngine, error) {
fest := &festival{
env: env,
phonemes: phonemes{
env: env,
},
quit: make(chan bool, 1),
say: make(chan string, 1),
cmd: make(chan string, 1),
}
executablePath := env.Prefs.AtariVox.FestivalBinary.Get().(string)
cmd := exec.Command(executablePath)
var err error
@ -88,19 +97,18 @@ func NewFestival(executablePath string) (AtariVoxEngine, error) {
}
go func() {
for {
select {
case <-fest.quit:
err = cmd.Process.Kill()
if err != nil {
logger.Logf("festival", err.Error())
logger.Logf(fest.env, "festival", err.Error())
}
_ = cmd.Wait()
return
case text := <-fest.say:
logger.Logf("festival", "say: %s", text)
logger.Logf(fest.env, "festival", "say: %s", text)
sayphones := fmt.Sprintf("(SayPhones '(%s))", text)
fest.stdin.Write([]byte(sayphones))
@ -145,68 +153,68 @@ func (fest *festival) SpeakJet(b uint8) {
return
case speed:
fest.speed = b
logger.Logf("festival", "speed: %d", fest.speed)
logger.Logf(fest.env, "festival", "speed: %d", fest.speed)
fest.cmd <- fmt.Sprintf("(set! FP_duration %d)", fest.speed)
fest.nextSpeakJetByte = none
return
case pitch:
fest.pitch = b
logger.Logf("festival", "pitch: %d", fest.pitch)
logger.Logf(fest.env, "festival", "pitch: %d", fest.pitch)
fest.cmd <- fmt.Sprintf("(set! FP_F0 %d)", fest.pitch)
fest.nextSpeakJetByte = none
return
}
if b >= 215 && b <= 254 {
logger.Logf("festival", "sound effect: %d", b)
logger.Logf(fest.env, "festival", "sound effect: %d", b)
return
}
switch b {
default:
logger.Logf("festival", "unsupported byte (%d)", b)
logger.Logf(fest.env, "festival", "unsupported byte (%d)", b)
return
case 31: // Reset
logger.Logf("festival", "reset")
logger.Logf(fest.env, "festival", "reset")
fest.reset()
return
case 0: // pause 0ms
return
case 1: // pause 100ms
logger.Logf("festival", "pause: 100ms: not implemented")
logger.Logf(fest.env, "festival", "pause: 100ms: not implemented")
return
case 2: // pause 200ms
logger.Logf("festival", "pause: 200ms: not implemented")
logger.Logf(fest.env, "festival", "pause: 200ms: not implemented")
return
case 3: // pause 700ms
logger.Logf("festival", "pause: 700ms: not implemented")
logger.Logf(fest.env, "festival", "pause: 700ms: not implemented")
return
case 4: // pause 30ms
logger.Logf("festival", "pause: 30ms: not implemented")
logger.Logf(fest.env, "festival", "pause: 30ms: not implemented")
return
case 5: // pause 60ms
logger.Logf("festival", "pause: 60ms: not implemented")
logger.Logf(fest.env, "festival", "pause: 60ms: not implemented")
return
case 6: // pause 90ms
logger.Logf("festival", "pause: 90ms: not implemented")
logger.Logf(fest.env, "festival", "pause: 90ms: not implemented")
return
case 7: // Fast
logger.Logf("festival", "fast: not implemented")
logger.Logf(fest.env, "festival", "fast: not implemented")
return
case 8: // Slow
logger.Logf("festival", "slow: not implemented")
logger.Logf(fest.env, "festival", "slow: not implemented")
return
case 14: // Stress
logger.Logf("festival", "stress: not implemented")
logger.Logf(fest.env, "festival", "stress: not implemented")
return
case 15: // Relax
logger.Logf("festival", "relax: not implemented")
logger.Logf(fest.env, "festival", "relax: not implemented")
return
case 20: // volume
logger.Logf("festival", "volume: not implemented")
logger.Logf(fest.env, "festival", "volume: not implemented")
fest.nextSpeakJetByte = unsupported
return
case 21: // speed
@ -218,30 +226,30 @@ func (fest *festival) SpeakJet(b uint8) {
fest.nextSpeakJetByte = pitch
return
case 23: // bend
logger.Logf("festival", "bend: not implemented")
logger.Logf(fest.env, "festival", "bend: not implemented")
return
case 24: // PortCtr
logger.Logf("festival", "port ctr: not implemented")
logger.Logf(fest.env, "festival", "port ctr: not implemented")
fest.nextSpeakJetByte = unsupported
return
case 25: // Port
logger.Logf("festival", "port: not implemented")
logger.Logf(fest.env, "festival", "port: not implemented")
fest.nextSpeakJetByte = unsupported
return
case 26: // Repeat
logger.Logf("festival", "repeat: not implemented")
logger.Logf(fest.env, "festival", "repeat: not implemented")
fest.nextSpeakJetByte = unsupported
return
case 28: // Call Phrase
logger.Logf("festival", "call phrase: not implemented")
logger.Logf(fest.env, "festival", "call phrase: not implemented")
fest.nextSpeakJetByte = unsupported
return
case 29: // Goto Phrase
logger.Logf("festival", "goto phrase: not implemented")
logger.Logf(fest.env, "festival", "goto phrase: not implemented")
fest.nextSpeakJetByte = unsupported
return
case 30: // Delay
logger.Logf("festival", "delay: not implemented")
logger.Logf(fest.env, "festival", "delay: not implemented")
fest.nextSpeakJetByte = unsupported
return

View file

@ -18,6 +18,7 @@ package savekey
import (
"os"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/logger"
"github.com/jetsetilly/gopher2600/resources"
)
@ -28,6 +29,8 @@ const eepromSize = 65536
// EEPROM represents the non-volatile memory in the SaveKey peripheral.
type EEPROM struct {
env *environment.Environment
// the next address an i2c read/write operation will access
Address uint16
@ -41,8 +44,9 @@ type EEPROM struct {
// NewEeprom is the preferred metho of initialisation for the EEPROM type. This
// function will initialise the memory and Read() any existing data from disk.
func newEeprom() *EEPROM {
func newEeprom(env *environment.Environment) *EEPROM {
ee := &EEPROM{
env: env,
Data: make([]uint8, eepromSize),
DiskData: make([]uint8, eepromSize),
}
@ -71,13 +75,13 @@ func (ee *EEPROM) snapshot() *EEPROM {
func (ee *EEPROM) Read() {
fn, err := resources.JoinPath(saveKeyPath)
if err != nil {
logger.Logf("savekey", "could not load eeprom file (%s)", err)
logger.Logf(ee.env, "savekey", "could not load eeprom file (%s)", err)
return
}
f, err := os.Open(fn)
if err != nil {
logger.Logf("savekey", "could not load eeprom file (%s)", err)
logger.Logf(ee.env, "savekey", "could not load eeprom file (%s)", err)
return
}
defer f.Close()
@ -86,57 +90,57 @@ func (ee *EEPROM) Read() {
// windows version (when running under wine) does not handle that
fs, err := os.Stat(fn)
if err != nil {
logger.Logf("savekey", "could not load eeprom file (%s)", err)
logger.Logf(ee.env, "savekey", "could not load eeprom file (%s)", err)
return
}
if fs.Size() != int64(len(ee.Data)) {
logger.Logf("savekey", "eeprom file is of incorrect length. %d should be 65536 ", fs.Size())
logger.Logf(ee.env, "savekey", "eeprom file is of incorrect length. %d should be 65536 ", fs.Size())
}
_, err = f.Read(ee.Data)
if err != nil {
logger.Logf("savekey", "could not load eeprom file (%s)", err)
logger.Logf(ee.env, "savekey", "could not load eeprom file (%s)", err)
return
}
// copy of data read from disk
copy(ee.DiskData, ee.Data)
logger.Logf("savekey", "eeprom file loaded from %s", fn)
logger.Logf(ee.env, "savekey", "eeprom file loaded from %s", fn)
}
// Write EEPROM data to disk.
func (ee *EEPROM) Write() {
fn, err := resources.JoinPath(saveKeyPath)
if err != nil {
logger.Logf("savekey", "could not write eeprom file (%s)", err)
logger.Logf(ee.env, "savekey", "could not write eeprom file (%s)", err)
return
}
f, err := os.Create(fn)
if err != nil {
logger.Logf("savekey", "could not write eeprom file (%s)", err)
logger.Logf(ee.env, "savekey", "could not write eeprom file (%s)", err)
return
}
defer func() {
err := f.Close()
if err != nil {
logger.Logf("savekey", "could not close eeprom file (%s)", err)
logger.Logf(ee.env, "savekey", "could not close eeprom file (%s)", err)
}
}()
n, err := f.Write(ee.Data)
if err != nil {
logger.Logf("savekey", "could not write eeprom file (%s)", err)
logger.Logf(ee.env, "savekey", "could not write eeprom file (%s)", err)
return
}
if n != len(ee.Data) {
logger.Logf("savekey", "eeprom file has not been truncated during write. %d should be 65536", n)
logger.Logf(ee.env, "savekey", "eeprom file has not been truncated during write. %d should be 65536", n)
return
}
logger.Logf("savekey", "eeprom file saved to %s", fn)
logger.Logf(ee.env, "savekey", "eeprom file saved to %s", fn)
// copy of data that's just bee written to disk
copy(ee.DiskData, ee.Data)

View file

@ -52,6 +52,8 @@ const (
// SaveKey represents the SaveKey peripheral. It implements the Peripheral
// interface.
type SaveKey struct {
env *environment.Environment
port plugging.PortID
bus ports.PeripheralBus
@ -96,16 +98,17 @@ func NewSaveKey(env *environment.Environment, port plugging.PortID, bus ports.Pe
}
sk := &SaveKey{
env: env,
port: port,
bus: bus,
SDA: i2c.NewTrace(),
SCL: i2c.NewTrace(),
State: SaveKeyStopped,
EEPROM: newEeprom(),
EEPROM: newEeprom(env),
}
sk.bus.WriteSWCHx(sk.port, 0xf0)
logger.Logf("savekey", "attached [%v]", sk.port)
logger.Logf(sk.env, "savekey", "attached [%v]", sk.port)
return sk
}
@ -254,7 +257,7 @@ func (sk *SaveKey) Step() {
// check for stop signal before anything else
if sk.State != SaveKeyStopped && sk.SCL.Hi() && sk.SDA.Rising() {
logger.Log("savekey", "stopped message")
logger.Log(sk.env, "savekey", "stopped message")
sk.State = SaveKeyStopped
sk.EEPROM.Write()
return
@ -281,7 +284,7 @@ func (sk *SaveKey) Step() {
switch sk.State {
case SaveKeyStopped:
if sk.SDA.Lo() {
logger.Log("savekey", "starting message")
logger.Log(sk.env, "savekey", "starting message")
sk.resetBits()
sk.State = SaveKeyStarting
}
@ -290,18 +293,18 @@ func (sk *SaveKey) Step() {
if sk.recvBit(sk.SDA.Falling()) {
switch sk.Bits {
case readSig:
logger.Log("savekey", "reading message")
logger.Log(sk.env, "savekey", "reading message")
sk.resetBits()
sk.State = SaveKeyData
sk.Dir = Reading
sk.Ack = true
case writeSig:
logger.Log("savekey", "writing message")
logger.Log(sk.env, "savekey", "writing message")
sk.State = SaveKeyAddressHi
sk.Dir = Writing
sk.Ack = true
default:
logger.Log("savekey", "unrecognised message")
logger.Log(sk.env, "savekey", "unrecognised message")
sk.State = SaveKeyStopped
}
}
@ -321,9 +324,9 @@ func (sk *SaveKey) Step() {
switch sk.Dir {
case Reading:
logger.Logf("savekey", "reading from address %#04x", sk.EEPROM.Address)
logger.Logf(sk.env, "savekey", "reading from address %#04x", sk.EEPROM.Address)
case Writing:
logger.Logf("savekey", "writing to address %#04x", sk.EEPROM.Address)
logger.Logf(sk.env, "savekey", "writing to address %#04x", sk.EEPROM.Address)
}
}
@ -340,9 +343,9 @@ func (sk *SaveKey) Step() {
if end {
if unicode.IsPrint(rune(sk.Bits)) {
logger.Logf("savekey", "read byte %#02x [%c]", sk.Bits, sk.Bits)
logger.Logf(sk.env, "savekey", "read byte %#02x [%c]", sk.Bits, sk.Bits)
} else {
logger.Logf("savekey", "read byte %#02x", sk.Bits)
logger.Logf(sk.env, "savekey", "read byte %#02x", sk.Bits)
}
sk.Ack = true
}
@ -350,9 +353,9 @@ func (sk *SaveKey) Step() {
case Writing:
if sk.recvBit(sk.SDA.Falling()) {
if unicode.IsPrint(rune(sk.Bits)) {
logger.Logf("savekey", "written byte %#02x [%c]", sk.Bits, sk.Bits)
logger.Logf(sk.env, "savekey", "written byte %#02x [%c]", sk.Bits, sk.Bits)
} else {
logger.Logf("savekey", "written byte %#02x", sk.Bits)
logger.Logf(sk.env, "savekey", "written byte %#02x", sk.Bits)
}
sk.EEPROM.put(sk.Bits)
sk.Ack = true

View file

@ -90,7 +90,8 @@ func newPlusROMpreferences() (*PlusROMPreferences, error) {
}
if !p.validateID() {
logger.Log("plusrom preferences", "existing ID invalid. generating new ID and saving")
// using logger.Allow because we don't mind a non-main emulation creating this log entry.
logger.Log(logger.Allow, "plusrom preferences", "existing ID invalid. generating new ID and saving")
err = p.ID.Set(p.generateID())
if err != nil {

View file

@ -73,7 +73,7 @@ func (riot *RIOT) Step(reg chipbus.ChangedRegister) {
if update {
update = riot.Ports.Update(reg)
if update {
logger.Logf("riot", "memory altered to no affect (%04x=%02x)", reg.Address, reg.Value)
logger.Logf(riot.env, "riot", "memory altered to no affect (%04x=%02x)", reg.Address, reg.Value)
}
}

View file

@ -20,6 +20,7 @@ import (
"strings"
"github.com/jetsetilly/gopher2600/debugger/govern"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware/television/coords"
"github.com/jetsetilly/gopher2600/hardware/television/signal"
"github.com/jetsetilly/gopher2600/hardware/television/specification"
@ -124,6 +125,8 @@ func (s *State) GetCoords() coords.TelevisionCoords {
// Television is a Television implementation of the Television interface. In all
// honesty, it's most likely the only implementation required.
type Television struct {
env *environment.Environment
// vcs will be nil unless AttachVCS() has been called
vcs VCSReturnChannel
@ -288,7 +291,8 @@ func (tv *Television) Plumb(vcs VCSReturnChannel, state *State) {
}
// AttachVCS attaches an implementation of the VCSReturnChannel.
func (tv *Television) AttachVCS(vcs VCSReturnChannel) {
func (tv *Television) AttachVCS(env *environment.Environment, vcs VCSReturnChannel) {
tv.env = env
tv.vcs = vcs
// notify the newly attached console of the current TV spec
@ -472,7 +476,7 @@ func (tv *Television) Signal(sig signal.SignalAttributes) {
if !tv.state.vsyncActive {
err := tv.newFrame(false)
if err != nil {
logger.Log("TV", err.Error())
logger.Log(tv.env, "TV", err.Error())
}
} else {
tv.state.scanline = specification.AbsoluteMaxScanlines - 1
@ -481,7 +485,7 @@ func (tv *Television) Signal(sig signal.SignalAttributes) {
// if we're not at end of screen then indicate new scanline
err := tv.newScanline()
if err != nil {
logger.Log("TV", err.Error())
logger.Log(tv.env, "TV", err.Error())
}
}
}
@ -529,7 +533,7 @@ func (tv *Television) Signal(sig signal.SignalAttributes) {
} else {
err := tv.newFrame(true)
if err != nil {
logger.Log("TV", err.Error())
logger.Log(tv.env, "TV", err.Error())
}
}
}
@ -585,7 +589,7 @@ func (tv *Television) Signal(sig signal.SignalAttributes) {
if tv.currentSignalIdx >= len(tv.signals) {
err := tv.renderSignals()
if err != nil {
logger.Log("TV", err.Error())
logger.Log(tv.env, "TV", err.Error())
}
}
}

View file

@ -601,7 +601,7 @@ func (tia *TIA) Step(reg chipbus.ChangedRegister, ct int) {
if tia.env.Prefs.Revision.Live.LateCOLUPF.Load().(bool) {
update = tia.Video.UpdatePlayfieldColor(reg)
if update {
logger.Logf("tia", "memory altered to no affect (%04x=%02x)", reg.Address, reg.Value)
logger.Logf(tia.env, "tia", "memory altered to no affect (%04x=%02x)", reg.Address, reg.Value)
}
}
}

View file

@ -143,8 +143,6 @@ func (bs *BallSprite) String() string {
s.WriteString("]")
}
notes := false
if int(bs.Size) > len(ballSizesBrief) {
panic("illegal size value for ball")
}
@ -153,37 +151,25 @@ func (bs *BallSprite) String() string {
s.WriteString(" ")
}
s.Write([]byte(sz))
s.WriteString(",")
if bs.MoreHMOVE {
s.WriteString(" hmoving")
s.WriteString(fmt.Sprintf(" [%04b]", bs.Hmove))
notes = true
s.WriteString(fmt.Sprintf(" hmoving [%04b],", bs.Hmove))
}
if bs.Enclockifier.Active {
// add a comma if we've already noted something else
if notes {
s.WriteString(",")
}
s.WriteString(fmt.Sprintf(" drw %s", bs.Enclockifier.String()))
notes = true
s.WriteString(fmt.Sprintf(" drw %s,", bs.Enclockifier.String()))
}
if !bs.Enabled {
if notes {
s.WriteString(",")
}
s.WriteString(" disb")
notes = true
s.WriteString(" disb,")
}
if bs.VerticalDelay {
if notes {
s.WriteString(",")
}
s.WriteString(" vdel")
s.WriteString(" vdel,")
}
return s.String()
return strings.TrimSuffix(s.String(), ",")
}
func (bs *BallSprite) rsync(adjustment int) {

View file

@ -180,39 +180,23 @@ func (ms *MissileSprite) String() string {
panic("illegal size value for missile")
}
notes := false
if ms.MoreHMOVE {
s.WriteString(" hmoving")
s.WriteString(fmt.Sprintf(" [%04b]", ms.Hmove))
notes = true
s.WriteString(fmt.Sprintf(" hmoving [%04b],", ms.Hmove))
}
if ms.Enclockifier.Active {
// add a comma if we've already noted something else
if notes {
s.WriteString(",")
}
s.WriteString(fmt.Sprintf(" drw %s", ms.Enclockifier.String()))
notes = true
s.WriteString(fmt.Sprintf(" drw %s,", ms.Enclockifier.String()))
}
if !ms.Enabled {
if notes {
s.WriteString(",")
}
s.WriteString(" disb")
notes = true
s.WriteString(" disb,")
}
if ms.ResetToPlayer {
if notes {
s.WriteString(",")
}
s.WriteString(" >pl<")
s.WriteString(" >pl<,")
}
return s.String()
return strings.TrimSuffix(s.String(), ",")
}
func (ms *MissileSprite) rsync(adjustment int) {

View file

@ -188,56 +188,43 @@ func (ps *PlayerSprite) String() string {
s.WriteString(fmt.Sprintf("> %#1x >", normalisedHmove))
s.WriteString(fmt.Sprintf(" %03d", ps.HmovedPixel))
if ps.MoreHMOVE {
s.WriteString("*] ")
s.WriteString("*]")
} else {
s.WriteString("] ")
s.WriteString("]")
}
// add a note to indicate that the nusiz value is about to update
if ps.ScanCounter.IsActive() && ps.SizeAndCopies != ps.ScanCounter.LatchedSizeAndCopies {
s.WriteString("*")
s.WriteString(" *")
}
// nusiz info
s.WriteString(" ")
if int(ps.SizeAndCopies) > len(playerSizesBrief) {
panic("illegal size value for player")
}
sz := playerSizesBrief[ps.SizeAndCopies]
if len(sz) > 0 {
s.WriteString(" ")
playerSize := playerSizesBrief[ps.SizeAndCopies]
if playerSize != "" {
s.WriteString(fmt.Sprintf(" %s", playerSize))
}
s.Write([]byte(sz))
// notes
notes := false
// hmove information
if ps.MoreHMOVE {
s.WriteString(" hmoving")
s.WriteString(fmt.Sprintf(" [%04b]", ps.Hmove))
notes = true
s.WriteString(fmt.Sprintf(" hmoving [%04b],", ps.Hmove))
}
// drawing or latching information
if ps.ScanCounter.IsActive() {
if notes {
s.WriteString(",")
}
s.WriteString(fmt.Sprintf(" drw (px %d", ps.ScanCounter.Pixel))
// add "sub-pixel" information
// add "sub-pixel" information. this happens when the player sprite is
// being stretched by NUSIZ
if ps.ScanCounter.count > 0 {
s.WriteString(fmt.Sprintf(".%d", ps.ScanCounter.count))
}
s.WriteString(")")
notes = true
s.WriteString("),")
} else if ps.ScanCounter.IsLatching() {
if notes {
s.WriteString(",")
}
s.WriteString(fmt.Sprintf(" latch (drw in %d)", ps.ScanCounter.latch))
s.WriteString(fmt.Sprintf(" latch (drw in %d),", ps.ScanCounter.latch))
}
// copy information if drawing or latching and nusiz is a multiple copy
@ -247,31 +234,22 @@ func (ps *PlayerSprite) String() string {
switch ps.ScanCounter.Cpy {
case 0:
case 1:
s.WriteString(" 2nd")
s.WriteString(" 2nd,")
case 2:
s.WriteString(" 3rd")
s.WriteString(" 3rd,")
default:
panic("more than 2 copies of player!?")
}
}
// additional notes
if ps.VerticalDelay {
if notes {
s.WriteString(",")
}
s.WriteString(" vdel")
notes = true
s.WriteString(" vdel,")
}
if ps.Reflected {
if notes {
s.WriteString(",")
}
s.WriteString(" ref")
s.WriteString(" ref,")
}
return s.String()
return strings.TrimSuffix(s.String(), ",")
}
func (ps *PlayerSprite) rsync(adjustment int) {

View file

@ -78,11 +78,14 @@ type VCS struct {
// NewVCS creates a new VCS and everything associated with the hardware. It is
// used for all aspects of emulation: debugging sessions, and regular play.
//
// The Label argument indicates which environment the emulation will be
// happening in. This affects how log entries are handled, amonst other things
//
// The Television argument should not be nil. The Notify and Preferences
// argument may be nil if required.
func NewVCS(tv *television.Television, notify notifications.Notify, prefs *preferences.Preferences) (*VCS, error) {
func NewVCS(label environment.Label, tv *television.Television, notify notifications.Notify, prefs *preferences.Preferences) (*VCS, error) {
// set up environment
env, err := environment.NewEnvironment(tv, notify, prefs)
env, err := environment.NewEnvironment(label, tv, notify, prefs)
if err != nil {
return nil, err
}
@ -120,7 +123,7 @@ func NewVCS(tv *television.Television, notify notifications.Notify, prefs *prefe
return nil, err
}
vcs.TV.AttachVCS(vcs)
vcs.TV.AttachVCS(env, vcs)
return vcs, nil
}
@ -245,25 +248,25 @@ func (vcs *VCS) SetClockSpeed(spec specification.Spec) {
case specification.SpecNTSC.ID:
if vcs.Clock != ntscClock {
vcs.Clock = ntscClock
logger.Log("vcs", "switching to NTSC clock")
logger.Log(vcs.Env, "vcs", "switching to NTSC clock")
}
case specification.SpecPAL.ID:
if vcs.Clock != palClock {
vcs.Clock = palClock
logger.Log("vcs", "switching to PAL clock")
logger.Log(vcs.Env, "vcs", "switching to PAL clock")
}
case specification.SpecPALM.ID:
if vcs.Clock != palMClock {
vcs.Clock = palMClock
logger.Log("vcs", "switching to PAL-M clock")
logger.Log(vcs.Env, "vcs", "switching to PAL-M clock")
}
case specification.SpecSECAM.ID:
if vcs.Clock != secamClock {
vcs.Clock = secamClock
logger.Log("vcs", "switching to SECAM clock")
logger.Log(vcs.Env, "vcs", "switching to SECAM clock")
}
default:
logger.Logf("vcs", "cannot set clock for unknown TV specification (%s)", spec.ID)
logger.Logf(vcs.Env, "vcs", "cannot set clock for unknown TV specification (%s)", spec.ID)
}
}

View file

@ -19,6 +19,21 @@ import (
"io"
)
// Permission implementatins indicate whether the environment making a log
// request is allowed to create new log entries
type Permission interface {
AllowLogging() bool
}
type allow struct{}
func (_ allow) AllowLogging() bool {
return true
}
// Allow indicates that the logging request should be allowed
var Allow Permission = allow{}
// only allowing one central log for the entire application. there's no need to
// allow more than one log.
var central *logger
@ -30,14 +45,18 @@ func init() {
central = newLogger(maxCentral)
}
// Log adds an entry to the central logger.
func Log(tag, detail string) {
central.log(tag, detail)
// Log adds an entry to the central logger
func Log(perm Permission, tag, detail string) {
if perm == Allow || perm.AllowLogging() {
central.log(tag, detail)
}
}
// Logf adds a formatted entry to the central logger.
func Logf(tag, detail string, args ...interface{}) {
central.logf(tag, detail, args...)
// Logf adds a formatted entry to the central logger
func Logf(perm Permission, tag, detail string, args ...interface{}) {
if perm == Allow || perm.AllowLogging() {
central.logf(tag, detail, args...)
}
}
// Clear all entries from central logger.

View file

@ -15,10 +15,16 @@
// Package logger is the central log repository for gopher2600. There is a
// single log for the entire application and can be accessed through the
// package level functions, principally Log().
// package level functions.
//
// Log entries can be grouped together with the tag argument in the Log()
// command.
// New log entries are made with the package level Log() and Logf() functions.
// Both these functions require an implementation of the Permission interface.
// This interface tests whether the environment making the logging request is
// allowed to make new log entries.
//
// The environment.Environment type satisfies the Permission interface. If it's
// not convenient to provide an instance of that type then logging.Allow can be
// used to provide blanket permission to the caller.
//
// The Colorizer type can be used with SetEcho() to output a simply coloured
// log entries (using ANSI control codes).

View file

@ -29,7 +29,7 @@ func TestLogger(t *testing.T) {
logger.Write(tw)
test.ExpectEquality(t, tw.Compare(""), true)
logger.Log("test", "this is a test")
logger.Log(logger.Allow, "test", "this is a test")
logger.Write(tw)
test.ExpectEquality(t, tw.Compare("test: this is a test\n"), true)
@ -37,7 +37,7 @@ func TestLogger(t *testing.T) {
// to manage
tw.Clear()
logger.Log("test2", "this is another test")
logger.Log(logger.Allow, "test2", "this is another test")
logger.Write(tw)
test.ExpectEquality(t, tw.Compare("test: this is a test\ntest2: this is another test\n"), true)

View file

@ -166,7 +166,7 @@ func (mcr *Macro) Run() {
}
func (mcr *Macro) run() {
logger.Logf("macro", "running %s", mcr.filename)
logger.Logf(logger.Allow, "macro", "running %s", mcr.filename)
// quit instructs the main script loop to end
var quit bool
@ -212,7 +212,7 @@ func (mcr *Macro) run() {
for ln := 0; ln < len(mcr.instructions) && !quit; ln++ {
logf := func(msg string, args ...any) {
logger.Logf("macro", "%s: %d: %s", mcr.filename, ln+headerNumLines, fmt.Sprintf(msg, args...))
logger.Logf(logger.Allow, "macro", "%s: %d: %s", mcr.filename, ln+headerNumLines, fmt.Sprintf(msg, args...))
}
// convert argument to number
@ -498,7 +498,7 @@ func (mcr *Macro) run() {
}
}
logger.Logf("macro", "finished %s", mcr.filename)
logger.Logf(logger.Allow, "macro", "finished %s", mcr.filename)
}
// Quit forces a running macro (ie. one that has been triggered) to end. Does

View file

@ -23,6 +23,7 @@ import (
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/debugger/govern"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/television"
"github.com/jetsetilly/gopher2600/setup"
@ -49,7 +50,7 @@ func Check(output io.Writer, profile Profile, cartload cartridgeloader.Loader, s
tv.SetFPSCap(!uncapped)
// create vcs
vcs, err := hardware.NewVCS(tv, nil, nil)
vcs, err := hardware.NewVCS(environment.MainEmulation, tv, nil, nil)
if err != nil {
return fmt.Errorf("performance: %w", err)
}

View file

@ -49,7 +49,7 @@ func RunProfiler(profile Profile, filenameHeader string, run func() error) error
defer func() {
err := f.Close()
if err != nil {
logger.Logf("performance", err.Error())
logger.Logf(logger.Allow, "performance", err.Error())
}
}()
@ -68,7 +68,7 @@ func RunProfiler(profile Profile, filenameHeader string, run func() error) error
defer func() {
err := f.Close()
if err != nil {
logger.Logf("performance", err.Error())
logger.Logf(logger.Allow, "performance", err.Error())
}
}()
@ -76,7 +76,7 @@ func RunProfiler(profile Profile, filenameHeader string, run func() error) error
runtime.GC()
err = pprof.WriteHeapProfile(f)
if err != nil {
logger.Logf("performance", err.Error())
logger.Logf(logger.Allow, "performance", err.Error())
}
}()
}
@ -89,7 +89,7 @@ func RunProfiler(profile Profile, filenameHeader string, run func() error) error
defer func() {
err := f.Close()
if err != nil {
logger.Logf("performance", err.Error())
logger.Logf(logger.Allow, "performance", err.Error())
}
}()
@ -108,7 +108,7 @@ func RunProfiler(profile Profile, filenameHeader string, run func() error) error
defer func() {
err := f.Close()
if err != nil {
logger.Logf("performance", err.Error())
logger.Logf(logger.Allow, "performance", err.Error())
}
}()
@ -117,7 +117,7 @@ func RunProfiler(profile Profile, filenameHeader string, run func() error) error
defer func() {
p.WriteTo(f, 0)
if err != nil {
logger.Logf("performance", err.Error())
logger.Logf(logger.Allow, "performance", err.Error())
}
}()
}

View file

@ -31,6 +31,8 @@ type Emulation struct {
vcs *hardware.VCS
}
const previewLabel = environment.Label("preview")
// NewEmulation is the preferred method of initialisation for the Emulation type
func NewEmulation(prefs *preferences.Preferences) (*Emulation, error) {
em := &Emulation{}
@ -43,11 +45,10 @@ func NewEmulation(prefs *preferences.Preferences) (*Emulation, error) {
tv.SetFPSCap(false)
// create a new VCS emulation
em.vcs, err = hardware.NewVCS(tv, nil, prefs)
em.vcs, err = hardware.NewVCS(previewLabel, tv, nil, prefs)
if err != nil {
return nil, fmt.Errorf("preview: %w", err)
}
em.vcs.Env.Label = environment.Label("preview")
return em, nil
}

View file

@ -86,7 +86,7 @@ func Load() (Properties, error) {
// prepare new entry if has is valid
if len(flds[1]) != 32 {
logger.Logf("properties", "invalid hash entry at line %d", line)
logger.Logf(logger.Allow, "properties", "invalid hash entry at line %d", line)
rejected++
} else {
entry = Entry{
@ -115,9 +115,9 @@ func Load() (Properties, error) {
return Properties{}, fmt.Errorf("pro: %w", err)
}
logger.Logf("properties", "%d entries loaded", len(pro.entries))
logger.Logf(logger.Allow, "properties", "%d entries loaded", len(pro.entries))
if rejected > 0 {
logger.Logf("properties", "%d entries rejected", rejected)
logger.Logf(logger.Allow, "properties", "%d entries rejected", rejected)
}
return pro, nil

View file

@ -71,7 +71,7 @@ func (ref *Reflector) SetEmulationState(state govern.State) {
case govern.Paused:
err := ref.render()
if err != nil {
logger.Logf("reflection", "%v", err)
logger.Logf(logger.Allow, "reflection", "%v", err)
}
}
}

View file

@ -26,6 +26,7 @@ import (
"github.com/jetsetilly/gopher2600/cartridgeloader"
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/debugger/govern"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/television"
"github.com/jetsetilly/gopher2600/logger"
@ -136,7 +137,7 @@ func (reg *LogRegression) regress(newRegression bool, output io.Writer, msg stri
tv.SetFPSCap(false)
// create VCS and attach cartridge
vcs, err := hardware.NewVCS(tv, nil, nil)
vcs, err := hardware.NewVCS(environment.MainEmulation, tv, nil, nil)
if err != nil {
return false, "", fmt.Errorf("log: %w", err)
}

View file

@ -28,6 +28,7 @@ import (
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/debugger/govern"
"github.com/jetsetilly/gopher2600/digest"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/riot/ports"
"github.com/jetsetilly/gopher2600/hardware/television"
@ -123,7 +124,7 @@ func (reg *PlaybackRegression) regress(newRegression bool, output io.Writer, msg
return false, "", fmt.Errorf("playback: %w", err)
}
vcs, err := hardware.NewVCS(tv, nil, nil)
vcs, err := hardware.NewVCS(environment.MainEmulation, tv, nil, nil)
if err != nil {
return false, "", fmt.Errorf("playback: %w", err)
}

View file

@ -28,6 +28,7 @@ import (
"github.com/jetsetilly/gopher2600/database"
"github.com/jetsetilly/gopher2600/debugger/govern"
"github.com/jetsetilly/gopher2600/digest"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/television"
"github.com/jetsetilly/gopher2600/setup"
@ -196,7 +197,7 @@ func (reg *VideoRegression) regress(newRegression bool, output io.Writer, msg st
}
// create VCS and attach cartridge
vcs, err := hardware.NewVCS(tv, nil, nil)
vcs, err := hardware.NewVCS(environment.MainEmulation, tv, nil, nil)
if err != nil {
return false, "", fmt.Errorf("video: %w", err)
}

View file

@ -344,7 +344,7 @@ func (r *Rewind) snapshot(level snapshotLevel) *State {
func (r *Rewind) RecordState() {
// sanity check to make sure the main loop is behaving correctly
if !r.vcs.CPU.LastResult.Final && !r.vcs.CPU.HasReset() {
logger.Logf("rewind", "RecordState() attempted mid CPU instruction")
logger.Logf(logger.Allow, "rewind", "RecordState() attempted mid CPU instruction")
return
}
@ -362,7 +362,7 @@ func (r *Rewind) RecordState() {
if r.resetBoundaryNextFrame {
r.resetBoundaryNextFrame = false
r.reset(levelBoundary)
logger.Logf("rewind", "boundary added at frame %d", r.vcs.TV.GetCoords().Frame)
logger.Logf(logger.Allow, "rewind", "boundary added at frame %d", r.vcs.TV.GetCoords().Frame)
return
}

View file

@ -18,12 +18,15 @@ package rewind
import (
"fmt"
"github.com/jetsetilly/gopher2600/environment"
"github.com/jetsetilly/gopher2600/hardware"
"github.com/jetsetilly/gopher2600/hardware/memory/memorymap"
"github.com/jetsetilly/gopher2600/hardware/television"
"github.com/jetsetilly/gopher2600/hardware/television/coords"
)
const searchLabel = environment.Label("search")
// SearchMemoryWrite runs an emulation between two states looking for the
// instance when the address is written to with the value (valueMask is applied
// to mask specific bits)
@ -51,7 +54,7 @@ func (r *Rewind) SearchMemoryWrite(tgt *State, addr uint16, value uint8, valueMa
}
_ = searchTV.SetFPSCap(false)
searchVCS, err := hardware.NewVCS(searchTV, nil, nil)
searchVCS, err := hardware.NewVCS(searchLabel, searchTV, nil, nil)
if err != nil {
return nil, fmt.Errorf("rewind: search: %w", err)
}
@ -115,7 +118,7 @@ func (r *Rewind) SearchRegisterWrite(tgt *State, reg rune, value uint8, valueMas
}
_ = searchTV.SetFPSCap(false)
searchVCS, err := hardware.NewVCS(searchTV, nil, nil)
searchVCS, err := hardware.NewVCS(searchLabel, searchTV, nil, nil)
if err != nil {
return nil, fmt.Errorf("rewind: search: %w", err)
}

View file

@ -102,7 +102,7 @@ func AttachCartridge(vcs *hardware.VCS, cartload cartridgeloader.Loader, resetVC
if err != nil {
return err
}
logger.Logf("setup", msg)
logger.Logf(logger.Allow, "setup", msg)
}
return nil

View file

@ -66,6 +66,8 @@ type Anim struct {
monitorInputDelay int
}
var animLabel = environment.Label("thumbnail_anim")
// NewAnim is the preferred method of initialisation for the Anim type
func NewAnim(prefs *preferences.Preferences) (*Anim, error) {
thmb := &Anim{
@ -91,11 +93,10 @@ func NewAnim(prefs *preferences.Preferences) (*Anim, error) {
tv.SetFPSCap(true)
// create a new VCS emulation
thmb.vcs, err = hardware.NewVCS(tv, thmb, prefs)
thmb.vcs, err = hardware.NewVCS(animLabel, tv, thmb, prefs)
if err != nil {
return nil, fmt.Errorf("thumbnailer: %w", err)
}
thmb.vcs.Env.Label = environment.Label("thumbnail_anim")
thmb.img = image.NewRGBA(image.Rect(0, 0, specification.ClksScanline, specification.AbsoluteMaxScanlines))
thmb.Reset()
@ -217,7 +218,7 @@ func (thmb *Anim) Create(cartload cartridgeloader.Loader, numFrames int, monitor
// attach cartridge using the setup system
err := setup.AttachCartridge(thmb.vcs, cartload, true)
if err != nil {
logger.Logf("thumbnailer", err.Error())
logger.Logf(logger.Allow, "thumbnailer", err.Error())
return
}
@ -264,7 +265,7 @@ func (thmb *Anim) Create(cartload cartridgeloader.Loader, numFrames int, monitor
return govern.Running, nil
})
if err != nil {
logger.Logf("thumbnailer", err.Error())
logger.Logf(logger.Allow, "thumbnailer", err.Error())
return
}
}()

View file

@ -51,6 +51,8 @@ type Image struct {
Render chan *image.RGBA
}
var imageLabel = environment.Label("image")
// NewImage is the preferred method of initialisation for the Image type
func NewImage(prefs *preferences.Preferences) (*Image, error) {
thmb := &Image{
@ -75,11 +77,10 @@ func NewImage(prefs *preferences.Preferences) (*Image, error) {
tv.SetFPSCap(false)
// create a new VCS emulation
thmb.vcs, err = hardware.NewVCS(tv, nil, prefs)
thmb.vcs, err = hardware.NewVCS(imageLabel, tv, nil, prefs)
if err != nil {
return nil, fmt.Errorf("thumbnailer: %w", err)
}
thmb.vcs.Env.Label = environment.Label("thumbnail")
thmb.img = image.NewRGBA(image.Rect(0, 0, specification.ClksScanline, specification.AbsoluteMaxScanlines))
thmb.Reset()
@ -153,7 +154,7 @@ func (thmb *Image) Create(state *rewind.State) {
})
if err != nil {
logger.Logf("thumbnailer", err.Error())
logger.Logf(logger.Allow, "thumbnailer", err.Error())
return
}
}

View file

@ -26,6 +26,8 @@ import (
"github.com/jetsetilly/gopher2600/rewind"
)
const replayLabel = environment.Label("tracker_replay")
// create replay emulation if it has not been created already
func (tr *Tracker) createReplayEmulation(mixer television.AudioMixer) error {
if tr.replayEmulation != nil {
@ -38,18 +40,15 @@ func (tr *Tracker) createReplayEmulation(mixer television.AudioMixer) error {
}
tv.AddAudioMixer(mixer)
tr.replayEmulation, err = hardware.NewVCS(tv, nil, nil)
tr.replayEmulation, err = hardware.NewVCS(replayLabel, tv, nil, nil)
if err != nil {
return fmt.Errorf("tracker: create replay emulation: %w", err)
}
tr.replayEmulation.Env.Label = replayEnv
tr.replayEmulation.TIA.Audio.SetTracker(tr)
return nil
}
const replayEnv = environment.Label("tracker_replay")
// Replay audio from start to end indexes
//
// The onEnd argument is a function to run when the replay has concluded
@ -64,7 +63,7 @@ func (tr *Tracker) Replay(start int, end int, mixer television.AudioMixer, onEnd
startState := tr.rewind.GetState(tr.crit.Entries[start].Coords.Frame)
if startState == nil {
logger.Logf("tracker", "replay: can't find rewind state for frame %d", tr.crit.Entries[start].Coords.Frame)
logger.Logf(logger.Allow, "tracker", "replay: can't find rewind state for frame %d", tr.crit.Entries[start].Coords.Frame)
return
}
@ -84,7 +83,7 @@ func (tr *Tracker) Replay(start int, end int, mixer television.AudioMixer, onEnd
return govern.Running, nil
})
if err != nil {
logger.Logf("tracker", "replay: %s", err.Error())
logger.Logf(logger.Allow, "tracker", "replay: %s", err.Error())
}
}()
}

View file

@ -165,7 +165,7 @@ func (tr *Tracker) AudioTick(env audio.TrackerEnvironment, channel int, reg audi
}
// add entry to list of entries only if we're not in the tracker emulation
if !env.IsEmulation(replayEnv) {
if !env.IsEmulation(replayLabel) {
if tr.emulation.State() != govern.Rewinding {
// find splice point in tracker
splice := len(tr.crit.Entries) - 1