Unreal Mode - Problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Unreal Mode - Problem

Post by Combuster »

Well, again I say that why you are in REAL mode, hidden part of the segment is never reloaded.
You're wrong, read the intel manuals. The segment register's shadow is replaced by a built-in GDT (read: a virtual GDT where base equals selector * 16)

As for the rest, you just contradicted yourself by saying that addressing does not change while entering protected mode, which can not be when both the base and selector are added to the offset in real mode, and in protected mode the selector is not added which would if you were right cause a jump as soon as PE gets set and the prefetch queue is worn out.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Masterkiller
Member
Member
Posts: 153
Joined: Sat May 05, 2007 6:20 pm

Re: Unreal Mode - Problem

Post by Masterkiller »

Combuster wrote:You're wrong, read the intel manuals. The segment register's shadow is replaced by a built-in GDT (read: a virtual GDT where base equals selector * 16)
I have read AMD manuals. Anyway There is one big problem with what you say. Selector select entry from GDT not by adding SELECTOR to GDT BASE. It takes high 13 bits as entry number (that's why 8192 entries possible) and last 3 bytes are privilege level and where to search - GDT or LDT (selector can point to LDT entry also). But in real mode there is no align reqired on the 16-bit segment. 0x1007 points to 0x10070, not to entry in virtual LDT at privelege level 3.
Another thing you should explain to proof you opinion is why my code works? I reload segments several times while in UNREAL mode and why visible part of the segments affect the 32-bit addresses? I don't think my CPU is damaged. :mrgreen:
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Unreal Mode - Problem

Post by Combuster »

IMO you don't deserve this reply.

Unreal mode is a hacked real mode, so real-mode style segment loading applies:

Code: Select all

MOV AX, 0xB800
MOV ES, AX                                ; ES.base = selector * 16 = 0xB800 * 16 = 0xB8000
MOV word [ES:0], 0x0700 + '0'             ; address = ES.base + 0 = 0xB8000
MOV BX, 2
MOV word [ES:BX], 0x0700 + 'w'            ; address = ES.base + DI = 0xB8000 + 2 = 0xB8002
MOV AX, 0xA000
MOV ES, AX                                ; ES.base = 0xA000 * 16 = 0xA0000
MOV EBX, 0x18004
MOV word [ES:EBX], 0x0700 + 'n'           ; address = ES.base + EBX = 0xA0000 + 0x18004 = 0xB8004
XOR AX, AX
MOV ES, AX                                ; ES.base = 0x0 * 16
MOV EBX, 0x6
MOV word [ES:0xB8000 + EBX], 0x0700 + 'e' ; address = ES.base + EBX + 0xB8000 = 0 + 6 + 0xB8000 = 0xB8006
ADD BX, 2
MOV word [ES:0xB8000 + EBX], 0x0700 + 'd' ; address = ES.base + EBX + 0xB8000 = 0 + 8 + 0xB8000 = 0xB8008
You just don't want to admit that you never tried setting ES to 0x8 in protected mode, then going back to real mode without touching it and when you use it for addressing it doesn't point to (0x8 * 16 + offset) like you claim but rather (0+offset) like everybody else claims.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Masterkiller
Member
Member
Posts: 153
Joined: Sat May 05, 2007 6:20 pm

Re: Unreal Mode - Problem

Post by Masterkiller »

Well I admit I said something wrong. I especially tested what you say. Well the test showed folling:

Code: Select all

MOV eax, cr0
OR al, 1
MOV cr0, eax
MOV ax, 0x10
MOV ES, ax
MOV eax, cr0
AND al, 0xFE
MOV cr0, eax
JMP 0x1000:$+5
a32 MOV word[ES:0xB8000], 0x0F00+'A'
XOR ax, ax
MOV ES, ax
a32 MOV word[ES:0xB8002], 0x0F00+'B'
MOV ax, 0x10
MOV ES, ax
a32 MOV word[ES:0xB8004], 0x0F00+'C'
MOV ax, 0x12
MOV ES, ax
a32 MOV word[ES:0xB8004], 0x0F00+'D'
CLI
HLT
Real -> Seg.selector * 16 + Offset (limit = 1MB)
Protected -> Seg.base + Offset (limit = 4GB <depends on the descriptor>)
Unreal (before change the segment) -> Seg.base + Offset (limit = 4GB <depends on the descriptor>)
Unreal (after change the segment) -> Seg.selector * 16 + Offset (limit = 4GB <descriptor changed, but...?>)

I will not argue without a reason. Yes I was wrong thinking that Seg.selector affects address just after entering unreal mode. But I admit you say the truth for everything. As I mentioned changing the CPU mode does not change how the segment addresses.
As it see from the test after enters unreal mode, descriptor base of ES is still used and ES:0xB8000 = 0x0 + 0xB8000 = 0xB8000.
Then reload the segment to 0. This time mode for CPU is real and it multiplies selector by 16 so ES:0xB8002 = 0x0 *16 + 0xB8002 = 0xB8002. That is exactly what you say.
Next I loaded 0x10 in the segment. I assume you are right and 0x10 is a threated as a selector to some virtual GDT (we are in real mode) that actually points to 0x100. ES:0xB8004 = 0x10*16 + 0xB8004 = 0x100 + 0xB8004 = 0xB8104
Theoritically that could be possible, but 0x12 is selector that should point to the same descriptor at different privelege level, well actually I get this: ES:0xB8006 = 0x12*16 + 0xB8006 = 0x120 + 0xB8006 = 0xB8126.
Then not included here even after changing the selector I still able to read/write locations such as: ES:0xD8000000 = 0x0 * 16 + 0xD8000000 = 0xD8000000. So not only I can present invalid selector while in (un)real mode, but also the limit is 4GB.
So this test shows how the base address is made in all modes, but what about the limit. You see, Seg.base is not used after reload the segment in unreal mode. But the limit is still 4GB. If Seg.limit (and granularity bit) is used to make the limit, then no way hidden part to be changed while unreal mode.
Attachments
The result from the code in the post...
The result from the code in the post...
result.png (3.62 KiB) Viewed 1008 times
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Unreal Mode - Problem

Post by Combuster »

Why are you still reading
base = selector * 16
as
base = (selector & 0xFFF8) * 16

That was never what I said.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Unreal Mode - Problem

Post by ~ »

Masterkiller wrote:When I've first tested writing to video buffer in 32-bit SVGA mode, my DS was also 0x1000 on entering UNREAL mode. Then I start loop writing to 0xD8000000 (start of SVGA Buffer). First several lines from the screen were empty. I thought it is a bug from bochs and tested it at real hardware, but the same result. Actually instruction writing to 0xD8010000 because of the visible part of the segment, and because while CPU is in real mode, this part is multiplied by 16 and added to address. Zero the visible part in unreal mode before using the segment fixed that.

Another way to fix it would be to substract the value of DS, to the value of, say, EDI:

Code: Select all

mov edi,0xD8000000    ;Our VESA Buffer

push eax    ;Save register (1)
 xor eax,eax    ;Clear our general purpose register (GPR)
 mov ax,ds      ;Copy the DS value in the GPR (it's 0x1000)
 shl eax,4        ;Multiply by 16 to get Phisical Address (now it's 0x10000)
 
 sub edi,eax    ;(0xD8000000-0x00010000) is equals to (D7FF0000)
                      ;So, using our DS:EDI pair by MOV instructions, we would
                      ;have:
                      ;         DS=0x1000, converted by processor to 0x10000
                      ;        EDI=D7FF0000
                      ;        (DS+EDI)==(0x10000+0xD7FF0000)==0xD8000000
pop eax     ;Restore register (1)


;Here we would have a proper address formed by
;DS:EDI to use it in Unreal Mode.

This way of doing things could make for a more flexible code since it no longer would require to avoid altering segment registers for things like BIOS calls that put stuff at addresses like ES:DI.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Unreal Mode - Problem

Post by jal »

jal wrote:You should never change the segment registers, as it will change their limit back to 64Kb (the normal value in real mode).
Combuster wrote:Another thing of unreal mode is that the limit doesn't get reset to 64k upon a write to a segment register - instead it is preserved.
Combuster wrote:
Masterkiller wrote: Well, again I say that why you are in REAL mode, hidden part of the segment is never reloaded.
You're wrong, read the intel manuals.
Ok, so what is it? The first Combuster quote seems to contradict what I was saying, then Masterkiller repeats that, but then Combuster denies it's true. So, is or isn't the limit reset when reloading segment registers? I'd be especially happy with references to the Intel manuals where it is explained.


JAL
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Unreal Mode - Problem

Post by Combuster »

Yes, the hidden part is reloaded as the intel manual states. However, the manuals systematically neglects to mention that in real mode not all hidden fields (read: segment limit) are reloaded. Probably because Unreal Mode was once a "bug" and they don't want to start "supporting a bug"
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply