Fix shadow slot 3 ROM in Apple //e

This commit is contained in:
Ivan Izaguirre 2019-11-06 00:02:03 +01:00 committed by Iván Izaguirre
parent 09117fd7c5
commit a28745ab83
4 changed files with 71 additions and 69 deletions

View File

@ -32,7 +32,7 @@ type cardLanguage struct {
cardBase cardBase
readState bool readState bool
writeState uint8 writeState uint8
altBank bool altBank bool // false is bank1, true is bank2
} }
const ( const (
@ -45,7 +45,7 @@ const (
func (c *cardLanguage) assign(a *Apple2, slot int) { func (c *cardLanguage) assign(a *Apple2, slot int) {
c.readState = false c.readState = false
c.writeState = lcWriteEnabled c.writeState = lcWriteEnabled
c.altBank = true c.altBank = true // Start on bank2
if a.isApple2e { if a.isApple2e {
// The Apple //e with 128kb has two blocks of language upper RAM // The Apple //e with 128kb has two blocks of language upper RAM
@ -69,7 +69,7 @@ func (c *cardLanguage) assign(a *Apple2, slot int) {
} }
func (c *cardLanguage) ssAction(ss uint8, write bool) { func (c *cardLanguage) ssAction(ss uint8, write bool) {
c.altBank = ((ss >> 3) & 1) == 1 c.altBank = ((ss >> 3) & 1) == 0
action := ss & 0x3 action := ss & 0x3
switch action { switch action {
case 0: case 0:

View File

@ -148,3 +148,10 @@ func (p *ioC0Page) poke(address uint16, value uint8) {
} }
ss(p, value) ss(p, value)
} }
func ssFromBool(value bool) uint8 {
if value {
return ssOn
}
return ssOff
}

View File

@ -36,8 +36,8 @@ type memoryManager struct {
altZeroPage bool // Use extra RAM from 0x0000 to 0x01ff. And additional language card block altZeroPage bool // Use extra RAM from 0x0000 to 0x01ff. And additional language card block
altMainRAMActiveRead bool // Use extra RAM from 0x0200 to 0xbfff for read altMainRAMActiveRead bool // Use extra RAM from 0x0200 to 0xbfff for read
altMainRAMActiveWrite bool // Use extra RAM from 0x0200 to 0xbfff for write altMainRAMActiveWrite bool // Use extra RAM from 0x0200 to 0xbfff for write
c3ROMActive bool // Apple2e slot 3 ROM shadow slotC3ROMActive bool // Apple2e slot 3 ROM shadow
cxROMActive bool // Apple2e slots ROM shadow intCxROMActive bool // Apple2e slots internal ROM shadow
activeSlot uint8 // Active slot owner of 0xc800 to 0xcfff activeSlot uint8 // Active slot owner of 0xc800 to 0xcfff
// Configuration switches, Base64A // Configuration switches, Base64A
@ -67,8 +67,47 @@ func newMemoryManager(a *Apple2) *memoryManager {
return &mmu return &mmu
} }
func (mmu *memoryManager) accessCArea(address uint16) memoryHandler {
if mmu.intCxROMActive {
return mmu.physicalROMe
}
// First slot area
if address <= addressLimitSlots {
slot := uint8((address >> 8) & 0x07)
mmu.activeSlot = slot
if !mmu.slotC3ROMActive && (slot == 3) {
return mmu.physicalROMe
}
return mmu.cardsROM[slot]
}
// Extra slot area
if address == ioC8Off {
// Reset extra slot area owner
mmu.activeSlot = 0
}
if !mmu.slotC3ROMActive && (mmu.activeSlot == 3) {
return mmu.physicalROMe
}
return mmu.cardsROMExtra[mmu.activeSlot]
}
func (mmu *memoryManager) accessLCArea(address uint16) memoryHandler {
block := mmu.lcSelectedBlock
if mmu.altZeroPage {
block = 1
}
if address <= addressLimitDArea {
if mmu.lcAltBank {
return mmu.physicalDAltRAM[block]
}
return mmu.physicalDRAM[block]
}
return mmu.physicalEFRAM[block]
}
func (mmu *memoryManager) accessRead(address uint16) memoryHandler { func (mmu *memoryManager) accessRead(address uint16) memoryHandler {
// First two pages // First two pages, $00xx and $01xx
if address <= addressLimitZero { if address <= addressLimitZero {
if mmu.altZeroPage { if mmu.altZeroPage {
return mmu.physicalMainRAMAlt return mmu.physicalMainRAMAlt
@ -84,46 +123,19 @@ func (mmu *memoryManager) accessRead(address uint16) memoryHandler {
return mmu.physicalMainRAM return mmu.physicalMainRAM
} }
// IO section // IO section, $C0cc
if address <= addressLimitIO { if address <= addressLimitIO {
return mmu.apple2.io return mmu.apple2.io
} }
// Slots sections // Slots sections, $Cxxx
if address <= addressLimitSlotsExtra { if address <= addressLimitSlotsExtra {
slot := uint8((address >> 8) & 0x07) return mmu.accessCArea(address)
if mmu.cxROMActive {
return mmu.physicalROMe
}
// First slot area
if address <= addressLimitSlots {
if mmu.c3ROMActive && (slot == 3) {
return mmu.physicalROMe
}
mmu.activeSlot = slot
return mmu.cardsROM[slot]
}
// Extra slot area
if address == ioC8Off {
// Reset extra slot area owner
mmu.activeSlot = 0
}
return mmu.cardsROMExtra[slot]
} }
// Upper address area // Upper address area
if mmu.lcActiveRead { if mmu.lcActiveRead {
block := mmu.lcSelectedBlock return mmu.accessLCArea(address)
if mmu.altZeroPage {
block = 1
}
if address <= addressLimitDArea {
if mmu.lcAltBank {
return mmu.physicalDAltRAM[block]
}
return mmu.physicalDRAM[block]
}
return mmu.physicalEFRAM[block]
} }
// Use ROM // Use ROM
@ -131,7 +143,7 @@ func (mmu *memoryManager) accessRead(address uint16) memoryHandler {
} }
func (mmu *memoryManager) accessWrite(address uint16) memoryHandler { func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
// First two pages // First two pages, $00xx and $01xx
if address <= addressLimitZero { if address <= addressLimitZero {
if mmu.altZeroPage { if mmu.altZeroPage {
return mmu.physicalMainRAMAlt return mmu.physicalMainRAMAlt
@ -147,40 +159,19 @@ func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
return mmu.physicalMainRAM return mmu.physicalMainRAM
} }
// IO section // IO section, $C0xx
if address <= addressLimitIO { if address <= addressLimitIO {
return mmu.apple2.io return mmu.apple2.io
} }
// Slots sections // Slots sections, $Cxxx
if address <= addressLimitSlotsExtra { if address <= addressLimitSlotsExtra {
slot := uint8((address >> 8) & 0x07) return mmu.accessCArea(address)
// First slot area
if address <= addressLimitSlots {
mmu.activeSlot = slot
return mmu.cardsROM[slot]
}
// Extra slot area
if address == ioC8Off {
// Reset extra slot area owner
mmu.activeSlot = 0
}
return mmu.cardsROMExtra[slot]
} }
// Upper address area // Upper address area
if mmu.lcActiveWrite { if mmu.lcActiveWrite {
block := mmu.lcSelectedBlock return mmu.accessLCArea(address)
if mmu.altZeroPage {
block = 1
}
if address <= addressLimitDArea {
if mmu.lcAltBank {
return mmu.physicalDAltRAM[block]
}
return mmu.physicalDRAM[block]
}
return mmu.physicalEFRAM[block]
} }
// Use ROM // Use ROM

View File

@ -17,9 +17,9 @@ func addApple2ESoftSwitches(io *ioC0Page) {
mmu := io.apple2.mmu mmu := io.apple2.mmu
addSoftSwitchesMmu(io, 0x02, 0x03, 0x13, &mmu.altMainRAMActiveRead, "RAMRD") addSoftSwitchesMmu(io, 0x02, 0x03, 0x13, &mmu.altMainRAMActiveRead, "RAMRD")
addSoftSwitchesMmu(io, 0x04, 0x05, 0x14, &mmu.altMainRAMActiveWrite, "RAMWRT") addSoftSwitchesMmu(io, 0x04, 0x05, 0x14, &mmu.altMainRAMActiveWrite, "RAMWRT")
addSoftSwitchesMmu(io, 0x06, 0x07, 0x15, &mmu.cxROMActive, "INTCXROM") addSoftSwitchesMmu(io, 0x06, 0x07, 0x15, &mmu.intCxROMActive, "INTCXROM")
addSoftSwitchesMmu(io, 0x08, 0x09, 0x16, &mmu.altZeroPage, "ALTZP") addSoftSwitchesMmu(io, 0x08, 0x09, 0x16, &mmu.altZeroPage, "ALTZP")
addSoftSwitchesMmu(io, 0x0a, 0x0b, 0x17, &mmu.c3ROMActive, "SLOTC3ROM") addSoftSwitchesMmu(io, 0x0a, 0x0b, 0x17, &mmu.slotC3ROMActive, "SLOTC3ROM")
// New IOU read softswithes // New IOU read softswithes
addSoftSwitchesIou(io, 0x00, 0x01, 0x18, ioFlag80Store, "80STORE") addSoftSwitchesIou(io, 0x00, 0x01, 0x18, ioFlag80Store, "80STORE")
@ -32,6 +32,13 @@ func addApple2ESoftSwitches(io *ioC0Page) {
io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage), "PAGE2") io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage), "PAGE2")
io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes), "HIRES") io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes), "HIRES")
io.addSoftSwitchR(0x11, func(_ *ioC0Page) uint8 {
return ssFromBool(mmu.lcAltBank)
}, "BSRBANK2")
io.addSoftSwitchR(0x12, func(_ *ioC0Page) uint8 {
return ssFromBool(mmu.lcActiveRead)
}, "BSRREADRAM")
// TOOD: // TOOD:
// AKD read on 0x10 // AKD read on 0x10
// VBL read on 0x19 // VBL read on 0x19
@ -50,10 +57,7 @@ func addSoftSwitchesMmu(io *ioC0Page, addressClear uint8, addressSet uint8, Addr
}, name+"ON") }, name+"ON")
io.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 { io.addSoftSwitchR(AddressGet, func(_ *ioC0Page) uint8 {
if *flag { return ssFromBool(*flag)
return ssOn
}
return ssOff
}, name) }, name)
} }