;Real Flat Mode
comment |
It's just Real-Mode with a little change. In Protected Mode ju don't have
really Segment-registers. A segment register in protected mode points just to
a entry in the GDT (global descriptor table). From there the information about
base-address, limit, access rights, etc. is taken and copied into a special
register, called shadow ram register. Per segment register (ES, DS, FS, ...)
one shadow ram register exists. Your real-flat-model init switches into
protected mode, loads the information about your datasegments into the
shadow-ram-register and comes back into real-mode. The special thing is, that
everything is like real-mode, just the shadow-ram-registers have their old
contense (your entrys !) from pm. Now feel free to access your memory. Things
like :
xor ax, ax
mov es, ax
mov edi, 0b8000h
mov al, '!'
db 67h
stosb
work ! You will trap in V86 mode if you try it.
|
;────────────────────────────────────────────────────────────────────────────
;╞│■╞═╡ Protected Mode Library for RFMI ╞═══════════│╞│ v1.0 revision 0 │╡│═╡
;────────────────────────────────────────────────────────────────────────────
;
; (C)OPYRIGHT BY PATRICK HELLWIG, ALL RIGHTS RESERVED
;
;────────────────────────────────────────────────────────────────────────────
.model small
.486p
.stack 50h
.code
jmp start
DESCRIPTOR STRUC
Limit00_15 dw ?
Base00_15 dw ?
Base16_23 db ?
Data1 db ? ;P,DPL,S,Type,Base23_16
Data2 db ? ;G,D,O,AVL,Limit19_16
Base24_31 db ?
DESCRIPTOR ENDS
GDTR LABEL FWORD
GDT_SIZE dw offset END_GDT - offset GDT ;GDT-SegLimit
GDT_BASE dd ? ;GDT-Address
END_GDTR LABEL
GDT LABEL
D0 DESCRIPTOR <?,?,?,?,?,?> ;Dummy
D1 DESCRIPTOR <0ffffh,0,0,10010010b,11001111b,0>
END_GDT LABEL
init_pm proc
mov ax, cs ;get current codesegment
and eax, 0FFFFh ;empty the upper 16bits
shl eax, 4 ;shift the segment by 4 to get the
mov bx, offset gdt ;real address
and ebx, 0FFFFh ;now get the offset of the gdt to
add eax, ebx ;calculate the 24bit address of GDT
mov GDT_BASE, eax
LGDT GDTR ;Load GDT into GDTR
cli
mov eax, cr0
or eax, 1 ;Enable PE-bit -> enable PM
mov cr0, eax
jmp start_PM ;important!
start_PM: mov ax, 8 ;Load our segment registers
mov ds, ax ;with the predefined values for
mov es, ax ;real flat model
mov fs, ax
mov gs, ax
mov eax, cr0
and eax, not 1 ;Disable PE-bit -> disable PM
mov cr0, eax
jmp exit_PM ;Important!
exit_PM:
xor ax, ax ;Now zero our segmentregisters
mov ds, ax ;Thats important for the use of
mov es, ax ;32bit addresses in Realmode !
mov fs, ax ;If we don't set them to 0, the
mov gs, ax ;address of the segmentregisters
sti ;would be added to the 32bit address
ret ;in, fe. esi !
endp init_pm
start: call init_pm
xor ax, ax
mov es, ax
mov edi, 0b8000h
mov al, '!'
mov es:[edi], al
mov ah, 4ch
int 21h
end start