--- np2/i286x/v30patch.cpp 2003/10/17 07:17:20 1.2 +++ np2/i286x/v30patch.cpp 2005/02/08 09:57:26 1.9 @@ -1,23 +1,28 @@ #include "compiler.h" -#include "i286.h" +#include "cpucore.h" #include "i286x.h" #include "i286xadr.h" #include "i286xs.h" #include "i286xrep.h" #include "i286xcts.h" -#include "memory.h" #include "pccore.h" #include "bios.h" #include "iocore.h" #include "i286x.mcr" #include "i286xea.mcr" -#include "dmap.h" +#include "dmax86.h" typedef struct { - DWORD opnum; - void (*v30opcode)(void); -} V30PATCH_T; + UINT opnum; + I286TBL v30opcode; +} V30PATCH; + +static I286TBL v30op[256]; +static I286TBL v30op_repne[256]; +static I286TBL v30op_repe[256]; +static I286TBL v30ope0xf6_xtable[8]; +static I286TBL v30ope0xf7_xtable[8]; static const BYTE shiftbase16[256] = @@ -94,7 +99,7 @@ I286 v30pop_ss(void) { // 17: pop shl eax, 4 // make segreg mov SS_BASE, eax mov SS_FIX, eax - cmp i286reg.prefix, 0 // 00/06/24 + cmp i286core.s.prefix, 0 // 00/06/24 je noprefix call removeprefix pop eax @@ -204,7 +209,7 @@ I286 v30mov_seg_ea(void) { // 8E: m segsetr:ret align 4 - setss: cmp i286reg.prefix, 0 // 00/05/13 + setss: cmp i286core.s.prefix, 0 // 00/05/13 je noprefix pop eax call eax // eax<-offset removeprefix @@ -793,8 +798,164 @@ I286 v30_repe(void) { // F3: repe } } +I286 v30div_ea8(void) { // F6-6: div ea8 -static V30PATCH_T v30patch_op[] = { + __asm { + PREPART_EA8(14) + movzx ebp, byte ptr I286_REG[eax] + GET_NEXTPRE2 + jmp divcheck + MEMORY_EA8(17) + movzx ebp, byte ptr I286_MEM[ecx] + jmp divcheck + EXTMEM_EA8 + movzx ebp, al + + align 4 + divcheck: test ebp, ebp + je divovf + mov ax, I286_AX + xor dx, dx + div bp + mov I286_AL, al + mov I286_AH, dl + mov dx, ax + FLAG_STORE_OF + test dh, dh + jne divovf + ret + + align 4 + divovf: INT_NUM(0) + } +} + +I286 v30idiv_ea8(void) { // F6-7 idiv ea8 + + __asm { + PREPART_EA8(17) + movsx ebp, byte ptr I286_REG[eax] + GET_NEXTPRE2 + jmp idivcheck + MEMORY_EA8(20) + movsx ebp, byte ptr I286_MEM[ecx] + jmp idivcheck + EXTMEM_EA8 + movsx ebp, al + + align 4 + idivcheck: test ebp, ebp + je idivovf + mov ax, I286_AX + cwd + idiv bp + mov I286_AL, al + mov I286_AH, dl + mov dx, ax + FLAG_STORE_OF + bt dx, 7 + adc dh, 0 + jne idivovf + ret + + align 4 + idivovf: INT_NUM(0) + } +} + +I286 v30_ope0xf6(void) { // F6: + + __asm { + movzx eax, bh + mov edi, eax + shr edi, 3-2 + and edi, 7*4 + jmp v30ope0xf6_xtable[edi] + } +} + +I286 v30div_ea16(void) { // F7-6: div ea16 + + __asm { + PREPART_EA16(22) + movzx ebp, word ptr I286_REG[eax*2] + GET_NEXTPRE2 + jmp divcheck + MEMORY_EA16(25) + movzx ebp, word ptr I286_MEM[ecx] + jmp divcheck + EXTMEM_EA16 + movzx ebp, ax + + align 4 + divcheck: test ebp, ebp + je divovf + movzx eax, I286_DX + shl eax, 16 + mov ax, I286_AX + xor edx, edx + div ebp + mov I286_AX, ax + mov I286_DX, dx + FLAG_STORE_OF + cmp eax, 10000h + jae divovf + ret + + align 4 + divovf: INT_NUM(0) + } +} + +I286 v30idiv_ea16(void) { // F7-7: idiv ea16 + + __asm { + PREPART_EA16(25) + movsx ebp, word ptr I286_REG[eax*2] + GET_NEXTPRE2 + jmp idivcheck + MEMORY_EA16(28) + movsx ebp, word ptr I286_MEM[ecx] + jmp idivcheck + EXTMEM_EA16 + cwde + mov ebp, eax + + align 4 + idivcheck: test ebp, ebp + je idivovf + movzx eax, I286_DX + shl eax, 16 + mov ax, I286_AX + cdq + idiv ebp + mov I286_AX, ax + mov I286_DX, dx + mov edx, eax + FLAG_STORE_OF + shr edx, 16 + adc dx, 0 + jne idivovf + ret + + align 4 + idivovf: INT_NUM(0) + } +} + +I286 v30_ope0xf7(void) { // F7: + + __asm { + movzx eax, bh + mov edi, eax + shr edi, 3-2 + and edi, 7*4 + jmp v30ope0xf7_xtable[edi] + } +} + + +static const V30PATCH v30patch_op[] = { {0x17, v30pop_ss}, // 17: pop ss {0x26, v30segprefix_es}, // 26: es: {0x2e, v30segprefix_cs}, // 2E: cs: @@ -818,8 +979,10 @@ static V30PATCH_T v30patch_op[] = { {0xd5, v30_aad}, // D5: AAD {0xd6, v30_xlat}, // D6: xlat (8086/V30) {0xf2, v30_repne}, // F2: repne - {0xf3, v30_repe} // F3: repe -}; + {0xf3, v30_repe}, // F3: repe + {0xf6, v30_ope0xf6}, // F6: + {0xf7, v30_ope0xf7}}; // F7: + // ----------------------------------------------------------------- repe @@ -872,7 +1035,7 @@ I286 v30repe_segprefix_ds(void) { } -static V30PATCH_T v30patch_repe[] = { +static const V30PATCH v30patch_repe[] = { {0x17, v30pop_ss}, // 17: pop ss {0x26, v30repe_segprefix_es}, // 26: repe es: {0x2e, v30repe_segprefix_cs}, // 2E: repe cs: @@ -896,8 +1059,10 @@ static V30PATCH_T v30patch_repe[] = { {0xd5, v30_aad}, // D5: AAD {0xd6, v30_xlat}, // D6: xlat (8086/V30) {0xf2, v30_repne}, // F2: repne - {0xf3, v30_repe} // F3: repe -}; + {0xf3, v30_repe}, // F3: repe + {0xf6, v30_ope0xf6}, // F6: + {0xf7, v30_ope0xf7}}; // F7: + // ----------------------------------------------------------------- repne @@ -949,7 +1114,7 @@ I286 v30repne_segprefix_ds(void) { } } -static V30PATCH_T v30patch_repne[] = { +static const V30PATCH v30patch_repne[] = { {0x17, v30pop_ss}, // 17: pop ss {0x26, v30repne_segprefix_es}, // 26: repne es: {0x2e, v30repne_segprefix_cs}, // 2E: repne cs: @@ -973,16 +1138,14 @@ static V30PATCH_T v30patch_repne[] = { {0xd5, v30_aad}, // D5: AAD {0xd6, v30_xlat}, // D6: xlat (8086/V30) {0xf2, v30_repne}, // F2: repne - {0xf3, v30_repe} // F3: repe -}; + {0xf3, v30_repe}, // F3: repe + {0xf6, v30_ope0xf6}, // F6: + {0xf7, v30_ope0xf7}}; // F7: -// --------------------------------------------------------------------------- -void (*v30op[256])(void); -void (*v30op_repne[256])(void); -void (*v30op_repe[256])(void); +// --------------------------------------------------------------------------- -static void v30patching(void (*dst[])(void), V30PATCH_T *patch, int length) { +static void v30patching(I286TBL *dst, const V30PATCH *patch, int length) { while(length--) { dst[patch->opnum] = patch->v30opcode; @@ -990,9 +1153,9 @@ static void v30patching(void (*dst[])(vo } } -#define V30PATCHING(a, b) v30patching(a, b, sizeof(b)/sizeof(V30PATCH_T)) +#define V30PATCHING(a, b) v30patching(a, b, sizeof(b)/sizeof(V30PATCH)) -void v30init(void) { +void v30xinit(void) { CopyMemory(v30op, i286op, sizeof(v30op)); V30PATCHING(v30op, v30patch_op); @@ -1000,13 +1163,19 @@ void v30init(void) { V30PATCHING(v30op_repne, v30patch_repne); CopyMemory(v30op_repe, i286op_repe, sizeof(v30op_repe)); V30PATCHING(v30op_repe, v30patch_repe); + CopyMemory(v30ope0xf6_xtable, ope0xf6_xtable, sizeof(v30ope0xf6_xtable)); + v30ope0xf6_xtable[6] = v30div_ea8; + v30ope0xf6_xtable[7] = v30idiv_ea8; + CopyMemory(v30ope0xf7_xtable, ope0xf7_xtable, sizeof(v30ope0xf7_xtable)); + v30ope0xf7_xtable[6] = v30div_ea16; + v30ope0xf7_xtable[7] = v30idiv_ea16; } -LABEL void v30(void) { +LABEL void v30x(void) { __asm { pushad - mov ebx, dword ptr (i286reg.prefetchque) + mov ebx, dword ptr (i286core.s.prefetchque) movzx esi, I286_IP cmp I286_TRAP, 0 @@ -1017,9 +1186,9 @@ LABEL void v30(void) { align 4 v30_mnlp: movzx eax, bl call v30op[eax*4] - cmp nevent.remainclock, 0 + cmp I286_REMCLOCK, 0 jg v30_mnlp - mov dword ptr (i286reg.prefetchque), ebx + mov dword ptr (i286core.s.prefetchque), ebx mov I286_IP, si popad ret @@ -1027,10 +1196,10 @@ v30_mnlp: movzx eax, bl align 4 v30_dma_mnlp: movzx eax, bl call v30op[eax*4] - call dmap_i286 - cmp nevent.remainclock, 0 + call dmax86 + cmp I286_REMCLOCK, 0 jg v30_dma_mnlp - mov dword ptr (i286reg.prefetchque), ebx + mov dword ptr (i286core.s.prefetchque), ebx mov I286_IP, si popad ret @@ -1042,18 +1211,18 @@ v30_trapping: movzx eax, bl je v30notrap mov ecx, 1 call i286x_localint -v30notrap: mov dword ptr (i286reg.prefetchque), ebx +v30notrap: mov dword ptr (i286core.s.prefetchque), ebx mov I286_IP, si popad ret } } -LABEL void v30_step(void) { +LABEL void v30x_step(void) { __asm { pushad - mov ebx, dword ptr (i286reg.prefetchque) + mov ebx, dword ptr (i286core.s.prefetchque) movzx esi, I286_IP movzx eax, bl @@ -1064,10 +1233,10 @@ LABEL void v30_step(void) { mov ecx, 1 call i286x_localint nexts: - mov dword ptr (i286reg.prefetchque), ebx + mov dword ptr (i286core.s.prefetchque), ebx mov I286_IP, si - call dmap_i286 + call dmax86 popad ret }