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

  1. /*
  2.  * ibmpc.c: hterm CRT driver (IBM-PC or AX1/AX2 dependent)
  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/07 Halca.Hirano use 98 compatible vram control procedures
  10.  *                (VRAM direct access)
  11.  * 1.3 89/07/20 Halca.Hirano add screen saver
  12.  * 1.4 89/07/30 Halca.Hirano add history editor related functions
  13.  *    remove BIOS call video access
  14.  *    ---- V2.3.-1 distribution ----
  15.  *  ---- V2.4.0 distribution ----
  16.  *  ---- V2.5.0 distribution ----
  17.  * 1.5 89/11/29 Halca.Hirano visible/audible/both bell mode
  18.  * 1.6 89/12/24 Halca.Hirano add nullFunction() to avoid optimizer bug 
  19.  *    in bell() wait loop
  20.  * 1.7 90/04/20 Halca.Hirano access VRAM thru addressing array
  21.  * 1.8 90/06/19 Halca.Hirano 
  22.  *        support soft font
  23.  * 1.9 90/07/07 Halca.Hirano
  24.  *    fix hanging up of AX soft font
  25.  *
  26.  * $Header: ibmpc.cv  1.10  90/07/05 08:37:26  hirano  Exp $
  27.  *
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include "config.h"
  32. #include "hterm.h"
  33. #include "option.h"
  34. #include "default.h"
  35. #include "global.h"
  36.  
  37.  
  38. /*
  39.  * physical line number VRAM address convertion table
  40.  * index = physical line number
  41.  * contents = VRAM address
  42.  */
  43. static u_short *ltopTab[MAX_LINE_25_MODE];
  44. /*
  45.  * logical line number to VRAM address conversion function
  46.  */
  47. #define ltop(y) (ltopTab[y])
  48.  
  49. struct _videoInfo {
  50.     char card[6];
  51.     u_short address;
  52. } videoInfo[] =
  53.     {{"JEGA", VRAM_EGA}, {"VGA", VRAM_VGA}, {"EGA", VRAM_EGA}, 
  54.     {"CGA", VRAM_CGA}, {"MDA", VRAM_MDA}, {"MCGA", VRAM_MCGA}, {0, 0}};
  55.  
  56. static short vramSegmentSave;        /* text move VRAM segment        */
  57. static u_char savedVideoMode;        /* video mode at start up        */
  58. static short backingStoreSeg;        /* soft font backing store        */
  59. static char FAR *backingStore;        /* pointer to backing store        */
  60.  
  61. void reverseScreen(void );
  62.  
  63. /*
  64. ** CRTInit(): initialize PC98 CRT
  65.  *
  66.  * called once just after hterm startup
  67.  */
  68. void CRTInit()
  69. {
  70.     register int i;
  71.     register u_short *p;
  72.     register struct _videoInfo *v;
  73.     
  74.     /*
  75.      *    build line number conversion table
  76.      */
  77.     p = (u_short *)0;
  78.     for (i = 0; i < MAX_LINE_25_MODE; i++) {
  79.         /* physical line no to VRAM address convertion table */
  80.         ltopTab[i] = p;
  81.         p += MAX_COLUMN;
  82.     }
  83.  
  84. #ifdef SOFT_FONT
  85.     /*
  86.      * allocate memory for VRAM backing store
  87.      */
  88.     backingStore = allocMem((long)MAX_CHAR*sizeof(short));
  89.     if (backingStore == 0) {
  90.         fprintf(stderr, msg_alloc, "backing store\n");
  91.         exit(1);
  92.     }
  93.     backingStoreSeg = FP_SEG(backingStore);
  94. #endif
  95.  
  96.     /*
  97.      * get VRAM address
  98.      */
  99. #ifdef AX
  100.     vramSegmentSave = vramSegment = VRAM_EGA;
  101.     gvramSegment = GVRAMSEG;
  102. #else /* AX */
  103.     vramSegmentSave = vramSegment = DEFAULT_VRAM_CARD;    /* set default    */
  104.     gvramSegment = GVRAMSEG;
  105.     for (v = videoInfo; *v->card; v++) {
  106.         if (getenv(v->card)) {
  107.             vramSegment = v->address;
  108.             break;
  109.         }
  110.     }
  111. #endif /* AX */
  112.     /*
  113.      * get VIDEO mode (TEXT mode is assumed.)
  114.      */
  115.     rg.h.ah = 0x0f;                /* get video mode command    */
  116.     int86(VIDEOBIOS, &rg, &rg);
  117.     savedVideoMode = rg.h.al;    /* save current mode        */
  118. }
  119.  
  120. /*
  121. ** CRTEnd()
  122.  */
  123. void CRTEnd()
  124. {
  125.     upScrRegion = 0;
  126.     lowScrRegion = BOTTOM_LINE_25_MODE;
  127. #ifdef SOFT_FONT
  128.     freeMem(backingStore);
  129.     if (softFont) {                    /* erase graphic screen        */
  130.         clearCurrentPage();
  131.         cursorOnOff(NO);
  132.         softFont = NO;
  133.     }
  134. #endif /* SOFT_FONT */
  135.     restoreCRTMode();
  136. }
  137.  
  138. /*
  139. ** setCRTMode()
  140.  *
  141.  * set CRT mode
  142.  */
  143. void setCRTMode()
  144. {
  145.     register int i;
  146.     u_short FAR *p;
  147.  
  148.     /*
  149.      * set CRT mode
  150.      */
  151. #ifdef SOFT_FONT
  152.     if (softFont) {
  153.         /*
  154.          *    erase text cursor and text VRAM
  155.          */
  156.         softFont = NO;
  157.         cursorOnOff(NO);
  158.         clearCurrentPage();
  159.         softFont = YES;
  160.         /*
  161.          * fake text VRAM dummy at vramBacking store
  162.          */
  163.         vramSegment = backingStoreSeg;
  164.         /*
  165.          * clear backing store    
  166.          */
  167.         FP_SEG(p) = vramSegment;
  168.         FP_OFF(p) = 0;
  169.         for (i = MAX_CHAR; i > 0; --i)
  170.             *p++ = (u_short)((eraseAttr<<8) | SPACE);
  171.         /*
  172.          * set GRAPHIC mode
  173.          */
  174.         rg.h.ah = 0;                /* set video mode command    */
  175.         rg.h.al = 0x10;                /* mono 640x350                */
  176.         int86(VIDEOBIOS, &rg, &rg);
  177.     } else 
  178. #endif /* SOFT_FONT */
  179.     {
  180.         /*
  181.          * set TEXT mode
  182.          */
  183.         rg.h.ah = 0;                /* set video mode command    */
  184.         rg.h.al = savedVideoMode;    /* restore mode                */
  185.         int86(VIDEOBIOS, &rg, &rg);
  186.         vramSegment = vramSegmentSave;
  187.     }
  188. }
  189.  
  190. /*
  191. ** restoreCRTMode()
  192.  *
  193.  * restore CRT mode to startup condition
  194.  */
  195. void restoreCRTMode()
  196. {
  197.     eraseAttr = attrib = _NORMAL;
  198.     softFont = NO;
  199.     setCRTMode();        /* MSDOS CRT mode is same as hterm's TEXT mode    */
  200.     clearCurrentPage();
  201.     cursorOnOff(YES);
  202. }
  203.         
  204. /*
  205. ** locate(register int x, int y)
  206.  *
  207.  * set cursor on position (x,y)
  208.  */
  209. void locate(x, y)
  210. register int x, y;
  211. {
  212.     cursorX = x;
  213.     cursorY = y;
  214.     if (cursor) {
  215. #ifdef SOFT_FONT
  216.         if (softFont) {
  217.             softFontLocate(x, y);
  218.         } else
  219. #endif
  220.         {
  221.             rg.h.ah = 2;            /* set cursor position survice code */
  222.             rg.h.bh = 0;            /* page number            */
  223.             rg.h.dh = y;            /* vertical coordinate        */
  224.             rg.h.dl = x;            /* horizontal coordinate    */
  225.              int86(VIDEOBIOS, &rg, &rg);    /* call rom bios        */
  226.         }
  227.     }
  228. }
  229.  
  230. /*
  231. ** isKanjiOnVRAM(x, y)
  232.  *
  233.  * return non zero if the character is kanji at current cursor position
  234.  */
  235. int isKanjiOnVRAM(x, y)
  236. int x;
  237. int y;
  238. {
  239.     u_short FAR *p;
  240.  
  241.     FP_SEG(p) = vramSegment;
  242.     FP_OFF(p) = (int)(ltop(y) + x);
  243.     return(isSJIS1(*p & 0xff));
  244. }
  245.  
  246. /*
  247. ** cursorOnOff(int onOff)
  248.  *
  249.  * set cursor form; on/off, blinking/static, underline/block
  250.  */
  251. void cursorOnOff(onOff)
  252. int onOff;
  253. {
  254. #ifdef SOFT_FONT
  255.     if (softFont) {
  256.         softCursorOnOff(onOff);
  257.     } else
  258. #endif
  259.     {
  260.         rg.h.ah = 1;            /* set cursor type survice code */
  261.         if (onOff == YES)
  262.             if (blockCursor == YES) /* block cursor on        */
  263.                 rg.x.cx = 0x0007;
  264.             else            /* underline cursor on        */
  265.                 rg.x.cx = 0x0607;
  266.         else
  267.             rg.x.cx = 0x2000;    /* cursor off            */
  268.         int86(0x10, &rg, &rg);
  269.     }
  270. }
  271.  
  272. /*
  273. ** putChar(register u_short c)
  274.  *
  275.  * put a charactor 'c' and attribute 'attrib' at (cursorX, cursorY)
  276.  */
  277. void putChar(c)
  278. u_short c;
  279. {
  280.     u_short FAR *p;
  281.  
  282.     FP_SEG(p) = vramSegment;
  283.     FP_OFF(p) = (int)(ltop(cursorY) + cursorX);
  284.     *p = (attrib << 8 | (u_char)c);
  285. }
  286.  
  287. /*
  288. ** insertLine(register u_short num)
  289.  *
  290.  * insert num lines at cursorY
  291.  *
  292.  * If cursorY is not in scroll region, ignore request
  293.  * If num exceeds scroll region, strict num into scroll region
  294.  *
  295.  */
  296. void insertLine(num)
  297. register int num;
  298. {
  299.     /*
  300.      * if cursor is out of scroll region or zero request, ignore request
  301.      */
  302.     if (cursorY < upScrRegion || cursorY > lowScrRegion || num == 0)
  303.         return;                            /* ignore                    */
  304.     if (softFont && cursor)
  305.         cursorOnOff(NO);
  306.     /*
  307.      * requested num must be in scroll region
  308.      */
  309.     if (lowScrRegion+1-cursorY < num)
  310.         num = lowScrRegion+1-cursorY;    /* out of scroll region        */
  311.     /* moveBackward(to, from, num, MOVE_ATTRIBUTE_TOO) */
  312.     moveBackward(ltop(cursorY+num), ltop(cursorY),
  313.             (lowScrRegion+1-cursorY-num) * MAX_COLUMN, YES);
  314. #ifdef SOFT_FONT
  315.     if (softFont) {
  316.         softFontInsertLine(num);
  317.         if (cursor)
  318.             cursorOnOff(YES);
  319.     }
  320. #endif
  321.     /*
  322.      * clear created lines
  323.      */
  324.     clearLine(cursorY, cursorY+num-1);
  325. }
  326.  
  327. /*
  328. ** deleteLine(register u_short num)
  329.  *
  330.  * delete num lines at cursorY
  331.  *
  332.  * If cursorY is not in scroll region, ignore request
  333.  * If num exceeds scroll region, strict num into scroll region
  334.  *
  335.  */
  336. void deleteLine(num)
  337. register int num;
  338. {
  339.     /*
  340.      * if cursor is out of scroll region or zero request, ignore request
  341.      */
  342.     if (cursorY < upScrRegion || cursorY > lowScrRegion || num == 0)
  343.         return;                            /* ignore                    */
  344.     if (softFont && cursor)
  345.         cursorOnOff(NO);
  346.     /*
  347.      * requested num must be in scroll region
  348.      */
  349.     if (lowScrRegion+1-cursorY < num)
  350.         num = lowScrRegion+1-cursorY;    /* out of scroll region        */
  351.     /* moveForward(to, from, num, MOVE_ATTRIBUTE_TOO) */
  352.     moveForward(ltop(cursorY), ltop(cursorY+num),
  353.             (lowScrRegion+1-cursorY-num)*MAX_COLUMN, YES);
  354. #ifdef SOFT_FONT
  355.     if (softFont) {
  356.         softFontDeleteLine(num);
  357.         if (cursor)
  358.             cursorOnOff(YES);
  359.     }
  360. #endif
  361.     /*
  362.      * clear created lines
  363.      */
  364.     clearLine(lowScrRegion-num+1, lowScrRegion);
  365. }
  366.  
  367. /*
  368. ** clearColumn(register u_shrot from, register u_short to)
  369.  *
  370.  * clear column 'from' to 'to'-1 on cursorY line, 
  371.  */
  372. void clearColumn(from, to)
  373. register u_short from, to;
  374. {
  375.     if (to > from) {
  376.         if (softFont && cursor)
  377.             cursorOnOff(NO);
  378.         fillVRAM(ltop(cursorY)+from, to-from, SPACE, eraseAttr);
  379. #ifdef SOFT_FONT
  380.         if (softFont) {
  381.             softFontClearColumn(from, to);
  382.             if (cursor)
  383.                 cursorOnOff(YES);
  384.         }
  385. #endif
  386.     }
  387. }
  388.  
  389. /*
  390. ** clearCurrentPage()
  391.  *
  392.  * clear current page
  393.  */
  394. void clearCurrentPage()
  395. {
  396.     clearLine(0, BOTTOM_LINE_25_MODE);
  397. }
  398.  
  399. /*
  400. ** insertChar(register int at, int n)
  401.  *
  402.  * insert n blank charactors at 'at' on cursorY line
  403.  */
  404. void insertChar(at, n)
  405. register int at;
  406. register int n;
  407. {
  408.     register u_short *src = ltop(cursorY)+at;
  409.     register int moveNum = MAX_COLUMN-at-n;
  410.  
  411.     if (softFont && cursor)
  412.         cursorOnOff(NO);
  413.     if (moveNum > 0)
  414.         moveBackward(src+n, src, moveNum, YES);
  415.     else
  416.         n = MAX_COLUMN-at;
  417.     fillVRAM(src, n, SPACE, eraseAttr);
  418. #ifdef SOFT_FONT
  419.     if (softFont) {
  420.         softFontInsertChar(at, n);
  421.         if (cursor)
  422.             cursorOnOff(YES);
  423.     }
  424. #endif
  425. }
  426.  
  427. /*
  428. ** deleteChar(register int at, register int n)
  429.  *
  430.  * delete 'n' characters at 'at' on cursorY line and make blank trailing 'n'
  431.  * characters.
  432.  */
  433. void deleteChar(at, n)
  434. register int at;
  435. register int n;
  436. {
  437.     register u_short *src = ltop(cursorY) + at;
  438.     register int moveNum = MAX_COLUMN-at-n;
  439.  
  440.     if (softFont && cursor)
  441.         cursorOnOff(NO);
  442.     if (moveNum > 0)
  443.         moveForward(src, src+n, moveNum, YES);
  444.     else {
  445.         n = MAX_COLUMN-at;
  446.         moveNum = 0;
  447.     }
  448.     fillVRAM(src+moveNum, n, SPACE, eraseAttr);
  449. #ifdef SOFT_FONT
  450.     if (softFont) {
  451.         softFontDeleteChar(at, n);
  452.         if (cursor)
  453.             cursorOnOff(YES);
  454.     }
  455. #endif
  456. }    
  457.  
  458. /*
  459. ** saveLine(int y, register u_char FAR *buf)
  460.  *
  461.  * copy line y in VRAM into buffer
  462.  * Kanji code is EUC in buffer.
  463.  */
  464. void saveLine(y, buf)
  465. int y;
  466. register u_char FAR *buf;
  467. {
  468.     register u_short c;
  469.     short FAR *from;
  470.     register u_char l;
  471.     register int i;
  472.  
  473.     FP_SEG(from) = vramSegment;
  474.     FP_OFF(from) = (int)ltop(y);
  475.  
  476. #ifdef KANJI
  477.     for (i = 0; i < MAX_COLUMN; i++) {
  478.         c = *from++;
  479.         if (c & 0x80) {        /* kanji */
  480.             l = c;
  481.             c = SJIStoJIS(l, *from++ & 0xff) | 0x8080;
  482.             *buf++ = c >> 8;
  483.             *buf++ = c;
  484.             i++;
  485.         } else
  486.             *buf++ = c;
  487.     }
  488. #else
  489.     for (i = 0; i < MAX_COLUMN; i++) {
  490.         *buf++ = (u_char)*from++;
  491.     }
  492. #endif /* KANJI */
  493. }
  494.  
  495. /*
  496. ** static void reverseScreen()
  497.  *
  498.  * reverse screen
  499.  */
  500. static void reverseScreen()
  501. {
  502.     short FAR *p;
  503.     register u_short c;
  504.     int i, j;
  505.  
  506. #ifdef SOFT_FONT
  507.     if (softFont)
  508.         softFontReverseScreen();
  509.     else 
  510. #endif /* SOFT_FONT */
  511.     {
  512.         FP_SEG(p) = vramSegment;
  513.         FP_OFF(p) = 0;
  514.         for (i = MAX_COLUMN*MAX_LINE_25_MODE; i > 0; --i) {
  515.             c = *p;
  516.             *p++ = (c & 0x88ff) | (~c & 0x7700);
  517.         }
  518.     }
  519. }
  520.  
  521. /*
  522. ** savePage(u_short buf[])
  523.  *
  524.  * save vram into save buffer 'buf' without code conversion
  525.  */
  526. void savePage(buf)
  527. u_short *buf;
  528. {
  529.     moveMemory(buf, getDSeg(), (u_short *)0, vramSegment, MAX_CHAR);
  530. }
  531.  
  532. /*
  533. ** restorePage(u_short buf)
  534.  *
  535.  * restore saved page into vram 
  536.  */
  537. void restorePage(buf)
  538. u_short *buf;
  539. {
  540.     register u_short c;
  541.     register u_char l;
  542.     u_short *p;
  543.     int cursorXSave = cursorX;
  544.     int cursorYSave = cursorY;
  545.  
  546.     moveMemory((u_short *)0, vramSegment, buf, getDSeg(), MAX_CHAR);
  547. #ifdef SOFT_FONT
  548.     if (softFont) {
  549.         softCursorOnOff(NO);
  550.         p = buf;            /* char pointer    */
  551.         for (cursorY = 0; cursorY <= realBottomLine; cursorY++) {
  552.             for (cursorX = 0; cursorX < MAX_COLUMN; cursorX++) {
  553.                 c = *p++;            /* get attribute and char    */
  554.                 attrib = (c >> 8);    /* attribute                */
  555.                 c &= 0xff;            /* strip attribute            */
  556.                 if (c & 0x80) {        /* kanji                     */
  557.                     l = c;
  558.                     c = SJIStoJIS(l, *p++ & 0xff);
  559.                     softFontPutChar(c);
  560.                     cursorX++;
  561.                 } else {        /* ASCII    */
  562.                     if (c < 0x20 || 0x7e < c)    /* ignore kana    */
  563.                         c = '?';
  564.                     softFontPutChar(c);
  565.                 }
  566.             }
  567.         }
  568.         cursorX = cursorXSave;
  569.         cursorY = cursorYSave;
  570.         if (cursor)
  571.             softCursorOnOff(YES);
  572.     }
  573. #endif /* SOFT_FONT */
  574. }
  575.  
  576. /*
  577. ** clearSavedPage(u_char buf[])
  578.  *
  579.  * clear saved page 
  580.  */
  581. void clearSavedPage(buf)
  582. u_short *buf;
  583. {
  584.     register int i;
  585.     register u_short *p;
  586.  
  587.     for (p = buf, i = MAX_CHAR; i > 0; --i)
  588.         *p++ = (u_short)((eraseAttr<<8) | SPACE);
  589. }
  590.  
  591. /*
  592. ** click()
  593.  *
  594.  * generate click 'pi' sound
  595.  */
  596. void click()
  597. {
  598.     int i;
  599.     u_char    status;
  600.  
  601.     status = inp(ADDR_BUZZAR);            /* read current status    */
  602.     outp(ADDR_BUZZAR, status | 0x3);        /* buzzar on        */
  603.     for (i = 0; i < CLICK_BEEP; i++)
  604.         nullFunction();            /* short wait        */
  605.     outp(ADDR_BUZZAR, status);            /* buzzar off        */
  606. }
  607.  
  608. /*
  609. ** bell()
  610.  *
  611.  * generate beep sound 'pii' with screen flush if required
  612.  */
  613. void bell()
  614. {
  615.     u_char    status;
  616.  
  617.     if (visibleBell == AUDIBLE_BELL  || visibleBell == BOTH_AV_BELL) {
  618.         status = inp(ADDR_BUZZAR);        /* read current status    */
  619.         outp(ADDR_BUZZAR, status | 0x3);    /* buzzar on        */
  620.     }
  621.     timerValue = timerLoadValue;
  622.     while (timerLoadValue - timerValue < BELL_BEEP) {
  623.         nullFunction();
  624.         if (visibleBell == VISIBLE_BELL || visibleBell == BOTH_AV_BELL) {
  625.             reverseScreen();
  626.             reverseScreen();
  627.         }
  628.     }
  629.     if (visibleBell == AUDIBLE_BELL  || visibleBell == BOTH_AV_BELL)
  630.         outp(ADDR_BUZZAR, status);        /* buzzar off        */
  631. }
  632.  
  633. /*
  634. ** textCRTOnOff(int  onOff)
  635.  *
  636.  * display text CRT or hide it
  637.  *
  638.  * actually Off means Page 2 of TEXT VRAM, it MAY be cleared!
  639.  */
  640. void textCRTOnOff(onOff)
  641. int onOff;
  642. {
  643.        if (onOff == NO)
  644.         clearCurrentPage();
  645. }
  646.  
  647. void setBorder(col)
  648. int col;
  649. {
  650.     /* not supported */
  651. }
  652.