Trailing-Edge
-
PDP-10 Archives
-
bb-m836d-bm
-
tools/scm/scm.mac
There are 3 other files named scm.mac in the archive. Click here to see a list.
TITLE SCM - Light speed .SCM file generation
;Compares files (similiar to FILCOM, but simpler and rather faster)
;21-Feb-83
;23-Jul-84 Add 2nd filename defaulting
SEARCH MONSYM,MACSYM
SALL
.MAJOR=2
.MINOR=0
.EDIT=3
.WHO=0 ;SM
F==0 ;FLAGS (F.xxx)
T1==1 ;THE USUAL SCRAP
T2==2
T3==3
T4==4
I==5 ;INDEX INTO LINKED LIST DURING COMPARES
FIL=6 ;ACTIVE FILE NUMBER (0 OR 1)
OFIL=7 ;THE OTHER FILE
READ==10 ;CONTROLS LINE NEXT READ BY INLINE
READ0==10 ;READ IS INDEXED BY 0 OR 1
READ1==11
STOPAT==12 ;WHERE SCANNING STOPS
STOP0==12 ;ALSO INDEXED BY 0 OR 1
STOP1==13
STLOC==14 ;WHERE SCANNING STARTS
STLO0==14 ;INDEX BY 0 OR 1
STLO1==15
CNT==16 ;COUNT OF LINES DURING PARANOIA CHECKS
P=17 ;STACK POINTER
;OFFSETS INTO THE DATA STRUCTURE
D.NEXT==0 ;ADDR OF NEXT STRING BLOCK
D.WHR==1 ;PAGE NUMBER,,LINE NUMBER IN PAGE
D.LAB==2 ;SIXBIT LABEL LAST SEEN
D.OFF==3 ;LINES DOWN FROM LAST LABEL SEEN
D.STR==4 ;THE BEGINNING OF THE LINE OF TEXT
;ASSEMBLY FLAGS
FTAPPD==-1 ;-1 TO MAKE APPENDED CHANGE STUFF PRETTY
FTSTAT==0 ;-1 TO GET STATS
COINCI==3 ;NUMBER OF LINES NEEDED TO BE THE SAME AFTER
; A DIFFERENCE TO PROVE THAT THE DIFFERENCE
; HAS ENDED (EG, HOW MANY CANT BE COINCIDENCE)
NPAG==10 ;NUMBER OF FILE PAGES TO HAUL IN AT ONCE
PPAG==NPAG*2+WHRBFR
PSIZ==<777-PPAG>*^D256 ;WORDS AVAILABLE TO EACH POOL
;TO FIT DDT IN, CHANGE 777 TO 750
POOL1=PPAG*1000 ;LOC TO START FIRST FILE POOL AT
POOL2=POOL1+PSIZ ;LOC TO START OTHER FILE POOL AT
F.RESC==1B0 ;RESCAN ON ENTER PASSES COMMAND
F.EXIT==1B1 ;EXIT AT NEXT COMMAND TIME
F.NMAC==1B35 ;NOT MACRO IF LIT
F.FILC==1B34 ;FILCOM MODE IF LIT
F.DIF==1B33 ;DIFFERENCES SEEN
F.EOF==1B32 ;EOFS ON BOTH JFNS
F.END==1B31 ;EOF ON A JFN
F.TTY==1B30 ;OUT TO .CTTRM
DEFINE COPYRI(text),<ASCIZ ~text~>
VECT: JRST ST ;START
JRST REE ;REENTRY
BYTE (3).WHO (9).MAJOR (6).MINOR (18).EDIT ;VERSION
-1,,CPYRIG ;COPYRIGHT
VECLEN=.-VECT
CPYRIG: COPYRI <
SCM - Fast and simple file comparer.
Copyright (C) 1983 by Digital Equipment Corporation, Maynard, Mass.
>
REE:
ST:
IFN FTSTAT,<
MOVX T1,.FHSLF
RUNTM%
MOVEM T1,STTIME#
>
RESET% ;CLEAR THE UNIVERSE
MOVEI P,STACK-1 ;SET STACK UP
SETZB F,MESFLG# ;NO FLAGS
MOVE T1,[ASCIZ/0) /]
MOVEM T1,LEAD ;NORMAL LEAD STRING
MOVX T1,.RSINI ;ANY COMMANDS FOR ME HERE?
RSCAN% ;..
ERJMP GCMD2 ;APPARENTLY NOT
SKIPN I,T1 ;ANY CHARATERS COME BACK?
JRST GCMD2 ;NO CHARACTERS THERE
MOVE T2,[POINT 7,[ASCIZ/SCM/]] ;MATCH THIS FOR RESCAN
RSCLOP: SOJL I,GCMD2 ;COUNT DOWN THE CHARACTERS
PBIN%
CAIN T1,.CHCRT ;IGNORE <CR>
JRST RSCLOP
CAIG T1," "
JRST TRMNR ;SPACE OR LESS TERMINATES PROGGY NAME
MOVE T1,CHRTAB(T1)
TXNN T1,CH%SYM
JRST GARBAG
ILDB T3,T2 ;CHECK...
CAIN T3,(T1)
JRST RSCLOP ;NEXT CHARACTER
JRST GARBAG ;NO MATCH
TRMNR: CAIE T1,.CHTAB
CAIN T1," " ;HOW DID IT END?
TXOA F,F.RESC ;YES, WE HAVE "progname "
JRST GARBAG ;IF ENDED WITH <LF>, NO RESCAN
JRST GCMD2
GARBAG: JUMPE I,GCMD2 ;HERE TO TOSS UNWANTED RESCAN
MOVX T1,.CTTRM ;IF NONE LEFT, DON'T TRY
SETZ T2,
MOVN T3,I ;TOSS I CHARACTERS
SIN% ;ALL GONE
ERJMP .+1
JRST GCMD2
GCMD: HLLZS F
TXNE F,F.EXIT!F.RESC
JRST LEAVE
GCMD2: TXNE F,F.RESC ;NO PROMPT ON RESCAN
SKIPA T1,[POINT 7,ZERO] ;.. ;< FOR BALANCE
HRROI T1,[ASCIZ/SCM>/] ;NORMAL PROMPT
MOVEM T1,CMDBLK+.CMRTY
DMOVE T1,[EXP CMDBLK,INIINB]
CALL PARSE ;PROMPT
JFCL ;SNH
MOVEM F,REALF#
MOVEM P,TMPP#
TRAPRP: MOVE P,TMPP ;FOR REPARSE
MOVE F,REALF
MOVE T1,[CZ%NIF+CZ%ABT+CZ%NUD+.FHSLF]
CLZFF% ;CLOSE ANY OPEN FILES
ERJMP .+1
SETZ FIL,
MOVX T1,GJ%OLD
MOVEM T1,GTJBLK+.GJGEN
MOVSI T4,-4
SETZM GTJBLK+.GJDEV(T4)
AOBJN T4,.-1
JRST FSTFLE
OTHFLE: MOVSI T4,-2 ;NEED TO GET 2 FIELDS FROM JFNS
MOVE T1,[POINT 7,TMPSTR]
SDEFS: MOVE T3,JFSTAB(T4)
MOVE T2,INJFN+0
MOVEM T1,GTJBLK+.GJNAM(T4) ;STORE THE POINTER TO THE COMING STRING
JFNS% ;OK, WRITE THE STRING
CAMN T1,GTJBLK+.GJNAM(T4) ;DID ANYTHING GET WRITTEN?
SETZM GTJBLK+.GJNAM(T4) ;NO, SO NO DEFAULT KNOWN
IDPB T3,T1 ;THIS FORCES A NULL
AOBJN T4,SDEFS ;NEXT FIELD, PLEASE?
FSTFLE: DMOVE T1,[EXP CMDBLK,[<.CMCFM>B8+[<.CMFIL>B8]]]
CALL PARSE ;PARSE INPUT FILE
JRST NOINFL
CAIN T3,.CMCFM
JRST LEAVE
HRRZM T2,INJFN(FIL) ;STORE JFN
MOVE T1,T2
MOVX T2,7B5+OF%RD ;ONLY NEED READ ACCESS FOR FILE WINDOWS
OPENF%
ERJMP NOINFL ;ERROR OUT
SIZEF%
ERJMP NOINFL
JUMPE T2,LEN0FL ;DON'T ACCEPT 0 LENGTH FILES
MOVEM T2,CHRFIL(FIL)
HRRO T1,[[ASCIZ/against/]
[ASCIZ/to file/]](FIL)
CALL GUIDE ;GIVE RIGHT GUIDE WORD
TRCN FIL,1 ;DONE 2ND INPUT FILE YET?
JRST OTHFLE ;NO, GO DO
SETZM OUTJFN#
MOVX T1,GJ%FOU+GJ%MSG ;SET UP FOR OUTPUT FILE
MOVEM T1,GTJBLK+.GJGEN
SETZM GTJBLK+.GJDEV
SETZM GTJBLK+.GJDIR
HRROI T1,[ASCIZ/SCM/] ;.SCM DEFAULT
MOVEM T1,GTJBLK+.GJEXT
HRROI T1,[ASCIZ/DIFFERENCES/]
MOVEM T1,GTJBLK+.GJNAM
DMOVE T1,[EXP CMDBLK,OFLINB]
CALL PARSE ;PARSE IT
JRST UNPARS
CAIE T3,.CMFIL
JRST NOFILE
MOVEM T2,OUTJFN
SWCCDE: DMOVE T1,[EXP CMDBLK,SWCINB]
CALL PARSE
JRST UNPARS
NOFILE: CAIN T3,.CMCFM
JRST OKGO
HRRZ T2,(T2)
JRST (T2)
WINSWI: DMOVE T1,[EXP CMDBLK,NUMINB]
CALL PARSE
JRST BADNQE
CAIG T2,0
MOVEI T2,COINCI
MOVEM T2,COINCH
JRST SWCCDE
MESSWI: DMOVE T1,[EXP CMDBLK,DNSINB]
CALL PARSE
JRST BADYQE
HRRZ T2,(T2)
MOVEM T2,MESFLG
JRST SWCCDE
FILSWI: MOVX T4,F.FILC
JRST YNSWI
EXISWI: TXO F,F.EXIT
JRST SWCCDE
MACSWI: MOVX T4,F.NMAC
YNSWI: DMOVE T1,[EXP CMDBLK,YNINB]
CALL PARSE
JRST BADYQE
HRRZ T2,(T2)
CAIE T2,0
TDZA F,T4
TDO F,T4
JRST SWCCDE
OKGO: SKIPE T2,OUTJFN
JRST OUTJFO
TXO F,F.TTY
MOVX T2,.CTTRM
MOVEM T2,OUTJFN ;STORE JFN
JRST ALLSET
OUTJFO: MOVE T1,T2
MOVX T2,7B5+OF%WR ;WRITE ACCESS
OPENF%
ERJMP NOOUFL
MOVX T1,.FHSLF
HRRO T2,OUTJFN ;PRIMARY OUT TO FILE!
SPJFN%
ALLSET: SETZ FIL, ;OUTPUT FILE HEADER
FILINF: MOVEI T1,1(FIL)
DPB T1,[POINT 2,FLEAD+1,6]
HRROI T1,FLEAD
PSOUT%
MOVX T1,.PRIOU ;OUTPUT FILESPEC
MOVE T2,INJFN(FIL)
SETZ T3,
JFNS%
ERJMP .+1
HRROI T1,CRLF
PSOUT%
TRCN FIL,1 ;DONE BOTH FILENAMES?
JRST FILINF ;NO, GO AGAIN
HRROI T1,CRLF
PSOUT%
SETZB READ0,READ1 ;ZERO OUT AC BORNE VARIABLES
MOVE T1,[ZERO,,ZERO+1]
BLT T1,EZER ;ZERO OUT VAR SPACE
;SCAN STARTS WITH FIL CONTAINING ZERO
BFRCHK: SKIPE READ(FIL) ;IS THERE LIVE DATA OUT THERE?
JRST BFRCH2 ;YES, DONT RESTART THE POOL
MOVE T1,BEGIN(FIL) ;CLOBBER POOL
MOVEM T1,WHERE(FIL)
SETZM LAST(FIL) ;THIS WILL BE POOLS FIRST LINE
BFRCH2: CALL INLINE ;READ IN A LINE
JRST FINIS ;BOTH FILES HAVE HIT EOF
TRCN FIL,1 ;SWITCH TO OTHER FILE
JRST BFRCHK ;GO BACK IF FILE 2 NOT READ YET
DMOVE T1,LINE ;GOT A LINE FROM EACH; COMPARE
CALL SAME ;..
JRST BFRCHK ;THE SAME, GET ANOTHER PAIR
TXO F,F.DIF ;FILES ARE DIFFERENT, REAL OUTPUT FILE
DMOVE STLOC,WHRBLK
MOVEI OFIL,1 ;FIL IS ZERO HERE
MOVE STOP1,WHRBLK+1 ;SO SET UP THE OTHER FILE THIS WAY
FNEND: CALL INLINE ;READ A LINE FROM THIS FILE
JRST ENDDIF ;BOTH HIT EOF. DUMP THE DIFFERENCES.
MOVE T1,WHRBLK(FIL)
MOVEM T1,STOPAT(FIL)
SKIPA I,STLOC(OFIL)
SCAN1: MOVE I,D.NEXT(I)
MOVEI T1,D.STR(I)
MOVE T2,STOPAT(FIL)
MOVEI T2,D.STR(T2)
CALL SAME
SKIPA CNT,COINCH
JRST FMATCH
MOVEI T1,D.STR(I)
HRLI T1,(POINT 7,0,6)
LDB T2,T1
CAIE T2,.CHCRT
JRST NBLANK
ILDB T2,T1
CAIN T2,.CHLFD
JRST FMATCH
NBLANK: MOVEM FIL,FILTMP#
MOVEM I,SCNTMP#
MOVE T1,D.NEXT(I)
MOVEM T1,READ(OFIL)
JUMPLE CNT,GOTCON
MAYBE: CALL SKLINE
JRST GOTCON
CALL SKLINE
JRST GOTCON
DMOVE T1,LINE
CALL SAME
JRST MAYBEC
FALSE: MOVE READ1,D.NEXT(STOP1) ;THESE ARE READ AND STOPAT, REMEMBER
MOVE READ0,D.NEXT(STOP0)
MOVE I,SCNTMP
IFN FTSTAT,< AOS FMACNT>
FMATCH: CAME I,STOPAT(OFIL)
JRST SCAN1
EXCH FIL,OFIL
JRST FNEND
MAYBEC: SOJG CNT,MAYBE
GOTCON: MOVE T1,FILTMP
MOVE T1,STOPAT(T1)
SETZM D.NEXT(T1)
MOVE T1,SCNTMP
SETZM D.NEXT(T1)
ENDDIF: SETZ FIL,
BEGDMP: MOVEI T1,1(FIL)
DPB T1,[POINT 2,LEAD,6] ;BUILD LEADIN STRING WITH RIGHT FILE #
SETOM INPAGE# ;IMPOSSIBLE PAGE NUMBER
SKIPA I,STLOC(FIL) ;ENTER WITH FIRST POINTER
LINOUT: MOVE I,D.NEXT(I) ;NEXT POINTER, PLEASE
JUMPE I,OTHFIL ;IF NO MORE LINES, TRY OTHER FILE
LDB T2,[POINT 7,D.STR(I),6] ;IS THIS LINE LACKING CHARACTER(S)?
JUMPE T2,LINOUT ;NO LINE, SKIP OUTPUT
TXNN F,F.FILC
JRST SCMLED
HRRZ T2,D.WHR(I)
ADDI T2,1
MOVE T4,[POINT 7,LEAD,13]
CAMN T2,INPAGE
JRST NOPAGN
MOVEM T2,INPAGE
CALL DECOUT
NOPAGN: MOVX T1,.CHTAB
IDPB T1,T4
SETZ T1,
IDPB T1,T4
SCMLED: HRROI T1,LEAD
LEDOUT: PSOUT%
HRROI T1,D.STR(I) ;OUT THE LINE
PSOUT%
SETO T2, ;FIND OUT IF LAST LINE ENDED WITH <LF>
ADJBP T2,T1 ;..
LDB T2,T2 ;..
CAIN T2,.CHLFD
JRST LINOUT
HRROI T1,CRLF ;DIDN'T. WE'LL ADD ONE FOR READABILITY
PSOUT%
JRST LINOUT ;NEXT LINE...
OTHFIL: JUMPN FIL,ENDWRI ;IF BOTH FILES DONE, QUIT
TXNN F,F.FILC
JRST SCMOUT
HRROI T1,FILMID
JRST DMPBAR
SCMOUT: MOVE T4,[POINT 7,MIDLIN+2,20]
MOVE I,STLOC
MOVE T2,D.WHR(I) ;WITH LINE AND PAGE COUNTS FOR FUN
MOVEM T2,TMP# ;....
MOVEI T2,1(T2)
CALL DECOUT
MOVE T1,[POINT 7,[ASCIZ/, line /]]
CALL CSTRA
HLRZ T2,TMP
CALL DECOUT
SKIPN T3,D.LAB(I)
JRST NOLABM
MOVE T1,[POINT 7,[ASCIZ/ **** /]]
CALL CSTRA
MOVE T2,[POINT 6,T3]
LABO: ILDB T1,T2
JUMPE T1,ELABO
ADDI T1," "
IDPB T1,T4
TLNE T2,770K
JRST LABO
ELABO: MOVEI T1,":"
IDPB T1,T4
SKIPN T2,D.OFF(I)
JRST NOLABM
MOVEI T1,"+"
IDPB T1,T4
CALL DECOUT
MOVEI T1,"L"
IDPB T1,T4
NOLABM: MOVEI T1,.CHCRT ;FASTER THAN CSTR WITH CRLF
IDPB T1,T4
MOVEI T1,.CHLFD
IDPB T1,T4
SETZ T1,
IDPB T1,T4
HRROI T1,MIDLIN
DMPBAR: PSOUT% ;NOPE, OUT SEPARATOR
AOJA FIL,BEGDMP ;SET FIL TO 1 AND DO OTHER FILE
ENDWRI: HRROI T1,BARLIN
PSOUT%
TXNN F,F.EOF ;ALL DONE?
SOJA FIL,BFRCHK ;NO, KEEP SCANNING
FINIS: TXNN F,F.TTY ;IF OUT TO TTY, NO CLOSE STUFF
JRST GOCLOS
TXNE F,F.DIF
JRST DIFER
JRST NODIFS
GOCLOS: SETO T2, ;RESTORE PRIMARY JFNS
MOVX T1,.FHSLF
SPJFN%
ERJMP .+1
TXNN F,F.DIF ;IF NO DIF'S SEEN, LET FALL PREY...
JRST NODIFS ;..TO LEAVE CODE,...
MOVE T1,OUTJFN
CLOSF% ;...ELSE CLOSE HERE.
ERJMP .+1 ;SNH
DIFER: MOVE T2,MESFLG
CAIE T2,M.DIF
JRST GCMD
HRROI T1,[ASCIZ/?Files are different./]
JRST LEAMSG
NODIFS: HRROI T1,[ASCIZ/?Files are identical./]
MOVE T2,MESFLG
CAIN T2,M.SAME
LEAMSG: PSOUT% ;ELSE IF THE SAME, SAY SO
JRST GCMD
LEAVE: SETO T1,
MOVE T2,[.FHSLF,,WHRBFR]
MOVE T3,[1B0+777-WHRBFR+1]
PMAP%
ERJMP .+1
MOVE T1,[CZ%ABT+CZ%NUD+CZ%NIF+.FHSLF]
CLZFF% ;BLOW AWAY ANYTHING LEFT AROUND
RESET% ;BLOW HARDER
IFN FTSTAT,<
MOVX T1,.FHSLF
RUNTM%
SUB T1,STTIME
MOVE T2,T1
HRROI T1,[ASCIZ/
Runtime: /]
CALL SDECOT
HRROI T1,[ASCIZ/ ms.
Number of false alarms: /]
PSOUT%
MOVE T2,FMACNT
CALL SDECOT
SETZ FIL,
HRROI T1,[ASCIZ ~
Number of rereads/lines:~]
PSOUT%
RETYP: MOVEI T1,.CHTAB
PBOUT%
MOVE T2,RERCNT(FIL)
CALL SDECOT
MOVEI T1,"/"
PBOUT%
SKIPE T2,LINCNT(FIL)
CALL SDECOT
TRCN FIL,1
JRST RETYP
HRROI T1,[ASCIZ/
Max use of pools:/]
PSOUT%
POLUSE: MOVE T2,PL1MAX(FIL)
SUB T2,BEGIN(FIL)
MOVE T3,BEGIN+1(FIL)
SUB T3,BEGIN(FIL)
IMULI T2,^D100
IDIV T2,T3
CAIG T2,0
MOVEI T2,1
MOVEI T1,.CHTAB
PBOUT%
CALL SDECOT
MOVEI T1,"%"
PBOUT%
TRCN FIL,1
JRST POLUSE
>
HALTF% ;DONE
JRST ST
;Subroutines and such like
;Probably faster than NOUT%
DECOUT: PUSH P,ZERO
DECOU2: IDIVI T2,^D10
ADDI T3,"0"
PUSH P,T3
JUMPN T2,DECOU2
DECOU3: POP P,T2
JUMPE T2,CPOPJ
IDPB T2,T4
JRST DECOU3
IFN FTSTAT,<
SDECOT: MOVEI T3,^D10
MOVX T1,.PRIOU
NOUT%
ERJMP .+1
RET
>
;INLINE and SKLINE.
;Read a line and link it into the list. T2 returned pointing to the block
; so linked in. SKLINE switches input first, INLINE leaves it alone.
SKLINE: TRC FIL,1 ;FLIP INPUT FIRST
;..
INLINE: SKIPN T2,READ(FIL) ;ARE WE READING STUFF ALREADY IN CORE?
JRST INPUT ;NO
IFN FTSTAT,<
AOS RERCNT(FIL)
>
MOVEM T2,WHRBLK(FIL) ;YES, RESET THE POINTER
MOVEI T1,D.STR(T2)
MOVEM T1,LINE(FIL) ;STORE STRING POINTER
MOVE T1,D.NEXT(T2) ;AND ADVANCE "READ"
MOVEM T1,READ(FIL)
JRST CPOPJ1 ;ALL DONE
INPUT: SKIPG INJFN(FIL) ;AT EOF?
JRST CPOPJ1 ;YES, ALL DONE
MOVE T2,WHERE(FIL) ;WHERE TO BUILD NEW LINE BLOCK
MOVEM T2,WHRBLK(FIL) ;..
SETZM D.NEXT(T2) ;IT HAS NO NEXT YET
MOVE T1,PAGCNT(FIL)
HRL T1,LINCNT(FIL)
MOVEM T1,D.WHR(T2) ;STORE PAGE AND LINE STUFF
MOVEI T2,D.STR(T2)
SETZM (T2) ;STRING IS NULL
MOVEM T2,LINE(FIL) ;STORE NEW STRING ADDRESS
HRLI T2,(POINT 7) ;MAKE A POINTER
NONULL: SOSL BFRCNT(FIL) ;ANY CHARACTERS TO COPY?
JRST CHRIB ;NEW BUFFER NOT NEEDED
MOVEM T2,TMP ;STORE STRING POINTER FOR LATER
SKIPG T1,CHRFIL(FIL) ;ANY CHARACTERS LEFT TO READ
JRST EOFFLG ;NOPE, EOF
MOVE T2,T1 ;COPY NUMBER OF CHARS.
SUBI T1,5*1000*NPAG ;DECR BY NUMBER THAT FIT IN BUFFER
MOVEM T1,CHRFIL(FIL) ;DECR FILE COUNT
CAILE T2,5*1000*NPAG ;MORE THAN A BUFFER LEFT?
MOVEI T2,5*1000*NPAG ;YES, BUT WE ONLY HAVE A BUFFER HERE
SUBI T2,1 ;DECR FOR CHARACTER READ BELOW
MOVEM T2,BFRCNT(FIL) ;AND STORE COUNT
MOVE T1,ATPAG(FIL) ;USUAL ADVANCE THROUGH FILE PAGE STUFF
HRL T1,INJFN(FIL)
MOVE T2,[EXP WHRBFR,WHRBFR+NPAG](FIL)
HRLI T2,.FHSLF
MOVX T3,PM%CNT+PM%RD+PM%EPN+NPAG
PMAP%
ERJMP EOFFLG
LSH T2,9 ;BUILD BYTE POINTER TO BUFFER
HRLI T2,(POINT 7)
MOVEM T2,BFRPTR(FIL) ;AND STORE
MOVEI T2,NPAG ;ADVANCE FILE COUNT
ADDM T2,ATPAG(FIL)
MOVE T2,TMP ;RESTORE T2
CHRIB: ILDB T1,BFRPTR(FIL) ;GET A CHARACTER!
JUMPE T1,NONULL ;WE DON'T TAKE NULLS
CAIE T1,.CHFFD ;FORMFEED?
JRST NFFD ;NO, TREAT NORMALLY
AOS PAGCNT(FIL)
SETZM LINCNT(FIL)
MOVEI T1,"^"
IDPB T1,T2
TLNN T2,760000
SETZM 1(T2)
MOVEI T1,"L"
NFFD: IDPB T1,T2 ;WRITE TO NEW LINE BLOCK
TLNN T2,760000 ;IF LAST BYTE OF THIS WORD,...
SETZM 1(T2) ;CLEAR NEXT WORD
CAIE T1,.CHLFD ;LINEFEED?
JRST NONULL ;NO, TRY AGAIN
NOEOF: TXZA F,F.END ;LINE COPIED, NO EOF
EOFFLG: TXO F,F.END ;HERE IF CHAR COUNT EXHAUSTED
MOVEI T2,2(T2)
MOVEM T2,WHERE(FIL)
IFN FTAPPD,<
; This is here so the last line of a file is marked as unique - ie, the
; last line of file 0 can only match the exact same text in file 1, if
; that line in file 1 is also file 1's last line. The only effect this has
; is that, if (for instance) file 1 is only different from file 0 in that
; it is longer, then the last line of file 0 is typed out as differing.
; For instance, if file 0 is
;QQ
; And file 1 is
;QQ
;A
;B
; then the typeout would be
;1) QQ
;*****
;2) QQ
;2) A
;2) B
; instead of just
;2) A
;2) B
; This behaviour is different from FILCOM, and can be stopped by changing
; the value of FTAPPD
SKIPG BFRCNT(FIL) ;IS THIS BUFFER NOW EMPTY?
SKIPLE CHRFIL(FIL) ;AND ARE THERE UNREAD BUFFERS OUT THERE?
JRST .+2 ;ONE'S FALSE. MORE CHARACTERS LEFT
AOS @LINE(FIL) ;JUST READ LAST LINE. MARK 1B35 IN IT
> ;End of FTAPPD
CAMLE T2,BEGIN+1(FIL) ;IS FILE INTO NEXT POOL?
JRST CURSE ;YES, GO DIE HIDEOUSLY
IFN FTSTAT,<
CAMLE T2,PL1MAX(FIL)
MOVEM T2,PL1MAX(FIL)
>
SETZB T4,LABEL
JUMPN FIL,ESCAN
TXNE F,F.NMAC!F.FILC ;NOT A .MAC FILE? OR /SCM?
JRST ESCAN
MOVE T1,LINE(FIL)
HRLI T1,(POINT 7)
MOVE T2,[POINT 6,LABEL]
SCANL: ILDB T3,T1
SKIPL T3,CHRTAB(T3)
JRST ISNSYM
SUBI T3," "
TLNE T2,770K
IDPB T3,T2
JRST SCANL
ISNSYM: CAIE T3,":"
SETZM LABEL
ESCAN: SKIPN T1,LABEL
JRST NNLAB
MOVEM T1,OLDLAB
SETZM OFFSET
JRST NOLAB2
NNLAB: AOS OFFSET
NOLAB2: TXNN F,F.END ;IF AT EOF...
AOS LINCNT(FIL) ;DONT INCR LINE COUNT
FILE1: MOVE T2,WHRBLK(FIL) ;WHERE DOES THIS NEW BLOCK START?
JUMPN FIL,FILE1A
MOVE T1,OFFSET
MOVEM T1,D.OFF(T2)
MOVE T1,OLDLAB
MOVEM T1,D.LAB(T2)
FILE1A: SKIPE T1,LAST(FIL) ;IS THERE A LAST BLOCK TO POINT TO IT?
MOVEM T2,D.NEXT(T1) ;YES, LINK UP
EBLK: MOVEM T2,LAST(FIL) ;THIS IS NOW THE LAST BLOCK
TXNN F,F.END ;EOF CHECKS NOW?
JRST CPOPJ1 ;NO, DONE
;..
EOFFIL: MOVE T1,INJFN(FIL) ;EOF. CLOSE THIS FILE...
CLOSF%
ERJMP .+1
SETOM INJFN(FIL) ;MARK NO FILE HERE
MOVNI T1,-1(FIL) ;T1/ TRASH,,?xOTHER FILE NUMBER
SKIPGE INJFN(T1) ;IS THE OTHER FILE GONE TOO?
TXOA F,F.EOF ;YES, MARK DONE AND SING. RET
AOS (P) ;NO, SKIP RET
RET
;SINGLE RET IF THE SAME, +2 IF DIF.
SAME: MOVE T3,(T1)
CAME T3,(T2)
AOSA (P) ;ANY DIFFERENCE IS A DIFFERENCE
TRNN T3,177*2 ;ASCIZ NULL, 5TH POSITION
RET
ADDI T1,1
AOJA T2,SAME
;WHYDIF:
; IFN FTAPPD,<
; XOR T3,(T2) ;IS 1B35 LIT FOR ONE BUT NOT THE OTHER?
; TRNE T3,1B35 ;1B35 MARKS EOF
; JRST CPOPJ1 ;YES, DIFFERENT, NO EXCUSES
; > ;END IFN FTAPPD
; HRLI T1,(POINT 7) ;NO, CHECK FOR TRAILING SPACE STUFF
; HRLI T2,(POINT 7)
;SAME1: ILDB T3,T1
; ILDB T4,T2
; CAIE T3,(T4)
; JRST DEFSEN
; JUMPN T3,SAME1
; JRST CPOPJ1
;DEFSEN: JUMPE T3,MAYOK
;TRAILS: CAIE T3,.CHCRT
; CAIN T3," "
; JRST MAYOK
; CAIE T3,.CHTAB
; CAIN T3,.CHLFD
; JRST MAYOK
; JRST CPOPJ1 ;NOT THE SAME
;MAYOK: JUMPE T4,ISOK
; CAIE T4,.CHCRT
; CAIN T4,.CHLFD
; JRST ISOK
; CAIE T4," "
; CAIN T4,.CHTAB
; JRST ISOK
; JRST CPOPJ1
;ISOK: CAIE T3,0
; ILDB T3,T1
; CAIE T4,0
; ILDB T4,T2
; JUMPN T3,TRAILS
; JUMPN T4,TRAILS
; RET
CSTRA: ILDB T2,T1 ;COPY STRING REF'D BY T1 TO T4
JUMPE T2,CPOPJ ;DON'T COPY NULL
IDPB T2,T4
JRST CSTRA
INIINB: <.CMINI>B8
CONINB: <.CMCFM>B8
OFLINB: <.CMCFM>B8+OF2INB
OF2INB: <.CMFIL>B8+SWIINB
SWCINB: <.CMCFM>B8+SWIINB
SWIINB: <.CMSWI>B8
EXP SWILST
SWILST: SWILEN,,SWILEN
[ASCIZ/EXIT/],,EXISWI
[ASCIZ/MACRO:/],,MACSWI
[ASCIZ/MESSAGE:/],,MESSWI
[ASCIZ/SCM:/],,FILSWI
[ASCIZ/WINDOW:/],,WINSWI
SWILEN=.-SWILST-1
NUMINB: <.CMNUM>B8
^D10
DNSINB: <.CMKEY>B8
EXP DNSLST
M.SAME==0 ;DEFAULT
M.DIF==1 ;DIFFERENT
M.SHH==2
DNSLST: DNSLEN,,DNSLEN
[ASCIZ/DIFFERENT/],,M.DIF
[ASCIZ/NONE/],,M.SHH
[ASCIZ/SAME/],,M.SAME
DNSLEN=.-DNSINB-1
YNINB: <.CMKEY>B8
EXP YNLST
YNLST: YNLEN,,YNLEN
[ASCIZ/NO/],,0
[ASCIZ/YES/],,1
YNLEN==.-YNLST-1
;CALL TO PARSE WHATEVER.
PARSE: COMND%
HITME: ERJMP [SETO T3, ;EOF (assumed) RETS -1
MOVX T1,CM%NOP ;AND PARSE FAILURE
RET]
HRRZS T3
LDB T3,[POINT 9,(T3),8]
TXNN T1,CM%NOP
CPOPJ1: AOS (P)
CPOPJ: RET
;CALL TO CONFIRM
CONFRM: DMOVEM T1,1(P)
MOVEM T3,3(P)
DMOVE T1,[EXP CMDBLK,CONINB]
COMND%
MOVE T3,3(P)
DMOVE T1,1(P)
RET
GUIDE: HRROM T1,GUIINB+.CMDAT
DMOVEM T2,1(P)
DMOVE T1,[EXP CMDBLK,GUIINB]
COMND%
DMOVE T2,1(P)
RET
NOINFL: HRROI T1,[ASCIZ/
?Can't access file /]
PSOUT%
MOVEI T1,"1"(FIL)
PBOUT%
HRROI T1,[ASCIZ/: /]
JRST LSTERR
LEN0FL: HRROI T1,[ASCIZ/
?File /]
PSOUT%
MOVEI T1,"1"(FIL)
PBOUT%
MOVX T1,.FHSLF
MOVX T2,BOTX04
SETER% ;CONVENIENT ERROR MESSAGE CODE
ERJMP .+1
HRROI T1,[ASCIZ/ is empty: /]
JRST LSTERR
NOOUFL: HRROI T1,[ASCIZ/
?Cant open output file: /]
;..
LSTERR: PSOUT%
MOVX T1,.PRIOU
HRLOI T2,.FHSLF
SETZ T3,
ERSTR%
JRST GCMD
JRST GCMD
JRST GCMD
BADYQE: HRROI T1,[ASCIZ/
?Bad option to a switch./]
JRST LEAMSG
BADNQE: HRROI T1,[ASCIZ/
?Garbage for numeric input./]
JRST LEAMSG
UNPARS: HRROI T1,[ASCIZ/
?Unable to parse confirm, filename, or switch where expected./]
JRST LEAMSG
CURSE: HRROI T1,[ASCIZ/
?Internal buffer overflow./]
JRST LEAMSG
BARLIN: ASCIZ/***********************************************
/
FILMID: ASCIZ /****
/
BEGIN: EXP POOL1,POOL2,777700
CRLF: ASCIZ/
/
;Character information. CH%SYM must be 1B0.
CH%SYM==1B0
CH%EOL==1B1
CH%DIG==1B2
CH%UPR==1B3
CH%DWN==1B4
CHRTAB: 0
1
2
3
4
5
6
7
10
11
CH%EOL! 12
13
CH%EOL! 14
CH%EOL! 15
16
17
20
21
22
23
24
25
26
27
30
31
32
33
34
35
36
37
40
41
42
43
CH%SYM! 44
CH%SYM! 45
46
47
50
51
52
53
54
55
CH%SYM! 56
57
CH%DIG!CH%SYM! 60
CH%DIG!CH%SYM! 61
CH%DIG!CH%SYM! 62
CH%DIG!CH%SYM! 63
CH%DIG!CH%SYM! 64
CH%DIG!CH%SYM! 65
CH%DIG!CH%SYM! 66
CH%DIG!CH%SYM! 67
CH%DIG!CH%SYM! 70
CH%DIG!CH%SYM! 71
72
73
74
75
76
77
100
CH%UPR!CH%SYM! 101
CH%UPR!CH%SYM! 102
CH%UPR!CH%SYM! 103
CH%UPR!CH%SYM! 104
CH%UPR!CH%SYM! 105
CH%UPR!CH%SYM! 106
CH%UPR!CH%SYM! 107
CH%UPR!CH%SYM! 110
CH%UPR!CH%SYM! 111
CH%UPR!CH%SYM! 112
CH%UPR!CH%SYM! 113
CH%UPR!CH%SYM! 114
CH%UPR!CH%SYM! 115
CH%UPR!CH%SYM! 116
CH%UPR!CH%SYM! 117
CH%UPR!CH%SYM! 120
CH%UPR!CH%SYM! 121
CH%UPR!CH%SYM! 122
CH%UPR!CH%SYM! 123
CH%UPR!CH%SYM! 124
CH%UPR!CH%SYM! 125
CH%UPR!CH%SYM! 126
CH%UPR!CH%SYM! 127
CH%UPR!CH%SYM! 130
CH%UPR!CH%SYM! 131
CH%UPR!CH%SYM! 132
133
134
135
136
137
140
CH%DWN!CH%SYM! 101
CH%DWN!CH%SYM! 102
CH%DWN!CH%SYM! 103
CH%DWN!CH%SYM! 104
CH%DWN!CH%SYM! 105
CH%DWN!CH%SYM! 106
CH%DWN!CH%SYM! 107
CH%DWN!CH%SYM! 110
CH%DWN!CH%SYM! 111
CH%DWN!CH%SYM! 112
CH%DWN!CH%SYM! 113
CH%DWN!CH%SYM! 114
CH%DWN!CH%SYM! 115
CH%DWN!CH%SYM! 116
CH%DWN!CH%SYM! 117
CH%DWN!CH%SYM! 120
CH%DWN!CH%SYM! 121
CH%DWN!CH%SYM! 122
CH%DWN!CH%SYM! 123
CH%DWN!CH%SYM! 124
CH%DWN!CH%SYM! 125
CH%DWN!CH%SYM! 126
CH%DWN!CH%SYM! 127
CH%DWN!CH%SYM! 130
CH%DWN!CH%SYM! 131
CH%DWN!CH%SYM! 132
173
174
175
176
177
JFSTAB: 1B8 ;FILENAME FOR JFNS
1B11 ;EXTENSION FOR JFNS
XLIST
LIT
LIST
;WRITABLES
COINCH: COINCI-1
MIDLIN: ASCIZ /**** On Page /
BLOCK ^D80/5
LEAD: BLOCK 2 ;GETS SET UP AT RUN TIME
FLEAD: ASCIZ /File 0) /
BFRSIZ==^D50
CMDBLK: 0,,TRAPRP
.PRIIN,,.PRIOU
BLOCK 1 ;PROMPT FILLED IN AT RUNTIME
-1,,BFFR
-1,,BFFR
BFRSIZ*5-1
BFRSIZ*5-1
-1,,ATOM
BFRSIZ*5-1
GTJBLK
GUIINB: <.CMNOI>B8
BLOCK 1
GTJBLK: BLOCK 16
ATOM: BLOCK BFRSIZ
BFFR: BLOCK BFRSIZ
CHRFIL: BLOCK 2
BFRPTR: BLOCK 2
INJFN: BLOCK 2
WHERE: BLOCK 2
TMPSTR: BLOCK 50
ZERO: BLOCK 1
LABEL: BLOCK 1
OLDLAB: BLOCK 1
OFFSET: BLOCK 1
ATPAG: BLOCK 2
BFRCNT: BLOCK 2
LINE: BLOCK 2
LAST: BLOCK 2
WHRBLK: BLOCK 2
LINCNT: BLOCK 2
PAGCNT: BLOCK 2
IFN FTSTAT,<
RERCNT: BLOCK 2
PL1MAX: BLOCK 2
FMACNT: BLOCK 1
>
EZER=.-1
STACK: BLOCK 15
LIT ;JUST IN CASE
VAR ;and all those vars...
ENDPRG:
WHRBFR==<ENDPRG+100+2000>/1000+1 ;PAGE TO START FILE BUFFERS AT
;SPACE FOR PATCHING AND SYMBOLS
END <VECLEN,,VECT>