From c4f7a7e7095ccdafae2b33aa7c07b1b42f971469 Mon Sep 17 00:00:00 2001 From: Ivan Izaguirre Date: Thu, 16 May 2019 22:51:04 +0200 Subject: [PATCH] Rework of the memory manager. No longer based on pages, but on bigger go byte ranges --- apple2/ansiConsoleFrontend.go | 132 ++++++++++------------------------ apple2/apple2.go | 33 +-------- apple2/cardBase.go | 7 +- apple2/cardDisk2.go | 25 ++----- apple2/diskette16sector.go | 25 ++----- apple2/ioC0Page.go | 22 +++--- apple2/memoryManager.go | 108 ++++++++++++++++------------ apple2/memoryRange.go | 25 +++++++ apple2/rxmPage.go | 46 ------------ apple2/screenHiRes.go | 6 +- apple2/screenText.go | 2 +- apple2/softSwitches2e.go | 12 ++-- apple2/unassignedPage.go | 24 ------- 13 files changed, 155 insertions(+), 312 deletions(-) create mode 100644 apple2/memoryRange.go delete mode 100644 apple2/rxmPage.go delete mode 100644 apple2/unassignedPage.go diff --git a/apple2/ansiConsoleFrontend.go b/apple2/ansiConsoleFrontend.go index 9817914..0afedba 100644 --- a/apple2/ansiConsoleFrontend.go +++ b/apple2/ansiConsoleFrontend.go @@ -21,27 +21,17 @@ type ansiConsoleFrontend struct { apple2 *Apple2 keyChannel chan uint8 extraLineFeeds chan int - textUpdated bool stdinKeyboard bool + lastContent string } func newAnsiConsoleFrontend(a *Apple2, stdinKeyboard bool) *ansiConsoleFrontend { var fe ansiConsoleFrontend fe.apple2 = a fe.stdinKeyboard = stdinKeyboard - fe.subscribeToTextPages() return &fe } -func (fe *ansiConsoleFrontend) subscribeToTextPages() { - observer := func(_ uint8, _ bool) { - fe.textUpdated = true - } - for i := 0x04; i < 0x08; i++ { - fe.apple2.mmu.physicalMainRAM[i].observer = observer - } -} - const refreshDelayMs = 100 func (fe *ansiConsoleFrontend) GetKey(strobed bool) (key uint8, ok bool) { @@ -85,101 +75,53 @@ func (fe *ansiConsoleFrontend) GetKey(strobed bool) (key uint8, ok bool) { return } -func ansiCursorUp(steps int) { - fmt.Printf("\033[%vA", steps) -} - -func (fe *ansiConsoleFrontend) textModeGoRoutineFast() { - fe.extraLineFeeds = make(chan int, 100) - - fmt.Printf(strings.Repeat("\n", 26)) - for { - if fe.textUpdated { - fe.textUpdated = false - // Go up - ansiCursorUp(26) - done := false - for !done { - select { - case lineFeeds := <-fe.extraLineFeeds: - ansiCursorUp(lineFeeds) - default: - done = true - } - } - - fmt.Println(strings.Repeat("#", 44)) - - // See "Understand the Apple II", page 5-10 - // http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf - isAltText := fe.apple2.isApple2e && fe.apple2.io.isSoftSwitchActive(ioFlagAltChar) - var i, j, h, c uint8 - // Top, middle and botton screen - for i = 0; i < 120; i = i + 40 { - // Memory pages - for j = 0x04; j < 0x08; j++ { - p := fe.apple2.mmu.physicalMainRAM[j] - // The two half pages - for _, h = range []uint8{0, 128} { - line := "" - for c = i + h; c < i+h+40; c++ { - line += textMemoryByteToString(p.internalPeek(c), isAltText) - } - fmt.Printf("# %v #\n", line) - } - } - } - - fmt.Println(strings.Repeat("#", 44)) - if fe.stdinKeyboard { - fmt.Print("\033[KLine: ") - } - } - time.Sleep(refreshDelayMs * time.Millisecond) - } +func ansiCursorUp(steps int) string { + return fmt.Sprintf("\033[%vA", steps) } func (fe *ansiConsoleFrontend) textModeGoRoutine() { fe.extraLineFeeds = make(chan int, 100) - fmt.Printf(strings.Repeat("\n", 26)) + fmt.Printf(strings.Repeat("\n", textLines+3)) for { - if fe.textUpdated { - fe.textUpdated = false - // Go up - ansiCursorUp(26) - done := false - for !done { - select { - case lineFeeds := <-fe.extraLineFeeds: - ansiCursorUp(lineFeeds) - default: - done = true - } + // Go up + content := ansiCursorUp(textLines + 3) + done := false + for !done { + select { + case lineFeeds := <-fe.extraLineFeeds: + content += ansiCursorUp(lineFeeds) + default: + done = true } + } - pageIndex := 0 - if fe.apple2.io.isSoftSwitchActive(ioFlagSecondPage) { - pageIndex = 1 + content += "\n" + content += fmt.Sprintln(strings.Repeat("#", textColumns+4)) + + pageIndex := 0 + if fe.apple2.io.isSoftSwitchActive(ioFlagSecondPage) { + pageIndex = 1 + } + isAltText := fe.apple2.isApple2e && fe.apple2.io.isSoftSwitchActive(ioFlagAltChar) + + for l := 0; l < textLines; l++ { + line := "" + for c := 0; c < textColumns; c++ { + char := getTextChar(fe.apple2, c, l, pageIndex) + line += textMemoryByteToString(char, isAltText) } - isAltText := fe.apple2.isApple2e && fe.apple2.io.isSoftSwitchActive(ioFlagAltChar) + content += fmt.Sprintf("# %v #\n", line) + } - fmt.Println(strings.Repeat("#", 44)) - for line := 0; line < 24; line++ { - text := "" - for col := 0; col < 40; col++ { - value := getTextChar(fe.apple2, col, line, pageIndex) - text += textMemoryByteToString(value, isAltText) - } - fmt.Printf("# %v #\n", text) - } + content += fmt.Sprintln(strings.Repeat("#", textColumns+4)) + if fe.stdinKeyboard { + content += "\033[KLine: " + } - fmt.Println(strings.Repeat("#", 44)) - if fe.stdinKeyboard { - fmt.Print("\033[KLine: ") - } - - //saveSnapshot(fe.apple2) + if content != fe.lastContent { + fmt.Print(content) + fe.lastContent = content } time.Sleep(refreshDelayMs * time.Millisecond) } diff --git a/apple2/apple2.go b/apple2/apple2.go index 8e5981f..a0b32d9 100644 --- a/apple2/apple2.go +++ b/apple2/apple2.go @@ -3,7 +3,6 @@ package apple2 import ( "fmt" "go6502/core6502" - "io/ioutil" "time" ) @@ -36,11 +35,10 @@ func NewApple2(romFile string, charRomFile string, clockMhz float64, var a Apple2 a.mmu = newMemoryManager(&a) a.cpu = core6502.NewNMOS6502(a.mmu) - a.loadRom(romFile) + a.mmu.loadRom(romFile) if charRomFile != "" { a.cg = NewCharacterGenerator(charRomFile) } - a.mmu.resetRomPaging() a.commandChannel = make(chan int, 100) a.isColor = isColor a.fastMode = fastMode @@ -182,32 +180,3 @@ func (a *Apple2) releaseFastMode() { a.fastRequestsCounter-- } } - -func (a *Apple2) loadRom(filename string) { - bytes, err := ioutil.ReadFile(filename) - if err != nil { - panic(err) - } - size := len(bytes) - if size != apple2RomSize && size != apple2eRomSize { - panic("Rom size not supported") - } - - 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]) - } -} diff --git a/apple2/cardBase.go b/apple2/cardBase.go index a3dcbcc..4a00977 100644 --- a/apple2/cardBase.go +++ b/apple2/cardBase.go @@ -2,7 +2,7 @@ package apple2 type cardBase struct { a *Apple2 - rom []memoryPage + rom *memoryRange slot int ssr [16]softSwitchR ssw [16]softSwitchW @@ -11,8 +11,9 @@ type cardBase struct { func (c *cardBase) insert(a *Apple2, slot int) { c.a = a c.slot = slot - if slot != 0 && c.rom[0] != nil { - a.mmu.setPage(uint8(0xC0+slot), c.rom[0]) + if slot != 0 && c.rom != nil { + c.rom.base = uint16(0xC000 + slot*0x100) + a.mmu.setPage(uint8(0xC0+slot), c.rom) } for i := 0; i < 0x10; i++ { diff --git a/apple2/cardDisk2.go b/apple2/cardDisk2.go index 5577585..fb29fb7 100644 --- a/apple2/cardDisk2.go +++ b/apple2/cardDisk2.go @@ -30,7 +30,7 @@ type cardDisk2Drive struct { func newCardDisk2(filename string) *cardDisk2 { var c cardDisk2 - c.rom = loadCardRom(filename) + c.rom = newMemoryRange(0, loadCardRom(filename)) // Phase control soft switches // Lazy emulation. It only checks for phases on and move the head @@ -137,29 +137,12 @@ func newCardDisk2(filename string) *cardDisk2 { return &c } -func loadCardRom(filename string) []memoryPage { - bytes, err := ioutil.ReadFile(filename) +func loadCardRom(filename string) []uint8 { + data, err := ioutil.ReadFile(filename) if err != nil { panic(err) } - - size := len(bytes) - pages := size / 256 - if (size % 256) > 0 { - pages++ - } - - rom := make([]romPage, pages) - for i := 0; i < size; i++ { - rom[i>>8].burn(uint8(i), bytes[i]) - } - - memPages := make([]memoryPage, pages) - for i := range rom { - memPages[i] = &rom[i] - } - - return memPages + return data } func (d *cardDisk2Drive) insertDiskette(dt *diskette16sector) { diff --git a/apple2/diskette16sector.go b/apple2/diskette16sector.go index 391057a..08e176e 100644 --- a/apple2/diskette16sector.go +++ b/apple2/diskette16sector.go @@ -1,6 +1,7 @@ package apple2 import ( + "io/ioutil" "os" ) @@ -33,41 +34,25 @@ func (d *diskette16sector) read(track int, position int) (value uint8, newPositi func loadDisquette(filename string) *diskette16sector { var d diskette16sector - f, err := os.Open(filename) + data, err := ioutil.ReadFile(filename) if err != nil { panic(err) } - defer f.Close() + size := len(data) - stats, statsErr := f.Stat() - if statsErr != nil { - panic(err) - } - - size := stats.Size() if size == nibImageSize { // Load file already in nib format for i := 0; i < numberOfTracks; i++ { - d.track[i] = make([]byte, nibBytesPerTrack) - n, err := f.Read(d.track[i]) - if err != nil || n != nibBytesPerTrack { - panic("Error loading file") - } + d.track[i] = data[nibBytesPerTrack*i : nibBytesPerTrack*(i+1)] } } else if size == dskImageSize { - // Load file in dsk format - data := make([]byte, dskImageSize) - n, err := f.Read(data) - if err != nil || n != dskImageSize { - panic("Error loading file") - } // Convert to nib for i := 0; i < numberOfTracks; i++ { trackData := data[i*bytesPerTrack : (i+1)*bytesPerTrack] d.track[i] = nibEncodeTrack(trackData, defaultVolumeTag, byte(i)) } } else { - panic("Disk size with nib format has to be 232960 bytes") + panic("Invalid disk size") } return &d diff --git a/apple2/ioC0Page.go b/apple2/ioC0Page.go index ea8f34c..5496643 100644 --- a/apple2/ioC0Page.go +++ b/apple2/ioC0Page.go @@ -80,32 +80,26 @@ func (p *ioC0Page) setSpeakerProvider(s SpeakerProvider) { p.speaker = s } -func (p *ioC0Page) Peek(address uint8) uint8 { +func (p *ioC0Page) peek(address uint16) uint8 { //fmt.Printf("Peek on $C0%02x ", address) - ss := p.softSwitchesR[address] + pageAddress := uint8(address) + ss := p.softSwitchesR[pageAddress] if ss == nil { if p.apple2.panicSS { - panic(fmt.Sprintf("Unknown softswitch on read to 0xC0%02x", address)) + panic(fmt.Sprintf("Unknown softswitch on read to 0xC0%02x", pageAddress)) } return 0 } return ss(p) } -func (p *ioC0Page) internalPeek(address uint8) uint8 { - return 0 -} - -func (p *ioC0Page) all() []uint8 { - return nil -} - -func (p *ioC0Page) Poke(address uint8, value uint8) { +func (p *ioC0Page) poke(address uint16, value uint8) { //fmt.Printf("Poke on $C0%02x with %02x ", address, value) - ss := p.softSwitchesW[address] + pageAddress := uint8(address) + ss := p.softSwitchesW[pageAddress] if ss == nil { if p.apple2.panicSS { - panic(fmt.Sprintf("Unknown softswitch on write to 0xC0%02x", address)) + panic(fmt.Sprintf("Unknown softswitch on write to 0xC0%02x", pageAddress)) } return } diff --git a/apple2/memoryManager.go b/apple2/memoryManager.go index e453792..831bdb7 100644 --- a/apple2/memoryManager.go +++ b/apple2/memoryManager.go @@ -1,26 +1,25 @@ package apple2 +import "io/ioutil" + // See https://fabiensanglard.net/fd_proxy/prince_of_persia/Inside%20the%20Apple%20IIe.pdf // See https://i.stack.imgur.com/yn21s.gif type memoryManager struct { apple2 *Apple2 // Map of assigned pages - activeMemory [256]memoryPage + activeMemoryRead [256]memoryHandler + activeMemoryWrite [256]memoryHandler // Pages prepared to be paged in and out - physicalMainRAM []ramPage // 0x0000 to 0xbfff, Up to 48 Kb - physicalROM []romPage // 0xd000 to 0xffff, 12 Kb - physicalROMe []romPage // 0xc000 to 0xcfff, Zero or 4bk in the Apple2e - unassignedExpansionROM []unassignedPage // 0xc000 to 0xcfff + physicalMainRAM *memoryRange // 0x0000 to 0xbfff, Up to 48 Kb + physicalROM *memoryRange // 0xd000 to 0xffff, 12 Kb + physicalROMe *memoryRange // 0xc000 to 0xcfff, Zero or 4bk in the Apple2e } -// memoryPage is a data page of 256 bytes -type memoryPage interface { - Peek(uint8) uint8 - Poke(uint8, uint8) - internalPeek(uint8) uint8 - all() []uint8 +type memoryHandler interface { + peek(uint16) uint8 + poke(uint16, uint8) } const ( @@ -34,18 +33,11 @@ func (mmu *memoryManager) Peek(address uint16) uint8 { } hi := uint8(address >> 8) - lo := uint8(address) - return mmu.activeMemory[hi].Peek(lo) -} - -func (mmu *memoryManager) internalPeek(address uint16) uint8 { - hi := uint8(address >> 8) - lo := uint8(address) - return mmu.activeMemory[hi].internalPeek(lo) -} - -func (mmu *memoryManager) internalPage(hi uint8) []uint8 { - return mmu.activeMemory[hi].all() + mh := mmu.activeMemoryRead[hi] + if mh == nil { + return 0xf4 // Or some random number + } + return mh.peek(address) } // Poke sets the data at the given address @@ -54,15 +46,24 @@ func (mmu *memoryManager) Poke(address uint16, value uint8) { mmu.resetSlotExpansionRoms() } hi := uint8(address >> 8) - lo := uint8(address) - mmu.activeMemory[hi].Poke(lo, value) + mh := mmu.activeMemoryWrite[hi] + if mh == nil { + return + } + mh.poke(address, 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 +func (mmu *memoryManager) setPage(index uint8, mh memoryHandler) { + mmu.setPageRead(index, mh) + mmu.setPageWrite(index, mh) +} +func (mmu *memoryManager) setPageRead(index uint8, mh memoryHandler) { + mmu.activeMemoryRead[index] = mh +} + +func (mmu *memoryManager) setPageWrite(index uint8, mh memoryHandler) { + mmu.activeMemoryWrite[index] = mh } // When 0xcfff is accessed the card expansion rom is unassigned @@ -71,9 +72,8 @@ func (mmu *memoryManager) resetSlotExpansionRoms() { // Ignore if the Apple2 shadow ROM is active return } - for i := 8; i < 16; i++ { - p := mmu.unassignedExpansionROM[i] - mmu.setPage(uint8(i+0xc0), &p) + for i := uint8(0xc8); i < 0xd0; i++ { + mmu.setPage(i, nil) } } @@ -82,25 +82,43 @@ func newMemoryManager(a *Apple2) *memoryManager { mmu.apple2 = a // Assign RAM from 0x0000 to 0xbfff, 48kb - mmu.physicalMainRAM = make([]ramPage, 0xc0) - for i := 0; i <= 0xbf; i++ { - mmu.setPage(uint8(i), &(mmu.physicalMainRAM[i])) + ram := make([]uint8, 0xc000) + mmu.physicalMainRAM = newMemoryRange(0, ram) + for i := 0; i < 0xc000; i = i + 0x100 { + mmu.setPage(uint8(i>>8), mmu.physicalMainRAM) } - // Set the 0xc100 to 0xcfff as unasigned, 4kb. It wil be taken by slot cards. - mmu.unassignedExpansionROM = make([]unassignedPage, 0x10) - for i := 1; i < 0x10; i++ { - page := uint8(i + 0xc0) - p := &mmu.unassignedExpansionROM[i] - p.page = page - mmu.setPage(page, p) - } return &mmu } +func (mmu *memoryManager) loadRom(filename string) { + data, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + size := len(data) + if size != apple2RomSize && size != apple2eRomSize { + panic("Rom size not supported") + } + + a := mmu.apple2 + 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 = newMemoryRange(0xc000, data[0:extraRomSize]) + romStart = extraRomSize + } + + a.mmu.physicalROM = newMemoryRange(0xd000, data[romStart:]) + mmu.resetRomPaging() +} + func (mmu *memoryManager) resetRomPaging() { // Assign the first 12kb of ROM from 0xd000 to 0xfff - for i := 0xd0; i <= 0xff; i++ { - mmu.setPage(uint8(i), &(mmu.physicalROM[i-0xd0])) + for i := 0x0000; i < 0x3000; i = i + 0x100 { + mmu.setPageRead(uint8(0xd0+(i>>8)), mmu.physicalROM) } } diff --git a/apple2/memoryRange.go b/apple2/memoryRange.go new file mode 100644 index 0000000..95285e1 --- /dev/null +++ b/apple2/memoryRange.go @@ -0,0 +1,25 @@ +package apple2 + +type memoryRange struct { + base uint16 + data []uint8 +} + +func newMemoryRange(base uint16, data []uint8) *memoryRange { + var m memoryRange + m.base = base + m.data = data + return &m +} + +func (m *memoryRange) peek(address uint16) uint8 { + return m.data[address-m.base] +} + +func (m *memoryRange) poke(address uint16, value uint8) { + m.data[address-m.base] = value +} + +func (m *memoryRange) subRange(a, b uint16) []uint8 { + return m.data[a-m.base : b-m.base] +} diff --git a/apple2/rxmPage.go b/apple2/rxmPage.go deleted file mode 100644 index 3686dae..0000000 --- a/apple2/rxmPage.go +++ /dev/null @@ -1,46 +0,0 @@ -package apple2 - -type rxmPage struct { - data [256]uint8 - observer func(address uint8, isWrite bool) -} - -type ramPage struct { - rxmPage -} - -type romPage struct { - rxmPage -} - -func (p *rxmPage) Peek(address uint8) uint8 { - p.touch(address, false) - return p.data[address] -} - -func (p *rxmPage) internalPeek(address uint8) uint8 { - return p.data[address] -} - -func (p *rxmPage) all() []uint8 { - return p.data[:] -} - -func (p *rxmPage) Poke(address uint8, value uint8) { - p.touch(address, true) - p.data[address] = value -} - -func (p *rxmPage) touch(address uint8, isWrite bool) { - if p.observer != nil { - p.observer(address, isWrite) - } -} - -func (p *romPage) Poke(address uint8, value uint8) { - // Do nothing -} - -func (p *romPage) burn(address uint8, value uint8) { - p.data[address] = value -} diff --git a/apple2/screenHiRes.go b/apple2/screenHiRes.go index 8529b77..d19b770 100644 --- a/apple2/screenHiRes.go +++ b/apple2/screenHiRes.go @@ -30,11 +30,7 @@ func getHiResLine(a *Apple2, line int, page int) []uint8 { } address += getHiResLineOffset(line) - hi := uint8(address >> 8) - lo := uint8(address) - - memPage := a.mmu.internalPage(hi) - return memPage[lo : lo+40] + return a.mmu.physicalMainRAM.subRange(address, address+40) } func snapshotHiResModeMonoShift(a *Apple2, page int, mixedMode bool, light color.Color) *image.RGBA { diff --git a/apple2/screenText.go b/apple2/screenText.go index b0cbb5e..80567bf 100644 --- a/apple2/screenText.go +++ b/apple2/screenText.go @@ -31,7 +31,7 @@ func getTextChar(a *Apple2, col int, line int, page int) uint8 { address = textPage2Address } address += getTextCharOffset(col, line) - return a.mmu.internalPeek(address) + return a.mmu.physicalMainRAM.subRange(address, address+1)[0] } func snapshotTextMode(a *Apple2, page int, mixMode bool, light color.Color) *image.RGBA { diff --git a/apple2/softSwitches2e.go b/apple2/softSwitches2e.go index fece250..1e297ab 100644 --- a/apple2/softSwitches2e.go +++ b/apple2/softSwitches2e.go @@ -46,8 +46,8 @@ func getSoftSwitchExt(ioFlag uint8, dstValue uint8, action softSwitchExtAction) func softSwitchIntCxRomOn(io *ioC0Page) { mmu := io.apple2.mmu - for i := uint8(1); i < 16; i++ { - mmu.setPage(uint8(0xc0+i), &mmu.physicalROMe[i]) + for i := 0x100; i < 0x1000; i = i + 0x100 { + mmu.setPage(uint8(i>>8), mmu.physicalROMe) } } @@ -55,7 +55,7 @@ func softSwitchIntCxRomOff(io *ioC0Page) { // TODO restore all the ROM from the slot for 0xc1 to 0xc7 mmu := io.apple2.mmu for i := 1; i < 16; i++ { - mmu.setPage(uint8(0xc0+i), &mmu.unassignedExpansionROM[i]) + mmu.setPage(uint8(0xc0+i), nil) } } @@ -65,13 +65,13 @@ func softSwitchSlotC3RomOn(io *ioC0Page) { } // TODO restore the slot 3 ROM mmu := io.apple2.mmu - mmu.setPage(0xC3, &mmu.unassignedExpansionROM[3]) + mmu.setPage(0xC3, nil) } func softSwitchSlotC3RomOff(io *ioC0Page) { if io.isSoftSwitchActive(ioFlagIntCxRom) { - return // Ignore if allt the Apple2 shadow ROM is active + return // Ignore if alt the Apple2 shadow ROM is active } mmu := io.apple2.mmu - mmu.setPage(0xC3, &mmu.physicalROMe[3]) + mmu.setPageRead(0xC3, mmu.physicalROMe) } diff --git a/apple2/unassignedPage.go b/apple2/unassignedPage.go deleted file mode 100644 index b8e479a..0000000 --- a/apple2/unassignedPage.go +++ /dev/null @@ -1,24 +0,0 @@ -package apple2 - -type unassignedPage struct { - page uint8 -} - -func (p *unassignedPage) Peek(address uint8) uint8 { - //fmt.Printf("Read on address 0x%02x%02x\n", p.page, address) - //panic(address) - return 0xdd -} - -func (p *unassignedPage) internalPeek(address uint8) uint8 { - return 0xdd -} - -func (p *unassignedPage) all() []uint8 { - return nil -} - -func (p *unassignedPage) Poke(address uint8, value uint8) { - //fmt.Printf("Write on address 0x%02x%02x\n", p.page, address) - //panic(address) -}