home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / SRC26_2.ZIP / SRC / PC98.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-13  |  14.4 KB  |  706 lines

  1. /*
  2. ** pc98.c: hterm NEC PC98xx physical CRT driver and bell driver
  3.  *
  4.  * Author: HIRANO Satoshi
  5.  * (C) 1989  Halca Computer Science Laboratory TM
  6.  *           University of Tokyo
  7.  *
  8.  * 1.1 89/06/15 Halca.Hirano creation
  9.  * 1.2 89/07/20 Halca.Hirano add many features
  10.  *    use generic memory move functions to access VRAM
  11.  *    ---- V2.3.-1 distribution ----
  12.  *    ---- V2.4.0 distribution ----
  13.  *  ---- V2.5.0 distribution ----
  14.  * 1.3 89/11/29 Halca.Hirano visible/audible/both bell mode
  15.  * 1.4 89/12/24 Halca.Hirano add nullFunction() to avoid optimizer bug
  16.  *    in bell() wait loop
  17.  * 1.5 90/04/20 Halca.Hirano access VRAM thru addressing array
  18.  *        remember function key display status at startup
  19.  * 1.6 90/06/19 Halca.Hirano 
  20.  *        support soft font
  21.  * 1.7 90/07/07 Halca.Hirano
  22.  *    turn back light on/off when textCRTOn/Off for PC9801NS
  23.  *
  24.  * $Header: pc98.cv  1.11  90/07/05 08:37:26  hirano  Exp $
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include "config.h"
  29. #include "hterm.h"
  30. #include "option.h"
  31. #include "default.h"
  32. #include "global.h"
  33.  
  34.  
  35. /*
  36. ** static variables
  37.  */
  38.  
  39. /*
  40.  * physical line number VRAM address convertion table
  41.  * index = physical line number
  42.  * contents = VRAM address
  43.  */
  44. static u_short *ltopTab[MAX_LINE_25_MODE];
  45. /*
  46.  * logical line number to VRAM address conversion function
  47.  */
  48. #define ltop(y) (ltopTab[y])
  49.  
  50. static short backingStoreSeg;        /* soft font backing store        */
  51. static char FAR *backingStore;        /* pointer to backing store        */
  52. static void reverseScreen(void);
  53.  
  54. /*
  55. ** void CRTInit(): initialize PC98 CRT
  56.  *
  57.  * called once just after hterm startup
  58.  */
  59. void CRTInit()
  60. {
  61.     register int i;
  62.     register u_short *p;
  63.     u_short FAR *v;
  64.  
  65.     vramSegment = VRAMSEG;
  66.     gvramSegment = GVRAMSEG;
  67. #ifdef SOFT_FONT
  68.     /*
  69.      * allocate memory for VRAM backing store
  70.      */
  71.     backingStore = allocMem((long)(ATTR_OFFSET*2));
  72.     if (backingStore == 0) {
  73.         fprintf(stderr, msg_alloc, "backing store\n");
  74.         exit(1);
  75.     }
  76.     backingStoreSeg = FP_SEG(backingStore);
  77. #endif
  78.     /*
  79.      *    build line number conversion table
  80.      */
  81.     p = (u_short *)0;
  82.     for (i = 0; i < MAX_LINE_25_MODE; i++) {
  83.         /* physical line no to VRAM address conversion table */
  84.         ltopTab[i] = p;
  85.         p += MAX_COLUMN;
  86.     }
  87.     /*
  88.      * remember function key is displayed or not
  89.      * (it may not be so strict)
  90.      */
  91.     FP_SEG(v) = vramSegment;
  92.     FP_OFF(v) = (int)ltop(BOTTOM_LINE_25_MODE);
  93.     funKeyDisplayed = NO;
  94.     for (i = 0; i < 20; i++, v++)
  95.         if (*v != 0 && *v != 0x20) {
  96.             funKeyDisplayed = YES;
  97.             break;
  98.         }
  99.     printf("\x1b[>1h");            /* clear funktion key line        */
  100. }
  101.  
  102. /*
  103. ** void CRTEnd()
  104.  */
  105. void CRTEnd()
  106. {
  107.     upScrRegion = 0;
  108.     lowScrRegion = BOTTOM_LINE_25_MODE;
  109. #ifdef SOFT_FONT
  110.     freeMem(backingStore);
  111.     if (softFont) {                    /* erase graphic screen        */
  112.         clearCurrentPage();
  113.         cursorOnOff(NO);
  114.         softFont = NO;
  115.     }
  116. #endif /* SOFT_FONT */
  117.     restoreCRTMode();
  118. }
  119.  
  120. /*
  121. ** void setCRTMode()
  122.  *
  123.  * set CRT mode
  124.  */
  125. void setCRTMode()
  126. {
  127.     /*
  128.      * set crt mode (25/20 lines)
  129.      */
  130.     setCRTLineMode(realMaxLine < 21 ? 0 : 1);    /* 20 or 25 line mode    */
  131.     /*
  132.      * set CRT mode
  133.      */
  134. #ifdef SOFT_FONT
  135.     if (softFont) {
  136.         /*
  137.          * make text CRT tranparent overlay
  138.          *    erase text cursor
  139.          */
  140.         softFont = NO;
  141.         cursorOnOff(NO);
  142.         clearCurrentPage();
  143.         /*
  144.          * fake text VRAM dummy at vramBacking store
  145.          */
  146.         vramSegment = backingStoreSeg;
  147.         clearCurrentPage();        /* clear backing store    */
  148.         softFont = YES;
  149. #ifndef PC98XA
  150.         /*
  151.          * set graphic mode, color 640x400
  152.          */
  153.         rg.h.ah = 0x42;
  154.         rg.h.ch = 0xc0 ;        /* color, 640x400, use page 1 */
  155.         int86(CRTBIOS, &rg, &rg);
  156.         /*
  157.          * set color palette; blue plane displays white color
  158.          */
  159.         outp(0xaa, 0x75);
  160. #endif        
  161.     } else 
  162. #endif /* SOFT_FONT */
  163.     {
  164.         vramSegment = VRAMSEG;
  165. #ifndef PC98XA
  166.         /*
  167.          * set graphic mode
  168.          */
  169.         rg.h.ah = 0x42;
  170.         rg.h.ch = 0xc0;        /* color, 640x400, use page 1 */
  171.         int86(CRTBIOS, &rg, &rg);
  172.         /*
  173.          * set color palette; blue plane displays blue color
  174.          */
  175.         outp(0xaa, 0x15);
  176. #endif        
  177.     }
  178.     graphicCRTOnOff(YES);
  179. }
  180.  
  181. /*
  182. ** void restoreCRTMode()
  183.  *
  184.  * restore CRT mode to startup condition
  185.  */
  186. void restoreCRTMode()
  187. {
  188.     eraseAttr = attrib = _NORMAL;
  189.     softFont = NO;
  190.     setCRTMode();        /* MSDOS CRT mode is same as hterm's TEXT mode    */
  191.     setCRTLineMode(1);    /* 25 line mode    */
  192.     clearCurrentPage();
  193.     cursorOnOff(YES);
  194.     if (funKeyDisplayed)
  195.         printf("\x1b[>1l");
  196.     setBorder(0);
  197. }
  198.         
  199. /*
  200. ** void locate(register int x, int y)
  201.  *
  202.  * set cursor on position (x,y)
  203.  */
  204. void locate(x, y)
  205. register int x;
  206. int y;
  207. {
  208.     register u_short *ad;
  209.  
  210.     cursorX = x;
  211.     cursorY = y;
  212.     if (cursor) {
  213. #ifdef SOFT_FONT
  214.         if (softFont) {
  215.             softFontLocate(x, y);
  216.         } else
  217. #endif
  218.         {
  219.             ad = ltop(y) + x;
  220.             rg.h.ah = 0x13;            /* cursor position command    */
  221.             rg.x.dx = (int)ad;
  222.             int86(CRTBIOS, &rg, &rg);    /* call CRT BIOS        */
  223.         }
  224.     }
  225. }
  226.  
  227. /*
  228. ** int isKanjiOnVRAM(x, y)
  229.  *
  230.  * return non zero if the character is kanji at current cursor position
  231.  */
  232. int isKanjiOnVRAM(x, y)
  233. int x;
  234. int y;
  235. {
  236.     u_short FAR *p;
  237.  
  238.     FP_SEG(p) = vramSegment;
  239.     FP_OFF(p) = (int)(ltop(y) + x);
  240.     return((*p & 0xff00) && (*(p+1) & 0x8000));
  241. }
  242.  
  243. /*
  244. ** void cursorOnOff(int onOff)
  245.  *
  246.  * set cursor form; on/off, blinking/static, underline/block
  247.  */
  248. void cursorOnOff(onOff)
  249. int onOff;
  250. {
  251. #ifdef SOFT_FONT
  252.     if (softFont) {
  253.         softCursorOnOff(onOff);
  254.     } else
  255. #endif
  256.     {
  257.         rg.h.al = (blinkCursor == YES ? 0 : 1);
  258.         rg.h.ah = 0x10;
  259.         int86(CRTBIOS, &rg, &rg);
  260.         rg.h.ah = (onOff == YES ? 0x11 : 0x12);
  261.         int86(CRTBIOS, &rg, &rg);
  262.     }
  263. }
  264.  
  265. /*
  266. ** void putChar(register u_short c)
  267.  *
  268.  * put a charactor 'c' and attribute 'attrib' at (cursorX, cursorY)
  269.  */
  270. void putChar(c)
  271. register u_short c;
  272. {
  273.     u_short FAR *p;
  274.  
  275.     FP_SEG(p) = vramSegment;
  276.     FP_OFF(p) = (int)(ltop(cursorY) + cursorX);
  277.     *p = c;
  278.     FP_OFF(p) += ATTR_OFFSET;
  279.     *p = attrib;
  280. }
  281.  
  282. /*
  283. ** void insertLine(register u_short num)
  284.  *
  285.  * insert num lines at cursorY
  286.  *
  287.  * If cursorY is not in scroll region, ignore request
  288.  * If num exceeds scroll region, strict num into scroll region
  289.  *
  290.  */
  291. void insertLine(num)
  292. register int num;
  293. {
  294.     /*
  295.      * if cursor is out of scroll region or zero request, ignore request
  296.      */
  297.     if (cursorY < upScrRegion || cursorY > lowScrRegion || num == 0)
  298.         return;                            /* ignore                    */
  299.     if (softFont && cursor)
  300.         cursorOnOff(NO);
  301.     /*
  302.      * requested num must be in scroll region
  303.      */
  304.     if (lowScrRegion+1-cursorY < num)
  305.         num = lowScrRegion+1-cursorY;    /* out of scroll region        */
  306.     /* moveBackward(to, from, num, MOVE_ATTRIBUTE_TOO) */
  307.     moveBackward(ltop(cursorY+num), ltop(cursorY),
  308.             (lowScrRegion+1-cursorY-num) * MAX_COLUMN, YES);
  309. #ifdef SOFT_FONT
  310.     if (softFont) {
  311.         softFontInsertLine(num);
  312.         if (cursor)
  313.             cursorOnOff(YES);
  314.     }
  315. #endif
  316.     /*
  317.      * clear created lines
  318.      */
  319.     clearLine(cursorY, cursorY+num-1);
  320. }
  321.  
  322. /*
  323. ** void deleteLine(register u_short num)
  324.  *
  325.  * delete num lines at cursorY
  326.  *
  327.  * If cursorY is not in scroll region, ignore request
  328.  * If num exceeds scroll region, strict num into scroll region
  329.  *
  330.  */
  331. void deleteLine(num)
  332. register int num;
  333. {
  334.     /*
  335.      * if cursor is out of scroll region or zero request, ignore request
  336.      */
  337.     if (cursorY < upScrRegion || cursorY > lowScrRegion || num == 0)
  338.         return;                            /* ignore                    */
  339.     if (softFont && cursor)
  340.         cursorOnOff(NO);
  341.     /*
  342.      * requested num must be in scroll region
  343.      */
  344.     if (lowScrRegion+1-cursorY < num)
  345.         num = lowScrRegion+1-cursorY;    /* out of scroll region        */
  346.     /* moveForward(to, from, num, MOVE_ATTRIBUTE_TOO) */
  347.     moveForward(ltop(cursorY), ltop(cursorY+num),
  348.             (lowScrRegion+1-cursorY-num)*MAX_COLUMN, YES);
  349. #ifdef SOFT_FONT
  350.     if (softFont) {
  351.         softFontDeleteLine(num);
  352.         if (cursor)
  353.             cursorOnOff(YES);
  354.     }
  355. #endif
  356.     /*
  357.      * clear created lines
  358.      */
  359.     clearLine(lowScrRegion-num+1, lowScrRegion);
  360. }
  361.  
  362. /*
  363. ** void clearColumn(register u_shrot from, register u_short to)
  364.  *
  365.  * clear column 'from' to 'to'-1 on cursorY line, 
  366.  */
  367. void clearColumn(from, to)
  368. register u_short from, to;
  369. {
  370.     if (to > from) {
  371.         if (softFont && cursor)
  372.             cursorOnOff(NO);
  373.         fillVRAM(ltop(cursorY)+from, to-from, SPACE, eraseAttr);
  374. #ifdef SOFT_FONT
  375.         if (softFont) {
  376.             softFontClearColumn(from, to);
  377.             if (cursor)
  378.                 cursorOnOff(YES);
  379.         }
  380. #endif
  381.     }
  382. }
  383.  
  384. /*
  385. ** void clearCurrentPage()
  386.  *
  387.  * clear current page
  388.  */
  389. void clearCurrentPage()
  390. {
  391.     clearLine(0, BOTTOM_LINE_25_MODE);
  392. }
  393.  
  394. /*
  395. ** void insertChar(register u_short at, u_short n)
  396.  *
  397.  * insert n blank charactors at 'at' on cursorY line
  398.  */
  399. void insertChar(at, n)
  400. register int at;
  401. int n;
  402. {
  403.     register u_short *src = ltop(cursorY)+at;
  404.     register int moveNum = MAX_COLUMN-at-n;
  405.  
  406.     if (softFont && cursor)
  407.         cursorOnOff(NO);
  408.     if (moveNum > 0)
  409.         moveBackward(src+n, src, moveNum, YES);
  410.     else
  411.         n = MAX_COLUMN-at;
  412.     fillVRAM(src, n, SPACE, eraseAttr);
  413. #ifdef SOFT_FONT
  414.     if (softFont) {
  415.         softFontInsertChar(at, n);
  416.         if (cursor)
  417.             cursorOnOff(YES);
  418.     }
  419. #endif
  420. }
  421.  
  422. /*
  423. ** void deleteChar(register int at, register int n)
  424.  *
  425.  * delete 'n' characters at 'at' on cursorY line and make blank trailing 'n'
  426.  * characters.
  427.  */
  428. void deleteChar(at, n)
  429. register int at;
  430. register int n;
  431. {
  432.     register u_short *src = ltop(cursorY) + at;
  433.     register int moveNum = MAX_COLUMN-at-n;
  434.  
  435.     if (softFont && cursor)
  436.         cursorOnOff(NO);
  437.     if (moveNum > 0)
  438.         moveForward(src, src+n, moveNum, YES);
  439.     else {
  440.         n = MAX_COLUMN-at;
  441.         moveNum = 0;
  442.     }
  443.     fillVRAM(src+moveNum, n, SPACE, eraseAttr);
  444. #ifdef SOFT_FONT
  445.     if (softFont) {
  446.         softFontDeleteChar(at, n);
  447.         if (cursor)
  448.             cursorOnOff(YES);
  449.     }
  450. #endif
  451. }
  452.  
  453. /*
  454. ** void saveLine(int y, register u_char FAR *buf)
  455.  *
  456.  * copy line y in VRAM into buffer
  457.  * Kanji code is EUC in buffer.
  458.  */
  459. void saveLine(y, buf)
  460. int y;
  461. register u_char FAR *buf;
  462. {
  463.     short FAR *from;
  464.     register u_short c;
  465.     register u_char l;
  466.     register int i;
  467.  
  468.     FP_SEG(from) = vramSegment;
  469.     FP_OFF(from) = (int)ltop(y);
  470.     
  471.     for (i = 0; i < MAX_COLUMN; i++) {
  472.         c = *from++;
  473.         if (c & 0xff00) {    /* kanji */
  474.             l = c;
  475.             *buf++ = (l + 0x20) | 0x80;
  476.             *buf++ = (c >> 8) | 0x80;
  477.             from++;
  478.             i++;
  479.         } else {        /* ASCII    */
  480.             if (c == 0xef || c == 0xfc)    /* back slash */
  481.                 c = 0x5c;
  482.             else if (c == 0xde)        /* backquote */
  483.                 c = 0x60;
  484.             else if (c < 0x20 || 0x7e < c)    /* ignore kana    */
  485.                 c = '?';
  486.             *buf++ = c;
  487.         }
  488.     }
  489. }
  490.  
  491. /*
  492. ** static void reverseScreen()
  493.  *
  494.  * reverse screen
  495.  */
  496. static void reverseScreen()
  497. {
  498.     short FAR *p;
  499.     register u_short c, a;
  500.     int i;
  501.  
  502. #ifdef SOFT_FONT
  503.     if (softFont)
  504.         softFontReverseScreen();
  505.     else 
  506. #endif /* SOFT_FONT */
  507.     {
  508.         FP_SEG(p) = vramSegment;
  509.         FP_OFF(p) = ATTR_OFFSET;
  510.     
  511.         a = 0x0004;
  512.         for (i = MAX_COLUMN*MAX_LINE_25_MODE; i > 0; --i) {
  513.             c = *p;
  514.             *p++ = ((c & ~a) | (~c & a));
  515.         }
  516.     }
  517. }
  518.  
  519. /*
  520. ** void savePage(u_short buf[])
  521.  *
  522.  * save vram into save buffer 'buf' without code conversion
  523.  */
  524. void savePage(buf)
  525. u_short buf[];
  526. {
  527.     /* charactor VARM */
  528.     moveMemory(buf, getDSeg(), (u_short *)0, vramSegment, MAX_CHAR);
  529.     /* attribute VRAM */
  530.     moveMemory(&buf[MAX_CHAR], getDSeg(), (u_short *)ATTR_OFFSET, vramSegment, MAX_CHAR);
  531. }
  532.  
  533. /*
  534. ** void restorePage(u_short buf[])
  535.  *
  536.  * restore saved page into vram 
  537.  */
  538. void restorePage(buf)
  539. u_short buf[];
  540. {
  541.     register u_short c;
  542.     register u_char l;
  543.     u_short *p, *a;
  544.  
  545.     /* character VRAM */
  546.     moveMemory((u_short *)0, vramSegment, buf, getDSeg(), MAX_CHAR);
  547.     /* attribute VRAM */
  548.     moveMemory((u_short *)ATTR_OFFSET, vramSegment, &buf[MAX_CHAR], getDSeg(), MAX_CHAR);
  549.  
  550. #ifdef SOFT_FONT
  551.     if (softFont) {
  552.         int cursorXSave = cursorX;
  553.         int cursorYSave = cursorY;
  554.  
  555.         softCursorOnOff(NO);
  556.         p = buf;            /* char pointer    */
  557.         a = &buf[MAX_CHAR];    /* attrib pointer    */
  558.         for (cursorY = 0; cursorY <= realBottomLine; cursorY++) {
  559.             for (cursorX = 0; cursorX < MAX_COLUMN; cursorX++) {
  560.                 c = *p++;
  561.                 attrib = *a++;
  562.                 if (c & 0xff00) {    /* kanji */
  563.                     l = c;
  564.                     softFontPutChar(((l+0x20) << 8) | (c >> 8));
  565.                     p++;
  566.                     a++;
  567.                     cursorX++;
  568.                 } else {        /* ASCII    */
  569.                     if (c == 0xef || c == 0xfc)    /* back slash */
  570.                         c = 0x5c;
  571.                     else if (c == 0xde)        /* backquote */
  572.                         c = 0x60;
  573.                     else if (c < 0x20 || 0x7e < c)    /* ignore kana    */
  574.                         c = '?';
  575.                     softFontPutChar(c);
  576.                 }
  577.             }
  578.         }
  579.         cursorX = cursorXSave;
  580.         cursorY = cursorYSave;
  581.         if (cursor)
  582.             softCursorOnOff(YES);
  583.     }
  584. #endif /* SOFT_FONT */
  585. }
  586.  
  587. /*
  588. ** void clearSavedPage(u_char buf[])
  589.  *
  590.  * clear saved page 
  591.  */
  592. void clearSavedPage(buf)
  593. u_short buf[];
  594. {
  595.     register int i;
  596.     register u_short *p;
  597.  
  598.     for (p = buf, i = MAX_CHAR; i > 0; --i)
  599.         *p++ = SPACE;
  600.     for (p = &buf[MAX_CHAR], i = MAX_CHAR; i > 0; --i)
  601.         *p++ = eraseAttr;
  602. }
  603.  
  604. /*
  605. ** void click()
  606.  *
  607.  * generate click 'pi' sound
  608.  */
  609. void click()
  610. {
  611.     int i;
  612.  
  613.     outp(PORT_C, 0x06);            /* buzzar on        */
  614.     for (i = 0; i < CLICK_BEEP; i++)
  615.         nullFunction();            /* short wait        */
  616.     outp(PORT_C, 0x07);
  617. }
  618.  
  619. /*
  620.  * void bell()
  621.  *
  622.  * generate beep sound 'pii' with screen flush if required
  623.  */
  624. void bell()
  625. {
  626.     if (visibleBell == AUDIBLE_BELL  || visibleBell == BOTH_AV_BELL)
  627.         outp(PORT_C, 0x06);            /* buzzar on        */
  628.     timerValue = timerLoadValue;
  629.     while (timerLoadValue - timerValue < BELL_BEEP) {
  630.         nullFunction();
  631.         if (visibleBell == VISIBLE_BELL || visibleBell == BOTH_AV_BELL) {
  632.             reverseScreen();
  633.             reverseScreen();
  634.         }
  635.     }
  636.     if (visibleBell == AUDIBLE_BELL  || visibleBell == BOTH_AV_BELL)
  637.         outp(PORT_C, 0x07);            /* buzzar off        */
  638. }
  639.  
  640. /*
  641. ** void textCRTOnOff(int  onOff)
  642.  *
  643.  * display text CRT or hide it
  644.  */
  645. void textCRTOnOff(onOff)
  646. int onOff;
  647. {
  648.     rg.h.ah = (onOff ? 0x0c : 0x0d);
  649.     int86(CRTBIOS, &rg, &rg);
  650.     /*
  651.      * PC9801NS back light control
  652.      */
  653.     if (onOff)
  654.         outp(0xce8e, 0x80);        /* turn back light on    */
  655.     else
  656.         outp(0xce8e, 0x00);        /* turn back light off    */
  657. }
  658.  
  659. /*
  660. ** void graphicCRTOnOff(int  onOff)
  661.  *
  662.  * display graphic CRT or hide it
  663.  */
  664. void graphicCRTOnOff(onOff)
  665. int onOff;
  666. {
  667.     /*
  668.      * show graphic page
  669.      */
  670.     rg.h.ah = onOff ? 0x40 : 0x41;    /* 0x40 = ON, 0x41 = OFF    */
  671.     int86(CRTBIOS, &rg, &rg);
  672. }
  673.  
  674. /*
  675. ** void setCRTLineMode(int mode25)
  676.  *
  677.  * switch 25 lines mode or 20 lines mode
  678.  */
  679. void setCRTLineMode(mode25)
  680. int mode25;        /* 1 = 25 lines mode, 0 = 20 lines mode     */
  681. {
  682. #ifndef PC98XA
  683.     /* PC98XA does not support 20 line mode */
  684.     rg.h.ah = 0x0a;
  685.     rg.h.al = (mode25 ? 0 : 1);
  686.     int86(CRTBIOS, &rg, &rg);
  687. #endif
  688. }
  689.  
  690. /*
  691. ** setBorder(int col)
  692.  *
  693.  * void set border coloer to col
  694.  */
  695. void setBorder(col)
  696. int col;
  697. {
  698.     static char     ucw[2];            /* UCW                        */
  699.  
  700.     ucw[1] = col;            /* color code                */
  701.     rg.h.ah = 0x44;            /* set border color command    */
  702.     rg.x.bx = (int)ucw;
  703.     int86(CRTBIOS, &rg, &rg);
  704. }
  705.  
  706.