Skip to content

Commit d41e724

Browse files
committed
tracebacks saves more state, +documentation
1 parent ff38de5 commit d41e724

1 file changed

Lines changed: 43 additions & 6 deletions

File tree

cpu/core.go

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
8497
type 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.
573599
func (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

Comments
 (0)