Simplify softswitches

This commit is contained in:
Iván Izaguirre 2022-08-05 19:43:17 +02:00
parent f2bc9f21aa
commit 9feded23f8
22 changed files with 196 additions and 190 deletions

View File

@ -58,33 +58,27 @@ func loadBase64aRom(a *Apple2) error {
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, buildNotImplementedSoftSwitchW(io), "80COLOFF")
io.addSoftSwitchW(0x0E, notImplementedSoftSwitchW, "ALTCHARSETOFF") io.addSoftSwitchW(0x0E, buildNotImplementedSoftSwitchW(io), "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")
// ROM pagination softswitches. They use the annunciator 0 and 1 // ROM pagination softswitches. They use the annunciator 0 and 1
mmu := io.apple2.mmu mmu := io.apple2.mmu
io.addSoftSwitchRW(0x58, func(*ioC0Page) uint8 { io.addSoftSwitchRW(0x58, func() uint8 {
p := mmu.getActiveROMPage() p := mmu.getActiveROMPage()
mmu.setActiveROMPage(p & 2) mmu.setActiveROMPage(p & 2)
return 0 return 0
}, "ANN0OFF-ROM") }, "ANN0OFF-ROM")
io.addSoftSwitchRW(0x59, func(*ioC0Page) uint8 { io.addSoftSwitchRW(0x59, func() uint8 {
p := mmu.getActiveROMPage() p := mmu.getActiveROMPage()
mmu.setActiveROMPage(p | 1) mmu.setActiveROMPage(p | 1)
return 0 return 0
}, "ANN0ON-ROM") }, "ANN0ON-ROM")
io.addSoftSwitchRW(0x5A, func(*ioC0Page) uint8 { io.addSoftSwitchRW(0x5A, func() uint8 {
p := mmu.getActiveROMPage() p := mmu.getActiveROMPage()
mmu.setActiveROMPage(p & 1) mmu.setActiveROMPage(p & 1)
return 0 return 0
}, "ANN1OFF-ROM") }, "ANN1OFF-ROM")
io.addSoftSwitchRW(0x5B, func(*ioC0Page) uint8 { io.addSoftSwitchRW(0x5B, func() uint8 {
p := mmu.getActiveROMPage() p := mmu.getActiveROMPage()
mmu.setActiveROMPage(p | 2) mmu.setActiveROMPage(p | 2)
return 0 return 0

View File

@ -118,23 +118,23 @@ func (c *cardBase) addCardSoftSwitchRW(address uint8, ss softSwitchR, name strin
c._ssr[address] = ss c._ssr[address] = ss
c._ssrName[address] = name c._ssrName[address] = name
c._ssw[address] = func(p *ioC0Page, _ uint8) { c._ssw[address] = func(uint8) {
ss(p) ss()
} }
c._sswName[address] = name c._sswName[address] = name
} }
type softSwitches func(io *ioC0Page, address uint8, data uint8, write bool) uint8 type softSwitches func(address uint8, data uint8, write bool) uint8
func (c *cardBase) addCardSoftSwitches(sss softSwitches, name string) { func (c *cardBase) addCardSoftSwitches(sss softSwitches, name string) {
for i := uint8(0x0); i <= 0xf; i++ { for i := uint8(0x0); i <= 0xf; i++ {
address := i address := i
c.addCardSoftSwitchR(address, func(io *ioC0Page) uint8 { c.addCardSoftSwitchR(address, func() uint8 {
return sss(io, address, 0, false) return sss(address, 0, false)
}, fmt.Sprintf("%v%XR", name, address)) }, fmt.Sprintf("%v%XR", name, address))
c.addCardSoftSwitchW(address, func(io *ioC0Page, value uint8) { c.addCardSoftSwitchW(address, func(value uint8) {
sss(io, address, value, true) sss(address, value, true)
}, fmt.Sprintf("%v%XW", name, address)) }, fmt.Sprintf("%v%XW", name, address))
} }
} }

View File

@ -80,7 +80,7 @@ func (c *CardDisk2) assign(a *Apple2, slot int) {
// Q1, Q2, Q3 and Q4 phase control soft switches, // Q1, Q2, Q3 and Q4 phase control soft switches,
for i := uint8(0); i < 4; i++ { for i := uint8(0); i < 4; i++ {
phase := i phase := i
c.addCardSoftSwitchR(phase<<1, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(phase<<1, func() uint8 {
// Update magnets and position // Update magnets and position
drive := &c.drive[c.selected] drive := &c.drive[c.selected]
drive.phases &^= (1 << phase) drive.phases &^= (1 << phase)
@ -93,7 +93,7 @@ func (c *CardDisk2) assign(a *Apple2, slot int) {
return c.dataLatch // All even addresses return the last dataLatch return c.dataLatch // All even addresses return the last dataLatch
}, fmt.Sprintf("PHASE%vOFF", phase)) }, fmt.Sprintf("PHASE%vOFF", phase))
c.addCardSoftSwitchR((phase<<1)+1, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR((phase<<1)+1, func() uint8 {
// Update magnets and position // Update magnets and position
drive := &c.drive[c.selected] drive := &c.drive[c.selected]
drive.phases |= (1 << phase) drive.phases |= (1 << phase)
@ -108,21 +108,21 @@ func (c *CardDisk2) assign(a *Apple2, slot int) {
} }
// Q4, power switch // Q4, power switch
c.addCardSoftSwitchR(0x8, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(0x8, func() uint8 {
c.softSwitchQ4(false) c.softSwitchQ4(false)
return c.dataLatch return c.dataLatch
}, "Q4DRIVEOFF") }, "Q4DRIVEOFF")
c.addCardSoftSwitchR(0x9, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(0x9, func() uint8 {
c.softSwitchQ4(true) c.softSwitchQ4(true)
return 0 return 0
}, "Q4DRIVEON") }, "Q4DRIVEON")
// Q5, drive selecion // Q5, drive selecion
c.addCardSoftSwitchR(0xA, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(0xA, func() uint8 {
c.softSwitchQ5(0) c.softSwitchQ5(0)
return c.dataLatch return c.dataLatch
}, "Q5SELECT1") }, "Q5SELECT1")
c.addCardSoftSwitchR(0xB, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(0xB, func() uint8 {
c.softSwitchQ5(1) c.softSwitchQ5(1)
return 0 return 0
}, "Q5SELECT2") }, "Q5SELECT2")
@ -130,10 +130,10 @@ func (c *CardDisk2) assign(a *Apple2, slot int) {
// Q6, Q7 // Q6, Q7
for i := uint8(0xC); i <= 0xF; i++ { for i := uint8(0xC); i <= 0xF; i++ {
iCopy := i iCopy := i
c.addCardSoftSwitchR(iCopy, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(iCopy, func() uint8 {
return c.softSwitchQ6Q7(iCopy, 0) return c.softSwitchQ6Q7(iCopy, 0)
}, "Q6Q7") }, "Q6Q7")
c.addCardSoftSwitchW(iCopy, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(iCopy, func(value uint8) {
c.softSwitchQ6Q7(iCopy, value) c.softSwitchQ6Q7(iCopy, value)
}, "Q6Q7") }, "Q6Q7")
} }

View File

@ -80,7 +80,7 @@ func (c *CardDisk2Sequencer) reset() {
} }
func (c *CardDisk2Sequencer) assign(a *Apple2, slot int) { func (c *CardDisk2Sequencer) assign(a *Apple2, slot int) {
c.addCardSoftSwitches(func(_ *ioC0Page, address uint8, data uint8, write bool) uint8 { c.addCardSoftSwitches(func(address uint8, data uint8, write bool) uint8 {
/* /*
Slot card pins to SN74LS259 latch mapping: Slot card pins to SN74LS259 latch mapping:
slot_address[3,2,1] => latch_address[2,1,0] slot_address[3,2,1] => latch_address[2,1,0]

View File

@ -42,7 +42,7 @@ const (
func (c *CardFastChip) assign(a *Apple2, slot int) { func (c *CardFastChip) assign(a *Apple2, slot int) {
// The softswitches are outside the card reserved ss // The softswitches are outside the card reserved ss
// Only writes are implemented to avoid conflicts with the joysticks // Only writes are implemented to avoid conflicts with the joysticks
a.io.addSoftSwitchW(0x6a, func(_ *ioC0Page, value uint8) { a.io.addSoftSwitchW(0x6a, func(value uint8) {
if value == fastChipUnlockToken { if value == fastChipUnlockToken {
c.unlockCounter++ c.unlockCounter++
if c.unlockCounter >= fastChipUnlockRepeats { if c.unlockCounter >= fastChipUnlockRepeats {
@ -55,25 +55,25 @@ func (c *CardFastChip) assign(a *Apple2, slot int) {
} }
}, "FASTCHIP-LOCK") }, "FASTCHIP-LOCK")
a.io.addSoftSwitchW(0x6b, func(_ *ioC0Page, _ uint8) { a.io.addSoftSwitchW(0x6b, func(uint8) {
if c.unlocked { if c.unlocked {
c.enabled = true c.enabled = true
} }
}, "FASTCHIP-ENABLE") }, "FASTCHIP-ENABLE")
a.io.addSoftSwitchW(0x6d, func(_ *ioC0Page, value uint8) { a.io.addSoftSwitchW(0x6d, func(value uint8) {
if c.enabled { if c.enabled {
c.setSpeed(a, value) c.setSpeed(a, value)
} }
}, "FASTCHIP-SPEED") }, "FASTCHIP-SPEED")
a.io.addSoftSwitchW(0x6e, func(_ *ioC0Page, value uint8) { a.io.addSoftSwitchW(0x6e, func(value uint8) {
if c.enabled { if c.enabled {
c.configRegister = value c.configRegister = value
} }
}, "FASTCHIP-CONFIG") }, "FASTCHIP-CONFIG")
a.io.addSoftSwitchW(0x6f, func(_ *ioC0Page, value uint8) { a.io.addSoftSwitchW(0x6f, func(value uint8) {
if c.enabled && c.configRegister == 0 { if c.enabled && c.configRegister == 0 {
c.setSpeed(a, value) c.setSpeed(a, value)
} }

View File

@ -73,7 +73,7 @@ const (
func (c *CardHardDisk) assign(a *Apple2, slot int) { func (c *CardHardDisk) assign(a *Apple2, slot int) {
c.loadRom(buildHardDiskRom(slot)) c.loadRom(buildHardDiskRom(slot))
c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(0, func() uint8 {
// Prodos entry point // Prodos entry point
command := a.mmu.Peek(0x42) command := a.mmu.Peek(0x42)
unit := a.mmu.Peek(0x43) unit := a.mmu.Peek(0x43)
@ -95,16 +95,16 @@ func (c *CardHardDisk) assign(a *Apple2, slot int) {
return proDosDeviceErrorIO return proDosDeviceErrorIO
} }
}, "HDCOMMAND") }, "HDCOMMAND")
c.addCardSoftSwitchR(1, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(1, func() uint8 {
// Blocks available, low byte // Blocks available, low byte
return uint8(c.disk.GetSizeInBlocks()) return uint8(c.disk.GetSizeInBlocks())
}, "HDBLOCKSLO") }, "HDBLOCKSLO")
c.addCardSoftSwitchR(2, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(2, func() uint8 {
// Blocks available, high byte // Blocks available, high byte
return uint8(c.disk.GetSizeInBlocks() >> 8) return uint8(c.disk.GetSizeInBlocks() >> 8)
}, "HDBLOCKHI") }, "HDBLOCKHI")
c.addCardSoftSwitchR(3, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(3, func() uint8 {
// Smart port entry point // Smart port entry point
command := c.a.mmu.Peek(c.mliParams + 1) command := c.a.mmu.Peek(c.mliParams + 1)
paramsAddress := uint16(c.a.mmu.Peek(c.mliParams+2)) + uint16(c.a.mmu.Peek(c.mliParams+3))<<8 paramsAddress := uint16(c.a.mmu.Peek(c.mliParams+2)) + uint16(c.a.mmu.Peek(c.mliParams+3))<<8
@ -127,13 +127,13 @@ func (c *CardHardDisk) assign(a *Apple2, slot int) {
return proDosDeviceErrorIO return proDosDeviceErrorIO
} }
}, "HDSMARTPORT") }, "HDSMARTPORT")
c.addCardSoftSwitchW(4, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(4, func(value uint8) {
c.mliParams = (c.mliParams & 0xff00) + uint16(value) c.mliParams = (c.mliParams & 0xff00) + uint16(value)
if c.trace { if c.trace {
fmt.Printf("[CardHardDisk] Smart port LO: 0x%x.\n", c.mliParams) fmt.Printf("[CardHardDisk] Smart port LO: 0x%x.\n", c.mliParams)
} }
}, "HDSMARTPORTLO") }, "HDSMARTPORTLO")
c.addCardSoftSwitchW(5, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(5, func(value uint8) {
c.mliParams = (c.mliParams & 0x00ff) + (uint16(value) << 8) c.mliParams = (c.mliParams & 0x00ff) + (uint16(value) << 8)
if c.trace { if c.trace {
fmt.Printf("[CardHardDisk] Smart port HI: 0x%x.\n", c.mliParams) fmt.Printf("[CardHardDisk] Smart port HI: 0x%x.\n", c.mliParams)

View File

@ -32,7 +32,7 @@ func NewCardInOut() *CardInOut {
} }
func (c *CardInOut) assign(a *Apple2, slot int) { func (c *CardInOut) assign(a *Apple2, slot int) {
c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(0, func() uint8 {
if c.reader == nil { if c.reader == nil {
c.reader = bufio.NewReader(os.Stdin) c.reader = bufio.NewReader(os.Stdin)
} }
@ -48,7 +48,7 @@ func (c *CardInOut) assign(a *Apple2, slot int) {
//fmt.Printf("[cardInOut] Read access to softswith 0x%x for slot %v, value %x.\n", 0, slot, value) //fmt.Printf("[cardInOut] Read access to softswith 0x%x for slot %v, value %x.\n", 0, slot, value)
return value return value
}, "INOUTR") }, "INOUTR")
c.addCardSoftSwitchW(1, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(1, func(value uint8) {
//fmt.Printf("[cardInOut] Write access to softswith 0x%x for slot %v, value 0x%x: %v, %v.\n", 1, slot, value, value&0x7f, string(value&0x7f)) //fmt.Printf("[cardInOut] Write access to softswith 0x%x for slot %v, value 0x%x: %v, %v.\n", 1, slot, value, value&0x7f, string(value&0x7f))
if value&0x7f == 13 { if value&0x7f == 13 {
fmt.Printf("\n") fmt.Printf("\n")

View File

@ -68,11 +68,11 @@ func (c *CardLanguage) assign(a *Apple2, slot int) {
a.mmu.initLanguageRAM(1) 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() uint8 {
c.ssAction(iCopy, false) c.ssAction(iCopy, false)
return 0 return 0
}, "LANGCARDR") }, "LANGCARDR")
c.addCardSoftSwitchW(iCopy, func(*ioC0Page, uint8) { c.addCardSoftSwitchW(iCopy, func(uint8) {
c.ssAction(iCopy, true) c.ssAction(iCopy, true)
}, "LANGCARDW") }, "LANGCARDW")
} }

View File

@ -21,7 +21,7 @@ func NewCardLogger() *CardLogger {
} }
func (c *CardLogger) assign(a *Apple2, slot int) { func (c *CardLogger) assign(a *Apple2, slot int) {
c.addCardSoftSwitches(func(_ *ioC0Page, address uint8, data uint8, write bool) uint8 { c.addCardSoftSwitches(func(address uint8, data uint8, write bool) uint8 {
if write { if write {
fmt.Printf("[cardLogger] Write access to softswith 0x%x for slot %v, value 0x%02x.\n", address, slot, data) fmt.Printf("[cardLogger] Write access to softswith 0x%x for slot %v, value 0x%02x.\n", address, slot, data)
} else { } else {

View File

@ -65,31 +65,31 @@ func (c *CardMemoryExpansion) GetInfo() map[string]string {
func (c *CardMemoryExpansion) assign(a *Apple2, slot int) { func (c *CardMemoryExpansion) assign(a *Apple2, slot int) {
// Read pointer position // Read pointer position
c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(0, func() uint8 {
return uint8(c.index) return uint8(c.index)
}, "MEMORYEXLOR") }, "MEMORYEXLOR")
c.addCardSoftSwitchR(1, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(1, func() uint8 {
return uint8(c.index >> 8) return uint8(c.index >> 8)
}, "MEMORYEXMIR") }, "MEMORYEXMIR")
c.addCardSoftSwitchR(2, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(2, func() uint8 {
// Top nibble returned is 0xf // Top nibble returned is 0xf
return uint8(c.index>>16) | 0xf0 return uint8(c.index>>16) | 0xf0
}, "MEMORYEXHIR") }, "MEMORYEXHIR")
// Set pointer position // Set pointer position
c.addCardSoftSwitchW(0, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(0, func(value uint8) {
c.index = (c.index &^ 0xff) + int(value) c.index = (c.index &^ 0xff) + int(value)
}, "MEMORYEXLOW") }, "MEMORYEXLOW")
c.addCardSoftSwitchW(1, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(1, func(value uint8) {
c.index = (c.index &^ 0xff00) + int(value)<<8 c.index = (c.index &^ 0xff00) + int(value)<<8
}, "MEMORYEXMIW") }, "MEMORYEXMIW")
c.addCardSoftSwitchW(2, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(2, func(value uint8) {
// Only lo nibble is used // Only lo nibble is used
c.index = (c.index &^ 0xff0000) + int(value&0x0f)<<16 c.index = (c.index &^ 0xff0000) + int(value&0x0f)<<16
}, "MEMORYEXHIW") }, "MEMORYEXHIW")
// Read data // Read data
c.addCardSoftSwitchR(3, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(3, func() uint8 {
var value uint8 var value uint8
if c.index < len(c.ram) { if c.index < len(c.ram) {
value = c.ram[c.index] value = c.ram[c.index]
@ -101,7 +101,7 @@ func (c *CardMemoryExpansion) assign(a *Apple2, slot int) {
}, "MEMORYEXR") }, "MEMORYEXR")
// Write data // Write data
c.addCardSoftSwitchW(3, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(3, func(value uint8) {
if c.index < len(c.ram) { if c.index < len(c.ram) {
c.ram[c.index] = value c.ram[c.index] = value
} }
@ -110,7 +110,7 @@ func (c *CardMemoryExpansion) assign(a *Apple2, slot int) {
// The rest of the softswitches return 255, at least on //e and //c // The rest of the softswitches return 255, at least on //e and //c
for i := uint8(4); i < 16; i++ { for i := uint8(4); i < 16; i++ {
c.addCardSoftSwitchR(i, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(i, func() uint8 {
return 255 return 255
}, "MEMORYEXUNUSEDR") }, "MEMORYEXUNUSEDR")
} }

View File

@ -92,7 +92,7 @@ func (c *CardMouse) readMouse() (uint16, uint16, bool) {
} }
func (c *CardMouse) assign(a *Apple2, slot int) { func (c *CardMouse) assign(a *Apple2, slot int) {
c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(0, func() uint8 {
if c.iOut == 0 { if c.iOut == 0 {
// Create a new response // Create a new response
x, y, pressed := c.readMouse() x, y, pressed := c.readMouse()
@ -126,7 +126,7 @@ func (c *CardMouse) assign(a *Apple2, slot int) {
return value return value
}, "MOUSEOUT") }, "MOUSEOUT")
c.addCardSoftSwitchW(1, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(1, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] PR#%v <- %02x\n", slot, value) fmt.Printf("[cardMouse] PR#%v <- %02x\n", slot, value)
} }
@ -140,21 +140,21 @@ func (c *CardMouse) assign(a *Apple2, slot int) {
} }
}, "MOUSEIN") }, "MOUSEIN")
c.addCardSoftSwitchW(2, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(2, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] SetMouse(0x%02v)\n", value) fmt.Printf("[cardMouse] SetMouse(0x%02v)\n", value)
} }
c.setMode(value & 0x0f) c.setMode(value & 0x0f)
}, "SETMOUSE") }, "SETMOUSE")
c.addCardSoftSwitchW(3, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(3, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] ServeMouse() NOT IMPLEMENTED\n") fmt.Printf("[cardMouse] ServeMouse() NOT IMPLEMENTED\n")
} }
panic("Mouse interrupts not implemented") panic("Mouse interrupts not implemented")
}, "SERVEMOUSE") }, "SERVEMOUSE")
c.addCardSoftSwitchW(4, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(4, func(value uint8) {
if c.mode&mouseModeEnabled == 1 { if c.mode&mouseModeEnabled == 1 {
x, y, pressed := c.readMouse() x, y, pressed := c.readMouse()
@ -186,7 +186,7 @@ func (c *CardMouse) assign(a *Apple2, slot int) {
} }
}, "READMOUSE") }, "READMOUSE")
c.addCardSoftSwitchW(5, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(5, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] ClearMouse() NOT IMPLEMENTED\n") fmt.Printf("[cardMouse] ClearMouse() NOT IMPLEMENTED\n")
} }
@ -195,13 +195,13 @@ func (c *CardMouse) assign(a *Apple2, slot int) {
c.set(mouseXLo, 0) c.set(mouseXLo, 0)
c.set(mouseYLo, 0) c.set(mouseYLo, 0)
}, "CLEARMOUSE") }, "CLEARMOUSE")
c.addCardSoftSwitchW(6, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(6, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] PosMouse() NOT IMPLEMENTED\n") fmt.Printf("[cardMouse] PosMouse() NOT IMPLEMENTED\n")
} }
}, "POSMOUSE") }, "POSMOUSE")
c.addCardSoftSwitchW(7, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(7, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] ClampMouse(%v)\n", value) fmt.Printf("[cardMouse] ClampMouse(%v)\n", value)
} }
@ -219,13 +219,13 @@ func (c *CardMouse) assign(a *Apple2, slot int) {
} }
}, "CLAMPMOUSE") }, "CLAMPMOUSE")
c.addCardSoftSwitchW(8, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(8, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] HomeMouse() NOT IMPLEMENTED\n") fmt.Printf("[cardMouse] HomeMouse() NOT IMPLEMENTED\n")
} }
}, "HOMEMOUSE") }, "HOMEMOUSE")
c.addCardSoftSwitchW(0xc, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(0xc, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] InitMouse()\n") fmt.Printf("[cardMouse] InitMouse()\n")
} }
@ -236,7 +236,7 @@ func (c *CardMouse) assign(a *Apple2, slot int) {
c.mode = 0 c.mode = 0
}, "INITMOUSE") }, "INITMOUSE")
c.addCardSoftSwitchW(8, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(8, func(value uint8) {
if c.trace { if c.trace {
fmt.Printf("[cardMouse] TimeData(%v) NOT IMPLEMENTED\n", value) fmt.Printf("[cardMouse] TimeData(%v) NOT IMPLEMENTED\n", value)
} }

View File

@ -33,7 +33,7 @@ func (c *CardParallelPrinter) assign(a *Apple2, slot int) {
} }
c.file = f c.file = f
c.addCardSoftSwitchW(0, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(0, func(value uint8) {
c.printByte(value) c.printByte(value)
}, "PARALLELDEVW") }, "PARALLELDEVW")

View File

@ -38,17 +38,17 @@ func setupRGBCard(a *Apple2) *cardRGB {
a.io.softSwitchesData[ioFlagRGBCardActive] = ssOn a.io.softSwitchesData[ioFlagRGBCardActive] = ssOn
// Does not have ROM or private softswitches. It spies on the softswitches // Does not have ROM or private softswitches. It spies on the softswitches
a.io.addSoftSwitchRW(0x50, func(io *ioC0Page) uint8 { a.io.addSoftSwitchRW(0x50, func() uint8 {
io.softSwitchesData[ioFlagText] = ssOff a.io.softSwitchesData[ioFlagText] = ssOff
// Reset RGB modes when entering graphics mode // Reset RGB modes when entering graphics mode
c.step = 0 c.step = 0
io.softSwitchesData[ioFlag1RGBCard] = ssOn a.io.softSwitchesData[ioFlag1RGBCard] = ssOn
io.softSwitchesData[ioFlag2RGBCard] = ssOn a.io.softSwitchesData[ioFlag2RGBCard] = ssOn
return 0 return 0
}, "TEXTOFF") }, "TEXTOFF")
a.io.addSoftSwitchRW(0x5e, func(io *ioC0Page) uint8 { a.io.addSoftSwitchRW(0x5e, func() uint8 {
io.softSwitchesData[ioFlagAnnunciator3] = ssOff a.io.softSwitchesData[ioFlagAnnunciator3] = ssOff
switch c.step { switch c.step {
case 0: case 0:
c.step++ c.step++
@ -59,14 +59,14 @@ func setupRGBCard(a *Apple2) *cardRGB {
return 0 return 0
}, "ANN3OFF-RGB") }, "ANN3OFF-RGB")
a.io.addSoftSwitchRW(0x5f, func(io *ioC0Page) uint8 { a.io.addSoftSwitchRW(0x5f, func() uint8 {
io.softSwitchesData[ioFlagAnnunciator3] = ssOn a.io.softSwitchesData[ioFlagAnnunciator3] = ssOn
switch c.step { switch c.step {
case 1: case 1:
io.softSwitchesData[ioFlag1RGBCard] = io.softSwitchesData[ioFlag80Col] a.io.softSwitchesData[ioFlag1RGBCard] = a.io.softSwitchesData[ioFlag80Col]
c.step++ c.step++
case 3: case 3:
io.softSwitchesData[ioFlag2RGBCard] = io.softSwitchesData[ioFlag80Col] a.io.softSwitchesData[ioFlag2RGBCard] = a.io.softSwitchesData[ioFlag80Col]
c.step++ c.step++
} }

View File

@ -14,11 +14,11 @@ It's is like the extra 64kb on an Apple IIe 80col 64kb card, but with up to 256
func setupRAMWorksCard(a *Apple2, banks int) { func setupRAMWorksCard(a *Apple2, banks int) {
a.mmu.initExtendedRAM(banks) a.mmu.initExtendedRAM(banks)
ssr := func(_ *ioC0Page) uint8 { ssr := func() uint8 {
return a.mmu.extendedRAMBlock return a.mmu.extendedRAMBlock
} }
ssw := func(_ *ioC0Page, value uint8) { ssw := func(value uint8) {
a.mmu.setExtendedRAMActiveBlock(value) a.mmu.setExtendedRAMActiveBlock(value)
} }

View File

@ -37,11 +37,11 @@ func (c *CardSaturn) assign(a *Apple2, slot int) {
// TODO: use addCardSoftSwitches() // TODO: use addCardSoftSwitches()
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() uint8 {
c.ssAction(iCopy) c.ssAction(iCopy)
return 0 return 0
}, "SATURNR") }, "SATURNR")
c.addCardSoftSwitchW(iCopy, func(*ioC0Page, uint8) { c.addCardSoftSwitchW(iCopy, func(uint8) {
c.ssAction(iCopy) c.ssAction(iCopy)
}, "SATURNW") }, "SATURNW")
} }

View File

@ -81,19 +81,19 @@ func (c *CardSwyft) assign(a *Apple2, slot int) {
} }
c.rom = data c.rom = data
c.addCardSoftSwitchRW(0, func(*ioC0Page) uint8 { c.addCardSoftSwitchRW(0, func() uint8 {
a.mmu.inhibitROM(c) a.mmu.inhibitROM(c)
c.bank2 = false c.bank2 = false
return 0x55 return 0x55
}, "SWYFTONBANK1") }, "SWYFTONBANK1")
c.addCardSoftSwitchRW(1, func(*ioC0Page) uint8 { c.addCardSoftSwitchRW(1, func() uint8 {
a.mmu.inhibitROM(nil) a.mmu.inhibitROM(nil)
c.bank2 = false c.bank2 = false
return 0x55 return 0x55
}, "SWYFTOFFBANK1") }, "SWYFTOFFBANK1")
c.addCardSoftSwitchRW(2, func(*ioC0Page) uint8 { c.addCardSoftSwitchRW(2, func() uint8 {
a.mmu.inhibitROM(c) a.mmu.inhibitROM(c)
c.bank2 = true c.bank2 = true
return 0x55 return 0x55

View File

@ -37,7 +37,7 @@ func NewCardThunderClockPlus() *CardThunderClockPlus {
} }
func (c *CardThunderClockPlus) assign(a *Apple2, slot int) { func (c *CardThunderClockPlus) assign(a *Apple2, slot int) {
c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(0, func() uint8 {
bit := c.upd1990.Out() bit := c.upd1990.Out()
// Get the next data bit from uPD1990AC on the MSB // Get the next data bit from uPD1990AC on the MSB
if bit { if bit {
@ -46,7 +46,7 @@ func (c *CardThunderClockPlus) assign(a *Apple2, slot int) {
return 0 return 0
}, "THUNDERCLOCKR") }, "THUNDERCLOCKR")
c.addCardSoftSwitchW(0, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(0, func(value uint8) {
dataIn := (value & 0x01) == 1 dataIn := (value & 0x01) == 1
clock := ((value >> 1) & 0x01) == 1 clock := ((value >> 1) & 0x01) == 1
strobe := ((value >> 2) & 0x01) == 1 strobe := ((value >> 2) & 0x01) == 1

View File

@ -37,14 +37,14 @@ const (
func (c *CardVidHD) assign(a *Apple2, slot int) { func (c *CardVidHD) assign(a *Apple2, slot int) {
// The softswitches are outside the card reserved ss // The softswitches are outside the card reserved ss
a.io.addSoftSwitchR(0x22, notImplementedSoftSwitchR, "VIDHD-TBCOLOR") a.io.addSoftSwitchR(0x22, buildNotImplementedSoftSwitchR(a.io), "VIDHD-TBCOLOR")
a.io.addSoftSwitchW(0x22, notImplementedSoftSwitchW, "VIDHD-TBCOLOR") a.io.addSoftSwitchW(0x22, buildNotImplementedSoftSwitchW(a.io), "VIDHD-TBCOLOR")
a.io.addSoftSwitchR(0x29, getStatusSoftSwitch(ioDataNewVideo), "VIDHD-NEWVIDEO") a.io.addSoftSwitchR(0x29, getStatusSoftSwitch(a.io, ioDataNewVideo), "VIDHD-NEWVIDEO")
a.io.addSoftSwitchW(0x29, setStatusSoftSwitch(ioDataNewVideo), "VIDHD-NEWVIDEO") a.io.addSoftSwitchW(0x29, setStatusSoftSwitch(a.io, ioDataNewVideo), "VIDHD-NEWVIDEO")
a.io.addSoftSwitchR(0x34, notImplementedSoftSwitchR, "VIDHD-CLOCKCTL") a.io.addSoftSwitchR(0x34, buildNotImplementedSoftSwitchR(a.io), "VIDHD-CLOCKCTL")
a.io.addSoftSwitchW(0x34, notImplementedSoftSwitchW, "VIDHD-CLOCKCTL") a.io.addSoftSwitchW(0x34, buildNotImplementedSoftSwitchW(a.io), "VIDHD-CLOCKCTL")
a.io.addSoftSwitchR(0x35, notImplementedSoftSwitchR, "VIDHD-SHADOW") a.io.addSoftSwitchR(0x35, buildNotImplementedSoftSwitchR(a.io), "VIDHD-SHADOW")
a.io.addSoftSwitchW(0x35, notImplementedSoftSwitchW, "VIDHD-SHADOW") a.io.addSoftSwitchW(0x35, buildNotImplementedSoftSwitchW(a.io), "VIDHD-SHADOW")
c.cardBase.assign(a, slot) c.cardBase.assign(a, slot)
} }

View File

@ -77,11 +77,11 @@ func (c *CardVidex) assign(a *Apple2, slot int) {
ssName += "ADDRESS" ssName += "ADDRESS"
} }
c.addCardSoftSwitchR(i, func(*ioC0Page) uint8 { c.addCardSoftSwitchR(i, func() uint8 {
c.sramPage = sramPage c.sramPage = sramPage
return c.mc6845.Read(rsPin) return c.mc6845.Read(rsPin)
}, ssName+"R") }, ssName+"R")
c.addCardSoftSwitchW(i, func(_ *ioC0Page, value uint8) { c.addCardSoftSwitchW(i, func(value uint8) {
c.sramPage = sramPage c.sramPage = sramPage
c.mc6845.Write(rsPin, value) c.mc6845.Write(rsPin, value)
}, ssName+"W") }, ssName+"W")

View File

@ -21,8 +21,8 @@ type ioC0Page struct {
panicNotImplemented bool panicNotImplemented bool
} }
type softSwitchR func(io *ioC0Page) uint8 type softSwitchR func() uint8
type softSwitchW func(io *ioC0Page, value uint8) type softSwitchW func(value uint8)
// SpeakerProvider provides a speaker implementation // SpeakerProvider provides a speaker implementation
type SpeakerProvider interface { type SpeakerProvider interface {
@ -69,8 +69,8 @@ func (p *ioC0Page) setPanicNotImplemented(value bool) {
func (p *ioC0Page) addSoftSwitchRW(address uint8, ss softSwitchR, name string) { func (p *ioC0Page) addSoftSwitchRW(address uint8, ss softSwitchR, name string) {
p.addSoftSwitchR(address, ss, name) p.addSoftSwitchR(address, ss, name)
p.addSoftSwitchW(address, func(p *ioC0Page, _ uint8) { p.addSoftSwitchW(address, func(uint8) {
ss(p) ss()
}, name) }, name)
} }
@ -122,7 +122,7 @@ func (p *ioC0Page) peek(address uint16) uint8 {
} }
return 0 return 0
} }
value := ss(p) value := ss()
if p.trace && address != 0xc000 { if p.trace && address != 0xc000 {
name := p.softSwitchesRName[pageAddress] name := p.softSwitchesRName[pageAddress]
fmt.Printf("Softswitch peek on $%04x %v: $%02x\n", address, name, value) fmt.Printf("Softswitch peek on $%04x %v: $%02x\n", address, name, value)
@ -146,7 +146,7 @@ func (p *ioC0Page) poke(address uint16, value uint8) {
name := p.softSwitchesWName[pageAddress] name := p.softSwitchesWName[pageAddress]
fmt.Printf("Softswitch poke on $%04x %v with $%02x\n", address, name, value) fmt.Printf("Softswitch poke on $%04x %v with $%02x\n", address, name, value)
} }
ss(p, value) ss(value)
} }
func (p *ioC0Page) setBase(_ uint16) { func (p *ioC0Page) setBase(_ uint16) {

View File

@ -29,81 +29,86 @@ const (
func addApple2SoftSwitches(io *ioC0Page) { func addApple2SoftSwitches(io *ioC0Page) {
io.addSoftSwitchRW(0x00, keySoftSwitch, "KEYBOARD") // Keyboard io.addSoftSwitchRW(0x00, buildKeySoftSwitch(io), "KEYBOARD") // Keyboard
io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch, "AKD") // Keyboard Strobe io.addSoftSwitchRW(0x10, buildStrobeKeyboardSoftSwitch(io), "AKD") // Keyboard Strobe
io.addSoftSwitchR(0x20, notImplementedSoftSwitchR, "TAPEOUT") // Cassette Output io.addSoftSwitchR(0x20, buildNotImplementedSoftSwitchR(io), "TAPEOUT") // Cassette Output
io.addSoftSwitchRW(0x30, speakerSoftSwitch, "SPEAKER") // Speaker io.addSoftSwitchRW(0x30, buildSpeakerSoftSwitch(io), "SPEAKER") // Speaker
io.addSoftSwitchR(0x40, notImplementedSoftSwitchR, "STROBE") // Game connector Strobe io.addSoftSwitchR(0x40, buildNotImplementedSoftSwitchR(io), "STROBE") // Game connector Strobe
// Note: Some sources indicate that all these cover 16 positions // Note: Some sources indicate that all these cover 16 positions
// for read and write. But the Apple2e takes over some of them, with // for read and write. But the Apple2e takes over some of them, with
// the prevention on acting only on writes. // the prevention on acting only on writes.
io.addSoftSwitchRW(0x50, getSoftSwitch(ioFlagText, false), "TEXTOFF") io.addSoftSwitchRW(0x50, getSoftSwitch(io, ioFlagText, false), "TEXTOFF")
io.addSoftSwitchRW(0x51, getSoftSwitch(ioFlagText, true), "TEXTON") io.addSoftSwitchRW(0x51, getSoftSwitch(io, ioFlagText, true), "TEXTON")
io.addSoftSwitchRW(0x52, getSoftSwitch(ioFlagMixed, false), "MIXEDOFF") io.addSoftSwitchRW(0x52, getSoftSwitch(io, ioFlagMixed, false), "MIXEDOFF")
io.addSoftSwitchRW(0x53, getSoftSwitch(ioFlagMixed, true), "MIXEDON") io.addSoftSwitchRW(0x53, getSoftSwitch(io, ioFlagMixed, true), "MIXEDON")
io.addSoftSwitchRW(0x54, getSoftSwitch(ioFlagSecondPage, false), "PAGE2OFF") io.addSoftSwitchRW(0x54, getSoftSwitch(io, ioFlagSecondPage, false), "PAGE2OFF")
io.addSoftSwitchRW(0x55, getSoftSwitch(ioFlagSecondPage, true), "PAGE2ON") io.addSoftSwitchRW(0x55, getSoftSwitch(io, ioFlagSecondPage, true), "PAGE2ON")
io.addSoftSwitchRW(0x56, getSoftSwitch(ioFlagHiRes, false), "HIRESOFF") io.addSoftSwitchRW(0x56, getSoftSwitch(io, ioFlagHiRes, false), "HIRESOFF")
io.addSoftSwitchRW(0x57, getSoftSwitch(ioFlagHiRes, true), "HIRESON") io.addSoftSwitchRW(0x57, getSoftSwitch(io, ioFlagHiRes, true), "HIRESON")
io.addSoftSwitchRW(0x58, getSoftSwitch(ioFlagAnnunciator0, false), "ANN0OFF") io.addSoftSwitchRW(0x58, getSoftSwitch(io, ioFlagAnnunciator0, false), "ANN0OFF")
io.addSoftSwitchRW(0x59, getSoftSwitch(ioFlagAnnunciator0, true), "ANN0ON") io.addSoftSwitchRW(0x59, getSoftSwitch(io, ioFlagAnnunciator0, true), "ANN0ON")
io.addSoftSwitchRW(0x5a, getSoftSwitch(ioFlagAnnunciator1, false), "ANN1OFF") io.addSoftSwitchRW(0x5a, getSoftSwitch(io, ioFlagAnnunciator1, false), "ANN1OFF")
io.addSoftSwitchRW(0x5b, getSoftSwitch(ioFlagAnnunciator1, true), "ANN1ON") io.addSoftSwitchRW(0x5b, getSoftSwitch(io, ioFlagAnnunciator1, true), "ANN1ON")
io.addSoftSwitchRW(0x5c, getSoftSwitch(ioFlagAnnunciator2, false), "ANN2OFF") io.addSoftSwitchRW(0x5c, getSoftSwitch(io, ioFlagAnnunciator2, false), "ANN2OFF")
io.addSoftSwitchRW(0x5d, getSoftSwitch(ioFlagAnnunciator2, true), "ANN2ON") io.addSoftSwitchRW(0x5d, getSoftSwitch(io, ioFlagAnnunciator2, true), "ANN2ON")
io.addSoftSwitchRW(0x5e, getSoftSwitch(ioFlagAnnunciator3, false), "ANN3OFF") io.addSoftSwitchRW(0x5e, getSoftSwitch(io, ioFlagAnnunciator3, false), "ANN3OFF")
io.addSoftSwitchRW(0x5f, getSoftSwitch(ioFlagAnnunciator3, true), "ANN3ON") io.addSoftSwitchRW(0x5f, getSoftSwitch(io, ioFlagAnnunciator3, true), "ANN3ON")
io.addSoftSwitchR(0x60, notImplementedSoftSwitchR, "CASSETTE") // Cassette Input io.addSoftSwitchR(0x60, buildNotImplementedSoftSwitchR(io), "CASSETTE") // Cassette Input
io.addSoftSwitchR(0x61, getButtonSoftSwitch(0), "PB0") io.addSoftSwitchR(0x61, buildButtonSoftSwitch(io, 0), "PB0")
io.addSoftSwitchR(0x62, getButtonSoftSwitch(1), "PB1") io.addSoftSwitchR(0x62, buildButtonSoftSwitch(io, 1), "PB1")
io.addSoftSwitchR(0x63, getButtonSoftSwitch(2), "PB2") io.addSoftSwitchR(0x63, buildButtonSoftSwitch(io, 2), "PB2")
io.addSoftSwitchR(0x64, getPaddleSoftSwitch(0), "PDL0") io.addSoftSwitchR(0x64, buildPaddleSoftSwitch(io, 0), "PDL0")
io.addSoftSwitchR(0x65, getPaddleSoftSwitch(1), "PDL1") io.addSoftSwitchR(0x65, buildPaddleSoftSwitch(io, 1), "PDL1")
io.addSoftSwitchR(0x66, getPaddleSoftSwitch(2), "PDL2") io.addSoftSwitchR(0x66, buildPaddleSoftSwitch(io, 2), "PDL2")
io.addSoftSwitchR(0x67, getPaddleSoftSwitch(3), "PDL3") io.addSoftSwitchR(0x67, buildPaddleSoftSwitch(io, 3), "PDL3")
// The previous 8 softswitches are repeated // The previous 8 softswitches are repeated
io.addSoftSwitchR(0x68, notImplementedSoftSwitchR, "CASSETTE") // Cassette Input io.addSoftSwitchR(0x68, buildNotImplementedSoftSwitchR(io), "CASSETTE") // Cassette Input
io.addSoftSwitchR(0x69, getButtonSoftSwitch(0), "PB0") io.addSoftSwitchR(0x69, buildButtonSoftSwitch(io, 0), "PB0")
io.addSoftSwitchR(0x6A, getButtonSoftSwitch(1), "PB1") io.addSoftSwitchR(0x6A, buildButtonSoftSwitch(io, 1), "PB1")
io.addSoftSwitchR(0x6B, getButtonSoftSwitch(2), "PB2") io.addSoftSwitchR(0x6B, buildButtonSoftSwitch(io, 2), "PB2")
io.addSoftSwitchR(0x6C, getPaddleSoftSwitch(0), "PDL0") io.addSoftSwitchR(0x6C, buildPaddleSoftSwitch(io, 0), "PDL0")
io.addSoftSwitchR(0x6D, getPaddleSoftSwitch(1), "PDL1") io.addSoftSwitchR(0x6D, buildPaddleSoftSwitch(io, 1), "PDL1")
io.addSoftSwitchR(0x6E, getPaddleSoftSwitch(2), "PDL2") io.addSoftSwitchR(0x6E, buildPaddleSoftSwitch(io, 2), "PDL2")
io.addSoftSwitchR(0x6F, getPaddleSoftSwitch(3), "PDL3") io.addSoftSwitchR(0x6F, buildPaddleSoftSwitch(io, 3), "PDL3")
io.addSoftSwitchR(0x70, strobePaddlesSoftSwitch, "RESETPDL") // Game controllers reset io.addSoftSwitchR(0x70, buildStrobePaddlesSoftSwitch(io), "RESETPDL") // Game controllers reset
// For RGB screen modes. Default to NTSC artifacts // For RGB screen modes. Default to NTSC artifacts
io.softSwitchesData[ioFlag1RGBCard] = ssOn io.softSwitchesData[ioFlag1RGBCard] = ssOn
io.softSwitchesData[ioFlag2RGBCard] = ssOn io.softSwitchesData[ioFlag2RGBCard] = ssOn
} }
func notImplementedSoftSwitchR(io *ioC0Page) uint8 { func buildNotImplementedSoftSwitchR(io *ioC0Page) softSwitchR {
// Return random info. Some games (Serpentine) used CASSETTE and get stuck if not changing. return func() uint8 {
return uint8(io.apple2.cpu.GetCycles()) // Return random info. Some games (Serpentine) used CASSETTE and get stuck if not changing.
return uint8(io.apple2.cpu.GetCycles())
}
} }
func notImplementedSoftSwitchW(*ioC0Page, uint8) { func buildNotImplementedSoftSwitchW(io *ioC0Page) softSwitchW {
return func(uint8) {
// Do nothing
}
} }
func setStatusSoftSwitch(ioFlag uint8) softSwitchW { func setStatusSoftSwitch(io *ioC0Page, ioFlag uint8) softSwitchW {
return func(io *ioC0Page, value uint8) { return func(value uint8) {
io.softSwitchesData[ioFlag] = value io.softSwitchesData[ioFlag] = value
} }
} }
func getStatusSoftSwitch(ioFlag uint8) softSwitchR { func getStatusSoftSwitch(io *ioC0Page, ioFlag uint8) softSwitchR {
return func(io *ioC0Page) uint8 { return func() uint8 {
return io.softSwitchesData[ioFlag] return io.softSwitchesData[ioFlag]
} }
} }
func getSoftSwitch(ioFlag uint8, isSet bool) softSwitchR { func getSoftSwitch(io *ioC0Page, ioFlag uint8, isSet bool) softSwitchR {
return func(io *ioC0Page) uint8 { return func() uint8 {
if isSet { if isSet {
io.softSwitchesData[ioFlag] = ssOn io.softSwitchesData[ioFlag] = ssOn
} else { } else {
@ -113,35 +118,40 @@ func getSoftSwitch(ioFlag uint8, isSet bool) softSwitchR {
} }
} }
func speakerSoftSwitch(io *ioC0Page) uint8 { func buildSpeakerSoftSwitch(io *ioC0Page) softSwitchR {
if io.speaker != nil { return func() uint8 {
io.speaker.Click(io.apple2.cpu.GetCycles()) if io.speaker != nil {
} io.speaker.Click(io.apple2.cpu.GetCycles())
return 0
}
func keySoftSwitch(io *ioC0Page) uint8 {
strobed := (io.softSwitchesData[ioDataKeyboard] & (1 << 7)) == 0
if io.keyboard != nil {
if key, ok := io.keyboard.GetKey(strobed); ok {
io.softSwitchesData[ioDataKeyboard] = key + (1 << 7)
} }
return 0
} }
value := io.softSwitchesData[ioDataKeyboard]
//fmt.Printf("Key $%02x, %v\n", value, strobed)
return value
} }
func strobeKeyboardSoftSwitch(io *ioC0Page) uint8 { func buildKeySoftSwitch(io *ioC0Page) softSwitchR {
result := io.softSwitchesData[ioDataKeyboard] return func() uint8 {
//fmt.Printf("Strobe $%02x\n", result) strobed := (io.softSwitchesData[ioDataKeyboard] & (1 << 7)) == 0
io.softSwitchesData[ioDataKeyboard] &^= 1 << 7 if io.keyboard != nil {
return result if key, ok := io.keyboard.GetKey(strobed); ok {
io.softSwitchesData[ioDataKeyboard] = key + (1 << 7)
}
}
value := io.softSwitchesData[ioDataKeyboard]
//fmt.Printf("Key $%02x, %v\n", value, strobed)
return value
}
} }
func getButtonSoftSwitch(i int) softSwitchR { func buildStrobeKeyboardSoftSwitch(io *ioC0Page) softSwitchR {
return func(io *ioC0Page) uint8 { return func() uint8 {
result := io.softSwitchesData[ioDataKeyboard]
//fmt.Printf("Strobe $%02x\n", result)
io.softSwitchesData[ioDataKeyboard] &^= 1 << 7
return result
}
}
func buildButtonSoftSwitch(io *ioC0Page, i int) softSwitchR {
return func() uint8 {
if io.joysticks != nil && io.joysticks.ReadButton(i) { if io.joysticks != nil && io.joysticks.ReadButton(i) {
return 128 return 128
} }
@ -161,8 +171,8 @@ func getButtonSoftSwitch(i int) softSwitchR {
const paddleToCyclesFactor = 11 const paddleToCyclesFactor = 11
func getPaddleSoftSwitch(i int) softSwitchR { func buildPaddleSoftSwitch(io *ioC0Page, i int) softSwitchR {
return func(io *ioC0Page) uint8 { return func() uint8 {
if io.joysticks == nil { if io.joysticks == nil {
return 255 // Capacitors never discharge if there is not joystick return 255 // Capacitors never discharge if there is not joystick
} }
@ -180,8 +190,10 @@ func getPaddleSoftSwitch(i int) softSwitchR {
} }
} }
func strobePaddlesSoftSwitch(io *ioC0Page) uint8 { func buildStrobePaddlesSoftSwitch(io *ioC0Page) softSwitchR {
// On the real machine this discharges the capacitors. return func() uint8 {
io.paddlesStrobeCycle = io.apple2.cpu.GetCycles() // On the real machine this discharges the capacitors.
return 0 io.paddlesStrobeCycle = io.apple2.cpu.GetCycles()
return 0
}
} }

View File

@ -31,19 +31,19 @@ func addApple2ESoftSwitches(io *ioC0Page) {
addSoftSwitchesIou(io, 0x0e, 0x0f, 0x1e, ioFlagAltChar, "ALTCHARSET") addSoftSwitchesIou(io, 0x0e, 0x0f, 0x1e, ioFlagAltChar, "ALTCHARSET")
// Previous read softswithes // Previous read softswithes
io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText), "TEXT") io.addSoftSwitchR(0x1A, getStatusSoftSwitch(io, ioFlagText), "TEXT")
io.addSoftSwitchR(0x1B, getStatusSoftSwitch(ioFlagMixed), "MIXED") io.addSoftSwitchR(0x1B, getStatusSoftSwitch(io, ioFlagMixed), "MIXED")
io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage), "PAGE2") io.addSoftSwitchR(0x1C, getStatusSoftSwitch(io, ioFlagSecondPage), "PAGE2")
io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes), "HIRES") io.addSoftSwitchR(0x1D, getStatusSoftSwitch(io, ioFlagHiRes), "HIRES")
io.addSoftSwitchR(0x11, func(_ *ioC0Page) uint8 { io.addSoftSwitchR(0x11, func() uint8 {
return ssFromBool(mmu.lcAltBank) return ssFromBool(mmu.lcAltBank)
}, "BSRBANK2") }, "BSRBANK2")
io.addSoftSwitchR(0x12, func(_ *ioC0Page) uint8 { io.addSoftSwitchR(0x12, func() uint8 {
return ssFromBool(mmu.lcActiveRead) return ssFromBool(mmu.lcActiveRead)
}, "BSRREADRAM") }, "BSRREADRAM")
io.addSoftSwitchR(0x19, func(_ *ioC0Page) uint8 { io.addSoftSwitchR(0x19, func() uint8 {
// See "Inside Apple IIe", page 268 // See "Inside Apple IIe", page 268
// See http://rich12345.tripod.com/aiivideo/vbl.html // See http://rich12345.tripod.com/aiivideo/vbl.html
// For each screen draw: // For each screen draw:
@ -62,29 +62,29 @@ func addApple2ESoftSwitches(io *ioC0Page) {
} }
func addSoftSwitchesMmu(io *ioC0Page, addressClear uint8, addressSet uint8, AddressGet uint8, flag *bool, name string) { func addSoftSwitchesMmu(io *ioC0Page, addressClear uint8, addressSet uint8, AddressGet uint8, flag *bool, name string) {
io.addSoftSwitchW(addressClear, func(_ *ioC0Page, _ uint8) { io.addSoftSwitchW(addressClear, func(uint8) {
*flag = false *flag = false
}, name+"OFF") }, name+"OFF")
io.addSoftSwitchW(addressSet, func(_ *ioC0Page, _ uint8) { io.addSoftSwitchW(addressSet, func(uint8) {
*flag = true *flag = true
}, name+"ON") }, name+"ON")
io.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 { io.addSoftSwitchR(AddressGet, func() uint8 {
return ssFromBool(*flag) return ssFromBool(*flag)
}, name) }, name)
} }
func addSoftSwitchesIou(io *ioC0Page, addressClear uint8, addressSet uint8, AddressGet uint8, ioFlag uint8, name string) { func addSoftSwitchesIou(io *ioC0Page, addressClear uint8, addressSet uint8, AddressGet uint8, ioFlag uint8, name string) {
io.addSoftSwitchW(addressClear, func(_ *ioC0Page, _ uint8) { io.addSoftSwitchW(addressClear, func(uint8) {
io.softSwitchesData[ioFlag] = ssOff io.softSwitchesData[ioFlag] = ssOff
}, name+"OFF") }, name+"OFF")
io.addSoftSwitchW(addressSet, func(_ *ioC0Page, _ uint8) { io.addSoftSwitchW(addressSet, func(uint8) {
io.softSwitchesData[ioFlag] = ssOn io.softSwitchesData[ioFlag] = ssOn
}, name+"ON") }, name+"ON")
io.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 { io.addSoftSwitchR(AddressGet, func() uint8 {
return io.softSwitchesData[ioFlag] return io.softSwitchesData[ioFlag]
}, name) }, name)
} }