1
0
Fork 0

CPU Cores keep their own flag handling

New lazyflags header file


Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1086
This commit is contained in:
Sjoerd van der Berg 2003-07-06 13:10:28 +00:00
parent cbd33bfa95
commit 708d8cb3c3
8 changed files with 160 additions and 29 deletions

View file

@ -3,24 +3,51 @@
#include "pic.h"
#include "regs.h"
#include "cpu.h"
#include "lazyflags.h"
#include "fpu.h"
#include "debug.h"
#include "inout.h"
#include "callback.h"
Bit8u PAGE_Readb(PhysPt address);
Bit16u PAGE_Readw(PhysPt address);
Bit32u PAGE_Readd(PhysPt address);
void PAGE_Writeb(PhysPt address,Bit8u val);
void PAGE_Writew(PhysPt address,Bit16u val);
void PAGE_Writed(PhysPt address,Bit32u val);
typedef PhysPt EAPoint;
#define SegBase(c) SegPhys(c)
#define LoadMb(off) mem_readb_inline(off)
#define LoadMw(off) mem_readw_inline(off)
#define LoadMd(off) mem_readd_inline(off)
#if 1
#define LoadMb(off) mem_readb(off)
#define LoadMw(off) mem_readw(off)
#define LoadMd(off) mem_readd(off)
#define LoadMbs(off) (Bit8s)(LoadMb(off))
#define LoadMws(off) (Bit16s)(LoadMw(off))
#define LoadMds(off) (Bit32s)(LoadMd(off))
#define SaveMb(off,val) mem_writeb_inline(off,val)
#define SaveMw(off,val) mem_writew_inline(off,val)
#define SaveMd(off,val) mem_writed_inline(off,val)
#define SaveMb(off,val) mem_writeb(off,val)
#define SaveMw(off,val) mem_writew(off,val)
#define SaveMd(off,val) mem_writed(off,val)
#else
#define LoadMb(off) PAGE_Readb(off)
#define LoadMw(off) PAGE_Readw(off)
#define LoadMd(off) PAGE_Readd(off)
#define LoadMbs(off) (Bit8s)(LoadMb(off))
#define LoadMws(off) (Bit16s)(LoadMw(off))
#define LoadMds(off) (Bit32s)(LoadMd(off))
#define SaveMb(off,val) PAGE_Writeb(off,val)
#define SaveMw(off,val) PAGE_Writew(off,val)
#define SaveMd(off,val) PAGE_Writed(off,val)
#endif
#define LoadD(reg) reg
#define SaveD(reg,val) reg=val
@ -43,10 +70,14 @@ static INLINE void DecodeModRM(void) {
if (inst.rm<0xc0) inst.rm_eaa=(inst.prefix & PREFIX_ADDR) ? RMAddress_32() : RMAddress_16();
}
#define LEAVECORE \
SaveIP(); \
FILLFLAGS;
#define EXCEPTION(blah) \
{ \
Bit8u new_num=blah; \
SaveIP(); \
LEAVECORE; \
Interrupt(new_num); \
LoadIP(); \
goto nextopcode; \
@ -55,11 +86,12 @@ static INLINE void DecodeModRM(void) {
Bitu Full_DeCode(void) {
LoadIP();
flags.type=t_UNKNOWN;
while (CPU_Cycles>0) {
#if C_DEBUG
cycle_count++;
#if C_HEAVY_DEBUG
SaveIP();
LEAVECORE;
if (DEBUG_HeavyIsBreakpoint()) return 1;
#endif
#endif
@ -76,8 +108,8 @@ restartopcode:
nextopcode:;
CPU_Cycles--;
}
SaveIP();
return 0;
LEAVECORE;
return CBRET_NONE;
}

View file

@ -265,10 +265,12 @@ l_M_Ed:
inst.op1.d=4;
break;
case D_IRETw:
flags.type=t_UNKNOWN;
CPU_IRET(false);
LoadIP();
goto nextopcode;
case D_IRETd:
flags.type=t_UNKNOWN;
CPU_IRET(true);
LoadIP();
goto nextopcode;
@ -470,7 +472,7 @@ l_M_Ed:
CPU_CPUID();
goto nextopcode;
case D_HLT:
SaveIP();
LEAVECORE;
CPU_HLT();
return 0x0;
default:

View file

@ -80,10 +80,9 @@ static INLINE Bit32u Pop_32(void) {
}
}
#if 0
if (flags.intf && PIC_IRQCheck) { \
SaveIP(); \
LEAVECORE; \
PIC_runIRQs(); \
LoadIP(); \
} \

View file

@ -339,7 +339,7 @@ switch (inst.code.op) {
goto nextopcode;
case O_INT:
SaveIP();
LEAVECORE;
#if C_DEBUG
if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return 1;
else if (DEBUG_IntBreakpoint(inst.op1.b)) return 1;
@ -371,7 +371,7 @@ switch (inst.code.op) {
goto nextopcode;
case O_CBACK:
if (inst.op1.d<CB_MAX) {
SaveIP();
LEAVECORE;
Bitu ret=CallBack_Handlers[inst.op1.d]();
switch (ret) {
case CBRET_NONE:
@ -409,9 +409,11 @@ switch (inst.code.op) {
CPU_LTR(inst.op1.d);
goto nextopcode; /* Else value will saved */
case 0x04: /* VERR */
FILLFLAGS;
CPU_VERR(inst.op1.d);
goto nextopcode; /* Else value will saved */
case 0x05: /* VERW */
FILLFLAGS;
CPU_VERW(inst.op1.d);
goto nextopcode; /* Else value will saved */
@ -452,6 +454,7 @@ switch (inst.code.op) {
break;
}
case 6: /* LMSW */
FILLFLAGS;
CPU_LMSW(inst.op1.w);
goto nextopcode;
default:
@ -466,18 +469,21 @@ switch (inst.code.op) {
break;
case O_LAR:
{
FILLFLAGS;
Bitu ar;CPU_LAR(inst.op1.d,ar);
inst.op1.d=ar;
}
break;
case O_LSL:
{
FILLFLAGS;
Bitu limit;CPU_LSL(inst.op1.d,limit);
inst.op1.d=limit;
}
break;
case O_ARPL:
{
FILLFLAGS;
Bitu new_sel=inst.op1.d;
CPU_ARPL(new_sel,inst.op2.d);
inst.op1.d=new_sel;

View file

@ -99,10 +99,10 @@ switch (inst.code.save) {
LoadIP();
break;
case S_FLGb:
SETFLAGSb(inst.op1.d);
SETFLAGSb(inst.op1.b);
break;
case S_FLGw:
SETFLAGSw(inst.op1.d);
SETFLAGSw(inst.op1.w);
break;
case S_FLGd:
SETFLAGSd(inst.op1.d);

View file

@ -112,6 +112,10 @@ PhysPt SelBase(Bitu sel) {
}
}
void CPU_SetFlags(Bitu word) {
flags.word=word;
}
bool CPU_CheckState(void) {
Bitu old_state=cpu.state;
cpu.state=0;
@ -184,8 +188,7 @@ bool Interrupt(Bitu num) {
break;
};
#endif
FILLFLAGS;
if (!(cpu.state & STATE_PROTECTED)) { /* RealMode Interrupt */
/* Save everything on a 16-bit stack */
CPU_Push16(flags.word & 0xffff);
@ -262,11 +265,11 @@ bool CPU_IRET(bool use32) {
if (use32) {
reg_eip=CPU_Pop32();
SegSet16(cs,CPU_Pop32());
SETFLAGSw(CPU_Pop32());
CPU_SetFlags(CPU_Pop32());
} else {
reg_eip=CPU_Pop16();
SegSet16(cs,CPU_Pop16());
SETFLAGSw(CPU_Pop16());
CPU_SetFlagsw(CPU_Pop16());
}
return true;
} else { /* Protected mode IRET */
@ -280,7 +283,7 @@ bool CPU_IRET(bool use32) {
} else {
offset=CPU_Pop16();
selector=CPU_Pop16();
old_flags=CPU_Pop16();
old_flags=(flags.word & 0xffff0000) | CPU_Pop16();
}
Bitu rpl=selector & 3;
Descriptor desc;
@ -304,7 +307,7 @@ bool CPU_IRET(bool use32) {
Segs.big[cs]=desc.Big();
Segs.val[cs]=(selector & 0xfffc) | cpu.cpl;;
reg_eip=offset;
SETFLAGSw(old_flags);
CPU_SetFlags(old_flags);
LOG_MSG("IRET:Same level return to %X:%X",selector,offset);
} else {
/* Return to higher privilege */
@ -591,7 +594,6 @@ bool CPU_LMSW(Bitu word) {
}
void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) {
flags.type=t_UNKNOWN;
if ((dest_sel & 3) < (src_sel & 3)) {
dest_sel=(dest_sel & 0xfffc) + (src_sel & 3);
// dest_sel|=0xff3f0000;
@ -603,7 +605,6 @@ void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) {
void CPU_LAR(Bitu selector,Bitu & ar) {
Descriptor desc;Bitu rpl=selector & 3;
flags.type=t_UNKNOWN;
if (!cpu.gdt.GetDescriptor(selector,desc)){
SETFLAGBIT(ZF,false);
return;
@ -651,7 +652,6 @@ void CPU_LAR(Bitu selector,Bitu & ar) {
void CPU_LSL(Bitu selector,Bitu & limit) {
Descriptor desc;Bitu rpl=selector & 3;
flags.type=t_UNKNOWN;
if (!cpu.gdt.GetDescriptor(selector,desc)){
SETFLAGBIT(ZF,false);
return;
@ -694,7 +694,6 @@ void CPU_LSL(Bitu selector,Bitu & limit) {
void CPU_VERR(Bitu selector) {
Descriptor desc;Bitu rpl=selector & 3;
flags.type=t_UNKNOWN;
if (!cpu.gdt.GetDescriptor(selector,desc)){
SETFLAGBIT(ZF,false);
return;
@ -727,7 +726,6 @@ void CPU_VERR(Bitu selector) {
void CPU_VERW(Bitu selector) {
Descriptor desc;Bitu rpl=selector & 3;
flags.type=t_UNKNOWN;
if (!cpu.gdt.GetDescriptor(selector,desc)){
SETFLAGBIT(ZF,false);
return;
@ -846,7 +844,6 @@ void CPU_Init(Section* sec) {
reg_eip=0;
flags.word=FLAG_IF;
flags.type=t_UNKNOWN;
cpu.full.entry=cpu.full.prefix=0;
cpu.state=0xff; //To initialize it the first time

View file

@ -23,6 +23,7 @@
#include "dosbox.h"
#include "cpu.h"
#include "lazyflags.h"
#include "pic.h"

94
src/cpu/lazyflags.h Normal file
View file

@ -0,0 +1,94 @@
/*
* Copyright (C) 2002-2003 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
* 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 Library 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.
*/
//Flag Handling
Bitu get_CF(void);
Bitu get_AF(void);
Bitu get_ZF(void);
Bitu get_SF(void);
Bitu get_OF(void);
Bitu get_PF(void);
#define SETFLAGSb(FLAGB) \
{ \
flags.type=t_UNKNOWN; \
flags.word&=0xffffff00; \
flags.word|=(FLAGB&0xff); \
}
#define SETFLAGSw(FLAGW) \
{ \
flags.type=t_UNKNOWN; \
CPU_SetFlagsw(FLAGW); \
}
#define SETFLAGSd(FLAGD) \
{ \
flags.type=t_UNKNOWN; \
CPU_SetFlags(FLAGD); \
}
#define FILLFLAGS \
{ \
flags.word=(flags.word & ~FLAG_MASK) | \
(get_CF() ? FLAG_CF : 0 ) | \
(get_PF() ? FLAG_PF : 0 ) | \
(get_AF() ? FLAG_AF : 0 ) | \
(get_ZF() ? FLAG_ZF : 0 ) | \
(get_SF() ? FLAG_SF : 0 ) | \
(get_OF() ? FLAG_OF : 0 ); \
flags.type=t_UNKNOWN; \
}
#define LoadCF SETFLAGBIT(CF,get_CF());
#define LoadZF SETFLAGBIT(ZF,get_ZF());
#define LoadSF SETFLAGBIT(SF,get_SF());
#define LoadOF SETFLAGBIT(OF,get_OF());
#define LoadAF SETFLAGBIT(AF,get_AF());
//Types of Flag changing instructions
enum {
t_UNKNOWN=0,
t_ADDb,t_ADDw,t_ADDd,
t_ORb,t_ORw,t_ORd,
t_ADCb,t_ADCw,t_ADCd,
t_SBBb,t_SBBw,t_SBBd,
t_ANDb,t_ANDw,t_ANDd,
t_SUBb,t_SUBw,t_SUBd,
t_XORb,t_XORw,t_XORd,
t_CMPb,t_CMPw,t_CMPd,
t_INCb,t_INCw,t_INCd,
t_DECb,t_DECw,t_DECd,
t_TESTb,t_TESTw,t_TESTd,
t_SHLb,t_SHLw,t_SHLd,
t_SHRb,t_SHRw,t_SHRd,
t_SARb,t_SARw,t_SARd,
t_ROLb,t_ROLw,t_ROLd,
t_RORb,t_RORw,t_RORd,
t_RCLb,t_RCLw,t_RCLd,
t_RCRb,t_RCRw,t_RCRd,
t_NEGb,t_NEGw,t_NEGd,
t_CF,t_ZF,
t_DSHLw,t_DSHLd,
t_DSHRw,t_DSHRd,
t_MUL,t_DIV,
t_NOTDONE,
t_LASTFLAG
};