home *** CD-ROM | disk | FTP | other *** search
-
- title Manage the VHARD FAT cache
- subttl Prologue
- page 60,132
-
- comment {
-
- ******************************************************************************
-
- File VHCACHE.ASM
-
- Author:
- Aaron L. Brenner
-
- BIX mail address albrenner
- GEnie address A.BRENNER
-
- This program is hereby released to the public domain.
-
- Purpose:
- Provide a command-driven interface to the VHARD FAT/root dir cache.
-
- Command syntax:
- VHCACHE [? | ON | OFF | MANUAL | AUTO | FLUSH]
-
- Parameters:
- ? or INFO Display information about the cache.
- ON Enable the cache.
- OFF Disable and remove the cache.
- MANUAL Disable auto-flush.
- AUTO Enable auto-flush.
- FLUSH Write the cache to disk.
-
- If no parameters, a brief usage message is displayed.
-
- ERRORLEVEL returned:
- 0 The requested operation was performed successfully.
- 1 An error was reported by the driver.
- 2 Command syntax error.
- 3 VHARD.SYS not installed.
- 4 Invalid DOS version
- 5 Insufficient free memory
-
- Notes:
- All commands (including "?") require that VHARD.SYS be installed.
-
- Revision history:
- 1.00 07/20/90 ALB Created.
-
- ******************************************************************************
-
- endcomment {
-
- subttl Included files
- page
-
- include dd_defs.inc
- include vhard.inc
-
- subttl Program stack and data
- page
-
- vhcache_stack segment stack
-
- dw 128 dup (0)
-
- vhcache_stack ends
-
-
- vhcache_data segment
-
- assume ds:vhcache_data
-
- ax_value dw 4c00h
- dx_value dw 0
-
- vhctl_handle dw 0
- vhctl_name db 'VHARDCTL',0
-
- vhard_drive db 0ffh ; Drive assigned (FF = unavailable)
- vhard_ver dw 0 ; BCD version of driver
- vhard_BPB DOS_BPB <> ; BPB for the driver (we ignore it)
-
- cache_flags db 0 ; Flags for the cache if installed
- cache_addr dw 0, 0 ; Address of current cache
-
- cmd_block VH_CMD <>
-
- cmd_keyword db 8 dup (0) ; The keyword on the command line
-
- vhversion db 'VHARD version is $'
- vhdrive_is db 'VHARD is using drive letter $'
- cached_at db 'Currently installed cache is at $'
- needs_flushing db 'Cache needs to be FLUSHed', 13, 10, '$'
- auto_enabled db 'AUTOflush is enabled', 13, 10, '$'
-
- ;
- ; Error messages
- ;
- no_share db 'SHARE.EXE must be run before AUTOflush can be'
- db ' enabled.', 13, 10, '$'
- bad_dos_ver db 'Invalid DOS version for AUTOflush.', 13, 10, '$'
- no_memory db 'Not enough memory', 13, 10, '$'
- no_cache db 'The cache is not yet installed', 13, 10, '$'
- unk_err db 'unknown error$'
- em1 db 'drive not read$'
- em2 db 'seek error$'
- em3 db 'general failure$'
- em4 db 'CRC error$'
- em5 db 'DMA boundary error$'
- em6 db 'DMA overrun$'
- em7 db 'sector not found$'
- em8 db 'diskette is write-protected$'
- em9 db 'address mark not found$'
- em10 db 'unknown BIOS command$'
- em11 db 'unknown VHARD command$'
- em12 db 'cache already installed$'
- em13 db 'cache not installed$'
- em14 db 'cache must be flushed$'
-
- err_prefix db 'Error: $'
- crlf_str db 13, 10, '$'
-
- error_messages dw unk_err
- dw em1
- dw em2
- dw em3
- dw em4
- dw em5
- dw em6
- dw em7
- dw em8
- dw em9
- dw em10
- dw em11
- dw em12
- dw em13
- dw em14
-
-
- ;
- ; Keywords we recognize
- ;
- kw1 db 1,'?'
- kw11 db 4,'INFO'
- kw2 db 2,'ON'
- kw3 db 3,'OFF'
- kw4 db 6,'MANUAL'
- kw5 db 4,'AUTO'
- kw6 db 5,'FLUSH'
-
- keywords dw kw1, kw_info
- dw kw11, kw_info
- dw kw2, kw_on
- dw kw3, kw_off
- dw kw4, kw_manual
- dw kw5, kw_auto
- dw kw6, kw_flush
- dw 0
-
- usage_msg db 'VHCACHE v1.00 - Public Domain Software', 13, 10
- db 13, 10, 'Usage: VHPREP [? | ON | OFF | MANUAL | AUTO'
- db ' | FLUSH]', 13, 10
- db 13, 10, '? or INFO Display information on the cache'
- db 13, 10, 'ON Enable the cache'
- db 13, 10, 'OFF Disable and remove the cache'
- db 13, 10, 'MANUAL Disable auto-flush'
- db 13, 10, 'AUTO Enable auto-flush'
- db 13, 10, 'FLUSH Write the cache to disk'
- db 13, 10, '$'
-
- bad_kw db 'Unknown keyword: "$'
- bad_kw2 db '".', 13, 10, '$'
- no_driver db 'VHARD.SYS must be installed', 13, 10, '$'
-
- vhcache_data ends
-
-
- subttl Start of program code
- page
-
- vhcache_code segment
-
- assume cs:vhcache_code, ds:nothing, es:nothing, ss:vhcache_stack
-
-
- start proc
-
- call initialize ; Do program initialization
-
- assume ds:vhcache_data
-
- call do_command ; Do the command they want
- mov ax,ax_value ;
- mov dx,dx_value ;
- int 21h ;
-
- start endp
-
-
- ;*****************************************************************************
- ;
- ; Perform once-only program initialization.
- ;
- ;*****************************************************************************
- initialize proc near
-
- mov ax,vhcache_data ; Get our data segment
- mov es,ax ;
-
- assume es:vhcache_data
-
- mov si,81h ; Point to the command tail
- cld ; Make sure of direction
- init_l1:
- lodsb ; Get a character
- cmp al,' ' ; Is it a blank?
- je init_l1 ; Yep - ignore it
- cmp al,9 ; Tab?
- je init_l1 ; Yes - ignore it
- cmp al,0dh ; End of the line?
- jne init_l2 ; No - copy the keyword
- push es ; Set DS aright
- pop ds ;
-
- assume ds:vhcache_data
-
- mov dx,offset usage_msg ; Display the usage message
- mov ah,9 ;
- int 21h ;
- mov ax,4c02h ; Pretend it's an error
- int 21h ; Exit to DOS
- init_l2:
-
- assume ds:nothing
-
- dec si ; Point back to where we stopped
- mov di,offset cmd_keyword[1]; Point to where we're copying to
- mov cx,6 ; Max we want to copy
- init_l3:
- lodsb ; Get the next byte
- cmp al,' ' ; Done with the command?
- je init_l5 ; Yes - stop copying
- cmp al,9 ; Done with it?
- je init_l5 ; Yes - stop copying
- cmp al,0dh ; End of the line?
- je init_l5 ; Yes - stop copying
- jcxz init_l3 ; If the name buffer's full, ignore
- cmp al,'a' ; Is it lower case?
- jb init_l4 ; No - use it
- cmp al,'z' ; Is it?
- ja init_l4 ; Nope - use it
- xor al,20h ; Make it upper case
- init_l4:
- stosb ; Put it in the name buffer
- inc cmd_keyword[0] ; Count this character
- dec cx ; Both ways
- jmp short init_l3 ; Loop back for more
- init_l5:
- sub al,al ; Terminate it, too
- stosb ;
- push es ; Swap segments so we can release our
- push ds ; environment
- pop es ;
- pop ds ;
-
- assume ds:vhcache_data, es:nothing
-
- mov es,es:[2ch] ; Get our environment segment
- mov ah,49h ; Fn to release memory
- int 21h ;
- push ds ; Lastly, set ES to our data seg
- pop es ;
-
- assume es:vhcache_data
-
- mov dx,offset vhctl_name ; Try to get to the VHARDCTL device
- mov ax,3c02h ;
- int 21h ;
- jnc init_l6 ; If we could, make sure it's a device
- init_err:
- mov dx,offset no_driver ; Complain that the driver's missing
- mov ah,9 ;
- int 21h ;
- mov ax,4c03h ; Exit with appropriate code
- int 21h ;
- init_l6:
- mov bx,ax ; Get the handle for it
- mov vhctl_handle,ax ; Save it for later use, too
- mov ax,4400h ; Get info on the handle
- int 21h ;
- test dl,80h ; Is this a device?
- jz init_err ; No - just a file, so complain
- mov cmd_block.VC_cmd_code,CMD_GETDATA; Get driver info
- mov word ptr cmd_block.VC_buffer[0],offset vhard_drive
- mov word ptr cmd_block.VC_buffer[2],ds
- mov dx,offset cmd_block ; Write it out to the driver
- mov cx,size VH_CMD ;
- mov ax,4403h ;
- int 21h ;
- ret ; Return to Main
-
- initialize endp
-
-
- ;*****************************************************************************
- ;
- ; Perform the command specified by cmd_keyword.
- ;
- ;*****************************************************************************
- do_command proc near
-
- sub bx,bx ; Start at the base of the table
- mov cx,bx ;
- docm_l1:
- mov di,keywords[bx] ; Pick up a keyword pointer
- or di,di ; Hit the end of the table?
- jnz docm_l2 ; No - see if they match
- mov dx,offset bad_kw ; Report an unknown keyword
- mov ah,9 ;
- int 21h ;
- mov dx,offset cmd_keyword[1]; Display the errant keyword
- mov cl,cmd_keyword[0] ;
- sub ch,ch ;
- mov bx,1 ;
- mov ah,40h ;
- int 21h ;
- mov dx,offset bad_kw2 ; Finish out the message
- mov ah,9 ;
- int 21h ;
- mov ax,4c02h ; Exit with error code
- int 21h ;
- docm_l2:
- mov si,offset cmd_keyword ; Point to the keyword they entered
- mov cl,[si] ; Get the length of it
- inc cl ; Allow for length byte
- rep cmpsb ; Is this the one they entered?
- je docm_l3 ; Yep - call the routine
- add bx,4 ; Point to next table entry
- jmp short docm_l1 ; Loop back
- docm_l3:
- call keywords[2][bx] ; Call the appropriate routine
- ret ; Return to Main
-
- do_command endp
-
- subttl Command keyword handlers
- page
-
- ;*****************************************************************************
- ;
- ; Command keyword handlers
- ;
- ;*****************************************************************************
-
-
- ;*****************************************************************************
- ;
- ; Handle the "?" or "INFO" keyword.
- ; Display information about the cache.
- ;
- ;*****************************************************************************
- kw_info proc near
-
- mov al,5 ; Get the cache info
- mov word ptr cmd_block.VC_buffer[0],offset cache_flags
- mov word ptr cmd_block.VC_buffer[2],ds
- call call_driver ; Get the info
- test cache_flags,CACHE_INSTALLED ; Is the cache installed?
- jnz kwin_l1 ; Yep - display its info
- mov dx,offset no_cache ; Tell 'em it ain't there
- mov ah,9 ;
- int 21h ;
- jmp kwin_exit ; Exit now
- kwin_l1:
- mov dx,offset vhversion ; Say what version of VHARD we have
- mov ah,9 ;
- int 21h ;
- mov ax,vhard_ver ; Get the version word
- push ax ; Save it
- mov al,ah ; Display major version
- call disp_byte ;
- mov dl,'.' ;
- mov ah,6 ;
- int 21h ;
- pop ax ; Display minor version
- call disp_byte ;
- mov dx,offset crlf_str ; End the line
- mov ah,9 ;
- int 21h ;
- inc vhard_drive ; Do we have the drive assigned
- jz kwin_l2 ; Nope - don't know what drive
- mov dx,offset vhdrive_is ; Tell 'em the drive letter
- mov ah,9 ;
- int 21h ;
- mov dl,vhard_drive ;
- add dl,'@' ;
- mov ah,6 ;
- int 21h ;
- mov dl,':' ;
- mov ah,6 ;
- int 21h ;
- mov dx,offset crlf_str ; End this line
- mov ah,9 ;
- int 21h ;
- kwin_l2:
- mov dx,offset cached_at ; Tell 'em where the cache is now
- mov ah,9 ;
- int 21h ;
- mov ax,cache_addr[2] ;
- call disp_word ;
- mov dl,':' ;
- mov ah,6 ;
- int 21h ;
- mov ax,cache_addr[0] ;
- call disp_word ;
- mov dx,offset crlf_str ; End the line
- mov ah,9 ;
- int 21h ;
- test cache_flags,CACHE_DIRTY ; Is the cache dirty?
- jz kwin_l3 ; No - just exit
- mov dx,offset needs_flushing; Tell 'em it needs to be flushed
- mov ah,9 ;
- int 21h ;
- kwin_l3:
- test cache_flags,CACHE_AUTO ; AUTOflush enabled?
- jz kwin_exit ; Nope - exit now
- mov dx,offset auto_enabled ; Tell 'em about it
- mov ah,9 ;
- int 21h ;
- kwin_exit:
- ret ; Return to caller
-
- kw_info endp
-
-
- ;*****************************************************************************
- ;
- ; Output the value in AX as 4 hex digits
- ;
- ;*****************************************************************************
- disp_word proc near
-
- push ax ; Save the value
- mov al,ah ; Do the high byte first
- call disp_byte ;
- pop ax ; Now, the low byte
- disp_byte:
- push ax ; Save the low nybble
- mov cl,4 ; Move the high nybble down
- shr al,cl ;
- call disp_nybble ; Display the nybble
- pop ax ; Get low nybble back
- disp_nybble:
- and al,0fh ; Keep the low nybble
- add al,90h ; Convert to ASCII hex digit
- daa ;
- adc al,40h ;
- daa ;
- mov dl,al ; Send it to the display
- mov ah,6 ;
- int 21h ;
- ret ; Return to caller
-
- disp_word endp
-
-
- ;*****************************************************************************
- ;
- ; Handle the "ON" keyword
- ;
- ;*****************************************************************************
- kw_on proc near
-
- mov ah,51h ; Get our PSP
- int 21h ;
- mov es,bx ;
- mov bx,768 ; Need 12K at least
- mov ah,4ah ;
- int 21h ;
- jnc kwon_l1 ; If we got it, install
- mov dx,offset no_memory ; Report insufficient memory
- mov ah,9 ;
- int 21h ;
- mov byte ptr ax_value[0],5 ; Exit code
- jmp short kwon_exit ; Exit now
- kwon_l1:
- mov word ptr cmd_block.VC_buffer[0],0 ; Set cache ptr
- mov word ptr cmd_block.VC_buffer[2],es ; to PSP:0
- mov al,1 ; Enable the cache
- call call_driver ;
- jnc kwon_l2 ; If we did, continue
- call report_error ; Report the error
- jmp short kwon_exit ; Exit now
- kwon_l2:
- mov byte ptr ax_value[1],31h; Change exit fn to TSR exit
- mov dx_value,768 ; Set DX to # of paragraphs needed
- mov ah,30h ; Get our DOS version
- int 21h ;
- cmp al,3 ; At least 3.x?
- jb kwon_exit ; Nope - no auto-flush available
- mov ax,1000h ; See if SHARE is installed
- int 2fh ;
- or al,al ; Is it?
- jz kwon_exit ; Nope - no auto-flush
- mov al,4 ; Enable cache auto-flush
- call call_driver ;
- kwon_exit:
- ret ; Return to caller
-
- kw_on endp
-
-
- ;*****************************************************************************
- ;
- ; Handle the "OFF" keyword.
- ;
- ;*****************************************************************************
- kw_off proc near
-
- mov al,0 ; Disable the cache
- call call_driver ;
- jnc kwof_l1 ; If no error, release the memory
- call report_error ; Report the error
- jmp short kwof_exit ; Exit now
- kwof_l1:
- ;
- ; VHARDCTL set our VC_buffer to point to the existing cache
- ;
- mov es,word ptr cmd_block.VC_buffer[2] ; Get segment to free
- mov ah,49h ; Function to release memory
- int 21h ; Get rid of the memory
- kwof_exit:
- ret ; Return to caller
-
- kw_off endp
-
-
- ;*****************************************************************************
- ;
- ; Handle the "MANUAL" keyword
- ;
- ;*****************************************************************************
- kw_manual proc near
-
- mov al,3 ; Disable auto-flush
- call call_driver ;
- jnc kwmn_exit ; Exit if no error
- call report_error ; Report the error
- kwmn_exit:
- ret ; Return to caller
-
- kw_manual endp
-
-
- ;*****************************************************************************
- ;
- ; Handle the "AUTO" keyword
- ;
- ;*****************************************************************************
- kw_auto proc near
-
- mov ah,30h ; Get DOS version
- int 21h ;
- cmp al,3 ; Is it at least 3.x?
- jb kwau_err1 ; Nope - can't do autoflush
- mov ax,1000h ; See if SHARE is installed
- int 2fh ;
- cmp al,0 ; Is it?
- jz kwau_err2 ; Nope - report error
- mov al,4 ; Enable auto-flush
- call call_driver ;
- jnc kwau_exit ; Exit if it went
- call report_error ; Report an error
- kwau_exit:
- ret ; Return to caller
- ;
- kwau_err1:
- mov dx,offset bad_dos_ver ;
- jmp short kwau_err3 ;
- kwau_err2:
- mov dx,offset no_share ;
- kwau_err3:
- mov ah,9 ; Display the error message
- int 21h ;
- mov ax,4c04h ; Exit with appropriate error code
- int 21h ;
-
- kw_auto endp
-
-
- ;*****************************************************************************
- ;
- ; Handle the "FLUSH" keyword
- ;
- ;*****************************************************************************
- kw_flush proc near
-
- mov al,2 ; Send the "Flush Cache" command
- call call_driver ;
- jnc kwfl_exit ; Exit if it went
- mov byte ptr ax_value[0],1 ; Set exit code
- call report_error ; Report the error
- kwfl_exit:
- ret ; Return to caller
-
- kw_flush endp
-
-
- ;*****************************************************************************
- ;
- ; Call VHARDCTL.
- ;
- ; Call with command code in AL.
- ;
- ; Returns with CF = 1 if VC_status <> STS_OK
- ;
- ;*****************************************************************************
- call_driver proc near
-
- mov cmd_block.VC_cmd_code,CMD_CACHE ; It's a cache command
- mov cmd_block.VC_track,al ; Set the subcommand
- mov cmd_block.VC_status,STS_OK ; Init to "OK" status
- mov ax,4403h ; IOCTL write function
- mov dx,offset cmd_block ; Point to the data to write
- mov cx,size VH_CMD ; Number of bytes to write
- mov bx,vhctl_handle ; Handle to write to
- int 21h ; Do it
- cmp cmd_block.VC_status,STS_OK ; Did it fly?
- je clld_ok ; Yes - return CF=0
- stc ; Return error flag
- jmp short clld_exit ; Exit now
- clld_ok:
- clc ; No error
- clld_exit:
- ret ; Return to caller
-
- call_driver endp
-
-
- ;*****************************************************************************
- ;
- ; Common error-reporting routine
- ;
- ;*****************************************************************************
- report_error proc near
-
- assume ds:vhcache_data
-
- mov bl,cmd_block.VC_status ; Get the return status
- cmp bl,STS_BAD_ERROR ; See if it was an unknown error
- jne rpte_l1 ; No - point to proper error message
- mov si,offset unk_err ; Point to "Unknown error" message
- jmp short rpte_l2 ; Continue
- rpte_l1:
- sub bh,bh ; Make the error code an offset
- shl bx,1 ;
- mov si,error_messages[bx] ; Point to the error message
- rpte_l2:
- mov dx,offset err_prefix ;
- mov ah,9 ;
- int 21h ;
- mov dx,si ;
- mov ah,9 ;
- int 21h ;
- mov dx,offset crlf_str ;
- mov ah,9 ;
- int 21h ;
- mov byte ptr ax_value[0],1 ; Set exit code
- ret ; Return to caller
-
- report_error endp
-
-
- vhcache_code ends
-
- end start
-