More CPU sanitisation.

This commit is contained in:
SarahW 2019-02-08 21:17:56 +00:00
commit 03b5a44aca
14 changed files with 248 additions and 252 deletions

View file

@ -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)
{

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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"

214
src/ibm.h
View file

@ -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

View file

@ -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;

View file

@ -1,6 +1,8 @@
#ifndef _MEM_H_
#define _MEM_H_
#include "x86.h"
typedef struct mem_mapping_t
{
struct mem_mapping_t *prev, *next;

View file

@ -11,6 +11,7 @@
#include "model.h"
#include "nmi.h"
#include "t1000.h"
#include "x86.h"
int oldromset;
int nvrmask=63;

View file

@ -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;

View file

@ -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*/

View file

@ -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

219
src/x86.h
View file

@ -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

View file

@ -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];