nxos/BIGMEM.ASM
2014-01-27 10:02:18 +01:00

419 lines
8.9 KiB
NASM
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;NXOS
;Written by: Alberto Venturini (Alb) - 2001
;Email address: -albe-@libero.it
;Modulo aggiuntivo di gestione della memoria
;Questo modulo cambia la modalit… del processore da
;Real mode 16-bit a Real mode 32-bit.
;In questo modo si ha accesso a taaaanta memoria (64 Mbyte
;al massimo...ma direi che sono pi— che sufficienti!)
;e si ha comunque compatibilit… con la real mode 16-bit.
;Questo file va assemblato con tasm32.exe e linkato con un
;linker che supporti l'output in flat binary (".bin") (ad
;esempio elink.exe).
StartingOffset equ 120000h ;Offset a partire dal quale Š disponibile
;la memoria utente
TableOffset equ 110000h ;Offset della tabella per l'allocazione
.386p
Code Segment Para Public Use16
Assume CS:Code
org 0h
;------------------------------------------------------------------------------
Main:
;Installazione del driver
cli
xor ax,ax
mov es,ax
mov ax,offset Int2fh
mov es:[2fh*4],ax
mov ax,cs
mov es:[2fh*4+2],ax
call Real32Init
mov ah,02h
mov bl,1
int 20h
;------------------------------------------------------------------------------
Int2fh:
cmp ah,00h
je Int2fh_00h
cmp ah,01h
je Int2fh_01h
cmp ah,02h
je Int2fh_02h
cmp ah,03h
je Int2fh_03h
cmp ah,04h
je Int2fh_04h
cmp ah,05h
je Int2fh_05h
iret
Int2fh_00h:
call Real32Init
iret
Int2fh_01h:
call Real32End
iret
Int2fh_02h:
call XMS_Avail
iret
Int2fh_03h:
call MemAlloc32
iret
Int2fh_04h:
call MemoryLeft
iret
Int2fh_05h:
call MemFree32
iret
;------------------------------------------------------------------------------
Real32Init:
;Inizializza la Real Mode a 32 bit
;no Input, no Output
pusha
call Check_Safety ;giusto per sicurezza, anche se non dovrebbero
;esserci errori.
test ax,ax
jnz Real32Init_Error
call Enable_A20 ;Inizializza la 32bit real mode
call Pmode
call XMS_Avail ;Calcola la memoria totale
cmp ax,128
jbe Real32Init_Error
mov word ptr cs:[TotalMemory],ax ;Mettiamo la memoria totale in
;questa variabile
Real32Init_PrepareTable:
mov cx,ax ;In AX ho il numero totale di Kbytes presenti.
;Inizializza il valore corrispondente a questi
;Kbytes a zero.
sub cx,64 ;Toglie 64 (perchŠ Š primi 64 kbytes sono occupati
;dalla tabella di allocazione della memoria).
mov ax,0
mov es,ax
mov edi,TableOffset
Real32Init_Table2:
;Azzera tutte le posizioni nella tabella di allocazione della memoria
mov es:[edi],al ;Nota: non funziona il "tradizionale" stosb...
inc edi
loop Real32Init_Table2
popa
ret
Real32Init_Error:
call Disable_A20
popa
ret
;------------------------------------------------------------------------------
Real32End:
;Termina la Real Mode a 32 bit
push ax
call Disable_A20
pop ax
ret
;------------------------------------------------------------------------------
MemAlloc32:
;Input DX=numero di Kbytes da allocare
;Output EDI=offset a partire dal quale Š disponibile la memoria
push ax
push cx
push dx
push es
xor ax,ax
mov es,ax
mov edi,TableOffset ;edi punta alla tabella di allocazione memoria
MemAlloc32_CheckSingle:
;Esegue questo ciclo finchŠ non trova un valore uguale a 0 (cioŠ un Kbyte
;libero).
mov al,es:[edi]
inc edi
cmp di,cs:[TotalMemory]
jae MemAlloc32_MemoryNotFound
test al,al
jnz MemAlloc32_CheckSingle
MemAlloc32_CheckTotal:
mov cx,dx
dec cx
MemAlloc32_CheckTotal2:
;Controlla se ci sono abbastanza Kbytes contigui liberi
test cx,cx
jz MemAlloc32_MemoryFound
mov al,es:[edi]
inc edi
cmp di,cs:[TotalMemory]
jae MemAlloc32_MemoryNotFound
dec cx
test al,al
jz MemAlloc32_CheckTotal2
jmp MemAlloc32_CheckSingle
MemAlloc32_MemoryFound:
sub di,dx
mov al,1
push edi
MemAlloc32_MemoryFound2:
;Occupa la memoria!
mov es:[edi],al
inc edi
dec dx
jnz MemAlloc32_MemoryFound2
pop edi
;Conversione di EDI: da indice nella tabella di allocazione a offset
and edi,0000FFFFh
shl edi,10 ;converte il risultato in Kbytes
add edi,StartingOffset
pop es
pop dx
pop cx
pop ax
ret
MemAlloc32_MemoryNotFound:
;[...]
pop es
pop dx
pop cx
pop ax
ret
;------------------------------------------------------------------------------
MemoryLeft:
;questa procedura ritorna la memoria libera disponibile.
;CX=numero di Kbytes *contigui* liberi
;DX=numero di Kbytes *totali* liberi
push ax
push bx
push es
push edi
mov edi,TableOffset
xor ax,ax
mov dx,ax
mov bx,ax
mov es,ax
MemoryLeft_1:
mov al,es:[edi]
inc edi
cmp di,cs:[TotalMemory]
je MemoryLeft_End
test al,al
jnz MemoryLeft_1
inc dx
mov cx,1
MemoryLeft_2:
mov al,es:[edi]
inc edi
cmp di,cs:[TotalMemory]
je MemoryLeft_End2
test al,al
jnz MemoryLeft_3
inc cx
inc dx
jmp MemoryLeft_2
MemoryLeft_3:
cmp cx,bx
jbe MemoryLeft_1
mov bx,cx
jmp MemoryLeft_1
MemoryLeft_End2:
cmp cx,bx
jbe MemoryLeft_End
mov bx,cx
MemoryLeft_End:
pop edi
pop es
pop bx
pop ax
ret
;------------------------------------------------------------------------------
MemFree32:
;input EDI=offset a partire dal quale va liberata la memoria
;DX=numero di Kbytes da liberare
push ax
push dx
push es
push edi
sub edi,StartingOffset
shr edi,10
add edi,TableOffset
xor ax,ax
mov es,ax
MemFree32_1:
mov es:[edi],al
inc edi
dec dx
jnz MemFree32_1
pop edi
pop es
pop dx
pop ax
ret
;------------------------------------------------------------------------------
;Il codice sotto l'ho preso da un file di Alexei A. Frounze
;Il file originale si chiama "4gb.zip" ed Š scaricabile dal
;sito dell'autore: http://www.chat.ru/~alexfru
;--------------------------- A20 line switching ----------------------------
Enable_A20:
Mov AL, 0D1h
Out 64h, AL
Mov AL, 0DFh
Out 60h, AL
Ret
Disable_A20:
Mov AL, 0D1h
Out 64h, AL
Mov AL, 0DDh
Out 60h, AL
Ret
;----------- Checking processor mode and looking for Himem.sys -------------
Check_Safety:
SMSW CS:XXX
Mov AX, CS:XXX
And AX, 1
JNZ @@CSQ ; 1 - Processor is in Protected Mode
@@CSQ:
Ret
XXX DW ?
;------------------------- Getting XMS ammount -----------------------------
Read_CMOS:
Out 70h, AL ; CMOS address should be stored in the AL register
Jmp @@RCW ; Little delay
@@RCW:
In AL, 71h ; AL = value
Ret
XMS_Avail:
;Output AX=memoria disponibile (con un massimo di circa 64Mb,
;perchŠ Š una word...)
;Questa funzione restituisce la memoria XMS disponibile.
Mov AL, 31h ; 31h = hi byte address
Call Read_CMOS
Mov AH, AL
Mov AL, 30h ; 30h = low byte address
Call Read_CMOS ; AX = XMS installed above 1MB (in Kilobytes)
sub ax,128 ;toglie 128 perchŠ la memoria disponibile inizia da 120000h
ret
;-------- Protected mode intialization and creation of 4GB segment ---------
PMode:
Xor EAX, EAX
Mov AX, CS
Shl EAX, 4
LEA EDX, GDT
Add EAX, EDX
Mov DWord Ptr CS:GDTR+2, EAX; Fill in GDTR with physical address
; of Global Descriptor Table
Push DS
CLI
LGDT FWord Ptr CS:GDTR ; Load Global Descriptor Table
Mov EAX, 1
Mov CR0, EAX ; Set Protected Mode
Mov AX, 8
Mov DS, AX
Mov ES, AX
Mov FS, AX
Mov GS, AX ; All segment registers are loaded
; with 4GB segment's selector
Xor EAX, EAX
Mov CR0, EAX ; Set Real Mode
STI
Pop DS
;----------------------------------------------------------;
; Now you can access all the memory by putting zero to a ;
; segment register and 32bit physical address to an index ;
; register. ;
; -= Simple example =- ;
; Xor AX, AX ;
; Mov ES, AX ; zero the ES register ;
; Mov EDI, 1024*1024+65536 ; 1st byte we can use freely ;
; Mov BL, Byte Ptr ES:[EDI] ; read byte ;
; Mov DWord Ptr ES:[EDI], EDX ; write dword ;
;----------------------------------------------------------;
Ret
;------------------------------------------------------------------------------
GDT DQ 0, 8F92000000FFFFh ; "0" & "4GB" Descriptors
GDTR DW 16, 0, 0
TotalMemory dw ?
Errormsg db 'An error occurred while switching to 32-bit real mode',13,10,0
Code EndS
End