First post, by superfury
I'm trying to get the (I)MUL test to pass it's flags test, but for some reason it won't give the correct results.
Different MUL instructions:
80186+ IMUL:
void CPU186_OP69(){if (modrm_check16(¶ms,1,1)) return; //Abort on fault!temp1.val32 = modrm_read16(¶ms,1);temp2.val32 = immw;modrm_decode16(¶ms,&info,0);debugger_setcommand("IMUL %s,%04X",info.text,temp2);if ((temp1.val32 &0x8000)==0x8000) temp1.val32 |= 0xFFFF0000;if ((temp2.val32 &0x8000)==0x8000) temp2.val32 |= 0xFFFF0000;temp3.val32 = ((temp1.val32*temp2.val32)&0xFFFFFFFF);REG_AX = temp3.val16;REG_DX = temp3.val16high;if (((temp1.val32>>15)==0) || ((temp1.val32>>15)==0x1FFFF)) FLAGW_OF(0);else FLAGW_OF(1);FLAGW_CF(FLAG_OF); //OF=CF!}
8086 MULB:
case 4: //MULBtempAL = REG_AL; //Save a backup for calculating cycles!temp1.val32 = (uint32_t)oper1b * (uint32_t)REG_AL;REG_AX = temp1.val16 & 0xFFFF;if (((temp1.val16&0xFF80)==0) || ((temp1.val16&0xFF80)==0xFF80)){FLAGW_OF(0); //Both zeroed!}else FLAGW_OF(1); //Set due to overflow!FLAGW_CF(FLAG_OF); //Same!tempAL = FLAG_ZF; //Backup!flag_szp8(REG_AL);if (EMULATED_CPU==CPU_8086) //8086 only?{FLAGW_ZF(tempAL); //Restore Zero flag!if (REG_AX) FLAGW_ZF(0); //8086/8088 clears the Zero flag when not zero only. Undocumented bug!}if (MODRM_EA(params)) //Memory?{CPU[activeCPU].cycles_OP = 76+MODRM_EA(params); //Mem max!}else //Register?{CPU[activeCPU].cycles_OP = 70; //Reg!}if (NumberOfSetBits(tempAL)>1) //More than 1 bit set?{CPU[activeCPU].cycles_OP += NumberOfSetBits(tempAL) - 1; //1 cycle for all bits more than 1 bit set!}break;
8086 IMULB:
case 5: //IMULBoper1 = oper1b;temp1.val32 = REG_AL;temp2.val32 = oper1b;//Sign extend!if ((temp1.val8 & 0x80) == 0x80) temp1.val32 |= 0xFFFFFF00;if ((temp2.val8 & 0x80) == 0x80) temp2.val32 |= 0xFFFFFF00;//Multiply and convert to 16-bit!temp3.val32s = temp1.val32s; //Load and...temp3.val32s *= temp2.val32s; //Multiply!REG_AX = temp3.val16; //Load into AX!if (((temp1.val16&0xFF80)==0) || ((temp1.val16&0xFF80)==0xFF80)){FLAGW_OF(0); //Both zeroed!}else FLAGW_OF(1); //Set due to overflow!FLAGW_CF(FLAG_OF); //Same!if (EMULATED_CPU==CPU_8086){FLAGW_ZF(0); //Clear ZF!}if (MODRM_EA(params)) //Memory?{CPU[activeCPU].cycles_OP = 86 + MODRM_EA(params); //Mem max!}else //Register?{CPU[activeCPU].cycles_OP = 80; //Reg!}break;
8086 MULW:
case 4: //MULWtempAX = REG_AX; //Save a backup for calculating cycles!temp1.val32 = (uint32_t)oper1 * (uint32_t)REG_AX;REG_AX = temp1.val16;REG_DX = temp1.val16high;if (((temp1.val32>>15)==0) || ((temp1.val32>>15)==0x1FFFF)) FLAGW_OF(0);else FLAGW_OF(1);FLAGW_CF(FLAG_OF); //OF=CF!tempAL = FLAG_ZF; //Backup!flag_szp16(REG_AX);if (EMULATED_CPU==CPU_8086){FLAGW_ZF(tempAL); //Restore!if ((EMULATED_CPU==CPU_8086) && temp1.val32) FLAGW_ZF(0); //8086/8088 clears the Zero flag when not zero only.}if (MODRM_EA(params)) //Memory?{CPU[activeCPU].cycles_OP = 124 + MODRM_EA(params); //Mem max!}else //Register?{CPU[activeCPU].cycles_OP = 118; //Reg!}if (NumberOfSetBits(tempAX)>1) //More than 1 bit set?{CPU[activeCPU].cycles_OP += NumberOfSetBits(tempAX) - 1; //1 cycle for all bits more than 1 bit set!}break;
8086 IMULW:
case 5: //IMULWtemp1.val32 = REG_AX;temp2.val32 = oper1;//Sign extend!if (temp1.val16 & 0x8000) temp1.val32 |= 0xFFFF0000;if (temp2.val16 & 0x8000) temp2.val32 |= 0xFFFF0000;temp3.val32s = temp1.val32s; //Load and...temp3.val32s *= temp2.val32s; //Signed multiplication!REG_AX = temp3.val16; //into register axREG_DX = temp3.val16high; //into register dxif (((temp1.val32>>15)==0) || ((temp1.val32>>15)==0x1FFFF)) FLAGW_OF(0);else FLAGW_OF(1);FLAGW_CF(FLAG_OF); //OF=CF!if (EMULATED_CPU==CPU_8086){FLAGW_ZF(0); //Clear ZF!}if (MODRM_EA(params)) //Memory?{CPU[activeCPU].cycles_OP = 128 + MODRM_EA(params); //Mem max!}else //Register?{CPU[activeCPU].cycles_OP = 134; //Reg max!}break;
I'm getting the strangest flag errors, as can be seen in the log within the ZIP file(there's two files: debugger.log contains the disassembly, ROM_log.log contains the surrounding wrapper test results).
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io