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.