1 //+----------------------------------------------------------------------------
5 // Module: Video driver
7 // Synopsis: low-level interface to video memory
9 // Created: sgasch 5 Jul 2003
11 //+----------------------------------------------------------------------------
20 extern BIOS_HARDWARE_BLOCK g_BiosHardwareBlock;
25 #define FG_BG_TO_ATTRIB_BYTE(fg,bg) ((fg&0x0F)|((bg&0x0F)<<4))
28 #define CRT_ADDR_REG (0x3D4)
29 #define CRT_DATA_REG (0x3D5)
30 #define CRT_CURSOR_LOC_HIGH_REG (0x0E)
31 #define CRT_CURSOR_LOC_LOW_REG (0x0F)
32 #define ZERO_BASED_LINE_COL_TO_BYTE_OFFSET(L,C)\
33 (((g_bScreenResolution[COLS] << 1) * (L)) + ((C) << 1))
34 #define ZERO_BASED_LINE_COL_TO_ULONG_OFFSET(L,C)\
35 (ZERO_BASED_LINE_COL_TO_BYTE_OFFSET((L),(C)) >> 2)
40 BYTE *g_pVideoMemory = NULL;
41 BYTE g_bScreenResolution[2] = { 0, 0 };
42 BYTE g_bSoftCursor[2] = { 0, 0 };
43 BYTE g_bColorAttribute = FG_BG_TO_ATTRIB_BYTE(BLACK, WHITE);
45 typedef struct _VIDEO_LOOKUP_ENTRY
48 BYTE *pStartOfVideoMemory;
53 static VIDEO_LOOKUP_ENTRY g_VideoLookupTable[] =
58 { "Monochrome display adapter",
64 { "Code 3: Undefined",
67 { "EGA with color display",
70 { "EGA with mono display",
73 { "Code 6: Undefined",
76 { "VGA with mono display",
79 { "VGA with color display",
82 { "Code 9: Undefined",
85 { "MCGA with digital color",
88 { "MCGA with monochrome",
91 { "MCGA with analog color",
97 //+----------------------------------------------------------------------------
99 // Function: VideopInitialize
107 //+----------------------------------------------------------------------------
109 VideopInitialize(void)
111 BYTE uType = g_BiosHardwareBlock.bDisplayType;
115 // Based on the font size (width in pixels), set the index into the
116 // screen lines lookup table
118 switch(g_BiosHardwareBlock.bFontSize)
132 // If the display type returned by BIOS is known to us, use the
133 // lookup table to populate some globals here.
135 if (uType <= ARRAY_LENGTH(g_VideoLookupTable))
137 g_pVideoMemory = g_VideoLookupTable[uType].pStartOfVideoMemory;
138 g_bScreenResolution[LINES] =
139 g_VideoLookupTable[uType].uScreenLines[uIndex];
143 // Otherwise make some guesses
147 g_pVideoMemory = (BYTE *)0x000B8000;
148 g_bScreenResolution[LINES] = 25;
150 g_bScreenResolution[COLS] = 80;
153 // Set color to WHITE on BLACK
155 VideoSetCurrentColorAttribute(WHITE, BLACK);
158 // Clear the screen and thus synchronize the hardware and soft cursor
162 return(STATUS_SUCCESS);
166 //+----------------------------------------------------------------------------
168 // Function: VideoDriverMain
172 // Arguments: UINT uEvent
176 //+----------------------------------------------------------------------------
178 VideoDriverMain(UINT uEvent)
182 case DEVICE_DRIVER_INITIALIZATION:
183 return(VideopInitialize());
187 return(STATUS_NOT_SUPPORTED);
189 case DEVICE_DRIVER_SHUTDOWN:
190 g_fVideoEnabled = FALSE;
191 return(STATUS_SUCCESS);
199 VideoDriverRead(UINT uAddress,
204 VideoDriverWrite(UINT uAddress,
209 VideoDriverIoctl(UINT uIoctlCode,
215 // Move the hardware cursor on the screen to sync up with the software
216 // cursor position in g_bSoftwareCursor
219 VideoSetHardwareCursor(void)
221 WORD wOffset; // byte offset into video mem
222 BYTE bOrig; // original port contents holder
225 // Cursor is zero-based (e.g. line 24 is the last one)
227 ASSERT(g_bSoftCursor[LINES] < g_bScreenResolution[LINES]);
228 ASSERT(g_bSoftCursor[COLS] < g_bScreenResolution[COLS]);
230 wOffset = ZERO_BASED_LINE_COL_TO_BYTE_OFFSET(g_bSoftCursor[LINES],
231 g_bSoftCursor[COLS]);
232 ASSERT(wOffset <= (g_bScreenResolution[LINES] *
233 g_bScreenResolution[COLS]) * 2 - 2);
236 // Save original contents of CRT address register.
238 bOrig = in(CRT_ADDR_REG);
241 // Set the high cursor location byte
243 out(CRT_ADDR_REG, CRT_CURSOR_LOC_HIGH_REG);
244 out(CRT_DATA_REG, (wOffset >> 8) & 0xFF);
248 // Set the low cursor location byte
250 out(CRT_ADDR_REG, CRT_CURSOR_LOC_LOW_REG);
252 out(CRT_DATA_REG, (wOffset & 0xFF));
256 // Restore contents of the CRT address register
258 out(CRT_ADDR_REG, bOrig);
263 VideoSetCurrentColorAttribute(BYTE bFg, BYTE bBg)
265 bFg &= 0x0F; // restrict these guys to colors
266 bBg &= 0x0F; // and the high intense bit
268 g_bColorAttribute = FG_BG_TO_ATTRIB_BYTE(bFg, bBg);
272 VideoClearScreen(void)
274 ULONG *p = (ULONG *)g_pVideoMemory;
279 // Start uCount at the number of ULONGs in visible video memory
281 uCount = ZERO_BASED_LINE_COL_TO_BYTE_OFFSET(g_bScreenResolution[LINES] - 1,
282 g_bScreenResolution[COLS] - 1);
287 // Construct a fill ULONG: blank attrib blank attrib
290 uFill |= (ULONG)g_bColorAttribute;
291 uFill |= ((ULONG)g_bColorAttribute) << 16;
294 // Blast uFills into video memory
303 // Set cursor position to 0,0
305 g_bSoftCursor[LINES] = g_bSoftCursor[COLS] = 0;
306 VideoSetHardwareCursor();
313 ULONG *p = (ULONG *)g_pVideoMemory;
314 ULONG uUlongsPerLine = (g_bScreenResolution[COLS] >> 1); // 2X/4
318 ASSERT(sizeof(ULONG) == 4);
319 ASSERT(sizeof(BYTE) == 1);
322 i < (g_bScreenResolution[LINES] - 2);
326 // Start at i, 0. Copy a ULONG up from i+1, 0. Do the whole line i.
332 *p = *(p + uUlongsPerLine);
338 // Construct a fill ULONG: blank attrib blank attrib
341 uFill |= (ULONG)g_bColorAttribute;
342 uFill |= ((ULONG)g_bColorAttribute) << 16;
345 // Blank the last line
347 p = (ULONG *)(g_pVideoMemory +
348 ZERO_BASED_LINE_COL_TO_BYTE_OFFSET(g_bScreenResolution[LINES] - 1, 0));
361 BYTE *p = (g_pVideoMemory +
362 ZERO_BASED_LINE_COL_TO_BYTE_OFFSET(g_bSoftCursor[LINES],
363 g_bSoftCursor[COLS]));
367 g_bSoftCursor[LINES]++;
368 if (g_bSoftCursor[LINES] >= g_bScreenResolution[LINES])
371 g_bSoftCursor[LINES] = g_bScreenResolution[LINES] - 1;
373 g_bSoftCursor[COLS] = 0;
378 *p = g_bColorAttribute;
380 g_bSoftCursor[COLS]++;
381 if (g_bSoftCursor[COLS] >= g_bScreenResolution[COLS])
383 g_bSoftCursor[COLS] = 0;
384 g_bSoftCursor[LINES]++;
385 if (g_bSoftCursor[LINES] >= g_bScreenResolution[LINES])
388 g_bSoftCursor[LINES] = g_bScreenResolution[LINES] - 1;
395 VideoPutNullTerminatedString(BYTE *s)
407 VideoPutNullTerminatedString("RUNAWAYSTRING!?!\n\0");
411 VideoSetHardwareCursor();
415 VideoSetCursorPosition(BYTE bLine, BYTE bCol)
417 if (bLine >= g_bScreenResolution[LINES])
419 bLine = g_bScreenResolution[LINES] - 1;
421 if (bCol >= g_bScreenResolution[COLS])
423 bCol = g_bScreenResolution[COLS] - 1;
426 g_bSoftCursor[LINES] = bLine;
427 g_bSoftCursor[COLS] = bCol;
428 VideoSetHardwareCursor();
432 VideoGetCursorPosition(BYTE *pbLine, BYTE *pbCol)
434 *pbLine = g_bSoftCursor[LINES];
435 *pbCol = g_bSoftCursor[COLS];
439 VideoPrint(CHAR *szFormat, ...)
449 va_start(args, szFormat);
464 iVal = va_arg(args, int);
465 q = RtlIntToAscii(iVal, buf, ARRAY_LENGTH(buf), 10);
466 ASSERT(strlen(q) < 20);
467 VideoPutNullTerminatedString(q);
470 uVal = va_arg(args, unsigned int);
471 q = RtlIntToAscii(uVal, buf, ARRAY_LENGTH(buf), 10);
472 ASSERT(strlen(q) < 20);
473 VideoPutNullTerminatedString(q);
476 uVal = va_arg(args, unsigned int);
477 q = RtlIntToAscii(uVal, buf, ARRAY_LENGTH(buf), 16);
478 ASSERT(strlen(q) < 20);
479 VideoPutNullTerminatedString(q);
482 szVal = va_arg(args, char *);
483 VideoPutNullTerminatedString(szVal);
486 iVal = va_arg(args, int);
487 VideoPutChar(iVal & 0xFF);
502 VideoSetHardwareCursor();