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

  1. /*
  2.  * j3100.c: hterm screen driver for J-3100 series
  3.  *
  4.  * Author: Kaz.Tominaga@Titech/giken
  5.  *
  6.  * 1.1 89/11/01 Tominaga@titech/giken converted from ibmpc.c
  7.  * 1.2 89/11/29 Halca.Hirano visible/audible/both bell mode
  8.  * 1.3 90/06/21 Halca.Hirano 
  9.  *    remove multiple page support by explicit page selection
  10.  *    support soft font
  11.  * 1.4 90/07/05 Halca.Hirano
  12.  *    turn backlight off when text CRT off (called by screen saver)
  13.  *
  14.  * $Header: j3100.cv  1.8  90/07/05 08:37:26  hirano  Exp $
  15.  */
  16.  
  17. #ifdef J3100
  18. #include "option.h"
  19. #include <stdio.h>
  20. #include "config.h"
  21. #include "hterm.h"
  22. #include "default.h"
  23. #include "global.h"
  24.  
  25. /* the expression of cursor location in BIOS    */
  26. #define    B_CURSOR(x,y)    (u_short)((((y) & 0xff) << 8) | ((x) & 0xff))
  27.  
  28. /*
  29.  * physical line number VRAM address convertion table
  30.  * index = physical line number
  31.  * contents = VRAM address
  32.  */
  33. static u_short *ltopTab[MAX_LINE_25_MODE];
  34. /*
  35.  * logical line number to VRAM address conversion function
  36.  */
  37. #define ltop(y) (ltopTab[y])
  38.  
  39. static u_short    screenmode;    /* screen mode */
  40. static u_short    scrollmode;    /* scroll mode */
  41. static u_short    cursormode;    /* cursor mode */
  42. static u_short    cursorshape;    /* cursor shape */
  43. static u_short    syslinecount;    /* system line count */
  44. static short vramSegmentSave;        /* text move VRAM segment        */
  45. static short backingStoreSeg;        /* soft font backing store        */
  46. static char FAR *backingStore;        /* pointer to backing store        */
  47.  
  48. static void reverseScreen(void );
  49.  
  50. /*
  51. ** void CRTInit(): initialize PC98 CRT
  52.  *
  53.  * called once just after hterm startup
  54.  */
  55. void CRTInit()
  56. {
  57.     register int i;
  58.     register u_short *p;
  59.  
  60. #ifdef SOFT_FONT
  61.     /*
  62.      *    build line number conversion table
  63.      */
  64.     p = (u_short *)0;
  65.     for (i = 0; i < MAX_LINE_25_MODE; i++) {
  66.         /* physical line no to VRAM address convertion table */
  67.         ltopTab[i] = p;
  68.         p += MAX_COLUMN;
  69.     }
  70.  
  71.     /*
  72.      * allocate memory for VRAM backing store
  73.      */
  74.     backingStore = allocMem((long)MAX_CHAR*sizeof(short));
  75.     if (backingStore == 0) {
  76.         fprintf(stderr, msg_alloc, "backing store\n");
  77.         exit(1);
  78.     }
  79.     backingStoreSeg = FP_SEG(backingStore);
  80. #endif
  81.     vramSegmentSave = vramSegment = VRAM_MONO;
  82.     gvramSegment = GVRAMSEG;    /* but reset later    */
  83.     
  84.     /* read screen mode */
  85.     rg.h.ah = 0x0f;
  86.     int86(VIDEOBIOS, &rg, &rg);
  87.     screenmode = rg.h.al;
  88.     
  89.     /* read scroll mode */
  90.     rg.x.ax = 0x8200;
  91.     rg.h.bl = -1;
  92.     int86(VIDEOBIOS, &rg, &rg);
  93.     scrollmode = rg.h.al;
  94.  
  95.     /* read cursor mode */
  96.     rg.x.ax = 0x8204;
  97.     rg.h.bl = -1;
  98.     int86(VIDEOBIOS, &rg, &rg);
  99.     cursormode = rg.h.al;
  100.  
  101.     /* read cursor shape */
  102.     rg.h.ah = 3;
  103.     int86(VIDEOBIOS, &rg, &rg);
  104.     cursorshape = rg.x.cx;
  105.  
  106.     /* get system line count */
  107.     rg.x.ax = 0x0cff;
  108.     int86(SYSTEMSUB, &rg, &rg);
  109.     syslinecount = rg.h.al;
  110. }
  111.  
  112. /*
  113. ** void CRTEnd()
  114.  */
  115. void CRTEnd()
  116. {
  117.     freeMem(backingStore);
  118.     upScrRegion = 0;
  119.     lowScrRegion = BOTTOM_LINE_25_MODE;
  120. #ifdef SOFT_FONT
  121.     if (softFont) {                    /* erase graphic screen        */
  122.         clearCurrentPage();
  123.         cursorOnOff(NO);
  124.         softFont = NO;
  125.     }
  126. #endif /* SOFT_FONT */
  127.     restoreCRTMode();
  128. }
  129.  
  130.  
  131. /*
  132. ** void setCRTMode()
  133.  *
  134.  * set CRT mode
  135.  */
  136. void setCRTMode()
  137. {
  138.     short FAR *p;
  139.     int  i;
  140.  
  141.     /*
  142.      * set CRT mode
  143.      */
  144. #ifdef SOFT_FONT
  145.     if (softFont) {
  146.         /*
  147.          *    erase text cursor and text VRAM
  148.          */
  149.         softFont = NO;
  150.         cursorOnOff(NO);
  151.         clearCurrentPage();
  152.         softFont = YES;
  153.         /*
  154.          * fake text VRAM dummy at vramBacking store
  155.          */
  156.         vramSegment = backingStoreSeg;
  157.         /*
  158.          * clear backing store    
  159.          */
  160.         FP_SEG(p) = vramSegment;
  161.         FP_OFF(p) = 0;
  162.         for (i = MAX_CHAR; i > 0; --i)
  163.             *p++ = (u_short)((eraseAttr<<8) | SPACE);
  164.         /*
  165.          * set GRAPHIC mode
  166.          */
  167.         rg.h.ah = 0;                /* set video mode command    */
  168.         rg.h.al = 0x0074;            /* mono 640x400(?)            */
  169.         int86(VIDEOBIOS, &rg, &rg);
  170.     } else 
  171. #endif /* SOFT_FONT */
  172.     {
  173.         vramSegment = vramSegmentSave;
  174.         /*
  175.          * set TEXT mode
  176.          */
  177.         /* set screen mode */
  178.         rg.x.ax = 0x0074;    /* graphics 25rows */
  179.         int86(VIDEOBIOS, &rg, &rg);
  180.  
  181.         /* set scroll mode */
  182.         rg.x.ax = 0x8200;
  183.         rg.h.bl = 0;        /* fast scroll mode */
  184.         int86(VIDEOBIOS, &rg, &rg);
  185.  
  186.         /* set one system line for feps */
  187.         rg.x.ax = 0x0c00;
  188.         int86(SYSTEMSUB, &rg, &rg);
  189.  
  190.         /* cursor mode is set by setup */
  191.     }
  192. }
  193.  
  194. /*
  195. ** void restoreCRTMode()
  196.  *
  197.  * restore CRT mode to startup condition
  198.  */
  199. void restoreCRTMode()
  200. {
  201.     /* restore screen mode */
  202.     rg.h.ah = 0;
  203.     rg.h.al = screenmode;
  204.     int86(VIDEOBIOS, &rg, &rg);
  205.  
  206.     /* restore scroll mode */
  207.     rg.x.ax = 0x8200;
  208.     rg.h.bl = scrollmode;
  209.     int86(VIDEOBIOS, &rg, &rg);
  210.  
  211.     /* restore cursor mode */
  212.     rg.x.ax = 0x8204;
  213.     rg.h.bl = cursormode;
  214.     int86(VIDEOBIOS, &rg, &rg);
  215.  
  216.     /* restore cursor shape */
  217.     rg.h.ah = 1;
  218.     rg.x.cx = cursorshape;
  219.     int86(VIDEOBIOS, &rg, &rg);
  220.  
  221.     /* restore system line count */
  222.     rg.h.ah = 0x0c;
  223.     rg.h.al = syslinecount;
  224.     int86(SYSTEMSUB, &rg, &rg);
  225. }
  226.  
  227. /*
  228. ** locate(register int x, int y)
  229.  *
  230.  * set cursor on position (x,y)
  231.  */
  232. void locate(x, y)
  233. register int x, y;
  234. {
  235.     cursorX = x;
  236.     cursorY = y;
  237. #ifdef SOFT_FONT
  238.     if (softFont) {
  239.         if (cursor)
  240.             softFontLocate(x, y);
  241.     } else
  242. #endif
  243.         b_setCursor(B_CURSOR(x, y));        /* set cursor using bios */
  244. }
  245.  
  246. #ifdef SOFT_FONT
  247. /*
  248. ** int isKanjiOnVRAM(x, y)
  249.  *
  250.  * return non zero if the character is kanji at current cursor position
  251.  *
  252.  */
  253. int isKanjiOnVRAM(x, y)
  254. int x;
  255. int y;
  256. {
  257.     u_short FAR *p;
  258.  
  259.     FP_SEG(p) = vramSegment;
  260.     FP_OFF(p) = (int)(ltop(y) + x);
  261.     return(isSJIS1(*p & 0xff));
  262. }
  263. #endif /* SOFT_FONT */
  264.  
  265. /*
  266. ** void cursorOnOff(int onOff)
  267.  *
  268.  * set cursor form; on/off, blinking/static, underline/block
  269.  */
  270. void cursorOnOff(onOff)
  271. int onOff;
  272. {
  273. #ifdef SOFT_FONT
  274.     if (softFont) {
  275.         softCursorOnOff(onOff);
  276.     } else
  277. #endif
  278.     {
  279.         rg.x.ax = 0x8204;        /* set cursor mode    */
  280.         rg.h.bl = blinkCursor ? 0/*blink*/ : 1/*static*/;
  281.         int86(VIDEOBIOS, &rg, &rg);
  282.  
  283.         rg.h.ah = 1;            /* set cursor type service code */
  284.         if (onOff == YES)
  285.             rg.x.cx = blockCursor ? 0x010e/*block*/ : 0x0b0e/*underline*/;
  286.         else
  287.             rg.x.cx = 0x0f00;    /* cursor off            */
  288.         int86(VIDEOBIOS, &rg, &rg);
  289.     }
  290. }
  291.  
  292. /*
  293. ** void putChar(register u_short c)
  294.  *
  295.  * put a charactor 'c' and attribute 'attrib' at (cursorX, cursorY)
  296.  */
  297. void putChar(c)
  298. register u_short c;
  299. {
  300.     u_short    attr;
  301.     u_short    code;
  302.     u_short FAR *p;
  303.  
  304. #ifdef SOFT_FONT
  305.     if (softFont) {
  306.         /*
  307.          * update backing store
  308.          */
  309.         FP_SEG(p) = vramSegment;
  310.         FP_OFF(p) = (int)(ltop(cursorY) + cursorX);
  311.         *p = (attrib << 8 | (u_char)c);
  312.     } else
  313. #endif
  314.     {
  315.         /* attribute decoding */
  316.         if (attrib & _REVER) {
  317.             attr = _REVER_ATTR;
  318.         } else if (attrib & _UNDER) {
  319.             attr = _UNDER_ATTR;
  320.         } else if (attrib & _HIGH && c != SPACE) {
  321.             attr = _HIGH_ATTR;
  322.         } else if (attrib & _BLINK && c != SPACE) {
  323.             attr = _BLINK_ATTR;
  324.         } else {
  325.             attr = _NORMAL_ATTR;
  326.         }
  327.  
  328.         code = (attr << 8) | (u_char)c;
  329.         b_writeChar(code);            /* put a char using bios */
  330.     }
  331. }
  332.  
  333. /*
  334. ** void insertLine(register u_short num)
  335.  *
  336.  * insert num lines at cursorY
  337.  *
  338.  * If cursorY is not in scroll region, ignore request
  339.  * If num exceeds scroll region, strict num into scroll region
  340.  *
  341.  */
  342. void insertLine(num)
  343. register int num;
  344. {
  345.     u_short    savexy;
  346.  
  347.     /*
  348.      * if cursor is out of scroll region or zero request, ignore request
  349.      */
  350.     if (cursorY < upScrRegion || cursorY > lowScrRegion || num == 0)
  351.         return;                            /* ignore                    */
  352.     /*
  353.      * requested num must be in scroll region
  354.      */
  355.     if (lowScrRegion+1-cursorY < num)
  356.         num = lowScrRegion+1-cursorY;    /* out of scroll region        */
  357.  
  358. #ifdef SOFT_FONT
  359.     if (softFont) {
  360.         /*
  361.          * update backing store then move GVRAM
  362.          */
  363.         if (cursor)
  364.             cursorOnOff(NO);
  365.         /* moveBackward(to, from, num, MOVE_ATTRIBUTE_TOO) */
  366.         moveBackward(ltop(cursorY+num), ltop(cursorY),
  367.             (lowScrRegion+1-cursorY-num) * MAX_COLUMN, YES);
  368.         softFontInsertLine(num);
  369.         if (cursor)
  370.             cursorOnOff(YES);
  371.         /*
  372.          * clear created lines
  373.          */
  374.         clearLine(cursorY, cursorY+num-1);
  375.     } else
  376. #endif
  377.     {
  378.         savexy = b_getCursor();        /* save cursor position */
  379.         rg.h.ah = 7;        /* scroll down bios */
  380.         rg.h.al = num;        /* scroll line */
  381.         /* scroll region */
  382.         rg.x.cx = B_CURSOR(0, cursorY);
  383.         rg.x.dx = B_CURSOR(MAX_COLUMN-1, lowScrRegion);
  384.         int86(VIDEOBIOS, &rg, &rg);
  385.         b_setCursor(savexy);        /* restore cursor position */
  386.     }
  387. }
  388.  
  389. /*
  390. ** void deleteLine(register u_short num)
  391.  *
  392.  * delete num lines at cursorY
  393.  *
  394.  * If cursorY is not in scroll region, ignore request
  395.  * If num exceeds scroll region, strict num into scroll region
  396.  *
  397.  */
  398. void deleteLine(num)
  399. register int num;
  400. {
  401.     u_short    savexy;
  402.  
  403.     /*
  404.      * if cursor is out of scroll region or zero request, ignore request
  405.      */
  406.     if (cursorY < upScrRegion || cursorY > lowScrRegion || num == 0)
  407.         return;                            /* ignore                    */
  408.     /*
  409.      * requested num must be in scroll region
  410.      */
  411.     if (lowScrRegion+1-cursorY < num)
  412.         num = lowScrRegion+1-cursorY;    /* out of scroll region        */
  413.  
  414. #ifdef SOFT_FONT
  415.     if (softFont) {
  416.         /*
  417.          * update backing store then move GVRAM
  418.          */
  419.         if (cursor)
  420.             cursorOnOff(NO);
  421.         /* moveForward(to, from, num, MOVE_ATTRIBUTE_TOO) */
  422.         moveForward(ltop(cursorY), ltop(cursorY+num),
  423.             (lowScrRegion+1-cursorY-num)*MAX_COLUMN, YES);
  424.         softFontDeleteLine(num);
  425.         if (cursor)
  426.             cursorOnOff(YES);
  427.         /*
  428.          * clear created lines
  429.          */
  430.         clearLine(lowScrRegion-num+1, lowScrRegion);
  431.     } else
  432. #endif
  433.     {
  434.         savexy = b_getCursor();        /* save cursor position */
  435.         rg.h.ah = 6;        /* scroll up bios */
  436.         rg.h.al = num;        /* scroll line */
  437.         /* scroll region */
  438.         rg.x.cx = B_CURSOR(0, cursorY);
  439.         rg.x.dx = B_CURSOR(MAX_COLUMN-1, lowScrRegion);
  440.         int86(VIDEOBIOS, &rg, &rg);
  441.         b_setCursor(savexy);        /* restore cursor position */
  442.     }
  443. }
  444.  
  445. /*
  446. ** void clearColumn(register u_shrot from, register u_short to)
  447.  *
  448.  * clear column 'from' to 'to'-1 on cursorY line, 
  449.  */
  450. void clearColumn(from, to)
  451. register u_short from, to;
  452. {
  453.     int    savexy;
  454.  
  455.     if (to > from) {
  456. #ifdef SOFT_FONT
  457.         if (softFont) {
  458.             if (cursor)
  459.                 cursorOnOff(NO);
  460.             fillVRAM(ltop(cursorY)+from, to-from, SPACE, eraseAttr);
  461.             softFontClearColumn(from, to);
  462.             if (cursor)
  463.                 cursorOnOff(YES);
  464.         } else
  465. #endif
  466.         {
  467.             savexy = b_getCursor();        /* save cursor position */
  468.             rg.h.ah = 6;        /* use scroll up bios to clear region    */
  469.             rg.h.al = 0;        /* scroll line = 0 means 'clear'    */
  470.             /* scroll region */
  471.             rg.x.cx = B_CURSOR(from, cursorY);
  472.             rg.x.dx = B_CURSOR(to-1, cursorY);
  473.             int86(VIDEOBIOS, &rg, &rg);
  474.             b_setCursor(savexy);        /* restore cursor position */
  475.         }
  476.     }
  477. }
  478.  
  479. /*
  480. ** void clearCurrentPage()
  481.  *
  482.  * clear current page
  483.  */
  484. void clearCurrentPage()
  485. {
  486. #ifdef SOFT_FONT
  487.     if (softFont) {
  488.         clearLine(0, BOTTOM_LINE_25_MODE);
  489.     } else 
  490. #endif
  491.     {    
  492.         rg.h.ah = 6;        /* use scroll up bios to clear region    */
  493.         rg.h.al = 0;        /* scroll line = 0 means 'clear'    */
  494.         /* scroll region */
  495.         rg.x.cx = B_CURSOR(0, 0);
  496.         rg.x.dx = B_CURSOR(MAX_COLUMN-1, realBottomLine);
  497.         int86(VIDEOBIOS, &rg, &rg);
  498.     }
  499. }
  500.  
  501. /*
  502. ** void insertChar(register int at, int n)
  503.  *
  504.  * insert n blank charactors at 'at' on cursorY line
  505.  */
  506. void insertChar(at, n)
  507. register int at;
  508. register int n;
  509. {
  510.     register int moveNum = MAX_COLUMN-at-n;
  511.     u_short    savexy;
  512.  
  513. #ifdef SOFT_FONT
  514.     if (softFont) {
  515.         register u_short *src = ltop(cursorY)+at;
  516.         if (cursor)
  517.             cursorOnOff(NO);
  518.         if (moveNum > 0)
  519.             moveBackward(src+n, src, moveNum, YES);
  520.         else
  521.             n = MAX_COLUMN-at;
  522.         fillVRAM(src, n, SPACE, eraseAttr);
  523.         softFontInsertChar(at, n);
  524.         if (cursor)
  525.             cursorOnOff(YES);
  526.     } else
  527. #endif
  528.     {            
  529.         savexy = b_getCursor();        /* save cursor position */
  530.         if (moveNum > 0)
  531.             moveBackwardJ3(B_CURSOR(at+n, cursorY), B_CURSOR(at, cursorY), moveNum);
  532.         else
  533.             n = MAX_COLUMN-at;
  534.         clearColumn(at, at+n);
  535.  
  536.         b_setCursor(savexy);        /* restore cursor position */
  537.     }
  538. }
  539.  
  540. /*
  541. ** void deleteChar(register int at, register int n)
  542.  *
  543.  * delete 'n' characters at 'at' on cursorY line and make blank trailing 'n'
  544.  * characters.
  545.  */
  546. void deleteChar(at, n)
  547. register int at;
  548. register int n;
  549. {
  550.     register int moveNum = MAX_COLUMN-at-n;
  551.     u_short    savexy;
  552.  
  553. #ifdef SOFT_FONT
  554.     if (softFont) {
  555.         register u_short *src = ltop(cursorY)+at;
  556.         if (cursor)
  557.             cursorOnOff(NO);
  558.         if (moveNum > 0)
  559.             moveForward(src, src+n, moveNum, YES);
  560.         else {
  561.             n = MAX_COLUMN-at;
  562.             moveNum = 0;
  563.         }
  564.         fillVRAM(src+moveNum, n, SPACE, eraseAttr);
  565.         softFontDeleteChar(at, n);
  566.         if (cursor)
  567.             cursorOnOff(YES);
  568.     } else
  569. #endif
  570.     {
  571.         savexy = b_getCursor();        /* save cursor position */
  572.  
  573.         if (moveNum > 0)
  574.             moveForwardJ3(B_CURSOR(at, cursorY), B_CURSOR(at+n, cursorY), moveNum);
  575.         else
  576.             n = MAX_COLUMN-at;
  577.         clearColumn(MAX_COLUMN-n, MAX_COLUMN);
  578.  
  579.         b_setCursor(savexy);        /* restore cursor position */
  580.     }
  581. }
  582.  
  583. /*
  584. ** void saveLine(int y, register u_char FAR *buf)
  585.  *
  586.  * copy line y in VRAM into buffer
  587.  * Kanji code is EUC in buffer.
  588.  */
  589. void saveLine(y, buf)
  590. int y;
  591. register u_char FAR *buf;
  592. {
  593. #ifdef SOFT_FONT
  594.     if (softFont) {
  595.         register u_short c;
  596.         short FAR *from;
  597.         register u_char l;
  598.         register int i;
  599.  
  600.         FP_SEG(from) = vramSegment;
  601.         FP_OFF(from) = (int)ltop(y);
  602.  
  603.         for (i = 0; i < MAX_COLUMN; i++) {
  604.             c = *from++;
  605.             if (c & 0x80) {        /* kanji */
  606.                 l = c;
  607.                 c = SJIStoJIS(l, *from++ & 0xff) | 0x8080;
  608.                 *buf++ = c >> 8;
  609.                 *buf++ = c;
  610.                 i++;
  611.             } else
  612.                 *buf++ = c;
  613.         }
  614.     } else
  615. #endif /* SOFT_FONT */
  616.     {    
  617.         register u_short c, c2, i;
  618.         u_short    savexy;        /* bios expression */
  619.  
  620.         /* save current cursor position by bios call */
  621.         savexy = b_getCursor();
  622.  
  623.         for (i = 0; i < MAX_COLUMN; i++) {
  624.             c = b_readCharAt(B_CURSOR(i, y));
  625.             if (c & 0x80) {        /* kanji */
  626.                 /* Oops! hankaku-kana is not supported! */
  627.                 i++;
  628.                 c2 = b_readCharAt(B_CURSOR(i, y));
  629.                 c = SJIStoJIS(c, c2 & 0xff) | 0x8080;
  630.                 *buf++ = c >> 8;
  631.                 *buf++ = c;
  632.             } else {
  633.                 *buf++ = c;
  634.             }
  635.         }
  636.  
  637.         /* restore cursor position by calling bios */
  638.         b_setCursor(savexy);
  639.     }
  640. }
  641.  
  642. /*
  643. ** static void reverseScreen()
  644.  *
  645.  * reverse screen
  646.  */
  647. static void reverseScreen()
  648. {
  649. #ifdef SOFT_FONT
  650.     if (softFont)
  651.         softFontReverseScreen();
  652.     else 
  653. #endif /* SOFT_FONT */
  654.         v_reverseScreen();
  655. }
  656.  
  657. /*
  658. ** void savePage(u_short buf[])
  659.  *
  660.  * save vram into save buffer 'buf' without code conversion
  661.  */
  662. void savePage(buf)
  663. u_short *buf;
  664. {
  665.     u_short    savexy;
  666.  
  667. #ifdef SOFT_FONT
  668.     if (softFont)    
  669.         moveMemory(buf, getDSeg(), (u_short *)0, vramSegment, MAX_CHAR);
  670.     else
  671. #endif
  672.     {
  673.         savexy = b_getCursor();
  674.         saveVRAM(buf, getDSeg());
  675.         b_setCursor(savexy);
  676.     }
  677. }
  678.  
  679. /*
  680. ** void restorePage(u_short buf)
  681.  *
  682.  * restore saved page into vram 
  683.  */
  684. void restorePage(buf)
  685. u_short *buf;
  686. {
  687.     u_short    savexy;
  688.  
  689. #ifdef SOFT_FONT
  690.     register u_short c;
  691.     register u_char l;
  692.     u_short *p;
  693.     int cursorXSave = cursorX;
  694.     int cursorYSave = cursorY;
  695.  
  696.     if (softFont) {
  697.         moveMemory((u_short *)0, vramSegment, buf, getDSeg(), MAX_CHAR);
  698.         softCursorOnOff(NO);
  699.         p = buf;            /* char pointer    */
  700.         for (cursorY = 0; cursorY <= realBottomLine; cursorY++) {
  701.             for (cursorX = 0; cursorX < MAX_COLUMN; cursorX++) {
  702.                 c = *p++;            /* get attribute and char    */
  703.                 attrib = (c >> 8);    /* attribute                */
  704.                 c &= 0xff;            /* strip attribute            */
  705.                 if (c & 0x80) {        /* kanji                     */
  706.                     l = c;
  707.                     c = SJIStoJIS(l, *p++ & 0xff);
  708.                     softFontPutChar(c);
  709.                     cursorX++;
  710.                 } else {        /* ASCII    */
  711.                     if (c < 0x20 || 0x7e < c)    /* ignore kana    */
  712.                         c = '?';
  713.                     softFontPutChar(c);
  714.                 }
  715.             }
  716.         }
  717.         cursorX = cursorXSave;
  718.         cursorY = cursorYSave;
  719.         if (cursor)
  720.             softCursorOnOff(YES);
  721.     } else
  722. #endif /* SOFT_FONT */
  723.     {
  724.         savexy = b_getCursor();    
  725.         loadVRAM(buf, getDSeg());
  726.         b_setCursor(savexy);
  727.     }
  728. }
  729.  
  730. /*
  731. ** void clearSavedPage(u_char buf[])
  732.  *
  733.  * clear saved page 
  734.  */
  735. void clearSavedPage(buf)
  736. u_short *buf;
  737. {
  738.     register int i;
  739.     register u_short *p;
  740.  
  741.     for (p = buf, i = MAX_CHAR; i > 0; --i)
  742.         *p++ = (u_short)((eraseAttr<<8) | SPACE);
  743. }
  744.  
  745. /*
  746. ** void click()
  747.  *
  748.  * generate click 'pi' sound
  749.  */
  750. void click()
  751. {
  752.     int i;
  753.     u_char    status;
  754.  
  755.     status = inp(ADDR_BUZZAR);        /* read current status    */
  756.     outp(ADDR_BUZZAR, status | 0x3);    /* buzzar on        */
  757.     for (i = 0; i < CLICK_BEEP; i++)
  758.         nullFunction();            /* short wait        */
  759.     outp(ADDR_BUZZAR, status);        /* buzzar off        */
  760. }
  761.  
  762. /*
  763. ** void bell()
  764.  *
  765.  * generate beep sound 'pii' with screen flush if required
  766.  */
  767. void bell()
  768. {
  769.     u_char    status;
  770.  
  771.     /* check shift status for discarding beeps */
  772.     rg.h.ah = 2;
  773.     int86(KEY_BIOS, &rg, &rg);
  774.     if ((rg.h.al & 0x03) == 0x03) return;    /* both SHIFT are pressed */
  775.  
  776.     cursorOnOff(NO);                /* for flashing screen    */
  777.     if (visibleBell == AUDIBLE_BELL  || visibleBell == BOTH_AV_BELL) {
  778.         status = inp(ADDR_BUZZAR);    /* read current status    */
  779.         outp(ADDR_BUZZAR,status | 0x3);    /* buzzar on        */
  780.     }
  781.     timerValue = timerLoadValue;
  782.     while (timerLoadValue - timerValue < BELL_BEEP) {
  783.         nullFunction();
  784.         if (visibleBell == VISIBLE_BELL || visibleBell == BOTH_AV_BELL) {
  785.             reverseScreen();
  786.             reverseScreen();
  787.         }
  788.     }
  789.     cursorOnOff(cursor);    /* redisplay cursor    if required */
  790.     if (visibleBell == AUDIBLE_BELL  || visibleBell == BOTH_AV_BELL)
  791.         outp(ADDR_BUZZAR, status);    /* buzzar off        */
  792. }
  793.  
  794. /*
  795. ** void textCRTOnOff(int  onOff)
  796.  *
  797.  * display text CRT or hide it
  798.  *
  799.  * actually Off means clearing of current page
  800.  * backlight is turned off
  801.  */
  802. void textCRTOnOff(onOff)
  803. int onOff;
  804. {
  805.     if (onOff == NO) {
  806.         clearCurrentPage();
  807.         outp(0xe8, 0xb05a);        /* back light off    */
  808.     } else
  809.         outp(0xe8, 0xbf5a);        /* back light on    */
  810. }
  811.  
  812. void setBorder(col)
  813. int col;
  814. {
  815.     /* not supported */
  816. }
  817. #endif /* J3100 */
  818.