More V20/V30 fixes.
This commit is contained in:
206
src/cpu/808x.c
206
src/cpu/808x.c
@@ -313,7 +313,7 @@ readmemw(uint32_t s, uint16_t a)
|
|||||||
else {
|
else {
|
||||||
wait(4, 1);
|
wait(4, 1);
|
||||||
ret = read_mem_b(s + a);
|
ret = read_mem_b(s + a);
|
||||||
ret |= read_mem_b(s + (is186 ? (a + 1) : (a + 1) & 0xffff)) << 8;
|
ret |= read_mem_b(s + ((is186 && !is_nec) ? (a + 1) : (a + 1) & 0xffff)) << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -385,7 +385,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v)
|
|||||||
else {
|
else {
|
||||||
write_mem_b(addr, v & 0xff);
|
write_mem_b(addr, v & 0xff);
|
||||||
wait(4, 1);
|
wait(4, 1);
|
||||||
addr = s + (is186 ? (a + 1) : ((a + 1) & 0xffff));
|
addr = s + ((is186 && !is_nec) ? (a + 1) : ((a + 1) & 0xffff));
|
||||||
write_mem_b(addr, v >> 8);
|
write_mem_b(addr, v >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,7 +794,7 @@ seteaq(uint64_t val)
|
|||||||
static void
|
static void
|
||||||
push(uint16_t *val)
|
push(uint16_t *val)
|
||||||
{
|
{
|
||||||
if (is186 && SP == 1) {
|
if ((is186 && !is_nec) && (SP == 1)) {
|
||||||
writememw(ss - 1, 0, *val);
|
writememw(ss - 1, 0, *val);
|
||||||
SP = cpu_state.eaaddr = 0xFFFF;
|
SP = cpu_state.eaaddr = 0xFFFF;
|
||||||
return;
|
return;
|
||||||
@@ -963,7 +963,7 @@ interrupt(uint16_t addr)
|
|||||||
pfq_clear();
|
pfq_clear();
|
||||||
ovr_seg = NULL;
|
ovr_seg = NULL;
|
||||||
access(39, 16);
|
access(39, 16);
|
||||||
tempf = cpu_state.flags & (is_nec && cpu_state.inside_emulation_mode ? 0x8fd7 : 0x0fd7);
|
tempf = cpu_state.flags & ((is_nec && cpu_state.inside_emulation_mode) ? 0x8fd7 : 0x0fd7);
|
||||||
push(&tempf);
|
push(&tempf);
|
||||||
cpu_state.flags &= ~(I_FLAG | T_FLAG);
|
cpu_state.flags &= ~(I_FLAG | T_FLAG);
|
||||||
access(40, 16);
|
access(40, 16);
|
||||||
@@ -1653,7 +1653,8 @@ execx86(int cycs)
|
|||||||
int8_t nibble_result_s;
|
int8_t nibble_result_s;
|
||||||
uint16_t addr, tempw, new_cs, new_ip;
|
uint16_t addr, tempw, new_cs, new_ip;
|
||||||
uint16_t tempw_int, size, tempbp, lowbound;
|
uint16_t tempw_int, size, tempbp, lowbound;
|
||||||
uint16_t highbound, regval;
|
uint16_t highbound, regval, orig_sp, wordtopush;
|
||||||
|
uint16_t immediate;
|
||||||
int bits;
|
int bits;
|
||||||
uint32_t dest_seg, i, carry, nibble;
|
uint32_t dest_seg, i, carry, nibble;
|
||||||
uint32_t srcseg, byteaddr;
|
uint32_t srcseg, byteaddr;
|
||||||
@@ -1679,6 +1680,97 @@ execx86(int cycs)
|
|||||||
// pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode);
|
// pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode);
|
||||||
if (is186) {
|
if (is186) {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
case 0x60: /*PUSHA/PUSH R*/
|
||||||
|
orig_sp = SP;
|
||||||
|
wait(1, 0);
|
||||||
|
push(&AX);
|
||||||
|
push(&CX);
|
||||||
|
push(&DX);
|
||||||
|
push(&BX);
|
||||||
|
push(&orig_sp);
|
||||||
|
push(&BP);
|
||||||
|
push(&SI);
|
||||||
|
push(&DI);
|
||||||
|
handled = 1;
|
||||||
|
break;
|
||||||
|
case 0x61: /*POPA/POP R*/
|
||||||
|
wait(9, 0);
|
||||||
|
DI = pop();
|
||||||
|
SI = pop();
|
||||||
|
BP = pop();
|
||||||
|
(void) pop(); /* former orig_sp */
|
||||||
|
BX = pop();
|
||||||
|
DX = pop();
|
||||||
|
CX = pop();
|
||||||
|
AX = pop();
|
||||||
|
handled = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x62: /* BOUND r/m */
|
||||||
|
lowbound = 0;
|
||||||
|
highbound = 0;
|
||||||
|
regval = 0;
|
||||||
|
do_mod_rm();
|
||||||
|
|
||||||
|
lowbound = readmemw(easeg, cpu_state.eaaddr);
|
||||||
|
highbound = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||||
|
regval = get_reg(cpu_reg);
|
||||||
|
if (lowbound > regval || highbound < regval) {
|
||||||
|
cpu_state.pc = cpu_state.oldpc;
|
||||||
|
interrupt(5);
|
||||||
|
}
|
||||||
|
handled = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x64:
|
||||||
|
case 0x65:
|
||||||
|
if (is_nec) {
|
||||||
|
/* REPC/REPNC */
|
||||||
|
wait(1, 0);
|
||||||
|
in_rep = (opcode == 0x64 ? 1 : 2);
|
||||||
|
rep_c_flag = 1;
|
||||||
|
completed = 0;
|
||||||
|
handled = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x68:
|
||||||
|
wordtopush = pfq_fetchw();
|
||||||
|
wait(1, 0);
|
||||||
|
push(&wordtopush);
|
||||||
|
handled = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x69:
|
||||||
|
immediate = 0;
|
||||||
|
bits = 16;
|
||||||
|
do_mod_rm();
|
||||||
|
read_ea(0, 16);
|
||||||
|
immediate = pfq_fetchw();
|
||||||
|
mul(cpu_data & 0xFFFF, immediate);
|
||||||
|
set_reg(cpu_reg, cpu_data);
|
||||||
|
set_co_mul(16, cpu_dest != 0);
|
||||||
|
handled = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x6a:
|
||||||
|
wordtopush = sign_extend(pfq_fetchb());
|
||||||
|
push(&wordtopush);
|
||||||
|
handled = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x6b: /* IMUL reg16,reg16/mem16,imm8 */
|
||||||
|
immediate = 0;
|
||||||
|
bits = 16;
|
||||||
|
do_mod_rm();
|
||||||
|
read_ea(0, 16);
|
||||||
|
immediate = pfq_fetchb();
|
||||||
|
mul(cpu_data & 0xFFFF, immediate);
|
||||||
|
set_reg(cpu_reg, cpu_data);
|
||||||
|
set_co_mul(16, cpu_dest != 0);
|
||||||
|
handled = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x6c:
|
case 0x6c:
|
||||||
case 0x6d: /* INM dst, DW/INS dst, DX */
|
case 0x6d: /* INM dst, DW/INS dst, DX */
|
||||||
bits = 8 << (opcode & 1);
|
bits = 8 << (opcode & 1);
|
||||||
@@ -1757,28 +1849,6 @@ execx86(int cycs)
|
|||||||
handled = 1;
|
handled = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xc9: /* LEAVE/DISPOSE */
|
|
||||||
SP = BP;
|
|
||||||
BP = pop();
|
|
||||||
handled = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x62: /* BOUND r/m */
|
|
||||||
lowbound = 0;
|
|
||||||
highbound = 0;
|
|
||||||
regval = 0;
|
|
||||||
do_mod_rm();
|
|
||||||
|
|
||||||
lowbound = readmemw(easeg, cpu_state.eaaddr);
|
|
||||||
highbound = readmemw(easeg, cpu_state.eaaddr + 2);
|
|
||||||
regval = get_reg(cpu_reg);
|
|
||||||
if (lowbound > regval || highbound < regval) {
|
|
||||||
cpu_state.pc = cpu_state.oldpc;
|
|
||||||
interrupt(5);
|
|
||||||
}
|
|
||||||
handled = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xc0:
|
case 0xc0:
|
||||||
case 0xc1: /*rot imm8 */
|
case 0xc1: /*rot imm8 */
|
||||||
bits = 8 << (opcode & 1);
|
bits = 8 << (opcode & 1);
|
||||||
@@ -1868,6 +1938,12 @@ execx86(int cycs)
|
|||||||
set_ea(cpu_data);
|
set_ea(cpu_data);
|
||||||
handled = 1;
|
handled = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xc9: /* LEAVE/DISPOSE */
|
||||||
|
SP = BP;
|
||||||
|
BP = pop();
|
||||||
|
handled = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
@@ -2423,34 +2499,8 @@ execx86(int cycs)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x60: /*JO alias*/
|
case 0x60: /*JO alias*/
|
||||||
if (is186) { /* PUSHA/PUSH R*/
|
|
||||||
uint16_t orig_sp = SP;
|
|
||||||
wait(1, 0);
|
|
||||||
push(&AX);
|
|
||||||
push(&CX);
|
|
||||||
push(&DX);
|
|
||||||
push(&BX);
|
|
||||||
push(&orig_sp);
|
|
||||||
push(&BP);
|
|
||||||
push(&SI);
|
|
||||||
push(&DI);
|
|
||||||
} else
|
|
||||||
jcc(opcode, cpu_state.flags & V_FLAG);
|
|
||||||
break;
|
|
||||||
case 0x70: /*JO*/
|
case 0x70: /*JO*/
|
||||||
case 0x61: /*JNO alias*/
|
case 0x61: /*JNO alias*/
|
||||||
if (is186) { /* POPA/POP R*/
|
|
||||||
wait(9, 0);
|
|
||||||
DI = pop();
|
|
||||||
SI = pop();
|
|
||||||
BP = pop();
|
|
||||||
(void) pop(); /* former orig_sp */
|
|
||||||
BX = pop();
|
|
||||||
DX = pop();
|
|
||||||
CX = pop();
|
|
||||||
AX = pop();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x71: /*JNO*/
|
case 0x71: /*JNO*/
|
||||||
jcc(opcode, cpu_state.flags & V_FLAG);
|
jcc(opcode, cpu_state.flags & V_FLAG);
|
||||||
break;
|
break;
|
||||||
@@ -2464,13 +2514,6 @@ execx86(int cycs)
|
|||||||
case 0x74: /*JE*/
|
case 0x74: /*JE*/
|
||||||
case 0x65: /*JNE alias*/
|
case 0x65: /*JNE alias*/
|
||||||
case 0x75: /*JNE*/
|
case 0x75: /*JNE*/
|
||||||
if (is_nec && (opcode & 0xFE) == 0x64) {
|
|
||||||
/* REPC/REPNC */
|
|
||||||
wait(1, 0);
|
|
||||||
in_rep = (opcode == 0x64 ? 1 : 2);
|
|
||||||
rep_c_flag = 1;
|
|
||||||
completed = 0;
|
|
||||||
} else
|
|
||||||
jcc(opcode, cpu_state.flags & Z_FLAG);
|
jcc(opcode, cpu_state.flags & Z_FLAG);
|
||||||
break;
|
break;
|
||||||
case 0x66: /*JBE alias*/
|
case 0x66: /*JBE alias*/
|
||||||
@@ -2480,47 +2523,14 @@ execx86(int cycs)
|
|||||||
jcc(opcode, cpu_state.flags & (C_FLAG | Z_FLAG));
|
jcc(opcode, cpu_state.flags & (C_FLAG | Z_FLAG));
|
||||||
break;
|
break;
|
||||||
case 0x68: /*JS alias*/
|
case 0x68: /*JS alias*/
|
||||||
if (is186) { /* PUSH imm16 */
|
|
||||||
uint16_t wordtopush = pfq_fetchw();
|
|
||||||
wait(1, 0);
|
|
||||||
push(&wordtopush);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x78: /*JS*/
|
case 0x78: /*JS*/
|
||||||
case 0x69: /*JNS alias*/
|
case 0x69: /*JNS alias*/
|
||||||
if (is186 && opcode == 0x69) { /* IMUL reg16,reg16/mem16,imm16 */
|
|
||||||
uint16_t immediate = 0;
|
|
||||||
bits = 16;
|
|
||||||
do_mod_rm();
|
|
||||||
read_ea(0, 16);
|
|
||||||
immediate = pfq_fetchw();
|
|
||||||
mul(cpu_data & 0xFFFF, immediate);
|
|
||||||
set_reg(cpu_reg, cpu_data);
|
|
||||||
set_co_mul(16, cpu_dest != 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x79: /*JNS*/
|
case 0x79: /*JNS*/
|
||||||
jcc(opcode, cpu_state.flags & N_FLAG);
|
jcc(opcode, cpu_state.flags & N_FLAG);
|
||||||
break;
|
break;
|
||||||
case 0x6A: /*JP alias*/
|
case 0x6A: /*JP alias*/
|
||||||
if (is186) { /* PUSH imm8 */
|
|
||||||
uint16_t wordtopush = sign_extend(pfq_fetchb());
|
|
||||||
push(&wordtopush);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x7A: /*JP*/
|
case 0x7A: /*JP*/
|
||||||
case 0x6B: /*JNP alias*/
|
case 0x6B: /*JNP alias*/
|
||||||
if (is186 && opcode == 0x6B) { /* IMUL reg16,reg16/mem16,imm8 */
|
|
||||||
uint16_t immediate = 0;
|
|
||||||
bits = 16;
|
|
||||||
do_mod_rm();
|
|
||||||
read_ea(0, 16);
|
|
||||||
immediate = pfq_fetchb();
|
|
||||||
mul(cpu_data & 0xFFFF, immediate);
|
|
||||||
set_reg(cpu_reg, cpu_data);
|
|
||||||
set_co_mul(16, cpu_dest != 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x7B: /*JNP*/
|
case 0x7B: /*JNP*/
|
||||||
jcc(opcode, cpu_state.flags & P_FLAG);
|
jcc(opcode, cpu_state.flags & P_FLAG);
|
||||||
break;
|
break;
|
||||||
@@ -2734,7 +2744,7 @@ execx86(int cycs)
|
|||||||
break;
|
break;
|
||||||
case 0x9C: /*PUSHF*/
|
case 0x9C: /*PUSHF*/
|
||||||
access(33, 16);
|
access(33, 16);
|
||||||
tempw = cpu_state.flags & (is_nec && cpu_state.inside_emulation_mode ? MD_FLAG | 0x0fd7 : 0x0fd7);
|
tempw = cpu_state.flags & ((is_nec && cpu_state.inside_emulation_mode) ? (MD_FLAG | 0x0fd7) : 0x0fd7);
|
||||||
push(&tempw);
|
push(&tempw);
|
||||||
break;
|
break;
|
||||||
case 0x9D: /*POPF*/
|
case 0x9D: /*POPF*/
|
||||||
@@ -3109,12 +3119,20 @@ execx86(int cycs)
|
|||||||
|
|
||||||
case 0xD4: /*AAM*/
|
case 0xD4: /*AAM*/
|
||||||
wait(1, 0);
|
wait(1, 0);
|
||||||
|
if (is_nec) {
|
||||||
|
(void) pfq_fetchb();
|
||||||
|
cpu_src = 10;
|
||||||
|
} else
|
||||||
cpu_src = pfq_fetchb();
|
cpu_src = pfq_fetchb();
|
||||||
if (x86_div(AL, 0))
|
if (x86_div(AL, 0))
|
||||||
set_pzs(16);
|
set_pzs(16);
|
||||||
break;
|
break;
|
||||||
case 0xD5: /*AAD*/
|
case 0xD5: /*AAD*/
|
||||||
wait(1, 0);
|
wait(1, 0);
|
||||||
|
if (is_nec) {
|
||||||
|
(void) pfq_fetchb();
|
||||||
|
mul(10, AH);
|
||||||
|
} else
|
||||||
mul(pfq_fetchb(), AH);
|
mul(pfq_fetchb(), AH);
|
||||||
cpu_dest = AL;
|
cpu_dest = AL;
|
||||||
cpu_src = cpu_data;
|
cpu_src = cpu_data;
|
||||||
|
@@ -357,7 +357,7 @@ cpu_set(void)
|
|||||||
unmask_a20_in_smm = 0;
|
unmask_a20_in_smm = 0;
|
||||||
|
|
||||||
CPUID = cpu_s->cpuid_model;
|
CPUID = cpu_s->cpuid_model;
|
||||||
is8086 = (cpu_s->cpu_type > CPU_8088) && !(cpu_s->cpu_type == CPU_V20);
|
is8086 = (cpu_s->cpu_type > CPU_8088) && (cpu_s->cpu_type != CPU_V20) && (cpu_s->cpu_type != CPU_188);
|
||||||
is_nec = (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30);
|
is_nec = (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30);
|
||||||
is186 = (cpu_s->cpu_type == CPU_186) || (cpu_s->cpu_type == CPU_188) || (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30);
|
is186 = (cpu_s->cpu_type == CPU_186) || (cpu_s->cpu_type == CPU_188) || (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30);
|
||||||
is286 = (cpu_s->cpu_type >= CPU_286);
|
is286 = (cpu_s->cpu_type >= CPU_286);
|
||||||
|
Reference in New Issue
Block a user