The program plays sounds for each numeric key on extended keyboard when Num lock is on.
Operators had problem with entering data when Num lock was off and they pressed arrows
instead numbers and they asked to create this utility.
Program starts, checks previous copy in memory and finishes if it exists.
Else it decodes following code in memory (protection from static and dynamic
(Turbo Debugger) disassembling), moves resident part to PSP, sets up interruption's
vector and finishes. Resident part responds on keyboard interruption and plays appropriate
sound. Resident part can be disabled and enabled by pressing keys CTRL+SHIFT(L)+SHIFT(R).
title numsound.asm
page 60,120
code segment byte public
assume cs:code,ds:code,es:code
org 100h
beg proc far
start: jmp init
beg endp
;secr db 'Barbotko S. 1993' ; copyright
secr db 30h,0a1h,98h,9ch,0eeh,8dh,0b6h,0f6h,02h,99h,0b8h,80h,62h,72h,0e4h,0cch
inter2F: pushf
cmp ax,0ee00h ;
jz itis_my
cmp ax,0ef00h
jnz no_my
itis_my: mov al,0ffh
popf
iret
no_my: popf
db 0EAh ; jmp far using old vector
offt_2f dw 0
segt_2f dw 0
inter: mov word ptr cs:ax_old+offs_psp,ax ; save flags and registers
lahf
mov byte ptr cs:f_old+offs_psp,ah
mov word ptr cs:es_old+offs_psp,es
mov word ptr cs:di_old+offs_psp,di
mov word ptr cs:cx_old+offs_psp,cx
mov al,byte ptr cs:kod_old+offs_psp ; is previous code E0h ?
cmp al,0E0h
jz inter_old ;if yes, this is key of extended keyboard,
mov ah,02h ; don't work with it.
int 16h ; get status of CTRL , SHIFT (R)(L)
; mov ah,al ; and NumLock
; and ah,00000111b ;(ctrl_shift)
; cmp ah,00000111b ;(ctrl_shift)
mov ah,byte ptr cs:run_off+offs_psp
test al,111b
jnz cont ; if their combination then invert
not ah ; byte off/on
mov byte ptr cs:run_off+offs_psp,ah
cont: cmp ah,0
jnz inter_old
test al,00100000b ;(numactiv) - check status of NumLock...
cmp al,0
jnz inter_old ; if it is set then don't work with it
inter_new:
mov ax,cs ; get ...
mov es,ax
mov di,offset ar_sc_kod+offs_psp
cld
mov cx,11
in al,60h ; ... scan-code and search for
repne scasb ; frequency for it
jne inter_old
mov di,10
sub di,cx
sal di,1
mov cx,word ptr es:ar_hz+offs_psp[di] ; get counter ...
soun: mov al,0b6h ; set up it (frequency)
out 43h,al
mov al,cl
out 42h,al
mov al,ch
out 42h,al
in al,61h ; turn on ...
or al,00000011b ;(sound_on)
out 61h,al
mov cx,2500h ;... delay ...
lp: loop lp
in al,61h ; ... turn off
and al,11111100b ;(sound_off)
out 61h,al
inter_old: in al,60h ; remember scan-code for next time
mov byte ptr cs:kod_old+offs_psp,al
mov es,word ptr cs:es_old+offs_psp ; restore registies ...
jmp dal
nop
;copyr db 'BarSSoft, 1993' ; label for RELEASE
copyr db 30h,0a1h,94h,0dch,6dh,0eah,67h,46h,61h,01h,0c4h,0e4h,72h,66h
dal:
mov di,word ptr cs:di_old+offs_psp
mov cx,word ptr cs:cx_old+offs_psp
mov ah,byte ptr cs:f_old+offs_psp
sahf ; ... and flags
mov ax,word ptr cs:ax_old+offs_psp
db 0EAh ; jmp far using old vector
offt dw 0
segt dw 0
; scan-codes of numeric keys
ar_sc_kod db 4fh,50h,51h,4bh,4ch,4dh,47h,48h,49h,52h,53h
; counters for them
ar_hz dw 2280,2152,1998,1912,1810,1708,1612,1522,1437,1356,1280
f_old db 0
es_old dw 0
di_old dw 0
cx_old dw 0
ax_old dw 0
kod_old db 0 ; for previous scan-code
run_off db 0 ; byte of program status - off/on
ctrl_shift equ 00000111b ; combination of CTRL+SHIFT(R)+SHIFT(L)
numactiv equ 00100000b ; NumLock is set up
sound_on equ 00000011b ; turning on ...
sound_off equ 11111100b ; ... and turning off sound
beg_psp equ 5ch ; beginning of resident part in PSP
offs_psp equ beg_psp-113h ; offset for bytes of data
len_res equ init-inter2F ; length of resident part
init:
mov ax,beg_psp
mov bx,ax
add ax,1c6h
push ax
mov ax,cs
mov ds,ax
mov cl,3
sar bx,cl
sal bx,1
call step2
lipa db 58h,25h ; pop ax and ax,... , i.e. trash
mov di,offset secro ; decode copyrights
mov cx,0007h
mov bx,offset copyr
mov si,offset secr
lp1: mov ax,word ptr ds:[bx]
lipa2 db 0ebh,0c8h ; here will be: ror ax,cl
mov word ptr ds:[bx],ax
mov ax,word ptr ds:[si]
ror ax,cl
mov word ptr ds:[di],ax
inc si
inc si
inc di
inc di
inc bx
inc bx
loop lp1
mov ax,word ptr es:[si] ; still decoding
ror ax,1
ror ax,1
mov word ptr es:[di],ax
mov ah,9 ;copyright
mov dx,offset soft
int 21h
mov ax,0ee00h
int 2fh
cmp al,0ffh ; no - see result of int 2fh (0ee00h)
jz no_run ; yes - already in memory !
mov ax,0ef00h
int 2fh
cmp al,0ffh ; no - see result of int 2fh (0ef00h)
jnz cont1 ; yes - already in memory !
no_run: mov ah,9 ; message 'already in memory' and end
mov dx,offset in_mem
int 21h
int 20h
cont1: mov ax,3509h ; save vector 09h
int 21h
mov offt,bx
mov segt,es
mov ax,352fh ; save vector 2fh
int 21h
mov offt_2f,bx
mov segt_2f,es
mov ax,cs ; transfer resident part into PSP
mov ds,ax ; offset = 5Ch
mov es,ax
mov di,beg_psp
mov si,offset inter2F
mov cx,len_res
cld
rep movsb
mov dx,beg_psp+15h ; set up new vector for 09h ...
mov ax,2509h
int 21h
mov dx,beg_psp ; ... and 2fh ...
mov ax,252Fh
int 21h
mov ax,cs:[2ch] ; release environment part
mov es,ax ; for other programs
mov ah,49h
int 21h
mov dx,beg_psp+len_res ; stay as resident noticing the new length
int 27h
step2:
mov ax,word ptr es:[bx] ; it it working under debugger ?
mov es,ax
cmp ax,word ptr es:[bx]
je no_debug
ret
no_debug: pop ax ; return skipping two bytes
add bx,beg_psp+1beh
mov byte ptr cs:[bx],0d3h
and ax,0fh
cmp ax,0fh
jz m1
and ax,0f0h
m1: mov bx,ax
ret
soft label byte ; welcome message
db 15 dup(32),201,42 dup(205),187,0dh,0ah
db 15 dup(32),186,6 dup(32),'Sounds for numeric keys. v 2.4 (c)',6 dup(32) ,186,0dh,0ah
db 15 dup(32),186,7 dup(32),'Copyright by '
secro db 'Barbotko S. 1993',7 dup(32),186,0dh,0ah
db 15 dup(32),186,32,'For off/on press CTRL+SHIFT(L)+SHIFT(R)',32,186,0dh,0ah
db 15 dup(32),200,42 dup(205),188,0dh,0ah,'$'
in_mem db 20 dup(32),"I'm already in memory !",'$'
code ends
end start