Reply 20 of 178, by superfury
This is what happens with the POST 10h part(full log of all memory and registers in the old format(the common log format doesn't have any of those yet)):
Edit: Looking at the debugger, somehow ES is cleared after loading it with selector 0x18(16-bit protected mode segment with 1MB limit)? That causes the memory access after it to detect a NULL ES access, which causes a #GP fault?
Edit: Hmmm... Strange: The loading of DS seems to clear the ES selector?
Edit: Found the bug: Loading 32-bit registers into a segment register caused the 32-bit write routine to write to the segment register and immediately after write a 32-bit value to the 16-bit segment register pointer(which was typecased to a 32-bit pointer for easy compatibility). Thus it was writing zeroes to the next segment register(or CPU data following it itself), causing bugs(NULL checks being triggered on data segment registers when being used in instructions). Fixing this makes it continue to the next steps.
Edit: After fixing one more bug(16-bit segment register write is always 16-bit, never using 32-bit registers or memory), it now proceeds to step 12h, which fails. Apparently the BSF instruction is incorrect?
Current implementation:
void CPU80386_OP0FBC_16() {
word temp;
modrm_generateInstructionTEXT("BSF",16,0,PARAM_MODRM12);
if (modrm_check16(¶ms,1,1)) return;
if (modrm_check16(¶ms,1,0)) return;
if (CPU8086_instructionstepreadmodrmw(0,&instructionbufferw,1)) return; //Read src!
if (instructionbufferw==0) //Nothing?
{
FLAGW_ZF(1); //Set zero flag!
BST_cnt = 0; //No count!
CPU_apply286cycles(); /* Apply cycles */
}
else
{
if (CPU8086_instructionstepreadmodrmw(2,&instructionbufferw2,0)) return; //Read dest!
if (CPU[activeCPU].instructionstep==0) //Executing?
{
FLAGW_ZF(0);
temp = 0;
BST_cnt = 0; //Init counter!
for (;(((instructionbufferw>>temp)&1)==0) && (temp<16);) //Still searching?
{
++temp;
instructionbufferw2 = temp;
++BST_cnt; //Increase counter!
}
++BST_cnt; //Increase counter!
++CPU[activeCPU].instructionstep;
CPU_apply286cycles(); /* Apply cycles */
if (modrm_ismemory(params)) return; //Delay when running!
}
if (CPU8086_instructionstepwritemodrmw(4,instructionbufferw2,0,0)) return; //Write the result!
}
} //BSF /r r16,r/m16
void CPU80386_OP0FBC_32() {
uint_32 temp;
modrm_generateInstructionTEXT("BSF",32,0,PARAM_MODRM12);
if (modrm_check32(¶ms,1,1)) return;
if (modrm_check32(¶ms,1,0)) return;
if (CPU80386_instructionstepreadmodrmdw(0,&instructionbufferd,1)) return; //Read src!
if (instructionbufferd==0) //Nothing?
{
FLAGW_ZF(1); //Set zero flag!
BST_cnt = 0; //No count!
CPU_apply286cycles(); /* Apply cycles */
}
else
{
if (CPU80386_instructionstepreadmodrmdw(2,&instructionbufferd2,0)) return; //Read dest!
if (CPU[activeCPU].instructionstep==0) //Executing?
{
FLAGW_ZF(0);
temp = 0;
BST_cnt = 0; //Init counter!
for (;(((instructionbufferd>>temp)&1)==0) && (temp<32);) //Still searching?
{
++temp;
instructionbufferd2 = temp;
++BST_cnt; //Increase counter!
}
++BST_cnt; //Increase counter!
++CPU[activeCPU].instructionstep;
CPU_apply286cycles(); /* Apply cycles */
if (modrm_ismemory(params)) return; //Delay when running!
}
if (CPU80386_instructionstepwritemodrmdw(4,instructionbufferd2,0)) return; //Write the result!
}
} //BSF /r r32,r/m32
'
Edit: There were some bugs in the way the data was read/written, as well as the results being incorrect. After fixing this, the test now passes and moves on to the next test(Bit Test instructions), which fail also.
Edit: Having fixed those, it now continues on to the Near and Far call in protected mode tests(POST 16h). That one HLTs when it returns from a CALLF?
Edit: It seems to be HLTing after a 16-bit RETF at 0010:19DA?
The RETF after the "o16 call word %1:%%farfn16" at https://github.com/barotto/test386.asm/blob/m … /call_m.asm#L65 seems to go wrong for some unknown reason? The offset is written, but the segment is zero?
Edit: There was a problem with 16-bit stack pushes on 32-bit operand sizes. This has now been fixed, so the CALLF test passes.
Now it tries the ARPL instruction. The first one succeeds, but the second one fails(the one on a memory operand).
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io