Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is it possible to address more than 1MB in real-mode

672 views
Skip to first unread message

Elcaro Nosille

unread,
Feb 18, 2008, 3:08:52 PM2/18/08
to
Would it be possible to use a 32-bit addressing-mode in real-mode via
address-size prefix and thereby to have segments which are 4GB long?
Someone in a different NG claimed that he can address more than 1MB
in real-mode with the large addressing-modes. The time I dealt with
such things is 15 years ago and the only way to have segments which
are 4GB long is to switch into 32 bit protected-mode, load the seg-
ment registers from appropriate selectors and to get back into real
-mode with interrupts disabled to prevent the cached selectors to
be overwritten.

Noob

unread,
Feb 18, 2008, 4:59:47 PM2/18/08
to
Elcaro Nosille wrote:

Isn't this what some call unreal mode?
http://en.wikipedia.org/wiki/Unreal_mode

Alex Buell

unread,
Feb 18, 2008, 4:09:17 PM2/18/08
to
On Mon, 18 Feb 2008 21:08:52 +0100, I waved a wand and this message
magically appears in front of Elcaro Nosille:

IIRC, that was due to a bug in segmented addressing on the 8086/8088
processors. You could address the first 64K above the 1MB address range
due to this; but that was many, many years ago and I probably
misremember but I think it's actually something like that.
--
http://www.munted.org.uk

Fearsome grindings.

Jack Klein

unread,
Feb 18, 2008, 10:27:06 PM2/18/08
to
On Mon, 18 Feb 2008 21:09:17 +0000, Alex Buell <spam...@crayne.org>
wrote in comp.lang.asm.x86:

I think your memory is a little bit hazy. The 8086 and 8088 only had
20 address lines, A0 through A19, and so could only generate one MB
different physical addresses. If an instruction with a high enough
starting address (segment above F000 hex) used a large enough offset,
it would wrap around and address RAM in the first 64K.

Some software, and some BIOSes, in particular, took advantage of that
wrap around, which is why early processors with more address lines
(286, 386, 486) had a hardware circuit on the board (the A20 gate),
that could pass their address line A20 through, allowing access to all
memory, or always force A20 as seen by memory to 0, causing the warp
around for 8088 DOS compatibility with poorly designed software.

In the days of DOS 5 and 6, himem.sys sometimes had problems enabling
the A20 gate on some motherboards, because different makers
implemented it in different ways.

When the A20 gate was enabled, processors 286 and above could load a
real mode segment register with FFF0 hex and access 64K - 16 bytes
above one meg. That was what was called the HMA, High Memory Area.

But that is very different from having full 32-bit addressing in real
mode like the OP asked for.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html

Jason Burgon

unread,
Feb 18, 2008, 10:43:49 PM2/18/08
to
"Noob" <ro...@localhost.news.free.fr> wrote in message
news:47b9ff18$0$12492$426a...@news.free.fr...

> Isn't this what some call unreal mode?
> http://en.wikipedia.org/wiki/Unreal_mode

Yes, and it's very similar to how 386+(?) supervisor mode works as well I
believe.

--
Jay

Jason Burgon - author of Graphic Vision
http://homepage.ntlworld.com/gvision

Tim Roberts

unread,
Feb 18, 2008, 11:31:55 PM2/18/08
to
Noob <ro...@localhost.news.free.fr> wrote:

Exactly right. That's the only way to do it. Without that magic, the
real-mode selectors have a limit of 64k bytes, regardless of the address
size prefix.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Alex Buell

unread,
Feb 19, 2008, 3:15:05 AM2/19/08
to
On Mon, 18 Feb 2008 21:27:06 -0600, I waved a wand and this message
magically appears in front of Jack Klein:

> I think your memory is a little bit hazy. The 8086 and 8088 only had
> 20 address lines, A0 through A19, and so could only generate one MB
> different physical addresses. If an instruction with a high enough
> starting address (segment above F000 hex) used a large enough offset,
> it would wrap around and address RAM in the first 64K.
>
> Some software, and some BIOSes, in particular, took advantage of that
> wrap around, which is why early processors with more address lines
> (286, 386, 486) had a hardware circuit on the board (the A20 gate),
> that could pass their address line A20 through, allowing access to all
> memory, or always force A20 as seen by memory to 0, causing the warp
> around for 8088 DOS compatibility with poorly designed software.
>
> In the days of DOS 5 and 6, himem.sys sometimes had problems enabling
> the A20 gate on some motherboards, because different makers
> implemented it in different ways.
>
> When the A20 gate was enabled, processors 286 and above could load a
> real mode segment register with FFF0 hex and access 64K - 16 bytes
> above one meg. That was what was called the HMA, High Memory Area.
>
> But that is very different from having full 32-bit addressing in real
> mode like the OP asked for.

Haha, you're absolutely correct, thank you for refreshing my memory
indeed yes that was what I was thinking of!

Wolfgang Kern

unread,
Feb 19, 2008, 10:42:10 AM2/19/08
to

Elcaro Nosille asked:

> Would it be possible to use a 32-bit addressing-mode in real-mode via
> address-size prefix and thereby to have segments which are 4GB long?

No, except beside UnReal/BigReal you can only access the first 64 KB
(-16 bytes, aka HMA) above the first MB with A20 enabled and with
the segment at FFFF.

> Someone in a different NG claimed that he can address more than 1MB
> in real-mode with the large addressing-modes.

I dont think that this will work very well, Unreal/Bigreal will crash
on any IRQ if the handlers weren't written explicite for it.
And if one think to create them, he may be better advised to create
PM32-handlers and use fully working PM<->RM or VM switches instead.

> The time I dealt with
> such things is 15 years ago and the only way to have segments which
> are 4GB long is to switch into 32 bit protected-mode, load the seg-
> ment registers from appropriate selectors and to get back into real
> -mode with interrupts disabled to prevent the cached selectors to
> be overwritten.

Yeah, that was the old XMS/EMM way during DOS times where
IRQ handling during PM weren't available while in plain DOS.
Mode swapping OSes should cover IRQ-handling in both real and protected
mode to keep sequence-sensible HW (mouse,keybd,net,...) in synch.

btw: I once encountered a CPU-bug (may be still in some 'modern' chips)
with an operand size extended instruction...

:RM16
db 66h |BT(c/r/s) [mem],reg32 ;this can range within +/-256 MB

...where it could in fact access another segment (even not above 1 MB)
without raising an exception.
__
wolfgang


Jim Leonard

unread,
Feb 19, 2008, 10:30:38 AM2/19/08
to
On Feb 18, 3:09 pm, Alex Buell <spamt...@crayne.org> wrote:
> IIRC, that was due to a bug in segmented addressing on the 8086/8088
> processors. You could address the first 64K above the 1MB address range
> due to this; but that was many, many years ago and I probably
> misremember but I think it's actually something like that.

Replace 808x with 80286+ and you're correct. The 808x didn't have
enough address lines for this trick to work; the 286 and later did.
(80186 *might* have, but I don't have the sheets in front of me atm to
confirm)

SoLo2

unread,
Feb 19, 2008, 12:53:30 PM2/19/08
to
Hello!


Is UNREAL MODE i386 assembler?

Because I haven't seen the specific
way of how the offset registers (16bits)
can access the whole 4GB space, if the
segment registers are holding the only
1 descriptor with the flat memory and
cannot be changed.

So, maybe it is i386 assembler with the
new larger 32bit offset registers? or
maybe the user must change the descriptor
entry each time to access upper memories?

Having 4096 descriptor entries of 64KB
each, the old i86 assembler could have
accessed 256MB of memory.
4096 descriptor entries are 32KB.


Greetings,
H.Samso

Terence

unread,
Feb 19, 2008, 5:25:39 PM2/19/08
to
Ah! You spoilt youngsters!
I remember when we thought having 4k bytes was wonderful, after using
50 word drums...

ArarghMail802NOSPAM

unread,
Feb 19, 2008, 5:12:56 PM2/19/08
to

My 80186 book seems to think that it took the same memory size as the
8086.
--
ArarghMail802 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the extra stuff from the reply address.

Stephen Sprunk

unread,
Feb 19, 2008, 7:49:41 PM2/19/08
to
"SoLo2" <spam...@crayne.org> wrote in message
news:d97b55a5-f121-4e30...@d4g2000prg.googlegroups.com...

> Is UNREAL MODE i386 assembler?

That's possible but not necessary. You can use most i386 (and above)
instructions to get 32-bit operations in real or unreal modes with the
appropriate prefix. The ones you can't use only make sense in protected
mode.

> Because I haven't seen the specific
> way of how the offset registers (16bits)
> can access the whole 4GB space, if the
> segment registers are holding the only
> 1 descriptor with the flat memory and
> cannot be changed.
>
> So, maybe it is i386 assembler with the
> new larger 32bit offset registers?

No; a segment in real or unreal modes is only 64kB because only the low 16
bits in the offset are used; any high bits are ignored. The only difference
is that in unreal mode you can place your segments arbitrarily in memory,
via the LDT/GDT, instead of having them all overlapping in the first 1MB of
memory as in real mode.

> or maybe the user must change the descriptor
> entry each time to access upper memories?
>
> Having 4096 descriptor entries of 64KB
> each, the old i86 assembler could have
> accessed 256MB of memory.

Real mode assembly doesn't have descriptors; the 64kB segments are defined
as being at sequential intervals of 16 bytes, giving you no more than 1MB
(+64kB if A20 is active) of accessible RAM.

Unreal mode basically consists of setting the descriptors in protected mode
and then switching back to real mode. I don't know if it was intentional,
but the CPU will continue interpreting DS, CS, SS, etc. as selectors instead
of reverting to real-mode segments.

Since the 8086 didn't have protected mode, you can't enter unreal mode.
IIRC, you couldn't on an i286 either because there was no way to get out of
protected mode without resetting the processor.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

ArarghMail802NOSPAM

unread,
Feb 19, 2008, 7:29:48 PM2/19/08
to

I fondly remember when my schools 1401 was upgraded from 8,000 chars
to 12,000. It was needed to run the Fortran compiler (also the
schools production work). Just about 40 years ago. :-)

Frank Kotler

unread,
Feb 19, 2008, 9:01:25 PM2/19/08
to
Elcaro Nosille wrote:
> Would it be possible to use a 32-bit addressing-mode in real-mode via
> address-size prefix and thereby to have segments which are 4GB long?

Data segments, yes. In real mode, we're using ip and sp, not eip and
esp, so these need to be kept "low".

> Someone in a different NG claimed that he can address more than 1MB
> in real-mode with the large addressing-modes. The time I dealt with
> such things is 15 years ago and the only way to have segments which
> are 4GB long is to switch into 32 bit protected-mode, load the seg-
> ment registers from appropriate selectors and to get back into real
> -mode with interrupts disabled to prevent the cached selectors to
> be overwritten.

Need interrupts disabled for the brief time you're in pmode, but once
back in real mode, we can enable 'em. The only thing that will alter the
"limit" is going back to pmode and reloading the selector. An ISR might
do this (never seen it). Running djgpp-Nasm *does* do it (and leaves
junk in the high word of 32-bit regs, too!). In order to avoid potential
problems with this, install the "relimiter" code as a handler for the
segment overrun exception... Like Herman Dullink's code, here:

<http://www.programmersheaven.com/download/1364/download.aspx>

I've "translated" Herman's code to Nasm, and have a few examples. Rock
solid, in my experience.

This isn't very "convenient" - it needs to be started from real mode,
which most folks don't use, these days - gotta reboot to use it. (yes,
you need a 386+, and no, you can't do it with 16-bit offset registers)
Other than that, it's a wonderful playground!

Best,
Frank

Hell, I'll post an example. This one doesn't actually go over 1 Meg, but
it will, trust me. Based on Herman Dullink's code - translation errors
are mine...

; Flat Real/Real Big mode
; nasm -f bin -o flattest.com flattest.asm

org 100h

section .data
GDT dw 15 ; Limit (16 bytes)
dw GDT,0 ; Offset within current segment...
dw 0 ; Unused

FLAT_desc dw 0ffffh ; Limit (bit 0..15)
db 0,0,0 ; Base (bit 0..23)
db 92h ; Access rights
db 0cfh ; Page granularity + Limit(16..19)
db 0 ; Base (bit 24..31)

FLAT_sel equ FLAT_desc - GDT

old_IRQ5 dd 0
last_Exc_13 dd 0
IRQ5_flag db 0

message db ' Message written using direct screen writing'
db ' & 32-bit offsets in REAL-mode!! '
no_NT_msg db 'This program requires at least an i386sx!',10,'$'
V86_msg db 'Cannot run in a virtual environment!',10,'$'
SOE_msg db 'Segment Overrun Exception!',10,'$'
allocerrmsg db 'Allocation error!',0Dh,0Ah,0,'$'

[section .text]

call FLAT_install ; Enable 4Gb address space

; mov ax,3 ; Colour text mode
; int 10h
xor ax,ax ; Base ES <- 000[0000]0h
mov es,ax
mov ah,1fh ; Colour = White on blue
top:
mov si,message
mov edi,000b8000h ; EDI <- top left screen address
mov cx,80 ; Write one line
l1: lodsb ; Get a char
a32 stosw ; [es:edi] Store char + attrib
loop l1

xor ax,ax
int 016h
; mov ax,0003h
; int 010h
cmp al, 1Bh
jnz top
exit:
call FLAT_destall ; <- Very Important!!!
mov ax,04C00h ; return success
int 021h

;-------------------------------------------------------------------
FLAT_install ; proc ; Installs FLAT_tsr

pushf ; Check for NT-flag (only on 386+)
pushf
pop ax
xor ah,40h
push ax
popf
pushf
pop bx
popf
cmp ah,bh
jne no_NT
; SMSW is a priviledged
instruction(?)
smsw ax ; Check for real mode
test al,1
jnz short V86
pushf ; Save flags & DS register
push ds
cli
xor eax,eax ; Get IRQ5 vector & Set FLAT_tsr
mov ds,ax
mov ebx,[ds:34h]
mov [cs:old_IRQ5],ebx
mov dword [ds:34h],FLAT_tsr
mov ax,cs
mov [ds:36h],ax
shl eax,4 ; Build Global Descriptor Table
add dword [cs:GDT+2],eax
pop ds ; Restore DS register & flags
popf
ret

no_NT: mov ah,09h ; Write message
mov dx,no_NT_msg
push cs
pop ds
int 21h
mov ax,4C01h ; Terminate with error code 1
int 21h

V86: mov ah,09h ; Write message
mov dx,V86_msg
push cs
pop ds
int 21h
mov ax,4C02h ; Terminate with error code 2
int 21h

;--------------------------------------------------------------------------
FLAT_destall ; proc ; Destalls FLAT_tsr

push ds ; Save DS register
xor ax,ax ; Restore old IRQ5 vector
mov ds,ax
mov eax,[cs:old_IRQ5]
mov [ds:34h],eax
pop ds ; Restore DS register
ret

;------------------------------------------------------------------------
FLAT_tsr ; proc

test byte[cs:IRQ5_flag],01h ; Exception within IRQ5 handler?
jnz short Exc_13
push ax ; Ask PIC if IRQ5 is 'IN-SERVICE'
mov al,0Bh
out 20h,al
jmp $+2
in al,20h
test al,20h
pop ax
jz short Exc_13

IRQ5: mov byte[cs:IRQ5_flag],1 ; Call old IRQ5 handler
pushf
call dword [cs:old_IRQ5]
mov byte[cs:IRQ5_flag],0
iret

Exc_13: push eax ; Save accumulator

mov eax,[ss:esp+4] ; Get address of SOE
cmp eax,[cs:last_Exc_13] ; Same as last time?
je short SOE
mov [cs:last_Exc_13],eax
lgdt [cs:GDT] ; Load GDT Register

push gs
push fs
push es
push ds
push bx ; Save registers

mov eax,CR0
or al,1 ; Enter Protected mode
mov CR0,eax
jmp $+2

mov bx,FLAT_sel ; Load 4Gb limits
mov ds,bx
mov es,bx
mov fs,bx
mov gs,bx

and al,0FEh ; Back to Real mode
mov CR0,eax
pop bx
pop ds
pop es
pop fs
pop gs ; Restore registers

; mov al, 'X'
; int 29h

pop eax ; Restore accumulator
iret ; Done

SOE: call FLAT_destall ; Remove FLAT_tsr
mov ah,0fh ; Clear screen
int 10h
mov ah,00h
int 10h
mov ah,09h ; Write message
mov dx,SOE_msg
push cs
pop ds
int 21h
mov ax,4C0Dh ; Terminate with error code 13
int 21h

H. Peter Anvin

unread,
Feb 19, 2008, 11:36:18 PM2/19/08
to
Stephen Sprunk wrote:
>>
>> So, maybe it is i386 assembler with the
>> new larger 32bit offset registers?
>
> No; a segment in real or unreal modes is only 64kB because only the low
> 16 bits in the offset are used; any high bits are ignored. The only
> difference is that in unreal mode you can place your segments
> arbitrarily in memory, via the LDT/GDT, instead of having them all
> overlapping in the first 1MB of memory as in real mode.
>

That is incorrect. "Unreal mode" is about changing the segment limits,
returning to real mode, and then use address size overrides to access
high memory.

>> or maybe the user must change the descriptor
>> entry each time to access upper memories?
>>
>> Having 4096 descriptor entries of 64KB
>> each, the old i86 assembler could have
>> accessed 256MB of memory.
>
> Real mode assembly doesn't have descriptors; the 64kB segments are
> defined as being at sequential intervals of 16 bytes, giving you no more
> than 1MB (+64kB if A20 is active) of accessible RAM.
>
> Unreal mode basically consists of setting the descriptors in protected
> mode and then switching back to real mode. I don't know if it was
> intentional, but the CPU will continue interpreting DS, CS, SS, etc. as
> selectors instead of reverting to real-mode segments.
>

That is also incorrect. The CPU will not reset the limit field of the
hidden descriptor register; however, the CPU will NOT interpret segment
selectors once back in real mode - loading a value into a segment
register back in real mode will set its base to (value << 4) just as
before. The limit field, however, is never touched, so it will stay at
what it last was in protected mode.

-hpa

Dirk Wolfgang Glomp

unread,
Feb 20, 2008, 4:58:35 AM2/20/08
to
Am Tue, 19 Feb 2008 16:42:10 +0100 schrieb Wolfgang Kern:

I am the one, who talk with Elcaro Nosille.

The beginning of that discurs is Elcaros statement, that we need an
64bit-mode to adress linear. I answer, that it is also possible with
the 16bit-adressmode(first without specifying if i ment in PM or RM).
Beside that statement i offer the Unrealmode.

But i think there is a little misinterpretation, that i use the Unrealmode
with the 32bit-adressmode. I only use it with the 16bit-adressmode, to
adress linear the hole 4GB-adressspace and also handel with IRQs and
softints of the DOS/BIOS enviroment.

> Unreal/Bigreal will crash
> on any IRQ if the handlers weren't written explicite for it.

I always enable IRQs after i switch to the Unrealmode leaving
16Bit-adressmode. No crash occur, when i use Softints. So only the
32Bit-adressmode need in both ways(for PM and RM), an explicite written
handler.

Into the Unrealmode there is no problem to relaod an extended segment with
an other segmentadress, also as H. Peter Anvin discribe:

"The CPU will not reset the limit field of the hidden descriptor register;
however, the CPU will NOT interpret segment selectors once back in real
mode - loading a value into a segment register back in real mode will set
its base to (value << 4) just as before. The limit field, however, is
never touched, so it will stay at what it last was in protected mode."

Dirk

H. Peter Anvin

unread,
Feb 20, 2008, 4:53:45 PM2/20/08
to
Dirk Wolfgang Glomp wrote:
>
>> Unreal/Bigreal will crash
>> on any IRQ if the handlers weren't written explicite for it.
>
> I always enable IRQs after i switch to the Unrealmode leaving
> 16Bit-adressmode. No crash occur, when i use Softints. So only the
> 32Bit-adressmode need in both ways(for PM and RM), an explicite written
> handler.
>

The problem is that if any interrupt handler ever goes in the PM, it
will destroy unreal mode on return (there is, unfortunately, no sane way
to read out the segment limits so they can be restored.) So you're
playing a gamble with the underlying platform.

What's better, IMNSHO, is to stay in protected mode, and intercept
interrupts and drop back into (normal) real mode for those.

-hpa

Dirk Wolfgang Glomp

unread,
Feb 21, 2008, 2:01:51 AM2/21/08
to
Am Wed, 20 Feb 2008 13:53:45 -0800 schrieb H. Peter Anvin:

> Dirk Wolfgang Glomp wrote:
>>
>>> Unreal/Bigreal will crash
>>> on any IRQ if the handlers weren't written explicite for it.
>>
>> I always enable IRQs after i switch to the Unrealmode leaving
>> 16Bit-adressmode. No crash occur, when i use Softints. So only the
>> 32Bit-adressmode need in both ways(for PM and RM), an explicite written
>> handler.
>>
>
> The problem is that if any interrupt handler ever goes in the PM, it
> will destroy unreal mode on return (there is, unfortunately, no sane way
> to read out the segment limits so they can be restored.) So you're
> playing a gamble with the underlying platform.

I didn´t know any normal DOS-IRQ that goes to PM, so only memmorymanager do
that?

Dirk

Wolfgang Kern

unread,
Feb 21, 2008, 12:49:12 PM2/21/08
to

Dirk Wolfgang Glomp wrote:

>>>> Unreal/Bigreal will crash
>>>> on any IRQ if the handlers weren't written explicite for it.

>>> I always enable IRQs after i switch to the Unrealmode leaving
>>> 16Bit-adressmode. No crash occur, when i use Softints. So only the
>>> 32Bit-adressmode need in both ways(for PM and RM), an explicite written
>>> handler.

I cannot image that IRQs can work while in Unreal mode.

>> The problem is that if any interrupt handler ever goes in the PM, it
>> will destroy unreal mode on return (there is, unfortunately, no sane way
>> to read out the segment limits so they can be restored.) So you're
>> playing a gamble with the underlying platform.

> I didn´t know any normal DOS-IRQ that goes to PM, so only memmorymanager
do
> that?

One problem is that the CPU actually switches between RM/PM when CS is
reloaded, the trick to set data-segment registers to flat/unlimted,
right after b0(CR0) is set, works only until CS become altered.
So the final IRET in any IRQ-handler (timer,key,mouse...) will do this
unwanted mode transition (turning BigReal/UnReal into PM).

Another thing to assume is that RM IRQ-handlers may temporary reload
DS/ES/.. and so reset the limit to 64KB again.

There are some workarounds for this problems, like what Frank posted,
but an easier way is to disable IRQs for short periods or use only
FS and GS for flat-addressing, these two are rare used in plain DOS.
__
wolfgang


Frank Kotler

unread,
Feb 21, 2008, 6:50:46 PM2/21/08
to
Wolfgang Kern wrote:
> Dirk Wolfgang Glomp wrote:
>
>
>>>>>Unreal/Bigreal will crash
>>>>>on any IRQ if the handlers weren't written explicite for it.
>
>
>>>>I always enable IRQs after i switch to the Unrealmode leaving
>>>>16Bit-adressmode. No crash occur, when i use Softints. So only the
>>>>32Bit-adressmode need in both ways(for PM and RM), an explicite written
>>>>handler.
>
>
> I cannot image that IRQs can work while in Unreal mode.

Don't have to imagine it. Run the code!

>>>The problem is that if any interrupt handler ever goes in the PM, it
>>>will destroy unreal mode on return (there is, unfortunately, no sane way
>>>to read out the segment limits so they can be restored.) So you're
>>>playing a gamble with the underlying platform.
>
>
>>I didn´t know any normal DOS-IRQ that goes to PM, so only memmorymanager
> do that?
>
>
> One problem is that the CPU actually switches between RM/PM when CS is
> reloaded,

???

> the trick to set data-segment registers to flat/unlimted,
> right after b0(CR0) is set, works only until CS become altered.

Nonsense! What effect would reloading CS (still/again in RM) have on
limits for ds, es, fs, gs???

> So the final IRET in any IRQ-handler (timer,key,mouse...) will do this
> unwanted mode transition (turning BigReal/UnReal into PM).

Into PM??? How???

> Another thing to assume is that RM IRQ-handlers may temporary reload
> DS/ES/.. and so reset the limit to 64KB again.

Reloading segregs in RM does *not* reset limits!!! If an IRQ handler
switches to PM, it will probably set limits to 0FFFFh (like we're
"supposed" to) when it switches back to RM. In this case (never seen
it), an SOE will occur - and our handler will put us back in "relimited
real mode".

> There are some workarounds for this problems, like what Frank posted,

Herman Dullink. I ain't that smart.

> but an easier way is to disable IRQs for short periods or use only
> FS and GS for flat-addressing, these two are rare used in plain DOS.

No need to disable IRQs once we're back in RM. Sticking with FS and GS
might make sense - we may want DS and/or ES loaded with the "real",
"unflat" segment to which dos loaded us... but you *can* swap 'em back
and forth.

I'd *prove* it to ya, but I hate to reboot. :)

Near the end of Herman's "FLAT_tsr", I added some code, commented out in
what I posted:

...


pop fs
pop gs ; Restore registers

; mov al, 'X'
; int 29h

I know calling ints in an IRQ handler is iffy, but this seems to work.
If you don't see an "X" at all, you were already in "Flat Real Mode: (I
really prefer "relimited real mode" as a descriptive name). Some
versions of himem.sys leave us with 4G-1 limits (!), so this is common.
If you see more than one "X", something (IRQ handler?) has set our
limits back to 0FFFFh, an SOE has triggered and the "workaround" was
necessary. I've never seen this, but I tend to run "mature" hardware.

(carefully avoiding any mention of A20 - I let himem.sys deal with that)

If I can get in the mood to reboot to dos, I'll work some more on that
"challenge" we were discussing in a.l.a. - is it faster than Windows?

Best,
Frank

Dirk Wolfgang Glomp

unread,
Feb 22, 2008, 1:02:20 AM2/22/08
to
Am Thu, 21 Feb 2008 18:49:12 +0100 schrieb Wolfgang Kern:

> Dirk Wolfgang Glomp wrote:
>
>>>>> Unreal/Bigreal will crash
>>>>> on any IRQ if the handlers weren't written explicite for it.
>
>>>> I always enable IRQs after i switch to the Unrealmode leaving
>>>> 16Bit-adressmode. No crash occur, when i use Softints. So only the
>>>> 32Bit-adressmode need in both ways(for PM and RM), an explicite written
>>>> handler.
>
> I cannot image that IRQs can work while in Unreal mode.

No problem with himem.sys, ramdisk, mousedriver, cdromdriver, reloading
any segmentregister, enable all IRQ, using softints and adress the hole
4GB. It is only a problem to use memmorymanager like emm386.exe.

>>> The problem is that if any interrupt handler ever goes in the PM, it
>>> will destroy unreal mode on return (there is, unfortunately, no sane way
>>> to read out the segment limits so they can be restored.) So you're
>>> playing a gamble with the underlying platform.
>
>> I didn´t know any normal DOS-IRQ that goes to PM, so only memmorymanager
> do
>> that?
>
> One problem is that the CPU actually switches between RM/PM when CS is
> reloaded, the trick to set data-segment registers to flat/unlimted,
> right after b0(CR0) is set, works only until CS become altered.

Yes, the only way to switch into PM is to set b0(CR0) and altering CS.

> So the final IRET in any IRQ-handler (timer,key,mouse...) will do this
> unwanted mode transition (turning BigReal/UnReal into PM).

I don´t believe that an IRET can swap from RM/UnrealM into PM (and back).

> Another thing to assume is that RM IRQ-handlers may temporary reload
> DS/ES/.. and so reset the limit to 64KB again.

The first two things that i do after switching to Unrealmode, is to enable
IRQs and load the unlimited DS with the adress of my Datasegment.

> There are some workarounds for this problems, like what Frank posted,
> but an easier way is to disable IRQs for short periods or use only
> FS and GS for flat-addressing, these two are rare used in plain DOS.

There isn´t any problem when i unlimit only DS and enable IRQs in the
Unrealmode.

Dirk

Wolfgang Kern

unread,
Feb 22, 2008, 7:44:06 AM2/22/08
to

Dirk Wolfgang Glomp wrote:

[...]
I checked it out and you are right!
more details in my answer to Frank.

__
wolfgang


Wolfgang Kern

unread,
Feb 22, 2008, 7:41:52 AM2/22/08
to

Frank Kotler wrote:

[...about Unreal/Bigreal]

>> I cannot image that IRQs can work while in Unreal mode.

> Don't have to imagine it. Run the code!

I checked it out with my own code a few minutes ago:

My old AMD DX486 always resets the segment limits to RM bounds
on FARcall/jump and IRET, but I'm really surprised that K7,K8 and
also an old Celeron (could't check on AMD64 yet) keep the entered
limits without further notice.

And because my OS were once written for 486, without resetting RM-limits,
it actually remain in Unreal mode whenever it enters RM :)

So YES. Dirk is right on this one and it seem to work without problems.
only my debugger seems a bit confused, because it truncates the address
to 16-bit in "real"-mode and I have no idea how to tell the difference.

... sorry for the confusion.

> I'd *prove* it to ya, but I hate to reboot. :)

Thanks, done it myself already ;)

...


> If I can get in the mood to reboot to dos, I'll work some more on that
> "challenge" we were discussing in a.l.a. - is it faster than Windows?

Would be interesting to compare Linux against windoze on this one,
both are 'supported' with vendor specific HW-accellerators.

__
wolfgang


Rod Pemberton

unread,
Feb 23, 2008, 3:27:06 AM2/23/08
to

"Wolfgang Kern" <spam...@crayne.org> wrote in message
news:fpmg43$ssi$1...@newsreader2.utanet.at...

>
> Frank Kotler wrote:
>
> [...about Unreal/Bigreal]
>
> >> I cannot image that IRQs can work while in Unreal mode.
>
> > Don't have to imagine it. Run the code!
>
> I checked it out with my own code a few minutes ago:
>
> My old AMD DX486 always resets the segment limits to RM bounds
> on FARcall/jump and IRET, but I'm really surprised that K7,K8 and
> also an old Celeron (could't check on AMD64 yet) keep the entered
> limits without further notice.
>

While you're experimenting with "undocumented" modes, have you tried Rick
Hohensee's "Forreal" mode:

http://groups.google.com/group/comp.lang.forth/msg/7a27652cd0239969?hl=en
http://groups.google.com/group/comp.lang.forth/msg/669d559d6c4fdaf3
http://groups.google.com/group/linux.kernel/msg/63f852603a32582c
http://groups.google.com/group/linux.kernel/msg/f0bfcdc616fa7d85?hl=en

Is it for real? ;-)


RP

Dirk Wolfgang Glomp

unread,
Feb 23, 2008, 3:05:54 AM2/23/08
to
Am Fri, 22 Feb 2008 13:44:06 +0100 schrieb Wolfgang Kern:

> Dirk Wolfgang Glomp wrote:
>
> [...]
> I checked it out and you are right!
> more details in my answer to Frank.

Mhm.

Dirk

Wolfgang Kern

unread,
Feb 23, 2008, 7:06:21 AM2/23/08
to

Rod Pemberton wrote:

[...about Unreal/Bigreal]


I may use other names for the available mode variants, but my OS really
is a mix of 16/32 bit code in unprotected flat mode and can 'call'
16-bit RealMode BIOS routines without problems, even I figured just
yesterday that it's in UnReal mode instead of trueRM ;)

But I use only two sets of identical working IRQ-handlers for RM-16
and PM32 and disable IRQs for the short intermediate states.

Ricks posts show that I'm not the only HEX-freak, but I avoid octals.
__
wolfgang


Rod Pemberton

unread,
Feb 24, 2008, 12:41:55 AM2/24/08
to
"Wolfgang Kern" <spam...@crayne.org> wrote in message
news:fpp2au$ugj$1...@newsreader2.utanet.at...

> Rod Pemberton wrote:
> [...about Unreal/Bigreal]
>
> even I figured just
> yesterday that [my OS is] in UnReal mode instead of trueRM ;)
>

Does this affect your 486DX results w/IRET etc.?


RP

Wolfgang Kern

unread,
Feb 24, 2008, 7:56:57 AM2/24/08
to

Rod Pemberton wrote:

>> [...about Unreal/Bigreal]
>> even I figured just
>> yesterday that [my OS is] in UnReal mode instead of trueRM ;)

> Does this affect your 486DX results w/IRET etc.?

No it didn't affect it at all [on this very early AMD 486DX50],
and I'm surprised that later CPUs keep the limits in 16-bit RM.
I once read in the manuals that segment limits are hardwired
to 64K for RM, but x86 design seem to have changed meanwhile.

__
wolfgang


H. Peter Anvin

unread,
Mar 23, 2008, 3:39:23 PM3/23/08
to

That was never true (although the manuals had a lot of baloney in them.)
It is, however, true in *V86* mode.

-hpa

H. Peter Anvin

unread,
Mar 23, 2008, 3:37:06 PM3/23/08
to
Dirk Wolfgang Glomp wrote:
>>>
>> The problem is that if any interrupt handler ever goes in the PM, it
>> will destroy unreal mode on return (there is, unfortunately, no sane way
>> to read out the segment limits so they can be restored.) So you're
>> playing a gamble with the underlying platform.
>
> I didn´t know any normal DOS-IRQ that goes to PM, so only memmorymanager do
> that?
>

You don't know what the BIOS does behind the back of either DOS or
anything else. In particular, if the hardware requires access to high
memory (as some disk and network controllers do these days), you have to
go to PM.

-hpa

Cyril Novikov

unread,
Mar 23, 2008, 8:17:59 PM3/23/08
to

I've been running AMI BIOS under a VT hypervisor lately (basically,
booting an OS with int 19h using native I/O and virtualized memory), and
it does use unreal mode (apparently, for some local APIC stuff, don't
ask me why, I have no idea). It also does that if you use int 13h.
Interrupt handlers do not go to PM, though, at least not the disk I/O ones.

By the way, emulating unreal mode with Intel's sucky VT is a special
kind of fun.

Dirk Wolfgang Glomp

unread,
Mar 24, 2008, 2:37:17 AM3/24/08
to

For those controllers, i have to go to PM, or the driver is a PM-driver for
the RM, or the BIOS goes to PM and back before DOS is booting?

Dirk

H. Peter Anvin

unread,
Mar 24, 2008, 12:38:59 PM3/24/08
to

Typically, they drop into PM and back when they get an interrupt
(software or hardware.)

-hpa

Dirk Wolfgang Glomp

unread,
Mar 25, 2008, 3:31:18 AM3/25/08
to

Are these onboard-controllers like SATA hooking to int13h?

There is a problem to use emm386.exe?

Dirk

João Jerónimo

unread,
Mar 25, 2008, 10:53:27 PM3/25/08
to
Elcaro Nosille wrote:
> Would it be possible to use a 32-bit addressing-mode in real-mode via
> address-size prefix and thereby to have segments which are 4GB long?

Yes, it's possible. However, first you have to change the size of the
segments in the Internal Descriptor Cache. Otherwise, you'll get a GPF (i'm
not sure, however, if the processor even tries to handle such a strange
thing as a GPF triggered in real mode of if it tripple faults immediately)...

This (changing the size of the segments) is a feature of PM, so you need PM
to do this. So, you go to 16-bit PM, you load your segment registers with
4GB segment descriptors, and then you switch back to real mode, since you
still want to run the BIOS and things alike... Then, you can access data
above 1MB and (I suppose), run code there. Beware that the BIOS won't be
able to return to extended memory, though...

What I described is what we usually call Unreal Mode, Voodoo Mode, Flat
Real Mode, 32-bit Real Mode (this is the less accurate of them!), etc.
In the unlikely case that you have a 386 or a 286, you can also use LOADALL
(but it's not recommended unless you don't intend to share your code with
anyone else).

JJ

Dirk Wolfgang Glomp

unread,
Mar 26, 2008, 4:54:16 AM3/26/08
to
Am Wed, 26 Mar 2008 02:53:27 +0000 schrieb João Jerónimo:

[Unrealmode]


> Then, you can access data
> above 1MB and (I suppose), run code there.

I think the Descriptor Cache can´t be hold a codesegment with 4GB when we
switch back to RM. So only the instructionpointer(IP with 16bit) let us
execute our opcodes in the fist MB of ram.

Dirk

Mike Gonta

unread,
Mar 26, 2008, 5:04:23 AM3/26/08
to
On Feb 18, 4:08 pm, Elcaro Nosille wrote:

> Would it be possible to use a 32-bit addressing-mode in real-mode via
> address-size prefix and thereby to have segments which are 4GB long?

It's possible to use a 32 bit protected mode bios extender.
This permits 32 bit protected mode programming with full bios access.

æBIOS now boots and runs from a USB flash drive in both modes (floppy
and hard drive) as well as Qemu emulation.
æBIOS is free to download and includes the full source code in FASM.

Mike Gonta
look and see - many look but few see

http://aeBIOS.com


João Jerónimo

unread,
Mar 26, 2008, 7:42:02 PM3/26/08
to
Dirk Wolfgang Glomp wrote:
>> Then, you can access data
>> above 1MB and (I suppose), run code there.
>
> I think the Descriptor Cache can´t be hold a codesegment with 4GB when we
> switch back to RM. So only the instructionpointer(IP with 16bit) let us
> execute our opcodes in the fist MB of ram.

I admit you are likely to be right.

JJ

Wolfgang Kern

unread,
Mar 26, 2008, 6:24:48 PM3/26/08
to

JJ "João Jerónimo" asked:


The opcode for 'Loadall' got a totally different meaning on newer CPUs !

I figured it out a few weeks ago, YES if you don't (re)set the limit
of your seg-regs whenever you switch from PM to RM. The stored seg-limits
(this hidden 48 bits) remain valid and let you access all 4GB within RM.

Last checks showed that this is valid for CPUs above/equal 486DX, while
previous CPUs may have a hard-wired 64 KB limit for RM (stated in 386/486
Intel docs) regardless of desciptor setups (mentioned as ignored at
all in RM).

Modern (586+) seem to remember the PM-limit settings for seg regs when
re-entering real (unreal/bigreal then) mode [except for CS of course].
__
wolfgang


H. Peter Anvin

unread,
Mar 28, 2008, 6:38:08 PM3/28/08
to
Dirk Wolfgang Glomp wrote:
>> Typically, they drop into PM and back when they get an interrupt
>> (software or hardware.)
>
> Are these onboard-controllers like SATA hooking to int13h?

I don't know of any, but it's possible.

> There is a problem to use emm386.exe?

Shouldn't be.

-hpa

Dirk Wolfgang Glomp

unread,
Mar 29, 2008, 1:33:43 AM3/29/08
to

Thanks.

Dirk

0 new messages