IMD 1.16: 26/05/2007 17:32:39 SD116 MAP104 EDFILE COMV MAP104 ASM MAP104 ASMMLOAD COM NULU COMx!"#$%&'()*+,-./SD116 INFo0123456789:;<=SD116A ASM>?@ABCDEFGHIJKLMSD116A ASMNOPQRSTUVWXYZ[\]SD116A ASM^_`abcdefghijklmSD116A ASMnopqrstuvwxyz{|}SD116A ASM~SD116A ASM2SD116A COM%SD116A HISVSDREM116ASM SWEEP COM\- 0061 Vers: 01-10-84; by: J.C.Kaltwasser & M.J.Mosko, K3RL $=  **͂+}2'++*'&0+!'ͥ(}2'*'&!)*/!*!ͪ*͢*!'!)*"'*'!Z!b(!Z!!*!\8+!)*ʇ!Z*!*!ͪ*͢*!\+!\!!"'*'*"'*'!)*ʶ!"'!*'*! ͘(!i͇+*'!}2'"'2'*"'͹ !\"'*'! (!C)**'! (!O)*ͤ)*'! (!M)*ͤ)=!"'!!͟!\ͺ+|ʅ! ͪ*!*!ͪ*M! ͪ*!"'Ý*'&*ʖ_Ý!}2'!?ͪ**'&|*'&!E*!}2'*'&!g)!x)!}2'*'&*'&***u(}2'!!*'&!E)**'&!)*ͯ)9 !}2'*'&!Q)**'&!)*ͯ)b*'&!H)*t*'&!M)*ʆ*'&!B)*ʛ!"'*'&!Z)*ʷ*'!:*"'*'&!-)**'!)*'!:*"'*'!:*"'*'&!R)* !*"'*'&!A)*b!*"'*'*':*!E**')"'|b!*':**'!E*"'*'&!O)*~!*"'*'&!S)**'&!C)*ͯ)ʠ]*'&! )**'&!+)*ͯ)*'&!=)*ͯ)!'(*'V)!"'*'*'*=͓ !\@+͢*!*͓ ͓ !*͓ !*!͢ !*!͢ !1*͓ !E*!͢ !\*!͢ !s*͓ !*!͢ !*!͢ !*͓ !*!͢ !*!͢ !*͓ ! *͓ ͓ !- *͓ !B *!͢ !Z *!͢ !q *͓ ! *!͢ ! *!͢ ! *͓ ! *͓ ! *͓ ͓ ! *͓ !͢ !!*͓ !͢ !7!*͓ !͢ !i!*͓ !͢ !!*͓ !͢ !!*͓ !͢ !!*͓ !͢ !"*͓ !͢ !U"*͓ !͢ !f"*͓ !͢ !"*͓ ! ͢ !"*͓ ! ͢ !"*͓ ! ͢ !+#*͓ !͢ !G#*͓ !͢ !o#*͓ !͢ !#*͓ !͢ !#*͓ !͢ !#*͓ !͢ !$*͓ ͓ !>$*!'!!*!'+!͢ !V$*͓ !͢ !$*͓ !͢ !$*͓ !$*͓ !͢ !#%*͓ !͢ !f%*͓ !͢ !%*͓ !͢ !%*͓ ͓ !͢ !%*͓ !͢ ! &*͓ !>&*͓ !&*!'!!*!'+!}2(*(&!)ʇ ͓ !(D)!!! ͪ*! ͪ*!9)ʵ ! ͪ*͇*!}2(*(&!Y!(2) !Y*(&(*!(D)!&*! }2'*'&|6 *'&}2'*'&}2'!>*'&!g)}2'K !}2'!}2'!>}2'*"'!}2'!}2'*'&*'&**| *}2(͟*(&! )*(&*ͤ)ʨ *(&"(!*()* !!!&*!\+| ! ͪ*!&*!ͪ*M! !è !*()*M !!!&*!\ͺ+|> ! ͪ*!&*!ͪ*M! !è *X&*()*| !',)!)s !}2'*"'è *W&*()*ʨ !')!)ʢ !}2'*"'*'&|0 *(&! )*(&*ͤ)ʬ *(&"(*U&*()*d *'&|T *'&!)# *'&!:*}2'!')!'ͺ)!}2'Q *'!)Q !6}2'!M}2'!')!'ͺ)!}2'a !')!}2'é *V&*()*y é !*()*ʩ !}2'*'&!)*ʩ !}2'!')- *(&}2(!)- *(&u(ͪ*!i*'!i*'(!*'&)ͤ)*(&*'&)ͯ)**'&*'&!i*'($=*(&! )*(&*ͤ)*(&" (*U&* ()*ʺ *'&!>)ʐ *'&!:*}2'!')!'ͺ)÷ *'!)ʷ !5}2'!M}2'!')!'ͺ) *V&* ()* ͍ !* ()* !}2' !* ()* !)}2(=!}2(*(&$!i*'*(&**'&*'&*(&3͍*'&! *'&)**n *'"5(*'&!S)*}!(!!*!}20(2'21(2(2'2'!}2(!!!&*!(+!(!(!(!!*!(!".(!(!(!)*(͟!!!?ͪ**5("'!)}2'!}22(*2(&!)X!'*2(&!*!2(D)*.(!(!!(!((s*.((!\)*ʦ*(&!))}2(!.(%)X*.((!;)**1(&!))}21(!.(%)! *X*1(&| !'!'D)*.((u(*!.(%)! *X*.((!,)*-!.(%)!}2(X*(&|S!'!'D)!.(%)(*p!.(%)(u(}2 (* (&!A)* (&!F)ͯ)* (&!0)* (&!9)ͯ)ͤ)ʷ!ͪ*!}20(sP* (&!AV)* (&!F2)ͤ)* (&!A:*! }2 (* (&!0:*}2 (!'*'&!'*'&(*(&* (&x)**(&!)*I!'D)!}2(!}2(*'&!)p!ͪ*!}20(sX*0(&|r!"7("9(}2'23(*'&*'&}22(*'&!C(ʹ!}2'!Uͭ|?!)}2'!}24(*4(&*'&2)?!'*4(&(!aV)!'*4(&(!z2)ͤ)7!'*4(&!'*4(&(!ͤ)*!4(D)!}2'!Zͭ|Y!}2'!Oͭ||͓ !&*!:*"7(!Mͭ|ʙ͓ !'*}2'!Aͭ|ʹ*'!"'*!\ͺ+*3(&*'&)!'*3(&(*2(&N)*ͤ)!3(D)!}23(*3(&*'&)*y!Oͭ*7(*9((ͤ)2!}23(!9(%)y*2(&*'&V)^*2(&*'&:*!}2'g*2(&}2'!}2'!)}2'!2(D)*2(&!V)!Bͭ|ʣ!'ͺ)é!'%)*'*'*!}22(!\ͺ+|*5("'!!!(!*!4'*!ͪ*!}2'*|2*2(&}2'*}23(!!!@'*!}2'ù**A*}2;(*;(&!i!9((*'&ͤ)}2<(*'&|ʤ*<(&!aV)*<(&!z2)ͤ)ʤ*<(&!ͤ)͇**<(&͇**'&!)*!͇*!}2=(*=(&*'&2) !'*=(&(!9()*!)͇*!=(D)!͇**'&|*!'D)!}2'Ì*'&!6)^*'&!}2'!'D)!'%)!}2'Ì*'!)ʌ!}2'!>}2'!'D)!'%)!}2'*'&!M)ʺ*'&!}2'!'D)!'%)*'!)!}2'!>}2'!'D)!'%)!9!9(u(*!9(!A)!9(!0:*͇*!9(!7:*͇**'&!:*!)*'&!>:*!:">(!>(K)^͓ !O'*!Z*!V'**'! !a'**'Ϳ!d'*!h'*!*!p'**'Ϳ!s'*͓ !v'*!}2@(*@(&!)*@(&*'!ͤ)3! ͪ*!@(D)!'*!}2@(*@(&!)A*@(&*'!ͤ)!g)ͼ!@(D)͓ !'*!}2@(*@(&!)p!'*!@(D)!'**'!x)*'"'!}2@(*@(&!)V͓ *'*@(&"C(*C(d!'*!}2A(*A(&!)!i*@(&*A(&(3! ͪ*!A(D)!'*!}2A(*A(&!)=!i*@(&*A(&($!A(D)!<ͪ**@(&!}2@(Ñ͓ ''!9!9(!ͤ)*!9(!)Y!9(ͪ*`!.ͪ*͇*!9*"'!}2E(*E(&!2)*'!g)}2G(*'!E*"'*G(&! )*G(&!0}2F(*G(&!7}2F(!*E(&*F(&*!E()!!!*!*! ͪ*͇*!9*"'!}2I(*I(&!2)*'!(ͤ)s*'! g)}2H(*'! E*"'!!I()*H(&!0**I(&!2)ʗ!!I()!0*!!!*!9*ʸ!*!͇*!}2J(*J(&!(/*J(&!:*}2J(!9**J(&)!ͤ)!0}2K(*K(&!9)$*K(&!}2K(*K(&ͪ*͇*!9(!)!ͤ)!0}2L(*L(&!9)p*L(&!}2L(*L(&ͪ*!9(!ͤ)!0}2L(*L(&!9)ʯ*L(&!}2L(*L(&ͪ*͇*!9(!ͤ)!0}2M(*M(&!9)*M(&!}2M(*M(&ͪ*͇*!P(!!*!P(+!P(!(}2O(!P(!͂(!P(*O(&!(!H)*a!O()!}2V(h! }2V(!"X(!"Z(*O(&!}2N(*N(&!V)!P(*N(&(}2W(!0"\(*W(&!9)ʿ!7"\(*X(*Z(*W(&*\(:*x)"X(*Z(*V(&x)"Z(!N()*X(!}2^(*^(&!@!(2)/!@*^(&(*!^(D)*E&!)g!9**E&*!9**E&*Û!9**E&!ͤ)*!9**E&!ͤ)*͇*!}2_(*_(&!P!(2)!P*_(&(*!_(D)!}2`(*`(&!K!(2)!K*`(&(*!`(D)!F!(!)*X!}2a(*a(&!O)N! *!a(D)! *Ñ!}2a(*a(&!F!(2)ʑ!F*a(&(*!a(D)No File Specified. Not Found.Bad Record.RECORD = ADDRESS = OFFSET = HelpRead/Edit File Utility Functions:A - Address to dump B - Dump at beginning C - Continue SearchE - Enter Edit Mode H - This help list M - Expanded Help listO - Set address offsetQ - Quit this program R - Read & dump recordS - Search for string Z - Dump at end of fileCR - (+/=) - Adv record(-/_) - Decr record Edit Mode Functions:^E - Toggle data fields^W - Write buffer out ^X - Abort Edit Mode ^J - Cursor Down ^K - Cursor Up ^H - Cursor Left ^L - Cursor Right Expanded HelpRead/Edit File Utility Functions:A - Enter relative address to dumpB - Set record to beginning of file and dump dataC - Continue search. Restarts search on last entered search string.E - Enter Edit mode on current recordH - Brief description of the functionsM - This help descriptionO - Enter offset address relative to start of file (.COM = 100h)Q - Quit programR - Enter record number to dumpS - Search for hex or ASCII string in file (starts at current record)'\' = ASCII string delimiters (ex: \Test\)',' = hex and/or ASCII delimiters (ex: 41,\Test\,4A';' = select search optionsA - Start search from beginning of fileB - Search BackwardsM - Search on certain bits set; use mask xxO - Stop on xx occurrence of stringU - Translate lower case characters to upper caseZ - Search recognition on least significant 7 bits onlyHit for more -Z - Set record to end of file and dump dataCR - carriage return (or +/= key) - advances record and dumps the data-/_ key - decrements record and dumps the dataEdit mode: ('^' refers to the Control key)^[ - (ESC) Accept next char into edit field even if a control char^E - Toggle between ASCII and hex data fields^W - Flush record to disk^X - Abort edit mode without updating record^J - Cursor down ^K - Cursor up ^H - Cursor left ^L - Cursor right Input integers are decimal. Use 'h' suffix for hexadecimal entries.Hit to continue -Edit RecordWriting Buffer ** WRITE ERROR **EDIT ABORTED** READ ERROR **?Search String = Stop on string occurrence = Enter string search mask = Not Found.SEARCH ABORTEDFile: Record: (H) LOF: (H) -- ---------------- - >xs(~# f(}a{ o~aڔ({Ҕ( w#Ä(~#Ü(!^#6~( (#÷(}|#~ (((6#÷(i`^#Vr+s|r)!„*+Ä*ngr)!ڄ*+Ä*r)!ڄ*+Ä*(+|4ng*r)!+,)-|^#Vr+s|*r)!+E*|z{.zW{_-ʠ)җ)} DMoxGyOÁ)|}o|g}o|gK)#|5ng),|}o|gzʄ*|g}o)zʄ*}o|g)͑*#||!„*#Ä*~#fo}}|r)!ʄ*+Ä*}o|g"*."*{_zW**-"*ʄ*>)D**OxG|* ?T*} =Š*}/o|/g!+ñ*ÿ*o&ÿ*͙*!**͙*K* !+*ñ*͙*͙* ͙*_+͙*  ʴ*>ô*  ͙*͙*ñ*͙*ñ*͙*ñ*ñ*͙*ñ*͙*ñ*͙*ñ*͙*ñ*͙*ñ*ñ*͙*͙*ñ* ñ*͙* ͙*!ñ*͙*"ñ*͙*#͙*$͙*%͙*(ñ*xs(~# f(}a{ o~aڔ({Ҕ( w#Ä(~#Ü(!^#6~( (#÷(}|#~ (((6#÷(i`^#Vr+s|r)!„*+Ä*n; MAP.ASM ; version 1.04 ; ; 04/06/85 ; v1.03 had a bug in it. When someone tried to MAP a specific ; drive, the program would report drive A: instead of the selected ; drive. MAP command syntax now makes a little more sense. ; ; 04/02/85 ; Another major change. This version will now let the user select ; which drive to map. In addition, the descriptive mode routines ; are now conditional (see EQUate DESCRIP), this is for sysops who ; don't want to use extra disk space to handle section ; descriptions. In the library, I've changed README.TXT to ; MAPxxx.MOD. ; ; 03/01/85 ; This sucker's getting pretty slick. I've added a routine to ; print a description of the section along with its name ; (description is inside -*.* file, see README.TXT in MAP102.LBR ; for more information). I've also added an abort and XOFF ; handling routine, in the process switching over to all BDOS ; direct console I/O. ; ; * * * ; ; This program was designed for RCP/M systems that, for one reason ; or another, cannot use SECTION (i.e. a system whose download ; areas change daily). It goes through the directory of each ; online user area and drive looking for catalog label files ; (-*.*). Upon finding such a file it displays bytes 2-8 of the ; filename and the drive/user area where the file is located. For ; example, a file in A6: called -UTILITY.05A would be displayed as ; "A6: = UTILITY". Of course, this means that filename bytes 2-8 ; have to be somehow descriptive of that particular section. ; ; If you have any bug reports/fixes, please contact me either by ; calling B-RCP/M (214) 840-9552 and leaving a message via the ; CP/M NOTE command or write to: ; ; Bob Horn ; c/o Horn Engineering Associates ; 1714 Patricia Lane ; Garland, Texas 75042 ; ; PS: The RCP/M hours are pretty sporadic, but if you call about ; 7PM central time or early morning (midnight to 8AM) you ; stand a pretty good chance of getting online. Note that at ; some hours an aux. 5" based system is up with just a ; bulletin board online ; TRUE EQU 0FFH FALSE EQU NOT TRUE ; ; CP/M Equates ; BOOT EQU 0 ;org zero CP/M BDOS EQU BOOT+5 ;bdos entry DEFDMA EQU 80H ;normal default DMA address TPA EQU BOOT+100H ;ORG address DFCB EQU 5CH ;CP/M default FCB CONIN EQU 1 ;BDOS console input function CONOUT EQU 2 ;console output function DIRCON EQU 6 ;direct console I/O PBUF EQU 9 ;print buffer function RDCON EQU 10 ;read console buffer function CONSTAT EQU 11 ;console status function SELDISK EQU 14 ;select default disk function OPENF EQU 15 ;open file function CLOSEF EQU 16 ;close file function SRCHF EQU 17 ;search for first dir file function SRCHN EQU 18 ;search for next file function DELF EQU 19 ;delete file function READF EQU 20 ;read file function WRITEF EQU 21 ;write file function MAKEF EQU 22 ;make file function GETDISK EQU 25 ;get default disk function SETDMA EQU 26 ;set DMA address function SETATTR EQU 30 ;set file attributes USRSTAT EQU 32 ;get/set user number ACHAR EQU 'C'-'@' ;characters for abort and pause, XOFF EQU 'S'-'@' ;respectively. MUST be ctrl chars. ; ; Misc Equates ; BELL EQU 07H ;bell character BS EQU 08H ;backspace character LF EQU 0AH ;line feed CR EQU 0DH ;carriage return BLANK EQU 20H ;space character ; ; Program Equates ; VERS EQU 1 ;version REV EQU 04 ;revision # MONTH EQU 04 ;date of last revision DAY EQU 06 YEAR EQU 85 ; ; If you make any changes, please change the above accordingly ; ; FENCE EQU '|' ;separator between section names NUMCOL EQU 2 ;# of sections to be displayed on ;each line, 4 for 80 column display ; DESCRIP EQU TRUE ;true, produce description code ZCPR EQU TRUE ;true if using ZCPR for MXDRV/USR ; ;if false, see IF NOT ZCPR area below IF ZCPR MXDRV EQU 3DH ;set to location of ZCPR MAXDRV MXUSR EQU 3FH ; " MAXUSER ENDIF ; ORG TPA ;program runs here ; ; Main program ; START: JMP START1 ;jump over fixed data ; IF NOT ZCPR MXDRV: DB 1 ;max drive to search (A:=0, B:=1, etc.) MXUSR: DB 8 ;max user to search +1 ENDIF ; DIRFNAME: DB '-??????????' ;wild card directory name START1: LXI H,0 ;find CP/M stack pointer DAD SP SHLD OLDSP ;save old stack pointer LXI SP,STACK ;set up our local stack ; LDA DFCB+1 ;get first character of command line CPI '?' ;request for help? JZ HELP ;then help 'im ; IF DESCRIP CPI 'D' ;? if descriptive mode JNZ START2 ;it's not, go ahead MVI A,0FFH ;it is, set the flag STA DESFLG ENDIF ;descrip ; START2: LXI H,SIGNON ;point to signon message CALL IPBUF ;and show it ; ; Get the default drive & user, save them, and log onto A0: ; MVI C,GETDISK ;get the default drive CALL BDOS STA DEFDRV ;save it ; MVI C,USRSTAT ;get the default user MVI E,0FFH CALL BDOS STA DEFUSR ;save it ; MVI E,0 ;set default to A: MVI C,SELDISK ; CALL BDOS ; MVI E,0 ;user 0 MVI C,USRSTAT CALL BDOS ; LDA DFCB ;see if specific drive ORA A ;set flags CNZ SPCDRV ;one specific drive, set it ; ; Here we set up the DMA and initialize some values ; LXI D,DEFDMA ;set the CP/M DMA address MVI C,SETDMA CALL BDOS ; ; Now start the directory search. ; LFORFL: CALL ZFCB ;zero the FCB LXI B,11 ;11 char in file name LXI H,DIRFNAME ;the wild card file name LXI D,FCB+1 ;point to FCB file name space CALL MOVE ;move the file name in ; LXI D,FCB ;find first match MVI C,SRCHF CALL BDOS INR A ;returns 0ffh if not found JZ MORETGO ;None there DCR A ;set A back to normal LXI H,DEFDMA ;point to DMA buffer CALL FINDFN ;find the file name in the DMA space ; IF DESCRIP LDA DESFLG ;see if descriptive mode ORA A ;set flags JNZ DESCAL ;call descriptive routine if so ENDIF ;descrip ; CALL PRINTFN ;Print the filename with pertinent data ; MORETGO: LDA CURUSR ;get the current user MOV B,A LDA MXUSR ;and the max user INR B ;bump the current user CMP B ;same as (MXUSR)? JZ NDRIVE ;if so, go to the next drive MOV A,B ;and if not, store new current user STA CURUSR MVI C,USRSTAT ;and move up one MOV E,B CALL BDOS JMP LFORFL ;look for another file ; NDRIVE: LDA DFCB ;see if specific drive ORA A ;set flags JNZ EXIT ;yeah, quit now ; LDA CURDRV ;get current drive MOV B,A LDA MXDRV ;get max drive CMP B ;same? JZ EXIT ;if so, we're done MOV A,B ;if not, get CURDRV back in A INR A ;...bump current drive counter STA CURDRV ;...save it MOV E,A ;...and log onto the next drive MVI C,SELDISK CALL BDOS XRA A ;zero user area count STA CURUSR MOV E,A ;...and log onto user 0 MVI C,USRSTAT CALL BDOS CALL CRLF ;new line LDA CURCOL ;get current column count ORA A ;set flags JZ LFORFL ;it's been reset by ZCOL already ;so look for next file XRA A ;else reset STA CURCOL CALL CRLF ;new line JMP LFORFL ;look for file ; IF DESCRIP DESCAL: CALL DESFN ;call the descriptive filename routine JMP MORETGO ;and go back ENDIF ;descrip ; EXIT: LXI H,QMSG ;tell how to get help CALL IPBUF ; EXIT1: LDA DEFUSR ;get default user area back MOV E,A MVI C,USRSTAT CALL BDOS ;set it ; LDA DEFDRV ;get default drive back MOV E,A MVI C,SELDISK CALL BDOS ;set it ; CALL CRLF ; LHLD OLDSP ;recover CP/M SP SPHL ;set it RET ;and exit quietly to CP/M ; ABORT: MVI C,PBUF ;print abort message LXI D,AMSG CALL BDOS JMP EXIT1 ; ;************************ ;*** CONSOLE MESSAGES *** ;************************ ; SIGNON: DB CR,LF,'MAP v',VERS+'0','.',(REV/10)+'0',(REV MOD 10)+'0',', ' ; DB (MONTH/10)+'0',(MONTH MOD 10)+'0','-' ; DB (DAY/10)+'0',(DAY MOD 10)+'0','-' ; DB '19',(YEAR/10)+'0',(YEAR MOD 10)+'0' ; DB CR,LF,'from Horn Engineering Associates',CR,LF,LF DB cr,lf,'Ctrl-',ACHAR+'@' DB ' to abort, Ctrl-',XOFF+'@'  DB ' to pause...',CR,LF,LF,'$' ; AMSG: DB CR,LF,LF,'++ Aborted ++',CR,LF,LF,'$' ; SAMSG: DB 'Illegal drive...',CR,LF,'$' ; DRMSG: DB 'MAP of drive $' ; QMSG: DB CR,LF,LF,'Type ''MAP ?'' for assistance with using this' DB ' program.',CR,LF,'$' ; IF DESCRIP ; NULMSG: DB 29,'Description not available...$' ; ^ ^ ; # of bytes in message MUST END WITH $ ; ENDIF ; ;************************************** ;*** THE PRIVATE FILE CONTROL BLOCK *** ;************************************** ; FCB: FCB$DISK: DB 0 ;preset default drive FCB$NAME: DB '-???????' ;preset default file name FCB$TYP DB '???' ;file type FCB$EXTENT: DB 0 ;preset extent FCB$RESV: DB 0,0 ;reserved by CP/M FCB$RECUSED: DB 0 ;records used FCB$ABUSED: DB 0,0,0,0,0,0,0,0 ;assigned blocks DB 0,0,0,0,0,0,0,0 FCB$SEQREC: DB 0 ;sequential record number FCB$RANREC: DW 0 ;random record number FCB$RANRECO: DB 0 ;record overflow ; ;******************* ;*** SUBROUTINES *** ;******************* ; ; PRINTFN - Presents all pertinent section data ; PRINTFN: INX H ;Point past "-" INX H PUSH H ;save it for later ; ; Ok, now, where is the section? ; LDA CURDRV ;get current drive ; ADI 'A' ;make drive ASCII CALL PCHAR ;print it LDA CURUSR ;get current user CALL PASC ;make # ASCII ; MVI A,' ' CALL PCHAR MVI A,'=' CALL PCHAR MVI A,' ' CALL PCHAR ;print " = " ; ; Now, print the section name ; POP H MVI C,10 ; was 7 but we want ALL CALL PSTRING ; ; Check the column counter and act accordingly. Don't want a messy ; screen ; LDA CURCOL ;get the current column CPI NUMCOL-1 ;printed all on this line yet? JZ ZCOL ;yep, zero counter INR A ;nope, bump counter STA CURCOL ;and save it ; MVI A,' ' ;print " | " between section names CALL PCHAR MVI A,FENCE CALL PCHAR MVI A,' ' CALL PCHAR RET ;back we go ; ZCOL: XRA A ;zero A STA CURCOL ;store it as the current column CALL CRLF ;end of line RET ; IF DESCRIP ; ; DESFN - Print filename and description ; DESFN: INX H ;Point past "-" INX H PUSH H ;save it for later ; ; Ok, now, where is the section? ; LDA CURDRV ;get current drive ; ADI 'A' ;make drive ASCII CALL PCHAR ;print it LDA CURUSR ;get current user CALL PASC ;make # ASCII ; MVI A,' ' CALL PCHAR MVI A,'=' CALL PCHAR MVI A,' ' CALL PCHAR ;print " = " ; ; Now, print the section name ; POP H PUSH H MVI C,10 ; was 7, but we want ALL CALL PSTRING MVI A,' ' ;make sure at least 2 spaces between CALL PCHAR ;filename and description MVI A,' ' CALL PCHAR ; ; Now we're ready to move the filename into the FCB, open it, ; and read the description (if any). ; CALL ZFCB ;first clean things up POP H ;recover filename DCX H ;get the "-" back LXI B,11 ;# of characters to move LXI D,FCB+1 ;where to move them CALL MOVE ;do it ; ; Now open the file and read 1 record ; MVI C,OPENF ;BDOS open file LXI D,FCB CALL BDOS ;  MVI C,READF ;BDOS read sequential LXI D,FCB CALL BDOS ORA A ;set flags CNZ NULFLE ;must be empty file ; ; Close the file (even though we don't really have to) ; MVI C,CLOSEF ;BDOS close file LXI D,FCB CALL BDOS ; ; Now display information ; LXI H,DEFDMA CALL IPBUF ; CALL CRLF ;new line ; RET ;go home ; NULFLE: LDA NULMSG ;get # of bytes in message MOV C,A ;put it in BC MOV B,0 LXI H,NULMSG+1 ;point to message LXI D,DEFDMA ;put it in the DMA CALL MOVE ;move it RET ;go home to Kansas ; ENDIF ;descrip ; ; ZFCB - Zero the 36 bytes in the designated FCB ; ZFCB: MVI C,36 LXI H,FCB ;point to FCB ZLOOP: MVI M,0 ;enter a zero INX H ;bump pointer DCR C ;bump down counter JNZ ZLOOP ;loop for more RET ; ; FINDFN - Locates directory file name in DMA after directory ; search. Returns pointer in HL. Entry with directory code in A. ; FINDFN: ADD A ;*2 ADD A ;*4 ADD A ;*8 ADD A ;*16 ADD A ;*32 MOV E,A ;offset to DE MVI D,0 DAD D ;add to HL RET ; ; MOVE - Moves the number of characters in BC from (HL) to (DE) ; MOVE: MOV A,M ;get char from (HL) STAX D ;put in (DE) INX H INX D DCX B MOV A,C ;get LS count byte ORA B ;both B & C zero? JNZ MOVE ;loop til done RET ; ; PSTRING - Prints string pointed to by HL. ; Number of characters to print in C ; PSTRING: PUSH H ;save string pointer PUSH B ;save count MOV A,M ;get a character CALL PCHAR ;print it POP B ;restore count POP H ;restore pointer INX H ;bump it DCR C ;done? JNZ PSTRING ;if not RET ; ; IPBUF - Same is BDOS PBUF, 'cept it checks for abort character ; and expects the print string to be pointed to by HL ; IPBUF: PUSH H ;save string pointer MOV A,M ;get a character CPI '$' ;is that all? JZ PDONE ;if so, quit CALL PCHAR ;if not, print a character POP H ;else restore counter INX H ;bump up JMP IPBUF ;go again PDONE: POP H ;save stack RET ; ; ; CRLF - Puts a CR and LF out to console ; CRLF: MVI A,CR CALL PCHAR MVI A,LF CALL PCHAR RET ; ; PCHAR - Prints the character in A ; PCHAR: PUSH PSW ; CALL GETCON ;see if a key pressed CPI ACHAR ;if so, was it an abort request? JZ ABORT ;then abort CPI XOFF ;XOFF? CZ PAUSE ;then pause until key pressed ; POP PSW MOV E,A MVI C,DIRCON CALL BDOS RET ; ; PASC - Unpacks two ascii decimal digits from value in A ; displays them on the console with no leading 0's. ; PASC: MVI C,0 ;initialize quotient PASC1: SUI 10 ;repeatedly subtract 10 JC PASC2 ;if underflow INR C ;else increment the quotient JMP PASC1 ;and subtract again ; PASC2: ADI 10 ;Correct the underflow PUSH PSW ;save the remainder MOV A,C ;get the quotient ORA A ;set flags JZ ONENUM ;only one number to display ADI 030H ;adjust to ascii CALL PCHAR ;print it POP PSW ;get remainder ADI 030H ;make ascii CALL PCHAR ;print it ; MVI A,':' ;print a ":" after the drive/user CALL PCHAR ;  RET ; ONENUM: POP PSW ;get the # ADI 030H ;make ASCII CALL PCHAR ;print it MVI A,':' ;and a colon CALL PCHAR MVI A,' ' ;and a space to make up for the leading CALL PCHAR ;0 ; RET ;go home ; GETCON: MVI C,DIRCON ;BDOS direct console I/O MVI E,0FFH ;for input CALL BDOS ;do it RET ; PAUSE: PUSH PSW ;save EVERYTHING PUSH B PUSH D PUSH H ; PLOOP: MVI C,DIRCON ;direct console I/O MVI E,0FFH ;input CALL BDOS ORA A JZ PLOOP ;wait until key pressed ; POP H ;get everything back POP D POP B POP PSW ; RET ; ; SPCDRV - if a specific drive chosen for map, this routine checks ; MXDRV to see if possible, and if so sets up that drive ; as default. ; SPCDRV: LDA MXDRV ;get max drive MOV B,A ;move to B LDA DFCB ;get drive chosen DCR A ;bump down INR B ;and fix B for compare CMP B ;compare the two JNC SPCABT ;not ok, exit MOV E,A MVI C,SELDISK ;select disk CALL BDOS ;do it ; LXI H,DRMSG ;Say MAP of drive x: CALL IPBUF  LDA DFCB ;Get MAP drive back DCR A ;bump down STA CURDRV ;store it for display ADI 'A' ;Make ASCII CALL PCHAR ;print it MVI A,':' ;...and a colon CALL PCHAR ; CALL CRLF CALL CRLF ; RET ; SPCABT: LXI H,SAMSG ;print "drive out of range" CALL IPBUF JMP EXIT ;and exit to CP/M. ; HELP: LXI H,HMSG ;print help message CALL IPBUF JMP EXIT1 ;and exit to CP/M ; HMSG: DB CR,LF,LF DB 'Examples of use:',CR,LF,LF DB ' MAP presents a map of all drives/' DB 'user-areas,' DB CR,LF,' no descriptions.' IF DESCRIP DB CR,LF,LF DB ' MAP D presents a map of all drives/' DB 'user-areas,' DB CR,LF,' with descriptions.' ENDIF DB CR,LF,LF DB ' MAP B: presents a map of drive B:,' DB CR,LF,' no descriptions.' IF DESCRIP DB CR,LF,LF DB ' MAP B:D presents a map of drive B:,' DB CR,LF,' with descriptions.' ENDIF DB CR,LF,'$' ; ; ;************************ ;*** UNITIALIZED AREA *** ;************************ ; DEFUSR: DB 0 ;storage for default user area DEFDRV: DB 0 ;default drive CURUSR: DB 0 ;current user area CURDRV: DB 0 ;current drive ; CURCOL: DB 0 ;current column ; IF DESCRIP DESFLG: DB 0 ;marks descriptive mode ENDIF ;descrip ; OLDSP: DW 0 DS 64 ;our private stack area STACK: EQU $ ; END  COM!9" 1I ͇MLOAD ver. 2.4 Copyright (C) 1983, 1984, 1985 by NightOwl Software, Inc. ͏ s͋zdͿͽ : ! * !  &<* !~#ʏG<6#" *}O| G6# x¿* +Fʏ#~ FUi~#Ui" ))))_* \ =A: i: i<2 –#![  < ,K6L#" x–2 ] 7ͽ <!e~ ½6H#6E#6X`^ ! ~4! ~d* 1:˜2 W _° g o: ̖ +: : " *  " :9 * " *   w# ØG! ~wx1N1N: R_!~! 4\ͽ 2 <4!͖ * * !:9ͽ \ͽ ѷ£*  " v+" * * " ͽ \ !  <~ !<ͽ ͽ <* * {OzGxr\!ͽ ͽ * #" yրOxGz͇Loaded * ͇ bytes (͇H)͇ to file %: ʚ͇ Over a * ͇ byte binary file͇ Start address: * ͇H Ending address: * ͇H Bias: * ͇H ͇Saved image size: * )͇ bytes (͇H, - ͇ records) * }G|͇ ++ Warning: program origin NOT at 100H ++ \ͽ <(͍~#%ʜ/Í:\©͋ <@/:[} o&>:/!]>./Í~ #/#  |{0/> /> /|}'Ɛ'@'_ͽ ~#=#~ FUX0:fAG?͇ Command line syntax error Ï͉ Ambiguous file name: % not allowed.͉ File % not found.͉ Disk full.͉ Directory full.͉ Premature end-of-file in %͉ Checksum error in %͉ Can't close %͉ Memory full while loading %͉ Format error in file %͉ Writing %, nothing loaded͉ MLOAD syntax: MLOAD [=] [,...] [] (brackets denote optional items) is the optional output filename are input file(s) is a hex load offset within the output file may be an optional non-HEX file to be patched by subsequently named HEX files (specifying The filetype enables this function). Note that ZCPR2-style drive/user notation may be used in all file specifications (e.g., "B3:MYFILE.COM, "A14:MDM7.HEX"). ͍v>2 " " * }o|g"   !]<: ! } w#͋ 2  % x _ } 6# 6 # 6# ͨ # ͨ #( :~U AC @#~#:+xG~0G#~:K #{ ~.#yu  k { ͨ #*ʗ ?‹ U  { à >? ™ ͨ #à ~/., :=ȷ/  " 2 = go : *  y "    go\ ] y!"#$a{ e!z #v i HEX ͽ ͽ I I UTFIL> is the optional output filename are input file(s) is a hex load offset within the output file may be an optional non-HEX file to be patched by subsequently named HEX files (specifying The filetype enables this fF NULU 1.5 (11/01/85) Copyright (C) 1984, 1985 by Martin Murray!:7O<`Ͱ4 âPPF >2>G3:8=0ډm͔Ï!"1!9"1!9"*e&###:fO *<"8*hDM) "<22m332r2(3 ͔"8=}0 -͔m͔">_Tm͔*"!"ͯ+ -O)(lm<  WORK-LBR.$$$ NCF NOF LBR )ibrary lL membersNULU/s oryDiskUnDfile erroreleteress RETURN CRCreadunwritten datalRe runchKBrief entriesAbandonConsole put to be ing enameRWildcard specsqueezeFilesweep Extract drive/user to: ...ReplacedirectAddtoggleClose themodeGetHelpListOpen aPrintStrsearch/AddDrive/User changeViewopenExit inputoutputREADYNextPreviousCloseFindLog newMass operationsOpen newPrintTagUntagViewrExit command modeHelp! FJKMNSUVdktdisk fullcan't make filemedia changeddisk i/odisk r/ofile r/obad drivepassword existsambiguityfile table fullchecksumno memoryuser cancelsyntaxfile not foundincompatible cp/m versionbad decode table͔4!͓TYPE -H FOR HELP  * &j;e9*<"RN8 :8= ^>V l21!N#W>ͼ: 6!!"6>2yʈ:2 ÈABORTEDï2*6>!  2j%y$>2j%G ͪ4ð4 ͔>ë5:<2Clos͑Ͷ4\$:Ͷ>\>g222ê4 Ͷ4 changes?h4͡4͑2<~-#~GͶxN*U6ml! ͚͡4inreceived from :.͗>ON)ʨ:e2,2e*4m ã:͗+mTo! ͡4outsent to F+:.͗2O9ͪ4>KN) v2~5mͧ4ö4,}*6\, ͡4Press ^C to stopF+t9ȗ,:͗+X*h,1/Xͤ9.,w͡4Deleting: :.G3́.>P͛13,3*6Ϳ *6) ʣ úC% N8 ͡4Undeleting%" ͡4 %.&*%*%*/&.C%"%"% Ͷ4 can't be  undeleted--name existsU&7÷~(#>):< +6>2:2> 92 2 g Tj !=2 º ͪ4>2  Ͷ4 |  2:\2:=Ī4:0ͪ4221em:À>?Ͷ!͚92<2ɗ2B *<;<= *6Ϳ: >:͟7 ͊7:= !<*6>͛ *6" *U" !"U:0!" >O2 :͗+Jo7:͗+y$y;`i#"" N8 e<% s#r#6 #%:B=N7s#r#å oN8 7!"* ͪ4! y;;< " g|<") 2[ {<": ͪ4!Ͷ4.>͇5!|&͏.."6!R I6>  7>k2X Ͷ4 : 4O6ABCDEFLMOPQRTUVWXYZ? ] y͆!Ú9* # * +} * Õ g Ͷ4?h4 *) { %͡4Deleting: .&:>O >> >U&Ͷ4    Ͷ4ind what? s  O >*w#w#wC% %}BK;<, * Ͷ4Log: g "6g >*s͡4, , Print, , or View (DEPQV) Enter one: 42 O6EQDPV y͆ ͡4Destination? \[-  ͭ.>::#6} >D ͼ |&."6  : D{  Ͷ4 name: g "6kg  Ͷ4  ͱ Ͷ4  ;{ ͫ*c >*"22s Ͷ4 Tagged = >k͆Ë ͫ ʔ O<> e  ͡4Old:  =<Oͼ:"6͡4New: K N g o7!"6!"U >!͖564O6LOXYZ?y?` a ͽ Menu>52x 2$>2d !~> 2x ^No. ;^No open. Jͧ4ö4+j; !"2!#";<ڑgk<>ʨ#N#F<* g##~"i #k<*>::*6"*<"6*Ù6!"6B*U>"#:6#"U,m>"*6Ϳ2?2=2E!\>,8) C% >ʁ>͗+',,\3!=33ͭ.́.<:>ON)2E `iÎ%%(&>a(ž; 3;!#"> ͇5Ͷ4--> found;Ð!"͡4Now searching: O9e9TʬBO: 2y2 6':;BCFHKLXY>:y6"JZ:e:m m4 CmlF+͹2:.GG31Insert disk containx͗͡4 and pC]O9e9!W>"6"U>¾!J~6>¬͡4-:: 6ABCDEFGHKLNOPQRSTUVWXY<>?O!ͥ7͘7͓͉͆9z>:4Ͷ4:>>a*6:eG:͗+G&H6[7 !!̀6"U*62>͗+ʦt9ʑfʑ!+"z}l C5!"z!"zͣ:,2e'd>ͫ5O*6> ڷw# ²,2͋!33ͭ.!W>ͭ.> 6;76 #!U=͘7>O2 !mT5}"z:e͗+*:2i~5͒ERROR ͧ4>v>Ç5>&H%'2e9͒closed. 2~5͡4CONOUT file ö4!=:,ͭ.\[-og2G'3OG3;<1> y$`i""N8% |&#:N87g,!:,2=ͭ.!=͘7oG3F+͛1>5!ͭ. will be ked to >W4>5ͪ42ʬ!"%"r"%!oG3)2"+!"I"&&!="t9ʕ+"*&&}O<Ͷ4 -Continue?h4ʕ!}+"+͡4 Copying: !#"U&#!:"$ͼ:͓.% s#r###"ͨ&+>+>G3ͺ+`}*%"%*j"jʦ>MʦM•*,DM!"r:,G3>ͱ*ʕ*,",I8 :,G3'2*!O9Ͷ4 abortedreopenold>K2 *6!"6k"6m7*j}*,DM*r:,G3>ͱ*ʕ\:=G3͛1:,G3g,!>::#>.682͑Ͷ4 ked.m7÷!"jͪ4eT) +!<+*6\[-K !52>-2$>2!>?2ͧ4͔4Ͷ4 >5ö4l2 :.G32(321F+m2>͗+G>g,*<:,ͭ.o1Can't find ͑͡4Replace it and pCʑ1F+: 6KOXm͡4NO LIBRARY OPENmlF+! ͥ 2͑͘222 Ͷ4 open. (Buffer size: *,*,O<><Ͷ4 sectors)múU :>U !=> 6͓Ͱ4 not found. To make it, enter the number of to allow.!"͡4 Pnow to abort making the. Allow how many: ~~<~T#͓É!> ͖5ʑ52}>N ;<ڪ;<ҼDM!=o͇M Too many.2!<"*6>=:6#͌:"o5f5> 4o5f5͡4 ͧ42ʧ4O> >͇5#ͪ4>Ćy͆͆9͓#:2 :2ͪ4͓2>@mm͌:2|e<͘7o9*<@>ͫ5u*6̀66~ž:‹um*U6 :͗+mͪ4l*6) *<;<>>̀$K >Oà>Rà:>O mg,͘2͡4 is READ-ONLY. Modify anyway?h4g22 <2>S ͡4now O:2^>NÆͼ4FF:2: 6'":;BHIJLOUYZ<>ʋ>Í>?2 g,:,*<ͭ.> 6¨ > 6'":;ABCDEFGHJKLNOPQRSTUVWXYZ<>?*6Ϳ:22*6) ͢! >2:22?CmU:2*U>U=͘76,}"*6\, !I-͘7 w<2yOyO}o|g|g}!oi a_{zı9{z33:l,>͗+*,*,w*,O<K'H",ė+G3Z͔z   := G >G:cx2> 2<5&o:2͡4ERROR Ͷ4: }!Z:!]W!Oͥ7͓ê4unnamed!W>{ʍ)ʍʍʍw# p6y~<#O!ͥ7͓Õ͉ÕJ*: 6VPS<+4T`UC} O P)Pk#E N d] = W ) / E Z  ,}\,͔4\:.́.!=<:>ON)3!DMc'',,LUS"`i#>(<"))"Ͳ&<:>PN)>2< <",;<͞:!  :`i"!rs#rͶ'!ͥ MSe<>K͛ 1'>M 212l"n͡4Library: +͡4Name Index Size KiloBytes CRC2j%>!C%"<%% y¸͋>5͡4DIRECTORY >5xͪ4(&>P5͂>P5͂>P5:B=N7͂>P5>2<*&&=I6>0 7͓x"<*%?͋*%X͋p͋>5͡4Active sectors ͡4Unused ͡4Total <2j%>5G ͈Ó=> 2 72$:l,2՗C%<N8=[-2\BK.F+͡4Extracting...>͗+t9%<7͡4 %*/&͏.\͋Ͷ4 to ͨ&>7a(: ͗ '2RyN!=;6̓͗>&ʑa(S‘'ʑ:͗++*&&}O<>K \[-BK!=. '\͹2!=>ͭ.>K<:N)+ *!O9:<'4&*,>ͱ* 'C%͡4Deleting...%ʼ%͡4 .&y =U& >U&*%+"E >2< *,"; !; w3A ͡4Active entries: *%Ͷ4, Deleted: *%Ͷ4, Free: *&Ͷ4, Total: *%Ͷ4.ɗ2<>ON)!"&"&"&}#",J*ʁ!~’! #~ ’! #|<A<’!{<{<"T!'))Ͳ&y!"%"a!!j;"!e9<:*<>N):.2,>;;k *, ~͊& yi!:l,͙!>M'ʕ!ʕ!'>dO9'C%t9%ʼx5̔4̪4%(&c'å!2A",2#<=,"+t9q#+"H$2j%<$><$,q#,=;=m$#"!I->.:#m$#"!!"W$#ͪ4C%q"|<"W$V$q">Oʠ"Rʠ".&Ͷ4 already exists--not added.!:A"R "d$Ͷ4 not in library--not replaced!=3"d$Ͷ4: Cannot add an 8 megabyte file!!"#V$>U&z$%"%"#*#O<"#e#>#Ͷ4No room for: d$<[#*&}>fG#Ͷ4No directory space for: #*H$"#*%O<#e#V$>U&!2# !>2j%U2$V$ʘ#Ͷ4Replacing: ç#Ͷ4Adding: "*$U&!=͘7;d$ q#p###"$4$=)2*,DM!"6$>+2$:.G3ͺ+:,G3$($+"<*#>ͱ**6$"6$($#!>U&q#pz$%%;¤%!#"%!"%ò%!#"%!"%l%s#r#l%"%DM"%y>U!}+"%!^#V#"%!O<*,DM"&|&"/&<~ k2<~!&n&<##d&^#Vr+swÊ&+> <*,!&ʙ&<##Ï&4Ÿ!Aj; >9~ʼ&ʾ7#&y&~&&# &<<*+*B+w*D++}K'*,#",g,͛1'USɗ%'>%'>%'<<;'<4'K'g,1ȗ2e,K,*,7<*,DMF/g,*,͸,`i",>a('Gyʀ'Ͷ4---> !=͓x5:o'>5͡4^C=abort,^X=next file,L=next line,=next page>5>2(ͪ4x' (a('_(x5'4<͡4press RETURN...4>N͉ t9<>=2(x53(:o2(446 L3(!H(Ú9R(W(<\(R(>(>(>N2((2(+>ͺ:l,2(!("/"(!"(*<"(*, "(>(U/"(®(t(*,O<",*tڨ(!/"(>2(!;<~#"(:l,2)>͗+J**, "(*+*B+"(>͗+(S>*,DM8)/)**5)!)#",*,;<>RS*, ~2)")`i>(<> <"):l,͗+*,:gG~})#p)>F:g<͗+<:*g98PYO<گ)><> <³)>ڳ)ʳ)>MDMO<)BKe<*,s#r`i",!:)=$:)[-2,G3:<>,.K,9,,*,N8g,!$9:l,͗+>2e,*,DM*,!",J*<F*{><<2*]*"*",`i",*,}DM*,*,O<><>M;ҙ*2!3͋1,,*,DM*,O<",Ҿ*"*`i",BK*,*,g,*2!3{1*g,͸,:<,*<*,2g,!",",3͋12g,:,́.<ͬ<*,*,"B+*,O<"D+ͼ<33:l,2v+ :gj+͗+G3ù2y͗+W+*h,~W+! ~###~1)2wwW+:e,K,2l,,,ȷ:,G3:gO*<9,N8O ,N8*h,\$͋9<*,DM!",*,:",ͼ<*,*,*,O|,O:g,>Bɷ!+ "b,!++ ",v<"h,8 ",2!͞:R1<#22!͞:j1<2#!"-*-#"-< -[-!I-ͭ."-!I-[-G3!1O+},-2-y!`O #[-332.<2'32.>::~ʰ-͟7 # 6> 2<5ʙ-|™-}*kҙ-2.6ʯ-@O:j".+q# -*?-.- ڴ-3;-ô-xʴ- y-xʴ--w#.x >?-> H99>?:.>2<+:#>>;7#Pd.12Ͱ4File exists-delete it?h4>P͛12U2KU.2w.)2US>M<2!=ͭ.ɗÕ.> !=ͭ.>::#6ͼ 2<2@w#i&I6;76:#:>.:# .ͺ:<~> 2-/#~?/?/>2-/~=/#PY:>< #~?A/6/`i>(t×/ʹ/=2/>////>==2/:/2/O! "/O>/70O>=2/yO! 0##^#Vz/y2/z&0{/*/O<>70>J<2@2T0@ͳ0Ͷ4Drive : Total *I=T]*E=#zW{_u0+j0:B=ʆ0)=~0Ͷ4k, Used O<Ͷ4k, Free Ͷ4k<21:8=00*<*<22=_.͔D^#V2<0`Z30><<͔*E=# 1W+}11z 1`i:B=-1)=(1<0ͼ<͔=1@=::8=1ȗ+w+w<͔ʼe1>Z3<͔ʼZ3<"͔ʼOZ3<!͔ʼOZ3S͔<Z3*< 2ͼ<"<Ô#͔! |<!!s#r#6>332(3:I3< ͔2I3<ͼ<2I3_ ÔG:8=0yu3xn3u3|y| d4:|<"A4{<")4{<"04{<"3|Ÿ3}=!I<Ҵ3DM)ң3`i÷34+}¾3#"3# 43!O<33 43!O<33*34þ3|g}o#4:g4A4!4;4;4J4 :f4-7J4͋9YͶ4No>N>5>2ͪ4ö4ͪ4ͼ4 o9ö4͓͓43;>́:42S=.:C5~>5~͆>5#4> 4 ͆S5:2:2::2O:<͆9É5*5++"5ͫ5##"5qܨ<#6+ ͔^#r{ͬ<=I6Ó՗2F6͌:A62ͼ<"k6:<O͜;}Q6{0:j6!w#"k66~ͮ9#v6+Ͷ6"6W>~ʧ6ʥ6#ͫ6ʎ6Ͷ6y~6 #ͫ6¶6Z:;79:3;287̈́<>U~3;G3;#<(<)=U7"f7!N#F# ͌:{7 bk ͑7ü:͘7 ͌:ò:͌:ü:.:ü:|< xʼ7:#zª7<:`:88*Mm8*8*hOTDM#"8*8 w#s#r8e<"<#9ʼs#rÐ828"88*8;<><#|<8#98"8v<>8O<8"ÿ8ê8!}!#~#8~ 9;<#8++~<2$9~>269bk",9<>=2$9!##",9>v<<<<:*g9< O<*g9O<`9"g9<>M!"g9>Æ>́:>N:> Æͼ<͙<~w#_N::ͼ<_ 9 9 9:9=ü9 9 9>9><29ÔW:d 9999 y:2:͙<6#;;O~*:<#:<#2:yͬ<*՗2;>)ܔ;yOxG҈;ܔ;=v;:;><2;?y";}|;3333x;՗yOxG{_zWñ;z;}o|g!";é;*;<`i SUPER DIRECTORY PROGRAM information (primarily for SYSOPs) Information on how to install/use on RCPM systems. Read the SD.HIS file for the history of updates to this program. ------------------------------------------------------------------------ NOTE: May be assembled with ASM, LASM, M80, MAC or SLRMAC ------------------------------------------------------------------------ NOTE: All usage examples below assume the use of $ as an option marker. For those who prefer the ZCPR style / may be used instead, and for those who for some reason like the CP/M+ method, [ serves the same purpose. In other words, SD *.A?M $ADLN SD *.A?M /ADLN SD *.A?M[ADLN] are all identical. A space is required before $ or / but is not needed before [. A trailing ] is optional (and ignored) ------------------------------------------------------------------------ A feature has been added that does away with the need for several versions of SD.COM. It allows the inclusion of a 4, 6, or 8 on the com- mand line which relates to 40, 64 or 80 character displays. (2, 3, or 4 filenames per line.) The default value is that stored in NPL and LPS if MAXCL is NO, and the value at MAXCL and LPS1, 2 or 3 if MAXCL is YES. MAXCL - this equate, if YES, enables RCP/M operators to store the value of 2, 3, or 4 at the location defined by MAXC. Just have your signon or RBBS program ask for or assign a value for NPL (names per line) and store it at the location MAXC. The suggested addresses for MAXC are 3BH if using 3EH for the wheeel byte location or 3EH if using 3BH for the wheel byte. No need to keep several versions of SD online for various users, such as DIR40, DIR64. The following equates are the values for the number of lines per screen (LPS) to be changed as needed when MAXCL = YES. LPS1 - this is the number of lines per screen if NPL = 3. (64 col option) LPS2 - this is the number of lines per screen if NPL  < 3. (40 col option) These additional equates allow one to specify the number of lines that will be displayed for each of the optional formats (4 & 6). This would allow one to set up SD for optional remote use with a TRS-80 Mod 100 (for example) by setting LPS2 to a value of 8. Here are some command line examples: If MAXCL = yes SD Will display all files on current drive using the value stored at MAXC to determine the number of filenames per line. SD $6 Will display all files on the current drive and display files in the 64 column mode (3 filenames per line). It will also store a 3 at the memory location defined by MAXC for subsequent use by SD or any other utility that uses the variable filenames per line function. If MAXCL = NO SD Will display all files on the current drive using the value defined by the NPL equate. SD $4 Will display all files on the current drive and display files in the 40 column mode (2 filesnames per line). It will revert to the mode de- fined by NPL on subsequent uses of SD. KTHREE - this equate allows control over the number of columns used in the display of file sizes. If KTHREE = YES, then only three digits will be used, limiting proper display of file sizes to 999k or less. If KTHREE = NO, then SD will use five digits, allowing files as large as 64,535k to be displayed. The advantage of using KTHREE = YES is that you may use a fence charcter even in the four file display mode. This makes the display more readable. (Note: KTHREE only changes the display of individual file sizes and totals are not affected.) PDRI RI & PRUS - these equates allow (if YES) or disallow (if NO) the printing of the drive and/or user numbers at the front of each file display line. These affect only the CRT format and all printer formats still report the drive (and user if REPUSR = YES) numbers. This allows the display of the user number without the drive specification if this format is needed. A good example would be a 40-column format used on a RBBS which makes use of a large number of user areas. NOMORE - This equate, if true, adds an additional LF after the [more] message at the end of the page. If not set, when running remote and being saved for later printing, the [more] message is over-written by the next directory entry and shows as trash on a printout. Not a problem for local use. PRLIBD - if this equate is set 'NO' when PRDI and PRUS are 'YES', SD will suppress the display of drive/user numbers on LBR file display lines. One may wish to use this format if PRBRDR = YES. PRBRDR - allows the printing of a quasi-border around the left side of library file member lines if set 'YES'. This makes for a more read- able format when displaying a large number of LBR files. (Try it both ways until you decide if you want this option on or off.) USELC - This equate can be set to display file name characters with attribute bits set in lower case OR highlight video (reverse video is the recommended choice). Which method is used depends on the length of the RVON string. (Video highlight sequences are not sent to an RCPM caller but still display on the local screen). Similarly, and again subject to the USELC option you can display the banner in a (possibly different) hihlight mode. In place of the $U option, you may specify the Drive/User with the filename, such as: SD A1:*.*, SD 1:*.*, SD B:FN.FT, SD B4:FN.FT $AD, etc. You may still use the $U option if desired, although it seems the DU: form is a much easier and more logical method. File lengths over four megabytes are read correctly. Files may be shown in vertical or horizontal listings, although this must be set when the program is assembled for a particular system. The distribution copy is set for vertical alphabetization since most non-RCPM users will likely prefer this presentation. (SYSOPs will need to set a number of equates and reassemble the file in any event.) SD.COM has support for .LBR files (an 'L' option to list their mem- ber files) and support for the "WHEEL" byte option. Size of library member files are shown in 'k'. To use SD.COM: B>SD shows all non .SYS files on current drive/user B>SD *.* same as SD B>SD ? displays a help guide with available commands B>SD *.ASM shows all .ASM files on current drive/user B>SD HELLO.* shows all files this D/U starting with HELLO B>SD *.TXT $AD shows all .TXT files on all drives and users B>SD MDM.* $ADL shows all files starting with MDM on all drives and user areas and in all libraries In addition to the filename option, up to 11 command line options may be specified. Option fields are preceded by a single dollar sign. Example: SD B:$ADnU0fpS. (Upper-case and/or lower-case may be used.) Spaces within the option field are insignificant i.e., "$ SADN U0FP" is equivalent to "$ S A D N U0 F P"). The only exception concerns the "USER" option, cannot say "U 5", must say "U5", etc. Users should also be aware of two restrictions on the command line format. SD scans the entire command line for a dollar sign preceded by at least 1 blank to delimit the beginning of the option field. For this reason, invoking SD with a command line such as: "SD $ $AR" is illegal, since SD will consider the first dollar sign to be the option field de- limiter. If you need to specify a filename whose first character is a dollar sign precede it with a drive code as in "SD A:$ $AR". In this instance, SD will consider the first dollar sign insignificant as it is not preceded by a blank. The same applies to the "/" character. You give up the ability to specifically search for a filename whose name begins with a '$' or '/'. However, such files will be listed along with others if the command line "SD $CU3" (or any other options) were specified. OPTIONAL COMMANDS: ----------------- "A" - all users: Causes SD to display directories of all user areas starting at the user area specified in the 'U' option or, if the 'U' option is omitted, user area 0 and continuing up through the MAXUSR value from the LODRV-HIDRV table. (WHEEL=TRUE and the WHEELbyte set, 0-MXZUSR.) "D" - all disk option: Allows SD to search all disk drives online starting with the first disk drive allowed (nor- mally "A" drive). For example, "SD B:$D" will result in SD searching all drives beginning with drive B. "SD $D" will result in SD searching all drives auto- matically beginning with the A drive, regardless what drive you started on. "F" - file option: The directory output will be echoed to a disk file named "DISK.DIR" on the DEFAULT drive. If this name already exists then the directory output will be APPENDED to the end of the file. "DISK.DIR" will otherwise start as a new file. The append feature al- allows you to build up one massive file on the default drive containing the directories of all of your disks, without having to concantenate a swarm of individual directory files. "L" - LBR list option: Library file members are shown followed by their length in 'k'. The total length of the entire library is also shown. "N" - no page option: Disables the page pause option. Use- ful when running SD in the 'F' and/or 'A' modes when you don't want the page prompt slowing you down. The page- pause prompt will not be put into the output file or to the printer (if either is enabled). "O" - only shows .SYS files: Most CP/M systems have at least a few .SYS files which normally do not show when requesting a directory listing. This option shows ONLY those .SYS files. (R/O files show with any normal listing.) It is very handy feature as no reverse video, etc. is needed to quickly show .SYS files. (USELC can be set to put the attribute character into lower case for both .SYS and R/O files, we recommend its use. REVID will allow using reverse video in the display if available.) "P" - printer option: Forces all console output to be echoed to the CP/M list device, with the most significant bit set to 0. "Q" - Quickly show NEW files: Show the files that do NOT have the archive flag in a file's directory entry set. This will show new files that have been uploaded or recently added to the disk. For example, to see a list of ALL new files in ALL user areas of ALL drives, enter: SD $ADQ. To see the new files in just the area that you are currently logged into enter: SD $Q. "S" - system option: .SYS system files will be included in the output rather than being suppressed. (USELC will show the attribute character in lower case, easily and quickly identifying any .SYS files when this option is exercised. R/O files will also then have the attribute character in lower case. REVID will allow using reverse video if that is available.) "U" - user option: Allows the specification of the user num- ber for the directory of the form "Uxx" where the user # is greater than 0, but not greater than a specified value not to exceed 15. The user option specification will be illegal if the user # is out of range, omitted, or if 'U' is specified on a pre-CP/M 2 system. "U1" is legal, but "U 1" is not. In this respect, the 'U' op- tion differs from the other options in that embedded spaces ARE significant. "V" - SD version number and date is displayed. "4, 6, or 8" - Filenames per line option: These will allow the user to specify the number of filesnames per line to be used in the display. The format used relates to 40, 64, or 80 character displays which give 2, 3 or 4 filenames per line, respectively. If MAXCL = YES, the specified value is stored in the memory location de- fined by MAXC. If MAXCL = NO then SD reverts back to the value defined by NPL after displaying the optional format. If MAXCL= YES and WHLCL = YES then SD will not allow the use of these command line options and will use the value stored at MAXC for display. If an unrecognized option (or illegal user option specification) is detected, the command line will be played back to the console up to the point where the error was detected. If the REPERR option is disabled, SD will ignore everything on the command line past the illegal field. In this situation, an incorrect user number would default back to the current user number. Finally, if the all-disk and/or all-user options are enabled it may be desirable to restrict searches. To facilitate this, a table is in- cluded in SD (beginning at label "LODRV" and continuing through "HIDRV"). The table consists of a single byte for each drive to be searched begin- ning with 'A'. Each byte may be in the range of 0-31 and defines the highest user number that SD will search for that particular drive. The highest drive number to search is defined by the length of the table. If four DBs are present between LODRV and HIDRV, then drives A-D can be searched. The source file includes the LODRV-HIDRV table in its maximum configuration for 16 drives. However, delete all DBs referencing drives that are not available on your system. Even though SD will intercept attempts to search non-existant drives, there really is no point in al- lowing SD to always search drive C when you only have 2 logical drives. Depending on how your BIOS is constructed and how long it takes to let the BDOS know of the select error, it could save some time. You don't have to be running NZCPR or ZCPR2 to use the WHEEL, MAXCL, MAXUSER, or MAXDRIVE byte features, just have your signon or RBBS pro- gram assign and store the correct values in the proper locations to set these features, or add code to BYE to provide the correct values when a remote user logs on (before entering CP/M). - Notes contributed by various people er to search is defined by the length of the table. If four DBs are present between LODRV and HIDRV, then drives A-D can be se; SUPER DIRECTORY PROGRAM ; SD116 ; 30 Apr 86 ; ; Read SD.INF for detailed instructions on configuring SD for your ; system. For information regarding this utility's modification ; history, read SD.HIS. ; ; ; NOTE: This version can be assembled with ; ASM, LASM, M80, MAC, RMAC OR SLRMAC. ; ; ; SD displays the directory of a CP/M disk, sorted alphabetically, with ; the file size in k, rounded to the nearest CP/M block size. It also ; displays library files with the file size in k, if the '$L' option is ; selected. ; ; Current versions of SD automatically adjust for any block size and di- ; rectory length under CP/M 2.x, 3.x or MP/M (any version). They also ; automatically adjust for any number of disk drives and work satisfac- ; torily even if no disk is in that drive at the moment. Provisions are ; made for: ; ; 1) automatic pauses when the screen fills up ; 2) searching individual or multiple drives and/or user areas ; 3) unconditional or optional resetting the disk system before ; execution begins ; 4) directing output to a disk file called DISK.DIR and append- ; ing to that file on subsequent runs ; 5) summary line output giving drive and user information, ; number of files matched and how much space they consume, ; and the amount of free space remaining on the disk ; 6) displaying or suppressing "system" files ; 7) accepting ambiguous filenames with or without a drive name ; 8) printer output ; 9) optional help menu with '?' ; ;----------------------------------------------------------------------- ; ; (Remove the semi-colon (";") from before ASEG if assembling with M80) ; ; ASEG ; Needed for M80 or RMAC ; ; ; Define version number ; MAIN EQU 1 ; Main block number VER EQU 16 ; Current version ; MONTH EQU 04 ; Month DAY EQU 30 ; Day YEAR EQU 86 ; Year ; ; NO EQU 0 YES EQU NOT NO ; Cannot use 0FFH with many assemblers ; EDATE EQU no ; Set to NO for USA, YES for anywhere else. ; Only affects format of numeric date ; (DD/MM/YY vs MM/DD/YY) in version display ; ; Define some ASCII characters ; CR EQU 0DH LF EQU 0AH ESC EQU 1BH ; ; ;------------------------ user options --------------------------------- ; CPM3 EQU NO ; Set to yes if using CP/M 3 or above TIMEON EQU NO ; YES, fetches TIMEON from BYE and dis- ; plays "Time on system is xx Minutes" ; ; ; RCPM options ; WHEEL EQU yes ; Yes if using a wheel byte for RCPM use MAXUR EQU yes ; Yes if MAXU byte is supported MAXDR EQU yes ; Yes if MAXD byte is supported MAXCL EQU NO ; Yes if storing MNPL value at MAXC WHLOC EQU 3EH ; Set to wheel location if using wheel MAXC EQU 3BH ; Set to # of names per line location MAXD EQU 3DH ; Set to max drive location if MAXDR=Yes MAXU EQU 3FH ; Set to max user location if MAXUR=Yes MXZUSR EQU 15 ; Maximum user # allowed with WHEEL set ; ; ; Command line options ; PGPAWS EQU YES ; Allow pause [more] after each page? ; ; ; If any of the following equates are set NO, it prevents their use by ; any user (including the SYSOP) unless the wheel byte has been set for ; SYSOP use. If running an RCPM, you may wish to say NO for those with ; an asterisk, such as USEF, USERO, USEP and USES to prevent others from ; using them - the wheel byte would make them available for SYSOP use. USEA EQU YES ; Allow looking at all available areas? USEC EQU YES ; Allow selecting 1, 2 or 3 columns? USED EQU YES ; Allow looking at all available disks? USEF EQU no ;*Allow making a local disk copy? USEL EQU YES ; Allow showing all library members? USEO EQU no ;*Allow showing only $SYS files? USEP EQU no ;*Allow making local printer listing? USEQ EQU YES ; Allow showing only non-$ARChived files? USES EQU no ;*Allow showing all, AND $SYS files? USEU EQU YES ; Allow selecting starting user area? ; ; ; Displaying files with tagged attributes ($R/O, $SYS, $ARC etc.) ; in an unique manner so they are easy to find, if present. ; ; Example: ; ; FILENAME.SyS - $SYS attribute set ; FILENAME.doC - $SYS and $R/O both set ; FILENAME.com - $SYS, $R/O and $ARC all set ; ; For EITHER lower-case or highlight video display, USELC must be YES ; in which case the decision which to use depends on the setting of the ; string at label RVON: below. ; USELC EQU YES ; Yes for lowercase letters (A-Z) for ; tagged attributes. ; ; If your terminal supports inverse or other highlight mode, you can ; have attributes show as inverse characters. This allows any character ; tagged to be visible, as opposed to the simple USELC method. All you ; need do is patch in your highlight-on and highlight-off strings at ; RVON and RVOFF AND set USELC to YES. ; ; You can also have the banner lines printed in (a possibly different) ; highlight video. Patch in the strings at ULON and ULOFF. ; ; Up to 7 bytes each for enter and exit codes are allowed, can patch via ; DDT, etc. ; ; If running under BYE then inverse video will only appear on the local ; console. ; ; ; Hardware equates ; IF NOT MAXCL NPL EQU 4 ; # of names per line max values are: ; 2 for 40 x xx, 3 for 64 x 16, and ; 4 for 80 x 24 ENDIF ; NOT MAXCL ; LPS EQU 24 ; # of lines per screen max values are: ; ? for 40 x xx, 16 for 64 x 16, ; 24 for 80x24 LPS1 EQU 16 ; # of lines per screen if names per ; line = 3 LPS2 EQU 8 ; # of lines per screen if names per ; line < 3 FENCEC EQU '|' ; Separator character - space for none ; ; ; Miscellaneous equates KTHREE EQU NO ; Yes limits file size columns to three ; digits. NO=normal for 80 char. line PRDI EQU NO ; Yes to print drive # on each line PRUS EQU NO ; Yes to print user # on each line PRLIBD EQU NO ; If Yes and PRUS and PRDI are Yes then ; drive and user numbers will be dis- ; played on library listing lines. PRBRDR EQU YES ; Yes to print quasi-borders for library ; files VCODE EQU no ; Yes for normal vertical alphabetization ; ; ; BDOS equates ; BDOS EQU 0005H FCB EQU 005CH TBUF EQU 0080H ; RDCHR EQU 1 ; Read character from console WRCHR EQU 2 ; Write character to console PRINTS EQU 9 ; Print string CONST EQU 11 ; Check console status CPMVER EQU 12 ; Return CP/M version RESET EQU 13 ; Reset disk system SELDSK EQU 14 ; Select disk OPEN EQU 15 ; 0FFH=not found CLOSE EQU 16 ; " " " SEARCH EQU 17 ; " " " NEXT EQU 18 ; " " " READ EQU 20 ; Not 0 = EOF WRITE EQU 21 ; Not 0 = disk full MAKE EQU 22 ; 0ffh = directory full CURDSK EQU 25 ; Get currently logged disk name SETDMA EQU 26 ; Set current DMA GALLOC EQU 27 ; Get address of allocation vector CURDPB EQU 31 ; Get current disk parameters CURUSR EQU 32 ; Get currently logged user number ; ZRDVER EQU 48 ; Return ZRDOS version SETWBT EQU 50 ; Set warm boot trap (ZRDOS) RESWBT EQU 52 ; Reset warm boot trap (ZRDOS) ; ; ;----------------------------------------------------------------------- ; ; BEGIN EXECUTABLE PROGRAM CODE ; ;----------------------------------------------------------------------- ; ; ORG 0100H ; JMP START ; ; IF NOT MAXCL MNPL: DB NPL ; Names per line (# of columns) MLPS: DB LPS ; Lines per screen (between pauses) ENDIF ; NOT MAXCL ; IF MAXCL MNPL: DB 0 MLPS: DB 0 ENDIF ; MAXCL ; FENC: DB FENCEC ; Fence character ; VERNAME:DB CR,LF,'SD',MAIN+'0' DB VER/10+'0',VER MOD 10+'0',' - ' ; ; IF EDATE DB MONTH/10+'0',MONTH MOD 10+'0','/' ENDIF ; EDATE ; DB DAY/10+'0',DAY MOD 10+'0','/' ; IF NOT EDATE DB MONTH/10+'0',MONTH MOD 10+'0','/' ENDIF ; NOT EDATE ; DB YEAR/10+'0',YEAR MOD 10+'0' DB 0 ; ;----------------------------------------------------------------------- ; IF USELC DB 'RVON>' ; Pointer to help locate via DDT RVON: DB 0 ; Length of string following DB 0,0,0,0,0,0,0 ; Up to 7 chars for ENTER REVERSE ; DB 'RVOFF>' ; Pointer to help locate via DDT RVOFF: DB 0 ; Length of following string DB 0,0,0,0,0,0,0 ; Up to 7 chars for EXIT REVERSE ; ; ; If byte at RVON is zero then simple lower-case will be used to display ; file attributes. DB 'ULON>' ; Pointer to help locate via DDT ULON: DB 0 ; Length of following string DB 0,0,0,0,0,0,0 ; Up to 7 chars for UNDERLINE ON ; DB 'ULOFF>' ; Pointer to help locate via DDT ULOFF: DB 0 ; Length of following string DB 0,0,0,0,0,0,0 ; Up to 7 chars for UNDERLINE OFF ; ; ; If byte at ULON is zero then no highlighting will be used for the ; banner line. ; ; Recommended choices for monochrome screens: ; File attributes in REVERSE video ; Banner UNDERLINED ; ; If you have a colour screen then your choice but main text in yellow, ; file attributes in inverse red and cyan banner looks slick. ; ENDIF ; USELC ; ;----------------------------------------------------------------------- ; ; Drive/user area lookup table ; ; Note that the LODRV-HIDRV table is included here fully configured. ; For your own use, you should change the maximum user areas as appro- ; priate for each drive on your system. Note that there are only 32 ; user areas available under CP/M 2, so the highest legal user area you ; can specify is 31 (range 0-31 = 32 areas). The program will convert ; anything over 31 into mod 32. Enter 0FFH to skip a drive on a search. ; This method allows multi-drive systems to be searched that are not ; necessarily sequential. Use 15 (range 0-15 = 16 user areas) if your ; system does not have/use the extended range to 32 user areas.) ; DB 'MAXUSR TBL>' ; Label to make finding the table easier ; LODRV EQU $ ; Mark beginning of drive/user table ; DB 15 ; Maximum user area for drive A DB 15 ; " " " " " B DB 15 ; " " " " " C DB 15 ; " " " " " D DB 0FFH ; " " " " " E DB 0FFH ; " " " " " F DB 0FFH ; " " " " " G DB 0FFH ; " " " " " H DB 0FFH ; " " " " " I DB 0FFH ; " " " " " J DB 0FFH ; " " " " " K DB 0FFH ; " " " " " L DB 0FFH ; " " " " " M DB 0FFH ; " " " " " N DB 0FFH ; " " " " " O DB 0FFH ; " " " " " P ; HIDRV EQU $ ; Mark end of drive/user table ; ; ;----------------------------------------------------------------------- ; ; Program starts here ; ;----------------------------------------------------------------------- ; ; START: LXI H,0 DAD SP ; HL=old stack SHLD STACK ; Save it LXI SP,STACK ; Get new stack ; ; ; See if help is wanted ; LXI H,FCB+1 MOV A,M CPI '?' JNZ INIT INX H MOV A,M CPI ' ' JZ HELPME ; ; ; Zero out the entire initialization data area ; INIT: LXI H,DATA0 ; Point to beginning of init. data area PUSH H ; Save for non-zero filling later MVI C,DATA1-DATA0 ; Get length of data area XRA A ; Zero accumulator ; ZFILL: MOV M,A INX H DCR C JNZ ZFILL ; ; ; Now copy non-zero initialization data from the template area ; POP H ; Reset HL to data0 LXI D,TMPLT0 ; Set DE to beginning of template MVI C,TMPLT1-TMPLT0 ; Get length of template area ; NZFILL: LDAX D ; Get template byte MOV M,A ; Move to data area INX D INX H DCR C JNZ NZFILL MVI C,ZRDVER ; Get ZRDOS version CALL BDOS MOV A,L STA ZRDFLG ; Save it MVI C,CPMVER ; Get and save the CP/M version # CALL BDOS MOV A,L STA VERFLG CPI 20H ; Set carry if CP/M 1.4 PUSH PSW ; Save result for BYE test MVI E,0FFH ; Get current user number if CP/M 2 MVI C,CURUSR ; Fall through with A=0 if not CNC CPM STA OLDUSR ; Initialize startup user number STA NEWUSR ; And make new user match it STA BASUSR ; Directories POP PSW ; Recover CP/M version flag MVI E,241 ; Special BYE5xx call MVI C,CURUSR ; Returns 77 if BYE5xx active CNC CPM ; OK because BYE5xx won't be running SUI 77 ; on a CP/M 1.4 system anyway. STA BYEACT ; BYEACT=0 if BYE5xx running ; IF TIMEON CALL TIME ENDIF ; TIMEON ; LXI H,81H ; Point to command line MOV A,M CPI '[' ; May occur immediately after command JZ CLOK ; under CP/M+ (and maybe 2.2??) INX H ORA A JNZ CLOK MOV M,A ; CLOK: LXI D,FCB CALL FNAME MOV A,B CPI 0FFH JZ CLUS STAX D ; CLUS: MOV A,C CPI 0FFH JZ CLNON STA NEWUSR STA BASUSR ; CLNON: MVI C,CURDSK CALL CPM ; Get current disk nr STA OLDDSK ; Save for reset if needed INR A STA OUTFCB ; Set directory output file drive LXI H,FCB MOV A,M ; Get drive name for directory search ORA A ; Any specified? JNZ STRT1A ; Yes skip next routine LDA OLDDSK ; Otherwise, get default disk INR A JMP START2 ; STRT1A: PUSH PSW MVI A,1 STA DFLAG POP PSW ; START2: MOV M,A ; Put the absolute drive code in ; directory FCB ; ; If at least one option is allowed scan the command line for the option ; field delimiter. The option field delimiter is considered valid only ; if it is preceded by at least 1 space (otherwise it may be part of the ; directory filename). Any unrecognized options or illegal user numbers ; will be flagged. (We scan the command line buffer rather than the 2nd ; default FCB because all 8 options plus a 2 digit user number won't fit ; in the FCB name field). ; LXI H,80H ; Set command line buffer pointer MOV B,M ; Get length of command line buffer ; ; ; Search for valid command line delimiter. If not found, assume no op- ; tions. ; SCNDOL: INX H DCR B JM CLOPN ; Exit if command line buffer empty MOV A,M CPI '[' ; Allow CP/M 3 style option delimiter JZ OPTDLM CPI '$' ; Standard CP/M 2.2 style delimiter JZ SPB4 CPI '/' ; ZCPR style option delimiter JNZ SCNDOL ; SPB4: DCX H ; '$' found - make sure a space precedes MOV A,M INX H CPI ' ' JNZ SCNDOL ; No space - ignore "$" and search again ; ; Valid delimiter found. Scan the rest of the buffer for options. ; Errors past this point will cause an abort if the command line error ; option is enabled. Otherwise, the dud option will be ignored and SD ; will attempt to continue stumbling through the rest of the field. OPTDLM: XCHG ; Get option field pointer to DE ; SCNOPT: INX D ; Bump to next option field character DCR B ; Dock characters left in option field JM CLOPN ; If option field exhausted, exit ; SCNAGN: LDAX D ; Get the next option character CPI ' ' ; Do we have a space? JZ SCNOPT ; Ignore it if so CPI ']' ; CP/M3-style terminator JZ SCNOPT ; Can have options after ] if you want ; IF WHEEL AND (NOT USEU) CPI 'U' ; Disallowing "U" option, treat JZ CLERR ; As error if there.. ENDIF ; WHEEL AND (NOT USEU) ; LXI H,OTBL-1 ; Get base of option lookup table MVI C,OEND-OTBL+1 ; Get length of option lookup table ; NOMACH: INX H ; Bump to next option table character DCR C ; Are we out of the table? JZ CK4USR ; If so, check for user option ; IF WHEEL ; NZCPR/ZCPR2? (wheel byte?) PUSH PSW ; Save accumulator value LDA WHLOC ; Get wheel byte ORA A ; Check it JZ NOMAC1 ; It's zero, so forget it MOV A,M ; Get the table option CPI '4' ; If 4 then skip LC CON JZ UCBP CPI '6' ; If 6 then skip LC CON JZ UCBP CPI '8' ; If 8 then skip LC CON JZ UCBP ANI 0DFH ; Make sure is upper case ; UCBP: MOV M,A ; Stuff back in table ; NOMAC1: POP PSW ; Restore accumulator ENDIF ; WHEEL ; CMP M ; Compare character with option table JNZ NOMACH ; Exit if no match MVI M,0 ; Otherwise, activate the flag CPI 'D' ; All disk search? CZ NOMAC2 ; Yes, start at a always CPI 'A' ; All user search? CZ NOMAC4 ; Yes, always start at user # 0 JMP SCNOPT ; And go get the next option character ; NOMAC2: PUSH PSW PUSH H LDA DFLAG ORA A JNZ NOMAC3 LXI H,FCB ; Set FCB drive byte to drive A MVI A,1 MOV M,A POP H POP PSW RET ; NOMAC3: POP H POP PSW RET ; NOMAC4: LDA AFLAG ; Asking for $U3A or $U4A, etc.? ORA A RNZ MVI A,0 ; Always start at user # 0 STA NEWUSR STA BASUSR RET ;..... ; ; ; If option character doesn't match the table, see if we have a user ; option. ; CK4USR: CPI 'U' JNZ CLERR ; Last option, so bad deal if not it ; UAGN: INX D ; Bump to user number digit DCR B JM CLERR ; Error if nothing left LDAX D ; Get decimal digit CPI ' ' ; Ignore leading spaces JZ UAGN SUI 30H ; Subtract ASCII bias JC CLERR ; Error if < 0 CPI 10 JNC CLERR ; Error if > 9 STA NEWUSR ; Save user number, might be only 1 digit STA BASUSR ; Duplicate it if multi-disk mode MVI A,1 STA AFLAG ; To allow $U3A, etc. INX D ; Bump to possible 2nd digit of user # DCR B JM CLOPN ; No more buffer, exit with user # LDAX D ; Else, check for another digit SUI 30H JC SCNAGN ; If next char not numeric, it is not CPI 10 ; Part of user number so go check for JNC SCNAGN ; Another option MOV L,A ; Save units digit LDA NEWUSR ; Get tens digit ADD A ; Multiply by 10 MOV H,A ADD A ADD A ADD H ADD L ; Combine with units digit STA NEWUSR ; Save the total user number STA BASUSR ; Duplicate it if multi-disk mode JMP SCNOPT ; Continue scanning ; ; ; If command line error option enabled, playback the command line up ; to the character that we gagged on and exit. CLERR: XRA A INX D ; Tag end of command line with terminator STAX D CALL CRLF LXI D,ERRMS2 CALL PRINT LXI D,ERRTAG CALL PRINT LXI H,81H ; Playback bad cmd line to error point ; CLELP: MOV A,M ORA A JZ CLEX CALL TYPE INX H JMP CLELP ; CLEX: MVI A,'?' ; Tag line with a '?' field CALL TYPE CALL CRLF ; Space down 1 more line JMP EX0 ; And return to CP/M ;.... ; ; ; Options input or not specified. If reset option specified, reset ; the disk system now. Its important that the reset be done OUTSIDE ; the multiple drive loop if the file output option is enabled because ; CP/M 1.4 clobbers the DMA buffer on reset. ; ; ; Check for command line option for 40,64, or 80 column & store value ; CLOPN: LDA CL4FLG ; Load a with 40 column flag ORA A ; Test it JNZ CLOPN1 ; No then skip to 64 column test PUSH PSW ; If so then save accumulator MVI A,2 ; 2 names per line for 40 column ; IF MAXCL ; If storing value in external location STA MAXC ; Do it ENDIF ; MAXCL ; IF NOT MAXCL ; If storing value internal to sd STA MNPL ; Do it ENDIF ; NOT MAXCL ; MVI A,LPS2 STA MLPS POP PSW ; Get it back again ; CLOPN1: LDA CL6FLG ; Load a with 64 column flag ORA A ; Test it JNZ CLOPN2 ; No then skip to 80 col test PUSH PSW ; If so then save accumulator MVI A,3 ; 3 names per line for 64 column ; IF MAXCL ; If storing value in external location STA MAXC ; Do it ENDIF ; MAXCL ; IF NOT MAXCL ; If storing value internal to SD STA MNPL ; Do it ENDIF ; NOT MAXCL ; MVI A,LPS1 STA MLPS POP PSW ; Get back where you belong ; CLOPN2: LDA CL8FLG ; Load a with 80 column flag ORA A ; Test it JNZ DOPTN ; No then exit to test for 'R' option PUSH PSW ; If so then save accumulator MVI A,4 ; 4 names per line for 80 column ; IF MAXCL ; If storing value in external location STA MAXC ; Do it ENDIF ; MAXCL ; IF NOT MAXCL ; If storing value internal to SD STA MNPL ; Do it ENDIF ; NOT MAXCL ; MVI A,LPS STA MLPS POP PSW ; Get it back ; DOPTN: LDA DOPFLG ; If multi-disk flag set, ORA A ; Need to set error traps CZ SWAPEM ; Swap BDOS error vector tables ; ; ; Set MNPL and MLPS values if MAXCL ; IF MAXCL LDA MAXC ; Load a reg with value @ maxc STA MNPL ; Punch A into MNPL MVI A,LPS ; Load A- register with LPS STA MLPS ; Assume 4 names across LDA MAXC ; Get value at MAXC CPI 3 ; 3 columns across? JNZ LPCL1 ; If not then jump to LPCL1 MVI A,LPS1 ; Load A-reg with MNPL for 3 columns STA MLPS ; Punch it into MPLS ; LPCL1: LDA MAXC ; Get MAXC value again CPI 2 ; 2 columns across? JZ LPCL2 ; If so then jmp to LPCL2 and set MNPL CPI 1 ; Not 2 across, how about 1? JNZ LPSE ; If not then jump to exit ; LPCL2: MVI A,LPS2 ; It was 1 or 2 so set MNPL with LPS2 STA MLPS ; LPSE: ENDIF ; MAXCL ; ; ; Validate drive code and user area numbers from the drive table ; NOOPT: LXI D,DRUMSG ; Get the drive/user error message PUSH D LDA FCB ; Get directory drive code DCR A ; Normalize to range of 0-31 CPI HIDRV-LODRV ; Compare with maximum drives on-line JNC ERXIT ; Take drive error exit if out of range ; IF MAXDR ; Look for MAXD LXI H,MAXD ; Address to HL MOV L,M ; MAXD to L INX H ; Add one CMP L ; Check it JNC ERXIT ; Oops if not bigger ENDIF ; MAXDR ; MOV E,A ; Use drive code as index into table MVI D,0 ; IF WHEEL LDA WHLOC ; Get wheel byte ORA A ; Check it JZ USRCK ; If reset, restrict user MVI A,MXZUSR ; If set, max user = MXZUSR JMP USRCK2 ENDIF ; WHEEL ; USRCK: LXI H,LODRV ; Point to base of drive/user table DAD D MOV A,M ; Get the maximum user # for this drive ; IF MAXUR ; Use low memory values if smaller MOV H,A ; Current value of MAXUSR LDA MAXU ; Alternate value SBI 1 ; MAXUSR was really maximum user + 1 CMP H ; Compare the two JNC USRCK2 ; Jump if table value smaller or equal STA MAXUSR ; Else replace it ENDIF ; MAXUR ; USRCK2: MOV B,A ; Save the max user for later testing ANI 1FH ; Make sure its in range 0 - 31 STA MAXUSR ; Save it for later LXI H,NEWUSR ; Point to the directory user area CMP M ; Compare it with the maximum JC ERXIT ; Take error exit if user number illegal POP D ; Destroy error message pointer MOV A,B ; Check to see if this drive ORA A ; Has been mapped out JM NDSK ; If so then skip this drive LXI H,FCB+1 ; Point to name MOV A,M ; Any specified? CPI '$' JZ WCD CPI '/' JZ WCD CPI ' ' JNZ GOTFCB ; ; ; No FCB - make FCB all '?' ; WCD: MVI B,11 ; Filename + file type = 11 ; QLOOP: MVI M,'?' ; Store '?' in FCB INX H DCR B JNZ QLOOP ; GOTFCB: MVI A,'?' ; Force wild extent STA FCB+12 CALL SETSRC ; Set DMA for BDOS media change check LXI H,FCB ; Point to FCB drive code for directory MOV E,M ; Get the drive code out of the FCB DCR E ; Normalize drive code for select MVI C,SELDSK ; Select the directory drive to retrieve CALL CPM ; The proper allocation vector CALL CKVER ; Check version JC V14 ; Pre-2.x...get parameterss the 1.4 way MVI C,CURDPB ; It is 2.x or MP/M...request DPB CALL BDOS INX H INX H MOV A,M ; Get block shift STA BLKSHF INX H ; Bump to block mask MOV A,M STA BLKMSK ; Get it INX H INX H MOV E,M ; Get maximum block # INX H MOV D,M XCHG SHLD BLKMAX ; Save it XCHG INX H MOV E,M ; Get directory size INX H MOV D,M XCHG JMP FREE ; Let free save it and setup order table ; V14: LHLD BDOS+1 ; Get params 1.4 style MVI L,3BH ; Point to directory size MOV E,M ; Get it MVI D,0 ; Force high order to 0 PUSH D ; Save for later INX H ; Point to block shift MOV A,M ; Fetch STA BLKSHF ; Save INX H ; Point to block mask MOV A,M ; Fetch it STA BLKMSK ; And save it INX H MOV E,M ; Get maximum block number  MVI D,0 XCHG SHLD BLKMAX ; Save it POP H ; Restore directory size JMP FREE20 ; Go figure free space from alloc vector ; ; ; Calculate # of K free on selected drive now so that the FREE figure ; will not reflect either the creation or additions to the DISK.DIR file ; (which we would probably erase or move anyway). ; FREE: SHLD DIRMAX ; Save max # of entries in directory LDA VERFLG ; Check version # CPI 30H ; 3.0? JC FREE20 ; Use old method if not LDA FCB ; Get drive # DCR A MOV E,A ; Use new compute free space BDOS call MVI C,46 CALL CPM MVI C,3 ; Answer is a 24-bit integer ; FRE3L1: LXI H,TBUF+2 ; Answer is in 1st 3 bytes of DMA adr MVI B,3 ; Convert it from records to k ORA A ; By dividing by 8 ; FRE3L2: MOV A,M RAR MOV M,A DCX H DCR B JNZ FRE3L2 ; Loop for 3 bytes DCR C JNZ FRE3L1 ; Shift 3 times LHLD TBUF ; Now get result in k JMP SAVFRE ; Go store it ; FREE20: MVI C,GALLOC ; Get address of allocation vector CALL BDOS XCHG  LHLD BLKMAX ; Get its length INX H LXI B,0 ; Init block count to 0 ; GSPBYT: PUSH D ; Save alloc address LDAX D MVI E,8 ; Set to process 8 blocks ; GSPLUP: RAL ; Test bit JC NOTFRE INX B ; NOTFRE: MOV D,A ; Save bits DCX H ; Count down blocks MOV A,L ORA H JZ ENDALC ; Quit if out of blocks MOV A,D ; Restore bits DCR E ; Count down 8 bits JNZ GSPLUP ; Do another bit POP D ; Bump to next byte.. INX D ; Of alloc. vector JMP GSPBYT ; Process it ; ENDALC: POP D ; Clear allocation vector from stack MOV L,C ; Copy blocks to hl MOV H,B LDA BLKSHF ; Get block shift factor SUI 3 ; Convert from records to k JZ SAVFRE ; Skip shifts if 1k blocks ret in HL ; FREKLP: DAD H ; Multiply blocks by k/block DCR A JNZ FREKLP ; SAVFRE: SHLD FREEBY ; Save the free space for output later ; ; ; Reenter here on subsequent passes while in the all-users mode ; SETTBL: LHLD DIRMAX ; Get directory maximum again INX H ; Directory size is dirmax+1 DAD H ; Double directory size LXI D,ORDER ; To get size of order table DAD D ; Allocate order table SHLD TBLOC ; Name tbl begins where order tbl ends SHLD NEXTT XCHG LHLD BDOS+1 ; Make sure we have room to continue MOV A,E SUB L MOV A,D SBB H JNC OUTMEM CALL CKVER ; Set carry if pre-CP/M 2 LDA NEWUSR ; Get user area for directory MOV E,A MVI C,CURUSR ; Get the user function CNC CPM ; And set new user number if CP/M 2 ; ; ; Look up the FCB in the directory ; MVI A,'?' LXI H,FCB+12 MOV M,A ; Match all extents INX H MOV M,A ; Match all S1 bytes INX H MOV M,A ; Match all S2 bytes LXI H,0 SHLD COUNT ; Initialize match counter SHLD TOTFIL ; " total file counter SHLD TOTSIZ ; " total size counter CALL SETSRC ; Set DMA for directory search MVI C,SEARCH ; Get 'search first' function JMP LOOK ; And go search for 1st match ; ; ; Read more directory entries ; MORDIR: MVI C,NEXT ; Search next ; LOOK: LXI D,FCB CALL CPM ; Read directory entry INR A ; Check for end (0FFH) JZ SPRINT ; If no more, sort & print what we have ; ; ; Point to directory entry ; SOME: DCR A ; Undo previous INR A ANI 3 ; Make modulus 4 ADD A ; Multiply ADD A ; By 32 because ADD A ; Each directory ADD A ; Entry is 32 ADD A ; Bytes long LXI H,TBUF+1 ; Point to buffer (skip to FN/FT) ADD L ; Point to entry ADI 9 ; Point to sys byte MOV L,A ; Save (can't carry to H) LDA QOPFLG ; User want to find only non-$ARC files? ORA A JNZ OSYS INX H ; Yes so get the archive byte back MOV A,M DCX H ORA A ; Check bit 7 for $ARC file JM MORDIR ; If set, ignore this filename ; OSYS: LDA OOPFLG ; User want to find only $SYS files? ORA A JNZ CKSYS MOV A,M ; Get system byte back ORA A ; Check bit 7 for $SYS file JP MORDIR ; If not set, ignore this filename JMP SYSFOK ; Else check for a match ; CKSYS: LDA SOPFLG ; Did user request $SYS files? ORA A JZ SYSFOK ; If yes, exit MOV A,M ; Get system byte back ORA A ; Check bit 7 for $SYS file JM MORDIR ; Skip that file ; SYSFOK: MOV A,L ; Go back now SUI 10 ; Back to user number (allocation flag) MOV L,A ; HL points to entry now LDA NEWUSR ; Get current user CMP M JNZ MORDIR ; Ignore if different INX H ; ; ; Move entry to table ; XCHG ; Entry to DE LHLD NEXTT ; Next table entry to HL MVI B,11 ; Entry length (name, type, extent) ; TMOVE: LDAX D ; Get entry character ; IF NOT USELC ANI 7FH ; Remove attributes ENDIF ; NOT USELC ; MOV M,A ; Store in table INX D INX H DCR B ; More? JNZ TMOVE INX D ; DE->> S1 INX D ; DE->> S2 LDAX D ; Get S2 byte, overflow=int(extents/32) PUSH H ; Save HL MOV L,A ; Set up 16-bit multiply MVI H,0 MVI B,5 CALL SHLL ; Hl is now # of overflow extents DCX D ; DE->> S1 DCX D ; DE->> extent LDAX D ; Get extent ADD L MOV L,A MOV A,H ACI 0 MOV H,A ; HL now has total extents MVI B,7 CALL SHLL ; HL now has total records less last ext INX D ; DE->> S1 INX D ; DE->> S2 INX D ; Point to sector count LDAX D ; Get it ADD L MOV L,A MOV A,H ACI 0 MOV H,A ; HL now has total records XTHL ; Do some fancy shuffling XCHG XTHL XCHG MOV M,D INX H MOV M,E POP D ; All back to normal... INX H SHLD NEXTT ; Save updated table address XCHG LHLD COUNT ; Bump the # of matches made INX H SHLD COUNT LXI H,13 ; Size of next entry DAD D XCHG ; Future NEXTT is in DE LHLD BDOS+1 ; Pick up TPA end MOV A,E SUB L ; Compare NEXTT-TPA end MOV A,D SBB H JC MORDIR ; If TPA end > NEXTT, loop back for more OUTMEM: CALL ERXIT ; Exit if directory too large DB 'Memory',0 ;..... ; ; ; Shift HL left by B bits ; SHLL: DAD H DCR B RZ JMP SHLL ;..... ; ; ; Sort and print ; SPRINT: CALL SETFOP ; Return to file output DMA & user # LHLD COUNT ; Get file name count MOV A,L ORA H ; Any found? JZ PRTOTL ; Exit if no files found PUSH H ; Save file count STA SUPSPC ; Enable leading zero suppression ; ; ; Initialize the order table ; LHLD TBLOC ; Get start of name table XCHG ; Into de LXI H,ORDER ; Point to order table LXI B,13 ; Entry length ; BLDORD: MOV M,E ; Save low order address INX H MOV M,D ; Save high order address INX H XCHG ; Table addr to HL DAD B ; Point to next entry XCHG XTHL ; Save tbl addr, fetch loop counter DCX H ; Count down loop MOV A,L ORA H ; More? XTHL ; (restore table address, save counter) JNZ BLDORD ; Yes, go do another one POP H ; Clean loop counter off stack LHLD COUNT ; Get count SHLD SCOUNT ; Save as # to sort DCX H ; Only 1 entry? MOV A,L ORA H JZ DONE ; Yes, so skip sort ; ; ; This sort routine is adapted from SOFTWARE TOOLS by Kernigan and ; Plaugher. ; SORT: LHLD SCOUNT ; Number of entries ; L0: ORA A ; Clear carry MOV A,H ; GAP=GAP/2 RAR MOV H,A MOV A,L RAR MOV L,A ORA H ; Is it zero? JZ DONE ; Then none left MOV A,L ; Make gap odd ORI 1 MOV L,A SHLD GAP INX H ; I=GAP+1 ; L2: SHLD I XCHG LHLD GAP MOV A,E ; J=I-GAP SUB L MOV L,A MOV A,D SBB H MOV H,A ; L3: SHLD J XCHG LHLD GAP ; JG=J+GAP DAD D SHLD JG MVI A,13 ; Compare 13 chars CALL COMPARE ; Compare (J) and (JG) JP L5 ; If A(J)<=A(JG) LHLD J XCHG LHLD JG CALL SWAP ; Exchange a(J) and a(JG) LHLD J ; J=J-GAP XCHG LHLD GAP MOV A,E SUB L MOV L,A MOV A,D SBB H MOV H,A JM L5 ; If J>0 goto l3 ORA L ; Check for zero JZ L5 JMP L3 ; L5: LHLD SCOUNT ; For later XCHG LHLD I ; I=I+1 INX H MOV A,E ; If I<=n goto l2 SUB L MOV A,D SBB H JP L2 LHLD GAP JMP L0 ;..... ; ; ; Sort is all done - print entries ; DONE: LDA FOPFLG ORA A JNZ NOOUT ; If file output, fall through, A=0 ; ; If all user option enabled, and we're not on the first pass, then the ; output file is already open and positioned, so we can skip the open. ; LXI H,OPNFLG ; Get pointer to output file open flag  CMP M ; A=0,set Z if OPNFLG=0 also JNZ NOOUT ; If OPNFLG not zero, skip open DCR M ; Else, set opnflg for next user # ; First pass on file append - prepare DISK.DIR to receive new or append- ; ed output. ; LXI D,OUTFCB ; Does output file already exist? MVI C,SEARCH CALL CPM INR A JNZ OPENIT ; If it does, open it for processing MVI C,MAKE ; Otherwise, create the output file CALL CPM INR A JNZ NOOUT ; Continue if open successful ; ; ; If make or open fails, declare error ; OPNERR: CALL ERXIT DB 'Open',0 ;..... ; ; WRTERR: CALL ERXIT DB 'Write',0 ;..... ; ; ; Output file already exists - open it and position to the last record ; of the last extent. ; OPENIT: MVI C,OPEN ; Open 1st extent of output file CALL CPM INR A JZ OPNERR ; Bad deal if 1st won't open ; OPNMOR: LDA OUTFCB+15 CPI 128 JC LSTEXT ; If RC<128, this is last extent LXI H,OUTFCB+12 INR M ; Else, bump to next extent MVI C,OPEN ; And try to open it CALL CPM INR A JNZ OPNMOR ; Continue opening extents til no more DCR M ; Then, reopen preceding extent MVI C,OPEN CALL CPM LDA OUTFCB+15 ; Get RC for the last extent ; ; ; At this point, OUTFCB is opened to the last extent of the file, so ; read in the last record in the last extent. ; LSTEXT: ORA A ; Is this extent empty? JZ NOOUT ; If so, then starting a clean slate DCR A ; Normalize record count STA OUTFCB+32 ; Set record number to read MVI C,READ ; And read last record of file CALL CPM ORA A ; Was read successful? JZ RDOK ; If so, proceed to scan for eof mark ; APERR: CALL ERXIT DB 'Append',0 ;..... ; ; ; We now have the last record in the file in our buffer. Scan the last ; record for the EOF mark, indicating where we can start adding data. ; RDOK: LXI H,OUTBUF ; Point to start of output buffer MVI B,128 ; Get length of output buffer ; SCAN: MOV A,M CPI 'Z'-40H ; Have we found end of file? JZ RESCR ; If so, save pointers and reset cr INX H DCR B JNZ SCAN ; Otherwise, look until end of buffer ; ; ; If we find an explicit EOF mark in the last buffer (or an implied EOF ; if the last record is full), move the FCB record and extent pointers ; back to correct for the read operation so that our first write opera- ; tion will effectively replace the last record of the DISK.DIR file. ; RESCR: PUSH H ; Save EOF buffer pointer PUSH B ; Save EOF buffer remaining LXI H,OUTFCB+32 ; Get current record again DCR M ; Dock it JP SAMEXT ; If CR>=0, we're still in same extent LXI H,OUTFCB+12 ; Else, move to previous extent DCR M MVI C,OPEN ; Then, reopen the previous extent CALL CPM INR A JZ APERR ; Append position error if can't reopen LDA OUTFCB+15 ; Else, put to last record of extent DCR A STA OUTFCB+32 ; SAMEXT: POP PSW ; Recall where EOF is in buffer STA BUFCNT ; And set buffer counter POP H ; Recall next buffer pointer SHLD BUFPNT ; And set pointer for first addition ; NOOUT: LDA FIRSTT ; Time through ORA A JNZ NOVOPT ; No, we've been here before MVI A,0FFH ; Virgin, poke it STA FIRSTT LDA VOPFLG ORA A ; If version display flag set, print it JNZ NOVOPT ; It's not LXI D,VERNAME CALL PRINT CALL CRLF ; NOVOPT: LHLD COUNT SHLD LCOUNT LXI H,0 SHLD LBTOTL SHLD LMTOTL LXI H,ORDER ; Initialize order table pointer SHLD NEXTL SHLD NEXTT ; IF VCODE LHLD COUNT ; Code computes end of name CALL MULT13 ; Table (or start of second table XCHG ; where files will be stored after LHLD TBLOC ; redundant extents removed.) DAD D SHLD NEWPTR ; Save it twice SHLD XPOINT ; For later ENDIF ; VCODE ; IF NOT VCODE JMP NEWLIN ; Start new line and output the files ENDIF ; NOT VCODE ; ; ; Output the directory files we've matched ; ENTRY: LHLD COUNT DCX H ; Dock file count SHLD COUNT MOV A,H ; Is this the last file? ORA L JZ OKPRNT ; If count=0, last file so skip compare ; ; ; Compare each entry to make sure that it isn't part of a multiple ex- ; tent file. Go only when we have the last extent of the file. ; PUSH B ; Save NPL ; IF NOT VCODE CALL CKABRT ; Check for abort code from keyboard ENDIF ; NOT VCODE ; LHLD NEXTT MVI A,11 CALL COMPR ; Does this entry match next one? POP B ; Recall NPL JNZ OKPRNT ; No, print it INX H INX H ; Skip since highest extent last in list SHLD NEXTT JMP ENTRY ; Loop back for next lowest extent ; ; ; Vcode substitution . If VCODE option chosen, OKPRINT moves unique ; filenames and sizes in 'k' to a second table above the first for use ; later. ; OKPRNT: LHLD NEXTT ; Get order table pointer MOV E,M ; Get low order address INX H MOV D,M ; Get high order address INX H SHLD NEXTT ; Save updated table pointer XCHG ; Table entry to HL ; IF VCODE PUSH H ; Save address of byte to be moved LHLD NEWPTR ; Get address in new table to put it in PUSH H ; Save it LXI D,13 ; Update it DAD D SHLD NEWPTR ; Save for later - will be end of table POP H ; Get current move to address XCHG ; Put in DE POP H ; Get current move from address back MVI B,11 ; Size of file name, type CALL MOVE ; Move it PUSH D ENDIF ; VCODE ; IF NOT VCODE MVI B,8 ; File name length CALL TYPEIT ; Type filename MVI A,'.' ; Period after filename CALL TYPE MVI B,3 ; Display 3 characters of filetype CALL TYPEIT ENDIF ; NOT VCODE ; CALL DOIT LHLD TOTSIZ ; De now has rounded size in k DAD D ; Add to total used SHLD TOTSIZ LHLD TOTFIL ; Increment file count INX H SHLD TOTFIL XCHG ; Get back file size ; IF VCODE POP D ; Get back where size is to go MOV A,H ; Move size to table two STAX D INX D MOV A,L STAX D ; ; ; One file MOVED - test to see if we have to move another one. ; LHLD COUNT ; Get current file counter and test it MOV A,H ORA L JZ PRTOTL ; To summary output if no more files JMP ENTRY ; If more, go get them ENDIF ; VCODE ; ; ; Output the size of the individual file ; IF NOT VCODE CALL FDECPRT ; Go print it MVI A,'k' ; And follow with k size CALL TYPE ; ; ; One file output - test to see if we have to output another one. ; LHLD COUNT ; Get current file counter and test it MOV A,H ORA L JZ PRTOTL ; To summary output if no more files ; ; ; At least one more file to output - can we put it on the current line? ; DCR C PUSH PSW CNZ FENCE ; If room left output the fence char. POP PSW JNZ ENTRY ; And go output another file ; ; ; Current line full, start a new one ; NEWLIN: LDA MNPL MOV C,A ; Reset names per line counter CALL CRLF ; Space down to next line ENDIF ; NOT VCODE ; IF PRDI AND (NOT VCODE) LDA FCB ; Precede new line with drive name ADI 'A'-1 CALL TYPE ENDIF ; PRDI AND (NOT VCODE) ; IF PRDI AND (NOT VCODE) AND PRUS ; ; If reporting user # and running under CALL CKVER ; Cp/m 2, output the user number too CNC TYPUSR ENDIF ; PRDI AND (etc.) ; IF PRDI AND (NOT VCODE) MVI A,':' ; Tag header with a colon and a space CALL FPAD ; And exit back to entry ENDIF ; PRDI AND (NOT VCODE) ; IF NOT VCODE JMP ENTRY ; Go back and output another file ENDIF ; NOT VCODE ; ; ; Compute the size of the file/library and update our summary datum. ; This has been changed into a subroutine so that both the file size ; computation and a library size (when printing out library members) ; can be computed in K. ; DOIT: MOV D,M INX H MOV E,M ; Size in DE (records) LDA BLKMSK PUSH PSW ADD E MOV E,A MOV A,D ACI 0 MOV D,A POP PSW CMA ANA E MOV E,A MVI B,3 ; SHRR: MOV A,D ORA A RAR MOV D,A MOV A,E RAR MOV E,A DCR B JNZ SHRR RET ;..... ; ; ; Print HL in decimal with leading zero suppression ; FDECPRT: IF KTHREE ; Individual file size print XRA A ; Clear leading zero flag STA LZFLG JMP SKTHSD ENDIF ; KTHREE ; DECPRT: XRA A ; Clear leading zero flag STA LZFLG LXI D,-10000 LDA SUPSPC PUSH PSW XRA A STA SUPSPC CALL DIGIT  POP PSW STA SUPSPC LXI D,-1000 ; Print 1000's digit CALL DIGIT ; SKTHSD: LXI D,-100 ; Etc. CALL DIGIT LXI D,-10 CALL DIGIT MVI A,'0' ; Get 1's digit ADD L JMP TYPE ; DIGIT: MVI B,'0' ; Start off with ASCII 0 ; DIGLP: PUSH H ; Save current remainder DAD D ; Subtract JNC DIGEX ; Quit on overflow POP PSW ; Throw away remainder INR B ; Bump digit JMP DIGLP ; Loop back ; DIGEX: POP H ; Restore pointer MOV A,B CPI '0' ; Zero digit? JNZ DIGNZ ; No, type it LDA LZFLG ; Leading zero? ORA A MVI A,'0' JNZ TYPE ; Print digit LDA SUPSPC ; Get space suppression flag ORA A ; See if printing file totals RZ ; Yes, don't give leading spaces JMP SPACE ; Leading zero...print space ; DIGNZ: STA LZFLG ; Leading zero flag so next zero prints JMP TYPE ; And print digit ;..... ; ; ;----------------------------------------------------------------------- ; VCODE subroutines begin here ; ;Multiply contents of HL register by 13 ; IF VCODE  MULT13: MOV D,H MOV E,L DAD H DAD D DAD H DAD H DAD D RET ;..... ; ; ; Main subroutine to print out a filename and column delimiter ; SUBA: CALL PFILE1 ; Routine to print a filename RZ ; If at end of line return with zero set CC FENCE ; Print column delimiter if more LHLD JUMPER ; Put the jumper back in de XCHG ORI 1 ; Insure non zero return RET ;..... ; ; PFILE1: MOV A,M ; Let's see what we have CPI 0FEH RNC ANI 7FH ; Strip parity bit PUSH B ; Save the number of columns MVI B,8 ; Print file name and type CALL TYPEIT MVI A,'.' CALL TYPE MVI B,3 CALL TYPEIT PUSH H CALL CKABRT ; Ctl-c from keyboard? POP H MOV D,M ; Get it into INX H MOV E,M XCHG ; Hl CALL FDECPRT ; And print it out MVI A,'k' CALL TYPE POP B ; Get back number of columns LHLD TOTFIL ; Get number of files left DCX H ; Reduce it by one SHLD TOTFIL ; And resave it MOV A,H ORA L ; Down to zero yet? RZ ; Return if no more files DCR C ; Decrement it and STC ; Force carry on this return RET ENDIF ; VCODE ; ; end of VCODE routines ;----------------------------------------------------------------------- ; ; Show total space and files used ; PRTOTL: IF NOT VCODE LDA LOPFLG ORA A JNZ PRTOT1 LHLD TOTFIL ; How many files did we match? MOV A,H ORA L CNZ PRTLMEM ; Skip the .lbr check if none found ; PRTOT1: ENDIF ; NOT VCODE ; XRA A ; Get a zero to... STA SUPSPC ; Suppress leading spaces in totals LHLD TOTFIL ; How many files did we match? MOV A,H ORA L JZ NXTUSR ; Skip the summary if we didn't find any PUSH H ; Save TOTFIL STA FNDFLG ; Set file found flag ; IF VCODE ; Leading crlf for vertical output mode LDA FIRSTT ; If not first time through ORA A CNZ CRLF ENDIF ; VCOEE ; LXI D,TOTMS1 ; Print CRLF " Drive " CALL PRINT ; IF USELC LDA ULON ; Turn on underline or whatever on ORA A ; local console CNZ UNLON ENDIF ; USELC ; SKPUL1: LXI D,TOTMS2 CALL PRINT LDA FCB ADI 'A'-1 CALL TYPE ; Output the drive code CALL CKVER JC NOUSER CALL TYPUSR ; Output the user number ; NOUSER: LXI D,TOTMS6 ; Print " Files: " CALL PRINT POP H ; Recall TOTFIL CALL DECPRT ; Print number of files matched PUSH PSW ; Just in case LDA MNPL ; Load a with # of names per line CPI 3 ; Is it 3? JZ SKDRV ; Yes then skip cr,lf print CPI 4 ; Is it 4? JZ SKDRV ; Yes then skip CRLF, print LXI D,TOTMS3 ; Split drive status line for 40 CALL PRINT ; Do it ; SKDRV: POP PSW ; Put it back LXI D,TOTMS4 ; No CRLF needed since display > 40 CALL PRINT LHLD TOTSIZ ; Print total k used by files matched CALL DECPRT LXI D,TOTMS5 ; Print "K " CALL PRINT CALL PRTFRE ; Output free space remaining ; IF USELC LDA ULON ORA A CNZ UNLOFF ENDIF ; ; ; Summary line printed, now print the detail files, but first compute ; total lines the printout will take. ; IF VCODE NPRNT: PUSH PSW ; Just in case LDA MNPL ; Load a with # names per line CPI 1 ; Is it 1? JNZ MNC1 ; If not test for 2 LXI D,0-1 ; Minus number of columns LXI B,1-1 ; Number of columns minus 1 ; MNC1: CPI 2 ; Wasn't 1, is it 2? JNZ MNC2 ; If not then test for 3 LXI D,0-2 ; Minus number of columns LXI B,2-1 ; Number of columns minus 1 ; MNC2: CPI 3 ; Wasn't 2, is it 3? JNZ MNC3 ; If not then test for 4 LXI D,0-3 ; Minus number of columns LXI B,3-1 ; Number of columns minus 1 ; MNC3: CPI 4 ; Wasn't 3, is it 4? JNZ MNC4 ; If not then fall through LXI D,0-4 ; Minus number of columns LXI B,4-1 ; Number of columns minus 1 ; MNC4: POP PSW ; Put it back LHLD TOTFIL ; Get total number of files DAD B ; Round up to a full line MVI C,0FFH ; NPRNT1: INR C ; 'c' will end up holding number DAD D ; Of lines to be displayed. JC NPRNT1 MOV A,C STA LINES ; Done, save it for later STA SUPSPC ; Allow spaces in front of file sizes ; ; ; Number of lines times size of an entry equals the number of bytes to ; jump in the second table when outputing files in vertical order. ; MOV L,A ; Put number of lines into HL MVI H,0 CALL MULT13 SHLD JUMPER ; Put it away ; ; ; Fill a record with FF at the end of table 2 ; LHLD NEWPTR ; Now points to end of table 2 MVI B,128 MVI A,0FFH ; NPRNT2: MOV M,A INX H DCR B JNZ NPRNT2 ; ; ; Increment the number of files for use later in SUBA. This insures ; that a column delimiter will be printed after the last filename, if ; the file appears in other than the last column of the display. ; LXI H,TOTFIL INR M ; ; ; Print out a line of files ; NPRNT3: CALL CRLF ; Start a new line PUSH PSW ; Save it just in case LDA MNPL ; Load a with # of names per line MOV C,A ; Reset number of columns POP PSW ; Put it back ENDIF ; VCODE ; IF PRDI AND VCODE PUSH B LDA FCB ; Show drive letter at beginning of ADI 'A'-1 ; Each line CALL TYPE ENDIF ; PRDI AND VCODE ; IF PRUS AND PRDI AND VCODE CALL CKVER CNC TYPUSR ENDIF ; PRUS AND PRDI AND VCODE ; IF PRDI AND VCODE MVI A,':' CALL FPAD POP B ENDIF ; PRDI AND VCODE ; ; ; Print first filename ; IF VCODE LHLD XPOINT ; XPOINT points to start of second table CALL SUBA ; at entry. Below, it is incremented ; for additional lines of printout. JZ NLINE ; Either out of columns or out of files ; ; ; Print second filename ; LHLD XPOINT DAD D CALL SUBA JZ NLINE ; ; ; NOTE: The following conditionals are used only to save some bytes if ; running with only two or three columns of files in display. ; ; Print third filename, if still room on line ; PUSH PSW ; Just in case LDA MNPL ; Load a with # of names per line CPI 1 ; Is it 1? JZ VCLT2 ; If so then skip name print CPI 2 ; Is it 2? JZ VCLT2 ; If so then skip name print POP PSW ; Put it back where it belongs LHLD XPOINT DAD D DAD D CALL SUBA JZ NLINE JMP VCMT2 ; VCLT2: POP PSW ; Didn't put it back so do it now ; ; ; Print fourth filename ; VCMT2: PUSH PSW ; Just in case it's loaded bang! LDA MNPL ; Load A with # of names per line CPI 4 ; Is it 4? JNZ VCLT3 ; If not then skip fourth name print POP PSW ; Put it back LHLD XPOINT DAD D DAD D DAD D CALL SUBA JMP VCMT3 ; VCLT3: POP PSW ; Didn't put it back yet so do it now ; VCMT3: DS 0 ; ; Wasn't 4 so go NLINE: LHLD XPOINT ; Increment xpoint to next file LXI D,13 DAD D SHLD XPOINT LHLD TOTFIL ; Time to see if we're out of files MOV A,H ORA L JZ DOLIB ; Yes we are LXI H,LINES ; Nope, just need a new line DCR M JNZ NPRNT3 ENDIF ; VCODE ; DOLIB: IF VCODE LDA LOPFLG ORA A JNZ DOLIB1 LHLD TOTFIL ; How many files did we match? MOV A,H ORA L CNZ PRTLMEM ; Skip the library check if none found ; DOLIB1: ENDIF ; VCODE ; ; ; Directory for one user area completed. If 'all users' option is se- ; lected, then go do another directory on the next user number until we ; exceed the maximum user # for the selected drive. ; NXTUSR: LDA AOPFLG ; If not all users mode - skip next ORA A JNZ GOCLZ CALL CKVER ; Are we running CP/M 2? JC GOCLZ ; Skip user increment if not CALL CKABRT ; Check for user abort first LDA MAXUSR ; No abort - get maximum user number LXI H,NEWUSR ; Bump directory user number INR M CMP M ; Does next user # exceed maximum? JNC SETTBL ; Continue if more user areas to go LDA BASUSR ; Reset base user number for the MOV M,A ; Next directory search ; ; ; We've finished all of our outputting. Flush the remainder of the out- ; put buffer and close the file before going to exit routine. ; GOCLZ: LXI H,OPNFLG ; Get file open status and reset flag to MOV A,M ; force reopen on next pass MVI M,0 ORA A JZ NXTDSK ; Skip closing DISK.DIR if not open LXI H,BUFCNT MOV A,M ; Retrieve # of unflushed characters in MVI M,128 ; Buffer, force BUFCNT to empty status ORA A ; If BUFCNT=128, buffer empty set sign JM CLOSE ; Close DISK.DIR if buffer is empty JZ FLUSH ; Write last record to DISK.DIR if full LHLD BUFPNT ; Else pad unused buffer with CTL-Z ; PUTAGN: MVI M,'Z'-40H INX H DCR A JNZ PUTAGN ; Keep padding until buffer filled out ; FLUSH: LXI D,OUTFCB ; Flush the last output buffer MVI C,WRITE CALL CPM ORA A JNZ WRTERR ; CLOZE: LXI D,OUTFCB ; Close the output file MVI C,CLOSE CALL CPM ; ; ; Directory for all user areas completed. If the multi-disk option is ; enabled and selected, reset to the base user area and repeat the di- ; rectory for next drive on-line until we either exceed the drives in ; our LODRV-HIDRV table, or the BDOS shuts us down with a select or bad ; record error, which will be intercepted back to the EXIT module. ; NXTDSK: LXI H,FNDFLG ; Get file found flag MOV A,M MVI M,0 ; Clear file found flag for next drive ORA A JNZ NDSK ; Continue if at least 1 file found LXI H,FOPFLG DCR M PUSH H LXI D,NOFMS1 ; Print first part of no files message CALL PRINT ; Print it LDA MNPL ; Load a with # of names per line CPI 4 ; Is it 4? JZ LNOFM ; If so then jump to long message print CPI 3 ; Is it 3? JZ LNOFM ; If so then jump to long message print LXI D,NOFSM ; Isn't 3 or 4 so set up short message CALL PRINT ; Print it JMP NNOFM ; Skip long message print IF MAXCL ; If MAXCL then print short message ; LNOFM: LXI D,NOFSM ; as RCPM's won't want to print it ENDIF ; MAXCL ; IF NOT MAXCL ; Not MAXCL so long message is defined LNOFM: LXI D,NOFLM ENDIF ; NOT MAXCL ; CALL PRINT ; Print message ; NNOFM: LDA FCB ADI 'A'-1 CALL TYPE ; Output the drive CALL CKVER JC NOUSR1 CALL TYPUSR ; Output the user number ; NOUSR1: LXI D,NOFMS2 ; Print divider CALL PRINT CALL PRTFRE ; Tag with free message ; IF NOT VCODE CALL CRLF ; Need extra CRLF in horiz. output mode ENDIF ; NOT VCODE ; POP H INR M ; NDSK: LDA DOPFLG ; If multi-disk not selected - skip next ORA A JNZ NPRT CALL CKABRT ; Check for user abort first MVI A,HIDRV-LODRV ; Get maximum drive code to search LXI H,FCB ; Bump directory FCB drive code INR M CMP M ; Does next disk exceed maximum? JC NPRT ; IF MAXDR LDA MAXD ; Look at another value limit INR A CMP M ; Is it lower? JC NPRT ; Bail out if too low JMP NOOPT ; Search next disk ENDIF ; MAXDR ; JNC NOOPT ; Search next disk if maxdr not true ; ; ; If no printer, fall through to EXIT ; NPRT: LDA POPFLG ORA A ; Printer active? JNZ EXIT ; No, just exit... MVI C,5 MVI E,CR ; Print a CRLF CALL CPM MVI E,LF ; Line feed CALL CPM JMP EXIT ; All done - exit to CCP ;..... ; ; ; Print the user number of the directory in decimal ; TYPUSR: LDA NEWUSR CPI 10 ; If user no. < 10, skip tens digit JC DUX PUSH B MVI C,'0'-1 ; DUY: INR C ; Get tens digit SUI 10 JNC DUY ; Loop until we've gone too far ADI 10 MOV B,A ; Save units digit MOV A,C ; Print tens digit CALL TYPE MOV A,B ; Get units back POP B ; DUX: ADI '0' JMP TYPE ;..... ;  ; ; Force new line on video and check for page pause ; CRLF: MVI A,CR ; Send CR CALL TYPE MVI A,LF ; Send LF JMP TYPE ;..... ; ; ; Separate the directory output on a line with a space, the delimiter, ; followed by another space. ; FENCE: CALL SPACE LDA FENC ; Fence character ; FPAD: CALL TYPE ; Print it, fall into space ; SPACE: MVI A,' ' ; Fall through to type ; ; ; Output character in A to console, and optionally to printer and/or the ; output file. ; TYPE: PUSH B PUSH D PUSH H PUSH PSW ; Save the character to output CALL TYPE1 ; Send it to console CALL CKABRT ; Check for user abort request POP PSW ; Restore the output character ANI 7FH ; Strip parity bit on character ; ; ; Test file output mode and skip to page pause test if not active. ; MOV B,A ; Save stripped character to B LDA FOPFLG ; Is file output active? ORA A JNZ NOWRIT ; Go check for page pause if not ; ; ; File output mode active - make sure we have room in buffer to add the  ; next character. If buffer full, write out current record first and ; then start a new record with current character. ; LHLD BUFPNT ; Get current buffer pointer LDA BUFCNT ; Get buffer capacity remaining ORA A JNZ PUTBUF ; Continue if buffer not full CALL SETFOP ; Set the DMA address LXI D,OUTFCB ; Else write the current buffer out MVI C,WRITE CALL CPM ; (note call must save character in B) ORA A JNZ WRTERR ; Write error exit if disk full or R/O LXI H,OUTBUF ; Reset buffer pointer MVI A,128 ; Reset buffer capacity ; PUTBUF: MOV M,B ; Shove char. to next buffer position INX H ; Bump buffer pointer SHLD BUFPNT ; And save it DCR A ; Dock count of chars. left in buffer STA BUFCNT ; And save it ; NOWRIT: MOV A,B ; Recall stripped character ANI 7FH ; Strip parity bit on character MOV E,A ; Setup list output call MVI C,5 LDA POPFLG ; Test printer flag ORA A CZ CPM ; Print character if flag true MOV A,E ; Recall character ; IF PGPAWS CPI LF ; Do we have a line feed? JNZ TYPRET ; Exit if not LDA NOPFLG ; Is the page pause function disabled? ORA A JZ TYPRET ; Exit if so LDA POPFLG ; Check for printer option ORA A JZ TYPRET ; If enabled, skip page pause LDA LINCNT ; Get line count INR A ; Bump it LXI H,MLPS CMP M ; Are we at the end of the screen? JC NOTEOS ; Skip if not LXI D,EOSMSG ; Else, display pause message MVI C,PRINTS ; Without checking for lfs CALL BDOS CALL CINPUT ; Wait for character CPI 'C'-40H ; Want to abort? JZ EXIT1 ; Abort on CTL-C LXI D,MORERA ; Overwrite the [more] display MVI C,PRINTS CALL BDOS XRA A ; Reset line count ; NOTEOS: STA LINCNT ; Save new line count ENDIF ; PGPAWS ; TYPRET: POP H ; Exit from type POP D POP B RET ;..... ; ; ; Output character ; TYPE1: IF USELC ORA A ; Check for attributes not set JP TYPE2 ANI 7FH ; Strip off the attribute bit now MOV E,A ; Save while we find out how to display LDA RVON ; See if highlight video enabled ORA A ; 0 -> use lower case MOV A,E ; Restore character JNZ TYPERV CPI 'A' ; Change only from A-Z JC TYPE2 CPI 'Z'+1 JNC TYPE2 ; Punctuation can change so leave it ORI 20H ; If attribute, make lower case ENDIF ; USELC ; TYPE2: MOV E,A ; Get character into BDOS entry register MVI C,WRCHR JMP BDOS ; Call conout via the BDOS ; IF USELC TYPERV: PUSH PSW ; Save character while we turn on RV CALL REVON ; Switch to reverse video POP PSW CALL TYPE2 ; Output the character now ; ; Return to normal video ; ; Routines to turn on/off highlight video ; REVOFF: LXI H,RVOFF JMP BLTYPE ; UNLON: LXI H,ULON JMP BLTYPE ; UNLOFF: LXI H,ULOFF JMP BLTYPE ; REVON: LXI H,RVON ; BLTYPE: MOV B,M INX H LDA BYEACT ; Check for BYE5 active. If so then ORA A ; turn on RV for local console only JNZ TYPEIT ; No BYE5 - use normal routine for RV ; ; ; Print a string at HL of length B on local console only ; B5TYPE: MOV A,M CALL LOCTYP INX H  DCR B JNZ B5TYPE RET ;..... ; ; LOCTYP: PUSH H PUSH D PUSH B MOV E,A MVI C,68 CALL CPM POP B POP D POP H RET ENDIF ; USELC ;..... ; ; ; Print a string at HL of length B ; TYPEIT: MOV A,M CALL TYPE INX H DCR B JNZ TYPEIT RET ;..... ; ; ; Print string on the console ; PRINT: LDAX D ; Get the character from the DE string ANI 7FH ; Strip off any parity ORA A ; See if it is a 0 RZ ; Terminates with a 0 character CALL TYPE ; Show the character on the console INX D ; Next string position JMP PRINT ; Go do another ;..... ; ; ; Fetch character from console (without echo) ; CINPUT: LHLD 0000H+1 MVI L,9 CALL GOHL ANI 7FH ; Strip off any parity RET ;..... ; ; ; Check for a CTL-C or CTL-S entered from the keyboard. Jump to EXIT ; if CTL-C, pause on CTL-S. ; CKABRT: LHLD 000H+1 MVI L,6 ; Check status of keyboard CALL GOHL ; Any key pressed? ORA A RZ ; No, return to caller CALL CINPUT ; Get character CPI 'C'-40H ; CTL-C? JZ EX0 ; If yes, quit CPI 'S'-40H ; CTL-S? RNZ ; No, return to caller CALL CINPUT ; Yes, wait for another char. CPI 'C'-40H ; Might be CTL-C JZ EX0 ; If yes, fall through and continue RET ;..... ; ; ;Routine to do disk reset if D option entered on command line ; DSET: MVI C,RESET CALL CPM RET ;..... ; ; ;Kludge to allow call to address in HL ; GOHL: PCHL ;..... ; ; ; Entry to BDOS saving all extended registers ; CPM: PUSH B PUSH D PUSH H LDA ZRDFLG ; ZRDOS running? ORA A JNZ ZRD ; ZRDOS error trap and DOSs call CALL BDOS MOV B,A ; Save return code LDA VERFLG ; Is this 3.0? CPI 30H MOV A,B JC CPM20 ; No, exit normally CPI 0FFH ; It is 3.0 - was return code ff? JNZ CPM20 ; No, exit normally MOV A,H ; 3.0 and A=FF - check for error code ORA A JNZ DSKERR ; Trap out if we got a physical error MOV A,B ; Else continue normally ; CPM20: POP H POP D POP B RET ;..... ; ; ; ZRDOS Error Trap and System Call exits to CPM20 ; ZRD: CALL SETTRAP ; Set the warm boot trap CALL BDOS ; Do what we're told CALL RESTRAP ; Reset the trap JMP CPM20 ; Error free exit ;..... ; ; ; Set Warm Boot Trap in ZRDOS ; SETTRAP:PUSH H PUSH D PUSH B MVI C,SETWBT ; Set warm boot trap to come here LXI D,WBTRAP CALL BDOS POP B POP D POP H RET ;..... ; ; ; WBTRAP is where the ZRDOS returns control on warm boot (error) ; WBTRAP: LXI H,DSKERR ; Return here after reseeting the trap PUSH H ; Save DSKERR on stack ; ; ; Reset Warm Boot Trap in ZRDOS ; RESTRAP:PUSH H PUSH D PUSH B PUSH PSW MVI C,RESWBT ; Reset warm boot trap CALL BDOS POP PSW POP B POP D POP H RET ;..... ; ; ; For file output mode, return to old user area and set DMA for the file ; output buffer. ; SETFOP: CALL CKVER ; Clear carry if CP/M 2 or later LDA OLDUSR ; Get user number at startup MOV E,A MVI C,CURUSR CNC CPM ; Reset the old user number if CP/M 2 LXI D,OUTBUF ; Move DMS from search buffer into the JMP SET2 ; Output buffer RET ;..... ; ; ; Move disk buffer DMA to default buffer for directory search operations ; and BDOS media change routines (necessary for pre-CP/M 2 systems while ; in file output mode with an active buffer). ; SETSRC: LXI D,TBUF ; SET2: MVI C,SETDMA JMP CPM ;..... ; ; ; Print the amount of free space remaining on the selected drive ; PRTFRE: LXI D,TOTMS7 ; Print " ( " CALL PRINT LHLD FREEBY CALL DECPRT ; Print k free LXI D,TOTMS8 ; Print "k free) " JMP PRINT ;..... ; ; ; Show string on the console ; SHOW: LDAX D ; Get the character from the de string ANI 7FH ; Strip off any parity ORA A ; See if it is a 0 RZ ; Terminates with a 0 character PUSH B PUSH D PUSH H CALL TYPE2 ; Show the character on the console POP H POP D POP B INX D ; Next string position JMP SHOW ; Go do another ;..... ; ; ; Compare routine for sort COMPR: PUSH H ; Save table address MOV E,M ; Load low order INX H MOV D,M ; Load high order INX H MOV C,M INX H MOV B,M ; ; ; BC, DE now point to entries to be compared ; XCHG MOV E,A ; Get count ; CMPLP: MOV A,M ANI 7FH MOV D,A LDAX B ANI 7FH CMP D INX H INX B JNZ NOTEQL ; Quit on mismatch DCR E ; Or end of count JNZ CMPLP ; NOTEQL: POP H RET ; Conditional code tells all ;..... ; ; ; Swap entries in the order table ; SWAP: LXI B,ORDER-2 ; Table base DAD H ; *2 DAD B ; + base XCHG DAD H ; *2 DAD B ; + base MOV C,M LDAX D XCHG MOV M,C STAX D INX H INX D MOV C,M LDAX D XCHG MOV M,C STAX D RET ;..... ; ; ; New compare routine ; COMPARE:LXI B,ORDER-2 DAD H DAD B XCHG DAD H DAD B XCHG MOV C,M INX H MOV B,M XCHG MOV E,M INX H MOV D,M XCHG MOV E,A ; Count ; CMPLPE: MOV A,M ANI 7FH MOV D,A LDAX B ANI 7FH CMP D INX B INX H RNZ DCR E JNZ CMPLPE RET ;..... ; ; ; Error exit ; ERXIT: MVI A,0FFH STA FOPFLG ; Disable file output mode on error CALL CRLF ; Space down POP D ; Get pointer to message string CALL PRINT ; Print it LXI D,ERRMS1 ; Print " Error" CALL PRINT CALL CRLF ; Space down ; ; ; Exit - all done, restore stack ; EXIT: LDA DOPFLG ; If multi-disk not selected - skip next ORA A JNZ EX0 CALL CKABRT ; Check for user abort first MVI A,HIDRV-LODRV ; Get maximum drive code to search LXI H,FCB ; Bump directory FCB drive code INR M CMP M ; Does next disk exceed maximum? JC EX0 ; IF MAXDR LDA MAXD ; Look at another value limit INR A CMP M ; Is it lower? JC EX0 ; Bail out if too low JMP NOOPT ; Search next disk ENDIF ; MAXDR ; JNC NOOPT ; Search next disk if maxdr not true ; EX0: IF VCODE CALL CRLF ; Turn up a blank line at end ENDIF ; VCODE ; MVI C,CONST ; Check console status CALL CPM ORA A ; Character waiting? MVI C,RDCHR CNZ CPM ; Gobble up character LDA ZRDFLG ; ZRDOS running? ORA A JNZ EXIT2 ; Yes LDA VERFLG ; Or error mode, depending on version CPI 30H JC EXIT1 MVI C,2DH MVI E,0 ; Set error mode back to default CALL CPM JMP EXIT2 ; EXIT1: LDA DOPFLG ; If they were swapped ORA A CZ SWAPEM ; EXIT2: LHLD STACK ; Get old stack pointer SPHL ; Move back to old stack RET ; And return to CCP ;..... ; ; ; Trap BDOS select and sector error vectors to our own intercept routine ; so we can catch a reference to an illegal drive. ; SWAPEM: LDA ZRDFLG ; See if ZRDOS running ORA A RNZ ; Yes, quit this LDA VERFLG ; Check version CPI 30H ; See if error mode call is available JC SWAP20 ; If not, use BDOS error vectors MVI C,2DH MVI E,0FFH ; Use set error mode call CALL CPM ; Set "return code only" mode RET ; SWAP20: LHLD BDOS+1 ; Get pointer to base of BDOS INX H ; Swap in the new pointer if running a MOV E,M ; Program below the CCP INX H MOV D,M XCHG ; Now HL points to the proper vector MVI L,9 ; Point to record error vector LXI D,VECTBL ; Exchanging with our own vector table MVI A,4 ; 4 bytes to swap ; SWAPLP: MOV B,M ; Get byte from HL XCHG MOV C,M ; Get byte from DE MOV M,B ; Put byte from HL XCHG MOV M,C ; Put byte from DE INX H ; Bump exchange pointers INX D DCR A ; Dock counter JNZ SWAPLP ; Continue swapping til done RET ;..... ; ; ; Check CP/M version number. Return carry flag set if pre-CP/M 2. If ; CP/M 2 or later or MP/M (any version), return carry clear. ; CKVER: LDA VERFLG CPI 20H RET ;..... ; ; ; Recovery point from intercepted BDOS select and bad record errors ; DSKERR: LXI SP,STACK ; Get out of BDOS' stack JMP EXIT ; And exit back to CCP ;..... ; ; ;----------------------------------------------------------------------- ; start of FNAME routine ; ; Main module ; on entry, DE points to FCB to be filled and HL points to first ; bytre of target string, RFCB is 36 bytes long ; on exit, B=disk number (1 for A, etc.) and C=user number ; HL points to terminating character ; A=0 and Z set if error in disk or user numbers ; A=0FFH and NZ if ok ; MAXDISK EQU 16 ; Maximum number of disks MAXUSER EQU 31 ; Maximum user number ; FNAME: PUSH D ; Save DE MVI A,0FFH ; Set default disk and user STA DISK STA USER MVI B,36 ; Initialize FCB PUSH D ; Save pointer XRA A ; A=0 ; FNINI: STAX D ; Store zero INX D ; Point to next DCR B ; Count down JNZ FNINI POP D ; Get pointer back ; ; ; Scan for colon in string ; PUSH H ; Save pointer ; COLON: MOV A,M ; Scan for a colon or space INX H ; Point to next CPI ':' ; Colon found? JZ COLON1 CPI ',' ; Comma found? JC GETF1 CPI '[' JZ GETF1 CPI ' '+1 ; Delimiter? JZ GETF1 JMP COLON ; Continue if not end of line ; COLON1: POP H ; Clear stack MOV A,M ; Save possible drive specification CALL CAPS ; Capitalize CPI 'A' ; Digit if less than 'A' JC USERCK ; Process user number SUI 'A' ; Convert to 0-31 CPI MAXDISK ; Within bounds? JC SVDISK ; ERREXIT:XRA A ; Error indicator POP D ; Restore 'DE' RET ;..... ; ; ; Log in specified disk ; SVDISK: INR A ; Adjust to 1 for 'a' STA DISK ; Save flag INX H ; Point to next character ; ; ; Check for user ; USERCK: MOV A,M ; Get possible user number CPI ':' ; No user number JZ GETFILE CPI '?' ; All user numbers? JNZ USERC1 STA USER ; Set value INX H ; Point to after MOV A,M ; Must be colon CPI ':' JZ GETFILE JMP ERREXIT ; Fatal error if not colon after ? ; USERC1: XRA A ; Zero user number MOV B,A ; 'B' = accumulator for user number ; USRLOOP:MOV A,M ; Get digit INX H ; Point to next CPI ':' ; Done? JZ USRDN SUI '0' ; Convert to binary JC ERREXIT ; User number error? CPI 10 JNC ERREXIT MOV C,A ; Next digit in 'C' MOV A,B ; Old number in 'A' ADD A ; *2 ADD A ; *4 ADD B ; *5 ADD A ; *10 ADD C ; *10+new digit MOV B,A ; Result in 'B' JMP USRLOOP ; USRDN: MOV A,B ; Get nuer user number CPI MAXUSER+1 ; Within range? JNC ERREXIT STA USER ; Save in flag JMP GETFILE ; ; Extract file name ; GETF1: POP H ; Get pointer to byte ; GETFILE:MOV A,M ; Pointing to colon? CPI ':' JNZ GFILE1 INX H ; Skip over colon ; GFILE1: MOV A,M ; Get next character CPI ',' ; Delimiter? JZ GFQUES CPI '[' JZ GFQUES CPI ' '+1 ; Not a delimiter? JNC GFILE2 ; GFQUES: INX D ; Fill with ??? MVI B,11 ; 11 bytes MVI A,'?' ; GFFILL: STAX D ; Put? INX D ; Point to next DCR B ; Count down JNZ GFFILL ; FNDONE: LDA DISK ; Get disk number MOV B,A ; In 'B' LDA USER ; Get user number MOV C,A ; In 'C' POP D ; Restore registers MVI A,0FFH ; No error ORA A ; Set flags RET ;..... ; ; ; Get file name fields ; GFILE2: MVI B,8 ; At most, 8 bytes for filename CALL SCANF ; Scan and fill MVI B,3 ; At most, 3 bytes for filetype MOV A,M ; Get delimiter CPI '.' ; Filename ending in '.'? JNZ GFILE3 INX H ; Point to character after '.' CALL SCANF ; Scan and fill JMP FNDONE ; Done...return to 'args' ; GFILE3: CALL SCANF4 ; Fill with spaces JMP FNDONE ;..... ; ; ; Scanner routine ; SCANF: CALL DELCK ; Check for delimiter JZ SCANF4 ; Fill with spaces if found INX D ; Point to next byte in filename CPI '*' ; Question mark fill ? JNZ SCANF1 MVI A,'?' ; Place '?' STAX D JMP SCANF2 ; SCANF1: STAX D ; Place character INX H ; Point to next position ; SCANF2: DCR B ; Count down JNZ SCANF ; Continue loop ; SCANF3: CALL DELCK ; "B" chars or more - skip to delimiter RZ INX H ; Point to next JMP SCANF3 ; SCANF4: INX D ; Point to next filename or filetype MVI A,' ' ; Fill with spaces STAX D DCR B ; Count down JNZ SCANF4 RET ;..... ; ; ; Buffers ; DISK: DB 0 ; Disk number USER: DB 0 ; User number ;..... ; ; ; Check character pointed to by 'HL' for a delimiter, return with Zero ; flag set if the character is a delimiter ; DELCK: MOV A,M ; Get the character CALL CAPS ; Capitalize ORA A ; 0=delimiter RZ CPI ' '+1 ; Space character+1 JC DELCK1 ; Space character or less CPI '=' RZ CPI 5FH ; Underscore RZ CPI '.' RZ CPI ':' RZ CPI ';' RZ CPI ',' RZ CPI '<' RZ CPI '>' RZ CPI '[' RET ; DELCK1: CMP M ; Compare with self for ok RET ; CAPS: CPI 'a' RC CPI 'z'+1 RNC SUI 20H RET ;..... ; ; end of FNAME routine ;----------------------------------------------------------------------- ; ; Subroutines to read library file directory ; PRTLMEM:LXI H,ORDER ; Initialize order table pointer SHLD NEXTL XRA A STA LNCNT ; ENTRYL: LHLD LCOUNT ; Get FCB count DCX H ; Decrement it SHLD LCOUNT MOV A,H ; Is this the last file? ORA L JZ LBRTST ; If count=0, last file, skip compare PUSH B CALL CKABRT ; Check for abort code from keyboard LHLD NEXTL MVI A,11 CALL COMPR ; Does this entry match next one? POP B JNZ LBRTST ; No, print it INX H INX H ; Highest extent comes last in list SHLD NEXTL JMP ENTRYL ; Loop back for next lowest extent ; ; ; Exit Library member printing ; LBEXIT: LHLD LMTOTL MOV A,H ORA L RZ PUSH H ; Save member count XRA A ; Get a zero to... STA SUPSPC ; Suppress leading spaces in totals LXI H,MNPL ; If last line is full, don't turn LDA LNCNT ; Up extra line CMP M CNZ CRLF ; If partial line, extra line needed ; IF PRBRDR LXI D,CONTM1 ; Print "There are " ENDIF ; PRBRDR ; IF NOT PRBRDR LXI D,CONTM2 ENDIF ; NOT PRBRDR ; CALL PRINT POP H ; Get total member count back CALL DECPRT LXI D,MFILES ; Print "Members in " CALL PRINT LHLD LBTOTL CALL DECPRT LXI D,LIBR JMP PRINT ;..... ; ; ; Valid entry obtained - spit it out. ; LBRTST: LHLD NEXTL ; Get order table pointer MOV E,M ; Get low order address INX H MOV D,M ; Get high order address INX H SHLD NEXTL ; Save updated table pointer LXI H,8 DAD D CALL CKLBR JNZ LBRNEX PUSH D LXI H,MNPL LDA LNCNT ; Old code here CMP M CNZ CRLF PUSH PSW ; Just in case LDA MNPL ; Load a with # of names per line CPI 4 ; Is it 4? JZ LBMS ; If so then jump to long lbr message CPI 3 ; Is it 3? JZ LBMS ; If so then jump to long lbr message ; IF PRBRDR LXI D,LFMSP3 ; Set up short "LBR members" message ENDIF ; PRBRDR ; IF NOT PRBRDR LXI D,LFMSP4 ENDIF ; NOT PRBRDR ; CALL PRINT ; Print it JMP SKLBMS ; Skip past long message ; LBMS: IF PRBRDR LXI D,LFMSP1 ; Set up long "Library directory" msg ENDIF ; PRBRDR ; IF NOT PRBRDR LXI D,LFMSP2 ENDIF ; NOT PRBRDR ; CALL PRINT ; Print it ; SKLBMS: IF USELC LDA ULON ; Highlight library file name if ORA A ; enabled CNZ UNLON ENDIF ;USELC ; POP PSW ; Put it back LDA FCB ; Get current drive ADI 'A'-1 ; Convert to ascii CALL TYPE ; Print it CALL TYPUSR ; Print user # after it MVI A,':' ; And colon CALL TYPE POP H PUSH H MVI B,8 ; File name length CALL TYPEIT MVI A,'.' ; Period after filename CALL TYPE MVI B,3 ; Display 3 characters of filetype CALL TYPEIT ; IF USELC PUSH H ; Retain HL integrity for DOIT LDA ULON ORA A ; Turn off highlighting if enabled CNZ UNLOFF POP H ; Restore HL ENDIF ; USELC ; CALL DOIT ; Compute size of library in k XCHG CALL DECPRT LXI D,LFMSP5 CALL PRINT POP H ; ; ; Saves the library file name into LBRFCB ; LDA FCB LXI D,LBRFCB ; To STAX D INX D MVI B,11 ; Length CALL MOVE ; Do the move XCHG MVI B,25 ; CLMFCB: MVI M,0 INX H DCR B JNZ CLMFCB CALL SETLDMA LXI D,LBRFCB ; Point to file MVI C,OPEN ; Get function CALL CPM ; Open it MVI C,READ LXI D,LBRFCB CALL CPM CALL SETFOP LXI H,LBBUF MOV A,M ORA A JZ CKLDIR ; Check directory present? ; BADLBR: LXI H,NLBRF MVI B,25 CALL TYPEIT ; LMLEXI: CALL LBCLOSE ; ; ; Do next library file ; LBRNEX: LHLD LCOUNT ; Check count MOV A,H ORA L JZ LBEXIT ; No more, all done JMP ENTRYL ; Else, get next .LBR file ; NLBRF: DB '++ Not a LIBRARY file ++',CR,LF ;..... ; ; ; Close the library file ; LBCLOSE:LXI D,LBRFCB MVI C,CLOSE CALL CPM RET ;..... ; ; ;Set the Library file DMA address ; SETLDMA:CALL CKVER ; Set carry if pre-CP/M 2 LDA NEWUSR ; Get user area for directory MOV E,A MVI C,CURUSR ; Get the user function CNC CPM ; And set new user number if CP/M 2 LXI D,LBBUF MVI C,SETDMA CALL CPM RET ;..... ; ; ; Check to see if there indeed is a LBR file directory ; CKLDIR: MVI B,11 ; Length of file name MVI A,' ' ; Space INX H ; CKDLP: CMP M JNZ BADLBR DCR B INX H JNZ CKDLP ; ; ; The first entry in the LBR directory is indeed blank. Now see if the ; directory size is >0 MOV E,M ; File starting location low INX H ; Must be zero here MOV A,M ; File starting location high ORA E ; Must be zero here also JNZ BADLBR INX H MOV E,M ; Get library size low INX H ; Point to library size high MOV D,M ; Get library size high MOV A,D ORA E ; Library must have some size JZ BADLBR DCX D XCHG SHLD SLFILE LHLD LBTOTL INX H SHLD LBTOTL LDA MNPL STA LNCNT ; Reset names per line counter MVI B,3 LXI H,17 DAD D JMP LMTEST ; LFMLOP: LHLD SLFILE ; Get MOV A,L ORA H JZ LMLEXI DCX H SHLD SLFILE CALL SETLDMA MVI C,READ LXI D,LBRFCB CALL CPM CALL SETFOP MVI B,4 ; Get file count per record LXI H,LBBUF ; Get buffer starting address ; LMTEST: MOV A,M ; Get member open flag ORA A ; Test for open JZ PRMNAM ; LMTESA: LXI D,32 ; Member not open get offset DAD D ; To next and add it in DCR B ; Is buffer empty ? JNZ LMTEST ; No so test next entry JMP LFMLOP ; Yes, get next buffer ; PRMNAM: PUSH H ; Print member name and size PUSH B CALL CKABRT ; Check for abort code from keyboard LXI H,LNCNT LDA MNPL CMP M JNZ PRMNA1 ; IF PRBRDR MVI A,'*' ; Load A-register with border character CALL TYPE ; Print it MVI A,' ' CALL TYPE ; Print space between border and text ENDIF ; PRBRDR ; IF PRDI AND PRLIBD LDA LBRFCB ; Precede new line with drive name ADI 'A'-1 CALL TYPE ENDIF ; PRDI AND PRLIBD ; IF PRDI AND PRLIBD AND PRUS CALL CKVER ; Under CP/M 2, output the user number CNC TYPUSR ENDIF ; PRDI AND PRLIBD AND PRUS ; IF PRDI AND PRLIBD MVI A,':' ; Tag header with a colon and a space CALL FPAD ; And exit back to entry ENDIF ; PRDI AND PRLIBD ; PRMNA1: POP B POP H PUSH H PUSH B INX H MVI B,8 ; File name length CALL TYPEIT MVI A,'.' ; Period after filename CALL TYPE MVI B,3 ; Display 3 characters of filetype CALL TYPEIT INX H INX H MOV E,M INX H MOV D,M XCHG ; ; ; Output the size of the individual file ; PUSH D PUSH H PUSH H LHLD LLENLOC PUSH H POP D POP H DAD D SHLD LLENLOC POP H ; ; ; New code added to convert lib members from records to 'k'. Upon entry ; member's size in records is in HL. ; LXI D,7 ; Round up to nearest 1k DAD D XCHG LXI H,0 MOV A,E ; Put low byte of record count in A RRC RRC RRC ANI 1FH MOV E,A ; And put it back MOV L,D ; Get the high byte if any MVI D,0 ; Clean out the old resting place DAD H ; Multiply it by 32 to convert to DAD H ; number of k bytes DAD H DAD H DAD H DAD D ; And add in the low byte POP D CALL FDECPRT ; Go print it MVI A,'k' ; Follow with size CALL TYPE ; ; ; At least one more file to output - can we put it on the current line? ; LHLD LMTOTL INX H SHLD LMTOTL LDA LNCNT DCR A STA LNCNT PUSH PSW CNZ FENCE ; If room left, output the fence char. POP PSW POP B POP H JNZ LMTESA ; And go output another file ; ; ; Current line full, start a new one ; LDA MNPL STA LNCNT ; Reset names per line counter CALL CRLF ; Space down to next line JMP LMTESA ; ; ; Move characters from 'HL' to 'DE' length in 'B' ; MOVE: MOV A,M ; Get a character STAX D ; Store it INX H ; To next 'from' INX D ; To next 'to' DCR B ; More? JNZ MOVE ; Yes, loop RET ; No, return ;..... ; ; ; Test file extent for LBR ; CKLBR: PUSH H PUSH D PUSH B XCHG LXI H,LBRTYP MVI C,3 ; CKLBL: LDAX D ANI 7FH CMP M JNZ CKLBX INX H INX D DCR C JNZ CKLBL ; CKLBX: POP B POP D POP H RET ;..... ; ; LFMSP1: DB CR,LF,'** Library directory for ',0 LFMSP2: DB CR,LF,'Library directory for ',0 LFMSP3: DB '** ' LFMSP4: DB 'Lbr members in ',0 LFMSP5: DB 'k' ; IF PRBRDR DB ' **' ENDIF ; PRBRDR ; DB CR,LF,0 ; LBRTYP: DB 'LBR' ;..... ; ;----------------------------------------------------------------------- ; TIMEON routine ; ; Go through a search to see if BYE is active. ; IF TIMEON TIME: LHLD 0001H ; Point to warm boot again DCX H ; If BYE active, MOV D,M ; Pick up pointer to BYE variables DCX H ; (COVECT) followed by 'BYE' MOV E,M LXI H,15 ; Calculate address of BYE variable DAD D ; Where ptr to orig BIOS vector stored MOV E,M ; Load that address into DE INX H ; If BIOS active, DE now points to MOV D,M ; Original BIOS console output vector INX H ; Point to BYE signon message MOV A,M ; Get letter ANI 05FH ; Convert to upper case if needed CPI 'B' ; Try to match 'BYE' RNZ ; Out if BYE not active INX H MOV A,M ANI 05FH ; Convert to upper case if needed CPI 'Y' RNZ INX H MOV A,M ANI 05FH ; Convert to upper case if needed CPI 'E' RNZ LXI D,6 ; Bye is running, so point to RTCBUF DAD D MOV E,M ; Get RTCBUF address INX H ; And MOV D,M ; Stuff in DE XCHG ; Then put in HL (RTCBUF address) LXI D,7 DAD D ; Further offset to time-on-system byte MOV A,M ; (A) now has time-on LXI H,TONMS1 ; Where to store it in ASCII CALL DEC8 ; Convert binary to ASCII LXI D,TONMSG CALL PRINT ; Print the message RET ; And return ;..... ; ; ; DEC8 will convert an 8 bit binary number in A to 3 ASCII bytes. ; HL points to the MSB location where the ASCII bytes will be stored. ; Leading zeros are suppressed, so store spaces in your buffer before ; calling. ; DEC8: PUSH B PUSH D MVI E,0 ; Leading zero flag MVI D,100 ; DEC81: MVI C,'0'-1 ; DEC82: INR C SUB D ; 100 or 10 JNC DEC82 ; Still + ADD D ; Now add it back MOV B,A ; Remainder MOV A,C ; Get 100/10 CPI '1' ; Zero? JNC DEC84 ; Yes MOV A,E ; Check flag ORA A ; Reset? MOV A,C ; Restore byte JZ DEC85 ; Leading zeros are skipped ; DEC84: MOV M,A ; Store it in buffer pointed at by HL INX H ; Increment storage location MVI E,0FFH ; Set zero flag ; DEC85: MOV A,D SUI 90 ; 100 to 10 MOV D,A MOV A,B ; Remainder JNC DEC81 ; Do it again ADI '0' ; Make ascii MOV M,A ; And store it POP D POP B RET ; TONMSG: DB CR,LF,'Minutes on System: ' TONMS1: DB ' ',0 ENDIF ; TIMEON ;..... ; ; end of TIMEON routine ;----------------------------------------------------------------------- ; ; Help menu if ? is typed, using a fancy ZCMD or ZCPR system ; IF WHEEL HELPME: LXI D,OPTMSG ; Point at message CALL SHOW LDA WHLOC ; Check wheel ORA A ; If set, help out poor SYSOP JZ EXIT2 ; No - exit ; LXI D,SYSOP1 ; Point at message CALL SHOW JMP EXIT2 ; And exit ;..... ; ; ; This menu of options will appear to normal users (WHEEL not set). ; Modify the menus to accomodate your system requirments. ; OPTMSG: DB CR,LF,CR,LF DB ' Available Options (start with a $ or / or [):' DB CR,LF,CR,LF DB ' A - all user areas U - user area to start' DB CR,LF DB ' D - all drives V - show version number' DB CR,LF DB ' L - list library members 4 - 40 col display (2-wide)' DB CR,LF DB ' N - no page pause [more] 6 - 64 col display (3-wide)' DB CR,LF DB ' Q - show non-$ARChived files 8 - 80 col display (4-wide)' DB CR,LF,CR,LF DB ' Example - to list all drives and user areas, no pauses:' DB CR,LF,CR,LF DB ' A0>DIR $ADN' DB CR,LF,CR,LF,0 ;..... ; ; ; This menu of options appears only when the WHEEL is set. ; SYSOP1: DB ' * * * Special SYSOP Options (WHEEL SET): * * *' DB CR,LF,CR,LF DB ' F - file output (DISK.DIR)  P - printer output' DB CR,LF DB ' O - only show $SYS files S - include $SYS files' DB CR,LF,CR,LF,0 ENDIF ; WHEEL ; ; ; Help menu if ? is typed, NOT using any fancy ZCMD or ZCPR system ; IF NOT WHEEL HELPME: LXI D,OPTMSG ; Point at message CALL SHOW JMP EXIT2 ; And exit ;..... ; ; OPTMSG: DB CR,LF,CR,LF DB ' Available Options (start with a $ or / or [):' DB CR,LF,CR,LF DB ' A - all user areas S - include $SYS files' DB CR,LF DB ' D - all drives U - user area to start' DB CR,LF DB ' F - file output (DISK.DIR) V - show version number' DB CR,LF DB ' L - list library members 4 - 40 col display (2-wide)' DB CR,LF DB ' N - no page pause [more] 6 - 64 col display (3-wide)' DB CR,LF DB ' O - only show $SYS files 8 - 80 col display (4-wide)' DB CR,LF DB ' P - printer output Q - show non-$ARChived files' DB CR,LF,CR,LF DB ' Example - to list all drives and user areas, no pauses:' DB CR,LF,CR,LF DB ' A0>DIR $ADN' DB CR,LF,CR,LF,0 ENDIF ; NOT WHEEL ;..... ; ; end of program code ;----------------------------------------------------------------------- ; ;Initialized data area ; DRUMSG: DB 'Drive/User',0 ; IF PGPAWS EOSMSG: DB ' [more]',CR,'$' MORERA: DB ' ',CR,'$' ENDIF ; PGPAWS ; ERRMS1: DB ' ' ERRMS2: DB 'Error',0 ERRTAG: DB ' ->',0 NOFMS1: DB CR,LF,CR,LF,' ',0 NOFLM: DB '>> No detectable file(s) on ',0 NOFSM: DB '>> No file(s) on ',0 NOFMS2: DB ': ',0 TOTMS1: DB CR,LF,' ',0 TOTMS2: DB 'Drive ',0 TOTMS3: DB ' ',CR,LF,0 TOTMS4: DB '/',0 TOTMS5: DB 'k ',0 TOTMS6: DB ': Files: ',0 TOTMS7: DB ' Free: ',0 TOTMS8: DB 'k',0 CONTM1: DB CR,LF,'** There are ',0 CONTM2: DB CR,LF,'There are ',0 MFILES: DB ' member files in ',0 LIBR: DB ' library(s)' ; IF PRBRDR DB ' **' ENDIF ; PRBRDR ; DB 0 ;..... ; ; ; Permanently initialized data area ; VECTBL: DW DSKERR ; BDOS record error intercept vector DW DSKERR ; BDOS select error intercept vector ; ; ; Template of initialization data for when SD is run or rerun ; ; The values here are copied by initialization code into ; the area in which they are actually used by the program ; TMPLT0 EQU $ ; Mark start of initialization template ; ; Option field lookup table. Note that you can force any of these op- ; tions as a DEFAULT by changing the letter for the option into a zero ; (assuming that its enabling equate is true). Each option that you ; hard-wire in this manner will no longer be recognized as a command ; line OPTION, and if you redundantly key it in, SD will flag it as un- ; recognized. ; OTBL0: IF USEA DB 'A' ; All users option flag ENDIF ; USEA ; IF NOT USEA DB 'a' ENDIF ; NOT USEA ; IF USEC DB '4' ENDIF ; USEC ; IF NOT USEC DB '4'+40H ENDIF ; NOT USEC ; IF USEC DB '6' ENDIF ; USEC ; IF NOT USEC DB '6'+40H ENDIF ; NOT USEC ; IF USEC DB '8' ENDIF ; USEC ; IF NOT USEC DB '8'+40H ENDIF ; USEC ; IF USED DB 'D' ; Multi-disk option flag ENDIF ; USED ; IF NOT USED DB 'd' ENDIF ; NOT USED ; IF USEF DB 'F' ; DISK.DIR file output option ENDIF ; USEF ; IF NOT USEF DB 'f' ENDIF ; NOT USEF ; IF USEL DB 'L' ; Display library members flag ENDIF ; USEL ; IF NOT USEL DB 'l' ENDIF ; NOT USEL ; IF PGPAWS ; No page-pause option flag DB 'N' ENDIF ; PGPAWS ; IF USEO DB 'O' ; To show .SYS files only ENDIF ; USEO ; IF NOT USEO DB 'o' ENDIF ; NOT USEO ; IF USEP DB 'P' ; Printer output option ENDIF ; USEP ; IF NOT USEP DB 'p' ENDIF ; NOT USEP ; IF USEQ DB 'Q' ; To show only non-$ARC files ENDIF ; USEQ ; IF NOT USEQ DB 'q' ENDIF ; NOT USEQ ; IF USES DB 'S' ENDIF ; USES ; IF NOT USES DB 's' ENDIF ; NOT USES ; DB 'V' ; OEND0 EQU $ ;..... ; ; End of option lookup table ;-------------------------------------------------------- --------------- ; BUFPN0: DW OUTBUF ; Ptr to next location in output buffer BUFCN0: DB 128 ; Number of bytes left in output buffer OUTFC0: DB 0,'DISK DIR' TMPLT1 EQU $ ; End of initialization data template ; ; ; End of code that must be stored on disk in the .COM file ;======================================================================= ; ; Data area reinitialized by code when SD is run or rerun ; DATA0 EQU $ ; Mark beginning of area to initialize OTBL EQU $ ; Mark start of option table AOPFLG: DS 1 CL4FLG: DS 1 CL6FLG: DS 1 CL8FLG: DS 1 DOPFLG: DS 1 FOPFLG: DS 1 LOPFLG: DS 1 NOPFLG: DS 1 OOPFLG: DS 1 POPFLG: DS 1 QOPFLG: DS 1 SOPFLG: DS 1 VOPFLG: DS 1 OEND EQU $ ; Mark end of option table ; ; ; End of option lookup table ;----------------------------------------------------------------------- ; BUFPNT: DS 2 ; Ptr to next location in output buffer BUFCNT: DS 1 ; Number of bytes left in output buffer OUTFCB: DS 1 + 8 + 3 ; Space for user # filename and filetype ; ; ; Beginning of area reinitialized to zero each time SD.COM is run ; DS 21 ; Rest of DISK.DIR FCB OPNFLG: DS 1 ; File open flag for all user files AFLAG: DS 1 ; If a option check for prior u option DFLAG: DS 1 ; If d option check for prior drive FNDFLG: DS 1 ; Flag whether any files matched ; LINCNT: DS 1 ; Count of lines printed on screen LLENLOC:DS 2 ; Running total of .LBR length LMTOTL: DS 2 LBTOTL: DS 2 LNCNT: DS 1 LCOUNT: DS 2 NEXTL: DS 2 SLFILE: DS 2 LINES: DS 1 ; Number of lines to be printed out. FIRSTT: DS 1 ; First time flag for version # display DATA1 EQU $ ; Mark end of area to initialize ;..... ; ; ; Uninitialized data area ; OUTBUF: DS 128 ; Output file buffer BASUSR: DS 1 ; Dupe of original dir. user # to search BLKMAX: DS 2 ; Highest block # on drive BLKMSK: DS 1 ; Records/blk - 1 BLKSHF: DS 1 ; # shifts to mult by sec/blk COUNT: DS 2 ; Entry count DIRMAX: DS 2 ; Highest file # in directory FREEBY: DS 2 ; Has number of k left on dir. drive GAP: DS 2 ; Sort routine storage HITRAP: DS 1 ; Highlit trap (previously typed char) I: DS 2 ; Sort routine storage J: DS 2 ; Sort routine storage JG: DS 2 ; Sort routine storage LZFLG: DS 1 ; 0 when printing leading zeros MAXUSR: DS 1 ; Max user # for drive from lookup table NEWUSR: DS 1 ; Has user # selected by "$U" option NEXTT: DS 2 ; Next table entry OLDDSK: DS 1 ; Holder for currently logged-in drive OLDUSR: DS 1 ; Contains user number upon invocation SCOUNT: DS 2 ; # to sort SUPSPC: DS 1 ; Leading space flag for decimal routine TBLOC: DS 2 ; Pointer to start of name table TEMP: DS 2 ; Save directory entry TOTFIL: DS 2 ; Total number of files TOTSIZ: DS 2 ; Total size of all files VERFLG: DS 1 ; CP/M version number (0=pre-CP/M 2) ZRDFLG: DS 1 ; ZRDOS version number BYEACT: DS 1 ; Will be zero if BYE5xx is running ; LBRFCB: DS 36 LBBUF: DS 80H ; IF VCODE NEWPTR: DS 2 ; Pointer to start of second table XPOINT: DS 2 JUMPER: DS 2 ; Amount to increment by in second table ENDIF ; VCODE ; DS 60 ; Stack area STACK: DS 2 ; Save old stack pointer here ; ORDER EQU $ ; Order table starts here ;..... ; ; END DS 1 ; Max user # for drive from lookup table NEWUSR: DS 1 ; Has user # selected by "$U" option NEXTT: DS 2 ; Next table entry OLDDSK: DS 1 ; Holder for currently logged-in drive OLDUSR: DS 1 ; Contains user number upon invocation SCOUNT: DS 2 ; # to sort SUPSPC: DS 1 ; Leading space flag for decimal routine TBLOC: DS 2 ; Pointer to start of name table TEMP: DS 2 ; Save directory entry TOTFIL: DS 2 ; Total number of files TOTSIZ: DS 2 ; Total size of all files VERFLG: DS 1 ; CP/M version number (0=pre-CP/M 2) ZRDFLG: DS 1 ; ZRDOS version number BYEACT: DS 1 ; Will be zero if BYE5xx is running ; LBRFCB: DS 36 LBBUF: DS 80H ; IF VCODE NEWPTR: DS 2 ; Pointer to start of second table XPOINT: DS 2 JUMPER: DS 2 ; Amount to inj| SD116 - 30/04/86RVON>RVOFF>ULON>ULOFF>MAXUSR TBL>!9"G1G!]~?„#~ !!yEw# ‹]w# —0}2e }2d  ԧ 2X2T2> ԧ M2f!~[#w\1 xy2T2>ͧ 2W<2!\~:W<>2w!F#~[=$5/ +~#  >]>!x# ʪ:>s~4r6r8rwS6ḊA̜>:™!\>w:>2T2>U ʯ0 2T2>>20C Co:Tg2T2>>f k k !~{ #>?{ f :z1>2>2:{D>2>2:|W>2>2:} :\=ҍ !=n#ҍ _:>ʃ>Õ!Z~g:?ҕ2SG2S!Tڍ x !]~$ʻ/ʻ  6?#½>?2h !\^ͧ % ##~2B#~2A##^#V"?#^#V*.;^#~2B#~2A#^"?L"E:d0L:\=_.ͧ !~w+: 4*Ã*?#bW+}sz]Yi`:Bʃ)=~"G*E#)I"\"U*{zo% :T_ ԧ >?!hw#w#w!"C"`"b \ͧ <=! o:#~+:~!:~} o:T#*U w# o&yo|gyo|gr#s#"U*C#"C! *{z͍ Memory)y *C}2[*\!I s#r# +}˜*C"Y+} *Y|g}o }o"I#"L*I{ozg"N*I"P> k *N*PV *N*I{ozg  *Y*L#{z*I÷:~!5ͧ 2:k f *C"!""!I""Ul*C+"C|'͂ *U> 9 '##"U*U^#V#"Ua >.{ a v*b"b*`#"`͕>k{ *C| p :Of V#^:A_zW/_zW{_‰ɯ2R:[2[2[>0{ 0x0:R>0{ :[y 2R{ :*`|` 2[*`|k2k :92 k :\@{ % 0G k ͕:NNk k *b͕k  :98 :yŠ% ڊ͂ :S!T4҆:>w!~6ʿ!~6ʫ*6#=¤ͧ Lͧ !~6 !~5k :k k :\@{ %  G k  f 4:}1 ͂ >!\41 :=<1 ^^:¢  ͧ  ͧ â :T a / R Gy{ x0{ > { > { y :{ >  ͂ G:~· *:® ͧ L!>p#"=2x_:̧ { : : :  !,A !9A !GA !F#:fa ~T #J _Dͧ ~{ #a { k *. ͦ *.ͦ w  w   ͧ :e G:d0x |+ x  2 !+ 4% :X_ ԧ  ç k *G͕k  ' ^#V#N#F_~W #T C G) ) Nq#NqG) ) N#F^#V_~W #} >2~f k k f :} ͂ >!\4 :=< ^^ ͧ ħ :e :d0 -ͧ :} *G:e:d0 -ͧ *#^#V. Y>FNpq#= :d 1Gâ >2- 2. $կ> ~#:_ ,ں [ʺ !ʺ F ~W Ax As <2- #~:ʻ ? 2. #~:ʻ p G~#:ʮ 0p p OxGÒ x p 2. û ~: #~, [ !  >? :- G:. O> ~. # $ / $ * >? # / # > $ ~W !U =_.:;,<>[ɾa{ !I"2*+"|ʿ ͂ *> 9 ¿ ##"j *|2[!:f k ͕8k *͕Jk *^#V#"!͵{!:f :  k k :92 :\@{ G >:{ a >.{ a :98 v͕k :\g ͬ6#Kͩgͧ gͧ !~ʾ!a ͠*|ʎ j ++ Not a LIBRARY file ++ gͧ % :T_ ԧ ͧ  > #p#^#~p#^#Vzp"*#":2!*}x+"ͩgͧ !~& ͂ !:?>*{ > { #a >.{ a ##^#V*"!{_j)))))͕>k{ *#":=2p :2f ~#¬!# ¾ ** Library directory for Library directory for ** Lbr members in k ** LBR7' :> ' Available Options (start with a $ or / or [): A - all user areas U - user area to start D - all drives V - show version number L - list library members 4 - 40 col display (2-wide) N - no page pause [more] 6 - 64 col display (3-wide) Q - show non-$ARChived files 8 - 80 col display (4-wide) Example - to list all drives and user areas, no pauses: A0>DIR $ADN * * * Special SYSOP Options (WHEEL SET): * * * F - file output (DISK.DIR) P - printer output O - only show $SYS files S - include $SYS files Drive/User [more] $ $ Error -> >> No detectable file(s) on >> No file(s) on : Drive /k : Files: Free: k ** There are There are member files in library(s) **+ + A468DfLNopQsVDISK DIR͕>k{ *#":=2p :2f ~#¬!# ¾ ** Library directory for Library directory for ** Lbr members in k ** LBR7' :> ' Available Options (start with a $ or / or [): A - all user areas U - user area to start D - all drives V - show version number L - list library members 4 - 4SD HISTORY: ========== ;----------------------------------------------------------------------- ; 06/12/86 BUG FIX: A misplaced semicolon caused release 116 to fail to ; v116a parse user areas from the command line, such as: SD B4: ; This has been fixed in the .COM file and the .AQM file in ; this library. Please spread the word. ;----------------------------------------------------------------------- ; 04/30/86 *Re-worked REVID/USELC logic. REVID option deleted as its ; v116 function now encompassed within USELC. If USELC is set and ; the RVON string is non-null then reverse video will be used ; instead of lower-case conversion for the display of file ; name characters with the attribute bit set. However, if BYE ; is also running then the reverse video sequence will NOT be ; sent over the phone line. If the RVON string is null then ; simple lower-case conversion will be used to display file ; attributes. A further improvement might be to ch"eck the ; WHEEL byte and, if set, send L/C out over the modem while ; using highlighting on the local screen. ; *Note that the BYE test uses BDOS function 32 and works for ; BYE5nn or BYE339. The code invoked by setting the TIMEON ; option uses a different technique and I have not tested it. ; For that matter, the local console output is also dependent ; on the extended BDOS functions of BYE5nn or BYE339. ; *On the same theme, added option to display banner in (pos- ; sibly different) highlight mode. Suggest using underlining. ; The highlight sequence is not sent to an RCPM caller. ; *Changed lines containing a semicolon and nothing else to ; blank lines. Renders listing a bit less cluttered, the ; source file minutely smaller and if for some reason you ; should ever want to print an assembly listing then it saves ; a LOT of print time and head movement. ; *Added alternative option delimiters. '$' is an awkward key ; on most keyboards for a touch typist. You can now use '/' ; as for ZCPR or '[' if you prefer the CP/M+ style. Like '$', ; '/' must be preceded by a blank but '[' does not need it ; since '[' cannot be a file name character. Trailing ']' is ; optional. ; *Changed all dates in this file to universal format so people ; outside the USA can read them. Also pinched an idea from ; Irv Hoff's KMD program and inserted an EDATE (Eurodate) op- ; tion to display version date as DD/MM/YY. ; - John Hastwell-Batten ; Tesseract RCPM+ ; New South Wales, Australia ; ;----------------------------------------------------------------------- ; 04/04/86 Cleaned up several bugs which had been put in versions 112- ; v115 114 by sloppy updaters: Calls to CKABRT restored as they ; were in SD110. This fixes the problem many Sysops have ; noticed with the $L display and makes it easier to abort ; the program with ^C. Fixed nested IF-ENDIF condition in ;  TYPE1:. This bug was introduced in SD114. Added code to ; turn off page pauses when $P (printer) option is used. The ; NOMORE equate added in SD112 has been removed since it is ; no longer necessary. Fixed obscure bug in CLEX: which ; caused $D option to be run instead of giving command error ; when using invalid option following $D on command line. ; This bug was in every SD version which I could find. ; - Murray Simsolo LIKUG RCPM ; (516)825-8465 ; ;----------------------------------------------------------------------- ; 04/03/86 *A new option ($Q) has been added to display files that do ; v114 NOT have their $ARChive bit set. This is useful on vary ; large hard disks, or RCPM systems that get a lot of uploads, ; to help speed things up when backing up the hard disk. It ; is also useful to the remote caller so that they can see ; what is new since the last back up. ; *The command "SD114 $ADNQS" will show what areas need to be  ; backed up and which ones can be skipped over. [I am using ; ZRDOS's "AC" program to back up with.] (Thanks to Dave ; Hardy for the idea.) ; *Also added was the USELCW equate, with this equate true, ; [and WHEEL true, and the WHEEL byte set]. Everything works ; as discribed in v111 (below). ; *If the WHEEL byte is NOT set then the character is printed ; normally (no lower case or reverse video) this keeps the re- ; verse video strings from being sent to the remote user (un- ; less they have WHEEL set). ; *If USELCW is false then the WHEEL byte is ignored and every- ; thing works as discribed in v111. ; - Bob Paddock ZNODE 38 ; ;----------------------------------------------------------------------- ; 03/12/86 Corrected bug in TYPE1 that caused characters with attribute ; v113 bit set to never be output if REVID option was used without ; also using USELC. - Dave Paul ; ;----------------------------------------------------------------------- ; 04/04/86 Cleaned up several bugs which had been put in versions 112- ; v115 114 by sloppy updaters: Calls to CKABRT restored as they ; were in SD110. This fixes the problem many Sysops have ; noticed with the $L display and makes it easier to abort ; the program with ^C. Fixed nested IF-ENDIF condition in ; TYPE1:. This bug was introduced in SD114. Added code to ; turn off page pauses when $P (printer) option is used. The ; NOMORE equate added in SD112 has been removed since it is ; no longer necessary. Fixed obscure bug in CLEX: which ; caused $D option to be run instead of giving command error ; when using invalid option following $D on command line. ; This bug was in every SD version which I could find. ; - Murray Simsolo LIKUG RCPM ; (516)825-8465 ; ;----------------------------------------------------------------------- ; 04/03/86 *A new option ($Q) has been added to display files that do ; v114 NOT have #their $ARChive bit set. This is useful on vary ; large hard disks, or RCPM systems that get a lot of uploads, ; to help speed things up when backing up the hard disk. It ; is also useful to the remote caller so that they can see ; what is new since the last back up. ; *The command "SD114 $ADNQS" will show what areas need to be ; backed up and which ones can be skipped over. [I am using ; ZRDOS's "AC" program to back up with.] (Thanks to Dave ; Hardy for the idea.) ; *Also added was the USELCW equate, with this equate true, ; [and WHEEL true, and the WHEEL byte set]. Everything works ; as discribed in v111 (below). ; *If the WHEEL byte is NOT set then the character is printed ; normally (no lower case or reverse video) this keeps the re- ; verse video strings from being sent to the remote user (un- ; less they have WHEEL set). ; *If USELCW is false then the WHEEL byte is ignored and every- ; thing works as discribed in v111.  ; - Bob Paddock ZNODE 38 ; ;----------------------------------------------------------------------- ; 04/03/86 *A new option ($Q) has been added to display files that do ; v114 NOT have their $ARChive bit set. This is useful on vary ; large hard disks, or RCPM systems that get a lot of uploads, ; to help speed things up when backing up the hard disk. It ; is also useful to the remote caller so that they can see ; what is new since the last back up. ; *The command "SD114 $ADNQS" will show what areas need to be ; backed up and which ones can be skipped over. [I am using ; ZRDOS's "AC" program to back up with.] (Thanks to Dave ; Hardy for the idea.) ; *Also added was the USELCW equate, with this equate true, ; [and WHEEL true, and the WHEEL byte set]. Everything works ; as discribed in v111 (below). ; *If the WHEEL byte is NOT set then the character is printed ; normally (no lower case or reverse video) this keeps the re- ; verse video strings from being sent to the remote user (un- ; less they have WHEEL set). ; *If USELCW is false then the WHEEL byte is ignored and every- ; thing works as discribed in v111. ; - Bob Paddock ZNODE 38 ; ;----------------------------------------------------------------------- ; 03/12/86 Corrected bug in TYPE1 that caused characters with attribute ; v113 bit set to never be output if REVID option was used without ; also using USELC. - Dave Paul ; ;----------------------------------------------------------------------- ; 01/24/86 *Moved misplaced ENDIF in TYPE2. This caused 00h to be sent ; v112 causing every character to be followed by a null bytes. ; This speed-up helps when running under BYE at 300 Baud (yes ; some of us still are slow users). Before change, 300 baud ; output looked like 110... Also moved major call to CKABRT ; so only is called at end of line at CRLF. (Also speeds ; things up !!) ; *Added NOMORE equate so that when overwriting [more] mes- ; sage an additional LF is printed. This keeps printed copy ; produced at remote end from having next line overprint ; [more] producing garbage on printer. ; - Mike Vore, W3CCV ; ;---------------------------------------------------------------------- ; 11/20/85 Minor hack to re-install a reverse video capability for ; v111 displaying attribute tags. USELC is limited to alpha A-Z ; so REVID will let you see other characters that have been ; tagged. Up to 7 bytes each for enter and exit sequences ; are available. They can be patched via DDT, DU, etc., or ; if left all 0, will be ignored. You can set USELC too, if ; inverse lower case excites you. ; - Dick Mead, Pasadena ZNODE 36 ; ;---------------------------------------------------------------------- ; 11/15/86 This is a major update (skipped to v110) and incorporates ; v110 changes requested by several Sysops. Installation of this ; program was becoming a nightmare even for experienced RCP/M ; operators. Many confusing and redundant equates have been ; eliminated. The installer no longer need be concerned with ; running BYE low or high, or where his BDOS page starts. The ; need to install computer dependent code has been eliminated. ; Previous versions could be assembled with combinations of ; equates that could result in assembler errors, or worse, ; crash the system. A new option ($O) has been added to dis- ; play ONLY system (.SYS) files. Simplicity and security were ; the results. - Wayne Masters & Irv Hoff ; Potpourri, (408) 378-7474 ;----------------------------------------------------------------------- , Pasadena ZNODE 36 ; ;---------------------------------------------------------------------- ; 11/15/86 This is a major update (skipped to v110) and incorporates ; v110 changes requested by several Sysops. Installation of this ; program wa$; ;SDREMOTE.ASM by Michael Conley 5/16/86 ; ;Beginning with SD version 116, the program checks to see whether BYE is ;running and if so, doesn't send reverse video characters to the remote ;user. ; ;This patch is for remote systems NOT RUNNING BYE. It checks your UART ;to see if a carrier is present and, if so, wipes out the reverse video ;codes so you don't make a mess of the remote user's terminal. Tuck it ;into the program after the four lines of code in label START: and before ;the comment "See if help is wanted" ; ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ;these are the only equates you need to set in this patch ; MSTAT EQU 1 ;equate your modem status port here DCD EQU 80H ;equate carrier detect bit here ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; CARRCK: ;this kills reverse vid if carrier detected IN MSTAT ; ANI DCD ; see if carrier up JZ OFFLN ; no carrier, don't wipe out reverse video code XRA A ; otherwise blow away reverse vid chars STA RVON STA RVOFF STA ULON ; and blow away underline chars STA ULOFF OFFLN: ; ; See if help is wanted  It checks your UART ;to see if a carrier is present and, if so, wipes out the reverse video ;codes so you don't make a mess of the remote user's terminal. Tuck it ;into the program after the four lines of code in label START: and before ;the comment "See if help is wanted" ; ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ;these are the only equates you need to set in this patch ; MSTAT EQU 1 ;equate your modem status port here DCD EQU 80H ;equate carrier detect bit here ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; CARRCK: ;this kills reverse vid if carrier detected IN MSTAT ; ANI DCD ; see if carrier up JZ OFFLN ; no carrier, don't wipe out reverse video kNSWP is copyright (c) 1983 by Dave Rand 10232-160 Street Edmonton, Alberta (403) 484-4114!9"1=*."7.2.2. 2.2.2. 0ڱ2.-!]. `>?!" .".!^#6#6!M ͼr@Drive :.AQ:.<>*Q>? =__o&S2.@:!.]@ !" .#"+."-.w!=.͊}+h#" .!e2*.+" .#͈".!"."/."1.1=:.2:.d* .#}»@ No files.XL'SʪÀ9*.͈dG!!5~ȸ###^#V:._:.__1*-.@K in #@ files. *+.@K free. u uBXSDTUVPEkL'CM A RcFWY%?Q *.#".* .,Ҁ!".9À*.|+".€9* .".À@ Which drive? @:!AڀQҀ :.GA2.9rw9*+.@K remaining on drive AQ>:Q9x2.rÀ@ Which flags (1-4,R,S,A)? @!o. 6#L!!~ʀ#">.*>.#">.ʊ!o. ʄ#w_>_> 1234zzzzRSA@ Delete file? Y€*.;À͈]2\ `6`__^_:e!@ R/O. Delete? Y:e2e\\_* .*.{ozg))))xV~# xL* .+" .*.,+".@ Erase Tagged or Untagged files (T/U)? TʤU€T>ʬ2 .@ Do you wish to be prompted (Y/N/A)? ʀAʀNY>¯24.!".͈4~G: .f@ Deleting ---> :4.W@ Delete (Y/N/A)? AzYfʃ;h#* .#}z+,!".À!".Ü ~6ʩ#*1."1.*/."/.*/.@K (*1.@K).*.͈4͌u@ Tagged files = *.͈ͩu4~6#*1.~"1.*/.~"/.@ New drive/user/mask? @!!~ʀ#">.:\`:.<=2.:;.y#~*>y:.2.:] ‘!]^ 6?`!\. `992.~ʸV#ª2.@ Illegal drive code.Àͥ:.2;.:.29.~0ں:AںQҺA29.#~:ȷ*:0:'G#~:33036302;.x 2;.>2;.! !!^#6#p#~iwV@ Copy to drive/user? @!!~ʀ r#:D.::.G:;.ʧ:9.G:.@ Can't copy to same drive and user.À*.͈2H.I. `~2:.@ Copy to (filespec)? @!!~ʀ#">.*>.ͥ:] > !I.] ~#4 :\=29.!I.]NT ͙!]I. 怶w#\ !\n. `:.G:9.ʅ  r À@ Squeeze, Unsqueeze or Reverse (S,U,R)? 2.S U R€> 2D.9:.2:. a!͈4~+Fƒ x2:.:D.O :.G:9.O ::.G:;.O @ Skipping, same drive & user --> à :D.s ʊ @ Copying --> Þ @ SQ/USQ --> Þ @ Setting --> @ to :D.) !o. ~ #» !w. ~  ~ # e ~Q#  1 2 3 4 R/W R/O SYS ARC :9.AQ:;.< ::.o& G >:Q:.e @ with CRC.:D.z ʴ } z 6ʜ #* ., 9ñ @ --- Aborted ---ÀH. `~6`2:.d!I.o. ~ww# H.!I. `} !͈4~3 @ Retagging --> > Q4͌#* ., À"@(~#a QS @)~ Q#j ".͵ *."".*. v,­ *.:.U$ R$ *.:.Rʽ U !0͂#*. 0!H.n. 6`!w.~ 6Q#6Q#6Q@(!o.j >.Q%j @)s*.!H.͘'}0!0D C @ Not a SQ file.">."B.:;.2;.!\n.6 `s!"| _h *B.,}0@ ERROR - Checksum error in file nngo͵ @ Premature EOF on file... aborted.À0*:9.G:.::.G:;.ȸ!H.n. `2n.!"@.sd*."5.:.–H.l"5.*7.,ܺCͺ}0 |g}o{))))))),*.*7.~y|±}ڳ.&],H.͇"5. ||¥ͺÖ͏ʀl&͇"5.l:.@ Verifying --> R!z.{.6`n..!]~ ʀ ~ µ6?#­@ !/€".À@ Tag what? @!!">.!]~ ʀ@ !/€@ Tagging --> ͈> Q4͌#* .,J͈]N/> ~?\#Q*.͈ ~2:.@ New name, or *? @!!">.!l#~ ʀ ?#¡:;.¶::.w*.͈. r*.* .#" .e2*.+" .".,ڀ!".À:.29.\2\ `d:e9:e2e:u2u\:;._::.F__!mI. `2H.H.*.͊}ʒ@ Destination file exists! rÀ:;.ʢG::.::.___\__!m `::.__!\H. `2H.>?2T.*.H.͊}ʽ" .H.R!mI. `H.!)))))*. T.`H..ý@ Directory full.À<¨!=!o `*7.,@ OUT OF MEMORY?<¨i`@ Old name? @!!">.!.:. ʀ:;.2 .@ New name? @!!">.!n.:o. ʀ9!͈.¢@ Renaming -->  ~2:.@ to !mG:2#* .,R9>. r~ F: .?G># ɯ/o.m> ?~#=:;.::.:.AQ n&} 5 >:QyJ> Qͧ>.QͧJ*.#@. #~#> Q@K : ʢ*ʢ#yQ~Q#§9>2=.92=.<23.@Press ^X to abort, L to advance a line, cr to advance a page. >2<.*.͈ v,!nD*."".!0D D9!"L*.""."bnu>-_ ‚:3.<23.:<.O:=.O:3.G:OLʹlʹ23.O:3.=23.O0ÀO iiX!T.U.6`H.2H. `~2:.d*.""." .H.<@ Can't open file!À__:9._:;._ :._::.^*."&."$."(.R"n.<:w.ʻ:w.2w."!w.E.`6$#6$#6$ ""<@ Destination disk directory full.À!z.{.6`dH.<@ Can't close file!ÀRn."Rn.<=m"!n.~.`!E..`n.<=!E.w.`:Q.G:w.2w.:y.2y.n.*(.*$.G,xw#"$.*$.*&.,R:.,n.Y*$.,*&."$.*&.*$.~}yC#|N}P.],n.V͏%* .*".,ʂ~#"".d*.""." . :.H.¼* ." .—n*".* .,n= ,*".H.͏*"." .n͏ʀl&͇*"." .ü* .!==~V# `~##~#~  x$>[I* .".+|*.|ȯ|g}o".„#".* .+}o|g".!".*.".*.*.".*.*.}o|g".á*.#".*.,oÛ*.͈".*.͈". ~O## *.*.Fwx# |}!".".#".* ." .Q͟h*.".#".* .+" .|E*.͈*.`*.#".*.͈".*.͈". #•*.~ F. x:.?G># ɷ!"-.* .#}!=*-."-. x',?,$?d,2?} =?yRR> Q=G ] |S{0Q }0*0#*0~.Ҙg xʩ|-“#Ï}o|g:*.ʽ)=õ"+.:._.*:GxG|g}o ý^)))))#~&o))))o$#:*.ZK<}>o}}o}}o}#~#`a{_:._<ʀ0`:02*."0L L* .9ͩ9L*>.!\w=L!\*>.:. O0O:77:.Lx,yH,py2;.ͷr#*b6?dwQͷyh#6 r.¢ͷʢ#*’6?ÔwͷʩØ#6 ¢#6«">. =_.:;<> !.!yg)>g>!or$s%# :.~#, *@.O!. ~W$^"@. @ ~#Q@ _{dldr_!u! ~#G~d#z))))= NSWEEP - Version 2.07 07/17/1984 (c) Dave Rand, 1983, 1984 Edmonton, Alberta $ A - Retag files : Q - Squeeze/Unsqueeze tagged files B - Back one file : R - Rename file(s) C - Copy file : S - Check remaining space D - Delete file : T - Tag file for mass E - Erase T/U files : U - Untag file& F - Find file : V - View file L - Log new disk/user : W - Wildcard tag of files M - Mass file copy : Y - Set file status P - Print file : ? - Display this help X - Exit to CP/M : cr, sp - Forward one file $"x#"z#!9""c#v]#>2t#2w#c#"~#*x#n͝"Gp#Œ"<"c#"#]#c">*z#"|#|ʓ"c#s#r#c#s#r#*|#+h"1>*x#*~#a{_USQ section (C) 1983, 1984 by Dave Rand (403) 484-4114!9"":w#"=2w#:v#####>==2w#:v#2v#:u#O:t#.#nŒ"O>=2t#yO*z#=###^#Vz#y2u#z>Z#{/|}nŒ"nŒ"go>2+"B,!9",1,*B,}o>͍+"+">,"@,&+2+W+#>Ð'vͨ+#>Ð'}2++|#c+?$!+$#456$~6 $G+~+#6$>+<+6$6$#4~#>+~6+:+2++#:+Q$>+<+*>,^#V#N#zl$#V$>Ð'~*@,w#s#r#q#"+>2+#^#V#N#~#2<,{$:+G*@,#ͮ+ڶ$####Ÿ$y2=,$*+y2=, }O|GT]+++:<,w#s#r#:=,w*+####"+:+<2+„$:+!*%45 %%%#%!*p27,28,l*g2+2+<27,29, '>29,! ,,ͻ+&29,!,:5,͍+::,Nw:6,/< 'G:;, '4x26,&!$,,+!,:5,͍+~2:,:6,&w:9,#%! ,,+#%>26,:*!5,4!'>28,#%~!,͍+~2;,&! ,̈́,2+*+))>͍+ ,",!",!,͒+~w6#w#w#w͒+̈́,!+̈́,*+* ,ͨ+>Ґ'*,* ,:+ʡ'"D,!9",1,!v(*+(!͡+"+*D,#~ ')#'>.)x͍+~ ')#')*+())*+~)#z(2+2+>2+c+v(c+(!+Y(#45v(~6J(G+~(=(v(>(<(v(v(#4~(>(~6(:+2+((:+ʑ(>(<(>́+###(:+ʰ(G:+¨()>2+*+|>(*,((́+F#^#V:+O{_zW:+ ()2+(y2+})|:8,I):+*+*+G:+Os#r#}0) z:)`)%)"+"+y2+!+4~`)2+!+~w:*=Gp)>':8,~):7,¤&!*p:8,#%28,27,#%́+:+w#*++2,,+!"," ,,!,e- ,!,͒+:+!$,͍+4!+5:8,)*+6:+O})7zW{_~*A+~+}* *~)*s#r*+/w#6#"+}!+4>́+###!I*͗)*+>+w+,կ++ä,**x!+4#4#4#4++*o&))*>,4#4#4ɯGO*>,w#w#w#q# ,+!+w#w#w#w#!+++!"+c+oc+gnk+*+͍+"+!+4#4#4*>,G͍+x͍+xo$շ#•+}o|g|}##~+~+~H + +x ~#+x ~++yxX+G]T~w+”,kb ,xG-"L-"N-Hi&)))#"T-!W-^-Aw#,!W-"P-!^-"R-*N-A#,C-A*L-~w#,!T-5,#5G-*P-A~w#-y2V-*R-DM*P-*N-#:V-=2V--?,*P-*R-"P-"R-,7H-*P-xH "-!- "-i`)))#"-A!-6#„-A*-+~w-kbA+~w›-Һ-*-!-Aw#°-!-5Œ-#455Ì-4#4#4++*o&))*>,4#4#4ɯGO*>,w#w#w#q# ,+!+w#w#w#w#!+++!"+c+oc+gnk+*+͍+"+!+4#4#4*>,G͍+x͍+xo$շ#•+}o|g|}##~+~+~H + +x ~#+x ~++yxX+G]T~w+”,kb ,xG-"L-"N-Hi&)))#"T-!W-^-Aw#,!W-"P-!^-"R-*N-A#,C-A*L-~w#,!T-5,#5G-*'