mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-01-21 23:29:46 +00:00
Experimental cards: Logger and InOut
This commit is contained in:
parent
684c8f7172
commit
8233b99e43
@ -39,9 +39,10 @@ func (a *Apple2) Run(log bool) {
|
||||
// Start the processor
|
||||
a.cpu.Reset()
|
||||
referenceTime := time.Now()
|
||||
|
||||
for {
|
||||
// Run a 6502 step
|
||||
a.cpu.ExecuteInstruction(log)
|
||||
a.cpu.ExecuteInstruction(log && a.cycleDurationNs != 0)
|
||||
|
||||
// Execute meta commands
|
||||
commandsPending := true
|
||||
@ -80,6 +81,8 @@ const (
|
||||
CommandSaveState
|
||||
// CommandLoadState reload the last state
|
||||
CommandLoadState
|
||||
// CommandDumpDebugInfo dumps usefull info
|
||||
CommandDumpDebugInfo
|
||||
)
|
||||
|
||||
// SendCommand enqueues a command to the emulator thread
|
||||
@ -105,6 +108,8 @@ func (a *Apple2) executeCommand(command int) {
|
||||
case CommandLoadState:
|
||||
fmt.Println("Loading state")
|
||||
a.load("apple2.state")
|
||||
case CommandDumpDebugInfo:
|
||||
a.dumpDebugInfo()
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,3 +177,19 @@ func (a *Apple2) load(filename string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Apple2) dumpDebugInfo() {
|
||||
// See "Apple II Monitors Peeled"
|
||||
pageZeroSymbols := map[int]string{
|
||||
0x36: "CSWL",
|
||||
0x37: "CSWH",
|
||||
0x38: "KSWL",
|
||||
0x39: "KSWH",
|
||||
}
|
||||
|
||||
fmt.Printf("Page zero values:\n")
|
||||
for _, k := range []int{0x36, 0x37, 0x38, 0x39} {
|
||||
d := a.mmu.physicalMainRAM.data[k]
|
||||
fmt.Printf(" %v(0x%x): 0x%02x\n", pageZeroSymbols[k], k, d)
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,16 @@ func (a *Apple2) AddSaturnCard(slot int) {
|
||||
a.insertCard(&cardSaturn{}, slot)
|
||||
}
|
||||
|
||||
// AddCardLogger inserts a fake card that logs accesses
|
||||
func (a *Apple2) AddCardLogger(slot int) {
|
||||
a.insertCard(&cardLogger{}, slot)
|
||||
}
|
||||
|
||||
// AddCardInOut inserts a fake card that interfaces with the emulator host
|
||||
func (a *Apple2) AddCardInOut(slot int) {
|
||||
a.insertCard(&cardInOut{}, slot)
|
||||
}
|
||||
|
||||
// ConfigureStdConsole uses stdin and stdout to interface with the Apple2
|
||||
func (a *Apple2) ConfigureStdConsole(stdinKeyboard bool, stdoutScreen bool) {
|
||||
if !stdinKeyboard && !stdoutScreen {
|
||||
|
147
apple2/cardInOut.go
Normal file
147
apple2/cardInOut.go
Normal file
@ -0,0 +1,147 @@
|
||||
package apple2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/*
|
||||
In out card experiment to interface with the emulator host.
|
||||
|
||||
See:
|
||||
"Apple II Monitors peeled."
|
||||
http://mysite.du.edu/~etuttle/math/acia.htm
|
||||
|
||||
*/
|
||||
|
||||
type cardInOut struct {
|
||||
cardBase
|
||||
i int
|
||||
}
|
||||
|
||||
func (c *cardInOut) assign(a *Apple2, slot int) {
|
||||
for i := 0x0; i <= 0xf; i++ {
|
||||
iCopy := i
|
||||
c.ssr[i] = func(*ioC0Page) uint8 {
|
||||
value := []uint8{0xc1, 0xc1, 0x93, 0x0}[c.i%4]
|
||||
c.i++
|
||||
fmt.Printf("[cardInOut] Read access to softswith 0x%x for slot %v, value %x.\n", iCopy, slot, value)
|
||||
//return 0x41 + 0x80
|
||||
return []uint8{0x41, 0x41, 0x13}[i%3] + 0x80
|
||||
}
|
||||
c.ssw[i] = func(_ *ioC0Page, value uint8) {
|
||||
fmt.Printf("[cardInOut] Write access to softswith 0x%x for slot %v, value 0x%x.\n", iCopy, slot, value)
|
||||
}
|
||||
}
|
||||
|
||||
in := true
|
||||
out := false
|
||||
|
||||
data := [256]uint8{
|
||||
// Register
|
||||
0xA9, 0xC2,
|
||||
0x85, 0x37,
|
||||
0x85, 0x39,
|
||||
0xA9, 0x10,
|
||||
0x85, 0x36,
|
||||
0xA9, 0x15,
|
||||
0x85, 0x38,
|
||||
0x60, 0xEA,
|
||||
|
||||
// Out char
|
||||
0x8D, 0xA1, 0xC0,
|
||||
0x60, 0xEA,
|
||||
|
||||
// Get char
|
||||
0x91, 0x28,
|
||||
0xAD, 0xA0, 0xC0,
|
||||
0x60,
|
||||
}
|
||||
|
||||
if !out {
|
||||
// NOP the CSWL,H change
|
||||
for _, v := range []uint8{2, 3, 8, 9} {
|
||||
data[v] = 0xEA
|
||||
}
|
||||
}
|
||||
|
||||
if !in {
|
||||
// NOP the KSWL,H change
|
||||
for _, v := range []uint8{4, 5, 12, 13} {
|
||||
data[v] = 0xEA
|
||||
}
|
||||
}
|
||||
|
||||
c.rom = newMemoryRange(0xC200, data[0:255])
|
||||
|
||||
if slot != 2 {
|
||||
// To make ifwork on other slots, patch C2, A0 and A1
|
||||
panic("Only slot 2 supported for the InOut card")
|
||||
}
|
||||
c.cardBase.assign(a, slot)
|
||||
}
|
||||
|
||||
/*
|
||||
The ROM code was assembled using https://www.masswerk.at/6502/assembler.html
|
||||
|
||||
src:
|
||||
BASL = $28
|
||||
CSWL = $36
|
||||
CSWH = $37
|
||||
KSWL = $38
|
||||
KSWH = $39
|
||||
|
||||
* = $C200
|
||||
Register:
|
||||
LDA #$C2
|
||||
STA *CSWH
|
||||
STA *KSWH
|
||||
LDA #$10
|
||||
STA *CSWL
|
||||
LDA #$15
|
||||
STA *KSWL
|
||||
RTS
|
||||
NOP
|
||||
OutChar:
|
||||
STA $C0A1
|
||||
RTS
|
||||
NOP
|
||||
GetChar:
|
||||
STA (BASL),Y
|
||||
LDA $C0A0
|
||||
RTS
|
||||
|
||||
|
||||
assembled as:
|
||||
0000 BASL = 0028
|
||||
0000 CSWL = 0036
|
||||
0000 CSWH = 0037
|
||||
0000 KSWL = 0038
|
||||
0000 KSWH = 0039
|
||||
|
||||
* = $C200
|
||||
C200 REGIST
|
||||
C200 LDA #$C2 A9 C2
|
||||
C202 STA *CSWH 85 37
|
||||
C204 STA *KSWH 85 39
|
||||
C206 LDA #$10 A9 10
|
||||
C208 STA *CSWL 85 36
|
||||
C20A LDA #$15 A9 15
|
||||
C20C STA *KSWL 85 38
|
||||
C20E RTS 60
|
||||
C20F NOP EA
|
||||
C210 OUTCHA
|
||||
C210 STA $C0A1 8D A1 C0
|
||||
C213 RTS 60
|
||||
C214 NOP EA
|
||||
C215 GETCHA
|
||||
C215 STA (BASL),Y 91 28
|
||||
C217 LDA $C0A0 AD A0 C0
|
||||
C21A RTS
|
||||
|
||||
object code:
|
||||
A9 C2 85 37 85 39 A9 10
|
||||
85 36 A9 15 85 38 60 EA
|
||||
8D A1 C0 60 EA 91 28 AD
|
||||
A0 C0 60
|
||||
|
||||
*/
|
43
apple2/cardLogger.go
Normal file
43
apple2/cardLogger.go
Normal file
@ -0,0 +1,43 @@
|
||||
package apple2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/*
|
||||
Logger card. It never existed, I use it to trace accesses to the card.
|
||||
*/
|
||||
|
||||
type cardLogger struct {
|
||||
cardBase
|
||||
}
|
||||
|
||||
func (c *cardLogger) assign(a *Apple2, slot int) {
|
||||
for i := 0x0; i <= 0xf; i++ {
|
||||
iCopy := i
|
||||
c.ssr[i] = func(*ioC0Page) uint8 {
|
||||
fmt.Printf("[cardLogger] Read access to softswith 0x%x for slot %v.\n", iCopy, slot)
|
||||
return 0
|
||||
}
|
||||
c.ssw[i] = func(_ *ioC0Page, value uint8) {
|
||||
fmt.Printf("[cardLogger] Write access to softswith 0x%x for slot %v, value 0x%v.\n", iCopy, slot, value)
|
||||
}
|
||||
}
|
||||
|
||||
if slot != 0 {
|
||||
a.mmu.setPagesRead(uint8(0xc0+slot), uint8(0xc0+slot), c)
|
||||
}
|
||||
c.cardBase.assign(a, slot)
|
||||
}
|
||||
|
||||
// MemoryHandler implementation
|
||||
func (c *cardLogger) peek(address uint16) uint8 {
|
||||
fmt.Printf("[cardLogger] Read in %x.\n", address)
|
||||
c.a.dumpDebugInfo()
|
||||
|
||||
return 0xf3
|
||||
}
|
||||
|
||||
func (*cardLogger) poke(address uint16, value uint8) {
|
||||
fmt.Printf("[cardLogger] Write %x in %x.\n", value, address)
|
||||
}
|
@ -97,6 +97,8 @@ func (k *sdlKeyboard) putKey(keyEvent *sdl.KeyboardEvent) {
|
||||
k.a.SendCommand(apple2.CommandSaveState)
|
||||
case sdl.K_F8:
|
||||
k.a.SendCommand(apple2.CommandLoadState)
|
||||
case sdl.K_F9:
|
||||
k.a.SendCommand(apple2.CommandDumpDebugInfo)
|
||||
}
|
||||
|
||||
// Missing values 91 to 95. Usually control for [\]^_
|
||||
|
Loading…
x
Reference in New Issue
Block a user