@@ -38,7 +38,8 @@ type Core struct {
3838 // CPU instead of a generic 6502.
3939 Features CoreFeatureFlags
4040
41- Trace []uint16
41+ // Traceback state slice for keeping tracebacks if enabled.
42+ Trace []TracebackState
4243
4344 // What to do before executing instructions in `StepOnce()`.
4445 PreStep func (this * Core )
@@ -79,6 +80,18 @@ type Core struct {
7980 writingPointer uint16 // The pointer to writing to memory with `*Core.Write()`.
8081}
8182
83+ // A TracebackState is the data structure for tracebacks. If tracebacks are enabled,
84+ // the processor flags and registers are saved every step, only up to how many
85+ // tracebacks are requested in CoreFeatureFlags.
86+ type TracebackState struct {
87+ A byte // A - accumulator
88+ X byte // X
89+ Y byte // Y
90+ PC uint16 // PC - program counter
91+ S uint8 // S - stack pointer; starts at `0x01FF` and grows down to `0x0100`
92+ Flags byte // P - status, flags
93+ }
94+
8295// A struct for a set of feature flags that can be changed to have the emulator
8396// "specialized" to a specific 6502-compatible CPU instead of a generic 6502.
8497type CoreFeatureFlags struct {
@@ -152,6 +165,8 @@ type CoreFeatureFlags struct {
152165 // This is defaulted to true.
153166 ConsoleOutOnBreak bool
154167
168+ // Tracebacks for processor dumping. If non-zero, it saves traceback states
169+ // up to that number. If zero, none are kept.
155170 Traceback uint8
156171}
157172
@@ -364,7 +379,14 @@ func (c *Core) StepOnce() (valid bool) {
364379 }
365380
366381 if c .Features .Traceback > 0 {
367- c .Trace = append (c .Trace , c .PC )
382+ c .Trace = append (c .Trace , TracebackState {
383+ A : c .A ,
384+ X : c .X ,
385+ Y : c .Y ,
386+ PC : c .PC ,
387+ S : c .S ,
388+ Flags : c .Flags ,
389+ })
368390 if len (c .Trace ) > int (c .Features .Traceback ) {
369391 c .Trace = c .Trace [1 :]
370392 }
@@ -570,11 +592,26 @@ func (c *Core) ProgramCounterDump(coloured bool) (out string) {
570592 return out
571593}
572594
595+ // Returns a dump of all traceback states, and some memory around the captured
596+ // program counter for deeper debugging.
597+ //
598+ // See `*Core.MemoryDump` for detailed output documentation.
573599func (c * Core ) TracebackDumps (coloured bool ) (out string ) {
574- for idx , tracePc := range c .Trace {
575- out += fmt .Sprintf ("Trace %2d - PC: [%04x]" , idx , tracePc )
576- if idx == 0 || (idx > 0 && c .Trace [idx - 1 ] != tracePc ) {
577- out += "\n " + c .MemoryDump (uint16 (max (int32 (tracePc )- 0x11 , 0 )), tracePc + 0x11 , tracePc , coloured )
600+ for idx , traceState := range c .Trace {
601+ out += fmt .Sprintf ("Trace %2d - " , idx )
602+ out += fmt .Sprintf ("PC: %04x | S: %02x | A: %02x | X: %02x | Y: %02x | Fl: " ,
603+ traceState .PC , traceState .S , traceState .A , traceState .X , traceState .Y )
604+
605+ for idx , chr := range "nv-bdizc" {
606+ realRune := chr
607+ if traceState .Flags << idx & 0b10000000 > 0 && chr != '-' {
608+ realRune -= 32
609+ }
610+ out += string (realRune )
611+ }
612+
613+ if idx == 0 || (idx > 0 && c .Trace [idx - 1 ] != traceState ) {
614+ out += "\n " + c .MemoryDump (uint16 (max (int32 (traceState .PC )- 0x11 , 0 )), traceState .PC + 0x11 , traceState .PC , coloured )
578615 } else {
579616 out += " ..same as last"
580617 }
0 commit comments