From cccb0583db887b65182155c90cc7a81ef3d3b6b9 Mon Sep 17 00:00:00 2001 From: Ivan Izaguirre Date: Fri, 17 May 2019 09:54:49 +0200 Subject: [PATCH] Support for the Saturn 128KB card --- apple2/apple2.go | 7 +++ apple2/cardSaturn.go | 146 +++++++++++++++++++++++++++++++++++++++++++ main.go | 3 +- 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 apple2/cardSaturn.go diff --git a/apple2/apple2.go b/apple2/apple2.go index fb5ec15..62e6b15 100644 --- a/apple2/apple2.go +++ b/apple2/apple2.go @@ -77,6 +77,13 @@ func (a *Apple2) AddLanguageCard(slot int) { d.applyState() } +// AddSaturnCard inserts a 128Kb card +func (a *Apple2) AddSaturnCard(slot int) { + d := newCardSaturn() + d.cardBase.insert(a, slot) + d.applyState() +} + // ConfigureStdConsole uses stdin and stdout to interface with the Apple2 func (a *Apple2) ConfigureStdConsole(stdinKeyboard bool, stdoutScreen bool) { if !stdinKeyboard && !stdoutScreen { diff --git a/apple2/cardSaturn.go b/apple2/cardSaturn.go new file mode 100644 index 0000000..3ed7e73 --- /dev/null +++ b/apple2/cardSaturn.go @@ -0,0 +1,146 @@ +package apple2 + +/* + +RAM card with 128Kb. It's like 8 language cards. + +http://www.applelogic.org/files/SATURN128MAN.pdf + +*/ + +type cardSaturn struct { + cardBase + readState bool + writeState int + activeBank int + activeBlock int + ramBankA [8]*memoryRange // First 4kb to map in 0xD000-0xDFFF + ramBankB [8]*memoryRange // Second 4kb to map in 0xD000-0xDFFF + ramUpper [8]*memoryRange // Upper 8kb to map in 0xE000-0xFFFF +} + +const ( + // Write enabling requires two sofstwitch accesses + saturnWriteDisabled = 0 + saturnWriteHalfEnabled = 1 + saturnWriteEnabled = 2 +) + +func newCardSaturn() *cardSaturn { + var c cardSaturn + c.readState = false + c.writeState = lcWriteEnabled + c.activeBank = 1 + + for i := 0; i < 8; i++ { + c.ramBankA[i] = newMemoryRange(0xd000, make([]uint8, 0x1000)) + c.ramBankB[i] = newMemoryRange(0xd000, make([]uint8, 0x1000)) + c.ramUpper[i] = newMemoryRange(0xe000, make([]uint8, 0x2000)) + } + for i := 0x0; i <= 0xf; i++ { + iCopy := i + c.ssr[i] = func(*ioC0Page) uint8 { + c.ssAction(iCopy) + return 0 + } + c.ssw[i] = func(*ioC0Page, uint8) { + // Writing resets write count (from A2AUDIT) + c.writeState = lcWriteDisabled + } + } + return &c +} + +func (c *cardSaturn) ssAction(ss int) { + switch ss { + case 0: + // RAM read, no writes + c.activeBank = 0 + c.readState = true + c.writeState = lcWriteDisabled + case 1: + // ROM read, RAM write + c.activeBank = 0 + c.readState = false + c.writeState++ + case 2: + // ROM read, no writes + c.activeBank = 0 + c.readState = false + c.writeState = lcWriteDisabled + case 3: + //RAM read, RAM write + c.activeBank = 0 + c.readState = true + c.writeState++ + case 4: + c.activeBlock = 0 + case 5: + c.activeBlock = 1 + case 6: + c.activeBlock = 2 + case 7: + c.activeBlock = 3 + case 8: + // RAM read, no writes + c.activeBank = 1 + c.readState = true + c.writeState = lcWriteDisabled + case 9: + // ROM read, RAM write + c.activeBank = 1 + c.readState = false + c.writeState++ + case 10: + // ROM read, no writes + c.activeBank = 1 + c.readState = false + c.writeState = lcWriteDisabled + case 11: + //RAM read, RAM write + c.activeBank = 1 + c.readState = true + c.writeState++ + case 12: + c.activeBlock = 0 + case 13: + c.activeBlock = 1 + case 14: + c.activeBlock = 2 + case 15: + c.activeBlock = 3 + } + + if c.writeState > lcWriteEnabled { + c.writeState = lcWriteEnabled + } + + c.applyState() +} + +func (c *cardSaturn) getActiveBank() [8]*memoryRange { + if c.activeBank == 0 { + return c.ramBankA + } + return c.ramBankB +} + +func (c *cardSaturn) applyState() { + mmu := c.a.mmu + block := c.activeBlock + + if c.readState { + mmu.setPagesRead(0xd0, 0xdf, c.getActiveBank()[block]) + mmu.setPagesRead(0xe0, 0xff, c.ramUpper[block]) + } else { + mmu.setPagesRead(0xd0, 0xff, mmu.physicalROM) + } + + if c.writeState == lcWriteEnabled { + mmu.setPagesWrite(0xd0, 0xdf, c.getActiveBank()[block]) + mmu.setPagesWrite(0xe0, 0xff, c.ramUpper[block]) + } else { + mmu.setPagesWrite(0xd0, 0xff, nil) + } + +} diff --git a/main.go b/main.go index a03d1aa..dd4ebe6 100644 --- a/main.go +++ b/main.go @@ -69,7 +69,8 @@ func main() { log := false a := apple2.NewApple2(*romFile, *charRomFile, *cpuClock, !*mono, *fastDisk, *panicSS) - a.AddLanguageCard(0) + //a.AddLanguageCard(0) + a.AddSaturnCard(0) if *disk2Slot > 0 { a.AddDisk2(*disk2Slot, *disk2RomFile, *diskImage) }