1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-21 10:13:35 +00:00
2016-11-07 07:35:37 +01:00

402 lines
11 KiB
Plaintext
Executable File
Raw 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 B.
;A filename block consists of four words, which hold the
;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 A
;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 A 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 A.
;It can read more characters off D, or by calling RFN"RUC
;If it skips, RFN assumes that the character in A 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 $$PFND,$$PFND==0 ;Include PFND, like PFN but device of "DSK"
; or fn2 of ">" is suppressed.
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
DEV==0 ;Indices into the filename block.
FN1==1
FN2==2
SNM==3
.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 B points at.
;A filename block has four words, which get the device name, sname, fn1 and fn2.
;The terminating character is left in A.
;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.
RFN: PUSH P,B
PUSH P,C
MOVE C,B ;Put the filename block addr in C since RSIXG returns in B.
PUSH P,FN1(C) ;Save default FN1, FN2 for ^X, ^Y.
PUSH P,FN2(C)
SETZ E, ;Number of names stored yet is 0.
RFN0: PUSHJ P,RUC
RFN2: PUSHJ P,RSIXG ;Read one filename.
JRST RFN1
PUSHJ P,RFNN ;If it's not null, store it.
RFN1: CAIE A,": ;Check char that ended name,
CAIN A,";
JRST RFN0
CAIN A,40 ;If was space, : or ;, read another name.
JRST RFN0
IFN $$SWITCH,[
CAIN A,"/ ;If stopped on "/" or "(", call switch rtn.
JRST RFNSL ;Read 1 switch.
CAIN A,"(
JRST RFNPAR ;Read many switches until ).
];IFN $$SWITCH
CAIE A,^X
CAIN A,^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,B
POPJ P,
;STORE THE NAME IN B.
RFNN: CAIN A,":
JRST RFNC ;: => USE AS DEVICE.
CAIN A,";
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 $$SWITCH,[ ;Code for processing switches, when a "/" or "(" is seen.
RFNPAR: PUSHJ P,RUC ;Get next char. Is it a ")"?
RFNPA1: CAIN A,")
JRST RFN0 ;Paren ends switches.
CAIE A,0
CAIN A,^M
JRST RFN1 ;CR ends spec even in switch list.
PUSHJ P,SWITCH ;Try to gobble the switch.
JRST RFNPAR ;Char in A used up, get another.
JRST RFNPA1 ;Char in A not part of switch; is it ")"?
RFNSL: PUSHJ P,RUC
CAIE A,0
CAIN A,^M ;/<CR> ENDS SPEC.
JRST RFN1
PUSHJ P,SWITCH ;Otherwise, process it as switch.
JRST RFN0 ;No skip => char in A was gobbled by switch.
JRST RFN2 ;Skip => let next RSIXG gobble the char now in A.
];IFN $$SWITCH
;Here to store the word in B as the SNAME.
RFNS: MOVEM B,SNM(C) ;Set the sname.
TLO E,1_SNM ;Say the sname has been specified in this filespec.
MOVSI B,'DSK ;Consider setting the device to DSK:
TLNN E,1_DEV ;If dev was just spec'd, don't override the spec'd one.
MOVEM B,DEV(C) ;It is a feature that this doesn't set 1_DEV,
POPJ P, ; it lets the user tell exactly what was given.
;Here to store the word in B as the device name.
RFNC: MOVEM B,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 B as the FN1.
RFNF1: MOVEM B,FN1(C) ;Set the FN1, say was spec'd.
TLO E,1_FN1
POPJ P,
;Here to store the word in B as the FN2.
RFNF2: MOVEM B,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 A,(P) ;POINT TO THE STACKED DEFAULT FN1 OR FN2
MOVE B,-^Y(A) ;AND GET IT.
PUSHJ P,RFNN ;STORE IT NORMALLY.
JRST RFN0 ;GET NEXT NAME.
;Subroutines for filename reading.
IFE $$RUC,[
;Read char into A 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: ILDB A,D
CAIL A,140
SUBI A,40
POPJ P,
];IFE $$RUC
;Read SIXBIT word into B from b.p. in D, leaving terminating char in A.
;Expects first character in A already.
;Terminates on a Space or control character or Rubout.
;Skips if the word was non-null.
RSIX: PUSH P,C
MOVE C,[440640,,B] ;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 A
;and skip or not, clobbering no ACs.
RSIXG: PUSH P,C
MOVE C,[440600,,B] ;BP FOR STORING THE SIXBIT.
RSIXG1: SETZ B, ;NO CHARS SO .
RSIX0: CAIN A,^Q
JRST RSIX2 ;^Q QUOTES A CHAR WHICH WOULD TERMINATE.
CAIE A,177
CAIG A,40
JRST RSIX1 ;SPACE OR CTL CHAR => STOP.
TLNE C,40
JRST RSIX3 ;RSIX WAS CALLED, ALL OTHER CHARS NORMAL.
CAIE A,":
CAIN A,"; ;RSIXG, STOP ON : AND ;.
JRST RSIX1
PUSHJ P,RSIXTP
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 A,40 ;INSERT NORMAL CHAR IN THE 6BIT.
TLNE C,77^4 ;IGNORE CHARS AFTER THE FIRST 6.
IDPB A,C
PUSHJ P,RUC
JRST RSIX0
];IFN $$RFN
IFN $$PFN,[ ;Routines for printing filenames.
;Convert the filenames in the filename block which B points at
;to ASCII, depositing it down the b.p. 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,A
PUSH P,C
MOVE C,DEV(B)
CAMN C,[SIXBIT/DSK/]
MOVE C,MNAME
JRST PFN1
]
PFN: PUSH P,A
PUSH P,C
MOVE C,DEV(B) ;Print device name, colon, and space.
PFN1: PUSHJ P,PSIXF
MOVEI A,":
IDPB A,D
MOVEI A,40
IDPB A,D
MOVE C,SNM(B) ;Print sname, semicolon, and space.
PUSHJ P,PSIXF
MOVEI A,";
IDPB A,D
MOVEI A,40
IDPB A,D
MOVE C,FN1(B) ;Print fn1 and space.
PUSHJ P,PSIXF
MOVEI A,40
IDPB A,D
MOVE C,FN2(B) ;Print fn2.
PUSHJ P,PSIXF
SETZ A, ;Store terminating ^@ but don't advance D over it.
MOVE C,D
IDPB A,C
POP P,C
POP P,A
POPJ P,
;Print SIXBIT word in C down b.p. in D,
;putting ^Q's before appropriate characters.
;Clobbers C.
PSIXF: LDB A,[360600,,C] ;Extract first character
LSH C,6 ;and flush it.
ADDI A,40
CAIE A,":
CAIN A,";
JRST PSIXF1
CAIN A,40
JRST PSIXF1
PUSHJ P,PSIXTP
JRST PSIXF2
PSIXF1: PUSH P,A
MOVEI A,^Q
IDPB A,D
POP P,A
PSIXF2: IDPB A,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,A
PUSH P,C
MOVE C,DEV(B) ;Print device name, colon, and space.
IFN $$MNAME,CAME C,MNAME
CAMN C,[SIXBIT /DSK/]
JRST PFNBR1
JUMPE C,PFNBR1
PUSHJ P,PSIXF
MOVEI A,":
IDPB A,D
MOVEI A,40
IDPB A,D
PFNBR1: SKIPE C,SNM(B) ;Print sname, semicolon, and space.
CAMN C,MSNAME
JRST PFNBR2
PUSHJ P,PSIXF
MOVEI A,";
IDPB A,D
MOVEI A,40
IDPB A,D
PFNBR2: MOVE C,FN1(B) ;Print fn1 and space.
PUSHJ P,PSIXF
SKIPN FN2(B)
JRST PFNBR3
MOVEI A,40
IDPB A,D
MOVE C,FN2(B) ;Print fn2.
PUSHJ P,PSIXF
PFNBR3: SETZ A, ;Store terminating ^@ but don't advance D over it.
MOVE C,D
IDPB A,C
POP P,C
POP P,A
POPJ P,
];IFN $$PFNBRF
IFN $$PFND,[ ;Routine to print filenames, omitting true defaults.
;PFND is called like PFN, but it omits the device if it is "DSK" and the
; fn2 if it is ">".
PFND: PUSH P,A
PUSH P,C
SKIPE C,DEV(B) ;Print device name, colon, and space.
CAMN C,[SIXBIT /DSK/]
JRST PFND1
PUSHJ P,PSIXF
MOVEI A,":
IDPB A,D
MOVEI A,40
IDPB A,D
PFND1: SKIPN C,SNM(B) ;Print sname, semicolon, and space.
JRST PFND2
PUSHJ P,PSIXF
MOVEI A,";
IDPB A,D
MOVEI A,40
IDPB A,D
PFND2: MOVE C,FN1(B) ;Print fn1.
PUSHJ P,PSIXF
SKIPE C,FN2(B) ;Print space, fn2.
CAMN C,[SIXBIT />/]
JRST PFND3
MOVEI A,40
IDPB A,D
PUSHJ P,PSIXF
PFND3: SETZ A, ;Store terminating ^@ but don't advance D over it.
MOVE C,D
IDPB A,C
POP P,C
POP P,A
POPJ P,
];IFN $$PFND
IFN $$MNAME,[ ;Routine to initialize MNAME.
RMNAME: SYSCAL SSTATU,[REPEAT 6,[? %CLOUT,,MNAME]]
.LOSE %LSSYS
POPJ P,
];IFN $$MNAME
.END RFN