⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kbdcode.inc

📁 MMURTL(tm) Computer Operating System Ver x0.8, source code.
💻 INC
📖 第 1 页 / 共 2 页
字号:
;   MMURTL Operating System Source Code
;   Copyright 1991,1992,1993, Richard A. Burgess
;   ALL RIGHTS RESERVED
;   Version x0.8
;
;ISR for the keyboard.  This is vectored to by the processor whenever
;INT 21 fires off.  This puts the single byte from the 8042
;KBD processor into the buffer.  Short and sweet the way all ISRs
;should be... (most are not this easy though).  This also sends
;a message to the KBD Task (using ISend) when the buffer is almost
;full so it will be forced to process some of the raw keys even
;if no keyboard requests are waiting.

IntKeyBrd:				     		;Key Board (KB) INT 21
	    PUSHAD						;Save all registers
	    MOV ESI, pKbdIn				;Set up pointer
	    XOR EAX,EAX
	    IN  AL, 60h	  				;Read byte
	    MOV EBX, dKbdCnt			;See if buffer full
	    CMP EBX, 20h				;Buffer size
	    JE KbdEnd 	     			;Buffer is full - Don't save it
	    MOV BYTE PTR [ESI], AL 			;Move into buf
	    INC dKbdCnt						;One more in the buf
	    INC ESI							;Next byte in
	    CMP ESI, OFFSET rgbKbdBuf+20h	;past end yet?
	    JB KbdEnd
	    MOV ESI, OFFSET rgbKbdBuf	;Back to beginning of buffer
KbdEnd:
	    MOV pKbdIn, ESI				;Set up pointer for next time

		CMP fKBDInitDone, 0			;Service isn't ready for messages yet
		JE KbdExit

		;ISend a msg to Keyboard task
		MOV EBX, KbdMainExch		;Yes - ISend Message to KbdTask
		PUSH EBX                    ;exchange to send to
		PUSH 0FFFFFFFFh             ;bogus msg
		PUSH 0FFFFFFFFh             ;bogus msg
		CALL FAR PTR _ISendMsg		;tell him to come and get it...
KbdExit:
		PUSH 1
		CALL FAR PTR _EndOfIRQ
	    POPAD
	    IRETD

;===============================================
;This gets one byte from the Kbd Buffer and returns it in AL
;Zero is returned if no key exists.
;
ReadKBDBuf PROC NEAR
		CLI
	    MOV ESI, pKbdOut		;Get ptr to next char to come out
	    MOV EAX, dKbdCnt		;See if there are any bytes
	    CMP EAX, 0
	    JE RdKBDone 			;No - Leave 0 in EAX
	    DEC dKbdCnt				;Yes - make cnt right
	    XOR EAX,EAX
	    MOV AL, BYTE PTR [ESI]			;Put byte in AL
	    INC ESI
	    CMP ESI, OFFSET rgbKbdBuf+20h	;past end yet?
	    JB RdKBDone
	    MOV ESI, OFFSET rgbKbdBuf	;Back to beginning of buffer
RdKBDone:
	    MOV pKbdOut, ESI			;Save ptr to next char to come out
	    STI
		RETN
ReadKbdBuf ENDP
;
;========================================================
;
; Reads and processes all bytes from the RAW keyboard buffer
; and places them and their proper state bytes and into the next DWord
; in the translated buffer if it is an edit key.

XLateRawKBD:
	    CALL ReadKbdBuf
	    CMP EAX, 0
	    JE XLateDone			;No

	    MOV BL, bKbdMode		;See if we are RAW... (for testing ONLY)
	    CMP BL, 1
	    JNE KB001				;NO - keep going
	    JMP XLateDone			;Yes, leave the key in AL

		;Now we check to see if the byte is 0Eh which tells us
		;this is a two key code that needs to be translated from
		;our special table before processing.  This turns the
		;two key code into a single code and sets a state
		;bit to indicate this.

KB001:
	    CMP AL, 0E0h			;Key PREFIX???
	    JNE KB006				;NO...
	    MOV ECX, 50 			;Try 50 times to get second char
KB002:
	    CALL ReadKbdBuf
	    CMP EAX, 0
	    JNE KB003				;We got another char
	    LOOP KB002				;Back to get another char
	    JMP XLateDone			;Guess one isn't comming...

KB003:
	    MOV ESI, OFFSET KbdTable2
	    MOV ECX, nKbdTable2
KB004:
	    CMP BYTE PTR [ESI], AL
	    JE	KB005
	    INC ESI					;Two byte further into table 2
	    INC ESI
	    DEC ECX
	    JNZ KB004				;Go to next table entry
	    JMP KB006

KB005:
	    INC ESI					;One byte further over to get Xlate byte
	    XOR EAX,EAX
	    MOV AL, [ESI]			;Fall thru to check on char...

      ;This next section checks for special keys (shift, alt, etc.)
      ;BL has SHIFT state, CL has LOCK State, AL has byte from buffer.

KB006:
	    XOR EBX, EBX
	    XOR ECX, ECX
	    MOV BL, KbdState		;BL has Shift, Alt, Ctrl states
	    MOV CL, KbdLock			;BH has Num, Caps, & Scroll Lock

	    CMP AL, 45h 			;Key = NumLock ?
	    JNE KB007				;NO...
	    BTC ECX, NmLockBit		;Compliment bit
	    JMP KB022
KB007:
	    CMP AL, 3Ah 			;Caps Lock?
	    JNE KB008
	    BTC ECX, CpLockBit		;Compliment bit in BH
	    JMP KB022
KB008:
	    CMP AL, 46h 			;Scroll Lock?
	    JNE KB009
	    BTC ECX, ScLockBit		;Compliment bit in BH
	    JMP KB022
KB009:
	    CMP AL, 2Ah 			;Char Left Shift On?
	    JNE KB010
	    BTS EBX, ShftLeftBit
	    JMP KB021
KB010:
	    CMP AL, 36h 			;Right Shift On?
	    JNE KB011
	    BTS EBX, ShftRiteBit
	    JMP KB021
KB011:
	    CMP AL, 0AAh			;Left Shift Off?
	    JNE KB012
	    BTR EBX, ShftLeftBit
	    JMP KB021

KB012:
	    CMP AL, 0B6h			;Right Shift Off?
	    JNE KB013
	    BTR EBX, ShftRiteBit
	    JMP KB021

KB013:
	    CMP AL, 1Dh 			;Left Ctrl On?
	    JNE KB014
	    BTS EBX, CtrlLeftBit
	    JMP KB021

KB014:
	    CMP AL, 71h 			;Right Ctrl On?
	    JNE KB015
	    BTS EBX, CtrlRiteBit
	    JMP KB021

KB015:
	    CMP AL, 09Dh			;Left Ctrl Off?
	    JNE KB016
	    BTR EBX, CtrlLeftBit
	    JMP KB021

KB016:
	    CMP AL, 0F1h			;Right Ctrl Off?
	    JNE KB017
	    BTR EBX, CtrlRiteBit
	    JMP KB021
KB017:
	    CMP AL, 38h 			;Left Alt On?
	    JNE KB018
	    BTS EBX, AltLeftBit
	    JMP KB021
KB018:
	    CMP AL, 70h 			;Right Alt On?
	    JNE KB019
	    BTS EBX, AltRiteBit
	    JMP KB021
KB019:
	    CMP AL, 0B8h			;Left Alt Off?
	    JNE KB020
	    BTR EBX, AltLeftBit
	    JMP KB021
KB020:
	    CMP AL, 0F0h			;Right Alt Off?
	    JNE KB023
	    BTR EBX, AltRiteBit
KB021:
	    MOV KbdState, BL		;Put Kbd Shift State back
	    JMP XLateDone 			;
KB022:
	    MOV KbdLock, CL			;Put Kbd Lock State back
	    CALL SetKbdLEDS			;Set LEDs on keyboard
	    JMP XLateRawKBD			;

		;We jumped here if it wasn't a key that is specially handled

KB023:
	    TEST AL,  80h			;Check for high bit (key-up code)
	    JNZ	 XLateDone 			;Go back, else fall through

	    OR AL,AL				;Zero not a valid code
	    JZ XLateDone 			;Go back, else fall through

       ;If we got here, IT'S AN EDIT KEY DOWN!
       ;Now we lookup the code and do a single translation.

	    AND EAX, 0FFh				;Chop off any upper bit junk
	    MOV ESI, OFFSET KbdTable	;Set up to index table
	    MOV DL, BYTE PTR [ESI+EAX]	;Save in DL
	    OR AL,AL					;Zero not a valid code
	    JZ XLateDone 				;Go back, else fall through

	    MOV CL, KbdState			;Get Shift state
	    MOV CH, KbdLock				;Get lock state

		;TO let the user know if the key came from the Numeric
		;keypad we set the high bits in the first translation
		;table for these keys.  This next piece of code tests for it
		;and sets the low bit in DH if it its. DH is later moved
		;into the high byte of the returned key code.

		MOV DH, 0
		TEST DL, 80h				;High bit set?
		MOV DH, 1					;Indicates key came numeric pad

		;See if shift key is down and shift all keys it is is

		TEST CL, ShftDownMask		;Either shift key down?
		JZ KB025					;No, go look for locks
		JMP SHORT KB027				;Yes, go do the translation

KB025:  ;See if key is from Numerc Keypad (high bit will be set)

		TEST DL, 80h				;High bit set?
		JZ KB026					;No
		AND CH, NmLockMask			;Yes, is NumLock ON
		JZ KB026
		CMP DL, 0ADh				;Do not shift DASH (-) Special Case
		JE KB026
		JMP SHORT KB027				;Do the shift Xlation

KB026:	;See if Caps Lock is on and if key is between 61h and 7Ah
		;do the translation

		TEST CH, CpLockMask			;Is CpLock ON
		JZ KB029					;No
		CMP DL, 61h					;Is key >= 'a'
		JB KB029					;No
		CMP DL, 7Ah					;Is key <= 'z'
		JA KB029					;No
		;Fall through to do the translation

KB027:	;Do the shift translation and leave in DL
		MOV	AL, DL					;Put in AL
		AND EAX, 07Fh				;Chop all above 7 bits
	    MOV ESI, OFFSET KbdTableS	;Set up to index table
	    MOV DL, BYTE PTR [ESI+EAX]	;Save in DL
		;Fall though to put key in final buffer

       ;Place DL in the LOW byte of the DWord to go into the
       ;final buffer (the data the user will get)
       ;If the high bit is set comming from the primary
       ;translation table, this means the key was from the
       ;numeric keypad so we set the numpad bit in status
KB029:
		MOV AH, DH
		SHL EAX, 8				;Num Pad indicator
	    MOV AL, KbdState		;Get Shift state
	    MOV AH, KbdLock			;Get lock state
	    SHL EAX, 8
		AND DL, 7Fh				;Lop of high bit (if there)
	    MOV AL, DL

		;EAX now has the buffered info for the user (Key, Shifts & Locks)
		;Now we put it in the DWord buffer if it is NOT a GLOBAL.
		;If global, we put it in dGlobalKey.

		TEST AH, CtrlDownMask		;Either Ctrl Down?
		JZ KB029A					;No
		TEST AH, AltDownMask		;Either Alt Down?
		JZ KB029A					;No

		;It IS a global key request!
		MOV dGlobalKey, EAX			;Save it
	    JMP  XLateRawKBD			;Back for more (if there is any)

KB029A:
	    MOV  EBX, dKBCnt			;See if buffer full
	    CMP  EBX, 64				;number of DWords in final buffer
	    JE   XLateDone 				;Buffer is FULL..
	    MOV  ESI, pKBIn				;Get ptr to next IN to final buffer
	    MOV  [ESI], EAX				;Move into buf
	    INC  dKBCnt					;One more DWord in the buf
		ADD  ESI, 4
	    CMP  ESI, OFFSET rgdKBBuf+100h
	    JB   KB030
	    MOV  ESI, OFFSET rgdKBBuf	;Reset to buf beginning
KB030:
	    MOV  pKBIn, ESI			;Save ptr to next in
	    JMP  XLateRawKBD
XlateDone:
		XOR EAX, EAX
	    RETN

;========================================================
;
; Returns a keyboard code from FINAL keyboard buffer.
; Returns zero in EAX if buffer is empty.
;
; IN :  Nothing
; OUT:  EAX has Key or 0 if none
; USED: EAX, ESI
; MODIFIES: dKBCnt, pKBOut
;
ReadKBFinal:
		MOV EAX, dKBCnt
		CMP EAX, 0
		JE KBFDone					;Nothing final buffer
	    DEC dKBCnt					;One more DWord in the buf
		MOV ESI, pKBOut				;ptr to next code out
		MOV EAX, [ESI]				;Put it in EAX
		ADD ESI, 4					;Next code please...
	    CMP ESI, OFFSET rgdKBBuf+100h	;Past end of buff?
	    JB  KBF02					;No
	    MOV	ESI, OFFSET rgdKBBuf	;Yes, Reset to beginning
KBF02:
	    MOV pKBOut, ESI				;Update pKBOut
KBFDone:
	    RETN

;========================================================
;
; This is the keyboard Service task. It is an infinite loop
; that services requests from users of the keyboard.  It
; calls XLateRawKBD to process raw keyboard buffer data,
; and waits at the KeyBoard Service Main Exchange for users.
; When it gets a request it checks the service code and handles
; it accordingly.

KBDServiceTask:
		CALL XLateRawKBD			;Processes RAW buffer if not empty

		CMP dGlobalKey, 0
		JE  KST01					;No global key came in
KBDGlobal1:
		PUSH KbdGlobExch
		PUSH OFFSET KbdMsgBuf1L		;Where to return pRqBlk
		CALL FAR PTR _CheckMsg		;Check to see if RqWaiting
		OR EAX, EAX					;Yes if ZERO
		JZ KBDGlobal2				;Rq waiting for global
		MOV dGlobalKey, 0			;Wipe out global key (no one wants it)
		JMP KBDServiceTask			;Start over again

KBDGlobal2:
		MOV EBX, KbdMsgBuf1L		;pRqBlk into EBX
		MOV ESI, [EBX.pData1]		;Ptr where to return key
		OR ESI, ESI					;Is it null?? (Bad news if so)
		JNZ KBDGlobal3				;No, probably good ptr
		PUSH EBX					;Yes, BAD PTR. Push pRqBlk
		PUSH ErcNullPtr				;Push error
		CALL FAR PTR _Respond
		JMP KBDServiceTask			;Go back to the top
KBDGlobal3:
		MOV EDX, dGlobalKey
		MOV [ESI], EDX				;Give em the key!
		PUSH EBX					;Push pRqBlk
		PUSH 0						;Push NO ERROR
		CALL FAR PTR _Respond
		JMP KBDGlobal1				;Go back to see if other want it

KST01:
		CMP ddVidOwner, 2			;Debugger has video
		JNE	KST01ND					;NOT in Debugger
		PUSH 20
		CALL FAR PTR _Sleep			;
		CALL XLateRawKBD			;Processes RAW buffer
		JMP KBDServiceTask			;Go back to the top

KST01ND:
		PUSH KbdMainExch			;See if someones "Requesting"
		PUSH OFFSET KbdMsgBuf1L		;
		CALL FAR PTR _WaitMsg		;Wait for the message

		;If we got here we got a Request or Msg from ISR
		CMP KbdMsgBuf1L, 0FFFFFFFFh	;Is it a msg from the KBD ISR?
		JNE KST02					;No, jump to handle Request

		;If we got here, ISR sent msg to us (something in the buffer)

		CALL XLateRawKBD			;Processes RAW buffer

		CMP dGlobalKey, 0
		JNE KBDGlobal1				;A global key came in

		PUSH KbdWaitExch			;See if owner is waiting for a key
		PUSH OFFSET KbdMsgBuf1L		;Where to return Request or msg
		CALL FAR PTR _CheckMsg		;Check to see if another msg came in
		OR EAX, EAX					;Yes if ZERO
		JNZ KBDServiceTask			;No Rq/Msg waiting, Go back to the top
									;Fall thru to check request
KST02:
		;If we got here we've got a Request from Main or Wait Exch

		MOV EBX, KbdMsgBuf1L		;pRqBlk into EBX
		MOV CX, [EBX.ServiceCode]	;Save in CX

		CMP CX, 0					;Job Abort Notify
		JE KSTAbort					;
		CMP CX, 1					;ReadKbd
		JE KSTRead					;
		CMP CX, 2					;ReadKbdGlobal
		JE KSTReadGlobal			;
		CMP CX, 3					;CancelGlobal
		JE KSTCancelGlobal			;
		CMP CX, 4					;AssignKBD
		JE KSTAssignKbd				;

		PUSH EBX					;HOMEY DON'T SERVICE THAT!
		PUSH ErcBadSvcCode			;Bad service code
		CALL FAR PTR _Respond
		JMP KBDServiceTask			;Go back to the top

KSTRead:
		MOV EAX, [EBX.RqOwnerJob]	;Who's Request is it?
		CMP EAX, KbdOwner
		JE KSTRead00				;This guy owns it!
		PUSH EBX					;Not the owner, so send to Hold Exch
		PUSH KbdHoldExch			;
		CALL FAR PTR _MoveRequest
		JMP KBDServiceTask			;Go back to the top
KSTRead00:
		CALL ReadKBFinal			;Get Code from Buf (Uses EAX, ESI)
		CMP EAX, 0					;No Key in Final Buffer
		JE KSTRead02				;Go see if they asked to wait
		MOV ESI, [EBX.pData1]		;Ptr where to return key
		CMP ESI, 0					;Is it null?? (Bad news if so)
		JNE KSTRead01				;No, probably good ptr
		PUSH EBX					;Yes, BAD PTR. Push pRqBlk
		PUSH ErcNullPtr				;Push error
		CALL FAR PTR _Respond
		JMP KBDServiceTask			;Go back to the top
KSTRead01:
		MOV [ESI], EAX				;Give them the key code
		PUSH EBX					;RqHandle
		PUSH 0						;NO Error
		CALL FAR PTR _Respond
		JMP KBDServiceTask			;Go back to the top

KSTRead02:
		CMP [EBX.dData0], 0			;Wait for key?  0 in dData0 = Don't wait
		JNE KSTRead04				;Yes
		PUSH EBX
		PUSH ErcNoKeyAvail			;Error Code (No key to give you)
		CALL FAR PTR _Respond
		JMP KBDServiceTask			;Go back to the top

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -