TITLE TFR24C70.ASM
PAGE 60 ,132
;
;   This program intercepts the ROM KB interrupt 09H (Tech
;   Manual, A-25, line 1784) and tests every KB entry to see
;   whether CapsLock or NumLock has been toggled.  If CapsLock was
;   toggled it displays the sysbol @ , and if NumLock was toggled
;   it displays the symbol #, both in enhanced video.  The location
;   of the display is determined by the Equates for row and
;   columns respectively for the two flags, and the display
;   format is determined by the equate DF for the attribute.
;   The status is determined from the flag KB_FLAG of the ROM
;   (TM, A-2, line 69 is the location).
;
;   Refer to: PC World, Oct. '83, pg 266.  Does not mix well with
;    Lotus 1-2-3 or Scrollk; with ProKey install after ProKey.
;
;   This version displays flags after every KB use at row 00, col 78.
;
;          ***  Define Constants Used by Program ***
;
KB_DATA EQU     060H    ;8259 Port with KB scancode
KB_CTL  EQU     061H    ;8259 Port with control data for port
ROWCAPS EQU     00      ;Row for Caps Display (0-24)
COLCAPS EQU     78      ;Column for Caps Display (0-79)
ROWNUMS EQU     00      ;Row for Nums display
COLNUMS EQU     79      ;Column for Nums display
DF      EQU     15      ;Normal Intensified Display format
;
;              *********  Macro Section  *********
        IF1
CSR_SET MACRO   ROW,COL ;Sets CSR Pos. on PGE 0
        MOV     DH,ROW  ;Sets row
        MOV     DL,COL  ;Sets col
        MOV     BH,0    ;Sets pge
        MOV     AH,2    ;ROM BIOS VIDEO function
        INT     010H    ;ROM BIOS VIDEO interrupt
        ENDM
CSR_GET MACRO           ;Return CSR Pos. on PGE 0
        MOV     BH,0    ;(DH,DL)=ROW,COL returned
        MOV     AH,3    ;Function in ROM BIOS Video
        INT     010H    ;ROM BIOS VIDEO Interrupt
        ENDM
ROMVIDEO        MACRO   CHR,NO_TIMES,ATTR       ;INT 10,FN.10,Disp.Char.at
        MOV     BH,0    ;Current cursor pos.BH=Page
        MOV     AL,CHR          ;Char. to be displayed
        MOV     CX,NO_TIMES     ;Char. count
        MOV     BL,ATTR ;Screen attribute,7 normal, 15 enhanced
        MOV     AH,9    ;Function call
        INT     10H     ;ROM VIDEO Interrupt
        ENDM            ;MACRO End
        ENDIF
;
DATA    SEGMENT AT 40H  ;ROM DATA, TM, A-2, line 59
        ORG     17H     ;Location in ROM of
KB_FLAG LABEL   BYTE    ;KB_FLAG(see A-2 of Tech.Man.)
DATA    ENDS
;
CSEG    SEGMENT
        ASSUME  CS:CSEG,DS:DATA
;
        ORG     100H
;
; The block of code below directs interrupt 9H to 5CH in Program Prefix
; rather than the usual location in ROM
;
START:  MOV     DX,5CH          ;Set DS:DX to locn 5CH in program prefix
        MOV     AL,9H           ;Set the KB interrupt (9H=9)
        MOV     AH,25H          ;DOS function call for interrupt
        INT     21H             ;DOS interrupt for service
        MOV     DI,DX           ;Move KB routine down so it starts
        MOV     SI,KB_ADDR      ;At locn 5CH in program prefix
        MOV     CX,KB_LNTH      ;This sets count in CX for MOVSB at FINISH
        JMP     FINISH          ;to include just operative code resident.
;
; KB Interrupt routine. Copy beginning of ROM routine to allow easy
; jump to later ROM code.  Copy code from TM, A-25, line 1788(line 1787
; is inserted just before ports are sampled) to line 1808.
;
KB:     PUSH    AX              ;Save registers used
        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSH    SI
        PUSH    DI
        PUSH    DS
        PUSH    ES
        CLD
        MOV     AX,DATA
        MOV     DS,AX
        STI
        IN      AL,KB_DATA      ;Get key code
        PUSH    AX
        IN      AL,KB_CTL       ;Restore KB
        MOV     AH,AL
        OR      AL,80H
        OUT     KB_CTL,AL
        XCHG    AH,AL
        OUT     KB_CTL,AL
        POP     AX
        MOV     AH,AL           ;Save key code
;
; End of copied ROM code.  Start own code. (The part of ROM code that follows
; this is just that part which handles the KB interrupt 10H, which is what
; the DOS KB interrupts use.)
;
        CMP     AL,0FFH         ;Overrun? Line 1812 of ROM
        JZ      INTERIM         ;Resting place for Near Jump
;          *********  Start of Operable Code  *********
;
; ****  Routine to Test for Caps Lock and Num Lock Toggle  ****
        PUSH    AX              ;Save registers not saved by Video Int.
        PUSH    DI
        PUSH    SI
        MOV     BL,KB_FLAG      ;Status to BL
        AND     BL,60H          ;Sets bits for both on
        CSR_GET                 ;Need to save cursor
        MOV     CS:ROWSAVED,DH  ;Save cursor locations
        MOV     CS:COLSAVED,DL
        CMP     BL,60H          ;See if both on, if not then
        JNE     TRY1            ;to test for CAPS only on
        CSR_SET ROWCAPS,COLCAPS ;both on display
        ROMVIDEO        '@',1,DF
        CSR_SET ROWNUMS,COLNUMS
        ROMVIDEO        '#',1,DF ;both now displayed
        JMP     HOME            ;Exit
INTERIM:JMP     ROM_KB          ;Needed for near JZ above
TRY1:   CMP     BL,40H          ;Is Caps alone on?
        JNE     TRY2            ;If not, test for Nums only
        CSR_SET ROWCAPS,COLCAPS ;Display just Caps only
        ROMVIDEO        '@',1,DF
        CSR_SET ROWNUMS,COLNUMS ;and blanks for nums
        ROMVIDEO        ' ',1,DF
        JMP     HOME            ;Exit
TRY2:   CMP     BL,20H          ;See if just Nums on
        JNE     BOTH_OFF        ;if not, both off
        CSR_SET ROWCAPS,COLCAPS ;Blank for caps
        ROMVIDEO        ' ',1,DF
        CSR_SET ROWNUMS,COLNUMS ;and Nums is on alone here
        ROMVIDEO        '#',1,DF
        JMP     HOME            ;Exit
BOTH_OFF:       CSR_SET ROWCAPS,COLCAPS
        ROMVIDEO        ' ',1,DF ;Blank Caps spaces
        CSR_SET ROWNUMS,COLNUMS  ;Blank Nums spaces
        ROMVIDEO        ' ',1,DF
HOME:   CSR_SET CS:ROWSAVED,CS:COLSAVED
home0:                          ;No change if here, exit
        POP     SI              ;Restore registers
        POP     DI
        POP     AX
;
ROM_KB: MOV     AH,AL
        JMP     FAR PTR ROM_ADR ;To ROM for processing
;
FINISH: REP     MOVSB
        MOV     DX,DI           ;End program but leave KB resident
        INT     27H             ;DOS call for stay resident
;
; *******  Memory for CS must go here and be addressed CS:  *********
;
ROWSAVED        DB      ?       ;Row position from DH
COLSAVED        DB      ?       ;Col position from DL
;
KB_END:
;
CSEG    ENDS
;
ROM     SEGMENT AT 0F000H       ;ROM BIOS KB entry points
        ASSUME  CS:ROM
        ORG     0E9A8H          ;This is line 1812 on A-26 of T.M.
ROM_ADR LABEL   FAR             ;Perform all but initial processing
ROM     ENDS
;
KB_ADDR EQU     (OFFSET KB-OFFSET START)+100H
KB_LNTH EQU     (OFFSET KB_END-OFFSET KB)
;
        END     START
