Category : Utilities for DOS and Windows Machines
Archive   : RBKEYSWP.ZIP

Output of file : RBKEYSWP.ASM contained in archive : RBKEYSWP.ZIP
;* *
;* RBkeyswap v2.0 6/22/91 *
;* (c) Copyright 1989, 1991 Ralf Brown *
;* *
;* Permission is granted to redistribute unmodified copies in their *
;* entirety. Modified copies may be distributed provided that they *
;* are clearly marked as modified and the original unmodified source *
;* code is distributed together with the modification. *
;* *
;* ------------------------------------------------------------------ *
;* *
;* RBkeyswap is a program to fix the IBM's enhanced keyboard, which *
;* places the Escape, Control, and CapsLock keys in the wrong places. *
;* After running RBkeyswap, Escape and `/~ will be exchanged, as will *
;* the left control key and the CapsLock key. The right control key *
;* will be unaffected. *
;* *
;* RBkeyswap loads itself high (no need for LOADHI or LH) into either *
;* an XMS upper memory block or a DOS 5.0 UMB. If neither is avail- *
;* able, RBkeyswap will go resident in low memory, using just 128 *
;* bytes (it needs a mere 64 bytes in high memory). Note that it will *
;* use 272 bytes under DOS 2.x, because those versions force all TSRs *
;* to leave at least that much resident. *
;* *
;* You need a BIOS which provides the keyboard intercept on INT 15h. *
;* If your BIOS does not support this, RBkeyswap will merely use up *
;* memory without doing anything. *
;* *
;* Usage: RBKEYSWP *
;* Note: the program does not check whether it is already installed, *
;* so a second run will re-swap the keys, negating the action and *
;* using up a small amount of extra memory. *
;* *
;* ------------------------------------------------------------------ *
;* *
;* Rebuilding RBkeyswap: *
;* *

code segment 'code'
assume cs:code

org 2Ch
envseg dw ? ; segment address of our environment

org 100h
jmp init

banner db 13,"RBkeyswap 2.0",9,"(c) Copyright 1989, 1991 Ralf Brown",13,10
db "Swaps Esc/tilde and CapsLock/LeftCtrl",13,10,"$"
db 26 ; stop output here if TYPEing the .COM file


jnc not_ours ; has a previous handler said to ignore scan code?
cmp ah,4Fh ; scan code translation?
jne not_ours ; if not, chain immediately
cmp al,0E1h ; is it a special key such as "Pause"?
je int15_setbranch
cmp al,0E0h ; or a right-{alt,ctrl}?
_branch: ; (if prev scan was E0h or E1h, we will
BRANCH equ (_branch-int15_handler) ; branch unconditionally)
je int15_setbranch ; the opcode here gets toggled between
; JE and JMP SHORT as needed
shl al,1 ; move break bit into CF
pushf ; and remember it for later
cmp al,1Dh*2 ; ctrl?
je ctrl_or_capslock
cmp al,3Ah*2 ; capslock?
je ctrl_or_capslock
cmp al,01h*2 ; ESC?
je esc_or_tilde
cmp al,29h*2 ; backquote/tilde key?
jne int15_no_xlat
xor al,0Fh*2 ; (AL xor 0F) xor 27 == (AL xor 28h)
; 01h -> 29h, 29h -> 01h
; thus esc and tilde swapped
xor al,27h*2 ; 1Dh -> 3Ah, 3Ah -> 1Dh
; thus left-ctrl and capslock swapped
popf ; retrieve break bit in CF
rcr al,1 ; and add to translated scan code
jmp short int15_done

xor byte ptr cs:BRANCH,(74h xor 0EBh) ; toggle between JE and JMP
stc ; use the scan code
db 0EAh ; FAR JMP chain to previous handler
old_int15 dd ?

end_resident label byte
code_size equ $ - int15_handler
resident_code equ (code_size + 15)/16


xms_entry dd 0
resident_seg dw 0 ; location of interrupt handler after relocation
resident_size dw 0 ; number of paras to keep on going TSR
alloc_strat dw 0
link_state db 0 ; are UMBs part of memory chain?
exit_func db 4Ch ; will change to 31h if we must go resident

assume ds:code
mov dx,offset banner
mov ah,9
int 21h ; identify ourself
mov ax,3515h
int 21h ; get old vector
mov word ptr old_int15,bx ; and store in new interrupt handler
mov word ptr old_int15 + 2,es
; first, see if we can load into an XMS upper memory block
mov ax,352Fh
int 21h ; find out whether INT 2F is valid
mov ax,es
or ax,bx ; don't try XMS if INT 2F is NULL
jz no_XMS ; (could be case under DOS 2.x)
mov ax,4300h ; see if XMS is installed
int 2Fh
cmp al,80h ; did XMS respond?
jnz no_XMS
mov ax,4310h ; if XMS present, get its entry point
int 2Fh
mov word ptr xms_entry,bx
mov word ptr xms_entry+2,es ; and store entry point for call
mov ah,10h ; request UMB
mov dx,resident_code ; this is how much we need
call xms_entry ; ask XMS for the memory
cmp ax,1 ; did we get it?
jne no_XMS ; if not, try DOS 5 UMB
mov resident_seg,bx ; remember where we'll relocate
jmp relocate_handler ; and go install
; if no XMS, try a DOS5 UMB
mov ax,3000h ; get DOS version
int 21h
cmp al,5 ; DOS 5.0 or higher?
jb not_dos5
cmp al,10 ; but make sure not OS/2 penalty box
jae not_dos5
mov ax,5802h ; get UMB link state
int 21h
mov link_state,al ; and remember it for later restore
mov ax,5803h ; set link state
mov bx,1 ; UMBs are part of memory chain
int 21h
mov ax,5800h ; get allocation strategy
int 21h
mov alloc_strat,ax ; and remember it for later restore
mov ax,5801h ; set allocation strategy
mov bx,40h ; alloc high memory only
int 21h
mov ah,48h ; allocate memory
mov bx,resident_code ; this is how much we need
int 21h ; try to allocate the UMB
pushf ; remember whether we succeeded
jc no_highmem ; did we succeed?
mov resident_seg,ax ; yes, so remember where to relocate
dec ax ; address the MCB for our new memory
mov es,ax ; block
mov word ptr es:[1],0Ah ; make DOS owner of UMB, so it won't be
mov word ptr es:[8],"CS" ; released when we exit (details below)
; Reasons for mucking with the MCB:
; DOS 5 will release any memory blocks owned by the program when
; it exits without going TSR, even if the blocks are in high memory
; and high memory has been disconnected from the memory chain. So,
; we need to change the owner field such that DOS thinks it belongs to
; somebody else and doesn't release it when we exit. Both 08h and
; 0Ah are used by DOS itself, so we know they won't be messed with.
; However, the DOS 5 MEM program gets confused by 08h, because it
; thinks the block should have subblocks, which it doesn't. 0Ah is
; normally a locked-out portion of high memory, so there aren't any
; problems there. I put "SC" in the name field to make DOS think
; this is "system code".
mov ax,5801h
mov bx,alloc_strat ; restore allocation strategy
int 21h
mov ax,5803h ; restore link state
mov bh,0
mov bl,link_state
int 21h
popf ; get back whether we were successful
jnc relocate_handler ; if successful, go install
; as a last resort, use our own PSP to store the code, and go resident
mov ax,cs
add ax,4 ; copy to offset 40h in PSP
mov resident_seg,ax
mov exit_func,31h ; TSR rather than normal exit
mov ah,49h ; since we will be going resident,
mov es,envseg ; discard our environment
int 21h
mov envseg,0 ; and zero the ptr in the PSP
mov resident_size,resident_code + 4
; relocate interrupt handler into the PSP or UMB
mov si,offset int15_handler
mov es,resident_seg ; get back destination segment
xor di,di
mov cx,code_size ; number of bytes to copy
rep movsb ; copy the interrupt handler
; install the new interrupt handler
push ds
mov ds,resident_seg
mov dx,0
mov ax,2515h ; set INT 15h
int 21h
pop ds
; finally, exit (going resident if necessary)
mov dx,resident_size
mov ah,exit_func ; 4Ch or 31h
mov al,0
int 21h

code ends
end RBkeyswap

  3 Responses to “Category : Utilities for DOS and Windows Machines
Archive   : RBKEYSWP.ZIP

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: