From: Shamus Hammons Date: Thu, 30 Dec 2021 03:04:04 +0000 (-0600) Subject: Graphical fixes for DHIRES and added CASIN emulation. X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=apple2;a=commitdiff_plain;h=e4b94bfc1e03e2c2848ab34e5f0cd8790e10f4b3 Graphical fixes for DHIRES and added CASIN emulation. Total Replay exposed (yet again!) a couple of flaws in apple2's emulation: it would crash on the Serpentine demo and would display bad graphics on DHIRES screen transitions. The latter was caused by a lack of CASIN emulation (and it's still not confirmed that it's correct), and the latter was caused by bad handling of the the STORE80 softswitch. Has it been almost a year since the last commit? How time does fly... :-/ --- diff --git a/.gitignore b/.gitignore index ad2bfdc..2dbb8d3 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,7 @@ docs/misc/ web/source/ misc/ changes-since-last-commit.txt +*.txt +disks.old/ +disks.old2/ +pix/ diff --git a/cross-compile b/cross-compile index 2598b84..7d3b918 100755 --- a/cross-compile +++ b/cross-compile @@ -7,8 +7,9 @@ # export PATH=/opt/mxe/usr/bin:$PATH #make CROSS=i686-pc-mingw32- clean && make CROSS=i686-pc-mingw32- -make CROSS=x86_64-w64-mingw32.static- clean \ - && make CROSS=x86_64-w64-mingw32.static- \ +#make CROSS=x86_64-w64-mingw32.static- clean +make CROSS=i686-w64-mingw32.static- clean \ + && make CROSS=i686-w64-mingw32.static- \ && upx -9v apple2.exe #TARGET = apple2 diff --git a/src/mmu.cpp b/src/mmu.cpp index dc5e57c..77578d4 100644 --- a/src/mmu.cpp +++ b/src/mmu.cpp @@ -9,7 +9,7 @@ // WHO WHEN WHAT // --- ---------- ----------------------------------------------------------- // JLH 09/27/2013 Created this file - +// #include "mmu.h" #include "apple2.h" @@ -19,7 +19,6 @@ #include "sound.h" #include "video.h" - // Debug defines //#define LC_DEBUG @@ -82,7 +81,6 @@ uint8_t * lcBankMemoryW = &ram[0xD000]; // $D000 - $DFFF (write) uint8_t * upperMemoryR = &ram[0xE000]; // $E000 - $FFFF (read) uint8_t * upperMemoryW = &ram[0xE000]; // $E000 - $FFFF (write) - // Function prototypes uint8_t ReadNOP(uint16_t); void WriteNOP(uint16_t, uint8_t); @@ -136,13 +134,13 @@ void SwitchHIRESW(uint16_t, uint8_t); uint8_t SwitchDHIRESR(uint16_t); void SwitchDHIRESW(uint16_t, uint8_t); void SwitchIOUDIS(uint16_t, uint8_t); +uint8_t ReadCassetteIn(uint16_t); uint8_t ReadButton0(uint16_t); uint8_t ReadButton1(uint16_t); uint8_t ReadPaddle0(uint16_t); uint8_t ReadIOUDIS(uint16_t); uint8_t ReadDHIRES(uint16_t); - // The main Apple //e memory map AddressMap memoryMap[] = { { 0x0000, 0x01FF, AM_RAM, &pageZeroMemory, 0, 0, 0 }, @@ -190,6 +188,8 @@ AddressMap memoryMap[] = { { 0xC054, 0xC055, AM_READ_WRITE, 0, 0, SwitchPAGE2R, SwitchPAGE2W }, { 0xC056, 0xC057, AM_READ_WRITE, 0, 0, SwitchHIRESR, SwitchHIRESW }, { 0xC05E, 0xC05F, AM_READ_WRITE, 0, 0, SwitchDHIRESR, SwitchDHIRESW }, + // $C060 is Cassette IN. No idea what it reads with N/C + { 0xC060, 0xC060, AM_READ, 0, 0, ReadCassetteIn, 0 }, { 0xC061, 0xC061, AM_READ, 0, 0, ReadButton0, 0 }, { 0xC062, 0xC062, AM_READ, 0, 0, ReadButton1, 0 }, { 0xC064, 0xC067, AM_READ, 0, 0, ReadPaddle0, 0 }, @@ -230,7 +230,6 @@ Read from $C800-$CFFF causes I/O STROBE to go low (and INTCXROM and INTC8ROM are */ - void SetupAddressMap(void) { for(uint32_t i=0; i<0x10000; i++) @@ -318,7 +317,6 @@ void SetupAddressMap(void) SwitchLC(); } - // // Reset the MMU state after a power down event // @@ -328,17 +326,22 @@ void ResetMMUPointers(void) { mainMemoryTextR = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); mainMemoryTextW = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryHGRR = (displayPage2 ? &ram2[0x2000] : &ram[0x2000]); + mainMemoryHGRW = (displayPage2 ? &ram2[0x2000] : &ram[0x2000]); } else { - mainMemoryTextR = (ramwrt ? &ram2[0x0400] : &ram[0x0400]); +// Shouldn't mainMemoryTextR depend on ramrd??? (I think it should...) + mainMemoryTextR = (ramrd ? &ram2[0x0400] : &ram[0x0400]); mainMemoryTextW = (ramwrt ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]); + mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]); } mainMemoryR = (ramrd ? &ram2[0x0200] : &ram[0x0200]); - mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]); mainMemoryW = (ramwrt ? &ram2[0x0200] : &ram[0x0200]); - mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]); +// mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]); +// mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]); // slot6Memory = (intCXROM ? &rom[0xC600] : &diskROM[0]); // slot3Memory = (slotC3ROM ? &rom[0] : &rom[0xC300]); @@ -353,7 +356,6 @@ WriteLog("ALTZP = %s\n", (altzp ? "ON" : "off")); #endif } - // // Set up slot access // @@ -415,7 +417,6 @@ So maybe... */ } - // // Built-in functions // @@ -430,12 +431,10 @@ uint8_t ReadNOP(uint16_t) return 0xFF; } - void WriteNOP(uint16_t, uint8_t) { } - uint8_t ReadMemory(uint16_t address) { //WriteLog("ReadMemory: addr=$%04X, addrPtrRead[addr]=$%X, addrOffset[addr]=$%X, val=$%02X\n", address, addrPtrRead[address], addrOffset[address], addrPtrRead[address][addrOffset[address]]); @@ -444,7 +443,6 @@ uint8_t ReadMemory(uint16_t address) return (*addrPtrRead[address])[addrOffset[address]]; } - void WriteMemory(uint16_t address, uint8_t byte) { // We can write protect memory this way, but it adds a branch to the mix. @@ -456,7 +454,6 @@ void WriteMemory(uint16_t address, uint8_t byte) (*addrPtrWrite[address])[addrOffset[address]] = byte; } - // // The main memory access functions used by V65C02 // @@ -490,7 +487,6 @@ if ((address > 0xC000 && address < 0xC100) || address == 0xC601) #endif } - void AppleWriteMem(uint16_t address, uint8_t byte) { #if 0 @@ -523,7 +519,6 @@ if (address == 0x000D) (*(funcMapWrite[address]))(address, byte); } - // // Generic slot handlers. These are set up here so that we can catch INTCXROM, // INTC8ROM & SLOTC3ROM here instead of having to catch them in each slot handler. @@ -546,7 +541,6 @@ uint8_t SlotR(uint16_t address) return (*(slotHandlerR[slot]))(address & 0xFF); } - void SlotW(uint16_t address, uint8_t byte) { if (intCXROM) @@ -564,7 +558,6 @@ void SlotW(uint16_t address, uint8_t byte) (*(slotHandlerW[slot]))(address & 0xFF, byte); } - // // Slot handling for 2K address space at $C800-$CFFF // @@ -576,7 +569,6 @@ uint8_t Slot2KR(uint16_t address) return (*(slotHandler2KR[enabledSlot]))(address & 0x7FF); } - void Slot2KW(uint16_t address, uint8_t byte) { if (intCXROM || intC8ROM) @@ -585,7 +577,6 @@ void Slot2KW(uint16_t address, uint8_t byte) (*(slotHandler2KW[enabledSlot]))(address & 0x7FF, byte); } - // // Actual emulated I/O functions follow // @@ -594,51 +585,54 @@ uint8_t ReadKeyboard(uint16_t /*addr*/) return lastKeyPressed | ((uint8_t)keyDown << 7); } - void Switch80STORE(uint16_t address, uint8_t) { store80Mode = (bool)(address & 0x01); WriteLog("Setting 80STORE to %s...\n", (store80Mode ? "ON" : "off")); + // It seems this affects more than just the text RAM, it also seems to affect the graphics RAM as well... if (store80Mode) { mainMemoryTextR = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); mainMemoryTextW = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryHGRR = (displayPage2 ? &ram2[0x2000] : &ram[0x2000]); + mainMemoryHGRW = (displayPage2 ? &ram2[0x2000] : &ram[0x2000]); } else { - mainMemoryTextR = (ramwrt ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryTextR = (ramrd ? &ram2[0x0400] : &ram[0x0400]); mainMemoryTextW = (ramwrt ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]); + mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]); } } - void SwitchRAMRD(uint16_t address, uint8_t) { ramrd = (bool)(address & 0x01); mainMemoryR = (ramrd ? &ram2[0x0200] : &ram[0x0200]); - mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]); +// mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]); if (store80Mode) return; mainMemoryTextR = (ramrd ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]); } - void SwitchRAMWRT(uint16_t address, uint8_t) { ramwrt = (bool)(address & 0x01); mainMemoryW = (ramwrt ? &ram2[0x0200] : &ram[0x0200]); - mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]); +// mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]); if (store80Mode) return; mainMemoryTextW = (ramwrt ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]); } - // // Since any slots that aren't populated are set to read from the ROM anyway, // we only concern ourselves with switching populated slots here. (Note that @@ -674,7 +668,6 @@ WriteLog("Setting SLOTCXROM to %s...\n", (address & 0x01 ? "ON" : "off")); #endif } - void SwitchALTZP(uint16_t address, uint8_t) { altzp = (bool)(address & 0x01); @@ -705,7 +698,6 @@ void SwitchSLOTC3ROM(uint16_t address, uint8_t) #endif } - /* We need to see where this is being switched from; if we know that, we can switch in the appropriate ROM to $C800-$CFFF. N.B.: Will probably need a custom handler routine, as some cards (like the Apple Hi-Speed SCSI card) split the 2K range into a 1K RAM space and a 1K bank switch ROM space. */ @@ -723,7 +715,6 @@ WriteLog("Hitting INTC8ROM (read)...\n"); return rom[0xCFFF]; } - // // This resets the INTC8ROM switch (RW) // @@ -733,20 +724,17 @@ WriteLog("Hitting INTC8ROM (write)...\n"); intC8ROM = false; } - void Switch80COL(uint16_t address, uint8_t) { col80Mode = (bool)(address & 0x01); } - void SwitchALTCHARSET(uint16_t address, uint8_t) { alternateCharset = (bool)(address & 0x01); WriteLog("Setting ALTCHARSET to %s...\n", (alternateCharset ? "ON" : "off")); } - uint8_t ReadKeyStrobe(uint16_t) { // No character data is read from here, just the 'any key was pressed' @@ -756,13 +744,11 @@ uint8_t ReadKeyStrobe(uint16_t) return byte; } - uint8_t ReadBANK2(uint16_t) { return (lcState < 0x04 ? 0x80 : 0x00); } - uint8_t ReadLCRAM(uint16_t) { // If bits 0 & 1 are set, but not at the same time, then it's ROM @@ -770,104 +756,87 @@ uint8_t ReadLCRAM(uint16_t) return (lcROM ? 0x00 : 0x80); } - uint8_t ReadRAMRD(uint16_t) { return (uint8_t)ramrd << 7; } - uint8_t ReadRAMWRT(uint16_t) { return (uint8_t)ramwrt << 7; } - uint8_t ReadSLOTCXROM(uint16_t) { return (uint8_t)intCXROM << 7; } - uint8_t ReadALTZP(uint16_t) { return (uint8_t)altzp << 7; } - uint8_t ReadSLOTC3ROM(uint16_t) { return (uint8_t)slotC3ROM << 7; } - uint8_t Read80STORE(uint16_t) { return (uint8_t)store80Mode << 7; } - uint8_t ReadVBL(uint16_t) { return (uint8_t)vbl << 7; } - uint8_t ReadTEXT(uint16_t) { return (uint8_t)textMode << 7; } - uint8_t ReadMIXED(uint16_t) { return (uint8_t)mixedMode << 7; } - uint8_t ReadPAGE2(uint16_t) { return (uint8_t)displayPage2 << 7; } - uint8_t ReadHIRES(uint16_t) { return (uint8_t)hiRes << 7; } - uint8_t ReadALTCHARSET(uint16_t) { return (uint8_t)alternateCharset << 7; } - uint8_t Read80COL(uint16_t) { return (uint8_t)col80Mode << 7; } - void WriteKeyStrobe(uint16_t, uint8_t) { keyDown = false; } - uint8_t ReadSpeaker(uint16_t) { ToggleSpeaker(); return 0; } - void WriteSpeaker(uint16_t, uint8_t) { ToggleSpeaker(); } - uint8_t SwitchLCR(uint16_t address) { lcState = address & 0x0B; @@ -875,14 +844,12 @@ uint8_t SwitchLCR(uint16_t address) return 0; } - void SwitchLCW(uint16_t address, uint8_t) { lcState = address & 0x0B; SwitchLC(); } - void SwitchLC(void) { switch (lcState) @@ -958,7 +925,6 @@ WriteLog("SwitchLC: Read/write bank 2\n"); } } - uint8_t SwitchTEXTR(uint16_t address) { WriteLog("Setting TEXT to %s...\n", (address & 0x01 ? "ON" : "off")); @@ -966,14 +932,12 @@ WriteLog("Setting TEXT to %s...\n", (address & 0x01 ? "ON" : "off")); return 0; } - void SwitchTEXTW(uint16_t address, uint8_t) { WriteLog("Setting TEXT to %s...\n", (address & 0x01 ? "ON" : "off")); textMode = (bool)(address & 0x01); } - uint8_t SwitchMIXEDR(uint16_t address) { WriteLog("Setting MIXED to %s...\n", (address & 0x01 ? "ON" : "off")); @@ -981,14 +945,12 @@ WriteLog("Setting MIXED to %s...\n", (address & 0x01 ? "ON" : "off")); return 0; } - void SwitchMIXEDW(uint16_t address, uint8_t) { WriteLog("Setting MIXED to %s...\n", (address & 0x01 ? "ON" : "off")); mixedMode = (bool)(address & 0x01); } - uint8_t SwitchPAGE2R(uint16_t address) { WriteLog("Setting PAGE2 to %s...\n", (address & 0x01 ? "ON" : "off")); @@ -998,12 +960,13 @@ WriteLog("Setting PAGE2 to %s...\n", (address & 0x01 ? "ON" : "off")); { mainMemoryTextR = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); mainMemoryTextW = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryHGRR = (displayPage2 ? &ram2[0x2000] : &ram[0x2000]); + mainMemoryHGRW = (displayPage2 ? &ram2[0x2000] : &ram[0x2000]); } return 0; } - void SwitchPAGE2W(uint16_t address, uint8_t) { WriteLog("Setting PAGE2 to %s...\n", (address & 0x01 ? "ON" : "off")); @@ -1013,10 +976,11 @@ WriteLog("Setting PAGE2 to %s...\n", (address & 0x01 ? "ON" : "off")); { mainMemoryTextR = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); mainMemoryTextW = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]); + mainMemoryHGRR = (displayPage2 ? &ram2[0x2000] : &ram[0x2000]); + mainMemoryHGRW = (displayPage2 ? &ram2[0x2000] : &ram[0x2000]); } } - uint8_t SwitchHIRESR(uint16_t address) { WriteLog("Setting HIRES to %s...\n", (address & 0x01 ? "ON" : "off")); @@ -1024,14 +988,12 @@ WriteLog("Setting HIRES to %s...\n", (address & 0x01 ? "ON" : "off")); return 0; } - void SwitchHIRESW(uint16_t address, uint8_t) { WriteLog("Setting HIRES to %s...\n", (address & 0x01 ? "ON" : "off")); hiRes = (bool)(address & 0x01); } - uint8_t SwitchDHIRESR(uint16_t address) { WriteLog("Setting DHIRES to %s (ioudis = %s)...\n", ((address & 0x01) ^ 0x01 ? "ON" : "off"), (ioudis ? "ON" : "off")); @@ -1042,7 +1004,6 @@ WriteLog("Setting DHIRES to %s (ioudis = %s)...\n", ((address & 0x01) ^ 0x01 ? " return 0; } - void SwitchDHIRESW(uint16_t address, uint8_t) { WriteLog("Setting DHIRES to %s (ioudis = %s)...\n", ((address & 0x01) ^ 0x01 ? "ON" : "off"), (ioudis ? "ON" : "off")); @@ -1050,25 +1011,29 @@ WriteLog("Setting DHIRES to %s (ioudis = %s)...\n", ((address & 0x01) ^ 0x01 ? " dhires = !((bool)(address & 0x01)); } - void SwitchIOUDIS(uint16_t address, uint8_t) { ioudis = !((bool)(address & 0x01)); } +uint8_t ReadCassetteIn(uint16_t) +{ + // No idea what it's supposed to return if there's no cassette attached, so let's try this (Serpentine crashes if $FF is returned...) + // Serpentine crashes even earlier if $00 is returned... Now what??? + // This seems to work for Serpentine, not sure what's supposed to be returned here... Maybe it's an RNG when N/C? + return 0x5A; +} uint8_t ReadButton0(uint16_t) { return (uint8_t)openAppleDown << 7; } - uint8_t ReadButton1(uint16_t) { return (uint8_t)closedAppleDown << 7; } - // The way the paddles work is that a strobe is written (or read) to $C070, // then software counts down the time that it takes for the paddle outputs // to have bit 7 return to 0. If there are no paddles connected, bit 7 @@ -1079,19 +1044,16 @@ uint8_t ReadPaddle0(uint16_t) return 0xFF; } - uint8_t ReadIOUDIS(uint16_t) { return (uint8_t)ioudis << 7; } - uint8_t ReadDHIRES(uint16_t) { return (uint8_t)dhires << 7; } - // Whenever a read is done to a MMIO location that is unconnected to anything, // it actually sees the RAM access done by the video generation hardware. Some // programs exploit this, so we emulate it here. @@ -1131,7 +1093,6 @@ uint8_t ReadFloatingBus(uint16_t) | (!store80Mode && displayPage2 ? 0x4000 : 0) | ((vcount & 0x07) << 10); - // The address so read is *always* in main RAM, not alt RAM + // The address so read is *always* in main RAM, never alt RAM return ram[address]; } - diff --git a/src/video.cpp b/src/video.cpp index 1245308..065ca03 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -337,8 +337,7 @@ static void RenderLoRes(uint16_t toLine = 24); static void RenderDLoRes(uint16_t toLine = 24); static void RenderHiRes(uint16_t toLine = 192); static void RenderDHiRes(uint16_t toLine = 192); -static void RenderVideoFrame(/*uint32_t *, int*/); - +static void RenderVideoFrame(); void SetupBlurTable(void) { @@ -346,7 +345,8 @@ void SetupBlurTable(void) // last four bits are copies of the previous four... // Odd. Doing the bit patterns from 0-$7F doesn't work, but going // from 0-$7FF stepping by 16 does. Hm. - // Well, it seems that going from 0-$7F doesn't have enough precision to do the job. + // Well, it seems that going from 0-$7F doesn't have enough precision + // to do the job. for(uint16_t bitPat=0; bitPat<0x800; bitPat+=0x10) { uint16_t w0 = bitPat & 0x111, w1 = bitPat & 0x222, w2 = bitPat & 0x444, w3 = bitPat & 0x888; @@ -379,7 +379,6 @@ void SetupBlurTable(void) } } - void TogglePalette(void) { if (palette == (uint32_t *)colors) @@ -404,7 +403,6 @@ void TogglePalette(void) } } - void CycleScreenTypes(void) { char scrTypeStr[3][40] = { "Color TV", "White monochrome", "Green monochrome" }; @@ -417,13 +415,11 @@ void CycleScreenTypes(void) SpawnMessage("%s", scrTypeStr[screenType]); } - void ToggleTickDisplay(void) { showFrameTicks = !showFrameTicks; } - static uint32_t msgTicks = 0; static char message[4096]; @@ -436,10 +432,8 @@ void SpawnMessage(const char * text, ...) va_end(arg); msgTicks = 120; -//WriteLog("\n%s\n", message); } - static void DrawString2(uint32_t x, uint32_t y, uint32_t color, char * msg); static void DrawString(void) { @@ -452,7 +446,6 @@ static void DrawString(void) DrawString2(8, 8, 0x0020FF20, message); } - static void DrawString(uint32_t x, uint32_t y, uint32_t color, char * msg) { //This approach works, and seems to be fast enough... Though it probably would @@ -464,7 +457,6 @@ static void DrawString(uint32_t x, uint32_t y, uint32_t color, char * msg) DrawString2(x, y, color, msg); } - static void DrawString2(uint32_t x, uint32_t y, uint32_t color, char * msg) { uint32_t length = strlen(msg), address = x + (y * VIRTUAL_SCREEN_WIDTH); @@ -510,7 +502,6 @@ static void DrawString2(uint32_t x, uint32_t y, uint32_t color, char * msg) } } - static void DrawFrameTicks(void) { uint32_t color = 0x00FF2020; @@ -559,9 +550,7 @@ static void DrawFrameTicks(void) if ((frameTimePtr % 15) == 0) { -// uint32_t prevClock = (frameTimePtr + 1) % 60; uint64_t prevClock = (frameTimePtr + 1) % 60; -// float fps = 59.0f / (((float)frameTime[frameTimePtr] - (float)frameTime[prevClock]) / 1000.0f); double fps = 59.0 / ((double)(frameTime[frameTimePtr] - frameTime[prevClock]) / (double)SDL_GetPerformanceFrequency()); sprintf(msg, "%.1lf FPS", fps); } @@ -569,14 +558,13 @@ static void DrawFrameTicks(void) DrawString(20, 24, color, msg); } - static void Render40ColumnTextLine(uint8_t line) { uint32_t pixelOn = (screenType == ST_GREEN_MONO ? 0xFF61FF61 : 0xFFFFFFFF); for(int x=0; x<40; x++) { - uint8_t chr = ram[lineAddrLoRes[line] + (displayPage2 ? 0x0400 : 0x0000) + x]; + uint8_t chr = ram[lineAddrLoRes[line] + (!store80Mode && displayPage2 ? 0x0400 : 0x0000) + x]; // Render character at (x, y) @@ -624,7 +612,6 @@ static void Render40ColumnTextLine(uint8_t line) } } - static void Render80ColumnTextLine(uint8_t line) { uint32_t pixelOn = (screenType == ST_GREEN_MONO ? 0xFF61FF61 : 0xFFFFFFFF); @@ -680,21 +667,18 @@ static void Render80ColumnTextLine(uint8_t line) } } - static void Render40ColumnText(void) { for(uint8_t line=0; line<24; line++) Render40ColumnTextLine(line); } - static void Render80ColumnText(void) { for(uint8_t line=0; line<24; line++) Render80ColumnTextLine(line); } - static void RenderLoRes(uint16_t toLine/*= 24*/) { // NOTE: The green mono rendering doesn't skip every other line... !!! FIX !!! @@ -734,8 +718,8 @@ fb fb fb -> 15 [1111] -> 15 WHITE for(uint16_t x=0; x<40; x+=2) { - uint8_t scrByte1 = ram[lineAddrLoRes[y] + (displayPage2 ? 0x0400 : 0x0000) + x + 0] & 0x0F; - uint8_t scrByte2 = ram[lineAddrLoRes[y] + (displayPage2 ? 0x0400 : 0x0000) + x + 1] & 0x0F; + uint8_t scrByte1 = ram[lineAddrLoRes[y] + (!store80Mode && displayPage2 ? 0x0400 : 0x0000) + x + 0] & 0x0F; + uint8_t scrByte2 = ram[lineAddrLoRes[y] + (!store80Mode && displayPage2 ? 0x0400 : 0x0000) + x + 1] & 0x0F; scrByte1 = mirrorNybble[scrByte1]; scrByte2 = mirrorNybble[scrByte2]; // This is just a guess, but it'll have to do for now... @@ -761,7 +745,6 @@ fb fb fb -> 15 [1111] -> 15 WHITE for(uint32_t cy=0; cy<8; cy++) { scrBuffer[((x * 14) + (i * 4) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = palette[color]; -// scrBuffer[((x * 14) + (i * 4) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = palette[color]; } } } @@ -775,7 +758,6 @@ fb fb fb -> 15 [1111] -> 15 WHITE for(uint32_t cy=0; cy<8; cy++) { scrBuffer[((x * 14) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = (pixels & 0x08000000 ? pixelOn : 0xFF000000); -// scrBuffer[((x * 14) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = (pixels & 0x08000000 ? pixelOn : 0xFF000000); } pixels <<= 1; @@ -789,8 +771,8 @@ fb fb fb -> 15 [1111] -> 15 WHITE for(uint16_t x=0; x<40; x+=2) { - uint8_t scrByte1 = ram[lineAddrLoRes[y] + (displayPage2 ? 0x0400 : 0x0000) + x + 0] >> 4; - uint8_t scrByte2 = ram[lineAddrLoRes[y] + (displayPage2 ? 0x0400 : 0x0000) + x + 1] >> 4; + uint8_t scrByte1 = ram[lineAddrLoRes[y] + (!store80Mode && displayPage2 ? 0x0400 : 0x0000) + x + 0] >> 4; + uint8_t scrByte2 = ram[lineAddrLoRes[y] + (!store80Mode && displayPage2 ? 0x0400 : 0x0000) + x + 1] >> 4; scrByte1 = mirrorNybble[scrByte1]; scrByte2 = mirrorNybble[scrByte2]; // This is just a guess, but it'll have to do for now... @@ -816,7 +798,6 @@ fb fb fb -> 15 [1111] -> 15 WHITE for(uint32_t cy=8; cy<16; cy++) { scrBuffer[((x * 14) + (i * 4) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = palette[color]; -// scrBuffer[((x * 14) + (i * 4) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = palette[color]; } } } @@ -830,7 +811,6 @@ fb fb fb -> 15 [1111] -> 15 WHITE for(uint32_t cy=8; cy<16; cy++) { scrBuffer[((x * 14) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = (pixels & 0x08000000 ? pixelOn : 0xFF000000); -// scrBuffer[((x * 14) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = (pixels & 0x08000000 ? pixelOn : 0xFF000000); } pixels <<= 1; @@ -840,7 +820,6 @@ fb fb fb -> 15 [1111] -> 15 WHITE } } - // // Render the Double Lo Res screen (HIRES off, DHIRES on) // @@ -1003,7 +982,6 @@ FB FB FB -> 15 [1111] -> 15 WHITE } } - static void RenderHiRes(uint16_t toLine/*= 192*/) { #if 0 @@ -1023,11 +1001,11 @@ static void RenderHiRes(uint16_t toLine/*= 192*/) for(uint16_t x=0; x<40; x+=2) { - uint8_t screenByte = ram[lineAddrHiRes[y] + (displayPage2 ? 0x2000 : 0x0000) + x]; + uint8_t screenByte = ram[lineAddrHiRes[y] + (!store80Mode && displayPage2 ? 0x2000 : 0x0000) + x]; uint32_t pixels = appleHiresToMono[previousLoPixel | screenByte]; previousLoPixel = (screenByte << 2) & 0x0100; - screenByte = ram[lineAddrHiRes[y] + (displayPage2 ? 0x2000 : 0x0000) + x + 1]; + screenByte = ram[lineAddrHiRes[y] + (!store80Mode && displayPage2 ? 0x2000 : 0x0000) + x + 1]; uint32_t pixels2 = appleHiresToMono[previousLoPixel | screenByte]; previousLoPixel = (screenByte << 2) & 0x0100; @@ -1077,7 +1055,6 @@ static void RenderHiRes(uint16_t toLine/*= 192*/) } } - static void RenderDHiRes(uint16_t toLine/*= 192*/) { // Now it is. Now roll this fix into all the other places... !!! FIX !!! @@ -1092,14 +1069,18 @@ static void RenderDHiRes(uint16_t toLine/*= 192*/) for(uint16_t x=0; x<40; x+=2) { - uint8_t screenByte = ram[lineAddrHiRes[y] + (displayPage2 ? 0x2000 : 0x0000) + x]; + uint8_t screenByte = ram[lineAddrHiRes[y] + (!store80Mode && displayPage2 ? 0x2000 : 0x0000) + x]; uint32_t pixels = (mirrorTable[screenByte & 0x7F]) << 14; - screenByte = ram[lineAddrHiRes[y] + (displayPage2 ? 0x2000 : 0x0000) + x + 1]; + + screenByte = ram[lineAddrHiRes[y] + (!store80Mode && displayPage2 ? 0x2000 : 0x0000) + x + 1]; pixels = pixels | (mirrorTable[screenByte & 0x7F]); - screenByte = ram2[lineAddrHiRes[y] + (displayPage2 ? 0x2000 : 0x0000) + x]; + + screenByte = ram2[lineAddrHiRes[y] + (!store80Mode && displayPage2 ? 0x2000 : 0x0000) + x]; pixels = pixels | ((mirrorTable[screenByte & 0x7F]) << 21); - screenByte = ram2[lineAddrHiRes[y] + (displayPage2 ? 0x2000 : 0x0000) + x + 1]; + + screenByte = ram2[lineAddrHiRes[y] + (!store80Mode && displayPage2 ? 0x2000 : 0x0000) + x + 1]; pixels = pixels | ((mirrorTable[screenByte & 0x7F]) << 7); + pixels = previous4bits | (pixels >> 1); // We now have 28 pixels (expanded from 14) in word: mask is $0F FF FF FF @@ -1140,7 +1121,6 @@ static void RenderDHiRes(uint16_t toLine/*= 192*/) } } - void RenderVideoFrame(void) { if (GUI::powerOnState == true) @@ -1204,7 +1184,6 @@ void RenderVideoFrame(void) DrawFrameTicks(); } - // // Prime SDL and create surfaces // @@ -1258,7 +1237,6 @@ bool InitVideo(void) return true; } - // // Free various SDL components // @@ -1272,7 +1250,6 @@ void VideoDone(void) WriteLog("Video: Done.\n"); } - // // Render the Apple video screen to the primary texture // @@ -1285,7 +1262,6 @@ void RenderAppleScreen(SDL_Renderer * renderer) SDL_RenderCopy(renderer, sdlTexture, NULL, NULL); } - // // Fullscreen <-> window switching // @@ -1298,4 +1274,3 @@ void ToggleFullScreen(void) if (retVal != 0) WriteLog("Video::ToggleFullScreen: SDL error = %s\n", SDL_GetError()); } -