mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-08-05 17:25:23 +00:00
CPM-65 preconfigured model and better CPM-65 BIOS and BDOS tracing
This commit is contained in:
@@ -233,6 +233,7 @@ The available pre-configured models are:
|
||||
basis108: Basis 108
|
||||
cpm: Apple ][+ with CP/M
|
||||
cpm3: Apple //e with CP/M 3.0
|
||||
cpm65: Apple //e with CPM-65
|
||||
dos32: Apple ][ with 13 sectors disk adapter and DOS 3.2x
|
||||
swyft: swyft
|
||||
|
||||
@@ -263,7 +264,8 @@ The available cards are:
|
||||
|
||||
The available tracers are:
|
||||
cpm: Trace CPM BDOS calls
|
||||
cpm65: Trace CPM65 BDOS calls
|
||||
cpm65: Trace CPM65 BDOS calls skipping terminal IO
|
||||
cpm65full: Trace CPM65 BDOS calls
|
||||
cpu: Trace CPU execution
|
||||
mli: Trace ProDOS MLI calls
|
||||
mos: Trace MOS calls with Applecorn skipping terminal IO
|
||||
|
3
configs/cpm65.cfg
Normal file
3
configs/cpm65.cfg
Normal file
@@ -0,0 +1,3 @@
|
||||
name: Apple //e with CPM-65
|
||||
parent: 2enh
|
||||
s6: diskii,disk1=<internal>/cpm65.po
|
16
doc/cpm65.md
Normal file
16
doc/cpm65.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# CPM-65
|
||||
|
||||
CPM-65 is a native port of Digital Research's seminal 1977 operating system CP/M to the 6502. See https://github.com/davidgiven/cpm65
|
||||
|
||||
It runs on an Apple IIe with 80 columns.
|
||||
To run use the preconfigured model `cpm65`.
|
||||
|
||||
Usefull commands:
|
||||
|
||||
- `ìzapple -model cpm65` : To run the preconfigured setup
|
||||
- `izapple apple2e.po`: To use the disk apple2e.po to run any release from [cpm65 releases](https://github.com/davidgiven/cpm65/releases/tag/dev)
|
||||
- `ìzapple -model cpm65 -trace cpm65` : To trace the BDOS calls, skipping the console related calls
|
||||
- `ìzapple -model cpm65 -trace cpm65full` : To trace all the BDOS calls.
|
||||
|
||||
Todo:
|
||||
- The address for the BIOS and BDOS entrypoints is hardwired. It should be extracted somehow from the running memory.
|
@@ -53,6 +53,7 @@ The available pre-configured models are:
|
||||
basis108: Basis 108
|
||||
cpm: Apple ][+ with CP/M
|
||||
cpm3: Apple //e with CP/M 3.0
|
||||
cpm65: Apple //e with CPM-65
|
||||
dos32: Apple ][ with 13 sectors disk adapter and DOS 3.2x
|
||||
swyft: swyft
|
||||
|
||||
@@ -83,7 +84,8 @@ The available cards are:
|
||||
|
||||
The available tracers are:
|
||||
cpm: Trace CPM BDOS calls
|
||||
cpm65: Trace CPM65 BDOS calls
|
||||
cpm65: Trace CPM65 BDOS calls skipping terminal IO
|
||||
cpm65full: Trace CPM65 BDOS calls
|
||||
cpu: Trace CPU execution
|
||||
mli: Trace ProDOS MLI calls
|
||||
mos: Trace MOS calls with Applecorn skipping terminal IO
|
||||
|
Binary file not shown.
@@ -74,9 +74,19 @@ func getTracerFactory() map[string]*traceBuilder {
|
||||
}
|
||||
tracerFactory["cpm65"] = &traceBuilder{
|
||||
name: "cpm65",
|
||||
description: "Trace CPM65 BDOS calls skipping terminal IO",
|
||||
executionTracer: newTraceCpm65(true),
|
||||
}
|
||||
tracerFactory["cpm65full"] = &traceBuilder{
|
||||
name: "cpm65full",
|
||||
description: "Trace CPM65 BDOS calls",
|
||||
executionTracer: newTraceCpm65(false),
|
||||
}
|
||||
tracerFactory["cpm"] = &traceBuilder{
|
||||
name: "cpm",
|
||||
description: "Trace CPM BDOS calls skipping terminal IO",
|
||||
executionTracer: newTraceCpm(true),
|
||||
}
|
||||
tracerFactory["cpm"] = &traceBuilder{
|
||||
name: "cpm",
|
||||
description: "Trace CPM BDOS calls",
|
||||
@@ -109,6 +119,8 @@ func setupTracers(a *Apple2, paramString string) error {
|
||||
if builder.executionTracer != nil {
|
||||
a.addTracer(builder.executionTracer)
|
||||
}
|
||||
|
||||
fmt.Printf("Tracer %s enabled\n", builder.name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -15,7 +15,8 @@ type traceCpm65 struct {
|
||||
}
|
||||
|
||||
const (
|
||||
cpm65BdosEntrypoint uint16 = 0x0804 // start-3, not really sure about this
|
||||
cpm65BdosEntrypoint uint16 = 0xeb8f // TODO: find the correct address dinamically
|
||||
cpm65BiosEntrypoint uint16 = 0xfdce // TODO: find the correct address dinamically
|
||||
)
|
||||
|
||||
func newTraceCpm65(skipConsole bool) *traceCpm65 {
|
||||
@@ -40,15 +41,26 @@ func (t *traceCpm65) inspect() {
|
||||
switch regY {
|
||||
case 2: // CONSOLE_OUTPUT
|
||||
if !t.skipConsole {
|
||||
fmt.Printf("CPM65 BDOS call $%02x:%s from $%04x with \"%c\"\n", regY, bdos65CodeToName(regY), pc, regA)
|
||||
fmt.Printf("CPM65 BDOS call %02v:%s with \"%c\"\n", regY, bdos65CodeToName(regY), regA)
|
||||
}
|
||||
case 9: // WRITE_STRING
|
||||
if !t.skipConsole {
|
||||
text := t.getCpm65String(param)
|
||||
fmt.Printf("CPM65 BDOS call $%02x:%s from $%04x with \"%s\"\n", regY, bdos65CodeToName(regY), pc, text)
|
||||
fmt.Printf("CPM65 BDOS call %02v:%s with \"%s\"\n", regY, bdos65CodeToName(regY), text)
|
||||
}
|
||||
default:
|
||||
fmt.Printf("CPM65 BDOS call $%02x:%s from $%04x\n", regY, bdos65CodeToName(regY), pc)
|
||||
fmt.Printf("CPM65 BDOS call %02v:%s($%04x)\n", regY, bdos65CodeToName(regY), param)
|
||||
}
|
||||
}
|
||||
|
||||
if pc == cpm65BiosEntrypoint {
|
||||
regA, regX, regY, _ := t.a.cpu.GetAXYP()
|
||||
param := uint16(regX)<<8 | uint16(regA)
|
||||
if regY > 2 /*CONOUT*/ || !t.skipConsole {
|
||||
switch regY {
|
||||
default:
|
||||
fmt.Printf("CPM65 BIOS call %02v:%s($%04x)\n", regY, bios65CodeToName(regY), param)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,6 +109,26 @@ var cpm65BdosNames = []string{
|
||||
"WRITE_RANDOM_FILLED", // 40
|
||||
"GETZP", // 41
|
||||
"GETTPA", // 42
|
||||
"PARSE_FILENAME", // 43
|
||||
}
|
||||
|
||||
var cpm65BiosNames = []string{
|
||||
"CONST", // 0
|
||||
"CONIN", // 1
|
||||
"CONOUT", // 2
|
||||
"SELDSK", // 3
|
||||
"SETSEC", // 4
|
||||
"SETDMA", // 5
|
||||
"READ", // 6
|
||||
"WRITE", // 7
|
||||
"RELOCATE", // 8
|
||||
"GETTPA", // 9
|
||||
"SETTPA", // 10
|
||||
"GETZP", // 11
|
||||
"SETZP", // 12
|
||||
"SETBANK", // 13
|
||||
"ADDDRV", // 14
|
||||
"FINDDRV", // 15
|
||||
}
|
||||
|
||||
func bdos65CodeToName(code uint8) string {
|
||||
@@ -106,11 +138,18 @@ func bdos65CodeToName(code uint8) string {
|
||||
return fmt.Sprintf("BDOS_%d", code)
|
||||
}
|
||||
|
||||
func bios65CodeToName(code uint8) string {
|
||||
if code < uint8(len(cpm65BiosNames)) {
|
||||
return cpm65BiosNames[code]
|
||||
}
|
||||
return fmt.Sprintf("BIOS_%d", code)
|
||||
}
|
||||
|
||||
func (t *traceCpm65) getCpm65String(address uint16) string {
|
||||
s := ""
|
||||
for {
|
||||
ch := t.a.mmu.Peek(address)
|
||||
if ch == '$' {
|
||||
if ch == '$' || ch == 0 {
|
||||
break
|
||||
}
|
||||
s += string(ch)
|
||||
|
Reference in New Issue
Block a user