Diff for /np2/bios/bios18.c between versions 1.4 and 1.42

version 1.4, 2003/11/15 07:10:02 version 1.42, 2005/03/23 08:07:48
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
 #include        "i286.h"  #include        "cpucore.h"
 #include        "memory.h"  
 #include        "pccore.h"  #include        "pccore.h"
 #include        "iocore.h"  #include        "iocore.h"
   #include        "gdc_sub.h"
 #include        "bios.h"  #include        "bios.h"
 #include        "biosmem.h"  #include        "biosmem.h"
 #include        "font.h"  #include        "font.h"
   
   
 static  int             sti_waiting = 0;  
   
 typedef struct {  typedef struct {
         BYTE    GBON_PTN;          UINT8   GBON_PTN;
         BYTE    GBBCC;          UINT8   GBBCC;
         BYTE    GBDOTU;          UINT8   GBDOTU;
         BYTE    GBDSP;          UINT8   GBDSP;
         BYTE    GBCPC[4];          UINT8   GBCPC[4];
         BYTE    GBSX1[2];          UINT8   GBSX1[2];
         BYTE    GBSY1[2];          UINT8   GBSY1[2];
         BYTE    GBLNG1[2];          UINT8   GBLNG1[2];
         BYTE    GBWDPA[2];          UINT8   GBWDPA[2];
         BYTE    GBRBUF[2][3];          UINT8   GBRBUF[2][3];
         BYTE    GBSX2[2];          UINT8   GBSX2[2];
         BYTE    GBSY2[2];          UINT8   GBSY2[2];
         BYTE    GBMDOT[2];          UINT8   GBMDOT[2];
         BYTE    GBCIR[2];          UINT8   GBCIR[2];
         BYTE    GBLNG2[2];          UINT8   GBLNG2[2];
         BYTE    GBMDOTI[8];          UINT8   GBMDOTI[8];
         BYTE    GBDTYP;          UINT8   GBDTYP;
         BYTE    GBFILL;          UINT8   GBFILL;
 } UCWTBL;  } UCWTBL;
   
 #if 0  
 typedef struct {  typedef struct {
         BYTE    raster;          UINT8   raster;
         BYTE    cfi;          UINT8   pl;
         BYTE    pl;          UINT8   bl;
         BYTE    bl;          UINT8   cl;
         BYTE    cl;  
         BYTE    ssl;  
         BYTE    padding[2];  
 } CRTDATA;  } CRTDATA;
   
 static const CRTDATA crtdata[] = {  static const UINT8 modenum[4] = {3, 1, 0, 2};
                                                 {0x07, 0x3b,    0x00, 0x07, 0x08, 0x00},  
                                                 {0x09, 0x4b,    0x1f, 0x08, 0x08, 0x00},  static const CRTDATA crtdata[7] = {
                                                 {0x0f, 0x7b,    0x00, 0x0f, 0x10, 0x00},                                                  {0x09,  0x1f, 0x08, 0x08},              // 200-20
                                                 {0x13, 0x9b,    0x1e, 0x11, 0x10, 0x00}};                                                  {0x07,  0x00, 0x07, 0x08},              // 200-25
 #endif                                                  {0x13,  0x1e, 0x11, 0x10},              // 400-20
                                                   {0x0f,  0x00, 0x0f, 0x10},              // 400-25
                                                   {0x17,  0x1c, 0x13, 0x10},              // 480-20
                                                   {0x12,  0x1f, 0x11, 0x10},              // 480-25
                                                   {0x0f,  0x00, 0x0f, 0x10}};             // 480-30
   
   static const UINT8 gdcmastersync[6][8] = {
                                   {0x10,0x4e,0x07,0x25,0x0d,0x0f,0xc8,0x94},              // 15
                                   {0x10,0x4e,0x07,0x25,0x07,0x07,0x90,0x65},              // 24
                                   {0x10,0x4e,0x47,0x0c,0x07,0x0d,0x90,0x89},              // 31
                                   {0x10,0x4e,0x4b,0x0c,0x03,0x06,0xe0,0x95},              // 31-480:20
                                   {0x10,0x4e,0x4b,0x0c,0x03,0x0b,0xdb,0x95},              // 31-480:25
                                   {0x10,0x4e,0x4b,0x0c,0x03,0x06,0xe0,0x95}};             // 31-480:30
   
   static const UINT8 gdcslavesync[6][8] = {
                                   {0x02,0x26,0x03,0x11,0x86,0x0f,0xc8,0x94},              // 15-L
                                   {0x02,0x4e,0x4b,0x0c,0x83,0x06,0xe0,0x95},              // 31-H
                                   {0x02,0x26,0x03,0x11,0x83,0x07,0x90,0x65},              // 24-L
                                   {0x02,0x4e,0x07,0x25,0x87,0x07,0x90,0x65},              // 24-M
                                   {0x02,0x26,0x41,0x0c,0x83,0x0d,0x90,0x89},              // 31-L
                                   {0x02,0x4e,0x47,0x0c,0x87,0x0d,0x90,0x89}};             // 31-M
   
   typedef struct {
           UINT8   lr;
           UINT8   cfi;
   } CSRFORM;
   
   static const CSRFORM csrform[4] = {
                                                   {0x07, 0x3b}, {0x09, 0x4b},
                                                   {0x0f, 0x7b}, {0x13, 0x9b}};
   
   static const UINT8 sync200l[8] = {0x02,0x26,0x03,0x11,0x86,0x0f,0xc8,0x94};
   static const UINT8 sync200m[8] = {0x02,0x26,0x03,0x11,0x83,0x07,0x90,0x65};
   static const UINT8 sync400m[8] = {0x02,0x4e,0x07,0x25,0x87,0x07,0x90,0x65};
   
   
 static UINT16 keyget(void) {  static UINT16 keyget(void) {
Line 68  static UINT16 keyget(void) { Line 95  static UINT16 keyget(void) {
         return(0xffff);          return(0xffff);
 }  }
   
 void bios0x18_16(BYTE chr, BYTE atr) {  
   // ---- master
   
   void bios0x18_0a(REG8 mode) {
   
   const CRTDATA   *crt;
   
           gdc_forceready(GDCWORK_MASTER);
   
           gdc.mode1 &= ~(0x2d);
           mem[MEMB_CRT_STS_FLAG] = mode;
           crt = crtdata;
           if (!(np2cfg.dipsw[0] & 1)) {
                   mem[MEMB_CRT_STS_FLAG] |= 0x80;
                   gdc.mode1 |= 0x08;
                   crt += 2;
           }
           if (!(mode & 0x01)) {
                   crt += 1;                                               // 25行
           }
           if (mode & 0x02) {
                   gdc.mode1 |= 0x04;                              // 40桁
           }
           if (mode & 0x04) {
                   gdc.mode1 |= 0x01;                              // アトリビュート
           }
           if (mode & 0x08) {
                   gdc.mode1 |= 0x20;                              // コードアクセス
           }
           mem[MEMB_CRT_RASTER] = crt->raster;
           crtc.reg.pl = crt->pl;
           crtc.reg.bl = crt->bl;
           crtc.reg.cl = crt->cl;
           crtc.reg.ssl = 0;
           gdc_restorekacmode();
           bios0x18_10(0);
   }
   
   void bios0x18_0c(void) {
   
           if (!(gdcs.textdisp & GDCSCRN_ENABLE)) {
                   gdcs.textdisp |= GDCSCRN_ENABLE;
                   screenupdate |= 2;
           }
   }
   
   static void bios0x18_0f(UINT seg, UINT off, REG8 num, REG8 cnt) {
   
           UINT8   *p;
           UINT    raster;
           UINT    t;
   
           SETBIOSMEM16(0x0053e, (UINT16)off);
           SETBIOSMEM16(0x00540, (UINT16)seg);
           mem[0x00547] = num;
           mem[0x0053D] = cnt;
           p = gdc.m.para + GDC_SCROLL + (num << 2);
   
   #if defined(SUPPORT_CRT31KHZ)
           if (mem[MEMB_CRT_BIOS] & 0x80) {
                   raster = (mem[MEMB_CRT_RASTER] + 1) << 4;
           }
           else {
   #endif
                   if (!(mem[MEMB_CRT_STS_FLAG] & 0x01)) {         // 25
                           raster = 8 << 4;
                   }
                   else {                                                                          // 20
                           raster = 16 << 4;
                           }
                   if (mem[MEMB_CRT_STS_FLAG] & 0x80) {
                           raster <<= 1;
                   }
   #if defined(SUPPORT_CRT31KHZ)
           }
   #endif
   
           while((cnt--) && (p < (gdc.m.para + GDC_SCROLL + 0x10))) {
                   t = MEML_READ16(seg, off);
                   t >>= 1;
                   STOREINTELWORD(p, t);
                   t = MEML_READ16(seg, off + 2);
                   t *= raster;
                   STOREINTELWORD(p + 2, t);
                   off += 4;
                   p += 4;
           }
           gdcs.textdisp |= GDCSCRN_ALLDRAW2;
           screenupdate |= 2;
   }
   
   void bios0x18_10(REG8 curdel) {
   
           UINT8   sts;
           UINT    pos;
   
           sts = mem[MEMB_CRT_STS_FLAG];
           mem[MEMB_CRT_STS_FLAG] = sts & (~0x40);
           pos = sts & 0x01;
           if (sts & 0x80) {
                   pos += 2;
           }
           mem[MEMB_CRT_CNT] = (curdel << 5);
           gdc.m.para[GDC_CSRFORM + 0] = csrform[pos].lr;
           gdc.m.para[GDC_CSRFORM + 1] = curdel << 5;
           gdc.m.para[GDC_CSRFORM + 2] = csrform[pos].cfi;
           gdcs.textdisp |= GDCSCRN_ALLDRAW2 | GDCSCRN_EXT;
   }
   
   REG16 bios0x18_14(REG16 seg, REG16 off, REG16 code) {
   
           UINT16  size;
   const UINT8     *p;
           UINT8   buf[32];
           UINT    i;
   
           switch(code >> 8) {
                   case 0x00:                      // 8x8
                           size = 0x0101;
                           MEML_WRITE16(seg, off, 0x0101);
                           p = fontrom + 0x82000 + ((code & 0xff) << 4);
                           MEML_WRITESTR(seg, off + 2, p, 8);
                           break;
   
   //              case 0x28:
                   case 0x29:                      // 8x16 KANJI
                   case 0x2a:
                   case 0x2b:
                           size = 0x0102;
                           MEML_WRITE16(seg, off, 0x0102);
                           p = fontrom;
                           p += (code & 0x7f) << 12;
                           p += (((code >> 8) - 0x20) & 0x7f) << 4;
                           MEML_WRITESTR(seg, off + 2, p, 16);
                           break;
   
                   case 0x80:                      // 8x16 ANK
                           size = 0x0102;
                           p = fontrom + 0x80000 + ((code & 0xff) << 4);
                           MEML_WRITESTR(seg, off + 2, p, 16);
                           break;
   
                   default:
                           size = 0x0202;
                           p = fontrom;
                           p += (code & 0x7f) << 12;
                           p += (((code >> 8) - 0x20) & 0x7f) << 4;
                           for (i=0; i<16; i++, p++) {
                                   buf[i*2+0] = *p;
                                   buf[i*2+1] = *(p+0x800);
                           }
                           MEML_WRITESTR(seg, off + 2, buf, 32);
                           break;
           }
           MEML_WRITE16(seg, off, size);
           return(size);
   }
   
   static void bios0x18_1a(REG16 seg, REG16 off, REG16 code) {
   
           UINT8   *p;
           UINT8   buf[32];
           UINT    i;
   
           if (((code >> 8) & 0x7e) == 0x76) {
                   MEML_READSTR(seg, off + 2, buf, 32);
                   p = fontrom;
                   p += (code & 0x7f) << 12;
                   p += (((code >> 8) - 0x20) & 0x7f) << 4;
                   for (i=0; i<16; i++, p++) {
                           *p = buf[i*2+0];
                           *(p+0x800) = buf[i*2+1];
                   }
                   cgwindow.writable |= 0x80;
           }
   }
   
   void bios0x18_16(REG8 chr, REG8 atr) {
   
         UINT32  i;          UINT32  i;
   
Line 82  void bios0x18_16(BYTE chr, BYTE atr) { Line 286  void bios0x18_16(BYTE chr, BYTE atr) {
         gdcs.textdisp |= GDCSCRN_ALLDRAW;          gdcs.textdisp |= GDCSCRN_ALLDRAW;
 }  }
   
 #define SWAPU16(a, b) { UINT16 tmp; tmp = (a); (a) = (b); (b) = tmp; }  
   
 static void bios18_47(void) {  // ---- 31khz
   
   #if defined(SUPPORT_CRT31KHZ)
   static REG8 bios0x18_30(REG8 rate, REG8 scrn) {
   
           int                     crt;
           int                     master;
           int                     slave;
   const CRTDATA   *p;
   
           if (((rate & 0xf8) != 0x08) || (scrn & (~0x33)) || ((scrn & 3) == 3)) {
                   return(0);
           }
           if ((scrn & 0x30) == 0x30) {                            // 640x480
   #if defined(SUPPORT_PC9821)
                   if (rate & 4) {
                           gdc_analogext(TRUE);
                           mem[MEMB_PRXDUPD] |= 0x80;
                           crt = 4;
                           master = 3 + (scrn & 3);
                           slave = 1;
                           gdc.analog |= (1 << GDCANALOG_256E);
                   }
                   else
   #endif
                   return(0);
           }
           else {
                   if ((scrn & 3) >= 2) {
                           return(0);
                   }
                   if (rate & 4) {                                                 // 31khz
                           crt = 2;
                           master = 2;
                           slave = 4;
                   }
                   else if (mem[MEMB_PRXCRT] & 0x40) {             // 24khz
                           crt = 2;
                           master = 1;
                           slave = 2;
                   }
                   else {
                           crt = 0;
                           master = 0;
                           slave = 0;
                   }
                   if ((scrn & 0x20) && (mem[MEMB_PRXDUPD] & 0x04)) {
                           slave += 1;
                   }
   #if defined(SUPPORT_PC9821)
                   else {
                           gdc_analogext(FALSE);
                           mem[MEMB_PRXDUPD] &= ~0x80;
                   }
                   gdc.analog &= ~(1 << (GDCANALOG_256E));
   #endif
           }
           crt += (scrn & 3);
   
           if (rate & 4) {
                   gdc.display |= (1 << GDCDISP_31);
           }
           else {
                   gdc.display &= ~(1 << GDCDISP_31);
           }
   
           CopyMemory(gdc.m.para + GDC_SYNC, gdcmastersync[master], 8);
           ZeroMemory(gdc.m.para + GDC_SCROLL, 4);
           gdc.m.para[GDC_PITCH] = 80;
   
           p = crtdata + crt;
           gdc.m.para[GDC_CSRFORM + 0] = p->raster;
           gdc.m.para[GDC_CSRFORM + 1] = 0;
           gdc.m.para[GDC_CSRFORM + 2] = (p->raster << 3) + 3;
           crtc.reg.pl = p->pl;
           crtc.reg.bl = p->bl;
           crtc.reg.cl = p->cl;
           crtc.reg.ssl = 0;
           crtc.reg.sur = 1;
           crtc.reg.sdr = 0;
   
           CopyMemory(gdc.s.para + GDC_SYNC, gdcslavesync[slave], 8);
           ZeroMemory(gdc.s.para + GDC_SCROLL, 4);
           if (slave & 1) {
                   gdc.s.para[GDC_PITCH] = 80;
                   gdc.clock |= 3;
                   mem[MEMB_PRXDUPD] |= 0x04;
                   gdc.s.para[GDC_SCROLL+3] = 0x40;
           }
           else {
                   gdc.s.para[GDC_PITCH] = 40;
                   gdc.clock &= ~3;
                   mem[MEMB_PRXDUPD] &= ~0x04;
           }
           if ((scrn & 0x30) == 0x10) {
                   gdc.s.para[GDC_SCROLL+0] = (200*40) & 0xff;
                   gdc.s.para[GDC_SCROLL+1] = (200*40) >> 8;
           }
           if ((scrn & 0x20) || (!(mem[MEMB_PRXCRT] & 0x40))) {
                   gdc.mode1 &= ~(0x10);
                   gdc.s.para[GDC_CSRFORM] = 0;
           }
           else {
                   gdc.mode1 |= 0x10;
                   gdc.s.para[GDC_CSRFORM] = 1;
           }
   
           gdcs.textdisp &= ~GDCSCRN_ENABLE;
           gdcs.textdisp |= GDCSCRN_EXT | GDCSCRN_ALLDRAW2;
           gdcs.grphdisp |= GDCSCRN_EXT | GDCSCRN_ALLDRAW2;
           screenupdate |= 2;
   
           mem[0x597] &= ~3;
           mem[0x597] |= (scrn >> 4) & 3;
           mem[MEMB_CRT_STS_FLAG] &= ~0x11;
           if (!(scrn & 1)) {
                   mem[MEMB_CRT_STS_FLAG] |= 0x01;
           }
           if (scrn & 2) {
                   mem[MEMB_CRT_STS_FLAG] |= 0x10;
           }
           return(5);                      // 最後にGDCへ送ったデータ…
   }
   
   static REG8 bios0x18_31al(void) {
   
           UINT8   rate;
   
           rate = 0x08 + ((gdc.display >> (GDCDISP_31 - 5)) & 4);
           return(rate);
   }
   
   static REG8 bios0x18_31bh(void) {
   
           UINT8   scrn;
   
           scrn = (mem[0x597] & 3) << 4;
           if (!(mem[MEMB_CRT_STS_FLAG] & 0x01)) {
                   scrn |= 0x01;
           }
           if (mem[MEMB_CRT_STS_FLAG] & 0x10) {
                   scrn |= 0x02;
           }
           return(scrn);
   }
   #endif
   
   
   // ---- slave
   
   void bios0x18_40(void) {
   
           gdc_forceready(GDCWORK_SLAVE);
           if (!(gdcs.grphdisp & GDCSCRN_ENABLE)) {
                   gdcs.grphdisp |= GDCSCRN_ENABLE;
                   screenupdate |= 2;
           }
           mem[MEMB_PRXCRT] |= 0x80;
   }
   
   void bios0x18_41(void) {
   
           gdc_forceready(GDCWORK_SLAVE);
           if (gdcs.grphdisp & GDCSCRN_ENABLE) {
                   gdcs.grphdisp &= ~(GDCSCRN_ENABLE);
                   screenupdate |= 2;
           }
           mem[MEMB_PRXCRT] &= 0x7f;
   }
   
   void bios0x18_42(REG8 mode) {
   
           UINT8   crtmode;
   #if defined(SUPPORT_CRT31KHZ)
           UINT8   rate;
           UINT8   scrn;
   #endif
           int             slave;
   
           gdc_forceready(GDCWORK_MASTER);
           gdc_forceready(GDCWORK_SLAVE);
   
           crtmode = modenum[mode >> 6];
   #if defined(SUPPORT_CRT31KHZ)
           rate = bios0x18_31al();
           scrn = bios0x18_31bh();
           if ((mem[MEMB_CRT_BIOS] & 0x80) &&
                   (((scrn & 0x30) == 0x30) || (crtmode == 3))) {
                   bios0x18_30(rate, (REG8)((crtmode << 4) + 1));
           }
           else {
   #endif
                   ZeroMemory(gdc.s.para + GDC_SCROLL, 4);
                   if (crtmode == 2) {                                                     // ALL
                           crtmode = 2;
                           if ((mem[MEMB_PRXDUPD] & 0x24) == 0x20) {
                                   mem[MEMB_PRXDUPD] ^= 4;
                                   gdc.clock |= 3;
                                   CopyMemory(gdc.s.para + GDC_SYNC, gdcslavesync[3], 8);
                                   gdc.s.para[GDC_PITCH] = 80;
                                   gdcs.grphdisp |= GDCSCRN_EXT;
                                   mem[MEMB_PRXDUPD] |= 0x08;
                           }
                   }
                   else {
                           if ((mem[MEMB_PRXDUPD] & 0x24) == 0x24) {
                                   mem[MEMB_PRXDUPD] ^= 4;
                                   gdc.clock &= ~3;
   #if defined(SUPPORT_CRT31KHZ)
                                   if (rate & 4) slave = 4;
                                   else
   #endif
                                   slave = (mem[MEMB_PRXCRT] & 0x40)?2:0;
                                   CopyMemory(gdc.s.para + GDC_SYNC, gdcslavesync[slave], 8);
                                   gdc.s.para[GDC_PITCH] = 40;
                                   gdcs.grphdisp |= GDCSCRN_EXT;
                                   mem[MEMB_PRXDUPD] |= 0x08;
                           }
                           if (crtmode & 1) {                              // UPPER
                                   gdc.s.para[GDC_SCROLL+0] = (200*40) & 0xff;
                                   gdc.s.para[GDC_SCROLL+1] = (200*40) >> 8;
                           }
                   }
                   if (mem[MEMB_PRXDUPD] & 4) {
                           gdc.s.para[GDC_SCROLL+3] = 0x40;
                   }
                   if ((crtmode == 2) || (!(mem[MEMB_PRXCRT] & 0x40))) {
                           gdc.mode1 &= ~(0x10);
                           gdc.s.para[GDC_CSRFORM] = 0;
                   }
                   else {
                           gdc.mode1 |= 0x10;
                           gdc.s.para[GDC_CSRFORM] = 1;
                   }
   #if defined(SUPPORT_CRT31KHZ)
                   mem[MEMB_CRT_BIOS] &= ~3;
                   mem[MEMB_CRT_BIOS] |= crtmode;
           }
   #endif
           if (crtmode != 3) {
                   gdcs.disp = (mode >> 4) & 1;
           }
           if (!(mode & 0x20)) {
                   gdc.mode2 &= ~0x04;
           }
           else {
                   gdc.mode2 |= 0x04;
           }
           gdcs.mode2 = gdc.mode2;
           gdcs.grphdisp |= GDCSCRN_ALLDRAW2;
           screenupdate |= 2;
   }
   
   static void setbiosgdc(UINT32 csrw, const GDCVECT *vect, UINT8 ope) {
   
           gdc.s.para[GDC_CSRW + 0] = (UINT8)csrw;
           gdc.s.para[GDC_CSRW + 1] = (UINT8)(csrw >> 8);
           gdc.s.para[GDC_CSRW + 2] = (UINT8)(csrw >> 16);
   
           gdc.s.para[GDC_VECTW] = vect->ope;
           gdc_vectreset(&gdc.s);
   
           gdc.s.para[GDC_WRITE] = ope;
           mem[MEMB_PRXDUPD] &= ~3;
           mem[MEMB_PRXDUPD] |= ope;
   }
   
   static void bios0x18_47(void) {
   
         UCWTBL          ucw;          UCWTBL          ucw;
         GDCVECT         vect;          GDCVECT         vect;
Line 95  static void bios18_47(void) { Line 565  static void bios18_47(void) {
         GDCSUBFN        func;          GDCSUBFN        func;
         UINT32          csrw;          UINT32          csrw;
         UINT16          data;          UINT16          data;
           UINT16          data2;
         UINT16          GBMDOTI;          UINT16          GBMDOTI;
           UINT8           ope;
           SINT16          dx;
           SINT16          dy;
   
         // GDCバッファを空に          gdc_forceready(GDCWORK_SLAVE);
         if (gdc.s.cnt) {          MEML_READSTR(CPU_DS, CPU_BX, &ucw, sizeof(ucw));
                 gdc_work(GDCWORK_SLAVE);  
         }  
         gdc_forceready(&gdc.s);  
   
         i286_memstr_read(I286_DS, I286_BX, &ucw, sizeof(ucw));  
         GBSX1 = LOADINTELWORD(ucw.GBSX1);          GBSX1 = LOADINTELWORD(ucw.GBSX1);
         GBSY1 = LOADINTELWORD(ucw.GBSY1);          GBSY1 = LOADINTELWORD(ucw.GBSY1);
         GBSX2 = LOADINTELWORD(ucw.GBSX2);          GBSX2 = LOADINTELWORD(ucw.GBSX2);
         GBSY2 = LOADINTELWORD(ucw.GBSY2);          GBSY2 = LOADINTELWORD(ucw.GBSY2);
         ZeroMemory(&vect, sizeof(vect));          ZeroMemory(&vect, sizeof(vect));
           data = 0;
           data2 = 0;
         if (ucw.GBDTYP == 0x01) {          if (ucw.GBDTYP == 0x01) {
                 short dx, dy;                  func = gdcsub_vectl;
                 func = gdcsub_line;                  gdcsub_setvectl(&vect, GBSX1, GBSY1, GBSX2, GBSY2);
                 if ((GBSX1 > GBSX2) ||          }
                         ((GBSX1 == GBSX2) && (GBSY1 > GBSY2))) {          else if (ucw.GBDTYP <= 0x02) {
                         SWAPU16(GBSX1, GBSX2);                  func = gdcsub_vectr;
                         SWAPU16(GBSY1, GBSY2);                  vect.ope = 0x40 + (ucw.GBDSP & 7);
                 }  
                 dx = GBSX2 - GBSX1;                  dx = GBSX2 - GBSX1;
                 dy = GBSY2 - GBSY1;                  if (dx < 0) {
                 if (dy > 0) {                          dx = 0 - dx;
                         if (dx < dy) {  
                                 vect.ope = 0;  
                                 SWAPU16(dx, dy);  
                         }  
                         else {  
                                 vect.ope = 1;  
                         }  
                 }                  }
                 else {                  dy = GBSY2 - GBSY1;
                         dy = -dy;                  if (dy < 0) {
                         if (dx > dy) {                          dy = 0 - dy;
                                 vect.ope = 2;  
                         }  
                         else {  
                                 vect.ope = 3;  
                                 SWAPU16(dx, dy);  
                         }  
                 }  
                 STOREINTELWORD(vect.DC, dx);  
                 data = dy * 2;  
                 STOREINTELWORD(vect.D1, data);  
                 data -= dx;  
                 STOREINTELWORD(vect.D, data);  
                 data -= dx;  
                 STOREINTELWORD(vect.D2, data);  
         }  
         else if (ucw.GBDTYP == 0x02) {  
                 func = gdcsub_box;  
                 if (GBSX1 > GBSX2) {  
                         SWAPU16(GBSX1, GBSX2);  
                 }                  }
                 if (GBSY1 > GBSY2) {                  switch(ucw.GBDSP & 3) {
                         SWAPU16(GBSY1, GBSY2);                          case 0:
                                   data = dy;
                                   data2 = dx;
                                   break;
   
                           case 1:
                                   data2 = (UINT16)dx + (UINT16)dy;
                                   data2 >>= 1;
                                   data = (UINT16)dx - (UINT16)dy;
                                   data = (data >> 1) & 0x3fff;
                                   break;
   
                           case 2:
                                   data = dx;
                                   data2 = dy;
                                   break;
   
                           case 3:
                                   data2 = (UINT16)dx + (UINT16)dy;
                                   data2 >>= 1;
                                   data = (UINT16)dy - (UINT16)dx;
                                   data = (data >> 1) & 0x3fff;
                                   break;
                 }                  }
                 STOREINTELWORD(vect.DC, 3);                  STOREINTELWORD(vect.DC, 3);
                   STOREINTELWORD(vect.D, data);
                   STOREINTELWORD(vect.D2, data2);
                 STOREINTELWORD(vect.D1, 0xffff);                  STOREINTELWORD(vect.D1, 0xffff);
                 data = GBSX2 - GBSX1;  
                 STOREINTELWORD(vect.DM, data);                  STOREINTELWORD(vect.DM, data);
                 STOREINTELWORD(vect.D2, data);          }
                 data = GBSY2 - GBSY1;          else {
                   func = gdcsub_vectc;
                   vect.ope = 0x20 + (ucw.GBDSP & 7);
                   vect.DC[0] = ucw.GBLNG1[0];
                   vect.DC[1] = ucw.GBLNG1[1];
   //              data = LOADINTELWORD(ucw.GBLNG2) - 1;
                   data = LOADINTELWORD(ucw.GBCIR) - 1;
                 STOREINTELWORD(vect.D, data);                  STOREINTELWORD(vect.D, data);
                   data >>= 1;
                   STOREINTELWORD(vect.D2, data);
                   STOREINTELWORD(vect.D1, 0x3fff);
                   if (ucw.GBDTYP == 0x04) {
                           vect.DM[0] = ucw.GBMDOT[0];
                           vect.DM[1] = ucw.GBMDOT[1];
                   }
           }
           if ((CPU_CH & 0xc0) == 0x40) {
                   GBSY1 += 200;
           }
           csrw = (GBSY1 * 40) + (GBSX1 >> 4);
           csrw += (GBSX1 & 0xf) << 20;
           GBMDOTI = (GDCPATREVERSE(ucw.GBMDOTI[0]) << 8) +
                                                                                           GDCPATREVERSE(ucw.GBMDOTI[1]);
           if ((CPU_CH & 0x30) == 0x30) {
                   ope = (ucw.GBON_PTN & 1)?GDCOPE_SET:GDCOPE_CLEAR;
                   func(csrw + 0x4000, &vect, GBMDOTI, ope);
                   ope = (ucw.GBON_PTN & 2)?GDCOPE_SET:GDCOPE_CLEAR;
                   func(csrw + 0x8000, &vect, GBMDOTI, ope);
                   ope = (ucw.GBON_PTN & 4)?GDCOPE_SET:GDCOPE_CLEAR;
                   csrw += 0xc000;
                   func(csrw, &vect, GBMDOTI, ope);
         }          }
         else {          else {
                 return;                  ope = ucw.GBDOTU & 3;
                   csrw += 0x4000 + ((CPU_CH & 0x30) << 10);
                   func(csrw, &vect, GBMDOTI, ope);
         }          }
         if ((I286_CH & 0xc0) == 0x40) {  
           // 最後に使った奴を記憶
           *(UINT16 *)(mem + MEMW_PRXGLS) = *(UINT16 *)(ucw.GBMDOTI);
           STOREINTELWORD(mem + GDC_TEXTW, GBMDOTI);
           setbiosgdc(csrw, &vect, ope);
   }
   
   static void bios0x18_49(void) {
   
           UCWTBL          ucw;
           UINT            i;
           UINT8           pat[8];
           UINT16          tmp;
           GDCVECT         vect;
           UINT16          GBSX1;
           UINT16          GBSY1;
           UINT32          csrw;
           UINT8           ope;
   
           gdc_forceready(GDCWORK_SLAVE);
   
           MEML_READSTR(CPU_DS, CPU_BX, &ucw, sizeof(ucw));
           for (i=0; i<8; i++) {
                   mem[MEMW_PRXGLS + i] = ucw.GBMDOTI[i];
                   pat[i] = GDCPATREVERSE(ucw.GBMDOTI[i]);
                   gdc.s.para[GDC_TEXTW + i] = pat[i];
           }
           vect.ope = 0x10 + (ucw.GBDSP & 7);
           if (*(UINT16 *)ucw.GBLNG1) {
                   tmp = (LOADINTELWORD(ucw.GBLNG2) - 1) & 0x3fff;
                   STOREINTELWORD(vect.DC, tmp);
                   vect.D[0] = ucw.GBLNG1[0];
                   vect.D[1] = ucw.GBLNG1[1];
           }
           else {
                   STOREINTELWORD(vect.DC, 7);
                   STOREINTELWORD(vect.D, 7);
           }
   
           GBSX1 = LOADINTELWORD(ucw.GBSX1);
           GBSY1 = LOADINTELWORD(ucw.GBSY1);
           if ((CPU_CH & 0xc0) == 0x40) {
                 GBSY1 += 200;                  GBSY1 += 200;
         }          }
         csrw = (GBSY1 * 40) + (GBSX1 >> 4);          csrw = (GBSY1 * 40) + (GBSX1 >> 4);
         csrw += (GBSX1 & 0xf) << 20;          csrw += (GBSX1 & 0xf) << 20;
         GBMDOTI = LOADINTELWORD(ucw.GBMDOTI);          if ((CPU_CH & 0x30) == 0x30) {
         if ((I286_CH & 0x30) == 0x30) {                  ope = (ucw.GBON_PTN & 1)?GDCOPE_SET:GDCOPE_CLEAR;
                 if (ucw.GBON_PTN & 1) {                  gdcsub_text(csrw + 0x4000, &vect, pat, ope);
                         func(0x04000 + csrw, &vect, GBMDOTI, GDCOPE_SET);                  ope = (ucw.GBON_PTN & 2)?GDCOPE_SET:GDCOPE_CLEAR;
                 }                  gdcsub_text(csrw + 0x8000, &vect, pat, ope);
                 else {                  ope = (ucw.GBON_PTN & 4)?GDCOPE_SET:GDCOPE_CLEAR;
                         func(0x04000 + csrw, &vect, GBMDOTI, GDCOPE_CLEAR);                  csrw += 0xc000;
                 }                  gdcsub_text(csrw, &vect, pat, ope);
                 if (ucw.GBON_PTN & 2) {          }
                         func(0x08000 + csrw, &vect, GBMDOTI, GDCOPE_SET);          else {
                 }                  ope = ucw.GBDOTU & 3;
                 else {                  csrw += 0x4000 + ((CPU_CH & 0x30) << 10);
                         func(0x08000 + csrw, &vect, GBMDOTI, GDCOPE_CLEAR);                  gdcsub_text(csrw, &vect, pat, ope);
                 }          }
                 if (ucw.GBON_PTN & 4) {  
                         func(0x0c000 + csrw, &vect, GBMDOTI, GDCOPE_SET);          // 最後に使った奴を記憶
           setbiosgdc(csrw, &vect, ope);
   }
   
   
   // ---- PC-9821
   
   #if defined(SUPPORT_PC9821)
   static void bios0x18_4d(REG8 mode) {
   
           if ((mem[0x45c] & 0x40) &&
                   ((mem[MEMB_CRT_BIOS] & 3) == 2)) {
                   if (mode == 0) {
                           gdc_analogext(FALSE);
                           mem[MEMB_PRXDUPD] &= ~0x7f;
                           mem[MEMB_PRXDUPD] |= 0x04;
                   }
                   else if (mode == 1) {
                           gdc_analogext(TRUE);
                           mem[MEMB_PRXDUPD] |= 0x80;
                 }                  }
                 else {                  else {
                         func(0x0c000 + csrw, &vect, GBMDOTI, GDCOPE_CLEAR);                          mem[MEMB_PRXDUPD] |= 0x04;
                 }                  }
         }          }
         else {  
                 func(csrw + 0x4000 + ((I286_CH & 0x30) << 10), &vect,  
                                                                                                                 GBMDOTI, ucw.GBDOTU);  
         }  
 }  }
   #endif
   
   
   // ----
   
 void bios0x18(void) {  void bios0x18(void) {
   
         UINT    pos;          union {
         BYTE    buf[34];                  BOOL    b;
         BYTE    *p;                  REG8    r8;
                   UINT16  w;
                   UINT32  d;
                   UINT8   col[4];
           }               tmp;
         int             i;          int             i;
         UINT16  tmp;  
         UINT32  pal;  
   
 //      TRACE_("int18", I286_AH);  
   
         sti_waiting ^= 1;  #if 0
         if (!sti_waiting) {                                     // 割込み許可の遊び          TRACEOUT(("int18 AX=%.4x %.4x:%.4x", CPU_AX,
                 I286_IP--;                                                          MEML_READ16(CPU_SS, CPU_SP+2),
                 I286_STI;                                                          MEML_READ16(CPU_SS, CPU_SP)));
                 nevent_forceexit();  #endif
                 return;  
         }  
   
         switch(I286_AH) {          switch(CPU_AH) {
                 case 0x00:                                              // キー・データの読みだし                  case 0x00:                                              // キー・データの読みだし
                         if (mem[MEMB_KB_COUNT]) {                          if (mem[MEMB_KB_COUNT]) {
                                 I286_AX = keyget();                                  CPU_AX = keyget();
                         }                          }
                         else {                          else {
                                 I286_IP--;                                  CPU_IP--;
                                 I286_REMCLOCK = -1;                                  CPU_REMCLOCK = -1;
                                 break;                                  break;
                         }                          }
                         break;                          break;
   
                 case 0x01:                                              // キー・バッファ状態のセンス                  case 0x01:                                              // キー・バッファ状態のセンス
                         if (mem[MEMB_KB_COUNT]) {                          if (mem[MEMB_KB_COUNT]) {
                                 pos = GETBIOSMEM16(MEMW_KB_BUF_HEAD);                                  tmp.d = GETBIOSMEM16(MEMW_KB_BUF_HEAD);
                                 I286_AX = GETBIOSMEM16(pos);                                  CPU_AX = GETBIOSMEM16(tmp.d);
                                 I286_BH = 1;                                  CPU_BH = 1;
                         }                          }
                         else {                          else {
                                 I286_BH = 0;                                  CPU_BH = 0;
                         }                          }
                         break;                          break;
   
                 case 0x02:                                              // シフト・キー状態のセンス                  case 0x02:                                              // シフト・キー状態のセンス
                         I286_AL = mem[MEMB_SHIFT_STS];                          CPU_AL = mem[MEMB_SHIFT_STS];
                         break;                          break;
   
                 case 0x03:                                              // キーボード・インタフェイスの初期化                  case 0x03:                                              // キーボード・インタフェイスの初期化
Line 248  void bios0x18(void) { Line 804  void bios0x18(void) {
                         break;                          break;
   
                 case 0x04:                                              // キー入力状態のセンス                  case 0x04:                                              // キー入力状態のセンス
                         I286_AH = mem[0x00052a + (I286_AL & 0x0f)];                          CPU_AH = mem[MEMX_KB_KY_STS + (CPU_AL & 0x0f)];
                         break;                          break;
   
                 case 0x05:                                              // キー入力センス                  case 0x05:                                              // キー入力センス
                         if (mem[MEMB_KB_COUNT]) {                          if (mem[MEMB_KB_COUNT]) {
                                 I286_AX = keyget();                                  CPU_AX = keyget();
                                 I286_BH = 1;                                  CPU_BH = 1;
                         }                          }
                         else {                          else {
                                 I286_BH = 0;                                  CPU_BH = 0;
                         }                          }
                         break;                          break;
   
                 case 0x0a:                                              // CRTモードの設定                  case 0x0a:                                              // CRTモードの設定(15/24khz)
 #if 1                          bios0x18_0a(CPU_AL);
                         mem[MEMB_CRT_STS_FLAG] = 0x80 | (I286_AL & 0x0f);  
                         // GDCバッファを空に  
                         if (gdc.m.cnt) {  
                                 gdc_work(GDCWORK_MASTER);  
                         }  
                         gdc_forceready(&gdc.m);  
   
                         gdc.mode1 &= ~(0x25);  
                         gdc.mode1 |= 0x08;  
                         if (I286_AL & 0x02) {  
                                 gdc.mode1 |= 0x04;                              // 40桁  
                         }  
                         if (I286_AL & 0x04) {  
                                 gdc.mode1 |= 0x01;                              // アトリビュート  
                         }  
                         if (I286_AL & 0x08) {  
                                 gdc.mode1 |= 0x20;                              // コードアクセス  
                         }  
                         if (I286_AL & 0x01) {                                   // 20行  
                                 mem[MEMB_CRT_RASTER] = 0x13;  
                                 gdc.m.para[GDC_CSRFORM + 0] = 0x13;  
                                 gdc.m.para[GDC_CSRFORM + 1] = 0x00;  
                                 gdc.m.para[GDC_CSRFORM + 2] = 0x9b;  
                                 crtc.reg.pl = 0x1e;  
                                 crtc.reg.bl = 0x11;  
                         }  
                         else {                                                                  // 25行  
                                 mem[MEMB_CRT_RASTER] = 0x0f;  
                                 gdc.m.para[GDC_CSRFORM + 0] = 0x0f;  
                                 gdc.m.para[GDC_CSRFORM + 1] = 0x00;  
                                 gdc.m.para[GDC_CSRFORM + 2] = 0x7b;  
                                 crtc.reg.pl = 0x00;  
                                 crtc.reg.bl = 0x0f;  
                         }  
                         crtc.reg.cl = 0x10;  
                         crtc.reg.ssl = 0x00;  
                         gdcs.textdisp |= GDCSCRN_ALLDRAW2;  
                         gdc_restorekacmode();  
                         break;                          break;
 #else  
                         // GDCバッファを空に  
                         if (gdc.m.cnt) {  
                                 gdc_work(GDCWORK_MASTER);  
                         }  
                         gdc_forceready(&gdc.m);  
   
                         mem[MEMB_CRT_STS_FLAG] = I286_AL;  
                         if (systemport_r(0x33) & 0x08) {  
                                 mem[MEMB_CRT_STS_FLAG] |= 0x80;  
                         }  
 #endif  
   
                 case 0x0b:                                              // CRTモードのセンス                  case 0x0b:                                              // CRTモードのセンス
                         I286_AL = mem[MEMB_CRT_STS_FLAG];                          CPU_AL = mem[MEMB_CRT_STS_FLAG];
                         break;                          break;
   
                 case 0x0c:                                              // テキスト画面の表示開始                  case 0x0c:                                              // テキスト画面の表示開始
                         if (!(gdcs.textdisp & GDCSCRN_ENABLE)) {                          bios0x18_0c();
                                 gdcs.textdisp |= GDCSCRN_ENABLE;  
                                 screenupdate |= 2;  
                         }  
                         break;                          break;
   
                 case 0x0d:                                              // テキスト画面の表示終了                  case 0x0d:                                              // テキスト画面の表示終了
Line 334  void bios0x18(void) { Line 837  void bios0x18(void) {
                         break;                          break;
   
                 case 0x0e:                                              // 一つの表示領域の設定                  case 0x0e:                                              // 一つの表示領域の設定
                         // GDCバッファを空に                          gdc_forceready(GDCWORK_MASTER);
                         if (gdc.m.cnt) {  
                                 gdc_work(GDCWORK_MASTER);  
                         }  
                         gdc_forceready(&gdc.m);  
   
                         ZeroMemory(&gdc.m.para[GDC_SCROLL], 16);                          ZeroMemory(&gdc.m.para[GDC_SCROLL], 16);
                         tmp = I286_DX >> 1;                          tmp.w = CPU_DX >> 1;
                         STOREINTELWORD(gdc.m.para + GDC_SCROLL, tmp);                          SETBIOSMEM16(MEMW_CRT_W_VRAMADR, tmp.w);
                           STOREINTELWORD(gdc.m.para + GDC_SCROLL + 0, tmp.w);
                           tmp.w = 200 << 4;
                           if (mem[MEMB_CRT_STS_FLAG] & 0x80) {
                                   tmp.w <<= 1;
                           }
                           SETBIOSMEM16(MEMW_CRT_W_RASTER, tmp.w);
                           STOREINTELWORD(gdc.m.para + GDC_SCROLL + 2, tmp.w);
                         gdcs.textdisp |= GDCSCRN_ALLDRAW2;                          gdcs.textdisp |= GDCSCRN_ALLDRAW2;
                         screenupdate |= 2;  //                      screenupdate |= 2;
                         break;                          break;
   
                 case 0x0f:                                              // 複数の表示領域の設定                  case 0x0f:                                              // 複数の表示領域の設定
                         SETBIOSMEM16(0x0053e, I286_CX);                          gdc_forceready(GDCWORK_MASTER);
                         SETBIOSMEM16(0x00540, I286_BX);                          bios0x18_0f(CPU_BX, CPU_CX, CPU_DH, CPU_DL);
                         mem[0x00547] = I286_DH;  
                         mem[0x0053D] = I286_DL;  
                         // wait sync int  
                         if ((i = I286_DL) > 0) {  
                                 pos = I286_CX;  
                                 p = gdc.m.para + GDC_SCROLL + (I286_DH << 2);  
                                 while((i--) && (p < (gdc.m.para + GDC_SCROLL + 0x10))) {  
                                         tmp = i286_memword_read(I286_BX, pos);  
                                         tmp >>= 1;  
                                         STOREINTELWORD(p, tmp);  
                                         tmp = i286_memword_read(I286_BX, pos + 2);  
                                         if (!(mem[MEMB_CRT_STS_FLAG] & 1)) {    // 25  
                                                 tmp *= (16 * 16);  
                                         }  
                                         else {                                                                  // 20  
                                                 tmp *= (20 * 16);  
                                         }  
                                         if (!(mem[MEMB_CRT_STS_FLAG] & 0x80)) {                 // ver0.29  
                                                 tmp >>= 1;  
                                         }  
                                         STOREINTELWORD(p + 2, tmp);  
                                         pos += 4;  
                                         p += 4;  
                                 }  
                         }  
                         gdcs.textdisp |= GDCSCRN_ALLDRAW2;  
                         screenupdate |= 2;  
                         break;                          break;
   
                 case 0x10:                                              // カーソルタイプの設定                  case 0x10:                                              // カーソルタイプの設定(15/24khz)
                         // GDCバッファを空に                          gdc_forceready(GDCWORK_MASTER);
                         if (gdc.m.cnt) {                          bios0x18_10((REG8)(CPU_AL & 1));
                                 gdc_work(GDCWORK_MASTER);  
                         }  
                         gdc_forceready(&gdc.m);  
   
                         gdc.m.para[GDC_CSRFORM + 0] &= 0x7f;  
                         gdc.m.para[GDC_CSRFORM + 1] &= 0xdf;  
                         gdc.m.para[GDC_CSRFORM + 1] |= (I286_AL & 1) << 5;  
                         gdcs.textdisp |= GDCSCRN_EXT;  
                         break;                          break;
   
                 case 0x11:                                              // カーソルの表示開始                  case 0x11:                                              // カーソルの表示開始
                         // GDCバッファを空に                          gdc_forceready(GDCWORK_MASTER);
                         if (gdc.m.cnt) {  
                                 gdc_work(GDCWORK_MASTER);  
                         }  
                         gdc_forceready(&gdc.m);  
                                                                                                         // 00/08/02  
                         if (gdc.m.para[GDC_CSRFORM] != (mem[MEMB_CRT_RASTER] | 0x80)) {                          if (gdc.m.para[GDC_CSRFORM] != (mem[MEMB_CRT_RASTER] | 0x80)) {
                                 gdc.m.para[GDC_CSRFORM] = mem[MEMB_CRT_RASTER] | 0x80;                                  gdc.m.para[GDC_CSRFORM] = mem[MEMB_CRT_RASTER] | 0x80;
                         }                          }
Line 406  void bios0x18(void) { Line 871  void bios0x18(void) {
                         break;                          break;
   
                 case 0x12:                                              // カーソルの表示停止                  case 0x12:                                              // カーソルの表示停止
                         // GDCバッファを空に                          gdc_forceready(GDCWORK_MASTER);
                         if (gdc.m.cnt) {  
                                 gdc_work(GDCWORK_MASTER);  
                         }  
                         gdc_forceready(&gdc.m);  
                                                                                                         // 00/08/02  
                         if (gdc.m.para[GDC_CSRFORM] != mem[MEMB_CRT_RASTER]) {                          if (gdc.m.para[GDC_CSRFORM] != mem[MEMB_CRT_RASTER]) {
                                 gdc.m.para[GDC_CSRFORM] = mem[MEMB_CRT_RASTER];                                  gdc.m.para[GDC_CSRFORM] = mem[MEMB_CRT_RASTER];
                                 gdcs.textdisp |= GDCSCRN_ALLDRAW | GDCSCRN_EXT;                                  gdcs.textdisp |= GDCSCRN_ALLDRAW | GDCSCRN_EXT;
Line 419  void bios0x18(void) { Line 879  void bios0x18(void) {
                         break;                          break;
   
                 case 0x13:                                              // カーソル位置の設定                  case 0x13:                                              // カーソル位置の設定
                         // GDCバッファを空に                          gdc_forceready(GDCWORK_MASTER);
                         if (gdc.m.cnt) {                          tmp.w = CPU_DX >> 1;
                                 gdc_work(GDCWORK_MASTER);                          if (LOADINTELWORD(gdc.m.para + GDC_CSRW) != tmp.w) {
                         }                                  STOREINTELWORD(gdc.m.para + GDC_CSRW, tmp.w);
                         gdc_forceready(&gdc.m);  
   
                         tmp = I286_DX >> 1;  
                         if (LOADINTELWORD(gdc.m.para + GDC_CSRW) != tmp) {  
                                 STOREINTELWORD(gdc.m.para + GDC_CSRW, tmp);  
                                 gdcs.textdisp |= GDCSCRN_EXT;                                  gdcs.textdisp |= GDCSCRN_EXT;
                         }                          }
                         break;                          break;
   
                 case 0x14:                                              // フォントパターンの読み出し                  case 0x14:                                              // フォントパターンの読み出し
                         switch(I286_DH) {                          bios0x18_14(CPU_BX, CPU_CX, CPU_DX);
                                 case 0x00:                      // 8x8  
                                         i286_memword_write(I286_BX, I286_CX, 0x0101);  
                                         i286_memstr_write(I286_BX, I286_CX+2,  
                                                                 fontrom + 0x82000 + (I286_DL << 3), 8);  
                                         break;  
   
                                 case 0x28:                      // 8x16 KANJI  
                                 case 0x29:  
                                 case 0x2a:  
                                 case 0x2b:  
                                         i286_memword_write(I286_BX, I286_CX, 0x0102);  
                                         i286_memstr_write(I286_BX, I286_CX+2,  
                                                                 fontrom + ((I286_DL & 0x7f) << 12)  
                                                                                 + ((I286_DH - 0x20) << 4), 16);  
                                         break;  
   
                                 case 0x80:                      // 8x16 ANK  
                                         i286_memword_write(I286_BX, I286_CX, 0x0102);  
                                         i286_memstr_write(I286_BX, I286_CX+2,  
                                                                 fontrom + 0x80000 + (I286_DL << 4), 16);  
                                         break;  
   
                                 default:  
                                         buf[0] = 0x02;  
                                         buf[1] = 0x02;  
                                         p = fontrom + ((I286_DL & 0x7f) << 12)  
                                                                 + (((I286_DH - 0x20) & 0x7f) << 4);  
                                         for (i=1; i<17; i++, p++) {  
                                                 buf[i*2+0] = *p;  
                                                 buf[i*2+1] = *(p+0x800);  
                                         }  
                                         i286_memstr_write(I286_BX, I286_CX, buf, 34);  
                                         break;  
                         }  
                         break;                          break;
   
                 case 0x15:                                              // ライトペン位置読みだし                  case 0x15:                                              // ライトペン位置読みだし
                         break;                          break;
   
                 case 0x16:                                              // テキストVRAMの初期化                  case 0x16:                                              // テキストVRAMの初期化
                         bios0x18_16(I286_DL, I286_DH);                          bios0x18_16(CPU_DL, CPU_DH);
                         break;                          break;
   
                 case 0x17:                                              // ブザーの起呼                  case 0x17:                                              // ブザーの起呼
Line 489  void bios0x18(void) { Line 910  void bios0x18(void) {
                         break;                          break;
   
                 case 0x1a:                                              // ユーザー文字の定義                  case 0x1a:                                              // ユーザー文字の定義
                         if ((I286_DH & 0x7e) == 0x76) {                          bios0x18_1a(CPU_BX, CPU_CX, CPU_DX);
                                 i286_memstr_read(I286_BX, I286_CX+2, buf, 32);  
                                 p = fontrom + ((I286_DL & 0x7f) << 12)  
                                                         + (((I286_DH - 0x20) & 0x7f) << 4);  
                                 for (i=0; i<16; i++, p++) {  
                                         *p = buf[i*2+0];  
                                         *(p+0x800) = buf[i*2+1];  
                                 }  
                                 cgwindow.writable |= 0x80;  
                         }  
                         break;                          break;
   
                 case 0x1b:                                              // KCGアクセスモードの設定                  case 0x1b:                                              // KCGアクセスモードの設定
                         switch(I286_AL) {                                               // 実装し忘れ   // ver0.28                          switch(CPU_AL) {
                                 case 0:                                  case 0:
                                         mem[MEMB_CRT_STS_FLAG] &= ~0x08;                                          mem[MEMB_CRT_STS_FLAG] &= ~0x08;
                                         gdc.mode1 &= ~0x20;                                          gdc.mode1 &= ~0x20;
Line 516  void bios0x18(void) { Line 928  void bios0x18(void) {
                                         break;                                          break;
                         }                          }
                         break;                          break;
   #if defined(SUPPORT_CRT31KHZ)
                   case 0x30:
                           if (mem[MEMB_CRT_BIOS] & 0x80) {
                                   gdc_forceready(GDCWORK_MASTER);
                                   gdc_forceready(GDCWORK_SLAVE);
                                   tmp.r8 = bios0x18_30(CPU_AL, CPU_BH);
                                   CPU_AH = tmp.r8;
                                   if (tmp.r8 == 0x05) {
                                           CPU_AL = 0;
                                           CPU_BH = 0;
                                   }
                                   else {
                                           CPU_AL = 1;
                                           CPU_BH = 1;
                                   }
                           }
                           break;
   
                 case 0x40:                                              // グラフィック画面の表示開始                  case 0x31:
                         if (!(gdcs.grphdisp & GDCSCRN_ENABLE)) {                          if (mem[MEMB_CRT_BIOS] & 0x80) {
                                 gdcs.grphdisp |= GDCSCRN_ENABLE;                                  CPU_AL = bios0x18_31al();
                                 screenupdate |= 2;                                  CPU_BH = bios0x18_31bh();
                         }                          }
                           break;
   #endif
                   case 0x40:                                              // グラフィック画面の表示開始
                           bios0x18_40();
                         break;                          break;
   
                 case 0x41:                                              // グラフィック画面の表示終了                  case 0x41:                                              // グラフィック画面の表示終了
                         if (gdcs.grphdisp & GDCSCRN_ENABLE) {                          bios0x18_41();
                                 gdcs.grphdisp &= ~(GDCSCRN_ENABLE);  
                                 screenupdate |= 2;  
                         }  
                         break;                          break;
   
                 case 0x42:                                              // 表示領域の設定                  case 0x42:                                              // 表示領域の設定
                         // GDCバッファを空に                          bios0x18_42(CPU_CH);
                         if (gdc.s.cnt) {  
                                 gdc_work(GDCWORK_SLAVE);  
                         }  
                         gdc_forceready(&gdc.s);  
   
                         ZeroMemory(&gdc.s.para[GDC_SCROLL], 8);  
                         switch(I286_CH & 0xc0) {  
                                 case 0x40:                                      // UPPER  
                                         if ((mem[MEMB_PRXDUPD] & 0x24) == 0x24) {  
                                                 mem[MEMB_PRXDUPD] ^= 4;  
                                                 gdc.clock &= ~3;  
                                                 gdc.s.para[GDC_PITCH] = 40;  
                                                 gdcs.grphdisp |= GDCSCRN_EXT;  
                                         }  
                                         gdc.mode1 |= 0x10;  
                                         gdc.s.para[GDC_CSRFORM] = 1;  
                                         gdc.s.para[GDC_SCROLL+0] = (200*40) & 0xff;  
                                         gdc.s.para[GDC_SCROLL+1] = (200*40) >> 8;  
                                         break;  
   
                                 case 0x80:                                      // LOWER  
                                         if ((mem[MEMB_PRXDUPD] & 0x24) == 0x24) {  
                                                 mem[MEMB_PRXDUPD] ^= 4;  
                                                 gdc.clock &= ~3;  
                                                 gdc.s.para[GDC_PITCH] = 40;  
                                                 gdcs.grphdisp |= GDCSCRN_EXT;  
                                         }  
                                         gdc.mode1 |= 0x10;  
                                         gdc.s.para[GDC_CSRFORM] = 1;  
                                         break;  
   
                                 default:                                        // ALL  
                                         if ((mem[MEMB_PRXDUPD] & 0x24) == 0x20) {  
                                                 mem[MEMB_PRXDUPD] ^= 4;  
                                                 gdc.clock |= 3;  
                                                 gdc.s.para[GDC_PITCH] = 80;  
                                                 gdcs.grphdisp |= GDCSCRN_EXT;  
                                         }  
                                         gdc.mode1 &= ~(0x10);  
                                         gdc.s.para[GDC_CSRFORM] = 0;  
                                         break;  
                         }  
                         gdcs.disp = (I286_CH >> 4) & 1;                         // 00/05/23  
                         gdcs.grphdisp |= GDCSCRN_ALLDRAW2;  
                         screenupdate |= 2;  
                         break;                          break;
   
                 case 0x43:                                              // パレットの設定                  case 0x43:                                              // パレットの設定
                         i286_memstr_read(I286_DS, I286_BX + offsetof(UCWTBL, GBCPC),                          MEML_READSTR(CPU_DS, CPU_BX + offsetof(UCWTBL, GBCPC),
                                                                                                                                         buf, 4);                                                                                                                                  tmp.col, 4);
                         pal = LOADINTELDWORD(buf);                          for (i=0; i<4; i++) {
                         for (i=8; i--;) {                                  gdc_setdegitalpal(6 - (i*2), (REG8)(tmp.col[i] >> 4));
                                 gdc_setdegitalpal(i, (BYTE)(pal & 15));                                  gdc_setdegitalpal(7 - (i*2), (REG8)(tmp.col[i] & 15));
                                 pal >>= 4;  
                         }                          }
                         break;                          break;
   
                   case 0x44:                                              // ボーダカラーの設定
   //                      if (!(mem[MEMB_PRXCRT] & 0x40)) {
   //                              color = MEML_READ8(CPU_DS, CPU_BX + 1);
   //                      }
                           break;
   
                   case 0x45:
                   case 0x46:
                           TRACEOUT(("unsupport bios 18-%.2x", CPU_AH));
                           break;
   
                 case 0x47:                                              // 直線、矩形の描画                  case 0x47:                                              // 直線、矩形の描画
                         bios18_47();                  case 0x48:                                              // 円の描画
                           bios0x18_47();
                           break;
   
                   case 0x49:                                              // グラフィック文字の描画
                           bios0x18_49();
                           break;
   
                   case 0x4a:                                              // 描画モードの設定
                           if (!(mem[MEMB_PRXCRT] & 0x01)) {
                                   gdc.s.para[GDC_SYNC] = CPU_CH;
                                   gdcs.grphdisp |= GDCSCRN_EXT;
                                   if (CPU_CH & 0x10) {
                                           mem[MEMB_PRXDUPD] &= ~0x08;
                                   }
                                   else {
                                           mem[MEMB_PRXDUPD] |= 0x08;
                                   }
                           }
                         break;                          break;
   #if defined(SUPPORT_PC9821)
                   case 0x4d:
                           bios0x18_4d(CPU_CH);
                           break;
   #endif
         }          }
 }  }
   

Removed from v.1.4  
changed lines
  Added in v.1.42


RetroPC.NET-CVS <cvs@retropc.net>