Simplify softswitches
This commit is contained in:
parent
f2bc9f21aa
commit
9feded23f8
18
base64a.go
18
base64a.go
|
@ -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
|
||||||
|
|
14
cardBase.go
14
cardBase.go
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
cardDisk2.go
16
cardDisk2.go
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
22
cardMouse.go
22
cardMouse.go
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
20
cardRGB.go
20
cardRGB.go
|
@ -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++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
16
cardVidHD.go
16
cardVidHD.go
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
12
ioC0Page.go
12
ioC0Page.go
|
@ -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) {
|
||||||
|
|
166
softSwitches2.go
166
softSwitches2.go
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue