1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-19 16:21:37 +00:00
Files
PDP-10.its/src/rwk/files.12
2018-02-28 21:13:04 +01:00

417 lines
12 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.BEGIN RFN ;-*-MIDAS-*-
SUBTTL Routines for parsing and printing filenames
;Basic conventions:
;We assume that there are accumulators A, B, C, D and E, not necessarily
;consecutive, and that the stack is in P.
;No routine clobbers ACs other than the
;ones it is documented to clobber, and none touches even temporarily
;any AC other than A, B, C, D, E and P.
;All code generated is pure.
;The main routines, RFN, PFN, PFNBRF and PFNMCH, never skip.
;This file contains two routines, RFN to read filenames and PFN to print.
;Both expect a b.p. for ILDB'ing or IDPB'ing the text, in D.
;Both expect a pointer to a filename block in A.
;A filename block consists of four words, which hold th
;left-justified sixbit DEVICE, FN1, FN2 and SNAME in that order.
;The RFN routine assumes that the user has defined the label RSIXTP
;(RSIX-Terminator-P) which should expect a character in B
;and skip if it should terminate a filename, or start a switch.
;It will not be called with control characters.
;Thus, you might want it to skip when given ",", "_" or "/".
;PFN similarly assumes that there is a routine PSIXTP will will
;skip for a character in B that needs a ^Q printed in front of it.
;Normally, RSIXTP and PSIXTP can be the same routine.
;If you want switches to be processed in filenames,
;set $$SWITCH to 1 and define the label SWITCH as a routine to read a switch.
;It will be called with the first character of the switch in B.
;It can read more characters off D, or by calling RFN"RUC
;If it skips, RFN assumes that the character in B should be reprocessed.
;A slash is followed by a single switch, while parentheses enclose
;any number of switches. However, neither slash nor "(" will be
;recognized unless RSIXTP skips for it. This gives the caller
;run-time control of whether switches are to be processed.
;If $$MNAME is set, the user must define MNAME to point to
;a word holding this machine's name in SIXBIT. RFN"RMNAME initializes it.
;If $$PFNBRF is set, the user must define MSNAME to point to
;a word holding the "default" SNAME (the one not to be mentioned).
;These symbols should be defined by the user to select parts of this file:
IFNDEF $$RFN,$$RFN==0 ;Include RFN, the routine for reading filenames.
IFNDEF $$SWITCH,$$SWITCH==0 ;Include routines for processing "/" and "(-)" switches.
IFNDEF $$PFN,$$PFN==0 ;Include PFN, the routine for printing filenames.
IFNDEF $$PFNBRF,$$PFNBRF==0 ;Include routine to print filenames briefly.
IFNDEF $$RUC,$$RUC==0 ;1 => don't define RUC; use a user-supplied definition.
IFNDEF $$MNAME,$$MNAME==0 ;1 => assume MNAME is defined and holds this machine's name.
IFN $$SWITCH,$$RFN==1
IFN $$PFNBRF,$$PFNBRF==1
ifndef $$sixp,$$sixp==0 ;default to no special terminators
ifndef $$altp,$$altp==0 ;nonzero => altmode prints defaults
ifn $$altp,$$pfn==1 ;altmode requires that we be able to print
ifndef p,p==sp ;alternate name for P
.AUXIL ;Don't mention all our internal symbols in crefs.
;PRINT VERSION NUMBER
.TYO6 .IFNM1
.TYO 40
.TYO6 .IFNM2
PRINTX/ INCLUDED IN THIS ASSEMBLY.
/
DEFINE SYSCAL NAME,ARGS
.CALL [SETZ ? SIXBIT/NAME/ ? ARGS ((SETZ))]
TERMIN
IFN $$RFN,[ ;Routines for reading filenames.
;Read a file spec off the b.p. in D into the file block that A points at.
;A filename block has four words, which get the device name, sname, fn1 and fn2.
;The terminating character is left in B.
;In E's left half we return flags indicating which of the four names were
;specified: 1,, for the device; 2,, for the FN1; 4,, for the FN2; 10,, for the SNAME.
DEV==0 ;Indices into the filename block.
FN1==1
FN2==2
SNM==3
ifn $$altp,[
devloc: 0]
RFN: PUSH P,A
PUSH P,C
MOVE C,A ;Put the filename block addr in C since RSIXG returns in A.
PUSH P,FN1(C) ;Save default FN1, FN2 for ^X, ^Y.
PUSH P,FN2(C)
ifn $$altp,[movem c,devloc] ;save location of file block for restarting
restrt: SETZ E, ;Number of names stored yet is 0.
RFN0: PUSHJ P,RUC
ifn $$altp,[cain b,33 ;altmode?
jrst alttyp] ;yes, go print out our defaults
RFN2: PUSHJ P,RSIXG ;Read one filename.
JRST RFN1
PUSHJ P,RFNN ;If it's not null, store it.
RFN1:
ifn $$altp,[cain b,33 ;altmode?
jrst alttyp] ;yes, go print out our defaults
CAIE B,72 ;Check char that ended name, ":"
CAIN B,"73 ;or ";"
JRST RFN0
CAIN B,40 ;If was space, : or ;, read another name.
JRST RFN0
IFN $$SWITCH,[
CAIN B,57 ;"/" -- If stopped on "/" or "(", call switch rtn.
JRST RFNSL ;Read 1 switch.
CAIN B,50 ;"("
JRST RFNPAR ;Read many switches until ).
];IFN $$SWITCH
CAIE B,^X
CAIN B,^Y ;If was ^X or ^Y,
JRST RFNX ;use the default FN1 or FN2 as next name.
SUB P,[2,,2]
POP P,C
POP P,A
POPJ P,
;STORE THE NAME IN A.
RFNN: CAIN B,72 ;":"
JRST RFNC ;: => USE AS DEVICE.
CAIN B,73 ;";"
JRST RFNS ;; => USE AS SNAME.
AOJA E,RFNT(E) ;ELSE USE AS NEXT NAME IN NORMAL SEQUENCE.
;Table for storing a name normally.
;N'th entry used for N'th name.
RFNT: JRST RFNF1 ;1st name, set FN1
JRST RFNF2 ;Second, set FN2.
JRST RFNC ;Third, set device.
JRST RFNS ;Fourth, set sname.
SOS E ;Fifth one, ignore, and don't let count advance past 5.
POPJ P, ;So this word isn't part of the dispatch.
ifn $$altp,[
alttyp: type /$
/
push sp,d
move a,devloc ;restore saved filename block
move d,[tyo tyoc,b] ;type it out
call pfn
type / /
pop sp,d
jrst restrt ;go back and try again with our new defaults
]
IFN $$SWITCH,[ ;Code for processing switches, when a "/" or "(" is seen.
RFNPAR: PUSHJ P,RUC ;Get next char. Is it a ")"?
RFNPA1: CAIN B,51 ;")"
JRST RFN0 ;Paren ends switches.
CAIE B,0
CAIN B,^M
JRST RFN1 ;CR ends spec even in switch list.
PUSHJ P,SWITCH ;Try to gobble the switch.
JRST RFNPAR ;Char in I used up, get another.
JRST RFNPA1 ;Char in I not part of switch; is it ")"?
RFNSL: PUSHJ P,RUC
CAIE B,0
CAIN B,^M ;/<CR> ENDS SPEC.
JRST RFN1
PUSHJ P,SWITCH ;Otherwise, process it as switch.
JRST RFN0 ;No skip => char in B was gobbled by switch.
JRST RFN2 ;Skip => let next RSIXG gobble the char now in B.
];IFN $$SWITCH
;Here to store the word in A as the SNAME.
RFNS: MOVEM A,SNM(C) ;Set the sname.
TLO E,1_SNM ;Say the sname has been specified in this filespec.
MOVS A,DEV(C) ;Get the device,
TLNE E,1_DEV ;If dev was just spec'd, don't override the spec'd one.
POPJ P,
LSH A,-6 ;Else check 1st 2 chars,
CAIE A,'AI ' ;see if dev is one known to use the sname.
CAIN A,'ML '
POPJ P, ;If it is, nothing else to do.
CAIN A,'DM '
POPJ P,
CAIE A,'PK '
CAIN A,'PK '
POPJ P,
CAIE A,'CL '
CAIN A,'JO '
POPJ P,
RFNS1: MOVSI A,'DSK ' ;OTHERWISE SET THE DEVICE TO DSK:
;Here to store the word in A as the device name.
RFNC: MOVEM A,DEV(C) ;Set the dev name,
TLO E,1_DEV ;and say the device name was explicitly specified.
POPJ P,
;Here to store the word in A as the FN1.
RFNF1: MOVEM A,FN1(C) ;Set the FN1, say was spec'd.
TLO E,1_FN1
POPJ P,
;Here to store the word in A as the FN2.
RFNF2: MOVEM A,FN2(C) ;Set the FN2, say was spec'd.
TLO E,1_FN2
POPJ P,
;Here to process a ^X or ^Y, by taking the stacked default FN1 or FN2 and using it as input.
RFNX: ADDI B,(P) ;POINT TO THE STACKED DEFAULT FN1 OR FN2
MOVE A,-^Y(B) ;AND GET IT.
PUSHJ P,RFNN ;STORE IT NORMALLY.
JRST RFN0 ;GET NEXT NAME.
;Subroutines for filename reading.
IFE $$RUC,[
;Read char into B from b.p. in D and convert to upper case.
;Filename reading does all its input via RUC.
;If $$RUC is set, we assume that the user has defined RUC,
;and call the user's definition.
RUC: xct d ;D has op to put char in b
CAIge B,140
POPJ P,
caie b,177 ;don't modify rubout
SUBI B,40
popj p,
];IFE $$RUC
;Read SIXBIT word into A from source in D, leaving terminating char in B.
;Expects first character in B already.
;Terminates on a Space or control character or Rubout.
;Skips if the word was non-null.
RSIX: PUSH P,C
MOVE C,[440640,,A] ;Extra bit in b.p. set says RSIX, not RSIXG.
JRST RSIXG1
;Similar but stop on :, ;, and any characters which RSIXTP skips for.
;We assume that the user has defined RSIXTP to accept a character in B
;and skip or not, clobbering no ACs.
RSIXG: PUSH P,C
MOVE C,[440600,,A] ;BP FOR STORING THE SIXBIT.
RSIXG1: SETZ A, ;NO CHARS SO .
RSIX0: CAIn B,177
jrst [setz b, ;no char
came c,[440600,,a] ;don't over-rubout
jrst [dpb b,c ;clear out the old char
add c,[060000,,0] ;back up a char
jrst rsix4] ;and get another char to work with
jrst rsix4]
CAIN B,^Q
JRST RSIX2 ;^Q QUOTES A CHAR WHICH WOULD TERMINATE.
CAIG B,40
JRST RSIX1 ;SPACE OR CTL CHAR => STOP.
CAIGE B,100 ;(IF THIS SKIPS, ALL LATER TESTS WOULD FAIL ANYWAY)
TLNE C,40
JRST RSIX3 ;RSIX WAS CALLED, ALL OTHER CHARS NORMAL.
CAIE B,72 ;":"
CAIN B,73 ;";" -- RSIXG, STOP ON : AND ;.
JRST RSIX1
ifn $$sixp,[PUSHJ P,RSIXTP] ;only if we want to bother
JRST RSIX3
RSIX1: SKIPL C ;TERMINATE: SKIP IF GOT >= 1 CHAR.
AOS -1(P)
POP P,C
POPJ P,
RSIX2: PUSHJ P,RUC ;^Q => READ THE QUOTED CHAR.
RSIX3: SUBI B,40 ;INSERT NORMAL CHAR IN THE 6BIT.
TLNE C,77^4 ;IGNORE CHARS AFTER THE FIRST 6.
IDPB B,C
rsix4: PUSHJ P,RUC
JRST RSIX0
];IFN $$RFN
IFN $$PFN,[ ;Routines for printing filenames.
;Convert the filenames in the filename block which A points at
;to ASCII, depositing it down the destination in D, followed by a ^@
;which D is not advanced over.
;A filename block is four words containing the device, fn1, fn2 and sname.
;It is assumed that PSIXTP (PSIX-Terminator-P) is defined as a
;routine which, given a character in B, skips if a ^Q should be
;printed before that character. Space, colon and semicolon get ^Q'd
;in any case. Thus, you can usually make PSIXTP and RSIXTP the same.
;PFNMCH is the same as PFN except that if the device is DSK
;it prints the name of this machine (from MNAME) instead.
IFN $$MNAME,[
PFNMCH: PUSH P,B
PUSH P,C
MOVE C,DEV(A)
CAME C,[SIXBIT/DSK/]
MOVE C,MNAME
JRST PFN1
]
PFN: PUSH P,B
PUSH P,C
MOVE C,DEV(A) ;Print device name, colon, and space.
PFN1: PUSHJ P,PSIXF
MOVEI B,72 ;":"
xct d
MOVEI B,40
xct d
MOVE C,SNM(A) ;Print sname, semicolon, and space.
PUSHJ P,PSIXF
MOVEI B,73 ;";"
xct d
MOVEI B,40
xct d
MOVE C,FN1(A) ;Print fn1 and space.
PUSHJ P,PSIXF
MOVEI B,40
xct d
MOVE C,FN2(A) ;Print fn2.
PUSHJ P,PSIXF
;;the next have been commented out because it isn't needed: The user can do it
;; if he wants, since he gets his destination operation back again. But if it
;; is a TYO it will lose to go putting out stray nulls
; SETZ B, ;Store terminating ^@ but don't advance D over it.
; MOVE C,D
; IDPB B,C
POP P,C
POP P,B
POPJ P,
;Print SIXBIT word in C down destination in D,
;putting ^Q's before appropriate characters.
;Clobbers C.
PSIXF: LDB B,[360600,,C] ;Extract first character
LSH C,6 ;and flush it.
ADDI B,40
CAIE B,72 ;":"
CAIN B,73 ;";"
JRST PSIXF1
CAIN B,40
JRST PSIXF1
ifn $$sixp,[PUSHJ P,PSIXTP]
JRST PSIXF2
PSIXF1: PUSH P,B
MOVEI B,^Q
xct d
POP P,B
PSIXF2: xct d
JUMPN C,PSIXF ;ALL THE REST BLANK => DONE.
POPJ P,
];IFN $$PFN
IFN $$PFNBRF,[ ;Routine to print filenames, as briefly as possible.
;PFNBRF is called like PFN, but it omits names which have their default values.
;It is assumed that MSNAME is defined to be the address of a word
;holding the "default" SNAME.
PFNBRF: PUSH P,B
PUSH P,C
MOVE C,DEV(A) ;Print device name, colon, and space.
IFN $$MNAME,CAME C,MNAME
CAMN C,[SIXBIT /DSK/]
JRST PFNBR1
JUMPE C,PFNBR1
PUSHJ P,PSIXF
MOVEI B,72 ;":"
xct d
MOVEI B,40
xct d
PFNBR1: SKIPE C,SNM(A) ;Print sname, semicolon, and space.
CAMN C,MSNAME
JRST PFNBR2
PUSHJ P,PSIXF
MOVEI B,73 ;";"
xct d
MOVEI B,40
xct d
PFNBR2: MOVE C,FN1(A) ;Print fn1 and space.
PUSHJ P,PSIXF
SKIPN FN2(A)
JRST PFNBR3
MOVEI B,40
xct d
MOVE C,FN2(A) ;Print fn2.
PUSHJ P,PSIXF
PFNBR3:
; SETZ B, ;Store terminating ^@ but don't advance D over it.
; MOVE C,D
; IDPB B,C
POP P,C
POP P,B
POPJ P,
];IFN $$PFNBRF
IFN $$MNAME,[ ;Routine to initialize MNAME.
RMNAME: SYSCAL SSTATU,[REPEAT 6,[? %CLOUT,,MNAME]]
.LOSE %LSSYS
POPJ P,
];IFN $$MNAME
.END RFN