home *** CD-ROM | disk | FTP | other *** search
- RED segment para public 'code'
- assume cs:RED, ds:RED, es:RED, ss:NOTHING
- org 100h ; .COM format
- BEGIN:
- jmp CODE_START ; Jump around data declarations
- ;
- DECLARE: ; Messages, Storage Areas, Equates
- COPYRIGHT db 'REDirect (C) 1985, Dickinson Associates Inc.'
- db 13,10,'$'
- PATH_FILE_LEN equ 77 ;Length = 1, Path = 63, FileName = 12, 0 = 1
- SOURCE_FILE db PATH_FILE_LEN dup (0)
- TARGET_PATH db PATH_FILE_LEN dup (0)
- SOURCE_END dw 0
- TARGET_END dw 0
- PC_DOS_VER db 0
- VALID_IN db 'abcdefghijklmnopqrstuvwxyz,;=',9
- VALID_OUT db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
- VALID_NUM equ $ - VALID_OUT + 1
- ERR_FLAG db 0
- ERR_HEAD db 10,13,'REDirect Error - $'
- BAD_VERSION db 'Incorrect PC-DOS Version$'
- NO_PARMS db 'Correct Syntax is:',13,10,10
- db 'RED [d:][source_path]source_filename[.ext] [d:][target_path]$'
- FILE_NOT_FOUND db 'File Not Found$'
- PATH_NOT_FOUND db 'Target Path Not Found$'
- PC_DOS_2_PATCH db 13,10,'or $'
- DRIVES_CONFLICT db 'Source and Target Disk Drives Conflict$'
- UNDEFINED_ERR db 'Undefined Error: PC-DOS Function 56H$'
- ERR_TAIL db 10,10,13,' . . . Aborting',10,13,13,'$'
- GOOD_MSG db ' . . REDirected to . . $'
- BAD_MSG1 db ' . . NOT REDirected . . $'
- BAD_MSG2 db ' . . already exists$'
- END_LINE db 10,13,'$'
- ;
- CODE_START: ; Parse command line into source & target parameters
- mov dx,offset COPYRIGHT ; Display copyright notice
- mov ah,9h
- int 21h
- mov ah,30h ; Get PC-DOS Version
- int 21h
- mov PC_DOS_VER,al
- mov si,80h ; PSP parameter byte count pointer
- mov cl,[si] ; Move byte count to CL
- xor ch,ch ; Zero CH
- jcxz NO_PARMS_PASSED ; If CX is zero, there are no parameters
- mov dx,cx ; Save byte count in dx
- inc si ; Point to parameter area
- mov di,si ; Copy SI to DI for cleanup routine
- cld ; Set direction flag to forward
- CLEAN_PARMS: ; Change valid delimiters to blanks, lower to upper case
- lodsb ; Load each character to AL
- push di ; Save DI on stack
- mov di,offset VALID_IN ; Point to table of valid inputs
- push cx ; Save CX on stack
- mov cx,VALID_NUM ; Set CX to number of inputs to look for
- repne scasb ; See if any are in AL
- jcxz CLEAN_END ; If not, change nothing
- mov bx,VALID_NUM ; Set up BX to point to valid output
- sub bx,cx ; This will leave BX one off
- mov al,VALID_OUT [bx - 1] ; Load the valid output to AL
- CLEAN_END:
- pop cx ; Restore CX
- pop di ; Restore DI
- stosb ; Store modified AL back to PSP
- loop CLEAN_PARMS ; Loop until CX is zero
- ;
- mov cx,dx ; Restore number of bytes in PSP to CX
- mov dx,2 ; Set DX to look for up to 2 parameters
- mov bx,offset SOURCE_FILE ; Set BX to address of 1st parameter
- mov al,' ' ; Set up to scan for first non-blank
- mov di,81h ; Set DI to PC-DOS parameter pointer
- FIND_PARMS: ; Start looking for parameters, load to program storage
- repe scasb ; Scan while blanks
- mov si,di ; Set SI to second non-blank byte
- dec si ; Adjust it to first non-blank byte
- inc cx ; Adjust CX to compensate
- jcxz PARMS_LOADED ; If CX is zero, no parameters left
- mov di,bx ; Set DI to parameter hold area
- mov ax,cx ; Store CX to first byte of hold area
- stosb ; DI is adjusted to second byte here
- STORE: lodsb ; Load each byte to AL
- cmp al,' ' ; Is it a blank?
- jz END_STORE ; Yes, end of this parameter
- stosb ; No, store the byte to hold area
- END_STORE:
- loopnz STORE ; Keep looking
- sub [bx],cx ; Store number of bytes in each
- jcxz PARMS_LOADED ; If CX is zero, no more parameters
- dec byte ptr [bx] ; parameter to first byte of hold area
- mov di,si ; Set up to scan for next non-blank
- dec di ; Adjust DI to point to the blank
- inc cx ; Adjust CX to compensate
- dec dx ; Decrement DX counter
- cmp dx,0 ; Is DX zero?
- jz PARMS_LOADED ; Yes, all expected parameters loaded
- add bx,PATH_FILE_LEN ; No, point to next part of hold area
- jmp FIND_PARMS ; Go back and look for more
- PARMS_LOADED: ; All parameters are loaded
- cmp SOURCE_FILE[0],0 ; If there are no bytes in the
- ja FIX_UP ; SOURCE_FILE, no parameters present
- NO_PARMS_PASSED: ; Exit with an error if there
- mov dx,offset NO_PARMS ; are no parameters passed
- jmp ERROR_EXIT
- FIX_UP: ; Fix SOURCE_FILE and TARGET_PATH
- mov si,offset SOURCE_FILE ; For Search and Rename calls
- lodsb ; Get Number of bytes
- xor ah,ah ; Zero high byte of AX
- mov di,si ; Move SI to DI for scan
- add di,ax ; Start scan at end of parameter
- dec di
- mov cx,ax ; Set CX to number of bytes
- mov al,'\' ; Scan for the last '\'
- std ; Set direction flag to reverse
- repnz scasb ; Scan while not '\'
- jnz NO_SOURCE_DIR ; If Zero Flag not set, '\' not found
- add di,2 ; Add 2 to DI to point to file name
- jmp SOURCE_FIXED ; position
- NO_SOURCE_DIR: ; No source directory was specified
- add di,1 ; Adjust DI
- cmp SOURCE_FILE[2],':' ; Check for specified disk drive
- jne SOURCE_FIXED ; None present, we're done
- mov di,offset SOURCE_FILE[3]; Yes, set DI to point to first byte
- SOURCE_FIXED: ; after ':'
- mov SOURCE_END,di ; Move DI to SOURCE_END pointer
- ;
- cld ; Set direction flag to forward
- mov si,offset TARGET_PATH ; Set up to look for '\' present
- lodsb ; Get number of bytes
- cmp al,0 ; If it's zero, no target specified
- je NO_TARGET
- xor ah,ah ; Zero high byte of AX
- add si,ax ; Add it to SI to point to end
- dec si ; Decrement SI to adjust
- lodsb ; Look at last byte
- mov di,si ; Copy SI to DI
- cmp al,'\' ; Is last byte a '\'?
- je TARGET_FIXED ; Yes, everything's fine
- cmp TARGET_PATH[0],2 ; If TARGET_PATH is 2 bytes long and
- jne STORE_SLASH ; is a disk drive specification,
- cmp TARGET_PATH[2],':' ; let it default to the current
- je TARGET_FIXED ; directory.
- STORE_SLASH: ; Place a '\' at the end of
- mov al,'\' ; TARGET_PATH if user did
- stosb ; not
- TARGET_FIXED:
- mov TARGET_END,di ; Move DI to TARGET_END pointer
- jmp FIND_FILE
- NO_TARGET: ; Set up to allow target path default
- mov TARGET_END,offset TARGET_PATH + 1 ; to current path
- FIND_FILE:
- mov dx,offset SOURCE_FILE + 1 ; DX points to SOURCE_FILE
- mov ah,4eh ; Request function 4EH (find 1st file)
- mov cx,0 ; Set CX to zero for normal files only
- int 21h ; Call PC-DOS
- jnc FOUND_FILE ; If no error, first file found
- mov dx,offset FILE_NOT_FOUND ; If no files found, exit
- jmp ERROR_EXIT ; program with error message
- FOUND_FILE:
- mov di,SOURCE_END ; DI points to end of source path
- mov si,9eh ; SI points to default DTA in PSP
- mov cx,13 ; DTA will have 13 bytes
- rep movsb ; Move bytes to SOURCE_FILE
- mov di,TARGET_END ; DI points to end of target path
- mov si,9eh ; SI points to default DTA in PSP
- mov cx,13 ; DTA will have 13 bytes
- rep movsb ; Move bytes to TARGET_PATH
- ;
- mov dx,offset SOURCE_FILE + 1 ; DX points to old file name
- mov di,offset TARGET_PATH + 1 ; DI points to new file name
- mov ah,56h ; Request function 56H (rename file)
- int 21h ; Call PC-DOS
- jnc GOOD_RED ; If no error, call was successful
- cmp ax,3 ; Check for error 3 (path not found)
- jne ERR_5
- mov dx,offset PATH_NOT_FOUND
- jmp ERROR_EXIT ; Exit program with error message
- ERR_5: cmp ax,5 ; Check for error 5 (file inaccessible)
- jne ERR_17
- mov ERR_FLAG,1 ; Soft error -
- call RED_MSG ; Issue message with subroutine
- jmp NEXT_FILE ; and keep going
- ERR_17: cmp ax,17 ; Check for error 17 (drive conflict)
- jne UNDEF
- mov dx,offset DRIVES_CONFLICT
- jmp ERROR_EXIT ; Exit program with error message
- UNDEF: mov dx,offset UNDEFINED_ERR ; Undefined error from function 56H
- jmp ERROR_EXIT ; Exit program with error message
- GOOD_RED:
- mov ERR_FLAG,0 ; Set error flag off and
- call RED_MSG ; issue message with subroutine
- NEXT_FILE: ; Look for next file
- mov ah,4fh ; Request function 4FH (find next file)
- mov cx,0
- int 21h
- jnc FOUND_ANOTHER ; No error, another file was found
- jmp END_OK ; Error, we're done finding files
- FOUND_ANOTHER:
- jmp FOUND_FILE ; Go process next file
- END_OK: int 20h ; Exit to PC-DOS
-
- ERROR_EXIT: ; Print Error Message and Exit
- push dx ; Save error message pointer on stack
- mov ah,9 ; Display error header
- mov dx,offset ERR_HEAD
- int 21h
- mov ah,9 ; Display error message
- pop dx
- int 21h
- mov ah,9 ; Display error tail
- mov dx,offset ERR_TAIL
- int 21h
- int 20h ; Exit to PC-DOS
- ;
- RED_MSG proc near ; Display message for each file
- mov cx,2 ; 2 fields - source & target file
- mov bx,offset SOURCE_FILE + 1 ; Point to source file
- START1: mov si,bx ; Copy BX to SI
- START2: lodsb ; Load each byte to AL
- cmp al,0 ; If ASCII 0, end of field
- je BETWEEN
- mov dl,al ; Copy byte to DL for funciton 2H
- mov ah,2h ; Request function 2H
- int 21h ; Call PC-DOS
- jmp START2 ; Get next character
- BETWEEN:cmp cx,2 ; Is it first or second field?
- jne CR_LF ; If second, display end of message
- cmp ERR_FLAG,0 ; Is this a success message?
- jz OK1 ; Yes, go use GOOD_MSG
- mov dx, offset BAD_MSG1 ; No, display first part of BAD_MSG
- mov ah,9h ; Request function 9H
- int 21h ; Call PC-DOS
- jmp NEXT ; Go process next field
- OK1: mov dx,offset GOOD_MSG ; Display GOOD_MSG
- mov ah,9h ; Request function 9H
- int 21h ; Call PC-DOS
- jmp NEXT ; Go process next field
- CR_LF: cmp ERR_FLAG,0 ; Is this a success message?
- jz OK2 ; Yes, go terminate message
- mov dx,offset BAD_MSG2 ; No, display second part of BAD_MSG
- mov ah,9h ; Request function 9H
- int 21h ; Call PC-DOS
- PC_DOS_2: ; Patch for incorrect error
- cmp PC_DOS_VER,3 ; return in PC-DOS 2.0 and 2.1
- jae OK2
- mov dx,offset PC_DOS_2_PATCH
- mov ah,9h
- int 21h
- mov dx,offset PATH_NOT_FOUND
- int 21h
- OK2: mov dx,offset END_LINE ; Terminate display line
- mov ah,9h ; Request function 9H
- int 21h ; Call PC-DOS
- NEXT: add bx,PATH_FILE_LEN ; Move BX to point to next field
- loop START1 ; Loop for second field
- ret ; Or end and return to callint point
- RED_MSG endp
- RED ends
- end BEGIN