mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-28 02:30:36 +00:00
112 lines
2.8 KiB
Go
112 lines
2.8 KiB
Go
package izapple2
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"golang.org/x/exp/maps"
|
|
"golang.org/x/exp/slices"
|
|
)
|
|
|
|
type executionTracer interface {
|
|
connect(a *Apple2)
|
|
inspect()
|
|
}
|
|
|
|
type traceBuilder struct {
|
|
name string
|
|
description string
|
|
executionTracer executionTracer
|
|
connectFunc func(a *Apple2)
|
|
}
|
|
|
|
var traceFactory map[string]*traceBuilder
|
|
|
|
func getTracerFactory() map[string]*traceBuilder {
|
|
if traceFactory != nil {
|
|
return traceFactory
|
|
}
|
|
|
|
tracerFactory := make(map[string]*traceBuilder)
|
|
|
|
tracerFactory["mos"] = &traceBuilder{
|
|
name: "mos",
|
|
description: "Trace MOS calls with Applecorn skipping terminal IO",
|
|
executionTracer: newTraceApplecorn(true),
|
|
}
|
|
tracerFactory["mosfull"] = &traceBuilder{
|
|
name: "mosfull",
|
|
description: "Trace MOS calls with Applecorn",
|
|
executionTracer: newTraceApplecorn(false),
|
|
}
|
|
tracerFactory["mli"] = &traceBuilder{
|
|
name: "mli",
|
|
description: "Trace ProDOS MLI calls",
|
|
executionTracer: newTraceProDOS(),
|
|
}
|
|
tracerFactory["ucsd"] = &traceBuilder{
|
|
name: "ucsd",
|
|
description: "Trace UCSD system calls",
|
|
executionTracer: newTracePascal(),
|
|
}
|
|
tracerFactory["cpu"] = &traceBuilder{
|
|
name: "cpu",
|
|
description: "Trace CPU execution",
|
|
connectFunc: func(a *Apple2) { a.cpu.SetTrace(true) },
|
|
}
|
|
tracerFactory["ss"] = &traceBuilder{
|
|
name: "ss",
|
|
description: "Trace sotfswiches calls",
|
|
connectFunc: func(a *Apple2) { a.io.setTrace(true) },
|
|
}
|
|
tracerFactory["ssreg"] = &traceBuilder{
|
|
name: "ssreg",
|
|
description: "Trace sotfswiches registrations",
|
|
connectFunc: func(a *Apple2) { a.io.setTraceRegistrations(true) },
|
|
}
|
|
tracerFactory["panicSS"] = &traceBuilder{
|
|
name: "panicSS",
|
|
description: "Panic on unimplemented softswitches",
|
|
connectFunc: func(a *Apple2) { a.io.setPanicNotImplemented(true) },
|
|
}
|
|
tracerFactory["cpm65"] = &traceBuilder{
|
|
name: "cpm65",
|
|
description: "Trace CPM65 BDOS calls",
|
|
executionTracer: newTraceCpm65(false),
|
|
}
|
|
return tracerFactory
|
|
}
|
|
|
|
func availableTracers() []string {
|
|
names := maps.Keys(getTracerFactory())
|
|
slices.Sort(names)
|
|
return names
|
|
}
|
|
|
|
func setupTracers(a *Apple2, paramString string) error {
|
|
tracerFactory := getTracerFactory()
|
|
tracerNames := splitConfigurationString(paramString, ',')
|
|
for _, tracer := range tracerNames {
|
|
tracer = strings.ToLower(strings.TrimSpace(tracer))
|
|
if tracer == "none" {
|
|
continue
|
|
}
|
|
builder, ok := tracerFactory[tracer]
|
|
if !ok {
|
|
return fmt.Errorf("unknown tracer %s", tracer)
|
|
}
|
|
if builder.connectFunc != nil {
|
|
builder.connectFunc(a)
|
|
}
|
|
if builder.executionTracer != nil {
|
|
a.addTracer(builder.executionTracer)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (a *Apple2) addTracer(tracer executionTracer) {
|
|
tracer.connect(a)
|
|
a.tracers = append(a.tracers, tracer)
|
|
}
|