Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-07 - decus/20-0163/cdirs.mac
There are no other files named cdirs.mac in the archive.
;Multi-column directory program by Joshua Brodsky
;Completed 12/30/80 as a gift to Mr. George Glenn. Final version 4.25.
;Revised 12/4/81 for submission to DECUS.

	TITLE DIREC - Multi-column directory lister.
	SEARCH MONSYM,MACSYM

;This program is capable of printing any number of columns per listing
;From 2 up. 5 columns work best on 80-column terminals, but if you
;use a 132 column terminal, 8 columns will fit.
	COLUMN==5				;Columns per listing.

;Define accumulator names:
	A==1					;Multi-purpose AC's.
	B==2
	FLAGS==3				;Flags for JFNS here.
	INDEX==16
	LINE==5					;Line number variable.
	T1==6					;Temporary storage.
	T2==7
	T3==10
	FILES==11				;Count of files printed.
	TABS==12				;Count of tabs.
	GENER==13				;Number of generations.
;Gener is used to calculate how many files were printed, and did not
;have their own line.
	NUL==14					;Blank used as a null.
;AC's 15 and 16 are not used.
	P==17					;Stack pointer.

START:	RESET					;Reset all
	RSCAN
	  JRST ERROR
	CAIL 1,7
	JRST READ
	MOVEI 1,.PRIIN
	CFIBF
	MOVE A,[GJ%OLD+GJ%IFG+GJ%FLG+GJ%SHT]	;Flags,short,wildcards
	MOVE B,[POINT 7,FILE]			;Default specification
	JRST GET				;Go join read for GTJFN
READ:	REPEAT 6,<PBIN>
READ2:	MOVEI A,GTBLK
	SETZ B,
GET:	GTJFN					;Join default to GTJFN
	  JRST ERROR				;Error address
	MOVE INDEX,A				;Save flags for GNJFN
	MOVEI 1,-1
	RFCOC
	TXO 2,1B34
	TXZ 2,1B35
	TXO 3,1B2
	TXZ 3,1B3+1B8+1B9
	SFCOC
	MOVEI 1,.PRIIN
	BKJFN
	  JRST ERROR
	PBIN
	CAIE 1,"/"
	JRST ..REC
	MOVEI 1,^D17
	PBOUT
	SETOM PRINTR

..REC:	SETZ LINE,
	SETZ FILES,
	SETZ TABS,
	SETZ GENER,
	SETZ NUL,
	MOVE P,[IOWD ^D1000,POINTR]		;Set up stack pointer
	PUSH P,NUL				;Start with a NULL
;This section prints the structure and directory. It can be deleted
;without affecting the rest of the program.
	HRROI A,[ASCIZ/
  /]
	PSOUT					;Indent for directory
	MOVEI A,.PRIOU				;Set up JFNS
	HRRZ B,INDEX				;Clear flags from JFN
	MOVE FLAGS,[1B2+1B5+JS%PAF]		;Output only directory
	JFNS					;Print it.
	HRROI A,[ASCIZ/
/]						;New line
	PSOUT					;Output it.

SETUP:	MOVE A,[POINT 7,BUFF]			;Set up buffer pointer
	HRRZ B,INDEX				;Clear flags from JFN
;A 6 is put in the left half of AC2 to fool the main loop into
;printing the full name on the first file.
	HLL B,[6,,0]				;And put 6 instead

;Main loop. Here the file names and their pointers are saved.
LOOP:	TXNN B,GN%NAM+GN%EXT+GN%DIR+GN%STR
	JRST GEN
	TXNN B,GN%NAM+GN%DIR+GN%STR
	JRST EXT
	TXNE B,GN%DIR+GN%STR
	JRST [SETOM .REC
		JRST OK]
NAME:	MOVE FLAGS,[1B8+1B11+1B14+JS%PAF]	;Name changed. Give all
	IDPB NUL,A				;Null byte for printing
	PUSH P,A				;Save current pointer
	JRST JFNS1				;Put name in buffer

EXT:	MOVE FLAGS,[1B11+1B14+JS%PAF]		;Extension+gen only
	IDPB NUL,A				;Null byte for printing
	PUSH P,A				;Save pointer
	MOVEI NUL,^D32				;Indent for EXT
	IDPB NUL,A				;(Save two spaces)
	IDPB NUL,A
	SETZ NUL,				;Reset NUL for later
	JRST JFNS1				;and print.

GEN:	MOVE FLAGS,[1B14]			;Generation only
	MOVEI NUL,^D44				;Put a comma
	IDPB NUL,A				;in the buffer
	SETZ NUL,				;Reset NUL for later
	ADDI GENER,1				;Add file #, not line #

JFNS1:	JFNS					;Store name in buffer
	MOVE T1,A				;Save a in T1
	MOVE A,INDEX				;Get index handle
	ADDI LINE,1				;Update line #
	GNJFN					;Get next JFN
	  JRST OK				;End of files?
	MOVE B,A				;Put JFN+FLAGS in AC2
	MOVE A,T1				;Restore a
	JRST LOOP				;and loop back.

;This section makes final adjustments before printing.
;Now that the main loop is over, AC14 (NUL) is used as a temporary AC.
OK:	MOVE T2,LINE				;Save line in T2
	SUB LINE,GENER				;Subtract # of GENS
	IDIVI LINE,COLUMN			;Divide by # of columns
;You may recall about IDIV that if there is a remainder, it is put in
;the next accumulator after the one being divided.
	SKIPE T1				;If even division, skip
	ADDI LINE,1				;Otherwise, add 1 to 7
	REPEAT COLUMN,<PUSH P,NUL>
;This section prints the files from the buffer according to the
;pointers, which are taken according to the number of columns.
PRINT:	ADDI FILES,1				;Add 1 to files.
	CAMLE FILES,LINE			;Printed all files?
	JRST DONE				;Yes. Done.
	MOVE B,POINTR(FILES)			;Take pointer @FILES
	MOVEI A,.PRIOU
	MOVEI 3,^D15				;Max 15 characters
	SETZ 4,
	SOUT					;And print that name
	CAIL 3,^D7				;Too few chars?
	JSR FRETAB				;Print an extra tab
	JSR TAB					;Print a TAB or CR.
	MOVE T3,FILES				;Save files. Use T3
	MOVEI NUL,2				;Set NUL to 2

;This is part of the print loop which controls the number of columns.
LOOPA:	ADD T3,LINE				;Add number of lines
	MOVE B,POINTR(T3)			;and get that pointer.
	JUMPE B,PRINTX				;If NUL, recycle.
	MOVEI A,.PRIOU
	MOVEI 3,^D15
	SETZ 4,
	SOUT					;Print name.
	CAIL 3,^D7				;Too few chars
	JSR FRETAB				;Print extra tab.
	JSR TAB					;TAB or CR.
	ADDI NUL,1				;Add 1 to NUL
	CAIG NUL,COLUMN				;More than columns?
	JRST LOOPA				;No, go back.
	JRST PRINT				;Yes. Goto main loop

;Eventually, if the number of files is not divisible by the number
;of columns, the last column will have a few blank lines at the end.
;This will prevent the program from printing random characters there.
PRINTX:	MOVEI TABS,COLUMN-1			;Equivelnt of CR.
	JSR TAB
	JRST PRINT				;And go back to loop

;This subroutine keeps track of the tabulation between file names.
TAB:	Z					;Address to store PC
	ADDI TABS,1				;Add one to TAB count
	CAIL TABS,COLUMN			; < than # of columns?
	JRST RET				;No, print CR
	MOVEI A,^D9				;Yes, print TAB
	PBOUT
	JRST @TAB				;And return.
RET:	MOVEI A,^D13				;Print CR and
	PBOUT
	MOVEI A,^D10				;Linefeed.
	PBOUT
	SETZ TABS,				;Reset TAB count
	JRST @TAB				;And return.

;FRETAB prints a tab unaccounted for by TAB: (used for files too short).
FRETAB:	Z
	MOVEI 1,^D9
	PBOUT
	JRST @FRETAB

;This section completes the program and prints the number of files.
DONE:	MOVEI TABS,COLUMN-1			;Equivelent of CR
	JSR TAB
	TMSG <  TOTAL NUMBER OF FILES IS >
	MOVEI A,.PRIOU				;Output number to TTY
	MOVEI FLAGS,^D10			;With a RADIX of 10
	MOVE B,T2				;Retrieve number files
	NOUT					;Output number
	  JRST ERROR				;Error address
	TMSG <
>
	MOVE 1,.REC
	JUMPN 1,[SETZM .REC
		TMSG <
>
		JRST ..REC]
	MOVEI 1,-1
	SIBE
	JRST [	CAIL 2,3
		JRST READ2
		MOVEI 1,-1
		CFIBF
		JRST DONE2]
DONE2:	MOVE 1,PRINTR
	JUMPE 1,DONE3
	MOVEI 1,^D19
	PBOUT
DONE3:	HALTF					;Stop. Done!
	JRST DONE3
	JRST DONE3

ERROR:	HRROI 1,ERRSTR
	MOVE B,[.FHSLF,,-1]			;Most recent error
	SETZ FLAGS,				;No limit of letters
	ERSTR					;Print error
	JFCL					;Ignore errors
	JFCL
	HRROI 1,ERRSTR
	ESOUT
	HALTF					;Stop.
	JRST START				;Restart address
ERRSTR:	BLOCK 10
BUFF:	BLOCK ^D10000				;Storage for file names
POINTR:	BLOCK ^D1000				;Storage for pointers
.REC:	Z

;This contains the default file specification to be used when none is
;typed in after the command (put in the RSCAN buffer).
;It can be changed without any other modification. Right now it is *.*.* .
FILE:	ASCIZ/*.*.*/				;Default specification

PRINTR:	Z

GTBLK:	GJ%OLD+GJ%IFG+.GJALL
	.PRIIN,,.PRIOU
	BLOCK 2
	POINT 7,[ASCIZ/*/]
	POINT 7,[ASCIZ/*/]
	BLOCK 4

	END START				;End.