From f3d0f6e11188cc93cf8ded2fdf930abc7d2029cf Mon Sep 17 00:00:00 2001 From: Ivan Izaguirre Date: Sun, 24 May 2020 18:17:36 +0200 Subject: [PATCH] IIc softswitches --- apple2.go | 2 +- apple2Setup.go | 3 +- ioC0Page.go | 41 ++++++++++++++++++++ softSwitches2.go | 17 +++++---- softSwitches2c.go | 96 +++++++++++++++++++++++++++++++++++++++++++++++ softSwitches2e.go | 44 ++++------------------ 6 files changed, 156 insertions(+), 47 deletions(-) create mode 100644 softSwitches2c.go diff --git a/apple2.go b/apple2.go index 7545592..c473a30 100644 --- a/apple2.go +++ b/apple2.go @@ -19,7 +19,7 @@ type Apple2 struct { io *ioC0Page cg *CharacterGenerator cards [8]card - isApple2e bool + isApple2e bool // Or IIc. TODO: remove uses commandChannel chan int cycleDurationNs float64 // Current speed. Inverse of the cpu clock in Ghz isColor bool diff --git a/apple2Setup.go b/apple2Setup.go index 4e4d68f..0408394 100644 --- a/apple2Setup.go +++ b/apple2Setup.go @@ -53,8 +53,7 @@ func newApple2c() *Apple2 { a.mmu.InitRAMalt() addApple2SoftSwitches(a.io) addApple2ESoftSwitches(a.io) - - a.mmu.intCxROMActive = true + addApple2CSoftSwitches(a.io) return &a } diff --git a/ioC0Page.go b/ioC0Page.go index 0a9c50d..7f7a84a 100644 --- a/ioC0Page.go +++ b/ioC0Page.go @@ -94,6 +94,13 @@ func (p *ioC0Page) addSoftSwitchW(address uint8, ss softSwitchW, name string) { p.softSwitchesWName[address] = name } +func (p *ioC0Page) copySoftSwitchRW(src uint8, dst uint8) { + p.softSwitchesR[dst] = p.softSwitchesR[src] + p.softSwitchesRName[dst] = p.softSwitchesRName[src] + p.softSwitchesW[dst] = p.softSwitchesW[src] + p.softSwitchesWName[dst] = p.softSwitchesWName[src] +} + func (p *ioC0Page) isSoftSwitchActive(ioFlag uint8) bool { return (p.softSwitchesData[ioFlag] & ssOn) == ssOn } @@ -155,3 +162,37 @@ func ssFromBool(value bool) uint8 { } return ssOff } + +func (p *ioC0Page) addSoftSwitchesMmu(addressClear uint8, addressSet uint8, AddressGet uint8, flag *bool, name string) { + p.addSoftSwitchW(addressClear, func(_ *ioC0Page, _ uint8) { + *flag = false + }, name+"OFF") + + p.addSoftSwitchW(addressSet, func(_ *ioC0Page, _ uint8) { + *flag = true + }, name+"ON") + + p.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 { + return ssFromBool(*flag) + }, name) +} + +func (p *ioC0Page) disableSoftSwitchesMmu(addressClear uint8, addressSet uint8, addressGet uint8) { + p.addSoftSwitchW(addressClear, nil, "DISABLED") + p.addSoftSwitchW(addressSet, nil, "DISABLED") + p.addSoftSwitchR(addressGet, nil, "DISABLED") +} + +func (p *ioC0Page) addSoftSwitchesIou(addressClear uint8, addressSet uint8, addressGet uint8, ioFlag uint8, name string) { + p.addSoftSwitchW(addressClear, func(io *ioC0Page, _ uint8) { + io.softSwitchesData[ioFlag] = ssOff + }, name+"OFF") + + p.addSoftSwitchW(addressSet, func(io *ioC0Page, _ uint8) { + io.softSwitchesData[ioFlag] = ssOn + }, name+"ON") + + p.addSoftSwitchR(addressGet, func(io *ioC0Page) uint8 { + return io.softSwitchesData[ioFlag] + }, name) +} diff --git a/softSwitches2.go b/softSwitches2.go index e673ad6..73b40a5 100644 --- a/softSwitches2.go +++ b/softSwitches2.go @@ -12,14 +12,15 @@ const ( ioFlagAnnunciator2 uint8 = 0x5c ioFlagAnnunciator3 uint8 = 0x5e - ioDataCassette uint8 = 0x60 - ioFlagButton0 uint8 = 0x61 - ioFlagButton1 uint8 = 0x62 - ioFlagButton2 uint8 = 0x63 - ioDataPaddle0 uint8 = 0x64 - ioDataPaddle1 uint8 = 0x65 - ioDataPaddle2 uint8 = 0x66 - ioDataPaddle3 uint8 = 0x67 + ioDataCassette uint8 = 0x60 + ioFlag40ColOnly uint8 = 0x60 // Only for Apple IIc + ioFlagButton0 uint8 = 0x61 + ioFlagButton1 uint8 = 0x62 + ioFlagButton2 uint8 = 0x63 + ioDataPaddle0 uint8 = 0x64 + ioDataPaddle1 uint8 = 0x65 + ioDataPaddle2 uint8 = 0x66 + ioDataPaddle3 uint8 = 0x67 ) func addApple2SoftSwitches(io *ioC0Page) { diff --git a/softSwitches2c.go b/softSwitches2c.go new file mode 100644 index 0000000..3cec1c4 --- /dev/null +++ b/softSwitches2c.go @@ -0,0 +1,96 @@ +package apple2 + +/* + See: + Inside the Apple IIc by Gary B. Little +*/ + +const ( + ioFlagMouseXIntOcurred uint8 = 0x15 + ioFlagMouseYIntOcurred uint8 = 0x17 + ioFlagVblInt uint8 = 0x19 + ioFlagMouseXYInterrupts uint8 = 0x58 + ioFlagVblInterrupts uint8 = 0x5a + ioFlagXEdge uint8 = 0x5c + ioFlagYEdge uint8 = 0x5e + ioFlagIOUDis uint8 = 0x7e +) + +func addApple2CSoftSwitches(io *ioC0Page) { + // Disable not used IIe softswitches + io.disableSoftSwitchesMmu(0x06, 0x07, 0x15) + io.disableSoftSwitchesMmu(0x0a, 0x0b, 0x17) + + // Replace softswitches + io.addSoftSwitchR(0x60, getStatusSoftSwitch(ioFlag40ColOnly), "RD80SW") // Instead og CASSETTE + io.addSoftSwitchR(0x19, getStatusSoftSwitch(ioFlagVblInt), "VBLINT") // Replaces the not INT based in IIe + + // Mouse interrupts + io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagMouseXIntOcurred), "MOUSEX0INT") + io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagMouseYIntOcurred), "MOUSEY0INT") + + // Replacement of the IOU annunciators 0x58 to 0x5f + io.addSoftSwitchesIou(0x5f, 0x5e, 0x7f, ioFlagAnnunciator3, "DHIRES") + io.addSoftSwitchesIou(0x7e, 0x7f, 0x7e, ioFlagIOUDis, "IOUDIS") + addSoftSwitchesIouDis(io, 0x58, 0x59, 0x40, ioFlagMouseXYInterrupts, "MOUSEXYINTENABLED") + addSoftSwitchesIouDis(io, 0x5a, 0x5b, 0x41, ioFlagVblInterrupts, "VBLINTENABLED") + addSoftSwitchesIouDis(io, 0x5c, 0x5d, 0x42, ioFlagXEdge, "MOUSEXEDGE") + addSoftSwitchesIouDis(io, 0x5e, 0x5f, 0x43, ioFlagYEdge, "MOUSEYEDGE") + //io.addSoftSwitchR(0x70, notImplementedSoftSwitchR, "PTRIG") // TODO: use also for interrupt clear + + io.copySoftSwitchRW(0x7e, 0x78) + io.copySoftSwitchRW(0x7f, 0x79) + io.copySoftSwitchRW(0x7e, 0x7a) + io.copySoftSwitchRW(0x7f, 0x7b) + io.copySoftSwitchRW(0x7e, 0x7c) + io.copySoftSwitchRW(0x7f, 0x7d) + + // 0x98: port 1 data register + // 0x99: port 1 status register & reset + // 0x9a: port 1 command register + // 0x9b: port 1 control register + + // 0xa8: port 2 data register + // 0xa9: port 2 status register & reset + // 0xaa: port 2 command register, used for keyboard interrupts (InsideIIc,332) + // 0xab: port 2 control register + + // Plus a language card in pseudo slot 0 and a disk II card in slot 6 + + // Initial values + io.softSwitchesData[ioFlag40ColOnly] = ssOn // The switch will always be off + io.softSwitchesData[ioFlagIOUDis] = ssOn // Verified on Apple IIc ROM FF + mmu := io.apple2.mmu + mmu.intCxROMActive = true +} + +func addSoftSwitchesIouDis(p *ioC0Page, addressClear uint8, addressSet uint8, + addressGet uint8, ioFlag uint8, name string) { + + prevClear := p.softSwitchesW[addressClear] + p.addSoftSwitchW(addressClear, func(io *ioC0Page, value uint8) { + if io.softSwitchesData[ioFlagIOUDis] == ssOn { + io.softSwitchesData[ioFlag] = ssOff + } else { + prevClear(io, value) + } + }, name+"OFF") + + prevSet := p.softSwitchesW[addressClear] + p.addSoftSwitchW(addressSet, func(io *ioC0Page, value uint8) { + if io.softSwitchesData[ioFlagIOUDis] == ssOn { + io.softSwitchesData[ioFlag] = ssOn + } else { + prevSet(io, value) + } + }, name+"ON") + + prevGet := p.softSwitchesR[addressGet] + p.addSoftSwitchR(addressGet, func(io *ioC0Page) uint8 { + if io.softSwitchesData[ioFlagIOUDis] == ssOn { + return io.softSwitchesData[ioFlag] + } + return prevGet(io) + }, name) + +} diff --git a/softSwitches2e.go b/softSwitches2e.go index 433ac10..dcc3fd0 100644 --- a/softSwitches2e.go +++ b/softSwitches2e.go @@ -18,16 +18,16 @@ const ( func addApple2ESoftSwitches(io *ioC0Page) { // New MMU read softswithes mmu := io.apple2.mmu - addSoftSwitchesMmu(io, 0x02, 0x03, 0x13, &mmu.altMainRAMActiveRead, "RAMRD") - addSoftSwitchesMmu(io, 0x04, 0x05, 0x14, &mmu.altMainRAMActiveWrite, "RAMWRT") - addSoftSwitchesMmu(io, 0x06, 0x07, 0x15, &mmu.intCxROMActive, "INTCXROM") - addSoftSwitchesMmu(io, 0x08, 0x09, 0x16, &mmu.altZeroPage, "ALTZP") - addSoftSwitchesMmu(io, 0x0a, 0x0b, 0x17, &mmu.slotC3ROMActive, "SLOTC3ROM") - addSoftSwitchesMmu(io, 0x00, 0x01, 0x18, &mmu.store80Active, "80STORE") + io.addSoftSwitchesMmu(0x02, 0x03, 0x13, &mmu.altMainRAMActiveRead, "RAMRD") + io.addSoftSwitchesMmu(0x04, 0x05, 0x14, &mmu.altMainRAMActiveWrite, "RAMWRT") + io.addSoftSwitchesMmu(0x06, 0x07, 0x15, &mmu.intCxROMActive, "INTCXROM") + io.addSoftSwitchesMmu(0x08, 0x09, 0x16, &mmu.altZeroPage, "ALTZP") + io.addSoftSwitchesMmu(0x0a, 0x0b, 0x17, &mmu.slotC3ROMActive, "SLOTC3ROM") + io.addSoftSwitchesMmu(0x00, 0x01, 0x18, &mmu.store80Active, "80STORE") // New IOU read softswithes - addSoftSwitchesIou(io, 0x0c, 0x0d, 0x1f, ioFlag80Col, "80COL") - addSoftSwitchesIou(io, 0x0e, 0x0f, 0x1e, ioFlagAltChar, "ALTCHARSET") + io.addSoftSwitchesIou(0x0c, 0x0d, 0x1f, ioFlag80Col, "80COL") + io.addSoftSwitchesIou(0x0e, 0x0f, 0x1e, ioFlagAltChar, "ALTCHARSET") // Previous read softswithes io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText), "TEXT") @@ -59,31 +59,3 @@ func addApple2ESoftSwitches(io *ioC0Page) { //io.softSwitchesData[ioFlagAltChar] = ssOn // Not sure about this. } - -func addSoftSwitchesMmu(io *ioC0Page, addressClear uint8, addressSet uint8, AddressGet uint8, flag *bool, name string) { - io.addSoftSwitchW(addressClear, func(_ *ioC0Page, _ uint8) { - *flag = false - }, name+"OFF") - - io.addSoftSwitchW(addressSet, func(_ *ioC0Page, _ uint8) { - *flag = true - }, name+"ON") - - io.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 { - return ssFromBool(*flag) - }, name) -} - -func addSoftSwitchesIou(io *ioC0Page, addressClear uint8, addressSet uint8, AddressGet uint8, ioFlag uint8, name string) { - io.addSoftSwitchW(addressClear, func(_ *ioC0Page, _ uint8) { - io.softSwitchesData[ioFlag] = ssOff - }, name+"OFF") - - io.addSoftSwitchW(addressSet, func(_ *ioC0Page, _ uint8) { - io.softSwitchesData[ioFlag] = ssOn - }, name+"ON") - - io.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 { - return io.softSwitchesData[ioFlag] - }, name) -}