1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-28 12:59:20 +00:00

KSFEDR source code.

This commit is contained in:
Lars Brinkhoff
2016-11-07 07:35:37 +01:00
parent 0efda0c8bc
commit be6af1cb94
4 changed files with 2935 additions and 1 deletions

1062
src/kshack/ksfedr.146 Executable file

File diff suppressed because it is too large Load Diff

1471
src/syseng/format.305 Executable file

File diff suppressed because it is too large Load Diff

401
src/syseng/rfn.13 Executable file
View File

@@ -0,0 +1,401 @@
.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