]> Shamusworld >> Repos - apple2/blobdiff - src/video.cpp
Improvements to timing, disk selector; added Double LoRes.
[apple2] / src / video.cpp
index 444b7e54620ab19065e55d9fccd3daa463017a4d..7a28cde86d5563e6c9313ec56f68501df5fde16e 100644 (file)
@@ -494,20 +494,12 @@ static void Render80ColumnTextLine(uint8_t line)
 
        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)
 
@@ -732,6 +724,169 @@ fb fb fb -> 15 [1111] -> 15               WHITE
 }
 
 
+//
+// 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);
@@ -912,7 +1067,12 @@ void RenderVideoFrame(void)
                        else
                        {
                                if (dhires)
-                                       RenderDHiRes();
+                               {
+                                       if (hiRes)
+                                               RenderDHiRes();
+                                       else
+                                               RenderDLoRes();
+                               }
                                else if (hiRes)
                                        RenderHiRes();
                                else
@@ -946,6 +1106,7 @@ bool InitVideo(void)
 
 //     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)
        {