| version 1.7, 2004/07/12 10:33:02 | version 1.11, 2005/03/03 06:59:41 | 
| Line 10 | Line 10 | 
 | #include        "iocore.h" | #include        "iocore.h" | 
 | #include        "i286x.mcr" | #include        "i286x.mcr" | 
 | #include        "i286xea.mcr" | #include        "i286xea.mcr" | 
| #include        "dmap.h" | #include        "dmax86.h" | 
|  | #if defined(ENABLE_TRAP) | 
|  | #include        "steptrap.h" | 
|  | #endif | 
 |  |  | 
 |  |  | 
 | typedef struct { | typedef struct { | 
 | UINT    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 UINT8 shiftbase16[256] = | 
 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | 
 | 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | 
 | 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | 
| Line 37  static const BYTE shiftbase16[256] = | Line 46  static const BYTE shiftbase16[256] = | 
 | 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | 
 | 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}; | 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}; | 
 |  |  | 
| static const BYTE shiftbase09[256] = | static const UINT8 shiftbase09[256] = | 
 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, | 
 | 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, | 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, | 
 | 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, | 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, | 
| Line 55  static const BYTE shiftbase09[256] = | Line 64  static const BYTE shiftbase09[256] = | 
 | 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, | 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, | 
 | 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3}; | 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3}; | 
 |  |  | 
| static const BYTE shiftbase17[256] = | static const UINT8 shiftbase17[256] = | 
 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, | 
 | 16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, | 16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, | 
 | 15,16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, | 15,16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, | 
| Line 792  I286 v30_repe(void) {       // F3: repe | Line 801  I286 v30_repe(void) {       // F3: repe | 
 | } | } | 
 | } | } | 
 |  |  | 
 |  | I286 v30div_ea8(void) {                                                 // F6-6: div ea8 | 
 |  |  | 
 |  | __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 | 
 |  |  | 
| static V30PATCH_T v30patch_op[] = { | 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 817  static V30PATCH_T v30patch_op[] = { | Line 982  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 871  I286 v30repe_segprefix_ds(void) { | Line 1038  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 895  static V30PATCH_T v30patch_repe[] = { | Line 1062  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 948  I286 v30repne_segprefix_ds(void) { | Line 1117  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 972  static V30PATCH_T v30patch_repne[] = { | Line 1141  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 989  static void v30patching(void (*dst[])(vo | Line 1156  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 v30xinit(void) { | void v30xinit(void) { | 
 |  |  | 
| Line 999  void v30xinit(void) { | Line 1166  void v30xinit(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 v30x(void) { | LABEL void v30x(void) { | 
| Line 1014  LABEL void v30x(void) { | Line 1187  LABEL void v30x(void) { | 
 | jne             short v30_dma_mnlp | jne             short v30_dma_mnlp | 
 |  |  | 
 | align   4 | align   4 | 
| v30_mnlp:               movzx   eax, bl | v30_mnlp: | 
|  | #if defined(ENABLE_TRAP) | 
|  | mov             edx, esi | 
|  | movzx   ecx, I286_CS | 
|  | call    steptrap | 
|  | #endif | 
|  | 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 | 
| Line 1024  v30_mnlp:  movzx eax, bl | Line 1203  v30_mnlp:  movzx eax, bl | 
 | ret | ret | 
 |  |  | 
 | align   4 | align   4 | 
| v30_dma_mnlp:   movzx   eax, bl | v30_dma_mnlp: | 
|  | #if defined(ENABLE_TRAP) | 
|  | mov             edx, esi | 
|  | movzx   ecx, I286_CS | 
|  | call    steptrap | 
|  | #endif | 
|  | 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 (i286core.s.prefetchque), ebx | mov             dword ptr (i286core.s.prefetchque), ebx | 
| Line 1035  v30_dma_mnlp: movzx eax, bl | Line 1220  v30_dma_mnlp: movzx eax, bl | 
 | ret | ret | 
 |  |  | 
 | align   4 | align   4 | 
| v30_trapping:   movzx   eax, bl | v30_trapping: | 
|  | #if defined(ENABLE_TRAP) | 
|  | mov             edx, esi | 
|  | movzx   ecx, I286_CS | 
|  | call    steptrap | 
|  | #endif | 
|  | movzx   eax, bl | 
 | call    v30op[eax*4] | call    v30op[eax*4] | 
 | cmp             I286_TRAP, 0 | cmp             I286_TRAP, 0 | 
 | je              v30notrap | je              v30notrap | 
| Line 1066  nexts: | Line 1257  nexts: | 
 | mov             dword ptr (i286core.s.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 | 
 | } | } |