diff --git a/bios/bios.c b/bios/bios.c index 5948ce7a..da52b1af 100644 --- a/bios/bios.c +++ b/bios/bios.c @@ -1,6 +1,6 @@ #include "compiler.h" #include "dosio.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -49,7 +49,7 @@ static void bios_reinitbyswitch(void) { BYTE biosflag; BYTE ext_mem; - CPUTYPE = 0; + CPU_TYPE = 0; prxcrt = 0xc8; if (gdc.display & 2) { prxcrt |= 0x04; // color16 @@ -80,7 +80,7 @@ static void bios_reinitbyswitch(void) { ext_mem = np2cfg.EXTMEM; // ver0.28 } else { - CPUTYPE = CPUTYPE_V30; + CPU_TYPE = CPUTYPE_V30; ext_mem = 0; biosflag |= 0x40; } @@ -231,19 +231,19 @@ static void bios_boot(void) { if (!(sysport.c & 0x20)) { bios_reinitbyswitch(); } - I286_CS = 0x0000; - I286_IP = 0x04f8; - I286_DS = 0x0000; - I286_DX = 0x43d; - I286_AL = 0x10; + CPU_CS = 0x0000; + CPU_IP = 0x04f8; + CPU_DS = 0x0000; + CPU_DX = 0x43d; + CPU_AL = 0x10; mem[0x004f8] = 0xee; // out dx, al mem[0x004f9] = 0xea; // call far SETBIOSMEM16(0x004fa, 0x0000); SETBIOSMEM16(0x004fc, 0xffff); } else { - I286_SP = GETBIOSMEM16(0x00404); - I286_SS = GETBIOSMEM16(0x00406); + CPU_SP = GETBIOSMEM16(0x00404); + CPU_SS = GETBIOSMEM16(0x00406); } } @@ -252,15 +252,15 @@ UINT MEMCALL biosfunc(UINT32 adrs) { UINT16 bootseg; - if ((i286core.s.itfbank) && (adrs >= 0xf8000) && (adrs < 0x100000)) { - I286_IP--; - I286_REMCLOCK = -1; + if ((CPU_ITFBANK) && (adrs >= 0xf8000) && (adrs < 0x100000)) { + CPU_IP--; + CPU_REMCLOCK = -1; return(1); } switch(adrs) { // ver0.30 case BIOS_BASE + BIOSOFST_EOIM: - I286_REMCLOCK -= 300; + CPU_REMCLOCK -= 300; iocore_out8(0x00, 0x20); return(0); @@ -272,78 +272,78 @@ UINT MEMCALL biosfunc(UINT32 adrs) { return(0); case BIOS_BASE + BIOSOFST_02: - I286_REMCLOCK -= 300; + CPU_REMCLOCK -= 300; bios0x02(); return(1); case BIOS_BASE + BIOSOFST_08: - I286_REMCLOCK -= 300; + CPU_REMCLOCK -= 300; bios0x08(); return(1); case BIOS_BASE + BIOSOFST_09: - I286_REMCLOCK -= 300; + CPU_REMCLOCK -= 300; bios0x09(); return(1); case BIOS_BASE + BIOSOFST_0c: - I286_REMCLOCK -= 500; + CPU_REMCLOCK -= 500; bios0x0c(); return(1); case BIOS_BASE + BIOSOFST_12: - I286_REMCLOCK -= 500; + CPU_REMCLOCK -= 500; bios0x12(); return(1); case BIOS_BASE + BIOSOFST_13: - I286_REMCLOCK -= 500; + CPU_REMCLOCK -= 500; bios0x13(); return(1); case BIOS_BASE + BIOSOFST_18: - I286_REMCLOCK -= 200; + CPU_REMCLOCK -= 200; bios0x18(); return(1); case BIOS_BASE + BIOSOFST_19: - I286_REMCLOCK -= 200; + CPU_REMCLOCK -= 200; bios0x19(); return(1); case BIOS_BASE + BIOSOFST_1a: - I286_REMCLOCK -= 200; + CPU_REMCLOCK -= 200; bios0x1a(); return(1); case BIOS_BASE + BIOSOFST_1b: - I286_REMCLOCK -= 200; + CPU_REMCLOCK -= 200; bios0x1b(); return(1); case BIOS_BASE + BIOSOFST_1c: - I286_REMCLOCK -= 200; + CPU_REMCLOCK -= 200; bios0x1c(); return(1); case BIOS_BASE + BIOSOFST_WAIT: - I286_STI; + CPU_STI; if (fddmtr_biosbusy) { // ver0.26 - I286_IP--; - I286_REMCLOCK = -1; + CPU_IP--; + CPU_REMCLOCK = -1; } else { switch(CTRL_FDMEDIA) { case DISKTYPE_2HD: if (pic.pi[1].isr & PIC_INT42) { - I286_IP--; - I286_REMCLOCK -= 1000; + CPU_IP--; + CPU_REMCLOCK -= 1000; } break; case DISKTYPE_2DD: if (pic.pi[1].isr & PIC_INT41) { - I286_IP--; - I286_REMCLOCK -= 1000; + CPU_IP--; + CPU_REMCLOCK -= 1000; } break; } @@ -362,29 +362,29 @@ UINT MEMCALL biosfunc(UINT32 adrs) { bios_reinitbyswitch(); // ver0.27 bios_vectorset(); // ver0.29 bootseg = bootstrapload(); - I286_STI; - I286_CS = (bootseg != 0)?bootseg:0xe800; - I286_DS = 0x0000; - I286_SS = 0x0030; - I286_SP = 0x00e6; - I286_IP = 0x0000; + CPU_STI; + CPU_CS = (bootseg != 0)?bootseg:0xe800; + CPU_DS = 0x0000; + CPU_SS = 0x0030; + CPU_SP = 0x00e6; + CPU_IP = 0x0000; return(1); case 0xfffe8: // ブートストラップロード - I286_REMCLOCK -= 2000; + CPU_REMCLOCK -= 2000; bootseg = bootstrapload(); if (bootseg) { - I286_STI; - I286_CS = bootseg; - I286_IP = 0x0000; - I286_SS = 0x0030; - I286_SP = 0x00e6; + CPU_STI; + CPU_CS = bootseg; + CPU_IP = 0x0000; + CPU_SS = 0x0030; + CPU_SP = 0x00e6; return(1); } return(0); case 0xfffec: - I286_REMCLOCK -= 2000; + CPU_REMCLOCK -= 2000; bootstrapload(); return(0); } @@ -399,8 +399,8 @@ UINT MEMCALL biosfunc(UINT32 adrs) { if (biosrom) { return(0); } - I286_IP--; - I286_REMCLOCK = -1; + CPU_IP--; + CPU_REMCLOCK = -1; return(1); } diff --git a/bios/bios02.c b/bios/bios02.c index 69d393cc..6054b5c3 100644 --- a/bios/bios02.c +++ b/bios/bios02.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -42,8 +42,8 @@ void bios0x02(void) { textout(ptr, msg4); mem[0x004f8] = 0xfa; // cli mem[0x004f9] = 0xf4; // hlt - I286_CS = 0; - I286_IP = 0x4f8; + CPU_CS = 0; + CPU_IP = 0x4f8; } } diff --git a/bios/bios08.c b/bios/bios08.c index c28363af..389f6de8 100644 --- a/bios/bios08.c +++ b/bios/bios08.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -17,7 +17,7 @@ void bios0x08(void) { if (catimcnt == 0) { pic.pi[0].imr |= PIC_SYSTEMTIMER; iocore_out8(0x00, 0x20); - i286_interrupt(7); + CPU_INTERRUPT(7); } else { iocore_out8(0x00, 0x20); diff --git a/bios/bios09.c b/bios/bios09.c index 2ee26a39..c8e0544c 100644 --- a/bios/bios09.c +++ b/bios/bios09.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -87,10 +87,10 @@ void bios0x09(void) { } else { if (key == 0x60) { - i286_interrupt(6); + CPU_INTERRUPT(6); } else if (key == 0x61) { - i286_interrupt(5); + CPU_INTERRUPT(5); } else if (key < 0x70) { code = mem[base + key - 0x0c] << 8; diff --git a/bios/bios0c.c b/bios/bios0c.c index a1a85940..bdbdef36 100644 --- a/bios/bios0c.c +++ b/bios/bios0c.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +// #include "i286.h" #include "memory.h" #include "pccore.h" #include "iocore.h" diff --git a/bios/bios12.c b/bios/bios12.c index 9d9bc785..ba3ab3f7 100644 --- a/bios/bios12.c +++ b/bios/bios12.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +// #include "i286.h" #include "memory.h" #include "pccore.h" #include "iocore.h" diff --git a/bios/bios13.c b/bios/bios13.c index 559fbba4..4c29d183 100644 --- a/bios/bios13.c +++ b/bios/bios13.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +// #include "i286.h" #include "memory.h" #include "pccore.h" #include "iocore.h" diff --git a/bios/bios18.c b/bios/bios18.c index ddd2c60a..7ea6d035 100644 --- a/bios/bios18.c +++ b/bios/bios18.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -103,7 +103,7 @@ static void bios18_47(void) { } gdc_forceready(&gdc.s); - i286_memstr_read(I286_DS, I286_BX, &ucw, sizeof(ucw)); + i286_memstr_read(CPU_DS, CPU_BX, &ucw, sizeof(ucw)); GBSX1 = LOADINTELWORD(ucw.GBSX1); GBSY1 = LOADINTELWORD(ucw.GBSY1); GBSX2 = LOADINTELWORD(ucw.GBSX2); @@ -165,13 +165,13 @@ static void bios18_47(void) { else { return; } - if ((I286_CH & 0xc0) == 0x40) { + if ((CPU_CH & 0xc0) == 0x40) { GBSY1 += 200; } csrw = (GBSY1 * 40) + (GBSX1 >> 4); csrw += (GBSX1 & 0xf) << 20; GBMDOTI = LOADINTELWORD(ucw.GBMDOTI); - if ((I286_CH & 0x30) == 0x30) { + if ((CPU_CH & 0x30) == 0x30) { if (ucw.GBON_PTN & 1) { func(0x04000 + csrw, &vect, GBMDOTI, GDCOPE_SET); } @@ -192,7 +192,7 @@ static void bios18_47(void) { } } else { - func(csrw + 0x4000 + ((I286_CH & 0x30) << 10), &vect, + func(csrw + 0x4000 + ((CPU_CH & 0x30) << 10), &vect, GBMDOTI, ucw.GBDOTU); } } @@ -206,26 +206,27 @@ void bios0x18(void) { UINT16 tmp; UINT32 pal; -// TRACE_("int18", I286_AH); +// TRACE_("int18", CPU_AH); sti_waiting ^= 1; if (sti_waiting) { // 割込み許可の遊び - I286_STI; + CPU_STI; if (PICEXISTINTR) { - I286_IP--; + CPU_IP--; nevent_forceexit(); return; } } + sti_waiting = 0; - switch(I286_AH) { + switch(CPU_AH) { case 0x00: // キー・データの読みだし if (mem[MEMB_KB_COUNT]) { - I286_AX = keyget(); + CPU_AX = keyget(); } else { - I286_IP--; - I286_REMCLOCK = -1; + CPU_IP--; + CPU_REMCLOCK = -1; break; } break; @@ -233,16 +234,16 @@ void bios0x18(void) { case 0x01: // キー・バッファ状態のセンス if (mem[MEMB_KB_COUNT]) { pos = GETBIOSMEM16(MEMW_KB_BUF_HEAD); - I286_AX = GETBIOSMEM16(pos); - I286_BH = 1; + CPU_AX = GETBIOSMEM16(pos); + CPU_BH = 1; } else { - I286_BH = 0; + CPU_BH = 0; } break; case 0x02: // シフト・キー状態のセンス - I286_AL = mem[MEMB_SHIFT_STS]; + CPU_AL = mem[MEMB_SHIFT_STS]; break; case 0x03: // キーボード・インタフェイスの初期化 @@ -250,22 +251,22 @@ void bios0x18(void) { break; case 0x04: // キー入力状態のセンス - I286_AH = mem[0x00052a + (I286_AL & 0x0f)]; + CPU_AH = mem[0x00052a + (CPU_AL & 0x0f)]; break; case 0x05: // キー入力センス if (mem[MEMB_KB_COUNT]) { - I286_AX = keyget(); - I286_BH = 1; + CPU_AX = keyget(); + CPU_BH = 1; } else { - I286_BH = 0; + CPU_BH = 0; } break; case 0x0a: // CRTモードの設定 #if 1 - mem[MEMB_CRT_STS_FLAG] = 0x80 | (I286_AL & 0x0f); + mem[MEMB_CRT_STS_FLAG] = 0x80 | (CPU_AL & 0x0f); // GDCバッファを空に if (gdc.m.cnt) { gdc_work(GDCWORK_MASTER); @@ -274,16 +275,16 @@ void bios0x18(void) { gdc.mode1 &= ~(0x25); gdc.mode1 |= 0x08; - if (I286_AL & 0x02) { + if (CPU_AL & 0x02) { gdc.mode1 |= 0x04; // 40桁 } - if (I286_AL & 0x04) { + if (CPU_AL & 0x04) { gdc.mode1 |= 0x01; // アトリビュート } - if (I286_AL & 0x08) { + if (CPU_AL & 0x08) { gdc.mode1 |= 0x20; // コードアクセス } - if (I286_AL & 0x01) { // 20行 + if (CPU_AL & 0x01) { // 20行 mem[MEMB_CRT_RASTER] = 0x13; gdc.m.para[GDC_CSRFORM + 0] = 0x13; gdc.m.para[GDC_CSRFORM + 1] = 0x00; @@ -311,14 +312,14 @@ void bios0x18(void) { } gdc_forceready(&gdc.m); - mem[MEMB_CRT_STS_FLAG] = I286_AL; + mem[MEMB_CRT_STS_FLAG] = CPU_AL; if (systemport_r(0x33) & 0x08) { mem[MEMB_CRT_STS_FLAG] |= 0x80; } #endif case 0x0b: // CRTモードのセンス - I286_AL = mem[MEMB_CRT_STS_FLAG]; + CPU_AL = mem[MEMB_CRT_STS_FLAG]; break; case 0x0c: // テキスト画面の表示開始 @@ -343,27 +344,27 @@ void bios0x18(void) { gdc_forceready(&gdc.m); ZeroMemory(&gdc.m.para[GDC_SCROLL], 16); - tmp = I286_DX >> 1; + tmp = CPU_DX >> 1; STOREINTELWORD(gdc.m.para + GDC_SCROLL, tmp); gdcs.textdisp |= GDCSCRN_ALLDRAW2; screenupdate |= 2; break; case 0x0f: // 複数の表示領域の設定 - SETBIOSMEM16(0x0053e, I286_CX); - SETBIOSMEM16(0x00540, I286_BX); - mem[0x00547] = I286_DH; - mem[0x0053D] = I286_DL; + SETBIOSMEM16(0x0053e, CPU_CX); + SETBIOSMEM16(0x00540, CPU_BX); + mem[0x00547] = CPU_DH; + mem[0x0053D] = CPU_DL; // wait sync int - if ((i = I286_DL) > 0) { - pos = I286_CX; - p = gdc.m.para + GDC_SCROLL + (I286_DH << 2); + if ((i = CPU_DL) > 0) { + pos = CPU_CX; + p = gdc.m.para + GDC_SCROLL + (CPU_DH << 2); while((i--) && (p < (gdc.m.para + GDC_SCROLL + 0x10))) { REG16 t; - t = i286_memword_read(I286_BX, pos); + t = i286_memword_read(CPU_BX, pos); t >>= 1; STOREINTELWORD(p, t); - t = i286_memword_read(I286_BX, pos + 2); + t = i286_memword_read(CPU_BX, pos + 2); if (!(mem[MEMB_CRT_STS_FLAG] & 1)) { // 25 t *= (16 * 16); } @@ -391,7 +392,7 @@ void bios0x18(void) { gdc.m.para[GDC_CSRFORM + 0] &= 0x7f; gdc.m.para[GDC_CSRFORM + 1] &= 0xdf; - gdc.m.para[GDC_CSRFORM + 1] |= (I286_AL & 1) << 5; + gdc.m.para[GDC_CSRFORM + 1] |= (CPU_AL & 1) << 5; gdcs.textdisp |= GDCSCRN_EXT; break; @@ -428,7 +429,7 @@ void bios0x18(void) { } gdc_forceready(&gdc.m); - tmp = I286_DX >> 1; + tmp = CPU_DX >> 1; if (LOADINTELWORD(gdc.m.para + GDC_CSRW) != tmp) { STOREINTELWORD(gdc.m.para + GDC_CSRW, tmp); gdcs.textdisp |= GDCSCRN_EXT; @@ -436,39 +437,39 @@ void bios0x18(void) { break; case 0x14: // フォントパターンの読み出し - switch(I286_DH) { + switch(CPU_DH) { 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); + i286_memword_write(CPU_BX, CPU_CX, 0x0101); + i286_memstr_write(CPU_BX, CPU_CX + 2, + fontrom + 0x82000 + (CPU_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); + 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(I286_BX, I286_CX, 0x0102); - i286_memstr_write(I286_BX, I286_CX+2, - fontrom + 0x80000 + (I286_DL << 4), 16); + 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 + ((I286_DL & 0x7f) << 12) - + (((I286_DH - 0x20) & 0x7f) << 4); + 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(I286_BX, I286_CX, buf, 34); + i286_memstr_write(CPU_BX, CPU_CX, buf, 34); break; } break; @@ -477,7 +478,7 @@ void bios0x18(void) { break; case 0x16: // テキストVRAMの初期化 - bios0x18_16(I286_DL, I286_DH); + bios0x18_16(CPU_DL, CPU_DH); break; case 0x17: // ブザーの起呼 @@ -492,10 +493,10 @@ void bios0x18(void) { break; case 0x1a: // ユーザー文字の定義 - if ((I286_DH & 0x7e) == 0x76) { - i286_memstr_read(I286_BX, I286_CX+2, buf, 32); - p = fontrom + ((I286_DL & 0x7f) << 12) - + (((I286_DH - 0x20) & 0x7f) << 4); + 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]; @@ -505,7 +506,7 @@ void bios0x18(void) { break; case 0x1b: // KCGアクセスモードの設定 - switch(I286_AL) { // 実装し忘れ // ver0.28 + switch(CPU_AL) { case 0: mem[MEMB_CRT_STS_FLAG] &= ~0x08; gdc.mode1 &= ~0x20; @@ -542,7 +543,7 @@ void bios0x18(void) { gdc_forceready(&gdc.s); ZeroMemory(&gdc.s.para[GDC_SCROLL], 8); - switch(I286_CH & 0xc0) { + switch(CPU_CH & 0xc0) { case 0x40: // UPPER if ((mem[MEMB_PRXDUPD] & 0x24) == 0x24) { mem[MEMB_PRXDUPD] ^= 4; @@ -578,13 +579,13 @@ void bios0x18(void) { gdc.s.para[GDC_CSRFORM] = 0; break; } - gdcs.disp = (I286_CH >> 4) & 1; // 00/05/23 + gdcs.disp = (CPU_CH >> 4) & 1; gdcs.grphdisp |= GDCSCRN_ALLDRAW2; screenupdate |= 2; break; case 0x43: // パレットの設定 - i286_memstr_read(I286_DS, I286_BX + offsetof(UCWTBL, GBCPC), + i286_memstr_read(CPU_DS, CPU_BX + offsetof(UCWTBL, GBCPC), buf, 4); pal = LOADINTELDWORD(buf); for (i=8; i--;) { diff --git a/bios/bios19.c b/bios/bios19.c index 08057137..1c1293c7 100644 --- a/bios/bios19.c +++ b/bios/bios19.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -28,10 +28,10 @@ void bios0x19(void) { UINT16 dseg; BYTE flag; - if (I286_AH < 2) { + if (CPU_AH < 2) { // 通信速度… - mode = I286_CH | 0x02; - speed = I286_AL; + mode = CPU_CH | 0x02; + speed = CPU_AL; if (speed >= 8) { speed = 4; // 1200bps } @@ -56,69 +56,69 @@ void bios0x19(void) { iocore_out8(0x32, 0x00); // dummy instruction iocore_out8(0x32, 0x40); // reset iocore_out8(0x32, mode); // mode - iocore_out8(0x32, I286_CL); // cmd + iocore_out8(0x32, CPU_CL); // cmd #endif iocore_out8(0x77, 0xb6); iocore_out8(0x75, (BYTE)rs_speed[speed]); iocore_out8(0x75, (BYTE)(rs_speed[speed] >> 8)); ZeroMemory(&rsb, sizeof(rsb)); - rsb.FLAG = (I286_AH << 4); - rsb.CMD = I286_CL; + rsb.FLAG = (CPU_AH << 4); + rsb.CMD = CPU_CL; sysport.c &= ~7; - if (!(I286_CL & RCMD_IR)) { + if (!(CPU_CL & RCMD_IR)) { rsb.FLAG |= RFLAG_INIT; - if (I286_CL & RCMD_RXE) { + if (CPU_CL & RCMD_RXE) { sysport.c |= 1; pic.pi[0].imr &= ~PIC_RS232C; } } - rsb.STIME = I286_BH; + rsb.STIME = CPU_BH; if (!rsb.STIME) { rsb.STIME = 0x04; } - rsb.RTIME = I286_BL; + rsb.RTIME = CPU_BL; if (!rsb.RTIME) { rsb.RTIME = 0x40; } - doff = I286_DI + sizeof(RSBIOS); + doff = CPU_DI + sizeof(RSBIOS); STOREINTELWORD(rsb.HEADP, doff); STOREINTELWORD(rsb.PUTP, doff); STOREINTELWORD(rsb.GETP, doff); - doff += I286_DX; + doff += CPU_DX; STOREINTELWORD(rsb.TAILP, doff); - cnt = I286_DX >> 3; + cnt = CPU_DX >> 3; STOREINTELWORD(rsb.XOFF, cnt); - cnt += I286_DX >> 2; + cnt += CPU_DX >> 2; STOREINTELWORD(rsb.XON, cnt); // ポインタ〜 - SETBIOSMEM16(MEMW_RS_CH0_OFST, I286_DI); - SETBIOSMEM16(MEMW_RS_CH0_SEG, I286_ES); - i286_memstr_write(I286_ES, I286_DI, &rsb, sizeof(rsb)); + SETBIOSMEM16(MEMW_RS_CH0_OFST, CPU_DI); + SETBIOSMEM16(MEMW_RS_CH0_SEG, CPU_ES); + i286_memstr_write(CPU_ES, CPU_DI, &rsb, sizeof(rsb)); - I286_AH = 0; + CPU_AH = 0; } - else if (I286_AH < 7) { + else if (CPU_AH < 7) { doff = GETBIOSMEM16(MEMW_RS_CH0_OFST); dseg = GETBIOSMEM16(MEMW_RS_CH0_SEG); if ((!doff) && (!dseg)) { - I286_AH = 1; + CPU_AH = 1; return; } flag = i286_membyte_read(dseg, doff + R_FLAG); if (!(flag & RFLAG_INIT)) { - I286_AH = 1; + CPU_AH = 1; return; } - switch(I286_AH) { + switch(CPU_AH) { case 0x02: - I286_CX = i286_memword_read(dseg, doff + R_CNT); + CPU_CX = i286_memword_read(dseg, doff + R_CNT); break; case 0x03: - iocore_out8(0x30, I286_AL); + iocore_out8(0x30, CPU_AL); break; case 0x04: @@ -128,7 +128,7 @@ void bios0x19(void) { // データ引き取り pos = i286_memword_read(dseg, doff + R_GETP); - I286_CX = i286_memword_read(dseg, pos); + CPU_CX = i286_memword_read(dseg, pos); // 次のポインタをストア pos += 2; @@ -148,24 +148,24 @@ void bios0x19(void) { flag &= ~RFLAG_XOFF; } flag &= ~RFLAG_BOVF; - I286_AH = 0; + CPU_AH = 0; i286_membyte_write(dseg, doff + R_FLAG, flag); return; } else { - I286_AH = 3; + CPU_AH = 3; } break; case 0x05: - iocore_out8(0x32, I286_AL); - if (I286_AL & RCMD_IR) { + iocore_out8(0x32, CPU_AL); + if (CPU_AL & RCMD_IR) { flag &= ~RFLAG_INIT; i286_membyte_write(dseg, doff + R_FLAG, flag); sysport.c &= ~1; pic.pi[0].imr |= PIC_RS232C; } - else if (!(I286_AL & RCMD_RXE)) { + else if (!(CPU_AL & RCMD_RXE)) { sysport.c &= ~1; pic.pi[0].imr |= PIC_RS232C; } @@ -173,22 +173,22 @@ void bios0x19(void) { sysport.c |= 1; pic.pi[0].imr &= ~PIC_RS232C; } - i286_membyte_write(dseg, doff + R_CMD, I286_AL); + i286_membyte_write(dseg, doff + R_CMD, CPU_AL); break; case 0x06: - I286_CH = iocore_inp8(0x32); - I286_CL = iocore_inp8(0x33); + CPU_CH = iocore_inp8(0x32); + CPU_CL = iocore_inp8(0x33); break; } - I286_AH = 0; + CPU_AH = 0; if (flag & RFLAG_BOVF) { i286_membyte_write(dseg, doff + R_FLAG, (BYTE)(flag & (~RFLAG_BOVF))); - I286_AH = 2; + CPU_AH = 2; } } else { - I286_AH = 0; + CPU_AH = 0; } } diff --git a/bios/bios1a.c b/bios/bios1a.c index 76e7beff..a89ca0c2 100644 --- a/bios/bios1a.c +++ b/bios/bios1a.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -9,37 +9,37 @@ static void printerbios_11(void) { if (iocore_inp8(0x42) & 0x04) { // busy? - I286_AH = 0x01; - iocore_out8(0x40, I286_AL); + CPU_AH = 0x01; + iocore_out8(0x40, CPU_AL); #if 0 iocore_out8(0x46, 0x0e); iocore_out8(0x46, 0x0f); #endif } else { - I286_AH = 0x02; + CPU_AH = 0x02; } } void bios0x1a_main(void) { // ver0.30 - switch(I286_AH & 0x0f) { + switch(CPU_AH & 0x0f) { case 0x00: - if (I286_AH == 0x30) { - if (I286_CX) { + if (CPU_AH == 0x30) { + if (CPU_CX) { do { - I286_AL = i286_membyte_read(I286_ES, I286_BX); + CPU_AL = i286_membyte_read(CPU_ES, CPU_BX); printerbios_11(); - if (I286_AH & 0x02) { - I286_AH = 0x02; + if (CPU_AH & 0x02) { + CPU_AH = 0x02; return; } - I286_BX++; - } while(--I286_CX); - I286_AH = 0x00; + CPU_BX++; + } while(--CPU_CX); + CPU_AH = 0x00; } else { - I286_AH = 0x02; + CPU_AH = 0x02; } } else { @@ -47,32 +47,32 @@ void bios0x1a_main(void) { // ver0.30 iocore_out8(0x46, 0x82); // reset iocore_out8(0x46, 0x0f); // PSTB inactive iocore_out8(0x37, 0x0c); // printer f/f - I286_AH = (iocore_inp8(0x42) >> 2) & 1; + CPU_AH = (iocore_inp8(0x42) >> 2) & 1; } break; case 0x01: printerbios_11(); break; case 0x02: - I286_AH = (iocore_inp8(0x42) >> 2) & 1; + CPU_AH = (iocore_inp8(0x42) >> 2) & 1; break; default: - I286_AH = 0x00; + CPU_AH = 0x00; break; } } void bios0x1a(void) { - if (I286_AH & 0x10) { + if (CPU_AH & 0x10) { bios0x1a_main(); // ver0.30 } else { - if (I286_AH == 0x04) { - I286_AH = 0x02; + if (CPU_AH == 0x04) { + CPU_AH = 0x02; } else { - I286_AH = 0x00; + CPU_AH = 0x00; } } } diff --git a/bios/bios1b.c b/bios/bios1b.c index d6843d4a..77438b09 100644 --- a/bios/bios1b.c +++ b/bios/bios1b.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -37,10 +37,10 @@ static void init_fdd_equip(void) { static void biosfd_setchrn(void) { - fdc.C = I286_CL; - fdc.H = I286_DH; - fdc.R = I286_DL; - fdc.N = I286_CH; + fdc.C = CPU_CL; + fdc.H = CPU_DH; + fdc.R = CPU_DL; + fdc.N = CPU_CH; } #if 0 @@ -102,7 +102,7 @@ static UINT16 fdfmt_biospara(BYTE fmt, BYTE rpm) { // ver0.31 off += fdc.us * 2; off = i286_memword_read(seg, off); off += n * 8; - if (!(I286_AH & 0x40)) { + if (!(CPU_AH & 0x40)) { off += 4; } if (fmt) { @@ -137,7 +137,7 @@ static void fdd_int(int result) { if (result == FDCBIOS_NORESULT) { // ver0.29 return; } - switch(I286_AH & 0x0f) { + switch(CPU_AH & 0x0f) { case 0x00: // シーク case 0x01: // ベリファイ case 0x02: // 診断の為の読み込み @@ -197,11 +197,11 @@ static struct { static void b0patch(void) { - if ((!b0p.flg) || (b0p.cx != I286_CX) || (b0p.dx != I286_DX)) { + if ((!b0p.flg) || (b0p.cx != CPU_CX) || (b0p.dx != CPU_DX)) { b0p.flg = TRUE; b0p.pos = 0; - b0p.cx = I286_CX; - b0p.dx = I286_DX; + b0p.cx = CPU_CX; + b0p.dx = CPU_DX; } else { if (!b0p.pos) { @@ -211,8 +211,8 @@ static void b0patch(void) { REG8 c; REG8 cl; REG8 last; - addr = ES_BASE + I286_BP; - size = I286_BX; + addr = ES_BASE + CPU_BP; + size = CPU_BX; cnt = 0; last = 0; while(size--) { @@ -239,10 +239,10 @@ static void b0patch(void) { } } } - if ((b0p.pos >> 3) < I286_BX) { + if ((b0p.pos >> 3) < CPU_BX) { UINT32 addr; REG8 c; - addr = ES_BASE + I286_BP + (b0p.pos >> 3); + addr = ES_BASE + CPU_BP + (b0p.pos >> 3); c = i286_memoryread(addr); c ^= (1 << (b0p.pos & 7)); b0p.pos++; @@ -277,13 +277,13 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 // とりあえずBIOSの時は無視する fdc.mf = 0xff; // ver0.29 -// TRACE_("int 1Bh", I286_AH); +// TRACE_("int 1Bh", CPU_AH); change_rpm(rpm); // ver0.31 - if ((I286_AH & 0x0f) != 0x0a) { + if ((CPU_AH & 0x0f) != 0x0a) { fdc.crcn = 0; } - if ((I286_AH & 0x0f) != 0x03) { + if ((CPU_AH & 0x0f) != 0x03) { CTRL_FDMEDIA = type; switch(type) { case DISKTYPE_2HD: @@ -297,21 +297,21 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 } break; } - if (fdc.us != (I286_AL & 0x03)) { - fdc.us = I286_AL & 0x03; + if (fdc.us != (CPU_AL & 0x03)) { + fdc.us = CPU_AL & 0x03; fdc.crcn = 0; } - hd = ((I286_DH) ^ (I286_AL >> 2)) & 1; + hd = ((CPU_DH) ^ (CPU_AL >> 2)) & 1; if (fdc.hd != hd) { fdc.hd = hd; fdc.crcn = 0; } if (!fdd_diskready(fdc.us)) { fdd_int(FDCBIOS_NONREADY); - if (I286_AH == 0x84) { // ver0.28 + if (CPU_AH == 0x84) { // ver0.28 return(0x68); // 新センスは 両用ドライブ情報も } - if (I286_AH == 0xc4) { // ver0.31 + if (CPU_AH == 0xc4) { // ver0.31 if (np2cfg.usefd144) { return(0x6c); } @@ -328,10 +328,10 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 } } - switch(I286_AH & 0x0f) { + switch(CPU_AH & 0x0f) { case 0x00: // シーク - if (I286_AH & 0x10) { - if (!biosfd_seek(I286_CL, ndensity)) { + if (CPU_AH & 0x10) { + if (!biosfd_seek(CPU_CL, ndensity)) { result = FDCBIOS_SEEKSUCCESS; } else { @@ -342,8 +342,8 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 break; case 0x01: // ベリファイ - if (I286_AH & 0x10) { - if (!biosfd_seek(I286_CL, ndensity)) { + if (CPU_AH & 0x10) { + if (!biosfd_seek(CPU_CL, ndensity)) { result = FDCBIOS_SEEKSUCCESS; } else { @@ -364,7 +364,7 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 else { secsize = 128 << 8; } - size = I286_BX; + size = CPU_BX; while(size) { if (size > secsize) { accesssize = secsize; @@ -377,7 +377,7 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 } size -= accesssize; mtr_r += accesssize; // ver0.26 - if ((fdc.R++ == (BYTE)para) && (I286_AH & 0x80) && (!fdc.hd)) { + if ((fdc.R++ == (BYTE)para) && (CPU_AH & 0x80) && (!fdc.hd)) { fdc.hd = 1; fdc.H = 1; fdc.R = 1; @@ -409,7 +409,7 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 else if (fdd_diskprotect(fdc.us)) { ret_ah = 0x10; } - if (I286_AL & 0x80) { // 2HD + if (CPU_AL & 0x80) { // 2HD ret_ah |= 0x01; } else { // 2DD @@ -420,9 +420,9 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 ret_ah |= 0x04; } } - if (I286_AH & 0x80) { // ver0.30 + if (CPU_AH & 0x80) { // ver0.30 ret_ah |= 8; // 1MB/640KB両用ドライブ - if ((I286_AH & 0x40) && + if ((CPU_AH & 0x40) && (np2cfg.usefd144)) { // ver0.31 ret_ah |= 4; // 1.44対応ドライブ } @@ -430,8 +430,8 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 break; case 0x05: // データの書き込み - if (I286_AH & 0x10) { - if (!biosfd_seek(I286_CL, ndensity)) { + if (CPU_AH & 0x10) { + if (!biosfd_seek(CPU_CL, ndensity)) { result = FDCBIOS_SEEKSUCCESS; } else { @@ -457,8 +457,8 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 else { secsize = 128 << 8; } - size = I286_BX; - addr = ES_BASE + I286_BP; + size = CPU_BX; + addr = ES_BASE + CPU_BP; while(size) { if (size > secsize) { accesssize = secsize; @@ -473,7 +473,7 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 addr += accesssize; size -= accesssize; mtr_r += accesssize; // ver0.26 - if ((fdc.R++ == (BYTE)para) && (I286_AH & 0x80) && (!fdc.hd)) { + if ((fdc.R++ == (BYTE)para) && (CPU_AH & 0x80) && (!fdc.hd)) { fdc.hd = 1; fdc.H = 1; fdc.R = 1; @@ -494,8 +494,8 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 case 0x02: // 診断の為の読み込み case 0x06: // データの読み込み - if (I286_AH & 0x10) { - if (!biosfd_seek(I286_CL, ndensity)) { + if (CPU_AH & 0x10) { + if (!biosfd_seek(CPU_CL, ndensity)) { result = FDCBIOS_SEEKSUCCESS; } else { @@ -522,8 +522,8 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 else { secsize = 128 << 8; } - size = I286_BX; - addr = ES_BASE + I286_BP; + size = CPU_BX; + addr = ES_BASE + CPU_BP; while(size) { if (size > secsize) { accesssize = secsize; @@ -539,7 +539,7 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 size -= accesssize; mtr_r += accesssize; // ver0.26 if (fdc.R++ == (BYTE)para) { - if ((I286_AH & 0x80) && (!fdc.hd)) { + if ((CPU_AH & 0x80) && (!fdc.hd)) { fdc.hd = 1; fdc.H = 1; fdc.R = 1; @@ -569,7 +569,7 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 #endif } #if 1 - else if ((I286_AH & 0x0f) == 0x02) { // ARS対策… + else if ((CPU_AH & 0x0f) == 0x02) { // ARS対策… ret_ah = 0x00; result = FDCBIOS_READERROR; } @@ -587,9 +587,9 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 break; case 0x0a: // READ ID - fdc.mf = I286_AH & 0x40; // ver0.29 - if (I286_AH & 0x10) { // ver0.28 - if (!biosfd_seek(I286_CL, ndensity)) { + fdc.mf = CPU_AH & 0x40; // ver0.29 + if (CPU_AH & 0x10) { // ver0.28 + if (!biosfd_seek(CPU_CL, ndensity)) { result = FDCBIOS_SEEKSUCCESS; } else { @@ -609,23 +609,23 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 mtr_r += 128 << 8; } ret_ah = 0x00; - I286_CL = fdc.C; - I286_DH = fdc.H; - I286_DL = fdc.R; - I286_CH = fdc.N; + CPU_CL = fdc.C; + CPU_DH = fdc.H; + CPU_DL = fdc.R; + CPU_CH = fdc.N; result = FDCBIOS_SUCCESS; break; case 0x0d: // フォーマット - if (I286_AH & 0x10) { - biosfd_seek(I286_CL, ndensity); + if (CPU_AH & 0x10) { + biosfd_seek(CPU_CL, ndensity); } if (fdd_diskprotect(fdc.us)) { ret_ah = 0x70; break; } - fdc.d = I286_DL; - fdc.N = I286_CH; + fdc.d = CPU_DL; + fdc.N = CPU_CH; para = fdfmt_biospara(1, rpm); if (!para) { ret_ah = 0xd0; @@ -633,9 +633,9 @@ static BYTE fdd_operate(BYTE type, BOOL ndensity, BYTE rpm) { // ver0.31 } fdc.sc = (BYTE)para; fdd_formatinit(); - pos = I286_BP; + pos = CPU_BP; for (s=0; s> 4; - if ((I286_AL & 0x0f) >= 2) { + np2drv = (CPU_AL & 0x20) >> 4; + if ((CPU_AL & 0x0f) >= 2) { return(0x60); } - np2drv |= (I286_AL & 1); + np2drv |= (CPU_AL & 1); sxsi = &sxsi_hd[np2drv]; - if (I286_AL & 0x80) { - if ((I286_DL >= sxsi->sectors) || - (I286_DH >= sxsi->surfaces) || - (I286_CX >= sxsi->tracks)) { + if (CPU_AL & 0x80) { + if ((CPU_DL >= sxsi->sectors) || + (CPU_DH >= sxsi->surfaces) || + (CPU_CX >= sxsi->tracks)) { return(0xd0); } - (*pos) = ((I286_CX * sxsi->surfaces) + I286_DH) * sxsi->sectors - + I286_DL; + (*pos) = ((CPU_CX * sxsi->surfaces) + CPU_DH) * sxsi->sectors + + CPU_DL; } else { - *pos = (I286_DL << 16) | I286_CX; - if (!(I286_AL & 0x20)) { + *pos = (CPU_DL << 16) | CPU_CX; + if (!(CPU_AL & 0x20)) { (*pos) &= 0x1fffff; } if ((*pos) >= sxsi->totals) { @@ -740,13 +740,13 @@ static BYTE sxsi_operate(BYTE type) { long pos; // int i; - drv = (I286_AL & 0x20) >> 4; - if ((I286_AL & 0x0f) >= 2) { + drv = (CPU_AL & 0x20) >> 4; + if ((CPU_AL & 0x0f) >= 2) { return(0x60); } - drv |= (I286_AL & 1); + drv |= (CPU_AL & 1); - switch(I286_AH & 0x0f) { + switch(CPU_AH & 0x0f) { case 0x01: // ベリファイ case 0x07: // リトラクト case 0x0f: // リトラクト @@ -763,47 +763,47 @@ static BYTE sxsi_operate(BYTE type) { case 0x04: // センス ret_ah = 0x00; - if ((I286_AH == 0x04) && (type == HDDTYPE_SASI)) { + if ((CPU_AH == 0x04) && (type == HDDTYPE_SASI)) { ret_ah = 0x04; } - else if ((I286_AH == 0x44) && (type == HDDTYPE_SCSI)) { - I286_BX = 1; + else if ((CPU_AH == 0x44) && (type == HDDTYPE_SCSI)) { + CPU_BX = 1; } - else if (I286_AH == 0x84) { - I286_BX = sxsi_hd[drv].size; - I286_CX = sxsi_hd[drv].tracks; - I286_DH = sxsi_hd[drv].surfaces; - I286_DL = sxsi_hd[drv].sectors; + else if (CPU_AH == 0x84) { + CPU_BX = sxsi_hd[drv].size; + CPU_CX = sxsi_hd[drv].tracks; + CPU_DH = sxsi_hd[drv].surfaces; + CPU_DL = sxsi_hd[drv].sectors; } break; case 0x05: // データの書き込み - i286_memx_read(ES_BASE + I286_BP, work, I286_BX); + i286_memx_read(ES_BASE + CPU_BP, work, CPU_BX); ret_ah = sxsi_pos(&pos); if (!ret_ah) { - ret_ah = sxsi_write(I286_AL, pos, work, I286_BX); + ret_ah = sxsi_write(CPU_AL, pos, work, CPU_BX); } break; case 0x06: // データの読み込み ret_ah = sxsi_pos(&pos); if (!ret_ah) { - ret_ah = sxsi_read(I286_AL, pos, work, I286_BX); + ret_ah = sxsi_read(CPU_AL, pos, work, CPU_BX); if (ret_ah < 0x20) { - i286_memx_write(ES_BASE + I286_BP, work, I286_BX); + i286_memx_write(ES_BASE + CPU_BP, work, CPU_BX); } } break; case 0x0d: // フォーマット - if (I286_DL) { + if (CPU_DL) { ret_ah = 0x30; break; } - i286_memstr_read(I286_ES, I286_BP, work, I286_BX); + i286_memstr_read(CPU_ES, CPU_BP, work, CPU_BX); ret_ah = sxsi_pos(&pos); if (!ret_ah) { - ret_ah = sxsi_format(I286_AL, pos); + ret_ah = sxsi_format(CPU_AL, pos); } break; @@ -996,7 +996,7 @@ void bios0x1b(void) { BYTE ret_ah; REG8 flag; - switch(I286_AL & 0xf0) { + switch(CPU_AL & 0xf0) { case 0x90: ret_ah = fdd_operate(DISKTYPE_2HD, 0, 0); break; @@ -1034,7 +1034,7 @@ void bios0x1b(void) { #if 0 { static BYTE p = 0; - if ((I286_CL == 0x4d) && (ret_ah == 0xe0)) { + if ((CPU_CL == 0x4d) && (ret_ah == 0xe0)) { if (!p) { trace_sw = 1; p++; @@ -1047,16 +1047,16 @@ void bios0x1b(void) { #if 0 TRACEOUT(("%04x:%04x AX=%04x BX=%04x %02x:%02x:%02x:%02x\n" \ "ES=%04x BP=%04x \nret=%02x", - i286_memword_read(I286_SS, I286_SP+2), - i286_memword_read(I286_SS, I286_SP), - I286_AX, I286_BX, I286_CL, I286_DH, I286_DL, I286_CH, - I286_ES, I286_BP, ret_ah)); + i286_memword_read(CPU_SS, CPU_SP+2), + i286_memword_read(CPU_SS, CPU_SP), + CPU_AX, CPU_BX, CPU_CL, CPU_DH, CPU_DL, CPU_CH, + CPU_ES, CPU_BP, ret_ah)); #endif - I286_AH = ret_ah; - flag = i286_membyte_read(I286_SS, I286_SP+4) & 0xfe; + CPU_AH = ret_ah; + flag = i286_membyte_read(CPU_SS, CPU_SP+4) & 0xfe; if (ret_ah >= 0x20) { flag += 1; } - i286_membyte_write(I286_SS, I286_SP+4, flag); + i286_membyte_write(CPU_SS, CPU_SP + 4, flag); } diff --git a/bios/bios1c.c b/bios/bios1c.c index 080b1fd9..9dec3bba 100644 --- a/bios/bios1c.c +++ b/bios/bios1c.c @@ -1,7 +1,7 @@ #include "compiler.h" #include "parts.h" #include "timemng.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -26,22 +26,22 @@ void bios0x1c(void) { BYTE buf[6]; - switch(I286_AH) { + switch(CPU_AH) { case 0x00: // get system timer calendar_get(buf); - i286_memstr_write(I286_ES, I286_BX, buf, 6); + i286_memstr_write(CPU_ES, CPU_BX, buf, 6); break; case 0x01: // put system timer - i286_memstr_read(I286_ES, I286_BX, buf, 6); + i286_memstr_read(CPU_ES, CPU_BX, buf, 6); mem[MEMB_MSW8] = buf[0]; // ver0.29 calendar_set(buf); break; case 0x02: // set interval timer (single) - SETBIOSMEM16(0x0001c, I286_BX); - SETBIOSMEM16(0x0001e, I286_ES); - SETBIOSMEM16(0x0058a, I286_CX); + SETBIOSMEM16(0x0001c, CPU_BX); + SETBIOSMEM16(0x0001e, CPU_ES); + SETBIOSMEM16(0x0058a, CPU_CX); iocore_out8(0x77, 0x36); bios0x1c_03(); break; diff --git a/cbus/amd98.c b/cbus/amd98.c index 1efd54dd..6bd7e9cd 100644 --- a/cbus/amd98.c +++ b/cbus/amd98.c @@ -38,19 +38,19 @@ void amd98int(NEVENTITEM item) { // ---- -static void IOOUTCALL amd_od8(UINT port, BYTE dat) { +static void IOOUTCALL amd_od8(UINT port, REG8 dat) { opn.opnreg = dat; (void)port; } -static void IOOUTCALL amd_od9(UINT port, BYTE dat) { +static void IOOUTCALL amd_od9(UINT port, REG8 dat) { opn.extreg = dat; (void)port; } -static void IOOUTCALL amd_oda(UINT port, BYTE dat) { +static void IOOUTCALL amd_oda(UINT port, REG8 dat) { if (opn.opnreg < 0x0e) { psggen_setreg(&psg1, opn.opnreg, dat); @@ -61,13 +61,13 @@ static void IOOUTCALL amd_oda(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL amd_odb(UINT port, BYTE dat) { +static void IOOUTCALL amd_odb(UINT port, REG8 dat) { if (opn.extreg < 0x0e) { psggen_setreg(&psg2, opn.extreg, dat); } else if (opn.extreg == 0x0f) { - BYTE b; + REG8 b; b = psg2.reg.io2; if ((b & 1) > (dat & 1)) { b &= 0xc2; @@ -98,16 +98,16 @@ static const BYTE amdr[] = {0x01, 0x08, 0x10, 0x20, 0x06, 0x40}; (void)port; } -static void IOOUTCALL amd_odc(UINT port, BYTE dat) { +static void IOOUTCALL amd_odc(UINT port, REG8 dat) { - itimer_setcount(3, dat); + pit_setcount(3, dat); setamd98event(NEVENT_ABSOLUTE); (void)port; } -static void IOOUTCALL amd_ode(UINT port, BYTE dat) { +static void IOOUTCALL amd_ode(UINT port, REG8 dat) { - itimer_setflag(3, dat); + pit_setflag(3, dat); (void)port; } diff --git a/cbus/board118.c b/cbus/board118.c index 2fdb2ab8..3cbf82e1 100644 --- a/cbus/board118.c +++ b/cbus/board118.c @@ -9,13 +9,13 @@ #include "s98.h" -static void IOOUTCALL ymf_o188(UINT port, BYTE dat) { +static void IOOUTCALL ymf_o188(UINT port, REG8 dat) { opn.opnreg = dat; (void)port; } -static void IOOUTCALL ymf_o18a(UINT port, BYTE dat) { +static void IOOUTCALL ymf_o18a(UINT port, REG8 dat) { S98_put(NORMAL2608, opn.opnreg, dat); if (opn.opnreg < 0x10) { @@ -49,13 +49,13 @@ static void IOOUTCALL ymf_o18a(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL ymf_o18c(UINT port, BYTE dat) { +static void IOOUTCALL ymf_o18c(UINT port, REG8 dat) { opn.extreg = dat; (void)port; } -static void IOOUTCALL ymf_o18e(UINT port, BYTE dat) { +static void IOOUTCALL ymf_o18e(UINT port, REG8 dat) { S98_put(EXTEND2608, opn.extreg, dat); opn.reg[opn.extreg + 0x100] = dat; @@ -73,13 +73,13 @@ static void IOOUTCALL ymf_o18e(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL ymf_i188(UINT port) { +static REG8 IOINPCALL ymf_i188(UINT port) { (void)port; return(fmtimer.status); } -static BYTE IOINPCALL ymf_i18a(UINT port) { +static REG8 IOINPCALL ymf_i18a(UINT port) { if (opn.opnreg == 0x0e) { return(fmboard_getjoy(&psg1)); @@ -91,7 +91,7 @@ static BYTE IOINPCALL ymf_i18a(UINT port) { return(opn.reg[opn.opnreg]); } -static BYTE IOINPCALL ymf_i18c(UINT port) { +static REG8 IOINPCALL ymf_i18c(UINT port) { if (opn.extend) { return(fmtimer.status & 3); @@ -100,7 +100,7 @@ static BYTE IOINPCALL ymf_i18c(UINT port) { return(0xff); } -static BYTE IOINPCALL ymf_i18e(UINT port) { +static REG8 IOINPCALL ymf_i18e(UINT port) { if (opn.extend) { return(opn.reg[opn.opnreg]); @@ -109,7 +109,7 @@ static BYTE IOINPCALL ymf_i18e(UINT port) { return(0xff); } -static void extendchannel(BYTE enable) { +static void extendchannel(REG8 enable) { opn.extend = enable; if (enable) { @@ -123,14 +123,14 @@ static void extendchannel(BYTE enable) { } } -static void IOOUTCALL ymf_oa460(UINT port, BYTE dat) { +static void IOOUTCALL ymf_oa460(UINT port, REG8 dat) { cs4231.extfunc = dat; - extendchannel((BYTE)(dat & 1)); + extendchannel((REG8)(dat & 1)); (void)port; } -static BYTE IOINPCALL ymf_ia460(UINT port) { +static REG8 IOINPCALL ymf_ia460(UINT port) { (void)port; return(0x80 | (cs4231.extfunc & 1)); diff --git a/cbus/board14.c b/cbus/board14.c index 42e63537..311e5dac 100644 --- a/cbus/board14.c +++ b/cbus/board14.c @@ -13,7 +13,7 @@ // ---- 8253C-2 -static UINT16 pit3_latch(void) { +static UINT pit3_latch(void) { SINT32 clock; @@ -24,12 +24,12 @@ static UINT16 pit3_latch(void) { if (pc.baseclock == PCBASECLOCK25) { clock = clock * 13 / 16; } - return((UINT16)clock); + return(clock); } return(0); } -static void pit3_setflag(BYTE value) { +static void pit3_setflag(REG8 value) { pit.flag[3] = 0; if (value & 0x30) { @@ -41,7 +41,7 @@ static void pit3_setflag(BYTE value) { } } -static BOOL pit3_setcount(BYTE value) { +static BOOL pit3_setcount(REG8 value) { switch(pit.mode[3] & 0x30) { case 0x10: // access low @@ -67,10 +67,10 @@ static BOOL pit3_setcount(BYTE value) { return(FALSE); } -static BYTE pit3_getcount(void) { +static REG8 pit3_getcount(void) { - BYTE ret; - UINT16 w; + REG8 ret; + REG16 w; if (!(pit.mode[3] & 0x30)) { w = pit.latch[3]; @@ -80,17 +80,17 @@ static BYTE pit3_getcount(void) { } switch(pit.mode[3] & 0x30) { case 0x10: // access low - return((BYTE)w); + return((UINT8)w); case 0x20: // access high - return((BYTE)(w >> 8)); + return((UINT8)(w >> 8)); } // access word if (!(pit.flag[3] & 1)) { - ret = (BYTE)w; + ret = (UINT8)w; } else { - ret = (BYTE)(w >> 8); + ret = (UINT8)(w >> 8); } pit.flag[3] ^= 1; return(ret); @@ -131,19 +131,19 @@ void musicgenint(NEVENTITEM item) { // ---- I/O -static void IOOUTCALL musicgen_o088(UINT port, BYTE dat) { +static void IOOUTCALL musicgen_o088(UINT port, REG8 dat) { musicgen.porta = dat; (void)port; } -static void IOOUTCALL musicgen_o08a(UINT port, BYTE dat) { +static void IOOUTCALL musicgen_o08a(UINT port, REG8 dat) { musicgen.portb = dat; (void)port; } -static void IOOUTCALL musicgen_o08c(UINT port, BYTE dat) { +static void IOOUTCALL musicgen_o08c(UINT port, REG8 dat) { if (dat & 0x80) { if (!(musicgen.portc & 0x80)) { @@ -154,7 +154,7 @@ static void IOOUTCALL musicgen_o08c(UINT port, BYTE dat) { musicgen.sync = 0; sound_sync(); musicgen.key[musicgen.ch] = dat; - tms3631_setkey(&tms3631, (BYTE)musicgen.ch, dat); + tms3631_setkey(&tms3631, (REG8)musicgen.ch, dat); } else if ((!(dat & 0x40)) && (musicgen.portc & 0x40)) { musicgen.sync = 1; @@ -165,7 +165,7 @@ static void IOOUTCALL musicgen_o08c(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL musicgen_o188(UINT port, BYTE dat) { +static void IOOUTCALL musicgen_o188(UINT port, REG8 dat) { sound_sync(); musicgen.mask = dat; @@ -173,7 +173,7 @@ static void IOOUTCALL musicgen_o188(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL musicgen_o18c(UINT port, BYTE dat) { +static void IOOUTCALL musicgen_o18c(UINT port, REG8 dat) { if (!pit3_setcount(dat)) { setmusicgenevent(NEVENT_ABSOLUTE); @@ -181,49 +181,49 @@ static void IOOUTCALL musicgen_o18c(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL musicgen_o18e(UINT port, BYTE dat) { +static void IOOUTCALL musicgen_o18e(UINT port, REG8 dat) { pit3_setflag(dat); (void)port; } -static BYTE IOINPCALL musicgen_i088(UINT port) { +static REG8 IOINPCALL musicgen_i088(UINT port) { (void)port; return(musicgen.porta); } -static BYTE IOINPCALL musicgen_i08a(UINT port) { +static REG8 IOINPCALL musicgen_i08a(UINT port) { (void)port; return(musicgen.portb); } -static BYTE IOINPCALL musicgen_i08c(UINT port) { +static REG8 IOINPCALL musicgen_i08c(UINT port) { (void)port; return(musicgen.portc); } -static BYTE IOINPCALL musicgen_i08e(UINT port) { +static REG8 IOINPCALL musicgen_i08e(UINT port) { (void)port; return(0x08); } -static BYTE IOINPCALL musicgen_i188(UINT port) { +static REG8 IOINPCALL musicgen_i188(UINT port) { (void)port; return(musicgen.mask); } -static BYTE IOINPCALL musicgen_i18c(UINT port) { +static REG8 IOINPCALL musicgen_i18c(UINT port) { (void)port; return(pit3_getcount()); } -static BYTE IOINPCALL musicgen_i18e(UINT port) { +static REG8 IOINPCALL musicgen_i18e(UINT port) { (void)port; #if 1 @@ -264,10 +264,10 @@ void board14_bind(void) { void board14_allkeymake(void) { - int i; + REG8 i; for (i=0; i<8; i++) { - tms3631_setkey(&tms3631, (BYTE)i, musicgen.key[i]); + tms3631_setkey(&tms3631, i, musicgen.key[i]); } } diff --git a/cbus/board26k.c b/cbus/board26k.c index a2fd6f53..35f00c6b 100644 --- a/cbus/board26k.c +++ b/cbus/board26k.c @@ -8,13 +8,13 @@ #include "s98.h" -static void IOOUTCALL opn_o188(UINT port, BYTE dat) { +static void IOOUTCALL opn_o188(UINT port, REG8 dat) { opn.opnreg = dat; (void)port; } -static void IOOUTCALL opn_o18a(UINT port, BYTE dat) { +static void IOOUTCALL opn_o18a(UINT port, REG8 dat) { S98_put(NORMAL2608, opn.opnreg, dat); if (opn.opnreg < 0x10) { @@ -44,7 +44,7 @@ static void IOOUTCALL opn_o18a(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL opn_i188(UINT port) { +static REG8 IOINPCALL opn_i188(UINT port) { (void)port; #if 1 // ドラッケンで未定義フラグ見てる テスト終了 @@ -54,7 +54,7 @@ static BYTE IOINPCALL opn_i188(UINT port) { #endif } -static BYTE IOINPCALL opn_i18a(UINT port) { +static REG8 IOINPCALL opn_i18a(UINT port) { if (opn.opnreg == 0x0e) { return(fmboard_getjoy(&psg1)); @@ -79,8 +79,8 @@ static const IOINP opn_i[4] = { void board26k_reset(void) { opngen_setcfg(3, 0); - fmtimer_reset((BYTE)(np2cfg.snd26opt & 0xc0)); - soundrom_loadex((BYTE)(np2cfg.snd26opt & 7), "26"); + fmtimer_reset(np2cfg.snd26opt & 0xc0); + soundrom_loadex(np2cfg.snd26opt & 7, "26"); opn.base = (np2cfg.snd26opt & 0x10)?0x000:0x100; } diff --git a/cbus/board86.c b/cbus/board86.c index 55a83334..86c040fb 100644 --- a/cbus/board86.c +++ b/cbus/board86.c @@ -9,13 +9,13 @@ #include "s98.h" -static void IOOUTCALL opna_o188(UINT port, BYTE dat) { +static void IOOUTCALL opna_o188(UINT port, REG8 dat) { opn.opnreg = dat; (void)port; } -static void IOOUTCALL opna_o18a(UINT port, BYTE dat) { +static void IOOUTCALL opna_o18a(UINT port, REG8 dat) { S98_put(NORMAL2608, opn.opnreg, dat); if (opn.opnreg < 0x10) { @@ -54,13 +54,13 @@ static void IOOUTCALL opna_o18a(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL opna_o18c(UINT port, BYTE dat) { +static void IOOUTCALL opna_o18c(UINT port, REG8 dat) { opn.extreg = dat; (void)port; } -static void IOOUTCALL opna_o18e(UINT port, BYTE dat) { +static void IOOUTCALL opna_o18e(UINT port, REG8 dat) { S98_put(EXTEND2608, opn.extreg, dat); opn.reg[opn.extreg + 0x100] = dat; @@ -77,13 +77,13 @@ static void IOOUTCALL opna_o18e(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL opna_i188(UINT port) { +static REG8 IOINPCALL opna_i188(UINT port) { (void)port; return(fmtimer.status); } -static BYTE IOINPCALL opna_i18a(UINT port) { +static REG8 IOINPCALL opna_i18a(UINT port) { if (opn.opnreg == 0x0e) { return(fmboard_getjoy(&psg1)); @@ -95,7 +95,7 @@ static BYTE IOINPCALL opna_i18a(UINT port) { return(opn.reg[opn.opnreg]); } -static BYTE IOINPCALL opna_i18c(UINT port) { +static REG8 IOINPCALL opna_i18c(UINT port) { if (opn.extend) { return((fmtimer.status & 3) | (opn.adpcmmask & 8)); @@ -104,7 +104,7 @@ static BYTE IOINPCALL opna_i18c(UINT port) { return(0xff); } -static BYTE IOINPCALL opna_i18e(UINT port) { +static REG8 IOINPCALL opna_i18e(UINT port) { if (opn.extend) { return(opn.reg[opn.opnreg]); @@ -113,7 +113,7 @@ static BYTE IOINPCALL opna_i18e(UINT port) { return(0xff); } -static void extendchannel(BYTE enable) { +static void extendchannel(REG8 enable) { opn.extend = enable; if (enable) { @@ -139,9 +139,9 @@ static const IOINP opna_i[4] = { void board86_reset(void) { - fmtimer_reset((BYTE)((np2cfg.snd86opt & 0x10) | - ((np2cfg.snd86opt & 0x4) << 5) | - ((np2cfg.snd86opt & 0x8) << 3))); + fmtimer_reset((np2cfg.snd86opt & 0x10) | + ((np2cfg.snd86opt & 0x4) << 5) | + ((np2cfg.snd86opt & 0x8) << 3)); opngen_setcfg(3, OPN_STEREO | 0x038); if (np2cfg.snd86opt & 2) { soundrom_load(0xcc000, "86"); @@ -162,7 +162,7 @@ void board86_bind(void) { // ---- + chibioto -static void IOOUTCALL opnac_o18e(UINT port, BYTE dat) { +static void IOOUTCALL opnac_o18e(UINT port, REG8 dat) { S98_put(EXTEND2608, opn.extreg, dat); opn.reg[opn.extreg + 0x100] = dat; @@ -178,7 +178,7 @@ static void IOOUTCALL opnac_o18e(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL opnac_i18c(UINT port) { +static REG8 IOINPCALL opnac_i18c(UINT port) { if (opn.extend) { return((fmtimer.status & 3) | adpcm_status(&adpcm)); @@ -188,7 +188,7 @@ static BYTE IOINPCALL opnac_i18c(UINT port) { return(0xff); } -static BYTE IOINPCALL opnac_i18e(UINT port) { +static REG8 IOINPCALL opnac_i18e(UINT port) { if (opn.extend) { if (opn.extreg == 0x08) { diff --git a/cbus/boardspb.c b/cbus/boardspb.c index 7ca45af8..e3711ccb 100644 --- a/cbus/boardspb.c +++ b/cbus/boardspb.c @@ -8,13 +8,13 @@ #include "s98.h" -static void IOOUTCALL spb_o188(UINT port, BYTE dat) { +static void IOOUTCALL spb_o188(UINT port, REG8 dat) { opn.opnreg = dat; (void)port; } -static void IOOUTCALL spb_o18a(UINT port, BYTE dat) { +static void IOOUTCALL spb_o18a(UINT port, REG8 dat) { S98_put(NORMAL2608, opn.opnreg, dat); if (opn.opnreg < 0x10) { @@ -51,13 +51,13 @@ static void IOOUTCALL spb_o18a(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL spb_o18c(UINT port, BYTE dat) { +static void IOOUTCALL spb_o18c(UINT port, REG8 dat) { opn.extreg = dat; (void)port; } -static void IOOUTCALL spb_o18e(UINT port, BYTE dat) { +static void IOOUTCALL spb_o18e(UINT port, REG8 dat) { S98_put(EXTEND2608, opn.extreg, dat); opn.reg[opn.extreg + 0x100] = dat; @@ -71,13 +71,13 @@ static void IOOUTCALL spb_o18e(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL spb_i188(UINT port) { +static REG8 IOINPCALL spb_i188(UINT port) { (void)port; return((fmtimer.status & 3) | adpcm_status(&adpcm)); } -static BYTE IOINPCALL spb_i18a(UINT port) { +static REG8 IOINPCALL spb_i18a(UINT port) { if (opn.opnreg == 0x0e) { return(fmboard_getjoy(&psg1)); @@ -89,7 +89,7 @@ static BYTE IOINPCALL spb_i18a(UINT port) { return(opn.reg[opn.opnreg]); } -static BYTE IOINPCALL spb_i18e(UINT port) { +static REG8 IOINPCALL spb_i18e(UINT port) { if (opn.extreg == 0x08) { return(adpcm_readsample(&adpcm)); @@ -101,13 +101,13 @@ static BYTE IOINPCALL spb_i18e(UINT port) { // ---- spark board -static void IOOUTCALL spr_o588(UINT port, BYTE dat) { +static void IOOUTCALL spr_o588(UINT port, REG8 dat) { opn.opn2reg = dat; (void)port; } -static void IOOUTCALL spr_o58a(UINT port, BYTE dat) { +static void IOOUTCALL spr_o58a(UINT port, REG8 dat) { if (opn.opn2reg < 0x30) { if (opn.opn2reg == 0x28) { @@ -132,13 +132,13 @@ static void IOOUTCALL spr_o58a(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL spr_o58c(UINT port, BYTE dat) { +static void IOOUTCALL spr_o58c(UINT port, REG8 dat) { opn.ext2reg = dat; (void)port; } -static void IOOUTCALL spr_o58e(UINT port, BYTE dat) { +static void IOOUTCALL spr_o58e(UINT port, REG8 dat) { opn.reg[opn.ext2reg + 0x300] = dat; if (opn.ext2reg >= 0x30) { @@ -148,13 +148,13 @@ static void IOOUTCALL spr_o58e(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL spr_i588(UINT port) { +static REG8 IOINPCALL spr_i588(UINT port) { (void)port; return(fmtimer.status); } -static BYTE IOINPCALL spr_i58a(UINT port) { +static REG8 IOINPCALL spr_i58a(UINT port) { if (opn.opn2reg >= 0x20) { return(opn.reg[opn.opn2reg + 0x200]); @@ -163,13 +163,13 @@ static BYTE IOINPCALL spr_i58a(UINT port) { return(0xff); } -static BYTE IOINPCALL spr_i58c(UINT port) { +static REG8 IOINPCALL spr_i58c(UINT port) { (void)port; return(fmtimer.status & 3); } -static BYTE IOINPCALL spr_i58e(UINT port) { +static REG8 IOINPCALL spr_i58e(UINT port) { (void)port; return(opn.reg[opn.opn2reg + 0x200]); @@ -187,10 +187,10 @@ static const IOINP spb_i[4] = { void boardspb_reset(void) { - fmtimer_reset((BYTE)(np2cfg.spbopt & 0xc0)); + fmtimer_reset(np2cfg.spbopt & 0xc0); opn.channels = 6; opngen_setcfg(6, OPN_STEREO | 0x03f); - soundrom_loadex((BYTE)(np2cfg.spbopt & 7), "SPB"); + soundrom_loadex(np2cfg.spbopt & 7, "SPB"); opn.base = ((np2cfg.spbopt & 0x10)?0x000:0x100); } @@ -215,11 +215,11 @@ static const IOINP spr_i[4] = { void boardspr_reset(void) { - fmtimer_reset((BYTE)(np2cfg.spbopt & 0xc0)); + fmtimer_reset(np2cfg.spbopt & 0xc0); opn.reg[0x2ff] = 0; opn.channels = 12; opngen_setcfg(12, OPN_STEREO | 0x03f); - soundrom_loadex((BYTE)(np2cfg.spbopt & 7), "SPB"); + soundrom_loadex(np2cfg.spbopt & 7, "SPB"); opn.base = (np2cfg.spbopt & 0x10)?0x000:0x100; } diff --git a/cbus/boardx2.c b/cbus/boardx2.c index e49a7fc7..bbd84307 100644 --- a/cbus/boardx2.c +++ b/cbus/boardx2.c @@ -9,13 +9,13 @@ #include "s98.h" -static void IOOUTCALL opn_o088(UINT port, BYTE dat) { +static void IOOUTCALL opn_o088(UINT port, REG8 dat) { opn.opn2reg = dat; (void)port; } -static void IOOUTCALL opn_o08a(UINT port, BYTE dat) { +static void IOOUTCALL opn_o08a(UINT port, REG8 dat) { if (opn.opn2reg < 0x10) { if (opn.opn2reg != 0x0e) { @@ -26,7 +26,7 @@ static void IOOUTCALL opn_o08a(UINT port, BYTE dat) { if (opn.opn2reg < 0x30) { if (opn.opn2reg == 0x28) { if ((dat & 0x0f) < 3) { - opngen_keyon((dat & 0x0f), dat); + opngen_keyon(dat & 0x0f, dat); } } else { @@ -44,13 +44,13 @@ static void IOOUTCALL opn_o08a(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL opn_i088(UINT port) { +static REG8 IOINPCALL opn_i088(UINT port) { (void)port; return(fmtimer.status); } -static BYTE IOINPCALL opn_i08a(UINT port) { +static REG8 IOINPCALL opn_i08a(UINT port) { if (opn.opn2reg == 0x0e) { return(0xff); @@ -65,13 +65,13 @@ static BYTE IOINPCALL opn_i08a(UINT port) { // ---- -static void IOOUTCALL opna_o188(UINT port, BYTE dat) { +static void IOOUTCALL opna_o188(UINT port, REG8 dat) { opn.opnreg = dat; (void)port; } -static void IOOUTCALL opna_o18a(UINT port, BYTE dat) { +static void IOOUTCALL opna_o18a(UINT port, REG8 dat) { S98_put(NORMAL2608, opn.opnreg, dat); if (opn.opnreg < 0x10) { @@ -88,11 +88,11 @@ static void IOOUTCALL opna_o18a(UINT port, BYTE dat) { else if (opn.opnreg < 0x30) { if (opn.opnreg == 0x28) { if ((dat & 0x0f) < 3) { - opngen_keyon((dat & 0x0f)+3, dat); + opngen_keyon((dat & 0x0f) + 3, dat); } else if (((dat & 0x0f) != 3) && ((dat & 0x0f) < 7)) { - opngen_keyon((dat & 0x0f)+2, dat); + opngen_keyon((dat & 0x0f) + 2, dat); } } else { @@ -110,13 +110,13 @@ static void IOOUTCALL opna_o18a(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL opna_o18c(UINT port, BYTE dat) { +static void IOOUTCALL opna_o18c(UINT port, REG8 dat) { opn.extreg = dat; (void)port; } -static void IOOUTCALL opna_o18e(UINT port, BYTE dat) { +static void IOOUTCALL opna_o18e(UINT port, REG8 dat) { S98_put(EXTEND2608, opn.extreg, dat); opn.reg[opn.extreg + 0x100] = dat; @@ -133,13 +133,13 @@ static void IOOUTCALL opna_o18e(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL opna_i188(UINT port) { +static REG8 IOINPCALL opna_i188(UINT port) { (void)port; return(fmtimer.status); } -static BYTE IOINPCALL opna_i18a(UINT port) { +static REG8 IOINPCALL opna_i18a(UINT port) { if (opn.opnreg == 0x0e) { return(fmboard_getjoy(&psg2)); @@ -151,7 +151,7 @@ static BYTE IOINPCALL opna_i18a(UINT port) { return(opn.reg[opn.opnreg]); } -static BYTE IOINPCALL opna_i18c(UINT port) { +static REG8 IOINPCALL opna_i18c(UINT port) { if (opn.extend) { return((fmtimer.status & 3) | (opn.adpcmmask & 8)); @@ -160,7 +160,7 @@ static BYTE IOINPCALL opna_i18c(UINT port) { return(0xff); } -static BYTE IOINPCALL opna_i18e(UINT port) { +static REG8 IOINPCALL opna_i18e(UINT port) { if (opn.extend) { return(opn.reg[opn.opnreg]); @@ -169,7 +169,7 @@ static BYTE IOINPCALL opna_i18e(UINT port) { return(0xff); } -static void extendchannel(BYTE enable) { +static void extendchannel(REG8 enable) { opn.extend = enable; if (enable) { diff --git a/cbus/cs4231io.c b/cbus/cs4231io.c index 70dc73d0..e6ba5e96 100644 --- a/cbus/cs4231io.c +++ b/cbus/cs4231io.c @@ -7,13 +7,13 @@ #include "fmboard.h" -static void IOOUTCALL csctrl_oc24(UINT port, BYTE dat) { +static void IOOUTCALL csctrl_oc24(UINT port, REG8 dat) { cs4231.portctrl = dat; (void)port; } -static void IOOUTCALL csctrl_oc2b(UINT port, BYTE dat) { +static void IOOUTCALL csctrl_oc2b(UINT port, REG8 dat) { if ((cs4231.portctrl & 0x2f) == 0x20) { cs4231.port &= 0xff00; @@ -22,7 +22,7 @@ static void IOOUTCALL csctrl_oc2b(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL csctrl_oc2d(UINT port, BYTE dat) { +static void IOOUTCALL csctrl_oc2d(UINT port, REG8 dat) { if ((cs4231.portctrl & 0x2f) == 0x20) { cs4231.port &= 0x00ff; @@ -31,13 +31,13 @@ static void IOOUTCALL csctrl_oc2d(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL csctrl_ic24(UINT port) { +static REG8 IOINPCALL csctrl_ic24(UINT port) { (void)port; return(0x80 | cs4231.portctrl); } -static BYTE IOINPCALL csctrl_ic2b(UINT port) { +static REG8 IOINPCALL csctrl_ic2b(UINT port) { switch(cs4231.portctrl & 0x0f) { case 0x00: @@ -53,7 +53,7 @@ static BYTE IOINPCALL csctrl_ic2b(UINT port) { return(0xff); } -static BYTE IOINPCALL csctrl_ic2d(UINT port) { +static REG8 IOINPCALL csctrl_ic2d(UINT port) { switch(cs4231.portctrl & 0x0f) { case 0x00: @@ -96,7 +96,7 @@ void cs4231io_bind(void) { iocore_attachinp(0xc2d, csctrl_ic2d); } -void IOOUTCALL cs4231io_w8(UINT port, BYTE value) { +void IOOUTCALL cs4231io_w8(UINT port, REG8 value) { switch(port & 0x0f) { case 0: @@ -121,7 +121,7 @@ void IOOUTCALL cs4231io_w8(UINT port, BYTE value) { } } -BYTE IOINPCALL cs4231io_r8(UINT port) { +REG8 IOINPCALL cs4231io_r8(UINT port) { switch(port & 0x0f) { case 0: diff --git a/cbus/cs4231io.h b/cbus/cs4231io.h index c0174507..c28874a6 100644 --- a/cbus/cs4231io.h +++ b/cbus/cs4231io.h @@ -7,8 +7,8 @@ extern "C" { void cs4231io_reset(void); void cs4231io_bind(void); -void IOOUTCALL cs4231io_w8(UINT port, BYTE value); -BYTE IOINPCALL cs4231io_r8(UINT port); +void IOOUTCALL cs4231io_w8(UINT port, REG8 value); +REG8 IOINPCALL cs4231io_r8(UINT port); #ifdef __cplusplus } diff --git a/cbus/mpu98ii.c b/cbus/mpu98ii.c index b8bacbe7..9acf374c 100644 --- a/cbus/mpu98ii.c +++ b/cbus/mpu98ii.c @@ -40,10 +40,10 @@ enum { COMMNG cm_mpu98; -static const BYTE mpuirqnum[4] = {3, 5, 6, 12}; +static const UINT8 mpuirqnum[4] = {3, 5, 6, 12}; -static const BYTE fd_step1[4][4] = {{0, 0, 0, 0}, {1, 0, 0, 0}, - {1, 0, 1, 0}, {1, 1, 1, 0}}; +static const UINT8 fd_step1[4][4] = {{0, 0, 0, 0}, {1, 0, 0, 0}, + {1, 0, 1, 0}, {1, 1, 1, 0}}; static void makeintclock(void) { @@ -58,9 +58,9 @@ static void makeintclock(void) { mpu98.clock = (pc.realclock * 5 / l); // /12 } -static void sendallclocks(BYTE data) { +static void sendallclocks(REG8 data) { - BYTE quarter; + REG8 quarter; int i; quarter = data >> 2; @@ -68,13 +68,12 @@ static void sendallclocks(BYTE data) { quarter = 64; } for (i=0; i<4; i++) { - mpu98.fd_step[i] = fd_step1[data & 3][i]; - mpu98.fd_step[i] += quarter; + mpu98.fd_step[i] = quarter + fd_step1[data & 3][i]; } mpu98.fd_remain = 0; } -static void setrecvdata(BYTE data) { +static void setrecvdata(REG8 data) { if (mpu98.cnt < MPU98_RECVBUFS) { mpu98.buf[(mpu98.pos + mpu98.cnt) & (MPU98_RECVBUFS - 1)] = data; @@ -90,14 +89,14 @@ static void mpu98ii_int(void) { static void ch_step(void) { int i; - BYTE bit; + REG8 bit; if (mpu98.flag1 & MPU1FLAG_F9) { if (mpu98.f9.step) { mpu98.f9.step--; } } - for (i=0, bit=1; bit; bit<<=1, i++) { + for (i=0, bit=1; i<8; bit<<=1, i++) { if (mpu98.intch & bit) { if (mpu98.ch[i].step) { mpu98.ch[i].step--; @@ -109,7 +108,7 @@ static void ch_step(void) { static BOOL ch_nextsearch(void) { int i; - BYTE bit; + REG8 bit; ch_nextsearch_more: if (mpu98.intreq == 9) { @@ -147,7 +146,7 @@ static BOOL ch_nextsearch(void) { } ch->datas = 0; } - setrecvdata((BYTE)(0xf0 + mpu98.intreq)); + setrecvdata((REG8)(0xf0 + mpu98.intreq)); mpu98ii_int(); mpu98.recvevent |= MIDIE_STEP; return(TRUE); @@ -204,9 +203,9 @@ static void midiwait(SINT32 waitclock) { } } -static BOOL sendcmd(BYTE cmd) { +static BOOL sendcmd(REG8 cmd) { - BYTE work; + REG8 work; mpu98.cmd = cmd; switch(cmd & 0xf0) { @@ -338,7 +337,7 @@ static BOOL sendcmd(BYTE cmd) { return(TRUE); } -static void group_ex(BYTE cmd, BYTE data) { +static void group_ex(REG8 cmd, REG8 data) { switch(cmd) { case 0xe0: // tempo @@ -372,7 +371,7 @@ static void group_ex(BYTE cmd, BYTE data) { } } -static void senddat(BYTE data) { +static void senddat(REG8 data) { MPUCH *ch; @@ -505,7 +504,7 @@ static void senddat(BYTE data) { } -static void IOOUTCALL mpu98ii_o0(UINT port, BYTE dat) { +static void IOOUTCALL mpu98ii_o0(UINT port, REG8 dat) { UINT sent; @@ -515,11 +514,11 @@ static void IOOUTCALL mpu98ii_o0(UINT port, BYTE dat) { if (cm_mpu98->connect != COMCONNECT_OFF) { if (mpu98.mode) { - sent = cm_mpu98->write(cm_mpu98, dat); + sent = cm_mpu98->write(cm_mpu98, (BYTE)dat); } else { if ((mpu98.cmd == 0xd0) || (mpu98.cmd == 0xdf)) { - sent = cm_mpu98->write(cm_mpu98, dat); + sent = cm_mpu98->write(cm_mpu98, (BYTE)dat); } else { senddat(dat); @@ -533,7 +532,7 @@ static void IOOUTCALL mpu98ii_o0(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL mpu98ii_o2(UINT port, BYTE dat) { +static void IOOUTCALL mpu98ii_o2(UINT port, REG8 dat) { if (cm_mpu98 == NULL) { cm_mpu98 = commng_create(COMCREATE_MPU98II); @@ -564,7 +563,7 @@ static void IOOUTCALL mpu98ii_o2(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL mpu98ii_i0(UINT port) { +static REG8 IOINPCALL mpu98ii_i0(UINT port) { if (cm_mpu98 == NULL) { cm_mpu98 = commng_create(COMCREATE_MPU98II); @@ -587,9 +586,9 @@ static BYTE IOINPCALL mpu98ii_i0(UINT port) { return(0xff); } -static BYTE IOINPCALL mpu98ii_i2(UINT port) { +static REG8 IOINPCALL mpu98ii_i2(UINT port) { - BYTE ret; + REG8 ret; if (cm_mpu98 == NULL) { cm_mpu98 = commng_create(COMCREATE_MPU98II); diff --git a/cbus/mpu98ii.h b/cbus/mpu98ii.h index 4b83dc49..cbf91f8c 100644 --- a/cbus/mpu98ii.h +++ b/cbus/mpu98ii.h @@ -10,19 +10,19 @@ enum { #define MPUCHDATAS 4 typedef struct { - BYTE step; - BYTE datas; - BYTE remain; - BYTE rstat; - BYTE recv; - BYTE padding[2]; + UINT8 step; + UINT8 datas; + UINT8 remain; + UINT8 rstat; + UINT8 recv; + UINT8 padding[2]; BYTE data[MPUCHDATAS]; } MPUCH; typedef struct { - BYTE step; - BYTE cmd; - BYTE padding[2]; + UINT8 step; + UINT8 cmd; + UINT8 padding[2]; UINT16 remain; UINT16 datas; BYTE data[MPU98_EXCVBUFS]; @@ -39,29 +39,29 @@ typedef struct { int pos; UINT16 port; // ver0.28 - BYTE irqnum; - BYTE data; - - BYTE intch; - BYTE intreq; - - BYTE fd_remain; - BYTE fd_cnt; - BYTE fd_step[4]; - - BYTE status; - BYTE mode; - BYTE cmd; - BYTE timebase; - BYTE tempo; - BYTE tempos; - BYTE recvevent; - BYTE remainstep; - BYTE timing; - BYTE avail; - BYTE bar; - - BYTE flag1; + UINT8 irqnum; + UINT8 data; + + UINT8 intch; + UINT8 intreq; + + UINT8 fd_remain; + UINT8 fd_cnt; + UINT8 fd_step[4]; + + UINT8 status; + UINT8 mode; + UINT8 cmd; + UINT8 timebase; + UINT8 tempo; + UINT8 tempos; + UINT8 recvevent; + UINT8 remainstep; + UINT8 timing; + UINT8 avail; + UINT8 bar; + + UINT8 flag1; } _MPU98II, *MPU98II; diff --git a/cbus/pc9861k.c b/cbus/pc9861k.c index 61b81888..d9302235 100644 --- a/cbus/pc9861k.c +++ b/cbus/pc9861k.c @@ -17,8 +17,8 @@ const UINT32 pc9861k_speed[11] = {75, 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 76800}; -static const BYTE ch1_irq[4] = {IRQ_INT0, IRQ_INT1, IRQ_INT2, IRQ_INT3}; -static const BYTE ch2_irq[4] = {IRQ_INT0, IRQ_INT41, IRQ_INT5, IRQ_INT6}; +static const UINT8 ch1_irq[4] = {IRQ_INT0, IRQ_INT1, IRQ_INT2, IRQ_INT3}; +static const UINT8 ch2_irq[4] = {IRQ_INT0, IRQ_INT41, IRQ_INT5, IRQ_INT6}; static const _PC9861CH pc9861def = {0x05, 0xff, 7, 1, 0, 0, 2400, NEVENT_MAXCLOCK, 0, 0, 0}; @@ -38,7 +38,7 @@ static void pc9861k_callback(COMMNG cm, PC9861CH m) { } } else { - m->result &= (BYTE)~2; + m->result &= ~2; } if (m->signal & 4) { if (m->send) { @@ -69,7 +69,7 @@ void pc9861ch2cb(NEVENTITEM item) { pc9861k_callback(cm_pc9861ch2, &pc9861ch2); } -static UINT32 pc9861k_getspeed(BYTE dip) { +static UINT32 pc9861k_getspeed(REG8 dip) { UINT speed; @@ -123,13 +123,13 @@ static void pc9861ch2_open(void) { // ------------------------------------------------------------------------- static void IOOUTCALL pc9861data_w8(COMMNG cm, PC9861CH m, - UINT port, BYTE value) { + UINT port, REG8 value) { UINT32 mul2; switch(port & 0x3) { case 0x01: - cm->write(cm, value); + cm->write(cm, (BYTE)value); if (m->signal & 4) { m->send = 0; pic_setirq(m->irq); @@ -187,7 +187,7 @@ static void IOOUTCALL pc9861data_w8(COMMNG cm, PC9861CH m, } } -static BYTE IOINPCALL pc9861data_r8(COMMNG cm, PC9861CH m, UINT port) { +static REG8 IOINPCALL pc9861data_r8(COMMNG cm, PC9861CH m, UINT port) { switch(port & 0x3) { case 0x01: @@ -203,7 +203,7 @@ static BYTE IOINPCALL pc9861data_r8(COMMNG cm, PC9861CH m, UINT port) { } -static void IOOUTCALL pc9861k_ob0(UINT port, BYTE dat) { +static void IOOUTCALL pc9861k_ob0(UINT port, REG8 dat) { if (cm_pc9861ch1 == NULL) { pc9861ch1_open(); @@ -212,7 +212,7 @@ static void IOOUTCALL pc9861k_ob0(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL pc9861k_ob2(UINT port, BYTE dat) { +static void IOOUTCALL pc9861k_ob2(UINT port, REG8 dat) { if (cm_pc9861ch2 == NULL) { pc9861ch2_open(); @@ -221,7 +221,7 @@ static void IOOUTCALL pc9861k_ob2(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL pc9861k_ib0(UINT port) { +static REG8 IOINPCALL pc9861k_ib0(UINT port) { if (cm_pc9861ch1 == NULL) { pc9861ch1_open(); @@ -230,7 +230,7 @@ static BYTE IOINPCALL pc9861k_ib0(UINT port) { return(cm_pc9861ch1->getstat(cm_pc9861ch1) | pc9861ch1.vect); } -static BYTE IOINPCALL pc9861k_ib2(UINT port) { +static REG8 IOINPCALL pc9861k_ib2(UINT port) { if (cm_pc9861ch2 == NULL) { pc9861ch2_open(); @@ -240,7 +240,7 @@ static BYTE IOINPCALL pc9861k_ib2(UINT port) { } -static void IOOUTCALL pc9861k_ob1(UINT port, BYTE dat) { +static void IOOUTCALL pc9861k_ob1(UINT port, REG8 dat) { if (cm_pc9861ch1 == NULL) { pc9861ch1_open(); @@ -248,7 +248,7 @@ static void IOOUTCALL pc9861k_ob1(UINT port, BYTE dat) { pc9861data_w8(cm_pc9861ch1, &pc9861ch1, port, dat); } -static BYTE IOINPCALL pc9861k_ib1(UINT port) { +static REG8 IOINPCALL pc9861k_ib1(UINT port) { if (cm_pc9861ch2 == NULL) { pc9861ch1_open(); @@ -257,7 +257,7 @@ static BYTE IOINPCALL pc9861k_ib1(UINT port) { } -static void IOOUTCALL pc9861k_ob9(UINT port, BYTE dat) { +static void IOOUTCALL pc9861k_ob9(UINT port, REG8 dat) { if (cm_pc9861ch2 == NULL) { pc9861ch2_open(); @@ -265,7 +265,7 @@ static void IOOUTCALL pc9861k_ob9(UINT port, BYTE dat) { pc9861data_w8(cm_pc9861ch2, &pc9861ch2, port, dat); } -static BYTE IOINPCALL pc9861k_ib9(UINT port) { +static REG8 IOINPCALL pc9861k_ib9(UINT port) { if (cm_pc9861ch2 == NULL) { pc9861ch2_open(); diff --git a/cbus/pc9861k.h b/cbus/pc9861k.h index aad8ff66..9e3e5b5b 100644 --- a/cbus/pc9861k.h +++ b/cbus/pc9861k.h @@ -1,9 +1,9 @@ typedef struct { - BYTE result; - BYTE data; - BYTE signal; - BYTE send; + UINT8 result; + UINT8 data; + UINT8 signal; + UINT8 send; UINT pos; UINT dummyinst; diff --git a/cbus/pcm86io.c b/cbus/pcm86io.c index 4a1c6a41..6378ebe1 100644 --- a/cbus/pcm86io.c +++ b/cbus/pcm86io.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "pcm86io.h" @@ -10,21 +10,21 @@ extern PCM86CFG pcm86cfg; -static const BYTE pcm86bits[] = {1, 1, 1, 2, 0, 0, 0, 1}; +static const UINT8 pcm86bits[] = {1, 1, 1, 2, 0, 0, 0, 1}; static const SINT32 pcm86rescue[] = {PCM86_RESCUE * 32, PCM86_RESCUE * 24, PCM86_RESCUE * 16, PCM86_RESCUE * 12, PCM86_RESCUE * 8, PCM86_RESCUE * 6, PCM86_RESCUE * 4, PCM86_RESCUE * 3}; -static void IOOUTCALL pcm86_oa460(UINT port, BYTE val) { +static void IOOUTCALL pcm86_oa460(UINT port, REG8 val) { pcm86.extfunc = val; - fmboard_extenable((BYTE)(val & 1)); + fmboard_extenable((REG8)(val & 1)); (void)port; } -static void IOOUTCALL pcm86_oa466(UINT port, BYTE val) { +static void IOOUTCALL pcm86_oa466(UINT port, REG8 val) { if ((val & 0xe0) == 0xa0) { sound_sync(); @@ -34,9 +34,9 @@ static void IOOUTCALL pcm86_oa466(UINT port, BYTE val) { (void)port; } -static void IOOUTCALL pcm86_oa468(UINT port, BYTE val) { +static void IOOUTCALL pcm86_oa468(UINT port, REG8 val) { - BYTE xchgbit; + REG8 xchgbit; sound_sync(); xchgbit = pcm86.fifo ^ val; @@ -48,7 +48,7 @@ static void IOOUTCALL pcm86_oa468(UINT port, BYTE val) { pcm86.virbuf = 0; pcm86.write = 0; pcm86.reqirq = 0; - pcm86.lastclock = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK; + pcm86.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; pcm86.lastclock <<= 6; } // サンプリングレート変更 @@ -58,7 +58,7 @@ static void IOOUTCALL pcm86_oa468(UINT port, BYTE val) { } pcm86.fifo = val & (~0x10); if ((xchgbit & 0x80) && (val & 0x80)) { - pcm86.lastclock = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK; + pcm86.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; pcm86.lastclock <<= 6; } pcm86.write = 1; @@ -66,7 +66,7 @@ static void IOOUTCALL pcm86_oa468(UINT port, BYTE val) { (void)port; } -static void IOOUTCALL pcm86_oa46a(UINT port, BYTE val) { +static void IOOUTCALL pcm86_oa46a(UINT port, REG8 val) { sound_sync(); if (pcm86.fifo & 0x20) { @@ -94,7 +94,7 @@ static void IOOUTCALL pcm86_oa46a(UINT port, BYTE val) { (void)port; } -static void IOOUTCALL pcm86_oa46c(UINT port, BYTE val) { +static void IOOUTCALL pcm86_oa46c(UINT port, REG8 val) { if (pcm86.virbuf < PCM86_LOGICALBUF) { pcm86.virbuf++; @@ -112,20 +112,20 @@ static void IOOUTCALL pcm86_oa46c(UINT port, BYTE val) { (void)port; } -static BYTE IOINPCALL pcm86_ia460(UINT port) { +static REG8 IOINPCALL pcm86_ia460(UINT port) { (void)port; return(0x40 | (pcm86.extfunc & 1)); } -static BYTE IOINPCALL pcm86_ia466(UINT port) { +static REG8 IOINPCALL pcm86_ia466(UINT port) { UINT32 nowclk; UINT32 past; - BYTE ret; + REG8 ret; sound_sync(); - nowclk = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK; + nowclk = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; nowclk <<= 6; past = nowclk - pcm86.lastclock; if (past >= pcm86.stepclock) { @@ -143,9 +143,9 @@ static BYTE IOINPCALL pcm86_ia466(UINT port) { return(ret); } -static BYTE IOINPCALL pcm86_ia468(UINT port) { +static REG8 IOINPCALL pcm86_ia468(UINT port) { - BYTE ret; + REG8 ret; ret = pcm86.fifo & (~0x10); if ((pcm86.write) && (pcm86.fifo & 0x20)) { @@ -160,13 +160,13 @@ static BYTE IOINPCALL pcm86_ia468(UINT port) { return(ret); } -static BYTE IOINPCALL pcm86_ia46a(UINT port) { +static REG8 IOINPCALL pcm86_ia46a(UINT port) { (void)port; return(pcm86.dactrl); } -static BYTE IOINPCALL pcm86_inpdummy(UINT port) { +static REG8 IOINPCALL pcm86_inpdummy(UINT port) { (void)port; return(0); diff --git a/common.h b/common.h index 46fce029..08333750 100644 --- a/common.h +++ b/common.h @@ -32,7 +32,7 @@ enum { #endif -// Optimize Macros +// ---- Optimize Macros #ifndef REG8 #define REG8 BYTE @@ -40,9 +40,6 @@ enum { #ifndef REG16 #define REG16 UINT16 #endif -#ifndef REG32 -#define REG32 UINT32 -#endif #ifndef LOW12 #define LOW12(a) ((a) & 0x0fff) @@ -76,20 +73,20 @@ enum { #if defined(BYTESEX_LITTLE) typedef union { struct { - BYTE b; - BYTE g; - BYTE r; - BYTE e; + UINT8 b; + UINT8 g; + UINT8 r; + UINT8 e; } p; UINT32 d; } RGB32; #elif defined(BYTESEX_BIG) typedef union { struct { - BYTE e; - BYTE r; - BYTE g; - BYTE b; + UINT8 e; + UINT8 r; + UINT8 g; + UINT8 b; } p; UINT32 d; } RGB32; diff --git a/debugsub.c b/debugsub.c index 6dfd392d..4aaf0d6d 100644 --- a/debugsub.c +++ b/debugsub.c @@ -1,7 +1,7 @@ #include "compiler.h" #include "strres.h" #include "dosio.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -101,10 +101,10 @@ const char *debugsub_regs(void) { static char work[256]; - SPRINTF(work, str_register, I286_AX, I286_BX, I286_CX, I286_DX, - I286_SP, I286_BP, I286_SI, I286_DI, - I286_DS, I286_ES, I286_SS, I286_CS, I286_IP); - milstr_ncat(work, debugsub_flags(I286_FLAG), sizeof(work)); + SPRINTF(work, str_register, CPU_AX, CPU_BX, CPU_CX, CPU_DX, + CPU_SP, CPU_BP, CPU_SI, CPU_DI, + CPU_DS, CPU_ES, CPU_SS, CPU_CS, CPU_IP); + milstr_ncat(work, debugsub_flags(CPU_FLAG), sizeof(work)); milstr_ncat(work, CRCONST, sizeof(work)); return(work); } diff --git a/fdd/sxsi.c b/fdd/sxsi.c index 478e1ce4..ec320a92 100644 --- a/fdd/sxsi.c +++ b/fdd/sxsi.c @@ -1,7 +1,7 @@ #include "compiler.h" #include "dosio.h" #include "sysmng.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "sxsi.h" @@ -246,7 +246,7 @@ const _SXSIHDD *sxsi; } while(size) { rsize = min(size, sxsi->size); - I286_REMCLOCK -= rsize; + CPU_REMCLOCK -= rsize; if (file_read((FILEH)sxsi->fh, buf, rsize) != rsize) { return(0xd0); } @@ -276,7 +276,7 @@ const _SXSIHDD *sxsi; } while(size) { wsize = min(size, sxsi->size); - I286_REMCLOCK -= wsize; + CPU_REMCLOCK -= wsize; if (file_write((FILEH)sxsi->fh, buf, wsize) != wsize) { return(0x70); } @@ -313,7 +313,7 @@ const _SXSIHDD *sxsi; while(size) { wsize = min(size, sizeof(work)); size -= wsize; - I286_REMCLOCK -= wsize; + CPU_REMCLOCK -= wsize; if (file_write((FILEH)sxsi->fh, work, wsize) != wsize) { return(0x70); } diff --git a/i286c/i286.h b/i286c/cpucore.h similarity index 51% rename from i286c/i286.h rename to i286c/cpucore.h index 0f7e3afa..24b8a4ec 100644 --- a/i286c/i286.h +++ b/i286c/cpucore.h @@ -1,8 +1,8 @@ //---------------------------------------------------------------------------- // -// i286x : 80286 Engine for Pentium ver0.02 +// i286c : 80286 Engine for Pentium ver0.05 // -// Copyright by Yui/Studio Milmake 1999-2000 +// Copyright by Yui/Studio Milmake 1999-2003 // //---------------------------------------------------------------------------- @@ -18,6 +18,22 @@ enum { }; #endif +enum { + C_FLAG = 0x0001, + P_FLAG = 0x0004, + A_FLAG = 0x0010, + Z_FLAG = 0x0040, + S_FLAG = 0x0080, + T_FLAG = 0x0100, + I_FLAG = 0x0200, + D_FLAG = 0x0400, + O_FLAG = 0x0800 +}; + +enum { + CPUTYPE_V30 = 0x01 +}; + #ifndef CPUCALL #define CPUCALL #endif @@ -132,8 +148,8 @@ typedef struct { UINT16 prefix; UINT8 trap; UINT8 cpu_type; - UINT32 pf_semaphore; - UINT32 repbak; + UINT32 ____pf_semaphore; // 未使用 + UINT32 ____repbak; // 未使用 UINT32 inport; UINT32 ovflag; I286DTR GDTR; @@ -144,7 +160,8 @@ typedef struct { } I286STAT; typedef struct { // for ver0.73 - UINT dummy; + BYTE *ext; + UINT32 extsize; } I286EXT; typedef struct { @@ -158,96 +175,83 @@ extern "C" { #endif extern I286CORE i286core; -extern const BYTE iflags[]; - - -#define I286_MEM mem - -#define I286_REG i286core.s.r -#define I286_SEGREG i286core.s.r.w.es - -#define I286_AX i286core.s.r.w.ax -#define I286_BX i286core.s.r.w.bx -#define I286_CX i286core.s.r.w.cx -#define I286_DX i286core.s.r.w.dx -#define I286_SI i286core.s.r.w.si -#define I286_DI i286core.s.r.w.di -#define I286_BP i286core.s.r.w.bp -#define I286_SP i286core.s.r.w.sp -#define I286_CS i286core.s.r.w.cs -#define I286_DS i286core.s.r.w.ds -#define I286_ES i286core.s.r.w.es -#define I286_SS i286core.s.r.w.ss -#define I286_IP i286core.s.r.w.ip - -#define SEG_BASE i286core.s.es_base -#define ES_BASE i286core.s.es_base -#define CS_BASE i286core.s.cs_base -#define SS_BASE i286core.s.ss_base -#define DS_BASE i286core.s.ds_base -#define SS_FIX i286core.s.ss_fix -#define DS_FIX i286core.s.ds_fix - -#define I286_AL i286core.s.r.b.al -#define I286_BL i286core.s.r.b.bl -#define I286_CL i286core.s.r.b.cl -#define I286_DL i286core.s.r.b.dl -#define I286_AH i286core.s.r.b.ah -#define I286_BH i286core.s.r.b.bh -#define I286_CH i286core.s.r.b.ch -#define I286_DH i286core.s.r.b.dh - -#define I286_FLAG i286core.s.r.w.flag -#define I286_FLAGL i286core.s.r.b.flag_l -#define I286_FLAGH i286core.s.r.b.flag_h -#define I286_TRAP i286core.s.trap -#define I286_OV i286core.s.ovflag - -#define I286_REMCLOCK i286core.s.remainclock -#define I286_BASECLOCK i286core.s.baseclock -#define I286_CLOCK i286core.s.clock - - -enum { - C_FLAG = 0x0001, - P_FLAG = 0x0004, - A_FLAG = 0x0010, - Z_FLAG = 0x0040, - S_FLAG = 0x0080, - T_FLAG = 0x0100, - I_FLAG = 0x0200, - D_FLAG = 0x0400, - O_FLAG = 0x0800 -}; - -#define CPUTYPE i286core.s.cpu_type -#define CPUTYPE_V30 0x01 - -// ver0.28 -#define REPPOSBAK i286core.s.repbak -#define PREFIX_SMP i286core.s.pf_semaphore +extern const UINT8 iflags[]; -#define isI286DI (!(I286_FLAG & I_FLAG)) -#define isI286EI (I286_FLAG & I_FLAG) -#define I286_CLI I286_FLAG &= ~I_FLAG; \ - I286_TRAP = 0; -#define I286_STI I286_FLAG |= I_FLAG; \ - I286_TRAP = (I286_FLAG >> 8) & 1; +void i286c_initialize(void); +void i286c_reset(void); +void CPUCALL i286c_interrupt(REG8 vect); -void i286_initialize(void); -void i286_reset(void); -void i286_resetprefetch(void); +void i286c(void); +void i286c_step(void); -void CPUCALL i286_interrupt(BYTE vect); - -void i286(void); -void i286_step(void); - -void v30(void); -void v30_step(void); +void v30c(void); +void v30c_step(void); #ifdef __cplusplus } #endif + +// ---- macros + +#define CPU_STATSAVE i286core.s + +#define CPU_AX i286core.s.r.w.ax +#define CPU_BX i286core.s.r.w.bx +#define CPU_CX i286core.s.r.w.cx +#define CPU_DX i286core.s.r.w.dx +#define CPU_SI i286core.s.r.w.si +#define CPU_DI i286core.s.r.w.di +#define CPU_BP i286core.s.r.w.bp +#define CPU_SP i286core.s.r.w.sp +#define CPU_CS i286core.s.r.w.cs +#define CPU_DS i286core.s.r.w.ds +#define CPU_ES i286core.s.r.w.es +#define CPU_SS i286core.s.r.w.ss +#define CPU_IP i286core.s.r.w.ip + +#define ES_BASE i286core.s.es_base +#define CS_BASE i286core.s.cs_base +#define SS_BASE i286core.s.ss_base +#define DS_BASE i286core.s.ds_base + +#define CPU_AL i286core.s.r.b.al +#define CPU_BL i286core.s.r.b.bl +#define CPU_CL i286core.s.r.b.cl +#define CPU_DL i286core.s.r.b.dl +#define CPU_AH i286core.s.r.b.ah +#define CPU_BH i286core.s.r.b.bh +#define CPU_CH i286core.s.r.b.ch +#define CPU_DH i286core.s.r.b.dh + +#define CPU_FLAG i286core.s.r.w.flag +#define CPU_FLAGL i286core.s.r.b.flag_l + +#define CPU_REMCLOCK i286core.s.remainclock +#define CPU_BASECLOCK i286core.s.baseclock +#define CPU_CLOCK i286core.s.clock +#define CPU_ADRSMASK i286core.s.adrsmask +#define CPU_RESETREQ i286core.s.resetreq +#define CPU_ITFBANK i286core.s.itfbank +#define CPU_INPADRS i286core.s.inport + +#define CPU_EXTMEM i286core.e.ext +#define CPU_EXTMEMSIZE i286core.e.extsize + +#define CPU_TYPE i286core.s.cpu_type + +#define CPU_isDI (!(i286core.s.r.w.flag & I_FLAG)) +#define CPU_isEI (i286core.s.r.w.flag & I_FLAG) +#define CPU_CLI i286core.s.r.w.flag &= ~I_FLAG; \ + i286core.s.trap = 0; +#define CPU_STI i286core.s.r.w.flag |= I_FLAG; \ + i286core.s.trap = (i286core.s.r.w.flag >> 8) & 1; + +#define CPU_INITIALIZE i286c_initialize +#define CPU_RESET i286c_reset +#define CPU_CLEARPREFETCH() +#define CPU_INTERRUPT(v) i286c_interrupt(v) +#define CPU_EXEC i286c +#define CPU_EXECV30 v30c + diff --git a/i286c/dmap.c b/i286c/dmap.c index 40bbbeb0..a008cb71 100644 --- a/i286c/dmap.c +++ b/i286c/dmap.c @@ -33,7 +33,7 @@ void dmap_i286(void) { break; default: - ch->outproc((BYTE)i286_memoryread(ch->adrs.d)); + ch->outproc(i286_memoryread(ch->adrs.d)); break; } ch->adrs.d += ((ch->mode & 0x20)?-1:1); @@ -72,7 +72,7 @@ void dmap_v30(void) { break; default: - ch->outproc((BYTE)i286_memoryread(ch->adrs.d)); + ch->outproc(i286_memoryread(ch->adrs.d)); break; } ch->adrs.w[DMA16_LOW] += ((ch->mode & 0x20)?-1:1); diff --git a/i286c/i286c.c b/i286c/i286c.c index ee70a42b..692c40c8 100644 --- a/i286c/i286c.c +++ b/i286c/i286c.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "v30patch.h" #include "memory.h" @@ -11,7 +11,7 @@ I286CORE i286core; -const BYTE iflags[256] = { // Z_FLAG, S_FLAG, P_FLAG +const UINT8 iflags[256] = { // Z_FLAG, S_FLAG, P_FLAG 0x44, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, @@ -48,26 +48,26 @@ const BYTE iflags[256] = { // Z_FLAG, S_FLAG, P_FLAG // ---- - BYTE _szpcflag8[0x200]; + UINT8 _szpcflag8[0x200]; #if !defined(MEMOPTIMIZE) - BYTE _szpflag16[0x10000]; + UINT8 _szpflag16[0x10000]; #endif #if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) - BYTE *_reg8_b53[256]; - BYTE *_reg8_b20[256]; + UINT8 *_reg8_b53[256]; + UINT8 *_reg8_b20[256]; #endif #if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) UINT16 *_reg16_b53[256]; UINT16 *_reg16_b20[256]; #endif -void i286_initialize(void) { +void i286c_initialize(void) { UINT i; UINT bit; - BYTE f; + REG8 f; for (i=0; i<0x100; i++) { f = P_FLAG; @@ -95,14 +95,14 @@ void i286_initialize(void) { pos = ((i & 0x20)?0:1); #endif pos += ((i >> 3) & 3) * 2; - _reg8_b53[i] = ((BYTE *)&I286_REG) + pos; + _reg8_b53[i] = ((UINT8 *)&I286_REG) + pos; #if defined(BYTESEX_LITTLE) pos = ((i & 0x4)?1:0); #else pos = ((i & 0x4)?0:1); #endif pos += (i & 3) * 2; - _reg8_b20[i] = ((BYTE *)&I286_REG) + pos; + _reg8_b20[i] = ((UINT8 *)&I286_REG) + pos; #if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) _reg16_b53[i] = ((UINT16 *)&I286_REG) + ((i >> 3) & 7); _reg16_b20[i] = ((UINT16 *)&I286_REG) + (i & 7); @@ -130,21 +130,18 @@ void i286_initialize(void) { #if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) i286cea_initialize(); #endif - v30init(); + v30cinit(); } -void i286_reset(void) { +void i286c_reset(void) { - ZeroMemory(&i286core.s, sizeof(i286core.s)); + ZeroMemory(&I286_STAT, sizeof(I286_STAT)); I286_CS = 0x1fc0; CS_BASE = 0x1fc00; - i286core.s.adrsmask = 0xfffff; + I286_ADRSMASK = 0xfffff; } -void i286_resetprefetch(void) { -} - -void CPUCALL i286_intnum(UINT vect, REG16 IP) { +void CPUCALL i286c_intnum(UINT vect, REG16 IP) { const BYTE *ptr; @@ -162,7 +159,7 @@ const BYTE *ptr; I286_WORKCLOCK(20); } -void CPUCALL i286_interrupt(BYTE vect) { +void CPUCALL i286c_interrupt(REG8 vect) { UINT op; const BYTE *ptr; @@ -179,13 +176,13 @@ const BYTE *ptr; I286_TRAP = 0; ptr = I286_MEM + (vect * 4); - I286_IP = LOADINTELWORD(ptr+0); // real mode! - I286_CS = LOADINTELWORD(ptr+2); // real mode! + I286_IP = LOADINTELWORD(ptr + 0); // real mode! + I286_CS = LOADINTELWORD(ptr + 2); // real mode! CS_BASE = I286_CS << 4; I286_WORKCLOCK(20); } -void i286(void) { +void i286c(void) { UINT opcode; @@ -194,7 +191,7 @@ void i286(void) { GET_PCBYTE(opcode); i286op[opcode](); if (I286_TRAP) { - i286_interrupt(1); + i286c_interrupt(1); } dmap_i286(); } while(I286_REMCLOCK > 0); @@ -214,7 +211,7 @@ void i286(void) { } } -void i286_step(void) { +void i286c_step(void) { UINT opcode; diff --git a/i286c/i286c.h b/i286c/i286c.h index 17555f9b..754ced45 100644 --- a/i286c/i286c.h +++ b/i286c/i286c.h @@ -6,14 +6,72 @@ #undef MEMOPTIMIZE #endif + +#define I286_MEM mem + +#define I286_STAT i286core.s.r + +#define I286_REG i286core.s.r +#define I286_SEGREG i286core.s.r.w.es + +#define I286_AX i286core.s.r.w.ax +#define I286_BX i286core.s.r.w.bx +#define I286_CX i286core.s.r.w.cx +#define I286_DX i286core.s.r.w.dx +#define I286_SI i286core.s.r.w.si +#define I286_DI i286core.s.r.w.di +#define I286_BP i286core.s.r.w.bp +#define I286_SP i286core.s.r.w.sp +#define I286_CS i286core.s.r.w.cs +#define I286_DS i286core.s.r.w.ds +#define I286_ES i286core.s.r.w.es +#define I286_SS i286core.s.r.w.ss +#define I286_IP i286core.s.r.w.ip + +#define SEG_BASE i286core.s.es_base +#define ES_BASE i286core.s.es_base +#define CS_BASE i286core.s.cs_base +#define SS_BASE i286core.s.ss_base +#define DS_BASE i286core.s.ds_base +#define SS_FIX i286core.s.ss_fix +#define DS_FIX i286core.s.ds_fix + +#define I286_AL i286core.s.r.b.al +#define I286_BL i286core.s.r.b.bl +#define I286_CL i286core.s.r.b.cl +#define I286_DL i286core.s.r.b.dl +#define I286_AH i286core.s.r.b.ah +#define I286_BH i286core.s.r.b.bh +#define I286_CH i286core.s.r.b.ch +#define I286_DH i286core.s.r.b.dh + +#define I286_FLAG i286core.s.r.w.flag +#define I286_FLAGL i286core.s.r.b.flag_l +#define I286_FLAGH i286core.s.r.b.flag_h +#define I286_TRAP i286core.s.trap +#define I286_OV i286core.s.ovflag + +#define I286_GDTR i286core.s.GDTR +#define I286_IDTR i286core.s.IDTR +#define I286_MSW i286core.s.MSW + +#define I286_REMCLOCK i286core.s.remainclock +#define I286_BASECLOCK i286core.s.baseclock +#define I286_CLOCK i286core.s.clock +#define I286_ADRSMASK i286core.s.adrsmask +#define I286_INPADRS i286core.s.inport + +#define I286_PREFIX i286core.s.prefix + + #define I286FN static void #define I286EXT void typedef void (*I286OP)(void); -extern BYTE _szpcflag[0x200]; +extern UINT8 _szpcflag[0x200]; -extern void CPUCALL i286_intnum(UINT vect, REG16 IP); +extern void CPUCALL i286c_intnum(UINT vect, REG16 IP); #if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) extern void i286cea_initialize(void); @@ -30,7 +88,7 @@ I286EXT i286c_cts(void); #define I286_8X static void CPUCALL -typedef void (CPUCALL * I286OP8XREG8)(BYTE *p); +typedef void (CPUCALL * I286OP8XREG8)(UINT8 *p); typedef void (CPUCALL * I286OP8XEXT8)(UINT32 madr); typedef void (CPUCALL * I286OP8XREG16)(UINT16 *p, UINT32 src); typedef void (CPUCALL * I286OP8XEXT16)(UINT32 madr, UINT32 src); @@ -42,11 +100,11 @@ extern const I286OP8XEXT16 c_op8xext16_table[]; #define I286_SFT static void CPUCALL -typedef void (CPUCALL * I286OPSFTR8)(BYTE *p); +typedef void (CPUCALL * I286OPSFTR8)(UINT8 *p); typedef void (CPUCALL * I286OPSFTE8)(UINT32 madr); typedef void (CPUCALL * I286OPSFTR16)(UINT16 *p); typedef void (CPUCALL * I286OPSFTE16)(UINT32 madr); -typedef void (CPUCALL * I286OPSFTR8CL)(BYTE *p, BYTE cl); +typedef void (CPUCALL * I286OPSFTR8CL)(UINT8 *p, BYTE cl); typedef void (CPUCALL * I286OPSFTE8CL)(UINT32 madr, BYTE cl); typedef void (CPUCALL * I286OPSFTR16CL)(UINT16 *p, BYTE cl); typedef void (CPUCALL * I286OPSFTE16CL)(UINT32 madr, BYTE cl); diff --git a/i286c/i286c.mcr b/i286c/i286c.mcr index 74f289e1..b88e895b 100644 --- a/i286c/i286c.mcr +++ b/i286c/i286c.mcr @@ -24,16 +24,16 @@ #if defined(I286C_TEST) -extern BYTE BYTESZPF(UINT r); -extern BYTE BYTESZPCF(UINT r); +extern UINT8 BYTESZPF(UINT r); +extern UINT8 BYTESZPCF(UINT r); #define BYTESZPCF2(a) BYTESZPCF((a) & 0x1ff) -extern BYTE WORDSZPF(UINT32 r); -extern BYTE WORDSZPCF(UINT32 r); +extern UINT8 WORDSZPF(UINT32 r); +extern UINT8 WORDSZPCF(UINT32 r); #elif !defined(MEMOPTIMIZE) -extern BYTE _szpcflag8[0x200]; -extern BYTE _szpflag16[0x10000]; +extern UINT8 _szpcflag8[0x200]; +extern UINT8 _szpflag16[0x10000]; #define BYTESZPF(a) (_szpcflag8[(a)]) #define BYTESZPCF(a) (_szpcflag8[(a)]) #define BYTESZPCF2(a) (_szpcflag8[(a) & 0x1ff]) @@ -42,7 +42,7 @@ extern BYTE _szpflag16[0x10000]; #else -extern BYTE _szpcflag8[0x200]; +extern UINT8 _szpcflag8[0x200]; #define BYTESZPF(a) (_szpcflag8[(a)]) #define BYTESZPCF(a) (_szpcflag8[(a)]) @@ -59,20 +59,20 @@ extern BYTE _szpcflag8[0x200]; // ---- reg position #if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) -extern BYTE *_reg8_b53[256]; -extern BYTE *_reg8_b20[256]; +extern UINT8 *_reg8_b53[256]; +extern UINT8 *_reg8_b20[256]; #define REG8_B53(op) _reg8_b53[(op)] #define REG8_B20(op) _reg8_b20[(op)] #else #if defined(BYTESEX_LITTLE) #define REG8_B53(op) \ - (((BYTE *)&I286_REG) + (((op) >> 2) & 6) + (((op) >> 5) & 1)) + (((UINT8 *)&I286_REG) + (((op) >> 2) & 6) + (((op) >> 5) & 1)) #define REG8_B20(op) \ - (((BYTE *)&I286_REG) + (((op) & 3) * 2) + (((op) >> 2) & 1)) + (((UINT8 *)&I286_REG) + (((op) & 3) * 2) + (((op) >> 2) & 1)) #else -#define REG8_B53(op) (((BYTE *)&I286_REG) + (((op) >> 2) & 6) + \ +#define REG8_B53(op) (((UINT8 *)&I286_REG) + (((op) >> 2) & 6) + \ ((((op) >> 5) & 1) ^ 1)) -#define REG8_B20(op) (((BYTE *)&I286_REG) + (((op) & 3) * 2) + \ +#define REG8_B20(op) (((UINT8 *)&I286_REG) + (((op) & 3) * 2) + \ ((((op) >> 2) & 1) ^ 1)) #endif #endif @@ -111,13 +111,14 @@ extern UINT calc_a(UINT op, UINT32 *seg); #define SWAPBYTE(p, q) { \ - BYTE tmp = (p); \ + REG8 tmp; \ + tmp = (p); \ (p) = (q); \ (q) = tmp; \ } #define SWAPWORD(p, q) { \ - UINT16 tmp; \ + REG16 tmp; \ tmp = (p); \ (p) = (q); \ (q) = tmp; \ @@ -214,7 +215,7 @@ extern UINT calc_a(UINT op, UINT32 *seg); #define ADDWORD(r, d, s) \ (r) = (s) + (d); \ I286_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x8000; \ - I286_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ I286_FLAGL |= WORDSZPCF(r); @@ -233,13 +234,13 @@ extern UINT calc_a(UINT op, UINT32 *seg); #define ADCBYTE(r, d, s) \ (r) = (I286_FLAGL & 1) + (s) + (d); \ I286_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80; \ - I286_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ I286_FLAGL |= BYTESZPCF(r); #define ADCWORD(r, d, s) \ (r) = (I286_FLAGL & 1) + (s) + (d); \ I286_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x8000; \ - I286_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ I286_FLAGL |= WORDSZPCF(r); @@ -247,13 +248,13 @@ extern UINT calc_a(UINT op, UINT32 *seg); #define SBBBYTE(r, d, s) \ (r) = (d) - (s) - (I286_FLAGL & 1); \ I286_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80; \ - I286_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ I286_FLAGL |= BYTESZPCF2(r); #define SBBWORD(r, d, s) \ (r) = (d) - (s) - (I286_FLAGL & 1); \ I286_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x8000; \ - I286_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ I286_FLAGL |= WORDSZPCF(r); @@ -273,7 +274,7 @@ extern UINT calc_a(UINT op, UINT32 *seg); #define SUBBYTE(r, d, s) \ (r) = (d) - (s); \ I286_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80; \ - I286_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ I286_FLAGL |= BYTESZPCF2(r); #define SUBWORD(r, d, s) \ @@ -298,19 +299,19 @@ extern UINT calc_a(UINT op, UINT32 *seg); #define NEGBYTE(d, s) \ (d) = 0 - (s); \ I286_OV = ((d) & (s)) & 0x80; \ - I286_FLAGL = (BYTE)(((d) ^ (s)) & A_FLAG); \ + I286_FLAGL = (UINT8)(((d) ^ (s)) & A_FLAG); \ I286_FLAGL |= BYTESZPCF2(d); #define NEGWORD(d, s) \ (d) = 0 - (s); \ I286_OV = ((d) & (s)) & 0x8000; \ - I286_FLAGL = (BYTE)(((d) ^ (s)) & A_FLAG); \ + I286_FLAGL = (UINT8)(((d) ^ (s)) & A_FLAG); \ I286_FLAGL |= WORDSZPCF(d); #define BYTE_MUL(r, d, s) \ I286_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ - (r) = (BYTE)(d) * (BYTE)(s); \ + (r) = (UINT8)(d) * (UINT8)(s); \ I286_OV = (r) >> 8; \ if (I286_OV) { \ I286_FLAGL |= C_FLAG; \ @@ -348,8 +349,8 @@ extern UINT calc_a(UINT op, UINT32 *seg); (s)++; \ I286_OV = (s) & (b ^ (s)) & 0x80; \ I286_FLAGL &= C_FLAG; \ - I286_FLAGL |= (BYTE)((b ^ (s)) & A_FLAG); \ - I286_FLAGL |= BYTESZPF((BYTE)(s)); \ + I286_FLAGL |= (UINT8)((b ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPF((UINT8)(s)); \ } #define INCWORD(s) { \ @@ -357,7 +358,7 @@ extern UINT calc_a(UINT op, UINT32 *seg); (s)++; \ I286_OV = (s) & (b ^ (s)) & 0x8000; \ I286_FLAGL &= C_FLAG; \ - I286_FLAGL |= (BYTE)((b ^ (s)) & A_FLAG); \ + I286_FLAGL |= (UINT8)((b ^ (s)) & A_FLAG); \ I286_FLAGL |= WORDSZPF((UINT16)(s)); \ } @@ -368,8 +369,8 @@ extern UINT calc_a(UINT op, UINT32 *seg); b--; \ I286_OV = (s) & (b ^ (s)) & 0x80; \ I286_FLAGL &= C_FLAG; \ - I286_FLAGL |= (BYTE)((b ^ (s)) & A_FLAG); \ - I286_FLAGL |= BYTESZPF((BYTE)b); \ + I286_FLAGL |= (UINT8)((b ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPF((UINT8)b); \ (s) = b; \ } @@ -378,7 +379,7 @@ extern UINT calc_a(UINT op, UINT32 *seg); b--; \ I286_OV = (s) & (b ^ (s)) & 0x8000; \ I286_FLAGL &= C_FLAG; \ - I286_FLAGL |= (BYTE)((b ^ (s)) & A_FLAG); \ + I286_FLAGL |= (UINT8)((b ^ (s)) & A_FLAG); \ I286_FLAGL |= WORDSZPF((UINT16)b); \ (s) = b; \ } @@ -392,7 +393,7 @@ extern UINT calc_a(UINT op, UINT32 *seg); (r) = (UINT16)d; \ I286_OV = d & (d ^ s) & 0x8000; \ I286_FLAGL &= C_FLAG; \ - I286_FLAGL |= (BYTE)((d ^ s) & A_FLAG); \ + I286_FLAGL |= (UINT8)((d ^ s) & A_FLAG); \ I286_FLAGL |= WORDSZPF((UINT16)d); \ I286_WORKCLOCK(clock); \ } @@ -404,7 +405,7 @@ extern UINT calc_a(UINT op, UINT32 *seg); (r) = (UINT16)d; \ I286_OV = s & (d ^ s) & 0x8000; \ I286_FLAGL &= C_FLAG; \ - I286_FLAGL |= (BYTE)((d ^ s) & A_FLAG); \ + I286_FLAGL |= (UINT8)((d ^ s) & A_FLAG); \ I286_FLAGL |= WORDSZPF((UINT16)d); \ I286_WORKCLOCK(clock); \ } @@ -502,5 +503,5 @@ extern UINT calc_a(UINT op, UINT32 *seg); } -#define INT_NUM(a, b) i286_intnum((a), (REG16)(b)) +#define INT_NUM(a, b) i286c_intnum((a), (REG16)(b)) diff --git a/i286c/i286c_0f.c b/i286c/i286c_0f.c index c0bbc7ac..a2183bc3 100644 --- a/i286c/i286c_0f.c +++ b/i286c/i286c_0f.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "memory.h" #include "i286c.mcr" @@ -13,10 +13,10 @@ I286_0F _sgdt(UINT op) { I286_WORKCLOCK(11); if (op < 0xc0) { ad = GET_EA(op, &seg); - i286_memorywrite_w(seg + ad, i286core.s.GDTR.limit); - i286_memorywrite_w(seg + LOW16(ad + 2), i286core.s.GDTR.base); + i286_memorywrite_w(seg + ad, I286_GDTR.limit); + i286_memorywrite_w(seg + LOW16(ad + 2), I286_GDTR.base); i286_memorywrite_w(seg + LOW16(ad + 4), - (REG16)(0xff00 + i286core.s.GDTR.base24)); + (REG16)(0xff00 + I286_GDTR.base24)); } else { INT_NUM(6, I286_IP - 2); @@ -31,10 +31,10 @@ I286_0F _sidt(UINT op) { I286_WORKCLOCK(12); if (op < 0xc0) { ad = GET_EA(op, &seg); - i286_memorywrite_w(seg + ad, i286core.s.IDTR.limit); - i286_memorywrite_w(seg + LOW16(ad + 2), i286core.s.IDTR.base); + i286_memorywrite_w(seg + ad, I286_IDTR.limit); + i286_memorywrite_w(seg + LOW16(ad + 2), I286_IDTR.base); i286_memorywrite_w(seg + LOW16(ad + 4), - (REG16)(0xff00 + i286core.s.IDTR.base24)); + (REG16)(0xff00 + I286_IDTR.base24)); } else { INT_NUM(6, I286_IP - 2); @@ -49,10 +49,10 @@ I286_0F _lgdt(UINT op) { I286_WORKCLOCK(11); if (op < 0xc0) { ad = GET_EA(op, &seg); - i286core.s.GDTR.limit = i286_memoryread_w(seg + ad); - i286core.s.GDTR.base = i286_memoryread_w(seg + LOW16(ad + 2)); - i286core.s.GDTR.base24 = i286_memoryread(seg + LOW16(ad + 4)); - i286core.s.GDTR.reserved = i286_memoryread(seg + LOW16(ad + 5)); + I286_GDTR.limit = i286_memoryread_w(seg + ad); + I286_GDTR.base = i286_memoryread_w(seg + LOW16(ad + 2)); + I286_GDTR.base24 = i286_memoryread(seg + LOW16(ad + 4)); + I286_GDTR.reserved = i286_memoryread(seg + LOW16(ad + 5)); } else { INT_NUM(6, I286_IP - 2); @@ -67,10 +67,10 @@ I286_0F _lidt(UINT op) { I286_WORKCLOCK(11); if (op < 0xc0) { ad = GET_EA(op, &seg); - i286core.s.IDTR.limit = i286_memoryread_w(seg + ad); - i286core.s.IDTR.base = i286_memoryread_w(seg + LOW16(ad + 2)); - i286core.s.IDTR.base24 = i286_memoryread(seg + LOW16(ad + 4)); - i286core.s.IDTR.reserved = i286_memoryread(seg + LOW16(ad + 5)); + I286_IDTR.limit = i286_memoryread_w(seg + ad); + I286_IDTR.base = i286_memoryread_w(seg + LOW16(ad + 2)); + I286_IDTR.base24 = i286_memoryread(seg + LOW16(ad + 4)); + I286_IDTR.reserved = i286_memoryread(seg + LOW16(ad + 5)); } else { INT_NUM(6, I286_IP - 2); @@ -81,11 +81,11 @@ I286_0F _smsw(UINT op) { if (op >= 0xc0) { I286_WORKCLOCK(3); - *(REG16_B20(op)) = i286core.s.MSW; + *(REG16_B20(op)) = I286_MSW; } else { I286_WORKCLOCK(6); - i286_memorywrite_w(CALC_EA(op), i286core.s.MSW); + i286_memorywrite_w(CALC_EA(op), I286_MSW); } } @@ -93,11 +93,11 @@ I286_0F _lmsw(UINT op) { if (op >= 0xc0) { I286_WORKCLOCK(2); - i286core.s.MSW = *(REG16_B20(op)); + I286_MSW = *(REG16_B20(op)); } else { I286_WORKCLOCK(3); - i286core.s.MSW = i286_memoryread_w(CALC_EA(op)); + I286_MSW = i286_memoryread_w(CALC_EA(op)); } } @@ -113,7 +113,7 @@ I286_0F _loadall286(void) { UINT16 tmp; I286_WORKCLOCK(195); - i286core.s.MSW = LOADINTELWORD(mem + 0x804); + I286_MSW = LOADINTELWORD(mem + 0x804); tmp = LOADINTELWORD(mem + 0x818); I286_OV = tmp & O_FLAG; I286_FLAG = tmp & (0xfff ^ O_FLAG); diff --git a/i286c/i286c_8x.c b/i286c/i286c_8x.c index a5f1c2ab..01a3a338 100644 --- a/i286c/i286c_8x.c +++ b/i286c/i286c_8x.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "memory.h" #include "i286c.mcr" diff --git a/i286c/i286c_ea.c b/i286c/i286c_ea.c index b451ddd5..2e82918b 100644 --- a/i286c/i286c_ea.c +++ b/i286c/i286c_ea.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "memory.h" #include "i286c.mcr" diff --git a/i286c/i286c_f6.c b/i286c/i286c_f6.c index c7fcf201..0848c018 100644 --- a/i286c/i286c_f6.c +++ b/i286c/i286c_f6.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "memory.h" #include "i286c.mcr" diff --git a/i286c/i286c_fe.c b/i286c/i286c_fe.c index 2b29629e..872c5539 100644 --- a/i286c/i286c_fe.c +++ b/i286c/i286c_fe.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "memory.h" #include "i286c.mcr" diff --git a/i286c/i286c_mn.c b/i286c/i286c_mn.c index 232709f8..d1e21203 100644 --- a/i286c/i286c_mn.c +++ b/i286c/i286c_mn.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "memory.h" #include "pccore.h" @@ -623,13 +623,13 @@ I286FN _segprefix_es(void) { // 26: es: SS_FIX = ES_BASE; DS_FIX = ES_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -769,13 +769,13 @@ I286FN _segprefix_cs(void) { // 2e: cs: SS_FIX = CS_BASE; DS_FIX = CS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -910,13 +910,13 @@ I286FN _segprefix_ss(void) { // 36: ss: SS_FIX = SS_BASE; DS_FIX = SS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -1027,13 +1027,13 @@ I286FN _segprefix_ds(void) { // 3e: ds: SS_FIX = DS_BASE; DS_FIX = DS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -1820,7 +1820,7 @@ I286FN _popf(void) { // 9D: popf I286_TRAP = ((flag & 0x300) == 0x300); I286_WORKCLOCK(5); #if defined(INTR_FAST) - if ((flag & I_FLAG) && (PICEXISTINTR)) { + if ((I286_TRAP) || ((flag & I_FLAG) && (PICEXISTINTR))) { I286IRQCHECKTERM } #else @@ -2282,7 +2282,7 @@ I286FN _iret(void) { // CF: iret CS_BASE = I286_CS << 4; I286_WORKCLOCK(31); #if defined(INTR_FAST) - if ((flag & I_FLAG) && (PICEXISTINTR)) { + if ((I286_TRAP) || ((flag & I_FLAG) && (PICEXISTINTR))) { I286IRQCHECKTERM } #else @@ -2475,9 +2475,9 @@ I286FN _in_al_data8(void) { // E4: in al, DATA8 I286_WORKCLOCK(5); GET_PCBYTE(port) - i286core.s.inport = CS_BASE + I286_IP; + I286_INPADRS = CS_BASE + I286_IP; I286_AL = iocore_inp8(port); - i286core.s.inport = 0; + I286_INPADRS = 0; } I286FN _in_ax_data8(void) { // E5: in ax, DATA8 @@ -2577,12 +2577,12 @@ I286FN _lock(void) { // F0: lock I286FN _repne(void) { // F2: repne - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repne[op](); - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -2591,12 +2591,12 @@ I286FN _repne(void) { // F2: repne I286FN _repe(void) { // F3: repe - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repe[op](); - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -2662,11 +2662,11 @@ I286FN _sti(void) { // FB: sti I286_FLAG |= I_FLAG; I286_TRAP = (I286_FLAG & T_FLAG) >> 8; #if defined(INTR_FAST) - if (!PICEXISTINTR) { - NEXT_OPCODE; + if ((I286_TRAP) || (PICEXISTINTR)) { + REMAIN_ADJUST(1) } else { - REMAIN_ADJUST(1) + NEXT_OPCODE; } #else REMAIN_ADJUST(1) @@ -2985,13 +2985,13 @@ I286FN _repe_segprefix_es(void) { DS_FIX = ES_BASE; SS_FIX = ES_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repe[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -3002,13 +3002,13 @@ I286FN _repe_segprefix_cs(void) { DS_FIX = CS_BASE; SS_FIX = CS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repe[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -3019,13 +3019,13 @@ I286FN _repe_segprefix_ss(void) { DS_FIX = SS_BASE; SS_FIX = SS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repe[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -3036,13 +3036,13 @@ I286FN _repe_segprefix_ds(void) { DS_FIX = DS_BASE; SS_FIX = DS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repe[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -3330,13 +3330,13 @@ I286FN _repne_segprefix_es(void) { DS_FIX = ES_BASE; SS_FIX = ES_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repne[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -3347,13 +3347,13 @@ I286FN _repne_segprefix_cs(void) { DS_FIX = CS_BASE; SS_FIX = CS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repne[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -3364,13 +3364,13 @@ I286FN _repne_segprefix_ss(void) { DS_FIX = SS_BASE; SS_FIX = SS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repne[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -3381,13 +3381,13 @@ I286FN _repne_segprefix_ds(void) { DS_FIX = DS_BASE; SS_FIX = DS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); i286op_repne[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); diff --git a/i286c/i286c_rp.c b/i286c/i286c_rp.c index cac593ca..35d3c826 100644 --- a/i286c/i286c_rp.c +++ b/i286c/i286c_rp.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "memory.h" #include "pccore.h" @@ -86,7 +86,7 @@ I286EXT i286c_rep_movsb(void) { break; } if (I286_REMCLOCK <= 0) { - I286_IP -= i286core.s.prefix + 1; + I286_IP -= I286_PREFIX + 1; break; } } @@ -109,7 +109,7 @@ I286EXT i286c_rep_movsw(void) { break; } if (I286_REMCLOCK <= 0) { - I286_IP -= i286core.s.prefix + 1; + I286_IP -= I286_PREFIX + 1; break; } } @@ -133,7 +133,7 @@ I286EXT i286c_rep_lodsb(void) { break; } if (I286_REMCLOCK <= 0) { - I286_IP -= i286core.s.prefix + 1; + I286_IP -= I286_PREFIX + 1; break; } } @@ -154,7 +154,7 @@ I286EXT i286c_rep_lodsw(void) { break; } if (I286_REMCLOCK <= 0) { - I286_IP -= i286core.s.prefix + 1; + I286_IP -= I286_PREFIX + 1; break; } } @@ -178,7 +178,7 @@ I286EXT i286c_rep_stosb(void) { break; } if (I286_REMCLOCK <= 0) { - I286_IP -= i286core.s.prefix + 1; + I286_IP -= I286_PREFIX + 1; break; } } @@ -199,7 +199,7 @@ I286EXT i286c_rep_stosw(void) { break; } if (I286_REMCLOCK <= 0) { - I286_IP -= i286core.s.prefix + 1; + I286_IP -= I286_PREFIX + 1; break; } } diff --git a/i286c/i286c_sf.c b/i286c/i286c_sf.c index 6d919d4a..2e119e32 100644 --- a/i286c/i286c_sf.c +++ b/i286c/i286c_sf.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "memory.h" #include "i286c.mcr" diff --git a/i286c/memory.c b/i286c/memory.c index 7d41d4ad..802f1225 100644 --- a/i286c/memory.c +++ b/i286c/memory.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "egcmem.h" #include "pccore.h" @@ -17,12 +17,12 @@ static void MEMCALL i286_wt(UINT32 address, REG8 value) { - mem[address & i286core.s.adrsmask] = (BYTE)value; + mem[address & CPU_ADRSMASK] = (BYTE)value; } static void MEMCALL tram_wt(UINT32 address, REG8 value) { - I286_REMCLOCK -= vramop.tramwait; + CPU_REMCLOCK -= vramop.tramwait; if (address < 0xa2000) { mem[address] = (BYTE)value; tramupdate[LOW12(address >> 1)] = 1; @@ -54,7 +54,7 @@ static void MEMCALL tram_wt(UINT32 address, REG8 value) { static void MEMCALL vram_w0(UINT32 address, REG8 value) { - I286_REMCLOCK -= vramop.vramwait; + CPU_REMCLOCK -= vramop.vramwait; mem[address] = (BYTE)value; vramupdate[LOW15(address)] |= 1; gdcs.grphdisp |= 1; @@ -62,7 +62,7 @@ static void MEMCALL vram_w0(UINT32 address, REG8 value) { static void MEMCALL vram_w1(UINT32 address, REG8 value) { - I286_REMCLOCK -= vramop.vramwait; + CPU_REMCLOCK -= vramop.vramwait; mem[address + VRAM_STEP] = (BYTE)value; vramupdate[LOW15(address)] |= 2; gdcs.grphdisp |= 2; @@ -73,7 +73,7 @@ static void MEMCALL grcg_rmw0(UINT32 address, REG8 value) { REG8 mask; BYTE *vram; - I286_REMCLOCK -= vramop.grcgwait; + CPU_REMCLOCK -= vramop.grcgwait; mask = ~value; address = LOW15(address); vramupdate[address] |= 1; @@ -102,7 +102,7 @@ static void MEMCALL grcg_rmw1(UINT32 address, REG8 value) { REG8 mask; BYTE *vram; - I286_REMCLOCK -= vramop.grcgwait; + CPU_REMCLOCK -= vramop.grcgwait; mask = ~value; address = LOW15(address); vramupdate[address] |= 2; @@ -130,7 +130,7 @@ static void MEMCALL grcg_tdw0(UINT32 address, REG8 value) { BYTE *vram; - I286_REMCLOCK -= vramop.grcgwait; + CPU_REMCLOCK -= vramop.grcgwait; address = LOW15(address); vramupdate[address] |= 1; gdcs.grphdisp |= 1; @@ -154,7 +154,7 @@ static void MEMCALL grcg_tdw1(UINT32 address, REG8 value) { BYTE *vram; - I286_REMCLOCK -= vramop.grcgwait; + CPU_REMCLOCK -= vramop.grcgwait; address = LOW15(address); vramupdate[address] |= 2; gdcs.grphdisp |= 2; @@ -195,12 +195,12 @@ static void MEMCALL i286_wn(UINT32 address, REG8 value) { static REG8 MEMCALL i286_rd(UINT32 address) { - return(mem[address & i286core.s.adrsmask]); + return(mem[address & CPU_ADRSMASK]); } static REG8 MEMCALL tram_rd(UINT32 address) { - I286_REMCLOCK -= vramop.tramwait; + CPU_REMCLOCK -= vramop.tramwait; if (address < 0xa4000) { return(mem[address]); } @@ -217,13 +217,13 @@ static REG8 MEMCALL tram_rd(UINT32 address) { static REG8 MEMCALL vram_r0(UINT32 address) { - I286_REMCLOCK -= vramop.vramwait; + CPU_REMCLOCK -= vramop.vramwait; return(mem[address]); } static REG8 MEMCALL vram_r1(UINT32 address) { - I286_REMCLOCK -= vramop.vramwait; + CPU_REMCLOCK -= vramop.vramwait; return(mem[address + VRAM_STEP]); } @@ -232,7 +232,7 @@ static REG8 MEMCALL grcg_tcr0(UINT32 address) { const BYTE *vram; REG8 ret; - I286_REMCLOCK -= vramop.grcgwait; + CPU_REMCLOCK -= vramop.grcgwait; vram = mem + LOW15(address); ret = 0; if (!(grcg.modereg & 1)) { @@ -255,7 +255,7 @@ static REG8 MEMCALL grcg_tcr1(UINT32 address) { const BYTE *vram; REG8 ret; - I286_REMCLOCK -= vramop.grcgwait; + CPU_REMCLOCK -= vramop.grcgwait; ret = 0; vram = mem + LOW15(address); if (!(grcg.modereg & 1)) { @@ -285,7 +285,7 @@ static REG8 MEMCALL emmc_rd(UINT32 address) { static REG8 MEMCALL i286_itf(UINT32 address) { - if (i286core.s.itfbank) { + if (CPU_ITFBANK) { address = ITF_ADRS + LOW15(address); } return(mem[address]); @@ -298,7 +298,7 @@ static void MEMCALL i286w_wt(UINT32 address, REG16 value) { BYTE *ptr; - ptr = mem + (address & i286core.s.adrsmask); + ptr = mem + (address & CPU_ADRSMASK); STOREINTELWORD(ptr, value); } @@ -349,7 +349,7 @@ static void MEMCALL tramw_wt(UINT32 address, REG16 value) { #define GRCGW_NON(page) { \ - I286_REMCLOCK -= vramop.vramwait; \ + CPU_REMCLOCK -= vramop.vramwait; \ STOREINTELWORD(mem + address + VRAM_STEP*(page), value); \ vramupdate[LOW15(address)] |= (1 << page); \ vramupdate[LOW15(address + 1)] |= (1 << page); \ @@ -358,7 +358,7 @@ static void MEMCALL tramw_wt(UINT32 address, REG16 value) { #define GRCGW_RMW(page) { \ BYTE *vram; \ - I286_REMCLOCK -= vramop.grcgwait; \ + CPU_REMCLOCK -= vramop.grcgwait; \ address = LOW15(address); \ vramupdate[address] |= (1 << page); \ vramupdate[address + 1] |= (1 << page); \ @@ -404,7 +404,7 @@ static void MEMCALL tramw_wt(UINT32 address, REG16 value) { #define GRCGW_TDW(page) { \ BYTE *vram; \ - I286_REMCLOCK -= vramop.grcgwait; \ + CPU_REMCLOCK -= vramop.grcgwait; \ address = LOW15(address); \ vramupdate[address] |= (1 << page); \ vramupdate[address + 1] |= (1 << page); \ @@ -480,13 +480,13 @@ static REG16 MEMCALL i286w_rd(UINT32 address) { BYTE *ptr; - ptr = mem + (address & i286core.s.adrsmask); + ptr = mem + (address & CPU_ADRSMASK); return(LOADINTELWORD(ptr)); } static REG16 MEMCALL tramw_rd(UINT32 address) { - I286_REMCLOCK -= vramop.tramwait; + CPU_REMCLOCK -= vramop.tramwait; if (address < (0xa4000 - 1)) { return(LOADINTELWORD(mem + address)); } @@ -515,13 +515,13 @@ static REG16 MEMCALL tramw_rd(UINT32 address) { static REG16 MEMCALL vramw_r0(UINT32 address) { - I286_REMCLOCK -= vramop.vramwait; + CPU_REMCLOCK -= vramop.vramwait; return(LOADINTELWORD(mem + address)); } static REG16 MEMCALL vramw_r1(UINT32 address) { - I286_REMCLOCK -= vramop.vramwait; + CPU_REMCLOCK -= vramop.vramwait; return(LOADINTELWORD(mem + address + VRAM_STEP)); } @@ -530,7 +530,7 @@ static REG16 MEMCALL grcgw_tcr0(UINT32 address) { BYTE *vram; REG16 ret; - I286_REMCLOCK -= vramop.grcgwait; + CPU_REMCLOCK -= vramop.grcgwait; ret = 0; vram = mem + LOW15(address); if (!(grcg.modereg & 1)) { @@ -553,7 +553,7 @@ static REG16 MEMCALL grcgw_tcr1(UINT32 address) { BYTE *vram; REG16 ret; - I286_REMCLOCK -= vramop.grcgwait; + CPU_REMCLOCK -= vramop.grcgwait; ret = 0; vram = mem + LOW15(address); if (!(grcg.modereg & 1)) { @@ -610,7 +610,7 @@ const BYTE *ptr; static REG16 MEMCALL i286w_itf(UINT32 address) { - if (i286core.s.itfbank) { + if (CPU_ITFBANK) { address = ITF_ADRS + LOW15(address); } return(LOADINTELWORD(mem + address)); @@ -743,8 +743,8 @@ static REG8 MEMCALL _i286_memoryread(UINT32 address) { #if defined(USE_HIMEM) else if (address >= 0x10fff0) { address -= 0x100000; - if (address < extmemmng_size) { - return(extmemmng_ptr[address]); + if (address < CPU_EXTMEMSIZE) { + return(CPU_EXTMEM[address]); } else { return(0xff); @@ -769,15 +769,15 @@ static REG16 MEMCALL _i286_memoryread_w(UINT32 address) { if (address == (0x00fff0 - 1)) { ret = mem[0x100000 + address]; } - else if (address < extmemmng_size) { - ret = extmemmng_ptr[address]; + else if (address < CPU_EXTMEMSIZE) { + ret = CPU_EXTMEM[address]; } else { ret = 0xff; } address++; - if (address < extmemmng_size) { - ret += extmemmng_ptr[address] << 8; + if (address < CPU_EXTMEMSIZE) { + ret += CPU_EXTMEM[address] << 8; } else { ret += 0xff00; @@ -826,8 +826,8 @@ REG8 MEMCALL i286_memoryread(UINT32 address) { #if defined(USE_HIMEM) else if (address >= 0x10fff0) { address -= 0x100000; - if (address < extmemmng_size) { - return(extmemmng_ptr[address]); + if (address < CPU_EXTMEMSIZE) { + return(CPU_EXTMEM[address]); } else { return(0xff); @@ -852,15 +852,15 @@ REG16 MEMCALL i286_memoryread_w(UINT32 address) { if (address == (0x00fff0 - 1)) { ret = mem[0x100000 + address]; } - else if (address < extmemmng_size) { - ret = extmemmng_ptr[address]; + else if (address < CPU_EXTMEMSIZE) { + ret = CPU_EXTMEM[address]; } else { ret = 0xff; } address++; - if (address < extmemmng_size) { - ret += extmemmng_ptr[address] << 8; + if (address < CPU_EXTMEMSIZE) { + ret += CPU_EXTMEM[address] << 8; } else { ret += 0xff00; @@ -888,8 +888,8 @@ void MEMCALL i286_memorywrite(UINT32 address, REG8 value) { #if defined(USE_HIMEM) else if (address >= 0x10fff0) { address -= 0x100000; - if (address < extmemmng_size) { - extmemmng_ptr[address] = (BYTE)value; + if (address < CPU_EXTMEMSIZE) { + CPU_EXTMEM[address] = (BYTE)value; } } #endif @@ -909,12 +909,12 @@ void MEMCALL i286_memorywrite_w(UINT32 address, REG16 value) { if (address == (0x00fff0 - 1)) { mem[address] = (BYTE)value; } - else if (address < extmemmng_size) { - extmemmng_ptr[address] = (BYTE)value; + else if (address < CPU_EXTMEMSIZE) { + CPU_EXTMEM[address] = (BYTE)value; } address++; - if (address < extmemmng_size) { - extmemmng_ptr[address] = (BYTE)(value >> 8); + if (address < CPU_EXTMEMSIZE) { + CPU_EXTMEM[address] = (BYTE)(value >> 8); } } #endif diff --git a/i286c/v30patch.c b/i286c/v30patch.c index 63961e1a..d9e54910 100644 --- a/i286c/v30patch.c +++ b/i286c/v30patch.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286c.h" #include "v30patch.h" #include "memory.h" @@ -97,13 +97,13 @@ I286FN v30segprefix_es(void) { // 26: es: SS_FIX = ES_BASE; DS_FIX = ES_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -114,13 +114,13 @@ I286FN v30segprefix_cs(void) { // 2e: cs: SS_FIX = CS_BASE; DS_FIX = CS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -131,13 +131,13 @@ I286FN v30segprefix_ss(void) { // 36: ss: SS_FIX = SS_BASE; DS_FIX = SS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -148,13 +148,13 @@ I286FN v30segprefix_ds(void) { // 3e: ds: SS_FIX = DS_BASE; DS_FIX = DS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -413,12 +413,12 @@ I286FN v30_xlat(void) { // D6: xlat I286FN v30_repne(void) { // F2: repne - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repne[op](); - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -427,12 +427,12 @@ I286FN v30_repne(void) { // F2: repne I286FN v30_repe(void) { // F3: repe - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repe[op](); - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -472,13 +472,13 @@ I286FN v30repe_segprefix_es(void) { DS_FIX = ES_BASE; SS_FIX = ES_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repe[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -489,13 +489,13 @@ I286FN v30repe_segprefix_cs(void) { DS_FIX = CS_BASE; SS_FIX = CS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repe[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -506,13 +506,13 @@ I286FN v30repe_segprefix_ss(void) { DS_FIX = SS_BASE; SS_FIX = SS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repe[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -523,13 +523,13 @@ I286FN v30repe_segprefix_ds(void) { DS_FIX = DS_BASE; SS_FIX = DS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repe[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -569,13 +569,13 @@ I286FN v30repne_segprefix_es(void) { DS_FIX = ES_BASE; SS_FIX = ES_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repne[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -586,13 +586,13 @@ I286FN v30repne_segprefix_cs(void) { DS_FIX = CS_BASE; SS_FIX = CS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repne[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -603,13 +603,13 @@ I286FN v30repne_segprefix_ss(void) { DS_FIX = SS_BASE; SS_FIX = SS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repne[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -620,13 +620,13 @@ I286FN v30repne_segprefix_ds(void) { DS_FIX = DS_BASE; SS_FIX = DS_BASE; - i286core.s.prefix++; - if (i286core.s.prefix < MAX_PREFIX) { + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { UINT op; GET_PCBYTE(op); v30op_repne[op](); REMOVE_PREFIX - i286core.s.prefix = 0; + I286_PREFIX = 0; } else { INT_NUM(6, I286_IP); @@ -672,7 +672,7 @@ static void v30patching(void (*op[])(void), const V30PATCH *patch, int cnt) { #define V30PATCHING(a, b) v30patching(a, b, sizeof(b)/sizeof(V30PATCH)) -void v30init(void) { +void v30cinit(void) { CopyMemory(v30op, i286op, sizeof(v30op)); V30PATCHING(v30op, v30patch_op); @@ -682,7 +682,7 @@ void v30init(void) { V30PATCHING(v30op_repe, v30patch_repe); } -void v30(void) { +void v30c(void) { UINT opcode; @@ -691,7 +691,7 @@ void v30(void) { GET_PCBYTE(opcode); v30op[opcode](); if (I286_TRAP) { - i286_interrupt(1); + i286c_interrupt(1); } dmap_v30(); } while(I286_REMCLOCK > 0); @@ -711,7 +711,7 @@ void v30(void) { } } -void v30_step(void) { +void v30c_step(void) { UINT opcode; diff --git a/i286c/v30patch.h b/i286c/v30patch.h index 727546d6..48707c02 100644 --- a/i286c/v30patch.h +++ b/i286c/v30patch.h @@ -1,3 +1,3 @@ -void v30init(void); +void v30cinit(void); diff --git a/i286x/i286.h b/i286x/cpucore.h similarity index 52% rename from i286x/i286.h rename to i286x/cpucore.h index a5ae18c6..54768687 100644 --- a/i286x/i286.h +++ b/i286x/cpucore.h @@ -1,8 +1,8 @@ //---------------------------------------------------------------------------- // -// i286c : 80286 Engine for Pentium ver0.02 +// i286x : 80286 Engine for Pentium ver0.05 // -// Copyright by Yui/Studio Milmake 1999-2000 +// Copyright by Yui/Studio Milmake 1999-2003 // //---------------------------------------------------------------------------- @@ -18,6 +18,22 @@ enum { }; #endif +enum { + C_FLAG = 0x0001, + P_FLAG = 0x0004, + A_FLAG = 0x0010, + Z_FLAG = 0x0040, + S_FLAG = 0x0080, + T_FLAG = 0x0100, + I_FLAG = 0x0200, + D_FLAG = 0x0400, + O_FLAG = 0x0800 +}; + +enum { + CPUTYPE_V30 = 0x01 +}; + #ifndef CPUCALL #define CPUCALL __fastcall #endif @@ -144,7 +160,8 @@ typedef struct { } I286STAT; typedef struct { // for ver0.73 - UINT dummy; + BYTE *ext; + UINT32 extsize; } I286EXT; typedef struct { @@ -158,96 +175,84 @@ extern "C" { #endif extern I286CORE i286core; -extern const BYTE iflags[]; - - -#define I286_MEM mem - -#define I286_REG i286core.s.r -#define I286_SEGREG i286core.s.r.w.es - -#define I286_AX i286core.s.r.w.ax -#define I286_BX i286core.s.r.w.bx -#define I286_CX i286core.s.r.w.cx -#define I286_DX i286core.s.r.w.dx -#define I286_SI i286core.s.r.w.si -#define I286_DI i286core.s.r.w.di -#define I286_BP i286core.s.r.w.bp -#define I286_SP i286core.s.r.w.sp -#define I286_CS i286core.s.r.w.cs -#define I286_DS i286core.s.r.w.ds -#define I286_ES i286core.s.r.w.es -#define I286_SS i286core.s.r.w.ss -#define I286_IP i286core.s.r.w.ip - -#define SEG_BASE i286core.s.es_base -#define ES_BASE i286core.s.es_base -#define CS_BASE i286core.s.cs_base -#define SS_BASE i286core.s.ss_base -#define DS_BASE i286core.s.ds_base -#define SS_FIX i286core.s.ss_fix -#define DS_FIX i286core.s.ds_fix - -#define I286_AL i286core.s.r.b.al -#define I286_BL i286core.s.r.b.bl -#define I286_CL i286core.s.r.b.cl -#define I286_DL i286core.s.r.b.dl -#define I286_AH i286core.s.r.b.ah -#define I286_BH i286core.s.r.b.bh -#define I286_CH i286core.s.r.b.ch -#define I286_DH i286core.s.r.b.dh - -#define I286_FLAG i286core.s.r.w.flag -#define I286_FLAGL i286core.s.r.b.flag_l -#define I286_FLAGH i286core.s.r.b.flag_h -#define I286_TRAP i286core.s.trap -#define I286_OV i286core.s.ovflag - -#define I286_REMCLOCK i286core.s.remainclock -#define I286_BASECLOCK i286core.s.baseclock -#define I286_CLOCK i286core.s.clock - - -enum { - C_FLAG = 0x0001, - P_FLAG = 0x0004, - A_FLAG = 0x0010, - Z_FLAG = 0x0040, - S_FLAG = 0x0080, - T_FLAG = 0x0100, - I_FLAG = 0x0200, - D_FLAG = 0x0400, - O_FLAG = 0x0800 -}; - -#define CPUTYPE i286core.s.cpu_type -#define CPUTYPE_V30 0x01 - -// ver0.28 -#define REPPOSBAK i286core.s.repbak -#define PREFIX_SMP i286core.s.pf_semaphore +extern const UINT8 iflags[]; -#define isI286DI (!(I286_FLAG & I_FLAG)) -#define isI286EI (I286_FLAG & I_FLAG) -#define I286_CLI I286_FLAG &= ~I_FLAG; \ - I286_TRAP = 0; -#define I286_STI I286_FLAG |= I_FLAG; \ - I286_TRAP = (I286_FLAG >> 8) & 1; +void i286x_initialize(void); +void i286x_reset(void); +void i286x_resetprefetch(void); +void CPUCALL i286x_interrupt(BYTE vect); -void i286_initialize(void); -void i286_reset(void); -void i286_resetprefetch(void); +void i286x(void); +void i286x_step(void); -void CPUCALL i286_interrupt(BYTE vect); - -void i286(void); -void i286_step(void); - -void v30(void); -void v30_step(void); +void v30x(void); +void v30x_step(void); #ifdef __cplusplus } #endif + +// ---- macros + +#define CPU_STATSAVE i286core.s + +#define CPU_AX i286core.s.r.w.ax +#define CPU_BX i286core.s.r.w.bx +#define CPU_CX i286core.s.r.w.cx +#define CPU_DX i286core.s.r.w.dx +#define CPU_SI i286core.s.r.w.si +#define CPU_DI i286core.s.r.w.di +#define CPU_BP i286core.s.r.w.bp +#define CPU_SP i286core.s.r.w.sp +#define CPU_CS i286core.s.r.w.cs +#define CPU_DS i286core.s.r.w.ds +#define CPU_ES i286core.s.r.w.es +#define CPU_SS i286core.s.r.w.ss +#define CPU_IP i286core.s.r.w.ip + +#define ES_BASE i286core.s.es_base +#define CS_BASE i286core.s.cs_base +#define SS_BASE i286core.s.ss_base +#define DS_BASE i286core.s.ds_base + +#define CPU_AL i286core.s.r.b.al +#define CPU_BL i286core.s.r.b.bl +#define CPU_CL i286core.s.r.b.cl +#define CPU_DL i286core.s.r.b.dl +#define CPU_AH i286core.s.r.b.ah +#define CPU_BH i286core.s.r.b.bh +#define CPU_CH i286core.s.r.b.ch +#define CPU_DH i286core.s.r.b.dh + +#define CPU_FLAG i286core.s.r.w.flag +#define CPU_FLAGL i286core.s.r.b.flag_l + +#define CPU_REMCLOCK i286core.s.remainclock +#define CPU_BASECLOCK i286core.s.baseclock +#define CPU_CLOCK i286core.s.clock +#define CPU_ADRSMASK i286core.s.adrsmask +#define CPU_RESETREQ i286core.s.resetreq +#define CPU_ITFBANK i286core.s.itfbank +#define CPU_INPADRS i286core.s.inport + +#define CPU_EXTMEM i286core.e.ext +#define CPU_EXTMEMSIZE i286core.e.extsize + +#define CPU_TYPE i286core.s.cpu_type + +#define CPU_isDI (!(i286core.s.r.w.flag & I_FLAG)) +#define CPU_isEI (i286core.s.r.w.flag & I_FLAG) +#define CPU_CLI i286core.s.r.w.flag &= ~I_FLAG; \ + i286core.s.trap = 0; +#define CPU_STI i286core.s.r.w.flag |= I_FLAG; \ + i286core.s.trap = (i286core.s.r.w.flag >> 8) & 1; + +#define CPU_INITIALIZE i286x_initialize +#define CPU_RESET i286x_reset +#define CPU_CLEARPREFETCH i286x_resetprefetch +#define CPU_INTERRUPT(v) i286x_interrupt(v) +#define CPU_EXEC i286x +#define CPU_EXECV30 v30x + diff --git a/i286x/i286x.cpp b/i286x/i286x.cpp index fc39ea32..9a06400e 100644 --- a/i286x/i286x.cpp +++ b/i286x/i286x.cpp @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286x.h" #include "i286xadr.h" #include "i286xs.h" @@ -52,13 +52,13 @@ const BYTE iflags[256] = { // Z_FLAG, S_FLAG, P_FLAG 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84}; -void i286_initialize(void) { +void i286x_initialize(void) { i286xadr_init(); - v30init(); + v30xinit(); } -void i286_reset(void) { +void i286x_reset(void) { ZeroMemory(&i286core.s, sizeof(i286core.s)); I286_CS = 0x1fc0; @@ -67,7 +67,7 @@ void i286_reset(void) { } -LABEL void i286_resetprefetch(void) { +LABEL void i286x_resetprefetch(void) { __asm { pushad @@ -79,7 +79,7 @@ LABEL void i286_resetprefetch(void) { } } -LABEL void __fastcall i286_interrupt(BYTE vect) { +LABEL void __fastcall i286x_interrupt(BYTE vect) { __asm { pushad @@ -169,7 +169,7 @@ LABEL void __fastcall i286x_localint(void) { -LABEL void i286(void) { +LABEL void i286x(void) { __asm { pushad @@ -217,7 +217,7 @@ i286notrap: mov dword ptr (i286core.s.prefetchque), ebx -LABEL void i286_step(void) { +LABEL void i286x_step(void) { __asm { pushad diff --git a/i286x/i286x.h b/i286x/i286x.h index 7bc85497..8e2f90fe 100644 --- a/i286x/i286x.h +++ b/i286x/i286x.h @@ -1,4 +1,63 @@ +#define I286_MEM mem + +#define I286_STAT i286core.s.r + +#define I286_REG i286core.s.r +#define I286_SEGREG i286core.s.r.w.es + +#define I286_AX i286core.s.r.w.ax +#define I286_BX i286core.s.r.w.bx +#define I286_CX i286core.s.r.w.cx +#define I286_DX i286core.s.r.w.dx +#define I286_SI i286core.s.r.w.si +#define I286_DI i286core.s.r.w.di +#define I286_BP i286core.s.r.w.bp +#define I286_SP i286core.s.r.w.sp +#define I286_CS i286core.s.r.w.cs +#define I286_DS i286core.s.r.w.ds +#define I286_ES i286core.s.r.w.es +#define I286_SS i286core.s.r.w.ss +#define I286_IP i286core.s.r.w.ip + +#define SEG_BASE i286core.s.es_base +#define ES_BASE i286core.s.es_base +#define CS_BASE i286core.s.cs_base +#define SS_BASE i286core.s.ss_base +#define DS_BASE i286core.s.ds_base +#define SS_FIX i286core.s.ss_fix +#define DS_FIX i286core.s.ds_fix + +#define I286_AL i286core.s.r.b.al +#define I286_BL i286core.s.r.b.bl +#define I286_CL i286core.s.r.b.cl +#define I286_DL i286core.s.r.b.dl +#define I286_AH i286core.s.r.b.ah +#define I286_BH i286core.s.r.b.bh +#define I286_CH i286core.s.r.b.ch +#define I286_DH i286core.s.r.b.dh + +#define I286_FLAG i286core.s.r.w.flag +#define I286_FLAGL i286core.s.r.b.flag_l +#define I286_FLAGH i286core.s.r.b.flag_h +#define I286_TRAP i286core.s.trap +#define I286_OV i286core.s.ovflag + +#define I286_GDTR i286core.s.GDTR +#define I286_IDTR i286core.s.IDTR +#define I286_MSW i286core.s.MSW + +#define I286_REMCLOCK i286core.s.remainclock +#define I286_BASECLOCK i286core.s.baseclock +#define I286_CLOCK i286core.s.clock +#define I286_ADRSMASK i286core.s.adrsmask +#define I286_INPADRS i286core.s.inport + +// ver0.28 +#define REPPOSBAK i286core.s.repbak +#define PREFIX_SMP i286core.s.pf_semaphore + + #define I286 __declspec(naked) static void #define I286EXT __declspec(naked) void diff --git a/i286x/i286xadr.cpp b/i286x/i286xadr.cpp index 7aa8792b..8ad616d1 100644 --- a/i286x/i286xadr.cpp +++ b/i286x/i286xadr.cpp @@ -1,5 +1,6 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" +#include "i286x.h" #include "memory.h" #include "i286x.mcr" #include "i286xea.mcr" diff --git a/i286x/i286xcts.cpp b/i286x/i286xcts.cpp index 5a24a9c9..1c2aafbd 100644 --- a/i286x/i286xcts.cpp +++ b/i286x/i286xcts.cpp @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286x.h" #include "i286xadr.h" #include "i286xcts.h" diff --git a/i286x/i286xrep.cpp b/i286x/i286xrep.cpp index 2a0a9164..fa055b85 100644 --- a/i286x/i286xrep.cpp +++ b/i286x/i286xrep.cpp @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286x.h" #include "i286xs.h" #include "i286xrep.h" diff --git a/i286x/i286xs.cpp b/i286x/i286xs.cpp index f5ef5f7d..9a373021 100644 --- a/i286x/i286xs.cpp +++ b/i286x/i286xs.cpp @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286x.h" #include "i286xadr.h" #include "memory.h" diff --git a/i286x/memory.x86 b/i286x/memory.x86 index 3aae434e..b3f9e45a 100644 --- a/i286x/memory.x86 +++ b/i286x/memory.x86 @@ -17,15 +17,14 @@ section .bss ; extern ___font extern _vramop - extern _extmemmng_ptr - extern _extmemmng_size - MAINMEMORY equ _mem EXTMEMORY equ 0 VIDEOMEMORY equ _mem USERSMEMORY_R equ 0a8000h USERSMEMORY_W equ 0a0000h +_extmemmng_ptr equ _i286core + i286core_t.ext +_extmemmng_size equ _i286core + i286core_t.extsize %if 1 _font equ _mem + FONT_ADRS @@ -98,7 +97,7 @@ section .text ; normal memory align 16 @i286_wt: mov ebx, ecx - and ebx, [_i286core + i286stat_t.adrsmask] + and ebx, [_i286core + i286core_t.adrsmask] mov [MAINMEMORY + ebx], dl pop ebx ret @@ -106,7 +105,7 @@ section .text ; tram write align 16 @tram_wt: mov ebx, [_vramop + vramop_t.tramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx mov ebx, ecx cmp ecx, 000a2000h jnc short wtram_a @@ -155,7 +154,7 @@ wcgwindow_e: pop ebx or byte [_vramupdate + ebx], 1 or byte [_gdcs + gdcs_t.grphdisp], 1 mov ebx, [_vramop + vramop_t.vramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx pop ebx ret @@ -167,7 +166,7 @@ wcgwindow_e: pop ebx or byte [_vramupdate + ebx], 2 or byte [_gdcs + gdcs_t.grphdisp], 2 mov ebx, [_vramop + vramop_t.vramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx pop ebx ret @@ -188,7 +187,7 @@ wcgwindow_e: pop ebx or byte [_gdcs + gdcs_t.grphdisp], 1 grcg_rmw: mov ebx, [_vramop + vramop_t.grcgwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx mov ebx, dword [_grcg + grcg_t.mode] mov bl, dl not bl @@ -237,7 +236,7 @@ grcgrmw_end: pop ecx or byte [_gdcs + gdcs_t.grphdisp], 1 grcg_tdw: mov ebx, [_vramop + vramop_t.grcgwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx mov bh, [_grcg + grcg_t.modereg] shr bh, 1 jc short grcgtdw_r @@ -296,7 +295,7 @@ grcgtdw_end: pop ecx ; normal memory align 16 @i286_rd: mov ebx, ecx - and ebx, [_i286core + i286stat_t.adrsmask] + and ebx, [_i286core + i286core_t.adrsmask] mov al, [MAINMEMORY + ebx] pop ebx ret @@ -304,7 +303,7 @@ grcgtdw_end: pop ecx ; font cg-window align 16 @tram_rd: mov ebx, [_vramop + vramop_t.tramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx cmp ecx, 0a4000h jnc rcgwindow_s rcgwindow_n: mov al, [MAINMEMORY + ecx] @@ -327,7 +326,7 @@ rcgwindow_s: cmp ecx, 0a5000h align 16 @vram_r0: mov al, [VIDEOMEMORY + ecx] mov ebx, [_vramop + vramop_t.vramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx pop ebx ret @@ -335,7 +334,7 @@ rcgwindow_s: cmp ecx, 0a5000h align 16 @vram_r1: mov al, [VIDEOMEMORY + VRAM_STEP + ecx] mov ebx, [_vramop + vramop_t.vramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx pop ebx ret @@ -350,7 +349,7 @@ rcgwindow_s: cmp ecx, 0a5000h and ecx, 7fffh grcg_tcr: mov ebx, [_vramop + vramop_t.grcgwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx mov al, 0 mov bh, [_grcg + grcg_t.modereg] shr bh, 1 @@ -406,7 +405,7 @@ grcgtcr_end: not al ; BIOS or ITF align 16 -@i286_itf: cmp byte [_i286core + i286stat_t.itfbank], 0 +@i286_itf: cmp byte [_i286core + i286core_t.itfbank], 0 jne readmem_itr mov al, [MAINMEMORY + ecx] pop ebx @@ -423,7 +422,7 @@ readmem_itr: mov ebx, ecx ; normal memory align 16 @i286w_wt: mov ebx, ecx - and ebx, [_i286core + i286stat_t.adrsmask] + and ebx, [_i286core + i286core_t.adrsmask] mov [MAINMEMORY + ebx], dx pop ebx ret @@ -431,7 +430,7 @@ readmem_itr: mov ebx, ecx ; tram write align 16 @tramw_wt: mov ebx, [_vramop + vramop_t.tramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx mov ebx, ecx cmp ecx, 000a1fffh jnc short wtramw_a @@ -506,7 +505,7 @@ wcgwinw_odd: add ebx, dword [_cgwindow + cgwin_t.high] or word [_vramupdate + ebx], 0101h or byte [_gdcs + gdcs_t.grphdisp], 1 mov ebx, [_vramop + vramop_t.vramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx pop ebx ret @@ -518,7 +517,7 @@ wcgwinw_odd: add ebx, dword [_cgwindow + cgwin_t.high] or word [_vramupdate + ebx], 0202h or byte [_gdcs + gdcs_t.grphdisp], 2 mov ebx, [_vramop + vramop_t.vramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx pop ebx ret @@ -539,7 +538,7 @@ wcgwinw_odd: add ebx, dword [_cgwindow + cgwin_t.high] or byte [_gdcs + gdcs_t.grphdisp], 1 grcgw_rmw: mov ebx, [_vramop + vramop_t.grcgwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx push eax mov ebx, dword [_grcg + grcg_t.mode] mov bx, dx @@ -590,7 +589,7 @@ grcgwrmw_end: pop eax or byte [_gdcs + gdcs_t.grphdisp], 1 grcgw_tdw: mov ebx, [_vramop + vramop_t.grcgwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx mov ebx, [_grcg + grcg_t.mode] test ebx, 010000h jne short grcgwtdw_r @@ -657,7 +656,7 @@ egcw_wtodd: ; normal memory align 16 @i286w_rd: mov ebx, ecx - and ebx, [_i286core + i286stat_t.adrsmask] + and ebx, [_i286core + i286core_t.adrsmask] mov ax, [MAINMEMORY + ebx] pop ebx ret @@ -665,7 +664,7 @@ egcw_wtodd: ; font cg-window align 16 @tramw_rd: mov ebx, [_vramop + vramop_t.tramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx cmp ecx, 0a3fffh jnc rcgwwindow_s mov ax, [MAINMEMORY + ecx] @@ -719,7 +718,7 @@ rcgwwindow_a4fff: mov ebx, dword [_cgwindow + cgwin_t.high] align 16 @vramw_r0: mov ax, [VIDEOMEMORY + ecx] mov ebx, [_vramop + vramop_t.vramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx pop ebx ret @@ -727,7 +726,7 @@ rcgwwindow_a4fff: mov ebx, dword [_cgwindow + cgwin_t.high] align 16 @vramw_r1: mov ax, [VIDEOMEMORY + VRAM_STEP + ecx] mov ebx, [_vramop + vramop_t.vramwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx pop ebx ret @@ -742,7 +741,7 @@ rcgwwindow_a4fff: mov ebx, dword [_cgwindow + cgwin_t.high] and ecx, 7fffh grcgw_tcr: mov ebx, [_vramop + vramop_t.grcgwait] - sub [_i286core + i286stat_t.remainclock], ebx + sub [_i286core + i286core_t.remainclock], ebx mov ax, 0 mov ebx, [_grcg + grcg_t.mode] test ebx, 010000h @@ -819,7 +818,7 @@ egcw_rdodd: ; BIOS or ITF align 16 -@i286w_itf: cmp byte [_i286core + i286stat_t.itfbank], 0 +@i286w_itf: cmp byte [_i286core + i286core_t.itfbank], 0 jne readwmem_itr mov ax, [MAINMEMORY + ecx] pop ebx diff --git a/i286x/v30patch.cpp b/i286x/v30patch.cpp index 19929dae..50d6ffcb 100644 --- a/i286x/v30patch.cpp +++ b/i286x/v30patch.cpp @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286x.h" #include "i286xadr.h" #include "i286xs.h" @@ -992,7 +992,7 @@ static void v30patching(void (*dst[])(void), V30PATCH_T *patch, int length) { #define V30PATCHING(a, b) v30patching(a, b, sizeof(b)/sizeof(V30PATCH_T)) -void v30init(void) { +void v30xinit(void) { CopyMemory(v30op, i286op, sizeof(v30op)); V30PATCHING(v30op, v30patch_op); @@ -1002,7 +1002,7 @@ void v30init(void) { V30PATCHING(v30op_repe, v30patch_repe); } -LABEL void v30(void) { +LABEL void v30x(void) { __asm { pushad @@ -1049,7 +1049,7 @@ v30notrap: mov dword ptr (i286core.s.prefetchque), ebx } } -LABEL void v30_step(void) { +LABEL void v30x_step(void) { __asm { pushad diff --git a/i286x/v30patch.h b/i286x/v30patch.h index ace41b53..d34c637f 100644 --- a/i286x/v30patch.h +++ b/i286x/v30patch.h @@ -1 +1,3 @@ -void v30init(void); + +void v30xinit(void); + diff --git a/i386c/cpucore.c b/i386c/cpucore.c new file mode 100644 index 00000000..13649fb7 --- /dev/null +++ b/i386c/cpucore.c @@ -0,0 +1,53 @@ +/* $Id: cpucore.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +#include "compiler.h" +#include "cpucore.h" + + + BYTE szpcflag[0x200]; + BYTE szpflag_w[0x10000]; + + +void i386c_initialize(void) { + + DWORD i; + DWORD bit; + BYTE f; + + for (i=0; i<0x100; i++) { + f = P_FLAG; + for (bit=0x80; bit; bit>>=1) { + if (i & bit) { + f ^= P_FLAG; + } + } + if (!(i & 0xff)) { + f |= Z_FLAG; + } + if (i & 0x80) { + f |= S_FLAG; + } + szpcflag[i+0x000] = f; + szpcflag[i+0x100] = f | C_FLAG; + } + + for (i=0; i<0x10000; i++) { + f = P_FLAG; + for (bit=0x80; bit; bit>>=1) { + if (i & bit) { + f ^= P_FLAG; + } + } + if (!i) { + f |= Z_FLAG; + } + if (i & 0x8000) { + f |= S_FLAG; + } + szpflag_w[i] = f; + } + +// #if (defined(I286_C) || defined(I286_ASM_C)) + ia32_init(); +// #endif +} diff --git a/i386c/cpucore.h b/i386c/cpucore.h new file mode 100644 index 00000000..b5ae4fea --- /dev/null +++ b/i386c/cpucore.h @@ -0,0 +1,15 @@ +/* $Id: cpucore.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +#ifndef NP2_I386C_CPUCORE_H__ +#define NP2_I386C_CPUCORE_H__ + +#define I286_MEMREADMAX 0xa4000 +#define I286_MEMWRITEMAX 0xa0000 + +#if defined(CPU386) +#include "ia32/cpu.h" +#else /* !CPU386 */ +#include "i286/cpu.h" +#endif /* CPU386 */ + +#endif /* !NP2_I386C_CPUCORE_H__ */ diff --git a/i386c/dmap.c b/i386c/dmap.c new file mode 100644 index 00000000..a008cb71 --- /dev/null +++ b/i386c/dmap.c @@ -0,0 +1,85 @@ +#include "compiler.h" +#include "memory.h" +#include "pccore.h" +#include "iocore.h" +#include "dmap.h" + + +void dmap_i286(void) { + + DMACH ch; + int bit; + + if (dmac.working) { + ch = dmac.dmach; + bit = 1; + do { + if (dmac.working & bit) { + // DMA working ! + if (!ch->leng.w) { + dmac.stat |= bit; + dmac.working &= ~bit; + ch->extproc(DMAEXT_END); + } + ch->leng.w--; + + switch(ch->mode & 0x0c) { + case 0x00: // verifty + ch->inproc(); + break; + + case 0x04: // port->mem + i286_memorywrite(ch->adrs.d, ch->inproc()); + break; + + default: + ch->outproc(i286_memoryread(ch->adrs.d)); + break; + } + ch->adrs.d += ((ch->mode & 0x20)?-1:1); + } + ch++; + bit <<= 1; + } while(bit & 0x0f); + } +} + +void dmap_v30(void) { + + DMACH ch; + int bit; + + if (dmac.working) { + ch = dmac.dmach; + bit = 1; + do { + if (dmac.working & bit) { + // DMA working ! + if (!ch->leng.w) { + dmac.stat |= bit; + dmac.working &= ~bit; + ch->extproc(DMAEXT_END); + } + ch->leng.w--; + + switch(ch->mode & 0x0c) { + case 0x00: // verifty + ch->inproc(); + break; + + case 0x04: // port->mem + i286_memorywrite(ch->adrs.d, ch->inproc()); + break; + + default: + ch->outproc(i286_memoryread(ch->adrs.d)); + break; + } + ch->adrs.w[DMA16_LOW] += ((ch->mode & 0x20)?-1:1); + } + ch++; + bit <<= 1; + } while(bit & 0x0f); + } +} + diff --git a/i386c/dmap.h b/i386c/dmap.h new file mode 100644 index 00000000..cb89e62d --- /dev/null +++ b/i386c/dmap.h @@ -0,0 +1,12 @@ + +#ifdef __cplusplus +extern "C" { +#endif + +void dmap_i286(void); +void dmap_v30(void); + +#ifdef __cplusplus +} +#endif + diff --git a/i386c/egcmem.c b/i386c/egcmem.c new file mode 100644 index 00000000..45317fea --- /dev/null +++ b/i386c/egcmem.c @@ -0,0 +1,1030 @@ +#include "compiler.h" +#include "memory.h" +#include "egcmem.h" +#include "pccore.h" +#include "iocore.h" +#include "vram.h" + + +// C版EGCのみ ROPの回数を記録する +// #define LOG_EGCROP + + +enum { + EGCADDR_L = 0, + EGCADDR_H = 1 +}; +#define EGCADDR(a) (a) + + + +static EGCQUAD egc_src; +static EGCQUAD data; + +static const UINT planead[4] = {VRAM_B, VRAM_R, VRAM_G, VRAM_E}; + + +static const BYTE bytemask_u0[64] = // dir:right by startbit + (len-1)*8 + {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01, + 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x03, 0x01, + 0xf0, 0x78, 0x3c, 0x1e, 0x0f, 0x07, 0x03, 0x01, + 0xf8, 0x7c, 0x3e, 0x1f, 0x0f, 0x07, 0x03, 0x01, + 0xfc, 0x7e, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, + 0xfe, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, + 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01}; + +static const BYTE bytemask_u1[8] = // dir:right by length + {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; + +static const BYTE bytemask_d0[64] = // dir:left by startbit + (len-1)*8 + {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, + 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc0, 0x80, + 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0xe0, 0xc0, 0x80, + 0x1f, 0x3e, 0x7c, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, + 0x3f, 0x7e, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, + 0x7f, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, + 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; + +static const BYTE bytemask_d1[8] = // dir:left by length + {0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; + +#ifdef LOG_EGCROP +static int egcropcnt[256]; +#endif + + +void egcshift(void) { + + BYTE src8, dst8; + + egc.remain = LOW12(egc.leng) + 1; + egc.func = (egc.sft >> 12) & 1; + if (!egc.func) { + egc.inptr = egc.buf; + egc.outptr = egc.buf; + } + else { + egc.inptr = egc.buf + 4096/8 + 3; + egc.outptr = egc.buf + 4096/8 + 3; + } + egc.srcbit = egc.sft & 0x0f; + egc.dstbit = (egc.sft >> 4) & 0x0f; + + src8 = egc.srcbit & 0x07; + dst8 = egc.dstbit & 0x07; + if (src8 < dst8) { + +// dir:inc +// ****---4 -------8 -------- +// ******-- -4------ --8----- -- +// 1st -> data[0] >> (dst - src) +// 2nd -> (data[0] << (8 - (dst - src))) | (data[1] >> (dst - src)) + +// dir:dec +// -------- 8------- 6-----** +// --- -----8-- -----6-- ---***** +// 1st -> data[0] << (dst - src) +// 2nd -> (data[0] >> (8 - (dst - src))) | (data[1] << (dst - src)) + + egc.func += 2; + egc.sft8bitr = dst8 - src8; + egc.sft8bitl = 8 - egc.sft8bitr; + } + else if (src8 > dst8) { + +// dir:inc +// ****---4 -------8 -------- +// **---4-- -----8-- ------ +// 1st -> (data[0] << (src - dst)) | (data[1] >> (8 - (src - dst)) +// 2nd -> (data[0] << (src - dst)) | (data[1] >> (8 - (src - dst)) + +// dir:dec +// -------- 8------- 3--***** +// ----- ---8---- ---3--** +// 1st -> (data[0] >> (dst - src)) | (data[-1] << (8 - (src - dst)) +// 2nd -> (data[0] >> (dst - src)) | (data[-1] << (8 - (src - dst)) + + egc.func += 4; + egc.sft8bitl = src8 - dst8; + egc.sft8bitr = 8 - egc.sft8bitl; + } + egc.stack = 0; +} + + +static void egcsftb_upn_sub(UINT ext) { + + if (egc.dstbit >= 8) { + egc.dstbit -= 8; + egc.srcmask._b[ext] = 0; + return; + } + if (egc.dstbit) { + if ((egc.dstbit + egc.remain) >= 8) { + egc.srcmask._b[ext] = bytemask_u0[egc.dstbit + (7*8)]; + egc.remain -= (8 - egc.dstbit); + egc.dstbit = 0; + } + else { + egc.srcmask._b[ext] = bytemask_u0[egc.dstbit + + (egc.remain - 1) * 8]; + egc.remain = 0; + egc.dstbit = 0; + } + } + else { + if (egc.remain >= 8) { + egc.remain -= 8; + } + else { + egc.srcmask._b[ext] = bytemask_u1[egc.remain - 1]; + egc.remain = 0; + } + } + egc_src._b[0][ext] = egc.outptr[0]; + egc_src._b[1][ext] = egc.outptr[4]; + egc_src._b[2][ext] = egc.outptr[8]; + egc_src._b[3][ext] = egc.outptr[12]; + egc.outptr++; +} + +static void egcsftb_dnn_sub(UINT ext) { + + if (egc.dstbit >= 8) { + egc.dstbit -= 8; + egc.srcmask._b[ext] = 0; + return; + } + if (egc.dstbit) { + if ((egc.dstbit + egc.remain) >= 8) { + egc.srcmask._b[ext] = bytemask_d0[egc.dstbit + (7*8)]; + egc.remain -= (8 - egc.dstbit); + egc.dstbit = 0; + } + else { + egc.srcmask._b[ext] = bytemask_d0[egc.dstbit + + (egc.remain - 1) * 8]; + egc.remain = 0; + egc.dstbit = 0; + } + } + else { + if (egc.remain >= 8) { + egc.remain -= 8; + } + else { + egc.srcmask._b[ext] = bytemask_d1[egc.remain - 1]; + egc.remain = 0; + } + } + egc_src._b[0][ext] = egc.outptr[0]; + egc_src._b[1][ext] = egc.outptr[4]; + egc_src._b[2][ext] = egc.outptr[8]; + egc_src._b[3][ext] = egc.outptr[12]; + egc.outptr--; +} + + +// ****---4 -------8 -------- +// ******-- -4------ --8----- -- +// 1st -> data[0] >> (dst - src) +// 2nd -> (data[0] << (8 - (dst - src))) | (data[1] >> (dst - src)) + +static void egcsftb_upr_sub(UINT ext) { + + if (egc.dstbit >= 8) { + egc.dstbit -= 8; + egc.srcmask._b[ext] = 0; + return; + } + if (egc.dstbit) { + if ((egc.dstbit + egc.remain) >= 8) { + egc.srcmask._b[ext] = bytemask_u0[egc.dstbit + (7*8)]; + egc.remain -= (8 - egc.dstbit); + } + else { + egc.srcmask._b[ext] = bytemask_u0[egc.dstbit + + (egc.remain - 1) * 8]; + egc.remain = 0; + } + egc.dstbit = 0; + egc_src._b[0][ext] = (egc.outptr[0] >> egc.sft8bitr); + egc_src._b[1][ext] = (egc.outptr[4] >> egc.sft8bitr); + egc_src._b[2][ext] = (egc.outptr[8] >> egc.sft8bitr); + egc_src._b[3][ext] = (egc.outptr[12] >> egc.sft8bitr); + } + else { + if (egc.remain >= 8) { + egc.remain -= 8; + } + else { + egc.srcmask._b[ext] = bytemask_u1[egc.remain - 1]; + egc.remain = 0; + } + egc_src._b[0][ext] = (egc.outptr[0] << egc.sft8bitl) | + (egc.outptr[1] >> egc.sft8bitr); + egc_src._b[1][ext] = (egc.outptr[4] << egc.sft8bitl) | + (egc.outptr[5] >> egc.sft8bitr); + egc_src._b[2][ext] = (egc.outptr[8] << egc.sft8bitl) | + (egc.outptr[9] >> egc.sft8bitr); + egc_src._b[3][ext] = (egc.outptr[12] << egc.sft8bitl) | + (egc.outptr[13] >> egc.sft8bitr); + egc.outptr++; + } +} + + +// -------- 8------- 6-----** +// --- -----8-- -----6-- ---***** +// 1st -> data[0] << (dst - src) +// 2nd -> (data[0] >> (8 - (dst - src))) | (data[-1] << (dst - src)) + +static void egcsftb_dnr_sub(UINT ext) { + + if (egc.dstbit >= 8) { + egc.dstbit -= 8; + egc.srcmask._b[ext] = 0; + return; + } + if (egc.dstbit) { + if ((egc.dstbit + egc.remain) >= 8) { + egc.srcmask._b[ext] = bytemask_d0[egc.dstbit + (7*8)]; + egc.remain -= (8 - egc.dstbit); + } + else { + egc.srcmask._b[ext] = bytemask_d0[egc.dstbit + + (egc.remain - 1) * 8]; + egc.remain = 0; + } + egc.dstbit = 0; + egc_src._b[0][ext] = (egc.outptr[0] << egc.sft8bitr); + egc_src._b[1][ext] = (egc.outptr[4] << egc.sft8bitr); + egc_src._b[2][ext] = (egc.outptr[8] << egc.sft8bitr); + egc_src._b[3][ext] = (egc.outptr[12] << egc.sft8bitr); + } + else { + if (egc.remain >= 8) { + egc.remain -= 8; + } + else { + egc.srcmask._b[ext] = bytemask_d1[egc.remain - 1]; + egc.remain = 0; + } + egc.outptr--; + egc_src._b[0][ext] = (egc.outptr[1] >> egc.sft8bitl) | + (egc.outptr[0] << egc.sft8bitr); + egc_src._b[1][ext] = (egc.outptr[5] >> egc.sft8bitl) | + (egc.outptr[4] << egc.sft8bitr); + egc_src._b[2][ext] = (egc.outptr[9] >> egc.sft8bitl) | + (egc.outptr[8] << egc.sft8bitr); + egc_src._b[3][ext] = (egc.outptr[13] >> egc.sft8bitl) | + (egc.outptr[12] << egc.sft8bitr); + } +} + + +// ****---4 -------8 -------- +// **---4-- -----8-- ------ +// 1st -> (data[0] << (src - dst)) | (data[1] >> (8 - (src - dst)) +// 2nd -> (data[0] << (src - dst)) | (data[1] >> (8 - (src - dst)) + +static void egcsftb_upl_sub(UINT ext) { + + if (egc.dstbit >= 8) { + egc.dstbit -= 8; + egc.srcmask._b[ext] = 0; + return; + } + if (egc.dstbit) { + if ((egc.dstbit + egc.remain) >= 8) { + egc.srcmask._b[ext] = bytemask_u0[egc.dstbit + (7*8)]; + egc.remain -= (8 - egc.dstbit); + egc.dstbit = 0; + } + else { + egc.srcmask._b[ext] = bytemask_u0[egc.dstbit + + (egc.remain - 1) * 8]; + egc.remain = 0; + egc.dstbit = 0; + } + } + else { + if (egc.remain >= 8) { + egc.remain -= 8; + } + else { + egc.srcmask._b[ext] = bytemask_u1[egc.remain - 1]; + egc.remain = 0; + } + } + egc_src._b[0][ext] = (egc.outptr[0] << egc.sft8bitl) | + (egc.outptr[1] >> egc.sft8bitr); + egc_src._b[1][ext] = (egc.outptr[4] << egc.sft8bitl) | + (egc.outptr[5] >> egc.sft8bitr); + egc_src._b[2][ext] = (egc.outptr[8] << egc.sft8bitl) | + (egc.outptr[9] >> egc.sft8bitr); + egc_src._b[3][ext] = (egc.outptr[12] << egc.sft8bitl) | + (egc.outptr[13] >> egc.sft8bitr); + egc.outptr++; +} + + +// -------- 8------- 3--***** +// ----- ---8---- ---3--** +// 1st -> (data[0] >> (dst - src)) | (data[-1] << (8 - (src - dst)) +// 2nd -> (data[0] >> (dst - src)) | (data[-1] << (8 - (src - dst)) + +static void egcsftb_dnl_sub(UINT ext) { + + if (egc.dstbit >= 8) { + egc.dstbit -= 8; + egc.srcmask._b[ext] = 0; + return; + } + if (egc.dstbit) { + if ((egc.dstbit + egc.remain) >= 8) { + egc.srcmask._b[ext] = bytemask_d0[egc.dstbit + (7*8)]; + egc.remain -= (8 - egc.dstbit); + egc.dstbit = 0; + } + else { + egc.srcmask._b[ext] = bytemask_d0[egc.dstbit + + (egc.remain - 1) * 8]; + egc.remain = 0; + egc.dstbit = 0; + } + } + else { + if (egc.remain >= 8) { + egc.remain -= 8; + } + else { + egc.srcmask._b[ext] = bytemask_d1[egc.remain - 1]; + egc.remain = 0; + } + } + egc.outptr--; + egc_src._b[0][ext] = (egc.outptr[1] >> egc.sft8bitl) | + (egc.outptr[0] << egc.sft8bitr); + egc_src._b[1][ext] = (egc.outptr[5] >> egc.sft8bitl) | + (egc.outptr[4] << egc.sft8bitr); + egc_src._b[2][ext] = (egc.outptr[9] >> egc.sft8bitl) | + (egc.outptr[8] << egc.sft8bitr); + egc_src._b[3][ext] = (egc.outptr[13] >> egc.sft8bitl) | + (egc.outptr[12] << egc.sft8bitr); +} + + +static void egcsftb_upn0(UINT32 adrs) { + + UINT ext; + + ext = EGCADDR(adrs & 1); + if (egc.stack < (UINT)(8 - egc.dstbit)) { + egc.srcmask._b[ext] = 0; + return; + } + egc.stack -= (8 - egc.dstbit); + egcsftb_upn_sub(ext); + if (!egc.remain) { + egcshift(); + } +} + +static void egcsftw_upn0(UINT32 adrs) { + + if (egc.stack < (UINT)(16 - egc.dstbit)) { + egc.srcmask.w = 0; + return; + } + egc.stack -= (16 - egc.dstbit); + egcsftb_upn_sub(EGCADDR_L); + if (egc.remain) { + egcsftb_upn_sub(EGCADDR_H); + if (egc.remain) { + return; + } + } + else { + egc.srcmask._b[EGCADDR_H] = 0; + } + egcshift(); + (void)adrs; +} + +static void egcsftb_dnn0(UINT32 adrs) { + + UINT ext; + + ext = EGCADDR(adrs & 1); + if (egc.stack < (UINT)(8 - egc.dstbit)) { + egc.srcmask._b[ext] = 0; + return; + } + egc.stack -= (8 - egc.dstbit); + egcsftb_dnn_sub(ext); + if (!egc.remain) { + egcshift(); + } +} + +static void egcsftw_dnn0(UINT32 adrs) { + + if (egc.stack < (UINT)(16 - egc.dstbit)) { + egc.srcmask.w = 0; + return; + } + egc.stack -= (16 - egc.dstbit); + egcsftb_dnn_sub(EGCADDR_H); + if (egc.remain) { + egcsftb_dnn_sub(EGCADDR_L); + if (egc.remain) { + return; + } + } + else { + egc.srcmask._b[EGCADDR_L] = 0; + } + egcshift(); + (void)adrs; +} + + +static void egcsftb_upr0(UINT32 adrs) { // dir:up srcbit < dstbit + + int ext; + + ext = EGCADDR(adrs & 1); + if (egc.stack < (UINT)(8 - egc.dstbit)) { + egc.srcmask._b[ext] = 0; + return; + } + egc.stack -= (8 - egc.dstbit); + egcsftb_upr_sub(ext); + if (!egc.remain) { + egcshift(); + } +} + +static void egcsftw_upr0(UINT32 adrs) { // dir:up srcbit < dstbit + + if (egc.stack < (UINT)(16 - egc.dstbit)) { + egc.srcmask.w = 0; + return; + } + egc.stack -= (16 - egc.dstbit); + egcsftb_upr_sub(EGCADDR_L); + if (egc.remain) { + egcsftb_upr_sub(EGCADDR_H); + if (egc.remain) { + return; + } + } + else { + egc.srcmask._b[EGCADDR_H] = 0; + } + egcshift(); + (void)adrs; +} + +static void egcsftb_dnr0(UINT32 adrs) { // dir:up srcbit < dstbit + + UINT ext; + + ext = EGCADDR(adrs & 1); + if (egc.stack < (UINT)(8 - egc.dstbit)) { + egc.srcmask._b[ext] = 0; + return; + } + egc.stack -= (8 - egc.dstbit); + egcsftb_dnr_sub(ext); + if (!egc.remain) { + egcshift(); + } +} + +static void egcsftw_dnr0(UINT32 adrs) { // dir:up srcbit < dstbit + + if (egc.stack < (UINT)(16 - egc.dstbit)) { + egc.srcmask.w = 0; + return; + } + egc.stack -= (16 - egc.dstbit); + egcsftb_dnr_sub(EGCADDR_H); + if (egc.remain) { + egcsftb_dnr_sub(EGCADDR_L); + if (egc.remain) { + return; + } + } + else { + egc.srcmask._b[EGCADDR_L] = 0; + } + egcshift(); + (void)adrs; +} + + +static void egcsftb_upl0(UINT32 adrs) { // dir:up srcbit > dstbit + + UINT ext; + + ext = EGCADDR(adrs & 1); + if (egc.stack < (UINT)(8 - egc.dstbit)) { + egc.srcmask._b[ext] = 0; + return; + } + egc.stack -= (8 - egc.dstbit); + egcsftb_upl_sub(ext); + if (!egc.remain) { + egcshift(); + } +} + +static void egcsftw_upl0(UINT32 adrs) { // dir:up srcbit > dstbit + + if (egc.stack < (UINT)(16 - egc.dstbit)) { + egc.srcmask.w = 0; + return; + } + egc.stack -= (16 - egc.dstbit); + egcsftb_upl_sub(EGCADDR_L); + if (egc.remain) { + egcsftb_upl_sub(EGCADDR_H); + if (egc.remain) { + return; + } + } + else { + egc.srcmask._b[EGCADDR_H] = 0; + } + egcshift(); + (void)adrs; +} + +static void egcsftb_dnl0(UINT32 adrs) { // dir:up srcbit > dstbit + + UINT ext; + + ext = EGCADDR(adrs & 1); + if (egc.stack < (UINT)(8 - egc.dstbit)) { + egc.srcmask._b[ext] = 0; + return; + } + egc.stack -= (8 - egc.dstbit); + egcsftb_dnl_sub(ext); + if (!egc.remain) { + egcshift(); + } +} + +static void egcsftw_dnl0(UINT32 adrs) { // dir:up srcbit > dstbit + + if (egc.stack < (UINT)(16 - egc.dstbit)) { + egc.srcmask.w = 0; + return; + } + egc.stack -= (16 - egc.dstbit); + egcsftb_dnl_sub(EGCADDR_H); + if (egc.remain) { + egcsftb_dnl_sub(EGCADDR_L); + if (egc.remain) { + return; + } + } + else { + egc.srcmask._b[EGCADDR_L] = 0; + } + egcshift(); + (void)adrs; +} + + +static void (*egcsft_proc[])(UINT32 adrs) = { + egcsftw_upn0, egcsftw_dnn0, + egcsftw_upr0, egcsftw_dnr0, + egcsftw_upl0, egcsftw_dnl0, + + egcsftb_upn0, egcsftb_dnn0, + egcsftb_upr0, egcsftb_dnr0, + egcsftb_upl0, egcsftb_dnl0}; + + +// --------------------------------------------------------------------------- + +static void shiftinput_byte(UINT ext) { + + if (egc.stack <= 16) { + if (egc.srcbit >= 8) { + egc.srcbit -= 8; + } + else { + egc.stack += (8 - egc.srcbit); + egc.srcbit = 0; + } + if (!(egc.sft & 0x1000)) { + egc.inptr++; + } + else { + egc.inptr--; + } + } + egc.srcmask._b[ext] = 0xff; + egcsft_proc[egc.func + 6](ext); +} + +static void shiftinput_incw(void) { + + if (egc.stack <= 16) { + egc.inptr += 2; + if (egc.srcbit >= 8) { + egc.outptr++; + } + egc.stack += (16 - egc.srcbit); + egc.srcbit = 0; + } + egc.srcmask.w = 0xffff; + egcsft_proc[egc.func](0); +} + +static void shiftinput_decw(void) { + + if (egc.stack <= 16) { + egc.inptr -= 2; + if (egc.srcbit >= 8) { + egc.outptr--; + } + egc.stack += (16 - egc.srcbit); + egc.srcbit = 0; + } + egc.srcmask.w = 0xffff; + egcsft_proc[egc.func](0); +} + + +#define EGCOPE_SHIFT { \ + if (egc.ope & 0x400) { \ + if (func < 6) { \ + if (!(egc.sft & 0x1000)) { \ + egc.inptr[ 0] = (BYTE)value; \ + egc.inptr[ 1] = (BYTE)(value >> 8); \ + egc.inptr[ 4] = (BYTE)value; \ + egc.inptr[ 5] = (BYTE)(value >> 8); \ + egc.inptr[ 8] = (BYTE)value; \ + egc.inptr[ 9] = (BYTE)(value >> 8); \ + egc.inptr[12] = (BYTE)value; \ + egc.inptr[13] = (BYTE)(value >> 8); \ + shiftinput_incw(); \ + } \ + else { \ + egc.inptr[-1] = (BYTE)value; \ + egc.inptr[ 0] = (BYTE)(value >> 8); \ + egc.inptr[ 3] = (BYTE)value; \ + egc.inptr[ 4] = (BYTE)(value >> 8); \ + egc.inptr[ 7] = (BYTE)value; \ + egc.inptr[ 8] = (BYTE)(value >> 8); \ + egc.inptr[11] = (BYTE)value; \ + egc.inptr[12] = (BYTE)(value >> 8); \ + shiftinput_decw(); \ + } \ + } \ + else { \ + egc.inptr[ 0] = (BYTE)value; \ + egc.inptr[ 4] = (BYTE)value; \ + egc.inptr[ 8] = (BYTE)value; \ + egc.inptr[12] = (BYTE)value; \ + shiftinput_byte(EGCADDR(ad & 1)); \ + } \ + } \ +} + + +static void gdc_ope(UINT32 ad, REG16 value, int func) { + + EGCQUAD pat; + EGCQUAD dst; + + egc.mask2.w = egc.mask.w; + + switch(egc.ope & 0x1800) { + case 0x0800: + EGCOPE_SHIFT; + switch(egc.fgbg & 0x6000) { + case 0x2000: + pat.d[0] = egc.bgc.d[0]; + pat.d[1] = egc.bgc.d[1]; + break; + case 0x4000: + pat.d[0] = egc.fgc.d[0]; + pat.d[1] = egc.fgc.d[1]; + break; + default: + if ((egc.ope & 0x0300) == 0x0100) { // ver0.29 + pat.d[0] = egc_src.d[0]; + pat.d[1] = egc_src.d[1]; + } + else { + pat.d[0] = egc.patreg.d[0]; + pat.d[1] = egc.patreg.d[1]; + } + break; + } + ad &= ~1; + dst.w[0] = *(UINT16 *)(&mem[ad + VRAM_B]); + dst.w[1] = *(UINT16 *)(&mem[ad + VRAM_R]); + dst.w[2] = *(UINT16 *)(&mem[ad + VRAM_G]); + dst.w[3] = *(UINT16 *)(&mem[ad + VRAM_E]); + +#ifdef LOG_EGCROP + egcropcnt[egc.ope & 0xff]++; +#endif + data.d[0] = 0; + data.d[1] = 0; + if (egc.ope & 0x80) { + data.d[0] |= (pat.d[0] & egc_src.d[0] & dst.d[0]); + data.d[1] |= (pat.d[1] & egc_src.d[1] & dst.d[1]); + } + if (egc.ope & 0x40) { + data.d[0] |= ((~pat.d[0]) & egc_src.d[0] & dst.d[0]); + data.d[1] |= ((~pat.d[1]) & egc_src.d[1] & dst.d[1]); + } + if (egc.ope & 0x20) { + data.d[0] |= (pat.d[0] & egc_src.d[0] & (~dst.d[0])); + data.d[1] |= (pat.d[1] & egc_src.d[1] & (~dst.d[1])); + } + if (egc.ope & 0x10) { + data.d[0] |= ((~pat.d[0]) & egc_src.d[0] & (~dst.d[0])); + data.d[1] |= ((~pat.d[1]) & egc_src.d[1] & (~dst.d[1])); + } + if (egc.ope & 0x08) { + data.d[0] |= (pat.d[0] & (~egc_src.d[0]) & dst.d[0]); + data.d[1] |= (pat.d[1] & (~egc_src.d[1]) & dst.d[1]); + } + if (egc.ope & 0x04) { + data.d[0] |= ((~pat.d[0]) & (~egc_src.d[0]) & dst.d[0]); + data.d[1] |= ((~pat.d[1]) & (~egc_src.d[1]) & dst.d[1]); + } + if (egc.ope & 0x02) { + data.d[0] |= (pat.d[0] & (~egc_src.d[0]) & (~dst.d[0])); + data.d[1] |= (pat.d[1] & (~egc_src.d[1]) & (~dst.d[1])); + } + if (egc.ope & 0x01) { + data.d[0] |= ((~pat.d[0]) & (~egc_src.d[0]) & (~dst.d[0])); + data.d[1] |= ((~pat.d[1]) & (~egc_src.d[1]) & (~dst.d[1])); + } + egc.mask2.w &= egc.srcmask.w; + break; + case 0x1000: + switch(egc.fgbg & 0x6000) { + case 0x2000: // ver0.29 + data.d[0] = egc.bgc.d[0]; + data.d[1] = egc.bgc.d[1]; + break; + case 0x4000: // ver0.29 + data.d[0] = egc.fgc.d[0]; + data.d[1] = egc.fgc.d[1]; + break; + default: +#if 0 + data.d[0] = egc.patreg.d[0]; + data.d[1] = egc.patreg.d[1]; +#else + EGCOPE_SHIFT; + data.d[0] = egc_src.d[0]; + data.d[1] = egc_src.d[1]; + egc.mask2.w &= egc.srcmask.w; +#endif + break; + } + break; + default: +#if defined(BYTESEX_LITTLE) + data.w[0] = (UINT16)value; + data.w[1] = (UINT16)value; + data.w[2] = (UINT16)value; + data.w[3] = (UINT16)value; +#else + data._b[0][0] = (BYTE)value; + data._b[0][1] = (BYTE)(value >> 8); + data.w[1] = data.w[0]; + data.w[2] = data.w[0]; + data.w[3] = data.w[0]; +#endif + break; + } +} + +REG8 MEMCALL egc_read(UINT32 addr) { + + UINT32 ad; + UINT ext; + + if (gdcs.access) { + addr += VRAM_STEP; + } + ad = VRAM_POS(addr); + ext = EGCADDR(addr & 1); + egc.lastvram._b[0][ext] = mem[ad + VRAM_B]; + egc.lastvram._b[1][ext] = mem[ad + VRAM_R]; + egc.lastvram._b[2][ext] = mem[ad + VRAM_G]; + egc.lastvram._b[3][ext] = mem[ad + VRAM_E]; + + // shift input + if (!(egc.ope & 0x400)) { + egc.inptr[0] = egc.lastvram._b[0][ext]; + egc.inptr[4] = egc.lastvram._b[1][ext]; + egc.inptr[8] = egc.lastvram._b[2][ext]; + egc.inptr[12] = egc.lastvram._b[3][ext]; + shiftinput_byte(ext); + } + + if ((egc.ope & 0x0300) == 0x0100) { + egc.patreg._b[0][ext] = mem[ad + VRAM_B]; + egc.patreg._b[1][ext] = mem[ad + VRAM_R]; + egc.patreg._b[2][ext] = mem[ad + VRAM_G]; + egc.patreg._b[3][ext] = mem[ad + VRAM_E]; + } + if (!(egc.ope & 0x2000)) { + int pl = (egc.fgbg >> 8) & 3; + if (!(egc.ope & 0x400)) { + return(egc_src._b[pl][ext]); + } + else { + return(mem[ad + planead[pl]]); + } + } + return(mem[addr]); +} + + +void MEMCALL egc_write(UINT32 addr, REG8 value) { + + UINT ext; + REG16 wvalue; + + addr = LOW15(addr); + ext = EGCADDR(addr & 1); + if (!gdcs.access) { + gdcs.grphdisp |= 1; + vramupdate[addr] |= 0x01; + } + else { + gdcs.grphdisp |= 2; + vramupdate[addr] |= 0x02; + addr += VRAM_STEP; + } + if ((egc.ope & 0x0300) == 0x0200) { + egc.patreg._b[0][ext] = mem[addr + VRAM_B]; + egc.patreg._b[1][ext] = mem[addr + VRAM_R]; + egc.patreg._b[2][ext] = mem[addr + VRAM_G]; + egc.patreg._b[3][ext] = mem[addr + VRAM_E]; + } + + value = (BYTE)value; + wvalue = (value << 8) + value; + if (!ext) { + gdc_ope(addr, wvalue, egc.func + 6); + } + else { + gdc_ope(addr, wvalue, egc.func + 6); + } + if (egc.mask2._b[ext]) { + if (!(egc.access & 1)) { + mem[addr + VRAM_B] &= ~egc.mask2._b[ext]; + mem[addr + VRAM_B] |= data._b[0][ext] & egc.mask2._b[ext]; + } + if (!(egc.access & 2)) { + mem[addr + VRAM_R] &= ~egc.mask2._b[ext]; + mem[addr + VRAM_R] |= data._b[1][ext] & egc.mask2._b[ext]; + } + if (!(egc.access & 4)) { + mem[addr + VRAM_G] &= ~egc.mask2._b[ext]; + mem[addr + VRAM_G] |= data._b[2][ext] & egc.mask2._b[ext]; + } + if (!(egc.access & 8)) { + mem[addr + VRAM_E] &= ~egc.mask2._b[ext]; + mem[addr + VRAM_E] |= data._b[3][ext] & egc.mask2._b[ext]; + } + } +} + +REG16 MEMCALL egc_read_w(UINT32 addr) { + + UINT32 ad; + + if (!(addr & 1)) { + if (gdcs.access) { + addr += VRAM_STEP; + } + ad = VRAM_POS(addr); + egc.lastvram.w[0] = *(UINT16 *)(&mem[ad + VRAM_B]); + egc.lastvram.w[1] = *(UINT16 *)(&mem[ad + VRAM_R]); + egc.lastvram.w[2] = *(UINT16 *)(&mem[ad + VRAM_G]); + egc.lastvram.w[3] = *(UINT16 *)(&mem[ad + VRAM_E]); + + // shift input + if (!(egc.ope & 0x400)) { + if (!(egc.sft & 0x1000)) { + egc.inptr[ 0] = egc.lastvram._b[0][EGCADDR_L]; + egc.inptr[ 1] = egc.lastvram._b[0][EGCADDR_H]; + egc.inptr[ 4] = egc.lastvram._b[1][EGCADDR_L]; + egc.inptr[ 5] = egc.lastvram._b[1][EGCADDR_H]; + egc.inptr[ 8] = egc.lastvram._b[2][EGCADDR_L]; + egc.inptr[ 9] = egc.lastvram._b[2][EGCADDR_H]; + egc.inptr[12] = egc.lastvram._b[3][EGCADDR_L]; + egc.inptr[13] = egc.lastvram._b[3][EGCADDR_H]; + shiftinput_incw(); + } + else { + egc.inptr[-1] = egc.lastvram._b[0][EGCADDR_L]; + egc.inptr[ 0] = egc.lastvram._b[0][EGCADDR_H]; + egc.inptr[ 3] = egc.lastvram._b[1][EGCADDR_L]; + egc.inptr[ 4] = egc.lastvram._b[1][EGCADDR_H]; + egc.inptr[ 7] = egc.lastvram._b[2][EGCADDR_L]; + egc.inptr[ 8] = egc.lastvram._b[2][EGCADDR_H]; + egc.inptr[11] = egc.lastvram._b[3][EGCADDR_L]; + egc.inptr[12] = egc.lastvram._b[3][EGCADDR_H]; + shiftinput_decw(); + } + } + + if ((egc.ope & 0x0300) == 0x0100) { + egc.patreg.d[0] = egc.lastvram.d[0]; + egc.patreg.d[1] = egc.lastvram.d[1]; + } + if (!(egc.ope & 0x2000)) { + int pl = (egc.fgbg >> 8) & 3; + if (!(egc.ope & 0x400)) { + return(LOADINTELWORD(egc_src._b[pl])); + } + else { + return(LOADINTELWORD(mem + ad + planead[pl])); + } + } + return(LOADINTELWORD(mem + addr)); + } + else if (!(egc.sft & 0x1000)) { + REG16 ret; + ret = egc_read(addr); + ret |= egc_read(addr+1) << 8; + return(ret); + } + else { + REG16 ret; + ret = egc_read(addr+1) << 8; + ret |= egc_read(addr); + return(ret); + } +} + +void MEMCALL egc_write_w(UINT32 addr, REG16 value) { + + if (!(addr & 1)) { // word access + addr = LOW15(addr); + if (!gdcs.access) { + gdcs.grphdisp |= 1; + *(UINT16 *)(vramupdate + addr) |= 0x0101; + } + else { + gdcs.grphdisp |= 2; + *(UINT16 *)(vramupdate + addr) |= 0x0202; + addr += VRAM_STEP; + } + if ((egc.ope & 0x0300) == 0x0200) { + egc.patreg.w[0] = *(UINT16 *)(&mem[addr + VRAM_B]); + egc.patreg.w[1] = *(UINT16 *)(&mem[addr + VRAM_R]); + egc.patreg.w[2] = *(UINT16 *)(&mem[addr + VRAM_G]); + egc.patreg.w[3] = *(UINT16 *)(&mem[addr + VRAM_E]); + } + gdc_ope(addr, value, egc.func); + if (egc.mask2.w) { + if (!(egc.access & 1)) { + *(UINT16 *)(&mem[addr + VRAM_B]) &= ~egc.mask2.w; + *(UINT16 *)(&mem[addr + VRAM_B]) |= data.w[0] & egc.mask2.w; + } + if (!(egc.access & 2)) { + *(UINT16 *)(&mem[addr + VRAM_R]) &= ~egc.mask2.w; + *(UINT16 *)(&mem[addr + VRAM_R]) |= data.w[1] & egc.mask2.w; + } + if (!(egc.access & 4)) { + *(UINT16 *)(&mem[addr + VRAM_G]) &= ~egc.mask2.w; + *(UINT16 *)(&mem[addr + VRAM_G]) |= data.w[2] & egc.mask2.w; + } + if (!(egc.access & 8)) { + *(UINT16 *)(&mem[addr + VRAM_E]) &= ~egc.mask2.w; + *(UINT16 *)(&mem[addr + VRAM_E]) |= data.w[3] & egc.mask2.w; + } + } + } + else if (!(egc.sft & 0x1000)) { + egc_write(addr, (REG8)value); + egc_write(addr+1, (REG8)(value >> 8)); + } + else { + egc_write(addr+1, (REG8)(value >> 8)); + egc_write(addr, (REG8)value); + } +} + diff --git a/i386c/egcmem.h b/i386c/egcmem.h new file mode 100644 index 00000000..67d95edd --- /dev/null +++ b/i386c/egcmem.h @@ -0,0 +1,16 @@ + +#ifdef __cplusplus +extern "C" { +#endif + +void egcshift(void); + +REG8 MEMCALL egc_read(UINT32 addr); +void MEMCALL egc_write(UINT32 addr, REG8 value); +REG16 MEMCALL egc_read_w(UINT32 addr); +void MEMCALL egc_write_w(UINT32 addr, REG16 value); + +#ifdef __cplusplus +} +#endif + diff --git a/i386c/ia32/cpu.c b/i386c/ia32/cpu.c new file mode 100644 index 00000000..5ac4d9ed --- /dev/null +++ b/i386c/ia32/cpu.c @@ -0,0 +1,105 @@ +/* $Id: cpu.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "inst_table.h" + +jmp_buf exec_1step_jmpbuf; + +void +exec_1step(void) +{ + BYTE op; + + CPU_PREV_EIP = CPU_EIP; + + cpu_inst = cpu_inst_default; + + for (;;) { + GET_PCBYTE(op); + + /* prefix */ + if (insttable_info[op] & INST_PREFIX) { + (*insttable_1byte[0][op])(); + continue; + } + break; + } + + /* normal / rep, but not use */ + if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) { + (*insttable_1byte[CPU_INST_OP32][op])(); + return; + } + + /* rep */ + CPU_WORKCLOCK(5); + if (!CPU_INST_AS32) { + if (CPU_CX != 0) { + if (!(insttable_info[op] & REP_CHECKZF)) { + /* rep */ + do { + (*insttable_1byte[CPU_INST_OP32][op])(); + } while (--CPU_CX); + } else if (CPU_INST_REPUSE != 0xf2) { + /* repe */ + do { + (*insttable_1byte[CPU_INST_OP32][op])(); + } while (--CPU_CX && (CPU_FLAGL & Z_FLAG)); + } else { + /* repne */ + do { + (*insttable_1byte[CPU_INST_OP32][op])(); + } while (--CPU_CX && !(CPU_FLAGL & Z_FLAG)); + } + } + } else { + if (CPU_ECX != 0) { + if (!(insttable_info[op] & REP_CHECKZF)) { + /* rep */ + do { + (*insttable_1byte[CPU_INST_OP32][op])(); + } while (--CPU_ECX); + } else if (CPU_INST_REPUSE != 0xf2) { + /* repe */ + do { + (*insttable_1byte[CPU_INST_OP32][op])(); + } while (--CPU_ECX && (CPU_FLAGL & Z_FLAG)); + } else { + /* repne */ + do { + (*insttable_1byte[CPU_INST_OP32][op])(); + } while (--CPU_ECX && !(CPU_FLAGL & Z_FLAG)); + } + } + } +} diff --git a/i386c/ia32/cpu.h b/i386c/ia32/cpu.h new file mode 100644 index 00000000..37b0d35a --- /dev/null +++ b/i386c/ia32/cpu.h @@ -0,0 +1,587 @@ +/* $Id: cpu.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Intel Architecture 32-bit Processor Interpreter Engine for Pentium + + Copyright by Yui/Studio Milmake 1999-2000 + Copyright by Norio HATTORI 2000,2001 + Copyright by NONAKA Kimihiro 2002-2003 +*/ + +#ifndef IA32_CPU_CPU_H__ +#define IA32_CPU_CPU_H__ + +#if 0 // -> compiler.h +#include +#include +#include +#include +#include +#include +#endif + +#include "interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { +#if defined(BYTESEX_LITTLE) + struct { + BYTE l; + BYTE h; + BYTE _hl; + BYTE _hh; + } b; + struct { + WORD w; + WORD _hw; + } w; +#elif defined(BYTESEX_BIG) + struct { + BYTE _hh; + BYTE _hl; + BYTE h; + BYTE l; + } b; + struct { + WORD _hw; + WORD w; + } w; +#endif + DWORD d; +} REG32; + +#ifdef __cplusplus +} +#endif + +#include "cpu_io.h" +#include "cpu_mem.h" +#include "exception.h" +#include "paging.h" +#include "resolve.h" +#include "segments.h" +#include "task.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + CPU_EAX_INDEX = 0, + CPU_ECX_INDEX = 1, + CPU_EDX_INDEX = 2, + CPU_EBX_INDEX = 3, + CPU_ESP_INDEX = 4, + CPU_EBP_INDEX = 5, + CPU_ESI_INDEX = 6, + CPU_EDI_INDEX = 7, + CPU_REG_NUM +}; + +enum { + CPU_ES_INDEX = 0, + CPU_CS_INDEX = 1, + CPU_SS_INDEX = 2, + CPU_DS_INDEX = 3, + CPU_SEGREG286_NUM = 4, + CPU_FS_INDEX = 4, + CPU_GS_INDEX = 5, + CPU_SEGREG_NUM +}; + +#if 1 // ・ム・テ・ッ、キ、ハ、、、ネ、タ、癸ゥ + +typedef struct { + REG32 reg[CPU_REG_NUM]; + WORD sreg[CPU_SEGREG_NUM]; + + REG32 eflags; + + REG32 eip; + REG32 prev_eip; +} CPU_REGS; + +typedef struct { + WORD gdtr_limit; + DWORD gdtr_base; + WORD idtr_limit; + DWORD idtr_base; + + WORD ldtr; + WORD tr; + descriptor_t ldtr_desc; + descriptor_t tr_desc; + + DWORD cr0; + DWORD cr1; + DWORD cr2; + DWORD cr3; + DWORD cr4; + DWORD mxcsr; +} CPU_SYSREGS; + +typedef struct { + descriptor_t sreg[CPU_SEGREG_NUM]; + + DWORD inport; + DWORD ovflag; + + BYTE ss_32; + BYTE trap; + BYTE cpu_type; + BYTE _dummy; + + BYTE cpl; + BYTE protected_mode; + BYTE paging; + BYTE vm86; + + DWORD ioaddr; /* I/O bitmap linear address */ + WORD iolimit; /* I/O bitmap count */ + + BYTE nerror; /* double fault/ triple fault */ + BYTE prev_exception; +} CPU_STAT; + +typedef struct { + BYTE op_32; + BYTE as_32; + BYTE rep_used; + BYTE seg_used; + DWORD seg_base; +} CPU_INST; + +#else + +typedef struct { + REG32 reg[CPU_REG_NUM]; + WORD sreg[CPU_SEGREG_NUM]; + + REG32 eflags; + + REG32 eip; + REG32 prev_eip; +} __attribute__((packed)) CPU_REGS; + +typedef struct { + WORD gdtr_limit; + DWORD gdtr_base; + WORD idtr_limit; + DWORD idtr_base; + + WORD ldtr; + WORD tr; + descriptor_t ldtr_desc; + descriptor_t tr_desc; + + DWORD cr0; + DWORD cr1; + DWORD cr2; + DWORD cr3; + DWORD cr4; + DWORD mxcsr; +} __attribute__((packed)) CPU_SYSREGS; + +typedef struct { + descriptor_t sreg[CPU_SEGREG_NUM]; + + DWORD inport; + DWORD ovflag; + + BYTE ss_32; + BYTE trap; + BYTE cpu_type; + BYTE _dummy; + + BYTE cpl; + BYTE protected_mode; + BYTE paging; + BYTE vm86; + + DWORD ioaddr; /* I/O bitmap linear address */ + WORD iolimit; /* I/O bitmap count */ + + BYTE nerror; /* double fault/ triple fault */ + BYTE prev_exception; +} __attribute__((packed)) CPU_STAT; + +typedef struct { + BYTE op_32; + BYTE as_32; + BYTE rep_used; + BYTE seg_used; + DWORD seg_base; +} __attribute__((packed)) CPU_INST; + +#endif + +extern CPU_REGS cpu_regs; +extern CPU_SYSREGS cpu_sysregs; +extern CPU_STAT cpu_stat; +extern CPU_INST cpu_inst; +extern CPU_INST cpu_inst_default; +extern BYTE iflags[]; + +extern jmp_buf exec_1step_jmpbuf; + + +/* + * CPUID + */ +/* vendor */ +#define CPU_VENDOR_1 0x756e6547 /* "Genu" */ +#define CPU_VENDOR_2 0x49656e69 /* "ineI" */ +#define CPU_VENDOR_3 0x6c65746e /* "ntel" */ + +/* version */ +#define CPU_FAMILY 6 +#define CPU_MODEL 1 +#define CPU_STEPPING 3 + +/* feature */ +#define CPU_FEATURE_FPU (1 << 0) +#define CPU_FEATURE_VME (1 << 1) +#define CPU_FEATURE_DE (1 << 2) +#define CPU_FEATURE_PSE (1 << 3) +#define CPU_FEATURE_TSC (1 << 4) +#define CPU_FEATURE_MSR (1 << 5) +#define CPU_FEATURE_PAE (1 << 6) +#define CPU_FEATURE_MCE (1 << 7) +#define CPU_FEATURE_CX8 (1 << 8) +#define CPU_FEATURE_APIC (1 << 9) +/* (1 << 10) */ +#define CPU_FEATURE_SEP (1 << 11) +#define CPU_FEATURE_MTRR (1 << 12) +#define CPU_FEATURE_PGE (1 << 13) +#define CPU_FEATURE_MCA (1 << 14) +#define CPU_FEATURE_CMOV (1 << 15) +#define CPU_FEATURE_FGPAT (1 << 16) +#define CPU_FEATURE_PSE36 (1 << 17) +#define CPU_FEATURE_PN (1 << 18) +/* (1 << 19) */ +/* (1 << 20) */ +/* (1 << 21) */ +/* (1 << 22) */ +#define CPU_FEATURE_MMX (1 << 23) +#define CPU_FEATURE_FXSR (1 << 24) +#define CPU_FEATURE_XMM (1 << 25) +/* (1 << 26) */ +/* (1 << 27) */ +/* (1 << 28) */ +/* (1 << 29) */ +/* (1 << 30) */ +/* (1 << 31) */ +#ifdef USE_FPU +#define CPU_FEATURES (CPU_FEATURE_CMOV|CPU_FEATURE_FPU) +#else +#define CPU_FEATURES (CPU_FEATURE_CMOV) +#endif + + +#define CPU_REGS_BYTEL(n) cpu_regs.reg[(n)].b.l +#define CPU_REGS_BYTEH(n) cpu_regs.reg[(n)].b.h +#define CPU_REGS_WORD(n) cpu_regs.reg[(n)].w.w +#define CPU_REGS_DWORD(n) cpu_regs.reg[(n)].d +#define CPU_REGS_SREG(n) cpu_regs.sreg[(n)] + +#define CPU_STAT_SREG(n) cpu_stat.sreg[(n)] +#define CPU_STAT_SREGBASE(n) cpu_stat.sreg[(n)].u.seg.segbase +#define CPU_STAT_SREGEND(n) cpu_stat.sreg[(n)].u.seg.segend +#define CPU_STAT_SREGLIMIT(n) cpu_stat.sreg[(n)].u.seg.limit +#define CPU_STAT_SREG_CLEAR(n) \ +do { \ + memset(&CPU_STAT_SREG(n), 0, sizeof(descriptor_t)); \ +} while (/*CONSTCOND*/ 0) +#define CPU_STAT_SREG_INIT(n) \ +do { \ + descriptor_t sd; \ + memset(&CPU_STAT_SREG(n), 0, sizeof(CPU_STAT_SREG(n))); \ + memset(&sd, 0, sizeof(sd)); \ + sd.u.seg.limit = 0xffff; \ + CPU_SET_SEGDESC_DEFAULT(&sd, (n), 0); \ + CPU_STAT_SREG(n) = sd; \ +} while (/*CONSTCOND*/ 0) + + +#define CPU_AL CPU_REGS_BYTEL(CPU_EAX_INDEX) +#define CPU_CL CPU_REGS_BYTEL(CPU_ECX_INDEX) +#define CPU_DL CPU_REGS_BYTEL(CPU_EDX_INDEX) +#define CPU_BL CPU_REGS_BYTEL(CPU_EBX_INDEX) +#define CPU_AH CPU_REGS_BYTEH(CPU_EAX_INDEX) +#define CPU_CH CPU_REGS_BYTEH(CPU_ECX_INDEX) +#define CPU_DH CPU_REGS_BYTEH(CPU_EDX_INDEX) +#define CPU_BH CPU_REGS_BYTEH(CPU_EBX_INDEX) + +#define CPU_AX CPU_REGS_WORD(CPU_EAX_INDEX) +#define CPU_CX CPU_REGS_WORD(CPU_ECX_INDEX) +#define CPU_DX CPU_REGS_WORD(CPU_EDX_INDEX) +#define CPU_BX CPU_REGS_WORD(CPU_EBX_INDEX) +#define CPU_SP CPU_REGS_WORD(CPU_ESP_INDEX) +#define CPU_BP CPU_REGS_WORD(CPU_EBP_INDEX) +#define CPU_SI CPU_REGS_WORD(CPU_ESI_INDEX) +#define CPU_DI CPU_REGS_WORD(CPU_EDI_INDEX) +#define CPU_IP cpu_regs.eip.w.w + +#define CPU_EAX CPU_REGS_DWORD(CPU_EAX_INDEX) +#define CPU_ECX CPU_REGS_DWORD(CPU_ECX_INDEX) +#define CPU_EDX CPU_REGS_DWORD(CPU_EDX_INDEX) +#define CPU_EBX CPU_REGS_DWORD(CPU_EBX_INDEX) +#define CPU_ESP CPU_REGS_DWORD(CPU_ESP_INDEX) +#define CPU_EBP CPU_REGS_DWORD(CPU_EBP_INDEX) +#define CPU_ESI CPU_REGS_DWORD(CPU_ESI_INDEX) +#define CPU_EDI CPU_REGS_DWORD(CPU_EDI_INDEX) +#define CPU_EIP cpu_regs.eip.d +#define CPU_PREV_EIP cpu_regs.prev_eip.d + +#define CPU_ES CPU_REGS_SREG(CPU_ES_INDEX) +#define CPU_CS CPU_REGS_SREG(CPU_CS_INDEX) +#define CPU_SS CPU_REGS_SREG(CPU_SS_INDEX) +#define CPU_DS CPU_REGS_SREG(CPU_DS_INDEX) +#define CPU_FS CPU_REGS_SREG(CPU_FS_INDEX) +#define CPU_GS CPU_REGS_SREG(CPU_GS_INDEX) + +#define ES_BASE cpu_stat.sreg[CPU_ES_INDEX].u.seg.segbase +#define CS_BASE cpu_stat.sreg[CPU_CS_INDEX].u.seg.segbase +#define SS_BASE cpu_stat.sreg[CPU_SS_INDEX].u.seg.segbase +#define DS_BASE cpu_stat.sreg[CPU_DS_INDEX].u.seg.segbase +#define FS_BASE cpu_stat.sreg[CPU_FS_INDEX].u.seg.segbase +#define GS_BASE cpu_stat.sreg[CPU_GS_INDEX].u.seg.segbase + +#define CPU_EFLAG cpu_regs.eflags.d +#define CPU_FLAG cpu_regs.eflags.w.w +#define CPU_FLAGL cpu_regs.eflags.b.l +#define CPU_FLAGH cpu_regs.eflags.b.h +#define CPU_TRAP cpu_stat.trap +#define CPU_INPORT cpu_stat.inport +#define CPU_OV cpu_stat.ovflag + +#define C_FLAG (1 << 0) +#define P_FLAG (1 << 2) +#define A_FLAG (1 << 4) +#define Z_FLAG (1 << 6) +#define S_FLAG (1 << 7) +#define T_FLAG (1 << 8) +#define I_FLAG (1 << 9) +#define D_FLAG (1 << 10) +#define O_FLAG (1 << 11) +#define IOPL_FLAG (3 << 12) +#define NT_FLAG (1 << 14) +#define RF_FLAG (1 << 16) +#define VM_FLAG (1 << 17) +#define AC_FLAG (1 << 18) +#define VIF_FLAG (1 << 19) +#define VIP_FLAG (1 << 20) +#define ID_FLAG (1 << 21) +#define SZP_FLAG (P_FLAG|Z_FLAG|S_FLAG) +#define SZAP_FLAG (P_FLAG|A_FLAG|Z_FLAG|S_FLAG) +#define SZPC_FLAG (C_FLAG|P_FLAG|Z_FLAG|S_FLAG) +#define SZAPC_FLAG (C_FLAG|P_FLAG|A_FLAG|Z_FLAG|S_FLAG) +#define ALL_FLAG (SZAPC_FLAG|T_FLAG|I_FLAG|D_FLAG|O_FLAG|IOPL_FLAG|NT_FLAG) +#define ALL_EFLAG (ALL_FLAG|RF_FLAG|VM_FLAG|AC_FLAG|VIF_FLAG|VIP_FLAG|ID_FLAG) + +#define REAL_FLAGREG ((CPU_FLAG & 0xf7ff) | (CPU_OV ? O_FLAG : 0)) +#define REAL_EFLAGREG ((CPU_EFLAG & 0xfffff7ff) | (CPU_OV ? O_FLAG : 0)) + +void set_flags(WORD new_flags, WORD mask); +void set_eflags(DWORD new_flags, DWORD mask); + +#define CPU_TYPE cpu_stat.cpu_type +#define CPUTYPE_V30 0x01 + +#define CPU_INST_OP32 cpu_inst.op_32 +#define CPU_INST_AS32 cpu_inst.as_32 +#define CPU_INST_REPUSE cpu_inst.rep_used +#define CPU_INST_SEGUSE cpu_inst.seg_used +#define CPU_INST_SEGREG_INDEX cpu_inst.seg_base +#define DS_FIX (!CPU_INST_SEGUSE ? CPU_DS_INDEX : CPU_INST_SEGREG_INDEX) +#define SS_FIX (!CPU_INST_SEGUSE ? CPU_SS_INDEX : CPU_INST_SEGREG_INDEX) + +#define CPU_STAT_CS_BASE cpu_stat.sreg[CPU_CS_INDEX].u.seg.limit +#define CPU_STAT_CS_LIMIT cpu_stat.sreg[CPU_CS_INDEX].u.seg.limit +#define CPU_STAT_CS_END cpu_stat.sreg[CPU_CS_INDEX].u.seg.segend + +#define CPU_STAT_SS32 cpu_stat.ss_32 +#define CPU_STAT_PM cpu_stat.protected_mode +#define CPU_STAT_VM86 cpu_stat.vm86 +#define CPU_STAT_PAGING cpu_stat.paging +#define CPU_STAT_CPL cpu_stat.cpl + +#define CPU_STAT_IOPL ((CPU_EFLAG & IOPL_FLAG) >> 12) +#define CPU_IOPL0 0 +#define CPU_IOPL1 1 +#define CPU_IOPL2 2 +#define CPU_IOPL3 3 + +#define CPU_STAT_IOADDR cpu_stat.ioaddr +#define CPU_STAT_IOLIMIT cpu_stat.iolimit + +#define CPU_STAT_NERROR cpu_stat.nerror +#define CPU_STAT_PREV_EXCEPTION cpu_stat.prev_exception + +#define CPU_CLI do { CPU_FLAG &= ~I_FLAG; \ + CPU_TRAP = 0; } while (/*CONSTCOND*/ 0) +#define CPU_STI do { CPU_FLAG |= I_FLAG; \ + CPU_TRAP = (CPU_FLAG >> 8) & 1; } while (/*CONSTCOND*/0) + +#define CPU_GDTR_LIMIT cpu_sysregs.gdtr_limit +#define CPU_GDTR_BASE cpu_sysregs.gdtr_base +#define CPU_IDTR_LIMIT cpu_sysregs.idtr_limit +#define CPU_IDTR_BASE cpu_sysregs.idtr_base +#define CPU_LDTR cpu_sysregs.ldtr +#define CPU_LDTR_DESC cpu_sysregs.ldtr_desc +#define CPU_LDTR_BASE cpu_sysregs.ldtr_desc.u.seg.segbase +#define CPU_LDTR_END cpu_sysregs.ldtr_desc.u.seg.segend +#define CPU_LDTR_LIMIT cpu_sysregs.ldtr_desc.u.seg.limit +#define CPU_TR cpu_sysregs.tr +#define CPU_TR_DESC cpu_sysregs.tr_desc +#define CPU_TR_BASE cpu_sysregs.tr_desc.u.seg.segbase +#define CPU_TR_END cpu_sysregs.tr_desc.u.seg.segend +#define CPU_TR_LIMIT cpu_sysregs.tr_desc.u.seg.limit + +#define CPU_CR0 cpu_sysregs.cr0 +#define CPU_CR1 cpu_sysregs.cr1 +#define CPU_CR2 cpu_sysregs.cr2 +#define CPU_CR3 cpu_sysregs.cr3 +#define CPU_CR4 cpu_sysregs.cr4 +#define CPU_MXCSR cpu_sysregs.mxcsr + +#define CPU_CR0_PE (1 << 0) +#define CPU_CR0_MP (1 << 1) +#define CPU_CR0_EM (1 << 2) +#define CPU_CR0_TS (1 << 3) +#define CPU_CR0_ET (1 << 4) +#define CPU_CR0_NE (1 << 5) +#define CPU_CR0_WP (1 << 16) +#define CPU_CR0_AM (1 << 18) +#define CPU_CR0_NW (1 << 29) +#define CPU_CR0_CD (1 << 30) +#define CPU_CR0_PG (1 << 31) + +#define CPU_CR3_PD_MASK 0xfffff000 +#define CPU_CR3_PWT (1 << 3) +#define CPU_CR3_PCD (1 << 4) + +#define CPU_CR4_VME (1 << 0) +#define CPU_CR4_PVI (1 << 1) +#define CPU_CR4_TSD (1 << 2) +#define CPU_CR4_DE (1 << 3) +#define CPU_CR4_PSE (1 << 4) +#define CPU_CR4_PAE (1 << 5) +#define CPU_CR4_MCE (1 << 6) +#define CPU_CR4_PGE (1 << 7) +#define CPU_CR4_PCE (1 << 8) +#define CPU_CR4_OSFXSR (1 << 9) +#define CPU_CR4_OSXMMEXCPT (1 << 10) + + +void ia32_initialize(void); + +void ia32reset(void); +void ia32(void); +void ia32withtrap(void); +void ia32withdma(void); + +void ia32_step(void); +void CPUCALL ia32_interrupt(BYTE vect); +void CPUCALL ia32_exception(DWORD vect, DWORD p1, DWORD p2); + +void exec_1step(void); +#define INST_PREFIX (1 << 0) +#define INST_STRING (1 << 1) +#define REP_CHECKZF (1 << 7) + +void disasm(WORD cs, DWORD maddr); + +void ia32_printf(const char *buf, ...); +void ia32_warning(const char *buf, ...); +void ia32_panic(const char *buf, ...); + +void ia32_bioscall(void); + +void FASTCALL change_pm(BOOL onoff); +void FASTCALL change_vm(BOOL onoff); + +extern BYTE szpcflag[0x200]; +extern BYTE szpflag_w[0x10000]; + +extern BYTE *reg8_b20[0x100]; +extern BYTE *reg8_b53[0x100]; +extern WORD *reg16_b20[0x100]; +extern WORD *reg16_b53[0x100]; +extern DWORD *reg32_b20[0x100]; +extern DWORD *reg32_b53[0x100]; + + +// ---- i286 + +typedef struct { + SINT32 remainclock; + SINT32 baseclock; + UINT32 clock; + + UINT32 adrsmask; // ? + UINT32 inport; // ? + UINT8 resetreq; + UINT8 itfbank; +} I386STAT; + +typedef struct { // for ver0.73 + BYTE *ext; + UINT32 extsize; +} I386EXT; + +typedef struct { + I386STAT s; // STATsave、オ、、ナロ + I386EXT e; +} I386CORE; + +extern I386CORE i386core; + +#define CPU_STATSAVE i386core.s + +#define CPU_REMCLOCK i386core.s.remainclock +#define CPU_BASECLOCK i386core.s.baseclock +#define CPU_CLOCK i386core.s.clock +#define CPU_ADRSMASK i386core.s.adrsmask +#define CPU_RESETREQ i386core.s.resetreq +#define CPU_ITFBANK i386core.s.itfbank +#define CPU_INPADRS i386core.s.inport + +#define CPU_EXTMEM i386core.e.ext +#define CPU_EXTMEMSIZE i386core.e.extsize + +#ifdef __cplusplus +} +#endif + +#endif /* !IA32_CPU_CPU_H__ */ diff --git a/i386c/ia32/cpu_io.c b/i386c/ia32/cpu_io.c new file mode 100644 index 00000000..8fe01e38 --- /dev/null +++ b/i386c/ia32/cpu_io.c @@ -0,0 +1,123 @@ +/* $Id: cpu_io.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "pccore.h" +#include "iocore.h" + + +static void +check_io(WORD port, int len) +{ + WORD off; + BYTE bit; + BYTE map; + + /* 、ス、筅ス、 I/O オイト・゙・テ・ラ、ャフオ、、セケ */ + if (CPU_STAT_IOLIMIT == 0) { + EXCEPTION(GP_EXCEPTION, 0); + } + + off = port / 8; + bit = 1 << (port % 8); + for (; len > 0; ++off, bit = 0x01) { + /* I/O オイト・゙・テ・ラ、マ・モ・テ・ネテアーフ、ハ、ホ、ヌ */ + if (off * 8 >= CPU_STAT_IOLIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + + map = cpu_lmemoryread(CPU_STAT_IOADDR + off); + for (; (len > 0) && (bit != 0x00); bit <<= 1, --len) { + if (map & bit) { + EXCEPTION(GP_EXCEPTION, 0); + } + } + } +} + +BYTE +cpu_in(WORD port) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 1); + } + return iocore_inp8(port); +} + +WORD +cpu_in_w(WORD port) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 2); + } + return iocore_inp16(port); +} + +DWORD +cpu_in_d(WORD port) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 4); + } + return iocore_inp32(port); +} + +void +cpu_out(WORD port, BYTE data) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 1); + } + iocore_out8(port, data); +} + +void +cpu_out_w(WORD port, WORD data) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 2); + } + iocore_out16(port, data); +} + +void +cpu_out_d(WORD port, DWORD data) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 4); + } + iocore_out32(port, data); +} diff --git a/i386c/ia32/cpu_io.h b/i386c/ia32/cpu_io.h new file mode 100644 index 00000000..2afb99a5 --- /dev/null +++ b/i386c/ia32/cpu_io.h @@ -0,0 +1,48 @@ +/* $Id: cpu_io.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_CPU_IO_H__ +#define IA32_CPU_CPU_IO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +BYTE cpu_in(WORD port); +WORD cpu_in_w(WORD port); +DWORD cpu_in_d(WORD port); +void cpu_out(WORD port, BYTE val); +void cpu_out_w(WORD port, WORD val); +void cpu_out_d(WORD port, DWORD val); + +#ifdef __cplusplus +} +#endif + +#endif /* !IA32_CPU_CPU_IO_H__ */ diff --git a/i386c/ia32/cpu_mem.c b/i386c/ia32/cpu_mem.c new file mode 100644 index 00000000..ef60bafb --- /dev/null +++ b/i386c/ia32/cpu_mem.c @@ -0,0 +1,640 @@ +/* $Id: cpu_mem.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "memory.h" + +// 、「、ネ、ヌ。ト +extern DWORD cpumem_addrmask; + +BYTE *cpumem = 0; +DWORD extmem_size = 0; +BYTE protectmem_size = 0; + +/* + * initialize 1MB-16MB memory + */ + +int +init_cpumem(BYTE usemem) +{ + DWORD size; + + if (usemem > 13) + usemem = 13; + size = usemem << 20; + + if (extmem_size != size - (LOWMEM - 0x100000)) { + if (cpumem) { + free(cpumem); + cpumem = 0; + } + + if (size <= LOWMEM - 0x100000) { + extmem_size = 0; + cpumem = 0; + } else { + extmem_size = size - (LOWMEM - 0x100000); + cpumem = (BYTE*)malloc(extmem_size); + if (cpumem == NULL) { + protectmem_size = 0; + return FAILURE; + } + } + } + + if (cpumem) + memset(cpumem, 0, extmem_size); + + protectmem_size = usemem; + return SUCCESS; +} + + +/* + * memory access check + */ +void +cpu_memoryread_check(descriptor_t* sd, DWORD madr, DWORD length, int e) +{ + + if (!CPU_STAT_PM) { + if ((madr > sd->u.seg.segend - length + 1) + || (length - 1 > sd->u.seg.limit)) { + EXCEPTION(e, 0); + } + } else { + /* invalid */ + if (!sd->valid) { + EXCEPTION(GP_EXCEPTION, 0); + } + + /* not present */ + if (!sd->p) { + EXCEPTION(e, 0); + } + + switch (sd->type) { + case 0: case 1: /* ro */ + case 2: case 3: /* rw */ + case 10: case 11: /* rx */ + case 14: case 15: /* rxc */ + if ((madr > sd->u.seg.segend - length + 1) + || (length - 1 > sd->u.seg.limit)) { + EXCEPTION(e, 0); + } + break; + + case 4: case 5: /* ro (expand down) */ + case 6: case 7: /* rw (expand down) */ + { + DWORD uplimit = sd->d ? 0xffffffff : 0x0000ffff; + if ((madr <= sd->u.seg.segend) + || (madr > uplimit) + || (uplimit - madr < length - 1)) { + EXCEPTION(e, 0); + } + } + break; + + default: + EXCEPTION(e, 0); + break; + } + } +#if 0 /* XXX */ + sd->flag |= CPU_DESC_READABLE; +#endif +} + +void +cpu_memorywrite_check(descriptor_t* sd, DWORD madr, DWORD length, int e) +{ + + if (!CPU_STAT_PM) { + if ((madr > sd->u.seg.segend - length + 1) + || (length - 1 > sd->u.seg.limit)) { + EXCEPTION(e, 0); + } + } else { + /* invalid */ + if (!sd->valid) { + EXCEPTION(GP_EXCEPTION, 0); + } + + /* not present */ + if (!sd->p) { + EXCEPTION(e, 0); + } + + switch (sd->type) { + case 2: case 3: /* rw */ + if ((madr > sd->u.seg.segend - length + 1) + || (length - 1 > sd->u.seg.limit)) { + EXCEPTION(e, 0); + } + break; + + case 6: case 7: /* rw (expand down) */ + { + DWORD uplimit = sd->d ? 0xffffffff : 0x0000ffff; + if ((madr <= sd->u.seg.segend) + || (madr > uplimit) + || (uplimit - madr < length - 1)) { + EXCEPTION(e, 0); + } + } + break; + + default: + EXCEPTION(e, 0); + break; + } + } +#if 0 /* XXX */ + sd->flag |= CPU_DESC_WRITABLE; +#endif +} + +BOOL +cpu_stack_push_check(descriptor_t* sdp, DWORD esp, DWORD length) +{ + + if (!CPU_STAT_PM) + return TRUE; + + if (!sdp->valid || !sdp->p) + return FALSE; +#ifdef _DEBUG + if (!sdp->s || sdp->u.seg.c || !sdp->u.seg.wr) + return FALSE; +#endif + + if (!sdp->d) + esp &= 0xffff; + if (sdp->u.seg.ec) { + DWORD limit = (sdp->d) ? 0xffffffff : 0xffff; + if ((esp == 0) + || (esp < length) + || (esp - length <= sdp->u.seg.segend) + || (esp > limit)) + return FALSE; + } else { + /* expand-up stack */ + if (esp == 0) { + if ((sdp->d && (sdp->u.seg.segend != 0xffffffff)) + || (!sdp->d && (sdp->u.seg.segend != 0xffff))) + return FALSE; + } else { + if ((esp < length) + || (esp - 1 > sdp->u.seg.segend)) + return FALSE; + } + } + return TRUE; +} + +BOOL +cpu_stack_pop_check(descriptor_t* sdp, DWORD esp, DWORD length) +{ + DWORD limit; + + if (!CPU_STAT_PM) + return TRUE; + + if (!sdp->valid || !sdp->p) + return FALSE; +#ifdef _DEBUG + if (!sdp->s || sdp->u.seg.c || !sdp->u.seg.wr) + return FALSE; +#endif + + if (!sdp->d) { + esp &= 0xffff; + limit = 0xffff; + } else { + limit = 0xffffffff; + } + if (sdp->u.seg.ec) { + if ((esp == limit) + || ((limit - esp) + 1 < length)) + return FALSE; + } else { + /* expand-up stack */ + if ((esp == limit) + || (sdp->u.seg.segend == 0) + || (esp > sdp->u.seg.segend) + || ((sdp->u.seg.segend - esp) + 1 < length)) + return FALSE; + } + return TRUE; +} + + +/* + * code fetch + */ +BYTE MEMCALL +cpu_codefetch(DWORD madr) +{ + descriptor_t *sd; + DWORD addr; + + sd = &CPU_STAT_SREG(CPU_CS_INDEX); + if (!CPU_INST_AS32) + madr &= 0xffff; + if (madr <= sd->u.seg.segend) { + addr = CPU_STAT_SREGBASE(CPU_CS_INDEX) + madr; + if (!CPU_STAT_PM) + return cpu_memoryread(addr); + return cpu_lcmemoryread(addr); + } + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} + +WORD MEMCALL +cpu_codefetch_w(DWORD madr) +{ + descriptor_t *sd; + DWORD addr; + + sd = &CPU_STAT_SREG(CPU_CS_INDEX); + + if (!CPU_INST_AS32) + madr &= 0xffff; + if (madr <= sd->u.seg.segend) { + addr = CPU_STAT_SREGBASE(CPU_CS_INDEX) + madr; + if (!CPU_STAT_PM) + return cpu_memoryread_w(addr); + return cpu_lcmemoryread_w(addr); + } + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} + +DWORD MEMCALL +cpu_codefetch_d(DWORD madr) +{ + descriptor_t *sd; + DWORD addr; + + sd = &CPU_STAT_SREG(CPU_CS_INDEX); + if (!CPU_INST_AS32) + madr &= 0xffff; + if (madr <= sd->u.seg.segend) { + addr = CPU_STAT_SREGBASE(CPU_CS_INDEX) + madr; + if (!CPU_STAT_PM) + return cpu_memoryread_d(addr); + return cpu_lcmemoryread_d(addr); + } + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} + + +/* + * virtual address -> linear address + */ +BYTE MEMCALL +cpu_vmemoryread(int idx, DWORD madr) +{ + descriptor_t *sd; + DWORD addr; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sd = &CPU_STAT_SREG(idx); + if (!sd->valid) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (!CPU_INST_AS32) + madr &= 0xffff; + for (;;) { + if ((sd->flag & CPU_DESC_READABLE) + || (madr <= sd->u.seg.segend)) { + addr = CPU_STAT_SREGBASE(idx) + madr; + if (!CPU_STAT_PM) + return cpu_memoryread(addr); + return cpu_lmemoryread(addr); + } + cpu_memoryread_check(sd, madr, 1, + (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); + } + /*NOTREACHED*/ +} + +WORD MEMCALL +cpu_vmemoryread_w(int idx, DWORD madr) +{ + descriptor_t *sd; + DWORD addr; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sd = &CPU_STAT_SREG(idx); + if (!sd->valid) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (!CPU_INST_AS32) + madr &= 0xffff; + for (;;) { + if ((sd->flag & CPU_DESC_READABLE) + || (madr <= sd->u.seg.segend - 1)) { + addr = CPU_STAT_SREGBASE(idx) + madr; + if (!CPU_STAT_PM) + return cpu_memoryread_w(addr); + return cpu_lmemoryread_w(addr); + } + cpu_memoryread_check(sd, madr, 2, + (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); + } + /*NOTREACHED*/ +} + +DWORD MEMCALL +cpu_vmemoryread_d(int idx, DWORD madr) +{ + descriptor_t *sd; + DWORD addr; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sd = &CPU_STAT_SREG(idx); + if (!sd->valid) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (!CPU_INST_AS32) + madr &= 0xffff; + for (;;) { + if ((sd->flag & CPU_DESC_READABLE) + || (madr <= sd->u.seg.segend - 3)) { + addr = CPU_STAT_SREGBASE(idx) + madr; + if (!CPU_STAT_PM) + return cpu_memoryread_d(addr); + return cpu_lmemoryread_d(addr); + } + cpu_memoryread_check(sd, madr, 4, + (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); + } + /*NOTREACHED*/ +} + +/* vaddr memory write */ +void MEMCALL +cpu_vmemorywrite(int idx, DWORD madr, BYTE val) +{ + descriptor_t *sd; + DWORD addr; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sd = &CPU_STAT_SREG(idx); + if (!sd->valid) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (!CPU_INST_AS32) + madr &= 0xffff; + for (;;) { + if ((sd->flag & CPU_DESC_WRITABLE) + || (madr <= sd->u.seg.segend)) { + addr = CPU_STAT_SREGBASE(idx) + madr; + if (!CPU_STAT_PM) { + /* real mode */ + cpu_memorywrite(addr, val); + } else { + /* protected mode */ + cpu_lmemorywrite(addr, val); + } + return; + } + cpu_memorywrite_check(sd, madr, 1, + (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); + } + /*NOTREACHED*/ +} + +void MEMCALL +cpu_vmemorywrite_w(int idx, DWORD madr, WORD val) +{ + descriptor_t *sd; + DWORD addr; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sd = &CPU_STAT_SREG(idx); + if (!sd->valid) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (!CPU_INST_AS32) + madr &= 0xffff; + for (;;) { + if ((sd->flag & CPU_DESC_WRITABLE) + || (madr <= sd->u.seg.segend - 1)) { + addr = CPU_STAT_SREGBASE(idx) + madr; + if (!CPU_STAT_PM) { + /* real mode */ + cpu_memorywrite_w(addr, val); + } else { + /* protected mode */ + cpu_lmemorywrite_w(addr, val); + } + return; + } + cpu_memorywrite_check(sd, madr, 2, + (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); + } + /*NOTREACHED*/ +} + +void MEMCALL +cpu_vmemorywrite_d(int idx, DWORD madr, DWORD val) +{ + descriptor_t *sd; + DWORD addr; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sd = &CPU_STAT_SREG(idx); + if (!sd->valid) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (!CPU_INST_AS32) + madr &= 0xffff; + for (;;) { + if ((sd->flag & CPU_DESC_WRITABLE) + || (madr <= sd->u.seg.segend - 3)) { + addr = CPU_STAT_SREGBASE(idx) + madr; + if (!CPU_STAT_PM) { + /* real mode */ + cpu_memorywrite_d(addr, val); + } else { + /* protected mode */ + cpu_lmemorywrite_d(addr, val); + } + return; + } + cpu_memorywrite_check(sd, madr, 4, + (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); + } + /*NOTREACHED*/ +} + +/* + * physical address memory function + */ +void MEMCALL +cpu_memorywrite_d(DWORD address, DWORD value) +{ + DWORD adr = address & cpumem_addrmask; + + if (adr < LOWMEM - 3) { + __i286_memorywrite_d(adr, value); + } else if (adr < LOWMEM) { + cpu_memorywrite_w(adr, value & 0xffff); + cpu_memorywrite_w(adr + 2, (value >> 16) & 0xffff); + } else { + adr -= LOWMEM; + if (adr < extmem_size) { + SETDWORD(cpumem + adr, value); + } else { + ia32_panic("cpu_memorywrite_d: out of universe."); + } + } +} + +void MEMCALL +cpu_memorywrite_w(DWORD address, WORD value) +{ + DWORD adr = address & cpumem_addrmask; + + if (adr < LOWMEM - 1) { + __i286_memorywrite_w(adr, value); + } else if (adr < LOWMEM) { + __i286_memorywrite(adr, value & 0xff); + cpumem[adr - (LOWMEM - 1)] = (value >> 8) & 0xff; + } else { + adr -= LOWMEM; + if (adr < extmem_size) { + SETWORD(cpumem + adr, value); + } else { + ia32_panic("cpu_memorywrite_w: out of universe."); + } + } +} + +void MEMCALL +cpu_memorywrite(DWORD address, BYTE value) +{ + DWORD adr = address & cpumem_addrmask; + + if (adr < LOWMEM) { + __i286_memorywrite(adr, value); + } else { + adr -= LOWMEM; + if (adr < extmem_size) { + cpumem[adr] = value; + } else { + ia32_panic("cpu_memorywrite: out of universe."); + } + } +} + +DWORD MEMCALL +cpu_memoryread_d(DWORD address) +{ + DWORD adr = address & cpumem_addrmask; + DWORD val; + + if (adr < LOWMEM - 3) { + val = __i286_memoryread_d(adr); + } else if (adr < LOWMEM) { + val = cpu_memoryread_w(adr); + val |= (DWORD)cpu_memoryread_w(adr + 2) << 16; + } else { + adr -= LOWMEM; + if (adr < extmem_size) { + val = GETDWORD(cpumem + adr); + } else { + val = (DWORD)-1; + ia32_panic("cpu_memoryread_d: out of universe."); + } + } + return val; +} + +WORD MEMCALL +cpu_memoryread_w(DWORD address) +{ + DWORD adr = address & cpumem_addrmask; + WORD val; + + if (adr < LOWMEM - 1) { + val = __i286_memoryread_w(adr); + } else if (adr < LOWMEM) { + val = cpu_memoryread(adr); + val |= (WORD)cpumem[adr - (LOWMEM - 1)] << 8; + } else { + adr -= LOWMEM; + if (adr < extmem_size) { + val = GETWORD(cpumem + adr); + } else { + val = (WORD)-1; + ia32_panic("cpu_memoryread_w: out of universe."); + } + } + return val; +} + +BYTE MEMCALL +cpu_memoryread(DWORD address) +{ + DWORD adr = address & cpumem_addrmask; + BYTE val; + + if (adr < LOWMEM) { + val = __i286_memoryread(adr); + } else { + adr -= LOWMEM; + if (adr < extmem_size) { + val = cpumem[adr]; + } else { + val = (BYTE)-1; + ia32_panic("cpu_memoryread: out of universe."); + } + } + return val; +} diff --git a/i386c/ia32/cpu_mem.h b/i386c/ia32/cpu_mem.h new file mode 100644 index 00000000..18a7ed6d --- /dev/null +++ b/i386c/ia32/cpu_mem.h @@ -0,0 +1,86 @@ +/* $Id: cpu_mem.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_CPU_MEM_H__ +#define IA32_CPU_CPU_MEM_H__ + +#include "segments.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern BYTE *cpumem; +extern BYTE protectmem_size; +extern DWORD extmem_size; + +int init_cpumem(BYTE usemem); + +/* + * memory access check + */ +void cpu_memoryread_check(descriptor_t* sd, DWORD madr, DWORD length, int e); +void cpu_memorywrite_check(descriptor_t* sd, DWORD madr, DWORD length, int e); +BOOL cpu_stack_push_check(descriptor_t* sd, DWORD madr, DWORD length); +BOOL cpu_stack_pop_check(descriptor_t* sd, DWORD madr, DWORD length); +#define CHECK_STACK_PUSH(sdp, addr, n) cpu_stack_push_check(sdp, addr, n) +#define CHECK_STACK_POP(sdp, addr, n) cpu_stack_pop_check(sdp, addr, n) + +/* + * physcal address function + */ +void MEMCALL cpu_memorywrite(DWORD address, BYTE value); +void MEMCALL cpu_memorywrite_w(DWORD address, WORD value); +void MEMCALL cpu_memorywrite_d(DWORD address, DWORD value); +BYTE MEMCALL cpu_memoryread(DWORD address); +WORD MEMCALL cpu_memoryread_w(DWORD address); +DWORD MEMCALL cpu_memoryread_d(DWORD address); + +/* + * virtual address function + */ +void MEMCALL cpu_vmemorywrite(int idx, DWORD address, BYTE value); +void MEMCALL cpu_vmemorywrite_w(int idx, DWORD address, WORD value); +void MEMCALL cpu_vmemorywrite_d(int idx, DWORD address, DWORD value); +BYTE MEMCALL cpu_vmemoryread(int idx, DWORD address); +WORD MEMCALL cpu_vmemoryread_w(int idx, DWORD address); +DWORD MEMCALL cpu_vmemoryread_d(int idx, DWORD address); + +/* + * code fetch + */ +BYTE MEMCALL cpu_codefetch(DWORD madr); +WORD MEMCALL cpu_codefetch_w(DWORD madr); +DWORD MEMCALL cpu_codefetch_d(DWORD madr); + +#ifdef __cplusplus +} +#endif + +#endif /* !IA32_CPU_CPU_MEM_H__ */ diff --git a/i386c/ia32/ctrlxfer.c b/i386c/ia32/ctrlxfer.c new file mode 100644 index 00000000..82218aac --- /dev/null +++ b/i386c/ia32/ctrlxfer.c @@ -0,0 +1,995 @@ +/* $Id: ctrlxfer.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "ctrlxfer.h" + + +void +JMPfar_pm(WORD selector, DWORD new_ip) +{ + selector_t jmp_sel; + selector_t sel2; + int rv; + + VERBOSE(("JMPfar_pm: selector = 0x%04x, new_ip = 0x%08x", selector, new_ip)); + + /* + * IF effective address in the CS, DS, ES, FS, GS, or SS segment is illegal + * OR segment selector in target operand null + * THEN #GP(0); + * FI; + */ + /* XXX */ + + rv = parse_selector(&jmp_sel, selector); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + } + + if (jmp_sel.desc.s) { + /* code segment descriptor */ + if (!jmp_sel.desc.u.seg.c) { + /* data segment */ + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + } + + /* check privilege level */ + if (!jmp_sel.desc.u.seg.ec) { + VERBOSE(("NONCONFORMING-CODE-SEGMENT")); + /* イシエャ p.119 4.8.1.1. */ + if ((jmp_sel.rpl > CPU_STAT_CPL) + || (jmp_sel.desc.dpl != CPU_STAT_CPL)) { + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + } + } else { + VERBOSE(("CONFORMING-CODE-SEGMENT")); + /* イシエャ p.120 4.8.1.2. */ + if (jmp_sel.desc.dpl > CPU_STAT_CPL) { + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + } + } + + /* not present */ + if (selector_is_not_present(&jmp_sel)) { + EXCEPTION(NP_EXCEPTION, jmp_sel.idx); + } + + if (!CPU_INST_OP32) { + new_ip &= 0xffff; + } + + /* out of range */ + if (new_ip > jmp_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + load_cs(jmp_sel.selector, &jmp_sel.desc, CPU_STAT_CPL); + SET_EIP(new_ip); + } else { + /* system descriptor */ + switch (jmp_sel.desc.type) { + case CPU_SYSDESC_TYPE_CALL_16: + case CPU_SYSDESC_TYPE_CALL_32: + VERBOSE(("CALL-GATE")); + + /* check privilege level */ + if ((jmp_sel.desc.dpl < CPU_STAT_CPL) + || (jmp_sel.desc.dpl < jmp_sel.rpl)) { + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&jmp_sel)) { + EXCEPTION(NP_EXCEPTION, jmp_sel.idx); + } + + /* parse call gate selector */ + rv = parse_selector(&sel2, jmp_sel.desc.u.gate.selector); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, sel2.idx); + } + + /* check code segment descriptor */ + if (!sel2.desc.s || !sel2.desc.u.seg.c) { + EXCEPTION(GP_EXCEPTION, sel2.idx); + } + + /* check privilege level */ + if (!sel2.desc.u.seg.ec) { + /* イシエャ p.119 4.8.1.1. */ + if ((sel2.rpl > CPU_STAT_CPL) + || (sel2.desc.dpl != CPU_STAT_CPL)) { + EXCEPTION(GP_EXCEPTION, sel2.idx); + } + } else { + /* イシエャ p.120 4.8.1.2. */ + if (sel2.desc.dpl > CPU_STAT_CPL) { + EXCEPTION(GP_EXCEPTION, sel2.idx); + } + } + + /* not present */ + if (selector_is_not_present(&sel2)) { + EXCEPTION(NP_EXCEPTION, sel2.idx); + } + + new_ip = jmp_sel.desc.u.gate.offset; + if (jmp_sel.desc.type == CPU_SYSDESC_TYPE_CALL_16) { + new_ip &= 0xffff; + } + + /* out of range */ + if (new_ip > sel2.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + load_cs(sel2.selector, &sel2.desc, CPU_STAT_CPL); + SET_EIP(new_ip); + break; + + /* + * テ豢ャ p.373 JMP フソホ + * + * JMP フソホ皃ヌ・ソ・ケ・ッ。ヲ・ケ・、・テ・チ、シツケヤ、ケ、、ネ、ュ、マ EFLAGS ・・ク・ケ・ソ、ヒ + * ・ヘ・ケ・ネ、オ、、ソ・ソ・ケ・ッ。ヲ・ユ・鬣ー (NT) 、ャ・サ・テ・ネ、オ、、コ。「ソキ、キ、、 TSS 、ホ + * ーハチー、ホ・ソ・ケ・ッ。ヲ・・・ッ。ヲ・ユ・」。シ・・ノ、ヒチー、ホ・ソ・ケ・ッ、ホ TSS ・サ・・ッ・ソ、ャ + * ・。シ・ノ、オ、、ハ、、、ホ、ヌテーユ、オ、、ソ、、。」、キ、ソ、ャ、テ、ニ。「チー、ホ・ソ・ケ・ッ、リ、ホ + * ・・ソ。シ・、マ IRET フソホ皃ホシツケヤ、ヌ、マシツクス、ヌ、ュ、ハ、、。」JMP フソホ皃ヌ + * ・ソ・ケ・ッ。ヲ・ケ・、・テ・チ、シツケヤ、ケ、、ホ、マ。「、ス、ホナタ、ヌ CALL フソホ皃ネーロ、ハ、。」 + * 、ケ、ハ、、チ。「CALL フソホ皃マ NT ・ユ・鬣ー、・サ・テ・ネ、キ。「ーハチー、ホ + * ・ソ・ケ・ッ。ヲ・・・ッセハ、・サ。シ・ヨ、ケ、、ホ、ヌ。「IRET フソホ皃ヌ、ホ・ウ。シ・クオ + * ・ソ・ケ・ッ、リ、ホ・・ソ。シ・、ャイトヌス、ヒ、ハ、。」 + */ + case CPU_SYSDESC_TYPE_TASK: + VERBOSE(("TASK-GATE")); + + /* check privilege level */ + if ((jmp_sel.desc.dpl < CPU_STAT_CPL) + || (jmp_sel.desc.dpl < jmp_sel.rpl)) { + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&jmp_sel)) { + EXCEPTION(NP_EXCEPTION, jmp_sel.idx); + } + + /* parse call tss selector */ + rv = parse_selector(&sel2, jmp_sel.desc.u.gate.selector); + if (rv < 0 || sel2.ldt) { + EXCEPTION(GP_EXCEPTION, sel2.idx); + } + + /* check descriptor type */ + switch (sel2.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + break; + + default: + EXCEPTION(GP_EXCEPTION, sel2.idx); + break; + } + + /* not present */ + if (selector_is_not_present(&sel2)) { + EXCEPTION(NP_EXCEPTION, sel2.idx); + } + + task_switch(&sel2, TASK_SWITCH_JMP); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + break; + + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + VERBOSE(("TASK-STATE-SEGMENT")); + + /* check privilege level */ + if ((jmp_sel.desc.dpl < CPU_STAT_CPL) + || (jmp_sel.desc.dpl < jmp_sel.rpl)) { + EXCEPTION(TS_EXCEPTION, jmp_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&jmp_sel)) { + EXCEPTION(NP_EXCEPTION, jmp_sel.idx); + } + + task_switch(&jmp_sel, TASK_SWITCH_JMP); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("JMPfar_pm: task is busy")); + /*FALLTHROUGH*/ + default: + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + break; + } + } +} + +/* + * 4.3.6. ニテク「・・ル・エヨ、ホ・ウ。シ・チ犲 + * + * 1. ・「・ッ・サ・ケク「、ホ・チ・ァ・テ・ッ(ニテク「・チ・ァ・テ・ッ)、シツケヤ、ケ、。」 + * 2. SS, ESP, CS, EIP 、ホウニ・・ク・ケ・ソ、ホクスコ゚テマ、ーサナェ、ヒニ篷、ヒ・サ。シ・ヨ、ケ、。」 + * 3. TSS ・・ク・ケ・ソ、ヒウハヌシ、オ、、ニ、、、ソキ、キ、、・ケ・ソ・テ・ッ(、ケ、ハ、、チ。「クスコ゚・ウ。シ・、オ、、ニ、、、 + * ニテク「・・ル・ヘム、ホ・ケ・ソ・テ・ッ)、ホ・サ・ー・皈・ネ・・ク・ケ・ソ、ネ・ケ・ソ・テ・ッ・ン・、・・ソ、 + * SS ・・ク・ケ・ソ、ネ ESP ・・ク・ケ・ソ、ヒ・。シ・ノ、キ。「ソキ、キ、、・ケ・ソ・テ・ッ、ヒタレ、ツリ、ィ、。」 + * 4. ・ウ。シ・クオ・ラ・・キ。シ・ク・网ホ・ケ・ソ・テ・ッ、ヒツミ、キ、ニーサナェ、ヒ・サ。シ・ヨ、キ、ニ、ェ、、、ソ SS テヘ、ネ + * ESP テヘ、。「、ウ、ホソキ、キ、、・ケ・ソ・テ・ッ、ヒ・ラ・テ・キ・螟ケ、。」 + * 5. ・ウ。シ・クオ・ラ・・キ。シ・ク・网ホ・ケ・ソ・テ・ッ、ォ、鬣ム・鬣癸シ・ソ、・ウ・ヤ。シ、ケ、。」ソキ、キ、、・ケ・ソ・テ・ッ + * 、ヒ・ウ・ヤ。シ、オ、、・ム・鬣癸シ・ソ、ホソ、マ。「・ウ。シ・。ヲ・イ。シ・ネ。ヲ・ヌ・」・ケ・ッ・・ラ・ソニ筅ホテヘ、ヌ + * キ隍゙、。」 + * 6. ・ウ。シ・クオ・ラ・・キ。シ・ク・网ヒツミ、キ、ニーサナェ、ヒ・サ。シ・ヨ、キ、ニ、ェ、、、ソ CS テヘ、ネ EIP テヘ、。「 + * ソキ、キ、、・ケ・ソ・テ・ッ、ヒ・ラ・テ・キ・螟ケ、。」 + * 7. ソキ、キ、、・ウ。シ・ノ。ヲ・サ・ー・皈・ネ、ホ・サ・ー・皈・ネ。ヲ・サ・・ッ・ソ、ネソキ、キ、、フソホ皈ン・、・・ソ、。「 + * ・ウ。シ・。ヲ・イ。シ・ネ、ォ、 CS ・・ク・ケ・ソ、ネ EIP ・・ク・ケ・ソ、ヒ、ス、、セ、・。シ・ノ、ケ、。」 + * 8. ・ウ。シ・、オ、、ソ・ラ・・キ。シ・ク・网ホシツケヤ、ソキ、キ、、ニテク「・・ル・、ヌウォサマ、ケ、。」 + */ +void +CALLfar_pm(WORD selector, DWORD new_ip) +{ + selector_t call_sel; + selector_t sel2; + int rv; + + VERBOSE(("CALLfar_pm: selector = 0x%04x, new_ip = 0x%08x", selector, new_ip)); + + rv = parse_selector(&call_sel, selector); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + + if (call_sel.desc.s) { + /* code segment descriptor */ + if (!call_sel.desc.u.seg.c) { + /* data segment */ + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + + /* check privilege level */ + if (!call_sel.desc.u.seg.ec) { + VERBOSE(("NONCONFORMING-CODE-SEGMENT")); + + /* イシエャ p.119 4.8.1.1. */ + if ((call_sel.rpl > CPU_STAT_CPL) + || (call_sel.desc.dpl != CPU_STAT_CPL)) { + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + } else { + VERBOSE(("CONFORMING-CODE-SEGMENT")); + + /* イシエャ p.120 4.8.1.2. */ + if (call_sel.desc.dpl > CPU_STAT_CPL) { + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + } + + /* not present */ + if (selector_is_not_present(&call_sel)) { + EXCEPTION(NP_EXCEPTION, call_sel.idx); + } + + if (CPU_INST_OP32) { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 8); + /* out of range */ + if (new_ip > call_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + PUSH0_32(CPU_CS); + PUSH0_32(CPU_EIP); + } else { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 4); + /* out of range */ + if (new_ip > call_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + PUSH0_16(CPU_CS); + PUSH0_16(CPU_IP); + new_ip &= 0xffff; + } + load_cs(call_sel.selector, &call_sel.desc, CPU_STAT_CPL); + SET_EIP(new_ip); + } else { + DWORD temp_eip, temp_esp; + WORD temp_cs, temp_ss; + + /* system descriptor */ + switch (call_sel.desc.type) { + case CPU_SYSDESC_TYPE_CALL_16: + case CPU_SYSDESC_TYPE_CALL_32: + VERBOSE(("CALL-GATE")); + + /* check privilege level */ + if ((call_sel.desc.dpl < CPU_STAT_CPL) + || (call_sel.desc.dpl < call_sel.rpl)) { + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&call_sel)) { + EXCEPTION(NP_EXCEPTION, call_sel.idx); + } + + /* parse code segment descriptor */ + rv = parse_selector(&sel2, call_sel.desc.u.gate.selector); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, sel2.idx); + } + + /* check code segment & privilege level */ + if (!sel2.desc.s + || !sel2.desc.u.seg.c + || sel2.desc.dpl > CPU_STAT_CPL) { + EXCEPTION(GP_EXCEPTION, sel2.idx); + } + + /* not present */ + if (selector_is_not_present(&sel2)) { + EXCEPTION(NP_EXCEPTION, sel2.idx); + } + + /* save register */ + temp_cs = CPU_CS; + temp_ss = CPU_SS; + temp_eip = CPU_EIP; + temp_esp = CPU_ESP; + if (sel2.desc.type == CPU_SYSDESC_TYPE_CALL_16) { + temp_eip &= 0xffff; + temp_esp &= 0xffff; + } + + new_ip = call_sel.desc.u.gate.offset; + + /* out of range */ + if (new_ip > sel2.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (!sel2.desc.u.seg.ec + && (sel2.desc.dpl < CPU_STAT_CPL)) { + DWORD param[32]; // copy param + selector_t ss_sel; + DWORD tss_esp; + WORD tss_ss; + BYTE i; + + VERBOSE(("MORE-PRIVILEGE")); + + get_stack_from_tss(sel2.desc.dpl, &tss_ss, &tss_esp); + + /* parse stack segment descriptor */ + rv = parse_selector(&ss_sel, tss_ss); + if (rv < 0) { + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + + /* check privilege level */ + if ((ss_sel.rpl != sel2.desc.dpl) + || (ss_sel.desc.dpl != sel2.desc.dpl) + || !ss_sel.desc.s + || !ss_sel.desc.u.seg.wr) { + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&ss_sel)) { + EXCEPTION(NP_EXCEPTION, ss_sel.idx); + } + + if (call_sel.desc.type == CPU_SYSDESC_TYPE_CALL_32){ + CHECK_STACK_PUSH(&ss_sel.desc, tss_esp, 16 + sel2.desc.u.gate.count * 4); + + /* dump param */ + for (i = 0; i < sel2.desc.u.gate.count; i++) { + param[i] = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP + i * 4); + } + + load_ss(tss_ss, &ss_sel.desc, ss_sel.desc.dpl); + CPU_ESP = tss_esp; + load_cs(sel2.selector, &sel2.desc, sel2.desc.dpl); + SET_EIP(new_ip); + + PUSH0_32(temp_ss); + PUSH0_32(temp_esp); + + /* restore param */ + for (i = sel2.desc.u.gate.count; i != 0; i--) { + PUSH0_32(param[i - 1]); + } + + PUSH0_32(temp_cs); + PUSH0_32(temp_eip); + } else { + CHECK_STACK_PUSH(&ss_sel.desc, tss_esp, 8 + sel2.desc.u.gate.count * 2); + + new_ip &= 0xffff; + + /* dump param */ + for (i = 0; i < sel2.desc.u.gate.count; i++) { + param[i] = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP + i * 2); + } + + load_ss(tss_ss, &ss_sel.desc, ss_sel.desc.dpl); + CPU_ESP = tss_esp & 0xffff; + load_cs(sel2.selector, &sel2.desc, sel2.desc.dpl); + SET_EIP(new_ip); + + PUSH0_16(temp_ss); + PUSH0_16(temp_esp); + + /* restore param */ + for (i = sel2.desc.u.gate.count; i != 0; i--) { + PUSH0_16(param[i - 1]); + } + + PUSH0_16(temp_cs); + PUSH0_16(temp_eip); + } + } else { + VERBOSE(("SAME-PRIVILEGE")); + + if (call_sel.desc.type == CPU_SYSDESC_TYPE_CALL_32){ + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 8); + + load_cs(sel2.selector, &sel2.desc, CPU_STAT_CPL); + SET_EIP(new_ip); + + PUSH0_32(temp_cs); + PUSH0_32(temp_eip); + } else { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 4); + + load_cs(sel2.selector, &sel2.desc, CPU_STAT_CPL); + new_ip &= 0xffff; + SET_EIP(new_ip); + + PUSH0_16(temp_cs); + PUSH0_16(temp_eip); + } + } + break; + + case CPU_SYSDESC_TYPE_TASK: + VERBOSE(("TASK-GATE")); + + /* check privilege level */ + if ((call_sel.desc.dpl < CPU_STAT_CPL) + || (call_sel.desc.dpl < call_sel.rpl)) { + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&call_sel)) { + EXCEPTION(NP_EXCEPTION, call_sel.idx); + } + + /* tss descriptor */ + rv = parse_selector(&sel2, call_sel.desc.u.gate.selector); + if (rv < 0 || sel2.ldt) { + EXCEPTION(GP_EXCEPTION, sel2.idx); + } + + /* check descriptor type */ + switch (sel2.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("CALLfar_pm: task is busy")); + /*FALLTHROUGH*/ + default: + EXCEPTION(GP_EXCEPTION, sel2.idx); + break; + } + + /* not present */ + if (selector_is_not_present(&sel2)) { + EXCEPTION(NP_EXCEPTION, sel2.idx); + } + + task_switch(&sel2, TASK_SWITCH_CALL); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + break; + + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + VERBOSE(("TASK-STATE-SEGMENT")); + + /* check privilege level */ + if ((call_sel.desc.dpl < CPU_STAT_CPL) + || (call_sel.desc.dpl < call_sel.rpl)) { + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&call_sel)) { + EXCEPTION(NP_EXCEPTION, call_sel.idx); + } + + task_switch(&call_sel, TASK_SWITCH_CALL); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("CALLfar_pm: task is busy")); + /*FALLTHROUGH*/ + default: + EXCEPTION(GP_EXCEPTION, call_sel.idx); + break; + } + } +} + +/* + * 4.3.6. ニテク「・・ル・エヨ、ホ・・ソ。シ・チ犲 + * + * 1. ニテク「・チ・ァ・テ・ッ、シツケヤ、ケ、。」 + * 2. CS ・・ク・ケ・ソ、ネ EIP ・・ク・ケ・ソ、ヒ・ウ。シ・チー、ホテヘ、・・ケ・ネ・「、ケ、。」 + * 3. RET フソホ皃ヒ・ェ・ラ・キ・逾ー、ュソ、ホ n 、ャ、「、セケ遉マ。「・ム・鬣癸シ・ソ、・ケ・ソ・テ・ッ、ォ、 + * ウォハ、ケ、、ソ、癸「n ・ェ・レ・鬣・ノ、ヌサリト熙オ、、ソ・ミ・、・ネソ、タ、ア・ケ・ソ・テ・ッ。ヲ・ン・、・・ソ、 + * ・、・・ッ・・皈・ネ、ケ、。」・ウ。シ・。ヲ・イ。シ・ネ。ヲ・ヌ・」・ケ・ッ・・ラ・ソ、ャ。「・ケ・ソ・テ・ッエヨ、ヌ + * 1 、トーハセ螟ホ・ム・鬣癸シ・ソ、・ウ・ヤ。シ、ケ、、隍ヲサリト熙キ、ニ、、、セケ遉マ。「RET n フソホ皃 + * サネヘム、キ、ニホセ・ケ・ソ・テ・ッ、ォ、鬣ム・鬣癸シ・ソ、ウォハ、キ、ハ、ア、、ミ、ハ、鬢ハ、、。」n ・ェ・レ・鬣・ノ + * 、ヒ、マ。「ウニ・ケ・ソ・テ・ッセ、ヌ・ム・鬣癸シ・ソ、ャタヘュ、ケ、・ミ・、・ネソ、サリト熙ケ、。」 + * ・・ソ。シ・サ、ヒ。「・ラ・・サ・テ・オ、マウニ・ケ・ソ・テ・ッ、ヒツミ、キ、ニ n 、タ、ア ESP 、・、・・ッ・・皈・ネ + * 、キ。「、ウ、、鬢ホ・ム・鬣癸シ・ソ、・ケ・ソ・テ・ッ、ォ、鮑ホィ、隍ッコス、ケ、。」 + * 4. SS ・・ク・ケ・ソ、ネ ESP ・・ク・ケ・ソ、ヒ。「・ウ。シ・チー、ホテヘ、・・ケ・ネ・「、ケ、。」、ウ、、ヌ。「 + * ・ウ。シ・クオ・ラ・・キ。シ・ク・网ホ・ケ・ソ・テ・ッ、リタレ、ツリ、ィ、鬢、。」 + * 5. RET フソホ皃ヒ・ェ・ラ・キ・逾ー、ュソ、ホ n 、ャ、「、セケ遉マ。「・ム・鬣癸シ・ソ、・ケ・ソ・テ・ッ、ォ、 + * ウォハ、ケ、、ソ、癸「n ・ェ・レ・鬣・ノ、ヌサリト熙オ、、ソ・ミ・、・ネソ、タ、ア・ケ・ソ・テ・ッ。ヲ・ン・、・・ソ、 + * ・、・・ッ・・皈・ネ、ケ、(・ケ・ニ・テ・ラ 3 、ホタ篶タ、サイセネ)。」 + * 6. ・ウ。シ・クオ・ラ・・キ。シ・ク・网ホシツケヤ、コニウォ、ケ、。」 + */ +void +RETfar_pm(DWORD nbytes) +{ + selector_t ret_sel; + int rv; + DWORD new_ip; + WORD selector; + + VERBOSE(("RETfar_pm: nbytes = %d", nbytes)); + + if (CPU_INST_OP32) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 8 + nbytes); + if (CPU_STAT_SS32) { + new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP); + selector = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP + 4); + } else { + new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_SP); + selector = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_SP + 4); + } + } else { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 4 + nbytes); + if (CPU_STAT_SS32) { + new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP); + selector = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP + 2); + } else { + new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP); + selector = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP + 2); + } + } + + rv = parse_selector(&ret_sel, selector); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, ret_sel.idx); + } + + /* check code segment descriptor */ + if (!ret_sel.desc.s || !ret_sel.desc.u.seg.c) { + EXCEPTION(GP_EXCEPTION, ret_sel.idx); + } + + /* check privilege level */ + if (ret_sel.rpl < CPU_STAT_CPL + || (ret_sel.desc.u.seg.ec && (ret_sel.desc.dpl > ret_sel.rpl))) { + EXCEPTION(GP_EXCEPTION, ret_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&ret_sel)) { + EXCEPTION(NP_EXCEPTION, ret_sel.idx); + } + + if (ret_sel.rpl > CPU_STAT_CPL) { + selector_t ss_sel; + selector_t temp_sel; + DWORD new_sp; + WORD new_ss; + int i; + + VERBOSE(("RETURN-OUTER-PRIVILEGE-LEVEL")); + + if (CPU_INST_OP32) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 16 + nbytes); + if (CPU_STAT_SS32) { + new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP + 8 + nbytes); + new_ss = (WORD)cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP + 8 + 4 + nbytes); + } else { + new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, (WORD)(CPU_SP + 8 + nbytes)); + new_ss = (WORD)cpu_vmemoryread_d(CPU_SS_INDEX, (WORD)(CPU_SP + 8 + 4 + nbytes)); + } + } else { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 8 + nbytes); + if (CPU_STAT_SS32) { + new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP + 4 + nbytes); + new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP + 4 + 2 + nbytes); + } else { + new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, (WORD)(CPU_SP + 4 + nbytes)); + new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, (WORD)(CPU_SP + 4 + 2 + nbytes)); + } + } + + rv = parse_selector(&ss_sel, new_ss); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } + + /* check stack segment descriptor */ + /* check privilege level */ + if ((ss_sel.rpl != ret_sel.rpl) + || (ss_sel.desc.dpl != ret_sel.rpl) + || !ss_sel.desc.s + || !ss_sel.desc.u.seg.wr) { + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&ss_sel)) { + EXCEPTION(SS_EXCEPTION, ss_sel.idx); + } + + /* check code segment limit */ + if (new_ip > ret_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + /* set new register */ + load_cs(ret_sel.selector, &ret_sel.desc, ret_sel.rpl); + SET_EIP(new_ip); + load_ss(ss_sel.selector, &ss_sel.desc, ret_sel.rpl); + CPU_ESP = new_sp; + + /* check segment register */ + for (i = 0; i < CPU_SEGREG_NUM; i++) { + if (i == CPU_CS_INDEX || i == CPU_SS_INDEX) + continue; + + rv = parse_selector(&temp_sel, CPU_REGS_SREG(i)); + if (rv < 0) { + CPU_REGS_SREG(i) = 0; + CPU_STAT_SREG(i).valid = 0; + continue; + } + + /* check privilege level */ + if (!temp_sel.desc.s + || (temp_sel.desc.u.seg.c && temp_sel.desc.u.seg.wr) + || ((!temp_sel.desc.u.seg.c || !temp_sel.desc.u.seg.ec) + && ((temp_sel.desc.dpl < CPU_STAT_CPL) || (temp_sel.desc.dpl < temp_sel.rpl)))) { + CPU_REGS_SREG(i) = 0; + CPU_STAT_SREG(i).valid = 0; + continue; + } + } + CPU_ESP += nbytes; + } else { + VERBOSE(("RETURN-TO-SAME-PRIVILEGE-LEVEL")); + + if (CPU_INST_OP32) { + if (new_ip > ret_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + POP0_32(CPU_EIP); + POP0_32(CPU_CS); + } else { + new_ip &= 0xffff; + if (new_ip > ret_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + POP0_16(CPU_EIP); + POP0_16(CPU_CS); + } + load_cs(ret_sel.selector, &ret_sel.desc, CPU_STAT_CPL); + SET_EIP(new_ip); + CPU_ESP += nbytes; + } +} + +void +IRET_pm() +{ + selector_t iret_sel; + int rv; + DWORD new_ip, new_flags; + WORD new_cs; + + VERBOSE(("IRET_pm")); + + if (CPU_STAT_VM86) { + /* RETURN-FROM-VIRTUAL-8086-MODE */ + VERBOSE(("Virtual-8086 mode: PE=1, VM=1")); + VERBOSE(("Processor is in virtual-8086 mode when IRET is executed and stays in virtual-8086 mode")); + + if (CPU_STAT_IOPL == CPU_IOPL3) { + VERBOSE(("Virtual mode: PE=1, VM=1, IOPL=3")); + if (CPU_INST_OP32) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 12); + POP0_32(new_ip); + POP0_32(new_cs); + POP0_32(new_flags); + + set_eflags(new_flags, I_FLAG|RF_FLAG); + } else { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 6); + POP0_16(new_ip); + POP0_16(new_cs); + POP0_16(new_flags); + + set_flags(new_flags, I_FLAG); + } + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + return; + } + VERBOSE(("trap to virtual-8086 monitor: PE=1, VM=1, IOPL<3")); + EXCEPTION(GP_EXCEPTION, 0); + } else if (CPU_EFLAG & NT_FLAG) { + VERBOSE(("TASK-RETURN: PE=1, VM=0, NT=1")); + + new_cs = get_link_selector_from_tss(); + rv = parse_selector(&iret_sel, new_cs); + if (rv < 0 || iret_sel.ldt) { + EXCEPTION(GP_EXCEPTION, iret_sel.idx); + } + + /* check system segment */ + if (iret_sel.desc.s) { + EXCEPTION(GP_EXCEPTION, iret_sel.idx); + } + switch (iret_sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + break; + + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + VERBOSE(("IRET_pm: task is not busy")); + /*FALLTHROUGH*/ + default: + EXCEPTION(GP_EXCEPTION, iret_sel.idx); + break; + } + + /* not present */ + if (selector_is_not_present(&iret_sel)) { + EXCEPTION(NP_EXCEPTION, iret_sel.idx); + } + + task_switch(&iret_sel, TASK_SWITCH_IRET); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + } else { + if (CPU_INST_OP32) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 12); + POP0_32(new_ip); + POP0_32(new_cs); + POP0_32(new_flags); + } else { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 6); + POP0_16(new_ip); + POP0_16(new_cs); + POP0_16(new_flags); + } + + if ((CPU_STAT_CPL == 0) && (new_flags & VM_FLAG)) { + /* RETURN-TO-VIRTUAL-8086-MODE */ + descriptor_t sd; + DWORD new_sp; + WORD segsel[CPU_SEGREG_NUM]; + int i; + + VERBOSE(("Interrupt procedure was in virtual-8086 mode: PE=1, VM=1 in flags image")); + + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 24); + + segsel[CPU_CS_INDEX] = new_cs; + POP0_32(new_sp); + POP0_32(segsel[CPU_SS_INDEX]); + POP0_32(segsel[CPU_ES_INDEX]); + POP0_32(segsel[CPU_DS_INDEX]); + POP0_32(segsel[CPU_FS_INDEX]); + POP0_32(segsel[CPU_GS_INDEX]); + + for (i = 0; i < CPU_SEGREG_NUM; i++) { + CPU_REGS_SREG(i) = segsel[i]; + sd.u.seg.limit = 0xffff; + CPU_SET_SEGDESC_DEFAULT(&sd, i, segsel[i]); + sd.dpl = 3; + CPU_STAT_SREG(i) = sd; + } + CPU_ESP = new_sp; + SET_EIP(new_ip & 0xffff); + + set_eflags(new_flags, IOPL_FLAG|RF_FLAG); + } else { + DWORD mask; + + /* PROTECTED-MODE-RETURN */ + VERBOSE(("PE=1, VM=0 in flags image")); + + rv = parse_selector(&iret_sel, new_cs); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, iret_sel.idx); + } + + /* check code segment descriptor */ + if (!iret_sel.desc.s || !iret_sel.desc.u.seg.c) { + EXCEPTION(GP_EXCEPTION, iret_sel.idx); + } + + /* check privilege level */ + if ((iret_sel.rpl < CPU_STAT_CPL) + || (iret_sel.desc.u.seg.ec && (iret_sel.desc.dpl > iret_sel.rpl))) { + EXCEPTION(GP_EXCEPTION, iret_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&iret_sel)) { + EXCEPTION(NP_EXCEPTION, iret_sel.idx); + } + + if (iret_sel.rpl > CPU_STAT_CPL) { + /* RETURN-OUTER-PRIVILEGE-LEVEL */ + selector_t ss_sel; + WORD new_sp, new_ss; + + if (CPU_INST_OP32) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 8); + if (CPU_STAT_SS32) { + new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP); + new_ss = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP + 4); + } else { + new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_SP); + new_ss = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_SP + 4); + } + } else { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 4); + if (CPU_STAT_SS32) { + new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP); + new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP + 2); + } else { + new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP); + new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP + 2); + } + } + + rv = parse_selector(&ss_sel, new_ss); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } + + /* check stack segment descriptor */ + /* check privilege level */ + if ((ss_sel.rpl != iret_sel.rpl) + || (ss_sel.desc.dpl != iret_sel.rpl) + || !ss_sel.desc.s + || !ss_sel.desc.u.seg.wr) { + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&ss_sel)) { + EXCEPTION(SS_EXCEPTION, ss_sel.idx); + } + } else { + VERBOSE(("RETURN-TO-SAME-PRIVILEGE-LEVEL")); + } + + /* check code segment limit */ + if (new_ip > iret_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + /* set new register */ + load_cs(iret_sel.selector, &iret_sel.desc, iret_sel.rpl); + SET_EIP(new_ip); + + mask = 0; + if (CPU_INST_OP32) + mask |= RF_FLAG; + if (CPU_STAT_CPL <= CPU_STAT_IOPL) + mask |= I_FLAG; + if (CPU_STAT_CPL == 0) { + mask |= IOPL_FLAG; + if (CPU_INST_OP32) + mask |= VM_FLAG|VIF_FLAG|VIP_FLAG; + } + set_eflags(new_flags, mask); + + if (iret_sel.rpl > CPU_STAT_CPL) { + selector_t temp_sel; + int i; + + /* RETURN-OUTER-PRIVILEGE-LEVEL */ + /* check segment register */ + for (i = 0; i < CPU_SEGREG_NUM; i++) { + if ((i == CPU_CS_INDEX) || (i == CPU_SS_INDEX)) + continue; + + rv = parse_selector(&temp_sel, CPU_REGS_SREG(i)); + if (rv < 0) { + CPU_REGS_SREG(i) = 0; + CPU_STAT_SREG(i).valid = 0; + continue; + } + + if ((!temp_sel.desc.u.seg.c || !temp_sel.desc.u.seg.ec) + && (CPU_STAT_CPL > temp_sel.desc.dpl)) { + CPU_REGS_SREG(i) = 0; + CPU_STAT_SREG(i).valid = 0; + continue; + } + } + } + } + } +} diff --git a/i386c/ia32/ctrlxfer.h b/i386c/ia32/ctrlxfer.h new file mode 100644 index 00000000..96aa9a1e --- /dev/null +++ b/i386c/ia32/ctrlxfer.h @@ -0,0 +1,46 @@ +/* $Id: ctrlxfer.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_CTRLXFER_H__ +#define IA32_CPU_CTRLXFER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void JMPfar_pm(WORD selector, DWORD new_ip); +void CALLfar_pm(WORD selector, DWORD new_ip); +void RETfar_pm(DWORD nbytes); +void IRET_pm(); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_CTRLXFER_H__ */ diff --git a/i386c/ia32/debug.c b/i386c/ia32/debug.c new file mode 100644 index 00000000..f01e896b --- /dev/null +++ b/i386c/ia32/debug.c @@ -0,0 +1,184 @@ +/* $Id: debug.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cpu.h" +#ifdef USE_FPU + #include "instructions/fpu/fpu.h" +#endif + +extern BOOL is_a20(void); /* in ../cpuio.c */ + +static char *cpu_reg2str(void) +{ + static char buf[512]; + + sprintf(buf, + "eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n" + "eip=%08x esp=%08x ebp=%08x prev_eip=%08x\n" + "cs=%04x ss=%04x ds=%04x es=%04x fs=%04x gs=%04x\n" + "eflag=%08x " +/* ID VIP VIF AC VM RF NT IOPL OF DF IF TF SF ZF AF PF CF */ + "[ ID=%d VIP=%d VIF=%d AC=%d VM=%d RF=%d NT=%d IOPL=%d%d %s %s %s TF=%d %s %s %s %s %s ]\n" + "gdtr=%08x:%04x idtr=%08x:%04x ldtr=%04x tr=%04x\n" + "cr0=%08x cr1=%08x cr2=%08x cr3=%08x cr4=%08x mxcsr=%08x\n", + I286_EAX, I286_EBX, I286_ECX, I286_EDX, I286_ESI, I286_EDI, + I286_EIP, I286_ESP, I286_EBP, CPU_PREV_EIP, + I286_CS, I286_SS, I286_DS, I286_ES, I286_FS, I286_GS, + I286_EFLAG, + (I286_EFLAG & ID_FLAG) != 0, + (I286_EFLAG & VIP_FLAG) != 0, + (I286_EFLAG & VIF_FLAG) != 0, + (I286_EFLAG & AC_FLAG) != 0, + (I286_EFLAG & VM_FLAG) != 0, + (I286_EFLAG & RF_FLAG) != 0, + (I286_EFLAG & NT_FLAG) != 0, + I286_EFLAG >> 13 & 1, + I286_EFLAG >> 12 & 1, + I286_EFLAG & O_FLAG ? "OV" : "NV", + I286_EFLAG & D_FLAG ? "UP" : "DN", + I286_EFLAG & I_FLAG ? "DI" : "EI", + (I286_EFLAG & T_FLAG) != 0, + I286_EFLAG & S_FLAG ? "NG" : "PL", + I286_EFLAG & Z_FLAG ? "ZR" : "NZ", + I286_EFLAG & A_FLAG ? "AC" : "NA", + I286_EFLAG & P_FLAG ? "PE" : "PO", + I286_EFLAG & C_FLAG ? "CY" : "NC", + CPU_GDTR_BASE, CPU_GDTR_LIMIT, CPU_IDTR_BASE, CPU_IDTR_LIMIT, CPU_LDTR, CPU_TR, + CPU_CR0, CPU_CR1, CPU_CR2, CPU_CR3, CPU_CR4, CPU_MXCSR); + + return buf; +} + +#ifdef USE_FPU +static char *fpu_reg2str(void) +{ + static char buf[512]; + char tmp[128]; + int i; + int no; + + strcpy(buf, "st=\n"); + for(no = 0; no < 8; no++) + { + for(i = 9; i >= 0; i--) + { + sprintf(tmp, "%02x", FPU_ST[no][i]); + strcat(buf, tmp); + } + strcat(buf, "\n"); + } + + sprintf(tmp, + "ctrl=%04x status=%04x tag=%04x\n" + "inst=%08x%04x data=%08x%04x op=%03x\n", + FPU_CTRLWORD, + FPU_STATUSWORD, + FPU_TAGWORD, + FPU_INSTPTR_OFFSET, FPU_INSTPTR_SEG, + FPU_DATAPTR_OFFSET, FPU_DATAPTR_SEG, + FPU_LASTINSTOP); + strcat(buf, tmp); + + return buf; +} +#endif + +static char *a20str(void) +{ + static char buf[32]; + + sprintf(buf, "a20line=%s\n", is_a20() ? "enable" : "disable"); + return buf; +} + +static char *mem2str(DWORD cs, DWORD ip) +{ + static char buf[128]; + char tmp[16]; + int i; + + strcpy(buf, "mem=... "); + for(i = -10; i < 0; i++) + { + sprintf(tmp, "%02x ", __i286_memoryread((cs << 4) + ip + i)); + strcat(buf, tmp); + } + sprintf(tmp, "<%02x> ", __i286_memoryread((cs << 4) + ip)); + strcat(buf, tmp); + for(i = 1; i <= 10; i++) + { + sprintf(tmp, "%02x ", __i286_memoryread((cs << 4) + ip + i)); + strcat(buf, tmp); + } + strcat(buf, "...\n"); + + return buf; +} + +void FASTCALL msgbox_str(char *msg) +{ + + printf(msg); + fflush(stdout); + exit(1); +} + +void FASTCALL msgbox_mem(DWORD no) +{ + char buf[2048]; + char tmp[16]; + + strcpy(buf, cpu_reg2str()); + strcat(buf, "\n"); +#ifdef USE_FPU + strcat(buf, fpu_reg2str()); + strcat(buf, "\n"); +#endif + strcat(buf, mem2str(I286_CS, I286_IP)); + strcat(buf, "\n"); + sprintf(tmp, "no=%08x\n", no); + strcat(buf, tmp); + + msgbox_str(buf); +} + +void put_cpuinfo(void) +{ + char buf[2048]; + + strcpy(buf, cpu_reg2str()); + strcat(buf, "\n"); +#ifdef USE_FPU + strcat(buf, fpu_reg2str()); + strcat(buf, "\n"); +#endif + strcat(buf, a20str()); + + printf(buf); +} diff --git a/i386c/ia32/disasm.c b/i386c/ia32/disasm.c new file mode 100644 index 00000000..f973e1d2 --- /dev/null +++ b/i386c/ia32/disasm.c @@ -0,0 +1,1414 @@ +/* $Id: disasm.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ +/* $NetBSD: db_disasm.c,v 1.28 2002/10/01 12:56:49 fvdl Exp $ */ + +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * Id: db_disasm.c,v 2.3 91/02/05 17:11:03 mrt (CMU) + */ + +/* + * Instruction disassembler. + */ + +#include "cpu.h" + +typedef BOOL boolean_t; +typedef DWORD db_addr_t; +typedef long db_expr_t; + +#define db_radix 16 +#define db_printf ia32_printf +#define db_printsym(off, strategy, funcp) db_printf(db_num_to_str(off)) +#define db_get_value(cs,loc,size,is_signed) \ + (db_expr_t)((size == 4) ? cpu_vmemoryread_d(cs,loc) \ + : ((size == 2) ? cpu_vmemoryread_w(cs,loc) \ + : ((size == 1) ? cpu_vmemoryread(cs,loc) : 0))) + +static char * +db_num_to_str(db_expr_t val) +{ + static char buf[25]; + + if (db_radix == 16) { + snprintf(buf, sizeof(buf), "%lx", val); + } else if (db_radix == 8) { + snprintf(buf, sizeof(buf), "%lo", val); + } else { + snprintf(buf, sizeof(buf), "%lu", val); + } + return buf; +} + +static void +db_format_radix(char *buf, size_t bufsiz, SQWORD val, int altflag) +{ + const char *fmt; + + UNUSED(altflag); + + if (db_radix == 16) { + fmt = "-%llx"; + } else if (db_radix == 8) { + fmt = "-%llo"; + } else { + fmt = "-%llu"; + } + if (val < 0) + val = -val; + else + ++fmt; + + snprintf(buf, bufsiz, fmt, val); +} + +/* + * Size attributes + */ +#define DISASM_BYTE 0 +#define DISASM_WORD 1 +#define DISASM_LONG 2 +#define DISASM_QUAD 3 +#define DISASM_SNGL 4 +#define DISASM_DBLR 5 +#define DISASM_EXTR 6 +#define DISASM_SDEP 7 +#define DISASM_NONE 8 + +/* + * Addressing modes + */ +#define E 1 /* general effective address */ +#define Eind 2 /* indirect address (jump, call) */ +#define Ew 3 /* address, word size */ +#define Eb 4 /* address, byte size */ +#define R 5 /* register, in 'reg' field */ +#define Rw 6 /* word register, in 'reg' field */ +#define Ri 7 /* register in instruction */ +#define S 8 /* segment reg, in 'reg' field */ +#define Si 9 /* segment reg, in instruction */ +#define A 10 /* accumulator */ +#define BX 11 /* (bx) */ +#define CL 12 /* cl, for shifts */ +#define DX 13 /* dx, for IO */ +#define SI 14 /* si */ +#define DI 15 /* di */ +#define CR 16 /* control register */ +#define DR 17 /* debug register */ +#define TR 18 /* test register */ +#define I 19 /* immediate, unsigned */ +#define Is 20 /* immediate, signed */ +#define Ib 21 /* byte immediate, unsigned */ +#define Ibs 22 /* byte immediate, signed */ +#define Iw 23 /* word immediate, unsigned */ +#define Il 24 /* long immediate */ +#define O 25 /* direct address */ +#define Db 26 /* byte displacement from EIP */ +#define Dl 27 /* long displacement from EIP */ +#define o1 28 /* constant 1 */ +#define o3 29 /* constant 3 */ +#define OS 30 /* immediate offset/segment */ +#define ST 31 /* FP stack top */ +#define STI 32 /* FP stack */ +#define X 33 /* extended FP op */ +#define XA 34 /* for 'fstcw %ax' */ + +struct inst { + char * i_name; /* name */ + short i_has_modrm; /* has regmodrm byte */ + short i_size; /* operand size */ + int i_mode; /* addressing modes */ + char * i_extra; /* pointer to extra opcode table */ +}; + +#define op1(x) (x) +#define op2(x,y) ((x)|((y)<<8)) +#define op3(x,y,z) ((x)|((y)<<8)|((z)<<16)) + +struct finst { + char * f_name; /* name for memory instruction */ + int f_size; /* size for memory instruction */ + int f_rrmode; /* mode for rr instruction */ + char * f_rrname; /* name for rr instruction + (or pointer to table) */ +}; + +const char * const db_Grp6[] = { + "sldt", + "str", + "lldt", + "ltr", + "verr", + "verw", + "", + "" +}; + +const char * const db_Grp7[] = { + "sgdt", + "sidt", + "lgdt", + "lidt", + "smsw", + "", + "lmsw", + "invlpg" +}; + +const char * const db_Grp8[] = { + "", + "", + "", + "", + "bt", + "bts", + "btr", + "btc" +}; + +const char * const db_Grp9[] = { + "", + "cmpxchg8b", + "", + "", + "", + "", + "", + "", +}; + +const struct inst db_inst_0f0x[] = { +/*00*/ { "", TRUE, DISASM_NONE, op1(Ew), (char *)db_Grp6 }, +/*01*/ { "", TRUE, DISASM_NONE, op1(Ew), (char *)db_Grp7 }, +/*02*/ { "lar", TRUE, DISASM_LONG, op2(E,R), 0 }, +/*03*/ { "lsl", TRUE, DISASM_LONG, op2(E,R), 0 }, +/*04*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*05*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*06*/ { "clts", FALSE, DISASM_NONE, 0, 0 }, +/*07*/ { "", FALSE, DISASM_NONE, 0, 0 }, + +/*08*/ { "invd", FALSE, DISASM_NONE, 0, 0 }, +/*09*/ { "wbinvd",FALSE, DISASM_NONE, 0, 0 }, +/*0a*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*0b*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*0c*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*0d*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*0e*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*0f*/ { "", FALSE, DISASM_NONE, 0, 0 }, +}; + +const struct inst db_inst_0f2x[] = { +/*20*/ { "mov", TRUE, DISASM_LONG, op2(CR,E), 0 }, /* use E for reg */ +/*21*/ { "mov", TRUE, DISASM_LONG, op2(DR,E), 0 }, /* since mod == 11 */ +/*22*/ { "mov", TRUE, DISASM_LONG, op2(E,CR), 0 }, +/*23*/ { "mov", TRUE, DISASM_LONG, op2(E,DR), 0 }, +/*24*/ { "mov", TRUE, DISASM_LONG, op2(TR,E), 0 }, +/*25*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*26*/ { "mov", TRUE, DISASM_LONG, op2(E,TR), 0 }, +/*27*/ { "", FALSE, DISASM_NONE, 0, 0 }, + +/*28*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*29*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*2a*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*2b*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*2c*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*2d*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*2e*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*2f*/ { "", FALSE, DISASM_NONE, 0, 0 }, +}; + +const struct inst db_inst_0f3x[] = { +/*30*/ { "wrmsr", FALSE, DISASM_NONE, 0, 0 }, +/*31*/ { "rdtsc", FALSE, DISASM_NONE, 0, 0 }, +/*32*/ { "rdmsr", FALSE, DISASM_NONE, 0, 0 }, +/*33*/ { "rdpmc", FALSE, DISASM_NONE, 0, 0 }, +/*34*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*35*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*36*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*37*/ { "", FALSE, DISASM_NONE, 0, 0 }, + +/*38*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*39*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*3a*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*3v*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*3c*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*3d*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*3e*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*3f*/ { "", FALSE, DISASM_NONE, 0, 0 }, +}; + +const struct inst db_inst_0f8x[] = { +/*80*/ { "jo", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*81*/ { "jno", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*82*/ { "jb", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*83*/ { "jnb", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*84*/ { "jz", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*85*/ { "jnz", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*86*/ { "jbe", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*87*/ { "jnbe", FALSE, DISASM_NONE, op1(Dl), 0 }, + +/*88*/ { "js", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*89*/ { "jns", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*8a*/ { "jp", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*8b*/ { "jnp", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*8c*/ { "jl", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*8d*/ { "jnl", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*8e*/ { "jle", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*8f*/ { "jnle", FALSE, DISASM_NONE, op1(Dl), 0 }, +}; + +const struct inst db_inst_0f9x[] = { +/*90*/ { "seto", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*91*/ { "setno", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*92*/ { "setb", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*93*/ { "setnb", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*94*/ { "setz", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*95*/ { "setnz", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*96*/ { "setbe", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*97*/ { "setnbe",TRUE, DISASM_NONE, op1(Eb), 0 }, + +/*98*/ { "sets", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*99*/ { "setns", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*9a*/ { "setp", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*9b*/ { "setnp", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*9c*/ { "setl", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*9d*/ { "setnl", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*9e*/ { "setle", TRUE, DISASM_NONE, op1(Eb), 0 }, +/*9f*/ { "setnle",TRUE, DISASM_NONE, op1(Eb), 0 }, +}; + +const struct inst db_inst_0fax[] = { +/*a0*/ { "push", FALSE, DISASM_NONE, op1(Si), 0 }, +/*a1*/ { "pop", FALSE, DISASM_NONE, op1(Si), 0 }, +/*a2*/ { "cpuid", FALSE, DISASM_NONE, 0, 0 }, +/*a3*/ { "bt", TRUE, DISASM_LONG, op2(R,E), 0 }, +/*a4*/ { "shld", TRUE, DISASM_LONG, op3(Ib,E,R), 0 }, +/*a5*/ { "shld", TRUE, DISASM_LONG, op3(CL,E,R), 0 }, +/*a6*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*a7*/ { "", FALSE, DISASM_NONE, 0, 0 }, + +/*a8*/ { "push", FALSE, DISASM_NONE, op1(Si), 0 }, +/*a9*/ { "pop", FALSE, DISASM_NONE, op1(Si), 0 }, +/*aa*/ { "rsm", FALSE, DISASM_NONE, 0, 0 }, +/*ab*/ { "bts", TRUE, DISASM_LONG, op2(R,E), 0 }, +/*ac*/ { "shrd", TRUE, DISASM_LONG, op3(Ib,E,R), 0 }, +/*ad*/ { "shrd", TRUE, DISASM_LONG, op3(CL,E,R), 0 }, +/*ae*/ { "fxsave",TRUE, DISASM_LONG, 0, 0 }, +/*af*/ { "imul", TRUE, DISASM_LONG, op2(E,R), 0 }, +}; + +const struct inst db_inst_0fbx[] = { +/*b0*/ { "cmpxchg",TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*b1*/ { "cmpxchg",TRUE, DISASM_LONG, op2(R, E), 0 }, +/*b2*/ { "lss", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*b3*/ { "btr", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*b4*/ { "lfs", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*b5*/ { "lgs", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*b6*/ { "movzb", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*b7*/ { "movzw", TRUE, DISASM_LONG, op2(E, R), 0 }, + +/*b8*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*b9*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*ba*/ { "", TRUE, DISASM_LONG, op2(Ib, E), (char *)db_Grp8 }, +/*bb*/ { "btc", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*bc*/ { "bsf", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*bd*/ { "bsr", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*be*/ { "movsb", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*bf*/ { "movsw", TRUE, DISASM_LONG, op2(E, R), 0 }, +}; + +const struct inst db_inst_0fcx[] = { +/*c0*/ { "xadd", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*c1*/ { "xadd", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*c2*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*c3*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*c4*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*c5*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*c6*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*c7*/ { "", TRUE, DISASM_NONE, op1(E), (char *)db_Grp9 }, +/*c8*/ { "bswap", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*c9*/ { "bswap", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*ca*/ { "bswap", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*cb*/ { "bswap", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*cc*/ { "bswap", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*cd*/ { "bswap", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*ce*/ { "bswap", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*cf*/ { "bswap", FALSE, DISASM_LONG, op1(Ri), 0 }, +}; + +const struct inst * const db_inst_0f[] = { + db_inst_0f0x, + 0, + db_inst_0f2x, + db_inst_0f3x, + 0, + 0, + 0, + 0, + db_inst_0f8x, + db_inst_0f9x, + db_inst_0fax, + db_inst_0fbx, + db_inst_0fcx, + 0, + 0, + 0 +}; + +const char * const db_Esc92[] = { + "fnop", "", "", "", "", "", "", "" +}; +const char * const db_Esc93[] = { + "", "", "", "", "", "", "", "" +}; +const char * const db_Esc94[] = { + "fchs", "fabs", "", "", "ftst", "fxam", "", "" +}; +const char * const db_Esc95[] = { + "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","" +}; +const char * const db_Esc96[] = { + "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp", + "fincstp" +}; +const char * const db_Esc97[] = { + "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos" +}; + +const char * const db_Esca4[] = { + "", "fucompp","", "", "", "", "", "" +}; + +const char * const db_Escb4[] = { + "", "", "fnclex","fninit","", "", "", "" +}; + +const char * const db_Esce3[] = { + "", "fcompp","", "", "", "", "", "" +}; + +const char * const db_Escf4[] = { + "fnstsw","", "", "", "", "", "", "" +}; + +const struct finst db_Esc8[] = { +/*0*/ { "fadd", DISASM_SNGL, op2(STI,ST), 0 }, +/*1*/ { "fmul", DISASM_SNGL, op2(STI,ST), 0 }, +/*2*/ { "fcom", DISASM_SNGL, op2(STI,ST), 0 }, +/*3*/ { "fcomp", DISASM_SNGL, op2(STI,ST), 0 }, +/*4*/ { "fsub", DISASM_SNGL, op2(STI,ST), 0 }, +/*5*/ { "fsubr", DISASM_SNGL, op2(STI,ST), 0 }, +/*6*/ { "fdiv", DISASM_SNGL, op2(STI,ST), 0 }, +/*7*/ { "fdivr", DISASM_SNGL, op2(STI,ST), 0 }, +}; + +const struct finst db_Esc9[] = { +/*0*/ { "fld", DISASM_SNGL, op1(STI), 0 }, +/*1*/ { "", DISASM_NONE, op1(STI), "fxch" }, +/*2*/ { "fst", DISASM_SNGL, op1(X), (char *)db_Esc92 }, +/*3*/ { "fstp", DISASM_SNGL, op1(X), (char *)db_Esc93 }, +/*4*/ { "fldenv", DISASM_NONE, op1(X), (char *)db_Esc94 }, +/*5*/ { "fldcw", DISASM_NONE, op1(X), (char *)db_Esc95 }, +/*6*/ { "fnstenv",DISASM_NONE, op1(X), (char *)db_Esc96 }, +/*7*/ { "fnstcw", DISASM_NONE, op1(X), (char *)db_Esc97 }, +}; + +const struct finst db_Esca[] = { +/*0*/ { "fiadd", DISASM_WORD, 0, 0 }, +/*1*/ { "fimul", DISASM_WORD, 0, 0 }, +/*2*/ { "ficom", DISASM_WORD, 0, 0 }, +/*3*/ { "ficomp", DISASM_WORD, 0, 0 }, +/*4*/ { "fisub", DISASM_WORD, op1(X), (char *)db_Esca4 }, +/*5*/ { "fisubr", DISASM_WORD, 0, 0 }, +/*6*/ { "fidiv", DISASM_WORD, 0, 0 }, +/*7*/ { "fidivr", DISASM_WORD, 0, 0 } +}; + +const struct finst db_Escb[] = { +/*0*/ { "fild", DISASM_WORD, 0, 0 }, +/*1*/ { "", DISASM_NONE, 0, 0 }, +/*2*/ { "fist", DISASM_WORD, 0, 0 }, +/*3*/ { "fistp", DISASM_WORD, 0, 0 }, +/*4*/ { "", DISASM_WORD, op1(X), (char *)db_Escb4 }, +/*5*/ { "fld", DISASM_EXTR, 0, 0 }, +/*6*/ { "", DISASM_WORD, 0, 0 }, +/*7*/ { "fstp", DISASM_EXTR, 0, 0 }, +}; + +const struct finst db_Escc[] = { +/*0*/ { "fadd", DISASM_DBLR, op2(ST,STI), 0 }, +/*1*/ { "fmul", DISASM_DBLR, op2(ST,STI), 0 }, +/*2*/ { "fcom", DISASM_DBLR, op2(ST,STI), 0 }, +/*3*/ { "fcomp", DISASM_DBLR, op2(ST,STI), 0 }, +/*4*/ { "fsub", DISASM_DBLR, op2(ST,STI), "fsubr" }, +/*5*/ { "fsubr", DISASM_DBLR, op2(ST,STI), "fsub" }, +/*6*/ { "fdiv", DISASM_DBLR, op2(ST,STI), "fdivr" }, +/*7*/ { "fdivr", DISASM_DBLR, op2(ST,STI), "fdiv" }, +}; + +const struct finst db_Escd[] = { +/*0*/ { "fld", DISASM_DBLR, op1(STI), "ffree" }, +/*1*/ { "", DISASM_NONE, 0, 0 }, +/*2*/ { "fst", DISASM_DBLR, op1(STI), 0 }, +/*3*/ { "fstp", DISASM_DBLR, op1(STI), 0 }, +/*4*/ { "frstor", DISASM_NONE, op1(STI), "fucom" }, +/*5*/ { "", DISASM_NONE, op1(STI), "fucomp" }, +/*6*/ { "fnsave", DISASM_NONE, 0, 0 }, +/*7*/ { "fnstsw", DISASM_NONE, 0, 0 }, +}; + +const struct finst db_Esce[] = { +/*0*/ { "fiadd", DISASM_LONG, op2(ST,STI), "faddp" }, +/*1*/ { "fimul", DISASM_LONG, op2(ST,STI), "fmulp" }, +/*2*/ { "ficom", DISASM_LONG, 0, 0 }, +/*3*/ { "ficomp", DISASM_LONG, op1(X), (char *)db_Esce3 }, +/*4*/ { "fisub", DISASM_LONG, op2(ST,STI), "fsubrp" }, +/*5*/ { "fisubr", DISASM_LONG, op2(ST,STI), "fsubp" }, +/*6*/ { "fidiv", DISASM_LONG, op2(ST,STI), "fdivrp" }, +/*7*/ { "fidivr", DISASM_LONG, op2(ST,STI), "fdivp" }, +}; + +const struct finst db_Escf[] = { +/*0*/ { "fild", DISASM_LONG, 0, 0 }, +/*1*/ { "", DISASM_LONG, 0, 0 }, +/*2*/ { "fist", DISASM_LONG, 0, 0 }, +/*3*/ { "fistp", DISASM_LONG, 0, 0 }, +/*4*/ { "fbld", DISASM_NONE, op1(XA), (char *)db_Escf4 }, +/*5*/ { "fld", DISASM_QUAD, 0, 0 }, +/*6*/ { "fbstp", DISASM_NONE, 0, 0 }, +/*7*/ { "fstp", DISASM_QUAD, 0, 0 }, +}; + +const struct finst * const db_Esc_inst[] = { + db_Esc8, db_Esc9, db_Esca, db_Escb, + db_Escc, db_Escd, db_Esce, db_Escf +}; + +const char * const db_Grp1[] = { + "add", + "or", + "adc", + "sbb", + "and", + "sub", + "xor", + "cmp" +}; + +const char * const db_Grp2[] = { + "rol", + "ror", + "rcl", + "rcr", + "shl", + "shr", + "shl", + "sar" +}; + +const struct inst db_Grp3[] = { + { "test", TRUE, DISASM_NONE, op2(I,E), 0 }, + { "test", TRUE, DISASM_NONE, op2(I,E), 0 }, + { "not", TRUE, DISASM_NONE, op1(E), 0 }, + { "neg", TRUE, DISASM_NONE, op1(E), 0 }, + { "mul", TRUE, DISASM_NONE, op2(E,A), 0 }, + { "imul", TRUE, DISASM_NONE, op2(E,A), 0 }, + { "div", TRUE, DISASM_NONE, op2(E,A), 0 }, + { "idiv", TRUE, DISASM_NONE, op2(E,A), 0 }, +}; + +const struct inst db_Grp4[] = { + { "inc", TRUE, DISASM_BYTE, op1(E), 0 }, + { "dec", TRUE, DISASM_BYTE, op1(E), 0 }, + { "", TRUE, DISASM_NONE, 0, 0 }, + { "", TRUE, DISASM_NONE, 0, 0 }, + { "", TRUE, DISASM_NONE, 0, 0 }, + { "", TRUE, DISASM_NONE, 0, 0 }, + { "", TRUE, DISASM_NONE, 0, 0 }, + { "", TRUE, DISASM_NONE, 0, 0 } +}; + +const struct inst db_Grp5[] = { + { "inc", TRUE, DISASM_LONG, op1(E), 0 }, + { "dec", TRUE, DISASM_LONG, op1(E), 0 }, + { "call", TRUE, DISASM_NONE, op1(Eind),0 }, + { "lcall", TRUE, DISASM_NONE, op1(Eind),0 }, + { "jmp", TRUE, DISASM_NONE, op1(Eind),0 }, + { "ljmp", TRUE, DISASM_NONE, op1(Eind),0 }, + { "push", TRUE, DISASM_LONG, op1(E), 0 }, + { "", TRUE, DISASM_NONE, 0, 0 } +}; + +const struct inst db_inst_table[256] = { +/*00*/ { "add", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*01*/ { "add", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*02*/ { "add", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*03*/ { "add", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*04*/ { "add", FALSE, DISASM_BYTE, op2(Is, A), 0 }, +/*05*/ { "add", FALSE, DISASM_LONG, op2(Is, A), 0 }, +/*06*/ { "push", FALSE, DISASM_NONE, op1(Si), 0 }, +/*07*/ { "pop", FALSE, DISASM_NONE, op1(Si), 0 }, + +/*08*/ { "or", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*09*/ { "or", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*0a*/ { "or", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*0b*/ { "or", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*0c*/ { "or", FALSE, DISASM_BYTE, op2(I, A), 0 }, +/*0d*/ { "or", FALSE, DISASM_LONG, op2(I, A), 0 }, +/*0e*/ { "push", FALSE, DISASM_NONE, op1(Si), 0 }, +/*0f*/ { "", FALSE, DISASM_NONE, 0, 0 }, + +/*10*/ { "adc", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*11*/ { "adc", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*12*/ { "adc", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*13*/ { "adc", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*14*/ { "adc", FALSE, DISASM_BYTE, op2(Is, A), 0 }, +/*15*/ { "adc", FALSE, DISASM_LONG, op2(Is, A), 0 }, +/*16*/ { "push", FALSE, DISASM_NONE, op1(Si), 0 }, +/*17*/ { "pop", FALSE, DISASM_NONE, op1(Si), 0 }, + +/*18*/ { "sbb", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*19*/ { "sbb", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*1a*/ { "sbb", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*1b*/ { "sbb", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*1c*/ { "sbb", FALSE, DISASM_BYTE, op2(Is, A), 0 }, +/*1d*/ { "sbb", FALSE, DISASM_LONG, op2(Is, A), 0 }, +/*1e*/ { "push", FALSE, DISASM_NONE, op1(Si), 0 }, +/*1f*/ { "pop", FALSE, DISASM_NONE, op1(Si), 0 }, + +/*20*/ { "and", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*21*/ { "and", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*22*/ { "and", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*23*/ { "and", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*24*/ { "and", FALSE, DISASM_BYTE, op2(I, A), 0 }, +/*25*/ { "and", FALSE, DISASM_LONG, op2(I, A), 0 }, +/*26*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*27*/ { "aaa", FALSE, DISASM_NONE, 0, 0 }, + +/*28*/ { "sub", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*29*/ { "sub", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*2a*/ { "sub", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*2b*/ { "sub", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*2c*/ { "sub", FALSE, DISASM_BYTE, op2(Is, A), 0 }, +/*2d*/ { "sub", FALSE, DISASM_LONG, op2(Is, A), 0 }, +/*2e*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*2f*/ { "das", FALSE, DISASM_NONE, 0, 0 }, + +/*30*/ { "xor", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*31*/ { "xor", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*32*/ { "xor", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*33*/ { "xor", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*34*/ { "xor", FALSE, DISASM_BYTE, op2(I, A), 0 }, +/*35*/ { "xor", FALSE, DISASM_LONG, op2(I, A), 0 }, +/*36*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*37*/ { "daa", FALSE, DISASM_NONE, 0, 0 }, + +/*38*/ { "cmp", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*39*/ { "cmp", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*3a*/ { "cmp", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*3b*/ { "cmp", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*3c*/ { "cmp", FALSE, DISASM_BYTE, op2(Is, A), 0 }, +/*3d*/ { "cmp", FALSE, DISASM_LONG, op2(Is, A), 0 }, +/*3e*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*3f*/ { "aas", FALSE, DISASM_NONE, 0, 0 }, + +/*40*/ { "inc", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*41*/ { "inc", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*42*/ { "inc", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*43*/ { "inc", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*44*/ { "inc", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*45*/ { "inc", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*46*/ { "inc", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*47*/ { "inc", FALSE, DISASM_LONG, op1(Ri), 0 }, + +/*48*/ { "dec", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*49*/ { "dec", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*4a*/ { "dec", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*4b*/ { "dec", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*4c*/ { "dec", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*4d*/ { "dec", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*4e*/ { "dec", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*4f*/ { "dec", FALSE, DISASM_LONG, op1(Ri), 0 }, + +/*50*/ { "push", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*51*/ { "push", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*52*/ { "push", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*53*/ { "push", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*54*/ { "push", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*55*/ { "push", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*56*/ { "push", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*57*/ { "push", FALSE, DISASM_LONG, op1(Ri), 0 }, + +/*58*/ { "pop", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*59*/ { "pop", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*5a*/ { "pop", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*5b*/ { "pop", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*5c*/ { "pop", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*5d*/ { "pop", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*5e*/ { "pop", FALSE, DISASM_LONG, op1(Ri), 0 }, +/*5f*/ { "pop", FALSE, DISASM_LONG, op1(Ri), 0 }, + +/*60*/ { "pusha", FALSE, DISASM_LONG, 0, 0 }, +/*61*/ { "popa", FALSE, DISASM_LONG, 0, 0 }, +/*62*/ { "bound", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*63*/ { "arpl", TRUE, DISASM_NONE, op2(Ew,Rw), 0 }, + +/*64*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*65*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*66*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*67*/ { "", FALSE, DISASM_NONE, 0, 0 }, + +/*68*/ { "push", FALSE, DISASM_LONG, op1(I), 0 }, +/*69*/ { "imul", TRUE, DISASM_LONG, op3(I,E,R), 0 }, +/*6a*/ { "push", FALSE, DISASM_LONG, op1(Ib), 0 }, +/*6b*/ { "imul", TRUE, DISASM_LONG, op3(Ibs,E,R),0 }, +/*6c*/ { "ins", FALSE, DISASM_BYTE, op2(DX, DI), 0 }, +/*6d*/ { "ins", FALSE, DISASM_LONG, op2(DX, DI), 0 }, +/*6e*/ { "outs", FALSE, DISASM_BYTE, op2(SI, DX), 0 }, +/*6f*/ { "outs", FALSE, DISASM_LONG, op2(SI, DX), 0 }, + +/*70*/ { "jo", FALSE, DISASM_NONE, op1(Db), 0 }, +/*71*/ { "jno", FALSE, DISASM_NONE, op1(Db), 0 }, +/*72*/ { "jb", FALSE, DISASM_NONE, op1(Db), 0 }, +/*73*/ { "jnb", FALSE, DISASM_NONE, op1(Db), 0 }, +/*74*/ { "jz", FALSE, DISASM_NONE, op1(Db), 0 }, +/*75*/ { "jnz", FALSE, DISASM_NONE, op1(Db), 0 }, +/*76*/ { "jbe", FALSE, DISASM_NONE, op1(Db), 0 }, +/*77*/ { "jnbe", FALSE, DISASM_NONE, op1(Db), 0 }, + +/*78*/ { "js", FALSE, DISASM_NONE, op1(Db), 0 }, +/*79*/ { "jns", FALSE, DISASM_NONE, op1(Db), 0 }, +/*7a*/ { "jp", FALSE, DISASM_NONE, op1(Db), 0 }, +/*7b*/ { "jnp", FALSE, DISASM_NONE, op1(Db), 0 }, +/*7c*/ { "jl", FALSE, DISASM_NONE, op1(Db), 0 }, +/*7d*/ { "jnl", FALSE, DISASM_NONE, op1(Db), 0 }, +/*7e*/ { "jle", FALSE, DISASM_NONE, op1(Db), 0 }, +/*7f*/ { "jnle", FALSE, DISASM_NONE, op1(Db), 0 }, + +/*80*/ { "", TRUE, DISASM_BYTE, op2(I, E), (char *)db_Grp1 }, +/*81*/ { "", TRUE, DISASM_LONG, op2(I, E), (char *)db_Grp1 }, +/*82*/ { "", TRUE, DISASM_BYTE, op2(Is,E), (char *)db_Grp1 }, +/*83*/ { "", TRUE, DISASM_LONG, op2(Ibs,E), (char *)db_Grp1 }, +/*84*/ { "test", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*85*/ { "test", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*86*/ { "xchg", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*87*/ { "xchg", TRUE, DISASM_LONG, op2(R, E), 0 }, + +/*88*/ { "mov", TRUE, DISASM_BYTE, op2(R, E), 0 }, +/*89*/ { "mov", TRUE, DISASM_LONG, op2(R, E), 0 }, +/*8a*/ { "mov", TRUE, DISASM_BYTE, op2(E, R), 0 }, +/*8b*/ { "mov", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*8c*/ { "mov", TRUE, DISASM_NONE, op2(S, Ew), 0 }, +/*8d*/ { "lea", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*8e*/ { "mov", TRUE, DISASM_NONE, op2(Ew, S), 0 }, +/*8f*/ { "pop", TRUE, DISASM_LONG, op1(E), 0 }, + +/*90*/ { "nop", FALSE, DISASM_NONE, 0, 0 }, +/*91*/ { "xchg", FALSE, DISASM_LONG, op2(A, Ri), 0 }, +/*92*/ { "xchg", FALSE, DISASM_LONG, op2(A, Ri), 0 }, +/*93*/ { "xchg", FALSE, DISASM_LONG, op2(A, Ri), 0 }, +/*94*/ { "xchg", FALSE, DISASM_LONG, op2(A, Ri), 0 }, +/*95*/ { "xchg", FALSE, DISASM_LONG, op2(A, Ri), 0 }, +/*96*/ { "xchg", FALSE, DISASM_LONG, op2(A, Ri), 0 }, +/*97*/ { "xchg", FALSE, DISASM_LONG, op2(A, Ri), 0 }, + +/*98*/ { "cbw", FALSE, DISASM_SDEP, 0, "cwde" }, /* cbw/cwde */ +/*99*/ { "cwd", FALSE, DISASM_SDEP, 0, "cdq" }, /* cwd/cdq */ +/*9a*/ { "lcall", FALSE, DISASM_NONE, op1(OS), 0 }, +/*9b*/ { "wait", FALSE, DISASM_NONE, 0, 0 }, +/*9c*/ { "pushf", FALSE, DISASM_LONG, 0, 0 }, +/*9d*/ { "popf", FALSE, DISASM_LONG, 0, 0 }, +/*9e*/ { "sahf", FALSE, DISASM_NONE, 0, 0 }, +/*9f*/ { "lahf", FALSE, DISASM_NONE, 0, 0 }, + +/*a0*/ { "mov", FALSE, DISASM_BYTE, op2(O, A), 0 }, +/*a1*/ { "mov", FALSE, DISASM_LONG, op2(O, A), 0 }, +/*a2*/ { "mov", FALSE, DISASM_BYTE, op2(A, O), 0 }, +/*a3*/ { "mov", FALSE, DISASM_LONG, op2(A, O), 0 }, +/*a4*/ { "movs", FALSE, DISASM_BYTE, op2(SI,DI), 0 }, +/*a5*/ { "movs", FALSE, DISASM_LONG, op2(SI,DI), 0 }, +/*a6*/ { "cmps", FALSE, DISASM_BYTE, op2(SI,DI), 0 }, +/*a7*/ { "cmps", FALSE, DISASM_LONG, op2(SI,DI), 0 }, + +/*a8*/ { "test", FALSE, DISASM_BYTE, op2(I, A), 0 }, +/*a9*/ { "test", FALSE, DISASM_LONG, op2(I, A), 0 }, +/*aa*/ { "stos", FALSE, DISASM_BYTE, op1(DI), 0 }, +/*ab*/ { "stos", FALSE, DISASM_LONG, op1(DI), 0 }, +/*ac*/ { "lods", FALSE, DISASM_BYTE, op1(SI), 0 }, +/*ad*/ { "lods", FALSE, DISASM_LONG, op1(SI), 0 }, +/*ae*/ { "scas", FALSE, DISASM_BYTE, op1(SI), 0 }, +/*af*/ { "scas", FALSE, DISASM_LONG, op1(SI), 0 }, + +/*b0*/ { "mov", FALSE, DISASM_BYTE, op2(I, Ri), 0 }, +/*b1*/ { "mov", FALSE, DISASM_BYTE, op2(I, Ri), 0 }, +/*b2*/ { "mov", FALSE, DISASM_BYTE, op2(I, Ri), 0 }, +/*b3*/ { "mov", FALSE, DISASM_BYTE, op2(I, Ri), 0 }, +/*b4*/ { "mov", FALSE, DISASM_BYTE, op2(I, Ri), 0 }, +/*b5*/ { "mov", FALSE, DISASM_BYTE, op2(I, Ri), 0 }, +/*b6*/ { "mov", FALSE, DISASM_BYTE, op2(I, Ri), 0 }, +/*b7*/ { "mov", FALSE, DISASM_BYTE, op2(I, Ri), 0 }, + +/*b8*/ { "mov", FALSE, DISASM_LONG, op2(I, Ri), 0 }, +/*b9*/ { "mov", FALSE, DISASM_LONG, op2(I, Ri), 0 }, +/*ba*/ { "mov", FALSE, DISASM_LONG, op2(I, Ri), 0 }, +/*bb*/ { "mov", FALSE, DISASM_LONG, op2(I, Ri), 0 }, +/*bc*/ { "mov", FALSE, DISASM_LONG, op2(I, Ri), 0 }, +/*bd*/ { "mov", FALSE, DISASM_LONG, op2(I, Ri), 0 }, +/*be*/ { "mov", FALSE, DISASM_LONG, op2(I, Ri), 0 }, +/*bf*/ { "mov", FALSE, DISASM_LONG, op2(I, Ri), 0 }, + +/*c0*/ { "", TRUE, DISASM_BYTE, op2(Ib, E), (char *)db_Grp2 }, +/*c1*/ { "", TRUE, DISASM_LONG, op2(Ib, E), (char *)db_Grp2 }, +/*c2*/ { "ret", FALSE, DISASM_NONE, op1(Iw), 0 }, +/*c3*/ { "ret", FALSE, DISASM_NONE, 0, 0 }, +/*c4*/ { "les", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*c5*/ { "lds", TRUE, DISASM_LONG, op2(E, R), 0 }, +/*c6*/ { "mov", TRUE, DISASM_BYTE, op2(I, E), 0 }, +/*c7*/ { "mov", TRUE, DISASM_LONG, op2(I, E), 0 }, + +/*c8*/ { "enter", FALSE, DISASM_NONE, op2(Ib, Iw), 0 }, +/*c9*/ { "leave", FALSE, DISASM_NONE, 0, 0 }, +/*ca*/ { "lret", FALSE, DISASM_NONE, op1(Iw), 0 }, +/*cb*/ { "lret", FALSE, DISASM_NONE, 0, 0 }, +/*cc*/ { "int", FALSE, DISASM_NONE, op1(o3), 0 }, +/*cd*/ { "int", FALSE, DISASM_NONE, op1(Ib), 0 }, +/*ce*/ { "into", FALSE, DISASM_NONE, 0, 0 }, +/*cf*/ { "iret", FALSE, DISASM_NONE, 0, 0 }, + +/*d0*/ { "", TRUE, DISASM_BYTE, op2(o1, E), (char *)db_Grp2 }, +/*d1*/ { "", TRUE, DISASM_LONG, op2(o1, E), (char *)db_Grp2 }, +/*d2*/ { "", TRUE, DISASM_BYTE, op2(CL, E), (char *)db_Grp2 }, +/*d3*/ { "", TRUE, DISASM_LONG, op2(CL, E), (char *)db_Grp2 }, +/*d4*/ { "aam", TRUE, DISASM_NONE, 0, 0 }, +/*d5*/ { "aad", TRUE, DISASM_NONE, 0, 0 }, +/*d6*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*d7*/ { "xlat", FALSE, DISASM_BYTE, op1(BX), 0 }, + +/*d8*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Esc8 }, +/*d9*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Esc9 }, +/*da*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Esca }, +/*db*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Escb }, +/*dc*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Escc }, +/*dd*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Escd }, +/*de*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Esce }, +/*df*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Escf }, + +/*e0*/ { "loopne",FALSE, DISASM_NONE, op1(Db), 0 }, +/*e1*/ { "loope", FALSE, DISASM_NONE, op1(Db), 0 }, +/*e2*/ { "loop", FALSE, DISASM_NONE, op1(Db), 0 }, +/*e3*/ { "jcxz", FALSE, DISASM_SDEP, op1(Db), "jecxz" }, +/*e4*/ { "in", FALSE, DISASM_BYTE, op2(Ib, A), 0 }, +/*e5*/ { "in", FALSE, DISASM_LONG, op2(Ib, A) , 0 }, +/*e6*/ { "out", FALSE, DISASM_BYTE, op2(A, Ib), 0 }, +/*e7*/ { "out", FALSE, DISASM_LONG, op2(A, Ib) , 0 }, + +/*e8*/ { "call", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*e9*/ { "jmp", FALSE, DISASM_NONE, op1(Dl), 0 }, +/*ea*/ { "ljmp", FALSE, DISASM_NONE, op1(OS), 0 }, +/*eb*/ { "jmp", FALSE, DISASM_NONE, op1(Db), 0 }, +/*ec*/ { "in", FALSE, DISASM_BYTE, op2(DX, A), 0 }, +/*ed*/ { "in", FALSE, DISASM_LONG, op2(DX, A) , 0 }, +/*ee*/ { "out", FALSE, DISASM_BYTE, op2(A, DX), 0 }, +/*ef*/ { "out", FALSE, DISASM_LONG, op2(A, DX) , 0 }, + +/*f0*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*f1*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*f2*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*f3*/ { "", FALSE, DISASM_NONE, 0, 0 }, +/*f4*/ { "hlt", FALSE, DISASM_NONE, 0, 0 }, +/*f5*/ { "cmc", FALSE, DISASM_NONE, 0, 0 }, +/*f6*/ { "", TRUE, DISASM_BYTE, 0, (char *)db_Grp3 }, +/*f7*/ { "", TRUE, DISASM_LONG, 0, (char *)db_Grp3 }, + +/*f8*/ { "clc", FALSE, DISASM_NONE, 0, 0 }, +/*f9*/ { "stc", FALSE, DISASM_NONE, 0, 0 }, +/*fa*/ { "cli", FALSE, DISASM_NONE, 0, 0 }, +/*fb*/ { "sti", FALSE, DISASM_NONE, 0, 0 }, +/*fc*/ { "cld", FALSE, DISASM_NONE, 0, 0 }, +/*fd*/ { "std", FALSE, DISASM_NONE, 0, 0 }, +/*fe*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Grp4 }, +/*ff*/ { "", TRUE, DISASM_NONE, 0, (char *)db_Grp5 }, +}; + +const struct inst db_bad_inst = + { "???", FALSE, DISASM_NONE, 0, 0 } +; + +#define f_mod(byte) ((byte)>>6) +#define f_reg(byte) (((byte)>>3)&0x7) +#define f_rm(byte) ((byte)&0x7) + +#define sib_ss(byte) ((byte)>>6) +#define sib_index(byte) (((byte)>>3)&0x7) +#define sib_base(byte) ((byte)&0x7) + +struct i_addr { + int is_reg; /* if reg, reg number is in 'disp' */ + int disp; + const char * base; + const char * index; + int ss; +}; + +const char * const db_index_reg_16[8] = { + "%bx,%si", + "%bx,%di", + "%bp,%si", + "%bp,%di", + "%si", + "%di", + "%bp", + "%bx" +}; + +const char * const db_reg[3][8] = { + { "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh" }, + { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di" }, + { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi" } +}; + +const char * const db_seg_reg[8] = { + "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", "" +}; + +/* + * lengths for size attributes + */ +const int db_lengths[] = { + 1, /* DISASM_BYTE */ + 2, /* DISASM_WORD */ + 4, /* DISASM_LONG */ + 8, /* DISASM_QUAD */ + 4, /* DISASM_SNGL */ + 8, /* DISASM_DBLR */ + 10, /* DISASM_EXTR */ +}; + +#define get_value_inc(result, cs, loc, size, is_signed) \ + do { \ + result = db_get_value((cs), (loc), (size), (is_signed)); \ + (loc) += (size); \ + } while (0) + + +static db_addr_t db_read_address(WORD, db_addr_t, int, int, struct i_addr *); +static void db_print_address(char *, int, struct i_addr *); +static db_addr_t db_disasm_esc(WORD cs, db_addr_t, int, int, int, char *); + +/* + * Read address at location and return updated location. + */ +static db_addr_t +db_read_address(cs, loc, short_addr, regmodrm, addrp) + WORD cs; + db_addr_t loc; + int short_addr; + int regmodrm; + struct i_addr *addrp; /* out */ +{ + int mod, rm, sib, index, disp; + + mod = f_mod(regmodrm); + rm = f_rm(regmodrm); + + if (mod == 3) { + addrp->is_reg = TRUE; + addrp->disp = rm; + return (loc); + } + addrp->is_reg = FALSE; + addrp->index = 0; + + if (short_addr) { + addrp->index = 0; + addrp->ss = 0; + switch (mod) { + case 0: + if (rm == 6) { + get_value_inc(disp, cs, loc, 2, TRUE); + addrp->disp = disp; + addrp->base = 0; + } else { + addrp->disp = 0; + addrp->base = db_index_reg_16[rm]; + } + break; + case 1: + get_value_inc(disp, cs, loc, 1, TRUE); + addrp->disp = disp; + addrp->base = db_index_reg_16[rm]; + break; + case 2: + get_value_inc(disp, cs, loc, 2, TRUE); + addrp->disp = disp; + addrp->base = db_index_reg_16[rm]; + break; + } + } else { + if (mod != 3 && rm == 4) { + get_value_inc(sib, cs, loc, 1, FALSE); + rm = sib_base(sib); + index = sib_index(sib); + if (index != 4) + addrp->index = db_reg[DISASM_LONG][index]; + addrp->ss = sib_ss(sib); + } + + switch (mod) { + case 0: + if (rm == 5) { + get_value_inc(addrp->disp, cs, loc, 4, FALSE); + addrp->base = 0; + } else { + addrp->disp = 0; + addrp->base = db_reg[DISASM_LONG][rm]; + } + break; + case 1: + get_value_inc(disp, cs, loc, 1, TRUE); + addrp->disp = disp; + addrp->base = db_reg[DISASM_LONG][rm]; + break; + case 2: + get_value_inc(disp, cs, loc, 4, FALSE); + addrp->disp = disp; + addrp->base = db_reg[DISASM_LONG][rm]; + break; + } + } + return (loc); +} + +static void +db_print_address(seg, size, addrp) + char * seg; + int size; + struct i_addr *addrp; +{ + if (addrp->is_reg) { + db_printf("%s", db_reg[size][addrp->disp]); + return; + } + + if (seg) + db_printf("%s:", seg); + + db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY, db_printf); + if (addrp->base != 0 || addrp->index != 0) { + db_printf("("); + if (addrp->base) + db_printf("%s", addrp->base); + if (addrp->index) + db_printf(", %s, %d", addrp->index, 1<ss); + db_printf(")"); + } +} + +/* + * Disassemble floating-point ("escape") instruction + * and return updated location. + */ +static db_addr_t +db_disasm_esc(cs, loc, inst, short_addr, size, seg) + WORD cs; + db_addr_t loc; + int inst; + int short_addr; + int size; + char * seg; +{ + int regmodrm; + const struct finst *fp; + int mod; + struct i_addr address; + char * name; + + UNUSED(size); + + get_value_inc(regmodrm, cs, loc, 1, FALSE); + fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm)]; + mod = f_mod(regmodrm); + if (mod != 3) { + /* + * Normal address modes. + */ + loc = db_read_address(cs, loc, short_addr, regmodrm, &address); + db_printf("%s", fp->f_name); + switch(fp->f_size) { + case DISASM_SNGL: + db_printf("s"); + break; + case DISASM_DBLR: + db_printf("l"); + break; + case DISASM_EXTR: + db_printf("t"); + break; + case DISASM_WORD: + db_printf("s"); + break; + case DISASM_LONG: + db_printf("l"); + break; + case DISASM_QUAD: + db_printf("q"); + break; + default: + break; + } + db_printf("\t"); + db_print_address(seg, DISASM_BYTE, &address); + } else { + /* + * 'reg-reg' - special formats + */ + switch (fp->f_rrmode) { + case op2(ST,STI): + name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; + db_printf("%s\t%%st, %%st(%d)",name,f_rm(regmodrm)); + break; + case op2(STI,ST): + name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; + db_printf("%s\t%%st(%d), %%st",name, f_rm(regmodrm)); + break; + case op1(STI): + name = (fp->f_rrname) ? fp->f_rrname : fp->f_name; + db_printf("%s\t%%st(%d)",name, f_rm(regmodrm)); + break; + case op1(X): + db_printf("%s", ((char **)fp->f_rrname)[f_rm(regmodrm)]); + break; + case op1(XA): + db_printf("%s\t%%ax", + ((char **)fp->f_rrname)[f_rm(regmodrm)]); + break; + default: + db_printf(""); + break; + } + } + + return (loc); +} + +/* + * Disassemble instruction at 'loc'. 'altfmt' specifies an + * (optional) alternate format. Return address of start of + * next instruction. + */ +static db_addr_t +db_disasm(cs, loc, altfmt) + WORD cs; + db_addr_t loc; + boolean_t altfmt; +{ + int inst; + int size; + int short_addr; + char * seg; + const struct inst * ip; + char * i_name; + int i_size; + int i_mode; + int regmodrm = 0; + boolean_t first; + int displ; + int prefix; + int imm; + int imm2; + int len; + struct i_addr address; + + UNUSED(altfmt); + + get_value_inc(inst, cs, loc, 1, FALSE); + short_addr = CPU_INST_OP32 ? FALSE : TRUE; + size = short_addr ? DISASM_WORD : DISASM_LONG; + seg = 0; + + /* + * Get prefixes + */ + prefix = TRUE; + do { + switch (inst) { + case 0x66: /* data16 */ + size = short_addr ? DISASM_LONG : DISASM_WORD; + break; + case 0x67: + short_addr = CPU_INST_OP32 ? TRUE : FALSE; + break; + case 0x26: + seg = "%es"; + break; + case 0x36: + seg = "%ss"; + break; + case 0x2e: + seg = "%cs"; + break; + case 0x3e: + seg = "%ds"; + break; + case 0x64: + seg = "%fs"; + break; + case 0x65: + seg = "%gs"; + break; + case 0xf0: + db_printf("lock "); + break; + case 0xf2: + db_printf("repne "); + break; + case 0xf3: + db_printf("repe "); /* XXX repe VS rep */ + break; + default: + prefix = FALSE; + break; + } + if (prefix) + get_value_inc(inst, cs, loc, 1, FALSE); + } while (prefix); + + if (inst >= 0xd8 && inst <= 0xdf) { + loc = db_disasm_esc(cs, loc, inst, short_addr, size, seg); + db_printf("\n"); + return (loc); + } + + if (inst == 0x0f) { + get_value_inc(inst, cs, loc, 1, FALSE); + ip = db_inst_0f[inst>>4]; + if (ip == 0) + ip = &db_bad_inst; + else + ip = &ip[inst&0xf]; + } else { + ip = &db_inst_table[inst]; + } + + if (ip->i_has_modrm) { + get_value_inc(regmodrm, cs, loc, 1, FALSE); + loc = db_read_address(cs, loc, short_addr, regmodrm, &address); + } + + i_name = ip->i_name; + i_size = ip->i_size; + i_mode = ip->i_mode; + + if (ip->i_extra == (char *)db_Grp1 || + ip->i_extra == (char *)db_Grp2 || + ip->i_extra == (char *)db_Grp6 || + ip->i_extra == (char *)db_Grp7 || + ip->i_extra == (char *)db_Grp8) { + i_name = ((char **)ip->i_extra)[f_reg(regmodrm)]; + } else if (ip->i_extra == (char *)db_Grp3) { + ip = (struct inst *)ip->i_extra; + ip = &ip[f_reg(regmodrm)]; + i_name = ip->i_name; + i_mode = ip->i_mode; + } else if (ip->i_extra == (char *)db_Grp4 || + ip->i_extra == (char *)db_Grp5) { + ip = (struct inst *)ip->i_extra; + ip = &ip[f_reg(regmodrm)]; + i_name = ip->i_name; + i_mode = ip->i_mode; + i_size = ip->i_size; + } + + if (i_size == DISASM_SDEP) { + if (size == DISASM_WORD) + db_printf("%s", i_name); + else + db_printf("%s", ip->i_extra); + } else { + db_printf("%s", i_name); + if (i_size != DISASM_NONE) { + if (i_size == DISASM_BYTE) { + db_printf("b"); + size = DISASM_BYTE; + } else if (i_size == DISASM_WORD) { + db_printf("w"); + size = DISASM_WORD; + } else if (size == DISASM_WORD) { + db_printf("w"); + } else { + db_printf("l"); + } + } + } + db_printf("\t"); + for (first = TRUE; + i_mode != 0; + i_mode >>= 8, first = FALSE) { + char tbuf[24]; + + if (!first) + db_printf(", "); + + switch (i_mode & 0xFF) { + case E: + db_print_address(seg, size, &address); + break; + case Eind: + db_printf("*"); + db_print_address(seg, size, &address); + break; + case Ew: + db_print_address(seg, DISASM_WORD, &address); + break; + case Eb: + db_print_address(seg, DISASM_BYTE, &address); + break; + case R: + db_printf("%s", db_reg[size][f_reg(regmodrm)]); + break; + case Rw: + db_printf("%s", db_reg[DISASM_WORD][f_reg(regmodrm)]); + break; + case Ri: + db_printf("%s", db_reg[size][f_rm(inst)]); + break; + case S: + db_printf("%s", db_seg_reg[f_reg(regmodrm)]); + break; + case Si: + db_printf("%s", db_seg_reg[f_reg(inst)]); + break; + case A: + db_printf("%s", db_reg[size][0]); /* acc */ + break; + case BX: + if (seg) + db_printf("%s:", seg); + db_printf("(%s)", short_addr ? "%bx" : "%ebx"); + break; + case CL: + db_printf("%%cl"); + break; + case DX: + db_printf("%%dx"); + break; + case SI: + if (seg) + db_printf("%s:", seg); + db_printf("(%s)", short_addr ? "%si" : "%esi"); + break; + case DI: + db_printf("%%es:(%s)", short_addr ? "%di" : "%edi"); + break; + case CR: + db_printf("%%cr%d", f_reg(regmodrm)); + break; + case DR: + db_printf("%%dr%d", f_reg(regmodrm)); + break; + case TR: + db_printf("%%tr%d", f_reg(regmodrm)); + break; + case I: + len = db_lengths[size]; + get_value_inc(imm, cs, loc, len, FALSE);/* unsigned */ + db_format_radix(tbuf, 24, (unsigned int)imm, TRUE); + db_printf("$%s", tbuf); + break; + case Is: + len = db_lengths[size]; + get_value_inc(imm, cs, loc, len, TRUE); /* signed */ + db_format_radix(tbuf, 24, imm, TRUE); + db_printf("$%s", tbuf); + break; + case Ib: + get_value_inc(imm, cs, loc, 1, FALSE); /* unsigned */ + db_format_radix(tbuf, 24, (unsigned int)imm, TRUE); + db_printf("$%s", tbuf); + break; + case Ibs: + get_value_inc(imm, cs, loc, 1, TRUE); /* signed */ + db_format_radix(tbuf, 24, imm, TRUE); + db_printf("$%s", tbuf); + break; + case Iw: + get_value_inc(imm, cs, loc, 2, FALSE); /* unsigned */ + db_format_radix(tbuf, 24, (unsigned int)imm, TRUE); + db_printf("$%s", tbuf); + break; + case Il: + get_value_inc(imm, cs, loc, 4, FALSE); + db_format_radix(tbuf, 24, (unsigned int)imm, TRUE); + db_printf("$%s", tbuf); + break; + case O: + if (short_addr) + get_value_inc(displ, cs, loc, 2, TRUE); + else + get_value_inc(displ, cs, loc, 4, TRUE); + if (seg) { + db_format_radix(tbuf, 24, displ, TRUE); + db_printf("%s:%s", seg, tbuf); + } else + db_printsym((db_addr_t)displ, DB_STGY_ANY, + db_printf); + break; + case Db: + get_value_inc(displ, cs, loc, 1, TRUE); + db_printsym((db_addr_t)(displ + loc), DB_STGY_XTRN, + db_printf); + break; + case Dl: + get_value_inc(displ, cs, loc, 4, TRUE); + db_printsym((db_addr_t)(displ + loc), DB_STGY_XTRN, + db_printf); + break; + case o1: + db_printf("$1"); + break; + case o3: + db_printf("$3"); + break; + case OS: + get_value_inc(imm, cs, loc, 4, FALSE); /* offset */ + db_format_radix(tbuf, 24, (unsigned int)imm, TRUE); + db_printf("$%s", tbuf); + get_value_inc(imm2, cs, loc, 2, FALSE); /* segment */ + db_format_radix(tbuf, 24, (unsigned int)imm2, TRUE); + db_printf(",%s", tbuf); + break; + } + } + + db_printf("\n"); + return (loc); +} + +void +disasm(WORD cs, DWORD loc) +{ + + db_disasm(cs, loc, FALSE); +} diff --git a/i386c/ia32/exception.c b/i386c/ia32/exception.c new file mode 100644 index 00000000..4c75d137 --- /dev/null +++ b/i386c/ia32/exception.c @@ -0,0 +1,539 @@ +/* $Id: exception.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +void +memory_dump(int idx, DWORD madr) +{ + DWORD addr; + size_t size; + unsigned char buf[16]; + size_t s, i; + BYTE p; + + if (madr < 0x80) { + size = madr + 0x80; + addr = 0; + } else { + size = 0x100; + addr = madr - 0x80; + } + printf("memory dump\n-- \n"); + for (s = 0; s < size; s++) { + if ((s % 16) == 0) { + printf("%08x: ", addr + s); + memset(buf, '.', sizeof(buf)); + } + + p = cpu_vmemoryread(idx, addr + s); + printf("%02x ", p); + if (p >= 0x20 && p <= 0x7e) + buf[s % 16] = p; + + if ((s % 16) == 15) { + printf("| "); + for (i = 0; i < sizeof(buf); i++) + printf("%c", buf[i]); + printf("\n"); + } + } +} + +static const int exctype[EXCEPTION_NUM] = { + 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, +}; + +static const int dftable[4][4] = { + { 0, 0, 0, 1, }, + { 0, 1, 0, 1, }, + { 0, 1, 1, 1, }, + { 1, 1, 1, 1, }, +}; + +void +exception(int num, int error_code) +{ + int errorp = 0; + + VERBOSE(("exception: num = 0x%02x, error_code = %x", num, error_code)); + + CPU_STAT_NERROR++; + if ((CPU_STAT_NERROR >= 3) + || (CPU_STAT_NERROR == 2 && CPU_STAT_PREV_EXCEPTION == DF_EXCEPTION)) { + /* Triple fault */ + ia32_panic("exception: catch triple fault!"); + } + + switch (num) { + case DE_EXCEPTION: /* (F) スササ・ィ・鬘シ */ + case BR_EXCEPTION: /* (F) BOUND 、ホネマーマウー */ + case UD_EXCEPTION: /* (F) フオク・ェ・レ・ウ。シ・ノ */ + case NM_EXCEPTION: /* (F) ・ヌ・ミ・、・ケサネヘムノヤイト (FPU 、ャフオ、、) */ + CPU_EIP = CPU_PREV_EIP; + /*FALLTHROUGH*/ + case DB_EXCEPTION: /* (F/T) ・ヌ・ミ・テ・ー */ + case NMI_EXCEPTION: /* (I) NMI ウ荀ケ、゚ */ + case BP_EXCEPTION: /* (T) ・ヨ・。シ・ッ・ン・、・・ネ */ + case OF_EXCEPTION: /* (T) ・ェ。シ・ミ。シ・ユ・。シ */ + errorp = 0; + break; + + case DF_EXCEPTION: /* (A) ・タ・ヨ・・ユ・ゥ・・ネ (errcode: 0) */ + errorp = 1; + error_code = 0; + break; + + case AC_EXCEPTION: /* (F) ・「・鬣、・・皈・ネ・チ・ァ・テ・ッ (errcode: 0) */ + error_code = 0; + /*FALLTHROUGH*/ + case TS_EXCEPTION: /* (F) フオク TSS (errcode) */ + case NP_EXCEPTION: /* (F) ・サ・ー・皈・ネノヤコ゚ (errcode) */ + case SS_EXCEPTION: /* (F) ・ケ・ソ・テ・ッ・サ・ー・皈・ネ・ユ・ゥ・・ネ (errcode) */ + case GP_EXCEPTION: /* (F) ーネフハンクホ羌ー (errcode) */ + case PF_EXCEPTION: /* (F) ・レ。シ・ク・ユ・ゥ・・ネ (errcode) */ + CPU_EIP = CPU_PREV_EIP; + errorp = 1; + break; + + case MF_EXCEPTION: /* (F) ノ簇ーセョソナタ・ィ・鬘シ */ + CPU_EIP = CPU_PREV_EIP; + errorp = 0; + break; + + case MC_EXCEPTION: /* (A) ・゙・キ・・チ・ァ・テ・ッ */ + CPU_EIP = CPU_PREV_EIP; + errorp = 0; + break; + + case XF_EXCEPTION: /* (F) ・ケ・ネ・遙シ・゚・・ー SIMD ウネト・フソホ */ + CPU_EIP = CPU_PREV_EIP; + errorp = 0; + break; + + default: + ia32_panic("exception(): unknown exception (%d)", num); + break; + } + + if (CPU_STAT_NERROR >= 2) { + if (dftable[exctype[CPU_STAT_PREV_EXCEPTION]][exctype[num]]) { + num = DF_EXCEPTION; + } + } + CPU_STAT_PREV_EXCEPTION = num; + + INTERRUPT(num, FALSE, errorp, error_code); + CPU_STAT_NERROR = 0; + siglongjmp(exec_1step_jmpbuf, 1); +} + +/* + * ・ウ。シ・。ヲ・イ。シ・ネ。ヲ・ヌ・」・ケ・ッ・・ラ・ソ + * + * 31 16 15 14 13 12 8 7 5 4 0 + * +------------------------------------+--+-----+----------+-----+---------+ + * | ・ェ・ユ・サ・テ・ネ 31..16 | P| DPL | 0 1 1 0 0|0 0 0|・ォ・ヲ・・ネ | 4 + * +------------------------------------+--+-----+----------+-----+---------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | ・サ・ー・皈・ネ。ヲ・サ・・ッ・ソ | ・ェ・ユ・サ・テ・ネ 15..0 | 0 + * +------------------------------------+-----------------------------------+ + */ + +/* + * ウ荀ケ、゚・ヌ・」・ケ・ッ・・ラ・ソ + *-- + * ・ソ・ケ・ッ。ヲ・イ。シ・ネ + * + * 31 16 15 14 13 12 8 7 0 + * +------------------------------------+--+-----+----------+---------------+ + * | Reserved | P| DPL | 0 D 1 0 1| Reserved | 4 + * +------------------------------------+--+-----+----------+---------------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | TSS ・サ・ー・皈・ネ。ヲ・サ・・ッ・ソ | Reserved | 0 + * +------------------------------------+-----------------------------------+ + *-- + * ウ荀ケ、゚。ヲ・イ。シ・ネ + * + * 31 16 15 14 13 12 8 7 5 4 0 + * +------------------------------------+--+-----+----------+-----+---------+ + * | ・ェ・ユ・サ・テ・ネ 31..16 | P| DPL | 0 D 1 1 0|0 0 0|Reserved | 4 + * +------------------------------------+--+-----+----------+-----+---------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | ・サ・ー・皈・ネ。ヲ・サ・・ッ・ソ | ・ェ・ユ・サ・テ・ネ 15..0 | 0 + * +------------------------------------+-----------------------------------+ + *-- + * ・ネ・鬣テ・ラ。ヲ・イ。シ・ネ + * + * 31 16 15 14 13 12 8 7 5 4 0 + * +------------------------------------+--+-----+----------+-----+---------+ + * | ・ェ・ユ・サ・テ・ネ 31..16 | P| DPL | 0 D 1 1 1|0 0 0|Reserved | 4 + * +------------------------------------+--+-----+----------+-----+---------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | ・サ・ー・皈・ネ。ヲ・サ・・ッ・ソ | ・ェ・ユ・サ・テ・ネ 15..0 | 0 + * +------------------------------------+-----------------------------------+ + *-- + * DPL : ・ヌ・」・ケ・ッ・・ラ・ソニテク「・・ル・ + * ・ェ・ユ・サ・テ・ネ : ・ラ・・キ。シ・ク・罍ヲ・ィ・・ネ・遙ヲ・ン・、・・ネ、゙、ヌ、ホ・ェ・ユ・サ・テ・ネ + * P : ・サ・ー・皈・ネツクコ゚・ユ・鬣ー + * ・サ・・ッ・ソ : ・ヌ・」・ケ・ニ・」・ヘ。シ・キ・逾。ヲ・ウ。シ・ノ。ヲ・サ・ー・皈・ネ、ホ・サ・ー・皈・ネ。ヲ・サ・・ッ・ソ + * D : ・イ。シ・ネ、ホ・オ・、・コ。・0 = 16 bit, 1 = 32 bit + */ + +void +interrupt(int num, int softintp, int errorp, int error_code) +{ + DWORD idt_idx; + + VERBOSE(("interrupt: num = 0x%02x, softintp = %s, errorp = %s, error_code = %02x", num, softintp ? "on" : "off", errorp ? "on" : "off", error_code)); + + if (!CPU_STAT_PM) { + /* real mode */ + idt_idx = num * 4; + if (idt_idx + 3 > CPU_IDTR_LIMIT) { + EXCEPTION(GP_EXCEPTION, num * 4 | 2); + } + + if (!softintp) { + BYTE op = cpu_codefetch(CPU_EIP); + if (op == 0xf4) { /* hlt */ + CPU_EIP++; + } + } + + REGPUSH0(REAL_FLAGREG); + REGPUSH0(CPU_CS); + REGPUSH0(CPU_IP); + + if (softintp) { + CPU_EFLAG &= ~(T_FLAG | I_FLAG | AC_FLAG); + CPU_TRAP = 0; + } + + CPU_EIP = cpu_memoryread_w(CPU_IDTR_BASE + num * 4); + CPU_CS = cpu_memoryread_w(CPU_IDTR_BASE + num * 4 + 2); + CPU_SET_SEGREG(CPU_CS_INDEX, CPU_CS); + CPU_WORKCLOCK(20); + } else { + /* protected mode */ + selector_t task_sel, intr_sel, ss_sel; + descriptor_t gd; + int rv; + DWORD flags = REAL_EFLAGREG; + DWORD mask = 0; + DWORD new_ip, new_sp; + DWORD old_ip, old_sp; + WORD new_ss; + WORD old_cs, old_ss; + + /* VM86 && IOPL < 3 && interrupt cause == INTn */ + if (CPU_STAT_VM86 && (CPU_STAT_IOPL < CPU_IOPL3) && (softintp == -1)) { + EXCEPTION(GP_EXCEPTION, 0); + } + + idt_idx = num * 8; + if (idt_idx + 7 > CPU_IDTR_LIMIT) { + EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp); + } + + CPU_SET_GATEDESC(&gd, CPU_IDTR_BASE + idt_idx); + if (!gd.valid || !gd.p) { + EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp); + } + + switch (gd.type) { + case CPU_SYSDESC_TYPE_TASK: + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_INTR_32: + case CPU_SYSDESC_TYPE_TRAP_16: + case CPU_SYSDESC_TYPE_TRAP_32: + break; + + default: + EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp); + break; + } + + /* 5.10.1.1. ホ羌ー。ソウ荀ケ、゚・マ・・ノ・鬘ヲ・ラ・・キ。シ・ク・网ホハンク */ + if (softintp && (gd.dpl < CPU_STAT_CPL)) { + EXCEPTION(GP_EXCEPTION, num * 8 | 2); + } + + switch (gd.type) { + case CPU_SYSDESC_TYPE_TASK: + rv = parse_selector(&task_sel, gd.u.gate.selector); + if (rv < 0 || task_sel.ldt) { + EXCEPTION(TS_EXCEPTION, task_sel.idx); + } + + /* check gate type */ + switch (task_sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("interrupt: task is busy.")); + /*FALLTHROUGH*/ + default: + EXCEPTION(TS_EXCEPTION, task_sel.idx); + break; + } + + /* not present */ + if (selector_is_not_present(&task_sel)) { + EXCEPTION(NP_EXCEPTION, task_sel.idx); + } + + task_switch(&task_sel, TASK_SWITCH_INTR); + + if (errorp) { + if (task_sel.desc.type == CPU_SYSDESC_TYPE_TSS_32) { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 4); + PUSH0_32(error_code); + } else { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 2); + PUSH0_16(error_code); + } + } + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + break; + + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_INTR_32: + flags &= I_FLAG; + mask |= I_FLAG; + /*FALLTHROUGH*/ + case CPU_SYSDESC_TYPE_TRAP_16: + case CPU_SYSDESC_TYPE_TRAP_32: + flags &= ~(T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG); + mask |= T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG; + + new_ip = intr_sel.desc.u.seg.segbase; + old_ss = CPU_SS; + old_cs = CPU_CS; + old_ip = CPU_EIP; + old_sp = CPU_ESP; + + VERBOSE(("TRAP-OR-INTERRUPT-GATE")); + + rv = parse_selector(&intr_sel, gd.u.gate.selector); + if (rv < 0) { + EXCEPTION(GP_EXCEPTION, intr_sel.idx | !softintp); + } + + if (!intr_sel.desc.s + || !intr_sel.desc.u.seg.c + || (intr_sel.desc.dpl > CPU_STAT_CPL)) { + EXCEPTION(GP_EXCEPTION, intr_sel.idx | !softintp); + } + + /* not present */ + if (selector_is_not_present(&intr_sel)) { + EXCEPTION(NP_EXCEPTION, intr_sel.idx | !softintp); + } + + if (!intr_sel.desc.u.seg.ec && (intr_sel.desc.dpl < CPU_STAT_CPL)) { + DWORD stacksize; + + if (CPU_STAT_VM86) { + VERBOSE(("INTER-PRIVILEGE-LEVEL-INTERRUPT")); + stacksize = errorp ? 12 : 10; + } else { + if (intr_sel.desc.dpl != 0) { + EXCEPTION(GP_EXCEPTION, intr_sel.idx); + } + VERBOSE(("INTERRUPT-FROM-VIRTUAL-8086-MODE")); + stacksize = errorp ? 20 : 18; + } + + get_stack_from_tss(intr_sel.desc.dpl, &new_ss, &new_sp); + rv = parse_selector(&ss_sel, new_ss); + if (rv < 0) { + EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp); + } + + if ((ss_sel.rpl != intr_sel.desc.dpl) + || (ss_sel.desc.dpl != intr_sel.desc.dpl) + || !ss_sel.desc.s + || ss_sel.desc.u.seg.c + || !ss_sel.desc.u.seg.wr) { + EXCEPTION(TS_EXCEPTION, ss_sel.idx | !softintp); + } + + /* not present */ + if (selector_is_not_present(&ss_sel)) { + EXCEPTION(SS_EXCEPTION, ss_sel.idx | !softintp); + } + + switch (gd.type) { + case CPU_SYSDESC_TYPE_INTR_32: + case CPU_SYSDESC_TYPE_TRAP_32: + CHECK_STACK_PUSH(&ss_sel.desc, new_sp, stacksize * 2); + break; + + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_TRAP_16: + CHECK_STACK_PUSH(&ss_sel.desc, new_sp, stacksize); + new_ip &= 0xffff; + break; + } + + /* out of range */ + if (new_ip > intr_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + load_ss(new_ss, &ss_sel.desc, intr_sel.desc.dpl); + CPU_ESP = new_sp; + + if (!CPU_STAT_VM86) { + switch (gd.type) { + case CPU_SYSDESC_TYPE_INTR_32: + case CPU_SYSDESC_TYPE_TRAP_32: + PUSH0_32(CPU_GS); + PUSH0_32(CPU_FS); + PUSH0_32(CPU_DS); + PUSH0_32(CPU_ES); + break; + + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_TRAP_16: + PUSH0_16(CPU_GS); + PUSH0_16(CPU_FS); + PUSH0_16(CPU_DS); + PUSH0_16(CPU_ES); + break; + } + + CPU_SET_SEGREG(CPU_GS_INDEX, 0); + CPU_SET_SEGREG(CPU_FS_INDEX, 0); + CPU_SET_SEGREG(CPU_DS_INDEX, 0); + CPU_SET_SEGREG(CPU_ES_INDEX, 0); + } + + switch (gd.type) { + case CPU_SYSDESC_TYPE_INTR_32: + case CPU_SYSDESC_TYPE_TRAP_32: + PUSH0_32(old_ss); + PUSH0_32(old_sp); + PUSH0_32(REAL_EFLAGREG); + PUSH0_32(old_cs); + PUSH0_32(old_ip); + if (errorp) { + PUSH0_32(error_code); + } + break; + + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_TRAP_16: + PUSH0_16(old_ss); + PUSH0_16(old_sp); + PUSH0_16(REAL_FLAGREG); + PUSH0_16(old_cs); + PUSH0_16(old_ip); + if (errorp) { + PUSH0_16(error_code); + } + break; + } + + load_cs(intr_sel.selector, &intr_sel.desc, intr_sel.desc.dpl); + SET_EIP(new_ip); + set_eflags(flags, mask); + } else { + if (CPU_STAT_VM86 + || (!intr_sel.desc.u.seg.ec && (intr_sel.desc.dpl != CPU_STAT_CPL))) { + EXCEPTION(GP_EXCEPTION, intr_sel.idx); + } + VERBOSE(("INTRA-PRIVILEGE-LEVEL-INTERRUPT")); + + switch (gd.type) { + case CPU_SYSDESC_TYPE_INTR_32: + case CPU_SYSDESC_TYPE_TRAP_32: + CHECK_STACK_PUSH(&ss_sel.desc, new_sp, errorp ? 16 : 12); + break; + + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_TRAP_16: + CHECK_STACK_PUSH(&ss_sel.desc, new_sp, errorp ? 8 : 6); + new_ip &= 0xffff; + break; + } + + /* out of range */ + if (new_ip > intr_sel.desc.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + switch (gd.type) { + case CPU_SYSDESC_TYPE_INTR_32: + case CPU_SYSDESC_TYPE_TRAP_32: + PUSH0_32(REAL_EFLAGREG); + PUSH0_32(CPU_CS); + PUSH0_32(CPU_EIP); + if (errorp) { + PUSH0_32(error_code); + } + break; + + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_TRAP_16: + PUSH0_16(REAL_FLAGREG); + PUSH0_16(CPU_CS); + PUSH0_16(CPU_IP); + if (errorp) { + PUSH0_16(error_code); + } + break; + } + + load_cs(intr_sel.selector, &intr_sel.desc, CPU_STAT_CPL); + SET_EIP(new_ip); + set_eflags(flags, mask); + } + break; + + default: + EXCEPTION(GP_EXCEPTION, num * 8 | 2 | !softintp); + break; + } + } +} diff --git a/i386c/ia32/exception.h b/i386c/ia32/exception.h new file mode 100644 index 00000000..4246a29a --- /dev/null +++ b/i386c/ia32/exception.h @@ -0,0 +1,73 @@ +/* $Id: exception.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_EXCEPTION_H__ +#define IA32_CPU_EXCEPTION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + DE_EXCEPTION = 0, /* F */ + DB_EXCEPTION = 1, /* F/T */ + NMI_EXCEPTION = 2, /* I */ + BP_EXCEPTION = 3, /* T */ + OF_EXCEPTION = 4, /* T */ + BR_EXCEPTION = 5, /* F */ + UD_EXCEPTION = 6, /* F */ + NM_EXCEPTION = 7, /* F */ + DF_EXCEPTION = 8, /* A, Err(0) */ + /* CoProcesser Segment Overrun = 9 */ + TS_EXCEPTION = 10, /* F */ + NP_EXCEPTION = 11, /* F, Err */ + SS_EXCEPTION = 12, /* F, Err */ + GP_EXCEPTION = 13, /* F, Err */ + PF_EXCEPTION = 14, /* F, Err */ + /* Reserved = 15 */ + MF_EXCEPTION = 16, /* F */ + AC_EXCEPTION = 17, /* F, Err(0) */ + MC_EXCEPTION = 18, /* A, Err(?) */ + XF_EXCEPTION = 19, /* F */ + EXCEPTION_NUM +}; + +#define EXCEPTION(num, vec) \ + exception(num, vec); +#define INTERRUPT(num, softintp, errorp, error_code) \ + interrupt(num, softintp, errorp, error_code) + +void exception(int num, int vec); +void interrupt(int num, int softintp, int errorp, int error_code); + +#ifdef __cplusplus +} +#endif + +#endif /* !IA32_CPU_EXCEPTION_H__ */ diff --git a/i386c/ia32/groups.c b/i386c/ia32/groups.c new file mode 100644 index 00000000..d6327d0e --- /dev/null +++ b/i386c/ia32/groups.c @@ -0,0 +1,478 @@ +/* $Id: groups.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" +#include "groups.h" +#include "inst_table.h" + + +/* group 1 */ +void +Grp1_EbIb(void) +{ + DWORD op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + (*insttable_G1EbIb[idx])(reg8_b20[op]); + } else { + CPU_WORKCLOCK(7); + (*insttable_G1EbIb_ext[idx])(calc_ea_dst(op)); + } +} + +void +Grp1_EwIb(void) +{ + WORD *out; + DWORD op, madr, src; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg16_b20[op]; + GET_PCBYTES(src); + (*insttable_G1EwIx[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCBYTES(src); + (*insttable_G1EwIx_ext[idx])(madr, src); + } +} + +void +Grp1_EdIb(void) +{ + DWORD *out; + DWORD op, madr, src; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg32_b20[op]; + GET_PCBYTESD(src); + (*insttable_G1EdIx[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCBYTESD(src); + (*insttable_G1EdIx_ext[idx])(madr, src); + } +} + +void +Grp1_EwIw(void) +{ + WORD *out; + DWORD op, madr, src; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg16_b20[op]; + GET_PCWORD(src); + (*insttable_G1EwIx[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCWORD(src); + (*insttable_G1EwIx_ext[idx])(madr, src); + } +} + +void +Grp1_EdId(void) +{ + DWORD *out; + DWORD op, madr, src; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg32_b20[op]; + GET_PCDWORD(src); + (*insttable_G1EdIx[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCDWORD(src); + (*insttable_G1EdIx_ext[idx])(madr, src); + } +} + + +/* group 2 */ +void +Grp2_EbIb(void) +{ + BYTE *out; + DWORD op, madr; + int idx; + BYTE cl; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg8_b20[op]; + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EbCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EbCL_ext[idx])(madr, cl); + } +} + +void +Grp2_EwIb(void) +{ + WORD *out; + DWORD op, madr; + int idx; + BYTE cl; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg16_b20[op]; + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EwCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EwCL_ext[idx])(madr, cl); + } +} + +void +Grp2_EdIb(void) +{ + DWORD *out; + DWORD op, madr; + int idx; + BYTE cl; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg32_b20[op]; + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EdCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EdCL_ext[idx])(madr, cl); + } +} + +void +Grp2_Eb(void) +{ + DWORD op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + (*insttable_G2Eb[idx])(reg8_b20[op]); + } else { + CPU_WORKCLOCK(7); + (*insttable_G2Eb_ext[idx])(calc_ea_dst(op)); + } +} + +void +Grp2_Ew(void) +{ + DWORD op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + (*insttable_G2Ew[idx])(reg16_b20[op]); + } else { + CPU_WORKCLOCK(7); + (*insttable_G2Ew_ext[idx])(calc_ea_dst(op)); + } +} + +void +Grp2_Ed(void) +{ + DWORD op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + (*insttable_G2Ed[idx])(reg32_b20[op]); + } else { + CPU_WORKCLOCK(7); + (*insttable_G2Ed_ext[idx])(calc_ea_dst(op)); + } +} + +void +Grp2_EbCL(void) +{ + BYTE *out; + DWORD op, madr; + int idx; + BYTE cl; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg8_b20[op]; + cl = CPU_CL; + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EbCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + cl = CPU_CL; + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EbCL_ext[idx])(madr, cl); + } +} + +void +Grp2_EwCL(void) +{ + WORD *out; + DWORD op, madr; + int idx; + BYTE cl; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg16_b20[op]; + cl = CPU_CL; + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EwCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + cl = CPU_CL; + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EwCL_ext[idx])(madr, cl); + } +} + +void +Grp2_EdCL(void) +{ + DWORD *out; + DWORD op, madr; + int idx; + BYTE cl; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg32_b20[op]; + cl = CPU_CL; + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EdCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + cl = CPU_CL; + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EdCL_ext[idx])(madr, cl); + } +} + + +/* group 3 */ +void +Grp3_Eb(void) +{ + + DWORD op; + + GET_PCBYTE(op); + (*insttable_G3Eb[(op >> 3) & 7])(op); +} + +void +Grp3_Ew(void) +{ + + DWORD op; + + GET_PCBYTE(op); + (*insttable_G3Ew[(op >> 3) & 7])(op); +} + +void +Grp3_Ed(void) +{ + + DWORD op; + + GET_PCBYTE(op); + (*insttable_G3Ed[(op >> 3) & 7])(op); +} + + +/* group 4 */ +void +Grp4(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G4[(op >> 3) & 7])(op); +} + + +/* group 5 */ +void +Grp5_Ew(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G5Ew[(op >> 3) & 7])(op); +} + +void +Grp5_Ed(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G5Ed[(op >> 3) & 7])(op); +} + + +/* group 6 */ +void +Grp6_16(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G6_16[(op >> 3) & 7])(op); +} + +void +Grp6_32(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G6_32[(op >> 3) & 7])(op); +} + + +/* group 7 */ +void +Grp7_16(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G7_16[(op >> 3) & 7])(op); +} + +void +Grp7_32(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G7_32[(op >> 3) & 7])(op); +} + + +/* group 8 */ +void +Grp8_EwIb(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G8EwIb[(op >> 3) & 7])(op); +} + +void +Grp8_EdIb(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G8EdIb[(op >> 3) & 7])(op); +} + + +/* group 9 */ +void +Grp9(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_G9[(op >> 3) & 7])(op); +} diff --git a/i386c/ia32/groups.h b/i386c/ia32/groups.h new file mode 100644 index 00000000..7d99e857 --- /dev/null +++ b/i386c/ia32/groups.h @@ -0,0 +1,86 @@ +/* $Id: groups.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_GROUPS_H__ +#define IA32_CPU_GROUPS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* group 1 */ +void Grp1_EbIb(void); +void Grp1_EwIb(void); +void Grp1_EdIb(void); +void Grp1_EwIw(void); +void Grp1_EdId(void); + +/* group 2 */ +void Grp2_Eb(void); +void Grp2_Ew(void); +void Grp2_Ed(void); +void Grp2_EbCL(void); +void Grp2_EwCL(void); +void Grp2_EdCL(void); +void Grp2_EbIb(void); +void Grp2_EwIb(void); +void Grp2_EdIb(void); + +/* group 3 */ +void Grp3_Eb(void); +void Grp3_Ew(void); +void Grp3_Ed(void); + +/* group 4 */ +void Grp4(void); + +/* group 5 */ +void Grp5_Ew(void); +void Grp5_Ed(void); + +/* group 6 */ +void Grp6_16(void); +void Grp6_32(void); + +/* group 7 */ +void Grp7_16(void); +void Grp7_32(void); + +/* group 8 */ +void Grp8_EwIb(void); +void Grp8_EdIb(void); + +/* group 9 */ +void Grp9(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_GROUPS_H__ */ diff --git a/i386c/ia32/ia32.c b/i386c/ia32/ia32.c new file mode 100644 index 00000000..3073a5a2 --- /dev/null +++ b/i386c/ia32/ia32.c @@ -0,0 +1,239 @@ +/* $Id: ia32.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + + +CPU_REGS cpu_regs; +CPU_SYSREGS cpu_sysregs; +CPU_STAT cpu_stat; +CPU_INST cpu_inst; +CPU_INST cpu_inst_default; +I386CORE i386core; + +// #if defined(USE_ASM) +BYTE iflags[] = { + 0x44, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, +}; +// #endif /* USE_ASM */ + +BYTE *reg8_b20[0x100]; +BYTE *reg8_b53[0x100]; +WORD *reg16_b20[0x100]; +WORD *reg16_b53[0x100]; +DWORD *reg32_b20[0x100]; +DWORD *reg32_b53[0x100]; + + +void +ia32_init(void) +{ + int i; + + memset(&cpu_regs, 0, sizeof(cpu_regs)); + memset(&cpu_sysregs, 0, sizeof(cpu_sysregs)); + memset(&cpu_stat, 0, sizeof(cpu_stat)); + memset(&cpu_inst_default, 0, sizeof(cpu_inst_default)); + + CPU_EDX = (CPU_FAMILY << 8) | (CPU_MODEL << 4) | CPU_STEPPING; + CPU_EFLAG = 2; + CPU_CR0 = CPU_CR0_CD | CPU_CR0_NW | CPU_CR0_ET; + CPU_MXCSR = 0x1f80; + CPU_GDTR_LIMIT = 0xffff; + CPU_IDTR_LIMIT = 0xffff; + + for (i = 0; i < CPU_SEGREG_NUM; ++i) { + CPU_STAT_SREG_INIT(i); + } + CPU_LDTR_LIMIT = 0xffff; + CPU_TR_LIMIT = 0xffff; + + for (i = 0; i < 0x100; ++i) { + /* 8bit */ + if (i & 0x20) { + /* h */ + reg8_b53[i] = &CPU_REGS_BYTEH((i >> 3) & 3); + } else { + /* l */ + reg8_b53[i] = &CPU_REGS_BYTEL((i >> 3) & 3); + } + + if (i & 0x04) { + /* h */ + reg8_b20[i] = &CPU_REGS_BYTEH(i & 3); + } else { + /* l */ + reg8_b20[i] = &CPU_REGS_BYTEL(i & 3); + } + + /* 16bit */ + reg16_b53[i] = &CPU_REGS_WORD((i >> 3) & 7); + reg16_b20[i] = &CPU_REGS_WORD(i & 7); + + /* 32bit */ + reg32_b53[i] = &CPU_REGS_DWORD((i >> 3) & 7); + reg32_b20[i] = &CPU_REGS_DWORD(i & 7); + } + + resolve_init(); +#if defined(SUPPORT_TLB) + tlb_init(); +#endif +#ifdef USE_FPU + fpu_init(); +#endif +} + +/* + * ・筍シ・ノチォーワ + */ +void FASTCALL +change_pm(BOOL onoff) +{ + int i; + + if (onoff) { + for (i = 0; i < CPU_SEGREG_NUM; i++) { + CPU_STAT_SREG(i).valid = TRUE; + CPU_STAT_SREG(i).dpl = 0; + } + VERBOSE(("Entering to Protected-Mode...")); + } else { + VERBOSE(("Leaveing from Protected-Mode...")); + } + CPU_STAT_CPL = 0; + CPU_STAT_PM = onoff; +} + +void FASTCALL +change_pg(BOOL onoff) +{ + + if (onoff) { + VERBOSE(("Entering to Paging-Mode...")); + } else { + VERBOSE(("Leaveing from Pagin-Mode...")); + } + CPU_STAT_PAGING = onoff; +} + +void FASTCALL +change_vm(BOOL onoff) +{ + descriptor_t sd; + int i; + + if (onoff) { + for (i = 0; i < CPU_SEGREG_NUM; i++) { + sd.u.seg.limit = 0xffff; + CPU_SET_SEGDESC_DEFAULT(&sd, i, CPU_REGS_SREG(i)); + sd.dpl = 3; + CPU_STAT_SREG(i) = sd; + } + VERBOSE(("Entering to Virtual-8086-Mode...")); + } else { + VERBOSE(("Leaveing from Virtual-8086-Mode...")); + } + CPU_STAT_VM86 = onoff; +} + +/* + * flags + */ +static void +modify_eflags(DWORD new_flags, DWORD mask) +{ + DWORD orig = CPU_EFLAG; + + new_flags &= ALL_EFLAG; + mask &= ALL_EFLAG; + CPU_EFLAG = (REAL_EFLAGREG & ~mask) | (new_flags & mask) | 0x2; + + CPU_OV = CPU_FLAG & O_FLAG; + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); + if ((orig ^ CPU_EFLAG) & VM_FLAG) { + if (CPU_EFLAG & VM_FLAG) { + change_vm(1); + } else { + change_vm(0); + } + } +} + +void +set_flags(WORD new_flags, WORD mask) +{ + + mask &= I_FLAG|IOPL_FLAG; + mask |= SZAPC_FLAG|T_FLAG|D_FLAG|O_FLAG|NT_FLAG; + modify_eflags(new_flags, mask); +} + +void +set_eflags(DWORD new_flags, DWORD mask) +{ + + mask &= I_FLAG|IOPL_FLAG|RF_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG; + mask |= SZAPC_FLAG|T_FLAG|D_FLAG|O_FLAG|NT_FLAG; + mask |= AC_FLAG|ID_FLAG; + modify_eflags(new_flags, mask); +} diff --git a/i386c/ia32/ia32.mcr b/i386c/ia32/ia32.mcr new file mode 100644 index 00000000..f6e843ad --- /dev/null +++ b/i386c/ia32/ia32.mcr @@ -0,0 +1,972 @@ +/* $Id: ia32.mcr,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_IA32_MCR__ +#define IA32_CPU_IA32_MCR__ + +/* + * misc + */ +#define __CBW(src) ((WORD)((SBYTE)(src))) +#define __CBD(src) ((DWORD)((SBYTE)(src))) +#define __CWDE(src) ((SWORD)(src)) + +#define SWAPBYTE(p, q) \ +do { \ + BYTE __tmp = (p); \ + (p) = (q); \ + (q) = __tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SWAPWORD(p, q) \ +do { \ + WORD __tmp = (p); \ + (p) = (q); \ + (q) = __tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SWAPDWORD(p, q) \ +do { \ + DWORD __tmp = (p); \ + (p) = (q); \ + (q) = __tmp; \ +} while (/*CONSTCOND*/ 0) + +/* + * bswap + */ +#if defined(bswap32) && !defined(USE_ASM_BSWAP) +#define BSWAP_DWORD(v) bswap32(v) +#else /* !bswap32 || USE_ASM_BSWAP */ +INLINE static DWORD +BSWAP_DWORD(DWORD val) +{ +#if defined(__GNUC__) && (defined(i386) || defined(__i386__)) + __asm__ __volatile__ ( +#if defined(USE_ASM_BSWAP) + "bswap %0" +#else /* !USE_ASM_BSWAP */ + "rorw $8, %w1\n\t" + "rorl $16, %1\n\t" + "rorw $8, %w1\n\t" +#endif /* USE_ASM_BSWAP */ + : "=r" (val) : "0" (val)); + return val; +#else /* !(__GNUC__ && (i386 || __i386__)) */ + DWORD v; + v = (val & 0x000000ff) << 24; + v |= (val & 0x0000ff00) << 8; + v |= (val & 0x00ff0000) >> 8; + v |= (val & 0xff000000) >> 24; + return v; +#endif /* __GNUC__ && (i386 || __i386__) */ +} +#endif /* bswap32 && !USE_ASM_BSWAP */ + + +/* + * clock + */ +#ifndef DONT_USE_NEVENT +#define CPU_WORKCLOCK(clock) \ +do { \ + CPU_REMCLOCK -= (clock); \ +} while (/*CONSTCOND*/ 0) + +#define CPU_HALT() \ +do { \ + CPU_REMCLOCK = -1; \ +} while (/*CONSTCOND*/ 0) + +#define IRQCHECKTERM() \ +do { \ + if (CPU_REMCLOCK > 0) { \ + CPU_BASECLOCK -= CPU_REMCLOCK; \ + CPU_REMCLOCK = 0; \ + } \ +} while (/*CONSTCOND*/ 0) +#endif + + +#define SET_EIP(v) \ +do { \ + DWORD __new_ip = (v); \ + if (!CPU_INST_OP32) { \ + __new_ip &= 0x0000ffff; \ + } \ + if (__new_ip > CPU_STAT_CS_LIMIT) { \ + EXCEPTION(GP_EXCEPTION, 0); \ + } \ + CPU_EIP = __new_ip; \ +} while (/*CONSTCOND*/ 0) + +#define ADD_EIP(v) \ +do { \ + DWORD __tmp_ip = CPU_EIP + (v); \ + if (!CPU_INST_OP32) { \ + __tmp_ip &= 0x0000ffff; \ + } \ + if (__tmp_ip > CPU_STAT_CS_LIMIT) { \ + EXCEPTION(GP_EXCEPTION, 0); \ + } \ + CPU_EIP = __tmp_ip; \ +} while (/*CONSTCOND*/ 0) + + +#define GET_PCBYTE(v) \ +do { \ + (v) = cpu_codefetch(CPU_EIP); \ + ADD_EIP(1); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCBYTES(v) \ +do { \ + (v) = __CBW(cpu_codefetch(CPU_EIP)); \ + ADD_EIP(1); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCBYTESD(v) \ +do { \ + (v) = __CBD(cpu_codefetch(CPU_EIP)); \ + ADD_EIP(1); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCWORD(v) \ +do { \ + (v) = cpu_codefetch_w(CPU_EIP); \ + ADD_EIP(2); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCWORDS(v) \ +do { \ + (v) = __CWDE(cpu_codefetch_w(CPU_EIP)); \ + ADD_EIP(2); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCDWORD(v) \ +do { \ + (v) = cpu_codefetch_d(CPU_EIP); \ + ADD_EIP(4); \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG8(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = *(reg8_b53[(b)]); \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG8P(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = reg8_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG16(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = *(reg16_b53[(b)]); \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG16P(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = reg16_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG32(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = *(reg32_b53[(b)]); \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG32P(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = reg32_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG8_EA(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg8_b20[(b)]); \ + } else { \ + DWORD __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg8_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG16_EA(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg16_b20[(b)]); \ + } else { \ + DWORD __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg16_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG16_EA8(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg8_b20[(b)]); \ + } else { \ + DWORD __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg16_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG32_EA(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg32_b20[(b)]); \ + } else { \ + DWORD __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg32_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG32_EA8(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg8_b20[(b)]); \ + } else { \ + DWORD __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg32_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG32_EA16(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg16_b20[(b)]); \ + } else { \ + DWORD __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg32_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + + +/* + * arith + */ +#define _ADDBYTE(r, d, s) \ +do { \ + (r) = (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(r) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _ADDWORD(r, d, s) \ +do { \ + (r) = (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x8000; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) & 0xffff0000) { \ + (r) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(WORD)(r)]; \ +} while (/*CONSTCOND*/ 0) + +#define _ADDDWORD(r, d, s) \ +do { \ + (r) = (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80000000; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) < (s)) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((r) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((r) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(BYTE)(r)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _ORBYTE(d, s) \ +do { \ + (d) |= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(BYTE)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _ORWORD(d, s) \ +do { \ + (d) |= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpflag_w[(WORD)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _ORDWORD(d, s) \ +do { \ + (d) |= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(BYTE)(d)] & P_FLAG; \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define _ADCBYTE(r, d, s) \ +do { \ + (r) = (CPU_FLAGL & C_FLAG) + (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(r) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _ADCWORD(r, d, s) \ +do { \ + (r) = (CPU_FLAGL & C_FLAG) + (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x8000; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) & 0xffff0000) { \ + (r) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(WORD)(r)]; \ +} while (/*CONSTCOND*/ 0) + +#define _ADCDWORD(r, d, s) \ +do { \ + (r) = (CPU_FLAGL & C_FLAG) + (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80000000; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) < (s)) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((r) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((r) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(BYTE)(r)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define _BYTE_SBB(r, d, s) \ +do { \ + (r) = (d) - (s) - (CPU_FLAGL & C_FLAG); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(r) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SBB(r, d, s) \ +do { \ + (r) = (d) - (s) - (CPU_FLAGL & C_FLAG); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x8000; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) & 0xffff0000) { \ + (r) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(WORD)(r)]; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SBB(r, d, s) \ +do { \ + (r) = (d) - (s) - (CPU_FLAGL & C_FLAG); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80000000; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((d) < (s)) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((r) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((r) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(BYTE)(r)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _ANDBYTE(d, s) \ +do { \ + (d) &= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(BYTE)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _ANDWORD(d, s) \ +do { \ + (d) &= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpflag_w[(WORD)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _ANDDWORD(d, s) \ +do { \ + (d) &= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(BYTE)(d)] & P_FLAG; \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_SUB(r, d, s) \ +do { \ + (r) = (d) - (s); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(r) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SUB(r, d, s) \ +do { \ + (r) = (d) - (s); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x8000; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) & 0xffff0000) { \ + (r) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(WORD)(r)]; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SUB(r, d, s) \ +do { \ + (r) = (d) - (s); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80000000; \ + CPU_FLAGL = (BYTE)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((d) < (s)) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((r) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((r) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(BYTE)(r)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_XOR(d, s) \ +do { \ + (d) ^= s; \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(BYTE)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_XOR(d, s) \ +do { \ + (d) ^= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpflag_w[(WORD)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_XOR(d, s) \ +do { \ + (d) ^= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(BYTE)(d)] & P_FLAG; \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_NEG(d, s) \ +do { \ + (d) = 0 - (s); \ + CPU_OV = ((d) & (s)) & 0x80; \ + CPU_FLAGL = (BYTE)(((d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(d) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_NEG(d, s) \ +do { \ + (d) = 0 - (s); \ + CPU_OV = ((d) & (s)) & 0x8000; \ + CPU_FLAGL = (BYTE)(((d) ^ (s)) & A_FLAG); \ + if ((d) & 0xffff0000) { \ + (d) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(WORD)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_NEG(d, s) \ +do { \ + (d) = 0 - (s); \ + CPU_OV = ((d) & (s)) & 0x80000000; \ + CPU_FLAGL = (BYTE)(((d) ^ (s)) & A_FLAG); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } else { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(BYTE)(d)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_MUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (BYTE)(d) * (BYTE)(s); \ + CPU_OV = (r) >> 8; \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_MUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (WORD)(d) * (WORD)(s); \ + CPU_OV = (r) >> 16; \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_MUL(r, d, s) \ +do { \ + QWORD __v; \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + __v = (QWORD)(d) * (QWORD)(s); \ + (r) = (DWORD)__v; \ + CPU_OV = (DWORD)(__v >> 32); \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_IMUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (SBYTE)(d) * (SBYTE)(s); \ + CPU_OV = ((r) + 0x80) & 0xffffff00; \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_IMUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (SWORD)(d) * (SWORD)(s); \ + /* -32768 < r < 32767 (CF = OV = 0) */ \ + /* 0xffff8000 < r < 0x00007fff (CF = OV = 0) */ \ + /* 0x00000000 < r + 0x8000 < 0x0000ffff (CF = OV = 0) */ \ + CPU_OV = ((r) + 0x8000) & 0xffff0000; \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_IMUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (SQWORD)(d) * (SQWORD)(s); \ + CPU_OV = (DWORD)(((r) + 0x80000000ULL) >> 32); \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define _BYTE_INC(s) \ +do { \ + BYTE __b = (s); \ + __b++; \ + CPU_OV = __b & (__b ^ (s)) & 0x80; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (BYTE)((__b ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[__b]; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_INC(s) \ +do { \ + WORD __b = (s); \ + __b++; \ + CPU_OV = __b & (__b ^ (s)) & 0x8000; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (BYTE)((__b ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpflag_w[__b]; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_INC(s) \ +do { \ + DWORD __b = (s); \ + __b++; \ + CPU_OV = __b & (__b ^ (s)) & 0x80000000; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (BYTE)((__b ^ (s)) & A_FLAG); \ + if (__b == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if (__b & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(BYTE)(__b)] & P_FLAG; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define _BYTE_DEC(s) \ +do { \ + BYTE __b = (s); \ + __b--; \ + CPU_OV = (s) & (__b ^ (s)) & 0x80; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (BYTE)((__b ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[__b]; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_DEC(s) \ +do { \ + WORD __b = (s); \ + __b--; \ + CPU_OV = (s) & (__b ^ (s)) & 0x8000; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (BYTE)((__b ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpflag_w[__b]; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_DEC(s) \ +do { \ + DWORD __b = (s); \ + __b--; \ + CPU_OV = (s) & (__b ^ (s)) & 0x80000000; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (BYTE)((__b ^ (s)) & A_FLAG); \ + if ((__b) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((__b) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(BYTE)(__b)] & P_FLAG; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + + +/* + * stack + */ +#define REGPUSH(reg, clock) \ +do { \ + CPU_SP -= 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, reg); \ + CPU_WORKCLOCK(clock); \ +} while (/*CONSTCOND*/ 0) + +#define REGPUSH_32(reg, clock) \ +do { \ + CPU_ESP -= 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_ESP, reg); \ + CPU_WORKCLOCK(clock); \ +} while (/*CONSTCOND*/ 0) + +#define REGPUSH0(reg) \ +do { \ + CPU_SP -= 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, reg); \ +} while (/*CONSTCOND*/ 0) + +/* Operand Size == 16 && Stack Size == 32 */ +#define REGPUSH0_16_32(reg) \ +do { \ + CPU_ESP -= 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_ESP, reg); \ +} while (/*CONSTCOND*/ 0) + +/* Operand Size == 32 && Stack Size == 16 */ +#define REGPUSH0_32_16(reg) \ +do { \ + CPU_SP -= 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_SP, reg); \ +} while (/*CONSTCOND*/ 0) + +#define REGPUSH0_32(reg) \ +do { \ + CPU_ESP -= 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_ESP, reg); \ +} while (/*CONSTCOND*/ 0) + +#define SP_PUSH(reg, clock) \ +do { \ + WORD sp = CPU_SP; \ + CPU_SP -= 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, sp); \ + CPU_WORKCLOCK(clock); \ +} while (/*CONSTCOND*/ 0) + +#define SP_PUSH0(reg) \ +do { \ + WORD sp = CPU_SP; \ + CPU_SP -= 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, sp); \ +} while (/*CONSTCOND*/ 0) + +#define SP_PUSH0_16_32(reg) \ +do { \ + WORD sp = CPU_SP; \ + CPU_ESP -= 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_ESP, sp); \ +} while (/*CONSTCOND*/ 0) + +#define ESP_PUSH(reg, clock) \ +do { \ + DWORD esp = CPU_ESP; \ + CPU_ESP -= 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_ESP, esp); \ + CPU_WORKCLOCK(clock); \ +} while (/*CONSTCOND*/ 0) + +#define ESP_PUSH0_32_16(reg) \ +do { \ + DWORD esp = CPU_ESP; \ + CPU_SP -= 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_SP, esp); \ +} while (/*CONSTCOND*/ 0) + +#define ESP_PUSH0_32(reg) \ +do { \ + DWORD esp = CPU_ESP; \ + CPU_ESP -= 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_ESP, esp); \ +} while (/*CONSTCOND*/ 0) + +#define PUSH0_16(reg) \ +do { \ + if (!CPU_STAT_SS32) { \ + REGPUSH0(reg); \ + } else { \ + REGPUSH0_16_32(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define PUSH0_32(reg) \ +do { \ + if (!CPU_STAT_SS32) { \ + REGPUSH0_32_16(reg); \ + } else { \ + REGPUSH0_32(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XPUSH0(reg) \ +do { \ + if (!CPU_INST_OP32) { \ + PUSH0_16(reg); \ + } else { \ + PUSH0_32(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define SP_PUSH0_16(reg) \ +do { \ + WORD sp = CPU_SP; \ + if (!CPU_STAT_SS32) { \ + CPU_SP -= 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, sp); \ + } else { \ + CPU_ESP -= 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_ESP, sp); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define SP_PUSH0_32(reg) \ +do { \ + DWORD esp = CPU_ESP; \ + if (!CPU_STAT_SS32) { \ + CPU_SP -= 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_SP, esp); \ + } else { \ + CPU_ESP -= 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_ESP, esp); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP(reg, clock) \ +do { \ + (reg) = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP); \ + CPU_SP += 2; \ + CPU_WORKCLOCK(clock); \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP_32(reg, clock) \ +do { \ + (reg) = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP); \ + CPU_ESP += 4; \ + CPU_WORKCLOCK(clock); \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP0(reg) \ +do { \ + (reg) = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP); \ + CPU_SP += 2; \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP0_16_32(reg) \ +do { \ + (reg) = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP); \ + CPU_ESP += 2; \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP0_32_16(reg) \ +do { \ + (reg) = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_SP); \ + CPU_SP += 4; \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP0_32(reg) \ +do { \ + (reg) = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP); \ + CPU_ESP += 4; \ +} while (/*CONSTCOND*/ 0) + +#define POP0_16(reg) \ +do { \ + if (!CPU_STAT_SS32) { \ + REGPOP0(reg); \ + } else { \ + REGPOP0_16_32(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define POP0_32(reg) \ +do { \ + if (!CPU_STAT_SS32) { \ + REGPOP0_32_16(reg); \ + } else { \ + REGPOP0_32(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define SP_POP0_16(reg) \ +do { \ + if (!CPU_STAT_SS32) { \ + (reg) = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP); \ + } else { \ + (reg) = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define ESP_POP0_32(reg) \ +do { \ + if (!CPU_STAT_SS32) { \ + (reg) = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_SP); \ + } else { \ + (reg) = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* + * jump + */ +#define JMPSHORT(clock) \ +do { \ + DWORD __ip; \ + CPU_WORKCLOCK(clock); \ + __ip = __CBD(cpu_codefetch(CPU_EIP)); \ + __ip++; \ + ADD_EIP(__ip); \ +} while (/*CONSTCOND*/ 0) + +#define JMPNEAR(clock) \ +do { \ + WORD __ip; \ + CPU_WORKCLOCK(clock); \ + __ip = __CWDE(cpu_codefetch_w(CPU_EIP)); \ + __ip += 2; \ + ADD_EIP(__ip); \ +} while (/*CONSTCOND*/ 0) + +#define JMPNEAR_4(clock) \ +do { \ + DWORD __ip; \ + CPU_WORKCLOCK(clock); \ + __ip = cpu_codefetch_d(CPU_EIP); \ + __ip += 4; \ + ADD_EIP(__ip); \ +} while (/*CONSTCOND*/ 0) + +#define JMPNOP(clock, d) \ +do { \ + CPU_WORKCLOCK(clock); \ + ADD_EIP((d)); \ +} while (/*CONSTCOND*/ 0) + +/* instruction check */ +#include "ia32xc.mcr" + +#endif /* IA32_CPU_IA32_MCR__ */ diff --git a/i386c/ia32/ia32xc.mcr b/i386c/ia32/ia32xc.mcr new file mode 100644 index 00000000..bca03c25 --- /dev/null +++ b/i386c/ia32/ia32xc.mcr @@ -0,0 +1,1684 @@ +/* $Id: ia32xc.mcr,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_IA32XC_MCR__ +#define IA32_CPU_IA32XC_MCR__ + +#if defined(IA32_CROSS_CHECK) && defined(__GNUC__) && (defined(i386) || defined(__i386__)) + +#define IA32_CPU_ENABLE_XC + +/* + * arith + */ +#define XC_ADDBYTE(r, d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __d = (d) & 0xff; \ + BYTE __r = __d; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ADDBYTE((r), (d), (s)); \ + __R = (r) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "addb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADDBYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_ADDBYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_ADDBYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADDBYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ADDWORD(r, d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ADDWORD((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "addw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax", "ecx"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADDWORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_ADDWORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_ADDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ADDDWORD(r, d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ADDDWORD((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "addl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax", "ecx"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADDDWORD: __s = %08x, __d = %08x", __s, __d); \ + ia32_warning("XC_ADDDWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_ADDDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADDDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ORBYTE(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __d = (d) & 0xff; \ + BYTE __r = __d; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ORBYTE((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "orb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ORBYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_ORBYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_ORBYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ORBYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ORWORD(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ORWORD((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "orw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ORWORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_ORWORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_ORWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ORWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ORDWORD(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ORDWORD((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "orl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ORDWORD: __s = %08x, __d = %08x", __s, __d); \ + ia32_warning("XC_ORDWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_ORDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ORDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define XC_ADCBYTE(r, d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __d = (d) & 0xff; \ + BYTE __r = __d; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _ADCBYTE((r), (d), (s)); \ + __R = (r) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "adcb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADCBYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_ADCBYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_ADCBYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADCBYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ADCWORD(r, d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _ADCWORD((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "adcw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADCWORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_ADCWORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_ADCWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADCWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ADCDWORD(r, d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _ADCDWORD((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "adcl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADCDWORD: __s = %08x, __d = %08x", __s, __d); \ + ia32_warning("XC_ADCDWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_ADCDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADCDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define XC_BYTE_SBB(r, d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __d = (d) & 0xff; \ + BYTE __r = __d; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_SBB((r), (d), (s)); \ + __R = (r) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "sbbb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SBB: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_BYTE_SBB: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SBB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_BYTE_SBB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SBB(r, d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _WORD_SBB((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "sbbw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SBB: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_WORD_SBB: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SBB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_WORD_SBB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SBB(r, d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_SBB((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "sbbl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SBB: __s = %08x, __d = %08x", __s, __d);\ + ia32_warning("XC_DWORD_SBB: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SBB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_DWORD_SBB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ANDBYTE(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __d = (d) & 0xff; \ + BYTE __r = __d; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ANDBYTE((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "andb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ANDBYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_ANDBYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_ANDBYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ANDBYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ANDWORD(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ANDWORD((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "andw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ANDWORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_ANDWORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_ANDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ANDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ANDDWORD(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _ANDDWORD((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "andl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ANDDWORD: __s = %08x, __d = %08x", __s, __d); \ + ia32_warning("XC_ANDDWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_ANDDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ANDDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SUB(r, d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __d = (d) & 0xff; \ + BYTE __r = __d; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_SUB((r), (d), (s)); \ + __R = (r) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "subb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SUB: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_BYTE_SUB: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SUB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_BYTE_SUB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SUB(r, d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SUB((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "subw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SUB: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_WORD_SUB: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SUB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_WORD_SUB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SUB(r, d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SUB((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "subl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SUB: __s = %08x, __d = %08x", __s, __d);\ + ia32_warning("XC_DWORD_SUB: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SUB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_DWORD_SUB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_XOR(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __d = (d) & 0xff; \ + BYTE __r = __d; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_XOR((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "xorb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_XORBYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_XORBYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_XORBYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_XORBYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_XOR(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_XOR((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "xorw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_XORWORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_XORWORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_XORWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_XORWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_XOR(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_XOR((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "xorl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_XORDWORD: __s = %08x, __d = %08x", __s, __d); \ + ia32_warning("XC_XORDWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_XORDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_XORDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_NEG(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_NEG((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "negb %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_NEG: __s = %02x", __s); \ + ia32_warning("XC_BYTE_NEG: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_NEG: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_BYTE_NEG: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_NEG(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_NEG((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "negw %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_NEG: __s = %04x", __s); \ + ia32_warning("XC_WORD_NEG: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_NEG: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_WORD_NEG: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_NEG(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_NEG((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "negl %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_NEG: __s = %08x", __s);\ + ia32_warning("XC_DWORD_NEG: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_NEG: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_DWORD_NEG: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_MUL(r, d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __d = (d) & 0xff; \ + WORD __r; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_MUL((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "movb %4, %%ah\n\t" \ + "mulb %%ah\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_MUL: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_BYTE_MUL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_MUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_MUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_MUL(r, d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + DWORD __r; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_MUL((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "push %%edx\n\t" \ + "movw %3, %%ax\n\t" \ + "movw %4, %%dx\n\t" \ + "mulw %%dx\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "andl $0x0000ffff, %0\n\t" \ + "shll $16, %%edx\n\t" \ + "orl %%edx, %0\n\t" \ + "popl %%edx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax", "edx"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_MUL: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_WORD_MUL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_WORD_MUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_MUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_MUL(r, d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r; \ + DWORD __h; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_MUL((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "push %%edx\n\t" \ + "movl %4, %%eax\n\t" \ + "movl %5, %%edx\n\t" \ + "mull %%edx\n\t" \ + "movl %%eax, %0\n\t" \ + "movl %%edx, %1\n\t" \ + "lahf\n\t" \ + "movb %%ah, %2\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %3\n\t" \ + "popl %%edx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__h), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax", "edx"); \ + if ((__R != __r) || \ + (CPU_OV != __h) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_MUL: __s = %08x, __d = %08x", __s, __d);\ + ia32_warning("XC_DWORD_MUL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_MUL: CPU_OV == %08x, __h == %08x", \ + CPU_OV, __h); \ + ia32_warning("XC_DWORD_MUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_MUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_IMUL(r, d, s) \ +do { \ + SBYTE __s = (s) & 0xff; \ + SBYTE __d = (d) & 0xff; \ + SWORD __R; \ + SWORD __r; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_IMUL((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "movb %4, %%ah\n\t" \ + "imulb %%ah\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_IMUL: __s = %02x, __d = %02x", __s, __d);\ + ia32_warning("XC_BYTE_IMUL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_BYTE_IMUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_IMUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_IMUL(r, d, s) \ +do { \ + SWORD __s = (s) & 0xffff; \ + SWORD __d = (d) & 0xffff; \ + SDWORD __r; \ + SDWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_IMUL((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "push %%edx\n\t" \ + "movw %3, %%ax\n\t" \ + "movw %4, %%dx\n\t" \ + "imulw %%dx\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "andl $0x0000ffff, %0\n\t" \ + "shll $16, %%edx\n\t" \ + "orl %%edx, %0\n\t" \ + "popl %%edx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax", "edx"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_IMUL: __s = %04x, __d = %04x", __s, __d);\ + ia32_warning("XC_WORD_IMUL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_WORD_IMUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_IMUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_IMUL(r, d, s) \ +do { \ + SQWORD __R; \ + SDWORD __s = (s); \ + SDWORD __d = (d); \ + DWORD __r; \ + DWORD __h; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_IMUL((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "push %%edx\n\t" \ + "movl %4, %%eax\n\t" \ + "movl %5, %%edx\n\t" \ + "imull %%edx\n\t" \ + "movl %%eax, %0\n\t" \ + "movl %%edx, %1\n\t" \ + "lahf\n\t" \ + "movb %%ah, %2\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %3\n\t" \ + "popl %%edx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__h), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax", "edx"); \ + if (((DWORD)__R != __r) || \ + ((DWORD)(__R >> 32) != __h) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_IMUL: __s = %08x, __d = %08x",__s, __d);\ + ia32_warning("XC_DWORD_IMUL: __Rl = %08x, __r = %08x", \ + (DWORD)__R, __r); \ + ia32_warning("XC_DWORD_IMUL: __Rh == %08x, __h == %08x", \ + (DWORD)(__R >> 32), __h); \ + ia32_warning("XC_DWORD_IMUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_IMUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert((DWORD)__R == __r); \ + assert((DWORD)(__R >> 32) == __h); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define XC_BYTE_INC(s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_INC((s)); \ + __R = (s) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "incb %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_INC: __s = %02x", __s); \ + ia32_warning("XC_BYTE_INC: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_INC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_BYTE_INC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_INC(s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_INC((s)); \ + __R = (s) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "incw %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_INC: __s = %04x", __s); \ + ia32_warning("XC_WORD_INC: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_INC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_WORD_INC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_INC(s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_INC((s)); \ + __R = (s); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "incl %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_INC: __s = %08x", __s); \ + ia32_warning("XC_DWORD_INC: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_INC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_DWORD_INC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define XC_BYTE_DEC(s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_DEC((s)); \ + __R = (s) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "decb %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_DEC: __s = %02x", __s); \ + ia32_warning("XC_BYTE_DEC: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_DEC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_BYTE_DEC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_DEC(s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_DEC((s)); \ + __R = (s) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "decw %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_DEC: __s = %04x", __s); \ + ia32_warning("XC_WORD_DEC: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_DEC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_WORD_DEC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_DEC(s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_DEC((s)); \ + __R = (s); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "decl %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_DEC: __s = %08x", __s); \ + ia32_warning("XC_DWORD_DEC: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_DEC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_DWORD_DEC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define ADDBYTE(r, d, s) XC_ADDBYTE(r, d, s) +#define ADDWORD(r, d, s) XC_ADDWORD(r, d, s) +#define ADDDWORD(r, d, s) XC_ADDDWORD(r, d, s) +#define ORBYTE(d, s) XC_ORBYTE(d, s) +#define ORWORD(d, s) XC_ORWORD(d, s) +#define ORDWORD(d, s) XC_ORDWORD(d, s) +#define ADCBYTE(r, d, s) XC_ADCBYTE(r, d, s) +#define ADCWORD(r, d, s) XC_ADCWORD(r, d, s) +#define ADCDWORD(r, d, s) XC_ADCDWORD(r, d, s) +#define BYTE_SBB(r, d, s) XC_BYTE_SBB(r, d, s) +#define WORD_SBB(r, d, s) XC_WORD_SBB(r, d, s) +#define DWORD_SBB(r, d, s) XC_DWORD_SBB(r, d, s) +#define ANDBYTE(d, s) XC_ANDBYTE(d, s) +#define ANDWORD(d, s) XC_ANDWORD(d, s) +#define ANDDWORD(d, s) XC_ANDDWORD(d, s) +#define BYTE_SUB(r, d, s) XC_BYTE_SUB(r, d, s) +#define WORD_SUB(r, d, s) XC_WORD_SUB(r, d, s) +#define DWORD_SUB(r, d, s) XC_DWORD_SUB(r, d, s) +#define BYTE_XOR(d, s) XC_BYTE_XOR(d, s) +#define WORD_XOR(d, s) XC_WORD_XOR(d, s) +#define DWORD_XOR(d, s) XC_DWORD_XOR(d, s) +#define BYTE_NEG(d, s) XC_BYTE_NEG(d, s) +#define WORD_NEG(d, s) XC_WORD_NEG(d, s) +#define DWORD_NEG(d, s) XC_DWORD_NEG(d, s) +#define BYTE_MUL(r, d, s) XC_BYTE_MUL(r, d, s) +#define WORD_MUL(r, d, s) XC_WORD_MUL(r, d, s) +#define DWORD_MUL(r, d, s) XC_DWORD_MUL(r, d, s) +#define BYTE_IMUL(r, d, s) XC_BYTE_IMUL(r, d, s) +#define WORD_IMUL(r, d, s) XC_WORD_IMUL(r, d, s) +#define DWORD_IMUL(r, d, s) XC_DWORD_IMUL(r, d, s) +#define BYTE_INC(s) XC_BYTE_INC(s) +#define WORD_INC(s) XC_WORD_INC(s) +#define DWORD_INC(s) XC_DWORD_INC(s) +#define BYTE_DEC(s) XC_BYTE_DEC(s) +#define WORD_DEC(s) XC_WORD_DEC(s) +#define DWORD_DEC(s) XC_DWORD_DEC(s) + +#define XC_STORE_FLAGL() WORD __xc_flagl = CPU_FLAGL + +#else /* !(IA32_CROSS_CHECK && __GNUC__ && (i386) || __i386__)) */ + +#define ADDBYTE(r, d, s) _ADDBYTE(r, d, s) +#define ADDWORD(r, d, s) _ADDWORD(r, d, s) +#define ADDDWORD(r, d, s) _ADDDWORD(r, d, s) +#define ORBYTE(d, s) _ORBYTE(d, s) +#define ORWORD(d, s) _ORWORD(d, s) +#define ORDWORD(d, s) _ORDWORD(d, s) +#define ADCBYTE(r, d, s) _ADCBYTE(r, d, s) +#define ADCWORD(r, d, s) _ADCWORD(r, d, s) +#define ADCDWORD(r, d, s) _ADCDWORD(r, d, s) +#define BYTE_SBB(r, d, s) _BYTE_SBB(r, d, s) +#define WORD_SBB(r, d, s) _WORD_SBB(r, d, s) +#define DWORD_SBB(r, d, s) _DWORD_SBB(r, d, s) +#define ANDBYTE(d, s) _ANDBYTE(d, s) +#define ANDWORD(d, s) _ANDWORD(d, s) +#define ANDDWORD(d, s) _ANDDWORD(d, s) +#define BYTE_SUB(r, d, s) _BYTE_SUB(r, d, s) +#define WORD_SUB(r, d, s) _WORD_SUB(r, d, s) +#define DWORD_SUB(r, d, s) _DWORD_SUB(r, d, s) +#define BYTE_XOR(d, s) _BYTE_XOR(d, s) +#define WORD_XOR(d, s) _WORD_XOR(d, s) +#define DWORD_XOR(d, s) _DWORD_XOR(d, s) +#define BYTE_NEG(d, s) _BYTE_NEG(d, s) +#define WORD_NEG(d, s) _WORD_NEG(d, s) +#define DWORD_NEG(d, s) _DWORD_NEG(d, s) +#define BYTE_MUL(r, d, s) _BYTE_MUL(r, d, s) +#define WORD_MUL(r, d, s) _WORD_MUL(r, d, s) +#define DWORD_MUL(r, d, s) _DWORD_MUL(r, d, s) +#define BYTE_IMUL(r, d, s) _BYTE_IMUL(r, d, s) +#define WORD_IMUL(r, d, s) _WORD_IMUL(r, d, s) +#define DWORD_IMUL(r, d, s) _DWORD_IMUL(r, d, s) +#define BYTE_INC(s) _BYTE_INC(s) +#define WORD_INC(s) _WORD_INC(s) +#define DWORD_INC(s) _DWORD_INC(s) +#define BYTE_DEC(s) _BYTE_DEC(s) +#define WORD_DEC(s) _WORD_DEC(s) +#define DWORD_DEC(s) _DWORD_DEC(s) + +#define XC_STORE_FLAGL() + +#endif /* IA32_CROSS_CHECK && __GNUC__ && (i386) || __i386__) */ + +#endif /* IA32_CPU_IA32_MCR__ */ diff --git a/i386c/ia32/inst_table.c b/i386c/ia32/inst_table.c new file mode 100644 index 00000000..9ad8d138 --- /dev/null +++ b/i386c/ia32/inst_table.c @@ -0,0 +1,1794 @@ +/* $Id: inst_table.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" + +#include "inst_table.h" +#include "groups.h" + +#include "bin_arith.h" +#include "bit_byte.h" +#include "ctrl_trans.h" +#include "data_trans.h" +#include "dec_arith.h" +#include "flag_ctrl.h" +#include "logic_arith.h" +#include "misc_inst.h" +#include "seg_reg.h" +#include "shift_rotate.h" +#include "string_inst.h" +#include "system_inst.h" + +#include "fp.h" + + +/* + * UNDEF OP + */ +static void +undef_op(void) +{ + + EXCEPTION(UD_EXCEPTION, 0); +} + +static void +undef_op2(DWORD v) +{ + +// UNUSED(v); + EXCEPTION(UD_EXCEPTION, 0); +} + + +BYTE insttable_info[256] = { + 0, /* 00 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 08 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 10 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 18 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 20 */ + 0, + 0, + 0, + 0, + 0, + INST_PREFIX, /* ES: */ + 0, + 0, /* 28 */ + 0, + 0, + 0, + 0, + 0, + INST_PREFIX, /* CS: */ + 0, + + 0, /* 30 */ + 0, + 0, + 0, + 0, + 0, + INST_PREFIX, /* SS: */ + 0, + 0, /* 38 */ + 0, + 0, + 0, + 0, + 0, + INST_PREFIX, /* DS: */ + 0, + + 0, /* 40 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 48 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 50 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 58 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 60 */ + 0, + 0, + 0, + INST_PREFIX, /* FS: */ + INST_PREFIX, /* GS: */ + INST_PREFIX, /* OpSize: */ + INST_PREFIX, /* AddrSize: */ + 0, /* 68 */ + 0, + 0, + 0, + INST_STRING, /* INSB_YbDX */ + INST_STRING, /* INSW_YvDX */ + INST_STRING, /* OUTSB_DXXb */ + INST_STRING, /* OUTSW_DXXv */ + + 0, /* 70 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 78 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 80 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 88 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 90 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 98 */ + 0, + 0, + INST_PREFIX, /* FWAIT */ + 0, + 0, + 0, + 0, + + 0, /* A0 */ + 0, + 0, + 0, + INST_STRING, /* MOVSB_XbYb */ + INST_STRING, /* MOVSW_XvYv */ + INST_STRING | REP_CHECKZF, /* CMPSB_XbYb */ + INST_STRING | REP_CHECKZF, /* CMPSW_XvYv */ + 0, /* A8 */ + 0, + INST_STRING, /* STOSB_YbAL */ + INST_STRING, /* STOSW_YveAX */ + INST_STRING, /* LODSB_ALXb */ + INST_STRING, /* LODSW_eAXXv */ + INST_STRING | REP_CHECKZF, /* SCASB_ALXb */ + INST_STRING | REP_CHECKZF, /* SCASW_eAXXv */ + + 0, /* B0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* B8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* C0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* C8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* D0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* D8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* E0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* E8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + INST_PREFIX, /* F0 *//* LOCK */ + 0, + INST_PREFIX, /* REPNE */ + INST_PREFIX, /* REPE */ + 0, + 0, + 0, + 0, + 0, /* F8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +void (*insttable_1byte[2][256])(void) = { + /* 16bit */ + { + ADD_EbGb, /* 00 */ + ADD_EwGw, + ADD_GbEb, + ADD_GwEw, + ADD_ALIb, + ADD_AXIw, + PUSH16_ES, + POP16_ES, + OR_EbGb, /* 08 */ + OR_EwGw, + OR_GbEb, + OR_GwEw, + OR_ALIb, + OR_AXIw, + PUSH16_CS, + _2byte_ESC16, + + ADC_EbGb, /* 10 */ + ADC_EwGw, + ADC_GbEb, + ADC_GwEw, + ADC_ALIb, + ADC_AXIw, + PUSH16_SS, + POP16_SS, + SBB_EbGb, /* 18 */ + SBB_EwGw, + SBB_GbEb, + SBB_GwEw, + SBB_ALIb, + SBB_AXIw, + PUSH16_DS, + POP16_DS, + + AND_EbGb, /* 20 */ + AND_EwGw, + AND_GbEb, + AND_GwEw, + AND_ALIb, + AND_AXIw, + Prefix_ES, + DAA, + SUB_EbGb, /* 28 */ + SUB_EwGw, + SUB_GbEb, + SUB_GwEw, + SUB_ALIb, + SUB_AXIw, + Prefix_CS, + DAS, + + XOR_EbGb, /* 30 */ + XOR_EwGw, + XOR_GbEb, + XOR_GwEw, + XOR_ALIb, + XOR_AXIw, + Prefix_SS, + AAA, + CMP_EbGb, /* 38 */ + CMP_EwGw, + CMP_GbEb, + CMP_GwEw, + CMP_ALIb, + CMP_AXIw, + Prefix_DS, + AAS, + + INC_AX, /* 40 */ + INC_CX, + INC_DX, + INC_BX, + INC_SP, + INC_BP, + INC_SI, + INC_DI, + DEC_AX, /* 48 */ + DEC_CX, + DEC_DX, + DEC_BX, + DEC_SP, + DEC_BP, + DEC_SI, + DEC_DI, + + PUSH_AX, /* 50 */ + PUSH_CX, + PUSH_DX, + PUSH_BX, + PUSH_SP, + PUSH_BP, + PUSH_SI, + PUSH_DI, + POP_AX, /* 58 */ + POP_CX, + POP_DX, + POP_BX, + POP_SP, + POP_BP, + POP_SI, + POP_DI, + + PUSHA, /* 60 */ + POPA, + BOUND_GwMa, + ARPL_EwGw, + Prefix_FS, + Prefix_GS, + OpSize, + AddrSize, + PUSH_Iw, /* 68 */ + IMUL_GwEwIw, + PUSH_Ib, + IMUL_GwEwIb, + INSB_YbDX, + INSW_YwDX, + OUTSB_DXXb, + OUTSW_DXXw, + + JO_Jb, /* 70 */ + JNO_Jb, + JC_Jb, + JNC_Jb, + JZ_Jb, + JNZ_Jb, + JNA_Jb, + JA_Jb, + JS_Jb, /* 78 */ + JNS_Jb, + JP_Jb, + JNP_Jb, + JL_Jb, + JNL_Jb, + JLE_Jb, + JNLE_Jb, + + Grp1_EbIb, /* 80 */ + Grp1_EwIw, + Grp1_EbIb, + Grp1_EwIb, + TEST_EbGb, + TEST_EwGw, + XCHG_EbGb, + XCHG_EwGw, + MOV_EbGb, /* 88 */ + MOV_EwGw, + MOV_GbEb, + MOV_GwEw, + MOV_EwSw, + LEA_GwM, + MOV_SwEw, + POP_Ew, + + _NOP, /* 90 */ + XCHG_CXAX, + XCHG_DXAX, + XCHG_BXAX, + XCHG_SPAX, + XCHG_BPAX, + XCHG_SIAX, + XCHG_DIAX, + CBW, /* 98 */ + CWD, + CALL16_Ap, + FWAIT, + PUSHF_Fw, + POPF_Fw, + SAHF, + LAHF, + + MOV_ALOb, /* A0 */ + MOV_AXOw, + MOV_ObAL, + MOV_OwAX, + MOVSB_XbYb, + MOVSW_XwYw, + CMPSB_XbYb, + CMPSW_XwYw, + TEST_ALIb, /* A8 */ + TEST_AXIw, + STOSB_YbAL, + STOSW_YwAX, + LODSB_ALXb, + LODSW_AXXw, + SCASB_ALXb, + SCASW_AXXw, + + MOV_ALIb, /* B0 */ + MOV_CLIb, + MOV_DLIb, + MOV_BLIb, + MOV_AHIb, + MOV_CHIb, + MOV_DHIb, + MOV_BHIb, + MOV_AXIw, /* B8 */ + MOV_CXIw, + MOV_DXIw, + MOV_BXIw, + MOV_SPIw, + MOV_BPIw, + MOV_SIIw, + MOV_DIIw, + + Grp2_EbIb, /* C0 */ + Grp2_EwIb, + RETnear16_Iw, + RETnear16, + LES_GwMp, + LDS_GwMp, + MOV_EbIb, + MOV_EwIw, + ENTER_IwIb, /* C8 */ + LEAVE16, + RETfar16_Iw, + RETfar16, + INT3, + INT_Ib, + INTO, + IRET, + + Grp2_Eb, /* D0 */ + Grp2_Ew, + Grp2_EbCL, + Grp2_EwCL, + AAM, + AAD, + SALC, /* undoc(8086) */ + XLAT, + ESC0, /* D8 */ + ESC1, + ESC2, + ESC3, + ESC4, + ESC5, + ESC6, + ESC7, + + LOOPNE_Jb, /* E0 */ + LOOPE_Jb, + LOOP_Jb, + JeCXZ_Jb, + IN_ALIb, + IN_AXIb, + OUT_IbAL, + OUT_IbAX, + CALL_Aw, /* E8 */ + JMP_Jw, + JMP16_Ap, + JMP_Jb, + IN_ALDX, + IN_AXDX, + OUT_DXAL, + OUT_DXAX, + + _LOCK, /* F0 */ + INT1, + _REPNE, + _REPE, + HLT, + CMC, + Grp3_Eb, + Grp3_Ew, + CLC, /* F8 */ + STC, + CLI, + STI, + CLD, + STD, + Grp4, + Grp5_Ew, + }, + + /* 32bit */ + { + ADD_EbGb, /* 00 */ + ADD_EdGd, + ADD_GbEb, + ADD_GdEd, + ADD_ALIb, + ADD_EAXId, + PUSH32_ES, + POP32_ES, + OR_EbGb, /* 08 */ + OR_EdGd, + OR_GbEb, + OR_GdEd, + OR_ALIb, + OR_EAXId, + PUSH32_CS, + _2byte_ESC32, + + ADC_EbGb, /* 10 */ + ADC_EdGd, + ADC_GbEb, + ADC_GdEd, + ADC_ALIb, + ADC_EAXId, + PUSH32_SS, + POP32_SS, + SBB_EbGb, /* 18 */ + SBB_EdGd, + SBB_GbEb, + SBB_GdEd, + SBB_ALIb, + SBB_EAXId, + PUSH32_DS, + POP32_DS, + + AND_EbGb, /* 20 */ + AND_EdGd, + AND_GbEb, + AND_GdEd, + AND_ALIb, + AND_EAXId, + undef_op, /* Prefix_ES */ + DAA, + SUB_EbGb, /* 28 */ + SUB_EdGd, + SUB_GbEb, + SUB_GdEd, + SUB_ALIb, + SUB_EAXId, + undef_op, /* Prefix_CS */ + DAS, + + XOR_EbGb, /* 30 */ + XOR_EdGd, + XOR_GbEb, + XOR_GdEd, + XOR_ALIb, + XOR_EAXId, + undef_op, /* Prefix_SS */ + AAA, + CMP_EbGb, /* 38 */ + CMP_EdGd, + CMP_GbEb, + CMP_GdEd, + CMP_ALIb, + CMP_EAXId, + undef_op, /* Prefix_DS */ + AAS, + + INC_EAX, /* 40 */ + INC_ECX, + INC_EDX, + INC_EBX, + INC_ESP, + INC_EBP, + INC_ESI, + INC_EDI, + DEC_EAX, /* 48 */ + DEC_ECX, + DEC_EDX, + DEC_EBX, + DEC_ESP, + DEC_EBP, + DEC_ESI, + DEC_EDI, + + PUSH_EAX, /* 50 */ + PUSH_ECX, + PUSH_EDX, + PUSH_EBX, + PUSH_ESP, + PUSH_EBP, + PUSH_ESI, + PUSH_EDI, + POP_EAX, /* 58 */ + POP_ECX, + POP_EDX, + POP_EBX, + POP_ESP, + POP_EBP, + POP_ESI, + POP_EDI, + + PUSHAD, /* 60 */ + POPAD, + BOUND_GdMa, + ARPL_EwGw, + undef_op, /* Prefix_FS */ + undef_op, /* Prefix_GS */ + undef_op, /* OpSize */ + undef_op, /* AddrSize */ + PUSH_Id, /* 68 */ + IMUL_GdEdId, + PUSH_Ib, + IMUL_GdEdIb, + INSB_YbDX, + INSD_YdDX, + OUTSB_DXXb, + OUTSD_DXXd, + + JO_Jb, /* 70 */ + JNO_Jb, + JC_Jb, + JNC_Jb, + JZ_Jb, + JNZ_Jb, + JNA_Jb, + JA_Jb, + JS_Jb, /* 78 */ + JNS_Jb, + JP_Jb, + JNP_Jb, + JL_Jb, + JNL_Jb, + JLE_Jb, + JNLE_Jb, + + Grp1_EbIb, /* 80 */ + Grp1_EdId, + Grp1_EbIb, + Grp1_EdIb, + TEST_EbGb, + TEST_EdGd, + XCHG_EbGb, + XCHG_EdGd, + MOV_EbGb, /* 88 */ + MOV_EdGd, + MOV_GbEb, + MOV_GdEd, + MOV_EwSw, + LEA_GdM, + MOV_SwEw, + POP_Ed, + + _NOP, /* 90 */ + XCHG_ECXEAX, + XCHG_EDXEAX, + XCHG_EBXEAX, + XCHG_ESPEAX, + XCHG_EBPEAX, + XCHG_ESIEAX, + XCHG_EDIEAX, + CWDE, /* 98 */ + CDQ, + CALL32_Ap, + undef_op, /* FWAIT */ + PUSHFD_Fd, + POPFD_Fd, + SAHF, + LAHF, + + MOV_ALOb, /* A0 */ + MOV_EAXOd, + MOV_ObAL, + MOV_OdEAX, + MOVSB_XbYb, + MOVSD_XdYd, + CMPSB_XbYb, + CMPSD_XdYd, + TEST_ALIb, /* A8 */ + TEST_EAXId, + STOSB_YbAL, + STOSD_YdEAX, + LODSB_ALXb, + LODSD_EAXXd, + SCASB_ALXb, + SCASD_EAXXd, + + MOV_ALIb, /* B0 */ + MOV_CLIb, + MOV_DLIb, + MOV_BLIb, + MOV_AHIb, + MOV_CHIb, + MOV_DHIb, + MOV_BHIb, + MOV_EAXId, /* B8 */ + MOV_ECXId, + MOV_EDXId, + MOV_EBXId, + MOV_ESPId, + MOV_EBPId, + MOV_ESIId, + MOV_EDIId, + + Grp2_EbIb, /* C0 */ + Grp2_EdIb, + RETnear32_Iw, + RETnear32, + LES_GdMp, + LDS_GdMp, + MOV_EbIb, + MOV_EdId, + ENTER_IwIb, /* C8 */ + LEAVE32, + RETfar32_Iw, + RETfar32, + INT3, + INT_Ib, + INTO, + IRETD, + + Grp2_Eb, /* D0 */ + Grp2_Ed, + Grp2_EbCL, + Grp2_EdCL, + AAM, + AAD, + SALC, /* undoc(8086) */ + XLAT, + ESC0, /* D8 */ + ESC1, + ESC2, + ESC3, + ESC4, + ESC5, + ESC6, + ESC7, + + LOOPNE_Jb, /* E0 */ + LOOPE_Jb, + LOOP_Jb, + JeCXZ_Jb, + IN_ALIb, + IN_EAXIb, + OUT_IbAL, + OUT_IbEAX, + CALL_Ad, /* E8 */ + JMP_Jd, + JMP32_Ap, + JMP_Jb, + IN_ALDX, + IN_EAXDX, + OUT_DXAL, + OUT_DXEAX, + + _LOCK, /* F0 */ + INT1, + undef_op, /* repne */ + undef_op, /* repe */ + HLT, + CMC, + Grp3_Eb, + Grp3_Ed, + CLC, /* F8 */ + STC, + CLI, + STI, + CLD, + STD, + Grp4, + Grp5_Ed, + }, +}; + +void (*insttable_2byte[2][256])(void) = { + /* 16bit */ + { + Grp6_16, /* 00 */ + Grp7_16, + LAR_GwEw, + LSL_GwEw, + undef_op, + LOADALL286, /* undoc(286) */ + CLTS, + undef_op, + INVD, /* 08 */ + WBINVD, + undef_op, + UD2, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* 10 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 18 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + MOV_RdCd, /* 20 */ + MOV_RdDd, + MOV_CdRd, + MOV_DdRd, + MOV_RdTd, + undef_op, + MOV_TdRd, + undef_op, + undef_op, /* 28 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + WRMSR, /* 30 */ + RDTSC, + RDMSR, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 38 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + CMOVO_GwEw, /* 40 */ + CMOVNO_GwEw, + CMOVC_GwEw, + CMOVNC_GwEw, + CMOVZ_GwEw, + CMOVNZ_GwEw, + CMOVNA_GwEw, + CMOVA_GwEw, + CMOVS_GwEw, /* 48 */ + CMOVNS_GwEw, + CMOVP_GwEw, + CMOVNP_GwEw, + CMOVL_GwEw, + CMOVNL_GwEw, + CMOVLE_GwEw, + CMOVNLE_GwEw, + + undef_op, /* 50 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 58 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* 60 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 68 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* 70 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 78 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + JO_Jw, /* 80 */ + JNO_Jw, + JC_Jw, + JNC_Jw, + JZ_Jw, + JNZ_Jw, + JNA_Jw, + JA_Jw, + JS_Jw, /* 88 */ + JNS_Jw, + JP_Jw, + JNP_Jw, + JL_Jw, + JNL_Jw, + JLE_Jw, + JNLE_Jw, + + SETO_Eb, /* 90 */ + SETNO_Eb, + SETC_Eb, + SETNC_Eb, + SETZ_Eb, + SETNZ_Eb, + SETNA_Eb, + SETA_Eb, + SETS_Eb, /* 98 */ + SETNS_Eb, + SETP_Eb, + SETNP_Eb, + SETL_Eb, + SETNL_Eb, + SETLE_Eb, + SETNLE_Eb, + + PUSH16_FS, /* A0 */ + POP16_FS, + _CPUID, + BT_EwGw, + SHLD_EwGwIb, + SHLD_EwGwCL, + CMPXCHG_EbGb, /* undoc(486) */ + CMPXCHG_EwGw, /* undoc(486) */ + PUSH16_GS, /* A8 */ + POP16_GS, + RSM, + BTS_EwGw, + SHRD_EwGwIb, + SHRD_EwGwCL, + undef_op, + IMUL_GwEw, + + CMPXCHG_EbGb, /* B0 */ + CMPXCHG_EwGw, + LSS_GwMp, + BTR_EwGw, + LFS_GwMp, + LGS_GwMp, + MOVZX_GwEb, + MOVZX_GdEw, + undef_op, /* B8 */ + UD2, + Grp8_EwIb, + BTC_EwGw, + BSF_GwEw, + BSR_GwEw, + MOVSX_GwEb, + MOVSX_GdEw, + + XADD_EbGb, /* C0 */ + XADD_EwGw, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + Grp9, + BSWAP_EAX, /* C8 */ + BSWAP_ECX, + BSWAP_EDX, + BSWAP_EBX, + BSWAP_ESP, + BSWAP_EBP, + BSWAP_ESI, + BSWAP_EDI, + + undef_op, /* D0 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* D8 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* E0 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* E8 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* F0 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* F8 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + }, + + /* 32bit */ + { + Grp6_32, /* 00 */ + Grp7_32, + LAR_GdEw, + LSL_GdEw, + undef_op, + LOADALL, /* undoc(286) */ + CLTS, + undef_op, + INVD, /* 08 */ + WBINVD, + undef_op, + UD2, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* 10 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 18 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + MOV_RdCd, /* 20 */ + MOV_RdDd, + MOV_CdRd, + MOV_DdRd, + MOV_RdTd, + undef_op, + MOV_TdRd, + undef_op, + undef_op, /* 28 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + WRMSR, /* 30 */ + RDTSC, + RDMSR, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 38 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + CMOVO_GdEd, /* 40 */ + CMOVNO_GdEd, + CMOVC_GdEd, + CMOVNC_GdEd, + CMOVZ_GdEd, + CMOVNZ_GdEd, + CMOVNA_GdEd, + CMOVA_GdEd, + CMOVS_GdEd, /* 48 */ + CMOVNS_GdEd, + CMOVP_GdEd, + CMOVNP_GdEd, + CMOVL_GdEd, + CMOVNL_GdEd, + CMOVLE_GdEd, + CMOVNLE_GdEd, + + undef_op, /* 50 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 58 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* 60 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 68 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* 70 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* 78 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + JO_Jd, /* 80 */ + JNO_Jd, + JC_Jd, + JNC_Jd, + JZ_Jd, + JNZ_Jd, + JNA_Jd, + JA_Jd, + JS_Jd, /* 88 */ + JNS_Jd, + JP_Jd, + JNP_Jd, + JL_Jd, + JNL_Jd, + JLE_Jd, + JNLE_Jd, + + SETO_Eb, /* 90 */ + SETNO_Eb, + SETC_Eb, + SETNC_Eb, + SETZ_Eb, + SETNZ_Eb, + SETNA_Eb, + SETA_Eb, + SETS_Eb, /* 98 */ + SETNS_Eb, + SETP_Eb, + SETNP_Eb, + SETL_Eb, + SETNL_Eb, + SETLE_Eb, + SETNLE_Eb, + + PUSH32_FS, /* A0 */ + POP32_FS, + _CPUID, + BT_EdGd, + SHLD_EdGdIb, + SHLD_EdGdCL, + CMPXCHG_EbGb, /* undoc(486) */ + CMPXCHG_EdGd, /* undoc(486) */ + PUSH32_GS, /* A8 */ + POP32_GS, + RSM, + BTS_EdGd, + SHRD_EdGdIb, + SHRD_EdGdCL, + undef_op, + IMUL_GdEd, + + CMPXCHG_EbGb, /* B0 */ + CMPXCHG_EdGd, + LSS_GdMp, + BTR_EdGd, + LFS_GdMp, + LGS_GdMp, + MOVZX_GdEb, + MOVZX_GdEw, + undef_op, /* B8 */ + UD2, + Grp8_EdIb, + BTC_EdGd, + BSF_GdEd, + BSR_GdEd, + MOVSX_GdEb, + MOVSX_GdEw, + + XADD_EbGb, /* C0 */ + XADD_EdGd, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + Grp9, + BSWAP_EAX, /* C8 */ + BSWAP_ECX, + BSWAP_EDX, + BSWAP_EBX, + BSWAP_ESP, + BSWAP_EBP, + BSWAP_ESI, + BSWAP_EDI, + + undef_op, /* D0 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* D8 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* E0 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* E8 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + undef_op, /* F0 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, /* F8 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + }, +}; + + +/* + * for group + */ + +/* group 1 */ +void (*insttable_G1EbIb[])(BYTE *) = { + ADD_EbIb, + OR_EbIb, + ADC_EbIb, + SBB_EbIb, + AND_EbIb, + SUB_EbIb, + XOR_EbIb, + CMP_EbIb, +}; +void (*insttable_G1EbIb_ext[])(DWORD) = { + ADD_EbIb_ext, + OR_EbIb_ext, + ADC_EbIb_ext, + SBB_EbIb_ext, + AND_EbIb_ext, + SUB_EbIb_ext, + XOR_EbIb_ext, + CMP_EbIb_ext, +}; + +void (*insttable_G1EwIx[])(WORD *, DWORD) = { + ADD_EwIx, + OR_EwIx, + ADC_EwIx, + SBB_EwIx, + AND_EwIx, + SUB_EwIx, + XOR_EwIx, + CMP_EwIx, +}; +void (*insttable_G1EwIx_ext[])(DWORD, DWORD) = { + ADD_EwIx_ext, + OR_EwIx_ext, + ADC_EwIx_ext, + SBB_EwIx_ext, + AND_EwIx_ext, + SUB_EwIx_ext, + XOR_EwIx_ext, + CMP_EwIx_ext, +}; + +void (*insttable_G1EdIx[])(DWORD *, DWORD) = { + ADD_EdIx, + OR_EdIx, + ADC_EdIx, + SBB_EdIx, + AND_EdIx, + SUB_EdIx, + XOR_EdIx, + CMP_EdIx, +}; +void (*insttable_G1EdIx_ext[])(DWORD, DWORD) = { + ADD_EdIx_ext, + OR_EdIx_ext, + ADC_EdIx_ext, + SBB_EdIx_ext, + AND_EdIx_ext, + SUB_EdIx_ext, + XOR_EdIx_ext, + CMP_EdIx_ext, +}; + + +/* group 2 */ +void (*insttable_G2Eb[])(BYTE *) = { + ROL_Eb, + ROR_Eb, + RCL_Eb, + RCR_Eb, + SHL_Eb, + SHR_Eb, + SHL_Eb, + SAR_Eb, +}; +void (*insttable_G2Eb_ext[])(DWORD) = { + ROL_Eb_ext, + ROR_Eb_ext, + RCL_Eb_ext, + RCR_Eb_ext, + SHL_Eb_ext, + SHR_Eb_ext, + SHL_Eb_ext, + SAR_Eb_ext, +}; + +void (*insttable_G2Ew[])(WORD *) = { + ROL_Ew, + ROR_Ew, + RCL_Ew, + RCR_Ew, + SHL_Ew, + SHR_Ew, + SHL_Ew, + SAR_Ew, +}; +void (*insttable_G2Ew_ext[])(DWORD) = { + ROL_Ew_ext, + ROR_Ew_ext, + RCL_Ew_ext, + RCR_Ew_ext, + SHL_Ew_ext, + SHR_Ew_ext, + SHL_Ew_ext, + SAR_Ew_ext, +}; + +void (*insttable_G2Ed[])(DWORD *) = { + ROL_Ed, + ROR_Ed, + RCL_Ed, + RCR_Ed, + SHL_Ed, + SHR_Ed, + SHL_Ed, + SAR_Ed, +}; +void (*insttable_G2Ed_ext[])(DWORD) = { + ROL_Ed_ext, + ROR_Ed_ext, + RCL_Ed_ext, + RCR_Ed_ext, + SHL_Ed_ext, + SHR_Ed_ext, + SHL_Ed_ext, + SAR_Ed_ext, +}; + +void (*insttable_G2EbCL[])(BYTE *, BYTE) = { + ROL_EbCL, + ROR_EbCL, + RCL_EbCL, + RCR_EbCL, + SHL_EbCL, + SHR_EbCL, + SHL_EbCL, + SAR_EbCL, +}; +void (*insttable_G2EbCL_ext[])(DWORD, BYTE) = { + ROL_EbCL_ext, + ROR_EbCL_ext, + RCL_EbCL_ext, + RCR_EbCL_ext, + SHL_EbCL_ext, + SHR_EbCL_ext, + SHL_EbCL_ext, + SAR_EbCL_ext, +}; + +void (*insttable_G2EwCL[])(WORD *, BYTE) = { + ROL_EwCL, + ROR_EwCL, + RCL_EwCL, + RCR_EwCL, + SHL_EwCL, + SHR_EwCL, + SHL_EwCL, + SAR_EwCL, +}; +void (*insttable_G2EwCL_ext[])(DWORD, BYTE) = { + ROL_EwCL_ext, + ROR_EwCL_ext, + RCL_EwCL_ext, + RCR_EwCL_ext, + SHL_EwCL_ext, + SHR_EwCL_ext, + SHL_EwCL_ext, + SAR_EwCL_ext, +}; + +void (*insttable_G2EdCL[])(DWORD *, BYTE) = { + ROL_EdCL, + ROR_EdCL, + RCL_EdCL, + RCR_EdCL, + SHL_EdCL, + SHR_EdCL, + SHL_EdCL, + SAR_EdCL, +}; +void (*insttable_G2EdCL_ext[])(DWORD, BYTE) = { + ROL_EdCL_ext, + ROR_EdCL_ext, + RCL_EdCL_ext, + RCR_EdCL_ext, + SHL_EdCL_ext, + SHR_EdCL_ext, + SHL_EdCL_ext, + SAR_EdCL_ext, +}; + +/* group 3 */ +void (*insttable_G3Eb[])(DWORD) = { + TEST_EbIb, + TEST_EbIb, + NOT_Eb, + NEG_Eb, + MUL_ALEb, + IMUL_ALEb, + DIV_ALEb, + IDIV_ALEb, +}; + +void (*insttable_G3Ew[])(DWORD) = { + TEST_EwIw, + TEST_EwIw, + NOT_Ew, + NEG_Ew, + MUL_AXEw, + IMUL_AXEw, + DIV_AXEw, + IDIV_AXEw, +}; + +void (*insttable_G3Ed[])(DWORD) = { + TEST_EdId, + TEST_EdId, + NOT_Ed, + NEG_Ed, + MUL_EAXEd, + IMUL_EAXEd, + DIV_EAXEd, + IDIV_EAXEd, +}; + +/* group 4 */ +void (*insttable_G4[])(DWORD) = { + INC_Eb, + DEC_Eb, + undef_op2, + undef_op2, + undef_op2, + undef_op2, + undef_op2, + undef_op2, +}; + +/* group 5 */ +void (*insttable_G5Ew[])(DWORD) = { + INC_Ew, + DEC_Ew, + CALL_Ew, + CALL16_Ep, + JMP_Ew, + JMP16_Ep, + PUSH_Ew, + undef_op2, /* POP_Ew_G5 */ +}; + +void (*insttable_G5Ed[])(DWORD) = { + INC_Ed, + DEC_Ed, + CALL_Ed, + CALL32_Ep, + JMP_Ed, + JMP32_Ep, + PUSH_Ed, + undef_op2, /* POP_Ed_G5 */ +}; + +/* group 6 */ +void (*insttable_G6_16[])(DWORD) = { + SLDT_Ew, + STR_Ew, + LLDT_Ew, + LTR_Ew, + VERR_Ew, + VERW_Ew, + undef_op2, + undef_op2, +}; + +void (*insttable_G6_32[])(DWORD) = { + SLDT_Ed, + STR_Ed, + LLDT_Ew, + LTR_Ew, + VERR_Ew, + VERW_Ew, + undef_op2, + undef_op2, +}; + +/* group 7 */ +void (*insttable_G7_16[])(DWORD) = { + SGDT16_Ms, + SIDT16_Ms, + LGDT16_Ms, + LIDT16_Ms, + SMSW_Ew, + undef_op2, + LMSW_Ew, + INVLPG, +}; + +void (*insttable_G7_32[])(DWORD) = { + SGDT32_Ms, + SIDT32_Ms, + LGDT32_Ms, + LIDT32_Ms, + SMSW_Ed, + undef_op2, + LMSW_Ew, + INVLPG, +}; + +/* group 8 */ +void (*insttable_G8EwIb[])(DWORD) = { + undef_op2, + undef_op2, + undef_op2, + undef_op2, + BT_EwIb, + BTS_EwIb, + BTR_EwIb, + BTC_EwIb, +}; + +void (*insttable_G8EdIb[])(DWORD) = { + undef_op2, + undef_op2, + undef_op2, + undef_op2, + BT_EdIb, + BTS_EdIb, + BTR_EdIb, + BTC_EdIb, +}; + +/* group 9 */ +void (*insttable_G9[])(DWORD) = { + undef_op2, + CMPXCHG8B, + undef_op2, + undef_op2, + undef_op2, + undef_op2, + undef_op2, + undef_op2, +}; diff --git a/i386c/ia32/inst_table.h b/i386c/ia32/inst_table.h new file mode 100644 index 00000000..0faacfbe --- /dev/null +++ b/i386c/ia32/inst_table.h @@ -0,0 +1,102 @@ +/* $Id: inst_table.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INST_TABLE_H__ +#define IA32_CPU_INST_TABLE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* info of instruction */ +extern BYTE insttable_info[256]; + +/* table of instruction */ +extern void (*insttable_1byte[2][256])(void); +extern void (*insttable_2byte[2][256])(void); + + +/* + * for group + */ + +/* group 1 */ +extern void (*insttable_G1EbIb[])(BYTE *); +extern void (*insttable_G1EwIx[])(WORD *, DWORD); +extern void (*insttable_G1EdIx[])(DWORD *, DWORD); +extern void (*insttable_G1EbIb_ext[])(DWORD); +extern void (*insttable_G1EwIx_ext[])(DWORD, DWORD); +extern void (*insttable_G1EdIx_ext[])(DWORD, DWORD); + +/* group 2 */ +extern void (*insttable_G2Eb[])(BYTE *); +extern void (*insttable_G2Ew[])(WORD *); +extern void (*insttable_G2Ed[])(DWORD *); +extern void (*insttable_G2EbCL[])(BYTE *, BYTE); +extern void (*insttable_G2EwCL[])(WORD *, BYTE); +extern void (*insttable_G2EdCL[])(DWORD *, BYTE); +extern void (*insttable_G2Eb_ext[])(DWORD); +extern void (*insttable_G2Ew_ext[])(DWORD); +extern void (*insttable_G2Ed_ext[])(DWORD); +extern void (*insttable_G2EbCL_ext[])(DWORD, BYTE); +extern void (*insttable_G2EwCL_ext[])(DWORD, BYTE); +extern void (*insttable_G2EdCL_ext[])(DWORD, BYTE); + +/* group 3 */ +extern void (*insttable_G3Eb[])(DWORD); +extern void (*insttable_G3Ew[])(DWORD); +extern void (*insttable_G3Ed[])(DWORD); + +/* group 4 */ +extern void (*insttable_G4[])(DWORD); + +/* group 5 */ +extern void (*insttable_G5Ew[])(DWORD); +extern void (*insttable_G5Ed[])(DWORD); + +/* group 6 */ +extern void (*insttable_G6_16[])(DWORD); +extern void (*insttable_G6_32[])(DWORD); + +/* group 7 */ +extern void (*insttable_G7_16[])(DWORD); +extern void (*insttable_G7_32[])(DWORD); + +/* group 8 */ +extern void (*insttable_G8EwIb[])(DWORD); +extern void (*insttable_G8EdIb[])(DWORD); + +/* group 9 */ +extern void (*insttable_G9[])(DWORD); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INST_TABLE_H__ */ diff --git a/i386c/ia32/instructions/bin_arith.c b/i386c/ia32/instructions/bin_arith.c new file mode 100644 index 00000000..f6d77a9a --- /dev/null +++ b/i386c/ia32/instructions/bin_arith.c @@ -0,0 +1,1642 @@ +/* $Id: bin_arith.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "bin_arith.h" + + +/* + * ADD + */ +void +ADD_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + ADDBYTE(res, dst, src); + *out = (BYTE)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ADDBYTE(res, dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); + } +} + +void +ADD_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + ADDWORD(res, dst, src); + *out = (WORD)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ADDWORD(res, dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); + } +} + +void +ADD_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + ADDDWORD(res, dst, src); + *out = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ADDDWORD(res, dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +void +ADD_GbEb(void) +{ + BYTE *out; + DWORD op, src, dst, res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + ADDBYTE(res, dst, src); + *out = (BYTE)res; +} + +void +ADD_GwEw(void) +{ + WORD *out; + DWORD op, src, dst, res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + ADDWORD(res, dst, src); + *out = (WORD)res; +} + +void +ADD_GdEd(void) +{ + DWORD *out; + DWORD op, src, dst, res; + + PREPART_REG32_EA(op, src, out, 2, 7); + dst = *out; + ADDDWORD(res, dst, src); + *out = (DWORD)res; +} + +void +ADD_ALIb(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCBYTE(src); + dst = CPU_AL; + ADDBYTE(res, dst, src); + CPU_AL = (BYTE)res; +} + +void +ADD_AXIw(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCWORD(src); + dst = CPU_AX; + ADDWORD(res, dst, src); + CPU_AX = (WORD)res; +} + +void +ADD_EAXId(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCDWORD(src); + dst = CPU_EAX; + ADDDWORD(res, dst, src); + CPU_EAX = res; +} + +void +ADD_EbIb(BYTE *regp) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = *regp; + ADDBYTE(res, dst, src); + *regp = (BYTE)res; +} + +void +ADD_EbIb_ext(DWORD madr) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ADDBYTE(res, dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); +} + +void +ADD_EwIx(WORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + ADDWORD(res, dst, src); + *regp = (WORD)res; +} + +void +ADD_EwIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ADDWORD(res, dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); +} + +void +ADD_EdIx(DWORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + ADDDWORD(res, dst, src); + *regp = res; +} + +void +ADD_EdIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ADDDWORD(res, dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); +} + + +/* + * ADC + */ +void +ADC_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + ADCBYTE(res, dst, src); + *out = (BYTE)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ADCBYTE(res, dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); + } +} + +void +ADC_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + ADCWORD(res, dst, src); + *out = (WORD)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ADCWORD(res, dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); + } +} + +void +ADC_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + ADCDWORD(res, dst, src); + *out = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ADCDWORD(res, dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, (WORD)res); + } +} + +void +ADC_GbEb(void) +{ + BYTE *out; + DWORD op, src, dst, res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + ADCBYTE(res, dst, src); + *out = (BYTE)res; +} + +void +ADC_GwEw(void) +{ + WORD *out; + DWORD op, src, dst, res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + ADCWORD(res, dst, src); + *out = (WORD)res; +} + +void +ADC_GdEd(void) +{ + DWORD *out; + DWORD op, src, dst, res; + + PREPART_REG32_EA(op, src, out, 2, 7); + dst = *out; + ADCDWORD(res, dst, src); + *out = res; +} + +void +ADC_ALIb(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCBYTE(src); + dst = CPU_AL; + ADCBYTE(res, dst, src); + CPU_AL = (BYTE)res; +} + +void +ADC_AXIw(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCWORD(src); + dst = CPU_AX; + ADCWORD(res, dst, src); + CPU_AX = (WORD)res; +} + +void +ADC_EAXId(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCDWORD(src); + dst = CPU_EAX; + ADCDWORD(res, dst, src); + CPU_EAX = res; +} + +void +ADC_EbIb(BYTE *regp) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = *regp; + ADCBYTE(res, dst, src); + *regp = (BYTE)res; +} + +void +ADC_EbIb_ext(DWORD madr) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ADCBYTE(res, dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); +} + +void +ADC_EwIx(WORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + ADCWORD(res, dst, src); + *regp = (WORD)res; +} + +void +ADC_EwIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ADCWORD(res, dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); +} + +void +ADC_EdIx(DWORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + ADCDWORD(res, dst, src); + *regp = res; +} + +void +ADC_EdIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ADCDWORD(res, dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); +} + + +/* + * SUB + */ +void +SUB_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + BYTE_SUB(res, dst, src); + *out = (BYTE)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SUB(res, dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); + } +} + +void +SUB_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + WORD_SUB(res, dst, src); + *out = (WORD)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SUB(res, dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); + } +} + +void +SUB_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + DWORD_SUB(res, dst, src); + *out = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SUB(res, dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +void +SUB_GbEb(void) +{ + BYTE *out; + DWORD op, src, dst, res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + BYTE_SUB(res, dst, src); + *out = (BYTE)res; +} + +void +SUB_GwEw(void) +{ + WORD *out; + DWORD op, src, dst, res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + WORD_SUB(res, dst, src); + *out = (WORD)res; +} + +void +SUB_GdEd(void) +{ + DWORD *out; + DWORD op, src, dst, res; + + PREPART_REG32_EA(op, src, out, 2, 7); + dst = *out; + DWORD_SUB(res, dst, src); + *out = res; +} + +void +SUB_ALIb(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCBYTE(src); + dst = CPU_AL; + BYTE_SUB(res, dst, src); + CPU_AL = (BYTE)res; +} + +void +SUB_AXIw(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCWORD(src); + dst = CPU_AX; + WORD_SUB(res, dst, src); + CPU_AX = (WORD)res; +} + +void +SUB_EAXId(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCDWORD(src); + dst = CPU_EAX; + DWORD_SUB(res, dst, src); + CPU_EAX = res; +} + +void +SUB_EbIb(BYTE *regp) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = *regp; + BYTE_SUB(res, dst, src); + *regp = (BYTE)res; +} + +void +SUB_EbIb_ext(DWORD madr) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SUB(res, dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); +} + +void +SUB_EwIx(WORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + WORD_SUB(res, dst, src); + *regp = (WORD)res; +} + +void +SUB_EwIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SUB(res, dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); +} + +void +SUB_EdIx(DWORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + DWORD_SUB(res, dst, src); + *regp = res; +} + +void +SUB_EdIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SUB(res, dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); +} + + +/* + * SBB + */ +void +SBB_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + BYTE_SBB(res, dst, src); + *out = (BYTE)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SBB(res, dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); + } +} + +void +SBB_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + WORD_SBB(res, dst, src); + *out = (WORD)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SBB(res, dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); + } +} + +void +SBB_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + DWORD_SBB(res, dst, src); + *out = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SBB(res, dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +void +SBB_GbEb(void) +{ + BYTE *out; + DWORD op, src, dst, res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + BYTE_SBB(res, dst, src); + *out = (BYTE)res; +} + +void +SBB_GwEw(void) +{ + WORD *out; + DWORD op, src, dst, res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + WORD_SBB(res, dst, src); + *out = (WORD)res; +} + +void +SBB_GdEd(void) +{ + DWORD *out; + DWORD op, src, dst, res; + + PREPART_REG32_EA(op, src, out, 2, 7); + dst = *out; + DWORD_SBB(res, dst, src); + *out = res; +} + +void +SBB_ALIb(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCBYTE(src); + dst = CPU_AL; + BYTE_SBB(res, dst, src); + CPU_AL = (BYTE)res; +} + +void +SBB_AXIw(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCWORD(src); + dst = CPU_AX; + WORD_SBB(res, dst, src); + CPU_AX = (WORD)res; +} + +void +SBB_EAXId(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(3); + GET_PCDWORD(src); + dst = CPU_EAX; + DWORD_SBB(res, dst, src); + CPU_EAX = res; +} + +void +SBB_EbIb(BYTE *regp) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = *regp; + BYTE_SBB(res, dst, src); + *regp = (BYTE)res; +} + +void +SBB_EbIb_ext(DWORD madr) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SBB(res, dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); +} + +void +SBB_EwIx(WORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + WORD_SBB(res, dst, src); + *regp = (WORD)res; +} + +void +SBB_EwIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SBB(res, dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); +} + +void +SBB_EdIx(DWORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + DWORD_SBB(res, dst, src); + *regp = res; +} + +void +SBB_EdIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SBB(res, dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); +} + + +/* + * IMUL + */ +void +IMUL_ALEb(DWORD op) +{ + DWORD madr; + SDWORD res; + SBYTE src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(13); + src = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(16); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_AL; + BYTE_IMUL(res, dst, src); + CPU_AX = (WORD)res; +} + +void +IMUL_AXEw(DWORD op) +{ + DWORD madr; + SDWORD res; + SWORD src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(21); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(24); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_AX; + WORD_IMUL(res, dst, src); + CPU_AX = (WORD)(res & 0xffff); + CPU_DX = (WORD)(res >> 16); +} + +void +IMUL_EAXEd(DWORD op) +{ + DWORD madr; + SQWORD res; + SDWORD src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(21); + src = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(24); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_EAX; + DWORD_IMUL(res, dst, src); + CPU_EAX = (DWORD)res; + CPU_EDX = (DWORD)(res >> 32); +} + +void +IMUL_GwEw(void) +{ + WORD *out; + DWORD op; + SDWORD res; + SWORD src, dst; + + PREPART_REG16_EA(op, src, out, 21, 27); + dst = *out; + WORD_IMUL(res, dst, src); + *out = (WORD)res; +} + +void +IMUL_GdEd(void) +{ + DWORD *out; + DWORD op; + SQWORD res; + SDWORD src, dst; + + PREPART_REG32_EA(op, src, out, 21, 27); + dst = *out; + DWORD_IMUL(res, dst, src); + *out = (DWORD)res; +} + +void +IMUL_GwEwIb(void) +{ + WORD *out; + DWORD op; + SDWORD res; + SWORD src, dst; + + PREPART_REG16_EA(op, src, out, 21, 24); + GET_PCBYTES(dst); + WORD_IMUL(res, dst, src); + *out = (WORD)res; +} + +void +IMUL_GdEdIb(void) +{ + DWORD *out; + DWORD op; + SQWORD res; + SDWORD src, dst; + + PREPART_REG32_EA(op, src, out, 21, 24); + GET_PCBYTESD(dst); + DWORD_IMUL(res, dst, src); + *out = (DWORD)res; +} + +void +IMUL_GwEwIw(void) +{ + WORD *out; + DWORD op; + SDWORD res; + SWORD src, dst; + + PREPART_REG16_EA(op, src, out, 21, 24); + GET_PCWORD(dst); + WORD_IMUL(res, dst, src); + *out = (WORD)res; +} + +void +IMUL_GdEdId(void) +{ + DWORD *out; + DWORD op; + SQWORD res; + SDWORD src, dst; + + PREPART_REG32_EA(op, src, out, 21, 24); + GET_PCDWORD(dst); + DWORD_IMUL(res, dst, src); + *out = res; +} + + +/* + * MUL + */ +void +MUL_ALEb(DWORD op) +{ + DWORD res, madr; + BYTE src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(13); + src = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(16); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_AL; + BYTE_MUL(res, dst, src); + CPU_AX = (WORD)res; +} + +void +MUL_AXEw(DWORD op) +{ + DWORD res, madr; + WORD src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(21); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(24); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_AX; + WORD_MUL(res, dst, src); + CPU_AX = (WORD)res; + CPU_DX = (WORD)(res >> 16); +} + +void +MUL_EAXEd(DWORD op) +{ + DWORD res, madr; + DWORD src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(21); + src = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(24); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_EAX; + DWORD_MUL(res, dst, src); + CPU_EAX = res; + CPU_EDX = CPU_OV; +} + + +/* + * IDIV + */ +void +IDIV_ALEb(DWORD op) +{ + DWORD madr; + SWORD tmp, r; + SBYTE src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + tmp = (SWORD)CPU_AX; + if (src != 0) { + r = tmp / src; + if (((r + 0x80) & 0xff00) == 0) { + CPU_AL = (SBYTE)r; + CPU_AH = tmp % src; + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void +IDIV_AXEw(DWORD op) +{ + SDWORD tmp, r; + DWORD madr; + SWORD src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + tmp = (SDWORD)(((DWORD)CPU_DX << 16) + CPU_AX); + if (src != 0) { + r = tmp / src; + if (((r + 0x8000) & 0xffff0000) == 0) { + CPU_AX = (SWORD)r; + CPU_DX = tmp % src; + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void +IDIV_EAXEd(DWORD op) +{ + SQWORD tmp, r; + SDWORD src; + DWORD madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + tmp = (SQWORD)(((QWORD)CPU_EDX << 32) + CPU_EAX); + if (src != 0) { + r = tmp / src; + if (((r + 0x80000000) & 0xffffffff00000000ULL) == 0) { + CPU_EAX = (SDWORD)r; + CPU_EDX = tmp % src; + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + + +/* + * DIV + */ +void +DIV_ALEb(DWORD op) +{ + DWORD madr; + WORD tmp; + BYTE src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + tmp = CPU_AX; + if (src != 0) { + if (tmp < ((WORD)src << 8)) { + CPU_AL = tmp / src; + CPU_AH = tmp % src; + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void +DIV_AXEw(DWORD op) +{ + DWORD madr; + DWORD tmp; + WORD src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + tmp = ((DWORD)CPU_DX << 16) + CPU_AX; + if (src != 0) { + if (tmp < ((DWORD)src << 16)) { + CPU_AX = (WORD)(tmp / src); + CPU_DX = (WORD)(tmp % src); + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void +DIV_EAXEd(DWORD op) +{ + DWORD madr; + QWORD tmp; + DWORD src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + tmp = ((QWORD)CPU_EDX << 32) + CPU_EAX; + if (src != 0) { + if (tmp < ((QWORD)src << 32)) { + CPU_EAX = (DWORD)(tmp / src); + CPU_EDX = (DWORD)(tmp % src); + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + + +/* + * INC + */ +void +INC_Eb(DWORD op) +{ + BYTE *out; + DWORD madr; + BYTE value; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + BYTE_INC(*out); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + value = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_INC(value); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, value); + } +} + +void +INC_Ew(DWORD op) +{ + WORD *out; + DWORD madr; + WORD value; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + WORD_INC(*out); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + value = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_INC(value); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, value); + } +} + +void +INC_Ed(DWORD op) +{ + DWORD *out; + DWORD madr; + DWORD value; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + DWORD_INC(*out); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + value = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_INC(value); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, value); + } +} + +void INC_AX(void) { WORD_INC(CPU_AX); CPU_WORKCLOCK(2); } +void INC_CX(void) { WORD_INC(CPU_CX); CPU_WORKCLOCK(2); } +void INC_DX(void) { WORD_INC(CPU_DX); CPU_WORKCLOCK(2); } +void INC_BX(void) { WORD_INC(CPU_BX); CPU_WORKCLOCK(2); } +void INC_SP(void) { WORD_INC(CPU_SP); CPU_WORKCLOCK(2); } +void INC_BP(void) { WORD_INC(CPU_BP); CPU_WORKCLOCK(2); } +void INC_SI(void) { WORD_INC(CPU_SI); CPU_WORKCLOCK(2); } +void INC_DI(void) { WORD_INC(CPU_DI); CPU_WORKCLOCK(2); } + +void INC_EAX(void) { DWORD_INC(CPU_EAX); CPU_WORKCLOCK(2); } +void INC_ECX(void) { DWORD_INC(CPU_ECX); CPU_WORKCLOCK(2); } +void INC_EDX(void) { DWORD_INC(CPU_EDX); CPU_WORKCLOCK(2); } +void INC_EBX(void) { DWORD_INC(CPU_EBX); CPU_WORKCLOCK(2); } +void INC_ESP(void) { DWORD_INC(CPU_ESP); CPU_WORKCLOCK(2); } +void INC_EBP(void) { DWORD_INC(CPU_EBP); CPU_WORKCLOCK(2); } +void INC_ESI(void) { DWORD_INC(CPU_ESI); CPU_WORKCLOCK(2); } +void INC_EDI(void) { DWORD_INC(CPU_EDI); CPU_WORKCLOCK(2); } + + + +/* + * DEC + */ +void +DEC_Eb(DWORD op) +{ + BYTE *out; + DWORD madr; + BYTE value; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + BYTE_DEC(*out); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + value = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_DEC(value); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, value); + } +} + +void +DEC_Ew(DWORD op) +{ + WORD *out; + DWORD madr; + WORD value; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + WORD_DEC(*out); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + value = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_DEC(value); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, value); + } +} + +void +DEC_Ed(DWORD op) +{ + DWORD *out; + DWORD madr; + DWORD value; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + DWORD_DEC(*out); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + value = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_DEC(value); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, value); + } +} + +void DEC_AX(void) { WORD_DEC(CPU_AX); CPU_WORKCLOCK(2); } +void DEC_CX(void) { WORD_DEC(CPU_CX); CPU_WORKCLOCK(2); } +void DEC_DX(void) { WORD_DEC(CPU_DX); CPU_WORKCLOCK(2); } +void DEC_BX(void) { WORD_DEC(CPU_BX); CPU_WORKCLOCK(2); } +void DEC_SP(void) { WORD_DEC(CPU_SP); CPU_WORKCLOCK(2); } +void DEC_BP(void) { WORD_DEC(CPU_BP); CPU_WORKCLOCK(2); } +void DEC_SI(void) { WORD_DEC(CPU_SI); CPU_WORKCLOCK(2); } +void DEC_DI(void) { WORD_DEC(CPU_DI); CPU_WORKCLOCK(2); } + +void DEC_EAX(void) { DWORD_DEC(CPU_EAX); CPU_WORKCLOCK(2); } +void DEC_ECX(void) { DWORD_DEC(CPU_ECX); CPU_WORKCLOCK(2); } +void DEC_EDX(void) { DWORD_DEC(CPU_EDX); CPU_WORKCLOCK(2); } +void DEC_EBX(void) { DWORD_DEC(CPU_EBX); CPU_WORKCLOCK(2); } +void DEC_ESP(void) { DWORD_DEC(CPU_ESP); CPU_WORKCLOCK(2); } +void DEC_EBP(void) { DWORD_DEC(CPU_EBP); CPU_WORKCLOCK(2); } +void DEC_ESI(void) { DWORD_DEC(CPU_ESI); CPU_WORKCLOCK(2); } +void DEC_EDI(void) { DWORD_DEC(CPU_EDI); CPU_WORKCLOCK(2); } + + +/* + * NEG + */ +void +NEG_Eb(DWORD op) +{ + BYTE *out; + DWORD src, dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + src = *out; + BYTE_NEG(dst, src); + *out = (BYTE)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_NEG(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); + } +} + +void +NEG_Ew(DWORD op) +{ + WORD *out; + DWORD src, dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + src = *out; + WORD_NEG(dst, src); + *out = (WORD)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_NEG(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); + } +} + +void +NEG_Ed(DWORD op) +{ + DWORD *out; + DWORD src, dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + src = *out; + DWORD_NEG(dst, src); + *out = dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_NEG(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + + +/* + * CMP + */ +void +CMP_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + BYTE_SUB(res, dst, src); +} + +void +CMP_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + WORD_SUB(res, dst, src); +} + +void +CMP_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, res, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + DWORD_SUB(res, dst, src); +} + +void +CMP_GbEb(void) +{ + BYTE *out; + DWORD op, src, dst, res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + BYTE_SUB(res, dst, src); +} + +void +CMP_GwEw(void) +{ + WORD *out; + DWORD op, src, dst, res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + WORD_SUB(res, dst, src); +} + +void +CMP_GdEd(void) +{ + DWORD *out; + DWORD op, src, dst, res; + + PREPART_REG32_EA(op, src, out, 2, 7); + dst = *out; + DWORD_SUB(res, dst, src); +} + +void +CMP_ALIb(void) +{ + DWORD src, res; + + CPU_WORKCLOCK(3); + GET_PCBYTE(src); + BYTE_SUB(res, CPU_AL, src); +} + +void +CMP_AXIw(void) +{ + DWORD src, res; + + CPU_WORKCLOCK(3); + GET_PCWORD(src); + WORD_SUB(res, CPU_AX, src); +} + +void +CMP_EAXId(void) +{ + DWORD src, res; + + CPU_WORKCLOCK(3); + GET_PCDWORD(src); + DWORD_SUB(res, CPU_EAX, src); +} + +void +CMP_EbIb(BYTE *regp) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = *regp; + BYTE_SUB(res, dst, src); +} + +void +CMP_EbIb_ext(DWORD madr) +{ + DWORD src, dst, res; + + GET_PCBYTE(src); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SUB(res, dst, src); +} + +void +CMP_EwIx(WORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + WORD_SUB(res, dst, src); +} + +void +CMP_EwIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SUB(res, dst, src); +} + +void +CMP_EdIx(DWORD *regp, DWORD src) +{ + DWORD dst, res; + + dst = *regp; + DWORD_SUB(res, dst, src); +} + +void +CMP_EdIx_ext(DWORD madr, DWORD src) +{ + DWORD dst, res; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SUB(res, dst, src); +} diff --git a/i386c/ia32/instructions/bin_arith.h b/i386c/ia32/instructions/bin_arith.h new file mode 100644 index 00000000..d31a35b1 --- /dev/null +++ b/i386c/ia32/instructions/bin_arith.h @@ -0,0 +1,199 @@ +/* $Id: bin_arith.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_BIN_ARITH_H__ +#define IA32_CPU_INSTRUCTION_BIN_ARITH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ADD */ +void ADD_EbGb(void); +void ADD_EwGw(void); +void ADD_EdGd(void); +void ADD_GbEb(void); +void ADD_GwEw(void); +void ADD_GdEd(void); +void ADD_ALIb(void); +void ADD_AXIw(void); +void ADD_EAXId(void); +void ADD_EbIb(BYTE *); +void ADD_EwIx(WORD *, DWORD); +void ADD_EdIx(DWORD *, DWORD); +void ADD_EbIb_ext(DWORD); +void ADD_EwIx_ext(DWORD, DWORD); +void ADD_EdIx_ext(DWORD, DWORD); + +/* ADC */ +void ADC_EbGb(void); +void ADC_EwGw(void); +void ADC_EdGd(void); +void ADC_GbEb(void); +void ADC_GwEw(void); +void ADC_GdEd(void); +void ADC_ALIb(void); +void ADC_AXIw(void); +void ADC_EAXId(void); +void ADC_EbIb(BYTE *); +void ADC_EwIx(WORD *, DWORD); +void ADC_EdIx(DWORD *, DWORD); +void ADC_EbIb_ext(DWORD); +void ADC_EwIx_ext(DWORD, DWORD); +void ADC_EdIx_ext(DWORD, DWORD); + +/* SUB */ +void SUB_EbGb(void); +void SUB_EwGw(void); +void SUB_EdGd(void); +void SUB_GbEb(void); +void SUB_GwEw(void); +void SUB_GdEd(void); +void SUB_ALIb(void); +void SUB_AXIw(void); +void SUB_EAXId(void); +void SUB_EbIb(BYTE *); +void SUB_EwIx(WORD *, DWORD); +void SUB_EdIx(DWORD *, DWORD); +void SUB_EbIb_ext(DWORD); +void SUB_EwIx_ext(DWORD, DWORD); +void SUB_EdIx_ext(DWORD, DWORD); + +/* SBB */ +void SBB_EbGb(void); +void SBB_EwGw(void); +void SBB_EdGd(void); +void SBB_GbEb(void); +void SBB_GwEw(void); +void SBB_GdEd(void); +void SBB_ALIb(void); +void SBB_AXIw(void); +void SBB_EAXId(void); +void SBB_EbIb(BYTE *); +void SBB_EwIx(WORD *, DWORD); +void SBB_EdIx(DWORD *, DWORD); +void SBB_EbIb_ext(DWORD); +void SBB_EwIx_ext(DWORD, DWORD); +void SBB_EdIx_ext(DWORD, DWORD); + +/* IMUL */ +void IMUL_ALEb(DWORD op); +void IMUL_AXEw(DWORD op); +void IMUL_EAXEd(DWORD op); +void IMUL_GwEw(void); +void IMUL_GdEd(void); +void IMUL_GwEwIb(void); +void IMUL_GdEdIb(void); +void IMUL_GwEwIw(void); +void IMUL_GdEdId(void); + +/* MUL */ +void MUL_ALEb(DWORD op); +void MUL_AXEw(DWORD op); +void MUL_EAXEd(DWORD op); + +/* IDIV */ +void IDIV_ALEb(DWORD op); +void IDIV_AXEw(DWORD op); +void IDIV_EAXEd(DWORD op); + +/* DIV */ +void DIV_ALEb(DWORD op); +void DIV_AXEw(DWORD op); +void DIV_EAXEd(DWORD op); + +/* INC */ +void INC_Eb(DWORD op); +void INC_Ew(DWORD op); +void INC_Ed(DWORD op); +void INC_AX(void); +void INC_CX(void); +void INC_DX(void); +void INC_BX(void); +void INC_SP(void); +void INC_BP(void); +void INC_SI(void); +void INC_DI(void); +void INC_EAX(void); +void INC_ECX(void); +void INC_EDX(void); +void INC_EBX(void); +void INC_ESP(void); +void INC_EBP(void); +void INC_ESI(void); +void INC_EDI(void); + +/* DEC */ +void DEC_Eb(DWORD op); +void DEC_Ew(DWORD op); +void DEC_Ed(DWORD op); +void DEC_AX(void); +void DEC_CX(void); +void DEC_DX(void); +void DEC_BX(void); +void DEC_SP(void); +void DEC_BP(void); +void DEC_SI(void); +void DEC_DI(void); +void DEC_EAX(void); +void DEC_ECX(void); +void DEC_EDX(void); +void DEC_EBX(void); +void DEC_ESP(void); +void DEC_EBP(void); +void DEC_ESI(void); +void DEC_EDI(void); + +/* NEG */ +void NEG_Eb(DWORD op); +void NEG_Ew(DWORD op); +void NEG_Ed(DWORD op); + +/* CMP */ +void CMP_EbGb(void); +void CMP_EwGw(void); +void CMP_EdGd(void); +void CMP_GbEb(void); +void CMP_GwEw(void); +void CMP_GdEd(void); +void CMP_ALIb(void); +void CMP_AXIw(void); +void CMP_EAXId(void); +void CMP_EbIb(BYTE *); +void CMP_EwIx(WORD *, DWORD); +void CMP_EdIx(DWORD *, DWORD); +void CMP_EbIb_ext(DWORD); +void CMP_EwIx_ext(DWORD, DWORD); +void CMP_EdIx_ext(DWORD, DWORD); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_BIN_ARITH_H__ */ diff --git a/i386c/ia32/instructions/bit_byte.c b/i386c/ia32/instructions/bit_byte.c new file mode 100644 index 00000000..557a3175 --- /dev/null +++ b/i386c/ia32/instructions/bit_byte.c @@ -0,0 +1,1040 @@ +/* $Id: bit_byte.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "bit_byte.h" + + +/* + * BT + */ +void +BT_EwGw(void) +{ + DWORD op, src, dst, madr, ad; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ad += 2 * (src >> 4); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + } + if (dst & (1 << (src & 0x0f))) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } +} + +void +BT_EdGd(void) +{ + DWORD op, src, dst, madr, ad; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ad += 4 * (src >> 5); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + } + if (dst & (1 << (src & 0x1f))) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } +} + +void +BT_EwIb(DWORD op) +{ + DWORD src, dst, madr, ad; + + GET_PCBYTE(src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ad += 2 * (src >> 4); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + } + if (dst & (1 << (src & 0x0f))) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } +} + +void +BT_EdIb(DWORD op) +{ + DWORD src, dst, madr, ad; + + GET_PCBYTE(src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ad += 4 * (src >> 5); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + } + if (dst & (1 << (src & 0x1f))) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } +} + +/* + * BTS + */ +void +BTS_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, madr, ad; + WORD bit; + + PREPART_EA_REG16(op, src); + bit = 1 << (src & 0x0f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + if (*out & bit) { + CPU_FLAGL |= C_FLAG; + } else { + *out |= bit; + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ad += 2 * (src >> 4); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + dst |= bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, ad, dst); + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTS_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, madr, ad; + DWORD bit; + + PREPART_EA_REG32(op, src); + bit = 1 << (src & 0x1f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + if (*out & bit) { + CPU_FLAGL |= C_FLAG; + } else { + *out |= bit; + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ad += 4 * (src >> 5); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + dst |= bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, ad, dst); + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTS_EwIb(DWORD op) +{ + WORD *out; + DWORD src, dst, madr, ad; + WORD bit; + + GET_PCBYTE(src); + bit = 1 << (src & 0x0f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + if (*out & bit) { + CPU_FLAGL |= C_FLAG; + } else { + *out |= bit; + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ad += 2 * (src >> 4); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + dst |= bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, ad, dst); + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTS_EdIb(DWORD op) +{ + DWORD *out; + DWORD src, dst, madr, ad; + DWORD bit; + + GET_PCBYTE(src); + bit = 1 << (src & 0x1f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + if (*out & bit) { + CPU_FLAGL |= C_FLAG; + } else { + *out |= bit; + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ad += 4 * (src >> 5); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + dst |= bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, ad, dst); + CPU_FLAGL &= ~C_FLAG; + } + } +} + +/* + * BTR + */ +void +BTR_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, madr, ad; + WORD bit; + + PREPART_EA_REG16(op, src); + bit = 1 << (src & 0x0f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + if (*out & bit) { + *out &= ~bit; + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ad += 2 * (src >> 4); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + if (dst & bit) { + dst &= ~bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, ad, dst); + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTR_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, madr, ad; + DWORD bit; + + PREPART_EA_REG32(op, src); + bit = 1 << (src & 0x1f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + if (*out & bit) { + *out &= ~bit; + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ad += 4 * (src >> 5); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + if (dst & bit) { + dst &= ~bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, ad, dst); + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTR_EwIb(DWORD op) +{ + WORD *out; + DWORD src, dst, madr, ad; + WORD bit; + + GET_PCBYTE(src); + bit = 1 << (src & 0x0f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + if (*out & bit) { + *out &= ~bit; + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ad += 2 * (src >> 4); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + if (dst & bit) { + dst &= ~bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, ad, dst); + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTR_EdIb(DWORD op) +{ + DWORD *out; + DWORD src, dst, madr, ad; + DWORD bit; + + GET_PCBYTE(src); + bit = 1 << (src & 0x1f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + if (*out & bit) { + *out &= ~bit; + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ad += 4 * (src >> 5); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + if (dst & bit) { + dst &= ~bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, ad, dst); + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } +} + + +/* + * BTC + */ +void +BTC_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, madr, ad; + WORD bit; + + PREPART_EA_REG16(op, src); + bit = 1 << (src & 0x0f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + if (*out & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + *out ^= bit; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ad += 2 * (src >> 4); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, ad, dst ^ bit); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTC_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, madr, ad; + DWORD bit; + + PREPART_EA_REG32(op, src); + bit = 1 << (src & 0x1f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + if (*out & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + *out ^= bit; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ad += 4 * (src >> 5); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, ad, dst ^ bit); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTC_EwIb(DWORD op) +{ + WORD *out; + DWORD src, dst, madr, ad; + WORD bit; + + GET_PCBYTE(src); + bit = 1 << (src & 0x0f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + if (*out & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + *out ^= bit; + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ad += 2 * (src >> 4); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, ad, dst ^ bit); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } +} + +void +BTC_EdIb(DWORD op) +{ + DWORD *out; + DWORD src, dst, madr, ad; + DWORD bit; + + GET_PCBYTE(src); + bit = 1 << (src & 0x1f); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + if (*out & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + *out ^= bit; + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + ad = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ad += 4 * (src >> 5); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, ad, dst ^ bit); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } +} + +/* + * BSF + */ +void +BSF_GwEw(void) +{ + WORD *out; + DWORD op, src; + int bit; + + PREPART_REG16_EA(op, src, out, 2, 7); + if (src == 0) { + CPU_FLAGL |= Z_FLAG; + /* dest reg is undefined */ + } else { + for (bit = 0; (bit < 16) && !(src & (1 << bit)); bit++) + continue; + *out = (WORD)bit; + CPU_FLAGL &= ~Z_FLAG; + } +} + +void +BSF_GdEd(void) +{ + DWORD *out; + DWORD op, src; + int bit; + + PREPART_REG32_EA(op, src, out, 2, 7); + if (src == 0) { + CPU_FLAGL |= Z_FLAG; + /* dest reg is undefined */ + } else { + for (bit = 0; (bit < 32) && !(src & (1 << bit)); bit++) + continue; + *out = (DWORD)bit; + CPU_FLAGL &= ~Z_FLAG; + } +} + +/* + * BSR + */ +void +BSR_GwEw(void) +{ + WORD *out; + DWORD op, src; + int bit; + + PREPART_REG16_EA(op, src, out, 2, 7); + if (src == 0) { + CPU_FLAGL |= Z_FLAG; + /* dest reg is undefined */ + } else { + for (bit = 15; (bit >= 0) && !(src & (1 << bit)); bit--) + continue; + *out = (WORD)bit; + CPU_FLAGL &= ~Z_FLAG; + } +} + +void +BSR_GdEd(void) +{ + DWORD *out; + DWORD op, src; + int bit; + + PREPART_REG32_EA(op, src, out, 2, 7); + if (src == 0) { + CPU_FLAGL |= Z_FLAG; + /* dest reg is undefined */ + } else { + for (bit = 31; (bit >= 0) && !(src & (1 << bit)); bit--) + continue; + *out = (DWORD)bit; + CPU_FLAGL &= ~Z_FLAG; + } +} + +/* + * SETcc + */ +void +SETO_Eb(void) +{ + DWORD op, src, madr; + BYTE v = CPU_OV ? 1 : 0; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNO_Eb(void) +{ + DWORD op, src, madr; + BYTE v = CPU_OV ? 0 : 1; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETC_Eb(void) +{ + DWORD op, src, madr; + BYTE v = CPU_FLAGL & C_FLAG; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNC_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & C_FLAG) ? 0 : 1; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETZ_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & Z_FLAG) ? 1 : 0; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNZ_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & Z_FLAG) ? 0 : 1; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETA_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & (Z_FLAG|C_FLAG)) ? 0 : 1; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNA_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & (Z_FLAG|C_FLAG)) ? 1 : 0; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETS_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & S_FLAG) ? 1 : 0; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNS_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & S_FLAG) ? 0 : 1; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETP_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & P_FLAG) ? 1 : 0; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNP_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (CPU_FLAGL & P_FLAG) ? 0 : 1; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETL_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (!CPU_OV == !(CPU_FLAGL & S_FLAG)) ? 1 : 0; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNL_Eb(void) +{ + DWORD op, src, madr; + BYTE v = (!CPU_OV == !(CPU_FLAGL & S_FLAG)) ? 0 : 1; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETLE_Eb(void) +{ + DWORD op, src, madr; + BYTE v = ((CPU_FLAGL & Z_FLAG) || (!CPU_OV == !(CPU_FLAGL & S_FLAG))) ? 1 : 0; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNLE_Eb(void) +{ + DWORD op, src, madr; + BYTE v = ((CPU_FLAGL & Z_FLAG) || (!CPU_OV == !(CPU_FLAGL & S_FLAG))) ? 0 : 1; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +/* + * TEST + */ +void +TEST_EbGb(void) +{ + DWORD op, src, tmp, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + ANDBYTE(tmp, src); +} + +void +TEST_EwGw(void) +{ + DWORD op, src, tmp, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + ANDWORD(tmp, src); +} + +void +TEST_EdGd(void) +{ + DWORD op, src, tmp, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + ANDDWORD(tmp, src); +} + +void +TEST_ALIb(void) +{ + DWORD src, tmp; + + CPU_WORKCLOCK(3); + tmp = CPU_AL; + GET_PCBYTE(src); + ANDBYTE(tmp, src); +} + +void +TEST_AXIw(void) +{ + DWORD src, tmp; + + CPU_WORKCLOCK(3); + tmp = CPU_AX; + GET_PCWORD(src); + ANDWORD(tmp, src); +} + +void +TEST_EAXId(void) +{ + DWORD src, tmp; + + CPU_WORKCLOCK(3); + tmp = CPU_EAX; + GET_PCDWORD(src); + ANDDWORD(tmp, src); +} + +void +TEST_EbIb(DWORD op) +{ + DWORD src, tmp, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + GET_PCBYTE(src); + ANDBYTE(tmp, src); +} + +void +TEST_EwIw(DWORD op) +{ + DWORD src, tmp, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + GET_PCWORD(src); + ANDWORD(tmp, src); +} + +void +TEST_EdId(DWORD op) +{ + DWORD src, tmp, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + GET_PCDWORD(src); + ANDDWORD(tmp, src); +} diff --git a/i386c/ia32/instructions/bit_byte.h b/i386c/ia32/instructions/bit_byte.h new file mode 100644 index 00000000..f81481db --- /dev/null +++ b/i386c/ia32/instructions/bit_byte.h @@ -0,0 +1,103 @@ +/* $Id: bit_byte.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_BIT_BYTE_H__ +#define IA32_CPU_INSTRUCTION_BIT_BYTE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * BTx + */ +void BT_EwGw(void); +void BT_EdGd(void); +void BT_EwIb(DWORD op); +void BT_EdIb(DWORD op); +void BTS_EwGw(void); +void BTS_EdGd(void); +void BTS_EwIb(DWORD op); +void BTS_EdIb(DWORD op); +void BTR_EwGw(void); +void BTR_EdGd(void); +void BTR_EwIb(DWORD op); +void BTR_EdIb(DWORD op); +void BTC_EwGw(void); +void BTC_EdGd(void); +void BTC_EwIb(DWORD op); +void BTC_EdIb(DWORD op); + +/* + * BSx + */ +void BSF_GwEw(void); +void BSF_GdEd(void); +void BSR_GwEw(void); +void BSR_GdEd(void); + +/* + * SETcc + */ +void SETO_Eb(void); +void SETNO_Eb(void); +void SETC_Eb(void); +void SETNC_Eb(void); +void SETZ_Eb(void); +void SETNZ_Eb(void); +void SETA_Eb(void); +void SETNA_Eb(void); +void SETS_Eb(void); +void SETNS_Eb(void); +void SETP_Eb(void); +void SETNP_Eb(void); +void SETL_Eb(void); +void SETNL_Eb(void); +void SETLE_Eb(void); +void SETNLE_Eb(void); + +/* + * TEST + */ +void TEST_EbGb(void); +void TEST_EwGw(void); +void TEST_EdGd(void); +void TEST_ALIb(void); +void TEST_AXIw(void); +void TEST_EAXId(void); + +void TEST_EbIb(DWORD); +void TEST_EwIw(DWORD); +void TEST_EdId(DWORD); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_BIT_BYTE_H__ */ diff --git a/i386c/ia32/instructions/ctrl_trans.c b/i386c/ia32/instructions/ctrl_trans.c new file mode 100644 index 00000000..1fd44480 --- /dev/null +++ b/i386c/ia32/instructions/ctrl_trans.c @@ -0,0 +1,1449 @@ +/* $Id: ctrl_trans.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" +#include "ctrlxfer.h" + +#include "ctrl_trans.h" + + +/* + * JMP + */ +void +JMP_Jb(void) +{ + DWORD ip; + + CPU_WORKCLOCK(7); + GET_PCBYTESD(ip); + ADD_EIP(ip); +} + +void +JMP_Jw(void) +{ + WORD ip; + + CPU_WORKCLOCK(7); + GET_PCWORD(ip); + ADD_EIP(ip); +} + +void +JMP_Jd(void) +{ + DWORD ip; + + CPU_WORKCLOCK(7); + GET_PCDWORD(ip); + ADD_EIP(ip); +} + +void +JMP_Ew(DWORD op) +{ + DWORD madr; + WORD new_ip; + + if (op >= 0xc0) { + CPU_WORKCLOCK(7); + new_ip = *(reg16_b20[op]); + SET_EIP(new_ip); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + SET_EIP(new_ip); + } +} + +void +JMP_Ed(DWORD op) +{ + DWORD madr; + DWORD new_ip; + + if (op >= 0xc0) { + CPU_WORKCLOCK(7); + new_ip = *(reg32_b20[op]); + SET_EIP(new_ip); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + SET_EIP(new_ip); + } +} + +void +JMP16_Ap(void) +{ + WORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(11); + GET_PCWORD(new_ip); + GET_PCWORD(new_cs); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + JMPfar_pm(new_cs, new_ip); + } +} + +void +JMP32_Ap(void) +{ + DWORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(11); + GET_PCDWORD(new_ip); + GET_PCWORD(new_cs); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + JMPfar_pm(new_cs, new_ip); + } +} + +void +JMP16_Ep(DWORD op) +{ + DWORD madr; + WORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(11); + if (op < 0xc0) { + madr = get_ea(op); + new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + JMPfar_pm(new_cs, new_ip); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +JMP32_Ep(DWORD op) +{ + DWORD madr; + DWORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(11); + if (op < 0xc0) { + madr = get_ea(op); + new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + JMPfar_pm(new_cs, new_ip); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +/* jo */ +void +JO_Jb(void) +{ + + if (!CPU_OV) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JO_Jw(void) +{ + + if (!CPU_OV) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JO_Jd(void) +{ + + if (!CPU_OV) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jno */ +void +JNO_Jb(void) +{ + + if (CPU_OV) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNO_Jw(void) +{ + + if (CPU_OV) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNO_Jd(void) +{ + + if (CPU_OV) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jc */ +void +JC_Jb(void) +{ + + if (!(CPU_FLAGL & C_FLAG)) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JC_Jw(void) +{ + + if (!(CPU_FLAGL & C_FLAG)) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JC_Jd(void) +{ + + if (!(CPU_FLAGL & C_FLAG)) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jnc */ +void +JNC_Jb(void) +{ + + if (CPU_FLAGL & C_FLAG) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} +void +JNC_Jw(void) +{ + + if (CPU_FLAGL & C_FLAG) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} +void +JNC_Jd(void) +{ + + if (CPU_FLAGL & C_FLAG) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jz */ +void +JZ_Jb(void) +{ + + if (!(CPU_FLAGL & Z_FLAG)) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JZ_Jw(void) +{ + + if (!(CPU_FLAGL & Z_FLAG)) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JZ_Jd(void) +{ + + if (!(CPU_FLAGL & Z_FLAG)) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jnz */ +void +JNZ_Jb(void) +{ + + if (CPU_FLAGL & Z_FLAG) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNZ_Jw(void) +{ + + if (CPU_FLAGL & Z_FLAG) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNZ_Jd(void) +{ + + if (CPU_FLAGL & Z_FLAG) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jna */ +void +JNA_Jb(void) +{ + + if (!(CPU_FLAGL & (Z_FLAG | C_FLAG))) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNA_Jw(void) +{ + + if (!(CPU_FLAGL & (Z_FLAG | C_FLAG))) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNA_Jd(void) +{ + + if (!(CPU_FLAGL & (Z_FLAG | C_FLAG))) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* ja */ +void +JA_Jb(void) +{ + + if (CPU_FLAGL & (Z_FLAG | C_FLAG)) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JA_Jw(void) +{ + + if (CPU_FLAGL & (Z_FLAG | C_FLAG)) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JA_Jd(void) +{ + + if (CPU_FLAGL & (Z_FLAG | C_FLAG)) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* js */ +void +JS_Jb(void) +{ + + if (!(CPU_FLAGL & S_FLAG)) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JS_Jw(void) +{ + + if (!(CPU_FLAGL & S_FLAG)) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JS_Jd(void) +{ + + if (!(CPU_FLAGL & S_FLAG)) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jns */ +void +JNS_Jb(void) +{ + + if (CPU_FLAGL & S_FLAG) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNS_Jw(void) +{ + + if (CPU_FLAGL & S_FLAG) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNS_Jd(void) +{ + + if (CPU_FLAGL & S_FLAG) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jp */ +void +JP_Jb(void) +{ + + if (!(CPU_FLAGL & P_FLAG)) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JP_Jw(void) +{ + + if (!(CPU_FLAGL & P_FLAG)) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JP_Jd(void) +{ + + if (!(CPU_FLAGL & P_FLAG)) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jnp */ +void +JNP_Jb(void) +{ + + if (CPU_FLAGL & P_FLAG) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNP_Jw(void) +{ + + if (CPU_FLAGL & P_FLAG) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNP_Jd(void) +{ + + if (CPU_FLAGL & P_FLAG) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jl */ +void +JL_Jb(void) +{ + + if ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV)) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JL_Jw(void) +{ + + if ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV)) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JL_Jd(void) +{ + + if ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV)) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jnl */ +void +JNL_Jb(void) +{ + + if ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV)) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNL_Jw(void) +{ + + if ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV)) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNL_Jd(void) +{ + + if ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV)) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jle */ +void +JLE_Jb(void) +{ + + if ((!(CPU_FLAGL & Z_FLAG)) && ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV))) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JLE_Jw(void) +{ + + if ((!(CPU_FLAGL & Z_FLAG)) && ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV))) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JLE_Jd(void) +{ + + if ((!(CPU_FLAGL & Z_FLAG)) && ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV))) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jnle */ +void +JNLE_Jb(void) +{ + + if ((CPU_FLAGL & Z_FLAG) || ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV))) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNLE_Jw(void) +{ + + if ((CPU_FLAGL & Z_FLAG) || ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV))) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNLE_Jd(void) +{ + + if ((CPU_FLAGL & Z_FLAG) || ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV))) { + JMPNOP(2, 4); + } else { + JMPNEAR_4(7); + } +} + +/* jcxz */ +void +JeCXZ_Jb(void) +{ + + if (!CPU_INST_AS32) { + if (CPU_CX) { + JMPNOP(4, 1); + } else { + JMPSHORT(8); + } + } else { + if (CPU_ECX) { + JMPNOP(4, 1); + } else { + JMPSHORT(8); + } + } +} + +/* + * LOOPcc + */ +/* loopne */ +void +LOOPNE_Jb(void) +{ + + if (!CPU_INST_AS32) { + CPU_CX--; + if (CPU_CX == 0 || (CPU_FLAGL & Z_FLAG)) { + JMPNOP(4, 1); + } else { + JMPSHORT(8); + } + } else { + CPU_ECX--; + if (CPU_ECX == 0 || (CPU_FLAGL & Z_FLAG)) { + JMPNOP(4, 1); + } else { + JMPSHORT(8); + } + } +} + +/* loope */ +void +LOOPE_Jb(void) +{ + + if (!CPU_INST_AS32) { + CPU_CX--; + if (CPU_CX == 0 || !(CPU_FLAGL & Z_FLAG)) { + JMPNOP(4, 1); + } else { + JMPSHORT(8); + } + } else { + CPU_ECX--; + if (CPU_ECX == 0 || !(CPU_FLAGL & Z_FLAG)) { + JMPNOP(4, 1); + } else { + JMPSHORT(8); + } + } +} + +/* loop */ +void +LOOP_Jb(void) +{ + + if (!CPU_INST_AS32) { + CPU_CX--; + if (CPU_CX == 0) { + JMPNOP(4, 1); + } else { + JMPSHORT(8); + } + } else { + CPU_ECX--; + if (CPU_ECX == 0) { + JMPNOP(4, 1); + } else { + JMPSHORT(8); + } + } +} + +/* + * CALL + */ +void +CALL_Aw(void) +{ + WORD ip; + + CPU_WORKCLOCK(7); + GET_PCWORD(ip); + PUSH0_16(CPU_IP); + ADD_EIP(ip); +} + +void +CALL_Ad(void) +{ + DWORD ip; + + CPU_WORKCLOCK(7); + GET_PCDWORD(ip); + PUSH0_32(CPU_EIP); + ADD_EIP(ip); +} + +void +CALL_Ew(DWORD op) +{ + DWORD madr; + WORD new_ip; + + if (op >= 0xc0) { + CPU_WORKCLOCK(7); + new_ip = *(reg16_b20[op]); + PUSH0_16(CPU_IP); + SET_EIP(new_ip); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + PUSH0_16(CPU_IP); + SET_EIP(new_ip); + } +} + +void +CALL_Ed(DWORD op) +{ + DWORD madr; + DWORD new_ip; + + if (op >= 0xc0) { + CPU_WORKCLOCK(7); + new_ip = *(reg32_b20[op]); + PUSH0_32(CPU_EIP); + SET_EIP(new_ip); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + PUSH0_32(CPU_EIP); + SET_EIP(new_ip); + } +} + +void +CALL16_Ap(void) +{ + WORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(13); + GET_PCWORD(new_ip); + GET_PCWORD(new_cs); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + PUSH0_16(CPU_CS); + PUSH0_16(CPU_IP); + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + CALLfar_pm(new_cs, new_ip); + } +} + +void +CALL32_Ap(void) +{ + DWORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(13); + GET_PCDWORD(new_ip); + GET_PCWORD(new_cs); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + PUSH0_32(CPU_CS); + PUSH0_32(CPU_EIP); + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + CALLfar_pm(new_cs, new_ip); + } +} + +void +CALL16_Ep(DWORD op) +{ + DWORD ad; + WORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(16); + if (op < 0xc0) { + ad = get_ea(op); + new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); + new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad + 2); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + PUSH0_16(CPU_CS); + PUSH0_16(CPU_IP); + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + CALLfar_pm(new_cs, new_ip); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +CALL32_Ep(DWORD op) +{ + DWORD ad; + DWORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(16); + if (op < 0xc0) { + ad = get_ea(op); + new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); + new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad + 4); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + PUSH0_32(CPU_CS); + PUSH0_32(CPU_EIP); + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + CALLfar_pm(new_cs, new_ip); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +/* + * RET + */ +void +RETnear16(void) +{ + WORD new_ip; + + CPU_WORKCLOCK(11); + POP0_16(new_ip); + SET_EIP(new_ip); +} + +void +RETnear32(void) +{ + DWORD new_ip; + + CPU_WORKCLOCK(11); + POP0_32(new_ip); + SET_EIP(new_ip); +} + +void +RETnear16_Iw(void) +{ + WORD new_ip; + WORD ad; + + CPU_WORKCLOCK(11); + GET_PCWORD(ad); + POP0_16(new_ip); + SET_EIP(new_ip); + CPU_SP += ad; +} + +void +RETnear32_Iw(void) +{ + DWORD new_ip; + DWORD ad; + + CPU_WORKCLOCK(11); + GET_PCDWORD(ad); + POP0_32(new_ip); + SET_EIP(new_ip); + CPU_ESP += ad; +} + +void +RETfar16(void) +{ + WORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(15); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + POP0_16(new_ip); + POP0_16(new_cs); + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + RETfar_pm(0); + } +} + +void +RETfar32(void) +{ + DWORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(15); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + POP0_32(new_ip); + POP0_32(new_cs); + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + RETfar_pm(0); + } +} + +void +RETfar16_Iw(void) +{ + WORD ad; + WORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(15); + GET_PCWORD(ad); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + POP0_16(new_ip); + POP0_16(new_cs); + CPU_SP += ad; + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + RETfar_pm(ad); + } +} + +void +RETfar32_Iw(void) +{ + DWORD ad; + DWORD new_ip; + WORD new_cs; + + CPU_WORKCLOCK(15); + GET_PCDWORD(ad); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + POP0_32(new_ip); + POP0_32(new_cs); + CPU_ESP += ad; + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + RETfar_pm(ad); + } +} + +void +IRET(void) +{ + WORD new_ip; + WORD flag; + WORD new_cs; + + CPU_WORKCLOCK(31); + if (!CPU_STAT_PM) { + /* Real mode */ + POP0_16(new_ip); + POP0_16(new_cs); + POP0_16(flag); + + CPU_FLAG = flag & 0x7fd5; + CPU_OV = CPU_FLAG & O_FLAG; + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + IRET_pm(); + } + IRQCHECKTERM(); +} + +void +IRETD(void) +{ + DWORD new_ip; + DWORD flag; + WORD new_cs; + + CPU_WORKCLOCK(31); + if (!CPU_STAT_PM) { + /* Real mode */ + POP0_32(new_ip); + POP0_32(new_cs); + POP0_32(flag); + + CPU_EFLAG = (flag & 0x00257fd5) | (REAL_EFLAGREG & 0x1a0000); + CPU_OV = CPU_FLAG & O_FLAG; + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); + + CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + SET_EIP(new_ip); + } else { + /* Protected mode */ + IRET_pm(); + } + IRQCHECKTERM(); +} + +/* + * INT + */ +void +INT1(void) +{ + + CPU_WORKCLOCK(23); + INTERRUPT(1, 1, 0, 0); +} + +void +INT3(void) +{ + + CPU_WORKCLOCK(23); + INTERRUPT(3, 2, 0, 0); +} + +void +INTO(void) +{ + + if (!CPU_OV) { + CPU_WORKCLOCK(4); + return; + } + CPU_WORKCLOCK(24); + INTERRUPT(4, 3, 0, 0); +} + +void +INT_Ib(void) +{ + BYTE vect; + + CPU_WORKCLOCK(23); + if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { + GET_PCBYTE(vect); + INTERRUPT(vect, -1, 0, 0); + return; + } + EXCEPTION(GP_EXCEPTION, 0); +} + +void +BOUND_GwMa(void) +{ + DWORD op, madr; + WORD reg; + int vect; + + CPU_WORKCLOCK(13); + GET_PCBYTE(op); + if (op < 0xc0) { + reg = *(reg16_b53[op]); + madr = calc_ea_dst(op); + if (reg >= cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr) && + reg <= cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2)) { + return; + } + vect = BR_EXCEPTION; + } else { + vect = UD_EXCEPTION; + } + EXCEPTION(vect, 0); +} + +void +BOUND_GdMa(void) +{ + DWORD op, madr; + DWORD reg; + int vect; + + CPU_WORKCLOCK(13); + GET_PCBYTE(op); + if (op < 0xc0) { + reg = *(reg32_b53[op]); + madr = calc_ea_dst(op); + if (reg >= cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr) && + reg <= cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 4)) { + return; + } + vect = BR_EXCEPTION; + } else { + vect = UD_EXCEPTION; + } + EXCEPTION(vect, 0); +} + +/* + * STACK + */ +void +ENTER_IwIb(void) +{ + WORD dimsize; + BYTE level; + + GET_PCWORD(dimsize); + GET_PCBYTE(level); + level &= 0x1f; + + /* check stack room size */ + if (CPU_STAT_PM) { + DWORD size = dimsize; + DWORD sp; + if (CPU_INST_OP32) { + size = (level + 1) * 4; + } else { + size = (level + 1) * 2; + } + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { + sp = CPU_SP; + } + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, size); + } + + XPUSH0(CPU_EBP); + if (level == 0) { /* enter level=0 */ + CPU_WORKCLOCK(11); + if (!CPU_INST_OP32) { + CPU_BP = CPU_SP; + } else { + CPU_EBP = CPU_ESP; + } + if (!CPU_STAT_SS32) { + CPU_SP -= dimsize; + } else { + CPU_ESP -= dimsize; + } + } else { + --level; + if (level == 0) { /* enter level=1 */ + CPU_WORKCLOCK(15); + if (!CPU_INST_OP32) { + WORD tmp = CPU_SP; + PUSH0_16(tmp); + CPU_BP = tmp; + CPU_SP -= dimsize; + } else { + DWORD tmp; + if (!CPU_STAT_SS32) { + tmp = CPU_SP; + REGPUSH0_32_16(tmp); + CPU_EBP = (WORD)tmp; + CPU_ESP -= dimsize; + } else { + tmp = CPU_ESP; + REGPUSH0_32(tmp); + CPU_EBP = tmp; + CPU_ESP -= dimsize; + } + } + } else { /* enter level=2-31 */ + CPU_WORKCLOCK(12 + level * 4); + if (!CPU_INST_OP32) { + WORD bp = CPU_BP; + WORD val; + + CPU_BP = CPU_SP; + if (!CPU_STAT_SS32) { + while (level--) { + bp -= 2; + CPU_SP -= 2; + val = cpu_vmemoryread_w(CPU_SS_INDEX, bp); + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, val); + } + REGPUSH0(CPU_BP); + CPU_SP -= dimsize; + } else { + while (level--) { + bp -= 2; + CPU_ESP -= 2; + val = cpu_vmemoryread_w(CPU_SS_INDEX, bp); + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_ESP, val); + } + REGPUSH0_16_32(CPU_EBP); + CPU_ESP -= dimsize; + } + } else { + DWORD ebp = CPU_EBP; + DWORD val; + + if (!CPU_STAT_SS32) { + CPU_EBP = CPU_SP; + while (level--) { + ebp -= 4; + CPU_SP -= 4; + val = cpu_vmemoryread_d(CPU_SS_INDEX, ebp); + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_SP, val); + } + REGPUSH0_32_16(CPU_EBP); + CPU_SP -= dimsize; + } else { + CPU_EBP = CPU_ESP; + while (level--) { + ebp -= 4; + CPU_ESP -= 4; + val = cpu_vmemoryread_d(CPU_SS_INDEX, ebp); + cpu_vmemorywrite(CPU_SS_INDEX, CPU_ESP, val); + } + REGPUSH0_32(CPU_EBP); + CPU_ESP -= dimsize; + } + } + } + } +} + +void +LEAVE16(void) +{ + WORD bp; + DWORD sp, size; + + CPU_WORKCLOCK(5); + + if (CPU_STAT_PM) { + bp = CPU_BP; + if (!CPU_STAT_SS32) { + sp = CPU_SP; + size = 2; + } else { + sp = CPU_ESP; + size = 4; + } + if (bp < sp) { + ia32_panic("LEAVE16: bp < sp"); + } + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, (bp - sp) + size); + } + + CPU_SP = CPU_BP; + REGPOP0(CPU_BP); +} + +void +LEAVE32(void) +{ + DWORD bp, sp, size; + + CPU_WORKCLOCK(5); + + if (CPU_STAT_PM) { + bp = CPU_EBP; + if (CPU_STAT_SS32) { + sp = CPU_ESP; + size = 4; + } else { + sp = CPU_SP; + size = 2; + } + if (bp < sp) { + ia32_panic("LEAVE32: bp < sp"); + } + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, (bp - sp) + size); + } + + if (CPU_STAT_SS32) { + CPU_ESP = CPU_EBP; + REGPOP0_32(CPU_EBP); + } else { + CPU_SP = CPU_BP; + REGPOP0_32_16(CPU_EBP); + } +} diff --git a/i386c/ia32/instructions/ctrl_trans.h b/i386c/ia32/instructions/ctrl_trans.h new file mode 100644 index 00000000..7b33f9dd --- /dev/null +++ b/i386c/ia32/instructions/ctrl_trans.h @@ -0,0 +1,158 @@ +/* $Id: ctrl_trans.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_CTRL_TRANS_H__ +#define IA32_CPU_INSTRUCTION_CTRL_TRANS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JMP + */ +void JMP_Jb(void); +void JMP_Jw(void); +void JMP_Jd(void); +void JMP_Ew(DWORD); +void JMP_Ed(DWORD); +void JMP16_Ap(void); +void JMP32_Ap(void); +void JMP16_Ep(DWORD); +void JMP32_Ep(DWORD); + +/* + * Jcc + */ +void JO_Jb(void); +void JO_Jw(void); +void JO_Jd(void); +void JNO_Jb(void); +void JNO_Jw(void); +void JNO_Jd(void); +void JC_Jb(void); +void JC_Jw(void); +void JC_Jd(void); +void JNC_Jb(void); +void JNC_Jw(void); +void JNC_Jd(void); +void JZ_Jb(void); +void JZ_Jw(void); +void JZ_Jd(void); +void JNZ_Jb(void); +void JNZ_Jw(void); +void JNZ_Jd(void); +void JA_Jb(void); +void JA_Jw(void); +void JA_Jd(void); +void JNA_Jb(void); +void JNA_Jw(void); +void JNA_Jd(void); +void JS_Jb(void); +void JS_Jw(void); +void JS_Jd(void); +void JNS_Jb(void); +void JNS_Jw(void); +void JNS_Jd(void); +void JP_Jb(void); +void JP_Jw(void); +void JP_Jd(void); +void JNP_Jb(void); +void JNP_Jw(void); +void JNP_Jd(void); +void JL_Jb(void); +void JL_Jw(void); +void JL_Jd(void); +void JNL_Jb(void); +void JNL_Jw(void); +void JNL_Jd(void); +void JLE_Jb(void); +void JLE_Jw(void); +void JLE_Jd(void); +void JNLE_Jb(void); +void JNLE_Jw(void); +void JNLE_Jd(void); +void JeCXZ_Jb(void); + +/* + * LOOPcc + */ +void LOOPNE_Jb(void); +void LOOPE_Jb(void); +void LOOP_Jb(void); + +/* + * CALL + */ +void CALL_Aw(void); +void CALL_Ad(void); +void CALL_Ew(DWORD); +void CALL_Ed(DWORD); +void CALL16_Ap(void); +void CALL32_Ap(void); +void CALL16_Ep(DWORD); +void CALL32_Ep(DWORD); + +/* + * RET + */ +void RETnear16(void); +void RETnear32(void); +void RETnear16_Iw(void); +void RETnear32_Iw(void); +void RETfar16(void); +void RETfar32(void); +void RETfar16_Iw(void); +void RETfar32_Iw(void); +void IRET(void); +void IRETD(void); + +/* + * INT + */ +void INT1(void); +void INT3(void); +void INTO(void); +void INT_Ib(void); + +void BOUND_GwMa(void); +void BOUND_GdMa(void); + +/* + * STACK + */ +void ENTER_IwIb(void); +void LEAVE16(void); +void LEAVE32(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_CTRL_TRANS_H__ */ diff --git a/i386c/ia32/instructions/data_trans.c b/i386c/ia32/instructions/data_trans.c new file mode 100644 index 00000000..0bd8ca6f --- /dev/null +++ b/i386c/ia32/instructions/data_trans.c @@ -0,0 +1,1669 @@ +/* $Id: data_trans.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "data_trans.h" + +/* + * MOV + */ +void +MOV_EbGb(void) +{ + DWORD op, src, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void +MOV_EwGw(void) +{ + DWORD op, src, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg16_b20[op]) = src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void +MOV_EdGd(void) +{ + DWORD op, src, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg32_b20[op]) = src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void +MOV_GbEb(void) +{ + BYTE *out; + DWORD op, src; + + PREPART_REG8_EA(op, src, out, 2, 5); + *out = src; +} + +void +MOV_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + *out = src; +} + +void +MOV_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + *out = src; +} + +void +MOV_EwSw(void) +{ + DWORD op, src, madr; + BYTE idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 3; + if (idx < CPU_SEGREG_NUM) { + src = CPU_REGS_SREG(idx); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg16_b20[op]) = src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, src); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_SwEw(void) +{ + DWORD op, src, madr; + BYTE idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 3; + if (idx != CPU_CS_INDEX && idx < CPU_SEGREG_NUM) { + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + CPU_SET_SEGREG(idx, src); + if (idx == CPU_SS_INDEX) { + exec_1step(); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_ALOb(void) +{ + DWORD madr; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } else { + GET_PCDWORD(madr); + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } +} + +void +MOV_AXOw(void) +{ + DWORD madr; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + CPU_AX = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } else { + GET_PCDWORD(madr); + CPU_AX = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } +} + +void +MOV_EAXOd(void) +{ + DWORD madr; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + CPU_EAX = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } else { + GET_PCDWORD(madr); + CPU_EAX = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } +} + +void +MOV_ObAL(void) +{ + DWORD madr; + + CPU_WORKCLOCK(3); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, CPU_AL); + } else { + GET_PCDWORD(madr); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, CPU_AL); + } +} + +void +MOV_OwAX(void) +{ + DWORD madr; + + CPU_WORKCLOCK(3); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_AX); + } else { + GET_PCDWORD(madr); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_AX); + } +} + +void +MOV_OdEAX(void) +{ + DWORD madr; + + CPU_WORKCLOCK(3); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_EAX); + } else { + GET_PCDWORD(madr); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_EAX); + } +} + +void +MOV_EbIb(void) +{ + DWORD op, src, res, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(res); + *(reg8_b20[op]) = (BYTE)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCBYTE(res); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); + } +} + +void +MOV_EwIw(void) +{ + DWORD op, src, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCWORD(res); + *(reg16_b20[op]) = (WORD)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCWORD(res); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); + } +} + +void +MOV_EdId(void) +{ + DWORD op, src, res, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCDWORD(res); + *(reg32_b20[op]) = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCDWORD(res); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +void MOV_ALIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_AL); } +void MOV_CLIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_CL); } +void MOV_DLIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_DL); } +void MOV_BLIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_BL); } +void MOV_AHIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_AH); } +void MOV_CHIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_CH); } +void MOV_DHIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_DH); } +void MOV_BHIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_BH); } + +void MOV_AXIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_AX); } +void MOV_CXIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_CX); } +void MOV_DXIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_DX); } +void MOV_BXIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_BX); } +void MOV_SPIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_SP); } +void MOV_BPIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_BP); } +void MOV_SIIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_SI); } +void MOV_DIIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_DI); } + +void MOV_EAXId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EAX); } +void MOV_ECXId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_ECX); } +void MOV_EDXId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EDX); } +void MOV_EBXId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EBX); } +void MOV_ESPId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_ESP); } +void MOV_EBPId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EBP); } +void MOV_ESIId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_ESI); } +void MOV_EDIId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EDI); } + +/* + * CMOVcc + */ +void +CMOVO_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CPU_OV) { + *out = src; + } +} + +void +CMOVO_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CPU_OV) { + *out = src; + } +} + +void +CMOVNO_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (!CPU_OV) { + *out = src; + } +} + +void +CMOVNO_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (!CPU_OV) { + *out = src; + } +} + +void +CMOVC_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CPU_FLAGL & C_FLAG) { + *out = src; + } +} + +void +CMOVC_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CPU_FLAGL & C_FLAG) { + *out = src; + } +} + +void +CMOVNC_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & C_FLAG)) { + *out = src; + } +} + +void +CMOVNC_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & C_FLAG)) { + *out = src; + } +} + +void +CMOVZ_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CPU_FLAGL & Z_FLAG) { + *out = src; + } +} + +void +CMOVZ_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CPU_FLAGL & Z_FLAG) { + *out = src; + } +} + +void +CMOVNZ_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & Z_FLAG)) { + *out = src; + } +} + +void +CMOVNZ_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & Z_FLAG)) { + *out = src; + } +} + +void +CMOVA_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & (Z_FLAG | C_FLAG))) { + *out = src; + } +} + +void +CMOVA_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & (Z_FLAG | C_FLAG))) { + *out = src; + } +} + +void +CMOVNA_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CPU_FLAGL & (Z_FLAG | C_FLAG)) { + *out = src; + } +} + +void +CMOVNA_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CPU_FLAGL & (Z_FLAG | C_FLAG)) { + *out = src; + } +} + +void +CMOVS_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CPU_FLAGL & S_FLAG) { + *out = src; + } +} + +void +CMOVS_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CPU_FLAGL & S_FLAG) { + *out = src; + } +} + +void +CMOVNS_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & S_FLAG)) { + *out = src; + } +} + +void +CMOVNS_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & S_FLAG)) { + *out = src; + } +} + +void +CMOVP_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CPU_FLAGL & P_FLAG) { + *out = src; + } +} + +void +CMOVP_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CPU_FLAGL & P_FLAG) { + *out = src; + } +} + +void +CMOVNP_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & P_FLAG)) { + *out = src; + } +} + +void +CMOVNP_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (!(CPU_FLAGL & P_FLAG)) { + *out = src; + } +} + +void +CMOVL_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if ((!CPU_OV) != (!(CPU_FLAGL & S_FLAG))) { + *out = src; + } +} + +void +CMOVL_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if ((!CPU_OV) != (!(CPU_FLAGL & S_FLAG))) { + *out = src; + } +} + +void +CMOVNL_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if ((!CPU_OV) == (!(CPU_FLAGL & S_FLAG))) { + *out = src; + } +} + +void +CMOVNL_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if ((!CPU_OV) == (!(CPU_FLAGL & S_FLAG))) { + *out = src; + } +} + +void +CMOVLE_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if ((CPU_FLAGL & Z_FLAG) || ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV))) { + *out = src; + } +} + +void +CMOVLE_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if ((CPU_FLAGL & Z_FLAG) || ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV))) { + *out = src; + } +} + +void +CMOVNLE_GwEw(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if ((!(CPU_FLAGL & Z_FLAG)) && ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV))) { + *out = src; + } +} + +void +CMOVNLE_GdEd(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if ((!(CPU_FLAGL & Z_FLAG)) && ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV))) { + *out = src; + } +} + +/* + * XCHG + */ +void +XCHG_EbGb(void) +{ + BYTE *out, *src; + DWORD op, madr; + BYTE tmp; + + PREPART_EA_REG8P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg8_b20[op]; + SWAPBYTE(*out, *src); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, *src); + *src = tmp; + } +} + +void +XCHG_EwGw(void) +{ + WORD *out, *src; + DWORD op, madr; + WORD tmp; + + PREPART_EA_REG16P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg16_b20[op]; + SWAPWORD(*out, *src); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, *src); + *src = tmp; + } +} + +void +XCHG_EdGd(void) +{ + DWORD *out, *src; + DWORD op, madr; + DWORD tmp; + + PREPART_EA_REG32P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg32_b20[op]; + SWAPDWORD(*out, *src); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, *src); + *src = tmp; + } +} + +/* void XCHG_AXAX(void) { } */ +void XCHG_CXAX(void) { CPU_WORKCLOCK(3); SWAPWORD(CPU_CX, CPU_AX); } +void XCHG_DXAX(void) { CPU_WORKCLOCK(3); SWAPWORD(CPU_DX, CPU_AX); } +void XCHG_BXAX(void) { CPU_WORKCLOCK(3); SWAPWORD(CPU_BX, CPU_AX); } +void XCHG_SPAX(void) { CPU_WORKCLOCK(3); SWAPWORD(CPU_SP, CPU_AX); } +void XCHG_BPAX(void) { CPU_WORKCLOCK(3); SWAPWORD(CPU_BP, CPU_AX); } +void XCHG_SIAX(void) { CPU_WORKCLOCK(3); SWAPWORD(CPU_SI, CPU_AX); } +void XCHG_DIAX(void) { CPU_WORKCLOCK(3); SWAPWORD(CPU_DI, CPU_AX); } + +/* void XCHG_EAXEAX(void) { } */ +void XCHG_ECXEAX(void) { CPU_WORKCLOCK(3); SWAPDWORD(CPU_ECX, CPU_EAX); } +void XCHG_EDXEAX(void) { CPU_WORKCLOCK(3); SWAPDWORD(CPU_EDX, CPU_EAX); } +void XCHG_EBXEAX(void) { CPU_WORKCLOCK(3); SWAPDWORD(CPU_EBX, CPU_EAX); } +void XCHG_ESPEAX(void) { CPU_WORKCLOCK(3); SWAPDWORD(CPU_ESP, CPU_EAX); } +void XCHG_EBPEAX(void) { CPU_WORKCLOCK(3); SWAPDWORD(CPU_EBP, CPU_EAX); } +void XCHG_ESIEAX(void) { CPU_WORKCLOCK(3); SWAPDWORD(CPU_ESI, CPU_EAX); } +void XCHG_EDIEAX(void) { CPU_WORKCLOCK(3); SWAPDWORD(CPU_EDI, CPU_EAX); } + +/* + * BSWAP + */ +void BSWAP_EAX(void) { CPU_WORKCLOCK(2); CPU_EAX = BSWAP_DWORD(CPU_EAX); } +void BSWAP_ECX(void) { CPU_WORKCLOCK(2); CPU_ECX = BSWAP_DWORD(CPU_ECX); } +void BSWAP_EDX(void) { CPU_WORKCLOCK(2); CPU_EDX = BSWAP_DWORD(CPU_EDX); } +void BSWAP_EBX(void) { CPU_WORKCLOCK(2); CPU_EBX = BSWAP_DWORD(CPU_EBX); } +void BSWAP_ESP(void) { CPU_WORKCLOCK(2); CPU_ESP = BSWAP_DWORD(CPU_ESP); } +void BSWAP_EBP(void) { CPU_WORKCLOCK(2); CPU_EBP = BSWAP_DWORD(CPU_EBP); } +void BSWAP_ESI(void) { CPU_WORKCLOCK(2); CPU_ESI = BSWAP_DWORD(CPU_ESI); } +void BSWAP_EDI(void) { CPU_WORKCLOCK(2); CPU_EDI = BSWAP_DWORD(CPU_EDI); } + +/* + * XADD + */ +void +XADD_EbGb(void) +{ + BYTE *out, *src; + DWORD op, dst, res, madr; + + PREPART_EA_REG8P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + ADDBYTE(res, dst, *src); + *src = dst; + *out = (BYTE)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ADDBYTE(res, dst, *src); + *src = dst; + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); + } +} + +void +XADD_EwGw(void) +{ + WORD *out, *src; + DWORD op, dst, res, madr; + + PREPART_EA_REG16P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + ADDWORD(res, dst, *src); + *src = dst; + *out = (WORD)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ADDWORD(res, dst, *src); + *src = dst; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); + } +} + +void +XADD_EdGd(void) +{ + DWORD *out, *src; + DWORD op, dst, res, madr; + + PREPART_EA_REG32P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + ADDDWORD(res, dst, *src); + *src = dst; + *out = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ADDDWORD(res, dst, *src); + *src = dst; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +/* + * CMPXCHG + */ +void +CMPXCHG_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, madr, tmp; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + out = reg8_b20[op]; + dst = *out; + BYTE_SUB(tmp, CPU_AL, dst); + if (CPU_FLAGL & Z_FLAG) { + *out = src; + } else { + CPU_AL = dst; + } + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SUB(tmp, CPU_AL, dst); + if (CPU_FLAGL & Z_FLAG) { + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, src); + } else { + CPU_AL = dst; + } + } +} + +void +CMPXCHG_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, madr, tmp; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + out = reg16_b20[op]; + dst = *out; + WORD_SUB(tmp, CPU_AX, dst); + if (CPU_FLAGL & Z_FLAG) { + *out = src; + } else { + CPU_AX = dst; + } + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SUB(tmp, CPU_AX, dst); + if (CPU_FLAGL & Z_FLAG) { + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, src); + } else { + CPU_AX = dst; + } + } +} + +void +CMPXCHG_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, madr, tmp; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + out = reg32_b20[op]; + dst = *out; + WORD_SUB(tmp, CPU_EAX, dst); + if (CPU_FLAGL & Z_FLAG) { + *out = src; + } else { + CPU_EAX = dst; + } + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SUB(tmp, CPU_AX, dst); + if (CPU_FLAGL & Z_FLAG) { + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } else { + CPU_EAX = dst; + } + } +} + +void +CMPXCHG8B(DWORD op) +{ + DWORD madr, dst_l, dst_h; + + if (op < 0xc0) { + CPU_WORKCLOCK(2); + madr = calc_ea_dst(op); + dst_l = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + dst_h = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 4); + if ((CPU_EDX == dst_h) && (CPU_EAX == dst_l)) { + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_EBX); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 4, CPU_ECX); + CPU_FLAGL |= Z_FLAG; + } else { + CPU_EDX = dst_h; + CPU_EAX = dst_l; + CPU_FLAGL &= ~Z_FLAG; + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +/* + * PUSH + */ +void PUSH_AX(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_AX); } +void PUSH_CX(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_CX); } +void PUSH_DX(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_DX); } +void PUSH_BX(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_BX); } +void PUSH_SP(void) { CPU_WORKCLOCK(3); SP_PUSH0_16(CPU_SP); } +void PUSH_BP(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_BP); } +void PUSH_SI(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_SI); } +void PUSH_DI(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_DI); } + +void PUSH_EAX(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EAX); } +void PUSH_ECX(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_ECX); } +void PUSH_EDX(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EDX); } +void PUSH_EBX(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EBX); } +void PUSH_ESP(void) { CPU_WORKCLOCK(3); ESP_PUSH0_32(CPU_ESP); } +void PUSH_EBP(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EBP); } +void PUSH_ESI(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_ESI); } +void PUSH_EDI(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EDI); } + +void +PUSH_Ew(DWORD op) +{ + DWORD dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg16_b20[op]); + PUSH0_16(dst); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + PUSH0_16(dst); + } +} + +void +PUSH_Ed(DWORD op) +{ + DWORD dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg32_b20[op]); + PUSH0_32(dst); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + PUSH0_32(dst); + } +} + +void +PUSH_Ib(void) +{ + SDWORD val; + + CPU_WORKCLOCK(3); + GET_PCBYTESD(val); + XPUSH0((WORD)val); +} + +void +PUSH_Iw(void) +{ + WORD val; + + CPU_WORKCLOCK(3); + GET_PCWORD(val); + PUSH0_16(val); +} + +void +PUSH_Id(void) +{ + DWORD val; + + CPU_WORKCLOCK(3); + GET_PCDWORD(val); + PUSH0_32(val); +} + +void PUSH16_ES(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_ES); } +void PUSH16_CS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_CS); } +void PUSH16_SS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_SS); } +void PUSH16_DS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_DS); } +void PUSH16_FS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_FS); } +void PUSH16_GS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_GS); } + +void PUSH32_ES(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_ES); } +void PUSH32_CS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_CS); } +void PUSH32_SS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_SS); } +void PUSH32_DS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_DS); } +void PUSH32_FS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_FS); } +void PUSH32_GS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_GS); } + +/* + * POP + */ +void POP_AX(void) { CPU_WORKCLOCK(5); POP0_16(CPU_AX); } +void POP_CX(void) { CPU_WORKCLOCK(5); POP0_16(CPU_CX); } +void POP_DX(void) { CPU_WORKCLOCK(5); POP0_16(CPU_DX); } +void POP_BX(void) { CPU_WORKCLOCK(5); POP0_16(CPU_BX); } +void POP_SP(void) { CPU_WORKCLOCK(5); SP_POP0_16(CPU_SP); } +void POP_BP(void) { CPU_WORKCLOCK(5); POP0_16(CPU_BP); } +void POP_SI(void) { CPU_WORKCLOCK(5); POP0_16(CPU_SI); } +void POP_DI(void) { CPU_WORKCLOCK(5); POP0_16(CPU_DI); } + +void POP_EAX(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EAX); } +void POP_ECX(void) { CPU_WORKCLOCK(5); POP0_32(CPU_ECX); } +void POP_EDX(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EDX); } +void POP_EBX(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EBX); } +void POP_ESP(void) { CPU_WORKCLOCK(5); ESP_POP0_32(CPU_ESP); } +void POP_EBP(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EBP); } +void POP_ESI(void) { CPU_WORKCLOCK(5); POP0_32(CPU_ESI); } +void POP_EDI(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EDI); } + +void +POP_Ew(void) +{ + DWORD op, madr; + WORD src; + + CPU_WORKCLOCK(5); + + POP0_16(src); + GET_PCBYTE(op); + if (op >= 0xc0) { + *(reg16_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void +POP_Ew_G5(DWORD op) +{ + DWORD madr; + WORD src; + + CPU_WORKCLOCK(5); + + POP0_16(src); + if (op >= 0xc0) { + *(reg16_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void +POP_Ed(void) +{ + DWORD op, madr; + DWORD src; + + CPU_WORKCLOCK(5); + + POP0_32(src); + GET_PCBYTE(op); + if (op >= 0xc0) { + *(reg32_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void +POP_Ed_G5(DWORD op) +{ + DWORD src, madr; + + CPU_WORKCLOCK(5); + + POP0_32(src); + if (op >= 0xc0) { + *(reg32_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void +POP16_ES(void) +{ + WORD src; + + CPU_WORKCLOCK(5); + + POP0_16(src); + CPU_SET_SEGREG(CPU_ES_INDEX, src); +} + +void +POP32_ES(void) +{ + DWORD src; + + CPU_WORKCLOCK(5); + + POP0_32(src); + CPU_SET_SEGREG(CPU_ES_INDEX, src); +} + +void +POP16_SS(void) +{ + WORD src; + + CPU_WORKCLOCK(5); + + POP0_16(src); + CPU_SET_SEGREG(CPU_SS_INDEX, src); + exec_1step(); +} + +void +POP32_SS(void) +{ + DWORD src; + + CPU_WORKCLOCK(5); + + POP0_32(src); + CPU_SET_SEGREG(CPU_SS_INDEX, src); + exec_1step(); +} + +void +POP16_DS(void) +{ + WORD src; + + CPU_WORKCLOCK(5); + + POP0_16(src); + CPU_SET_SEGREG(CPU_DS_INDEX, src); +} + +void +POP32_DS(void) +{ + DWORD src; + + CPU_WORKCLOCK(5); + + POP0_32(src); + CPU_SET_SEGREG(CPU_DS_INDEX, src); +} + +void +POP16_FS(void) +{ + WORD src; + + CPU_WORKCLOCK(5); + + POP0_16(src); + CPU_SET_SEGREG(CPU_FS_INDEX, src); +} + +void +POP32_FS(void) +{ + DWORD src; + + CPU_WORKCLOCK(5); + + POP0_32(src); + CPU_SET_SEGREG(CPU_FS_INDEX, src); +} + +void +POP16_GS(void) +{ + WORD src; + + CPU_WORKCLOCK(5); + + POP0_16(src); + CPU_SET_SEGREG(CPU_GS_INDEX, src); +} + +void +POP32_GS(void) +{ + DWORD src; + + CPU_WORKCLOCK(5); + + POP0_32(src); + CPU_SET_SEGREG(CPU_GS_INDEX, src); +} + +/* + * PUSHA/POPA + */ +void +PUSHA(void) +{ + + CPU_WORKCLOCK(17); + if (!CPU_STAT_SS32) { + if (CPU_STAT_PM) { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_SP, 16); + } + REGPUSH0(CPU_AX); + REGPUSH0(CPU_CX); + REGPUSH0(CPU_DX); + REGPUSH0(CPU_BX); + SP_PUSH0(CPU_SP); + REGPUSH0(CPU_BP); + REGPUSH0(CPU_SI); + REGPUSH0(CPU_DI); + } else { + if (CPU_STAT_PM) { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 32); + } + REGPUSH0_16_32(CPU_AX); + REGPUSH0_16_32(CPU_CX); + REGPUSH0_16_32(CPU_DX); + REGPUSH0_16_32(CPU_BX); + SP_PUSH0_16_32(CPU_SP); + REGPUSH0_16_32(CPU_BP); + REGPUSH0_16_32(CPU_SI); + REGPUSH0_16_32(CPU_DI); + } +} + +void +PUSHAD(void) +{ + + CPU_WORKCLOCK(17); + if (!CPU_STAT_SS32) { + if (CPU_STAT_PM) { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_SP, 16); + } + REGPUSH0_32_16(CPU_EAX); + REGPUSH0_32_16(CPU_ECX); + REGPUSH0_32_16(CPU_EDX); + REGPUSH0_32_16(CPU_EBX); + ESP_PUSH0_32_16(CPU_ESP); + REGPUSH0_32_16(CPU_EBP); + REGPUSH0_32_16(CPU_ESI); + REGPUSH0_32_16(CPU_EDI); + } else { + if (CPU_STAT_PM) { + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 32); + } + REGPUSH0_32(CPU_EAX); + REGPUSH0_32(CPU_ECX); + REGPUSH0_32(CPU_EDX); + REGPUSH0_32(CPU_EBX); + ESP_PUSH0_32(CPU_ESP); + REGPUSH0_32(CPU_EBP); + REGPUSH0_32(CPU_ESI); + REGPUSH0_32(CPU_EDI); + } +} + +void +POPA(void) +{ + + CPU_WORKCLOCK(19); + if (!CPU_STAT_SS32) { + if (CPU_STAT_PM) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_SP, 16); + } + REGPOP0(CPU_DI); + REGPOP0(CPU_SI); + REGPOP0(CPU_BP); + CPU_SP += 2; + REGPOP0(CPU_BX); + REGPOP0(CPU_DX); + REGPOP0(CPU_CX); + REGPOP0(CPU_AX); + } else { + if (CPU_STAT_PM) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 32); + } + REGPOP0_16_32(CPU_DI); + REGPOP0_16_32(CPU_SI); + REGPOP0_16_32(CPU_BP); + CPU_ESP += 2; + REGPOP0_16_32(CPU_BX); + REGPOP0_16_32(CPU_DX); + REGPOP0_16_32(CPU_CX); + REGPOP0_16_32(CPU_AX); + } +} + +void +POPAD(void) +{ + + CPU_WORKCLOCK(19); + if (!CPU_STAT_SS32) { + if (CPU_STAT_PM) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_SP, 16); + } + REGPOP0_32_16(CPU_EDI); + REGPOP0_32_16(CPU_ESI); + REGPOP0_32_16(CPU_EBP); + CPU_SP += 4; + REGPOP0_32_16(CPU_EBX); + REGPOP0_32_16(CPU_EDX); + REGPOP0_32_16(CPU_ECX); + REGPOP0_32_16(CPU_EAX); + } else { + if (CPU_STAT_PM) { + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), CPU_ESP, 32); + } + REGPOP0_32(CPU_EDI); + REGPOP0_32(CPU_ESI); + REGPOP0_32(CPU_EBP); + CPU_ESP += 4; + REGPOP0_32(CPU_EBX); + REGPOP0_32(CPU_EDX); + REGPOP0_32(CPU_ECX); + REGPOP0_32(CPU_EAX); + } +} + +/* + * in port + */ +void +IN_ALDX(void) +{ + + CPU_WORKCLOCK(5); + CPU_AL = cpu_in(CPU_DX); +} + +void +IN_AXDX(void) +{ + + CPU_WORKCLOCK(5); + CPU_AX = cpu_in_w(CPU_DX); +} + +void +IN_EAXDX(void) +{ + + CPU_WORKCLOCK(5); + CPU_EAX = cpu_in_d(CPU_DX); +} + +void +IN_ALIb(void) +{ + BYTE port; + + CPU_WORKCLOCK(5); + GET_PCBYTE(port); + CPU_AL = cpu_in(port); +} + +void +IN_AXIb(void) +{ + BYTE port; + + CPU_WORKCLOCK(5); + GET_PCBYTE(port); + CPU_AX = cpu_in_w(port); +} + +void +IN_EAXIb(void) +{ + BYTE port; + + CPU_WORKCLOCK(5); + GET_PCBYTE(port); + CPU_EAX = cpu_in_d(port); +} + +/* + * out port + */ +void +OUT_DXAL(void) +{ + + CPU_WORKCLOCK(3); + cpu_out(CPU_DX, CPU_AL); +} + +void +OUT_DXAX(void) +{ + + CPU_WORKCLOCK(3); + cpu_out_w(CPU_DX, CPU_AX); +} + +void +OUT_DXEAX(void) +{ + + CPU_WORKCLOCK(3); + cpu_out_d(CPU_DX, CPU_EAX); +} + +void +OUT_IbAL(void) +{ + BYTE port; + + CPU_WORKCLOCK(3); + GET_PCBYTE(port); + cpu_out(port, CPU_AL); +} + +void +OUT_IbAX(void) +{ + BYTE port; + + CPU_WORKCLOCK(3); + GET_PCBYTE(port); + cpu_out_w(port, CPU_AX); +} + +void +OUT_IbEAX(void) +{ + BYTE port; + + CPU_WORKCLOCK(3); + GET_PCBYTE(port); + cpu_out_w(port, CPU_EAX); +} + +/* + * convert + */ +void +CWD(void) +{ + + CPU_WORKCLOCK(2); + if (CPU_AX & 0x8000) { + CPU_DX = 0xffff; + } else { + CPU_DX = 0; + } +} + +void +CDQ(void) +{ + + CPU_WORKCLOCK(2); + if (CPU_EAX & 0x80000000) { + CPU_EDX = 0xffffffff; + } else { + CPU_EDX = 0; + } +} + +void +CBW(void) +{ + WORD tmp; + + CPU_WORKCLOCK(2); + tmp = __CBW(CPU_AL); + CPU_AX = tmp; +} + +void +CWDE(void) +{ + DWORD tmp; + + CPU_WORKCLOCK(2); + tmp = __CWDE(CPU_AX); + CPU_EAX = tmp; +} + +/* + * MOVSx + */ +void +MOVSX_GwEb(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA8(op, src, out, 2, 5); + *out = __CBW(src); +} + +void +MOVSX_GdEb(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA8(op, src, out, 2, 5); + *out = __CBD(src); +} + +void +MOVSX_GdEw(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA16(op, src, out, 2, 5); + *out = __CWDE(src); +} + +/* + * MOVZx + */ +void +MOVZX_GwEb(void) +{ + WORD *out; + DWORD op, src; + + PREPART_REG16_EA8(op, src, out, 2, 5); + *out = (BYTE)src; +} + +void +MOVZX_GdEb(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA8(op, src, out, 2, 5); + *out = (BYTE)src; +} + +void +MOVZX_GdEw(void) +{ + DWORD *out; + DWORD op, src; + + PREPART_REG32_EA16(op, src, out, 2, 5); + *out = (WORD)src; +} diff --git a/i386c/ia32/instructions/data_trans.h b/i386c/ia32/instructions/data_trans.h new file mode 100644 index 00000000..6d0390ba --- /dev/null +++ b/i386c/ia32/instructions/data_trans.h @@ -0,0 +1,285 @@ +/* $Id: data_trans.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_DATA_TRANS_H__ +#define IA32_CPU_INSTRUCTION_DATA_TRANS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MOV + */ +void MOV_EbGb(void); +void MOV_EwGw(void); +void MOV_EdGd(void); +void MOV_GbEb(void); +void MOV_GwEw(void); +void MOV_GdEd(void); +void MOV_EwSw(void); +void MOV_SwEw(void); +void MOV_ALOb(void); +void MOV_AXOw(void); +void MOV_EAXOd(void); +void MOV_ObAL(void); +void MOV_OwAX(void); +void MOV_OdEAX(void); +void MOV_EbIb(void); +void MOV_EwIw(void); +void MOV_EdId(void); +void MOV_ALIb(void); +void MOV_CLIb(void); +void MOV_DLIb(void); +void MOV_BLIb(void); +void MOV_AHIb(void); +void MOV_CHIb(void); +void MOV_DHIb(void); +void MOV_BHIb(void); +void MOV_AXIw(void); +void MOV_CXIw(void); +void MOV_DXIw(void); +void MOV_BXIw(void); +void MOV_SPIw(void); +void MOV_BPIw(void); +void MOV_SIIw(void); +void MOV_DIIw(void); +void MOV_EAXId(void); +void MOV_ECXId(void); +void MOV_EDXId(void); +void MOV_EBXId(void); +void MOV_ESPId(void); +void MOV_EBPId(void); +void MOV_ESIId(void); +void MOV_EDIId(void); + +/* + * CMOVcc + */ +void CMOVO_GwEw(void); +void CMOVO_GdEd(void); +void CMOVNO_GwEw(void); +void CMOVNO_GdEd(void); +void CMOVC_GwEw(void); +void CMOVC_GdEd(void); +void CMOVNC_GwEw(void); +void CMOVNC_GdEd(void); +void CMOVZ_GwEw(void); +void CMOVZ_GdEd(void); +void CMOVNZ_GwEw(void); +void CMOVNZ_GdEd(void); +void CMOVA_GwEw(void); +void CMOVA_GdEd(void); +void CMOVNA_GwEw(void); +void CMOVNA_GdEd(void); +void CMOVS_GwEw(void); +void CMOVS_GdEd(void); +void CMOVNS_GwEw(void); +void CMOVNS_GdEd(void); +void CMOVP_GwEw(void); +void CMOVP_GdEd(void); +void CMOVNP_GwEw(void); +void CMOVNP_GdEd(void); +void CMOVL_GwEw(void); +void CMOVL_GdEd(void); +void CMOVNL_GwEw(void); +void CMOVNL_GdEd(void); +void CMOVLE_GwEw(void); +void CMOVLE_GdEd(void); +void CMOVNLE_GwEw(void); +void CMOVNLE_GdEd(void); + +/* + * XCHG + */ +void XCHG_EbGb(void); +void XCHG_EwGw(void); +void XCHG_EdGd(void); +void XCHG_CXAX(void); +void XCHG_DXAX(void); +void XCHG_BXAX(void); +void XCHG_SPAX(void); +void XCHG_BPAX(void); +void XCHG_SIAX(void); +void XCHG_DIAX(void); +void XCHG_ECXEAX(void); +void XCHG_EDXEAX(void); +void XCHG_EBXEAX(void); +void XCHG_ESPEAX(void); +void XCHG_EBPEAX(void); +void XCHG_ESIEAX(void); +void XCHG_EDIEAX(void); + +/* + * BSWAP + */ +void BSWAP_EAX(void); +void BSWAP_ECX(void); +void BSWAP_EDX(void); +void BSWAP_EBX(void); +void BSWAP_ESP(void); +void BSWAP_EBP(void); +void BSWAP_ESI(void); +void BSWAP_EDI(void); + +/* + * XADD + */ +void XADD_EbGb(void); +void XADD_EwGw(void); +void XADD_EdGd(void); + +/* + * CMPXCHG + */ +void CMPXCHG_EbGb(void); +void CMPXCHG_EwGw(void); +void CMPXCHG_EdGd(void); +void CMPXCHG8B(DWORD op); + +/* + * PUSH + */ +void PUSH_AX(void); +void PUSH_CX(void); +void PUSH_DX(void); +void PUSH_BX(void); +void PUSH_SP(void); +void PUSH_BP(void); +void PUSH_SI(void); +void PUSH_DI(void); +void PUSH_EAX(void); +void PUSH_ECX(void); +void PUSH_EDX(void); +void PUSH_EBX(void); +void PUSH_ESP(void); +void PUSH_EBP(void); +void PUSH_ESI(void); +void PUSH_EDI(void); +void PUSH_Ib(void); +void PUSH_Iw(void); +void PUSH_Id(void); +void PUSH16_ES(void); +void PUSH16_CS(void); +void PUSH16_SS(void); +void PUSH16_DS(void); +void PUSH16_FS(void); +void PUSH16_GS(void); +void PUSH32_ES(void); +void PUSH32_CS(void); +void PUSH32_SS(void); +void PUSH32_DS(void); +void PUSH32_FS(void); +void PUSH32_GS(void); + +void PUSH_Ew(DWORD); +void PUSH_Ed(DWORD); + +/* + * POP + */ +void POP_AX(void); +void POP_CX(void); +void POP_DX(void); +void POP_BX(void); +void POP_SP(void); +void POP_BP(void); +void POP_SI(void); +void POP_DI(void); +void POP_EAX(void); +void POP_ECX(void); +void POP_EDX(void); +void POP_EBX(void); +void POP_ESP(void); +void POP_EBP(void); +void POP_ESI(void); +void POP_EDI(void); +void POP_Ew(void); +void POP_Ed(void); +void POP16_ES(void); +void POP32_ES(void); +void POP16_SS(void); +void POP32_SS(void); +void POP16_DS(void); +void POP32_DS(void); +void POP16_FS(void); +void POP32_FS(void); +void POP16_GS(void); +void POP32_GS(void); + +void POP_Ew_G5(DWORD); +void POP_Ed_G5(DWORD); + +/* + * PUSHA/POPA + */ +void PUSHA(void); +void PUSHAD(void); +void POPA(void); +void POPAD(void); + +/* + * in/out + */ +void IN_ALDX(void); +void IN_AXDX(void); +void IN_EAXDX(void); +void IN_ALIb(void); +void IN_AXIb(void); +void IN_EAXIb(void); +void OUT_DXAL(void); +void OUT_DXAX(void); +void OUT_DXEAX(void); +void OUT_IbAL(void); +void OUT_IbAX(void); +void OUT_IbEAX(void); + +/* + * convert + */ +void CWD(void); +void CDQ(void); +void CBW(void); +void CWDE(void); + +/* + * MOVSx/MOVZx + */ +void MOVSX_GwEb(void); +void MOVSX_GdEb(void); +void MOVSX_GdEw(void); +void MOVZX_GwEb(void); +void MOVZX_GdEb(void); +void MOVZX_GdEw(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_DATA_TRANS_H__ */ diff --git a/i386c/ia32/instructions/dec_arith.c b/i386c/ia32/instructions/dec_arith.c new file mode 100644 index 00000000..05afb2f4 --- /dev/null +++ b/i386c/ia32/instructions/dec_arith.c @@ -0,0 +1,299 @@ +/* $Id: dec_arith.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "dec_arith.h" + + +/* + * decimal arithmetic + */ +void +DAA(void) +{ +#if defined(IA32_CPU_ENABLE_XC) + BYTE __s = CPU_AL; + BYTE __r = __s; + BYTE __R; + BYTE __f; + XC_STORE_FLAGL(); +#endif + + CPU_WORKCLOCK(3); + if ((CPU_FLAGL & A_FLAG) || (CPU_AL & 0x0f) > 9) { + CPU_FLAGL |= A_FLAG; + CPU_FLAGL |= (((WORD)CPU_AL + 6) >> 8) & 1; /* C_FLAG */ + CPU_AL += 6; + } + if ((CPU_FLAGL & C_FLAG) || (CPU_AL & 0xf0) > 0x90) { + CPU_FLAGL |= C_FLAG; + CPU_AL += 0x60; + } + CPU_FLAGL &= A_FLAG | C_FLAG; + CPU_FLAGL |= szpcflag[CPU_AL] & (S_FLAG | Z_FLAG); + +#if defined(IA32_CPU_ENABLE_XC) + __R = CPU_AL; + + __asm__ __volatile__( + "pushf\n\t" + "pushl %%eax\n\t" + "movb %3, %%ah\n\t" + "sahf\n\t" + "movb %2, %%al\n\t" + "daa\n\t" + "movb %%al, %0\n\t" + "lahf\n\t" + "movb %%ah, %1\n\t" + "popl %%eax\n\t" + "popf\n\t" + : "=m" (__r), "=m" (__f) + : "0" (__r), "m" (__xc_flagl) + : "eax"); + if ((__R != __r) || + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0)) { + ia32_warning("XC_DAA: __s = %02x", __s); + ia32_warning("XC_DAA: __R = %02x, __r = %02x", __R, __r); + ia32_warning("XC_DAA: CPU_FLAGL = %02x, __f = %02x, " + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); + ia32_warning("XC_DAA: __xc_flagl = %02x", __xc_flagl); + __ASSERT(__R == __r); + __ASSERT(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); + } +#endif +} + +void +DAS(void) +{ +#if defined(IA32_CPU_ENABLE_XC) + BYTE __s = CPU_AL; + BYTE __r = __s; + BYTE __R; + BYTE __f; + XC_STORE_FLAGL(); +#endif + + CPU_WORKCLOCK(3); + if ((CPU_FLAGL & A_FLAG) || (CPU_AL & 0x0f) > 9) { + CPU_FLAGL |= A_FLAG; + CPU_FLAGL |= (((WORD)CPU_AL - 6) >> 8) & 1; /* C_FLAG */ + CPU_AL -= 6; + } + if ((CPU_FLAGL & C_FLAG) || CPU_AL > 0x9f) { + CPU_FLAGL |= C_FLAG; + CPU_AL -= 0x60; + } + CPU_FLAGL &= A_FLAG | C_FLAG; + CPU_FLAGL |= szpcflag[CPU_AL] & (S_FLAG | Z_FLAG); + +#if defined(IA32_CPU_ENABLE_XC) + __R = CPU_AL; + + __asm__ __volatile__( + "pushf\n\t" + "pushl %%eax\n\t" + "movb %3, %%ah\n\t" + "sahf\n\t" + "movb %2, %%al\n\t" + "das\n\t" + "movb %%al, %0\n\t" + "lahf\n\t" + "movb %%ah, %1\n\t" + "popl %%eax\n\t" + "popf\n\t" + : "=m" (__r), "=m" (__f) + : "0" (__r), "m" (__xc_flagl) + : "eax"); + if ((__R != __r) || + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0)) { + ia32_warning("XC_DAS: __s = %02x", __s); + ia32_warning("XC_DAS: __R = %02x, __r = %02x", __R, __r); + ia32_warning("XC_DAS: CPU_FLAGL = %02x, __f = %02x, " + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); + ia32_warning("XC_DAS: __xc_flagl = %02x", __xc_flagl); + __ASSERT(__R == __r); + __ASSERT(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); + } +#endif +} + +void +AAA(void) +{ +#if defined(IA32_CPU_ENABLE_XC) + BYTE __s = CPU_AL; + BYTE __s1 = CPU_AH; + BYTE __r = __s; + BYTE __r1; + BYTE __R; + BYTE __R1; + BYTE __f; + XC_STORE_FLAGL(); +#endif + + CPU_WORKCLOCK(3); + if ((CPU_FLAGL & A_FLAG) || (CPU_AL & 0x0f) > 9) { + CPU_AL += 6; + CPU_AH++; + CPU_FLAGL |= (A_FLAG | C_FLAG); + } else { + CPU_FLAGL &= ~(A_FLAG | C_FLAG); + } + CPU_AL &= 0x0f; + +#if defined(IA32_CPU_ENABLE_XC) + __R = CPU_AL; + __R1 = CPU_AH; + + __asm__ __volatile__( + "pushf\n\t" + "pushl %%eax\n\t" + "movb %4, %%ah\n\t" + "sahf\n\t" + "movb %3, %%al\n\t" + "aaa\n\t" + "movb %%al, %0\n\t" + "movb %%ah, %1\n\t" + "lahf\n\t" + "movb %%ah, %2\n\t" + "popl %%eax\n\t" + "popf\n\t" + : "=m" (__r), "=m" (__r1), "=m" (__f) + : "0" (__r), "m" (__xc_flagl) + : "eax"); + if ((__R != __r) || + (__R1 != __r1) || + (((__f ^ CPU_FLAGL) & (A_FLAG|C_FLAG)) != 0)) { + ia32_warning("XC_AAA: __s = %02x, __s1 = %02x", __s, __s1); + ia32_warning("XC_AAA: __R = %02x, __R1 = %02x", __R, __R1); + ia32_warning("XC_AAA: __r = %02x, __r1 = %02x", __r, __r1); + ia32_warning("XC_AAA: CPU_FLAGL = %02x, __f = %02x, " + "mask = %02x", CPU_FLAGL, __f, (A_FLAG|C_FLAG)); + ia32_warning("XC_AAA: __xc_flagl = %02x", __xc_flagl); + __ASSERT(__R == __r); + __ASSERT(__R1 == __r1); + __ASSERT(((__f ^ CPU_FLAGL) & (A_FLAG|C_FLAG)) == 0); + } +#endif +} + +void +AAS(void) +{ +#if defined(IA32_CPU_ENABLE_XC) + BYTE __s = CPU_AL; + BYTE __s1 = CPU_AH; + BYTE __r = __s; + BYTE __r1; + BYTE __R; + BYTE __R1; + BYTE __f; + XC_STORE_FLAGL(); +#endif + + CPU_WORKCLOCK(3); + if ((CPU_FLAGL & A_FLAG) || (CPU_AL & 0x0f) > 9) { + CPU_AL -= 6; + CPU_AH--; + CPU_FLAGL |= (A_FLAG | C_FLAG); + } else { + CPU_FLAGL &= ~(A_FLAG | C_FLAG); + } + CPU_AL &= 0x0f; + +#if defined(IA32_CPU_ENABLE_XC) + __R = CPU_AL; + __R1 = CPU_AH; + + __asm__ __volatile__( + "pushf\n\t" + "pushl %%eax\n\t" + "movb %4, %%ah\n\t" + "sahf\n\t" + "movb %3, %%al\n\t" + "aas\n\t" + "movb %%al, %0\n\t" + "movb %%ah, %1\n\t" + "lahf\n\t" + "movb %%ah, %2\n\t" + "popl %%eax\n\t" + "popf\n\t" + : "=m" (__r), "=m" (__r1), "=m" (__f) + : "0" (__r), "m" (__xc_flagl) + : "eax"); + if ((__R != __r) || + (__R1 != __r1) || + (((__f ^ CPU_FLAGL) & (A_FLAG|C_FLAG)) != 0)) { + ia32_warning("XC_AAS: __s = %02x, __s1 = %02x", __s, __s1); + ia32_warning("XC_AAS: __R = %02x, __R1 = %02x", __R, __R1); + ia32_warning("XC_AAS: __r = %02x, __r1 = %02x", __r, __r1); + ia32_warning("XC_AAS: CPU_FLAGL = %02x, __f = %02x, " + "mask = %02x", CPU_FLAGL, __f, (A_FLAG|C_FLAG)); + ia32_warning("XC_AAS: __xc_flagl = %02x", __xc_flagl); + __ASSERT(__R == __r); + __ASSERT(__R1 == __r1); + __ASSERT(((__f ^ CPU_FLAGL) & (A_FLAG|C_FLAG)) == 0); + } +#endif +} + +void +AAM(void) +{ + BYTE base; + BYTE al; + + CPU_WORKCLOCK(16); + GET_PCBYTE(base); + if (base != 0) { + al = CPU_AL; + CPU_AH = al / base; + CPU_AL = al % base; + CPU_FLAGL = szpcflag[CPU_AL]; + return; + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void +AAD(void) +{ + DWORD base; + + CPU_WORKCLOCK(14); + GET_PCBYTE(base); + CPU_AL += (BYTE)(CPU_AH * base); + CPU_AH = 0; + CPU_FLAGL &= ~(S_FLAG | Z_FLAG | P_FLAG); + CPU_FLAGL |= szpcflag[CPU_AL]; +} diff --git a/i386c/ia32/instructions/dec_arith.h b/i386c/ia32/instructions/dec_arith.h new file mode 100644 index 00000000..1515194f --- /dev/null +++ b/i386c/ia32/instructions/dec_arith.h @@ -0,0 +1,51 @@ +/* $Id: dec_arith.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_DEC_ARITH_H__ +#define IA32_CPU_INSTRUCTION_DEC_ARITH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * decimal arithmetic + */ +void DAA(void); +void DAS(void); +void AAA(void); +void AAS(void); +void AAM(void); +void AAD(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_DEC_ARITH_H__ */ diff --git a/i386c/ia32/instructions/flag_ctrl.c b/i386c/ia32/instructions/flag_ctrl.c new file mode 100644 index 00000000..6de5974d --- /dev/null +++ b/i386c/ia32/instructions/flag_ctrl.c @@ -0,0 +1,212 @@ +/* $Id: flag_ctrl.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "flag_ctrl.h" + + +/* + * flag contol instructions + */ +void +STC(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAGL |= C_FLAG; +} + +void +CLC(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAGL &= ~C_FLAG; +} + +void +CMC(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAGL ^= C_FLAG; +} + +void +CLD(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAG &= ~D_FLAG; +} + +void +STD(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAG |= D_FLAG; +} + +void +LAHF(void) +{ + + CPU_WORKCLOCK(2); + CPU_AH = (CPU_FLAGL & SZAPC_FLAG) | 0x2; /* SZ0A0P1C */ +} + +void +SAHF(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAGL = (CPU_AH & SZAPC_FLAG) | 0x2; /* SZ0A0P1C */ +} + +/* + * PUSHF/POPF + */ +void +PUSHF_Fw(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_CPL == 3)) { + WORD flags = REAL_FLAGREG; + flags = (flags & ALL_FLAG) | 2; + PUSH0_16(flags); + return; + } + /* VM86 && IOPL != 3 */ + EXCEPTION(GP_EXCEPTION, 0); +} + +void +PUSHFD_Fd(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_CPL == 3)) { + DWORD flags = REAL_EFLAGREG; + flags = (flags & ALL_EFLAG) | 2; + PUSH0_32(flags); + return; + } + /* VM86 && IOPL != 3 */ + EXCEPTION(GP_EXCEPTION, 0); +} + +void +POPF_Fw(void) +{ + WORD flags, mask = 0; + + CPU_WORKCLOCK(3); + if (!CPU_STAT_PM) { + /* Real Mode */ + POP0_16(flags); + mask = I_FLAG|IOPL_FLAG; + } else if (!CPU_STAT_VM86) { + /* Protected Mode */ + POP0_16(flags); + if (CPU_STAT_CPL == 0) { + mask = I_FLAG|IOPL_FLAG; + } else if (CPU_STAT_CPL <= CPU_STAT_IOPL) { + mask = I_FLAG; + } + } else if (CPU_STAT_IOPL == CPU_IOPL3) { + /* Virtual-8086 Mode, IOPL == 3 */ + POP0_16(flags); + mask = I_FLAG; + } else { + EXCEPTION(GP_EXCEPTION, 0); + flags = 0; + /* compiler happy */ + } + set_flags(flags, mask); + IRQCHECKTERM(); +} + +void +POPFD_Fd(void) +{ + DWORD flags, mask = 0; + + CPU_WORKCLOCK(3); + if (!CPU_STAT_PM) { + /* Real Mode */ + POP0_32(flags); + flags &= ~(VIF_FLAG|VIP_FLAG); + mask = I_FLAG|IOPL_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; + } if (!CPU_STAT_VM86) { + /* Protected Mode */ + POP0_32(flags); + if (CPU_STAT_CPL == 0) { + flags &= ~(VIP_FLAG|VIF_FLAG); + mask = I_FLAG|IOPL_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; + } else if (CPU_STAT_CPL <= CPU_STAT_IOPL) { + flags &= ~(VIP_FLAG|VIF_FLAG); + mask = I_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; + } + } else if (CPU_STAT_IOPL == CPU_IOPL3) { + /* Virtual-8086 Mode, IOPL == 3 */ + POP0_32(flags); + mask = I_FLAG; + } else { + EXCEPTION(GP_EXCEPTION, 0); + flags = 0; + /* compiler happy */ + } + set_eflags(flags, mask); + IRQCHECKTERM(); +} + +void +STI(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAG |= I_FLAG; + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); + exec_1step(); + IRQCHECKTERM(); +} + +void +CLI(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAG &= ~I_FLAG; + CPU_TRAP = 0; +} diff --git a/i386c/ia32/instructions/flag_ctrl.h b/i386c/ia32/instructions/flag_ctrl.h new file mode 100644 index 00000000..b04e8f69 --- /dev/null +++ b/i386c/ia32/instructions/flag_ctrl.h @@ -0,0 +1,55 @@ +/* $Id: flag_ctrl.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_FLAG_CTRL_H__ +#define IA32_CPU_INSTRUCTION_FLAG_CTRL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void STC(void); +void CLC(void); +void CMC(void); +void CLD(void); +void STD(void); +void LAHF(void); +void SAHF(void); +void PUSHF_Fw(void); +void PUSHFD_Fd(void); +void POPF_Fw(void); +void POPFD_Fd(void); +void STI(void); +void CLI(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_FLAG_CTRL_H__ */ diff --git a/i386c/ia32/instructions/fpu/fp.h b/i386c/ia32/instructions/fpu/fp.h new file mode 100644 index 00000000..c0710f9a --- /dev/null +++ b/i386c/ia32/instructions/fpu/fp.h @@ -0,0 +1,59 @@ +/* $Id: fp.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_FPU_FP_H__ +#define IA32_CPU_INSTRUCTION_FPU_FP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void FWAIT(void); +void ESC0(void); +void ESC1(void); +void ESC2(void); +void ESC3(void); +void ESC4(void); +void ESC5(void); +void ESC6(void); +void ESC7(void); + +#define ESC1 ESC0 +#define ESC2 ESC0 +#define ESC3 ESC0 +#define ESC4 ESC0 +#define ESC5 ESC0 +#define ESC6 ESC0 +#define ESC7 ESC0 + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_FPU_FP_H__ */ diff --git a/i386c/ia32/instructions/fpu/fpdummy.c b/i386c/ia32/instructions/fpu/fpdummy.c new file mode 100644 index 00000000..44237ed5 --- /dev/null +++ b/i386c/ia32/instructions/fpu/fpdummy.c @@ -0,0 +1,23 @@ +/* $Id: fpdummy.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + + +void +FWAIT(void) +{ +} + +void +ESC0(void) +{ + DWORD op, madr; + + GET_PCBYTE(op); + if (op >= 0xc0) { + } else { + madr = calc_lea(op); + } +} diff --git a/i386c/ia32/instructions/logic_arith.c b/i386c/ia32/instructions/logic_arith.c new file mode 100644 index 00000000..9ed90cc1 --- /dev/null +++ b/i386c/ia32/instructions/logic_arith.c @@ -0,0 +1,698 @@ +/* $Id: logic_arith.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "logic_arith.h" + + +/* + * AND + */ +void +AND_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + ANDBYTE(dst, src); + *out = (BYTE)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ANDBYTE(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); + } +} + +void +AND_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + ANDWORD(dst, src); + *out = (WORD)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ANDWORD(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); + } +} + +void +AND_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + ANDDWORD(dst, src); + *out = dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ANDDWORD(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +AND_GbEb(void) +{ + BYTE *out; + DWORD op, src, dst; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + ANDBYTE(dst, src); + *out = (BYTE)dst; +} + +void +AND_GwEw(void) +{ + WORD *out; + DWORD op, src, dst; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + ANDWORD(dst, src); + *out = (WORD)dst; +} + +void +AND_GdEd(void) +{ + DWORD *out; + DWORD op, src, dst; + + PREPART_REG32_EA(op, src, out, 2, 7); + dst = *out; + ANDDWORD(dst, src); + *out = dst; +} + +void +AND_ALIb(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCBYTE(src); + dst = CPU_AL; + ANDBYTE(dst, src); + CPU_AL = (BYTE)dst; +} + +void +AND_AXIw(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCWORD(src); + dst = CPU_AX; + ANDWORD(dst, src); + CPU_AX = (WORD)dst; +} + +void +AND_EAXId(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCDWORD(src); + dst = CPU_EAX; + ANDDWORD(dst, src); + CPU_EAX = dst; +} + +void +AND_EbIb(BYTE *p) +{ + DWORD src, dst; + + GET_PCBYTE(src); + dst = *p; + ANDBYTE(dst, src); + *p = (BYTE)dst; +} + +void +AND_EbIb_ext(DWORD madr) +{ + DWORD src, dst; + + GET_PCBYTE(src); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ANDBYTE(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); +} + +void +AND_EwIx(WORD *p, DWORD src) +{ + DWORD dst; + + dst = *p; + ANDWORD(dst, src); + *p = (WORD)dst; +} + +void +AND_EwIx_ext(DWORD madr, DWORD src) +{ + DWORD dst; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ANDWORD(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); +} + +void +AND_EdIx(DWORD *p, DWORD src) +{ + DWORD dst; + + dst = *p; + ANDDWORD(dst, src); + *p = dst; +} + +void +AND_EdIx_ext(DWORD madr, DWORD src) +{ + DWORD dst; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ANDDWORD(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * OR + */ +void +OR_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + ORBYTE(dst, src); + *out = (BYTE)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ORBYTE(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); + } +} + +void +OR_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + ORWORD(dst, src); + *out = (WORD)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ORWORD(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); + } +} + +void +OR_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + ORDWORD(dst, src); + *out = dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ORDWORD(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +OR_GbEb(void) +{ + BYTE *out; + DWORD op, src, dst; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + ORBYTE(dst, src); + *out = (BYTE)dst; +} + +void +OR_GwEw(void) +{ + WORD *out; + DWORD op, src, dst; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + ORWORD(dst, src); + *out = (WORD)dst; +} + +void +OR_GdEd(void) +{ + DWORD *out; + DWORD op, src, dst; + + PREPART_REG32_EA(op, src, out, 2, 7); + dst = *out; + ORDWORD(dst, src); + *out = dst; +} + +void +OR_ALIb(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCBYTE(src); + dst = CPU_AL; + ORBYTE(dst, src); + CPU_AL = (BYTE)dst; +} + +void +OR_AXIw(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCWORD(src); + dst = CPU_AX; + ORWORD(dst, src); + CPU_AX = (WORD)dst; +} + +void +OR_EAXId(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCDWORD(src); + dst = CPU_EAX; + ORDWORD(dst, src); + CPU_EAX = dst; +} + +void +OR_EbIb(BYTE *p) +{ + DWORD src, dst; + + GET_PCBYTE(src); + dst = *p; + ORBYTE(dst, src); + *p = (BYTE)dst; +} + +void +OR_EbIb_ext(DWORD madr) +{ + DWORD src, dst; + + GET_PCBYTE(src); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + ORBYTE(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); +} + +void +OR_EwIx(WORD *p, DWORD src) +{ + DWORD dst; + + dst = *p; + ORWORD(dst, src); + *p = (WORD)dst; +} + +void +OR_EwIx_ext(DWORD madr, DWORD src) +{ + DWORD dst; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + ORWORD(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); +} + +void +OR_EdIx(DWORD *p, DWORD src) +{ + DWORD dst; + + dst = *p; + ORDWORD(dst, src); + *p = dst; +} + +void +OR_EdIx_ext(DWORD madr, DWORD src) +{ + DWORD dst; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + ORDWORD(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * XOR + */ +void +XOR_EbGb(void) +{ + BYTE *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + BYTE_XOR(dst, src); + *out = (BYTE)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_XOR(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); + } +} + +void +XOR_EwGw(void) +{ + WORD *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + WORD_XOR(dst, src); + *out = (WORD)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_XOR(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); + } +} + +void +XOR_EdGd(void) +{ + DWORD *out; + DWORD op, src, dst, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + DWORD_XOR(dst, src); + *out = dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_XOR(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +XOR_GbEb(void) +{ + BYTE *out; + DWORD op, src, dst; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + BYTE_XOR(dst, src); + *out = (BYTE)dst; +} + +void +XOR_GwEw(void) +{ + WORD *out; + DWORD op, src, dst; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + WORD_XOR(dst, src); + *out = (WORD)dst; +} + +void +XOR_GdEd(void) +{ + DWORD *out; + DWORD op, src, dst; + + PREPART_REG32_EA(op, src, out, 2, 7); + dst = *out; + DWORD_XOR(dst, src); + *out = dst; +} + +void +XOR_ALIb(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCBYTE(src); + dst = CPU_AL; + BYTE_XOR(dst, src); + CPU_AL = (BYTE)dst; +} + +void +XOR_AXIw(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCWORD(src); + dst = CPU_AX; + WORD_XOR(dst, src); + CPU_AX = (WORD)dst; +} + +void +XOR_EAXId(void) +{ + DWORD src, dst; + + CPU_WORKCLOCK(3); + GET_PCDWORD(src); + dst = CPU_EAX; + DWORD_XOR(dst, src); + CPU_EAX = dst; +} + +void +XOR_EbIb(BYTE *p) +{ + DWORD src, dst; + + GET_PCBYTE(src); + dst = *p; + BYTE_XOR(dst, src); + *p = (BYTE)dst; +} + +void +XOR_EbIb_ext(DWORD madr) +{ + DWORD src, dst; + + GET_PCBYTE(src); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_XOR(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); +} + +void +XOR_EwIx(WORD *p, DWORD src) +{ + DWORD dst; + + dst = *p; + WORD_XOR(dst, src); + *p = (WORD)dst; +} + +void +XOR_EwIx_ext(DWORD madr, DWORD src) +{ + DWORD dst; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_XOR(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); +} + +void +XOR_EdIx(DWORD *p, DWORD src) +{ + DWORD dst; + + dst = *p; + DWORD_XOR(dst, src); + *p = dst; +} + +void +XOR_EdIx_ext(DWORD madr, DWORD src) +{ + DWORD dst; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_XOR(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * NOT + */ +void +NOT_Eb(DWORD op) +{ + DWORD dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) ^= 0xff; + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + dst = dst ^ 0xff; + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); + } +} + +void +NOT_Ew(DWORD op) +{ + DWORD dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg16_b20[op]) ^= 0xffff; + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + dst = dst ^ 0xffff; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); + } +} + +void +NOT_Ed(DWORD op) +{ + DWORD dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg32_b20[op]) ^= 0xffffffff; + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + dst = dst ^ 0xffffffff; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} diff --git a/i386c/ia32/instructions/logic_arith.h b/i386c/ia32/instructions/logic_arith.h new file mode 100644 index 00000000..a9f9f6dd --- /dev/null +++ b/i386c/ia32/instructions/logic_arith.h @@ -0,0 +1,105 @@ +/* $Id: logic_arith.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_LOGIC_ARITH_H__ +#define IA32_CPU_INSTRUCTION_LOGIC_ARITH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * AND + */ +void AND_EbGb(void); +void AND_EwGw(void); +void AND_EdGd(void); +void AND_GbEb(void); +void AND_GwEw(void); +void AND_GdEd(void); +void AND_ALIb(void); +void AND_AXIw(void); +void AND_EAXId(void); +void AND_EbIb(BYTE *); +void AND_EwIx(WORD *, DWORD); +void AND_EdIx(DWORD *, DWORD); +void AND_EbIb_ext(DWORD); +void AND_EwIx_ext(DWORD, DWORD); +void AND_EdIx_ext(DWORD, DWORD); + +/* + * OR + */ +void OR_EbGb(void); +void OR_EwGw(void); +void OR_EdGd(void); +void OR_GbEb(void); +void OR_GwEw(void); +void OR_GdEd(void); +void OR_ALIb(void); +void OR_AXIw(void); +void OR_EAXId(void); +void OR_EbIb(BYTE *); +void OR_EwIx(WORD *, DWORD); +void OR_EdIx(DWORD *, DWORD); +void OR_EbIb_ext(DWORD); +void OR_EwIx_ext(DWORD, DWORD); +void OR_EdIx_ext(DWORD, DWORD); + +/* + * XOR + */ +void XOR_EbGb(void); +void XOR_EwGw(void); +void XOR_EdGd(void); +void XOR_GbEb(void); +void XOR_GwEw(void); +void XOR_GdEd(void); +void XOR_ALIb(void); +void XOR_AXIw(void); +void XOR_EAXId(void); +void XOR_EbIb(BYTE *); +void XOR_EwIx(WORD *, DWORD); +void XOR_EdIx(DWORD *, DWORD); +void XOR_EbIb_ext(DWORD); +void XOR_EwIx_ext(DWORD, DWORD); +void XOR_EdIx_ext(DWORD, DWORD); + +/* + * NOT + */ +void NOT_Eb(DWORD op); +void NOT_Ew(DWORD op); +void NOT_Ed(DWORD op); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_LOGIC_ARITH_H__ */ diff --git a/i386c/ia32/instructions/misc_inst.c b/i386c/ia32/instructions/misc_inst.c new file mode 100644 index 00000000..7b37bde2 --- /dev/null +++ b/i386c/ia32/instructions/misc_inst.c @@ -0,0 +1,230 @@ +/* $Id: misc_inst.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "misc_inst.h" +#include "inst_table.h" + + +void +LEA_GwM(void) +{ + WORD *out; + DWORD op, dst; + + GET_PCBYTE(op); + if (op < 0xc0) { + CPU_WORKCLOCK(3); + out = reg16_b53[op]; + dst = calc_lea(op); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LEA_GdM(void) +{ + DWORD *out; + DWORD op, dst; + + GET_PCBYTE(op); + if (op < 0xc0) { + CPU_WORKCLOCK(3); + out = reg32_b53[op]; + dst = calc_lea(op); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +_NOP(void) +{ + + ia32_bioscall(); +} + +void +UD2(void) +{ + + EXCEPTION(UD_EXCEPTION, 0); +} + +void +XLAT(void) +{ + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_BX + CPU_AL); + } else { + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_EBX + CPU_AL); + } +} + +void +_CPUID(void) +{ + + switch (CPU_EAX) { + case 0: + CPU_EAX = 1; + CPU_EBX = CPU_VENDOR_1; + CPU_EDX = CPU_VENDOR_2; + CPU_ECX = CPU_VENDOR_3; + break; + + case 1: + CPU_EAX = (CPU_FAMILY << 8) | (CPU_MODEL << 4) | CPU_STEPPING; + CPU_EBX = 0; + CPU_ECX = 0; + CPU_EDX = CPU_FEATURES; + break; + + case 2: + CPU_EAX = 0; + CPU_EBX = 0; + CPU_ECX = 0; + CPU_EDX = 0; + break; + } +} + +/* undoc 8086 */ +void +SALC(void) +{ + + CPU_WORKCLOCK(2); + CPU_AL = (CPU_FLAGL & C_FLAG) - 1; +} + +/* undoc 286 */ +void +LOADALL286(void) +{ + + ia32_panic("LOADALL286: not implemented yet."); +} + +/* undoc 386 */ +void +LOADALL(void) +{ + + ia32_panic("LOADALL: not implemented yet."); +} + +void +OpSize(void) +{ + + CPU_INST_OP32 = !cpu_inst_default.op_32; +} + +void +AddrSize(void) +{ + + CPU_INST_AS32 = !cpu_inst_default.as_32; +} + +void +_2byte_ESC16(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_2byte[0][op])(); +} + +void +_2byte_ESC32(void) +{ + DWORD op; + + GET_PCBYTE(op); + (*insttable_2byte[1][op])(); +} + +void +Prefix_ES(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_ES_INDEX; +} + +void +Prefix_CS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_CS_INDEX; +} + +void +Prefix_SS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_SS_INDEX; +} + +void +Prefix_DS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_DS_INDEX; +} + +void +Prefix_FS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_FS_INDEX; +} + +void +Prefix_GS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_GS_INDEX; +} diff --git a/i386c/ia32/instructions/misc_inst.h b/i386c/ia32/instructions/misc_inst.h new file mode 100644 index 00000000..4466584a --- /dev/null +++ b/i386c/ia32/instructions/misc_inst.h @@ -0,0 +1,63 @@ +/* $Id: misc_inst.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_MISC_H__ +#define IA32_CPU_INSTRUCTION_MISC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void LEA_GwM(void); +void LEA_GdM(void); +void _NOP(void); +void UD2(void); +void XLAT(void); +void _CPUID(void); + +void SALC(void); /* undoc 8086 */ +void LOADALL286(void); /* undoc 286 */ +void LOADALL(void); /* undoc 386 */ + +void OpSize(void); +void AddrSize(void); +void _2byte_ESC16(void); +void _2byte_ESC32(void); +void Prefix_ES(void); +void Prefix_CS(void); +void Prefix_SS(void); +void Prefix_DS(void); +void Prefix_FS(void); +void Prefix_GS(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_MISC_H__ */ diff --git a/i386c/ia32/instructions/seg_reg.c b/i386c/ia32/instructions/seg_reg.c new file mode 100644 index 00000000..da533db7 --- /dev/null +++ b/i386c/ia32/instructions/seg_reg.c @@ -0,0 +1,235 @@ +/* $Id: seg_reg.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "seg_reg.h" + + +void +LES_GwMp(void) +{ + WORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + CPU_SET_SEGREG(CPU_ES_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LES_GdMp(void) +{ + DWORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + CPU_SET_SEGREG(CPU_ES_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LSS_GwMp(void) +{ + WORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + CPU_SET_SEGREG(CPU_SS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LSS_GdMp(void) +{ + DWORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + CPU_SET_SEGREG(CPU_SS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LDS_GwMp(void) +{ + WORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + CPU_SET_SEGREG(CPU_DS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LDS_GdMp(void) +{ + DWORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + CPU_SET_SEGREG(CPU_DS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LFS_GwMp(void) +{ + WORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + CPU_SET_SEGREG(CPU_FS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LFS_GdMp(void) +{ + DWORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + CPU_SET_SEGREG(CPU_FS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LGS_GwMp(void) +{ + WORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + CPU_SET_SEGREG(CPU_GS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LGS_GdMp(void) +{ + DWORD *out; + DWORD op, dst, madr; + WORD sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = get_ea(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + CPU_SET_SEGREG(CPU_GS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} diff --git a/i386c/ia32/instructions/seg_reg.h b/i386c/ia32/instructions/seg_reg.h new file mode 100644 index 00000000..0bc4f106 --- /dev/null +++ b/i386c/ia32/instructions/seg_reg.h @@ -0,0 +1,52 @@ +/* $Id: seg_reg.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SEG_REG_H__ +#define IA32_CPU_INSTRUCTION_SEG_REG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void LES_GwMp(void); +void LES_GdMp(void); +void LSS_GwMp(void); +void LSS_GdMp(void); +void LDS_GwMp(void); +void LDS_GdMp(void); +void LFS_GwMp(void); +void LFS_GdMp(void); +void LGS_GwMp(void); +void LGS_GdMp(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_SEG_REG_H__ */ diff --git a/i386c/ia32/instructions/shift_rotate.c b/i386c/ia32/instructions/shift_rotate.c new file mode 100644 index 00000000..6c30e09f --- /dev/null +++ b/i386c/ia32/instructions/shift_rotate.c @@ -0,0 +1,1092 @@ +/* $Id: shift_rotate.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "shift_rotate.h" +#include "shift_rotate.mcr" + + +/* + * shift + */ +/* + * SAR + */ +void +SAR_Eb(BYTE *out) +{ + DWORD src, dst; + + src = *out; + BYTE_SAR1(dst, src); + *out = (BYTE)dst; +} + +void +SAR_Eb_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SAR1(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SAR_Ew(WORD *out) +{ + DWORD src, dst; + + src = *out; + WORD_SAR1(dst, src); + *out = (WORD)dst; +} + +void +SAR_Ew_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SAR1(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SAR_Ed(DWORD *out) +{ + DWORD src, dst; + + src = *out; + DWORD_SAR1(dst, src); + *out = dst; +} + +void +SAR_Ed_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SAR1(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* ExCL, ExIb */ +void +SAR_EbCL(BYTE *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + BYTE_SARCL(dst, src, cl); + *out = dst; +} + +void +SAR_EbCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SARCL(dst, src, cl); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SAR_EwCL(WORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + WORD_SARCL(dst, src, cl); + *out = dst; +} + +void +SAR_EwCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SARCL(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SAR_EdCL(DWORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + DWORD_SARCL(dst, src, cl); + *out = dst; +} + +void +SAR_EdCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SARCL(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * SHR + */ +void +SHR_Eb(BYTE *out) +{ + DWORD src, dst; + + src = *out; + BYTE_SHR1(dst, src); + *out = (BYTE)dst; +} + +void +SHR_Eb_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SHR1(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SHR_Ew(WORD *out) +{ + DWORD src, dst; + + src = *out; + WORD_SHR1(dst, src); + *out = (WORD)dst; +} + +void +SHR_Ew_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SHR1(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SHR_Ed(DWORD *out) +{ + DWORD src, dst; + + src = *out; + DWORD_SHR1(dst, src); + *out = dst; +} + +void +SHR_Ed_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SHR1(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* ExCL, ExIb */ +void +SHR_EbCL(BYTE *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + BYTE_SHRCL(dst, src, cl); + *out = dst; +} + +void +SHR_EbCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SHRCL(dst, src, cl); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SHR_EwCL(WORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + WORD_SHRCL(dst, src, cl); + *out = dst; +} + +void +SHR_EwCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SHRCL(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SHR_EdCL(DWORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + DWORD_SHRCL(dst, src, cl); + *out = dst; +} + +void +SHR_EdCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SHRCL(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * SHL/SAL + */ +void +SHL_Eb(BYTE *out) +{ + DWORD src, dst; + + src = *out; + BYTE_SHL1(dst, src); + *out = (BYTE)dst; +} + +void +SHL_Eb_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SHL1(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SHL_Ew(WORD *out) +{ + DWORD src, dst; + + src = *out; + WORD_SHL1(dst, src); + *out = (WORD)dst; +} + +void +SHL_Ew_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SHL1(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SHL_Ed(DWORD *out) +{ + DWORD src, dst; + + src = *out; + DWORD_SHL1(dst, src); + *out = dst; +} + +void +SHL_Ed_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SHL1(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* ExCL, ExIb */ +void +SHL_EbCL(BYTE *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + BYTE_SHLCL(dst, src, cl); + *out = dst; +} + +void +SHL_EbCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SHLCL(dst, src, cl); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SHL_EwCL(WORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + WORD_SHLCL(dst, src, cl); + *out = dst; +} + +void +SHL_EwCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SHLCL(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +SHL_EdCL(DWORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + DWORD_SHLCL(dst, src, cl); + *out = dst; +} + +void +SHL_EdCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SHLCL(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * SHRD + */ +void +SHRD_EwGwIb(void) +{ + WORD *out; + DWORD op, src, dst, madr; + BYTE cl; + + PREPART_EA_REG16(op, src); + GET_PCBYTE(cl); + if (op >= 0xc0) { + out = reg16_b20[op]; + dst = *out; + WORD_SHRD(dst, src, cl); + *out = dst; + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SHRD(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +SHRD_EdGdIb(void) +{ + DWORD *out; + DWORD op, src, dst, madr; + BYTE cl; + + PREPART_EA_REG32(op, src); + GET_PCBYTE(cl); + if (op >= 0xc0) { + out = reg32_b20[op]; + dst = *out; + DWORD_SHRD(dst, src, cl); + *out = dst; + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SHRD(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +SHRD_EwGwCL(void) +{ + WORD *out; + DWORD op, src, dst, madr; + BYTE cl; + + PREPART_EA_REG16(op, src); + cl = CPU_CL; + if (op >= 0xc0) { + out = reg16_b20[op]; + dst = *out; + WORD_SHRD(dst, src, cl); + *out = dst; + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SHRD(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +SHRD_EdGdCL(void) +{ + DWORD *out; + DWORD op, src, dst, madr; + BYTE cl; + + PREPART_EA_REG32(op, src); + cl = CPU_CL; + if (op >= 0xc0) { + out = reg32_b20[op]; + dst = *out; + DWORD_SHRD(dst, src, cl); + *out = dst; + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SHRD(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +/* + * SHLD + */ +void +SHLD_EwGwIb(void) +{ + WORD *out; + DWORD op, src, dst, madr; + BYTE cl; + + PREPART_EA_REG16(op, src); + GET_PCBYTE(cl); + if (op >= 0xc0) { + out = reg16_b20[op]; + dst = *out; + WORD_SHLD(dst, src, cl); + *out = dst; + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SHLD(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +SHLD_EdGdIb(void) +{ + DWORD *out; + DWORD op, src, dst, madr; + BYTE cl; + + PREPART_EA_REG32(op, src); + GET_PCBYTE(cl); + if (op >= 0xc0) { + out = reg32_b20[op]; + dst = *out; + DWORD_SHLD(dst, src, cl); + *out = dst; + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SHLD(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +SHLD_EwGwCL(void) +{ + WORD *out; + DWORD op, src, dst, madr; + BYTE cl; + + PREPART_EA_REG16(op, src); + cl = CPU_CL; + if (op >= 0xc0) { + out = reg16_b20[op]; + dst = *out; + WORD_SHLD(dst, src, cl); + *out = dst; + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SHLD(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +void +SHLD_EdGdCL(void) +{ + DWORD *out; + DWORD op, src, dst, madr; + BYTE cl; + + PREPART_EA_REG32(op, src); + cl = CPU_CL; + if (op >= 0xc0) { + out = reg32_b20[op]; + dst = *out; + DWORD_SHLD(dst, src, cl); + *out = dst; + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SHLD(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + } +} + +/* + * rotate + */ +/* + * ROR + */ +void +ROR_Eb(BYTE *out) +{ + DWORD src, dst; + + src = *out; + BYTE_ROR1(dst, src); + *out = (BYTE)dst; +} + +void +ROR_Eb_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_ROR1(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +ROR_Ew(WORD *out) +{ + DWORD src, dst; + + src = *out; + WORD_ROR1(dst, src); + *out = (WORD)dst; +} + +void +ROR_Ew_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_ROR1(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +ROR_Ed(DWORD *out) +{ + DWORD src, dst; + + src = *out; + DWORD_ROR1(dst, src); + *out = dst; +} + +void +ROR_Ed_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_ROR1(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* ExCL, ExIb */ +void +ROR_EbCL(BYTE *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + BYTE_RORCL(dst, src, cl); + *out = dst; +} + +void +ROR_EbCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_RORCL(dst, src, cl); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +ROR_EwCL(WORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + WORD_RORCL(dst, src, cl); + *out = dst; +} + +void +ROR_EwCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_RORCL(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +ROR_EdCL(DWORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + DWORD_RORCL(dst, src, cl); + *out = dst; +} + +void +ROR_EdCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_RORCL(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * ROL + */ +void +ROL_Eb(BYTE *out) +{ + DWORD src, dst; + + src = *out; + BYTE_ROL1(dst, src); + *out = (BYTE)dst; +} + +void +ROL_Eb_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_ROL1(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +ROL_Ew(WORD *out) +{ + DWORD src, dst; + + src = *out; + WORD_ROL1(dst, src); + *out = (WORD)dst; +} + +void +ROL_Ew_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_ROL1(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +ROL_Ed(DWORD *out) +{ + DWORD src, dst; + + src = *out; + DWORD_ROL1(dst, src); + *out = dst; +} + +void +ROL_Ed_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_ROL1(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* ExCL, ExIb */ +void +ROL_EbCL(BYTE *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + BYTE_ROLCL(dst, src, cl); + *out = dst; +} + +void +ROL_EbCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_ROLCL(dst, src, cl); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +ROL_EwCL(WORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + WORD_ROLCL(dst, src, cl); + *out = dst; +} + +void +ROL_EwCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_ROLCL(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +ROL_EdCL(DWORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + DWORD_ROLCL(dst, src, cl); + *out = dst; +} + +void +ROL_EdCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_ROLCL(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * RCR + */ +void +RCR_Eb(BYTE *out) +{ + DWORD src, dst; + + src = *out; + BYTE_RCR1(dst, src); + *out = (BYTE)dst; +} + +void +RCR_Eb_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_RCR1(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +RCR_Ew(WORD *out) +{ + DWORD src, dst; + + src = *out; + WORD_RCR1(dst, src); + *out = (WORD)dst; +} + +void +RCR_Ew_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_RCR1(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +RCR_Ed(DWORD *out) +{ + DWORD src, dst; + + src = *out; + DWORD_RCR1(dst, src); + *out = dst; +} + +void +RCR_Ed_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_RCR1(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* ExCL, ExIb */ +void +RCR_EbCL(BYTE *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + BYTE_RCRCL(dst, src, cl); + *out = dst; +} + +void +RCR_EbCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_RCRCL(dst, src, cl); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +RCR_EwCL(WORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + WORD_RCRCL(dst, src, cl); + *out = dst; +} + +void +RCR_EwCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_RCRCL(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +RCR_EdCL(DWORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + DWORD_RCRCL(dst, src, cl); + *out = dst; +} + +void +RCR_EdCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_RCRCL(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* + * RCL + */ +void +RCL_Eb(BYTE *out) +{ + DWORD src, dst; + + src = *out; + BYTE_RCL1(dst, src); + *out = (BYTE)dst; +} + +void +RCL_Eb_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_RCL1(dst, src); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +RCL_Ew(WORD *out) +{ + DWORD src, dst; + + src = *out; + WORD_RCL1(dst, src); + *out = (WORD)dst; +} + +void +RCL_Ew_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_RCL1(dst, src); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +RCL_Ed(DWORD *out) +{ + DWORD src, dst; + + src = *out; + DWORD_RCL1(dst, src); + *out = dst; +} + +void +RCL_Ed_ext(DWORD madr) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_RCL1(dst, src); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} + +/* ExCL, ExIb */ +void +RCL_EbCL(BYTE *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + BYTE_RCLCL(dst, src, cl); + *out = dst; +} + +void +RCL_EbCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_RCLCL(dst, src, cl); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +RCL_EwCL(WORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + WORD_RCLCL(dst, src, cl); + *out = dst; +} + +void +RCL_EwCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_RCLCL(dst, src, cl); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); +} + +void +RCL_EdCL(DWORD *out, BYTE cl) +{ + DWORD src, dst; + + src = *out; + DWORD_RCLCL(dst, src, cl); + *out = dst; +} + +void +RCL_EdCL_ext(DWORD madr, BYTE cl) +{ + DWORD src, dst; + + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_RCLCL(dst, src, cl); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); +} diff --git a/i386c/ia32/instructions/shift_rotate.h b/i386c/ia32/instructions/shift_rotate.h new file mode 100644 index 00000000..7878c82a --- /dev/null +++ b/i386c/ia32/instructions/shift_rotate.h @@ -0,0 +1,169 @@ +/* $Id: shift_rotate.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SHIFT_ROTATE_H__ +#define IA32_CPU_INSTRUCTION_SHIFT_ROTATE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * SAR + */ +void SAR_Eb(BYTE *); +void SAR_Ew(WORD *); +void SAR_Ed(DWORD *); +void SAR_Eb_ext(DWORD); +void SAR_Ew_ext(DWORD); +void SAR_Ed_ext(DWORD); +void SAR_EbCL(BYTE *, BYTE); +void SAR_EbCL_ext(DWORD, BYTE); +void SAR_EwCL(WORD *, BYTE); +void SAR_EwCL_ext(DWORD, BYTE); +void SAR_EdCL(DWORD *, BYTE); +void SAR_EdCL_ext(DWORD, BYTE); + +/* + * SHR + */ +void SHR_Eb(BYTE *); +void SHR_Ew(WORD *); +void SHR_Ed(DWORD *); +void SHR_Eb_ext(DWORD); +void SHR_Ew_ext(DWORD); +void SHR_Ed_ext(DWORD); +void SHR_EbCL(BYTE *, BYTE); +void SHR_EbCL_ext(DWORD, BYTE); +void SHR_EwCL(WORD *, BYTE); +void SHR_EwCL_ext(DWORD, BYTE); +void SHR_EdCL(DWORD *, BYTE); +void SHR_EdCL_ext(DWORD, BYTE); + +/* + * SHL + */ +void SHL_Eb(BYTE *); +void SHL_Ew(WORD *); +void SHL_Ed(DWORD *); +void SHL_Eb_ext(DWORD); +void SHL_Ew_ext(DWORD); +void SHL_Ed_ext(DWORD); +void SHL_EbCL(BYTE *, BYTE); +void SHL_EbCL_ext(DWORD, BYTE); +void SHL_EwCL(WORD *, BYTE); +void SHL_EwCL_ext(DWORD, BYTE); +void SHL_EdCL(DWORD *, BYTE); +void SHL_EdCL_ext(DWORD, BYTE); + +/* + * SHRD + */ +void SHRD_EwGwIb(void); +void SHRD_EdGdIb(void); +void SHRD_EwGwCL(void); +void SHRD_EdGdCL(void); + +/* + * SHLD + */ +void SHLD_EwGwIb(void); +void SHLD_EdGdIb(void); +void SHLD_EwGwCL(void); +void SHLD_EdGdCL(void); + +/* + * ROR + */ +void ROR_Eb(BYTE *); +void ROR_Ew(WORD *); +void ROR_Ed(DWORD *); +void ROR_Eb_ext(DWORD); +void ROR_Ew_ext(DWORD); +void ROR_Ed_ext(DWORD); +void ROR_EbCL(BYTE *, BYTE); +void ROR_EbCL_ext(DWORD, BYTE); +void ROR_EwCL(WORD *, BYTE); +void ROR_EwCL_ext(DWORD, BYTE); +void ROR_EdCL(DWORD *, BYTE); +void ROR_EdCL_ext(DWORD, BYTE); + +/* + * ROL + */ +void ROL_Eb(BYTE *); +void ROL_Ew(WORD *); +void ROL_Ed(DWORD *); +void ROL_Eb_ext(DWORD); +void ROL_Ew_ext(DWORD); +void ROL_Ed_ext(DWORD); +void ROL_EbCL(BYTE *, BYTE); +void ROL_EbCL_ext(DWORD, BYTE); +void ROL_EwCL(WORD *, BYTE); +void ROL_EwCL_ext(DWORD, BYTE); +void ROL_EdCL(DWORD *, BYTE); +void ROL_EdCL_ext(DWORD, BYTE); + +/* + * RCR + */ +void RCR_Eb(BYTE *); +void RCR_Ew(WORD *); +void RCR_Ed(DWORD *); +void RCR_Eb_ext(DWORD); +void RCR_Ew_ext(DWORD); +void RCR_Ed_ext(DWORD); +void RCR_EbCL(BYTE *, BYTE); +void RCR_EbCL_ext(DWORD, BYTE); +void RCR_EwCL(WORD *, BYTE); +void RCR_EwCL_ext(DWORD, BYTE); +void RCR_EdCL(DWORD *, BYTE); +void RCR_EdCL_ext(DWORD, BYTE); + +/* + * RCL + */ +void RCL_Eb(BYTE *); +void RCL_Ew(WORD *); +void RCL_Ed(DWORD *); +void RCL_Eb_ext(DWORD); +void RCL_Ew_ext(DWORD); +void RCL_Ed_ext(DWORD); +void RCL_EbCL(BYTE *, BYTE); +void RCL_EbCL_ext(DWORD, BYTE); +void RCL_EwCL(WORD *, BYTE); +void RCL_EwCL_ext(DWORD, BYTE); +void RCL_EdCL(DWORD *, BYTE); +void RCL_EdCL_ext(DWORD, BYTE); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_SHIFT_ROTATE_H__ */ diff --git a/i386c/ia32/instructions/shift_rotate.mcr b/i386c/ia32/instructions/shift_rotate.mcr new file mode 100644 index 00000000..ae50e23e --- /dev/null +++ b/i386c/ia32/instructions/shift_rotate.mcr @@ -0,0 +1,826 @@ +/* $Id: shift_rotate.mcr,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_SHIFT_ROTATE_MCR__ +#define IA32_CPU_SHIFT_ROTATE_MCR__ + +/* + * SAR + */ +#define _BYTE_SAR1(d, s) \ +do { \ + (d) = (BYTE)(((SBYTE)(s)) >> 1); \ + CPU_OV = 0; \ + CPU_FLAGL = (BYTE)(szpcflag[(BYTE)(d)] | A_FLAG | ((s) & 1)); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SAR1(d, s) \ +do { \ + (d) = (WORD)(((SWORD)(s)) >> 1); \ + CPU_OV = 0; \ + CPU_FLAGL = (BYTE)(szpflag_w[(WORD)(d)] | A_FLAG | ((s) & 1)); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SAR1(d, s) \ +do { \ + (d) = (DWORD)(((SDWORD)(s)) >> 1); \ + CPU_OV = 0; \ + CPU_FLAGL = (BYTE)(A_FLAG | ((s) & 1)); /* C_FLAG */ \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(BYTE)(d)] & P_FLAG); \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_SARCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (c) { \ + (s) = ((SBYTE)(s)) >> ((c) - 1); \ + CPU_FLAGL = (BYTE)((s) & 1); /* C_FLAG */ \ + (s) = (BYTE)(((SBYTE)(s)) >> 1); \ + CPU_OV = 0; \ + CPU_FLAGL |= (szpcflag[(BYTE)(s)] | A_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SARCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (c) { \ + (s) = ((SWORD)(s)) >> ((c) - 1); \ + CPU_FLAGL = (BYTE)((s) & 1); /* C_FLAG */ \ + (s) = (WORD)(((SWORD)(s)) >> 1); \ + CPU_OV = 0; \ + CPU_FLAGL |= szpflag_w[(WORD)(s)]; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SARCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (s) = ((SDWORD)(s)) >> ((c) - 1); \ + CPU_FLAGL = (BYTE)((s) & 1); /* C_FLAG */ \ + (s) = (DWORD)(((SDWORD)(s)) >> 1); \ + CPU_OV = 0; \ + if ((s) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((s) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(BYTE)(s)] & P_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * SHR + */ +#define _BYTE_SHR1(d, s) \ +do { \ + (d) = (s) >> 1; \ + CPU_OV = (s) & 0x80; \ + CPU_FLAGL = (BYTE)(szpcflag[(BYTE)(d)] | A_FLAG | ((s) & 1)); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SHR1(d, s) \ +do { \ + (d) = (s) >> 1; \ + CPU_OV = (s) & 0x8000; \ + CPU_FLAGL = (BYTE)(szpflag_w[(WORD)(d)] | A_FLAG | ((s) & 1)); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHR1(d, s) \ +do { \ + (d) = (s) >> 1; \ + CPU_OV = (s) & 0x80000000; \ + CPU_FLAGL = (BYTE)(A_FLAG | ((s) & 1)); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(BYTE)(d)] & P_FLAG); \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_SHRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (c) { \ + if ((c) >= 0x10) { \ + (c) &= 7; \ + (c) |= 8; \ + } \ + (s) >>= (c) - 1; \ + CPU_FLAGL = (BYTE)((s) & 1); \ + (s) >>= 1; \ + CPU_OV = ((s) ^ ((s) >> 1)) & 0x40; \ + CPU_FLAGL |= (szpcflag[(BYTE)(s)] | A_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SHRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (c) { \ + (c)--; \ + if (c) { \ + (s) >>= (c); \ + CPU_OV = 0; \ + } else { \ + CPU_OV = (s) & 0x8000; \ + } \ + CPU_FLAGL = (BYTE)((s) & 1); \ + (s) >>= 1; \ + CPU_FLAGL |= szpflag_w[(WORD)(s)]; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (c) { \ + (c)--; \ + if (c) { \ + (s) >>= (c); \ + CPU_OV = 0; \ + } else { \ + CPU_OV = (s) & 0x80000000; \ + } \ + CPU_FLAGL = (BYTE)((s) & 1); \ + (s) >>= 1; \ + if ((s) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((s) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(BYTE)(s)] & P_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * SHL + */ +#define _BYTE_SHL1(d, s) \ +do { \ + (d) = (s) << 1; \ + CPU_OV = ((s) ^ (d)) & 0x80; \ + CPU_FLAGL = szpcflag[(d) & 0x1ff] | A_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SHL1(d, s) \ +do { \ + (d) = (s) << 1; \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ + CPU_FLAGL = (BYTE)(szpflag_w[(WORD)(d)] | A_FLAG | ((d) >> 16)); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHL1(d, s) \ +do { \ + (d) = (s) << 1; \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ + CPU_FLAGL = (BYTE)(A_FLAG | (szpcflag[(BYTE)(d)] & P_FLAG)); \ + if ((s) & 0x80000000) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_SHLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (c) { \ + if ((c) >= 0x10) { \ + (c) &= 7; \ + (c) |= 8; \ + } \ + (s) <<= (c); \ + (s) &= 0x1ff; \ + CPU_FLAGL = (szpcflag[(s) & 0x1ff] | A_FLAG); \ + CPU_OV = ((s) ^ ((s) >> 1)) & 0x80; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SHLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (c) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) + 0x4000) & 0x8000; \ + } \ + (s) <<= (c); \ + (s) &= 0x1ffff; \ + CPU_FLAGL = szpflag_w[(WORD)(s)] | A_FLAG; \ + CPU_FLAGL |= (BYTE)((s) >> 16); /* C_FLAG */ \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (c) { \ + (c)--; \ + if ((c)) { \ + (s) <<= (c); \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) + 0x40000000) & 0x80000000; \ + } \ + CPU_FLAGL = A_FLAG; \ + if ((s) & 0x80000000) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + (s) <<= 1; \ + if ((s) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((s) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(BYTE)(s)] & P_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * SHRD + */ +#define _WORD_SHRD(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + if ((c) < 16) { \ + CPU_FLAGL = (BYTE)(((d) >> ((c) - 1)) & 1); /*C_FLAG*/ \ + (d) |= (s) << 16; \ + (d) >>= (c); \ + (d) &= 0xffff; \ + CPU_FLAGL |= szpflag_w[(WORD)(d)] | A_FLAG; \ + CPU_OV = (d) & 0x8000; \ + } \ + /* XXX + CPU_FLAGL = (BYTE)(((d) >> ((c) - 1)) & 1); \ + (d) |= (s) << 16; \ + (d) >>= (c); \ + if ((c) > 16) { \ + (d) |= (s) << (32 - (c)); \ + } \ + (d) &= 0xffff; \ + CPU_FLAGL |= (szpflag_w[(d)] | A_FLAG); \ + CPU_OV = (d) & 0x8000; \ + */ \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHRD(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + CPU_FLAGL = (BYTE)(((d) >> ((c) - 1)) & 1); /* C_FLAG */ \ + (d) >>= (c); \ + (d) |= (s) << (32 - (c)); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(BYTE)(d)] & P_FLAG); \ + CPU_OV = (d) & 0x80000000; \ + } \ +} while (/*CONSTCOND*/ 0) + +/* + * SHLD + */ +#define _WORD_SHLD(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + if ((c) < 16) { \ + CPU_FLAGL = (BYTE)(((d) >> (16 - (c))) & 1); /*C_FLAG*/\ + (d) = ((d) << 16) | (s); \ + (d) <<= (c); \ + (d) >>= 16; \ + CPU_FLAGL |= szpflag_w[(d)] | A_FLAG; \ + CPU_OV = (d) & 0x8000; \ + } \ + /* XXX + CPU_FLAGL = (BYTE)(((d) >> (16 - (c))) & 1); \ + (d) = ((d) << 16) | (s); \ + (d) <<= (c); \ + if ((c) > 16) { \ + (d) |= ((s) << ((c) - 16)); \ + } \ + (d) >>= 16; \ + CPU_FLAGL |= szpflag_w[(d)] | A_FLAG; \ + CPU_OV = (d) & 0x8000; \ + */ \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHLD(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + CPU_FLAGL = (BYTE)(((d) >> (32 - (c))) & 1); /* C_FLAG */ \ + (d) <<= (c); \ + (d) |= ((s) >> (32 - (c))); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(BYTE)(d)] & P_FLAG); \ + CPU_OV = (d) & 0x80000000; \ + } \ +} while (/*CONSTCOND*/ 0) + +/* + * ROR + */ +#define _BYTE_ROR1(d, s) \ +do { \ + DWORD tmp = (s) & 1; \ + (d) = (tmp << 7) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x80; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_ROR1(d, s) \ +do { \ + DWORD tmp = (s) & 1; \ + (d) = (tmp << 15) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_ROR1(d, s) \ +do { \ + DWORD tmp = (s) & 1; \ + (d) = (tmp << 31) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_RORCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c) = ((c) - 1) & 7; \ + if ((c)) { \ + (s) = ((s) >> (c)) | ((s) << (8 - (c))); \ + (s) &= 0xff; \ + } \ + _BYTE_ROR1(d, s); \ + } else { \ + (d) = (s); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RORCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp; \ + (c)--; \ + if ((c)) { \ + (c) &= 0x0f; \ + (s) = ((s) >> (c)) | ((s) << (16 - (c))); \ + (s) &= 0xffff; \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) >> 15) ^ ((s) & 1); \ + } \ + tmp = (s) & 1; \ + (s) = (tmp << 15) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RORCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp; \ + (c)--; \ + if ((c)) { \ + (s) = ((s) >> (c)) | ((s) << (32 - (c))); \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) >> 31) ^ ((s) & 1); \ + } \ + tmp = (s) & 1; \ + (s) = (tmp << 31) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * ROL + */ +#define _BYTE_ROL1(d, s) \ +do { \ + DWORD tmp = (s) >> 7; /* C_FLAG */ \ + (d) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x80; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_ROL1(d, s) \ +do { \ + DWORD tmp = (s) >> 15; /* C_FLAG */ \ + (d) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_ROL1(d, s) \ +do { \ + DWORD tmp = (s) >> 31; /* C_FLAG */ \ + (d) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_ROLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c) = ((c) - 1) & 7; \ + if ((c)) { \ + (s) = ((s) << (c)) | ((s) >> (8 - (c))); \ + (s) &= 0xff; \ + } \ + _BYTE_ROL1(d, s); \ + } else { \ + (d) = (s); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_ROLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp; \ + (c)--; \ + if ((c)) { \ + (c) &= 0x0f; \ + (s) = ((s) << (c)) | ((s) >> (16 - (c))); \ + (s) &= 0xffff; \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) + 0x4000) & 0x8000; \ + } \ + tmp = (s) >> 15; \ + (s) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_ROLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp; \ + (c)--; \ + if ((c)) { \ + (s) = ((s) << (c)) | ((s) >> (32 - (c))); \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) + 0x40000000) & 0x80000000; \ + } \ + tmp = (s) >> 31; \ + (s) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * RCR + */ +#define _BYTE_RCR1(d, s) \ +do { \ + (d) = ((CPU_FLAGL & C_FLAG) << 7) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) & 1; \ + CPU_OV = ((s) ^ (d)) & 0x80; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RCR1(d, s) \ +do { \ + (d) = ((CPU_FLAGL & C_FLAG) << 15) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) & 1; \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RCR1(d, s) \ +do { \ + (d) = ((CPU_FLAGL & C_FLAG) << 31) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) & 1; \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_RCRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + while ((c)--) { \ + (s) |= (tmp << 8); \ + tmp = (s) & 1; \ + (s) >>= 1; \ + } \ + CPU_OV = ((s) ^ ((s) >> 1)) & 0x40; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RCRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) >> 15) ^ tmp; \ + } \ + while ((c)--) { \ + (s) |= (tmp << 16); \ + tmp = (s) & 1; \ + (s) >>= 1; \ + } \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RCRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) >> 31) ^ tmp; \ + } \ + while ((c)--) { \ + tmp = (s) & 1; \ + (s) = (tmp << 31) | ((s) >> 1); \ + } \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * RCL + */ +#define _BYTE_RCL1(d, s) \ +do { \ + (d) = ((s) << 1) | (CPU_FLAGL & C_FLAG); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) >> 7; /* C_FLAG */ \ + CPU_OV = ((s) ^ (d)) & 0x80; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RCL1(d, s) \ +do { \ + (d) = ((s) << 1) | (CPU_FLAGL & C_FLAG); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) >> 15; /* C_FLAG */ \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RCL1(d, s) \ +do { \ + (d) = ((s) << 1) | (CPU_FLAGL & C_FLAG); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) >> 31; /* C_FLAG */ \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_RCLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + while ((c)--) { \ + (s) = (((s) << 1) | tmp) & 0x1ff; \ + tmp = (s) >> 8; \ + } \ + CPU_OV = ((s) ^ ((s) >> 1)) & 0x80; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RCLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) + 0x4000) & 0x8000; \ + } \ + while ((c)--) { \ + (s) = (((s) << 1) | tmp) & 0x1ffff; \ + tmp = (s) >> 16; \ + } \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RCLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + DWORD tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) + 0x40000000) & 0x80000000; \ + } \ + while ((c)--) { \ + tmp = (s) & 0x80000000; \ + (s) = ((s) << 1) | (tmp & 1); \ + tmp >>= 31; \ + } \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#if defined(IA32_CROSS_CHECK) && defined(__GNUC__) && (defined(i386) || defined(i386)) + +#include "shift_rotatexc.mcr" + +#define BYTE_SAR1(d, s) XC_BYTE_SAR1(d, s) +#define WORD_SAR1(d, s) XC_WORD_SAR1(d, s) +#define DWORD_SAR1(d, s) XC_DWORD_SAR1(d, s) +#define BYTE_SARCL(d, s, c) XC_BYTE_SARCL(d, s, c) +#define WORD_SARCL(d, s, c) XC_WORD_SARCL(d, s, c) +#define DWORD_SARCL(d, s, c) XC_DWORD_SARCL(d, s, c) +#define BYTE_SHR1(d, s) XC_BYTE_SHR1(d, s) +#define WORD_SHR1(d, s) XC_WORD_SHR1(d, s) +#define DWORD_SHR1(d, s) XC_DWORD_SHR1(d, s) +#define BYTE_SHRCL(d, s, c) XC_BYTE_SHRCL(d, s, c) +#define WORD_SHRCL(d, s, c) XC_WORD_SHRCL(d, s, c) +#define DWORD_SHRCL(d, s, c) XC_DWORD_SHRCL(d, s, c) +#define BYTE_SHL1(d, s) XC_BYTE_SHL1(d, s) +#define WORD_SHL1(d, s) XC_WORD_SHL1(d, s) +#define DWORD_SHL1(d, s) XC_DWORD_SHL1(d, s) +#define BYTE_SHLCL(d, s, c) XC_BYTE_SHLCL(d, s, c) +#define WORD_SHLCL(d, s, c) XC_WORD_SHLCL(d, s, c) +#define DWORD_SHLCL(d, s, c) XC_DWORD_SHLCL(d, s, c) +#define WORD_SHRD(d, s, c) XC_WORD_SHRD(d, s, c) +#define DWORD_SHRD(d, s, c) XC_DWORD_SHRD(d, s, c) +#define WORD_SHLD(d, s, c) XC_WORD_SHLD(d, s, c) +#define DWORD_SHLD(d, s, c) XC_DWORD_SHLD(d, s, c) +#define BYTE_ROR1(d, s) XC_BYTE_ROR1(d, s) +#define WORD_ROR1(d, s) XC_WORD_ROR1(d, s) +#define DWORD_ROR1(d, s) XC_DWORD_ROR1(d, s) +#define BYTE_RORCL(d, s, c) XC_BYTE_RORCL(d, s, c) +#define WORD_RORCL(d, s, c) XC_WORD_RORCL(d, s, c) +#define DWORD_RORCL(d, s, c) XC_DWORD_RORCL(d, s, c) +#define BYTE_ROL1(d, s) XC_BYTE_ROL1(d, s) +#define WORD_ROL1(d, s) XC_WORD_ROL1(d, s) +#define DWORD_ROL1(d, s) XC_DWORD_ROL1(d, s) +#define BYTE_ROLCL(d, s, c) XC_BYTE_ROLCL(d, s, c) +#define WORD_ROLCL(d, s, c) XC_WORD_ROLCL(d, s, c) +#define DWORD_ROLCL(d, s, c) XC_DWORD_ROLCL(d, s, c) +#define BYTE_RCR1(d, s) XC_BYTE_RCR1(d, s) +#define WORD_RCR1(d, s) XC_WORD_RCR1(d, s) +#define DWORD_RCR1(d, s) XC_DWORD_RCR1(d, s) +#define BYTE_RCRCL(d, s, c) XC_BYTE_RCRCL(d, s, c) +#define WORD_RCRCL(d, s, c) XC_WORD_RCRCL(d, s, c) +#define DWORD_RCRCL(d, s, c) XC_DWORD_RCRCL(d, s, c) +#define BYTE_RCL1(d, s) XC_BYTE_RCL1(d, s) +#define WORD_RCL1(d, s) XC_WORD_RCL1(d, s) +#define DWORD_RCL1(d, s) XC_DWORD_RCL1(d, s) +#define BYTE_RCLCL(d, s, c) XC_BYTE_RCLCL(d, s, c) +#define WORD_RCLCL(d, s, c) XC_WORD_RCLCL(d, s, c) +#define DWORD_RCLCL(d, s, c) XC_DWORD_RCLCL(d, s, c) + +#else /* !(IA32_CROSS_CHECK && __GNUC__ && (i386) || __i386__)) */ + +#define BYTE_SAR1(d, s) _BYTE_SAR1(d, s) +#define WORD_SAR1(d, s) _WORD_SAR1(d, s) +#define DWORD_SAR1(d, s) _DWORD_SAR1(d, s) +#define BYTE_SARCL(d, s, c) _BYTE_SARCL(d, s, c) +#define WORD_SARCL(d, s, c) _WORD_SARCL(d, s, c) +#define DWORD_SARCL(d, s, c) _DWORD_SARCL(d, s, c) +#define BYTE_SHR1(d, s) _BYTE_SHR1(d, s) +#define WORD_SHR1(d, s) _WORD_SHR1(d, s) +#define DWORD_SHR1(d, s) _DWORD_SHR1(d, s) +#define BYTE_SHRCL(d, s, c) _BYTE_SHRCL(d, s, c) +#define WORD_SHRCL(d, s, c) _WORD_SHRCL(d, s, c) +#define DWORD_SHRCL(d, s, c) _DWORD_SHRCL(d, s, c) +#define BYTE_SHL1(d, s) _BYTE_SHL1(d, s) +#define WORD_SHL1(d, s) _WORD_SHL1(d, s) +#define DWORD_SHL1(d, s) _DWORD_SHL1(d, s) +#define BYTE_SHLCL(d, s, c) _BYTE_SHLCL(d, s, c) +#define WORD_SHLCL(d, s, c) _WORD_SHLCL(d, s, c) +#define DWORD_SHLCL(d, s, c) _DWORD_SHLCL(d, s, c) +#define WORD_SHRD(d, s, c) _WORD_SHRD(d, s, c) +#define DWORD_SHRD(d, s, c) _DWORD_SHRD(d, s, c) +#define WORD_SHLD(d, s, c) _WORD_SHLD(d, s, c) +#define DWORD_SHLD(d, s, c) _DWORD_SHLD(d, s, c) +#define BYTE_ROR1(d, s) _BYTE_ROR1(d, s) +#define WORD_ROR1(d, s) _WORD_ROR1(d, s) +#define DWORD_ROR1(d, s) _DWORD_ROR1(d, s) +#define BYTE_RORCL(d, s, c) _BYTE_RORCL(d, s, c) +#define WORD_RORCL(d, s, c) _WORD_RORCL(d, s, c) +#define DWORD_RORCL(d, s, c) _DWORD_RORCL(d, s, c) +#define BYTE_ROL1(d, s) _BYTE_ROL1(d, s) +#define WORD_ROL1(d, s) _WORD_ROL1(d, s) +#define DWORD_ROL1(d, s) _DWORD_ROL1(d, s) +#define BYTE_ROLCL(d, s, c) _BYTE_ROLCL(d, s, c) +#define WORD_ROLCL(d, s, c) _WORD_ROLCL(d, s, c) +#define DWORD_ROLCL(d, s, c) _DWORD_ROLCL(d, s, c) +#define BYTE_RCR1(d, s) _BYTE_RCR1(d, s) +#define WORD_RCR1(d, s) _WORD_RCR1(d, s) +#define DWORD_RCR1(d, s) _DWORD_RCR1(d, s) +#define BYTE_RCRCL(d, s, c) _BYTE_RCRCL(d, s, c) +#define WORD_RCRCL(d, s, c) _WORD_RCRCL(d, s, c) +#define DWORD_RCRCL(d, s, c) _DWORD_RCRCL(d, s, c) +#define BYTE_RCL1(d, s) _BYTE_RCL1(d, s) +#define WORD_RCL1(d, s) _WORD_RCL1(d, s) +#define DWORD_RCL1(d, s) _DWORD_RCL1(d, s) +#define BYTE_RCLCL(d, s, c) _BYTE_RCLCL(d, s, c) +#define WORD_RCLCL(d, s, c) _WORD_RCLCL(d, s, c) +#define DWORD_RCLCL(d, s, c) _DWORD_RCLCL(d, s, c) + +#endif /* IA32_CROSS_CHECK && __GNUC__ && (i386) || __i386__) */ + +#endif /* IA32_CPU_SHIFT_ROTATE_MCR__ */ diff --git a/i386c/ia32/instructions/shift_rotatexc.mcr b/i386c/ia32/instructions/shift_rotatexc.mcr new file mode 100644 index 00000000..87709ecd --- /dev/null +++ b/i386c/ia32/instructions/shift_rotatexc.mcr @@ -0,0 +1,2147 @@ +/* $Id: shift_rotatexc.mcr,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SHIFT_ROTATEXC_H__ +#define IA32_CPU_INSTRUCTION_SHIFT_ROTATEXC_H__ + +#define XC_BYTE_SAR1(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_SAR1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "sarb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SAR1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SAR1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SAR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SAR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SAR1(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SAR1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "sarw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SAR1: __s = %04x", __s); \ + ia32_warning("XC_WORD_SAR1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SAR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SAR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SAR1(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SAR1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "sarl $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SAR1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SAR1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SAR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SAR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SARCL(d, s, c) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_SARCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "sarb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_SARCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SARCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_SARCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SARCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SARCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SARCL(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SARCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "sarw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SARCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_SARCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_SARCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SARCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SARCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SARCL(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SARCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "sarl %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SARCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SARCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SARCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SARCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SARCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SHR1(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_SHR1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shrb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SHR1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SHR1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SHR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SHR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHR1(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SHR1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shrw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SHR1: __s = %04x", __s); \ + ia32_warning("XC_WORD_SHR1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHR1(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SHR1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shrl $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SHR1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SHR1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SHRCL(d, s, c) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_SHRCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shrb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_SHRCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SHRCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_SHRCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SHRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SHRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHRCL(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SHRCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shrw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SHRCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_SHRCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_SHRCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHRCL(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SHRCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shrl %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SHRCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SHRCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SHRCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SHL1(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_SHL1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shlb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SHL1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SHL1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SHL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SHL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/0) + +#define XC_WORD_SHL1(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SHL1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shlw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SHL1: __s = %04x", __s); \ + ia32_warning("XC_WORD_SHL1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHL1(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SHL1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shll $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SHL1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SHL1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_SHL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SHLCL(d, s, c) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_SHLCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shlb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_SHLCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SHLCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_SHLCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SHLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SHLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHLCL(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SHLCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shlw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SHLCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_SHLCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_SHLCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHLCL(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SHLCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shll %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SHLCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SHLCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SHLCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHRD(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SHRD((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "pushl %%edx\n\t" \ + "movb %5, %%cl\n\t" \ + "movw %4, %%dx\n\t" \ + "shrdw %%cl, %%dx, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%edx\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__c) \ + : "eax", "ecx", "edx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SHRD: __s = %04x, __d = %04x", \ + __s, __d); \ + ia32_warning("XC_WORD_SHRD: __c = %02x", __c); \ + ia32_warning("XC_WORD_SHRD: __R = %04x, __r = %04x",\ + __R, __r); \ + ia32_warning("XC_WORD_SHRD: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHRD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert((__c != 1) || (!CPU_OV == !__o)); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHRD(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SHRD((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "pushl %%edx\n\t" \ + "movb %5, %%cl\n\t" \ + "movl %4, %%edx\n\t" \ + "shrdl %%cl, %%edx, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%edx\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__c) \ + : "eax", "ecx", "edx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SHRD: __s = %08x, __d = %08x", \ + __s, __d); \ + ia32_warning("XC_DWORD_SHRD: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SHRD: __R = %08x, __r = %08x",\ + __R, __r); \ + ia32_warning("XC_DWORD_SHRD: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHRD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert((__c != 1) || (!CPU_OV == !__o)); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHLD(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __d = (d) & 0xffff; \ + WORD __r = __d; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_SHLD((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "pushl %%edx\n\t" \ + "movb %5, %%cl\n\t" \ + "movw %4, %%dx\n\t" \ + "shldw %%cl, %%dx, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%edx\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__c) \ + : "eax", "ecx", "edx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SHLD: __s = %04x, __d = %04x", \ + __s, __d); \ + ia32_warning("XC_WORD_SHLD: __c = %02x", __c); \ + ia32_warning("XC_WORD_SHLD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHLD: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHLD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert((__c != 1) || (!CPU_OV == !__o)); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHLD(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __d = (d); \ + DWORD __r = __d; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_SHLD((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "pushl %%edx\n\t" \ + "movb %5, %%cl\n\t" \ + "movl %4, %%edx\n\t" \ + "shldl %%cl, %%edx, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%edx\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__c) \ + : "eax", "ecx", "edx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SHLD: __s = %08x, __d = %08x", \ + __s, __d); \ + ia32_warning("XC_DWORD_SHLD: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SHLD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHLD: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHLD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert((__c != 1) || (!CPU_OV == !__o)); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_ROR1(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_ROR1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rorb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_ROR1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_ROR1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_ROR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_ROR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_ROR1(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_ROR1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rorw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_ROR1: __s = %04x", __s); \ + ia32_warning("XC_WORD_ROR1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_ROR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_ROR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_ROR1(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_ROR1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rorl $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_ROR1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_ROR1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_ROR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_ROR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RORCL(d, s, c) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_RORCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rorb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_RORCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RORCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_RORCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RORCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RORCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RORCL(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_RORCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rorw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_RORCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_RORCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_RORCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RORCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RORCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RORCL(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_RORCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rorl %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_RORCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RORCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_RORCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RORCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RORCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_ROL1(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_ROL1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rolb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_ROL1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_ROL1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_ROL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_ROL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_ROL1(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_ROL1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rolw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_ROL1: __s = %04x", __s); \ + ia32_warning("XC_WORD_ROL1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_ROL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_ROL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_ROL1(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_ROL1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "roll $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_ROL1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_ROL1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_ROL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_ROL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_ROLCL(d, s, c) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _BYTE_ROLCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rolb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_ROLCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_ROLCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_ROLCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_ROLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_ROLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_ROLCL(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _WORD_ROLCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rolw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_ROLCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_ROLCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_ROLCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_ROLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_ROLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_ROLCL(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + \ + _DWORD_ROLCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "roll %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_ROLCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_ROLCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_ROLCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_ROLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_ROLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RCR1(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_RCR1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_RCR1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RCR1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RCR1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_BYTE_RCR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RCR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RCR1(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _WORD_RCR1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_RCR1: __s = %04x", __s); \ + ia32_warning("XC_WORD_RCR1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RCR1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_WORD_RCR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RCR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RCR1(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_RCR1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrl $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_RCR1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RCR1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RCR1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_DWORD_RCR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RCR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RCRCL(d, s, c) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_RCRCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_RCRCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RCRCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_RCRCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RCRCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_BYTE_RCRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RCRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RCRCL(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _WORD_RCRCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_RCRCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_RCRCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_RCRCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RCRCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_WORD_RCRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RCRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RCRCL(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_RCRCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrl %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_RCRCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RCRCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_RCRCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RCRCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_DWORD_RCRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RCRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RCL1(d, s) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_RCL1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rclb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_RCL1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RCL1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RCL1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_BYTE_RCL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RCL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RCL1(d, s) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _WORD_RCL1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rclw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_RCL1: __s = %04x", __s); \ + ia32_warning("XC_WORD_RCL1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RCL1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_WORD_RCL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RCL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RCL1(d, s) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_RCL1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcll $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_RCL1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RCL1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RCL1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_DWORD_RCL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RCL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RCLCL(d, s, c) \ +do { \ + BYTE __s = (s) & 0xff; \ + BYTE __r = __s; \ + BYTE __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_RCLCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rclb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_RCLCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RCLCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_RCLCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RCLCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_BYTE_RCLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RCLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RCLCL(d, s, c) \ +do { \ + WORD __s = (s) & 0xffff; \ + WORD __r = __s; \ + WORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _WORD_RCLCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rclw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_RCLCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_RCLCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_RCLCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RCLCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_WORD_RCLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RCLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RCLCL(d, s, c) \ +do { \ + DWORD __s = (s); \ + DWORD __r = __s; \ + DWORD __R; \ + BYTE __c = (c) & 0xff; \ + BYTE __f; \ + BYTE __o; \ + BYTE __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_RCLCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcll %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_RCLCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RCLCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_RCLCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RCLCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_DWORD_RCLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RCLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#endif /* IA32_CPU_INSTRUCTION_SHIFT_ROTATEXC_H__ */ diff --git a/i386c/ia32/instructions/string_inst.c b/i386c/ia32/instructions/string_inst.c new file mode 100644 index 00000000..f747e191 --- /dev/null +++ b/i386c/ia32/instructions/string_inst.c @@ -0,0 +1,433 @@ +/* $Id: string_inst.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "string_inst.h" + + +/* movs */ +void +MOVSB_XbYb(void) +{ + BYTE tmp; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_vmemorywrite(CPU_ES_INDEX, CPU_DI, tmp); + CPU_SI += STRING_DIR; + CPU_DI += STRING_DIR; + } else { + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_vmemorywrite(CPU_ES_INDEX, CPU_EDI, tmp); + CPU_ESI += STRING_DIR; + CPU_EDI += STRING_DIR; + } +} + +void +MOVSW_XwYw(void) +{ + WORD tmp; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_DI, tmp); + CPU_SI += STRING_DIRx2; + CPU_DI += STRING_DIRx2; + } else { + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_EDI, tmp); + CPU_ESI += STRING_DIRx2; + CPU_EDI += STRING_DIRx2; + } +} + +void +MOVSD_XdYd(void) +{ + DWORD tmp; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_DI, tmp); + CPU_SI += STRING_DIRx4; + CPU_DI += STRING_DIRx4; + } else { + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_EDI, tmp); + CPU_ESI += STRING_DIRx4; + CPU_EDI += STRING_DIRx4; + } +} + + +/* cmps */ +void +CMPSB_XbYb(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(8); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_DI); + BYTE_SUB(res, dst, src); + CPU_SI += STRING_DIR; + CPU_DI += STRING_DIR; + } else { + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_EDI); + BYTE_SUB(res, dst, src); + CPU_ESI += STRING_DIR; + CPU_EDI += STRING_DIR; + } +} + +void +CMPSW_XwYw(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(8); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_DI); + WORD_SUB(res, dst, src); + CPU_SI += STRING_DIRx2; + CPU_DI += STRING_DIRx2; + } else { + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_EDI); + WORD_SUB(res, dst, src); + CPU_ESI += STRING_DIRx2; + CPU_EDI += STRING_DIRx2; + } +} + +void +CMPSD_XdYd(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(8); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_DI); + DWORD_SUB(res, dst, src); + CPU_SI += STRING_DIRx4; + CPU_DI += STRING_DIRx4; + } else { + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_EDI); + DWORD_SUB(res, dst, src); + CPU_ESI += STRING_DIRx4; + CPU_EDI += STRING_DIRx4; + } +} + + +/* scas */ +void +SCASB_ALXb(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(7); + dst = CPU_AL; + if (!CPU_INST_AS32) { + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_DI); + BYTE_SUB(res, dst, src); + CPU_DI += STRING_DIR; + } else { + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_EDI); + BYTE_SUB(res, dst, src); + CPU_EDI += STRING_DIR; + } +} + +void +SCASW_AXXw(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(7); + dst = CPU_AX; + if (!CPU_INST_AS32) { + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_DI); + WORD_SUB(res, dst, src); + CPU_DI += STRING_DIRx2; + } else { + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_EDI); + WORD_SUB(res, dst, src); + CPU_EDI += STRING_DIRx2; + } +} + +void +SCASD_EAXXd(void) +{ + DWORD src, dst, res; + + CPU_WORKCLOCK(7); + dst = CPU_EAX; + if (!CPU_INST_AS32) { + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_DI); + DWORD_SUB(res, dst, src); + CPU_DI += STRING_DIRx4; + } else { + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_EDI); + DWORD_SUB(res, dst, src); + CPU_EDI += STRING_DIRx4; + } +} + + +/* lods */ +void +LODSB_ALXb(void) +{ + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); + CPU_SI += STRING_DIR; + } else { + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); + CPU_ESI += STRING_DIR; + } +} + +void +LODSW_AXXw(void) +{ + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + CPU_AX = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); + CPU_SI += STRING_DIRx2; + } else { + CPU_AX = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); + CPU_ESI += STRING_DIRx2; + } +} + +void +LODSD_EAXXd(void) +{ + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + CPU_EAX = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); + CPU_SI += STRING_DIRx4; + } else { + CPU_EAX = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); + CPU_ESI += STRING_DIRx4; + } +} + + +/* stos */ +void +STOSB_YbAL(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_INST_AS32) { + cpu_vmemorywrite(CPU_ES_INDEX, CPU_DI, CPU_AL); + CPU_DI += STRING_DIR; + } else { + cpu_vmemorywrite(CPU_ES_INDEX, CPU_EDI, CPU_AL); + CPU_EDI += STRING_DIR; + } +} + +void +STOSW_YwAX(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_INST_AS32) { + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_DI, CPU_AX); + CPU_DI += STRING_DIRx2; + } else { + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_EDI, CPU_AX); + CPU_EDI += STRING_DIRx2; + } +} + +void +STOSD_YdEAX(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_INST_AS32) { + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_DI, CPU_EAX); + CPU_DI += STRING_DIRx4; + } else { + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_EDI, CPU_EAX); + CPU_EDI += STRING_DIRx4; + } +} + + +/* repeat */ +void +_REPNE(void) +{ + + CPU_INST_REPUSE = 0xf2; +} + +void +_REPE(void) +{ + + CPU_INST_REPUSE = 0xf3; +} + + +/* ins */ +void +INSB_YbDX(void) +{ + BYTE data; + + CPU_WORKCLOCK(5); + data = cpu_in(CPU_DX); + if (!CPU_INST_AS32) { + cpu_vmemorywrite(CPU_ES_INDEX, CPU_DI, data); + CPU_DI += STRING_DIR; + } else { + cpu_vmemorywrite(CPU_ES_INDEX, CPU_EDI, data); + CPU_EDI += STRING_DIR; + } +} + +void +INSW_YwDX(void) +{ + WORD data; + + CPU_WORKCLOCK(5); + data = cpu_in_w(CPU_DX); + if (!CPU_INST_AS32) { + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_DI, data); + CPU_DI += STRING_DIRx2; + } else { + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_EDI, data); + CPU_EDI += STRING_DIRx2; + } +} + +void +INSD_YdDX(void) +{ + DWORD data; + + CPU_WORKCLOCK(5); + data = cpu_in_d(CPU_DX); + if (!CPU_INST_AS32) { + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_DI, data); + CPU_DI += STRING_DIRx4; + } else { + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_EDI, data); + CPU_EDI += STRING_DIRx4; + } +} + + +/* outs */ +void +OUTSB_DXXb(void) +{ + BYTE data; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + data = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_out(CPU_DX, data); + CPU_SI += STRING_DIR; + } else { + data = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_out(CPU_DX, data); + CPU_ESI += STRING_DIR; + } +} + +void +OUTSW_DXXw(void) +{ + WORD data; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + data = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_out_w(CPU_DX, data); + CPU_SI += STRING_DIRx2; + } else { + data = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_out_w(CPU_DX, data); + CPU_ESI += STRING_DIRx2; + } +} + +void +OUTSD_DXXd(void) +{ + DWORD data; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + data = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_out_d(CPU_DX, data); + CPU_SI += STRING_DIRx4; + } else { + data = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_out_d(CPU_DX, data); + CPU_ESI += STRING_DIRx4; + } +} diff --git a/i386c/ia32/instructions/string_inst.h b/i386c/ia32/instructions/string_inst.h new file mode 100644 index 00000000..fbd9d8f4 --- /dev/null +++ b/i386c/ia32/instructions/string_inst.h @@ -0,0 +1,84 @@ +/* $Id: string_inst.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_STRING_H__ +#define IA32_CPU_INSTRUCTION_STRING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define STRING_DIR ((CPU_FLAG & D_FLAG) ? -1 : 1) +#define STRING_DIRx2 ((CPU_FLAG & D_FLAG) ? -2 : 2) +#define STRING_DIRx4 ((CPU_FLAG & D_FLAG) ? -4 : 4) + +/* movs */ +void MOVSB_XbYb(void); +void MOVSW_XwYw(void); +void MOVSD_XdYd(void); + +/* cmps */ +void CMPSB_XbYb(void); +void CMPSW_XwYw(void); +void CMPSD_XdYd(void); + +/* scas */ +void SCASB_ALXb(void); +void SCASW_AXXw(void); +void SCASD_EAXXd(void); + +/* lods */ +void LODSB_ALXb(void); +void LODSW_AXXw(void); +void LODSD_EAXXd(void); + +/* stos */ +void STOSB_YbAL(void); +void STOSW_YwAX(void); +void STOSD_YdEAX(void); + +/* repeat */ +void _REPNE(void); +void _REPE(void); + +/* ins */ +void INSB_YbDX(void); +void INSW_YwDX(void); +void INSD_YdDX(void); + +/* outs */ +void OUTSB_DXXb(void); +void OUTSW_DXXw(void); +void OUTSD_DXXd(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_STRING_H__ */ diff --git a/i386c/ia32/instructions/system_inst.c b/i386c/ia32/instructions/system_inst.c new file mode 100644 index 00000000..7a201ddc --- /dev/null +++ b/i386c/ia32/instructions/system_inst.c @@ -0,0 +1,981 @@ +/* $Id: system_inst.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "system_inst.h" + + +void +LGDT16_Ms(DWORD op) +{ + DWORD madr; + DWORD base; + WORD limit; + + if (op < 0xc0) { + if (!CPU_STAT_PM || !CPU_STAT_VM86 || CPU_STAT_CPL == 0) { + CPU_WORKCLOCK(11); + madr = get_ea(op); + limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); + base &= 0x00ffffff; + + VERBOSE(("LGDT16_Ms: GDTR_BASE = 0x%08x, GDTR_LIMIT = 0x%04x", base, limit)); + + CPU_GDTR_BASE = base; + CPU_GDTR_LIMIT = limit; + return; + } + EXCEPTION(GP_EXCEPTION, 0); + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LGDT32_Ms(DWORD op) +{ + DWORD madr; + DWORD base; + WORD limit; + + if (op < 0xc0) { + if (!CPU_STAT_PM || !CPU_STAT_VM86 || CPU_STAT_CPL == 0) { + CPU_WORKCLOCK(11); + madr = get_ea(op); + limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); + + VERBOSE(("LGDT32_Ms: GDTR_BASE = 0x%08x, GDTR_LIMIT = 0x%04x", base, limit)); + + CPU_GDTR_BASE = base; + CPU_GDTR_LIMIT = limit; + return; + } + EXCEPTION(GP_EXCEPTION, 0); + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +SGDT16_Ms(DWORD op) +{ + DWORD madr; + DWORD base; + WORD limit; + + if (op < 0xc0) { + CPU_WORKCLOCK(11); + base = CPU_GDTR_BASE & 0x00ffffff; + limit = CPU_GDTR_LIMIT; + madr = get_ea(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +SGDT32_Ms(DWORD op) +{ + DWORD madr; + DWORD base; + WORD limit; + + if (op < 0xc0) { + CPU_WORKCLOCK(11); + base = CPU_GDTR_BASE; + limit = CPU_GDTR_LIMIT; + madr = get_ea(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LLDT_Ew(DWORD op) +{ + DWORD src, madr; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (CPU_STAT_CPL == 0) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + load_ldtr(src, GP_EXCEPTION); + return; + } + EXCEPTION(GP_EXCEPTION, 0); + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +SLDT_Ew(DWORD op) +{ + DWORD madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + *(reg16_b20[op]) = CPU_LDTR; + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_LDTR); + } +} + +void +SLDT_Ed(DWORD op) +{ + DWORD madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + *(reg32_b20[op]) = CPU_LDTR; + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_LDTR); + } +} + +void +LTR_Ew(DWORD op) +{ + DWORD src, madr; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (CPU_STAT_CPL == 0) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + load_tr(src); + return; + } + EXCEPTION(GP_EXCEPTION, 0); + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +STR_Ew(DWORD op) +{ + DWORD madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + *(reg16_b20[op]) = CPU_TR; + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_TR); + } +} + +void +STR_Ed(DWORD op) +{ + DWORD madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + *(reg32_b20[op]) = CPU_TR; + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_TR); + } +} + +void +LIDT16_Ms(DWORD op) +{ + DWORD madr; + DWORD base; + WORD limit; + + GET_PCBYTE(op); + if (op < 0xc0) { + CPU_WORKCLOCK(11); + madr = get_ea(op); + limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); + base &= 0x00ffffff; + CPU_IDTR_BASE = base; + CPU_IDTR_LIMIT = limit; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LIDT32_Ms(DWORD op) +{ + DWORD madr; + DWORD base; + WORD limit; + + GET_PCBYTE(op); + if (op < 0xc0) { + CPU_WORKCLOCK(11); + madr = get_ea(op); + limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); + CPU_IDTR_BASE = base; + CPU_IDTR_LIMIT = limit; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +SIDT16_Ms(DWORD op) +{ + DWORD madr; + DWORD base; + WORD limit; + + GET_PCBYTE(op); + if (op < 0xc0) { + CPU_WORKCLOCK(11); + base = CPU_IDTR_BASE & 0x00ffffff; + limit = CPU_IDTR_LIMIT; + madr = get_ea(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +SIDT32_Ms(DWORD op) +{ + DWORD madr; + DWORD base; + WORD limit; + + if (op < 0xc0) { + CPU_WORKCLOCK(11); + base = CPU_IDTR_BASE; + limit = CPU_IDTR_LIMIT; + madr = get_ea(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_CdRd(void) +{ + DWORD op, src; + DWORD reg; + int idx; + + CPU_WORKCLOCK(11); + GET_PCBYTE(op); + if (op >= 0xc0) { + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + EXCEPTION(GP_EXCEPTION, 0); + } + + src = *(reg32_b20[op]); + idx = (op >> 3) & 7; + switch (idx) { + case 0: /* CR0 */ + /* + * 0 = PE (protect enable) + * 1 = MP (monitor coprocesser) + * 2 = EM (emulation) + * 3 = TS (task switch) + * 4 = ET (extend type, FPU present = 1) + * 5 = NE (numeric error) + * 16 = WP (write protect) + * 18 = AM (alignment mask) + * 29 = NW (not write-through) + * 30 = CD (cache diable) + * 31 = PG (pageing) + */ + + /* イシエャ p.182 ウ荀ケ、゚ 13 - ーネフハンクホ羌ー */ + if ((src & (CPU_CR0_PE|CPU_CR0_PG)) == (DWORD)CPU_CR0_PG) { + EXCEPTION(GP_EXCEPTION, 0); + } + if ((src & (CPU_CR0_NW|CPU_CR0_CD)) == CPU_CR0_NW) { + EXCEPTION(GP_EXCEPTION, 0); + } + + reg = CPU_CR0; + src &= 0xe005003f; +#ifndef USE_FPU + src &= ~CPU_CR0_ET; /* FPU not present */ +#else + src |= CPU_CR0_ET; /* FPU present */ +#endif + CPU_CR0 = src; + + if ((reg ^ CPU_CR0) & (CPU_CR0_PE|CPU_CR0_PG)) { + tlb_flush(FALSE); + } + if ((reg ^ CPU_CR0) & CPU_CR0_PE) { + if (CPU_CR0 & CPU_CR0_PE) { + change_pm(1); + } + } + if ((reg ^ CPU_CR0) & CPU_CR0_PG) { + if (CPU_CR0 & CPU_CR0_PG) { + change_pg(1); + } else { + change_pg(0); + } + } + if ((reg ^ CPU_CR0) & CPU_CR0_PE) { + if (!(CPU_CR0 & CPU_CR0_PE)) { + change_pm(0); + } + } + break; + + case 2: /* CR2 */ + CPU_CR2 = src; /* page fault linear address */ + break; + + case 3: /* CR3 */ + /* + * 31-12 = page directory base + * 4 = PCD (page level cache diable) + * 3 = PWT (page level write throgh) + */ + CPU_CR3 = src & 0xfffff018; + tlb_flush(FALSE); + break; + + case 4: /* CR4 */ + /* + * 10 = OSXMMEXCPT (support non masking exception by OS) + * 9 = OSFXSR (support FXSAVE, FXRSTOR by OS) + * 8 = PCE (performance monitoring counter enable) + * 7 = PGE (page global enable) + * 6 = MCE (machine check enable) + * 5 = PAE (physical address extention) + * 4 = PSE (page size extention) + * 3 = DE (debug extention) + * 2 = TSD (time stamp diable) + * 1 = PVI (protected mode virtual interrupt) + * 0 = VME (VM8086 mode extention) + */ + reg = 0; /* allow */ + if (src & ~reg) { + if (src & 0xfffffc00) { + EXCEPTION(GP_EXCEPTION, 0); + } + ia32_warning("MOV_CdRd: CR4 <- 0x%08x", src); + } + + reg = CPU_CR0; + CPU_CR4 = src; + + if ((reg ^ CPU_CR4) & (CPU_CR4_PSE|CPU_CR4_PGE|CPU_CR4_PAE)) { + tlb_flush(FALSE); + } + break; + + default: + ia32_panic("MOV_CdRd: CR reg index (%d)", idx); + /*NOTREACHED*/ + break; + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_RdCd(void) +{ + DWORD *out; + DWORD op; + + CPU_WORKCLOCK(11); + PREPART_EA_REG32P(op, out); + if (op >= 0xc0) { + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + EXCEPTION(GP_EXCEPTION, 0); + } + + switch (op & 7) { + case 0: + *out = CPU_CR0; + break; + + case 2: + *out = CPU_CR2; + break; + + case 3: + *out = CPU_CR3; + break; + + case 4: + *out = CPU_CR4; + break; + + default: + ia32_panic("MOV_RdCd: CR reg index (%d)", op & 7); + /*NOTREACHED*/ + break; + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LMSW_Ew(DWORD op) +{ + DWORD src, madr; + + if (CPU_STAT_PM && CPU_STAT_CPL != 0) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + + CPU_CR0 &= ~0xfffffffe; /* can't switch back from protected mode */ + CPU_CR0 |= (src & 0xf); /* TS, EM, MP, PE */ + if ((src ^ CPU_CR0) & CPU_CR0_PE) { + change_pm(1); /* switch to protected mode */ + } +} + +void +SMSW_Ew(DWORD op) +{ + DWORD madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg16_b20[op]) = (WORD)CPU_CR0; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)CPU_CR0); + } +} + +void +SMSW_Ed(DWORD op) +{ + DWORD madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg32_b20[op]) = CPU_CR0; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)CPU_CR0); + } +} + +void +CLTS(void) +{ + + CPU_WORKCLOCK(2); + if (CPU_STAT_PM && CPU_STAT_CPL != 0) { + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_CR0 &= ~CPU_CR0_TS; +} + +void +ARPL_EwGw(void) +{ + DWORD op, src, dst, madr; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + + if ((dst & 3) < (src & 3)) { + dst &= ~3; + dst |= (src & 3); + CPU_FLAGL |= Z_FLAG; + } else { + CPU_FLAGL &= ~Z_FLAG; + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +/* + * DPL + */ +void +LAR_GwEw(void) +{ + selector_t sel; + WORD *out; + DWORD op; + int rv; + WORD selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_REG16_EA(op, selector, out, 5, 11); + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + if (sel.desc.s) { + if (!(sel.desc.u.seg.c && !sel.desc.u.seg.ec) && + ((sel.desc.dpl < CPU_STAT_CPL) || (sel.desc.dpl < sel.rpl))) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } else { + switch (sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_LDT: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_CALL_16: + case CPU_SYSDESC_TYPE_TASK: + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + case CPU_SYSDESC_TYPE_CALL_32: + break; + + default: + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + + *out = sel.desc.h & 0xff00; + CPU_FLAGL |= Z_FLAG; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LAR_GdEw(void) +{ + selector_t sel; + DWORD *out; + DWORD op; + int rv; + WORD selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_REG32_EA(op, selector, out, 5, 11); + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + if (sel.desc.s) { + if (!(sel.desc.u.seg.c && !sel.desc.u.seg.ec) + && ((sel.desc.dpl < CPU_STAT_CPL) || (sel.desc.dpl < sel.rpl))) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } else { + switch (sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_LDT: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_CALL_16: + case CPU_SYSDESC_TYPE_TASK: + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + case CPU_SYSDESC_TYPE_CALL_32: + break; + + default: + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + + *out = sel.desc.h & 0x00ffff00; /* 0x00fxff00, x? */ + CPU_FLAGL |= Z_FLAG; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LSL_GwEw(void) +{ + selector_t sel; + WORD *out; + DWORD op; + int rv; + WORD selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_REG16_EA(op, selector, out, 5, 11); + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + if (sel.desc.s) { + if (!(sel.desc.u.seg.c && !sel.desc.u.seg.ec) + && ((sel.desc.dpl < CPU_STAT_CPL) || (sel.desc.dpl < sel.rpl))) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } else { + switch (sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_LDT: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + break; + + default: + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + + *out = (WORD)sel.desc.u.seg.limit; + CPU_FLAGL |= Z_FLAG; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LSL_GdEw(void) +{ + selector_t sel; + DWORD *out; + DWORD op; + int rv; + WORD selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_REG32_EA(op, selector, out, 5, 11); + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + if (sel.desc.s) { + if (!(sel.desc.u.seg.c && !sel.desc.u.seg.ec) + && ((CPU_STAT_CPL > sel.desc.dpl) || (sel.rpl > sel.desc.dpl))) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } else { + switch (sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_LDT: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + break; + + default: + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + + *out = sel.desc.u.seg.limit; + CPU_FLAGL |= Z_FLAG; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +VERR_Ew(DWORD op) +{ + selector_t sel; + DWORD madr; + int rv; + WORD selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + selector = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + selector = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + /* system segment */ + if (!sel.desc.s) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + /* non-conforming code segment && (CPL > DPL || RPL > DPL) */ + if ((sel.desc.u.seg.c && !sel.desc.u.seg.ec) + && ((CPU_STAT_CPL > sel.desc.dpl) || (sel.rpl > sel.desc.dpl))) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + /* code segment is not readable */ + if (sel.desc.u.seg.c && !sel.desc.u.seg.wr) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + CPU_FLAGL |= Z_FLAG; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +VERW_Ew(DWORD op) +{ + selector_t sel; + DWORD madr; + int rv; + WORD selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + selector = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + selector = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + /* system segment || code segment */ + if (!sel.desc.s || sel.desc.u.seg.c) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + /* data segment is not writable */ + if (sel.desc.u.seg.c && !sel.desc.u.seg.wr) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + /* privilege level */ + if ((CPU_STAT_CPL > sel.desc.dpl) || (sel.rpl > sel.desc.dpl)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + CPU_FLAGL |= Z_FLAG; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_DdRd(void) +{ + + ia32_panic("MOV_DdRd: not implemented yet!"); +} + +void +MOV_RdDd(void) +{ + + ia32_panic("MOV_DdRd: not implemented yet!"); +} + +void +INVD(void) +{ + + CPU_WORKCLOCK(11); + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + EXCEPTION(GP_EXCEPTION, 0); + } + /* nothing to do */ +} + +void +WBINVD(void) +{ + + CPU_WORKCLOCK(11); + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + EXCEPTION(GP_EXCEPTION, 0); + } + /* nothing to do */ +} + +void +INVLPG(DWORD op) +{ + DWORD madr; + + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + EXCEPTION(GP_EXCEPTION, 0); + } + + if (op < 0xc0) { + CPU_WORKCLOCK(11); + madr = get_ea(op); + tlb_flush_page(madr); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +_LOCK(void) +{ + + /* Nothing to do */ +} + +void +HLT(void) +{ + + if (CPU_STAT_PM && CPU_STAT_CPL != 0) { + EXCEPTION(GP_EXCEPTION, 0); + } + + CPU_HALT(); + CPU_EIP--; +} + +void +RSM(void) +{ + + ia32_panic("RSM: not implemented yet!"); +} + +void +RDMSR(void) +{ + +#if 1 + EXCEPTION(UD_EXCEPTION, 0); +#else + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + EXCEPTION(GP_EXCEPTION, 0); + } +#endif +} + +void +WRMSR(void) +{ + +#if 1 + EXCEPTION(UD_EXCEPTION, 0); +#else + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + EXCEPTION(GP_EXCEPTION, 0); + /* MTRR 、リ、ホス、ュケ、゚サ tlb_flush(FALSE) */ + } +#endif +} + +void +RDTSC(void) +{ + + ia32_panic("RDTSC: not implemented yet!"); +} + +void +MOV_TdRd(void) +{ + + ia32_panic("MOV_TdRd: not implemented yet!"); +} + +void +MOV_RdTd(void) +{ + + ia32_panic("MOV_RdTd: not implemented yet!"); +} diff --git a/i386c/ia32/instructions/system_inst.h b/i386c/ia32/instructions/system_inst.h new file mode 100644 index 00000000..1d25b2df --- /dev/null +++ b/i386c/ia32/instructions/system_inst.h @@ -0,0 +1,112 @@ +/* $Id: system_inst.h,v 1.1 2003/12/08 00:55:32 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SYSTEM_H__ +#define IA32_CPU_INSTRUCTION_SYSTEM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* load gdtr */ +void LGDT16_Ms(DWORD op); +void LGDT32_Ms(DWORD op); +void SGDT16_Ms(DWORD op); +void SGDT32_Ms(DWORD op); +void LLDT_Ew(DWORD op); +void SLDT_Ew(DWORD op); +void SLDT_Ed(DWORD op); +void LTR_Ew(DWORD op); +void STR_Ew(DWORD op); +void STR_Ed(DWORD op); + +/* load idtr */ +void LIDT16_Ms(DWORD op); +void LIDT32_Ms(DWORD op); +void SIDT16_Ms(DWORD op); +void SIDT32_Ms(DWORD op); + +/* ctrl reg */ +void MOV_CdRd(void); +void MOV_RdCd(void); + +/* msw */ +void LMSW_Ew(DWORD op); +void SMSW_Ew(DWORD op); +void SMSW_Ed(DWORD op); + +/* */ +void CLTS(void); +void ARPL_EwGw(void); + +/* dpl */ +void LAR_GwEw(void); +void LAR_GdEw(void); +void LSL_GwEw(void); +void LSL_GdEw(void); + +/* */ +void VERR_Ew(DWORD op); +void VERW_Ew(DWORD op); + +/* dbg reg */ +void MOV_DdRd(void); +void MOV_RdDd(void); + +/* cache */ +void INVD(void); +void WBINVD(void); + +/* */ +void INVLPG(DWORD op); + +/* */ +void _LOCK(void); +void HLT(void); + +/* ctrl reg */ +void RSM(void); + +/* msr */ +void RDMSR(void); +void WRMSR(void); + +/* ctrl reg */ +void RDTSC(void); + +/* test reg */ +void MOV_TdRd(void); +void MOV_RdTd(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_INSTRUCTION_SYSTEM_H__ */ diff --git a/i386c/ia32/interface.c b/i386c/ia32/interface.c new file mode 100644 index 00000000..84d36784 --- /dev/null +++ b/i386c/ia32/interface.c @@ -0,0 +1,214 @@ +/* $Id: interface.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" +#include "dmap.h" +#include "bios.h" + + +void +ia32reset(void) +{ +// cpu_init(); +#ifdef USE_FPU // ->ia32_init +// fpu_init(); +#endif + + CPU_SET_SEGREG(CPU_CS_INDEX, 0x1fc0); +} + +void +ia32(void) +{ + int rv; + + rv = sigsetjmp(exec_1step_jmpbuf, 1); + switch (rv) { + case 0: + break; + + default: + CPU_EIP = CPU_PREV_EIP; + break; + } + + do { + exec_1step(); + } while (CPU_REMCLOCK > 0); +} + +void +ia32withtrap(void) +{ + int rv; + + rv = sigsetjmp(exec_1step_jmpbuf, 1); + switch (rv) { + case 0: + break; + + default: + CPU_EIP = CPU_PREV_EIP; + break; + } + + + do { + exec_1step(); + if (CPU_TRAP) { + ia32_interrupt(1); + } + } while (CPU_REMCLOCK > 0); +} + +void +ia32withdma(void) +{ + int rv; + + rv = sigsetjmp(exec_1step_jmpbuf, 1); + switch (rv) { + case 0: + break; + + default: + CPU_EIP = CPU_PREV_EIP; + break; + } + + + do { + exec_1step(); + dmap_i286(); + } while (CPU_REMCLOCK > 0); +} + +void +ia32_step(void) +{ + int rv; + + rv = sigsetjmp(exec_1step_jmpbuf, 1); + switch (rv) { + case 0: + break; + + default: + CPU_EIP = CPU_PREV_EIP; + break; + } + + + do { + exec_1step(); + if (CPU_TRAP) { + ia32_interrupt(1); + } + dmap_i286(); + } while (CPU_REMCLOCK > 0); +} + +void CPUCALL +ia32_interrupt(BYTE vect) +{ + + INTERRUPT(vect, 0, 0, 0); +} + +/* + * error function + */ +void +ia32_panic(const char *str, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + strcat(buf, "\n"); + + fprintf(stderr, buf); + __ASSERT(0); + exit(1); +} + +void +ia32_warning(const char *str, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + strcat(buf, "\n"); + + fprintf(stderr, buf); +} + +void +ia32_printf(const char *str, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + + fprintf(stderr, buf); +} + +/* + * bios call interface + */ +void +ia32_bioscall(void) +{ + + /* XXX */ + if (!CPU_STAT_PM && !CPU_INST_OP32 && !CPU_INST_AS32) { + DWORD adrs; + WORD sreg; + + adrs = ((CPU_IP-1) & 0xffff) + CPU_STAT_SREGBASE(CPU_CS_INDEX); + if ((adrs >= 0xf8000) && (adrs < 0x100000)) { + biosfunc(adrs); + sreg = CPU_ES; + CPU_SET_SEGREG(CPU_ES_INDEX, sreg); + sreg = CPU_CS; + CPU_SET_SEGREG(CPU_CS_INDEX, sreg); + sreg = CPU_SS; + CPU_SET_SEGREG(CPU_SS_INDEX, sreg); + sreg = CPU_DS; + CPU_SET_SEGREG(CPU_DS_INDEX, sreg); + } + } +} diff --git a/i386c/ia32/interface.h b/i386c/ia32/interface.h new file mode 100644 index 00000000..e9f7a8f8 --- /dev/null +++ b/i386c/ia32/interface.h @@ -0,0 +1,138 @@ +/* $Id: interface.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INTERFACE_H__ +#define IA32_CPU_INTERFACE_H__ + +#if 0 // 、ウ、ホ、「、ソ、熙 compiler.h、リ +#include "compiler.h" + +#include +#include + +#include "memory.h" +#include "nevent.h" +#include "iobridge.h" + +#include "bios.h" +#include "cpuio.h" +#include "dmac.h" + +#if defined(_DEBUG) +#define ASSERT(v) assert(v) +#define VERBOSE(v) ia32_warning v +#else +#define ASSERT(v) +#define VERBOSE(v) +#endif +#endif + +// --> 、「、ネ、ヌ common.h、リ +#ifndef INLINE +#define INLINE +#endif + +#if 1 // 、ウ、 SINT64/UINT64 、コ、、ウ、ネ +typedef unsigned __int64 QWORD; +typedef signed __int64 SQWORD; +#else +typedef unsigned long long QWORD; +typedef signed long long SQWORD; +#endif + +typedef signed char SBYTE; +typedef signed short SWORD; +typedef signed int SDWORD; + +#if 0 +#define I286_AL CPU_AL +#define I286_CL CPU_CL +#define I286_DL CPU_DL +#define I286_BL CPU_BL +#define I286_AH CPU_AH +#define I286_CH CPU_CH +#define I286_DH CPU_DH +#define I286_BH CPU_BH + +#define I286_AX CPU_AX +#define I286_CX CPU_CX +#define I286_DX CPU_DX +#define I286_BX CPU_BX +#define I286_SP CPU_SP +#define I286_BP CPU_BP +#define I286_SI CPU_SI +#define I286_DI CPU_DI +#define I286_IP CPU_IP + +#define I286_EAX CPU_EAX +#define I286_ECX CPU_ECX +#define I286_EDX CPU_EDX +#define I286_EBX CPU_EBX +#define I286_ESP CPU_ESP +#define I286_EBP CPU_EBP +#define I286_ESI CPU_ESI +#define I286_EDI CPU_EDI +#define I286_EIP CPU_EIP + +#define I286_ES CPU_ES +#define I286_CS CPU_CS +#define I286_SS CPU_SS +#define I286_DS CPU_DS +#define I286_FS CPU_FS +#define I286_GS CPU_GS + +#define I286_EFLAG CPU_EFLAG +#define I286_FLAG CPU_FLAG +#define I286_FLAGL CPU_FLAGL +#define I286_FLAGH CPU_FLAGH +#define I286_TRAP CPU_TRAP +#define I286_INPORT CPU_INPORT +#define I286_OV CPU_OV +#define i286s cpu_stat +#endif + +#define CPU_isDI (!(CPU_FLAG & I_FLAG)) +#define CPU_isEI (CPU_FLAG & I_FLAG) + +#define CPU_INITIALIZE() i386c_initialize() +#define CPU_RESET() ia32reset() +#define CPU_CLEARPREFETCH() +#define CPU_INTERRUPT(a) ia32_interrupt(a) +#define CPU_EXEC() ia32() +#define CPU_EXECV30() ia32() + +// #define CPU_WITHTRAP() ia32withtrap() +// #define CPU_WITHDMA() ia32withdma() +// #define CPU_STEP() ia32_step() + +void FASTCALL msgbox_str(char *msg); +void FASTCALL msgbox_mem(DWORD no); +void put_cpuinfo(void); + +#endif /* IA32_CPU_INTERFACE_H__ */ diff --git a/i386c/ia32/paging.c b/i386c/ia32/paging.c new file mode 100644 index 00000000..da472408 --- /dev/null +++ b/i386c/ia32/paging.c @@ -0,0 +1,762 @@ +/* $Id: paging.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +/* + * ・レ。シ・ク。ヲ・ヌ・」・・ッ・ネ・遙ヲ・ィ・・ネ・ (4K ・ミ・、・ネ・レ。シ・クサネヘムサ) + * + * 31 12 11 9 8 7 6 5 4 3 2 1 0 + * +----------------------------------------+------+-+--+-+-+---+---+---+---+-+ + * | ・レ。シ・ク。ヲ・ニ。シ・ヨ・、ホ・ル。シ・ケ。ヲ・「・ノ・・ケ |サネヘムイト|G|PS|0|A|PCD|PWT|U/S|R/W|P| + * +----------------------------------------+------+-+--+-+-+---+---+---+---+-+ + * | | | | | | | | | | + * 9-11: ・キ・ケ・ニ・爍ヲ・ラ・・ー・鬣゙、ャサネヘムイトヌス --------+ | | | | | | | | | + * 8: ・ー・。シ・ミ・。ヲ・レ。シ・ク(フオサ、オ、、) ------------+ | | | | | | | | + * 7: ・レ。シ・ク。ヲ・オ・、・コ (0 = 4k ・ミ・、・ネ・レ。シ・ク) ---------+ | | | | | | | + * 6: ヘスフ (0) ---------------------------------------+ | | | | | | + * 5: ・「・ッ・サ・ケ -----------------------------------------+ | | | | | + * 4: ・ュ・罕テ・キ・衫オク --------------------------------------+ | | | | + * 3: ・鬣、・ネ・ケ・。シ --------------------------------------------+ | | | + * 2: ・譯シ・カ。ソ・ケ。シ・ム・ミ・、・カ (0 = ・ケ。シ・ム・ミ・、・カ) ---------------------+ | | + * 1: ニノ、゚シ隍遙ソス、ュケ、゚ (0 = ニノ、゚シ隍熙ホ、゚) ---------------------------+ | + * 0: ・レ。シ・クツクコ゚ ---------------------------------------------------------+ + */ +#define CPU_PDE_BASEADDR_MASK 0xfffff000 +#define CPU_PDE_PAGE_SIZE (1 << 7) +#define CPU_PDE_ACCESS (1 << 5) +#define CPU_PDE_CACHE_DISABLE (1 << 4) +#define CPU_PDE_WRITE_THROUGH (1 << 3) +#define CPU_PDE_USER_MODE (1 << 2) +#define CPU_PDE_WRITABLE (1 << 1) +#define CPU_PDE_PRESENT (1 << 0) + +/* + * ・レ。シ・ク。ヲ・ヌ・」・・ッ・ネ・遙ヲ・ィ・・ネ・ (4M ・ミ・、・ネ・レ。シ・クサネヘムサ) + * + * 31 22 21 12 11 9 8 7 6 5 4 3 2 1 0 + * +----------------------------+-----------+------+-+--+-+-+---+---+---+---+-+ + * |・レ。シ・ク・ニ。シ・ヨ・、ホハェヘ・「・ノ・・ケ| ヘスフコム、゚ |サネヘムイト|G|PS|D|A|PCD|PWT|U/S|R/W|P| + * +----------------------------+-----------+------+-+--+-+-+---+---+---+---+-+ + * | | | | | | | | | | + * 9-11: ・キ・ケ・ニ・爍ヲ・ラ・・ー・鬣゙、ャサネヘムイトヌス --------+ | | | | | | | | | + * 8: ・ー・。シ・ミ・。ヲ・レ。シ・ク ------------------------+ | | | | | | | | + * 7: ・レ。シ・ク。ヲ・オ・、・コ (1 = 4M ・ミ・、・ネ・レ。シ・ク) ---------+ | | | | | | | + * 6: ・タ。シ・ニ・」 ---------------------------------------+ | | | | | | + * 5: ・「・ッ・サ・ケ -----------------------------------------+ | | | | | + * 4: ・ュ・罕テ・キ・衫オク --------------------------------------+ | | | | + * 3: ・鬣、・ネ・ケ・。シ --------------------------------------------+ | | | + * 2: ・譯シ・カ。ソ・ケ。シ・ム・ミ・、・カ (0 = ・ケ。シ・ム・ミ・、・カ) ---------------------+ | | + * 1: ニノ、゚シ隍遙ソス、ュケ、゚ (0 = ニノ、゚シ隍熙ホ、゚) ---------------------------+ | + * 0: ・レ。シ・クツクコ゚ ---------------------------------------------------------+ + */ +#define CPU_PDE_4M_BASEADDR_MASK 0xffc00000 +#define CPU_PDE_4M_GLOBAL_PAGE (1 << 8) +#define CPU_PDE_4M_PAGE_SIZE (1 << 7) +#define CPU_PDE_4M_DIRTY (1 << 6) +#define CPU_PDE_4M_ACCESS (1 << 5) +#define CPU_PDE_4M_CACHE_DISABLE (1 << 4) +#define CPU_PDE_4M_WRITE_THROUGH (1 << 3) +#define CPU_PDE_4M_USER_MODE (1 << 2) +#define CPU_PDE_4M_WRITABLE (1 << 1) +#define CPU_PDE_4M_PRESENT (1 << 0) + +/* + * ・レ。シ・ク。ヲ・ニ。シ・ヨ・。ヲ・ィ・・ネ・ (4k ・ミ・、・ネ。ヲ・レ。シ・ク) + * + * 31 12 11 9 8 7 6 5 4 3 2 1 0 + * +----------------------------------------+------+-+-+-+-+---+---+---+---+-+ + * | ・レ。シ・ク、ホ・ル。シ・ケ。ヲ・「・ノ・・ケ |サネヘムイト|G|0|D|A|PCD|PWT|U/S|R/W|P| + * +----------------------------------------+------+-+-+-+-+---+---+---+---+-+ + * | | | | | | | | | | + * 9-11: ・キ・ケ・ニ・爍ヲ・ラ・・ー・鬣゙、ャサネヘムイトヌス -------+ | | | | | | | | | + * 8: ・ー・。シ・ミ・。ヲ・レ。シ・ク -----------------------+ | | | | | | | | + * 7: ヘスフ (0) -----------------------------------+ | | | | | | | + * 6: ・タ。シ・ニ・」 -------------------------------------+ | | | | | | + * 5: ・「・ッ・サ・ケ ---------------------------------------+ | | | | | + * 4: ・ュ・罕テ・キ・衫オク ------------------------------------+ | | | | + * 3: ・鬣、・ネ・ケ・。シ ------------------------------------------+ | | | + * 2: ・譯シ・カ。ソ・ケ。シ・ム・ミ・、・カ (0 = ・ケ。シ・ム・ミ・、・カ) -------------------+ | | + * 1: ニノ、゚シ隍遙ソス、ュケ、゚ (0 = ニノ、゚シ隍熙ホ、゚) -------------------------+ | + * 0: ・レ。シ・クツクコ゚ -------------------------------------------------------+ + */ +#define CPU_PTE_BASEADDR_MASK 0xfffff000 +#define CPU_PTE_GLOBAL_PAGE (1 << 8) +#define CPU_PTE_DIRTY (1 << 6) +#define CPU_PTE_ACCESS (1 << 5) +#define CPU_PTE_CACHE_DISABLE (1 << 4) +#define CPU_PTE_WRITE_THROUGH (1 << 3) +#define CPU_PTE_USER_MODE (1 << 2) +#define CPU_PTE_WRITABLE (1 << 1) +#define CPU_PTE_PRESENT (1 << 0) + +/* + * ・レ。シ・ク・ユ・ゥ・・ネホ羌ー + * + * 4-31: ヘスフコム、゚ + * 3: RSVD: 0 = ・ユ・ゥ・・ネ、ホクカー、マヘスフ・モ・テ・ネー翳ソ、ヌ、マ、ハ、ォ、テ、ソ。・ + * 1 = ・レ。シ・ク。ヲ・ユ・ゥ・・ネ、ホクカー、マ。、ー翳ソ、ネ・゙。シ・ッ、オ、、ソ PTE 、゙、ソ、マ + * PDE 、ホヘスフ・モ・テ・ネーフテヨ、ホ、ヲ、チー、ト、ヌ。、1 、ャク。スミ、オ、、ソ、ウ、ネ、ヌ、「、。・ + * 2: U/S: 0 = ・ユ・ゥ・・ネ、ホクカー、ネ、ハ、テ、ソ・「・ッ・サ・ケ、マ・ラ・・サ・テ・オ、ャ・ケ。シ・ム・ミ・、・カ。ヲ + * ・筍シ・ノ、ヌシツケヤテ讀ヒケヤ、、、ソ。・ + * 1 = ・ユ・ゥ・・ネ、ホクカー、ネ、ハ、テ、ソ・「・ッ・サ・ケ、マ・ラ・・サ・テ・オ、ャ・譯シ・カ。ヲ・筍シ・ノ、ヌ + * シツケヤテ讀ヒケヤ、、、ソ。・ + * 1: W/R: 0 = ・ユ・ゥ・・ネ、ホクカー、ネ、ハ、テ、ソ・「・ッ・サ・ケ、ャニノ、゚シ隍熙ヌ、「、テ、ソ。・ + * 1 = ・ユ・ゥ・・ネ、ホクカー、ネ、ハ、テ、ソ・「・ッ・サ・ケ、ャス、ュケ、゚、ヌ、「、テ、ソ。・ + * 0: P: 0 = ・ユ・ゥ・・ネ、ホクカー、ャノヤコ゚・レ。シ・ク、ヌ、「、テ、ソ。・ + * 1 = ・ユ・ゥ・・ネ、ホクカー、ャ・レ。シ・ク。ヲ・・ル・ハンクー翳ソ、ヌ、「、テ、ソ。・ + */ + +/* + * イシエャ 4.12. ・レ。シ・クハンク、ネ・サ・ー・皈・ネハンク、ホチネ、゚ケ遉、サ + * 。ヨノス 4-2. ・レ。シ・ク。ヲ・ヌ・」・・ッ・ネ・熙ネ・レ。シ・ク。ヲ・ニ。シ・ヨ・、ホハンク、ホチネ、゚ケ遉、サ。ラ + * + * +------------+------------+------------+ + * | PDE | PTE | merge | + * +-----+------+-----+------+-----+------+ + * | pri | type | pri | type | pri | type | + * +-----+------+-----+------+-----+------+ + * | u | ro | u | ro | u | ro | + * | u | ro | u | rw | u | ro | + * | u | rw | u | ro | u | ro | + * | u | rw | u | rw | u | rw | + * | u | ro | s | ro | s | rw/p | + * | u | ro | s | rw | s | rw/p | + * | u | rw | s | ro | s | rw/p | + * | u | rw | s | rw | s | rw | + * | s | ro | u | ro | s | rw/p | + * | s | ro | u | rw | s | rw/p | + * | s | rw | u | ro | s | rw/p | + * | s | rw | u | rw | s | rw | + * | s | ro | s | ro | s | rw/p | + * | s | ro | s | rw | s | rw/p | + * | s | rw | s | ro | s | rw/p | + * | s | rw | s | rw | s | rw | + * +-----+------+-----+------+-----+------+ + * + * 「ィ rw/p : CR0 、ホ WP ・モ・テ・ネ、ャ ON 、ホセケ遉ヒ、マ ro + */ + +/* + * ・皈筵・「・ッ・サ・ケ/PxE(セ蠏ュサイセネ)/CPL/CR0 、ネ・レ。シ・ク・「・ッ・サ・ケク「、ホエリキク + * + * +-----+-----+-----+-----+-----+---+ + * | CR0 | CPL | PxE | PxE | ope | | + * | W/P | u/s | u/s | r/w | r/w | | + * +-----+-----+-----+-----+-----+---+ + * | n/a | s | s | n/a | r | o | + * | n/a | s | u | n/a | r | o | + * | n/a | u | s | n/a | r | x | + * | n/a | u | u | n/a | r | o | + * +-----+-----+-----+-----+-----+---+ + * | n | s | s | r | w | o | + * | n | s | u | r | w | o | + * | n | u | s | r | w | x | + * | n | u | u | r | w | x | + * +-----+-----+-----+-----+-----+---+ + * | p | s | s | r | w | x | + * | p | s | u | r | w | x | + * | p | u | s | r | w | x | + * | p | u | u | r | w | x | + * +-----+-----+-----+-----+-----+---+ + * | n | s | s | w | w | o | + * | n | s | u | w | w | o | + * | n | u | s | w | w | x | + * | n | u | u | w | w | o | + * +-----+-----+-----+-----+-----+---+ + * | p | s | s | w | w | o | + * | p | s | u | w | w | x | + * | p | u | s | w | w | x | + * | p | u | u | w | w | o | + * +-----+-----------+-----+-----+---+ + */ +#if !defined(USE_PAGE_ACCESS_TABLE) +static const DWORD page_access = 0xd0cdd0ff; +#else /* USE_PAGE_ACCESS_TABLE */ +static const BYTE page_access_bit[32] = { + 1, /* CR0: n, CPL: s, PTE: s, PTE: r, ope: r */ + 1, /* CR0: n, CPL: s, PTE: s, PTE: r, ope: w */ + 1, /* CR0: n, CPL: s, PTE: s, PTE: w, ope: r */ + 1, /* CR0: n, CPL: s, PTE: s, PTE: w, ope: w */ + + 1, /* CR0: n, CPL: s, PTE: u, PTE: r, ope: r */ + 1, /* CR0: n, CPL: s, PTE: u, PTE: r, ope: w */ + 1, /* CR0: n, CPL: s, PTE: u, PTE: w, ope: r */ + 1, /* CR0: n, CPL: s, PTE: u, PTE: w, ope: w */ + + 0, /* CR0: n, CPL: u, PTE: s, PTE: r, ope: r */ + 0, /* CR0: n, CPL: u, PTE: s, PTE: r, ope: w */ + 0, /* CR0: n, CPL: u, PTE: s, PTE: w, ope: r */ + 0, /* CR0: n, CPL: u, PTE: s, PTE: w, ope: w */ + + 1, /* CR0: n, CPL: u, PTE: u, PTE: r, ope: r */ + 0, /* CR0: n, CPL: u, PTE: u, PTE: r, ope: w */ + 1, /* CR0: n, CPL: u, PTE: u, PTE: w, ope: r */ + 1, /* CR0: n, CPL: u, PTE: u, PTE: w, ope: w */ + + 1, /* CR0: p, CPL: s, PTE: s, PTE: r, ope: r */ + 0, /* CR0: p, CPL: s, PTE: s, PTE: r, ope: w */ + 1, /* CR0: p, CPL: s, PTE: s, PTE: w, ope: r */ + 1, /* CR0: p, CPL: s, PTE: s, PTE: w, ope: w */ + + 1, /* CR0: p, CPL: s, PTE: u, PTE: r, ope: r */ + 0, /* CR0: p, CPL: s, PTE: u, PTE: r, ope: w */ + 1, /* CR0: p, CPL: s, PTE: u, PTE: w, ope: r */ + 0, /* CR0: p, CPL: s, PTE: u, PTE: w, ope: w */ + + 0, /* CR0: p, CPL: u, PTE: s, PTE: r, ope: r */ + 0, /* CR0: p, CPL: u, PTE: s, PTE: r, ope: w */ + 0, /* CR0: p, CPL: u, PTE: s, PTE: w, ope: r */ + 0, /* CR0: p, CPL: u, PTE: s, PTE: w, ope: w */ + + 1, /* CR0: p, CPL: u, PTE: u, PTE: r, ope: r */ + 0, /* CR0: p, CPL: u, PTE: u, PTE: r, ope: w */ + 1, /* CR0: p, CPL: u, PTE: u, PTE: w, ope: r */ + 1, /* CR0: p, CPL: u, PTE: u, PTE: w, ope: w */ +}; +#endif /* !USE_PAGE_ACCESS_TABLE */ + +/* + *-- + * 32bit ハェヘ・「・ノ・・ケ 4k ・レ。シ・ク + * + * ・・ヒ・「。ヲ・「・ノ・・ケ + * 31 22 21 12 11 0 + * +------------------------+----------------------+--------------------------+ + * | ・レ。シ・ク。ヲ・ヌ・」・・ッ・ネ・ | ・レ。シ・ク。ヲ・ニ。シ・ヨ・ | ・ェ・ユ・サ・テ・ネ | + * +------------------------+----------------------+--------------------------+ + * | | | + * +-----------+ +-----------+ +----------+ + * | | | + * | ・レ。シ・ク。ヲ・ヌ・」・・ッ・ネ・ | ・レ。シ・ク。ヲ・ニ。シ・ヨ・ ・レ。シ・ク | + * | +--------------------+ | +-------------------+ +------------------+ | + * | | | | | | | | | + * | | | | +-------------------+ | | | + * | | | +>| page table entry |-+ | | | + * | +--------------------+ +-------------------+ | | | | + * +>|page directory entry|-+ | | | +------------------+ | + * +--------------------+ | | | | | physical address |<+ + * | | | | | | +------------------+ + * | | | | | | | | + * +>+--------------------+ +>+-------------------+ +>+------------------+ + * | + * +- CR3(ハェヘ・「・ノ・・ケ) + */ + +static DWORD paging(DWORD laddr, int crw, int user_mode); +static BOOL tlb_lookup(DWORD vaddr, int crw, DWORD* paddr); +static void tlb_update(DWORD paddr, DWORD entry, int crw); + + +DWORD MEMCALL +cpu_linear_memory_read(DWORD laddr, DWORD length, int code) +{ + DWORD paddr; + DWORD remain; /* page remain */ + DWORD r; + DWORD value = 0; + int crw; + int pl; + + crw = CPU_PAGING_PAGE_READ; + crw |= code ? CPU_PAGING_PAGE_CODE : CPU_PAGING_PAGE_DATA; + pl = (CPU_STAT_CPL == 3); + + /* XXX: 4MB pages... */ + remain = 0x1000 - (laddr & 0x00000fff); + for (;;) { + paddr = paging(laddr, crw, pl); + + r = (remain > length) ? length : remain; + switch (r) { + case 1: + value = (value << 8) | cpu_memoryread(paddr); + break; + + case 2: + value = (value << 16) | cpu_memoryread_w(paddr); + break; + + case 3: + value <<= 24; + value |= cpu_memoryread_w(paddr) << 8; + value |= cpu_memoryread(paddr + 2); + break; + + case 4: + value = cpu_memoryread_d(paddr); + break; + + default: + ia32_panic("cpu_linear_memory_read(): out of range\n"); + break; + } + + if (length == r) + break; + + length -= r; + remain -= r; + laddr += r; + } + + return value; +} + +void MEMCALL +cpu_linear_memory_write(DWORD laddr, DWORD length, DWORD value) +{ + DWORD paddr; + DWORD remain; /* page remain */ + DWORD r; + int pl; + + pl = (CPU_STAT_CPL == 3); + + /* XXX: 4MB pages... */ + remain = 0x1000 - (laddr & 0x00000fff); + for (;;) { + paddr = paging(laddr, CPU_PAGING_PAGE_WRITE|CPU_PAGING_PAGE_DATA, pl); + + r = (remain > length) ? length : remain; + switch (r) { + case 1: + cpu_memorywrite(paddr, value); + value >>= 8; + break; + + case 2: + cpu_memorywrite_w(paddr, value); + value >>= 16; + break; + + case 3: + cpu_memorywrite_w(paddr, value); + cpu_memorywrite(paddr, value >> 16); + value >>= 24; + break; + + case 4: + cpu_memorywrite_d(paddr, value); + break; + + default: + ia32_panic("cpu_linear_memory_write(): out of range\n"); + break; + } + + if (length == r) + break; + + length -= r; + remain -= r; + laddr += r; + } +} + +void MEMCALL +paging_check(DWORD laddr, DWORD length, int rw) +{ + DWORD addr; + int n; + int pl; + + pl = (CPU_STAT_CPL == 3); + + /* XXX: 4MB pages... */ + n = ((laddr & 0xfff) + length) / 0x1000; + addr = (laddr & ~0xfff); + do { + (void)paging(addr, rw, pl); + addr += 0x1000; + } while (--n > 0); +} + +static DWORD +paging(DWORD laddr, int crw, int user_mode) +{ + DWORD paddr; /* physical address */ + DWORD pde_addr; /* page directory entry address */ + DWORD pde; /* page directory entry */ + DWORD pte_addr; /* page table entry address */ + DWORD pte; /* page table entry */ + DWORD bit; + DWORD err = 0; + +#if defined(IA32_SUPPORT_TLB) + if (tlb_lookup(laddr, crw, &paddr)) + return paddr; +#endif /* IA32_SUPPORT_TLB */ + + pde_addr = (CPU_CR3 & CPU_CR3_PD_MASK) | ((laddr >> 20) & 0xffc); + pde = cpu_memoryread_d(pde_addr); + if (!(pde & CPU_PDE_PRESENT)) { + err = 0; + goto pf_exception; + } + if (!(pde & CPU_PDE_ACCESS)) { + pde |= CPU_PDE_ACCESS; + cpu_memorywrite_d(pde_addr, pde); + } + + /* no support PAE */ + __ASSERT(!(CPU_CR4 & CPU_CR4_PAE)); + + if ((CPU_CR4 & CPU_CR4_PSE) && (pde & CPU_PDE_PAGE_SIZE)) { + /* 4MB page size */ + + /* fake PTE bit */ + pte = pde | CPU_PTE_DIRTY; + pte_addr = 0; /* compiler happy */ + + /* make physical address */ + paddr = (pde & CPU_PDE_4M_BASEADDR_MASK) | (laddr & 0x003fffff); + } else { + /* 4KB page size */ + pte_addr = (pde & CPU_PDE_BASEADDR_MASK) | ((laddr >> 10) & 0xffc); + pte = cpu_memoryread_d(pte_addr); + if (!(pte & CPU_PTE_PRESENT)) { + err = 0; + goto pf_exception; + } + if (!(pte & CPU_PTE_ACCESS)) { + pte |= CPU_PTE_ACCESS; + cpu_memorywrite_d(pte_addr, pte); + } + + /* make physical address */ + paddr = (pte & CPU_PTE_BASEADDR_MASK) | (laddr & 0x00000fff); + } + + bit = crw & 1; + bit |= (pde & pte & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE)); + bit |= (user_mode << 3); + bit |= (CPU_CR0 & CPU_CR0_WP) >> 12; + +#if !defined(USE_PAGE_ACCESS_TABLE) + if (!(page_access & (1 << bit))) +#else + if (!(page_access_bit[bit])) +#endif + { + err = 1; + goto pf_exception; + } + + if ((crw & 1) && !(pte & CPU_PTE_DIRTY)) { + pte |= CPU_PTE_DIRTY; + cpu_memorywrite_d(pte_addr, pte); + } + +#if defined(IA32_SUPPORT_TLB) + tlb_update(paddr, pte, crw); +#endif /* IA32_SUPPORT_TLB */ + + return paddr; + +pf_exception: + CPU_CR2 = laddr; + err |= ((crw & 1) << 1) | (user_mode << 2); + EXCEPTION(PF_EXCEPTION, err); + return 0; /* compiler happy */ +} + +#if defined(IA32_SUPPORT_TLB) +/* + * TLB + */ +typedef struct { + BYTE valid; /* TLB entry is valid */ + BYTE global; /* this TLB entry is global */ + BYTE score; + BYTE pad; + + DWORD tag; + DWORD mask; /* 4K or 2M or 4M */ + + DWORD paddr; /* physical addr */ +} TLB_ENTRY_T; + +typedef struct { + BYTE kind; +#define TLB_KIND_INSTRUCTION (1 << 1) +#define TLB_KIND_DATA (1 << 2) +#define TLB_KIND_COMBINE (TLB_KIND_INSTRUCTION|TLB_KIND_DATA) +#define TLB_KIND_SMALL (1 << 3) +#define TLB_KIND_LARGE (1 << 4) +#define TLB_KIND_BOTH (TLB_KIND_SMALL|TLB_KIND_LARGE) + + BYTE way; /* n-way associative */ + BYTE idx; /* number of TLB index */ + BYTE bpad; + + WORD num; /* number of TLB entry */ + WORD wpad; + + TLB_ENTRY_T* entry; /* entry[assoc][idx] or entry[assoc] if idx == 1*/ +} TLB_T; + +static int ntlb; +static TLB_T tlb[4]; /* i TLB, i (lp) TLB, d TLB, d (lp) TLB */ + +#if defined(IA32_PROFILE_TLB) +/* profiling */ +static DWORD tlb_hits; +static DWORD tlb_misses; +static DWORD tlb_lookups; +static DWORD tlb_updates; +static DWORD tlb_flushes; +static DWORD tlb_global_flushes; +static DWORD tlb_entry_flushes; + +#define PROFILE_INC(v) (v)++; +#else /* !IA32_PROFILE_TLB */ +#define PROFILE_INC(v) +#endif /* IA32_PROFILE_TLB */ + +void +tlb_init() +{ + int i; + + for (i = 0; i < NELEMENTS(tlb); i++) { + if (tlb[i].entry) { + free(tlb[i].entry); + } + } + memset(tlb, 0, sizeof(tlb)); + +#if defined(IA32_PROFILE_TLB) + tlb_hits = 0; + tlb_misses = 0; + tlb_lookups = 0; + tlb_updates = 0; + tlb_flushes = 0; + tlb_global_flushes = 0; + tlb_entry_flushes = 0; +#endif /* IA32_PROFILE_TLB */ + + /* XXX ・ラ・・サ・テ・オシハフ、ヒ、キ、ソ、ャ、テ、ニ TLB ケスタョ、ケステロ、ケ、 */ + + /* 、ネ、熙「、ィ、コ i486 キチシー、ヌ。ト */ + /* combine (I/D) TLB: 4KB Pages, 4-way set associative 32 entries */ + ntlb = 1; + tlb[0].kind = TLB_KIND_COMBINE | TLB_KIND_SMALL; + tlb[0].num = 32; + tlb[0].way = 4; + tlb[0].idx = tlb[0].num / tlb[0].way; + + for (i = 0; i < ntlb; i++) { + tlb[i].entry = (TLB_ENTRY_T*)calloc(sizeof(TLB_ENTRY_T), tlb[i].num); + if (tlb[i].entry == 0) { + ia32_panic("tlb_init(): can't alloc TLB entry\n"); + } + } +} + +void +tlb_flush(BOOL allflush) +{ + TLB_ENTRY_T* ep; + int i, j; + + if (allflush) { + PROFILE_INC(tlb_global_flushes); + } else { + PROFILE_INC(tlb_flushes); + } + + for (i = 0; i < ntlb; i++) { + ep = tlb[i].entry; + for (j = 0; j < tlb[i].num; j++, ep++) { + if (ep->valid && (allflush || !ep->global)) { + ep->valid = 0; + PROFILE_INC(tlb_entry_flushes); + } + } + } +} + +void +tlb_flush_page(DWORD vaddr) +{ + TLB_ENTRY_T* ep; + int idx; + int i; + + for (i = 0; i < ntlb; i++) { + if (tlb[i].idx == 1) { + /* fully set associative */ + idx = 0; + } else { + if (tlb[i].kind & TLB_KIND_SMALL) { + idx = (vaddr >> 12) & (tlb[i].idx - 1); + } else { + idx = (vaddr >> 22) & (tlb[i].idx - 1); + } + } + + /* search */ + ep = &tlb[i].entry[idx * tlb[i].way]; + for (i = 0; i < tlb[i].way; i++) { + if (ep->valid) { + if ((vaddr & ep->mask) == ep->tag) { + ep->valid = 0; + PROFILE_INC(tlb_entry_flushes); + break; + } + } + } + } +} + +BOOL +tlb_lookup(DWORD vaddr, int crw, DWORD* paddr) +{ + TLB_ENTRY_T* ep; + int idx; + int i; + + PROFILE_INC(tlb_lookups); + + crw &= CPU_PAGING_PAGE_CODE | CPU_PAGING_PAGE_DATA; + for (i = 0; i < ntlb; i++) { + if (tlb[i].kind & crw) { + if (tlb[i].idx == 1) { + /* fully set associative */ + idx = 0; + } else { + if (tlb[i].kind & TLB_KIND_SMALL) { + idx = (vaddr >> 12) & (tlb[i].idx - 1); + } else { + idx = (vaddr >> 22) & (tlb[i].idx - 1); + } + } + + /* search */ + ep = &tlb[i].entry[idx * tlb[i].way]; + for (i = 0; i < tlb[i].way; i++) { + if (ep->valid) { + if ((vaddr & ep->mask) == ep->tag) { + if (ep->score != (BYTE)~0) + ep->score++; + *paddr = ep->paddr; + PROFILE_INC(tlb_hits); + return TRUE; + } + } + } + } + } + PROFILE_INC(tlb_misses); + return FALSE; +} + +void +tlb_update(DWORD paddr, DWORD entry, int crw) +{ + TLB_ENTRY_T* ep; + int idx; + int i, j; + int min_way; + WORD min_score = ~0; + + PROFILE_INC(tlb_updates); + + crw &= CPU_PAGING_PAGE_CODE | CPU_PAGING_PAGE_DATA; + for (i = 0; i < ntlb; i++) { + if (tlb[i].kind & crw) { + if (tlb[i].idx == 1) { + /* fully set associative */ + idx = 0; + } else { + /* n-way set associative */ + if (!(entry & CPU_PDE_PAGE_SIZE)) { + if (!(tlb[i].kind & TLB_KIND_SMALL)) + continue; + idx = (entry >> 12) & (tlb[i].idx - 1); + } else { + if (!(tlb[i].kind & TLB_KIND_LARGE)) + continue; + idx = (entry >> 22) & (tlb[i].idx - 1); + } + } + + /* search */ + ep = &tlb[i].entry[idx * tlb[i].way]; + for (min_way = 0, j = 0; j < tlb[i].way; j++, ep++) { + if (ep->valid) { + if (min_score >= ep->score) { + min_way = j; + min_score = ep->score; + } + } else { + min_way = j; + min_score = 0; + break; + } + } + + /* replace */ + ep = &tlb[i].entry[idx * tlb[i].way + min_way]; + ep->valid = 1; + ep->global = (entry & CPU_PTE_GLOBAL_PAGE) ? 1 : 0; + ep->score = 0; + ep->mask = (entry & CPU_PDE_PAGE_SIZE) ? CPU_PDE_4M_BASEADDR_MASK : CPU_PTE_BASEADDR_MASK; + ep->tag = entry & ep->mask; + ep->paddr = paddr; + break; + } + } + __ASSERT(i != ntlb); +} +#else /* !IA32_SUPPORT_TLB */ +void +tlb_init() +{ + + /* nothing to do */ +} + +void +tlb_flush(BOOL allflush) +{ + +// UNUSED(allflush); +} + +void +tlb_flush_page(DWORD vaddr) +{ + +// UNUSED(vaddr); +} +#endif /* IA32_SUPPORT_TLB */ diff --git a/i386c/ia32/paging.h b/i386c/ia32/paging.h new file mode 100644 index 00000000..3ed3a269 --- /dev/null +++ b/i386c/ia32/paging.h @@ -0,0 +1,106 @@ +/* $Id: paging.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_PAGING_H__ +#define IA32_CPU_PAGING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* enter/leave paging mode */ +void FASTCALL change_pg(int onoff); + +/* paging check */ +void MEMCALL paging_check(DWORD laddr, DWORD length, int rw); + +/* paging_check(): rw */ +#define CPU_PAGING_PAGE_READ (0 << 0) +#define CPU_PAGING_PAGE_WRITE (1 << 0) + +/* + * linear address function + */ +DWORD MEMCALL cpu_linear_memory_read(DWORD address, DWORD length, int code); +void MEMCALL cpu_linear_memory_write(DWORD address, DWORD length, DWORD value); + +/* cpu_linear_memory_read(): code */ +#define CPU_PAGING_PAGE_CODE (1 << 1) +#define CPU_PAGING_PAGE_DATA (1 << 2) + +#define cpu_lmemoryread(a) \ + (CPU_STAT_PAGING) ? \ + (BYTE)cpu_linear_memory_read(a, 1, FALSE) : \ + cpu_memoryread(a); +#define cpu_lmemoryread_w(a) \ + (CPU_STAT_PAGING) ? \ + (WORD)cpu_linear_memory_read(a, 2, FALSE) : \ + cpu_memoryread_w(a); +#define cpu_lmemoryread_d(a) \ + (CPU_STAT_PAGING) ? \ + cpu_linear_memory_read(a, 4, FALSE) : \ + cpu_memoryread_d(a); + +#define cpu_lmemorywrite(a,v) \ + (CPU_STAT_PAGING) ? \ + cpu_linear_memory_write(a, 1, v) : \ + cpu_memorywrite(a,v); +#define cpu_lmemorywrite_w(a,v) \ + (CPU_STAT_PAGING) ? \ + cpu_linear_memory_write(a, 2, v) : \ + cpu_memorywrite_w(a,v); +#define cpu_lmemorywrite_d(a,v) \ + (CPU_STAT_PAGING) ? \ + cpu_linear_memory_write(a, 4, v) : \ + cpu_memorywrite_d(a,v); + +#define cpu_lcmemoryread(a) \ + (CPU_STAT_PAGING) ? \ + (BYTE)cpu_linear_memory_read(a, 1, TRUE) : \ + cpu_memoryread(a); +#define cpu_lcmemoryread_w(a) \ + (CPU_STAT_PAGING) ? \ + (WORD)cpu_linear_memory_read(a, 2, TRUE) : \ + cpu_memoryread_w(a); +#define cpu_lcmemoryread_d(a) \ + (CPU_STAT_PAGING) ? \ + cpu_linear_memory_read(a, 4, TRUE) : \ + cpu_memoryread_d(a); + +/* + * TLB function + */ +void tlb_init(); +void tlb_flush(BOOL allflush); +void tlb_flush_page(DWORD vaddr); +#ifdef __cplusplus +} +#endif + +#endif /* !IA32_CPU_PAGING_H__ */ diff --git a/i386c/ia32/resolve.c b/i386c/ia32/resolve.c new file mode 100644 index 00000000..ef8223c1 --- /dev/null +++ b/i386c/ia32/resolve.c @@ -0,0 +1,634 @@ +/* $Id: resolve.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + + +static DWORD (*calc_ea_dst_tbl[0x100])(void); +static DWORD (*calc_ea32_dst_tbl[0x100])(void); + + +DWORD +calc_ea_dst(DWORD op) +{ + + if (!CPU_INST_AS32) + return ((*calc_ea_dst_tbl[op])() & 0xffff); + return (*calc_ea32_dst_tbl[op])(); +} + + +/* + * common + */ +DWORD +ea_nop(void) +{ + + ia32_panic("ea_nop"); + return 0; +} + + +/* + * 16bit + */ + +/* + * ea_dest + */ +static DWORD +ea_bx_si(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return (CPU_BX + CPU_SI); +} + +static DWORD +ea_bx_si_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX + CPU_SI); +} + +static DWORD +ea_bx_si_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX + CPU_SI); +} + +static DWORD +ea_bx_di(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return (CPU_BX + CPU_DI); +} + +static DWORD +ea_bx_di_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX + CPU_DI); +} + +static DWORD +ea_bx_di_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX + CPU_DI); +} + +static DWORD +ea_bp_si(void) +{ + + CPU_INST_SEGREG_INDEX = SS_FIX; + return (CPU_BP + CPU_SI); +} + +static DWORD +ea_bp_si_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP + CPU_SI); +} + +static DWORD +ea_bp_si_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP + CPU_SI); +} + +static DWORD +ea_bp_di(void) +{ + + CPU_INST_SEGREG_INDEX = SS_FIX; + return (CPU_BP + CPU_DI); +} + +static DWORD +ea_bp_di_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP + CPU_DI); +} + +static DWORD +ea_bp_di_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP + CPU_DI); +} + +static DWORD +ea_si(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_SI; +} + +static DWORD +ea_si_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_SI); +} + +static DWORD +ea_si_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_SI); +} + +static DWORD +ea_di(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_DI; +} + +static DWORD +ea_di_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_DI); +} + +static DWORD +ea_di_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_DI); +} + +static DWORD +ea_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs; +} + +static DWORD +ea_bp_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP); +} + +static DWORD +ea_bp_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP); +} + +static DWORD +ea_bx(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_BX; +} + +static DWORD +ea_bx_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX); +} + +static DWORD +ea_bx_disp16(void) +{ + DWORD adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX); +} + +static DWORD (*c_ea_dst_tbl[])(void) = { + ea_bx_si, ea_bx_di, + ea_bp_si, ea_bp_di, + ea_si, ea_di, + ea_disp16, ea_bx, + ea_bx_si_disp8, ea_bx_di_disp8, + ea_bp_si_disp8, ea_bp_di_disp8, + ea_si_disp8, ea_di_disp8, + ea_bp_disp8, ea_bx_disp8, + ea_bx_si_disp16, ea_bx_di_disp16, + ea_bp_si_disp16, ea_bp_di_disp16, + ea_si_disp16, ea_di_disp16, + ea_bp_disp16, ea_bx_disp16, +}; + + +/* + * 32bit + */ +/* + * ea_dest 32 + */ +static DWORD +ea32_eax(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_EAX; +} + +static DWORD +ea32_ecx(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_ECX; +} + +static DWORD +ea32_edx(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_EDX; +} + +static DWORD +ea32_ebx(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_EBX; +} + +static DWORD +ea32_sib(void) +{ + DWORD op, dst; + DWORD base, idx, scale; + + GET_PCBYTE(op); + dst = 0; /* compiler happy */ + + base = op & 7; + idx = (op >> 3) & 7; + scale = (op >> 6) & 3; + switch (base) { + case 0: case 1: case 2: case 3: case 6: case 7: + CPU_INST_SEGREG_INDEX = DS_FIX; + dst = CPU_REGS_DWORD(base); + break; + + case 4: + CPU_INST_SEGREG_INDEX = SS_FIX; + dst = CPU_ESP; + break; + + case 5: + CPU_INST_SEGREG_INDEX = DS_FIX; + GET_PCDWORD(dst); + break; + } + if (idx != 4) + dst += CPU_REGS_DWORD(idx) << scale; + return dst; +} + +static DWORD +ea32_disp32(void) +{ + DWORD adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs; +} + +static DWORD +ea32_esi(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_ESI; +} + +static DWORD +ea32_edi(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_EDI; +} + +static DWORD +ea32_eax_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EAX; +} + +static DWORD +ea32_ecx_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_ECX; +} + +static DWORD +ea32_edx_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EDX; +} + +static DWORD +ea32_ebx_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EBX; +} + +static DWORD +ea32_sib_disp8(void) +{ + SDWORD adrs; + DWORD op; + DWORD base, idx, scale; + + GET_PCBYTE(op); + GET_PCBYTESD(adrs); + + base = op & 7; + idx = (op >> 3) & 7; + scale = (op >> 6) & 3; + switch (base) { + case 0: case 1: case 2: case 3: case 6: case 7: + CPU_INST_SEGREG_INDEX = DS_FIX; + break; + + case 4: case 5: + CPU_INST_SEGREG_INDEX = SS_FIX; + break; + } + if (idx != 4) + adrs += CPU_REGS_DWORD(idx) << scale; + return CPU_REGS_DWORD(base) + adrs; +} + +static DWORD +ea32_ebp_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return adrs + CPU_EBP; +} + +static DWORD +ea32_esi_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_ESI; +} + +static DWORD +ea32_edi_disp8(void) +{ + SDWORD adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EDI; +} + +static DWORD +ea32_eax_disp32(void) +{ + DWORD adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EAX; +} + +static DWORD +ea32_ecx_disp32(void) +{ + DWORD adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_ECX; +} + +static DWORD +ea32_edx_disp32(void) +{ + DWORD adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EDX; +} + +static DWORD +ea32_ebx_disp32(void) +{ + DWORD adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EBX; +} + +static DWORD +ea32_sib_disp32(void) +{ + DWORD adrs; + DWORD op; + DWORD base, idx, scale; + + GET_PCBYTE(op); + GET_PCDWORD(adrs); + + base = op & 7; + idx = (op >> 3) & 7; + scale = (op >> 6) & 3; + switch (base) { + case 0: case 1: case 2: case 3: case 6: case 7: + CPU_INST_SEGREG_INDEX = DS_FIX; + break; + + case 4: case 5: + CPU_INST_SEGREG_INDEX = SS_FIX; + break; + } + if (idx != 4) + adrs += CPU_REGS_DWORD(idx) << scale; + return CPU_REGS_DWORD(base) + adrs; +} + +static DWORD +ea32_ebp_disp32(void) +{ + DWORD adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return adrs + CPU_EBP; +} + +static DWORD +ea32_esi_disp32(void) +{ + DWORD adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_ESI; +} + +static DWORD +ea32_edi_disp32(void) +{ + DWORD adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EDI; +} + +static DWORD (*c_ea32_dst_tbl[])(void) = { + ea32_eax, ea32_ecx, + ea32_edx, ea32_ebx, + ea32_sib, ea32_disp32, + ea32_esi, ea32_edi, + ea32_eax_disp8, ea32_ecx_disp8, + ea32_edx_disp8, ea32_ebx_disp8, + ea32_sib_disp8, ea32_ebp_disp8, + ea32_esi_disp8, ea32_edi_disp8, + ea32_eax_disp32, ea32_ecx_disp32, + ea32_edx_disp32, ea32_ebx_disp32, + ea32_sib_disp32, ea32_ebp_disp32, + ea32_esi_disp32, ea32_edi_disp32, +}; + + +/* + * init table + */ +void +resolve_init(void) +{ + int i, pos; + + for (i = 0; i < 0xc0; ++i) { + pos = ((i >> 3) & 0x18) + (i & 0x07); + calc_ea_dst_tbl[i] = c_ea_dst_tbl[pos]; + calc_ea32_dst_tbl[i] = c_ea32_dst_tbl[pos]; + } + for (; i < 0x100; ++i) { + calc_ea_dst_tbl[i] = ea_nop; + calc_ea32_dst_tbl[i] = ea_nop; + } +} diff --git a/i386c/ia32/resolve.h b/i386c/ia32/resolve.h new file mode 100644 index 00000000..3aa7fd6d --- /dev/null +++ b/i386c/ia32/resolve.h @@ -0,0 +1,48 @@ +/* $Id: resolve.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_RESOLVE_H__ +#define IA32_CPU_RESOLVE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void resolve_init(void); + +DWORD calc_ea_dst(DWORD); +#define calc_lea(op) calc_ea_dst(op) +#define get_ea(op) calc_ea_dst(op) +#define get_lea(op) calc_ea_dst(op) + +#ifdef __cplusplus +} +#endif + +#endif /* IA32_CPU_RESOLVE_H__ */ diff --git a/i386c/ia32/segments.c b/i386c/ia32/segments.c new file mode 100644 index 00000000..88f35c1b --- /dev/null +++ b/i386c/ia32/segments.c @@ -0,0 +1,369 @@ +/* $Id: segments.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + + +void +load_segreg(int idx, WORD selector, int exc) +{ + selector_t sel; + int rv; + + + if ((unsigned int)idx >= CPU_SEGREG_NUM) { + ia32_panic("load_segreg: sreg(%d)", idx); + } + + if (!CPU_STAT_PM || CPU_STAT_VM86) { + descriptor_t sd; + + /* real-mode or vm86 mode */ + CPU_REGS_SREG(idx) = selector; + + sd.u.seg.limit = CPU_STAT_SREGLIMIT(idx); + CPU_SET_SEGDESC_DEFAULT(&sd, idx, selector); + CPU_STAT_SREG(idx) = sd; + return; + } + + /* + * protected mode + */ + VERBOSE(("load_segreg: idx = %d, selector = %04x, exc = %d", idx, selector, exc)); + + if (idx == CPU_CS_INDEX) { + ia32_panic("load_segreg: sreg(%d)", idx); + } + + rv = parse_selector(&sel, selector); + if (rv < 0) { + if ((rv != -2) || (idx == CPU_SS_INDEX)) { + EXCEPTION(exc, sel.idx); + } + CPU_REGS_SREG(idx) = sel.selector; + CPU_STAT_SREG_CLEAR(idx); + return; + } + + switch (idx) { + case CPU_SS_INDEX: + if ((CPU_STAT_CPL != sel.rpl) || + !sel.desc.s || sel.desc.u.seg.c || !sel.desc.u.seg.wr || + (CPU_STAT_CPL != sel.desc.dpl)) { + EXCEPTION(exc, sel.idx); + } + + /* not present */ + rv = selector_is_not_present(&sel); + if (rv < 0) { + EXCEPTION(SS_EXCEPTION, sel.idx); + } + + CPU_STAT_SS32 = sel.desc.d; + CPU_REGS_SREG(idx) = sel.selector; + CPU_STAT_SREG(idx) = sel.desc; + break; + + case CPU_ES_INDEX: + case CPU_DS_INDEX: + case CPU_FS_INDEX: + case CPU_GS_INDEX: + /* !(system segment || non-readble code segment */ + if (!sel.desc.s + || (sel.desc.u.seg.c && !sel.desc.u.seg.wr)) { + EXCEPTION(exc, sel.idx); + } + /* data segment || non-conforming code segment */ + if (!sel.desc.u.seg.c || !sel.desc.u.seg.ec) { + /* check privilege level */ + if ((sel.rpl > sel.desc.dpl) || (CPU_STAT_CPL > sel.desc.dpl)) { + EXCEPTION(exc, sel.idx); + } + } + + /* not present */ + rv = selector_is_not_present(&sel); + if (rv < 0) { + EXCEPTION(NP_EXCEPTION, sel.idx); + } + + CPU_REGS_SREG(idx) = sel.selector; + CPU_STAT_SREG(idx) = sel.desc; + break; + + default: + ia32_panic("load_segreg(): segment register index is invalid"); + break; + } +} + +/* + * load SS register + */ +void +load_ss(WORD selector, descriptor_t* sdp, BYTE cpl) +{ + + CPU_STAT_SS32 = sdp->d; + CPU_REGS_SREG(CPU_SS_INDEX) = (selector & ~3) | (cpl & 3); + CPU_STAT_SREG(CPU_SS_INDEX) = *sdp; +} + +/* + * load CS register + */ +void +load_cs(WORD selector, descriptor_t* sdp, BYTE cpl) +{ + + cpu_inst_default.op_32 = cpu_inst_default.as_32 = sdp->d; + CPU_REGS_SREG(CPU_CS_INDEX) = (selector & ~3) | (cpl & 3); + CPU_STAT_SREG(CPU_CS_INDEX) = *sdp; + CPU_STAT_CPL = cpl & 3; +} + +/* + * load LDT register + */ +void +load_ldtr(WORD selector, int exc) +{ + selector_t sel; + int rv; + + rv = parse_selector(&sel, selector); + if (rv < 0 || sel.ldt) { + if (rv == -2) { + /* null segment */ + CPU_LDTR = 0; + memset(&CPU_LDTR_DESC, 0, sizeof(CPU_LDTR_DESC)); + return; + } + EXCEPTION(exc, sel.selector); + } + + /* check descriptor type */ + if (!sel.desc.s || (sel.desc.type != CPU_SYSDESC_TYPE_LDT)) { + EXCEPTION(exc, sel.selector); + } + + /* check limit */ + if (sel.desc.u.seg.limit < 7) { + ia32_panic("load_ldtr: LDTR descriptor limit < 7"); + } + + /* not present */ + rv = selector_is_not_present(&sel); + if (rv < 0) { + EXCEPTION((exc == TS_EXCEPTION) ? TS_EXCEPTION : NP_EXCEPTION, sel.selector); + } + + CPU_LDTR = sel.selector; + CPU_LDTR_DESC = sel.desc; +} + +void +load_descriptor(descriptor_t *descp, DWORD addr) +{ + + descp->addr = addr; + descp->l = cpu_lmemoryread_d(descp->addr); + descp->h = cpu_lmemoryread_d(descp->addr + 4); + + descp->flag = 0; + + descp->p = (descp->h & CPU_DESC_H_P) == CPU_DESC_H_P; + descp->type = (descp->h & CPU_DESC_H_TYPE) >> 8; + descp->dpl = (descp->h & CPU_DESC_H_DPL) >> 13; + descp->s = (descp->h & CPU_DESC_H_S) == CPU_DESC_H_S; + + if (descp->s) { + /* code/data */ + descp->valid = 1; + + descp->d = (descp->h & CPU_SEGDESC_H_D) ? 1 : 0; + descp->u.seg.c = (descp->h & CPU_SEGDESC_H_D_C) ? 1 : 0; + descp->u.seg.g = (descp->h & CPU_SEGDESC_H_G) ? 1 : 0; + descp->u.seg.wr = (descp->type & CPU_SEGDESC_TYPE_WR) ? 1 : 0; + descp->u.seg.ec = (descp->type & CPU_SEGDESC_TYPE_EC) ? 1 : 0; + + descp->u.seg.segbase = (descp->l >> 16) & 0xffff; + descp->u.seg.segbase |= (descp->h & 0xff) << 16; + descp->u.seg.segbase |= descp->h & 0xff000000; + + descp->u.seg.limit = (descp->h & 0xf0000) | (descp->l & 0xffff); + if (descp->u.seg.g) { + descp->u.seg.limit <<= 12; + descp->u.seg.limit |= 0xfff; + } + + descp->u.seg.segend = descp->u.seg.segbase + descp->u.seg.limit; + + VERBOSE(("load_descriptor: %s segment descriptor: addr = 0x%08x, h = 0x%04x, l = %04x, type = %d, DPL = %d, base = 0x%08x, limit = 0x%08x, d = %s, g = %s, %s, %s", descp->u.seg.c ? "code" : "data", descp->addr, descp->h, descp->l, descp->type, descp->dpl, descp->u.seg.segbase, descp->u.seg.limit, descp->d ? "on" : "off", descp->u.seg.g ? "on" : "off", descp->u.seg.c ? (descp->u.seg.wr ? "executable/readable" : "execute-only") : (descp->u.seg.wr ? "writable" : "read-only"), (descp->u.seg.c ? (descp->u.seg.ec ? "conforming" : "non-conforming") : (descp->u.seg.ec ? "expand-down" : "expand-up")))); + } else { + /* system */ + switch (descp->type) { + case CPU_SYSDESC_TYPE_LDT: /* LDT */ + descp->valid = 1; + VERBOSE(("load_descriptor: LDT descriptor")); + break; + + case CPU_SYSDESC_TYPE_TASK: + descp->valid = 1; + descp->u.gate.selector = descp->l >> 16; + VERBOSE(("load_descriptor: task descriptor: selector = 0x%04x", descp->u.gate.selector)); + break; + + case CPU_SYSDESC_TYPE_TSS_16: /* 286 TSS */ + case CPU_SYSDESC_TYPE_TSS_BUSY_16: /* 286 TSS Busy */ + descp->valid = 1; + descp->u.seg.segbase |= (descp->h & 0xff) << 16; + descp->u.seg.segbase |= descp->l >> 16; + descp->u.seg.limit = descp->h & 0xf0000; + descp->u.seg.limit |= descp->l & 0xffff; + descp->u.seg.segend = descp->u.seg.segbase + descp->u.seg.limit; + VERBOSE(("load_descriptor: 16bit %sTSS descriptor: base = 0x%08x, limit = 0x%08x", (descp->type & CPU_SYSDESC_TYPE_TSS_BUSY) ? "busy " : "", descp->u.seg.segbase, descp->u.seg.limit)); + break; + + case CPU_SYSDESC_TYPE_CALL_16: /* 286 call gate */ + case CPU_SYSDESC_TYPE_INTR_16: /* 286 interrupt gate */ + case CPU_SYSDESC_TYPE_TRAP_16: /* 286 trap gate */ + if ((descp->h & 0x0000000e0) == 0) { + descp->valid = 1; + descp->u.gate.selector = descp->l >> 16; + descp->u.gate.offset = descp->l & 0xffff; + descp->u.gate.count = descp->h & 0x1f; + VERBOSE(("load_descriptor: 16bit %s gate descriptor: selector = 0x%04x, offset = 0x%08x, count = %d", (descp->type == CPU_SYSDESC_TYPE_CALL_16) ? "call" : ((descp->type == CPU_SYSDESC_TYPE_INTR_16) ? "interrupt" : "trap"), descp->u.gate.selector, descp->u.gate.offset, descp->u.gate.count)); + } else { + ia32_panic("load_descriptor: 286 gate is invalid"); + } + break; + + case CPU_SYSDESC_TYPE_TSS_32: /* 386 TSS */ + case CPU_SYSDESC_TYPE_TSS_BUSY_32: /* 386 TSS Busy */ + descp->valid = 1; + descp->d = (descp->h & CPU_SEGDESC_H_D) ? 1 : 0; + descp->u.seg.g = (descp->h & CPU_SEGDESC_H_G) ? 1 : 0; + descp->u.seg.segbase = descp->h & 0xff000000; + descp->u.seg.segbase |= (descp->h & 0xff) << 16; + descp->u.seg.segbase |= descp->l >> 16; + descp->u.seg.limit = descp->h & 0xf0000; + descp->u.seg.limit |= descp->l & 0xffff; + if (descp->u.seg.g) { + descp->u.seg.limit <<= 12; + descp->u.seg.limit |= 0xfff; + } + VERBOSE(("load_descriptor: 32bit %sTSS descriptor: base = 0x%08x, limit = 0x%08x, d = %s, g = %s", (descp->type & CPU_SYSDESC_TYPE_TSS_BUSY) ? "busy " : "", descp->u.seg.segbase, descp->u.seg.limit, descp->d ? "on" : "off", descp->u.seg.g ? "on" : "off")); + break; + + case CPU_SYSDESC_TYPE_CALL_32: /* 386 call gate */ + case CPU_SYSDESC_TYPE_INTR_32: /* 386 interrupt gate */ + case CPU_SYSDESC_TYPE_TRAP_32: /* 386 trap gate */ + if ((descp->h & 0x0000000e0) == 0) { + descp->valid = 1; + descp->d = (descp->h & CPU_GATEDESC_H_D) ? 1:0; + descp->u.gate.selector = descp->l >> 16; + descp->u.gate.offset = descp->h & 0xffff0000; + descp->u.gate.offset |= descp->l & 0xffff; + descp->u.gate.count = descp->h & 0x1f; + VERBOSE(("load_descriptor: 32bit %s gate descriptor: selector = 0x%04x, offset = 0x%08x, count = %d, d = %s", (descp->type == CPU_SYSDESC_TYPE_CALL_16) ? "call" : ((descp->type == CPU_SYSDESC_TYPE_INTR_16) ? "interrupt" : "trap"), descp->u.gate.selector, descp->u.gate.offset, descp->u.gate.count, descp->d ? "on" : "off")); + } else { + ia32_panic("load_descriptor: 286 gate is invalid"); + } + break; + + case 0: case 8: case 10: case 13: /* reserved */ + default: + descp->valid = 0; + ia32_panic("bad segment descriptor (%d)", descp->type); + break; + } + } +} + +int +parse_selector(selector_t* ssp, WORD selector) +{ + DWORD base; + WORD limit; + WORD idx; + + ssp->selector = selector; + ssp->idx = selector & ~3; + ssp->rpl = selector & 3; + ssp->ldt = selector & CPU_SEGMENT_TABLE_IND; + + VERBOSE(("parse_selector: selector = %04x, index = %d, RPL = %d, %cDT", ssp->selector, ssp->idx >> 3, ssp->rpl, ssp->ldt ? 'L' : 'G')); + + /* descriptor table */ + idx = selector & ~7; + if (ssp->ldt) { + /* LDT */ + if (!CPU_LDTR_DESC.valid) { + VERBOSE(("parse_selector: LDT is invalid")); + return -1; + } + base = CPU_LDTR_BASE; + limit = CPU_LDTR_LIMIT; + } else { + /* check null segment */ + if (idx == 0) { + VERBOSE(("parse_selector: null segment")); + return -2; + } + base = CPU_GDTR_BASE; + limit = CPU_GDTR_LIMIT; + } + if (idx + 7 > limit) { + VERBOSE(("parse_selector: segment limit check failed")); + return -3; + } + /* load descriptor */ + CPU_SET_SEGDESC(&ssp->desc, base + idx); + if (!ssp->desc.valid) { + VERBOSE(("parse_selector: segment descriptor is invalid")); + return -4; + } + return 0; +} + +int +selector_is_not_present(selector_t* ssp) +{ + /* not present */ + if (!ssp->desc.p) { + VERBOSE(("selector_is_not_present: not present")); + return -1; + } + CPU_SET_SEGDESC_POSTPART(&ssp->desc); + return 0; +} diff --git a/i386c/ia32/segments.h b/i386c/ia32/segments.h new file mode 100644 index 00000000..1dd8197b --- /dev/null +++ b/i386c/ia32/segments.h @@ -0,0 +1,217 @@ +/* $Id: segments.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_SEGMENTS_H__ +#define IA32_CPU_SEGMENTS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * segment selector + */ +#define CPU_SEGMENT_SELECTOR_INDEX_MASK ~7 +#define CPU_SEGMENT_SELECTOR_RPL_MASK 3 +#define CPU_SEGMENT_TABLE_IND (1 << 2) /* 0 = GDT, 1 = LDT */ + + +/* + * segment descriptor + */ +typedef struct { + union { + struct { + DWORD segbase; + DWORD segend; + DWORD limit; + + BYTE c; /* 0 = data, 1 = code */ + BYTE g; /* 4k base */ + BYTE wr; /* readable/writable */ + BYTE ec; /* expand down/conforming */ + } seg; + + struct { + WORD selector; + WORD w_pad; + DWORD offset; + + BYTE count; /* parameter count:call gate */ + + BYTE b_pad[7]; + } gate; + } u; + + DWORD addr; /* descriptor addr */ + DWORD l; /* low dword cache */ + DWORD h; /* high dword cache */ + + BYTE valid; /* descriptor valid flag */ + BYTE p; /* avail flag */ + + BYTE type; /* descriptor type */ + BYTE dpl; /* DPL */ + BYTE s; /* 0 = system, 1 = code/data */ + BYTE d; /* 0 = 16bit, 1 = 32bit */ + + BYTE flag; +#define CPU_DESC_READABLE (1 << 0) +#define CPU_DESC_WRITABLE (1 << 1) + + BYTE b_pad; +} descriptor_t; + +#define CPU_DESC_H_TYPE (0xf << 8) +#define CPU_DESC_H_S ( 1 << 12) /* 0 = system, 1 = code/data */ +#define CPU_DESC_H_DPL ( 3 << 13) +#define CPU_DESC_H_P ( 1 << 15) /* exist */ + +/* for segment descriptor */ +#define CPU_SEGDESC_H_A ( 1 << 8) +#define CPU_SEGDESC_H_D_C ( 1 << 11) /* 0 = data, 1 = code */ +#define CPU_SEGDESC_H_D ( 1 << 22) +#define CPU_SEGDESC_H_G ( 1 << 23) + +/* for gate descriptor */ +#define CPU_GATEDESC_H_D ( 1 << 11) + +/* for tss descriptor */ +#define CPU_TSS_H_BUSY ( 1 << 10) + +/* + * descriptor type + */ +#define CPU_SEGDESC_TYPE_A 0x01 +#define CPU_SEGDESC_TYPE_WR 0x02 +#define CPU_SEGDESC_TYPE_EC 0x04 + +#define CPU_SYSDESC_TYPE_TSS_16 0x01 +#define CPU_SYSDESC_TYPE_LDT 0x02 +#define CPU_SYSDESC_TYPE_TSS_BUSY_16 0x03 +#define CPU_SYSDESC_TYPE_CALL_16 0x04 /* call gate */ +#define CPU_SYSDESC_TYPE_TASK 0x05 /* task gate */ +#define CPU_SYSDESC_TYPE_INTR_16 0x06 /* hardware interrupt */ +#define CPU_SYSDESC_TYPE_TRAP_16 0x07 /* software interrupt */ +#define CPU_SYSDESC_TYPE_TSS_32 0x09 +#define CPU_SYSDESC_TYPE_TSS_BUSY_32 0x0b +#define CPU_SYSDESC_TYPE_CALL_32 0x0c /* call gate */ +#define CPU_SYSDESC_TYPE_INTR_32 0x0e /* hardware interrupt */ +#define CPU_SYSDESC_TYPE_TRAP_32 0x0f /* software interrupt */ + +#define CPU_SYSDESC_TYPE_TSS 0x01 +/* CPU_SYSDESC_TYPE_LDT 0x02 */ +#define CPU_SYSDESC_TYPE_TSS_BUSY 0x03 +#define CPU_SYSDESC_TYPE_CALL 0x04 +/* CPU_SYSDESC_TYPE_TASK 0x05 */ +#define CPU_SYSDESC_TYPE_INTR 0x06 +#define CPU_SYSDESC_TYPE_TRAP 0x07 + +#define CPU_SYSDESC_TYPE_TSS_BUSY_IND 0x02 + +#define CPU_SET_SEGDESC_DEFAULT(dscp, idx, selector) \ +do { \ + (dscp)->u.seg.segbase = (DWORD)(selector) << 4; \ + (dscp)->u.seg.segend = (dscp)->u.seg.segbase + (dscp)->u.seg.limit; \ + (dscp)->u.seg.c = ((idx) == CPU_CS_INDEX) ? 1 : 0; \ + (dscp)->u.seg.g = 0; \ + (dscp)->valid = 1; \ + (dscp)->p = 1; \ + (dscp)->type = ((idx) == CPU_CS_INDEX) ? 0x0a : \ + (((idx) == CPU_SS_INDEX) ? 0x06 : 0x02); \ + (dscp)->dpl = 0; \ + (dscp)->s = 1; /* code/data */ \ + (dscp)->d = 0; \ + (dscp)->flag = 0; \ +} while (/*CONSTCOND*/ 0) + +#define CPU_SET_SEGDESC_POSTPART(dscp) \ +do { \ + if ((dscp)->s) { \ + if (!((dscp)->h & CPU_SEGDESC_H_A)) { \ + (dscp)->h |= CPU_SEGDESC_H_A; \ + cpu_memorywrite_d((dscp)->addr + 4, (dscp)->h); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define CPU_SET_TASK_BUSY(dscp) \ +do { \ + DWORD h; \ + h = cpu_memoryread_d((dscp)->addr + 4); \ + if (!(h & CPU_TSS_H_BUSY)) { \ + (dscp)->type |= CPU_SYSDESC_TYPE_TSS_BUSY_IND; \ + h |= CPU_TSS_H_BUSY; \ + cpu_memorywrite_d((dscp)->addr + 4, h); \ + } else { \ + ia32_panic("CPU_SET_TASK_BUSY: already busy (%x)", h); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define CPU_SET_TASK_FREE(dscp) \ +do { \ + DWORD h; \ + h = cpu_memoryread_d((dscp)->addr + 4); \ + if (h & CPU_TSS_H_BUSY) { \ + (dscp)->type &= ~CPU_SYSDESC_TYPE_TSS_BUSY_IND; \ + h &= ~CPU_TSS_H_BUSY; \ + cpu_memorywrite_d((dscp)->addr + 4, h); \ + } else { \ + ia32_panic("CPU_SET_TASK_FREE: already free (%x)", h); \ + } \ +} while (/*CONSTCOND*/ 0) + +typedef struct { + WORD selector; + WORD idx; + WORD rpl; + BYTE ldt; + BYTE pad; + + descriptor_t desc; +} selector_t; + +int parse_selector(selector_t* ssp, WORD selector); +int selector_is_not_present(selector_t* ssp); + +#define CPU_SET_SEGDESC(descp, addr) load_descriptor(descp, addr) +#define CPU_SET_GATEDESC(descp, addr) load_descriptor(descp, addr) +void load_descriptor(descriptor_t* descp, DWORD addr); + +#define CPU_SET_SEGREG(idx, selector) load_segreg(idx, selector, GP_EXCEPTION) +void load_segreg(int idx, WORD selector, int exc); +void load_ss(WORD selector, descriptor_t* sdp, BYTE cpl); +void load_cs(WORD selector, descriptor_t* sdp, BYTE cpl); +void load_ldtr(WORD selector, int exc); + +#ifdef __cplusplus +} +#endif + +#endif /* !IA32_CPU_SEGMENTS_H__ */ diff --git a/i386c/ia32/task.c b/i386c/ia32/task.c new file mode 100644 index 00000000..c1c7788b --- /dev/null +++ b/i386c/ia32/task.c @@ -0,0 +1,390 @@ +/* $Id: task.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + + +void +load_tr(WORD selector) +{ + selector_t task_sel; + int rv; + + rv = parse_selector(&task_sel, selector); + if (rv < 0 || task_sel.ldt || task_sel.desc.s) { + EXCEPTION(GP_EXCEPTION, task_sel.idx); + } + + /* check descriptor type & stack room size */ + switch (task_sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + if (task_sel.desc.u.seg.limit < 0x2b) { + EXCEPTION(TS_EXCEPTION, task_sel.idx); + } + break; + + case CPU_SYSDESC_TYPE_TSS_32: + if (task_sel.desc.u.seg.limit < 0x67) { + EXCEPTION(TS_EXCEPTION, task_sel.idx); + } + break; + + default: + EXCEPTION(GP_EXCEPTION, task_sel.idx); + break; + } + + /* not present */ + rv = selector_is_not_present(&task_sel); + if (rv < 0) { + EXCEPTION(NP_EXCEPTION, task_sel.idx); + } + + CPU_SET_TASK_BUSY(&task_sel.desc); + CPU_TR = task_sel.selector; + CPU_TR_DESC = task_sel.desc; +} + +void +get_stack_from_tss(BYTE pl, WORD* new_ss, DWORD* new_esp) +{ + DWORD tss_stack_addr; + + switch (CPU_TR_DESC.type) { + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + tss_stack_addr = pl * 8 + 4; + if (tss_stack_addr + 7 > CPU_TR_DESC.u.seg.limit) { + EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); + } + tss_stack_addr += CPU_TR_DESC.u.seg.segbase; + *new_esp = cpu_lmemoryread_d(tss_stack_addr); + *new_ss = cpu_lmemoryread_w(tss_stack_addr + 4); + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + tss_stack_addr = pl * 4 + 2; + if (tss_stack_addr + 4 > CPU_TR_DESC.u.seg.limit) { + EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); + } + tss_stack_addr += CPU_TR_DESC.u.seg.segbase; + *new_esp = cpu_lmemoryread_w(tss_stack_addr); + *new_ss = cpu_lmemoryread_w(tss_stack_addr + 2); + break; + + default: + ia32_panic("get_stack_from_tss: TR is invalid (%d)\n", + CPU_TR_DESC.type); + break; + } +} + +WORD +get_link_selector_from_tss() +{ + + if (CPU_TR_DESC.type == CPU_SYSDESC_TYPE_TSS_BUSY_32) { + if (4 > CPU_TR_DESC.u.seg.limit) { + EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); + } + } else if (CPU_TR_DESC.type == CPU_SYSDESC_TYPE_TSS_BUSY_16) { + if (2 > CPU_TR_DESC.u.seg.limit) { + EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); + } + } else { + ia32_panic("get_link_selector_from_tss: TR is invalid (%d)\n", + CPU_TR_DESC.type); + return 0; /* compiler happy */ + } + + return cpu_lmemoryread_w(CPU_TR_DESC.u.seg.segbase); +} + +void +task_switch(selector_t* task_sel, int type) +{ + DWORD regs[CPU_REG_NUM]; + DWORD eip; + DWORD new_flags; + DWORD cr3 = 0; + WORD sreg[CPU_SEGREG_NUM]; + WORD ldtr; + WORD t, iobase; + + selector_t cs_sel; + int rv; + + DWORD cur_base; /* current task state */ + DWORD task_base; /* new task state */ + DWORD old_flags = REAL_EFLAGREG; + BOOL task16; + int nsreg; + int i; + + cur_base = CPU_TR_DESC.u.seg.segbase; + task_base = task_sel->desc.u.seg.segbase; + + /* limit check */ + switch (task_sel->desc.type) { + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + if (task_sel->desc.u.seg.limit < 103) { + EXCEPTION(TS_EXCEPTION, task_sel->idx); + } + task16 = FALSE; + nsreg = CPU_SEGREG_NUM; + break; + + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + if (task_sel->desc.u.seg.limit < 43) { + EXCEPTION(TS_EXCEPTION, task_sel->idx); + } + task16 = TRUE; + nsreg = CPU_SEGREG286_NUM; + break; + + default: + ia32_panic("task_switch: descriptor type is invalid."); + task16 = FALSE; /* compiler happy */ + nsreg = CPU_SEGREG_NUM; /* compiler happy */ + break; + } + + if (CPU_STAT_PAGING) { + /* task state paging check */ + paging_check(cur_base, CPU_TR_DESC.u.seg.limit, CPU_PAGING_PAGE_WRITE); + paging_check(task_base, task_sel->desc.u.seg.limit, CPU_PAGING_PAGE_WRITE); + } + + /* load task state */ + memset(sreg, 0, sizeof(sreg)); + if (!task16) { + if (CPU_STAT_PAGING) { + cr3 = cpu_lmemoryread_d(task_base + 28); + } + eip = cpu_lmemoryread_d(task_base + 32); + new_flags = cpu_lmemoryread_d(task_base + 36); + for (i = 0; i < CPU_REG_NUM; i++) { + regs[i] = cpu_lmemoryread_d(task_base + 40 + i * 4); + } + for (i = 0; i < nsreg; i++) { + sreg[i] = (WORD)cpu_lmemoryread_d(task_base + 72 + i * 4); + } + ldtr = (WORD)cpu_lmemoryread_d(task_base + 96); + t = cpu_lmemoryread_w(task_base + 100); + iobase = cpu_lmemoryread_w(task_base + 102); + } else { + eip = cpu_lmemoryread_w(task_base + 14); + new_flags = cpu_lmemoryread_w(task_base + 16); + for (i = 0; i < CPU_REG_NUM; i++) { + regs[i] = cpu_lmemoryread_w(task_base + 18 + i * 2); + } + for (i = 0; i < nsreg; i++) { + sreg[i] = cpu_lmemoryread_w(task_base + 34 + i * 2); + } + ldtr = cpu_lmemoryread_w(task_base + 42); + iobase = 0; + } + + /* if IRET or JMP, clear busy flag in this task: need */ + /* if IRET, clear NT_FLAG in current EFLAG: need */ + switch (type) { + case TASK_SWITCH_IRET: + /* clear NT_FLAG */ + old_flags &= ~NT_FLAG; + /*FALLTHROUGH*/ + case TASK_SWITCH_JMP: + /* clear busy flags in current task */ + CPU_SET_TASK_FREE(&CPU_TR_DESC); + break; + + case TASK_SWITCH_CALL: + case TASK_SWITCH_INTR: + /* Nothing to do */ + break; + + default: + ia32_panic("task_switch(): task switch type is invalid"); + break; + } + + /* save this task state in this task state segment ind */ + if (!task16) { + cpu_lmemorywrite_d(cur_base + 28, CPU_CR3); + cpu_lmemorywrite_d(cur_base + 32, CPU_EIP); + cpu_lmemorywrite_d(cur_base + 36, old_flags); + for (i = 0; i < CPU_REG_NUM; i++) { + cpu_lmemorywrite_d(cur_base + 40 + i * 4, CPU_REGS_DWORD(i)); + } + for (i = 0; i < nsreg; i++) { + cpu_lmemorywrite_d(cur_base + 72 + i * 4, CPU_REGS_SREG(i)); + } + cpu_lmemorywrite_d(cur_base + 96, CPU_LDTR); + } else { + cpu_lmemorywrite_w(cur_base + 14, CPU_IP); + cpu_lmemorywrite_w(cur_base + 16, (WORD)old_flags); + for (i = 0; i < CPU_REG_NUM; i++) { + cpu_lmemorywrite_w(cur_base + 18 + i * 2, CPU_REGS_WORD(i)); + } + for (i = 0; i < nsreg; i++) { + cpu_lmemorywrite_w(cur_base + 34 + i * 2, CPU_REGS_SREG(i)); + } + cpu_lmemorywrite_w(cur_base + 42, CPU_LDTR); + } + + /* set back link selector */ + switch (type) { + case TASK_SWITCH_CALL: + case TASK_SWITCH_INTR: + /* set back link selector */ + cpu_lmemorywrite_d(task_base, CPU_TR); + break; + + case TASK_SWITCH_IRET: + case TASK_SWITCH_JMP: + /* Nothing to do */ + break; + + default: + ia32_panic("task_switch(): task switch type is invalid"); + break; + } + + /* Now task switching! */ + + /* if CALL, INTR, set EFLAG image NT_FLAG */ + /* if CALL, INTR, JMP set busy flag */ + switch (type) { + case TASK_SWITCH_CALL: + case TASK_SWITCH_INTR: + /* set back link selector */ + new_flags |= NT_FLAG; + /*FALLTHROUGH*/ + case TASK_SWITCH_JMP: + CPU_SET_TASK_BUSY(&task_sel->desc); + break; + + case TASK_SWITCH_IRET: + /* Nothing to do */ + /* XXX: if IRET, check busy flag is active? */ + break; + + default: + ia32_panic("task_switch(): task switch type is invalid"); + break; + } + + /* set CR0 image CPU_CR0_TS */ + CPU_CR0 |= CPU_CR0_TS; + + /* load task selector to CPU_TR */ + CPU_TR = task_sel->selector; + CPU_TR_DESC = task_sel->desc; + + /* load task state (CR3, EFLAG, EIP, GPR, segreg, LDTR) */ + if (CPU_STAT_PAGING) { + /* XXX setCR3()? */ + CPU_CR3 = cr3 & 0xfffff018; + tlb_flush(FALSE); + } + + /* set new EFLAGS, EIP, GPR, segment register, LDTR */ + set_eflags(new_flags, I_FLAG|IOPL_FLAG|RF_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG); + CPU_PREV_EIP = CPU_EIP = eip; + for (i = 0; i < CPU_REG_NUM; i++) { + CPU_REGS_DWORD(i) = regs[i]; + } + for (i = 0; i < CPU_SEGREG_NUM; i++) { + CPU_REGS_SREG(i) = sreg[i]; + CPU_STAT_SREG_CLEAR(i); + } + CPU_LDTR = ldtr; + CPU_LDTR_DESC.valid = 0; + + /* load LDTR */ + load_ldtr(ldtr, TS_EXCEPTION); + + /* load CS */ + rv = parse_selector(&cs_sel, sreg[CPU_CS_INDEX]); + if (rv < 0) { + EXCEPTION(TS_EXCEPTION, cs_sel.idx); + } + + /* CS register must be code segment */ + if (!cs_sel.desc.s || !cs_sel.desc.u.seg.c) { + EXCEPTION(TS_EXCEPTION, cs_sel.idx); + } + + /* check privilege level */ + if (!cs_sel.desc.u.seg.ec) { + /* non-confirming code segment */ + if (cs_sel.desc.dpl != cs_sel.rpl) { + EXCEPTION(TS_EXCEPTION, cs_sel.idx); + } + } else { + /* confirming code segment */ + if (cs_sel.desc.dpl < cs_sel.rpl) { + EXCEPTION(TS_EXCEPTION, cs_sel.idx); + } + } + + /* CS segment is not present */ + rv = selector_is_not_present(&cs_sel); + if (rv < 0) { + EXCEPTION(NP_EXCEPTION, cs_sel.idx); + } + + /* Now loading CS register */ + load_cs(cs_sel.selector, &cs_sel.desc, cs_sel.desc.dpl); + + /* load ES, SS, DS, FS, GS segment register */ + for (i = 0; i < nsreg; i++) { + if (i != CPU_CS_INDEX) { + load_segreg(i, sreg[i], TS_EXCEPTION); + } + } + + /* I/O deny bitmap */ + if (!task16) { + if (task_sel->desc.u.seg.limit > iobase) { + CPU_STAT_IOLIMIT = task_sel->desc.u.seg.limit - iobase; + CPU_STAT_IOLIMIT *= 8; /* ・モ・テ・ネテアーフ、ヌハンサ、キ、ニ、ェ、ッ */ + CPU_STAT_IOADDR = task_sel->desc.u.seg.segbase + iobase; + } else { + CPU_STAT_IOLIMIT = 0; + } + } else { + CPU_STAT_IOLIMIT = 0; + } + + /* running new task */ + SET_EIP(eip); +} diff --git a/i386c/ia32/task.h b/i386c/ia32/task.h new file mode 100644 index 00000000..9422d25e --- /dev/null +++ b/i386c/ia32/task.h @@ -0,0 +1,88 @@ +/* $Id: task.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ + +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_TASK_H__ +#define IA32_CPU_TASK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { + struct { + WORD backlink; /* クオ、ホ・ソ・ケ・ッ・サ・・ッ・ソテヘ */ + struct { + WORD sp; /* ・ケ・ソ・テ・ッ・ン・、・・ソ */ + WORD ss; /* ・ケ・ソ・テ・ッ・サ・ー・皈・ネ */ + } stack[3]; /* ニテク「・・ル・ 0-2 */ + WORD ip; /* IP */ + WORD flags; /* FLAGS */ + WORD regs[8]; /* ・・ク・ケ・ソ */ + WORD sreg[4]; /* ・サ・ー・皈・ネ・・ク・ケ・ソ */ + WORD ldt; /* ・ソ・ケ・ッヒ隍ホ LDT ・サ・・ッ・ソテヘ */ + } tss16; + + struct { + REG32 backlink; /* REG16: クオ、ホ・ソ・ケ・ッ・サ・・ッ・ソテヘ */ + struct { + REG32 sp; /* REG32: ・ケ・ソ・テ・ッ・ン・、・・ソ */ + REG32 ss; /* REG16: ・ケ・ソ・テ・ッ・サ・ー・皈・ネ */ + } stack[3]; /* ニテク「・・ル・ 0-2 */ + REG32 cr3; /* REG32: ・ソ・ケ・ッヒ隍ホ CR3 */ + REG32 ip; /* REG32: EIP */ + REG32 flags; /* REG32: EFLAGS */ + REG32 regs[8]; /* REG32: ・・ク・ケ・ソ */ + REG32 sreg[6]; /* REG16: ・サ・ー・皈・ネ・・ク・ケ・ソ */ + REG32 ldt; /* REG16: ・ソ・ケ・ッヒ隍ホ LDT ・サ・・ッ・ソテヘ */ + WORD t; /* コヌイシーフ・モ・テ・ネ、ャ1、ホ、ネ、ュ。「・ソ・ケ・ッタレツリサ + 、ヒウ荀ケ、゚ネヨケ1、ホ・ユ・ゥ。シ・・ネ、ネッタク */ + WORD iobase; /* TSS タ霹ャ、ォ、 I/O オイト・ニ。シ・ヨ・・゙・テ・ラ + 、゙、ヌ、ホ・ミ・、・ネソ */ + } tss32; +} TASK_STATE_T; + +void load_tr(WORD selector); +void get_stack_from_tss(BYTE pl, WORD* new_ss, DWORD* new_esp); +WORD get_link_selector_from_tss(); + +void task_switch(selector_t* selector, int type); + +/* type */ +enum { + TASK_SWITCH_JMP, + TASK_SWITCH_CALL, + TASK_SWITCH_IRET, + TASK_SWITCH_INTR, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* !IA32_CPU_TASK_H__ */ diff --git a/i386c/memory.c b/i386c/memory.c new file mode 100644 index 00000000..b307e8d3 --- /dev/null +++ b/i386c/memory.c @@ -0,0 +1,1035 @@ +#include "compiler.h" + +#ifndef NP2_MEMORY_ASM + +#include "cpucore.h" +#include "memory.h" +#include "egcmem.h" +#include "pccore.h" +#include "iocore.h" +#include "vram.h" +#include "font.h" + + +#define USE_HIMEM + +// ---- write byte + +static void MEMCALL i286_wt(UINT32 address, REG8 value) { + + mem[address & CPU_ADRSMASK] = (BYTE)value; +} + +static void MEMCALL tram_wt(UINT32 address, REG8 value) { + + CPU_REMCLOCK -= vramop.tramwait; + if (address < 0xa2000) { + mem[address] = (BYTE)value; + tramupdate[LOW12(address >> 1)] = 1; + gdcs.textdisp |= 1; + } + else if (address < 0xa3fe0) { + if (!(address & 1)) { + mem[address] = (BYTE)value; + tramupdate[LOW12(address >> 1)] = 1; + gdcs.textdisp |= 1; + } + } + else if (address < 0xa4000) { + if (!(address & 1)) { + if ((!(address & 2)) || (gdcs.msw_accessable)) { + mem[address] = (BYTE)value; + tramupdate[LOW12(address >> 1)] = 1; + gdcs.textdisp |= 1; + } + } + } + else if (address < 0xa5000) { + if ((address & 1) && (cgwindow.writable & 1)) { + cgwindow.writable |= 0x80; + fontrom[cgwindow.high + ((address >> 1) & 0x0f)] = (BYTE)value; + } + } +} + +static void MEMCALL vram_w0(UINT32 address, REG8 value) { + + CPU_REMCLOCK -= vramop.vramwait; + mem[address] = (BYTE)value; + vramupdate[LOW15(address)] |= 1; + gdcs.grphdisp |= 1; +} + +static void MEMCALL vram_w1(UINT32 address, REG8 value) { + + CPU_REMCLOCK -= vramop.vramwait; + mem[address + VRAM_STEP] = (BYTE)value; + vramupdate[LOW15(address)] |= 2; + gdcs.grphdisp |= 2; +} + +static void MEMCALL grcg_rmw0(UINT32 address, REG8 value) { + + REG8 mask; + BYTE *vram; + + CPU_REMCLOCK -= vramop.grcgwait; + mask = ~value; + address = LOW15(address); + vramupdate[address] |= 1; + gdcs.grphdisp |= 1; + vram = mem + address; + if (!(grcg.modereg & 1)) { + vram[VRAM0_B] &= mask; + vram[VRAM0_B] |= (value & grcg.tile[0].b[0]); + } + if (!(grcg.modereg & 2)) { + vram[VRAM0_R] &= mask; + vram[VRAM0_R] |= (value & grcg.tile[1].b[0]); + } + if (!(grcg.modereg & 4)) { + vram[VRAM0_G] &= mask; + vram[VRAM0_G] |= (value & grcg.tile[2].b[0]); + } + if (!(grcg.modereg & 8)) { + vram[VRAM0_E] &= mask; + vram[VRAM0_E] |= (value & grcg.tile[3].b[0]); + } +} + +static void MEMCALL grcg_rmw1(UINT32 address, REG8 value) { + + REG8 mask; + BYTE *vram; + + CPU_REMCLOCK -= vramop.grcgwait; + mask = ~value; + address = LOW15(address); + vramupdate[address] |= 2; + gdcs.grphdisp |= 2; + vram = mem + address; + if (!(grcg.modereg & 1)) { + vram[VRAM1_B] &= mask; + vram[VRAM1_B] |= (value & grcg.tile[0].b[0]); + } + if (!(grcg.modereg & 2)) { + vram[VRAM1_R] &= mask; + vram[VRAM1_R] |= (value & grcg.tile[1].b[0]); + } + if (!(grcg.modereg & 4)) { + vram[VRAM1_G] &= mask; + vram[VRAM1_G] |= (value & grcg.tile[2].b[0]); + } + if (!(grcg.modereg & 8)) { + vram[VRAM1_E] &= mask; + vram[VRAM1_E] |= (value & grcg.tile[3].b[0]); + } +} + +static void MEMCALL grcg_tdw0(UINT32 address, REG8 value) { + + BYTE *vram; + + CPU_REMCLOCK -= vramop.grcgwait; + address = LOW15(address); + vramupdate[address] |= 1; + gdcs.grphdisp |= 1; + vram = mem + address; + if (!(grcg.modereg & 1)) { + vram[VRAM0_B] = grcg.tile[0].b[0]; + } + if (!(grcg.modereg & 2)) { + vram[VRAM0_R] = grcg.tile[1].b[0]; + } + if (!(grcg.modereg & 4)) { + vram[VRAM0_G] = grcg.tile[2].b[0]; + } + if (!(grcg.modereg & 8)) { + vram[VRAM0_E] = grcg.tile[3].b[0]; + } + (void)value; +} + +static void MEMCALL grcg_tdw1(UINT32 address, REG8 value) { + + BYTE *vram; + + CPU_REMCLOCK -= vramop.grcgwait; + address = LOW15(address); + vramupdate[address] |= 2; + gdcs.grphdisp |= 2; + vram = mem + address; + if (!(grcg.modereg & 1)) { + vram[VRAM1_B] = grcg.tile[0].b[0]; + } + if (!(grcg.modereg & 2)) { + vram[VRAM1_R] = grcg.tile[1].b[0]; + } + if (!(grcg.modereg & 4)) { + vram[VRAM1_G] = grcg.tile[2].b[0]; + } + if (!(grcg.modereg & 8)) { + vram[VRAM1_E] = grcg.tile[3].b[0]; + } + (void)value; +} + +static void MEMCALL egc_wt(UINT32 address, REG8 value) { + + egc_write(address, value); +} + +static void MEMCALL emmc_wt(UINT32 address, REG8 value) { + + extmem.pageptr[(address >> 14) & 3][LOW14(address)] = (BYTE)value; +} + +static void MEMCALL i286_wn(UINT32 address, REG8 value) { + + (void)address; + (void)value; +} + + +// ---- read byte + +static REG8 MEMCALL i286_rd(UINT32 address) { + + return(mem[address & CPU_ADRSMASK]); +} + +static REG8 MEMCALL tram_rd(UINT32 address) { + + CPU_REMCLOCK -= vramop.tramwait; + if (address < 0xa4000) { + return(mem[address]); + } + else if (address < 0xa5000) { + if (address & 1) { + return(fontrom[cgwindow.high + ((address >> 1) & 0x0f)]); + } + else { + return(fontrom[cgwindow.low + ((address >> 1) & 0x0f)]); + } + } + return(mem[address]); +} + +static REG8 MEMCALL vram_r0(UINT32 address) { + + CPU_REMCLOCK -= vramop.vramwait; + return(mem[address]); +} + +static REG8 MEMCALL vram_r1(UINT32 address) { + + CPU_REMCLOCK -= vramop.vramwait; + return(mem[address + VRAM_STEP]); +} + +static REG8 MEMCALL grcg_tcr0(UINT32 address) { + +const BYTE *vram; + REG8 ret; + + CPU_REMCLOCK -= vramop.grcgwait; + vram = mem + LOW15(address); + ret = 0; + if (!(grcg.modereg & 1)) { + ret |= vram[VRAM0_B] ^ grcg.tile[0].b[0]; + } + if (!(grcg.modereg & 2)) { + ret |= vram[VRAM0_R] ^ grcg.tile[1].b[0]; + } + if (!(grcg.modereg & 4)) { + ret |= vram[VRAM0_G] ^ grcg.tile[2].b[0]; + } + if (!(grcg.modereg & 8)) { + ret |= vram[VRAM0_E] ^ grcg.tile[3].b[0]; + } + return(ret ^ 0xff); +} + +static REG8 MEMCALL grcg_tcr1(UINT32 address) { + +const BYTE *vram; + REG8 ret; + + CPU_REMCLOCK -= vramop.grcgwait; + ret = 0; + vram = mem + LOW15(address); + if (!(grcg.modereg & 1)) { + ret |= vram[VRAM1_B] ^ grcg.tile[0].b[0]; + } + if (!(grcg.modereg & 2)) { + ret |= vram[VRAM1_R] ^ grcg.tile[1].b[0]; + } + if (!(grcg.modereg & 4)) { + ret |= vram[VRAM1_G] ^ grcg.tile[2].b[0]; + } + if (!(grcg.modereg & 8)) { + ret |= vram[VRAM1_E] ^ grcg.tile[3].b[0]; + } + return(ret ^ 0xff); +} + +static REG8 MEMCALL egc_rd(UINT32 address) { + + return(egc_read(address)); +} + +static REG8 MEMCALL emmc_rd(UINT32 address) { + + return(extmem.pageptr[(address >> 14) & 3][LOW14(address)]); +} + +static REG8 MEMCALL i286_itf(UINT32 address) { + + if (CPU_ITFBANK) { + address = ITF_ADRS + LOW15(address); + } + return(mem[address]); +} + + +// ---- write word + +static void MEMCALL i286w_wt(UINT32 address, REG16 value) { + + BYTE *ptr; + + ptr = mem + (address & CPU_ADRSMASK); + STOREINTELWORD(ptr, value); +} + +static void MEMCALL tramw_wt(UINT32 address, REG16 value) { + + if (address < 0xa1fff) { + STOREINTELWORD(mem + address, value); + tramupdate[LOW12(address >> 1)] = 1; + tramupdate[LOW12((address + 1) >> 1)] = 1; + gdcs.textdisp |= 1; + } + else if (address == 0xa1fff) { + STOREINTELWORD(mem + address, value); + tramupdate[0] = 1; + tramupdate[0xfff] = 1; + gdcs.textdisp |= 1; + } + else if (address < 0xa3fe0) { + if (address & 1) { + address++; + value >>= 8; + } + mem[address] = (BYTE)value; + tramupdate[LOW12(address >> 1)] = 1; + gdcs.textdisp |= 1; + } + else if (address < 0xa3fff) { + if (address & 1) { + address++; + value >>= 8; + } + if ((!(address & 2)) || (gdcs.msw_accessable)) { + mem[address] = (BYTE)value; + tramupdate[LOW12(address >> 1)] = 1; + gdcs.textdisp |= 1; + } + } + else if (address < 0xa5000) { + if (address & 1) { + value >>= 8; + } + if (cgwindow.writable & 1) { + cgwindow.writable |= 0x80; + fontrom[cgwindow.high + ((address >> 1) & 0x0f)] = (BYTE)value; + } + } +} + + +#define GRCGW_NON(page) { \ + CPU_REMCLOCK -= vramop.vramwait; \ + STOREINTELWORD(mem + address + VRAM_STEP*(page), value); \ + vramupdate[LOW15(address)] |= (1 << page); \ + vramupdate[LOW15(address + 1)] |= (1 << page); \ + gdcs.grphdisp |= (1 << page); \ +} + +#define GRCGW_RMW(page) { \ + BYTE *vram; \ + CPU_REMCLOCK -= vramop.grcgwait; \ + address = LOW15(address); \ + vramupdate[address] |= (1 << page); \ + vramupdate[address + 1] |= (1 << page); \ + gdcs.grphdisp |= (1 << page); \ + vram = mem + address + (VRAM_STEP * (page)); \ + if (!(grcg.modereg & 1)) { \ + BYTE tmp; \ + tmp = (BYTE)value; \ + vram[VRAM0_B+0] &= (~tmp); \ + vram[VRAM0_B+0] |= (tmp & grcg.tile[0].b[0]); \ + tmp = (BYTE)(value >> 8); \ + vram[VRAM0_B+1] &= (~tmp); \ + vram[VRAM0_B+1] |= (tmp & grcg.tile[0].b[0]); \ + } \ + if (!(grcg.modereg & 2)) { \ + BYTE tmp; \ + tmp = (BYTE)value; \ + vram[VRAM0_R+0] &= (~tmp); \ + vram[VRAM0_R+0] |= (tmp & grcg.tile[1].b[0]); \ + tmp = (BYTE)(value >> 8); \ + vram[VRAM0_R+1] &= (~tmp); \ + vram[VRAM0_R+1] |= (tmp & grcg.tile[1].b[0]); \ + } \ + if (!(grcg.modereg & 4)) { \ + BYTE tmp; \ + tmp = (BYTE)value; \ + vram[VRAM0_G+0] &= (~tmp); \ + vram[VRAM0_G+0] |= (tmp & grcg.tile[2].b[0]); \ + tmp = (BYTE)(value >> 8); \ + vram[VRAM0_G+1] &= (~tmp); \ + vram[VRAM0_G+1] |= (tmp & grcg.tile[2].b[0]); \ + } \ + if (!(grcg.modereg & 8)) { \ + BYTE tmp; \ + tmp = (BYTE)value; \ + vram[VRAM0_E+0] &= (~tmp); \ + vram[VRAM0_E+0] |= (tmp & grcg.tile[3].b[0]); \ + tmp = (BYTE)(value >> 8); \ + vram[VRAM0_E+1] &= (~tmp); \ + vram[VRAM0_E+1] |= (tmp & grcg.tile[3].b[0]); \ + } \ +} + +#define GRCGW_TDW(page) { \ + BYTE *vram; \ + CPU_REMCLOCK -= vramop.grcgwait; \ + address = LOW15(address); \ + vramupdate[address] |= (1 << page); \ + vramupdate[address + 1] |= (1 << page); \ + gdcs.grphdisp |= (1 << page); \ + vram = mem + address + (VRAM_STEP * (page)); \ + if (!(grcg.modereg & 1)) { \ + vram[VRAM0_B+0] = grcg.tile[0].b[0]; \ + vram[VRAM0_B+1] = grcg.tile[0].b[0]; \ + } \ + if (!(grcg.modereg & 2)) { \ + vram[VRAM0_R+0] = grcg.tile[1].b[0]; \ + vram[VRAM0_R+1] = grcg.tile[1].b[0]; \ + } \ + if (!(grcg.modereg & 4)) { \ + vram[VRAM0_G+0] = grcg.tile[2].b[0]; \ + vram[VRAM0_G+1] = grcg.tile[2].b[0]; \ + } \ + if (!(grcg.modereg & 8)) { \ + vram[VRAM0_E+0] = grcg.tile[3].b[0]; \ + vram[VRAM0_E+1] = grcg.tile[3].b[0]; \ + } \ + (void)value; \ +} + +static void MEMCALL vramw_w0(UINT32 address, REG16 value) GRCGW_NON(0) +static void MEMCALL vramw_w1(UINT32 address, REG16 value) GRCGW_NON(1) +static void MEMCALL grcgw_rmw0(UINT32 address, REG16 value) GRCGW_RMW(0) +static void MEMCALL grcgw_rmw1(UINT32 address, REG16 value) GRCGW_RMW(1) +static void MEMCALL grcgw_tdw0(UINT32 address, REG16 value) GRCGW_TDW(0) +static void MEMCALL grcgw_tdw1(UINT32 address, REG16 value) GRCGW_TDW(1) + +static void MEMCALL egcw_wt(UINT32 address, REG16 value) { + + if (!(address & 1)) { + egc_write_w(address, value); + } + else { + if (!(egc.sft & 0x1000)) { + egc_write(address, (REG8)value); + egc_write(address + 1, (REG8)(value >> 8)); + } + else { + egc_write(address + 1, (REG8)(value >> 8)); + egc_write(address, (REG8)value); + } + } +} + +static void MEMCALL emmcw_wt(UINT32 address, REG16 value) { + + BYTE *ptr; + + if ((address & 0x3fff) != 0x3fff) { + ptr = extmem.pageptr[(address >> 14) & 3] + LOW14(address); + STOREINTELWORD(ptr, value); + } + else { + extmem.pageptr[(address >> 14) & 3][0x3fff] = (BYTE)value; + extmem.pageptr[((address + 1) >> 14) & 3][0] = (BYTE)(value >> 8); + } +} + +static void MEMCALL i286w_wn(UINT32 address, REG16 value) { + + (void)address; + (void)value; +} + + +// ---- read word + +static REG16 MEMCALL i286w_rd(UINT32 address) { + + BYTE *ptr; + + ptr = mem + (address & CPU_ADRSMASK); + return(LOADINTELWORD(ptr)); +} + +static REG16 MEMCALL tramw_rd(UINT32 address) { + + CPU_REMCLOCK -= vramop.tramwait; + if (address < (0xa4000 - 1)) { + return(LOADINTELWORD(mem + address)); + } + else if (address == 0xa3fff) { + return(mem[address] + (fontrom[cgwindow.low] << 8)); + } + else if (address < 0xa4fff) { + if (address & 1) { + REG16 ret; + ret = fontrom[cgwindow.high + ((address >> 1) & 0x0f)]; + ret += fontrom[cgwindow.low + (((address + 1) >> 1) & 0x0f)] << 8; + return(ret); + } + else { + REG16 ret; + ret = fontrom[cgwindow.low + ((address >> 1) & 0x0f)]; + ret += fontrom[cgwindow.high + ((address >> 1) & 0x0f)] << 8; + return(ret); + } + } + else if (address == 0xa4fff) { + return((mem[0xa5000] << 8) | fontrom[cgwindow.high + 15]); + } + return(LOADINTELWORD(mem + address)); +} + +static REG16 MEMCALL vramw_r0(UINT32 address) { + + CPU_REMCLOCK -= vramop.vramwait; + return(LOADINTELWORD(mem + address)); +} + +static REG16 MEMCALL vramw_r1(UINT32 address) { + + CPU_REMCLOCK -= vramop.vramwait; + return(LOADINTELWORD(mem + address + VRAM_STEP)); +} + +static REG16 MEMCALL grcgw_tcr0(UINT32 address) { + + BYTE *vram; + REG16 ret; + + CPU_REMCLOCK -= vramop.grcgwait; + ret = 0; + vram = mem + LOW15(address); + if (!(grcg.modereg & 1)) { + ret |= LOADINTELWORD(vram + VRAM0_B) ^ grcg.tile[0].w; + } + if (!(grcg.modereg & 2)) { + ret |= LOADINTELWORD(vram + VRAM0_R) ^ grcg.tile[1].w; + } + if (!(grcg.modereg & 4)) { + ret |= LOADINTELWORD(vram + VRAM0_G) ^ grcg.tile[2].w; + } + if (!(grcg.modereg & 8)) { + ret |= LOADINTELWORD(vram + VRAM0_E) ^ grcg.tile[3].w; + } + return((UINT16)~ret); +} + +static REG16 MEMCALL grcgw_tcr1(UINT32 address) { + + BYTE *vram; + REG16 ret; + + CPU_REMCLOCK -= vramop.grcgwait; + ret = 0; + vram = mem + LOW15(address); + if (!(grcg.modereg & 1)) { + ret |= LOADINTELWORD(vram + VRAM1_B) ^ grcg.tile[0].w; + } + if (!(grcg.modereg & 2)) { + ret |= LOADINTELWORD(vram + VRAM1_R) ^ grcg.tile[1].w; + } + if (!(grcg.modereg & 4)) { + ret |= LOADINTELWORD(vram + VRAM1_G) ^ grcg.tile[2].w; + } + if (!(grcg.modereg & 8)) { + ret |= LOADINTELWORD(vram + VRAM1_E) ^ grcg.tile[3].w; + } + return((UINT16)(~ret)); +} + +static REG16 MEMCALL egcw_rd(UINT32 address) { + + REG16 ret; + + if (!(address & 1)) { + return(egc_read_w(address)); + } + else { + if (!(egc.sft & 0x1000)) { + ret = egc_read(address); + ret += egc_read(address + 1) << 8; + return(ret); + } + else { + ret = egc_read(address + 1) << 8; + ret += egc_read(address); + return(ret); + } + } +} + +static REG16 MEMCALL emmcw_rd(UINT32 address) { + +const BYTE *ptr; + REG16 ret; + + if ((address & 0x3fff) != 0x3fff) { + ptr = extmem.pageptr[(address >> 14) & 3] + LOW14(address); + return(LOADINTELWORD(ptr)); + } + else { + ret = extmem.pageptr[(address >> 14) & 3][0x3fff]; + ret += extmem.pageptr[((address + 1) >> 14) & 3][0] << 8; + return(ret); + } +} + +static REG16 MEMCALL i286w_itf(UINT32 address) { + + if (CPU_ITFBANK) { + address = ITF_ADRS + LOW15(address); + } + return(LOADINTELWORD(mem + address)); +} + + +// ---- table + +typedef void (MEMCALL * MEM8WRITE)(UINT32 address, REG8 value); +typedef REG8 (MEMCALL * MEM8READ)(UINT32 address); +typedef void (MEMCALL * MEM16WRITE)(UINT32 address, REG16 value); +typedef REG16 (MEMCALL * MEM16READ)(UINT32 address); + +static MEM8WRITE memory_write[] = { + i286_wt, i286_wt, i286_wt, i286_wt, // 00 + i286_wt, i286_wt, i286_wt, i286_wt, // 20 + i286_wt, i286_wt, i286_wt, i286_wt, // 40 + i286_wt, i286_wt, i286_wt, i286_wt, // 60 + i286_wt, i286_wt, i286_wt, i286_wt, // 80 + tram_wt, vram_w0, vram_w0, vram_w0, // a0 + emmc_wt, emmc_wt, i286_wn, i286_wn, // c0 + vram_w0, i286_wn, i286_wn, i286_wn}; // e0 + +static MEM8READ memory_read[] = { + i286_rd, i286_rd, i286_rd, i286_rd, // 00 + i286_rd, i286_rd, i286_rd, i286_rd, // 20 + i286_rd, i286_rd, i286_rd, i286_rd, // 40 + i286_rd, i286_rd, i286_rd, i286_rd, // 60 + i286_rd, i286_rd, i286_rd, i286_rd, // 80 + tram_rd, vram_r0, vram_r0, vram_r0, // a0 + emmc_rd, emmc_rd, i286_rd, i286_rd, // c0 + vram_r0, i286_rd, i286_rd, i286_itf}; // f0 + +static MEM16WRITE memword_write[] = { + i286w_wt, i286w_wt, i286w_wt, i286w_wt, // 00 + i286w_wt, i286w_wt, i286w_wt, i286w_wt, // 20 + i286w_wt, i286w_wt, i286w_wt, i286w_wt, // 40 + i286w_wt, i286w_wt, i286w_wt, i286w_wt, // 60 + i286w_wt, i286w_wt, i286w_wt, i286w_wt, // 80 + tramw_wt, vramw_w0, vramw_w0, vramw_w0, // a0 + emmcw_wt, emmcw_wt, i286w_wn, i286w_wn, // c0 + vramw_w0, i286w_wn, i286w_wn, i286w_wn}; // e0 + +static MEM16READ memword_read[] = { + i286w_rd, i286w_rd, i286w_rd, i286w_rd, // 00 + i286w_rd, i286w_rd, i286w_rd, i286w_rd, // 20 + i286w_rd, i286w_rd, i286w_rd, i286w_rd, // 40 + i286w_rd, i286w_rd, i286w_rd, i286w_rd, // 60 + i286w_rd, i286w_rd, i286w_rd, i286w_rd, // 80 + tramw_rd, vramw_r0, vramw_r0, vramw_r0, // a0 + emmcw_rd, emmcw_rd, i286w_rd, i286w_rd, // c0 + vramw_r0, i286w_rd, i286w_rd, i286w_itf}; // e0 + +static const MEM8WRITE vram_write[] = { + vram_w0, vram_w1, vram_w0, vram_w1, // 00 + vram_w0, vram_w1, vram_w0, vram_w1, // 40 + grcg_tdw0, grcg_tdw1, egc_wt, egc_wt, // 80 tdw/tcr + grcg_rmw0, grcg_rmw1, egc_wt, egc_wt}; // c0 rmw + +static const MEM8READ vram_read[] = { + vram_r0, vram_r1, vram_r0, vram_r1, // 00 + vram_r0, vram_r1, vram_r0, vram_r1, // 40 + grcg_tcr0, grcg_tcr1, egc_rd, egc_rd, // 80 tdw/tcr + vram_r0, vram_r1, egc_rd, egc_rd}; // c0 rmw + +static const MEM16WRITE vramw_write[] = { + vramw_w0, vramw_w1, vramw_w0, vramw_w1, // 00 + vramw_w0, vramw_w1, vramw_w0, vramw_w1, // 40 + grcgw_tdw0, grcgw_tdw1, egcw_wt, egcw_wt, // 80 tdw/tcr + grcgw_rmw0, grcgw_rmw1, egcw_wt, egcw_wt}; // c0 rmw + +static const MEM16READ vramw_read[] = { + vramw_r0, vramw_r1, vramw_r0, vramw_r1, // 00 + vramw_r0, vramw_r1, vramw_r0, vramw_r1, // 40 + grcgw_tcr0, grcgw_tcr1, egcw_rd, egcw_rd, // 80 tdw/tcr + vramw_r0, vramw_r1, egcw_rd, egcw_rd}; // c0 rmw + + +static REG8 MEMCALL i286_nonram_r(UINT32 address) { + + (void)address; + return(0xff); +} + +static REG16 MEMCALL i286_nonram_rw(UINT32 address) { + + (void)address; + return(0xffff); +} + +void MEMCALL i286_vram_dispatch(UINT func) { + + UINT proc; + + proc = func & 0x0f; + memory_write[0xa8000 >> 15] = vram_write[proc]; + memory_write[0xb0000 >> 15] = vram_write[proc]; + memory_write[0xb8000 >> 15] = vram_write[proc]; + memory_write[0xe0000 >> 15] = vram_write[proc]; + + memory_read[0xa8000 >> 15] = vram_read[proc]; + memory_read[0xb0000 >> 15] = vram_read[proc]; + memory_read[0xb8000 >> 15] = vram_read[proc]; + memory_read[0xe0000 >> 15] = vram_read[proc]; + + memword_write[0xa8000 >> 15] = vramw_write[proc]; + memword_write[0xb0000 >> 15] = vramw_write[proc]; + memword_write[0xb8000 >> 15] = vramw_write[proc]; + memword_write[0xe0000 >> 15] = vramw_write[proc]; + + memword_read[0xa8000 >> 15] = vramw_read[proc]; + memword_read[0xb0000 >> 15] = vramw_read[proc]; + memword_read[0xb8000 >> 15] = vramw_read[proc]; + memword_read[0xe0000 >> 15] = vramw_read[proc]; + + if (!(func & 0x10)) { // degital + memory_write[0xe0000 >> 15] = i286_wn; + memword_write[0xe0000 >> 15] = i286w_wn; + memory_read[0xe0000 >> 15] = i286_nonram_r; + memword_read[0xe0000 >> 15] = i286_nonram_rw; + } +#if defined(USE_ASM) + i286a_vram_dispatch(func); +#endif +} + +REG8 MEMCALL __i286_memoryread(UINT32 address) { + + if (address < I286_MEMREADMAX) { + return(mem[address]); + } +#if defined(USE_HIMEM) + else if (address >= 0x10fff0) { + address -= 0x100000; + if (address < CPU_EXTMEMSIZE) { + return(CPU_EXTMEM[address]); + } + else { + return(0xff); + } + } +#endif + else { + return(memory_read[(address >> 15) & 0x1f](address)); + } +} + +REG16 MEMCALL __i286_memoryread_w(UINT32 address) { + + REG16 ret; + + if (address < (I286_MEMREADMAX - 1)) { + return(LOADINTELWORD(mem + address)); + } +#if defined(USE_HIMEM) + else if (address >= (0x10fff0 - 1)) { + address -= 0x100000; + if (address == (0x00fff0 - 1)) { + ret = mem[0x100000 + address]; + } + else if (address < CPU_EXTMEMSIZE) { + ret = CPU_EXTMEM[address]; + } + else { + ret = 0xff; + } + address++; + if (address < CPU_EXTMEMSIZE) { + ret += CPU_EXTMEM[address] << 8; + } + else { + ret += 0xff00; + } + return(ret); + } +#endif + else if ((address & 0x7fff) != 0x7fff) { + return(memword_read[(address >> 15) & 0x1f](address)); + } + else { + ret = memory_read[(address >> 15) & 0x1f](address); + address++; + ret += memory_read[(address >> 15) & 0x1f](address) << 8; + return(ret); + } +} + +UINT32 MEMCALL __i286_memoryread_d(UINT32 address) { + + UINT32 ret; + + ret = __i286_memoryread_w(address); + ret |= (UINT32)__i286_memoryread_w(address + 2) << 16; + + return ret; +} + +void MEMCALL __i286_memorywrite(UINT32 address, REG8 value) { + + if (address < I286_MEMWRITEMAX) { + mem[address] = (BYTE)value; + } +#if defined(USE_HIMEM) + else if (address >= 0x10fff0) { + address -= 0x100000; + if (address < CPU_EXTMEMSIZE) { + CPU_EXTMEM[address] = (BYTE)value; + } + } +#endif + else { + memory_write[(address >> 15) & 0x1f](address, value); + } +} + +void MEMCALL __i286_memorywrite_w(UINT32 address, REG16 value) { + + if (address < (I286_MEMWRITEMAX - 1)) { + STOREINTELWORD(mem + address, value); + } +#if defined(USE_HIMEM) + else if (address >= (0x10fff0 - 1)) { + address -= 0x100000; + if (address == (0x00fff0 - 1)) { + mem[address] = (BYTE)value; + } + else if (address < CPU_EXTMEMSIZE) { + CPU_EXTMEM[address] = (BYTE)value; + } + address++; + if (address < CPU_EXTMEMSIZE) { + CPU_EXTMEM[address] = (BYTE)(value >> 8); + } + } +#endif + else if ((address & 0x7fff) != 0x7fff) { + memword_write[(address >> 15) & 0x1f](address, value); + } + else { + memory_write[(address >> 15) & 0x1f](address, (BYTE)value); + address++; + memory_write[(address >> 15) & 0x1f](address, (BYTE)(value >> 8)); + } +} + +void MEMCALL __i286_memorywrite_d(UINT32 address, UINT32 value) { + + __i286_memorywrite_w(address, value & 0xffff); + __i286_memorywrite_w(address + 2, (WORD)(value >> 16)); +} + +#if 0 +REG8 MEMCALL i286_membyte_read(UINT seg, UINT off) { + + UINT32 address; + + address = (seg << 4) + off; + if (address < I286_MEMREADMAX) { + return(mem[address]); + } + else { + return(i286_memoryread(address)); + } +} + +REG16 MEMCALL i286_memword_read(UINT seg, UINT off) { + + UINT32 address; + + address = (seg << 4) + off; + if (address < (I286_MEMREADMAX - 1)) { + return(LOADINTELWORD(mem + address)); + } + else { + return(i286_memoryread_w(address)); + } +} + +void MEMCALL i286_membyte_write(UINT seg, UINT off, REG8 value) { + + UINT32 address; + + address = (seg << 4) + off; + if (address < I286_MEMWRITEMAX) { + mem[address] = (BYTE)value; + } + else { + i286_memorywrite(address, value); + } +} + +void MEMCALL i286_memword_write(UINT seg, UINT off, REG16 value) { + + UINT32 address; + + address = (seg << 4) + off; + if (address < (I286_MEMWRITEMAX - 1)) { + STOREINTELWORD(mem + address, value); + } + else { + i286_memorywrite_w(address, value); + } +} +#endif + +void MEMCALL i286_memstr_read(UINT seg, UINT off, void *dat, UINT leng) { + + BYTE *out; + UINT32 adrs; + UINT size; + + out = (BYTE *)dat; + adrs = seg << 4; + if ((I286_MEMREADMAX >= 0x10000) && + (adrs < (I286_MEMREADMAX - 0x10000))) { + if (leng) { + size = 0x10000 - off; + if (size >= leng) { + CopyMemory(out, mem + adrs + off, leng); + return; + } + CopyMemory(out, mem + adrs + off, size); + out += size; + leng -= size; + } + while(leng >= 0x10000) { + CopyMemory(out, mem + adrs, 0x10000); + out += 0x10000; + leng -= 0x10000; + } + if (leng) { + CopyMemory(out, mem + adrs, leng); + } + } + else { + while(leng--) { + *out++ = i286_memoryread(adrs + off); + off = LOW16(off + 1); + } + } +} + +void MEMCALL i286_memstr_write(UINT seg, UINT off, + const void *dat, UINT leng) { + + BYTE *out; + UINT32 adrs; + UINT size; + + out = (BYTE *)dat; + adrs = seg << 4; + if ((I286_MEMWRITEMAX >= 0x10000) && + (adrs < (I286_MEMWRITEMAX - 0x10000))) { + if (leng) { + size = 0x10000 - off; + if (size >= leng) { + CopyMemory(mem + adrs + off, out, leng); + return; + } + CopyMemory(mem + adrs + off, out, size); + out += size; + leng -= size; + } + while(leng >= 0x10000) { + CopyMemory(mem + adrs, out, 0x10000); + out += 0x10000; + leng -= 0x10000; + } + if (leng) { + CopyMemory(mem + adrs, out, leng); + } + } + else { + while(leng--) { + i286_memorywrite(adrs + off, *out++); + off = LOW16(off + 1); + } + } +} + +void MEMCALL i286_memx_read(UINT32 address, void *dat, UINT leng) { + + if ((address + leng) < I286_MEMREADMAX) { + CopyMemory(dat, mem + address, leng); + } + else { + BYTE *out = (BYTE *)dat; + if (address < I286_MEMREADMAX) { + CopyMemory(out, mem + address, I286_MEMREADMAX - address); + out += I286_MEMREADMAX - address; + leng -= I286_MEMREADMAX - address; + address = I286_MEMREADMAX; + } + while(leng--) { + *out++ = i286_memoryread(address++); + } + } +} + +void MEMCALL i286_memx_write(UINT32 address, const void *dat, UINT leng) { + +const BYTE *out; + + if ((address + leng) < I286_MEMWRITEMAX) { + CopyMemory(mem + address, dat, leng); + } + else { + out = (BYTE *)dat; + if (address < I286_MEMWRITEMAX) { + CopyMemory(mem + address, out, I286_MEMWRITEMAX - address); + out += I286_MEMWRITEMAX - address; + leng -= I286_MEMWRITEMAX - address; + address = I286_MEMWRITEMAX; + } + while(leng--) { + i286_memorywrite(address++, *out++); + } + } +} + +#endif + diff --git a/i386c/memory.h b/i386c/memory.h new file mode 100644 index 00000000..1bad7f3d --- /dev/null +++ b/i386c/memory.h @@ -0,0 +1,156 @@ + +#ifdef NP2_MEMORY_ASM // アセンブラ版は 必ずfastcallで +#undef MEMCALL +#define MEMCALL FASTCALL +#endif + + +// 000000-0fffff メインメモリ +// 100000-10ffef HMA +// 110000-193fff FONT-ROM/RAM +// 1a8000-1e7fff VRAM1 +// 1f8000-1fffff ITF-ROM + +#define VRAM_STEP 0x100000 +#define VRAM_B 0x0a8000 +#define VRAM_R 0x0b0000 +#define VRAM_G 0x0b8000 +#define VRAM_E 0x0e0000 + +#define VRAM_POS(a) ((a) & (VRAM_STEP | 0x7fff)) + +#define VRAM0_B VRAM_B +#define VRAM0_R VRAM_R +#define VRAM0_G VRAM_G +#define VRAM0_E VRAM_E +#define VRAM1_B (VRAM_STEP + VRAM_B) +#define VRAM1_R (VRAM_STEP + VRAM_R) +#define VRAM1_G (VRAM_STEP + VRAM_G) +#define VRAM1_E (VRAM_STEP + VRAM_E) + +#define FONT_ADRS 0x110000 +#define ITF_ADRS 0x1f8000 + +#if defined(CPU386) +#if 0 +#define LOWMEM 0x100000 +#else +#define LOWMEM 0x10fff0 +#endif +#endif /* CPU386 */ + + +#if defined(BYTESEX_LITTLE) + +#define MEM_SETB(pos, data) mem[pos] = data +#define MEM_ANDB(pos, data) mem[pos] &= data +#define MEM_XORB(pos, data) mem[pos] ^= data +#define MEM_ORB(pos, data) mem[pos] |= data +#define MEM_SETW(pos, data) *(WORD *)(mem + (pos)) = (data) +#define MEM_SETD(pos, data) *(DWORD *)(mem + (pos)) = (data) +#define MEM_GETB(pos) (mem[pos]) +#define MEM_GETW(pos) (*(WORD *)(mem + (pos))) +#define MEM_GETD(pos) (*(DWORD *)(mem + (pos))) + +#elif defined(BYTESEX_BIG) + +#define MEM_SETB(pos, data) mem[pos] = data +#define MEM_ANDB(pos, data) mem[pos] &= data +#define MEM_XORB(pos, data) mem[pos] ^= data +#define MEM_ORB(pos, data) mem[pos] |= data +#define MEM_SETW(pos, data) \ + mem[(pos)] = (BYTE)data; \ + mem[(pos) + 1] = (BYTE)(data >> 8); +#define MEM_SETD(pos, data) \ + mem[(pos)] = (BYTE)data; \ + mem[(pos) + 1] = (BYTE)(data >> 8); \ + mem[(pos) + 2] = (BYTE)(data >> 16); \ + mem[(pos) + 3] = (BYTE)(data >> 24); +#define MEM_GETB(pos) (mem[pos]) +#define MEM_GETW(pos) \ + (((WORD)mem[(pos) + 1] << 8) | mem[(pos)]) +#define MEM_GETD(pos) \ + (((DWORD)mem[(pos) + 3] << 24) | \ + ((DWORD)mem[(pos) + 2] << 16) | \ + ((WORD)mem[(pos) + 1] << 8) | mem[(pos)]) +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +extern BYTE mem[0x200000]; + +void MEMCALL i286_vram_dispatch(UINT operate); + +void MEMCALL __i286_memorywrite(UINT32 address, REG8 value); +void MEMCALL __i286_memorywrite_w(UINT32 address, REG16 value); +void MEMCALL __i286_memorywrite_d(UINT32 address, UINT32 value); +REG8 MEMCALL __i286_memoryread(UINT32 address); +REG16 MEMCALL __i286_memoryread_w(UINT32 address); +UINT32 MEMCALL __i286_memoryread_d(UINT32 address); + +#ifndef CPU386 +#define i286_memorywrite(a,v) __i286_memorywrite(a,v) +#define i286_memorywrite_w(a,v) __i286_memorywrite_w(a,v) +#define i286_memorywrite_d(a,v) __i286_memorywrite_d(a,v) +#define i286_memoryread(a) __i286_memoryread(a) +#define i286_memoryread_w(a) __i286_memoryread_w(a) +#define i286_memoryread_d(a) __i286_memoryread_d(a) +#else /* CPU386 */ +void MEMCALL cpu_memorywrite(DWORD address, BYTE value); +void MEMCALL cpu_memorywrite_w(DWORD address, WORD value); +void MEMCALL cpu_memorywrite_d(DWORD address, DWORD value); +BYTE MEMCALL cpu_memoryread(DWORD address); +WORD MEMCALL cpu_memoryread_w(DWORD address); +DWORD MEMCALL cpu_memoryread_d(DWORD address); +#define i286_memorywrite(a,v) cpu_memorywrite(a,v) +#define i286_memorywrite_w(a,v) cpu_memorywrite_w(a,v) +#define i286_memorywrite_d(a,v) cpu_memorywrite_d(a,v) +#define i286_memoryread(a) cpu_memoryread(a) +#define i286_memoryread_w(a) cpu_memoryread_w(a) +#define i286_memoryread_d(a) cpu_memoryread_d(a) +#endif + +#ifdef NP2_MEMORY_ASM +BYTE MEMCALL i286_membyte_read(WORD seg, WORD off); +WORD MEMCALL i286_memword_read(WORD seg, WORD off); +void MEMCALL i286_membyte_write(WORD seg, WORD off, BYTE dat); +void MEMCALL i286_memword_write(WORD seg, WORD off, WORD dat); +#else +#define i286_membyte_read(a, b) \ + i286_memoryread(((DWORD)(a) << 4) + (WORD)(b)) +#define i286_memword_read(a, b) \ + i286_memoryread_w(((DWORD)(a) << 4) + (WORD)(b)) + +#define i286_membyte_write(a, b, c) \ + i286_memorywrite(((DWORD)(a) << 4) + (WORD)(b), (c)) +#define i286_memword_write(a, b, c) \ + i286_memorywrite_w(((DWORD)(a) << 4) + (WORD)(b), (c)) +#endif + +void MEMCALL i286_memstr_read(UINT seg, UINT off, void *dat, UINT leng); +void MEMCALL i286_memstr_write(UINT seg, UINT off, + const void *dat, UINT leng); +void MEMCALL i286_memx_read(UINT32 address, void *dat, UINT leng); +void MEMCALL i286_memx_write(UINT32 address, const void *dat, UINT leng); + +#ifdef __cplusplus +} +#endif + + +// とりあえず +#define GETDWORD(a) (((UINT32)(a)[0]) | \ + ((UINT32)(a)[1] << 8) | \ + ((UINT32)(a)[2] << 16) | \ + ((UINT32)(a)[3] << 24)) +#define GETWORD(a) (((UINT16)(a)[0]) | ((UINT16)(a)[1] << 8)) +#define SETDWORD(a, b) *((a)+0) = (BYTE)((b)); \ + *((a)+1) = (BYTE)((b)>>8); \ + *((a)+2) = (BYTE)((b)>>16); \ + *((a)+3) = (BYTE)((b)>>24) +#define SETWORD(a, b) *((a)+0) = (BYTE)((b)); \ + *((a)+1) = (BYTE)((b)>>8) + diff --git a/io/artic.c b/io/artic.c index bd2e7474..064e98a7 100644 --- a/io/artic.c +++ b/io/artic.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" @@ -16,7 +16,7 @@ void artic_callback(void) { else { mul *= 13; } - leng = I286_CLOCK + I286_BASECLOCK + I286_REMCLOCK; + leng = CPU_CLOCK + CPU_BASECLOCK + CPU_REMCLOCK; leng *= 2; leng -= artic.lastclk2; if (leng > 0) { @@ -38,7 +38,7 @@ static UINT32 artic_getcnt(void) { else { mul *= 13; } - leng = I286_CLOCK + I286_BASECLOCK + I286_REMCLOCK; + leng = CPU_CLOCK + CPU_BASECLOCK + CPU_REMCLOCK; leng *= 2; leng -= artic.lastclk2; if (leng > 0) { @@ -51,29 +51,29 @@ static UINT32 artic_getcnt(void) { // ---- I/O -static void IOOUTCALL artic_o5c(UINT port, BYTE dat) { +static void IOOUTCALL artic_o5c(UINT port, REG8 dat) { (void)port; (void)dat; - I286_REMCLOCK -= 20; + CPU_REMCLOCK -= 20; } -static BYTE IOINPCALL artic_i5c(UINT port) { +static REG8 IOINPCALL artic_i5c(UINT port) { (void)port; - return((BYTE)artic_getcnt()); + return((UINT8)artic_getcnt()); } -static BYTE IOINPCALL artic_i5d(UINT port) { +static REG8 IOINPCALL artic_i5d(UINT port) { (void)port; - return((BYTE)(artic_getcnt() >> 8)); + return((UINT8)(artic_getcnt() >> 8)); } -static BYTE IOINPCALL artic_i5f(UINT port) { +static REG8 IOINPCALL artic_i5f(UINT port) { (void)port; - return((BYTE)(artic_getcnt() >> 16)); + return((UINT8)(artic_getcnt() >> 16)); } @@ -93,7 +93,7 @@ void artic_bind(void) { iocore_attachinp(0x005f, artic_i5f); } -UINT16 IOINPCALL artic_r16(UINT port) { +REG16 IOINPCALL artic_r16(UINT port) { UINT32 cnt; diff --git a/io/artic.h b/io/artic.h index 8ccb3676..18fdf2fe 100644 --- a/io/artic.h +++ b/io/artic.h @@ -13,7 +13,7 @@ void artic_callback(void); void artic_reset(void); void artic_bind(void); -UINT16 IOINPCALL artic_r16(UINT port); +REG16 IOINPCALL artic_r16(UINT port); #ifdef __cplusplus } diff --git a/io/cgrom.c b/io/cgrom.c index c2167fb8..8684b965 100644 --- a/io/cgrom.c +++ b/io/cgrom.c @@ -41,7 +41,7 @@ static void cgwindowset(CGROM cr) { // ---- I/O // write charactor code low -static void IOOUTCALL cgrom_oa1(UINT port, BYTE dat) { +static void IOOUTCALL cgrom_oa1(UINT port, REG8 dat) { CGROM cr; @@ -52,7 +52,7 @@ static void IOOUTCALL cgrom_oa1(UINT port, BYTE dat) { } // write charactor code high -static void IOOUTCALL cgrom_oa3(UINT port, BYTE dat) { +static void IOOUTCALL cgrom_oa3(UINT port, REG8 dat) { CGROM cr; @@ -63,7 +63,7 @@ static void IOOUTCALL cgrom_oa3(UINT port, BYTE dat) { } // write charactor line -static void IOOUTCALL cgrom_oa5(UINT port, BYTE dat) { +static void IOOUTCALL cgrom_oa5(UINT port, REG8 dat) { CGROM cr; @@ -75,20 +75,20 @@ static void IOOUTCALL cgrom_oa5(UINT port, BYTE dat) { } // CG write pattern -static void IOOUTCALL cgrom_oa9(UINT port, BYTE dat) { +static void IOOUTCALL cgrom_oa9(UINT port, REG8 dat) { CGROM cr; cr = &cgrom; if ((cr->code & 0x007e) == 0x0056) { fontrom[((cr->code & 0x7f7f) << 4) + - cr->lr + cr->line] = dat; + cr->lr + cr->line] = (UINT8)dat; cgwindow.writable |= 0x80; } (void)port; } -static BYTE IOINPCALL cgrom_ia9(UINT port) { +static REG8 IOINPCALL cgrom_ia9(UINT port) { CGROM cr; const BYTE *ptr; diff --git a/io/cgrom.h b/io/cgrom.h index 454fad75..101b4e63 100644 --- a/io/cgrom.h +++ b/io/cgrom.h @@ -8,7 +8,7 @@ typedef struct { typedef struct { UINT low; UINT high; - BYTE writable; + UINT8 writable; } _CGWINDOW, *CGWINDOW; diff --git a/io/cpuio.c b/io/cpuio.c index c65d1243..4dfdcf88 100644 --- a/io/cpuio.c +++ b/io/cpuio.c @@ -1,31 +1,42 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "sound.h" #include "fmboard.h" +// 後で調整 +#if defined(CPU386) +DWORD cpumem_addrmask = 0xfffff; +#endif + // ---- I/O -static void IOOUTCALL cpuio_of0(UINT port, BYTE dat) { +static void IOOUTCALL cpuio_of0(UINT port, REG8 dat) { - i286core.s.adrsmask = 0x0fffff; - i286core.s.resetreq = 1; - i286_interrupt(0x02); + CPU_ADRSMASK = 0x0fffff; +#if defined(CPU386) + cpumem_addrmask = 0xfffff; +#endif + CPU_RESETREQ = 1; + CPU_INTERRUPT(0x02); nevent_forceexit(); (void)port; (void)dat; } -static void IOOUTCALL cpuio_of2(UINT port, BYTE dat) { +static void IOOUTCALL cpuio_of2(UINT port, REG8 dat) { - i286core.s.adrsmask = 0x1fffff; + CPU_ADRSMASK = 0x1fffff; +#if defined(CPU386) + cpumem_addrmask = 0xffffffff; +#endif (void)port; (void)dat; } -static BYTE IOINPCALL cpuio_if0(UINT port) { +static REG8 IOINPCALL cpuio_if0(UINT port) { BYTE ret; @@ -39,43 +50,54 @@ static BYTE IOINPCALL cpuio_if0(UINT port) { return(ret); } -static BYTE IOINPCALL cpuio_if2(UINT port) { +static REG8 IOINPCALL cpuio_if2(UINT port) { - BYTE ret; + REG8 ret; +#if 1 + ret = 0xff; + ret -= (REG8)((CPU_ADRSMASK >> 20) & 1); +#else ret = 0xfe; - if (i286core.s.adrsmask != 0x1fffff) { + if (CPU_ADRSMASK != 0x1fffff) { ret++; } +#endif (void)port; return(ret); } #ifdef CPU386 // defineを変えてね -static void IOOUTCALL cpuio_of6(UINT port, BYTE dat) { +static void IOOUTCALL cpuio_of6(UINT port, REG8 dat) { switch(dat) { case 0x02: - i286core.s.adrsmask = 0x1fffff; + CPU_ADRSMASK = 0x1fffff; +#if defined(CPU_386) + cpumem_addrmask = 0xffffffff; +#endif break; case 0x03: - i286core.s.adrsmask = 0x0fffff; + CPU_ADRSMASK = 0x0fffff; +#if defined(CPU_386) + cpumem_addrmask = 0xfffff; +#endif break; } (void)port; } -static BYTE IOINPCALL cpuio_if6(UINT port) { +static REG8 IOINPCALL cpuio_if6(UINT port) { - BYTE ret; + REG8 ret; ret = 0x00; - if (i286core.s.adrsmask != 0x1fffff) { + if (CPU_ADRSMASK != 0x1fffff) { ret |= 0x01; } - if (nmi.enable) { + if (nmiio.enable) { ret |= 0x02; } (void)port; diff --git a/io/crtc.c b/io/crtc.c index 4cd956e9..abad6fe3 100644 --- a/io/crtc.c +++ b/io/crtc.c @@ -7,20 +7,20 @@ // ---- I/O -static void IOOUTCALL crtc_o70(UINT port, BYTE dat) { +static void IOOUTCALL crtc_o70(UINT port, REG8 dat) { port = (port & 0x0e) >> 1; dat &= 0x1f; if (crtc.b[port] != dat) { - crtc.b[port] = dat; + crtc.b[port] = (UINT8)dat; gdcs.textdisp |= GDCSCRN_ALLDRAW; } } -static void IOOUTCALL crtc_o7c(UINT port, BYTE dat) { +static void IOOUTCALL crtc_o7c(UINT port, REG8 dat) { if (grcg.chip) { - grcg.modereg = dat; + grcg.modereg = (UINT8)dat; grcg.counter = 0; vramop.operate &= VOP_GRCGMASK; vramop.operate |= ((dat & 0xc0) >> 4); @@ -32,18 +32,18 @@ static void IOOUTCALL crtc_o7c(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL crtc_o7e(UINT port, BYTE dat) { +static void IOOUTCALL crtc_o7e(UINT port, REG8 dat) { int cnt; cnt = grcg.counter; - grcg.tile[cnt].b[0] = dat; - grcg.tile[cnt].b[1] = dat; + grcg.tile[cnt].b[0] = (UINT8)dat; + grcg.tile[cnt].b[1] = (UINT8)dat; grcg.counter = (cnt + 1) & 3; (void)port; } -static BYTE IOINPCALL crtc_i7c(UINT port) { +static REG8 IOINPCALL crtc_i7c(UINT port) { (void)port; return(grcg.modereg); diff --git a/io/crtc.h b/io/crtc.h index 550693da..390867d9 100644 --- a/io/crtc.h +++ b/io/crtc.h @@ -1,29 +1,29 @@ typedef union { struct { - BYTE pl; - BYTE bl; - BYTE cl; - BYTE ssl; - BYTE sur; - BYTE sdr; + UINT8 pl; + UINT8 bl; + UINT8 cl; + UINT8 ssl; + UINT8 sur; + UINT8 sdr; } reg; - BYTE b[6]; + UINT8 b[6]; } _CRTC, *CRTC; typedef union { - BYTE b[2]; + UINT8 b[2]; UINT16 w; } PAIR16; typedef struct { UINT32 counter; UINT16 mode; - BYTE modereg; - BYTE padding; + UINT8 modereg; + UINT8 padding; PAIR16 tile[4]; UINT32 gdcwithgrcg; - BYTE chip; + UINT8 chip; } _GRCG, *GRCG; diff --git a/io/dipsw.c b/io/dipsw.c index 4adae180..50a08b57 100644 --- a/io/dipsw.c +++ b/io/dipsw.c @@ -1,13 +1,13 @@ #include "compiler.h" #include "sysmng.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "sound.h" #include "beep.h" -void IOOUTCALL dipsw_w8(UINT port, BYTE value) { +void IOOUTCALL dipsw_w8(UINT port, REG8 value) { BYTE set; UINT update; @@ -76,10 +76,11 @@ void IOOUTCALL dipsw_w8(UINT port, BYTE value) { sysmng_update(update); } -BYTE IOINPCALL dipsw_r8(UINT port) { +REG8 IOINPCALL dipsw_r8(UINT port) { - BYTE ret = 0xff; + REG8 ret; + ret = 0xff; switch(port & 0x0f00) { case 0x0400: ret = (np2cfg.dipsw[0] ^ 0x04) & 0xbc; diff --git a/io/dipsw.h b/io/dipsw.h index 35f45ae4..689a2e71 100644 --- a/io/dipsw.h +++ b/io/dipsw.h @@ -3,8 +3,8 @@ extern "C" { #endif -void IOOUTCALL dipsw_w8(UINT port, BYTE value); -BYTE IOINPCALL dipsw_r8(UINT port); +void IOOUTCALL dipsw_w8(UINT port, REG8 value); +REG8 IOINPCALL dipsw_r8(UINT port); #ifdef __cplusplus } diff --git a/io/dmac.c b/io/dmac.c index 9dc11b1d..d1f84ce6 100644 --- a/io/dmac.c +++ b/io/dmac.c @@ -5,17 +5,17 @@ #include "cs4231.h" -void DMACCALL dma_dummyout(BYTE data) { +void DMACCALL dma_dummyout(REG8 data) { (void)data; } -BYTE DMACCALL dma_dummyin(void) { +REG8 DMACCALL dma_dummyin(void) { return(0xff); } -BYTE DMACCALL dma_dummyproc(BYTE func) { +REG8 DMACCALL dma_dummyproc(REG8 func) { (void)func; return(0); @@ -28,7 +28,7 @@ void dmac_check(void) { BOOL workchg; DMACH ch; - BYTE bit; + REG8 bit; workchg = FALSE; ch = dmac.dmach; @@ -63,7 +63,7 @@ void dmac_check(void) { // ---- I/O -static void IOOUTCALL dmac_o01(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o01(UINT port, REG8 dat) { DMACH dmach; int lh; @@ -75,7 +75,7 @@ static void IOOUTCALL dmac_o01(UINT port, BYTE dat) { dmach->adrsorg.b[lh] = dat; } -static void IOOUTCALL dmac_o03(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o03(UINT port, REG8 dat) { int ch; DMACH dmach; @@ -90,13 +90,13 @@ static void IOOUTCALL dmac_o03(UINT port, BYTE dat) { dmac.stat &= ~(1 << ch); } -static void IOOUTCALL dmac_o13(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o13(UINT port, REG8 dat) { dmac.dmach[dat & 3].sreq = dat; (void)port; } -static void IOOUTCALL dmac_o15(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o15(UINT port, REG8 dat) { if (dat & 4) { dmac.mask |= (1 << (dat & 3)); @@ -108,34 +108,34 @@ static void IOOUTCALL dmac_o15(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL dmac_o17(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o17(UINT port, REG8 dat) { dmac.dmach[dat & 3].mode = dat; (void)port; } -static void IOOUTCALL dmac_o19(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o19(UINT port, REG8 dat) { dmac.lh = DMA16_LOW; (void)port; (void)dat; } -static void IOOUTCALL dmac_o1b(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o1b(UINT port, REG8 dat) { dmac.mask = 0x0f; (void)port; (void)dat; } -static void IOOUTCALL dmac_o1f(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o1f(UINT port, REG8 dat) { dmac.mask = dat; dmac_check(); (void)port; } -static void IOOUTCALL dmac_o21(UINT port, BYTE dat) { +static void IOOUTCALL dmac_o21(UINT port, REG8 dat) { DMACH dmach; @@ -143,7 +143,7 @@ static void IOOUTCALL dmac_o21(UINT port, BYTE dat) { dmach->adrs.b[DMA32_HIGH + DMA16_LOW] = dat; } -static BYTE IOINPCALL dmac_i01(UINT port) { +static REG8 IOINPCALL dmac_i01(UINT port) { DMACH dmach; int lh; @@ -154,7 +154,7 @@ static BYTE IOINPCALL dmac_i01(UINT port) { return(dmach->leng.b[lh]); } -static BYTE IOINPCALL dmac_i03(UINT port) { +static REG8 IOINPCALL dmac_i03(UINT port) { DMACH dmach; int lh; @@ -165,7 +165,7 @@ static BYTE IOINPCALL dmac_i03(UINT port) { return(dmach->adrs.b[lh + DMA32_LOW]); } -static BYTE IOINPCALL dmac_i11(UINT port) { +static REG8 IOINPCALL dmac_i11(UINT port) { (void)port; return(dmac.stat); // ToDo!! diff --git a/io/dmac.h b/io/dmac.h index f1e1f3e4..ac0c85ed 100644 --- a/io/dmac.h +++ b/io/dmac.h @@ -52,13 +52,13 @@ typedef struct { UINT16 w; } lengorg; UINT16 action; - void (DMACCALL * outproc)(BYTE data); - BYTE (DMACCALL * inproc)(void); - BYTE (DMACCALL * extproc)(BYTE action); - BYTE mode; - BYTE sreq; - BYTE ready; - BYTE mask; + void (DMACCALL * outproc)(REG8 data); + REG8 (DMACCALL * inproc)(void); + REG8 (DMACCALL * extproc)(REG8 action); + UINT8 mode; + UINT8 sreq; + UINT8 ready; + UINT8 mask; } _DMACH, *DMACH; typedef struct { @@ -66,8 +66,8 @@ typedef struct { int lh; UINT work; UINT working; - BYTE mask; - BYTE stat; + UINT8 mask; + UINT8 stat; } _DMAC, *DMAC; @@ -75,9 +75,9 @@ typedef struct { extern "C" { #endif -void DMACCALL dma_dummyout(BYTE data); -BYTE DMACCALL dma_dummyin(void); -BYTE DMACCALL dma_dummyproc(BYTE func); +void DMACCALL dma_dummyout(REG8 data); +REG8 DMACCALL dma_dummyin(void); +REG8 DMACCALL dma_dummyproc(REG8 func); void dmac_reset(void); void dmac_bind(void); diff --git a/io/egc.c b/io/egc.c index bef25a0e..2d7e3765 100644 --- a/io/egc.c +++ b/io/egc.c @@ -19,7 +19,7 @@ static const UINT16 maskword[16][4] = { {0x0000,0xffff,0xffff,0xffff}, {0xffff,0xffff,0xffff,0xffff}}; -static void IOOUTCALL egc_o4a0(UINT port, BYTE value) { +static void IOOUTCALL egc_o4a0(UINT port, REG8 value) { if (!(vramop.operate & VOP_EGCBIT)) { return; @@ -130,7 +130,7 @@ void egc_bind(void) { } } -void IOOUTCALL egc_w16(UINT port, UINT16 value) { +void IOOUTCALL egc_w16(UINT port, REG16 value) { if (!(vramop.operate & VOP_EGCBIT)) { return; diff --git a/io/egc.h b/io/egc.h index 89dad73d..baac1e70 100644 --- a/io/egc.h +++ b/io/egc.h @@ -1,11 +1,11 @@ typedef union { - BYTE _b[2]; + UINT8 _b[2]; UINT16 w; } EGCWORD; typedef union { - BYTE _b[4][2]; + UINT8 _b[4][2]; UINT16 w[4]; UINT32 d[2]; } EGCQUAD; @@ -34,10 +34,10 @@ typedef struct { BYTE *outptr; EGCWORD mask2; EGCWORD srcmask; - BYTE srcbit; - BYTE dstbit; - BYTE sft8bitl; - BYTE sft8bitr; + UINT8 srcbit; + UINT8 dstbit; + UINT8 sft8bitl; + UINT8 sft8bitr; } _EGC, *EGC; @@ -47,7 +47,7 @@ extern "C" { void egc_reset(void); void egc_bind(void); -void IOOUTCALL egc_w16(UINT port, UINT16 value); +void IOOUTCALL egc_w16(UINT port, REG16 value); #ifdef __cplusplus } diff --git a/io/extmem.c b/io/extmem.c index 118438cb..dd0c47b2 100644 --- a/io/extmem.c +++ b/io/extmem.c @@ -1,35 +1,31 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" - BYTE *extmemmng_ptr; - UINT32 extmemmng_size; - - void extmemmng_clear(void) { - if (extmemmng_ptr) { - free(extmemmng_ptr); - extmemmng_ptr = NULL; - extmemmng_size = 0; + if (CPU_EXTMEM) { + _MFREE(CPU_EXTMEM); + CPU_EXTMEM = NULL; + CPU_EXTMEMSIZE = 0; } } BOOL extmemmng_realloc(UINT megabytes) { megabytes <<= 20; - if (megabytes != extmemmng_size) { + if (megabytes != CPU_EXTMEMSIZE) { extmemmng_clear(); if (megabytes) { - extmemmng_ptr = (BYTE *)malloc(megabytes + 16); - if (extmemmng_ptr == NULL) { + CPU_EXTMEM = (BYTE *)_MALLOC(megabytes + 16, "EXTMEM"); + if (CPU_EXTMEM == NULL) { return(FAILURE); } } - extmemmng_size = megabytes; + CPU_EXTMEMSIZE = megabytes; } return(SUCCESS); } @@ -37,11 +33,11 @@ BOOL extmemmng_realloc(UINT megabytes) { // ---- I/O -static void IOOUTCALL emm_o08e1(UINT port, BYTE dat) { +static void IOOUTCALL emm_o08e1(UINT port, REG8 dat) { UINT pos; - if (!(CPUTYPE & CPUTYPE_V30)) { + if (!(CPU_TYPE & CPUTYPE_V30)) { pos = (port >> 1) & 3; if (!extmem.target) { // ver0.28 extmem.page[pos] = 0xffffffff; @@ -49,24 +45,23 @@ static void IOOUTCALL emm_o08e1(UINT port, BYTE dat) { } else if (extmem.target < extmem.maxmem) { // ver0.28 dat &= 0xfc; - extmem.page[pos] = ((extmem.target-1) << 8) + dat; - extmem.pageptr[pos] = extmemmng_ptr + - (extmem.page[pos] << 12); + extmem.page[pos] = ((extmem.target - 1) << 8) + dat; + extmem.pageptr[pos] = CPU_EXTMEM + (extmem.page[pos] << 12); } } } -static void IOOUTCALL emm_o08e9(UINT port, BYTE dat) { +static void IOOUTCALL emm_o08e9(UINT port, REG8 dat) { - if (!(CPUTYPE & CPUTYPE_V30)) { + if (!(CPU_TYPE & CPUTYPE_V30)) { extmem.target = dat & 0x0f; } (void)port; } -static BYTE IOINPCALL emm_i08e9(UINT port) { +static REG8 IOINPCALL emm_i08e9(UINT port) { - if ((!(CPUTYPE & CPUTYPE_V30)) && + if ((!(CPU_TYPE & CPUTYPE_V30)) && (extmem.target) && (extmem.target < extmem.maxmem)) { return(0); } @@ -83,19 +78,22 @@ BOOL extmem_init(BYTE usemem) { UINT i; - if (usemem > 13) { // ver0.28 + if (usemem > 13) { usemem = 13; } extmem.target = 0; extmem.maxmem = 0; for (i=0; i<4; i++) { extmem.page[i] = 0xffffffff; - extmem.pageptr[i] = mem + 0xc0000 + (i << 14); // ver0.28 + extmem.pageptr[i] = mem + 0xc0000 + (i << 14); } if (extmemmng_realloc(usemem)) { return(FAILURE); } extmem.maxmem = usemem + 1; +#if defined(CPU386) + init_cpumem(usemem); +#endif return(SUCCESS); } diff --git a/io/extmem.h b/io/extmem.h index 12320e05..414beaad 100644 --- a/io/extmem.h +++ b/io/extmem.h @@ -1,7 +1,7 @@ typedef struct { UINT maxmem; - BYTE *pageptr[4]; // ver0.28 + BYTE *pageptr[4]; UINT target; UINT32 page[4]; } _EXTMEM, *EXTMEM; @@ -11,9 +11,6 @@ typedef struct { extern "C" { #endif -extern BYTE *extmemmng_ptr; -extern UINT32 extmemmng_size; - void extmemmng_clear(void); BOOL extmemmng_realloc(UINT megabytes); diff --git a/io/fdc.c b/io/fdc.c index 1d9d05cf..bcb62d9b 100644 --- a/io/fdc.c +++ b/io/fdc.c @@ -9,7 +9,7 @@ #include "fddfile.h" -static const BYTE FDCCMD_TABLE[32] = { +static const UINT8 FDCCMD_TABLE[32] = { 0, 0, 8, 2, 1, 8, 8, 1, 0, 8, 1, 0, 8, 5, 0, 2, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0}; @@ -40,7 +40,7 @@ static BOOL fdc_isfdcinterrupt(void) { return(fdc.intreq); } -BYTE DMACCALL fdc_dmafunc(BYTE func) { +REG8 DMACCALL fdc_dmafunc(REG8 func) { switch(func) { case DMAEXT_START: @@ -53,7 +53,7 @@ BYTE DMACCALL fdc_dmafunc(BYTE func) { return(0); } -static void fdc_dmaready(BYTE enable) { +static void fdc_dmaready(REG8 enable) { if (CTRL_FDMEDIA == DISKTYPE_2HD) { dmac.dmach[DMA_2HD].ready = enable; @@ -143,7 +143,7 @@ static void fdc_timeoutset(void) { -static BOOL FDC_DriveCheck(BYTE protectcheck) { +static BOOL FDC_DriveCheck(BOOL protectcheck) { if (!fddfile[fdc.us].fname[0]) { fdc.stat[fdc.us] = FDCRLT_IC0 | FDCRLT_NR | (fdc.hd << 2) | fdc.us; @@ -628,7 +628,7 @@ static void fdcstatusreset(void) { fdc.status = FDCSTAT_RQM; } -void DMACCALL fdc_DataRegWrite(BYTE data) { +void DMACCALL fdc_DataRegWrite(REG8 data) { // if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) == FDCSTAT_RQM) { switch(fdc.event) { @@ -667,8 +667,7 @@ void DMACCALL fdc_DataRegWrite(BYTE data) { // } } - -BYTE DMACCALL fdc_DataRegRead(void) { +REG8 DMACCALL fdc_DataRegRead(void) { // if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) // == (FDCSTAT_RQM | FDCSTAT_DIO)) { @@ -712,7 +711,7 @@ BYTE DMACCALL fdc_DataRegRead(void) { // ---- I/O -static void IOOUTCALL fdc_o92(UINT port, BYTE dat) { +static void IOOUTCALL fdc_o92(UINT port, REG8 dat) { // TRACEOUT(("fdc out %x %x", port, dat)); CTRL_FDMEDIA = DISKTYPE_2HD; @@ -722,7 +721,7 @@ static void IOOUTCALL fdc_o92(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL fdc_o94(UINT port, BYTE dat) { +static void IOOUTCALL fdc_o94(UINT port, REG8 dat) { // TRACEOUT(("fdc out %x %x", port, dat)); CTRL_FDMEDIA = DISKTYPE_2HD; @@ -735,7 +734,7 @@ static void IOOUTCALL fdc_o94(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL fdc_i90(UINT port) { +static REG8 IOINPCALL fdc_i90(UINT port) { // TRACEOUT(("fdc in %x %x", port, fdc.status)); CTRL_FDMEDIA = DISKTYPE_2HD; @@ -744,9 +743,9 @@ static BYTE IOINPCALL fdc_i90(UINT port) { return(fdc.status); } -static BYTE IOINPCALL fdc_i92(UINT port) { +static REG8 IOINPCALL fdc_i92(UINT port) { - BYTE ret; + REG8 ret; CTRL_FDMEDIA = DISKTYPE_2HD; if ((fdc.status & (FDCSTAT_RQM | FDCSTAT_DIO)) @@ -761,7 +760,7 @@ static BYTE IOINPCALL fdc_i92(UINT port) { return(ret); } -static BYTE IOINPCALL fdc_i94(UINT port) { +static REG8 IOINPCALL fdc_i94(UINT port) { CTRL_FDMEDIA = DISKTYPE_2HD; @@ -770,21 +769,21 @@ static BYTE IOINPCALL fdc_i94(UINT port) { } -static void IOOUTCALL fdc_oca(UINT port, BYTE dat) { +static void IOOUTCALL fdc_oca(UINT port, REG8 dat) { CTRL_FDMEDIA = DISKTYPE_2DD; fdc_DataRegWrite(dat); (void)port; } -static void IOOUTCALL fdc_occ(UINT port, BYTE dat) { +static void IOOUTCALL fdc_occ(UINT port, REG8 dat) { CTRL_FDMEDIA = DISKTYPE_2DD; fdc.ctrlreg = dat; (void)port; } -static BYTE IOINPCALL fdc_ic8(UINT port) { +static REG8 IOINPCALL fdc_ic8(UINT port) { CTRL_FDMEDIA = DISKTYPE_2DD; @@ -792,9 +791,9 @@ static BYTE IOINPCALL fdc_ic8(UINT port) { return(fdc.status); } -static BYTE IOINPCALL fdc_ica(UINT port) { +static REG8 IOINPCALL fdc_ica(UINT port) { - BYTE ret; + REG8 ret; CTRL_FDMEDIA = DISKTYPE_2DD; ret = fdc_DataRegRead(); @@ -803,7 +802,7 @@ static BYTE IOINPCALL fdc_ica(UINT port) { return(ret); } -static BYTE IOINPCALL fdc_icc(UINT port) { +static REG8 IOINPCALL fdc_icc(UINT port) { CTRL_FDMEDIA = DISKTYPE_2DD; @@ -812,13 +811,13 @@ static BYTE IOINPCALL fdc_icc(UINT port) { } -static void IOOUTCALL fdc_obe(UINT port, BYTE dat) { +static void IOOUTCALL fdc_obe(UINT port, REG8 dat) { fdc.chgreg = dat; (void)port; } -static BYTE IOINPCALL fdc_ibe(UINT port) { +static REG8 IOINPCALL fdc_ibe(UINT port) { (void)port; return((fdc.chgreg & 3) | 8); diff --git a/io/fdc.h b/io/fdc.h index 3471e47a..d999a34b 100644 --- a/io/fdc.h +++ b/io/fdc.h @@ -61,20 +61,20 @@ enum { }; typedef struct { - BYTE us, hd; - BYTE mt, mf, sk; - BYTE eot, gpl, dtl; - BYTE C, H, R, N; - BYTE srt, hut, hlt, nd; - BYTE stp, ncn, sc, d; - - BYTE status; - BYTE intreq; - BYTE lastdata; - BYTE tc; + UINT8 us, hd; + UINT8 mt, mf, sk; + UINT8 eot, gpl, dtl; + UINT8 C, H, R, N; + UINT8 srt, hut, hlt, nd; + UINT8 stp, ncn, sc, d; + + UINT8 status; + UINT8 intreq; + UINT8 lastdata; + UINT8 tc; UINT32 stat[4]; - BYTE treg[4]; + UINT8 treg[4]; int event; int cmdp; @@ -84,19 +84,19 @@ typedef struct { int bufp; int bufcnt; - BYTE cmd; + UINT8 cmd; BYTE cmds[15]; BYTE data[16]; BYTE buf[0x8000]; - BYTE ctrlfd; - BYTE crcn; + UINT8 ctrlfd; + UINT8 crcn; - BYTE ctrlreg; - BYTE busy; + UINT8 ctrlreg; + UINT8 busy; - BYTE chgreg; - BYTE rpm; // 1.44 + UINT8 chgreg; + UINT8 rpm; // 1.44 } _FDC, *FDC; @@ -110,9 +110,9 @@ void fdc_reset(void); void fdc_bind(void); void fdc_interrupt(void); -void DMACCALL fdc_DataRegWrite(BYTE data); -BYTE DMACCALL fdc_DataRegRead(void); -BYTE DMACCALL fdc_dmafunc(BYTE func); +void DMACCALL fdc_DataRegWrite(REG8 data); +REG8 DMACCALL fdc_DataRegRead(void); +REG8 DMACCALL fdc_dmafunc(REG8 func); void fdcsend_error7(void); void fdcsend_success7(void); diff --git a/io/fdd320.c b/io/fdd320.c index 84a3e984..f7ee33a3 100644 --- a/io/fdd320.c +++ b/io/fdd320.c @@ -8,16 +8,15 @@ BYTE fdd320_stat; -static BYTE IOINPCALL fdd320_i51(UINT port) { +static REG8 IOINPCALL fdd320_i51(UINT port) { (void)port; return(0x00); } -static BYTE IOINPCALL fdd320_i55(UINT port) { +static REG8 IOINPCALL fdd320_i55(UINT port) { fdd320_stat ^= 0xff; - (void)port; return(fdd320_stat); } diff --git a/io/gdc.c b/io/gdc.c index 72c314e3..d70b9efe 100644 --- a/io/gdc.c +++ b/io/gdc.c @@ -1,6 +1,6 @@ #include "compiler.h" #include "scrnmng.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -13,11 +13,11 @@ #define TURE_SYNC -static const BYTE defdegpal[4] = {0x04,0x15,0x26,0x37}; -static const BYTE defsync[8] = {0x10,0x4e,0x07,0x25,0x07,0x07,0x90,0x65}; +static const UINT8 defdegpal[4] = {0x04,0x15,0x26,0x37}; +static const UINT8 defsync[8] = {0x10,0x4e,0x07,0x25,0x07,0x07,0x90,0x65}; -void gdc_setdegitalpal(int color, BYTE value) { +void gdc_setdegitalpal(int color, REG8 value) { if (color & 4) { color &= 3; @@ -39,21 +39,21 @@ void gdc_setdegitalpal(int color, BYTE value) { } } -void gdc_setanalogpal(int color, int rgb, BYTE value) { +void gdc_setanalogpal(int color, int rgb, REG8 value) { - BYTE *ptr; + UINT8 *ptr; PAL1EVENT *event; - ptr = ((BYTE *)(gdc.anapal + color)) + rgb; + ptr = ((UINT8 *)(gdc.anapal + color)) + rgb; if (((*ptr) ^ value) & 0x0f) { gdcs.palchange = GDCSCRN_REDRAW; if (palevent.events < PALEVENTMAX) { if (!gdc.vsync) { event = palevent.event + palevent.events; event->clock = nevent.item[NEVENT_FLAMES].clock - - (I286_BASECLOCK - I286_REMCLOCK); + (CPU_BASECLOCK - CPU_REMCLOCK); event->color = (color * sizeof(RGB32)) + rgb; - event->value = value; + event->value = (UINT8)value; palevent.events++; } else { @@ -64,17 +64,17 @@ void gdc_setanalogpal(int color, int rgb, BYTE value) { *ptr = value; } -void gdc_setdegpalpack(int color, BYTE value) { +void gdc_setdegpalpack(int color, REG8 value) { if ((gdc.degpal[color] ^ value) & 0x77) { gdcs.palchange = GDCSCRN_REDRAW; } - gdc.degpal[color] = value; + gdc.degpal[color] = (UINT8)value; } void gdc_paletteinit(void) { - BYTE c; + int c; CopyMemory(gdc.degpal, defdegpal, 4); for (c=0; c<8; c++) { @@ -131,13 +131,13 @@ static void textdraw(void) { // ver0.30 void gdc_work(int id) { - UINT16 i; - BYTE data; GDCDATA item; - BYTE *dispflag; + UINT8 *dispflag; + UINT i; + BYTE data; - item = ((id==GDCWORK_MASTER)?(&gdc.m):(&gdc.s)); - dispflag = ((id==GDCWORK_MASTER)?(&gdcs.textdisp):(&gdcs.grphdisp)); + item = (id==GDCWORK_MASTER)?&gdc.m:&gdc.s; + dispflag = (id==GDCWORK_MASTER)?&gdcs.textdisp:&gdcs.grphdisp; for (i=0; icnt; i++) { data = (BYTE)item->fifo[i]; @@ -151,11 +151,13 @@ void gdc_work(int id) { item->rcv = 2; item->paracb = 1; break; + case 0x10: case 0x18: item->rcv = 1; item->paracb = 1; break; + default: item->rcv = 0; break; @@ -245,7 +247,7 @@ void gdc_restorekacmode(void) { // ---- I/O -static void IOOUTCALL gdc_o60(UINT port, BYTE dat) { +static void IOOUTCALL gdc_o60(UINT port, REG8 dat) { if (gdc.m.cnt < GDCCMD_MAX) { gdc.m.fifo[gdc.m.cnt++] = dat; @@ -253,7 +255,7 @@ static void IOOUTCALL gdc_o60(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_o62(UINT port, BYTE dat) { +static void IOOUTCALL gdc_o62(UINT port, REG8 dat) { if (gdc.m.cnt < GDCCMD_MAX) { gdc.m.fifo[gdc.m.cnt++] = 0x100 | dat; @@ -262,16 +264,16 @@ static void IOOUTCALL gdc_o62(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_o64(UINT port, BYTE dat) { +static void IOOUTCALL gdc_o64(UINT port, REG8 dat) { gdc.vsyncint = 1; (void)port; (void)dat; } -static void IOOUTCALL gdc_o68(UINT port, BYTE dat) { +static void IOOUTCALL gdc_o68(UINT port, REG8 dat) { - BYTE bit; + REG8 bit; if (!(dat & 0xf0)) { // ver0.28 bit = 1 << ((dat >> 1) & 7); @@ -299,9 +301,9 @@ static void IOOUTCALL gdc_o68(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_o6a(UINT port, BYTE dat) { +static void IOOUTCALL gdc_o6a(UINT port, REG8 dat) { - BYTE bit; + REG8 bit; if (!(dat & 0xf8)) { bit = (dat >> 1) & 3; @@ -367,10 +369,10 @@ static void IOOUTCALL gdc_o6a(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL gdc_i60(UINT port) { +static REG8 IOINPCALL gdc_i60(UINT port) { - BYTE ret; - long remain; + REG8 ret; + SINT32 remain; ret = 0x80 | gdc.vsync; // | m_drawing; remain = nevent_getremain(NEVENT_FLAMES); @@ -392,32 +394,32 @@ static BYTE IOINPCALL gdc_i60(UINT port) { gdc_work(GDCWORK_MASTER); } #ifdef SEARHC_SYNC - if ((i286core.s.inport) && (I286_REMCLOCK >= 5)) { + if ((CPU_INPADRS) && (CPU_REMCLOCK >= 5)) { UINT16 jadr = 0xfa74; UINT16 memv; - memv = i286_memoryread_w(i286core.s.inport); + memv = i286_memoryread_w(CPU_INPADRS); while((memv == 0x00eb) || (memv == 0x5fe6)) { jadr -= 0x200; - i286core.s.inport += 2; - memv = i286_memoryread_w(i286core.s.inport); + CPU_INPADRS += 2; + memv = i286_memoryread_w(CPU_INPADRS); } if ((memv == 0x20a8) || (memv == 0x2024)) { - memv = i286_memoryread_w(i286core.s.inport + 2); + memv = i286_memoryread_w(CPU_INPADRS + 2); if (memv == jadr) { // je if (!gdc.vsync) { - I286_REMCLOCK = -1; + CPU_REMCLOCK = -1; } } else if (memv == (jadr + 1)) { // jne if (gdc.vsync) { - I286_REMCLOCK = -1; + CPU_REMCLOCK = -1; } } } } #endif #ifdef TURE_SYNC // クロックイベントの誤差修正 - if (nevent.item[NEVENT_FLAMES].clock < (I286_BASECLOCK - I286_REMCLOCK)) { + if (nevent.item[NEVENT_FLAMES].clock < (CPU_BASECLOCK - CPU_REMCLOCK)) { ret ^= 0x20; } #endif @@ -425,7 +427,7 @@ static BYTE IOINPCALL gdc_i60(UINT port) { return(ret); } -static BYTE IOINPCALL gdc_i62(UINT port) { +static REG8 IOINPCALL gdc_i62(UINT port) { if (gdc.m.snd) { gdc.m.snd--; @@ -435,20 +437,20 @@ static BYTE IOINPCALL gdc_i62(UINT port) { return(0xff); } -static BYTE IOINPCALL gdc_i68(UINT port) { +static REG8 IOINPCALL gdc_i68(UINT port) { (void)port; return(gdc.mode1); } -static BYTE IOINPCALL gdc_i6a(UINT port) { +static REG8 IOINPCALL gdc_i6a(UINT port) { (void)port; return(gdc.mode2); } -static void IOOUTCALL gdc_oa0(UINT port, BYTE dat) { +static void IOOUTCALL gdc_oa0(UINT port, REG8 dat) { if (gdc.s.cnt < GDCCMD_MAX) { gdc.s.fifo[gdc.s.cnt++] = dat; @@ -460,7 +462,7 @@ static void IOOUTCALL gdc_oa0(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_oa2(UINT port, BYTE dat) { +static void IOOUTCALL gdc_oa2(UINT port, REG8 dat) { if (gdc.s.cnt < GDCCMD_MAX) { gdc.s.fifo[gdc.s.cnt++] = 0x100 | dat; @@ -470,7 +472,7 @@ static void IOOUTCALL gdc_oa2(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_oa4(UINT port, BYTE dat) { +static void IOOUTCALL gdc_oa4(UINT port, REG8 dat) { if ((gdcs.disp ^ dat) & 1) { gdcs.disp = dat & 1; @@ -479,7 +481,7 @@ static void IOOUTCALL gdc_oa4(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_oa6(UINT port, BYTE dat) { +static void IOOUTCALL gdc_oa6(UINT port, REG8 dat) { if ((gdcs.access ^ dat) & 1) { gdcs.access = dat & 1; @@ -490,7 +492,7 @@ static void IOOUTCALL gdc_oa6(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_oa8(UINT port, BYTE dat) { +static void IOOUTCALL gdc_oa8(UINT port, REG8 dat) { if (gdc.analog) { gdc.palnum = dat & 0x0f; @@ -501,7 +503,7 @@ static void IOOUTCALL gdc_oa8(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_oaa(UINT port, BYTE dat) { +static void IOOUTCALL gdc_oaa(UINT port, REG8 dat) { if (gdc.analog) { gdc_setanalogpal(gdc.palnum, offsetof(RGB32, p.g), dat); @@ -512,7 +514,7 @@ static void IOOUTCALL gdc_oaa(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_oac(UINT port, BYTE dat) { +static void IOOUTCALL gdc_oac(UINT port, REG8 dat) { if (gdc.analog) { gdc_setanalogpal(gdc.palnum, offsetof(RGB32, p.r), dat); @@ -523,7 +525,7 @@ static void IOOUTCALL gdc_oac(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL gdc_oae(UINT port, BYTE dat) { +static void IOOUTCALL gdc_oae(UINT port, REG8 dat) { if (gdc.analog) { gdc_setanalogpal(gdc.palnum, offsetof(RGB32, p.b), dat); @@ -534,9 +536,9 @@ static void IOOUTCALL gdc_oae(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL gdc_ia0(UINT port) { +static REG8 IOINPCALL gdc_ia0(UINT port) { - BYTE ret; + REG8 ret; SINT32 remain; ret = 0x80 | gdc.vsync | gdc.s_drawing; @@ -559,32 +561,32 @@ static BYTE IOINPCALL gdc_ia0(UINT port) { gdc_work(GDCWORK_SLAVE); } #ifdef SEARHC_SYNC - if ((i286core.s.inport) && (I286_REMCLOCK >= 5)) { + if ((CPU_INPADRS) && (CPU_REMCLOCK >= 5)) { UINT16 jadr = 0xfa74; UINT16 memv; - memv = i286_memoryread_w(i286core.s.inport); + memv = i286_memoryread_w(CPU_INPADRS); while((memv == 0x00eb) || (memv == 0x5fe6)) { jadr -= 0x200; - i286core.s.inport += 2; - memv = i286_memoryread_w(i286core.s.inport); + CPU_INPADRS += 2; + memv = i286_memoryread_w(CPU_INPADRS); } if ((memv == 0x20a8) || (memv == 0x2024)) { - memv = i286_memoryread_w(i286core.s.inport + 2); + memv = i286_memoryread_w(CPU_INPADRS + 2); if (memv == jadr) { // je if (!gdc.vsync) { - I286_REMCLOCK = -1; + CPU_REMCLOCK = -1; } } else if (memv == (jadr + 1)) { // jne if (gdc.vsync) { - I286_REMCLOCK = -1; + CPU_REMCLOCK = -1; } } } } #endif #ifdef TURE_SYNC // クロックイベントの誤差修正 - if (nevent.item[NEVENT_FLAMES].clock < (I286_BASECLOCK - I286_REMCLOCK)) { + if (nevent.item[NEVENT_FLAMES].clock < (CPU_BASECLOCK - CPU_REMCLOCK)) { ret ^= 0x20; } #endif @@ -592,7 +594,7 @@ static BYTE IOINPCALL gdc_ia0(UINT port) { return(ret); } -static BYTE IOINPCALL gdc_ia2(UINT port) { +static REG8 IOINPCALL gdc_ia2(UINT port) { if (gdc.s.snd) { gdc.s.snd--; @@ -602,13 +604,13 @@ static BYTE IOINPCALL gdc_ia2(UINT port) { return(0xff); } -static BYTE IOINPCALL gdc_ia4(UINT port) { +static REG8 IOINPCALL gdc_ia4(UINT port) { (void)port; return(gdcs.disp); } -static BYTE IOINPCALL gdc_ia6(UINT port) { +static REG8 IOINPCALL gdc_ia6(UINT port) { (void)port; return(gdcs.access); diff --git a/io/gdc.h b/io/gdc.h index b7df18e5..ab519639 100644 --- a/io/gdc.h +++ b/io/gdc.h @@ -5,41 +5,41 @@ typedef struct { BYTE para[256]; UINT16 fifo[GDCCMD_MAX]; UINT16 cnt; - BYTE ptr; - BYTE rcv; - BYTE snd; - BYTE cmd; - BYTE paracb; - BYTE reserved; + UINT8 ptr; + UINT8 rcv; + UINT8 snd; + UINT8 cmd; + UINT8 paracb; + UINT8 reserved; } _GDCDATA, *GDCDATA; typedef struct { _GDCDATA m; _GDCDATA s; - BYTE mode1; - BYTE mode2; - BYTE vsync; - BYTE vsyncint; + UINT8 mode1; + UINT8 mode2; + UINT8 vsync; + UINT8 vsyncint; int analog; int palnum; - BYTE degpal[4]; + UINT8 degpal[4]; RGB32 anapal[16]; - BYTE clock; - BYTE display; - BYTE bitac; - BYTE m_drawing; - BYTE s_drawing; - BYTE reserved[3]; + UINT8 clock; + UINT8 display; + UINT8 bitac; + UINT8 m_drawing; + UINT8 s_drawing; + UINT8 reserved[3]; } _GDC, *GDC; typedef struct { - BYTE access; - BYTE disp; - BYTE textdisp; - BYTE msw_accessable; - BYTE grphdisp; - BYTE palchange; - BYTE mode2; + UINT8 access; + UINT8 disp; + UINT8 textdisp; + UINT8 msw_accessable; + UINT8 grphdisp; + UINT8 palchange; + UINT8 mode2; } _GDCS, *GDCS; enum { @@ -72,9 +72,9 @@ void gdc_work(int id); void gdc_forceready(GDCDATA item); void gdc_paletteinit(void); -void gdc_setdegitalpal(int color, BYTE value); -void gdc_setanalogpal(int color, int rgb, BYTE value); -void gdc_setdegpalpack(int color, BYTE value); +void gdc_setdegitalpal(int color, REG8 value); +void gdc_setanalogpal(int color, int rgb, REG8 value); +void gdc_setdegpalpack(int color, REG8 value); void gdc_restorekacmode(void); diff --git a/io/gdc_cmd.tbl b/io/gdc_cmd.tbl index 095064cd..63d12381 100644 --- a/io/gdc_cmd.tbl +++ b/io/gdc_cmd.tbl @@ -1,9 +1,9 @@ typedef struct { - BYTE pos; - BYTE outdatas; - BYTE indatas; - BYTE flag; + UINT8 pos; + UINT8 outdatas; + UINT8 indatas; + UINT8 flag; } GDCCMD; static const GDCCMD gdc_cmd[256] = { diff --git a/io/iocore.c b/io/iocore.c index 75e3c288..121bd1f3 100644 --- a/io/iocore.c +++ b/io/iocore.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "cbuscore.h" @@ -52,12 +52,12 @@ typedef struct { } _IOCORE, *IOCORE; static _IOCORE iocore; -static BYTE ioterminate[0x100]; +static UINT8 ioterminate[0x100]; // ---- -static void IOOUTCALL defout(UINT port, BYTE dat) { +static void IOOUTCALL defout8(UINT port, REG8 dat) { if ((port & 0xfff0) == cs4231.port) { cs4231io_w8(port, dat); @@ -69,7 +69,7 @@ static void IOOUTCALL defout(UINT port, BYTE dat) { } } -static BYTE IOINPCALL definp(UINT port) { +static REG8 IOINPCALL definp8(UINT port) { if ((port & 0xfff0) == cs4231.port) { return(cs4231io_r8(port)); @@ -344,7 +344,7 @@ BOOL iocore_attachinp(UINT port, IOINP func) { void iocore_create(void) { UINT i; -const BYTE *p; +const UINT8 *p; UINT r; ZeroMemory(&iocore, sizeof(iocore)); @@ -353,7 +353,7 @@ const BYTE *p; p = termtbl[i].item; r = termtbl[i].items; do { - ioterminate[*p++] = (BYTE)(i + 1); + ioterminate[*p++] = (UINT8)(i + 1); } while(--r); } } @@ -387,8 +387,8 @@ BOOL iocore_build(void) { goto icbld_err; } for (i=0; i<256; i++) { - cmn->ioout[i] = defout; - cmn->ioinp[i] = definp; + cmn->ioout[i] = defout8; + cmn->ioinp[i] = definp8; } sys = (IOFUNC)listarray_append(iotbl, cmn); if (sys == NULL) { @@ -461,7 +461,9 @@ void iocore_bind(void) { iocore_cb(bindfn, sizeof(bindfn)/sizeof(IOCBFN)); } -void IOOUTCALL iocore_out8(UINT port, BYTE dat) { +#if !defined(TRACE) + +void IOOUTCALL iocore_out8(UINT port, REG8 dat) { IOFUNC iof; @@ -469,7 +471,7 @@ void IOOUTCALL iocore_out8(UINT port, BYTE dat) { iof->ioout[port & 0xff](port, dat); } -BYTE IOINPCALL iocore_inp8(UINT port) { +REG8 IOINPCALL iocore_inp8(UINT port) { IOFUNC iof; @@ -477,7 +479,36 @@ BYTE IOINPCALL iocore_inp8(UINT port) { return(iof->ioinp[port & 0xff](port)); } -void IOOUTCALL iocore_out16(UINT port, UINT16 dat) { +#else + +void IOOUTCALL iocore_out8(UINT port, REG8 dat) { + + IOFUNC iof; + + if (dat & (~0xff)) { + TRACEOUT(("iocore_out8 - %x %x", port, dat)); + } + iof = iocore.base[(port >> 8) & 0xff]; + iof->ioout[port & 0xff](port, dat); +} + +REG8 IOINPCALL iocore_inp8(UINT port) { + + IOFUNC iof; + REG8 ret; + + iof = iocore.base[(port >> 8) & 0xff]; + ret = iof->ioinp[port & 0xff](port); + + if (ret & (~0xff)) { + TRACEOUT(("iocore_inp8 - %x %x", port, ret)); + } + return(ret); +} + +#endif + +void IOOUTCALL iocore_out16(UINT port, REG16 dat) { IOFUNC iof; @@ -495,21 +526,21 @@ void IOOUTCALL iocore_out16(UINT port, UINT16 dat) { case TERM_MINUS: case TERM_EXT08: iof = iocore.base[(port >> 8) & 0xff]; - iof->ioout[port & 0xff](port, (BYTE)dat); + iof->ioout[port & 0xff](port, (UINT8)dat); return; } } iof = iocore.base[(port >> 8) & 0xff]; - iof->ioout[port & 0xff](port, (BYTE)dat); + iof->ioout[port & 0xff](port, (UINT8)dat); port++; iof = iocore.base[(port >> 8) & 0xff]; - iof->ioout[port & 0xff](port, (BYTE)(dat >> 8)); + iof->ioout[port & 0xff](port, (UINT8)(dat >> 8)); } -UINT16 IOINPCALL iocore_inp16(UINT port) { +REG16 IOINPCALL iocore_inp16(UINT port) { IOFUNC iof; - BYTE ret; + REG8 ret; if ((port & 0xfffc) == 0x005c) { return(artic_r16(port)); @@ -522,7 +553,7 @@ UINT16 IOINPCALL iocore_inp16(UINT port) { case TERM_ACTIVE: ret = iof->ioinp[port & 0xff](port); - return((I286_AX & 0xff00) + ret); + return((CPU_AX & 0xff00) + ret); case TERM_PLUS: ret = iof->ioinp[port & 0xff](port); @@ -542,3 +573,17 @@ UINT16 IOINPCALL iocore_inp16(UINT port) { return((UINT16)((iof->ioinp[port & 0xff](port) << 8) + ret)); } +void IOOUTCALL iocore_out32(UINT port, UINT32 dat) { + + iocore_out16(port, (UINT16)dat); + iocore_out16(port+2, (UINT16)(dat >> 16)); +} + +UINT32 IOINPCALL iocore_inp32(UINT port) { + + REG16 ret; + + ret = iocore_inp16(port); + return(ret + (iocore_inp16(port+2) << 16)); +} + diff --git a/io/iocore.h b/io/iocore.h index 9eb6e01b..fba12bb7 100644 --- a/io/iocore.h +++ b/io/iocore.h @@ -6,8 +6,8 @@ #define IOINPCALL #endif -typedef void (IOOUTCALL *IOOUT)(UINT port, BYTE val); -typedef BYTE (IOINPCALL *IOINP)(UINT port); +typedef void (IOOUTCALL *IOOUT)(UINT port, REG8 val); +typedef REG8 (IOINPCALL *IOINP)(UINT port); typedef void (*IOCBFN)(void); @@ -95,11 +95,14 @@ void iocore_cb(const IOCBFN *cbfn, UINT count); void iocore_reset(void); void iocore_bind(void); -void IOOUTCALL iocore_out8(UINT port, BYTE val); -BYTE IOINPCALL iocore_inp8(UINT port); +void IOOUTCALL iocore_out8(UINT port, REG8 dat); +REG8 IOINPCALL iocore_inp8(UINT port); -void IOOUTCALL iocore_out16(UINT port, UINT16 dat); -UINT16 IOINPCALL iocore_inp16(UINT port); +void IOOUTCALL iocore_out16(UINT port, REG16 dat); +REG16 IOINPCALL iocore_inp16(UINT port); + +void IOOUTCALL iocore_out32(UINT port, UINT32 dat); +UINT32 IOINPCALL iocore_inp32(UINT port); #ifdef __cplusplus } diff --git a/io/itf.c b/io/itf.c index 1514a75d..4b2ef264 100644 --- a/io/itf.c +++ b/io/itf.c @@ -1,20 +1,20 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" // ---- I/O -static void IOOUTCALL itf_o043d(UINT port, BYTE dat) { +static void IOOUTCALL itf_o043d(UINT port, REG8 dat) { switch(dat) { case 0x10: - i286core.s.itfbank = 1; + CPU_ITFBANK = 1; break; case 0x12: - i286core.s.itfbank = 0; + CPU_ITFBANK = 0; break; } (void)port; diff --git a/io/mouseif.c b/io/mouseif.c index 7b950c6e..55651208 100644 --- a/io/mouseif.c +++ b/io/mouseif.c @@ -1,6 +1,6 @@ #include "compiler.h" #include "mousemng.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" @@ -24,7 +24,7 @@ void mouseif_sync(void) { mouseif.rx = mouseif.sx; mouseif.ry = mouseif.sy; - mouseif.lastc = I286_CLOCK + I286_BASECLOCK + I286_REMCLOCK; + mouseif.lastc = CPU_CLOCK + CPU_BASECLOCK + CPU_REMCLOCK; } static void calc_mousexy(void) { @@ -32,7 +32,7 @@ static void calc_mousexy(void) { UINT32 clock; SINT32 diff; - clock = I286_CLOCK + I286_BASECLOCK + I286_REMCLOCK; + clock = CPU_CLOCK + CPU_BASECLOCK + CPU_REMCLOCK; diff = clock - mouseif.lastc; if (diff >= 2000) { SINT32 dx; @@ -89,7 +89,7 @@ void mouseint(NEVENTITEM item) { } } -static void setportc(BYTE value) { +static void setportc(REG8 value) { if ((value & 0x80) && (!(mouseif.portc & 0x80))) { calc_mousexy(); @@ -118,43 +118,43 @@ static void setportc(BYTE value) { } } } - mouseif.portc = value; + mouseif.portc = (UINT8)value; } // ---- I/O -static void IOOUTCALL mouseif_o7fdd(UINT port, BYTE dat) { +static void IOOUTCALL mouseif_o7fdd(UINT port, REG8 dat) { setportc(dat); (void)port; } -static void IOOUTCALL mouseif_o7fdf(UINT port, BYTE dat) { +static void IOOUTCALL mouseif_o7fdf(UINT port, REG8 dat) { if (dat & 0xf0) { - mouseif.mode = dat; + mouseif.mode = (UINT8)dat; if (dat == 0x93) { setportc(0); } } else { if (dat & 1) { - setportc((BYTE)(mouseif.portc | (1 << (dat >> 1)))); + setportc((REG8)(mouseif.portc | (1 << (dat >> 1)))); } else { - setportc((BYTE)(mouseif.portc & (~(1 << (dat >> 1))))); + setportc((REG8)(mouseif.portc & (~(1 << (dat >> 1))))); } } (void)port; } -static BYTE IOINPCALL mouseif_i7fd9(UINT port) { +static REG8 IOINPCALL mouseif_i7fd9(UINT port) { SINT16 x; SINT16 y; - BYTE ret; - BYTE portc; + REG8 ret; + REG8 portc; calc_mousexy(); ret = mouseif.b; @@ -181,21 +181,21 @@ static BYTE IOINPCALL mouseif_i7fd9(UINT port) { else { ret |= (x >> 4) & 0x0f; } -// TRACEOUT(("%x %x mouse [%x] %d -> %x", I286_CS, I286_IP, portc & 0x20, y, ret)); +// TRACEOUT(("%x %x mouse [%x] %d -> %x", CPU_CS, CPU_IP, portc & 0x20, y, ret)); (void)port; return(ret); } -static BYTE IOINPCALL mouseif_i7fdb(UINT port) { +static REG8 IOINPCALL mouseif_i7fdb(UINT port) { (void)port; return(0x40); } -static BYTE IOINPCALL mouseif_i7fdd(UINT port) { +static REG8 IOINPCALL mouseif_i7fdd(UINT port) { - BYTE ret; - BYTE mode; + REG8 ret; + REG8 mode; ret = mouseif.portc; mode = mouseif.mode; @@ -213,7 +213,7 @@ static BYTE IOINPCALL mouseif_i7fdd(UINT port) { } -static void IOOUTCALL mouseif_obfdb(UINT port, BYTE dat) { +static void IOOUTCALL mouseif_obfdb(UINT port, REG8 dat) { mouseif.timing = dat & 3; (void)port; diff --git a/io/mouseif.h b/io/mouseif.h index 0d619316..3bf7f6f7 100644 --- a/io/mouseif.h +++ b/io/mouseif.h @@ -10,11 +10,11 @@ typedef struct { SINT16 sy; SINT16 latch_x; SINT16 latch_y; - BYTE portc; - BYTE timing; - BYTE mode; - BYTE rapid; - BYTE b; + UINT8 portc; + UINT8 timing; + UINT8 mode; + UINT8 rapid; + UINT8 b; } _MOUSEIF, *MOUSEIF; diff --git a/io/nmiio.c b/io/nmiio.c index 47764654..51eeb188 100644 --- a/io/nmiio.c +++ b/io/nmiio.c @@ -1,19 +1,18 @@ #include "compiler.h" -#include "i286.h" #include "pccore.h" #include "iocore.h" // ---- I/O -static void IOOUTCALL nmiio_o50(UINT port, BYTE dat) { +static void IOOUTCALL nmiio_o50(UINT port, REG8 dat) { nmiio.enable = 0; (void)port; (void)dat; } -static void IOOUTCALL nmiio_o52(UINT port, BYTE dat) { +static void IOOUTCALL nmiio_o52(UINT port, REG8 dat) { nmiio.enable = 1; (void)port; diff --git a/io/np2sysp.c b/io/np2sysp.c index 78c469d3..4728f43a 100644 --- a/io/np2sysp.c +++ b/io/np2sysp.c @@ -1,7 +1,7 @@ #include "compiler.h" #include "strres.h" #include "taskmng.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" // #include "hostdrv.h" @@ -64,7 +64,7 @@ static void np2sysp_cpu(const void *arg1, const void *arg2) { // CPUを返す #if 1 // 80286 or V30 - if (!(CPUTYPE & CPUTYPE_V30)) { + if (!(CPU_TYPE & CPUTYPE_V30)) { np2sysp_outstr(str_80286, NULL); } else { @@ -190,14 +190,17 @@ static BOOL np2syspcmp(const char *p) { return(FALSE); } -static void IOOUTCALL np2sysp_o7ef(UINT port, BYTE dat) { +static void IOOUTCALL np2sysp_o7ef(UINT port, REG8 dat) { - UINT i; +const SYSPCMD *cmd; +const SYSPCMD *cmdterm; - np2sysp.substr[np2sysp.strpos] = dat; - for (i=0; i<(sizeof(np2spcmd)/sizeof(SYSPCMD)); i++) { - if (!np2syspcmp(np2spcmd[i].key)) { - np2spcmd[i].func(np2spcmd[i].arg1, np2spcmd[i].arg2); + np2sysp.substr[np2sysp.strpos] = (char)dat; + cmd = np2spcmd; + cmdterm = cmd + (sizeof(np2spcmd) / sizeof(SYSPCMD)); + while(cmd < cmdterm) { + if (!np2syspcmp(cmd->key)) { + cmd->func(cmd->arg1, cmd->arg2); break; } } @@ -206,11 +209,11 @@ static void IOOUTCALL np2sysp_o7ef(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL np2sysp_i7ef(UINT port) { +static REG8 IOINPCALL np2sysp_i7ef(UINT port) { - BYTE ret; + REG8 ret; - ret = np2sysp.outstr[np2sysp.outpos]; + ret = (UINT8)np2sysp.outstr[np2sysp.outpos]; if (ret) { np2sysp.outpos++; np2sysp.outpos &= NP2SYSP_MASK; diff --git a/io/pic.c b/io/pic.c index 39965269..2ee7edfd 100644 --- a/io/pic.c +++ b/io/pic.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" @@ -79,7 +79,7 @@ static void pic_rolpry(PICITEM pi) { } -static void pic_downbylevel(PICITEM picp, BYTE level) { +static void pic_downbylevel(PICITEM picp, UINT level) { int i; @@ -93,13 +93,13 @@ static void pic_downbylevel(PICITEM picp, BYTE level) { // eoi処理 -static void pic_forceeoibylevel(PICITEM picp, BYTE level) { +static void pic_forceeoibylevel(PICITEM picp, UINT level) { int i; if (picp->isr & (1 << level)) { picp->isr &= ~(1 << level); - (picp->levels)--; + picp->levels--; for (i=0; (ilevels) && (picp->level[i] != level); i++) { } for (; ilevels; i++) { picp->level[i] = picp->level[i+1]; @@ -121,7 +121,7 @@ void pic_irq(void) { p = &pic; // 割込み許可で 要求あり? - if ((isI286EI) && (!p->ext_irq) && + if ((CPU_isEI) && (!p->ext_irq) && ((p->pi[0].irr & (~p->pi[0].imr)) || (p->pi[1].irr & (~p->pi[1].imr)))) { @@ -134,7 +134,7 @@ void pic_irq(void) { } irq = 0xff; targetbit = 0; - for (bit=1, i=0; bit; bit<<=1, i++) { + for (bit=1, i=0; i<8; bit<<=1, i++) { if ((p->pi[0].irr & bit) && (!((p->pi[0].imr | p->pi[0].isr) & bit))) { if ((SINT8)p->pi[0].pry[i] > pry) { @@ -170,8 +170,8 @@ void pic_irq(void) { if (irq == 0) { // ver0.28 nevent_reset(NEVENT_PICMASK); } - i286_interrupt((BYTE)((p->pi[0].icw[1] & 0xf8) | irq)); // TRACEOUT(("hardware-int %.2x", (p->pi[0].icw[1] & 0xf8) | irq)); + CPU_INTERRUPT((REG8)((p->pi[0].icw[1] & 0xf8) | irq)); return; } if ((!p->pi[0].levels) || @@ -187,7 +187,7 @@ void pic_irq(void) { pry = (SINT8)p->pi[1].pry[p->pi[1].level[p->pi[1].levels - 1]]; } targetbit = 0; - for (bit=1, i=0; bit; bit<<=1, i++) { + for (bit=1, i=0; i<8; bit<<=1, i++) { if ((p->pi[1].irr & bit) && (!((p->pi[1].imr | p->pi[1].isr) & bit))) { if ((SINT8)p->pi[1].pry[i] > pry) { @@ -213,7 +213,7 @@ void pic_irq(void) { p->pi[0].level[p->pi[0].levels++] = sirq; } // TRACEOUT(("hardware-int %.2x", (p->pi[1].icw[1] & 0xf8) | irq)); - i286_interrupt((BYTE)((p->pi[1].icw[1] & 0xf8) | irq)); + CPU_INTERRUPT((REG8)((p->pi[1].icw[1] & 0xf8) | irq)); } } } @@ -231,10 +231,10 @@ void picmask(NEVENTITEM item) { } } -void pic_setirq(BYTE irq) { +void pic_setirq(REG8 irq) { PICITEM pi; - BYTE bit; + REG8 bit; pi = pic.pi; bit = 1 << (irq & 7); @@ -267,7 +267,7 @@ void pic_setirq(BYTE irq) { } } -void pic_resetirq(BYTE irq) { +void pic_resetirq(REG8 irq) { PICITEM pi; @@ -275,8 +275,7 @@ void pic_resetirq(BYTE irq) { pi->irr &= ~(1 << (irq & 7)); } - -void pic_registext(BYTE irq) { +void pic_registext(REG8 irq) { PICITEM pi; @@ -287,10 +286,10 @@ void pic_registext(BYTE irq) { // ---- I/O -static void IOOUTCALL pic_o00(UINT port, BYTE dat) { +static void IOOUTCALL pic_o00(UINT port, REG8 dat) { PICITEM picp; - BYTE level; + UINT level; // TRACEOUT(("pic %x %x", port, dat)); picp = &pic.pi[(port >> 3) & 1]; @@ -342,7 +341,7 @@ static void IOOUTCALL pic_o00(UINT port, BYTE dat) { extern int piccnt; #endif -static void IOOUTCALL pic_o02(UINT port, BYTE dat) { +static void IOOUTCALL pic_o02(UINT port, REG8 dat) { PICITEM picp; @@ -350,7 +349,7 @@ static void IOOUTCALL pic_o02(UINT port, BYTE dat) { picp = &pic.pi[(port >> 3) & 1]; if (!picp->writeicw) { #if 1 // マスクのセットだけなら nevent_forceexit()をコールしない - if ((isI286DI) || (pic.ext_irq) || + if ((CPU_isDI) || (pic.ext_irq) || ((picp->imr & dat) == picp->imr)) { picp->imr = dat; return; @@ -376,7 +375,7 @@ static void IOOUTCALL pic_o02(UINT port, BYTE dat) { nevent_forceexit(); } -static BYTE IOINPCALL pic_i00(UINT port) { +static REG8 IOINPCALL pic_i00(UINT port) { PICITEM picp; @@ -393,7 +392,7 @@ static BYTE IOINPCALL pic_i00(UINT port) { } } -static BYTE IOINPCALL pic_i02(UINT port) { +static REG8 IOINPCALL pic_i02(UINT port) { PICITEM picp; diff --git a/io/pic.h b/io/pic.h index b5d0ade5..10bc3350 100644 --- a/io/pic.h +++ b/io/pic.h @@ -1,23 +1,23 @@ typedef struct { int levels; - BYTE level[8]; + UINT8 level[8]; int levelsbak; - BYTE levelbak[8]; + UINT8 levelbak[8]; - BYTE pry[8]; - BYTE icw[4]; + UINT8 pry[8]; + UINT8 icw[4]; - BYTE imr; // ocw1 - BYTE ocw3; - BYTE irr; - BYTE ext; + UINT8 imr; // ocw1 + UINT8 ocw3; + UINT8 irr; + UINT8 ext; - BYTE isr; - BYTE isrbak; - BYTE writeicw; - BYTE padding; + UINT8 isr; + UINT8 isrbak; + UINT8 writeicw; + UINT8 padding; } _PICITEM, *PICITEM; @@ -67,9 +67,9 @@ void extirq_push(void); void extirq_pop(void); void pic_irq(void); -void pic_setirq(BYTE irq); -void pic_resetirq(BYTE irq); -void pic_registext(BYTE irq); +void pic_setirq(REG8 irq); +void pic_resetirq(REG8 irq); +void pic_registext(REG8 irq); void picmask(NEVENTITEM item); diff --git a/io/pit.c b/io/pit.c index cf82fde6..f06d35ad 100644 --- a/io/pit.c +++ b/io/pit.c @@ -3,7 +3,6 @@ // #include "compiler.h" -#include "i286.h" #include "pccore.h" #include "iocore.h" #include "sound.h" @@ -149,7 +148,7 @@ void rs232ctimer(NEVENTITEM item) { // --------------------------------------------------------------------------- -static UINT16 itimer_latch(int ch) { +static UINT pit_latch(int ch) { SINT32 clock; @@ -160,7 +159,7 @@ static UINT16 itimer_latch(int ch) { return(pit.value[1]); #ifdef uPD71054 case 0x06: - return(pit.value[1] & 0xfffe); + return(pit.value[1] & (~1)); #endif } #if defined(BEEPCOUNTEREX) @@ -175,29 +174,29 @@ static UINT16 itimer_latch(int ch) { else { clock >>= 16; } - return((UINT16)clock); + return(clock); #endif } clock = nevent_getremain(NEVENT_ITIMER + ch); if (clock >= 0) { - return((UINT16)(clock / pc.multiple)); + return(clock / pc.multiple); } return(0); } -void itimer_setflag(int ch, BYTE value) { +void pit_setflag(int ch, REG8 value) { pit.flag[ch] = 0; if (value & 0x30) { - pit.mode[ch] = value; + pit.mode[ch] = (UINT8)value; } else { // latch pit.mode[ch] &= ~0x30; - pit.latch[ch] = itimer_latch(ch); + pit.latch[ch] = (UINT16)pit_latch(ch); } } -BOOL itimer_setcount(int ch, BYTE value) { +BOOL pit_setcount(int ch, REG8 value) { switch(pit.mode[ch] & 0x30) { case 0x10: // access low @@ -223,30 +222,29 @@ BOOL itimer_setcount(int ch, BYTE value) { return(FALSE); } -BYTE itimer_getcount(int ch) { +REG8 pit_getcount(int ch) { - BYTE ret; - UINT16 w; + REG8 ret; + REG16 w; if (!(pit.mode[ch] & 0x30)) { w = pit.latch[ch]; } else { - w = itimer_latch(ch); + w = pit_latch(ch); } switch(pit.mode[ch] & 0x30) { case 0x10: // access low - return((BYTE)w); + return((UINT8)w); case 0x20: // access high - return((BYTE)(w >> 8)); + return((UINT8)(w >> 8)); } - // access word - if (!(pit.flag[ch] & 1)) { - ret = (BYTE)w; + if (!(pit.flag[ch] & 1)) { // access word + ret = (UINT8)w; } else { - ret = (BYTE)(w >> 8); + ret = (UINT8)(w >> 8); } pit.flag[ch] ^= 1; return(ret); @@ -256,10 +254,9 @@ BYTE itimer_getcount(int ch) { // ---- I/O // system timer -static void IOOUTCALL pit_o71(UINT port, BYTE dat) { +static void IOOUTCALL pit_o71(UINT port, REG8 dat) { -// TRACEOUT(("pic o71: %x [%.4x %.4x]", dat, I286_CS, I286_IP)); - if (itimer_setcount(0, dat)) { + if (pit_setcount(0, dat)) { return; } pic.pi[0].irr &= (~1); @@ -269,9 +266,9 @@ static void IOOUTCALL pit_o71(UINT port, BYTE dat) { } // beep -static void IOOUTCALL pit_o73(UINT port, BYTE dat) { +static void IOOUTCALL pit_o73(UINT port, REG8 dat) { - if (itimer_setcount(1, dat)) { + if (pit_setcount(1, dat)) { return; } setbeepevent(NEVENT_ABSOLUTE); @@ -285,9 +282,9 @@ static void IOOUTCALL pit_o73(UINT port, BYTE dat) { } // rs-232c -static void IOOUTCALL pit_o75(UINT port, BYTE dat) { +static void IOOUTCALL pit_o75(UINT port, REG8 dat) { - if (itimer_setcount(2, dat)) { + if (pit_setcount(2, dat)) { return; } rs232c_open(); @@ -296,14 +293,14 @@ static void IOOUTCALL pit_o75(UINT port, BYTE dat) { } // ctrl -static void IOOUTCALL pit_o77(UINT port, BYTE dat) { +static void IOOUTCALL pit_o77(UINT port, REG8 dat) { int ch; // TRACEOUT(("pic o77: %x", dat)); ch = (dat >> 6) & 3; if (ch != 3) { - itimer_setflag(ch, dat); + pit_setflag(ch, dat); if (ch == 0) { // 書込みで itimerのirrがリセットされる… pic.pi[0].irr &= (~1); if (dat & 0x30) { // 一応ラッチ時は割り込みをセットしない @@ -318,9 +315,9 @@ static void IOOUTCALL pit_o77(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL pit_i71(UINT port) { +static REG8 IOINPCALL pit_i71(UINT port) { - return(itimer_getcount((port >> 1) & 3)); + return(pit_getcount((port >> 1) & 3)); } diff --git a/io/pit.h b/io/pit.h index 36f1f59b..6552fefe 100644 --- a/io/pit.h +++ b/io/pit.h @@ -1,8 +1,8 @@ typedef struct { - BYTE mode[4]; - BYTE flag[4]; - BYTE intr[4]; + UINT8 mode[4]; + UINT8 flag[4]; + UINT8 intr[4]; UINT16 value[4]; UINT16 latch[4]; } _PIT, *PIT; @@ -17,9 +17,9 @@ void systimer(NEVENTITEM item); void beeponeshot(NEVENTITEM item); void rs232ctimer(NEVENTITEM item); -void itimer_setflag(int ch, BYTE value); -BOOL itimer_setcount(int ch, BYTE value); -BYTE itimer_getcount(int ch); +void pit_setflag(int ch, REG8 value); +BOOL pit_setcount(int ch, REG8 value); +REG8 pit_getcount(int ch); void itimer_reset(void); void itimer_bind(void); diff --git a/io/printif.c b/io/printif.c index 53df7cc2..d6b86479 100644 --- a/io/printif.c +++ b/io/printif.c @@ -1,14 +1,14 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" // ---- I/O -static BYTE IOINPCALL prt_i42(UINT port) { +static REG8 IOINPCALL prt_i42(UINT port) { - BYTE ret; + REG8 ret; ret = 0x84; if (pc.cpumode & CPUMODE_8MHz) { @@ -21,7 +21,7 @@ static BYTE IOINPCALL prt_i42(UINT port) { ret |= 0x08; } #ifndef EPSON_286 - if (CPUTYPE & CPUTYPE_V30) { + if (CPU_TYPE & CPUTYPE_V30) { ret |= 0x02; } #else diff --git a/io/serial.c b/io/serial.c index f057325a..bdc20649 100644 --- a/io/serial.c +++ b/io/serial.c @@ -4,7 +4,7 @@ #include "iocore.h" -static const BYTE joykeytable[12] = { +static const UINT8 joykeytable[12] = { 0x2a, 0x34, 0x29, 0x1c, 0x3c, 0x48, @@ -12,7 +12,7 @@ static const BYTE joykeytable[12] = { 0x3d, 0x4b, 0x3a, 0x43}; -static const BYTE kbexflag[0x80] = { +static const UINT8 kbexflag[0x80] = { // ESC, 1, 2, 3, 4, 5, 6, 7 ; 00h 0, 0, 0, 0, 0, 0, 0, 0, // 8, 9, 0, −, ^, ¥, BS, TAB ; 08h @@ -72,7 +72,7 @@ void keyb_callback(NEVENTITEM item) { } } -static void keyb_out(BYTE data) { +static void keyb_out(REG8 data) { if (keyb.buffers < KB_BUF) { keyb.buf[(keyb.pos + keyb.buffers) & KB_BUFMASK] = data; @@ -89,7 +89,7 @@ static void keyb_out(BYTE data) { // ---- - BYTE keystat[0x80]; + UINT8 keystat[0x80]; void keystat_reset(void) { @@ -97,9 +97,9 @@ void keystat_reset(void) { } -void keystat_senddata(BYTE data) { +void keystat_senddata(REG8 data) { - BYTE key; + REG8 key; BOOL keynochange; key = data & 0x7f; @@ -147,7 +147,7 @@ void keystat_senddata(BYTE data) { if (data & 0x80) { // ver0.30 return; } - keyb_out((BYTE)(data ^ 0x80)); + keyb_out((REG8)(data ^ 0x80)); } keyb_out(data); } @@ -155,46 +155,46 @@ void keystat_senddata(BYTE data) { void keystat_resetcopyhelp(void) { - BYTE i; + REG8 i; for (i=0x60; i<0x62; i++) { if (keystat[i] & 0x80) { keystat[i] &= 0x7f; - keyb_out((BYTE)(i | 0x80)); + keyb_out((REG8)(i | 0x80)); } } } void keystat_allrelease(void) { - UINT i; + REG8 i; for (i=0; i<0x80; i++) { if (keystat[i] & 0x80) { keystat[i] &= ~0x80; - keyb_out((BYTE)(i + 0x80)); + keyb_out((REG8)(i | 0x80)); } } } -void keystat_forcerelease(BYTE value) { +void keystat_forcerelease(REG8 value) { if (keystat[value & 0x7f] & 0x80) { keystat[value & 0x7f] &= ~0x80; - keyb_out((BYTE)(value | 0x80)); + keyb_out((REG8)(value | 0x80)); } } void keystat_resetjoykey(void) { int i; - BYTE key; + REG8 key; for (i=0; i<12; i++) { key = joykeytable[i]; if (keystat[key] & 0x80) { keystat[key] &= 0x7f; - keyb_out((BYTE)(key | 0x80)); + keyb_out((REG8)(key | 0x80)); } } } @@ -203,20 +203,20 @@ void keystat_resetjoykey(void) { // ---- typedef struct { - BYTE joysync; - BYTE joylast; - BYTE mouselast; - BYTE padding; - BYTE d_up; - BYTE d_dn; - BYTE d_lt; - BYTE d_rt; + UINT8 joysync; + UINT8 joylast; + UINT8 mouselast; + UINT8 padding; + UINT8 d_up; + UINT8 d_dn; + UINT8 d_lt; + UINT8 d_rt; } KEYEXT; static KEYEXT keyext; -static const BYTE mousedelta[] = {1, 1, 1, 1, +static const UINT8 mousedelta[] = {1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4}; -#define MOUSESTEPMAX ((sizeof(mousedelta) / sizeof(BYTE)) - 1) +#define MOUSESTEPMAX ((sizeof(mousedelta) / sizeof(UINT8)) - 1) void keyext_flash(void) { @@ -313,13 +313,13 @@ BYTE keyext_getmouse(SINT16 *x, SINT16 *y) { // ---- -static void IOOUTCALL keyb_o41(UINT port, BYTE dat) { +static void IOOUTCALL keyb_o41(UINT port, REG8 dat) { keyb.mode = dat; (void)port; } -static void IOOUTCALL keyb_o43(UINT port, BYTE dat) { +static void IOOUTCALL keyb_o43(UINT port, REG8 dat) { if ((!(dat & 0x08)) && (keyb.cmd & 0x08)) { keyboard_resetsignal(); @@ -331,13 +331,13 @@ static void IOOUTCALL keyb_o43(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL keyb_i41(UINT port) { +static REG8 IOINPCALL keyb_i41(UINT port) { (void)port; return(keyb.data); } -static BYTE IOINPCALL keyb_i43(UINT port) { +static REG8 IOINPCALL keyb_i43(UINT port) { (void)port; return(keyb.status); @@ -373,7 +373,7 @@ void keyboard_resetsignal(void) { // ver0.29 keyboard_reset(); for (i=0; i<0x80; i++) { if (keystat[i]) { - keyb_out((BYTE)i); + keyb_out((REG8)i); } } } @@ -445,10 +445,10 @@ void rs232c_midipanic(void) { // ---- -static void IOOUTCALL rs232c_o30(UINT port, BYTE dat) { +static void IOOUTCALL rs232c_o30(UINT port, REG8 dat) { if (cm_rs232c) { - cm_rs232c->write(cm_rs232c, dat); + cm_rs232c->write(cm_rs232c, (UINT8)dat); } if (sysport.c & 4) { rs232c.send = 0; @@ -460,7 +460,7 @@ static void IOOUTCALL rs232c_o30(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL rs232c_o32(UINT port, BYTE dat) { +static void IOOUTCALL rs232c_o32(UINT port, REG8 dat) { if (!(dat & 0xfd)) { rs232c.dummyinst++; @@ -518,13 +518,13 @@ static void IOOUTCALL rs232c_o32(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL rs232c_i30(UINT port) { +static REG8 IOINPCALL rs232c_i30(UINT port) { (void)port; return(rs232c.data); } -static BYTE IOINPCALL rs232c_i32(UINT port) { +static REG8 IOINPCALL rs232c_i32(UINT port) { if (!(rs232c_stat() & 0x20)) { return(rs232c.result | 0x80); diff --git a/io/serial.h b/io/serial.h index 87d13782..dc6b6b34 100644 --- a/io/serial.h +++ b/io/serial.h @@ -6,20 +6,20 @@ enum { }; typedef struct { - BYTE data; - BYTE mode; - BYTE cmd; - BYTE status; + UINT8 data; + UINT8 mode; + UINT8 cmd; + UINT8 status; int buffers; int pos; BYTE buf[KB_BUF]; } _KEYB, *KEYB; typedef struct { - BYTE result; - BYTE data; - BYTE send; - BYTE pad; + UINT8 result; + UINT8 data; + UINT8 send; + UINT8 pad; UINT pos; UINT dummyinst; UINT mul; @@ -32,9 +32,9 @@ extern "C" { #endif void keystat_reset(void); -void keystat_senddata(BYTE data); +void keystat_senddata(REG8 data); void keystat_allrelease(void); -void keystat_forcerelease(BYTE value); +void keystat_forcerelease(REG8 value); void keystat_resetcopyhelp(void); void keystat_resetjoykey(void); diff --git a/io/sysport.c b/io/sysport.c index 244bc3e7..18917b62 100644 --- a/io/sysport.c +++ b/io/sysport.c @@ -7,7 +7,7 @@ // ---- I/O -static void IOOUTCALL sysp_o35(UINT port, BYTE dat) { +static void IOOUTCALL sysp_o35(UINT port, REG8 dat) { if ((sysport.c ^ dat) & 0x04) { // ver0.29 rs232c.send = 1; @@ -17,9 +17,9 @@ static void IOOUTCALL sysp_o35(UINT port, BYTE dat) { (void)port; } -static void IOOUTCALL sysp_o37(UINT port, BYTE dat) { +static void IOOUTCALL sysp_o37(UINT port, REG8 dat) { - BYTE bit; + REG8 bit; if (!(dat & 0xf0)) { bit = 1 << (dat >> 1); @@ -39,25 +39,24 @@ static void IOOUTCALL sysp_o37(UINT port, BYTE dat) { (void)port; } -static BYTE IOINPCALL sysp_i31(UINT port) { +static REG8 IOINPCALL sysp_i31(UINT port) { (void)port; return(np2cfg.dipsw[1]); } -static BYTE IOINPCALL sysp_i33(UINT port) { +static REG8 IOINPCALL sysp_i33(UINT port) { - BYTE ret; + REG8 ret; ret = ((~np2cfg.dipsw[0]) & 1) << 3; ret |= rs232c_stat(); ret |= uPD4990.cdat; - (void)port; return(ret); } -static BYTE IOINPCALL sysp_i35(UINT port) { +static REG8 IOINPCALL sysp_i35(UINT port) { (void)port; return(sysport.c); diff --git a/io/sysport.h b/io/sysport.h index 8e087581..cbd547b6 100644 --- a/io/sysport.h +++ b/io/sysport.h @@ -1,6 +1,6 @@ typedef struct { - BYTE c; + UINT8 c; } _SYSPORT, *SYSPORT; diff --git a/io/upd4990.c b/io/upd4990.c index c2c65e1e..c111bce1 100644 --- a/io/upd4990.c +++ b/io/upd4990.c @@ -7,13 +7,13 @@ // ---- I/O -static void IOOUTCALL upd4990_o20(UINT port, BYTE dat) { +static void IOOUTCALL upd4990_o20(UINT port, REG8 dat) { - BYTE mod; - BYTE cmd; + REG8 mod; + REG8 cmd; mod = dat ^ uPD4990.last; - uPD4990.last = dat; + uPD4990.last = (UINT8)dat; if (dat & 0x08) { // STB if (mod & 0x08) { @@ -25,13 +25,16 @@ static void IOOUTCALL upd4990_o20(UINT port, BYTE dat) { case 0x00: // register hold uPD4990.regsft = 0; break; + case 0x01: // register shift uPD4990.regsft = 1; uPD4990.pos = (UPD4990_REGLEN * 8) - 1; break; + case 0x02: // time set / counter hold uPD4990.regsft = 0; break; + case 0x03: // time read uPD4990.regsft = 0; ZeroMemory(uPD4990.reg, sizeof(uPD4990.reg)); diff --git a/io/upd4990.h b/io/upd4990.h index 784a263a..d498b1d6 100644 --- a/io/upd4990.h +++ b/io/upd4990.h @@ -2,14 +2,14 @@ #define UPD4990_REGLEN 8 typedef struct { - BYTE last; - BYTE cmd; - BYTE serial; - BYTE parallel; + UINT8 last; + UINT8 cmd; + UINT8 serial; + UINT8 parallel; BYTE reg[UPD4990_REGLEN]; UINT pos; - BYTE cdat; - BYTE regsft; + UINT8 cdat; + UINT8 regsft; } _UPD4990, *UPD4990; diff --git a/lio/gcls.c b/lio/gcls.c index ee3bec1f..5eb54952 100644 --- a/lio/gcls.c +++ b/lio/gcls.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +// #include "cpucore.h" #include "memory.h" #include "lio.h" diff --git a/lio/gcolor1.c b/lio/gcolor1.c index 54ae089b..f276d303 100644 --- a/lio/gcolor1.c +++ b/lio/gcolor1.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -11,7 +11,7 @@ BYTE lio_gcolor1(void) { LIOGCOLOR1 dat; LIOGCOLOR1 gcolor1; - i286_memstr_read(I286_DS, I286_BX, &dat, sizeof(dat)); + i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat)); if (dat.palmode < 2) { gcolor1.palmax = 8; gcolor1.palmode = dat.palmode; diff --git a/lio/gcolor2.c b/lio/gcolor2.c index a6d40d7f..874da319 100644 --- a/lio/gcolor2.c +++ b/lio/gcolor2.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -17,7 +17,7 @@ BYTE lio_gcolor2(void) { MEMGCOLOR2 dat; - i286_memstr_read(I286_DS, I286_BX, &dat, sizeof(dat)); + i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat)); if (dat.pal >= lio.gcolor1.palmax) { return(5); diff --git a/lio/gline.c b/lio/gline.c index 6a0fa5a6..50d3f893 100644 --- a/lio/gline.c +++ b/lio/gline.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "lio.h" @@ -49,7 +49,7 @@ BYTE lio_gline(void) { SINT16 x2; SINT16 y2; - i286_memstr_read(I286_DS, I286_BX, &dat, sizeof(dat)); + i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat)); if (dat.pal == 0xff) { dat.pal = lio.gcolor1.fgcolor; } diff --git a/lio/gpset.c b/lio/gpset.c index 92c56c5f..87213bf6 100644 --- a/lio/gpset.c +++ b/lio/gpset.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "lio.h" @@ -17,9 +17,9 @@ BYTE lio_gpset(void) { SINT16 x; SINT16 y; - i286_memstr_read(I286_DS, I286_BX, &gpset, sizeof(gpset)); + i286_memstr_read(CPU_DS, CPU_BX, &gpset, sizeof(gpset)); if (gpset.pal >= lio.gcolor1.palmax) { - if (I286_AH == 2) { + if (CPU_AH == 2) { gpset.pal = lio.gcolor1.bgcolor; } else { diff --git a/lio/gput1.c b/lio/gput1.c index 24f12711..42223333 100644 --- a/lio/gput1.c +++ b/lio/gput1.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "lio.h" @@ -21,7 +21,7 @@ BYTE lio_gput1(void) { MEMGPUT1 dat; - i286_memstr_read(I286_DS, I286_BX, &dat, sizeof(dat)); + i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat)); return(0); } diff --git a/lio/gscreen.c b/lio/gscreen.c index 9d49ddb4..eb377c14 100644 --- a/lio/gscreen.c +++ b/lio/gscreen.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -41,7 +41,7 @@ BYTE lio_gscreen(void) { BYTE bit; int disp; - i286_memstr_read(I286_DS, I286_BX, &data, sizeof(data)); + i286_memstr_read(CPU_DS, CPU_BX, &data, sizeof(data)); if (data.mode == 0xff) { data.mode = lio.gscreen.mode; } diff --git a/lio/gview.c b/lio/gview.c index c56ba97b..ff2a366b 100644 --- a/lio/gview.c +++ b/lio/gview.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -52,7 +52,7 @@ BYTE lio_gview(void) { SINT16 x2; SINT16 y2; - i286_memstr_read(I286_DS, I286_BX, &dat, sizeof(dat)); + i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat)); x1 = (SINT16)LOADINTELWORD(dat.x1); y1 = (SINT16)LOADINTELWORD(dat.y1); x2 = (SINT16)LOADINTELWORD(dat.x2); diff --git a/lio/lio.c b/lio/lio.c index 4ba70f68..49b60e4e 100644 --- a/lio/lio.c +++ b/lio/lio.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -71,35 +71,35 @@ void bios_lio(BYTE cmd) { for (i=0; i<8; i++) { lio.degcol[i] = i; } - I286_AH = 0; + CPU_AH = 0; break; case 0x01: // a1: GSCREEN - I286_AH = lio_gscreen(); + CPU_AH = lio_gscreen(); break; case 0x02: // a2: GVIEW - I286_AH = lio_gview(); + CPU_AH = lio_gview(); break; case 0x03: // a3: GCOLOR1 - I286_AH = lio_gcolor1(); + CPU_AH = lio_gcolor1(); break; case 0x04: // a4: GCOLOR2 - I286_AH = lio_gcolor2(); + CPU_AH = lio_gcolor2(); break; case 0x05: // a5: GCLS - I286_AH = lio_gcls(); + CPU_AH = lio_gcls(); break; case 0x06: // a6: GPSET - I286_AH = lio_gpset(); + CPU_AH = lio_gpset(); break; case 0x07: // a7: GLINE - I286_AH = lio_gline(); + CPU_AH = lio_gline(); break; case 0x08: // a8: GCIRCLE @@ -115,7 +115,7 @@ void bios_lio(BYTE cmd) { break; case 0x0c: // ac: GPUT1 - I286_AH = lio_gput1(); + CPU_AH = lio_gput1(); break; case 0x0d: // ad: GPUT2 @@ -130,7 +130,7 @@ void bios_lio(BYTE cmd) { case 0x10: // ce: GCOPY break; } - // TRACEOUT(("lio cmd-%d, %d", cmd, I286_AH)); + // TRACEOUT(("lio cmd-%d, %d", cmd, CPU_AH)); } diff --git a/macos9/sysmng.cpp b/macos9/sysmng.cpp index e8758bfe..11b284a3 100644 --- a/macos9/sysmng.cpp +++ b/macos9/sysmng.cpp @@ -1,8 +1,8 @@ #include "compiler.h" #include "np2.h" #include "dosio.h" -#include "i286.h" #include "sysmng.h" +#include "cpucore.h" #include "pccore.h" #include "fddfile.h" @@ -24,7 +24,7 @@ static struct { void sysmng_workclockreset(void) { workclock.tick = GETTICK(); - workclock.clock = I286_CLOCK; + workclock.clock = CPU_CLOCK; workclock.draws = drawcount; } @@ -39,8 +39,8 @@ BOOL sysmng_workclockrenewal(void) { workclock.tick += tick; workclock.fps = ((drawcount - workclock.draws) * 10000) / tick; workclock.draws = drawcount; - workclock.khz = (I286_CLOCK - workclock.clock) / tick; - workclock.clock = I286_CLOCK; + workclock.khz = (CPU_CLOCK - workclock.clock) / tick; + workclock.clock = CPU_CLOCK; return(TRUE); } diff --git a/macosx/np2info.cpp b/macosx/np2info.cpp index ffb41d44..9417a2ff 100644 --- a/macosx/np2info.cpp +++ b/macosx/np2info.cpp @@ -3,7 +3,7 @@ #include "np2.h" #include "scrnmng.h" #include "np2info.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -68,7 +68,7 @@ static void info_ver(char *str, int maxlen) { static void info_cpu(char *str, int maxlen) { - milstr_ncpy(str, (CPUTYPE & CPUTYPE_V30)?str_V30:str_i286, maxlen); + milstr_ncpy(str, (CPU_TYPE & CPUTYPE_V30)?str_V30:str_i286, maxlen); } static void info_clock(char *str, int maxlen) { diff --git a/macosx/sysmng.cpp b/macosx/sysmng.cpp index 6fbcefd5..07552623 100644 --- a/macosx/sysmng.cpp +++ b/macosx/sysmng.cpp @@ -1,8 +1,8 @@ #include "compiler.h" #include "np2.h" #include "dosio.h" -#include "i286.h" #include "sysmng.h" +#include "cpucore.h" #include "pccore.h" #include "fddfile.h" #include "diskdrv.h" @@ -24,7 +24,7 @@ static struct { void sysmng_workclockreset(void) { workclock.tick = GETTICK(); - workclock.clock = I286_CLOCK; + workclock.clock = CPU_CLOCK; workclock.draws = drawcount; } @@ -39,8 +39,8 @@ BOOL sysmng_workclockrenewal(void) { workclock.tick += tick; workclock.fps = ((drawcount - workclock.draws) * 10000) / tick; workclock.draws = drawcount; - workclock.khz = (I286_CLOCK - workclock.clock) / tick; - workclock.clock = I286_CLOCK; + workclock.khz = (CPU_CLOCK - workclock.clock) / tick; + workclock.clock = CPU_CLOCK; return(TRUE); } diff --git a/nevent.c b/nevent.c index 35f42bd7..5e120e3a 100644 --- a/nevent.c +++ b/nevent.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" @@ -16,15 +16,15 @@ void nevent_get1stevent(void) { // 最短のイベントのクロック数をセット if (nevent.readyevents) { - I286_BASECLOCK = nevent.item[nevent.level[0]].clock; + CPU_BASECLOCK = nevent.item[nevent.level[0]].clock; } else { // イベントがない場合のクロック数をセット - I286_BASECLOCK = NEVENT_MAXCLOCK; + CPU_BASECLOCK = NEVENT_MAXCLOCK; } // カウンタへセット - I286_REMCLOCK = I286_BASECLOCK; + CPU_REMCLOCK = CPU_BASECLOCK; } static void nevent_execute(void) { @@ -64,13 +64,13 @@ void nevent_progress(void) { UINT curid; NEVENTITEM item; - I286_CLOCK += I286_BASECLOCK; + CPU_CLOCK += CPU_BASECLOCK; eventnum = 0; nextbase = NEVENT_MAXCLOCK; for (i=0; iclock -= I286_BASECLOCK; + item->clock -= CPU_BASECLOCK; if (item->clock > 0) { // イベント待ち中 nevent.level[eventnum++] = curid; @@ -89,10 +89,10 @@ void nevent_progress(void) { } } nevent.readyevents = eventnum; - I286_BASECLOCK = nextbase; - I286_REMCLOCK += nextbase; + CPU_BASECLOCK = nextbase; + CPU_REMCLOCK += nextbase; nevent_execute(); -// TRACEOUT(("nextbase = %d (%d)", nextbase, I286_REMCLOCK)); +// TRACEOUT(("nextbase = %d (%d)", nextbase, CPU_REMCLOCK)); } @@ -145,7 +145,7 @@ void nevent_set(UINT id, SINT32 eventclock, NEVENTCB proc, BOOL absolute) { // TRACEOUT(("event %d - %xclocks", id, eventclock)); - clock = I286_BASECLOCK - I286_REMCLOCK; + clock = CPU_BASECLOCK - CPU_REMCLOCK; item = &nevent.item[id]; item->proc = proc; item->flag = 0; @@ -179,10 +179,10 @@ void nevent_set(UINT id, SINT32 eventclock, NEVENTCB proc, BOOL absolute) { // もし最短イベントだったら... if (eventid == 0) { - clock = I286_BASECLOCK - item->clock; - I286_BASECLOCK -= clock; - I286_REMCLOCK -= clock; -// TRACEOUT(("reset nextbase -%d (%d)", clock, I286_REMCLOCK)); + clock = CPU_BASECLOCK - item->clock; + CPU_BASECLOCK -= clock; + CPU_REMCLOCK -= clock; +// TRACEOUT(("reset nextbase -%d (%d)", clock, CPU_REMCLOCK)); } } @@ -211,7 +211,7 @@ SINT32 nevent_getremain(UINT id) { // 現在進行してるイベントを検索 for (i=0; i 0) { - I286_BASECLOCK -= I286_REMCLOCK; - I286_REMCLOCK = 0; + if (CPU_REMCLOCK > 0) { + CPU_BASECLOCK -= CPU_REMCLOCK; + CPU_REMCLOCK = 0; } } diff --git a/pccore.c b/pccore.c index de1db345..ee7b9173 100644 --- a/pccore.c +++ b/pccore.c @@ -3,7 +3,7 @@ #include "soundmng.h" #include "sysmng.h" #include "timemng.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "np2ver.h" #include "pccore.h" @@ -204,7 +204,7 @@ static void sound_term(void) { void pccore_init(void) { - i286_initialize(); + CPU_INITIALIZE(); pal_initlcdtable(); pal_makelcdpal(); @@ -277,10 +277,10 @@ void pccore_reset(void) { ZeroMemory(mem + VRAM1_E, 0x08000); ZeroMemory(mem + FONT_ADRS, 0x08000); - i286_reset(); - CPUTYPE = 0; + CPU_RESET(); + CPU_TYPE = 0; if (np2cfg.dipsw[2] & 0x80) { - CPUTYPE = CPUTYPE_V30; + CPU_TYPE = CPUTYPE_V30; } //メモリスイッチ @@ -326,18 +326,18 @@ void pccore_reset(void) { if (np2cfg.ITF_WORK) { CS_BASE = 0xf0000; - I286_CS = 0xf000; - I286_IP = 0xfff0; + CPU_CS = 0xf000; + CPU_IP = 0xfff0; } else { for (i=0; i<8; i++) { mem[0xa3fe2 + i*4] = msw_default[i]; } CS_BASE = 0xfd800; - I286_CS = 0xfd80; - I286_IP = 0x0002; + CPU_CS = 0xfd80; + CPU_IP = 0x0002; } - i286_resetprefetch(); + CPU_CLEARPREFETCH(); sysmng_cpureset(); soundmng_play(); @@ -541,29 +541,29 @@ void pccore_exec(BOOL draw) { resetcnt++; #endif pic_irq(); - if (i286core.s.resetreq) { - i286core.s.resetreq = 0; - I286_CS = 0xf000; + if (CPU_RESETREQ) { + CPU_RESETREQ = 0; + CPU_CS = 0xf000; CS_BASE = 0xf0000; - I286_IP = 0xfff0; + CPU_IP = 0xfff0; #ifdef CPU386 // defineを変えてね - I286_DX = 0x0300; + CPU_DX = 0x0300; #endif - i286_resetprefetch(); + CPU_CLEARPREFETCH(); } #if 1 // ndef TRACE - if (I286_REMCLOCK > 0) { - if (!(CPUTYPE & CPUTYPE_V30)) { - i286(); + if (CPU_REMCLOCK > 0) { + if (!(CPU_TYPE & CPUTYPE_V30)) { + CPU_EXEC(); } else { - v30(); + CPU_EXECV30(); } } #else - while(I286_REMCLOCK > 0) { - TRACEOUT(("%.4x:%.4x", I286_CS, I286_IP)); + while(CPU_REMCLOCK > 0) { + TRACEOUT(("%.4x:%.4x", CPU_CS, CPU_IP)); i286_step(); } #endif diff --git a/sound/adpcm.h b/sound/adpcm.h index d6039a86..903b558e 100644 --- a/sound/adpcm.h +++ b/sound/adpcm.h @@ -64,11 +64,11 @@ void adpcm_setvol(UINT vol); void adpcm_reset(ADPCM ad); void adpcm_update(ADPCM ad); -void adpcm_setreg(ADPCM ad, BYTE reg, BYTE value); -BYTE adpcm_status(ADPCM ad); +void adpcm_setreg(ADPCM ad, REG8 reg, REG8 value); +REG8 adpcm_status(ADPCM ad); -BYTE SOUNDCALL adpcm_readsample(ADPCM ad); -void SOUNDCALL adpcm_datawrite(ADPCM ad, BYTE data); +REG8 SOUNDCALL adpcm_readsample(ADPCM ad); +void SOUNDCALL adpcm_datawrite(ADPCM ad, REG8 data); void SOUNDCALL adpcm_getpcm(ADPCM ad, SINT32 *buf, UINT count); #ifdef __cplusplus diff --git a/sound/adpcmc.c b/sound/adpcmc.c index 96274a5d..b9f489f9 100644 --- a/sound/adpcmc.c +++ b/sound/adpcmc.c @@ -46,7 +46,7 @@ void adpcm_update(ADPCM ad) { ad->level = (ad->reg.level * adpcmcfg.vol) >> 4; } -void adpcm_setreg(ADPCM ad, BYTE reg, BYTE value) { +void adpcm_setreg(ADPCM ad, REG8 reg, REG8 value) { UINT32 addr; @@ -115,7 +115,7 @@ void adpcm_setreg(ADPCM ad, BYTE reg, BYTE value) { } } -BYTE adpcm_status(ADPCM ad) { +REG8 adpcm_status(ADPCM ad) { return(((ad->status | 8) & ad->mask) | ad->play); } diff --git a/sound/adpcmg.c b/sound/adpcmg.c index b16d4208..6f1791c5 100644 --- a/sound/adpcmg.c +++ b/sound/adpcmg.c @@ -10,11 +10,11 @@ static const UINT adpcmdeltatable[8] = { 228, 228, 228, 228, 308, 408, 512, 612}; -BYTE SOUNDCALL adpcm_readsample(ADPCM ad) { +REG8 SOUNDCALL adpcm_readsample(ADPCM ad) { UINT32 pos; - BYTE data; - BYTE ret; + REG8 data; + REG8 ret; if ((ad->reg.ctrl1 & 0x60) == 0x20) { pos = ad->pos & 0x1fffff; @@ -24,7 +24,7 @@ BYTE SOUNDCALL adpcm_readsample(ADPCM ad) { } else { const BYTE *ptr; - BYTE bit; + REG8 bit; UINT tmp; ptr = ad->buf + ((pos >> 3) & 0x7fff); bit = 1 << (pos & 7); @@ -36,7 +36,7 @@ BYTE SOUNDCALL adpcm_readsample(ADPCM ad) { tmp += (ptr[0x28000] & bit) << 5; tmp += (ptr[0x30000] & bit) << 6; tmp += (ptr[0x38000] & bit) << 7; - data = (BYTE)(tmp >> (pos & 7)); + data = (REG8)(tmp >> (pos & 7)); pos++; } if (pos != ad->stop) { @@ -58,7 +58,7 @@ BYTE SOUNDCALL adpcm_readsample(ADPCM ad) { return(ret); } -void SOUNDCALL adpcm_datawrite(ADPCM ad, BYTE data) { +void SOUNDCALL adpcm_datawrite(ADPCM ad, REG8 data) { UINT32 pos; @@ -69,8 +69,8 @@ void SOUNDCALL adpcm_datawrite(ADPCM ad, BYTE data) { } else { BYTE *ptr; - BYTE bit; - BYTE mask; + UINT8 bit; + UINT8 mask; ptr = ad->buf + ((pos >> 3) & 0x7fff); bit = 1 << (pos & 7); mask = ~bit; @@ -136,7 +136,7 @@ static void SOUNDCALL getadpcmdata(ADPCM ad) { } else { const BYTE *ptr; - BYTE bit; + REG8 bit; UINT tmp; ptr = ad->buf + ((pos >> 3) & 0x7fff); bit = 1 << (pos & 7); diff --git a/sound/beepc.c b/sound/beepc.c index a3d6deb1..786c4234 100644 --- a/sound/beepc.c +++ b/sound/beepc.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "sound.h" @@ -81,7 +81,7 @@ static void beep_eventset(void) { if (beep.enable != enable) { beep.enable = enable; if (beep.events < BEEPEVENT_MAX) { - clock = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK; + clock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; evt = beep.event + beep.events; beep.events++; evt->clock = (clock - beep.clock) * beepcfg.samplebase; diff --git a/sound/cs4231.h b/sound/cs4231.h index 8458742a..6dcd7681 100644 --- a/sound/cs4231.h +++ b/sound/cs4231.h @@ -1,5 +1,5 @@ -typedef BYTE (*CS4231DMA)(void); +typedef REG8 (*CS4231DMA)(void); enum { CS4231_BUFFERS = (1 << 6), @@ -74,16 +74,16 @@ extern "C" { extern const CS4231DMA cs4231dec[16]; -BYTE cs4231_nodecode(void); +REG8 cs4231_nodecode(void); void cs4231_dma(NEVENTITEM item); -BYTE DMACCALL cs4231dmafunc(BYTE func); +REG8 DMACCALL cs4231dmafunc(REG8 func); void cs4231_initialize(UINT rate); void cs4231_setvol(UINT vol); void cs4231_reset(void); void cs4231_update(void); -void cs4231_control(UINT index, BYTE value); +void cs4231_control(UINT index, REG8 value); void SOUNDCALL cs4231_getpcm(CS4231 cs, SINT32 *pcm, UINT count); diff --git a/sound/cs4231c.c b/sound/cs4231c.c index 2028b1d3..14d0b781 100644 --- a/sound/cs4231c.c +++ b/sound/cs4231c.c @@ -31,7 +31,7 @@ void cs4231_setvol(UINT vol) { void cs4231_dma(NEVENTITEM item) { - BYTE ret; + REG8 ret; SINT32 cnt; if (item->flag & NEVENT_SETEVENT) { @@ -52,7 +52,7 @@ void cs4231_dma(NEVENTITEM item) { (void)item; } -BYTE DMACCALL cs4231dmafunc(BYTE func) { +REG8 DMACCALL cs4231dmafunc(REG8 func) { SINT32 cnt; @@ -84,7 +84,7 @@ void cs4231_update(void) { } -void cs4231_control(UINT index, BYTE value) { +void cs4231_control(UINT index, REG8 value) { *(((BYTE *)(&cs4231.reg)) + index) = value; switch(index) { diff --git a/sound/cs4231g.c b/sound/cs4231g.c index d35dd83c..f28186ef 100644 --- a/sound/cs4231g.c +++ b/sound/cs4231g.c @@ -11,12 +11,12 @@ extern CS4231CFG cs4231cfg; // ---- 補完くらいしようよ… -BYTE cs4231_nodecode(void) { +REG8 cs4231_nodecode(void) { return(0); } -static BYTE cs4231_pcm8s(void) { +static REG8 cs4231_pcm8s(void) { SINT32 leng; UINT indatas; @@ -58,7 +58,7 @@ static BYTE cs4231_pcm8s(void) { return((leng < 2)?1:0); } -static BYTE cs4231_pcm8m(void) { +static REG8 cs4231_pcm8m(void) { SINT32 leng; UINT indatas; @@ -102,7 +102,7 @@ static BYTE cs4231_pcm8m(void) { return((leng == 0)?1:0); } -static BYTE cs4231_pcm16s(void) { +static REG8 cs4231_pcm16s(void) { SINT32 leng; UINT indatas; @@ -148,7 +148,7 @@ static BYTE cs4231_pcm16s(void) { return((leng < 4)?1:0); } -static BYTE cs4231_pcm16m(void) { +static REG8 cs4231_pcm16m(void) { SINT32 leng; UINT indatas; diff --git a/sound/fmboard.c b/sound/fmboard.c index 61697d28..0764377a 100644 --- a/sound/fmboard.c +++ b/sound/fmboard.c @@ -1,7 +1,7 @@ #include "compiler.h" #include "joymng.h" #include "soundmng.h" -#include "i286.h" +// #include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "cbuscore.h" @@ -40,7 +40,7 @@ MUSICGEN musicgen; -static void (*extfn)(BYTE enable); +static void (*extfn)(REG8 enable); // ---- @@ -86,12 +86,12 @@ BYTE fmboard_getjoy(PSGGEN psg) { // ---- -void fmboard_extreg(void (*ext)(BYTE enable)) { +void fmboard_extreg(void (*ext)(REG8 enable)) { extfn = ext; } -void fmboard_extenable(BYTE enable) { +void fmboard_extenable(REG8 enable) { if (extfn) { (*extfn)(enable); diff --git a/sound/fmboard.h b/sound/fmboard.h index d7652058..84756ea4 100644 --- a/sound/fmboard.h +++ b/sound/fmboard.h @@ -64,8 +64,8 @@ extern MUSICGEN musicgen; BYTE fmboard_getjoy(PSGGEN psg); -void fmboard_extreg(void (*ext)(BYTE enable)); -void fmboard_extenable(BYTE enable); +void fmboard_extreg(void (*ext)(REG8 enable)); +void fmboard_extenable(REG8 enable); void fmboard_reset(BYTE num); void fmboard_bind(void); diff --git a/sound/fmtimer.c b/sound/fmtimer.c index c69f1c44..5ef4192a 100644 --- a/sound/fmtimer.c +++ b/sound/fmtimer.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +// #include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "sound.h" @@ -89,7 +89,7 @@ static void set_fmtimerbevent(BOOL absolute) { nevent_set(NEVENT_FMTIMERB, l, fmport_b, absolute); } -void fmtimer_reset(BYTE irq) { +void fmtimer_reset(UINT irq) { ZeroMemory(&fmtimer, sizeof(fmtimer)); @@ -104,9 +104,9 @@ void fmtimer_reset(BYTE irq) { pic_registext(fmtimer.irq); } -void fmtimer_setreg(BYTE reg, BYTE value) { +void fmtimer_setreg(REG8 reg, REG8 value) { -// TRACEOUT(("fm %x %x [%.4x:%.4x]", reg, value, I286_CS, I286_IP)); +// TRACEOUT(("fm %x %x [%.4x:%.4x]", reg, value, CPU_CS, CPU_IP)); switch(reg) { case 0x24: diff --git a/sound/fmtimer.h b/sound/fmtimer.h index cf519b7c..2e0947e1 100644 --- a/sound/fmtimer.h +++ b/sound/fmtimer.h @@ -17,8 +17,8 @@ extern "C" { void fmport_a(NEVENTITEM item); void fmport_b(NEVENTITEM item); -void fmtimer_reset(BYTE irq); -void fmtimer_setreg(BYTE reg, BYTE value); +void fmtimer_reset(UINT irq); +void fmtimer_setreg(REG8 reg, REG8 value); #ifdef __cplusplus } diff --git a/sound/opngen.h b/sound/opngen.h index a9491e71..4edb59c4 100644 --- a/sound/opngen.h +++ b/sound/opngen.h @@ -97,7 +97,7 @@ const SINT32 *release; // release raito SINT32 multiple; // multiple BYTE keyscale; // key scale BYTE env_mode; // envelope mode - BYTE envraito; // envelope raito + BYTE envratio; // envelope raito BYTE ssgeg1; // SSG-EG SINT32 env_cnt; // envelope count @@ -163,13 +163,13 @@ extern "C" { void opngen_initialize(UINT rate); void opngen_setvol(UINT vol); -void opngen_setVR(BYTE channel, BYTE value); +void opngen_setVR(REG8 channel, REG8 value); void opngen_reset(void); -void opngen_setcfg(BYTE maxch, UINT flag); -void opngen_setextch(UINT chnum, BYTE data); -void opngen_setreg(BYTE chbase, BYTE reg, BYTE value); -void opngen_keyon(UINT chnum, BYTE value); +void opngen_setcfg(REG8 maxch, UINT flag); +void opngen_setextch(UINT chnum, REG8 data); +void opngen_setreg(REG8 chbase, REG8 reg, REG8 value); +void opngen_keyon(UINT chnum, REG8 value); void SOUNDCALL opngen_getpcm(void *hdl, SINT32 *buf, UINT count); void SOUNDCALL opngen_getpcmvr(void *hdl, SINT32 *buf, UINT count); diff --git a/sound/opngenc.c b/sound/opngenc.c index ff567269..c2b8f097 100644 --- a/sound/opngenc.c +++ b/sound/opngenc.c @@ -31,13 +31,13 @@ static SINT32 decaytable[94]; static const SINT32 decayleveltable[16] = { SC( 0),SC( 1),SC( 2),SC( 3),SC( 4),SC( 5),SC( 6),SC( 7), SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)}; -static const BYTE multipletable[] = { +static const UINT8 multipletable[] = { 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; static const SINT32 nulltable[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -static const BYTE kftable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3}; -static const BYTE dttable[] = { +static const UINT8 kftable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3}; +static const UINT8 dttable[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, @@ -177,7 +177,7 @@ void opngen_setvol(UINT vol) { #endif } -void opngen_setVR(BYTE channel, BYTE value) { +void opngen_setVR(REG8 channel, REG8 value) { if ((channel & 3) && (value)) { opncfg.vr_en = TRUE; @@ -195,7 +195,7 @@ void opngen_setVR(BYTE channel, BYTE value) { static void set_algorithm(OPNCH *ch) { SINT32 *outd; - BYTE outslot; + UINT8 outslot; outd = &opngen.outdc; if (ch->stereo) { @@ -270,13 +270,13 @@ static void set_algorithm(OPNCH *ch) { ch->outslot = outslot; } -static void set_dt1_mul(OPNSLOT *slot, BYTE value) { +static void set_dt1_mul(OPNSLOT *slot, REG8 value) { slot->multiple = (SINT32)multipletable[value & 0x0f]; slot->detune1 = detunetable[(value >> 4) & 7]; } -static void set_tl(OPNSLOT *slot, BYTE value) { +static void set_tl(OPNSLOT *slot, REG8 value) { #if (EVC_BITS >= 7) slot->totallevel = ((~value) & 0x007f) << (EVC_BITS - 7); @@ -285,28 +285,28 @@ static void set_tl(OPNSLOT *slot, BYTE value) { #endif } -static void set_ks_ar(OPNSLOT *slot, BYTE value) { +static void set_ks_ar(OPNSLOT *slot, REG8 value) { - slot->keyscale = (BYTE)(((~value)>>6)&3); + slot->keyscale = ((~value) >> 6) & 3; value &= 0x1f; slot->attack = (value)?(attacktable + (value << 1)):nulltable; - slot->env_inc_attack = slot->attack[slot->envraito]; + slot->env_inc_attack = slot->attack[slot->envratio]; if (slot->env_mode == EM_ATTACK) { slot->env_inc = slot->env_inc_attack; } } -static void set_d1r(OPNSLOT *slot, BYTE value) { +static void set_d1r(OPNSLOT *slot, REG8 value) { value &= 0x1f; slot->decay1 = (value)?(decaytable + (value << 1)):nulltable; - slot->env_inc_decay1 = slot->decay1[slot->envraito]; + slot->env_inc_decay1 = slot->decay1[slot->envratio]; if (slot->env_mode == EM_DECAY1) { slot->env_inc = slot->env_inc_decay1; } } -static void set_dt2_d2r(OPNSLOT *slot, BYTE value) { +static void set_dt2_d2r(OPNSLOT *slot, REG8 value) { value &= 0x1f; slot->decay2 = (value)?(decaytable + (value << 1)):nulltable; @@ -314,18 +314,18 @@ static void set_dt2_d2r(OPNSLOT *slot, BYTE value) { slot->env_inc_decay2 = 0; } else { - slot->env_inc_decay2 = slot->decay2[slot->envraito]; + slot->env_inc_decay2 = slot->decay2[slot->envratio]; } if (slot->env_mode == EM_DECAY2) { slot->env_inc = slot->env_inc_decay2; } } -static void set_d1l_rr(OPNSLOT *slot, BYTE value) { +static void set_d1l_rr(OPNSLOT *slot, REG8 value) { slot->decaylevel = decayleveltable[(value >> 4)]; slot->release = decaytable + ((value & 0x0f) << 2) + 2; - slot->env_inc_release = slot->release[slot->envraito]; + slot->env_inc_release = slot->release[slot->envratio]; if (slot->env_mode == EM_RELEASE) { slot->env_inc = slot->env_inc_release; if (value == 0xff) { @@ -337,7 +337,7 @@ static void set_d1l_rr(OPNSLOT *slot, BYTE value) { } } -static void set_ssgeg(OPNSLOT *slot, BYTE value) { +static void set_ssgeg(OPNSLOT *slot, REG8 value) { value &= 0xf; if ((value == 0xb) || (value == 0xd)) { @@ -346,7 +346,7 @@ static void set_ssgeg(OPNSLOT *slot, BYTE value) { } else { slot->ssgeg1 = 0; - slot->env_inc_decay2 = slot->decay2[slot->envraito]; + slot->env_inc_decay2 = slot->decay2[slot->envratio]; } if (slot->env_mode == EM_DECAY2) { slot->env_inc = slot->env_inc_decay2; @@ -367,8 +367,8 @@ static void channleupdate(OPNCH *ch) { for (i=0; i<4; i++, slot++) { slot->freq_inc = (fc + slot->detune1[kc]) * slot->multiple; evr = (BYTE)(kc >> slot->keyscale); - if (slot->envraito != evr) { - slot->envraito = evr; + if (slot->envratio != evr) { + slot->envratio = evr; slot->env_inc_attack = slot->attack[evr]; slot->env_inc_decay1 = slot->decay1[evr]; slot->env_inc_decay2 = slot->decay2[evr]; @@ -382,8 +382,8 @@ static void channleupdate(OPNCH *ch) { slot->freq_inc = (ch->keynote[s] + slot->detune1[ch->kcode[s]]) * slot->multiple; evr = (BYTE)(ch->kcode[s] >> slot->keyscale); - if (slot->envraito != evr) { - slot->envraito = evr; + if (slot->envratio != evr) { + slot->envratio = evr; slot->env_inc_attack = slot->attack[evr]; slot->env_inc_decay1 = slot->decay1[evr]; slot->env_inc_decay2 = slot->decay2[evr]; @@ -426,14 +426,14 @@ void opngen_reset(void) { ch++; } for (i=0x30; i<0xc0; i++) { - opngen_setreg(0, (BYTE)i, 0xff); - opngen_setreg(3, (BYTE)i, 0xff); - opngen_setreg(6, (BYTE)i, 0xff); - opngen_setreg(9, (BYTE)i, 0xff); + opngen_setreg(0, (REG8)i, 0xff); + opngen_setreg(3, (REG8)i, 0xff); + opngen_setreg(6, (REG8)i, 0xff); + opngen_setreg(9, (REG8)i, 0xff); } } -void opngen_setcfg(BYTE maxch, UINT flag) { +void opngen_setcfg(REG8 maxch, UINT flag) { OPNCH *ch; UINT i; @@ -460,7 +460,7 @@ void opngen_setcfg(BYTE maxch, UINT flag) { } } -void opngen_setextch(UINT chnum, BYTE data) { +void opngen_setextch(UINT chnum, REG8 data) { OPNCH *ch; @@ -468,7 +468,7 @@ void opngen_setextch(UINT chnum, BYTE data) { ch[chnum].extop = data; } -void opngen_setreg(BYTE chbase, BYTE reg, BYTE value) { +void opngen_setreg(REG8 chbase, REG8 reg, REG8 value) { UINT chpos; OPNCH *ch; @@ -568,11 +568,11 @@ void opngen_setreg(BYTE chbase, BYTE reg, BYTE value) { } } -void opngen_keyon(UINT chnum, BYTE value) { +void opngen_keyon(UINT chnum, REG8 value) { OPNCH *ch; OPNSLOT *slot; - BYTE bit; + REG8 bit; UINT i; sound_sync(); diff --git a/sound/pcm86.h b/sound/pcm86.h index 508c273c..bbeb1671 100644 --- a/sound/pcm86.h +++ b/sound/pcm86.h @@ -77,7 +77,7 @@ void pcm86gen_setvol(UINT vol); void pcm86_reset(void); void pcm86gen_update(void); -void pcm86_setpcmrate(BYTE val); +void pcm86_setpcmrate(REG8 val); void pcm86_setnextintr(void); void SOUNDCALL pcm86gen_checkbuf(void); diff --git a/sound/pcm86c.c b/sound/pcm86c.c index fba90d2e..b344859f 100644 --- a/sound/pcm86c.c +++ b/sound/pcm86c.c @@ -1,5 +1,5 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "sound.h" @@ -54,7 +54,7 @@ void pcm86gen_update(void) { pcm86_setpcmrate(pcm86.fifo); } -void pcm86_setpcmrate(BYTE val) { +void pcm86_setpcmrate(REG8 val) { SINT32 rate; @@ -118,7 +118,7 @@ void SOUNDCALL pcm86gen_checkbuf(void) { long bufs; UINT32 past; - past = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK; + past = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; past <<= 6; past -= pcm86.lastclock; if (past >= pcm86.stepclock) { diff --git a/sound/psggen.h b/sound/psggen.h index 0cdc630e..6d1ba7ce 100644 --- a/sound/psggen.h +++ b/sound/psggen.h @@ -67,9 +67,9 @@ void psggen_initialize(UINT rate); void psggen_setvol(UINT vol); void psggen_reset(PSGGEN psg); -void psggen_setreg(PSGGEN psg, BYTE reg, BYTE val); -BYTE psggen_getreg(PSGGEN psg, BYTE reg); -void psggen_setpan(PSGGEN psg, UINT ch, BYTE pan); +void psggen_setreg(PSGGEN psg, REG8 reg, REG8 val); +REG8 psggen_getreg(PSGGEN psg, REG8 reg); +void psggen_setpan(PSGGEN psg, UINT ch, REG8 pan); void SOUNDCALL psggen_getpcm(PSGGEN psg, SINT32 *pcm, UINT count); diff --git a/sound/psggenc.c b/sound/psggenc.c index acfbd7c2..e33963ef 100644 --- a/sound/psggenc.c +++ b/sound/psggenc.c @@ -70,11 +70,11 @@ void psggen_reset(PSGGEN psg) { psg->tone[i].pvol = &psg->envvol; } for (i=0; ireg)[reg & 15]); } -void psggen_setpan(PSGGEN psg, UINT ch, BYTE pan) { +void psggen_setpan(PSGGEN psg, UINT ch, REG8 pan) { if ((psg) && (ch < 3)) { psg->tone[ch].pan = pan; diff --git a/sound/rhythm.h b/sound/rhythm.h index 8b908f49..4ec81186 100644 --- a/sound/rhythm.h +++ b/sound/rhythm.h @@ -39,7 +39,7 @@ void rhythm_setvol(UINT vol); void rhythm_reset(RHYTHM rhy); void rhythm_update(RHYTHM rhy); -void rhythm_setreg(RHYTHM rhy, BYTE reg, BYTE val); +void rhythm_setreg(RHYTHM rhy, REG8 reg, REG8 val); void SOUNDCALL rhythm_getpcm(RHYTHM rhy, SINT32 *pcm, UINT count); diff --git a/sound/rhythmc.c b/sound/rhythmc.c index 3000b9ef..cc48a9f0 100644 --- a/sound/rhythmc.c +++ b/sound/rhythmc.c @@ -172,10 +172,10 @@ void rhythm_update(RHYTHM rhy) { } while(++r < rterm); } -void rhythm_setreg(RHYTHM rhy, BYTE reg, BYTE value) { +void rhythm_setreg(RHYTHM rhy, REG8 reg, REG8 value) { RHYTHMCH *r; - BYTE bit; + REG8 bit; int i; if (reg == 0x10) { diff --git a/sound/s98.c b/sound/s98.c index 03c8ff5a..c6e85021 100644 --- a/sound/s98.c +++ b/sound/s98.c @@ -16,7 +16,7 @@ typedef struct { BYTE magic[3]; - BYTE formatversion; + UINT8 formatversion; BYTE timerinfo[4]; BYTE timerinfo2[4]; BYTE compressing[4]; @@ -61,7 +61,7 @@ static void S98_flush(void) { } } -static void S98_putc(BYTE data) { +static void S98_putc(REG8 data) { s98log.buf[s98log.p++] = data; if (s98log.p == S98LOG_BUFSIZE) { @@ -83,10 +83,10 @@ static void S98_putint(void) { S98_putc(0xFE); /* SYNC(n) */ s98log.intcount -= 2; while (s98log.intcount > 0x7f) { - S98_putc((BYTE)(0x80 | (s98log.intcount & 0x7f))); + S98_putc((REG8)(0x80 | (s98log.intcount & 0x7f))); s98log.intcount >>= 7; } - S98_putc((BYTE)(s98log.intcount & 0x7f)); + S98_putc((REG8)(s98log.intcount & 0x7f)); } s98log.intcount = 0; } @@ -138,11 +138,11 @@ BOOL S98_open(const char *filename) { for (i=0x30; i<0xb6; i++) { if ((i & 3) != 3) { S98_putc(NORMAL2608); - S98_putc((BYTE)i); + S98_putc((REG8)i); S98_putc(opn.reg[i]); #if 0 S98_putc(EXTEND2608); - S98_putc((BYTE)i); + S98_putc((REG8)i); S98_putc(opn.reg[i+0x100]); #endif } @@ -150,7 +150,7 @@ BOOL S98_open(const char *filename) { // PSG for (i=0x00; i<0x0e; i++) { S98_putc(NORMAL2608); - S98_putc((BYTE)i); + S98_putc((REG8)i); S98_putc(((BYTE *)&psg1.reg)[i]); } #endif @@ -174,7 +174,7 @@ void S98_close(void) { } } -void S98_put(BYTE module, BYTE addr, BYTE data) { +void S98_put(REG8 module, REG8 addr, REG8 data) { if (s98log.fh != FILEH_INVALID) { S98_putint(); diff --git a/sound/s98.h b/sound/s98.h index 29a02e2c..0a7a6b31 100644 --- a/sound/s98.h +++ b/sound/s98.h @@ -13,7 +13,7 @@ void S98_init(void); void S98_trash(void); BOOL S98_open(const char *filename); void S98_close(void); -void S98_put(BYTE module, BYTE addr, BYTE data); +void S98_put(REG8 module, REG8 addr, REG8 data); #ifdef __cplusplus } diff --git a/sound/sound.c b/sound/sound.c index b3f85814..8c1466d5 100644 --- a/sound/sound.c +++ b/sound/sound.c @@ -1,6 +1,6 @@ #include "compiler.h" #include "soundmng.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "iocore.h" #include "sound.h" @@ -126,7 +126,7 @@ void sound_reset(void) { if (sndstream.buffer) { soundmng_reset(); streamreset(); - soundcfg.lastclock = I286_CLOCK; + soundcfg.lastclock = CPU_CLOCK; beep_eventreset(); } } @@ -154,7 +154,7 @@ void sound_changeclock(void) { soundcfg.hzbase = hz; soundcfg.clockbase = clock; soundcfg.minclock = 2 * clock / hz; - soundcfg.lastclock = I286_CLOCK; + soundcfg.lastclock = CPU_CLOCK; } void sound_streamregist(void *hdl, SOUNDCB cbfn) { @@ -180,7 +180,7 @@ void sound_sync(void) { return; } - length = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK - soundcfg.lastclock; + length = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK - soundcfg.lastclock; if (length < soundcfg.minclock) { return; } @@ -217,7 +217,7 @@ const SINT32 *ret; SNDCSEC_ENTER; if (sndstream.remain > sndstream.reserve) { streamprepare(sndstream.remain - sndstream.reserve); - soundcfg.lastclock = I286_CLOCK + I286_BASECLOCK - I286_REMCLOCK; + soundcfg.lastclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK; beep_eventreset(); } } diff --git a/sound/soundrom.c b/sound/soundrom.c index 07a32fa4..2f9a736e 100644 --- a/sound/soundrom.c +++ b/sound/soundrom.c @@ -67,7 +67,7 @@ void soundrom_load(UINT32 address, const char *primary) { soundrom.address = address; } -void soundrom_loadex(BYTE sw, const char *primary) { +void soundrom_loadex(UINT sw, const char *primary) { if (sw < 4) { soundrom_load((0xc8000 + ((UINT32)sw << 14)), primary); diff --git a/sound/soundrom.h b/sound/soundrom.h index 1de7f630..bd431cc0 100644 --- a/sound/soundrom.h +++ b/sound/soundrom.h @@ -13,7 +13,7 @@ extern SOUNDROM soundrom; void soundrom_reset(void); void soundrom_load(UINT32 address, const char *primary); -void soundrom_loadex(BYTE sw, const char *primary); +void soundrom_loadex(UINT sw, const char *primary); #ifdef __cplusplus } diff --git a/sound/tms3631.h b/sound/tms3631.h index 57246cf1..0f2b9981 100644 --- a/sound/tms3631.h +++ b/sound/tms3631.h @@ -25,8 +25,8 @@ void tms3631_initialize(UINT rate); void tms3631_setvol(const BYTE *vol); void tms3631_reset(TMS3631 tms); -void tms3631_setkey(TMS3631 tms, BYTE ch, BYTE key); -void tms3631_setenable(TMS3631 tms, BYTE enable); +void tms3631_setkey(TMS3631 tms, REG8 ch, REG8 key); +void tms3631_setenable(TMS3631 tms, REG8 enable); void SOUNDCALL tms3631_getpcm(TMS3631 tms, SINT32 *pcm, UINT count); diff --git a/sound/tms3631c.c b/sound/tms3631c.c index 793a135a..83731898 100644 --- a/sound/tms3631c.c +++ b/sound/tms3631c.c @@ -60,12 +60,12 @@ void tms3631_reset(TMS3631 tms) { ZeroMemory(tms, sizeof(_TMS3631)); } -void tms3631_setkey(TMS3631 tms, BYTE ch, BYTE key) { +void tms3631_setkey(TMS3631 tms, REG8 ch, REG8 key) { tms->ch[ch & 7].freq = tms3631_freqtbl[key & 0x3f] >> tms3631cfg.ratesft; } -void tms3631_setenable(TMS3631 tms, BYTE enable) { +void tms3631_setenable(TMS3631 tms, REG8 enable) { tms->enable = enable; } diff --git a/sound/vermouth/midimod.c b/sound/vermouth/midimod.c index 20495cdb..42bddd31 100644 --- a/sound/vermouth/midimod.c +++ b/sound/vermouth/midimod.c @@ -448,6 +448,8 @@ MIDIMOD midimod_create(UINT samprate) { return(ret); mmcre_err2: + listarray_destroy(ret->namelist); + listarray_destroy(ret->pathtbl); _MFREE(ret); mmcre_err1: diff --git a/statsave.c b/statsave.c index fc6e7e55..615701d8 100644 --- a/statsave.c +++ b/statsave.c @@ -4,7 +4,7 @@ #include "scrnmng.h" #include "soundmng.h" #include "timemng.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -408,8 +408,8 @@ static int flagsave_ext(NP2FFILE f, const STENTRY *t) { ret = flagsave_create(f, t); if (ret != NP2FLAG_FAILURE) { ret |= flagsave_save(f, &extmem, sizeof(extmem)); - if (extmemmng_size) { - ret |= flagsave_save(f, extmemmng_ptr, extmemmng_size); + if (CPU_EXTMEM) { + ret |= flagsave_save(f, CPU_EXTMEM, CPU_EXTMEMSIZE); } ret |= flagsave_close(f); } @@ -429,8 +429,8 @@ static int flagload_ext(NP2FFILE f, const STENTRY *t) { } if (!extmemmng_realloc(extmem.maxmem - 1)) { pagemax = (extmem.maxmem - 1) << 8; - if (extmemmng_size) { - ret |= flagload_load(f, extmemmng_ptr, extmemmng_size); + if (CPU_EXTMEM) { + ret |= flagload_load(f, CPU_EXTMEM, CPU_EXTMEMSIZE); } } else { @@ -439,7 +439,7 @@ static int flagload_ext(NP2FFILE f, const STENTRY *t) { } for (i=0; i<4; i++) { if (extmem.page[i] < pagemax) { - extmem.pageptr[i] = extmemmng_ptr + (extmem.page[i] << 12); + extmem.pageptr[i] = CPU_EXTMEM + (extmem.page[i] << 12); } else { extmem.pageptr[i] = mem + 0xc0000 + (i << 14); diff --git a/statsave.tbl b/statsave.tbl index b975bcf9..17e22409 100644 --- a/statsave.tbl +++ b/statsave.tbl @@ -63,7 +63,7 @@ static const PROCTBL dmaproc[] = { {PROCID('d','m','e','c'), cs4231dmafunc}}; static const STENTRY np2tbl[] = { - {"CPU286", 0, NP2FLAG_CLOCK, &i286core.s, sizeof(i286core.s)}, + {"CPU286", 0, NP2FLAG_CLOCK, &CPU_STATSAVE, sizeof(CPU_STATSAVE)}, #if 1 // ver0.72 {"MEMORY", 0, NP2FLAG_MEM, NULL, 0x130000}, #else diff --git a/timing.c b/timing.c index 627214f1..9c4552e7 100644 --- a/timing.c +++ b/timing.c @@ -4,6 +4,7 @@ #include "fdd_mtr.h" #include "timing.h" + typedef struct { UINT32 tick; UINT cnt; diff --git a/update.txt b/update.txt index e548e2da..3daf2da9 100644 --- a/update.txt +++ b/update.txt @@ -6,6 +6,14 @@  これについては、直す気力があれば(286コードを追っかける時だけだし…) +// ---- + + ver0.72 + + ・主にRISC向けの最適化、その2 + ・CPU … シングルステップ割り込みの修正 + + // ----  ver0.71 → ver0.72 diff --git a/win9x/Makefile b/win9x/Makefile index befcde80..f8e5cc83 100644 --- a/win9x/Makefile +++ b/win9x/Makefile @@ -199,54 +199,55 @@ $(OBJ)/parts.oa : $(X86ASM)/parts.x86 $(OBJ)/i286c.o : $(I286C)/i286c.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/i286c.h $(I286C)/v30patch.h \ - $(I286C)/memory.h $(I286C)/dmap.h $(I286C)/i286c.mcr + $(I286C)/cpucore.h $(I286C)/i286c.h \ + $(I286C)/v30patch.h $(I286C)/memory.h \ + $(I286C)/dmap.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< $(OBJ)/i286c_mn.o : $(I286C)/i286c_mn.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/i286c.h $(I286C)/memory.h \ - $(BIOS)/bios.h $(I286C)/i286c.mcr + $(I286C)/cpucore.h $(I286C)/i286c.h \ + $(I286C)/memory.h $(BIOS)/bios.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< -$(OBJ)/i286c_ea.o : $(I286C)/i286c_ea.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/i286c_ea.o : $(I286C)/i286c_ea.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/i286c.h $(I286C)/memory.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< -$(OBJ)/i286c_0f.o : $(I286C)/i286c_0f.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/i286c_0f.o : $(I286C)/i286c_0f.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/i286c.h $(I286C)/memory.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< -$(OBJ)/i286c_8x.o : $(I286C)/i286c_8x.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/i286c_8x.o : $(I286C)/i286c_8x.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/i286c.h $(I286C)/memory.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< -$(OBJ)/i286c_sf.o : $(I286C)/i286c_sf.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/i286c_sf.o : $(I286C)/i286c_sf.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/i286c.h $(I286C)/memory.h \ $(I286C)/i286c.mcr $(I286C)/i286c_sf.mcr $(CC) $(COPT) -o $@ $< -$(OBJ)/i286c_f6.o : $(I286C)/i286c_f6.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/i286c_f6.o : $(I286C)/i286c_f6.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/i286c.h $(I286C)/memory.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< -$(OBJ)/i286c_fe.o : $(I286C)/i286c_fe.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/i286c_fe.o : $(I286C)/i286c_fe.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/i286c.h $(I286C)/memory.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< $(OBJ)/i286c_rp.o : $(I286C)/i286c_rp.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/i286c.h $(I286C)/memory.h \ - $(I286C)/i286c.mcr + $(I286C)/cpucore.h $(I286C)/i286c.h \ + $(I286C)/memory.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< $(OBJ)/v30patch.o : $(I286C)/v30patch.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/i286c.h $(I286C)/v30patch.h \ - $(I286C)/memory.h $(I286C)/dmap.h $(BIOS)/bios.h \ - $(I286C)/i286c.mcr + $(I286C)/cpucore.h $(I286C)/i286c.h \ + $(I286C)/v30patch.h $(I286C)/memory.h \ + $(I286C)/dmap.h $(BIOS)/bios.h $(I286C)/i286c.mcr $(CC) $(COPT) -o $@ $< $(OBJ)/memory.o : $(I286C)/memory.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(I286C)/egcmem.h \ - $(VRAM)/vram.h $(FONT)/font.h + $(I286C)/cpucore.h $(I286C)/memory.h \ + $(I286C)/egcmem.h $(VRAM)/vram.h $(FONT)/font.h $(CC) $(COPT) -o $@ $< $(OBJ)/egcmem.o : $(I286C)/egcmem.c $(HEADERS) $(PCCORES) $(IOCORES) \ @@ -260,12 +261,12 @@ $(OBJ)/dmap.o : $(I286C)/dmap.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(OBJ)/iocore.o : $(IO)/iocore.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(FMBOARDS) $(I286C)/i286.h $(CBUS)/cbuscore.h \ + $(FMBOARDS) $(I286C)/cpucore.h $(CBUS)/cbuscore.h \ $(SOUND)/sound.h $(CBUS)/cs4231io.h $(IO)/iocore16.tbl $(CC) $(COPT) -o $@ $< $(OBJ)/artic.o : $(IO)/artic.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h + $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/cgrom.o : $(IO)/cgrom.c $(HEADERS) $(PCCORES) $(IOCORES) \ @@ -273,7 +274,7 @@ $(OBJ)/cgrom.o : $(IO)/cgrom.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(CC) $(COPT) -o $@ $< $(OBJ)/cpuio.o : $(IO)/cpuio.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(FMBOARDS) $(I286C)/i286.h $(SOUND)/sound.h + $(FMBOARDS) $(I286C)/cpucore.h $(SOUND)/sound.h $(CC) $(COPT) -o $@ $< $(OBJ)/crtc.o : $(IO)/crtc.c $(HEADERS) $(PCCORES) $(IOCORES) \ @@ -281,8 +282,8 @@ $(OBJ)/crtc.o : $(IO)/crtc.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(CC) $(COPT) -o $@ $< $(OBJ)/dipsw.o : $(IO)/dipsw.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(TARGET)/sysmng.h $(I286C)/i286.h $(SOUND)/sound.h \ - $(SOUND)/beep.h + $(TARGET)/sysmng.h $(I286C)/cpucore.h \ + $(SOUND)/sound.h $(SOUND)/beep.h $(CC) $(COPT) -o $@ $< $(OBJ)/dmac.o : $(IO)/dmac.c $(HEADERS) $(PCCORES) $(IOCORES) \ @@ -294,7 +295,7 @@ $(OBJ)/egc.o : $(IO)/egc.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(CC) $(COPT) -o $@ $< $(OBJ)/extmem.o : $(IO)/extmem.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h + $(I286C)/cpucore.h $(I286C)/memory.h $(CC) $(COPT) -o $@ $< $(OBJ)/fdc.o : $(IO)/fdc.c $(HEADERS) $(PCCORES) $(IOCORES) \ @@ -305,7 +306,7 @@ $(OBJ)/fdd320.o : $(IO)/fdd320.c $(HEADERS) $(PCCORES) $(IOCORES) $(CC) $(COPT) -o $@ $< $(OBJ)/gdc.o : $(IO)/gdc.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(TARGET)/scrnmng.h $(I286C)/i286.h \ + $(TARGET)/scrnmng.h $(I286C)/cpucore.h \ $(I286C)/memory.h $(VRAM)/vram.h $(VRAM)/palettes.h \ $(IO)/gdc_cmd.tbl $(CC) $(COPT) -o $@ $< @@ -322,27 +323,28 @@ $(OBJ)/itf.o : $(IO)/itf.c $(HEADERS) $(PCCORES) $(IOCORES) $(CC) $(COPT) -o $@ $< $(OBJ)/mouseif.o : $(IO)/mouseif.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(TARGET)/mousemng.h $(I286C)/i286.h + $(TARGET)/mousemng.h $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/nmiio.o : $(IO)/nmiio.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h + $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/np2sysp.o : $(IO)/np2sysp.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(COMMON)/strres.h $(TARGET)/taskmng.h $(I286C)/i286.h + $(COMMON)/strres.h $(TARGET)/taskmng.h \ + $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/pic.o : $(IO)/pic.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h + $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/pit.o : $(IO)/pit.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(SOUND)/sound.h $(SOUND)/beep.h + $(I286C)/cpucore.h $(SOUND)/sound.h $(SOUND)/beep.h $(CC) $(COPT) -o $@ $< $(OBJ)/printif.o : $(IO)/printif.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h + $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/serial.o : $(IO)/serial.c $(HEADERS) $(PCCORES) $(IOCORES) \ @@ -409,7 +411,7 @@ $(OBJ)/amd98.o : $(CBUS)/amd98.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(CC) $(COPT) -o $@ $< $(OBJ)/pcm86io.o : $(CBUS)/pcm86io.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(FMBOARDS) $(I286C)/i286.h $(CBUS)/pcm86io.h \ + $(FMBOARDS) $(I286C)/cpucore.h $(CBUS)/pcm86io.h \ $(SOUND)/sound.h $(CC) $(COPT) -o $@ $< @@ -420,63 +422,64 @@ $(OBJ)/cs4231io.o : $(CBUS)/cs4231io.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(OBJ)/bios.o : $(BIOS)/bios.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(TARGET)/dosio.h $(I286C)/i286.h $(I286C)/memory.h \ - $(BIOS)/bios.h $(BIOS)/biosmem.h $(LIO)/lio.h \ - $(FDD)/fddfile.h $(FDD)/fdd_mtr.h $(BIOS)/fdfmt.h \ - $(BIOS)/keytable.res $(BIOS)/itfrom.res + $(TARGET)/dosio.h $(I286C)/cpucore.h \ + $(I286C)/memory.h $(BIOS)/bios.h $(BIOS)/biosmem.h \ + $(LIO)/lio.h $(FDD)/fddfile.h $(FDD)/fdd_mtr.h \ + $(BIOS)/fdfmt.h $(BIOS)/keytable.res \ + $(BIOS)/itfrom.res $(CC) $(COPT) -o $@ $< $(OBJ)/bios02.o : $(BIOS)/bios02.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios08.o : $(BIOS)/bios08.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios09.o : $(BIOS)/bios09.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios0c.o : $(BIOS)/bios0c.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(BIOS)/rsbios.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios12.o : $(BIOS)/bios12.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios13.o : $(BIOS)/bios13.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios18.o : $(BIOS)/bios18.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(FONT)/font.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios19.o : $(BIOS)/bios19.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(BIOS)/rsbios.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios1a.o : $(BIOS)/bios1a.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios1b.o : $(BIOS)/bios1b.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(FDD)/fddfile.h $(FDD)/fdd_mtr.h \ $(FDD)/sxsi.h $(CC) $(COPT) -o $@ $< $(OBJ)/bios1c.o : $(BIOS)/bios1c.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(TARGET)/timemng.h $(I286C)/i286.h \ + $(TARGET)/timemng.h $(I286C)/cpucore.h \ $(I286C)/memory.h $(BASE)/calendar.h \ $(BIOS)/bios.h $(BIOS)/biosmem.h $(CC) $(COPT) -o $@ $< @@ -484,7 +487,7 @@ $(OBJ)/bios1c.o : $(BIOS)/bios1c.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(OBJ)/sound.o : $(SOUND)/sound.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(TARGET)/soundmng.h $(I286C)/i286.h \ + $(TARGET)/soundmng.h $(I286C)/cpucore.h \ $(SOUND)/sound.h $(SOUND)/sndcsec.h $(SOUND)/beep.h $(CC) $(COPT) -o $@ $< @@ -494,12 +497,12 @@ $(OBJ)/sndcsec.o : $(SOUND)/sndcsec.c $(HEADERS) $(SOUND)/sound.h \ $(OBJ)/fmboard.o : $(SOUND)/fmboard.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(FMBOARDS) $(TARGET)/joymng.h $(TARGET)/soundmng.h \ - $(I286C)/i286.h $(CBUS)/cbuscore.h $(CBUS)/board14.h \ - $(CBUS)/board26k.h $(CBUS)/board86.h \ - $(CBUS)/boardx2.h $(CBUS)/board118.h \ - $(CBUS)/boardspb.h $(CBUS)/amd98.h $(CBUS)/pcm86io.h \ - $(CBUS)/cs4231io.h $(SOUND)/sound.h $(SOUND)/beep.h \ - $(GENERIC)/keydisp.h + $(I286C)/cpucore.h $(CBUS)/cbuscore.h \ + $(CBUS)/board14.h $(CBUS)/board26k.h \ + $(CBUS)/board86.h $(CBUS)/boardx2.h \ + $(CBUS)/board118.h $(CBUS)/boardspb.h \ + $(CBUS)/amd98.h $(CBUS)/pcm86io.h $(CBUS)/cs4231io.h \ + $(SOUND)/sound.h $(SOUND)/beep.h $(GENERIC)/keydisp.h $(CC) $(COPT) -o $@ $< $(OBJ)/fmtimer.o : $(SOUND)/fmtimer.c $(HEADERS) $(PCCORES) $(IOCORES) \ @@ -558,7 +561,7 @@ $(OBJ)/adpcmg.o : $(SOUND)/adpcmg.c $(HEADERS) $(SOUND)/sound.h \ $(CC) $(COPT) -o $@ $< $(OBJ)/pcm86c.o : $(SOUND)/pcm86c.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(FMBOARDS) $(I286C)/i286.h $(SOUND)/sound.h + $(FMBOARDS) $(I286C)/cpucore.h $(SOUND)/sound.h $(CC) $(COPT) -o $@ $< $(OBJ)/pcm86g.o : $(SOUND)/pcm86g.c $(HEADERS) $(PCCORES) $(IOCORES) \ @@ -684,45 +687,45 @@ $(OBJ)/fdd_mtr.o : $(FDD)/fdd_mtr.c $(HEADERS) $(PCCORES) \ $(CC) $(COPT) -o $@ $< $(OBJ)/sxsi.o : $(FDD)/sxsi.c $(HEADERS) $(PCCORES) \ - $(TARGET)/sysmng.h $(I286C)/i286.h $(FDD)/sxsi.h + $(TARGET)/sysmng.h $(I286C)/cpucore.h $(FDD)/sxsi.h $(CC) $(COPT) -o $@ $< $(OBJ)/lio.o : $(LIO)/lio.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h \ + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h \ $(BIOS)/biosmem.h $(VRAM)/vram.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< $(OBJ)/gscreen.o : $(LIO)/gscreen.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(LIO)/lio.h + $(I286C)/cpucore.h $(I286C)/memory.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< $(OBJ)/gview.o : $(LIO)/gview.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(LIO)/lio.h + $(I286C)/cpucore.h $(I286C)/memory.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< $(OBJ)/gcolor1.o : $(LIO)/gcolor1.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(LIO)/lio.h + $(I286C)/cpucore.h $(I286C)/memory.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< $(OBJ)/gcolor2.o : $(LIO)/gcolor2.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(I286C)/i286.h $(I286C)/memory.h $(LIO)/lio.h + $(I286C)/cpucore.h $(I286C)/memory.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< -$(OBJ)/gcls.o : $(LIO)/gcls.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/gcls.o : $(LIO)/gcls.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/memory.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< -$(OBJ)/gpset.o : $(LIO)/gpset.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/gpset.o : $(LIO)/gpset.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/memory.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< -$(OBJ)/gline.o : $(LIO)/gline.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/gline.o : $(LIO)/gline.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/memory.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< -$(OBJ)/gput1.o : $(LIO)/gput1.c $(HEADERS) $(I286C)/i286.h \ +$(OBJ)/gput1.o : $(LIO)/gput1.c $(HEADERS) $(I286C)/cpucore.h \ $(I286C)/memory.h $(LIO)/lio.h $(CC) $(COPT) -o $@ $< @@ -875,7 +878,7 @@ $(OBJ)/soundmng.o : $(TARGET)/soundmng.cpp $(HEADERS) $(COMMON)/parts.h \ $(OBJ)/sysmng.o : $(TARGET)/sysmng.cpp $(HEADERS) $(PCCORES) \ $(TARGET)/np2.h $(TARGET)/dosio.h $(TARGET)/sysmng.h \ - $(I286C)/i286.h $(FDD)/fddfile.h + $(I286C)/cpucore.h $(FDD)/fddfile.h $(CC) $(COPT) -o $@ $< $(OBJ)/taskmng.o : $(TARGET)/taskmng.cpp $(HEADERS) $(TARGET)/taskmng.h @@ -923,7 +926,7 @@ $(OBJ)/ini.o : $(TARGET)/ini.cpp $(HEADERS) $(PCCORES) \ $(OBJ)/np2info.o : $(TARGET)/np2info.cpp $(HEADERS) $(PCCORES) \ $(IOCORES) $(FMBOARDS) $(COMMON)/strres.h \ $(TARGET)/np2.h $(TARGET)/scrnmng.h \ - $(TARGET)/np2info.h $(I286C)/i286.h \ + $(TARGET)/np2info.h $(I286C)/cpucore.h \ $(I286C)/memory.h $(BIOS)/bios.h $(CC) $(COPT) -o $@ $< @@ -1029,7 +1032,7 @@ $(OBJ)/dialogs.o : $(DIALOG)/dialogs.cpp $(HEADERS) $(COMMON)/strres.h \ $(OBJ)/viewer.o : $(DEBUGUTY)/viewer.cpp $(HEADERS) \ $(TARGET)/resource.h $(TARGET)/np2.h \ $(DEBUGUTY)/viewer.h $(DEBUGUTY)/viewcmn.h \ - $(I286C)/i286.h + $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/viewcmn.o : $(DEBUGUTY)/viewcmn.cpp $(HEADERS) $(PCCORES) \ @@ -1038,7 +1041,7 @@ $(OBJ)/viewcmn.o : $(DEBUGUTY)/viewcmn.cpp $(HEADERS) $(PCCORES) \ $(DEBUGUTY)/viewmem.h $(DEBUGUTY)/viewreg.h \ $(DEBUGUTY)/viewseg.h $(DEBUGUTY)/view1mb.h \ $(DEBUGUTY)/viewasm.h $(DEBUGUTY)/viewsnd.h \ - $(I286C)/i286.h $(I286C)/memory.h $(BIOS)/bios.h + $(I286C)/cpucore.h $(I286C)/memory.h $(BIOS)/bios.h $(CC) $(COPT) -o $@ $< $(OBJ)/viewmenu.o : $(DEBUGUTY)/viewmenu.cpp $(HEADERS) \ @@ -1056,28 +1059,28 @@ $(OBJ)/viewreg.o : $(DEBUGUTY)/viewreg.cpp $(HEADERS) \ $(TARGET)/resource.h $(TARGET)/np2.h \ $(DEBUGUTY)/viewer.h $(DEBUGUTY)/viewcmn.h \ $(DEBUGUTY)/viewmenu.h $(DEBUGUTY)/viewmem.h \ - $(DEBUGUTY)/viewreg.h $(I286C)/i286.h + $(DEBUGUTY)/viewreg.h $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/viewseg.o : $(DEBUGUTY)/viewseg.cpp $(HEADERS) \ $(TARGET)/resource.h $(TARGET)/np2.h \ $(DEBUGUTY)/viewer.h $(DEBUGUTY)/viewcmn.h \ $(DEBUGUTY)/viewmenu.h $(DEBUGUTY)/viewmem.h \ - $(DEBUGUTY)/viewseg.h $(I286C)/i286.h + $(DEBUGUTY)/viewseg.h $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/view1mb.o : $(DEBUGUTY)/view1mb.cpp $(HEADERS) \ $(TARGET)/resource.h $(TARGET)/np2.h \ $(DEBUGUTY)/viewer.h $(DEBUGUTY)/viewcmn.h \ $(DEBUGUTY)/viewmenu.h $(DEBUGUTY)/viewmem.h \ - $(DEBUGUTY)/view1mb.h $(I286C)/i286.h + $(DEBUGUTY)/view1mb.h $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/viewasm.o : $(DEBUGUTY)/viewasm.cpp $(HEADERS) \ $(TARGET)/resource.h $(TARGET)/np2.h \ $(DEBUGUTY)/viewer.h $(DEBUGUTY)/viewcmn.h \ $(DEBUGUTY)/viewmenu.h $(DEBUGUTY)/viewmem.h \ - $(DEBUGUTY)/viewsnd.h $(I286C)/i286.h + $(DEBUGUTY)/viewsnd.h $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/viewsnd.o : $(DEBUGUTY)/viewsnd.cpp $(HEADERS) $(PCCORES) \ @@ -1095,7 +1098,7 @@ $(OBJ)/unasm.o : $(DEBUGUTY)/unasm.cpp $(HEADER) $(DEBUGUTY)/unasm.h $(OBJ)/pccore.o : $(BASE)/pccore.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(TARGET)/soundmng.h $(TARGET)/sysmng.h \ - $(TARGET)/timemng.h $(I286C)/i286.h \ + $(TARGET)/timemng.h $(I286C)/cpucore.h \ $(I286C)/memory.h $(CBUS)/cbuscore.h \ $(CBUS)/pc9861k.h $(CBUS)/mpu98ii.h $(BIOS)/bios.h \ $(VRAM)/vram.h $(VRAM)/scrndraw.h $(VRAM)/dispsync.h \ @@ -1107,7 +1110,8 @@ $(OBJ)/pccore.o : $(BASE)/pccore.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(BASE)/timing.h $(CC) $(COPT) -o $@ $< -$(OBJ)/nevent.o : $(BASE)/nevent.c $(HEADERS) $(PCCORES) $(I286C)/i286.h +$(OBJ)/nevent.o : $(BASE)/nevent.c $(HEADERS) $(PCCORES) \ + $(I286C)/cpucore.h $(CC) $(COPT) -o $@ $< $(OBJ)/calendar.o : $(BASE)/calendar.c $(HEADERS) $(PCCORES) \ @@ -1122,7 +1126,7 @@ $(OBJ)/timing.o : $(BASE)/timing.c $(HEADERS) $(PCCORES) \ $(OBJ)/statsave.o : $(BASE)/statsave.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(TARGET)/dosio.h $(TARGET)/commng.h \ $(TARGET)/scrnmng.h $(TARGET)/soundmng.h \ - $(TARGET)/timemng.h $(I286C)/i286.h \ + $(TARGET)/timemng.h $(I286C)/cpucore.h \ $(I286C)/memory.h $(CBUS)/cbuscore.h \ $(CBUS)/pc9861k.h $(CBUS)/mpu98ii.h \ $(CBUS)/board14.h $(BIOS)/bios.h $(VRAM)/vram.h \ @@ -1134,8 +1138,9 @@ $(OBJ)/statsave.o : $(BASE)/statsave.c $(HEADERS) $(PCCORES) $(IOCORES) \ $(CC) $(COPT) -o $@ $< $(OBJ)/debugsub.o : $(BASE)/debugsub.c $(HEADERS) $(PCCORES) $(IOCORES) \ - $(COMMON)/strres.h $(TARGET)/dosio.h $(I286C)/i286.h \ - $(I286C)/memory.h $(BASE)/debugsub.h + $(COMMON)/strres.h $(TARGET)/dosio.h \ + $(I286C)/cpucore.h $(I286C)/memory.h \ + $(BASE)/debugsub.h $(CC) $(COPT) -o $@ $< diff --git a/win9x/debuguty/view1mb.cpp b/win9x/debuguty/view1mb.cpp index ec9c7bd8..72edde63 100644 --- a/win9x/debuguty/view1mb.cpp +++ b/win9x/debuguty/view1mb.cpp @@ -6,7 +6,7 @@ #include "viewmenu.h" #include "viewmem.h" #include "view1mb.h" -#include "i286.h" +#include "cpucore.h" static void set_viewseg(HWND hwnd, NP2VIEW_T *view, WORD seg) { @@ -86,19 +86,19 @@ LRESULT CALLBACK view1mb_proc(NP2VIEW_T *view, case WM_COMMAND: switch(LOWORD(wp)) { case IDM_SEGCS: - set_viewseg(hwnd, view, I286_CS); + set_viewseg(hwnd, view, CPU_CS); break; case IDM_SEGDS: - set_viewseg(hwnd, view, I286_DS); + set_viewseg(hwnd, view, CPU_DS); break; case IDM_SEGES: - set_viewseg(hwnd, view, I286_ES); + set_viewseg(hwnd, view, CPU_ES); break; case IDM_SEGSS: - set_viewseg(hwnd, view, I286_SS); + set_viewseg(hwnd, view, CPU_SS); break; case IDM_SEGTEXT: diff --git a/win9x/debuguty/viewasm.cpp b/win9x/debuguty/viewasm.cpp index 0c52a4de..97007457 100644 --- a/win9x/debuguty/viewasm.cpp +++ b/win9x/debuguty/viewasm.cpp @@ -7,7 +7,7 @@ #include "viewmem.h" #include "viewasm.h" #include "unasm.h" -#include "i286.h" +#include "cpucore.h" static void set_viewseg(HWND hwnd, NP2VIEW_T *view, WORD seg) { @@ -147,19 +147,19 @@ LRESULT CALLBACK viewasm_proc(NP2VIEW_T *view, case WM_COMMAND: switch(LOWORD(wp)) { case IDM_SEGCS: - set_viewseg(hwnd, view, I286_CS); + set_viewseg(hwnd, view, CPU_CS); break; case IDM_SEGDS: - set_viewseg(hwnd, view, I286_DS); + set_viewseg(hwnd, view, CPU_DS); break; case IDM_SEGES: - set_viewseg(hwnd, view, I286_ES); + set_viewseg(hwnd, view, CPU_ES); break; case IDM_SEGSS: - set_viewseg(hwnd, view, I286_SS); + set_viewseg(hwnd, view, CPU_SS); break; case IDM_SEGTEXT: @@ -215,8 +215,8 @@ void viewasm_init(NP2VIEW_T *dst, NP2VIEW_T *src) { } } if (!src) { - dst->seg = I286_CS; - dst->off = I286_IP; + dst->seg = CPU_CS; + dst->off = CPU_IP; } dst->type = VIEWMODE_ASM; dst->maxline = 256; diff --git a/win9x/debuguty/viewcmn.cpp b/win9x/debuguty/viewcmn.cpp index 3a006619..b7e2e17f 100644 --- a/win9x/debuguty/viewcmn.cpp +++ b/win9x/debuguty/viewcmn.cpp @@ -10,7 +10,7 @@ #include "view1mb.h" #include "viewasm.h" #include "viewsnd.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -156,8 +156,8 @@ void viewcmn_setbank(NP2VIEW_T *view) { dmem = &view->dmem; dmem->vram = gdcs.disp; - dmem->itf = i286core.s.itfbank; - dmem->A20 = (BYTE)((i286core.s.adrsmask >> 20) & 1); + dmem->itf = CPU_ITFBANK; + dmem->A20 = (BYTE)((CPU_ADRSMASK >> 20) & 1); } @@ -184,10 +184,10 @@ void viewcmn_setmenuseg(HWND hwnd) { hmenu = GetSubMenu(hparent, 2); if (hmenu) { - modmenu(hmenu, 2, IDM_SEGCS, "CS", I286_CS); - modmenu(hmenu, 3, IDM_SEGDS, "DS", I286_DS); - modmenu(hmenu, 4, IDM_SEGES, "ES", I286_ES); - modmenu(hmenu, 5, IDM_SEGSS, "SS", I286_SS); + modmenu(hmenu, 2, IDM_SEGCS, "CS", CPU_CS); + modmenu(hmenu, 3, IDM_SEGDS, "DS", CPU_DS); + modmenu(hmenu, 4, IDM_SEGES, "ES", CPU_ES); + modmenu(hmenu, 5, IDM_SEGSS, "SS", CPU_SS); DrawMenuBar(hwnd); } } diff --git a/win9x/debuguty/viewer.cpp b/win9x/debuguty/viewer.cpp index f66dee9d..c8bd9a9f 100644 --- a/win9x/debuguty/viewer.cpp +++ b/win9x/debuguty/viewer.cpp @@ -3,7 +3,7 @@ #include "np2.h" #include "viewer.h" #include "viewcmn.h" -#include "i286.h" +#include "cpucore.h" static char np2viewclass[] = "NP2-ViewWindow"; @@ -275,8 +275,8 @@ static DWORD last = 0; for (i=0; ialive) && (!view->lock)) { if (view->type == VIEWMODE_ASM) { - view->seg = I286_CS; - view->off = I286_IP; + view->seg = CPU_CS; + view->off = CPU_IP; view->pos = 0; viewcmn_setvscroll(view->hwnd, view); } diff --git a/win9x/debuguty/viewreg.cpp b/win9x/debuguty/viewreg.cpp index c03f5662..5fe1efde 100644 --- a/win9x/debuguty/viewreg.cpp +++ b/win9x/debuguty/viewreg.cpp @@ -7,7 +7,7 @@ #include "viewmenu.h" #include "viewmem.h" #include "viewreg.h" -#include "i286.h" +#include "cpucore.h" static void viewreg_paint(NP2VIEW_T *view, RECT *rc, HDC hdc) { diff --git a/win9x/debuguty/viewseg.cpp b/win9x/debuguty/viewseg.cpp index 2ab54784..cbfe617e 100644 --- a/win9x/debuguty/viewseg.cpp +++ b/win9x/debuguty/viewseg.cpp @@ -6,7 +6,7 @@ #include "viewmenu.h" #include "viewmem.h" #include "viewseg.h" -#include "i286.h" +#include "cpucore.h" static void set_viewseg(HWND hwnd, NP2VIEW_T *view, WORD seg) { @@ -87,19 +87,19 @@ LRESULT CALLBACK viewseg_proc(NP2VIEW_T *view, case WM_COMMAND: switch(LOWORD(wp)) { case IDM_SEGCS: - set_viewseg(hwnd, view, I286_CS); + set_viewseg(hwnd, view, CPU_CS); break; case IDM_SEGDS: - set_viewseg(hwnd, view, I286_DS); + set_viewseg(hwnd, view, CPU_DS); break; case IDM_SEGES: - set_viewseg(hwnd, view, I286_ES); + set_viewseg(hwnd, view, CPU_ES); break; case IDM_SEGSS: - set_viewseg(hwnd, view, I286_SS); + set_viewseg(hwnd, view, CPU_SS); break; case IDM_SEGTEXT: diff --git a/win9x/np2info.cpp b/win9x/np2info.cpp index f39280fc..e3aa0bb5 100644 --- a/win9x/np2info.cpp +++ b/win9x/np2info.cpp @@ -3,7 +3,7 @@ #include "np2.h" #include "scrnmng.h" #include "np2info.h" -#include "i286.h" +#include "cpucore.h" #include "memory.h" #include "pccore.h" #include "iocore.h" @@ -69,7 +69,7 @@ static void info_ver(char *str, int maxlen) { static void info_cpu(char *str, int maxlen) { - milstr_ncpy(str, (CPUTYPE & CPUTYPE_V30)?str_V30:str_i286, maxlen); + milstr_ncpy(str, (CPU_TYPE & CPUTYPE_V30)?str_V30:str_i286, maxlen); } static void info_clock(char *str, int maxlen) { diff --git a/win9x/sysmng.cpp b/win9x/sysmng.cpp index b0d3726a..ce1ddb16 100644 --- a/win9x/sysmng.cpp +++ b/win9x/sysmng.cpp @@ -2,7 +2,7 @@ #include "np2.h" #include "dosio.h" #include "sysmng.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "fddfile.h" #if 0 @@ -29,7 +29,7 @@ static struct { void sysmng_workclockreset(void) { workclock.tick = GETTICK(); - workclock.clock = I286_CLOCK; + workclock.clock = CPU_CLOCK; workclock.draws = drawcount; } @@ -44,8 +44,8 @@ BOOL sysmng_workclockrenewal(void) { workclock.tick += tick; workclock.fps = ((drawcount - workclock.draws) * 10000) / tick; workclock.draws = drawcount; - workclock.khz = (I286_CLOCK - workclock.clock) / tick; - workclock.clock = I286_CLOCK; + workclock.khz = (CPU_CLOCK - workclock.clock) / tick; + workclock.clock = CPU_CLOCK; return(TRUE); } diff --git a/win9x/x86/np2asm.inc b/win9x/x86/np2asm.inc index bbb7950c..5380b767 100644 --- a/win9x/x86/np2asm.inc +++ b/win9x/x86/np2asm.inc @@ -47,7 +47,7 @@ SCRN_BUFSIZE equ 04b000h GDCCMD_MAX equ 32 - struc i286stat_t + struc i286core_t .reg resw 14 .remainclock resd 1 .baseclock resd 1 @@ -71,6 +71,8 @@ GDCCMD_MAX equ 32 .MSW resw 1 .resetreq resb 1 .itfbank resb 1 +.ext resd 1 +.extsize resd 1 endstruc struc gdcd_t diff --git a/win9xc/compiler.h b/win9xc/compiler.h index 2bb46f36..26d1e24b 100644 --- a/win9xc/compiler.h +++ b/win9xc/compiler.h @@ -1,18 +1,33 @@ #include #include #include +#include #define BYTESEX_LITTLE #define OSLANG_SJIS #define OSLINEBREAK_CRLF +#ifndef __GNUC__ typedef signed char SINT8; typedef unsigned char UINT8; typedef signed short SINT16; typedef unsigned short UINT16; typedef signed int SINT32; typedef unsigned int UINT32; +#else +#include +typedef signed char SINT8; +typedef unsigned char UINT8; +typedef short SINT16; +typedef unsigned short UINT16; +typedef int SINT32; +#endif + +// for RISC test +#define REG8 UINT +#define REG16 UINT + #include "common.h" #include "milstr.h" @@ -50,3 +65,5 @@ typedef unsigned int UINT32; #define SOUNDRESERVE 20 +#define FASTCALL __fastcall + diff --git a/win9xc/joymng.cpp b/win9xc/joymng.cpp index 8f8bc13f..f05ec2f8 100644 --- a/win9xc/joymng.cpp +++ b/win9xc/joymng.cpp @@ -5,7 +5,6 @@ #include "pccore.h" -static int joyactive = 0; static BYTE joyflag = 0xff; #define JOY_LEFT_BIT 0x04 diff --git a/win9xc/np2.cpp b/win9xc/np2.cpp index 588b8d93..585cefb7 100644 --- a/win9xc/np2.cpp +++ b/win9xc/np2.cpp @@ -1,6 +1,8 @@ #include "compiler.h" #include +#ifndef __GNUC__ #include +#endif #include "strres.h" #include "parts.h" #include "resource.h" @@ -45,7 +47,7 @@ #define STATSAVEMAX 10 static char np2help[] = "np2.hlp"; -static char np2resume[] = "sav"; +// static char np2resume[] = "sav"; static const char szAppCaption[] = "Neko Project II - C version"; static const char szClassName[] = "NP2-MainWindow"; @@ -133,8 +135,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CREATE: +#ifndef __GNUC__ WINNLSEnableIME(hWnd, FALSE); -// DragAcceptFiles(hWnd, TRUE); +#endif break; case WM_SYSCOMMAND: diff --git a/win9xc/scrnmng.cpp b/win9xc/scrnmng.cpp index 29ada14b..55a90d44 100644 --- a/win9xc/scrnmng.cpp +++ b/win9xc/scrnmng.cpp @@ -1,6 +1,8 @@ #include "compiler.h" #include +#ifndef __GNUC__ #include +#endif #include "resource.h" #include "np2.h" #include "mousemng.h" @@ -508,14 +510,18 @@ void scrnmng_topwinui(void) { if (scrnmng.flag & SCRNFLAG_FULLSCREEN) { ddraw.primsurf->SetClipper(ddraw.clipper); } +#ifndef __GNUC__ WINNLSEnableIME(hWndMain, TRUE); +#endif } } void scrnmng_clearwinui(void) { if ((ddraw.cliping > 0) && (!(--ddraw.cliping))) { +#ifndef __GNUC__ WINNLSEnableIME(hWndMain, FALSE); +#endif if (scrnmng.flag & SCRNFLAG_FULLSCREEN) { ddraw.primsurf->SetClipper(0); } diff --git a/win9xc/sysmng.cpp b/win9xc/sysmng.cpp index e0197547..3de88bd8 100644 --- a/win9xc/sysmng.cpp +++ b/win9xc/sysmng.cpp @@ -1,7 +1,7 @@ #include "compiler.h" #include "np2.h" #include "sysmng.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" @@ -21,7 +21,7 @@ static struct { void sysmng_workclockreset(void) { workclock.tick = GETTICK(); - workclock.clock = I286_CLOCK; + workclock.clock = CPU_CLOCK; workclock.draws = drawcount; } @@ -36,8 +36,8 @@ static BOOL workclockrenewal(void) { workclock.tick += tick; workclock.fps = ((drawcount - workclock.draws) * 10000) / tick; workclock.draws = drawcount; - workclock.khz = (I286_CLOCK - workclock.clock) / tick; - workclock.clock = I286_CLOCK; + workclock.khz = (CPU_CLOCK - workclock.clock) / tick; + workclock.clock = CPU_CLOCK; return(TRUE); } diff --git a/win9xc/trace.h b/win9xc/trace.h index 24ceaf13..cc8d03c6 100644 --- a/win9xc/trace.h +++ b/win9xc/trace.h @@ -4,6 +4,7 @@ #define TRACEINIT() #define TRACETERM() #define TRACEOUT(a) +#define VERBOSE(a) #else @@ -22,6 +23,7 @@ extern void trace_fmt(const char *str, ...); #define TRACEINIT() trace_init() #define TRACETERM() trace_term() #define TRACEOUT(arg) trace_fmt arg +#define VERBOSE(arg) trace_fmt arg #endif diff --git a/wince/w32/compiler.h b/wince/w32/compiler.h index d5aa8f16..4973a6d3 100644 --- a/wince/w32/compiler.h +++ b/wince/w32/compiler.h @@ -24,7 +24,6 @@ typedef unsigned int UINT32; // for RISC test #define REG8 UINT #define REG16 UINT -#define REG32 UINT #define LOW12(a) ((((UINT)(a)) << 20) >> 20) #define LOW14(a) ((((UINT)(a)) << 18) >> 18) #define LOW15(a) ((((UINT)(a)) << 17) >> 17) diff --git a/wince/wce/compiler.h b/wince/wce/compiler.h index e44a2a7e..23d99dd1 100644 --- a/wince/wce/compiler.h +++ b/wince/wce/compiler.h @@ -31,7 +31,6 @@ typedef signed int SINT32; // for ARM optimize #define REG8 UINT #define REG16 UINT -#define REG32 UINT #define LOW12(a) ((((UINT)(a)) << 20) >> 20) #define LOW14(a) ((((UINT)(a)) << 18) >> 18) #define LOW15(a) ((((UINT)(a)) << 17) >> 17) diff --git a/x11/sysmng.c b/x11/sysmng.c index 29b7a089..739a0b0d 100644 --- a/x11/sysmng.c +++ b/x11/sysmng.c @@ -3,7 +3,7 @@ #include "np2.h" #include "dosio.h" #include "fddfile.h" -#include "i286.h" +#include "cpucore.h" #include "pccore.h" #include "sysmng.h" #include "toolkit.h" @@ -26,7 +26,7 @@ sysmng_workclockreset(void) { workclock.tick = GETTICK(); - workclock.clock = I286_CLOCK; + workclock.clock = CPU_CLOCK; workclock.draws = drawcount; workclock.fps = 0; workclock.khz = 0; @@ -41,8 +41,8 @@ sysmng_workclockrenewal(void) workclock.tick += tick; workclock.fps = ((drawcount - workclock.draws) * 10000) / tick; workclock.draws = drawcount; - workclock.khz = (I286_CLOCK - workclock.clock) / tick; - workclock.clock = I286_CLOCK; + workclock.khz = (CPU_CLOCK - workclock.clock) / tick; + workclock.clock = CPU_CLOCK; return TRUE; } return FALSE;