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