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