better separation of cpu type specific features; make cpu type selectable
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3155
This commit is contained in:
parent
581a6c2322
commit
e3aba20b3c
12 changed files with 288 additions and 31 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* 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
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: cpu.h,v 1.52 2008-01-16 20:16:31 c2woody Exp $ */
|
||||
/* $Id: cpu.h,v 1.53 2008-05-18 13:10:42 c2woody Exp $ */
|
||||
|
||||
#ifndef DOSBOX_CPU_H
|
||||
#define DOSBOX_CPU_H
|
||||
|
@ -40,6 +40,14 @@
|
|||
|
||||
#define CPU_CYCLES_LOWER_LIMIT 100
|
||||
|
||||
|
||||
#define CPU_ARCHTYPE_MIXED 0xff
|
||||
#define CPU_ARCHTYPE_386SLOW 0x30
|
||||
#define CPU_ARCHTYPE_386FAST 0x35
|
||||
#define CPU_ARCHTYPE_486OLDSLOW 0x40
|
||||
#define CPU_ARCHTYPE_486NEWSLOW 0x45
|
||||
#define CPU_ARCHTYPE_PENTIUMSLOW 0x50
|
||||
|
||||
/* CPU Cycle Timing */
|
||||
extern Bit32s CPU_Cycles;
|
||||
extern Bit32s CPU_CycleLeft;
|
||||
|
@ -52,6 +60,8 @@ extern bool CPU_CycleAutoAdjust;
|
|||
extern bool CPU_SkipCycleAutoAdjust;
|
||||
extern Bitu CPU_AutoDetermineMode;
|
||||
|
||||
extern Bitu CPU_ArchitectureType;
|
||||
|
||||
/* Some common Defines */
|
||||
/* A CPU Handler */
|
||||
typedef Bits (CPU_Decoder)(void);
|
||||
|
@ -146,7 +156,7 @@ void CPU_Exception(Bitu which,Bitu error=0);
|
|||
bool CPU_SetSegGeneral(SegNames seg,Bitu value);
|
||||
bool CPU_PopSeg(SegNames seg,bool use32);
|
||||
|
||||
void CPU_CPUID(void);
|
||||
bool CPU_CPUID(void);
|
||||
Bitu CPU_Pop16(void);
|
||||
Bitu CPU_Pop32(void);
|
||||
void CPU_Push16(Bitu value);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* 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
|
||||
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: decoder.h,v 1.55 2008-05-18 13:11:14 c2woody Exp $ */
|
||||
|
||||
#define X86_DYNFPU_DH_ENABLED
|
||||
#define X86_INLINED_MEMACCESS
|
||||
|
||||
|
@ -1329,6 +1331,68 @@ static void dyn_mov_ev_gw(bool sign) {
|
|||
}
|
||||
}
|
||||
|
||||
static void dyn_cmpxchg_evgv(void) {
|
||||
dyn_get_modrm();
|
||||
DynReg * rm_reg=&DynRegs[decode.modrm.reg];
|
||||
gen_protectflags();
|
||||
if (decode.modrm.mod<3) {
|
||||
gen_releasereg(DREG(EAX));
|
||||
gen_releasereg(DREG(TMPB));
|
||||
gen_releasereg(rm_reg);
|
||||
|
||||
dyn_fill_ea();
|
||||
dyn_read_word(DREG(EA),DREG(TMPB),decode.big_op);
|
||||
gen_dop_word(DOP_CMP,decode.big_op,DREG(EAX),DREG(TMPB));
|
||||
Bit8u * branch=gen_create_branch(BR_NZ);
|
||||
|
||||
// eax==mem -> mem:=rm_reg
|
||||
dyn_write_word_release(DREG(EA),rm_reg,decode.big_op);
|
||||
gen_setzeroflag();
|
||||
gen_releasereg(DREG(EAX));
|
||||
gen_releasereg(DREG(TMPB));
|
||||
gen_releasereg(rm_reg);
|
||||
|
||||
Bit8u * jump=gen_create_jump();
|
||||
|
||||
gen_fill_branch(branch);
|
||||
// eax!=mem -> eax:=mem
|
||||
dyn_write_word_release(DREG(EA),DREG(TMPB),decode.big_op); // cmpxchg always issues write
|
||||
gen_dop_word(DOP_MOV,decode.big_op,DREG(EAX),DREG(TMPB));
|
||||
gen_clearzeroflag();
|
||||
gen_releasereg(DREG(EAX));
|
||||
gen_releasereg(DREG(TMPB));
|
||||
gen_releasereg(rm_reg);
|
||||
|
||||
gen_fill_jump(jump);
|
||||
} else {
|
||||
gen_releasereg(DREG(EAX));
|
||||
gen_releasereg(&DynRegs[decode.modrm.rm]);
|
||||
gen_releasereg(rm_reg);
|
||||
|
||||
gen_dop_word(DOP_CMP,decode.big_op,DREG(EAX),&DynRegs[decode.modrm.rm]);
|
||||
Bit8u * branch=gen_create_branch(BR_NZ);
|
||||
|
||||
// eax==rm -> rm:=rm_reg
|
||||
gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg);
|
||||
gen_setzeroflag();
|
||||
gen_releasereg(DREG(EAX));
|
||||
gen_releasereg(&DynRegs[decode.modrm.rm]);
|
||||
gen_releasereg(rm_reg);
|
||||
|
||||
Bit8u * jump=gen_create_jump();
|
||||
|
||||
gen_fill_branch(branch);
|
||||
// eax!=rm -> eax:=rm
|
||||
gen_dop_word(DOP_MOV,decode.big_op,DREG(EAX),&DynRegs[decode.modrm.rm]);
|
||||
gen_clearzeroflag();
|
||||
gen_releasereg(DREG(EAX));
|
||||
gen_releasereg(&DynRegs[decode.modrm.rm]);
|
||||
gen_releasereg(rm_reg);
|
||||
|
||||
gen_fill_jump(jump);
|
||||
}
|
||||
}
|
||||
|
||||
static void dyn_dshift_ev_gv(bool left,bool immediate) {
|
||||
dyn_get_modrm();
|
||||
DynReg * rm_reg=&DynRegs[decode.modrm.reg];
|
||||
|
@ -1995,6 +2059,8 @@ restart_prefix:
|
|||
case 0xad:dyn_dshift_ev_gv(false,false);break;
|
||||
/* Imul Ev,Gv */
|
||||
case 0xaf:dyn_imul_gvev(0);break;
|
||||
/* CMPXCHG */
|
||||
case 0xb1:dyn_cmpxchg_evgv();break;
|
||||
/* LFS,LGS */
|
||||
case 0xb4:
|
||||
dyn_get_modrm();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* 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
|
||||
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: risc_x86.h,v 1.30 2008-05-18 13:11:14 c2woody Exp $ */
|
||||
|
||||
static void gen_init(void);
|
||||
|
||||
/* End of needed */
|
||||
|
@ -268,6 +270,18 @@ static void gen_needcarry(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void gen_setzeroflag(void) {
|
||||
if (x86gen.flagsactive) IllegalOption("gen_setzeroflag");
|
||||
cache_addw(0x0c83); //OR DWORD [ESP],0x40
|
||||
cache_addw(0x4024);
|
||||
}
|
||||
|
||||
static void gen_clearzeroflag(void) {
|
||||
if (x86gen.flagsactive) IllegalOption("gen_clearzeroflag");
|
||||
cache_addw(0x2483); //AND DWORD [ESP],~0x40
|
||||
cache_addw(0xbf24);
|
||||
}
|
||||
|
||||
static bool skip_flags=false;
|
||||
|
||||
static void set_skipflags(bool state) {
|
||||
|
|
|
@ -468,7 +468,7 @@ l_M_Ed:
|
|||
AAS();
|
||||
goto nextopcode;
|
||||
case D_CPUID:
|
||||
CPU_CPUID();
|
||||
if (!CPU_CPUID()) goto illegalopcode;
|
||||
goto nextopcode;
|
||||
case D_HLT:
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
|
|
|
@ -585,8 +585,22 @@ switch (inst.code.op) {
|
|||
inst_op1_d&=~(1 << (inst_op2_d & 31));
|
||||
break;
|
||||
case O_BSWAP:
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegalopcode;
|
||||
BSWAP(inst_op1_d);
|
||||
break;
|
||||
case O_CMPXCHG:
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEWSLOW) goto illegalopcode;
|
||||
FillFlags();
|
||||
if (inst_op1_d==reg_eax) {
|
||||
inst_op1_d=reg_32(inst.rm_index);
|
||||
if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); // early write-pf
|
||||
SETFLAGBIT(ZF,1);
|
||||
} else {
|
||||
if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); // early write-pf
|
||||
reg_eax=inst_op1_d;
|
||||
SETFLAGBIT(ZF,0);
|
||||
}
|
||||
break;
|
||||
case O_FPU:
|
||||
#if C_FPU
|
||||
switch (((inst.rm>=0xc0) << 3) | inst.code.save) {
|
||||
|
|
|
@ -661,7 +661,7 @@ static OpCode OpCodeTable[1024]={
|
|||
{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx },
|
||||
|
||||
/* 0x3b0 - 0x3b7 */
|
||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||
{0 ,0 ,0 ,0 },{L_MODRM ,O_CMPXCHG ,S_Ed ,M_Ed },
|
||||
{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGdt },
|
||||
{L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd },
|
||||
{L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew },
|
||||
|
|
|
@ -94,7 +94,7 @@ enum {
|
|||
O_BTd,O_BTSd,O_BTRd,O_BTCd,
|
||||
O_BSFw,O_BSRw,O_BSFd,O_BSRd,
|
||||
|
||||
O_BSWAP,
|
||||
O_BSWAP,O_CMPXCHG,
|
||||
O_FPU,
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* 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
|
||||
|
@ -142,6 +142,11 @@
|
|||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
cpu.cr0&=(~CR0_TASKSWITCH);
|
||||
break;
|
||||
CASE_0F_B(0x08) /* INVD */
|
||||
CASE_0F_B(0x09) /* WBINVD */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
|
||||
break;
|
||||
CASE_0F_B(0x20) /* MOV Rd.CRx */
|
||||
{
|
||||
GetRM;
|
||||
|
@ -220,6 +225,14 @@
|
|||
if (CPU_WRITE_TRX(which,*eard)) RUNEXCEPTION();
|
||||
}
|
||||
break;
|
||||
CASE_0F_B(0x31) /* RDTSC */
|
||||
{
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMSLOW) goto illegal_opcode;
|
||||
Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double)CPU_CycleMax);
|
||||
reg_edx=(Bit32u)(tsc>>32);
|
||||
reg_eax=(Bit32u)(tsc&0xffffffff);
|
||||
}
|
||||
break;
|
||||
CASE_0F_W(0x80) /* JO */
|
||||
JumpCond16_w(TFLG_O);break;
|
||||
CASE_0F_W(0x81) /* JNO */
|
||||
|
@ -291,7 +304,8 @@
|
|||
if (CPU_PopSeg(fs,false)) RUNEXCEPTION();
|
||||
break;
|
||||
CASE_0F_B(0xa2) /* CPUID */
|
||||
CPU_CPUID();break;
|
||||
if (!CPU_CPUID()) goto illegal_opcode;
|
||||
break;
|
||||
CASE_0F_W(0xa3) /* BT Ew,Gw */
|
||||
{
|
||||
FillFlags();GetRMrw;
|
||||
|
@ -503,6 +517,7 @@
|
|||
}
|
||||
CASE_0F_B(0xc0) /* XADD Gb,Eb */
|
||||
{
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
GetRMrb;Bit8u oldrmrb=*rmrb;
|
||||
if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;}
|
||||
else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);}
|
||||
|
@ -510,25 +525,34 @@
|
|||
}
|
||||
CASE_0F_W(0xc1) /* XADD Gw,Ew */
|
||||
{
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
GetRMrw;Bit16u oldrmrw=*rmrw;
|
||||
if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;}
|
||||
else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);}
|
||||
break;
|
||||
}
|
||||
CASE_0F_B(0xc8) /* BSWAP EAX */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
BSWAP(reg_eax);break;
|
||||
CASE_0F_B(0xc9) /* BSWAP ECX */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
BSWAP(reg_ecx);break;
|
||||
CASE_0F_B(0xca) /* BSWAP EDX */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
BSWAP(reg_edx);break;
|
||||
CASE_0F_B(0xcb) /* BSWAP EBX */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
BSWAP(reg_ebx);break;
|
||||
CASE_0F_B(0xcc) /* BSWAP ESP */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
BSWAP(reg_esp);break;
|
||||
CASE_0F_B(0xcd) /* BSWAP EBP */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
BSWAP(reg_ebp);break;
|
||||
CASE_0F_B(0xce) /* BSWAP ESI */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
BSWAP(reg_esi);break;
|
||||
CASE_0F_B(0xcf) /* BSWAP EDI */
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
BSWAP(reg_edi);break;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* 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
|
||||
|
@ -235,6 +235,34 @@
|
|||
RMGdEdOp3(DIMULD,*rmrd);
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb1) /* CMPXCHG Ed,Gd */
|
||||
{
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEWSLOW) goto illegal_opcode;
|
||||
FillFlags();
|
||||
GetRMrd;
|
||||
if (rm >= 0xc0) {
|
||||
GetEArd;
|
||||
if (*eard==reg_eax) {
|
||||
*eard=*rmrd;
|
||||
SETFLAGBIT(ZF,1);
|
||||
} else {
|
||||
reg_eax=*eard;
|
||||
SETFLAGBIT(ZF,0);
|
||||
}
|
||||
} else {
|
||||
GetEAa;
|
||||
Bit32u val=LoadMd(eaa);
|
||||
if (val==reg_eax) {
|
||||
SaveMd(eaa,*rmrd);
|
||||
SETFLAGBIT(ZF,1);
|
||||
} else {
|
||||
SaveMd(eaa,val);
|
||||
reg_eax=val;
|
||||
SETFLAGBIT(ZF,0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
CASE_0F_D(0xb2) /* LSS Ed */
|
||||
{
|
||||
GetRMrd;
|
||||
|
@ -405,6 +433,7 @@
|
|||
}
|
||||
CASE_0F_D(0xc1) /* XADD Gd,Ed */
|
||||
{
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
|
||||
GetRMrd;Bit32u oldrmrd=*rmrd;
|
||||
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard+=oldrmrd;}
|
||||
else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,LoadMd(eaa)+oldrmrd);}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: cpu.cpp,v 1.110 2008-05-05 13:29:04 qbix79 Exp $ */
|
||||
/* $Id: cpu.cpp,v 1.111 2008-05-18 13:11:14 c2woody Exp $ */
|
||||
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
|
@ -61,6 +61,10 @@ bool CPU_CycleAutoAdjust = false;
|
|||
bool CPU_SkipCycleAutoAdjust = false;
|
||||
Bitu CPU_AutoDetermineMode = 0;
|
||||
|
||||
Bitu CPU_ArchitectureType = CPU_ARCHTYPE_MIXED;
|
||||
|
||||
Bitu CPU_flag_id_toggle=0;
|
||||
|
||||
void CPU_Core_Full_Init(void);
|
||||
void CPU_Core_Normal_Init(void);
|
||||
void CPU_Core_Simple_Init(void);
|
||||
|
@ -161,8 +165,10 @@ PhysPt SelBase(Bitu sel) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CPU_SetFlags(Bitu word,Bitu mask) {
|
||||
reg_flags=(reg_flags & ~mask)|(word & mask)|2|FLAG_ID;
|
||||
mask|=CPU_flag_id_toggle; // ID-flag can be toggled on cpuid-supporting CPUs
|
||||
reg_flags=(reg_flags & ~mask)|(word & mask)|2;
|
||||
cpu.direction=1-((reg_flags & FLAG_DF) >> 9);
|
||||
}
|
||||
|
||||
|
@ -1569,6 +1575,9 @@ bool CPU_WRITE_CRX(Bitu cr,Bitu value) {
|
|||
/* Check if privileged to access control registers */
|
||||
if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0);
|
||||
if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0);
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) {
|
||||
if (cr==4) return CPU_PrepareException(EXCEPTION_UD,0);
|
||||
}
|
||||
CPU_SET_CRX(cr,value);
|
||||
return false;
|
||||
}
|
||||
|
@ -1576,7 +1585,9 @@ bool CPU_WRITE_CRX(Bitu cr,Bitu value) {
|
|||
Bitu CPU_GET_CRX(Bitu cr) {
|
||||
switch (cr) {
|
||||
case 0:
|
||||
return cpu.cr0;
|
||||
if (CPU_ArchitectureType>=CPU_ARCHTYPE_PENTIUMSLOW) return cpu.cr0;
|
||||
else if (CPU_ArchitectureType>=CPU_ARCHTYPE_486OLDSLOW) return (cpu.cr0 & 0xe005003f);
|
||||
else return (cpu.cr0 | 0x7ffffff0);
|
||||
case 2:
|
||||
return paging.cr2;
|
||||
case 3:
|
||||
|
@ -1613,7 +1624,11 @@ bool CPU_WRITE_DRX(Bitu dr,Bitu value) {
|
|||
break;
|
||||
case 5:
|
||||
case 7:
|
||||
cpu.drx[7]=(value|0x400) & 0xffff2fff;
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMSLOW) {
|
||||
cpu.drx[7]=(value|0x400) & 0xffff2fff;
|
||||
} else {
|
||||
cpu.drx[7]=(value|0x400);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV DR%d,%X",dr,value);
|
||||
|
@ -1961,7 +1976,8 @@ bool CPU_PopSeg(SegNames seg,bool use32) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void CPU_CPUID(void) {
|
||||
bool CPU_CPUID(void) {
|
||||
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEWSLOW) return false;
|
||||
switch (reg_eax) {
|
||||
case 0: /* Vendor ID String and maximum level? */
|
||||
reg_eax=1; /* Maximum level */
|
||||
|
@ -1970,15 +1986,30 @@ void CPU_CPUID(void) {
|
|||
reg_ecx='n' | ('t' << 8) | ('e' << 16) | ('l'<< 24);
|
||||
break;
|
||||
case 1: /* get processor type/family/model/stepping and feature flags */
|
||||
reg_eax=0x402; /* intel 486 sx? */
|
||||
reg_ebx=0; /* Not Supported */
|
||||
reg_ecx=0; /* No features */
|
||||
reg_edx=1; /* FPU */
|
||||
if ((CPU_ArchitectureType==CPU_ARCHTYPE_486NEWSLOW) ||
|
||||
(CPU_ArchitectureType==CPU_ARCHTYPE_MIXED)) {
|
||||
reg_eax=0x402; /* intel 486dx */
|
||||
reg_ebx=0; /* Not Supported */
|
||||
reg_ecx=0; /* No features */
|
||||
reg_edx=0x00000001; /* FPU */
|
||||
} else if (CPU_ArchitectureType==CPU_ARCHTYPE_PENTIUMSLOW) {
|
||||
reg_eax=0x513; /* intel pentium */
|
||||
reg_ebx=0; /* Not Supported */
|
||||
reg_ecx=0; /* No features */
|
||||
reg_edx=0x00000011; /* FPU+TimeStamp/RDTSC */
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_CPU,LOG_ERROR)("Unhandled CPUID Function %x",reg_eax);
|
||||
reg_eax=0;
|
||||
reg_ebx=0;
|
||||
reg_ecx=0;
|
||||
reg_edx=0;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static Bits HLT_Decode(void) {
|
||||
|
@ -2140,7 +2171,11 @@ public:
|
|||
cpu.drx[i]=0;
|
||||
cpu.trx[i]=0;
|
||||
}
|
||||
cpu.drx[6]=0xffff1ff0;
|
||||
if (CPU_ArchitectureType==CPU_ARCHTYPE_PENTIUMSLOW) {
|
||||
cpu.drx[6]=0xffff0ff0;
|
||||
} else {
|
||||
cpu.drx[6]=0xffff1ff0;
|
||||
}
|
||||
cpu.drx[7]=0x00000400;
|
||||
|
||||
/* Init the cpu cores */
|
||||
|
@ -2237,7 +2272,7 @@ public:
|
|||
|
||||
CPU_CycleUp=section->Get_int("cycleup");
|
||||
CPU_CycleDown=section->Get_int("cycledown");
|
||||
std::string core(section->Get_string("core"));
|
||||
std::string core(section->Get_string("core"));
|
||||
cpudecoder=&CPU_Core_Normal_Run;
|
||||
if (core == "normal") {
|
||||
cpudecoder=&CPU_Core_Normal_Run;
|
||||
|
@ -2271,7 +2306,25 @@ public:
|
|||
#elif (C_DYNREC)
|
||||
CPU_Core_Dynrec_Cache_Init( core == "dynamic" );
|
||||
#endif
|
||||
|
||||
|
||||
CPU_ArchitectureType = CPU_ARCHTYPE_MIXED;
|
||||
std::string cputype(section->Get_string("cputype"));
|
||||
if (cputype == "auto") {
|
||||
CPU_ArchitectureType = CPU_ARCHTYPE_MIXED;
|
||||
} else if (cputype == "386") {
|
||||
CPU_ArchitectureType = CPU_ARCHTYPE_386FAST;
|
||||
} else if (cputype == "386_slow") {
|
||||
CPU_ArchitectureType = CPU_ARCHTYPE_386SLOW;
|
||||
} else if (cputype == "486_slow") {
|
||||
CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW;
|
||||
} else if (cputype == "pentium_slow") {
|
||||
CPU_ArchitectureType = CPU_ARCHTYPE_PENTIUMSLOW;
|
||||
}
|
||||
|
||||
if (CPU_ArchitectureType>=CPU_ARCHTYPE_486NEWSLOW) CPU_flag_id_toggle=FLAG_ID;
|
||||
else CPU_flag_id_toggle=0;
|
||||
|
||||
|
||||
if(CPU_CycleMax <= 0) CPU_CycleMax = 3000;
|
||||
if(CPU_CycleUp <= 0) CPU_CycleUp = 500;
|
||||
if(CPU_CycleDown <= 0) CPU_CycleDown = 20;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: paging.cpp,v 1.33 2008-01-05 21:05:06 c2woody Exp $ */
|
||||
/* $Id: paging.cpp,v 1.34 2008-05-18 13:11:14 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
@ -34,7 +34,6 @@
|
|||
#define LINK_TOTAL (64*1024)
|
||||
|
||||
#define USERWRITE_PROHIBITED ((cpu.cpl&cpu.mpl)==3)
|
||||
#define USERACCESS_PROHIBITED(u1,u2) (((u1)==0) && ((u2)==0))
|
||||
|
||||
|
||||
PagingBlock paging;
|
||||
|
@ -228,6 +227,20 @@ static INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,
|
|||
return true;
|
||||
}
|
||||
|
||||
static INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2) {
|
||||
switch (CPU_ArchitectureType) {
|
||||
case CPU_ARCHTYPE_MIXED:
|
||||
case CPU_ARCHTYPE_386SLOW:
|
||||
case CPU_ARCHTYPE_386FAST:
|
||||
default:
|
||||
return ((u1)==0) && ((u2)==0);
|
||||
case CPU_ARCHTYPE_486OLDSLOW:
|
||||
case CPU_ARCHTYPE_486NEWSLOW:
|
||||
case CPU_ARCHTYPE_PENTIUMSLOW:
|
||||
return ((u1)==0) || ((u2)==0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class InitPageHandler : public PageHandler {
|
||||
public:
|
||||
|
@ -316,12 +329,40 @@ public:
|
|||
// 2: can (but currently does not) fail a write privilege check
|
||||
// 3: fails a privilege check
|
||||
Bitu priv_check=0;
|
||||
if (USERACCESS_PROHIBITED(entry.block.us,table.block.us)) {
|
||||
if (InitPage_CheckUseraccess(entry.block.us,table.block.us)) {
|
||||
if ((cpu.cpl&cpu.mpl)==3) priv_check=3;
|
||||
else priv_check=1;
|
||||
else {
|
||||
switch (CPU_ArchitectureType) {
|
||||
case CPU_ARCHTYPE_MIXED:
|
||||
case CPU_ARCHTYPE_386FAST:
|
||||
default:
|
||||
// priv_check=0; // default
|
||||
break;
|
||||
case CPU_ARCHTYPE_386SLOW:
|
||||
case CPU_ARCHTYPE_486OLDSLOW:
|
||||
case CPU_ARCHTYPE_486NEWSLOW:
|
||||
case CPU_ARCHTYPE_PENTIUMSLOW:
|
||||
priv_check=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((entry.block.wr==0) || (table.block.wr==0)) {
|
||||
if (priv_check==0) priv_check=2;
|
||||
if (priv_check==0) {
|
||||
switch (CPU_ArchitectureType) {
|
||||
case CPU_ARCHTYPE_MIXED:
|
||||
case CPU_ARCHTYPE_386FAST:
|
||||
default:
|
||||
// priv_check=0; // default
|
||||
break;
|
||||
case CPU_ARCHTYPE_386SLOW:
|
||||
case CPU_ARCHTYPE_486OLDSLOW:
|
||||
case CPU_ARCHTYPE_486NEWSLOW:
|
||||
case CPU_ARCHTYPE_PENTIUMSLOW:
|
||||
priv_check=2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (writing && USERWRITE_PROHIBITED) priv_check=3;
|
||||
}
|
||||
if (priv_check==3) {
|
||||
|
@ -374,7 +415,7 @@ public:
|
|||
|
||||
if (!USERWRITE_PROHIBITED) return true;
|
||||
|
||||
if (USERACCESS_PROHIBITED(entry.block.us,table.block.us) ||
|
||||
if (InitPage_CheckUseraccess(entry.block.us,table.block.us) ||
|
||||
(((entry.block.wr==0) || (table.block.wr==0)) && writing)) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",
|
||||
cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
|
||||
|
@ -507,7 +548,7 @@ public:
|
|||
X86PageEntry entry;
|
||||
if (!InitPageCheckPresence_CheckOnly(lin_addr,true,table,entry)) return 0;
|
||||
|
||||
if (USERACCESS_PROHIBITED(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)))) {
|
||||
if (InitPage_CheckUseraccess(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)))) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",
|
||||
cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
|
||||
paging.cr2=lin_addr;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dosbox.cpp,v 1.135 2008-05-10 17:33:27 c2woody Exp $ */
|
||||
/* $Id: dosbox.cpp,v 1.136 2008-05-18 13:10:42 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -393,6 +393,12 @@ void DOSBOX_Init(void) {
|
|||
Pstring->Set_values(cores);
|
||||
Pstring->Set_help("CPU Core used in emulation. auto will switch to dynamic if available and appropriate.");
|
||||
|
||||
const char* cputype_values[] = { "auto", "386", "386_slow", "486_slow", "pentium_slow", 0};
|
||||
Pstring = secprop->Add_string("cputype",Property::Changeable::Always,"auto");
|
||||
Pstring->Set_values(cputype_values);
|
||||
Pstring->Set_help("CPU Type used in emulation. auto is the fastest choice.");
|
||||
|
||||
|
||||
Pmulti_remain = secprop->Add_multiremain("cycles",Property::Changeable::Always," ");
|
||||
Pmulti_remain->Set_help(
|
||||
"Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:\n"
|
||||
|
|
Loading…
Add table
Reference in a new issue