📄 llkeys.asm
字号:
;
;Entry:
; none
;
;Exit:
; [BX] = address of format descriptor
; -> FKCCNT
; FKDCNT
; FKNUM
;
;Uses:
; Per Convention.
;
;Preserves:
; DX
;
;Modifies:
; None.
;*****
;ALGORITHM:
;
; If the width = 40 then count = 5 else (width = 80), count = 10
; Hence it can just divide by 8 to achieve the result
;
; Actually this routine need only to return the format descriptor address
; as the number of function keys can be set by B$SCRSTT when the mode
; changes. It is assumed, of course, that the user would not want to
; change the number of softkeys displayed without changing the screen
; dimension. In this case, the first 4 lines of code can be removed.
cProc B$FKYFMT,<PUBLIC,NEAR>
cBegin
MOV BX,OFFSET DGROUP:FKPARM ;get address of format descriptor
MOV AL,b$ScrWidth ; Get the current screen width
MOV CL,3 ; Setup to divide by 8
SHR AL,CL ; AL = 5/10
MOV FKDCNT,AL ; Store it in the structure
cEnd ; End of FKYFMT
;***
;B$FKYMAP - map character to printable form for Function Key display
;OEM-interface routine
;
;Purpose:
; This routine is is called to map characters for the function
; key display. This routine allows certain key codes to be replaced
; by a different key code. For example, CHR$(13) might be mapped
; to the character '<'.
;
; This mapping should be done for any character that is unprintable
; or that would cause Screen Editor functions to be performed. Note
; that this routine must always return a legal key code, which should
; be a printable graphic character. No further mapping of the
; character will take place before it is printed.
;
;Entry:
; [AX] = character
; PSW.C set indicates a two byte character
;
;Exit:
; [AX] = character
; PSW.C set indicates a two byte character
;
;Uses:
; Per convention
;
;Preserves:
; CX, DX
;
;Exceptions:
; None.
;****
; ALGORITHM:
; If the input character is two-byte then return as it is
; else
; if input range is 0-13 or 28-31 (inclusive ranges)
; then map it using FKYMAP_TABLE
; else return input character itself
cProc B$FKYMAP,<PUBLIC,NEAR>
cBegin
JC FKYRET ; If char = 2-byte then exit
CMP AL,31 ; Is character in control range?
JA FKYRET ; NO, can be printed as is
CMP AL,13 ; Below 14, use the mapper
JBE FKY_XLAT ; Brif need to translate
CMP AL,28 ; Is 13 < char < 28?
JB FKY_RET1 ; Brif no mapping
SUB AL,(28-14) ; Bring it in range for mapping
FKY_XLAT:
CBW ; AL < 31 ; Therefore AH = 0
XCHG AX,BX ; BX need to be saved
MOV BL,CS:FKYMAP_TABLE[BX] ; Get the substitute char
XCHG AX,BX ; Restore back BX
FKY_RET1: ; Clear carry to indicate 1-byte
CLC
FKYRET: ; Exit...
cEnd ; End of FKYMAP
;***
;B$KEYINP - input key from keyboard
;OEM-interface routine
;
;Purpose:
; This routine gets a key from the keyboard and translates it
; to a code from the Microsoft Standard Keyboard code set.
; This routine will wait until a character is ready if PSW.Z
; is set, else it will return immediately with a flag if there
; was no available character.
;
; The host keyboard support may return a multiple code sequence
; for a given key depression rather than a single code. This
; routine must collect these codes and return a single Microsoft
; Standard Keyboard code.
;
; A goal in key mapping is to allow special keys (such as
; <backspace>) to cause the same action as a key in the control
; code range (such as ^H). Yet it is still desirable to return
; unique key codes to the user for the INKEY$ function. This
; is accomplished by having multiple mapping routines.
;
; This is one of many different routines that map characters from
; a machine specific form to and from the MicroSoft Key Codes.
; These codes are used within BASIC for all functions, and are
; only translated only on input, for INPUT$, and for INKEY$.
; This is the only routine which will get characters from the
; hardware, so it is the only one that has to map from the
; machine specific format to the MicroSoft format. The following
; routines are used to map from MicroSoft format to a different
; format for printing or for presenting to the user:
;
; B$EDTMAP - map a character during Screen Editing
; B$FKYMAP - map a character for the Function Key display
; B$INFMAP - map a character for INPUT$
; B$INKMAP - map a character for INKEY$
; B$PRTMAP - map a character for printing
;
; See the documentation with each function for the specifics of
; the particular mapping. Note that all characters that are sent
; to OEM functions for displaying, printing, device I/O, etc are
; Microsoft Key Codes.
;
; Note that all characters that are presented to the user go
; through mapping twice. First they go through B$KEYINP to
; convert them to Microsoft Standard Key Codes, then through
; either B$INFMAP, B$INKMAP, or B$EDTMAP before being
; presented to the user.
;
;Interim Character Support Considerations:
;
; All entry and exit conditions are unchanged except for two-byte
; characters (PSW.C set). Not, the value of DX determines
; whether the character is interim or final. If DX is 0, the
; character in AX is treated as an interim character.
;
;
;MicroSoft Key Codes:
;
; KeyCode(Hex) Remarks
; _______________________________________________________________
;
; 00 Null (but printable if a font exists)
; 01-0C Printable 1-byte characters
; 0D Carriage Return
; 0E-0F Printable 1-byte characters
; 20-7E ASCII characters
; 7F DELETE character
;
; 80 First byte of 2-byte character set
; 00-1F Unimplemented
; 20-3F Function Keys (mapped by INPUT routines)
; 40 Unimplemented
; 41-5A Super-shift Keys
; 5B-7E Unimplemented
; 80 printable character 80 (if a font exists)
; 81-FC Unimplemented
;
; 81-9F First byte of 2-byte character set
; 40-FC Second byte of 2-byte character set (7F is illegal)
;
; A0-DF Printable 1-byte character set
;
; E0-FC First byte of 2-byte character set
; 40-FC Second byte of 2-byte character set (7F is illegal)
;
; FE First byte of 3-byte character set
; 0000-FFFF Second and third bytes of a 3-byte character
; mapped to 1- or 2- byte character by INPUT routines
;
; FF First byte of 2-byte character set (Editor Control)
; 00-0F Editor control characters (as input keys)
; 10 Editor control key ( as input key)
; Printable character FE (as print code)
; 11-FE Editor control characters (as input keys)
; FF Editor control key ( as input key)
; Printable character FF, (font is space) as print code
;
; Note:
; Unimplemented key codes are also valid but currently they have no
; assigned function.
;
;
;Entry:
; PSW.Z set if B$KEYINP may wait for a key
;
;Exit:
; [AX] = Microsoft Standard Keyboard code
; [DX] = bytes 2 and 3 of three byte codes
; = 0 to signal a non-interim character (when PSW.C set)
; = 1 to signal a interim character (when PSW.C set)
; PSW.C = set indicates a 2 byte character
; PSW.C = reset indicates a 1 or 3 byte character code
; PSW.Z = set if no keys have been typed
; (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)
;
;Uses:
; Per Convention
;
;Preserves:
; BX, CX
;
;Exceptions:
; None.
;****
; For this implementation all control range codes and printable
; characters will be passed through as one byte keycodes except
; for the special codes 128D, 254D, and 255D (&H 80, FE, FF)
; which will be mapped as 2-byte codes. The IBM extended
; character set will be mapped as two or three byte codes
; in the Microsoft Standard Keyboard code set.
;
;ALGORITHM:
; if PSW.Z is set then
; wait for a character to be typed
; if IBM 2-byte char then
; if char is control-break then make it MS control break
; else
; if char is shifted function key then
; make it M.S. three byte code
; else
; map to M.S. code
; else
; if char is 128D or 254D or 255D then map to M.S. code
; else
; set PSW.Z and return
;#****
cProc B$KEYINP,<PUBLIC,NEAR>,<SI,BX>
cBegin
GET_A_KEY:
PUSHF ;save flags
KYBIO kPollKeyBoard ;loop while character
JNZ CHECK_KEY ; Key is available
NO_KEY:
POPF ; Get back flags
JZ GET_A_KEY ; Wait until a key is available
XOR AH,AH ; Indicate no key is available
JMP SHORT KEY_RET ; & Exit...
CHECK_KEY: ; Process the key
KYBIO kReadKeyBoard ;get key from buffer
MOV SI,RT_TEXTOFFSET KEYINP_TABLE; Get scancode table
CLD ; Set for autoincrement
OR AL,AL ;is it a two byte code?
JNZ Chk_One_Byte ; br. if not
OR AH,AH ; Check for BREAK key
JNZ Supershift_check ; Brif may be supershift key
OR AX,0FF03H ; Set BREAK key code
STC ; ZF = 0 ; CF = 1 (2-BYTE CODE)
JMP SHORT KEY_EXIT ; & Exit...
Chk_One_Byte:
TEST b$RcoFlg,0FFH ; is ronco installed ?
JZ Single_Byte ; Brif not
CMP AL,HidScn1 ; is hidden char code ?
JE SuperShift ; Brif yes
CMP AL,HidScn2 ; is hidden char code ?
JE SuperShift ; Brif yes
; CMP AH,HidScn1 ; KEYPAD / & ENTER need special care
; JNE Single_Byte ; Brif not, this is a normal character
; The following comparisons are done only for the RONCO KBD. Still it
; has to be ascertained as to why these are done as they seem to serve
; no purpose (judged by the existing code)
; CMP AL,CharSlash ; is Keypad / ?
; MOV AH,ScanSlash ; make it normal
; JE Single_Byte ; Brif yes
; CMP AL,CharEnter ; is Keypad enter ?
; MOV AH,ScanEnter ; make it normal
; JE Single_Byte ; Brif yes
; CMP AL,CharCTRLEnter; is keypad CTRL enter ?
; JMP SHORT Single_Byte ; Brif not, a normal character
Single_Byte:
; If al = 253 then return 3-byt code
MOV AH,0 ; Assume 1-byte
CMP AL,253D ;is it special char?
JE KEY_EXIT ; br. if so - Exit
JA KEY_MAP ; Map it to 3-byte code
CMP AL,128D ;is it special char?
JNE KEY_EXIT2 ; br. if 1-byte char : ZF = CF = 0
MOV AL,253D ; Scan code for ALT-128
JMP SHORT KEY_MAP ; Map to 8080H
SuperShift:
XOR AL,AL ; make it normal
SuperShift_Check:
XCHG AL,AH ; Copy scan code
; AH = 0
CMP AL,84D ;lower bound of shifted fctn. key?
JB KEY_MAP ;br. if below
CMP AL,114D ; upper bound of shifted fctn. key?
JB KEY_3_BYTE ; indicate 3-byte M.S. code
KEY_MAP:
XCHG AX,BX ; BL = Scan code of key
; BH = 0 at this point always
KEY_LOOP:
LODS KEYINP_TABLE ; [AH] = next <raw-code> entry in table
TEST AX,AX ; test for last table entry
JZ NO_KEY ; End of table - try again
CMP AH,BL ; look for match on scan code
JNE KEY_LOOP ; loop back if not found
KEY_FOUND:
MOV AH,80H ; Assume AH will have 80H
CMP SI,RT_TEXTOFFSET KEY_128; Is it two-byte code?
JB KEY_EXIT ; Exit 2-byte code CF = 1 already
MOV AH,255D
CMP SI,RT_TEXTOFFSET KEY_255; Is it 2-byte with AH=0FFH
JB KEY_EXIT ; Set AH = 0FFH and return
XCHG AX,BX ; Get scan code in AL
; AH = 0
KEY_3_BYTE: ; It is a 3-byte code
; When control comes here, AH = 0 always
MOV DX,0FEH ; 254 indicates 3-byte code
XCHG AX,DX ; DL is the keycode and AH = 0
KEY_EXIT2: ; Set ZF & CF to zero
SAHF ; CF = ZF = 0 at this point
KEY_EXIT:
POP BX ; Discard the flags on stack
KEY_RET: ; Generic Exit...
cEnd ; End of B$KEYINP
;***
;B$CTRLMAP
;
;PURPOSE:
;
; B$CTRLMAP will map the character in AL according to the table
; pointed to by BX. However, if the input character = 0FFFFH, then
; the returned character will be requested to be ignored in Graphics
; modes 4,5, & 6.
;
;ENTRY:
; [BX] = Character-Translation-Table-Address
; [AX] = Character to be translated
;
;EXIT:
; [AX] = Translated code
; PSW.C = Set to indicate 2-byte char
; PSW.Z = Set to indicate ignore the char
;
;MODIFIED:
; NONE
;
;****
cProc B$CTRLMAP,<NEAR> ; Map if it is a control character
cBegin
CMP AL,255D ; See if FFh
JNE MAP_IT ; Brif it is not 0FFFFH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -