home *** CD-ROM | disk | FTP | other *** search
/ PC Open 15 / PCOPEN15.ISO / MsDos / Keybit6 / SOURCE.ZIP / KEYBIT.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-02-22  |  11.8 KB  |  462 lines

  1. ;************************************************************************
  2. ;*                                    *
  3. ;*  KEYBIT Lite   Driver for Italian keyboards.                *
  4. ;*  Copyright 1994-1996 Pino Navato                    *
  5. ;*                                    *
  6. ;*  You can freely use and distribute this program.            *
  7. ;*  It's cardware: if you find it useful, send me a postcard.        *
  8. ;*                                    *
  9. ;*  This source code can be easily modified to work with other        *
  10. ;*  national keyboards.  You are allowed to make changes for this    *
  11. ;*  purpose and to redistribute the resulting program provided that:    *
  12. ;*  1) you distribute it as freeware or cardware along with its        *
  13. ;*     source code,                            *
  14. ;*  2) you fairly acknowledge my work both at the beginning of the new    *
  15. ;*     source code and in the program's documentation.            *
  16. ;*                                    *
  17. ;*                                    *
  18. ;*  My Fidonet address is 2:335/225.18 (The Bits BBS)            *
  19. ;*                                    *
  20. ;*  Send your postcard to:                        *
  21. ;*                                    *
  22. ;*    Pino Navato                            *
  23. ;*    Via Pittore, 164                        *
  24. ;*    80046 S.Giorgio a Cremano (NA)                    *
  25. ;*    ITALY                                *
  26. ;*                                    *
  27. ;************************************************************************
  28.  
  29.  
  30. .286                    ;Usa codice 286.
  31.  
  32. __TINY__    =    1        ;Usa il modello TINY.
  33.  
  34. KBD_MODEL    =    1        ;Definisce il tipo di tastiera che
  35.                     ;dovrà essere gestita da KEYBIT Lite.
  36.                     ;Valori ammessi:
  37.                     ;  1 = tastiera modello 141
  38.                     ;  2 = tastiera modello 142 standard
  39.                     ;  3 = tastiera modello 142 con il
  40.                     ;      car. "." sul tastierino numerico
  41.  
  42.  
  43.         INCLUDE    AMIS.MAC    ;Include la libreria di Ralf.
  44.  
  45.         @Startup        ;Macro che fornisce codice di startup.
  46.  
  47.  
  48. VERSION_NUM    =    0600h        ;Versione 6
  49. VERSION_STR    equ    "6"
  50.  
  51. CAPS_LOCK    =    64
  52. NUM_LOCK    =    32
  53. ALT        =    8 shl 4
  54. CTRL        =    4 shl 4
  55. SHIFT        =    3 shl 4        ;Shift sinistro + Shift destro.
  56. PAUSE        =    8
  57. LEFT_ALT    =    2
  58. E0_FLAG     =    2
  59. F1        =    3Bh
  60. F2        =    3Ch
  61. F12        =    58h
  62.  
  63.  
  64. bios_data_seg    segment at 40h
  65.  
  66.         org    17h
  67. shift_status    db    ?        ;Stato di Alt, Ctrl e Shift.
  68. extended_sh_st    db    ?        ;Stato di Ins, Pause e Left_Alt.
  69. dummy1        db    ?
  70. dummy2        dw    ?
  71. first_free_slot    dw    ?        ;Primo posto libero nel buffer.
  72.  
  73.         org    96h
  74. kb_status    db    ?        ;Stato del codice E0.
  75.  
  76. bios_data_seg    ends
  77.  
  78.  
  79. ;------------------------- Inizio del codice residente -------------------------
  80.  
  81. TSRcode@
  82.  
  83.         HOOKED_INTS  09h
  84.         ALTMPX         'Pino Nav','Keybit',VERSION_NUM,,,Y
  85.         ISP_HEADER   09h,hw_reset_2Dh
  86.  
  87.  
  88. ;-------------- Legge i flag di tastiera e il codice di scansione --------------
  89.  
  90. entry_point:    pusha
  91.         push    ds es
  92.  
  93.         push    bios_data_seg
  94.         pop    ds
  95.         assume    ds:bios_data_seg
  96.  
  97.         push    cs
  98.         pop    es
  99.         assume    es:TGROUP
  100.         
  101.         mov    bx,word ptr shift_status  ;bl=sh_status, bh=ext_sh_st.
  102.         shl    bl,4            ;Scarta i bit inutili.
  103.  
  104.         test    bh,PAUSE        ;Se è in pausa, ignora.
  105.         jnz    ignore_key
  106.         test    kb_status,E0_FLAG    ;Se è un tasto esteso, ignora.
  107.         jnz    ignore_key
  108.  
  109.         in    al,60h            ;Legge scan code.
  110.  
  111. ;        mov    ah,4Fh
  112. ;        stc
  113. ;        int    15h
  114. ;        jnc    signal_EOI
  115.  
  116.  
  117. ;------------------- Controlla e gestisce Ctrl+Alt+F1/F2/F12 -------------------
  118.  
  119. flags_mngment:    mov    dl,flags    ;Per ridurre i riferim. alla memoria.
  120.         cmp    bl,CTRL+ALT    ;E' Ctrl+Alt?
  121.         jne    check_active
  122.  
  123.         cmp    al,F1        ;E' stato premuto F1?
  124.         jne    cmp_f2
  125.         and    dl,not ACTIVE    ;Disabilita KEYBIT Lite.
  126.         jmp short end_fm
  127.  
  128. cmp_f2:     cmp    al,F2        ;E' stato premuto F2?
  129.         jne    cmp_f12
  130.         or    dl,ACTIVE    ;Abilita KEYBIT Lite.
  131.         jmp short end_fm
  132.  
  133. cmp_f12:    cmp    al,F12        ;E' stato premuto F12?
  134.         jne    ignore_key
  135.         xor    dl,vocal_flag    ;Inverte lo stato del bit 1.
  136.  
  137. end_fm:     mov    flags,dl    ;End of flags management.
  138.  
  139. signal_EOI:    mov    al,20h        ;Segnala End Of Interrupt...
  140.         out    20h,al        ;...all'interrupt controller.
  141.         jmp short exit
  142.  
  143.  
  144. ;----------- Affida la gestione del tasto alla vecchia ISR del BIOS ------------
  145.  
  146. ignore_key:    pop    es ds
  147.         popa
  148.         jmp    cs:ORIG_INT09h
  149.  
  150.  
  151. ;---------------------- Verifica se KEYBIT Lite è attivo -----------------------
  152.  
  153. check_active:    or    dl,dl        ;Se KEYBIT Lite è disabilitato...
  154.         jns    ignore_key    ;...non effettua alcuna conversione.
  155.  
  156.  
  157. ;--------------------- Gestione dei tasti Caps Lock e Ins ----------------------
  158.  
  159. patch_here    db    90h, 90h, 90h        ;Può diventare call auto_caps
  160. ins_mngment:    and    extended_sh_st,127    ;Ora può ripetere il tasto Ins.
  161.  
  162.  
  163. ;--------------------------- Chiama la ISR del BIOS ----------------------------
  164.  
  165.         mov    si,[first_free_slot]
  166.         pushf
  167.         call    ORIG_INT09h
  168.  
  169.  
  170. ;-------------------- Controlla se è un tasto da convertire --------------------
  171.  
  172. IF KBD_MODEL EQ 2
  173.         cmp    al,53h        ;E' il "." del tastierino?
  174.         je    keypad
  175. ENDIF
  176.  
  177.         mov    cx,TOT_CODES
  178.         mov    di,offset TGROUP:scan_codes
  179.         cld
  180.         repne    scasb     ;Confr. AL con ES:[DI] con postincrem. di DI.
  181.         jne    exit
  182.  
  183.  
  184. ;--------------------------- Filtra vocali accentate ---------------------------
  185.  
  186.         test    dl,vocal_flag    ;Deve convertire le vocali?
  187.         jz    found_key    ;Se no, usa la routine normale.
  188.         cmp    cx,5      ;Le vocali sono gli ultimi 5 car. in tabella.
  189.         jae    found_key
  190.         mov    dl,"`"        ;Si predispone ad usare " ` "
  191.         or    bl,bl        ;Tasto semplice?
  192.         jz    trap_vocal
  193.         test    bl,SHIFT    ;Shift+tasto?
  194.         jz    found_key
  195.         cmp    al,1Ah        ;1Ah = é
  196.         jne    found_key
  197.         mov    dl,"'"        ;Per la "é" usa " ' "
  198.  
  199.  
  200. ;------------- Conversione vocali accentate in vocali apostrofate --------------
  201.  
  202. trap_vocal:    mov    di,offset TGROUP:vocal_codes
  203.         add    di,cx
  204.         call    store_key
  205.         mov    cl,dl        ;dl contiene l'apostrofo opportuno.
  206.         call    store_key_4
  207.  
  208.  
  209. ;---------------- Ripristina i registri dallo stack e termina ------------------
  210.  
  211. exit:        pop    es ds
  212.         popa
  213.         iret
  214.         
  215.  
  216. ;--------- Gestisce il tastierino numerico (solo modello 142 standard) ---------
  217.  
  218. IF KBD_MODEL EQ 2
  219. keypad:     test    shift_status,NUM_LOCK    ;Num Lock attivo?
  220.         jnz    num_lock_on
  221. num_lock_off:    test    bl,SHIFT        ;Shift+tasto?
  222.         jz    exit
  223.         jnz    trap_keypad
  224. num_lock_on:    or    bl,bl            ;Tasto semplice?
  225.         jnz    exit
  226. trap_keypad:    mov    cl,","
  227.         call    store_key_2
  228.         jmp    exit
  229. ENDIF
  230.  
  231.  
  232. ;----------- Calcola il codice ASCII corrispondente al tasto premuto -----------
  233.  
  234. found_key:    mov    cl,TOT_CODES    ;Equiv. a mov cx,TOT_CODES perché ch=0
  235.         add    di,TOT_CODES-1    ;Ora DI punta ai caratteri normali.
  236.         or    bl,bl        ;E' stato premuto il tasto semplice?
  237.         jz    trap_key    ;Se sì, salta.
  238.         add    di,cx        ;Ora DI punta ai caratteri shiftati.
  239.         test    bl,SHIFT    ;Shift+tasto?
  240.         jnz    trap_key    ;Se sì, salta.
  241.         add    di,cx        ;Ora DI punta ai car. con Alt sinistro.
  242.         test    bh,LEFT_ALT    ;Alt sinistro+tasto?
  243.         jnz    trap_key    ;Se sì, salta.
  244.         add    di,cx        ;Ora DI punta ai car. con Alt destro.
  245.         or    bl,bl        ;Alt (destro)+tasto?
  246.         js    trap_key    ;Se sì, salta.
  247.         add    di,cx        ;Ora DI punta ai caratteri con Ctrl.
  248.  
  249.  
  250. ;------------ Inserisce nel buffer il codice ASCII appena calcolato ------------
  251.  
  252. trap_key:    call    store_key
  253.         jmp    exit
  254.         
  255.  
  256. ;---------------------- Inserisce un carattere nel buffer ----------------------
  257.  
  258. ;--- input:   ES:[DI] = codice ASCII
  259. ;          AL      = codice di scansione
  260. ;          CH      = 0
  261. ;          DS:SI  -> slot del buffer in cui inserire il carattere
  262. ;--- return:  AH e CX alterati
  263.  
  264. store_key:    mov    cl,es:[di]
  265.         jcxz    store_done    ;Salta se il carattere è indefinito.
  266.         cmp    cl,''        ;Se il carattere è '', lascia...
  267.         je    store_key_3    ;...CH=0 per non confonderlo con ^U.
  268. store_key_2:    mov    ch,al
  269. store_key_3:    mov    [first_free_slot],si
  270. store_key_4:    mov    ah,5
  271.         int    16h
  272. store_done:    ret
  273.  
  274.  
  275. ;----------------------------- Area dati residenti -----------------------------
  276.  
  277. ACTIVE        =    128        ;Per settare/resett. il bit 7 di flags.
  278. VOCAL_FLAG    =    64        ;Per settare/resett. il bit 6 di flags.
  279. flags        db    ACTIVE
  280.  
  281. vocal_codes    db    "uoiea"
  282.  
  283. IF KBD_MODEL EQ 1
  284. scan_codes    db    29h,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,1Bh  ;Tasti
  285.         db    56h,33h,34h,35h,28h,1Ah,0Dh,27h,2Bh  ;da intercettare.
  286. TOT_CODES    =    $-scan_codes
  287.         db    "\1234567890'+<,.-àèìòù"        ;Normale.
  288.         db    '|!"£$%&/()=?*>;:_°é^ç'        ;Shift.
  289.         db    "│",0,0,0,0,0,0,0,0,0,0,"`}≤└┘─┐{~┌~"    ;Alt sinistro.
  290.         db    "║",0,0,0,0,0,0,0,0,0,0,"`]≥«»═#[~@~"    ;Alt destro.
  291.         db    1Ch,0,0,0,0,0,0,0,0,0,0         ;Ctrl.
  292.         db    "`",0,"±╚╝",1Fh,"╗",0,"~╔~"        ;Ctrl.
  293.  
  294. ELSE
  295.  
  296. scan_codes    db    10h,29h,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,1Bh  ;Tasti
  297.         db    56h,33h,34h,35h,28h,1Ah,0Dh,27h,2Bh  ;da intercettare.
  298. TOT_CODES    =    $-scan_codes
  299.         db    0,"\1234567890'+<,.-àèìòù"        ;Normale.
  300.         db    0,'|!"£$%&/()=?*>;:_°é^ç'        ;Shift.
  301.         db    0,"│",0,0,0,0,0,0,0,0,0,0        ;Alt sinistro.
  302.         db    0,0,"≤└┘─┐",0,0,"┌",0            ;Alt sinistro.
  303.         db    "@║",0,0,"#",0,0,0,"{[]}"        ;Alt destro.
  304.         db    0,"~≥«»═",0,0,0, 0,"`"            ;Alt destro.
  305.         db    0,1Ch,0,0,0,0,0,0,0,0,0,0        ;Ctrl.
  306.         db    0,0,"±╚╝",1Fh,"╗",0,0,"╔",0        ;Ctrl.
  307. ENDIF
  308.  
  309.  
  310. ;--------------- Codice residente opzionale (gestione Caps Lock) ---------------
  311.  
  312. auto_caps:    test    bl,SHIFT
  313.         jz    auto_caps_done
  314.         cmp    al,10h
  315.         jb    auto_caps_done
  316.         cmp    al,19h
  317.         jbe    disable_caps
  318.         cmp    al,1Eh
  319.         jb    auto_caps_done
  320.         cmp    al,26h
  321.         jbe    disable_caps
  322.         cmp    al,2Ch
  323.         jb    auto_caps_done
  324.         cmp    al,32h
  325.         ja    auto_caps_done
  326.  
  327. disable_caps:    and    shift_status,not CAPS_LOCK
  328. auto_caps_done:    ret
  329.  
  330. OPT_CODE_LEN    =    $-auto_caps        ;Lungh. del codice opzionale.
  331.  
  332.  
  333. TSRcodeEnd@
  334.  
  335. ;-------------------------- Fine del codice residente --------------------------
  336. ;-------------------------------------------------------------------------------
  337.  
  338.  
  339. ;-------------------------------------------------------------------------------
  340. ;-------------------------- Procedura d'installazione --------------------------
  341.  
  342. _TEXT        segment 'CODE'
  343.         assume    cs:_TEXT,ds:NOTHING,es:NOTHING,ss:NOTHING
  344.  
  345.         @Startup2  Y
  346.         
  347.         push    ds
  348.         pop    es
  349.         assume    es:_INIT
  350.  
  351.         push    cs
  352.         pop    ds
  353.         assume    ds:_TEXT
  354.  
  355.         mov    bx,1000h
  356.         mov    ah,4Ah
  357.         int    21h
  358.  
  359.  
  360. ;-------------------------- Gestione riga di comando ---------------------------
  361.  
  362.         mov    si,81h            ;SI -> command line.
  363.         cld
  364. cmdline_loop:    db    26h,0ACh        ;lodsb es:
  365.         cmp    al,' '            ;Scarta spazi e TABs.
  366.         je    cmdline_loop
  367.         cmp    al,9
  368.         je    cmdline_loop
  369.         cmp    al,13            ;Nessun altro parametro?
  370.         je    install
  371.         cmp    al,'/'            ;C'è uno slash?
  372.         jne    analyse_param
  373.         db    26h,0ACh        ;Scarta lo slash (lodsb es:).
  374. analyse_param:    and    al,0DFh         ;Converte in maiuscola.
  375.         cmp    al,'A'            ;AutoCaps?
  376.            jne    cmp_with_L
  377.            add    tsr_len,OPT_CODE_LEN    ;Installa tutto.
  378.         push    ds
  379.         mov    ds,TGROUP@
  380.         assume    ds:TGROUP
  381.         mov    patch_here,0E8h                     ;Patch.
  382.            mov    word ptr patch_here+1,auto_caps-ins_mngment  ;Patch.
  383.         pop    ds
  384.         assume    ds:_TEXT
  385.            jmp    cmdline_loop
  386. cmp_with_L:    cmp    al,'L'
  387.         jne    cmp_with_N
  388.         mov    inst_mode,LOW_ONLY    ;Installazione tradizionale.
  389.            jmp    cmdline_loop
  390. cmp_with_N:    cmp    al,'N'
  391.         jne    cmp_with_R
  392.         db    26h,0ACh        ;lodsb es:
  393.         and    al,0DFh            ;Converte in maiuscola.
  394.         cmp    al,'T'
  395.         jne    unknown_param
  396.         mov    inst_mode,NO_TOPMEM    ;Installazione "No Top".
  397.         jmp    cmdline_loop
  398. cmp_with_R:    cmp    al,'R'
  399.         je    remove
  400.         cmp    al,'U'            ;Accetta anche U ("Uninstall").
  401.         je    remove
  402.         jmp    unknown_param
  403.  
  404.  
  405. ;-------------------------- Installa/disintalla ecc. ---------------------------
  406.  
  407. install:    INSTALL_TSR tsr_len,,BEST,,inst_notify,already_installed,,inst_mode
  408.  
  409. inst_notify:    DISPLAY_STRING banner_msg
  410.         ret
  411.  
  412. already_installed:
  413.         mov    dx,offset already_inst_msg
  414.         jmp short exit_with_error
  415.  
  416. unknown_param:    mov    dx,offset unknown_param_msg
  417.         jmp short exit_with_error
  418.  
  419. remove:     UNINSTALL cant_uninstall
  420.         push    cs
  421.         pop    ds
  422.         DISPLAY_STRING uninstalled_msg
  423.         mov    ax,4C00h
  424.         int    21h
  425.  
  426. cant_uninstall: mov    dx,offset cant_remove_msg
  427.  
  428. exit_with_error:
  429.         mov    ah,9
  430.         int    21h
  431.         mov    ax,4C01h
  432.         int    21h
  433.  
  434.  
  435. ;-------------------------- Dati per l'installazione ---------------------------
  436.  
  437. inst_mode    db    USE_TOPMEM    ;Modo d'installazione di default.
  438. tsr_len        dw    offset TGROUP:$AMIS$end_TSRcode - OPT_CODE_LEN
  439.  
  440.  
  441. ;-------------------------- Messaggi da visualizzare ---------------------------
  442.  
  443. banner_msg    db    13,10, 'KEYBIT Lite v.', VERSION_STR, '  di Pino Navato'
  444.         db    13,10, '$'
  445.  
  446. already_inst_msg db    13,10, 'KEYBIT Lite già installato.'
  447.          db    13,10, '$'
  448.  
  449. unknown_param_msg db    13,10, 'Parametro sconosciuto.'
  450.           db    13,10, '$'
  451.  
  452. uninstalled_msg db    13,10, 'KEYBIT Lite rimosso dalla memoria.'
  453.         db    13,10, '$'
  454.  
  455. cant_remove_msg db    13,10, 'Impossibile rimuovere KEYBIT Lite.'
  456.         db    13,10, '$'
  457.  
  458.  
  459. _TEXT        ENDS
  460.  
  461.         end    INIT
  462.