for(int x=0; x<80; x++)
{
-#if 0
-// This is wrong; it should grab from the alt bank if Page2 is set, not main RAM @ $0
- uint8_t chr = ram[lineAddrLoRes[line] + (displayPage2 ? 0x0400 : 0x0000) + x];
-
- if (x > 39)
- chr = ram2[lineAddrLoRes[line] + (displayPage2 ? 0x0400 : 0x0000) + x - 40];
-#else
uint8_t chr;
if (x & 0x01)
chr = ram[lineAddrLoRes[line] + (x >> 1)];
else
chr = ram2[lineAddrLoRes[line] + (x >> 1)];
-#endif
// Render character at (x, y)
}
+//
+// Render the Double Lo Res screen (HIRES off, DHIRES on)
+//
+static void RenderDLoRes(void)
+{
+// NOTE: The green mono rendering doesn't skip every other line... !!! FIX !!!
+// Also, we could set up three different Render functions depending on
+// which render type was set and call it with a function pointer. Would be
+// faster then the nested ifs we have now.
+/*
+Note that these colors correspond to the bit patterns generated by the numbers 0-F in order:
+Color #s correspond to the bit patterns in reverse... Interesting! [It's because
+the video generator reads the bit patters from bit 0--which makes them backwards
+from the normal POV.]
+
+00 00 00 -> 0 [0000] -> 0 (lores color #)
+3C 4D 00 -> 8 [0001] -> 8? BROWN
+00 5D 3C -> 4 [0010] -> 4? DARK GREEN
+3C AA 3C -> 12 [0011] -> 12? LIGHT GREEN (GREEN)
+41 30 7D -> 2 [0100] -> 2? DARK BLUE
+7D 7D 7D -> 10 [0101] -> 10? LIGHT GRAY (Grays are identical)
+41 8E BA -> 6 [0110] -> 6? MEDIUM BLUE (BLUE)
+7D DB BA -> 14 [0111] -> 14? AQUAMARINE (AQUA)
+7D 20 41 -> 1 [1000] -> 1? DEEP RED (MAGENTA)
+BA 6D 41 -> 9 [1001] -> 9? ORANGE
+7D 7D 7D -> 5 [1010] -> 5? DARK GRAY (Grays are identical)
+BA CB 7D -> 13 [1011] -> 13? YELLOW
+BE 51 BE -> 3 [1100] -> 3 PURPLE (VIOLET)
+FB 9E BE -> 11 [1101] -> 11? PINK
+BE AE FB -> 7 [1110] -> 7? LIGHT BLUE (CYAN)
+FB FB FB -> 15 [1111] -> 15 WHITE
+*/
+ uint8_t mirrorNybble[16] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
+ // Rotated one bit right (in the nybble)--right instead of left because
+ // these are backwards after all :-P
+ uint8_t mirrorNybble2[16] = { 0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15 };
+ uint32_t pixelOn = (screenType == ST_WHITE_MONO ? 0xFFFFFFFF : 0xFF61FF61);
+
+ for(uint16_t y=0; y<24; y++)
+ {
+ // Do top half of double lores screen bytes...
+
+ uint32_t previous3Bits = 0;
+
+ for(uint16_t x=0; x<40; x+=2)
+ {
+ uint8_t scrByte3 = ram2[lineAddrLoRes[y] + x + 0] & 0x0F;
+ uint8_t scrByte4 = ram2[lineAddrLoRes[y] + x + 1] & 0x0F;
+ uint8_t scrByte1 = ram[lineAddrLoRes[y] + x + 0] & 0x0F;
+ uint8_t scrByte2 = ram[lineAddrLoRes[y] + x + 1] & 0x0F;
+ scrByte1 = mirrorNybble[scrByte1];
+ scrByte2 = mirrorNybble[scrByte2];
+ scrByte3 = mirrorNybble2[scrByte3];
+ scrByte4 = mirrorNybble2[scrByte4];
+ // This is just a guess, but it'll have to do for now...
+ uint32_t pixels = previous3Bits | (scrByte3 << 24)
+ | (scrByte3 << 20) | (scrByte1 << 16)
+ | ((scrByte1 & 0x0C) << 12) | ((scrByte4 & 0x03) << 12)
+ | (scrByte4 << 8) | (scrByte2 << 4) | scrByte2;
+
+ // We now have 28 pixels (expanded from 14) in word: mask is $0F FF FF FF
+ // 0ppp 1111 1111 1111 11|11 1111 1111 1111
+ // 31 27 23 19 15 11 7 3 0
+
+ if (screenType == ST_COLOR_TV)
+ {
+ for(uint8_t i=0; i<7; i++)
+ {
+ uint8_t bitPat = (pixels & 0x7F000000) >> 24;
+ pixels <<= 4;
+
+ for(uint8_t j=0; j<4; j++)
+ {
+ uint8_t color = blurTable[bitPat][j];
+
+ 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];
+ }
+ }
+ }
+
+ previous3Bits = pixels & 0x70000000;
+ }
+ else
+ {
+ for(int j=0; j<28; j++)
+ {
+ for(uint32_t cy=0; cy<8; cy++)
+ {
+ scrBuffer[((x * 14) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = (pixels & 0x08000000 ? pixelOn : 0xFF000000);
+ }
+
+ pixels <<= 1;
+ }
+ }
+ }
+
+ // Now do bottom half...
+
+ previous3Bits = 0;
+
+ for(uint16_t x=0; x<40; x+=2)
+ {
+ uint8_t scrByte3 = ram2[lineAddrLoRes[y] + x + 0] >> 4;
+ uint8_t scrByte4 = ram2[lineAddrLoRes[y] + x + 1] >> 4;
+ uint8_t scrByte1 = ram[lineAddrLoRes[y] + x + 0] >> 4;
+ uint8_t scrByte2 = ram[lineAddrLoRes[y] + x + 1] >> 4;
+ scrByte1 = mirrorNybble[scrByte1];
+ scrByte2 = mirrorNybble[scrByte2];
+ scrByte3 = mirrorNybble2[scrByte3];
+ scrByte4 = mirrorNybble2[scrByte4];
+ // This is just a guess, but it'll have to do for now...
+// uint32_t pixels = previous3Bits | (scrByte1 << 24) | (scrByte1 << 20) | (scrByte1 << 16)
+// | ((scrByte1 & 0x0C) << 12) | ((scrByte2 & 0x03) << 12)
+// | (scrByte2 << 8) | (scrByte2 << 4) | scrByte2;
+ uint32_t pixels = previous3Bits | (scrByte3 << 24)
+ | (scrByte3 << 20) | (scrByte1 << 16)
+ | ((scrByte1 & 0x0C) << 12) | ((scrByte4 & 0x03) << 12)
+ | (scrByte4 << 8) | (scrByte2 << 4) | scrByte2;
+
+ // We now have 28 pixels (expanded from 14) in word: mask is $0F FF FF FF
+ // 0ppp 1111 1111 1111 11|11 1111 1111 1111
+ // 31 27 23 19 15 11 7 3 0
+
+ if (screenType == ST_COLOR_TV)
+ {
+ for(uint8_t i=0; i<7; i++)
+ {
+ uint8_t bitPat = (pixels & 0x7F000000) >> 24;
+ pixels <<= 4;
+
+ for(uint8_t j=0; j<4; j++)
+ {
+ uint8_t color = blurTable[bitPat][j];
+
+ for(uint32_t cy=8; cy<16; cy++)
+ {
+ scrBuffer[((x * 14) + (i * 4) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = palette[color];
+ }
+ }
+ }
+
+ previous3Bits = pixels & 0x70000000;
+ }
+ else
+ {
+ for(int j=0; j<28; j++)
+ {
+ for(uint32_t cy=8; cy<16; cy++)
+ {
+ scrBuffer[((x * 14) + j) + (((y * 16) + cy) * VIRTUAL_SCREEN_WIDTH)] = (pixels & 0x08000000 ? pixelOn : 0xFF000000);
+ }
+
+ pixels <<= 1;
+ }
+ }
+ }
+ }
+}
+
+
static void RenderHiRes(uint16_t toLine/*= 192*/)
{
//printf("RenderHiRes to line %u\n", toLine);
else
{
if (dhires)
- RenderDHiRes();
+ {
+ if (hiRes)
+ RenderDHiRes();
+ else
+ RenderDLoRes();
+ }
else if (hiRes)
RenderHiRes();
else
// int retVal = SDL_CreateWindowAndRenderer(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, SDL_WINDOW_OPENGL, &sdlWindow, &sdlRenderer);
int retVal = SDL_CreateWindowAndRenderer(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 0, &sdlWindow, &sdlRenderer);
+// int retVal = SDL_CreateWindowAndRenderer(VIRTUAL_SCREEN_WIDTH * 1, VIRTUAL_SCREEN_HEIGHT * 1, 0, &sdlWindow, &sdlRenderer);
if (retVal != 0)
{