From 2a683ebc5a1ad0b7473a99bf2679545e438a503e Mon Sep 17 00:00:00 2001 From: steve Date: Mon, 15 Jul 2019 15:26:29 +0100 Subject: [PATCH] o debugger - renamed STEPMODE to GRANULARITY - video granularity prompt no longer printed in bold type. easier to distinguish between that a cpu granularity prompt --- debugger/breakpoints.go | 6 +- debugger/colorterm/input.go | 8 +- debugger/colorterm/output.go | 22 +++--- debugger/commands.go | 125 +++++++++++++++--------------- debugger/console/console.go | 9 ++- debugger/console/plainterminal.go | 10 +-- debugger/console/style.go | 21 ++--- debugger/debugger.go | 37 ++++----- debugger/events.go | 2 +- debugger/help.go | 4 +- debugger/machineinfo.go | 2 +- debugger/print.go | 2 +- debugger/script/playback.go | 3 +- debugger/traps.go | 8 +- debugger/watches.go | 6 +- 15 files changed, 140 insertions(+), 125 deletions(-) diff --git a/debugger/breakpoints.go b/debugger/breakpoints.go index 378e9f42..2a21fb2b 100644 --- a/debugger/breakpoints.go +++ b/debugger/breakpoints.go @@ -116,11 +116,11 @@ func (bp *breakpoints) check(previousResult string) string { func (bp breakpoints) list() { if len(bp.breaks) == 0 { - bp.dbg.print(console.Feedback, "no breakpoints") + bp.dbg.print(console.StyleFeedback, "no breakpoints") } else { - bp.dbg.print(console.Feedback, "breakpoints") + bp.dbg.print(console.StyleFeedback, "breakpoints") for i := range bp.breaks { - bp.dbg.print(console.Feedback, "% 2d: %s", i, bp.breaks[i]) + bp.dbg.print(console.StyleFeedback, "% 2d: %s", i, bp.breaks[i]) } } } diff --git a/debugger/colorterm/input.go b/debugger/colorterm/input.go index fc63134e..ce696cc6 100644 --- a/debugger/colorterm/input.go +++ b/debugger/colorterm/input.go @@ -11,7 +11,7 @@ import ( ) // UserRead is the top level input function -func (ct *ColorTerminal) UserRead(input []byte, prompt string, events chan gui.Event, eventHandler func(gui.Event) error) (int, error) { +func (ct *ColorTerminal) UserRead(input []byte, prompt console.Prompt, events chan gui.Event, eventHandler func(gui.Event) error) (int, error) { // ctrl-c handling: currently, we put the terminal into rawmode and listen // for ctrl-c event using the readRune reader. @@ -43,12 +43,12 @@ func (ct *ColorTerminal) UserRead(input []byte, prompt string, events chan gui.E // for this to work we need to place the cursor in it's initial position // before we begin the loop ct.Print("\r") - ct.Print(ansi.CursorMove(len(prompt))) + ct.Print(ansi.CursorMove(len(prompt.Content))) for { ct.Print(ansi.CursorStore) - ct.UserPrint(console.Prompt, "%s%s", ansi.ClearLine, prompt) - ct.UserPrint(console.Input, string(input[:inputLen])) + ct.UserPrint(prompt.Style, "%s%s", ansi.ClearLine, prompt.Content) + ct.UserPrint(console.StyleInput, string(input[:inputLen])) ct.Print(ansi.CursorRestore) select { diff --git a/debugger/colorterm/output.go b/debugger/colorterm/output.go index 6778dcd8..83fe2196 100644 --- a/debugger/colorterm/output.go +++ b/debugger/colorterm/output.go @@ -8,29 +8,31 @@ import ( // UserPrint is the top level output function func (ct *ColorTerminal) UserPrint(sty console.Style, s string, a ...interface{}) { - if sty != console.Input { + if sty != console.StyleInput { ct.Print("\r") } switch sty { - case console.CPUStep: + case console.StyleCPUStep: ct.Print(ansi.PenColor["yellow"]) - case console.VideoStep: + case console.StyleVideoStep: ct.Print(ansi.DimPens["yellow"]) - case console.MachineInfo: + case console.StyleMachineInfo: ct.Print(ansi.PenColor["cyan"]) - case console.EmulatorInfo: + case console.StyleEmulatorInfo: ct.Print(ansi.PenColor["blue"]) - case console.Error: + case console.StyleError: ct.Print(ansi.PenColor["red"]) ct.Print("* ") - case console.Help: + case console.StyleHelp: ct.Print(ansi.DimPens["white"]) ct.Print(" ") - case console.Feedback: + case console.StyleFeedback: ct.Print(ansi.DimPens["white"]) - case console.Prompt: + case console.StylePrompt: ct.Print(ansi.PenStyles["bold"]) + case console.StylePromptAlt: + // nothing special } if len(a) > 0 { @@ -41,7 +43,7 @@ func (ct *ColorTerminal) UserPrint(sty console.Style, s string, a ...interface{} ct.Print(ansi.NormalPen) // add a newline if print style is anything other than prompt - if sty != console.Prompt && sty != console.Input { + if sty != console.StylePrompt && sty != console.StylePromptAlt && sty != console.StyleInput { ct.Print("\n") } } diff --git a/debugger/commands.go b/debugger/commands.go index 691bdfce..9e4660dc 100644 --- a/debugger/commands.go +++ b/debugger/commands.go @@ -50,7 +50,7 @@ const ( cmdRun = "RUN" cmdScript = "SCRIPT" cmdStep = "STEP" - cmdStepMode = "STEPMODE" + cmdGranularity = "GRANULARITY" cmdStick = "STICK" cmdSymbol = "SYMBOL" cmdTIA = "TIA" @@ -95,7 +95,7 @@ var commandTemplate = []string{ cmdRun, cmdScript + " [WRITE %S|END|%F]", cmdStep + " (CPU|VIDEO|%S)", - cmdStepMode + " (CPU|VIDEO)", + cmdGranularity + " (CPU|VIDEO)", cmdStick + " [0|1] [LEFT|RIGHT|UP|DOWN|FIRE|NOLEFT|NORIGHT|NOUP|NODOWN|NOFIRE]", cmdSymbol + " [%S (ALL|MIRRORS)|LIST (LOCATIONS|READ|WRITE)]", cmdTIA + " (DELAY|CLOCK)", @@ -244,13 +244,13 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) helpTxt, ok := Help[keyword] if ok == false { - dbg.print(console.Help, "no help for %s", keyword) + dbg.print(console.StyleHelp, "no help for %s", keyword) } else { helpTxt = fmt.Sprintf("%s\n\n Usage: %s", helpTxt, (*debuggerCommandsIdx)[keyword].String()) - dbg.print(console.Help, helpTxt) + dbg.print(console.StyleHelp, helpTxt) } } else { - dbg.print(console.Help, debuggerCommands.String()) + dbg.print(console.StyleHelp, debuggerCommands.String()) } case cmdInsert: @@ -259,7 +259,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) if err != nil { return doNothing, err } - dbg.print(console.Feedback, "machine reset with new cartridge (%s)", cart) + dbg.print(console.StyleFeedback, "machine reset with new cartridge (%s)", cart) case cmdScript: option, _ := tokens.Get() @@ -313,16 +313,16 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) } case cmdDisassembly: - dbg.disasm.Dump(dbg.printStyle(console.Feedback)) + dbg.disasm.Dump(dbg.printStyle(console.StyleFeedback)) case cmdGrep: search, _ := tokens.Get() output := strings.Builder{} dbg.disasm.Grep(search, &output, false, 3) if output.Len() == 0 { - dbg.print(console.Error, "%s not found in disassembly", search) + dbg.print(console.StyleError, "%s not found in disassembly", search) } else { - dbg.print(console.Feedback, output.String()) + dbg.print(console.StyleFeedback, output.String()) } case cmdSymbol: @@ -336,16 +336,16 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) // already caught by command line ValidateTokens() case "LOCATIONS": - dbg.disasm.Symtable.ListLocations(dbg.printStyle(console.Feedback)) + dbg.disasm.Symtable.ListLocations(dbg.printStyle(console.StyleFeedback)) case "READ": - dbg.disasm.Symtable.ListReadSymbols(dbg.printStyle(console.Feedback)) + dbg.disasm.Symtable.ListReadSymbols(dbg.printStyle(console.StyleFeedback)) case "WRITE": - dbg.disasm.Symtable.ListWriteSymbols(dbg.printStyle(console.Feedback)) + dbg.disasm.Symtable.ListWriteSymbols(dbg.printStyle(console.StyleFeedback)) } } else { - dbg.disasm.Symtable.ListSymbols(dbg.printStyle(console.Feedback)) + dbg.disasm.Symtable.ListSymbols(dbg.printStyle(console.StyleFeedback)) } default: @@ -355,7 +355,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) switch err := err.(type) { case errors.FormattedError: if err.Errno == errors.SymbolUnknown { - dbg.print(console.Feedback, "%s -> not found", symbol) + dbg.print(console.StyleFeedback, "%s -> not found", symbol) return doNothing, nil } } @@ -369,19 +369,19 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) // already caught by command line ValidateTokens() case "ALL", "MIRRORS": - dbg.print(console.Feedback, "%s -> %#04x", symbol, address) + dbg.print(console.StyleFeedback, "%s -> %#04x", symbol, address) // find all instances of symbol address in memory space // assumption: the address returned by SearchSymbol is the // first address in the complete list for m := address + 1; m < dbg.vcs.Mem.Cart.Origin(); m++ { if dbg.vcs.Mem.MapAddress(m, table == symbols.ReadSymTable) == address { - dbg.print(console.Feedback, "%s -> %#04x", symbol, m) + dbg.print(console.StyleFeedback, "%s -> %#04x", symbol, m) } } } } else { - dbg.print(console.Feedback, "%s -> %#04x", symbol, address) + dbg.print(console.StyleFeedback, "%s -> %#04x", symbol, address) } } @@ -428,18 +428,18 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) switch clear { case "BREAKS": dbg.breakpoints.clear() - dbg.print(console.Feedback, "breakpoints cleared") + dbg.print(console.StyleFeedback, "breakpoints cleared") case "TRAPS": dbg.traps.clear() - dbg.print(console.Feedback, "traps cleared") + dbg.print(console.StyleFeedback, "traps cleared") case "WATCHES": dbg.watches.clear() - dbg.print(console.Feedback, "watches cleared") + dbg.print(console.StyleFeedback, "watches cleared") case "ALL": dbg.breakpoints.clear() dbg.traps.clear() dbg.watches.clear() - dbg.print(console.Feedback, "breakpoints, traps and watches cleared") + dbg.print(console.StyleFeedback, "breakpoints, traps and watches cleared") default: // already caught by command line ValidateTokens() } @@ -460,26 +460,26 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) if err != nil { return doNothing, err } - dbg.print(console.Feedback, "breakpoint #%d dropped", num) + dbg.print(console.StyleFeedback, "breakpoint #%d dropped", num) case "TRAP": err := dbg.traps.drop(num) if err != nil { return doNothing, err } - dbg.print(console.Feedback, "trap #%d dropped", num) + dbg.print(console.StyleFeedback, "trap #%d dropped", num) case "WATCH": err := dbg.watches.drop(num) if err != nil { return doNothing, err } - dbg.print(console.Feedback, "watch #%d dropped", num) + dbg.print(console.StyleFeedback, "watch #%d dropped", num) default: // already caught by command line ValidateTokens() } case cmdOnHalt: if tokens.Remaining() == 0 { - dbg.print(console.Feedback, "auto-command on halt: %s", dbg.commandOnHalt) + dbg.print(console.StyleFeedback, "auto-command on halt: %s", dbg.commandOnHalt) return doNothing, nil } @@ -506,9 +506,9 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) // display the new/restored onhalt command(s) if dbg.commandOnHalt == "" { - dbg.print(console.Feedback, "auto-command on halt: OFF") + dbg.print(console.StyleFeedback, "auto-command on halt: OFF") } else { - dbg.print(console.Feedback, "auto-command on halt: %s", dbg.commandOnHalt) + dbg.print(console.StyleFeedback, "auto-command on halt: %s", dbg.commandOnHalt) } // run the new/restored onhalt command(s) @@ -517,7 +517,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) case cmdOnStep: if tokens.Remaining() == 0 { - dbg.print(console.Feedback, "auto-command on step: %s", dbg.commandOnStep) + dbg.print(console.StyleFeedback, "auto-command on step: %s", dbg.commandOnStep) return doNothing, nil } @@ -544,9 +544,9 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) // display the new/restored onstep command(s) if dbg.commandOnStep == "" { - dbg.print(console.Feedback, "auto-command on step: OFF") + dbg.print(console.StyleFeedback, "auto-command on step: OFF") } else { - dbg.print(console.Feedback, "auto-command on step: %s", dbg.commandOnStep) + dbg.print(console.StyleFeedback, "auto-command on step: %s", dbg.commandOnStep) } // run the new/restored onstep command(s) @@ -559,21 +559,21 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) if ok { switch strings.ToUpper(option) { case "DEFN": - dbg.print(console.Feedback, "%s", dbg.lastResult.Defn) + dbg.print(console.StyleFeedback, "%s", dbg.lastResult.Defn) } } else { var printTag console.Style if dbg.lastResult.Final { - printTag = console.CPUStep + printTag = console.StyleCPUStep } else { - printTag = console.VideoStep + printTag = console.StyleVideoStep } dbg.print(printTag, "%s", dbg.lastResult.GetString(dbg.disasm.Symtable, result.StyleExecution)) } } case cmdMemMap: - dbg.print(console.MachineInfo, "%v", dbg.vcs.Mem.MemoryMap()) + dbg.print(console.StyleMachineInfo, "%v", dbg.vcs.Mem.MemoryMap()) case cmdQuit: dbg.running = false @@ -587,7 +587,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) if err != nil { return doNothing, err } - dbg.print(console.Feedback, "machine reset") + dbg.print(console.StyleFeedback, "machine reset") case cmdRun: dbg.runUntilHalt = true @@ -598,9 +598,12 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) mode = strings.ToUpper(mode) switch mode { case "": + // calling step with no argument is the normal case case "CPU": + // changes granularity dbg.inputEveryVideoCycle = false case "VIDEO": + // changes granularity dbg.inputEveryVideoCycle = true default: dbg.inputEveryVideoCycle = false @@ -614,7 +617,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) return setDefaultStep, nil - case cmdStepMode: + case cmdGranularity: mode, present := tokens.Get() if present { mode = strings.ToUpper(mode) @@ -632,21 +635,21 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) } else { mode = "CPU" } - dbg.print(console.Feedback, "step mode: %s", mode) + dbg.print(console.StyleFeedback, "granularity: %s", mode) case cmdTerse: dbg.machineInfoVerbose = false - dbg.print(console.Feedback, "verbosity: terse") + dbg.print(console.StyleFeedback, "verbosity: terse") case cmdVerbose: dbg.machineInfoVerbose = true - dbg.print(console.Feedback, "verbosity: verbose") + dbg.print(console.StyleFeedback, "verbosity: verbose") case cmdVerbosity: if dbg.machineInfoVerbose { - dbg.print(console.Feedback, "verbosity: verbose") + dbg.print(console.StyleFeedback, "verbosity: verbose") } else { - dbg.print(console.Feedback, "verbosity: terse") + dbg.print(console.StyleFeedback, "verbosity: terse") } case cmdDebuggerState: @@ -660,7 +663,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) if ok { switch arg { case "ANALYSIS": - dbg.print(console.Feedback, dbg.disasm.String()) + dbg.print(console.StyleFeedback, dbg.disasm.String()) } } else { dbg.printMachineInfo(dbg.vcs.Mem.Cart) @@ -691,7 +694,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) v, err := strconv.ParseUint(value, 0, int(reg.Size())) if err != nil { - dbg.print(console.Error, "value must be a positive %dbit number", reg.Size()) + dbg.print(console.StyleError, "value must be a positive %dbit number", reg.Size()) } reg.Load(v) @@ -711,9 +714,9 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) // perform peek ai, err := dbg.dbgmem.peek(a) if err != nil { - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) } else { - dbg.print(console.MachineInfo, ai.String()) + dbg.print(console.StyleMachineInfo, ai.String()) } // loop through all addresses @@ -729,16 +732,16 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) val, err := strconv.ParseUint(v, 0, 8) if err != nil { - dbg.print(console.Error, "poke value must be 8bit number (%s)", v) + dbg.print(console.StyleError, "poke value must be 8bit number (%s)", v) return doNothing, nil } // perform single poke ai, err := dbg.dbgmem.poke(a, uint8(val)) if err != nil { - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) } else { - dbg.print(console.MachineInfo, ai.String()) + dbg.print(console.StyleMachineInfo, ai.String()) } case cmdHexLoad: @@ -747,7 +750,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) addr, err := strconv.ParseUint(a, 0, 16) if err != nil { - dbg.print(console.Error, "hexload address must be 16bit number (%s)", a) + dbg.print(console.StyleError, "hexload address must be 16bit number (%s)", a) return doNothing, nil } @@ -757,7 +760,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) for present { val, err := strconv.ParseUint(v, 0, 8) if err != nil { - dbg.print(console.Error, "hexload value must be 8bit number (%s)", addr) + dbg.print(console.StyleError, "hexload value must be 8bit number (%s)", addr) v, present = tokens.Get() continue // for loop (without advancing address) } @@ -765,9 +768,9 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) // perform individual poke ai, err := dbg.dbgmem.poke(uint16(addr), uint8(val)) if err != nil { - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) } else { - dbg.print(console.MachineInfo, ai.String()) + dbg.print(console.StyleMachineInfo, ai.String()) } // loop through all values @@ -805,7 +808,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) dbg.printMachineInfo(dbg.vcs.TIA.Video.Player0.SprDelay) dbg.printMachineInfo(dbg.vcs.TIA.Video.Player1.SprDelay) case "CLOCK": - dbg.print(console.Error, "not supported yet") + dbg.print(console.StyleError, "not supported yet") default: // already caught by command line ValidateTokens() } @@ -819,7 +822,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) option = strings.ToUpper(option) switch option { case "SPEC": - dbg.print(console.MachineInfo, dbg.gui.GetSpec().ID) + dbg.print(console.StyleMachineInfo, dbg.gui.GetSpec().ID) default: // already caught by command line ValidateTokens() } @@ -848,11 +851,11 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) switch plyr { case 0: p0 := strings.Split(dbg.getMachineInfo(dbg.vcs.TIA.Video.Player0), "\n") - dbg.print(console.MachineInfo, strings.Join(p0, "\n")) + dbg.print(console.StyleMachineInfo, strings.Join(p0, "\n")) case 1: p1 := strings.Split(dbg.getMachineInfo(dbg.vcs.TIA.Video.Player1), "\n") - dbg.print(console.MachineInfo, strings.Join(p1, "\n")) + dbg.print(console.StyleMachineInfo, strings.Join(p1, "\n")) default: p0 := strings.Split(dbg.getMachineInfo(dbg.vcs.TIA.Video.Player0), "\n") @@ -871,7 +874,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) s.WriteString(fmt.Sprintf("%s %s | %s\n", p0[i], strings.Repeat(" ", ml-len(p0[i])), p1[i])) } } - dbg.print(console.MachineInfo, s.String()) + dbg.print(console.StyleMachineInfo, s.String()) } } else { switch plyr { @@ -904,11 +907,11 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) switch mssl { case 0: m0 := strings.Split(dbg.getMachineInfo(dbg.vcs.TIA.Video.Missile0), "\n") - dbg.print(console.MachineInfo, strings.Join(m0, "\n")) + dbg.print(console.StyleMachineInfo, strings.Join(m0, "\n")) case 1: m1 := strings.Split(dbg.getMachineInfo(dbg.vcs.TIA.Video.Missile0), "\n") - dbg.print(console.MachineInfo, strings.Join(m1, "\n")) + dbg.print(console.StyleMachineInfo, strings.Join(m1, "\n")) default: // arrange the two missile's information side by side in order to @@ -930,7 +933,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) s.WriteString(fmt.Sprintf("%s %s | %s\n", m0[i], strings.Repeat(" ", ml-len(m0[i])), m1[i])) } } - dbg.print(console.MachineInfo, s.String()) + dbg.print(console.StyleMachineInfo, s.String()) } } else { switch mssl { @@ -1052,7 +1055,7 @@ func (dbg *Debugger) enactCommand(tokens *commandline.Tokens, interactive bool) dbg.digest.ResetDigest() } } else { - dbg.print(console.Feedback, dbg.digest.String()) + dbg.print(console.StyleFeedback, dbg.digest.String()) } } diff --git a/debugger/console/console.go b/debugger/console/console.go index 3c056af3..77574f46 100644 --- a/debugger/console/console.go +++ b/debugger/console/console.go @@ -4,9 +4,16 @@ import ( "gopher2600/gui" ) +// Prompt represents the text that is to pose as a prompt to the user when user +// input is required +type Prompt struct { + Content string + Style Style +} + // UserInput defines the operations required by an interface that allows input type UserInput interface { - UserRead(buffer []byte, prompt string, eventChannel chan gui.Event, eventHandler func(gui.Event) error) (int, error) + UserRead(buffer []byte, prompt Prompt, eventChannel chan gui.Event, eventHandler func(gui.Event) error) (int, error) IsInteractive() bool } diff --git a/debugger/console/plainterminal.go b/debugger/console/plainterminal.go index 9adc6812..a90dd76e 100644 --- a/debugger/console/plainterminal.go +++ b/debugger/console/plainterminal.go @@ -31,23 +31,23 @@ func (pt *PlainTerminal) RegisterTabCompleter(TabCompleter) { // UserPrint is the plain terminal print routine func (pt PlainTerminal) UserPrint(pp Style, s string, a ...interface{}) { switch pp { - case Error: + case StyleError: s = fmt.Sprintf("* %s", s) - case Help: + case StyleHelp: s = fmt.Sprintf(" %s", s) } s = fmt.Sprintf(s, a...) pt.output.Write([]byte(s)) - if pp != Prompt { + if pp != StylePrompt { pt.output.Write([]byte("\n")) } } // UserRead is the plain terminal read routine -func (pt PlainTerminal) UserRead(input []byte, prompt string, _ chan gui.Event, _ func(gui.Event) error) (int, error) { - pt.UserPrint(Prompt, prompt) +func (pt PlainTerminal) UserRead(input []byte, prompt Prompt, _ chan gui.Event, _ func(gui.Event) error) (int, error) { + pt.UserPrint(prompt.Style, prompt.Content) n, err := pt.input.Read(input) if err != nil { diff --git a/debugger/console/style.go b/debugger/console/style.go index c56bd191..2336eca7 100644 --- a/debugger/console/style.go +++ b/debugger/console/style.go @@ -6,39 +6,40 @@ type Style int // enumeration of print styles const ( // disassembly output at cpu cycle boundaries - CPUStep Style = iota + StyleCPUStep Style = iota // disassembly output at video cycle boundaries - VideoStep + StyleVideoStep // information about the machine - MachineInfo + StyleMachineInfo // information about the emulator, rather than the emulated machine - EmulatorInfo + StyleEmulatorInfo // the input prompt - Prompt + StylePrompt + StylePromptAlt // non-error information from a command - Feedback + StyleFeedback // help information - Help + StyleHelp // user input (not used by all user interface types [eg. echoing terminals]) - Input + StyleInput // information as a result of an error. errors can be generated by the // emulation or the debugger - Error + StyleError ) // IncludeInScriptOutput returns true if print styles is to be included in the // output of a script recording func (sty Style) IncludeInScriptOutput() bool { switch sty { - case Error, Input, Prompt: + case StyleError, StyleInput, StylePrompt: return false default: return true diff --git a/debugger/debugger.go b/debugger/debugger.go index e8261872..f28233d3 100644 --- a/debugger/debugger.go +++ b/debugger/debugger.go @@ -227,7 +227,7 @@ func (dbg *Debugger) Start(cons console.UserInterface, initScript string, cartri if initScript != "" { plb, err := script.StartPlayback(initScript) if err != nil { - dbg.print(console.Error, "error running debugger initialisation script: %s\n", err) + dbg.print(console.StyleError, "error running debugger initialisation script: %s\n", err) } err = dbg.inputLoop(plb, false) @@ -260,7 +260,7 @@ func (dbg *Debugger) loadCartridge(cartridgeFilename string) error { symtable, err := symbols.ReadSymbolsFile(cartridgeFilename) if err != nil { - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) // continuing because symtable is always valid even if err non-nil } @@ -316,7 +316,7 @@ func (dbg *Debugger) inputLoop(inputter console.UserInput, videoCycle bool) erro if dbg.commandOnStep != "" { _, err := dbg.parseInput(dbg.commandOnStep, false, true) if err != nil { - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) } } return dbg.inputLoop(inputter, true) @@ -359,15 +359,15 @@ func (dbg *Debugger) inputLoop(inputter console.UserInput, videoCycle bool) erro if (dbg.inputloopNext && !dbg.runUntilHalt) || dbg.inputloopHalt { _, err = dbg.parseInput(dbg.commandOnHalt, false, true) if err != nil { - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) } } } // print and reset accumulated break and trap messages - dbg.print(console.Feedback, dbg.breakMessages) - dbg.print(console.Feedback, dbg.trapMessages) - dbg.print(console.Feedback, dbg.watchMessages) + dbg.print(console.StyleFeedback, dbg.breakMessages) + dbg.print(console.StyleFeedback, dbg.trapMessages) + dbg.print(console.StyleFeedback, dbg.watchMessages) dbg.breakMessages = "" dbg.trapMessages = "" dbg.watchMessages = "" @@ -408,7 +408,7 @@ func (dbg *Debugger) inputLoop(inputter console.UserInput, videoCycle bool) erro if !videoCycle { // !!TODO: prevent printing of ScriptEnd error for // initialisation script - dbg.print(console.Feedback, err.Error()) + dbg.print(console.StyleFeedback, err.Error()) } return nil @@ -428,7 +428,7 @@ func (dbg *Debugger) inputLoop(inputter console.UserInput, videoCycle bool) erro // parse user input dbg.inputloopNext, err = dbg.parseInput(string(dbg.input[:n-1]), inputter.IsInteractive(), false) if err != nil { - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) } // prepare for next loop @@ -461,7 +461,7 @@ func (dbg *Debugger) inputLoop(inputter console.UserInput, videoCycle bool) erro dbg.lastStepError = true // print gopher error message - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) default: return err } @@ -470,8 +470,8 @@ func (dbg *Debugger) inputLoop(inputter console.UserInput, videoCycle bool) erro if dbg.lastResult.Final { err := dbg.lastResult.IsValid() if err != nil { - dbg.print(console.Error, "%s", dbg.lastResult.Defn) - dbg.print(console.Error, "%s", dbg.lastResult) + dbg.print(console.StyleError, "%s", dbg.lastResult.Defn) + dbg.print(console.StyleError, "%s", dbg.lastResult) return errors.NewFormattedError(errors.DebuggerError, err) } } @@ -480,7 +480,7 @@ func (dbg *Debugger) inputLoop(inputter console.UserInput, videoCycle bool) erro if dbg.commandOnStep != "" { _, err := dbg.parseInput(dbg.commandOnStep, false, true) if err != nil { - dbg.print(console.Error, "%s", err) + dbg.print(console.StyleError, "%s", err) } } } else { @@ -492,7 +492,7 @@ func (dbg *Debugger) inputLoop(inputter console.UserInput, videoCycle bool) erro return nil } -func (dbg *Debugger) buildPrompt(videoCycle bool) string { +func (dbg *Debugger) buildPrompt(videoCycle bool) console.Prompt { // decide which address value to use var promptAddress uint16 var promptBank int @@ -530,14 +530,15 @@ func (dbg *Debugger) buildPrompt(videoCycle bool) string { prompt = fmt.Sprintf("%s ! ", prompt) } - // - additional annotation if we're not showing the prompt in the main loop + // video cycle prompt if videoCycle && !dbg.lastResult.Final { - prompt = fmt.Sprintf("%s < ", prompt) - } else { prompt = fmt.Sprintf("%s > ", prompt) + return console.Prompt{Content: prompt, Style: console.StylePromptAlt} } - return prompt + // cpu cycle prompt + prompt = fmt.Sprintf("%s >> ", prompt) + return console.Prompt{Content: prompt, Style: console.StylePrompt} } // parseInput splits the input into individual commands. each command is then diff --git a/debugger/events.go b/debugger/events.go index bef381d6..2c317261 100644 --- a/debugger/events.go +++ b/debugger/events.go @@ -49,7 +49,7 @@ func (dbg *Debugger) guiEventHandler(event gui.Event) error { data := event.Data.(gui.EventDataMouse) _, err = dbg.parseInput(fmt.Sprintf("%s sl %d & hp %d", cmdBreak, data.Scanline, data.HorizPos), false, false) if err == nil { - dbg.print(console.Feedback, "mouse break on sl->%d and hp->%d", data.Scanline, data.HorizPos) + dbg.print(console.StyleFeedback, "mouse break on sl->%d and hp->%d", data.Scanline, data.HorizPos) } } diff --git a/debugger/help.go b/debugger/help.go index 4251c300..647b30e4 100644 --- a/debugger/help.go +++ b/debugger/help.go @@ -32,8 +32,8 @@ var Help = map[string]string{ cmdReset: "Reset the emulation to its initial state", cmdRun: "Run emulator until next halt state", cmdScript: "Run commands from specified file or record commands to a file", - cmdStep: "Step forward emulator one step (see STEPMODE command)", - cmdStepMode: "Change method of stepping: CPU or VIDEO", + cmdStep: "Step forward one step. Optional argument sets the amount to step by (eg. frame, scanline, etc.)", + cmdGranularity: "Change method of stepping: CPU or VIDEO", cmdStick: "Emulate a joystick input for Player 0 or Player 1", cmdSymbol: "Search for the address label symbol in disassembly. returns address", cmdTIA: "Display current state of the TIA", diff --git a/debugger/machineinfo.go b/debugger/machineinfo.go index 817e4fcb..75e188a1 100644 --- a/debugger/machineinfo.go +++ b/debugger/machineinfo.go @@ -13,7 +13,7 @@ type machineInformer interface { } func (dbg *Debugger) printMachineInfo(mi machineInformer) { - dbg.print(console.MachineInfo, "%s", dbg.getMachineInfo(mi)) + dbg.print(console.StyleMachineInfo, "%s", dbg.getMachineInfo(mi)) } func (dbg *Debugger) getMachineInfo(mi machineInformer) string { diff --git a/debugger/print.go b/debugger/print.go index 401e4d2f..be78e242 100644 --- a/debugger/print.go +++ b/debugger/print.go @@ -12,7 +12,7 @@ import ( // implementors func (dbg *Debugger) print(sty console.Style, s string, a ...interface{}) { // resolve string placeholders and return if the resulting string is empty - if sty != console.Help { + if sty != console.StyleHelp { s = fmt.Sprintf(s, a...) if len(s) == 0 { return diff --git a/debugger/script/playback.go b/debugger/script/playback.go index a0039b7f..7d98da8c 100644 --- a/debugger/script/playback.go +++ b/debugger/script/playback.go @@ -2,6 +2,7 @@ package script import ( "fmt" + "gopher2600/debugger/console" "gopher2600/errors" "gopher2600/gui" "io/ioutil" @@ -61,7 +62,7 @@ func (rps *Playback) IsInteractive() bool { } // UserRead implements ui.UserInput interface -func (rps *Playback) UserRead(buffer []byte, prompt string, _ chan gui.Event, _ func(gui.Event) error) (int, error) { +func (rps *Playback) UserRead(buffer []byte, _ console.Prompt, _ chan gui.Event, _ func(gui.Event) error) (int, error) { if rps.nextLine > len(rps.lines)-1 { return -1, errors.NewFormattedError(errors.ScriptEnd, rps.scriptFile) } diff --git a/debugger/traps.go b/debugger/traps.go index b619bf19..c6fcba7a 100644 --- a/debugger/traps.go +++ b/debugger/traps.go @@ -72,11 +72,11 @@ func (tr *traps) check(previousResult string) string { func (tr traps) list() { if len(tr.traps) == 0 { - tr.dbg.print(console.Feedback, "no traps") + tr.dbg.print(console.StyleFeedback, "no traps") } else { - tr.dbg.print(console.Feedback, "traps") + tr.dbg.print(console.StyleFeedback, "traps") for i := range tr.traps { - tr.dbg.print(console.Feedback, "% 2d: %s", i, tr.traps[i].target.ShortLabel()) + tr.dbg.print(console.StyleFeedback, "% 2d: %s", i, tr.traps[i].target.ShortLabel()) } } } @@ -93,7 +93,7 @@ func (tr *traps) parseTrap(tokens *commandline.Tokens) error { for _, t := range tr.traps { if t.target.Label() == tgt.Label() { addNewTrap = false - tr.dbg.print(console.Error, fmt.Sprintf("trap already exists (%s)", t)) + tr.dbg.print(console.StyleError, fmt.Sprintf("trap already exists (%s)", t)) break // for loop } } diff --git a/debugger/watches.go b/debugger/watches.go index eac92546..6e0e1096 100644 --- a/debugger/watches.go +++ b/debugger/watches.go @@ -124,11 +124,11 @@ func (wtc *watches) check(previousResult string) string { func (wtc *watches) list() { if len(wtc.watches) == 0 { - wtc.dbg.print(console.Feedback, "no watches") + wtc.dbg.print(console.StyleFeedback, "no watches") } else { - wtc.dbg.print(console.Feedback, "watches") + wtc.dbg.print(console.StyleFeedback, "watches") for i := range wtc.watches { - wtc.dbg.print(console.Feedback, "% 2d: %s", i, wtc.watches[i]) + wtc.dbg.print(console.StyleFeedback, "% 2d: %s", i, wtc.watches[i]) } } }