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:
parent
cbd33bfa95
commit
708d8cb3c3
8 changed files with 160 additions and 29 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -80,10 +80,9 @@ static INLINE Bit32u Pop_32(void) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if (flags.intf && PIC_IRQCheck) { \
|
||||
SaveIP(); \
|
||||
LEAVECORE; \
|
||||
PIC_runIRQs(); \
|
||||
LoadIP(); \
|
||||
} \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "dosbox.h"
|
||||
#include "cpu.h"
|
||||
#include "lazyflags.h"
|
||||
#include "pic.h"
|
||||
|
||||
|
||||
|
|
94
src/cpu/lazyflags.h
Normal file
94
src/cpu/lazyflags.h
Normal 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
|
||||
};
|
||||
|
Loading…
Add table
Reference in a new issue