home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-01-26 | 42.4 KB | 1,507 lines |
- ; KEYBOARD.A86
- title 'Keyboard ISR'
- pagesize 60+11
- ;************************************************
- ;* *
- ;* KEYBOARD INTERRUPT HANDLER *
- ;* CDOS 6.0 XIOS *
- ;* DRI OS ENGR, JMB, GMS *
- ;* *
- ;************************************************
- ; Modifications:
- ; 6.x
- ; 6 JAN 89 -- throw away scan code if re-entering GMS
- ; 22 Nov 88 -- Allow enhanced DEL_SCAN through GERMAN etc GMS
- ; 2 Nov 88 -- reload load DS in save_buf, stack swap only once IJ
- ; 10 OCT 88 -- allow CRTL/ALT dead keys GMS
- ; 6 SEP 88 -- do not allow SWITCH on enhanced arrow keys GMS
- ; 22 JUN 88 -- Fix problem with FRENCH & GERMAN enhanced GMS
- ; 19 FEB 88 -- Bug fix for national enhanced keyboard on model 30 GMS
- ; 18 FEB 88 -- JMP to MP_RESET@ GMS
- ; 6.0
- ; 18 NOV 87 -- re-enable AST color card support GMS
- ; 12 NOV 87 -- ROS keyboard data areas mapped for PC terminals GMS
- ; 11 NOV 87 -- bug fix re ALT GR key on enhanced keyboards GMS
- ; 7 NOV 87 -- keyboard interrupt stack increased (ran out on DELL 286) JW
- ; 3 NOV 87 -- print screen not checked if CONTROL SHIFT GMS
- ; 3 NOV 87 -- throw away CTRL/NUMLOCK and PAUSE keys GMS
- ; 1 NOV 87 -- removed S_REAL BDOS call - we now hardware reset the 386 JW
- ; 30 OCT 87 -- CNTRL BREAK handled by XIOS not ROS GMS
- ; 17 SEP 87 -- fix for 84 german keyboard numpad keys GMS
- ; 7 SEP 87 -- code added for V386pc option GMS
- ; 8 JUN 87 -- disable MMU on Ctl/Alt/Del w/ hw EEMM driver JW
- ; 5.2
- ; 13 MAY 87 -- Some National Keyboard changes added GMS
- ; 2 APR 87 -- Less stack usage for calls to ROS keyboard int routine GMS
- ; 18 MAR 87 -- Add support for enhanced keyboards GMS
- ; Test Setup byte for disabling of CTRL\ALT\DEL.
- ; 28 JAN 87 -- CDOS 386 Ctrl/Alt/Del - system call to reset to real mode- GMS
- ; 5.1
- ; 9 JAN 87 -- Alt key in national check upto '=' key - GMS
- ; 12 DEC 86 -- Test if AT/compatible and disable keyboard - wyse AT bug - GMS
- ; 26 NOV 86 -- Nat keyboards return pc scan code for ALT keys in PCMODE - GMS
- ; 11 NOV 86 -- Bug fix for old ros kb/buffer on old COMPAQ machines - GMS
- ; 25 SEP 86 -- European keyboard support added - GMS
- ; 5 SEP 86 -- fix AT isr reentrancy on caps-lock, num-lock and scroll-lock
- ; 12 AUG 86 -- NSEOI to SEOI (thx RH,JF)
- ; 19 JUN 86 -- make wmenu comes up if CAPS-LOCK on
- ; 27 MAY 86 -- add cntl-break isr
- ; 9 MAY 86 -- if FULL screen key w/ no wmenu, handle
- ; 29 APR 86 -- don't read AT kbd status if we've been preambled
- ; 16 APR 86 -- set keyboard isr mx flag for timer isr
- ; 1 APR 86 -- fix SYS-REQ and cntl-NUMLOCK bug
- ; 8 NOV 85 -- add cntl-pad-5 to toggle AST enhancment
- ; 7 JUN 85 -- update 4.1 ASM86 XIOS to 5.0 RASM86
- ; 23 OCT 85 -- rewrite to use ROS
-
- ; include COPYRITE.TXT
-
- nolist
- include CDOS.EQU
- include XIOS.EQU
- include PCHW.EQU
- include ROSDATA.EQU
- include ASCII.EQU
- include NAT.EQU
- list
- ; These have been included:
- ; include CDOS.EQU
- ; include XIOS.EQU
- ; include PCHW.EQU
- ; include ROSDATA.EQU
- ; include ASCII.EQU
- ; include NAT.EQU
-
-
-
- CGROUP group CODE
- DGROUP group DATA
-
- DATA dseg
- public switch_key$, wmenu_key$, prtsc_key$, key_flag$ ; for CONIN.A86
- public switch_bits$ ; for PUBDATA.A86
- public keyboard_isr$ ; for INIT.A86
- public kbd_imhere$ ; for INIT.A86
- public cntl_break$ ; for CONIN.A86
- if V386
- public save_kbdata$ ; for PCTERM.A86
- extrn active_vc$:byte
- endif
- extrn colsel_640$:word, ast_enhanced$:word ; in WINDOWS1.A86
- extrn ast_flag$:byte
- extrn top_screen$:byte, im_here$:byte ; in WINDOWS3.A86
- extrn pc_at$:byte
- extrn beep_counter$:byte ; in ISRS.A86
- extrn su_kbd_bits$:byte ; in HEADER.A86
-
- ; in NATDATA.A86
- extrn NX_tmp_us_flg$ :byte, NX_mode_table$ :byte
- extrn NX_ascii$ :word, NX_shift$ :word
- extrn NX_ctrl$ :word
- extrn NX_language$ :byte, NX_kbd_type$ :byte
- extrn NX_natnlmode$ :byte, NX_natnlstat$ :byte
- extrn NX_dead_key$ :byte, NX_ncasetbl$ :byte
- extrn NX_n7to8tbl$ :byte, NX_n7to8chr$ :byte
- extrn NX_deadtable$: word, NX_alt_table$ :byte, NX_dead_ascii$: word
- extrn NX_alt_chars$: byte
- extrn NX_dkeyv$ :word, NX_dkeyx$ :word
- extrn NX_last_dkey$ :word, NX_dkey_buff$ :byte
- extrn key_table$ :word, shift_table$ :word, control_table$ :word
- extrn NX_nasciitable$ :word, NX_nshifttable$ :word, NX_nctrltable$ :word
- extrn NX_ctrlalt$ :word, NX_ctrlalt_shft$ :word
-
-
-
- cseg
- public i_keyboard@ ; for INIT.A86
- public keyboard_isr$
- public NX_init@
- public NX_scanstr@ ; for LISTNAT.A86
- public NX_conout_xlat@ ; for WINDOWS1.A86
-
- extrn flagset@:near ; in HEADER.A86
- extrn sysdat$:word
- extrn disp_addr$ :dword
- extrn ros_color@:near ; in WINDOWS1.A86
- extrn point_vs@:near ; in WINDOWS3.A86
- extrn io_list_normal@:near ;
- extrn reset@:near ; in ISRS.A86
- if XM
- extrn mp_reset@:near ; in EMM.A86
- endif
- if V386
- extrn get_kbd_flags@:near ; in PCTERM.A86
- endif
- eject
-
- ;-----------
- i_keyboard@:
- ;-----------
- ; Use the ROS as much as possible for scan-code translation, etc., but
- ; we must 1) do flagsets to wake up CONIN or WMENU; and 2) look for
- ; screen-switch and WMENU key combinations which the ROS discards, and
- ; do our own print-screen.
- ; If AT and KBD STATUS is not exactly right, go to ROS ISR.
- ; If RELEASE instead of MAKE, go directly to ROS ISR.
- ; If MAKE, but not SWITCH, WMENU, or PRINT-SCREEN keys,
- ; go to ROS ISR, flagset, then dispatch.
- ; If SWITCH, WMENU, or PRINT-SCREEN, flagset, reset HW, then dispatch.
- ; If AST key stroke, toggle word for mode switcher and hit port.
- ; (12-4-85...don't hit port...it blanks the screen...too shocking)
- ;
- ; This ISR will set the flag specified in key_flag$, which will be
- ; CI_FLAG or WW_FLAG or ER_FLAG. Conin or ww_key or the statline error handler
- ; must at that point check switch_key$, wmenu_key$, and prtsc_key$ if desired
- ; before calling ROS to return a "regular" keystroke. Those three variables
- ; contain 0 if no screen-switch, wmenu-wake or full-window, or print-screen
- ; combination was typed.
-
- ; There is a small interrupt window in the ROS keyboard ISR where a timer int
- ; might come in. Our timer isr is significantly longer than ROS, and that
- ; apparently causes problems occasionally. Hard to pinpoint exactly where,
- ; but the timer isr now checks the kbd_imhere flag set here and just irets.
- ; This hits our performance, but not significantly.
-
- ; Enhanced keyboards have extra ALT key which can only be truly recognized
- ; by a scan code of 0E0H which preceeds both the make and break codes.
- ; This extra ALT key is used by international keyboards for characters on
- ; some keys which have 3/4 chars per key.
-
- cli ; in case someone pre-
- cld ;; ambled us
- push ds
- mov ds,sysdat
- inc kbd_imhere$ ;; indicate our presence
- push ax ;;
- test pc_at$,0ffh ;; are we on an AT
- jz not_at1 ;; jump if no
- mov al,DIS_KBD ;; disable keyboard
- call exec ;; execute command
- not_at1:
- push ds ;; check to see if we've
- sub ax,ax ;;
- mov ds,ax ;; been preambled
- mov ax,cs ;;
- cmp .26h,ax ;; int 9
- pop ds ;;
- jne been_preambled ;; can't re-read status
-
- test pc_at$,0ffh ;; are we on an AT
- jz not_at ;; jump if no
- in al,AT_KBD_STATUS ;; then check keyboard
- test al,KEY_READY ;; hunky-dory?
- jnz been_preambled
- jmp jmp_to_ros ;; if no, off to ROS
- been_preambled:
- not_at:
- in al,KBD_DATA ;; get the scan code
- cmp NX_language$,0 ;; U.S keyboard?
- je not_nat ;; avoid ALT GR test
- test NX_natnlstat$,NX_nkbd_bit
- jz not_nat ;; not national
-
- test last_char,HC ;; was last char hidden
- jz not_alt_gr ;; no..
- cmp al,ALT ;; is this one ALT
- jne test_alt_br
- or alt_gr,ALT_GR_BIT ;; set ALT GR status
- test_alt_br:
- cmp al,ALT+80h ;; ALT break key
- jne not_alt_gr
- and alt_gr,not ALT_GR_BIT ;; yes .. reset status
- not_alt_gr:
- and last_char,not HC ;; clear hidden flag
- cmp al,HIDDEN_KEY
- jne not_nat
- or last_char,HC ;; set flag
- not_nat:
- cmp al,0FAh ;; is it ACK
- jne call_to_ros
- jmp jmp_to_ros ;; yes go direct to ros
-
- if not V386
- call_to_ros:
- test al,80h ;; break?
- jz not_break ;; no, so continue
- ;; We're going to call direct to ROS
- mov ax,PC_SEGMENT
- mov ds,ax ;* point to the nether region
- mov ax,buffer_tail_40 ;;* buffer head
- mov ds,sysdat
- mov buf_tail,ax ;;* save it
- pop ax ! pop ds ;; pop registers to save stack
-
- pushf ;; fake an int
- callf keyboard_isr$ ;;
-
- push ds ! push ax ;; save registers
- mov ax,PC_SEGMENT ;* in buffer
- mov ds,ax ;* point to the nether region
- mov ax,buffer_tail_40 ;;* buffer head
- mov ds,sysdat
- cmp ax,buf_tail ;;* compare to previous start
- jne is_char ;;* char inserted so wake process
- dec kbd_imhere$ ;; now we're done
- pop ax ! pop ds
- iret ;; AT keyboard has been re-enabled
- ;; by the ROS keyboard ISR
- endif
- if V386
- ;; We're going to call to ROS at sometime
- ;; so first we must ensure correct keyboard flag
- ;; data is in the ROS data area..
- call_to_ros:
- cmp kbd_imhere$,1
- jne call_ros ; don't resave
- push cx
- push es
- push ax
- push si ! push di
- cmp active_vc$,NUM_VIR_CONS
- jae not_main ; must be serial in context
- push ds ; else update save area from ROS
- push ds ! pop es
- mov ax,PC_SEGMENT ; point at ROS data
- mov ds,ax
- mov si,offset kb_flag_40 ; keyboard data area
- mov di,offset save_kbdata$ ; save area
- mov cx,39
- rep movsb ; save kbd flags and buffer
- pop ds
- not_main:
- mov ax,PC_SEGMENT
- mov es,ax
- mov si,offset save_kbdata$ ; get saved ROS params
- mov di,offset kb_flag_40 ; and switch in
- mov cx,39
- rep movsb
- pop di ! pop si
- pop ax
- pop es
- pop cx
- call_ros:
- test al,80h ;; break char ?
- jnz save_buf
- jmp not_break ;; no, so continue - keyboard flags
- ;; restored on exit
- save_buf:
- mov ax,PC_SEGMENT
- mov ds,ax ;* point to the nether region
- mov ax,buffer_tail_40 ;;* buffer head
- mov ds,sysdat
- mov buf_tail,ax ;;* save it
- pop ax ! pop ds ;; pop registers to save stack
-
- pushf ;; fake an int
- callf keyboard_isr$ ;;
-
- cli
- cld
- push ds ! push ax ;; save registers
- mov ax,PC_SEGMENT ;#IJ - reload seg register
- mov ds,ax ;(corrupted by pop/push to save stack)
- mov ax,ds:buffer_tail_40 ;;* buffer head from ROS
- mov ds,sysdat
- cmp ax,buf_tail ;;* compare to previous start
- jne is_char ;;* char inserted so wake process
- ;; do not restore keyboard flags
- ;; done at exit
-
- cmp kbd_imhere$,1
- jne call_ros1
- push di ! push si ! push cx
- push es
- push ds
- push ds ! pop es
- mov ax,PC_SEGMENT ;* in buffer
- mov ds,ax ;* point to the nether region
- mov si,offset kb_flag_40 ; save main console ROS params
- mov di,offset save_kbdata$
- mov cx,39
- rep movsb
- pop ds
- call get_kbd_flags@ ; get active_vc save area offset in SI
- mov ax,PC_SEGMENT
- mov es,ax
- mov di,offset kb_flag_40 ; ROS keyboard data area offset
- mov cx,39 ; flags and buffer
- rep movsb ; put new values into ROS
-
- pop es
- pop cx ! pop si ! pop di
- call_ros1:
- dec kbd_imhere$ ;; now we're done
- pop ax ! pop ds
- iret ;; AT keyboard has been re-enabled
-
- endif
- jmp_to_ros:
- mov ds,sysdat
- dec kbd_imhere$
- pop ax ;; restore ax
- pop ds
- jmpf keyboard_isr$ ;; let the ROS do it
-
- eject
-
- ; char been inserted in buffer after a break
- ; We're going to flagset, so save'em all:
- ; this will allow ALT numpad keys to generate
- ; a char instantly....
- is_char:
- cmp kbd_imhere$,1
- jne no_swap1
- mov kbd_ss,ss ;;
- mov kbd_sp,sp ;;
- mov ss,sysdat$ ;;
- mov sp,offset kbd_i_stack ;;
- no_swap1:
-
- push es ! push bx ! push cx ! push dx
- push bp ! push si ! push di
-
- jmp normal1 ;; now do flagset and dispatch
-
-
- not_break:
- ; We know we must flagset, so save'em all:
-
- cmp kbd_imhere$,1
- je swap_stack
-
- ; If we've been re-entered just throw key away
- mov al,PIC_OCW_SEOI+KEYBOARD_CHANNEL ;; end-of-interrupt
- out PIC_OCW_PORT,al ;;
-
- ; make sure keyboard re-enabled on AT's
- test pc_at$,0ffh ;; are we on an AT
- jz not_at4 ;; jump if no
- mov al,ENA_KBD ;; enable keyboard
- call exec ;; execute command
- not_at4:
- dec kbd_imhere$ ;;
- pop ax
- pop ds
- iret
-
-
- swap_stack:
- mov kbd_ss,ss ;;
- mov kbd_sp,sp ;;
- mov ss,sysdat$ ;;
- mov sp,offset kbd_i_stack ;;
- no_swap2:
- push es ! push bx ! push cx ! push dx
- push bp ! push si ! push di
-
- mov kbd_scan,al ;;
- mov pc_scan_code,al
-
- ; Get shift state to be used by switch, menu, and print-screen:
- mov bx,ax ;;
- mov ax,PC_SEGMENT ;;
- mov es,ax ;;
- mov ah,es:kb_flag_40 ;; get action state
- mov al,bl ;; restore scan code
-
- ; Test for CTRL_BREAK
-
- test ah,CTRL_BIT ;; control shift
- jz not_ctr
- cmp al,BREAK_SCAN
- jne not_prtsc
- test pc_at$,0ffh ;; are we on an AT
- jz not_ate ;; jump if no
- test es:kb_flag_3_40,KBX ;; is it enhanced
- jz not_ate ;; no .. normal keyboard
- test es:kb_flag_3_40,LC_E0 ;; last char marker ??
- jz not_prtsc
- not_ate:
- mov cntl_break$,0ffh ;; set flag
- jmp hw_back ;; and leave
-
-
- ; Test for PRTSCR: not in CONTROL SHIFT
- not_ctr:
- cmp al,PRTSC_SCAN ;;
- jne not_prtsc ;;
- test pc_at$,0ffh ;; are we on an AT
- jz not_at2 ;; jump if no
- test es:kb_flag_3_40,KBX ;; is it enhanced
- jz not_at2 ;; no .. normal keyboard
- test es:kb_flag_3_40,LC_E0 ;; last char marker ??
- jnz prtsc ;; yes.. is print screen
- jmps not_prtsc
- not_at2:
- test ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT ;;
- jz not_prtsc ;;
- prtsc:
- mov prtsc_key$,al ;; save scan
- jmp hw_back ;; and leave
-
- not_prtsc:
- cmp al,NUMLOCK ;; We can't let cntl-numlock
- jne not_numlock ;; through...it kills us
- test es:kb_flag_3_40,LC_E1 ;; Enhanced keyboard hidden
- jz not_pause ;; code flag (used with PAUSE)
- and es:kb_flag_3_40,not LC_E1 ;; Clear flag before allowing
- not_pause: ;; NUMLOCK through
- test ah,CTRL_BIT ;;
- jz not_numlock
- jmp hw_back ;; throw away PAUSE key
- ;; and ctrl/numlock
- ;; jnz is_numlock ;;
- ;; jmps not_numlock
-
- ; Here if we need to fake out the cntl-numlock bit:
- ;;is_numlock:
- ;; and es:kb_flag_40,not CTRL_BIT ;; turn off control
- ;; pushf ;; fake an int
- ;; callf keyboard_isr$ ;;
- ;; or es:kb_flag_40,CTRL_BIT ;; turn control back on
- ;; jmp disp_back ;; and proceed as a normal key
-
-
- ; Test for CTRL/ALT/F1 thru F5 function keys for national
- not_numlock:
- push ax ;; save shift state
- and ah,CTRL_BIT or ALT_BIT ;; check only those shift keys
- cmp ah,CTRL_BIT or ALT_BIT
- pop ax
- jne not_ctrlalt_pfk ;; ignore if not CTRL/ALT
- cmp al,DEL_SCAN
- jne not_ctrlalt_del
- test su_kbd_bits$,01h ;; test ctrl/alt/del disabled
- jz is_ctrlalt_del ;; no
- jmp hw_back1 ;; else throw away...
- is_ctrlalt_del:
-
- if V386
- ; ** RESET SYSTEM TO REAL MODE ** to be used with caution.
-
- if 0 ;; The following call has been disabled
- ;; as it will only work if the OS
- ;; does not reside in paged memory.
- ;; As we sometimes move SYSDAT into
- ;; paged memory, the results are
- ;; a bit unpredictable...
- ;; We now force RESET@ to reset the
- ;; the CPU via the 8042 chip.
- mov cl,S_REAL
- int 224 ;; set to real mode
- endif
- jmp reset@ ;; hardware RESET
-
- endif
-
- if XM
- jmp mp_reset@ ;; disable EEMS MMU
- ;; and do hardware RESET
-
- endif
-
-
- not_ctrlalt_del:
- cmp al,F1_SCAN ;; check if function key
- jb not_ctrlalt_pfk
- cmp al,F5_SCAN
- ja not_ctrlalt_pfk
- sub al,F1_SCAN ;; make it zero based
- mov NX_natnlmode$,al ;; save current national mode
- call NX_update_mode
- jmp hw_back1 ;; exit.....
-
- not_ctrlalt_pfk:
- cmp al,PAD4_SCAN ;; anything below = normal
- jb normal ;;
- cmp al,DEL_SCAN ;; anything above is unwanted
- ja normal ;;
-
- ; Go through a jump table based on scan codes from 75 (pad-4) to 83 (del):
- sub bl,PAD4_SCAN ;;
- sub bh,bh ;;
- shl bx,1 ;; word table
- jmp pad_table[bx] ;;
-
- pad_table dw switch ;; PAD 4 75
- dw ast ;; PAD 5 76
- dw normal ;; PAD 6 77
- dw menu ;; PAD + 78
- dw switch ;; PAD 1 79
- dw switch ;; PAD 2 80
- dw switch ;; PAD 3 81
- dw normal ;; INS 82
- dw menu ;; DEL 83
- eject
-
- ; Here if we want to toggle the AST enhanced graphics switch to/from
- ; normal from/to enhanced.
- ast:
- cmp ah,CTRL_BIT ;; control-state?
- jne normal ;;
-
- test ast_flag$,0ffh ; make sure it is possibly AST
- jz not_ast
-
- mov ax,ast_enhanced ;;
- xchg ah,al ;;
- mov ast_enhanced,ax ;;
- mov dx,AST_ENHANCED_PORT ;;
- out dx,al ;;
-
- ; Now deal w/ the color select register:...change the default for 640,
- ; and also replace the value for the top screen mode if it's equal to
- ; the old default:
- mov dl,top_screen$ ;;
- call point_vs@ ;;
-
- mov ax,ds:colsel_640$ ;; toggle default 640 col sel.
- xchg ah,al ;;
- mov ds:colsel_640$,ax ;;
-
- cmp ah,VS_COLORSEL ;; is the one we just toggled
- jne dont_switch ;; FROM equal to what's in vs_?
- mov VS_COLORSEL,al ;;
- dont_switch:
- mov dx,COLOR_PORT ;; entry requirement
- call ros_color@ ;; hit it
- not_ast:
- jmp hw_back ;;
-
-
- ; Here if it's a "normal" key:
- ; now test if we're on the main
- ; section of the keyboard..... scan codes 1-53 + 86(enhanced keyboard)
- ; some languages affect certain keypad chars.
- normal:
- cmp NX_language$,0 ;; U.S keyboard?
- je normala
- test NX_natnlstat$,NX_nkbd_bit
- jz normala
- test Eshiftlock,01h ;; is it FRENCH/GERMAN enhanced
- jz normala
- test ah,CAPSLOCK_BIT ; is CAPSLOCK already down
- jz normala ; no let ROS have it
- cmp al,CAPSLOCK ; is it CAPSLOCK key
- jne test_eshift
- jmp hw_back1 ; yes.. throw it away
-
- test_eshift: ; if CAPSLOCK on and SHIFT key
- cmp al,SHFT_RIGHT ; then we must toggle CAPSLOCK off
- je tog_caps
- cmp al,SHFT_LEFT
- jne normala
- tog_caps:
- test es:kb_flag_3_40,LC_E0 ;; Enhanced keyboard hidden
- jnz normala ;; then not genuine shift
- and es:kb_flag_40,not CAPSLOCK_BIT ;; lets pretend it was CAPSLOCK
- jmps normal_ros1
-
- normala:
- cmp al,SPACE_SCAN ;; let national have space key
- je nat_jmp ;; for special case deadkey support
- cmp al,SCAN_102 ;; extra key - enhanced keyboard
- je nat_jmp
- cmp al,ALT
- je normal_ros1 ;; don't do flagset
- cmp al,SHFT_RIGHT
- je normal_ros1 ;; don't do flagset
- ja test_keypad ;; test keypad for some languages
- cmp al,SHFT_LEFT ;;
- je normal_ros1 ;; don't do flagset
- cmp al,CTRL ;; control key
- je normal_ros1 ;; don't do flagset
- cmp al,DIV_SCAN ;; NUMPAD divide key ?
- jne nat_jmp ;; no
- test es:kb_flag_3_40,LC_E0 ;; Enhanced keyboard hidden
- jz nat_jmp ;; no..
- jmps normal_ros ;; else let the ROS handle it
-
- ; is it national keyboard ??
- nat_jmp:
- cmp NX_language$,0 ;; U.S keyboard?
- je normal_ros ;; ....let the ROS do it
- test NX_natnlstat$,NX_nkbd_bit
- jz normal_ros
- jmp nat_kbd ;; national keyboard support ....
-
- ; let ROS handle input if not national mode
- normal_ros1:
- pushf ;; fake an int.
- callf keyboard_isr$ ;;
- jmp disp_back ;; don't flagset
-
- normal_ros:
- pushf ;; fake an int.
- callf keyboard_isr$ ;;
- ; jmp normal1 ;; go wake system
-
- ; Wake up the system after keyboard input
- ; springs to life at "io_conin@:"
- normal1:
- mov dx,key_flag$ ;;
- call flagset@ ;;
-
- jmp disp_back ;;
-
- ; some keypad keys are translated in some languages
- test_keypad:
- cmp al,DEL_SCAN ; SHIFT DEL -> conv to ','
- jne test_prt
- test es:kb_flag_3_40,LC_E0 ;; Enhanced keyboard hidden
- jnz normal_ros
- test ah,NUMLOCK_BIT
- jz no_num
- test ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT
- jz test_lang ; NUMLOCK + no SHIFT
- jmps normal_ros ; else let ros have it
- no_num:
- test ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT ; no NUMLOCK + SHIFT
- jz normal_ros ; no let ros have it
-
- test_lang:
- test NX_natnlstat$,NX_nkbd_bit
- jz normal_ros ;; not national
- cmp NX_language,4 ; Danish
- je conv_dot
- cmp NX_language,5 ; Swedish
- je conv_dot
- cmp NX_language,8 ; Norwegian
- je conv_dot
- test NX_kbd_type$,NX_enhanced ; is it enchanced keyboard version
- jz normal_ros ; no
- cmp NX_language,2 ; German enhanced ?
- je conv_dot ; yes
- jne normal_ros
- conv_dot:
- mov al,',' ; convert '.' to ','
- jmp save_with_msb ; save it
-
- test_prt:
- cmp NX_language,7 ; SPANISH ?
- jne normal_ros ; no ..
- test NX_kbd_type$,NX_enhanced ; is it enchanced keyboard version
- jnz normal_ros ; yes .. no translate
- cmp al,PRTSC_SCAN ; print screen key
- jne normal_ros
- mov al,'^' ; '*' converted to '^'
- jmp save_with_msb
-
- ; Here if it's maybe a "screen-switch" command:
- switch:
- test es:kb_flag_3_40,LC_E0 ;; last char marker ??
- jnz normal_jmp ;; yes ignore switch
- and ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT or CTRL_BIT or ALT_BIT ;;
- cmp ah,switch_bits$ ;; same ?
- jnz normal_jmp ;; no, so leave
-
- mov switch_key,al ;; save for conin
- jmps hw_back ;;
-
- ; Here if it's maybe a wmenu key:
- normal_jmp:
- jmp normal
-
- menu:
- test ah,CTRL_BIT ;; for us?
- jz normal_jmp ;;
- cmp al,DEL_SCAN ;; wmenu doesn't need to be
- je menu1 ;; here for FULL SCR. toggle
- cmp im_here$,0 ;; if wmenu not here...
- je normal_jmp ;;
- menu1:
- test ah,ALT_BIT ;; control-alt del. check
- jnz normal_jmp
-
- mov wmenu_key,al ;; save for conin/wmenu
- ; jmps hw_back ;;
-
- eject
-
- ; Watch the fall-through.
- ;; Exit point for keys handled by national
- ;; routines and not the ROS
- hw_back:
- mov dx,key_flag$ ;; CI_FLAG or WW_FLAG or ER_FLAG
- call flagset@ ;;
-
- ; Finish up with the HW:
- hw_back1:
- in al,KBD_CONTROL ;; get current cntl value
- mov ah,al ;;
- or al,80h ;; set RESET bit
- out KBD_CONTROL,al ;; reset keyboard
- mov al,ah ;; get original value
- jmps $+2 ;;
- out KBD_CONTROL,al ;;
-
- ; Talk to the PIC:
- mov al,PIC_OCW_SEOI+KEYBOARD_CHANNEL ;; end-of-interrupt
- out PIC_OCW_PORT,al ;;
-
- ; make sure keyboard re-enabled on AT's
- test pc_at$,0ffh ;; are we on an AT
- jz not_at3 ;; jump if no
- mov al,ENA_KBD ;; enable keyboard
- call exec ;; execute command
- not_at3:
-
- ; And iret by dispatching:
- disp_back:
-
- if V386 ; restore the current keyboard flags
- cmp kbd_imhere$,1
- jne disp_exit
- cld
- push ds
- push ds ! pop es
- mov ax,PC_SEGMENT ;* in buffer
- mov ds,ax ;* point to the nether region
- mov si,offset kb_flag_40 ; save main console ROS params
- mov di,offset save_kbdata$
- mov cx,39
- rep movsb
- pop ds
- call get_kbd_flags@ ; get active_vc save area offset in SI
- mov ax,PC_SEGMENT
- mov es,ax
- mov di,offset kb_flag_40 ; ROS keyboard data area offset
- mov cx,39 ; flags and buffer
- rep movsb ; put new values into ROS
-
- disp_exit:
- endif
-
- pop di ! pop si
- pop bp ! pop dx ! pop cx
-
- pop bx ! pop es ;;
-
- cmp kbd_imhere$,1
- jne no_swap3
- mov ss,kbd_ss ;;
- mov sp,kbd_sp ;;
- no_swap3:
- dec kbd_imhere$ ;;
-
- pop ax
- jmpf dispatch_addr$
- ;#IJ pop ds
- ;#IJ jmpf disp_addr$ ;; gone
-
- exec:
- push ax ! push cx
- sub cx,cx
- exec1:
- in al,AT_KBD_STATUS
- test al,IN_BUF_FULL
- loopnz exec1 ;; wait until command accepted
- pop cx ! pop ax
- out AT_KBD_STATUS,al ;; send command to keyboard
- ret ;; controller
-
- eject
-
- ;************************************************
- ;* *
- ;* NATIONAL KEYBOARD SUPPORT *
- ;* *
- ;************************************************
-
- ; AL = raw scan code
- ; AH = action state
-
- ; First correct an annoying feature (a bug)
- ; of the PC AT keyboard layout/firmware. On all European keyboards,
- ; the scancodes sent for two of the keys are swapped compared to
- ; the PC and XT keyboards. Long live IBM !
- nat_kbd:
- push ax
- mov dl,top_screen$ ;;
- call point_vs@ ;;
- mov al,VS_MODE
- mov key_vs_mode,al
- pop ax
-
- cmp pc_at$,0 ; are we running on an AT or clone?
- jne do_swap ; skip on PC's & XT's
- test NX_kbd_type$,NX_enhanced ; is it enchanced keyboard version
- jz test_alt ; handle enhanced keys on XT and model 30
- do_swap:
- cmp al,41 ; is it 1st key?
- je pc_at_swap ; yes, fix it
- cmp al,43 ; is it 2nd key?
- jne test_alt ; others are OK
- pc_at_swap: ; swap the key codes
- xor al,41 xor 43 ; 41 => 43, 43 => 41
- mov pc_scan_code,al ; save new value
- test_alt:
- test NX_kbd_type$,NX_enhanced ; is it enchanced keyboard version
- jz test_alt_norm ; no .. normal keyboard
- test alt_gr,ALT_GR_BIT ; ALT GR key down ?
- jz test_ctrl_alt
-
- push ds ;; same with PAUSE key
- mov bx,PC_SEGMENT ;;
- mov ds,bx ;;
- test kb_flag_1_40,L_ALT ;; is left ALT down
- pop ds
- jnz test_ctrl_alt ; yes.. ignore ALT GR
- and ah,not ALT_BIT ; else remove ALT bit from status
- test ah,CTRL_BIT ; yes.. is ctrl key down
- jnz test_alt_norm ; yes .. ignore ALT GR
- jmps get_alt_gr ; else do ALT GR translate
- test_ctrl_alt:
- test ah,ALT_BIT+CTRL_BIT
- jz test_alt_norm
- not_gr:
- mov ch,ah
- and ch,ALT_BIT+CTRL_BIT
- cmp ch,ALT_BIT+CTRL_BIT
- jne test_alt_norm
-
- ; Get key from ALT GR - (CTRL\ALT) table
- ; for national enhanced keyboards
- get_alt_gr:
- mov bx,offset NX_ctrlalt$ ; pointer to CTRL\ALT table
- test ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT
- jz not_shift ; leave it if not shifted
- mov bx,offset NX_ctrlalt_shft$ ; use CTRL\ALT shift table
- not_shift:
- mov NX_tmp_us_flg$, TRUE ; disable 7 to 8 temporarily
-
- mov al,pc_scan_code ; use this value in case translated
- cmp byte ptr kbd_scan,29h
- jne test_102
- mov al,54 ; character position reserved for extra key
- test_102:
- cmp byte ptr kbd_scan,SCAN_102 ; extra key (102 keyboard)
- jne just_xlat
- mov al,2bh ; key 102 uses old char 2bh scan code
- just_xlat:
- cmp al,SPACE_SCAN ;; don't translate
- jne do_xlat
- mov al,' ' ;; space char
- jmp key_scan_ok
- do_xlat:
- xlat bx ; get ASCII char in AL
- cmp al, 0ffh ; is it undefined
- je key_scan_nok
- ;; jmp NX_test_2nd_dkey ; no.....valid key
- jmp key_scan_ok
-
- key_scan_nok:
- mov ch,ah
- and ch,ALT_BIT + CTRL_BIT
- cmp ch,ALT_BIT + CTRL_BIT
- je test_alt_norm ; if CTRL\ALT then treat normal
- jmp key_scan_done ; else .... ignore
-
- ; Normal keyboard -
- test_alt_norm:
- test ah,ALT_BIT
- jnz test_alt_down
- jmp not_alt ; not ALT key
-
- ; The following piece of code had to be added to support ALT/letter
- ; on international keyboards, where the location of some keys is
- ; different from the US keyboard.
- test_alt_down:
- test ah,CTRL_BIT
- jz not_ctrlalt ; not CTRL\ALT
- mov al, pc_scan_code ; restore scan code
- test ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT
- jz not_shft_alt
- or al, 80h ; shift marked like this in ALT table
- not_shft_alt:
- mov cx, 0
- mov cl, NX_alt_table$ ; get number of special ALT's
- jcxz not_ctrlalt ; none of them
- push es
- push ds ! pop es ; point ES to DS
- mov di, offset NX_alt_table$+1 ; scan thru them
- cld
- repne scasb
- pop es
- jne not_ctrlalt
-
- sub di,offset NX_alt_table$ + 2 ; get number of scanned chars
- mov al,NX_alt_chars$[di] ; save the character
- mov NX_tmp_us_flg$, TRUE ; display as ascii (flag "CONOUT")
- jmp save_with_msb
-
-
- not_ctrlalt:
- mov al, pc_scan_code ; restore scan code
- cmp al, 2 ; scan code of digit "1"
- jb test_alt_letter ; below, forget it
- cmp al, 13 ; above "=", check if letter
- ja test_alt_letter ; check if ALT/letter
- add pc_scan_code, 118 ; ALT/1 thru ALT/0 are 120,...
- jmp turn_on_msb ; now it's all right
-
-
- test_alt_letter:
- mov bx, offset NX_nasciitable$ ; see if letter on keyboard
- xlat bx ; lookup table
- cmp al, 'a' ; check lower boundary
- jb not_alt_letter ; too small
- cmp al, 'z' ; check upper boundary
- ja not_alt_letter ; too big
-
- push es ; save ES
- push ds ! pop es ; MOV DS,ES
- mov di, offset key_table$ ; scan through US key table
- mov cx, 54 ; 54 chars at most
- cld ; scan forward
- repne scasb ; find out location on US kbd
- sub di, offset key_table$+1 ; subtract base + overscan
- mov ax, di ; AL = scan code
- mov pc_scan_code,al
- pop es ; restore extra segment
- jmp turn_on_msb ; return extended code for ALT
-
-
- ; test if this is an alt dead key.
- ; eat it up if it is one, continue if not.
- ; bit 7 in DEADTABLE contains shift bit,
- ; bit 6 in DEADTABLE contains alt bit
- ; (works fine because those codes are 1-59)
- ;
- not_alt_letter:
- cmp NX_natnlmode$, 1 ; 8 bit National mode ONLY
- jne no_alt_dkey
- mov cl, pc_scan_code ; get key code
- test ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT
- jz alt_dkey_noshift ; no shift, leave it
- or cl, 80h ; turn on shift bit
- alt_dkey_noshift:
- or cl, 40h ; turn on alt bit
- mov di, offset NX_deadtable$ ; find out if alt dead key
- call NX_scanstr@ ; look for a match
- cmp di,0FFFFh ; no match
- je no_alt_dkey ; forget it
- mov NX_last_dkey$, di ; save dead key
- no_alt_dkey:
- jmp key_scan_done ; eat up this code
-
-
- ; CTRL, SHIFT or NORMAL ascii national key
- not_alt:
- mov bx, NX_ascii$ ; translation table for single keys
- test ah,CTRL_BIT ; is control key down ?
- jz test_for_shift ; no, try shift
-
- mov bx, NX_ctrl$ ; yes, point to control key table
- jmps translate ; and make control code
-
- test_for_shift:
- cmp shiftlock,FALSE ;; french keyboard flag
- jnz test_caps ;; true
- test Eshiftlock,01h ; is german/french capslock down
- jz shift_test
- test_caps:
- test ah,CAPSLOCK_BIT
- jnz shift_t ; YES..
- shift_test:
- test ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT
- jz translate ; not shifted
- shift_t:
- mov bx, NX_shift$
- ; jmps translate ;use shift table if numlock
-
- translate:
- mov al,pc_scan_code ; use this value in case translated
-
- test NX_kbd_type$,NX_enhanced ; is it enhanced keyboard
- jz just_xlat1 ; no..
- cmp byte ptr kbd_scan,29h
- jne test_102_a
- mov al,54 ; character position reserved for extra key
- test_102_a:
- cmp byte ptr kbd_scan,SCAN_102 ; extra key (102 keyboard)
- jne just_xlat1
- mov al,2bh ; key 102 uses old char 2bh scan code
- just_xlat1:
- cmp al,SPACE_SCAN ;; don't translate
- jne translate1
- mov al,' ' ;; space char
- jmps key_scan_ok
- translate1:
- xlat bx ; get ASCII char in AL
- cmp al, 0ffh ; is it undefined
- jne key_scan_ok ; no.....valid key
- jmp key_scan_done ; yes .... ignore
-
- key_scan_ok:
- call NX_isdkey ; check if this is a dead key
- cmp di, 0FFFFh ; no match in table
- je NX_test_2nd_dkey ; character is not a dead key
- jmp key_scan_done ; just save it for later combination
- NX_test_2nd_dkey:
- call NX_chk_dkey ; try to combine it with dead key
-
- test ah,CAPSLOCK_BIT ;test for caps lock
- jz save_with_msb ; no...
- cmp shiftlock,FALSE ;; french keyboard flag
- jnz test_french ;; true
- test Eshiftlock,01h ; enhanced keyb shift lock supported ?
- jnz save_with_msb ; yes.. ignore CAPS translate
- test alt_gr,ALT_GR_BIT ; ALT GR key down
- jnz save_with_msb
- call NX_case_change ; else check if case sensitive
- jmps save_with_msb
-
- ;; Special test for FRENCH keyboard support
- ;; if CAPSLOCK numeric keys assume shift position
- test_french:
- test alt_gr,ALT_GR_BIT ; ALT GR key down ?
- jnz save_with_msb ; yes.. no further translation
-
- cmp kbd_scan,2 ; numeric keys and '-' and '='
- jb save_with_msb ; ignore keys below 1
-
- cmp kbd_scan,13 ; and above '+'
- ja save_with_msb
-
- mov al,kbd_scan ; restore the scan code
- mov bx,NX_shift$ ; assume no shift key down
- test ah,SHFT_LEFT_BIT or SHFT_RIGHT_BIT
- jz caps_xlat
- mov bx,NX_ascii$
- caps_xlat:
- xlat bx
- jmps save_with_msb
-
- turn_on_msb:
- mov ah, kbd_scan
- mov al,pc_scan_code
- mov kbd_scan,al
- xor al, al
- cmp ah, 2
- jb skip_alt_char
- cmp ah, 14
- jb save_with_msb ;check for alt and 1234567890-= keys
- cmp ah, 16 !
- jb skip_alt_char
- cmp ah, 26
- jb save_with_msb ;check for alt and qwertyuiop keys
- cmp ah, 30
- jb skip_alt_char
- cmp ah, 39
- jb save_with_msb ;check for alt and asdfghjkl keys
- cmp ah, 44
- jb skip_alt_char
- cmp ah, 51
- jb save_with_msb ;check for alt and zxcvbnm keys
-
- skip_alt_char:
- jmp key_scan_done
-
- save_with_msb:
- call NX_conin_xlat ; translate & check if valid
- jc key_scan_done ; eat it if invalid
-
- ;; Save character and scan code in ROS keyboard buffer
- mov ah,kbd_scan ; scan code value into AH
- insert_char:
- push ds
- mov cx,PC_SEGMENT
- mov ds,cx ;* point to the nether region
- mov bx,buffer_tail_40 ; get the buffer end pointer
- mov si,bx
- inc bx ! inc bx ; advance pointer
- cmp bx,buffer_end_40 ; at end of buffer ?
- jne not_end
- mov bx,buffer_start_40 ; yes... reset to start
- not_end:
- cmp bx,buffer_head_40 ; has the buffer wrapped
- je buf_full_beep ; yes...sound beeper !!
- mov [si],ax ; else poke scan/char into buffer
- mov buffer_tail_40,bx
- ;; mov ax,09102h
- ;; int 15h
- pop ds
- sub al, al ; clear and test buffer (JW)
- xchg al, NX_dkey_buff$ ; see if dead key character
- test al, al ; is available
- jz key_scan_nokey ; no, just continue
- mov ah, dkey_scan ; no scan code
- jmps insert_char ; insert in ROS output buffer
- key_scan_nokey:
- jmp hw_back ;; do FLAGSET then exit INT
-
- buf_full_beep:
- pop ds
- inc beep_counter$ ; sound beeper and exit......
- jmp hw_back
-
-
- ; Common exit if no character was detected
-
- key_scan_done:
- ;-------------
- jmp hw_back1 ;; reset hardware and exit
- ;; no FLAGSET
- eject
- ;****************************************
- ;* National keyboard subroutines
- ;****************************************
-
- ;=========
- NX_init@: ; initialize keyboard/screen/printer
- ;=========
- mov al, NX_natnlmode$
- ; call NX_update_mode
- ; ret ; back to XIOS_INIT
-
- NX_update_mode:
- cbw ; make it a word value
- mov bx, ax ; put it into index register
- mov al, NX_mode_table$[bx] ; get desired mode bits
- mov NX_natnlstat$, al ; setup new mode bits
- test al, NX_nkbd_bit ; see if european keyboard mode
- jnz NX_set_nt_kbd ; if set, enable european xlat table
-
- NX_set_us_kbd: ; else enable U.S. keyboard table
- mov NX_ascii$, offset key_table$ ;-> unshifted
- mov NX_shift$, offset shift_table$ ;-> shifted
- mov NX_ctrl$, offset control_table$ ;-> control
- jmps NX_update_mode_done
-
- NX_set_nt_kbd: ; enable European keyboard table
- mov NX_ascii$, offset NX_nasciitable$ ;-> unshifted table
- mov NX_shift$, offset NX_nshifttable$ ;-> shift table
- mov NX_ctrl$, offset NX_nctrltable$ ;-> control table
-
- ;;; Handle the special case of FRENCH CAPSLOCK KEY which
- ;;; acts as a SHIFTLOCK by translating all the keys on the keyboard
- ;;; and not just azerty keys.
-
- NX_update_mode_done:
- mov shiftlock,FALSE ; assume normal
- cmp NX_language$,1 ; is it FRENCH system
- jnz NX_update_exit1
- test al,NX_nkbd_bit ; national keyboard support
- jz NX_update_exit1
- mov shiftlock,TRUE
- NX_update_exit1:
- test NX_kbd_type$,NX_enhanced ; is it enchanced keyboard version
- jz NX_update_exit ; no .. normal keyboard
-
- ;; Handle special case of CAPSLOCK key on
- ;; FRENCH and GERMAN enhanced keyboard
-
- cmp NX_language$,1 ; is it FRENCH system
- jnz test_german
- or Eshiftlock,01h
- test_german:
- cmp NX_language$,2 ; is it GERMAN system
- jnz NX_update_exit
- or Eshiftlock,01h
-
- NX_update_exit:
- ret
-
-
- ;---------------
- NX_conin_xlat: ;translate 8 bit back to 7 bit if in 7 bit mode
- ;---------------
- ; Input: AL = char to translate
- ; Output: AL = translated character
- ;
- cmp NX_natnlmode$,3 ;Ctrl/Alt/F4 or F5 mode?
- jb NX_conin_xlat_done ;nothing to do if not
- ;
- mov bx,offset NX_n7to8chr$ ; scan thru 8 bit eqv chars
- NX_conin_loop:
- cmp byte ptr [bx], 0 ; see if end of translate tbl
- jz NX_conin_xlat_ignore ; yes, ignore if 8 bits
- cmp al,[bx] ; see if translation required
- jz NX_conin_8to7 ; yes, one of those characters
- inc bx ; no, may be next time
- jmps NX_conin_loop ; give it another try
-
- NX_conin_8to7:
- sub bx,offset NX_n7to8chr$ ; see how many chars checked
- mov al, NX_n7to8tbl$[bx] ; substitute it
-
- NX_conin_xlat_done:
- test al, al ; clear carry
- ret ; back to keyboard interrupt routine
-
- NX_conin_xlat_ignore:
- test al, al ; seven bits?
- jns NX_conin_xlat_done ; yes, return
- stc ; set carry
- ret
-
-
- NX_case_change: ; check if we need to change lower case <-> upper case
- ;----------------
- cmp al, 'z' ; yes
- ja NX_case_test ; not alphabetic
- cmp al, 'a' ; is it lower case ?
- jae do_case_change ; yes $ switch case
- cmp al, 'Z'
- ja NX_case_test ; not alphabetic
- cmp al, 'A' ; test for upper case
- jb NX_case_test ; not alphabetic
- do_case_change:
- xor al, 020h ; switch the case
- ret
-
- NX_case_test:
- ;--------------
- mov cl, al
- mov di, offset NX_ncasetbl$
- call NX_scanstr@
- cmp di, 0FFFFh
- je NX_no_case_change
- xor di, 1 ; lower < --- > upper
- mov al, NX_ncasetbl$[di] ; pick up the other
- NX_no_case_change:
- ret
-
-
- NX_isdkey: ; check if character is a dead key
- ;----------- ; AH = Shift state
-
- mov di, -1 ; assume no dead key
- ; test ah, CTRL_BIT+ALT_BIT
- ; jnz NX_no_dkey
- cmp NX_natnlmode$, 1 ; Ctrl/Alt/F2 mode?
- jne NX_no_dkey ; (others don't support dead keys)
- cmp al,'~'
- je is_dead
- mov cl,al
- mov di,offset NX_dead_ascii$
- call NX_scanstr@
- cmp di, -1
- je NX_no_dkey
- is_dead:
- mov cl, kbd_scan
- test Eshiftlock,01h ; is german/french capslock down
- jz shift_test3
- test ah,CAPSLOCK_BIT
- jnz shift_t3 ; YES..
- shift_test3:
- test ah, SHFT_LEFT_BIT or SHFT_RIGHT_BIT
- jz NX_isdkey_noshift
- shift_t3:
- or cl, 80H
- NX_isdkey_noshift:
- mov di, offset NX_deadtable$
- call NX_scanstr@
- cmp di, -1
- je NX_no_dkey
- mov NX_last_dkey$, di
- mov cl,kbd_scan
- mov dkey_scan,cl
- NX_no_dkey:
- ret
-
-
- NX_chk_dkey:
- ;-------------
- ; entry: al = character to combine with previous dead key
- ; exit: al = combined character
-
- mov di, NX_last_dkey$
- cmp di, -1
- je NX_chk_dkey_done
- mov cl, al
- shl di, 1
- mov di, NX_dkeyv$[di]
- call NX_scanstr@
- cmp di, -1
- je NX_bad_dkey
-
- mov bx, NX_last_dkey$
- shl bx, 1
- mov bx, NX_dkeyx$[bx]
- mov al, [bx+di]
- jmps NX_chk_dkey_done
-
- NX_bad_dkey:
- mov cl,dkey_scan ; swap old and new scan codes
- xchg cl,kbd_scan
- mov dkey_scan,cl
- mov di, NX_last_dkey$ ; was dead key != '..' ?
- cmp al, ' ' ; DEADKEY + ' ' --> DEAD
- je NX_dkey_blank ; don't return 2nd char if blank
- mov NX_dkey_buff$,al ; else save second character
- NX_dkey_blank:
- test di, di ; (has index zero)
- jnz NX_chk_space
- mov al,0f9h ; insert IBM decimal point char
- ;; inc beep_counter$ ; always beep
- jmps NX_chk_dkey_done
- NX_chk_space:
- ;; cmp al, ' ' ; dead key + ' ' doesn't beep
- ;; je NX_dkey_beep
- ;; inc beep_counter$ ; all others do
- NX_dkey_beep:
- mov al, NX_dead_key$[di]
- NX_chk_dkey_done:
- mov NX_last_dkey$, -1
- ret
-
-
-
- NX_xlt_7to8: ; translate 7 to 8 bit code
- ;-------------
- ; entry: cl = character to translate
- ; exit: cl = translated character
-
- push bx ; keep every register safe
- cmp NX_natnlmode$,3 ; 7 bit, nat scn, nat kbd?
- jne NX_xlt78_not_xlt ; not Ctrl/Alt/F4 mode
-
- mov bx,offset NX_n7to8tbl$ ; scan thru 7 bit eqv chars
- NX_xlt78_loop:
- cmp byte ptr [bx],0 ; see if end of translate tbl
- jz NX_xlt78_not_xlt ; yes, check for paragraph
- cmp cl,[bx] ; see if translation required
- jz NX_xlt78_7to8 ; yes, one of those characters
- inc bx ; no, may be next time
- jmps NX_xlt78_loop ; give it another try
-
- NX_xlt78_7to8:
- sub bx,offset NX_n7to8tbl$ ; see how many chars checked
- mov cl,NX_n7to8chr$[bx] ; get substitution
-
- NX_xlt78_not_xlt:
- pop bx
- ret
-
-
- NX_scanstr@: ; search for a character in a table
- ;------------
- ; entry: cl = character to look for
- ; di = address of string to search
- ; exit: cl = unmodified
- ; di = relative position of cl in string if match
- ; di = 0xffff if no match
-
- push ax ; save our scratch register
- mov ax, di ; save table in ax
- NX_scanstr_loop:
- cmp byte ptr [di], 0 ; end of string?
- je NX_scanstr_nomatch ; yes, definitly no match
- cmp cl, [di] ; match with character
- je NX_scanstr_match ; yes, found it
- inc di ; no, next character
- jmps NX_scanstr_loop ; another try...
-
- NX_scanstr_nomatch:
- mov di, 0ffffh ; get failure code
- jmps NX_scanstr_done ; return it
- NX_scanstr_match:
- sub di, ax ; offset to start of string
- NX_scanstr_done: ; return code
- pop ax ; restore scratch register
- ret
-
-
- ;----------------
- NX_conout_xlat@: ;called from module WINDOWS1.A86
- ;----------------
- ; Input: AL = character to translate
- ; Output: AL = translated character
- ; all others maintained
-
- push bx ; keep every register safe
- cmp NX_natnlmode$, 3 ; 7 bit, nat scn, nat kbd?
- jne NX_conout_not_xlt ; not Ctrl/Alt/F4 mode
- cmp NX_tmp_us_flg$, 0 ; temparaily 7/8 xlt off
- mov NX_tmp_us_flg$, 0 ; reset temporary US display
- jnz NX_conout_not_xlt ; leap if disabled
-
- mov bx, offset NX_n7to8tbl$ ; scan thru 7 bit eqv chars
- NX_conout_loop:
- cmp byte ptr [bx], 0 ; see if end of translate tbl
- jz NX_conout_not_xlt ; yes, check for paragraph
- cmp al, [bx] ; see if translation required
- jz NX_conout_7to8 ; yes, one of those characters
- inc bx ; no, may be next time
- jmps NX_conout_loop ; give it another try
-
- NX_conout_7to8:
- sub bx, offset NX_n7to8tbl$ ; see how many chars checked
- mov al, NX_n7to8chr$[bx] ; get substitution
-
- NX_conout_not_xlt:
- cmp al, 236 ; this is how we store para
- jne NX_conout_not_para ; not bloody paragraph char
- mov al, 21 ; IBM sez: paragraph = Ctrl/U
- NX_conout_not_para:
- pop bx
- ret ; back to display routine
-
-
-
- eject
-
- ;****************************************
- ;* KEYBOARD INTERRUPT DATA AREA *
- ;****************************************
-
- DATA dseg
- ; Stack:
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- dw 0CCCCh,0CCCCh,0CCCCh,0CCCCh
- kbd_i_stack rw 0
-
- kbd_ss rw 1 ; saved user stack
- kbd_sp rw 1
-
- switch_bits$ db CTRL_BIT ; set by FUNCTION
-
- switch_key$ db 0 ; for CONIN
- wmenu_key$ db 0 ; for WMENU/CONIN
- prtsc_key$ db 0 ; for CONIN
-
- key_flag$ dw CI_FLAG ; CI_FLAG or WW_FLAG or ER_FLAG
- kbd_scan rb 1 ; temp storage
- dkey_scan rb 1 ; temp storage
- buf_tail rw 1 ; temp buffer tail storage
- kbd_imhere$ db 0 ; mx
-
- cntl_break$ db 0 ; = FF if cntl-brk has been typed
-
- shiftlock db FALSE ; shift lock flag for FRENCH keyboard
- Eshiftlock db 0 ; Enhanced keyboard shiftlock flag
- key_vs_mode db 0 ; temp VS_MODE storage
- pc_scan_code db 0 ; pcmode scan code
-
- ; enhanced keyboard support
- last_char db 0 ; last char hidden flag
- alt_gr db 0 ; ALT GR key depressed status
-
- if V386
- save_kbdata$ rb 39 ; ROS keyboard data save area
- ; offset 17h- 3Eh in ROS data area
- endif
-
- eject
- cseg
-
- keyboard_isr$ rd 1 ; set in INIT
-
- end
-