; PROGRAM: RENAME ; VERSION: 3.0 ; DATE: 18 MAY 84 ; AUTHOR: RICHARD CONN ; PREVIOUS VERSIONS: 2.0 (16 JAN 83) ; PREVIOUS VERSIONS: 1.4 (6 JAN 83), 1.3 (7 DEC 82), 1.2 (10 NOV 82) ; PREVIOUS VERSION: RENAME.ASM Version 1.1 (26 OCT 81) ; vers equ 34 ; z3env defl 0fe00h ; ; Version 3.4 -- March 31, 1990 -- Gene Pizzetta ; Modified for more compact display, usually a single line for each ; file renamed. ^C aborts at any prompt. ; ; Version 3.3A -- December 30, 1987 -- Bruce Morgen ; Strip high bit from EFCB program name characters. "E" and "S" ; options require Wheel byte set; help message reflects this. ; ; Version 3.3 -- December 19, 1987 -- Bruce Morgen ; Help message now reflects actual COM file name used, PPIP-style ; dual syntax implemented (as requested by Ken Taschner). This ; required some rather tricky parsing to support the single-filespec ; syntax "afn.typ [/]c", so while I was at it I made control mode ; mandatory and automatic for single-filespec elements and eliminated ; the C option letter altogether (as Rick says: "it only makes ; sense"...). In order support this single-filespec mode when such ; an element is the last (or only) one in a RENAME command line, the ; second file-spec in the last (or only) command is tested if the ; MS-DOS syntax is detected. If that second filespec starts with a ; "/" or includes only valid option letters (and no more characters ; than the number of valid option letters) it is assumed to be an ; option specifier rather than a rename-to filespec. Following ; Howard Goldstein's (LX17 & 18) lead, filespec-to-FCB parsing calls ; the Z33 CCP if it's available. A Z80, HD64180, NSC800 or (someday?) ; Z280 CPU now is required. ; ; Version 3.2 -- August 25, 1987 -- Jay Sage ; Changed to allow a leading slash before an option to make program ; consistent with a number of other Z programs (this was supposed to ; happen, but there was a bug in the code). Put data into a DSEG. ; Made header indicate load address. ; ; Version 3.1 -- April 12, 1987 -- Jay Sage ; Took idea of Rick Charnes and implemented it as an option so that ; one does not have to have two versions of the program. The option ; is 'E'. Also updated code to ZCPR33 type-3 environment to allow ; linking RENAME for execution in high memory if desired. ; ; Version 3.0a -- April 9, 1987 -- Rick Charnes ; I have modified this source code slightly so that if you try to ; rename FILE1 to FILE2 and FILE2 already exists, the program will ; NOT ask you if you are sure you want to delete FILE2. It just ; goes ahead and deletes the darn thing and renames FILE1. I had ; an application for it, studied and little and ... it works. Be ; careful, though. This is a special use program, and NOT for ; everyday use. I found an alias in which I needed it. ; ; RENAME is used to change the name of one or more files. Unlike the ; ZCPR2-resident REN function, RENAME permits ambiguous filenames and ; supports an Inspect mode that allows the user to confirm each rename ; before it is done. Additionally, there is a Control Mode which allows ; the user to manually specify the name for each file as it is presented ; to him. ; ; RENAME dir:afn1=afn2,dir:afn3=afn4,... [/]o ; RENAME dir:afn2 afn1,dir:afn4 afn3,... [/]o ; RENAME dir:afn,dir:afn1=afn2,,dir:afn4 afn3... [/]o ; ; The first form shows elements of the CP/M style: ; dir:afn1=afn2 ; The second form shows elements of the MS-DOS style: ; dir:afn2 afn1 ; The third form adds the single-filespec: ; dir:afn ; which automatically invokes a Control Mode allowing the user to rename ; files individually. ; ; Option characters (o) are none or more of the following: ; I -- Inspect and approve each rename ; S -- Include SYStem files ; E -- Erase existing file without prompt ; ; Examples: ; RENAME *.MAC=*.ASM <-- rename all ASM files to MAC ; RENAME *.MAC <-- rename all MAC files to names input by user ; RENAME *.OBJ=*.COM SI <-- rename all COM files to OBJ, include SYStem ; files, and Inspect and approve each change ; false equ 0 true equ not false esize equ 16 ; SIZE OF DIR ENTRY (FROM SYSLIB DIRF ROUTINE) public cout ; So SYSLIB will use ours ext dirq ; DIRECTORY PROCESSOR ext z33chk ; Z33LIB test for version 3.3 ext z33fname ; Z33LIB CCP-based parser ext z3init ; INIT BUFFERS ext zfname ; FILE NAME PROCESSOR ext z3log ; Z3 DU LOG ext getefcb ; Get Z3's External FCB ext getwhl ; Get/test Z3's Wheel byte ext f$delete ; DELETE FILE ext f$rename ; RENAME FILE ext bbline ; INPUT LINE EDITOR ext initfcb ; INIT FCB ext bdos ; BDOS ENTRY ext putud ; SAVE CURRENT USER/DISK ext getud ; RESTORE CURRENT USER/DISK ext moveb ; COPY ROUTINE ext phldc ; PRINT HL AS DECIMAL CHARS ext eprint ; PRINT ROUTINE ext phl4hc ; PRINT HL AS 4 HEX CHARACTERS TO CONSOLE ext bout ; CONSOLE OUTPUT ROUTINE ext cin ; CONSOLE INPUT ROUTINE ext caps ; CAPITALIZE ROUTINE ext crlf ; NEW LINE ROUTINE ext fillb ; FILL ROUTINE ext codend ; CODE END COMPUTATION ROUTINE ; CP/M EQUATES fcb equ 5ch ; FCB buff equ 80h ; INPUT LINE BUFFER cr equ 13 ; carriage return lf equ 10 ; linefeed bel equ 7 ; bell ctrlc equ 3 ; ^C ; Environment Definition ; TYPE 3 HEADER ; Code modified as suggested by Charles Irvine to function correctly with ; interrupts enabled. Program will abort with an error message when not ; loaded to the correct address (attempt to run it under CP/M or Z30). entry: jr start0 ; Must use relative jump nop ; Filler db 'Z3ENV',3 ; Type-3 environment z3eadr: dw z3env ; Filled in by Z33 dw entry ; Intended load address start0: ld hl,0 ; Point to warmboot entry ld a,(hl) ; Save the byte there di ; Protect against interrupts ld (hl),0c9h ; Replace warmboot with a return opcode rst 0 ; Call address 0, pushing RETADDR ; onto stack retaddr: ld (hl),a ; Restore byte at 0 dec sp ; Get stack pointer to point dec sp ; To the value of RETADDR pop hl ; Get it into HL and restore stack ei ; We can allow interrupts again ld de,retaddr ; This is where we should be xor a ; Clear carry flag push hl ; Save address again sbc hl,de ; Subtract -- we should have 0 now pop hl ; Restore value of RETADDR jr z,start ; If addresses matched, begin real code ld de,notz33msg-retaddr ; Offset to message add hl,de ex de,hl ; Switch pointer to message into DE ld c,9 jp 0005h ; Return via BDOS print string function notz33msg: db 'Not Z33+$' ; Abort message if not Z33-compatible ; Start of Program start: ld (stack),sp ; SAVE THE STACK call codend ld (cmdlne),hl ; SETUP COMMAND LINE BUFFER ld de,100h ; BUFFER SIZE add hl,de ld (ntfcb),hl ; SET TEMP FCB add hl,de ld (dirbuf),hl ; PTR TO DIR BUFFER ld sp,hl ; NEW SP ld hl,(ntfcb) ; SET 2ND FCB ld de,40 add hl,de ld (ofcb),hl ld hl,(z3eadr) ; Point to ZCPR3 environment call z3init ; Initialize the ZCPR3 Env call putud ; SAVE CURRENT USER/DISK AWAY call eprint db 'RENAME Version ' db Vers/10+'0','.',(Vers mod 10)+'0',' (loaded at ',0 ld hl,entry call phl4hc call eprint db 'h)',0 ld a,(fcb+1) ; GET FIRST CHAR OF FILE NAME cp ' ' ; NO FILE SPEC? jr z,help cp '/' ; OPTION CAUGHT? jp nz,econt ; PRINT HELP INFORMATION help: call eprint db cr,lf,'Syntax:',cr,lf db ' Old style: newname=oldname',cr,lf,' ',0 call comnam call eprint db ' {dir:}afn.aft=afn.aft{,{dir:}afn.aft=afn.aft{,...}} {{/}options}',cr,lf db ' New style: oldname newname',cr,lf,' ',0 call comnam call eprint db ' {dir:}afn.aft afn.aft{,{dir:}afn.aft afn.aft{,...}} {{/}options}',cr,lf db ' Interactive control mode: oldname',cr,lf,' ',0 call comnam call eprint db ' {dir:}afn.aft{,{dir:}afn.aft{,...}} {{/}options}',cr,lf db ' All three forms may be mixed within a command line.',cr,lf db 'Options:',cr,lf db ' I Inspect mode (get user approval).' db 0 call getwhl jr z,return call eprint db cr,lf,' S Include system files.',cr,lf db ' E Erase existing files without prompting.' db 0 ; RETURN TO OS return: call getud ld sp,(stack) ; GET OLD STACK ret ; COPY BUFFER INTO TEMP BUFFER econt: ld de,(cmdlne) ; PT TO COMMAND LINE SAVE BUFFER ld hl,buff+1 ; PT TO BUFFER ld b,80h ; BUFFER SIZE call moveb ; COPY INTO COMMAND LINE BUFFER ; EXTRACT FLAGS IF PRESENT xor a ; SET NO INSPECT, NO R/O, AND NO SYSTEM FILES ld (inspect),a ld (eraflag),a ; SET NO ERASE WITHOUT PROMPT ld a,80h ; SELECT NON-SYS FILES ONLY ld (system),a ld hl,0 ; SET FILE COUNT ld (filecnt),hl ld hl,(cmdlne) ; PT TO BUFFER ; SKIP TO FILE NAME STRING sblank: ld bc,127 xor a cpir ld c,33 ld a,',' cpdr jr z,gcomma commaz: ld hl,(cmdlne) jr ncomma gcomma: push hl ld de,(cmdlne) xor a sbc hl,de pop hl jp z,help jr c,commaz inc hl inc hl ncomma: ld de,argtbl ld a,3 ld (de),a xor a call argv jp nz,help inc de ld a,(de) cp 3 jr z,triarg cp 2 jp nz,dspec ld hl,(argum2) dec hl ld a,(hl) inc hl sub '=' jp z,dspec calloq: call optq jp nz,dspec dec hl ld (hl),a inc hl jr option triarg: ld hl,(argum3) ld a,(hl) ; CHECK FOR LEADING SLASH ON OPTION AND SKIP IT IF SO opt: cp '/' ; OPTION CHAR? jr nz,option inc hl ; SKIP SLASH ; PROCESS LIST OF OPTIONS option: ld a,(hl) ; GET BYTE or a ; DONE? jr z,dspec inc hl ; PT TO NEXT CHAR cp ' ' ; SKIP OVER SPACES jr z,option cp '/' ; IF OPTION LETTER, OBVIOUS ERROR, SO HELP jp z,help cp 'E' ; ERASE OLD FILES? jr z,optera cp 'I' ; INSPECT? jr z,optins cp 'S' ; SYSTEM FILES? jp nz,help push af call getwhl jr z,nowhl pop af ld a,0c0h ; SET FOR SYS FILES ld (system),a jr option ; optera: push af call getwhl jr z,nowhl pop af ld a,0ffh ; AUTO ERASE MODE ld (eraflag),a jr option optins: ld a,0ffh ; INSPECT ld (inspect),a jr option nowhl: ld a,'"' call bout pop af call bout call eprint db '" option denied, Wheel privileges required.',cr,lf,0 jr option ; EXTRACT DISK, USER, AND FILE NAME INFORMATION dspec: ld hl,(cmdlne) ; PT TO BEFORE FIRST BYTE dec hl dspec0: inc hl ; PT TO BYTE ld a,(hl) ; GET BYTE or a ; DONE? jp z,help cp ' ' ; ? jr z,dspec0 ; MAJOR REENTRY POINT WHEN FILE SPECS ARE SEPARATED BY COMMAS ; HL PTS TO FIRST BYTE OF NEXT FILE SPEC dspec1: xor a ld (control),a call getud ; RESET USER IF NECESSARY ld de,(ntfcb) ; PT TO FCB IN DE call parsit ; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER ld (nextch),hl ; SAVE PTR TO DELIMITER WHICH ENDED SCAN call z3log ; LOG INTO DU ; FIRST NAME IS NOW EXTRACTED -- EXTRACT POSSIBLE SECOND NAME name2: ld de,(ofcb) ; PT TO FCB FOR 2ND NAME ld hl,(ntfcb) ; PT TO FIRST NAME ld b,16 ; COPY 16 BYTES call moveb ld hl,(nextch) ; PT TO CHAR WHICH ENDED PARSE ld a,(hl) ; GET IT cp '=' ; ASSIGNMENT? jr z,gotequ cp ' ' ; Reverse assignment? jr z,gotequ ld a,0ffh ld (control),a jr rename gotequ: push af inc hl ; PT TO CHAR AFTER '=' or space ld de,(ofcb) ; PT TO TEMP FCB call parsit ; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER ld (nextch),hl ; SAVE PTR TO DELIMITER WHICH ENDED SCAN pop af cp '=' jr z,rename ld hl,(ofcb) ; Swap pointers for MS-DOS "style" ld de,(ntfcb) ld (ofcb),de ld (ntfcb),hl ; LOAD DIRECTORY AND RENAME FILES rename: ld de,(ofcb) ; PT TO FCB ld hl,(dirbuf) ; PT TO END OF CODE call initfcb ; INIT THE FCB ld a,(system) ; SET FLAGS call dirq ; LOAD DIR, SELECT FILES, PACK, AND ALPHABETIZE ; REN DIR FILES; HL PTS TO FIRST FILE, BC=FILE COUNT call renfiles ; CHECK FOR NEXT FILE SPEC ld hl,(nextch) ; GET PTR ld a,(hl) ; GET DELIM cp ',' ; ANOTHER FILE? jr nz,rendone inc hl ; PT TO CHAR AFTER COMMA jr dspec1 ; CONTINUE PROCESSING ; RENAME COMPLETE -- PRINT COUNT AND EXIT rendone: call prcount ; PRINT FILE COUNT jp return ; RENAME SELECTED FILES renfiles: ld a,b ; CHECK FOR ANY FILES LOADED or c ret z ; PRINT FILE NAME renlp: push bc ; SAVE ENTRY COUNT call eprint db cr,lf,' ',0 push hl ; SAVE PTR TO FCB ld hl,(ntfcb) ; COPY NEW TEMPLATE INTO RENFCB ld de,renfcb ld b,16 call moveb pop hl ; GET PTR push hl ; SAVE PTR inc hl ; PT TO FN OF OLD NAME inc de ; PT TO FN OF RENFCB ld b,11 ; 11 BYTES TO FN AND FT renlp1: ld a,(de) ; GET CHAR OF NEW cp '?' ; CHANGE '?' TO OLD CHAR jr nz,renlp2 ld a,(hl) ; GET OLD CHAR and 7fh ; MASK OLD CHAR ld (de),a ; STORE IT AWAY AS NEW renlp2: inc hl ; PT TO NEXT CHAR inc de djnz renlp1 ; COUNT DOWN ld hl,renfcb ; PT TO NEW NAME call prfn ; PRINT FILE NAME pop hl ; get ptr to old file name ; CHECK FOR CONTROL MODE AND PERFORM CONTROL FUNCTION IF SET ld a,(control) ; GET FLAG or a ; NZ=YES jr nz,renctrl ; call eprint db ' from ',0 ; pop hl ; GET PTR TO OLD FILE NAME push hl ; SAVE IT AGAIN call prfn ; PRINT FILE NAME pop hl ; GET PTR ; CHECK FOR INSPECTION AND INSPECT IF SET ld a,(inspect) ; GET FLAG or a ; 0=NO jp z,doit ; PROMPT USER FOR RENAME call renq ; REN QUESTION cp CtrlC ; QUIT? jp z,quit cp 'Y' ; YES? jp z,doit ; DON'T RENAME FILE nodo: ld a,(control) or a call nz,crlf call eprint db ' NOT Renamed',0 jp rentest ; PRINT FILE NAME PTED TO BY HL prfn: inc hl ; PT TO FILE NAME ld b,8 ; PRINT NAME call prnt ld a,'.' ; DECIMAL call bout ld b,3 ; PRINT TYPE jp prnt ; PROMPT USER FOR RENAME renq: call eprint ; PRINT PROMPT db ' Rename (Y/[N])? ',0 call cin ; GET RESPONSE call caps ; CAPITALIZE cp 'Y' jr z,cout cp CtrlC ret z ld a,'N' cout: jp bout ; ECHO ; CONTROL FUNCTION -- ALLOW USER TO RENAME AS HE DESIRES renctrl: push hl ; SAVE PTR TO FILE rctrl: call eprint db ' New Name (=Skip)? ',0 ld a,0ffh ; CAPITALIZE call bbline ; INPUT LINE FROM USER or a ; CHECK FOR JUST jr nz,rctrl0 pop hl ; GET PTR TO FILE jp nodo ; PROCEED WITH NEXT ENTRY rctrl0: ld de,renfcb ; PLACE INTO NEW NAME FCB call parsit ; JUST EXTRACT NAME ld b,11 ; CHECK FOR ANY WILD CHARS rctrl1: inc de ; PT TO NEXT CHAR ld a,(de) ; GET IT cp '?' ; CAN'T BE WILD jr z,werr cp '*' ; CAN'T BE WILD jr z,werr dec b ; COUNT DOWN jr nz,rctrl1 jr rdoit ; DONE -- PERFORM RENAME werr: call eprint db bel,cr,lf,' No Wild Cards,',0 jr rctrl ; QUIT RENAME PROGRAM quit: call eprint db '^C',0 call prcount ; PRINT COUNT OF FILES RENAMED jp return ; REN FILE, BUT GET PTR FIRST rdoit: pop hl ; GET PTR ; RENAME FILE; OLD NAME PTED TO BY HL, NEW NAME IN RENFCB doit: push hl ; STEP 1 -- DETERMINE IF NEW NAME ALREADY EXISTS ld de,renfcb ; PT TO NEW NAME call initfcb ld c,17 ; SEARCH FOR FIRST call bdos inc a ; NOT FOUND? jr z,doit1 ld a,(eraflag) ; SEE IF UNPROMPTED ERASING OPTION IN EFFECT or a jr nz,delold ; IF SO, SKIP PROMPT ld a,(control) ; control mode? or a call nz,crlf call eprint db bel,' Exists, Delete (Y/[N])? ',0 call cin ; GET RESPONSE call caps cp 'Y' jr z,cout1 cp CtrlC jr z,quit ld a,'N' cout1: call bout pop hl ; PREP FOR ABORT cp 'Y' ; YES -- CONTINUE? jp nz,nodo ; NOT YES, SO SKIP IT push hl ; SAVE POINTER AGAIN delold: call initfcb ; CLEAR FCB ld c,30 ; SET FILE ATTRIBUTES TO R/W IF NOT ALREADY call bdos call initfcb call f$delete ; DELETE FILE doit1: pop hl ; HL PTS TO OLD NAME ; CLEAR THE OLD NAME'S ATTRIBUTES IN CASE IT WAS R/O push hl ; SAVE PTR TO OLD NAME ld de,(ofcb) ; COPY OLD NAME ld b,16 call moveb push de ; CLEAR ATTRIBUTES ld b,11 ; 11 BYTES inc de ; PT TO FIRST doit2: ld a,(de) ; GET CHAR and 7fh ; CLEAR ATT ld (de),a ; PUT CHAR inc de ; PT TO NEXT djnz doit2 ; COUNT DOWN pop de ; NOW SET ATTRIBUTES OF OLD NAME call initfcb ld c,30 ; SET ATTRIBUTES call bdos call initfcb ; DO THE RENAME ld hl,renfcb ; PT TO NEW NAME ex de,hl call initfcb ; INIT NEW FCB ex de,hl ; HL PTS TO NEW NAME, DE PTS TO OLD NAME call f$rename ; RENAME THE FILE ; RESTORE THE ORIGINAL ATTRIBUTE BITS pop hl ; GET PTR TO OLD NAME ld de,renfcb+1 ; PT TO NEW NAME push hl ; SAVE PTR TO OLD NAME inc hl ; PT TO FN OF OLD NAME ex de,hl ; HL PTS TO NEW NAME, DE PTS TO OLD NAME ld b,11 ; 11 BYTES doit3: ld a,(de) ; GET ATTRIBUTE BIT OF OLD NAME and 80h ; LOOK ONLY AT ATTRIBUTE BIT or (hl) ; MASK IN NEW NAME BYTE ld (hl),a ; STORE IT AWAY inc hl ; PT TO NEXT inc de djnz doit3 ; COUNT DOWN ; SET THE ORIGINAL ATTRIBUTES INTO THE NEW FILE ld de,renfcb ; PT TO FCB call initfcb ld c,30 ; SET ATTRIBUTES call bdos ld hl,(filecnt) ; INCREMENT FILE COUNT inc hl ld (filecnt),hl pop hl ; GET PTR TO DIRECTORY ENTRY ; PT TO NEXT ENTRY rentest: ld de,esize ; PT TO NEXT ENTRY add hl,de pop bc ; GET COUNT dec bc ; COUNT DOWN ld a,b ; CHECK FOR ZERO or c jp nz,renlp ; RETURN TO CALLER ret ; PRINT CHARS PTED TO BY HL FOR B BYTES prnt: ld a,(hl) ; GET CHAR call bout inc hl ; PT TO NEXT djnz prnt ; COUNT DOWN ret ; PRINT COUNT OF NUMBER OF FILES RENAMED prcount: call crlf ; NEW LINE ld hl,(filecnt) ; GET COUNT ld a,l ; CHECK FOR NONE or h jr z,prno call phldc ; PRINT DECIMAL COUNT jr prms prno: call eprint db 'No ',0 prms: ld hl,(filecnt) ; 1 FILE PROTECTED? ld a,h ; HIGH ZERO? or a jr nz,prmult ld a,l ; LOW ONE? cp 1 jr z,prsing prmult: call eprint db ' Files Renamed',0 ret prsing: call eprint db ' File Renamed',0 ret ; Check for ZCPR 3.3, branch to the appropriate parser parsit: call z33chk jp z,z33fname xor a jp zfname ; Print actual COMfile name if we can, ; otherwise print "RENAME" comnam: call getefcb jr z,noefcb ld b,8 comnml: inc hl ld a,(hl) and 7fh cp ' ' call nz,bout djnz comnml ret ; noefcb: call eprint db 'RENAME',0 ret ; AI (allegedly intelligent) routine to check for a string ; containing legal option letters ONLY. optq: ld a,(hl) sub '/' ; Slash is explicit option delim jr nz,noslsh ; If not slash, do char. check ld (hl),a ; If slash, null it out (A = 0) dec hl ld (hl),a ; Null out leading space inc hl ; Adjust pointer to options inc hl ret ; Return with Z flag ; noslsh: ld d,h ; Copy into de ld e,l xor a ; Search for terminating null ld bc,optlen ; Range for search cpir ; Do short search jr z,dooptq ; Found null, proceed ex de,hl ; Otherwise too long for options ret ; Return with NZ ; dooptq: push de dec de bloop: inc de ld a,(de) or a jr z,oqdone ; End of string, return with Z ld b,optlen ld hl,optltr lloop: cp (hl) jr z,bloop inc hl djnz lloop ; If B ticks down, a failure! dec b ; Cheap NZ return ; oqdone: pop hl ret ; optltr: db 'EIS' optlst: ds 0 optlen equ optlst-optltr ; SYSLIB Module Name: SARGV ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 ; public argv ; ARGV is a UNIX-style ARGC/ARGV string parser. It is passed ; a null-terminated string in HL and the address of a token pointer ; table in DE as follows: ; LXI H,STRING ; LXI D,ARGV$TABLE ; MVI A,0 ; do not mark token end ; CALL ARGV ; JNZ TOKEN$OVFL ; indicates more tokens than allowed ; ... ; ARGV$TABLE: ; DB MAX$ENT ; max number of entries permitted ; DS 1 ; number of entries stored by ARGV ; DS 2 ; pointer to token 1 ; DS 2 ; pointer to token 2 ; ... ; DS 2 ; pointer to token MAX$ENT ; Tokens are delimited by spaces and tabs. ; As well as '='. 27 Feb 86 jww ; Completed Joe's mod. by adding "=" to "sksp:" as well as "sknsp:" ; December 19, 1987 - Bruce Morgen ; On input, if A=0, the end of each token is not marked with a null. ; If A<>0, a null is placed after the last byte of each token. ; If all went well, return with A=0 and Zero Flag set. If there ; are possibly more tokens than pointers, return with A=0FFH and NZ. argv: push bc ; Save regs push de push hl ld c,a ; Save mark flag ex de,hl ld b,(hl) ; Get max entry count push hl ; Save address of max entry count inc hl ; Pt to token count inc hl ; Pt to first pointer ; On each loop, DE = address of next char in string and HL = address of ; next pointer buffer; B = number of pointer buffers remaining and C = ; mark flag (0 = no mark) loop: call sksp ; Skip spaces and tabs in string pted to by DE or a ; End of string? jr z,done ld (hl),e ; Store low inc hl ld (hl),d ; Store high inc hl dec b ; Count down jr z,loop2 call sknsp ; Skip until end of token or a ; Done? jr z,done ld a,c ; Get mark flag or a ; 0=no mark jr z,loop1 xor a ; Mark with null ld (de),a ; Store null inc de ; Pt to next char loop1: ld a,b ; Check count or a jr nz,loop ; Continue on loop2: call sknsp ; Skip over token call sksp ; Any tokens left? or a jr z,done ; None if EOL or 0ffh ; Make A = 0FFH to indicate more to come done: pop hl ; Get address of max token count push af ; Save return flags ld a,(hl) ; Get max token count sub b ; Subtract counter inc hl ; Pt to return count ld (hl),a ; Set return count pop af ; Get return flag pop hl ; Restore regs pop de pop bc ret ; Skip over space or tab characters sksp: ld a,(de) ; Get char and 7fh ; Mask inc de ; Pt to next cp ' ' ; Continue if space jr z,sksp cp 9 ; Continue if tab jr z,sksp cp '=' jr z,sksp dec de ; Pt to character ret ; Skip over non-space and non-tab characters ; Added '=' so that A:=B: construct yields two arguments. v1.1 jww sknsp: ld a,(de) ; Get char and 7fh ; Mask ret z ; Done if null cp ' ' ret z ; Done if space cp 9 ret z ; Done if tab cp '=' ret z ; New delimiter inc de ; Pt to next jr sknsp ; end ; End of argv inclusion ; BUFFERS dseg argtbl: max$ent: ds 1 ds 1 ds 2 argum2: ds 2 argum3: ds 2 inspect: ds 1 ; INSPECT FLAG (0=NO, 0FFH=YES) control: ds 1 ; CONTROL FLAG (0=NO, 0FFH=YES) system: ds 1 ; SYSTEM FLAG (80H=NON-SYS, 0C0H=SYS/NON-SYS) eraflag: ds 1 ; UNPROMPTED ERASURE OF EXISTING FILE (0=NO) nextch: ds 2 ; PTR TO NEXT CHAR IN MULTIFILE COMMAND LINE filecnt: ds 2 ; COUNT OF NUMBER OF FILES RENAMED renfcb: ds 40 ; FCB FOR RENAME ofcb: ds 2 ; FCB FOR OLD FILE NAME AND OLD FILE TEMPLATE ntfcb: ds 2 ; FCB FOR NEW FILE TEMPLATE cmdlne: ds 2 ; PTR TO COMMAND LINE BUFFER dirbuf: ds 2 ; PTR TO DIRECTORY BUFFER stack: ds 2 ; OLD STACK PTR end