From 754058e2e509298f70107fc1648099251ba5fa47 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Aug 2022 23:40:11 +0200 Subject: [PATCH] AAM and AAD instruction fixes, fixes #2551. --- src/cpu/386_common.c | 6 ++++++ src/cpu/cpu.c | 8 +++++--- src/cpu/cpu.h | 1 + src/cpu/x86.h | 5 +++-- src/cpu/x86_ops_bcd.h | 9 ++++++++- src/cpu/x86seg.c | 8 ++++++++ 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 6c09e588a..92360a248 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1481,10 +1481,16 @@ checkio(uint32_t port) } +#ifdef OLD_DIVEXCP #define divexcp() { \ x386_common_log("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ x86_int(0); \ } +#else +#define divexcp() { \ + x86de(NULL, 0); \ +} +#endif int diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 68cf6c38f..36d92605f 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -382,10 +382,10 @@ cpu_set(void) is_am486 = (cpu_s->cpu_type == CPU_ENH_Am486DX); is_am486dxl = (cpu_s->cpu_type == CPU_Am486DXL); - is6117 = !strcmp(cpu_f->manufacturer, "ALi"); + is6117 = !strcmp(cpu_f->manufacturer, "ALi"); - cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); - cpu_iscyrix = !strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST"); + cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); + cpu_iscyrix = !strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST"); /* SL-Enhanced Intel 486s have the same SMM save state table layout as Pentiums, and the WinChip datasheet claims those are Pentium-compatible as well. AMD Am486DXL/DXL2 also has compatible SMM, or would if not for it's different SMBase*/ @@ -398,6 +398,8 @@ cpu_set(void) is_cxsmm = (!strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST")) && (cpu_s->cpu_type >= CPU_Cx486S); + cpu_isintel = cpu_isintel || !strcmp(cpu_f->manufacturer, "AMD"); + hasfpu = (fpu_type != FPU_NONE); hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index b6998162f..964c456eb 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -669,6 +669,7 @@ extern void hardresetx86(void); extern void x86_int(int num); extern void x86_int_sw(int num); extern int x86_int_sw_rm(int num); +extern void x86de(char *s, uint16_t error); extern void x86gpf(char *s, uint16_t error); extern void x86np(char *s, uint16_t error); extern void x86ss(char *s, uint16_t error); diff --git a/src/cpu/x86.h b/src/cpu/x86.h index b9726dc57..32a3317ea 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -1,4 +1,4 @@ -#define ABRT_MASK 0x7f +#define ABRT_MASK 0x3f /*An 'expected' exception is one that would be expected to occur on every execution of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is one that would be unlikely to occur on the next exception, eg a page fault may be @@ -71,7 +71,8 @@ enum ABRT_NP = 0xB, ABRT_SS = 0xC, ABRT_GPF = 0xD, - ABRT_PF = 0xE + ABRT_PF = 0xE, + ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ }; diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index 385d63cd7..b37b6a6df 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -31,7 +31,14 @@ static int opAAD(uint32_t fetchdat) static int opAAM(uint32_t fetchdat) { int base = getbytef(); - if (!base || !cpu_isintel) base = 10; + + if (base == 0) { + x86de(NULL, 0); + return 1; + } + + if (!cpu_isintel) base = 10; + AH = AL / base; AL %= base; setznp16(AX); diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index e103f0247..c9398dd69 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -165,6 +165,14 @@ x86_doabrt(int x86_abrt) } +void +x86de(char *s, uint16_t error) +{ + cpu_state.abrt = ABRT_DE; + abrt_error = error; +} + + void x86gpf(char *s, uint16_t error) {