From 81e24b9cb51260723e9395b408817b2c6f930b16 Mon Sep 17 00:00:00 2001 From: TomW Date: Sun, 27 Apr 2014 11:40:03 +0100 Subject: [PATCH] Register operands on BOUND/LEA/LDS/LES/LFS/LGS/LSS now cause invalid opcode faults. Fixes NTVDM. --- src/386_ops.h | 11 +++++++++++ src/x86_ops_misc.h | 4 ++++ src/x86_ops_mov.h | 4 ++++ src/x86_ops_mov_seg.h | 12 ++++++++++++ 4 files changed, 31 insertions(+) diff --git a/src/386_ops.h b/src/386_ops.h index 18fbca1..b6619e0 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -3,6 +3,17 @@ OpFn *x86_opcodes; OpFn *x86_opcodes_0f; +#define ILLEGAL_ON(cond) \ + do \ + { \ + if ((cond)) \ + { \ + pc = oldpc; \ + x86illegal(); \ + return 0; \ + } \ + } while (0) + static inline void PUSH_W(uint16_t val) { if (stack32) diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index a7ee9fd..ddabb06 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -539,6 +539,7 @@ static int opBOUND_w_a16(uint32_t fetchdat) int16_t low, high; fetch_ea_16(fetchdat); + ILLEGAL_ON(mod == 3); low = geteaw(); high = readmemw(easeg, eaaddr + 2); if (abrt) return 0; @@ -555,6 +556,7 @@ static int opBOUND_w_a32(uint32_t fetchdat) int16_t low, high; fetch_ea_32(fetchdat); + ILLEGAL_ON(mod == 3); low = geteaw(); high = readmemw(easeg, eaaddr + 2); if (abrt) return 0; @@ -572,6 +574,7 @@ static int opBOUND_l_a16(uint32_t fetchdat) int32_t low, high; fetch_ea_16(fetchdat); + ILLEGAL_ON(mod == 3); low = geteal(); high = readmeml(easeg, eaaddr + 4); if (abrt) return 0; @@ -588,6 +591,7 @@ static int opBOUND_l_a32(uint32_t fetchdat) int32_t low, high; fetch_ea_32(fetchdat); + ILLEGAL_ON(mod == 3); low = geteal(); high = readmeml(easeg, eaaddr + 4); if (abrt) return 0; diff --git a/src/x86_ops_mov.h b/src/x86_ops_mov.h index ce00745..40f6f34 100644 --- a/src/x86_ops_mov.h +++ b/src/x86_ops_mov.h @@ -306,6 +306,7 @@ static int opMOV_a32_EAX(uint32_t fetchdat) static int opLEA_w_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); + ILLEGAL_ON(mod == 3); regs[reg].w = eaaddr; cycles -= timing_rr; return 0; @@ -313,6 +314,7 @@ static int opLEA_w_a16(uint32_t fetchdat) static int opLEA_w_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); + ILLEGAL_ON(mod == 3); regs[reg].w = eaaddr; cycles -= timing_rr; return 0; @@ -321,6 +323,7 @@ static int opLEA_w_a32(uint32_t fetchdat) static int opLEA_l_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); + ILLEGAL_ON(mod == 3); regs[reg].l = eaaddr & 0xffff; cycles -= timing_rr; return 0; @@ -328,6 +331,7 @@ static int opLEA_l_a16(uint32_t fetchdat) static int opLEA_l_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); + ILLEGAL_ON(mod == 3); regs[reg].l = eaaddr; cycles -= timing_rr; return 0; diff --git a/src/x86_ops_mov_seg.h b/src/x86_ops_mov_seg.h index 9ec20de..75bbe4a 100644 --- a/src/x86_ops_mov_seg.h +++ b/src/x86_ops_mov_seg.h @@ -219,6 +219,7 @@ static int opLDS_w_a16(uint32_t fetchdat) uint16_t addr, seg; fetch_ea_16(fetchdat); + ILLEGAL_ON(mod == 3); addr = readmemw(easeg, eaaddr); seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; loadseg(seg, &_ds); if (abrt) return 0; @@ -233,6 +234,7 @@ static int opLDS_w_a32(uint32_t fetchdat) uint16_t addr, seg; fetch_ea_32(fetchdat); + ILLEGAL_ON(mod == 3); addr = readmemw(easeg, eaaddr); seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; loadseg(seg, &_ds); if (abrt) return 0; @@ -248,6 +250,7 @@ static int opLDS_l_a16(uint32_t fetchdat) uint16_t seg; fetch_ea_16(fetchdat); + ILLEGAL_ON(mod == 3); addr = readmeml(easeg, eaaddr); seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; loadseg(seg, &_ds); if (abrt) return 0; @@ -263,6 +266,7 @@ static int opLDS_l_a32(uint32_t fetchdat) uint16_t seg; fetch_ea_32(fetchdat); + ILLEGAL_ON(mod == 3); addr = readmeml(easeg, eaaddr); seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; loadseg(seg, &_ds); if (abrt) return 0; @@ -278,6 +282,7 @@ static int opLSS_w_a16(uint32_t fetchdat) uint16_t addr, seg; fetch_ea_16(fetchdat); + ILLEGAL_ON(mod == 3); addr = readmemw(easeg, eaaddr); seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; loadseg(seg, &_ss); if (abrt) return 0; @@ -292,6 +297,7 @@ static int opLSS_w_a32(uint32_t fetchdat) uint16_t addr, seg; fetch_ea_32(fetchdat); + ILLEGAL_ON(mod == 3); addr = readmemw(easeg, eaaddr); seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; loadseg(seg, &_ss); if (abrt) return 0; @@ -307,6 +313,7 @@ static int opLSS_l_a16(uint32_t fetchdat) uint16_t seg; fetch_ea_16(fetchdat); + ILLEGAL_ON(mod == 3); addr = readmeml(easeg, eaaddr); seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; loadseg(seg, &_ss); if (abrt) return 0; @@ -322,6 +329,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t seg; fetch_ea_32(fetchdat); + ILLEGAL_ON(mod == 3); addr = readmeml(easeg, eaaddr); seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; loadseg(seg, &_ss); if (abrt) return 0; @@ -338,6 +346,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t addr, seg; \ \ fetch_ea_16(fetchdat); \ + ILLEGAL_ON(mod == 3); \ addr = readmemw(easeg, eaaddr); \ seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; \ loadseg(seg, &sel); if (abrt) return 0; \ @@ -352,6 +361,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t addr, seg; \ \ fetch_ea_32(fetchdat); \ + ILLEGAL_ON(mod == 3); \ addr = readmemw(easeg, eaaddr); \ seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; \ loadseg(seg, &sel); if (abrt) return 0; \ @@ -367,6 +377,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t seg; \ \ fetch_ea_16(fetchdat); \ + ILLEGAL_ON(mod == 3); \ addr = readmeml(easeg, eaaddr); \ seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; \ loadseg(seg, &sel); if (abrt) return 0; \ @@ -382,6 +393,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t seg; \ \ fetch_ea_32(fetchdat); \ + ILLEGAL_ON(mod == 3); \ addr = readmeml(easeg, eaaddr); \ seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; \ loadseg(seg, &sel); if (abrt) return 0; \