;************************************************************************ ;* * ;* KEYBIT Lite Driver for Italian keyboards. * ;* Copyright 1994-1999 Pino Navato * ;* * ;* You can freely use and distribute this program. * ;* It's cardware: if you find it useful, send me a postcard. * ;* * ;* This source code can be easily modified to work with other * ;* national keyboards. You are allowed to make changes for this * ;* purpose and to redistribute the resulting program provided that: * ;* 1) you distribute it as freeware or cardware along with its * ;* source code, * ;* 2) you fairly acknowledge my work both at the beginning of the new * ;* source code and in the program's documentation. * ;* * ;* * ;* My Internet addresses are: * ;* * ;* WWW: http://www.poboxes.com/pnavato/ * ;* http://www.geocities.com/SiliconValley/4421/ * ;* E-mail: pnavato@poboxes.com * ;* pnavato@geocities.com * ;* * ;* * ;* Send your postcard to: * ;* * ;* Pino Navato * ;* Via Pittore, 164 * ;* 80046 S.Giorgio a Cremano (NA) * ;* ITALY * ;* * ;************************************************************************ .286 ;Usa codice 286. __TINY__ = 1 ;Usa il modello TINY. KBD_MODEL = 1 ;Definisce il tipo di tastiera che ;dovr essere gestita da KEYBIT Lite. ;Valori ammessi: ; 1 = tastiera modello 141 ; 2 = tastiera modello 142 standard ; 3 = tastiera modello 142 con il ; car. "." sul tastierino numerico INCLUDE AMIS.MAC ;Include la libreria di Ralf. @Startup ;Macro che fornisce codice di startup. VERSION_NUM = 0700h ;Versione 7 VERSION_STR equ "7" CAPS_LOCK = 64 NUM_LOCK = 32 ALT = 8 shl 4 CTRL = 4 shl 4 SHIFT = 3 shl 4 ;Shift sinistro + Shift destro. PAUSE = 8 LEFT_ALT = 2 E0_FLAG = 2 F1 = 3Bh F2 = 3Ch F12 = 58h bios_data_seg segment at 40h org 17h shift_status db ? ;Stato di Alt, Ctrl e Shift. extended_sh_st db ? ;Stato di Ins, Pause e Left_Alt. dummy1 db ? dummy2 dw ? first_free_slot dw ? ;Primo posto libero nel buffer. org 96h kb_status db ? ;Stato del codice E0. bios_data_seg ends ;------------------------- Inizio del codice residente ------------------------- TSRcode@ HOOKED_INTS 09h ALTMPX 'Pino Nav','Keybit',VERSION_NUM,,,Y ISP_HEADER 09h,hw_reset_2Dh ;-------------- Legge i flag di tastiera e il codice di scansione -------------- entry_point: pusha push ds es push bios_data_seg pop ds assume ds:bios_data_seg push cs pop es assume es:TGROUP mov bx,word ptr shift_status ;bl=sh_status, bh=ext_sh_st. shl bl,4 ;Scarta i bit inutili. test bh,PAUSE ;Se in pausa, ignora. jnz ignore_key test kb_status,E0_FLAG ;Se un tasto esteso, ignora. jnz ignore_key in al,60h ;Legge scan code. ; mov ah,4Fh ; stc ; int 15h ; jnc signal_EOI ;------------------- Controlla e gestisce Ctrl+Alt+F1/F2/F12 ------------------- flags_mngment: mov dl,flags ;Per ridurre i riferim. alla memoria. cmp bl,CTRL+ALT ;E' Ctrl+Alt? jne check_active cmp al,F1 ;E' stato premuto F1? jne cmp_f2 and dl,not ACTIVE ;Disabilita KEYBIT Lite. jmp short end_fm cmp_f2: cmp al,F2 ;E' stato premuto F2? jne cmp_f12 or dl,ACTIVE ;Abilita KEYBIT Lite. jmp short end_fm cmp_f12: cmp al,F12 ;E' stato premuto F12? jne ignore_key xor dl,vocal_flag ;Inverte lo stato del bit 1. end_fm: mov flags,dl ;End of flags management. signal_EOI: mov al,20h ;Segnala End Of Interrupt... out 20h,al ;...all'interrupt controller. jmp short exit ;----------- Affida la gestione del tasto alla vecchia ISR del BIOS ------------ ignore_key: pop es ds popa jmp cs:ORIG_INT09h ;---------------------- Verifica se KEYBIT Lite attivo ----------------------- check_active: or dl,dl ;Se KEYBIT Lite disabilitato... jns ignore_key ;...non effettua alcuna conversione. ;--------------------- Gestione dei tasti Caps Lock e Ins ---------------------- patch_here db 90h, 90h, 90h ;Pu diventare call auto_caps ins_mngment: and extended_sh_st,127 ;Ora pu ripetere il tasto Ins. ;--------------------------- Chiama la ISR del BIOS ---------------------------- mov si,[first_free_slot] pushf call ORIG_INT09h ;-------------------- Controlla se un tasto da convertire -------------------- IF KBD_MODEL EQ 2 cmp al,53h ;E' il "." del tastierino? je keypad ENDIF mov cx,TOT_CODES mov di,offset TGROUP:scan_codes cld repne scasb ;Confr. AL con ES:[DI] con postincrem. di DI. jne exit ;--------------------------- Filtra vocali accentate --------------------------- test dl,vocal_flag ;Deve convertire le vocali? jz found_key ;Se no, usa la routine normale. cmp cx,5 ;Le vocali sono gli ultimi 5 car. in tabella. jae found_key mov dl,"`" ;Si predispone ad usare " ` " or bl,bl ;Tasto semplice? jz trap_vocal test bl,SHIFT ;Shift+tasto? jz found_key cmp al,1Ah ;1Ah = jne found_key mov dl,"'" ;Per la "" usa " ' " ;------------- Conversione vocali accentate in vocali apostrofate -------------- trap_vocal: mov di,offset TGROUP:vocal_codes add di,cx call store_key mov cl,dl ;dl contiene l'apostrofo opportuno. call store_key_4 ;---------------- Ripristina i registri dallo stack e termina ------------------ exit: pop es ds popa iret ;--------- Gestisce il tastierino numerico (solo modello 142 standard) --------- IF KBD_MODEL EQ 2 keypad: test shift_status,NUM_LOCK ;Num Lock attivo? jnz num_lock_on num_lock_off: test bl,SHIFT ;Shift+tasto? jz exit jnz trap_keypad num_lock_on: or bl,bl ;Tasto semplice? jnz exit trap_keypad: mov cl,"," call store_key_2 jmp exit ENDIF ;----------- Calcola il codice ASCII corrispondente al tasto premuto ----------- found_key: mov cl,TOT_CODES ;Equiv. a mov cx,TOT_CODES perch ch=0 add di,TOT_CODES-1 ;Ora DI punta ai caratteri normali. or bl,bl ;E' stato premuto il tasto semplice? jz trap_key ;Se s, salta. add di,cx ;Ora DI punta ai caratteri shiftati. test bl,SHIFT ;Shift+tasto? jnz trap_key ;Se s, salta. add di,cx ;Ora DI punta ai car. con Alt sinistro. test bh,LEFT_ALT ;Alt sinistro+tasto? jnz trap_key ;Se s, salta. add di,cx ;Ora DI punta ai car. con Alt destro. or bl,bl ;Alt (destro)+tasto? js trap_key ;Se s, salta. add di,cx ;Ora DI punta ai caratteri con Ctrl. ;------------ Inserisce nel buffer il codice ASCII appena calcolato ------------ trap_key: call store_key jmp exit ;---------------------- Inserisce un carattere nel buffer ---------------------- ;--- input: ES:[DI] = codice ASCII ; AL = codice di scansione ; CH = 0 ; DS:SI -> slot del buffer in cui inserire il carattere ;--- return: AH e CX alterati store_key: mov cl,es:[di] jcxz store_done ;Salta se il carattere indefinito. cmp cl,'' ;Se il carattere '', lascia... je store_key_3 ;...CH=0 per non confonderlo con ^U. store_key_2: mov ch,al store_key_3: mov [first_free_slot],si store_key_4: mov ah,5 int 16h store_done: ret ;----------------------------- Area dati residenti ----------------------------- ACTIVE = 128 ;Per settare/resett. il bit 7 di flags. VOCAL_FLAG = 64 ;Per settare/resett. il bit 6 di flags. flags db ACTIVE vocal_codes db "uoiea" IF KBD_MODEL EQ 1 scan_codes db 29h,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,1Bh ;Tasti db 56h,33h,34h,35h,28h,1Ah,0Dh,27h,2Bh ;da intercettare. TOT_CODES = $-scan_codes db "\1234567890'+<,.-" ;Normale. db '|!"$%&/()=?*>;:_^' ;Shift. db "",0,0,0,0,0,0,0,0,0,0,"`}Ŀ{~~" ;Alt sinistro. db "",0,0,0,0,0,0,0,0,0,0,"`]#[~@~" ;Alt destro. db 1Ch,0,0,0,0,0,0,0,0,0,0 ;Ctrl. db "`",0,"ȼ",1Fh,"",0,"~~" ;Ctrl. ELSE scan_codes db 10h,29h,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,1Bh ;Tasti db 56h,33h,34h,35h,28h,1Ah,0Dh,27h,2Bh ;da intercettare. TOT_CODES = $-scan_codes db 0,"\1234567890'+<,.-" ;Normale. db 0,'|!"$%&/()=?*>;:_^' ;Shift. db 0,"",0,0,0,0,0,0,0,0,0,0 ;Alt sinistro. db 0,0,"Ŀ",0,0,"",0 ;Alt sinistro. db "@",0,0,"#",0,0,0,"{[]}" ;Alt destro. db 0,"~",0,0,0, 0,"`" ;Alt destro. db 0,1Ch,0,0,0,0,0,0,0,0,0,0 ;Ctrl. db 0,0,"ȼ",1Fh,"",0,0,"",0 ;Ctrl. ENDIF ;--------------- Codice residente opzionale (gestione Caps Lock) --------------- auto_caps: test bl,SHIFT jz auto_caps_done cmp al,10h jb auto_caps_done cmp al,19h jbe disable_caps cmp al,1Eh jb auto_caps_done cmp al,26h jbe disable_caps cmp al,2Ch jb auto_caps_done cmp al,32h ja auto_caps_done disable_caps: and shift_status,not CAPS_LOCK auto_caps_done: ret OPT_CODE_LEN = $-auto_caps ;Lungh. del codice opzionale. TSRcodeEnd@ ;-------------------------- Fine del codice residente -------------------------- ;------------------------------------------------------------------------------- ;------------------------------------------------------------------------------- ;-------------------------- Procedura d'installazione -------------------------- _TEXT segment 'CODE' assume cs:_TEXT,ds:NOTHING,es:NOTHING,ss:NOTHING @Startup2 Y push ds pop es assume es:_INIT push cs pop ds assume ds:_TEXT mov bx,1000h mov ah,4Ah int 21h ;-------------------------- Gestione riga di comando --------------------------- mov si,81h ;SI -> command line. cld cmdline_loop: db 26h,0ACh ;lodsb es: cmp al,' ' ;Scarta spazi e TABs. je cmdline_loop cmp al,9 je cmdline_loop cmp al,13 ;Nessun altro parametro? je install cmp al,'/' ;C' uno slash? jne analyse_param db 26h,0ACh ;Scarta lo slash (lodsb es:). analyse_param: and al,0DFh ;Converte in maiuscola. cmp al,'A' ;AutoCaps? jne cmp_with_L add tsr_len,OPT_CODE_LEN ;Installa tutto. push ds mov ds,TGROUP@ assume ds:TGROUP mov patch_here,0E8h ;Patch. mov word ptr patch_here+1,auto_caps-ins_mngment ;Patch. pop ds assume ds:_TEXT jmp cmdline_loop cmp_with_L: cmp al,'L' jne cmp_with_N mov inst_mode,LOW_ONLY ;Installazione tradizionale. jmp cmdline_loop cmp_with_N: cmp al,'N' jne cmp_with_R db 26h,0ACh ;lodsb es: and al,0DFh ;Converte in maiuscola. cmp al,'T' jne unknown_param mov inst_mode,NO_TOPMEM ;Installazione "No Top". jmp cmdline_loop cmp_with_R: cmp al,'R' je remove cmp al,'U' ;Accetta anche U ("Uninstall"). je remove jmp unknown_param ;-------------------------- Installa/disintalla ecc. --------------------------- install: INSTALL_TSR tsr_len,,BEST,,inst_notify,already_installed,,inst_mode inst_notify: DISPLAY_STRING banner_msg ret already_installed: mov dx,offset already_inst_msg jmp short exit_with_error unknown_param: mov dx,offset unknown_param_msg jmp short exit_with_error remove: UNINSTALL cant_uninstall push cs pop ds DISPLAY_STRING uninstalled_msg mov ax,4C00h int 21h cant_uninstall: mov dx,offset cant_remove_msg exit_with_error: mov ah,9 int 21h mov ax,4C01h int 21h ;-------------------------- Dati per l'installazione --------------------------- inst_mode db USE_TOPMEM ;Modo d'installazione di default. tsr_len dw offset TGROUP:$AMIS$end_TSRcode - OPT_CODE_LEN ;-------------------------- Messaggi da visualizzare --------------------------- banner_msg db 13,10, 'KEYBIT Lite v.', VERSION_STR, ' di Pino Navato' db 13,10, '$' already_inst_msg db 13,10, 'KEYBIT Lite gi installato.' db 13,10, '$' unknown_param_msg db 13,10, 'Parametro sconosciuto.' db 13,10, '$' uninstalled_msg db 13,10, 'KEYBIT Lite rimosso dalla memoria.' db 13,10, '$' cant_remove_msg db 13,10, 'Impossibile rimuovere KEYBIT Lite.' db 13,10, '$' _TEXT ENDS end INIT