;********************************************** ; XREN.ASM 2/18/84 7:45 P.M. ; ; File renaming with wild cards *,? ; allowed in both the old and new file names ; ; USAGE: XREN (d:)fileOld fileNew ; ; Program: By Miguel Vasquez based on ; program by George M Gallen ; ; needs 8080 and CP/M ;*********************************************** ; ;--------------------EQUATES-------------------- ; BDOS EQU 5 ;Entry point to CP/M functions PRINTS EQU 9 ;Func. # to Print String OPEN EQU 15 ;Func. # to Open existing File CLOSE EQU 16 ;Func. # to Close File REN EQU 23 ;Func. # to Rename File FCB0 EQU 5CH ;CP/M's FCB NOFIND EQU 0FFH ;Error code for file not found ;------------------------------------------------ ;*************** MAIN PROGRAM START ************** ORG 0100H ;Start of TPA MAIN: CALL INIT ;Initialize our Stack. LDA FCB0+1 ;Check if source file is CPI ' ' ;blank. If so give BAD JZ BF ;FORMAT messg. and exit. LDA FCB0+17 ;Check second file CPI ' ' ;also. JZ BF ; ; LXI H,FCB0+1 ;Move original file name LXI D,FCB1+1 ;to its place in LXI B,11 ;FCB1 and FCB3. CALL LDIR ; LXI H,FCB0+1 ; LXI D,FCB3+1 LXI B,11 ; CALL LDIR ; ; LXI H,FCB0+17 ;Move new file name LXI D,FCB5+1 ;to FCB5. LXI B,11 ; CALL LDIR ; ; CALL DRIVE ;Save Drive specs ; RNLOOP: LXI H,FCB3 ;Try to open source file. CALL FOPEN ; CPI NOFIND ;If unsuccessful, then no more JZ ENDIT ;files, so end it. ; LXI H,FCB0+1 ;Put full file name (now without ??) LXI D,FCB1+1 ;(with the extensions) to LXI B,11 ;the appropriate spots in CALL LDIR ;FCB1. CALL NEWNAM ;Make new full file name in FCB2. ; MVI C,CLOSE ;Close the original file LXI D,FCB0 ; CALL BDOS ; ; LXI H,FCB2+1 ;Set up new full file name LXI D,FCB4+1 ;(with extension) LXI B,11 ;in FCB4. CALL LDIR ; ; LXI H,FCB4 ;Try to open the new file CALL FOPEN ; CPI NOFIND ;Could open it? Horrors!! JNZ CANNT ;Exit without renaming. ; MVI C,REN ;Rename the old file LXI D,FCB1 ;to the new name. CALL BDOS ; ; CALL INFORM ;Inform of files renamed JMP RNLOOP ;Process next one. ; CANNT: MVI C,CLOSE ;Found a file with that name!! CALL BDOS ;close it ! ; LXI H,FCB2+1 ;Move the Bad file LXI D,MSG7 ;name and extension LXI B,8 ;into Message #7 CALL LDIR ; INX D ; LXI B,3 ; CALL LDIR ; LXI D,MSG8 ;display message and JMP STROUT ;exit. ENDIT: LXI D,MSG5 ;We're done, prepare message JMP STROUT ;Print it and return to CP/M ; BF: LXI D,MSG6 ;Prepare BAD FORMAT message JMP STROUT ;go printit and exit ; ;=============== SUBROUTINES ====================== ; ;******************************************************** ; INFORM ; ; to print message with files being renamed ;******************************************************** INFORM: LXI H,FCB1+1 ;Move old file name LXI D,MSG3 ;and extension into LXI B,8 ;MSG3. CALL LDIR ; INX D ; LXI B,3 ; CALL LDIR ; LXI H,FCB2+1 ;Move new file name LXI D,MSG4 ;and extension into LXI B,8 ;MSG4. CALL LDIR ; INX D ;Then display message LXI B,3 ;with the two names CALL LDIR ;to let us know what's LXI D,MSG1 ;going on. (Drop down ; JMP STROUT ;into STROUT to do it) ;******************************************************** ; STROUT to send a string to the console ; ; Arguments : DE has the addr. of the string to be sent ;******************************************************* STROUT: MVI C,PRINTS ;Set function code JMP BDOS ;go doit ; ;******************************************************* ; DRIVE to save drives ; ; Arguments: The first byte of FCB0 contains ; the source drive: ; 0 for the logged drive ; 1 for drive A ; 2 for drive B, etc. ;******************************************************* DRIVE: LDA FCB0 ;Get the drive # and store STA FCB1 ;it in its place in FCB1, STA FCB3 ;FCB3, and FCB4. STA FCB4 ; ORA A ;Is it the Logged drive? RZ ;Yes, leave drive blank. ADI 64 ;No, convert to letter, STA DRV1 ;Save it and STA DRV2 ;add a colon. MVI A,':' ; STA DRV1+1 ; STA DRV2+1 ; RET ; ;******************************************************** ; NEWNAM to make new name ; ; Arguments: FCB0 has a regular full filename ; FCB5 hs a file name with wild cards (?) ; On exit FCB2 will have FCB5 but ; with ?'s replaced with the corresponding ; character from FCB0. ;******************************************************** NEWNAM: MVI B,11 ;Counter (bytes in file name). LXI D,FCB2+1 ;Destination addr. in DE. LXI H,FCB0+1 ;Use Stack as an extra PUSH H ;index register for FBC0.(Source) LXI H,FCB5+1 ;Mask addr. in HL LBA: MOV A,M ;Move mask byte to A. CPI '?' ;MasK='?' ? JNZ LBB ;no, output A. XTHL ;yes, Get FCB0 index into HL. MOV A,M ;Get source byte. XTHL ;Put FCB0 index back in stack. CPI ' ' ;Is source a blank? JNZ LBB ;No, then output it. MVI C,1 ;Yes, set C to number of MOV A,B ;bytes neccessary to CPI 4 ;fill the rest of JM LBC ;the name or extension MVI C,4 ;with blanks. That is: LBC: MOV A,B ;if B<4 then C=1 else C=4 SUB C ;C=B-C MOV C,A ; LBD: MOV A,C ;If C=0 then we are ORA A ;at the last blank byte, MVI A,' ' ;Go and output it. JZ LBB ; STAX D ;Put blank in FCB5. INX H ;Increment the three INX D ;indexes. XTHL ; INX H ; XTHL ; DCR B ;Decrement the two DCR C ;counters. JMP LBD ; LBB: STAX D ;Put char. in FCB5. INX H ;Increment the three INX D ;indexes. XTHL ; INX H ; XTHL ; DCR B ;Process next byte if JNZ LBA ;not thru yet. POP H ;If thru, restore stack RET ;and return ; ;******************************************************** ; FOPEN to try to open an existing file ; ; Arguments: HL has addr. of FCB with file to be opened ;******************************************************** FOPEN: LXI D,FCB0 ;Move FCB to CP/M's LXI B,35 ;FCB. CALL LDIR ; MVI C,OPEN ;Try to open the file. LXI D,FCB0 ; CALL BDOS ; RET ; ;******************************************************** ; LDIR to simulate Z-80's LDIR ; ; used to move a string from a location to another ; ; Arguments: HL addr. of source ; DE addr. of destination ; BC Number of bytes to be moved ; ; All the registers are modified ; ; Any Z-80 based computer (such as Osborne 1's) ; can replace all the CALL LDIR's ; with: DB 0EDH,0B0H ; or replace this subroutine with ; LDIR: DB 0EDH,0B0H ; RET ;*************************************************** LDIR: MOV A,M ;Move next byte STAX D ;to its destination. INX H ;Increment the pointers INX D ;to source and destination. DCX B ;Decrement byte count. MOV A,B ;Test if BC ORA C ;is zero. RZ ; Yes, then return. JMP LDIR ; No, process another byte ; ;******************************************************** ; INIT to initialize the stack ; and save CP/M's stack ;******************************************************** INIT: POP B ;get return addr. LXI H,0 ;load HL with DAD SP ;the stack pointer. SHLD CPMSTK ;save it in CPMSTK. LXI H,MYSTAK ;Change to my stack. SPHL ; LXI D,FINISH ;Put finish routine PUSH D ;in stack. PUSH B ;put return addr.in stack. RET ;return FINISH LHLD CPMSTK ;reinstall CP/M's stack SPHL ; RET ;and return to CP/M. ; ;========================= DATA AREAS ================== FCB1: DB 0 ;Drive for the Original FCB, DB '????????' ;Name DB '???' ;Extension DB 0,0,0,0 ;Filler ; FCB2: DB 0 ;New FCB, (drive) DB '????????' ;Name DB '???' ;Extension DB 0,0,0,0 ;Filler ; FCB3: DB 0 ;Full original FCB DB '????????' DB '???' DB 0,0,0,0,0 DB 0,0,0,0,0 DB 0,0,0,0,0 DB 0,0,0,0,0 DB 0,0,0 ; FCB4: DB 0 ;Full new FCB DB '????????' DB '???' DB 0,0,0,0,0 DB 0,0,0,0,0 DB 0,0,0,0,0 DB 0,0,0,0,0 DB 0,0,0 ; FCB5: DB 0 ;Mask for New FCB DB '????????' ;Name DB '???' ;Extension ; ; misc messages to let you know what's going on ; MSG1: DB 'RENAMING ' DRV1: DB ' ' ;2 spaces MSG3: DB ' ' ;8 spaces DB '.' DB ' ' ;3 spaces DB ' TO ' MSG4: DB ' ' ;8 spaces DB '.' DB ' ' ;3 spaces DB 13,10,'$' MSG5: DB 10,'No more matches',13,10 DB 'I AM DONE......',13,10,'$' MSG6: DB '* INVALID FORMAT *',13,10,10 DB 'It should be : ' DB 'XREN [d:]fileOld fileNew',13,10,10,7,'$' MSG8: DB 10,'THE FILE ' DRV2: DB ' ' ;2 spaces MSG7: DB ' ' ;8 spaces DB '.' DB ' ' ;3 spaces DB ' ALREADY EXISTS. ',13,10 DB 'PROCESSING HALTED. CANNOT RENAME ALL FILES' DB 13,10,10,7,'$' ; CPMSTK DS 2 ;CP/M's stack pointer DS 40 ; MYSTAK EQU $ ;My stack. END