;==============================================================;
;                                                              ;
;  Author       :  Roy Fan                                     ;
;                  fan@uci-750a                                ;
;  Program Name :  SwapKey.ASM                                 ;
;  Date Written :  August 10, 1984  @ 09:15                    ;
;  Last Revision:  August 26, 1984  @ 09:55                    ;
;  Documentation:  August 26, 1984  @ 09:55                    ;
;                                                              ;
;    This program SwapKey will swap two keys on the IBM ill-   ;
;  designed keyboard:  left shift key and back slash key.  It  ;
;  occupies only 80 bytes under DOS 1.x or 144 bytes under     ;
;  DOS 2.x once installed.                                     ;
;                                                              ;
;  Note:  This version of ROM is released on 04/24/81          ;
;                                                              ;
;  Caution:                                                    ;
;                                                              ;
;    1.  Since this program makes direct call to specific      ;
;        location in ROM, it might not work with other         ;
;        versions of ROM or other IBM compatibles.             ;
;    2.  For the same reason given above, this program will    ;
;        not work with other keyboard utilities, such as,      ;
;        ProKey, ScrolLk, SmartKey, etc.                       ;
;                                                              ;
;==============================================================;

;--------
; Equates
;--------

DATA          EQU    40H           ; ROM BIOS Data Area
KB_DATA       EQU    60H           ; 8255 Port A
Shift_Key     EQU    02AH          ; scan code for left shift key
Slash_Key     EQU    02BH          ; scan code for back slash key
DOS_1_x       EQU    16H           ; start address of codes under DOS 1.x
DOS_2_x       EQU    5CH           ; start address of codes under DOS 2.x
Start_Code    EQU    DOS_2_x       ; start address of codes

;------------------
; Interrupt Vectors
;------------------

Vector        SEGMENT AT 0
              ORG    24H           ; Keyboard interrupt (type 9)
Keyboard_Int  DD     ?
Vector        ENDS

;------
; Codes
;------

Swap_Shift    SEGMENT
              ASSUME  CS:Swap_Shift, DS:Vector
              ORG     100H

Start:        JMP    SHORT Init_Vect

Keyboard:
              STI                  ;
              PUSH   AX            ;
              PUSH   BX            ;
              PUSH   CX            ;
              PUSH   DX            ;
              PUSH   SI            ;
              PUSH   DI            ; Duplicate the codes in ROM at location
              PUSH   DS            ; F000:E987 .. F000:E996
              PUSH   ES            ;
              CLD                  ;
              MOV    AX,DATA       ;
              MOV    DS,AX         ;
              IN     AL,KB_DATA    ;
              MOV    AH,AL         ; save the scan code in AH
              AND    AH,80H        ; save only the break bit in AH
              AND    AL,7FH        ; turn off the break bit  in AL
              CMP    AL,Shift_Key  ; is it the left shift key
              JE     Shift         ;    Yes
              CMP    AL,Slash_Key  ; is it the back slash key
              JE     Slash         ;    Yes
Old_Keyboard:
              OR     AL,AH         ; restore the break bit
              DB     0EAH          ;
              DW     0E998H        ; do a long jump to F000:E998
              DW     0F000H        ;
Shift:        MOV    AL,Slash_Key  ; change the back slash key to shift key
              JMP    Old_Keyboard  ;   resume codes in ROM
Slash:        MOV    AL,Shift_Key  ; change the shift key to back slash key
              JMP    Old_Keyboard  ;   resume codes in ROM

Init_Vect:
              CLD
              MOV    SI,OFFSET Keyboard
              MOV    DI,Start_Code
              MOV    CX,OFFSET Init_Vect - OFFSET Keyboard
              REP    MOVSB

; copy the codes to location Start_Code (16H)

              MOV    DX,DI         ; save last location of the codes in DX

              XOR    AX,AX
              MOV    ES,AX
              MOV    AX,Start_Code
              MOV    DI,OFFSET Keyboard_Int
              CLI
              STOSW
              MOV    AX,CS
              STOSW
              STI

; point the keybaord interrupt to our own codes

              INT    27H           ; make our codes resident

Swap_Shift    ENDS

END           Start

