;Affiche le nombre hexa dans %0[dword] PROC biosprinth FAR ARG @num:dword USES ax,bx,cx,edx,si,di mov edx,[@num] mov ah,09h mov di,8 @@hexaize: rol edx,4 mov si,dx and si,1111b mov al,[cs:si+offset @@tab] mov cx,1 cmp al,32 jb @@control mov bx,7 mov ah,09h int 10h @@control: mov ah,0Eh int 10h dec di jnz @@hexaize ret @@tab db '0123456789ABCDEF' endp biosprinth ;Affiche le texte ASCIIZ pointé par %0 PROC biosprint FAR ARG @pointer:word USES ax,bx,cx,si mov si,[@pointer] mov cx,1 mov bx,7 @@again: lodsb or al,al jz @@fin cmp al,32 jb @@control mov ah,09h int 10h @@control: mov ah,0Eh int 10h jmp @@again @@fin: ret endp biosprint PROC enablea20 FAR USES ax 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 endp enablea20 PROC disablea20 FAR USES ax mov al,0d1h out 64h,al call a20wait mov al,0DDh out 60h,al call a20wait ;mov al,0ffh ;out 64h,al ;call a20wait ret endp disablea20 a20wait: in al,64h jmp @@suite @@suite: and al,2 jnz a20wait ret ;par le system control port A ;in al,92h ;or al,2 ;out 92h,al ;par le system control port A ;in al,92h ;and al,not 2 ;out 92h,al PROC flatmode FAR USES eax,bx,ds push cs pop ds ; first, calculate the linear address of GDT xor eax,eax mov ax,ds shl eax,4 add [dword ptr offset @@gdt+2],eax ; store as GDT linear base addr ; now load the GDT into the GDTR lgdt [fword ptr offset @@gdt] ; load GDT base mov bx,1 * size descriptor ; point to first descriptor cli ; turn off interrupts mov eax,cr0 ; prepare to enter protected mode or al,1 ; flip the PE bit mov cr0,eax ; we're now in protected mode jmp @@suite @@suite: mov fs,bx ; load the FS segment register and al,0FEh ; clear the PE bit again mov cr0,eax ; back to real mode jmp @@suite2 @@suite2: sti ; resume handling interrupts ret ; @@gdt descriptor ; the GDT itself descriptor <0ffffh, 0, 0, 091h, 0cfh, 0> ; 4G data segment @@gdtend: endp flatmode ;Attend l'appuie sur une touche PROC bioswaitkey FAR USES ax xor ax,ax int 16h ret endp bioswaitkey firstmb dw 0 ;Charge les sections du block %0 PROC mbloadsection FAR ARG @blocks:word USES ax,bx,cx,si,di,ds,es LOCAL @@toresov:word:60 mov ax,[@blocks] mov es,ax mov ds,ax cmp [word ptr 0],"EC" jne @@notace lea si,[@@toresov] mov [word ptr ss:si],0FFFFh mov bx,[ds:exe.sections] cmp bx,0 je @@finishloading @@loading: cmp [dword ptr bx],0 je @@finishloading mov ax,bx add ax,4 pushad call biosprint,ax popad call mbcreate,ax,[word ptr bx+2] jc @@error inc si inc si mov [ss:si],ax push si mov si,[bx] xor di,di mov es,ax mov cx,[bx+2] cld rep movsb pop si add bx,4 @@gonext: inc bx cmp [byte ptr bx],0 jne @@gonext inc bx jmp @@loading @@finishloading: cmp [word ptr ss:si],0FFFFh je @@finishdepands call mbloadfuncs,[word ptr ss:si] jc @@depandserror dec si dec si jmp @@finishloading @@finishdepands: ret @@notace: stc ret @@error: stc ret @@depandserror: stc ret endp mbloadsection ;Initialise les blocs de mémoire en prenant memorystart pour segment de base PROC mbinit FAR USES ax,cx,si,di,ds,es cmp [cs:firstmb],0 jne @@alreadyok push cs pop ds mov [cs:firstmb],memorystart mov ax,memorystart-2 mov es,ax mov si,offset afree xor di,di mov cx,size mb rep movsb clc ret @@alreadyok: stc ret endp mbinit afree mb <"HN",0,0,0,0A000h-memorystart,"Libre"> db 0 ;Creér un bloc de nom %0 de taille %1 (octets) -> n°segment dans AX PROC mbcreate FAR ARG @blocks:word,@size:word USES bx,cx,dx,si,di,ds,es push gs mov ax,[ss:bp+4] mov dx,ax dec dx dec dx mov gs,dx cmp [word ptr gs:0x0],'NH' je @@oktoset mov ax,memorystart @@oktoset: mov gs,ax mov cx,[@size] shr cx,4 inc cx mov bx,[cs:firstmb] dec bx dec bx mov dl,true @@searchfree: cmp dl,false je @@notenougtmem mov es,bx cmp [word ptr es:mb.check],"NH" jne @@memoryerror cmp [es:mb.isnotlast],true sete dl cmp [es:mb.reference],free jne @@notsogood mov ax,[es:mb.sizes] cmp cx,ax ja @@notsogood mov [word ptr es:mb.check],"NH" mov [es:mb.isnotlast],true mov [es:mb.reference],gs mov [es:mb.isresident],false lea di,[es:mb.names] push cx mov cx,24/4 mov si,[@blocks] cld rep movsd pop cx inc bx inc bx sub ax,cx cmp ax,0 je @@nofree dec ax dec ax mov [es:mb.sizes],cx add cx,bx mov es,cx mov si,offset afree xor di,di mov cx,size mb push cs pop ds cld rep movsb mov [es:mb.isnotlast],dl mov [es:mb.sizes],ax @@nofree: mov ax,bx pop gs clc ret @@notsogood: inc bx inc bx add bx,[es:mb.sizes] jmp @@searchfree @@memoryerror: pop gs stc ret @@notenougtmem: pop gs stc ret endp mbcreate ;Libère le bloc de mémoire %0 et ses sous blocs PROC mbfree FAR ARG @blocks:word USES ax,bx,cx,si,di,ds,es mov bx,[@blocks] mov ax,bx dec bx dec bx mov es,bx cmp [word ptr es:mb.check],"NH" jne @@memoryerror cmp [es:mb.reference],free je @@wasfree cmp [es:mb.isresident],true je @@wasresident mov [es:mb.reference],free push cs pop ds mov si,offset @@isfree lea di,[es:mb.names] mov cx,6 cld rep movsb mov bx,[cs:firstmb] dec bx dec bx @@searchtofree: mov es,bx cmp [word ptr es:mb.check],"NH" jne @@memoryerror inc bx inc bx add bx,[es:mb.sizes] cmp [es:mb.sizes],0 je @@nottofree cmp ax,[es:mb.reference] jne @@nottofree mov [es:mb.isresident],false mov [es:mb.reference],free mov si,offset @@isfree lea di,[es:mb.names] mov cx,6 cld rep movsb @@nottofree: cmp [es:mb.isnotlast],true je @@searchtofree call mbclean ret @@memoryerror: stc ret @@wasfree: stc ret @@wasresident: stc ret @@isfree db "libre",0 endp mbfree ;Mise a nivo de la mémoire (jonction de blocs libre) PROC mbclean FAR USES ax,bx,dx,es,gs mov bx,[cs:firstmb] dec bx dec bx xor ax,ax xor dx,dx @@searchfree: mov gs,bx cmp [word ptr gs:mb.check],"NH" jne @@memoryerror inc bx inc bx add bx,[gs:mb.sizes] cmp [word ptr gs:mb.sizes],0 je @@notenougtmem cmp [gs:mb.reference],free jne @@notfree cmp ax,0 je @@notmeetfree add dx,[gs:mb.sizes] mov [word ptr gs:mb.check],0 mov [dword ptr gs:mb.names],0 inc dx inc dx jmp @@nottrigered @@notmeetfree: xor dx,dx mov ax,gs jmp @@nottrigered @@notfree: cmp ax,0 je @@nottrigered mov es,ax add [es:mb.sizes],dx xor ax,ax @@nottrigered: cmp [gs:mb.isnotlast],true je @@searchfree cmp ax,0 je @@reallyfinish mov es,ax add [es:mb.sizes],dx mov [es:mb.isnotlast],false @@reallyfinish: clc ret @@notenougtmem: stc ret @@memoryerror: stc ret endp mbclean ;Rend le segment %0 résident PROC mbresident FAR ARG @blocks:word USES bx,es mov bx,[@blocks] dec bx dec bx mov es,bx cmp [word ptr es:mb.check],"NH" jne @@memoryerror mov [es:mb.isresident],true ret @@memoryerror: stc ret endp mbresident ;Rend le segment %0 non résident PROC mbnonresident FAR ARG @blocks:word USES bx,es mov bx,[@blocks] dec bx dec bx mov es,bx cmp [word ptr es:mb.check],"NH" jne @@memoryerror mov [es:mb.isresident],false ret @@memoryerror: stc ret endp mbnonresident ;Change le proprietaire de %0 a %1 PROC mbchown FAR ARG @blocks:word,@owner:word USES bx,dx,es mov bx,[@blocks] dec bx dec bx mov es,bx cmp [word ptr es:mb.check],"NH" jne @@memoryerror cmp [es:mb.reference],free je @@wasfree mov dx,[@owner] mov [es:mb.reference],dx ret @@memoryerror: stc ret @@wasfree: stc ret endp mbchown ;Alloue un bloc /data de CX caractere pour le process appelant -> ax PROC mballoc FAR ARG @size:word USES si,ds push cs pop ds call mbcreate,offset @@data,[@size] call mbchown,ax,[word ptr ss:bp+4] ret @@data db '/data',0 endp mballoc ;Renvoie en AX le MB n° %0 carry quand terminé PROC mbget FAR ARG @num:word USES bx,dx,es mov bx,[cs:firstmb] dec bx dec bx xor dx,dx @@searchfree: mov es,bx cmp [word ptr es:mb.check],"NH" jne @@memoryerror inc bx inc bx add bx,[es:mb.sizes] cmp [es:mb.sizes],0 je @@memoryerror cmp dx,[@num] je @@foundmcb ja @@notfound inc dx cmp [es:mb.isnotlast],true je @@searchfree @@memoryerror: stc ret @@foundmcb: mov ax,es inc ax inc ax clc ret @@notfound: stc ret endp mbget ;Renvoie en AX le MCB qui correspond a ds:%0 PROC mbfind FAR ARG @blocks:word USES bx,si,di,es mov bx,[cs:firstmb] dec bx dec bx mov si,[@blocks] @@search: mov es,bx lea di,[es:mb.names] cmp [word ptr es:mb.check],"NH" jne @@memoryerror inc bx inc bx add bx,[es:mb.sizes] cmp [es:mb.sizes],0 je @@memoryerror push si di @@cmpnames: mov al,[es:di] cmp al,[ds:si] jne @@ok cmp al,0 je @@ok inc si inc di jmp @@cmpnames @@ok: pop di si je @@foundmcb cmp [es:mb.isnotlast],true je @@search @@notfound: stc ret @@memoryerror: stc ret @@foundmcb: mov ax,es inc ax inc ax clc ret endp mbfind ;Renvoie en AX le sous mcb qui correspond a %0 et qui appartien a %1 PROC mbfindsb FAR ARG @blocks:word,@owner:word USES bx,dx,si,di,es mov bx,[cs:firstmb] dec bx dec bx mov si,[@blocks] lea di,[es:mb.names] mov dx,[@owner] @@search: mov es,bx cmp [word ptr es:mb.check],"NH" jne @@memoryerror inc bx inc bx add bx,[es:mb.sizes] cmp [es:mb.sizes],0 je @@memoryerror push si di @@cmpnames: mov al,[es:di] cmp al,[ds:si] jne @@ok cmp al,0 je @@ok inc si inc di jmp @@cmpnames @@ok: pop di si jne @@notfoundmcb cmp [es:mb.reference],dx je @@foundmcb @@notfoundmcb: cmp [es:mb.isnotlast],true je @@search @@notfound: stc ret @@foundmcb: mov ax,es inc ax inc ax clc ret @@memoryerror: stc ret endp mbfindsb ;Resouds les dépendances du bloc de mémoire %0 PROC mbloadfuncs FAR ARG @blocks:word USES ax,bx,cx,dx,si,ds mov ds,[@blocks] cmp [word ptr 0],"EC" jne @@notace mov si,[ds:exe.imports] cmp si,0 je @@endofloading @@loadfuncs: cmp [word ptr si],0 je @@endofloading call mbsearchfunc,si jnc @@toendoftext mov bx,si pushad call biosprint,si popad @@findend: inc bx cmp [byte ptr bx], ':' jne @@findend mov [byte ptr bx],0 call [cs:projfile],si jc @@erroronload mov [byte ptr bx],':' pushad call biosprint,si popad call mbsearchfunc,si jc @@libnotexist @@toendoftext: mov cl,[si] cmp cl,0 je @@oktonext inc si jmp @@toendoftext @@oktonext: inc si mov [si],ax mov [si+2],dx add si,4 jmp @@loadfuncs @@endofloading: clc ret @@notace: stc ret @@libnotexist: stc ret @@erroronload: stc ret endp mbloadfuncs ;Recherche une fonction pointé par DS:%0 en mémoire et renvoie son adresse en DX:AX PROC mbsearchfunc FAR ARG @func:word USES bx,si,di,es mov bx,[@func] mov si,bx @@findend: inc bx cmp [byte ptr bx], ':' jne @@findend mov [byte ptr bx],0 call mbfind,si mov [byte ptr bx],':' jc @@notfoundattallthesb mov es,ax cmp [word ptr es:exe.checks],"EC" jne @@notfoundattallthesb mov di,[es:exe.exports] inc bx inc bx @@functions: cmp [word ptr es:di],0 je @@notfoundattallthesb mov si,bx @@cmpnamesfunc: mov al,[es:di] cmp al,[ds:si] jne @@notfoundthesb cmp al,0 je @@seemsok inc si inc di jmp @@cmpnamesfunc @@notfoundthesb: mov al,[es:di] cmp al,0 je @@oktonext inc di jmp @@notfoundthesb @@oktonext: inc di inc di inc di jmp @@functions @@seemsok: mov dx,es mov ax,[es:di+1] clc ret @@notfoundattallthesb: stc ret endp mbsearchfunc