First commit
This commit is contained in:
commit
7d6d50e432
50 changed files with 5737 additions and 0 deletions
554
KEYBOARD.ASM
Normal file
554
KEYBOARD.ASM
Normal file
|
|
@ -0,0 +1,554 @@
|
|||
;Driver della tastiera per NXOS
|
||||
;------------------------------
|
||||
;Written by: MaX and Alb‚ - 2001
|
||||
;
|
||||
;Questo driver sostituisce le routine dell'int 16h del bios.
|
||||
;Controlla anche se particolari combinazioni di tasti sono state premute:
|
||||
;
|
||||
;CTRL+C o CTRL+Del --> Termina il processo visibile
|
||||
;CTRL+N --> Rende visibile il processo successivo
|
||||
|
||||
;Prossima funzione da implementare: GetString
|
||||
|
||||
|
||||
org 0h
|
||||
|
||||
InstallDriver:
|
||||
cli
|
||||
xor ax,ax
|
||||
mov es,ax
|
||||
mov ax,offset Int25h
|
||||
mov word ptr es:[25h*4],ax
|
||||
mov ax,cs
|
||||
mov word ptr es:[(25h*4)+2],ax
|
||||
|
||||
mov ax,word ptr es:[09h*4]
|
||||
mov word ptr cs:[OldInt09h],ax
|
||||
mov ax,word ptr es:[09h*4+2]
|
||||
mov word ptr cs:[OldInt09h+2],ax
|
||||
|
||||
mov ax,offset Int09h
|
||||
mov word ptr es:[09h*4],ax
|
||||
mov ax,cs
|
||||
mov word ptr es:[09h*4+2],ax
|
||||
|
||||
mov ah,02h
|
||||
mov bl,1
|
||||
int 20h
|
||||
|
||||
;==============================================================================
|
||||
|
||||
Int25h:
|
||||
cmp ah,00h
|
||||
je Int25h_00h
|
||||
cmp ah,01h
|
||||
je Int25h_01h
|
||||
cmp ah,02h
|
||||
je Int25h_02h
|
||||
cmp ah,03h
|
||||
je Int25h_03h
|
||||
cmp ah,04h
|
||||
je Int25h_04h
|
||||
cmp ah,05h
|
||||
je Int25h_05h
|
||||
cmp ah,06h
|
||||
je Int25h_06h
|
||||
cmp ah,07h
|
||||
je Int25h_07h
|
||||
iret
|
||||
Int25h_00h:
|
||||
call GetKey
|
||||
iret
|
||||
Int25h_01h:
|
||||
call TestKey
|
||||
retf 2 ;Attenzione qui: uso "retf 2" invece di "iret", perchè iret
|
||||
;ripristina lo stato dei
|
||||
;flags, mentre io voglio che il flag Z sia settato dalla
|
||||
;procedura "TestKey"
|
||||
Int25h_02h:
|
||||
call GetStatus
|
||||
iret
|
||||
Int25h_03h:
|
||||
call SetAutoRpt
|
||||
iret
|
||||
Int25h_04h:
|
||||
call EndKeyboardDriver
|
||||
iret
|
||||
Int25h_05h:
|
||||
call StoreKey
|
||||
iret
|
||||
Int25h_06h:
|
||||
call GetKeyWithEcho
|
||||
iret
|
||||
Int25h_07h:
|
||||
call GetStringWithEcho
|
||||
iret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
EndKeyboardDriver:
|
||||
xor ax,ax
|
||||
mov es,ax
|
||||
mov ax,word ptr cs:[OldInt09h]
|
||||
mov es:[09h*4],ax
|
||||
mov ax,word ptr cs:[OldInt09h+2]
|
||||
mov es:[09h*4+2],ax
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
GetKey:
|
||||
;prende il codice del tasto premuto dal buffer di tastiera e lo retituisce in AX
|
||||
;Output: al=ascii-code ah=scan-code
|
||||
push cx
|
||||
push si
|
||||
|
||||
GetKey1:
|
||||
mov ah,03h
|
||||
int 20h
|
||||
cmp si,cx
|
||||
je GetKey2 ;se il processo Š quello visibile, allora legge il tasto
|
||||
mov ah,05h ;altrimenti passa al processo successivo
|
||||
int 20h
|
||||
jmp GetKey1
|
||||
|
||||
GetKey2:
|
||||
Call TestKey
|
||||
jz GetKey1
|
||||
|
||||
cli
|
||||
push ds
|
||||
mov ax,40h
|
||||
mov ds,ax
|
||||
mov si,word ptr ds:[HeadPtr] ;carica in bx l'indirizzo del prossimo carattere
|
||||
mov ax,ds:[si] ;preleva il carattere e lo mette in ax
|
||||
inc si
|
||||
inc si
|
||||
cmp si,ds:[82h] ;check for overflow
|
||||
jnz GetKey_End
|
||||
mov si,ds:[80h] ;ripristina il valore originale di HeadPtr
|
||||
|
||||
GetKey_End:
|
||||
mov word ptr ds:[HeadPtr],si
|
||||
pop ds
|
||||
|
||||
pop si
|
||||
pop cx
|
||||
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
TestKey:
|
||||
;verifica se e' disponibile un carattere nel buffer
|
||||
; ZF=1 il carattere non e' disponibile
|
||||
; ZF=0 il carattere e' disponibile
|
||||
; se il car. e' disponibile allora al= ascii-code ah=scan-code
|
||||
; il carattere non viene rimosso dal buffer
|
||||
|
||||
push ds
|
||||
push bx
|
||||
|
||||
TestKey1:
|
||||
mov ah,03h
|
||||
int 20h
|
||||
cmp si,cx
|
||||
je TestKey2
|
||||
mov ah,05h
|
||||
int 20h
|
||||
jmp TestKey1
|
||||
|
||||
TestKey2:
|
||||
mov ax, 40h
|
||||
mov ds, ax
|
||||
cli ;regione critica
|
||||
mov bx, word ptr ds:[HeadPtr]
|
||||
mov ax, ds:[bx] ;mette il carattere letto dal buffer in ax
|
||||
cmp bx, word ptr ds:[TailPtr] ;ZF=1, se il buffer e' vuoto
|
||||
pop bx
|
||||
pop ds
|
||||
sti ;Bisogna ricordarsi di risettare l'interrupt flag, perchŠ
|
||||
;da TestKey non esco con un "iret" ma con "retf 2" (quindi
|
||||
;non viene risettato il valore originale dei flags)
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------------
|
||||
|
||||
GetStringWithEcho:
|
||||
;Input: DS:[SI] --> buffer in cui memorizzare la stringa
|
||||
;Output CX=numero di caratteri della stringa.
|
||||
;La stringa finisce quando viene premuto CR (#13) (cioŠ Enter). Il carattere
|
||||
;CR non viene memorizzato nel buffer
|
||||
;I caratteri premuti vengono visualizzati sul video.
|
||||
|
||||
push ax
|
||||
push si
|
||||
|
||||
xor cx,cx
|
||||
|
||||
GetString1:
|
||||
call GetKey
|
||||
cmp al,13
|
||||
je GetString_End
|
||||
cmp al,8
|
||||
je GetString_DelPressed
|
||||
mov byte ptr ds:[si],al
|
||||
inc si
|
||||
inc cx
|
||||
mov ah,00h
|
||||
int 24h
|
||||
jmp GetString1
|
||||
|
||||
GetString_DelPressed:
|
||||
test cx,cx
|
||||
jz GetString1
|
||||
|
||||
dec si
|
||||
dec cx
|
||||
mov al,' '
|
||||
mov byte ptr ds:[si],al
|
||||
|
||||
mov ah,05h
|
||||
int 24h
|
||||
sub dl,1
|
||||
push dx
|
||||
mov ah,06h
|
||||
int 24h
|
||||
|
||||
mov al,' '
|
||||
mov ah,00h
|
||||
int 24h
|
||||
|
||||
pop dx
|
||||
mov ah,06h
|
||||
int 24h
|
||||
|
||||
jmp GetString1
|
||||
|
||||
GetString_End:
|
||||
|
||||
pop si
|
||||
pop ax
|
||||
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
GetKeyWithEcho:
|
||||
;output AL=ascii code, AH=scan code
|
||||
|
||||
call GetKey
|
||||
push ax
|
||||
mov ah,00h
|
||||
int 24h
|
||||
pop ax
|
||||
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
;patch dell'interrupt 09h
|
||||
;Questo Š necessario per determinare la pressione di certe combinazioni di tasti
|
||||
;(es CTRL+C --> termina il processo visibile...ecc.)
|
||||
|
||||
;Per maggiori informazioni, consultate il capitolo 20 del libro
|
||||
;"The Art of Assembly Language".
|
||||
|
||||
Int09h:
|
||||
cli
|
||||
push ax
|
||||
push cx
|
||||
push ds
|
||||
|
||||
|
||||
mov ax,40h
|
||||
mov ds,ax
|
||||
; mov al,0adh
|
||||
; call SetCmd ;disabilita temporaneamente la tastiera
|
||||
|
||||
cli
|
||||
; xor cx,cx
|
||||
|
||||
Int09h_Wait4Data:
|
||||
; in al,64h
|
||||
; test al,10b
|
||||
; loopnz Int09h_Wait4Data
|
||||
|
||||
mov al,byte ptr ds:[17h]
|
||||
test al,100b
|
||||
jz OrigInt09h
|
||||
|
||||
and al,11111011b
|
||||
mov byte ptr ds:[17h],al
|
||||
|
||||
in al,60h
|
||||
cmp al,2eh ;guarda se Š stata premuta una C (per il CTRL+C)
|
||||
je Int09h_CtrlC
|
||||
cmp al,53h ;controlla se Š premuto Del
|
||||
je Int09h_CtrlC
|
||||
|
||||
cmp al,31h ;controlla se Š premuto il tasto 'N'
|
||||
je Int09h_CtrlN
|
||||
|
||||
; jmp OrigInt09h ;altrimenti salta all'interrupt originale
|
||||
|
||||
mov al,20h
|
||||
out 20h,al
|
||||
|
||||
pop ds
|
||||
pop cx
|
||||
pop ax
|
||||
|
||||
iret
|
||||
|
||||
|
||||
Int09h_CheckCtrlC:
|
||||
|
||||
; mov al,byte ptr ds:[17h]
|
||||
; test al,100b ;controlla se Š premuto CTRL
|
||||
; jnz Int09h_CtrlC
|
||||
|
||||
; jmp OrigInt09h
|
||||
|
||||
Int09h_CheckCtrlN:
|
||||
; mov al,byte ptr ds:[17h]
|
||||
; test al,100b
|
||||
; jnz Int09h_CtrlN
|
||||
|
||||
; jmp OrigInt09h
|
||||
|
||||
Int09h_CtrlC:
|
||||
;CTRL+C o CTRL+Del sono stati premuti
|
||||
; mov al,0aeh ;riabilita la tastiera
|
||||
; call SetCmd
|
||||
|
||||
mov al,20h ;segnale di fine interrupt
|
||||
out 20h,al
|
||||
|
||||
pop ds
|
||||
pop cx
|
||||
pop ax
|
||||
|
||||
mov ah,02h ;termina il processo corrente
|
||||
mov bl,0
|
||||
int 20h
|
||||
|
||||
Int09h_CtrlN:
|
||||
mov ah,06h ;controlla qual'Š il processo successivo
|
||||
int 20h
|
||||
|
||||
mov ah,02h ;setta visibile il processo successivo
|
||||
int 24h
|
||||
|
||||
; mov al,0aeh ;riabilita la tastiera
|
||||
; call SetCmd
|
||||
|
||||
mov al,20h ;segnale di fine interrupt
|
||||
out 20h,al
|
||||
|
||||
pop ds
|
||||
pop cx
|
||||
pop ax
|
||||
iret
|
||||
|
||||
OrigInt09h:
|
||||
; mov al,0aeh ;riabilita la tastiera
|
||||
; call SetCmd
|
||||
|
||||
; mov al,20h
|
||||
; out 20h,al
|
||||
|
||||
pop ds
|
||||
pop cx
|
||||
pop ax
|
||||
|
||||
jmp dword ptr cs:[OldInt09h] ;salta all'int 09h originale
|
||||
|
||||
|
||||
;--------------------------------------
|
||||
|
||||
SetCmd:
|
||||
;Questa procedura manda un comando al microcontroller della tastiera
|
||||
;INPUT AL:comando da mandare
|
||||
push cx
|
||||
cli
|
||||
xor cx,cx
|
||||
|
||||
push ax
|
||||
|
||||
SetCmd_Wait4Empty:
|
||||
in al,64h
|
||||
test al,10b
|
||||
loopnz SetCmd_Wait4Empty
|
||||
|
||||
pop ax
|
||||
out 64h,al
|
||||
|
||||
sti
|
||||
pop cx
|
||||
ret
|
||||
|
||||
;---------------------------------------------------------------------------------
|
||||
|
||||
;preleva lo stato dei tasti modificatori
|
||||
;NON TESTATO!!
|
||||
|
||||
GetStatus:
|
||||
|
||||
push ds
|
||||
mov ax, 40h
|
||||
mov ds, ax
|
||||
mov al, byte ptr ds:[KbdFlags1] ;mette in al lo stato dei tasti modificatori
|
||||
pop ds
|
||||
|
||||
ret
|
||||
|
||||
;----------------------------------------------
|
||||
|
||||
;setta il rapporto di autoripetizione
|
||||
;bh=0, 1, 2, or 3 (delay in 1/4 sec before autorepeat starts)
|
||||
;and bl=0..1Fh (repeat rate, about 2:1 to 30:1 (chars:sec).
|
||||
|
||||
;BH=0 --> 250 ms
|
||||
;BH=1 --> 500 ms
|
||||
;BH=2 --> 750 ms
|
||||
;Bh=3 --> 1 second
|
||||
|
||||
;BL=0 --> 30 rpts/sec
|
||||
;BL=1 --> 26 rpts/sec
|
||||
;...
|
||||
;BL=1fh --> 2 rpts /sec
|
||||
|
||||
SetAutoRpt:
|
||||
|
||||
push ax
|
||||
push cx
|
||||
push bx
|
||||
|
||||
mov al, 0ADh ;Disable kbd for now.
|
||||
call SetCmd
|
||||
and bh, 11b ;Force into proper range.
|
||||
mov cl, 5
|
||||
shl bh, cl ;Move to final position.
|
||||
and bl, 1Fh ;Force into proper range.
|
||||
or bh, bl ;8042 command data byte.
|
||||
mov al, 0F3h ;8042 set repeat rate cmd.
|
||||
call SendCmd ;Send the command to 8042.
|
||||
mov al, bh ;Get parameter byte
|
||||
call SendCmd ;Send parameter to the 8042.
|
||||
mov al, 0AEh ;Reenable keyboard.
|
||||
call SetCmd
|
||||
mov al, 0F4h ;Restart kbd scanning.
|
||||
call SendCmd
|
||||
|
||||
pop bx
|
||||
pop cx
|
||||
pop ax
|
||||
|
||||
ret
|
||||
|
||||
;----------------------------------------------
|
||||
|
||||
|
||||
; memorizza il carattere in CX nel buffer
|
||||
; CH=scan-code CL=ascii-code
|
||||
|
||||
;NON TESTATO!
|
||||
|
||||
StoreKey:
|
||||
|
||||
push ds
|
||||
push bx
|
||||
mov ax, 40h
|
||||
mov ds, ax
|
||||
cli ;regione critica
|
||||
mov bx, word ptr ds:[TailPtr] ;indirizzo di memorizzazione tasto
|
||||
push bx ;salva l'inidirizzo nello stack
|
||||
mov [bx], cx ;memorizza
|
||||
inc word PTR ds:[TailPtr] ;incrementa il puntatore di coda
|
||||
cmp bx, word ptr ds:[HeadPtr] ;sono stati sovrascritti dati?
|
||||
jne StoreOkay ;se non salta, se si continua
|
||||
pop word ptr cs:[TailPtr] ;riprende il vecchio indirizzo e ignora
|
||||
sub sp, 2 ;sistema lo stack
|
||||
StoreOkay:
|
||||
add sp, 2 ;rimuove dati dallo stack
|
||||
pop bx
|
||||
pop ds
|
||||
|
||||
ret
|
||||
|
||||
;-------------------------------------------------
|
||||
|
||||
; Spedisce un comando o un dato alla
|
||||
; keyboard data port (port 60h).
|
||||
|
||||
SendCmd:
|
||||
push ds
|
||||
push bx
|
||||
push cx
|
||||
mov cx, 40h
|
||||
mov ds, cx
|
||||
mov bx, ax ;Salva il dato
|
||||
mov bh, 3
|
||||
RetryLp:
|
||||
cli
|
||||
|
||||
; cancella il flag del registro KbdFlags4
|
||||
; flags: Cancella errori , riconoscimento accettato, rispedisci flags
|
||||
|
||||
and byte ptr ds:[KbdFlags4], 4fh
|
||||
|
||||
;aspetta finche' l'8042 processa il comando corrente
|
||||
|
||||
xor cx, cx
|
||||
|
||||
SendCmd_Wait4Empty:
|
||||
in al, 64h ;legge lo stato del registro
|
||||
test al, 10b ;Input buffer pieno?
|
||||
loopnz SendCmd_Wait4Empty ;aspetta finche' e' vuoto
|
||||
|
||||
|
||||
; Ok spedisci i dato alla porta 60h
|
||||
|
||||
mov al, bl
|
||||
out 60h, al
|
||||
sti
|
||||
|
||||
; Wait for the arrival of an acknowledgement from the keyboard ISR:
|
||||
|
||||
xor cx, cx
|
||||
Wait4Ack:
|
||||
test byte ptr ds:[KbdFlags4], 10 ;Acknowledge received bit.
|
||||
jnz GotAck
|
||||
loop Wait4Ack
|
||||
|
||||
dec bh
|
||||
jne RetryLp
|
||||
|
||||
; If the operation failed after 3 retries, set the error bit and quit.
|
||||
|
||||
or byte ptr ds:[KbdFlags4], 80h ;Set error bit.
|
||||
|
||||
GotAck:
|
||||
pop cx
|
||||
pop bx
|
||||
pop ds
|
||||
ret
|
||||
|
||||
;--------------------------------------
|
||||
|
||||
; variabili BIOS
|
||||
|
||||
KbdFlags1 equ 17h ; variabile che contiene lo stato dei tasti modificatori
|
||||
KbdFlags2 equ 18h ; altra variabile " " " " " "
|
||||
AltKpd equ 19h
|
||||
HeadPtr equ 1ah ; puntatore alla testa del buffer
|
||||
TailPtr equ 1ch ; puntatore alla coda del buffer
|
||||
Buffer equ 1eh ; buffer
|
||||
EndBuf equ 3eh
|
||||
KbdFlags3 equ 96h ; miscellaneos keyboard flags
|
||||
KbdFlags4 equ 97h ; " " " "
|
||||
|
||||
;variabili driver
|
||||
|
||||
OldInt09h dd ?
|
||||
Loading…
Add table
Add a link
Reference in a new issue