Extract components from the memory manager
This commit is contained in:
parent
55ad73d01d
commit
5b186f9b15
|
@ -18,15 +18,15 @@ Those tricks do not work with the Apple2e ROM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type ansiConsoleFrontend struct {
|
type ansiConsoleFrontend struct {
|
||||||
mmu *memoryManager
|
apple2 *Apple2
|
||||||
keyChannel chan uint8
|
keyChannel chan uint8
|
||||||
extraLineFeeds chan int
|
extraLineFeeds chan int
|
||||||
textUpdated bool
|
textUpdated bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAnsiConsoleFrontend(mmu *memoryManager) *ansiConsoleFrontend {
|
func newAnsiConsoleFrontend(a *Apple2) *ansiConsoleFrontend {
|
||||||
var fe ansiConsoleFrontend
|
var fe ansiConsoleFrontend
|
||||||
fe.mmu = mmu
|
fe.apple2 = a
|
||||||
fe.subscribeToTextPages()
|
fe.subscribeToTextPages()
|
||||||
return &fe
|
return &fe
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ func (fe *ansiConsoleFrontend) subscribeToTextPages() {
|
||||||
fe.textUpdated = true
|
fe.textUpdated = true
|
||||||
}
|
}
|
||||||
for i := 0x04; i < 0x08; i++ {
|
for i := 0x04; i < 0x08; i++ {
|
||||||
fe.mmu.physicalMainRAM[i].observer = observer
|
fe.apple2.mmu.physicalMainRAM[i].observer = observer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,13 +102,13 @@ func (fe *ansiConsoleFrontend) textModeGoRoutine() {
|
||||||
|
|
||||||
// See "Understand the Apple II", page 5-10
|
// See "Understand the Apple II", page 5-10
|
||||||
// http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf
|
// http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf
|
||||||
isAltText := fe.mmu.isApple2e && fe.mmu.ioPage.isSoftSwitchExtActive(ioFlagAltChar)
|
isAltText := fe.apple2.isApple2e && fe.apple2.ioPage.isSoftSwitchExtActive(ioFlagAltChar)
|
||||||
var i, j, h, c uint8
|
var i, j, h, c uint8
|
||||||
// Top, middle and botton screen
|
// Top, middle and botton screen
|
||||||
for i = 0; i < 120; i = i + 40 {
|
for i = 0; i < 120; i = i + 40 {
|
||||||
// Memory pages
|
// Memory pages
|
||||||
for j = 0x04; j < 0x08; j++ {
|
for j = 0x04; j < 0x08; j++ {
|
||||||
p := fe.mmu.physicalMainRAM[j]
|
p := fe.apple2.mmu.physicalMainRAM[j]
|
||||||
// The two half pages
|
// The two half pages
|
||||||
for _, h = range []uint8{0, 128} {
|
for _, h = range []uint8{0, 128} {
|
||||||
line := ""
|
line := ""
|
||||||
|
|
|
@ -1,19 +1,88 @@
|
||||||
package apple2
|
package apple2
|
||||||
|
|
||||||
import "go6502/core6502"
|
import (
|
||||||
|
"bufio"
|
||||||
|
"go6502/core6502"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
// Run instantiates an apple2 and start emulation
|
type Apple2 struct {
|
||||||
func Run(romFile string, log bool) {
|
cpu *core6502.State
|
||||||
mmu := newAddressSpace(romFile)
|
mmu *memoryManager
|
||||||
s := core6502.NewNMOS6502(mmu)
|
isApple2e bool
|
||||||
fe := newAnsiConsoleFrontend(mmu)
|
ioPage *ioC0Page // 0xc000 to 0xc080
|
||||||
mmu.ioPage.setKeyboardProvider(fe)
|
activeSlot int // Slot that has the addressing 0xc800 to 0ccfff
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewApple2 instantiates an apple2
|
||||||
|
func NewApple2(romFile string) *Apple2 {
|
||||||
|
var a Apple2
|
||||||
|
a.mmu = newMemoryManager(&a)
|
||||||
|
a.cpu = core6502.NewNMOS6502(a.mmu)
|
||||||
|
a.loadRom(romFile)
|
||||||
|
a.mmu.resetPaging()
|
||||||
|
|
||||||
|
// Set the io in 0xc000
|
||||||
|
a.ioPage = newIoC0Page(&a)
|
||||||
|
a.mmu.setPage(0xc0, a.ioPage)
|
||||||
|
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Apple2) Run(log bool) {
|
||||||
|
// Init frontend
|
||||||
|
fe := newAnsiConsoleFrontend(a)
|
||||||
|
a.ioPage.setKeyboardProvider(fe)
|
||||||
go fe.textModeGoRoutine()
|
go fe.textModeGoRoutine()
|
||||||
|
|
||||||
// Start the processor
|
// Start the processor
|
||||||
s.Reset()
|
a.cpu.Reset()
|
||||||
for {
|
for {
|
||||||
s.ExecuteInstruction(log)
|
a.cpu.ExecuteInstruction(log)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadRom loads a binary file to the top of the memory.
|
||||||
|
const (
|
||||||
|
apple2RomSize = 12 * 1024
|
||||||
|
apple2eRomSize = 16 * 1024
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *Apple2) loadRom(filename string) {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
stats, statsErr := f.Stat()
|
||||||
|
if statsErr != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
size := stats.Size()
|
||||||
|
if size != apple2RomSize && size != apple2eRomSize {
|
||||||
|
panic("Rom size not supported")
|
||||||
|
}
|
||||||
|
bytes := make([]byte, size)
|
||||||
|
buf := bufio.NewReader(f)
|
||||||
|
buf.Read(bytes)
|
||||||
|
|
||||||
|
romStart := 0
|
||||||
|
if size == apple2eRomSize {
|
||||||
|
// The extra 4kb ROM is first in the rom file.
|
||||||
|
// It starts with 256 unused bytes not mapped to 0xc000.
|
||||||
|
a.isApple2e = true
|
||||||
|
extraRomSize := apple2eRomSize - apple2RomSize
|
||||||
|
a.mmu.physicalROMe = make([]romPage, extraRomSize>>8)
|
||||||
|
for i := 0; i < extraRomSize; i++ {
|
||||||
|
a.mmu.physicalROMe[i>>8].burn(uint8(i), bytes[i])
|
||||||
|
}
|
||||||
|
romStart = extraRomSize
|
||||||
|
}
|
||||||
|
|
||||||
|
a.mmu.physicalROM = make([]romPage, apple2RomSize>>8)
|
||||||
|
for i := 0; i < apple2RomSize; i++ {
|
||||||
|
a.mmu.physicalROM[i>>8].burn(uint8(i), bytes[i+romStart])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package apple2
|
||||||
|
|
||||||
|
type disk2 struct {
|
||||||
|
mmu *memoryManager
|
||||||
|
slot int
|
||||||
|
}
|
||||||
|
|
||||||
|
func insertCardDisk2(mmu *memoryManager, slot int) disk2 {
|
||||||
|
var c disk2
|
||||||
|
c.mmu = mmu
|
||||||
|
c.slot = slot
|
||||||
|
return c
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package apple2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type expansionSlots struct {
|
||||||
|
mmu *memoryManager
|
||||||
|
cards [7]expansionCard
|
||||||
|
}
|
||||||
|
|
||||||
|
type expansionCard interface {
|
||||||
|
insert(es *expansionSlots, slot int) cardBase
|
||||||
|
activateRom()
|
||||||
|
}
|
||||||
|
|
||||||
|
type cardBase struct {
|
||||||
|
es *expansionSlots
|
||||||
|
rom []romPage
|
||||||
|
slot int
|
||||||
|
softSwitchesR [16]softSwitchR
|
||||||
|
softSwitchesW [16]softSwitchW
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
https://applesaucefdc.com/woz/reference2/
|
||||||
|
http://yesterbits.com/media/pubs/AppleOrchard/articles/disk-ii-part-1-1983-apr.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
type cardDisk2 struct {
|
||||||
|
cardBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCardDisk2(filename string) *cardDisk2 {
|
||||||
|
var c cardDisk2
|
||||||
|
c.rom = loadCardRom(filename)
|
||||||
|
return &c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cardBase) insert(es *expansionSlots, slot int) {
|
||||||
|
c.es = es
|
||||||
|
c.slot = slot
|
||||||
|
if c.rom != nil {
|
||||||
|
//rom = c.rom[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCardRom(filename string) []romPage {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
stats, statsErr := f.Stat()
|
||||||
|
if statsErr != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
size := stats.Size()
|
||||||
|
bytes := make([]byte, size)
|
||||||
|
buf := bufio.NewReader(f)
|
||||||
|
buf.Read(bytes)
|
||||||
|
|
||||||
|
pages := size / 256
|
||||||
|
if (size % 256) > 0 {
|
||||||
|
pages++
|
||||||
|
}
|
||||||
|
|
||||||
|
rom := make([]romPage, pages)
|
||||||
|
for i := int64(0); i < size; i++ {
|
||||||
|
rom[i>>8].burn(uint8(i), bytes[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return rom
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ type ioC0Page struct {
|
||||||
softSwitchesW [128]softSwitchW
|
softSwitchesW [128]softSwitchW
|
||||||
softSwitchesData [128]uint8
|
softSwitchesData [128]uint8
|
||||||
keyboard keyboardProvider
|
keyboard keyboardProvider
|
||||||
mmu *memoryManager
|
apple2 *Apple2
|
||||||
}
|
}
|
||||||
|
|
||||||
type softSwitchR func(io *ioC0Page) uint8
|
type softSwitchR func(io *ioC0Page) uint8
|
||||||
|
@ -27,12 +27,12 @@ const (
|
||||||
ssOff uint8 = 0x00
|
ssOff uint8 = 0x00
|
||||||
)
|
)
|
||||||
|
|
||||||
func newIoC0Page(mmu *memoryManager) *ioC0Page {
|
func newIoC0Page(a *Apple2) *ioC0Page {
|
||||||
var io ioC0Page
|
var io ioC0Page
|
||||||
io.mmu = mmu
|
io.apple2 = a
|
||||||
|
|
||||||
addApple2SoftSwitches(&io)
|
addApple2SoftSwitches(&io)
|
||||||
if mmu.isApple2e {
|
if a.isApple2e {
|
||||||
addApple2ESoftSwitches(&io)
|
addApple2ESoftSwitches(&io)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,28 @@
|
||||||
package apple2
|
package apple2
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// See https://fabiensanglard.net/fd_proxy/prince_of_persia/Inside%20the%20Apple%20IIe.pdf
|
// See https://fabiensanglard.net/fd_proxy/prince_of_persia/Inside%20the%20Apple%20IIe.pdf
|
||||||
// See https://i.stack.imgur.com/yn21s.gif
|
// See https://i.stack.imgur.com/yn21s.gif
|
||||||
|
|
||||||
type memoryManager struct {
|
type memoryManager struct {
|
||||||
|
apple2 *Apple2
|
||||||
// Map of assigned pages
|
// Map of assigned pages
|
||||||
activeMemory *pagedMemory
|
activeMemory [256]memoryPage
|
||||||
|
|
||||||
// Pages prepared to be paged in and out
|
// Pages prepared to be paged in and out
|
||||||
physicalMainRAM []ramPage // 0x0000 to 0xbfff, Up to 48 Kb
|
physicalMainRAM []ramPage // 0x0000 to 0xbfff, Up to 48 Kb
|
||||||
physicalROM []romPage // 0xd000 to 0xffff, 12 Kb
|
physicalROM []romPage // 0xd000 to 0xffff, 12 Kb
|
||||||
physicalROMe []romPage // 0xc000 to 0xcfff, Zero or 4bk in the Apple2e
|
physicalROMe []romPage // 0xc000 to 0xcfff, Zero or 4bk in the Apple2e
|
||||||
unassignedExpansionROM []unassignedPage // 0xc000 to 0xcfff
|
unassignedExpansionROM []unassignedPage // 0xc000 to 0xcfff
|
||||||
ioPage *ioC0Page // 0xc000 to 0xc080
|
}
|
||||||
isApple2e bool
|
|
||||||
activeSlot int // Slot that has the addressing 0xc800 to 0ccfff
|
// memoryPage is a data page of 256 bytes
|
||||||
|
type memoryPage interface {
|
||||||
|
Peek(uint8) uint8
|
||||||
|
Poke(uint8, uint8)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ioAreaMask uint16 = 0xFF80
|
ioC8Off uint16 = 0xCFFF
|
||||||
ioAreaValue uint16 = 0xC000
|
|
||||||
ioC8Off uint16 = 0xCFFF
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Peek returns the data on the given address
|
// Peek returns the data on the given address
|
||||||
|
@ -32,7 +30,10 @@ func (mmu *memoryManager) Peek(address uint16) uint8 {
|
||||||
if address == ioC8Off {
|
if address == ioC8Off {
|
||||||
mmu.resetSlotExpansionRoms()
|
mmu.resetSlotExpansionRoms()
|
||||||
}
|
}
|
||||||
return mmu.activeMemory.Peek(address)
|
|
||||||
|
hi := uint8(address >> 8)
|
||||||
|
lo := uint8(address)
|
||||||
|
return mmu.activeMemory[hi].Peek(lo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poke sets the data at the given address
|
// Poke sets the data at the given address
|
||||||
|
@ -40,96 +41,54 @@ func (mmu *memoryManager) Poke(address uint16, value uint8) {
|
||||||
if address == ioC8Off {
|
if address == ioC8Off {
|
||||||
mmu.resetSlotExpansionRoms()
|
mmu.resetSlotExpansionRoms()
|
||||||
}
|
}
|
||||||
mmu.activeMemory.Poke(address, value)
|
hi := uint8(address >> 8)
|
||||||
|
lo := uint8(address)
|
||||||
|
mmu.activeMemory[hi].Poke(lo, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPage assigns a MemoryPage implementation on the page given
|
||||||
|
func (mmu *memoryManager) setPage(index uint8, page memoryPage) {
|
||||||
|
//fmt.Printf("Assigning page 0x%02x type %s\n", index, reflect.TypeOf(page))
|
||||||
|
mmu.activeMemory[index] = page
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When 0xcfff is accessed the card expansion rom is unassigned
|
// When 0xcfff is accessed the card expansion rom is unassigned
|
||||||
func (mmu *memoryManager) resetSlotExpansionRoms() {
|
func (mmu *memoryManager) resetSlotExpansionRoms() {
|
||||||
if mmu.ioPage.isSoftSwitchExtActive(ioFlagIntCxRom) {
|
if mmu.apple2.ioPage.isSoftSwitchExtActive(ioFlagIntCxRom) {
|
||||||
// Ignore if the Apple2 shadow ROM is active
|
// Ignore if the Apple2 shadow ROM is active
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := 8; i < 16; i++ {
|
for i := 8; i < 16; i++ {
|
||||||
p := mmu.unassignedExpansionROM[i]
|
p := mmu.unassignedExpansionROM[i]
|
||||||
mmu.activeMemory.SetPage(uint8(i+0xc0), &p)
|
mmu.setPage(uint8(i+0xc0), &p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAddressSpace(romImage string) *memoryManager {
|
func newMemoryManager(a *Apple2) *memoryManager {
|
||||||
var mmu memoryManager
|
var mmu memoryManager
|
||||||
|
mmu.apple2 = a
|
||||||
var m pagedMemory
|
|
||||||
mmu.activeMemory = &m
|
|
||||||
|
|
||||||
// Assign RAM from 0x0000 to 0xbfff, 48kb
|
// Assign RAM from 0x0000 to 0xbfff, 48kb
|
||||||
mmu.physicalMainRAM = make([]ramPage, 0xc0)
|
mmu.physicalMainRAM = make([]ramPage, 0xc0)
|
||||||
for i := 0; i <= 0xbf; i++ {
|
for i := 0; i <= 0xbf; i++ {
|
||||||
m.SetPage(uint8(i), &(mmu.physicalMainRAM[i]))
|
mmu.setPage(uint8(i), &(mmu.physicalMainRAM[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
mmu.loadRom(romImage)
|
|
||||||
// Assign the first 12kb of ROM from 0xd000 to 0xfff
|
|
||||||
for i := 0xd0; i <= 0xff; i++ {
|
|
||||||
m.SetPage(uint8(i), &(mmu.physicalROM[i-0xd0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the io in 0xc000
|
|
||||||
mmu.ioPage = newIoC0Page(&mmu)
|
|
||||||
m.SetPage(0xc0, mmu.ioPage)
|
|
||||||
|
|
||||||
// Set the 0xc100 to 0xcfff as unasigned, 4kb. It wil be taken by slot cards.
|
// Set the 0xc100 to 0xcfff as unasigned, 4kb. It wil be taken by slot cards.
|
||||||
mmu.unassignedExpansionROM = make([]unassignedPage, 0x10)
|
mmu.unassignedExpansionROM = make([]unassignedPage, 0x10)
|
||||||
for i := 1; i < 0x10; i++ {
|
for i := 1; i < 0x10; i++ {
|
||||||
page := uint8(i + 0xc0)
|
page := uint8(i + 0xc0)
|
||||||
p := &mmu.unassignedExpansionROM[i]
|
p := &mmu.unassignedExpansionROM[i]
|
||||||
p.page = page
|
p.page = page
|
||||||
m.SetPage(page, p)
|
mmu.setPage(page, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &mmu
|
return &mmu
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadRom loads a binary file to the top of the memory.
|
func (mmu *memoryManager) resetPaging() {
|
||||||
const (
|
// Assign the first 12kb of ROM from 0xd000 to 0xfff
|
||||||
apple2RomSize = 12 * 1024
|
for i := 0xd0; i <= 0xff; i++ {
|
||||||
apple2eRomSize = 16 * 1024
|
mmu.setPage(uint8(i), &(mmu.physicalROM[i-0xd0]))
|
||||||
)
|
|
||||||
|
|
||||||
func (mmu *memoryManager) loadRom(filename string) {
|
|
||||||
f, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
stats, statsErr := f.Stat()
|
|
||||||
if statsErr != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
size := stats.Size()
|
|
||||||
if size != apple2RomSize && size != apple2eRomSize {
|
|
||||||
panic("Rom size not supported")
|
|
||||||
}
|
|
||||||
bytes := make([]byte, size)
|
|
||||||
buf := bufio.NewReader(f)
|
|
||||||
buf.Read(bytes)
|
|
||||||
|
|
||||||
romStart := 0
|
|
||||||
if size == apple2eRomSize {
|
|
||||||
// The extra 4kb ROM is first in the rom file.
|
|
||||||
// It starts with 256 unused bytes not mapped to 0xc000.
|
|
||||||
mmu.isApple2e = true
|
|
||||||
extraRomSize := apple2eRomSize - apple2RomSize
|
|
||||||
mmu.physicalROMe = make([]romPage, extraRomSize>>8)
|
|
||||||
for i := 0; i < extraRomSize; i++ {
|
|
||||||
mmu.physicalROMe[i>>8].burn(uint8(i), bytes[i])
|
|
||||||
}
|
|
||||||
romStart = extraRomSize
|
|
||||||
}
|
|
||||||
|
|
||||||
mmu.physicalROM = make([]romPage, apple2RomSize>>8)
|
|
||||||
for i := 0; i < apple2RomSize; i++ {
|
|
||||||
mmu.physicalROM[i>>8].burn(uint8(i), bytes[i+romStart])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
package apple2
|
|
||||||
|
|
||||||
// memoryPage is a data page of 256 bytes
|
|
||||||
type memoryPage interface {
|
|
||||||
Peek(uint8) uint8
|
|
||||||
Poke(uint8, uint8)
|
|
||||||
}
|
|
||||||
|
|
||||||
// pagedMemory represents the addressable space of the processor
|
|
||||||
type pagedMemory struct {
|
|
||||||
data [256]memoryPage
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peek returns the data on the given address
|
|
||||||
func (m *pagedMemory) Peek(address uint16) uint8 {
|
|
||||||
hi := uint8(address >> 8)
|
|
||||||
lo := uint8(address)
|
|
||||||
return m.data[hi].Peek(lo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poke sets the data at the given address
|
|
||||||
func (m *pagedMemory) Poke(address uint16, value uint8) {
|
|
||||||
hi := uint8(address >> 8)
|
|
||||||
lo := uint8(address)
|
|
||||||
m.data[hi].Poke(lo, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPage assigns a MemoryPage implementation on the page given
|
|
||||||
func (m *pagedMemory) SetPage(index uint8, page memoryPage) {
|
|
||||||
//fmt.Printf("Assigning page 0x%02x type %s\n", index, reflect.TypeOf(page))
|
|
||||||
m.data[index] = page
|
|
||||||
}
|
|
Binary file not shown.
|
@ -45,15 +45,17 @@ func getSoftSwitchExt(ioFlag uint8, dstValue uint8, action softSwitchExtAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
func softSwitchIntCxRomOn(io *ioC0Page) {
|
func softSwitchIntCxRomOn(io *ioC0Page) {
|
||||||
|
mmu := io.apple2.mmu
|
||||||
for i := uint8(1); i < 16; i++ {
|
for i := uint8(1); i < 16; i++ {
|
||||||
io.mmu.activeMemory.SetPage(uint8(0xc0+i), &io.mmu.physicalROMe[i])
|
mmu.setPage(uint8(0xc0+i), &mmu.physicalROMe[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func softSwitchIntCxRomOff(io *ioC0Page) {
|
func softSwitchIntCxRomOff(io *ioC0Page) {
|
||||||
// TODO restore all the ROM from the slot for 0xc1 to 0xc7
|
// TODO restore all the ROM from the slot for 0xc1 to 0xc7
|
||||||
|
mmu := io.apple2.mmu
|
||||||
for i := 1; i < 16; i++ {
|
for i := 1; i < 16; i++ {
|
||||||
io.mmu.activeMemory.SetPage(uint8(0xc0+i), &io.mmu.unassignedExpansionROM[i])
|
mmu.setPage(uint8(0xc0+i), &mmu.unassignedExpansionROM[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,12 +64,14 @@ func softSwitchSlotC3RomOn(io *ioC0Page) {
|
||||||
return // Ignore if allt the Apple2 shadow ROM is active
|
return // Ignore if allt the Apple2 shadow ROM is active
|
||||||
}
|
}
|
||||||
// TODO restore the slot 3 ROM
|
// TODO restore the slot 3 ROM
|
||||||
io.mmu.activeMemory.SetPage(0xC3, &io.mmu.unassignedExpansionROM[3])
|
mmu := io.apple2.mmu
|
||||||
|
mmu.setPage(0xC3, &mmu.unassignedExpansionROM[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
func softSwitchSlotC3RomOff(io *ioC0Page) {
|
func softSwitchSlotC3RomOff(io *ioC0Page) {
|
||||||
if io.isSoftSwitchExtActive(ioFlagIntCxRom) {
|
if io.isSoftSwitchExtActive(ioFlagIntCxRom) {
|
||||||
return // Ignore if allt the Apple2 shadow ROM is active
|
return // Ignore if allt the Apple2 shadow ROM is active
|
||||||
}
|
}
|
||||||
io.mmu.activeMemory.SetPage(0xC3, &io.mmu.physicalROMe[3])
|
mmu := io.apple2.mmu
|
||||||
|
mmu.setPage(0xC3, &mmu.physicalROMe[3])
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,5 +29,4 @@ func TestFunctional(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Errorf("Tests complited in %v megacycles.\n", s.cycles/1000000)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue