;LIST.ASM VERSION 2.0 11/29/77 ;LIST.ASM VERSION 1.9 11/21/77 JRB ; ; IMDOS FILE LIST UTILITY ; ; LISTS DISK FILE ON "LST:" DEVICE ; FCB FOR FILE MUSTBE 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 RUBOUT. ; OUPUT DEVICE IS ASSUMED TO HAVE 66 LINES PER PAGE ; ; THIS PROGRAM IS CODED TO RUN UNDER CP/M OR IMDOS ; ; COPYRIGHT (C) 1976,1977 ; IMSAI MANUFACTURING COMPANY, 14860 WICKS BLVD, SAN LEANDRO, CA 94577 ; PGSIZ EQU 66 ;NUMBER OF LINES PER PAGE PRINTPERPAGE EQU 60 ;NUMBER OF LINES TO PRINT PER PAGE PAGNUMCOL EQU 64 ;COLUMN FOR WORD "PAGE" AND NUMBER 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 $ LIST EQU 5 ;OUT CHAR (E) TO LST: DEVICE OPEN EQU 15 ;OPEN FILE CONTROL BLOCK READ EQU 20 ;READ NEXT SEQUENTIAL RECORD FCB EQU 5CH ;SYSTEM DEFAULT FILE CONTROL BLOCK NR EQU FCB+32 ;NEXT RECORD TO READ TBUFF EQU 80H ;WHERE CCP PUTS COMMAND LINE DEFBUF EQU 80H ;WHERE SECTORS ARE READ 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 TAKE VTAB (^K) AS FORM FEED CAUSE OF EDITOR BUG CR EQU 0DH ;CARRIAGE RETURN CTRLZ EQU 1AH ;CONTROL Z. EOF. POFF EQU 82H ;CHARACTER TO TURN LINE PRINTER OFF ;NOTE: AFTER THE WORD PAGE THERE IS A CONTROL-K, ;WHICH CAUSES PAGE FEED WHEN LISTED WITH THIS LISTER ;PAGE 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 ; COPYRIGHT INFORMATION FOR OBJECT IDENTIFICATION DB 'COPYRIGHT (C) 1977, IMSAI MFG CORP, MADE IN USA' ; ; ;FORMAT CONTROL FLAGS. YOU CAN CHANGE THESE WITH DDT OR BY EDIT-ASSEMBLE. TITLFLAG: DB 0FFH ;MAKE 0 TO SUPPRESS TITLE PAGNUMFLAG: DB 0FFH ;MAKE 0 TO SUPPRESS PAGE NUMBERS ;POINTER TO TITLE BUFFER. YOU CAN CHANGE THIS TO POINT AT TEXT ASSEMBLED ; ELSEWHERE IN PROGRAM, OR ADD CUSTOM TEXT AT REGULAR BUFFER. ;SEE COMMENTS AT TITLBUF (AT END). TITLPOINT: DW TITLBUF ; ***************************************************************** ; ; MAIN PROGRAM BEGINS HERE ; LISTGO: LXI H,0! DAD SP! SHLD CALLERSP! LXI SP,STACK ; ; SIGN-ON MESSAGE ; CALL INLMSG! DB 'LIST VERS 2.0 ',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 CIB9: ; ; SET UP TITL: DEFAULT TO WHAT WAS TYPED AFTER "LIST". ; ;THUS TITL CONSISTS OF FILE NAME AND ANYTHING USER TYPES AFTER IT LHLD TITLPOINT! XCHG ;WHERE TO PUT TEXT LXI H,TBUFF ;WHERE CCP LEFT TEXT MOV C,M ;NUMBER OF CHARS IN TBUFF MVI B,123 ;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 TITL9: ;PAGE ; ;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. 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 ; ; INIT OUTPUT ; XRA A! STA COL! STA LINE ;INIT CURSOR POSITION STA PAGE+1! INR A! STA PAGE ;.. PAGE STARTS AT DW 1 MVI A,FF! CALL LOCH ;SEND HARDWARE FORM FEED ;(NOP TO TTY; NOP TO LPT: ;IF ALREADY AT TOP OF FORM) ; PRINT TITL FOR FIRST PAGE CALL PTITL ; PASS ANY CR'S, LF'S, FORM FEEDS, ETC AT BEGINNING OF FILE ; (NOTE THAT WE HAVE ALREADY SENT A FORM FEED TO POSITION PAPER) 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 ; ; END OF FILE. FORM FEED AND EXIT. ; EOF: CALL LISFFSUB ;OUTPUT FF WITHOUT TITLE AND WO INF LOOPS ;TURN LPT MOTOR OFF. SHOULDN'T BOTHER OTHER DEVICES. MVI A,POFF! CALL LOCH ;EXIT ROUTINE EXIT: LHLD CALLERSP SPHL ;RESET SP FOR CCP MVI A,0 ;SAY NO ERROR 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 A SUBROUTINE ; NEWREC: MVI C,READ! LXI D,FCB! CALL BDOS ;READ RECORD CPI 1! JZ EOF ;IF END OF FILE ORA A! JNZ NSERR ;CHECK FOR GOOD RETURN FROM BDOS LXI H,ICOUNT! MVI M,128 ;INITBUFFER COUNTER LXI H,DEFBUF! SHLD IPOINT ;INIT BUFFFER POINTER POP H ;ENTRY POINT: INCH: PUSH H! LXI H,ICOUNT! DCR M ;COUNT CHARS USED FROM RECORD JM NEWREC ;IF RECORD USED UP, GET ANOTHER 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 ;PAGE ; ; *********************************** ; ; 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 POPLOC: 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... ;PAGE ;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... XRA A! LHLD PAGE! INX H! SHLD PAGE ;...TOP OF NEXT PAGE 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 LPOPX: POP PSW! RET ; LSC5: ;ADD CHARACTERS HERE ; ;MISCELLANEOUS CHARACTERS, PRINT ^ AND LETTER MVI A,'^'! CALL LSTCH! POP PSW! ORI 40H! 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 ; ;LIST OUTPUT CHAR IN A, WITHOUT PROCESSING ; LOCH: MOV E,A MVI C,LIST JMP BDOS ;PAGE ; ; 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 PAGNUMFLAG! 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 PAGE! CALL DECPR NOPAGNUM: ;TEST IF EITHER OF ABOVE WAS PRINTED LHLD TITLFLAG! LDA PAGNUMFLAG! 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 ;AD 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 ;PAGE ; ; 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 CALLEN: CALL BDOS RETREGS: 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 100H ;REST OF TITLE BUFFFER ; IPOINT: DS 2 ;INPUT BUFFER POINTER ICOUNT: DS 1 ;INPUT BUFFER DOWN-COUNTER ; COL: DS 1 LINE: DS 1 PAGE: DS 2 CALLERSP: DS 2 ;CALLER'S STACK POINTER ; ; DS 80 STACK: DS 4 DSTACK: DS 2 ; END LISTER