diff --git a/src/cpu/flags.cpp b/src/cpu/flags.cpp index 33c3224b..c7adc6ed 100644 --- a/src/cpu/flags.cpp +++ b/src/cpu/flags.cpp @@ -29,7 +29,7 @@ /* CF Carry Flag -- Set on high-order bit carry or borrow; cleared otherwise. */ -bool get_CF(void) { +Bitu get_CF(void) { switch (flags.type) { case t_UNKNOWN: @@ -44,7 +44,7 @@ bool get_CF(void) { case t_RCLb: case t_RCLw: case t_RCLd: - return flags.cf; + return GETFLAG(CF); break; case t_ADDb: return (flags.result.b0); + break; + case t_ADDw: + SET_FLAG(FLAG_CF,(flags.result.w0); + break; + case t_ADDd: + SET_FLAG(FLAG_CF,(flags.result.d0); + break; + + + case t_ADCb: + SET_FLAG(FLAG_CF,(flags.result.b < flags.var1.b) || (flags.oldcf && (flags.result.b == flags.var1.b))); + SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0); + break; + case t_ADCw: + SET_FLAG(FLAG_CF,(flags.result.w < flags.var1.w) || (flags.oldcf && (flags.result.w == flags.var1.w))); + SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0); + break; + case t_ADCd: + SET_FLAG(FLAG_CF,(flags.result.d < flags.var1.d) || (flags.oldcf && (flags.result.d == flags.var1.d))); + SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0); + break; + + + case t_SBBb: + SET_FLAG(FLAG_CF,(flags.var1.b < flags.result.b) || (flags.oldcf && (flags.var2.b==0xff))); + SET_FLAG(FLAG_AF,(((flags.var1.b ^ flags.var2.b) ^ flags.result.b) & 0x10)>0); + break; + case t_SBBw: + SET_FLAG(FLAG_CF,(flags.var1.w < flags.result.w) || (flags.oldcf && (flags.var2.w==0xffff))); + SET_FLAG(FLAG_AF,(((flags.var1.w ^ flags.var2.w) ^ flags.result.w) & 0x10)>0); + break; + case t_SBBd: + SET_FLAG(FLAG_CF,(flags.var1.d < flags.result.d) || (flags.oldcf && (flags.var2.d==0xffffffff))); + SET_FLAG(FLAG_AF,(((flags.var1.d ^ flags.var2.d) ^ flags.result.d) & 0x10)>0); + break; + + + case t_SUBb: + case t_CMPb: + SET_FLAG(FLAG_CF,(flags.var1.b0); + break; + case t_SUBw: + case t_CMPw: + SET_FLAG(FLAG_CF,(flags.var1.w0); + break; + case t_SUBd: + case t_CMPd: + SET_FLAG(FLAG_CF,(flags.var1.d0); + break; + + + case t_ORb: + SET_FLAG(FLAG_CF,false); + break; + case t_ORw: + SET_FLAG(FLAG_CF,false); + break; + case t_ORd: + SET_FLAG(FLAG_CF,false); + break; + + + case t_TESTb: + case t_ANDb: + SET_FLAG(FLAG_CF,false); + break; + case t_TESTw: + case t_ANDw: + SET_FLAG(FLAG_CF,false); + break; + case t_TESTd: + case t_ANDd: + SET_FLAG(FLAG_CF,false); + break; + + + case t_XORb: + SET_FLAG(FLAG_CF,false); + break; + case t_XORw: + SET_FLAG(FLAG_CF,false); + break; + case t_XORd: + SET_FLAG(FLAG_CF,false); + break; + + + case t_SHLb: + if (flags.var2.b>8) SET_FLAG(FLAG_CF,false); + else SET_FLAG(FLAG_CF,(flags.var1.b >> (8-flags.var2.b)) & 1); + break; + case t_SHLw: + if (flags.var2.b>16) SET_FLAG(FLAG_CF,false); + else SET_FLAG(FLAG_CF,(flags.var1.w >> (16-flags.var2.b)) & 1); + break; + case t_SHLd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + break; + + + case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ + SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + break; + case t_DSHLd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (32 - flags.var2.b)) & 1); + break; + + + case t_SHRb: + SET_FLAG(FLAG_CF,(flags.var1.b >> (flags.var2.b - 1)) & 1); + break; + case t_SHRw: + SET_FLAG(FLAG_CF,(flags.var1.w >> (flags.var2.b - 1)) & 1); + break; + case t_SHRd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + break; + + + case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ + SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + break; + case t_DSHRd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + break; + + + case t_SARb: + SET_FLAG(FLAG_CF,(((Bit8s) flags.var1.b) >> (flags.var2.b - 1)) & 1); + break; + case t_SARw: + SET_FLAG(FLAG_CF,(((Bit16s) flags.var1.w) >> (flags.var2.b - 1)) & 1); + break; + case t_SARd: + SET_FLAG(FLAG_CF,(((Bit32s) flags.var1.d) >> (flags.var2.b - 1)) & 1); + break; + + + case t_ROLb: + SET_FLAG(FLAG_CF,flags.result.b & 1); + break; + case t_ROLw: + SET_FLAG(FLAG_CF,flags.result.w & 1); + break; + case t_ROLd: + SET_FLAG(FLAG_CF,flags.result.d & 1); + break; + + + case t_RORb: + SET_FLAG(FLAG_CF,(flags.result.b & 0x80)>0); + break; + case t_RORw: + SET_FLAG(FLAG_CF,(flags.result.w & 0x8000)>0); + break; + case t_RORd: + SET_FLAG(FLAG_CF,(flags.result.d & 0x80000000)>0); + break; + + + case t_RCRb: + SET_FLAG(FLAG_CF,(flags.var1.b >> (flags.var2.b - 1)) & 1); + break; + case t_RCRw: + SET_FLAG(FLAG_CF,(flags.var1.w >> (flags.var2.b - 1)) & 1); + break; + case t_RCRd: + SET_FLAG(FLAG_CF,(flags.var1.d >> (flags.var2.b - 1)) & 1); + break; + + + case t_INCb: + SET_FLAG(FLAG_OF,(flags.result.b == 0x80)); + SET_FLAG(FLAG_AF,((flags.result.b & 0x0f) == 0)); + break; + case t_INCw: + SET_FLAG(FLAG_OF,(flags.result.w == 0x8000)); + SET_FLAG(FLAG_AF,((flags.result.w & 0x0f) == 0)); + break; + case t_INCd: + SET_FLAG(FLAG_OF,(flags.result.d == 0x80000000)); + SET_FLAG(FLAG_AF,((flags.result.d & 0x0f) == 0)); + break; + + + case t_DECb: + SET_FLAG(FLAG_OF,(flags.result.b == 0x7f)); + break; + case t_DECw: + SET_FLAG(FLAG_OF,(flags.result.w == 0x7fff)); + break; + case t_DECd: + SET_FLAG(FLAG_OF,(flags.result.d == 0x7fffffff)); + break; + + + case t_NEGb: + SET_FLAG(FLAG_CF,(flags.var1.b!=0)); + break; + case t_NEGw: + SET_FLAG(FLAG_CF,(flags.var1.w!=0)); + break; + case t_NEGd: + SET_FLAG(FLAG_CF,(flags.var1.d!=0)); + break; + + + case t_DIV: + SET_FLAG(FLAG_CF,false); /* Unkown */ + break; + default: + LOG(LOG_ERROR|LOG_CPU,"Unhandled flag type %d",flags.type); + return 0; + } + flags.word=new_flags; + return 0; +} + +Bit8u * blah=(Bit8u *)&get_Flags;