mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-23 00:30:21 +00:00
MOS return values
This commit is contained in:
parent
95b9d3ef05
commit
b270c1c55b
@ -211,6 +211,15 @@ func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
|
|||||||
return mmu.physicalROM[mmu.romPage]
|
return mmu.physicalROM[mmu.romPage]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mmu *memoryManager) peekWord(address uint16) uint16 {
|
||||||
|
return uint16(mmu.Peek(address)) +
|
||||||
|
uint16(mmu.Peek(address+1))<<8
|
||||||
|
|
||||||
|
//return uint16(mmu.Peek(address)) +
|
||||||
|
// 0x100*uint16(mmu.Peek(address+1))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Peek returns the data on the given address
|
// Peek returns the data on the given address
|
||||||
func (mmu *memoryManager) Peek(address uint16) uint8 {
|
func (mmu *memoryManager) Peek(address uint16) uint8 {
|
||||||
mh := mmu.accessRead(address)
|
mh := mmu.accessRead(address)
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
package izapple2
|
package izapple2
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
See:
|
See:
|
||||||
https://github.com/bobbimanners/Applecorn
|
https://github.com/bobbimanners/Applecorn
|
||||||
|
Chapter 45 https://raw.githubusercontent.com/bobbimanners/Applecorn/main/Manuals/Acorn%20BBC%20Micro%20User%20Guide.pdf
|
||||||
http://beebwiki.mdfs.net/Category:MOS_API
|
http://beebwiki.mdfs.net/Category:MOS_API
|
||||||
http://beebwiki.mdfs.net/OSBYTEs
|
http://beebwiki.mdfs.net/OSBYTEs
|
||||||
http://mdfs.net/Docs/Comp/BBC/Osbyte00
|
http://mdfs.net/Docs/Comp/BBC/Osbyte00
|
||||||
@ -15,10 +19,18 @@ type traceApplecorn struct {
|
|||||||
a *Apple2
|
a *Apple2
|
||||||
skipConsole bool
|
skipConsole bool
|
||||||
osbyteNames [256]string
|
osbyteNames [256]string
|
||||||
|
calls []mosCallData
|
||||||
|
}
|
||||||
|
|
||||||
|
type mosCallData struct {
|
||||||
|
caller uint16
|
||||||
|
api uint16
|
||||||
|
a, x, y uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
applecornMosVec uint16 = 0xffb9 // Start of the MOS entry points
|
applecornMosVec uint16 = 0xffb9 // Start of the MOS entry points
|
||||||
|
applecornNoCaller uint16 = 0xffff
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTraceApplecorn(a *Apple2, skipConsole bool) *traceApplecorn {
|
func newTraceApplecorn(a *Apple2, skipConsole bool) *traceApplecorn {
|
||||||
@ -35,20 +47,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, _ := t.a.cpu.GetPCAndSP()
|
pc, sp := t.a.cpu.GetPCAndSP()
|
||||||
if pc >= applecornMosVec {
|
if pc >= applecornMosVec {
|
||||||
regA, regX, regY := t.a.cpu.GetAXY()
|
regA, regX, regY := t.a.cpu.GetAXY()
|
||||||
s := ""
|
s := ""
|
||||||
|
|
||||||
if !t.skipConsole {
|
if !t.skipConsole {
|
||||||
switch pc {
|
switch pc {
|
||||||
case 0xffe0:
|
|
||||||
s = fmt.Sprintf("OSNEWL()")
|
|
||||||
case 0xffc8:
|
case 0xffc8:
|
||||||
ch := ""
|
ch := ""
|
||||||
if regA >= 0x20 && regA < 0x7f {
|
if regA >= 0x20 && regA < 0x7f {
|
||||||
@ -57,8 +66,14 @@ func (t *traceApplecorn) inspect() {
|
|||||||
s = fmt.Sprintf("OSNWRCH(A=%02x, '%v')", regA, ch)
|
s = fmt.Sprintf("OSNWRCH(A=%02x, '%v')", regA, ch)
|
||||||
case 0xffcb:
|
case 0xffcb:
|
||||||
s = fmt.Sprintf("OSNRDCH()")
|
s = fmt.Sprintf("OSNRDCH()")
|
||||||
case 0xffe7:
|
case 0xffe0:
|
||||||
s = fmt.Sprintf("OSRDCH()")
|
s = fmt.Sprintf("OSRDCH()")
|
||||||
|
//case 0xffe3: // This fallbacks to OSWRCH
|
||||||
|
// s = "OSASCI(?)"
|
||||||
|
//case 0xffe7: // This fallbacks to OSWRCH
|
||||||
|
// s = fmt.Sprintf("OSNEWL()")
|
||||||
|
//case 0xffec: // This fallbacks to OSWRCH
|
||||||
|
// s = fmt.Sprintf("OSNECR()")
|
||||||
case 0xffee:
|
case 0xffee:
|
||||||
ch := ""
|
ch := ""
|
||||||
if regA >= 0x20 && regA < 0x7f {
|
if regA >= 0x20 && regA < 0x7f {
|
||||||
@ -72,6 +87,8 @@ func (t *traceApplecorn) inspect() {
|
|||||||
switch pc {
|
switch pc {
|
||||||
case 0xffb9:
|
case 0xffb9:
|
||||||
s = "OSDRM(?)"
|
s = "OSDRM(?)"
|
||||||
|
case 0xffbc:
|
||||||
|
s = "VDUCHR(?)"
|
||||||
case 0xffbf:
|
case 0xffbf:
|
||||||
s = "OSEVEN(?)"
|
s = "OSEVEN(?)"
|
||||||
case 0xffc2:
|
case 0xffc2:
|
||||||
@ -90,18 +107,66 @@ func (t *traceApplecorn) inspect() {
|
|||||||
s = "OSARGS(?)"
|
s = "OSARGS(?)"
|
||||||
case 0xffdd:
|
case 0xffdd:
|
||||||
s = "OSFILE(?)"
|
s = "OSFILE(?)"
|
||||||
case 0xffe3:
|
|
||||||
s = "OSASCI(?)"
|
|
||||||
case 0xfff1:
|
case 0xfff1:
|
||||||
s = fmt.Sprintf("OSWORD(A=%02x,XY=%04x)", regA, uint16(regX)<<8+uint16(regY))
|
xy := uint16(regX) + uint16(regY)<<8
|
||||||
|
switch regA {
|
||||||
|
case 0: // Read line from input
|
||||||
|
lineAddress := t.a.mmu.peekWord(xy)
|
||||||
|
maxLength := t.a.mmu.Peek(xy + 2)
|
||||||
|
s = fmt.Sprintf("OSWORD('read line';A=%02x,XY=%04x,BUF=%04x,MAX=%02x)", regA, xy, lineAddress, maxLength)
|
||||||
|
default:
|
||||||
|
s = fmt.Sprintf("OSWORD(A=%02x,XY=%04x)", regA, xy)
|
||||||
|
}
|
||||||
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 s == "" && !(pc >= 0xffe3 && pc < 0xffee) {
|
||||||
|
// s = "UNKNOWN(?)"
|
||||||
|
//}
|
||||||
|
|
||||||
if s != "" {
|
if s != "" {
|
||||||
fmt.Printf("BBC MOS call to $%04x %s\n", pc, s)
|
caller := t.a.mmu.peekWord(0x100+uint16(sp+1)) + 1
|
||||||
|
t.calls = append(t.calls, mosCallData{caller, pc, regA, regX, regY})
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(t.calls) > 0 && pc == t.calls[len(t.calls)-1].caller {
|
||||||
|
// Returning from the call
|
||||||
|
regA, regX, regY := t.a.cpu.GetAXY()
|
||||||
|
call := t.calls[len(t.calls)-1]
|
||||||
|
s := ""
|
||||||
|
switch call.api {
|
||||||
|
case 0xfff1: // OSWORD
|
||||||
|
cbAddress := uint16(call.x) + uint16(call.y)<<8
|
||||||
|
switch call.a {
|
||||||
|
case 0: // Read line from input
|
||||||
|
lineAddress := t.a.mmu.peekWord(cbAddress)
|
||||||
|
line := t.getString(lineAddress, regY)
|
||||||
|
s = fmt.Sprintf(",line='%s'", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("=> (A=%02x,X=%02x,Y=%02x%s)\n", regA, regX, regY, s)
|
||||||
|
t.calls = t.calls[:len(t.calls)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *traceApplecorn) getString(address uint16, length uint8) string {
|
||||||
|
s := ""
|
||||||
|
for i := uint8(0); i < length; i++ {
|
||||||
|
ch := t.a.mmu.Peek(address + uint16(i))
|
||||||
|
s = s + string(ch)
|
||||||
|
}
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
@ -206,5 +206,5 @@ func (t *tracePascal) inspectPerArchitectureGuide() {
|
|||||||
func (t *tracePascal) param(index uint8) uint16 {
|
func (t *tracePascal) param(index uint8) uint16 {
|
||||||
_, sp := t.a.cpu.GetPCAndSP()
|
_, sp := t.a.cpu.GetPCAndSP()
|
||||||
return uint16(t.a.mmu.Peek(0x100+uint16(sp+index))) +
|
return uint16(t.a.mmu.Peek(0x100+uint16(sp+index))) +
|
||||||
uint16(t.a.mmu.Peek(0x100+uint16(sp+index+1)))<<8 - 2
|
uint16(t.a.mmu.Peek(0x100+uint16(sp+index+1)))<<8 - 2 // ??
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user