📄 llkeys.asm
字号:
; Now if the char is 0FFFFh, do not
; allow this in Graphics modes
MOV AH,b$BiosMode ; Get BIOS mode value
CMP AH,4 ; If 3 < AH < 6 then graphics
JB MAP255 ; Brif Text
CMP AH,7 ; Check for upper limit
CMC ; CF = 0 if Graphics
MAP255: ; Set AH accordingly
SBB AH,AH ; AH = 0/-1
JMP SHORT MAP_RET ; That's it.
MAP_IT:
CMP AL,31 ; Is 0 <= AL < 32
JA MAP_RET ; Brif not a control char
MAP_XLAT: ; Translate control char
XLAT PRTMAP_TABLE ; Do it now
CBW ; AH = -1 if 2-byte char
AND AL,07FH ; Knock off MSB
; AH is either 0 or 0FFH
CMP AH,80H ; This sets CF if AH = 0
; but ZF = 0 always
CMC ; Reverse the sense of CF for reporting
MAP_RET:
cEnd ; End of B$CTRLMAP
;***
;B$PRTMAP - Map a character into a form for printing
;OEM-interface routine
;
;Purpose:
; This routine is called to translate character codes from the
; Microsoft Standard Keyboard code set to either:
;
; 1. another code from the Microsoft Standard Keyboard set for
; printing.
; 2. a function code from the Microsoft Standard Keyboard set.
; 3. a request to ignore the character (it has no printable form)
;
; B$PRTMAP is called as a result of a requests to print characters.
; This routine must filter out all characters which are non-printable.
; If a printable character code is returned, then it must not
; cause any BIOS/VIO functions to be executed when it is sent to
; either the screen or a device. These codes must either be ignored
; or mapped to a Microsoft Standard Keyboard Function code. Examples
; of characters that have to be mapped are Function Keys and many
; of the control characters.
;
; This routine may return the code for any character, allowing
; characters to be moved around in the character set. For more
; information on character mapping, see the documentation for the
; function B$KEYINP.
;
; Note: If you want to use PRINT for escape sequences, B$PRTMAP
; must not map the ESC character &H3F to &HFF3F.
;
;Entry:
; [AX] = Microsoft Standard Keyboard code (1 or 2 byte only)
; PSW.C = set indicates a 2-byte char
;
;Exit:
; [AX] = code to be printed or function to be executed
; PSW.Z = set indicates to ignore the current char - AX don't care
; PSW.Z = reset indicates to process the char
; PSW.C = set indicates a two byte character
; PSW.C = reset indicates a one byte character ([AH] = 0)
;
;Uses:
; Per Convention
;
;Preserves:
; BX, CX, DX
;
;Exceptions:
; None.
;****
;ALGORITHM:
; if 2-byte char then
; if char is supershift or soft key then ignore
; else process char
; else
; if char is 255D then
; if mode is graphics then ignore char
; else process as 2-byte 255D,255D
; else
; if control char then map (1 or 2 bytes)
; process char
; NOTE: If ZF = 1 (ignore char) then AX is undefined. Currently, the
; callers (REDMAP, $SCREEN_OUT in IOTTY.ASM)
; ignore AX under this condition.
cProc B$PRTMAP,<PUBLIC,NEAR>
cBegin
JNC PRT_1_BYTE ; Process 1-byte code
PRT_2_BYTE: ; Process 2-byte chars
CMP AH,255D ; See if ctl char
JE PRT_1_BYTE ; Nope--1-byte char
CMP AH,80H ; If so, then it is a 1-byte char
JE PRT_EXIT ; Brif true. CF = 0
STC ; Indicate 2-byte char
JMP SHORT PRT_EXIT
; CF = 0 implies 2-byte code
PRT_1_BYTE: ; Check for control char range
PUSH BX ; Save BX
MOV BX,RT_TEXTOFFSET PRTMAP_TABLE ; Translation table
cCALL B$CTRLMAP ; Map the control char
POP BX ; Restore BX
PRT_EXIT: ; Generic exit...
cEnd ; End of B$PRTMAP
;***
;B$EDTMAP - map a character into a form for displaying
;OEM-interface routine
;
;Purpose:
; This routine is called to translate character codes from the
; Microsoft Standard Keyboard code set to either:
; 1. another code from the MIcrosoft Standard Keyboard set.
; 2. a function code from the Microsoft Standard Keyboard set.
; 3. a request to ignore the character.
;
; B$EDTMAP is called as a result of Screen editor requests to echo
; characters. It may be noted that Screen Editor screen control
; functions will be active only if this routine exits with the
; screen control function in AX, PSW.Z reset, and PSW.C set (indicating
; to process the associated editor function).
;
; This routine allows the OEM to map characters to Screen Editor
; functions and to change character codes. Screen Editor functions
; are performed when the associated control characters are printed.
; These control codes must be mapped to the appropriate function code
; by this routine. For example, if a carriage return should be
; mapped to FF0D (Carriage Return Function). Any character that
; is printable is printed without any further mapping.
;
;Entry:
; [AX] = Microsoft Standard Keyboard code (1 or 2 byte only)
; PSW.C = set indicates a 2-byte char
;
;Exit:
; [AX] = code to be printed or function to be executed
; PSW.Z = set indicates to ignore the current char - AX is don't care
; PSW.Z = reset indicates to process the char
; PSW.C = set indicates a 2-byte char
; PSW.C = reset indicates a single byte char in AL
;
;Uses:
; Per Convention
;
;Preserves:
; BX, CX, DX
;
;Exceptions:
; none
;****
cProc B$EDTMAP,<PUBLIC,NEAR>
cBegin
; The processing of edit mappint is almost identical to that of
; print map except that the lookup table is different. Hence setup
; BX to point to EDTMAP_TABLE and use B$PRTMAP control-char processing
; code.
JNC EDT_1_BYTE ; CF =0 means it is 1-byte char
; check graphics context also
EDT_2_BYTE: ; If special (AX = 0FFFFH) then
CMP AX,-1
JNE EDT_EXIT ; Brif not exit
EDT_1_BYTE: ; 1-Byte or 2-byte 0FFFFH char
PUSH BX ; Save BX, B$PRTMAP will unsave it
MOV BX,RT_TEXTOFFSET EDTMAP_TABLE; Lookup table address
cCALL B$CTRLMAP ; Process 1-byte chars
POP BX ; Restore BX
EDT_EXIT: ; Generic exit...
cEnd ; End of B$EDTMAP
;***
;B$INFMAP - map character for INPUT$
;OEM-interface routine
;
;Purpose:
; This routine is called to translate character codes from the
; Microsoft Standard Keyboard set to an OEM specific key code set.
; B$INFMAP is called during the processing of the INPUT$ function,
; when the characters are coming from the keyboard.
; Since there may be differences in the code values returned
; by the INPUT$ and INKEY$ functions, two separate support
; routines are required for these functions. Codes returned
; by B$INFMAP may be one or two byte codes.
;
; The way that a string for INPUT$ from KYBD: is created
; is by asking for characters from B$KEYINP, passing them
; to B$INFMAP, and storing the results in the string.
;
;Entry:
; [AX] = Microsoft Standard Keyboard code
; [DX] = bytes 2 and 3 of three byte codes
; PSW.C = set indicates a 2 byte character
; PSW.C = reset indicates a 1 or 3 byte character code
; (the code is in AL in the 1 byte case, AX in the 2 byte
; case, and AL and DX in the 3 byte case)
;
;Exit:
; [AX] = OEM code to be returned by INPUT$
; PSW.C = set indicates a 2 byte character
; PSW.C = reset indicates a 1 byte character code in AL
; PSW.Z = set indicates that there is no OEM code to associate
; with the Microsoft Code - AX is don't care
;
;Uses:
; Per Convention
;
;Preserves:
; BX, CX, DX
;
;Exceptions:
; None.
;****
cProc B$INFMAP,<PUBLIC,NEAR>
cBegin
JC INF_2_CHK ; If CF = 1 then it is 2-byte
CMP AL,254 ; Check if 3-byte char
JNE INF_EXIT ; Br if not a 3-byte char
; Return zero for 3-byte character codes. The following comparisons will
; ALL FAIL and hence the return code will be zero in AX
INF_2_CHK: ; Process 1-byte chars
CMP AX,-1 ; If AX is special 2-byte
JE INF_EXIT ; Then treat it as 1-byte only
CMP AX,8080H ; Is it special 80H?
JE INF_EXIT ; Brif so
CMP AX,0FF10H ; Is it special 0FEH?
MOV AL,254
JE INF_EXIT ; Br if true
INF_RET0:
XOR AX,AX ; Return ignore char AX = 0
INF_EXIT: ; Reset ZF & CF and exit
OR SP,SP
; Exit.
cEnd ; End of B$INFMAP
;***
;B$INKMAP - map character for INKEY$
;OEM-interface routine
;
;Purpose:
; This routine is called to translate character codes from the
; Microsoft Standard Keyboard set to an OEM specific key code set.
; B$INKMAP is called during the processing of the INKEY$ function.
; Since there are differences in IBM BASIC for the code values
; returned by the INPUT$ and INKEY$ functions, two separate
; support routines are required for these functions. One or
; two byte values will be returned from this code for the
; INKEY$ function.
;
;Entry:
; [AX] = Microsoft Standard Keyboard code
; [DX] = bytes 2 and 3 of three byte codes
; PSW.C = set indicates a 2 byte character
; PSW.C = reset indicates a 1 or 3 byte character code
; (the code is in AL in the 1 byte case, AX in the 2 byte
; case, and AL and DX in the 3 byte case)
;
;Exit:
; [AX] = OEM code to be returned by INKEY$.
; PSW.C = set indicates a 2 byte character
; PSW.C = reset indicates a 1 byte character code in AL
; PSW.Z = set indicates that there is no OEM code to associate
; with the Microsoft Code. AX is don't care
;
;Uses:
; Per Convention.
;
;Preserves:
; BX, CX, DX
;
;Exceptions:
; None.
;****
;
; ALGORITHM:
; If input is 3-byte code then restore extended code and exit
; else
; if 1-byte code then return with same code
; else REM input is 2-byte code
; if input is special 1-byte then return 1-byte code
; else search the table for match
; if match found then return mapped char
; else return zero in AX and request to ignore it.
;
; NOTE: If ZF = 1 (ignore char) then AX is undefined. Currently, the
; caller (B$INKY in IOTTY.ASM) ignores AX under this condition.
;
; IMPLEMENTATION:
; This function is exact opposite of B$KEYINP in the sense that the
; mapping is reversed. This assists us in sharing the same keyscan table
; for mapping. However, the main difference is in setting up the start
; address for key searching and the count of entries to be searched.
; The first one is determined the input high-byte (AH) value and
; the second one by the number of entries for each AH-type. The equates
; KEY_128_LEN & KEY_255_LEN provide the count values that can be
; moved into CX for looping. Also, notice that the 3-byte entries
; <new-AL> = 254 will not be used and separate in-line check would
; be made to detect both 3-byte characters and special 1-byte characters
;
cProc B$INKMAP,<PUBLIC,NEAR>,<BX,CX,SI>
cBegin
JC INK_2_BYTE ; Process 2-byte codes separately
CMP AL,254 ; Is it a 3-byte code?
CLC ; Assume 1-byte return code
JNE INK_EXIT ; NO, it is 1-byte, return the same code
SHL AL,1 ; CF = 1, ZF = 0 to indicate 2-byte code
XCHG AX,DX ; Restore extended code and say it is
; a 2-byte code (CF = 1)
JMP SHORT INK_EXIT
; Come here for 2-byte code and special 1-byte codes
INK_2_BYTE:
CMP AX,0FFFFH ; Is it 2-byte code for 255?
JE INK_1_BYTE ; Yes, set CF=ZF = 0 and exit
CMP AX,08080H ; Is it 2-byte code for 128?
JE INK_1_BYTE ; Brif so
CMP AX,0FF10H ; Is it 2-byte code for 254
JNE INK_MAP ; Brif not to map it
MOV AL,254 ; 0XFF10 maps to 0XFE
INK_1_BYTE: ; Set ZF = CF = 0
OR SP,SP
JMP SHORT INK_EXIT ; & Exit...
INK_MAP: ; Map the character using KEYINP_TABLE table
; It is really a 2-byte character. Try to map it to the scan code
; Examine High-byte to determine the table start
MOV CX,KEY_128_LEN ; Assume high-byte would be 128
MOV SI,RT_TEXTOFFSET KEYINP_TABLE ; Same as above
CMP AH,128 ; Is it 128?
JE INKMAP_LOOP ; Br to search the table
MOV CL,KEY_255_LEN ; Setup count and start address for
MOV SI,RT_TEXTOFFSET KEY_255_START ; High-byte = 255
; If AH <> 255 invalid input code - raise an alarm
DbAssertRelB AH,E,255,RT_TEXT,<Illegal 2-byte code in INKMAP>
INKMAP_LOOP:
XCHG AX,BX ; BL = Keycode
CLD ; Autoincrement
INK_LOOP: ; Search Loop
LODS KEYINP_TABLE ; Get both keycode and scancode
CMP AL,BL ; Is key found
JE INK_FOUND ; Brif match occurred
LOOP INK_LOOP ; Try again until end of table
INK_NOTFOUND: ; The key was not found. Simply return
XOR AX,AX ; zero in AX and request to ignore it.
JMP SHORT INK_EXIT ; Exit...
INK_FOUND: ; A match has been found
; Return the code in correct registers
MOV AL,AH ; Get the mapped character
XOR AH,AH ; Set High byte zero
SAHF ; ZF = 0
INK_CEXIT:
STC ; CF = 1
INK_EXIT: ; Exit...
cEnd ; End of B$INKMAP
sEnd RT_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -