;Affiche le nombre hexa dans %0[dword] proc biosprinth, num:dword mov edx,[num] mov ah,09h mov di,8 .hexaize: rol edx,4 mov si,dx and si,1111b mov al,[cs:si+.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 retf .tab db '0123456789ABCDEF' endp ;Affiche le texte ASCIIZ pointé par %0 proc biosprint, pointer 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: retf endp proc 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 retf endp proc disablea20 mov al,0d1h out 64h,al call a20wait mov al,0DDh out 60h,al call a20wait ;mov al,0ffh ;out 64h,al ;call a20wait retf endp 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 push cs pop ds ; first, calculate the linear address of GDT xor eax,eax mov ax,ds shl eax,4 add dword [.gdt+2],eax ; store as GDT linear base addr ; now load the GDT into the GDTR lgdt fword [.gdt] ; load GDT base mov bx,1 * descriptor.sizeof ; 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 retf ; .gdt: gdtitse descriptor .gdtend - .gdt - 1, .gdt, 0, 0, 0, 0 ; the GDT itself gdtdata descriptor 0ffffh, 0, 0, 091h, 0cfh, 0 ; 4G data segment .gdtend: endp ;Attend l'appuie sur une touche proc bioswaitkey xor ax,ax int 16h retf endp firstmb dw 0 ;Charge les sections du block %0 proc mbloadsection, blocks mov ax,[blocks] mov es,ax mov ds,ax cmp word [0],"EC" jne .notace lea si,[.toresov] mov word [ss:si],0FFFFh mov bx,[ds:exe.sections] cmp bx,0 je .finishloading .loading: cmp dword [bx],0 je .finishloading mov ax,bx add ax,4 pushad stdcall biosprint,ax popad stdcall mbcreate,ax,word [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 [bx],0 jne .gonext inc bx jmp .loading .finishloading: cmp word [ss:si],0FFFFh je .finishdepands stdcall mbloadfuncs,word [ss:si] jc .depandserror dec si dec si jmp .finishloading .finishdepands: retf .notace: stc retf .error: stc retf .depandserror: stc retf .toresov dw 60 dup (0) endp ;Initialise les blocs de mémoire en prenant memorystart pour segment de base proc mbinit cmp [cs:firstmb],0 jne .alreadyok push cs pop ds mov [cs:firstmb],memorystart mov ax,memorystart-2 mov es,ax mov si,afree xor di,di mov cx,mb.sizeof rep movsb clc retf .alreadyok: stc retf endp 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 , blocks, size push gs mov ax,[ss:bp+4] mov dx,ax dec dx dec dx mov gs,dx cmp word [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 [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 [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,afree xor di,di mov cx,mb.sizeof push cs pop ds cld rep movsb mov [es:mb.isnotlast],dl mov [es:mb.sizes],ax .nofree: mov ax,bx pop gs clc retf .notsogood: inc bx inc bx add bx,[es:mb.sizes] jmp .searchfree .memoryerror: pop gs stc retf .notenougtmem: pop gs stc retf endp ;Libère le bloc de mémoire %0 et ses sous blocs proc mbfree, blocks mov bx,[blocks] mov ax,bx dec bx dec bx mov es,bx cmp word [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,.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 [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,.isfree lea di,[es:mb.names] mov cx,6 cld rep movsb .nottofree: cmp [es:mb.isnotlast],true je .searchtofree stdcall mbclean retf .memoryerror: stc retf .wasfree: stc retf .wasresident: stc retf .isfree db "libre",0 endp ;Mise a nivo de la mémoire (jonction de blocs libre) proc mbclean mov bx,[cs:firstmb] dec bx dec bx xor ax,ax xor dx,dx .searchfree: mov gs,bx cmp word [gs:mb.check],"NH" jne .memoryerror inc bx inc bx add bx,[gs:mb.sizes] cmp word [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 [gs:mb.check],0 mov dword [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 retf .notenougtmem: stc retf .memoryerror: stc retf endp ;Rend le segment %0 résident proc mbresident, blocks mov bx,[blocks] dec bx dec bx mov es,bx cmp word [es:mb.check],"NH" jne .memoryerror mov [es:mb.isresident],true retf .memoryerror: stc retf endp ;Rend le segment %0 non résident proc mbnonresident, blocks mov bx,[blocks] dec bx dec bx mov es,bx cmp word [es:mb.check],"NH" jne .memoryerror mov [es:mb.isresident],false retf .memoryerror: stc retf endp ;Change le proprietaire de %0 a %1 proc mbchown ,blocks, owner mov bx,[blocks] dec bx dec bx mov es,bx cmp word [es:mb.check],"NH" jne .memoryerror cmp [es:mb.reference],free je .wasfree mov dx,[owner] mov [es:mb.reference],dx retf .memoryerror: stc retf .wasfree: stc retf endp ;Alloue un bloc /data de CX caractere pour le process appelant -> ax proc mballoc, size push cs pop ds stdcall mbcreate,.data,[size] stdcall mbchown,ax,word [ss:bp+4] retf .data db '/data',0 endp ;Renvoie en AX le MB n° %0 carry quand terminé proc mbget, num mov bx,[cs:firstmb] dec bx dec bx xor dx,dx .searchfree: mov es,bx cmp word [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 retf .foundmcb: mov ax,es inc ax inc ax clc retf .notfound: stc retf endp ;Renvoie en AX le MCB qui correspond a ds:%0 proc mbfind, blocks mov bx,[cs:firstmb] dec bx dec bx mov si,[blocks] .search: mov es,bx lea di,[es:mb.names] cmp word [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 retf .memoryerror: stc retf .foundmcb: mov ax,es inc ax inc ax clc retf endp ;Renvoie en AX le sous mcb qui correspond a %0 et qui appartien a %1 proc mbfindsb, blocks, owner 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 [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 retf .foundmcb: mov ax,es inc ax inc ax clc retf .memoryerror: stc retf endp ;Resouds les dépendances du bloc de mémoire %0 proc mbloadfuncs, blocks mov ds,[blocks] cmp word [0],"EC" jne .notace mov si,[ds:exe.imports] cmp si,0 je .endofloading .loadfuncs: cmp word [si],0 je .endofloading stdcall mbsearchfunc,si jnc .toendoftext mov bx,si ;pushad ;stdcall biosprint,si ;popad .findend: inc bx cmp byte [bx], ':' jne .findend mov byte [bx],0 stdcall [cs:projfile],si mov byte [bx],':' jc .erroronload ;pushad ;stdcall biosprint,si ;popad stdcall 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 retf .notace: stc retf .libnotexist: stc retf .erroronload: stc retf endp ;Recherche une fonction pointé par DS:%0 en mémoire et renvoie son adresse en DX:AX proc mbsearchfunc, func mov bx,[func] mov si,bx .findend: inc bx cmp byte [bx], ':' jne .findend mov byte [bx],0 stdcall mbfind,si mov byte [bx],':' jc .notfoundattallthesb mov es,ax cmp word [es:exe.checks],"EC" jne .notfoundattallthesb mov di,[es:exe.exports] inc bx inc bx .functions: cmp word [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 retf .notfoundattallthesb: stc retf endp