code segment
org 100h
assume cs:code,ds:code,es:code,ss:code
start:
jmp C1
old09addr label dword
old_ip09 dw ?
old_cs09 dw ?
new09addr label dword
new_ip09 dw ?
new_cs09 dw ?
mcb label dword
mcb_evb dw ? ; mcb: Memmory Control Block
mcb_psp dw ?
PRE_SCAN DB ? ;INT 9H中按下或松开一个键产生的扫描码
PRE_ASCII DB ? ;INT 9H中按下或松开一个键产生的字符码
LOO_SCAN DB ? ;INT 9H中松开一个键产生的扫描码
LOO_ASCII DB ? ;INT 9H中松开一个键产生的字符码
;修改后键盘ASCII码表
; 0123456789ABCDEF
ASC_ASC DB '????????????????';0
DB '????????????????';1
DB ' !"#$%&?()*+,-./';2
DB '0123456789:;<=>?';3
DB '@KXVMCNOPHQRSZYI';4
DB 'JADLEGWBUFT[/]^?';5 此处?号为原本的?号位置
DB '?kxvmcnophqrszyi';6
DB 'jadlegwbuft{|}~?';7
DB '????????????????';8
DB '????????????????';9
DB '????????????????';A
DB '????????????????';B
DB '????????????????';C
DB '????????????????';D
DB '????????????????';E
DB '????????????????';F
;根据ASCII->扫描码映射表找出扫描码
; 0 1 2 3 4 5 6 7 8 9 A B C D E F
ASC_SCAN DB ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ;0
DB ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ;1
DB ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ;2
DB 0BH, 02H, 03H, 04H, 05H, 06H, 07H, 08H, 09H, 0AH, ?, ?, ?, ?, ?, ? ;3
DB ?, 1EH, 30H, 2EH, 20H, 12H, 21H, 22H, 23H, 17H, 24H, 25H, 26H, 32H, 31H, 18H ;4
DB 19H, 10H, 13H, 1FH, 14H, 16H, 2FH, 11H, 2DH, 15H, 2CH, ?, ?, ?, ?, ? ;5
DB ?, 1EH, 30H, 2EH, 20H, 12H, 21H, 22H, 23H, 17H, 24H, 25H, 26H, 32H, 31H, 18H ;6
DB 19H, 10H, 13H, 1FH, 14H, 16H, 2FH, 11H, 2DH, 15H, 2CH, ?, ?, ?, ?, ? ;7
new09h proc near ;新INT9中断程序
CLI
push si
push es
push ds
push ax
push cs
pop ds
pushf
call CS:dword ptr old09addr ;调用原int9
;欠处理打印,NUMLOCK等非ASCII操作
MOV SI,0040H ;键盘缓冲区尾指针 0040:001C
MOV ES,SI
MOV SI,ES:[001CH] ;队尾指针BUFF_TAIL指向最后一个元素的后面
SUB SI,2 ;批
CMP SI,001EH
JAE EDGE
MOV SI,003CH
EDGE:
MOV AX,ES:[SI]
MOV PRE_SCAN,AH ;存入扫描码
MOV PRE_ASCII,AL ;存入字符码
CALL CHANGE
MOV ES:[SI],AX
pop ax
pop ds
pop es
pop si
iret
new09h endp
CHANGE PROC NEAR
PUSH ES
PUSH SI
PUSH DI
PUSH DX
;不考虑组合键
CMP al,0H ;ASCII码为0
jz exit
cmp al,30h
jb exit
cmp al,39h
jbe opr
l1: cmp al,41h
jb exit
cmp al,5AH
jbe opr
l2: cmp al,61h
jb exit
cmp al,7Ah
jbe opr
jmp exit
opr:
XOR DH,DH
MOV DL,AL
MOV DI,DX
LOOSE:
MOV DL,ASC_ASC[DI]
PUSH DX
XOR DH,DH
MOV DI,DX
POP DX
MOV DH,ASC_SCAN[DI]
TEST AH,80H ;
JZ PRESS
;为通码则到short press
OR DH,80H
PRESS:
MOV AX,DX ;修改后的键盘码放入AX返回
exit:
POP DX
POP DI
POP SI
POP ES
ret
CHANGE endp
END_TSR label byte
C1:
main proc near ;第一次运行install,下一次运行uninstall
; Get current 1ch interrupt vector
mov ax,3509h
int 21h
cmp bx,offset new09h
jnz in1
call uninstall
jmp in2
in1: call install
in2:
mov ax,4c00h
int 21h
main endp
uninstall proc near ;卸载tsr程序
push es
push ds
push dx
push bx
push ax
push di
mov dx, offset strMsgUninstall
mov ah, 09h
int 21h
; get new int9 cs:ip from interrupt vector table
; fetch old_cs09 and old_ip09
; restore old int9
mov ax,3509h
int 21h
mov di,offset old_cs09
mov dx,es:[di] ;old_cs09
mov ds,dx
mov dx,es:[di-2] ;old_ip09
mov ax,2509h
int 21h
; Release evirenment parameter block
;mov bx, 1
;mov ax, CS:[mcb_evb]
;mov ds, ax
;mov word ptr ds:[bx], 0
; Release TSR
;mov ax, CS:[mcb_psp]
;mov ds, ax
;mov word ptr ds:[bx], 0
pop di
pop ax
pop bx
pop dx
pop ds
pop es
ret
uninstall endp
install proc near ;安装新中断
push ds
push es
push ax
push bx
push cx
push dx
;save old int 09h
mov al,09h
mov ah,35h
int 21h
mov old_cs09,es
mov old_ip09,bx
mov dx, offset strMsgInstall
mov ah, 09h
int 21h
push ds
;set new int 09h
lea dx,new09h
mov ax,cs ;mov ax,seg new09h
mov ds,ax
mov al,09h
mov ah,25h
int 21h
mov [new_ip09],dx
mov [new_cs09],ds
pop ds
; Store the address of evirenment parameter block
;mov ax, cs
;dec ax
;mov [mcb_psp], ax ;mov cs:[mcb_psp], ax
;mov bx, 2ch
;mov ax, [bx] ;mov ax, cs:[bx]
;dec ax
;mov cs:[mcb_evb], ax
; exit and reside in memory
mov dx,OFFSET END_TSR ;从PSP开始的DX大小内存块驻留
mov cl,4 ;到END_TSR处之前为驻留部分
shr dx,cl
inc dx
mov ax, 3100h
int 21h
; exit and reside in memory
;MOV DX,((varlen+15)/16)+16 ;全部代码驻留
;MOV AX,3100H
;INT 21H
STI
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
ret
install endp
ln proc near ;回车换行
push ax
push dx
mov dl,0dh
mov ah,2
int 21h
mov dl,0ah
mov ah,2
int 21h
pop dx
pop ax
ret
ln endp
;键盘扫描码编码表
; 0123456789ABCDEF
SCAN_TABLE DB '??1234567890-=??' ;0
DB 'QWERTYUIOP[]??AS' ;1
DB "DFGHJKL;'`?/ZXCV" ;2
DB 'BNM,./?*????????' ;3
DB '??????????-?5?+?' ;4
DB '????????????????' ;5
DB '????????????????' ;6
DB '????????????????' ;7
; 0123456789ABCDEF ;
SCAN_TABLE0 DB '??1234567890-=??' ;0
DB 'JVTKZNXOGH[]??QL' ;1
DB "RYUIPAS;'`?/MBEC" ;2
DB 'WFD,./?*????????' ;3
DB '??????????-?5?+?' ;4
DB '????????????????' ;5
DB '????????????????' ;6
DB '????????????????' ;7
;计划修改后,键盘的扫描码表
;只对A-Z排序,原q位为a,原m位为z
;原键盘ASCII码编码表
; 0123456789ABCDEF
ASC_TABLE DB '????????????????';0
DB '????????????????';1
DB ' !"#$%&?()*+,-./';2
DB '0123456789:;<=>?';3
DB '@ABCDEFGHIJKLMNO';4
DB 'PQRSTUVWXYZ[/]^?';5
DB '?abcdefghijklmno';6
DB 'pqrstuvwxyz{|}~?';7
DB '????????????????';8
DB '????????????????';9
DB '????????????????';A
DB '????????????????';B
DB '????????????????';C
DB '????????????????';D
DB '????????????????';E
DB '????????????????';F
count dw ?
strMsgInstall db 07h, "AutoKey installed!$"
strMsgUninstall db 07h, "AutoKey uninstalled!$"
varlen equ $ - start
code ends
end start
; rtwxu zoqfrn.egd