home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 1 / FREEWARE.BIN / dmycon / consim.c < prev    next >
Text File  |  1989-10-17  |  29KB  |  1,314 lines

  1. /****************************************************
  2.  
  3.     FM-TOWNS FM16/FMR50 Console Sim Program
  4.  
  5.     89.9.16 make v1.00        by Ken
  6.     89.9.18 bug fix & speed up    by Ken
  7.     89.9.20 Consol BIOS apend   by Ken
  8.  
  9. ****************************************************/
  10. #include    <stdio.h>
  11. #include    <stdlib.h>
  12. #include    <ctype.h>
  13. #include    <process.h>
  14.  
  15. #define TRUE    1
  16. #define FALSE   0
  17. #define ERR     (-1)
  18.  
  19. #define UCHAR   unsigned char
  20. #define SHORT   short int
  21. #define    UNSIG    unsigned int
  22.  
  23. #define    OFFSET(p,n)    *((unsigned int *)(&(p)))=n
  24. #define    SEGSET(p,n)    *((unsigned int *)(&(p))+1)=n
  25. #define    LOW(p)        ((unsigned char *)(&(p)))
  26. #define    HIGH(p)        ((unsigned char *)(&(p))+1)
  27.  
  28. #define    CVRAM    0xC800
  29. #define    KVRAM    0xCA00
  30.  
  31. #define    SCR_X    80
  32. #define MAX_X   80
  33. #define MAX_Y   25
  34.  
  35. #define DMYKAN  0xFE
  36. #define CRCHR   0x1F
  37. #define TABCHR  0x09
  38. #define    NULCHR    0x20
  39. #define TAB     8
  40. #define CONTRL  FALSE
  41. #define    DEFCOL    COLOR
  42.  
  43.        SHORT    CUR_X=0,CUR_Y=0;
  44. static SHORT    CUR_DSP_FLG=0;
  45. static SHORT    Con_mode=0xCE;
  46. static SHORT    SCR_Y=MAX_Y;
  47. static SHORT    BAK_X,BAK_Y;
  48. static SHORT    COLOR=7,BAKCOL=0;
  49. static SHORT    KANMOD=TRUE;
  50. static UCHAR    BAKCH1=0;
  51. static UCHAR    KANCOD=0;
  52. static SHORT    EXTFLG=FALSE;
  53. static void    (*EXTPRO)();
  54. static SHORT    ESCCNT=0;
  55. static UCHAR    ESCPRM[12];
  56. static UCHAR    dmy_ram[MAX_X*MAX_Y*2];
  57.  
  58. struct {
  59.     SHORT    r_es;
  60.     SHORT    r_ds;
  61.     SHORT    r_di;
  62.     SHORT    r_si;
  63.     SHORT    r_bp;
  64.     SHORT    r_sp;
  65.     SHORT    r_bx;
  66.     SHORT    r_dx;
  67.     SHORT    r_cx;
  68.     SHORT    r_ax;
  69.     SHORT    r_ip;
  70.     SHORT    r_cs;
  71.     SHORT    r_cf;
  72. } ureg;
  73.  
  74. extern UCHAR    ankfont[];
  75.  
  76. /***************************************************
  77.  
  78.     <<< Compile to "BIOS.ASM" >>>
  79.  
  80. static void    colset(vp,cl,cnt)
  81. UNSIG    vp;
  82. int     cl,cnt;
  83. {
  84.     UCHAR far *p;
  85.  
  86.     SEGSET(p,CVRAM);
  87.     OFFSET(p,vp);
  88.     while ( cnt > 0 ) {
  89.     *(p++) = 0; *(p++) = cl;
  90.     cnt-=2;
  91.     }
  92. }
  93. static void    vramcpy(d,s,n)
  94. UNSIG    d,s;
  95. int    n;
  96. {
  97.     movedata(CVRAM,s,CVRAM,d,n);
  98.     movedata(KVRAM,s,KVRAM,d,n);
  99. }
  100. void    Wrt_Ank(ch,x,y,cl)
  101. UCHAR    ch;
  102. int    x,y,cl;
  103. {
  104.     int     i,at,bk;
  105.     UCHAR   *fp;
  106.     UCHAR far *vp;
  107.     UCHAR far *bp;
  108.  
  109.     fp = ankfont + ch * 16;
  110.     *((unsigned int *)(&vp)+1) = 0xC000;
  111.     *((unsigned int *)(&vp)) = x + (MAX_X * 16) * y;
  112.  
  113.     at = cl & 0x07;
  114.     if ( (cl & 0x20) != 0 ) at |= 0x08;
  115.     if ( (cl & 0x18) != 0 ) bk = 0xFF; else bk = 0;
  116.  
  117.     outp(0xFF81,0x0F);
  118.     for ( bp = vp,i = 0 ; i < 16 ; i++ ) {
  119.     *bp = 0;
  120.     bp += MAX_X;
  121.     }
  122.     outp(0xFF81,at);
  123.     for ( i = 0 ; i < 16 ; i++ ) {
  124.     *vp = *(fp++) ^ bk;
  125.     vp += MAX_X;
  126.     }
  127. }
  128. void    Wrt_Kan(ch,x,y,cl)
  129. int    ch;
  130. int    x,y,cl;
  131. {
  132.     int     i,at,bk;
  133.     UCHAR far *vp;
  134.     UCHAR far *bp;
  135.  
  136.     *((unsigned int *)(&vp)+1) = 0xC000;
  137.     *((unsigned int *)(&vp)) = x + (MAX_X * 16) * y;
  138.  
  139.     outp(0xFF94,ch >> 8);
  140.     outp(0xFF95,ch & 0xFF);
  141.  
  142.     at = cl & 0x07;
  143.     if ( (cl & 0x20) != 0 ) at |= 0x08;
  144.     if ( (cl & 0x18) != 0 ) bk = 0xFF; else bk = 0;
  145.  
  146.     outp(0xFF81,0x0F);
  147.     for ( bp = vp,i = 0 ; i < 16 ; i++ ) {
  148.     *bp = *(bp+1) = 0;
  149.     bp += MAX_X;
  150.     }
  151.     outp(0xFF81,at);
  152.     for ( i = 0 ; i < 16 ; i++ ) {
  153.     *vp = inp(0xFF96) ^ bk;
  154.     *(vp+1) = inp(0xFF97) ^ bk;
  155.     vp += MAX_X;
  156.     }
  157. }
  158. void    locate(x,y)
  159. int    x,y;
  160. {
  161.     int     i;
  162.     UCHAR far *vp;
  163.  
  164.     *((unsigned int *)(&vp)+1) = 0xC000;
  165.     *((unsigned int *)(&vp)) = x + (MAX_X * 16) * y + (MAX_X * 14);
  166.  
  167.     outp(0xFF81,0x0F);
  168.     for ( vp = vp,i = 0 ; i < 2 ; i++ ) {
  169.     *vp = 0xFF;
  170.     vp += MAX_X;
  171.     }
  172. }
  173. int     sjisto(cd)
  174. int     cd;
  175. {
  176.     int    hi,lo;
  177.  
  178.     hi=(cd >> 8)&0xff;
  179.     lo=cd & 0xff;
  180.     hi -= ( hi <= 0x9f) ? 0x71 : 0xb1;
  181.     hi = hi * 2 +1;
  182.     if ( lo > 0x7f )
  183.     lo--;
  184.     if ( lo >= 0x9e ) {
  185.         lo -= 0x7d;
  186.         hi++;
  187.     }
  188.     else
  189.         lo -= 0x1f;
  190.     return (hi << 8 | lo);
  191. }
  192. static void    Beep()
  193. {
  194.     int     i;
  195.  
  196.     for ( i = 0 ; i < 5000 ; i++ )
  197.     inp(0xFF98);
  198.     outp(0xFF98,0);
  199. }
  200. **************************************************************/
  201. static void    NextChr(sub)
  202. void     (*sub)();
  203. {
  204.     EXTFLG = TRUE;
  205.     EXTPRO = sub;
  206. }
  207. static void    Scrool()
  208. {
  209.     vramcpy(0,(MAX_X * 2),(MAX_X * 2) * (SCR_Y - 1));
  210.     colset((MAX_X * 2) * (SCR_Y - 1),COLOR,(MAX_X * 2));
  211. }
  212. static void    PutBS()
  213. {
  214.     if ( --CUR_X < 0 ) {
  215.         CUR_X = SCR_X - 1;
  216.         if ( --CUR_Y < 0 )
  217.             CUR_Y = 0;
  218.     }
  219. }
  220. static void    PutTAB()
  221. {
  222.     int     i;
  223.     extern void    PutChr();
  224.  
  225.     if ( (Con_mode & 0x02) == 0 )
  226.     i = 1;
  227.     else
  228.         i = ((CUR_X + TAB) / TAB) * TAB - CUR_X;
  229.     while ( i-- > 0 )
  230.     PutChr(COLOR|0xC0,NULCHR);
  231. }
  232. static void    PutLF()
  233. {
  234.     if ( ++CUR_Y >= SCR_Y ) {
  235.     CUR_Y = (SCR_Y - 1);
  236.     Scrool();
  237.     }
  238.     if ( (Con_mode & 0x01) != 0 )
  239.     CUR_X = 0;
  240. }
  241. static void    PutHOME()
  242. {
  243.     CUR_X = CUR_Y = 0;
  244. }
  245. static void    PutCLS()
  246. {
  247.     colset(0,COLOR,(MAX_X * 2) * SCR_Y);
  248.     CUR_X = CUR_Y = 0;
  249. }
  250. static void    PutCR()
  251. {
  252.     CUR_X = 0;
  253.     if ( (Con_mode & 0x01) != 0 )
  254.     PutLF();
  255. }
  256. static void    CurRit()
  257. {
  258.     if ( ++CUR_X >= SCR_X )
  259.         CUR_X = 0;
  260. }
  261. static void    CurLft()
  262. {
  263.     if ( --CUR_X < 0 )
  264.         CUR_X = SCR_X - 1;
  265. }
  266. static void    CurUp()
  267. {
  268.     if ( --CUR_Y < 0 )
  269.     CUR_Y = SCR_Y - 1;
  270. }
  271. static void    CurDwn()
  272. {
  273.     if ( ++CUR_Y >= SCR_Y )
  274.         CUR_Y = 0;
  275. }
  276. void    SVidAt(ch)
  277. int     ch;
  278. {
  279.     COLOR = ch & 0x3F;
  280. }
  281. void    SetDC2_s(ch)
  282. int     ch;
  283. {
  284.     CUR_X = BAKCH1;
  285.     CUR_Y = ch;
  286.     if ( CUR_X < 0 ) CUR_X = 0;
  287.     if ( CUR_X >= SCR_X ) CUR_X = SCR_X - 1;
  288.     if ( CUR_Y < 0 ) CUR_Y = 0;
  289.     if ( CUR_Y >= SCR_Y ) CUR_Y = SCR_Y - 1;
  290. }
  291. void    SetDC2(ch)
  292. int     ch;
  293. {
  294.     extern void    SetDC2_s();
  295.  
  296.     BAKCH1 = ch;
  297.     NextChr(SetDC2_s);
  298. }
  299. void    SetDC3_s(ch)
  300. int     ch;
  301. {
  302.     extern void    PutChr();
  303.  
  304.     while ( BAKCH1-- > 0 )
  305.         PutChr(0xC0|COLOR,ch);
  306. }
  307. void    SetDC3(ch)
  308. int     ch;
  309. {
  310.     extern void    SetDC3_s();
  311.  
  312.     BAKCH1 = ch;
  313.     NextChr(SetDC3_s);
  314. }
  315. static void    EraLin()
  316. {
  317.     colset((CUR_X * 2) + (MAX_X * 2) * CUR_Y,COLOR,(MAX_X - CUR_X) * 2);
  318. }
  319. static void    EraScr()
  320. {
  321.     colset((CUR_X * 2) + (MAX_X * 2) * CUR_Y,COLOR,
  322.        (MAX_X * 2) * SCR_Y - (CUR_X * 2) + (MAX_X * 2) * CUR_Y);
  323. }
  324. static void    InsLin()
  325. {
  326.     int     i;
  327.     UNSIG   p;
  328.  
  329.     p = (MAX_X * 2) * (SCR_Y - 1);
  330.     for ( i = SCR_Y - 1 ; i > CUR_Y ; i-- ) {
  331.         vramcpy(p,p-(MAX_X * 2),(MAX_X * 2));
  332.         p -= (MAX_X * 2);
  333.     }
  334.     colset((MAX_X * 2) * CUR_Y,COLOR,MAX_X * 2);
  335. }
  336. static void    DelLin()
  337. {
  338.     int     i;
  339.     UNSIG   p;
  340.  
  341.     p = (MAX_X * 2) * CUR_Y;
  342.     for ( i = CUR_Y ; i < (SCR_Y - 1) ; i ++ ) {
  343.         vramcpy(p,p+(MAX_X * 2),(MAX_X * 2));
  344.         p += (MAX_X * 2);
  345.     }
  346.     colset((MAX_X * 2) * (SCR_Y - 1),COLOR,MAX_X * 2);
  347. }
  348. void    SCurPs_s(ch)
  349. int     ch;
  350. {
  351.     CUR_Y = BAKCH1 - ' ';
  352.     CUR_X = ch - ' ';
  353.     if ( CUR_X < 0 ) CUR_X = 0;
  354.     if ( CUR_X >= SCR_X ) CUR_X = SCR_X - 1;
  355.     if ( CUR_Y < 0 ) CUR_Y = 0;
  356.     if ( CUR_Y >= SCR_Y ) CUR_Y = SCR_Y - 1;
  357. }
  358. void    SCurPs(ch)
  359. int     ch;
  360. {
  361.     extern void    SCurPs_s();
  362.  
  363.     BAKCH1 = ch;
  364.     NextChr(SCurPs_s);
  365. }
  366. void    CurAtt_s()
  367. {
  368. }
  369. void    CurAtt(ch)
  370. int    ch;
  371. {
  372.     extern void    CurAtt_s();
  373.  
  374.     NextChr(CurAtt_s);
  375. }
  376. static void    AnsiH()
  377. {
  378.     if ( ESCPRM[0] > 0 ) ESCPRM[0]--;
  379.     if ( ESCPRM[1] > 0 ) ESCPRM[1]--;
  380.     CUR_Y = ESCPRM[0];
  381.     CUR_X = ESCPRM[1];
  382.     if ( CUR_X < 0 ) CUR_X = 0;
  383.     if ( CUR_X >= SCR_X ) CUR_X = SCR_X - 1;
  384.     if ( CUR_Y < 0 ) CUR_Y = 0;
  385.     if ( CUR_Y >= SCR_Y ) CUR_Y = SCR_Y - 1;
  386. }
  387. static void    AnsiA()
  388. {
  389.     if ( (CUR_Y -= ESCPRM[0]) < 0 )
  390.         CUR_Y = 0;
  391. }
  392. static void    AnsiB()
  393. {
  394.     if ( (CUR_Y += ESCPRM[0]) >= SCR_Y )
  395.         CUR_Y = SCR_Y - 1;
  396. }
  397. static void    AnsiC()
  398. {
  399.     if ( (CUR_X += ESCPRM[0]) >= SCR_X )
  400.         CUR_X = SCR_X - 1;
  401. }
  402. static void    AnsiD()
  403. {
  404.     if ( (CUR_X -= ESCPRM[0]) < 0 )
  405.         CUR_X = 0;
  406. }
  407. static void    Ansis()
  408. {
  409.     BAK_X = CUR_X;
  410.     BAK_Y = CUR_Y;
  411. }
  412. static void    Ansiu()
  413. {
  414.     CUR_X = BAK_X;
  415.     CUR_Y = BAK_Y;
  416. }
  417. static void    AnsiJ()
  418. {
  419.     switch(ESCPRM[0]) {
  420.         case 0: EraScr(); break;
  421.         case 1: colset(0,COLOR,(CUR_X * 2) + (MAX_X * 2) * CUR_Y); break;
  422.         case 2: PutCLS(); break;
  423.     }
  424. }
  425. static void    AnsiK()
  426. {
  427.     switch(ESCPRM[0]) {
  428.         case 0: EraLin(); break;
  429.         case 1:
  430.             if ( CUR_X > 0 )
  431.         colset((MAX_X * 2) * CUR_Y,COLOR,CUR_X * 2);
  432.             break;
  433.         case 2: colset((MAX_X * 2) * CUR_Y,COLOR,MAX_X * 2); break;
  434.     }
  435. }
  436. static void    AnsiM()
  437. {
  438.     while ( ESCPRM[0]-- > 0 )
  439.         DelLin();
  440.     CUR_X = 0;
  441. }
  442. static void    AnsiL()
  443. {
  444.     while ( ESCPRM[0]-- > 0 )
  445.         InsLin();
  446.     CUR_X = 0;
  447. }
  448. static void    Ansiv()
  449. {
  450.     CUR_DSP_FLG = ESCPRM[0];
  451. }
  452. static void    Ansim()
  453. {
  454.     int     c;
  455.     int     i,n;
  456.     static char ansiatt[]={ 0x00,0x20,0x00,0x00,0x00,0x10,0x00,0x08,0x00 };
  457.     static char ansicol[]={ 0,2,4,6,1,3,5,7 };
  458.  
  459.     for ( n = 0,c = 0x07 ; n < ESCCNT ; n++ ) {
  460.         if ( (i = ESCPRM[n]) > 0 && i <= 8 ) {
  461.             c |= ansiatt[i];
  462.         } else if ( i == 0 ) {
  463.         c &= 0x07;
  464.     } else if ( i >= 30 && i <= 38 ) {
  465.             c &= 0xF8;
  466.             c |= ansicol[i-30];
  467.         } else if ( i >= 40 && i <= 47 ) {
  468.             BAKCOL = ansicol[i-40];        /* 現在未サポ-ト */
  469.         }
  470.     }
  471.     COLOR = c;
  472. }
  473. void    AnsiCom(ch)
  474. int     ch;
  475. {
  476.     if ( ch == ';' && ESCCNT < 8 )
  477.         ESCCNT++;
  478.     else if ( ch >= '0' && ch <= '9' )
  479.         ESCPRM[ESCCNT] = ESCPRM[ESCCNT] * 10 + (ch - '0');
  480.     else if ( ch != ' ' ) {
  481.         ESCCNT++;
  482.         switch(ch) {
  483.             case 'H': AnsiH(); break;
  484.             case 'f': AnsiH(); break;
  485.             case 'A': AnsiA(); break;
  486.             case 'B': AnsiB(); break;
  487.             case 'C': AnsiC(); break;
  488.             case 'D': AnsiD(); break;
  489.             case 's': Ansis(); break;
  490.             case 'u': Ansiu(); break;
  491.             case 'J': AnsiJ(); break;
  492.             case 'K': AnsiK(); break;
  493.             case 'm': Ansim(); break;
  494.             case 'M': AnsiM(); break;
  495.             case 'L': AnsiL(); break;
  496.         case 'v': Ansiv(); break;
  497.         }
  498.         return;
  499.     }
  500.     NextChr(AnsiCom);
  501. }
  502. static void    AnsiESC()
  503. {
  504.     extern void    AnsiCom();
  505.  
  506.     memset(ESCPRM,0,8);
  507.     ESCCNT = 0;
  508.     NextChr(AnsiCom);
  509. }
  510. void    EscCom(ch)
  511. int     ch;
  512. {
  513.     extern void    SCurPs(),SVidAt(),CurAtt();
  514.  
  515.     switch(ch) {
  516.         case '*': PutCLS(); break;
  517.         case 'T': EraLin(); break;
  518.         case 'Y': EraScr(); break;
  519.         case 'E': InsLin(); break;
  520.         case 'R': DelLin(); break;
  521.         case '=': NextChr(SCurPs); break;
  522.         case 'G': NextChr(SVidAt); break;
  523.         case 'K': KANMOD = TRUE; break;
  524.         case 'C': KANMOD = FALSE; break;
  525.     case '.': NextChr(CurAtt); break;
  526.         case '[': AnsiESC(); break;
  527.     case '1': case '2': case '3': break;    /* TAB Set/UnSet */
  528.         default: PutChr(0xC0|COLOR,ch); break;
  529.     }
  530. }
  531. static void    PutCnt(ch)
  532. int     ch;
  533. {
  534.     extern void    SVidAt(),SetDC2(),SetDC3(),EscCom();
  535.  
  536.     switch(ch) {
  537.     case 0x00: break;
  538.     case 0x07: Beep(); break;
  539.         case 0x08: PutBS(); break;
  540.         case 0x09: PutTAB(); break;
  541.     case 0x0A: PutLF(); break;
  542.         case 0x0B: PutHOME(); break;
  543.     case 0x0C: PutCLS(); break;
  544.         case 0x0D: PutCR(); break;
  545.  
  546.     case 0x12: NextChr(SetDC2); break;
  547.         case 0x13: NextChr(SetDC3); break;
  548.         case 0x15: PutCLS(); break;
  549.     case 0x16: PutCLS(); break;
  550.  
  551.     case 0x1B: NextChr(EscCom); break;
  552.  
  553.     case 0x1C: CurRit(); break;
  554.         case 0x1D: CurLft(); break;
  555.         case 0x1E: CurUp(); break;
  556.         case 0x1F: CurDwn(); break;
  557.  
  558.         default: PutChr(0xC0|COLOR,ch); break;
  559.     }
  560. }
  561. void    PutChr(att,ch)
  562. int     att,ch;
  563. {
  564.     UCHAR far *p;
  565.  
  566.     if ( (att & 0xC0) == 0xC0 )
  567.     att &= 0x3F;
  568.     else if ( ch < ' ' || ch == 0x7f ) {
  569.     if ( (att & 0x40) == 0 && (Con_mode & 0x80) != 0 ) {
  570.         PutCnt(ch);
  571.         return;
  572.     }
  573.     }
  574.  
  575.     SEGSET(p,CVRAM);
  576.     OFFSET(p,(CUR_X * 2 + (MAX_X * 2) * CUR_Y));
  577.     *p = ch; *(p+1) = att;
  578.     if ( (att & 0x40) != 0 ) {
  579.     *p = DMYKAN;
  580.     SEGSET(p,KVRAM);
  581.     *p = ch >> 8;
  582.     *(p+1) = ch;
  583.     }    
  584.     if ( ++CUR_X >= SCR_X ) {
  585.         CUR_X = 0;
  586.     if ( ++CUR_Y >= SCR_Y ) {
  587.             CUR_Y = SCR_Y - 1;
  588.             Scrool();
  589.         }
  590.     }
  591. }
  592. void    Chr_out(ch)
  593. int     ch;
  594. {
  595.     ch &= 0xff;
  596.  
  597.     if ( EXTFLG != FALSE ) {
  598.     EXTFLG = FALSE;
  599.     (*EXTPRO)(ch);
  600.         return;
  601.     }
  602.     if ( KANMOD != FALSE ) {
  603.         if ( KANCOD != '\0' ) {
  604.             if ( iskanji2(ch) != FALSE ) {
  605.         if ( CUR_X == (SCR_X - 1) ) {
  606.                     PutChr(COLOR,DMYKAN);
  607.                     PutChr(COLOR,DMYKAN);
  608.         } else {
  609.             ch = sjisto((int)((KANCOD << 8) | ch));
  610.             PutChr(0x40|COLOR,ch);
  611.                     PutChr(0xC0|COLOR,DMYKAN);
  612.                 }
  613.             } else {
  614.         PutChr(COLOR,KANCOD);
  615.         PutChr(COLOR,ch);
  616.         }
  617.             KANCOD = '\0';
  618.         return;
  619.         } else if ( iskanji(ch) != FALSE ) {
  620.         KANCOD = ch;
  621.             return;
  622.     }
  623.     }
  624.     PutChr(COLOR,ch);
  625. }
  626. /**************************************************************
  627.  
  628.     CONSOL BIOS (int 91h) 
  629.  
  630. ***************************************************************/
  631. void    VDB_00()    /* 初期化 */
  632. {
  633.     SCR_Y = MAX_Y - 1;
  634.     CUR_DSP_FLG = 0;
  635.     Con_mode = 0xCE;
  636.     CUR_X = CUR_Y = 0;
  637.     COLOR = 7;
  638.     colset(0,COLOR,(MAX_X * 2) * MAX_Y);
  639. }
  640. void    VDB_01(){}    /* 画面の表示制御 */
  641.  
  642. void    VDB_02()    /* 全画面消去 */
  643. {
  644.     colset(0,DEFCOL,(MAX_X * 2) * MAX_Y);
  645.     CUR_X = CUR_Y = 0;
  646. }
  647. void     VDB_03()    /* 表示画面サイズの設定 */
  648. {
  649. /*  SCR_X = x; */
  650.     if ( (SCR_Y = *HIGH(ureg.r_dx)) > MAX_Y )
  651.     SCR_Y = MAX_Y;
  652.     if ( (Con_mode & 0x40) != 0 )
  653.     SCR_Y - 1;
  654. }
  655. void     VDB_04()    /* 表示画面サイズの読み取り */
  656. {
  657.     *LOW(ureg.r_dx) = SCR_X;
  658.     *HIGH(ureg.r_dx) = SCR_Y;
  659. }
  660. void    VDB_05()    /* 表示画面サイズレパ-トリの読み取り */
  661. {
  662.     char far *p;
  663.  
  664.     SEGSET(p,ureg.r_ds);
  665.     OFFSET(p,ureg.r_di);
  666.  
  667.     if ( *(p++) < 4 )
  668.     return;
  669.     *(p++) = 1;
  670.     *(p++) = 80;
  671.     *(p++) = 25;
  672. }
  673. void     VDB_06()    /* アトリビュート機能範囲の読み取り */
  674. {
  675.     char far *p;
  676.  
  677.     SEGSET(p,ureg.r_ds);
  678.     OFFSET(p,ureg.r_di);
  679.     *(p++) = 0x03;    /* 漢字識別可能 */
  680.     *(p++) = 0x38;    /* リバ-ス & 強調 */
  681.     *(p++) = 0x07;    /* 最大色数 */
  682.     *p = 0;
  683. }
  684. void    VDB_07()    /* フォントパタ-ンの取り出し */
  685. {
  686.     int     i;
  687.     char    *fp;
  688.     char far *p;
  689.  
  690.     SEGSET(p,ureg.r_ds);
  691.     OFFSET(p,ureg.r_di);
  692.  
  693.     if ( *HIGH(ureg.r_bx) == 0 ) {    /* ANK 8x8 or 8x16 */
  694.     if ( *HIGH(ureg.r_dx) != 8 )
  695.         goto ERROR;
  696.     else if ( *LOW(ureg.r_dx) == 8 ) {
  697.         fp = ankfont + *LOW(ureg.r_bx) * 16;
  698.         for ( i = 0 ; i < 8 ; i++ )
  699.         *(p++) = *(fp++) | *(fp++);
  700.         return;
  701.     } else if ( *LOW(ureg.r_dx) == 16 ) {
  702.         fp = ankfont + *LOW(ureg.r_bx) * 16;
  703.         for ( i = 0 ; i < 16 ; i++ )
  704.         *(p++) = *(fp++);
  705.         return;
  706.     } else
  707.         goto ERROR;
  708.     } else if ( ureg.r_dx == 0x1010 ) {    /* Kanji 16x16 */
  709.         outp(0xFF94,*LOW(ureg.r_bx));
  710.         outp(0xFF95,*HIGH(ureg.r_bx));
  711.     for ( i = 0 ; i < 16 ; i++ ) {
  712.         *(p++) = inp(0xFF96);
  713.         *(p++) = inp(0xFF97);
  714.     }
  715.     return;
  716.     }
  717. ERROR:
  718.     *HIGH(ureg.r_ax) = 0x02;
  719.     ureg.r_cf |= 0x0001;
  720. }
  721. void    VDB_08(){}    /* 外字パタ-ンの登録 */
  722. void    VDB_09(){}    /* カ-ソル形状の設定 */
  723. void    VDB_0A(){}    /* カ-ソル形状の読み取り */
  724.  
  725. void    VDB_0B()    /* カ-ソル表示状態の設定 */ 
  726. {
  727.     CUR_DSP_FLG = *LOW(ureg.r_ax);
  728. }
  729. void    VDB_0C()    /* カ-ソル表示状態の読み取り */
  730. {
  731.     *LOW(ureg.r_ax) = CUR_DSP_FLG;
  732. }
  733. void    VDB_0D()    /* カーソル位置の指定 */
  734. {
  735.     CUR_X = *LOW(ureg.r_dx) - 1;
  736.     CUR_Y = *HIGH(ureg.r_dx) - 1;
  737.     if ( CUR_X < 0 ) CUR_X = 0;
  738.     if ( CUR_X >= SCR_X ) CUR_X = SCR_X - 1;
  739.     if ( CUR_Y < 0 ) CUR_Y = 0;
  740.     if ( CUR_Y >= SCR_Y ) CUR_Y = SCR_Y - 1;
  741. }
  742. void     VDB_0E()    /* カーソル位置の読み取り */
  743. {
  744.     *LOW(ureg.r_dx) = CUR_X + 1;
  745.     *HIGH(ureg.r_dx) = CUR_Y + 1;
  746. }
  747. void    VDB_0F()    /* アトリビュートの設定 */
  748. {
  749.     int    at,x,y;
  750.     char   far *p;
  751.     UCHAR  far *vp;
  752.  
  753.     x = *LOW(ureg.r_dx) - 1;
  754.     y = *HIGH(ureg.r_dx) - 1;
  755.     SEGSET(vp,CVRAM);
  756.     OFFSET(vp,(x * 2 + (MAX_X * 2) * y + 1));
  757.     SEGSET(p,ureg.r_ds);
  758.     OFFSET(p,(ureg.r_di + 1));
  759.     at = *vp & 0xC0;
  760.     *vp = at | (*p & 0x38) | (*(p+1) & 0x07);
  761. }
  762. void    VDB_10()    /* アトリビュートの読み取り */
  763. {
  764.     int    at,x,y;
  765.     char   far *p;
  766.     UCHAR  far *vp;
  767.  
  768.     x = *LOW(ureg.r_dx) - 1;
  769.     y = *HIGH(ureg.r_dx) - 1;
  770.     SEGSET(vp,CVRAM);
  771.     OFFSET(vp,(x * 2 + (MAX_X * 2) * y + 1));
  772.     SEGSET(p,ureg.r_ds);
  773.     OFFSET(p,ureg.r_di);
  774.     if ( (*vp & 0x40) != 0 )
  775.     *p = 0x01;
  776.     else if ( x > 0 && (*(vp-2) & 0x40) != 0 ) {
  777.     *p = 0x03;
  778.     vp -= 2;
  779.     } else
  780.     *p = 0x00;
  781.  
  782.     *(++p) = *vp & 0x38;
  783.     *(++p) = *vp & 0x07;
  784. }
  785. void    VDB_11()    /* デフォルトアトリビュ-トの設定 */
  786. {
  787.     char far *p;
  788.  
  789.     SEGSET(p,ureg.r_ds);
  790.     OFFSET(p,ureg.r_di);
  791.     DEFCOL = (*(++p) & 0x38);
  792.     DEFCOL |= (*(++p) & 0x07);
  793. }
  794. void    VDB_12()    /* デフォルトアトリビュ-トの読み取り */
  795. {
  796.     char far *p;
  797.  
  798.     SEGSET(p,ureg.r_ds);
  799.     OFFSET(p,ureg.r_di);
  800.     *(++p) = DEFCOL & 0x38;
  801.     *(++p) = DEFCOL & 0x07;
  802. }
  803. void    VDB_13()    /* 文字設定 */
  804. {
  805.     int    ch,x,y;
  806.     UCHAR  far *vp;
  807.  
  808.     x = *LOW(ureg.r_dx) - 1;
  809.     y = *HIGH(ureg.r_dx) - 1;
  810.     ch = *LOW(ureg.r_bx);
  811.     SEGSET(vp,CVRAM);
  812.     OFFSET(vp,(x * 2 + (MAX_X * 2) * y));
  813.     *(vp++) = ch;
  814.     if ( *LOW(ureg.r_ax) != 1 )
  815.     *vp = DEFCOL;
  816.     else
  817.     *vp &= 0x3F;
  818.     if ( *HIGH(ureg.r_bx) == 0x01 )
  819.     *vp |= 0x40;
  820.     else if ( *HIGH(ureg.r_bx) == 0x03 ) {
  821.     ch |= (*(vp-3) << 8);
  822.     *(vp-1) = *(vp-3) = DMYKAN;
  823.         SEGSET(vp,KVRAM);
  824.     *(vp-3) = ch >> 8;
  825.     *(vp-2) = ch;
  826.     }
  827. }
  828. void    VDB_14()    /* 文字読み取り */
  829. {
  830.     int    at,x,y;
  831.     UCHAR  far *vp;
  832.  
  833.     x = *LOW(ureg.r_dx) - 1;
  834.     y = *HIGH(ureg.r_dx) - 1;
  835.     SEGSET(vp,CVRAM);
  836.     OFFSET(vp,(x * 2 + (MAX_X * 2) * y));
  837.     if ( (*(vp+1) & 0x40) != 0 ) {
  838.     *HIGH(ureg.r_bx) = 0x01;
  839.         SEGSET(vp,KVRAM);
  840.         *LOW(ureg.r_bx) = *vp;
  841.     } else if ( x > 0 && (*(vp-1) & 0x40) != 0 ) {
  842.     *HIGH(ureg.r_bx) = 0x03;
  843.         SEGSET(vp,KVRAM);
  844.         *LOW(ureg.r_bx) = *(vp-1);
  845.     } else {
  846.     *HIGH(ureg.r_bx) = 0x00;
  847.         *LOW(ureg.r_bx) = *vp;
  848.     }
  849. }
  850. void    VDB_15()    /* 矩形域設定 */
  851. {
  852.     int     cx,ch;
  853.     int     x1,y1,x2,y2;
  854.     int     x,y,sx,sy;
  855.     UNSIG far *p;
  856.     UCHAR far *cp;
  857.     UCHAR far *ap;
  858.     UCHAR far *sp;
  859.     UCHAR far *vp;
  860.  
  861.     if ( (x1 = *LOW(ureg.r_dx)-1) >= MAX_X || x1 < 0)
  862.     goto ERROR;
  863.     if ( (y1 = *HIGH(ureg.r_dx)-1) >= SCR_Y || y1 < 0 )
  864.     goto ERROR;
  865.     if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
  866.     goto ERROR;
  867.     if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
  868.     goto ERROR;
  869.     sx = x2 - x1; sy = y2 - y1;
  870.     if ( sx <= 0 || sy <= 0 )
  871.     goto ERROR;
  872.     SEGSET(sp,CVRAM);
  873.     OFFSET(sp,(x1 * 2 + (MAX_X * 2) * y1));
  874.  
  875.     OFFSET(p,ureg.r_di);
  876.     SEGSET(p,ureg.r_ds);
  877.  
  878.     OFFSET(cp,*(p++));
  879.     SEGSET(cp,*(p++));
  880.  
  881.     OFFSET(ap,*(p++));
  882.     SEGSET(ap,*(p++));
  883.  
  884.     for ( y = 0 ; y < sy ; y++ ) {
  885.     for ( x = 0,vp = sp ; x < sx ; x++ ) {
  886.         *(vp++) = *(cp++);
  887.         if ( *(ap++) == 0x03 ) {
  888.         *(vp-2) |= 0x40;
  889.         ch = *(vp-3) << 8 | *(vp-1);
  890.         SEGSET(vp,KVRAM);
  891.         *(vp-3) = ch >> 8;
  892.         *(vp-2) = ch;
  893.         SEGSET(vp,CVRAM);
  894.         } else
  895.         *vp &= 0x3F;
  896.         if ( *LOW(ureg.r_ax) == 1 ) {
  897.         *vp = *(ap++) & 0x38;
  898.         *vp |= *(ap++) & 0x07; ap++;
  899.         }
  900.         vp++;
  901.     }
  902.     sp += (MAX_X * 2);
  903.     }
  904.     return;
  905. ERROR:
  906.     *HIGH(ureg.r_ax) = 0x02;
  907.     ureg.r_cf |= 0x0001;
  908. }
  909. void    VDB_16()        /* 矩形域読み取り */
  910. {
  911.     int     i;
  912.     int     x1,y1,x2,y2;
  913.     int     x,y,sx,sy;
  914.     UNSIG far *p;
  915.     UCHAR far *cp;
  916.     UCHAR far *ap;
  917.     UCHAR far *sp;
  918.     UCHAR far *vp;
  919.  
  920.     if ( (x1 = *LOW(ureg.r_dx)-1) >= MAX_X || x1 < 0)
  921.     goto ERROR;
  922.     if ( (y1 = *HIGH(ureg.r_dx)-1) >= SCR_Y || y1 < 0 )
  923.     goto ERROR;
  924.     if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
  925.     goto ERROR;
  926.     if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
  927.     goto ERROR;
  928.     sx = x2 - x1; sy = y2 - y1;
  929.     if ( sx <= 0 || sy <= 0 )
  930.     goto ERROR;
  931.     SEGSET(sp,CVRAM);
  932.     OFFSET(sp,(x1 * 2 + (MAX_X * 2) * y1));
  933.  
  934.     OFFSET(p,ureg.r_di);
  935.     SEGSET(p,ureg.r_ds);
  936.  
  937.     OFFSET(cp,*(p++));
  938.     SEGSET(cp,*(p++));
  939.  
  940.     OFFSET(ap,*(p++));
  941.     SEGSET(ap,*(p++));
  942.  
  943.     for ( y = 0 ; y < sy ; y++ ) {
  944.     for ( x = 0,vp = sp ; x < sx ; x++ ) {
  945.         *(cp++) = *(vp++);
  946.         if ( (*vp & 0x40) != 0 ) {
  947.         *(ap++) = 0x01;
  948.         SEGSET(vp,KVRAM);
  949.         *(cp-1) = *(vp-1);
  950.         SEGSET(vp,CVRAM);
  951.         } else if ( x > 0 && (*(vp-2) & 0x40) != 0 ) {
  952.         *(ap++) = 0x03;
  953.         SEGSET(vp,KVRAM);
  954.         *(cp-1) = *(vp-2);
  955.         SEGSET(vp,CVRAM);
  956.         } else
  957.         *(ap++) = 0x00;
  958.         if ( *LOW(ureg.r_ax) == 1 ) {
  959.         *(ap++) = *vp & 0x38;
  960.         *(ap++) = *vp & 0x07; ap++;
  961.         }
  962.         vp++;
  963.     }
  964.     sp += (MAX_X * 2);
  965.     }
  966.     return;
  967. ERROR:
  968.     *HIGH(ureg.r_ax) = 0x02;
  969.     ureg.r_cf |= 0x0001;
  970. }
  971. void    VDB_17()    /* 矩形域複写 */
  972. {
  973.     int     i;
  974.     int     x1,y1,x2,y2,x3,y3;
  975.     int     sx,sy;
  976.     UNSIG   sp;
  977.     UNSIG   dp;
  978.  
  979.     if ( (x1 = *LOW(ureg.r_dx) - 1) >= MAX_X || x1 < 0 )
  980.     goto ERROR;
  981.     if ( (y1 = *HIGH(ureg.r_dx) - 1) >= SCR_Y || y1 < 0 )
  982.     goto ERROR;
  983.     if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
  984.     goto ERROR;
  985.     if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
  986.     goto ERROR;
  987.     if ( (x3 = *LOW(ureg.r_cx) - 1) >= MAX_X || x3 < 0 )
  988.     goto ERROR;
  989.     if ( (y3 = *HIGH(ureg.r_cx) - 1) >= SCR_Y || y3 < 0 )
  990.     goto ERROR;
  991.     sx = x2 - x1; sy = y2 - y1;
  992.     if ( sx <= 0 || sy <= 0 )
  993.     goto ERROR;
  994.     if ( (x3 + sx) > MAX_X || (y3 + sy) > SCR_Y )
  995.     goto ERROR;
  996.  
  997.     if ( sp < dp ) {
  998.     sp = (x2 - 1) * 2 + (MAX_X * 2) * (y2 - 1);
  999.     dp = (x3 + sx - 1) * 2 + (MAX_X * 2) * (y3 + sy - 1);
  1000.     for ( i = 0 ; i < sy ; i++ ) {
  1001.         vramrcpy(dp,sp,sx * 2);
  1002.         sp -= (MAX_X * 2);
  1003.         dp -= (MAX_X * 2);
  1004.     }
  1005.     } else {
  1006.     sp = x1 * 2 + (MAX_X * 2) * y1;
  1007.     dp = x3 * 2 + (MAX_X * 2) * y3;
  1008.     for ( i = 0 ; i < sy ; i++ ) {
  1009.         vramcpy(dp,sp,sx * 2);
  1010.         sp += (MAX_X * 2);
  1011.         dp += (MAX_X * 2);
  1012.     }
  1013.     }
  1014.     return;
  1015. ERROR:
  1016.     *HIGH(ureg.r_ax) = 0x02;
  1017.     ureg.r_cf |= 0x0001;
  1018. }
  1019. void    VDB_18()    /* 矩形域消去 */
  1020. {
  1021.     int     i;
  1022.     int     x1,y1,x2,y2;
  1023.     int     sx,sy;
  1024.     UNSIG   sp;
  1025.  
  1026.     if ( (x1 = *LOW(ureg.r_dx) - 1) >= MAX_X || x1 < 0 )
  1027.     goto ERROR;
  1028.     if ( (y1 = *HIGH(ureg.r_dx) - 1) >= SCR_Y || y1 < 0 )
  1029.     goto ERROR;
  1030.     if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
  1031.     goto ERROR;
  1032.     if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
  1033.     goto ERROR;
  1034.     sx = x2 - x1; sy = y2 - y1;
  1035.     if ( sx <= 0 || sy <= 0 )
  1036.     goto ERROR;
  1037.     sp = (x1 * 2 + (MAX_X * 2) * y1);
  1038.  
  1039.     for ( i = 0 ; i < sy ; i++ ) {
  1040.     colset(sp,DEFCOL,sx * 2);
  1041.     sp += (MAX_X * 2);
  1042.     }
  1043.     return;
  1044. ERROR:
  1045.     *HIGH(ureg.r_ax) = 0x02;
  1046.     ureg.r_cf |= 0x0001;
  1047. }
  1048. void    VDB_19()    /* 全画面スクロ-ル */ 
  1049. {
  1050.     int     cx,i;
  1051.     UNSIG   vp;
  1052.  
  1053.     if ( (cx = ureg.r_cx) == 0 || cx > SCR_Y )
  1054.     cx = SCR_Y;
  1055.     for ( ; cx > 0 ; cx-- ) {
  1056.     switch(*LOW(ureg.r_ax)) {
  1057.         case 1:    /* 下方向 */
  1058.         i = (MAX_X * 2) * (SCR_Y - 1);
  1059.         vramrcpy(i + (MAX_X * 2 - 2),i - 2,i);
  1060.         colset(0,DEFCOL,(MAX_X * 2));
  1061.         break;
  1062.         case 2:    /* 右方向 */
  1063.         i = (MAX_X * 2) * SCR_Y - 2;
  1064.         vramrcpy(i,i - 2,i);
  1065.         vp = 0;
  1066.         for ( i = 0 ; i < SCR_Y ; i++ ) {
  1067.             colset(vp,DEFCOL,2);
  1068.             vp += (MAX_X * 2);
  1069.         }
  1070.         break;
  1071.         case 3:    /* 左方向 */
  1072.         vramcpy(0,2,(MAX_X * 2) * SCR_Y - 2);
  1073.         vp = (MAX_X * 2) - 2;
  1074.         for ( i = 0 ; i < SCR_Y ; i++ ) {
  1075.             colset(vp,DEFCOL,2);
  1076.             vp += (MAX_X * 2);
  1077.         }
  1078.         break;
  1079.             default:     /* case 0 上方向 */
  1080.         vramcpy(0,(MAX_X * 2),(MAX_X * 2) * (SCR_Y - 1));
  1081.         colset((MAX_X * 2) * (SCR_Y - 1),DEFCOL,(MAX_X * 2));
  1082.         break;
  1083.     }
  1084.     }
  1085. }
  1086. void    VDB_1A()    /* 部分スクロ-ル */
  1087. {
  1088.     int     cx,i;
  1089.     int     x1,y1,x2,y2;
  1090.     int     sx,sy;
  1091.     UNSIG   sp;
  1092.     UNSIG   vp;
  1093.  
  1094.     if ( (x1 = *LOW(ureg.r_dx) - 1) >= MAX_X || x1 < 0 )
  1095.     goto ERROR;
  1096.     if ( (y1 = *HIGH(ureg.r_dx) - 1) >= SCR_Y || y1 < 0 )
  1097.     goto ERROR;
  1098.     if ( (x2 = *LOW(ureg.r_bx)) > MAX_X )
  1099.     goto ERROR;
  1100.     if ( (y2 = *HIGH(ureg.r_bx)) > SCR_Y )
  1101.     goto ERROR;
  1102.     sx = x2 - x1; sy = y2 - y1;
  1103.     if ( sx <= 0 || sy <= 0 )
  1104.     goto ERROR;
  1105.     sp = (x1 * 2 + (MAX_X * 2) * y1);
  1106.  
  1107.     if ( (cx = ureg.r_cx) == 0 || cx > sy )
  1108.     cx = sy;
  1109.     for ( ; cx > 0 ; cx-- ) {
  1110.     switch(*LOW(ureg.r_ax)) {
  1111.         case 1:    /* 下方向 */
  1112.         vp = sp + (MAX_X * 2) * (sy - 1);
  1113.         for ( i = 0 ; i < (sy-1) ; i++ ) {
  1114.             vramcpy(vp,vp - (MAX_X * 2),sx * 2);
  1115.             vp -= (MAX_X * 2);
  1116.         }
  1117.         colset(sp,DEFCOL,sx * 2);
  1118.         break;
  1119.         case 2:    /* 右方向 */
  1120.         vp = sp + (sx * 2) - 2;
  1121.         for ( i = 0 ; i < sy ; i++ ) {
  1122.             vramrcpy(vp,vp - 2,sx * 2 - 2);
  1123.             vp += (MAX_X * 2);
  1124.         }
  1125.         vp = sp;
  1126.         for ( i = 0 ; i < sy ; i++ ) {
  1127.             colset(vp,DEFCOL,2);
  1128.             vp += (MAX_X * 2);
  1129.         }
  1130.         break;
  1131.         case 3:    /* 左方向 */
  1132.         vp = sp;
  1133.         for ( i = 0 ; i < sy ; i++ ) {
  1134.             vramcpy(vp,vp + 2,sx * 2 - 2);
  1135.             vp += (MAX_X * 2);
  1136.         }
  1137.         vp = sp + (sx * 2) - 2;
  1138.         for ( i = 0 ; i < sy ; i++ ) {
  1139.             colset(vp,DEFCOL,2);
  1140.             vp += (MAX_X * 2);
  1141.         }
  1142.         break;
  1143.             default:     /* case 0 上方向 */
  1144.         for ( vp = sp,i = 0 ; i < (sy-1) ; i++ ) {
  1145.             vramcpy(vp,vp + (MAX_X * 2),sx * 2);
  1146.             vp += (MAX_X * 2);
  1147.         }
  1148.         colset(vp,DEFCOL,sx * 2);
  1149.         break;
  1150.     }
  1151.     }
  1152.     return;
  1153. ERROR:
  1154.     *HIGH(ureg.r_ax) = 0x02;
  1155.     ureg.r_cf |= 0x0001;
  1156. }
  1157. void    VDB_1B()    /* コンソ-ル機能の設定 */
  1158. {
  1159.     int     i;
  1160.  
  1161.     i = Con_mode;
  1162.     Con_mode = (*LOW(ureg.r_ax) & 0xC7) | 0x08;
  1163.     if ( (i & 0x40) != (Con_mode & 0x40) ) {
  1164.     if ( (Con_mode & 0x40) != 0 )
  1165.         SCR_Y--;
  1166.     else
  1167.         SCR_Y++;
  1168.     }
  1169. }
  1170. void    VDB_1C()    /* コンソ-ル機能の読み取り */
  1171. {
  1172.     *LOW(ureg.r_ax) = Con_mode;
  1173. }
  1174. void    VDB_1D()    /* 文字の出力 */
  1175. {
  1176.     Chr_out(*LOW(ureg.r_ax));
  1177. }
  1178. void    VDB_1E()    /* 文字列の出力 */
  1179. {
  1180.     int     i;
  1181.     UCHAR far *p;
  1182.  
  1183.     SEGSET(p,ureg.r_ds);
  1184.     OFFSET(p,ureg.r_di);
  1185.     for ( i = ureg.r_cx ; i > 0 ; i-- )
  1186.     Chr_out(*(p++));
  1187. }
  1188. void    VDB_1F()    /* システム行書き込み */
  1189. {
  1190.     int    ch,cx,at,md;
  1191.     UNSIG far *p;
  1192.     UCHAR far *cp;
  1193.     UCHAR far *ap;
  1194.     UCHAR far *vp;
  1195.  
  1196.     if ( (Con_mode & 0x40) == 0 )
  1197.     return;
  1198.  
  1199.     OFFSET(p,ureg.r_di);
  1200.     SEGSET(p,ureg.r_ds);
  1201.  
  1202.     OFFSET(cp,*(p++));
  1203.     SEGSET(cp,*(p++));
  1204.  
  1205.     OFFSET(ap,*(p++));
  1206.     SEGSET(ap,*(p++));
  1207.  
  1208.     cx = ureg.r_cx;
  1209.     OFFSET(vp,CVRAM);
  1210.     SEGSET(vp,*LOW(ureg.r_dx) * 2 + (MAX_X * 2) * SCR_Y);
  1211.  
  1212.     for ( ; cx > 0 ; cx-- ) {
  1213.     *(vp++) = *(cp++);
  1214.     if ( *LOW(ureg.r_ax) != 1 ) {
  1215.         at = DEFCOL;
  1216.         md = *(ap++);
  1217.     } else {
  1218.         md = *(ap++);
  1219.         at = *(ap++) & 0x38;
  1220.         at |= (*(ap++) & 0x07); ap++;
  1221.     }
  1222.     *(vp++) = at;
  1223.     if ( md == 0x03 ) {
  1224.         ch = (*(vp-4) << 8) | *(vp-2);
  1225.         *(vp-4) = *(vp-2) = DMYKAN;
  1226.         *(vp-3) |= 0x40;
  1227.         SEGSET(vp,KVRAM);
  1228.         *(vp-4) = ch >> 8;
  1229.         *(vp-3) = ch;
  1230.         SEGSET(vp,CVRAM);
  1231.     }
  1232.     }
  1233. }
  1234. void    VDB_20()    /* 背景色の読み取り */
  1235. {
  1236.     ureg.r_dx = BAKCOL;
  1237. }
  1238. void    BIOS_91()
  1239. {
  1240.     int    cm;
  1241.     static void (*VDB_table[])()={
  1242.     VDB_00,    VDB_01,    VDB_02,    VDB_03,    VDB_04,    VDB_05,    VDB_06,    VDB_07,
  1243.     VDB_08,    VDB_09,    VDB_0A,    VDB_0B,    VDB_0C,    VDB_0D,    VDB_0E,    VDB_0F,
  1244.     VDB_10,    VDB_11,    VDB_12,    VDB_13,    VDB_14,    VDB_15,    VDB_16,    VDB_17,
  1245.     VDB_18,    VDB_19,    VDB_1A,    VDB_1B,    VDB_1C,    VDB_1D,    VDB_1E,    VDB_1F,
  1246.     VDB_20 };
  1247.  
  1248.     if ( (cm = *HIGH(ureg.r_ax)) <= 0x20 ) {
  1249.     *HIGH(ureg.r_ax) = 0;
  1250.     ureg.r_cf &= 0xFFFE;
  1251.     (*VDB_table[cm])();
  1252.     } else {
  1253.         *HIGH(ureg.r_ax) = 0x01;
  1254.         ureg.r_cf |= 0x0001;
  1255.     }
  1256. }
  1257. void    cflush()
  1258. {
  1259.     int    ch,x,y;
  1260.     register UCHAR  *dp;
  1261.     UCHAR far *cp;
  1262.     SHORT far *kp;
  1263.  
  1264.     SEGSET(cp,CVRAM);
  1265.     OFFSET(cp,0);
  1266.     SEGSET(kp,KVRAM);
  1267.     OFFSET(kp,0);
  1268.     dp = dmy_ram;
  1269.     for ( y = 0 ; y < MAX_Y ; y++ ) {
  1270.     for ( x = 0 ; x < MAX_X ; x++,dp+=2,cp+=2,kp++ ) {
  1271.         if ( (*(cp+1) & 0x40) != 0 ) {
  1272.         ch = *dp << 8 | *(dp+2);
  1273.         if ( *(dp+1) != *(cp+1) || ch != *kp ) {
  1274.             *dp = *kp >> 8;
  1275.             *(dp+1) = *(cp+1);
  1276.             *(dp+2) = *kp;
  1277.             *(dp+3) = *(cp+1) & 0x3F;
  1278.             Wrt_Kan(*(dp+2) << 8 | *(dp),x,y,*(cp+1));
  1279.         }
  1280.         x++; dp+=2; cp+=2; kp++;
  1281.         continue;
  1282.         } else if ( *dp != *cp || *(dp+1) != *(cp+1) ) {
  1283.         *dp = *cp;
  1284.         *(dp+1) = *(cp+1);
  1285.             Wrt_Ank(*dp,x,y,*(dp+1));
  1286.         }
  1287.     }
  1288.     }
  1289.     if ( CUR_DSP_FLG == 0 ) {
  1290.         dp = dmy_ram + CUR_X * 2 + (MAX_X * 2) * CUR_Y + 1;
  1291.         *dp ^= 0x10;
  1292.         locate(CUR_X,CUR_Y);
  1293.     }
  1294. }
  1295. void    main(argc,argv)
  1296. int    argc;
  1297. char    *argv[];
  1298. {
  1299.     int     i;
  1300.     char    *arg[10];
  1301.  
  1302.     for ( i = 0 ; i < 10 ; i++ ) {
  1303.     if ( --argc <= 0 )
  1304.         break;
  1305.     arg[i] = argv[i+1];
  1306.     }
  1307.     arg[i] = NULL;
  1308.  
  1309.     VDB_00();
  1310.     setbios();
  1311.     spawnvp(P_WAIT,arg[0],arg);
  1312.     resetbios();
  1313. }
  1314.