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.

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