home *** CD-ROM | disk | FTP | other *** search
-
- ;Portions of this code are copyrighted 1990
- ;by RSE Incorporated and used with permission
-
- Code segment byte public 'code'
- assume cs:code
- assume ds:code
-
- org 100h
- LGo: jmp Init
-
- BoostDelay dw 18 ;# of clock ticks (18.2/sec)
- BufSize dw 500 ;buffer size in bytes (5 per keystroke)
- CapSS db 4 ;1=RShft 2=LShft 4=Ctrl 8=Alt 12=Ctrl-Alt
- CapSC db 19 ;Ctrl-R record hot key
- RepSS db 4
- RepSC db 25 ;Ctrl-P playback hot key
- Delay dw 0 ;clock ticks since last key press
- EndBuff dw 0 ;offset of end of buffer
- Pntr dw offset Buffer ;offset where next key info goes
- Cap? db 0 ;capture flag
- UpperLimit dw 0
- Shift db 0 ;shift value of key
- Waet dw 0 ;keystroke delay
- Key dw 0 ;ASCII and Scan Code of key
- KeyBufEnd dw 0 ;end of BIOS key buffer
- Replay? db 0 ;replay flag
- Tick dw 0 ;keeps track of clock in sound proc
- Remove? db 0 ;indicates if key press or release
- Message db 'EncoreHere'
- BuffOff dw offset StrBytes
- BufSizOff dw offset BufSize
- Vec9 dd 0 ;Int 9 original vector
- Vec1C dd 0 ;Int 1C original vector
-
- I9 proc
- ;activated anytime a key is pressed OR released
- sti
- push ax
- push es
- mov ax,40h
- mov es,ax
- mov ah,es:17h ;put shift state in ah
- pop es
- and ah,0Fh ;just want shift states
-
- in al,60h ;get scan code of key press
- and al,7Fh ;mask out release bit
-
- I92: cmp al,cs:CapSC ;Record hot key scan code?
- jne I93
- jmp CapKey?
-
- I93: cmp al,cs:RepSC ;playback hot key scan code?
- jne I94
- jmp ReplayKey?
-
- I94: cmp cs:Replay?,1
- jne I95
-
- cmp al,1 ;Escape pressed during Replay?
- jne I95
-
- call EndReplay
- mov cs:Remove?,1 ;I9end will changes this to 0
-
- I945: call I9end
- pop ax
- iret
-
- I95: cli
- pushf
- call cs:Vec9 ;call originial interupt
- cmp cs:Cap?,1
- je Capture
-
- I96: pop ax
- iret
-
- ;capturing - done after Vec9 is called
- Capture: push es
-
- mov ax,40h
- mov es,ax
- mov ax,es:1Ch
- cmp ax,cs:KeyBufEnd
- jne I97
-
- ;if tail of buffer hasn't changed (no new keys) then return
- pop es
- pop ax
- iret
-
- I97: mov cs:KeyBufEnd,ax
- push di
- push bx
-
- mov di,cs:Pntr
-
- ;if key buffer is full then turn off capture
- cmp di,cs:UpperLimit
- jb I98
- call EndCap
- jmp I9a
-
- ;save key info
- ;format - first byte=ASCII, 2=Scan Code, 3=Shift state, 4&5=Delay
- I98: add cs:Pntr,5
- mov ax,cs:Delay
- mov cs:[di+3],ax ;delay
- mov cs:Delay,0
-
- ;get last key put into buffer (end of buffer-2)
- mov ax,40h
- mov es,ax
- mov bx,es:1Ch ;end of BIOS buffer
- cmp bx,1Eh ;remember, it's a circular buffer
- jne I99
- mov bx,3Eh
- I99: dec bx
- dec bx
- mov ax,es:[bx]
- mov cs:[di],ax ;ASCII (al) Scan Code (ah)
- mov al,es:17h ;shift state
- mov cs:[di+2],al
-
- I9a: pop bx
- pop di
- pop es
- pop ax
- cli
- iret
-
- ;Replay hot key pressed?
- ReplayKey?: cmp cs:Remove?,1
- je R20
- cmp ah,cs:RepSS
- je R1
- jmp I94
-
- ;initiate replay
- R1: cmp cs:Cap?,1
- jne R2
-
- ;quit capturing before initiating replay
- call EndCap
-
- R2: mov cs:Pntr,offset Buffer
- cmp cs:StrBytes,0
- ja R21
-
- R20: call I9end
- pop ax
- iret
-
- R21: push di
- push bx
- push ds
-
- mov ax,cs
- mov ds,ax
-
- ;use size of key sequence to compute end of buffer
- mov ax,StrBytes
- add ax,offset Buffer
- mov EndBuff,ax
-
- call GetVars ;get key info
-
- pop ds
- pop bx
- pop di
-
- call I9end ;clear key from keyboard
- mov cs:Delay,0 ;reset delay
-
- pop ax
- cli
- mov cs:Replay?,1 ;set replay flag
- iret
-
- ;capture hot key
- CapKey?: cmp cs:Remove?,1
- je R20
-
- cmp ah,cs:CapSS
- je Cap1
- jmp I94
- ;Capture
- Cap1: call I9end
- cmp cs:Cap?,1 ;if already capturing then end
- jne Cap2
- ;end capture
- call EndCap
- jmp Cap3
-
- ;starting capture
- Cap2: call sound
-
- ;reset buffer info
- mov cs:Delay,0
- mov cs:Pntr,offset Buffer
- mov cs:Cap?,1
- push ax
- mov ax,40h
- mov es,ax
- mov ax,es:1Ch
- mov cs:KeyBufEnd,ax
- pop es
-
- Cap3: pop ax
- iret
- I9 endp
-
- I9end proc
- in al,61h ;resets the keyboard
- mov ah,al
- or al,80h
- out 61h,al
- mov al,ah
- out 61h,al
-
- cli
- mov al,20h ;reset interupts
- out 20h,al
- sti
-
- xor cs:Remove?,1
- ret
- I9end endp
-
- EndCap proc ;ends capturing
- cli
- mov cs:Cap?,0
- sti
- call sound
- call sound
-
- ;anything captured?
- mov ax,cs:Pntr
-
- ;put size of key sequence StrBytes
- EC1: mov cs:EndBuff,ax
- sub ax,offset Buffer
- mov cs:StrBytes,ax
- ret
- EndCap endp
-
- I1C proc ;timer interupt
-
- pushf
- call cs:Vec1C ;call timer interupt
-
- inc cs:Delay
- cmp cs:Replay?,1
- jae T1
- iret ;if not replaying then we're done
-
- ;replaying
- T1: sti
- push ax
- push di
- push ds
-
- mov ax,cs
- mov ds,ax
-
- mov ax,Delay
- cmp ax,Waet ;waited long enough?
- jb T4 ;return
-
- ;put stuff in
- push es
- push bx
-
- mov ax,40h
- mov es,ax
- mov bx,es:1Ch ;adjust for circular buffer
- cmp bx,es:1Ah
- jne T3
-
- mov ax,Key
- mov es:[bx],ax ;put ASCII and Scan code in
- inc bx
- inc bx
- cmp bx,3Eh
- jne T2
- mov bx,1Eh
- T2: mov es:1Ch,bx ;adjust end of BIOS buffer
- mov al,Shift
- mov es:17h,al ;put shift state in
- push bx
- call GetVars ;get next key info
- pop bx
-
- T3: mov Delay,0 ;reset delay
- pop bx
- pop es
-
- T4: pop ds
- pop di
- pop ax
- iret
- I1C endp
-
- GetVars proc
- ;enter with Pntr pointing to variables and ds=cs
- ;returns Key (ASCII and Scan Code), Shift, and Waet
-
- mov di,Pntr
-
- GV1: mov ax,[di]
- mov Key,ax
- mov al,[di+2]
- mov Shift,al
- mov ax,[di+3]
- cmp ax,BoostDelay ;check if Waet <= Boost value
- ja GV3
- GV2: xor ax,ax
- GV3: mov Waet,ax
-
- add di,5
- mov Pntr,di
- cmp di,EndBuff
- ja EndReplay
- ret
- GetVars endp
-
- EndReplay proc
- ;terminate replay
- push es
- mov ax,40h
- mov es,ax
- mov cs:Pntr,offset Buffer
- mov cs:Replay?,0
- mov al,es:17h ;get shift state
- and al,0F0h ;eliminate shifts,ctrl,alt
- mov es:17h,al ;restore shift state
- pop es
- ret
- EndReplay endp
-
- Sound proc ;destroys AX
-
- push es
-
- mov ax,40h
- mov es,ax
- mov ax,es:6Ch
- S1: cmp es:6Ch,ax
- je S1 ;wait till clock tick changes
- inc ax
- mov cs:tick,ax
-
- mov al,0B6h
- out 43h,al ;get timer ready
-
- mov ax,0C00h
-
- out 42h,al
- mov al,ah
- out 42h,al ;set freq
-
- in al,61h
- or al,3
- out 61h,al ;turn speaker on
-
- mov ax,cs:tick
- S2: cmp ax,es:6Ch
- je S2 ;do for one clock tick
-
- in al,61h ;turn off speaker
- and al,11111100b
- out 61h,al
-
- pop es
- ret
- Sound endp
-
- Change? db 0 ;make command line changes permanent?
- Dummy3 db 0
- StrBytes dw 0
- Buffer db 0
-
- ;buffer will overwrite the following code
-
- Msg db 10,'ENCORE 1.0 Copyright (c) 1991 Ziff Communications Co.',13,10
- db 'PC Magazine ~ Scott Chaney ~ RSE Inc',13,10,10
- Msg0 db 'Syntax: ENCORE [/S] [/L] [/U] [/Kn../Bn../P]',13,10
- db ' /S = Save a keystroke sequence to disk',13,10
- db ' /L = Load a keystroke sequence (macro)',13,10
- db ' /U = Uninstall',13,10
- Msg1 db ' /Kn = Change size of keystroke buffer',13,10
- db ' /Bn = Change Boost threshold (in clock ticks)',13,10
- db ' /P = Make command line changes permanent',13,10
- Msg2 db 'Ctrl-R = Record keystrokes',13,10
- db 'Ctrl-P = Playback keystrokes',13,10,'$'
-
- Already db 10,'Encore is already loaded',13,10,10,'$'
-
- Init proc
-
- push cs
- pop ds
-
- ;check for command line
- mov bx,80h
- mov cl,[bx]
- cmp cl,0
- je P4
-
- mov si,81h
-
- Parse: mov al,[si]
- inc si
- cmp al,0Dh
- je P4
- cmp al,'/'
- je Parse
- cmp al,' '
- je Parse
-
- or al,20h ;convert to lower case
-
- cmp al,'p' ;make command line changes perm?
- jne P3
- mov Change?,1
-
- P3: cmp al,'k' ;change keystroke buffer size?
- jne P32 ;Parse
-
- call MakeNum
- mov bx,5
- mul bx
- mov BufSize,ax
- jmp Parse
-
- P32: cmp al,'l' ;load in key file?
- jne P34
- mov Ld,1
- jmp LdSv
-
- P34: cmp al,'s' ;save to key file?
- jne P35
- jmp LdSv
-
- P35: cmp al,'b' ;change boost value?
- jne P36
- call MakeNum
- mov BoostDelay,ax
- jmp Parse
-
- P36: cmp al,'u' ;uninstall?
- jne Parse
- jmp UnInstall
-
- P4: call Loaded?
- jne P42
-
- ;already loaded into memory
- mov ah,9
- mov dx,offset Already
- int 21h ;print 'already loaded'
- mov Msg1,'$'
- mov dx,offset Msg0
- mov ah,9
- int 21h
-
- mov dx,offset Msg2
- mov ah,9
- int 21h
- Outtahere: mov ah,4Ch
- int 21h ;end
-
- ;make command line changes permanent?
- P42: cmp Change?,1
- jne P5
- mov dx,offset FileName
- mov ax,3D02h
- int 21h ;open file
- mov bx,ax ;file handle
- mov dx,100h
- mov cx,7
- mov ah,40h
- int 21h ;write 7 bytes to file
- mov ah,3Eh
- int 21h ;close file
-
- P5: mov ah,9
- mov dx,offset Msg
- int 21h ;print copyright message
-
- mov ax,cs:2Ch
- mov es,ax
- mov ah,49h
- int 21h ;free environment memory
-
- mov ax,3509h
- int 21h ;get int 09 vector
- mov word ptr Vec9,BX
- mov word ptr Vec9[2],ES
-
- mov ax,351Ch
- int 21h ;get int vec 1C
- mov word ptr Vec1C,bx
- mov word ptr Vec1C[2],es
-
- mov word ptr cs:[0100],0
- mov bx,offset Buffer
- add bx,BufSize
- mov EndBuff,bx
- mov UpperLimit,bx
- mov cl,4
- shr bx,cl ;paragraphs needed
- sub bx,0Ah ;less 160 bytes code shifted
-
- push bx
- mov si,100h
- mov cx,offset Buffer
- sub cx,si
- mov di,60h
- push ds
- pop es
- cld
- rep movsb ;mov code down 160 bytes
-
- mov ax,ds
- sub ax,0Ah
- mov ds,ax
- mov ax,2509h
- mov dx,offset I9 ;set Int9 vector
- int 21h
-
- mov ax,251Ch
- mov dx,offset I1C ;set Int1C vector
- int 21h
-
- pop dx
- inc dx
- MOV Ax,3100h
- INT 21h ;terminate and stay resident
-
- Init endp
-
- MakeNum proc
- ;converts ASCII number to binary word
- xor ax,ax
- mov bx,0Ah
- MN1: mov cl,[si]
- cmp cl,'0'
- jb MN2
- cmp cl,'9'
- ja MN2
- mul bx
- xor ch,ch
- sub cl,'0'
- add ax,cx
- inc si
- jmp MN1
- MN2: ret
- MakeNum endp
-
- Ld db 0 ;1 if loading, 0 if saving
- ExitMsg db 13,10,'Encore not loaded',13,10,'$'
- NoFile db 13,10,'File not found',13,10,'$'
- NoCreate db 13,10,'Unable to create file.',13,10,'$'
- TooSmall db 13,10,'Buffer too small',13,10,'$'
- Removed db 13,10,'Encore is uninstalled',13,10,'$'
- Ext db '.ENC'
- FileName db 'ENCORE.COM',4 dup (0)
- StrSize dw 0
-
- LdSv proc
- ;used to either save a key seq to file, or load a key seq from file
- ;si is already set by Init
-
- ;make filename
- mov di,offset FileName
- LS0: mov al,[si]
- inc si
- cmp al,0Dh
- je LS1
- cmp al,' '
- je LS0
-
- mov [di],al
- inc di
- jmp LS0
-
- LS1: mov ax,word ptr Ext
- mov [di],ax
- mov ax, word ptr Ext+2
- mov [di+2],ax
-
- call Loaded?
- je LS2
-
- ;Encore not in memory
- mov dx, offset ExitMsg
- mov ah,9
- int 21h
- mov ah,4Ch
- int 21h
-
- ;move offset info from TSR into program
- LS2: mov si,offset BuffOff
- mov cx,4
- LS3: mov al,es:[di]
- mov [si],al
- inc si
- inc di
- loop LS3
-
- mov dx,offset FileName
- xor cx,cx
- mov ax,3D02h
- cmp Ld,1
- je LS4
- dec ah
- LS4: int 21h ;open filename, or create (if saving)
- jnc LS6
-
- ;unable to open file
- mov dx,offset NoFile
- cmp Ld,1
- je LS5
- mov dx,offset NoCreate
- LS5: mov ah,9
- int 21h
- mov ah,4Ch
- int 21h
-
- LS6: cmp Ld,1
- jne LS8
-
- ;if loading key sequence from disk
- mov bx,ax ;put file handle in bx
- mov cx,2
- mov ah,3Fh
- mov dx,offset StrSize
- int 21h ;read in StrSize
-
- ;check buffer size
- mov si,BufSizOff
- mov ax,es:[si]
- cmp ax,StrSize
- jae LS7
-
- ;not enough room in buffer
- mov dx,offset TooSmall
- mov ah,9
- int 21h
- jmp Endd
-
- LS7: xor cx,cx
- mov dx,cx
- mov ax,4200h
- int 21h ;move file ptr to beg of file
-
- mov cx,StrSize
- add cx,2
- mov dx,BuffOff
- push es
- pop ds
- mov ah,3Fh
- int 21h ;read key seq into TSR's buffer
- jmp Endd
-
- ;saving key sequence to disk
- LS8: push ax ;file handle
- mov bx,BuffOff
- mov cx,es:[bx] ;size of key sequence
- mov dx,bx
- pop bx
- push es
- pop ds
- mov ah,40h
- int 21h ;save StrSize and key sequence
-
- Endd: mov ah,3Eh
- int 21h ;close file
- mov ah,4Ch
- int 21h ;end program
-
- LdSv endp
- ;check if already loaded
-
- Loaded? proc
- ;checks to see if TSR already is loaded. If it is then zf set upon
- ;return and es:di points to offset info in TSR
-
- mov bx,offset Message
- inc Message ;avoid disk cache match
- mov ax,cs
- mov dx,0A000h-1
- NextPara: inc dx ;next paragraph
- mov es,dx
- cmp dx,ax
- je NotHere ;If our seg then search is done
- mov si,bx ;else check for match
- mov di,bx
- mov cx,0Ah
- rep cmpsb ;a match?
- jnz NextPara ;if no match, keep looking
- ret
-
- NotHere: inc ax
- cmp ax,dx ;return with not equal
- ret
-
- Loaded? endp
-
- UnInstall proc
- call Loaded?
- jne U2
-
- ;reset interupts to original values
- mov dx,word ptr es:Vec9
- mov ax,word ptr es:Vec9[2]
- mov ds,ax
- mov ax,2509h
- int 21h ;reset int 9
- mov dx,word ptr es:Vec1C
- mov ax,word ptr es:Vec1C[2]
- mov ds,ax
- mov ax,251Ch ;reset int 1C
- int 21h
- mov ax,es
- add ax,0Ah
- mov es,ax
- mov ah,49h
- int 21h ;free memory block
- push cs
- pop ds
- mov dx,offset Removed
- mov ah,9
- int 21h ;print message
- U2: mov ah,4Ch
- int 21h ;end
-
- UnInstall endp
-
- Code ends
- end LGo
-