; ce module regroupe des fonctions annexes dont on se servira lors du passage ; en mode protege. ; Auteur: Benoit Papillault ; Creation: Dimanche 15 Juin 1997 ; Historique: ; 15/06/1997: on se limitera a une version qui ne gere pas les ; interruptions, pas plus que les irq (tant pis) include model.inc .386p ; Quelques constantes pour le port du 8042 (controlleur clavier) ; read output_register equ 060h status_register equ 064h ; write data_register equ 060h command_register equ 064h _TEXT segment public 'CODE' use16 assume cs:_TEXT ; verifie que l'on a au moins un 386+, renvoie 1 dans ce cas, 0 sinon ; int check_processor(); public _check_processor _check_processor proc PROC_MODEL push bp mov bp,sp pushf xor ah,ah push ax popf pushf pop ax and ah,0f0h cmp ah,0f0h je short detectno386 mov ah,0f0h push ax popf pushf pop ax and ah,0f0h jz short detectno386 mov ax,1 jmp short check_ret detectno386: mov ax,0 check_ret: popf pop bp ret _check_processor endp ; verifie si l'on n'est pas deja en mode protege. renvoie 1 si l'on est deja ; en mode protege, 0 sinon. ; int check_v86(); public _check_v86 _check_v86 proc PROC_MODEL push bp mov bp,sp smsw ax test al,1 jnz already_v86 mov ax,0 jmp short _check_v86_return already_v86: mov ax,1 _check_v86_return: pop bp ret _check_v86 endp ; regarde l'etat du bit A20. Dans le cas ou A20=0, la ligne d'adresse A20 ; du processeur est toujours a zero, quelquesoit l'adresse emise. Dans le ; cas ou A20=1, la ligne d'adresse reflete la valeur "normale" du bit ; d'adresse 20 ; int get_a20() public _get_a20 _get_a20 proc PROC_MODEL push bp mov bp,sp push fs push gs xor ax,ax mov fs,ax dec ax mov gs,ax mov ax,fs:[0] cmp ax,gs:[10h] je a20_is_not_set mov ax,1 jmp short a20_return a20_is_not_set: xor ax,ax a20_return: ; mov sp,bp pop gs pop fs pop bp ret _get_a20 endp ; Attends que le buffer d'entree du 8042 soit vide attendre proc PROC_MODEL push bp mov bp,sp push ax push cx xor cx,cx l1: in al,status_register and al,2 loopnz l1 pop cx pop ax pop bp ret attendre endp ; ecriture d'un octet de commande (al) dans le registre du 8042 ; cette fonction n'est pas utilisable en C _write_command proc PROC_MODEL push bp mov bp,sp push ax call attendre mov al,0d1h out command_register,al call attendre pop ax out data_register,al call attendre mov al,0ffh out command_register,al pop bp ret _write_command endp ; Met la ligne A20 dans un etat determine ; renvoie 1 si tous est ok, 0 sinon ; int set_a20(int A20) public _set_a20 _set_a20 proc PROC_MODEL push bp mov bp,sp mov ax,[bp+cPtrSize+2] cmp ax,0 je disable_a20 ; enable a20 in al,92h ; PS/2 System Control Port or al,2 jmp short $+2 jmp short $+2 jmp short $+2 out 92h,al call _get_a20 cmp ax,1 je set_a20_ret_ok mov al,0dfh call _write_command ; on ne fait pas de test sur le bon fonctionnement de _write_command jmp set_a20_ret_ok disable_a20: ; disable a20 in al,92h ; PS/2 System Control Port and al,not 2 jmp short $+2 jmp short $+2 jmp short $+2 out 92h,al call _get_a20 cmp ax,0 je set_a20_ret_ok mov al,0ddh call _write_command set_a20_ret_ok: mov ax,1 jmp short set_a20_ret set_a20_ret_nok: xor ax,ax set_a20_ret: pop bp ret _set_a20 endp _TEXT ends code32 segment public use32 code32 ends end