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.

783 lines
11 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 "hwdetect.h"
  18. #if defined(_IA64_)
  19. #undef DBG
  20. #endif
  21. #if DBG
  22. #define ZLEN_SHORT(x) ((x < 0x10) + (x < 0x100) + (x < 0x1000))
  23. #define ZLEN_LONG(x) ((x < 0x10) + (x < 0x100) + (x < 0x1000) + (x < 0x10000) + (x < 0x100000)+(x < 0x1000000)+(x < 0x10000000))
  24. #define ROWS 25
  25. #define COLUMNS 80
  26. #define SCREEN_WIDTH COLUMNS
  27. #define SCREEN_SIZE ROWS * COLUMNS
  28. #if defined(NEC_98)
  29. #define NORMAL_ATTRIB 0xe1
  30. #define REVERSE_ATTRIB 0xe5
  31. #define SCREEN_START 0xa0000
  32. #define ATTROFFSET98 0x2000
  33. #else // PC98
  34. #define NORMAL_ATTRIB 0x07
  35. #define REVERSE_ATTRIB 0x70
  36. #define SCREEN_START 0xb8000
  37. #endif // PC98
  38. #if defined(NEC_98)
  39. #define IsANK(c) (!((c >= (UCHAR)0x81 && c <= (UCHAR)0x9f) || (c >= (UCHAR)0xe0 && c <= (UCHAR)0xfe)))
  40. static BOOLEAN IsKanji2nd = FALSE;
  41. static UCHAR Kanji1st;
  42. static int z = 25;
  43. USHORT
  44. HwGetKey(
  45. VOID
  46. );
  47. #endif // PC98
  48. //
  49. // Internal routines
  50. //
  51. VOID
  52. putc(
  53. IN CHAR
  54. );
  55. VOID
  56. putu(
  57. IN ULONG
  58. );
  59. VOID
  60. BlPuts(
  61. IN PCHAR
  62. );
  63. VOID
  64. puti(
  65. IN LONG
  66. );
  67. VOID
  68. putx(
  69. IN ULONG
  70. );
  71. VOID
  72. scroll(
  73. VOID
  74. );
  75. static
  76. VOID
  77. tab(
  78. VOID
  79. );
  80. static
  81. VOID
  82. newline(
  83. VOID
  84. );
  85. static
  86. VOID
  87. putzeros(
  88. USHORT,
  89. USHORT
  90. );
  91. USHORT
  92. Redirect = 0;
  93. //
  94. // Used by all BlPrint subordinate routines for padding computations.
  95. //
  96. CHAR sc=0;
  97. ULONG fw=0;
  98. VOID
  99. BlPrint(
  100. PCHAR cp,
  101. ...
  102. )
  103. /*++
  104. Routine Description:
  105. Standard printf function with a subset of formating features supported.
  106. Currently handles
  107. %d, %ld - signed short, signed long
  108. %u, %lu - unsigned short, unsigned long
  109. %c, %s - character, string
  110. %x, %lx - unsigned print in hex, unsigned long print in hex
  111. Does not do:
  112. - field width specification
  113. - floating point.
  114. Arguments:
  115. cp - pointer to the format string, text string.
  116. Returns:
  117. Nothing
  118. --*/
  119. {
  120. USHORT b,c,w,len;
  121. PUCHAR ap;
  122. ULONG l;
  123. //
  124. // Cast a pointer to the first word on the stack
  125. //
  126. ap = (PUCHAR)&cp + sizeof(PCHAR);
  127. sc = ' '; // default padding char is space
  128. //
  129. // Process the arguments using the descriptor string
  130. //
  131. while (b = *cp++)
  132. {
  133. if (b == '%')
  134. {
  135. c = *cp++;
  136. switch (c)
  137. {
  138. case 'd':
  139. puti((long)*((int *)ap));
  140. ap += sizeof(int);
  141. break;
  142. case 's':
  143. BlPuts(*((PCHAR *)ap));
  144. ap += sizeof (char *);
  145. break;
  146. case 'c':
  147. putc(*((char *)ap));
  148. ap += sizeof(int);
  149. break;
  150. case 'x':
  151. w = *((USHORT *)ap);
  152. len = ZLEN_SHORT(w);
  153. while(len--) putc('0');
  154. putx((ULONG)*((USHORT *)ap));
  155. ap += sizeof(int);
  156. break;
  157. case 'u':
  158. putu((ULONG)*((USHORT *)ap));
  159. ap += sizeof(int);
  160. break;
  161. case 'l':
  162. c = *cp++;
  163. switch(c) {
  164. case 'u':
  165. putu(*((ULONG *)ap));
  166. ap += sizeof(long);
  167. break;
  168. case 'x':
  169. l = *((ULONG *)ap);
  170. len = ZLEN_LONG(l);
  171. while(len--) putc('0');
  172. putx(*((ULONG *)ap));
  173. ap += sizeof(long);
  174. break;
  175. case 'd':
  176. puti(*((ULONG *)ap));
  177. ap += sizeof(long);
  178. break;
  179. }
  180. break;
  181. default :
  182. putc((char)b);
  183. putc((char)c);
  184. }
  185. }
  186. else
  187. putc((char)b);
  188. }
  189. }
  190. FPUCHAR vp = (FPUCHAR)SCREEN_START;
  191. FPUCHAR ScreenStart = (FPUCHAR)SCREEN_START;
  192. static int lcnt = 0;
  193. static int row = 0;
  194. VOID BlPuts(
  195. PCHAR cp
  196. )
  197. /*++
  198. Routine Description:
  199. Writes a string on the display at the current cursor position
  200. Arguments:
  201. cp - pointer to ASCIIZ string to display.
  202. Returns:
  203. Nothing
  204. --*/
  205. {
  206. char c;
  207. while(c = *cp++)
  208. putc(c);
  209. }
  210. //
  211. // Write a hex short to display
  212. //
  213. VOID putx(
  214. ULONG x
  215. )
  216. /*++
  217. Routine Description:
  218. Writes hex long to the display at the current cursor position.
  219. Arguments:
  220. x - ulong to write.
  221. Returns:
  222. Nothing
  223. --*/
  224. {
  225. ULONG j;
  226. if (x/16)
  227. putx(x/16);
  228. if((j=x%16) > 9) {
  229. putc((char)(j+'A'- 10));
  230. } else {
  231. putc((char)(j+'0'));
  232. }
  233. }
  234. VOID puti(
  235. LONG i
  236. )
  237. /*++
  238. Routine Description:
  239. Writes a long integer on the display at the current cursor position.
  240. Arguments:
  241. i - the integer to write to the display.
  242. Returns:
  243. Nothing
  244. --*/
  245. {
  246. if (i<0)
  247. {
  248. i = -i;
  249. putc((char)'-');
  250. }
  251. if (i/10)
  252. puti(i/10);
  253. putc((char)((i%10)+'0'));
  254. }
  255. VOID putu(
  256. ULONG u
  257. )
  258. /*++
  259. Routine Description:
  260. Write an unsigned long to display
  261. Arguments:
  262. u - unsigned
  263. --*/
  264. {
  265. if (u/10)
  266. putu(u/10);
  267. putc((char)((u%10)+'0'));
  268. }
  269. VOID putc(
  270. CHAR c
  271. )
  272. /*++
  273. Routine Description:
  274. Writes a character on the display at the current position.
  275. Arguments:
  276. c - character to write
  277. Returns:
  278. Nothing
  279. --*/
  280. {
  281. switch (c)
  282. {
  283. case '\n':
  284. newline();
  285. break;
  286. case '\t':
  287. tab();
  288. break;
  289. default :
  290. if (FP_OFF(vp) >= (SCREEN_SIZE * 2)) {
  291. vp = (FPUCHAR)((ScreenStart + (2*SCREEN_WIDTH*(ROWS-1))));
  292. #if defined(NEC_98)
  293. if ( z == 25 ){
  294. HwGetKey();
  295. z = 0;
  296. }
  297. #endif // PC98
  298. scroll();
  299. #if defined(NEC_98)
  300. z++;
  301. #endif // PC98
  302. }
  303. #if defined(NEC_98)
  304. if(IsKanji2nd) {
  305. IsKanji2nd = FALSE;
  306. // Shift JIS -> JIS code exchange
  307. Kanji1st -= (UCHAR)((Kanji1st <= (UCHAR)0x9f) ? 0x71 : 0xb1);
  308. Kanji1st = Kanji1st * 2 + 1;
  309. if((UCHAR)c > (UCHAR)0x7f){
  310. c--;
  311. }
  312. if((UCHAR)c >= (UCHAR)0x9e){
  313. c -= 0x7d;
  314. Kanji1st++;
  315. }else{
  316. c -= 0x1f;
  317. }
  318. // Create custom JIS code (to VRAM)
  319. Kanji1st += 0x60;
  320. *vp++ = Kanji1st - (CHAR)0x80;
  321. *vp++ = c;
  322. *vp++ = Kanji1st;
  323. *vp++ = c;
  324. lcnt +=2;
  325. Kanji1st = (UCHAR)0;
  326. } else if(!IsANK((UCHAR)c)) {
  327. IsKanji2nd = TRUE;
  328. Kanji1st = (UCHAR)c;
  329. } else {
  330. *vp++ = c;
  331. *vp++ = 0;
  332. ++lcnt;
  333. }
  334. #else // PC98
  335. *vp = c;
  336. vp += 2;
  337. ++lcnt;
  338. #endif // PC98
  339. }
  340. }
  341. VOID newline(
  342. VOID
  343. )
  344. /*++
  345. Routine Description:
  346. Moves the cursor to the beginning of the next line. If the bottom
  347. of the display has been reached, the screen is scrolled one line up.
  348. Arguments:
  349. None
  350. Returns:
  351. Nothing
  352. --*/
  353. {
  354. vp += (SCREEN_WIDTH - lcnt)<<1;
  355. if (++row > ROWS-1) {
  356. vp = (FPUCHAR)((ScreenStart + (2*SCREEN_WIDTH*(ROWS-1))));
  357. scroll();
  358. }
  359. lcnt = 0;
  360. }
  361. VOID scroll(
  362. VOID
  363. )
  364. /*++
  365. Routine Description:
  366. Scrolls the display UP one line.
  367. Arguments:
  368. None
  369. Returns:
  370. Nothing
  371. Notes:
  372. Currently we scroll the display by reading and writing directly from
  373. and to the video display buffer. We optionally switch to real mode
  374. and to int 10s
  375. --*/
  376. {
  377. USHORT i,j;
  378. USHORT far *p1 = (USHORT far *)ScreenStart;
  379. USHORT far *p2 = (USHORT far *)(ScreenStart + 2*SCREEN_WIDTH) ;
  380. #if defined(NEC_98)
  381. for (i=0; i < ROWS - 1; i++)
  382. for (j=0; j < SCREEN_WIDTH; j++)
  383. {
  384. *(p1+ATTROFFSET98) = *(p2+ATTROFFSET98);
  385. *p1++ = *p2++;
  386. }
  387. for (i=0; i < SCREEN_WIDTH; i++) {
  388. *(p1+ATTROFFSET98) = REVERSE_ATTRIB;
  389. *p1++ = 0 + ' '; // No KANJI support
  390. }
  391. #else // PC98
  392. for (i=0; i < ROWS - 1; i++)
  393. for (j=0; j < SCREEN_WIDTH; j++)
  394. *p1++ = *p2++;
  395. for (i=0; i < SCREEN_WIDTH; i++)
  396. *p1++ = REVERSE_ATTRIB*256 + ' ';
  397. #endif // PC98
  398. }
  399. static
  400. VOID tab(
  401. VOID
  402. )
  403. /*++
  404. Routine Description:
  405. Computes the next tab stop and moves the cursor to that location.
  406. Arguments:
  407. None
  408. Returns:
  409. Nothing
  410. --*/
  411. {
  412. int inc;
  413. inc = 8 - (lcnt % 8);
  414. vp += inc<<1;
  415. lcnt += inc;
  416. }
  417. VOID clrscrn(
  418. VOID
  419. )
  420. /*++
  421. Routine Description:
  422. Clears the video display by writing blanks with the current
  423. video attribute over the entire display.
  424. Arguments:
  425. None
  426. Returns:
  427. Nothing
  428. --*/
  429. {
  430. #if defined(NEC_98)
  431. int i;
  432. vp = (FPUCHAR)SCREEN_START;
  433. ScreenStart = (FPUCHAR)SCREEN_START;
  434. for (i = SCREEN_SIZE*2 ; i ; i--)
  435. {
  436. *(vp+ATTROFFSET98) = NORMAL_ATTRIB;
  437. *vp++ = 0 + ' ';
  438. *vp++ = 0;
  439. }
  440. #else // PC98
  441. int i,a;
  442. unsigned far *vwp = (unsigned far *)SCREEN_START;
  443. a = REVERSE_ATTRIB*256 + ' ';
  444. for (i = SCREEN_SIZE ; i ; i--)
  445. *vwp++ = a;
  446. #endif // PC98
  447. row = 0;
  448. lcnt = 0;
  449. vp = (FPUCHAR)ScreenStart;
  450. }
  451. #else
  452. VOID
  453. BlPrint(
  454. PCHAR cp,
  455. ...
  456. )
  457. /*++
  458. Routine Description:
  459. Standard printf function with a subset of formating features supported.
  460. Currently handles
  461. %d, %ld - signed short, signed long
  462. %u, %lu - unsigned short, unsigned long
  463. %c, %s - character, string
  464. %x, %lx - unsigned print in hex, unsigned long print in hex
  465. Does not do:
  466. - field width specification
  467. - floating point.
  468. Arguments:
  469. cp - pointer to the format string, text string.
  470. Returns:
  471. Nothing
  472. --*/
  473. {
  474. }
  475. VOID clrscrn(
  476. VOID
  477. )
  478. /*++
  479. Routine Description:
  480. Clears the video display by writing blanks with the current
  481. video attribute over the entire display.
  482. Arguments:
  483. None
  484. Returns:
  485. Nothing
  486. --*/
  487. {
  488. }
  489. #endif
  490. #if defined(NEC_98)
  491. VOID CursorOn(
  492. VOID
  493. )
  494. /*++
  495. Routine Description:
  496. Arguments:
  497. None
  498. Returns:
  499. Nothing
  500. --*/
  501. {
  502. _asm {
  503. mov ah,11h
  504. int 18h
  505. }
  506. }
  507. VOID CursorOff(
  508. VOID
  509. )
  510. /*++
  511. Routine Description:
  512. Arguments:
  513. None
  514. Returns:
  515. Nothing
  516. --*/
  517. {
  518. _asm {
  519. mov ah,12h
  520. int 18h
  521. }
  522. }
  523. #endif // PC98