perm filename TECO[CS,SYS] blob
sn#029541 filedate 1973-03-16 generic text, type T, neo UTF8
00100 TITLE TECO V.001 6 MAY 1967
00200 SUBTTL TAPE EDITOR AND CORRECTOR(V21) DON WITCRAFT
00300
00400 REPEAT 0,<
00500
00600 I. GENERAL DESCRIPTION
00700 TECO (TAPE EDITOR AND CORRECTOR) IS A SCOPE-KEYBOARD TEXT EDITOR.
00800 IT USES AN ON-LINE COMMAND LANGUAGE (WHICH PERMITS MACRO-DEFINITIONS,
00900 CONDITIONALS,ETC.) TO CONTROL INPUT-OUTPUT (PAPER AND MAGNETIC TAPES,
01000 SCOPE,ETC.) AS WELL AS TEXT OPERATIONS. THE MACRO LANGUAGE PERMITS THE
01100 MOST SOPHISTICATED SEARCH, MATCH, AND SUBSTITUTION OPERATIONS AS WELL AS
01200 SIMPLE TYPOGRAPHICAL CORRECTIONS TO TEXT. ALTHOUGH TECO IS DESIGNED
01300 TO BE USED WITH A DISPLAY, IT MAY BE USED WITHOUT ONE.
01400
01500 THE ORIGINAL TECO WAS A PDP-1 PROGRAM WRITTEN BY DANIEL L.
01600 MURPHY. PDP-6 TECO WAS WRITTEN BY STEWART NELSON, JACK HOLLOWAY, AND
01700 RICHARD GREENBLATT. PDP-10 TIMESHARING TECO WAS ADAPTED FROM PDP-6 TECO
01800 BY ROBERT CLEMENTS. THE CURRENT VERSION IS AN ATTEMPT TO MAKE THE LATTER
01900 REENTRANT.
02000 THERE ARE THREE KINDS OF STORAGE AREAS WITHIN TECO:
02100 (1) THE BUFFER
02200 (2) THE 36 Q-REGISTERS; DESIGNATED 0,1,...,9,A,B,...,Z
02300 (3) THE COMMAND STRING AREA.
02400 THE BUFFER AT ALL TIMES CONTAINS A (POSSIBLY NULL) CHARACTER STRING,
02500 GENERALLY CONSTITUTING A PAGE OF THE TEXT BEING EDITED. AT CERTAIN TIMES
02600 THE COMMAND-STRING AREA CONTAINS A STRING OF CHARACTERS WHICH TECO INTERPRETS
02700 AS A SERIES OF COMMANDS. EACH Q-REGISTER MAY:
02800 (A) BE UNDEFINED,
02900 (B) CONTAIN A POSITIVE OR NEGATIVE INTEGER, OR
03000 (C) CONTAIN A CHARACTER STRING.
03100 THE BUFFER IS THAT AREA WHERE TEXT TO BE EDITED IS EXAMINED AND MODIFIED;
03200 THE Q-REGISTERS ARE LOCATIONS FOR REMEMBERING QUANTITIES, OR STRINGS OF TEXT,
03300 FOR LATER USE; THE COMMAND STRING IS THE AREA FROM WHICH TECO TAKES
03400 INSTRUCTIONS.
03500 ASSOCIATED WITH THE BUFFER IS THE "POINTER": THIS IS A
03600 MOVABLE FLAG WHICH ALWAYS SITS BETWEEN TWO ADJACENT CHARACTERS IN THE
03700 BUFFER (OR AT EITHER END OF THE BUFFER). THE POINTER HAS A NUMERIC VALUE
03800 EQUAL TO THE NUMBER OF CHARACTERS TO ITS LEFT IN THE BUFFER.
03900 IF AT THE MOMENT THERE ARE N CHARACTERS IN THE BUFFER, THE POINTER'S
00100 VALUE MAY RANGE FROM 0 TO N.
00200 A GENERAL DESCRIPTION OF THE USAGE OF TECO IS AS FOLLOWS:
00300 THE USER GETS TECO INTO THE COMPUTER; TYPES IN COMMANDS TO DESCRIBE WHERE
00400 THE MATERIAL TO BE EDITED (THE "INPUT") IS. BY FURTHER COMMANDS, HE
00500 READS THE FIRST PAGE INTO THE BUFFER; INSPECTS IT ON THE DISPLAY AND
00600 MAKES CHANGES BY TYPING IN COMMANDS; OUTPUTS THE PAGE ONTO PAPER TAPE OR
00700 DECTAPE, AND READS IN THE NEXT PAGE; ETC.; AFTER OUTPUTTING THE LAST
00800 PAGE, HE CLOSES THE OUTPUT FILE, THEREBY RELEASING THE OUTPUT DEVICE.
00900 THIS IS BY NO MEANS THE ONLY WAY ONE MAY PROCEED, BUT IT IS THE MOST COMMON.
01000
01100
01200
01300 II. LOADING TECO
01400 TO LOAD TECO, TYPE THE MONITOR COMMAND:
01500 R TECO
01600 >
00100 ;ACCUMULATOR ASSIGNMENTS
00200
00300 FF←0 ;CONTROL FLAGS
00400 P←1 ;PUSH DOWN POINTER
00500 ;*** A, AA AND B MUST BE CONTIGUOUS AND IN THAT ORDER ***
00600 A←2
00700 AA←3 ;BYTE POINTER TO COMMAND BUFFER
00800 ;*** B AND E MUST BE ADJACENT AND B<11 ***
00900 B←4 ;COMMAND BUFFER END ADDRESS
01000 E←5
01100 C←6
01200 D←7
01300 F←10
01400 T←11
01500 ;*** TT AND TT1 MUST BE ADJACENT ***
01600 TT←12
01700 TT1←13
01800 IN←14
01900 OUT←15
02000 CH←16
02100 PF←17
02200 R←0 ;DATA AREA RELOCATION. XWD RELOC,RELOC
02300
02400 EXTERN JOBREL,JOBSYM,JOBDDT,JOBFF,JOB41,JOBREN
02500
02600 ;CONTROL FLAGS
02700 ;RIGHT HALF
02800
02900 ALTF←1 ;ALT-MODE SEEN
03000 ;LI1(0),GO1+2(0),LI4+2(1)
03100 ARG2←2 ;THERE IS A SECOND ARGUMENT
03200 ;GO1+2(0),CD+3(0),COMMA+2(1),HOLE+1(1)
03300 ARG←4 ;THERE IS AN ARGUMENT
03400 ;GO1+2(0),CD+3(0),CD7(1),COMMA+1(0),CHK2(1),BAKSL(0),BAKSL2(0),
03500 ;BAKSLM(1),LSSTH+5(0),GETARG+2(1)
03600 ITERF←10 ;INSIDE AN ITERATION
03700 ;GO1+2(0),OPEN+2(0),CLOSE+5(1),CLOSE+7(1),GRCH+2(0),LSSTH1(1)
03800 SLSL←20 ;@ SEEN
03900 ;GO1+2(0),INSERT+3(0),ATSIGN(1),SERCH+3(0)
04000 PCHFLG←40 ;N SEARCH
04100 ;GO1+2(0),CD+3(0),SERCHP(1),BEGIN2(0)
04200 COLONF←100 ;COLON SEEN
04300 ;GO1+2(0),COLON(1),FND+5(0),BEGIN1(0)
04400 SYLF←200 ;GO1+2(0),CD6+2(0),CD7(1)
04500 FINF←1000 ;GO1+2(0),CD5+1(0),YANK3+12(1)
04600 FINDR←2000 ;LEFT ARROW SEARCH
04700 ;GO1+2(0),CD+3(0),LARR(1),BEGIN2(0)
04800 QMFLG←4000 ;LI3+5(0),ERR+4(1)
04900 NOTF←10000 ;↑N SEARCH MODIFIER
05000 ;GO1+2(0),CD6+5(0),SERCH4(0),CNTRN(1)
05100 TRACEF←20000 ;? SEEN
05200 ;QUESTN(R)
05300 SEQF←40000 ;SEQUENCE NUMBER
05400 ;YNKSEQ(1),YANK5+5(0)
05500 BELLF←100000 ;↑G SEEN
05600 ;GO1+2(0),LI1(0),LI5+2(1)
05700
00100 ;LEFT HALF
00200
00300 UREAD←200 ;INPUT FILE IS OPEN
00400 ;YANK3+11(0),OPNRD(1)
00500 UWRITE←400 ;OUTPUT FILE IS OPEN
00600 ;OUTERR+4(0),OPNW1(1),CLOSEF(0)
00700 FILWD←2000 ;FILE WORD BEING ASSEMBLED.
00800 ;FILSPC(0),FILSPL+20(1),FILLS1+3(0),FILLS1+4(0)
00900 FEXTF←4000 ;FILE EXT EXPECTED (.TYPED).
01000 ;FILLS1(0),FILSP3+2(1)
01100
01200 OPDEF TYPR1 [30B8]
01300
01400 OPDEF OPEN [50B8]
01500
01600 ;CALLI UUOS
01700 RESET←0
01800
01900 DDTIN←1
02000 TYIN←DDTIN
02100 DDTOUT←3
02200 TYOUT←DDTOUT
02300 EXIT←12
02400 TIMER←22
02500 SWITCH←20
02600 UTPCLR←13
02700 INCHN←2
02800 OUTCHN←3
02900 LPDL←75
03000 GCTBL←100
03100 LPF←40
03200 BUFSIZ←205
03300 IFE <R>,<
03400 DEFINE U'(A,B)
03500 < A: BLOCK B>
03600 >
03700
03800 IFN <R>,
03900 < ZZ←CODEND
04000 DEFINE U'(A,B),<XLIST
04100 A←ZZ
04200 ZZ←ZZ+B
04300 LIST>
04400 >
04500
00100 ;STARTUP TIME INITIALIZATION
00200
00300 INTERNAL TECO
00400 TECO:
00500 INIT: CALLI RESET ;INITIALIZE ALL IO
00600 MOVE A,LOC41 ;SETUP UUO TRAP JOB41:=JSR ETYPER
00700 MOVEM A,JOB41(R)
00800 MOVE P,[XWD -LPDL,PDL-1]
00900 IFN <R>,< ADDI P,(R) ;RELOCATE PUSH DOWN LIST>
01000 HRRZ A,JOBREL(R) ;IF JOBDDT=0, JOBFF:=C(JOBREL)-202
01100 IFE <R>,< SKIPE JOBDDT ;OTHERWISE, JOBFF:=C(JOBSYM)-202
01200 HRRZ A,JOBSYM>
01300 MOVEM A,JOBFF(R)
01400 IMULI A,5
01500 MOVEM A,MEMSIZ(R) ;MEMSIZ:=C(JOBFF)*5
01600 MOVE A,TTYPT ;INITIALIZE TTY BUFFER
01700 MOVEM A,TYIPT(R)
01800 MOVEM A,TYOPT(R)
01900 SETZM TTYBUF(R)
02000 MOVE A,[XWD TTYBUF,TTYBUF+1]
02100 IFN <R>,< ADD A,R ;RELOCATE>
02200 BLT A,TTYBUF+24(R)
02300 SETZM SFINDF(R)
02400 MOVEI A,GOX ;SET FOR REENTER AT GOX
02500 MOVEM A,JOBREN(R)
02600 MOVSI A,263000+P*40
02700 MOVEM A,TRACS(R) ;TRACS:=POPJ P,
02800 SETZM OPNR1(R) ;CLEAR INPUT DEVICE NAME
02900 MOVEI A,CBUF+200
03000 IMULI A,5
03100 MOVEM A,BEG(R) ;BEG:=(CBUF+200)*5
03200 MOVEM A,PT(R) ;PT:=(CBUF+200)*5
03300 MOVEM A,Z(R) ;Z:=(CBUF+200)*5
03400 MOVEM A,QRBUF(R) ;QRBUF:=(CBUF+200)*5
03500 MOVEI A,CBUF+77
03600 MOVEM A,CBUFH(R) ;CBUFH:=CBUF+77
03700 MOVEI A,SYL
03800 MOVEM A,DLIM(R) ;DLIM:=SYL
03900 MOVE A,[XWD 10014,-1]
04000 MOVEM A,NROOM2(R) ;NROOM2:=XWD 10014,-1
04100 MOVE A,[JRST CNTRB2] ;CNTRB1+1:=JRST CNTRB2
04200 MOVEM A,CNTRB1+1(R)
04300 MOVEI FF,0 ;CLEAR FLAG REGISTER
00100 ;REENTER COMMAND INITIALIZATION
00200 ;FROM ETYPER+10
00300
00400 GOZ:
00500
00600 ;FROM LI5+4,OUTERR+5
00700
00800 GOX: PUSHJ P,CRR ;TYPE CRLF
00900
01000 ;FROM ALTMOD+4,ERR+12
01100
01200 GO: MOVE P,[XWD -LPDL,PDL-1] ;INITIALIZE PUSHDOWN LIST
01300 IFN <R>,< ADDI P,(R) ;RELOCATE POINTER>
01400 MOVE T,[JRST DQT2] ;INITIALIZE CONTROL B DISPATCH
01500 MOVEM T,CNTRB1(R) ;CNTRB1:=JRST DQT2
01600 GO1: SETZM ,LEV(R)
01700 MOVE PF,[XWD -LPF,PFL-1]
01800 IFN <R>,< ADDI PF,(R) ;RELOCATE POINTER>
01900 TRZ FF,777777-TRACEF-QMFLG
02000 JRST LIS
02100
02200
02300 LOC41: JSR ETYPER
02400
00100 ;ROUTINE TO RETURN NON-NULL TTY CHARACTER IN CH.
00200 ;CALL PUSHJ PDP,TYI
00300 ; RETURN
00400 ;FROM LI3+1
00500
00600 TYI: MOVE T,TTYPT
00700 CAMN T,TYIPT(R) ;IS TTY BUFFER EMPTY?
00800 TYI1: CALLI T,TYIN ;YES. GET A CHARACTER
00900 ILDB CH,TYIPT(R)
01000 JUMPN CH,CPOPJ ;IF NOT NULL CHARACTER, RETURN
01100 MOVE T,TTYPT ;NULL. RESET INPUT POINTER AND GET ANOTHER CHARACTER
01200 MOVEM T,TYIPT(R)
01300 JRST TYI1
01400
01500
01600
01700
01800 ;ROUTINE TO TYPE A CHARACTER.
01900 ;CALL MOVE CH,CHARACTER
02000 ; PUSHJ P,TYO
02100 ; RETURN
02200 ;CONTROL CHARACTERS ARE TYPED WITH "↑" FOLLOWED BY THE CORRESPONDING
02300 ;PRINTING CHARACTER.
02400 ;FROM CRR1+1,CRR1+3,LI3+1,LI3+23,ERRTYP+5,ERRMES+1,CONMES+3,SIXBMS+5,LIS+1
02500 ;ERR+2,LKUPER+7,ETYPER+11,FORM,COMMENT+3
02600
02700 TYO: PUSH P,CH ;NULL/IDLE,START OF MESSAGE,END OF ADDRESS, END OF
02800 ;TRANSMISSION,WRU,ARE YOU OR BELL?
02900 CAIL CH,7
03000 CAIN CH,10
03100 JRST TYO1 ;YES.
03200 CAIG CH,15 ;NO. HORIZONTAL TAB,LINE FEED,VERTICAL TAB
03300 ;FORM FEED OR CARRIAGE RETURN?
03400 JRST TYOB ;YES. TYPE IT AND RETURN
03500 CAIGE CH,40 ;NO. ANY OTHER CONTROL CHARACTER?
03600 JRST TYO1 ;YES.
03700 CAIN CH,175 ;NO. ALT-MODE?
03800 MOVEI CH,"$" ;YES. CONVERT IT TO $.
03900 TYOB: PUSHJ P,TYOA ;TYPE CH.
04000 POP P,CH ;RESTORE CH
04100 POPJ P,0 ;RETURN
04200
00100 TYOA: MOVE T,TTYPT ;INITIALIZE OUTPUT POINTER
00200 MOVEM T,TYOPT(R)
00300 IDPB CH,TYOPT(R) ;STORE CH IN TTYBUF
00400 TOUTCL: MOVEI T,0 ;TERMINATE OUTPUT STRING WITH A NULL
00500 IDPB T,TYOPT(R)
00600 MOVE T,TTYPT ;RESET OUTPUT POINTER.
00700 MOVEM T,TYOPT(R)
00800 HRRZ T,T
00900 CALLI T,TYOUT ;TYPE CH
01000 POPJ P,0
01100
01200 TYO1: PUSH P,CH ;TYPE CONTROL CHARACTER IN FORM "↑CH"
01300 MOVEI CH, "↑"
01400 PUSHJ P,TYOA ;TYPE ↑
01500 POP P,CH
01600 ADDI CH,100 ;CONVERT TO PRINTING CHARACTER
01700 JRST TYOB ;AND TYPE IT.
01800
01900 U TYIPT,1 ;INIT+16(TTYPT),TYI1+4(TTYPT)
02000 U TYOPT,1 ;INIT+17(TTYPT),TYOA+1(TTYPT),TOUTCL+3(TTYPT)
02100 TTYPT: XWD 440700,TTYBUF(R)
02200 U TTYBUF,25 ;INIT+20(0)
02300
00100 ;ROUTINE TO TYPE "? ERROR MESSAGE"
00200 ;CALL JSP A,ERRMES
00300 ; ASCIZ /ERROR MESSAGE/
00400 ; RETURN
00500 ;FROM PPA09,OUTERR,YANK09+2,INERR,ININER,LKUPER,ENTERR
00600
00700
00800 ERRMES: MOVEI CH,"?"
00900 PUSHJ P,TYO
01000
01100 ;ROUTINE TO TYPE "MESSAGE"
01200 ;CALL JSP A,CONMES
01300 ; ASCIZ /MESSAGE/
01400 ; RETURN
01500 ;FROM ININER+4,LKUPE1,LSTDIR+1
01600
01700 CONMES: HRLI A,440700
01800 ILDB CH,A
01900 JUMPE CH,1(A)
02000 PUSHJ P,TYO
02100 JRST .-3
02200
02300
02400 ;ROUTINE TO TYPE C(A) IN SIXBIT
02500 ;CALL MOVE A,[SIXBIT /MESSAGE/]
02600 ; PUSHJ P,SIXBMS
02700 ; RETURN
02800 ;FROM ININER+3,LKUPER+3,LKUPER+10
02900
03000
03100 SIXBMS: MOVNI B,6
03200 MOVE E,[XWD 440600,A]
03300 ILDB CH,E
03400 JUMPE CH,CPOPJ
03500 ADDI CH,40
03600 PUSHJ P,TYO
03700 AOJL B,.-4
03800 POPJ P,0
03900
04000 U STOPF,1
04100
04200 U INBUF,3 ;YANK3+2,OPNRD+14(SETZ IBUF1+1(R)),OPNRD+16,
04300 ;OPNRD+20,OPNRD+23
04400 U OUTBUF,3 ;PPA+2,OPNW1+12,OPNW1+13,OPNW1+22
04500
04600 U IBUF1,2*BUFSIZ+1
04700 U OBUF1,2*BUFSIZ+1
04800
00100 ;ROUTINE TO OUTPUT DECIMAL INTEGER
00200 ;CALL MOVE B, DECIMAL INTEGER
00300 ; MOVEI A,ADDRESS OF OUTPUT ROUTINE
00400 ; HRRM A,LISTF5(R)
00500 ; PUSHJ P,DPT
00600 ; RETURN
00700
00800 ;FROM PRNT+4,BAKSL1+4
00900
01000 DPT: JUMPGE B,.+3 ;NUMBER > 0?
01100 MOVEI CH,"-" ;NO. OUTPUT -
01200 PUSHJ P,@LISTF5(R)
01300 MOVMS B ;B:=ABSOLUTE VALUE OF B
01400 IDIVI B,12 ;E:=DIGIT
01500 HRLM E,(P) ;PUT DIGIT ON LEFT HALF OF TOP OF PUSH DOWN LIST
01600 JUMPE B,.+2 ;DONE?
01700 PUSHJ P,.-3 ;NO. PUSH THIS DIGIT AND PRINT RETURN ADDRESS.
01800 HLRZ CH,(P) ;YES. CH:=DIGIT
01900 ADDI CH,60 ;CONVERT IT TO ASCII.
02000 JRST @LISTF5(R) ;PRINT IT
02100
02200
02300
02400 ;ROUTINE TO TYPE CARRIAGE RETURN LINE FEED
02500 ;CALL PUSHJ P,CRR
02600 ; RETURN
02700 ;FROM GOX+1,LI4+11,CLIS,PRNT+5,ERR+3,GRTH+12
02800
02900 CRR: MOVEI CH,TYO ;SET OUTPUT DISPATCH TO TTY AND
03000 HRRM CH,LISTF5(R)
03100
03200 CRR1: MOVEI CH,15 ;OUTPUT CRLF
03300 PUSHJ P,@LISTF5(R)
03400 MOVEI CH,12
03500 JRST @LISTF5(R)
03600
00100 ;ROUTINE TO RETURN NEXT CHARACTER FROM COMMAND BUFFER AND ERROR IF EMPTY.
00200 ;CALL PUSHJ P,SKRCH
00300 ; RETURN WITH CHARACTER IN CH
00400 ;GOES TO ERR IF COMMAND BUFFER IS EMPTY
00500 ;FROM FILSPL,INSERT+10,SERCH2,SERCH2+12,EXCLAM,OGNF+5,UAR,FILS4L,FILS5L,COMMENT
00600
00700 SKRCH: SKIPN COMCNT(R) ;COMMAND BUFFER EMPTY?
00800 JSR ERR ;YES. SKRCH SHOULDN'T RUN OUT.
00900
01000 ;ROUTINE TO RETURN NEXT CHARACTER FROM COMMAND BUFFER.
01100 ;CALL PUSHJ P,RCH
01200 ; RETURN ALWAYS WITH CHARACTER IN CH
01300
01400 ;FROM CD5,INSERT+4,SERCH+4,QREG+1,DQUOTE+2,CNTRUP,ECMD
01500
01600 RCH: SOSGE COMCNT(R) ;DECREMENT COMMAND BUFFER CHARACTER COUNT
01700 ;IS COMMAND BUFFER EMPTY?
01800 JRST RCH2 ;YES. POP UP TO HIGHER MACRO LEVEL.
01900 ILDB CH,CPTR(R) ;NO. GET COMMAND CHARACTER IN CH
02000 XCT TRACS(R) ;RETURN OR JRST TYO IN TRACE MODE
02100 RCH2: POP P,CH ;SAVE RETURN FOR POPJ IN CH
02200 POP P,COMCNT(R) ;GET COUNT FROM NEXT MACRO LEVEL
02300 POP P,CPTR(R) ;POINTER TOO.
02400 POP P,COMAX(R) ;NUMBER OF COMMANDS.
02500 PUSH P,CH ;GET RETURN BACK ON PDL.
02600 JRST RCH ;TRY AGAIN.
02700
02800 U TRACS,1 ;INIT+26(POPJ P,),QUESTN+3
02900
03000 ;FROM NOGO+1,OG5+2,INCMA1
03100
03200 SKRCH1: SOSGE COMCNT(R) ;ANY CHARACTERS LEFT?
03300 JSR ERR ;NO. SUPPOSEDLY CAN'T RUN OUT OF
03400 ;COMMANDS AT THIS ROUTINE.
03500 ILDB CH,CPTR(R) ;YES. GET A CHARACTER.
03600 POPJ P, ;RETURN.
03700
00100 REPEAT 0,<
00200
00300 III. TYPING IN COMMANDS
00400 TECO INDICATES ITS READINESS TO ACCEPT COMMANDS BY TYPING
00500 AN ASTERISK (*). NEARLY ANY STRING OF CHARACTERS MAY BE TYPED IN.
00600 IF CAR RET IS TYPED, TECO IMAGINES THAT THE USER TYPED A LINE FEED
00700 FOLLOWING IT. ALL CHARACTERS TYPED IN ARE ECHOED BACK OUT BY TECO
00800 (INCLUDING THE IMAGINED LINE FEED) UNCHANGED EXCEPT AS FOLLOWS:
00900 (1) ALT MODE IS TYPED OUT AS $.
01000 (2) ON OUTPUT ONLY, CHARACTERS WHICH HAVE NO VISIBLE EFFECT
01100 AND ARE TYPED IN VIA THE CTRL SHIFT KEY COME OUT AS ↑
01200 FOLLOWED BY THE APPROPRIATE UN-CTRL CHARACTER.
01300 (3) RUBOUT DOES NOT GO IN, BUT INSTEAD ERASES THE LAST CHARACTER
01400 THAT DID GO IN. THIS ECHOES OUT THE CHARACTER THAT HAS
01500 JUST BEEN ERASED. RUBOUT MAY BE USED ANY NUMBER OF TIMES
01600 IN A ROW; IF THERE ARE NO CHARACTERS LEFT TO ERASE,
01700 RUBOUT ECHOES AS CARRIAGE RETURN---LINE FEED FOLLOWED BY
01800 AN ASTERISK.
01900 (4) TWO SUCCESSIVE ALT MODES INDICATE THE END OF THE STRING TYPED IN.
02000 WHEN THESE ARE ENCOUNTERED, TECO ECHOES THEM AS $S, TYPES
02100 CARRIAGE RETURN---LINE FEED, COPIES THE ENTIRE STRING OF
02200 CHARACTERS TYPED (EXCEPT THOSE ERASED) INTO THE COMMAND
02300 STRING AREA, AND STARTS TO INTERPRET AND PERFORM THESE
02400 NEW COMMANDS.
02500 (5) CTRL C RETURNS CONTROL TO THE TIME SHARING EXEC AT ONCE,
02600 WITHOUT WAITING FOR I/O TO FINISH.
02700 (6) TWO SUCCESSIVE CTRL G'S (BELL) WILL DELETE THE ENTIRE
02800 COMMAND STRING WITHOUT EXECUTING IT. TECO THEN
02900 TYPES RETURN-LINE FEED FOLLOWED BY AN ASTERISK.
03000 (7) THE COMMAND ↑G (BELL) WILL, WHEN PERFORMED, RETURN
03100 TO THE TIME SHARING EXEC BUT IT WILL HAVE WAITED
03200 FOR ALL TECO'S OUTPUT TO BE DONE.
03300 THE FORMAT IN WHICH TECO EXPECTS THESE COMMANDS, AND THE ACTIONS THEY
03400 DIRECT IT TO TAKE, COMPRISE THE BULK OF KNOWLEDGE THE USER SHOULD
03500 HAVE ABOUT TECO.
03600 >
00100 ;FROM LI3+21
00200
00300 CLIS: PUSHJ P,CRR ;TYPE CRLF
00400
00500 ;FROM GO1+3
00600
00700 LIS: MOVEI CH,"*"
00800 PUSHJ P,TYO ;TYPE *
00900 SETZM COMCNT(R) ;COMCNT:=0
01000 SETZM INTDPH(R) ;INTDPH:=0
01100 SETZM SYMS(R)
01200 MOVE T,[XWD SYMS,SYMS+1]
01300 IFN <R>,< ADD T,R>
01400 BLT T,SYMEND-1(R)
01500 MOVE AA,[XWD 700,CBUF-1(R)]
01600 MOVE B,CBUFH(R)
01700
01800 ;FROM LI3+26,LI5+1
01900
02000 LI1: TRZ FF,ALTF+BELLF
02100
02200 ;FROM LI4+3,LI5+3
02300
02400 LI2: CAILE B,(AA) ;COMMAND BUFFER EXCEEDED?
02500 JRST LI3 ;NO
02600 ADDI B,100 ;YES. EXPAND COMMAND BUFFER 100 WORDS.
02700 MOVE C,Z(R)
02800 IDIVI C,5 ;C:=DATA BUFFER END WORD ADDRESS.
02900 MOVE D,QRBUF(R)
03000 IDIVI D,5 ;D:=Q-REG BUFFER BASE WORD ADDRESS.
03100 SUBM C,D ;D:=NO. OF WORDS IN Q-REG BUFFER AND DATA BUFFER.
03200 MOVE CH,(C)
03300 MOVEM CH,100(C) ;MOVE Q-REG AND DATA BUFFERS UP 100 WORDS.
03400 SOS C
03500 SOJGE D,.-3
03600 MOVEI C,500
03700 ADDM C,BEG(R) ;BEG:=C(BEG)+500
03800 ADDM C,PT(R) ;PT:=C(PT)+500
03900 ADDM C,Z(R) ;Z:=C(Z)+500
04000 ADDM C,QRBUF(R) ;QRBUF:=C(QRBUF)+500
04100 MOVE D,Z(R)
04200 CAML D,MEMSIZ(R) ;HAVE BUFFERS EXCEEDED MEMORY CAPACITY?
04300 JRST GC1 ;YES. GARBAGE COLLECT.
00100
00200 ;FROM LI2+1
00300
00400 LI3: MOVEM B,CBUFH(R) ;NO. RESET HIGH END OF COMMAND BUFFER.
00500 PUSHJ P,TYI ;GET A NON-NULL CHARACTER IN CH
00600 CAIE CH,33 ;IS IT AN OLD ALT-MODE CODE?
00700 CAIN CH,176
00800 MOVEI CH,175 ;YES. CONVERT TO NEW ALT-MODE CODE.
00900 TRZE FF,QMFLG ;CLEAR ? FLAG. WAS IT ON?
01000 CAIE CH,"?" ;YES. IS THIS A "?"?
01100 AOSA COMCNT(R) ;NO. INCREMENT COMMAND CHARACTER COUNT
01200 JRST ERRTYP ;YES. TYPE BAD STRING
01300 IDPB CH,AA ;NO. STORE CHARACTER IN COMMAND BUFFER.
01400 CAIE CH,177 ;IS IT A RUBOUT?
01500 JRST LI4 ;NO.
01600
01700 ;DELETE A CHARACTER FROM THE COMMAND BUFFER.
01800 IBP AA ;YES. BACKUP BYTE POINTER TWO BYTES
01900 IBP AA
02000 IBP AA
02100 SOS D,AA
02200 CAMN AA,[XWD 100700+R,CBUF-1] ;DID IT GO PAST THE BEGINNING
02300 ;OF THE BUFFER
02400 JRST CLIS ;YES. TYPE *
02500 ILDB CH,D ;NO. TYPE DELETED CHARACTER
02600 PUSHJ P,TYO
02700 SOS COMCNT(R) ;REMOVE TWO CHARACTERS FROM COMMAND COUNT.
02800 SOS COMCNT(R)
02900 JRST LI1 ;AND GET ANOTHER COMMAND CHARACTER
03000
03100 ;FROM LI3+13
03200
03300 LI4: CAIE CH,175 ;ALT-MODE?
03400 JRST LI5 ;NO
03500 TRON FF,ALTF ;YES. SET ALT-MODE FLAG. WAS IT ON?
03600 JRST LI2 ;NO
03700 MOVEI CH,141 ;YES. TWO SUCCESSIVE ALT-MODES. END OF COMMAND.
03800 AOS A,COMCNT(R) ;MARK END OF COMMAND STRING WITH ASCII 141
03900 IDPB CH,AA
04000 MOVE AA,[XWD 700+R,CBUF-1] ;INITIALIZE COMMAND BYTE POINTER
04100 MOVEM AA,CPTR(R)
04200 PUSHJ P,CRR ;TYPE CRLF
04300 MOVEM A,COMAX(R) ;SET COMMAND CHARACTER ADDRESS UPPER BOUND
04400 JRST CD ;DECODE COMMAND
04500
00100 ;FROM LI4+1
00200
00300 LI5: CAIE CH,7 ;BELL?
00400 JRST LI1 ;NO. GET MORE CHARACTERS.
00500 TRON FF,BELLF ;YES. SET BELL FLAG. TWO SUCCESSIVE BELLS?
00600 JRST LI2 ;NO.
00700 JRST GOX ;YES. CLEAR COMMAND BUFFER.
00800
00100
00200 REPEAT 0,<
00300
00400 IV. QUANTITIES
00500 MANY TECO COMMANDS TAKE ARGUMENTS WITH NUMERIC VALUES, AND SOME
00600 COMMANDS TAKE DIFFERENT ACTION DEPENDING ON WHETHER ARGUMENTS ARE
00700 GIVEN OR NOT. THE FOLLOWING CHARACTERS MAY APPEAR IN COMMAND STRINGS TO
00800 DEVELOP NUMERIC VALUES. FURTHERMORE, SOME COMMANDS, BESIDES DIRECTING
00900 ACTION ON TECO'S PART, HAVE A NUMERIC VALUE THEMSELVES AND SO MAY ACT
01000 AS AN ARGUMENT TO A SUBSEQUENT COMMAND. IF A COMMAND MAY HAVE A VALUE,
01100 THIS WILL BE STATED IN ITS DESCRIPTION. IN ALL COMMAND DESCRIPTIONS,
01200 $ MEANS ALT-MODE AND ↑X MEANS X WITH THE CTRL KEY HELD. ALL CTRL
01300 CHARACTERS WHICH ARE TO BE INTERPRETED AS COMMANDS MAY BE TYPED IN BY
01400 TYPING UP ARROW ↑ FOLLOWED BY THE CORRESPONDING PRINTING CHARACTER.
01500
01600 0-9 DIGITS FORM DECIMAL INTEGERS.
01700 B =0 (I.E. RETURNS THE NUMERIC VALUE 0).
01800 Z =NUMBER OF CHARACTERS IN THE BUFFER.
01900 . =NUMBER OF CHARACTERS TO LEFT OF THE POINTER.
02000 QI (WHERE I IS A DIGIT OR LETTER) = NUMERIC VALUE MOST
02100 RECENTLY PUT INTO Q-REGISTER NAMED I.
02200 NA (WHERE N IS A NUMERIC ARGUMENT) = VALUE IN 7-BIT ASCII OF
02300 THE CHARACTER TO THE RIGHT OF THE POINTER.
02400 ↑H HAS THE VALUE OF ELAPSED TIME, IN 60THS OF A SECOND, SINCE MIDNITE.
02500 ↑F HAS THE VALUE OF THE CONSOLE DATA SWITCHES.
02600 ↑↑ HAS THE VALUE OF THE NEXT CHARACTER IN THE COMMAND STRING.
02700 ↑T CAUSES COMMAND INTERPRETATION TO STOP UNTIL THE USER
02800 TYPES A CHARACTER ON THE TELETYPE AND THEN HAS THE
02900 ASCII VALUE OF THE CHARACTER TYPED IN.
03000 \ HAS THE VALUE OF THE NUMBER REPRESENTED BY THE DIGITS
03100 (OR MINUS SIGN) FOLLOWING THE POINTER IN THE BUFFER.
03200 THE SCAN TERMINATES ON ANY OTHER CHARACTER. THE POINTER
03300 IS MOVED OVER THE NUMBER FOUND (IF ANY).
03400 M+N ADD TAKES 1 OR 2 ARGUMENTS. SPACE IS EQUIVALENT TO +.
03500 M-N SUBTRACT TAKES 1 OR 2 ARGUMENTS.
03600 M*N MULTIPLY TAKES 2 ARGUMENTS.
03700 M/N DIVIDE (TRUNCATES) TAKES 2 ARGUMENTS.
03800 M&N LOGICAL AND: BITWISE AND OF BINARY REPRESENTATION OF M
03900 AND N.
04000 M#N LOGICAL IOR: BITWISE INCLUSIVE OR OF BINARY REPRESENTATION
00100 OF M AND N.
00200
00300 OPERATORS +,-,*,/,# AND & ARE PERFORMED FROM LEFT TO RIGHT.
00400 THIS MAY BE OVERRULED BY USE OF
00500 ( ) NUMERIC PARENTHESIS.
00600 N= CAUSES THE VALUE OF N TO BE TYPED OUT.
00700 NUI PUTS QUANTITY N IN Q-REGISTER NAMED I.
00800 M,N IF A COMMAND TAKES TWO NUMERIC ARGUMENTS, COMMA IS USED TO
00900 SEPARATE THEM.
01000 H AN ABBREVIATION FOR B,Z WHICH IS A FREQUENTLY USED PAIR
01100 OF ARGUMENTS FOR COMMANDS.
01200 >
00100 ;FROM LI4+15,CD9(↑J,↑M,',W),ALTMOD+5,INCMA
00200
00300 CD:
00400
00500 ;FROM CD6+10,OPEN+6,APPEND+4,JMP1+2,KILL+4,JRET,COLON+1,FND+6,
00600 ;FND1+1,USEA+2,NOGO+5,EXCLAM+3,DQT1+1,OG3+4,OGFND+4,QUESTN+4,BAKSL1+12,
00700 ;OPENB+6,INCMA2+3,LSSTH1+1,LINE+4,QGET1
00800
00900 RET: TRZ FF,ARG2+ARG+FINDR+PCHFLG
01000
01100 ;FROM COMMA+4
01200
01300 CD1: SETZM NUM(R)
01400
01500 ;CD9(SPACE,+),OPENB+5
01600 ;ADD TAKES ONE OR TWO ARGUMENTS
01700
01800 CD2: MOVSI A,270000+B*40+R ;DELIM:=ADD B,(R)
01900
02000 ;FROM CAND+1,COR+1,MINUS+1,TIMES+1,SLASH+1
02100
02200 CD3: HLLM A,DLIM(R)
02300 CD4: SETZM SYL(R)
02400
02500 ;FROM CD7+1,MAC+31
02600
02700 CD5:
02800 PUSHJ P,RCH
02900 TRZ FF,FINF
03000 CD9: XCT DTB(CH) ;A:=XWD VALUE FLAG,DISPATCH ADDRESS
03100 ;OR DISPATCH DIRECTLY
03200 CD6: MOVE B,NUM(R)
03300 TRZE FF,SYLF ;DID LAST CHARACTER RETURN A VALUE OR WAS IT A DIGIT?
03400 XCT DLIM(R) ;YES. NUM:=NUM (DLIM OPERATOR) SYL
03500 MOVEM B,NUM(R)
03600 MOVE C,SARG(R) ;SAVE SECOND ARGUMENT IN C.
03700 TRZ FF,NOTF
03800 JUMPGE A,(A) ;DISPATCH IF VALUE RETURN COMMAND.
03900 PUSHJ P,(A) ;DISPATCH FOR NON-VALUE RETURN COMMANDS.
04000 JRST RET
04100
04200
04300
04400 U DLIM,1 ;INIT+41(SYL),CD3,CLOSE+4
04500 U NUM,1 ;CD1(0),CD6+3,CLOSE+10,APPND2(0),SERCH+1(0)
04600 U SYL,1 ;CD4(0),VALRET,CLOSE+2,BAKSLA+11,BAKSLA+13,BAKSL2+1
04700 U SARG,1 ;COMMA,HOLE(0)
00100 ;CD9(0,1,2,3,4,5,6,7,8,9)
00200 ;DIGITS FORM DECIMAL INTEGERS.
00300
00400 CDNUM: MOVE A,SYL(R)
00500 IMULI A,12
00600 ADDI A,-60(CH)
00700
00800 ;SOME COMMANDS HAVE A NUMERIC VALUE
00900 ;FROM END1+2,APPND2+1,FND+10,BEGIN+1,PCNT+2,CNTRUP+2,GTIME+1,LAT+1
01000
01100 VALRET: MOVEM A,SYL(R)
01200
01300 ;FROM CLOSE+11,BAKSL2+3
01400
01500 CD7: TRO FF,ARG+SYLF
01600 JRST CD5
01700
01800
01900 ;CD9(ALT-MODE)
02000
02100 ALTMOD: MOVE T,CPTR(R) ;IF NEXT COMMAND CHARACTER IS ALT-MODE,
02200 ;OR END OF COMMAND BUFFER, GO;ELSE CD.
02300 ILDB CH,T
02400 CAIE CH,175
02500 CAIN CH,141
02600 JRST GO
02700 JRST CD
02800
02900
03000 ;CD9(↑)
03100 ;↑ MEANS THAT THE NEXT CHARACTER IS A CONTROL CHARACTER.
03200
03300 UAR: PUSHJ P,SKRCH ;GET NEXT COMMAND CHARACTER.
03400 TRZ CH,100 ;CHANGE IT TO CONTROL CHARACTER
03500 JRST CD9 ;DISPATCH
03600
03700
03800
03900 ;CD9(↑G)
04000 ;FINISH OUTPUT AND RETURN TO THE TIME-SHARING EXEC.
04100
04200 DECDMP: CALLI EXIT
04300
00100 ;CD9(,)
00200 ;IF A COMMAND TAKES TWO NUMERIC ARGUMENTS, COMMA IS USED TO SEPARATE THEM
00300
00400 COMMA: MOVEM B,SARG(R) ;SAVE CURRENT ARGUMENT IN SARG.
00500 TRZE FF,ARG ;WAS THERE A CURRENT ARGUMENT?
00600 TROE FF,ARG2 ;YES. WAS THERE ALREADY A SECOND ARGUMENT?
00700 JSR ERR ;NO. EITHER NO ARGUMENT OR MORE THAN TWO ARGUMENTS.
00800 JRST CD1 ;YES. CLEAR CURRENT ARGUMENT.
00900
01000 ;CD9(&)
01100 ;LOGICAL AND
01200
01300 CAND: MOVSI A,404000+B*40+R ;DLIM:=AND B,(R)
01400 JRST CD3
01500
01600 ;CD9(#)
01700 ;LOGICAL OR
01800
01900 COR: MOVSI A,43400+B*40+R ;DLIM:=OR B,(R)
02000 JRST CD3
02100
02200 ;CD9(-)
02300 ;SUBTRACT TAKES ONE OR TWO ARGUMENTS
02400
02500 MINUS: MOVSI A,274000+B*40+R ;DLIM:=SUB B,(R)
02600 JRST CD3
02700
02800 ;CD9(*)
02900 ;MULTIPLY TAKES TWO ARGUMENTS
03000
03100 TIMES: MOVSI A,220000+B*40+R ;DLIM:=IMUL B,(R)
03200 JRST CD3
03300
03400 ;CD9(/)
03500 ;DIVIDE (TRUNCATES) TAKES TWO ARGUMENTS
03600
03700 SLASH: MOVSI A,230000+B*40+R ;DLIM:=IDIV B,(R)
03800 JRST CD3
03900
00100 ;CD9(B)
00200 ;RETURNS THE NUMERIC VALUE 0.
00300
00400 BEGIN: MOVEI A,0
00500 JRST VALRET
00600
00700
00800 ;CD9(H)
00900 ;AN ABBREVIATION FOR B,Z
01000
01100 HOLE: SETZM SARG(R) ;SET SECOND ARGUMENT TO 0.
01200 TROA FF,ARG2
01300
01400 ;CD9(.)
01500 ;.=NUMBER OF CHARACTERS TO THE LEFT OF THE POINTER
01600
01700 PNT: SKIPA A,PT(R)
01800
01900 ;CD9(Z)
02000 ;Z=NUMBER OF CHARACTERS IN THE BUFFER
02100
02200 END1: MOVE A,Z(R)
02300 SUB A,BEG(R)
02400 JRST VALRET
02500
02600 ;CD9(()
02700 ;() MAY BE USED TO OVERRIDE LEFT TO RIGHT OPERATOR SCAN FOR +,-,*,/,& AND #.
02800
02900 OPEN: PUSH P,NUM(R) ;PUSH CURRENT ARGUMENT.
03000 HLLZ A,DLIM(R) ;GET CURRENT OPERATOR.
03100 TRZE FF,ITERF ;ARE WE INSIDE AN ITERATION?
03200 IORI A,1 ;YES. MARK OPERATOR AS BEING WITHIN AN ITERATION.
03300 PUSH P,A ;PUSH CURRENT OPERATOR.
03400 AOS LEV(R) ;INCREMENT ( LEVEL.
03500 JRST RET
03600
03700 ;CD9())
03800 CLOSE: SOSGE LEV(R) ;IS THERE A (?
03900 JSR ERR ;NO.
04000 MOVEM B,SYL(R) ;YES. SAVE CURRENT ARGUMENT.
04100 POP P,CH ;RESTORE OPERATOR.
04200 HLLM CH,DLIM(R)
04300 TRZ FF,ITERF
04400 TRNE CH,1
04500 TRO FF,ITERF ;RESTORE ITERATION FLAG FOR THIS OPERATOR.
04600 POP P,NUM(R) ;RESTORE ARGUMENT.
04700 JRST CD7
04800
04900
05000
05100
05200 U LEV,1 ;GO1(0),OPEN+5,CLOSE
00100 ;CD9(=)
00200 ;N= CAUSES THE VALUE OF N TO BE TYPED OUT.
00300
00400 PRNT: TRNN FF,ARG ;HERE ON "=" COMMAND
00500 JSR ERR ;MUST HAVE ARG
00600 MOVEI A,TYO
00700 HRRM A,LISTF5(R) ;CONSOLE
00800 PUSHJ P,DPT
00900 JRST CRR ;CRLF AND RETURN TO CALLER
01000
01100
01200
01300 ;CD9(↑T)
01400 ;CAUSES COMMAND INTERPRETATION TO STOP UNTIL THE USER TYPES A CHARACTER
01500 ;ON THE TELETYPE AND THEN HAS THE ASCII VALUE OF THE CHARACTER TYPED IN.
01600
01700
01800 SPTYI: PUSHJ P,TYI
01900 SKIPA A,CH
02000
02100
02200 ;CD9(↑H)
02300 ;HAS THE VALUE OF ELAPSED TIME, IN 60THS OF A SECOND, SINCE MIDNITE.
02400
02500 GTIME: CALLI A,TIMER
02600 JRST VALRET
02700
02800
02900 ;CD9(↑F)
03000 ;HAS THE VALUE OF THE CONSOLE DATA SWITCHES.
03100
03200 LAT: CALLI A,SWITCH
03300 JRST VALRET
03400
03500
03600
03700 ;CD9(↑↑)
03800 ;HAS THE VALUE OF THE NEXT CHARACTER IN THE COMMAND STRING.
03900
04000 CNTRUP: PUSHJ P,RCH ;↑↑ HAS VALUE OF CHAR FOLLOWING IT
04100 MOVE A,CH
04200 JRST VALRET
04300
04400
04500
00100 ;CD9(BACKSLASH)
00200 ;HAS THE VALUE OF THE NUMBER REPRESENTED BY THE DIGITS (OR MINUS SIGN)
00300 ;FOLLOWING THE POINTER IN THE BUFFER. THE SCAN TERMINATES ON ANY OTHER
00400 ;CHARACTER. THE POINTER IS MOVED OVER THE NUMBER FOUND (IF ANY).
00500
00600
00700 BAKSL: TRZE FF,ARG ;WHICH KIND OF BACKSLASH?
00800 JRST BAKSL1 ;ARG TO MEMORY
00900 MOVE IN,PT(R) ;MEMORY TO VALRET
01000 BAKSLA: CAML IN,Z(R) ;OVERDID IT ?
01100 JRST BAKSL3 ;YES. EXIT
01200 PUSHJ P,GETINC ;NO. GET A CHAR
01300 CAIN CH,"-" ;MINUS SIGN?
01400 JRST BAKSLM ;YES. GO MARK IT.
01500 CAIG CH,"9" ;DIGIT?
01600 CAIGE CH,"0" ;DIGIT?
01700 SOJA IN,BAKSL2 ;NOT A DIGIT. BACKUP AND LEAVE LOOP
01800 SUBI CH,"0" ;CONVERT TO NUMBER
01900 EXCH CH,SYL(R)
02000 IMULI CH,12
02100 ADDM CH,SYL(R) ;SYL:= 10.*SYL+CH
02200 JRST BAKSLA ;LOOP
02300
02400 BAKSL3: MOVE IN,Z(R) ;HERE ON OVERFLOW
02500 BAKSL2: TRZE FF,ARG ;MINUS SIGN SEEN?
02600 MOVNS SYL(R) ;YES. NEGATE
02700 MOVEM IN,PT(R) ;MOVE POINTER PAST #
02800 JRST CD7 ;DONE
02900
03000
03100 BAKSLM: TRO FF,ARG
03200 JRST BAKSLA
03300
03400
03500
03600
03700 ;CD9(A)
03800 ;NA (WHERE N IS A NUMERIC ARGUMENT) = VALUE IN 7-BIT ASCII OF THE
03900 ;CHARACTER TO THE RIGHT OF THE POINTER.
04000
04100 ACMD: TRNN FF,ARG ;DOES AN ARGUMENT PRECEED A?
04200 JRST APPEND ;NO. THIS IN AN APPEND COMMAND.
04300 MOVE IN,PT(R) ;YES.
04400 PUSHJ P,GET ;CH:=CHARACTER TO THE RIGHT OF PT.
04500 MOVE A,CH ;RETURN CH AS VALUE.
04600 APPND2: SETZM NUM(R)
04700 JRST VALRET
00100 REPEAT 0,<
00200
00300 V. USE OF Q-REGISTERS
00400
00500 NUI PUTS THE NUMERIC VALUE N IN Q-REGISTER NAMED I (WHERE I IS
00600 A CHARACTER 0,1,...,9,A,B,...,Z.)
00700 QI HAS THE VALUE OF THE LATEST QUANTITY PUT INTO Q-REGISTER I.
00800 %I ADDS 1 TO THE QUANTITY IN Q-REGISTER I AND STANDS FOR THE NEW VALUE.
00900 M,NXI COPIES A PORTION OF THE BUFFER INTO Q-REGISTER I. IT SETS
01000 Q-REGISTER I TO A DUPLICATE OF THE (M+1)TH THROUGH NTH CHARACTERS
01100 IN THE BUFFER. THE BUFFER IS UNCHANGED. (FOR EXAMPLE: HXA
01200 PUTS A REPLICA OF THE ENTIRE BUFFER INTO Q-REGISTER A.)
01300 NXI INTO Q-REGISTER I IS COPIED THE STRING OF CHARACTERS STARTING
01400 IMMEDIATELY TO THE RIGHT OF THE POINTER AND PROCEEDING THROUGH
01500 THE NTH LINE FEED.
01600 GI THE TEXT IN Q-REGISTER I IS INSERTED INTO THE BUFFER AT THE CURRENT
01700 LOCATION OF THE POINTER. THE POINTER IS THEN PUT JUST TO THE RIGHT
01800 OF THE INSERTION. THE Q-REGISTER IS NOT CHANGED.
01900 [I PUSHES Q-REGISTER I ONTO THE Q-REGISTER PUSHDOWN LIST.
02000 ]I POPS Q-REGISTER I OFF THE Q-REGISTER PUSHDOWN LIST. THE
02100 Q-REGISTER PUSHDOWN LIST IS CLEARED EACH TIME $$ IS TYPED.
02200
02300 IT DOES NOT MAKE SENSE TO TECO TO "G" A Q-REGISTER GIVEN A
02400 NUMBER BY "U" NOR TO "Q" OR "%" ONE GIVEN TEXT BY "X".
02500 >
02600 ;CD9(U)
02700 ;NUI PUTS THE NUMERIC VALUE N IN Q-REGISTER I.
02800
02900 USE: TRNN FF,ARG ;DID AN ARGUMENT PRECEED U?
03000 JSR ERR ;NO.
03100
03200 ;FROM X2+4
03300
03400 USEA: PUSHJ P,QREGVI ;YES. CH:=Q-REGISTER INDEX.
03500 MOVEM B,QTAB-"0"(CH) ;STORE ARGUMENT IN SELECTED Q-REG.
03600 JRST RET
03700
03800 ;CD9(Q)
03900 ;QI HAS THE VALUE OF THE LATEST QUANTITY PUT INTO Q-REGISTER I.
04000
04100 QREG: PUSH P,USE1 ;SET RETURN ADDRESS TO VALRET AND FALL INTO QREGVI.
04200
04300 ;ROUTINE TO RETURN Q-REGISTER INDEX IN CH AND CONTENT IN A.
04400 ;CALL PUSHJ P,QREGVI
04500 ; RETURN
04600 ;ASSUMES COMCNT,CPTR AND COMAX ARE SET UP.
04700 ;IF NEXT CHARACTER IN COMMAND STRING IS NOT A LETTER OR A DIGIT, DOES NOT RETURN.
04800 ;FROM USEA,PCNT,OPENB+1,MAC,QGET
04900
05000 QREGVI: PUSHJ P,RCH ;CH:=NEXT COMMAND STRING CHARACTER.
05100 CAIL CH,"0" ;LETTER OR DIGIT?
05200 CAILE CH,"Z"
05300 JSR ERR ;NO
05400 CAIL CH,1+"9" ;YES. DIGIT?
05500 SUBI CH,"A"-"9"-1 ;NO. TRANSLATE LETTERS DOWN BY NUMBER OF
05600 ;CHARACTERS BETWEEN 9 AND A. ONLY 36 Q REG'S
05700 MOVE A,QTAB-"0"(CH) ;A:=CONTENTS OF Q-REGISTER.
05800 USE1: POPJ P,VALRET
05900
06000
06100 ;CD9(%)
06200 ;%I ADDS 1 TO THE QUANTITY IN Q-REGISTER I AND STANDS FOR THE
06300 ; NEW VALUE
06400
06500 PCNT: PUSHJ P,QREGVI ;CH:=Q-REGISTER INDEX.
06600 AOS A,QTAB-"0"(CH) ;INCREMENT Q-REG.
06700 JRST VALRET ;RETURN NEW VALUE.
06800
00100 ;CD9(X)
00200 ;M,NXI COPIES A PORTION OF THE BUFFER INTO Q-REGISTER I.
00300 ; IT SETS Q-REGISTER I TO A DUPLICATE OF THE (M+1)TH
00400 ; THROUGH NTH CHARACTERS IN THE BUFFER. THE BUFFER IS UNCHANGED.
00500 ;NXI INTO Q-REGISTER I IS COPIED THE STRING OF CHARACTERS STARTING
00600 ; IMMEDIATELY TO THE RIGHT OF THE POINTER AND PROCEEDING THROUGH
00700 ; THE NTH LINE FEED.
00800
00900 X: PUSHJ P,GETARG ;C:=FIRST STRING ARGUMENT ADDRESS
01000 ;B:=SECOND STRING ARGUMENT ADDRESS.
01100 CAMLE C,B ;IS SECOND ARG. ADDR. > FIRST ARG. ADDR.?
01200 JSR ERR ;NO.
01300 EXCH B,C ;YES.
01400 SUBI C,-3(B) ;C:=LENGTH OF STRING+3.
01500 ADD B,C ;B:=FIRST ARG ADDR + LENGTH OF STRING + 3
01600 PUSH P,PT(R)
01700 ADDM C,(P) ;(P):=PT + LENGTH OF STRING + 3.
01800 MOVE D,BEG(R)
01900 MOVEM D,PT(R) ;PT:=BEG
02000 PUSHJ P,NROOM ;INSERT STRING AT BEG
02100 MOVE OUT,RREL(R) ;RREL CONTAINS RELOCATION CONSTANT IF
02200 ;GARBAGE COL. OCCURRED.
02300 ADDM OUT,(P) ;RELOCATE TOP OF STRING POINTER.
02400 ADD B,OUT ;B:=FIRST ARG ADDR + LENGTH OF STRING + 3 + RREL
02500 MOVE OUT,BEG(R) ;OUT:=ADDRESS OF Q-REG BUFFER
02600 ADDM C,BEG(R) ;BEG:=C(BEG)+LENGTH OF STRING + 3
02700 MOVEI CH,141 ;FIRST CHARACTER OF BUFFER := 141
02800 PUSHJ P,PUT
02900 AOS OUT
03000 MOVE CH,C ;SECOND CHAR OF BUFFER :=LEAST SIGNIFICANT 7 BITS
03100 ;OF LENGTH OF STRING + 3
03200 PUSHJ P,PUT
03300 ROT CH,-7
03400 MOVE IN,B ;THIRD CHAR OF BUFFER := MOST SIGNIFICANT 7 BITS
03500 ;OF LENGTH OF STRING + 3
03600 AOS OUT
03700 X1: PUSHJ P,PUT ;MOVE STRING TO Q-REG BUFFER.
03800 AOS OUT
03900 CAIN C,3
04000 JRST X2
04100 PUSHJ P,GETINC
04200 SOJA C,X1
04300 X2: MOVE B,PT(R) ;QTAB ENTRY :=XWD 400000,Q-REG BUFFER
04400 ;ADDRESS RELATIVE TO C(QRBUF)
04500 SUB B,QRBUF(R)
04600 TLO B,400000
04700 POP P,PT(R) ;MOVE PT PAST STRING.
04800 JRST USEA ;MAKE QTAB ENTRY.
04900
00100 ;CD9(G)
00200 ;GI THE TEXT IN Q-REGISTER I IS INSERTED INTO THE BUFFER AT THE
00300 ; CURRENT LOCATION OF THE POINTER. THE POINTER IS THEN PUT JUST
00400 ; TO THE RIGHT OF THE INSERTION. THE Q-REGISTER IS NOT CHANGED.
00500
00600 QGET: PUSHJ P,QREGVI ;A:=QTAB ENTRY, CH:=Q-REG INDEX
00700 MOVE B,A
00800 TLZN B,377777 ;DOES Q-REG CONTAIN TEXT?
00900 TLZN B,400000
01000 JSR ERR ;NO
01100 ADD B,QRBUF(R) ;YES
01200 MOVE IN,B ;IN:=Q-REG BUFFER ADDRESS
01300 MOVE B,CH ;SAVE INDEX
01400 PUSHJ P,GETINC ;IS FIRST CHARACTER IN BUFFER 141?
01500 CAIE CH,141
01600 JSR ERR ;NO
01700 PUSHJ P,GETINC ;C:=LENGTH OF STRING
01800 MOVEM CH,C
01900 PUSHJ P,GETINC
02000 ROT CH,7
02100 IORM CH,C
02200 SUBI C,3
02300 PUSHJ P,NROOM ;MOVE FROM PT THROUGH Z UP C POSITIONS
02400 MOVE OUT,PT(R)
02500 HRRZ IN,QTAB-"0"(B)
02600 ADD IN,QRBUF(R)
02700 ADDI IN,3
02800 QGET1: JUMPE C,RET ;MOVE STRING INTO DATA BUFFER
02900 PUSHJ P,GETINC
03000 PUSHJ P,PUT
03100 AOS OUT,PT(R)
03200 SOJA C,QGET1
03300
00100 ;CD9(])
00200 ;]I POPS Q-REGISTER I OFF THE Q-REGISTER PUSHDOWN LIST.
00300 ; THE Q-REGISTER PUSHDOWN LIST IS CLEARED EACH TIME $$ IS TYPED.
00400
00500 CLOSEB: SKIPA C,[POP PF,]
00600
00700 ;CD9([)
00800 ;[I PUSHES Q-REGISTER I ONTO THE Q-REGISTER PUSHDOWN LIST.
00900
01000 OPENB: MOVSI C,261000+PF*40+R
01100 PUSHJ P,QREGVI
01200 HRRI C,QTAB-"0"(CH) ;C:=Q-REGISTER INDEX.
01300 XCT C ;PUSH OR POP Q-REGISTER.
01400 TRNE FF,ARG ;IS THERE AN ARGUMENT?
01500 JRST CD2 ;YES. DON'T DESTROY IT.
01600 JRST RET ;NO. CLEAR FLAGS.
01700
00100 REPEAT 0,<
00200
00300 VI INPUT-OUTPUT SELECTION
00400
00500 ERDEV:NAME.EXT[PROJNO,PROGNO]$
00600 SELECTS THE INPUT DEVICE, WHERE
00700 DEV: IS THE DEVICE NAME, SUCH AS DTA6 OR PTR
00800 NAME: IS THE NAME (IF ANY) OF THE FILE
00900 EXT IS THE FILE NAME EXTENSION (IF ANY)
01000 PROJNO,PROGNO ARE THE PROJECT AND PROGRAMMER NUMBERS
01100 ASSOCIATED WITH THE FILE IN A SYSTEM WITH A DISC.
01200 EWDEV:NAME.EXT[PROJNO,PROGNO]$
01300 SELECTS THE OUTPUT DEVICE AND OPENS THE FILE SPECIFIED (IF ANY).
01400 EZDEV:NAME.EXT[PROJNO,PROGNO]$
01500 SELECTS THE OUTPUT DEVICE, ISSUES A REWIND COMMAND TO IT,
01600 ISSUES A COMMAND TO ZERO ITS DIRECTORY, AND OPENS THE
01700 FILE SPECIFIED (IF ANY).
01800 EF FINISHES OUTPUT ON THE CURRENT OUTPUT FILE WITHOUT
01900 SELECTING A NEW OUTPUT FILE.
02000
02100 EM REWINDS THE CURRENTLY SELECTED INPUT DEVICE.
02200 NEM EXECUTES THE MTAPE UUO ON THE CURRENTLY SELECTED INPUT DEVICE
02300 USING N AS THE ADDRESS FIELD OF THE MTAPE. NOTE THAT N, AS
02400 USUAL, IS A DECIMAL NUMBER.
02500 >;CD9(E)
02600 ;E COMMANDS SELECT AND CONTROL FILE INPUT-OUTPUT MEDIA
02700
02800 ECMD: PUSHJ P,RCH
02900 CAIN CH,"R" ;NO. ER?
03000 JRST OPNRD ;YES. NEW INPUT FILE.
03100 CAIN CH,"W" ;NO. EW?
03200 JRST OPNWR ;YES. NEW OUTPUT FILE.
03300 CAIN CH,"F" ;NO. EF?
03400 JRST CLOSEF ;YES. CLOSE OUTPUT FILE.
03500 CAIN CH,"Z" ;NO. EZ?
03600 JRST ZERDIR ;YES. CLEAR DIRECTORY.
03700 CAIN CH,"M" ;NO. EM?
03800 JRST EMTAPE ;YES. EXECUTE MTAPE UUO.
03900 JSR ERR ;NO. COMMAND ERROR.
04000
04100
04200
04300
04400
04500
04600
04700
04800 U FILDEV,1 ;FILSPC+1(0),FILSP1+1
04900 U FILNAM,4 ;NAME IN SIXBIT. FILSPC+2(0),FILLS1+5
05000 ;(EXT)BLK #. FILSPC+3(0),FILLS1+2
05100 ;PROT,DATE. FILSPC+4(0)
05200 ;(PROJ)PROG. FILSPC+5(0),FILSPS,FILSP6
05300
00100 ;ER PREPARE TO READ FILE
00200 ;FROM ECMD+4
00300
00400 OPNRD: TLOE FF,UREAD ;SET INPUT FILE OPEN FLAG. WAS IT ON?
00500 RELEAS INCHN,0 ;YES. RELEASE IT BEFORE OPENING NEW FILE.
00600 PUSHJ P,FILSPC ;GET FILE SPEC
00700 MOVEI E,1
00800 MOVEM E,OPNRI(R)
00900 MOVE E,FILDEV(R) ;INITIALIZE OPEN UUO ARGUMENTS
01000 MOVEM E,OPNR1(R)
01100 MOVEI E,INBUF
01200 MOVEM E,OPNRB(R)
01300 OPEN INCHN,OPNRI(R) ;OPEN INPUT FILE
01400 JRST ININER
01500 MOVE E,[SETZ IBUF1+1(R)]
01600 MOVEM E,INBUF(R)
01700 MOVSI E,440700
01800 MOVEM E,INBUF+1(R)
01900 MOVE T,JOBFF(R)
02000 MOVEI E,IBUF1
02100 MOVEM E,JOBFF(R)
02200 INBUF INCHN,2
02300 MOVEM T,JOBFF(R)
02400 SETZM INBUF+2(R)
02500 LOOKUP INCHN,FILNAM(R)
02600 JRST LKUPER
02700 POPJ P,
02800
02900
03000 U OPNRI,1 ;INPUT FILE OPEN ARGUMENTS. OPNRD+4(1)
03100 U OPNR1,1 ;INPUT DEVICE. INIT+27(0),OPNRD+6
03200 U OPNRB,1 ;INITIALIZE TO XWD 0,INBUF. OPNRD+10
00100
00200 ;FROM OPNRD+10,OPNW1+10
00300
00400 ININER: JSP A,ERRMES
00500 ASCIZ /DEVICE /
00600 MOVE A,FILDEV(R)
00700 PUSHJ P,SIXBMS
00800 JSP A,CONMES
00900 ASCIZ / NOT AVAILABLE
01000 /
01100 JSR ERR
01200
01300
01400
01500 ;FROM OPNRD+24
01600
01700 LKUPER: JSP A,ERRMES
01800 ASCIZ /FILE /
01900 MOVE A,FILNAM(R)
02000 PUSHJ P,SIXBMS
02100 HLLZ A,FILNAM+1(R)
02200 JUMPE A,LKUPE1
02300 MOVEI CH,"."
02400 PUSHJ P,TYO
02500 PUSHJ P,SIXBMS
02600 LKUPE1: JSP A,CONMES
02700 ASCIZ / NOT FOUND
02800 /
02900 JSR ERR
03000
00100 ;EW SELECTS THE OUTPUT DEVICE AND OPENS THE FILE SPECIFIED (IF ANY)
00200 ;FROM ECMD+6
00300
00400 OPNWR: PUSHJ P,OPNW1
00500
00600 ;FROM ZERDIR+3
00700
00800 OPNW2: ENTER OUTCHN,FILNAM(R)
00900 JRST ENTERR
01000 POPJ P,
01100
01200
01300 ;FROM OPNWR,ZERDIR
01400
01500 OPNW1: TLOE FF,UWRITE
01600 RELEAS OUTCHN,0
01700 PUSHJ P,FILSPC
01800 MOVEI E,1
01900 MOVEM E,OPNWI(R)
02000 MOVE E,FILDEV(R)
02100 MOVEM E,OPNWD(R)
02200 HRLZI E,OUTBUF
02300 MOVEM E,OPNWB(R)
02400 OPEN OUTCHN,OPNWI(R)
02500 JRST ININERR
02600 MOVE E,[SETZ OBUF1+1(R)]
02700 MOVEM E,OUTBUF(R)
02800 MOVSI E,440700
02900 MOVEM E,OUTBUF+1(R)
03000 MOVE T,JOBFF(R)
03100 MOVEI E,OBUF1
03200 MOVEM E,JOBFF(R)
03300 OUTBUF OUTCHN,2
03400 MOVEM T,JOBFF(R)
03500 SETZM OUTBUF+2(R)
03600 POPJ P,0
03700
03800 U OPNWI,1 ;OUTPUT FILE OPEN ARGUMENTS. OPNW1+4(1)
03900 U OPNWD,1 ;OUTPUT DEVICE. OPNW1+6
04000 U OPNWB,1 ;OUTBUT BUFFER HEADER ADDRESS. OPNW1+10(OUTBUF)
04100
04200
04300
00100 ;FROM OPNW2+1
00200
00300 ENTERR: JSP A,ERRMES
00400 ASCIZ /DIRECTORY FULL ON OUTPUT
00500 /
00600 JSR ERR
00700
00800
00900
01000 ;EZ SELECTS THE OUTPUT DEVICE, ISSUES A REWIND COMMAND TO IT,
01100 ; ISSUES A COMMAND TO ZERO ITS DIRECTORY, AND OPENS THE FILE
01200 ; SPECIFIED (IF ANY).
01300 ;FROM ECMD+12
01400
01500 ZERDIR: PUSHJ P,OPNW1 ;DETERMINE OUTPUT DEVICE
01600 CALLI OUTCHN, UTPCLR ;CLEAR DIRECTORY OF OUTPUT DEVICE
01700 MTAPE OUTCHN,1 ;REWIND OUTPUT DEVICE
01800 JRST OPNW2 ;ENTER FILE
01900
02000
02100
02200
02300 ;EF FINISHES OUTPUT ON THE CURRENT OUTPUT FILE WITHOUT
02400 ; SELECTING A NEW OUTPUT FILE.
02500 ;FROM ECMD+10
02600
02700 CLOSEF: TLZN FF,UWRITE
02800 POPJ P,
02900 CLOSE OUTCHN,2
03000 STATZ OUTCHN,740000
03100 JRST OUTERR
03200 RELEAS OUTCHN,0
03300 POPJ P,
03400
03500
03600
03700
03800
03900
04000 ;EM EXECUTE MTAPE UUO.
04100 ;FROM ECMD+14
04200
04300 EMTAPE: TLNN FF,UREAD
04400 JSR ERR
04500 PUSHJ P,CHK2
04600 CAIGE B,20
04700 CAIGE B,1
04800 JSR ERR
04900 MTAPE INCHN,0(B)
05000 POPJ P,
05100
00100
00200 ;ROUTINE TO PARSE FILE DESIGNATOR
00300 ;FROM OPNRD+2,OPNW1+2,LSTDIR
00400
00500 FILSPC: TLZ FF,FILWD
00600 MOVSI E,'DSK'
00700 MOVEM E,FILDEV(R)
00800 HLLZS FILNAM+1(R)
00900 SETZM FILNAM+2(R)
01000 SETZB E,FILNAM+3(R)
01100
01200 ;FROM FILSPL+21,FILSP1+3,FILSP3+3,FILSP6+1
01300 FILSPL: PUSHJ P,SKRCH ;GET NEXT COMMAND CHARACTER. ERROR IF COMMAND BUFFER EMPTY.
01400 CAIN CH,175
01500 JRST FILSP2 ;ALT MODE
01600 CAIN CH,":"
01700 JRST FILSP1 ;DEVICE
01800 CAIN CH,"."
01900 JRST FILSP3 ;EXTENSION MARK
02000 CAIN CH,"["
02100 JRST FILSP4 ;PROJ PROG PAIR
02200 PUSHJ P,DQT2 ;LETTER OR DIGIT?
02300 TRZA B,777700 ;YES. DQT2 LEAVES CHARACTER IN B AND CH.
02400 JSR ERR ;NO
02500 TRC B,40 ;CONVERT TO SIXBIT.
02600 ROT B,-6
02700 TLNN E,770000 ;SIX CHARACTERS YET?
02800 ROTC B,6 ;NO. PACK IT INTO E
02900 TLO FF,FILWD ;YES.
03000 JRST FILSPL
03100
03200 ;END OF DESIGNATOR. STORE FILE NAME OR EXTENSION AND RETURN
03300
03400 FILSP2:
03500
03600 ;ROUTINE TO LEFT JUSTIFY E AND STORE IN FILE NAME OR FILE EXTENSION.
03700 ;CALL MOVE E,SIXBIT NAME RIGHT JUSTIFIED
03800 ; SET FILWD OR FEXTF FLAG
03900 ; PUSHJ P,FILLSH
04000 ; RETURN
04100 ;FROM FILSP1,FILSP3,FILSP4
04200
04300 FILLSH: SKIPE E ;NULL NAME?
04400 TLNE E,770000 ;NO. LEFT JUSTIFIED?
04500 JRST FILLS1 ;YES.
04600 LSH E,6 ;NO.
04700 JRST .-3
04800 FILLS1: TLZN FF,FEXTF ;EXTENSION?
04900 JRST .+3 ;NO.
05000 HLLZM E,FILNAM+1(R) ;YES. STORE IT.
05100 TLZ FF,FILWD
05200 TLZE FF,FILWD ;FILE NAME?
05300 MOVEM E,FILNAM(R) ;YES. STORE IT.
05400 POPJ P,0 ;NO. RETURN.
05500
00100 ;DEVICE NAME
00200
00300 FILSP1: PUSHJ P,FILLSH ;LEFT JUSTIFY IT.
00400 MOVEM E,FILDEV(R)
00500 FILS1A: MOVEI E,0
00600 JRST FILSPL
00700
00800 ;FILE NAME EXTENSION FOLLOWS
00900
01000 FILSP3: PUSHJ P,FILLSH ;STORE FILE NAME.
01100 TLO FF,FEXTF ;GET EXTENSION.
01200 JRST FILS1A
01300
01400 ;PROJECT-PROGRAMMER PAIR
01500
01600 FILSP4: PUSHJ P,FILLSH ;STORE NAME OR EXTENSION.
01700 MOVEI B,"," ;SCAN FOR ,
01800 PUSHJ P,FILSPP
01900 FILSP5: HRLZM E,FILNAM+3(R) ;STORE PROJECT NUMBER.
02000 MOVEI B,"]" ;SCAN FOR ]
02100 PUSHJ P,FILSPP
02200 FILSP6: HRRM E,FILNAM+3(R)
02300 JRST FILSPL
02400
02500 FILSPP: MOVEI E,0
02600 FILS4L: PUSHJ P,SKRCH ;GET NEXT COMMAND CHARACTER.
02700 CAIN CH,(B) ;DELIMITER?
02800 POPJ P, ;YES
02900 TRNE E,770000
03000 JRST FILS4L
03100 LSH E,6
03200 ADDI E,-40(CH)
03300 JRST FILS4L
00100 REPEAT 0,<
00200
00300 VII. INPUT COMMANDS
00400
00500 Y RENDER THE BUFFER EMPTY. READ INTO THE BUFFER UNTIL
00600 (A) A FORM FEED CHARACTER IS READ, OR
00700 (B) THE BUFFER IS WITHIN 128 CHARACTERS OF CAPACITY AND A LINE-FEED IS READ, OR
00800 (C) AND END OF FILE IS READ OR
00900 (D) THE BUFFER IS COMPLETELY FULL.
01000 THE FORM FEED (IF PRESENT) DOES NOT ENTER THE BUFFER.
01100 A APPEND TO THE END OF THE BUFFER FROM THE SELECTED INPUT
01200 TERMINATING THE READ IN THE SAME MANNER AS Y. THE POINTER
01300 IS NOT MOVED BY A.
01400 ITEXT$ INSERT, AT THE CURRENT POINTER LOCATION, THE TEXT FOLLOWING
01500 THE I UP TO BUT NOT INCLUDING THE FIRST ALT. MODE.
01600 THE POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
01700 N\ INSERT AT THE CURRENT POINTER LOCATION THE ASCII NUMBERS
01800 EQUAL TO N. FOR EXAMPLE, 69\ IS EQUIVALENT TO I69$. THE
01900 POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
02000 ↑ITEXT$ INSERTS AT THE CURRENT POINTER LOCATION THE ↑I (TAB) AND THE
02100 TEXT FOLLOWING THE ↑I UP TO BUT NOT INCLUDING THE
02200 ALT MODE. THE POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
02300 @IJTEXTJ INSERT, AT THE CURRENT POINTER POSITION, THE TEXT
02400 SURROUNDED BY THE INSTANCES OF THE TERMINATOR J, WHICH MAY BE AT
02500 THE USER'S CHOICE ANY CHARACTER NOT APPEARING IN THE TEXT. THE
02600 POINTER IS PUT TO THE RIGHT OF THE INSERTION.
02700 NI INSERT AT THE POINTER A CHARACTER WHOSE 7-BIT ASCII CODE IN N
02800 (BASE 10). THE POINTER IS MOVED TO THE RIGHT OF THE NEW CHARACTER.
02900 >
00100 ;CD9(Y)
00200 ;Y RENDER THE BUFFER EMPTY. READ INTO THE BUFFER UNTIL
00300 ; (A) A FORM FEED CHARACTER IS READ, OR
00400 ; (B) THE BUFFER IS WITHIN 128 CHARACTERS OF CAPACITY AND A LINE FEED IS READ, OR
00500 ; (C) AN END OF FILE IS READ, OR
00600 ; (D) THE BUFFER IS COMPLETELY FULL.
00700 ;THE FORM FEED (IF PRESENT) DOES NOT ENTER THE BUFFER.
00800
00900 YANK:
01000
01100 ;FROM NOFND1+7,PUN1+3
01200
01300 YANK1: MOVE OUT,BEG(R)
01400 MOVEM OUT,PT(R) ;PT:=BEG
01500
01600 ;FROM APPEND+3
01700
01800 YANK2:
01900 YANK3: TLNN FF,UREAD ;HAS AN INPUT FILE BEEN SPECIFIED?
02000 JRST YANK09 ;NO.
02100 SOSLE INBUF+2(R) ;YES. IS DEVICE BUFFER EMPTY?
02200 JRST YANK5 ;NO.
02300 INPUT INCHN,0 ;YES. FILL IT.
02400 STATZ INCHN,740000 ;ERROR?
02500 JRST INERR ;YES.
02600 STATO INCHN,20000 ;NO. END OF FILE?
02700 JRST YANK5 ;NO.
02800 TLZ FF,UREAD ;YES. DE-SELECT INPUT FILE.
02900 TRO FF,FINF
03000 JRST YANK51 ;CLEAR BUFFER AND RETURN.
03100 YANK5: ILDB CH,INBUF+1(R) ;CH:=NEXT CHARACTER.
03200 JUMPE CH,YANK3 ;IF NULL, IGNORE IT.
03300 MOVE T,@INBUF+1(R)
03400 TRNE T,1 ;SEQUENCE NUMBER?
03500 JRST YNKSEQ ;YES. IGNORE THEM.
03600 PUSHJ P,PUT ;NO. PUT CHARACTER IN DATA BUFFER.
03700 CAIE CH,14 ;FORM FEED?
03800 AOJA OUT,YANK4 ;NO. UPDATE DATA BUFFER POINTER AND CHECK FOR OVERFLOW.
03900 YANK51: MOVEM OUT,Z(R) ;YES. SET END OF DATA BUFFER AND RETURN
04000 POPJ P,0
04100 YANK09: SKIPE OPNR1(R) ;INPUT DEVICE SPECIFIED?
04200 JRST YANK51 ;YES. CLEAR BUFFER.
04300 JSP A,ERRMES ;NO.
04400 ASCIZ /NO FILE FOR INPUT
04500 /
04600 JSR ERR
04700
04800
04900 YNKSEQ: MOVNI T,5 ;IGNORE SEQ. NO. AND FOLLOWING TAB
05000 ADDM T,INBUF+2(R) ;DECREASE CHAR COUNT BY 5
05100 AOS INBUF+1(R) ;INCREMENT POINTER OVER SEQ. NO., & TAB
05200 JRST YANK3
00100 ;FROM YANK3+6
00200
00300 INERR: JSP A,ERRMES
00400 ASCIZ /ERROR ON INPUT DEVICE
00500 /
00600 JSR ERR
00700
00800 ;FROM YANK5+11
00900
01000 YANK4: MOVE T,MEMSIZ(R)
01100 CAIL T,200(<OUT>) ;WITHIN 128 CHARACTERS FROM TOP OF MEMORY?
01200 JRST YANK3 ;NO. GET MORE.
01300 CAILE T,0(<OUT>) ;YES. FULL?
01400 CAIN CH,12 ;NO. LINE FEED?
01500 JRST YANK51 ;YES. THAT'S ALL.
01600 JRST YANK3 ;NO. GET MORE.
01700
01800
01900
02000 ;A APPEND TO THE END OF THE BUFFER FROM THE SELECTED INPUT
02100 ; TERMINATING THE READ IN THE SAME MANNER AS Y. THE POINTER
02200 ; IS NOT MOVED BY A.
02300
02400 APPEND: MOVE OUT,Z(R) ;STORE DATA AT END OF BUFFER.
02500 PUSHJ P,YANK2
02600 JRST RET
02700
02800
00100 ;CD9(↑I)
00200 ;↑ITEXT$ INSERTS AT THE CURRENT POINTER LOCATION THE ↑I (TAB)
00300 ; AND THE TEXT FOLLOWING THE ↑I UP TO BUT NOT INCLUDING THE
00400 ; ALT MODE. THE POINTER IS PUT TO THE RIGHT OF THE INSERTED
00500 ; MATERIAL.
00600
00700 TAB: PUSHJ P,TAB2 ;INSERT TAB
00800
00900 ;CD9(I)
01000 ;ITEXT$ INSERT, AT THE CURRENT POINTER LOCATION, THE TEXT FOLLOWING
01100 ; THE I UP TO BUT NOT INCLUDING THE FIRST ALT. MODE. THE
01200 ; POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
01300
01400 INSERT: TRNE FF,ARG ;IS THERE AN ARGUMENT?
01500 JRST INS1A ;YES. NI COMMAND.
01600 MOVEI CH,175 ;NO. CH:=ALT-MODE.
01700 TRZE FF,SLSL ;DID @ PRECEED I?
01800 PUSHJ P,RCH ;YES. CH:=USER SELECTED TERMINATOR.
01900 MOVEM CH,A ;A:=INSERTION TERMINATOR.
02000 ;EITHER ALT-MODE OR USER CHOICE.
02100 MOVE B,CPTR(R) ;SAVE CURRENT POSITION OF CPTR.
02200 MOVEI C,0 ;COUNT # CHARACTERS TO INSERT IN C AND
02300 ;MOVE CPTR TO END OF STRING.
02400 PUSHJ P,SKRCH ;GET NEXT CHARACTER
02500 CAME CH,A ;IS IT THE TERMINATOR?
02600 AOJA C,.-2 ;NO. TRY AGAIN.
02700 PUSHJ P,NROOM ;YES. MOVE FROM PT THROUGH Z UP C POSITIONS.
02800 ADD B,CRREL(R) ;RELOCATE INITIAL VALUE OF CPTR IN CASE OF GARB. COL.
02900
03000 ;MOVE INSERTION INTO DATA BUFFER
03100 ;FROM BAKSL1+11
03200
03300 INS1B: MOVE OUT,PT(R)
03400 ILDB CH,B ;CH:=CHARACTER FROM COMMAND STRING.
03500 CAMN CH,A ;IS IT THE TERMINATOR?
03600 POPJ P, ;YES. DON'T STORE IT.
03700 PUSHJ P,PUT ;NO. STORE CHARACTER IN DATA BUFFER TO RIGHT OF PT.
03800 AOS PT(R) ;PT:=PT+1
03900 JRST INS1B ;LOOP
04000
04100
00100 ;NI INSERT AT THE POINTER A CHARACTER WHOSE 7-BIT ASCII CODE IS N
00200 ; (BASE 10). THE POINTER IS MOVED TO THE RIGHT OF THE NEW CHARACTER.
00300 ;FROM INSERT+1
00400
00500 INS1A:
00600 TAB1: MOVE CH,NUM(R) ;CH:=NUM
00700
00800 ;INSERT CH IN DATA BUFFER AT PT
00900 ;FROM TAB,TYOM+4
01000
01100 TAB2: MOVEI C,1 ;MOVE FROM PT THROUGH Z UP 1 POSITION.
01200 PUSHJ P,NROOM
01300 AOS OUT,PT(R) ;PT:=PT+1
01400 SOJA OUT,PUT ;STORE CH AT PT-1
01500
01600
01700
01800
01900 ;CD9(@)
02000 ;@IJTEXTJ INSERT, AT THE CURRENT POINTER POSITION, THE TEXT
02100 ; SURROUNDED BY THE INSTANCES OF THE TERMINATOR J, WHICH MAY BE AT
02200 ; THE USER'S CHOICE ANY CHARACTER NOT APPEARING IN THE TEXT.
02300 ; THE POINTER IS PUT TO THE RIGHT OF THE INSERTED MATERIAL.
02400
02500 ATSIGN: TRO FF,SLSL ;SLSL:=1
02600 JRST RET
02700
02800
02900 ;NBACKSLASH INSERT AT THE CURRENT POINTER LOCATION THE ASCII NUMBERS
03000 ; EQUAL TO N.
03100
03200 ;FROM BAKSL+1
03300
03400 BAKSL1: MOVE T,[XWD 700+R,BAKTAB-1]
03500 MOVEI C,0 ;COUNT # DIGITS IN C.
03600 MOVEI CH,BAKSL4 ;SET DPT TO RETURN TO BAKSL4
03700 HRRM CH,LISTF5
03800 PUSHJ P,DPT ;CONVERT C(B) TO ASCII AND STORE STRING IN BAKTAB.
03900 MOVEI A,141 ;MARK END OF STRING IN BAKTAB
04000 IDPB A,T
04100 MOVE B,[XWD 700+R,BAKTAB-1]
04200 PUSHJ P,NROOM ;MOVE FROM PT THROUGH Z UP C POSITIONS.
04300 PUSHJ P,INS1B ;INSERT STRING IN BAKTAB INTO DATA BUFFER AT PT.
04400 JRST RET
04500
04600 BAKSL4: IDPB CH,T ;STORE DIGIT IN BAKTAB
04700 AOJA C,CPOPJ ;C:=C+1. RETURNS TO DPT CALL + 1 ON COMPLETION.
04800
00100 REPEAT 0,<
00200
00300 VIII. OUTPUT COMMANDS
00400
00500 NV DISPLAYS ON THE SCOPE THE N LINES TO THE RIGHT OF THE
00600 POINTER, I.E., FROM THE POINTER THROUGH THE NTH FOLLOWING LINE
00700 FEED. IF N IS NEGATIVE, N LINES TO THE LEFT OF THE POINTER ARE
00800 DISPLAYED.
00900 V SAME AS 1V.
01000 I,JV DISPLAY THE (I+1)TH THROUGH JTH CHARACTERS IN THE BUFFER.
01100
01200 NOTES ON THE V COMMAND: THE DISPLAY CEASES IF THE V IS NOT THE LAST
01300 COMMAND OF THE COMMAND STRING, AND WHEN A NEW COMMAND STRING IS ENTERED.
01400 USUALLY V IS NOT NEEDED, SINCE WHENEVER NOT PROCESSING COMMANDS TECO
01500 AUTOMATICALLY DISPLAYS 10 LINES ON EACH SIDE OF THE POINTER (EXCEPT IF
01600 THE LAST COMMAND IT SAW WAS V). IN ALL DISPLAYS OF THE BUFFER, THE
01700 POINTER IS DISPLAYED AS A VERTICAL BAR, UNLESS IT IS NOT IN THE RANGE
01800 BEING DISPLAYED OR IS AT THE END OF THE BUFFER. NON-PRINTING CHARACTERS
01900 ARE DISPLAYED AS FOLLOWS: SPACE, TAB, CARRIAGE RETURN, AND LINE FEED
02000 HAVE THEIR USUAL EFFECT. CTRL CHARACTERS ARE DISPLAYED AS AN UP ARROW (↑)
02100 FOLLOWED BY THE CORRESPONDING PRINTING CHARACTERS; ALT MODE IS
02200 DISPLAYED AS $; AND OTHER CHARACTERS ARE DISPLAYED AS A DOWNWARD
02300 POINTING ARROW FOLLOWED BY A SUBSCRIPT WHICH IS THEIR 7-BIT ASCII CODE IN OCTAL.
02400
02500 N↑N SET NUMBER OF LINES AUTOMATICALLY DISPLAYED ON EACH SIDE OF POINTER
02600 TO N.
02700 N↑D SET DISPLAY SIZE TO N. LEGAL SIZES ARE 0, 1, 2, AND 3: 1 IS
02800 THE USUAL SIZE, 2 IS APPROPRIATE TO DEMOSNSTRATIONS TO GROUPS,
02900 0 IS TOO SMALL AND 3 IS TOO BIG.
03000 NVW SAME AS SIMILAR FOR OF V EXCEPT: WHEN THIS COMMAND IS ENCOUNTERED
03100 VW THE DISPLAY IS MAINTAINED AND FURTHER COMMANDS IN THE STRING
03200 I,JVW ARE NOT INTERPRETED UNTIL THE USER TYPES IN A CHARACTER. THEN
03300 THE DISPLAY CEASES, THE VW IS TREATED AS A NUMERIC QUANTITY
03400 EQUAL TO THE 7-BIT ASCII CODE OF THE CHARACTER JUST TYPED IN,
03500 AND COMMAND INTERPRETATION RESUMES. (SEE EXAMPLE 8.)
03600 NT TYPE OUT THE STRING OF CHARACTERS STARTING AT THE RIGHT OF THE
03700 POINTER AND CONTINUING THROUGH THE NTH LINE FEED ENCOUNTERED.
03800 IF N IS NEGATIVE, N LINES TO THE LEFT OF THE POINTER ARE TYPED.
00100 T SAME AS 1T.
00200 I,JT TYPE OUT THE (I+1)TH THROUGH THE JTH CHARACTER OF THE BUFFER.
00300
00400 NOTICE THAT T IS IDENTICAL TO V, EXCEPT THAT IS USES THE TELETYPE INSTEAD
00500 OF THE SCOPE.
00600
00700 PW OUTPUT THE ENTIRE BUFFER, FOLLOWED BY A FORM FEED CHARACTER,
00800 TO THE SELECTED OUTPUT DEVICE. BUFFER IS UNCHANGED AND POINTER
00900 IS UNMOVED.
01000 P IS IDENTICAL TO PWY.
01100 NP IS IDENTICAL TO PP...P (P PERFORMED N TIMES).
01200 I,JP OUTPUTS (I+1)TH THROUGH JTH CHARACTERS OF BUFFER. NO
01300 FORM FEED IS PUT AT THE END. BUFFER UNCHANGED; POINTER UNMOVED.
01400 >;CD9(T)
01500 ;NT TYPE OUT THE STRING OF CHARACTERS STARTING AT THE RIGHT OF THE
01600 ; POINTER AND CONTINUING THROUGH THE NTH LINE FEED ENCOUNTERED.
01700 ; IF N IS NEGATIVE, N LINES TO THE LEFT OF THE POINTER ARE TYPED.
01800 ;T SAME AS 1T.
01900 ;I,JT TYPE OUT THE (I+1)TH THROUGH THE JTH CHARACTER OF THE BUFFER.
02000
02100 TYPE:
02200 TYPE4: MOVEI D,TYO ;D:=ADDRESS OF OUTPUT ROUTINE.
02300
02400 ;FROM PUNCH+2
02500 TYPE0: PUSHJ P,GETARG ;C:=FIRST STRING ARGUMENT ADDRESS.
02600 ;B:=SECOND STRING ARGUMENT ADDRESS.
02700
02800 ;FROM PUNCHR+3
02900
03000 TYPE1: PUSHJ P,CHK1 ;C:=MAX(C(C),BEG), B:=MIN(C(B),Z)
03100 MOVE IN,C ;START GETTING CHARACTERS AT C.
03200 TYPE3: CAML IN,B ;DONE?
03300 JRST TYPE5 ;YES.
03400 PUSHJ P,GETINC ;NO. CH:=NEXT CHARACTER.
03500 PUSHJ P,(D) ;OUTPUT IT
03600 JRST TYPE3 ;LOOP
03700 TYPE5: MOVEI A,PPA
03800 MOVEI CH,14 ;IF PUNCHING, APPEND FF.
03900 CAIE A,(D) ;D=PPA?
04000 POPJ P, ;NO
04100 CPPA: JRST PPA ;YES. APPEND FF.
04200
04300
00100 PPA: TLNN FF,UWRITE ;OUTPUT FILE OPEN?
00200 JRST PPA09 ;NO.
00300 SOSLE OUTBUF+2(R) ;YES. IS OUTPUT BUFFER FULL?
00400 JRST PPA01 ;NO.
00500 OUTPUT OUTCHN,0 ;YES. WRITE IT
00600 STATZ OUTCHN,740000 ;ERROR?
00700 JRST OUTERR ;YES.
00800 PPA01: IDPB CH,OUTBUF+1(R) ;NO. CH TO OUTPUT BUFFER.
00900 POPJ P,0 ;RETURN
01000
01100 PPA09: JSP A,ERRMES
01200 ASCIZ /NO FILE FOR OUTPUT
01300 /
01400 JRST ERRA
01500
01600 ;FROM PPA+6
01700
01800 OUTERR: JSP A,ERRMES
01900 ASCIZ /ERROR ON OUTPUT DEVICE; FILE CLOSED
02000 /
02100 RELEAS OUTCHN,0 ;CLOSE FILE AND RELEASE OUTPUT DEVICE.
02200 TLZ FF,UWRITE ;CLEAR OUTPUT FILE OPEN INDICATOR.
02300 JRST GOX ;CLEAR COMMAND BUFFER AND WAIT FOR NEXT COMMAND.
02400
02500
00100
00200 ;CD9(P)
00300 ;PW OUTPUT THE ENTIRE BUFFER, FOLLOWED BY A FORM FEED CHARACTER.
00400 ; TO THE SELECTED OUTPUT DEVICE. BUFFER IS UNCHANGED AND POINTER
00500 ; IS UNMOVED.
00600 ;P IS IDENTICAL TO PWY.
00700 ;NP IS IDENTICAL TO PP...P (P PERFORMED N TIMES).
00800 ;I,JP OUTPUTS (I+1)TH THROUGH JTH CHARACTERS OF BUFFER. NO FORM
00900 ; FEED IS PUT AT THE END. BUFFER UNCHANGED; POINTER UNMOVED.
01000
01100 PUNCH:
01200
01300 ;FROM NOFND1+5
01400
01500 PUNCHA: MOVEI D,CPPA ;SELECT PPA FOR OUTPUT.
01600 TRNE FF,ARG2 ;I,JP?
01700 JRST TYPE0 ;YES. GET STRING ARGUMENTS AND OUTPUT.
01800 MOVE E,B ;NO. E:=N
01900 MOVE B,CPTR(R)
02000 ILDB T,B ;T:=COMMAND CHARACTER FOLLOWING P.
02100 JUMPL E,CPOPJ ;IF N<0, IGNORE P.
02200 PUN1: PUSHJ P,PUNCHR ;PUNCH OUT BUFFER
02300 SKIPE COMCNT(R) ;IF NO COMMANDS LEFT
02400 CAIE T,"W" ;OR COMMAND IS NOT W
02500 PUSHJ P,YANK1 ;RENEW BUFFER
02600 MOVE C,Z(R)
02700 CAMN C,BEG(R) ;EMPTY BUFFER?
02800 TRNN FF,FINF ;NO. QUIT ON EOF
02900 SOJG E,PUN1 ;YES. E:=E-1. DONE?
03000 ;YES
03100
03200 ;FROM TYI1+2,SIXBMS+3,CHK2+4,PUNCH+6,BAKSL4+1,GCM2+6
03300
03400 CPOPJ: POPJ P,0
03500
03600 ;FROM PUN1
03700
03800 PUNCHR: MOVE C,BEG(R) ;OUTPUT DATA BUFFER.
03900 MOVE B,Z(R)
04000 MOVEI D,PPA
04100 JRST TYPE1
04200
00100 REPEAT 0,<
00200
00300 IX. BASIC EDITING COMMANDS
00400
00500 NJ MOVE THE POINTER TO THE RIGHT OF THE NTH CHARACTER IN THE
00600 BUFFER. (I.E., GIVE "." THE VALUE N.)
00700 J SAME AS 0J.
00800 NC SAME AS .+NJ. NOTE THAT N MAY BE NEGATIVE.
00900 NR SAME AS .-NJ.
01000 NL IF N IS GREATER THAN 0: MOVE POINTER TO THE RIGHT, STOPPING WHEN IT HAS
01100 PASSED OVER N LINE FEEDS.
01200 IF N IS LESS THAN 0: MOVE POINTER TO THE LEFT; STOP WHEN IT HAS PASSED
01300 OVER N+1 LINE FEEDS AND THEN MOVE IT TO THE RIGHT
01400 OF THE LAST LINE FEED PASSED OVER.
01500 L SAME AS 1L.
01600 ND DELETE N CHARACTERS FROM THE BUFFER: IF N IS POSITIVE, DELETE
01700 THEM JUST TO THE RIGHT OF THE POINTER; IF N IS NEGATIVE, DELETE
01800 THEM JUST TO ITS LEFT.
01900 NK PERFORM NL BUT DELETE EVERYTHING THE POINTER MOVES OVER.
02000 M,NK DELETE THE (M+1)TH THROUGH NTH CHARACTER FROM THE BUFFER.
02100 THE POINTER IS THEN PUT WHERE THE DELETION TOOK PLACE.
02200 M,NXI THE STRING FROM CHARACTER (M+1)TH THROUGH NTH CHARACTER OF THE
02300 BUFFER IS COPIED INTO Q-REGISTER I.
02400 ITEXT$ INSERTS TEXT IN BUFFER AT POINTER; PUTS POINTER TO RIGHT
02500 @IJTEXTJ OF INSERTION.
02600 NI INSERTS CHARACTER WHOSE ASCII CODE IS N AT
02700 POINTER; PUTS POINTER AT RIGHT OF NEW CHARACTER.
02800 GI INSERTS AT THE POINTER A COPY OF THE TEXT IN Q-REGISTER I. THE
02900 POINTER IS SET AT THE RIGHT OF THE INSERTION.
03000 >
00100 ;CD9(J)
00200 ;NJ MOVE THE POINTER TO THE RIGHT OF THE NTH CHARACTER IN THE
00300 ; BUFFER. (I.E., GIVE "." THE VALUE N.)
00400 ;J SAME AS 0J.
00500
00600 JMP: ADD B,BEG(R) ;PT:=N+BEG
00700 JRST JMP1
00800
00900
01000
01100 ;CD9(R)
01200 ;NR SAME AS .-NJ.
01300
01400 REVERS: PUSHJ P,CHK2 ;MAKE SURE THERE IS AN ARGUMENT
01500 MOVNS B ;B:=-C(B)
01600 SKIPA
01700
01800 ;CD9(C)
01900 ;NC SAME AS .+NJ. NOTE THAT N MAY BE NEGATIVE.
02000
02100 CHARAC: PUSHJ P,CHK2 ;MAKE SURE THERE IS AN ARGUMENT
02200 ADD B,PT(R) ;B:=PT+C(B)
02300
02400 ;IF B LIES BETWEEN BEG AND Z, STORE IT IN PT.
02500 ;FROM JMP+1
02600
02700 JMP1: PUSHJ P,CHK ;IS C(B) WITHIN DATA BUFFER?
02800 MOVEM B,PT(R) ;YES. PT:=C(B)
02900 JRST RET
03000
03100 ;CD9(L)
03200 ;NL IF N>0: MOVE POINTER TO THE RIGHT, STOPPING WHEN IT HAS
03300 ; PASSED OVER N LINE FEEDS.
03400 ; IF N<0: MOVE POINTER TO THE LEFT; STOP WHEN IT HAS PASSED
03500 ; OVER N+1 LINE FEEDS AND THEN MOVE IT TO THE RIGHT OF
03600 ; THE LAST LINE FEED PASSED OVER.
03700 ;L SAME AS 1L.
03800
03900 LINE: TRNE FF,ARG2 ;IS THERE A SECOND ARGUMENT?
04000 JSR ERR ;YES. TOUGH
04100 PUSHJ P,GETARG ;NO. C:=FIRST STRING ARGUMENT ADDRESS,
04200 ;B:=SECOND STRING ARGUMENT ADDRESS.
04300 XOR B,C
04400 XORM B,PT(R)
04500 JRST RET
04600
00100 ;ROUTINE TO RETURN CURRENT ARGUMENT IN B
00200 ;ASSUMES A VALUE OF 1 WITH SIGN OF LAST OPERATOR IF THERE IS NO CURRENT ARGUMENT
00300 ;CALL PUSHJ P,CHK2
00400 ; RETURN WITH B:=CURRENT ARG.,+1 OR -1
00500 ;FROM REVERS,CHARAC,DELETE,EMTAPE+2
00600
00700 CHK2: TROE FF,ARG ;IS THERE AN ARGUMENT?
00800 POPJ P, ;YES. IT'S ALREADY IN B.
00900 ;NO
01000
01100 ;FROM GETARG+3
01200 CHK22: LDB B,[XWD 340200+R,DLIM] ;B:=1 WITH SIGN OF LAST OPERATOR.
01300 MOVNS B
01400 AOJA B,CPOPJ
01500
01600 ;CD9(K)
01700 ;NK PERFORM NL BUT DELETE EVERYTHING THE POINTER MOVES OVER.
01800 ;M,NK DELETE THE (M+1)TH THROUGH THE NTH CHARACTER FROM THE BUFFER.
01900 ; THE POINTER IS THEN PUT WHERE THE DELETION TOOK PLACE.
02000 ;K SAME AS 1K
02100
02200 KILL: PUSHJ P,GETARG ;C:=FIRST STRING ARG. ADDRESS
02300 ;B:=SECOND STRING ARG. ADDRESS
02400 PUSHJ P,CHK1 ;C:=MAX(C(C),BEG), B:=MIN(C(B),Z)
02500 MOVEM C,PT(R) ;PT:=C(C)
02600 SUB B,C ;B:=NO. OF CHARACTERS TO KILL.
02700 JUMPE B,RET ;IF NONE, RETURN. OTHERWISE, FALL INTO DELETE
02800
00100 ;CD9(D)
00200 ;ND DELETE N CHARACTERS FROM THE BUFFER: IF N IS POSITIVE, DELETE
00300 ; THEM JUST TO THE RIGHT OF THE POINTER; IF N IS NEGATIVE, DELETE
00400 ; THEM JUST TO ITS LEFT.
00500 ;D SAME AS 1D
00600
00700 DELETE: PUSHJ P,CHK2 ;MAKE SURE B CONTAINS AN ARGUMENT
00800 MOVM C,B
00900 MOVNS C ;C:=-ABS(B)
01000 ADD B,PT(R) ;B:=PT+B
01100 PUSHJ P,CHK ;STILL IN DATA BUFFER?
01200 CAMGE B,PT(R) ;YES. IS N NEGATIVE?
01300 MOVEM B,PT(R) ;YES. MOVE PT BACK FOR DELETION.
01400 PUSHJ P,NROOM ;MOVE FROM PT+ABS(C) THROUGH Z DOWN ABS(C) POSITIONS
01500 DEL2:
01600 JRET: JRST RET
01700
01800
01900
02000 ;ROUTINE TO CHECK DATA BUFFER POINTER
02100 ;CALL MOVE B,POINTER
02200 ; PUSHJ P,CHK
02300 ; RETURN IF B LIES BETWEEN BEG AND Z
02400 ;FROM;FROM JMP1,DELETE+4
02500
02600 CHK: CAMG B,Z(R)
02700 CAMGE B,BEG(R)
02800 JSR ERR
02900 POPJ P,
03000
03100 ;ROUTINE TO PUT STRING ARGUMENT ADDRESSES WITHIN DATA BUFFER
03200 ;BOUNDS AND CHECK ORDER RELATION.
03300 ;CALL MOVE C,FIRST STRING ARGUMENT ADDRESS
03400 ; MOVE B,SECOND STRING ARGUMENT ADDRESS
03500 ; PUSHJ P,CHK1
03600 ; RETURN
03700 ;C:=MAX*←xC),BEG), B:=MIN(C(B),Z)
03800 ;IF C>B, DOES NOT RETURN.
03900 ;FROM KILL+1,TYPE1
04000
04100 CHK1: CAMG C,BEG(R) ;C:=MAX(C(C),BEG)
04200 MOVE C,BEG(R)
04300 CAML B,Z(R) ;B:=MIN(C(B),Z)
04400 MOVE B,Z(R)
04500 CAMLE C,B ;C>B?
04600 JSR ERR ;YES.
04700 POPJ P, ;NO
04800
00100 REPEAT 0,<
00200
00300 X. SEARCH COMMANDS
00400
00500 THERE ARE THREE SEARCH COMMANDS: S, N, AND LEFT ARROW. EACH OF THESE
00600 MAY BE PRECEDED BY EITHER OR BOTH OF THE MODIFIER CHARACTERS : AND @.
00700 PRECEDING THE COMMAND LETTER, BUT FOLLOWING ANY MODIFIERS,
00800 MAY BE A NUMERIC ARGUMENT; IF THIS IS NOT SUPPLIED, ONE IS ASSUMED.
00900 FOLLOWING THE COMMAND LETTER IS A TEXT ARGUMENT IN THE SAME FORMAT
01000 AS FOR THE I OR @I COMMAND, DEPENDING ON THE ABSENCE OR PRESENCE OF THE
01100 @ MODIFIER. IF THE : MODIFIER IS NOT USED, A SEARCH COMMAND HAS NO
01200 NUMERIC VALUE. IF : IS USED, THE VALUE IS -1 IF THE SOUGHT MATERIAL IS
01300 FOUND AND 0 OTHERWISE.
01400 THE SEARCH COMMANDS ATTEMPT TO FIND IN THE BUFFER A MATCH TO THEIR
01500 TEXT ARGUMENT. THE SEARCH IS BEGUN AT THE LOCATION OF THE POINTER
01600 JUST PRIOR TO THE SEARCH, AND PROCEEDS TO THE RIGHT UNTIL EITHER A MATCH
01700 IS FOUND OR THE END OF THE BUFFER IS REACHED. IF THE MATCH IS FOUND,
01800 THE POINTER IS MOVED TO THE RIGHT OF THE STRING FOUND IN THE BUFFER AND
01900 THE COMMAND IS FINISHED. IF THE MATCH HAS NOT BEEN FOUND, THE ACTION
02000 DEPENDS ON WHETHER THE COMMAND WAS S, N, OR LEFT ARROW. THE S COMMAND IN SUCH A
02100 CIRCUMSTANCE IS SAID TO FAIL; THE N COMMAND PERFORMS A P AND THEN
02200 RESUMES SEARCHING; THE LEFT ARROW COMMAND PERFORMS A Y AND RESUMES THE SEARCH.
02300 IF N OR LEFT ARROW REACHES THE END OF THE FILE WITHOUT FINDING THE MATCH, THEY
02400 FAIL. IF A SEARCH FAILS (S REACHES THE END OF THE BUFFER; OR N OR LEFT ARROW
02500 REACHES THE END OF THE FILE), THE POINTER IS SET TO THE BEGINNING OF
02600 THE BUFFER. THEN IF THE : MODIFIER WAS NOT SPECIFIED, TECO TYPES OUT
02700 A QUESTION MARK AND IGNORES THE REMAINDER OF THE COMMAND STRING.
02800 SHOULD A NUMERIC ARGUMENT PRECEDE THE COMMAND LETTER, THIS IS
02900 EQUIVALENT TO WRITING OUT THE ENTIRE SEARCH COMMAND A NUMBER OF TIMES
03000 EQUAL TO THE VALUE OF THE ARGUMENT. IN OTHER WORDS, IF THE NUMBER
03100 IS N IT SEARCHES FOR THE NTH FOLLOWING INSTANCE OF THE TEXT.
03200 WITHIN A SEARCH FOUR CTRL CHARACTERS TAKE EFFECT. CTRL S
00100 MATCHES ANY SEPARATOR CHARACTER (I.E., ANY CHARACTER NOT A LETTER,
00200 NUMBER, PERIOD, DOLLAR SIGN, OR PERCENT SYMBOL.) CTRL X MATCHES ANY
00300 ARBITRARY CHARACTER. CTRL N NEGATES THE SENSE OF THE SEARCH FOR THE
00400 NEXT CHARACTER (E.G., CTRL NA FINDS ANY CHARACTER EXCEPT A.) CTRL Q
00500 TAKES THE NEXT CHARACTER LITERALLY EVEN IF IT IS ONE OF THESE FOUR
00600 CHARACTERS. (E.G., S CTRL N CTRL Q CTRL Q $$ FINDS ANY CHARACTER NOT
00700 A CTRL Q.)
00800 SINCE THESE CTRL CHARACTERS ARE PART OF A TEXT STRING RATHER
00900 THAN COMMANDS TO TECO, THEY MUST BE TYPED USING THE CTRL KEY. THE
01000 OPTION OF TYPING ↑ FOLLOWED BY THE CHARACTER DOES NOT APPLY
01100
01200 SEARCH SUMMARY
01300 ALL SEARCHES BEGIN AT THE CURRENT LOCATION OF THE POINTER.
01400 THEY MAY INCLUDE A NUMERIC ARGUMENT N SAYING TO SEARCH FOR THE NTH
01500 OCCURRENCE OF THE TEXT. THE POINTER IS LEFT FO THE RIGHT OF THE
01600 STRING FOUND IF THE SEARCH IS SUCCESSFUL, OTHERWISE AT THE END OF THE
01700 BUFFER. USE OF THE @ MODIFIER DETERMINES THE FORM OF THE TEXT ARGUMENT
01800 WHICH FOLLOWS THE COMMAND:
01900 IF @JTEXTJ J IS ANY CHARACTER NOT IN TEXT.
02000 IF NO A TEXT$ TEXT CONTAINS NO ALT MODE.
02100 >
00100 ;CD9(BACKSLASH)
00200
00300 LARR: TROA FF,FINDR ;FINDR:=1 FOR LEFT ARROW SEARCH
00400
00500 ;CD9(N)
00600
00700 SERCHP: TRO FF,PCHFLG ;PCHFLG:=1 FOR N SEARCH
00800
00900 ;CD9(S)
01000
01100 SERCH: MOVE E,B ;E:=ARGUMENT (IF ANY)
01200 SETZM NUM(R) ;NUM:=0
01300 MOVEI CH,175 ;USE ALT-MODE DELIMITER IF NO @ SEEN
01400 TRZE FF,SLSL ;@ SEEN?
01500 PUSHJ P,RCH ;YES. CH:=USER SPECIFIED DELIMITER.
01600 MOVEM CH,B ;B:=SEARCH STRING DELIMITER
01700 HRLZI F,STAB-STABP ;F:=XWD -LENGTH OF SEARCH TABLE,0
01800
01900 ;SET UP SEARCH TABLE
02000 ;FROM CNTRN+1
02100
02200 SERCH2: PUSHJ P,SKRCH ;CH:=NEXT COMMAND STRING CHARACTER.
02300 CAIN CH,(B) ;DELIMITER?
02400 JRST SERCH1 ;YES. DONE.
02500 CAIN CH,30 ;NO. ↑X?
02600 JRST CNTRX ;YES
02700 CAIN CH,16 ;NO. ↑N?
02800 JRST CNTRN ;YES.
02900 CAIN CH,23 ;NO. ↑S?
03000 JRST CNTRB ;YES
03100 CAIN CH,21 ;NO. ↑Q?
03200 PUSHJ P,SKRCH ;YES. ↑Q TAKES THE NEXT CHARACTER.
03300 HRLI CH,306000+CH*40 ;CH:=CAIN CH,CHARACTER
03400
03500 ;FROM CNTRX+1
03600
03700 SERCH4: TRZE FF,NOTF ;SEARCH SENSE REVERSED?
03800 TLC CH,4000 ;YES. CH:=CAIE CH,CHARACTER
03900 ;PUSHJ P,CNTRB1(R), OR CAIA
04000 MOVEI TT,STAB(F) ;RELOCATE
04100 HRLI TT,R
04200 MOVEM CH,@TT ;SAVE IN SEARCH TABLE
04300 AOBJN F,SERCH2 ;GET NEXT CHARACTER
04400 JSR ERR ;SEARCH TABLE IS FULL
04500
00100 ;START SEARCHING
00200 ;FROM NOFND1+11,FND1
00300
00400
00500 SERCH1: MOVE IN,PT(R) ;START SEARCHING AT PT
00600 TRNE FF,ARG ;IS THERE AN ARGUMENT?
00700 JUMPLE E,FND ;YES. SEEN STRING N TIMES?
00800 CAML IN,Z(R) ;NO. REACHED TOP OF BUFFER?
00900 JRST NOFND ;YES.
01000 MOVEI D,STAB
01100 SERCH3: CAIN D,STAB(F) ;END OF SEARCH TABLE?
01200 JRST FND ;YES.
01300 PUSHJ P,GETINC ;NO. CH:=NEXT DATA BUFFER CHARACTER.
01400 HRRI TT,(D) ;GETINC LEAVES R IN INDEX OF TT
01500 XCT @TT
01600
01700 ;FROM CNTRX+7
01800
01900 SERCH5: AOJA D,SERCH3 ;MATCH FOUND. GO TO NEXT TABLE ENTRY.
02000
02100 ;FROM CNTRX+6
02200
02300 SRCH5A: AOS PT(R) ;NO MATCH. PT:=PT+1
02400 JRST SERCH1 ;KEEP LOOKING
02500
02600 ;FROM SERCH1+2,SERCH3+1
02700
02800 FND: CAMLE IN,Z(R) ;REACH TOP OF BUFFER?
02900 JRST NOFND ;YES. SEARCH FAILED.
03000 SETOM SFINDF(R) ;NO. SFINDF:=-1
03100 MOVEM IN,PT(R) ;MOVE PT PAST THE STRING
03200 SOJG E,SERCH1 ;FIND IT N TIMES?
03300 TRZN FF,COLONF ;YES. COLON MODIFIER?
03400 JRST RET ;NO. DONE
03500 MOVNI A,1 ;YES. RETURN VALUE OF -1
03600 JRST VALRET
03700
00100
00200 ;FROM SERCH1+4,FND+1
00300
00400 NOFND: MOVE IN,BEG(R) ;SEARCH FAILED
00500 MOVEM IN,PT(R) ;PT:=BEG
00600 SETZM SFINDF(R) ;SFINDF:=0
00700 TRNE FF,PCHFLG+FINDR ;S SEARCH?
00800 JRST NOFND1 ;NO.
00900
01000 ;FROM NOFND1+1
01100
01200 BEGIN1: TRZN FF,COLONF ;YES. COLON MODIFIER?
01300 JRST NOFND2 ;NO
01400
01500 ;FROM NOFND2+1
01600
01700 BEGIN2: TRZ FF,PCHFLG+FINDR ;YES.
01800 JRST BEGIN ;RETURN VALUE OF 0
01900
02000
02100 ;FROM NOFND+4
02200
02300 NOFND1: TRNE FF,FINF ;INPUT FILE SELECTED?
02400 JRST BEGIN1 ;NO. DONE.
02500 PUSH P,E ;YES. SAVE SEARCH COUNT
02600 MOVEI B,1 ;PUNCH 1 PAGE ONLY
02700 TRNE FF,PCHFLG ;N SEARCH?
02800 PUSHJ P,PUNCHA ;YES. PUNCH THIS BUFFER AND REFILL IT.
02900 TRNE FF,FINDR ;LEFT ARROW SEARCH?
03000 PUSHJ P,YANK1 ;YES. FILL BUFFER.
03100 POP P,E ;RESTORE SEARCH COUNT.
03200 JRST SERCH1 ;RESUME SEARCH
03300
03400 ;FROM BEGIN1+1
03500
03600 NOFND2: TRNE FF,ITERF ;IN AN ITERATION?
03700 JRST BEGIN2 ;YES. RETURN VALUE OF 0
03800 JSP A,ERRMES
03900 ASCIZ /SEARCH/
04000 JSR ERR ;NO. SEARCH FAILED.
04100
00100 ;CNTR S MATCHES ANY SEPARATOR CHARACTER (I.E., ANY CHARACTER NOT
00200 ;A LETTER, NUMBER, PERIOD, DOLLAR SIGN OR PER CENT SYMBOL)
00300 ;FROM SERCH2+10
00400
00500 CNTRB: SKIPA CH,[JSR P,CNTRB1(R)] ;CH:=JSR P,CNTRB1(R)
00600
00700 ;CNTR X MATCHES ANY ARBITRARY CHARACTER
00800 ;FROM SERCH2+4
00900
01000 CNTRX: MOVSI CH,300000 ;CH:=CAI
01100 JRST SERCH4
01200
01300 ;HERE ON CNTR N CNTR S
01400 CNTRB2: MOVE A,[JRST DQT2] ;CNTRB1:=JRST DQT2
01500 MOVEM A,CNTRB1(R)
01600 PUSHJ P,DQT2 ;IS CH A TERMINATOR?
01700 JRST SRCH5A ;NO
01800 JRST SERCH5 ;YES
01900
02000 ;CNTR N REVERSES THE SENSE OF THE SEARCH FOR THE NEXT CHARACTER
02100 ;FROM SERCH2+6
02200
02300 CNTRN: TRO FF,NOTF
02400 JRST SERCH2
02500
02600 U CNTRB1,2 ;INITIALIZE TO JRST DQT2
02700 ;INITIALIZE TO JRST CNTRB2
02800
02900
03000 ;CD9(:)
03100
03200 COLON: TRO FF,COLONF
03300 JRST RET
03400
00100 REPEAT 0,<
00200
00300 XI. MACROS, ITERATIONS AND CONDITIONALS
00400
00500 MI PERFORM NOW THE TEXT IN Q-REGISTER I AS A SERIES OF COMMANDS.
00600 <> ITERATION BRACKETS. COMMAND INTERPRETATION IS SENT BACK TO THE <,
00700 WHEN THE > IS ENCOUNTERED.
00800 N; IF NOT IN AN ITERATION, GIVES AN ERROR. IF IN AN ITERATION AND
00900 IF THE VALUE OF N IS NEGATIVE, THIS COMMAND HAS NO EFFECT. IF
01000 N IS 0 OR GREATER, COMMAND INTERPRETATION IS SENT JUST PAST THE
01100 MATCHING RIGHT-ANGLE BRACKET TO THE RIGHT. OTHERWISE, NO EFFECT.
01200 ; IF NOT IN AN ITERATION, GIVES AN ERROR. IF IN AN ITERATION AND
01300 IF THE MOST RECENT SEARCH FAILED, SEND COMMAND TO FIRST UNMATCHED
01400 RIGHT-ANGLE BRACKET TO THE RIGHT. OTHERWISE, NO EFFECT.
01500 !TAG! TAG DEFINITION. THE TAG IS A NAME FOR THE LOCATION IT APPEARS
01600 IN IN A MACRO, ITERATION OR COMMAND STRING.
01700 OTAG$ GO TO THE TAG NAMED TAG. THE TAG MUST APPEAR IN THE CURRENT
01800 MACRO,ITERATION OR COMMAND STRING.
01900 N"G HAS NO EFFECT IF N IS GREATER THAN 0. OTHERWISE, SEND COMMAND INTERPRETATION
02000 TO NEXT MATCHING '. THE " AND ' MATCH SIMILAR TO ( AND ).
02100 N"L SEND COMMAND TO MATCHING ' UNLESS N IS LESS THAN 0.
02200 N"N SEND COMMAND TO MATCHING ' UNLESS N NOT = 0.
02300 N"E SEND COMMAND TO MATCHING ' UNLESS N=0.
02400 N"C SEND COMMAND TO MATCHING ' UNLESS THE VALUE OF N AS AN ASCII
02500 CHARACTER IS A LETTER, NUMBER, PERIOD (.), DOLLAR SIGN ($),
02600 OR PER CENT (%).
02700 >;CD9(M)
02800 ;MI PERFORM NOW THE TEXT IN Q-REGISTER I AS A SERIES OF COMMANDS.
02900
03000 MAC: PUSHJ P,QREGVI ;A:=C(Q-REG)
03100 PUSH P,COMAX(R) ;SAVE CURRENT COMMAND STATE
03200 PUSH P,CPTR(R)
03300 PUSH P,COMCNT(R)
03400 TLZE A,400000 ;MAKE SURE Q-REG CONTAINS TEXT
03500 TLZE A,377777
03600 JSR ERR ;Q-REG DOES NOT CONTAIN TEXT
03700 ADD A,QRBUF(R)
03800 MOVE IN,A
03900 PUSHJ P,GETINC ;GET FIRST CHARACTER OF MACRO
04000 CAIE CH,141 ;IT SHOULD BE FLAG
04100 JSR ERR ;OOPS
04200 PUSHJ P,GETINC ;GET NUMBER OF CHARACTERS IN MACRO
04300 MOVE A,CH
04400 PUSHJ P,GET
04500 ROT CH,7
04600 IOR A,CH
04700 SUBI A,3 ;-FLAG AND COUNT
04800 MOVEM A,COMCNT(R) ;THAT MANY COMMANDS TO COUNT
04900 MOVEM A,COMAX(R) ;AND MAX.
05000 IDIVI IN,5
05100 MOVE OUT,BTAB(<OUT>) ;MAKE A BYTE POINTER
05200 HRR OUT,IN
05300 MOVEM OUT,CPTR(R) ;PUT IT IN CPTR
05400 JRST CD5 ;DON'T FLUSH ANY ARGUMENTS
00100 ;CD9(<)
00200 ;<> ITERATION BRACKETS. COMMAND INTERPRETATION IS SENT
00300 ; BACK TO THE < WHEN THE > IS ENCOUNTERED.
00400
00500 LSSTH: AOS INTDPH(R)
00600 PUSH P,ITERCT(R) ;SAVE ITERATION COUNT
00700 PUSH P,CPTR(R) ;SAVE COMMAND STATE
00800 PUSH P,COMCNT(R)
00900 SETOM ITERCT(R) ;ITERCT:=-1
01000 TRZE FF,ARG ;IS THERE AN ARGUMENT?
01100 MOVEM B,ITERCT(R) ;YES. ITERCT:=ARGUMENT
01200 JRST LSSTH1
01300
01400
01500 ;CD9(>)
01600
01700 GRTH: SKIPG INTDPH(R) ;IS THERE A LEFT ANGLE BRACKET?
01800 JSR ERR ;NO.
01900 TRZ FF,ITERF ;YES
02000 SOSN ITERCT(R) ;ITERCT:=ITERCT-1. DONE?
02100 JRST INCMA2 ;YES
02200 MOVE A,-1(P) ;NO. RESTORE COMMAND STATE TO START OF ITERATION.
02300 MOVEM A,CPTR(R)
02400 MOVE A,(P)
02500 MOVEM A,COMCNT(R)
02600 TRNE FF,TRACEF ;TRACING?
02700 PUSHJ P,CRR ;YES. OUTPUT CRLF
02800
02900
03000 ;FROM LSSTH+7
03100
03200 LSSTH1: TRO FF,ITERF
03300 JRST RET
03400
03500
03600
03700
03800
03900
04000
04100 U ITERCT,1 ;INCMA2+2,GRTH+3,LSSTH+4(-1),LSSTH+6
04200 U INTDPH,1 ;LIS+3(0),INCMA2
04300 U SFINDF,1 ;INIT+21(0),FND+2(-1),NOFND+2(0),SEMICL+3
00100 ;CD9(;)
00200 ;; IF NOT IN AN ITERATION, GIVES ERROR. IF IN AN ITERATION AND
00300 ; IF THE MOST RECENT SEARCH FAILED, SEND COMMAND TO FIRST UNMATCHED
00400 ; > TO THE RIGHT. OTHERWISE, NO EFFECT.
00500
00600 SEMICL: TRNN FF,ITERF ;IN < > ?
00700 JSR ERR ;NO. LOSE.
00800 TRNN FF,ARG ;YES. IF NO ARG,
00900 MOVE B,SFINDF(R) ;USE LAST SEARCH SWITCH (0 OR -1).
01000
01100 INCMA: JUMPL B,CD ;IF ARG <0, JUST RET + EXECUTE LOOP
01200 MOVEI A,0 ;INIT COUNT OF <>
01300 INCMA1: PUSHJ P,SKRCH1 ;GET A CHAR
01400 CAIN CH,"<" ;<?
01500 AOJA A,INCMA1 ;YES. COUNT AND LOOP.
01600 CAIE CH,">" ;>?
01700 JRST INCMA1 ;NO. LOOP.
01800 SOJGE A,INCMA1 ;YES. LOOP IF MORE TO GO. COUNT.
01900
02000 ;FROM GRTH+4
02100
02200 INCMA2: SOS INTDPH(R) ;POP OUT A LEVEL
02300 SUB P,[XWD 2,2]
02400 POP P,ITERCT(R)
02500 JRST RET
02600
02700
02800
02900 ;CD9(!)
03000 ;!TAG! TAG DEFINITION. THE TAG IS A NAME FOR THE LOCATION IT
03100 ; APPEARS IN IN A MACRO, ITERATION OR COMMAND STRING.
03200
03300 EXCLAM: PUSHJ P,SKRCH ;EXCLAM JUST INCREMENTS PAST ANOTHER !-5
03400 CAIE CH,"!"
03500 JRST .-2
03600 JRST RET
03700
03800
03900
04000
00100 ;CD9(O)
00200 ;OTAG$ GO TO THE TAG NAMED TAG. THE TAG MUST APPEAR IN THE
00300 ; CURRENT MACRO OR COMMAND STRING.
00400
00500 OG: MOVE A,CPTR(R)
00600 MOVE AA,A
00700 IDIVI AA,17
00800 CAMN A,SYMS(B)
00900 JRST OGFND
01000 SKIPN SYMS(B)
01100 JRST OGNF
01200 CAMN A,SYMS+1(B)
01300
01400 ;FROM ES2+2
01500
01600 ES1: AOJA B,OGFND
01700 SKIPN SYMS+1(B)
01800 ES2: AOJA B,OGNF
01900 CAMN A,SYMS+2(B)
02000 AOJA B,ES1
02100 SKIPN SYMS+2(B)
02200 ADDI B,2
02300
02400 ;FROM OG+6,ES2
02500
02600 OGNF: PUSH P,CPTR(R)
02700 PUSH P,B
02800 MOVEI D,STAB+1
02900 MOVEI A,41
03000 MOVEM A,-1(D) ;STAB←"!"
03100 PUSHJ P,SKRCH
03200 MOVEM CH,(D) ;STAB+1 ... ← TAG
03300 CAIE CH,175
03400 AOJA D,.-3
03500 MOVEM A,(D) ;ALTMODE: STAB+N←"!"
03600 MOVE B,COMCNT(R)
03700 SUB B,COMAX(R) ;# REMAINING COMMANDS
03800 IDIVI B,5
03900 ADD B,CPTR(R) ;MAKE A COMMAND POINTER
04000 JUMPE E,OG2
04100 SOS B
04200 MOVMS E
04300 JRST .(E)
04400 IBP B
04500 IBP B
04600 IBP B
04700 IBP B
00100 OG2: MOVE AA,COMAX(R) ;ALL COMMANDS
00200 OG4: MOVEM B,CPTR(R)
00300 MOVEM AA,COMCNT(R)
00400 MOVEI E,STAB ;INIT SEARCH STRING TO "!"
00500 OG5: CAIN E,1(D) ;OVER STRING?
00600 JRST OG3 ;YES
00700 PUSHJ P,SKRCH1 ;NO. GET A CHAR
00800 CAMN CH,(E) ;MATCH ?
00900 AOJA E,OG5 ;YES. MOVE ON.
01000 IBP B ;NO. TRY A NEW STARTING PT
01100 SOJA AA,OG4 ;COUNT DOWN COMMANDS
01200
01300
01400
01500
01600 OG3: POP P,A
01700 POP P,SYMS(A)
01800 MOVEM AA,CNTS(A)
01900 MOVEM B,VALS(A)
02000 JRST RET
02100
02200
02300
02400
02500 ;FROM OG+4,ES1
02600
02700 OGFND: MOVE A,VALS(B)
02800 MOVEM A,CPTR(R)
02900 MOVE A,CNTS(B)
03000 MOVEM A,COMCNT(R)
03100 JRST RET
03200
03300
00100 ;CD9(")
00200 ;N"G HAS NO EFFECT IF N IS GREATER THAT 0. OTHERWISE,
00300 ; SEND COMMAND INTERPRETATION TO NEXT MATCHING '.
00400 ; THE " AND ' MATCH SIMILAR TO ( AND ).
00500 ;N"L SEND COMMAND TO MATCHING ' UNLESS N<0.
00600 ;N"N SEND COMMAND TO MATCHING ' UNLESS N NOT = 0.
00700 ;N"E SEND COMMAND TO MATCHING ' UNLESS N=0.
00800 ;N"C SEND COMMAND TO MATCHING ' UNLESS THE VALUE OF N AS AN ASCII
00900 ; CHARACTER IS A LETTER, NUMBER, PERIOD (.), DOLLAR SIGN ($),
01000 ; OR PER CENT (%).
01100
01200 DQUOTE: TRNN FF,ARG
01300 JSR ERR
01400 PUSHJ P,RCH
01500 MOVSI A,0
01600 CAIN CH,"G"
01700 MOVSI A,327000+B*40 ;A:=JUMPG B,
01800 CAIN CH,"L"
01900 MOVSI A,321000+B*40 ;A:=JUMPL B,
02000 CAIN CH,"N"
02100 MOVSI A,326000+B*40 ;A:=JUMPN B,
02200 CAIN CH,"E"
02300 MOVSI A,322000+B*40 ;A:=JUMPE B,
02400 CAIN CH,"C"
02500 JRST DQT1
02600 JUMPE A,ERRA
02700 HRRI A,RET
02800 XCT A
02900
03000 ;FROM DQT1+2
03100
03200 NOGO: MOVEI A,0 ;NOGO INCREMENTS COMMAND POINTER OVER
03300 ;A SINGLE QUOTE,SKIPPING PAIRS OF " & '.
03400 PUSHJ P,SKRCH1
03500 CAIN CH,42 ;DOUBLE QUOTE
03600 AOJA A,.-2
03700 CAIN CH,"'" ;SINGLE QUOTE
03800 SOJL A,RET
03900 JRST .-5
04000
04100
00100 ;FROM DQUOTE+15
00200
00300 DQT1: PUSHJ P,DQT3
00400 JRST RET
00500 JRST NOGO
00600
00700 ;FILSFL+11,CNTRX+5
00800
00900 DQT2: MOVE B,CH
01000
01100 ;ROUTINE TO TEST CHARACTER FOR $,%,.,0-9,A-Z
01200 ;CALL MOVE B,CHARACTER
01300 ; PUSHJ P,DQT3
01400 ; RETURN IF $,%,.,0-9,A-Z
01500 ; RETURN ON ALL OTHER CHARACTERS
01600
01700 ;FROM DQT1
01800
01900 DQT3: CAIE B,"$" ;$ OR %?
02000 CAIN B,"%"
02100 POPJ P, ;YES
02200 CAIN B,"." ;NO. POINT?
02300 POPJ P, ;YES.
02400 CAIGE B,"0" ;NO. DIGIT OR LETTER?
02500 JRST POPJ1 ;NO
02600 CAIG B,"9" ;MAYBE. DIGIT?
02700 POPJ P, ;YES.
02800 CAIGE B,"A" ;NO. LETTER?
02900 JRST POPJ1 ;NO.
03000 CAIG B,"Z"
03100 POPJ P, ;YES.
03200 POPJ1: AOS 0(P) ;NO.
03300 POPJ P,0
03400
00100 REPEAT 0,<
00200
00300 XII. SOME SIMPLE EXAMPLES OF EDITING
00400
00500 1. TO COPY THE ASCII FILE PGM.MAC ON DECTAPE 3, PUTTING THE NEW VERSION
00600 ON TAPE 2 WITH THE FILE NAME PGM2.MAC:
00700 ERDTA3:PGM.MAC$EWDTA2:PGM2.MAC$Y1000PEF$$
00800
00900 2. SAME AS (1), BUT IN THE NEW COPY CHANGE THE TITLE LINE FROM
01000 TITLE PGM1 J. SMITH TO TITLE PGM2 W. JONES.
01100 ERDTA3:PGM.MAC$EWDTA2:PGM2.MAC$
01200 YNTITLE PGM$KI2 W. JONES$-1LT$$
01300 (TECO WILL TYPE OUT THE CORRECTED LINE)
01400 1000PEF$$
01500
01600 3. TO COUNT LINE FEEDS IN THE BUFFER:
01700 J0UN<S
01800 $;%N>QN=$$
01900
02000 4. TO REPLACE ALL INSTANCES OF JUMPA WITH JRST
02100 J<SJUMPA$;-4DIJRST$>$$
02200
02300 5. TO CHANGE, THROUGHOUT THE BUFFER, A TO B, WHEREVER THE A
02400 IS FOLLOWED BY A DIGIT (ASCII CODE 48(BASE 10) THROUGH
02500 57(BASE 10)):
02600 J<SA$; 1A-47"G1A-58"L-1DIB$''>$$
02700
02800 6. TO MOVE THE POINTER TO THE LEFT OF THE FIRST CHARACTER THAT IS
02900 NOT A SPACE (I.E., TO SPACE IT OVER A ROW OF SPACES):
03000 !BK!1A-32"E1COBK$'
03100
03200 7. TO READ AND PERFORM A COMMAND STRING:
03300 YHXZMZ$$
03400
03500 WITH COMPLICATED LOOPS AND ITERATIONS IT IS GENERALLY WISE TO
03600 PERFORM THEM AS MACROS SO THAT THEIR TEXT IS IN Q-REGISTERS
03700 FOR DEBUGGING AND EDITING.
03800 8. TO MOVE ON TO A PAGE WHICH ONE WOULD RECOGNIZE BUT CANNOT
03900 DESCRIBE IN SUFFICIENT DETAIL TO USE N :
04000 <HVW-127;P>$$
04100 AS EACH PAGE APPEARS ON THE SCOPE, TYPE IN ANY CHARACTER
04200 EXCEPT RUBOUT (=127(BASE 10)) TO PROCEED TO THE NEXT PAGE, OR
04300 IF THIS IS A PAGE TO BE EDITED TYPE RUBOUT TO LEAVE THE
04400 ITERATION.
04500 >
00100 REPEAT 0,<
00200
00300 XIII. ERRORS
00400
00500 IT IS CONCEDED THAT TECO'S ERROR MESSAGES ARE NOT OVERLY
00600 INFORMATIVE. FOR ALL ILLEGAL OR MEANINGLESS COMMANDS TECO TYPES OUT
00700 ? AND IGNORES THE REMAINDER OF THE COMMAND STRING, RETURNING TO THE
00800 IDLE STATE. AT THIS POINT THE USER MAY TYPE ? BACK IN, AND TECO
00900 WOULD THEN RESPOND BY TYPING OUT 10 CHARACTERS OF THE COMMAND STRING,
01000 ENDING WITH THE BAD COMMAND. SEARCH COMMANDS ARE "BAD" IF THEY FAIL AND
01100 THE : MODIFIER WAS NOT USED.
01200
01300 >
01400
01500
01600 ;FROM LI3+10
01700
01800 ERRTYP: MOVE AA,ERR2(R) ;VALUE OF CPTR WHEN LAST ERROR OCCURRED.
01900 MOVEI B,12
02000 SUBI AA,2 ;BACK POINTER UP 10 CHARACTERS.
02100 ILDB CH,AA ;GET CHARACTER
02200 CAMG B,ERR1(R) ;WAS IT IN THE COMMAND BUFFER?
02300 PUSHJ P,TYO ;YES. TYPE IT.
02400 CAME AA,ERR2(R) ;HAVE WE REACHED THE BAD COMMAND?
02500 SOJA B,.-4 ;NO. DO IT AGAIN.
02600 JSR ERR ;YES. TYPE ? CRLF AND WAIT FOR NEXT COMMAND.
02700
02800 ;FROM INI,SKRCH+1,SKRCH1,COMMA+3,CLOSE+1,CHK+2,CHK1+5,YANK09+4,
02900 ;INERR+2,SERCH4+4,NOFND2+2,USE+1,QREG+4,PRNT+1,DQUOTE+1,CALDDT+2,SEMICL+1,
03000 ;GRTH+1,LINE+1,MAC+6,MAC+14,X+2,QGET+4,ECMD+15,
03100 ;EMTAPE+1,EMTAPE+5,ININER+6,LKUPE+2,FILSPL+13,FILS4L+5,FILS5L+5,ENTERR+2
03200
03300 ERR: 0
03400
03500 ;CD9(↑B,↑C,↑E,↑H,↑K,↑L,↑N,↑O,↑P,↑Q,↑R,↑S,↑T,↑U,↑V,↑W,↑X,↑Y
03600 ;↑Z,↑[,↑\,↑],↑←,$,V,130-134,136,137),DQUOTE+16,PPA09+2
03700
03800 ERRA:
03900 MOVEI CH,"?" ;TYPE ? CRLF
04000 PUSHJ P,TYO
04100 PUSHJ P,CRR
04200 TRO FF,QMFLG ;SET ? FLAG.
04300 MOVE A,COMAX(R)
04400 SUB A,COMCNT(R)
04500 MOVEM A,ERR1(R) ;ERR1:=COMAX-COMCNT
04600 MOVE A,CPTR(R)
04700 MOVEM A,ERR2(R) ;ERR2:=CPTR
04800 JRST GO ;GET NEXT COMMAND
04900
05000
05100
05200 U ERR1,1 ;ERRA+6
05300 U ERR2,1 ;ERRA+10
00100 ;UUO HANDLER
00200 ;HALTS ON UNDEFINED UUO
00300 ;CALL TYPR1 X
00400 ;PRINTS STRING AT X TERMINATED BY ! AND REINITIALIZES AT GOZ.
00500
00600 ETYPER: 0
00700 HLRZ B,40
00800 CAIE B,30000 ;TYPR1?
00900 JRST 4,. ;NO. OOPS
01000 HRLZI B,440700 ;YES. ADDRESS POINTS TO MESSAGE TERMINATED BY !
01100 HRR B,40
01200 ILDB CH,B
01300 CAIN CH,"!" ;END OF MESSAGE?
01400 JRST GOZ ;YES. REINITIALIZE
01500 PUSHJ P,TYO ;NO. PRINT A CHARACTER
01600 JRST .-4
01700
01800 U LISTF5,1 ;OUTPUT DISPATCH
01900
02000
02100
02200 XXTY01: ASCII /STORAGE CAPACITY EXCEEDED
02300 !/
02400 XXTY02: ASCII /GC ERROR
02500 !/
02600
02700
02800
02900 ILMEM: REPEAT 0,<
03000 JRST . ;THIS SHOULD BE FIXED UP
03100 CONSO 200000
03200 MOVEI B,10
03300 MOVE P,[XWD -LPDL,PDL]
03400 MOVEI CH,7
03500 PUSHJ P,TYO
03600 SOJG B,.-1
03700 JRST 10,ERR+1
03800 >
00100 REPEAT 0,<
00200
00300 XIV. DEBUGGING FEATURES
00400
00500 AS AN AID TO DEBUGGING MACROS AND ITERATIONS, TECO WILL
00600 WHEN IN TRACE MODE TYPE ON THE TELETYPE EACH COMMAND AS IT IS INTERPRETED,
00700 INTERSPACED WITH REQUESTED TELETYPE OUTPUT. TRACE MODE IS CONTROLLED
00800 BY A FLIP-FLOP WHICH IS CONTROLLED AS FOLLOWS:
00900
01000 ? WHEN NOT THE FIRST COMMAND OF A COMMAND STRING, COMPLEMENTS
01100 THE TRACE FLIP-FLOP.
01200 TECO ALSO ALLOWS THE USER TO INSERT COMMENNTS:
01300
01400 ↑ATEXTCTRL A
01500 OUTPUTS TO THE TELETYPE THE TEXT UP TO BUT NOT INCLUDING THE
01600 TERMINATING CTRL A. THE TEXT IS OTHERWISE IGNORED AND COMMAND
01700 INTERPRETATION RESUMES AFTER THE TERMINATING CTRL A. SINCE
01800 THE TERMINATOR IS NOT A COMMAND, IT MUST BE TYPED WITH THE
01900 CTRL KEY AND MAY NOT BE TYPED AS ↑A.
02000
02100 LASTLY, IF DDT HAS BEEN LOADED WITH TECO,
02200 ↑D TRANSFERS CONTROL TO DDT.
02300 >
02400
02500
02600
00100 ;CD9(?)
00200
00300 QUESTN: MOVE A,[JRST TYO]
00400 TRCE FF,TRACEF
00500 MOVSI A,263000+P*40 ;TRACS:=POPJ P,
00600 MOVEM A,TRACS(R)
00700 JRST RET
00800
00900
01000 COMMENT: PUSHJ P,SKRCH ;GET A COMMENT CHAR
01100 CAIN CH,1 ;↑A
01200 POPJ P,0 ;DONE
01300 PUSHJ P,TYO ;TYPE IT
01400 JRST COMMENT ;AND LOOP
01500
01600
01700
01800
01900
02000 ;CD9(↑D)
02100
02200 CALDDT: SKIPE T,JOBDDT(R)
02300 JRST (T)
02400 JSR ERR
02500
02600
02700
02800
02900
00100 ;ROUTINE TO RETURN STRING OPERATION STRING ARGUMENTS.
00200 ;ARGUMENTS ARE CHARACTER ADDRESSES IN THE DATA BUFFER.
00300 ;TRANSFORMS M,N OR N, WHERE THE LATTER SPECIFIES A NUMBER OF LINES,
00400 ;TO ARGUMENTS.
00500 ;CALL PUSHJ P,GETARG
00600 ; RETURN WITH FIRST ARGUMENT ADDRESS IN C, SECOND IN B.
00700
00800
00900
01000 ;FROM KILL,TYPE+1,LINE+2,X
01100
01200 GETARG: TRNE FF,ARG2 ;IS THERE A SECOND ARGUMENT?
01300 JRST GETAG6 ;YES
01400
01500 ;N SIGN INDICATES DIRECTION RELATIVE TO PT.
01600 TRON FF,ARG ;NO. IS THERE AN ARGUMENT?
01700 PUSHJ P,CHK22 ;NO. B:=1 IS LAST ARGUMENT FUNCTION WAS +,*,OR /
01800 ;B:=-1, IF &,#, OR -
01900 ;IE, ASSUME AN ARGUMENT OF 1 AND RETAIN SIGN
02000 MOVE IN,PT(R) ;IN:=PT
02100 GETAG4: JUMPLE B,GETAG2 ;WAS LAST ARGUMENT FUNCTION -?
02200 CAMN IN,Z(R) ;NO. ARGUMENT IS LOCATION OF NTH LINE
02300 ;FEED FORWARD FROM PT.
02400 ;IS PT AT END OF BUFFER?
02500 JRST GETAG1 ;YES.
02600 PUSHJ P,GETINC ;NO. CH:=NEXT DATA BUFFER CHARACTER, IN:=IN+1
02700 CAIE CH,12 ;LINE FEED?
02800 JRST GETAG4 ;NO. TRY AGAIN.
02900 SOJG B,GETAG4 ;YES. NTH LINE FEED?
03000
03100
03200 GETAG1: MOVE B,IN ;YES. RETURN FIRST ARGUMENT IN C
03300 MOVE C,PT(R) ;SECOND IN B.
03400 POPJ P,
03500
03600 ;M,N
03700 GETAG6: ADD B,BEG(R) ;C:=M+BEG
03800 ADD C,BEG(R) ;B:=N+BEG
03900 POPJ P,
04000
04100 GETAG2: SOS IN ;ARGUMENT IS POSITION OF NTH LINE FEED TO LEFT OF PT.
04200 ;N:=N-1
04300 CAMG IN,BEG(R) ;PASSED BEGINNING OF BUFFER?
04400 JRST GETAG3 ;YES. IN:=BEG
04500 PUSHJ P,GETINC ;NO. CH:=NEXT DATA BUFFER CHARACTER. IN:=IN+1
04600 CAIE CH,12 ;LINE FEED?
04700 SOJA IN,GETAG2 ;NO. BACK UP ONE POSITION AND TRY AGAIN.
04800 AOJLE B,.-1 ;YES. NTH LINE FEED?
04900
05000 GETAG3: CAMGE IN,BEG(R) ;YES. PASSED BEGINNING OF BUFFER?
05100 MOVE IN,BEG(R) ;YES. RESET TO BEGINNING.
05200 MOVE C,IN ;NO. RETURN FIRST ARGUMENT IN C.
05300 MOVE B,PT(R) ;SECOND IN B
05400 POPJ P,
05500
05600
05700
00100 ;ROUTINE TO RETURN IN CH THE CHARACTER TO THE RIGHT OF THE POINTER
00200 ;AND INCREMENT THE POINTER.
00300 ;CALL MOVE IN,POINTER (AS A CHARACTER ADDRESS)
00400 ; PUSHJ P,GETINC
00500 ; RETURN WITH CHARACTER IN CH AND POINTER TO CHARACTER IN IN.
00600
00700 ;FROM SERCH3+2,TYPE3+2,BAKSLA+2,MAC+12,MAC+15,X1+4,QGET+10,QGET+12,
00800 ;QGET1+1,GETAG4+3,GETAG2+3,GCS4A+1,GCERR+1,GCERR+3
00900
01000 GETINC: PUSHJ P,GET
01100 AOJA IN,CPOPJ
01200
01300 ;FROM APPND1+1,MAC+17,GETINC,GCM2+2
01400
01500 GET: MOVE TT,IN
01600 IDIVI TT,5
01700 HLL TT,BTAB(TT1)
01800 LDB CH,TT
01900 POPJ P,
02000
02100 ;FROM YANK5+7,INS1B+4,TAC2+3,X+21,X+24,X1,QGET1+2
02200
02300 PUT: MOVE TT,OUT
02400 IDIVI TT,5
02500 HLL TT,BTAB(TT1)
02600 DPB CH,TT
02700 POPJ P,
02800
02900 ;CHARACTER TRANSLATION BYTE POINTER TABLE
03000 ;TRANSLATES 1 CHARACTER POSITION TO THE RIGHT OF A CHARACTER ADDRESS POINTER
03100
03200 BTAB: XWD 350700+R,0
03300 XWD 260700+R,0
03400 XWD 170700+R,0
03500 XWD 100700+R,0
03600 XWD 10700+R,0
03700
03800
03900
04000
04100 TYOM: PUSH P,C ;TYO TO MEMORY
04200 PUSH P,OUT
04300 PUSH P,TT
04400 PUSH P,TT1
04500 PUSHJ P,TAB2
04600 POP P,TT1
04700 POP P,TT
04800 POP P,OUT
04900 POP P,C
05000 POPJ P,
05100
00100
00200 ;FROM DELETE+7,INSERT+13,TAB2+1,BAKSL1+10,X+12,QGET+21
00300
00400 NROOM: MOVEM 17,AC2+15(R) ;SAVE 17
00500 MOVE 17,PT(R)
00600 CAMN 17,Z(R) ;PT=Z? I.E., DATA BUFFER EXPANSION?
00700 JRST NROOM1 ;YES.
00800 MOVE 17,[XWD 2,AC2] ;NO. SAVE ACS 2 THROUGH 16.
00900 IFN <R>,< ADDI 17,(R) ;RELOCATE BLT POINTER ADDRESS.>
01000 BLT 17,AC2+14(R)
01100 JUMPL C,NROOM6 ;DELETION?
01200 SETOM GCFLG(R) ;NO.
01300 SETZM CRREL(R)
01400 SETZM RREL(R)
01500
01600 ;MOVE STRING STORAGE UP C CHARACTERS STARTING AT PT.
01700 ;FROM GC+26,GCS2+2
01800
01900 NROOM9: MOVE 17,Z(R)
02000 ADD 17,C
02100 CAML 17,MEMSIZ(R) ;WILL REQUEST OVERFLOW MEMORY?
02200 JRST GC ;YES. GARBAGE COLLECT.
02300 ;MOVE FROM PT THROUGH Z UP C POSITIONS
02400 MOVE 14,C ;NO.
02500 IDIVI 14,5 ;AC14:=Q(REQ/5), AC15:=REM(REQ/5)
02600 IMULI 15,7 ;AC15:=(REM(REQ/5))*7
02700 MOVN 13,15 ;AC13:=-(REM(REQ/5))*7
02800 MOVEI 15,-43(15) ;AC15:=(REM(REQ/5))*7-43
02900 MOVE 11,PT(R)
03000 IDIVI 11,5 ;AC11:=Q(PT/5), AC12:=REM(PT/5)
03100 MOVNI 16,-5(12)
03200 IMULI 16,7 ;AC16:=-(REM(PT/5)-5)*7
03300 DPB 16,[XWD 300600+R,NROOM2] ;SET SIZE FIELD OF LAST PARTIAL WORD POINTER.
03400 ADDI 14,1(11) ;AC14:=Q(REQ/5)+Q(PT/5)+1
03500 MOVE 16,Z(R)
03600 IDIVI 16,5 ;AC16:=Q(Z/5)
03700 MOVEI B,1(16)
03800 SUB B,11 ;B:=Q(Z/5)+1-Q(PT/5)=NO. OF WORDS TO MOVE.
03900 ;PUT MOVE ROUTINE IN FAST ACS
04000 HRLI 11,200000+B+A*40 ;AC11:=MOVE A,[Q(PT/5)](B)
04100 HRLOI 12,241000+A*40 ;AC12:=ROT A,-1
04200 HRLI 13,245000+A*40 ;AC13:=ROTC A,-(REM(REQ/5))*7
04300 HRLI 14,202000+B+AA*40 ;AC14:=MOVEM AA,[Q(PT/5)+1](B)
04400 HRLI 15,245000+A*40 ;AC15:=ROTC A,(REM(REQ/5))*7-43
04500 MOVE 17,[JRST,NROOM7] ;AC16:=SOJGE B,11
04600 MOVE 16,.+1 ;AC17:=JRST NROOM7
04700 SOJGE B,11 ;B:=B-1. DONE?
04800 NROOM7: ROTC A,43(13) ;YES. STORE LAST PARTIAL WORD.
04900 DPB A,NROOM2(R)
05000 ADDM C,Z(R) ;Z:=Z+REQ
05100
00100 ;FROM NROOM3+1
00200
00300 NROOM5: MOVE 17,[XWD 2,AC2] ;RESTORE ACS AND RETURN.
00400 IFN <R>,< ADDI 17,(R) ;RELOCATE BLT POINTER ADDRESS>
00500 MOVSS 17
00600 BLT 17,17
00700 POPJ P,
00800
00900
01000 U NROOM2,1 ;POINTER TO LAST PARTIAL WORD ON UPWARD MOVE.
01100
01200 ;EXPAND DATA BUFFER
01300 ;FROM NROOM+3
01400
01500 NROOM1: ADDM C,Z(R) ;PT=Z. Z:=Z+REQ
01600 PUSH P,C ;SAVE REQUEST
01700 MOVE C,Z(R)
01800 CAML C,MEMSIZ(R) ;DID WE OVERFLOW MEMORY?
01900 JRST GC1 ;YES. GARBAGE COLLECT.
02000 POP P,C ;GARBAGE COLLECTION WAS SUCCESSFUL. RESTORE REQUEST.
02100 MOVE 17,AC2+15(R) ;RESTORE 17
02200 POPJ P, ;RETURN
02300
00100 ;MOVE FROM PT+ABS(C) THROUGH Z DOWN ABS(C) POSITIONS.
00200 ;FROM NROOM+6
00300
00400 NROOM6: MOVE 14,PT(R) ;INITIALIZE PARTIAL WORD POINTER.
00500 IDIVI 14,5 ;AC14:=Q(PT/5), AC15:=REM(PT/5)
00600 MOVEM 14,B ;B:=Q(PT/5)
00700 HRRM 14,NROOM4(R)
00800 IMULI 15,7
00900 DPB 15,[XWD 300600+R,NROOM4] ;SIZE:=(REM(PT/5))*7
01000 MOVNI 15,-44(15)
01100 DPB 15,[XWD 360600+R,NROOM4] ;POSITION:=44-(REM(PT/5))*7
01200 MOVE 11,Z(R)
01300 IDIVI 11,5 ;AC11:=Q(Z/5)+1, AC12:=REM(Z/5)
01400 ADDI 11,1
01500 MOVE 13,C
01600 IDIVI 13,5
01700 ADDI 13,-1(11) ;AC13:=Q(Z/5)-Q(REQ/5)
01800 MOVNM 14,12 ;AC12:=(REM(REQ/5))*7
01900 IMULI 12,7
02000 MOVNI 15,-43(12) ;AC15:=43-(REM(REQ/5))*7
02100 SUBI B,1(13) ;B:=Q(PT/5)+Q(REQ/5)-Q(Z/5)-1:=# WORDS TO MOVE
02200
02300 NROOM8: HRLI 11,200000+B+AA*40 ;AC11:=MOVE AA,[Q(Z/5)+1](B)
02400 HRLI 12,245000+A*40 ;AC12:=ROTC A,(REM(REQ/5))*7
02500 HRLI 13,202000+B+A*40 ;AC13:=MOVEM A,[Q(Z/5)-Q(REQ/5)](B)
02600 MOVE 14,[ADDM A,@13] ;AC14:=ADDM A,@13
02700 HRLI 15,245000+A*40 ;AC15:=ROTC A,43-(REM(REQ/5))*7
02800 MOVE 17,[JRST NROOM3] ;AC16:=AOJLE B,11
02900 ADDM C,Z(R) ;AC17:=JRST NROOM3
03000 LDB C,NROOM4(R)
03100 MOVE A,@11 ;Z:=C(Z)-REQ
03200 ROT A,-1 ;A:=Q(PT/5)+Q(REQ/5) RIGHT JUSTIFIED.
03300 MOVE 16,.+1
03400 AOJLE B,11 ;B:=B+1. DONE?
03500
03600 NROOM3: DPB C,NROOM4(R) ;YES. DEPOSIT PARTIAL WORD.
03700 JRST NROOM5
03800
03900 U NROOM4,1 ;PARTIAL WORD POINTER FOR DOWNWARD MOVE
04000 ;NROOM6+3
00100
00200 ;FROM NROOM9+3
00300
00400 GC: AOSE GCFLG(R) ;FIRST ATTEMPT?
00500
00600 ;FROM LI2+23,NROOM1+4
00700 GC1: TYPR1 XXTY01 ;NO. TYPE "STORAGE CAPACITY EXCEEDED"
00800
00900 SETOM GCPTR(R) ;YES. GCPTR:=-1
01000 SETZM SYMS(R) ;CLEAR SYMS,VALS AND CNTS TABLES
01100 MOVE T,[XWD SYMS,SYMS+1]
01200 IFN <R>,< ADD T,R>
01300 BLT T,SYMEND-1(R)
01400 MOVEI T,CPTR(R) ;COMMAND BUFFER
01500 PUSHJ P,GCMA
01600 HRRZ T,P
01700 SUBI T,(R)
01800 CAIL T,PDL(R) ;PUSHDOWN LIST EMPTY?
01900 PUSHJ P,GCMA ;NO. GARBAGE COLLECT ALL BYTE POINTERS ON IT.
02000 CAILE T,PDL(R)
02100 SOJA T,.-2
02200 HRRZ T,AC2+PF-2(R) ;GARBAGE COLLECT Q-REG PUSHDOWN LIST.
02300 CAIL T,PFL(R)
02400 PUSHJ P,GCM
02500 CAILE T,PFL(R)
02600 SOJA T,.-2
02700 MOVE T,[XWD -44,QTAB] ;GARBAGE COLLECT Q-REGISTERS.
02800 PUSHJ P,GCM
02900 AOBJN T,.-1
03000 SKIPGE GCPTR(R) ;ANYTHING TO COLLECT?
03100 JRST NROOM9 ;NOPE.
00100
00200 GCS: MOVE IN,QRBUF(R)
00300
00400 ;FROM GCERR+7
00500
00600 GCS1A: MOVSI TT,1*5 ;TT>MAX. NO. CHARACTERS IN WORLD
00700 MOVE OUT,GCPTR(R) ;GO BACKWARDS THROUGH GCTAB
00800 GCS1: HRRZI A,GCTAB(<OUT>) ;RELOCATE
00900 TLO A,R
01000 HRRZ A,@A
01100 ADD A,QRBUF(R)
01200 CAMGE A,IN
01300 JRST GCS2
01400 CAMGE A,TT ;SET TT TO HIGHEST CHARACTER POSITION
01500 MOVE TT,A
01600 GCS2: SOJGE OUT,GCS1
01700 TRNN TT,-1 ;ANYTHING TO COLLECT?
01800 JRST NROOM9 ;NOPE.
01900 MOVE F,TT ;HIGHEST CHARACTER.
02000 IDIVI IN,5 ;C(QRBUF)/5
02100 IDIVI F,5 ;HIGH CHAR/5
02200 AOS IN ;C(QRBUF)/5+1
02300 MOVS OUT,F
02400 MOVE T,F
02500 SUB T,IN ;HIGH CHAR/5-C(QRBUF)/5+1
02600 JUMPLE T,GCS4A ;ANYTHING TO GET?
02700 HRR OUT,IN ;XWD HIGH CH/5,HIGH CH/5-C(QRBUF)/5+1=NREG
02800 MOVE B,Z(R)
02900 IDIVI B,5
03000 SUB B,T ;Z/5-NREG
03100 HRLI B,R
03200 IFN <R>,< ADD OUT,R>
03300 BLT OUT,@B ;MOVE STUFF DOWN
03400 MOVNS OUT,T
03500 IMULI OUT,5 ;OUT:=-5*NREG
03600 ADDM OUT,BEG(R) ;BEG:=C(BEG)-5*NREG
03700 ADDM OUT,PT(R) ;PT:=C(PT)-5*NREG
03800 ADDM OUT,Z(R) ;Z:=C(Z)-5*NREG
03900 ADDM OUT,RREL(R) ;RREL:=C(RREL)-5*NREG
04000 MOVE CH,GCPTR(R) ;UPDATE INSERTER
04100 HRLI TT1,R
00100
00200 ;FROM GCS4
00300
00400 GCS3: HRRI TT1,GCTAB(CH)
00500 HRRZ A,@TT1
00600 ADD A,QRBUF(R)
00700 CAMGE A,TT
00800 JRST GCS4
00900 ADDM OUT,@TT1
01000 HLRZ A,@TT1
01100 CAIN A,CPTR(R) ;IN COMMAND BUFFER?
01200 ADDM OUT,CRREL(R) ;YES. UPDATE COMMAND POINTER RELOCATION
01300 HRLI A,R
01400 SKIPL @A ;Q-REG?
01500 ADDM T,@A ;NO
01600 SKIPGE @A ;Q-REG?
01700 ADDM OUT,@A ;YES. RELOCATE BASE POINTER.
01800
01900 ;FROM GCS3+3
02000
02100 GCS4: SOJGE CH,GCS3 ;DONE?
02200 ADD TT,OUT ;YES. IN:=C(TT)-5*NREG
02300
02400 ;FROM GCS2+12
02500
02600 GCS4A: MOVE IN,TT ;IN SHOULD POINT TO AN END OF STRING FLAG (141)
02700 PUSHJ P,GETINC
02800 CAIE CH,141
02900
03000 ;FROM GCM2+11
03100
03200 GCERR: TYPR1 XXTY02 ;STRANGE LOSS
03300
03400 PUSHJ P,GETINC
03500 MOVE A,CH
03600 PUSHJ P,GETINC
03700 ROT CH,7
03800 IOR A,CH
03900 ADDI IN,-3(A)
04000 JRST GCS1A
04100
00100 ;FROM GC+17,GC+23
00200
00300 GCM: MOVE IN,(T)
00400 TLZE IN,400000 ;DOES Q-REG CONTAIN TEXT?
00500 TLZE IN,377777
00600 POPJ P, ;NO
00700 ADD IN,QRBUF(R) ;YES. ENTER POINTER IN GCTAB
00800
00900 ;FROM GCMA+15
01000
01100 GCM2: CAML IN,BEG(R) ;REGION BEFORE TEXT BUFFER?
01200 POPJ P, ;NO. FORGET IT.
01300 PUSHJ P,GET ;YES. CHECK FOR MARK.
01400 CAIE CH,141 ;END OF STRING?
01500 POPJ P, ;NO.
01600 SUB IN,QRBUF(R) ;YES. IN:=# CHARACTERS TO RETREIVE.
01700 ; IN Q-REG BUFFER AREA?
01800 JUMPL IN,CPOPJ ;NO. FORGET IT.
01900 AOS TT,GCPTR(R) ;YES. TO BE GRABBED.
02000 CAIL TT,GCTBL ;AM I WINNING?
02100 JRST GCERR ;NO. VERY BAD.
02200 HRL IN,T ;XWD ADDRESS OF BYTE POINTER,NO. CHARACTERS
02300 ADDI TT,GCTAB ;RELOCATE
02400 HRLI TT,R
02500 MOVEM IN,@TT ;SAVE DATA
02600 POPJ P, ;DONE THIS POINTER
02700
02800 ;IF T POINTS TO AN ASCII BYTE POINTER, IN:=CHARACTER ADDRESS OF TOP
02900 ;OF STRING - NO. OF CHARACTERS.
03000 ;FROM GC+7,GC+12
03100
03200 GCMA: HRLI TT1,R
03300 HRR TT1,T
03400 LDB TT,[XWD 221420,TT1] ;BYTE SIZE + XR
03500 TRC TT,700 ;DOES T POINT TO A TEXT BYTE POINTER?
03600 TRCE TT,700
03700 POPJ P, ;NO
03800 SOS TT1
03900 MOVE IN,@TT1 ;MAYBE. GET WORD BEFORE POINTER. (MAX)
04000 ADDI TT1,2
04100 SUB IN,@TT1 ;MAX-CT
04200 SOS TT1
04300 LDB TT,[XWD 360620,TT1] ;BYTE POSITION
04400 IDIVI TT,7 ;NO. OF CHARACTERS
04500 MOVEI TT1,4-3+1 ;2
04600 SUB TT1,TT ;2-NO. OF CHARACTERS
04700 HRRZ TT,(T) ;POINTER WORD ADDRESS (UNRELOCATED)
04800 IMULI TT,5 ;5*ADDRESS
04900 ADD TT,TT1
05000 SUBM TT,IN ;5*ADDRESS-NO. CHARS+2+MAX-CT
05100 JRST GCM2
05200
05300
05400
00100 U BEG,1 ;INIT+32,LI2+15,X+17,GCS2+22
00200 U PT,1 ;INIT+33,LI2+16,YANK1+1,JMP1+1,KILL+2,DELETE+6,
00300 ;INS1B+5,TAB2+2,SRCH5A,FND+3,NOFND+1,BAKSL2+2
00400 ;LINE+4,X+11,X2+3,QGET+3,GCS2+23
00500 U Z,1 ;INIT+34,LI2+17,YANK51,NROOM9+35,NROOM1,NROOM8+6,GCS2+24
00600 U QRBUF,1 ;INIT+35,LI2+20
00700 ;*** DO NOT SEPARATE ***
00800 U COMAX,1 ;NO. CHARACTERS IN COMMAND BUFFER AT START OF EXECUTION
00900 ;RCH2+2,LI4+12,OG4,MAC+23
01000 U CPTR,1 ;COMMAND BUFFER BYTE POINTER
01100 ;RCH2+2,LI4+10,OGFND+1,GRTH+6,MAC+30
01200 U COMCNT,1 ;NO. CHARACTERS REMAINING IN COMMAND BUFFER
01300 ;RCH,RCH2+1,SKRCH1,LI3+2(0),LI3+7,LI3+23,LI4+5,OG4+1
01400 ;OGFND+4,GRTH+10,MAC+22
01500 ;*** DO NOT SEPARATE ***
01600 U CBUFH,1 ;INIT+37,LI3
01700 U MEMSIZ,1 ;INIT+13
01800 U GCPTR,1 ;GC+2(-1)
01900 U CRREL,1 ;NROOM+10(0),GCS3+7
02000 U GCFLG,1 ;NROOM+7(-1),GC
02100 U RREL,1 ;NROOM+11(0),GCS2+25
00100 ;COMMAND DISPATCH TABLE
00200 ;DISPATCH IS BY XCT DTB(CH)
00300 ;FORMAT:
00400 ; MOVEI A,X ;IF X RETURNS A VALUE
00500 ; HRROI A,X ;IF X DOES NOT RETURN A VALUE AND EXITS WITH POPJ
00600 ; JRST X ;IF X DOES NOT RETURN A VALUE AND EXITS TO A
00700 ; ;FIXED LOCATION.
00800
00900 DTB:
01000 HRROI A,ERRA ;↑@
01100 HRROI A,COMMENT ;↑A
01200 HRROI A,ERRA ;↑B
01300 HRROI A,ERRA ;↑C
01400 MOVEI A,CALDDT ;↑D
01500 HRROI A,ERRA ;↑E
01600 MOVEI A,LAT ;↑F
01700 MOVEI A,DECDMP ;↑G
01800 MOVEI A,GTIME ;↑H
01900 HRROI A,TAB ;↑I
02000 MOVEI A,CD ;↑J
02100 HRROI A,ERRA ;↑K
02200 HRROI A,TYO ;↑L
02300 MOVEI A,CD ;↑M
02400 HRROI A,ERRA ;↑N
02500 HRROI A,ERRA ;↑O
02600 HRROI A,ERRA ;↑P
02700 HRROI A,ERRA ;↑Q
02800 HRROI A,ERRA ;↑R
02900 HRROI A,ERRA ;↑S
03000 MOVEI A,SPTYI ;↑T
03100 HRROI A,ERRA ;↑U
03200 HRROI A,ERRA ;↑V
03300 HRROI A,ERRA ;↑W
03400 HRROI A,ERRA ;↑X
03500 HRROI A,ERRA ;↑Y
03600 HRROI A,ERRA ;↑Z
03700 HRROI A,ERRA ;↑[
03800 HRROI A,ERRA ;↑BACKSLASH
03900 HRROI A,ERRA ;↑]
04000 MOVEI A,CNTRUP ;↑↑
04100 HRROI A,ERRA ;↑LEFT ARROW
04200
00100
00200 MOVEI A,CD2 ;SPACE
00300 MOVEI A,EXCLAM ;!
00400 MOVEI A,DQUOTE ;"
00500 MOVEI A,COR ;#
00600 HRROI A,ERRA ;$
00700 MOVEI A,PCNT ;%
00800 MOVEI A,CAND ;&
00900 MOVEI A,CD ;SINGLE QUOTE
01000 MOVEI A,OPEN ;(
01100 MOVEI A,CLOSE ;)
01200 MOVEI A,TIMES ;*
01300 MOVEI A,CD2 ;+
01400 MOVEI A,COMMA ;,
01500 MOVEI A,MINUS ;-
01600 MOVEI A,PNT ;.
01700 MOVEI A,SLASH ;/
01800 JRST CDNUM ;0
01900 JRST CDNUM ;1
02000 JRST CDNUM ;2
02100 JRST CDNUM ;3
02200 JRST CDNUM ;4
02300 JRST CDNUM ;5
02400 JRST CDNUM ;6
02500 JRST CDNUM ;7
02600 JRST CDNUM ;8
02700 JRST CDNUM ;9
02800 MOVEI A,COLON ;:
02900 MOVEI A,SEMICL ;;
03000 MOVEI A,LSSTH ;<
03100 HRROI A,PRNT ;=
03200 MOVEI A,GRTH ;>
03300 MOVEI A,QUESTN ;?
00100
00200 MOVEI A,ATSIGN ;@
00300 MOVEI A,ACMD ;A
00400 MOVEI A,BEGIN ;B
00500 MOVEI A,CHARAC ;C
00600 MOVEI A,DELETE ;D
00700 HRROI A,ECMD ;E
00800 JRST RET ;F
00900 MOVEI A,QGET ;G
01000 MOVEI A,HOLE ;H
01100 HRROI A,INSERT ;I
01200 MOVEI A,JMP ;J
01300 MOVEI A,KILL ;K
01400 MOVEI A,LINE ;L
01500 JRST MAC ;M
01600 MOVEI A,SERCHP ;N
01700 MOVEI A,OG ;O
01800 HRROI A,PUNCH ;P
01900 MOVEI A,QREG ;Q
02000 MOVEI A,REVERS ;R
02100 MOVEI A,SERCH ;S
02200 HRROI A,TYPE ;T
02300 MOVEI A,USE ;U
02400 HRROI A,ERRA ;V
02500 MOVEI A,CD ;W
02600 MOVEI A,X ;X
02700 HRROI A,YANK ;Y
02800 MOVEI A,END1 ;Z
02900 MOVEI A,OPENB ;[
03000 MOVEI A,BAKSL ;BACKSLASH
03100 MOVEI A,CLOSEB ;]
03200 MOVEI A,UAR ;↑
03300 MOVEI A,LARR ;LEFT ARROW
00100
00200 REPEAT 175-137-1,<HRROI A,ERRA>
00300 MOVEI A,ALTMOD ;ALT MODE
00400 HRROI A,ERRA
00500 HRROI A,ERRA
00100 U STAB,0 ;SEARCH TABLE
00200 ;SERCH4+2,OGNF+4,OGNF+6,OGFN+11
00300 U AC2,16 ;SAVE AC2-AC17 IN NROOM ROUTINE
00400 ;NROOM,NROOM5
00500 U BAKTAB,40-3-16 ;RECEIVES ASCII CONVERSION OF NUMERICAL ARGUMENT
00600 ;BAKSL4
00700
00800 CFIL1←STAB
00900 CFIL2←STAB+1
01000 U STABP,0
01100 U SYMS,22 ;LIS+4(0),OG3+1,GC+3(0)
01200 U VALS,22 ;LIS+4(0),OG3+3,GC+3(0)
01300 U CNTS,22 ;LIS+4(0),OG3+2,GC+3(0)
01400 U SYMEND,0
01500 U PFL,LPF
01600 U GCTAB,GCTBL ;GCS3+4,GCM2+13
01700 U QTAB,45 ;Q-REGISTER TABLE
01800 ;USEA+1,PCNT+1
01900 U PDL,LPDL
02000 U UAC,17
02100
02200
02300
02400 PATCH: BLOCK 10
00100
00200 LIT
00300 U CBUF,0
00400 U TOP,0
00500 CODEND: END INIT
00600