home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1985
/
04
/
red.asm
next >
Wrap
Assembly Source File
|
1986-02-05
|
10KB
|
259 lines
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