mirror of
https://github.com/PDP-10/its.git
synced 2026-01-18 01:02:15 +00:00
3804 lines
101 KiB
Plaintext
3804 lines
101 KiB
Plaintext
|
||
; -*-MIDAS-*-
|
||
|
||
TITLE SRCCOM
|
||
|
||
;;SRCCOM COMMAND ;; SRCCOM_/@/A/L/C/S
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;
|
||
;;; NOTE: THE CANONICAL SOURCE FOR THIS PROGRAM LIVES IN
|
||
;;; [MIT-AI] SYSENG;SRCCOM >
|
||
;;; ALL CHANGES, BUG FIXES, ETC SHOULD BE REFLECTED THERE.
|
||
;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;WAS ONCE DEC SRCCOM VERSION 16, MINIMALLY ADAPTED TO ITS.
|
||
;ALMOST TOTALLY REWRITTEN BY RMS, DEC '75.
|
||
;MUNGED FOR 10X/20X ASSEMBLY BY KLH, MAR '79.
|
||
|
||
IF1 [
|
||
IFE .OSMIDAS-SIXBIT/ITS/,ITS==1
|
||
IFE .OSMIDAS-SIXBIT/TENEX/,TNX==1
|
||
IFE .OSMIDAS-SIXBIT/TWENEX/,TNX==1 ? TWX==1
|
||
IFNDEF ITS,ITS==0
|
||
IFNDEF TNX,TNX==0
|
||
IFE ITS,IFE TNX,DEC==1
|
||
IFNDEF DEC,DEC==0
|
||
IFNDEF TWX,TWX==0
|
||
]
|
||
|
||
IFN TNX,[
|
||
.DECSAV ; Why go through LINK?
|
||
DEFINE HLPFIL ; SPECIFIES LOC OF HELP FILE
|
||
ASCIZ "INFO:SRCCOM.INFO"!TERMIN
|
||
]
|
||
|
||
;I/O CHANNELS. FOR TNX THESE ARE INDICES INTO JFNCHS.
|
||
|
||
CHTTI==0 ;TTY INPUT.
|
||
CHIN1==1 ;FIRST INPUT FILE
|
||
CHIN2==2 ;SECOND INPUT FILE.
|
||
CHIN3==3 ;THIRD INPUT FILE, FOR 3-WAY MERGES.
|
||
CHMRG==4 ;/M OUTPUT DEVICE FOR MERGE FILE
|
||
CHTTO==5 ;ITS NEEDS TYO CHANNEL
|
||
CHERR==6 ;FOR ERR DEVICE.
|
||
CHOUT==7 ;OUTPUT CHNL FOR DIFFERENCES.
|
||
CHCMD==10 ;COMMAND FILE READING CHANNEL.
|
||
CHUIN1==11 ;/$ USR INPUT
|
||
CHUIN2==12 ;/$ USR INPUT
|
||
CHUO1==13 ;/$ and output chans, since need both.
|
||
CHUO2==14 ;/$
|
||
|
||
;MAIN AC DEFINITIONS
|
||
|
||
W1=1
|
||
W2=2
|
||
W3=3
|
||
F1=4 ;LINE POINTER FILE 1 (CONTAINS ADDRESS OF LINE BLOCK)
|
||
F2=5 ;DITTO FILE 2
|
||
F3=6 ;DITTO FILE 3
|
||
FR=7 ;FLAG REGISTER (LH) AND FILE #(0 OR 1 OR 2)(RH)
|
||
CS=10
|
||
C=11 ;CONTAINS 1 CHAR FOR PROCESSING
|
||
T=12 ;TEMPORARY AC (MUNGED BY XJSYS CALLS)
|
||
TT=13 ;TEMP AC
|
||
BP=14 ; (RDLIN AC LOOP) BYTE POINTER IN FILENAME READER.
|
||
FP=15 ; BP+1 (RDLIN AC LOOP) ADDR OF FILE BLK
|
||
;=16 ; BP+2 (RDLIN AC LOOP)
|
||
P=17 ;PUSH DOWN POINTER
|
||
|
||
; ACC DEFS FOR TNX JSYS CODE
|
||
IFN TNX, R1=1 ? R2=2 ? R3=3 ? R4=4 ? R5=5
|
||
; ACC DEFS FOR STUFF BORROWED FROM MIDAS
|
||
IFN TNX, AA=6 ? A=1 ? B=2 ? D=4 ? E=5 ? F=FP ; NOTE A NOT AA+1
|
||
|
||
|
||
;ASCII CHARACTERS
|
||
|
||
TAB==11
|
||
ALTM==33 ;/M ALT-MODE TO END TTY INPUT FOR MERGE(/M)
|
||
|
||
;FLAGS - LH OF AC FR:
|
||
|
||
FL==1,,525252 ;BIT TYPEOUT MODE MASK.
|
||
FLINDR==1 ;/@ - FILE NAME FOLLOWS THE STRING ";COMPARISON OF " IN SPEC'D FILE.
|
||
;APPLIES TO 1ST INPUT FILE ONLY.
|
||
FLXCTF==2 ;/X - OPEN A COMMAND FILE AND START EXECUTING FROM IT.
|
||
FLISWT==4 ;/I - MERGE, BUT AUTOMATICALLY ANSWER "I" TO EVERY QUESTION
|
||
;AND DON'T TYPE ON THE TTY.
|
||
FLARCH==10 ;/A SWITCH - "ARCHIVE". APPEND OUTPUT TO FRONT OF EXISTING FILE.
|
||
FLLABL==20 ;/L SWITCH - REMEMBER FOR EACH FILE AND LINE THE PREVIOUS LABEL,
|
||
;AND PRINT IT IN THE HEADER LINE.
|
||
FLENDL==40 ;/E SWITCH - PRINT OUT THE FIRST MATCHING LINE FROM EACH FILE
|
||
;AFTER EACH RUN OF DIFFERENCES.
|
||
FLSPAC==100 ;/S SWITCH - IGNORE SPACING
|
||
FLCMNT==200 ;/C SWITCH - IGNORE COMMENTS
|
||
FLALL==400 ;/B OR /M SWITCH (ALLOWS COMPARING BLANK LINES)
|
||
; CR,LF,FF STORED LIKE DATA AND COMPARED
|
||
FLEOF1==1000 ;EOF SEEN ON FILE 1
|
||
FLEOF2==2000 ;EOF SEEN ON FILE 2
|
||
FLEOF3==4000 ;EOF SEEN ON FILE 3
|
||
FLFNUM==10000 ;/W SAYS PRINT FILE # ON EACH LINE OF DIFFERENCES.
|
||
FLFLAG==20000 ;/F SAYS MAKE COPY OF FILE 2, FLAGGING CHANGED LINES WITH VERT. BARS.
|
||
FLCASE==40000 ;/K SAYS IGNORE DIFFERENCES IN ALPHABETIC CASE
|
||
FLOVRD==100000 ;/! SAYS DO THE COMPARISON EVEN IF FILE1 AND FILE2 ARE SAME FILE.
|
||
FLXLBL==200000 ;/Y SAYS ANY UNINDENTED LINE NOT STARTING WITH A ";" IS A LABEL.
|
||
FLMERG==400000 ;/M SWITCH-MERGE 2 FILES INTO ONE CONVERSATIONALLY
|
||
|
||
;RH OF FR TELLS CERTAIN FUNCTIONS WHICH INPUT FILE TO OPERATE ON: 0 => FILE 1, 1 => FILE 2.
|
||
|
||
; Memory flags (cuz no more room in LH of FR!)
|
||
.SCALAR FVBIN ; -1 if doing binary compare (like FILCOM /W)
|
||
.SCALAR FSBIN ; -1 if doing SBLK/CSAVE compare
|
||
.SCALAR QFLAG ; -1 if doing /Q message at end of compare
|
||
|
||
;NAMES OF THE HEADER WORDS OF A FILE LINE
|
||
|
||
LNNEXT==0 ;MUST BE 0! ADDR OF HEADER OF NEXT LINE, OR 0 FOR LAST LINE.
|
||
LNSIZE==1 ;# OF CHARACTERS IN THE LINE, NOT COUNTING TERMINATING ZERO.
|
||
LNLLBL==2 ;1ST WORD OF ASCIZ OF MOST RECENT LABEL, OR 0.
|
||
LNLLB1==3 ;2ND WORD OF ASCIZ. COLON IS INCLUDED.
|
||
LNLLB2==4 ;4 WORDS IN ALL FOR HOLDING A LABEL.
|
||
LNLLB3==5
|
||
LNLBLN==4
|
||
LNPGNM==6 ;PAGE # THIS LINE STARTED ON
|
||
LNLNNM==7 ;LINE NUMBER THIS LINE STARTED ON
|
||
LNCHNM==10 ;CHARACTER NUMBER IN FILE OF 1ST CHARACTER IN LINE
|
||
LNDATA==11 ;INDEX OF THE FIRST DATA WORD. THE DATA ARE AN ASCIZ STRING
|
||
;THERE ARE ASSUMED TO BE JUST ENOUGH DATA WORDS
|
||
;TO HOLD THE NUMBER OF CHARACTERS THAT LNSIZE SAYS THERE ARE.
|
||
|
||
|
||
;PARAMETERS
|
||
|
||
IFNDEF MATCH,MATCH==3 ;# LINES TO BE MATCHED BEFORE RUN OF DIFFERENCES ENDS.
|
||
IFNDEF WPL,WPL==<40.*4>/5+1 ;# WORDS FOR FILENAMES FOR HEADER LINES.
|
||
IFNDEF LPDL,LPDL==30 ;LENGTH OF PUSH DOWN LIST
|
||
IFNDEF FILBFL,FILBFL==100 ;LENGTH OF INPUT FILE BUFFERS.
|
||
MRGBSZ==FILBFL*5 ;MERGE OUTPUT BUFFER LENGTH IN CHARS.
|
||
|
||
;/M THIS SRCCOM ALSO PERFORMS A MERGE FUNCTION IF /M IS TYPED
|
||
;/M DESTINATION FILE BECOMES MERGE OF 2 SOURCE FILES.
|
||
;/M DIFFERENCES ARE TYPED ON TTY, USER SELECTS WHICH HE WANTS
|
||
;/M AND IN WHAT ORDER BY TYPING IN 1 LINE COMMAND AFTER EACH PAIR
|
||
;/M OF DIFFERENCES IS TYPED OUT.
|
||
;/M HE MAY TYPE 1, 2, AND/OR T IN ANY ORDER FOLLOWED BY CR
|
||
;/M OR HE MAY CHANGE THE LAST COLUMN TYPED OUT TO ### BY TYPING
|
||
;/M C### FOLLOWED BY CR AS A SEPARATE COMMAND AFTER ANY PAIR OF DIFFERENCES
|
||
;/M TYPED OUT. SRCCOM WILL RESPOND WITH ANOTHER *, SO THE USER CAN TYPE
|
||
;/M ANOTHER COMMAND TO SELECT WHICH DIFFERENCES HE WANTS. INITIALLY THE
|
||
;/M MAX. COLUMN IS SET TO 72 WHENEVER SRCCOM IS RESTARTED WITH START COMMAND
|
||
;/M IT IS NOT RESET AFTER EACH FILE COMPARED.
|
||
;/M SIMILARLY THE USER MAY SET THE MAXIMUM
|
||
;/M NUMBER OF LINES TYPED FROM EACH FILE WITH L###.
|
||
|
||
;OPDEFS
|
||
|
||
CALL=PUSHJ P,
|
||
RET=POPJ P,
|
||
SAVE=PUSH P,
|
||
REST=POP P,
|
||
PJRST==JRST
|
||
IFN ITS,ERRHLT==.LOSE
|
||
IFN TNX,ERRHLT==HALT
|
||
|
||
;MACROS
|
||
|
||
IFN ITS,[
|
||
DEFINE SYSCAL A,B
|
||
.CALL [ SETZ ? SIXBIT/A/ ? B ((SETZ))]
|
||
TERMIN
|
||
]
|
||
; This may not work right on TENEX anymore, if so, fix the opsys flags
|
||
; so that we can tell 10x from 20x.
|
||
IFN TNX, .INSRT MID:XJSYS
|
||
|
||
DEFINE DBP7J AC,TAG=.+2
|
||
ADD AC,[070000,,]
|
||
JUMPGE AC,TAG
|
||
SUB AC,[430000,,1]
|
||
IFSN [TAG].+2,JRST TAG
|
||
TERMIN
|
||
|
||
DEFINE INSIRP INSN,ADDRS
|
||
IRPS ADDR,,[ADDRS]
|
||
INSN,ADDR
|
||
TERMIN TERMIN
|
||
|
||
;ADVANCE TO THE NEXT LINE IN FILE FILN, READING IT FROM THE FILE IF NECESSARY.
|
||
;GO TO EOFA IF THERE IS NO LINE DUE TO EOF.
|
||
DEFINE NEXTLN FILN,(EOFA)
|
||
SKIPE LNNEXT(F1+FILN-1)
|
||
JRST .+4
|
||
HRRI FR,FILN-1
|
||
CALL RDLIN
|
||
IFNB EOFA, JRST EOFA
|
||
.ELSE CAIA
|
||
MOVE F1+FILN-1,LNNEXT(F1+FILN-1)
|
||
TERMIN
|
||
|
||
; SOME MACROS TO MAKE I/O A LITTLE LESS SYSTEM DEPENDENT.
|
||
; OPTIMIZED IN FAVOR OF ITS.
|
||
IFN ITS,[
|
||
DEFINE M.CLS CH ; CLOSE CHAN
|
||
.CLOSE CH,
|
||
TERMIN
|
||
|
||
DEFINE M.MVCH CH1,CH2 ; MOVE CHANNEL FROM CH1 TO CH2
|
||
.IOPUS CH1,
|
||
.IOPOP CH2,
|
||
TERMIN
|
||
|
||
DEFINE MOUTC CH,?LOC ; SINGLE CHAR OUTPUT
|
||
.IOT CH,LOC
|
||
TERMIN
|
||
|
||
DEFINE M.BIN CH,LOC
|
||
.IOT CH,LOC
|
||
TERMIN
|
||
|
||
DEFINE M.SOUT CH,BPA,CNTA
|
||
SYSCAL SIOT,[MOVEI CH ? BPA ? CNTA]
|
||
.LOSE %LSFIL
|
||
TERMIN
|
||
|
||
DEFINE M.SIN CH,BPA,CNTA
|
||
SYSCAL SIOT,[MOVEI CH ? BPA ? CNTA]
|
||
.LOSE %LSFIL
|
||
TERMIN
|
||
] ;IFN ITS
|
||
|
||
IFN TNX,[
|
||
DEFINE M.CLS CH ; CLOSE CHAN
|
||
SAVE R1
|
||
SKIPLE R1,JFNCHS+CH
|
||
CLOSF
|
||
ERJMP .+1
|
||
SETZM JFNCHS+CH
|
||
REST R1
|
||
TERMIN
|
||
|
||
DEFINE M.MVCH CH1,CH2 ; MOVE CHANNEL FROM CH1 TO CH2
|
||
SAVE R1
|
||
SETZ R1,
|
||
EXCH R1,JFNCHS+CH1
|
||
EXCH R1,JFNCHS+CH2
|
||
CAILE R1,
|
||
CLOSF
|
||
ERJMP .+1
|
||
REST R1
|
||
TERMIN
|
||
|
||
DEFINE MOUTC CH,?LOC ; OUTPUT BYTE AT LOC
|
||
CALL [ PUSH P,JFNCHS+CH
|
||
PUSH P,LOC
|
||
PJRST TOUTC]
|
||
TERMIN
|
||
|
||
DEFINE M.BIN CH,LOC ; INPUT BYTE TO LOC
|
||
CALL [ PUSH P,JFNCHS+CH
|
||
PUSH P,[LOC]
|
||
JRST TINC]
|
||
TERMIN
|
||
|
||
DEFINE M.SOUT CH,BPA,CNTA ; OUTPUT STRING
|
||
MOVNS CNTA
|
||
SYSCAL SOUT,[JFNCHS+CH ? BPA ? CNTA][JUNK ? BPA ? CNTA]
|
||
MOVNS CNTA
|
||
TERMIN
|
||
|
||
DEFINE M.SIN CH,BPA,CNTA ; INPUT STRING
|
||
MOVEI T,[JFNCHS+CH ? BPA ? CNTA]
|
||
CALL TINS
|
||
TERMIN
|
||
|
||
] ;IFN TNX
|
||
|
||
DEFINE MOUTI CH,VAL ; OUTPUT IMMEDIATE VALUE
|
||
MOUTC CH,[VAL]
|
||
TERMIN
|
||
|
||
; SO MIDAS-BORROWED CODE WILL INTEGRATE BETTER.
|
||
DEFINE ETF ?ASCZ
|
||
JRST [ JSP T,ERRMSG
|
||
ASCZ
|
||
]
|
||
TERMIN
|
||
DEFINE TYPE &STR
|
||
CALL [ PUSH P,[[ASCIZ STR]]
|
||
PJRST TYPM]
|
||
TERMIN
|
||
|
||
DEFINE PRINTI &STR&
|
||
MOVEI C,.LENGTH STR
|
||
MOVE W2,[440700,,[ASCIZ STR]]
|
||
CALL PNTCNT
|
||
TERMIN
|
||
|
||
SUBTTL File Description Storage (FILBLK's)
|
||
|
||
|
||
; Definitions for indices into a FILBLK.
|
||
|
||
; Scratch block FB is formed while defining indices...
|
||
OFFSET -.
|
||
; Lots of crocks depend on the exact order of these 4 items.
|
||
IFN ITS\DEC,[
|
||
$F6DEV:: 0 ; SIXBIT Device name
|
||
$F6FN1:: 0 ; SIXBIT Filename (on ITS, FN1)
|
||
$F6FN2:: 0 ; SIXBIT Extension (on ITS, FN2)
|
||
$F6DIR:: 0 ; SIXBIT Directory (may be numerical PPN)
|
||
$FDEV==:$F6DEV ; These definitions made so some common code can do
|
||
$FDIR==:$F6DIR ; the right things.
|
||
$FNAME==:$F6FN1
|
||
$FEXT==:$F6FN2
|
||
$FVERS==:$F6FN2
|
||
]
|
||
IFN TNX,[ ; Almost all entries here are BP's to ASCIZ strings.
|
||
$FDEV:: 0 ; Device name
|
||
$FDIR:: 0 ; Directory name
|
||
$FNAME:: 0 ; File name (i.e. main name)
|
||
$FEXT:: 0 ; File type (or extension)
|
||
$FVERS:: 0 ; File version (or generation). NUMBER, not string.
|
||
$FTEMP:: 0 ; -1 => File is a temporary file.
|
||
$FACCT:: 0 ; Account string
|
||
$FPROT:: 0 ; Protection string
|
||
$FJFN:: 0 ; JFN for file (may be <desired JFN>,,<temp JFN>)
|
||
]
|
||
L$FBLK==. ; Length of a FILBLK.
|
||
OFFSET 0 ; End of index definitions.
|
||
|
||
|
||
INFB: BLOCK L$FBLK
|
||
LSTFB: BLOCK L$FBLK
|
||
|
||
IFN TNX,[
|
||
JFNCHS: BLOCK 20 ; INDEXED BY CHAN #, HOLDS JFNS
|
||
]
|
||
|
||
;SRCCOM STARTS HERE
|
||
|
||
BEG: MOVE P,[-LPDL,,PPSET-1] ;SET UP PDL.
|
||
|
||
IFN ITS,[
|
||
.OPEN CHTTI,[.UAI,,'TTY]
|
||
ERRHLT
|
||
.OPEN CHTTO,[.UAO,,'TTY]
|
||
ERRHLT
|
||
.SUSET [.RSNAM,,DEFDIR] ;GET DEFAULT DIR.
|
||
.SUSET [.ROPTIO,,W1]
|
||
TLO W1,OPTOPC
|
||
.SUSET [.SOPTIO,,W1]
|
||
.SUSET [.SMASK,,[%PIMPV]]
|
||
.SUSET [.SMSK2,,[1_CHTTO+1_CHOUT]] ;ENABLE --MORE-- INTERRUPTS
|
||
] ;IFN ITS
|
||
|
||
IFN TNX,[
|
||
RESET
|
||
CALL SEE20X ; SEE IF 10X OR 20X.
|
||
MOVEI W1,.PRIIN
|
||
MOVEM W1,JFNCHS+CHTTI
|
||
MOVEI W1,.PRIOU
|
||
MOVEM W1,JFNCHS+CHTTO
|
||
]
|
||
CALL GETJCL ; LOOK FOR JCL, SKIP IF FOUND
|
||
CAIA ; NONE
|
||
JRST RESTR1 ; HAVE SOME, GO EXECUTE.
|
||
|
||
MOVE 0,[SIXBIT/SRCCOM/] ;NO COMMAND STRING FROM SUPERIOR:
|
||
CALL TTOSIX ;IDENTIFY SELF TO USER.
|
||
MOUTI CHTTO,40 ;SPACE
|
||
IFDEF .FVERS,[
|
||
MOVE 0,[.FVERS]
|
||
CALL TTODEC
|
||
]
|
||
.ELSE [
|
||
MOVE 0,[.FNAM2] ;PRINT VERSION NUMBER.
|
||
CALL TTOSIX
|
||
]
|
||
JRST RESTRT
|
||
|
||
;COME HERE FOR A NEW COMMAND, AFTER FINISHED OR ERROR.
|
||
|
||
RESTRT: SETZM TTIBUF
|
||
RESTR1: MOVE P,[-LPDL,,PPSET-1] ;SET UP PUSH DOWN LIST
|
||
IFN ITS,.SUSET [.SWHO1,,[0]] ;CLEAR USER-SPEC'D WHOLINE FIELDS.
|
||
IFN ITS,.SUSET [.SMEMT,,[ENDCOR]]
|
||
SETZB FR,BEGP ;THIS IS THE ZERO WHICH WILL
|
||
;BE "BLT"ED TO CLEAR CORE
|
||
MOVE 0,[BEGP,,BEGP+1]
|
||
BLT ENDP-1
|
||
IFN TNX,[
|
||
MOVE 0,[FNBUF,,FNBUF+1]
|
||
SETZM FNBUF
|
||
BLT 0,FNBUF+LFNBUF-1
|
||
];TNX
|
||
|
||
MOVE W1,[440700,,MRGBF]
|
||
MOVEM W1,MRGBP
|
||
MOVEI W1,MRGBSZ
|
||
MOVEM W1,MRGCT
|
||
MOVE W1,SEG1
|
||
MOVEM W1,LBUFP1
|
||
MOVE W1,SEG2
|
||
MOVEM W1,LBUFP2
|
||
MOVE W1,SEG3
|
||
MOVEM W1,LBUFP3
|
||
AOS PAGNUM+0 ;ZEROED BY BLT ABOVE-1ST PAGE IS 1
|
||
AOS PAGNUM+1 ;DITTO FOR SECOND FILE
|
||
AOS PAGNUM+2
|
||
AOS LINNUM+0 ;SAME TRUE FOR 1ST LINE
|
||
AOS LINNUM+1
|
||
AOS LINNUM+2
|
||
SKIPE TTIBUF ;IF HAVE A JCL COMMAND,
|
||
SETOM CTLCF ;SAY RETURN AFTER JUST THIS CMD.
|
||
SKIPN TTIBUF
|
||
CALL CMDLIN ;NO DDT CMD, READ TTY LINE.
|
||
CALL TRYHLP ;IF COMMAND IS JUST "?" OR "HELP", PRINT HELP.
|
||
MOVE C,FSTTY ;OUTPUT DEFAULTS TO TTY IF NOT SPEC'D,
|
||
SKIPN CMDFIL ;UNLESS WE'RE IN A COMMAND FILE.
|
||
MOVEM C,LSTFB+$FDEV
|
||
MOVEI FP,INFB
|
||
CALL RFILE ;READ FILE NAME
|
||
CAIE C,"=
|
||
IFE TWX,[ ;Don't recognize "_" on Twenex, screws filenames
|
||
CAIN C,"_ ;IF FOLLOWED BY "_", IS OUTPUT SPEC,
|
||
CAIA
|
||
]
|
||
JRST CMD3
|
||
MOVE C,[INFB,,LSTFB]
|
||
BLT C,LSTFB+L$FBLK-1 ;SO USE AS LST FILE NAMES.
|
||
SETOM LSTEXP ;SAY LST FILE WAS EXPLICITLY SPECIFIED.
|
||
SETZM INFB+$FDEV
|
||
SKIPE CMDFIL ;IF NOT IN A COMMAND FILE, 1ST INPUT FILE SNAME
|
||
SETZM INFB+$FDIR ;DEFAULTS TO OUTPUT FILE SNAME.
|
||
CALL RFILE ;AND READ ANOTHER SPEC FOR 1ST INPUT FILE.
|
||
JRST CMD3
|
||
|
||
;NOW HAVE READ WHAT IS CERTAINLY THE 1ST INPUT SPEC.
|
||
CMD3: MOVE W2,DEFDIR ;DEFAULT THE OUTPUT FILE DEV AND SNAME NOW.
|
||
SKIPE CMDFIL ;CAN DO IT SINCE IT DOESN'T DEPEND ON SWITCH SETTINGS
|
||
MOVE W2,CMDOS ;AND MUST DO IT SINCE MIGHT GO TO CMDXCT AND WANT
|
||
SKIPN LSTFB+$FDIR ;TO KNOW THEIR FINAL VALUES.
|
||
MOVEM W2,LSTFB+$FDIR
|
||
MOVE W2,FSDSK
|
||
SKIPE CMDFIL
|
||
MOVE W2,CMDOD
|
||
SKIPN LSTFB+$FDEV
|
||
MOVEM W2,LSTFB+$FDEV
|
||
TLNN FR,FLINDR ;IF THE FIRST INPUT FILE IS INDIRECT, DEFAULT THE FN2
|
||
JRST CMD6 ;OF THE FILE TO GO INDIRECT THROUGH TO
|
||
MOVE W1,FSCMP ;TO THE FN2 OF THE LISTING FILE, AS WELL AS WE CAN.
|
||
TLNE FR,FLARCH ;CAN LOSE IN OBSCURE SITUATIONS THAT THE DOCUMENTATION
|
||
MOVE W1,FSCMPA ;WARNS USERS TO AVOID.
|
||
SKIPE LSTFB+$FEXT
|
||
MOVE W1,LSTFB+$FEXT
|
||
SKIPN INFB+$FEXT
|
||
MOVEM W1,INFB+$FEXT
|
||
MOVE W1,LSTFB+$FDIR ;ALSO DEFAULT SNAME AND DEV THAT WAY, BUT NEVER USE TTY:
|
||
SKIPN INFB+$FDIR ;NOTE THAT THE FN1 WILL DEFAULT TO THE LIST FILE'S
|
||
MOVEM W1,INFB+$FDIR ;ANYWAY.
|
||
MOVE W1,LSTFB+$FDEV
|
||
CAMN W1,FSTTY
|
||
MOVE W1,FSDSK
|
||
SKIPN INFB+$FDEV
|
||
MOVEM W1,INFB+$FDEV
|
||
CMD6: MOVE W1,CMDIS
|
||
SKIPN CMDFIL
|
||
MOVE W1,DEFDIR
|
||
SKIPN INFB+$FDIR
|
||
MOVEM W1,INFB+$FDIR
|
||
MOVE W1,CMDID ;DEFAULT DEVICE FOR 1ST INPUT FILE DEPENDS ON
|
||
SKIPN CMDFIL ;WHETHER WE'RE IN A COMMAND FILE.
|
||
MOVE W1,FSDSK
|
||
SKIPN INFB+$FDEV
|
||
MOVEM W1,INFB+$FDEV
|
||
SKIPN W1,INFB+$FVERS
|
||
MOVE W1,FVLOW ;IF ONLY ONE INPUT FILE SPECIFIED, DEFAULT ITS FN2 TO "<",
|
||
SKIPG TTICNT ;SINCE 2ND INPUT FILE WILL BE THE ">" OF THE SAME FILE.
|
||
MOVEM W1,INFB+$FVERS
|
||
RFIND1: MOVEI W1,CHIN1
|
||
CALL INOPEN ;NOW OPEN CHANNEL CHIN1.
|
||
TLNE FR,FLXCTF ;IS THIS AN EXECUTE FILE?
|
||
JRST CMDXCT
|
||
TLNE FR,FLINDR ;MAYBE THE FILE WE OPENED JUST HAS THE NAMES OF THE
|
||
JRST RFINDR ;REAL 1ST INPUT FILE. IF SO, READ THEM.
|
||
CALL RFILE ;READ NAMES OF & OPEN 2ND INPUT.
|
||
MOVEI W1,CHIN2
|
||
CALL INOPEN
|
||
TLNE FR,FLINDR\FLXCTF
|
||
JRST ERRIN2 ;FILE 2 INDIRECT? THAT ISN'T ALLOWED.
|
||
SKIPG TTICNT ;MORE FILES? MUST BE A 3-WAY MERGE.
|
||
JRST CMD4
|
||
CALL RFILE ;READ THE THIRD FILE'S NAME.
|
||
TLNN FR,FLMERG
|
||
JRST ERR3NM ;ERROR IF /M NOT SPECIFIED.
|
||
SETOM 3WAY
|
||
MOVEI W1,CHIN3
|
||
CALL INOPEN
|
||
TLNE FR,FLINDR\FLXCTF ;ERROR IF THIRD FILE IS INDIRECT.
|
||
JRST ERRIN3
|
||
SKIPG TTICNT ;ERROR IF ANYTHING LEFT AFTER THIRD FILE NAME.
|
||
JRST ERRXTRA
|
||
JRST CMD4
|
||
|
||
;NOW OPEN THE OUTPUT FILE.
|
||
CMD4: MOVEI FP,LSTFB
|
||
MOVE W2,FSCMP ;NORMAL DEFAULT OUTPUT FN2.
|
||
TLNE FR,FLARCH
|
||
MOVE W2,FSCMPA
|
||
MOVEI W1,CHOUT ;NORMALLY, SPEC'D FILE IS OUTPUT FILE,
|
||
TLNN FR,FLMERG
|
||
JRST CMD5
|
||
TLNE FR,FLARCH
|
||
JRST ERRARC
|
||
MOVEI W1,CHMRG ;BUT IF /M, IT IS MERE FILE NAME,
|
||
IFN ITS,[
|
||
.OPEN CHOUT,[.UAO,,'TTY] ;AND OUTPUT IS TO TTY:
|
||
ERRHLT
|
||
]
|
||
IFN TNX,[
|
||
PUSH P,JFNCHS+CHTTO
|
||
POP P,JFNCHS+CHOUT
|
||
]
|
||
MOVE W2,FSDMF2
|
||
TLNE FR,FLFLAG ;ALSO, WE HAVE DIFFERENT DEFAULT FN2'S
|
||
MOVE W2,FSFLGD
|
||
MOVE T,FSTTY
|
||
SKIPL LSTEXP ;AND DON'T DEFAULT TO TTY:; USE DSK: INSTEAD.
|
||
CAME T,LSTFB+$FDEV
|
||
JRST CMD5
|
||
MOVE T,FSDSK
|
||
MOVEM T,LSTFB+$FDEV
|
||
CMD5: SKIPN LSTFB+$FEXT ;DEFAULT THE FN2 IF NEC.
|
||
MOVEM W2,LSTFB+$FEXT
|
||
IFN ITS,[
|
||
SYSCAL TRANS,[
|
||
$FDEV(FP) ? $FNAME(FP) ? $FEXT(FP) ? $FDIR(FP)
|
||
MOVEI .UAO
|
||
MOVEM $FDEV(FP) ? MOVEM $FNAME(FP)
|
||
MOVEM $FEXT(FP) ? MOVEM $FDIR(FP)]
|
||
CALL OPENL
|
||
SYSCAL OPEN,[5000,,.UAO ? W1
|
||
$FDEV(FP) ? ['_SRCCO] ? ['OUTPUT] ? $FDIR(FP)]
|
||
CALL OPENL ;ERROR RTN, IN CASE FAILED.
|
||
SYSCAL TTYGET,[MOVEI CHOUT ? MOVEM TTYST1 ? MOVEM TTYST2 ? MOVEM W1]
|
||
JRST CMD2 ;JUMP IF OUTPUT FILE ISN'T A TTY.
|
||
SETOM OUTTTY
|
||
MOVEM W1,TTYSTS ;IT IS A TTY; SAVE THE TTYSTS TO RESTORE LATER
|
||
TLZE W1,%TSMOR ;AND TURN ON **MORE**'ING NOW.
|
||
SYSCAL TTYSET,[MOVEI CHOUT ? TTYST1 ? TTYST2 ? W1]
|
||
JFCL
|
||
] ;IFN ITS
|
||
IFN TNX,[
|
||
MOVE T,FSTTY
|
||
CAMN T,LSTFB+$FDEV ; ABOUT TO OPEN TTY FOR OUTPUT?
|
||
JRST [ PUSH P,JFNCHS+CHTTO ; IF SO JUST DUPLICATE TTY JFN
|
||
POP P,JFNCHS+CHOUT
|
||
SETOM OUTTTY
|
||
JRST CMD20]
|
||
MOVEI FP,LSTFB
|
||
HRLI FP,(W1) ; GET <CHAN>,,<FB PTR>
|
||
CALL OPNWR
|
||
CALL OPENL
|
||
CMD20:
|
||
]
|
||
|
||
;FINAL INITIALISATION, AND PRINTING OF THE FILE HEADER.
|
||
CMD2: SETZB F1,F2 ;RIGHT NOW WE HAVE NO LINES OF EITHER FILE IN CORE.
|
||
TLNE FR,FLMERG ;IF MERGING, LINES FLUSHED FROM FILE 1
|
||
SETOM MRGOUT+0 ;GO OUT TO THE MERGE FILE.
|
||
SETZ 0,
|
||
IFN ITS,[
|
||
.SUSET [.SWHO1,,[.BYTE 8 ? 166 ? 0 ? 55 ? ",]]
|
||
.SUSET [.SWHO3,,[1,,1]] ;INITIALIZE THE USER WHO-LINE FIELDS.
|
||
.SUSET [.SWHO2,,['HEADER]]
|
||
]
|
||
SKIPE 3WAY ;3-WAY MERGES HAVE A SPECIAL MAIN LOOP.
|
||
JRST 3LOOP
|
||
TLNE FR,FLMERG
|
||
JRST ENTER
|
||
MOVSI W1,-WPL
|
||
MOVE T,HBUF1(W1) ;LOOK FOR DIFFERENCES BETWEEN REAL FILE NAMES
|
||
CAMN T,HBUF2(W1) ;OF OUR TWO INPUT FILES.
|
||
AOBJN W1,.-2
|
||
TLNN FR,FLOVRD ;UNLESS FORCED BY /!,
|
||
JUMPGE W1,FIN5 ;IF THE NAMES ARE THE SAME, DON'T WASTE TIME COMPARING.
|
||
MOVEI W1,[ASCIZ /
|
||
;COMPARISON OF /]
|
||
CALL PRINT
|
||
MOVE W1,RCHSTP
|
||
CALL PRINT
|
||
MOVEI W1,[ASCIZ / AND /];RFINDR DEPENDS ON EXACT STRINGS USED HERE.
|
||
CALL PRINT
|
||
MOVE W1,RCHSTP+1
|
||
CALL PRINT
|
||
MOVEI W1,[ASCIZ /
|
||
;OPTIONS ARE /] ;NOTE RFINDR DEPENDS ON PRECISE STRING USED HERE.
|
||
CALL PRINT
|
||
IRPS X,,FLARCH FLALL FLCMNT FLENDL FLCASE FLLABL FLSPAC FLFNUM FLXLBL,Y,,A B C E K L S W Y
|
||
MOVEI W1,[ASCIZ * /Y*]
|
||
TLNE FR,X
|
||
CALL PRINT
|
||
TERMIN
|
||
MOVEI W1,[ASCIZ " /#"]
|
||
SKIPE FVBIN
|
||
CALL PRINT
|
||
MOVEI W1,[ASCIZ " /$"]
|
||
SKIPE FSBIN
|
||
CALL PRINT
|
||
MOVEI W1,[ASCIZ * /*]
|
||
CALL PRINT
|
||
MOVE T,NUMLIN
|
||
AOS T
|
||
CALL PNTDEC
|
||
CALL PCRLF
|
||
CALL PCRLF
|
||
JRST ENTER
|
||
|
||
ENTER:
|
||
IFN ITS,.SUSET [.SWHO2,,[SIXBIT/SAME/]]
|
||
SKIPE FVBIN ; Normally no binary compare
|
||
JRST BSAME ; Gadzooks! Use special routine.
|
||
SKIPE FSBIN
|
||
JRST SBSAME ; Use special SBLK compare routine
|
||
|
||
;THIS IS THE MAIN LOOP OF SRCCOM.
|
||
|
||
;COME HERE WHEN THE LAST TWO LINES MATCHED, TO TRY THE NEXT TWO.
|
||
SAME: SKIPE F1,LNNEXT(F1) ;ADVANCE PAST THE LINE THAT MATCHED
|
||
JRST SAME1
|
||
TRZ FR,-1 ;IF NO MORE LINES IN CORE, FLUSH ALL
|
||
SKIPE MRGOUT+0 ;THE LINES WE PASSED BY,
|
||
CALL MOVEUP
|
||
SETZM NLINE1 ;(IN THE SIMPLE COMMON CASE, FLUSH THEM FAST)
|
||
CALL RDLIN ;AND READ ANOTHER.
|
||
JRST END0 ;EOF => CHECK FILE 2 FOR EOF.
|
||
ERRHLT
|
||
SAME1: SKIPE F2,LNNEXT(F2) ;SIMILAR FOR F2,
|
||
JRST SAME2
|
||
SETZM NLINE2 ;BUT SINCE MRGOUT+1 SHOULD BE ZERO, IT'S SIMPLE.
|
||
HRRI FR,1
|
||
CALL RDLIN
|
||
JRST DIFF ;EOF IN FILE 2 BUT NOT IN FILE 1 => IT'S A DIFFERENCE.
|
||
ERRHLT
|
||
SAME2: CALL COMPL
|
||
JRST SAME ;THE TWO LINES ARE IDENTICAL; KEEP SCANNING.
|
||
JRST DIFF ;ELSE SEE HOW BIG THIS RUN OF DIFFERENCES IS.
|
||
|
||
; BINARY COMPARE - Main loop.
|
||
|
||
BSAME: TRZ FR,-1
|
||
CALL RDWRD ; Get word in W1
|
||
JRST BEND0 ; EOF => check file 2 for EOF
|
||
MOVE W2,W1
|
||
HRRI FR,1
|
||
CALL RDWRD ; Get another word from file 2
|
||
JRST BEND1 ; EOF on file 2, it"s a difference.
|
||
CAMN W1,W2 ; Compare words
|
||
JRST BSAME ; Won, get next one.
|
||
JRST BDIFF
|
||
BEND0: MOVE W2,W1 ; EOF on file 1, check file 2
|
||
HRRI F1,1
|
||
CALL RDWRD
|
||
JRST FIN2 ; If EOF on file 2 also, win!
|
||
PRINTI " EOF on file 1
|
||
"
|
||
AOS ERRCNT
|
||
JRST FIN2
|
||
BEND1: PRINTI " EOF on file 2
|
||
"
|
||
AOS ERRCNT
|
||
JRST FIN2
|
||
|
||
; Words are different. Must print out and show
|
||
; addr: <wd 1> <wd 2> <xor>
|
||
BDIFF: AOS ERRCNT ; Bump count of diffs
|
||
PUSH P,W1
|
||
PUSH P,W2
|
||
MOVE T,GWORDL(FR)
|
||
SUB T,GWORDC(FR) ; Find # words read thus far
|
||
CALL PNTOCT
|
||
PRINTI ": "
|
||
MOVE T,(P)
|
||
CALL PNTHWD
|
||
PRINTI " "
|
||
MOVE T,-1(P)
|
||
CALL PNTHWD
|
||
PRINTI " XOR= "
|
||
POP P,T
|
||
XOR T,(P)
|
||
CALL PNTHWD
|
||
POP P,T
|
||
CALL PCRLF
|
||
JRST BSAME
|
||
|
||
; Program ("SBLK") BINARY COMPARE - Main loop.
|
||
|
||
.SCALAR GWADR ; Address of word to get
|
||
|
||
|
||
SBSAME: TRZ FR,-1
|
||
CALL RDUWRD ; Get word in W1
|
||
JRST SBEND0 ; EOF => check file 2 for EOF
|
||
MOVE W2,W1
|
||
HRRI FR,1
|
||
CALL RDUWRD ; Get another word from file 2
|
||
JRST SBEND1 ; EOF on file 2, it"s a difference.
|
||
CAME W1,W2 ; Compare words
|
||
JRST SBDIFF
|
||
SBSAM0: AOS W1,GWADR
|
||
CAIG W1,-1
|
||
JRST SBSAME
|
||
JRST FIN2
|
||
|
||
SBEND0: MOVE W2,W1 ; EOF on file 1, check file 2
|
||
HRRI F1,1
|
||
CALL RDWRD
|
||
JRST FIN2 ; If EOF on file 2 also, win!
|
||
PRINTI " EOF on file 1
|
||
"
|
||
AOS ERRCNT
|
||
JRST FIN2
|
||
SBEND1: PRINTI " EOF on file 2
|
||
"
|
||
AOS ERRCNT
|
||
JRST FIN2
|
||
|
||
; Words are different. Must print out and show
|
||
; addr: <wd 1> <wd 2> <xor>
|
||
SBDIFF: AOS ERRCNT ; Bump count of diffs
|
||
PUSH P,W2
|
||
PUSH P,W1
|
||
MOVE T,GWADR ; Find # words read thus far
|
||
CALL PNTOCT
|
||
PRINTI ": "
|
||
MOVE T,-1(P) ; Get wd from file 1
|
||
CALL PNTHWD
|
||
PRINTI " "
|
||
MOVE T,(P) ; Then wd from file 2
|
||
CALL PNTHWD
|
||
PRINTI " XOR= "
|
||
POP P,T
|
||
XOR T,(P)
|
||
CALL PNTHWD
|
||
POP P,T
|
||
CALL PCRLF
|
||
JRST SBSAM0
|
||
|
||
;COME HERE WHEN A DIFFERENCE IS SEEN. F1 AND F2 POINT TO THE 1ST PAIR OF NON-MATCHING
|
||
;LINES, OR ARE ZERO TO SAY THAT AN ENTIRE FILE HAS BEEN MATCHED OFF.
|
||
DIFF: CALL MOVEUP ;FLUSH ANY MATCHING LINES STILL IN CORE BEFORE THOSE TWO.
|
||
TRC FR,1
|
||
CALL MOVEUP
|
||
SKIPE 0 ;0 SHOULD ALWAYS HOLD 0 FOR NEXTLN'S SAKE.
|
||
ERRHLT
|
||
IFN ITS,.SUSET [.SWHO2,,[SIXBIT/DIFF/]]
|
||
SETZM NCOMP1 ;NCOMP1 GETS NUMBER OF LINES OF FILE 1 WE HAVE FOR
|
||
SKIPE F1 ;CONSIDERATION.
|
||
AOS NCOMP1
|
||
SETZM NCOMP2 ;NCOMP2 GETS THE SAME THING FOR FILE 2.
|
||
SKIPE F2
|
||
AOS NCOMP2
|
||
DIFFRD: NEXTLN 1,END2 ;READ ANOTHER LINE FROM EACH FILE.
|
||
AOS NCOMP1
|
||
NEXTLN 2,DIFF2 ;NO NEW LINE FROM FILE 2 => DON'T COMPARE FILE 1 WITH IT
|
||
DIFF3: AOS NCOMP2
|
||
SKIPN CS,NCOMP1 ;HOW MANY FILE 1 LINES SHOULD WE CONSIDER?
|
||
JRST DIFFRD ;NONE?
|
||
SKIPA F1,LBUFP1 ;ELSE COMPARE ALL THE NON-MATCHING LINES OF FILE 1, 1 AT A TIME,
|
||
DIFF0: MOVE F1,W1 ;WITH THE NEW LINE FROM FILE 2.
|
||
CALL COMPL
|
||
CALL MULTI ;MATCH => CHECK FOR MULTI-LINE MATCH, GO TO SAME IF FOUND.
|
||
SKIPE W1,LNNEXT(F1)
|
||
SOJG CS,DIFF0
|
||
;AFTER COMPARING ALL THE FILE 1 LINES WITH THE NEW FILE 2 LINE, OR IF THERE IS NO NEW
|
||
;FILE 2 LINE, COME HERE TO COMPARE THE NEW FILE 1 LINE WITH ALL THE FILE 2 LINES.
|
||
;F1 IS ALREADY POINTING AT THE NEW FILE 1 LINE ("NEW" MEANS THAT DIFFRD GOT IT.
|
||
;IT MIGHT HAVE BEEN IN CORE ALREADY DUE TO NEXTLN'S DONE INSIDE MULTI).
|
||
DIFF2: SKIPE EOFFL1 ;BUT DON'T DO IT IF NO NEW FILE 1 LINE.
|
||
JRST DIFFRD
|
||
SKIPN CS,NCOMP2 ;HOW MANY LINES ARE WE CONSIDERING YET FROM FILE 2?
|
||
JRST DIFFRD ;NONE => NOTHING TO COMPARE WITH THE NEW LINE FROM 1.
|
||
SKIPA F2,LBUFP2 ;(MAY NOT BE SAME AS NLINE2, IF MULTI READ SOME LINES.)
|
||
DIFF1: MOVE F2,W1 ;ELSE LOOP HERE OVER THE FILE 2 LINES.
|
||
CALL COMPL
|
||
CALL MULTI
|
||
SKIPE W1,LNNEXT(F2)
|
||
SOJG CS,DIFF1
|
||
JRST DIFFRD ;NO MATCH => READ ANOTHER PAIR OF LINES AND TRY MATCHING THEM.
|
||
|
||
END0: SKIPE F2,LNNEXT(F2) ;HERE WHEN EOF IN FILE 1 AT SAME.
|
||
JRST DIFF ;MORE LINES IN FILE 2 => THEY'RE DIFFERENT.
|
||
SETZM NLINE2
|
||
HRRI FR,1
|
||
CALL RDLIN
|
||
JRST FIN2 ;EOF IN FILE 2 => ALL DONE.
|
||
ERRHLT
|
||
JRST DIFF
|
||
|
||
END2: NEXTLN 2,FINDIF ;NO NEW FILE 1 LINE IN DIFFRD. NO NEW FILE 2 LINE EITHER =>
|
||
JRST DIFF3 ;ALL THE NON-MATCHING LINES WE HAVE ARE DIFFERENCES.
|
||
;NEW LINE FROM FILE 2 => TRY MATCHING IT AGAINST FILE 1 LINES.
|
||
|
||
;AT THIS POINT NEITHER FILE HAS ANY MORE LINES TO BE READ.
|
||
;PRINT AS DIFFERENCES ANY LINES REMAINING FOR EITHER FILE.
|
||
|
||
FINDIF: SETZB F1,F2 ;MAKE SURE ALL LINES PRINTED IN CASE NO /E.
|
||
CALL COMSPC ;SEE IF DIFFERENCES VANISH IF WE IGNORE SPACES AND COMMENTS.
|
||
JRST FIN2 ;THEY DO; DON'T PRINT AS DIFFERENCES.
|
||
CALL PNTBTH ;PRINT ANY LINES
|
||
CALL TRYMRG
|
||
JRST FIN2
|
||
MOVEI W1,[ASCIZ/***************
|
||
/]
|
||
CALL PRINT
|
||
|
||
;COME HERE WHEN THE OUTPUT AND MERGE FILES ARE ALL GENERATED.
|
||
FIN2: TRZ FR,-1 ;OUTPUT THE STUFF IN FILE 1, IN CASE IN /M MODE.
|
||
CALL MOVEUP
|
||
TLNN FR,FLARCH ;IF SUPOSED TO BE ARCHIVING, DO THE APPEND NOW.
|
||
JRST FIN3
|
||
SKIPN ERRCNT ;BUT IF NO NEW STUFF TO APPEND, DO NOTHING,
|
||
JRST FIN5 ;AND THROW AWAY OUR 0-BLOCK FILE.
|
||
MOVE FP,[CHIN1,,LSTFB]
|
||
CALL OPNRDA
|
||
JRST FIN3 ;NO OLD FILE => JUST MAKE NEW ONE.
|
||
MOUTI CHOUT,^L
|
||
FIN4: MOVE W2,GCHARB ;IF SO, IF WE'RE ABOUT TO OVERWRITE A FILE,
|
||
MOVEI C,FILBFL*5 ;APPEND ITS OLD CONTENTS TO OUR OUTPUT, WITH ^L BETWEEN.
|
||
M.SIN CHIN1,W2,C ; INPUT
|
||
MOVNS C
|
||
ADDI C,FILBFL*5
|
||
JUMPE C,FIN3
|
||
MOVE W2,GCHARB
|
||
CALL PNTCNT
|
||
JRST FIN4
|
||
|
||
FIN5:
|
||
M.CLS CHOUT
|
||
IFN ITS,[
|
||
SYSCAL DELETE,[LSTFB+$FDEV ? ['_SRCCO] ? ['OUTPUT] ? LSTFB+$FDIR]
|
||
JFCL
|
||
]
|
||
|
||
FIN3: TLNE FR,FLMERG
|
||
CALL MRGFRC ;IF MERGING, FORCE OUT OUR BUFFER.
|
||
MOVEI W1,CHOUT ;WHICH CHANNEL IS OUR MOST IMPORTANT OUTPUT FILE ON?
|
||
TLNE FR,FLMERG
|
||
MOVEI W1,CHMRG
|
||
CALL RENMLO
|
||
MOVEI T,[ASCIZ /NO DIFFERENCES ENCOUNTERED/]
|
||
SKIPN ERRCNT ;ANY DIFFERENCES?
|
||
CALL TYPMS0 ;NO, PRINT MESSAGE
|
||
MOVEI T,[ASCIZ /? FILES ARE DIFFERENT/]
|
||
SKIPE QFLAG ;/Q MODE ON?
|
||
SKIPN ERRCNT ;/Q YES, ANY DIFFERNCES
|
||
SKIPA ;/Q NO
|
||
CALL TYPMS0 ;/Q YES
|
||
SKIPE ERRCNT ;/M ANY DIFFERENCES?
|
||
TLNN FR,FLMERG ;/M YES, MERGE IN PROGRESS?
|
||
JRST RELDEV ;/M NO, END OF SOURCE COMPARE
|
||
MOVEI T,[ASCIZ /END OF MERGE/]
|
||
TLNN FR,FLISWT\FLFLAG
|
||
CALL TYPMSG ;/M YES, PRINT END OF MERGE
|
||
JRST RELDEV ;END OF SOURCE COMPARE
|
||
|
||
;CALL MULTI TO CHECK FOR A MULTI-LINE MATCH, IF NECESSARY.
|
||
;IF THERE IS ONE, OR IT ISNT NECESSARY (NUMLIN = 0), RETURNS TO SAME
|
||
;AFTER PRINTING THE DIFFERENCES. IF THE MATCH FAILS, IT RETURNS
|
||
;NON-SKIPPING TO ITS CALLER.
|
||
|
||
;IN A 3-WAY MERGE, WE ARE USED TO COMPARE FILES 1 AND 2.
|
||
;WHEN WE FIND A MULTI-LINE MATCH, WE PUSH AN ENTRY ON
|
||
;12MTAB, THE TABLE OF PLACES WHERE FILES 1 AND 2 MATCH.
|
||
;EACH SUCH PLACE GETS COMPARED AGAINST FILE 3 LATER.
|
||
|
||
MULTI: SAVE CS
|
||
MOVEM F1,TEMPF1 ;SAVE CURRENT POINTERS
|
||
MOVEM F2,TEMPF2
|
||
SKIPG NUMLIN ;MULTIPLE LINE TEST?
|
||
JRST MULT8 ;NO
|
||
SETZM NUMTMP ;INIT MULTI-LINE COUNTER
|
||
MULT2: NEXTLN 1,MULTE ;MUST GET A NEW LINE FROM BOTH FILES
|
||
NEXTLN 2,MULT4 ;TO CONTINUE THE MULTI-LINE MATCH.
|
||
CALL COMPL ;COMPARE THEM
|
||
JRST MULT6 ;MATCH, TEST MULTI COUNTER
|
||
MULT4: SKIPE F1,TEMPF1 ;NO MATCH, RESET REGS
|
||
SETZM EOFFL1 ;IF NO LONGER AT LAST LINE, CAN'T BE AT EOF.
|
||
SKIPE F2,TEMPF2
|
||
SETZM EOFFL2
|
||
REST CS
|
||
RET
|
||
|
||
MULTE: NEXTLN 2,MULT8
|
||
JRST MULT4
|
||
|
||
MULT6: AOS W1,NUMTMP ;INDEX MULTI-LINE COUNTER
|
||
CAMGE W1,NUMLIN ;TEST FOR ENOUGH LINES MATCHED
|
||
JRST MULT2 ;COMPARE NEXT TWO.
|
||
MULT8: SKIPE 3WAY
|
||
JRST [ MOVE W1,TEMPF2 ;IN A 3-WAY MERGE, RECORD THIS MATCH OF FILES 1 AND 2
|
||
HRL W1,TEMPF1
|
||
IDPB W1,12MTBP
|
||
JRST MULT4] ;AND RETURN TO OUR CALLER (JUST AS IF WE HAD FAILED).
|
||
EXCH F1,TEMPF1 ;REMEMBER WHERE THE MULTI-LINE MATCH STOPPED,
|
||
EXCH F2,TEMPF2 ;GO BACK TO WHERE IT STARTED.
|
||
SUB P,[2,,2] ;FLUSH MULTI'S RETURN ADDRESS.
|
||
CALL COMSPC ;SEE IFF ALL DIFFERENCES VANISH WHEN IGNORE SPACES & COMMENTS.
|
||
JRST MULT10
|
||
CALL PNTBTH ;PRINT DIFFERENCES
|
||
|
||
;THE TEXT OF DIFFERENCES HAS BEEN PRINTED--PUT IN ******
|
||
;AND A CARRIAGE RETURN-LINE FEED AND GO BACK AND START COMPARING
|
||
;WHEN WE START COMPARING AGAIN THE LINE POINTERA WILL
|
||
;BE POINTING TO THE FIRST TWO LINES AFTER THE MATCHING LINES
|
||
|
||
CALL TRYMRG ;/M CHECK IF /M IN EFFECT, ASK FOR COMMAND
|
||
;/M AND OUTPUT IF YES
|
||
JRST MULT10 ;/M IN EFFECT
|
||
MOVE W1,[440700,,[ASCIZ /***************
|
||
|
||
/]]
|
||
CALL PRINT
|
||
MULT10: SKIPE F1,TEMPF1 ;NOW MOVE FORWARD PAST THE LINES MATCHED
|
||
SETZM EOFFL1 ;IN THE MULTI-LINE MATCH.
|
||
SKIPE F2,TEMPF2
|
||
SETZM EOFFL2
|
||
JRST ENTER
|
||
|
||
;AFTER FINDING A RUN OF DIFFERENCES, SEE WHETHER THE FILES ARE IDENTICAL
|
||
;WHEN WE IGNORE SPACES AND COMMENTS ACCORDING TO THE /S AND /C SWITCHES.
|
||
;IF SO, RETURNS NON-SKIPPING. SKIPS IF THE DIFFERENCE SHOULD BE PRINTED.
|
||
;EVEN IF /S AND /C ARE NOT SET, THIS ROUTINE TAKES CARE OF IGNORING
|
||
;DIFFERENCES IN BLANK LINES. ALSO, IF /K, IGNORES DIFFERENCES IN CASE.
|
||
|
||
COMSPC: TLNE FR,FLSPAC ;THIS ROUTINE CAN MAKE A DIFFERENCE IF
|
||
TLNE FR,FLALL ;WE ARE IGNORING BOTH SPACING AND BLANK LINES
|
||
TLNE FR,FLCMNT ;OR WE ARE IGNORING COMMENTS.
|
||
CAIA
|
||
JRST POPJ1 ;NOTHING IGNORED => DO PRINT.
|
||
SAVE F1
|
||
SAVE F2
|
||
SKIPE F1,NLINES+0 ;MAKE F1 AND F2 POINT AT THE FIRST DIFFERING LINES.
|
||
MOVE F1,LBUFP+0
|
||
SKIPE F2,NLINES+1
|
||
MOVE F2,LBUFP+1
|
||
COMSPL: CAMN F1,-1(P) ;HAVE WE CONSIDERED ALL THE LINES FROM FILE 1?
|
||
JRST COMSP2
|
||
HRRI FR,0 ;NO.
|
||
TLNN FR,FLALL ;DON'T SKIP LINES WITH JUST COMMENTS IF NOT IGNORING BLANK LINES!
|
||
CALL BLANKP ;FIRST, TRY TO IGNORE ESSENTIALLY BLANK LINES
|
||
JRST COMSP2 ;IN FILE 1.
|
||
MOVE F1,LNNEXT(F1) ;FOUND ONE => SKIP PAST IT.
|
||
JRST COMSPL
|
||
|
||
COMSP2: CAMN F2,(P) ;THEN TRY FOR BLANK LINES IN FILE 2
|
||
JRST COMSPX ;NO LINES IN FILE 2 => CAN'T WIN.
|
||
HRRI FR,1
|
||
TLNN FR,FLALL
|
||
CALL BLANKP
|
||
JRST COMSP3
|
||
MOVE F2,LNNEXT(F2)
|
||
JRST COMSPL
|
||
|
||
COMSP3: CAMN F1,-1(P) ;IF BOTH FILES HAVE LINES,
|
||
JRST COMSPX
|
||
CALL COMPCS ;SEE IF THEY ARE EQUAL WHEN SPACES & COMMENTS ARE IGNORED.
|
||
JRST COMSPF
|
||
;HERE WHEN WE CAN'T ELIMINATE ANY MORE LINES BY IGNORING SPACES & COMMENTS
|
||
COMSPX: CAMN F1,-1(P) ;IF NO LINES LEFT FROM EITHER FILE, WE WIN
|
||
CAME F2,(P)
|
||
AOS -2(P) ;OTHERWISE, THE DIFFERENCES ARE ESSENTIAL.
|
||
REST F2
|
||
REST F1
|
||
RET
|
||
|
||
;COME HERE IF TWO LINES MATCH WHEN WE IGNORE APPROPRIATE STUFF.
|
||
COMSPF: MOVE F1,LNNEXT(F1) ;SKIP BOTH LINES.
|
||
MOVE F2,LNNEXT(F2)
|
||
JRST COMSPL
|
||
|
||
;SKIP IF THE LINE F1(FR) POINTS AT IS BLANK WHEN
|
||
;SPACES AND COMMENTS ARE IGNORED ACCORDING TO SWITCH SETTINGS.
|
||
BLANKP: HRRZ W1,F1(FR)
|
||
MOVE C,LNSIZE(W1)
|
||
ADD W1,[440700,,LNDATA]
|
||
BLANK1: ILDB T,W1
|
||
SOJLE C,POPJ1 ;WE WIN IF EXHAUST THE LINE AFTER JUST SPACES AND CRLFS.
|
||
CAIE T,^M
|
||
CAIN T,^J
|
||
JRST BLANK1
|
||
CAIE T,40
|
||
CAIN T,^I
|
||
TLNN FR,FLSPAC
|
||
CAIA
|
||
JRST BLANK1
|
||
TLNE FR,FLCMNT ;IF /C, WE ALSO WIN IF WE FIND A SEMICOLON.
|
||
CAIE T,";
|
||
RET
|
||
JRST POPJ1
|
||
|
||
3LOOP:
|
||
IFN ITS,.SUSET [.SWHO2,,[SIXBIT/SAME/]]
|
||
|
||
;THIS IS THE MAIN LOOP OF 3-WAY MERGING.
|
||
|
||
;COME HERE WHEN THE LAST LINES OF ALL 3 FILES MATCHED, TO TRY THE NEXT LINES OF ALL 3.
|
||
3SAME: SKIPE F1,LNNEXT(F1) ;ADVANCE PAST THE LINE THAT MATCHED
|
||
JRST 3SAME1
|
||
TRZ FR,-1 ;IF NO MORE LINES IN CORE, FLUSH ALL
|
||
SKIPE MRGOUT+0 ;THE LINES WE PASSED BY,
|
||
CALL MOVEUP
|
||
SETZM NLINE1 ;(IN THE SIMPLE COMMON CASE, FLUSH THEM FAST)
|
||
CALL RDLIN ;AND READ ANOTHER.
|
||
CAIA
|
||
JFCL
|
||
3SAME1: SKIPE F2,LNNEXT(F2) ;SIMILAR FOR F2,
|
||
JRST 3SAME2
|
||
SETZM NLINE2 ;BUT SINCE MRGOUT+1 SHOULD BE ZERO, IT'S SIMPLE.
|
||
HRRI FR,1
|
||
CALL RDLIN
|
||
CAIA
|
||
JFCL
|
||
3SAME2: SKIPE F3,LNNEXT(F3) ;FOR F3, JUST LIKE F2.
|
||
JRST 3SAME3
|
||
SETZM NLINE3
|
||
HRRI FR,3
|
||
CALL RDLIN
|
||
CAIA
|
||
JFCL
|
||
3SAME3: MOVE W1,EOFFL1 ;UNLESS EITHER ALL 3 FILES ARE ENDING OR NONE,
|
||
CAMN W1,EOFFL2 ;IT'S A DIFFERENCE.
|
||
CAME W1,EOFFL3
|
||
JRST 3DIFF
|
||
CALL COMPL ;COMPARE LINE FROM FILE 1 WITH THAT FROM FILE 2.
|
||
CAIA
|
||
JRST 3DIFF
|
||
EXCH F2,F3
|
||
CALL COMPL ;COMPARE FILE 1 WITH FILE 3.
|
||
CAIA
|
||
JRST [ EXCH F2,F3
|
||
JRST 3DIFF]
|
||
EXCH F2,F3 ;1 MATCHES 2 AND MATCHES 3 => ALL 3 STILL THE SAME.
|
||
SKIPE EOFFL1
|
||
JRST FIN2
|
||
JRST 3SAME
|
||
|
||
;COME HERE, DURING A 3-WAY MERGE, WHEN A DIFFERENCE IS SEEN.
|
||
;THAT IS, WHEN ALL 3 FILES CEASE TO BE IDENTICAL.
|
||
;F1, F2, F3 POINT AT THE FIRST NON-MATCHING LINES,
|
||
;OR ARE ZERO TO SAY THAT AN ENTIRE FILE HAS BEEN MATCHED OFF.
|
||
;COME HERE WHEN A DIFFERENCE IS SEEN. F1 AND F2 POINT TO THE 1ST PAIR OF NON-MATCHING
|
||
;LINES, OR ARE ZERO TO SAY THAT AN ENTIRE FILE HAS BEEN MATCHED OFF.
|
||
3DIFF: HRRI FR,0
|
||
CALL MOVEUP ;FLUSH ANY MATCHING LINES STILL IN CORE BEFORE THOSE TWO.
|
||
HRRI FR,1
|
||
CALL MOVEUP
|
||
HRRI FR,2
|
||
CALL MOVEUP
|
||
SKIPE 0 ;0 SHOULD ALWAYS HOLD 0 FOR NEXTLN'S SAKE.
|
||
ERRHLT
|
||
IFN ITS,.SUSET [.SWHO2,,[SIXBIT/DIFF/]]
|
||
SETZM NCOMP1
|
||
SKIPL EOFFL1
|
||
AOS NCOMP1
|
||
SETZM NCOMP2
|
||
SKIPL EOFFL2
|
||
AOS NCOMP2
|
||
SETZM NCOMP3
|
||
SKIPL EOFFL3
|
||
AOS NCOMP3
|
||
MOVE W1,12MTBB ;CLEAR THE TABLE OF MATCHES BETWEEN FILES 1 AND 2.
|
||
MOVEM W1,12MTBP
|
||
3DIFFR: NEXTLN 1 ;READ ANOTHER LINE FROM EACH FILE.
|
||
SKIPL EOFFL1
|
||
AOS NCOMP1
|
||
NEXTLN 2
|
||
SKIPL EOFFL2
|
||
AOS NCOMP2
|
||
NEXTLN 3
|
||
SKIPL EOFFL3
|
||
AOS NCOMP3
|
||
SKIPE EOFFL2
|
||
JRST 3DIFF2
|
||
SKIPN CS,NCOMP1 ;HOW MANY FILE 1 LINES SHOULD WE CONSIDER?
|
||
JRST 3DIFF2
|
||
SKIPA F1,LBUFP1 ;COMPARE ALL THE NON-MATCHING LINES OF FILE 1, 1 AT A TIME,
|
||
3DIFF0: MOVE F1,W1 ;WITH THE NEW LINE FROM FILE 2.
|
||
CALL COMPL
|
||
CALL MULTI ;MATCH => CHECK FOR MULTI-LINE MATCH, PUT IN 12MTAB IF FOUND.
|
||
SKIPE W1,LNNEXT(F1)
|
||
SOJG CS,3DIFF0
|
||
;AFTER COMPARING ALL THE FILE 1 LINES WITH THE NEW FILE 2 LINE, OR IF THERE IS NO NEW
|
||
;FILE 2 LINE, COME HERE TO COMPARE THE NEW FILE 1 LINE WITH ALL THE FILE 2 LINES.
|
||
;F1 IS ALREADY POINTING AT THE NEW FILE 1 LINE ("NEW" MEANS THAT DIFFRD GOT IT.
|
||
;IT MIGHT HAVE BEEN IN CORE ALREADY DUE TO NEXTLN'S DONE INSIDE MULTI).
|
||
3DIFF2: SKIPE EOFFL1 ;BUT DON'T DO IT IF NO NEW FILE 1 LINE.
|
||
JRST 3DIFF3
|
||
SKIPN CS,NCOMP2 ;HOW MANY LINES ARE WE CONSIDERING YET FROM FILE 2?
|
||
JRST 3DIFF3
|
||
SKIPA F2,LBUFP2 ;(MAY NOT BE SAME AS NLINE2, IF MULTI READ SOME LINES.)
|
||
3DIFF1: MOVE F2,W1 ;ELSE LOOP HERE OVER THE FILE 2 LINES.
|
||
CALL COMPL
|
||
CALL MULTI ;IF MULTI-LINE MATCH FOUND, PUT IT IN 12MTAB.
|
||
SKIPE W1,LNNEXT(F2)
|
||
SOJG CS,3DIFF1
|
||
;NOW WE KNOW ABOUT THE PLACES WHERE FILES 1 AND 2 MATCH.
|
||
;EACH SUCH PLACE (WITHIN THE RANGE BEING CONSIDERED) IS LISTED IN 12MTAB.
|
||
;WE NOW COMPARE EACH OF THOSE PLACES AGAINST WHAT WE HAVE OF FILE 3.
|
||
3DIFF3: PUSH P,F1
|
||
PUSH P,F2
|
||
MOVE W1,12MTBB
|
||
3DIFF6: CAMN W1,12MTBP
|
||
JRST 3DIFF4 ;NO MATCH => READ ANOTHER PAIR OF LINES AND TRY MATCHING THEM.
|
||
ILDB F2,W1
|
||
PUSH P,W1
|
||
ANDI F2,-1 ;FIND THE FILE 2 LOCATION OF THE NEXT 1-2 MATCH.
|
||
MOVE CS,NCOMP3
|
||
SKIPA F1,LBUFP3
|
||
3DIFF5: MOVE F1,W1
|
||
CALL COMPL ;COMPARE THAT AGAINST EACH POINT OF FILE 3.
|
||
CALL 3MULTI ;NOTE THAT WE ARE USING F1 TO HOLD THE FILE 3 POINTER.
|
||
SKIPE W1,LNNEXT(F1)
|
||
SOJG CS,3DIFF5
|
||
POP P,W1
|
||
JRST 3DIFF6
|
||
|
||
3DIFF4: POP P,F2
|
||
POP P,F1 ;NO MATCH FOUND.
|
||
SKIPE EOFFL1 ;NORMALLY, READ ANOTHER LINE FROM EACH FILE.
|
||
SKIPL EOFFL2
|
||
JRST 3DIFFR
|
||
SKIPL EOFFL3
|
||
JRST 3DIFFR
|
||
JRST 3ALDIF ;BUT IF ALL ARE AT EOF, TAKE ALL REMAINING LINES OF ALL FILES AS DIFFS.
|
||
|
||
; THIS IS A COLLECTION OF STUFF THAT WAS UNDEFINED AT THE
|
||
; TIME CONVERSION TO TNX WAS DONE. VALUES ARE FURNISHED HERE
|
||
; JUST TO MINIMIZE ASSEMBLY BARFAGE, BUT SOMEDAY PRESUMABLY
|
||
; SOMEONE WILL REPLACE WITH THE PROPER THINGS.
|
||
3ALDIF:
|
||
3MULTI: RET ; NOP FOR NOW
|
||
.SCALAR 3WAY ; -1 IF DOING 3-WAY COMPARE
|
||
.SCALAR 12MTBP ; SOMETHING TO DO WITH 3WAY MERGE?
|
||
.SCALAR 12MTBB ; DITTO
|
||
|
||
;/M ROUTINE TO TEST IF MERGE IN EFFECT AND IF YES
|
||
;/M ACCPT COMMAND AND PASS TO MERGE OUTPUT FILE
|
||
;/M COMMANDS ARE ANY COMBINATION OF 1,2,I AND/OR T (WITH NO COMMAS)
|
||
;/M ALL OTHER CHARACTERS ARE ILLEGAL
|
||
;/M CALL: CALL TRYMRG
|
||
; MERGER DONE RETURN
|
||
; /M NOT IN EFFECT RETURN
|
||
|
||
TRYMRG: TLNN FR,FLMERG ;/M /M SWITCH IN EFFECT?
|
||
JRST POPJ1 ;/M NO, SKIP RETURN
|
||
IFN ITS,.SUSET [.SWHO2,,[SIXBIT/MERGE/]]
|
||
TLNE FR,FLISWT ;/I => ASSUME "I" AS AN ANSWER.
|
||
JRST MRGI1
|
||
TLNE FR,FLFLAG ;/F => PUT OUT THE FILE 2 STUFF WITH FLAGS.
|
||
JRST MRGU1
|
||
CALL GETMRG ;/M TYPE *,GET ALL OF MERGE COMMAND(CHECK SYNTAX)
|
||
LISTEN: CALL MRGIN ;/M GET NEXT MERGE COMMAND INPUT CHAR
|
||
CAIE C,"1 ;/M DID HE TYPE 1?
|
||
CAIN C,"2 ;/M DID HE TYPE 2?
|
||
JRST MRG5 ;YES FOR ONE OF THEM!
|
||
CAIN C,"I
|
||
JRST MRGI ;"I"=> PUT IN BOTH FILES' TEXTS AND IDENTIFYING MARKS.
|
||
CAIE C,"T ;/M "T" TYPED?
|
||
JRST MRG4 ;/M NO, CHECK FOR END OF COMMAND
|
||
MRG3B: CALL TTILIN
|
||
MRG3A: CALL TTICHR ;GET TTY INPUT CHAR.
|
||
CAIE C,^C ;/M EOF OR
|
||
CAIN C,ALTM ;/M ALT-MODE?
|
||
JRST LISTEN ;/M YES, END OF INSERT FROM TTY
|
||
CALL MRGO ;/M NO, OUTPUT CHAR TO MERGE FILE
|
||
CAIE C,^M ;CR -> SPECIAL.
|
||
JRST MRG3A ;ELSE GET MORE
|
||
MOVEI C,^J ;PUT IN ^J AFTER ^M.
|
||
CALL MRGO
|
||
JRST MRG3B ;GET NEXT TTY LINE.
|
||
|
||
MRG4: CAIE C,0 ;/M MUST BE NULL(END OF COMMAND)
|
||
ERRHLT ;/M NO SOME THING IS VERY WRONG
|
||
HRRI FR,0 ;/M FLUSH DIFFERENCES IN FILE ONE IF NOT ALREADY
|
||
SETZM MRGOUT(FR) ;/M BUT DO NOT OUTPUT ON MERGE FILE
|
||
CALL MOVEUP ;/M NO, OUTPUT DIFFERENCES AND FLUSH
|
||
HRRI FR,1 ;/M FLUSH DIFFERENCES IN FILE TWO IF NOT ALREADY
|
||
SETZM MRGOUT(FR) ;BUT DO NOT OUTPUT ON MERGE FILE
|
||
CALL MOVEUP ;/M NO, OUTPUT DIFFERENCES AND FLUSH
|
||
SETOM MRGOUT+0
|
||
RET ;/M RETURN, LEAVING MATCH LINES STILL IN BUFFER
|
||
|
||
MRG5: HRRI FR,-"1(C)
|
||
SETOM MRGOUT(FR) ;/M YES, SET FLAG SO MOVEUP WILL OUTPUT
|
||
CALL MOVEUP ;/M MOVE BUFFER UP OVER DIFFERENCES USER WANTS
|
||
JRST LISTEN ;/M GO GET ANOTHER CHARACTER
|
||
|
||
;/F => WHEN DIFFERENCES ARE FOUND, OUTPUT THE LINES FROM FILE 2
|
||
;WITH A "|" AT THE FRONT OF EACH ONE.
|
||
MRGU1: SETOM MRGOUT+1
|
||
HRRI FR,1
|
||
SETOM MRGUFL ;TELL MOVEUP TO INSERT "|"'S
|
||
PUSH P,F1(FR)
|
||
CALL MOVEUP ;OUTPUT THE STUFF FROM FILE 2
|
||
REST W1
|
||
MOVEI W2,[ASCIZ /^^^^/] ;THEN OUTPUT "^^^^" IN FRONT OF NEXT LINE
|
||
CAMN W1,F1(FR) ;IF THERE WERE NO LINES FROM FILE 2 (A DELETION).
|
||
CALL MRGPNT
|
||
SETZB C,MRGUFL
|
||
JRST MRG4 ;THROW AWAY STUFF FROM FILE 1 AND RETURN.
|
||
|
||
;"I" MERGE COMMAND - PUT IN THE MERGE FILE THE FOLLOWING:
|
||
;*** MERGE LOSSAGE ***
|
||
;*** FILE FOOBAR 1001 HAS:
|
||
;<TEXT FROM FILE 1>
|
||
;*** FILE FOOBAR 1002 HAS:
|
||
;<TEXT FROM FILE 2>
|
||
;*** END OF MERGE LOSSAGE ***
|
||
|
||
MRGI: SAVE [LISTEN]
|
||
MRGI1: MOVEI W2,[ASCIZ /*** MERGE LOSSAGE ***
|
||
*** FILE /]
|
||
CALL MRGPNT
|
||
MOVE W2,RCHSTP ;-> NAMES OF FILE 1.
|
||
CALL MRGPNT
|
||
MOVEI W2,[ASCIZ / HAS:
|
||
/]
|
||
CALL MRGPNT
|
||
SETOM MRGOUT ;OUTPUT THE TEXT OF FILE 1
|
||
HRRI FR,0
|
||
CALL MOVEUP
|
||
MOVEI W2,[ASCIZ /*** FILE /]
|
||
CALL MRGPNT
|
||
MOVE W2,RCHSTP+1 ;-> NAMES OF FILE 2.
|
||
CALL MRGPNT
|
||
MOVEI W2,[ASCIZ / HAS:
|
||
/]
|
||
CALL MRGPNT
|
||
SETOM MRGOUT+1 ;OUTPUT TEXT FROM FILE 2.
|
||
HRRI FR,1
|
||
CALL MOVEUP
|
||
SETZM MRGOUT+1 ;CLEAR THIS OR WE'D GET 2 COPIES OF FURTHER UNCHANGED TEXT!
|
||
MOVEI W2,[ASCIZ /*** END OF MERGE LOSSAGE ***
|
||
/]
|
||
JRST MRGPNT
|
||
|
||
;PRINT ASCIZ STRING <- W2 ON THE MERGE FILE.
|
||
MRGPNT: HRLI W2,440700
|
||
MRGPN1: ILDB C,W2
|
||
JUMPE C,CPOPJ
|
||
CALL MRGO
|
||
JRST MRGPN1
|
||
|
||
;OUTPUT STRING <- W2 WITH # CHARS IN C.
|
||
MRGCNT: SAVE W1
|
||
SKIPN W1,C
|
||
JRST POPW1J
|
||
MRGCN1: ILDB C,W2
|
||
CALL MRGO
|
||
SOJG W1,MRGCN1
|
||
JRST POPW1J
|
||
|
||
;HERE TO OUTPUT ONE CHARACTER TO CHMRG VIA BUFFER.
|
||
MRGO: IDPB C,MRGBP
|
||
SOSLE MRGCT
|
||
RET
|
||
|
||
;EMPTY OUT OUR CHMRG BUFFER.
|
||
MRGFRC: SAVE W1
|
||
SAVE W2
|
||
MOVE W1,[440700,,MRGBF]
|
||
MOVEM W1,MRGBP
|
||
MOVEI W2,MRGBSZ
|
||
SUB W2,MRGCT ;# CHARS FILLED IN IT.
|
||
ADDM W2,MRGCT ;MARK IT EMPTY (AFTER WE WRITE DATA).
|
||
JUMPE W2,MRGFR1
|
||
M.SOUT CHMRG,W1,W2 ; OUTPUT STRING
|
||
MRGFR1: REST W2
|
||
POPW1J: REST W1
|
||
RET
|
||
|
||
;/M ROUTINE TO GET INPUT FOR MERGE COMMAND
|
||
;/M STORES ENTIRE COMMAND IN SPECIAL BUFFER
|
||
;/M IN CASE USER TYPES T COMMAND AS ONE OF COMMANDS
|
||
;/M WHICH WILL SLAO REQUIRE TTY INPUT
|
||
;/M CHECK SYSTAX, DO NOT RTURN UNTIL GOOD COMMAND LINE TYPED IN
|
||
|
||
GTMRG0: HLRZ C,(P)
|
||
MOVEM W1,(C)
|
||
GETMRG: CALL TTILNA ;READ TTY LINE, PROMPTING WITH A "*".
|
||
MOVE W1,[440700,,MRGCOM] ;/M SET UP BYTE POINTER TO MERGE
|
||
;/M COMMAND BUFFER
|
||
GTMRG1: MOVEI C,0 ;/M IN CASE TOO LONG COMMAND
|
||
CAME W1,[350700,,MRGCOM+MRGLEN-1]
|
||
CALL TTICHU
|
||
CAIGE C,40 ;/M ALTM,LF?
|
||
MOVEI C,0 ;/M YES, FLAG END OF MERGE COMAND WITH NULL
|
||
IDPB C,W1 ;/M STORE CHAR
|
||
CAIE C,"1 ;/M IS IT "1"?
|
||
CAIN C,"2 ;/M OR "2"?
|
||
JRST GTMRG1 ;/M YES, GET ANOTHER
|
||
CAIE C,"I
|
||
CAIN C,"T ;/M NO, IS IT "T"?
|
||
JRST GTMRG1 ;/M YES, GET ANOTHER
|
||
CAIN C,"L
|
||
JRST GTMRGL
|
||
CAIE C,"C ;/M C?
|
||
JRST GTMRG3 ;/M NO
|
||
SKIPA W1,[COLMAX]
|
||
GTMRGL: MOVEI W1,LINMAX
|
||
HRLM W1,(P)
|
||
MOVEI W1,0
|
||
GTMRG2: CALL TTICHR ;/M GE CHAR
|
||
CAIGE C,40 ;/M END OFLINE CHAR?
|
||
JRST GTMRG0 ;/M YES STORE NEW MAX.
|
||
CAIL C,"0 ;/M NO, A DECIMAL DIGIT?
|
||
CAILE C,"9 ;/M
|
||
JRST GTMRG4 ;/M NO, PRINT ERROR
|
||
IMULI W1,12 ;/M YES CONVERT TO BINARY
|
||
ADDI W1,-"0(C) ;/M ADD IN THIS DIGIT
|
||
JRST GTMRG2 ;/M GO GET NEXT DIGIT
|
||
|
||
GTMRG3: MOVE W1,[440700,,MRGCOM] ;/M ASSUME IT IS END OF LINE
|
||
MOVEM W1,MRGBYT ;/M AND STORE BYTE POINTER TO SCANNED STRING
|
||
JUMPE C,CPOPJ ;/M IS IT?
|
||
GTMRG4: MOVE W1,[440700,,[ASCIZ "?ONLY 1, 2, I, AND/OR T ARE LEGAL IN MERGE COMMANDS
|
||
OR C### TO SET MAX. COL. OR L### TO SET MAX. LINES TYPED.
|
||
"]]
|
||
CALL PRINT ;/M PRINT ERROR
|
||
JRST GETMRG ;/M AND ASK FOR COMMAND OVER AGAIN
|
||
|
||
;/M ROUTINE TO GET NEXT CHAR FROM MERGE COMMAND BUFFER
|
||
;/M CALL: CALL MRGIN
|
||
;/M RETURN WITH CHAR IN C
|
||
|
||
MRGIN: ILDB C,MRGBYT ;/M GET NEXT CHAR
|
||
RET
|
||
|
||
;MOVEUP FLUSHES ALL THE LINES OF THE FILE SPECIFIED BY RH(FR)
|
||
;THAT ARE BEFORE THE LINE POINTED BY F1 OR F2 OR F3.
|
||
;IF THERE ARE ANY LINES AFTER F1 OR F2 OR F3, THEY HAVE TO BE BLT'ED DOWN
|
||
;TO THE BEGINNING OF THE FILE'S SEGMENT. IF THERE ARE NONE,
|
||
;ONLY POINTER RELOCATION TAKES PLACE.
|
||
;F1 OR F2 OR F3 CONTINUES TO POINT AT THE SAME LINE, OR REMAINS 0.
|
||
;IF MRGOUT(FR) IS NONZERO, THE FLUSHED LINES ARE OUTPUT TO THE
|
||
;MERGE FILE.
|
||
|
||
MOVEUP: SKIPN FSBIN
|
||
SKIPE FVBIN
|
||
RET ; Ignore if doing binary compare.
|
||
SKIPE MRGOUT(FR) ;SKIP IF SHOULD OUTPUT TO MERGE FILE,
|
||
CALL MOVEU1 ;DO SO.
|
||
SKIPE W1,F1(FR) ;GET ADDR OF 1ST LINE NOT TO FLUSH.
|
||
JRST MOVEU5
|
||
SETZM NLINES(FR) ;FLUSHING ALL LINES => JUST SAY THERE ARE NONE.
|
||
RET
|
||
|
||
MOVEU5: MOVEI T,1 ;T COUNTS THE NUMBER OF LINES LEFT.
|
||
MOVN C,W1 ;WE MUST BLT FROM C(W1) TO C(LBUFP(FR))
|
||
ADD C,LBUFP(FR) ;HOW FAR IS THAT?
|
||
MOVEU3: MOVE W2,W1 ;W2 REMEMBERS THE LAST LINE'S ADDR
|
||
CAMN W1,TEMPF1(FR) ;RELOCATE TEMPF1 IF IT POINTS AT THIS LINE.
|
||
ADDM C,TEMPF1(FR)
|
||
SKIPN W1,LNNEXT(W1) ;FIND THE NEXT LINE WHERE IT NOW IS
|
||
JRST MOVEU4
|
||
ADDM C,LNNEXT(W2) ;RELOCATE POINTER -> WHERE IT WILL BE BLT'ED TO.
|
||
AOJA T,MOVEU3 ;ANOTHER LINE => COUNT IT.
|
||
|
||
MOVEU4: MOVEM T,NLINES(FR)
|
||
HRLZ W1,F1(FR) ;LH(W1) GETS CURRENT ADDRESS OF 1ST LINE TO KEEP
|
||
HRR W1,LBUFP(FR) ;RH GETS NEW ADDR
|
||
MOVE T,LNSIZE(W2) ;FIND END OF LAST LINE
|
||
ADDI T,5
|
||
IDIVI T,5 ;FIRST FIND LENGTH IN WORDS
|
||
ADDI W2,LNDATA-1(T) ;ADD ADDR OF START OF LINE
|
||
ADD W2,C ;FIND WHERE THAT END IS BEING RELOCATED TO.
|
||
BLT W1,(W2) ;COPY THE LINES THAT ARE LEFT TO THEIR NEW HOMES.
|
||
MOVE W1,LBUFP(FR)
|
||
MOVEM W1,F1(FR) ;NOW RELOCATE F1(FR).
|
||
RET
|
||
|
||
;OUTPUT THE LINES UP THE FILE IN FR THAT ARE BEFORE F1 OR F2 OR F3 TO THE MERGE FILE.
|
||
MOVEU1: MOVE W1,LBUFP(FR) ;GET ADDR OF 1ST LINE TO BE FLUSHED.
|
||
SKIPN NLINES(FR)
|
||
SETZ W1,
|
||
MOVEU2: CAMN W1,F1(FR) ;REACHED 1ST LINE NOT TO BE FLUSHED?
|
||
RET ;NO, OUTPUT LINE W1 POINTS AT.
|
||
TLNE FR,FLFLAG
|
||
SKIPGE LPHONY ;IF THIS LINE IS PHONY (NOT FIRST AFTER A CRLF)
|
||
JRST MOVEU6 ;OMIT ANY /F HACKERY.
|
||
SKIPLE LPHONY ;IF FOLLOWS A STRAY CR, JUST PUT IN A TAB.
|
||
JRST MOVEU7
|
||
MOVEI C,"|
|
||
SKIPE MRGUFL ;IF OUTPUTTING DIFFERENCES IN /F MODE, PREFIX WITH "|".
|
||
CALL MRGO
|
||
TLNN FR,FLFLAG ;IN /F MODE, PUT A TAB BEFORE EVERY LINE
|
||
JRST MOVEU6
|
||
|
||
MOVEU7: MOVEI C,^I ;SO "|"'S AND "^"'S CAN STAND OUT.
|
||
CALL MRGO
|
||
MOVEU6: MOVEI W2,LNDATA(W1)
|
||
HRLI W2,440700 ;GET ADDR OF 1ST DATA WORD
|
||
MOVE C,LNSIZE(W1) ;AND # OF CHARACTERS.
|
||
SETZM LPHONY ;SET LPHONY FOR NEXT LINE UNLESS THIS ONE ENDS IN A CRLF.
|
||
CAIGE C,2
|
||
SETOM LPHONY
|
||
CALL MRGCNT ;TRANSFER THE CHARACTERS.
|
||
SOS W2
|
||
REPEAT 3,IBP W2 ;DECREMENT W2 TWICE.
|
||
ILDB C,W2
|
||
CAIE C,^M
|
||
SETOM LPHONY ;CHECK FOR THE TERMINAL CRLF.
|
||
ILDB C,W2
|
||
CAIE C,^J
|
||
SETOM LPHONY
|
||
CAIN C,^M
|
||
MOVNS LPHONY ;LEAVE 1 IN LPHONY IF LINE ENDS IN JUST CR.
|
||
MOVE W1,LNNEXT(W1) ;GO TRY THE NEXT LINE.
|
||
JRST MOVEU2
|
||
|
||
;SKIP UNLESS THE TWO CURRENT LINES ARE EQUAL. IGNORES CASE CHANGES AND
|
||
;SPACING CHANGES IF SPECIFIED, BUT NEVER IGNORES COMMENTS.
|
||
;MUSTN'T CLOBBER CS.
|
||
COMPL: MOVE C,LNSIZE(F1) ;FIRST TEST FOR EXACT MATCH.
|
||
CAME C,LNSIZE(F2)
|
||
JRST COMPUL ;LINE LENGTHS DIFFER => NO EXACT MATCH,
|
||
MOVEI W1,5(C) ;ELSE COMPARE THE LINES WORD-BY-WORD.
|
||
IDIVI W1,5
|
||
MOVNS W1 ;-<# WDS OF DATA IN LINE>
|
||
HRLZS W1
|
||
HRRI W1,LNDATA(F1) ;AOBJN POINTER TO DATAT IN FILE 1 LINE.
|
||
MOVEI W2,LNDATA(F2) ;AND POINTER TO DATA OF FILE 2 LINE.
|
||
SUB W2,W1
|
||
HRRM W2,COMPLX
|
||
COMPL1: MOVE C,(W1) ;COMPARE WORD BY WORD, IGNORING LOW BITS.
|
||
COMPLX: XOR C,(W1) ;ADDR FIELD MAKES E.A. POINT TO SECOND FILE'S LINE.
|
||
TDNE C,[-2]
|
||
JRST COMPUL ;JUMP IF NO EXACT MATCH.
|
||
AOBJN W1,COMPL1
|
||
RET
|
||
|
||
COMPUL: TLNN FR,FLCASE\FLSPAC ;NO EXACT MATCH. CAN WE TRY IGNORING STUFF?
|
||
JRST POPJ1 ;NO, SO MUST RETURN "NO MATCH".
|
||
;IGNORING CASE OR SPACING => WE GET A SECOND CHANCE.
|
||
MOVEI W1,LNDATA(F1)
|
||
MOVEI W2,LNDATA(F2)
|
||
HRLI W1,440700
|
||
HRLI W2,440700
|
||
COMPU1: ILDB T,W1 ;GET A CHARACTER FROM LINE FROM FIRST FILE
|
||
ILDB TT,W2 ;AND ONE FROM SECOND FILE
|
||
CAME T,TT ;THEY'RE EXACTLY EQUAL => KEEP LOOKING
|
||
JRST COMPU2
|
||
JUMPN T,COMPU1 ;BUT DON'T LOOK PAST ENDS OF THE LINES.
|
||
POPJ P, ;REACH ENDS OF LINES => LINES MATCH.
|
||
|
||
COMPU2: TLNN FR,FLSPAC
|
||
JRST COMPU4
|
||
CAIE T,40 ;IF SUPPOSED TO IGNORE CHANGES IN SPACING, DO SO
|
||
CAIN T,^I ;BY SKIPPING ALL SPACES & TABS IN BOTH FILES.
|
||
JRST [ILDB T,W1
|
||
JRST .-2]
|
||
CAIE TT,40
|
||
CAIN TT,^I
|
||
JRST [ILDB TT,W2
|
||
JRST .-2]
|
||
COMPU4: TLNN FR,FLCASE
|
||
JRST COMPU3
|
||
CAIL T,"A+40 ;IF SUPPOSED TO IGNORE CHANGES IN CASE, CONVERT TO U.C.
|
||
CAILE T,"Z+40
|
||
CAIA
|
||
SUBI T,40
|
||
CAIL TT,"A+40
|
||
CAILE TT,"Z+40
|
||
CAIA
|
||
SUBI TT,40
|
||
COMPU3: CAMN T,TT ;DO THEY MATCH NOW?
|
||
JRST COMPU1
|
||
JRST POPJ1 ;NO => LINES DON'T MATCH.
|
||
|
||
;SKIP UNLESS THE TWO CURRENT LINES ARE THE SAME WHEN APPROPRIATE
|
||
;STUFF IS IGNORED (SPACES AND COMMENTS, OR ALPHABETIC CASE,
|
||
; ACCORDING TO SWITCHES).
|
||
COMPCS: MOVEI W1,LNDATA(F1)
|
||
MOVEI W2,LNDATA(F2)
|
||
HRLI W1,440700
|
||
HRLI W2,440700
|
||
COMPL3: ILDB T,W1 ;GET A CHARACTER FROM LINE FROM FIRST FILE
|
||
COMPL6: ILDB TT,W2 ;AND ONE FROM SECOND FILE
|
||
CAME TT,T ;THIS IS THE BIG TEST--ARE THEY EQUAL
|
||
JRST COMPL4 ;NO
|
||
COMPL7: CAIN T,"; ;YES, COMMENT?
|
||
TLNN FR,FLCMNT ;YES, SUPPRESS COMMENTS?
|
||
JUMPN T,COMPL3 ;NO,NO. TEST FOR END OF LINE
|
||
RET ;LINES MATCH, RETURN
|
||
|
||
COMPL4: TLNN FR,FLSPAC ;CHARS DIFFER: MAYBE TRY IGNORING SPACING
|
||
JRST COMPL8
|
||
CAIE TT,40 ;SPACE IN FILE 2, OR TAB?
|
||
CAIN TT,TAB
|
||
JRST COMPL6 ;IF SO, SKIP IT.
|
||
COMPL5: CAIE T,40 ;SPACE IN FILE 1?
|
||
CAIN T,TAB ;OR TAB?
|
||
JRST [ILDB T,W1 ;SKIP TO FIRST NON-SPACE NON-TAB.
|
||
JRST COMPL5]
|
||
CAMN T,TT ;ARE THE CHARACTERS NOW THE SAME?
|
||
JRST COMPL7 ;YES, TEST FOR END OF LINES
|
||
COMPL8: TLNN FR,FLCASE ;SPACES DIDN'T HELP - ARE WE IGNORING CASE?
|
||
JRST COMPL2
|
||
CAIL T,"A+40 ;CHARS DON'T MATCH => WE STILL HAVE A CHANCE
|
||
CAILE T,"Z+40 ;IF THEY'RE BOTH LETTERS; CONVERT BOTH TO UPPER CASE.
|
||
CAIA
|
||
SUBI T,40
|
||
CAIL TT,"A+40
|
||
CAILE TT,"Z+40
|
||
CAIA
|
||
SUBI TT,40
|
||
CAMN T,TT ;IF THIS HELPED, KEEP GOING
|
||
JRST COMPL3 ;NO USE CHECKING FOR EOL - THESE MUST BE BOTH LETTERS.
|
||
;LAST CHANCE - MAYBE ONE FILE HAS A COMMENT AND THE OTHER IS AT END OF LINE.
|
||
COMPL2: CAIE T,"; ;COMMENT IN FILE 1?
|
||
CAIN TT,"; ;OR IN FILE 2?
|
||
TLNN FR,FLCMNT ;AND ARE COMMENTS BEING IGNORED?
|
||
JRST POPJ1 ;NO, FILES DON'T MATCH, SKIP RETURN
|
||
JUMPE T,CPOPJ ;YES, OTHER CHAR MUST BE NULL OR ELSE ONE
|
||
JUMPE TT,CPOPJ ; LINE IS LONGER THAN OTHER AND FILES DIFFER
|
||
POPJ1: AOS (P)
|
||
APOPJ:
|
||
CPOPJ: RET
|
||
|
||
;WHEN WE GET TO THIS POINT WE HAVE FOUND
|
||
;THE EXTENT OF THE DIFFERENCES AND WE ARE READY TO PRINT
|
||
;THESE DIFFERENCES OUT. F1 AND F2 POINT AT THE TWO MATCHING LINES
|
||
;THAT END THE RUN OF DIFFERENCES.
|
||
|
||
PNTBTH: AOS ERRCNT ;INCREMENT # OF RUNS OF DIFFERENCES.
|
||
TLNE FR,FLISWT+FLFLAG
|
||
RET ;DON'T TYPE ON TTY IF /I OR /F.
|
||
IFN ITS,.SUSET [.SWHO2,,[SIXBIT/PRINT/]]
|
||
MOVEM P,FLUSHP ;SUPPLY P FOR --MORE--FLUSHED TO POPJ FROM.
|
||
TRZ FR,-1 ;OUTPUT FILE 1
|
||
CALL PNTTXT ;PRINT FILE 1 DIFFERENCES
|
||
HRRI FR,1 ;THEN PRINT FILE 2 DIFFERENCES
|
||
CALL PNTTXT
|
||
SETZM FLUSHP
|
||
RET
|
||
|
||
;OUTPUT THE LINES OF FILE (FR) BEFORE F1(FR), WITH A HEADER LINE.
|
||
;IF FLENDL=1, ALSO PRINTS THE LINE F1(FR) POINTS AT, IF ANY.
|
||
PNTTXT: CALL PNTHDL ;FIRST, THE HEADER LINE.
|
||
SKIPN NLINES(FR)
|
||
RET ;NO LINES => THAT'S ALL.
|
||
MOVE W1,LBUFP(FR)
|
||
SETZ W3,
|
||
SKIPE CS,F1(FR) ;CS GETS LINE TO STOP AT.
|
||
TLNN FR,FLENDL
|
||
CAIA
|
||
MOVE CS,LNNEXT(CS)
|
||
PNTTX1: CAME W1,CS ;REACHED 1ST LINE NOT TO OUTPUT => DONE.
|
||
CAML W3,LINMAX ;PRINTED MAX # OF LINES => STOP.
|
||
RET
|
||
TLNN FR,FLFNUM ;IF USER WANTS FILE # ON EVERY LINE,
|
||
JRST PNTTX2
|
||
SAVE W1
|
||
MOVEI W1,FNUMBR(FR) ;PRINT IT FOR HIM.
|
||
CALL PRINT
|
||
REST W1
|
||
PNTTX2: MOVEI W2,LNDATA(W1)
|
||
HRLI W2,440700
|
||
MOVE C,LNSIZE(W1)
|
||
CAML C,COLMAX ;IN /M MODE, LIMIT CHARS PRINTED TO COLMAX.
|
||
MOVE C,COLMAX
|
||
TLNN FR,FLMERG
|
||
MOVE C,LNSIZE(W1)
|
||
CALL PNTCNT ;OUTPUT THE TEXT OF THE LINE.
|
||
TLNN FR,FLALL ;IN /B MODE, THE CRLF IF ANY IS IN THE LINE.
|
||
CALL PCRLF ;OTHERWISE, MUST SUPPLY IT.
|
||
MOVE W1,LNNEXT(W1) ;MOVE TO NEXT LINE.
|
||
AOJA W3,PNTTX1 ;COUNT # LINES OUTPUT SO FAR.
|
||
|
||
FNUMBR: ASCIZ /1) / ;FILE NUMBER OF FILE, FOR PRINTING.
|
||
ASCIZ /2) /
|
||
IFN .-FNUMBR-2,.ERR STRING TOO LONG
|
||
|
||
|
||
;OUTPUT A CRLF TO THE DIFFERENCE FILE.
|
||
PCRLF: MOVE W2,[440700,,[.BYTE 7 ? ^M ? ^J]]
|
||
MOVEI C,2
|
||
PNTCNT: M.SOUT CHOUT,W2,C
|
||
RET
|
||
|
||
;OUTPUT A HEADER LINE TO THE DIFFERENCE FILE, FOR INPUT FILE (FR).
|
||
PNTHDL: MOVE W2,[440700,,[ASCIZ/**** FILE /]]
|
||
MOVEI C,10.
|
||
CALL PNTCNT
|
||
MOVE W1,RCHSTP(FR)
|
||
CALL PRINT ;PRINT THE ASCIZ STRING CONTAINING THE FILE'S NAMES.
|
||
MOVE W2,[440700,,[ASCIZ /, /]]
|
||
MOVEI C,2
|
||
CALL PNTCNT
|
||
MOVE W1,LBUFP(FR) ;GET THE PAGE # OF THE FIRST LINE FROM THE FILE.
|
||
SKIPN NLINES(FR)
|
||
SKIPA T,PAGNUM(FR) ;OR THE .IOT'ING PAGE # IF THERE AR NONE.
|
||
MOVE T,LNPGNM(W1)
|
||
CALL PNTDEC
|
||
MOUTI CHOUT,"-
|
||
SKIPN NLINES(FR) ;THEN THE LINE NUMBER
|
||
SKIPA T,LINNUM(FR)
|
||
MOVE T,LNLNNM(W1)
|
||
CALL PNTDEC
|
||
MOVEI W1,[ASCIZ/ (/] ;AND, IN PARENS, THE CHARACTER NUMBER.
|
||
CALL PRINT
|
||
MOVE W1,LBUFP(FR)
|
||
SKIPN NLINES(FR)
|
||
SKIPA T,CHRNUM(FR)
|
||
MOVE T,LNCHNM(W1)
|
||
CALL PNTDEC
|
||
MOUTI CHOUT,51 ; RIGHT PAREN (SCREWS MACRO)
|
||
TLNN FR,FLLABL\FLXLBL
|
||
JRST PCRLF
|
||
MOVE W1,LBUFP(FR) ;IF THE LAST LABEL IS KNOWN, PRINT IT TOO.
|
||
SKIPN NLINES(FR)
|
||
JRST [ MOVEI T,(FR)
|
||
IMULI T,LNLBLN
|
||
ADDI T,LLABEL
|
||
JRST PNTHD1]
|
||
MOVEI T,LNLLBL(W1)
|
||
PNTHD1: SKIPN (T)
|
||
JRST PCRLF
|
||
MOVEI W1,[ASCIZ / AFTER /]
|
||
SAVE T
|
||
CALL PRINT
|
||
REST W1
|
||
TLNE FR,FLXLBL
|
||
MOUTI CHOUT,""
|
||
SAVE LNLBLN(W1)
|
||
SETZM LNLBLN(W1) ;SUPPLY A ZERO TO END THE ASCIZ.
|
||
CALL PRINT
|
||
REST LNLBLN(W1)
|
||
TLNE FR,FLXLBL
|
||
MOUTI CHOUT,""
|
||
JRST PCRLF
|
||
|
||
; PNTHWD - Output number in T in halfword format.
|
||
|
||
PNTHWD: PUSH P,T
|
||
HLRZS T
|
||
CALL PNTOCT
|
||
MOVEI C,2
|
||
MOVE W2,[440700,,[ASCIZ /,,/]]
|
||
CALL PNTCNT
|
||
POP P,T
|
||
JRST PNTOCT
|
||
|
||
; Print number in T in octal to difference file
|
||
; Use RH only, pad to 6 positions.
|
||
PNTOCT: MOVE W2,[440700,,PNTDBF]
|
||
PUSH P,T
|
||
MOVE TT,[220300,,(P)]
|
||
MOVSI C,-6
|
||
PNTOC2: ILDB T,TT
|
||
JUMPN T,PNTOC3
|
||
MOVEI T,40
|
||
IDPB T,W2 ; PAD OUT WITH SPACES
|
||
AOBJN C,PNTOC2
|
||
MOVEI T,"0
|
||
DPB T,W2
|
||
JRST PNTOC5
|
||
PNTOC4: ILDB T,TT
|
||
PNTOC3: ADDI T,"0
|
||
IDPB T,W2
|
||
AOBJN C,PNTOC4
|
||
PNTOC5: MOVEI C,6
|
||
MOVE W2,[440700,,PNTDBF]
|
||
POP P,T
|
||
JRST PNTCNT
|
||
|
||
|
||
;PRINT NUMBER IN T IN DECIMAL TO DIFFERENCE FILE
|
||
PNTDEC: MOVE W2,[440700,,PNTDBF]
|
||
SETZ C,
|
||
CALL PNTDE1
|
||
MOVE W2,[440700,,PNTDBF]
|
||
JRST PNTCNT
|
||
|
||
PNTDE1: IDIVI T,10.
|
||
HRLM TT,(P)
|
||
SKIPE T
|
||
CALL PNTDE1
|
||
HLRZ TT,(P)
|
||
ADDI TT,"0
|
||
IDPB TT,W2
|
||
AOJA C,CPOPJ
|
||
|
||
;RH(W1) IS ADDR OF ASCIZ STRING; PRINT IT ON DIFFERENCE FILE.
|
||
PRINT: MOVEI W2,(W1)
|
||
HRLI W2,440700
|
||
SETZ C, ;FIRST COUNT CHARS IN THE STRING,
|
||
ILDB T,W2
|
||
SKIPE T
|
||
AOJA C,.-2
|
||
MOVEI W2,(W1) ;THEN OUTPUT THE STRING.
|
||
HRLI W2,440700
|
||
JRST PNTCNT
|
||
|
||
;ASSUMING THAT F1(FR) POINTS TO THE LAST LINE IN FILE (FR),
|
||
;READ ANOTHER LINE AND MAKE F1(FR) POINT AT IT.
|
||
;ALSO OK IS IF WE HAVE NO LINES FROM THAT FILE AND F1(FR) IS 0.
|
||
;SKIPS TWICE IF SUCCESSFUL. CAN FAIL AND NOT SKIP IF CAN'T GET A LINE
|
||
;BECAUSE OF EOF; WILL RETURN WITH F1(FR) UNCHANGED AND EOFFL1(FR) NONZERO.
|
||
;WE DON'T EXPLICITLY GET CORE - THE MPV INT HANDER DOES THAT.
|
||
;THE MPV INT HANDLER CHECKS THE PC - ANY INSN THAT CAN LEGITIMATELY GET AN MPV
|
||
;SHOULD HAVE A LABEL SUCH AS "MPVOK1" AND BE MADE KNOWN TO THE INT HANDLER.
|
||
|
||
RDLIN: TDNE FR,EOFTBL(FR) ;GIVE UP IF AT EOF IN FILE.
|
||
JRST [ SETOM EOFFL1(FR)
|
||
RET]
|
||
MOVE W1,LBUFP(FR) ;IF NO LINES IN CORE, NEXT LINE GOES AT START OF SEG.
|
||
SKIPN NLINES(FR)
|
||
JRST RDLIN0
|
||
SKIPN W1,F1(FR) ;ELSE, GET POINTER TO CURRENT LINE
|
||
ERRHLT
|
||
MOVE T,LNSIZE(W1) ;FIND WORD AFTER THE END OF IT
|
||
ADDI T,5
|
||
IDIVI T,5
|
||
ADDI W1,LNDATA(T) ;THAT WILL BE THE ADDRESS OF THE NEW LINE.
|
||
RDLIN0: SETZ W3, ;COUNT # OF CHARS WE SKIP IN T.
|
||
MOVE CS,@GCHARP(FR) ;SWAP THE FILE B.P. INTO AN AC FOR SPEED.
|
||
RDLIN1: ILDB C,CS
|
||
CAIG C,^M
|
||
XCT RDLT1(C) ;LOOP TILL 1ST CHAR OF NON-NULL LINE SEEN.
|
||
RDLIN4: ADDB W3,CHRNUM(FR) ;INITIALIZE THE LINE'S DATA,
|
||
MPVOK0: MOVEM W3,LNCHNM(W1) ;STORING THE LAST WORD FIRST TO MAKE SURE CORE EXISTS.
|
||
IFN LNDATA-LNCHNM-1,.ERR
|
||
TLNN FR,FLLABL\FLXLBL ;SAVE TIME IF LABEL FEATURE NOT IN USE.
|
||
JRST RDLIN5
|
||
MOVEI W3,LNLLBL(W1)
|
||
DPB FR,[240100,,W3] ;PUT 4*RH(FR) IN LH(W3)
|
||
ADD W3,[LLABEL,,] .SEE LNLBLN ;4 WORDS OF LABEL STRING.
|
||
BLT W3,LNLLB3(W1)
|
||
RDLIN5: MOVE W2,PAGNUM(FR)
|
||
MOVEM W2,LNPGNM(W1)
|
||
MOVE W2,LINNUM(FR)
|
||
MOVEM W2,LNLNNM(W1)
|
||
SETZM LNNEXT(W1)
|
||
MOVEI W2,LNDATA(W1)
|
||
HRLI W2,440700 ;THEN MAKE W2 A B.P. TO IDPB THE DATA AREA,
|
||
MOVE RDLIN7,[RDLIN6,,BP]
|
||
BLT RDLIN7,RDLIN7
|
||
TDZ W3,W3 ;AND COUNT CHARS STORED IN LINE IN W3.
|
||
JRST MPVOK1
|
||
|
||
RDLIN6: OFFSET BP-.
|
||
RDLIN2:: ILDB C,CS
|
||
MPVOK1:: XCT RDLT2(C) ;USUALLY IDPB C,W2, BUT MAY EXIT TO RDLIN3.
|
||
RDLIN7:: AOJA W3,RDLIN2
|
||
OFFSET 0
|
||
|
||
RDLIN3: AOS NLINES(FR) ;WHEN WE GET HERE, THE LINE REALLY EXISTS,
|
||
SKIPE F1(FR) ;SO PUT IT IN THE CHAIN
|
||
MOVEM W1,@F1(FR)
|
||
IFN LNNEXT,.ERR
|
||
MOVEM W1,F1(FR) ;AND POINT AT IT.
|
||
MOVEM W3,LNSIZE(W1) ;REMEMBER # CHARS IN THIS LINE.
|
||
ADDM W3,CHRNUM(FR) ;UPDATE CHAR POSITION IN FILE
|
||
MOVEM CS,@GCHARP(FR) ;STORE BACK THE FILE'S BUFFER B.P.
|
||
SETZB T,TT
|
||
MPVOK6: IDPB T,W2 ;STORE A TRAILING ZERO, THEN
|
||
LDB T,[360600,,W2] ;ZERO OUT REST OF LAST WORD.
|
||
DPB T,[301400,,W2]
|
||
DPB TT,W2
|
||
TLNE FR,FLXLBL ;IF ANY UNINDENTED NON-COMMENT LINE IS A LABEL
|
||
CALL LABEL ;GO SET UP LLABEL WITH THIS LINE'S LABEL IF IT HAS ONE.
|
||
AOS (P)
|
||
JRST POPJ1
|
||
|
||
;DISPATCH TABLE FOR FINDING A NON-NULL LINE.
|
||
RDLT1: JFCL
|
||
JFCL
|
||
JFCL
|
||
JRST RDLINC ;^C
|
||
REPEAT 6,JFCL
|
||
JRST RDLINJ ;^J
|
||
JFCL
|
||
JRST RDLINL ;^L
|
||
JRST RDLINM ;^M
|
||
IFN .-RDLT1-^M-1,.ERR WRONG LENGTH TABLE
|
||
|
||
;DISPATCH TABLE FOR ADDING MORE CHARS TO A LINE.
|
||
RDLT2: REPEAT 200,IDPB C,W2
|
||
LOC RDLT2+^C ? JRST RDLILC
|
||
LOC RDLT2+^J ? JRST RDLILJ
|
||
LOC RDLT2+^L ? JRST RDLILL
|
||
LOC RDLT2+^M ? JRST RDLILM
|
||
LOC RDLT2+": ? JRST RDLCLN
|
||
LOC RDLT2+200
|
||
|
||
;^J, ^L OR ^M WHEN LOOKING FOR START OF LINE:
|
||
;UPDATE PAGE OR LINE NUMBER, AND IGNORE CHAR UNLESS /B.
|
||
RDLINL: TLNE FR,FLALL
|
||
JRST RDLIN4
|
||
SETZM LINNUM(FR)
|
||
AOS PAGNUM(FR)
|
||
AOS LINNUM(FR)
|
||
IFN ITS,[
|
||
HRLZ T,PAGNUM+0
|
||
HRR T,PAGNUM+1
|
||
.SUSET [.SWHO3,,T]
|
||
]
|
||
AOJA W3,RDLIN1
|
||
|
||
RDLINJ: TLNE FR,FLALL
|
||
JRST RDLIN4
|
||
AOS LINNUM(FR)
|
||
AOJA W3,RDLIN1
|
||
|
||
RDLINM: TLNN FR,FLALL
|
||
AOJA W3,RDLIN1 ;NO /B; SKIP THE CHAR, BUT COUNT IT IN # THAT WERE SKIPPED.
|
||
JRST RDLIN4 ;/B, ANY CHAR STARTS A LINE.
|
||
|
||
;^J, ^L OR ^M WHEN ADDING TO A NON-NULL LINE:
|
||
;UPDATE PAGE OR LINE NUM, AND END THE LINE, STORING CHAR IFF /B.
|
||
RDLILL: SETZM LINNUM(FR)
|
||
AOS PAGNUM(FR)
|
||
IFN ITS,[
|
||
HRLZ T,PAGNUM+0
|
||
HRR T,PAGNUM+1
|
||
.SUSET [.SWHO3,,T]
|
||
]
|
||
RDLILJ: AOS LINNUM(FR)
|
||
TLNN FR,FLALL
|
||
JRST RDLIL1
|
||
MPVOK2: IDPB C,W2
|
||
AOJA W3,RDLIN3
|
||
|
||
RDLIL1: AOS CHRNUM(FR) ;NOT /B: MUST UPDATE # CHARS FROM FILE SINCE RDLIN3 WON'T.
|
||
JRST RDLIN3
|
||
|
||
RDLILM: TLNN FR,FLALL ;^M INSIDE A LINE.
|
||
JRST RDLIL1
|
||
MPVOK3: IDPB C,W2 ;IN /B MODE, STORE IT AND LOOK FOR FOLLOWING ^J.
|
||
RDLIL2: ILDB C,CS
|
||
CAIN C,^J
|
||
AOJA W3,RDLILJ ;FOUND => STORE IT TOO.
|
||
CAMN CS,GCHARE(FR) ;DON'T LOSE BECAUSE OF WRAPAROUND IN BUFFER.
|
||
JRST [ CALL RELOAD
|
||
JRST RDLIL2]
|
||
AOJ W3,
|
||
DBP7J CS,RDLIN3
|
||
|
||
;HANDLE COLON IN A LINE. IF /L, MAYBE SET THE FILE'S LLABEL VARIABLE.
|
||
RDLCLN: TLNN FR,FLLABL
|
||
JRST MPVOK4 ;COLON JUST GOES INTO LINE IF LABEL FEATURE OFF.
|
||
JUMPE W3,MPVOK4 ;COLON AT BEGINNING OF LINE ISN'T A LABEL.
|
||
MOVEI T,LNDATA(W1) ;MAKE SURE THERE ARE NO SPACES, TABS, COLONS OR SEMIS
|
||
HRLI T,440700 ;BEFORE THIS COLON.
|
||
RDLCL0: ILDB TT,T
|
||
CAIG TT,40
|
||
JRST MPVOK4
|
||
CAIE TT,":
|
||
CAIN TT,";
|
||
JRST MPVOK4 ;IT LOSES - IT'S JUST A NORMAL COLON.
|
||
CAME T,W2 ;SKIP IF IT WINS. MAKE IT THIS FILE'S LAST LABEL.
|
||
JRST RDLCL0
|
||
MPVOK5: MOVES LNDATA+1(W1) ;MAKE SURE AT LEAST 2 WORDS OF CORE EXIST
|
||
MPVOK7: MOVES 1(T) ;MAKE SURE THERE'S SPACE FOR THE COLON AND TRAILING 0.
|
||
MOVEI TT,":
|
||
IDPB TT,T ;STORE THE COLON IN THE LINE.
|
||
SETZ TT, ;STORE A ^@ AFTER THE COLON. IT WILL GET OVERWRITTEN
|
||
IDPB TT,T ;BY LINE'S NEXT CHAR, BUT WILL LIVE ON IN LLABEL.
|
||
HRRZ T,FR
|
||
LSH T,2
|
||
ADDI T,LLABEL-1 ;T GETS LLABEL-1, PLUS 4 TIMES FILE NUMBER.
|
||
PUSH T,LNDATA(W1) ;STORE 1ST 2 WORDS OF THIS LINE'S DATA THERE.
|
||
PUSH T,LNDATA+1(W1)
|
||
REPEAT LNLBLN-2,PUSH T,[0] ;2 WORDS ARE ENOUGH FOR A MIDAS LABEL, SO ZERO OUT THE REST.
|
||
JRST MPVOK4
|
||
|
||
;HERE IF /Y, AFTER READING IN THE LINE, TO SEE IF IT HAS A LABEL.
|
||
;A LINE HAS A LABEL IN /Y MODE IF IT STARTS WITH ANYTHING BUT A SPACE, TAB OR ;.
|
||
;W1 POINTS AT THE LINE.
|
||
LABEL: SKIPN W3,LNSIZE(W1)
|
||
RET ;IGNORE EMPTY LINES.
|
||
LDB T,[350700,,LNDATA(W1)] ;GET THE LINE'S FIRST CHARACTER.
|
||
CAILE T,40
|
||
JRST LABEL1 ;STARTS WITH NON-CONTROL NOT SPACE => PROBABLY A LABEL.
|
||
CAIN T,40
|
||
RET
|
||
CAIE T,^I
|
||
CAIN T,^L ;BUT LINES STARTING WITH FORMATTERS AREN'T.
|
||
RET
|
||
CAIE T,^M ;IN /B MODE A LINE CAN BE JUST ONE OF THESE. THEY AREN'T.
|
||
CAIN T,^J
|
||
RET
|
||
LABEL1: CAIN T,"; ;CHECK ; HERE - SAVES TIME FOR INDENTED LINES.
|
||
RET
|
||
HRRZ T,FR
|
||
IMULI T,LNLBLN
|
||
ADDI T,LLABEL-1 ;GET -1 + ADDR OF PLACE TO PUT LABEL.
|
||
MOVE TT,T ;SAVE THIS FOR LABEL2 WHICH ALSO NEEDS IT.
|
||
REPEAT LNLBLN,[
|
||
CAIL W3,.RPCNT*5+1 ;COPY START OF LINE INTO IT, BUT DON'T GO PAST END OF LINE
|
||
PUSH T,.RPCNT+LNDATA(W1) ;IF IT IS A SHORT ONE.
|
||
] ;NO NEED TO ZERO OUT REST OF WORDS CAUSE IF LINE IS SHORT
|
||
TLNN FR,FLALL ;THEN THE REAL DATA MUST HAVE A ^@ AFTER IT ANYWAY.
|
||
RET
|
||
MOVEI T,1(TT) ;IN /B MODE, THE LINE MAY HAVE A REAL ^M^J IN IT,
|
||
HRLI T,440700 ;AND IF IT IS SHORT THEN THE ^M^J WAS COPIED INTO THE LABEL.
|
||
MOVEI W3,5*LNLBLN ;SO REPLACE IT WITH A NULL, IN THE LABEL.
|
||
LABEL2: ILDB TT,T
|
||
JUMPE TT,CPOPJ ;LABEL ENDS WITH NULL AND HAS NO ^M OR ^J?
|
||
CAIE TT,^M
|
||
CAIN TT,^J
|
||
CAIA
|
||
SOJG W3,LABEL2 ;MAYBE WE EXHAUST THE WORDS OF LABEL AND THERE IS NONE.
|
||
JUMPE W3,CPOPJ
|
||
SETZ TT, ;IF THERE IS A ^M OR ^J, TRUNCATE LABEL AT THAT POINT.
|
||
DPB TT,T
|
||
RET
|
||
|
||
;HANDLE ^C WHEN LOOKING FOR START OF LINE.
|
||
RDLINC: CAMN CS,GCHARE(FR) ;IS THIS THE ^C AFTER THE BUFFER?
|
||
JRST [ CALL RELOAD ;YES, RELOAD THE BUFFER AND TRY AGAIN.
|
||
JRST RDLIN1]
|
||
CAME CS,@GCHARZ(FR) ;IS THIS EOF, OR A ^C IN THE FILE?
|
||
JRST RDLIN4 ;^C IN FILE STARTS A LINE.
|
||
IOR FR,EOFTBL(FR) ;IT IS EOF.
|
||
RDLIL5: SETOM EOFFL1(FR)
|
||
MOVEM CS,@GCHARP(FR)
|
||
RET
|
||
|
||
;HANDLE ^C WHEN ADDING TO A LINE.
|
||
RDLILC: CAMN CS,GCHARE(FR)
|
||
JRST [ CALL RELOAD
|
||
JRST RDLIN2]
|
||
CAME CS,@GCHARZ(FR) ;^C IN FILE GOES IN THE LINE.
|
||
JRST MPVOK4
|
||
IOR FR,EOFTBL(FR) ;EOF IN MIDDLE OF LINE: SAY EOF WAS REACHED.
|
||
MOVEI T,LNDATA-1(W1)
|
||
RDLIL4: CAIN T,(W2) ;FLUSH ALL ^C'S AND ^@'S OFF THE END OF THE LINE.
|
||
JRST RDLIL5 ;LINE WAS NOTHING BUT ^C'S AND ^@'S? SAY THERE WAS NO LINE.
|
||
LDB C,W2
|
||
CAIE C,^C
|
||
JUMPN C,RDLIN3 ;LINE HAS SOMETHING ELSE, SO RETURN IT.
|
||
SOJ W3,
|
||
DBP7J W2,RDLIL4
|
||
|
||
MPVOK4: IDPB C,W2 ;COME HERE TO INSERT A ^C OR : IN A LINE,
|
||
AOJA W3,RDLIN2 ;WITHOUT THE SPECIAL HANDLING THEY SOMETIMES GET.
|
||
|
||
; RDWRD - Read a word from file. This is completely independent of
|
||
; RDLIN and RELOAD.
|
||
; Returns .+1 if EOF
|
||
; Returns .+2 otherwise,
|
||
; W1/ word
|
||
|
||
RDWRD: SOSGE GWORDC(FR) ; Decrement total cnt for file
|
||
JRST [ SETOM EOFFL1(FR) ; Hit EOF.
|
||
SETOM GWORDB(FR)
|
||
SETZM GWORDC(FR) ; Keep this normalized.
|
||
RET]
|
||
AOSE W1,GWORDB(FR) ; Skip for initial loadup
|
||
CAMLE W1,GWORDE(FR)
|
||
JRST RDWRD2 ; Load up the buffer.
|
||
MOVE W1,(W1)
|
||
AOS (P)
|
||
RET
|
||
RDWRD2: MOVEI CS,FILBFL
|
||
MOVE C,GWORDI(FR)
|
||
HRRZM C,GWORDB(FR)
|
||
CALL @GCHARX(FR) ; Read another bufferful
|
||
MOVE W1,@GWORDB(FR) ; Get 1st wd of buffer
|
||
AOS (P)
|
||
RET
|
||
|
||
GWORDL: BLOCK 3 ; # words length of file
|
||
GWORDC: BLOCK 3 ; # words left in file
|
||
GWORDB: -1 ? -1 ? -1
|
||
GWORDI: 444400,,FILBF1
|
||
444400,,FILBF2
|
||
444400,,FILBF3
|
||
GWORDE: FILBE1 ? FILBE2 ? FILBE3
|
||
|
||
; RUDWRD - Read a word from inferior process.
|
||
; This is completely independent of RDLIN and RELOAD.
|
||
; Returns .+1 if EOF
|
||
; Returns .+2 otherwise,
|
||
; W1/ word
|
||
|
||
RDUWRD: SOSGE GWORDC(FR) ; Decrement total cnt for file
|
||
JRST [ SETOM EOFFL1(FR) ; Hit EOF.
|
||
SETOM GWORDB(FR)
|
||
SETZM GWORDC(FR) ; Keep this normalized.
|
||
RET]
|
||
AOSE W1,GWORDB(FR) ; Skip for initial loadup
|
||
CAMLE W1,GWORDE(FR)
|
||
JRST RDUWD2 ; Load up the buffer.
|
||
MOVE W1,(W1)
|
||
AOS (P)
|
||
RET
|
||
RDUWD2: MOVEI CS,FILBFL
|
||
MOVE C,GWORDI(FR)
|
||
HRRZM C,GWORDB(FR)
|
||
CALL RDUBUF
|
||
MOVE W1,@GWORDB(FR) ; Get 1st wd of buffer
|
||
AOS (P)
|
||
RET
|
||
|
||
RDUBUF:
|
||
IFN ITS,[
|
||
M.SIN CHUIN1(FR),C,CS
|
||
RET
|
||
] ;IFN ITS
|
||
IFN TNX,[
|
||
TYPE "Error - TNX version doesn't have /$ feature yet
|
||
"
|
||
HALT
|
||
] ;IFN TNX
|
||
|
||
|
||
;REFILL THE BUFFER OF THE FILE (FR). WORKS WHETHER READING IN CHAR
|
||
;OR WORD MODE, ON BOTH ITS AND TNX (WHICH UPDATE BP'S DIFFERENTLY).
|
||
RELOAD: MOVE C,GCHARI(FR) ;YES, JUST REFILL THE BUFFER. GET BP
|
||
MOVEI CS,FILBFL ;AND COUNT
|
||
CALL @GCHARX(FR) ;INPUT THE STUFF
|
||
TLZ C,7700
|
||
TLO C,0700 ;MAKE BP A CHAR B.P. (IF NOT ALREADY)
|
||
MOVEI CS,^C
|
||
IDPB CS,C ;PUT A ^C AFTER WHAT WE INPUT.
|
||
MOVEM C,@GCHARZ(FR) ;AND SAVE BP TO EOF CHAR.
|
||
MOVE CS,GCHARB(FR) ;RE-INIT THE B.P.
|
||
RET
|
||
|
||
GCHARP: FILPT1 ;ADDRESS OF BUFFER BP OF FILE.
|
||
FILPT2
|
||
FILPT3
|
||
|
||
GCHARZ: FILEP1 ;ADDR OF B.P. TO THE ^C AFTER WHAT WAS READ IN.
|
||
FILEP2
|
||
FILEP3
|
||
|
||
GCHARI: 444400,,FILBF1 ; BP TO IDPB 1ST WD OF BUFFER.
|
||
444400,,FILBF2
|
||
444400,,FILBF3
|
||
|
||
GCHARB: 440700,,FILBF1 ;B.P. TO ILDB 1ST CHAR OF BUFFER.
|
||
440700,,FILBF2
|
||
440700,,FILBF3
|
||
|
||
GCHARE: 350700,,FILBE1+1 ;B.P. TO ^C AFTER END OF BUFFER.
|
||
350700,,FILBE2+1
|
||
350700,,FILBE3+1
|
||
|
||
GCHARX: [M.SIN CHIN1,C,CS ;INSTRS TO INPUT ON CHIN1
|
||
RET]
|
||
[M.SIN CHIN2,C,CS ;DITTO FOR CHIN2
|
||
RET]
|
||
[M.SIN CHIN3,C,CS
|
||
RET]
|
||
|
||
EOFTBL: FLEOF1,, ;EOF FLAG FOR FILE 1
|
||
FLEOF2,, ;EOF FLAG FOR FILE 2
|
||
FLEOF3,,
|
||
|
||
RCHSTP: 440700,,HBUF1 ;BYTE POINTERS TO HEADER TABLES
|
||
440700,,HBUF2
|
||
440700,,HBUF3
|
||
|
||
; INT HANDLER, ITS ONLY - HANDLES MPV AND --MORE-- INTERRUPTS.
|
||
; TNX DOESN'T NEED MPV HANDLER (ALTHO IT MAKES ERRORS HARDER TO FIND)
|
||
; AND DOESN'T HAVE --MORE-- INTERRUPTS...
|
||
|
||
IFN ITS,[
|
||
|
||
TSINT:
|
||
LOC 42 ? JSR TSINT ? LOC TSINT ; ENSURE INT VECTOR SET UP
|
||
0
|
||
0
|
||
EXCH W1,TSINT
|
||
JUMPL W1,MORINT
|
||
CAIE W1,%PIMPV
|
||
ERRHLT
|
||
HRRZ W1,TSINT+1 ;MPV INTERRUPTS TO GET MORE CORE ARE LEGAL
|
||
CAIE W1,MPVOK7 ;ONLY FROM CERTAIN SPOTS.
|
||
CAIN W1,MPVOK6
|
||
JRST TSINT2
|
||
CAIE W1,MPVOK5
|
||
CAIN W1,MPVOK4
|
||
JRST TSINT2
|
||
CAIE W1,MPVOK3
|
||
CAIN W1,MPVOK2
|
||
JRST TSINT2
|
||
CAIE W1,MPVOK1
|
||
CAIN W1,MPVOK0
|
||
CAIA
|
||
ERRHLT
|
||
TSINT2: .SUSET [.RMPVA,,W1]
|
||
LSH W1,-10.
|
||
SYSCAL CORBLK,[MOVEI 400000 ? MOVEI -1 ? W1 ? MOVEI 400001]
|
||
JRST [ CALL TYLERR ? JRST ERRFIN]
|
||
MOVE W1,TSINT
|
||
.DISMI TSINT+1
|
||
|
||
MORINT: MOVE W1,TSINT
|
||
INSIRP PUSH P,C T
|
||
MOVEI T,[ASCIZ /--MORE--/]
|
||
CALL TYPMS0
|
||
SYSCAL IOT,[MOVEI CHTTI ? MOVE C ? 5000,,%TIPEK]
|
||
.LOSE 1000
|
||
CAIN C,^C
|
||
JRST MORKIL
|
||
CAIE C,40
|
||
CAIN C,177
|
||
.IOT CHTTI,C ;SPACE OR RUBOUT IS GOBBLED.
|
||
SKIPE FLUSHP
|
||
CAIN C,40 ;IF IT ISN'T SPACE, AND WE CAN FLUSH, DO SO.
|
||
JRST MORPRC
|
||
MOVEI T,[ASCIZ /FLUSHED
|
||
/]
|
||
CALL TYPMS0
|
||
MOVE P,FLUSHP
|
||
SETZM FLUSHP
|
||
.DISMI [CPOPJ]
|
||
|
||
MORKIL: .IOT CHTTI,C ;^C => GOBBLE IT AND KILL THE SRCCOM.
|
||
.LOGOUT
|
||
.BREAK 16,160000
|
||
|
||
MORPRC: MOVEI T,[ASCIZ /
|
||
/]
|
||
CALL TYPMS0
|
||
INSIRP POP P,T C
|
||
.DISMI TSINT+1
|
||
|
||
] ;IFN ITS
|
||
|
||
;OPEN INPUT FILE ON CHNL IN W1.
|
||
|
||
INOPEN: MOVEI FP,INFB
|
||
HRLI FP,(W1) ;MAKE <CH>,,<FB ADDR>
|
||
IFN ITS,[
|
||
MOVSI W2,(SIXBIT/>/)
|
||
SKIPN $F6FN2(FP) ;DEFAULT THE FN2 TO ">".
|
||
MOVEM W2,$F6FN2(FP)
|
||
]
|
||
MOVEI W2,OPNRDA ;USE UNIT MODE FOR /X FILES,
|
||
TLNN FR,FLXCTF
|
||
MOVEI W2,OPNRDW ;USE BLOCK MODE FOR OTHER INPUT FILES.
|
||
CALL (W2)
|
||
CALL OPENL ; LOST?? REPORT ERROR.
|
||
MOVE W2,INOPT3-CHIN1(W1) ;GET ADDR OF LAST WORD OF BUFFER.
|
||
MOVEI W1,(W2)
|
||
HRLI W1,10700 ;MAKE B.P. TO END OF BUFFER,
|
||
MOVEM W1,FILPT1-FILBE1(W2)
|
||
MOVE W1,[ASCIC//]
|
||
MOVEM W1,1(W2)
|
||
HRRI FR,0 ;PUT NUMBER OF FILE INTO FR.
|
||
CAIE W2,FILBE1
|
||
HRRI FR,1
|
||
PJRST RCHST ;SET UP FILE'S HEADER.
|
||
|
||
INOPT3: FILBE1
|
||
FILBE2
|
||
FILBE3
|
||
|
||
;COME HERE WHEN /@ IS SPECIFIED FOR THE 1ST INPUT FILE.
|
||
;THAT MEANS TO TREAT THE SPECIFIED 1ST INPUT FILE AS A COMPARISON
|
||
;FILE, EXTRACT THE NAME OF THE SECOND FILE USED IN THAT COMPARISON,
|
||
;AND USE THAT FILE AS OUR 1ST INPUT FILE THIS TIME.
|
||
;JUMPS BACK TO THE COMMAND PROCESSING LEVEL TO OPEN THE REAL 1ST INPUT FILE.
|
||
RFINDR: MOVE W1,GCHARI
|
||
MOVEI W2,FILBFL
|
||
M.SIN CHIN1,W1,W2 ;READ IN SOME OF THE FILE.
|
||
ADDI W1,1
|
||
ANDI W1,-1 ;MAKE SURE IT LOOKS LIKE A COMPARISON FILE.
|
||
CAIGE W1,FILBF1+10.
|
||
JRST ERRIND
|
||
MOVE W1,FILBF1
|
||
MOVE W2,FILBF1+1
|
||
CAMN W1,[ASCII /
|
||
;CO/]
|
||
CAME W2,[ASCII /MPARI/]
|
||
JRST ERRIND
|
||
MOVE W1,FILBF1+2
|
||
CAME W1,[ASCII /SON O/]
|
||
JRST ERRIND
|
||
MOVE W1,[350700,,FILBF1+3] ;POINT AT THE SPACE AFTER THE "OF".
|
||
MOVEI W2,4
|
||
RFIND2: ILDB C,W1 ;THEN SKIP PAST 3 SPACES, TO BE AFTER THE "AND".
|
||
CAIE C,40
|
||
JRST RFIND2
|
||
SOJG W2,RFIND2
|
||
SAVE TTIPNT ;WHICH IS JUST AT THE SECOND COMPARED FILE'S NAME.
|
||
SAVE TTICNT
|
||
HRLZM P,TTICNT
|
||
MOVEM W1,TTIPNT ;READ IN THAT FILE NAME
|
||
CALL RFILE ;RFILE RETURNS AFTER THE FN2 SINCE FLINDR=1.
|
||
ILDB C,TTIPNT
|
||
CAIE C,^J
|
||
JRST .-2 ;PASS THE LINEFEED OF THAT LINE
|
||
MOVEI C,3
|
||
ADDM C,TTIPNT ;SKIP THE ";OPTIONS ARE "
|
||
CALL RFILSW ;READ THE SWITCHES FROM THE COMPARISON FILE
|
||
REST TTICNT
|
||
REST TTIPNT
|
||
TLZ FR,FLINDR
|
||
JRST RFIND1
|
||
|
||
IFN ITS,[
|
||
|
||
;PUT FILE DESCRIPTION IN ASCII INTO HBUF FOR THIS FILE
|
||
RCHST: SYSCAL RFNAME,[ MOVEI CHIN1(FR)
|
||
2000,,RCHSTB
|
||
2000,,RCHSTB+1
|
||
2000,,RCHSTB+2
|
||
2000,,RCHSTB+3]
|
||
.LOSE 1000
|
||
SYSCAL FILLEN,[MOVEI CHIN1(FR) ? MOVEM W2]
|
||
.LOSE 1000
|
||
MOVEM W2,GWORDL(FR) ; Set length of file
|
||
MOVEM W2,GWORDC(FR) ; Also # of words left to read
|
||
|
||
MOVE W2,RCHSTP(FR) ;NOW SET UP BYTE POINTER TO HEADER AREA TO READ INTO
|
||
MOVE T,RCHSTB ;GET THE CHOSEN DEVICE NAME
|
||
JSP W1,RCHST6 ;DEVICE NAME
|
||
": ;END WITH COLON
|
||
MOVE T,RCHSTB+3
|
||
JSP W1,RCHST6 ;SYSTEM NAME
|
||
"; ;TERMINATED BY SEMICOLON
|
||
SKIPN T,RCHSTB+1
|
||
MOVE T,INFB+$FNAME ;IF REALLY NONE, USE SPEC'D.
|
||
SKIPN LSTFB+$FNAME ;DEFAULT OUTPUT FN1 TO INPUT.
|
||
MOVEM T,LSTFB+$FNAME
|
||
JSP W1,RCHST6 ;FNAM1
|
||
40 ;TERMINATED (ITS CONVENTION) BY SPACE
|
||
SKIPN T,RCHSTB+2
|
||
MOVE T,INFB+$FEXT
|
||
JSP W1,RCHST6 ;FNAM2
|
||
0 ;DON'T PRINT TERMINATING CHAR
|
||
MOVEI C,0
|
||
IDPB C,W2 ;MARK END OF STRING
|
||
SKIPN FSBIN ; If hacking inferior process addr space, skip
|
||
RET ; else return, done.
|
||
|
||
SKIPN UNQNAM
|
||
.SUSET [.RJNAME,,UNQNAM]
|
||
AOS UNQNAM
|
||
MOVEI T,CHUO1(FR)
|
||
HRLI T,.UIO
|
||
SYSCAL OPEN,[T ? ['USR,,] ? [0] ? UNQNAM]
|
||
.LOSE 1000
|
||
MOVEI T,CHUIN1(FR)
|
||
HRLI T,.UII
|
||
SYSCAL OPEN,[T ? ['USR,,] ? [0] ? UNQNAM]
|
||
.LOSE 1000
|
||
SYSCAL LOAD,[MOVEI (T) ? MOVEI CHIN1(FR)]
|
||
.LOSE 1000
|
||
SYSCAL ACCESS,[MOVEI (T) ? [0]]
|
||
.LOSE 1000
|
||
SYSCAL USRVAR,[MOVEI (T) ? [SIXBIT /MEMT/] ? MOVEM W2]
|
||
.LOSE 1000
|
||
MOVEM W2,GWORDL(FR)
|
||
MOVEM W2,GWORDC(FR)
|
||
RET
|
||
.SCALAR UNQNAM
|
||
|
||
;JSP W1,RCHST6 ;PRINT (IDPB ASCII VIA W2) SIXBIT WORD IN T
|
||
; "<TERMINATING CHAR OR 0> ;FOLLOW WITH TERMINATING CHAR UNLESS SIXBIT IS NULL
|
||
; ^ DOESN'T PRINT TRAILING SPACES
|
||
|
||
RCHST6: JUMPE T,1(W1) ;RETURN ON NULL ARG
|
||
RCHS6A: MOVEI C,0 ;CLEAR OUT C TO RECEIVE CHAR
|
||
LSHC C,6 ;SHIFT IN NEXT CHAR
|
||
ADDI C,40 ;CONVERT TO ASCII
|
||
IDPB C,W2 ;DEPOSIT WHEREVER IT'S GOING
|
||
JUMPN T,RCHS6A ;LOOP UNTIL WORD EMPTY
|
||
SKIPE C,(W1) ;NOW GET TERMINATOR
|
||
IDPB C,W2 ;NOT NULL, USE IT
|
||
JRST 1(W1)
|
||
] ;IFN ITS
|
||
|
||
;READ IN A COMMAND, PROCESSING RUBOUTS, PROMPTING WITH "#".
|
||
CMDLIN: SKIPE CMDFIL
|
||
JRST TTIFIL ;IF IN COMMAND FILE, READ FROM IT INSTEAD OF TTY.
|
||
TTILIN: HRROS (P) ;PROMPT WITH "#".
|
||
JRST TTILI1
|
||
|
||
TTILNA: HRRZS (P) ;FOR /M INPUT, PROMPT WITH "*"
|
||
JRST TTILI1
|
||
|
||
;READ A CHAR OF TTY INPUT (OR ^M IF NONE LEFT).
|
||
TTICHR: SOSGE TTICNT ;IF NO CHARS LEFT,
|
||
SKIPA C,[^M] ;SAY EOL.
|
||
ILDB C,TTIPNT ;ELSE GET NEXT CHAR FROM BUFFER.
|
||
RET
|
||
|
||
;READ AND UPCASE A CHAR OF INPUT.
|
||
TTICHU: CALL TTICHR ;GET CHAR
|
||
CAIL C,"A+40 ;SKIP IF LESS THAN LOWER CASE A
|
||
CAILE C,"Z+40 ;SKIP IF IN RANGE A-Z
|
||
CAIA ;SKIP IF NOT A-Z (LC)
|
||
SUBI C,40 ;LOWER CASE TO UPPER CASE
|
||
RET
|
||
|
||
IFN ITS,[
|
||
RUBOUT"A=1
|
||
RUBOUT"B=2
|
||
RUBOUT"C=3
|
||
RUBOUT"D=4
|
||
|
||
RUBOUT"$$PROMPT==1
|
||
|
||
.INSRT SYSENG;RUBOUT
|
||
|
||
RUBOUT"INCHR:
|
||
.IOT CHTTI,RUBOUT"A
|
||
RET
|
||
|
||
RUBOUT"OUTCHR:
|
||
SYSCAL IOT,[%CLIMM,,CHTTO ? RUBOUT"A ? %CLBIT,,%TJMOR]
|
||
.LOSE %LSFIL
|
||
RET
|
||
|
||
RUBOUT"DISPLAY:
|
||
SYSCAL IOT,[%CLIMM,,CHTTO ? RUBOUT"A ? %CLBIT,,%TJMOR+%TJDIS]
|
||
.LOSE %LSFIL
|
||
RET
|
||
|
||
RUBOUT"PROMPT:
|
||
MOVEI RUBOUT"A,"#
|
||
SKIPL PRMNUM
|
||
MOVEI RUBOUT"A,"*
|
||
JRST RUBOUT"OUTCHR
|
||
|
||
RUBOUT"DISPATCH:
|
||
CAIN RUBOUT"A,%TXCTL+"Q ;MAKE ^Q NOT SPECIAL FOR RUBOUT PROCESSING.
|
||
JRST RUBOUT"INSECH ;THAT IS, IT WON'T QUOTE A RUBOUT.
|
||
CAIN RUBOUT"A,%TXCTL+"M ;^M SHOULD JUST INSERT A ^M, NOT ^M^J
|
||
JRST RUBOUT"BRKINS
|
||
JRST RUBOUT"RB$DSP
|
||
|
||
.SCALAR PRMNUM ;NEGATIVE => PROMPT WITH #. POS OR ZERO => PROMPT WITH *.
|
||
.VECTOR RBBLK(RUBOUT"RB.LEN) ;RUBOUT PROCESSOR ARGUMENT BLOCK.
|
||
|
||
;READ A LINE BY CALLING THE RUBOUT PACKAGE. ASSUMES LH OF (P) NEGATIVE => PROMPT WITH #.
|
||
TTILI1: CALL CRLF
|
||
MOVE W1,(P)
|
||
MOVEM W1,PRMNUM
|
||
TTILI9: CALL RUBOUT"PROMPT
|
||
MOVE W1,[010700,,TTIBUF-1]
|
||
MOVEM W1,TTIPNT ;SET UP FOR FETCHING CHARS LATER.
|
||
MOVEM W1,RBBLK+RUBOUT"RB.BEG
|
||
ADDI W1,TTIBFL
|
||
MOVEM W1,RBBLK+RUBOUT"RB.END
|
||
MOVEI RUBOUT"A,CHTTO
|
||
MOVEI RUBOUT"B,RBBLK
|
||
CALL RUBOUT"INIT
|
||
TTILI8: CALL RUBOUT"READ ;READ CHARACTERS UP TO BREAK CHAR.
|
||
CAMN RUBOUT"A,[-1]
|
||
JRST [ .IOT CHTTO,[^G] ;BUFFER FULL: DING, AND LET USER RUB OUT SOME.
|
||
JRST TTILI8]
|
||
JUMPL RUBOUT"A,TTILI1 ;OVER-RUBOUT => CRLF AND TRY AGAIN.
|
||
MOVEI W2,0
|
||
DPB W2,RBBLK+RUBOUT"RB.PTR ;REPLACE BREAK CHAR WITH 0.
|
||
CAIN RUBOUT"A,%TXCTL+"M
|
||
JRST TTILI4
|
||
CALL CRLF ;IF BREAK WASN'T A CR, TYPE A CR,
|
||
TLNN FR,FLMERG ;AND IF READING A COMMAND, REMEMBER TO RETURN TO DDT
|
||
SETOM CTLCF ;AFTER EXECUTING IT.
|
||
TTILI4: MOVE W1,TTIPNT ;COUNT THE CHARACTERS WE GOT. SET UP TTICNT.
|
||
SETZM TTICNT
|
||
TTILI2: CAMN W1,RBBLK+RUBOUT"RB.PTR
|
||
JRST TTILI3
|
||
IBP W1
|
||
AOS TTICNT
|
||
JRST TTILI2
|
||
|
||
TTILI3: SOSE TTICNT ;DON'T COUNT THE TERMINAL 0 IN TTICNT.
|
||
RET ;RETURN IF LINE IS NON NULL.
|
||
SKIPL (P) ;IF IT ISN'T A COMMAND, RETURN IT EVEN THOUGH NULL.
|
||
RET
|
||
SKIPGE CTLCF ;NULL COMMAND LINE ENDED BY ^C MEANS EXIT.
|
||
JRST QUIT
|
||
JRST TTILI9 ;OTHERWISE READ ANOTHER COMMAND LINE.
|
||
]
|
||
|
||
IFN TNX,[
|
||
TTILI1: CALL CRLF
|
||
TTILI2: SKIPE FLG20X ;ON A 20?
|
||
JRST TTIL20 ;YES
|
||
;COME HERE AFTER NULL LINE.
|
||
SETZM TTICNT ;NO CHARS READ YET.
|
||
SKIPGE (P)
|
||
MOUTI CHTTO,"#
|
||
SKIPL (P)
|
||
MOUTI CHTTO,"*
|
||
MOVE C,[440700,,TTIBUF]
|
||
MOVEM C,TTIPNT
|
||
TTILUP: CALL TYI ;READ A CHAR FROM TTY.
|
||
CAIN C,^M
|
||
JRST TTICR ;^M MEANS ALL READ.
|
||
CAIE C,^D
|
||
CAIN C,^U
|
||
JRST TTILI1 ;^U CANCELS CMD.
|
||
CAIN C,177
|
||
JRST TTIRUB
|
||
CAIN C,^L ;IF USER TYPES ^L, RETYPE THE BUFFERED INPUT.
|
||
JRST TTICTL
|
||
CAIE C,^Z
|
||
CAIN C,^C
|
||
JRST TTICTC ;^C MEANS DO CMD, THEN VALRET :KILL.
|
||
IDPB C,TTIPNT ;NORMAL CHAR.
|
||
AOS TTICNT
|
||
JRST TTILUP
|
||
|
||
TTICTC: CALL CRLF ;INDICATE COMMAND HAS BEEN TERMINATED.
|
||
TLNN FR,FLMERG ;^C DOES NOTHING IF INPUT TO MERGE.
|
||
SETOM CTLCF ;REMEMBER TO VALRET WHEN CMD DONE.
|
||
;HERE AFTER ORDINARY LINE TERMINATOR.
|
||
TTICR: SKIPL (P)
|
||
JRST TTICR1
|
||
SKIPN TTICNT ;IF NULL COMMAND LINE, RETRY.
|
||
JRST TTILI3
|
||
TTICR1: SETZ C,
|
||
IDPB C,TTIPNT ; TERMINATE WITH ASCIZ
|
||
MOVE C,[440700,,TTIBUF]
|
||
MOVEM C,TTIPNT ;SET UP FOR REMOVAL OF CHARS.
|
||
RET
|
||
|
||
TTILI3: SKIPE CTLCF ;NULL LINE:
|
||
JRST QUIT ;...IF ^C ENDED LINE.
|
||
JRST TTILI2
|
||
|
||
TTICTL: MOVEI T,[ASCIZ /#/] ;COME HERE FOR ^L. SCREEN ALREADY CLEARED ON DISPLAY.
|
||
SKIPL (P)
|
||
MOVEI T,[ASCIZ /*/]
|
||
CALL TYPMSG ;PRINT CRLF AND ASTERISK.
|
||
MOVE TT,[440700,,TTIBUF]
|
||
MOVE C,TTICNT ;THEN RETYPE THE BUFFERED INPUT.
|
||
M.SOUT CHTTO,TT,C
|
||
JRST TTILUP
|
||
|
||
TTIRUB: SOSGE TTICNT ;IF NO CHAR TO RUB, RETRY.
|
||
JRST TTILI1
|
||
LDB C,TTIPNT
|
||
MOUTC CHTTO,C ;PRINT RUBBED CHAR.
|
||
MOVSI C,070000
|
||
ADD C,TTIPNT
|
||
JUMPGE C,TTIRU1 ;IF STILL IN SAME WD.
|
||
MOVEI C,-1(C ) ;ELSE, MOVE TO END OF PREV. WD.
|
||
HRLI C,010700
|
||
TTIRU1: MOVEM C,TTIPNT
|
||
JRST TTILUP
|
||
|
||
;USE SYSTEM ROUTINES ON A 20
|
||
TTIL20: HRROI R3,[ASCIZ /#/] ;PROMPTING TEXT
|
||
SKIPL (P)
|
||
HRROI R3,[ASCIZ /*/]
|
||
MOVE R1,R3 ;HAVE TO OUTPUT PROMPT BY HAND, SIGH
|
||
PSOUT
|
||
HRROI R1,TTIBUF
|
||
MOVE R2,[RD%TOP+5*TTIBFL]
|
||
RDTTY
|
||
JRST RESTRT
|
||
TLZ R2,-1 ;FIGURE COUNT
|
||
SUBI R2,5*TTIBFL
|
||
LDB C,R1
|
||
CAIE C,^J
|
||
JRST TTIL21
|
||
MOVNI R3,1
|
||
ADJBP R3,R1
|
||
LDB C,R3
|
||
CAIE C,^M
|
||
JRST TTIL21
|
||
MOVE R1,R3
|
||
ADDI R2,1
|
||
TTIL21: MOVNI R3,1
|
||
ADJBP R3,R1
|
||
MOVEM R3,TTIPNT
|
||
SETCAM R2,TTICNT ; TTICNT := -R2-1
|
||
CAIE C,^Z
|
||
JRST TTICR
|
||
JRST TTICTC
|
||
] ;IFN TNX
|
||
|
||
;COME HERE TO SEE IF THE COMMAND STRING IS JUST "?" OR "HELP".
|
||
;IF NOT, RETURNS. IF SO, PRINTS HELP (FROM INFO;SRCCOM >)
|
||
;AND RETURNS TO RELDEV.
|
||
TRYHLP: SAVE TTIPNT
|
||
SAVE TTICNT
|
||
CALL TTINSP ;GO PAST INITIAL SPACES.
|
||
CAIN C,"?
|
||
JRST TRYHL1 ;"?" MIGHT BE START OF GOOD STUFF
|
||
CAIE C,"H ;SO MIGHT "H".
|
||
JRST TRYHLL ;ANYTHING ELSE => USER ISN'T ASKING FOR HELP.
|
||
CALL TTICHU
|
||
CAIE C,"E
|
||
JRST TRYHLL
|
||
CALL TTICHU
|
||
CAIE C,"L
|
||
JRST TRYHLL
|
||
CALL TTICHU
|
||
CAIE C,"P
|
||
JRST TRYHLL
|
||
TRYHL1: CALL TTINSP
|
||
CAIE C,^M
|
||
CAIN C,^C
|
||
CAIA
|
||
JRST TRYHLL
|
||
;USER WANTS HELP - GIVE IT TO HIM.
|
||
CALL OPNHLP
|
||
JRST ERRHLP
|
||
TRYHL3: M.BIN CHIN1,C
|
||
CAIN C,^L
|
||
JRST RELDEV
|
||
JUMPL C,RELDEV
|
||
MOUTC CHTTO,C
|
||
JRST TRYHL3
|
||
|
||
TRYHLL: REST TTICNT
|
||
REST TTIPNT
|
||
RET
|
||
|
||
;READ 1 CHAR FROM THE COMMAND STRING, THEN KEEP READING TILL READ A NON-SPACE.
|
||
;CONVERTS TO UPPER CASE.
|
||
TTINSP: CALL TTICHU
|
||
CAIN C,40
|
||
JRST TTINSP
|
||
RET
|
||
|
||
;COME HERE TO HANDLE A COMMAND WITH /X IN IT.
|
||
CMDXCT: SKIPE CMDFIL
|
||
JRST ERRXCT ;/X INSIDE AN EXECUTE FILE??
|
||
SKIPLE TTICNT ;ANY EXTRA FILES SPECIFIED?
|
||
JRST ERRXTRA
|
||
M.MVCH CHIN1,CHCMD ;MAKE THE ALREADY OPEN 1ST INPUT FILE BE OUR COMMAND FILE.
|
||
MOVE W1,INFB+$FDIR
|
||
MOVEM W1,CMDIS ;MAKE INPUT DEV AND SNAME THE INPUT DEFAULTS
|
||
MOVE W1,INFB+$FDEV
|
||
MOVEM W1,CMDID
|
||
MOVE W1,LSTFB+$FDIR
|
||
MOVEM W1,CMDOS ;AND OUR OUTPUT DEV AND SNAME THE OUTPUT DEFAULTS
|
||
MOVE W1,LSTFB+$FDEV
|
||
CAMN W1,FSTTY
|
||
MOVE W1,FSDSK
|
||
MOVEM W1,CMDOD
|
||
SETOM CMDFIL ;SAY WE ARE NOW EXECUTING A COMMAND FILE.
|
||
JRST RELDEV ;GO READ THE NEXT COMMAND.
|
||
|
||
;COME HERE TO READ A COMMAND LINE FROM A COMMAND FILE.
|
||
TTIFIL: SETZM TTICNT ;INITIALIZE THE COMMAND BUFFER EMPTY.
|
||
MOVE BP,[440700,,TTIBUF]
|
||
MOVEM BP,TTIPNT
|
||
;NOW SEE IF THERE ARE ANY MORE COMMANDS IN THE FILE.
|
||
TTIFI0: M.BIN CHCMD,C
|
||
TTIFI1: ANDI C,-1
|
||
CAIE C,^C ;EOF OR END OF 1ST PAGE => COMMAND FILE IS OVER.
|
||
CAIN C,^L
|
||
JRST TTIEOF
|
||
CAIE C,"; ;ELSE, A COMAND LINE IS IDENTIFIED BY
|
||
JRST TTIFI0 ;STARTING WITH ";;SRCCOM COMMAND ;;"
|
||
IRPC X,,[;SRCCOM COMMAND ;;]
|
||
M.BIN CHCMD,C
|
||
CAIE C,"X
|
||
JRST TTIFI1
|
||
TERMIN
|
||
;WE FOUND ANOTHER COMMAND LINE'S BEGINNING.
|
||
;NOW, EVERYTHING UP TO NEXT ^C, ^L, ^M OR ";;" IS PART OF THE COMMAND.
|
||
TDZA W1,W1
|
||
TTIFI2: MOVE W1,C ;REMEMBER THE PREVIOUS CHAR FOR FINDING ";;".
|
||
M.BIN CHCMD,C
|
||
ANDI C,-1
|
||
CAIE C,^C
|
||
CAIN C,^M
|
||
JRST TTIFI3
|
||
CAIN C,^L ;STOP BEFORE A ^C, ^L OR ^M.
|
||
JRST TTIFI3
|
||
CAIN C,"; ;BEFORE THE SECOND ";" OF A ";;",
|
||
CAIE W1,";
|
||
AOSA TTICNT
|
||
JRST TTIFI4 ;MUST STOP, AND FLUSH THE PREVIOUS ";".
|
||
IDPB C,BP ;ELSE STORE THE CHAR AND COUNT IT.
|
||
JRST TTIFI2
|
||
|
||
TTIFI4: SOS TTICNT
|
||
DBP7J BP,
|
||
TTIFI3: SETZ C, ;NOW WE HAVE READ IN A WHOLE LINE.
|
||
IDPB C,BP ;SO MAKE IT ASCIZ
|
||
MOVEI T,TTIBUF ;AND TYPE IT ON THE TTY SO USER CAN MONITOR PROGRESS.
|
||
CALL TYPMS0
|
||
JRST CRLF
|
||
|
||
TTIEOF: M.CLS CHCMD ;HERE AT END OF COMMAND FILE.
|
||
SETZM CMDFIL ;STOP TRYING TO USE IT, AND COMMIT SUICIDE IF A ^C
|
||
SKIPE CTLCF ;IS STILL LEFT FROM WHEN IT WAS SPECIFIED.
|
||
JRST QUIT
|
||
JRST TTILIN ;ELSE, READ FROM TTY.
|
||
|
||
SUBTTL ITS - FILESPEC READER
|
||
|
||
;READ FILE SPEC.
|
||
|
||
IFN ITS,[
|
||
|
||
RFILE: SETZM $F6FN2(FP) ;DEFAULT FN2 UP TO CALLER.
|
||
RFILSW: SETZ CS,
|
||
RFNAME: MOVE BP,[440600,,0]
|
||
MOVEI 0,6 ;SET UP TO READ IN A FILENAME.
|
||
MOVEM 0,RFILC
|
||
SETZ 0,
|
||
RFLOOP: CALL TTICHU ;READ A CHAR. UPPER CASE
|
||
CAIN C,^Q
|
||
JRST RFCTQ ;^Q QUOTES NEXT CHAR.
|
||
CAIE C,"=
|
||
CAIN C,",
|
||
JRST RFSPAC ;COMMAS TERMINATE SPEC.
|
||
CAIE C,"_
|
||
CAIG C,"
|
||
JRST RFSPAC ;THESE ALSO.
|
||
CAIN C,":
|
||
JRST RFCOL ;COLON SETS DEV.
|
||
CAIN C,";
|
||
JRST RFSEM ;SEMI SETS SNAME.
|
||
CAIN C,"/
|
||
JRST RFSPAC ;SLASH ENDS NAME.
|
||
JRST RFNORM ;ALL OTHER CHARS.
|
||
|
||
RFCTQ: CALL TTICHU ;READ UPPER CASE CHAR
|
||
CAIGE C,40
|
||
JRST RFSPAC ;DON'T TRY TO QUOTE A CONTROL CHARACTER.
|
||
RFNORM: MOVEI C,-40(C) ;CONV. TO SIXBIT.
|
||
SOSL RFILC ;PUT IN NAME IF ROOM LEFT.
|
||
IDPB C,BP
|
||
JRST RFLOOP
|
||
|
||
RFXCTB: MOVEM 0,$F6FN1(FP)
|
||
MOVEM 0,$F6FN2(FP)
|
||
MOVEM 0,$F6DEV(FP)
|
||
MOVEM 0,$F6DIR(FP)
|
||
SKIPA
|
||
|
||
RFCOL: SKIPE 0
|
||
MOVEM 0,$F6DEV(FP) ;SET DEVICE FIELD.
|
||
JRST RFNAME
|
||
|
||
RFSEM: SKIPE 0
|
||
MOVEM 0,$F6DIR(FP)
|
||
JRST RFNAME
|
||
|
||
RFSPAC: JUMPE 0,RFSPA0 ;IF NAME WAS READ,
|
||
XCT RFXCTB(CS) ;STORE IT,
|
||
AOJ CS, ;INCR. STORING POS.
|
||
TLNN FR,FLINDR
|
||
JRST RFSPA0
|
||
CAIN CS,2
|
||
RET
|
||
RFSPA0: CAIN C,^X ;AS 1ST NAME AVOIDS SETTING IT, ALLOWS FN2 TO BE SET.
|
||
JRST [ JUMPN CS,RFNAME
|
||
AOJA CS,RFNAME]
|
||
CAIN C,40
|
||
JRST RFNAME ;SPACE -- GET ANOTHER NAME.
|
||
CAIN C,^C
|
||
MOVEI C,^M
|
||
CAIE C,"/
|
||
RET ;NOT SLASH, RETURN.
|
||
CALL RDSW ; AHA, READ SWITCH.
|
||
JRST RFNAME ; THEN RETURN TO LOOP.
|
||
] ;IFN ITS
|
||
|
||
SUBTTL TNX - FILESPEC READER
|
||
|
||
IFN TNX,[
|
||
|
||
RFILE: SETZM $FVERS(FP) ; DEFAULT VERSION UP TO CALLER
|
||
RFILSW: SETZM RDFLG ; SAY HAVEN'T READ FILESPEC YET.
|
||
RFILE2: CALL TTICHR ; READ CHAR FROM LINE
|
||
CAIE C,^J
|
||
CAIN C,^M ; EOL?
|
||
JRST RFILE8 ; YES, EXIT
|
||
CAIE C,^C
|
||
CAIN C,0
|
||
JRST RFILE8
|
||
CAIN C,", ; COMMA?
|
||
JRST RFILE8 ; ALSO EXIT
|
||
IFE TWX,CAIE C,"_ ; Not on Twenex, thank you
|
||
CAIN C,"= ; EITHER OF THESE ARE VALID OUTPUT FILSPEC INDICATORS.
|
||
JRST RFILE8
|
||
CAIN C,"/ ; START OF SWITCH?
|
||
JRST [ CALL RDSW ; YES, READ IT & CONTINUE.
|
||
JRST RFILE2]
|
||
CAIE C,^I
|
||
CAIN C,40
|
||
JRST RFILE2 ; FLUSH WHITESPACE
|
||
|
||
; HERE HAVE FIRST CHAR OF FILENAME...
|
||
MOVE W2,[440700,,RFLBUF]
|
||
RFILE3: IDPB C,W2
|
||
CALL TTICHR ;ACCUMULATE CHARACTERS VALID IN FILE NAME
|
||
CAIE C,^J
|
||
CAIN C,^M
|
||
JRST RFILE4
|
||
CAIE C,^C
|
||
CAIN C,0
|
||
JRST RFILE4
|
||
CAIE C,",
|
||
CAIN C,"/
|
||
JRST RFILE4
|
||
IFE TWX,CAIE C,"_ ; Not on Twenex, thank you
|
||
CAIN C,"=
|
||
JRST RFILE4
|
||
CAIE C,^I
|
||
CAIN C,40
|
||
JRST RFILE4
|
||
CAIE C,^V
|
||
JRST RFILE3
|
||
IDPB C,W2
|
||
CALL TTICHR
|
||
JRST RFILE3
|
||
|
||
RFILE4: MOVEI A,0 ;MARK END OF ASCIZ STRING
|
||
IDPB A,W2
|
||
MOVE W2,TTIPNT
|
||
DBP7J W2, ; SKIP BACK ONE
|
||
MOVEM W2,TTIPNT
|
||
AOS TTICNT
|
||
RFILE5: SKIPE RDFLG ; ALREADY READ A FILESPEC?
|
||
JRST RFILE8 ; YES, DON'T READ THIS SPEC YET...
|
||
HRROI W2,RFLBUF
|
||
SYSCAL GTJFN,[[GJ%OFG+GJ%SHT] ? W2][$FJFN(FP) ? W2]
|
||
JRST RFILE9 ; SOME SORT OF SYNTAX ERROR
|
||
;HERE COULD COMPARE W2 AGAINST TTIPNT IN CASE EXTRA GARBAGE IN FILENAME
|
||
CALL JFNSTB ; STORE FILENAME SPEC IN FB
|
||
SYSCAL RLJFN,[$FJFN(FP)]
|
||
JFCL
|
||
SETZM $FJFN(FP)
|
||
|
||
; FILESPEC READ...
|
||
SETOM RDFLG ; SAY SO, SO IF SEE ANOTHER WILL STOP
|
||
JRST RFILE2
|
||
|
||
RFILE8: RET ; RETURN
|
||
|
||
RFILE9: HRROI W1,RFLBUF
|
||
PSOUT
|
||
MOUTI CHTTO,^I
|
||
CALL TYLERR ;TYPE LAST ERROR
|
||
JRST ERRFIN
|
||
|
||
.SCALAR RDFLG ; -1 WHEN FILESPEC READ
|
||
.VECTOR RFLBUF(20.) ;BUFFER FOR READING FILENAME INTO FOR GTJFN
|
||
] ;IFN TNX
|
||
|
||
SUBTTL SWITCH PROCESSING
|
||
|
||
;FOR SWITCH "A, SET OR CLEAR BIT D ACCORDING TO B.
|
||
DEFINE SWITCH A,B,D
|
||
CAIN C,"A
|
||
HRR!B!I BP,D
|
||
TERMIN
|
||
|
||
RDSW: CALL TTICHU ; READ A SWITCH (SHOULD BE NEXT CHAR).
|
||
SETZ BP,
|
||
SWITCH !,O,FLOVRD ;/! - FORCE COMPARISON BETWEEN A FILE AND ITSELF
|
||
SWITCH @,O,FLINDR ;/@ - GO INDIRECT THROUGH A COMPARISON FILE
|
||
;TO FIND THE FILE NAMES TO USE.
|
||
CAIN C,"# ;/# - Binary compare (= FILCOM /W)
|
||
JRST [ SETOM FVBIN ; Set memory flag (sigh)
|
||
RET]
|
||
CAIN C,"$ ;/$ - SBLK or CSAVE compare
|
||
JRST [ SETOM FSBIN
|
||
RET]
|
||
CAIN C,"Q ;/Q - Like FILCOM /Q, gives error
|
||
JRST [ SETOM QFLAG ; if files are different
|
||
RET] ; (for BATCON, mostly)
|
||
SWITCH B,O,FLALL ;/B - DON'T IGNORE BLANK LINES.
|
||
SWITCH C,O,FLCMNT ;/C - IGNORE COMMENTS.
|
||
CAIN C,"D
|
||
PJRST SWDISN ;/D - DISOWN SELF.
|
||
SWITCH E,O,FLENDL ;/E - PRINT THE MATCHING LINES THAT END THE
|
||
;RUN OF DIFFERENCES.
|
||
SWITCH F,O,FLFLAG+FLALL+FLMERG ;/F - GEN COPY OF FILE 2 WITH CHANGED LINES
|
||
;FLAGGED WITH VERTICAL BARS.
|
||
SWITCH I,O,FLMERG+FLISWT+FLALL ;/I - /M, BUT ANSWER ALL QUESTIONS WITH "I".
|
||
SWITCH K,O,FLCASE ;/K - IGNORE ALPHABETIC CASE DIFFERENCES
|
||
SWITCH L,O,FLLABL ;/L - EACH HEADER LINE MENTIONS PREVIOUS LABEL.
|
||
SWITCH M,O,FLALL+FLMERG ;/M - MERGE FILES.
|
||
SWITCH S,O,FLSPAC ;/S - IGNORE SPACES.
|
||
SWITCH W,O,FLFNUM ;/W - PRINT FILE # ON EACH LINE.
|
||
SWITCH X,O,FLXCTF ;/X - EXECUTE COMMANDS FROM FILE
|
||
SWITCH Y,O,FLXLBL ;/Y - ANY UNINDENTED TEXT IS A LABEL.
|
||
CAIL C,"1 ;DIGIT - SET NUMLIN.
|
||
CAILE C,"9
|
||
CAIA
|
||
JRST [MOVEI C,-"1(C) ;SET NUM. EXTRA LINES TO MATCH
|
||
MOVEM C,NUMLIN ;TO THE DIGIT, -1.
|
||
RET]
|
||
JUMPE BP,ERRSW ;ERROR UNLESS ONE OF ABOVE SWITCHES.
|
||
TLO FR,(BP) ;SET THE FLG.
|
||
RET ;SWITCH DONE, RETURN.
|
||
|
||
SUBTTL ERROR MESSAGES/HANDLING
|
||
|
||
;COME HERE AFTER FAILING INPUT OR OUTPUT OPEN.
|
||
|
||
OPENL:
|
||
IFN ITS,.LOGOUT
|
||
CALL LSTFIL ;PRINT NAME OF LOSING FILE (WHAT FP POINTS TO).
|
||
MOUTI CHTTO,^I
|
||
CALL TYLERR ;TYPE LAST ERROR
|
||
JRST ERRFIN
|
||
|
||
|
||
ERRXTR: JSP T,ERRMSG
|
||
ASCIZ "Extra input files specified"
|
||
|
||
ERRHLP: MOVEI T,[ASCIZ "Can't find help file!"]
|
||
CALL TYPMSG
|
||
; JRST OPENL
|
||
JRST ERRFIN
|
||
|
||
ERRIND: JSP T,ERRMSG
|
||
ASCIZ "Bad format /@ indirect file"
|
||
|
||
ERRIN2: JSP T,ERRMSG
|
||
ASCIZ "Can't use /@ or /X with second input file"
|
||
|
||
ERRIN3: JSP T,ERRMSG
|
||
ASCIZ "Can't use /@ or /X with third input file"
|
||
|
||
ERR3NM: JSP T,ERRMSG
|
||
ASCIZ "Three input files but /M not specified"
|
||
|
||
ERRXCT: JSP T,ERRMSG
|
||
ASCIZ "Recursive /X attempted"
|
||
|
||
ERRARC: JSP T,ERRMSG
|
||
ASCIZ "Can't archive and merge at once"
|
||
|
||
ERRSW: JSP T,ERRMSG
|
||
ASCIZ "Illegal switch"
|
||
|
||
|
||
|
||
ERRMSG: CALL TYPMSG ;FOR SIMPLE ERROR MESSAGES; TYPE & DROP THRU
|
||
|
||
;ALL ERROR MESSAGES COME THROUGH HERE.
|
||
|
||
ERRFIN:
|
||
IFN ITS,.RESET CHTTI, ; FLUSH TTY INPUT BUFFER
|
||
IFN TNX,CFIBF
|
||
SETZM CMDFIL ;STOP READING COMMAND FILE.
|
||
M.CLS CHCMD
|
||
SETZM CTLCF ;DON'T KILL SELF; READ ANOTHER CMD STRING INSTEAD.
|
||
|
||
;COMMAND TERMINATION, SUCCESSFUL OR NOT, ALWAYS COMES THROUGH HERE.
|
||
|
||
RELDEV: M.CLS CHIN1
|
||
M.CLS CHIN2
|
||
M.CLS CHMRG
|
||
IFN ITS,[
|
||
MOVE W1,TTYSTS
|
||
TLNE W1,%TSMOR
|
||
SYSCAL TTYSET,[MOVEI CHOUT ? TTYST1 ? TTYST2 ? W1]
|
||
JFCL
|
||
]
|
||
M.CLS CHOUT
|
||
SKIPE CMDFIL ;EXECUTING A FILE => READ MORE FROM IT.
|
||
JRST RELDE1
|
||
IFN ITS,.LOGOUT ;CAN'T GET ANOTHER CMD IF DISOWNED.
|
||
SKIPE CTLCF ;EXIT IF USER GAVE ^C.
|
||
JRST QUITX
|
||
|
||
RELDE1: CALL CRLF
|
||
JRST RESTRT ;ELSE, GET NEW CMD.
|
||
|
||
|
||
;ROUTINES FOR OUTPUTING ERROR MESSAGES
|
||
|
||
TYPMSG:
|
||
IFN ITS,.LOGOUT ;CAN'T PRINT MSG WITHOUT TTY.
|
||
CALL CRLF ;OUTPUT A CARRIAGE RETURN
|
||
TYPMS0: HRLI T,440700 ;THIS IS POINTER FOR ERROR MESSAGE
|
||
TYPMS1: ILDB C,T
|
||
JUMPE C,CPOPJ
|
||
CALL TYO
|
||
JRST TYPMS1
|
||
|
||
; TYPM - FOR USE WITH "TYPE" MACRO. STACK HAS ADDR OF ASCIZ STR.
|
||
TYPM: PUSH P,C
|
||
PUSH P,T
|
||
MOVE T,-2(P) ; GET ADDR OF ASCIZ
|
||
CALL TYPMSG ; OUTPUT
|
||
POP P,T
|
||
POP P,C
|
||
SUB P,[1,,1] ; FLUSH ARG
|
||
RET
|
||
|
||
;OUTPUT 6BIT WD IN 0 TO TTY.
|
||
TTOSIX: MOVE BP,0
|
||
TTOSI0: SETZ TT,
|
||
ROTC TT,6 ;GET NEXT CHAR.
|
||
MOVEI TT," (TT) ;CONV. 6BIT TO ASCII.
|
||
MOUTC CHTTO,TT
|
||
JUMPN BP,TTOSI0
|
||
RET
|
||
|
||
; OUTPUT DECIMAL # IN 0 TO TTY.
|
||
|
||
TTODEC: IDIVI 0,10.
|
||
HRLM W1,(P)
|
||
SKIPE 0
|
||
CALL TTODEC
|
||
HLRZ W1,(P)
|
||
ADDI W1,"0
|
||
MOUTC CHTTO,W1
|
||
RET
|
||
|
||
TYO: MOUTC CHTTO,C
|
||
RET
|
||
|
||
CRLF: MOUTI CHTTO,^M
|
||
MOUTI CHTTO,^J
|
||
RET
|
||
|
||
SUBTTL Auxiliary ITS Routines
|
||
|
||
IFN ITS,[
|
||
|
||
; GETJCL - Get JCL input
|
||
; W1/ <.OPTION var>
|
||
|
||
GETJCL: SETZM TTIBUF
|
||
TLNE W1,OPTCMD ; Don't do the .BREAK unless superior says so.
|
||
.BREAK 12,[5,,TTIBUF]
|
||
SKIPN TTIBUF
|
||
RET
|
||
MOVE W1,[440700,,TTIBUF] ; If have command string from superior,
|
||
MOVEM W1,TTIPNT ; set up to read from it.
|
||
SETZ CS,
|
||
GTJCL2: ILDB C,W1 ; Count chars. in it.
|
||
CAIE C,^M
|
||
CAIN C,0
|
||
CAIA
|
||
AOJA CS,GTJCL2
|
||
MOVEM CS,TTICNT ; Save num. chars to read.
|
||
AOS (P) ; Success return.
|
||
RET
|
||
|
||
|
||
; TYLERR - Type last error
|
||
|
||
TYLERR: .SUSET [.RBCHN,,C]
|
||
SYSCAL STATUS,[C ? MOVEM ERRFIL+2]
|
||
ERRHLT
|
||
.OPEN CHERR,ERRFIL
|
||
ERRHLT
|
||
TYLER2: M.BIN CHERR,C
|
||
CAIN C,^M
|
||
RET
|
||
MOUTC CHTTO,C
|
||
JRST TYLER2
|
||
|
||
ERRFIL: SIXBIT/ ERR/
|
||
3 ? 0
|
||
|
||
|
||
; LSTFIL - Print name of current file on LST ior TTY.
|
||
|
||
LSTFIL: MOVE 0,$F6DEV(FP)
|
||
CAMN 0,FSDSK
|
||
JRST LSTFI1
|
||
CALL TTOSIX ; Print dev if not DSK.
|
||
MOUTI CHTTO,":
|
||
LSTFI1: MOVE 0,$F6DIR(FP) ; Print sname
|
||
CAMN 0,DEFDIR ; If different from user's.
|
||
JRST LSTFI2
|
||
CALL TTOSIX
|
||
MOUTI CHTTO,73 ; ";
|
||
LSTFI2: MOVE 0,$F6FN1(FP)
|
||
CALL TTOSIX ; Print 1st name.
|
||
MOUTI CHTTO,40 ; Space
|
||
MOVE 0,$F6FN2(FP)
|
||
JRST TTOSIX ; , 2nd name.
|
||
|
||
|
||
SWDISN: .OPEN CHTTI,[SIXBIT/ NUL/]
|
||
ERRHLT
|
||
.OPEN CHTTO,[SIXBIT/ !NUL/]
|
||
ERRHLT
|
||
.VALUE [ASCIZ/:DISOWN :VK /] ; Give back tty.
|
||
RET
|
||
|
||
; TYI - Read char from TTY, return in C
|
||
|
||
TYI: .IOT CHTTI,C
|
||
RET
|
||
|
||
; OPNRDW - Open filblk for reading, word mode
|
||
; OPNRDA - Open filblk for reading, ascii mode
|
||
; FP/ <ch>,,<fb addr>
|
||
; Skip returns if opened.
|
||
|
||
OPNRDW: SAVE W1
|
||
HRLZI W1,.UII
|
||
JRST OPNRD2
|
||
OPNRDA: SAVE W1
|
||
HRLZI W1,.UAI ; Actually 0
|
||
OPNRD2: HLR W1,FP
|
||
SYSCAL OPEN,[W1 ? $F6DEV(FP) ? $F6FN1(FP) ? $F6FN2(FP) ? $F6DIR(FP)]
|
||
CAIA
|
||
AOS -1(P)
|
||
REST W1
|
||
RET
|
||
|
||
; RENMLO - Rename listing file
|
||
; W1/ <ch>
|
||
|
||
RENMLO: SYSCAL RENMWO,[W1 ? LSTFB+$FNAME ? LSTFB+$FEXT]
|
||
JFCL
|
||
RET
|
||
|
||
QUIT: .BREAK 16,140000 ; Die and echo ":KILL"
|
||
QUITX: .BREAK 16,160000 ; Die, announce "Finished" if not current
|
||
|
||
OPNHLP: SYSCAL OPEN,[MOVEI CHIN1 ? ['DSK,,]
|
||
['SRCCOM] ? [SIXBIT/>/] ? [SIXBIT/INFO/]]
|
||
RET
|
||
AOS (P)
|
||
RET
|
||
] ;IFN ITS
|
||
|
||
SUBTTL TNX - Auxiliary Routines
|
||
|
||
IFN TNX,[
|
||
|
||
; SEE20X - See if running under 20x or 10x
|
||
|
||
.SCALAR FLG20X ; -1 if 20x, 0 if 10x.
|
||
SEE20X: SETZM FLG20X
|
||
SYSCAL SYSGT,[['LOADTB]][B ? B]
|
||
SKIPN B ; If LOADTB is not defined
|
||
SETOM FLG20X ; It must be a twenex
|
||
RET
|
||
|
||
QUIT:
|
||
QUITX:
|
||
|
||
; Tell an MIT EXEC to flush this fork, like .BREAK 16,160000 on ITS
|
||
; This PRARG% code should be meaningless to (and ignored by) non-MIT EXECs.
|
||
|
||
IFDEF PRARG%,{ ; I don't know if PRARG% exists on 10X or not
|
||
|
||
IFNDEF .PRKIL, .PRKIL==:2
|
||
|
||
MOVE 1,[.PRAST,,.FHSLF]
|
||
MOVEI 2,[.PRKIL,,0]
|
||
MOVEI 3,1
|
||
PRARG% ; Tell the EXEC that we have a death wish
|
||
ERJMP .+1 ; Oh well
|
||
|
||
};IFNDEF PRARG%
|
||
|
||
HALTF
|
||
JRST RESTRT
|
||
|
||
; OPNWR - Open filblk for writing, ascii mode
|
||
; FP/ <ch>,,<fb addr>
|
||
|
||
OPNWR: SAVE W1
|
||
SAVE W2
|
||
MOVE W2,[070000,,OF%WR] ; Mode for char write
|
||
CALL GETJFO ; Get output jfn
|
||
JRST OPNRD8
|
||
JRST OPNRD5 ; Rest is same as OPNRD.
|
||
|
||
; OPNRDW - Open filblk for reading, word mode
|
||
; OPNRDA - Open filblk for reading, ascii mode
|
||
; FP/ <ch>,,<fb addr>
|
||
; Skip returns if opened.
|
||
|
||
OPNRDW: SAVE W1
|
||
SAVE W2
|
||
MOVE W2,[440000,,OF%RD] ; Mode for full-wd
|
||
JRST OPNRD2
|
||
OPNRDA: SAVE W1
|
||
SAVE W2
|
||
MOVE W2,[070000,,OF%RD] ; Mode for char
|
||
OPNRD2: CALL GETJFI ; Get input jfn
|
||
JRST OPNRD8 ; Failed
|
||
OPNRD5: SYSCAL OPENF,[$FJFN(FP) ? W2]
|
||
JRST [ SYSCAL CLOSF,[$FJFN(FP)]
|
||
JFCL
|
||
JRST OPNRD8]
|
||
PUSH P,$FJFN(FP)
|
||
HLRZ W1,FP
|
||
POP P,JFNCHS(W1)
|
||
CALL JFNSTB
|
||
AOS -2(P)
|
||
OPNRD8: REST W2
|
||
REST W1
|
||
RET
|
||
|
||
OPNHLP: PUSH P,R1
|
||
PUSH P,R2
|
||
MOVSI R1,(GJ%OLD+GJ%SHT)
|
||
HRROI R2,[HLPFIL] ; Filename defined as macro
|
||
GTJFN
|
||
JRST OPNHL7 ; Failed.
|
||
HRRZS R1
|
||
PUSH P,R1
|
||
MOVE B,[070000,,OF%RD]
|
||
OPENF
|
||
JRST [ POP P,R1
|
||
CLOSF
|
||
JFCL
|
||
JRST OPNHL7]
|
||
POP P,R1
|
||
MOVEM R1,JFNCHS+CHIN1
|
||
AOS -2(P)
|
||
OPNHL7: POP P,R2
|
||
POP P,R1
|
||
POPJ P,
|
||
|
||
; RENMLO - Rename listing file
|
||
; For moment, we don't hack temp filename, so this is a no-op.
|
||
|
||
RENMLO: RET
|
||
|
||
TYI: SAVE R1
|
||
TYI2: PBIN
|
||
CAIN R1,37
|
||
MOVEI R1,^M
|
||
CAIN R1,^J ; Actually for 20x only
|
||
JRST TYI2
|
||
MOVE C,R1
|
||
REST R1
|
||
RET
|
||
|
||
SWDISN: TYPE "Cannot disown on this losing system; continuing."
|
||
RET
|
||
|
||
LSTFIL: PJRST TYPFB
|
||
|
||
; TYLERR - Type last error
|
||
|
||
TYLERR: SKIPA A,[-1]
|
||
TERSTR: MOVE A,ERRCOD
|
||
HRLI A,.FHSLF
|
||
SYSCAL ERSTR,[[-1,,ERSTRB] ? A ? [-LERSTR,,]][A ? B ? B]
|
||
JRST TERST7 ; undefined err #?
|
||
HALT ; destination bad?
|
||
SETZ B,
|
||
IDPB B,A ; Ensure ASCIZ.
|
||
MOVEI T,ERSTRB
|
||
PJRST TYPMSG
|
||
; TYPR ERSTRB
|
||
; POPJ P,
|
||
TERST7: TYPE "Unknown error"
|
||
POPJ P,
|
||
|
||
LERSTR==80.
|
||
.VECTOR ERSTRB(<LERSTR+4>/5)
|
||
|
||
|
||
; RCHST - Set up filename string of input file as part of header output.
|
||
; Also set length vars.
|
||
|
||
RCHST: MOVEI A,CHIN1(FR) ; What a crock.
|
||
MOVE A,JFNCHS(A) ; Get jfn for file
|
||
PUSH P,A
|
||
MOVE B,RCHSTP(FR) ; Get bp to dest buffer
|
||
SYSCAL JFNS,[B ? A ? [111110,,1]][B]
|
||
SETZ A,
|
||
IDPB A,B ; Ensure asciz
|
||
POP P,A ; Get JFN again
|
||
SYSCAL SFPTR,[A ? [-1]][A] ; Set pointer to EOF
|
||
JFCL
|
||
SYSCAL RFPTR,[A][A ? B] ; Get # words to read
|
||
JFCL
|
||
MOVEM B,GWORDL(FR) ; Set length of file
|
||
MOVEM B,GWORDC(FR) ; Also # of words left to read
|
||
SYSCAL SFPTR,[A ? [0]] ; Point back to beg of file
|
||
JFCL
|
||
RET
|
||
|
||
] ;IFN TNX
|
||
|
||
SUBTTL TNX JCL reading
|
||
|
||
; This routine is taken from MIDAS and so has some CCL hackery that
|
||
; currently is commented out, but at some future time might prove useful.
|
||
IFN TNX,[
|
||
|
||
; GETJCL - Read "JCL" - RSCAN buffer or nnnMID.TMP file (from CCL)
|
||
|
||
GETJCL: SETZM TTIPNT
|
||
IFN 0,[
|
||
SKIPE CCLFLG ; Started at CCL location?
|
||
JRST JCLIN5 ; Yep, go snarf stuff specially.
|
||
]
|
||
SKIPN FLG20X ; Is this Tenex?
|
||
JRST [ MOVEI R1,.PRIIN ; Yes
|
||
BKJFN ; see what previous character was
|
||
RET ; *Gasp*
|
||
PBIN
|
||
CAIE R1,^_ ; Tenex newline?
|
||
SETOM TTIPNT ; No, set flag saying "TTY but no prompt"
|
||
RET] ; and skip the Twenex hackery below
|
||
SETZ R1, ; If not, check RSCAN.
|
||
RSCAN ; See if have anything in RSCAN buffer.
|
||
RET ; Huh? Shouldn't happen, but ignore it.
|
||
JUMPLE R1,APOPJ ; Also return if char cnt says nothing there.
|
||
MOVNI R3,(R1) ; Aha, set up cnt for SIN
|
||
HRROI R2,TTIBUF
|
||
MOVEI R1,.PRIIN ; Now ready for business...
|
||
SIN
|
||
LDB R1,R2 ; Now examine wages thereof
|
||
CAIE R1,^J ; Last char LF?
|
||
JRST [ MOVEI R1,^J
|
||
IDPB R1,R2 ; If not, make it so.
|
||
JRST .+1]
|
||
|
||
;;; Don't try to change the terminating character from LF to CR without
|
||
;;; giving it careful thought. GTJFN likes the filename to be terminated
|
||
;;; with LF, and can be quite intransigent in its behavior.
|
||
;;; Instead, make the other scan routines accept LF. --WBA
|
||
|
||
SETZ R1,
|
||
IDPB R1,R2 ; Must also ensure ASCIZ.
|
||
MOVE B,[440700,,TTIBUF] ; If the rescan line starts with "RUN ", skip that.
|
||
IRPC X,,[RUN ]
|
||
ILDB A,B
|
||
TRZ A,40 ; Convert to upper case
|
||
CAIE A,"X
|
||
JRST JCLIN4
|
||
TERMIN
|
||
CAIA
|
||
JCLIN4: MOVE B,[440700,,TTIBUF] ; Now flush the name of the file we were run from.
|
||
ILDB A,B
|
||
CAILE A,40
|
||
JRST .-2 ; Flush until random ctl seen (space, ^M)
|
||
CAIE A,40 ; If it wasn't a space,
|
||
RET ; then forget about the whole thing.
|
||
JCLIN3: MOVE C,B ; Now flush spaces. Save last ptr for chars.
|
||
ILDB A,B
|
||
CAIN A,40
|
||
JRST JCLIN3
|
||
CAIN A,^J ; And is first non-space something besides LF?
|
||
RET ; Bah, there wasn't anything in the JCL!!
|
||
MOVEM C,TTIPNT ; Else save ptr to start of real goods.
|
||
|
||
MOVE W1,C
|
||
SETZ CS,
|
||
GTJCL2: ILDB C,W1 ; Count chars. in it.
|
||
JUMPE C,GTJCL3 ; Null? (Shouldn't happen, but...)
|
||
CAIE C,^M ; CR or LF?
|
||
CAIN C,^J
|
||
CAIA ; Yes, must convert to null
|
||
AOJA CS,GTJCL2 ; Otherwise just count it
|
||
SETZ C,
|
||
DPB C,W1
|
||
GTJCL3: MOVEM CS,TTICNT ; Save num. chars to read.
|
||
AOS (P) ; Success return.
|
||
RET
|
||
|
||
IFN 0,[
|
||
; TNX snarf of CCL file. No such thing as tmpcor, so just
|
||
; look for real file with appropriate name.
|
||
JCLIN5: SETZM CCLFLG ; Want 0 in case abort out, will reset if win.
|
||
GJINF ; Get job # in R3
|
||
HRROI R1,CMBUF ; Use CMBUF to form filename string.
|
||
MOVEI R2,(R3)
|
||
MOVE R3,[NO%LFL+NO%ZRO+<3_18.>+10.]
|
||
NOUT ; ship out job num in 3 digits, radix 10.
|
||
HALT
|
||
HRROI R2,[ASCIZ /MID.TMP/]
|
||
SETZ R3,
|
||
SOUT ; Flesh out rest of filename string.
|
||
SETZ R2, ; Make sure it's ASCIZ.
|
||
BOUT
|
||
MOVE R1,[GJ%OLD+GJ%SHT] ; Use short-form GTJFN
|
||
HRROI R2,CMBUF ; and gobble name from CMBUF.
|
||
GTJFN
|
||
RET ; If failed, forget it.
|
||
MOVE R2,[070000,,OF%RD] ; Read 7-bit bytes
|
||
OPENF
|
||
RET ; Bah
|
||
HRROI R2,CMBUF ; Gobble stuff up.
|
||
MOVEI R3,CMBFL*5 ; Read until buffer full,
|
||
MOVEI R4,^J ; or LF seen.
|
||
SIN
|
||
JUMPLE R3,APOPJ ; Forget it if too big for buffer!!
|
||
|
||
MOVE R2,[440700,,CMBUF] ; Aha, we've got something, so set
|
||
MOVEM R2,CMPTR ; pointer to slurped stuff.
|
||
SETOM CCLFLG
|
||
HRROI R2,UTIBUF ; Slurp rest into larger buffer,
|
||
MOVNI R3,UTIBFL*5 ; using count only.
|
||
SIN
|
||
JUMPGE R3,APOPJ ; Refuse to hack grossly large file.
|
||
ADDI R3,UTIBFL*5
|
||
JUMPLE R3,APOPJ ; if nothing read, need write nothing out.
|
||
HRLI R1,(CO%NRJ) ; Don't release JFN,
|
||
CLOSF ; but stop reading from file.
|
||
RET
|
||
MOVE R2,[070000,,OF%WR] ; Now try to hack write access.
|
||
OPENF
|
||
RET
|
||
MOVE R2,R1 ; Source becomes destination...
|
||
HRROI R1,UTIBUF ; and UTIBUF becomes source,
|
||
MOVNS R3 ; for just as many bytes as were read.
|
||
SOUT
|
||
MOVEI R1,(R2) ; done, now just close file.
|
||
CLOSF ; (this time, release JFN).
|
||
RET
|
||
SETOM CCLMOR ; say that more CCL remains.
|
||
RET
|
||
] ;IFN 0 FOR NOW
|
||
|
||
] ;IFN TNX
|
||
|
||
SUBTTL TENEX misc. Filename Routines, FS string storage
|
||
|
||
IFN TNX,[ .SEE FSDSK ; Part of this page is NOT conditionalized!!
|
||
|
||
; To handle filenames of ASCIZ strings instead of SIXBIT words, each
|
||
; word has instead a byte pointer to an ASCIZ string. For purposes of
|
||
; easy comparison, all of these bp's point into FNBUF, and a routine
|
||
; (FNCHK) is provided which checks a just-stored string and returns a bp
|
||
; to either this string, if unique, or to a previously stored string if
|
||
; it is the same as the one just stored (which is then flushed). Thus
|
||
; strings can be compared for equality simply by a comparison of their
|
||
; byte pointers. While not necessary, strings are stored beginning on
|
||
; word boundaries for easier hacking.
|
||
|
||
; <# files>*<avg # strings/file>*<avg # words/string>+<# wds for constants>
|
||
IFNDEF MAXIND,MAXIND==10 ; # files
|
||
LFNBUF==<MAXIND+5>*5*3+20 ; Enough to hold strings for all output files,
|
||
; all translated files, and all .insrt files encountered.
|
||
; Later a GC'er can be hacked up so that of the latter only
|
||
; enough for the max .insrt level need be allocated.
|
||
|
||
FNBUF: BLOCK LFNBUF
|
||
|
||
; Macro to easily define constant strings for comparison purposes
|
||
DEFINE DEFSTR &STR&
|
||
440700,,%%FNLC
|
||
%%LSAV==.
|
||
LOC %%FNLC
|
||
ASCIZ STR
|
||
%%FNLC==.
|
||
LOC %%LSAV
|
||
TERMIN
|
||
%%FNLC==FNBUF
|
||
] ; IFN TNX!!!
|
||
|
||
; If not assembling for TENEX, the following strings become
|
||
; simple SIXBIT values. This makes it possible to write simple
|
||
; code to work for both TENEX and non-TENEX without messy conditionals.
|
||
|
||
IFE TNX,[
|
||
DEFINE DEFSTR &X&
|
||
.1STWD SIXBIT X!TERMIN
|
||
]
|
||
|
||
; This stuff defines various BP's into FNBUF to
|
||
; use for comparison purposes later.
|
||
FSDSK: DEFSTR /DSK/
|
||
FSTTY: DEFSTR /TTY/
|
||
FSNUL: DEFSTR /NUL/
|
||
FSCMP: DEFSTR /COMPARE/
|
||
FSCMPA: DEFSTR /CMPARC/
|
||
FSFLGD: DEFSTR /FLAGGD/
|
||
|
||
IFN ITS, FSDMF2:DEFSTR />/ ; default merge FN2
|
||
IFN TNX, FSDMF2:DEFSTR //
|
||
IFN ITS, FVLOW: DEFSTR /</
|
||
IFN TNX, FVLOW: .GJLEG ; -2 for lowest version
|
||
|
||
|
||
IFN TNX,[
|
||
FNBBP: 440700,,FNBUF ; Points to beg of FNBUF (hook for dynamic alloc)
|
||
FNBEP: FNBUF+LFNBUF-1 ; Points to last wd in FNBUF (address, not BP)
|
||
FNBWP: 440700,,%%FNLC ; Write Pointer into FNBUF.
|
||
FNBLWP: 440700,,%%FNLC ; Last Write Pointer, points to beg of string being stored
|
||
EXPUNG %%FNLC
|
||
|
||
; NOTE - provided MIDAS never restarts, no initialization is necessary to
|
||
; start using FNCHK. (Unless of course FNBUF is dynamically allocated someday)
|
||
|
||
; FNCHK - Check out just-stored filename. Returns BP in A to ASCIZ string,
|
||
; which will be "canonical" for comparison purposes.
|
||
; Clobbers A,B,T,TT,AA
|
||
; FNCHKZ - Makes sure just-writ string is ASCIZ'd out before FNCHK'ing.
|
||
|
||
FNCHKZ: MOVE B,FNBWP ; Get write ptr,
|
||
LDB A,B ; see if last char was 0,
|
||
JUMPE A,FNCHK0 ; if so can skip one clobberage.
|
||
SETZ A,
|
||
IDPB A,B ; zero out bytes,
|
||
FNCHK0: TLNE B,760000 ; until at end of word.
|
||
JRST .-2
|
||
ADD B,[<440700,,1>-<010700,,>] ; bump BP to point canonically at next.
|
||
MOVEM B,FNBWP
|
||
|
||
FNCHK: HRRZ B,FNBWP ; See if write ptr
|
||
CAML B,FNBEP ; has hit end of FNBUF, and
|
||
ETF [ASCIZ /Filename buffer overflow/] ; barf horribly if so.
|
||
MOVE A,FNBBP ; A - bp to start of existing string
|
||
MOVE AA,FNBLWP ; AA - bp to start of new string to store
|
||
FNCHK2: MOVEI T,(A) ; T - current addr being checked, existing str
|
||
MOVEI TT,(AA) ; TT - current addr, new str
|
||
CAIL T,(TT) ; If addrs are same, or overran somehow,
|
||
JRST [ MOVE A,AA ; didn't find any match, accept new string.
|
||
MOVE B,FNBWP
|
||
MOVEM B,FNBLWP ; Set up new last-write-ptr
|
||
POPJ P,]
|
||
FNCHK3: MOVE B,(T)
|
||
CAMN B,(TT) ; Compare strings, full word swoops.
|
||
JRST [ TRNE B,377 ; equal, last char zero?
|
||
AOJA T,[AOJA TT,FNCHK3] ; no, continue for whole string
|
||
; Found it! Flush just-stored string, don't want duplicate.
|
||
MOVEM AA,FNBWP ; Clobber write ptr to previous value.
|
||
POPJ P,]
|
||
; Not equal, move to next string to compare
|
||
MOVEI B,377 ; Check for ASCIZ,
|
||
TDNE B,(T) ; moving to end of current string
|
||
AOJA T,.-1
|
||
HRRI A,1(T) ; and updating BP to point at new string.
|
||
JRST FNCHK2 ; (T gets pointed there too at FNCHK2).
|
||
] ;IFN TNX
|
||
|
||
IFN TNX,[
|
||
|
||
; TYPFB - Type out FB pointed to by F
|
||
|
||
TYPFB: SKIPE B,$FDEV(F) ; First, device name?
|
||
JRST [ PUSHJ P,TYPZ
|
||
MOVEI A,":
|
||
PUSHJ P,TYOERR
|
||
JRST .+1]
|
||
SKIPE B,$FDIR(F) ; Directory?
|
||
JRST [ MOVEI A,"<
|
||
PUSHJ P,TYOERR
|
||
PUSHJ P,TYPZ
|
||
MOVEI A,">
|
||
PUSHJ P,TYOERR
|
||
JRST .+1]
|
||
SKIPE B,$FNAME(F)
|
||
PUSHJ P,TYPZ
|
||
MOVEI A,".
|
||
PUSHJ P,TYOERR
|
||
SKIPE B,$FEXT(F)
|
||
PUSHJ P,TYPZ
|
||
MOVEI A,". ; 20X uses "." to set off version,
|
||
SKIPN FLG20X ; but 10X uses ";".
|
||
MOVEI A,";
|
||
PUSHJ P,TYOERR
|
||
HRRE A,$FVERS(F)
|
||
JUMPL A,[MOVM B,A ; Is possible to have -1, -2, etc.
|
||
MOVEI A,"-
|
||
PUSHJ P,TYOERR
|
||
MOVE A,B
|
||
JRST .+1]
|
||
PUSHJ P,DPNT ; Version # output in decimal.
|
||
SKIPE $FTEMP(F)
|
||
TYPE ";T" ; May be temporary.
|
||
SKIPE B,$FPROT(F)
|
||
JRST [ TYPE ";P"
|
||
PUSHJ P,TYPZ
|
||
JRST .+1]
|
||
SKIPE B,$FACCT(F)
|
||
JRST [ TYPE ";A"
|
||
PUSHJ P,TYPZ
|
||
JRST .+1]
|
||
POPJ P,
|
||
|
||
; Takes BP in B, outputs to TYOERR until zero byte seen.
|
||
TYPZ: CAIA
|
||
PUSHJ P,TYOERR
|
||
ILDB A,B
|
||
JUMPN A,TYPZ+1
|
||
POPJ P,
|
||
|
||
DPNT: MOVE 0,A ; This entry pt for code borrowed from midas
|
||
PJRST TTODEC
|
||
|
||
TYOERR: MOVE C,A ; Ditto.
|
||
PJRST TYO
|
||
] ; IFN TNX
|
||
|
||
IFN TNX,[
|
||
; JFNSTR - Get filename strings for active JFN.
|
||
; A/ active JFN
|
||
; F/ addr of filename block to clobber.
|
||
; JFNSTB - Same, but ignores A and assumes JFN is already stored in block.
|
||
; Clobbers A,C
|
||
|
||
JFNSTB: SKIPA A,$FJFN(F) ; JFNSTB gets the JFN from block itself.
|
||
JFNSTR: MOVEM A,$FJFN(F) ; whereas JFNSTR stores it there...
|
||
MOVSI D,-NJSTRF ; Set up aobjn thru table.
|
||
JFNST2: PUSH P,T
|
||
SYSCAL JFNS,[FNBWP ? $FJFN(F) ? JSTRFX+1(D)][FNBWP]
|
||
POP P,T
|
||
MOVE C,JSTRFX(D) ; Now get index to place it belongs in file block,
|
||
CAIN C,$FVERS ; and check for this, because
|
||
JRST [ MOVE A,FNBLWP ; it wants to be a number, not a string.
|
||
MOVEM A,FNBWP ; Zap write pointer back to forget string,
|
||
PUSHJ P,CVSDEC ; and quickly convert before anything clobbers it.
|
||
JRST JFNST4] ; Skip over the FNCHKZ call.
|
||
|
||
MOVE A,FNBLWP ; Get previous write ptr
|
||
CAMN A,FNBWP ; and compare to make sure something written.
|
||
TDZA A,A ; If nothing, store zero.
|
||
PUSHJ P,FNCHKZ ; Fix up string, and get BP to it.
|
||
JFNST4: ADDI C,(F) ; make it an addr, and
|
||
MOVEM A,(C) ; store BP. (or value, for $FVERS)
|
||
ADDI D,1
|
||
AOBJN D,JFNST2
|
||
POPJ P,
|
||
|
||
; Filblk idx, output format wd for JFNS call
|
||
JSTRFX: $FDEV ? 100000,,
|
||
$FDIR ? 010000,,
|
||
$FNAME ? 001000,,
|
||
$FEXT ? 000100,,
|
||
$FVERS ? 000010,,
|
||
NJSTRF==<.-JSTRFX>/2
|
||
|
||
; CVSDEC - Converts ASCIZ string to decimal, assumes only digits seen, with
|
||
; a possible minus-sign prefix (ie negative # is allowed).
|
||
; A/ BP to ASCIZ
|
||
; Returns value in A, clobbers nothing else.
|
||
|
||
CVSDEC: PUSH P,B
|
||
PUSH P,C
|
||
MOVE C,A
|
||
SETZ A,
|
||
ILDB B,C ; Get 1st char
|
||
JUMPE B,CVSDC9
|
||
CAIN B,"- ; Minus sign?
|
||
JRST [ MOVE A,C ; Yes, parse rest of number
|
||
PUSHJ P,CVSDEC
|
||
MOVNS A ; and negate result.
|
||
JRST CVSDC9]
|
||
CVSDC2: IMULI A,10.
|
||
ADDI A,-"0(B)
|
||
ILDB B,C
|
||
JUMPN B,CVSDC2
|
||
CVSDC9: POP P,C
|
||
POP P,B
|
||
POPJ P,
|
||
|
||
; CVSSIX - Converts ASCIZ string to SIXBIT word.
|
||
; A/ BP to ASCIZ string,
|
||
; Returns SIXBIT word in A. Clobbers nothing else.
|
||
|
||
CVSSIX: PUSH P,B
|
||
PUSH P,C
|
||
PUSH P,D
|
||
MOVE D,A
|
||
SETZ A,
|
||
MOVE B,[440600,,A]
|
||
JRST CVSSX3
|
||
CVSSX2: CAIL C,140
|
||
SUBI C,40 ; Uppercase force
|
||
SUBI C,40 ; cvt to 6bit
|
||
IDPB C,B ; deposit
|
||
TLNN B,770000 ; If BP at end of word,
|
||
JRST CVSSX5 ; leave loop.
|
||
CVSSX3: ILDB C,D
|
||
JUMPN C,CVSSX2
|
||
CVSSX5: POP P,D
|
||
POP P,C
|
||
POP P,B
|
||
POPJ P,
|
||
|
||
] ; IFN TNX
|
||
|
||
IFN TNX,[
|
||
; Get a JFN for current FILBLK (in F) and stick it into $FJFN(F).
|
||
; A should hold flags in LH to use in 1st wd of block.
|
||
; GETJFI - sets usual flags for input
|
||
; GETJFO - sets " " output
|
||
; GETJFN - takes whatever A holds.
|
||
|
||
GETJFO: SKIPA A,[GJ%FOU+GJ%NEW] ; If hacking output, ask for new version.
|
||
GETJFI: MOVSI A,(GJ%OLD) ; If hacking input, file must exist.
|
||
GETJFN: PUSHJ P,TFMAP ; Stick filblk stuff into GTJFN scratch block.
|
||
PUSH P,R1
|
||
PUSH P,R2
|
||
MOVEI R1,GTJBLK
|
||
SETZ R2,
|
||
GTJFN
|
||
JRST [ MOVEM R1,ERRCOD ; failure, save error code.
|
||
JRST GETJF5]
|
||
HRRM R1,$FJFN(F) ; Win, save JFN.
|
||
AOS -2(P)
|
||
GETJF5: POP P,R2 ; Can't return in ACs cuz don't know what R1 etc are,
|
||
POP P,R1 ; and might clobber them here.
|
||
POPJ P,
|
||
.SCALAR ERRCOD
|
||
|
||
; TFMAP - Map Tenex filenames from filblk pointed to by F into
|
||
; standard scratch block for long-form GTJFN.
|
||
; A/ <flags>,,0 ; flags will go into LH of .GJGEN.
|
||
; Clobbers only A.
|
||
|
||
TFMAP: HRR A,$FVERS(F) ; Put version # in RH
|
||
SKIPE $FTEMP(F) ; If asking for temp file,
|
||
TLO A,(GJ%TMP) ; set appropriate flag.
|
||
MOVEM A,GTJBLK+.GJGEN
|
||
IRP FROM,,[$FDEV,$FDIR,$FNAME,$FEXT,$FPROT,$FACCT,$FJFN]TO,,[.GJDEV,.GJDIR,.GJNAM,.GJEXT,.GJPRO,.GJACT,.GJJFN]
|
||
MOVE A,FROM(F)
|
||
MOVEM A,GTJBLK+TO
|
||
TERMIN
|
||
MOVE A,[.NULIO,,.NULIO]
|
||
MOVEM A,GTJBLK+.GJSRC ; Don't hack I/O in gtjfn.
|
||
POPJ P,
|
||
|
||
.VECTOR GTJBLK(10.) ; Need exactly this many wds for non-extended long call
|
||
] ;IFN TNX
|
||
|
||
SUBTTL TNX - SUPPORT FOR I/O MACROS
|
||
|
||
IFN TNX,[
|
||
; TAKES -1(P)/ <JFN>, (P)/ <CHAR> AND OUTPUTS
|
||
TOUTC: EXCH R1,-1(P) ; GET JFN
|
||
EXCH R2,(P) ; AND CHAR
|
||
BOUT ; OUT IT GOES.
|
||
REST R2 ; RESTORE ACS AND RETURN
|
||
REST R1
|
||
RET
|
||
|
||
; TINC - TAKES -1(P)/ <JFN>, (P)/ <LOC> AND INPUTS FROM CHAN TO LOC
|
||
|
||
TINC: EXCH R1,-1(P) ; GET JFN
|
||
PUSH P,R2
|
||
BIN
|
||
ERJMP [HRROI R2,^C ; EOF (20X ONLY)
|
||
JRST .+1]
|
||
MOVEM R2,@-1(P) ; STORE BYTE IN DESIRED LOC
|
||
POP P,R2
|
||
SUB P,[1,,1] ; FLUSH LOC FROM STACK
|
||
POP P,R1
|
||
RET
|
||
|
||
; TINS - INPUT STRING
|
||
; TAKES T/ ADDR--> <JFN ADDR> ? <BP ADDR> ? <CNT ADDR>
|
||
|
||
TINS: SAVE R1
|
||
SAVE R2
|
||
SAVE R3
|
||
MOVE R1,@(T) ; GET JFN
|
||
MOVE R2,@1(T) ; AND BP
|
||
MOVN R3,@2(T) ; AND -COUNT
|
||
SIN
|
||
ERJMP .+1 ; ASSUME EOF AND PTRS UPDATED PROPERLY.
|
||
; THIS ONLY WINS ON 20X!
|
||
MOVNM R3,@2(T) ; RESTORE NEW CNT
|
||
MOVEM R2,@1(T) ; AND NEW BP
|
||
REST R3
|
||
REST R2
|
||
REST R1
|
||
RET
|
||
] ;IFN TNX
|
||
|
||
PATCH: BLOCK 100
|
||
|
||
CONSTA ;ITS
|
||
|
||
BEGP:: ;BEGINNING OF STORAGE ZEROED AT INIT.
|
||
JUNK: 0
|
||
PPSET: BLOCK LPDL ;PUSH DOWN LIST STORAGE
|
||
BLOCK 20
|
||
|
||
|
||
FLUSHP: BLOCK 1 ;P SAVED FOR RESTORATION IF A --MORE-- IS FLUSHED.
|
||
;0 => NOT POSSIBLE TO FLUSH NOW.
|
||
|
||
ERRCNT: BLOCK 1 ;DIFFERENCES COUNTER (0 MEANS NO DIFFERENCES)
|
||
|
||
LBUFP:
|
||
LBUFP1::BLOCK 1 ;POINTER TO BEGINNING OF LINE STORAGE FOR FILE #1
|
||
LBUFP2: BLOCK 1 ;DITTO FILE #2
|
||
LBUFP3: BLOCK 1
|
||
|
||
NLINES:
|
||
NLINE1::BLOCK 1 ;# OF LINES OF FILE 1 NOW IN CORE
|
||
NLINE2: BLOCK 1
|
||
NLINE3: BLOCK 1
|
||
|
||
EOFFL1: BLOCK 1 ;-1 => LAST NEXTLN ON FILE 1 WAS NO-OP'ED DUE TO EOF.
|
||
EOFFL2: BLOCK 1
|
||
EOFFL3: BLOCK 1
|
||
|
||
NCOMP1: BLOCK 1 ;HOW MANY LINES DIFF IS CONSIDERING FROM FILE 1
|
||
NCOMP2: BLOCK 1
|
||
NCOMP3: BLOCK 1
|
||
|
||
HBUF1: BLOCK WPL ;HOLDS TITLE FROM FIRST FILE
|
||
HBUF2: BLOCK WPL ;FROM SECOND FILE
|
||
HBUF3: BLOCK WPL
|
||
IFN ITS,[
|
||
RCHSTB: BLOCK 10. ;BLOCK WRITTEN INTO BY .RCHST
|
||
;WORD 0 RH DEV NAME, LH IF NON-ZERO THEN DEVICE NAME TO PRINT
|
||
;WRD 1 FNAM1
|
||
;WRD 2 FNAM2
|
||
;WRD 3 SYSTEM NAME
|
||
;WRD 4 NON-NEGATIVE => .ACCESS POINTER
|
||
;REST ROOM FOR EXPANSION OF SYSTEM CALL
|
||
]
|
||
PAGNUM: BLOCK 3 ;PAGE NUMBERS FOR THE TWO FILES, AT THE LEVEL OF RDLINE.
|
||
;THAT IS, THE PAGE # THAT THE NEXT LINE READ WILL START ON.
|
||
LINNUM: BLOCK 3 ;LINE NUMBERS FOR THE FILES, AT RDLINE LEVEL.
|
||
CHRNUM: BLOCK 3 ;# OF CHARS RDLINE HAS READ SO FAR FROM EACH FILE.
|
||
LLABEL: BLOCK 3*LNLBLN ;LNLBLN (4) WDS/FILE, 0 OR ASCIZ OF LAST LABEL AND A COLON.
|
||
MRGOUT: BLOCK 3 ;/M NON-ZERO MEANS OUTPUT TO MERGE FILE ALL
|
||
;/M LINES BEFORE WIPING OUT IN "MOVEUP" ROUTINE
|
||
;/M ALWAYS 0 IF /M NOT TYPED
|
||
LPHONY: BLOCK 1 ; -1 IFF LAST LINE OUTPUT BY MOVEUP DIDN'T END IN A CRLF,
|
||
;EXCEPT 1 => ENDED IN JUST A CR. 0 => ENDED IN A CRLF.
|
||
MRGLEN==2 ;/M LEAVE ROOM FOR 2 WORDS (10 CHAR) OF MERGE COMMAND.
|
||
MRGCOM: BLOCK MRGLEN ;/M BUFFER FOR MERGE COMMAND
|
||
BLOCK 1 ;/M GUARANTEE A NULL TERMINATION
|
||
MRGBYT: BLOCK 1 ;/M BYTE POINTER TO MERGE COMMAND STRING
|
||
MRGUFL: BLOCK 1 ;-1 => OUTPUTTING DIFFERENCES IN /F MODE; FROM MRGU1 TO MOVEUP.
|
||
|
||
OUTTTY: BLOCK 1 ;-1 => CHOUT IS OUTPUTTING TO A TTY.
|
||
IFN ITS,[
|
||
TTYSTS: BLOCK 1 ;SAVED TTYSET OF CHANNEL CHOUT, FOR RESTORATION AT RELDEV.
|
||
TTYST1: BLOCK 1
|
||
TTYST2: BLOCK 1
|
||
]
|
||
|
||
NUMTMP: BLOCK 1 ;TEMP FOR NUMLIN
|
||
TEMPF1: BLOCK 1 ;TEMP FOR F1
|
||
TEMPF2: BLOCK 1 ;TEMP FOR F2
|
||
TEMPF3: BLOCK 1
|
||
RFILC: 0 ;TEMP. FOR RFILE.
|
||
LSTEXP: 0 ;-1 => A BACKARROW WAS PRESENT IN COMMAND STRING.
|
||
|
||
|
||
FILBF1: BLOCK FILBFL ;FILE 1 BUFFER.
|
||
FILBE1=.-1
|
||
ASCIC//
|
||
FILPT1: 0 ;FILE 1 BUFFER PTR.
|
||
FILEP1: 0 ;FILE 1 B.P. TO THE ^C AFTERWHAT WAS READ IN.
|
||
|
||
FILBF2: BLOCK FILBFL ;FILE 2 BUFFER,
|
||
FILBE2=.-1
|
||
ASCIC//
|
||
FILPT2: 0 ;FILE 2 BUFFER PTR.
|
||
FILEP2: 0
|
||
|
||
FILBF3: BLOCK FILBFL ;FILE 3 BUFFER.
|
||
FILBE3=.-1
|
||
ASCIC//
|
||
FILPT3: 0 ;FILE 3 BUFFER PTR.
|
||
FILEP3: 0 ;FILE 3 B.P. TO THE ^C.
|
||
|
||
MRGBF: BLOCK MRGBSZ/5 ;BUFFER FOR MERGE OUTPUT
|
||
MRGBP: 0 ;B.P. FOR STUFFING BUFFER.
|
||
MRGCT: 0 ;# CHARS SPACE LEFT IN BUFFER.
|
||
|
||
PNTDBF: BLOCK 12./5+1 ;BUFFER FOR DECIMAL PRINT.
|
||
|
||
ENDP:: ;END OF STORAGE THAT'S ZEROED BEFORE EVERY COMMAND.
|
||
|
||
DEFDIR: 0 ;INITIAL (DEFAULT) DIRECTORY.
|
||
|
||
CMDFIL: 0 ;-1 => READING FROM THE FILE OPEN ON CHCMD
|
||
CMDIS: 0 ;DEFAULT INPUT DIR WHILE EXECUTING COMMAND FILE
|
||
CMDID: 0 ;DEFAULT INPUT DEVICE
|
||
CMDOS: 0 ;DEFAULT OUTPUT DIR
|
||
CMDOD: 0 ;DEFAULT OUTPUT DEVICE
|
||
|
||
CTLCF: 0 ;IF NOT 0, COMMIT SUICIDE AFTER FINISHING COMMAND.
|
||
|
||
COLMAX: <-1>_-1 ;/M MAX COLUMN TYPED OUT ON /M DIALOG
|
||
;/M CHANGED BY C COMMAND
|
||
LINMAX: <-1>_-1 ;/M MAX LINS TO TYPE OUT ON /M
|
||
NUMLIN: MATCH-1 ;# LINES FOR A MATCH
|
||
|
||
SEG1: 10000 ;START OF SEGMENT FOR FILE 1 LINES
|
||
SEG2: 201000 ;START OF SEGMENT FOR FILE 2 LINES
|
||
SEG3: 401000 ;START OF SEGMENT FOR FILE 3 LINES
|
||
|
||
TTIBUF: BLOCK 30 ;COMMAND BUFFER.
|
||
TTIBFL==.-TTIBUF
|
||
TTIPNT: 0 ;BYTE POINTER INTO TTIBUF.
|
||
TTICNT: 0 ;NUM. UNREAD CHARS LEFT IN TTIBUF.
|
||
|
||
|
||
CONSTANTS
|
||
|
||
FOO:
|
||
VARIABLES
|
||
|
||
-1
|
||
ENDCOR:
|
||
|
||
END BEG
|
||
|