📄 flatmem.inc
字号:
;----------------------------------------------------------------------------
; MASSiVE Flat Real mode routines
; (Version 1.0B)
; by
; NiX/MASSiVE
; Butterfly/MASSiVE
;
; You may use this sourcecode for free, we don't accept anything in return.
; But we would really like it if you greet us, or send your newest productions
; to us.
;
; This is a beta version, only providing you with the essential routines and
; some examples, just real plain flat-real-mode. More special things will be
; available in a next version.
;
; Read the DOC for more information.
.386P ; 386 Code ofcourse...
;---------------------------------------------------------------------------
; Descriptors and stuff used for setting up FRM
mem32_GDT dw 4 dup(0)
Code16GDT = 8
dw 0ffffh,0ffh,9a00h,0
Data16GDT = 16
dw 0ffffh,0ffh,9200h,0
Data32GDT = 24
dw 0ffffh,0ffh,9200h,8fh
GDTptr label fword
dw offset GDTptr-1-offset Mem32_GDT
dd offset Mem32_GDT ; Absolute adress GDTtable
dw 0
;-------------------------------------------------------------------------
; This routine sets DS, ES, FS and GS to a 4Gigabyte limit.
; To do this it swaps to PM for a little while, this is not possible in V86
; mode. If computer is in V86 mode the carry will be set on return, and you
; are still in RM.
; Crashes segment registers!!!
Set4Gig: mov eax,cr0 ; Check for V86 mode
ror eax,1 ;
jc Leave4Gig ; If carry set get out of here.
mov ax,cs ; Set up GDT for this code segment
mov ds,ax
movzx eax,ax
shl eax,4
add dword ptr ds:GDTptr+2,eax
lgdt fword ptr ds:GDTptr
mov ax,cs
and eax,65535
shl eax,4
mov word ptr ds:Mem32_GDT[Code16GDT+2],ax
mov word ptr ds:Mem32_GDT[Data16GDT+2],ax
ror eax,16
mov byte ptr ds:Mem32_GDT[Code16GDT+4],al
mov byte ptr ds:Mem32_GDT[Data16GDT+4],al
mov byte ptr ds:Mem32_GDT[Code16GDT+7],ah
mov byte ptr ds:Mem32_GDT[Data16GDT+7],ah
cli ; No ints
; Beam us to PMODE!!
mov eax,cr0
or al,1
mov cr0,eax
db 0eah ; Far jump to PMODE label
dw offset Pmode
dw Code16GDT
; We're in PMODE!!
Pmode: mov ax,Data32GDT
mov ds,ax ; Set them all to 4Gig
mov es,ax
mov fs,ax
mov gs,ax
; Beaming out!
mov eax,cr0
and al,0feh
mov cr0,eax
db 0eah ; Far jump to Rmode label.
dw offset Rmode
dw Code
; Back in the real world!
Rmode: clc ; No carry, everything went OK
sti ; Ints Back on.
Leave4Gig: ret
;----------------------------------------------------------------------------
; Initialises HIMEM.SYS for our program. If HIMEM.SYS isn't present a carry
; will be returned.
; This routine must be called before you use all other routines except for
; SET4GIG
Himem_Init: mov ax, 4300h
int 2Fh
cmp al, 80h
je HImemfound
stc
ret
Himemfound:
push es
mov ax, 4310h
int 2Fh
mov [word ptr cs:Himem_Entry], bx
mov [word ptr cs:Himem_Entry+2], es
pop es
clc
ret
Himem_Entry dd ?
;-----------------------------------------------------------------------------
; Allocates XMS memory
; Input: DX = Size in KB
; Output: DX = Handle
; If carry set alloc failed (probably out of mem...)
Alloc_XMS: mov ah, 9
call [cs:Himem_Entry]
cmp dx,ax
jnz AllocOK
or ax,ax
jnz AllocOK
stc
ret
AllocOK: clc
ret
;-----------------------------------------------------------------------------
; Deallocates XMS memory
; Input: DX = Handle
DAlloc_XMS: push dx
mov ah, 0dh
call [cs:Himem_entry]
pop dx
mov ah, 0Ah
call [cs:Himem_Entry] ; DAlloc
ret
;-----------------------------------------------------------------------------
; Returns absolute 32-bit adress of an XMS-Memoryblock
; Input: DX = Handle
; Output: EDX = 32Bit start adress of memoryblock
GetLinearAddress:
mov ah, 0Ch
call [cs:Himem_Entry]
shl edx,16
mov dx,bx
ret
;-----------------------------------------------------------------------------
; Returns the largest available XMS-Memoryblock
; Output: DX = Size of largest available memoryblock
GetMax_XMS: mov ah, 8
call [cs:Himem_Entry] ; avail.
ret
;-----------------------------------------------------------------------------
; Enables the A20 adress line. This is needed to adress the memory above 1Mb.
; Do this at the start of your program and everytime another program has been
; active. In an interrupt routine this means you should do it everytime the
; routine is being called, don't worry, it doesn't takes much time.
EnableA20:
mov al,0D1h
out 64h, al
call A20wait
mov al,0DFh
out 60h, al
call A20wait
mov al,0FFh
out 64h,al
call A20wait
ret
A20Wait: in al,64h
jmp $+2
and al,2
jnz A20wait
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -