Nanmed sotfswitches for easier traces.

This commit is contained in:
Ivan Izaguirre 2019-10-21 00:00:42 +02:00 committed by Iván Izaguirre
parent 61dae23726
commit d5433ad8d9
13 changed files with 181 additions and 137 deletions

View File

@ -26,15 +26,15 @@ func newBase64a() *Apple2 {
}
func addBase64aSoftSwitches(io *ioC0Page) {
// Other softswitches
io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW) // 80 columns off?
io.addSoftSwitchW(0x0E, notImplementedSoftSwitchW) // Alt char off?
// Other softswitches, not implemented but called from the ROM
io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW, "80COLOFF")
io.addSoftSwitchW(0x0E, notImplementedSoftSwitchW, "ALTCHARSETOFF")
// Write on the speaker. That is a double access and should do nothing
// but works somehow on the BASE64A
io.addSoftSwitchW(0x30, func(io *ioC0Page, value uint8) {
speakerSoftSwitch(io)
})
}, "SPEAKER")
}
func charGenColumnsMapBase64a(column int) int {

View File

@ -55,19 +55,19 @@ func loadBase64aRom(a *Apple2) error {
a.io.addSoftSwitchRW(0x58, func(*ioC0Page) uint8 {
r.changeBank(a.mmu, r.romBank&2)
return 0
})
}, "ANN0OFF-ROM")
a.io.addSoftSwitchRW(0x59, func(*ioC0Page) uint8 {
r.changeBank(a.mmu, r.romBank|1)
return 0
})
}, "ANN0ON-ROM")
a.io.addSoftSwitchRW(0x5A, func(*ioC0Page) uint8 {
r.changeBank(a.mmu, r.romBank&1)
return 0
})
}, "ANN1OFF-ROM")
a.io.addSoftSwitchRW(0x5B, func(*ioC0Page) uint8 {
r.changeBank(a.mmu, r.romBank|2)
return 0
})
}, "ANN1ON-ROM")
return nil
}

View File

@ -15,8 +15,10 @@ type cardBase struct {
rom *memoryRange
romExtra *memoryRange
slot int
ssr [16]softSwitchR
ssw [16]softSwitchW
_ssr [16]softSwitchR
_ssw [16]softSwitchW
_ssrName [16]string
_sswName [16]string
}
func (c *cardBase) loadRom(data []uint8) {
@ -45,11 +47,21 @@ func (c *cardBase) assign(a *Apple2, slot int) {
}
for i := 0; i < 0x10; i++ {
a.io.addSoftSwitchR(uint8(0xC80+slot*0x10+i), c.ssr[i])
a.io.addSoftSwitchW(uint8(0xC80+slot*0x10+i), c.ssw[i])
a.io.addSoftSwitchR(uint8(0xC80+slot*0x10+i), c._ssr[i], c._ssrName[i])
a.io.addSoftSwitchW(uint8(0xC80+slot*0x10+i), c._ssw[i], c._sswName[i])
}
}
func (c *cardBase) addCardSoftSwitchR(address uint8, ss softSwitchR, name string) {
c._ssr[address] = ss
c._ssrName[address] = name
}
func (c *cardBase) addCardSoftSwitchW(address uint8, ss softSwitchW, name string) {
c._ssw[address] = ss
c._sswName[address] = name
}
func (c *cardBase) save(w io.Writer) error {
// Empty
return nil

View File

@ -2,6 +2,7 @@ package apple2
import (
"encoding/binary"
"fmt"
"io"
)
@ -33,7 +34,7 @@ type cardDisk2 struct {
type cardDisk2Drive struct {
diskette *diskette16sector
currentPhase int
currentPhase uint8
power bool // q4
halfTrack int
position int
@ -50,12 +51,13 @@ const (
func (c *cardDisk2) assign(a *Apple2, slot int) {
// Q1, Q2, Q3 and Q4 phase control soft switches,
for i := 0; i < 4; i++ {
for i := uint8(0); i < 4; i++ {
phase := i
c.ssr[phase<<1] = func(_ *ioC0Page) uint8 {
c.addCardSoftSwitchR(phase<<1, func(_ *ioC0Page) uint8 {
return c.dataLatch // All even addresses return the last dataLatch
}
c.ssr[(phase<<1)+1] = func(_ *ioC0Page) uint8 {
}, fmt.Sprintf("PHASE%vOFF", phase))
c.addCardSoftSwitchR((phase<<1)+1, func(_ *ioC0Page) uint8 {
// Move the head up or down depending on the previous phase.
drive := &c.drive[c.selected]
delta := (phase - drive.currentPhase + 4) % 4
@ -79,50 +81,50 @@ func (c *cardDisk2) assign(a *Apple2, slot int) {
drive.currentPhase = phase
//fmt.Printf("DISKII: Current halftrack is %v\n", drive.halfTrack)
return 0
}
}, fmt.Sprintf("PHASE%vOFF", phase))
}
// Q4, power switch
c.ssr[0x8] = func(_ *ioC0Page) uint8 {
c.addCardSoftSwitchR(0x8, func(_ *ioC0Page) uint8 {
if c.drive[c.selected].power {
c.drive[c.selected].power = false
c.a.releaseFastMode()
}
return c.dataLatch
}
c.ssr[0x9] = func(_ *ioC0Page) uint8 {
}, "Q4DRIVEOFF")
c.addCardSoftSwitchR(0x9, func(_ *ioC0Page) uint8 {
if !c.drive[c.selected].power {
c.drive[c.selected].power = true
c.a.requestFastMode()
}
return 0
}
}, "")
// Q5, drive selecion
c.ssr[0xA] = func(_ *ioC0Page) uint8 {
c.addCardSoftSwitchR(0xA, func(_ *ioC0Page) uint8 {
c.selected = 0
return c.dataLatch
}
c.ssr[0xB] = func(_ *ioC0Page) uint8 {
}, "Q5SELECT1")
c.addCardSoftSwitchR(0xB, func(_ *ioC0Page) uint8 {
c.selected = 1
return 0
}
}, "Q5SELECT2")
// Q6, Q7
for i := 0xC; i <= 0xF; i++ {
for i := uint8(0xC); i <= 0xF; i++ {
iCopy := i
c.ssr[iCopy] = func(_ *ioC0Page) uint8 {
c.addCardSoftSwitchR(iCopy, func(_ *ioC0Page) uint8 {
return c.softSwitchQ6Q7(iCopy, 0)
}
c.ssw[iCopy] = func(_ *ioC0Page, value uint8) {
}, "Q6Q7")
c.addCardSoftSwitchW(iCopy, func(_ *ioC0Page, value uint8) {
c.softSwitchQ6Q7(iCopy, value)
}
}, "Q6Q7")
}
c.cardBase.assign(a, slot)
}
func (c *cardDisk2) softSwitchQ6Q7(index int, in uint8) uint8 {
func (c *cardDisk2) softSwitchQ6Q7(index uint8, in uint8) uint8 {
switch index {
case 0xC: // Q6L
c.q6 = false

View File

@ -77,7 +77,7 @@ const (
)
func (c *cardHardDisk) assign(a *Apple2, slot int) {
c.ssr[0] = func(*ioC0Page) uint8 {
c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 {
// Prodos entry point
command := a.mmu.Peek(0x42)
@ -99,15 +99,15 @@ func (c *cardHardDisk) assign(a *Apple2, slot int) {
// Prodos device command not supported
return proDosDeviceErrorIO
}
}
c.ssr[1] = func(*ioC0Page) uint8 {
}, "HDCOMMAND")
c.addCardSoftSwitchR(1, func(*ioC0Page) uint8 {
// Blocks available, low byte
return uint8(c.disk.header.Blocks)
}
c.ssr[2] = func(*ioC0Page) uint8 {
}, "HDBLOCKSLO")
c.addCardSoftSwitchR(2, func(*ioC0Page) uint8 {
// Blocks available, high byte
return uint8(c.disk.header.Blocks >> 8)
}
}, "HDBLOCKHI")
c.cardBase.assign(a, slot)
}

View File

@ -19,18 +19,18 @@ type cardInOut struct {
}
func (c *cardInOut) assign(a *Apple2, slot int) {
for i := 0x0; i <= 0xf; i++ {
for i := uint8(0x0); i <= 0xf; i++ {
iCopy := i
c.ssr[i] = func(*ioC0Page) uint8 {
c.addCardSoftSwitchR(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) {
}, "INOUTR")
c.addCardSoftSwitchW(i, func(_ *ioC0Page, value uint8) {
fmt.Printf("[cardInOut] Write access to softswith 0x%x for slot %v, value 0x%x.\n", iCopy, slot, value)
}
}, "INOUTW")
}
in := true

View File

@ -31,8 +31,8 @@ and selects the second 4K bank to map $D000-$DFFF."
type cardLanguage struct {
cardBase
readState bool
writeState int
activeBank int
writeState uint8
activeBank uint8
ramBankA *memoryRange // First 4kb to map in 0xD000-0xDFFF
ramBankB *memoryRange // Second 4kb to map in 0xD000-0xDFFF
ramUpper *memoryRange // Upper 8kb to map in 0xE000-0xFFFF
@ -54,22 +54,22 @@ func (c *cardLanguage) assign(a *Apple2, slot int) {
c.ramBankB = newMemoryRange(0xd000, make([]uint8, 0x1000))
c.ramUpper = newMemoryRange(0xe000, make([]uint8, 0x2000))
for i := 0x0; i <= 0xf; i++ {
for i := uint8(0x0); i <= 0xf; i++ {
iCopy := i
c.ssr[iCopy] = func(*ioC0Page) uint8 {
c.addCardSoftSwitchR(iCopy, func(*ioC0Page) uint8 {
c.ssAction(iCopy, false)
return 0
}
c.ssw[iCopy] = func(*ioC0Page, uint8) {
}, "LANGCARDR")
c.addCardSoftSwitchW(iCopy, func(*ioC0Page, uint8) {
c.ssAction(iCopy, true)
}
}, "LANGCARDW")
}
c.cardBase.assign(a, slot)
c.applyState()
}
func (c *cardLanguage) ssAction(ss int, write bool) {
func (c *cardLanguage) ssAction(ss uint8, write bool) {
c.activeBank = (ss >> 3) & 1
action := ss & 0x3
switch action {

View File

@ -13,15 +13,15 @@ type cardLogger struct {
}
func (c *cardLogger) assign(a *Apple2, slot int) {
for i := 0x0; i <= 0xf; i++ {
for i := uint8(0x0); i <= 0xf; i++ {
iCopy := i
c.ssr[i] = func(*ioC0Page) uint8 {
c.addCardSoftSwitchR(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) {
}, "LOGGERR")
c.addCardSoftSwitchW(i, func(_ *ioC0Page, value uint8) {
fmt.Printf("[cardLogger] Write access to softswith 0x%x for slot %v, value 0x%v.\n", iCopy, slot, value)
}
}, "LOGGERW")
}
if slot != 0 {

View File

@ -16,9 +16,9 @@ http://www.applelogic.org/files/SATURN128MAN.pdf
type cardSaturn struct {
cardBase
readState bool
writeState int
activeBank int
activeBlock int
writeState uint8
activeBank uint8
activeBlock uint8
ramBankA [saturnBlocks]*memoryRange // First 4kb to map in 0xD000-0xDFFF
ramBankB [saturnBlocks]*memoryRange // Second 4kb to map in 0xD000-0xDFFF
ramUpper [saturnBlocks]*memoryRange // Upper 8kb to map in 0xE000-0xFFFF
@ -45,21 +45,21 @@ func (c *cardSaturn) assign(a *Apple2, slot int) {
c.ramBankB[i] = newMemoryRange(0xd000, make([]uint8, 0x1000))
c.ramUpper[i] = newMemoryRange(0xe000, make([]uint8, 0x2000))
}
for i := 0x0; i <= 0xf; i++ {
for i := uint8(0x0); i <= 0xf; i++ {
iCopy := i
c.ssr[iCopy] = func(*ioC0Page) uint8 {
c.addCardSoftSwitchR(iCopy, func(*ioC0Page) uint8 {
c.ssAction(iCopy, false)
return 0
}
c.ssw[iCopy] = func(*ioC0Page, uint8) {
}, "SATURNR")
c.addCardSoftSwitchW(iCopy, func(*ioC0Page, uint8) {
c.ssAction(iCopy, true)
}
}, "SATURNW")
}
c.cardBase.assign(a, slot)
c.applyState()
}
func (c *cardSaturn) ssAction(ss int, write bool) {
func (c *cardSaturn) ssAction(ss uint8, write bool) {
switch ss {
case 0:
// RAM read, no writes

View File

@ -25,16 +25,16 @@ type cardThunderClockPlus struct {
}
func (c *cardThunderClockPlus) assign(a *Apple2, slot int) {
c.ssr[0] = func(*ioC0Page) uint8 {
c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 {
bit := c.microPD1990ac.out()
// Get the next data bit from uPD1990AC on the MSB
if bit {
return 0x80
}
return 0
}
}, "THUNDERCLOCKR")
c.ssw[0] = func(_ *ioC0Page, value uint8) {
c.addCardSoftSwitchW(0, func(_ *ioC0Page, value uint8) {
dataIn := (value & 0x01) == 1
clock := ((value >> 1) & 0x01) == 1
strobe := ((value >> 2) & 0x01) == 1
@ -43,7 +43,7 @@ func (c *cardThunderClockPlus) assign(a *Apple2, slot int) {
dataIn, clock, strobe, command) */
c.microPD1990ac.in(clock, strobe, command, dataIn)
}
}, "THUNDERCLOCKW")
c.cardBase.assign(a, slot)
}

View File

@ -9,6 +9,8 @@ import (
type ioC0Page struct {
softSwitchesR [256]softSwitchR
softSwitchesW [256]softSwitchW
softSwitchesRName [256]string
softSwitchesWName [256]string
softSwitchesData [128]uint8
keyboard KeyboardProvider
speaker SpeakerProvider
@ -69,25 +71,27 @@ func (p *ioC0Page) load(r io.Reader) error {
return binary.Read(r, binary.BigEndian, &p.softSwitchesData)
}
func (p *ioC0Page) addSoftSwitchRW(address uint8, ss softSwitchR) {
p.addSoftSwitchR(address, ss)
func (p *ioC0Page) addSoftSwitchRW(address uint8, ss softSwitchR, name string) {
p.addSoftSwitchR(address, ss, name)
p.addSoftSwitchW(address, func(p *ioC0Page, _ uint8) {
ss(p)
})
}, name)
}
func (p *ioC0Page) addSoftSwitchR(address uint8, ss softSwitchR) {
func (p *ioC0Page) addSoftSwitchR(address uint8, ss softSwitchR, name string) {
//if p.softSwitchesR[address] != nil {
// fmt.Printf("Addresss 0x0c%02x is already assigned for read\n", address)
//}
p.softSwitchesR[address] = ss
p.softSwitchesRName[address] = name
}
func (p *ioC0Page) addSoftSwitchW(address uint8, ss softSwitchW) {
func (p *ioC0Page) addSoftSwitchW(address uint8, ss softSwitchW, name string) {
//if p.softSwitchesW[address] != nil {
// fmt.Printf("Addresss 0x0c%02x is already assigned for write\n", address)
//}
p.softSwitchesW[address] = ss
p.softSwitchesWName[address] = name
}
func (p *ioC0Page) isSoftSwitchActive(ioFlag uint8) bool {
@ -116,16 +120,14 @@ func (p *ioC0Page) peek(address uint16) uint8 {
return 0
}
value := ss(p)
if p.trace {
fmt.Printf("Softswitch peek on $%04x: $%02x\n", address, value)
if p.trace && address != 0xc000 {
name := p.softSwitchesRName[pageAddress]
fmt.Printf("Softswitch peek on $%04x %v: $%02x\n", address, name, value)
}
return value
}
func (p *ioC0Page) poke(address uint16, value uint8) {
if p.trace {
fmt.Printf("Softswtich poke on $%04x with %02x\n", address, value)
}
pageAddress := uint8(address)
ss := p.softSwitchesW[pageAddress]
if ss == nil {
@ -134,5 +136,9 @@ func (p *ioC0Page) poke(address uint16, value uint8) {
}
return
}
if p.trace && address != 0xc000 {
name := p.softSwitchesWName[pageAddress]
fmt.Printf("Softswitch poke on $%04x %v with $%02x\n", address, name, value)
}
ss(p, value)
}

View File

@ -24,53 +24,53 @@ const (
func addApple2SoftSwitches(io *ioC0Page) {
io.addSoftSwitchRW(0x00, keySoftSwitch) // Keyboard
io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch) // Keyboard Strobe
io.addSoftSwitchR(0x20, notImplementedSoftSwitchR) // Cassette Output
io.addSoftSwitchR(0x30, speakerSoftSwitch) // Speaker
io.addSoftSwitchR(0x40, notImplementedSoftSwitchR) // Game connector Strobe
io.addSoftSwitchRW(0x00, keySoftSwitch, "KEYBOARD") // Keyboard
io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch, "AKD") // Keyboard Strobe
io.addSoftSwitchR(0x20, notImplementedSoftSwitchR, "TAPEOUT") // Cassette Output
io.addSoftSwitchR(0x30, speakerSoftSwitch, "SPEAKER") // Speaker
io.addSoftSwitchR(0x40, notImplementedSoftSwitchR, "STROBE") // Game connector Strobe
// Note: Some sources indicate that all these cover 16 positions
// for read and write. But the Apple2e take over some of them, with
// the prevention on acting only on writes.
io.addSoftSwitchRW(0x50, getSoftSwitch(ioFlagText, false))
io.addSoftSwitchRW(0x51, getSoftSwitch(ioFlagText, true))
io.addSoftSwitchRW(0x52, getSoftSwitch(ioFlagMixed, false))
io.addSoftSwitchRW(0x53, getSoftSwitch(ioFlagMixed, true))
io.addSoftSwitchRW(0x54, getSoftSwitch(ioFlagSecondPage, false))
io.addSoftSwitchRW(0x55, getSoftSwitch(ioFlagSecondPage, true))
io.addSoftSwitchRW(0x56, getSoftSwitch(ioFlagHiRes, false))
io.addSoftSwitchRW(0x57, getSoftSwitch(ioFlagHiRes, true))
io.addSoftSwitchRW(0x50, getSoftSwitch(ioFlagText, false), "TEXTOFF")
io.addSoftSwitchRW(0x51, getSoftSwitch(ioFlagText, true), "TEXTON")
io.addSoftSwitchRW(0x52, getSoftSwitch(ioFlagMixed, false), "MIXEDOFF")
io.addSoftSwitchRW(0x53, getSoftSwitch(ioFlagMixed, true), "MIXEDON")
io.addSoftSwitchRW(0x54, getSoftSwitch(ioFlagSecondPage, false), "PAGE2OFF")
io.addSoftSwitchRW(0x55, getSoftSwitch(ioFlagSecondPage, true), "PAGE2ON")
io.addSoftSwitchRW(0x56, getSoftSwitch(ioFlagHiRes, false), "HIRESOFF")
io.addSoftSwitchRW(0x57, getSoftSwitch(ioFlagHiRes, true), "HIRESON")
io.addSoftSwitchRW(0x58, getSoftSwitch(ioFlagAnnunciator0, false))
io.addSoftSwitchRW(0x59, getSoftSwitch(ioFlagAnnunciator0, true))
io.addSoftSwitchRW(0x5a, getSoftSwitch(ioFlagAnnunciator1, false))
io.addSoftSwitchRW(0x5b, getSoftSwitch(ioFlagAnnunciator1, true))
io.addSoftSwitchRW(0x5c, getSoftSwitch(ioFlagAnnunciator2, false))
io.addSoftSwitchRW(0x5d, getSoftSwitch(ioFlagAnnunciator2, true))
io.addSoftSwitchRW(0x5e, getSoftSwitch(ioFlagAnnunciator3, false))
io.addSoftSwitchRW(0x5f, getSoftSwitch(ioFlagAnnunciator3, true))
io.addSoftSwitchRW(0x58, getSoftSwitch(ioFlagAnnunciator0, false), "ANN0OFF")
io.addSoftSwitchRW(0x59, getSoftSwitch(ioFlagAnnunciator0, true), "ANN0ON")
io.addSoftSwitchRW(0x5a, getSoftSwitch(ioFlagAnnunciator1, false), "ANN1OFF")
io.addSoftSwitchRW(0x5b, getSoftSwitch(ioFlagAnnunciator1, true), "ANN1ON")
io.addSoftSwitchRW(0x5c, getSoftSwitch(ioFlagAnnunciator2, false), "ANN2OFF")
io.addSoftSwitchRW(0x5d, getSoftSwitch(ioFlagAnnunciator2, true), "ANN2ON")
io.addSoftSwitchRW(0x5e, getSoftSwitch(ioFlagAnnunciator3, false), "ANN3OFF")
io.addSoftSwitchRW(0x5f, getSoftSwitch(ioFlagAnnunciator3, true), "ANN3ON")
io.addSoftSwitchR(0x60, notImplementedSoftSwitchR) // Cassette Input
io.addSoftSwitchR(0x61, getButtonSoftSwitch(0))
io.addSoftSwitchR(0x62, getButtonSoftSwitch(1))
io.addSoftSwitchR(0x63, getButtonSoftSwitch(2))
io.addSoftSwitchR(0x64, getPaddleSoftSwitch(0))
io.addSoftSwitchR(0x65, getPaddleSoftSwitch(1))
io.addSoftSwitchR(0x66, getPaddleSoftSwitch(2))
io.addSoftSwitchR(0x67, getPaddleSoftSwitch(3))
io.addSoftSwitchR(0x60, notImplementedSoftSwitchR, "CASSETTE") // Cassette Input
io.addSoftSwitchR(0x61, getButtonSoftSwitch(0), "PB0")
io.addSoftSwitchR(0x62, getButtonSoftSwitch(1), "PB1")
io.addSoftSwitchR(0x63, getButtonSoftSwitch(2), "PB2")
io.addSoftSwitchR(0x64, getPaddleSoftSwitch(0), "PDL0")
io.addSoftSwitchR(0x65, getPaddleSoftSwitch(1), "PDL1")
io.addSoftSwitchR(0x66, getPaddleSoftSwitch(2), "PDL2")
io.addSoftSwitchR(0x67, getPaddleSoftSwitch(3), "PDL3")
// The previous 8 softswitches are repeated
io.addSoftSwitchR(0x68, notImplementedSoftSwitchR) // Cassette Input
io.addSoftSwitchR(0x69, getButtonSoftSwitch(0))
io.addSoftSwitchR(0x6A, getButtonSoftSwitch(1))
io.addSoftSwitchR(0x6B, getButtonSoftSwitch(2))
io.addSoftSwitchR(0x6C, getPaddleSoftSwitch(0))
io.addSoftSwitchR(0x6D, getPaddleSoftSwitch(1))
io.addSoftSwitchR(0x6E, getPaddleSoftSwitch(2))
io.addSoftSwitchR(0x6F, getPaddleSoftSwitch(3))
io.addSoftSwitchR(0x68, notImplementedSoftSwitchR, "CASSETTE") // Cassette Input
io.addSoftSwitchR(0x69, getButtonSoftSwitch(0), "PB0")
io.addSoftSwitchR(0x6A, getButtonSoftSwitch(1), "PB1")
io.addSoftSwitchR(0x6B, getButtonSoftSwitch(2), "PB2")
io.addSoftSwitchR(0x6C, getPaddleSoftSwitch(0), "PDL0")
io.addSoftSwitchR(0x6D, getPaddleSoftSwitch(1), "PDL1")
io.addSoftSwitchR(0x6E, getPaddleSoftSwitch(2), "PDL2")
io.addSoftSwitchR(0x6F, getPaddleSoftSwitch(3), "PDL3")
io.addSoftSwitchR(0x70, strobePaddlesSoftSwitch) // Game controllers reset
io.addSoftSwitchR(0x70, strobePaddlesSoftSwitch, "RESETPDL") // Game controllers reset
}
func notImplementedSoftSwitchR(*ioC0Page) uint8 {

View File

@ -1,38 +1,62 @@
package apple2
/*
See:
https://www.apple.asimov.net/documentation/hardware/machines/APPLE%20IIe%20Auxiliary%20Memory%20Softswitches.pdf
*/
const (
ioFlagRamRd uint8 = 0x13
ioFlagRamWrt uint8 = 0x14
ioFlagIntCxRom uint8 = 0x15
ioFlagAltZp uint8 = 0x16
ioFlagSlotC3Rom uint8 = 0x17
ioFlag80Store uint8 = 0x18
ioFlagAltChar uint8 = 0x19
ioFlagAltChar uint8 = 0x1E
ioFlag80Col uint8 = 0x1F
// ??? ioVertBlank uin8 = 0x19
)
func addApple2ESoftSwitches(io *ioC0Page) {
// New MMU read softswithes
io.addSoftSwitchW(0x06, getSoftSwitchExt(ioFlagIntCxRom, ssOff, softSwitchIntCxRomOff))
io.addSoftSwitchW(0x07, getSoftSwitchExt(ioFlagIntCxRom, ssOn, softSwitchIntCxRomOn))
io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagIntCxRom))
io.addSoftSwitchW(0x0A, getSoftSwitchExt(ioFlagSlotC3Rom, ssOff, softSwitchSlotC3RomOff))
io.addSoftSwitchW(0x0B, getSoftSwitchExt(ioFlagSlotC3Rom, ssOn, softSwitchSlotC3RomOn))
io.addSoftSwitchR(0x17, getStatusSoftSwitch(ioFlagSlotC3Rom))
io.addSoftSwitchW(0x02, getSoftSwitchExt(ioFlagRamRd, ssOff, nil), "RAMRDOFF")
io.addSoftSwitchW(0x03, getSoftSwitchExt(ioFlagRamWrt, ssOn, nil), "RAMRDON")
io.addSoftSwitchR(0x13, getStatusSoftSwitch(ioFlagRamWrt), "RAMRD")
io.addSoftSwitchW(0x04, getSoftSwitchExt(ioFlagRamWrt, ssOff, nil), "RAMWRTOFF")
io.addSoftSwitchW(0x05, getSoftSwitchExt(ioFlagRamWrt, ssOn, nil), "RAMWRTON")
io.addSoftSwitchR(0x14, getStatusSoftSwitch(ioFlagRamWrt), "RAMWRT")
io.addSoftSwitchW(0x06, getSoftSwitchExt(ioFlagIntCxRom, ssOff, softSwitchIntCxRomOff), "INTCXROMOFF")
io.addSoftSwitchW(0x07, getSoftSwitchExt(ioFlagIntCxRom, ssOn, softSwitchIntCxRomOn), "INTCXROMON")
io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagIntCxRom), "INTCXROM")
io.addSoftSwitchW(0x08, getSoftSwitchExt(ioFlagAltZp, ssOff, nil), "ALTZPOFF")
io.addSoftSwitchW(0x09, getSoftSwitchExt(ioFlagAltZp, ssOn, nil), "ALTZPON")
io.addSoftSwitchR(0x16, getStatusSoftSwitch(ioFlagAltZp), "ALTZP")
io.addSoftSwitchW(0x0A, getSoftSwitchExt(ioFlagSlotC3Rom, ssOff, softSwitchSlotC3RomOff), "SLOTC3ROMOFF")
io.addSoftSwitchW(0x0B, getSoftSwitchExt(ioFlagSlotC3Rom, ssOn, softSwitchSlotC3RomOn), "SLOTC3ROMON")
io.addSoftSwitchR(0x17, getStatusSoftSwitch(ioFlagSlotC3Rom), "SLOTC3ROM")
// Previous read softswithes
io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText))
io.addSoftSwitchR(0x1B, getStatusSoftSwitch(ioFlagMixed))
io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage))
io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes))
io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText), "TEXT")
io.addSoftSwitchR(0x1B, getStatusSoftSwitch(ioFlagMixed), "MIXED")
io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage), "PAGE2")
io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes), "HIRES")
// New IOU read softswithes
io.addSoftSwitchW(0x00, getSoftSwitchExt(ioFlag80Store, ssOff, nil))
io.addSoftSwitchW(0x01, getSoftSwitchExt(ioFlag80Store, ssOn, nil))
io.addSoftSwitchR(0x18, getStatusSoftSwitch(ioFlag80Store))
io.addSoftSwitchW(0x0C, getSoftSwitchExt(ioFlag80Col, ssOff, nil))
io.addSoftSwitchW(0x0D, getSoftSwitchExt(ioFlag80Col, ssOn, nil))
io.addSoftSwitchR(0x1F, getStatusSoftSwitch(ioFlag80Col))
io.addSoftSwitchW(0x0E, getSoftSwitchExt(ioFlagAltChar, ssOff, nil))
io.addSoftSwitchW(0x0F, getSoftSwitchExt(ioFlagAltChar, ssOn, nil))
io.addSoftSwitchR(0x1E, getStatusSoftSwitch(ioFlagAltChar))
io.addSoftSwitchW(0x00, getSoftSwitchExt(ioFlag80Store, ssOff, nil), "80STOREOFF")
io.addSoftSwitchW(0x01, getSoftSwitchExt(ioFlag80Store, ssOn, nil), "80STOREON")
io.addSoftSwitchR(0x18, getStatusSoftSwitch(ioFlag80Store), "80STORE")
io.addSoftSwitchW(0x0C, getSoftSwitchExt(ioFlag80Col, ssOff, nil), "80COLOFF")
io.addSoftSwitchW(0x0D, getSoftSwitchExt(ioFlag80Col, ssOn, nil), "80COLON")
io.addSoftSwitchR(0x1F, getStatusSoftSwitch(ioFlag80Col), "80COL")
io.addSoftSwitchW(0x0E, getSoftSwitchExt(ioFlagAltChar, ssOff, nil), "ALTCHARSETOFF")
io.addSoftSwitchW(0x0F, getSoftSwitchExt(ioFlagAltChar, ssOn, nil), "ALTCHARSETON")
io.addSoftSwitchR(0x1E, getStatusSoftSwitch(ioFlagAltChar), "ALTCHARSET")
// TOOD:
// AKD read on 0x10