More V20/V30 fixes.

This commit is contained in:
OBattler
2022-10-26 16:45:17 +02:00
parent d8eb5c7ff4
commit e6321d952a
2 changed files with 116 additions and 98 deletions

View File

@@ -313,7 +313,7 @@ readmemw(uint32_t s, uint16_t a)
else {
wait(4, 1);
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;
@@ -385,7 +385,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v)
else {
write_mem_b(addr, v & 0xff);
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);
}
@@ -794,7 +794,7 @@ seteaq(uint64_t val)
static void
push(uint16_t *val)
{
if (is186 && SP == 1) {
if ((is186 && !is_nec) && (SP == 1)) {
writememw(ss - 1, 0, *val);
SP = cpu_state.eaaddr = 0xFFFF;
return;
@@ -963,7 +963,7 @@ interrupt(uint16_t addr)
pfq_clear();
ovr_seg = NULL;
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);
cpu_state.flags &= ~(I_FLAG | T_FLAG);
access(40, 16);
@@ -1653,7 +1653,8 @@ execx86(int cycs)
int8_t nibble_result_s;
uint16_t addr, tempw, new_cs, new_ip;
uint16_t tempw_int, size, tempbp, lowbound;
uint16_t highbound, regval;
uint16_t highbound, regval, orig_sp, wordtopush;
uint16_t immediate;
int bits;
uint32_t dest_seg, i, carry, nibble;
uint32_t srcseg, byteaddr;
@@ -1679,6 +1680,97 @@ execx86(int cycs)
// pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode);
if (is186) {
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 0x6d: /* INM dst, DW/INS dst, DX */
bits = 8 << (opcode & 1);
@@ -1757,28 +1849,6 @@ execx86(int cycs)
handled = 1;
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 0xc1: /*rot imm8 */
bits = 8 << (opcode & 1);
@@ -1868,6 +1938,12 @@ execx86(int cycs)
set_ea(cpu_data);
handled = 1;
break;
case 0xc9: /* LEAVE/DISPOSE */
SP = BP;
BP = pop();
handled = 1;
break;
}
}
if (!handled) {
@@ -2423,34 +2499,8 @@ execx86(int cycs)
break;
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 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*/
jcc(opcode, cpu_state.flags & V_FLAG);
break;
@@ -2464,14 +2514,7 @@ execx86(int cycs)
case 0x74: /*JE*/
case 0x65: /*JNE alias*/
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;
case 0x66: /*JBE alias*/
case 0x76: /*JBE*/
@@ -2480,47 +2523,14 @@ execx86(int cycs)
jcc(opcode, cpu_state.flags & (C_FLAG | Z_FLAG));
break;
case 0x68: /*JS alias*/
if (is186) { /* PUSH imm16 */
uint16_t wordtopush = pfq_fetchw();
wait(1, 0);
push(&wordtopush);
break;
}
case 0x78: /*JS*/
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*/
jcc(opcode, cpu_state.flags & N_FLAG);
break;
case 0x6A: /*JP alias*/
if (is186) { /* PUSH imm8 */
uint16_t wordtopush = sign_extend(pfq_fetchb());
push(&wordtopush);
break;
}
case 0x7A: /*JP*/
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*/
jcc(opcode, cpu_state.flags & P_FLAG);
break;
@@ -2734,7 +2744,7 @@ execx86(int cycs)
break;
case 0x9C: /*PUSHF*/
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);
break;
case 0x9D: /*POPF*/
@@ -3109,13 +3119,21 @@ execx86(int cycs)
case 0xD4: /*AAM*/
wait(1, 0);
cpu_src = pfq_fetchb();
if (is_nec) {
(void) pfq_fetchb();
cpu_src = 10;
} else
cpu_src = pfq_fetchb();
if (x86_div(AL, 0))
set_pzs(16);
break;
case 0xD5: /*AAD*/
wait(1, 0);
mul(pfq_fetchb(), AH);
if (is_nec) {
(void) pfq_fetchb();
mul(10, AH);
} else
mul(pfq_fetchb(), AH);
cpu_dest = AL;
cpu_src = cpu_data;
add(8);

View File

@@ -357,7 +357,7 @@ cpu_set(void)
unmask_a20_in_smm = 0;
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);
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);