VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

In UniPCemu, only a few fields are reloaded in Real/Virtual 8086 mode:
- Base is loaded.
- Access rights are loaded with 0x93.

Furthermore, in Virtual 8086 mode, extra fields are loaded as well:
- Limit low is loaded with 0xFFFF.
- The remaining high byte (limit high, AVL, D/B and G fields) is loaded with 0x00.

Is this behaviour correct? Or do other fields get loaded in these two modes as well?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 8, by peterferrie

User metadata
Rank Oldbie
Rank
Oldbie

For real mode, the limit should be loaded, too. That's the basis of unreal mode, after all, and the loadall instruction can set it.

Note that Loadall can set bitness and D bits, too, and they are honoured.

Reply 2 of 8, by superfury

User metadata
Rank l33t++
Rank
l33t++

So the entire descriptor is reloaded? (All 6(286)/8(386+) bytes)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 4 of 8, by superfury

User metadata
Rank l33t++
Rank
l33t++

HIMEM.SYS does something odd, though(I notice after fixing some odd 32-bit bugs): It loads the 4GB segments DS/ES, returns to real mode and finally, before returning, loads 0 into them through AX? If the entire descriptor is reloaded, it would cancel out the unreal mode, reverting to normal real mode operating? So that cannot be true?

See my latest post in my other thread on my emulator: Finding bugs in 8086-80386 emulation core?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 8, by peterferrie

User metadata
Rank Oldbie
Rank
Oldbie

Loading 0 into them might be the special case that erases all content. I don't know. You might need to do some tests on hardware to see. For example, if you load a 4Gb segment in DS and then copy a 64kb ES to DS, does DS become limited again?

Reply 6 of 8, by peterferrie

User metadata
Rank Oldbie
Rank
Oldbie

Now that I think about it - HIMEM is using segment value 0 to avoid address shifting while memory in flat mode. So clearly the limits are not reloaded when the segment register is assigned, but I believe that they are if an interrupt occurs.

Reply 7 of 8, by Azarien

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

HIMEM.SYS does something odd, though(I notice after fixing some odd 32-bit bugs): It loads the 4GB segments DS/ES, returns to real mode and finally, before returning, loads 0 into them through AX? If the entire descriptor is reloaded, it would cancel out the unreal mode, reverting to normal real mode operating? So that cannot be true?

As far as I know, loading any value to segment register in real mode does not reload the underlying descriptor, so whatever was set during protected mode is still somewhat in force. After all, to exit pmode properly, we are supposed to load valid real-mode-like descriptors, and failure to do so results in unreal mode weirdness.

Reply 8 of 8, by superfury

User metadata
Rank l33t++
Rank
l33t++

So this is what I have now for real and Virtual 8086 mode segment loads:

			*CPU[activeCPU].SEGMENT_REGISTERS[segment] = value; //Just set the segment, don't load descriptor!
//Load the correct base data for our loading!
CPU[activeCPU].SEG_DESCRIPTOR[segment].base_low = (word)(((uint_32)value<<4)&0xFFFF); //Low base!
CPU[activeCPU].SEG_DESCRIPTOR[segment].base_mid = ((((uint_32)value << 4) & 0xFF0000)>>16); //Mid base!
CPU[activeCPU].SEG_DESCRIPTOR[segment].base_high = ((((uint_32)value << 4) & 0xFF000000)>>24); //High base!
CPU[activeCPU].SEG_base[segment] = ((CPU[activeCPU].SEG_DESCRIPTOR[segment].base_high<<24)|(CPU[activeCPU].SEG_DESCRIPTOR[segment].base_mid<<16)|CPU[activeCPU].SEG_DESCRIPTOR[segment].base_low); //Update the base address!
//This also maps the resulting segment in low memory (20-bit address space) in real mode, thus CS is pulled low as well!
CPU[activeCPU].SEG_DESCRIPTOR[segment].AccessRights = 0x93; //Compatible rights!
CPU[activeCPU].SEG_DESCRIPTOR[segment].limit_low = 0xFFFF;
if (getcpumode()==CPU_MODE_8086) //Virtual 8086 mode also loads the rights etc.? This is to prevent Virtual 8086 tasks having leftover data in their descriptors, causing faults! Real mode does load them, too!
{
CPU[activeCPU].SEG_DESCRIPTOR[segment].noncallgate_info = 0x00; //Not used!
}

Is that correct?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io