[Back to MEMORY SWAG index]   [Back to Main SWAG index]   [Original]   [Attachment]


{ SWAG NOTE :  The code for this material is attached below and encoded
  using XX3402 }

FLAT REAL / REAL BIG / UNREAL MODE (v1.2)

Flat Real mode, Real Big mode and UnReal mode are three names with the very
same meaning, I will call it FLAT in this text.

Since the  first PC-XT, people have  searched for methods to  get access to
more and more memory for their DOS programs: EMS, UMBs, XMS, DPMI. With the
i386, Intel has  given 32-bit power to the PC's.  Here's an example to take
advantage of  the 32-bit capabilities  of the i386  and compatibles without
the need  of protected mode,  DOS-extenders and/or special  interfaces like
VCPI & DPMI.

FLAT simply  allows you to  use 32-bit access  on top of  the normal 16-bit
addressing.  32-bit access  is possible  as the  well-known 64KB limits are
just registers  on the i386  and can be  altered to almost  any value up to
4GB. FLAT is not new, Microsoft's  HIMEM.SYS already uses it since 1988 for
its 'Move Extended Memory Block' service.

To understand  how FLAT works, you  have to understand how  the i386 works.
The  i386  is  not  made  as  one  but  several  seperate units; an ALU, an
INSTRUCTION PREFETCHER,  a SEGMENTATION UNIT,  a PAGING UNIT,  etc. Most of
these units  have no clue  about the  state  of the CPU;  Real or Protected
Mode.

The SEGMENTATION UNIT only holds the BASE, the LIMIT and some attributes of
the segment registers. These values are used for addressing rather than the
value  of the  segment registers.  When a  segment register  is assigned  a
value, in Real Mode and in a V86 task the BASE is loaded with 16 times this
value  so the  addressing is  compatible with  the 8086.  Most of the other
fields, including LIMIT, are unaffected. In normal Protected Mode operation
this value is  used as an index for the  GLOBAL/LOCAL DESCRIPTOR TABLE from
where all fields  BASE, LIMIT and attributes are fetched.  So, to alter the
LIMITs, we have to be in Protected Mode.

The SEGMENTATION UNIT will report a  fault when an instruction is trying to
address beyond a  LIMIT, or when an instruction is  trying to do an illegal
access like writing to a read-only segment. This fault will raise interrupt
number 13. In Protected Mode there's  an exception handler that will handle
this. In normal DOS operation (Real Mode), there is _no_ exception handler.
In fact, in the PC design interrupt  #13 is used for handling IRQ number 5.
This is  the reason DOS  will hang the  system when 32-bit  access is used.
While the IRQ  #5 handler expects the address of  the _next_ instruction is
pushed onto the stack, exception #13 will push the instruction which caused
the  exception. When  the IRQ  #5 handler  does an  IRET, the  CPU tries to
execute the very  same instruction, resulting in an  exception #13 (again),
etc, etc..

After a RESET or a switch to a V86 task, all segment LIMITs have a value of
64KB, this  to be compatible  with the  8086  and the 80286.  As the LIMITs
can't be altered from within a V86 task, FLAT will never work here. FLAT is
thus incompatible  with environments/programs where  a V86 task  is used to
simulate DOS, including:  - MS-Windows 3.x in 'Enhanced  Mode' - MS-Windows
NT - OS/2 2.x, Warp - Emm386, Qemm, etc.. simulating UMBs

Some environments/programs have an option to disable the DOS simulation:
 - MS-Windows'95; check the 'MS-DOS Mode' option
 - Emm386 simulating EMS; enter 'Emm386 OFF' at the DOS prompt

Due to a bug in Qemm (7.02),  its simulation cannot be disabled after being
enabled.  As  long  Qemm  stays  disabled  FLAT  will  work.  I do not have
experience with other EMS simulators (e.g 386max)

FLAT is fully compatible with:
 - DOS 2.0 and above
 - MS-Windows 3.x in 'Real Mode' and 'Standard Mode'
 - DesqView
 - Himem/XMS/UMB drivers
 - EMS drivers

All FLAT actually does it jump  to Protected Mode, alter the segment LIMITs
using a DESCRIPTOR with  a 4GB LIMIT, and jump back to  Real Mode. As other
programs/TSRs may  enter Protected Mode,  there's the possibility  that the
LIMITs are altered to 64KB again. This is why I have implemented FLAT as an
exception handler.  To allow IRQ  #5 to be  handled, the exception  handler
first checks the Interrupt Controller if IRQ  #5 is 'In Service'. If so, it
calls the IRQ #5 handler. FLAT will  terminate the program if it detects an
instruction  that is  causing an  exception #13,  even when  the LIMITs are
(re)set to 4GB.

To activate  FLAT, just call  the FLAT_install routine,  to remove/deactive
it, call  FLAT_destall. As FLAT must  be installed on top  of the interrupt
#13 handler,  FLAT has to be  deactivated first before any  changes to this
interrupt vector can  take place. As said above,  interrupt #13 is normally
used for IRQ #5.

FLAT is called FLAT because with  32-bit access the whole 4GB address space
of the 386  can be accessed with only using  offsets. But as the addressing
mechanism needs a segment the format [0000:<32-bit offset>] is used.

Using XMS, when an  EMB is locked, the physical base address  of the EMB is
returned. This base address can be used as base for access to the EMB:

        mov ah,09h                      ; Allocate EMB
        mov dx,256                      ; 256KB
        call XMS_driver                 ; Do it!
        test ax,ax                      ; Error?
        jz alloc_error
        mov ah,0Ch                      ; Lock EMB
        call XMS_driver                 ; Do it!
        test ax,ax                      ; Error?
        jz lock_error
        mov di,dx                       ; DX has high word of 256KB chunk
        shl edi,16
        mov di,bx                       ; BX has low word of 256KB chunk
        xor eax,eax                     ; Clear EAX
        mov es,ax                       ; ES:EDI now points to first address of 256KB chunk
        mov ecx,10000h                  ; 256KB equals 64K dwords
        rep stos dword ptr es:[edi]     ; Clear 256KB chunk

32-bit access is not specially meant for extended memory, it can be used for conventional memory as well. DOS allows memory allocations larger than 64KB which now is addressable as one big chunk rather than separate chunks of 64KB and/or less:

        mov ah,48h                      ; Allocate Memory
        mov bx,4000h                    ; 256KB (16K paragraphs)
        int 21h                         ; Do it!
        jc alloc_error                  ; Out of memory?
        mov es,ax                       ; 256KB can be accessed using es:00000000 through es:0003FFFFh
        xor eax,eax                     ; Clear EAX
        xor edi,edi                     ; ES:EDI now points to first address of 256KB chunk
        mov ecx,10000h                  ; 256KB equals 64K dwords
        rep stos dword ptr es:[edi]     ; Clear 256KB chunk

With the new VESA VBE Core Standard  2.0, the entire video memory of a SVGA
or other video adapter that  support linear/flat addressing can be accessed
as one large  chunk of memory somewhere in the  4GB(/16MB) address space of
the 386(sx):

        mov ax,4F01h                    ; Get VBE Mode Information
        mov cx,100h                     ; Mode : 640x400, 256 colours
        les di,ModeInfoBlockPtr         ; ES:DI now points to ModeInfoBlock structure
        int 10h                         ; Do it!
        cmp ax,4Fh                      ; Error?
        jne VBE_error
        mov ax,4F02h                    ; Set VBE Mode
        mov bx,0C100h                   ; Mode : 640x400, 256 colours, linear/flat, don't clear display
        int 10h                         ; Do it!
        cmp ax,4Fh                      ; Error?
        jne VBE_error
        xor eax,eax                     ; Clear EAX
        mov edi,dword ptr es:di[28h]    ; ModeInfoBlock[28h] = 'PhysBasePtr'
        mov es,ax                       ; ES:EDI now points to first address of 256KB video buffer
        mov ecx,10000h                  ; 640 x 400 bytes equals 256000 bytes equals about 64K dwords
        rep stos dword ptr es:[edi]     ; Clear 256KB video buffer

Accessing video memory  without the need of bankswitching  really speeds up
video  performance. In  terms of  pixels per  second, drawing  lines in the
1600x1200,256 colours graphics mode is now  faster than in the 320x200, 256
colours mode.

The only limitation of FLAT is your imagination. And you'll need that as no
high-level language DOS compiler I've seen (yet) supports 32-bit addressing
without  the need  of some  kind of  DOS-extender. However,  FLAT will link
smoothly with  almost any 16-bit DOS  compiler. I use Turbo  Pascal 5.5 and
6.0 myself for the body of the  programs I'm writing, and use some assembly
at  the places  I need  the 32-bit   addressing. See  EX2 for  a very  nice
example.


        Herman Dullink
        Groningen (the emulator city; CPC, MSX, ZX :-)
        the Netherlands
        +31-50-132829
        csg669@wing.rug.nl (fast)
        herman.dullink@prgbbs.idn.nl (1 day slower)

{ ---------------------------   CUT  ----------------------- }

ENCODED FLAT.ZIP FILE REMOVED.  PLEASE DOWNLOAD EITHER THE 
ATTACHMENT OR THE COMPLETE ZIP FILE.

[Back to MEMORY SWAG index]   [Back to Main SWAG index]   [Original]   [Attachment]