diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 441fd2e7..6fef35ef 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -35,7 +35,6 @@ Bitu get_CF(void) { switch (lflags.type) { case t_UNKNOWN: - case t_CF: case t_INCb: case t_INCw: case t_INCd: @@ -103,11 +102,11 @@ Bitu get_CF(void) { case t_SARd: return (((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1; case t_NEGb: - return (lf_var1b!=0); + return lf_var1b; case t_NEGw: - return (lf_var1w!=0); + return lf_var1w; case t_NEGd: - return (lf_var1d!=0); + return lf_var1d; case t_ROLb: return lf_resb & 1; case t_ROLw: @@ -115,11 +114,11 @@ Bitu get_CF(void) { case t_ROLd: return lf_resd & 1; case t_RORb: - return (lf_resb & 0x80)>0; + return (lf_resb & 0x80); case t_RORw: - return (lf_resw & 0x8000)>0; + return (lf_resw & 0x8000); case t_RORd: - return (lf_resd & 0x80000000)>0; + return (lf_resd & 0x80000000); case t_ORb: case t_ORw: case t_ORd: @@ -147,7 +146,6 @@ Bitu get_CF(void) { */ Bitu get_AF(void) { Bitu type=lflags.type; -again: switch (type) { case t_UNKNOWN: case t_ROLb: @@ -163,27 +161,24 @@ again: case t_RCLd: case t_RCRd: return GETFLAG(AF); - case t_CF: - type=lflags.prev_type; - goto again; case t_ADDb: case t_ADCb: case t_SBBb: case t_SUBb: case t_CMPb: - return (((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0; + return ((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10; case t_ADDw: case t_ADCw: case t_SBBw: case t_SUBw: case t_CMPw: - return (((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0; + return ((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10; case t_ADCd: case t_ADDd: case t_SBBd: case t_SUBd: case t_CMPd: - return (((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0; + return ((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10; case t_INCb: return (lf_resb & 0x0f) == 0; case t_INCw: @@ -197,11 +192,11 @@ again: case t_DECd: return (lf_resd & 0x0f) == 0x0f; case t_NEGb: - return (lf_var1b & 0x0f) > 0; + return lf_var1b & 0x0f; case t_NEGw: - return (lf_var1w & 0x0f) > 0; + return lf_var1w & 0x0f; case t_NEGd: - return (lf_var1d & 0x0f) > 0; + return lf_var1d & 0x0f; case t_ORb: case t_ORw: case t_ORd: @@ -241,7 +236,6 @@ again: Bitu get_ZF(void) { Bitu type=lflags.type; -again: switch (type) { case t_UNKNOWN: case t_ROLb: @@ -257,9 +251,6 @@ again: case t_RCLd: case t_RCRd: return GETFLAG(ZF); - case t_CF: - type=lflags.prev_type; - goto again; case t_ADDb: case t_ORb: case t_ADCb: @@ -325,7 +316,6 @@ again: */ Bitu get_SF(void) { Bitu type=lflags.type; -again: switch (type) { case t_UNKNOWN: case t_ROLb: @@ -341,9 +331,6 @@ again: case t_RCLd: case t_RCRd: return GETFLAG(SF); - case t_CF: - type=lflags.prev_type; - goto again; case t_ADDb: case t_ORb: case t_ADCb: @@ -359,7 +346,7 @@ again: case t_SHRb: case t_SARb: case t_NEGb: - return (lf_resb>=0x80); + return (lf_resb&0x80); case t_ADDw: case t_ORw: case t_ADCw: @@ -377,7 +364,7 @@ again: case t_DSHLw: case t_DSHRw: case t_NEGw: - return (lf_resw>=0x8000); + return (lf_resw&0x8000); case t_ADDd: case t_ORd: case t_ADCd: @@ -395,7 +382,7 @@ again: case t_DSHLd: case t_DSHRd: case t_NEGd: - return (lf_resd>=0x80000000); + return (lf_resd&0x80000000); case t_DIV: case t_MUL: return false; /* Unkown */ @@ -406,69 +393,32 @@ again: } Bitu get_OF(void) { - Bit8u var1b7, var2b7, resultb7; - Bit16u var1w15, var2w15, resultw15; - Bit32u var1d31, var2d31, resultd31; - Bitu type=lflags.type; -again: switch (type) { case t_UNKNOWN: case t_MUL: - case t_RCLb: - case t_RCLw: - case t_RCLd: - case t_SARb: - case t_SARw: - case t_SARd: return GETFLAG(OF); - case t_CF: - type=lflags.prev_type; - goto again; case t_ADDb: case t_ADCb: -// return (((lf_resb) ^ (lf_var2b)) & ((lf_resb) ^ (lf_var1b)) & 0x80)>0; - var1b7 = lf_var1b & 0x80; - var2b7 = lf_var2b & 0x80; - resultb7 = lf_resb & 0x80; - return (var1b7 == var2b7) && (resultb7 ^ var2b7); + return ((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var2b)) & 0x80; case t_ADDw: case t_ADCw: -// return (((lf_resw) ^ (lf_var2w)) & ((lf_resw) ^ (lf_var1w)) & 0x8000)>0; - var1w15 = lf_var1w & 0x8000; - var2w15 = lf_var2w & 0x8000; - resultw15 = lf_resw & 0x8000; - return (var1w15 == var2w15) && (resultw15 ^ var2w15); + return ((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var2w)) & 0x8000; case t_ADDd: case t_ADCd: -//TODO fix dword Overflow - var1d31 = lf_var1d & 0x80000000; - var2d31 = lf_var2d & 0x80000000; - resultd31 = lf_resd & 0x80000000; - return (var1d31 == var2d31) && (resultd31 ^ var2d31); + return ((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var2d)) & 0x80000000; case t_SBBb: case t_SUBb: case t_CMPb: -// return (((lf_var1b) ^ (lf_var2b)) & ((lf_var1b) ^ (lf_resb)) & 0x80)>0; - var1b7 = lf_var1b & 0x80; - var2b7 = lf_var2b & 0x80; - resultb7 = lf_resb & 0x80; - return (var1b7 ^ var2b7) && (var1b7 ^ resultb7); + return ((lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb)) & 0x80; case t_SBBw: case t_SUBw: case t_CMPw: -// return (((lf_var1w) ^ (lf_var2w)) & ((lf_var1w) ^ (lf_resw)) & 0x8000)>0; - var1w15 = lf_var1w & 0x8000; - var2w15 = lf_var2w & 0x8000; - resultw15 = lf_resw & 0x8000; - return (var1w15 ^ var2w15) && (var1w15 ^ resultw15); + return ((lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw)) & 0x8000; case t_SBBd: case t_SUBd: case t_CMPd: - var1d31 = lf_var1d & 0x80000000; - var2d31 = lf_var2d & 0x80000000; - resultd31 = lf_resd & 0x80000000; - return (var1d31 ^ var2d31) && (var1d31 ^ resultd31); + return ((lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd)) & 0x80000000; case t_INCb: return (lf_resb == 0x80); case t_INCw: @@ -488,43 +438,30 @@ again: case t_NEGd: return (lf_var1d == 0x80000000); case t_ROLb: - return ((lf_resb & 0x80) ^ (lf_resb & 1 ? 0x80 : 0)) != 0; - case t_ROLw: - return ((lf_resw & 0x8000) ^ (lf_resw & 1 ? 0x8000 : 0)) != 0; - case t_ROLd: - return ((lf_resd & 0x80000000) ^ (lf_resd & 1 ? 0x80000000 : 0)) != 0; - case t_SHLb: - if (lf_var2b>9) return false; - return ((lf_resb & 0x80) ^ - ((lf_var1b << (lf_var2b - 1)) & 0x80)) != 0; - case t_SHLw: - if (lf_var2b>17) return false; - return ((lf_resw & 0x8000) ^ - ((lf_var1w << (lf_var2b - 1)) & 0x8000)) != 0; - case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - return ((lf_resw & 0x8000) ^ - (((lf_var1d << (lf_var2b - 1)) >> 16) & 0x8000)) != 0; - case t_SHLd: - case t_DSHLd: - return ((lf_resd & 0x80000000) ^ - ((lf_var1d << (lf_var2b - 1)) & 0x80000000)) != 0; case t_RORb: + case t_RCLb: case t_RCRb: - return ((lf_resb ^ (lf_resb << 1)) & 0x80) > 0; - case t_RORw: - case t_RCRw: - case t_DSHRw: - return ((lf_resw ^ (lf_resw << 1)) & 0x8000) > 0; - case t_RORd: - case t_RCRd: - case t_DSHRd: - return ((lf_resd ^ (lf_resd << 1)) & 0x80000000) > 0; + case t_SHLb: case t_SHRb: - return (lf_resb >= 0x40); + return (lf_resb ^ lf_var1b) & 0x80; + case t_ROLw: + case t_RORw: + case t_RCLw: + case t_RCRw: + case t_SHLw: case t_SHRw: - return (lf_resw >= 0x4000); + case t_DSHRw: + case t_DSHLw: + return (lf_resw ^ lf_var1w) & 0x8000; + case t_ROLd: + case t_RORd: + case t_RCLd: + case t_RCRd: + case t_SHLd: case t_SHRd: - return (lf_resd >= 0x40000000); + case t_DSHRd: + case t_DSHLd: + return (lf_resd ^ lf_var1d) & 0x80000000; case t_ORb: case t_ORw: case t_ORd: @@ -537,7 +474,10 @@ again: case t_TESTb: case t_TESTw: case t_TESTd: - return false; /* Return false */ + case t_SARb: + case t_SARw: + case t_SARd: + return false; /* Return false */ case t_DIV: return false; /* Unkown */ default: @@ -547,22 +487,22 @@ again: } Bit16u parity_lookup[256] = { - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, + FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF }; Bitu get_PF(void) { @@ -576,7 +516,10 @@ Bitu get_PF(void) { } -void FillFlags(void) { +#if 0 + +Bitu FillFlags(void) { +// if (lflags.type==t_UNKNOWN) return reg_flags; Bitu new_word=(reg_flags & ~FLAG_MASK); if (get_CF()) new_word|=FLAG_CF; if (get_PF()) new_word|=FLAG_PF; @@ -586,237 +529,431 @@ void FillFlags(void) { if (get_OF()) new_word|=FLAG_OF; reg_flags=new_word; lflags.type=t_UNKNOWN; + return reg_flags; } -#if 0 +#else -Bitu get_Flags(void) { - Bitu new_flags=0; +#define DOFLAG_PF reg_flags=(reg_flags & ~FLAG_PF) | parity_lookup[lf_resb]; + +#define DOFLAG_AF reg_flags=(reg_flags & ~FLAG_AF) | (((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10); + +#define DOFLAG_ZFb SETFLAGBIT(ZF,lf_resb==0); +#define DOFLAG_ZFw SETFLAGBIT(ZF,lf_resw==0); +#define DOFLAG_ZFd SETFLAGBIT(ZF,lf_resd==0); + +#define DOFLAG_SFb reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resb & 0x80) >> 0); +#define DOFLAG_SFw reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resw & 0x8000) >> 8); +#define DOFLAG_SFd reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resd & 0x80000000) >> 24); + + + +#define SET_FLAG SETFLAGBIT +Bitu FillFlags(void) { switch (lflags.type) { + case t_UNKNOWN: + break; case t_ADDb: - SET_FLAG(FLAG_CF,(lf_resb0); + SET_FLAG(CF,(lf_resb0); + SET_FLAG(CF,(lf_resw0); + SET_FLAG(CF,(lf_resd0); + SET_FLAG(CF,(lf_resb < lf_var1b) || (lflags.oldcf && (lf_resb == lf_var1b))); + DOFLAG_AF; + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var1b)) & 0x80); + DOFLAG_PF; break; case t_ADCw: - SET_FLAG(FLAG_CF,(lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w))); - SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0); + SET_FLAG(CF,(lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w))); + DOFLAG_AF; + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var1w)) & 0x8000); + DOFLAG_PF; break; case t_ADCd: - SET_FLAG(FLAG_CF,(lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d))); - SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0); + SET_FLAG(CF,(lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d))); + DOFLAG_AF; + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var1d)) & 0x80000000); + DOFLAG_PF; break; - + case t_SBBb: - SET_FLAG(FLAG_CF,(lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff))); - SET_FLAG(FLAG_AF,(((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10)>0); + SET_FLAG(CF,(lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff))); + DOFLAG_AF; + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb) & 0x80); + DOFLAG_PF; break; case t_SBBw: - SET_FLAG(FLAG_CF,(lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff))); - SET_FLAG(FLAG_AF,(((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10)>0); + SET_FLAG(CF,(lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff))); + DOFLAG_AF; + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw) & 0x8000); + DOFLAG_PF; break; case t_SBBd: - SET_FLAG(FLAG_CF,(lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff))); - SET_FLAG(FLAG_AF,(((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10)>0); + SET_FLAG(CF,(lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff))); + DOFLAG_AF; + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd) & 0x80000000); + DOFLAG_PF; break; case t_SUBb: case t_CMPb: - SET_FLAG(FLAG_CF,(lf_var1b0); + SET_FLAG(CF,(lf_var1b0); + SET_FLAG(CF,(lf_var1w0); + SET_FLAG(CF,(lf_var1d8) SET_FLAG(FLAG_CF,false); - else SET_FLAG(FLAG_CF,(lf_var1b >> (8-lf_var2b)) & 1); + if (lf_var2b>8) SET_FLAG(CF,false); + else SET_FLAG(CF,(lf_var1b >> (8-lf_var2b)) & 1); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); + DOFLAG_PF; break; case t_SHLw: - if (lf_var2b>16) SET_FLAG(FLAG_CF,false); - else SET_FLAG(FLAG_CF,(lf_var1w >> (16-lf_var2b)) & 1); + if (lf_var2b>16) SET_FLAG(CF,false); + else SET_FLAG(CF,(lf_var1w >> (16-lf_var2b)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + DOFLAG_PF; break; case t_SHLd: - SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); + SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + DOFLAG_PF; break; - case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); + case t_DSHLw: + SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + DOFLAG_PF; break; case t_DSHLd: - SET_FLAG(FLAG_CF,(lf_var1d >> (32 - lf_var2b)) & 1); + SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + DOFLAG_PF; break; case t_SHRb: - SET_FLAG(FLAG_CF,(lf_var1b >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); + DOFLAG_PF; break; case t_SHRw: - SET_FLAG(FLAG_CF,(lf_var1w >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + DOFLAG_PF; break; case t_SHRd: - SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + DOFLAG_PF; break; case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + DOFLAG_PF; break; case t_DSHRd: - SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + DOFLAG_PF; break; case t_SARb: - SET_FLAG(FLAG_CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,false); + DOFLAG_PF; break; case t_SARw: - SET_FLAG(FLAG_CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,false); + DOFLAG_PF; break; case t_SARd: - SET_FLAG(FLAG_CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,false); + DOFLAG_PF; break; case t_ROLb: - SET_FLAG(FLAG_CF,lf_resb & 1); + SET_FLAG(CF,lf_resb & 1); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); break; case t_ROLw: - SET_FLAG(FLAG_CF,lf_resw & 1); + SET_FLAG(CF,lf_resw & 1); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); break; case t_ROLd: - SET_FLAG(FLAG_CF,lf_resd & 1); + SET_FLAG(CF,lf_resd & 1); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); break; case t_RORb: - SET_FLAG(FLAG_CF,(lf_resb & 0x80)>0); + SET_FLAG(CF,(lf_resb & 0x80)); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); break; case t_RORw: - SET_FLAG(FLAG_CF,(lf_resw & 0x8000)>0); + SET_FLAG(CF,(lf_resw & 0x8000)); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); break; case t_RORd: - SET_FLAG(FLAG_CF,(lf_resd & 0x80000000)>0); + SET_FLAG(CF,(lf_resd & 0x80000000)); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); break; + case t_RCLb: + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); + break; + case t_RCLw: + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); + break; + case t_RCLd: + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); + break; case t_RCRb: - SET_FLAG(FLAG_CF,(lf_var1b >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); + SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); break; case t_RCRw: - SET_FLAG(FLAG_CF,(lf_var1w >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); + SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); break; case t_RCRd: - SET_FLAG(FLAG_CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); + SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); break; - case t_INCb: - SET_FLAG(FLAG_OF,(lf_resb == 0x80)); - SET_FLAG(FLAG_AF,((lf_resb & 0x0f) == 0)); + SET_FLAG(AF,(lf_resb & 0x0f) == 0); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_resb == 0x80)); + DOFLAG_PF; break; case t_INCw: - SET_FLAG(FLAG_OF,(lf_resw == 0x8000)); - SET_FLAG(FLAG_AF,((lf_resw & 0x0f) == 0)); + SET_FLAG(AF,(lf_resw & 0x0f) == 0); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw == 0x8000)); + DOFLAG_PF; break; case t_INCd: - SET_FLAG(FLAG_OF,(lf_resd == 0x80000000)); - SET_FLAG(FLAG_AF,((lf_resd & 0x0f) == 0)); + SET_FLAG(AF,(lf_resd & 0x0f) == 0); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd == 0x80000000)); + DOFLAG_PF; break; - case t_DECb: - SET_FLAG(FLAG_OF,(lf_resb == 0x7f)); + SET_FLAG(AF,(lf_resb & 0x0f) == 0); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_resb == 0x7f)); + DOFLAG_PF; break; case t_DECw: - SET_FLAG(FLAG_OF,(lf_resw == 0x7fff)); + SET_FLAG(AF,(lf_resw & 0x0f) == 0); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_resw == 0x7fff)); + DOFLAG_PF; break; case t_DECd: - SET_FLAG(FLAG_OF,(lf_resd == 0x7fffffff)); + SET_FLAG(AF,(lf_resd & 0x0f) == 0); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_resd == 0x7fffffff)); + DOFLAG_PF; break; - case t_NEGb: - SET_FLAG(FLAG_CF,(lf_var1b!=0)); + SET_FLAG(CF,(lf_var1b!=0)); + SET_FLAG(AF,(lf_resb & 0x0f) == 0); + DOFLAG_ZFb; + SET_FLAG(SF,(lf_resb&0x80)); + SET_FLAG(OF,(lf_var1b == 0x80)); + DOFLAG_PF; break; case t_NEGw: - SET_FLAG(FLAG_CF,(lf_var1w!=0)); + SET_FLAG(CF,(lf_var1w!=0)); + SET_FLAG(AF,(lf_resw & 0x0f) == 0); + DOFLAG_ZFw; + SET_FLAG(SF,(lf_resw&0x8000)); + SET_FLAG(OF,(lf_var1w == 0x8000)); + DOFLAG_PF; break; case t_NEGd: - SET_FLAG(FLAG_CF,(lf_var1d!=0)); + SET_FLAG(CF,(lf_var1d!=0)); + SET_FLAG(AF,(lf_resd & 0x0f) == 0); + DOFLAG_ZFd; + SET_FLAG(SF,(lf_resd&0x80000000)); + SET_FLAG(OF,(lf_var1d == 0x80000000)); + DOFLAG_PF; break; case t_DIV: - SET_FLAG(FLAG_CF,false); /* Unkown */ + case t_MUL: break; + default: LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type); return 0; } - lflags.word=new_flags; - return 0; + lflags.type=t_UNKNOWN; + return reg_flags; } #endif