; ; MLIST.ASM - V3.4 ; by Keith Petersen, W8SDZ ; (revised 9/21/80) ; ; This program lists any size ASCII file by name, reading ; up to 16k of the file into memory at one time, in order ; to minimize disk activity during printout. ; ; Allows listing of multiple files by using ; normal CP/M ambiguous file names (i.e., ; MLIST *.ASM). Before each file is printed, ; the FILENAME.TYPE is displayed. ; ; Use CTL-S to pause, CTL-C to abort. ; Other characters are ignored. ; ; This program allows CP/M 1.4 users to have protected ; ASCII files on a remote system, provided that the CCP ; 'REN' (rename) and 'TYPE' functions have been changed ; to some other characters and MLIST.COM has been renamed ; to TYPE.COM. To protect a file, rename it so the last ; character of the file type is #. Example: MYFILE.AS# ; ; CP/M 2.x users may use 'TAG.COM' to set the f1' attribute ; of a file, which will prevent this program from listing it. ; ; ;05/27/80 Revised to abort on attempting to ; list a CP/M .COM file. TVC ; ;09/09/80 Revised check for '.COM' and '.OBJ' files so ; during attempt to list multiple files these ; would not abort the routine. Modified to ; issue an error message and continue with the ; next valid file. Added check for '#' character ; as the last character in the file type indicat- ; ing the file was not for distribution. Routine ; issues an error message and continues. Added ; check for 'first time flag' to exit routine so ; if no file is found meeting the requested ; parameters, '++NOT FOUND++' is issued to the ; console. NOTE: This required modifying the manner ; in which 'MFFLG1' was handled. J. Seymour ; ;09/20/80 Added ILPRT routine, revised messages, added new ; abort routine, added CP/M 2.x f1' protect test, ; cleaned up file. (KBP) ; ;09/21/80 Added test for SYS files, moved TAG test, ; removed extra OPEN of file. (KBP) ; ; NOTE: REQUIRES 'MAC' AND SEQIO.LIB TO ASSEMBLE ; ORG 100H ; MACLIB SEQIO ;DEFINE MACRO LIBRARY ; START: JMP START2 ;JMP AROUND IDENT DB 'MLIST.COM ver 3.4 9/21/80' ; START2: LXI H,0 DAD SP ;GET OLD STACK SHLD OLDSTK ;SAVE IT LXI SP,STACK;SET NEW STACK LHLD 1 ;POINT TO CP/M'S JMP TABLE LXI D,3 ;READY FOR ADD DAD D ;POINT TO CONSOLE STATUS SHLD CSTSC+1 ;MODIFY CALL ADDRESS DAD D ;POINT TO CONSOLE INPUT SHLD CIC+1 ;MODIFY CALL ADDRESS CALL ILPRT ;PRINT: DB 'MLIST ver 3.4',CR,LF DB 'CTL-S pauses, CTL-C aborts',0 LDA FCB+1 CPI ' ' ;SEE IF FILENAME THERE JNZ MORE CALL ILPRT ;PRINT: DB '++NO FILE NAME SPECIFIED++',0 JMP EXIT ; MORE: CALL MFNAME JNC CKFIL ;ANOTHER FILE FOUND, PRINT IT LDA MFFLG1 ;NOTHING FOUND, CHECK... ORA A ;... FIRST TIME FLAG JZ DONE ;AT LEAST ONE WAS FOUND CALL ILPRT ;PRINT: DB '++FILE NOT FOUND++',0 JMP EXIT ; DONE CALL ILPRT ;PRINT: DB 'DONE',0 JMP EXIT ; ;CHECK HERE FOR FILE PROTECTED BY CP/M 2.x f1' ATTRIBUTE ; CKFIL LDA MFCUR+1 ;POINT TO TAG FILE ATTR ANI 80H ;IS IT TAGGED? JZ CKFIL2 ;IF NOT, CONTINUE ; PROXIT CALL ILPRT ;PRINT: DB '++FILE NOT FOR DISTRIBUTION, SORRY++',0 JMP MORE ;SEE IF ANOTHER ; CKFIL2 LDA MFCUR+10 ;POINT TO SYS FILE ATTR ANI 80H ;IS IT SYS? JZ MOVNAM ;IF NOT, CONTINUE JMP PROXIT ;SYS FILE, CAN'T PRINT IT ; ;MOVE FILENAME FROM FCB+1 TO FNAME MOVNAM LXI H,FCB+1 LXI D,FNAME LXI B,8 CALL MOVER ;MOVE FILETYPE FROM FCB+9 TO FNAME+9 LXI H,FCB+9 LXI D,FNAME+9 LXI B,3 CALL MOVER CALL ILPRT ;PRINT: DB CR,LF,'--> FILE: ' FNAME DB 'XXXXXXXX.XXX' DB CR,LF,0 ; ; DEFINE SOURCE FILE: ; ; INFILE = INPUT FILE MODE ; DISKIN = INTERNAL NAME ; (NUL) = DEFAULT DISK DRIVE ; 1 = FIRST DEFAULT NAME (TFCB) ; (NUL) = " " TYPE ; 16384 = BUFFER SIZE ; DSKBUF = DISK BUFFER AREA ; FILE INFILE,DISKIN,,1,,16384,DSKBUF ; ;CHECK HERE FOR FILE PROTECTED BY A '#' AS THE LAST ;CHARACTER IN THE FILETYPE (EG. MLIST.AS#). ; LXI H,FCB+11 ;POINT TO LAST CHAR IN FCB MOV A,M ;GET IT ANI 7FH ;STRIP CP/M 2.x ATTR CPI '#' ;PROTECTED FILE? JZ PROXIT ;PROTECTED FILE, EXIT WITH MSG ; ;CHECK HERE FOR .COM FILE, WHICH CAN'T BE PRINTED ;EITHER ; CPI 'M' ;WAS LAST CHAR AN 'M'? JNZ OBJCHK ;IF NOT, CHK FOR '.OBJ' TYPE DCX H MOV A,M ;CHK NEXT ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'O' ;AN 'O'? JNZ READLP ;IF NOT IT'S OK TO PRINT DCX H MOV A,M ;WAS 'O', CHK NEXT CHAR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'C' ; 'C' AS IN '.COM'? JNZ READLP ;IF NOT, IT'S OK TO PRINT CALL ILPRT ;PRINT: DB '++CAN''T LIST A .COM FILE++',0 JMP MORE ;MORE TO PRINT? ; ;HERE WE CHECK FOR AN ATTEMPT TO LIST AN OBJECT FILE ; OBJCHK CPI 'J' ;WAS LAST CHAR AN 'J' THEN? JNZ READLP ;IF NOT, OK TO LIST DCX H MOV A,M ;MIGHT BE '.OBJ', CHK NEXT CHR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'B' ;IS IT A 'B'? JNZ READLP ;IF NOT, LIST DCX H MOV A,M ;WAS, CHK FIRST CHAR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'O' ; 'O' AS IN '.OBJ'? JNZ READLP ;IF NOT, PRINT THE FILE, IF SO CALL ILPRT ;PRINT: DB '++CAN''T LIST AN .OBJ FILE++',0 JMP MORE ;MORE TO PRINT? ; ;WRITE THE FILE TO CONSOLE ; READLP: GET DISKIN CPI EOF ;END OF FILE? JZ MORE ;YES, MORE FILES TO PRINT? CALL TYPE ;SEND CHAR TO CONSOLE CALL CSTS ;KEY PRESSED? ORA A CNZ CKKB ;CHECK WHAT KEY JMP READLP ; CKKB CALL CI ;SEE WHAT CHAR CPI 'S'-40H ;CTL-S? CZ CI ;YES, GET VALUE CPI 'C'-40H ;ABORT? JZ EXITA ;YES, PRINT ABORT MSG, EXIT RET ; CSTS PUSH B PUSH D PUSH H CSTSC CALL $-$ ;CHANGED BY INIT POP H POP D POP B RET ;FROM "CSTS" ; CI PUSH B PUSH D PUSH H CIC CALL $-$ ;CHANGED BY INIT POP H POP D POP B RET ;FROM "CI" ; ; ;INLINE PRINT ROUTINE ; CALL ILPRT ; DB 'MSG',0 ; ILPRT MVI A,CR CALL TYPE MVI A,LF CALL TYPE XTHL ;SAVE HL, GET MSG ; ILPLP MOV A,M ;GET CHAR CALL TYPE ;OUTPUT IT INX H ;POINT TO NEXT MOV A,M ;TEST ORA A ;..FOR END JNZ ILPLP MVI A,CR CALL TYPE MVI A,LF CALL TYPE XTHL ;RESTORE HL, RET ADDR RET ;RET PAST MSG ; ;TYPE CHAR IN A ; TYPE: PUSH B PUSH D PUSH H ANI 7FH ;STRIP PARITY BIT MOV E,A ;CHARACTER TO E FOR CP/M MVI C,WRCON CALL BDOS POP H POP D POP B RET ; EXITA MVI C,CSTAT ;GET CONSOLE STATUS CALL BDOS ORA A ;CHARACTER WAITING? MVI C,RDCON CNZ BDOS ;YES, CLEAR CHARACTER FROM CP/M CALL ILPRT ;PRINT: DB CR,LF,'++ABORTED++',0 ; EXIT LXI D,80H ;SET DMA ADDRESS TO NORMAL MVI C,STDMA ;FUNCTION NUMBER TO DO IT CALL BDOS ;DO IT LHLD OLDSTK ;GET OLD STACK SPHL ;RESTORE IT RET ;RETURN TO CP/M ; ;MULTI-FILE ACCESS SUBROUTINE. ALLOWS PROCESSING ;OF MULTIPLE FILES (I.E. *.ASM) FROM DISK. THIS ;ROUTINE BUILDS THE PROPER NAME IN THE FCB EACH ;TIME IT IS CALLED. CARRY IS SET IF NO MORE NAMES ;CAN BE FOUND. THE ROUTINE IS COMMENTED IN PSEUDO ;CODE, EACH PSEUDO CODE STATEMENT IS IN <<...>> ; MFNAME: ;<> MVI C,STDMA LXI D,80H CALL BDOS XRA A STA FCBEXT STA FCBRNO ;<> LDA MFFLG1 ORA A JZ MFN01 ;<> ;SAVE ORIG REQ LXI H,FCB LXI D,MFREQ LXI B,12 CALL MOVER LDA FCB STA MFCUR ;SAVE DISK IN CURR FCB ;<> LXI H,MFREQ LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHF LXI D,FCB CALL BDOS ;<> JMP MFN02 ; MFN01: ;<> LXI H,MFCUR LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHF LXI D,FCB CALL BDOS ;<> LXI H,MFREQ LXI D,FCB LXI B,12 CALL MOVER MVI C,SRCHN LXI D,FCB CALL BDOS ;<> MFN02: ;<> INR A STC RZ ;<> DCR A ANI 3 ADD A ADD A ADD A ADD A ADD A ADI 81H MOV L,A MVI H,0 PUSH H ;SAVE NAME POINTER LXI D,MFCUR+1 LXI B,11 CALL MOVER ;<> POP H LXI D,FCB+1 LXI B,11 CALL MOVER ;<> XRA A STA FCBEXT STA FCBRNO STA MFFLG1 ;TURN OFF 1ST TIME SW ;<> RET ;------------------------------------------------ ; ;MOVE SUBROUTINE ; MOVER MOV A,M STAX D INX H INX D DCX B MOV A,B ORA C JNZ MOVER RET ; ;MULTI-FILE ACCESS WORK AREA ; MFFLG1 DB 1 ;1ST TIME SW MFREQ DS 12 ;REQ NAME MFCUR DS 12 ;CURR NAME ; DS 60 ;STACK AREA STACK: EQU $ OLDSTK: DS 2 ;OLD STACK POINTER SAVED HERE ; DSKBUF: DS 16384 ;16K BUFFER ; ;BDOS/CBIOS EQUATES ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CSTAT EQU 11 OPEN EQU 15 SRCHF EQU 17 SRCHN EQU 18 STDMA EQU 26 BDOS EQU 5 FCB EQU 5CH FCBEXT EQU FCB+12 FCBRNO EQU FCB+32 ; END