cos2000v1/noyau/mcb.asm

235 lines
4.8 KiB
NASM

.model tiny
.486
smart
.code
org 0100h
include ..\include\mem.h
include ..\include\divers.h
start:
maxfunc equ 5
jmp tsr ;Saute à la routine résidente
nameed db 'MB' ;Nom drivers
id dw 1234h ;Identifiant drivers
Tsr:
cli ;Désactive interruptions logiciellement
cmp ax,cs:ID ;Compare si test de chargement
jne nomore ;Si pas test alors on continu
rol ax,3*4 ;Rotation de 3 chiffre de l'ID pour montrer que le drivers est chargé
jmp itsok ;On termine l'int avec notre code d'ID preuve du bon chargement de VIDEO
nomore:
cmp ah,maxfunc
jbe noerrorint
stc
jmp itsok
noerrorint:
clc
push bx
mov bl,ah ;On calcule d'aprés le n° de fonction
xor bh,bh ;quel sera l'entrée dans la table indexée
shl bx,1 ;des adresses fonctions.
mov bx,cs:[bx+tables] ;On récupère cette adresse depuis la table
mov cs:current,bx ;On la stocke temporairement pour obtenir les registres d'origine
pop bx
clc
call cs:current ;Puis on execute la fonction
itsok:
push bp
mov bp,sp ;On prend sp dans bp pour adresser la pile
jnc noerror ;La fonction appelée a renvoyer une erreur : Flag CARRY ?
or byte ptr [bp+6],1b;Si oui on le retranscrit sur le registre FLAG qui sera dépilé lors du IRET
;xor eax,eax
;mov ax,cs ;On récupère le segment et l'offset puis en renvoie l'adresse physique
;shl eax,4 ;de l'erreur.
;add ax,cs:current
jmp endofint ;on termine l'int
noerror:
and byte ptr [bp+6],0FEh;Si pas d'erreur on efface le Bit CARRY du FLAG qui sera dépilé lors du IRET
endofint:
pop bp
sti ;On réactive les interruptions logiciellement
iret ;Puis on retourne au programme appelant.
current dw 0 ;Mot temporaire qui contient l'adresse de la fonction appelée
tables dw MBinit ;Table qui contient les adresses de toutes les fonctions de VIDEO (WORD)
dw MBFree
dw MBCreate
dw MBresident
dw MBGet
FirstMB dw 0
;Initialise les blocs de mémoire en prenant memorystart pour segment de base
MBinit:
push ax cx es
cmp cs:FirstMB,0
jne notforfree
mov ax,memorystart
mov cs:Firstmb,ax
mov cx,0A000h
sub cx,ax
dec ax
dec ax
mov es,ax
cmp es:[MB.Check],'NH'
je notforfree
mov es:[MB.Reference],Free
mov es:[MB.Sizes],cx
mov es:[MB.Check],'NH'
mov dword ptr es:[MB.Names],'eerF'
mov dword ptr es:[MB.Names+4],0
mov es:[MB.IsNotLast],False
clc
pop es cx ax
ret
notforfree:
stc
pop es cx ax
ret
;Libère le bloc de mémoire GS
MBFree:
push bx es
mov bx,gs
dec bx
dec bx
mov es,bx
cmp es:[MB.Check],'NH'
je wasfree
cmp es:[MB.Reference],Free
je wasfree
cmp es:[MB.IsResident],true
je wasfree
mov es:[MB.IsResident],false
mov es:[MB.Reference],Free
mov dword ptr es:[MB.Names],'eerF'
mov dword ptr es:[MB.Names+4],0
pop es bx
ret
wasfree:
stc
pop es bx
ret
;Renvoie en GS le MB n° cx carry quand terminé
MBGet:
push bx dx
mov bx,cs:firstmb
dec bx
dec bx
xor dx,dx
searchfree2:
mov gs,bx
cmp gs:[MB.Check],'NH'
jne itsend
inc bx
inc bx
add bx,gs:[MB.Sizes]
cmp word ptr gs:[MB.Sizes],0
je itsend
cmp dx,cx
je foundmcb
ja itsend
inc dx
cmp gs:[MB.IsNotLast],true
je searchfree2
itsend:
stc
pop dx bx
ret
foundmcb:
clc
pop dx bx
ret
;Creér un bloc de nom ds:si de taille cx (octets) -> n°segment dans GS
MBCreate:
push ax bx cx dx si di es
shr cx,4
inc cx
mov bx,cs:firstmb
dec bx
dec bx
mov dl,1
searchfree:
cmp dl,False
je wasntgood
mov es,bx
cmp es:[MB.Check],'NH'
jne wasntgood
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],cs
mov es:[MB.IsResident],False
mov es:[MB.Sizes],cx
mov di,MB.Names
push ax cx
mov cx,32
loops:
mov dh,[si]
inc si
dec cx
jz endofloops
cmp dh,0
je endofloops
mov es:[di],dh
inc di
jmp loops
endofloops:
inc cx
mov al,0
rep stosb
pop cx ax
sub ax,cx
dec ax
dec ax
;js nofree
inc bx
inc bx
mov gs,bx
add bx,cx
mov es,bx
mov es:[MB.IsNotLast],dl
mov es:[MB.IsResident],False
mov es:[MB.Reference],Free
mov es:[MB.Sizes],ax
mov dword ptr es:[MB.Names],'eerF'
mov dword ptr es:[MB.Names+4],0
mov es:[MB.Check],'NH'
nofree:
clc
pop es di si dx cx bx ax
ret
wasntgood:
stc
pop es di si dx cx bx ax
ret
notsogood:
inc bx
inc bx
add bx,es:[MB.Sizes]
jmp searchfree
;Rend le segment GS résident
MBresident:
push bx es
mov bx,gs
dec bx
mov es,bx
mov es:[MB.IsResident],True
pop es bx
ret
end start