mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-22 09:30:19 +00:00
ROM can be paged, refactor the Base64A ROM
This commit is contained in:
parent
63c982d976
commit
9c27175f86
40
base64a.go
40
base64a.go
@ -1,8 +1,6 @@
|
||||
package izapple2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
import "fmt"
|
||||
|
||||
/*
|
||||
Copam BASE64A adaptation.
|
||||
@ -36,14 +34,16 @@ func loadBase64aRom(a *Apple2) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Create banks
|
||||
for j := range romBanksBytes {
|
||||
a.mmu.physicalROM[j] = newMemoryRange(0xd000, romBanksBytes[j], fmt.Sprintf("Base64 ROM page %v", j))
|
||||
// Create paged ROM
|
||||
romData := make([]uint8, 0, base64aRomBankSize*base64aRomBankCount)
|
||||
for _, bank := range romBanksBytes {
|
||||
romData = append(romData, bank...)
|
||||
}
|
||||
rom := newMemoryRangePagedROM(0xd000, romData, "Base64 ROM", base64aRomBankCount)
|
||||
|
||||
// Start with first bank active
|
||||
a.mmu.setActiveROMPage(0)
|
||||
|
||||
rom.setPage(0)
|
||||
a.mmu.physicalROM = rom
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -55,23 +55,31 @@ func addBase64aSoftSwitches(io *ioC0Page) {
|
||||
// ROM pagination softswitches. They use the annunciator 0 and 1
|
||||
mmu := io.apple2.mmu
|
||||
io.addSoftSwitchRW(0x58, func() uint8 {
|
||||
p := mmu.getActiveROMPage()
|
||||
mmu.setActiveROMPage(p & 2)
|
||||
if rom, ok := mmu.physicalROM.(*memoryRangeROM); ok {
|
||||
p := rom.getPage()
|
||||
rom.setPage(p & 2)
|
||||
}
|
||||
return 0
|
||||
}, "ANN0OFF-ROM")
|
||||
io.addSoftSwitchRW(0x59, func() uint8 {
|
||||
p := mmu.getActiveROMPage()
|
||||
mmu.setActiveROMPage(p | 1)
|
||||
if rom, ok := mmu.physicalROM.(*memoryRangeROM); ok {
|
||||
p := rom.getPage()
|
||||
rom.setPage(p | 1)
|
||||
}
|
||||
return 0
|
||||
}, "ANN0ON-ROM")
|
||||
io.addSoftSwitchRW(0x5A, func() uint8 {
|
||||
p := mmu.getActiveROMPage()
|
||||
mmu.setActiveROMPage(p & 1)
|
||||
if rom, ok := mmu.physicalROM.(*memoryRangeROM); ok {
|
||||
p := rom.getPage()
|
||||
rom.setPage(p & 1)
|
||||
}
|
||||
return 0
|
||||
}, "ANN1OFF-ROM")
|
||||
io.addSoftSwitchRW(0x5B, func() uint8 {
|
||||
p := mmu.getActiveROMPage()
|
||||
mmu.setActiveROMPage(p | 2)
|
||||
if rom, ok := mmu.physicalROM.(*memoryRangeROM); ok {
|
||||
p := rom.getPage()
|
||||
rom.setPage(p | 2)
|
||||
}
|
||||
return 0
|
||||
}, "ANN1ON-ROM")
|
||||
|
||||
|
@ -29,11 +29,9 @@ type CardThunderClockPlus struct {
|
||||
|
||||
func newCardThunderClockPlusBuilder() *cardBuilder {
|
||||
return &cardBuilder{
|
||||
name: "ThunderClock+ Card",
|
||||
description: "Clock card",
|
||||
defaultParams: &[]paramSpec{
|
||||
{"rom", "ROM file to load", "<internal>/ThunderclockPlusROM.bin"},
|
||||
},
|
||||
name: "ThunderClock+ Card",
|
||||
description: "Clock card",
|
||||
defaultParams: &[]paramSpec{},
|
||||
buildFunc: func(params map[string]string) (Card, error) {
|
||||
var c CardThunderClockPlus
|
||||
err := c.loadRomFromResource("<internal>/ThunderclockPlusROM.bin")
|
||||
|
@ -16,7 +16,7 @@ type memoryManager struct {
|
||||
cardsROMExtra [8]memoryHandler // 0xc800 to 0xcfff. 2048 bytes for each card
|
||||
|
||||
// Upper area ROM: 0xc000 to 0xffff (or 0xd000 to 0xffff on the II+)
|
||||
physicalROM [4]memoryHandler // 0xc000 (or 0xd000) to 0xffff, 16 (or 12) Kb. Up to four banks
|
||||
physicalROM memoryHandler // 0xc000 (or 0xd000) to 0xffff, 16 (or 12) Kb. Up to four banks
|
||||
|
||||
// Language card upper area RAM: 0xd000 to 0xffff. One bank for regular LC cards, up to 8 with Saturn
|
||||
physicalLangRAM []*memoryRange // 0xd000 to 0xffff, 12KB. Up to 8 banks.
|
||||
@ -44,9 +44,6 @@ type memoryManager struct {
|
||||
extendedRAMBlock uint8 // Block used for entended memory for RAMWorks cards
|
||||
mainROMinhibited memoryHandler // Alternative ROM from 0xd000 to 0xffff provided by a card with the INH signal.
|
||||
|
||||
// Configuration switches, Base64A
|
||||
romPage uint8 // Active ROM page
|
||||
|
||||
// Resolution cache
|
||||
lastAddressPage uint16 // The first byte is the page. The second is zero when the cached is valid.
|
||||
lastAddressHandler memoryHandler
|
||||
@ -90,12 +87,12 @@ func (mmu *memoryManager) accessCArea(address uint16) memoryHandler {
|
||||
// Internal IIe slot 3
|
||||
if (address <= addressLimitSlots) && !mmu.slotC3ROMActive && (slot == 3) {
|
||||
mmu.intC8ROMActive = true
|
||||
return mmu.physicalROM[mmu.romPage]
|
||||
return mmu.physicalROM
|
||||
}
|
||||
|
||||
// Internal IIe CxROM
|
||||
if mmu.intCxROMActive {
|
||||
return mmu.physicalROM[mmu.romPage]
|
||||
return mmu.physicalROM
|
||||
}
|
||||
|
||||
// First slot area
|
||||
@ -114,7 +111,7 @@ func (mmu *memoryManager) accessCArea(address uint16) memoryHandler {
|
||||
|
||||
// Extra slot area
|
||||
if mmu.intC8ROMActive {
|
||||
return mmu.physicalROM[mmu.romPage]
|
||||
return mmu.physicalROM
|
||||
}
|
||||
return mmu.cardsROMExtra[mmu.activeSlot]
|
||||
}
|
||||
@ -188,7 +185,7 @@ func (mmu *memoryManager) accessRead(address uint16) memoryHandler {
|
||||
if mmu.lcActiveRead {
|
||||
return mmu.accessUpperRAMArea(address)
|
||||
}
|
||||
return mmu.physicalROM[mmu.romPage]
|
||||
return mmu.physicalROM
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
|
||||
@ -221,7 +218,7 @@ func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
|
||||
if mmu.lcActiveWrite {
|
||||
return mmu.accessUpperRAMArea(address)
|
||||
}
|
||||
return mmu.physicalROM[mmu.romPage]
|
||||
return mmu.physicalROM
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) peekWord(address uint16) uint16 {
|
||||
@ -318,14 +315,6 @@ func (mmu *memoryManager) initExtendedRAM(groups int) {
|
||||
}
|
||||
|
||||
// Memory configuration
|
||||
func (mmu *memoryManager) setActiveROMPage(page uint8) {
|
||||
mmu.romPage = page
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) getActiveROMPage() uint8 {
|
||||
return mmu.romPage
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) setLanguageRAM(readActive bool, writeActive bool, altBank bool) {
|
||||
mmu.lcActiveRead = readActive
|
||||
mmu.lcActiveWrite = writeActive
|
||||
|
@ -12,6 +12,8 @@ type memoryRange struct {
|
||||
|
||||
type memoryRangeROM struct {
|
||||
memoryRange
|
||||
pageOffset uint16
|
||||
pages uint8
|
||||
}
|
||||
|
||||
func newMemoryRange(base uint16, data []uint8, name string) *memoryRange {
|
||||
@ -25,10 +27,15 @@ func newMemoryRange(base uint16, data []uint8, name string) *memoryRange {
|
||||
}
|
||||
|
||||
func newMemoryRangeROM(base uint16, data []uint8, name string) *memoryRangeROM {
|
||||
return newMemoryRangePagedROM(base, data, name, 1)
|
||||
}
|
||||
|
||||
func newMemoryRangePagedROM(base uint16, data []uint8, name string, pages uint8) *memoryRangeROM {
|
||||
var m memoryRangeROM
|
||||
m.base = base
|
||||
m.data = data
|
||||
m.name = name
|
||||
m.pages = pages
|
||||
return &m
|
||||
}
|
||||
|
||||
@ -48,10 +55,27 @@ func (m *memoryRange) subRange(a, b uint16) []uint8 {
|
||||
return m.data[a-m.base : b-m.base]
|
||||
}
|
||||
|
||||
func (m *memoryRangeROM) setPage(page uint8) {
|
||||
pageSize := len(m.data) / int(m.pages)
|
||||
m.pageOffset = uint16(int(page%m.pages) * pageSize)
|
||||
}
|
||||
|
||||
func (m *memoryRangeROM) getPage() uint8 {
|
||||
pageSize := len(m.data) / int(m.pages)
|
||||
return uint8(m.pageOffset / uint16(pageSize))
|
||||
}
|
||||
|
||||
func (m *memoryRangeROM) peek(address uint16) uint8 {
|
||||
return m.data[address-m.base+m.pageOffset]
|
||||
}
|
||||
func (m *memoryRangeROM) poke(address uint16, value uint8) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
func (m *memoryRangeROM) subRange(a, b uint16) []uint8 {
|
||||
return m.data[a-m.base+m.pageOffset : b-m.base+m.pageOffset]
|
||||
}
|
||||
|
||||
//lint:ignore U1000 this is used to write debug code
|
||||
func identifyMemory(m memoryHandler) string {
|
||||
ram, ok := m.(*memoryRange)
|
||||
|
@ -204,8 +204,8 @@ func (nsc *noSlotClockDS1216) loadTime() {
|
||||
|
||||
func setupNoSlotClock(a *Apple2, arg string) error {
|
||||
if arg == "main" {
|
||||
nsc := newNoSlotClockDS1216(a, a.mmu.physicalROM[0])
|
||||
a.mmu.physicalROM[0] = nsc
|
||||
nsc := newNoSlotClockDS1216(a, a.mmu.physicalROM)
|
||||
a.mmu.physicalROM = nsc
|
||||
} else {
|
||||
slot, err := strconv.ParseUint(arg, 10, 8)
|
||||
if err != nil || slot < 1 || slot > 7 {
|
||||
|
Loading…
Reference in New Issue
Block a user