TITLE 'GENERAL FILE LISTER PROGRAM' ;LIST.ASM VERSION 2.2L 800819 A. I. LARKY ;LIST.ASM VERSION 2.1L 800329 A.I.LARKY ;LIST.ASM VERSION 2.0L 790723 A.I.LARKY ;LIST.ASM VERSION 2.0 11/29/77 ;LIST.ASM VERSION 1.9 11/21/77 JRB ; ; LISTS DISK FILE ON "LST:" DEVICE ; FILE FCB MUST BE SET UP BEFORE ENTRY, ; AS FROM CCP "LIST NAME.TYP" COMMAND ; OR DDT "INAME.TYP" COMMAND. ; OUTPUT DEVICE IS CHANGEABLE BY MANIPULATING ; IO STATUS BYTE. ; LISTING CAN BE ABORTED BY TYPING ANYTHING. ; OUTPUT DEVICE IS ASSUMED TO HAVE 'PGSIZ' (66) ;LINES PER PAGE. ; MODIFIED BY A. I. LARKY ; TO ASK FOR STARTING PAGE NUMBER ; IF TITLE IS #T, DON'T PRINT A TITLE ; IF TITLE IS #P, DON'T PRINT PAGE NUMBER ; IF TITLE IS #B, OMIT BOTH TITLE AND PAGE NUMBER ; IF NUMERIC AFTER #, #B, #P, #T : START PRINTING ; AT THAT PAGE NUMBER. ; TO USE A 1K (OR LARGER) TEXT BUFFER ; PGSIZ EQU 66 ;NUMBER OF LINES PER PAGE PRINTPERPAGE EQU 60 ;NUMBER OF LINES TO PRINT/PAGE PAGNUMCOL EQU 70 ;COLUMN FOR WORD "PAGE" AND NO. BUFSIZE EQU 64 ;# OF SECTORS IN BUFFER UOPT EQU 0 ;UPPER CASE ONLY PRINTER (=1) BDOS EQU 5 ;SYSTEM CALL ENTRY POINT ;SYSTEM CALL FUNCTION NUMBERS CONIN EQU 1 ;CONSOLE INPUT CHAR CONOUT EQU 2 ;CONSOLE OUTPUT CHAR (E) CONRDY EQU 11 ;CONSOLE CHARACTER READY TEST PRINT EQU 9 ;PRINT STRING (DE) TO $ READCN EQU 10 ;READ CONSOLE BUFFER LIST EQU 5 ;OUT CHAR (E) TO LST: DEVICE OPEN EQU 15 ;OPEN FILE CONTROL BLOCK READ EQU 20 ;READ NEXT SEQUENTIAL RECORD SETDMA EQU 26 ;SET BUFFER ADDRESS FOR R/W FCB EQU 5CH ;DEFAULT FILE CONTROL BLOCK FLAGS EQU FCB+17 ;LOCATION OF FLAG INFO NR EQU FCB+32 ;NEXT RECORD TO READ TBUFF EQU 80H ;WHERE CCP PUTS COMMAND LINE TBASE EQU 100H ;TRANSIENT PROGRAM BASE ;EQUATES FOR ASCII CONTROL CHARACTERS TAB EQU 9 ;^I. TAB. LF EQU 0AH ;LINE FEED FF EQU 0CH ;FORM FEED ALTFF EQU 0BH ;ALSO USE VT (^K) AS FORM FEED SPCHR EQU "#" ;LEADIN FOR OPTIONS CR EQU 0DH ;CARRIAGE RETURN CTRLZ EQU 1AH ;CONTROL Z. EOF. POFF EQU 82H ;CHARACTER TO TURN LINE PRINTER OFF ; ORG TBASE ; ; ENTRY POINTS ; LISTER: JMP LISTGO ;NORMAL ENTRY LXI SP,DSTACK ;DDT DEBUGGING ENTRY CALL LISTGO ;USE "I" COMMAND TO SET FILE NAME RST 7 ;RETURN TO DDT ; ;FORMAT CONTROL FLAGS. YOU CAN CHANGE THESE WITH ;DDT OR BY EDIT-ASSEMBLE. ; TITLFLAG: DB 0FFH ;MAKE 0 TO SUPPRESS TITLE TITLLEN EQU PAGNUMCOL-2 ;MAX TITLE SIZE PGNMFL: DB 0FFH ;MAKE 0 TO SUPPRESS PAGE NUMBERS ;POINTER TO TITLE BUFFER. YOU CAN CHANGE THIS ;TO POINT AT TEXT ASSEMBLED ELSEWHERE IN PRO- ;GRAM, OR ADD CUSTOM TEXT AT REGULAR BUFFER. ;SEE COMMENTS AT TITLBUF (AT END). ; TITLPOINT: DW TITLBUF STARTPAG: DW 0 ;SET TO STARTING PAGE NUMBER NOPRINT: DB 0 ; 0 = OK TO PRINT ; *********************************************************** ; ; MAIN PROGRAM BEGINS HERE ; LISTGO: LXI H,0 DAD SP SHLD CALLERSP LXI SP,STACK ; ; SIGN-ON MESSAGE ; CALL INLMSG DB 'LIST VERS 2.2L - 800819',CR,LF,'$' ; ; ;CLEAR INPUT BUFFER SO DOUBLE-ENTERED CR AFTER ;COMMAND WON'T ABORT LIST MVI C,CONRDY CALL BDOS RAR JNC CIB9 ;IF NO CHARACTER MVI C,CONIN CALL BDOS ;GET (AND IGNORE) CHARACTER ; ; SET UP TITL: DEFAULT TO WHAT WAS TYPED AFTER "LIST". ; ;TITL CONSISTS OF FILE NAME AND ANYTHING USER TYPES AFTER IT CIB9: LXI H,FLAGS ;SEE IF SPECIAL FLAGS MOV A,M CPI SPCHR JNZ NOFLAG ;NOTHING SPECIAL ; NOW THAT WE FOUND THE SPCHR, FIND IT IN OTHER BUFFER LXI H,TBUFF FINDIT: INX H MOV A,M CPI SPCHR JNZ FINDIT ;NOT THERE YET MVI M,' ' ;WIPE IT OUT INX H MOV A,M ;GET FLAG SUI 'B' STA PGNMFL ;TURN OFF PAGE NUMBER (IF 0) STA TITLFLAG ;THIS TURNS OFF TITLE (IF 0) JZ NUMS ;FOUND PROPER FLAG, SO DONE SUI 'T'-'B' STA TITLFLAG ;TURN OFF TITLE ONLY (IF 0) JZ NUMS ;DONE NOW ADI 'T'-'P' STA PGNMFL ;TURN OFF PAGE NUMBER (IF 0) JZ NUMS ;ON TO CHECK PAGE NUMBER DCX H ;NO CODE, SO LOOK BACK ; SEE IF STARTING PAGE NUMBER FOLLOWS ; CAN FOLLOW THE # OR THE #B, #T, #P. NUMS: MVI M,' ' ;WIPE THE CODE CHARACTER MVI C,0 ;DIGIT COUNT LXI D,BUFFER-1 ; DIGIT SAVE LOCATION PUSH D ;SAVE START NUMS1: INX D INX H ;TO NEXT DIGIT MOV A,M ;GET ONE CHARACTER CPI '0' JC NUMS2 ;NOT A DIGIT CPI '9'+1 JNC NUMS2 ;NOT A DIGIT STAX D ;SAVE THE DIGIT MVI M,' ' ;WIPE IT OUT INR C ;COUNT DIGITS JMP NUMS1 ; NUMS2: MVI A,' ' STAX D ;TRAILING BLANK FOR STOPPER POP D ;START OF DIGITS XRA A ADD C JZ NOFLAG ;NO DIGITS HERE LXI H,0 ;INITIALIZE PAGE NUMBER CALL WHERE2 ;GET PAGE NUMBER NOFLAG: LHLD TITLPOINT XCHG ;WHERE TO PUT TEXT LXI H,TBUFF ;WHERE CCP LEFT TEXT MOV C,M ;NUMBER OF CHARS IN TBUFF MVI B,TITLLEN ;MAX # CHARS TO USE LDAX D ORA A JNZ TITL9 ;IF OTHER TEXT IS THERE, LEAVE IT ;ABOVE IS A PROVISION FOR USER MODIFICATION ;COPY TEXT TITLUP: DCR C JM TITL2 ;STOP IF INPUT USED UP INX H MOV A,M STAX D INX D ;MOVE 1 CHARACTER DCR B JNZ TITLUP ;STOP AT MAX # CHARS ;TERMINATE WITH 0 TITL2: XRA A STAX D ; ;INIT INPUT ; ; MAKE SURE NO ?'S IN FILE NAME: ; IF AFN IS GIVEN, DIRECTORY ENTRIES GET CHANGED ; TO ?'S ON AUTOMATIC CLOSES ON GOING TO ; NEXT EXTENT, AND SUCCESSIVE EXTENTS ; ARE NOT NECESSARILY OF THE SAME FILE. ; CCP TRANLATES *'S TO MULTIPLE ?'S. ; TITL9: LXI H,FCB ;WHERE NAME IS MVI C,11 ;NUMBER OF CHARS LXI D,EMQUES ;MESSAGE TO USE IF ? FOUND QLUP: INX H ;POINT NEXT CHARACTER MOV A,M ;GET CHARACTER CPI '?' JZ TERM ;JMP IF ? DCR C ;COUNT CHARACTERS TO TEST JNZ QLUP ;LOOP BACK UNLESS DONE ; OPEN FILE MVI C,OPEN LXI D,FCB CALL BDOS ;CALL SYSTEM CPI 255 LXI D,EMFNF ;MESSAGE IF ERROR JZ TERM ;IF NOT FOUND, ERROR EXIT XRA A STA NR ;SAY START AT RECORD 0 STA ICOUNT ;SAY EMPTY INPUT BUFFER STA ICOUNT+1 LDA STARTPAG ANA A JNZ INIT2 ;PAGE NUMBER KNOWN ALREADY ; ; FIND OUT WHERE TO START ; CALL INLMSG DB 'ENTER STARTING PAGE NUMBER - ',CR,LF,'$' MVI C,READCN LXI H,BUFFER MVI M,5 ;NO OF CHARS TO READ XCHG CALL BDOS ;READ CONSOLE BUFFER LXI H,0 ;CLEAR NUMBER AREA LXI D,BUFFER+1 ;CHARACTER COUNT WORD LDAX D MOV C,A ;SAVE CHARACTER COUNT CALL WHERE2 ;GET DIGITS BINARIZED ; ; INIT OUTPUT ; INIT2: XRA A STA COL STA LINE ;INIT CURSOR POSITION STA PAGEN+1 INR A STA PAGEN ;.. PAGE STARTS AT DW 1 LHLD PAGEN ;GET PAGE FOR CHECK STA NOPRINT ;START WITH PRINT OFF CALL PCHECK ;CHECK PRINT/NOPRINT FLAG ; PRINT TITL FOR FIRST PAGE CALL PTITL ; PASS ANY CR'S, LF'S, FORM FEEDS, ETC AT BEGINNING OF FILE CALL IGNORE ;PASS FF'S ETC, GET CHAR IN A JMP CLOOP1 ;ENTER CHARACTER LOOP ; ; LIST RECORD -- OUTPUT CHARACTER LOOP ; CLOOP: CALL INCH ;GET CHARACTER CLOOP1: PUSH B PUSH H CALL LSTCH ;PROCESS & LIST 1 CHAR ; CHECK CONSOLE STATUS, ABORT IF CHAR TYPED MVI C,CONRDY CALL BDOS RAR ;TEST LSB JC EOF POP H POP B JMP CLOOP ; ; PAGE NUMBER BINARIZATION ; WHERE2: INX D LDAX D ;GET THE CHARACTER CPI ' ' JZ WHERE4 ;SPACES STOP IT PUSH D ;START TO DECIMALIZE MOV E,L ;GET COPY OF CURRENT NUMBER MOV D,H DAD H ;2*N DAD H ;4*N DAD D ;5*N DAD H ;10*N POP D ;BUFFER ADDRESS CPI CR JZ WHERE4 ;CR IS END OF LIST SUI '0' ;DE-ASCII-IZE ADD L ;INSERT NEW DIGIT MOV L,A MOV A,H ACI 0 ;CARRY CORRECTION MOV H,A DCR C JNZ WHERE2 WHERE4: SHLD STARTPAG RET ; ; END OF FILE. FORM FEED AND EXIT. EOF: CALL LISFFSUB ;OUTPUT FF W/O TITLE AND WO INF LOOPS ;TURN LPT MOTOR OFF. SHOULDN'T BOTHER OTHER DEVICES. MVI A,POFF CALL LOCH ;EXIT ROUTINE EXIT: MVI C,SETDMA LXI D,TBUFF CALL BDOS ;RESET CP/M DEFAULT BUFFER LHLD CALLERSP SPHL ;RESET SP FOR CCP RET ; ; ERROR STUFF ; NSERR: LXI D,MERR ;MISCELLANEOUS ERRORS TERM: ;COME HERE W/ DE POINTING TO TEXT MVI C,PRINT CALL BDOS JMP EXIT ; MERR: DB CR,LF,'SOME KIND OF ERROR',CR,LF,'$' EMFNF: DB LF,'FILE NOT FOUND',CR,LF,'$' EMQUES: DB LF,'NO *''S OR ?''S PLEASE!',CR,LF,'$' ; ; ****************************** ; ; INPUT CHARACTER TO ACC ; NEWREC: MVI C,BUFSIZE ;# OF SECTORS TO READ XRA A STA ICOUNT STA ICOUNT+1 LXI H,BUFFER SHLD IPOINT NEWR2: PUSH B XCHG MVI C,SETDMA CALL BDOS MVI C,READ ;READ ANOTHER SECTOR LXI D,FCB CALL BDOS ;READ RECORD CPI 1 POP B JZ NEWR3 ;IF END OF FILE ORA A JNZ NSERR ;CHECK FOR GOOD RETURN FROM BDOS LXI D,128 LHLD ICOUNT DAD D SHLD ICOUNT LHLD IPOINT DAD D ;NEXT 128 FOR BUFFER SHLD IPOINT DCR C ;COUNT SECTORS JNZ NEWR2 ;MORE NEWR3: LHLD IPOINT MVI M,CTRLZ ;CRTL-Z AT END OF BUFFER LXI H,BUFFER SHLD IPOINT ;INIT BUFFFER POINTER POP H ;ENTRY POINT: INCH: PUSH H LXI D,-1 LHLD ICOUNT DAD D ;COUNT CHARS USED FROM RECORD MOV A,H ANA A JM NEWREC ;IF RECORD USED UP, GET ANOTHER SHLD ICOUNT LHLD IPOINT ;GET BUFFER POINTER MOV A,M ;FETCH CHARACTER CPI CTRLZ JZ EOF ;ON EOF GO DIRECT TO EOF ROUTINE INX H SHLD IPOINT ;POINT NEXT POP H RET ; ; *********************************** ; ; LIST CHAR IN A WITH PROCESSING OF SPECIAL CHARS ; ; KEEPS TRACK OF COLUMN, LINE, PAGE. ; EXPANDS TABS WITH STOPS EVERY 8 COLUMNS ; SIMULATES FORM FEEDS WITH LINE FEEDS. ; LSTCH: ;INCREMENT COLUMN COUNTER LXI H,COL INR M ;IGNORE PARITY BIT IN CHARS FFROM FILE ;(NOTE: ELSE CERTAIN CHARS CAN PRODUCE INFINITE LOOP OF ^'S. ; ONLY CHANGE FOR VERSION 1.3) ANI 7FH ;SPACE OR GREATER ASCII CODE JUST GETS PRINTED CPI ' ' JP LOCH ;GO PRINT IT DCR M ;ELSE RESTORE COLUMN COUNTER ;PROCESS SPECIALS PUSH PSW ; CPI CR JNZ LSC2 XRA A STA COL POP PSW ;GET CHAR BACK JMP LOCH ;GO LIST IT ; LSC2: CPI LF JNZ LSC3 LDA LINE CPI PRINTPERPAGE-1 JP LISFF ;PAGE FULL, MAKE LIKE FORM FEED POP PSW ;NORMAL CASE:CLEAR STACK AND... ;PROCESS AND PRINT LINE FEED LISLF: PUSH PSW MVI A,LF CALL LOCH ;OUTPUT LINE FEED LDA LINE INR A ;LINE+1 CPI PGSIZ JM LSC2A ;BUT IF BOTTOM OF PAGE, MAKE IT... LHLD PAGEN INX H SHLD PAGEN ;...TOP OF NEXT PAGE CALL PCHECK XRA A ;PRINT CHECKl LINE NUMBER RESET LSC2A: STA LINE POP PSW RET ; LSC3: CPI ALTFF JZ LISFF ;ALTERNATE FORM FEED CPI FF JNZ LSC4 ;PRINT CR, LF'S TILL LINE=0 LISFF: CALL LISFFSUB ;SIMULATE FFORM FEED ;NEED A TITLE AT TOP OF NEXT PAGE, BUT FIRST SEE IF ANY MORE ;NON-CR, NON-LF, NON-FF CHARACTERS IN FILE. ;THIS IT AVOIDS BLANK SPACE AT TOP OF PAGE. CALL IGNORE ;PASS CR, FF, ETC, GET NEXT CHAR IN A ;IF HERE, NOT AT EOFF AND NEXT CHAR IS IN A CALL PTITL ;PRINT TITLE POP H JMP LSTCH ;CLEAR STACK, GO LIST CHAR ; LSC4: CPI TAB JNZ LSC5 ;PRINT SPACES TILL LO 3 BITS OF COL = 0 LSC4A: MVI A,' ' CALL LSTCH LDA COL ANI 7 JNZ LSC4A POP PSW RET ; LSC5: ;ADD CHARACTERS HERE ; ;MISCELLANEOUS CHARACTERS, PRINT ^ AND LETTER MVI A,'^' CALL LSTCH POP PSW ORI 40 JMP LSTCH ; ; PROCESS AND OUTPUT (SIMULATED) FORM FEED LISFFSUB: MVI A,CR CALL LSTCH LSFF2: LDA LINE ORA A CNZ LISLF JNZ LSFF2 RET ;SUBROUTINE TO IGNORE CR'S, LF'S, FORM FEEDS. CALLED AT TOP ;OF EACH PAGE. RETURNS NEXT NON-IGNOORED CHARACTER IN A. ;TERMINATES LIST IF EOF ENCOUNTERED. IGNORE: CALL INCH ;INPUT CHARACTER OF SOURCE FILE TO A CPI CR JZ IGNORE CPI LF JZ IGNORE CPI FF JZ IGNORE CPI ALTFF JZ IGNORE RET ;CHARACTER IS IN A ; CHECK FOR AT OR PAST STARTING PAGE PCHECK: XCHG LHLD STARTPAG MOV A,D SUB H RNZ ;NOT THE SAME MOV A,E SUB L RC ;NOT .GE. ;PAGE MATCHES, SO SET TO PRINT XRA A STA NOPRINT RET ; ; ;LIST OUTPUT CHAR IN A, WITHOUT PROCESSING ; LOCH: IF UOPT ; COPE WITH UPPER-CASE ONLY PRINTERS CPI 'a' JC NUPC CPI 'z'+1 JNC NUPC ANI 5FH ;SHIFT TO UPPER CASE ENDIF ; NUPC: MOV E,A LDA NOPRINT ORA A RNZ ;NOT ALLOWED TO PRINT THIS MVI C,LIST JMP BDOS ; ; SUBROUTINE TO PRINT PAGE TITL ; PTITL: PUSH PSW PUSH H ;TITLE TEXT LDA TITLFLAG ORA A JZ NOTITL LHLD TITLPOINT CALL LSTRING NOTITL: ;PAGE NUMBER LDA PGNMFL ORA A JZ NOPAGNUM ;SPACE TO COLUMN PAGN1: MVI A,' ' CALL LSTCH ;MINIMUM ONE SPACE LDA COL SBI PAGNUMCOL JM PAGN1 ;"PAGE" TEXT LXI H,PAGETXT CALL LSTRING ;NUMBER LHLD PAGEN CALL DECPR NOPAGNUM: ;TEST IF EITHER OF ABOVE WAS PRINTED LHLD TITLFLAG LDA PGNMFL ORA L JZ PTITLEX ;NO, NEED NO CRLF'S ;CR AND 2 LF'S MVI A,CR CALL LSTCH MVI A,LF CALL LSTCH MVI A,LF CALL LSTCH PTITLEX: POP H POP PSW RET ; PAGETXT: DB 'PAGE ',0 ;SUBR TO LIST STRING (HL) TO NULL LSTRING: MOV A,M ORA A RZ INX H PUSH H CALL LSTCH POP H JMP LSTRING ; ; DECIMAL PRINT HL, UNSIGNED ; DECPR: PUSH B PUSH D PUSH H LXI B,-10 ;MINUS RADIX LXI D,-1 ;BECOMES NUMBER DIVIDED BY RADIX DECPR1: DAD B INX D JC DECPR1 ;SUBTRACT TILL NEGATIVE LXI B,10 DAD B ;ADD RADIX BACK ONCE XCHG ;HAVE N/10 IN HL, REMAINDER IN DE MOV A,H ORA L CNZ DECPR ;PRINT DIGITS LEFT OF THIS IF ANY MOV A,E ADI '0' CALL LOCH ;PRINT THIS DIGIT POP H POP D POP B RET ; ; OUTPUT IN-LINE MESSAGE TO CONSOLE INLMSG: XTHL ;SAVE H, GET TEXT LOCATION PUSH PSW MOV A,M INLML: CALL CONO INX H MOV A,M CPI '$' JNZ INLML ;$ ENDS TEXT INX H POP PSW XTHL RET ;RETURN AFTER TEXT ; ;OUTPUT CHAR FROM A CONO: PUSH PSW PUSH B PUSH D PUSH H MOV E,A MVI C,CONOUT CALL BDOS POP H POP D POP B POP PSW RET ; ;IF YOU WANT A SPECIAL TITLE, PATCH OR ASSEMBLE TEXT IN HERE ;TERMINATE WITH 0. ;IF BUFFER BEGINS WITH 0, INIT CODE COPIES OPERATOR'S TITLE IN. TITLBUF: DB 0 ;SAYS NO TITLE HERE YET DS TITLLEN ;REST OF TITLE BUFFFER ; IPOINT: DS 2 ;INPUT BUFFER POINTER ICOUNT: DS 2 ;INPUT BUFFER DOWN-COUNTER ; COL: DS 1 LINE: DS 1 PAGEN: DS 2 CALLERSP: DS 2 ;CALLER'S STACK POINTER ; ; DS 84 ;STACK ROOM STACK: EQU $ DSTACK: DS 2 ; BUFFER DS 1+BUFSIZE*128 ; END LISTER