home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 5
/
ctrom5b.zip
/
ctrom5b
/
DOS
/
UTILITY
/
DIVERSEN
/
KWIKHELP
/
KWIKGRAB.A86
< prev
next >
Wrap
Text File
|
1994-12-01
|
13KB
|
589 lines
;----------------------------------------------------------------
; KWIKGRAB 4 September 1994
; jtucker@adam.com.au
; JIM TUCKER 3:800/805
; This saves a screen to a disk file. This code is is for Eric
; Isaacson's A86V371 assembler released April 1994.
;----------------------------------------------------------------
INCLUDE \ALIB\MACROS.INC
jmp install
KEY_SCAN db 34 ;Default hotkey 'G'
KEY_SHIFT db 12 ;CTRL-ALT
REQUEST db 0 ;Set by ESC
BUSY db 0 ;Set by disk write and video
SWITCH db 0 ;Tried to unload
HOT_KEY2 db "G" ;Here for second load
FILENAME db 'SCREEN00.BIN',0 ;starting name
TRUENAME db 80 dup 0 ;filled by function 60h
NAME_POS dw ? ;points to last digit of
VIDEO_SEG dw ? ;set each time
OLD_INT10 dd ? ;trapped but not used
CRITICAL_ERROR db 0 ;set if we found one
INDOS_FLAG dd ? ;not safe to interrupt
ACTIVE db 0 ;don't use hotkey
HANDLE dw 0 ;used by file write
;----------------------------------------------------------------
; BIOS DISK - This simply sets BUSY while doing disk stuff
;----------------------------------------------------------------
NEW_INT13: cli ;just set busy
inc cs:busy
pushf ;needed for call
db 09Ah ;far call opcode
OLD_INT13 dd ? ;filled by install
pushf ;must preserve CF
dec cs:busy ;done, not busy
popf
retf 2 ;keep flags
;----------------------------------------------------------------
; BIOS VIDEO - Returns CS if called by us else sets BUSY flag
;----------------------------------------------------------------
NEW_INT10: cli
inc cs:busy ;set doin' sumthin' flag
cmp ax,0E07h ;beeping?
jne >l1 ;no
cmp bx,'BI' ;is it us?
jne >l1 ;no
cmp cx,'NS' ;doubly sure
jne >l1 ;not us
push cs ;yep, really really sure
pop bx ;return segment in BX
dec cs:busy ;not busy
iret ;just return to us
L1: pushf ;call while busy
call cs:old_int10
dec cs:busy ;no longer busy
iret ;done
;----------------------------------------------------------------
; BIOS KEYBOARD - Sets a flag if we want to save a screen
;----------------------------------------------------------------
L0: jmp exit_09
NEW_INT09: push ax,ds
mov ds,cs
cmp critical_error,0 ;did we have an error
jne l0 ;yes, forget it
cmp request,1 ;do we have one?
je l0 ;yes, doing it
cmp busy,0 ;is somebody busy?
jne l0 ;yes, forget it
in al,60h ;get key code
cmp al,key_scan ;our key?
jne l0 ;no, restore flags and exit
mov ah,2 ;get shift status
int 16h
and al,key_shift
cmp al,key_shift ;shift down?
jne l0 ;no, restore flags and exit
pop ds,ax ;as we were
PUSHALL ;save everything
mov ds,cs
mov video_seg,0B800h ;guess
mov ah,0Fh ;get mode
int 10h
cmp al,7 ;mono?
jne >l1 ;no
mov video_seg,0B000h ;bad guess
L1: mov ax,0002h ;hide mouse cursor
int 33h
xor si,si ;save screen
mov ds,cs:video_seg
mov es,cs
mov di,OFFSET video_buffer
mov cx,2000
rep movsw
mov es,cs:video_seg ;display squares
xor di,di
mov ax,07h by 254
mov cx,2000
rep stosw
mov ah,0 ;wait a bit
int 1Ah
add dx,9
mov bx,dx
L0: int 1Ah
cmp dx,bx
jne l0
mov ds,cs
mov si,OFFSET video_buffer
mov es,cs:video_seg
xor di,di
mov cx,2000
rep movsw
xor si,si ;restore screen
mov ds,cs:video_seg
mov es,cs
mov di,OFFSET video_buffer
mov cx,2000
rep movsw
mov ax,0001h ;restore moose
int 33h
mov cs:request,1 ;set flag for timer
in al,61h ;restore kb
mov ah,al
or al,80h
out 61h,al
mov al,ah
out 61h,al
cli
mov al,20h
out 20h,al
sti
xor ax,ax ;empty buffer
mov es,ax
mov ax,es:[041Ch]
mov es:[041Ah],ax
POPALL
iret
EXIT_09: pop ds,ax
db 0EAh ;JMP IMM16
OLD_INT09 dd ?
;----------------------------------------------------------------
; BIOS TIMER - Save to disk if request set
;----------------------------------------------------------------
NEW_INT08: pushf
db 09Ah ;call imm16
OLD_INT08 dd ?
sti
test cs:busy ;can we do it?
if nz jmp exit_08 ;no
test cs:request ;do we want to do it?
if z jmp exit_08 ;no
push bx,ds ;save these for dx,es
lds bx,cs:indos_flag ;test dos idle
cmp B[bx],0 ;get byte
pop ds,bx ;restore
if nz jmp exit_08 ;dos is busy
PUSHF
PUSHALL
L1: mov ds,cs ;use current segment
inc busy ;so we dont re-enter
inc active
mov request,0 ;clear the request
; Temporarily trap critical error
mov ax,3524h ;set it to ignore
CALL NEWDOS
push bx,es ;save old vector
mov dx,OFFSET new_int24 ;set our vector
mov ax,2524h ;which does nothing
CALL NEWDOS
; Open a file and write the video seg to the disk
L10: mov ds,cs
mov si,name_pos ;get this ready
L1: mov ax,3D00h ;try to open it
mov dx,OFFSET truename ;includes directory
CALL NEWDOS ;can we open it?
jc >l3 ;no, so doesn't exist
mov bx,ax ;it exist, close it
mov ah,3Eh
CALL NEWDOS
inc B[si] ;bump the filename number
cmp B[si],'9' ;too big?
jbe l1 ;no
mov B[si],'0' ;yes, make it zero
inc B[si-1] ;bump previous digit
cmp B[si-1],'9'+1 ;busted 99?
jne l1 ;no
mov B[si-1],'A' ;yes make it A
jmp l1
L3: mov ax,3C00h ;create it
mov dx,OFFSET truename
mov cx,0
CALL NEWDOS
jc >l4
mov bx,ax ;write the video to it
mov ds,cs
mov dx,OFFSET video_buffer
mov cx,4000
mov ah,40h
CALL NEWDOS
mov ah,3Eh ;close file
CALL NEWDOS
mov ax,0E07h ;go beep
int 10h
mov ds,cs:video_seg
mov si,1670 ;save screen bytes
mov es,cs
mov di,OFFSET store
mov cx,8
rep movsw
mov ds,cs ;write message
mov si,OFFSET grab_msg
mov es,cs:video_seg
mov di,1670
mov cx,8
rep movsw
mov ah,0 ;wait a sec
int 1Ah
add dx,18
mov bx,dx
L0: int 1Ah
cmp dx,bx
jne l0
mov ds,cs ;restore screen
mov si,OFFSET store
mov es,cs:video_seg
mov di,1670
mov cx,8
rep movsw
L4: dec busy
dec active
pop ds,dx ;get back es,bx
mov ax,2524h ;restore critical error
dosf
QUIT_08: POPALL
POPF
EXIT_08: iret
NEWDOS: cli
int 21h
sti
ret
;----------------------------------------------------------------
; CRITICAL ERROR - Used while writing
; This prevents "Abort, Retry Fail..."
;----------------------------------------------------------------
NEW_INT24: sti ;interrupts on
mov cs:critical_error,1 ;say no more
iret ;just return
STORE dw 8 DUP 0
GRAB_MSG dw 0FFh by ' '
dw 0FFh by '*'
dw 0FFh by ' '
dw 0FFh by 'O'
dw 0FFh by 'K'
dw 0FFh by ' '
dw 0FFh by '*'
dw 0FFh by ' '
EVEN 16
VIDEO_BUFFER db
;----------------------------------------------------------------
; This is the start of installation code
;----------------------------------------------------------------
INSTALLED_SEG dw 0
INSTALL: mov dx,sp
mov ax,OFFSET video_buffer
add ax,100h
add ax,4000
cmp ax,dx
jb >l1
L1: mov ax,0E07h
mov bx,'BI'
mov cx,'NS'
int 10h
cmp bx,'BI'
je >l1
mov installed_seg,bx
jmp unload
L1: call getscan ;hotkey option
mov si,OFFSET filename ;get truename
mov di,OFFSET truename
mov ah,60h
dosf
mov si,OFFSET truename
L2: lodsb
cmp al,0
jne l2
sub si,6 ;00 in truename
mov name_pos,si ;save position
mov si,name_pos ;get this ready
L1: mov ax,3D00h ;try to open it
mov dx,OFFSET truename ;includes directory
int 21h
jc >l2 ;no, so doesn't exist
mov bx,ax ;it exist, close it
mov ah,3Eh
int 21h
inc B [si] ;bump the filename number
cmp B [si],'9' ;too big?
jbe l1 ;no
mov B [si],'0' ;yes, make it zero
inc B [si-1] ;bump previous digit
cmp B [si-1],'9'+1 ;busted 99?
jne l1 ;no
mov B [si-1],'A' ;yes make it A
jmp l1
L2: mov ax,3400h ;get indos location
dosf
mov word ptr indos_flag, bx
mov word ptr indos_flag+2,es
mov ax,3508h ;trap INT 8
dosf
mov word ptr old_int08, bx
mov word ptr old_int08+2,es
mov ax,2508h
mov dx, OFFSET new_int08
dosf
mov ax,3509h ;trap INT 9
dosf
mov word ptr old_int09, bx
mov word ptr old_int09+2,es
mov ax,2509h
mov dx, OFFSET new_int09
dosf
mov ax,3510h ;trap INT 10
dosf
mov word ptr old_int10, bx
mov word ptr old_int10+2,es
mov ax,2510h
mov dx, OFFSET new_int10
dosf
mov ax,3513h ;trap INT 13
dosf
mov word ptr old_int13, bx
mov word ptr old_int13+2,es
mov ax,2513h
mov dx, OFFSET new_int13
dosf
mov es,[2Ch]
mov ah,49h
dosf
write installed
write file_mesg
write truename
call crlf
mov dx,OFFSET install
add dx,4000
add dx,15
shr dx,4
mov ax,3100h
dosf
ALREADY: mov dx,OFFSET already_mesg
mov ah,9
dosf
mov es,bx
mov al,es:hot_key2
mov cs:hot_key,al
write use_mesg
badexit
MESSAGE: mov ah,9
dosf
mov ax,4CFFh
dosf
@CRLF
ALREADY_MESG db cr,lf,'KWIKGRAB already installed. Use /U to unload'
db bell,cr,lf,eom
INSTALLED db cr,lf,'KWIKGRAB ■ Release 1994 JIM TUCKER',cr,lf
db 'Copyright (c) 1994 JIM TUCKER. All rights reserved',cr,lf
USE_MESG db 'Use <CTRL-ALT-'
HOT_KEY db 'G'
db '> to GRAB SCREEN as a binary file',cr,lf,0
FILE_MESG db 'First screen save file is: ',0
MEMORY_MESG db cr,lf,'Not enough memory here',bell,cr,lf,eom
HELP_MESG db cr,lf,'KWIKGRAB ■ Release 1994 JIM TUCKER',cr,lf
db 'Copyright (c) 1994 JIM TUCKER. All rights reserved',cr,lf
db 'Saves ASCII screen to binary ".BIN" file',cr,lf
db 'USAGE: KWIKGRAB [/K=Hotkey] | [/Unload]',cr,lf,eom
;----------------------------------------------------------------
; GETSCAN This gets scan code from the command line
;----------------------------------------------------------------
GETSCAN: mov dx,OFFSET help_mesg
mov si,81h
L1: lodsb
cmp al,' '
je l1
cmp al,cr
je ret
cmp al,'/'
if ne jmp message
lodsb
call caps
cmp al,'K'
if ne jmp message
lodsb
cmp al,'='
je >l2
cmp al,':'
if ne jmp message
L2: lodsb
call caps
cmp al,' '
if be jmp message
mov di,OFFSET char_string
mov cx,string_length
repne scasb
jne >l3
add key_shift,2
L3: mov hot_key,al
mov hot_key2,al
mov si,OFFSET scan
mov ah,0
add si,ax
lodsb
mov key_scan,al
ret
@CAPS
; Translation table: ASCII codes into keyboard scan codes
SCAN db 03, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, 49, 24
db 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 01, 26, 53, 27, 12
db 57, 02, 40, 04, 05, 06, 08, 40, 10, 11, 09, 13, 51, 12, 52, 53
db 11, 02, 03, 04, 05, 06, 07, 08, 09, 10, 39, 39, 51, 13, 52, 53
db 03, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, 49, 24
db 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 26, 43, 27, 07, 12
db 41, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, 49, 24
db 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 26, 43, 27, 41, 14
CHAR_STRING db '~!@#$%^&*()_+|{}:"<>?'
STRING_LENGTH EQU $-OFFSET CHAR_STRING
;----------------------------------------------------------------------
; UNLOAD
; This procedure removes KWIKGRAB from memory by replacing the vectors
; and releasing the memory used for the code and buffer.
;----------------------------------------------------------------------
UNLOAD: mov si,81h
L1: lodsb
cmp al,cr
if e jmp already
cmp al,'/'
jne l1
lodsb
call caps
cmp al,'U'
if ne jmp already
mov al,08h ;Check the timer interrupt
call check_seg
mov al,09h ;Check keyboard interrupt
call check_seg
mov al,10h ;Check the printer interrupt
call check_seg
mov al,13h ;Check dos idle interrupt
call check_seg
; Here if no interrupts have changed
L1: mov es,installed_seg
lds dx,es:old_int08
mov ax,2508h
dosf
lds dx,es:old_int09
mov ax,2509h
dosf
lds dx,es:old_int10
mov ax,2510h
dosf
lds dx,es:old_int13
mov ax,2513h
dosf
L1: mov bx,cs
mov [es:16h],bx
mov [es:0Ch],bx
mov W [es:0Ah],OFFSET quit
mov ah,50h
mov bx,es
int 21h
mov ax,4C00h
int 21h
QUIT: mov ds,cs
mov dx,OFFSET unload_mesg
QUIT2: mov ah,9
int 21h
mov ax,4C00h
int 21h ;Exit to dos
; This subroutine checks to see if an interrupt vector points to the
CHECK_SEG: mov ah,35h ;Get the vector
dosf
mov ax,es
cmp ax,installed_seg
jne >l1
ret
L1: mov dx,OFFSET cant_unload
jmp quit2
UNLOAD_MESG db cr,lf,'KWIKGRAB unloaded OK',cr,lf,eom
CANT_UNLOAD db cr,lf,'Sorry, cannot unload KWIKGRAB',7,cr,lf,eom
; This makes this file the same size as the installation so it can load high
; without having to expand
PADDING EQU OFFSET INSTALL+4000-$+100H
DB PADDING DUP 0
EVEN 16
END