More CPU sanitisation.
This commit is contained in:
parent
2554952658
commit
03b5a44aca
14 changed files with 248 additions and 252 deletions
|
|
@ -4,6 +4,11 @@
|
||||||
#include "x86_flags.h"
|
#include "x86_flags.h"
|
||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
|
|
||||||
|
x86seg gdt, ldt, idt, tr;
|
||||||
|
|
||||||
|
uint32_t cr2, cr3, cr4;
|
||||||
|
uint32_t dr[8];
|
||||||
|
|
||||||
uint32_t use32;
|
uint32_t use32;
|
||||||
int stack32;
|
int stack32;
|
||||||
int optype;
|
int optype;
|
||||||
|
|
@ -22,6 +27,8 @@ int fpucount=0;
|
||||||
|
|
||||||
uint16_t cpu_cur_status = 0;
|
uint16_t cpu_cur_status = 0;
|
||||||
|
|
||||||
|
uint32_t pccache;
|
||||||
|
uint8_t *pccache2;
|
||||||
|
|
||||||
void x86_int(int num)
|
void x86_int(int num)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
41
src/808x.c
41
src/808x.c
|
|
@ -40,28 +40,31 @@ int ins=0;
|
||||||
|
|
||||||
int is8086=0;
|
int is8086=0;
|
||||||
|
|
||||||
int nextcyc=0;
|
static uint32_t oldds;
|
||||||
int memcycs;
|
uint32_t oldss;
|
||||||
|
|
||||||
|
static int nextcyc=0;
|
||||||
|
static int memcycs;
|
||||||
|
|
||||||
static int cycdiff;
|
static int cycdiff;
|
||||||
void FETCHCOMPLETE();
|
static void FETCHCOMPLETE();
|
||||||
|
|
||||||
#define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint)
|
#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 (a!=(cs+cpu_state.pc)) memcycs+=4;
|
||||||
if (readlookup2[(a)>>12]==-1) return readmembl(a);
|
if (readlookup2[(a)>>12]==-1) return readmembl(a);
|
||||||
else return *(uint8_t *)(readlookup2[(a) >> 12] + (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);
|
if (readlookup2[(a)>>12]==-1) return readmembl(a);
|
||||||
else return *(uint8_t *)(readlookup2[(a) >> 12] + (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 (a!=(cs+cpu_state.pc)) memcycs+=(8>>is8086);
|
||||||
if ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) return readmemwl(s+a);
|
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; \
|
cpu_rm=rmdat&7; \
|
||||||
if (cpu_mod!=3) fetcheal(); }
|
if (cpu_mod!=3) fetcheal(); }
|
||||||
|
|
||||||
void writememb(uint32_t a, uint8_t v)
|
static void writememb(uint32_t a, uint8_t v)
|
||||||
{
|
{
|
||||||
memcycs+=4;
|
memcycs+=4;
|
||||||
if (writelookup2[(a)>>12]==-1) writemembl(a,v);
|
if (writelookup2[(a)>>12]==-1) writemembl(a,v);
|
||||||
else *(uint8_t *)(writelookup2[a >> 12] + 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);
|
memcycs+=(8>>is8086);
|
||||||
if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s+a,v);
|
if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s+a,v);
|
||||||
else *(uint16_t *)(writelookup2[(s + a) >> 12] + 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))
|
//#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()
|
static inline uint8_t FETCH()
|
||||||
{
|
{
|
||||||
uint8_t temp;
|
uint8_t temp;
|
||||||
|
|
@ -187,7 +186,7 @@ static inline void FETCHADD(int c)
|
||||||
// if (fetchcycles>24) fetchcycles=24;
|
// if (fetchcycles>24) fetchcycles=24;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FETCHCOMPLETE()
|
static void FETCHCOMPLETE()
|
||||||
{
|
{
|
||||||
// pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw);
|
// pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw);
|
||||||
if (!(fetchcycles&3)) return;
|
if (!(fetchcycles&3)) return;
|
||||||
|
|
@ -604,7 +603,6 @@ void resetx86()
|
||||||
use32=0;
|
use32=0;
|
||||||
cpu_cur_status = 0;
|
cpu_cur_status = 0;
|
||||||
stack32=0;
|
stack32=0;
|
||||||
cpu_hasCX8 = 0;
|
|
||||||
// i86_Reset();
|
// i86_Reset();
|
||||||
// cs=0xFFFF0;
|
// cs=0xFFFF0;
|
||||||
msw=0;
|
msw=0;
|
||||||
|
|
@ -665,7 +663,6 @@ void softresetx86()
|
||||||
cr4 = 0;
|
cr4 = 0;
|
||||||
cpu_state.eflags=0;
|
cpu_state.eflags=0;
|
||||||
cgate32=0;
|
cgate32=0;
|
||||||
cpu_hasCX8 = 0;
|
|
||||||
if (AT)
|
if (AT)
|
||||||
{
|
{
|
||||||
loadcs(0xF000);
|
loadcs(0xF000);
|
||||||
|
|
@ -845,7 +842,7 @@ int current_diff = 0;
|
||||||
between the two frequencies, use fixed point arithmetic when updating TSC.*/
|
between the two frequencies, use fixed point arithmetic when updating TSC.*/
|
||||||
static uint64_t tsc_frac = 0;
|
static uint64_t tsc_frac = 0;
|
||||||
|
|
||||||
void clockhardware()
|
static void clockhardware()
|
||||||
{
|
{
|
||||||
int diff = cycdiff - cycles - current_diff;
|
int diff = cycdiff - cycles - current_diff;
|
||||||
|
|
||||||
|
|
@ -864,7 +861,7 @@ static int takeint = 0;
|
||||||
|
|
||||||
int firstrepcycle=1;
|
int firstrepcycle=1;
|
||||||
|
|
||||||
void rep(int fv)
|
static void rep(int fv)
|
||||||
{
|
{
|
||||||
uint8_t temp;
|
uint8_t temp;
|
||||||
int c=CX;
|
int c=CX;
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,11 @@ int cpu_waitstates;
|
||||||
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
|
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
|
||||||
|
|
||||||
int is386;
|
int is386;
|
||||||
|
int is486;
|
||||||
|
int CPUID;
|
||||||
|
|
||||||
uint64_t tsc = 0;
|
uint64_t tsc = 0;
|
||||||
|
|
||||||
int is486;
|
|
||||||
|
|
||||||
int timing_rr;
|
int timing_rr;
|
||||||
int timing_mr, timing_mrl;
|
int timing_mr, timing_mrl;
|
||||||
int timing_rm, timing_rml;
|
int timing_rm, timing_rml;
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,8 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv);
|
||||||
uint8_t cyrix_read(uint16_t addr, void *priv);
|
uint8_t cyrix_read(uint16_t addr, void *priv);
|
||||||
|
|
||||||
extern int is8086;
|
extern int is8086;
|
||||||
|
extern int is486;
|
||||||
|
extern int CPUID;
|
||||||
|
|
||||||
void cpu_CPUID();
|
void cpu_CPUID();
|
||||||
void cpu_RDMSR();
|
void cpu_RDMSR();
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "plat-joystick.h"
|
#include "plat-joystick.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
#include "gameport.h"
|
#include "gameport.h"
|
||||||
#include "joystick_ch_flightstick_pro.h"
|
#include "joystick_ch_flightstick_pro.h"
|
||||||
|
|
|
||||||
214
src/ibm.h
214
src/ibm.h
|
|
@ -63,221 +63,9 @@ extern int readlnum,writelnum;
|
||||||
|
|
||||||
|
|
||||||
/*Processor*/
|
/*Processor*/
|
||||||
#define EAX cpu_state.regs[0].l
|
extern int ins, output, timetolive;
|
||||||
#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 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 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*/
|
/*Timer*/
|
||||||
typedef struct PIT_nr
|
typedef struct PIT_nr
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
This chip was used as part of many 386 chipsets
|
This chip was used as part of many 386 chipsets
|
||||||
It controls memory addressing and shadowing*/
|
It controls memory addressing and shadowing*/
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
int nextreg6;
|
int nextreg6;
|
||||||
uint8_t mcr22;
|
uint8_t mcr22;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef _MEM_H_
|
#ifndef _MEM_H_
|
||||||
#define _MEM_H_
|
#define _MEM_H_
|
||||||
|
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
typedef struct mem_mapping_t
|
typedef struct mem_mapping_t
|
||||||
{
|
{
|
||||||
struct mem_mapping_t *prev, *next;
|
struct mem_mapping_t *prev, *next;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "nmi.h"
|
#include "nmi.h"
|
||||||
#include "t1000.h"
|
#include "t1000.h"
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
int oldromset;
|
int oldromset;
|
||||||
int nvrmask=63;
|
int nvrmask=63;
|
||||||
|
|
|
||||||
1
src/pc.c
1
src/pc.c
|
|
@ -66,7 +66,6 @@ int start_in_fullscreen = 0;
|
||||||
|
|
||||||
static int override_drive_a = 0, override_drive_b = 0;
|
static int override_drive_a = 0, override_drive_b = 0;
|
||||||
|
|
||||||
int CPUID;
|
|
||||||
int vid_resize, vid_api;
|
int vid_resize, vid_api;
|
||||||
|
|
||||||
int cycles_lost = 0;
|
int cycles_lost = 0;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "sound_opl.h"
|
#include "sound_opl.h"
|
||||||
#include "sound_dbopl.h"
|
#include "sound_dbopl.h"
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
/*Interfaces between PCem and the actual OPL emulator*/
|
/*Interfaces between PCem and the actual OPL emulator*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include "sound_pas16.h"
|
#include "sound_pas16.h"
|
||||||
#include "sound_sb_dsp.h"
|
#include "sound_sb_dsp.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
/* Original PAS uses
|
/* Original PAS uses
|
||||||
2 x OPL2
|
2 x OPL2
|
||||||
|
|
|
||||||
219
src/x86.h
219
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;
|
extern uint32_t rmdat;
|
||||||
#define fetchdat rmdat
|
#define fetchdat rmdat
|
||||||
|
|
||||||
extern uint32_t easeg;
|
extern uint32_t easeg;
|
||||||
|
extern uint32_t *eal_r, *eal_w;
|
||||||
|
|
||||||
extern int oldcpl;
|
extern int oldcpl;
|
||||||
|
extern uint32_t oldss;
|
||||||
|
|
||||||
extern int nmi_enable;
|
extern int nmi_enable;
|
||||||
|
|
||||||
extern int trap;
|
extern int trap;
|
||||||
|
|
||||||
extern int output;
|
|
||||||
extern int timetolive;
|
|
||||||
|
|
||||||
extern uint8_t znptable8[256];
|
|
||||||
|
|
||||||
extern uint32_t use32;
|
extern uint32_t use32;
|
||||||
extern int stack32;
|
extern int stack32;
|
||||||
|
|
||||||
|
extern uint8_t znptable8[256];
|
||||||
extern uint16_t *mod1add[2][8];
|
extern uint16_t *mod1add[2][8];
|
||||||
extern uint32_t *mod1seg[8];
|
extern uint32_t *mod1seg[8];
|
||||||
|
|
||||||
extern int cgate32;
|
extern int cgate16, cgate32;
|
||||||
|
extern int cpl_override;
|
||||||
extern uint32_t *eal_r, *eal_w;
|
|
||||||
|
|
||||||
extern int x86_was_reset;
|
extern int x86_was_reset;
|
||||||
|
|
||||||
|
extern int insc;
|
||||||
|
extern int fpucount;
|
||||||
|
extern float mips,flops;
|
||||||
|
|
||||||
#define setznp168 setznp16
|
#define setznp168 setznp16
|
||||||
|
|
||||||
|
|
@ -71,6 +265,9 @@ void x86_doabrt(int x86_abrt);
|
||||||
extern int codegen_flat_ds;
|
extern int codegen_flat_ds;
|
||||||
extern int codegen_flat_ss;
|
extern int codegen_flat_ss;
|
||||||
|
|
||||||
|
extern uint32_t pccache;
|
||||||
|
extern uint8_t *pccache2;
|
||||||
|
|
||||||
void x86illegal();
|
void x86illegal();
|
||||||
|
|
||||||
void x86seg_reset();
|
void x86seg_reset();
|
||||||
|
|
@ -86,6 +283,8 @@ void exec386(int cycs);
|
||||||
void exec386_dynarec(int cycs);
|
void exec386_dynarec(int cycs);
|
||||||
|
|
||||||
void pmodeint(int num, int soft);
|
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 loadcscall(uint16_t seg, uint32_t old_pc);
|
||||||
void loadcsjmp(uint16_t seg, uint32_t old_pc);
|
void loadcsjmp(uint16_t seg, uint32_t old_pc);
|
||||||
void pmoderetf(int is32, uint16_t off);
|
void pmoderetf(int is32, uint16_t off);
|
||||||
|
|
@ -97,3 +296,5 @@ int x86_int_sw_rm(int num);
|
||||||
|
|
||||||
int divl(uint32_t val);
|
int divl(uint32_t val);
|
||||||
int idivl(int32_t val);
|
int idivl(int32_t val);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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)
|
void pmodeint(int num, int soft)
|
||||||
{
|
{
|
||||||
uint16_t segdat[4],segdat2[4],segdat3[4];
|
uint16_t segdat[4],segdat2[4],segdat3[4];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue