From 03b5a44aca8812c0b26948064510d3fa6bffc0d2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Feb 2019 21:17:56 +0000 Subject: [PATCH] More CPU sanitisation. --- src/386_common.c | 7 ++ src/808x.c | 41 ++++----- src/cpu.c | 4 +- src/cpu.h | 2 + src/gameport.c | 1 + src/ibm.h | 214 +------------------------------------------- src/mcr.c | 1 + src/mem.h | 2 + src/nvr.c | 1 + src/pc.c | 1 - src/sound_opl.c | 1 + src/sound_pas16.c | 1 + src/x86.h | 219 ++++++++++++++++++++++++++++++++++++++++++++-- src/x86seg.c | 5 -- 14 files changed, 248 insertions(+), 252 deletions(-) diff --git a/src/386_common.c b/src/386_common.c index d1c9326..df19e14 100644 --- a/src/386_common.c +++ b/src/386_common.c @@ -4,6 +4,11 @@ #include "x86_flags.h" #include "codegen.h" +x86seg gdt, ldt, idt, tr; + +uint32_t cr2, cr3, cr4; +uint32_t dr[8]; + uint32_t use32; int stack32; int optype; @@ -22,6 +27,8 @@ int fpucount=0; uint16_t cpu_cur_status = 0; +uint32_t pccache; +uint8_t *pccache2; void x86_int(int num) { diff --git a/src/808x.c b/src/808x.c index 83d06b6..cba4273 100644 --- a/src/808x.c +++ b/src/808x.c @@ -40,28 +40,31 @@ int ins=0; int is8086=0; -int nextcyc=0; -int memcycs; +static uint32_t oldds; +uint32_t oldss; + +static int nextcyc=0; +static int memcycs; static int cycdiff; -void FETCHCOMPLETE(); +static void FETCHCOMPLETE(); #define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint) -uint8_t readmemb(uint32_t a) +static uint8_t readmemb(uint32_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=4; if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } -uint8_t readmembf(uint32_t a) +static uint8_t readmembf(uint32_t a) { if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } -uint16_t readmemw(uint32_t s, uint16_t a) +static uint16_t readmemw(uint32_t s, uint16_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=(8>>is8086); if ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) return readmemwl(s+a); @@ -77,32 +80,28 @@ void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; } cpu_rm=rmdat&7; \ if (cpu_mod!=3) fetcheal(); } -void writememb(uint32_t a, uint8_t v) +static void writememb(uint32_t a, uint8_t v) { memcycs+=4; if (writelookup2[(a)>>12]==-1) writemembl(a,v); else *(uint8_t *)(writelookup2[a >> 12] + a) = v; } -void writememw(uint32_t s, uint32_t a, uint16_t v) +static void writememw(uint32_t s, uint32_t a, uint16_t v) { memcycs+=(8>>is8086); if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s+a,v); else *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v; } -void writememl(uint32_t s, uint32_t a, uint32_t v) -{ - if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememll(s+a,v); - else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v; -} //#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a)) -int fetchcycles=0,memcycs,fetchclocks; +static int fetchcycles=0,fetchclocks; + +static uint8_t prefetchqueue[6]; +static uint16_t prefetchpc; +static int prefetchw=0; -uint8_t prefetchqueue[6]; -uint16_t prefetchpc; -int prefetchw=0; static inline uint8_t FETCH() { uint8_t temp; @@ -187,7 +186,7 @@ static inline void FETCHADD(int c) // if (fetchcycles>24) fetchcycles=24; } -void FETCHCOMPLETE() +static void FETCHCOMPLETE() { // pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw); if (!(fetchcycles&3)) return; @@ -604,7 +603,6 @@ void resetx86() use32=0; cpu_cur_status = 0; stack32=0; - cpu_hasCX8 = 0; // i86_Reset(); // cs=0xFFFF0; msw=0; @@ -665,7 +663,6 @@ void softresetx86() cr4 = 0; cpu_state.eflags=0; cgate32=0; - cpu_hasCX8 = 0; if (AT) { loadcs(0xF000); @@ -845,7 +842,7 @@ int current_diff = 0; between the two frequencies, use fixed point arithmetic when updating TSC.*/ static uint64_t tsc_frac = 0; -void clockhardware() +static void clockhardware() { int diff = cycdiff - cycles - current_diff; @@ -864,7 +861,7 @@ static int takeint = 0; int firstrepcycle=1; -void rep(int fv) +static void rep(int fv) { uint8_t temp; int c=CX; diff --git a/src/cpu.c b/src/cpu.c index 29d4da2..3963646 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -99,11 +99,11 @@ int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; int is386; +int is486; +int CPUID; uint64_t tsc = 0; -int is486; - int timing_rr; int timing_mr, timing_mrl; int timing_rm, timing_rml; diff --git a/src/cpu.h b/src/cpu.h index 02a1340..ba22f12 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -143,6 +143,8 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv); uint8_t cyrix_read(uint16_t addr, void *priv); extern int is8086; +extern int is486; +extern int CPUID; void cpu_CPUID(); void cpu_RDMSR(); diff --git a/src/gameport.c b/src/gameport.c index fbf142a..d8eb6c4 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -4,6 +4,7 @@ #include "io.h" #include "plat-joystick.h" #include "timer.h" +#include "x86.h" #include "gameport.h" #include "joystick_ch_flightstick_pro.h" diff --git a/src/ibm.h b/src/ibm.h index 74498ef..ca63e29 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -63,221 +63,9 @@ extern int readlnum,writelnum; /*Processor*/ -#define EAX cpu_state.regs[0].l -#define ECX cpu_state.regs[1].l -#define EDX cpu_state.regs[2].l -#define EBX cpu_state.regs[3].l -#define ESP cpu_state.regs[4].l -#define EBP cpu_state.regs[5].l -#define ESI cpu_state.regs[6].l -#define EDI cpu_state.regs[7].l -#define AX cpu_state.regs[0].w -#define CX cpu_state.regs[1].w -#define DX cpu_state.regs[2].w -#define BX cpu_state.regs[3].w -#define SP cpu_state.regs[4].w -#define BP cpu_state.regs[5].w -#define SI cpu_state.regs[6].w -#define DI cpu_state.regs[7].w -#define AL cpu_state.regs[0].b.l -#define AH cpu_state.regs[0].b.h -#define CL cpu_state.regs[1].b.l -#define CH cpu_state.regs[1].b.h -#define DL cpu_state.regs[2].b.l -#define DH cpu_state.regs[2].b.h -#define BL cpu_state.regs[3].b.l -#define BH cpu_state.regs[3].b.h +extern int ins, output, timetolive; -typedef union -{ - uint32_t l; - uint16_t w; - struct - { - uint8_t l,h; - } b; -} x86reg; - -typedef struct -{ - uint32_t base; - uint32_t limit; - uint8_t access; - uint16_t seg; - uint32_t limit_low, limit_high; - int checked; /*Non-zero if selector is known to be valid*/ -} x86seg; - -typedef union MMX_REG -{ - uint64_t q; - int64_t sq; - uint32_t l[2]; - int32_t sl[2]; - uint16_t w[4]; - int16_t sw[4]; - uint8_t b[8]; - int8_t sb[8]; - float f[2]; -} MMX_REG; - -struct -{ - x86reg regs[8]; - - uint8_t tag[8]; - - x86seg *ea_seg; - uint32_t eaaddr; - - int flags_op; - uint32_t flags_res; - uint32_t flags_op1, flags_op2; - - uint32_t pc; - uint32_t oldpc; - uint32_t op32; - - int TOP; - - union - { - struct - { - int8_t rm, mod, reg; - } rm_mod_reg; - uint32_t rm_mod_reg_data; - } rm_data; - - int8_t ssegs; - int8_t ismmx; - int8_t abrt; - - int _cycles; - int cpu_recomp_ins; - - uint16_t npxs, npxc; - - double ST[8]; - - uint16_t MM_w4[8]; - - MMX_REG MM[8]; - - uint32_t old_fp_control, new_fp_control; -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ - uint16_t old_fp_control2, new_fp_control2; -#endif -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ - uint32_t trunc_fp_control; -#endif - x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; - - union - { - uint32_t l; - uint16_t w; - } CR0; - - uint16_t flags, eflags; -} cpu_state; - -#define cycles cpu_state._cycles - -extern uint16_t cpu_cur_status; - -/*The flags below must match in both cpu_cur_status and block->status for a block - to be valid*/ -#define CPU_STATUS_USE32 (1 << 0) -#define CPU_STATUS_STACK32 (1 << 1) -#define CPU_STATUS_PMODE (1 << 2) -#define CPU_STATUS_V86 (1 << 3) -#define CPU_STATUS_FLAGS 0xff - -/*If the flags below are set in cpu_cur_status, they must be set in block->status. - Otherwise they are ignored*/ -#define CPU_STATUS_NOTFLATDS (1 << 8) -#define CPU_STATUS_NOTFLATSS (1 << 9) -#define CPU_STATUS_MASK 0xff00 - -#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; - -COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128); - -#define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) - -uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; - -extern int ins,output; - -x86seg gdt,ldt,idt,tr; -x86seg _oldds; - -uint32_t pccache; -uint8_t *pccache2; -/*Segments - - _cs,_ds,_es,_ss are the segment structures - CS,DS,ES,SS is the 16-bit data - cs,ds,es,ss are defines to the bases*/ -#define CS cpu_state.seg_cs.seg -#define DS cpu_state.seg_ds.seg -#define ES cpu_state.seg_es.seg -#define SS cpu_state.seg_ss.seg -#define FS cpu_state.seg_fs.seg -#define GS cpu_state.seg_gs.seg -#define cs cpu_state.seg_cs.base -#define ds cpu_state.seg_ds.base -#define es cpu_state.seg_es.base -#define ss cpu_state.seg_ss.base -//#define seg_fs _fs.base -#define gs cpu_state.seg_gs.base - -#define CPL ((cpu_state.seg_cs.access>>5)&3) - -int loadseg(uint16_t seg, x86seg *s); -void loadcs(uint16_t seg); - -#define cr0 cpu_state.CR0.l -#define msw cpu_state.CR0.w - -uint32_t cr2, cr3, cr4; -uint32_t dr[8]; - -#define C_FLAG 0x0001 -#define P_FLAG 0x0004 -#define A_FLAG 0x0010 -#define Z_FLAG 0x0040 -#define N_FLAG 0x0080 -#define T_FLAG 0x0100 -#define I_FLAG 0x0200 -#define D_FLAG 0x0400 -#define V_FLAG 0x0800 -#define NT_FLAG 0x4000 -#define VM_FLAG 0x0002 /*In EFLAGS*/ -#define VIF_FLAG 0x0008 /*In EFLAGS*/ -#define VIP_FLAG 0x0010 /*In EFLAGS*/ - -#define WP_FLAG 0x10000 /*In CR0*/ - -#define CR4_VME (1 << 0) -#define CR4_PVI (1 << 1) -#define CR4_PSE (1 << 4) - -#define IOPL ((cpu_state.flags >> 12) & 3) - -#define IOPLp ((!(msw&1)) || (CPL<=IOPL)) -//#define IOPLp 1 - -//#define IOPLV86 ((!(msw&1)) || (CPL<=IOPL)) extern int cycles_lost; -extern int is486; -extern int insc; -extern int fpucount; -extern float mips,flops; -extern int cgate16; -extern int CPUID; - -extern int cpl_override; /*Timer*/ typedef struct PIT_nr diff --git a/src/mcr.c b/src/mcr.c index 81293c2..6c7d746 100644 --- a/src/mcr.c +++ b/src/mcr.c @@ -2,6 +2,7 @@ This chip was used as part of many 386 chipsets It controls memory addressing and shadowing*/ #include "ibm.h" +#include "x86.h" int nextreg6; uint8_t mcr22; diff --git a/src/mem.h b/src/mem.h index e55aece..79d0da4 100644 --- a/src/mem.h +++ b/src/mem.h @@ -1,6 +1,8 @@ #ifndef _MEM_H_ #define _MEM_H_ +#include "x86.h" + typedef struct mem_mapping_t { struct mem_mapping_t *prev, *next; diff --git a/src/nvr.c b/src/nvr.c index edabac9..fe89377 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -11,6 +11,7 @@ #include "model.h" #include "nmi.h" #include "t1000.h" +#include "x86.h" int oldromset; int nvrmask=63; diff --git a/src/pc.c b/src/pc.c index 49d58ee..a259bc9 100644 --- a/src/pc.c +++ b/src/pc.c @@ -66,7 +66,6 @@ int start_in_fullscreen = 0; static int override_drive_a = 0, override_drive_b = 0; -int CPUID; int vid_resize, vid_api; int cycles_lost = 0; diff --git a/src/sound_opl.c b/src/sound_opl.c index 33f6fd9..368a1d8 100644 --- a/src/sound_opl.c +++ b/src/sound_opl.c @@ -5,6 +5,7 @@ #include "sound.h" #include "sound_opl.h" #include "sound_dbopl.h" +#include "x86.h" /*Interfaces between PCem and the actual OPL emulator*/ diff --git a/src/sound_pas16.c b/src/sound_pas16.c index 7f44fe7..d55b921 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -12,6 +12,7 @@ #include "sound_pas16.h" #include "sound_sb_dsp.h" #include "timer.h" +#include "x86.h" /* Original PAS uses 2 x OPL2 diff --git a/src/x86.h b/src/x86.h index a656124..a9365c0 100644 --- a/src/x86.h +++ b/src/x86.h @@ -1,32 +1,226 @@ +#ifndef _X86_H_ +#define _X86_H_ + +#define EAX cpu_state.regs[0].l +#define ECX cpu_state.regs[1].l +#define EDX cpu_state.regs[2].l +#define EBX cpu_state.regs[3].l +#define ESP cpu_state.regs[4].l +#define EBP cpu_state.regs[5].l +#define ESI cpu_state.regs[6].l +#define EDI cpu_state.regs[7].l +#define AX cpu_state.regs[0].w +#define CX cpu_state.regs[1].w +#define DX cpu_state.regs[2].w +#define BX cpu_state.regs[3].w +#define SP cpu_state.regs[4].w +#define BP cpu_state.regs[5].w +#define SI cpu_state.regs[6].w +#define DI cpu_state.regs[7].w +#define AL cpu_state.regs[0].b.l +#define AH cpu_state.regs[0].b.h +#define CL cpu_state.regs[1].b.l +#define CH cpu_state.regs[1].b.h +#define DL cpu_state.regs[2].b.l +#define DH cpu_state.regs[2].b.h +#define BL cpu_state.regs[3].b.l +#define BH cpu_state.regs[3].b.h + +typedef union +{ + uint32_t l; + uint16_t w; + struct + { + uint8_t l,h; + } b; +} x86reg; + +typedef struct +{ + uint32_t base; + uint32_t limit; + uint8_t access; + uint16_t seg; + uint32_t limit_low, limit_high; + int checked; /*Non-zero if selector is known to be valid*/ +} x86seg; + +typedef union MMX_REG +{ + uint64_t q; + int64_t sq; + uint32_t l[2]; + int32_t sl[2]; + uint16_t w[4]; + int16_t sw[4]; + uint8_t b[8]; + int8_t sb[8]; + float f[2]; +} MMX_REG; + +struct +{ + x86reg regs[8]; + + uint8_t tag[8]; + + x86seg *ea_seg; + uint32_t eaaddr; + + int flags_op; + uint32_t flags_res; + uint32_t flags_op1, flags_op2; + + uint32_t pc; + uint32_t oldpc; + uint32_t op32; + + int TOP; + + union + { + struct + { + int8_t rm, mod, reg; + } rm_mod_reg; + uint32_t rm_mod_reg_data; + } rm_data; + + int8_t ssegs; + int8_t ismmx; + int8_t abrt; + + int _cycles; + int cpu_recomp_ins; + + uint16_t npxs, npxc; + + double ST[8]; + + uint16_t MM_w4[8]; + + MMX_REG MM[8]; + + uint32_t old_fp_control, new_fp_control; +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ + uint16_t old_fp_control2, new_fp_control2; +#endif +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ + uint32_t trunc_fp_control; +#endif + x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; + + union + { + uint32_t l; + uint16_t w; + } CR0; + + uint16_t flags, eflags; +} cpu_state; + +#define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) + +#define cycles cpu_state._cycles + +#define cr0 cpu_state.CR0.l +#define msw cpu_state.CR0.w + +/*Segments - + _cs,_ds,_es,_ss are the segment structures + CS,DS,ES,SS is the 16-bit data + cs,ds,es,ss are defines to the bases*/ +#define CS cpu_state.seg_cs.seg +#define DS cpu_state.seg_ds.seg +#define ES cpu_state.seg_es.seg +#define SS cpu_state.seg_ss.seg +#define FS cpu_state.seg_fs.seg +#define GS cpu_state.seg_gs.seg +#define cs cpu_state.seg_cs.base +#define ds cpu_state.seg_ds.base +#define es cpu_state.seg_es.base +#define ss cpu_state.seg_ss.base +//#define seg_fs _fs.base +#define gs cpu_state.seg_gs.base + +#define CPL ((cpu_state.seg_cs.access>>5)&3) + +#define C_FLAG 0x0001 +#define P_FLAG 0x0004 +#define A_FLAG 0x0010 +#define Z_FLAG 0x0040 +#define N_FLAG 0x0080 +#define T_FLAG 0x0100 +#define I_FLAG 0x0200 +#define D_FLAG 0x0400 +#define V_FLAG 0x0800 +#define NT_FLAG 0x4000 +#define VM_FLAG 0x0002 /*In EFLAGS*/ +#define VIF_FLAG 0x0008 /*In EFLAGS*/ +#define VIP_FLAG 0x0010 /*In EFLAGS*/ + +#define WP_FLAG 0x10000 /*In CR0*/ + +#define CR4_VME (1 << 0) +#define CR4_PVI (1 << 1) +#define CR4_PSE (1 << 4) + +#define IOPL ((cpu_state.flags >> 12) & 3) + +#define IOPLp ((!(msw&1)) || (CPL<=IOPL)) + +extern x86seg gdt, ldt, idt, tr; + +extern uint32_t cr2, cr3, cr4; +extern uint32_t dr[8]; + + +extern uint16_t cpu_cur_status; + +/*The flags below must match in both cpu_cur_status and block->status for a block + to be valid*/ +#define CPU_STATUS_USE32 (1 << 0) +#define CPU_STATUS_STACK32 (1 << 1) +#define CPU_STATUS_PMODE (1 << 2) +#define CPU_STATUS_V86 (1 << 3) +#define CPU_STATUS_FLAGS 0xff + +/*If the flags below are set in cpu_cur_status, they must be set in block->status. + Otherwise they are ignored*/ +#define CPU_STATUS_NOTFLATDS (1 << 8) +#define CPU_STATUS_NOTFLATSS (1 << 9) +#define CPU_STATUS_MASK 0xff00 + + extern uint32_t rmdat; #define fetchdat rmdat extern uint32_t easeg; +extern uint32_t *eal_r, *eal_w; extern int oldcpl; +extern uint32_t oldss; extern int nmi_enable; extern int trap; -extern int output; -extern int timetolive; - -extern uint8_t znptable8[256]; - extern uint32_t use32; extern int stack32; +extern uint8_t znptable8[256]; extern uint16_t *mod1add[2][8]; extern uint32_t *mod1seg[8]; -extern int cgate32; - -extern uint32_t *eal_r, *eal_w; +extern int cgate16, cgate32; +extern int cpl_override; extern int x86_was_reset; - +extern int insc; +extern int fpucount; +extern float mips,flops; #define setznp168 setznp16 @@ -71,6 +265,9 @@ void x86_doabrt(int x86_abrt); extern int codegen_flat_ds; extern int codegen_flat_ss; +extern uint32_t pccache; +extern uint8_t *pccache2; + void x86illegal(); void x86seg_reset(); @@ -86,6 +283,8 @@ void exec386(int cycs); void exec386_dynarec(int cycs); void pmodeint(int num, int soft); +int loadseg(uint16_t seg, x86seg *s); +void loadcs(uint16_t seg); void loadcscall(uint16_t seg, uint32_t old_pc); void loadcsjmp(uint16_t seg, uint32_t old_pc); void pmoderetf(int is32, uint16_t off); @@ -97,3 +296,5 @@ int x86_int_sw_rm(int num); int divl(uint32_t val); int idivl(int32_t val); + +#endif diff --git a/src/x86seg.c b/src/x86seg.c index bed02ad..21a3778 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -1653,11 +1653,6 @@ void pmoderetf(int is32, uint16_t off) } } -void restore_stack() -{ - ss=oldss; cpu_state.seg_ss.limit=oldsslimit; -} - void pmodeint(int num, int soft) { uint16_t segdat[4],segdat2[4],segdat3[4];