| version 1.2, 2003/10/17 07:17:20 | version 1.10, 2005/02/12 12:13:58 | 
| 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 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 38  static const BYTE shiftbase16[256] = | Line 43  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 56  static const BYTE shiftbase09[256] = | Line 61  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 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 1017  LABEL void v30(void) { | Line 1186  LABEL void v30(void) { | 
 | align   4 | align   4 | 
 | v30_mnlp:               movzx   eax, bl | v30_mnlp:               movzx   eax, bl | 
 | call    v30op[eax*4] | call    v30op[eax*4] | 
| cmp             nevent.remainclock, 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             nevent.remainclock, 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 | 
 | } | } |