From e65e11fe9aff3678eb08ee431a048933e96f7bc1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Sep 2019 03:33:05 +0200 Subject: [PATCH] Reworked CPU instruction segment limit and page fault checking a bit, fixes #406; Implemented the MCA enable/disable bit for the MCA WD NIC's, fixes #407; A small bug fix in dma.c. --- src/cpu/386_common.h | 21 +++++++--- src/cpu/x86_ops_mmx_mov.h | 18 ++++----- src/cpu/x86_ops_mov.h | 24 +++-------- src/cpu/x87_ops_loadstore.h | 70 ++++++++++++--------------------- src/cpu_new/386_common.h | 25 ++++++++---- src/cpu_new/386_ops.h | 8 ++-- src/cpu_new/x86_ops_mmx_mov.h | 8 ++-- src/cpu_new/x86_ops_mov.h | 24 +++-------- src/cpu_new/x87_ops_loadstore.h | 2 - src/dma.c | 45 ++++++--------------- src/mem.c | 41 ------------------- src/network/net_wd8003.c | 15 +++---- 12 files changed, 109 insertions(+), 192 deletions(-) diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index d85c3e247..428bf3118 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -103,7 +103,7 @@ break; \ } -#define CHECK_WRITE(chseg, low, high) \ +#define CHECK_WRITE_COMMON(chseg, low, high) \ if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \ { \ x86gpf("Limit check (WRITE)", 0); \ @@ -116,7 +116,10 @@ else \ x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ return 1; \ - } \ + } + +#define CHECK_WRITE(chseg, low, high) \ + CHECK_WRITE_COMMON(chseg, low, high) \ if (cr0 >> 31) { \ (void) mmutranslatereal((chseg)->base + low, 1); \ (void) mmutranslatereal((chseg)->base + high, 1); \ @@ -296,14 +299,22 @@ static __inline uint32_t geteal_mem() return readmeml(easeg,cpu_state.eaaddr); } +static __inline int seteaq_cwc(void) +{ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + return 0; +} + static __inline void seteaq(uint64_t v) { + if (seteaq_cwc()) + return; writememql(easeg, cpu_state.eaaddr, v); } -#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else { writememb386l(easeg,cpu_state.eaaddr,v); } } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v -#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else { writememwl(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].w=v -#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else { writememll(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].l=v +#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else { writememb386l(easeg,cpu_state.eaaddr,v); } } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v +#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else { writememwl(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].w=v +#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else { writememll(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].l=v #define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v); diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index 14d192244..a742941ea 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -59,8 +59,8 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } @@ -78,8 +78,8 @@ static int opMOVD_mm_l_a32(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } @@ -100,7 +100,7 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat) { uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].q = dst; CLOCK_CYCLES(2); @@ -121,7 +121,7 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat) { uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].q = dst; CLOCK_CYCLES(2); @@ -141,8 +141,8 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } @@ -161,7 +161,7 @@ static int opMOVQ_mm_q_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index 06aae8582..cf9bb82c0 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -184,7 +184,6 @@ static int opMOV_b_imm_a16(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); @@ -197,7 +196,6 @@ static int opMOV_b_imm_a32(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getbyte(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); @@ -211,7 +209,6 @@ static int opMOV_w_imm_a16(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getword(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); seteaw(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); @@ -224,7 +221,6 @@ static int opMOV_w_imm_a32(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getword(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); seteaw(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); @@ -237,7 +233,6 @@ static int opMOV_l_imm_a16(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getlong(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); seteal(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 0); @@ -250,7 +245,6 @@ static int opMOV_l_imm_a32(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getlong(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); seteal(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 1); @@ -335,7 +329,7 @@ static int opMOV_a16_AL(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); writememb(cpu_state.ea_seg->base, addr, AL); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); @@ -345,7 +339,7 @@ static int opMOV_a32_AL(uint32_t fetchdat) { uint32_t addr = getlong(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); writememb(cpu_state.ea_seg->base, addr, AL); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); @@ -355,7 +349,7 @@ static int opMOV_a16_AX(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); writememw(cpu_state.ea_seg->base, addr, AX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); @@ -365,7 +359,7 @@ static int opMOV_a32_AX(uint32_t fetchdat) { uint32_t addr = getlong(); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); writememw(cpu_state.ea_seg->base, addr, AX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); @@ -375,7 +369,7 @@ static int opMOV_a16_EAX(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); writememl(cpu_state.ea_seg->base, addr, EAX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); @@ -385,7 +379,7 @@ static int opMOV_a32_EAX(uint32_t fetchdat) { uint32_t addr = getlong(); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); writememl(cpu_state.ea_seg->base, addr, EAX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,0,1, 1); @@ -470,7 +464,6 @@ static int opMOV_b_r_a16(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(getr8(cpu_reg)); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); @@ -489,7 +482,6 @@ static int opMOV_b_r_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(getr8(cpu_reg)); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); @@ -508,7 +500,6 @@ static int opMOV_w_r_a16(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); seteaw(cpu_state.regs[cpu_reg].w); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); @@ -527,7 +518,6 @@ static int opMOV_w_r_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); seteaw(cpu_state.regs[cpu_reg].w); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); @@ -546,7 +536,6 @@ static int opMOV_l_r_a16(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); seteal(cpu_state.regs[cpu_reg].l); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 0); @@ -565,7 +554,6 @@ static int opMOV_l_r_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); seteal(cpu_state.regs[cpu_reg].l); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 1); diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index a5cb3910f..3001e8ca8 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -46,10 +46,8 @@ static int opFISTiw_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); -/* if (temp64 > 32767 || temp64 < -32768) - fatal("FISTw overflow %i\n", temp64);*/ seteaw((int16_t)temp64); CLOCK_CYCLES(29); return cpu_state.abrt; @@ -60,10 +58,8 @@ static int opFISTiw_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); -/* if (temp64 > 32767 || temp64 < -32768) - fatal("FISTw overflow %i\n", temp64);*/ seteaw((int16_t)temp64); CLOCK_CYCLES(29); return cpu_state.abrt; @@ -75,10 +71,8 @@ static int opFISTPiw_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); -/* if (temp64 > 32767 || temp64 < -32768) - fatal("FISTw overflow %i\n", temp64);*/ seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(29); @@ -90,10 +84,8 @@ static int opFISTPiw_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); -/* if (temp64 > 32767 || temp64 < -32768) - fatal("FISTw overflow %i\n", temp64);*/ seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(29); @@ -138,7 +130,7 @@ static int FBSTP_a16(uint32_t fetchdat) int c; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); tempd = ST(0); if (tempd < 0.0) tempd = -tempd; @@ -165,7 +157,7 @@ static int FBSTP_a32(uint32_t fetchdat) int c; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); tempd = ST(0); if (tempd < 0.0) tempd = -tempd; @@ -192,7 +184,7 @@ static int FISTPiq_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) temp64 = cpu_state.MM[cpu_state.TOP].q; else @@ -208,7 +200,7 @@ static int FISTPiq_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) temp64 = cpu_state.MM[cpu_state.TOP].q; else @@ -250,10 +242,8 @@ static int opFISTil_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); -/* if (temp64 > 2147483647 || temp64 < -2147483647) - fatal("FISTl out of range! %i\n", temp64);*/ seteal((int32_t)temp64); CLOCK_CYCLES(28); return cpu_state.abrt; @@ -264,10 +254,8 @@ static int opFISTil_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); -/* if (temp64 > 2147483647 || temp64 < -2147483647) - fatal("FISTl out of range! %i\n", temp64);*/ seteal((int32_t)temp64); CLOCK_CYCLES(28); return cpu_state.abrt; @@ -279,10 +267,8 @@ static int opFISTPil_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); -/* if (temp64 > 2147483647 || temp64 < -2147483647) - fatal("FISTl out of range! %i\n", temp64);*/ seteal((int32_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(28); @@ -294,10 +280,8 @@ static int opFISTPil_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); -/* if (temp64 > 2147483647 || temp64 < -2147483647) - fatal("FISTl out of range! %i\n", temp64);*/ seteal((int32_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(28); @@ -310,7 +294,7 @@ static int opFLDe_a16(uint32_t fetchdat) double t; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); CLOCK_CYCLES(6); @@ -322,7 +306,7 @@ static int opFLDe_a32(uint32_t fetchdat) double t; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); CLOCK_CYCLES(6); @@ -334,7 +318,7 @@ static int opFSTPe_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(6); @@ -345,7 +329,7 @@ static int opFSTPe_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(6); @@ -358,7 +342,7 @@ static int opFLDd_a16(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); t.i = geteaq(); if (cpu_state.abrt) return 1; x87_push(t.d); CLOCK_CYCLES(3); @@ -383,7 +367,7 @@ static int opFSTd_a16(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); CLOCK_CYCLES(8); @@ -395,7 +379,7 @@ static int opFSTd_a32(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); CLOCK_CYCLES(8); @@ -408,8 +392,7 @@ static int opFSTPd_a16(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); @@ -422,8 +405,7 @@ static int opFSTPd_a32(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); @@ -449,7 +431,7 @@ static int opFLDs_a32(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); ts.i = geteal(); if (cpu_state.abrt) return 1; x87_push((double)ts.s); CLOCK_CYCLES(3); @@ -462,7 +444,7 @@ static int opFSTs_a16(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); CLOCK_CYCLES(7); @@ -474,7 +456,7 @@ static int opFSTs_a32(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); CLOCK_CYCLES(7); @@ -487,7 +469,7 @@ static int opFSTPs_a16(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); @@ -500,7 +482,7 @@ static int opFSTPs_a32(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); diff --git a/src/cpu_new/386_common.h b/src/cpu_new/386_common.h index 84661f193..3ac390f98 100644 --- a/src/cpu_new/386_common.h +++ b/src/cpu_new/386_common.h @@ -104,7 +104,7 @@ int checkio(int port); break; \ } -#define CHECK_WRITE(chseg, low, high) \ +#define CHECK_WRITE_COMMON(chseg, low, high) \ if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \ { \ x86gpf("Limit check (WRITE)", 0); \ @@ -117,7 +117,10 @@ int checkio(int port); else \ x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ return 1; \ - } \ + } + +#define CHECK_WRITE(chseg, low, high) \ + CHECK_WRITE_COMMON(chseg, low, high) \ if (cr0 >> 31) { \ (void) mmutranslatereal((chseg)->base + low, 1); \ (void) mmutranslatereal((chseg)->base + high, 1); \ @@ -296,14 +299,22 @@ static inline uint32_t geteal_mem() return readmeml(easeg,cpu_state.eaaddr); } -static inline void seteaq(uint64_t v) +static __inline int seteaq_cwc(void) { - writememql(easeg+cpu_state.eaaddr, v); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + return 0; } -#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v -#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v -#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v +static __inline void seteaq(uint64_t v) +{ + if (seteaq_cwc()) + return; + writememql(easeg + cpu_state.eaaddr, v); +} + +#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v +#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v +#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v #define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); #define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); diff --git a/src/cpu_new/386_ops.h b/src/cpu_new/386_ops.h index 64332dd29..f2c54c0ce 100644 --- a/src/cpu_new/386_ops.h +++ b/src/cpu_new/386_ops.h @@ -456,7 +456,7 @@ const OpFn OP_TABLE(486_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -478,7 +478,7 @@ const OpFn OP_TABLE(486_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -500,7 +500,7 @@ const OpFn OP_TABLE(486_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -522,7 +522,7 @@ const OpFn OP_TABLE(486_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, diff --git a/src/cpu_new/x86_ops_mmx_mov.h b/src/cpu_new/x86_ops_mmx_mov.h index f598d5b24..e17721229 100644 --- a/src/cpu_new/x86_ops_mmx_mov.h +++ b/src/cpu_new/x86_ops_mmx_mov.h @@ -60,7 +60,7 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } @@ -79,7 +79,7 @@ static int opMOVD_mm_l_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } @@ -142,7 +142,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } @@ -161,7 +161,7 @@ static int opMOVQ_mm_q_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } diff --git a/src/cpu_new/x86_ops_mov.h b/src/cpu_new/x86_ops_mov.h index ca123607c..2c96317b7 100644 --- a/src/cpu_new/x86_ops_mov.h +++ b/src/cpu_new/x86_ops_mov.h @@ -184,7 +184,6 @@ static int opMOV_b_imm_a16(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); @@ -197,7 +196,6 @@ static int opMOV_b_imm_a32(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getbyte(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); @@ -211,7 +209,6 @@ static int opMOV_w_imm_a16(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getword(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); seteaw(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); @@ -224,7 +221,6 @@ static int opMOV_w_imm_a32(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getword(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); seteaw(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); @@ -237,7 +233,6 @@ static int opMOV_l_imm_a16(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getlong(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); seteal(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 0); @@ -250,7 +245,6 @@ static int opMOV_l_imm_a32(uint32_t fetchdat) ILLEGAL_ON((rmdat & 0x38) != 0); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getlong(); if (cpu_state.abrt) return 1; - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); seteal(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 1); @@ -335,7 +329,7 @@ static int opMOV_a16_AL(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); writememb(cpu_state.ea_seg->base, addr, AL); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); @@ -345,7 +339,7 @@ static int opMOV_a32_AL(uint32_t fetchdat) { uint32_t addr = getlong(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); writememb(cpu_state.ea_seg->base, addr, AL); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); @@ -355,7 +349,7 @@ static int opMOV_a16_AX(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); writememw(cpu_state.ea_seg->base, addr, AX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); @@ -365,7 +359,7 @@ static int opMOV_a32_AX(uint32_t fetchdat) { uint32_t addr = getlong(); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); writememw(cpu_state.ea_seg->base, addr, AX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); @@ -375,7 +369,7 @@ static int opMOV_a16_EAX(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); writememl(cpu_state.ea_seg->base, addr, EAX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); @@ -385,7 +379,7 @@ static int opMOV_a32_EAX(uint32_t fetchdat) { uint32_t addr = getlong(); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); writememl(cpu_state.ea_seg->base, addr, EAX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,0,1, 1); @@ -470,7 +464,6 @@ static int opMOV_b_r_a16(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(getr8(cpu_reg)); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); @@ -489,7 +482,6 @@ static int opMOV_b_r_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(getr8(cpu_reg)); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); @@ -508,7 +500,6 @@ static int opMOV_w_r_a16(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); seteaw(cpu_state.regs[cpu_reg].w); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); @@ -527,7 +518,6 @@ static int opMOV_w_r_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); seteaw(cpu_state.regs[cpu_reg].w); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); @@ -546,7 +536,6 @@ static int opMOV_l_r_a16(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); seteal(cpu_state.regs[cpu_reg].l); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 0); @@ -565,7 +554,6 @@ static int opMOV_l_r_a32(uint32_t fetchdat) else { SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); seteal(cpu_state.regs[cpu_reg].l); CLOCK_CYCLES(is486 ? 1 : 2); PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 1); diff --git a/src/cpu_new/x87_ops_loadstore.h b/src/cpu_new/x87_ops_loadstore.h index ae7e8ae1a..2ed5aec5a 100644 --- a/src/cpu_new/x87_ops_loadstore.h +++ b/src/cpu_new/x87_ops_loadstore.h @@ -391,7 +391,6 @@ static int opFSTPd_a16(uint32_t fetchdat) FP_ENTER(); fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); @@ -405,7 +404,6 @@ static int opFSTPd_a32(uint32_t fetchdat) FP_ENTER(); fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); diff --git a/src/dma.c b/src/dma.c index 1ed1bced2..59b4cef71 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1,40 +1,22 @@ /* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the VARCem Project. + * This file is part of the 86Box distribution. * * Implementation of the Intel DMA controllers. * - * Version: @(#)dma.c 1.0.5 2019/02/07 + * Version: @(#)dma.c 1.0.6 2019/09/21 * - * Authors: Fred N. van Kempen, + * Authors: Sarah Walker, * Miran Grca, - * Sarah Walker, + * Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #include #include @@ -945,10 +927,7 @@ dma_ps2_run(int channel) int dma_mode(int channel) { - if (channel < 4) - return(dma[channel].mode); - else - return(dma[channel & 3].mode); + return(dma[channel].mode); } diff --git a/src/mem.c b/src/mem.c index 1674acc07..05dfaa7ba 100644 --- a/src/mem.c +++ b/src/mem.c @@ -532,12 +532,6 @@ writemembl(uint32_t addr, uint8_t val) uint8_t readmemb386l(uint32_t seg, uint32_t addr) { - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - - return -1; - } - return readmembl(addr + seg); } @@ -545,11 +539,6 @@ readmemb386l(uint32_t seg, uint32_t addr) void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) { - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return; - } - writemembl(addr + seg, val); } @@ -560,11 +549,6 @@ readmemwl(uint32_t seg, uint32_t addr) mem_mapping_t *map; uint32_t addr2 = mem_logical_addr = seg + addr; - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return -1; - } - if (addr2 & 1) { if (!cpu_cyrix_alignment || (addr2 & 7) == 7) sub_cycles(timing_misaligned); @@ -612,11 +596,6 @@ writememwl(uint32_t seg, uint32_t addr, uint16_t val) mem_mapping_t *map; uint32_t addr2 = mem_logical_addr = seg + addr; - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return; - } - if (addr2 & 1) { if (!cpu_cyrix_alignment || (addr2 & 7) == 7) sub_cycles(timing_misaligned); @@ -672,11 +651,6 @@ readmemll(uint32_t seg, uint32_t addr) mem_mapping_t *map; uint32_t addr2 = mem_logical_addr = seg + addr; - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return -1; - } - if (addr2 & 3) { if (!cpu_cyrix_alignment || (addr2 & 7) > 4) sub_cycles(timing_misaligned); @@ -723,11 +697,6 @@ writememll(uint32_t seg, uint32_t addr, uint32_t val) mem_mapping_t *map; uint32_t addr2 = mem_logical_addr = seg + addr; - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return; - } - if (addr2 & 3) { if (!cpu_cyrix_alignment || (addr2 & 7) > 4) sub_cycles(timing_misaligned); @@ -784,11 +753,6 @@ readmemql(uint32_t seg, uint32_t addr) mem_mapping_t *map; uint32_t addr2 = mem_logical_addr = seg + addr; - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return -1; - } - if (addr2 & 7) { sub_cycles(timing_misaligned); if ((addr2 & 0xfff) > 0xff8) { @@ -823,11 +787,6 @@ writememql(uint32_t seg, uint32_t addr, uint64_t val) mem_mapping_t *map; uint32_t addr2 = mem_logical_addr = seg + addr; - if (seg == (uint32_t) -1) { - x86gpf("NULL segment", 0); - return; - } - if (addr2 & 7) { sub_cycles(timing_misaligned); if ((addr2 & 0xfff) > 0xff8) { diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 39a2b5a71..2148a2142 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -11,15 +11,15 @@ * - SMC/WD 8013EBT (ISA 16-bit); * - SMC/WD 8013EP/A (MCA). * - * Version: @(#)net_wd8003.c 1.0.5 2018/10/22 + * Version: @(#)net_wd8003.c 1.0.6 2019/09/21 * * Authors: Fred N. van Kempen, * TheCollector1995, * Miran Grca, * Peter Grehan, * - * Copyright 2017,2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2016-2019 Miran Grca. * Portions Copyright (C) 2002 MandrakeSoft S.A. * * This program is free software; you can redistribute it and/or modify @@ -613,13 +613,14 @@ wd_mca_write(int port, uint8_t val, void *priv) /* Initialize the device if fully configured. */ /* Register (new) I/O handler. */ - wd_io_set(dev, dev->base_address); + if (dev->pos_regs[2] & 0x01) + wd_io_set(dev, dev->base_address); mem_mapping_set_addr(&dev->ram_mapping, dev->ram_addr, dev->ram_size); - if (dev->msr & WE_MSR_ENABLE_RAM) + + mem_mapping_disable(&dev->ram_mapping); + if ((dev->msr & WE_MSR_ENABLE_RAM) && (dev->pos_regs[2] & 0x01)) mem_mapping_enable(&dev->ram_mapping); - else - mem_mapping_disable(&dev->ram_mapping); wdlog("%s: attached IO=0x%X IRQ=%d, RAM addr=0x%06x\n", dev->name, dev->base_address, dev->irq, dev->ram_addr);