mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-03-12 03:34:16 +00:00
RAMWorks card support for up to 16MB RAM
This commit is contained in:
parent
ede3b65257
commit
65f013e9b3
24
README.md
24
README.md
@ -19,7 +19,8 @@ Portable emulator of an Apple II+ or //e. Written in Go.
|
||||
- DiskII controller
|
||||
- 16Kb Language Card
|
||||
- 256Kb Saturn RAM
|
||||
- 1Mb Memory Expansion Card
|
||||
- 1Mb Memory Expansion Card (slinky)
|
||||
- RAMWorks style expansion Card (up to 16MB additional) (Apple //e only)
|
||||
- ThunderClock Plus real time clock
|
||||
- Bootable hard disk card
|
||||
- Apple //e 80 columns with 64Kb extra RAM and optional RGB modes
|
||||
@ -34,8 +35,9 @@ Portable emulator of an Apple II+ or //e. Written in Go.
|
||||
- Double-Width High-Resolution graphics (Apple //e only)
|
||||
- Super High Resolution (VidHD only)
|
||||
- Mixed mode
|
||||
- RGB card text 40 columns with 16 colors for foreground and background
|
||||
- RGB card text 40 columns with 16 colors for foreground and background (mixable)
|
||||
- RGB card mode 11, mono 560x192
|
||||
- RGB card mode 12, ntsc 160*192
|
||||
- RGB card mode 13, ntsc 140*192 (regular DHGR)
|
||||
- RGB card mode 14, mix of modes 11 and 13 on the fly
|
||||
- Displays:
|
||||
@ -61,7 +63,7 @@ No installation required. [Download](https://github.com/ivanizag/apple2/releases
|
||||
|
||||
Execute without parameters to have an emulated Apple //e Enhanced with 128kb booting DOS 3.3 ready to run Applesoft:
|
||||
|
||||
``` shell
|
||||
``` terminal
|
||||
casa@servidor:~$ ./apple2sdl
|
||||
```
|
||||
|
||||
@ -71,7 +73,7 @@ casa@servidor:~$ ./apple2sdl
|
||||
|
||||
Download a DSK or WOZ file or use an URL ([Asimov](https://www.apple.asimov.net/images/) is an excellent source) with the `-disk` parameter:
|
||||
|
||||
``` shell
|
||||
``` terminal
|
||||
casa@servidor:~$ ./apple2sdl -disk "https://www.apple.asimov.net/images/games/action/karateka/karateka (includes intro).dsk"
|
||||
```
|
||||
|
||||
@ -82,7 +84,7 @@ casa@servidor:~$ ./apple2sdl -disk "https://www.apple.asimov.net/images/games/ac
|
||||
Download the excellent [Total Replay](https://archive.org/details/TotalReplay) compilation by
|
||||
[a2-4am](https://github.com/a2-4am/4cade). Run it with the `-hd` parameter:
|
||||
|
||||
``` shell
|
||||
``` terminal
|
||||
casa@servidor:~$ ./apple2sdl -hd "Total Replay v3.0.2mg"
|
||||
```
|
||||
|
||||
@ -94,7 +96,7 @@ Displays super hi-res box art as seen with the VidHD card.
|
||||
|
||||
To run text mode right on the terminal without the SDL2 dependency, use `apple2console`. It runs on the console using ANSI escape codes. Input is sent to the emulated Apple II one line at a time:
|
||||
|
||||
``` shell
|
||||
``` terminal
|
||||
casa@servidor:~$ ./apple2console -model 2plus
|
||||
|
||||
############################################
|
||||
@ -145,7 +147,7 @@ Only valid on SDL mode
|
||||
|
||||
### Command line options
|
||||
|
||||
``` shell
|
||||
```terminal
|
||||
-charRom string
|
||||
rom file for the character generator (default "<default>")
|
||||
-disk string
|
||||
@ -180,6 +182,8 @@ Only valid on SDL mode
|
||||
panic if a not implemented softswitch is used
|
||||
-profile
|
||||
generate profile trace to analyse with pprof
|
||||
-ramworks int
|
||||
memory to use with RAMWorks card, 0 for no card, max is 16384 (default 8192)
|
||||
-rgb
|
||||
emulate the RGB modes of the 80col RGB card for DHGR (default true)
|
||||
-rom string
|
||||
@ -212,7 +216,7 @@ The only dependency is having a working Go installation on any platform.
|
||||
|
||||
Run:
|
||||
|
||||
``` shell
|
||||
``` terminal
|
||||
go get github.com/ivanizag/apple2/apple2console
|
||||
go build github.com/ivanizag/apple2/apple2console
|
||||
```
|
||||
@ -223,7 +227,7 @@ Besides having a working Go installation, install the SDL2 developer files. Vali
|
||||
|
||||
Run:
|
||||
|
||||
``` shell
|
||||
``` terminal
|
||||
go get github.com/ivanizag/apple2/apple2sdl
|
||||
go build github.com/ivanizag/apple2/apple2sdl
|
||||
```
|
||||
@ -232,7 +236,7 @@ go build github.com/ivanizag/apple2/apple2sdl
|
||||
|
||||
To create executables for Linux and Windows without installing Go, SDL2 or the Windows cross compilation toosl, run:
|
||||
|
||||
``` shell
|
||||
``` terminal
|
||||
cd docker
|
||||
./build.sh
|
||||
```
|
||||
|
@ -24,7 +24,7 @@ func newApple2e() *Apple2 {
|
||||
a.mmu = newMemoryManager(&a)
|
||||
a.cpu = core6502.NewNMOS6502(a.mmu)
|
||||
a.io = newIoC0Page(&a)
|
||||
a.mmu.InitRAMalt()
|
||||
a.mmu.initExtendedRAM(1)
|
||||
addApple2SoftSwitches(a.io)
|
||||
addApple2ESoftSwitches(a.io)
|
||||
|
||||
@ -37,7 +37,7 @@ func newApple2eEnhanced() *Apple2 {
|
||||
a.mmu = newMemoryManager(&a)
|
||||
a.cpu = core6502.NewCMOS65c02(a.mmu)
|
||||
a.io = newIoC0Page(&a)
|
||||
a.mmu.InitRAMalt()
|
||||
a.mmu.initExtendedRAM(1)
|
||||
addApple2SoftSwitches(a.io)
|
||||
addApple2ESoftSwitches(a.io)
|
||||
|
||||
@ -194,6 +194,10 @@ func (a *Apple2) AddRGBCard() {
|
||||
setupRGBCard(a)
|
||||
}
|
||||
|
||||
func (a *Apple2) AddRAMWorks(banks int) {
|
||||
setupRAMWorksCard(a, banks)
|
||||
}
|
||||
|
||||
// AddCardLogger inserts a fake card that logs accesses
|
||||
func (a *Apple2) AddCardLogger(slot int) {
|
||||
a.insertCard(&cardLogger{}, slot)
|
||||
|
@ -69,6 +69,10 @@ func MainApple() *Apple2 {
|
||||
"memoryExpSlot",
|
||||
4,
|
||||
"slot for the Memory Expansion card with 1GB. -1 for none")
|
||||
ramWorksKb := flag.Int(
|
||||
"ramworks",
|
||||
8192,
|
||||
"memory to use with RAMWorks card, 0 for no card, max is 16384")
|
||||
thunderClockCardSlot := flag.Int(
|
||||
"thunderClockCardSlot",
|
||||
5,
|
||||
@ -253,6 +257,13 @@ func MainApple() *Apple2 {
|
||||
}
|
||||
}
|
||||
|
||||
if *ramWorksKb != 0 {
|
||||
if *ramWorksKb%64 != 0 {
|
||||
panic("Ramworks size must be a multiple of 64")
|
||||
}
|
||||
a.AddRAMWorks(*ramWorksKb / 64)
|
||||
}
|
||||
|
||||
if *rgbCard {
|
||||
a.AddRGBCard()
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ Modes by RGB flags 1 and 2:
|
||||
0-0: 560*192 mono
|
||||
1-1: 140*192 ntsc
|
||||
0-1: Mixed mode
|
||||
1-0: 160*192 ntsc (not supported)
|
||||
1-0: 160*192 ntsc
|
||||
|
||||
*/
|
||||
|
||||
|
34
cardRamWorks.go
Normal file
34
cardRamWorks.go
Normal file
@ -0,0 +1,34 @@
|
||||
package apple2
|
||||
|
||||
/*
|
||||
RAMWorks style card on the Apple IIe aus slot.
|
||||
https://patents.google.com/patent/US4601018
|
||||
https://ae.applearchives.com/apple_e/ramworks_iii/ramworks_iii_basic_manual_1.pdf
|
||||
|
||||
Diagnostics disks:
|
||||
https://ae.applearchives.com/apple_e/ramworks_iii/ramworks_diagnostics.zip
|
||||
|
||||
It's is like the extra 64kb on an Apple IIe 80col 64kb card, but with up to 256 banks
|
||||
*/
|
||||
|
||||
func setupRAMWorksCard(a *Apple2, banks int) {
|
||||
a.mmu.initExtendedRAM(banks)
|
||||
|
||||
ssr := func(_ *ioC0Page) uint8 {
|
||||
return a.mmu.extendedRAMBlock
|
||||
}
|
||||
|
||||
ssw := func(_ *ioC0Page, value uint8) {
|
||||
a.mmu.setExtendedRAMActiveBlock(value)
|
||||
}
|
||||
|
||||
// Does not have a slot assigned
|
||||
a.io.addSoftSwitchR(0x71, ssr, "RAMWORKSR")
|
||||
a.io.addSoftSwitchR(0x73, ssr, "RAMWORKSR")
|
||||
a.io.addSoftSwitchR(0x75, ssr, "RAMWORKSR")
|
||||
a.io.addSoftSwitchR(0x77, ssr, "RAMWORKSR")
|
||||
a.io.addSoftSwitchW(0x71, ssw, "RAMWORKSW")
|
||||
a.io.addSoftSwitchW(0x73, ssw, "RAMWORKSW")
|
||||
a.io.addSoftSwitchW(0x75, ssw, "RAMWORKSW")
|
||||
a.io.addSoftSwitchW(0x77, ssw, "RAMWORKSW")
|
||||
}
|
@ -114,7 +114,7 @@ func (c *cardSaturn) ssAction(ss uint8) {
|
||||
}
|
||||
|
||||
func (c *cardSaturn) applyState() {
|
||||
c.a.mmu.setLanguageRAMBlock(c.activeBlock)
|
||||
c.a.mmu.setLanguageRAMActiveBlock(c.activeBlock)
|
||||
c.a.mmu.setLanguageRAM(c.readState, c.writeState == lcWriteEnabled, c.altBank)
|
||||
}
|
||||
|
||||
|
@ -12,19 +12,23 @@ type memoryManager struct {
|
||||
apple2 *Apple2
|
||||
|
||||
// Main RAM area: 0x0000 to 0xbfff
|
||||
physicalMainRAM *memoryRange // 0x0000 to 0xbfff, Up to 48 Kb
|
||||
physicalMainRAMAlt *memoryRange // 0x0000 to 0xbfff, Up to 48 Kb. Additional
|
||||
physicalMainRAM *memoryRange // 0x0000 to 0xbfff, Up to 48 Kb
|
||||
|
||||
// Slots area: 0xc000 to 0xcfff
|
||||
cardsROM [8]memoryHandler //0xcs00 to 0xcsff. 256 bytes for each card
|
||||
cardsROM [8]memoryHandler //0xcs00 to 0xcSff. 256 bytes for each card
|
||||
cardsROMExtra [8]memoryHandler // 0xc800 to 0xcfff. 2048 bytes for each card
|
||||
physicalROMe memoryHandler // 0xc100 to 0xcfff, Zero or 4kb in the Apple2e
|
||||
|
||||
// Upper area: 0xd000 to 0xffff
|
||||
physicalROM [4]memoryHandler // 0xd000 to 0xffff, 12 Kb. Up to four banks
|
||||
physicalDRAM []memoryHandler // 0xd000 to 0xdfff, 4KB. Up to 8 banks.
|
||||
physicalDAltRAM []memoryHandler // 0xd000 to 0xdfff, 4KB. Up to 8 banks.
|
||||
physicalEFRAM []memoryHandler // 0xe000 to 0xffff, 8KB. Up to 8 banks.
|
||||
// Upper area ROM: 0xd000 to 0xffff
|
||||
physicalROM [4]memoryHandler // 0xd000 to 0xffff, 12 Kb. Up to four
|
||||
|
||||
// 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.
|
||||
physicalLangAltRAM []*memoryRange // 0xd000 to 0xdfff, 4KB. Up to 8 banks.
|
||||
|
||||
// Extended RAM: 0x0000 to 0xffff (with 4Kb moved from 0xc000 to 0xd000 alt). One bank for extended Apple 2e card, up to 256 with RamWorks
|
||||
physicalExtRAM []*memoryRange // 0x0000 to 0xffff. 60Kb, 0xc000 to 0xcfff not used. Up to 256 banks
|
||||
physicalExtAltRAM []*memoryRange // 0xd000 to 0xdfff, 4Kb. Up to 256 banks.
|
||||
|
||||
// Configuration switches, Language cards
|
||||
lcSelectedBlock uint8 // Language card block selected. Usually, allways 0. But Saturn has 8
|
||||
@ -40,6 +44,7 @@ type memoryManager struct {
|
||||
slotC3ROMActive bool // Apple2e slot 3 ROM shadow
|
||||
intCxROMActive bool // Apple2e slots internal ROM shadow
|
||||
activeSlot uint8 // Active slot owner of 0xc800 to 0xcfff
|
||||
extendedRAMBlock uint8 // Block used for entended memory for RAMWorks cards
|
||||
|
||||
// Configuration switches, Base64A
|
||||
romPage uint8 // Active ROM page
|
||||
@ -97,23 +102,35 @@ func (mmu *memoryManager) accessCArea(address uint16) memoryHandler {
|
||||
return mmu.cardsROMExtra[mmu.activeSlot]
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) accessLCArea(address uint16) memoryHandler {
|
||||
block := mmu.lcSelectedBlock
|
||||
func (mmu *memoryManager) accessUpperRAMArea(address uint16) memoryHandler {
|
||||
if mmu.altZeroPage {
|
||||
block = 1
|
||||
}
|
||||
if address <= addressLimitDArea {
|
||||
if mmu.lcAltBank {
|
||||
return mmu.physicalDAltRAM[block]
|
||||
// Use extended RAM
|
||||
block := mmu.extendedRAMBlock
|
||||
if mmu.lcAltBank && address <= addressLimitDArea {
|
||||
return mmu.physicalExtAltRAM[block]
|
||||
}
|
||||
return mmu.physicalDRAM[block]
|
||||
return mmu.physicalExtRAM[mmu.extendedRAMBlock]
|
||||
}
|
||||
return mmu.physicalEFRAM[block]
|
||||
|
||||
// Use language card
|
||||
block := mmu.lcSelectedBlock
|
||||
if mmu.lcAltBank && address <= addressLimitDArea {
|
||||
return mmu.physicalLangAltRAM[block]
|
||||
}
|
||||
return mmu.physicalLangRAM[block]
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) getPhysicalMainRAM(alt bool) *memoryRange {
|
||||
if alt {
|
||||
return mmu.physicalMainRAMAlt
|
||||
func (mmu *memoryManager) getPhysicalMainRAM(ext bool) memoryHandler {
|
||||
if ext {
|
||||
return mmu.physicalExtRAM[mmu.extendedRAMBlock]
|
||||
}
|
||||
return mmu.physicalMainRAM
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) getVideoRAM(ext bool) *memoryRange {
|
||||
if ext {
|
||||
// The video memory uses the first extended RAM block, even with RAMWorks
|
||||
return mmu.physicalExtRAM[0]
|
||||
}
|
||||
return mmu.physicalMainRAM
|
||||
}
|
||||
@ -142,7 +159,7 @@ func (mmu *memoryManager) accessRead(address uint16) memoryHandler {
|
||||
return mmu.accessCArea(address)
|
||||
}
|
||||
if mmu.lcActiveRead {
|
||||
return mmu.accessLCArea(address)
|
||||
return mmu.accessUpperRAMArea(address)
|
||||
}
|
||||
return mmu.physicalROM[mmu.romPage]
|
||||
}
|
||||
@ -171,7 +188,7 @@ func (mmu *memoryManager) accessWrite(address uint16) memoryHandler {
|
||||
return mmu.accessCArea(address)
|
||||
}
|
||||
if mmu.lcActiveWrite {
|
||||
return mmu.accessLCArea(address)
|
||||
return mmu.accessUpperRAMArea(address)
|
||||
}
|
||||
return mmu.physicalROM[mmu.romPage]
|
||||
}
|
||||
@ -205,19 +222,24 @@ func (mmu *memoryManager) setCardROMExtra(slot int, mh memoryHandler) {
|
||||
mmu.cardsROMExtra[slot] = mh
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) initLanguageRAM(groups int) {
|
||||
mmu.physicalDRAM = make([]memoryHandler, groups)
|
||||
mmu.physicalDAltRAM = make([]memoryHandler, groups)
|
||||
mmu.physicalEFRAM = make([]memoryHandler, groups)
|
||||
for i := 0; i < groups; i++ {
|
||||
mmu.physicalDRAM[i] = newMemoryRange(0xd000, make([]uint8, 0x1000))
|
||||
mmu.physicalDAltRAM[i] = newMemoryRange(0xd000, make([]uint8, 0x1000))
|
||||
mmu.physicalEFRAM[i] = newMemoryRange(0xe000, make([]uint8, 0x2000))
|
||||
func (mmu *memoryManager) initLanguageRAM(groups uint8) {
|
||||
// Apple II+ language card or Saturn (up to 8 groups)
|
||||
mmu.physicalLangRAM = make([]*memoryRange, groups)
|
||||
mmu.physicalLangAltRAM = make([]*memoryRange, groups)
|
||||
for i := uint8(0); i < groups; i++ {
|
||||
mmu.physicalLangRAM[i] = newMemoryRange(0xd000, make([]uint8, 0x3000))
|
||||
mmu.physicalLangAltRAM[i] = newMemoryRange(0xd000, make([]uint8, 0x1000))
|
||||
}
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) InitRAMalt() {
|
||||
mmu.physicalMainRAMAlt = newMemoryRange(0, make([]uint8, 0xc000))
|
||||
func (mmu *memoryManager) initExtendedRAM(groups int) {
|
||||
// Apple IIe 80 col card with 64Kb style RAM or RAMWorks (up to 256 banks)
|
||||
mmu.physicalExtRAM = make([]*memoryRange, groups)
|
||||
mmu.physicalExtAltRAM = make([]*memoryRange, groups)
|
||||
for i := 0; i < groups; i++ {
|
||||
mmu.physicalExtRAM[i] = newMemoryRange(0, make([]uint8, 0x10000))
|
||||
mmu.physicalExtAltRAM[i] = newMemoryRange(0xd000, make([]uint8, 0x1000))
|
||||
}
|
||||
}
|
||||
|
||||
// Memory configuration
|
||||
@ -235,11 +257,19 @@ func (mmu *memoryManager) setLanguageRAM(readActive bool, writeActive bool, altB
|
||||
mmu.lcAltBank = altBank
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) setLanguageRAMBlock(block uint8) {
|
||||
block = block % uint8(len(mmu.physicalDRAM))
|
||||
func (mmu *memoryManager) setLanguageRAMActiveBlock(block uint8) {
|
||||
block = block % uint8(len(mmu.physicalLangRAM))
|
||||
mmu.lcSelectedBlock = block
|
||||
}
|
||||
|
||||
func (mmu *memoryManager) setExtendedRAMActiveBlock(block uint8) {
|
||||
if int(block) >= len(mmu.physicalExtRAM) {
|
||||
// How does the real hardware reacts?
|
||||
block = 0
|
||||
}
|
||||
mmu.extendedRAMBlock = block
|
||||
}
|
||||
|
||||
// TODO: complete save and load
|
||||
func (mmu *memoryManager) save(w io.Writer) error {
|
||||
err := mmu.physicalMainRAM.save(w)
|
||||
|
@ -31,7 +31,7 @@ func getHiResLine(a *Apple2, line int, isSecondPage bool, auxMem bool) []uint8 {
|
||||
}
|
||||
|
||||
address += getHiResLineOffset(line)
|
||||
return a.mmu.getPhysicalMainRAM(auxMem).subRange(address, address+hiResLineBytes)
|
||||
return a.mmu.getVideoRAM(auxMem).subRange(address, address+hiResLineBytes)
|
||||
}
|
||||
|
||||
func snapshotHiResModeMono(a *Apple2, isSecondPage bool, light color.Color) *image.RGBA {
|
||||
|
@ -24,8 +24,10 @@ func snapshotSuperHiResMode(a *Apple2) *image.RGBA {
|
||||
size := image.Rect(0, 0, shrWidth, shrHeight)
|
||||
img := image.NewRGBA(size)
|
||||
|
||||
videoRAM := a.mmu.getVideoRAM(true)
|
||||
|
||||
// Load the palettes
|
||||
paletteMem := a.mmu.physicalMainRAMAlt.subRange(shrColorPalettesAddress, shrColorPalettesAddressEnd)
|
||||
paletteMem := videoRAM.subRange(shrColorPalettesAddress, shrColorPalettesAddressEnd)
|
||||
colors := make([]color.Color, palettesCount)
|
||||
iMem := 0
|
||||
for i := 0; i < palettesCount; i++ {
|
||||
@ -46,13 +48,13 @@ func snapshotSuperHiResMode(a *Apple2) *image.RGBA {
|
||||
|
||||
// Build the lines
|
||||
for y := 0; y < shrHeight; y++ {
|
||||
controlByte := a.mmu.physicalMainRAMAlt.peek(shrScanLineControlAddress + uint16(y))
|
||||
controlByte := videoRAM.peek(shrScanLineControlAddress + uint16(y))
|
||||
is640Wide := (controlByte & 0x80) != 0
|
||||
isColorFill := (controlByte & 0x20) != 0
|
||||
paletteIndex := (controlByte & 0x0f) << 4
|
||||
|
||||
lineAddress := shrPixelDataAddress + uint16(shrWidthBytes*y)
|
||||
lineBytes := a.mmu.physicalMainRAMAlt.subRange(lineAddress, uint16(lineAddress+shrWidthBytes))
|
||||
lineBytes := videoRAM.subRange(lineAddress, uint16(lineAddress+shrWidthBytes))
|
||||
|
||||
if is640Wide {
|
||||
// Line is 640 pixels, two bits per pixel
|
||||
|
@ -20,7 +20,7 @@ const (
|
||||
)
|
||||
|
||||
func snapshotText40Mode(a *Apple2, isSecondPage bool, light color.Color) *image.RGBA {
|
||||
text := getTextFromMemory(a.mmu.physicalMainRAM, isSecondPage)
|
||||
text := getTextFromMemory(a.mmu.getVideoRAM(false), isSecondPage)
|
||||
return renderTextMode(a, text, nil /*colorMap*/, light)
|
||||
}
|
||||
|
||||
@ -30,13 +30,13 @@ func snapshotText80Mode(a *Apple2, isSecondPage bool, light color.Color) *image.
|
||||
}
|
||||
|
||||
func snapshotText40RGBMode(a *Apple2, isSecondPage bool) *image.RGBA {
|
||||
text := getTextFromMemory(a.mmu.physicalMainRAM, isSecondPage)
|
||||
colorMap := getTextFromMemory(a.mmu.physicalMainRAMAlt, isSecondPage)
|
||||
text := getTextFromMemory(a.mmu.getVideoRAM(false), isSecondPage)
|
||||
colorMap := getTextFromMemory(a.mmu.getVideoRAM(true), isSecondPage)
|
||||
return renderTextMode(a, text, colorMap, nil)
|
||||
}
|
||||
|
||||
func snapshotText40RGBModeColors(a *Apple2, isSecondPage bool) *image.RGBA {
|
||||
colorMap := getTextFromMemory(a.mmu.physicalMainRAMAlt, isSecondPage)
|
||||
colorMap := getTextFromMemory(a.mmu.getVideoRAM(true), isSecondPage)
|
||||
return renderTextMode(a, nil /*text*/, colorMap, nil)
|
||||
}
|
||||
|
||||
@ -49,8 +49,8 @@ func getTextCharOffset(col int, line int) uint16 {
|
||||
}
|
||||
|
||||
func getText80FromMemory(a *Apple2, isSecondPage bool) []uint8 {
|
||||
text40Columns := getTextFromMemory(a.mmu.physicalMainRAM, isSecondPage)
|
||||
text40ColumnsAlt := getTextFromMemory(a.mmu.physicalMainRAMAlt, isSecondPage)
|
||||
text40Columns := getTextFromMemory(a.mmu.getVideoRAM(false), isSecondPage)
|
||||
text40ColumnsAlt := getTextFromMemory(a.mmu.getVideoRAM(true), isSecondPage)
|
||||
|
||||
// Merge the two 40 cols to return 80 cols
|
||||
text80Columns := make([]uint8, 2*len(text40Columns))
|
||||
@ -165,7 +165,7 @@ func DumpTextModeAnsi(a *Apple2) string {
|
||||
if is80Columns {
|
||||
text = getText80FromMemory(a, isSecondPage)
|
||||
} else {
|
||||
text = getTextFromMemory(a.mmu.physicalMainRAM, isSecondPage)
|
||||
text = getTextFromMemory(a.mmu.getVideoRAM(false), isSecondPage)
|
||||
}
|
||||
columns := len(text) / textLines
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user