First post, by superfury
Anyone can see what's going wrong, when calculating the BCD instruction flags?
//BCD opcodes!byte CPU8086_internal_DAA(){word ALVAL, oldCF;CPUPROT1oldCF = FLAG_CF; //Save old Carry!ALVAL = (word)REG_AL;if (((ALVAL&0xF)>9) || FLAG_AF){oper1 = ALVAL+6;ALVAL = (oper1&0xFF);FLAGW_CF((((oper1&0xFF00)>0)?1:0)|FLAG_CF);FLAGW_AF(1);}else FLAGW_AF(0);if (((REG_AL)>0x99) || oldCF){ALVAL += 0x60;FLAGW_CF(1);}else{FLAGW_CF(0);}REG_AL = (byte)(ALVAL&0xFF); //Write the value back to AL!flag_szp8(REG_AL);//if (ALVAL&0xFF00) FLAGW_OF(1); else FLAGW_OF(0); //Undocumented: Overflow flag!CPUPROT2if (CPU_apply286cycles()==0) //No 80286+ cycles instead?{CPU[activeCPU].cycles_OP += 4; //Timings!}return 0;}byte CPU8086_internal_DAS(){INLINEREGISTER byte tempCF, tempAL;INLINEREGISTER word bigAL;bigAL = (word)(tempAL = REG_AL);tempCF = FLAG_CF; //Save old values!CPUPROT1if (((bigAL&0xF)>9) || FLAG_AF){oper1 = bigAL = REG_AL-6;REG_AL = oper1&255;FLAGW_CF(tempCF|((oper1&0xFF00)>0));FLAGW_AF(1);}else FLAGW_AF(0);if ((tempAL>0x99) || tempCF){bigAL -= 0x60;REG_AL = (byte)(bigAL&0xFF);FLAGW_CF(1);}else{FLAGW_CF(0);}
flag_szp8(REG_AL);//if (bigAL&0xFF00) FLAGW_OF(1); else FLAGW_OF(0); //Undocumented: Overflow flag!CPUPROT2if (CPU_apply286cycles()==0) //No 80286+ cycles instead?{CPU[activeCPU].cycles_OP += 4; //Timings!}return 0;}byte CPU8086_internal_AAA(){CPUPROT1if (EMULATED_CPU<CPU_80286) //Before new CPU?{if (((REG_AL&0xF)>9) || FLAG_AF){REG_AL += 6;++REG_AH;FLAGW_AF(1);FLAGW_CF(1);}else{FLAGW_AF(0);FLAGW_CF(0);}REG_AL &= 0xF;}else //Newer CPUs?{if (((REG_AL&0xF)>9) || FLAG_AF){REG_AX += 0x0106;FLAGW_AF(1);FLAGW_CF(1);}else{FLAGW_AF(0);FLAGW_CF(0);}REG_AL &= 0xF;}//flag_szp8(REG_AL); //Basic flags!flag_p8(REG_AL); //Parity is affected!if (EMULATED_CPU<CPU_80286) //Before new CPU?{FLAGW_ZF((REG_AL==0)?1:0); //Zero is affected!}else{FLAGW_ZF((REG_AL==0)?1:0); //Zero is affected!FLAGW_SF(0); //Clear Sign!}//z=s=p=o=?CPUPROT2if (CPU_apply286cycles()==0) //No 80286+ cycles instead?{CPU[activeCPU].cycles_OP += 4; //Timings!}return 0;}byte CPU8086_internal_AAS(){CPUPROT1if (EMULATED_CPU<CPU_80286) //Before new CPU?{if (((REG_AL&0xF)>9) || FLAG_AF){REG_AL -= 6;--REG_AH;FLAGW_AF(1);FLAGW_CF(1);}else{FLAGW_AF(0);FLAGW_CF(0);}REG_AL &= 0xF;}else //Newer CPUs?{if (((REG_AL&0xF)>9) || FLAG_AF){REG_AX -= 0x0106;FLAGW_AF(1);FLAGW_CF(1);}else{FLAGW_AF(0);FLAGW_CF(0);}REG_AL &= 0xF;}//flag_szp8(REG_AL); //Basic flags!flag_p8(REG_AL); //Parity is affected!if (EMULATED_CPU<CPU_80286) //Before new CPU?{FLAGW_ZF((REG_AL==0)?1:0); //Zero is affected!}else{FLAGW_ZF((REG_AL==0)?1:0); //Zero is affected!FLAGW_SF(0); //Sign is cleared!}//z=s=o=p=?CPUPROT2if (CPU_apply286cycles()==0) //No 80286+ cycles instead?{CPU[activeCPU].cycles_OP += 4; //Timings!}return 0;}OPTINLINE byte CPU8086_internal_AAM(byte data){CPUPROT1if ((!data) && (CPU[activeCPU].instructionstep==0)) //First step?{CPU[activeCPU].cycles_OP += 1; //Timings always!++CPU[activeCPU].instructionstep; //Next step after we're done!CPU[activeCPU].executed = 0; //Not executed yet!return 1;}word quotient, remainder;byte error, applycycles;CPU8086_internal_DIV(REG_AL,data,"ient,&remainder,&error,8,2,6,&applycycles);if (error) //Error occurred?{CPU_exDIV0(); //Raise error that's requested!return 1;}else //Valid result?{REG_AH = (byte)(quotient&0xFF);REG_AL = (byte)(remainder&0xFF);//Flags are set on newer CPUs according to the MOD operation: Sign, Zero and Parity are set according to the mod operation(AL) and Overflow, Carry and Auxiliary carry are cleared.flag_szp8(REG_AL); //Result of MOD instead!FLAGW_OF(0); FLAGW_CF(0); FLAGW_AF(0); //Clear these!//C=O=A=?}CPUPROT2return 0;}OPTINLINE byte CPU8086_internal_AAD(byte data){CPUPROT1oper2 = (word)REG_AL; //What to add!REG_AX = (REG_AH*data); //AADoper1 = REG_AX; //Load for addition!op_add16(); //Add, 16-bit, including flags!REG_AX = res16; //The result to load!REG_AH = 0; //AH is cleared!//C=O=A=?CPUPROT2if (CPU_apply286cycles()==0) //No 80286+ cycles instead?{CPU[activeCPU].cycles_OP += 60; //Timings!}return 0;}
The 80186 test suite fails on these, expecting the Overflow flag(???) to be set in some of these cases, as well as the auxiliary flag not to be set?
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io
