First post, by superfury
I'm trying to get the flags properly implemented in UniPCemu, but the 80186(or 80286, since it expects the high 4 bits to be zeroed?) testsuite says the carry and adjust flags are incorrect?
//Addition Carry, Overflow, Adjust logic
//Tables based on http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt
//Index Bit0=sumsign, Bit1=num2sign(add or sub negated value), Bit2=num1sign(v1)
byte addoverflow[8] = {0,1,0,0,0,0,1,0};
byte suboverflow[8] = {0,0,0,1,1,0,0,0};
//Flags(Aux/Carry):
//ADD: ((op1)^(op2))^(((op1)^(result))&~((op1)^(op2)))^result
//SUB: ((op1)^(op2))^(((op1)^(result))&((op1)^(op2)))^result
//Auxiliary flag: ((op1^op2)^((op1^result)&(~(op1^op2))^result
//Auxiliary flag: ((op1)^(op2))^(((op1)^(result))&~((op1)^(op2)))^result
//borrow/carry bits
#define bcbitsa(v1,v2) (((v1)^(v2))^(((v1)^(dst))&~((v1)^(v2)))^dst)
#define bcbitss(v1,v2) (((v1)^(v2))^(((v1)^(dst))&((v1)^(v2)))^dst)
void flag_adcoa8(uint8_t v1, uint16_t add, uint16_t dst)
{
FLAGW_CF((bcbitsa((uint16_t)v1,add)>>7)&1); //Carry?
FLAGW_OF(addoverflow[((dst>>7)&1)|(((add>>6)&2))|((v1>>5)&4)]); //Overflow?
FLAGW_AF((bcbitsa((uint16_t)v1,add)&0x8)>>3); //Adjust?
}
void flag_adcoa16(uint16_t v1, uint32_t add, uint32_t dst)
{
FLAGW_CF((bcbitsa((uint32_t)v1,add)>>15)&1); //Carry?
FLAGW_OF(addoverflow[((dst>>15)&1)|(((add>>14)&2))|((v1>>13)&4)]); //Overflow?
FLAGW_AF((bcbitsa((uint32_t)v1,add)&0x8)>>3); //Adjust?
}
void flag_adcoa32(uint32_t v1, uint64_t add, uint64_t dst)
{
FLAGW_CF((bcbitsa((uint64_t)v1,add)>>31)&1); //Carry?
FLAGW_OF(addoverflow[((dst>>31)&1)|(((add>>30)&2))|((v1>>29)&4)]); //Overflow?
FLAGW_AF((bcbitsa((uint32_t)v1,add)&0x8)>>3); //Adjust?
}
//Substract Carry, Overflow, Adjust logic
void flag_subcoa8(uint8_t v1, uint16_t sub, uint16_t dst)
{
FLAGW_CF((bcbitss((uint16_t)v1,sub)>>7)&1); //Carry?
FLAGW_OF(suboverflow[((dst>>7)&1)|((sub>>6)&2)|((v1>>5)&4)]); //Overflow?
FLAGW_AF((bcbitss((uint16_t)v1,sub)&0x8)>>3); //Adjust?
}
void flag_subcoa16(uint16_t v1, uint32_t sub, uint32_t dst)
{
FLAGW_CF((bcbitss((uint32_t)v1,sub)>>15)&1); //Carry?
FLAGW_OF(suboverflow[((dst>>15)&1)|((sub>>14)&2)|((v1>>13)&4)]); //Overflow?
FLAGW_AF((bcbitss((uint32_t)v1,sub)&0x8)>>3); //Adjust?
}
void flag_subcoa32(uint32_t v1, uint64_t sub, uint64_t dst)
{
FLAGW_CF((bcbitss((uint64_t)v1,sub)>>31)&1); //Carry?
FLAGW_OF(suboverflow[((dst>>31)&1)|((sub>>30)&2)|((v1>>29)&4)]); //Overflow?
FLAGW_AF((bcbitss((uint64_t)v1,sub)&0x8)>>3); //Adjust?
}
Anyone knows what's going wrong? I've based it on http://www.emulators.com/docs/nx11_flags.htm and the code that's talked about(which is mentioned as well, at least the ADD instruction). For some reason, UniPCemu's doesn't match the dumped flags? The overflow flags now uses the tables from http://teaching.idallen.com/dat2343/10f/notes … 40_overflow.txt
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io