|
|
| version 1.4, 2003/11/28 08:01:32 | version 1.11, 2005/03/26 07:48:36 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "i286.h" | #include "cpucore.h" |
| #include "i286c.h" | #include "i286c.h" |
| #include "v30patch.h" | #include "v30patch.h" |
| #include "memory.h" | |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "bios.h" | #include "bios.h" |
| #include "dmap.h" | #include "dmav30.h" |
| #include "i286c.mcr" | #include "i286c.mcr" |
| #if defined(ENABLE_TRAP) | |
| #include "steptrap.h" | |
| #endif | |
| // victory30 patch | // victory30 patch |
| Line 25 | Line 27 |
| typedef struct { | typedef struct { |
| UINT opnum; | UINT opnum; |
| void (*v30opcode)(void); | I286OP v30opcode; |
| } V30PATCH; | } V30PATCH; |
| static void (*v30op[256])(void); | static I286OP v30op[256]; |
| static void (*v30op_repne[256])(void); | static I286OP v30op_repne[256]; |
| static void (*v30op_repe[256])(void); | static I286OP v30op_repe[256]; |
| static I286OPF6 v30ope0xf6_table[8]; | |
| static I286OPF6 v30ope0xf7_table[8]; | |
| static const BYTE shiftbase16[256] = | static const UINT8 rotatebase16[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 51 static const BYTE shiftbase16[256] = | Line 55 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 rotatebase09[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 69 static const BYTE shiftbase09[256] = | Line 73 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 rotatebase17[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 97 I286FN v30segprefix_es(void) { // 26: | Line 101 I286FN v30segprefix_es(void) { // 26: |
| SS_FIX = ES_BASE; | SS_FIX = ES_BASE; |
| DS_FIX = ES_BASE; | DS_FIX = ES_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op[op](); | v30op[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 114 I286FN v30segprefix_cs(void) { // 2e: | Line 118 I286FN v30segprefix_cs(void) { // 2e: |
| SS_FIX = CS_BASE; | SS_FIX = CS_BASE; |
| DS_FIX = CS_BASE; | DS_FIX = CS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op[op](); | v30op[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 131 I286FN v30segprefix_ss(void) { // 36: | Line 135 I286FN v30segprefix_ss(void) { // 36: |
| SS_FIX = SS_BASE; | SS_FIX = SS_BASE; |
| DS_FIX = SS_BASE; | DS_FIX = SS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op[op](); | v30op[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 148 I286FN v30segprefix_ds(void) { // 3e: | Line 152 I286FN v30segprefix_ds(void) { // 3e: |
| SS_FIX = DS_BASE; | SS_FIX = DS_BASE; |
| DS_FIX = DS_BASE; | DS_FIX = DS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op[op](); | v30op[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 224 I286FN v30_popf(void) { // 9D: popf | Line 228 I286FN v30_popf(void) { // 9D: popf |
| I286FN v30shift_ea8_data8(void) { // C0: shift EA8, DATA8 | I286FN v30shift_ea8_data8(void) { // C0: shift EA8, DATA8 |
| BYTE *out; | UINT8 *out; |
| UINT op; | UINT op; |
| UINT32 madr; | UINT32 madr; |
| BYTE cl; | REG8 cl; |
| GET_PCBYTE(op) | GET_PCBYTE(op) |
| if (op >= 0xc0) { | if (op >= 0xc0) { |
| Line 239 I286FN v30shift_ea8_data8(void) { // C | Line 243 I286FN v30shift_ea8_data8(void) { // C |
| madr = CALC_EA(op); | madr = CALC_EA(op); |
| if (madr >= I286_MEMWRITEMAX) { | if (madr >= I286_MEMWRITEMAX) { |
| GET_PCBYTE(cl) | GET_PCBYTE(cl) |
| if ((op & 0x30) == 0x10) { // rotate with carry | I286_WORKCLOCK(cl); |
| cl = shiftbase09[cl]; | if (!(op & 0x20)) { // rotate |
| if (!(op & 0x10)) { | |
| cl = rotatebase16[cl]; | |
| } | |
| else { // rotate with carry | |
| cl = rotatebase09[cl]; | |
| } | |
| } | } |
| else { | else { |
| cl = shiftbase16[cl]; | cl = max(cl, 9); |
| } | } |
| I286_WORKCLOCK(cl); | |
| sft_e8cl_table[(op >> 3) & 7](madr, cl); | sft_e8cl_table[(op >> 3) & 7](madr, cl); |
| return; | return; |
| } | } |
| out = mem + madr; | out = mem + madr; |
| } | } |
| GET_PCBYTE(cl) | GET_PCBYTE(cl) |
| if ((op & 0x30) == 0x10) { // rotate with carry | I286_WORKCLOCK(cl); |
| cl = shiftbase09[cl]; | if (!(op & 0x20)) { // rotate |
| if (!(op & 0x10)) { | |
| cl = rotatebase16[cl]; | |
| } | |
| else { // rotate with carry | |
| cl = rotatebase09[cl]; | |
| } | |
| } | } |
| else { | else { |
| cl = shiftbase16[cl]; | cl = max(cl, 9); |
| } | } |
| I286_WORKCLOCK(cl); | |
| sft_r8cl_table[(op >> 3) & 7](out, cl); | sft_r8cl_table[(op >> 3) & 7](out, cl); |
| } | } |
| Line 267 I286FN v30shift_ea16_data8(void) { // | Line 281 I286FN v30shift_ea16_data8(void) { // |
| UINT16 *out; | UINT16 *out; |
| UINT op; | UINT op; |
| UINT32 madr; | UINT32 madr; |
| BYTE cl; | REG8 cl; |
| GET_PCBYTE(op) | GET_PCBYTE(op) |
| if (op >= 0xc0) { | if (op >= 0xc0) { |
| Line 279 I286FN v30shift_ea16_data8(void) { // | Line 293 I286FN v30shift_ea16_data8(void) { // |
| madr = CALC_EA(op); | madr = CALC_EA(op); |
| if (INHIBIT_WORDP(madr)) { | if (INHIBIT_WORDP(madr)) { |
| GET_PCBYTE(cl); | GET_PCBYTE(cl); |
| if ((op & 0x30) == 0x10) { // rotate with carry | I286_WORKCLOCK(cl); |
| cl = shiftbase17[cl]; | if (!(op & 0x20)) { // rotate |
| if (!(op & 0x10)) { | |
| cl = rotatebase16[cl]; | |
| } | |
| else { // with carry | |
| cl = rotatebase17[cl]; | |
| } | |
| } | } |
| else { | else { // shift |
| cl = shiftbase16[cl]; | cl = max(cl, 17); |
| } | } |
| I286_WORKCLOCK(cl); | |
| sft_e16cl_table[(op >> 3) & 7](madr, cl); | sft_e16cl_table[(op >> 3) & 7](madr, cl); |
| return; | return; |
| } | } |
| out = (UINT16 *)(mem + madr); | out = (UINT16 *)(mem + madr); |
| } | } |
| GET_PCBYTE(cl); | GET_PCBYTE(cl); |
| if ((op & 0x30) == 0x10) { // rotate with carry | I286_WORKCLOCK(cl); |
| cl = shiftbase17[cl]; | if (!(op & 0x20)) { // rotate |
| if (!(op & 0x10)) { | |
| cl = rotatebase16[cl]; | |
| } | |
| else { // with carry | |
| cl = rotatebase17[cl]; | |
| } | |
| } | } |
| else { | else { // shift |
| cl = shiftbase16[cl]; | cl = max(cl, 17); |
| } | } |
| I286_WORKCLOCK(cl); | |
| sft_r16cl_table[(op >> 3) & 7](out, cl); | sft_r16cl_table[(op >> 3) & 7](out, cl); |
| } | } |
| I286FN v30shift_ea8_cl(void) { // D2: shift EA8, cl | I286FN v30shift_ea8_cl(void) { // D2: shift EA8, cl |
| BYTE *out; | UINT8 *out; |
| UINT op; | UINT op; |
| UINT32 madr; | UINT32 madr; |
| BYTE cl; | REG8 cl; |
| GET_PCBYTE(op) | GET_PCBYTE(op) |
| if (op >= 0xc0) { | if (op >= 0xc0) { |
| Line 320 I286FN v30shift_ea8_cl(void) { // D2: | Line 344 I286FN v30shift_ea8_cl(void) { // D2: |
| if (madr >= I286_MEMWRITEMAX) { | if (madr >= I286_MEMWRITEMAX) { |
| cl = I286_CL; | cl = I286_CL; |
| I286_WORKCLOCK(cl); | I286_WORKCLOCK(cl); |
| if ((op & 0x30) == 0x10) { // rotate with carry | if (!(op & 0x20)) { // rotate |
| cl = shiftbase09[cl]; | if (!(op & 0x10)) { |
| cl = rotatebase16[cl]; | |
| } | |
| else { // rotate with carry | |
| cl = rotatebase09[cl]; | |
| } | |
| } | } |
| else { | else { |
| cl = shiftbase16[cl]; | cl = max(cl, 9); |
| } | } |
| sft_e8cl_table[(op >> 3) & 7](madr, cl); | sft_e8cl_table[(op >> 3) & 7](madr, cl); |
| return; | return; |
| Line 333 I286FN v30shift_ea8_cl(void) { // D2: | Line 362 I286FN v30shift_ea8_cl(void) { // D2: |
| } | } |
| cl = I286_CL; | cl = I286_CL; |
| I286_WORKCLOCK(cl); | I286_WORKCLOCK(cl); |
| if ((op & 0x30) == 0x10) { // rotate with carry | if (!(op & 0x20)) { // rotate |
| cl = shiftbase09[cl]; | if (!(op & 0x10)) { |
| cl = rotatebase16[cl]; | |
| } | |
| else { // rotate with carry | |
| cl = rotatebase09[cl]; | |
| } | |
| } | } |
| else { | else { |
| cl = shiftbase16[cl]; | cl = max(cl, 9); |
| } | } |
| sft_r8cl_table[(op >> 3) & 7](out, cl); | sft_r8cl_table[(op >> 3) & 7](out, cl); |
| } | } |
| Line 347 I286FN v30shift_ea16_cl(void) { // D3 | Line 381 I286FN v30shift_ea16_cl(void) { // D3 |
| UINT16 *out; | UINT16 *out; |
| UINT op; | UINT op; |
| UINT32 madr; | UINT32 madr; |
| BYTE cl; | REG8 cl; |
| GET_PCBYTE(op) | GET_PCBYTE(op) |
| if (op >= 0xc0) { | if (op >= 0xc0) { |
| Line 360 I286FN v30shift_ea16_cl(void) { // D3 | Line 394 I286FN v30shift_ea16_cl(void) { // D3 |
| if (INHIBIT_WORDP(madr)) { | if (INHIBIT_WORDP(madr)) { |
| cl = I286_CL; | cl = I286_CL; |
| I286_WORKCLOCK(cl); | I286_WORKCLOCK(cl); |
| if ((op & 0x30) == 0x10) { // rotate with carry | if (!(op & 0x20)) { // rotate |
| cl = shiftbase17[cl]; | if (!(op & 0x10)) { |
| cl = rotatebase16[cl]; | |
| } | |
| else { // with carry | |
| cl = rotatebase17[cl]; | |
| } | |
| } | } |
| else { | else { // shift |
| cl = shiftbase16[cl]; | cl = max(cl, 17); |
| } | } |
| sft_e16cl_table[(op >> 3) & 7](madr, cl); | sft_e16cl_table[(op >> 3) & 7](madr, cl); |
| return; | return; |
| Line 373 I286FN v30shift_ea16_cl(void) { // D3 | Line 412 I286FN v30shift_ea16_cl(void) { // D3 |
| } | } |
| cl = I286_CL; | cl = I286_CL; |
| I286_WORKCLOCK(cl); | I286_WORKCLOCK(cl); |
| if ((op & 0x30) == 0x10) { // rotate with carry | if (!(op & 0x20)) { // rotate |
| cl = shiftbase17[cl]; | if (!(op & 0x10)) { |
| cl = rotatebase16[cl]; | |
| } | |
| else { // with carry | |
| cl = rotatebase17[cl]; | |
| } | |
| } | } |
| else { | else { // shift |
| cl = shiftbase16[cl]; | cl = max(cl, 17); |
| } | } |
| sft_r16cl_table[(op >> 3) & 7](out, cl); | sft_r16cl_table[(op >> 3) & 7](out, cl); |
| } | } |
| I286FN v30_aam(void) { // D4: AAM | I286FN v30_aam(void) { // D4: AAM |
| BYTE al; | UINT8 al; |
| I286_WORKCLOCK(16); | I286_WORKCLOCK(16); |
| I286_IP++; // is 10 | I286_IP++; // is 10 |
| Line 399 I286FN v30_aad(void) { // D5: AAD | Line 443 I286FN v30_aad(void) { // D5: AAD |
| I286_WORKCLOCK(14); | I286_WORKCLOCK(14); |
| I286_IP++; // is 10 | I286_IP++; // is 10 |
| I286_AL += (BYTE)(I286_AH * 10); | I286_AL += (UINT8)(I286_AH * 10); |
| I286_AH = 0; | I286_AH = 0; |
| I286_FLAGL &= ~(S_FLAG | Z_FLAG | P_FLAG); | I286_FLAGL &= ~(S_FLAG | Z_FLAG | P_FLAG); |
| I286_FLAGL |= BYTESZPF(I286_AL); | I286_FLAGL |= BYTESZPF(I286_AL); |
| Line 413 I286FN v30_xlat(void) { // D6: xlat | Line 457 I286FN v30_xlat(void) { // D6: xlat |
| I286FN v30_repne(void) { // F2: repne | I286FN v30_repne(void) { // F2: repne |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repne[op](); | v30op_repne[op](); |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 427 I286FN v30_repne(void) { // F2: repn | Line 471 I286FN v30_repne(void) { // F2: repn |
| I286FN v30_repe(void) { // F3: repe | I286FN v30_repe(void) { // F3: repe |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repe[op](); | v30op_repe[op](); |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| } | } |
| } | } |
| I286_F6 v30_div_ea8(UINT op) { | |
| UINT16 tmp; | |
| UINT8 src; | |
| if (op >= 0xc0) { | |
| I286_WORKCLOCK(14); | |
| src = *(REG8_B20(op)); | |
| } | |
| else { | |
| I286_WORKCLOCK(17); | |
| src = i286_memoryread(CALC_EA(op)); | |
| } | |
| tmp = I286_AX; | |
| if ((src) && (tmp < ((UINT16)src << 8))) { | |
| I286_AL = tmp / src; | |
| I286_AH = tmp % src; | |
| } | |
| else { | |
| INT_NUM(0, I286_IP); // V30 | |
| } | |
| } | |
| I286_F6 v30_idiv_ea8(UINT op) { | |
| SINT16 tmp; | |
| SINT16 r; | |
| SINT8 src; | |
| if (op >= 0xc0) { | |
| I286_WORKCLOCK(17); | |
| src = *(REG8_B20(op)); | |
| } | |
| else { | |
| I286_WORKCLOCK(20); | |
| src = i286_memoryread(CALC_EA(op)); | |
| } | |
| tmp = (SINT16)I286_AX; | |
| if (src) { | |
| r = tmp / src; | |
| if (!((r + 0x80) & 0xff00)) { | |
| I286_AL = (UINT8)r; | |
| I286_AH = tmp % src; | |
| return; | |
| } | |
| } | |
| INT_NUM(0, I286_IP); // V30 | |
| } | |
| I286FN v30_ope0xf6(void) { // F6: | |
| UINT op; | |
| GET_PCBYTE(op); | |
| v30ope0xf6_table[(op >> 3) & 7](op); | |
| } | |
| I286_F6 v30_div_ea16(UINT op) { | |
| UINT32 tmp; | |
| UINT32 src; | |
| if (op >= 0xc0) { | |
| I286_WORKCLOCK(22); | |
| src = *(REG16_B20(op)); | |
| } | |
| else { | |
| I286_WORKCLOCK(25); | |
| src = i286_memoryread_w(CALC_EA(op)); | |
| } | |
| tmp = (I286_DX << 16) + I286_AX; | |
| if ((src) && (tmp < (src << 16))) { | |
| I286_AX = tmp / src; | |
| I286_DX = tmp % src; | |
| } | |
| else { | |
| INT_NUM(0, I286_IP); // V30 | |
| } | |
| } | |
| I286_F6 v30_idiv_ea16(UINT op) { | |
| SINT32 tmp; | |
| SINT32 r; | |
| SINT16 src; | |
| if (op >= 0xc0) { | |
| I286_WORKCLOCK(25); | |
| src = *(REG16_B20(op)); | |
| } | |
| else { | |
| I286_WORKCLOCK(28); | |
| src = i286_memoryread_w(CALC_EA(op)); | |
| } | |
| tmp = (SINT32)((I286_DX << 16) + I286_AX); | |
| if (src) { | |
| r = tmp / src; | |
| if (!((r + 0x8000) & 0xffff0000)) { | |
| I286_AX = (SINT16)r; | |
| I286_DX = tmp % src; | |
| return; | |
| } | |
| } | |
| INT_NUM(0, I286_IP); // V30 | |
| } | |
| I286FN v30_ope0xf7(void) { // F7: | |
| UINT op; | |
| GET_PCBYTE(op); | |
| v30ope0xf7_table[(op >> 3) & 7](op); | |
| } | |
| static const V30PATCH v30patch_op[] = { | static const V30PATCH v30patch_op[] = { |
| {0x26, v30segprefix_es}, // 26: es: | {0x26, v30segprefix_es}, // 26: es: |
| {0x2e, v30segprefix_cs}, // 2E: cs: | {0x2e, v30segprefix_cs}, // 2E: cs: |
| Line 462 static const V30PATCH v30patch_op[] = { | Line 620 static const V30PATCH 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 472 I286FN v30repe_segprefix_es(void) { | Line 631 I286FN v30repe_segprefix_es(void) { |
| DS_FIX = ES_BASE; | DS_FIX = ES_BASE; |
| SS_FIX = ES_BASE; | SS_FIX = ES_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repe[op](); | v30op_repe[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 489 I286FN v30repe_segprefix_cs(void) { | Line 648 I286FN v30repe_segprefix_cs(void) { |
| DS_FIX = CS_BASE; | DS_FIX = CS_BASE; |
| SS_FIX = CS_BASE; | SS_FIX = CS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repe[op](); | v30op_repe[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 506 I286FN v30repe_segprefix_ss(void) { | Line 665 I286FN v30repe_segprefix_ss(void) { |
| DS_FIX = SS_BASE; | DS_FIX = SS_BASE; |
| SS_FIX = SS_BASE; | SS_FIX = SS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repe[op](); | v30op_repe[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 523 I286FN v30repe_segprefix_ds(void) { | Line 682 I286FN v30repe_segprefix_ds(void) { |
| DS_FIX = DS_BASE; | DS_FIX = DS_BASE; |
| SS_FIX = DS_BASE; | SS_FIX = DS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repe[op](); | v30op_repe[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 559 static const V30PATCH v30patch_repe[] = | Line 718 static const V30PATCH 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 569 I286FN v30repne_segprefix_es(void) { | Line 729 I286FN v30repne_segprefix_es(void) { |
| DS_FIX = ES_BASE; | DS_FIX = ES_BASE; |
| SS_FIX = ES_BASE; | SS_FIX = ES_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repne[op](); | v30op_repne[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 586 I286FN v30repne_segprefix_cs(void) { | Line 746 I286FN v30repne_segprefix_cs(void) { |
| DS_FIX = CS_BASE; | DS_FIX = CS_BASE; |
| SS_FIX = CS_BASE; | SS_FIX = CS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repne[op](); | v30op_repne[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 603 I286FN v30repne_segprefix_ss(void) { | Line 763 I286FN v30repne_segprefix_ss(void) { |
| DS_FIX = SS_BASE; | DS_FIX = SS_BASE; |
| SS_FIX = SS_BASE; | SS_FIX = SS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repne[op](); | v30op_repne[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 620 I286FN v30repne_segprefix_ds(void) { | Line 780 I286FN v30repne_segprefix_ds(void) { |
| DS_FIX = DS_BASE; | DS_FIX = DS_BASE; |
| SS_FIX = DS_BASE; | SS_FIX = DS_BASE; |
| i286reg.prefix++; | I286_PREFIX++; |
| if (i286reg.prefix < MAX_PREFIX) { | if (I286_PREFIX < MAX_PREFIX) { |
| UINT op; | UINT op; |
| GET_PCBYTE(op); | GET_PCBYTE(op); |
| v30op_repne[op](); | v30op_repne[op](); |
| REMOVE_PREFIX | REMOVE_PREFIX |
| i286reg.prefix = 0; | I286_PREFIX = 0; |
| } | } |
| else { | else { |
| INT_NUM(6, I286_IP); | INT_NUM(6, I286_IP); |
| Line 656 static const V30PATCH v30patch_repne[] = | Line 816 static const V30PATCH 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: | |
| // --------------------------------------------------------------------------- | // --------------------------------------------------------------------------- |
| static void v30patching(void (*op[])(void), const V30PATCH *patch, int cnt) { | static void v30patching(I286OP *op, const V30PATCH *patch, int cnt) { |
| do { | do { |
| op[patch->opnum] = patch->v30opcode; | op[patch->opnum] = patch->v30opcode; |
| Line 672 static void v30patching(void (*op[])(voi | Line 833 static void v30patching(void (*op[])(voi |
| #define V30PATCHING(a, b) v30patching(a, b, sizeof(b)/sizeof(V30PATCH)) | #define V30PATCHING(a, b) v30patching(a, b, sizeof(b)/sizeof(V30PATCH)) |
| void v30init(void) { | void v30cinit(void) { |
| CopyMemory(v30op, i286op, sizeof(v30op)); | CopyMemory(v30op, i286op, sizeof(v30op)); |
| V30PATCHING(v30op, v30patch_op); | V30PATCHING(v30op, v30patch_op); |
| Line 680 void v30init(void) { | Line 841 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_table, c_ope0xf6_table, sizeof(v30ope0xf6_table)); | |
| v30ope0xf6_table[6] = v30_div_ea8; | |
| v30ope0xf6_table[7] = v30_idiv_ea8; | |
| CopyMemory(v30ope0xf7_table, c_ope0xf7_table, sizeof(v30ope0xf7_table)); | |
| v30ope0xf7_table[6] = v30_div_ea16; | |
| v30ope0xf7_table[7] = v30_idiv_ea16; | |
| } | } |
| void v30(void) { | void v30c(void) { |
| UINT opcode; | UINT opcode; |
| if (I286_TRAP) { | if (I286_TRAP) { |
| do { | do { |
| #if defined(ENABLE_TRAP) | |
| steptrap(CPU_CS, CPU_IP); | |
| #endif | |
| GET_PCBYTE(opcode); | GET_PCBYTE(opcode); |
| v30op[opcode](); | v30op[opcode](); |
| if (I286_TRAP) { | if (I286_TRAP) { |
| i286_interrupt(1); | i286c_interrupt(1); |
| } | } |
| dmap_v30(); | dmav30(); |
| } while(I286_REMCLOCK > 0); | } while(I286_REMCLOCK > 0); |
| } | } |
| else if (dmac.working) { | else if (dmac.working) { |
| do { | do { |
| #if defined(ENABLE_TRAP) | |
| steptrap(CPU_CS, CPU_IP); | |
| #endif | |
| GET_PCBYTE(opcode); | GET_PCBYTE(opcode); |
| v30op[opcode](); | v30op[opcode](); |
| dmap_v30(); | dmav30(); |
| } while(I286_REMCLOCK > 0); | } while(I286_REMCLOCK > 0); |
| } | } |
| else { | else { |
| do { | do { |
| #if defined(ENABLE_TRAP) | |
| steptrap(CPU_CS, CPU_IP); | |
| #endif | |
| GET_PCBYTE(opcode); | GET_PCBYTE(opcode); |
| v30op[opcode](); | v30op[opcode](); |
| } while(I286_REMCLOCK > 0); | } while(I286_REMCLOCK > 0); |
| } | } |
| } | } |
| void v30_step(void) { | void v30c_step(void) { |
| UINT opcode; | UINT opcode; |
| Line 725 void v30_step(void) { | Line 901 void v30_step(void) { |
| if (I286_OV) { | if (I286_OV) { |
| I286_FLAG |= (O_FLAG); | I286_FLAG |= (O_FLAG); |
| } | } |
| dmap_v30(); | dmav30(); |
| } | } |