x86 real mode effects of loading a segment register?

Emulation of old PCs, PC hardware, or PC peripherals.

x86 real mode effects of loading a segment register?

Postby superfury » 2017-9-27 @ 07:21

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?
superfury
l33t
 
Posts: 2040
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: x86 real mode effects of loading a segment register?

Postby peterferrie » 2017-9-27 @ 23:52

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.
peterferrie
Oldbie
 
Posts: 603
Joined: 2008-5-08 @ 21:54

Re: x86 real mode effects of loading a segment register?

Postby superfury » 2017-9-28 @ 02:44

So the entire descriptor is reloaded? (All 6(286)/8(386+) bytes)?
superfury
l33t
 
Posts: 2040
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: x86 real mode effects of loading a segment register?

Postby peterferrie » 2017-9-29 @ 20:21

It's unclear (some of those bits would be hard to test), but I suppose that it is.
peterferrie
Oldbie
 
Posts: 603
Joined: 2008-5-08 @ 21:54

Re: x86 real mode effects of loading a segment register?

Postby superfury » 2017-10-01 @ 12:31

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: https://www.vogons.org/viewtopic.php?f= ... 00#p616765
superfury
l33t
 
Posts: 2040
Joined: 2014-3-08 @ 11:25
Location: Netherlands

Re: x86 real mode effects of loading a segment register?

Postby peterferrie » 2017-10-03 @ 19:15

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?
peterferrie
Oldbie
 
Posts: 603
Joined: 2008-5-08 @ 21:54

Re: x86 real mode effects of loading a segment register?

Postby peterferrie » 2017-10-06 @ 15:53

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.
peterferrie
Oldbie
 
Posts: 603
Joined: 2008-5-08 @ 21:54

Re: x86 real mode effects of loading a segment register?

Postby Azarien » 2017-10-10 @ 12:34

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.
Azarien
Member
 
Posts: 381
Joined: 2015-5-14 @ 07:14

Re: x86 real mode effects of loading a segment register?

Postby superfury » 2017-10-12 @ 16:49

So this is what I have now for real and Virtual 8086 mode segment loads:
Code: Select all
         *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?
superfury
l33t
 
Posts: 2040
Joined: 2014-3-08 @ 11:25
Location: Netherlands


Return to PC Emulation

Who is online

Users browsing this forum: No registered users and 3 guests