Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

630 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. display.c
  5. Author:
  6. Thomas Parslow (tomp) Mar-01-90
  7. Abstract:
  8. Video support routines.
  9. The SU module only need to be able to write to the video display
  10. in order to report errors, traps, etc.
  11. The routines in this file all write to a video buffer assumed to be
  12. at realmode address b800:0000, and 4k bytes in length. The segment
  13. portion of the far pointers used to access the video buffer are stamped
  14. with a protmode selector value when we switch to protect mode. This is
  15. done in the routine "ProtMode" in "misc386.asm".
  16. --*/
  17. #include "su.h"
  18. #define ZLEN_SHORT(x) ((x < 0x10) + (x < 0x100) + (x < 0x1000))
  19. #define ZLEN_LONG(x) ((x < 0x10) + (x < 0x100) + (x < 0x1000) + (x < 0x10000) + (x < 0x100000)+(x < 0x1000000)+(x < 0x10000000))
  20. #ifdef DEBUG1
  21. #define ROWS 43
  22. #else
  23. #define ROWS 25
  24. #endif
  25. #define COLUMNS 80
  26. #define SCREEN_WIDTH COLUMNS
  27. #define SCREEN_SIZE ROWS * COLUMNS
  28. #define NORMAL_ATTRIB 0x07
  29. #define REVERSE_ATTRIB 0x70
  30. #define SCREEN_START 0xb8000000
  31. #define VIDEO_BIOS 0x10
  32. #define LINES_400_CONFIGURATION 0x1202
  33. #define SELECT_SCAN_LINE 0x301
  34. #define SET_80X25_16_COLOR_MODE 0x3
  35. #define LOAD_8X8_CHARACTER_SET 0x1112
  36. //
  37. // Internal routines
  38. //
  39. static
  40. VOID
  41. tab(
  42. VOID
  43. );
  44. static
  45. VOID
  46. newline(
  47. VOID
  48. );
  49. static
  50. VOID
  51. putzeros(
  52. USHORT,
  53. USHORT
  54. );
  55. USHORT
  56. Redirect = 0;
  57. VOID
  58. InitializeVideoSubSystem(
  59. VOID
  60. )
  61. /*++
  62. Routine Description:
  63. Initializes the video mode to 80x50 alphanumeric mode with 400 lines
  64. vertical resolution.
  65. Arguments:
  66. None
  67. Returns:
  68. Nothing
  69. --*/
  70. {
  71. BIOSREGS ps;
  72. UCHAR _far *BiosArea;
  73. //
  74. // Set 40:10 to indicate color is the default display
  75. // *(40:10) &= ~0x30;
  76. // *(40:10) |= 0x20;
  77. //
  78. // Fixes obscure situation where both monochrome and VGA adapters
  79. // are installed and the monochrome is the default display.
  80. //
  81. BiosArea = (UCHAR _far *)(0x410L);
  82. *BiosArea &= ~0x30;
  83. *BiosArea |= 0x20;
  84. //
  85. // Establish 80x25 alphanumeric mode with 400-lines vertical resolution
  86. //
  87. ps.fn = VIDEO_BIOS;
  88. ps.ax = LINES_400_CONFIGURATION;
  89. ps.bx = SELECT_SCAN_LINE;
  90. biosint(&ps);
  91. ps.fn = VIDEO_BIOS;
  92. ps.ax = SET_80X25_16_COLOR_MODE;
  93. biosint(&ps);
  94. DBG1(
  95. ps.ax = LOAD_8X8_CHARACTER_SET;
  96. ps.bx = 0;
  97. biosint(&ps);
  98. )
  99. //
  100. // HACK-O-RAMA - Make some random video BIOS calls here to make sure the
  101. // BIOS is initialized and warmed up and ready to go. Otherwise,
  102. // some Number 9 S3 cards don't quite work right later in the game.
  103. // John Vert (jvert) 9-Jun-1993
  104. //
  105. //
  106. // set cursor position to 0,0
  107. //
  108. ps.fn = VIDEO_BIOS;
  109. ps.ax = 0x2000;
  110. ps.bx = 0;
  111. ps.dx = 0;
  112. biosint(&ps);
  113. //
  114. // write character (' ' in this case)
  115. //
  116. ps.fn = VIDEO_BIOS;
  117. ps.ax = 0x0a00 | (USHORT)' ';
  118. ps.bx = 0;
  119. ps.cx = 1;
  120. biosint(&ps);
  121. clrscrn();
  122. return ;
  123. }
  124. //
  125. // Used by all BlPrint subordinate routines for padding computations.
  126. //
  127. CHAR sc=0;
  128. ULONG fw=0;
  129. VOID
  130. BlPrint(
  131. PCHAR cp,
  132. ...
  133. )
  134. /*++
  135. Routine Description:
  136. Standard printf function with a subset of formating features supported.
  137. Currently handles
  138. %d, %ld - signed short, signed long
  139. %u, %lu - unsigned short, unsigned long
  140. %c, %s - character, string
  141. %x, %lx - unsigned print in hex, unsigned long print in hex
  142. Does not do:
  143. - field width specification
  144. - floating point.
  145. Arguments:
  146. cp - pointer to the format string, text string.
  147. Returns:
  148. Nothing
  149. --*/
  150. {
  151. USHORT b,c,w,len;
  152. PUCHAR ap;
  153. ULONG l;
  154. //
  155. // Cast a pointer to the first word on the stack
  156. //
  157. ap = (PUCHAR)&cp + sizeof(PCHAR);
  158. sc = ' '; // default padding char is space
  159. //
  160. // Process the arguments using the descriptor string
  161. //
  162. while (b = *cp++)
  163. {
  164. if (b == '%')
  165. {
  166. c = *cp++;
  167. switch (c)
  168. {
  169. case 'd':
  170. puti((long)*((int *)ap));
  171. ap += sizeof(int);
  172. break;
  173. case 's':
  174. puts(*((PCHAR *)ap));
  175. ap += sizeof (char *);
  176. break;
  177. case 'c':
  178. putc(*((char *)ap));
  179. ap += sizeof(int);
  180. break;
  181. case 'x':
  182. w = *((USHORT *)ap);
  183. len = ZLEN_SHORT(w);
  184. while(len--) putc('0');
  185. putx((ULONG)*((USHORT *)ap));
  186. ap += sizeof(int);
  187. break;
  188. case 'u':
  189. putu((ULONG)*((USHORT *)ap));
  190. ap += sizeof(int);
  191. break;
  192. case 'l':
  193. c = *cp++;
  194. switch(c) {
  195. case 'u':
  196. putu(*((ULONG *)ap));
  197. ap += sizeof(long);
  198. break;
  199. case 'x':
  200. l = *((ULONG *)ap);
  201. len = ZLEN_LONG(l);
  202. while(len--) putc('0');
  203. putx(*((ULONG *)ap));
  204. ap += sizeof(long);
  205. break;
  206. case 'd':
  207. puti(*((ULONG *)ap));
  208. ap += sizeof(long);
  209. break;
  210. }
  211. break;
  212. default :
  213. putc((char)b);
  214. putc((char)c);
  215. }
  216. }
  217. else
  218. putc((char)b);
  219. }
  220. }
  221. FPUCHAR vp = (FPUCHAR)SCREEN_START;
  222. FPUCHAR ScreenStart = (FPUCHAR)SCREEN_START;
  223. static int lcnt = 0;
  224. static int row = 0;
  225. VOID puts(
  226. PCHAR cp
  227. )
  228. /*++
  229. Routine Description:
  230. Writes a string on the display at the current cursor position
  231. Arguments:
  232. cp - pointer to ASCIIZ string to display.
  233. Returns:
  234. Nothing
  235. --*/
  236. {
  237. char c;
  238. while(c = *cp++)
  239. putc(c);
  240. }
  241. //
  242. // Write a hex short to display
  243. //
  244. VOID putx(
  245. ULONG x
  246. )
  247. /*++
  248. Routine Description:
  249. Writes hex long to the display at the current cursor position.
  250. Arguments:
  251. x - ulong to write.
  252. Returns:
  253. Nothing
  254. --*/
  255. {
  256. ULONG j;
  257. if (x/16)
  258. putx(x/16);
  259. if((j=x%16) > 9) {
  260. putc((char)(j+'A'- 10));
  261. } else {
  262. putc((char)(j+'0'));
  263. }
  264. }
  265. VOID puti(
  266. LONG i
  267. )
  268. /*++
  269. Routine Description:
  270. Writes a long integer on the display at the current cursor position.
  271. Arguments:
  272. i - the integer to write to the display.
  273. Returns:
  274. Nothing
  275. --*/
  276. {
  277. if (i<0)
  278. {
  279. i = -i;
  280. putc((char)'-');
  281. }
  282. if (i/10)
  283. puti(i/10);
  284. putc((char)((i%10)+'0'));
  285. }
  286. VOID putu(
  287. ULONG u
  288. )
  289. /*++
  290. Routine Description:
  291. Write an unsigned long to display
  292. Arguments:
  293. u - unsigned
  294. --*/
  295. {
  296. if (u/10)
  297. putu(u/10);
  298. putc((char)((u%10)+'0'));
  299. }
  300. VOID putc(
  301. CHAR c
  302. )
  303. /*++
  304. Routine Description:
  305. Writes a character on the display at the current position.
  306. Arguments:
  307. c - character to write
  308. Returns:
  309. Nothing
  310. --*/
  311. {
  312. switch (c)
  313. {
  314. case '\n':
  315. newline();
  316. break;
  317. case '\t':
  318. tab();
  319. break;
  320. default :
  321. if (FP_OFF(vp) >= (SCREEN_SIZE * 2)) {
  322. vp = (FPUCHAR)((ScreenStart + (2*SCREEN_WIDTH*(ROWS-1))));
  323. scroll();
  324. }
  325. *vp = c;
  326. vp += 2;
  327. ++lcnt;
  328. }
  329. }
  330. VOID newline(
  331. VOID
  332. )
  333. /*++
  334. Routine Description:
  335. Moves the cursor to the beginning of the next line. If the bottom
  336. of the display has been reached, the screen is scrolled one line up.
  337. Arguments:
  338. None
  339. Returns:
  340. Nothing
  341. --*/
  342. {
  343. vp += (SCREEN_WIDTH - lcnt)<<1;
  344. if (++row > ROWS-1) {
  345. vp = (FPUCHAR)((ScreenStart + (2*SCREEN_WIDTH*(ROWS-1))));
  346. scroll();
  347. }
  348. lcnt = 0;
  349. }
  350. VOID scroll(
  351. VOID
  352. )
  353. /*++
  354. Routine Description:
  355. Scrolls the display UP one line.
  356. Arguments:
  357. None
  358. Returns:
  359. Nothing
  360. Notes:
  361. Currently we scroll the display by reading and writing directly from
  362. and to the video display buffer. We optionally switch to real mode
  363. and to int 10s
  364. --*/
  365. {
  366. USHORT i,j;
  367. USHORT far *p1 = (USHORT far *)ScreenStart;
  368. USHORT far *p2 = (USHORT far *)(ScreenStart + 2*SCREEN_WIDTH) ;
  369. for (i=0; i < ROWS - 1; i++)
  370. for (j=0; j < SCREEN_WIDTH; j++)
  371. *p1++ = *p2++;
  372. for (i=0; i < SCREEN_WIDTH; i++)
  373. *p1++ = REVERSE_ATTRIB*256 + ' ';
  374. }
  375. static
  376. VOID tab(
  377. VOID
  378. )
  379. /*++
  380. Routine Description:
  381. Computes the next tab stop and moves the cursor to that location.
  382. Arguments:
  383. None
  384. Returns:
  385. Nothing
  386. --*/
  387. {
  388. int inc;
  389. inc = 8 - (lcnt % 8);
  390. vp += inc<<1;
  391. lcnt += inc;
  392. }
  393. VOID clrscrn(
  394. VOID
  395. )
  396. /*++
  397. Routine Description:
  398. Clears the video display by writing blanks with the current
  399. video attribute over the entire display.
  400. Arguments:
  401. None
  402. Returns:
  403. Nothing
  404. --*/
  405. {
  406. int i,a;
  407. unsigned far *vwp = (unsigned far *)ScreenStart;
  408. a = NORMAL_ATTRIB*256 + ' ';
  409. for (i = SCREEN_SIZE ; i ; i--)
  410. *vwp++ = a;
  411. row = 0;
  412. lcnt = 0;
  413. vp = (FPUCHAR)ScreenStart;
  414. }
  415. // END OF FILE