From d5433ad8d9f47b27760c371a3d41d75f133e358c Mon Sep 17 00:00:00 2001 From: Ivan Izaguirre Date: Mon, 21 Oct 2019 00:00:42 +0200 Subject: [PATCH] Nanmed sotfswitches for easier traces. --- base64a.go | 8 ++--- base64aRom.go | 8 ++--- cardBase.go | 20 ++++++++--- cardDisk2.go | 42 ++++++++++++----------- cardHardDisk.go | 12 +++---- cardInOut.go | 10 +++--- cardLanguage.go | 16 ++++----- cardLogger.go | 10 +++--- cardSaturn.go | 18 +++++----- cardThunderClockPlus.go | 8 ++--- ioC0Page.go | 26 ++++++++------ softSwitches2.go | 76 ++++++++++++++++++++--------------------- softSwitches2e.go | 64 +++++++++++++++++++++++----------- 13 files changed, 181 insertions(+), 137 deletions(-) diff --git a/base64a.go b/base64a.go index e35cdfc..4646584 100644 --- a/base64a.go +++ b/base64a.go @@ -26,15 +26,15 @@ func newBase64a() *Apple2 { } func addBase64aSoftSwitches(io *ioC0Page) { - // Other softswitches - io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW) // 80 columns off? - io.addSoftSwitchW(0x0E, notImplementedSoftSwitchW) // Alt char off? + // Other softswitches, not implemented but called from the ROM + io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW, "80COLOFF") + io.addSoftSwitchW(0x0E, notImplementedSoftSwitchW, "ALTCHARSETOFF") // Write on the speaker. That is a double access and should do nothing // but works somehow on the BASE64A io.addSoftSwitchW(0x30, func(io *ioC0Page, value uint8) { speakerSoftSwitch(io) - }) + }, "SPEAKER") } func charGenColumnsMapBase64a(column int) int { diff --git a/base64aRom.go b/base64aRom.go index 9bb88da..b79f5f1 100644 --- a/base64aRom.go +++ b/base64aRom.go @@ -55,19 +55,19 @@ func loadBase64aRom(a *Apple2) error { a.io.addSoftSwitchRW(0x58, func(*ioC0Page) uint8 { r.changeBank(a.mmu, r.romBank&2) return 0 - }) + }, "ANN0OFF-ROM") a.io.addSoftSwitchRW(0x59, func(*ioC0Page) uint8 { r.changeBank(a.mmu, r.romBank|1) return 0 - }) + }, "ANN0ON-ROM") a.io.addSoftSwitchRW(0x5A, func(*ioC0Page) uint8 { r.changeBank(a.mmu, r.romBank&1) return 0 - }) + }, "ANN1OFF-ROM") a.io.addSoftSwitchRW(0x5B, func(*ioC0Page) uint8 { r.changeBank(a.mmu, r.romBank|2) return 0 - }) + }, "ANN1ON-ROM") return nil } diff --git a/cardBase.go b/cardBase.go index 85dec00..332065c 100644 --- a/cardBase.go +++ b/cardBase.go @@ -15,8 +15,10 @@ type cardBase struct { rom *memoryRange romExtra *memoryRange slot int - ssr [16]softSwitchR - ssw [16]softSwitchW + _ssr [16]softSwitchR + _ssw [16]softSwitchW + _ssrName [16]string + _sswName [16]string } func (c *cardBase) loadRom(data []uint8) { @@ -45,11 +47,21 @@ func (c *cardBase) assign(a *Apple2, slot int) { } for i := 0; i < 0x10; i++ { - a.io.addSoftSwitchR(uint8(0xC80+slot*0x10+i), c.ssr[i]) - a.io.addSoftSwitchW(uint8(0xC80+slot*0x10+i), c.ssw[i]) + a.io.addSoftSwitchR(uint8(0xC80+slot*0x10+i), c._ssr[i], c._ssrName[i]) + a.io.addSoftSwitchW(uint8(0xC80+slot*0x10+i), c._ssw[i], c._sswName[i]) } } +func (c *cardBase) addCardSoftSwitchR(address uint8, ss softSwitchR, name string) { + c._ssr[address] = ss + c._ssrName[address] = name +} + +func (c *cardBase) addCardSoftSwitchW(address uint8, ss softSwitchW, name string) { + c._ssw[address] = ss + c._sswName[address] = name +} + func (c *cardBase) save(w io.Writer) error { // Empty return nil diff --git a/cardDisk2.go b/cardDisk2.go index ffe25ec..80108ac 100644 --- a/cardDisk2.go +++ b/cardDisk2.go @@ -2,6 +2,7 @@ package apple2 import ( "encoding/binary" + "fmt" "io" ) @@ -33,7 +34,7 @@ type cardDisk2 struct { type cardDisk2Drive struct { diskette *diskette16sector - currentPhase int + currentPhase uint8 power bool // q4 halfTrack int position int @@ -50,12 +51,13 @@ const ( func (c *cardDisk2) assign(a *Apple2, slot int) { // Q1, Q2, Q3 and Q4 phase control soft switches, - for i := 0; i < 4; i++ { + for i := uint8(0); i < 4; i++ { phase := i - c.ssr[phase<<1] = func(_ *ioC0Page) uint8 { + c.addCardSoftSwitchR(phase<<1, func(_ *ioC0Page) uint8 { return c.dataLatch // All even addresses return the last dataLatch - } - c.ssr[(phase<<1)+1] = func(_ *ioC0Page) uint8 { + }, fmt.Sprintf("PHASE%vOFF", phase)) + + c.addCardSoftSwitchR((phase<<1)+1, func(_ *ioC0Page) uint8 { // Move the head up or down depending on the previous phase. drive := &c.drive[c.selected] delta := (phase - drive.currentPhase + 4) % 4 @@ -79,50 +81,50 @@ func (c *cardDisk2) assign(a *Apple2, slot int) { drive.currentPhase = phase //fmt.Printf("DISKII: Current halftrack is %v\n", drive.halfTrack) return 0 - } + }, fmt.Sprintf("PHASE%vOFF", phase)) } // Q4, power switch - c.ssr[0x8] = func(_ *ioC0Page) uint8 { + c.addCardSoftSwitchR(0x8, func(_ *ioC0Page) uint8 { if c.drive[c.selected].power { c.drive[c.selected].power = false c.a.releaseFastMode() } return c.dataLatch - } - c.ssr[0x9] = func(_ *ioC0Page) uint8 { + }, "Q4DRIVEOFF") + c.addCardSoftSwitchR(0x9, func(_ *ioC0Page) uint8 { if !c.drive[c.selected].power { c.drive[c.selected].power = true c.a.requestFastMode() } return 0 - } + }, "") // Q5, drive selecion - c.ssr[0xA] = func(_ *ioC0Page) uint8 { + c.addCardSoftSwitchR(0xA, func(_ *ioC0Page) uint8 { c.selected = 0 return c.dataLatch - } - c.ssr[0xB] = func(_ *ioC0Page) uint8 { + }, "Q5SELECT1") + c.addCardSoftSwitchR(0xB, func(_ *ioC0Page) uint8 { c.selected = 1 return 0 - } + }, "Q5SELECT2") // Q6, Q7 - for i := 0xC; i <= 0xF; i++ { + for i := uint8(0xC); i <= 0xF; i++ { iCopy := i - c.ssr[iCopy] = func(_ *ioC0Page) uint8 { + c.addCardSoftSwitchR(iCopy, func(_ *ioC0Page) uint8 { return c.softSwitchQ6Q7(iCopy, 0) - } - c.ssw[iCopy] = func(_ *ioC0Page, value uint8) { + }, "Q6Q7") + c.addCardSoftSwitchW(iCopy, func(_ *ioC0Page, value uint8) { c.softSwitchQ6Q7(iCopy, value) - } + }, "Q6Q7") } c.cardBase.assign(a, slot) } -func (c *cardDisk2) softSwitchQ6Q7(index int, in uint8) uint8 { +func (c *cardDisk2) softSwitchQ6Q7(index uint8, in uint8) uint8 { switch index { case 0xC: // Q6L c.q6 = false diff --git a/cardHardDisk.go b/cardHardDisk.go index a947f8e..ecf780b 100644 --- a/cardHardDisk.go +++ b/cardHardDisk.go @@ -77,7 +77,7 @@ const ( ) func (c *cardHardDisk) assign(a *Apple2, slot int) { - c.ssr[0] = func(*ioC0Page) uint8 { + c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 { // Prodos entry point command := a.mmu.Peek(0x42) @@ -99,15 +99,15 @@ func (c *cardHardDisk) assign(a *Apple2, slot int) { // Prodos device command not supported return proDosDeviceErrorIO } - } - c.ssr[1] = func(*ioC0Page) uint8 { + }, "HDCOMMAND") + c.addCardSoftSwitchR(1, func(*ioC0Page) uint8 { // Blocks available, low byte return uint8(c.disk.header.Blocks) - } - c.ssr[2] = func(*ioC0Page) uint8 { + }, "HDBLOCKSLO") + c.addCardSoftSwitchR(2, func(*ioC0Page) uint8 { // Blocks available, high byte return uint8(c.disk.header.Blocks >> 8) - } + }, "HDBLOCKHI") c.cardBase.assign(a, slot) } diff --git a/cardInOut.go b/cardInOut.go index 5ba15b4..669cc6a 100644 --- a/cardInOut.go +++ b/cardInOut.go @@ -19,18 +19,18 @@ type cardInOut struct { } func (c *cardInOut) assign(a *Apple2, slot int) { - for i := 0x0; i <= 0xf; i++ { + for i := uint8(0x0); i <= 0xf; i++ { iCopy := i - c.ssr[i] = func(*ioC0Page) uint8 { + c.addCardSoftSwitchR(i, func(*ioC0Page) uint8 { value := []uint8{0xc1, 0xc1, 0x93, 0x0}[c.i%4] c.i++ fmt.Printf("[cardInOut] Read access to softswith 0x%x for slot %v, value %x.\n", iCopy, slot, value) //return 0x41 + 0x80 return []uint8{0x41, 0x41, 0x13}[i%3] + 0x80 - } - c.ssw[i] = func(_ *ioC0Page, value uint8) { + }, "INOUTR") + c.addCardSoftSwitchW(i, func(_ *ioC0Page, value uint8) { fmt.Printf("[cardInOut] Write access to softswith 0x%x for slot %v, value 0x%x.\n", iCopy, slot, value) - } + }, "INOUTW") } in := true diff --git a/cardLanguage.go b/cardLanguage.go index 4578798..fd6d0a8 100644 --- a/cardLanguage.go +++ b/cardLanguage.go @@ -31,8 +31,8 @@ and selects the second 4K bank to map $D000-$DFFF." type cardLanguage struct { cardBase readState bool - writeState int - activeBank int + writeState uint8 + activeBank uint8 ramBankA *memoryRange // First 4kb to map in 0xD000-0xDFFF ramBankB *memoryRange // Second 4kb to map in 0xD000-0xDFFF ramUpper *memoryRange // Upper 8kb to map in 0xE000-0xFFFF @@ -54,22 +54,22 @@ func (c *cardLanguage) assign(a *Apple2, slot int) { c.ramBankB = newMemoryRange(0xd000, make([]uint8, 0x1000)) c.ramUpper = newMemoryRange(0xe000, make([]uint8, 0x2000)) - for i := 0x0; i <= 0xf; i++ { + for i := uint8(0x0); i <= 0xf; i++ { iCopy := i - c.ssr[iCopy] = func(*ioC0Page) uint8 { + c.addCardSoftSwitchR(iCopy, func(*ioC0Page) uint8 { c.ssAction(iCopy, false) return 0 - } - c.ssw[iCopy] = func(*ioC0Page, uint8) { + }, "LANGCARDR") + c.addCardSoftSwitchW(iCopy, func(*ioC0Page, uint8) { c.ssAction(iCopy, true) - } + }, "LANGCARDW") } c.cardBase.assign(a, slot) c.applyState() } -func (c *cardLanguage) ssAction(ss int, write bool) { +func (c *cardLanguage) ssAction(ss uint8, write bool) { c.activeBank = (ss >> 3) & 1 action := ss & 0x3 switch action { diff --git a/cardLogger.go b/cardLogger.go index eadf445..a9b665d 100644 --- a/cardLogger.go +++ b/cardLogger.go @@ -13,15 +13,15 @@ type cardLogger struct { } func (c *cardLogger) assign(a *Apple2, slot int) { - for i := 0x0; i <= 0xf; i++ { + for i := uint8(0x0); i <= 0xf; i++ { iCopy := i - c.ssr[i] = func(*ioC0Page) uint8 { + c.addCardSoftSwitchR(i, func(*ioC0Page) uint8 { fmt.Printf("[cardLogger] Read access to softswith 0x%x for slot %v.\n", iCopy, slot) return 0 - } - c.ssw[i] = func(_ *ioC0Page, value uint8) { + }, "LOGGERR") + c.addCardSoftSwitchW(i, func(_ *ioC0Page, value uint8) { fmt.Printf("[cardLogger] Write access to softswith 0x%x for slot %v, value 0x%v.\n", iCopy, slot, value) - } + }, "LOGGERW") } if slot != 0 { diff --git a/cardSaturn.go b/cardSaturn.go index e76cd73..5b93978 100644 --- a/cardSaturn.go +++ b/cardSaturn.go @@ -16,9 +16,9 @@ http://www.applelogic.org/files/SATURN128MAN.pdf type cardSaturn struct { cardBase readState bool - writeState int - activeBank int - activeBlock int + writeState uint8 + activeBank uint8 + activeBlock uint8 ramBankA [saturnBlocks]*memoryRange // First 4kb to map in 0xD000-0xDFFF ramBankB [saturnBlocks]*memoryRange // Second 4kb to map in 0xD000-0xDFFF ramUpper [saturnBlocks]*memoryRange // Upper 8kb to map in 0xE000-0xFFFF @@ -45,21 +45,21 @@ func (c *cardSaturn) assign(a *Apple2, slot int) { c.ramBankB[i] = newMemoryRange(0xd000, make([]uint8, 0x1000)) c.ramUpper[i] = newMemoryRange(0xe000, make([]uint8, 0x2000)) } - for i := 0x0; i <= 0xf; i++ { + for i := uint8(0x0); i <= 0xf; i++ { iCopy := i - c.ssr[iCopy] = func(*ioC0Page) uint8 { + c.addCardSoftSwitchR(iCopy, func(*ioC0Page) uint8 { c.ssAction(iCopy, false) return 0 - } - c.ssw[iCopy] = func(*ioC0Page, uint8) { + }, "SATURNR") + c.addCardSoftSwitchW(iCopy, func(*ioC0Page, uint8) { c.ssAction(iCopy, true) - } + }, "SATURNW") } c.cardBase.assign(a, slot) c.applyState() } -func (c *cardSaturn) ssAction(ss int, write bool) { +func (c *cardSaturn) ssAction(ss uint8, write bool) { switch ss { case 0: // RAM read, no writes diff --git a/cardThunderClockPlus.go b/cardThunderClockPlus.go index 882ab5a..073e088 100644 --- a/cardThunderClockPlus.go +++ b/cardThunderClockPlus.go @@ -25,16 +25,16 @@ type cardThunderClockPlus struct { } func (c *cardThunderClockPlus) assign(a *Apple2, slot int) { - c.ssr[0] = func(*ioC0Page) uint8 { + c.addCardSoftSwitchR(0, func(*ioC0Page) uint8 { bit := c.microPD1990ac.out() // Get the next data bit from uPD1990AC on the MSB if bit { return 0x80 } return 0 - } + }, "THUNDERCLOCKR") - c.ssw[0] = func(_ *ioC0Page, value uint8) { + c.addCardSoftSwitchW(0, func(_ *ioC0Page, value uint8) { dataIn := (value & 0x01) == 1 clock := ((value >> 1) & 0x01) == 1 strobe := ((value >> 2) & 0x01) == 1 @@ -43,7 +43,7 @@ func (c *cardThunderClockPlus) assign(a *Apple2, slot int) { dataIn, clock, strobe, command) */ c.microPD1990ac.in(clock, strobe, command, dataIn) - } + }, "THUNDERCLOCKW") c.cardBase.assign(a, slot) } diff --git a/ioC0Page.go b/ioC0Page.go index 52523a6..4c02bd8 100644 --- a/ioC0Page.go +++ b/ioC0Page.go @@ -9,6 +9,8 @@ import ( type ioC0Page struct { softSwitchesR [256]softSwitchR softSwitchesW [256]softSwitchW + softSwitchesRName [256]string + softSwitchesWName [256]string softSwitchesData [128]uint8 keyboard KeyboardProvider speaker SpeakerProvider @@ -69,25 +71,27 @@ func (p *ioC0Page) load(r io.Reader) error { return binary.Read(r, binary.BigEndian, &p.softSwitchesData) } -func (p *ioC0Page) addSoftSwitchRW(address uint8, ss softSwitchR) { - p.addSoftSwitchR(address, ss) +func (p *ioC0Page) addSoftSwitchRW(address uint8, ss softSwitchR, name string) { + p.addSoftSwitchR(address, ss, name) p.addSoftSwitchW(address, func(p *ioC0Page, _ uint8) { ss(p) - }) + }, name) } -func (p *ioC0Page) addSoftSwitchR(address uint8, ss softSwitchR) { +func (p *ioC0Page) addSoftSwitchR(address uint8, ss softSwitchR, name string) { //if p.softSwitchesR[address] != nil { // fmt.Printf("Addresss 0x0c%02x is already assigned for read\n", address) //} p.softSwitchesR[address] = ss + p.softSwitchesRName[address] = name } -func (p *ioC0Page) addSoftSwitchW(address uint8, ss softSwitchW) { +func (p *ioC0Page) addSoftSwitchW(address uint8, ss softSwitchW, name string) { //if p.softSwitchesW[address] != nil { // fmt.Printf("Addresss 0x0c%02x is already assigned for write\n", address) //} p.softSwitchesW[address] = ss + p.softSwitchesWName[address] = name } func (p *ioC0Page) isSoftSwitchActive(ioFlag uint8) bool { @@ -116,16 +120,14 @@ func (p *ioC0Page) peek(address uint16) uint8 { return 0 } value := ss(p) - if p.trace { - fmt.Printf("Softswitch peek on $%04x: $%02x\n", address, value) + if p.trace && address != 0xc000 { + name := p.softSwitchesRName[pageAddress] + fmt.Printf("Softswitch peek on $%04x %v: $%02x\n", address, name, value) } return value } func (p *ioC0Page) poke(address uint16, value uint8) { - if p.trace { - fmt.Printf("Softswtich poke on $%04x with %02x\n", address, value) - } pageAddress := uint8(address) ss := p.softSwitchesW[pageAddress] if ss == nil { @@ -134,5 +136,9 @@ func (p *ioC0Page) poke(address uint16, value uint8) { } return } + if p.trace && address != 0xc000 { + name := p.softSwitchesWName[pageAddress] + fmt.Printf("Softswitch poke on $%04x %v with $%02x\n", address, name, value) + } ss(p, value) } diff --git a/softSwitches2.go b/softSwitches2.go index 7d84de0..67725d7 100644 --- a/softSwitches2.go +++ b/softSwitches2.go @@ -24,53 +24,53 @@ const ( func addApple2SoftSwitches(io *ioC0Page) { - io.addSoftSwitchRW(0x00, keySoftSwitch) // Keyboard - io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch) // Keyboard Strobe - io.addSoftSwitchR(0x20, notImplementedSoftSwitchR) // Cassette Output - io.addSoftSwitchR(0x30, speakerSoftSwitch) // Speaker - io.addSoftSwitchR(0x40, notImplementedSoftSwitchR) // Game connector Strobe + io.addSoftSwitchRW(0x00, keySoftSwitch, "KEYBOARD") // Keyboard + io.addSoftSwitchRW(0x10, strobeKeyboardSoftSwitch, "AKD") // Keyboard Strobe + io.addSoftSwitchR(0x20, notImplementedSoftSwitchR, "TAPEOUT") // Cassette Output + io.addSoftSwitchR(0x30, speakerSoftSwitch, "SPEAKER") // Speaker + io.addSoftSwitchR(0x40, notImplementedSoftSwitchR, "STROBE") // Game connector Strobe // Note: Some sources indicate that all these cover 16 positions // for read and write. But the Apple2e take over some of them, with // the prevention on acting only on writes. - io.addSoftSwitchRW(0x50, getSoftSwitch(ioFlagText, false)) - io.addSoftSwitchRW(0x51, getSoftSwitch(ioFlagText, true)) - io.addSoftSwitchRW(0x52, getSoftSwitch(ioFlagMixed, false)) - io.addSoftSwitchRW(0x53, getSoftSwitch(ioFlagMixed, true)) - io.addSoftSwitchRW(0x54, getSoftSwitch(ioFlagSecondPage, false)) - io.addSoftSwitchRW(0x55, getSoftSwitch(ioFlagSecondPage, true)) - io.addSoftSwitchRW(0x56, getSoftSwitch(ioFlagHiRes, false)) - io.addSoftSwitchRW(0x57, getSoftSwitch(ioFlagHiRes, true)) + io.addSoftSwitchRW(0x50, getSoftSwitch(ioFlagText, false), "TEXTOFF") + io.addSoftSwitchRW(0x51, getSoftSwitch(ioFlagText, true), "TEXTON") + io.addSoftSwitchRW(0x52, getSoftSwitch(ioFlagMixed, false), "MIXEDOFF") + io.addSoftSwitchRW(0x53, getSoftSwitch(ioFlagMixed, true), "MIXEDON") + io.addSoftSwitchRW(0x54, getSoftSwitch(ioFlagSecondPage, false), "PAGE2OFF") + io.addSoftSwitchRW(0x55, getSoftSwitch(ioFlagSecondPage, true), "PAGE2ON") + io.addSoftSwitchRW(0x56, getSoftSwitch(ioFlagHiRes, false), "HIRESOFF") + io.addSoftSwitchRW(0x57, getSoftSwitch(ioFlagHiRes, true), "HIRESON") - io.addSoftSwitchRW(0x58, getSoftSwitch(ioFlagAnnunciator0, false)) - io.addSoftSwitchRW(0x59, getSoftSwitch(ioFlagAnnunciator0, true)) - io.addSoftSwitchRW(0x5a, getSoftSwitch(ioFlagAnnunciator1, false)) - io.addSoftSwitchRW(0x5b, getSoftSwitch(ioFlagAnnunciator1, true)) - io.addSoftSwitchRW(0x5c, getSoftSwitch(ioFlagAnnunciator2, false)) - io.addSoftSwitchRW(0x5d, getSoftSwitch(ioFlagAnnunciator2, true)) - io.addSoftSwitchRW(0x5e, getSoftSwitch(ioFlagAnnunciator3, false)) - io.addSoftSwitchRW(0x5f, getSoftSwitch(ioFlagAnnunciator3, true)) + io.addSoftSwitchRW(0x58, getSoftSwitch(ioFlagAnnunciator0, false), "ANN0OFF") + io.addSoftSwitchRW(0x59, getSoftSwitch(ioFlagAnnunciator0, true), "ANN0ON") + io.addSoftSwitchRW(0x5a, getSoftSwitch(ioFlagAnnunciator1, false), "ANN1OFF") + io.addSoftSwitchRW(0x5b, getSoftSwitch(ioFlagAnnunciator1, true), "ANN1ON") + io.addSoftSwitchRW(0x5c, getSoftSwitch(ioFlagAnnunciator2, false), "ANN2OFF") + io.addSoftSwitchRW(0x5d, getSoftSwitch(ioFlagAnnunciator2, true), "ANN2ON") + io.addSoftSwitchRW(0x5e, getSoftSwitch(ioFlagAnnunciator3, false), "ANN3OFF") + io.addSoftSwitchRW(0x5f, getSoftSwitch(ioFlagAnnunciator3, true), "ANN3ON") - io.addSoftSwitchR(0x60, notImplementedSoftSwitchR) // Cassette Input - io.addSoftSwitchR(0x61, getButtonSoftSwitch(0)) - io.addSoftSwitchR(0x62, getButtonSoftSwitch(1)) - io.addSoftSwitchR(0x63, getButtonSoftSwitch(2)) - io.addSoftSwitchR(0x64, getPaddleSoftSwitch(0)) - io.addSoftSwitchR(0x65, getPaddleSoftSwitch(1)) - io.addSoftSwitchR(0x66, getPaddleSoftSwitch(2)) - io.addSoftSwitchR(0x67, getPaddleSoftSwitch(3)) + io.addSoftSwitchR(0x60, notImplementedSoftSwitchR, "CASSETTE") // Cassette Input + io.addSoftSwitchR(0x61, getButtonSoftSwitch(0), "PB0") + io.addSoftSwitchR(0x62, getButtonSoftSwitch(1), "PB1") + io.addSoftSwitchR(0x63, getButtonSoftSwitch(2), "PB2") + io.addSoftSwitchR(0x64, getPaddleSoftSwitch(0), "PDL0") + io.addSoftSwitchR(0x65, getPaddleSoftSwitch(1), "PDL1") + io.addSoftSwitchR(0x66, getPaddleSoftSwitch(2), "PDL2") + io.addSoftSwitchR(0x67, getPaddleSoftSwitch(3), "PDL3") // The previous 8 softswitches are repeated - io.addSoftSwitchR(0x68, notImplementedSoftSwitchR) // Cassette Input - io.addSoftSwitchR(0x69, getButtonSoftSwitch(0)) - io.addSoftSwitchR(0x6A, getButtonSoftSwitch(1)) - io.addSoftSwitchR(0x6B, getButtonSoftSwitch(2)) - io.addSoftSwitchR(0x6C, getPaddleSoftSwitch(0)) - io.addSoftSwitchR(0x6D, getPaddleSoftSwitch(1)) - io.addSoftSwitchR(0x6E, getPaddleSoftSwitch(2)) - io.addSoftSwitchR(0x6F, getPaddleSoftSwitch(3)) + io.addSoftSwitchR(0x68, notImplementedSoftSwitchR, "CASSETTE") // Cassette Input + io.addSoftSwitchR(0x69, getButtonSoftSwitch(0), "PB0") + io.addSoftSwitchR(0x6A, getButtonSoftSwitch(1), "PB1") + io.addSoftSwitchR(0x6B, getButtonSoftSwitch(2), "PB2") + io.addSoftSwitchR(0x6C, getPaddleSoftSwitch(0), "PDL0") + io.addSoftSwitchR(0x6D, getPaddleSoftSwitch(1), "PDL1") + io.addSoftSwitchR(0x6E, getPaddleSoftSwitch(2), "PDL2") + io.addSoftSwitchR(0x6F, getPaddleSoftSwitch(3), "PDL3") - io.addSoftSwitchR(0x70, strobePaddlesSoftSwitch) // Game controllers reset + io.addSoftSwitchR(0x70, strobePaddlesSoftSwitch, "RESETPDL") // Game controllers reset } func notImplementedSoftSwitchR(*ioC0Page) uint8 { diff --git a/softSwitches2e.go b/softSwitches2e.go index 4d92821..d7234f9 100644 --- a/softSwitches2e.go +++ b/softSwitches2e.go @@ -1,38 +1,62 @@ package apple2 +/* + See: + https://www.apple.asimov.net/documentation/hardware/machines/APPLE%20IIe%20Auxiliary%20Memory%20Softswitches.pdf +*/ + const ( + ioFlagRamRd uint8 = 0x13 + ioFlagRamWrt uint8 = 0x14 ioFlagIntCxRom uint8 = 0x15 + ioFlagAltZp uint8 = 0x16 ioFlagSlotC3Rom uint8 = 0x17 ioFlag80Store uint8 = 0x18 - ioFlagAltChar uint8 = 0x19 + ioFlagAltChar uint8 = 0x1E ioFlag80Col uint8 = 0x1F + // ??? ioVertBlank uin8 = 0x19 ) func addApple2ESoftSwitches(io *ioC0Page) { // New MMU read softswithes - io.addSoftSwitchW(0x06, getSoftSwitchExt(ioFlagIntCxRom, ssOff, softSwitchIntCxRomOff)) - io.addSoftSwitchW(0x07, getSoftSwitchExt(ioFlagIntCxRom, ssOn, softSwitchIntCxRomOn)) - io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagIntCxRom)) - io.addSoftSwitchW(0x0A, getSoftSwitchExt(ioFlagSlotC3Rom, ssOff, softSwitchSlotC3RomOff)) - io.addSoftSwitchW(0x0B, getSoftSwitchExt(ioFlagSlotC3Rom, ssOn, softSwitchSlotC3RomOn)) - io.addSoftSwitchR(0x17, getStatusSoftSwitch(ioFlagSlotC3Rom)) + io.addSoftSwitchW(0x02, getSoftSwitchExt(ioFlagRamRd, ssOff, nil), "RAMRDOFF") + io.addSoftSwitchW(0x03, getSoftSwitchExt(ioFlagRamWrt, ssOn, nil), "RAMRDON") + io.addSoftSwitchR(0x13, getStatusSoftSwitch(ioFlagRamWrt), "RAMRD") + + io.addSoftSwitchW(0x04, getSoftSwitchExt(ioFlagRamWrt, ssOff, nil), "RAMWRTOFF") + io.addSoftSwitchW(0x05, getSoftSwitchExt(ioFlagRamWrt, ssOn, nil), "RAMWRTON") + io.addSoftSwitchR(0x14, getStatusSoftSwitch(ioFlagRamWrt), "RAMWRT") + + io.addSoftSwitchW(0x06, getSoftSwitchExt(ioFlagIntCxRom, ssOff, softSwitchIntCxRomOff), "INTCXROMOFF") + io.addSoftSwitchW(0x07, getSoftSwitchExt(ioFlagIntCxRom, ssOn, softSwitchIntCxRomOn), "INTCXROMON") + io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagIntCxRom), "INTCXROM") + + io.addSoftSwitchW(0x08, getSoftSwitchExt(ioFlagAltZp, ssOff, nil), "ALTZPOFF") + io.addSoftSwitchW(0x09, getSoftSwitchExt(ioFlagAltZp, ssOn, nil), "ALTZPON") + io.addSoftSwitchR(0x16, getStatusSoftSwitch(ioFlagAltZp), "ALTZP") + + io.addSoftSwitchW(0x0A, getSoftSwitchExt(ioFlagSlotC3Rom, ssOff, softSwitchSlotC3RomOff), "SLOTC3ROMOFF") + io.addSoftSwitchW(0x0B, getSoftSwitchExt(ioFlagSlotC3Rom, ssOn, softSwitchSlotC3RomOn), "SLOTC3ROMON") + io.addSoftSwitchR(0x17, getStatusSoftSwitch(ioFlagSlotC3Rom), "SLOTC3ROM") // Previous read softswithes - io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText)) - io.addSoftSwitchR(0x1B, getStatusSoftSwitch(ioFlagMixed)) - io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage)) - io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes)) + io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText), "TEXT") + io.addSoftSwitchR(0x1B, getStatusSoftSwitch(ioFlagMixed), "MIXED") + io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage), "PAGE2") + io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes), "HIRES") // New IOU read softswithes - io.addSoftSwitchW(0x00, getSoftSwitchExt(ioFlag80Store, ssOff, nil)) - io.addSoftSwitchW(0x01, getSoftSwitchExt(ioFlag80Store, ssOn, nil)) - io.addSoftSwitchR(0x18, getStatusSoftSwitch(ioFlag80Store)) - io.addSoftSwitchW(0x0C, getSoftSwitchExt(ioFlag80Col, ssOff, nil)) - io.addSoftSwitchW(0x0D, getSoftSwitchExt(ioFlag80Col, ssOn, nil)) - io.addSoftSwitchR(0x1F, getStatusSoftSwitch(ioFlag80Col)) - io.addSoftSwitchW(0x0E, getSoftSwitchExt(ioFlagAltChar, ssOff, nil)) - io.addSoftSwitchW(0x0F, getSoftSwitchExt(ioFlagAltChar, ssOn, nil)) - io.addSoftSwitchR(0x1E, getStatusSoftSwitch(ioFlagAltChar)) + io.addSoftSwitchW(0x00, getSoftSwitchExt(ioFlag80Store, ssOff, nil), "80STOREOFF") + io.addSoftSwitchW(0x01, getSoftSwitchExt(ioFlag80Store, ssOn, nil), "80STOREON") + io.addSoftSwitchR(0x18, getStatusSoftSwitch(ioFlag80Store), "80STORE") + + io.addSoftSwitchW(0x0C, getSoftSwitchExt(ioFlag80Col, ssOff, nil), "80COLOFF") + io.addSoftSwitchW(0x0D, getSoftSwitchExt(ioFlag80Col, ssOn, nil), "80COLON") + io.addSoftSwitchR(0x1F, getStatusSoftSwitch(ioFlag80Col), "80COL") + + io.addSoftSwitchW(0x0E, getSoftSwitchExt(ioFlagAltChar, ssOff, nil), "ALTCHARSETOFF") + io.addSoftSwitchW(0x0F, getSoftSwitchExt(ioFlagAltChar, ssOn, nil), "ALTCHARSETON") + io.addSoftSwitchR(0x1E, getStatusSoftSwitch(ioFlagAltChar), "ALTCHARSET") // TOOD: // AKD read on 0x10