--- np2/bios/bios18.c 2004/02/20 08:32:23 1.20 +++ np2/bios/bios18.c 2004/02/21 17:52:04 1.24 @@ -2,6 +2,7 @@ #include "cpucore.h" #include "pccore.h" #include "iocore.h" +#include "gdc_sub.h" #include "bios.h" #include "biosmem.h" #include "font.h" @@ -97,11 +98,7 @@ void bios0x18_0a(REG8 mode) { const CRTDATA *crt; - // GDCバッファを空に - if (gdc.m.cnt) { - gdc_work(GDCWORK_MASTER); - } - gdc_forceready(&gdc.m); + gdc_forceready(GDCWORK_MASTER); gdc.mode1 &= ~(0x2d); mem[MEMB_CRT_STS_FLAG] = mode; @@ -132,6 +129,74 @@ const CRTDATA *crt; bios0x18_10(0); } +REG16 bios0x18_14(REG16 seg, REG16 off, REG16 code) { + + UINT16 size; +const BYTE *p; + BYTE buf[32]; + UINT i; + + switch(code >> 8) { + case 0x00: // 8x8 + size = 0x0101; + i286_memword_write(seg, off, 0x0101); + p = fontrom + 0x82000 + ((code & 0xff) << 4); + i286_memstr_write(seg, off + 2, p, 8); + break; + + case 0x28: // 8x16 KANJI + case 0x29: + case 0x2a: + case 0x2b: + size = 0x0102; + i286_memword_write(seg, off, 0x0102); + p = fontrom; + p += (code & 0x7f) << 12; + p += (((code >> 8) - 0x20) & 0x7f) << 4; + i286_memstr_write(seg, off + 2, p, 16); + break; + + case 0x80: // 8x16 ANK + size = 0x0102; + p = fontrom + 0x80000 + ((code & 0xff) << 4); + i286_memstr_write(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); + } + i286_memstr_write(seg, off + 2, buf, 32); + break; + } + i286_memword_write(seg, off, size); + return(size); +} + +static void bios0x18_1a(REG16 seg, REG16 off, REG16 code) { + + BYTE *p; + BYTE buf[32]; + UINT i; + + if (((code >> 8) & 0x7e) == 0x76) { + i286_memstr_read(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; @@ -146,8 +211,77 @@ void bios0x18_16(REG8 chr, REG8 atr) { gdcs.textdisp |= GDCSCRN_ALLDRAW; } -#define SWAPU16(a, b) { UINT16 tmp; tmp = (a); (a) = (b); (b) = tmp; } +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) { + + BOOL b; + + gdc_forceready(GDCWORK_SLAVE); + ZeroMemory(&gdc.s.para[GDC_SCROLL], 8); + if ((mode & 0xc0) == 0xc0) { // ALL + b = FALSE; + if ((mem[MEMB_PRXDUPD] & 0x24) == 0x20) { + mem[MEMB_PRXDUPD] ^= 4; + gdc.clock |= 3; + CopyMemory(gdc.s.para + GDC_SYNC, sync400m, 8); + gdc.s.para[GDC_PITCH] = 80; + gdcs.grphdisp |= GDCSCRN_EXT; + mem[MEMB_PRXDUPD] |= 0x08; + } + } + else { + b = TRUE; + if ((mem[MEMB_PRXDUPD] & 0x24) == 0x24) { + mem[MEMB_PRXDUPD] ^= 4; + gdc.clock &= ~3; + CopyMemory(gdc.s.para + GDC_SYNC, + (mem[MEMB_PRXCRT] & 0x40)?sync200m:sync200l, 8); + gdc.s.para[GDC_PITCH] = 40; + gdcs.grphdisp |= GDCSCRN_EXT; + mem[MEMB_PRXDUPD] |= 0x08; + } + if (mode & 0x40) { // UPPER + gdc.s.para[GDC_SCROLL+0] = (200*40) & 0xff; + gdc.s.para[GDC_SCROLL+1] = (200*40) >> 8; + } + } + if ((!b) || (!(mem[MEMB_PRXCRT] & 0x40))) { + gdc.mode1 &= ~(0x10); + gdc.s.para[GDC_CSRFORM] = 0; + } + else { + gdc.mode1 |= 0x10; + gdc.s.para[GDC_CSRFORM] = 1; + } + gdcs.disp = (mode >> 4) & 1; + if (!(mode & 0x20)) { + gdc.mode1 &= ~0x04; + } + else { + gdc.mode2 |= 0x04; + } + gdcs.grphdisp |= GDCSCRN_ALLDRAW2; + screenupdate |= 2; +} static void setbiosgdc(UINT32 csrw, const GDCVECT *vect, UINT8 ope) { @@ -164,7 +298,7 @@ static void setbiosgdc(UINT32 csrw, cons } -static void bios18_47(void) { +static void bios0x18_47(void) { UCWTBL ucw; GDCVECT vect; @@ -181,14 +315,8 @@ static void bios18_47(void) { SINT16 dx; SINT16 dy; - // GDCバッファを空に - if (gdc.s.cnt) { - gdc_work(GDCWORK_SLAVE); - } - gdc_forceready(&gdc.s); - + gdc_forceready(GDCWORK_SLAVE); i286_memstr_read(CPU_DS, CPU_BX, &ucw, sizeof(ucw)); - GBSX1 = LOADINTELWORD(ucw.GBSX1); GBSY1 = LOADINTELWORD(ucw.GBSY1); GBSX2 = LOADINTELWORD(ucw.GBSX2); @@ -198,40 +326,7 @@ static void bios18_47(void) { data2 = 0; if (ucw.GBDTYP == 0x01) { func = gdcsub_vectl; - if ((GBSX1 > GBSX2) || - ((GBSX1 == GBSX2) && (GBSY1 > GBSY2))) { - SWAPU16(GBSX1, GBSX2); - SWAPU16(GBSY1, GBSY2); - } - dx = GBSX2 - GBSX1; - dy = GBSY2 - GBSY1; - if (dy > 0) { - if (dx < dy) { - vect.ope = 0; - SWAPU16(dx, dy); - } - else { - vect.ope = 1; - } - } - else { - dy = -dy; - if (dx > dy) { - vect.ope = 2; - } - else { - vect.ope = 3; - SWAPU16(dx, dy); - } - } - vect.ope += 0x08; - STOREINTELWORD(vect.DC, dx); - data = dy * 2; - STOREINTELWORD(vect.D1, data); - data -= dx; - STOREINTELWORD(vect.D, data); - data -= dx; - STOREINTELWORD(vect.D2, data); + gdcsub_setvectl(&vect, GBSX1, GBSY1, GBSX2, GBSY2); } else if (ucw.GBDTYP <= 0x02) { func = gdcsub_vectr; @@ -314,11 +409,11 @@ static void bios18_47(void) { // 最後に使った奴を記憶 *(UINT16 *)(mem + MEMW_PRXGLS) = *(UINT16 *)(ucw.GBMDOTI); - *(UINT16 *)(gdc.s.para + GDC_TEXTW) = *(UINT16 *)(ucw.GBMDOTI); + STOREINTELWORD(mem + GDC_TEXTW, GBMDOTI); setbiosgdc(csrw, &vect, ope); } -static void bios18_49(void) { +static void bios0x18_49(void) { UCWTBL ucw; UINT i; @@ -330,11 +425,7 @@ static void bios18_49(void) { UINT32 csrw; UINT8 ope; - // GDCバッファを空に - if (gdc.s.cnt) { - gdc_work(GDCWORK_SLAVE); - } - gdc_forceready(&gdc.s); + gdc_forceready(GDCWORK_SLAVE); i286_memstr_read(CPU_DS, CPU_BX, &ucw, sizeof(ucw)); for (i=0; i<8; i++) { @@ -389,10 +480,10 @@ void bios0x18(void) { BOOL b; UINT16 w; UINT32 d; + UINT8 col[4]; } tmp; UINT pos; - BYTE buf[34]; BYTE *p; int i; @@ -481,11 +572,7 @@ void bios0x18(void) { break; case 0x0e: // 一つの表示領域の設定 - // GDCバッファを空に - if (gdc.m.cnt) { - gdc_work(GDCWORK_MASTER); - } - gdc_forceready(&gdc.m); + gdc_forceready(GDCWORK_MASTER); ZeroMemory(&gdc.m.para[GDC_SCROLL], 16); tmp.w = CPU_DX >> 1; @@ -502,11 +589,7 @@ void bios0x18(void) { break; case 0x0f: // 複数の表示領域の設定 - // GDCバッファを空に - if (gdc.m.cnt) { - gdc_work(GDCWORK_MASTER); - } - gdc_forceready(&gdc.m); + gdc_forceready(GDCWORK_MASTER); SETBIOSMEM16(0x0053e, CPU_CX); SETBIOSMEM16(0x00540, CPU_BX); @@ -541,21 +624,13 @@ void bios0x18(void) { break; case 0x10: // カーソルタイプの設定 - // GDCバッファを空に - if (gdc.m.cnt) { - gdc_work(GDCWORK_MASTER); - } - gdc_forceready(&gdc.m); + gdc_forceready(GDCWORK_MASTER); bios0x18_10((REG8)(CPU_AL & 1)); break; case 0x11: // カーソルの表示開始 - // GDCバッファを空に - if (gdc.m.cnt) { - gdc_work(GDCWORK_MASTER); - } - gdc_forceready(&gdc.m); + gdc_forceready(GDCWORK_MASTER); if (gdc.m.para[GDC_CSRFORM] != (mem[MEMB_CRT_RASTER] | 0x80)) { gdc.m.para[GDC_CSRFORM] = mem[MEMB_CRT_RASTER] | 0x80; @@ -564,11 +639,7 @@ void bios0x18(void) { break; case 0x12: // カーソルの表示停止 - // GDCバッファを空に - if (gdc.m.cnt) { - gdc_work(GDCWORK_MASTER); - } - gdc_forceready(&gdc.m); + gdc_forceready(GDCWORK_MASTER); if (gdc.m.para[GDC_CSRFORM] != mem[MEMB_CRT_RASTER]) { gdc.m.para[GDC_CSRFORM] = mem[MEMB_CRT_RASTER]; @@ -577,11 +648,7 @@ void bios0x18(void) { break; case 0x13: // カーソル位置の設定 - // GDCバッファを空に - if (gdc.m.cnt) { - gdc_work(GDCWORK_MASTER); - } - gdc_forceready(&gdc.m); + gdc_forceready(GDCWORK_MASTER); tmp.w = CPU_DX >> 1; if (LOADINTELWORD(gdc.m.para + GDC_CSRW) != tmp.w) { @@ -591,41 +658,7 @@ void bios0x18(void) { break; case 0x14: // フォントパターンの読み出し - switch(CPU_DH) { - case 0x00: // 8x8 - i286_memword_write(CPU_BX, CPU_CX, 0x0101); - i286_memstr_write(CPU_BX, CPU_CX + 2, - fontrom + 0x82000 + (CPU_DL << 4), 8); - break; - - case 0x28: // 8x16 KANJI - case 0x29: - case 0x2a: - case 0x2b: - i286_memword_write(CPU_BX, CPU_CX, 0x0102); - i286_memstr_write(CPU_BX, CPU_CX + 2, - fontrom + ((CPU_DL & 0x7f) << 12) - + ((CPU_DH - 0x20) << 4), 16); - break; - - case 0x80: // 8x16 ANK - i286_memword_write(CPU_BX, CPU_CX, 0x0102); - i286_memstr_write(CPU_BX, CPU_CX + 2, - fontrom + 0x80000 + (CPU_DL << 4), 16); - break; - - default: - buf[0] = 0x02; - buf[1] = 0x02; - p = fontrom + ((CPU_DL & 0x7f) << 12) - + (((CPU_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(CPU_BX, CPU_CX, buf, 34); - break; - } + bios0x18_14(CPU_BX, CPU_CX, CPU_DX); break; case 0x15: // ライトペン位置読みだし @@ -647,16 +680,7 @@ void bios0x18(void) { break; case 0x1a: // ユーザー文字の定義 - if ((CPU_DH & 0x7e) == 0x76) { - i286_memstr_read(CPU_BX, CPU_CX + 2, buf, 32); - p = fontrom + ((CPU_DL & 0x7f) << 12) - + (((CPU_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; - } + bios0x18_1a(CPU_BX, CPU_CX, CPU_DX); break; case 0x1b: // KCGアクセスモードの設定 @@ -676,85 +700,23 @@ void bios0x18(void) { break; case 0x40: // グラフィック画面の表示開始 - // GDCバッファを空に - if (gdc.s.cnt) { - gdc_work(GDCWORK_SLAVE); - } - if (!(gdcs.grphdisp & GDCSCRN_ENABLE)) { - gdcs.grphdisp |= GDCSCRN_ENABLE; - screenupdate |= 2; - } - mem[MEMB_PRXCRT] |= 0x80; + bios0x18_40(); break; case 0x41: // グラフィック画面の表示終了 - // GDCバッファを空に - if (gdc.s.cnt) { - gdc_work(GDCWORK_SLAVE); - } - gdc_forceready(&gdc.s); - if (gdcs.grphdisp & GDCSCRN_ENABLE) { - gdcs.grphdisp &= ~(GDCSCRN_ENABLE); - screenupdate |= 2; - } - mem[MEMB_PRXCRT] &= 0x7f; + bios0x18_41(); break; case 0x42: // 表示領域の設定 - // GDCバッファを空に - if (gdc.s.cnt) { - gdc_work(GDCWORK_SLAVE); - } - gdc_forceready(&gdc.s); - - ZeroMemory(&gdc.s.para[GDC_SCROLL], 8); - if ((CPU_CH & 0xc0) == 0xc0) { // ALL - tmp.b = FALSE; - if ((mem[MEMB_PRXDUPD] & 0x24) == 0x20) { - mem[MEMB_PRXDUPD] ^= 4; - gdc.clock |= 3; - CopyMemory(gdc.s.para + GDC_SYNC, sync400m, 8); - gdc.s.para[GDC_PITCH] = 80; - gdcs.grphdisp |= GDCSCRN_EXT; - mem[MEMB_PRXDUPD] |= 0x08; - } - } - else { - tmp.b = TRUE; - if ((mem[MEMB_PRXDUPD] & 0x24) == 0x24) { - mem[MEMB_PRXDUPD] ^= 4; - gdc.clock &= ~3; - CopyMemory(gdc.s.para + GDC_SYNC, - (mem[MEMB_PRXCRT] & 0x40)?sync200m:sync200l, 8); - gdc.s.para[GDC_PITCH] = 40; - gdcs.grphdisp |= GDCSCRN_EXT; - mem[MEMB_PRXDUPD] |= 0x08; - } - if (CPU_CH & 0x40) { // UPPER - gdc.s.para[GDC_SCROLL+0] = (200*40) & 0xff; - gdc.s.para[GDC_SCROLL+1] = (200*40) >> 8; - } - } - if ((!tmp.b) || (!(mem[MEMB_PRXCRT] & 0x40))) { - gdc.mode1 &= ~(0x10); - gdc.s.para[GDC_CSRFORM] = 0; - } - else { - gdc.mode1 |= 0x10; - gdc.s.para[GDC_CSRFORM] = 1; - } - gdcs.disp = (CPU_CH >> 4) & 1; - gdcs.grphdisp |= GDCSCRN_ALLDRAW2; - screenupdate |= 2; + bios0x18_42(CPU_CH); break; case 0x43: // パレットの設定 i286_memstr_read(CPU_DS, CPU_BX + offsetof(UCWTBL, GBCPC), - buf, 4); - tmp.d = LOADINTELDWORD(buf); - for (i=8; i--;) { - gdc_setdegitalpal(i, (REG8)(tmp.d & 15)); - tmp.d >>= 4; + tmp.col, 4); + for (i=0; i<4; i++) { + gdc_setdegitalpal(6 - (i*2), (REG8)(tmp.col[i] >> 4)); + gdc_setdegitalpal(7 - (i*2), (REG8)(tmp.col[i] & 15)); } break; @@ -771,11 +733,11 @@ void bios0x18(void) { case 0x47: // 直線、矩形の描画 case 0x48: // 円の描画 - bios18_47(); + bios0x18_47(); break; case 0x49: // グラフィック文字の描画 - bios18_49(); + bios0x18_49(); break; case 0x4a: // 描画モードの設定