More Apple //e softswitches

This commit is contained in:
Ivan Izaguirre 2019-11-04 00:23:03 +01:00 committed by Iván Izaguirre
parent 3660e0ae98
commit 09117fd7c5
8 changed files with 160 additions and 166 deletions

View File

@ -8,7 +8,6 @@ import (
// newApple2 instantiates an apple2 // newApple2 instantiates an apple2
func newApple2plus() *Apple2 { func newApple2plus() *Apple2 {
var a Apple2 var a Apple2
a.Name = "Apple ][+" a.Name = "Apple ][+"
a.mmu = newMemoryManager(&a) a.mmu = newMemoryManager(&a)
@ -20,12 +19,12 @@ func newApple2plus() *Apple2 {
} }
func newApple2e() *Apple2 { func newApple2e() *Apple2 {
var a Apple2 var a Apple2
a.Name = "Apple IIe" a.Name = "Apple IIe"
a.mmu = newMemoryManager(&a) a.mmu = newMemoryManager(&a)
a.cpu = core6502.NewCMOS65c02(a.mmu) a.cpu = core6502.NewCMOS65c02(a.mmu)
a.io = newIoC0Page(&a) a.io = newIoC0Page(&a)
a.mmu.InitRAMalt()
addApple2SoftSwitches(a.io) addApple2SoftSwitches(a.io)
addApple2ESoftSwitches(a.io) addApple2ESoftSwitches(a.io)
@ -33,12 +32,12 @@ func newApple2e() *Apple2 {
} }
func newApple2eEnhanced() *Apple2 { func newApple2eEnhanced() *Apple2 {
var a Apple2 var a Apple2
a.Name = "Apple //e" a.Name = "Apple //e"
a.mmu = newMemoryManager(&a) a.mmu = newMemoryManager(&a)
a.cpu = core6502.NewCMOS65c02(a.mmu) a.cpu = core6502.NewCMOS65c02(a.mmu)
a.io = newIoC0Page(&a) a.io = newIoC0Page(&a)
a.mmu.InitRAMalt()
addApple2SoftSwitches(a.io) addApple2SoftSwitches(a.io)
addApple2ESoftSwitches(a.io) addApple2ESoftSwitches(a.io)

View File

@ -90,7 +90,7 @@ func MainApple() *Apple2 {
) )
model := flag.String( model := flag.String(
"model", "model",
"2e", "2enh",
"set base model. Models available 2plus, 2e, 2enh, base64a", "set base model. Models available 2plus, 2e, 2enh, base64a",
) )
profile := flag.Bool( profile := flag.Bool(

View File

@ -1,8 +1,6 @@
package main package main
import ( import (
"fmt"
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
) )
@ -98,7 +96,6 @@ func (j *sdlJoysticks) ReadButton(i int) bool {
case 2: case 2:
value = j.button[3] || j.keys[2] value = j.button[3] || j.keys[2]
} }
fmt.Printf("Button %v: %v.\n", i, value)
return value return value
} }

View File

@ -1,6 +1,8 @@
package apple2 package apple2
import ( import (
"fmt"
"github.com/ivanizag/apple2/core6502" "github.com/ivanizag/apple2/core6502"
) )
@ -22,6 +24,45 @@ func newBase64a() *Apple2 {
return &a return &a
} }
const (
// There are 6 ROM chips. Each can have 4Kb or 8Kb. They can fill
// 2 or 4 banks with 2kb windows.
base64aRomBankSize = 12 * 1024
base64aRomBankCount = 4
base64aRomWindowSize = 2 * 1024
base64aRomChipCount = 6
)
func loadBase64aRom(a *Apple2) error {
// Load the 6 PROM dumps
romBanksBytes := make([][]uint8, base64aRomBankCount)
for j := range romBanksBytes {
romBanksBytes[j] = make([]uint8, 0, base64aRomBankSize)
}
for i := 0; i < base64aRomChipCount; i++ {
filename := fmt.Sprintf("<internal>/BASE64A_%X.BIN", 0xd0+i*0x08)
data, err := loadResource(filename)
if err != nil {
return err
}
for j := range romBanksBytes {
start := (j * base64aRomWindowSize) % len(data)
romBanksBytes[j] = append(romBanksBytes[j], data[start:start+base64aRomWindowSize]...)
}
}
// Create banks
for j := range romBanksBytes {
a.mmu.physicalROM[j] = newMemoryRange(0xd000, romBanksBytes[j])
}
// Start with first bank active
a.mmu.setActiveROMPage(0)
return nil
}
func addBase64aSoftSwitches(io *ioC0Page) { func addBase64aSoftSwitches(io *ioC0Page) {
// Other softswitches, not implemented but called from the ROM // Other softswitches, not implemented but called from the ROM
io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW, "80COLOFF") io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW, "80COLOFF")
@ -32,6 +73,30 @@ func addBase64aSoftSwitches(io *ioC0Page) {
io.addSoftSwitchW(0x30, func(io *ioC0Page, value uint8) { io.addSoftSwitchW(0x30, func(io *ioC0Page, value uint8) {
speakerSoftSwitch(io) speakerSoftSwitch(io)
}, "SPEAKER") }, "SPEAKER")
// ROM pagination softswitches. They use the annunciator 0 and 1
mmu := io.apple2.mmu
io.addSoftSwitchRW(0x58, func(*ioC0Page) uint8 {
p := mmu.getActiveROMPage()
mmu.setActiveROMPage(p & 2)
return 0
}, "ANN0OFF-ROM")
io.addSoftSwitchRW(0x59, func(*ioC0Page) uint8 {
p := mmu.getActiveROMPage()
mmu.setActiveROMPage(p | 1)
return 0
}, "ANN0ON-ROM")
io.addSoftSwitchRW(0x5A, func(*ioC0Page) uint8 {
p := mmu.getActiveROMPage()
mmu.setActiveROMPage(p & 1)
return 0
}, "ANN1OFF-ROM")
io.addSoftSwitchRW(0x5B, func(*ioC0Page) uint8 {
p := mmu.getActiveROMPage()
mmu.setActiveROMPage(p | 2)
return 0
}, "ANN1ON-ROM")
} }
func charGenColumnsMapBase64a(column int) int { func charGenColumnsMapBase64a(column int) int {

View File

@ -1,70 +0,0 @@
package apple2
import (
"fmt"
)
/*
Copam BASE64A uses paginated ROM
*/
const (
// There are 6 ROM chips. Each can have 4Kb or 8Kb. They can fill
// 2 or 4 banks with 2kb windows.
base64aRomBankSize = 12 * 1024
base64aRomBankCount = 4
base64aRomWindowSize = 2 * 1024
base64aRomChipCount = 6
)
func loadBase64aRom(a *Apple2) error {
// Load the 6 PROM dumps
romBanksBytes := make([][]uint8, base64aRomBankCount)
for j := range romBanksBytes {
romBanksBytes[j] = make([]uint8, 0, base64aRomBankSize)
}
for i := 0; i < base64aRomChipCount; i++ {
filename := fmt.Sprintf("<internal>/BASE64A_%X.BIN", 0xd0+i*0x08)
data, err := loadResource(filename)
if err != nil {
return err
}
for j := range romBanksBytes {
start := (j * base64aRomWindowSize) % len(data)
romBanksBytes[j] = append(romBanksBytes[j], data[start:start+base64aRomWindowSize]...)
}
}
// Create banks
for j := range romBanksBytes {
a.mmu.physicalROM[j] = newMemoryRange(0xd000, romBanksBytes[j])
}
// Start with first bank active
a.mmu.setActiveROMPage(0)
// Add rom soft switches. They use the annunciator 0 and 1
a.io.addSoftSwitchRW(0x58, func(*ioC0Page) uint8 {
p := a.mmu.getActiveROMPage()
a.mmu.setActiveROMPage(p & 2)
return 0
}, "ANN0OFF-ROM")
a.io.addSoftSwitchRW(0x59, func(*ioC0Page) uint8 {
p := a.mmu.getActiveROMPage()
a.mmu.setActiveROMPage(p | 1)
return 0
}, "ANN0ON-ROM")
a.io.addSoftSwitchRW(0x5A, func(*ioC0Page) uint8 {
p := a.mmu.getActiveROMPage()
a.mmu.setActiveROMPage(p & 1)
return 0
}, "ANN1OFF-ROM")
a.io.addSoftSwitchRW(0x5B, func(*ioC0Page) uint8 {
p := a.mmu.getActiveROMPage()
a.mmu.setActiveROMPage(p | 2)
return 0
}, "ANN1ON-ROM")
return nil
}

View File

@ -47,8 +47,12 @@ func (c *cardLanguage) assign(a *Apple2, slot int) {
c.writeState = lcWriteEnabled c.writeState = lcWriteEnabled
c.altBank = true c.altBank = true
a.mmu.initLanguageRAM(1) if a.isApple2e {
// The Apple //e with 128kb has two blocks of language upper RAM
a.mmu.initLanguageRAM(2)
} else {
a.mmu.initLanguageRAM(1)
}
for i := uint8(0x0); i <= 0xf; i++ { for i := uint8(0x0); i <= 0xf; i++ {
iCopy := i iCopy := i
c.addCardSoftSwitchR(iCopy, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(iCopy, func(*ioC0Page) uint8 {

View File

@ -2,7 +2,6 @@ package apple2
import ( import (
"encoding/binary" "encoding/binary"
"fmt"
"io" "io"
) )
@ -27,23 +26,27 @@ type memoryManager struct {
physicalDAltRAM []memoryHandler // 0xd000 to 0xdfff, 4KB. Up to 8 banks. physicalDAltRAM []memoryHandler // 0xd000 to 0xdfff, 4KB. Up to 8 banks.
physicalEFRAM []memoryHandler // 0xe000 to 0xffff, 8KB. Up to 8 banks. physicalEFRAM []memoryHandler // 0xe000 to 0xffff, 8KB. Up to 8 banks.
// Pages prapared for optional card ROM banks in 0xc800 to 0xcfff // Configuration switches, Language cards
altMainRAMActiveRead bool // Use extra RAM on the 128KB Apple2e for read
altMainRAMActiveWrite bool // Use extra RAM on the 128KB Apple2e for write
c3ROMActive bool // Apple2e slot 3 ROM shadow
cxROMActive bool // Apple2e slots ROM shadow
activeSlot uint8 // Active slot owner of 0xc800 to 0xcfff
lcSelectedBlock uint8 // Language card block selected. Usually, allways 0. But Saturn has 8 lcSelectedBlock uint8 // Language card block selected. Usually, allways 0. But Saturn has 8
lcActiveRead bool // Upper RAM active for read lcActiveRead bool // Upper RAM active for read
lcActiveWrite bool // Upper RAM active for read lcActiveWrite bool // Upper RAM active for read
lcAltBank bool // Alternate lcAltBank bool // Alternate
romPage uint8 // Active ROM page
// Configuration switches, Apple //e
altZeroPage bool // Use extra RAM from 0x0000 to 0x01ff. And additional language card block
altMainRAMActiveRead bool // Use extra RAM from 0x0200 to 0xbfff for read
altMainRAMActiveWrite bool // Use extra RAM from 0x0200 to 0xbfff for write
c3ROMActive bool // Apple2e slot 3 ROM shadow
cxROMActive bool // Apple2e slots ROM shadow
activeSlot uint8 // Active slot owner of 0xc800 to 0xcfff
// Configuration switches, Base64A
romPage uint8 // Active ROM page
} }
const ( const (
ioC8Off uint16 = 0xcfff ioC8Off uint16 = 0xcfff
addressLimitZero uint16 = 0x01ff
addressLimitMainRAM uint16 = 0xbfff addressLimitMainRAM uint16 = 0xbfff
addressLimitIO uint16 = 0xc0ff addressLimitIO uint16 = 0xc0ff
addressLimitSlots uint16 = 0xc7ff addressLimitSlots uint16 = 0xc7ff
@ -59,14 +62,20 @@ type memoryHandler interface {
func newMemoryManager(a *Apple2) *memoryManager { func newMemoryManager(a *Apple2) *memoryManager {
var mmu memoryManager var mmu memoryManager
mmu.apple2 = a mmu.apple2 = a
mmu.physicalMainRAM = newMemoryRange(0, make([]uint8, 0xc000))
ram := make([]uint8, 0xc000) // Reserve 48kb
mmu.physicalMainRAM = newMemoryRange(0, ram)
return &mmu return &mmu
} }
func (mmu *memoryManager) accessRead(address uint16) memoryHandler { func (mmu *memoryManager) accessRead(address uint16) memoryHandler {
// First two pages
if address <= addressLimitZero {
if mmu.altZeroPage {
return mmu.physicalMainRAMAlt
}
return mmu.physicalMainRAM
}
// Main RAM area // Main RAM area
if address <= addressLimitMainRAM { if address <= addressLimitMainRAM {
if mmu.altMainRAMActiveRead { if mmu.altMainRAMActiveRead {
@ -104,13 +113,17 @@ func (mmu *memoryManager) accessRead(address uint16) memoryHandler {
// Upper address area // Upper address area
if mmu.lcActiveRead { if mmu.lcActiveRead {
block := mmu.lcSelectedBlock
if mmu.altZeroPage {
block = 1
}
if address <= addressLimitDArea { if address <= addressLimitDArea {
if mmu.lcAltBank { if mmu.lcAltBank {
return mmu.physicalDAltRAM[mmu.lcSelectedBlock] return mmu.physicalDAltRAM[block]
} }
return mmu.physicalDRAM[mmu.lcSelectedBlock] return mmu.physicalDRAM[block]
} }
return mmu.physicalEFRAM[mmu.lcSelectedBlock] return mmu.physicalEFRAM[block]
} }
// Use ROM // Use ROM
@ -118,6 +131,14 @@ func (mmu *memoryManager) accessRead(address uint16) memoryHandler {
} }
func (mmu *memoryManager) accessWrite(address uint16) memoryHandler { func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
// First two pages
if address <= addressLimitZero {
if mmu.altZeroPage {
return mmu.physicalMainRAMAlt
}
return mmu.physicalMainRAM
}
// Main RAM area // Main RAM area
if address <= addressLimitMainRAM { if address <= addressLimitMainRAM {
if mmu.altMainRAMActiveWrite { if mmu.altMainRAMActiveWrite {
@ -149,13 +170,17 @@ func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
// Upper address area // Upper address area
if mmu.lcActiveWrite { if mmu.lcActiveWrite {
block := mmu.lcSelectedBlock
if mmu.altZeroPage {
block = 1
}
if address <= addressLimitDArea { if address <= addressLimitDArea {
if mmu.lcAltBank { if mmu.lcAltBank {
return mmu.physicalDAltRAM[mmu.lcSelectedBlock] return mmu.physicalDAltRAM[block]
} }
return mmu.physicalDRAM[mmu.lcSelectedBlock] return mmu.physicalDRAM[block]
} }
return mmu.physicalEFRAM[mmu.lcSelectedBlock] return mmu.physicalEFRAM[block]
} }
// Use ROM // Use ROM
@ -166,7 +191,7 @@ func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
func (mmu *memoryManager) Peek(address uint16) uint8 { func (mmu *memoryManager) Peek(address uint16) uint8 {
mh := mmu.accessRead(address) mh := mmu.accessRead(address)
if mh == nil { if mh == nil {
fmt.Printf("Reading void addressing 0x%x\n", address) //fmt.Printf("Reading void addressing 0x%x\n", address)
return 0xf4 // Or some random number return 0xf4 // Or some random number
} }
return mh.peek(address) return mh.peek(address)
@ -176,7 +201,7 @@ func (mmu *memoryManager) Peek(address uint16) uint8 {
func (mmu *memoryManager) Poke(address uint16, value uint8) { func (mmu *memoryManager) Poke(address uint16, value uint8) {
mh := mmu.accessWrite(address) mh := mmu.accessWrite(address)
if mh == nil { if mh == nil {
fmt.Printf("Writing to void addressing 0x%x\n", address) //fmt.Printf("Writing to void addressing 0x%x\n", address)
return return
} }
mh.poke(address, value) mh.poke(address, value)
@ -202,6 +227,10 @@ func (mmu *memoryManager) initLanguageRAM(groups int) {
} }
} }
func (mmu *memoryManager) InitRAMalt() {
mmu.physicalMainRAMAlt = newMemoryRange(0, make([]uint8, 0xc000))
}
// Memory configuration // Memory configuration
func (mmu *memoryManager) setActiveROMPage(page uint8) { func (mmu *memoryManager) setActiveROMPage(page uint8) {
mmu.romPage = page mmu.romPage = page

View File

@ -6,38 +6,25 @@ package apple2
*/ */
const ( const (
ioFlagRamRd uint8 = 0x13 ioFlag80Store uint8 = 0x18
ioFlagRamWrt uint8 = 0x14 ioFlagAltChar uint8 = 0x1E
ioFlagIntCxRom uint8 = 0x15 ioFlag80Col uint8 = 0x1F
ioFlagAltZp uint8 = 0x16
ioFlagSlotC3Rom uint8 = 0x17
ioFlag80Store uint8 = 0x18
ioFlagAltChar uint8 = 0x1E
ioFlag80Col uint8 = 0x1F
// ??? ioVertBlank uin8 = 0x19 // ??? ioVertBlank uin8 = 0x19
) )
func addApple2ESoftSwitches(io *ioC0Page) { func addApple2ESoftSwitches(io *ioC0Page) {
// New MMU read softswithes // New MMU read softswithes
io.addSoftSwitchW(0x02, getSoftSwitchExt(ioFlagRamRd, ssOff, nil), "RAMRDOFF") mmu := io.apple2.mmu
io.addSoftSwitchW(0x03, getSoftSwitchExt(ioFlagRamWrt, ssOn, nil), "RAMRDON") addSoftSwitchesMmu(io, 0x02, 0x03, 0x13, &mmu.altMainRAMActiveRead, "RAMRD")
io.addSoftSwitchR(0x13, getStatusSoftSwitch(ioFlagRamWrt), "RAMRD") addSoftSwitchesMmu(io, 0x04, 0x05, 0x14, &mmu.altMainRAMActiveWrite, "RAMWRT")
addSoftSwitchesMmu(io, 0x06, 0x07, 0x15, &mmu.cxROMActive, "INTCXROM")
addSoftSwitchesMmu(io, 0x08, 0x09, 0x16, &mmu.altZeroPage, "ALTZP")
addSoftSwitchesMmu(io, 0x0a, 0x0b, 0x17, &mmu.c3ROMActive, "SLOTC3ROM")
io.addSoftSwitchW(0x04, getSoftSwitchExt(ioFlagRamWrt, ssOff, nil), "RAMWRTOFF") // New IOU read softswithes
io.addSoftSwitchW(0x05, getSoftSwitchExt(ioFlagRamWrt, ssOn, nil), "RAMWRTON") addSoftSwitchesIou(io, 0x00, 0x01, 0x18, ioFlag80Store, "80STORE")
io.addSoftSwitchR(0x14, getStatusSoftSwitch(ioFlagRamWrt), "RAMWRT") addSoftSwitchesIou(io, 0x0c, 0x0d, 0x1f, ioFlag80Col, "80COL")
addSoftSwitchesIou(io, 0x0e, 0x0f, 0x1e, ioFlagAltChar, "ALTCHARSET")
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 // Previous read softswithes
io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText), "TEXT") io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText), "TEXT")
@ -45,19 +32,6 @@ func addApple2ESoftSwitches(io *ioC0Page) {
io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage), "PAGE2") io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage), "PAGE2")
io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes), "HIRES") io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes), "HIRES")
// New IOU read softswithes
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: // TOOD:
// AKD read on 0x10 // AKD read on 0x10
// VBL read on 0x19 // VBL read on 0x19
@ -66,37 +40,33 @@ func addApple2ESoftSwitches(io *ioC0Page) {
} }
type softSwitchExtAction func(io *ioC0Page) func addSoftSwitchesMmu(io *ioC0Page, addressClear uint8, addressSet uint8, AddressGet uint8, flag *bool, name string) {
io.addSoftSwitchW(addressClear, func(_ *ioC0Page, _ uint8) {
*flag = false
}, name+"OFF")
func getSoftSwitchExt(ioFlag uint8, dstValue uint8, action softSwitchExtAction) softSwitchW { io.addSoftSwitchW(addressSet, func(_ *ioC0Page, _ uint8) {
return func(io *ioC0Page, _ uint8) { *flag = true
currentValue := io.softSwitchesData[ioFlag] }, name+"ON")
if currentValue == dstValue {
return // Already switched, ignore io.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 {
if *flag {
return ssOn
} }
if action != nil { return ssOff
action(io) }, name)
}
io.softSwitchesData[ioFlag] = dstValue
}
} }
func softSwitchIntCxRomOn(io *ioC0Page) { func addSoftSwitchesIou(io *ioC0Page, addressClear uint8, addressSet uint8, AddressGet uint8, ioFlag uint8, name string) {
//io.apple2.mmu.setPagesRead(0xc1, 0xcf, io.apple2.mmu.physicalROMe) io.addSoftSwitchW(addressClear, func(_ *ioC0Page, _ uint8) {
} io.softSwitchesData[ioFlag] = ssOff
}, name+"OFF")
func softSwitchIntCxRomOff(io *ioC0Page) { io.addSoftSwitchW(addressSet, func(_ *ioC0Page, _ uint8) {
// TODO restore all the ROM from the slots for 0xc1 to 0xc7 io.softSwitchesData[ioFlag] = ssOn
//io.apple2.mmu.setPages(0xc1, 0xc7, nil) }, name+"ON")
}
func softSwitchSlotC3RomOn(io *ioC0Page) { io.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 {
// TODO restore the slot 3 ROM return io.softSwitchesData[ioFlag]
//io.apple2.mmu.setPages(0xc3, 0xc3, nil) }, name)
} }
func softSwitchSlotC3RomOff(io *ioC0Page) {
//io.apple2.mmu.setPagesRead(0xc3, 0xc3, io.apple2.mmu.physicalROMe)
}
// TODO: apply state after persistance load