Simpler approach for Applecorn trace, no reentrancy
This commit is contained in:
parent
612adbc11f
commit
3b56312d9c
|
@ -2,7 +2,6 @@ package izapple2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -19,19 +18,20 @@ type traceApplecorn struct {
|
||||||
a *Apple2
|
a *Apple2
|
||||||
skipConsole bool
|
skipConsole bool
|
||||||
osbyteNames [256]string
|
osbyteNames [256]string
|
||||||
calls []mosCallData
|
call mosCallData
|
||||||
lastDepth int
|
lastDepth int
|
||||||
|
wasInKernel bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type mosCallData struct {
|
type mosCallData struct {
|
||||||
caller uint16
|
|
||||||
api uint16
|
api uint16
|
||||||
a, x, y uint8
|
a, x, y uint8
|
||||||
|
skipLog bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
applecornMosVec uint16 = 0xffb9 // Start of the MOS entry points
|
applecornKernelStart uint16 = 0xc000 // Code above this is out of BBC territory
|
||||||
applecornNoCaller uint16 = 0xffff
|
applecornNoCaller uint16 = 0xffff
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTraceApplecorn(a *Apple2, skipConsole bool) *traceApplecorn {
|
func newTraceApplecorn(a *Apple2, skipConsole bool) *traceApplecorn {
|
||||||
|
@ -48,16 +48,17 @@ func newTraceApplecorn(a *Apple2, skipConsole bool) *traceApplecorn {
|
||||||
t.osbyteNames[0x85] = "top user mem for mode"
|
t.osbyteNames[0x85] = "top user mem for mode"
|
||||||
t.osbyteNames[0x86] = "read cursor pos"
|
t.osbyteNames[0x86] = "read cursor pos"
|
||||||
t.osbyteNames[0xDA] = "clear VDU queue"
|
t.osbyteNames[0xDA] = "clear VDU queue"
|
||||||
t.calls = make([]mosCallData, 0)
|
|
||||||
return &t
|
return &t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *traceApplecorn) inspect() {
|
func (t *traceApplecorn) inspect() {
|
||||||
pc, sp := t.a.cpu.GetPCAndSP()
|
pc, _ := t.a.cpu.GetPCAndSP()
|
||||||
if pc >= 0xd000 /*applecornMosVec*/ {
|
inKernel := pc >= applecornKernelStart
|
||||||
regA, regX, regY := t.a.cpu.GetAXY()
|
|
||||||
|
|
||||||
s := ""
|
if !t.wasInKernel && inKernel {
|
||||||
|
regA, regX, regY, _ := t.a.cpu.GetAXYP()
|
||||||
|
|
||||||
|
s := "UNKNOWN"
|
||||||
skip := false
|
skip := false
|
||||||
|
|
||||||
// Page 2 vectors
|
// Page 2 vectors
|
||||||
|
@ -123,17 +124,15 @@ func (t *traceApplecorn) inspect() {
|
||||||
case 0xffe0:
|
case 0xffe0:
|
||||||
s = fmt.Sprintf("OSRDCH()")
|
s = fmt.Sprintf("OSRDCH()")
|
||||||
skip = t.skipConsole
|
skip = t.skipConsole
|
||||||
/*
|
case 0xffe3: // This fallbacks to OSWRCH
|
||||||
case 0xffe3: // This fallbacks to OSWRCH
|
s = "OSASCI(?)"
|
||||||
s = "OSASCI(?)"
|
skip = t.skipConsole
|
||||||
skip = t.skipConsole
|
case 0xffe7: // This fallbacks to OSWRCH
|
||||||
case 0xffe7: // This fallbacks to OSWRCH
|
s = fmt.Sprintf("OSNEWL()")
|
||||||
s = fmt.Sprintf("OSNEWL()")
|
skip = t.skipConsole
|
||||||
skip = t.skipConsole
|
case 0xffec: // This fallbacks to OSWRCH
|
||||||
case 0xffec: // This fallbacks to OSWRCH
|
skip = t.skipConsole
|
||||||
skip = t.skipConsole
|
s = fmt.Sprintf("OSNECR()")
|
||||||
s = fmt.Sprintf("OSNECR()")
|
|
||||||
*/
|
|
||||||
case 0xffee:
|
case 0xffee:
|
||||||
ch := ""
|
ch := ""
|
||||||
if regA >= 0x20 && regA < 0x7f {
|
if regA >= 0x20 && regA < 0x7f {
|
||||||
|
@ -153,48 +152,42 @@ func (t *traceApplecorn) inspect() {
|
||||||
}
|
}
|
||||||
case 0xfff4:
|
case 0xfff4:
|
||||||
s = fmt.Sprintf("OSBYTE('%s';A=%02x,X=%02x,Y=%02x)", t.osbyteNames[regA], regA, regX, regY)
|
s = fmt.Sprintf("OSBYTE('%s';A=%02x,X=%02x,Y=%02x)", t.osbyteNames[regA], regA, regX, regY)
|
||||||
//if regA == 0xda {
|
|
||||||
// t.a.cpu.Reset()
|
|
||||||
//}
|
|
||||||
case 0xfff7:
|
case 0xfff7:
|
||||||
s = "OSCLI(?)"
|
s = "OSCLI(?)"
|
||||||
}
|
}
|
||||||
|
|
||||||
if !skip && s != "" {
|
t.call.api = pc
|
||||||
caller := t.a.mmu.peekWord(0x100+uint16(sp+1)) + 1
|
t.call.a = regA
|
||||||
t.calls = append(t.calls, mosCallData{caller, pc, regA, regX, regY})
|
t.call.x = regX
|
||||||
if len(t.calls) > t.lastDepth {
|
t.call.y = regY
|
||||||
// Reentrant call, first of block
|
t.call.skipLog = skip
|
||||||
fmt.Println()
|
if !skip {
|
||||||
}
|
|
||||||
if len(t.calls) > 1 {
|
|
||||||
// Reentrant call
|
|
||||||
fmt.Printf("%s", strings.Repeat(" ", len(t.calls)))
|
|
||||||
}
|
|
||||||
fmt.Printf("BBC MOS call to $%04x %s ", pc, s)
|
fmt.Printf("BBC MOS call to $%04x %s ", pc, s)
|
||||||
t.lastDepth = len(t.calls)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(t.calls) > 0 && pc == t.calls[len(t.calls)-1].caller {
|
if t.wasInKernel && !inKernel && !t.call.skipLog {
|
||||||
// Returning from the call
|
// Returning from the call
|
||||||
regA, regX, regY := t.a.cpu.GetAXY()
|
regA, regX, regY, _ := t.a.cpu.GetAXYP()
|
||||||
call := t.calls[len(t.calls)-1]
|
|
||||||
s := ""
|
s := ""
|
||||||
switch call.api {
|
switch t.call.api {
|
||||||
case 0xfff1: // OSWORD
|
case 0xfff1: // OSWORD
|
||||||
cbAddress := uint16(call.x) + uint16(call.y)<<8
|
cbAddress := uint16(t.call.x) + uint16(t.call.y)<<8
|
||||||
switch call.a {
|
switch t.call.a {
|
||||||
case 0: // Read line from input
|
case 0: // Read line from input
|
||||||
lineAddress := t.a.mmu.peekWord(cbAddress)
|
lineAddress := t.a.mmu.peekWord(cbAddress)
|
||||||
line := t.getString(lineAddress, regY)
|
line := t.getString(lineAddress, regY)
|
||||||
s = fmt.Sprintf(",line='%s'", line)
|
s = fmt.Sprintf(",line='%s'", line)
|
||||||
|
|
||||||
|
t.a.cpu.SetTrace(true)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("=> (A=%02x,X=%02x,Y=%02x%s)\n", regA, regX, regY, s)
|
fmt.Printf("=> (A=%02x,X=%02x,Y=%02x%s)\n", regA, regX, regY, s)
|
||||||
t.calls = t.calls[:len(t.calls)-1]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.wasInKernel = inKernel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *traceApplecorn) getString(address uint16, length uint8) string {
|
func (t *traceApplecorn) getString(address uint16, length uint8) string {
|
||||||
|
|
Loading…
Reference in New Issue