; ; index words. hl := hl + 2*a (max a =127) ; a,f,h,l indexw: add a ; " " ; index bytes. hl := hl + a ; a,f,h,l indexb: add l mov l,a rnc inr h ret ; ; ----------------------------------------------- ; multi-file access routine ; ; Multi-file access subroutine. Allows processing of multiple files ; (i.e., *.ASM) from disk. Builds the correct name in the FCB each ; time it is called. The command is used in programs to process ; single or multiple files. The FCB is set up with the next name, ; ready to do normal processing (open, read, etc.) when routine is ; called. The initial call (mfirst flag = 0) sets the sub-system up ; from the name in FCB. Carry is set if no more names are found. ; Tbuf is used and dma is set to it. ; a,f,d,e,h,l mfnam: call rsdma; set default dma addr. xra a sta fcbext lda mfirst ora a jnz mfnam1 mvi a,1 sta mfirst; Flag system started lxi h,fcb lxi d,mfbase call move12; save the pattern lda fcb sta mflast; Save disk in current FCB mvi a,srchf jmp mfnam2 ; mfnam1: lxi h,mflast lxi d,fcb call move12; copy last filename mvi a,srchf; reset dos pointers to it call fileop lxi h,mfbase lxi d,fcb call move12; set to the base pattern mvi a,srchn mfnam2: call fileop; search first or search next inr a jz mfnam3; none-found, exit sub-system dcr a; correct for inr above ani 3 add a; *2 add a; *4 add a; *8 add a; *16 words = 32 bytes lxi h,tbuf+1 call indexw; to dir entry found push h; Save name pointer lxi d,mflast+1 mvi b,11 call move; record the found file name pop h lxi d,fcb+1 mvi b,11 call move; revise fcb to the found file xra a sta fcbext; set up for opening sta fcbrno ret mfnam3: sta mfirst; 0. reset flag to re-initialize stc; signal no more files ret ; ; end of multi-file access routine ; --------------------------------------------- ; ; Loads a command line addressed by 'DE' registers (max # characters ; in line in DE^, number of characters in line in DE+1^, line starts ; at DE+2^) into FCBs addressed by HL^ registers. The FCB should be ; at least 33 bytes in length. The command line buffer must have a ; maximum length at least one more than the greatest number of ; characters that will be needed. Regs. preserved cmdln: push psw push b push d push h; init 2 half FCBs at hl^ with nulls mvi m,0; blanks in name/type areas inx h mvi b,11 mvi a,' ' call fill; blank fill mvi b,5 call fillz; zero fill mvi b,11 mvi a,' ' call fill; blank fill mvi b,4 call fillz; zero fill pop h push h xchg; Get start of command line in HL inx h; Address # bytes in command line mov e,m; Load DE pair with # bytes mvi d,0 inx h dad d; Point to byte after last character mvi m,cr; In command line and store delimiter pop h; Restore HL and DE pop d push d push h inx d; Address start of command inx d call drivx; extract any drive info mvi c,8; Transfer first filename to FCB call trans cpi cr jz cmdln3 cpi ' '; If space, then start of 2nd filename jz cmdln1 pop h; Filetype starts after 8th byte push h lxi b,9 dad b mvi c,3; Transfer type of first file call trans cpi cr jz cmdln3 cmdln1: ldax d; Eat multiple spaces between names cpi ' ' jnz cmdln2 inx d jmp cmdln1 cmdln2: pop h; 2nd name starts in 16th byte push h; Point HL to this byte lxi b,16 dad b call drivx; extract any drive info mvi c,8 call trans cpi cr jz cmdln3 pop h; 2nd file type starts in 25th byte push h lxi b,25 dad b mvi c,3 call trans cmdln3: pop h push h inx h; Point to 1st char of 1st name in FCB call scanl; Check for * (ambiguous names) pop h push h lxi b,17; To 1st char of 2nd name in FCB dad b call scanl pop h pop d pop b pop psw ret ; ; transfer up to (c) chars from de^ to hl^. Stop at hl^ a delimiter ; advance hl and de. Scan to hl^ a delimiter, absorb excess chars. ; a,f,c,d,e,h,l trans: ldax d inx d call ucase; upshift for CCPLUS command line cpi cr rz; delimiter cpi '.' rz; delimiter cpi ' ' rz; delimiter dcr c jm trans; field full, scan w/o transfer mov m,a inx h; Transfer to FCB. jmp trans ; ; Extract drive id (if any) from string de^ to fcb hl^. ; advance hl^ past drive specifier. ; a,f,d,e,h,l drivx: inx d; Check 2nd byte of filename. if it.. ldax d; Is a ":", then drive was specified.. dcx d cpi ':' jnz drivxx; Else zero for default drive ldax d; ('INIT' put zero) ani 5fh sui '@'; Calculate drive (A=1, B=2,...) mov m,a; Place it in FCB inx d; Address first byte in command line inx d drivxx: inx h; And name field in FCB ret ; ; scan fcb name hl^, converting * to '?' fields ; a,f,b,h,l scanl: mvi b,8; Size of name field call scanl1; Scan & fill name field mvi b,3; Size of type field scanl1: mov a,m; Scan & fill cpi '*' mvi a,'?'; in case fill here jz fill inx h dcr b jnz scanl1 ret ; ; Clears the FCB hl^ area, except the drive specifier ; a,f,b,h,l initfcb: inx h; advance over drive specifier mvi b,11; Clears the filename/type area mvi a,' ' call fill mvi b,21; zero the rest ; " " ; fill hl^ for b with zero ; a,f,b,h,l fillz: xra a ; " " ; fill hl^ for b with a ; f,b,h,l fill: mov m,a inx h dcr b jnz fill ret ; ; Copies TBUF to CMDBUF, scans CMDBUF counting names ; and putting delimiter (space) after last name ; scan: lxi d,cmdbuf; Save orig TBUF contents in cmdbuf push d lxi h,tbuf mvi b,128 call move pop h push h mov a,m call indexb inx h; Now pointing at space after last char mvi m,' '; Put in the space pop h; Get cmdbuf count again mov b,m inx h; Skip the first space inr b scan1: inx h; On first entry HL points to 1st char dcr b; 1st go-thru B is count to last space jz scan5 mov a,m; Look for the first space cpi ' ' jnz scan1 scan2: inx h; Eat extra spaces dcr b jz scan5 mov a,m cpi ' ' jz scan2 shld bgnms; Save start of names in cmdbuf inr b dcx h scan3: inx h dcr b jz scan5 mov a,m cpi ' ' jnz scan3 lda namect; Counts names inr a sta namect; and repeat test, next line scan4: mov a,m cpi ' ' jnz scan3 inx h; Eat spaces dcr b jnz scan4 scan5: lda namect; Were there any names? ora a rnz; Yes pop h; Remove calls from stack pop h jmp opterr; Bail out to avoid BDOS error ; ; ; ------------------------------------------------------------------- ; ; Show the file name as stored in the FCB but in CP/M format ; showfil: mvi a,1; Show on local CRT only sta remoff call ilprt db 'File name: ',0 lxi h,fcb+1 xra a sta ftycnt mvi c,11 ; " " prnam: call ftytst inx h dcr c jnz prnam ret ; ftytst: lda ftycnt inr a sta ftycnt cpi 9; Are we at the file type? jz spctst; Go if so ; " " endspt: mov a,m cpi ' '; Test for space cnz ctype; Type if not ret ; spctst: mov a,m cpi ' '; Test for space in 1st file type byte rz; Do not output period if space mvi a,'.' call ctype jmp endspt; Output 1st file type byte ; ; --------------------------------------------------