From 3233cfc244057d62c28074d30a7eae2ab2172eda Mon Sep 17 00:00:00 2001 From: Will Angenent Date: Sat, 26 May 2018 22:27:29 +0100 Subject: [PATCH] Added page switching in text, gr and hgr --- mmu/io.go | 40 ++++++++++++++++++++++++++++------------ mmu/mmu.go | 24 +++++++++++++++++++++++- video/video.go | 14 ++++++++++++++ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/mmu/io.go b/mmu/io.go index a136156..1c6fa26 100644 --- a/mmu/io.go +++ b/mmu/io.go @@ -160,15 +160,16 @@ func readWrite(address uint16, isRead bool) bool { SetFakeAltZP(true) return true case CLR80VID: - // 80 column card hasn't been implemented yet + SetCol80(false) + return true + case SET80VID: + SetCol80(true) return true case TXTPAGE1: - // 80 column card hasn't been implemented yet - SetFakePage2(false) + SetPage2(false) return true case TXTPAGE2: - // 80 column card hasn't been implemented yet - SetFakePage2(true) + SetPage2(true) return true case CLRTEXT: VideoState.TextMode = false @@ -188,6 +189,16 @@ func readWrite(address uint16, isRead bool) bool { case SETHIRES: VideoState.HiresMode = true return true + case CLR80COL: + if !isRead { + SetStore80(false) + return true + } else { + return false + } + case SET80COL: + SetStore80(true) + return true case STATEREG: // Ignore not implemented memory management reg return true @@ -294,6 +305,13 @@ func ReadIO(address uint16) uint8 { // using 80-column display mode not implemented return 0x0d + case RDPAGE2: + if Page2 { + return 0x8d + } else { + return 0x0d + } + // 4-bit annunciator inputs case SETAN0, CLRAN0, SETAN1, CLRAN1, SETAN2, CLRAN2, SETAN3, CLRAN3: // Annunciators not implemented @@ -303,11 +321,11 @@ func ReadIO(address uint16) uint8 { case CLSAPPLE: // Closed apple key not implemented case RD80COL: - // RD80COL not implemented - return 0x0d - case RDPAGE2: - // RDPAGE2 not implemented - return 0x0d + if Store80 { + return 0x8d + } else { + return 0x0d + } case RDALTCH: // RDALTCH not implemented return 0x0d @@ -341,8 +359,6 @@ func WriteIO(address uint16, value uint8) { case CLR80COL: // CLR80COL not implemented return - case SET80COL: - // SET80COL not implemented case CLRC3ROM: // CLRC3ROM not implemented case SETC3ROM: diff --git a/mmu/mmu.go b/mmu/mmu.go index 703f895..8cdbbd9 100644 --- a/mmu/mmu.go +++ b/mmu/mmu.go @@ -29,6 +29,9 @@ var ( FakeAuxMemoryWrite bool // Aux memory isn't implemented FakeAltZP bool // Aux memory isn't implemented FakePage2 bool // Aux memory isn't implemented + Col80 bool // 80 Column card is on (not implemented) + Store80 bool // 80 Column card is on (not implemented) + Page2 bool // Main memory Page2 is selected ) func ApplyMemoryConfiguration() { @@ -165,7 +168,24 @@ func SetFakeAltZP(value bool) { ApplyMemoryConfiguration() } -func SetFakePage2(value bool) { +func SetCol80(value bool) { + Col80 = value + // No changes are needed when this is toggled +} + +func SetPage2(value bool) { + // If the 80 column card is enabled, then this toggles aux memory + // Otherwise, page1/page2 is toggled in the main memory + if Col80 { + FakePage2 = value + ApplyMemoryConfiguration() + } else { + Page2 = value + } +} + +func SetStore80(value bool) { + Store80 = value FakePage2 = value ApplyMemoryConfiguration() } @@ -177,6 +197,8 @@ func InitRAM() { FakeAuxMemoryWrite = false // Aux memory isn't implemented FakeAltZP = false // Aux memory isn't implemented FakePage2 = false // Aux memory isn't implemented + Col80 = false // Aux memory isn't implemented + Page2 = false ApplyMemoryConfiguration() } diff --git a/video/video.go b/video/video.go index 7b5f2a2..c8b1f85 100644 --- a/video/video.go +++ b/video/video.go @@ -120,6 +120,11 @@ func drawLores(screen *ebiten.Image, x int, y int, value uint8) error { func drawTextBlock(screen *ebiten.Image, start int, end int) error { for y := start; y < end; y++ { base := 128*(y%8) + 40*(y/8) + + if mmu.Page2 { + base += 0x400 + } + for x := 0; x < 40; x++ { offset := textVideoMemory + base + x value := mmu.ReadPageTable[offset>>8][offset&0xff] @@ -136,6 +141,11 @@ func drawTextBlock(screen *ebiten.Image, start int, end int) error { func drawLoresBlock(screen *ebiten.Image, start int, end int) error { for y := start; y < end; y++ { base := 128*(y%8) + 40*(y/8) + + if mmu.Page2 { + base += 0x400 + } + for x := 0; x < 40; x++ { offset := textVideoMemory + base + x value := mmu.ReadPageTable[offset>>8][offset&0xff] @@ -182,6 +192,10 @@ func drawHiresScreen(screen *ebiten.Image) error { // Woz is a genius yOffset := 0x2000 - (0x3d8)*(y>>6) + 0x80*(y>>3) + 0x400*(y&0x7) + if mmu.Page2 { + yOffset += 0x2000 + } + for x := 0; x < 40; x++ { offset := yOffset + x value := mmu.ReadPageTable[offset>>8][offset&0xff]