Залипание клавиш

Тема в разделе "WASM.HARDWARE", создана пользователем Jin X, 19 июн 2018.

  1. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Продолжаю клавиатурную тему :)
    Есть прога, которая показывает нажатые клавиши (т.е. жмём все 4 стрелки – видим, что все 4 нажаты, отпускаем по одной, видим 3, 2, 1, 0).
    Так вот, если быстро стукнуть по нескольким клавишам (по тем же стрелкам, например), получаем генерацию IRQ 1 с нажатием 4-х клавиш и следом IRQ 1 с отпусканием... не всегда 4-х, а чаще 3-х или 2-х. Соответственно, 1 или 2 клавиши продолжают отображаться как нажатые.
    Причём, при запуске из-под винды (DOSBox, VMware+FreeDOS) такого нет, только в чистом DOS'е.

    Но тут есть один интересный момент. При таком же быстром ударе по Ctrl, Alt и Shift происходит то же самое (что неудивительно), при этом если я делаю это в каком-нибудь Volcov Commander, то вижу, что строка с помощью по функциональным клавишам остаётся в состоянии Shift или Alt, к примеру. Но! Если я нажму на букву, то эта буква будет воспроизведена как обычная буква, без Shift или Alt. Значит, BIOS каким-то образом понимает (в момент нажатия на букву, судя по всему), что Shift или Alt всё же отпущен. Как он это понимает?
     
  2. ReEnAsm

    ReEnAsm New Member

    Публикаций:
    0
    Регистрация:
    27 фев 2011
    Сообщения:
    5
    Вот так:
    Код (ASM):
    1. TITLE 01/04/84 KEYBOARD BIOS
    2. .XLIST
    3. INCLUDE DSEG.SRC
    4. INCLUDE POSTEQU.SRC
    5. .LIST
    6.  
    7. PUBLIC   KEYBOARD_IO_1
    8. PUBLIC   KB_INT_1
    9. PUBLIC   K16
    10.  
    11. INCLUDE SEGMENT.SRC
    12.  
    13. EXTRN   DDS:NEAR
    14. EXTRN   START_1:NEAR
    15. EXTRN   K6:BYTE
    16. EXTRN   K6L:ABS
    17. EXTRN   K7:BYTE
    18. EXTRN   K8:BYTE
    19. EXTRN   K9:BYTE
    20. EXTRN   K10:BYTE
    21. EXTRN   K11:BYTE
    22. EXTRN   K12:BYTE
    23. EXTRN   K13:BYTE
    24. EXTRN   K14:BYTE
    25. EXTRN   K15:BYTE
    26.  
    27. ;---- INT 16 ---------------------------------------------------------
    28. ; KEYBOARD I/O
    29. ;   THESE ROUTINES PROVIDE KEYBOARD SUPPORT
    30. ; INPUT
    31. ;   (AH)=0   READ THE NEXT ASCII CHARACTER STRUCK FROM THE KEYBOARD
    32. ;     RETURN THE RESULT IN (AL), SCAN CODE IN (AH)
    33. ;   (AH)=1   SET THE Z FLAG TO INDICATE IF AN ASCII CHARACTER IS AVAILABLE
    34. ;     TO BE READ.
    35. ;     (ZF)=1 -- NO CODE AVAILABLE
    36. ;     (ZF)=0 -- CODE IS AVAILABLE
    37. ;     IF ZF = 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS
    38. ;     IN AX, AND THE ENTRY REMAINS IN THE BUFFER
    39. ;   (AH)=2   RETURN THE CURRENT SHIFT STATUS IN AL REGISTER
    40. ;     THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE
    41. ;     EQUATES FOR KB_FLAG
    42. ; OUTPUT
    43. ;   AS NOTED ABOVE, ONLY AX AND FLAGS CHANGED
    44. ;   ALL REGISTERS RETAINED
    45. ;----------------------------------------
    46.    ASSUME   CS:CODE,DS:DATA
    47.  
    48. KEYBOARD_IO_1   PROC   FAR    ;>>> ENTRY POINT FOR ORG 0E82EH
    49.    STI       ; INTERRUPTS BACK ON
    50.    PUSH   DS     ; SAVE CURRENT DS
    51.    PUSH   BX     ; SAVE BX TEMPORARILY
    52.    CALL   DDS     ; ESTABLISH POINTER TO DATA REGION
    53.    OR   AH,AH     ; AH=0
    54.    JZ   K1B     ; ASCII_READ
    55.    DEC   AH     ; AH=1
    56.    JZ   K2     ; ASCII_STATUS
    57.    DEC   AH     ; AH=2
    58.    JZ   K3     ; SHIFT_STATUS
    59.    POP   BX     ; RECOVER REGISTER
    60.    POP   DS
    61.    IRET       ; INVALID COMMAND
    62.  
    63. ;------ READ THE KEY TO FIGURE OUT WHAT TO DO
    64.  
    65. K1B:   MOV   BX,BUFFER_HEAD   ; GET POINTER TO HEAD OF BUFFER
    66.    CMP   BX,BUFFER_TAIL   ; TEST END OF BUFFER
    67.    JNE   K1C     ; IF ANYTHING IN BUFFER DONT DO INTERRUPT
    68. ;
    69.    MOV   AX,09002H   ; MOVE IN WAIT CODE & TYPE
    70.    INT   15H     ; PERFORM OTHER FUNCTION
    71. K1:         ; ASCII READ
    72.    STI       ; INTERRUPTS BACK ON DURING LOOP
    73.    NOP       ; ALLOW AN INTERRUPT TO OCCUR
    74. K1C:   CLI       ; INTERRUPTS BACK OFF
    75.    MOV   BX,BUFFER_HEAD   ; GET POINTER TO HEAD OF BUFFER
    76.    CMP   BX,BUFFER_TAIL   ; TEST END OF BUFFER
    77.    PUSH   BX     ; SAVE ADDRESS
    78.    PUSHF       ; SAVE FLAG
    79.    CALL   MAKE_LED   ; GO GET MODE INDICATOR DATA BYTE
    80.    MOV   BL,KB_FLAG_2   ; GET PREVIOUS BITS
    81.    XOR   BL,AL     ; SEE IF ANY DIFFERENT
    82.    AND   BL,07H     ; ISOLATE INDICATOR BITS
    83.    JZ   K1A     ; IF NO CHANGE BYPASS UPDATE
    84. ;
    85.    CALL   SND_LED1   ; GO TURN ON MODE INDICATORS
    86.    CLI       ; DISABLE INTERRUPTS
    87. K1A:   POPF       ; RESTORE FLAGS
    88.    POP   BX     ; RESTORE ADDRESS
    89.    JZ   K1     ; LOOP UNTIL SOMETHING IN BUFFER
    90. ;
    91.    MOV   AX,[BX]    ; GET SCAN CODE AND ASCII CODE
    92.    CALL   K4     ; MOVE POINTER TO NEXT POSITION
    93.    MOV   BUFFER_HEAD,BX   ; STORE VALUE IN VARIABLE
    94.  
    95.    POP   BX     ; RECOVER REGISTER
    96.    POP   DS     ; RECOVER SEGMENT
    97.    IRET       ; RETURN TO CALLER
    98.  
    99. ;------ ASCII STATUS
    100.  
    101. K2:
    102.    CLI       ; INTERRUPTS OFF
    103.    MOV   BX,BUFFER_HEAD   ; GET HEAD POINTER
    104.    CMP   BX,BUFFER_TAIL   ; IF EQUAL (Z=1) THEN NOTHING THERE
    105.    MOV   AX,[BX]
    106.    PUSHF       ; SAVE FLAGS
    107. ;
    108.    PUSH   AX     ; SAVE CODE
    109.    CALL   MAKE_LED   ; GO GET MODE INDICATOR DATA BYTE
    110.    MOV   BL,KB_FLAG_2   ; GET PREVIOUS BITS
    111.    XOR   BL,AL     ; SEE IF ANY DIFFERENT
    112.    AND   BL,07H     ; ISOLATE INDICATOR BITS
    113.    JZ   SK2     ; IF NO CHANGE BYPASS UPDATE
    114. ;
    115.    CALL   SND_LED1   ; GO TURN ON MODE INDICATORS
    116. SK2:   POP   AX     ; RESTORE CODE
    117.    POPF       ; RESTORE FLAGS
    118.    STI       ; INTERRUPTS BACK ON
    119.    POP   BX     ; RECOVER REGISTER
    120.    POP   DS     ; RECOVER SEGMENT
    121.    RET   2     ; THROW AWAY FLAGS
    122.  
    123. ;------ SHIFT STATUS
    124.  
    125. K3:
    126.    MOV   AL,KB_FLAG   ; GET THE SHIFT STATUS FLAGS
    127.    POP   BX     ; RECOVER REGISTER
    128.    POP   DS     ; RECOVER REGISTERS
    129.    IRET       ; RETURN TO CALLER
    130. KEYBOARD_IO_1   ENDP
    131.  
    132. ;------ INCREMENT A BUFFER POINTER
    133.  
    134. K4   PROC   NEAR
    135.    INC   BX     ; MOVE TO NEXT WORD IN LIST
    136.    INC   BX
    137.    CMP   BX,BUFFER_END   ; AT END OF BUFFER?
    138.    JNE   K5     ; NO, CONTINUE
    139.    MOV   BX,BUFFER_START ; YES, RESET TO BUFFER BEGINNING
    140. K5:
    141.    RET
    142. K4   ENDP
    143.  
    144. ;------ KEYBOARD INTERRUPT ROUTINE
    145.  
    146. KB_INT_1 PROC   FAR
    147.    STI       ; ENABLE INTERRUPTS
    148.    PUSH   BP
    149.    PUSH   AX
    150.    PUSH   BX
    151.    PUSH   CX
    152.    PUSH   DX
    153.    PUSH   SI
    154.    PUSH   DI
    155.    PUSH   DS
    156.    PUSH   ES
    157.    CLD       ; FORWARD DIRECTION
    158.    CALL   DDS     ; SET UP ADDRESSING
    159.    MOV   AL,DIS_KBD   ; DISABLE THE KEYBOARD
    160.    CALL   SHIP_IT    ; EXECUTE DISABLE
    161.  
    162. ;------- WAIT FOR COMMAND TO ACCEPTED
    163.    CLI       ; DISABLE INTERRUPTS
    164.    SUB   CX,CX     ;
    165. KB_INT_01:
    166.    IN   AL,STATUS_PORT   ;
    167.    TEST   AL,INPT_BUF_FULL
    168.    LOOPNZ   KB_INT_01   ; WAIT FOR COMMAND TO BE ACCEPTED
    169.  
    170.    IN   AL,PORT_A   ; READ IN THE CHARACTER
    171.    STI       ; ENABLE INTERRUPTS AGAIN
    172.  
    173. ;--------CHECK FOR A RESEND COMMAND TO KEYBOARD
    174.  
    175.    CMP   AL,KB_RESEND   ; IS THE INPUT A RESEND
    176.    JE   KB_INT_4   ; GO IF RESEND
    177.  
    178. ;------- CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
    179.  
    180.    CMP   AL,KB_ACK   ; IS THE INPUT AN ACKNOWLEDGE
    181.    JNZ   KB_INT_2   ; GO IF NOT
    182.  
    183. ;------- A COMMAND TO THE KEYBOARD WAS ISSUED
    184.  
    185.    CLI       ; DISABLE INTERRUPTS
    186.    OR   KB_FLAG_2,KB_FA ; INDICATE ACK RECEIVED
    187.    JMP   K26     ; RETURN IF NOT (THIS ACK RETURNED FOR DATA)
    188.  
    189. ;-------- RESEND THE LAST BYTE
    190.  
    191. KB_INT_4:
    192.    CLI       ; DISABLE INTERRUPTS
    193.    OR   KB_FLAG_2,KB_FE ; INDICATE RESEND RECEIVED
    194.    JMP   K26     ; RETURN IF NOT (THIS ACK RETURNED FOR DATA)
    195.  
    196. KB_INT_2:
    197.  
    198. ;--------UPDATE MODE INDICATORS IF CHANGE IN STATE
    199.  
    200.    PUSH   AX     ; SAVE DATA IN
    201.    CALL   MAKE_LED   ; GO GET MODE INDICATOR DATA BYTE
    202.    MOV   BL,KB_FLAG_2   ; GET PREVIOUS BITS
    203.    XOR   BL,AL     ; SEE IF ANY DIFFERENT
    204.    AND   BL,07H     ; ISOLATE INDICATOR BITS
    205.    JZ   UP0     ; IF NO CHANGE BYPASS UPDATE
    206. ;
    207.    CALL   SND_LED    ; GO TURN ON MODE INDICATORS
    208. UP0:   POP   AX     ; RESTORE DATA IN
    209.    MOV   AH,AL     ; SAVE SCAN CODE IN AH ALSO
    210.  
    211. ;------ TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
    212.  
    213.    CMP   AL,KB_OVER_RUN   ; IS THIS AN OVERRUN CHAR
    214.    JNZ   K16     ; NO, TEST FOR SHIFT KEY
    215.    JMP   K62     ; BUFFER_FULL_BEEP
    216.  
    217. ;------ TEST FOR SHIFT KEYS
    218.  
    219. K16:         ; TEST_SHIFT
    220.    AND   AL,07FH    ; TURN OFF THE BREAK BIT
    221.    PUSH   CS
    222.    POP   ES     ; ESTABLISH ADDRESS OF SHIFT TABLE
    223.  
    224. ;------- TEST FOR SYSTEM KEY
    225.  
    226.    CMP   AL,SYS_KEY   ; IS IT THE SYSTEM KEY?
    227.    JNZ   K16A     ; CONTINUE IF NOT
    228. ;
    229.    TEST   AH,080H    ; CHECK IF THIS A BREAK CODE
    230.    JNZ   K16C     ; DONT TOUCH SYSTEM INDICATOR IF TRUE
    231. ;
    232.    TEST   KB_FLAG_1,SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN
    233.    JNZ   K16B     ; IF YES, DONT PROCESS SYSTEM INDICATOR
    234. ;
    235.    OR   KB_FLAG_1,SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
    236.    MOV   AL,EOI       ; END OF INTERRUPT COMMAND
    237.    OUT   020H,AL      ; SEND COMMAND TO INTERRUPT CONTROL PORT
    238.            ; INTERRUPT-RETURN-NO-EOI
    239.    MOV   AL,ENA_KBD     ; INSURE KEYBOARD IS ENABLED
    240.    CALL   SHIP_IT      ; EXECUTE ENABLE
    241.    MOV   AX,08500H   ; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
    242.    STI       ; MAKE SURE INTERRUPTS ENABLED
    243.    INT   15H     ; USER INTERRUPT
    244.    JMP   K27A     ; END PROCESSING
    245. K16B:   JMP   K26     ; IGNORE SYSTEM KEY
    246. ;
    247. K16C:   AND   KB_FLAG_1,NOT SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
    248.    MOV   AL,EOI       ; END OF INTERRUPT COMMAND
    249.    OUT   020H,AL      ; SEND COMMAND TO INTERRUPT CONTROL PORT
    250.            ; INTERRUPT-RETURN-NO-EOI
    251.    MOV   AL,ENA_KBD     ; INSURE KEYBOARD IS ENABLED
    252.    CALL   SHIP_IT      ; EXECUTE ENABLE
    253.    MOV   AX,08501H   ; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
    254.    STI       ; MAKE SURE INTERRUPTS ENABLED
    255.    INT   15H     ; USER INTERRUPT
    256.    JMP   K27A     ; IGNORE SYSTEM KEY
    257. ;
    258. K16A:   MOV   DI,OFFSET K6   ; SHIFT KEY TABLE
    259.    MOV   CX,OFFSET K6L   ; LENGTH
    260.    REPNE   SCASB     ; LOOK THROUGH THE TABLE FOR A MATCH
    261.    MOV   AL,AH     ; RECOVER SCAN CODE
    262.    JE   K17     ; JUMP IF MATCH FOUND
    263.    JMP   K25     ; IF NO MATCH, THEN SHIFT NOT FOUND
    264.  
    265. ;------ SHIFT KEY FOUND
    266.  
    267. K17:   SUB   DI,OFFSET K6+1   ; ADJUST PTR TO SCAN CODE MATCH
    268.    MOV   AH,CS:K7[DI]   ; GET MASK INTO AH
    269.    TEST   AL,80H     ; TEST FOR BREAK KEY
    270.    JZ   K17C     ; BREAK_SHIFT_FOUND
    271.    JMP   SHORT K23   ; CONTINUE
    272.  
    273. ;-------- DETERMINE SET OR TOGGLE
    274.  
    275. K17C:   CMP   AH,SCROLL_SHIFT
    276.    JAE   K18       ; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
    277.  
    278. ;------ PLAIN SHIFT KEY, SET SHIFT ON
    279.  
    280.    OR   KB_FLAG,AH     ; TURN ON SHIFT BIT
    281.    JMP   K26       ; INTERRUPT_RETURN
    282.  
    283. ;------ TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
    284.  
    285. K18:           ; SHIFT-TOGGLE
    286.    TEST   KB_FLAG, CTL_SHIFT   ; CHECK CTL SHIFT STATE
    287.    JZ   K18A       ; JUMP IF NOT CTL STATE
    288.  
    289.    JMP   K25
    290. K18A:   CMP   AL,INS_KEY     ; CHECK FOR INSERT KEY
    291.    JNZ   K22       ; JUMP IF NOT INSERT KEY
    292.    TEST   KB_FLAG, ALT_SHIFT   ; CHECK FOR ALTERNATE SHIFT
    293.    JZ   K19       ; JUMP IF NOT ALTERNATE SHIFT
    294.    JMP   K25     ; JUMP IF ALTERNATE SHIFT
    295. K19:   TEST   KB_FLAG, NUM_STATE   ; CHECK FOR BASE STATE
    296.    JNZ   K21       ; JUMP IF NUM LOCK IS ON
    297.    TEST   KB_FLAG, LEFT_SHIFT+RIGHT_SHIFT    ;
    298.    JZ   K22       ; JUMP IF BASE STATE
    299.  
    300. K20:           ; NUMERIC ZERO, NOT INSERT KEY
    301.    MOV   AX, 5230H     ; PUT OUT AN ASCII ZERO
    302.    JMP   K57       ; BUFFER_FILL
    303. K21:           ; MIGHT BE NUMERIC
    304.    TEST   KB_FLAG, LEFT_SHIFT+RIGHT_SHIFT    ;
    305.    JZ   K20       ; JUMP NUMERIC, NOT INSERT
    306.  
    307. K22:           ; SHIFT TOGGLE KEY HIT; PROCESS IT
    308.    TEST   AH,KB_FLAG_1     ; IS KEY ALREADY DEPRESSED
    309.    JZ   K22A0       ; GO IF NOT
    310.    JMP   SHORT K26     ; JUMP IF KEY ALREADY DEPRESSED
    311. K22A0:   OR   KB_FLAG_1,AH     ; INDICATE THAT THE KEY IS DEPRESSED
    312.    XOR   KB_FLAG,AH     ; TOGGLE THE SHIFT STATE
    313.  
    314. ;------- TOGGLE LED IF CAPS OR NUM KEY DEPRESSED
    315.  
    316.    TEST   AH,CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
    317.    JZ   K22B       ; GO IF NOT
    318.    PUSH   AX       ; SAVE SCAN CODE AND SHIFT MASK
    319.    CALL   SND_LED      ; GO TURN MODE INDICATORS ON
    320.    POP   AX       ; RESTORE SCAN CODE
    321.  
    322. K22B:   CMP   AL,INS_KEY     ; TEST FOR 1ST MAKE OF INSERT KEY
    323.    JNE   K26       ; JUMP IF NOT INSERT KEY
    324.    MOV   AX,INS_KEY*256     ; SET SCAN CODE INTO AH, 0 INTO AL
    325.    JMP   K57       ; PUT INTO OUTPUT BUFFER
    326.  
    327. ;------ BREAK SHIFT FOUND
    328.  
    329. K23:           ; BREAK-SHIFT-FOUND
    330.    CMP   AH,SCROLL_SHIFT    ; IS THIS A TOGGLE KEY
    331.    JAE   K24       ; YES, HANDLE BREAK TOGGLE
    332.    NOT   AH       ; INVERT MASK
    333.    AND   KB_FLAG,AH     ; TURN OFF SHIFT BIT
    334.    CMP   AL,ALT_KEY+80H     ; IS THIS ALTERNATE SHIFT RELEASE
    335.    JNE   K26       ; INTERRUPT_RETURN
    336.  
    337. ;------ ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
    338.  
    339.    MOV   AL,ALT_INPUT
    340.    MOV   AH,0       ; SCAN CODE OF 0
    341.    MOV   ALT_INPUT,AH     ; ZERO OUT THE FIELD
    342.    CMP   AL,0       ; WAS THE INPUT=0
    343.    JE   K26       ; INTERRUPT_RETURN
    344.    JMP   K58       ; IT WASN'T, SO PUT IN BUFFER
    345.  
    346. K24:           ; BREAK-TOGGLE
    347.    NOT   AH       ; INVERT MASK
    348.    AND   KB_FLAG_1,AH     ; INDICATE NO LONGER DEPRESSED
    349.    JMP   SHORT K26     ; INTERRUPT_RETURN
    350.  
    351. ;------ TEST FOR HOLD STATE
    352.  
    353. K25:           ; NO-SHIFT-FOUND
    354.    CMP   AL,80H       ; TEST FOR BREAK KEY
    355.    JAE   K26       ; NOTHING FOR BREAK CHARS FROM HERE ON
    356.    TEST   KB_FLAG_1,HOLD_STATE   ; ARE WE IN HOLD STATE
    357.    JZ   K28       ; BRANCH AROUND TEST IF NOT
    358.    CMP   AL,NUM_KEY
    359.    JE   K26       ; CAN'T END HOLD ON NUM_LOCK
    360.    AND   KB_FLAG_1,NOT HOLD_STATE   ; TURN OFF THE HOLD STATE BIT
    361.  
    362. K26:         ; INTERRUPT-RETURN
    363.    CLI       ; TURN OFF INTERRUPTS
    364.    MOV   AL,EOI     ; END OF INTERRUPT COMMAND
    365.    OUT   020H,AL    ; SEND COMMAND TO INTERRUPT CONTROL PORT
    366. K27:         ; INTERRUPT-RETURN-NO-EOI
    367.    MOV   AL,ENA_KBD   ; INSURE KEYBOARD IS ENABLED
    368.    CALL   SHIP_IT    ; EXECUTE ENABLE
    369.  
    370. K27A:   CLI       ; DISABLE INTERRUPTS
    371.    POP   ES     ; RESTORE REGISTERS
    372.    POP   DS     ; "
    373.    POP   DI     ; "
    374.    POP   SI     ; "
    375.    POP   DX     ; "
    376.    POP   CX     ; "
    377.    POP   BX     ; "
    378.    POP   AX     ; "
    379.    POP   BP     ; "
    380.    IRET       ; RETURN, INTERRUPTS ON WITH FLAG CHANGE
    381.  
    382. ;------ NOT IN   HOLD STATE
    383.  
    384. K28:         ; NO-HOLD-STATE
    385.    TEST   KB_FLAG,ALT_SHIFT ; ARE WE IN ALTERNATE SHIFT
    386.    JNZ   K29     ; JUMP IF ALTERNATE SHIFT
    387.    JMP   K38     ; JUMP IF NOT ALTERNATE
    388.  
    389. ;------ TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
    390.  
    391. K29:         ; TEST-RESET
    392.    TEST   KB_FLAG,CTL_SHIFT ; ARE WE IN CONTROL SHIFT ALSO
    393.    JZ   K31     ; NO RESET
    394.    CMP   AL,DEL_KEY   ; SHIFT STATE IS THERE, TEST KEY
    395.    JNE   K31     ; NO-RESET
    396.  
    397. ;------ CTL-ALT-DEL HAS BEEN FOUND, DO I/O CLEANUP
    398.  
    399.    MOV   RESET_FLAG, 1234H ; SET FLAG FOR RESET FUNCTION
    400.    JMP   START_1    ; JUMP TO POWER ON DIAGNOSTICS
    401.  
    402. ;------ ALT-INPUT-TABLE
    403. K30   LABEL   BYTE
    404.    DB   82,79,80,81,75,76,77
    405.    DB   71,72,73   ; 10 NUMBERS ON KEYPAD
    406. ;------ SUPER-SHIFT-TABLE
    407.    DB   16,17,18,19,20,21,22,23 ; A-Z TYPEWRITER CHARS
    408.    DB   24,25,30,31,32,33,34,35
    409.    DB   36,37,38,44,45,46,47,48
    410.    DB   49,50
    411.  
    412. ;------ IN ALTERNATE SHIFT, RESET NOT FOUND
    413.  
    414. K31:           ; NO-RESET
    415.    CMP   AL,57       ; TEST FOR SPACE KEY
    416.    JNE   K32       ; NOT THERE
    417.    MOV   AL,' '  ; SET SPACE CHAR
    418.    JMP   K57       ; BUFFER_FILL
    419.  
    420. ;------ LOOK FOR KEY PAD ENTRY
    421.  
    422. K32:           ; ALT-KEY-PAD
    423.    MOV   DI,OFFSET K30     ; ALT-INPUT-TABLE
    424.    MOV   CX,10       ; LOOK FOR ENTRY USING KEYPAD
    425.    REPNE   SCASB       ; LOOK FOR MATCH
    426.    JNE   K33       ; NO_ALT_KEYPAD
    427.    SUB   DI,OFFSET K30+1    ; DI NOW HAS ENTRY VALUE
    428.    MOV   AL,ALT_INPUT     ; GET THE CURRENT BYTE
    429.    MOV   AH,10       ; MULTIPLY BY 10
    430.    MUL   AH
    431.    ADD   AX,DI       ; ADD IN THE LATEST ENTRY
    432.    MOV   ALT_INPUT,AL     ; STORE IT AWAY
    433.    JMP   K26       ; THROW AWAY THAT KEYSTROKE
    434.  
    435. ;------ LOOK FOR SUPERSHIFT ENTRY
    436.  
    437. K33:           ; NO-ALT-KEYPAD
    438.    MOV   ALT_INPUT,0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
    439.    MOV   CX,26       ; DI,ES ALREADY POINTING
    440.    REPNE   SCASB       ; LOOK FOR MATCH IN ALPHABET
    441.    JNE   K34       ; NOT FOUND, FUNCTION KEY OR OTHER
    442.    MOV   AL,0       ; ASCII CODE OF ZERO
    443.    JMP   K57       ; PUT IT IN THE BUFFER
    444.  
    445. ;------ LOOK FOR TOP ROW OF ALTERNATE SHIFT
    446.  
    447. K34:           ; ALT-TOP-ROW
    448.    CMP   AL,2       ; KEY WITH '1' ON IT
    449.    JB   K35       ;  NOT ONE OF INTERESTING KEYS
    450.    CMP   AL,14       ;  IS IT IN THE REGION
    451.    JAE   K35       ;  ALT-FUNCTION
    452.    ADD   AH,118       ;  CONVERT PSEUDO SCAN CODE TO RANGE
    453.    MOV   AL,0       ;  INDICATE AS SUCH
    454.    JMP   K57       ;  BUFFER_FILL
    455.  
    456. ;------ TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
    457.  
    458. K35:           ; ALT-FUNCTION
    459.    CMP   AL,59       ; TEST FOR IN TABLE
    460.    JAE   K37       ; ALT-CONTINUE
    461. K36:           ; CLOSE-RETURN
    462.    JMP   K26       ; IGNORE THE KEY
    463. K37:           ; ALT-CONTINUE
    464.    CMP   AL,71       ; IN KEYPAD REGION
    465.    JAE   K36       ; IF SO, IGNORE
    466.    MOV   BX,OFFSET K13     ; ALT SHIFT PSEUDO SCAN TABLE
    467.    JMP   K63       ; TRANSLATE THAT
    468.  
    469. ;------ NOT IN ALTERNATE SHIFT
    470.  
    471. K38:           ; NOT-ALT-SHIFT
    472.    TEST   KB_FLAG,CTL_SHIFT   ; ARE WE IN CONTROL SHIFT
    473.    JZ   K44       ; NOT-CTL-SHIFT
    474.  
    475. ;------ CONTROL SHIFT, TEST SPECIAL CHARACTERS
    476. ;------ TEST FOR BREAK AND PAUSE KEYS
    477.    CMP   AL,SCROLL_KEY     ; TEST FOR BREAK
    478.    JNE   K39       ; NO-BREAK
    479.    MOV   BX,BUFFER_START    ; RESET BUFFER TO EMPTY
    480.    MOV   BUFFER_HEAD,BX
    481.    MOV   BUFFER_TAIL,BX
    482.    MOV   BIOS_BREAK,80H     ; TURN ON BIOS_BREAK BIT
    483.  
    484. ;-------- ENABLE KEYBOARD
    485.  
    486.    MOV   AL,ENA_KBD     ; ENABLE KEYBOARD
    487.    CALL   SHIP_IT      ; EXECUTE ENABLE
    488.    INT   1BH       ; BREAK INTERRUPT VECTOR
    489.    SUB   AX,AX       ; PUT OUT DUMMY CHARACTER
    490.    JMP   K57       ; BUFFER_FILL
    491.  
    492. K39:           ; NO_BREAK
    493.    CMP   AL,NUM_KEY     ; LOOK FOR PAUSE KEY
    494.    JNE   K41       ; NO-PAUSE
    495.    OR   KB_FLAG_1,HOLD_STATE   ; TURN ON THE HOLD FLAG
    496.  
    497. ;-----   ENABLE KEYBOARD
    498.  
    499.    MOV   AL,ENA_KBD     ; ENABLE KEYBOARD
    500.    CALL   SHIP_IT      ; EXECUTE ENABLE
    501.    MOV   AL,EOI       ; END OF INTERRUPT TO CONTROL PORT
    502.    OUT   020H,AL      ; ALLOW FURTHER KEYSTROKE INTS
    503.  
    504. ;------ DURING PAUSE INTERVAL, TURN CRT BACK ON
    505.  
    506.    CMP   CRT_MODE,7     ; IS THIS THE BLACK AND WHITE CARD
    507.    JE   K40       ; YES, NOTHING TO DO
    508.    MOV   DX,03D8H     ; PORT FOR COLOR CARD
    509.    MOV   AL,CRT_MODE_SET    ; GET THE VALUE OF THE CURRENT MODE
    510.    OUT   DX,AL       ; SET THE CRT MODE, SO THAT CRT IS ON
    511. K40:           ; PAUSE-LOOP
    512.  
    513. K40A:
    514.    TEST   KB_FLAG_1,HOLD_STATE
    515.    JNZ   K40       ; LOOP UNTIL FLAG TURNED OFF
    516.    JMP   K27A       ; INTERRUPT_RETURN_NO_EOI
    517. K41:           ; NO-PAUSE
    518.  
    519. ;------ TEST SPECIAL CASE KEY 55
    520.  
    521.    CMP   AL,55
    522.    JNE   K42       ; NOT-KEY-55
    523.    MOV   AX,114*256     ; START/STOP PRINTING SWITCH
    524.    JMP   K57       ; BUFFER_FILL
    525.  
    526. ;------ SET UP TO TRANSLATE CONTROL SHIFT
    527.  
    528. K42:           ; NOT-KEY-55
    529.    MOV   BX,OFFSET K8     ; SET UP TO TRANSLATE CTL
    530.    CMP   AL,59       ; IS IT IN TABLE
    531.    JB   K56       ; YES, GO TRANSLATE CHAR
    532.            ; CTL-TABLE-TRANSLATE
    533.    MOV   BX,OFFSET K9     ; CTL TABLE SCAN
    534.    JMP   K63       ; TRANSLATE_SCAN
    535.  
    536. ;------ NOT IN CONTROL SHIFT
    537.  
    538. K44:           ; NOT-CTL-SHIFT
    539.  
    540.    CMP   AL,71       ; TEST FOR KEYPAD REGION
    541.    JAE   K48       ; HANDLE KEYPAD REGION
    542.    TEST   KB_FLAG,LEFT_SHIFT+RIGHT_SHIFT
    543.    JZ   K54       ; TEST FOR SHIFT STATE
    544.  
    545. ;------ UPPER CASE, HANDLE SPECIAL CASES
    546.  
    547.    CMP   AL,15       ; BACK TAB KEY
    548.    JNE   K45       ; NOT-BACK-TAB
    549.    MOV   AX,15*256     ; SET PSEUDO SCAN CODE
    550.    JMP   SHORT K57     ; BUFFER_FILL
    551.  
    552. K45:           ; NOT-BACK-TAB
    553.    CMP   AL,55       ; PRINT SCREEN KEY
    554.    JNE   K46       ; NOT-PRINT-SCREEN
    555.  
    556. ;------ ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
    557.  
    558.    MOV   AL,ENA_KBD     ; INSURE KEYBOARD IS ENABLED
    559.    CALL   SHIP_IT      ; EXECUTE ENABLE
    560.    MOV   AL,EOI       ; END OF CURRENT INTERRUPT
    561.    OUT   020H,AL      ;  SO FURTHER THINGS CAN HAPPEN
    562.    PUSH   BP       ; SAVE POINTER
    563.    INT   5H       ; ISSUE PRINT SCREEN INTERRUPT
    564.    POP   BP       ; RESTORE POINTER
    565.    JMP   K27       ; GO BACK WITHOUT EOI OCCURRING
    566.  
    567. K46:           ; NOT-PRINT-SCREEN
    568.    CMP   AL,59       ; FUNCTION KEYS
    569.    JB   K47       ; NOT-UPPER-FUNCTION
    570.    MOV   BX,OFFSET K12     ; UPPER CASE PSEUDO SCAN CODES
    571.    JMP   K63       ; TRANSLATE_SCAN
    572.  
    573. K47:           ; NOT-UPPER-FUNCTION
    574.    MOV   BX,OFFSET K11     ; POINT TO UPPER CASE TABLE
    575.    JMP   SHORT K56     ; OK, TRANSLATE THE CHAR
    576.  
    577. ;------ KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
    578.  
    579. K48:           ; KEYPAD-REGION
    580.    TEST   KB_FLAG,NUM_STATE   ; ARE WE IN NUM LOCK
    581.    JNZ   K52       ; TEST FOR SURE
    582.    TEST   KB_FLAG,LEFT_SHIFT+RIGHT_SHIFT   ; ARE WE IN SHIFT STATE
    583.    JNZ   K53       ; IF SHIFTED, REALLY NUM STATE
    584.  
    585. ;------ BASE CASE FOR KEYPAD
    586.  
    587. K49:           ; BASE-CASE
    588.            ;
    589.    CMP   AL,74       ; SPECIAL CASE FOR A COUPLE OF KEYS
    590.    JE   K50       ; MINUS
    591.    CMP   AL,78
    592.    JE   K51
    593.    SUB   AL,71       ; CONVERT ORIGIN
    594.    MOV   BX,OFFSET K15     ; BASE CASE TABLE
    595.    JMP   K64       ; CONVERT TO PSEUDO SCAN
    596.  
    597. K50:   MOV   AX,74*256+'-'  ; MINUS
    598.    JMP   SHORT K57     ; BUFFER_FILL
    599.  
    600. K51:   MOV   AX,78*256+'+'  ; PLUS
    601.    JMP   SHORT K57     ; BUFFER_FILL
    602.  
    603. ;------ MIGHT BE NUM LOCK, TEST SHIFT STATUS
    604.  
    605. K52:           ; ALMOST-NUM-STATE
    606.    TEST   KB_FLAG,LEFT_SHIFT+RIGHT_SHIFT
    607.    JNZ   K49       ; SHIFTED TEMP OUT OF NUM STATE
    608.  
    609. K53:           ; REALLY NUM STATE
    610.    SUB   AL,70       ; CONVERT ORIGIN
    611.    MOV   BX,OFFSET K14     ; NUM STATE TABLE
    612.    JMP   SHORT K56     ; TRANSLATE_CHAR
    613.  
    614. ;------ PLAIN OLD LOWER CASE
    615.  
    616. K54:           ; NOT-SHIFT
    617.    CMP   AL,59       ; TEST FOR FUNCTION KEYS
    618.    JB   K55       ; NOT-LOWER-FUNCTION
    619.    MOV   AL,0       ; SCAN CODE IN AH ALREADY
    620.    JMP   SHORT K57     ; BUFFER_FILL
    621.  
    622. K55:           ; NOT-LOWER-FUNCTION
    623.    MOV   BX,OFFSET K10     ; LC TABLE
    624.  
    625. ;------ TRANSLATE THE CHARACTER
    626.  
    627. K56:           ; TRANSLATE-CHAR
    628.    DEC   AL       ; CONVERT ORIGIN
    629.    XLAT   CS:K11       ; CONVERT THE SCAN CODE TO ASCII
    630.  
    631. ;------ PUT CHARACTER INTO BUFFER
    632.  
    633. K57:           ; BUFFER_FILL
    634.    CMP   AL,-1       ; IS THIS AN IGNORE CHAR
    635.    JE   K59       ; YES, DO NOTHING WITH IT
    636.    CMP   AH,-1       ; LOOK FOR -1 PSEUDO SCAN
    637.    JE   K59       ; NEAR_INTERRUPT_RETURN
    638.  
    639. ;------ HANDLE THE CAPS LOCK PROBLEM
    640.  
    641. K58:           ; BUFFER_FILL-NOTEST
    642.    TEST   KB_FLAG,CAPS_STATE   ; ARE WE IN CAPS LOCK STATE
    643.    JZ   K61       ; SKIP IF NOT
    644.  
    645. ;------ IN CAPS LOCK STATE
    646.  
    647.    TEST   KB_FLAG,LEFT_SHIFT+RIGHT_SHIFT   ; TEST FOR SHIFT STATE
    648.    JZ   K60       ; IF NOT SHIFT, CONVERT LOWER TO UPPER
    649.  
    650. ;------ CONVERT ANY UPPER CASE TO LOWER CASE
    651.  
    652.    CMP   AL,'A'  ; FIND OUT IF ALPHABETIC
    653.    JB   K61       ; NOT-CAPS-STATE
    654.    CMP   AL,'Z'
    655.    JA   K61       ; NOT_CAPS STATE
    656.    ADD   AL,'a'-'A'  ; CONVERT TO LOWER CASE
    657.    JMP   SHORT K61     ; NOT_CAPS_STATE
    658.  
    659. K59:           ; NEAR-INTERRUPT-RETURN
    660.    JMP   K26       ; INTERRUPT_RETURN
    661.  
    662. ;------ CONVERT ANY LOWER CASE TO UPPER CASE
    663.  
    664. K60:           ; LOWER-TO-UPPER
    665.    CMP   AL,'a'  ; FIND OUT IF ALPHABETIC
    666.    JB   K61       ; NOT_CAPS_STATE
    667.    CMP   AL,'z'
    668.    JA   K61       ; NOT CAPS STATE
    669.    SUB   AL,'a'-'A'  ; CONVERT TO UPPER CASE
    670.  
    671. K61:           ; NOT-CAPS-STATE
    672.    MOV   BX,BUFFER_TAIL     ; GET THE END POINTER TO THE BUFFER
    673.    MOV   SI,BX       ; SAVE THE VALUE
    674.    CALL   K4       ; ADVANCE THE TAIL
    675.    CMP   BX,BUFFER_HEAD     ; HAS THE BUFFER WRAPPED AROUND
    676.    JE   K62       ; BUFFER_FULL_BEEP
    677.    MOV   [SI],AX      ; STORE THE VALUE
    678.    MOV   BUFFER_TAIL,BX     ; MOVE THE POINTER UP
    679.    CLI         ; TURN OFF INTERRUPTS
    680.    MOV   AL,EOI       ; END OF INTERRUPT COMMAND
    681.    OUT   020H,AL      ; SEND COMMAND TO INTERRUPT CONTROL PORT
    682.    MOV   AL,ENA_KBD     ; INSURE KEYBOARD IS ENABLED
    683.    CALL   SHIP_IT      ; EXECUTE ENABLE
    684.    MOV   AX,09102H     ; MOVE IN POST CODE & TYPE
    685.    INT   15H       ; PERFORM OTHER FUNCTION
    686.    JMP   K27A       ; INTERRUPT_RETURN
    687.  
    688.  
    689. ;------ TRANSLATE SCAN FOR PSEUDO SCAN CODES
    690.  
    691. K63:           ; TRANSLATE-SCAN
    692.    SUB   AL,59       ; CONVERT ORIGIN TO FUNCTION KEYS
    693. K64:           ; TRANSLATE-SCAN-ORGD
    694.    XLAT   CS:K9       ; CTL TABLE SCAN
    695.    MOV   AH,AL       ; PUT VALUE INTO AH
    696.    MOV   AL,0       ; ZERO ASCII CODE
    697.    JMP   K57       ; PUT IT INTO THE BUFFER
    698.  
    699. KB_INT_1   ENDP
    700.  
    701. K62:
    702.    MOV   AL,EOI     ; ENABLE INTR. CTL. CHIP
    703.    OUT   INTA00,AL   ;
    704.    MOV   BX,82H     ; NUMBER OF CYCLES FOR 1/8 SECOND TONE
    705.    IN   AL,KB_CTL   ; GET CONTROL INFORMATION
    706.    PUSH   AX     ; SAVE
    707. K65:         ; BEEP-CYCLE
    708.    AND   AL,0FCH    ; TURN OFF TIMER GATE AND SPEAKER DATA
    709.    JMP   SHORT $+2   ; IO DELAY
    710.    OUT   KB_CTL,AL   ; OUTPUT TO CONTROL
    711.    MOV   CX,0CEH    ; HALF CYCLE TIME FOR TONE
    712. K66:   LOOP   K66     ; SPEAKER OFF
    713.    OR   AL,2     ; TURN ON SPEAKER BIT
    714.    OUT   KB_CTL,AL   ; OUTPUT TO CONTROL
    715.    MOV   CX,0E5H    ; SET UP COUNT
    716. K67:   LOOP   K67     ; ANOTHER HALF CYCLE
    717.    DEC   BX     ; TOTAL TIME COUNT
    718.    JNZ   K65     ; DO ANOTHER CYCLE
    719.    POP   AX     ; RECOVER CONTROL
    720.    OUT   KB_CTL,AL   ; OUTPUT THE CONTROL
    721.    JMP   K27     ; EXIT
    722.  
    723. ;------------------------------------------------------------------------------
    724. ;
    725. ;   SND_DATA
    726. ;
    727. ;     THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
    728. ;     TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS.  IT ALSO
    729. ;     HANDLES ANY RETRIES IF REQUIRED
    730. ;
    731. ;------------------------------------------------------------------------------
    732.  
    733. SND_DATA PROC   NEAR
    734.    PUSH   AX     ; SAVE REGISTERS
    735.    PUSH   BX     ; "
    736.    PUSH   CX
    737.    MOV   BH,AL     ; SAVE TRANSMITTED BYTE FOR RETRIES
    738.    MOV   BL,3     ; LOAD RETRY COUNT
    739. SD0:   CLI       ; DISABLE INTERRUPTS
    740.    AND   KB_FLAG_2,NOT (KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
    741.  
    742. ;------- WAIT FOR COMMAND TO ACCEPTED
    743.  
    744.    SUB   CX,CX     ;
    745. SD5:
    746.    IN   AL,STATUS_PORT   ;
    747.    TEST   AL,INPT_BUF_FULL
    748.    LOOPNZ   SD5     ; WAIT FOR COMMAND TO BE ACCEPTED
    749. ;
    750.    MOV   AL,BH     ; REESTABLISH BYTE TO TRANSMIT
    751.    OUT   PORT_A,AL   ; SEND BYTE
    752.    STI       ; ENABLE INTERRUPTS
    753.    MOV   CX,01A00H   ; LOAD COUNT FOR 10 ms+
    754. SD1:   TEST   KB_FLAG_2,KB_FE+KB_FA ; SEE IF EITHER BIT SET
    755.    JNZ   SD3     ; IF SET, SOMETHING RECEIVED GO PROCESS
    756. ;
    757.    LOOP   SD1     ; OTHERWISE WAIT
    758. ;
    759. SD2:   DEC   BL     ; DECREMENT RETRY COUNT
    760.    JNZ   SD0     ; RETRY TRANSMISSION
    761. ;
    762.    OR   KB_FLAG_2,KB_ERR ; TURN ON TRANSMIT ERROR FLAG
    763.    JMP   SHORT SD4   ; RETRIES EXHAUSTED FORGET TRANSMISSION
    764. ;
    765. SD3:   TEST   KB_FLAG_2,KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
    766.    JZ   SD2     ; IF NOT, GO RESEND
    767. ;
    768. SD4:
    769.    POP   CX     ; RESTORE REGISTERS
    770.    POP   BX     ;
    771.    POP   AX     ; *
    772.    RET       ; RETURN, GOOD TRANSMISSION
    773. SND_DATA ENDP
    774.  
    775. ;------------------------------------------------------------------------------
    776. ;   SND_LED
    777. ;
    778. ;     THIS ROUTINES TURNS ON THE MODE INDICATORS.
    779. ;
    780. ;------------------------------------------------------------------------------
    781. SND_LED PROC   NEAR
    782.    CLI       ; TURN OFF INTERRUPTS
    783.    TEST   KB_FLAG_2,KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
    784.    JNZ   SL1     ; DONT UPDATE AGAIN IF UPDATE UNDERWAY
    785. ;
    786.    OR   KB_FLAG_2,KB_PR_LED ; TURN ON UPDATE IN PROCESS
    787.    MOV   AL,EOI     ; END OF INTERRUPT COMMAND
    788.    OUT   020H,AL    ; SEND COMMAND TO INTERRUPT CONTROL PORT
    789.    JMP   SHORT SL0   ; GO SEND MODE INDICATOR COMMAND
    790. ;
    791. SND_LED1:
    792.    CLI       ; TURN OFF INTERRUPTS
    793.    TEST   KB_FLAG_2,KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
    794.    JNZ   SL1     ; DONT UPDATE AGAIN IF UPDATE UNDERWAY
    795. ;
    796.    OR   KB_FLAG_2,KB_PR_LED ; TURN ON UPDATE IN PROCESS
    797. SL0:   MOV   AL,LED_CMD   ; LED CMD BYTE
    798.    CALL   SND_DATA   ; SEND DATA TO KEYBOARD
    799.    CLI       ;
    800.    CALL   MAKE_LED   ; GO FORM INDICATOR DATA BYTE
    801.    AND   KB_FLAG_2,0F8H   ; CLEAR MODE INDICATOR BITS
    802.    OR   KB_FLAG_2,AL   ; SAVE PRESENT INDICATORS STATES FOR NEXT TIME
    803.    TEST   KB_FLAG_2,KB_ERR ; TRANSMIT ERROR DETECTED
    804.    JNZ   SL2     ; IF YES, BYPASS SECOND BYTE TRANSMISSION
    805. ;
    806.    CALL   SND_DATA   ; SEND DATA TO KEYBOARD
    807.    CLI       ; TURN OFF INTERRUPTS
    808.    TEST   KB_FLAG_2,KB_ERR ; TRANSMIT ERROR DETECTED
    809.    JZ   SL3     ; IF NOT, DONT SEND AN ENABLE COMMAND
    810. ;
    811. SL2:   MOV   AL,KB_ENABLE   ; GET KEYBOARD CSA ENABLE COMMAND
    812.    CALL   SND_DATA   ; SEND DATA TO KEYBOARD
    813.    CLI       ; TURN OFF INTERRUPTS
    814. SL3:   AND   KB_FLAG_2,NOT(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
    815.          ; UPDATE AND TRANSMIT ERROR FLAG
    816. SL1:   STI       ; ENABLE INTERRUPTS
    817.    RET       ; RETURN TO CALLER
    818. SND_LED ENDP
    819.  
    820. ;------------------------------------------------------------------------------
    821. ;   MAKE_LED
    822. ;
    823. ;     THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
    824. ;     THE MODE INDICATORS
    825. ;
    826. ;------------------------------------------------------------------------------
    827. MAKE_LED PROC   NEAR
    828.    PUSH   CX     ; SAVE CX
    829.    MOV   AL,KB_FLAG   ; GET CAPS & NUM LOCK INDICATORS
    830.    AND   AL,CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
    831.    MOV   CL,4     ; SHIFT COUNT
    832.    ROL   AL,CL     ; SHIFT BITS OVER TO TURN ON INDICATORS
    833.    AND   AL,07H     ; MAKE SURE ONLY MODE BITS ON
    834.    POP   CX     ;
    835.    RET       ; RETURN TO CALLER
    836. MAKE_LED ENDP
    837. ;------------------------------------------------------------------------------
    838. ;   SHIP_IT
    839. ;
    840. ;     THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
    841. ;     TO THE KEYBOARD CONTROLLER.
    842. ;
    843. ;------------------------------------------------------------------------------
    844. SHIP_IT PROC   NEAR
    845.    PUSH   AX     ; SAVE DATA TO SEND
    846. ;------- WAIT FOR COMMAND TO ACCEPTED
    847.  
    848.    CLI       ; DISABLE INTERRUPTS
    849.    SUB   CX,CX     ; CLEAR COUNTER
    850. S10:
    851.    IN   AL,STATUS_PORT   ;
    852.    TEST   AL,INPT_BUF_FULL
    853.    LOOPNZ   S10     ; WAIT FOR COMMAND TO BE ACCEPTED
    854. ;
    855.    POP   AX     ; GET DATA TO SEND
    856.    OUT   STATUS_PORT,AL   ; SEND TO KEYBOARD CONTROLLER
    857.    STI       ; ENABLE INTERRUPTS AGAIN
    858.    RET       ; RETURN TO CALLER
    859. SHIP_IT ENDP
    860. CODE   ENDS
    861.    END
     
    Последнее редактирование модератором: 21 янв 2019