1 #include "precomp.h" 2 3 #define NDEBUG 4 #include <debug.h> 5 6 PUSHORT VgaArmBase; 7 PHYSICAL_ADDRESS VgaPhysical; 8 9 /* PRIVATE FUNCTIONS *********************************************************/ 10 11 VOID 12 NTAPI 13 DisplayCharacter( 14 _In_ CHAR Character, 15 _In_ ULONG Left, 16 _In_ ULONG Top, 17 _In_ ULONG TextColor, 18 _In_ ULONG BackColor) 19 { 20 PUCHAR FontChar; 21 ULONG i, j, XOffset; 22 23 /* Get the font line for this character */ 24 FontChar = &VidpFontData[Character * BOOTCHAR_HEIGHT - Top]; 25 26 /* Loop each pixel height */ 27 for (i = BOOTCHAR_HEIGHT; i > 0; --i) 28 { 29 /* Loop each pixel width */ 30 XOffset = Left; 31 for (j = (1 << 7); j > 0; j >>= 1) 32 { 33 /* Check if we should draw this pixel */ 34 if (FontChar[Top] & (UCHAR)j) 35 { 36 /* We do, use the given Text Color */ 37 SetPixel(XOffset, Top, (UCHAR)TextColor); 38 } 39 else if (BackColor < BV_COLOR_NONE) 40 { 41 /* 42 * This is a background pixel. We're drawing it 43 * unless it's transparent. 44 */ 45 SetPixel(XOffset, Top, (UCHAR)BackColor); 46 } 47 48 /* Increase X Offset */ 49 XOffset++; 50 } 51 52 /* Move to the next Y ordinate */ 53 Top++; 54 } 55 } 56 57 VOID 58 NTAPI 59 DoScroll( 60 _In_ ULONG Scroll) 61 { 62 ULONG Top, Offset; 63 PUSHORT SourceOffset, DestOffset; 64 PUSHORT i, j; 65 66 /* Set memory positions of the scroll */ 67 SourceOffset = &VgaArmBase[(VidpScrollRegion[1] * (SCREEN_WIDTH / 8)) + (VidpScrollRegion[0] >> 3)]; 68 DestOffset = &SourceOffset[Scroll * (SCREEN_WIDTH / 8)]; 69 70 /* Start loop */ 71 for (Top = VidpScrollRegion[1]; Top <= VidpScrollRegion[3]; ++Top) 72 { 73 /* Set number of bytes to loop and start offset */ 74 Offset = VidpScrollRegion[0] >> 3; 75 j = SourceOffset; 76 77 /* Check if this is part of the scroll region */ 78 if (Offset <= (VidpScrollRegion[2] >> 3)) 79 { 80 /* Update position */ 81 i = (PUSHORT)(DestOffset - SourceOffset); 82 83 /* Loop the X axis */ 84 do 85 { 86 /* Write value in the new position so that we can do the scroll */ 87 WRITE_REGISTER_USHORT(j, READ_REGISTER_USHORT(j + (ULONG_PTR)i)); 88 89 /* Move to the next memory location to write to */ 90 j++; 91 92 /* Move to the next byte in the region */ 93 Offset++; 94 95 /* Make sure we don't go past the scroll region */ 96 } while (Offset <= (VidpScrollRegion[2] >> 3)); 97 } 98 99 /* Move to the next line */ 100 SourceOffset += (SCREEN_WIDTH / 8); 101 DestOffset += (SCREEN_WIDTH / 8); 102 } 103 } 104 105 VOID 106 NTAPI 107 PreserveRow( 108 _In_ ULONG CurrentTop, 109 _In_ ULONG TopDelta, 110 _In_ BOOLEAN Restore) 111 { 112 PUSHORT Position1, Position2; 113 ULONG Count; 114 115 /* Calculate the position in memory for the row */ 116 if (Restore) 117 { 118 /* Restore the row by copying back the contents saved off-screen */ 119 Position1 = &VgaArmBase[CurrentTop * (SCREEN_WIDTH / 8)]; 120 Position2 = &VgaArmBase[SCREEN_HEIGHT * (SCREEN_WIDTH / 8)]; 121 } 122 else 123 { 124 /* Preserve the row by saving its contents off-screen */ 125 Position1 = &VgaArmBase[SCREEN_HEIGHT * (SCREEN_WIDTH / 8)]; 126 Position2 = &VgaArmBase[CurrentTop * (SCREEN_WIDTH / 8)]; 127 } 128 129 /* Set the count and loop every pixel */ 130 Count = TopDelta * (SCREEN_WIDTH / 8); 131 while (Count--) 132 { 133 /* Write the data back on the other position */ 134 WRITE_REGISTER_USHORT(Position1, READ_REGISTER_USHORT(Position2)); 135 136 /* Increase both positions */ 137 Position1++; 138 Position2++; 139 } 140 } 141 142 VOID 143 NTAPI 144 VidpInitializeDisplay(VOID) 145 { 146 // 147 // Set framebuffer address 148 // 149 WRITE_REGISTER_ULONG(PL110_LCDUPBASE, VgaPhysical.LowPart); 150 WRITE_REGISTER_ULONG(PL110_LCDLPBASE, VgaPhysical.LowPart); 151 152 // 153 // Initialize timings to 640x480 154 // 155 WRITE_REGISTER_ULONG(PL110_LCDTIMING0, LCDTIMING0_PPL(SCREEN_WIDTH)); 156 WRITE_REGISTER_ULONG(PL110_LCDTIMING1, LCDTIMING1_LPP(SCREEN_HEIGHT)); 157 158 // 159 // Enable the LCD Display 160 // 161 WRITE_REGISTER_ULONG(PL110_LCDCONTROL, 162 LCDCONTROL_LCDEN | 163 LCDCONTROL_LCDTFT | 164 LCDCONTROL_LCDPWR | 165 LCDCONTROL_LCDBPP(4)); 166 } 167 168 VOID 169 NTAPI 170 InitPaletteWithTable( 171 _In_ PULONG Table, 172 _In_ ULONG Count) 173 { 174 UNIMPLEMENTED; 175 } 176 177 /* PUBLIC FUNCTIONS **********************************************************/ 178 179 /* 180 * @implemented 181 */ 182 BOOLEAN 183 NTAPI 184 VidInitialize( 185 _In_ BOOLEAN SetMode) 186 { 187 DPRINT1("bv-arm v0.1\n"); 188 189 // 190 // Allocate framebuffer 191 // 600kb works out to 640x480@16bpp 192 // 193 VgaPhysical.QuadPart = -1; 194 VgaArmBase = MmAllocateContiguousMemory(600 * 1024, VgaPhysical); 195 if (!VgaArmBase) return FALSE; 196 197 // 198 // Get physical address 199 // 200 VgaPhysical = MmGetPhysicalAddress(VgaArmBase); 201 if (!VgaPhysical.QuadPart) return FALSE; 202 DPRINT1("[BV-ARM] Frame Buffer @ 0x%p 0p%p\n", VgaArmBase, VgaPhysical.LowPart); 203 204 // 205 // Setup the display 206 // 207 VidpInitializeDisplay(); 208 209 // 210 // We are done! 211 // 212 return TRUE; 213 } 214 215 /* 216 * @implemented 217 */ 218 VOID 219 NTAPI 220 VidResetDisplay( 221 _In_ BOOLEAN HalReset) 222 { 223 // 224 // Clear the current position 225 // 226 VidpCurrentX = 0; 227 VidpCurrentY = 0; 228 229 // 230 // Re-initialize the VGA Display 231 // 232 VidpInitializeDisplay(); 233 234 // 235 // Re-initialize the palette and fill the screen black 236 // 237 InitializePalette(); 238 VidSolidColorFill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, BV_COLOR_BLACK); 239 } 240 241 /* 242 * @implemented 243 */ 244 VOID 245 NTAPI 246 VidCleanUp(VOID) 247 { 248 UNIMPLEMENTED; 249 while (TRUE); 250 } 251 252 /* 253 * @implemented 254 */ 255 VOID 256 NTAPI 257 VidScreenToBufferBlt( 258 _Out_writes_bytes_(Delta * Height) PUCHAR Buffer, 259 _In_ ULONG Left, 260 _In_ ULONG Top, 261 _In_ ULONG Width, 262 _In_ ULONG Height, 263 _In_ ULONG Delta) 264 { 265 UNIMPLEMENTED; 266 while (TRUE); 267 } 268 269 /* 270 * @implemented 271 */ 272 VOID 273 NTAPI 274 VidSolidColorFill( 275 _In_ ULONG Left, 276 _In_ ULONG Top, 277 _In_ ULONG Right, 278 _In_ ULONG Bottom, 279 _In_ UCHAR Color) 280 { 281 int y, x; 282 283 // 284 // Loop along the Y-axis 285 // 286 for (y = Top; y <= Bottom; y++) 287 { 288 // 289 // Loop along the X-axis 290 // 291 for (x = Left; x <= Right; x++) 292 { 293 // 294 // Draw the pixel 295 // 296 SetPixel(x, y, Color); 297 } 298 } 299 } 300