|
|
| version 1.3, 2003/10/19 14:56:15 | version 1.9, 2005/02/08 09:57:26 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "i286.h" | #include "cpucore.h" |
| #include "i286x.h" | #include "i286x.h" |
| #include "i286xadr.h" | #include "i286xadr.h" |
| #include "i286xs.h" | #include "i286xs.h" |
| #include "i286xrep.h" | #include "i286xrep.h" |
| #include "i286xcts.h" | #include "i286xcts.h" |
| #include "memory.h" | |
| #include "pccore.h" | #include "pccore.h" |
| #include "bios.h" | #include "bios.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "i286x.mcr" | #include "i286x.mcr" |
| #include "i286xea.mcr" | #include "i286xea.mcr" |
| #include "dmap.h" | #include "dmax86.h" |
| typedef struct { | typedef struct { |
| DWORD opnum; | UINT opnum; |
| void (*v30opcode)(void); | I286TBL v30opcode; |
| } V30PATCH_T; | } 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] = | static const BYTE shiftbase16[256] = |
| Line 94 I286 v30pop_ss(void) { // 17: pop | Line 99 I286 v30pop_ss(void) { // 17: pop |
| shl eax, 4 // make segreg | shl eax, 4 // make segreg |
| mov SS_BASE, eax | mov SS_BASE, eax |
| mov SS_FIX, eax | mov SS_FIX, eax |
| cmp i286reg.prefix, 0 // 00/06/24 | cmp i286core.s.prefix, 0 // 00/06/24 |
| je noprefix | je noprefix |
| call removeprefix | call removeprefix |
| pop eax | pop eax |
| Line 204 I286 v30mov_seg_ea(void) { // 8E: m | Line 209 I286 v30mov_seg_ea(void) { // 8E: m |
| segsetr:ret | segsetr:ret |
| align 4 | align 4 |
| setss: cmp i286reg.prefix, 0 // 00/05/13 | setss: cmp i286core.s.prefix, 0 // 00/05/13 |
| je noprefix | je noprefix |
| pop eax | pop eax |
| call eax // eax<-offset removeprefix | call eax // eax<-offset removeprefix |
| Line 793 I286 v30_repe(void) { // F3: repe | Line 798 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 | {0x17, v30pop_ss}, // 17: pop ss |
| {0x26, v30segprefix_es}, // 26: es: | {0x26, v30segprefix_es}, // 26: es: |
| {0x2e, v30segprefix_cs}, // 2E: cs: | {0x2e, v30segprefix_cs}, // 2E: cs: |
| Line 818 static V30PATCH_T v30patch_op[] = { | Line 979 static V30PATCH_T v30patch_op[] = { |
| {0xd5, v30_aad}, // D5: AAD | {0xd5, v30_aad}, // D5: AAD |
| {0xd6, v30_xlat}, // D6: xlat (8086/V30) | {0xd6, v30_xlat}, // D6: xlat (8086/V30) |
| {0xf2, v30_repne}, // F2: repne | {0xf2, v30_repne}, // F2: repne |
| {0xf3, v30_repe} // F3: repe | {0xf3, v30_repe}, // F3: repe |
| }; | {0xf6, v30_ope0xf6}, // F6: |
| {0xf7, v30_ope0xf7}}; // F7: | |
| // ----------------------------------------------------------------- repe | // ----------------------------------------------------------------- repe |
| Line 872 I286 v30repe_segprefix_ds(void) { | Line 1035 I286 v30repe_segprefix_ds(void) { |
| } | } |
| static V30PATCH_T v30patch_repe[] = { | static const V30PATCH v30patch_repe[] = { |
| {0x17, v30pop_ss}, // 17: pop ss | {0x17, v30pop_ss}, // 17: pop ss |
| {0x26, v30repe_segprefix_es}, // 26: repe es: | {0x26, v30repe_segprefix_es}, // 26: repe es: |
| {0x2e, v30repe_segprefix_cs}, // 2E: repe cs: | {0x2e, v30repe_segprefix_cs}, // 2E: repe cs: |
| Line 896 static V30PATCH_T v30patch_repe[] = { | Line 1059 static V30PATCH_T v30patch_repe[] = { |
| {0xd5, v30_aad}, // D5: AAD | {0xd5, v30_aad}, // D5: AAD |
| {0xd6, v30_xlat}, // D6: xlat (8086/V30) | {0xd6, v30_xlat}, // D6: xlat (8086/V30) |
| {0xf2, v30_repne}, // F2: repne | {0xf2, v30_repne}, // F2: repne |
| {0xf3, v30_repe} // F3: repe | {0xf3, v30_repe}, // F3: repe |
| }; | {0xf6, v30_ope0xf6}, // F6: |
| {0xf7, v30_ope0xf7}}; // F7: | |
| // ----------------------------------------------------------------- repne | // ----------------------------------------------------------------- repne |
| Line 949 I286 v30repne_segprefix_ds(void) { | Line 1114 I286 v30repne_segprefix_ds(void) { |
| } | } |
| } | } |
| static V30PATCH_T v30patch_repne[] = { | static const V30PATCH v30patch_repne[] = { |
| {0x17, v30pop_ss}, // 17: pop ss | {0x17, v30pop_ss}, // 17: pop ss |
| {0x26, v30repne_segprefix_es}, // 26: repne es: | {0x26, v30repne_segprefix_es}, // 26: repne es: |
| {0x2e, v30repne_segprefix_cs}, // 2E: repne cs: | {0x2e, v30repne_segprefix_cs}, // 2E: repne cs: |
| Line 973 static V30PATCH_T v30patch_repne[] = { | Line 1138 static V30PATCH_T v30patch_repne[] = { |
| {0xd5, v30_aad}, // D5: AAD | {0xd5, v30_aad}, // D5: AAD |
| {0xd6, v30_xlat}, // D6: xlat (8086/V30) | {0xd6, v30_xlat}, // D6: xlat (8086/V30) |
| {0xf2, v30_repne}, // F2: repne | {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--) { | while(length--) { |
| dst[patch->opnum] = patch->v30opcode; | dst[patch->opnum] = patch->v30opcode; |
| Line 990 static void v30patching(void (*dst[])(vo | Line 1153 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)); | CopyMemory(v30op, i286op, sizeof(v30op)); |
| V30PATCHING(v30op, v30patch_op); | V30PATCHING(v30op, v30patch_op); |
| Line 1000 void v30init(void) { | Line 1163 void v30init(void) { |
| V30PATCHING(v30op_repne, v30patch_repne); | V30PATCHING(v30op_repne, v30patch_repne); |
| CopyMemory(v30op_repe, i286op_repe, sizeof(v30op_repe)); | CopyMemory(v30op_repe, i286op_repe, sizeof(v30op_repe)); |
| V30PATCHING(v30op_repe, v30patch_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 { | __asm { |
| pushad | pushad |
| mov ebx, dword ptr (i286reg.prefetchque) | mov ebx, dword ptr (i286core.s.prefetchque) |
| movzx esi, I286_IP | movzx esi, I286_IP |
| cmp I286_TRAP, 0 | cmp I286_TRAP, 0 |
| Line 1019 v30_mnlp: movzx eax, bl | Line 1188 v30_mnlp: movzx eax, bl |
| call v30op[eax*4] | call v30op[eax*4] |
| cmp I286_REMCLOCK, 0 | cmp I286_REMCLOCK, 0 |
| jg v30_mnlp | jg v30_mnlp |
| mov dword ptr (i286reg.prefetchque), ebx | mov dword ptr (i286core.s.prefetchque), ebx |
| mov I286_IP, si | mov I286_IP, si |
| popad | popad |
| ret | ret |
| Line 1027 v30_mnlp: movzx eax, bl | Line 1196 v30_mnlp: movzx eax, bl |
| align 4 | align 4 |
| v30_dma_mnlp: movzx eax, bl | v30_dma_mnlp: movzx eax, bl |
| call v30op[eax*4] | call v30op[eax*4] |
| call dmap_i286 | call dmax86 |
| cmp I286_REMCLOCK, 0 | cmp I286_REMCLOCK, 0 |
| jg v30_dma_mnlp | jg v30_dma_mnlp |
| mov dword ptr (i286reg.prefetchque), ebx | mov dword ptr (i286core.s.prefetchque), ebx |
| mov I286_IP, si | mov I286_IP, si |
| popad | popad |
| ret | ret |
| Line 1042 v30_trapping: movzx eax, bl | Line 1211 v30_trapping: movzx eax, bl |
| je v30notrap | je v30notrap |
| mov ecx, 1 | mov ecx, 1 |
| call i286x_localint | call i286x_localint |
| v30notrap: mov dword ptr (i286reg.prefetchque), ebx | v30notrap: mov dword ptr (i286core.s.prefetchque), ebx |
| mov I286_IP, si | mov I286_IP, si |
| popad | popad |
| ret | ret |
| } | } |
| } | } |
| LABEL void v30_step(void) { | LABEL void v30x_step(void) { |
| __asm { | __asm { |
| pushad | pushad |
| mov ebx, dword ptr (i286reg.prefetchque) | mov ebx, dword ptr (i286core.s.prefetchque) |
| movzx esi, I286_IP | movzx esi, I286_IP |
| movzx eax, bl | movzx eax, bl |
| Line 1064 LABEL void v30_step(void) { | Line 1233 LABEL void v30_step(void) { |
| mov ecx, 1 | mov ecx, 1 |
| call i286x_localint | call i286x_localint |
| nexts: | nexts: |
| mov dword ptr (i286reg.prefetchque), ebx | mov dword ptr (i286core.s.prefetchque), ebx |
| mov I286_IP, si | mov I286_IP, si |
| call dmap_i286 | call dmax86 |
| popad | popad |
| ret | ret |
| } | } |