From b8fb44fed602ea9ea2d21b7fe64c4321247e89f6 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Fri, 18 Nov 2022 18:46:45 +0100 Subject: [PATCH] TECO for SITS. --- build/misc.tcl | 5 + build/timestamps.txt | 2 + src/rjl/teco.96 | 5405 ++++++++++++++++++++++++++++++++++++++++++ src/rjl/tecoio.19 | 835 +++++++ 4 files changed, 6247 insertions(+) create mode 100644 src/rjl/teco.96 create mode 100644 src/rjl/tecoio.19 diff --git a/build/misc.tcl b/build/misc.tcl index c4f46fe5..ed426032 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -1658,6 +1658,11 @@ expect ":KILL" respond "*" ":palx dired\r" expect ":KILL" +# TECO for SITS. +respond "*" ":cwd rjl\r" +respond "*" ":palx teco\r" +expect ":KILL" + # SLOGO, 11LOGO for SITS. respond "*" ":cwd nlogo\r" respond "*" ":palx slogo_@slogo\r" diff --git a/build/timestamps.txt b/build/timestamps.txt index cc80b180..0aa0eac8 100644 --- a/build/timestamps.txt +++ b/build/timestamps.txt @@ -1832,6 +1832,8 @@ rjl/logops.70 197303061151.09 rjl/lstops.11 197109150931.27 rjl/musops.21 197302212116.23 rjl/salvd.3 197512150856.09 +rjl/teco.96 197806042310.40 +rjl/tecoio.19 197502241148.50 rjl/turops.67 197303061139.25 rjl/vecops.1 197107261022.12 rlb/fasdmp.124 197901090635.35 diff --git a/src/rjl/teco.96 b/src/rjl/teco.96 new file mode 100644 index 00000000..5d6180b0 --- /dev/null +++ b/src/rjl/teco.96 @@ -0,0 +1,5405 @@ + .TITLE TECO +R0=%0 +R1=%1 +R2=%2 +R3=%3 +R4=%4 +R5=%5 +SP=%6 +R6=%6 +R7=%7 +PC=%7 + +.IIF NDF .SEE,RT11=1 +.IF DF RT11 + .IF NZ RT11 + SITS=0 + TVS=0 + .ENDC +.ENDC +.IIF NDF RT11,.IIF NDF SITS,SITS=1 +.IIF NDF RT11,RT11=0 +.IIF NDF LSI,LSI=0 +.IIF NDF TVS,.IIF Z LSI, TVS=1 +.IIF NDF TVS,.IIF NZ LSI, TVS=0 +.IIF Z RT11,VERN=%FNAM2 +.IIF NZ RT11,VERN=69. +;GENERAL INFORMATION + +;Q REGISTER FORMATS +; Q REGISTERS ARE STORED IN A BLOCK WHERE EACH Q REGISTER HAS THE FORMAT: +;
+;THE HEADER CONSISTS OF , EACH AS A BYTE. THE ONLY FLAG +;WITH ANY MEANING IS THE HIGH ORDER BIT, WHICH IS 1=>0 NUMBER, 0=> ALPHA. +;THE NAME IS A CHAR CORRESPONDING TO THE NAME. +;DATA DEPENDS ON WHETHER THE Q REGISTER IS NUMERIC OR ALPHA. IF IT +;IS NUMERIC, THEN IT IS JUST ONE WORD OF DATA. ALPHA Q REGISTERS ARE +;STORED WITH ONE WORD OF COUNT, THEN THE CHARS AS BYTES. AN EXTRA BYTE +;MAY BE ADDED TO INSURE THAT THE NEXT Q REGISTER STARTS ON A WORD BOUNDRY. + + +MESC= 33 ;DOUBLE ESC IS MASTER +CPTR= R3 ;CHAR PTR +EOA= R4 ;END OF ALL + +;R5,R2,R1,R0 ARE FOR FUN + +RUBOUT= 177 +XCTU= 'U-100 + + +;DEFINE SOME PARAMETERS + +MEMINC = 2048. ;GET MEMORY IN 2K CHUNKS +MEMINT = 4096. ;INITIAL MEMORY SIZE +EXBLEN = 100. ;EXECUTE BUFFER IS 100 BYTES LONG + + +.IF DF .SEE ;I.E., IF PALX + +.MACRO .CSECT +.ENDM + +.MACRO .ASECT +.ENDM + +.MACRO .GLOBL A,B,C,D,E,F,G,H,I,J,K,L +.IF DF PASS2 +.IRP X, +.IIF NB X,.IIF NDF X,X==0 +.ENDR +.ENDC +.ENDM + +.ENDC + +.GLOBL APPIT,BACKT,CHECKC,CHEI,CHEL,CHEP,CHET,CLO,CLRTTY +.GLOBL DELIT,EMOPEN,EMCLOS,EMREAD,FILNIL,INTTY,LO,MEMLIM,MOPEN +.GLOBL PPINIT,PPO,PPOL,PRI,PRINIT,RSTTY,SSTAT,START,TTFLSH +.GLOBL .REDCH + + + + .MACRO CEXIT X +EX$.'X: + .ENDM + + + .MACRO EXIT A + JMP EX$. + .ENDM + + .MACRO EXITA A + JMP EX$.A + .ENDM + + .MACRO EXITZ A + JMP EX$.Z + .ENDM + + +.MACRO ERROR NRX +.IF NDF E.'NRX +EE$CNT=EE$CNT+1 + ERRGEN \EE$CNT,NRX +.ENDC + MOV #E.'NRX,R1 + EXITZ +.ENDM + +.MACRO ERRGEN X,NRX + .MACRO E$'X +E.'NRX=. + .ASCIZ \NRX\ + .ENDM +.ENDM + + +.IIF NDF EE$CNT, EE$CNT=0 + + +;MACRO TO PUSH ARGUMENTS ON STACK + +.MACRO PUSH ARGS + .IRP ARG, + MOV ARG,-(SP) + .ENDR +.ENDM + + +;MACRO TO POP ARGUMENTS FROM STACK + +.MACRO POP ARGS + .IRP ARG, + MOV (SP)+,ARG + .ENDR +.ENDM + + + .MACRO PUSHR1 + MOV R1,-(SP) + SUB CSTART,@SP + .ENDM + + .MACRO POPR1 + MOV (SP)+,R1 + ADD CSTART,R1 + .ENDM + +BRNUM=0 + +.MACRO BRCONS COND,SYM,NUM + COND' SYM'NUM +.ENDM + +.MACRO SYMCONS SYM,NUM +SYM'NUM'=. +.ENDM + + .MACRO TSTMEM X,BAD,GOOD + ADD EOA,X + .IF NB BAD + BCS BAD + .IFF + BRCONS BCS,BUM,\BRNUM + .ENDC + SYMCONS ASS,\BRNUM + CMP X,LIMBF + .IF NB GOOD + BLO GOOD + .IFF + BRCONS BLO,BUM,\BRNUM + .ENDC + JSR PC,GETMEX + BRCONS BNE,ASS,\BRNUM + .IF NB BAD + BR BAD + .ENDC + SYMCONS BUM,\BRNUM + BRNUM=BRNUM+1 + .ENDM + +.MACRO TYOESC X + MOV #X,R0 + JSR PC,ETTPUT +.ENDM + +.MACRO .TYO X + MOV #X,R0 + JSR PC,TTPUTC +.ENDM + .IF Z RT11 +.=300 + JMP START +.=400 +.IFF + .CSECT STACK +.ENDC + + +.IF Z RT11 +.MACRO DCS NAME,VAL +NAME==VAL +.ENDM +.INSRT SITS;SITSS SYMS +.IF NZ LSI +LSTTY=1 +LSDISK=1 +LSCLK=1 +LSPRNT=1 +LSFLEM=0 +.INSRT SITS;SITMAC > +.INSRT NLOGO;FLOPDF > +.INSRT NLOGO;LSITVR > +.INSRT NLOGO;LSITS > +.ENDC +.ENDC + STATE: 0 ;MUST BE FIRST!!! +TBUFX: 0 +BOQ: 0 ;START OF Q REGISTER AREA +BOB: 0 ;START OF TEXT BUFFER (END OF Q REGS) +ENBF.4: 0 ;END OF BUFFER AREA - 4 +ENBF: 0 ;END OF BUFFER AREA +NUM: 0 +STKSV: 0 ;STACK PTR SAVE +STKLIM: 0 ;STACK LIMIT +LIMBF: 0 ;LIMIT FOR TEXT +CMDLOC: 0 ;DEBUG +CSTART: 0 ;PLACE TO PUT START OF Q-MACRO +CEND: 0 ;END OF CURRENT COMMAND STR +CVAL: 0 ;VALUE OF EXP +CVAL1: 0 ;FIRST OF TWO ARGS +FFLAG: 0 ;1=>DO SECOND HALF OF F OPERATION FROM EVAL +MVAL: 0 +ERNDX: 0 +QNDX: 0 +QLEN: 0 +ITTER: 0 ;ITERATION COUNT +COVAL: 0 ;FOR : +COVAL1: 0 +CTRLX: 0 +CTRLY: 0 +INCNT: 0 +ERRSAV: 0 +MPTR: 0 +BOTTOM: 10. ;BOTTOM MARGIN AS % OF SCREEN +TOP: 10. ;TOP MARGIN AS % OF SCREEN +CENTER: 40. ;WHERE TO PUT CURSOR AS % FROM TOP +TOPSCR: 1 ;NUMBER OF LINES RESERVED AT THE TOP OF THE SCREEN +HPOS: 0 ;HORIZONTAL POSITION OF CURSOR +VPOS: 0 ;VERTICAL POSITION OF CURSOR +WINDOW: 0 ;CHAR NUMBER OF SCREEN 0,0 +RMODE: 0 ;1=>IN ^R MODE, 0=>IN NORMAL MODE +RMODE1: 0 ;CONTROL KLUDGE, TELLS PEOPLE HOW TO JUMP +REXPT: 1 ;EXPT FOR R MODE COMMANDS +RMARK: 0 ;USED BY MACROS AS THE MARK POSITION +LASTCH: 0 ;CONTAINS THE LAST CHAR READ IN ^R MODE +CTLMTA: 0 ;CONTROL AND META BITS +CTRLBT=200 +METABT=400 +TTFLAG: 0 ;TTFLAG OF TTY STATUS +TTFLG2: 0 +TTFLG3: 0 + WAITLK: .BYTE 0 +COSTAT: .BYTE 0 +COCOP: .BYTE 0 +DEBSW: .BYTE 0 ;DEBUG SW +QPDS: .BYTE 0 ;Q PUSH DOWN POINTER +FFLG: .BYTE 0 ;FORM FEED FLAG +SCHSW: .BYTE 0 +UCSW: .BYTE 0 +DOSW: .BYTE 0 +INPFLG: .BYTE 0 +OUTFLG: .BYTE 0 +ERNUM: .BYTE 0 +BAKFLG: .BYTE 0 +FFSW: .BYTE 0 +GOSW: .BYTE 0 +ITCNT: .BYTE 0 +ATSW: .BYTE 0 +COLSW: .BYTE 0 +QMODE: .BYTE 0 +COP: .BYTE 0 +RBOUT: .BYTE 0 +COLFLG: .BYTE 0 +ATFLG: .BYTE 0 +ERREG: .BYTE -1 +INCHR: .BYTE 0 +QFLG: .BYTE 0 +QREG: .BYTE 0 +QFREG: .BYTE 0 +QARG: .BYTE 0 +SFLG: .BYTE 0 +INITFL: .BYTE 0 +ECHOSW: .BYTE 0 ;SWITCH TO TURN OFF ECHOING ON TYPIN +GRAPHM: .BYTE 0 ;ENABLE TTY GRAPHICS +SAVSW: .BYTE 0 +MFLG: .BYTE 0 +;;WAITLK: .BYTE 0 ;1=>SUPERIOR PROCESS WAITING SO IGNORE QUITS +SAVFIL: .BLKB 50. +EMFLG: .BYTE 0 +EMPDS: .BYTE 0 +EMFIL: .BLKB 50. +EMBUF: .BLKB 100. +ERCMD: .BYTE 'M + .BYTE '.,'G,33,33 + .EVEN + OUPFH: .BLKW +INPFH: .BLKW +FILNAM: .BLKB 50. +INAMEP: .ASCII / I: / +INAME: .BLKB 50. +ONAMEP: .ASCII / O: / +ONAME: .BLKB 50. +BAKFIL: .BLKB 50. +TMPFIL: .BLKB 50. +TTYMAX=80. +TTYBUF: .BLKB TTYMAX +TTYEND: +TTYCNT: .BLKB +TTYM: .BLKB +TTYBP: .BLKW +TTYEP: .BLKW +TTYINP: .BLKW +TTYOUP: .BLKW +PINMAX=512. ;LENGTH OF INPUT BUFFER +PINBUF: .BLKB PINMAX +PINCNT: .BLKW +PINPTR: .BLKW +EXBUF: .BLKB EXBLEN ;BUFFER FOR EU COMMAND STRINGS + +;TIMING VARIABLES + +PUT: .BLKW 2 +PST: .BLKW 2 +CUT: .BLKW 2 +CST: .BLKW 2 + ;SUPPORTED (SOMEWHAT) TERMINALS +TERMT: TT2500 ;TERMINAL TYPE +;VECTOR OF TERMINAL DEPENDENT ROUTINES +TDVEC=. +SETCUR: TTSETC +GRCRLF: TTGRCL +KILLSC: TTKILS +CLREOL: TTCLRE +CLRSCR: TTCLRS +PAGSIZ: 29. ;SIZE OF PAGE IN LINES +LLEN: 71. ;LINE LENGTH OF MY TTY IN CHARS +PADLF: 0 ;PADDING ON LINEFEED (in milliseconds) +TDVECE=. + +PADSPD: 1 ;NUMBER OF MILLSECONDS/CHARACTER + ;E.G. 9600 BAUD = 1, 4800 =2, 2400= 4 + +;VECTORS FOR EACH TYPE OF TERMINAL +.IFNZ TVS +TV: TVSETC + TVGRCL + TVKILS + TVCLRE + TVCLRS + 36. + 90. + 0 +.ENDC +TT2500: TTSETC + TTGRCL + TTKILS + TTCLRE + TTCLRS + 29. + 71. + 0 + +C100: C1SETC + C1GRCL + C1KILS + C1CLRE + C1CLRS + 24. + 79. + 5 + +DATAP: DPSETC + DPGRCL + DPKILS + DPCLRE + DPCLRS + 24. + 71. + 0 + +VT52: VTSETC + VTGRCL + VTKILS + VTCLRE + VTCLRS + 24. + 79. + 0 + +ECMDTB: .REPT 96. ;NO LOWER CASE CHARS + CHE3A ;ERROR + .ENDR +FOO=. +.IRPC X,ABCDFILMNPRSTUVWYX +.=ECMDTB+<2*''X> + CHE'X +.ENDR +.=FOO + + +.IIF NZ SITS,.INSRT STECOI > + + ; .CSECT PGM,IPURE + +TECO: JSR PC,CRLF ;TYPE A NL BEFORE THE STAR + JSR PC,INTTY ;INITIALIZE THE TTY + MOVB #1,INITFL ;SAY THAT WE ARE DOING INTIALIZATION + MOV EOA,R1 ;COPY OUR INITIAL COMMAND INTO COMMAND BUFFER + CLRB (R1)+ +; JSR PC,GETINIT ;COPY INITIAL COMMAND AT R1 LEAVE R1 AT ZERO +; BEQ STRTUP ;IF THERE WAS NO LOGIN DIRECTORY +; DEC R1 ;FIX THE POINTER TO END OF INITIAL COMMAND +; JMP GOMAN ;NOW EXECUTE INITIAL COMMAND + + + +;THE THEORY OF THE STARTUP IS TO COPY THE MESSAGE ENFOOBAR$$ TO A COMMAND +;BUFFER AND THEN EXECUTE THAT BUFFER. + +STRTUP: CLRB INITFL ;FROM NOW ON INIT IS OVER + TSTB SAVFIL ;DID WE HAVE A COMMAND ARGUMENT + BEQ 3$ ;NO JUST START EXECUTING NORMAL COMMANDS + MOV EOA,R1 ;GET POINTER TO COMMAND BUFFER + TSTB (R1)+ ;EVERYTHING UP TO EOA IS COMMAND + MOV #STRTCMD,R0 ;POINTER TO STARTUP COMMAND +1$: MOVB (R0)+,(R1)+ ;COPY THE COMMAND + BNE 1$ ;WHILE NOT EQUAL TO ZERO + DEC R1 ;BACK UP OVER THE ZERO + MOV #SAVFIL,R0 ;NOW COPY THE FILE NAME INTO THE COMMAND BUFFER +2$: MOVB (R0)+,(R1)+ + BNE 2$ ;AGAIN, WHILE NOT ZERO + DEC R1 ;AGAIN, BACK UP OVER THE ZERO + MOVB #MESC,(R1)+ ;FINALLY FINISH THE STRING WITH A PAIR OF ALT'S + MOVB #MESC,(R1) + JMP GOMAN ;AND EXECUTE THE COMMAND + +3$: JMP NEXT ;READ IN A NEW COMMAND BUFFER + + +; .CSECT STACK +STRTCMD:.ASCIZ "EN" ;WE WILL EXECUTE THIS COMMAND TO FILE + .EVEN +; .CSECT PGM + + + + +GETFIL: CMPB (R1),#MESC + BNE 2$ + MOV #FILNAM,R0 + MOV #BAKFIL,R2 +1$: MOVB (R2)+,(R0)+ + BNE 1$ + BR GETFL1 +2$: JSR PC,SETFNM +GETFL1: CLRB FFLG + JSR PC,BACKT + BCC 3$ + JSR PC,PPINIT + BCC 2$ + RTS PC + +2$: MOV R1,-(R6) + MOV #FILMSG,R1 + MOV #FILMEN,R2 + JSR PC,TYPER + MOV (R6)+,R1 +4$: CCC + RTS PC + +3$: JSR PC,IPUT + BR 4$ + + + + CEXIT Z + + TSTB RMODE ;ARE WE IN ^R MODE? + BEQ 22$ ;NO + JSR PC,RCLR ;MAKE SURE WE GO OUT + CLR RMODE ;TELL EVERYBODY WE'RE OUT + CLR RMODE1 ;JUST TO MAKE SURE + +22$: TSTB MFLG + BNE 44$ + + + SUB CSTART,CMDLOC + MOV CMDLOC,ERNDX + MOV R1,ERRSAV + MOVB QMODE,QREG + CLRB QMODE + INCB SAVSW + MOV CEND,R0 + SUB CSTART,R0 + MOV R0,QLEN + CLR QNDX + MOVB QREG,R0 + BEQ 1$ + JSR PC,FINDQ2 + BNE 1$ + CLR QLEN +1$: MOVB #'?,R0 + JSR PC,STUFF +ERRPRT=. + MOVB QREG,ERREG + CLRB SAVSW + +44$: MOV STKSV,SP + BR ERPRT + + JSR PC,FINDQ2 + BLE ERPRT + CLR R5 + MOV #ERRST,R1 + MOV #ENDER,R2 + CMP R1,ERRSAV + BEQ 55$ +50$: CLR R0 + JSR PC,SSTR + INC R0 + CMP R0,ERRSAV + BEQ 55$ + MOV R0,R1 + INC R5 + BR 50$ +55$: MOVB R5,ERNUM + JSR PC,FIXUP + MOV EOA,R1 + CLRB (R1)+ + MOV #ERCMD,R2 +60$: MOVB (R2)+,(R1)+ + BNE 60$ + DEC R1 + JMP GOMAN + +ERPRT=. +CTLZ: MOV ERRSAV,R1 + JSR PC,RSTTY + MOV #'?,R0 + JSR PC,TYO + CLR R0 + MOV #ENDER,R2 ;WORST CASE END + JSR PC,SSTR ;FIND THE NULL + MOV R0,R2 ;SET UP END + JSR PC,TYPER ;TYP THE ERROR SHORT FORM + +CONT: +REDO: JSR PC,CRLF +NEXT: JSR PC,FIXUP + CLRB GOSW +; TSTB INITFL +; BEQ 1$ +; JMP STRTUP + +1$: CLRB (R1)+ + CLRB @R1 + JSR PC,RSTTY + MOV ENBF,LIMBF + MOV #'*,R0 +NTY: JSR PC,TYO ;OUTPUT A * PROMPT +NCHR: CMP R1,ENBF.4 ;STILL ROOM IN INPUT BUFFER? +;ENBF CONTAINS END OF BUFFER, ENBF.4 CONTAINS END - 4 + BLO BAKG ; YES + MOV R1,-(SP) ;SAVE IT + JSR PC,GETMEX + MOV (SP)+,R1 + TST R0 + BNE NCHR + MOV R1,-(SP) ;SAVE IT FOR A SEC + MOV #WATCH,R1 ;WARNING MSG + MOV #WATCHN,R2 ;END OF IT + JSR PC,TYPER ;ZAP IT + MOV (SP)+,R1 ;GET IT BACK + CMP R1,ENBF ;LAST CHANCE? + BLO BAKG ;STILL LUCKY + ERROR ; NO. GIVE ERROR + BAKG: JSR PC,TYI ;GET A CHAR INTO R0 + TSTB GOSW ;SHOULD WE STOP HERE? + BNE .CONT ;YES, MUST HAVE TYPED ^B OR ^Q + JSR PC,RSTTY + CMP R0,#RUBOUT + BEQ CTA + CMP R0,#XCTU ;DELETE LINE CHAR? + BEQ CTU + TST R0 ;NULL? + BEQ CTU ;YES + CMP R0,#'R-'@ ;CONTROL R? + BEQ CTR ;YES + MOVB R0,(R1)+ + CMPB 1(EOA),#'? + BNE 2$ + JSR PC,CRLF + TSTB ERREG + BLT REDO + BEQ 3$ + CMPB ERREG,#60 + BGE 5$ + MOV #QMSGE,R1 + MOV #QMSGN,R2 + JSR PC,TYPER + CLR R0 + MOV #EMFIL,R1 + MOV R1,R2 + ADD #50.,R2 + JSR PC,SSTR + MOV R0,R2 + JSR PC,TYPER + BR 6$ +5$: MOV #QMSG,R1 + MOV #QMEN,R2 + JSR PC,TYPER + MOVB ERREG,R0 + JSR PC,TYO +6$: JSR PC,CRLF +3$: MOVB #'?,R0 + JSR PC,FINDQ2 + MOV R2,R1 + TST (R2)+ + ADD (R2)+,R2 + CMP (R1)+,(R1)+ + ADD ERNDX,R1 + JSR PC,TYPER + JMP REDO + +2$: CMP R0,#MESC ;IS IT AN ESCAPE CHAR? + BNE NCHR ; NO- JUST LOOP FOR MORE CHARS. + CMPB R0,-2(R1) ; IS THE PREVIOUS AN ESC?? + BEQ GO2IT + JMP NCHR + +.CONT: JMP CONT + CTR: MOV R1,R2 ;END + MOV EOA,R1 ;START OF INPUT + INC R1 + CMP R1,R2 + BEQ .CONT + JSR PC,CRLF + MOV #'*,R0 + JSR PC,TYO + JSR PC,TYPER ;PUT IT + MOV R2,R1 ;RESTORE + BR CTA3 + +;CONTROL U (^U) (DELETE INPUT LINE) + +CTU: MOV #'U-'@,R0 ;TYPE ^U + JSR PC,TYO +1$: CMPB -(R1),#15 + BEQ 2$ + CMP R1,EOA + BHI 1$ + JMP CONT + +2$: INC R1 + JSR PC,CRLF + BR CTA3 + +CTA: TSTB RBOUT + BNE CTA1 + INCB RBOUT + MOV #'\,R0 + JSR PC,TYO +CTA1: MOVB -(R1),R0 + CMP R1,EOA + BHI CTA2 + INC R1 +CTA3: JMP NCHR +CTA2: JMP NTY + GO2IT: JSR PC,CRLF +GOMAN: CLRB ITCNT + CLRB GOSW + MOV #1,CTRLX + MOV #1,CTRLY + MOV ENBF,R0 +1$: MOVB -(R1),-(R0) ;MOVE INPUT BUFFER TO THE + CMP R1,EOA ;END OF THE WORLD, THUS LEAVING + BHI 1$ ;THE MOST ROOM FOR MAIN BUFFER. + INC R0 + MOV R0,R1 + MOV R0,LIMBF + JSR PC,SETST + JSR PC,CMDX ;NOW DISPATCH ON COMMANDS. + CMP R1,ENBF ;DID IT END UP PROPER? + BNE 2$ + JMP NEXT + +2$: ERROR ; NO- TELL HIM. + + CEXIT + + TST FFLAG + BEQ CMDX + JMP CHF2 + +NULL: +CMDX: MOV R1,CMDLOC + CMP SP,STKLIM ;STACK OVERFLOW?? + BLOS OVFL + CLR STATE + CLRB ATSW + CLRB COLSW + MOV #1,CVAL ;DUMMY VALUE OF 1 + CEXIT A + TST FFLAG + BEQ CMDX1 + JMP CHF2 ;DO THE SECOND PART OF AN FS OR FN OPERATION +CMDX1: TST RMODE1 ;ARE WE IN ^R MODE? + BEQ CMDX2 ;NO + JMP RCHCNT ;EXECUTE ^R COMMANDS, THIS FINISHES A MACRO +CMDX2: JSR PC,CHECKC ;MAKE SURE GOSW=0, ELSE JMP TO BAKG + JSR PC,GETCHU ;GET AN UPPER CASE CHAR TO DISPATCH ON INTO R0 + CMP R0,#174 + BEQ VERTB + CMP R0,#136 + BNE 2$ + JSR PC,GETCHU + SUB #100,R0 + CMP R0,#40 + BHIS NONE +2$: CMP R0,#137 + BHI NONE + ASL R0 + JMP @DTAB(R0) ;DISPATCH ON COMMAND + +OVFL: ERROR + +NONE: ERROR + +VERTB: CMP R1,CEND + BHIS 1$ + CMPB (R1)+,#15 + BEQ 2$ + BR VERTB +1$: DEC R1 +2$: EXIT + ;COMMAND + + +CHPL: BIT #7,STATE + BEQ CHPL2 +CHOP: BIT #2,STATE + BNE EXPER1 + MOVB -1(R1),COP +CHPL1: BIS #2,STATE +CHPL2: EXITA + +;COMMAND - + +CHMI: BIT #7,STATE + BNE CHOP + NEG CVAL + BR CHPL1 + +CHMUL: +CHDIV: +CHAND: +CHOR: BIT #7,STATE + BNE CHOP +EXPER1: ERROR + +;COMMAND , + +CHCOM: JSR PC,ARG.7 + MOV #10,STATE + MOV CVAL,CVAL1 + CLR CVAL + EXITA + +CHAT: TSTB ATSW + BNE 1$ + INCB ATSW + EXITA + +1$: ERROR + +CHCOL: TSTB COLSW + BNE 1$ + INCB COLSW + MOVB STATE,COSTAT + MOVB COP,COCOP + MOV CVAL,COVAL + MOV CVAL1,COVAL1 + CLR STATE + EXITA + +1$: ERROR + + + ;ROUTINE TO READ A NUMBER FROM POINTER IN BUFFER + +CHBS: CMP STATE,#4 ;DO WE HAVE A NUMBER ARGUMENT? + BEQ 1$ ;YES, THEN HE WANTS TO PUT IT INTO BUFFER + MOV R1,-(SP) + MOV CPTR,R1 ;WHERE TO START READING THE NUMBER + MOV EOA,R2 ;BOUND ON WHERE THE END OF NUMBER CAN BE + CMPB @R1,#'- + BEQ 3$ + CMPB @R1,#'+ + BNE 4$ + INC R1 +4$: JSR PC,DECIN +5$: CMP R1,EOA + BHI 2$ + MOV R1,CPTR + MOV (SP)+,R1 + JMP EVAL + +3$: INC R1 + JSR PC,DECIN + NEG R0 + BR 5$ + +1$: JMP CHBS2 + +2$: ERROR + +CTUP: JSR PC,GETCH + BR EVAL + +CTT: JSR PC,TYI + CMP R0,#'B-'@ + BNE EVAL + JMP CONT + +CHQ: JSR PC,FINDQ + BEQ QRERR + MOV 2(R2),R0 + BR EVAL + +CHPER: JSR PC,FINDQ + BPL QRERR + MOV 2(R2),R0 + INC R0 + MOV R0,2(R2) + BR EVAL + +QRERR: ERROR + +CTE: MOVB FFLG,R0 + BR EVAL + CHRP: JSR PC,ARG.7 + RTS PC + +CHLP: TSTB COLSW ;IN COLON? + BEQ 1$ ;NO + MOVB COSTAT,-(SP) ;STATE AND COP + MOVB COCOP,1(R6) + MOV COVAL,-(SP) + MOV COVAL1,-(SP) +1$: MOVB ATSW,-(SP) + MOVB COLSW,1(R6) + MOVB STATE,-(SP) + MOVB COP,1(SP) + MOV CVAL,-(SP) + MOV CVAL1,-(SP) + MOVB ITCNT,-(SP) + CLRB ITCNT + JSR PC,CMDX + CMPB -1(R1),#') + BNE 2$ + MOV CVAL,R0 + MOVB (SP)+,ITCNT + MOV (SP)+,CVAL1 + MOV (SP)+,CVAL + MOVB 1(SP),COP + MOVB (SP)+,STATE + MOVB 1(R6),COLSW + MOVB (SP)+,ATSW + TSTB COLSW + BEQ EVAL + MOV (SP)+,COVAL1 + MOV (SP)+,COVAL + MOVB 1(R6),COCOP + MOVB (SP)+,COSTAT + BR EVAL + +2$: ERROR + + + +CTRX: MOV CTRLX,R0 + BR EVAL + +CTRY: MOV CTRLY,R0 + BR EVAL + + +CTLH: MOV NUM,R0 + NEG R0 + BR EVAL + + +CTLF: MOV ERNDX,R0 + BR EVAL + +CTLK: MOV ERREG,R0 + BR EVAL + +CTLN: MOVB ERNUM,R0 + BR EVAL + +CTB: BPT + EXIT + ;COMMAND B (BEGINNING OF BUFFER) + +CHB: CLR R0 +EVAL: ADD STATE,PC + BR CHB1 + BR CHB2 + BR TRP3 + BR CHB3 + BR CHB1 + BR CHB2 + BR TRP3 + BR CHB3 + +CHB3: MOVB COP,R2 ;OP + CMP R2,#'- + BNE CHB4 + SUB R0,CVAL +CHB6X: BIC #2,STATE + EXITA + +CHB4: CMP R2,#'+ + BNE 1$ + ADD R0,CVAL + BR CHB6X + +1$: CMP R2,#'* + BNE 2$ + MOV R1,-(SP) + MUL CVAL,R0 + MOV R1,CVAL + MOV (SP)+,R1 + BR CHB6X + +2$: CMP R2,#'/ + BNE 3$ + MOV R1,-(SP) + MOV R0,-(SP) + CLR R0 + MOV CVAL,R1 + DIV (SP)+,R0 + MOV R0,CVAL + MOV (SP)+,R1 + BR CHB6X + +3$: CMP R2,#'& + BNE 4$ + COM R0 + BIC R0,CVAL + BR CHB6X + +4$: CMP R2,#'# + BNE 5$ + BIS R0,CVAL + BR CHB6X + 5$: ERROR + +CHB1: MOV R0,CVAL ;REPLACE DUMMY + BIS #4,STATE + EXITA + +CHB2: NEG R0 + MOV R0,CVAL + ADD #2,STATE + EXITA + +;COMMAND H (ALL) + +CHH: JSR PC,ARG.5 + CLR CVAL1 + MOV #10,STATE + +;COMMAND Z + +CHZ: MOV EOA,R0 + SUB BOB,R0 + BR EVAL + +;COMMAND PERIOD (.) + +CHPD: MOV CPTR,R0 + SUB BOB,R0 + BR EVAL + + +;COMMAND NUMBER (IE 0-9) + +CHNM: MOVB (R1)+,R0 + JSR PC,GETUC + CMPB R0,#'A + BEQ 7$ + SUB #2,R1 ;WHERE TO START READING NUMBER + MOV CEND,R2 ;BOUND ON END OF NUMBER + JSR PC,DECIN + BR EVAL + +7$: CLR R0 + CMP CPTR,EOA ;LAST?? + BEQ 1$ ;YES + MOVB (CPTR),R0 +1$: BR EVAL + +TRP3: ERROR + ;COMMAND ESCAPE ($) + +CMESC: CMP R1,CEND + BHIS 1$ + CMPB @R1,#MESC + BNE CMEXIT + INC R1 +1$: RTS PC + +CHA: TSTB COLSW + BNE 1$ + TST STATE + BEQ 2$ + ERROR +2$: JSR PC,IPUT +CMEXIT=. + EXIT + +1$: JSR PC,FINDQ + BGE 4$ + ERROR + +4$: MOVB QFREG,-(R6) + JSR PC,SETLIM + MOVB (R6)+,QFREG + JSR PC,APPEND + EXIT + ;ROUTINE TO APPEND TO THE END OF A QREGISTER + +APPEND: PUSH ;SAVE REGISTER + PUSHR1 + MOVB QFREG,R0 + JSR PC,FINDQ2 + BMI ABAD1 + BEQ APP3 + MOV R2,R1 + MOV QLEN,R2 + BIT #1,2(R1) + BEQ 6$ + INC R2 +6$: BIC #1,R2 + MOV R2,-(R6) + TSTMEM R2,ABAD + MOV R2,-(R6) + MOVB QFREG,R0 + JSR PC,FINDQ2 + TST (R2)+ + MOV R2,-(R6) + ADD (R2)+,R2 + BIC #1,R2 + TST (R2)+ + MOV 2(R6),R1 + MOV (R6)+,(R6) + MOV EOA,R0 + MOV R1,EOA +1$: MOVB -(R0),-(R1) + CMP R0,R2 + BHI 1$ + MOV (R6)+,R0 + MOV R0,R1 + ADD (R1)+,R1 + ADD QLEN,(R0) + ADD (R6),BOB + ADD (R6),BOQ + ADD (R6)+,CPTR + TSTB EMFLG + BEQ 7$ + MOV #EMBUF,R0 + BR 8$ +7$: JSR PC,QSET +8$: MOV QLEN,R2 + BEQ 4$ +2$: MOVB (R0)+,(R1)+ + SOB R2,2$ + MOVB #MESC,(R1) +4$: JSR PC,SETST + POPR1 + POP ;RESTORE + RTS PC + +ABAD: ERROR +ABAD1: ERROR + +APP3: MOVB QFREG,R0 + JSR PC,STUFF + TST (R6)+ + POP ;RESTORE + RTS PC + +;COMMAND J (JUMP) + +CHJ: JSR PC,ARG.1 + BNE 1$ + CLR CVAL ;ALLOW FOR DUMMY ARG +1$: MOV CVAL,R0 + ADD BOB,R0 + MOV R0,CPTR + CMP CPTR,EOA + BLOS 2$ + MOV EOA,CPTR +2$: EXIT + +;COMMAND R + +CHR: TSTB COLSW + BEQ 1$ + JSR PC,ARG.1A + BNE 2$ + CLR CVAL +2$: MOV CVAL,INCNT + MOVB (R1)+,INCHR + JSR PC,IPUT1 + EXIT + +1$: NEG CVAL + +;COMMAND C (ADVANCE PTR) + +CHC: JSR PC,ARG.2 ;FIX THE ARGS + MOV R0,CPTR + EXIT + ;COMMAND L (NEXT LINE) + +CHL: TSTB COLSW + BNE CHL1 + JSR PC,ARG.3 ;GET RESULT + MOV R0,CPTR + EXIT + +CHL1: MOV R1,-(R6) + MOV #41,R5 + JSR PC,CRLF + +1$: CMP R5,#200 + BEQ 11$ + MOV R5,R0 + JSR PC,FINDQ2 + BEQ 10$ + BGT 3$ + JSR PC,TYO + MOV #40,R0 + JSR PC,TYO + JSR PC,TYO + MOV #'N,R0 + JSR PC,TYO + MOV #11,R0 + JSR PC,TYO + MOV 2(R2),R0 + JSR PC,CEQ1 + BR 15$ + +3$: JSR PC,TYO + MOV #11,R0 + JSR PC,TYO + MOV R2,-(R6) + MOV 2(R2),R0 + BLT 21$ + JSR PC,CEQ1 + BR 22$ +21$: JSR PC,DECOUX + MOVB (R6)+,R2 +23$: MOVB (R6)+,R0 + JSR PC,TYO + DEC R2 + BGT 23$ +22$: MOV (R6)+,R2 + MOV #11,R0 + JSR PC,TYO + TST 2(R2) + BEQ 15$ + MOV #25.,R1 + TST (R2)+ + CMP (R2),R1 + BHIS 6$ + MOV (R2),R1 +6$: TST (R2)+ +7$: MOVB (R2)+,R0 + CMP R0,#15 + BEQ 15$ + CMP R0,#11 + BNE 8$ + SUB #7,R1 + BLE 15$ +8$: JSR PC,TYO + SOB R1,7$ + +15$: JSR PC,CRLF +10$: INC R5 + BR 1$ + +11$: MOV (R6)+,R1 + EXIT + +;COMMAND T (TYPE) + +CHT: TSTB COLSW ;SHOULD WE TYPE A QREGISTER? + BNE 1$ ;YES + TSTB ATSW ;SHOULD WE DO WINDOW DISPLAY? + BNE 4$ ;YES + JSR PC,ARG.11 ;GET BOUNDS + MOV R1,-(SP) ;SAVE IT + MOV R0,R1 ;SWITCH + JSR PC,TYPER + MOV (SP)+,R1 ;RESTORE + EXIT + +1$: JSR PC,FINDQ + BMI 2$ + BNE 3$ + JMP QBAD +2$: MOV 2(R2),R0 + JSR PC,CEQ1 + JSR PC,CRLF + EXIT + +3$: MOV R1,-(R6) + MOV R2,R1 + ADD #4,R1 + ADD 2(R2),R2 + ADD #4,R2 + JSR PC,TYPER + JSR PC,CRLF + MOV (R6)+,R1 + EXIT + + +;^R MODE SCREEN HACKERY + +4$: TST STATE ;WERE THERE ANY ARGUMENTS + BNE 5$ ;YES, MUST HAVE BEEN + JSR PC,UPDATE ;SET CURSOR TO . ON SCREEN AND MAYBE NEW WINDOW + EXIT + +5$: CMP STATE,#14 ;ARE WE IN TWO ARG MODE? + BNE 6$ ;NO, MUST BE IN ONE ARG MODE + JSR PC,ARG.10 ;OK FIX THE ARGUMENTS INTO R0 AND R2 + JSR PC,GTYPER ;TYPE EVERYTHING BETWEEN R0 AND R2 + BNE 7$ ;CAN'T ERROR + EXIT + +6$: JSR PC,ARG.7 ;MAKE SURE ARGS ARE CORRECT + MOV CVAL,R0 ;ONE ARGUMENT, TYPE FROM HERE TO BOTTOM + ADD BOB,R0 ;MAKE IT ABSOLUTE + JSR PC,TYPSCN ;TYPE EVERYTHING FROM R0 TO BOTTOM OF SCREEN + BNE 7$ ;CAN'T, ERROR + EXIT + +7$: ERROR + +;ROUTINE TO SET THE CURSOR TO . ON SCREEN. IF . IS OFF THE SCREEN, THEN +;A NEW WINDOW WILL BE CHOSEN AND THE SCREEN REDISPLAYED + +UPDATE: PUSH ;GET SOME REGISTERS + MOV CPTR,R0 ;OTHERWISE SET SCREEN CURSOR TO DOT + JSR PC,SETPOS ;SET HPOS AND VPOS TO POSTION R0 + BNE 2$ ;CAN'T, PICK A NEW WINDOW + MOV TOP,R0 ;PERCENTAGE OF FORBIDDEN ZONE AT TOP OF WINDOW + MUL PAGSIZ,R0 ;FIND NUMBER OF FORBIDDEN LINES + DIV #100.,R0 ;LINES INTO R0, REMAINDER INTO R1 + CMP VPOS,R0 ;WOULD WE BE IN FORBIDDEN ZONE? + BHIS 1$ ;NO + TST WINDOW ;ARE WE AT THE TOP OF BUFFER? + BNE 2$ ;NO BETTER PICK A NEW WINDOW + +1$: MOV BOTTOM,R0 ;PERCENTAGE OF FORBIDDEN ZONE AT BOTTOM + MUL PAGSIZ,R0 ;FIND NUMBER OF FORBIDDEN LINES + DIV #100.,R0 ;LINES INTO R0 + MOV PAGSIZ,R1 ;NUMBER OF LINES ON SCREEN + SUB R0,R1 ;FIND BOTTOM LINE OF FORBIDDEN ZONE + CMP VPOS,R1 ;WOULD WE BE BELOW IT + BHIS 2$ ;YES, BETTER PICK A NEW WINDOW + JSR PC,@SETCUR ;OK, GO AHEAD AN SET CURSOR + POP ;CLEAN UP + RTS PC + +2$: JSR PC,SETWIN ;PICK A NEW WINDOW + MOV WINDOW,R0 + ADD BOB,R0 ;MAKE IT ABSOLUTE + JSR PC,TYPSCN ;TYPE EVERYTHING FROM R0 TO BOTTOM OF SCREEN + MOV CPTR,R0 ;NOW SET THE CURSOR + JSR PC,SETPOS ;SET HPOS AND VPOS TO CURSOR LOCATION + JSR PC,@SETCUR ;NOW ACTUALLY MOVE THE CURSOR + POP ;CLEAN UP + RTS PC + +;ROUTINE TO PICK A NEW WINDOW LOCATION. FOR NOW JUST ASSUME SCREEN LINES +;EQUAL CHAR LINES AND BACK UP %CENTER FROM DOT. + +SETWIN: PUSH ;GET SOME REGISTERS + MOV CENTER,R0 ;% OF SCREEN FROM TOP TO SET CURSOR + MUL PAGSIZ,R0 ;GET IT IN LINES + DIV #100.,R0 ;SINCE CENTER IS IN % + MOV R0,R1 ;GET COUNT OF LINES + NEG R1 ;SINCE WERE GOING BACK + MOV CPTR,R0 ;OUR CURRENT POSITION + JSR PC,LINE ;MOVE R0 BACK R1 LINES + SUB BOB,R0 ;MAKE IT RELATIVE TO BOB + MOV R0,WINDOW ;THIS WILL BE OUR NEW WINDOW + POP ;CLEAN UP + RTS PC + + +;ROUTINE TO TYPE EVERYTHING BETWEEN R0 AND BOTTOM OF SCREEN, WHERE R0 +;IS INTERPRETED AS A CHAR POINTER. ROUTINE WILL FAIL IF R0 IS LESS THAN +;WINDOW. CLEARS Z IF IT SUCCEEDS. + +TYPSCN: MOV WINDOW,-(SP) ;FIND ABSOLUTE ADDRESS OF WINDOW + ADD BOB,(SP) + CMP R0,(SP)+ ;MAKE SURE ITS REALLY ON THE SCREEN + BLT 1$ ;NO, BEFORE WINDOW HENCE OFF THE SCREEN + PUSH ;NEED SOME REGISTERS + MOV PAGSIZ,R1 ;HOW MANY LINES TO TYPE + JSR PC,SETPOS ;SET VPOS TO STARTING POSITION + BNE 1$ ;ERROR?? + JSR PC,@SETCUR ;ACTUALLY PUT THE CURSOR THERE + SUB VPOS,R1 ;NUMBER OF LINES ALREADY DISPLAYED + JSR PC,LINE ;MOVE R0 DOWN PAGSIZ LINES + MOV R0,R2 ;THIS WILL BE END POINTER + POP ;RESTORE THE START POINTER + JSR PC,@KILLSC ;KILL TO BOTTOM OF SCREEN + JSR PC,GTYPER ;OK, NOW TYPE EVERYTHING FROM R0 TO R2 + POP ;CLEAN UP + SEZ ;SIGNAL NO ERRORS + RTS PC + +1$: CLZ ;SIGNAL AN ERROR + RTS PC + +;ROUTINE TO TYPE PORTIONS OF THE SCREEN. IT EXPECTS A STARTING CHAR NUMBER +;IN R0 AND LAST CHAR POINTER IN R2. IT WILL SET THE CURSOR TO SCREEN +;POSITION OF R0'TH CHAR, THEN TYPE EVERYTHING IN BUFFER BETWEEN R0 AND R2, +;THEN RESTORE THE CURSOR TO IT'S ORIGINAL POSITION. CLEARS Z IF R0 IS NOT +;ON THE SCREEN. + +GTYPER: JSR PC,SETPOS ;SET HPOS AND VPOS TO R0 ON SCREEN + BNE 1$ ;CAN'T, IT WOULD BE OFF THE SCREEN + JSR PC,@SETCUR ;OK, PUT THE CURSOR THERE + PUSH ;GET A REGISTER + MOV R0,R1 ;JSR PC,TYPER LIKES STARTING CHAR HERE + JSR PC,TYPER ;TYPE IT + POP ;CLEAN UP + SEZ ;SIGNAL NO ERRORS + RTS PC + +1$: CLZ ;SIGNAL ERROR + RTS PC + + + +;ROUTINE TO SET HPOS AND VPOS TO THE SCREEN POSITION OF CHAR POINTED +;TO BY R0. WILL CLR Z IF THIS POSITION IS NOT ON THE SCREEN. + +SETPOS: PUSH ;SAVE SOME REGISTERS + SUB BOB,R0 ;MAKE RELATIVE TO BOB + CMP R0,WINDOW ;IS AFTER THE FIRST CHAR ON SCREEN? + BLO 1$ ;NO, MUST BE OFF THE SCREEN + MOV R0,R5 ;COPY THIS LOCATION + SUB WINDOW,R5 ;GET NUMBER OF CHARS + MOV WINDOW,R0 ;SET BEGINNING POINTER TO WINDOW + ADD BOB,R0 + CLR R1 ;0 INITIAL SCREEN LINE + CLR R2 ;0 INITIAL SCREEN COLUMN + JSR PC,COUNT ;SET R1 TO FINAL LINE AND R2 TO FINAL COLUMN + ADD TOPSCR,R1 ;NUMBER OF UNUSED LINES AT THE TOP OF THE SCREEN + CMP R1,PAGSIZ ;IS IT OFF THE BOTTOM OF SCREEN? + BHIS 1$ ;YUP, ERROR + MOV R1,VPOS ;SET VERTICAL POSITION + MOV R2,HPOS ;SET HORIZONTAL POSITION + POP ;CLEAN UP + SEZ ;SIGNAL NO ERROR + RTS PC + +1$: POP ;CLEAN UP + CLZ ;SIGNAL ERROR + RTS PC + +;ROUTINE TO TYPE FROM BEGINNING OF LINE + +CHV: JSR PC,ARG.1 ;TEST IT + BNE 1$ +2$: MOV #4,STATE ;FAKE IT + CLR CVAL ;0L + JSR PC,ARG.9 + INC CVAL +3$: MOV R0,-(SP) ;SAVE IT + JSR PC,ARG.9 ;GET END + MOV (SP)+,R0 ;SWITCH + MOV R1,-(SP) + MOV R0,R1 + JSR PC,TYPER ;ZAP IT + MOV (SP)+,R1 ;POP + EXIT + +1$: TST CVAL + BLE 2$ + MOV #4,STATE + NEG CVAL + JSR PC,ARG.9 + NEG CVAL + BR 3$ + CHX: JSR PC,ARG.11 ;GET BOUNDS + JSR PC,QINSRT + EXIT + +QINSRT: SUB R0,R2 ;HOW MANY?? + TSTB COLSW + BNE 1$ + SUB BOB,R0 ;MAKE OFFSET +1$: MOV R0,-(SP) ;AND SAVE IT + MOV R2,-(SP) ;SAVE IT + MOV R2,-(SP) ;SAVE IT + JSR PC,FINDQ ;GET THE Q REGISTER +QINSR1: BEQ 6$ ;NOT THERE + BMI 10$ ;NUMERIC + CMP 2(R2),@SP ;LARGER? + BHIS 7$ + SUB 2(R2),@SP ;GET DIFFERENCE + BR 10$ ;SKIP OVER + +6$: CLR R2 ;USE IT AS A FLAG +10$: ADD #12,@SP + TSTMEM @SP,XBAD +7$: MOV R2,(SP)+ ;GET RID OF JUNK AND TEST R2 + BEQ 11$ ;SKIP IF NON-EXISTENT + MOVB QFREG,-(R6) + JSR PC,KILLQ ;KILL THE OLD + MOVB (R6)+,QFREG +11$: MOV @SP,R2 ;RESTORE + ADD #6,R2 ;HEADER AND TRAILER + BIC #1,R2 ;WORDS + MOV R2,-(SP) ;SAVE IT + ADD EOA,R2 ;GET END + MOV R2,-(SP) ;SAVE IT + BR 3$ + +21$: MOVB -(EOA),-(R2) ;MOVE DOWN +3$: CMP EOA,BOB ;DONE?? + BHI 21$ ;NO + MOV (SP)+,EOA ;FIX IT + MOV R2,BOB + CLR -(R2) ;FIX BOQ WORD + MOV R2,BOQ + ADD @SP,CPTR + SUB (SP)+,R2 ;ADDRESS TO PUT Q + MOVB QFREG,(R2) ; FILL IN NAME + MOVB (R2)+,(R2)+ ;MOVE IN NON-ZERO POSITIVE NUMBER + MOV @SP,(R2)+ ;COUNT + BEQ 2$ + MOV 2(SP),R0 ;RESTORE + TSTB COLSW + BNE 22$ + ADD BOB,R0 ;FIX IT BACK +22$: TSTB QFLG + BEQ 23$ + TSTB EMFLG + BEQ 25$ + MOV #EMBUF,R0 + BR 23$ +25$: MOV R2,-(R6) + JSR PC,QSET + MOV (R6)+,R2 +23$: MOVB (R0)+,(R2)+ ;MOVE IN TEXT + DEC @SP ;FINISHED?? + BNE 23$ ;NO +2$: MOVB #MESC,(R2)+ ;ESC AT END + ADD #4,SP ;GET RID OF JUNK + RTS PC ;AND LEAVE + + +XBAD: TSTB SAVSW + BEQ XBAD1 + JMP ERRPRT +XBAD1: ERROR + CHLBR: JSR PC,ARG.5 ;NO ARGS + DECB QPDS ;ANOTHER NAME + BVS 2$ + MOV #4,-(SP) + JSR PC,FINDQ + BNE 1$ + CLR R2 + BR 5$ + +1$: TST @R2 ;CORRECT? + BMI 5$ ;YES + ADD #2,@SP ;FIX IT + ADD 2(R2),@SP ;COMME CA + BIC #1,@SP ;WORDS +5$: MOV @SP,-(SP) ;SAVE IT + TSTMEM @SP,XBAD + MOV @SP,R0 ;GET END +6$: MOVB -(EOA),-(R0) ;MOVE DOWN + CMP EOA,BOQ ;DONE? + BHI 6$ ;NO + MOV R0,BOQ ;FIX THAT + TST R2 + BNE 10$ + MOVB QPDS,(EOA)+ + MOVB #-2,(EOA)+ + CLR (EOA)+ + BR 8$ + +10$: CMPB QMODE,QFREG + BNE 4$ + MOV (R2)+,(EOA)+ + MOV CSTART,R5 + SUB #4,R5 + MOVB QPDS,(R5) + MOVB QPDS,QMODE + BR 7$ + +4$: MOV (R2)+,(EOA)+ ;MOVE IN STUFF + MOVB QPDS,-2(EOA) ;NEW NAME +7$: MOV (R2)+,(EOA)+ ;MOVE IT IN + CMP EOA,R0 ;DONE? + BLO 7$ ;NO +8$: MOV (SP)+,EOA ;NEW END + ADD @SP,CPTR ;FIX THESE + ADD (SP)+,BOB ;COMME CA + EXIT ;LA FIN + +2$: INCB QPDS ;FIX IT + ERROR + +QBAD: ERROR + + CHU: JSR PC,ARG.7 + JSR PC,FINDQ ;FIND THE OLD Q + BEQ 2$ ;NOT THERE + BPL 3$ ;TEXT + MOV CVAL,2(R2) ;PUT IT IN + EXIT ;AND LEAVE + +3$: JSR PC,KILLQ ;KILL THE OLD +2$: MOV #4,R2 + TSTMEM R2,XBAD + MOV R2,R0 + BR 5$ ;SKIP OVER + +4$: MOVB -(EOA),-(R0) +5$: CMP EOA,BOB + BHI 4$ + MOV R2,EOA + CLR -(R0) + MOV R0,BOQ + ADD #4,CPTR + ADD #4,BOB + MOV CVAL,-(R0) + MOVB #-1,-(R0) + MOVB -1(R1),-(R0) + EXIT + +;GET A Q REGISTER +CHG: JSR PC,ARG.5 + JSR PC,FINDQ ;FIND THE Q REGISTER + BLE QBAD ;BAD NEWS + TST (R2)+ ;SKIP NAME + MOV (R2)+,-(SP) ;GET COUNT + BEQ 7$ + TSTMEM @SP,GBAD2 + MOV @SP,R0 + BR 2$ + +1$: MOVB -(EOA),-(R0) ;MOVE IN THE TEXT +2$: CMP EOA,CPTR ;DONE?? + BHI 1$ ;NO + MOV R0,CPTR ;NEW ONE +3$: MOVB (R2)+,(EOA)+ ;MOVE IT IN + CMP EOA,R0 ;FINISHED?? + BLO 3$ ;NO + MOV (SP)+,EOA ;SET IT UP + EXIT ;AND RETURN + +7$: TST (SP)+ + EXIT + +GBAD2: ERROR + CHM: JSR PC,FINDQ ;FIND IT + BLE QBAD ;NOT ALPHA +CHM3: MOV MPTR,-(R6) + CMPB R0,#'? + BNE 1$ + INCB MFLG +1$: PUSHR1 + MOVB QMODE,-(R6) + MOVB ITCNT,1(R6) + MOV R6,MPTR + MOV CTRLX,-(R6) + MOV CTRLY,-(R6) + MOVB ATSW,-(R6) + MOVB COLSW,1(R6) + MOVB QARG,-(R6) + MOV MVAL,-(R6) + MOV RMODE1,-(R6) ;SAVE STATE OF RMODE + TST STATE + BNE 3$ + MOV #1,CTRLX +5$: MOV #1,CTRLY + BR CHM4 + +3$: CMP STATE,#4 + BNE 4$ + MOV CVAL,CTRLX + BR 5$ + +4$: CMP STATE,#14 + BNE CHM1 + MOV CVAL1,CTRLX + MOV CVAL,CTRLY + +CHM4: MOVB @R2,QMODE ;RESET IT + JSR PC,SETST ;SET UP CSTART AND CEND TO QREG NAMED BY QMODE + MOV CSTART,R1 + CLRB ITCNT + CLRB QARG + CLR MVAL + CLR RMODE1 ;MACROS ARE INITIALLY OUT OF RMODE + JSR PC,CMDX ;GO TO IT + MOV MVAL,QLEN + MOV (R6)+,RMODE1 ;RESTORE RMODE STATE + MOV (R6)+,MVAL + MOVB (R6)+,CVAL + MOVB 1(R6),COLSW + MOVB (R6)+,ATSW + MOV (R6)+,CTRLY + MOV (R6)+,CTRLX + CMPB -(R1),#MESC + BNE MBAD2 ;NO + MOVB QMODE,CVAL1 + MOVB 1(R6),ITCNT + MOVB (R6)+,QMODE + JSR PC,SETST ;RESET CSTART AND CEND TO QREG NAMED BY QMODE + POPR1 + CMPB CVAL1,EMPDS + BNE 25$ + MOVB CVAL1,R0 + JSR PC,FINDQ2 + JSR PC,KILLQ + DECB EMPDS +;falls through + ;falls in +25$: MOVB #MESC,R0 + TSTB ATSW + BEQ 17$ + MOVB (R1)+,R0 +17$: MOVB R0,ATSW + TSTB QARG + BEQ 20$ +19$: MOVB ATSW,R0 + JSR PC,SSTRX + MOV R0,R1 +22$: DECB QARG + BLE 24$ + INC R1 + BR 19$ +24$: CMPB ATSW,#MESC + BEQ 20$ + INC R1 + +20$: MOVB CVAL,QARG + MOV (R6)+,MPTR + TSTB COLSW + BNE 30$ + EXIT +30$: MOV QLEN,CVAL + CMPB (R1),#MESC + BNE CHM2 + INC R1 +CHM2: CLRB ATSW + CLRB COLSW + MOV #4,STATE + EXITA ;AND LEAVE + +CHM1: ERROR +MBAD2: ERROR ;BAD RETURN + + +CHRBR: JSR PC,ARG.5 ;NO ARGS + MOVB QPDS,R0 ;GET NAME + BEQ 1$ ;NONE ON STACK + JSR PC,FINDQ2 ;FIND IT + BEQ 1$ ;LOSE AGAIN + JSR PC,FINDQ ;FIND WHERE TO POP + BEQ 2$ ;NONE + JSR PC,KILLQ ;KILL IT +2$: MOVB QPDS,R0 + JSR PC,FINDQ2 ;ENCORE + BEQ 1$ + CMPB 1(R2),#-2 + BNE 3$ + JSR PC,KILLQ + BR 4$ + +3$: MOVB -1(R1),@R2 ;CHANGE NAME +4$: INCB QPDS + EXIT ;QUIT + +1$: ERROR + + +CTLV: JSR PC,ARG.7 + MOV CVAL,MVAL + EXIT + ;DELETE + +CHD: JSR PC,ARG.8 +CHD1: JSR R7,DELE ;SKIP OVER + EXIT + +;KILL + +CHK: TSTB COLSW + BNE 1$ + JSR PC,ARG.11 + BR CHD1 + +1$: JSR PC,FINDQ + BNE 2$ + ERROR +2$: JSR PC,KILLQ + EXIT + +DELE: CMP R0,R2 + BHIS 6$ + CMP R0,CPTR + BHIS 3$ + CMP R2,CPTR + BLO 4$ + MOV R0,CPTR + BR 3$ + +4$: SUB R2,CPTR + ADD R0,CPTR + BR 3$ + +2$: MOVB (R2)+,(R0)+ +3$: CMP R2,EOA + BLO 2$ + MOV R0,EOA +6$: RTS R7 + ;COMMAND E (ER & EY & ED & EW & EF & EM) + +CHE: JSR PC,ARG.5 + JSR PC,GETCHU ;GET NEXT CHARACTER, IN UPPER CASE + ASL R0 + BIC #177401,R0 ;ONLY YOU CAN HELP PREVENT RANDOMNESS + JMP @ECMDTB(R0) + +CHER: JSR PC,SETFNM ;SET UP THE FNM + JSR PC,PRINIT ;AND OPEN THE FILE +C2$: BCC C1$ ; GOOD. + +CHERWE: JSR PC,QSET + MOV R0,R1 + JSR PC,TYPER + JSR PC,CRLF ;AND A CR/LF + ERROR ;AND ERROR + +C1$: CLRB FFLG ;START AFRESH + EXIT + +CHEW: JSR PC,SETFNM + JSR PC,PPINIT ;OPEN FIL FOR OUTPUT + BCS CHERWE ;ERROR + EXIT + +CHEV: JSR PC,SETFNM ;GET THE NAME + CMPB #'>,-2(R2) ;is the last char >? + BEQ 1$ ;if yes, don't delete the file + JSR PC,DELIT ;TRY DELETING BUT IGNORE ERRORS +1$: JSR PC,PPINIT ;TRY OPEN + BCS CHERWE ;LOSE + EXIT + +CHED: JSR PC,SETFNM + JSR PC,DELIT + BCS CHERWE + EXIT + +CHEA: JSR PC,SETFNM + JSR PC,APPIT + BCS CHERWE + EXIT + + + +CHEU:.IF Z LSI + BPT + EXIT +.IFF + JSR PC,SETEXC ;COPY COMMAND STRING INTO QREG " AND EXBUF + BCS 1$ ;IF COMMAND STRING WAS TOO LONG TO FIT EXBUF + TSTB EXBUF ;ANY STRING? + BEQ 2$ ;NO, JUST DIE + MOVB EXBUF,R0 + SUB #60,R0 + BLT 1$ + CMP #4,R0 + BLE 1$ + JSR PC,UNMOUNT + EXIT + +1$: JSR PC,QSET ;SET UP SOME POINTERS + MOV R0,R1 ;POINTER TO START OF STRING + JSR PC,TYPER ;TYPE THE COMMAND STRING + JSR PC,CRLF ;TYPE JSR PC,CRLF + ERROR ;COMPLAIN + +2$: HALT + EXIT +.ENDC + ;ROUTINE TO READ AND MACRO A FILE + +CHEM: CMPB EMPDS,#40 ;40 IS MAXIMUM DEPTH OF EM MACROS + BEQ 6$ ;WE HAVE REACHED MAXIMUM DEPTH, ERROR + INCB EMPDS ;ADVANCE DEPTH COUNTER + JSR PC,SETFN ;READ FILE NAME FROM COMMAND STRING INTO FILNAM + JSR PC,EMOPEN ;OPEN THE FILE + BCS 4$ ;CAN'T + MOV R0,-(SP) ;SAVE THE FILE HANDLE + MOVB #1,EMFLG ;SIGNAL THAT WE ARE READING FROM FILE + +1$: MOV (SP),R0 ;GET A FRESH COPY OF FILE HANDLE + JSR PC,EMREAD ;READ 100. BYTES OF FILE INTO EMBUF + BCS 2$ ;PROBLEMS... + MOV R0,QLEN ;R0 HAS ACTUAL NUMBER OF BYTES READ + BEQ 2$ ;NOTHING TO APPEND + MOVB EMPDS,QFREG ;USE THIS NUMBER AS QREG TO PUT IT IN + JSR PC,APPEND ;COPY STUFF FROM EMBUFF TO QREG + CMP R0,#100. ;DID WE REALLY READ 100. BYTES? + BEQ 1$ ;YES, THERE MUST BE SOME MORE THEN + +2$: MOV (SP)+,R0 ;POP FILE HANDLE + JSR PC,EMCLOSE ;CLOSE THE EMFILE + INC R1 ;FIX THE COMMAND POINTER + TSTB ATSW + BEQ 3$ + SUB #2,R1 +3$: CLRB EMFLG + MOVB EMPDS,R0 ;THIS IS THE QREG WE PUT IT IN + JSR PC,FINDQ2 ;SET UP POINTERS TO THIS QREG + JMP CHM3 ;NOW GO AND MACRO IT + +4$: +; TSTB INITFL ;IS THIS PART OF THE STARTUP? +; BEQ 5$ ;NO, GIVE AN ERROR +; JMP STRTUP ;ELSE, CONTINUE WITH STARTUP + +5$: ERROR +6$: ERROR + +CHY: JSR PC,ARG.5 +CHEY:CHYX: MOV BOB,EOA + JSR PC,IPUTC + MOV BOB,CPTR ;RESET POINTER TO BEGINNING + EXIT + +CHEF: JSR PC,CLO ;CLEAR OUTPUT + BCS 1$ + EXIT +1$: ERROR + +CHEB: JSR PC,SETFNM ;SET UP FILE NAME + JSR PC,BACKT ;DO THE WHOLE THING + JMP C2$ + +CHEX: JSR PC,CLRTTY ;GO BACK TO OLD TTY MODE + MOV #1,QLEN + +CHEX1=. +1$: MOV BOB,R0 + MOV EOA,R2 ;BUFFER LIMITS + CMP R0,R2 ;ANY THERE? + BEQ 3$ ;NO + TST OUTFLG ;MAKE SURE WE HAVE AN OUTPUT FILE + BEQ 23$ ;NO, OK FIX UP THE TTY, AND COMPLAIN + JSR PC,OPUT ;OUTPUT IT + MOV BOB,EOA ;RESET + TSTB FFLG + BGT 2$ ;NO + BEQ 4$ + MOV #14,R0 + JSR PC,PPO +4$: TSTB INPFLG ;INPUT FILE? + BEQ 2$ + JSR PC,IPUTC ;GET MORE + BR 1$ + +3$: TSTB FFLG + BLE 4$ +2$: JSR PC,CLO ;CLOSE IT + BCS 23$ + TST QLEN + BEQ 6$ + JMP FINISH ;LEAVE + +23$: JSR PC,INTTY ;OH-OH BETTER GO BACK TO TECO TTY MODE + ERROR + +6$: MOV BOB,CPTR + JSR PC,GETFIL + BCC CHESEX + JMP CHERWE + + +CHEN: CLR QLEN + BR CHEX1 + + CHES: JSR PC,GETCHU + CMPB R0,#'D + BNE 1$ + MOVB #1,UCSW + MOVB #1,SCHSW +CHESEX=. + EXIT + +1$: CMPB R0,#'U + BNE 2$ + BISB #1,UCSW + EXIT + +2$: CMP R0,#'F + BNE 3$ + BISB #1,FFSW + EXIT + +3$: +4$: CMP R0,#'S + BNE 5$ + MOVB #1,SFLG + EXIT + +5$: CMP R0,#'R ;SHOULD WE GO INTO ^R MODE? + BNE CHE3A ;NO + PUSHR1 ;SAVE R1 RELATIVE TO CSTART SO IF WE EXPAND.. + PUSH RMODE ;SAVE OUR CURRENT STATE + TST RMODE ;ARE WE ALREADY IN ^R MODE? + BNE 6$ ;YES, NO NEED TO SET PARAMS AGAIN + CLR HPOS + CLR VPOS ;SET TO TOP OF SCREEN + JSR PC,RSET ;SET PARAMETERS FOR ^R MODE +6$: MOV #1,RMODE ;ENABLE ^R MODE + JSR PC,RCHL ;DRAW A NEW WINDOW + JSR PC,RCH ;START EXECUTING ^R MODE COMMANDS + POP RMODE ;RESTORE PREVIOUS STATE + POPR1 ;RESTORE RELATIVE TO CSTART INCASE IT MOVED + TST RMODE ;ARE WE STILL IN ^R MODE? + BNE 7$ ;YES, NO REASON TO LEAVE + JSR PC,RCLR ;OK BETTER CLEAN UP A LITTLE +7$: EXIT + + +CHEC: JSR PC,GETCHU + CMPB R0,#'D + BNE 1$ + CLRB UCSW + CLRB SCHSW + EXIT + +1$: CMP R0,#'U + BNE 2$ + CLRB UCSW + EXIT + +2$: CMP R0,#'F + BNE 3$ + CLRB FFSW + EXIT + +3$: +4$: CMP R0,#'S + BNE 5$ + CLRB SFLG + EXIT + +5$: CMP R0,#'R ;WHAT ABOUT ^R MODE? + BNE CHE3A ;NO, MUST BE ERROR + CLR RMODE ;JUST LEAVE A MESSAGE FOR SOMEBODY ELSE + EXIT + + + + +CHE3A: ERROR + ;COMMAND P & PW (OUTPUT CURRENT BUFFER AND READ NEXT ONE.) + +CHP: MOVB @R1,R0 ;CHECK FOR PW + JSR PC,GETUC + CMPB R0,#'W ;?? + BEQ 4$ ;YES + CMP STATE,#14 ;TWO ARGS? + BEQ 1$ ;YES + JSR PC,ARG.6 ;GET ARGS +2$: JSR PC,PAGE ;WRITE OUT CURRENT PAGE, AND FETCH NEW ONE + DEC CVAL ;FIN?? + BGT 2$ ;NO + EXIT ;RTS PC + +1$: JSR PC,ARG.10 ;GET RANGE + JSR PC,OPUT ;ZAP IT + EXIT ;AND QUIT + +4$: JSR PC,GETCH ;JUST CHECKING + CMP STATE,#14 ;TWO ARGS? + BEQ 1$ ;YES - SAME AS P + JSR PC,ARG.6 ;GET ARG +5$: MOV BOB,R0 ;START + MOV EOA,R2 ;END + CMP R0,R2 ;NOTHING? + BEQ 6$ ;YUP + JSR PC,OPUT ;ZAP IT + MOV #14,R0 ;FF + JSR PC,PPO + DEC CVAL ;DONE? + BGT 5$ ;NO +6$: EXIT + + + + +;ROUTINE TO OUTPUT ONE PAGE AND FETCH THE NEXT ONE, CLOBBERS R0 AND R2 + +PAGE: MOV BOB,R0 ;START + MOV EOA,R2 ;END + CMP R0,R2 ;NOTHING? + BEQ 1$ ;YES + MOV R0,EOA ;RESET + MOV R0,CPTR ;COMME CA + JSR PC,OPUT ;DO IT TO IT + MOV #14,R0 ;AND FF + JSR PC,PPO + +1$: JSR PC,IPUTC ;GET NEXT BUFFER + RTS PC + ;COMMAND S (SEARCH) + +CHS: JSR PC,ARG.4 + PUSH CPTR ;SAVE THE VALUE OF . + JSR PC,SCBF + BCS CHSLOSE +2$: DEC CVAL ;ONE SEARCH SUCCEDED + BGT 3$ + TST (SP)+ + BR CHSWIN +3$: JSR PC,SCBFX + BCC 2$ +CHSLOSE: POP CPTR + MOVB ATSW,R0 + TST FFLAG + BEQ 1$ + CLR FFLAG + JSR PC,SSTRX + MOV R0,R1 + INC R1 +CHSWIN=. + MOVB ATSW,R0 +1$: JSR PC,SSTRX + MOV R0,R1 + MOVB SCHSW,R0 + TSTB COLSW + BEQ 2$ + INC R1 + SUB FFLAG,R1 + CLRB ATSW + CLRB COLSW + MOVB COSTAT,STATE + MOVB COCOP,COP + MOV COVAL,CVAL + MOV COVAL1,CVAL1 + JMP EVAL + +2$: CMPB @R1,#MESC + BEQ 3$ + INC R1 + SUB FFLAG,R1 +3$: BISB ITCNT,R0 ;TEST FOR ITER OR SUCCESS + BEQ 5$ + EXIT +5$: ERROR + CHN: JSR PC,ARG.4 + JSR PC,SCBF + BCS 5$ +2$: DEC CVAL + BGT 1$ + BR CHSWIN + +8$: MOV #14,R0 + JSR PC,PPO +3$: JSR PC,IPUTC ;GET NEXT PAGE +1$: JSR PC,SCBFX + BCC 2$ +5$: MOV BOB,R0 ;GET START + MOV EOA,R2 ;AND END + CMP R0,R2 + BEQ 4$ + JSR PC,OPUT ;PUT IT + MOV BOB,EOA ;RESET + TSTB FFLG ;FINISHED?? + BEQ 3$ ;NO + BLT 8$ + BR CHSLOSE + +4$: TSTB FFLG + BLE 3$ + BR CHSLOSE + +CHBA: JSR PC,ARG.4 + JSR PC,SCBF ;SEARCH BUFFER + BCS 3$ +2$: DEC CVAL ;FINISHED? + BLE CHSWIN +1$: JSR PC,SCBFX + BCC 2$ +3$: MOV BOB,EOA ;RESET + TSTB FFLG ;FINISHED? + BGT CHSLOSE ;YES + JSR PC,IPUTC + BR 1$ ;AND CONTINUE + ;COMMAND TAB + +CHTAB: JSR PC,ARG.5 + CMPB -(R1),#11 + BEQ CHI1 + MOV #11,CVAL + BR CHI3 + +;COMMAND I (INSERT) + +CHI: TST STATE + BEQ CHI0 + JSR PC,ARG.7 +CHI3: MOV CVAL,R0 ;THE CHAR NUMBER WILL BE IN CVAL + JSR PC,INSERT ;INSERT THIS CHAR INTO THE BUFFER + EXIT ;THAT'S ALL + + +;ROUTINE TO INSERT THE CHAR IN R0 INTO THE BUFFER + +INSERT: PUSH ;SAVE THE CHAR + MOV #1,R2 + TSTMEM R2,BMV6 ;MAKE SURE WE HAVE ROOM FOR IT + MOV EOA,R0 ;GET OTHER POINTER + MOV R2,EOA ;RESET IT + BR 2$ ;AND SKIP + +1$: MOVB -(R0),-(R2) ;MOVE THE CHARS DOWN +2$: CMP R0,CPTR ;FINISHED? + BHI 1$ ;NO + MOVB (SP)+,(CPTR)+ ;MOVE IN THE CHAR + RTS PC + +CHI0: TSTB COLSW ;SHOULD WE INSERT INTO Q REGISTER + BEQ CHI1 ;NO, NORMAL STRING INSERT + + MOVB (R1)+,-(R6) ;OTHERWISE DO INSERT INTO Q REGISTER + CMPB (R6),#60 + BGE 1$ + ERROR + +1$: JSR PC,SETLIM + MOVB (R6)+,R0 + JSR PC,STUFF + EXIT + +CHI1: JSR PC,SETLIM + MOV QLEN,R0 + BEQ CHI6 + MOV R0,R2 + TSTMEM R2,BMV6 + MOV EOA,R0 + MOV R2,EOA + BR 3$ + +4$: MOVB -(R0),-(R2) +3$: CMP R0,CPTR + BHI 4$ + JSR PC,QSET + MOV QLEN,R2 +5$: MOVB (R0)+,(CPTR)+ + SOB R2,5$ +CHI6: CLR FFLAG + TSTB COLSW + BNE 1$ + EXIT +1$: CLRB COLSW + CLRB ATSW + CMPB (R1),#MESC + BNE 2$ + INC R1 +2$: EXITA + + + +BMV6: ERROR + + +SETLIM: MOVB #MESC,R0 + TSTB ATSW + BEQ 1$ + MOVB (R1)+,R0 +1$: MOVB R0,ATSW + JSR PC,SSTRX + CMPB ATSW,#MESC + BEQ 2$ + INC R0 +2$: SUB R1,R0 + MOV R0,-(R6) + MOVB ATSW,R0 + JSR PC,STRX + MOV (R6),R5 + ADD (R6)+,R1 + RTS PC + ;ROUTINE TO PUT A CHAR REPRESENTATION OF A NUMBER INTO THE BUFFER + +CHBS2: JSR PC,ARG.7 ;EXACTLY 1 + MOV CVAL,R0 ;GET IT + JSR PC,DECOUX ;GET CHARS + MOVB (SP)+,R2 ;COUNT + BIC #177400,R2 ;SINCE WE DID A MOVB COUNT,-(SP) + TSTMEM R2,BMV6 ;MAKE SURE WE HAVE ROOM FOR IT + MOV R2,R0 ;SAVE IT + BR 5$ + +3$: MOVB -(EOA),-(R2) ;MOVE DOWN +5$: CMP EOA,CPTR + BHI 3$ +4$: MOVB (SP)+,(CPTR)+ + CMP CPTR,R2 + BLO 4$ + MOV R0,EOA + EXIT + + +CHF: INC FFLAG + + + +CHF3: JSR R7,CHECKC + JSR R7,GETCHU + CMP R0,#'S + BEQ 1$ + CMP R0,#'N + BEQ 1$ + CMP R0,#'V ;GET A VARIABLE NAME + BEQ CHFV ;EXECUTE THE V FUNCTION + ERROR + +1$: ASL R0 + MOVB COLSW,COLFLG + MOVB ATSW,ATFLG + JMP @DTAB(R0) + +CHF2: MOVB ATFLG,ATSW + MOVB COLFLG,COLSW + + MOV NUM,R0 + NEG R0 + JSR R7,ARG.21 + JSR R7,LFB1 + JSR R7,DELE + + CMPB (R1),#MESC + BNE 2$ + CMPB 1(R1),#MESC + BNE 1$ + JMP CHI6 +1$: INC R1 +2$: JMP CHI1 + + + +;ROUTINE TO HACK VARIALBES VIA SYMBOLIC NAMES + +CHFV: CLR FFLAG ;SO WE DON'T GO BACK TO CHF2 + MOV #SYMTAB,R0 ;POINTER TO SYMBOL TABLE + MOV R1,-(SP) ;SAVE POINTER TO CHAR STRING + +1$: TST (R0) ;ARE THERE ANY MORE SYMBOLS? + BEQ 7$ ;NO, BAD SYMBOL NAME + JSR PC,CMPSTR ;LOOK FOR THIS SYMBOL + BEQ 3$ ;FOUND IT! + INC R0 + BIC #1,R0 ;GO TO WORD BOUNDRY + +2$: ADD (R0)+,R0 ;SKIP ANY ARGUMENTS + TST (R0)+ ;SKIP THE FUNCTION + MOV (SP),R1 ;RESTORE POINTER TO CHAR STRING + BR 1$ ;AHH THERE IT IS, NOW CHECK NEXT SYMBOL + +3$: TST (SP)+ ;POP THE OLD R1 + CMPB (R1)+,#MESC ;MAKE SURE THE LAST SYMBOL CHAR IS ESC + BNE 7$ ;SYMBOL ERROR IF NOT + INC R0 ;MAKE SURE WE'RE ON WORD BOUNDRY + BIC #1,R0 + +4$: MOV (R0)+,R2 ;GET A COUNT OF THE ARGUMENTS + BEQ 6$ ;NONE! + ASR R2 ;SINCE COUNT IS 2*NUMBER OF VARIABLES + +5$: MOV (R0)+,-(SP) ;PUSH AN ARGUMENT + SOB R2,5$ ;PUSH ALL THE ARGUMENTS + +6$: JMP @(R0)+ ;NOW EXECUTE THE FUNCTION + +7$: ERROR + + +;ROUTINE TO COMPARE TWO STRINGS. EXPECTS POINTER TO FIRST STRING IN +;R0 AND POINTER TO SECOND IN R1. THE COMPARISON ENDS WHEN A DIFFERENCE +;APPEARS, OR WHEN A ZERO APPEARS IN THE FIRST STRING. Z=> STRINGS EQUAL. + +CMPSTR: TSTB (R0)+ ;ARE WE AT THE END OF THE FIRST STRING? + BEQ 2$ ;YUP + CMPB -1(R0),(R1)+ ;ELSE CHECK THE NEXT BYTE + BEQ CMPSTR ;EQUAL, SO KEEP LOOKING + MOVB -1(R1),-(SP) + CMPB #'a,(SP) + BGT 3$ + CMPB #'z,(SP) + BLT 3$ + SUB #40,(SP) + CMPB -1(R0),(SP)+ + BEQ CMPSTR + BR 1$ +3$: TST (SP)+ +1$: TSTB (R0)+ ;FIND THE END OF THE STRING + BNE 1$ ;NOT YET + CLZ ;SIGNAL NOT EQUAL +2$: RTS PC + +;ROUTINE TO HANDLE SIMPLE LOCAL VARIABLES + +SYMLOC: JSR PC,SETVAR ;SET THE VARIABLES + ADD #4,SP ;POP THE ARGUMENTS + JMP EVAL ;AND CONTINUE + + +;ROUTINE TO GO INTO GRAPHICS MODE + +SYMGRF: + JSR PC,SETVAR ;SET THE VARIABLES + TSTB GRAPHM ;ARE WE NOW IN GRAPHICS MODE? + BEQ 1$ ;NO, TURN OFF GRAPHICS MODE + JSR PC,@SETCUR ;SET THE CURSOR TO RIGHT SPOT + +1$: ADD #4,SP ;POP THE ARGUMENTS + JMP EVAL ;AND CONTINUE + + +;ROUTINE TO SET GRAPHIC VARIABLES, WHICH SHOULD ALSO AFFECT THE SCREEN + +SYMVPS: ADD TOPSCR,CVAL ;make setting vpos relative to +SYMCUR: JSR PC,SETVAR ;SET THE VARIABLES + TSTB GRAPHM ;ARE WE IN GRAPHICS MODE? + BEQ 1$ ;YES, DO NOT ACTUALLY MOVE THE CURSOR + JSR PC,@SETCUR ;SET THE CURSOR +1$: ADD #4,SP ;POP THE ARGUMENTS + JMP EVAL ;AND CONTINUE + + +;ROUTINE TO ASSIGN VALUES TO VARIABLES + +SETVAR: JSR PC,ARG.1 ;SHOULD HAVE 0 OR 1 ARGUMENT + BEQ 2$ ;NO ARGUMENTS + TST 2(SP) ;IS IT A WORD OR BYTE? + BEQ 1$ ;WORD + MOVB CVAL,@4(SP) ;ASSIGN A BYTE VALUE + BR 2$ + +1$: MOV CVAL,@4(SP) ;ASSIGN A WORD VALUE + +2$: TST 2(SP) ;IS IT A WORD OR BYTE + BEQ 3$ ;WORD + MOVB @4(SP),R0 ;GET A BYTE VALUE + BR 4$ + +3$: MOV @4(SP),R0 ;GET A WORD VALUE + +4$: CLR STATE ;WE ABSORBED ANY ARGS PRESENT + RTS PC + + +;COMPUTE LINSIZ, LEAVE RESULT IN R0 AS ARGUMENT TO NEXT COMMAND + +SYMLIN: JSR PC,ARG.5 ;MAKE SURE THERE'S NO ARGUMENTS + JSR PC,LINSIZ ;DO THE FUNCTION, LEAVE RESULT IN R0 + JMP EVAL + + + +;ROUTINE TO COMPUTE THE NUMBER OF SCREEN LINES IN THE LINE OF . + +LINSIZ: PUSH ;FREE SOME REGISTERS + MOV CPTR,R0 ;GET . INTO R0 + CLR R1 ;WE WANT THE BEGINNING OF THIS LINE + JSR PC,LINE ;MOVE R0 HERE + PUSH ;SAVE IT + MOV CPTR,R0 + MOV #1,R1 + JSR PC,LINE ;NOW GO FORWARD 1 LINE + MOV R0,R5 ;LEAVE RESULTS IN R5 + POP ;RESTOR POINTER TO BEGINNING OF LINE + SUB R0,R5 ;COUNT THIS MANY CHARS + CLR R1 ;INITIAL LINE COUNT 0 + CLR R2 ;INITIAL COLUMN POSITION 0 + JSR PC,COUNT ;COUNT LINES AND COLUMNS + MOV R1,R0 ;RETURN LINE COUNT + TST R2 ;WAS THERE ANY OVERFLOW? + BEQ 1$ ;NO + INC R0 ;ELSE ADD IN AS EXTRA LINE + +1$: POP ;CLEAN UP + RTS PC + + +;ROUTINE TO MOVE A POINTER FORWARD OR BACKWARD LINES IN THE BUFFER. +;EXPECTS THE POINTER IN R0, AND A COUNT IN R1 WHOSE FORMAT IS JUST LIKE L. + +LINE: TST R1 ;SHOULD WE MOVE FORWARD OR BACKWARD + BGT 3$ ;FORWARDS + NEG R1 ;CONVERT TO A POSITIVE NUMBER + +1$: CMP R0,BOB ;LOOK FOR BEGINNING OF LINE + BLOS 2$ ;AT BEGINNING OF BUFFER + CMPB -(R0),#15 ;LOOK FOR A NL + BNE 1$ ;KEEP LOOKING + DEC R1 ;ONE LESS LINE + BGE 1$ ;KEEP DOING WHILE COUNT IS POSITIVE + INC R0 ;BACK OVER NL +2$: RTS PC + +3$: CMP R0,EOA ;NOW LOOK FOR END OF LINE + BHIS 4$ ;AT END OF BUFFER + CMPB (R0)+,#15 ;LOOK FOR A NL + BNE 3$ ;KEEP LOOKING + SOB R1,3$ ;KEEP MOV'N WHILE SOME COUNT IS LEFT +4$: RTS PC + ;ROUTINE TO READ AND WRITE ENTRIES IN RCMAC. RCMAC IS AN ARRAY OF FUNCTIONS +;TO BE EXECUTED BY CHARS IN CONTROL R MODE. THE ARRAY IS INDEXED BY CHARS +;HENCE THERE ARE 128 ENTRIES. WITH ONE ARG, THIS COMMAND RETURNS THE VALUE +;OF THE ARRAY SPECIFIED BY THE ARG WHICH SHOULD BE 0-127. WITH TWO ARGS, +;THE FIRST ARG IS INSERTED IN THE LOCATION OF THE SECOND ARG. SEE RCH FOR +;THE INTERPRETATION PLACED ON RCMAC ENTRIES. THIS ROUTINE IS ALSO USED + +SYMCST: POP R2 ;THIS SHOULD BE POINTER TO THE DISPATCH TABLE + JSR PC,ARG.12 ;MAKE SURE ARGS ARE IN CORRECT FORMAT + BNE 1$ ;THERE WERE TWO ARGS + MOV CVAL,R0 ;OTHERWISE, 1 ARG, GET THE ARRAY INDEX + ASL R0 ;CONVERT TO WORD OFFSET + ADD R0,R2 ;GET THE OFFSET INTO THE TABLE + BR 2$ ;RETURN THE INDEXED VALUE + +1$: MOV CVAL,R0 ;GET THE ARRAY INDEX + ASL R0 ;CONVERT TO WORD OFFSET + ADD R0,R2 ;GET THE OFFSET INTO THE TABLE + MOV CVAL1,(R2) ;INSERT THE FIRST ARG INTO THE ARRAY + +2$: MOV (R2),R0 ;GET THE VALUE SPECIFIED BY INDEX + CLR STATE ;WE ABSORBED ANY ARGS + JMP EVAL ;USE R0 AS ARG FOR NEXT COMMAND + + + +;ROUTINE TO EXECUTE ONE OF THE ^R MODE FUNCTIONS. THE FUNCTION SHOULD +;BE IN THE FORMAT RETURNED BY RCMAC, NAMELY A NEGATIVE INTEGER. + +SYMEXC: JSR PC,ARG.7 ;MAKE SURE WE HAVE EXACTLY ONE ARGUMENT + MOV CVAL,R0 ;THIS WILL BE THE FUNCTION + PUSH R1 ;SAVE COMMAND LOCATION + JSR PC,RCHJMP ;EXECUTE THE FUNCTION IN RDTAB CHOSEN BY R0 + POP R1 ;GET BACK ON THE TRACK + EXIT + + + +;ROUTINE TO RING THE BELL + +SYMBELL:JSR PC,ARG.5 ;NO ARGUMENTS PERMITTED + JSR PC,BELL ;RING THE BELL + EXIT ;THAT'S ALL + + +;ROUTINE TO RETURN INFO ABOUT A QREG. RETURNS -1 IF QREG IS NUMERIC, +;0 IF QREG IS ABSENT AND 1 IF IT'S A TEXT QREG. + +SYMQTS: JSR PC,ARG.7 ;EXACTLY ONE ARG + MOV CVAL,R0 ;GET NUMERIC REPRESENTATION OF QREG + JSR PC,FINDQ1 ;SET R2 POINTING TO QREG + BGT 1$ ;MUST BE TEXT QREG + BLT 2$ ;NO IT'S NUMERIC + CLR R0 ;NOT TEXT OR NUMERIC, IT'S NOT THERE + BR 3$ + +1$: MOV #1,R0 ;SAY THAT IT'S TEXT + BR 3$ + +2$: MOV #-1,R0 ;SAY THAT IT'S NUMERIC + +3$: CLR STATE ;TO ABSORB ARGUMENTS + JMP EVAL ;TO RETURN THE VALUE +;COMMAND LEFT BRACKET (<) + +CLB: JSR PC,ARG.1 + BNE 1$ ;ARG SPECIFIED + NEG CVAL ;SET TO -1 +1$: MOV ITTER,-(SP) + MOV CVAL,ITTER + BEQ 3$ + INCB ITCNT +5$: PUSHR1 + JSR PC,CMDX + +ITPUSH=6 + + CMPB -1(R1),#'> + BNE LOOPER + DEC ITTER + BEQ 4$ + POPR1 + BR 5$ + +4$: DECB ITCNT + TST (SP)+ + MOV (SP)+,ITTER + EXIT + +3$: MOV (SP)+,ITTER + MOV #'>+<'<*400>,R0 + JSR PC,MSTRX + MOV R0,R1 + INC R1 + EXIT + +LOOPER: ERROR + +;COMMAND RIGHT BRACKET (>) + +CRB: RTS PC + CHDQ: JSR PC,ARG.7 + JSR PC,GETCHU + CMP R0,#'G + BNE 2$ + TST CVAL + BGT 19$ + +11$: MOV #''+<'"*400>,R0 + JSR PC,MSTRX + MOV R0,R1 +19$: EXIT + +2$: CMP R0,#'L + BNE 3$ + TST CVAL + BLT 19$ + BR 11$ + +3$: CMP R0,#'E + BNE 4$ + TST CVAL + BEQ 19$ + BR 11$ + +4$: CMP R0,#'N + BNE 5$ + TST CVAL + BNE 19$ + BR 11$ + +5$: CMP R0,#'C + BNE 6$ + MOV CVAL,R0 + JSR PC,CHKSEP + BCC 19$ + BR 11$ + +6$: ERROR + ;COMMAND ; (??) + +CSC: JSR PC,ARG.1 + BEQ 1$ + TST CVAL + BR 3$ + +1$: TSTB SCHSW +3$: BNE 10$ + TSTB ITCNT + BEQ 2$ + MOV #'>+<'<*400>,R0 + JSR PC,MSTRX + MOV #1,ITTER + MOV R0,R1 +10$: EXIT + +2$: ERROR + CHEXPL: MOVB #'!,R0 + JSR PC,SSTRX + MOV R0,R1 + INC R1 + EXIT + +CHO: JSR PC,ARG.1 + BNE 1$ + CLR CVAL +1$: MOV R1,R0 + MOV CVAL,R1 + CMPB R1,ITCNT + BHI 2$ + MUL #ITPUSH,R1 + ADD R1,SP + CMP SP,STKSV + BHIS 3$ + MOV R0,R1 + MOV R0,-(SP) + MOV #MESC,R0 + JSR PC,SSTRX + MOV CSTART,R1 +8$: MOV #'!,R0 +5$: CMP R1,CEND + BHIS 2$ + CMPB (R1)+,R0 + BNE 5$ + JSR PC,SSTRX + MOV @SP,R2 +6$: CMP R1,R0 + BHIS 7$ + CMPB @R2,#MESC + BEQ 9$ + CMPB (R1)+,(R2)+ + BEQ 6$ +9$: INC R0 + MOV R0,R1 + BR 8$ + +7$: CMPB @R2,#MESC + BNE 9$ + INC R0 + MOV R0,R1 + TST (SP)+ + EXIT + +2$: ERROR + +3$: ERROR + ;^W TYPE A STRING + +CTW: JSR PC,ARG.5 + MOV #'W-'@,R0 + JSR PC,STRX + MOV #'W-100,R0 + JSR PC,SSTRX + MOV R0,R1 + INC R1 + MOV R1,-(R6) + JSR PC,QSET + MOV R0,R1 + JSR PC,TYPER + MOV (R6)+,R1 + EXIT + +;COMMAND ^L (ECHO A FORM FEED) + +CTL: JSR PC,ARG.5 + JSR PC,@CLRSCR + JSR PC,DSTAT + EXIT + +;COMMAND = (TYPE OUT VALUE) + +CEQ: JSR PC,ARG.7 + JSR PC,PRNUM + JSR PC,CRLF + EXIT + +PRNUM: MOV CVAL,R0 +CEQ1: JSR PC,DECOUT + TST R0 + BPL 2$ + JSR PC,DECOUX + MOV #40,R0 + JSR PC,TYO + MOVB (SP)+,R2 +1$: MOV (SP)+,R0 + JSR PC,TYO + DEC R2 + BGT 1$ +2$: RTS PC + +CTG: JSR PC,GETCHU + CMPB R0,#MESC + BNE 1$ + JSR PC,GETCHU + CMPB R0,#MESC + BNE 1$ + JMP FINISH + +1$: ERROR + +CHQUES: JSR PC,ARG.5 + COMB DEBSW + EXIT + ;ROUTINE TO READ IN A Q REGISTER NAME AND RETURN A POINTER TO THE DATA. +;SETS Z BIT IF NOT FOUND, SETS N BIT IF NUMERIC. RETURNS WITH R2 POINTING +;TO FIRST WORD OF QREG HEADER. FINDQ2 SAME EXCEPT EXPECTS NAME IN R0. + +FINDQ: + +1$: JSR PC,GETCH ;GET A CHAR INTO R0 + +FINDQ1=. +2$: CMP R0,#'@ ;LOOK FOR VALID QREG NAMES + BEQ 3$ + CMP R0,#'? + BEQ 3$ + CMP R0,#'" + BEQ 3$ + + CMP R0,#'0 ;MUST BE GREATER THAN THIS + BLO 8$ ;NOPE, ERROR + CMP R0,#'9 ;IS IT NUMERIC? + BLOS 3$ ;OK, GO AHEAD AND FIND IT + CMP R0,#'A ;ALPHA? + BLO 8$ ;NOPE, ERROR + CMP R0,#'Z ;UPPER CASE ALPHA? + BLOS 3$ ;OK! + CMP R0,#'a ;WHAT ABOUT LOWER CASE ALPHA + BLO 8$ ;HMM BAD + CMP R0,#'z ;REALLY? + BHI 8$ ;MUST BE BAD + +FINDQ2=. ;WILL THIS WORK?? +3$: MOV TBUFX,R2 ;INITIALIZE THE SEARCH + MOVB R0,QFREG + MOV R0,@BOQ ;GET Q REGISTER NAME TO STOP SEARCH + +4$: CMPB R0,@R2 ;IS THIS IT? + BNE 6$ ;NO + CMP R2,BOQ ;REALLY FOUND? + BEQ 5$ ;NO, WE RAN OUT OF STUFF + TST @R2 ;SET FLAG N IF NUMERIC +5$: RTS PC + +6$: TST (R2)+ ;NUMERIC? + BMI 7$ ;YUP + ADD (R2)+,R2 ;ALPHA - ADD COUNT + BIC #1,R2 ;MAKE WORDS +7$: TST (R2)+ ;GO TO NEXT + BR 4$ ;CONTINUE + +8$: ERROR ;BAD NEWS + + +;ROUTINE TO DELETE A Q REGISTER + +KILLQ: MOV #4,R0 ;COUNT FOR NUMERIC + TST @R2 ;IS IT NUMERIC?? + BMI 1$ ;YES + ADD 2(R2),R0 ;GET COUNT + BIC #1,R0 ;MAKE WORDS + TST (R0)+ ;SKIP TO END +1$: SUB R0,CPTR ;RESET ALL THE POINTERS + SUB R0,BOB + SUB R0,BOQ + SUB R0,EOA + ADD R2,R0 ;ADDRESS TO MOVE FROM +2$: MOV (R0)+,(R2)+ ;MOVE THINGS UP + CMP R2,EOA ;DONE?? + BLO 2$ ;NOPE + TSTB QMODE + BEQ 3$ + PUSHR1 + JSR PC,SETST + POPR1 + CMP R1,CEND ;KILL ME? + BHIS QK +3$: RTS PC + +QK: ERROR + ;ROUTINE TO SET UP THE COMMAND START AND END POINTERS. EXPECTS AND IMPLICIT +;ARGUMENT IN QMODE, NAMELY THE CHARACTER NAME OF THE QREG TO MACRO. IF THIS +;CHAR IS ZERO, THE TOP LEVEL COMMAND BUFFER IS ASSUMED. WHAT A KLUDGE. + +SETST: MOVB QMODE,R0 ;THIS SHOULD BE CHAR NAME OF QREG TO MACRO + BEQ 1$ ;NONE, MUST BE AT TOP LEVEL + JSR PC,FINDQ2 ;SET R2 POINT TO QREG + BLE QK ;NONE THERE + ADD #4,R2 ;THIS WILL BE START OF TEXT + MOV R2,CSTART ;SO START COMMAND HERE + ADD -2(R2),R2 ;GET THE LENGTH AND ADD TO START OF TEXT + INC R2 ;FUDGE FACTOR + MOV R2,CEND ;THIS WILL BE THE END OF THE COMMAND + RTS PC + +1$: MOV LIMBF,CSTART ;REMEMBER WE STARTED HERE... + MOV ENBF,CEND ;END ENDED HERE + RTS PC + + + +;ROUTINE TO CHECK FOR MORE MEMORY + +GETMEX: MOV R2,-(SP) + PUSHR1 + MOV ENBF,R0 + JSR PC,GETMEM + BEQ 1$ + MOV R0,-(SP) + MOV ENBF,R1 + ADD R1,R0 + MOV R0,ENBF + MOV R0,ENBF.4 + SUB #6,ENBF.4 + BR 2$ + +3$: MOVB -(R1),-(R0) +2$: CMP R1,LIMBF + BHI 3$ + MOV R0,LIMBF + MOVB QFREG,-(R6) + JSR PC,SETST + MOVB (R6)+,QFREG + MOV (SP)+,R0 +1$: POPR1 + MOV (SP)+,R2 + TST R0 + RTS PC + ;SEARCH FOR CHAR IN STRING +;R0=CHAR R1=PTR R2=END +;RETURNS WITH R0 POINTING TO THE CHAR IF FOUND, R1 AT INITIAL POSITION + +SSTRX: MOV CEND,R2 +SSTR: MOV R1,-(SP) +SSTR2: CMP R1,R2 + BHIS SSTR1 + CMPB R0,(R1)+ + BNE SSTR2 +SSTR3: MOV R1,R0 + DEC R0 + MOV (SP)+,R1 + RTS PC + +SSTR1: MOV R0,-(SP) +SSTR1X: MOV #'[,R0 + JSR PC,TYO + MOV (SP)+,R0 + JSR PC,TYO + MOV #'],R0 + JSR PC,TYO + ERROR + +MSTRX: MOV CEND,R2 + MOV R1,-(SP) + CLR -(SP) + MOV R0,-(SP) + SWAB R0 +1$: CMP R1,R2 + BHIS SSTR1X + CMPB R0,@R1 + BNE 3$ + INC 2(SP) + INC R1 + BR 1$ + +3$: CMPB @SP,(R1)+ + BNE 1$ + DEC 2(SP) + BGE 1$ + ADD #4,SP + BR SSTR3 + STRX: MOV CEND,R2 + PUSHR1 + MOVB QMODE,QREG + MOV R1,QNDX + SUB CSTART,QNDX + MOV #-25.,-(R6) + MOV MPTR,-(R6) + JSR PC,CHEK + JSR PC,SSTR + SUB R1,R0 + MOV R0,QLEN +STR1: MOV (R6)+,MPTR + TST (R6)+ + JSR PC,SETST + POPR1 + TSTB SFLG + BEQ 3$ + MOVB #'",R0 + JSR PC,STUFF +3$: RTS PC + +CHEK: CMP R1,R2 + BHIS SSTR1 +CHEK1: CMPB (R1),#'P-100 + BEQ 2$ + CMPB (R1),#'O-100 + BNE 1$ + MOV #CTLO,(R6) +3$: INC R1 +1$: RTS PC +2$: MOV #CTLP,(R6) + BR 3$ + +CTLO: MOVB (R1),R0 + JSR PC,FINDQ2 + BLE CTLO1 + INC 2(R6) + BEQ CTLO2 + MOV R2,R1 + CMP (R1)+,(R1)+ + CMP 2(R2),#2 + BLT 1$ + JSR PC,CHEK1 +1$: MOVB (R2),QREG + CLR QNDX + MOV 2(R2),QLEN + BR STR1 + +CTLO1: ERROR <$O.REG> +CTLO2: ERROR <$O.LOOP> + +CTLP: TST MPTR + BEQ ZROLN + MOVB (R1),R0 + CMP R0,#'1 + BLT 4$ + CMP R0,#'9 + BLE 1$ +4$: JSR PC,FINDQ2 + BGE 3$ + MOV 2(R2),R0 + BGT CTLP3 + ERROR <$P.ARG> +3$: ERROR <$P.REG> + +1$: SUB #60,R0 +CTLP3: MOV R0,-(R6) + CMPB R0,QARG + BLOS 1$ + MOVB R0,QARG +1$: MOVB @MPTR,R0 + ADD #2,MPTR + MOVB R0,QREG + BNE 10$ + MOV LIMBF,R1 + MOV R1,-(R6) + MOV ENBF,R2 + BR 11$ + +10$: JSR PC,FINDQ2 + CMP (R2)+,(R2)+ + MOV R2,-(R6) + MOV R2,R1 + ADD -2(R2),R2 + +11$: MOV MPTR,R0 + MOV (R6),R5 + ADD (R0),R1 + TST (R0)+ + MOV (R0),MPTR + MOVB -12(R0),R0 + + ADD #MESC,R0 + CMP R0,#MESC + BEQ 5$ + MOVB (R1)+,R0 +5$: MOV R0,QLEN + + MOVB QMODE,-(R6) + MOVB QREG,QMODE +3$: MOV QLEN,R0 + JSR PC,SSTR + DEC 4(R6) + BEQ CTLP4 + MOV R0,R1 + INC R1 + BR 3$ + +ZROLN: CLR QNDX + CLR QLEN + JMP STR1 + +CTLP4: MOVB (R6)+,QMODE + SUB R1,R0 + MOV R0,QLEN + CMP (R6)+,(R6)+ + CMP R0,#2 + BLT 1$ + JSR PC,CHEK1 +1$: SUB R5,R1 + MOV R1,QNDX + JMP STR1 + +QSET: MOVB QREG,R0 + BNE 1$ + MOV LIMBF,R2 + BR 2$ + +1$: JSR PC,FINDQ2 + BGT 3$ + ERROR +3$: CMP (R2)+,(R2)+ +2$: ADD QNDX,R2 + MOV R2,R0 + ADD QLEN,R2 + RTS PC + +STUFF: PUSHR1 + INCB QFLG + MOV #1$,-(R6) + TST -(R6) + MOV QLEN,-(R6) + MOV (R6),-(R6) + JSR PC,FINDQ2 + JMP QINSR1 +1$: JSR PC,SETST + POPR1 + CLRB QFLG + RTS PC + + +FIXUP: MOV (R6)+,R5 + MOV STKSV,R6 + CLRB QMODE + JSR PC,CLRPDS + CLRB RBOUT + CLR FFLAG + MOV EOA,R1 + CLR MPTR + CLRB EMFLG + CLRB MFLG + CLRB QFLG + JMP @R5 + GETCHU: JSR PC,GETCH + JMP GETUC + +GETCH: CMP R1,CEND + BHIS 1$ + MOVB (R1)+,R0 + TSTB DEBSW + BEQ 2$ + JSR PC,TYO +2$: RTS PC + +1$: ERROR + +CHKSEP: CMPB R0,#'$ + BEQ 2$ + CMPB R0,#'. + BEQ 2$ + CMPB R0,#'0 + BLO 1$ + CMPB R0,#'9 + BLOS 2$ + CMPB R0,#'A + BLO 1$ + CMPB R0,#'Z + BLOS 2$ + CMPB R0,#'A + BLO 1$ + CMPB R0,#'Z + BLOS 2$ +1$: SEC + RTS PC + +2$: CLC + RTS PC + +CLRPDS: MOVB QMODE,-(R6) + CLRB QMODE +3$: TSTB QPDS + BEQ 1$ + MOVB QPDS,R0 + INCB QPDS + JSR PC,FINDQ2 + BEQ 3$ + JSR PC,KILLQ + BR 3$ + +1$: TSTB EMPDS + BEQ 2$ + MOVB EMPDS,R0 + DECB EMPDS + JSR PC,FINDQ2 + BEQ 1$ + JSR PC,KILLQ + BR 1$ + +2$: MOVB (R6)+,QMODE + RTS PC + IPUTC: TSTB FFLG + BGT 6$ + CLRB FFLG +IPUT=. + MOVB #-1,INCHR + CLR INCNT +IPUT1=. + TSTB FFLG + BGT 6$ + TSTB INPFLG + BEQ 4$ + MOV #6,R2 + TSTMEM R2,1$ + TSTB FFLG + BMI 5$ + CLRB FFLG +2$: JSR PC,PRI + BCS 7$ + CMP R0,#14 + BNE 3$ + DECB FFLG +6$: RTS PC + +5$: MOV #14,R0 + CLRB FFLG +3$: MOVB R0,(EOA)+ + CMPB R0,INCHR + BEQ 6$ + DEC INCNT + BEQ 6$ + JSR PC,CHECKC + MOV #400,R2 + TSTMEM R2,,2$ + RTS PC + +4$: ERROR + +1$: ERROR + +7$: INCB FFLG ;EOF FLAG + RTS PC + +OPUT: TSTB OUTFLG ;ANY OUTPUT FILE + BNE 1$ ;YES + ERROR + +1$: MOV R1,-(SP) + MOV R0,R1 + JSR PC,PPOL + MOV (SP)+,R1 + RTS PC + SCBF: JSR PC,SETLIM + SUB R5,R1 + JSR PC,QSET + CLR NUM + MOV QLEN,R2 + BEQ SCBFX +1$: CMPB (R0)+,#'C-100 + BEQ 2$ + CMPB -1(R0),#'N-100 + BNE 3$ +2$: DEC R2 + INC R0 +3$: INC NUM + DEC R2 + BGT 1$ + +SCBFX: MOVB #-1,SCHSW + JSR PC,QSET + MOV R1,-(R6) + MOV R0,-(R6) +9$: MOV (R6),R0 + MOV CPTR,R2 + MOV QLEN,R1 + +1$: TST R1 + BEQ 12$ + CMP R2,EOA + BHIS 13$ + CMPB @R0,#'X-'@ + BHI 2$ + BEQ 5$ + CMPB @R0,#'C-'@ + BNE 4$ + JSR PC,SCHECK + BR 2$ + +5$: CMPB (R0)+,(R2)+ +20$: DEC R1 + BR 1$ + +4$: CMPB @R0,#'N-'@ + BNE 8$ + JSR PC,SCHECK + CMPB (R0)+,(R2)+ + BNE 20$ + BR 3$ + +8$: CMPB @R0,#'D-'@ + BNE 2$ + MOV R0,-(SP) + MOVB (R2)+,R0 + JSR PC,CHKSEP + MOV (SP)+,R0 + INC R0 + BCS 20$ + BR 3$ + +2$: DEC R1 + CMPB (R0)+,(R2)+ + BEQ 1$ +3$: INC CPTR + BR 9$ + +12$: MOV R2,CPTR + CLC + BR 14$ + +13$: MOV BOB,CPTR + CLRB SCHSW + SEC +14$: MOV 2(R6),R1 + MOV (R6)+,(R6)+ + RTS PC + SCHECK: INC R0 + CMP R1,#2 + BLT 1$ + DEC R1 + RTS PC +1$: ERROR + + ;TYPE ONE ARGUMENT - C, R, D + +ARG.8: JSR PC,ARG.2 +LFB1: MOV R0,R2 ;DUP IT + CMP R0,CPTR ;BEFORE OR AFTER?? + BHI 11$ ;BEFORE + MOV CPTR,R2 ;FIX + RTS PC ;AND QUIT + +11$: MOV CPTR,R0 ;LOWER ONE + RTS PC ;FINI + +;TYPE TWO ARGUMENT - L + +ARG.9: JSR PC,ARG.3 + BR LFB1 + +;TYPE FOUR ARG - T, K,X, ... + +ARG.11: CMP STATE,#14 + BNE ARG.9 ;LINE ORIENTED + ;DROP FOR TWO ARGS + +;TYPE THREE ARG - X,Y + +ARG.10: TSTB COLSW + BNE COLBAD + MOV CVAL,R2 + MOV CVAL1,R0 + ADD BOB,R0 + CMP R0,EOA + BHI FXARG1 + ADD BOB,R2 + CMP R2,R0 + BLO FXARG1 + CMP R2,EOA + BLOS FXARG2 + MOV EOA,R2 +FXARG2: RTS PC + +FXARG1: ERROR + +;TYPE 5 ARG - NO ARG - EX, ... + +ARG.5: TSTB COLSW + BNE COLBAD + TST STATE + BEQ 1$ ;GOOD +EARG5=. + ERROR + +1$: RTS PC + ;TYPE 6 ARG - 1 OR NONE + +ARG.6: TSTB COLSW + BNE COLBAD + BIT #13,STATE + BEQ 1$ + ERROR + +1$: RTS PC + +COLBAD: ERROR + +;TYPE SEVEN ARG - EXACTLY ONE + +ARG.7: TSTB COLSW + BNE COLBAD + CMP STATE,#4 ;IS IT? + BEQ 1$ ;YUP + ERROR + +1$: RTS PC + +;TYPE 8 ARG - 0 OR 1 AND SET CODES EQ FOR 0 NE FOR 1 + +ARG.1: TSTB COLSW + BNE COLBAD +ARG.1A: BIT STATE,#13 + BEQ 1$ + ERROR + +1$: TST STATE + RTS PC + +;TYPE 9 + +ARG.2: TSTB COLSW + BNE COLBAD + CMP STATE,#4 + BLOS 18$ ;GOOD + ERROR + +18$: MOV CVAL,R0 ;GET ARG +ARG.21: ADD CPTR,R0 ;MAKE REAL ADDR + CMP R0,EOA ;TOO FAR? + BLOS 1$ ;NO + MOV EOA,R0 ;FIX IT + RTS PC + +1$: CMP R0,BOB ;BEFORE BUFFER? + BHIS 2$ ;GOOD + MOV BOB,R0 ;FIX IT +2$: RTS PC + ;TYPE 10 + +ARG.3: TSTB COLSW + BNE COLBAD + MOV CVAL,R2 ;SET UP ARG + MOV CPTR,R0 + CMP STATE,#4 + BLOS $7 + ERROR + +$7: BEQ LFQ + TST STATE + BEQ LFF +LFB: CMP R0,BOB + BLOS LFF1 + CMPB -(R0),#15 + BNE LFB + INC R2 + BLE LFB + INC R0 +LFF1: RTS PC + +LFQ: TST R2 + BLE LFB +LFF: CMP R0,EOA + BHIS LFF1 + CMPB (R0)+,#15 + BNE LFF + DEC R2 + BGT LFF + RTS PC + +ARG.4: BIT #13,STATE + BEQ 1$ + ERROR + +1$: RTS PC + + +;TYPE 12 ARG 1 OR 2 ARGS, THE LAST ONE MUST BE IN RANGE 0-511, FOR RCMAC + +ARG.12: TSTB COLSW ;NO COLONS + BNE COLBAD + TST STATE ;WE BETTER HAVE AT LEAST ONE ARG + BEQ 1$ ;HMM BAD + CMP CVAL,#512. ;MAKE SURE IT'S VALID + BHIS 1$ ;TOO HIGH + CMP STATE,#4 ;SET Z IF WE HAVE ONE ARG + RTS PC + +1$: ERROR + +; .CSECT STACK + + .NLIST BEX +INIT: .ASCIZ /EMTECO.INIT/<33><33> +WATCH: .ASCII <12>/NEARING END OF BUFFER!!/<12> +WATCHN: +FILMSG: .ASCII <12>/FILE CREATED/<12> +FILMEN: +QMSG: .ASCII /IN MACRO Q-REG - / +QMEN: +QMSGE: .ASCII /IN EXTERNAL MACRO - / +QMSGN: + .EVEN + .LIST BEX + ;DISPATCH TABLE + +DTAB: + ;CONTROL CHARS. + NONE ;NULL + NONE ;^A + CTB ;^B + NONE ;^C + NONE ;^D + CTE ;^E + CTLF ;^F + CTG ;^G + CTLH ;^H + CHTAB ;^I (TAB) + NULL ;^J (LF) + CTLK ;^K + CTL ;^L + NULL ;^M (CR) + CTLN ;^N + NONE ;^O + NONE ;^P + NONE ;^Q + NONE ;^R + NONE ;^S + CTT ;^T + NONE ;^U + CTLV ;^V + CTW ;^W + CTRX ;^X + CTRY ;^Y + CTLZ ;^Z + ;FUNNY CTRL & SPECIALS + CMESC ;ESC + NONE ;^\ + NONE ;^] + CTUP ;^^ + NONE ;^_ + NULL ;SP + CHEXPL ; ! + CHDQ ; " + CHOR ; # + NONE ; $ + CHPER ; % + CHAND ; & + NULL ; ' + CHLP ; ( + CHRP ; ) + CHMUL ; * + CHPL ; + + CHCOM ; , + CHMI ; - + CHPD ; . + CHDIV ; / + ;NUMERALS +.REPT 10. + CHNM ; 0-9 +.ENDR + ;MORE SPECIALS + CHCOL ; : + CSC ; ; + CLB ; < + CEQ ; = + CRB ; > + CHQUES ; ? + CHAT ; @ + ;ALPHABETICS + CHA ; A + CHB ; B + CHC ; C + CHD ; D + CHE ; E + CHF ; F + CHG ; G + CHH ; H + CHI ; I + CHJ ; J + CHK ; K + CHL ; L + CHM ; M + CHN ; N + CHO ; O + CHP ; P + CHQ ; Q + CHR ; R + CHS ; S + CHT ; T + CHU ; U + CHV ; V + NONE ; W + CHX ; X + CHY ; Y + CHZ ; Z + CHLBR ; [ + CHBS ; \ + CHRBR ; ] + NONE ; ^ + CHBA ; _ + + +;TABLE OF SYMBOLS ACCESSIBLE TO TECO + +.MACRO DEFSYM NAME,FUNCTION,ARG1,ARG2,ARG3 + .ASCIZ NAME + .EVEN + .IF B ARG1 + 0 + .IFF + NARGS=1 + .IF NB ARG2 + NARGS=2 + .IF NB ARG3 + NARGS=3 + .ENDC + .ENDC + NARGS*2 + ARG1 + .IF NB ARG2 + ARG2 + .IF NB ARG3 + ARG3 + .ENDC + .ENDC + .ENDC + FUNCTION +.ENDM + +SYMTAB: DEFSYM "%BOTTOM",SYMLOC,BOTTOM,0 ;BOTTOM MARGIN + DEFSYM "%TOP",SYMLOC,TOP,0 ;TOP MARGIN + DEFSYM "%CENTER",SYMLOC,CENTER,0 ;CENTER OF WINDOW + DEFSYM "TOPSCR",SYMLOC,TOPSCR,0 ;FREE AREA AT THE TOP + DEFSYM "HEIGHT",SYMLOC,PAGSIZ,0 ;SIZE OF SCREEN IN LINES + DEFSYM "WIDTH",SYMLOC,LLEN,0 ;LINE LENGTH IN CHARS + DEFSYM "WINDOW",SYMLOC,WINDOW,0 ;NUMBER OF FIRST CHAR IN WINDOW + DEFSYM "GRAPHM",SYMGRF,GRAPHM,1 ;GRAPHICS MODE FLAG + DEFSYM "ECHOSW",SYMLOC,ECHOSW,1 ;0=>ECHO ON, 1=>ECHO OFF + DEFSYM "LINESIZE",SYMLIN ;NUMBER OF SCREEN LINES OF . + DEFSYM "RMODE",SYMLOC,RMODE,0 ;0=>NORMAL, 1=>^RMODE + DEFSYM "REXPT",SYMLOC,REXPT,0 ;EXPONENT FOR ^R COMMANDS + DEFSYM "RMARK",SYMLOC,RMARK,0 ;MARK FOR ^R COMMANDS + DEFSYM "REXEC",SYMEXC ;EXECUTE ^R MODE FUNCTIONS + DEFSYM "RLASTCH",SYMLOC,LASTCH,0 ;LAST CHAR READ IN ^R MODE + DEFSYM "BELL",SYMBELL ;RING THE BELL + DEFSYM "QTEST",SYMQTS ;RETURN STATUS OF REG + DEFSYM "^RMODE",SYMLOC,RMODE,0 ;0=>NORMAL, 1=>^RMODE + DEFSYM "^REXPT",SYMLOC,REXPT,0 ;EXPONENT FOR ^R COMMANDS + DEFSYM "^RCMAC",SYMCST,RCMAC ;READ AND WRITE RCMAC ARRAY + DEFSYM "^REXEC",SYMEXC ;EXECUTE ^R MODE FUNCTIONS + DEFSYM "^RLASTCH",SYMLOC,LASTCH,0 ;LAST CHAR READ IN ^R MODE + DEFSYM "^RHPOS",SYMCUR,HPOS,0 ;HORIZONTAL POSITION OF CURSOR + DEFSYM "^RVPOS",SYMVPS,VPOS,0 ;VERTICAL POSITION OF CURSOR +.IIF NZ TVS, DEFSYM "TV",SETTV ;TV CONSOLE + DEFSYM "C100",SETCON ;CONCEPT 100 + DEFSYM "TT2500",SETT25 ;2500 + DEFSYM "VT52",SETVT + DEFSYM "DATA",SETDAT ;DATAPOINT + DEFSYM "PADLF",SYMLOC,PADLF,0 + DEFSYM "PADSPEED",SYMLOC,PADSPD,0 + 0 ;END THE SYMBOL TABLE + .SBTTL ^R MODE COMMANDS + +;THIS SECTION PROCESSES THE ^R MODE COMMANDS. RCH IS THE MAIN DISPATCH +;ROUTINE OF THESE COMMANDS CORRESPONDING TO CHX FOR THE NORMAL COMMANDS. +;THE CONTROL R MODE COMMANDS DIFFER FROM NORMAL COMMANDS IN THAT THEY ARE +;EXECUTED AS SOON AS THE CHAR IS READ FROM THE TTY. NORMALLY, NON-CONTROL, +;NON-RUBOUT CHARS ARE SIMPLY INSERTED IN THE BUFFER AND SOME DISPLAY UPDATE +;IS RTS PC. CONTROL CHARS AND RUBOUT EXECUTE SPECIAL FUNCTION SUCH AS MOVING +;THE CURSOR AROUND, DELETING CHARS ETC. + +;^R MODE DISPATCHING + +;AS EACH CHAR IS READ IN, IT IS USED TO EXECUTE A COMMAND BASED ON THE +;THE R MODE DISPATCH TABLE, RCMAC. THIS TABLE IS A VECTOR OF NUMBERS +;WHICH CAN BE MODIFIED BY THE USER VIA THE FV^RCMACRO$ COMMAND. THE CHAR +;READ IN, DISPATCHES INTO THIS TABLE AND A NUMBER IS READ OUT. POSITIVE +;NUMBERS ARE ASSUMED TO BE THE ASCII VALUE OF A QREGISTER TO MACRO. +;THE QREGISTER IS MACRO'D VIA CHM AND RETURNS TO RCH VIA THE CHX JMP. +;NEGATIVE NUMBERS ARE FIRST CONVERTED TO POSITIVE, THEN USED TO SELECT +;A ^RMODE COMMAND VIA THE RDTAB. + +;.CSECT PGM + +RCH: CLR RMODE1 ;JUST SOME INITIALIZATION FOR CONTROL KLUDGE + TST RMODE ;ARE WE STILL IN ^R MODE? + BEQ 1$ ;NO, RETURN TO CALLER + JSR PC,RCHDSP ;NOW DISPATCH + CLR CTLMTA ;FLUSH THE OLD CONTROL AND META BITS + BR RCH ;NOW CHECK FOR MORE + +1$: RTS PC + + + +;DISPATCH ROUTINE. EXPECTS R1 TO HOLD A POINTER TO A TABLE 128 WORDS LONG. +;NEGATIVE NUMBERS IN THE TABLE REFER TO RDTAB ROUTINES, POSITIVE NUMBERS +;REFER TO Q REGISTERS. + +RCHDSP: JSR PC,TYI ;GET A CHAR INTO R0 + MOV R0,LASTCH ;SAVE THE CHAR + BIC #177600,R0 ;MAKE SURE IT'S 0-127 + BIS CTLMTA,R0 ;SET THE CONTROL AND META BITS + ASL R0 ;CONVERT TO WORD OFFSET + MOV #RCMAC,R1 ;USE THE C TABLE FOR DISPATCHING + ADD R0,R1 ;ADD THE BASE ADDRESS OF THE TABLE + MOV (R1),R0 ;GET THE FUNCTION TO EXECUTE + BLE RCHJMP ;NEGATIVE, THUS DISPATCH INTO RDTAB + JSR PC,FINDQ1 ;SET POINTERS TO PROPER Q REGISTER + BLE 1$ ;NOT ALPHA Q REG + MOV #1,RMODE1 ;TELL SOME PEOPLE WE ARE DOING ^R MODE + JMP CHM3 ;OTHERWISE, MACRO THIS QREGISTER + +1$: ERROR + +RCHCNT: RTS PC ;CONTINUATION POINT FOR MACROS + + + +;ROUTINE TO ACTUALLY JUMP THROUGH THE DISPATCH TABLE. IT IS LABLED +;SEPARATELY BECAUSE IT IS ALSO CALLED BY SYMEXC TO EXECUTE FUNCTIONS. + +RCHJMP: NEG R0 ;CONVERT TO POSITIVE + ASL R0 ;CONVERT TO WORD OFFSET + CMP R0,#RDSIZ ;MAKE SURE ITS A VALID FUNCTION + BHIS 1$ ;TOO HIGH + JMP @RDTAB(R0) ;EXECUTE THE FUNCTION + +1$: ERROR + ;ROUTINE TO RING THE TERMINAL'S BELL IMPLYING UNDEFINED ^R CHAR + +RCHUDF: JSR PC,BELL ;RING THE TERMINAL'S BELL + RTS PC + + + +;ROUTINE TO ESCAPE FROM ^R MODE + +RCHESC: CLR RMODE ;JUST CLEAR THE FLAG + RTS PC + + + +;ROUTINE TO SELECT A NEW DISPLAY WINDOW AND UPDATE THE SCREEN + +RCHL: JSR PC,DSTAT ;SET NEW STATUS LINE UP THERE + JSR PC,SETWIN ;SELECT A NEW WINDOW + MOV WINDOW,R0 + ADD BOB,R0 ;MAKE IT ABSOLUTE + JSR PC,TYPSCN ;TYPE EVERYTHING FROM R0 TO BOTTOM + JSR PC,UPDATE ;NOW SET THE CURSOR + RTS PC + + + +;ROUTINE TO MULTIPLY THE EXPT BY 4 + +RCHU: MOV REXPT,R0 ;GET THE RMODE EXPT + MUL #4.,R0 ;MULTIPLY IT BY 4 + MOV R1,REXPT ;PUT IT BACK + RTS PC + + + +;ROUTINE TO READ A QUOTED CHAR + +RCHQ: JSR PC,TYI ;GET A CHAR INTO R0 + JSR PC,RSTTY ;RESET SOME TTY STUFF + MOV R0,LASTCH ;SAVE IT + JSR PC,RCHNRM ;INSERT IT INTO THE BUFFER + RTS PC + ;ROUTINE TO INSERT NORMAL CHARS INTO BUFFER + +RCHNRM: PUSH ;SAVE CURRENT CURSOR POSITION + JSR PC,LINSIZ ;GET THE SCREEN SIZE OF . LINE INTO R0 + MOV R0,R1 ;SAVE IT + MOV LASTCH,R0 ;GET THE ACTUAL CHAR + JSR PC,INSERT ;INSERT IT INTO THE BUFFER + JSR PC,LINSIZ ;GET THE SCREEN SIZE OF . LINE INTO R0 + CMP R0,R1 ;HAS THE LINE GROWN? + BNE 1$ ;YES, MUST REDISPLAY REST OF SCREEN + MOV (SP),R0 ;GET OUR OLD CURSOR POSITION + MOV #1,R1 ;GO FORWARD ONE LINE + JSR PC,LINE ;ADVANCE R0 TO END OF CURRENT LINE + MOV R0,R2 ;THIS WILL BE THE END POINTER + MOV (SP),R1 ;OLD CHAR POSITION IS START POINTER + JSR PC,@CLREOL ;CLEAR TO END OF LINE + PUSH ;SAVE OUR OLD POSITION + JSR PC,TYPER ;TYPE TO END OF LINE + POP ;SET UP THE ARGUMENTS TO COUNT + MOV #1,R5 ;WE WANT TO COUNT 1 CHAR POSITION + JSR PC,COUNT ;FIGURE OUT WHERE TO LEAVE THE CURSOR + MOV R1,VPOS ;NEW VERTICAL POSITION + MOV R2,HPOS ;NEW HORIZONTAL POSITION + JSR PC,@SETCUR ;PUT THE CURSOR THERE + BR 2$ + +1$: POP ;RESTORE OUR ORIGINAL CURSOR POSITION + JSR PC,TYPSCN ;TYPE EVERYTHING FROM HERE DOWN + JSR PC,UPDATE ;PUT THE CURSOR IN THE RIGHT SPOT +2$: DEC REXPT + BGT RCHNRM ;REPEAT!! + RTS PC + + + + +;ROUTINE TO INSERT A CR + +RCHM: PUSH ;SAVE OUR CURRENT CURSOR + MOV #15,R0 + JSR PC,INSERT + POP ;GET OUR OLD CURSOR POSITION + JSR PC,TYPSCN ;TYPE TO BOTTOM OF THE SCREEN + JSR PC,UPDATE ;PUT THE CURSOR IN THE RIGHT PLACE + RTS PC + ;ROUTINE TO DELETE CHARS FROM THE BUFFER + +RCHD: MOV REXPT,R1 ;GET A COPY OF THE EXPT + BEQ 5$ ;ZERO, SO NOTHING TO DO + CMP CPTR,EOA ;ARE WE AT THE END OF THE WORLD? + BHIS RCHER1 ;YES, NOTHING TO DELETE + MOV CPTR,R0 ;NOW SEE IF WE WILL DELETE ANY NL'S + +1$: CMP R0,EOA ;ARE WE AT THE END YET? + BHIS 2$ ;YUP, OK NOTHING LEFT TO CHECK + CMPB (R0)+,#15 ;CHECK FOR A NEWLINE + BEQ 6$ ;FOUND ONE, DO WHOLE SCREEN UPDATE + SOB R1,1$ ;KEEP CHECKING + +2$: JSR PC,LINSIZ ;GET THE LENGTH OF CURRENT LINE + PUSH ;SAVE IT + MOV CPTR,R0 ;GET ANOTHER COPY OF CURSOR + MOV R0,R2 ;COPY IT + ADD REXPT,R2 ;TO DELETE THIS MANY CHARS + CMP R2,EOA ;HAVE WE GONE TOO FAR? + BLOS 3$ ;NO, IT'S OK + MOV EOA,R2 ;ELSE, PUT IT TO THE END + +3$: JSR PC,DELE ;DELETE IT FROM BUFFER + JSR PC,LINSIZ ;NOW SEE HOW LONG THE LINE IS + CMP R0,(SP)+ ;HAS IT CHANGED? + BNE 8$ ;YES, TYPE TO BOTTOM OF SCREEN + MOV CPTR,R0 ;GET ANOTHER COPY OF CURSOR + MOV #1,R1 ;WE WANT TO GO FORWARD 1 LINE + JSR PC,LINE ;MOVE R0 + MOV R0,R2 ;COPY IT + JSR PC,@CLREOL ;AND CLEAR THE LINE BEFORE TYPEING + MOV CPTR,R0 ;GET POINTER TO STARTING POSITION + JSR PC,GTYPER ;TYPE IT + CMP R2,EOA ;ARE WE AT END OF WORLD? + BLO 4$ ;NO, EVERYTHINGS OK + JSR PC,@CLREOL ;ELSE KILL TO END OF THIS LINE +4$: JSR PC,UPDATE ;PUT THE CURSOR WHERE IT BELONGS +5$: MOV #1,REXPT ;RESET THE EXPT + RTS PC + +6$: MOV CPTR,R0 ;GET THE CURSOR + MOV R0,R2 ;COPY THE CURSOR + ADD REXPT,R2 ;DELETE THIS MUCH + CMP R2,EOA ;WOULD WE GO TOO FAR? + BLOS 7$ ;NO, IT'S OK + MOV EOA,R2 ;ELSE RESET IT +7$: JSR PC,DELE ;DO IT + +8$: MOV CPTR,R0 ;GET COPY OF CURSOR POSITION + JSR PC,TYPSCN ;TYPE TO BOTTOM OF SCREEN + JSR PC,UPDATE ;PUT THE CURSOR WHERE IT BELONGS + MOV #1,REXPT ;RESET THE EXPT + RTS PC + + + ;ROUTINE TO KILL REST OF A LINE + +RCHK: CMP CPTR,EOA ;IS THERE ANYTHING TO KILL? + BHIS RCHER1 ;NO, ERROR + MOV CPTR,R0 ;COPY THE POINTER + MOV REXPT,R1 ;TO GO FORWARD ONE LINE + BLE 1$ ;FOR NOW, HAD BETTER BE POSITIVE + JSR PC,LINE ;MOVE R0 FORWARD + MOV R0,R2 ;THIS WILL BE END MARKER + MOV CPTR,R0 ;COPY POINTER AGAIN + JSR PC,DELE ;KILL THE LINE + MOV CPTR,R0 ;COPY POINTER ONCE MORE + JSR PC,TYPSCN ;TYPE TO END OF SCREEN + JSR PC,UPDATE ;PUT CURSOR WHERE IT BELONGS +1$: MOV #1,REXPT ;RESET REXPT + RTS PC + + + +;ROUTINE TO RUBOUT + +RCHRUB: CMP CPTR,BOB ;ARE WE ALREADY AT BEGINNING + BLOS RCHER1 ;YES, NOTHING TO RUBOUT + MOV CPTR,R0 ;GET A COPY OF THE CURSOR + SUB REXPT,R0 ;SEE IF THIS WOULD CAUSE IT TO GO TOO FAR + CMP R0,BOB ;TOO FAR? + BHIS 1$ ;NO, IT'S OK + MOV CPTR,R0 ;ELSE COMPUTE THE MAXIMUM WE CAN GO BACK + SUB BOB,R0 ;THIS IS IT + MOV R0,REXPT ;USE THIS AMOUNT + +1$: PUSH ;SAVE IT + JSR PC,RCHH ;GO BACK EXPT CHARS + POP ;NOW DELETE THIS MUCH + JSR PC,RCHD ;KILL THE CHAR + MOV #1,REXPT ;RESET THE EXPT + RTS PC + + + +;ERROR ROUTINE, JUST RINGS A BELL + +RCHER1: JSR PC,BELL ;GIVE HIM AN ERROR + MOV #1,REXPT ;RESET THE EXPT + RTS PC + ;ROUTINE TO HANDLE THE SPECIAL KEYS ON A VT52. THE DEFAULT IS +;TO USE THIS TABLE TO DISPATCH ON THE $X CHARS. + + +RCHMTA: BIS #METABT,CTLMTA ;SET THE META BIT + JMP RCHDSP + +RCHCTL: BIS #CTRLBT,CTLMTA + JMP RCHDSP + +RCHCMT: BIS #CTRLBT!METABT,CTLMTA ;SET BOTH CONTROL AND META + JMP RCHDSP + + + ;ROUTINE TO MOVE BACK LINES + +RCHP: CMP CPTR,BOB ;ARE WE AT THE BEGINNING? + BLOS RCHERR ;YES, NO WHERE TO GO + NEG REXPT ;TO MOVE BACK REXPT LINES + BR RCHNP ;COMMON ROUTINE + + + +;ROUTINE TO MOVE TO NEXT LINE + +RCHN: CMP CPTR,EOA ;ARE WE AT THE END ALREADY? + BHIS RCHERR ;YES ERROR + +RCHNP: MOV CPTR,R0 + MOV REXPT,R1 ;GO DOWN EXPT LINES + MOV #1,REXPT ;RESET EXPT + JSR PC,LINE ;MOVE R0 + MOV R0,CPTR ;RESET POINTER + JSR PC,UPDATE ;RESET CURSOR + RTS PC + + + +;ROUTINE TO MOVE BACK CHARS + +RCHH: CMP CPTR,BOB ;ARE WE ALREADY AT BEGINNING? + BLOS RCHERR ;YES, CAN'T GO BACK ANY MORE + SUB REXPT,CPTR ;MOVE THE CURSOR BACK + CMP CPTR,BOB ;DID WE GO TOO FAR? + BHIS RCHFH ;NO, IT'S OK + MOV BOB,CPTR ;ELSE FIX IT + BR RCHFH ;COMMON ROUTINE + + +;ROUTINE TO MOVE FORWARD CHARS + +RCHF: CMP CPTR,EOA ;ARE WE AT THE END? + BHIS RCHERR ;YUP, NO WHERE TO GO + ADD REXPT,CPTR ;MOVE THE CURSOR FORWARD + CMP CPTR,EOA ;TOO FAR? + BLOS RCHFH ;NO, ITS OK + MOV EOA,CPTR ;ELSE FIX IT + +RCHFH: MOV #1,REXPT ;RESET THE EXPT + JSR PC,UPDATE ;PUT CURSOR WHERE IT BELONGS + RTS PC + + +;COMMON ERROR ROUTINE + +RCHERR: MOV #1,REXPT ;RESET THE EXPT + JSR PC,BELL ;BLEEP TO TELL HIM + RTS PC + ;ROUTINE TO GO TO BEGINNING OF A LINE + +RCHA: CMP REXPT,#1 ;DID HE TYPE ANY ^U'S + BNE RCHE1 ;YES, WELL THEN DO THE OPPOSITE, NAMELY ^E +RCHA1: MOV CPTR,R0 ;GET OUR INITIAL POSITION + CLR R1 ;THIS MEANS BEGINNING LIKE FOR L COMMAND + JSR PC,LINE ;GO TO BEGINNING OF LINE + BR RCHAEB ;JOIN COMMON ROUTINE TO UPDATE DISPLAY + + + + +;ROUTINE TO GO TO END OF A LINE + +RCHE: CMP REXPT,#1 ;DID HE TYPE ANY ^U'S + BNE RCHA1 ;YES, DO THE OPPOSITE, NAMELY ^A +RCHE1: MOV CPTR,R0 ;GET OUR INITIAL POSITION + MOV #1,R1 ;GO FORWARD ONE LINE + JSR PC,LINE + CMPB -1(R0),#15 ;IS THE CHAR JUST BEFORE CURSOR A NL? + BNE RCHAEB ;NO, MUST BE AT THE END OF WORLD + DEC R0 ;OTHERWISE, BACK UP BEFORE NL + BR RCHAEB ;JOIN COMMON ROUTINE + + + +;ROUTINE TO GO TO BEGINNING OF BUFFER + +RCHB: CMP REXPT,#1 ;DID HE TYPE ANY ^U'S + BNE 1$ ;YES, THEN HE WANT TO GO TO END OF BUFFER + MOV BOB,R0 ;OTHERWISE, CURSOR GO TO START + BR RCHAEB ;JOIN COMMON ROUTINE TO UPDATE DISPLAY + +1$: MOV EOA,R0 ;SET CURSOR TO END OF WORLD + + +RCHAEB: MOV #1,REXPT ;RESET REXPT TO ITS DEFAULT VALUE + MOV R0,CPTR ;PEOPLE SHOULD LEAVE NEW CURSOR LOC IN R0 + JSR PC,UPDATE ;FIX UP THE SCREEN + RTS PC + + ;ROUTINE TO INSERT A NL AND BACK OVER IT + +RCHO: MOV REXPT,R1 ;MAKE SURE THERE IS SOMETHING TO DO + BEQ 2$ ;NO + +1$: PUSH ;SAVE CURSOR + MOV #15,R0 + JSR PC,INSERT + POP ;GO BACK TO OUR CURRENT POSITION + SOB R1,1$ + +2$: MOV #1,REXPT ;RESET REXPT + MOV CPTR,R0 ;ARG TO TYPSCN + JSR PC,TYPSCN ;TYPE FROM R0 TO END OF SCREEN + JSR PC,UPDATE ;PUT THE CURSOR BACK TO RIGHT SPOT + RTS PC + + + +;ROUTINE TO PAGE SOME NUMBER OF TIMES + +RCHV: DEC REXPT ;ANYTHING LEFT TO DO + BLT 1$ ;NOPE + JSR PC,PAGE ;WRITE OUT ONE PAGE + BR RCHV ;DO IT AGAIN + +1$: MOV #1,REXPT ;RESET REXPT + JSR PC,RCHL ;RESET THE WINDOW AND RETYPE THE SCREEN + RTS PC + ;ACCENT STUFF +RCHACC: MOV LASTCH,R0 + MOV #ACCTAB,R1 +1$: CMPB 1(R1),R0 ;FOUND THE RIGHT CHAR? + BEQ 2$ ;YUP + TST (R1)+ + BNE 1$ +5$: JMP RCHUDF ;??? HOW DID WE LOSE? +2$: PUSH R1 ;TO BE SAFE + MOVB (R1),LASTCH + JSR PC,RCHNRM ;INSERT THE ACCENT + JSR PC,RCHH ;AND BACKSPACE OVER IT + JSR PC,TYI ;INPUT NEXT CHAR + POP R1 ;POINTER TO THE HEAD OF THE TABLE + TST (R1)+ +3$: CMPB R0,(R1) ;THIS ONE? + BEQ 4$ + TST (R1)+ + TSTB 1(R1) + BLT 3$ + JSR PC,RCHD ;DELETE THE ACCENT + BR 5$ +4$: MOVB 1(R1),-(SP) + JSR PC,RCHD ;DELETE THE ACCENT + POP LASTCH ;GET THE CHARACTER TO INSERT + JMP RCHNRM + +ACCTAB: .BYTE 240,'\ + .BYTE 'A,201 + .BYTE 'E,204 + .BYTE 'O,212 + .BYTE 'U,215 + .BYTE 'a,221 + .BYTE 'e,224 + .BYTE 'o,232 + .BYTE 'u,235 + + .BYTE 241,'^ + .BYTE 'A,202 + .BYTE 'E,205 + .BYTE 'I,210 + .BYTE 'O,213 + .BYTE 'U,216 + .BYTE 'a,222 + .BYTE 'e,225 + .BYTE 'i,230 + .BYTE 'o,233 + .BYTE 'u,236 + + .BYTE 242,'" + .BYTE 'E,206 + .BYTE 'I,211 + .BYTE 'O,214 + .BYTE 'U,217 + .BYTE 'e,226 + .BYTE 'i,231 + .BYTE 'o,234 + .BYTE 'u,237 + + .BYTE 243,'/ + .BYTE 'E,207 + .BYTE 'e,227 + + .BYTE ',,', + .BYTE 'C,203 + .BYTE 'c,223 + 0 + +RCHFSW: PUSH + TST FRENCH ;IS FRENCH SWITCH ON? + BNE 1$ +4$: POP + JMP RCHNRM ;NO, DO NORMAL THING +1$: MOV LASTCH,R0 + MOV #FRCTAB,R1 +2$: CMPB R0,(R1)+ ;IS THIS THE THING TO BE CONVERTED? + BEQ 3$ + TSTB (R1)+ ;GO TO NEXT + BEQ 5$ ;RAN OFF END, TRY OTHER TABLE + +3$: MOVB (R1),LASTCH + BR 4$ ;GO DO NORMAL THING WITH CONVERTED CHARACTER + +5$: MOV #FRATAB,R1 ;THE ACCENT CHARS +6$: CMPB R0,(R1)+ ;ON OF THESE? + BEQ 7$ + TSTB (R1)+ + BNE 6$ + BR 4$ ;NOT IN EITHER TABLE + +7$: MOVB (R1),LASTCH ;PUT THE ACCENT HERE + JMP RCHACC ;AND GO PROCESS IT + +FRCTAB: .BYTE '?,223 ;C CEDILA + .BYTE '/,227 ;E AGUE + .BYTE '~,'? + .BYTE '`,'/ + 0 + +FRATAB: .BYTE '{,'^ + .BYTE '},'\ + .BYTE '|,'" + 0 + +;ROUTINE TO DO A SEARCH +RCHSER: PUSH + MOV #SEARPT,R1 + JSR PC,GOBLIN ;RAD IN A LINE + HALT + + +GOBLIN: JSR PC,SETSP1 ;SET UP THE PROMPT + MOV #SPSTA2,R2 + CLR (R2) +1$: JSR PC,DSTAT + JSR PC,TYI + CMP #15,R0 + BEQ 2$ + CMP #177,R0 + BNE 3$ + CLRB -(R2) + BR 1$ +3$: CMP #SPSTA2+MAXSPL,R2 + BEQ 2$ + MOVB R0,(R2)+ + BR 1$ +2$: RTS PC + +SEARPT: .ASCIZ /Search:/ +.EVEN + ;TABLE ^R MODE FUNCTIONS + +;THE RCM NAMES ARE THE VALUES STORED IN RCMAC +;THE RCH NAMES ARE THE ACTUAL ROUTINES + +.MACRO DEFR NAME + RCM'NAME = - + RCH'NAME + RDSIZ = RDSIZ + 2 +.ENDM + +RDSIZ = 0 + + +;.CSECT STACK + +RDTAB: DEFR UDF ;UNDEFINED, JUST BLEEP + DEFR NRM ;INSERT NORMAL CHARS + DEFR D ;DELETE CHARS + DEFR ESC ;ESCAPE FROM ^R MODE + DEFR L ;SELECT A NEW WINDOW + DEFR M ;INSERT A IN ITS MODE + DEFR K ;KILL TO END OF LINE + DEFR RUB ;RUB OUT A CHAR + DEFR N ;GO FORWARD EXPT LINES + DEFR P ;GO BACK EXPT LINES + DEFR F ;GO FORWARD EXPT CHARS + DEFR H ;GO BACK EXPT CHARS + DEFR U ;MULTIPLY REXPT BY 4 + DEFR Q ;INSERT ANY CHAR, QUOTED INSERT + DEFR A ;GO TO BEGINNING OF LINE + DEFR B ;GO TO BEGINNING OR END OF BUFFER + DEFR E ;GO TO END OF LINE + DEFR O ;INSERT NL AND BACK OVER IT + DEFR V ;PAGE + DEFR ACC ;SPECIAL ACCENT STUFF + DEFR MTA ;META + DEFR CTL ;CONTROL + DEFR SER ;SEARCH + DEFR CMT ;CONTROL AND META + DEFR FSW ;NORMAL IF NOT IN FRENCH MODE + ;CONTROL R MODE CHAR DISPATCH TABLE +;TO FIND THE FUNCTION SPECIFIED BY RCM'NAME, LOOK FOR A ROUTINE LABLED RCH'NAME + +RCMAC: .REPT 1000 + RCMUDF + .ENDR + +.MACRO DK KEY,ROT + .=> + RCM'ROT +.ENDM + +;FOR CONTROL-NOT META KEYS +.MACRO DKC KEY,ROT + .=+400> + RCM'ROT +.ENDM + +;FOR META-NOT-CONTROL KEYS +.MACRO DKM KEY,ROT + .=+1000> + RCM'ROT +.ENDM + +;FOR CONTROL-META KEYS +.MACRO DKCM KEY,ROT + .=+1400> + RCM'ROT +.ENDM + + + + DK 1,A ;^A + DK 2,B ;^B + DK 4,D ;^D + DK 5,E ;^E + DK 6,F ;^F + DK 10,H ;^H + DK 11,NRM ;^I + DK 13,K ;^K + DK 14,L ;^L + DK 15,M ;^M + DK 16,N ;^N + DK 17,O ;^O + DK 20,P ;^P + DK 21,Q ;^Q + DK 23,SER ;^S + DK 25,U ;^U + DK 26,V ;^V + DK 33,MTA ;ESC + DK 34,CMT ;^\ + + .REPT 95. + DK .RPCNT+40,NRM ;NON-CONTROL NON-RUBOUT CHARS + .ENDR + +;ON C100, THE FOLLOWING KEYS MIGHT GET SWAPPED IN FRENCH MODE: + DK '{,FSW + DK '},FSW + DK '|,FSW + DK '/,FSW + DK '?,FSW + DK '^,FSW + DK '~,FSW + DK 177,RUB ;RUBOUT + + +;HERE ARE THE META-NOT-CONTROL CHARACTERS + + DKM 33,ESC ;TWO ALT'S ESCAPE +;FOR C100: + DKM 73,P ;UPARROW KEY + DKM 76,H ;BACKARROW + DKM 75,F ;FORWARD ARROW + DKM 74,N ;DOWNARROW + DKM 134,V ;UNSHIFTED SCROLL + +.=RCMAC+2000 + + + +; .CSECT STACK +ERRST: +EE$CNX=0 +.MACRO ERRCAL X + E$'X +.ENDM + + .REPT EE$CNT +EE$CNX=EE$CNX+1 + ERRCAL \EE$CNX + .ENDR +.EVEN +ENDER: + + + + +;MACRO TO SIMULATE READCH FOR NOW + + +.MACRO READCH + JSR PC,.REDCH +.ENDM + + +; .CSECT STACK + +;DEFINE STORAGE FOR THE TTY OUTPUT BUFFER + +TTOBUF: +TTFLDS: 1 ;FILE DESCRIPTOR FOR TTY OUTPUT FILE +TTLEFT: 512. ;REMAINING SLOTS IN BUFFER +TTNEXT: TTOBFF ;POINTER TO NEXT FREE SLOT +TTOBFF: .BLKB 512. ;BUFFER FOR ACTUAL OUTPUT + + + +;TABLE OF SPECIAL ROUTINES FOR PROCESSING CONTROL CHARS + + .EVEN +CTRTBL: NTYI ;^@ + NTYI ;^A + NTYI ;^B + NTYI ;^C + NTYI ;^D + NTYI ;^E + NTYI ;^F + NTYI ;^G + NTYI ;^H + NTYI ;^I + NTYI ;^J + NTYI ;^K + NTYI ;^L + NTYI ;^M + NTYI ;^N + NTYI ;^O + NTYI ;^P + NTYI ;^Q + NTYI ;^R + NTYI ;^S + NTYI ;^T + CTRU ;^U + NTYI ;^V + NTYI ;^W + NTYI ;^X + NTYI ;^Y + NTYI ;^Z + NTYI ;^[ (ALTMODE) + NTYI ;^\ + NTYI ;^] + NTYI ;^^ + NTYI ;^_ + ;TTYMOD COMMAND USED TO READ THE TTY INITIAL STATUS +GFL: 0 + +;TTYMOD COMMAND USED TO REPLACE THE TTY DATA +SFL: 0 + + +; .CSECT PGM + + +;ROUTINE TO GO INTO ^R MODE + +RSET: MOVB #1,ECHOSW ;DISABLE ECHOING + MOVB #1,GRAPHM ;ENABLE GRAPHICS MODE + MOVB #1,RMODE + RTS PC + + +;ROUTINE TO GO OUT OF ^R MODE + +RCLR: + MOV PAGSIZ,VPOS ;NOW SET CURSOR TO BOTTOM OF SCREEN + DEC VPOS ;WE WANT LAST LINE + CLR HPOS ;FIRST COLUMN + JSR PC,@SETCUR ;PUT THE CURSOR HERE + JSR PC,@CLREOL ;KILL THE LINE + DEC VPOS ;MOVE BACK TO PREVIOUS LINE + DEC VPOS ;MOV BACK ANOTHER LINE SO WE DON'T SCROLL + JSR PC,@SETCUR ;PUT THE CURSOR HERE + CLR R0 + JSR PC,SSTAT + CLRB ECHOSW ;RE-ENABLE ECHOING + CLRB RMODE + RTS PC + +;ROUTINE TO READ A CHAR FROM THE TTY + +TYI: READCH + MOV (SP)+,R0 + BIC #177600,R0 + CMP R0,#40 ;IS IT A CONTROL CHAR? + BHIS NTYI ;NO + ASL R0 ;CONVERT TO WORD OFFSET + MOV CTRTBL(R0),-(SP) ;GET THE SPECIAL ROUTINE TO EXECUTE + ASR R0 ;RETURN R0 TO NORMAL + JMP @(SP)+ ;NOW EXECUTE SPECIAL ROUTINE AND RETURN + +NTYI: CMP R0,#177 ;IS IT RUBOUT? + BEQ 2$ ;YES, DO NOTHING + TSTB UCSW ;SHOULD WE UPPER CHASE THE CHAR? + BEQ 1$ ;NOPE + JSR PC,GETUC ;CHANGE IT TO UPPER CASE + +1$: JSR PC,CHKRB ;CHECK IF WE SHOULD PRINT \ + TSTB ECHOSW ;SHOULD WE ECHO THE CHAR? + BNE 2$ ;NO + JSR PC,TYO ;ECHO IT + +2$: RTS PC ;RETURN CHAR IN R0 + + +;ROUTINE TO PROCESS ^U'S + +CTRU: JSR PC,CHKRB ;FIX ANY RUBOUT STUFF + RTS PC + + ;OUTPUT A CHAR IN R0 + +TYO: JSR PC,CTYO ;PROCESS CHAR AND PUT IN BUFFER + JSR PC,TTFLSH ;MAKE SURE THE BUFFER IS EMPTY + RTS PC + + +;PUT CHAR IN R0 INTO THE TTY OUTPUT BUFFER + +CTYO: CMP R0,#40 ;IS IT A CONTROL CHAR + BLO 1$ ;YES, SPECIAL TREATMENT + BIT #200,R0 ;IS IT A SPECIAL GRAPHIC? + BEQ 21$ ;NOPE + CMP #TT2500,TERMT ;ONLY 2500 HAS SPECIAL GRAPHICS + BEQ 22$ + CMP #C100,TERMT ;NOW THE CONCEPT 100 HAS THEM TOO + BEQ 23$ + BIC #200,R0 + JSR PC,CTYO ;JUST TYPE NORMALLY + BIS #200,R0 + RTS PC + +22$: PUSH R0 + MOV #22,R0 ;SPCIAL QUOTE + JSR PC,TTPUTC + POP R0 +21$: JSR PC,NTYO ;TYPE AS NORMAL CHAR + RTS PC + +23$: PUSH R0 + MOV #'j,R0 + JSR PC,ETTPUT ;SELECT CHARACTER SET + MOV #41,R0 + JSR PC,TTPUTC ;CHARACTER SET 1 + MOV #'T,R0 ;UGH, TRANSPARENT MODE + JSR PC,ETTPUT + MOV (SP),R0 + BIC #200,R0 + JSR PC,NTYO ;TYPE NORMALLY + MOV #'t,R0 + JSR PC,ETTPUT ;TRANSPARENT MODE OFF + MOV #'j,R0 + JSR PC,ETTPUT ;SELECT CHAR SET BACK + MOV #40,R0 + JSR PC,TTPUTC ;WHEW! + POP R0 + RTS PC + +1$: CMP R0,#33 ;ALTMODE? + BNE 2$ ;NO + MOV R0,-(SP) ;SAVE THE CHAR + MOV #'$,R0 ;CHANGE ALTMODES TO DOLLAR SIGNS + JSR PC,NTYO ;TYPE NORMALLY + MOV (SP)+,R0 ;RESTORE THE ALTMODE + RTS PC + +2$: CMP R0,#14 ;FORMF? + BNE 4$ ;NOPE + TST RMODE ;ARE WE IN ^R MODE? + BNE 9$ ;YES, TYPE AS ^L + TSTB FFSW ;SHOULD WE TYPE FORMFEEDS? + BEQ 9$ ;YES, TYPE AS ^L + BR 15$ + +4$: CMP R0,#15 ;NL? + BNE 6$ ;NO + TSTB GRAPHM ;DO SPECIAL GRAPHICS HACK? + BNE 5$ ;YES + PUSH R0 ;SAVE THE CR + MOV #12,R0 ;PUT A LF INTO THE BUFFER + JSR PC,TTPUTC +13$: POP R0 ;RESTORE THE CR AND PUT IT IN THE BUFFER + BR 15$ + +5$: JSR PC,@GRCRLF ;SPECIAL GRAPHIC CRLF + RTS PC + +6$: CMP R0,#11 ;TAB? + BNE 9$ ;NO + TSTB GRAPHM ;DO SPECIAL GRAPHICS HACK? + BNE 7$ ;YES +15$: JSR PC,TTPUTC ;PUT THE CHAR INTO THE BUFFER + RTS PC + +7$: PUSH ;NEED SOME REGISTERS + MOV HPOS,R1 ;OUR CURRENT HORIZONTAL POSTION + ADD #8.,R1 + BIC #7,R1 ;SET R1 TO NEXT TAB STOP + SUB HPOS,R1 ;THIS IS HOW MANY SPACES WE MUST TYPE + MOV #40,R0 ;A SPACE +8$: JSR PC,NTYO ;TYPE IT + SOB R1,8$ ;TYPE THE APPROPRIATE NUMBER OF SPACES + POP ;CLEAN UP + RTS PC + + +9$: MOV R0,-(SP) ;SAVE THE ORGINAL CHAR + MOV #'^,R0 + JSR PC,NTYO ;TYPE AN ^ + MOV (SP),R0 ;NOW GET THE ORIGINAL CHAR + ADD #100,R0 ;CONVERT FROM CONTROL TO NORMAL + JSR PC,NTYO ;NOW TYPE AS NORMAL CHAR + MOV (SP)+,R0 ;RESTORE THE ORIGINAL CHAR + RTS PC + + + +;ROUTINE TO TYPE NORMAL CHARS AND HACK OVERFLOWS +;NTYO IS ONLY CALLED BY CTYO AND BY ITSELF +;IT IS ONLY CALLED WITH NON-CONTROL CHARACTERS, AND IT MAINTAINS HPOS +;IT ALSO NOTICES LINE OVERFLOW AND DOES THE \ HACK IF THE LINE OVERFLOWS +;CALLING GRCRLF TO RETURN THE CARRIGE AND CLR HPOS AND INC VPOS +;IF NTYO IS CALLED WITH VPOS OR HPOS EQUAL OR GREATER TO THE SCREEN LIMITS, +;IT DOES NOTHING. +;NTYO CALLS TTPUTC TO DO THE ACTUAL OUTPUTING +;NOTE THAT IF GRAPHM IS ZERO NONE OF THESE SPECIAL HACKS HAPPEN +NTYO: TSTB GRAPHM ;SPECIAL GRAPHIC STUFF + BNE 1$ ;YUP + JMP TTPUTC ;PUT CHAR IN BUFFER + +1$: CMP VPOS,PAGSIZ ;ARE WE PAST THE END OF SCREEN? + BHIS 2$ ;YUP, IGNORE ANYTHING + MOV LLEN,-(SP) ;GET THE LLEN OF SCREEN + DEC (SP) ;GET NUMBER OF LAST COLUMN + CMP HPOS,(SP)+ ;ARE WE THERE? + BEQ 3$ ;YES, DO AN OVERFLOW + JSR PC,TTPUTC ;PUT CHAR IN BUFFER + INC HPOS ;ADVANCE TO NEXT CHAR POSITION +2$: RTS PC + +3$: PUSH R0 ;SAVE THE CHAR + MOV #'\,R0 ;BACKSLASH MARKS THE OVERFLOW + JSR PC,TTPUTC ;PUT IT IN THE BUFFER + POP R0 ;RESTORE THE CHAR + JSR PC,@GRCRLF ;TYPE A NEWLINE + JSR PC,NTYO ;NOW TYPE THE CHAR NORMALLY + RTS PC + + +; .CSECT STACK ;D SPACE STORAGE FOR INDIRECT EXECUTION +TTWCNT: 0 ;COUNT OF CHARS TO WRITE +; .CSECT PGM + + + +;ROUTINE TO DO BUFFERED OUTPUT ON THE TTY OUTPUT BUFFER + +TTPUTC: TST TTLEFT ;ANY SPACE LEFT? + BGT 1$ ;THERE ARE SOME SLOTS LEFT + JSR PC,TTFLSH ;OTHERWISE FLUSH THE OUTPUT + +1$: MOVB R0,@TTNEXT ;PUT IN THE CHAR + PUSH R0 + JSR PC,TTSCUR + CMP #12,(SP) ;LINE FEED? + BNE 2$ + MOV PADLF,R0 + JSR PC,PAD +2$: POP R0 + INC TTNEXT ;ADVANCE POINTER + DEC TTLEFT ;ONE LESS SPACE LEFT + RTS PC + +;ROUTINE TO PUT (R0) MILLISECONDS OF PADDING INTO THE BUFFER + +PAD: PUSH R1 + MOV R0,R1 + BEQ 2$ + CLR R0 + DIV PADSPD,R1 ;CONVERT FROM MILLISECS TO CHARACTER TIMES + MOV #177,R0 +1$: JSR PC,TTPUTC + SOB R1,1$ +2$: POP R1 + RTS PC + + +;ROUTINE TO DO A SPECIAL GRAPHICS CRLF + +DPGRCL: +TTGRCL: +TVGRCL: +C1GRCL: +VTGRCL: PUSH R0 ;NEED A REGISTER + JSR PC,@CLREOL + MOV #15,R0 ;NOW TYPE A CARRIAGE RETURN + JSR PC,TTPUTC + CLR HPOS ;GO TO COLUMN 0 + CMP VPOS,PAGSIZ ;HAVE WE OVERFLOWED SCREEN? + BHIS GRLF1 ;YUP, DON'T BOTHER TO TYPE ANYTHING ELSE + INC VPOS + CMP VPOS,PAGSIZ ;ABOUT TO OVERFLOW SCREEN? + BLO GRLF ;NOPE + TSTB RMODE ;IN ^R MODE? + BNE GRLF1 ;YES, DON'T TYPE THE LF + MOV TOPSCR,VPOS + JSR PC,@SETCUR ;SET CURSOR TO TOP OF SCREEN + BR GRLF2 +GRLF: MOV #12,R0 + JSR PC,TTPUTC +GRLF2: TST RMODE + BNE GRLF1 ;DON'T CLEAR THE LINE IN ^R MODE + JSR PC,@CLREOL +GRLF1: POP R0 ;CLEAN UP + RTS PC + + + +;CLEAR TO END OF LINE +TVCLRE: +TTCLRE: +DPCLRE: PUSH R0 + MOV #36,R0 ;KILL TO END OF LINE + JSR PC,TTPUTC +PUTRET: POP R0 + RTS PC + +VTCLRE: PUSH R0 + MOV #'K,R0 + JSR PC,ETTPUT + BR PUTRET + +C1CLRE: PUSH R0 + MOV #23,R0 + JSR PC,ETTPUT + MOV #16.,R0 + JSR PC,PAD + BR PUTRET + +ETTPUT: PUSH R0 + MOV #33,R0 ;TYPE ESCAPE CHAR + JSR PC,TTPUTC + POP R0 + JMP TTPUTC + +;ROUTINE TO SET THE CURSOR TO THE LOCATION SPECIFIED BY HPOS AND VPOS + +VTSETC: PUSH R0 ;NEED A REGISTER + MOV #'Y,R0 ;TYPE Y + JSR PC,ETTPUT ;TYPE ESC Y + MOV VPOS,R0 ;THE LINE ADDRESS + ADD #40,R0 ;THATS HOW THE VT52 LIKES IT + JSR PC,TTPUTC + MOV HPOS,R0 ;THE COLUMN ADDRESS + ADD #40,R0 + JSR PC,TTPUTC + JSR PC,TTFLSH ;MAKE SURE THE BUFFER IS EMPTY + POP R0 ;CLEAN UP + RTS PC + +; SITS CURSOR POSITIONING STUFF +.IF NZ TVS +TVSETC: MOV HPOS,-(SP) + MOV VPOS,-(SP) + MOV #2,-(SP) + MOVB #.TVSET+.PRWRT,1(SP) + $INVOK + RTS PC +2$: +.ENDC + +C1SETC: PUSH R0 + MOV #141,R0 + JSR PC,ETTPUT + MOV VPOS,R0 + ADD #40,R0 + JSR PC,TTPUTC + MOV HPOS,R0 + ADD #40,R0 + JSR PC,TTPUTC + JSR PC,TTFLSH + POP R0 + RTS PC + +DPSETC: +TTSETC: PUSH + TST VPOS ;GOING TO 0? + BNE 8$ + TST HPOS + BNE 8$ + MOV #35,R0 ;HOME UP + JSR PC,TTPUTC + CLR DVPOS + CLR DHPOS + BR SETDON +8$: MOV #13,R0 ;GO DOWN + MOV VPOS,R1 + SUB DVPOS,R1 + BEQ SETHOR ;NO CHANGE IN VERTICAL + BGT SETCUP ;SET CURSOR DOWN (OVPOS < VPOS) + MOV #32,R0 ;GO UP + NEG R1 +SETCUP: JSR PC,TTPUTC + SOB R1,SETCUP +SETHOR: MOV #30,R0 ;GO BACKWARDS + MOV HPOS,R1 + SUB DHPOS,R1 + BEQ SETDON ;DONE + BGT SETFWD ;SET IT FORWARD (HPOS > OHPOS) + MOV #31,R0 + NEG R1 +SETFWD: JSR PC,TTPUTC + SOB R1,SETFWD +SETDON: JSR PC,TTFLSH + POP +SETRTS: RTS PC + +TTSCUR: CMP #TT2500,TERMT + BEQ 1$ + CMP #DATAP,TERMT + BNE SETRTS +1$: BIC #177400,R0 + CMP R0,#40 + BGE INCH ;REGULAR CHAR INC THE HORIZONTAL POSITION + ASL R0 ;MAKE IT A WORD OFFSET + JMP @CURTAB(R0) + +INCH: CMP LLEN,DHPOS ;END OF THE LINE? + BEQ 1$ ;YES DON'T INC IT + INC DHPOS +1$: RTS PC + +INCV: CMP PAGSIZ,DVPOS ;BOTTOM OF SCREEN? + BEQ 1$ + INC DVPOS ;NO SO GO DOWN +1$: RTS PC + +DECH: TST DHPOS + BEQ 1$ + DEC DHPOS ;DON'T LET IT GO NEGATIVE +1$: RTS PC + +DECV: TST DVPOS + BEQ 1$ + DEC DVPOS +1$: RTS PC + +HUP: CLR DVPOS ;HOME UP +DCR: CLR DHPOS + RTS PC + +HDOWN: CLR DHPOS ;HOME DOWN + MOV PAGSIZ,DVPOS +DNULL: RTS PC + +DPTAB: INC DHPOS + BIC #7,DHPOS ;FAKE OUT A TAB + RTS PC + +CURTAB: DNULL ;^@ + DNULL ;^A + DNULL ;^B + DNULL ;^C + DNULL ;^D + DNULL ;^E + DNULL ;^F + DNULL ;^G + DECH ;^H (BACKSPACE) + DPTAB ;^I (TAB) + INCV ;^J (LF) + INCV ;^K (DOWN) + DNULL ;^L + DCR ;^M (CR) + DNULL ;^N + DNULL ;^O + DNULL ;^P + DNULL ;^Q + DNULL ;^R + DNULL ;^S + DNULL ;^T + DNULL ;^U + DNULL ;^V + DNULL ;^W + INCH ;^X (RT) + DECH ;^Y (LT) + DECV ;^Z (UP) + DNULL ;ESC + HDOWN + HUP + DNULL + DNULL +DVPOS: 0 +DHPOS: 0 + + + + +;ROUTINES TO CLEAR THE SCREEN +TVCLRS: +TTCLRS: +DPCLRS: MOV #35,R0 +GNCLRS: JSR PC,TTPUTC +GNCLR1: MOV TOPSCR,VPOS + CLR HPOS + JSR PC,@SETCUR + JMP @KILLSC + +C1CLRS: PUSH R0 + MOV #'?,R0 + JSR PC,ETTPUT + POP R0 + BR GNCLR1 + +VTCLRS: MOV #'H,R0 + JSR PC,ETTPUT + BR GNCLR1 + +;ROUTINE TO KILL FROM HERE TO END OF SCREEN + +VTKILS: PUSH R0 + MOV #'J,R0 ;KILL TO END OF SCREEN CHAR + JSR PC,ETTPUT ;SEND IT + JSR PC,TTFLSH ;EMPTY THE BUFFER + POP R0 + RTS PC + +.IF NZ TVS +TVKILS: PUSH + MOV PAGSIZ,R1 + SUB VPOS,R1 + BLT 4$ + CMP -(SP),-(SP) + MOV #<.TVSET*400>+2,-(SP) ;READ CURSOR POSITION + $INVOK +2$: JSR PC,@CLREOL + TST R1 ;LAST LINE? + BEQ 3$ ;YES + MOV #15,R0 + JSR PC,TTPUTC + MOV #12,R0 ;SPACE DOWN + JSR PC,TTPUTC + DEC R1 + BR 2$ +3$: JSR PC,TTFLSH + MOV #<<.TVSET+.PRWRT>*400>+2,-(SP) + $INVOK +4$: POP + RTS PC +.ENDC +TTKILS: +DPKILS: PUSH R0 + MOV #37,R0 + JSR PC,TTPUTC + JSR PC,TTFLSH + POP R0 + RTS PC + +C1KILS: PUSH R0 + MOV #3,R0 + JSR PC,ETTPUT + MOV #100.,R0 + JSR PC,PAD + POP R0 + RTS PC + +;ROUTINE TO RING THE TERMINAL'S BELL + +BELL: PUSH R0 +.IFNZ TVS + CMP #TV,TERMT ;NO BELL FOR TVS CURRENTLY + BEQ 1$ +.ENDC + MOV #7,R0 ;CONTROL G + JSR PC,TTPUTC ;SEND IT + JSR PC,TTFLSH ;EMPTY THE BUFFER +1$: POP R0 + RTS PC + +;DISPLAY THE STATUS LINE AS THE TOP SCREEN LINE +DSTAT: TST GRAPHM + BEQ 1$ + PUSH + CLR HPOS + CLR VPOS ;GO TO THE TOP LINE + JSR PC,@SETCUR + JSR PC,@CLREOL ;CLEAR IT OUT + TST STFLAG ;SPECIAL STATUS LINE? + BNE 4$ + MOV #GREET,R1 + JSR PC,ZTYPE + MOV #VERN,R0 + JSR PC,DECOUT + TSTB INPFLG + BEQ 2$ + MOV #INAMEP,R1 + JSR PC,ZTYPE +2$: TSTB OUTFLG + BEQ 3$ + MOV #ONAMEP,R1 + JSR PC,ZTYPE +3$: JSR PC,TTFLSH + POP + JSR PC,@SETCUR + POP +1$: RTS PC + +4$: MOV #SPSTA1,R1 + JSR PC,ZTYPE + MOV #SPSTA2,R1 + JSR PC,ZTYPE + BR 3$ + +STFLAG: 0 ;NON-ZERO IMPLIES TYPE THE CRUFT BELOW IN THE STATUS LINE +MAXSPL=50. +SPSTA1: .BLKB MAXSPL +SPSTA2: .BLKB MAXSPL + +SETSP1: MOV #SPSTA1,R0 + BR SETSP +SETSP2: MOV #SPSTA2,R0 +SETSP: PUSH R2 + MOV #1,STFLAG + MOV #MAXSPL-1,R2 +1$: MOVB (R1)+,(R0)+ + BEQ 2$ + SOB R2,1$ + CLRB (R0)+ +2$: POP R2 + RTS PC + +ZTYPE: PUSH R0 +1$: MOVB (R1)+,R0 + BEQ 2$ + JSR PC,CTYO + BR 1$ +2$: POP R0 + RTS PC + +GREET: .ASCIZ /EDITOR./ + .EVEN + + ;ROUTINE TO COUNT SCREEN POSITION OFFSETS FROM ACTUAL CHARS IN +;THE BUFFER. EXPECTS STARTING CHAR POINTER IN R0, STARTING SCREEN +;LINE IN R1, STARTING SCREEN COLUMN IN R2 AND COUNT OF CHARS IN R5. +;RETURNS FINALLY LINE IN R1 AND FINAL COLUMN IN R2. + +COUNT: TST R5 ;ANY CHARS TO COUNT? + BEQ 10$ ;NO, JUST RETURN + MOV LLEN,-(SP) + DEC (SP) ;FIND NUMBER OF LAST COLUMN + +1$: CMPB (R0)+,#40 ;IS IT A CONTROL CHAR? + BHIS 7$ ;NO, NORMAL CHAR + CMPB -1(R0),#33 ;IS IT ESCAPE? + BEQ 7$ ;PRINTS AS "$" + CMPB -1(R0),#11 ;TAB? + BNE 4$ ;NO + MOV R2,-(SP) + ADD #8.,(SP) + BIC #7,(SP) + SUB R2,(SP) ;FIND COUNT TO NEXT TAB STOP + +2$: CMP R2,2(SP) ;ARE WE IN LAST COLUMN + BLO 3$ ;NO + INC R1 ;ELSE DO CRLF + CLR R2 + +3$: INC R2 + DEC (SP) ;ONE LESS SPACE IN THE TAB + BGT 2$ ;SOME MORE LEFT, KEEP COUNTING + TST (SP)+ ;POP THE COUNT + BR 9$ ;THAT'S ALL FOR THIS TAB + +4$: CMPB -1(R0),#15 ;NL? + BNE 5$ ;NOPE + INC R1 ;GO DOWN ONE LINE + CLR R2 ;BACK TO COLUMN 0 + BR 9$ ;THAT'S ALL FOR THIS NL + +5$: CMP R2,(SP) ;ASSUME NORMAL CTRL CHAR, SKIP TWO SPACES + BLO 6$ ;NO, WE'RE NOT IN LAST COLUMN + INC R1 ;ELSE GO DOWN ONE LINE + CLR R2 ;AND BACK TO COLUMN 0 + +6$: INC R2 ;ONE SPACE + +7$: CMP R2,(SP) ;ARE WE IN LAST COLUMN + BLO 8$ ;NO, NOT IN LAST COLUMN + INC R1 ;ELSE GO DOWN ONE LINE + CLR R2 ;AND BACK TO COLUMN 0 + +8$: INC R2 ;ONE SPACE + +9$: SOB R5,1$ ;THAT'S ALL FOR THAT CHAR + TST (SP)+ ;POP THE LAST COLUMN NUMBER + +10$: RTS PC + +GETUC: CMPB R0,#140 + BLOS 1$ + CMPB R0,#'Z+40 + BHI 1$ + SUB #40,R0 +1$: RTS PC + + + +CHKRB: TSTB RBOUT + BEQ 1$ + PUSH R0 + MOV #'\,R0 + JSR PC,CTYO + POP R0 + CLRB RBOUT +1$: RTS R7 + +TYO.R: JSR R7,CHKRB + JSR R7,CTYO + RTS R7 + + + +;OUTPUT A NEW LINE + +CRLF: PUSH ;NEED A REGISTER + MOV #15,R0 ;NEWLINE + JSR PC,TYO ;TYPE IT + POP ;CLEAN UP + RTS PC + + + +;OUTPUT A STRING BETWEEN R1 AND R2 + +TYPER: CMP R1,R2 + BHIS 1$ + JSR PC,CHECKC + MOVB (R1)+,R0 + JSR PC,CTYO ;PUT A CHAR IN THE BUFFER + BR TYPER +1$: JSR PC,TTFLSH ;EMPTY THE BUFFER + RTS PC + ;DECIMAL CONVERT, EXPECTS R1 POINTING TO STRING AND R2 POINTING TO MAX LENGTH + +DECIN: MOV R3,-(SP) ;SAVE IT + CLR R3 ;AND CLEAR +1$: CMP R1,R2 ;ARE WE PAST BOUNDRY + BHI 2$ ;YES, GIVE UP + MOVB (R1)+,R0 ;NEXT CHAR + CMP R0,#'0 ;DIGIT? + BLO 2$ ;NO + CMP R0,#'9 + BHI 2$ + MUL #10.,R3 + SUB #'0,R0 + ADD R0,R3 + BR 1$ + +2$: MOV R3,R0 + MOV (SP)+,R3 + DEC R1 ;ADJUST + RTS PC + + + +;DECIMAL OUTPUT, TYPES THE NUMBER IN R0 + +DECOUT: PUSH + TST R0 ;NEGATIVE NUMBER? + BGE 1$ ;NOPE + MOV #'-,R0 ;ELSE TYPE MINUS SIGN + JSR PC,TYO ;TYPE IT + MOV 2(SP),R0 ;RESTORE THE NUMBER + NEG R0 ;CONVERT TO POSITIVE, AN TYPE AS POSITIVE + +1$: MOV R0,R1 ;DIVIDEND SHOULD BE 32 BIT NUMBER IN R0,R1 + CLR R0 ;ZERO HIGH ORDER BITS OF NUMBER + DIV #10.,R0 ;PUT DIVIDEND IN R0, REMAINDER IN R1 + TST R0 ;ZERO REMAINDER? + BEQ 2$ ;YES, NOW UNWIND RECURSION + JSR PC,DECOUT ;ELSE TYPE HIGH ORDER DIGITS RECURSIVELY + +2$: MOV R1,R0 ;COPY REMAINDER + ADD #'0,R0 ;CONVERT TO CHAR 0 + JSR PC,TYO ;TYPE IT + POP ;CLEAN UP + RTS PC + +;ROUTINE TO TAKE A NUMBER IN R0 AND CONVERT TO A STRING REPRESENTATION +;WHICH IS SAVED ON THE STACK. WHEN THIS ROUTINE RETURNS, THE FIRST +;THING ON THE STACK IS A COUNT OF CHARS IN THE NUMBER, THEN COME THE +;CHARS, WITH MOST SIGNIFICANT DIGIT ON TOP. + +DECOUX: MOV R1,R2 ;SAVE R1 + MOVB #1,STATE+1 ;THIS WILL BE THE COUNT +2$: CMP R0,#10. ;LESS THAN 10? + BLO 1$ ;YES, THE LAST DIGIT + INCB STATE+1 ;ONE MORE CHAR PUSHED + MOV R0,R1 ;GET READY FOR THE DIVIDE + CLR R0 + DIV #10.,R0 ;GET REMAINDER IN R1 + MOV @SP,-(SP) ;MOVE RETURN ADDRESS DOWN + ADD #60,R1 ;CONVERT TO ASCII DIGIT + MOV R1,2(SP) ;COPY THE DIGIT INTO STACK SPOT + BR 2$ ;DO ANOTHER CHAR + +1$: MOV R2,R1 ;RESTORE R1 + MOV (SP)+,R2 ;PUT THE RETURN ADDRESS IN R2 + ADD #60,R0 ;CONVERT LAST DIGIT TO ASCII DIGIT + MOV R0,-(SP) ;SAVE THE LAST DIGIT + MOVB STATE+1,-(SP) ;SAVE THE COUNT OF CHARS + CLRB STATE+1 ;?? + JMP @R2 ;RTS SORT OF + + + + + + +;SUBROUTINES FOR HACKING ASCIZ STRINGS FOR DIRECTORIES AND FILENAMES. + +;ROUTINE TO CONCATENATE ONE STRING TO ANOTHER. HEAD GOES IN R1, TAIL IN R0, +;AND LENGTH OF RESULT FIELD IN R2. TAIL IS COPIED IN HEAD FIELD. + +CONCAT: TSTB (R1)+ ;FIND THE END OF THE HEAD FIELD + BEQ 1$ ;GOT IT + SOB R2,CONCAT ;CAN ONLY DO THIS MUCH + SEC ;SIGNAL ERROR + RTS PC + +1$: TSTB -(R1) ;BACK UP TO ZERO BYTE, THEN FALL INTO MOVSTR + + + +;ROUTINE TO MOVE AN ASCIZ STRING FROM ONE PLACE TO ANOTHER. + +MOVSTR: MOVB (R0)+,(R1)+ ;MOVE FROM (R0) TO (R1) + BEQ 1$ ;FOUND THE END + SOB R2,MOVSTR ;R2 HAS MAXIMUM LENGTH OF RESULT FIELD + SEC ;SIGNAL ERROR +1$: RTS PC + + + ;ROUTINE TO MOVE THE DIRECTORY PART OF A FILENAME TO ANOTHER FIELD +;AS AN ASCIZ STRING. R0 POINTS TO FILENAME, R1 TO FIELD, AND R2 CONTAINS +;SIZE OF THE FIELD. + +PUTDIR: PUSH ;SAVE PTR TO BEGINNING OF DIRECTORY + +1$: TSTB (R0)+ ;LOOK FOR THE END OF THE FILENAME + BNE 1$ ;NOT THERE YET.. + +2$: CMP R0,(SP) ;ARE WE AT THE BEGINNING YET? + BLOS 5$ ;YES, MUST NOT BE ANY FILENAME + CMPB -(R0),#'/ ;LOOK FOR LAST / IN FILENAME + BNE 2$ ;NOT FOUND YET + +3$: INC R0 ;MOVE TO CHAR AFTER / + PUSH ;SAVE THIS SPOT + MOV 2(SP),R0 ;RESET POINTER TO START OF FILENAME + +4$: MOVB (R0)+,(R1)+ ;MOVE A CHAR + DEC R2 ;ONE LESS CHAR OF ROOM + BLE 6$ ;NO ROOM, OVERFLOW ERROR + CMP R0,(SP) ;ARE WE DONE? + BLO 4$ ;NO, STILL SOME LEFT + POP ;CLEAN UP A LITTLE + +5$: DEC R2 ;ROOM FOR ZERO? + BLT 7$ ;NO, SIGNAL ERROR + CLRB (R1) ;PUT A ZERO AT THE END + POP ;CLEAN UP THE REST + CCC ;SIGNAL NO ERRORS + RTS PC + +6$: POP ;CLEAN UP A LITTLE +7$: POP ;CLEAN UP THE REST + SEC ;SIGNAL ERROR + RTS PC + + +;ROUTINE TO COPY JUST THE FILENAME PROPER FROM A PATHNAME. + +PUTFIL: PUSH ;SAVE POINTER TO PATHNAME + +1$: TSTB (R0)+ ;LOOK FOR THE END OF THE PATHNAME + BNE 1$ ;NOT THERE YET + +2$: CMP R0,(SP) ;ARE WE AT BEGINNING? + BLOS 3$ ;YES + CMPB -(R0),#'/ ;ELSE LOOK FOR LAST / + BNE 2$ ;NOT FOUND YET + INC R0 ;SKIP THE / + +3$: ADD #2,SP ;CLEAN UP + JSR PC,MOVSTR ;PUT IN AS MUCH OF THE NAME AS WILL FIT + CLRB -(R1) ;MAKE SURE THERE IS A ZERO AT THE END + RTS PC + +FILUNM: MOV #FILNAM,R2 + CLR FILNIL ;NO ILLEGAL CHAR + BR SETFN2 + +;ROUTINES TO GET A FILENAME FROM COMMAND STRING, PUT IN QREGISTER ", +;THEN COPY TO FILNAM OR EMFIL. + +SETFNM: MOV #FILNAM,R2 ;PUT THE FILENAME IN FIELD FILNAM + BR SETFN1 + +SETFN: MOV #EMFIL,R2 ;PUT THE FILENAME IN FIELD EMFIL + +SETFN1: MOV #40,FILNIL ;SPACE IS ILLEGAL +SETFN2: MOV R2,-(R6) ;POINTER TO RESULT FIELD + MOVB ATSW,-(R6) + JSR R7,SETLIM ;COPY NAME STR INTO QREG ", ADVANCE R1 PAST IT + MOVB (R6)+,ATSW ;SETLIM CLOBBERS TO DELIMITER $ IN ATSW WAS 0 + MOV R1,-(R6) ;SAVE POINTER TO COMMAND STRING + JSR R7,QSET ;SET R0 TO START OF NAME STRING, R2 TO END + MOV QLEN,R1 ;LENGTH OF NAMESTR, SET BY QSET + CMP R1,#44. ;WAS IT LESS THAN OR EQUAL TO 44 CHARS? + BLE 5$ ;YES, IT'S OK + MOV #44.,R1 ;ELSE SET IT TO 44. AS MAXIMUM +5$: MOV 2(R6),R2 ;RESTORE POINTER TO RESULT FIELD +1$: CMPB @R0,#33 ;$ MARKS THE END OF THE FIELD, ARE WE THERE? + BEQ 2$ ;YES, DONE + CMPB (R0),FILNIL ;SHOULDN'T BE ANY SPACES IN FILENAMES + BLOS .BADF ;FOUND A SPACE OR CONTROL CHAR, BAD FILE NAME + CMPB (R0),#'Z!40 ;MAKE SURE NO BRACKETS OR OTHER STRANGOS + BHI .BADF ;FOUND ONE + CMPB #'a,(R0) ;LOWER CASE? + BGT 12$ + CMPB #'z,(R0) + BLT 12$ + BICB #40,(R0) +12$: MOVB (R0)+,(R2)+ ;MOVE CHARS TO RESULT FIELD + SOB R1,1$ ;THERE ARE R1 OF THEM +2$: CLRB (R2)+ ;NOW PUT A ZERO AT THE END OF THE FIELD + MOV (R6)+,R1 ;THIS PUTS POINTER AT END + TST (R6)+ ;POP LENGTH + RTS PC + +.BADF: JMP CHERWE + +;ROUTINE TO COPY A EXEC STRING FROM COMMAND STRING INTO QREGISTER " AND EXBUF. +;EXPECTS R1 POINTING TO START OF STRING AND RETURNS WITH R1 POINTING AFTER. + +SETEXC: MOVB ATSW,-(SP) ;SAVE THE ATSW + JSR PC,SETLIM ;COPY STRING INTO QREG " AND ADVANCE R1 + MOVB (SP)+,ATSW ;RESTORE THE ATSW + PUSH ;NEED A REGISTER + JSR PC,QSET ;SET R0 TO START OF STRING, R1 TO LENGTH + MOV QLEN,R1 ;GET THE LENGTH OF THE STRING + CMP R1,#EXBLEN ;IS IT TOO BIG? + BHIS 3$ ;YES, ERROR + MOV #EXBUF,R2 ;POINTER TO DESTINATION FIELD + +1$: CMPB (R0),#33 ;33 MARKS THE END, ARE WE THERE? + BEQ 2$ ;YUP, STOP HERE + MOVB (R0)+,(R2)+ ;ELSE COPY NEXT BYTE + SOB R1,1$ ;KEEP AT IT + +2$: CLRB (R2)+ ;PUT A ZERO AT THE END + POP ;RESTORE POINTER TO COMMAND STRING + CCC ;SIGNAL NO ERRORS + RTS PC + +3$: POP ;CLEAN UP + SEC ;SIGNAL AN ERROR + RTS PC + + + +;TERMINAL SET ROUTINES +;SET UP FOR SITS TV +.IFNZ TVS +SETTV: JSR PC,ARG.5 ;NO ARGUMENTS PERMITTED + MOV #TV,TERMT + BR SETTER +.ENDC + +SETVT: JSR PC,ARG.5 ;NO ARGUMENTS PERMITTED + MOV #VT52,TERMT +SETTER: PUSH + MOVB #1,GRAPHM ;WE ARE IN GRAPHICS MODE + MOV TERMT,R0 + MOV #TDVEC,R1 +1$: MOV (R0)+,(R1)+ + CMP R1,#TDVECE + BNE 1$ + JSR PC,@CLRSCR ;CLEAR THE SCREEN + POP + EXIT + +SETCON: JSR PC,ARG.5 ;NO ARGUMENTS PERMITTED + PUSH R0 + TYOESC 'U ; SET PROGRAMMER MODE OR ABS MOVE WON'T WORK! + TYOESC 'f ; SET TEXT MODE (FOR INS/DEL LINE TO WORK!) + TYOESC '7 ; SET CHARACTER MODE (AS OPPOSED TO BLOCK) + TYOESC '5 ; SET UPPER-LOWER CASE MODE + TYOESC '8 ; SET FULL DUPLEX + TYOESC 'l ; RESET AUTO LINEFEED (NORMAL CR) + TYOESC 'N ; SEND SET ATTRIBUTE WORD COMMAND + .TYO 110 ; ATTRIBUTE WORD WITH ALL ZEROS, EXCEPT + ; PROTECT = 1 (NO PROTECTION) + TYOESC '$ ; RESET ALL FUNCTION KEYS + TYOESC 'o ; CHANGE MESSAGE CHARACTER + .TYO 46 ; EOM + .TYO 0 ; GETS CHANGED TO NULL + TYOESC 'X ; SET FUNCTION PAD TO XMIT + POP R0 + MOV #C100,TERMT + BR SETTER + +SETT25: JSR PC,ARG.5 ;NO ARGUMENTS PERMITTED + MOV #TT2500,TERMT + BR SETTER + +SETDAT: JSR PC,ARG.5 ;NO ARGUMENTS PERMITTED + MOV #DATAP,TERMT + BR SETTER + +;ROUTINE TO GENERATE A COMMAND TO EM THE USER'S TECO.INIT FILE FROM HIS +;LOGIN DIRECTORY. USES GLOBAL ROUTINE _GETCD TO GET HIS COMMAND DIRECTORY +;FROM THE USR_INFO FILE. + +; .GLOBL _GETCD +; .CSECT STACK +INITHD: .ASCIZ "EM" +INITTL: .ASCII "/.TECO.INIT" + .BYTE 33 + .BYTE 33 + .BYTE 0 +.EVEN +; .CSECT PGM + +GETINIT:MOV #INITHD,R0 ;GET POINTER TO HEAD STRING, DEST PTR IN R1 + MOV #50.,R2 ;LENGTH OF THE DESTINATION FIELD + JSR PC,MOVSTR ;COPY IN THE HEAD STRING + DEC R1 ;BACK UP TO THE ZERO + PUSH ;SAVE THIS LOCATION + MOV R1,-(SP) ;POINTER OF WHERE TO PUT LOGIN DIRECTORY +; JSR PC,.GETCD ;COPY IN THE THE LOGIN DIRECTORY + TST (SP)+ ;POP THE ARGUMENT + POP ;RESTORE POINTER TO START OF LOGIN DIRECTORY + TSTB (R1) ;IF ZERO, THEN NO COMMAND DIRECTORY WAS FOUND + BEQ 1$ ;ZERO, SO USE WORKING DIRECTORY + MOV #INITTL,R0 ;POINTER TO TAIL STRING + MOV #50.,R2 ;LENGTH OF THE FIELD + JSR PC,CONCAT ;CONCATENTATE TAIL STRING + CLZ ;SIGNAL NO ERROR + RTS PC + +1$: SEZ ;SIGNAL AN ERROR + RTS PC + ; .CSECT STACK + .EVEN + +MEMMSG: .ASCII " BYTES]" ;MESSAGE TO TYPE WHEN WE GET MORE MEMORY + .BYTE 12 ;FINISH WITH CRLF +MEMMEN: ;JUST MARK END OF MEMMSG + +.EVEN + +; .CSECT PGM +;ROUTINE TO INITIALIZE THE BUFFER AND ASSOCIATED VARIABLES + +; .GLOBL _END,_ETEXT,_EDATA + +BFINIT: + MOV #.ENDX,ENBF ;THE ADDRESS OF _END SHOULD BE END OF DATA + MOV ENBF,EOA ;OUR INITIAL END OF ALL + ADD #MEMINT,ENBF ;WHAT OUR INITIAL BREAK ADDRESS SHOULD BE + MOV ENBF,LIMBF ;LIMIT OF BUFFER TOO + MOV ENBF,ENBF.4 ;ALMOST END OF BUFFER MARKER + SUB #6,ENBF.4 ;IT'S 6 WORDS FROM REAL END + TST (EOA)+ ;LEAVE A ZERO AT THE BOTTOM + MOV EOA,TBUFX ;START OF QREGISTER AREA + MOV EOA,BOQ ;END OF QREGISTER AREA + TST (EOA)+ ;LEAVE A WORD TO SEPARATE QREGISTER FROM BUF + MOV EOA,BOB ;START OF BUFFER + MOV EOA,CPTR ;CURSOR + MOV EOA,CEND ;COMMAND END + MOV EOA,CMDLOC ;LOCATION OF COMMAND + MOV MEMLIM,STKLIM ;STACK SHOULD NOT GROW INTO BUFFER AREA + RTS PC + +;ROUTINE TO GET MORE MEMORY FOR BUFFER. CALL WITH CURRENT END OF MEMORY +;IN R0. RETURN AMOUNT ADDITIONAL WE GOT IN R0 + +GETMEM: ADD #MEMINC,R0 ;WE WANT THIS MUCH MORE + CMP R0,MEMLIM ;WOULD THIS PUT US PAST END + BHIS 1$ ;YES, DON'T DO IT + PUSH ;NEED SOME REGISTERS + MOV #'[,R0 ;TYPE A [ + JSR PC,TYO + POP R0 + JSR PC,DECOUT ;TYPE HOW MUCH CORE WE HAVE NOW + MOV #MEMMSG,R1 ;POINTER TO OUR MEMORY MESSAGE + MOV #MEMMEN,R2 ;END OF OUR MEMORY MESSAGE + JSR PC,TYPER ;TYPE IT + POP ;CLEAN UP + MOV #MEMINC,R0 ;WE GOT THIS MUCH MORE + RTS PC + +1$: CLR R0 ;TELL CALLER WE COULDN'T GET ANY MORE + RTS PC + ;ROUTINE TO PROCESS ANY COMMAND ARGUMENTS THAT WE WERE GIVEN. +;SEE WRITEUP IN UNIX MANUAL FOR EXEC, FOR EXPLANATION OF THIS. + +GETARG: CMP 2(SP),#1 ;WERE WE GIVEN ANY ARGUMENTS? + BEQ 1$ ;NO, JUST THE NAME "TECO" + MOV 6(SP),R0 ;THIS SHOULD BE POINTER TO ARG #1 STRING + MOV #SAVFIL,R1 ;POINTER TO RESULT FIELD + MOV #50.,R2 ;SIZE OF RESULT FIELD + JSR PC,MOVSTR ;COPY IT + +1$: RTS PC + + + +;PROGRAM BEGINS HERE. SET UP STACK AND PROCESS ARGUMENTS + +.IF NZ SITS + .BLKW 20 +TMPPDL: 0 +START: + MOV #TMPPDL,SP +.IFNZ LSI + RESET + JSR PC,LSINIT + JSR PC,MEMCHK + JSR PC,HINIT +.ENDC +.IF Z LSI + JSR PC,BRKINT + PUSH <#7*400+0,#0,#17_8.+377,#.CRWRT+1> ;CREATE + .MAP + BNE 9$ ;LOSE? + BPT +9$: +.ENDC + MOV MEMTOP,SP ;THE TOP OF MEMORY + MOV SP,STKSV + JSR PC,BFINIT + JMP TECO +.ENDC +;PROGRAM COMES HERE TO LEAVE TECO + +FINISH: JSR PC,CLRTTY + TSTB BAKFLG ;DO WE HAVE ANY TMPFIL AROUND? + BEQ 1$ ;NO, EVERYTHING'S OK + BPT +1$: MOV #3,R0 +.IFNZ LSI +2$: JSR PC,UNMOUNT + DEC R0 + BGE 2$ + MOV CURCAP,R0 + JSR PC,DELCAP + CLR CURCAP + HALT +.IFF + BPT +.ENDC + + +.ENDX=. +PASS2=1 + .END START diff --git a/src/rjl/tecoio.19 b/src/rjl/tecoio.19 new file mode 100644 index 00000000..d68a4601 --- /dev/null +++ b/src/rjl/tecoio.19 @@ -0,0 +1,835 @@ +.TITLE TECOIO +.SBTTL GLOBALS, MACROS, DEFINITIONS + +.CSECT TECOIO + +.GLOBL CLSFIL, CURFRE, DATE, DOCCL, EOFLAG, GETBUF, GETFLS +.GLOBL INPSAV, LISTEN, NI, NO, NWATCH, NOCTLO +.GLOBL P, PDL, PRINT, PUTBUF, QMAX, QRSTOR, QZ +.GLOBL RWSIZE, SCHBUF, SCHSIZ, SIZER, SWITCH, TECO, TECOPD +.GLOBL TECOSP, TEXIT, TIME, TXSTOR, TYPE, XITNOW +.GLOBL ZMAX, ZZ, .VVV.V +.GLOBL DOCCL, TECOCH +.GLOBL DSPLAY, ECHO, TYO, DERFLG, CMDFLG, TOPDIS, TTINIT +;THIS IS ALL THE NEW STUFF + +.MCALL .CLOSE, .CSISPC,.DATE, .DSTAT, .ENTER, .EXIT, .FETCH +.MCALL .LOCK, .LOOKU, .PRINT, .RCTRLO,.READ, .RELEAS,.RENAME +.MCALL .REOPEN,.SAVEST,.SETTOP,.SRESET,.TTINR, .TTYIN, .TTYOUT +.MCALL .UNLOCK,.WRITE, .WAIT + + +.MACRO ERROR R50COD,TEXT + .CSECT $TIOER +$$$=. + .RAD50 /R50COD/ + .ASCIZ TEXT + .EVEN + .CSECT TECOIO + JSR R5,ERR + .WORD $$$ +.ENDM ERROR + +.MACRO ERROR1 R50COD,TEXT + .CSECT $TIOER +$$$=. + .RAD50 /R50COD/ + .ASCIZ TEXT + .EVEN + .CSECT TECOIO + MOV #$$$,R2 + MOV (R2)+,R0 + SEC + RETURN +.ENDM ERROR1 + + .SBTTL MACROS FOR GENERATING CODE + +;MACRO TO PUSH THINGS ONTO THE STACK +.MACRO SAVE THINGS +.IRP X, + MOV X,-(SP) +.ENDM +.ENDM + +;MACRO TO POP THINGS FROM STACK +.MACRO REST THINGS +.IRP X, + MOV (SP)+,X +.ENDM +.ENDM + + +; GLOBAL ERROR CODES +NI == 54171 ;RAD 50 OF NFI +NO == 54177 ;RAD 50 OF NFO + +; RT-11 PARAMETERS +PGMTOP == 50 ;POINTER TO TOP OF LOADED PROGRAM +RMON == 54 ;POINTER TO START OF RMON +USRBUF == 266 ;OFFSET INTO RMON OF USR START +STACK == 42 ;START OF USER STACK +USTART == 40 ;START ADDRESS OF PROGRAM +JSW == 44 ;JOB STATUS WORD +TTYUSR == 10000 ;TELETYPE I/O IN USER MODE +REENTR == 20000 ;PROGRAM IS REENTERABLE + +; TECO SIZE PARAMETERS +SCHSIZ == 100 ;SIZE OF SEARCH BUFFER +SIZEPD == 100 ;PUSH DOWN SIZE + +; VARIOUS ASCII CHARACTERS +BELL = 7 +TAB = 11 +LF = 12 +FF = 14 +CR = 15 +RIGHT = 30 ;USED BY DISPLAY +LEFT = 31 ;GUESS WHAT? +UP = 32 ;UP 1 LINE (USED BY DISPLAY) +ALTMOD = 33 +BOT = 34 ;BOTTOM OF SCREEN +TOP = 35 ;TOP OF SCREEN +ERLINE = 36 ;ERASE LINE +ERSCRN = 37 ;ERASE SCREEN +SPACE = 40 +RUBOUT = 177 + .SBTTL CORE ORGANIZATION + +;THE CORE OBTAINED BY TECOIO AND GIVEN TO TECO IS +; ORGANIZED AS FOLLOWS: +; +; ********************************* +; * * +; * READ/WRITE AREA * +; * SIZE = RWSIZE * +; * * +; * CLEARED BY TECOIO * +; * * +; ********************************* +; * * +; * PUSH DOWN LIST * +; * POINTED TO BY TECOPD * +; * SIZE = SIZEPD (GLOBAL) * +; * * +; ********************************* +; * * +; * SEARCH BUFFER * +; * POINTED TO BY SCHBUF * +; * SIZE = SCHSIZ (GLOBAL) * +; * * +; ********************************* +; * * +; * TEXT STORAGE AREA * +; * POINTED TO BY TXSTOR * +; * SIZE IN ZMAX(RW AREA) * +; * * +; ********************************* +; * * +; * Q-REGISTER STORAGE * +; * POINTED TO BY QRSTOR * +; * SIZE IN QMAX(RW AREA) * +; * * +; ********************************* +; * * +; * FREE STORAGE * +; * SIZE IN CURFRE * +; * NO POINTER * +; * * +; ********************************* +; +; ALL POINTERS IN TECOIO ARE RELATIVE TO THE BEGINNING OF +; THE IMPURE AREA, WHICH IS POINTED TO BY FREEST IN TECOIO. +; THE TEXT STORAGE AREA AND Q-REGISTER STORAGE AREAS +; ALSO HAVE AN ASSOCIATED WORD IN THE R/W AREA TELLING HOW +; MUCH OF THE ALLOCATED STORAGE IS IN USE. +; THE POINTERS ARE ARRANGED AS: +; TXSTOR, ZZ, ZMAX +; AND QRSTOR, QZ, QMAX + + +.SBTTL SAVE, RESTORE, ERROR + +.ENABL LSB + +SAVREG: MOV E,-(SP) + MOV D,-(SP) + MOV C,-(SP) + MOV B,-(SP) + MOV SP,SPSAVE ;SAVE FOR ERROR RETURN + MOV A,-(SP) + MOV F,-(SP) ;RETURN ADDRESS + MOV 6*2(SP),F + CLR LOCKFL ;SAY USR NOT LOCKED IN YET + JSR PC, @(SP)+ ;EXCHANGE HIM FOR US + + INC LOCKFL ;WAS USR LOCKED IN? + BNE 1$ ;NO IF NON-0 + .UNLOCK ;FREE USR IF LOCKED IN +1$: CLC ;SAY NORMAL RETURN + MOV (SP)+,A +2$: MOV (SP)+,B + MOV (SP)+,C + MOV (SP)+,D + MOV (SP)+,E + MOV (SP)+,F + RTS PC + +ERR: INC LOCKFL ;WAS USR LOCKED IN? + BNE 3$ ;NO IF NON-0 + .UNLOCK ;ERRORS FREE USR, TOO +3$: SEC ;TELL TECO THINGS ARE NO GOOD + MOV (R5)+,B ;POINT TO RAD50 CODE + MOV (B)+,A ;GET CODE IN R0, POINTER IN B + MOV SPSAVE,SP ;RESTORE STACK + MOV B,2(SP) ;POINTER IS RETURNED IN R2 + BR 2$ ;AND EXIT + +.DSABL LSB + + ;LISTEN FOR CHARACTER, RETURNED IN D +LISTEN: BIS #TTYUSR,@#JSW ;THIS WILL GO AWAY IN SITS + JSR PC,TIOQ ;GET THE CHARACTER + BEQ .-4 ;NOT THERE YET + MOV D,A ;MAKE THINGS COMPATIBLE + JMP ECHO + + +;DISPLAY PARAMETERS +TOPMAR=7 ;# OF LINES CURSOR IS (INITIALLY) FROM TOP OF SCREEN +BOTMAR=3 ;# OF LINES -1 FROM BOTTOM OF SCREEN FOR COMMAND INPUT +VSPACE=20 ;AMOUNT OF LINES ALLOWED ON SCREEN +HSPACE==70 ;HORIZONTAL SCREEN SPACE +DISPTR: 0 ;DISPLAY POINTER (STARTING LINE OF CURRENT DISPLAY) +CMDPTR: .WORD 0,0 ;POINTER TO COMMAND INPUT +CURPTR: .WORD 0,0 ;POINTER TO CURSOR +CMDFLG: 0 ;IF 0 => NO INITIALIZATION OF COMMAND DISPLAY NEEDED +DERFLG: 0 ;SET WHEN AN ERROR HAS BEEN PRINTED TO PROTECT TOP LINE OF SCREEN +MSG1: .ASCII /TECO/ +MSG2: .ASCII /--MORE--/ +MSG3: .ASCII /FLUSHED/ +MSG4: .ASCII /SITS CONSOLE FREE/ + + +;CONTROLLER FOR DISPLAY SCREEN +DSPLAY: JSR PC,ACSAV ;SAVE REGISTERS + MOV TOPMAR,C ;PTR IS THIS MANY LINES FROM TOP OF SCREEN + MOV P(F),B ;CURRENT TEXT POINTER (WILL CHANGE) + MOV B,E ;COPY IT + ADD TXSTOR(F),B ;MAKE POINTER ABSOLUTE + MOV B,F ;AND SAVE IT + MOV ZZ(F),D ;LENGTH OF BUFFER CURRENTLY IN USE + ADD TXSTOR(F),D ;MAKE AN ABSOLUTE POINTER TO END + SAVE D ;KEEP IT ON TOP OF THE STACK + TST E ;IS POINTER AT TOP OF PAGE? + BEQ DSPLA5 ;PTR IS AT TOP OF PAGE +DSPLA1: CMPB -(B),LF ;START COUNT BACK # OF LINEFEEDS FROM CURSOR + BEQ DSPLA2 ;FOUND ONE + CMP B,F ;BACK TO THE START YET? + BNE DSPLA1 ;NOT YET + MOV DISPTR,B ;YES, MARK THIS POINT AS START OF DISPLAY + BR DSPLA5 ;AND GO DISPLAY +DSPLA2: SOB C,DSPLA1 ;ONE LESS LINE + TST (B)+ ;CORRECT PTR, NOW WE'RE AT THE RIGHT PLACE +DSPLA5: MOV #35,D ;THIS PUTS US AT THE TOP OF THE PAGE + JSR PC,TYO ;PRINT IT + MOV VSPACE,C ;# OF LINES ALLOWED ON THE SCREEN + TEST DERFLG ;WAS THERE AN ERROR PRINTED LAST TIME? + BEQ DSPLA3 ;NO, NORMAL DISPLAY + MOV #LF,D ;YES, SAVE TOP LINE OF DISPLAY + JSR PC,TYO ;START ONE LINE FROM TOP + CLR DERFLG ;NEXT DISPLAY IS NORMAL +DSPLA3: CMP B,F ;HAVE WE REACHED THE CURSOR? + BNE DSPLA4 ;NOPE + MOV '/,D ;YES, DISPLAY IT + JSR PC,TYO + MOV '\,D + JSR PC,TYO +DSPLA4: MOV (B)+,D ;GET NEXT CHARACTER TO PRINT + JSR PC,TYO ;OUTPUT THE CHARACTER + CMP B,SP ;ARE WE AT END OF TEXT? + BEQ DSPRET ;THEN DONE FOR NOW + CMP D,LF ;WAS IT A LINEFEED? + BNE DSPLA3 ;NOPE, GO AHEAD + SOB C,DSPLA3 ;YES, THAT MEANS ONE LESS LINE OF SPACE + MOV #8,E ;# OF ARGS FOR PRINT + MOV #MSG2,D ;REACHED THE END OF THE SCREEN, PRINT OUT "--MORE--" + JSR PC,PRINT + JSR PC,LISTEN ;WAIT FOR REPLY + CMP D,SPACE ;DOES HE WANT MORE? + BEQ DSPLA5 ;YES, GIVE HIM WHAT HE WANTS +DSPLA6: MOV #7,E ;ARGS FOR PRINT + MOV #MSG3,D ;PRINT OUT "FLUSHED" + JSR PC,PRINT +;HERE, SET UP FOR COMMAND MODE (PROBABLY SHOULD SET FLAG) +;OR, WE COULD JUST FALL RIGHT IN +DSPCM4: MOV #BOT,D ;GET TO BOTTOM OF SCREEN + JSR PC,TYO + MOV CMDPTR,B ;GET POSITION WHERE WE LEFT OFF + MOV (B)+,C ;THIS MANY LINES FROM BOTTOM + BEQ DSPCM1 ;WE'RE ALREADY THERE + MOV #UP,D ;MOVE US UP + JSR PC,DSPCM3 ;THIS PRINTS THE CHARACTER C TIMES +DSPCM1: MOV (B),C ;THIS MANY CHARACTERS FROM EDGE OF SCREEN + BEQ DSPCM2 ;THERE AGAIN + MOV #RIGHT,D ;PUT US THERE + JSR PC,DSPCM3 +;DO ANY NECSSARY THINGS BEFORE LEAVING +DSPCM2: TST (SP)+ ;GET RID OF CRUD ON TOP OF STACK + JSR PC,ACRES + RTS PC +DSPCM3: JSR PC,TYO + SOB C,DSPCM3 + RTS PC +DSPCMD: JSR PC,ACSAV ;THIS IS CALLED FROM MAIN TECO LOOP + BR DSPCM4 +DSPRET: MOV #-1, CMDFLG ;DONE WITH DISPLAY, THIS CAUSES COMMAND ECHO TO INIT ITSELF + BR DSPCM2 + + +;THIS ROUTINE ECHOES COMMAND INPUT ON SCREEN. +;IT IS ESSENTIALLY A SOPHISTICATED TYO +ECHO: MOV A,D ;HAVE TO BE COMPATIBLE + MOV CMDPTR,B ;KEEP TRACK OF WHERE WE ARE + TST CMDFLG ;SHOULD WE INITIALIZE FIRST? + BEQ ECHO3 ;NOPE,ALREADY DONE + JSR PC,DSPCMD ;YES, THIS DOES THE WORK + CLR CMDFLG ;WON'T HAVE TO BE DONE AGAIN +ECHO3: JSR PC,TYO + CMP D,#LF ;WAS THAT A LINEFEED? + BEQ ECHO1 ;YES + MOV CHARNO,2(B) ;SET POSITION FOM EDGE OF SCREEN + RTS PC +ECHO1: DEC (B) ;ONE LINE CLOSER TO BOTTOM OF SCREEN + BGE ECHO2 ;WE'RE STILL ON IT + MOV #BOTMAR,C ;WE FELL OFF THE BOTTOM + MOV #UP,D ;GET BACK TO THE TOP + JSR PC,DSPCM3 +ECHO2: CLR 2(B) ;STARTING AT EDGE AGAIN + MOV #ERLINE,D ;CLEAR OUT OLD STUFF + JSR PC,TYO + MOV D,A ;ONCE AGAIN + RTS PC ;DONE, GO GET NEXT CHARACTER + +TOPDIS: MOV #TOP,D ;GET TO TOP OF SCREEN + JSR PC,TYO + TST DERFLG ;DO WE HAVE A PENDING ERROR? + BNE .+4 ;YES, INDEED +1$: RTS PC ;ALL DONE + MOV #ERLINE,D ;MAKE ROOM FOR IT + JSR PC,TYO + BR 1$ + +TTINIT: BIC #TILIPM!TIMAGO!TIMAGI!TOTRAN,TTYST + BIS #TICVM!TIECM,TTYST + RTS PC + .SBTTL PRINT STRING, TEXIT, NOCTLO, TIME, DATE, SWITCH +;EXPECTS POINTER TO STRING IN D, LENGTH OF STRING IN E + +PRINT: TST D ;IS THERE A STRING THERE? + BEQ 3$ ;NOPE, THAT WAS EASY +1$: MOVB (D)+,D + JSR PC,TYO ;OUTPUT THE CHARACTER + SOB E,1$ ;THIS MANY CHARACTERS +3$: RTS PC + + +TEXIT: ;EXIT FROM TECO + MOV #TOP,D + JSR PC,TYO + MOV #ERSCRN,D ;ERASE SCREEN + JSR PC,TYO ;CLEAR THE SCREEN + MOV #MSG4,D ;FAREWELL MESSAGE + MOV #17,E ;THIS LONG + JSR PC, PRINT ;PRINT IT + MOV SP,A ;SOFT EXIT + .EXIT + +XITNOW: BIC #TTYUSR,@#JSW ;TURN OFF SPECIAL MODE BIT +NOCTLO: .RCTRLO + RTS PC + +DATE: .DATE + RTS PC + +TIME: CLR A ;SORRY, WE HAVE NO TIME + RTS PC + +SWITCH: MOV @#177570,A + RTS PC + + .SBTTL SIZER SWAPS THE USR TO GET MORE CORE + +SIZER: MOV A,-(SP) ;SAVE A FOR TECO + MOV @#RMON,A ;POINT TO THE RESIDENT + TST -(A) ;FIX FOR FUNNY SETTOP + SUB @#PGMTOP,A ;SUBTRACT OFF OUR CURRENT TOP + CMP A,B ;CAN WE GET HIM WHAT HE WANTS? + BLO 1$ ;HE LOSES + ADD A,CURFRE(F) ;YES. GIVE HIM WHAT WE CAN + ADD @#PGMTOP,A ;FIX FOR A SETTOP + .SETTOP ;TELL THE MONITOR WE'RE SWAPPING + .RCTRLO ;TELL THE USER + .PRINT #MESSAG + CLC ;AND BE SUCCESSFUL +1$: MOV (SP)+,A ;RESTORE A + RTS PC + .SBTTL GETFLS - ENTRY FOR ER, EW, AND EB + +FNEB: JMP FNERR ;OUT OF BRANCH RANGE +GETFLS: JSR F,SAVREG ;CAREFUL WITH THESE + MOV E,C ;MOVE LENGTH TO WHERE WE WANT IT + MOV #FILSPC,D ;COPY FILE SPEC BEFORE LOCKING USR + CMP C,#23 ;IS THE STRING TOO LONG? + BHI FNEB ; YES, BOOT HIM +1$: MOVB (A)+,(D)+ ;MOVE A BYTE + DEC C ;COUNT DOWN + BGT 1$ ; TO 0 (-1 IF ORIGINALLY 0) + MOVB #'<,(D)+ ;PUT IN TERMINATOR + CLRB (D)+ ;AND END IT + .LOCK ;KEEP THE USR HANDY + DEC LOCKFL ;AND FORCE US TO UNLOCK HIM LATER + TST B ;WHAT ARE WE DOING? + BEQ EREAD + BPL EWRITE + +; EDIT BACKUP: +; CLOSE ANY EXISTING OUTPUT FILE (AND FIX EB) +; DO AN EDIT READ +; FUDGE THE NAME, AND FALL THROUGH TO AN EDIT WRITE + + CALL FLUSH ;CLOSE OUTPUT FILE, IF ANY + CALL EREAD ;START AN INPUT FILE + MOV #INBLK+12,A ;PREPARE TO COPY OUTPUT NAME + MOV #OUTBLK+12,F ; AND SET UP POINTER, TOO + MOV -(A),-(F) + MOV -(A),-(F) + MOV -(A),-(F) + MOV -(A),-(F) + MOV -(A),-(F) + MOV SP,EBFLG ;MARK EB IN PROGRESS + BR EWRIT1 ;AND ENTER THE OUTPUT FILE + .SBTTL EDIT WRITE + +; EDIT WRITE: +; IF AN OUTPUT FILE IS OPEN, CLOSE IT (AND FIX EB) +; SCAN THE FILE NAME +; CLEAR THE OUTPUT BUFFERS + +EWRITE: TST EBFLG ;WE CAN'T DO THIS IF EB-ING + BNE EBERR ;SO CLOBBER HIM + CALL FLUSH ;YES, CLOSE IT + ;NOTE THAT FLUSH SETS F TO OUTBLK + CALL FNGET ;GET THE FILE NAME SCANNED, HANDLERS +EWRIT1: .ENTER 13,F,FILENG ;ENTER THE FILE + BCS DEVFUL ;AN ERROR IS DEVICE FULL + MOV #OUTFNM,B ;POINT TO AREA FOR SAVED NAME + MOV #FILSPC,A ;POINT TO INPUT NAME +1$: MOVB (A)+,E ;GET A BYTE + MOVB E,(B)+ ;SAVE IT + CMPB #'0,E ;CHECK FOR ALPHA, NUMBER, OR : + BHI 2$ + CMPB #':,E + BHIS 1$ + CMPB #'A,E + BHI 2$ + CMPB #'Z,E + BHIS 1$ +2$: CLRB -(B) + MOV #OBUF1+512.,-(F) ;POINT TO FIRST BUFFER TOP + MOV #OBUF1,-(F) ;POINT TO DATA START + CLR -(F) ;START WITH BLOCK 0 + RETURN ;RETURN (WHAT A COMMENT!) +DEVFUL: ERROR FUL,<"DEVICE FULL"> +EBERR: ERROR EBK,<"EDIT BACKUP STILL OPEN"> + .SBTTL EDIT READ, READ NEXT BLOCK + +; EDIT READ: +; FIX UP ANY EB FILES +; RELEASE INPUT HANDLER +; SCAN FILE NAME, GET HANDLER +; LOOKUP FILE, PRIME ONE BLOCK, BEGIN READ OF NEXT + +EREAD: MOV #IBUF1+512.,E ;WE WILL BE NEEDING PTR TO BUFFER TOP + TST C ;IS FILE NAME NULL? + BGE 1$ ;NO, DO AN EDIT READ + MOV #SSINFO,D ;YES, DO A REOPEN + TST @D ;IS THERE A SAVED FILE? + BEQ NOFSAV ;NO, ERROR + MOV #INBLK,F ;POINT TO INPUT BLOCK + .CLOSE 12 ;GET RID OF OLD INPUT FILE + CALL RELEAS ;GET RID OF OLD HANDLER + MOV (D)+,@F ;PUT BACK DEVICE NAME + CALL FETCH ;MAKE SURE HANDLER IS IN + MOV E,-(F) ;SET TOP-OF-BUFFER + MOV (D)+,-(F) ;SET BUFFER OFFSET + ADD E,@F ;MAKE ABSOLUTE BUFFER POINTER + MOV (D)+,-(F) ;RESTORE BLOCK NUMBER + MOV (D)+,-(F) ; AND EOF FLAGS + .REOPEN 12,D ;REOPEN THE FILE + BR 2$ ;AND REPRIME BUFFERS + +1$: MOV #IBTOP,F ;POINT TO FLAG WORD + CLR (F)+ ;AND SAY WE HAVE NO INPUT + .CLOSE 12 ; AND CLOSE US IF HE DIDN'T + CALL RELEAS ;DUMP THE HANDLER + CALL FNGET ;SCAN THE NAME + .LOOKUP 12,F ;AND FIND THE FILE + BCS EINOFL ;IT WEREN'T THERE + MOV #IBUF1+512.,E ;POINT TO THE FIRST BUFFER TOP + MOV E,-(F) ;SAVE IT AS BUFFER PTR + MOV @E,-(F) ;SAVE BUFFER PTR + CLR -(F) ;START AT BLOCK #0 + MOV #-1,-(F) ;NO EOF YET! +2$: MOV FREEST,A ;SET TECO'S EOF FLAG + CLR EOFLAG(A) ; IN HIS AREA + CALL BREAD ;GET A BLOCK IN CORE +; ;BREAD RETURNS POINTER TO OTHER TOP +; CALL BREAD ;FALL INTO READ ROUTINE + +;BUFFER READ: READS NEXT BLOCK INTO DESIGNATED AREA + +BREAD: TST EFFLG ;ARE WE SWITCHED TO EOF BUFFER? + BGT 1$ ;YES, BOOT HIM + .WAIT 12 + BCS 1$ ;DID WE GET AN ERROR? +; ;@E IS BOTTOM PTR, 2(E) IS NEXT TOP + .READ 12,(E)+,#400,IBLKNM ;READ A LOAD + MOV @E,E ;RETURN POINTER TO NEXT TOP + INC IBLKNM ;BUMP BLOCK NUMBER + BCC 1$ ;CARRY IS INPUT ERROR OR EOF + TSTB @#52 ;WHAT KIND OF ERROR? + BNE INERR ;HARDWARE + INC EFFLG ;EOF, SOFT ERROR +1$: RETURN +EINOFL: ERROR FNF,<'FILE "'<-2>'" NOT FOUND'> +INERR: ERROR INP,<"INPUT ERROR"> +NOFSAV: ERROR NFS,<"NO FILE SAVED"> + .SBTTL CLOSE FILE, FLUSH OUTPUT BUFFER + +;END FILE +; DO ANY EB CLOSING NEEDED +; RELEASE HANDLER FOR OUTPUT, CLEAR FLAG + +CLSFIL: TST OBTOP ;IS AN OUTPUT FILE OPEN? + BEQ NOOFIL ;ERROR IF NOT + JSR F,SAVREG + .LOCK ;HOLD TIGHT TO USR + DEC LOCKFL ;BUT TELL US WHEN TO GIVE HIM UP +; BR FLUSH ;FLUSH BUFFER, CLOSE FILE + +;FLUSH: +; IF OUTPUT BUFFER HAS DATA IN IT, IT IS PADDED WITH ZEROS +; AND WRITTEN OUT +; WAIT FOR IO TO QUIESCE +; CLOSE FILE, DO EB RENAME IF NEEDED + +FLUSH: MOV #OBPTR,F ;POINT TO BUFFER POINTERS + MOV (F)+,E ;E -> NEXT BYTE IN BUFFER + MOV (F)+,A ;A -> TOP OF BUFFER + BEQ ERTN ;RETURN IF NO FILE OPEN + CMP E,@A ;IF THE BUFFER IS EMPTY + BEQ 3$ ; DO NOT WRITE IT + BR 2$ ;ENTER FILL LOOP +1$: CLRB (E)+ +2$: CMP E,A ;FULL TO TOP? + BNE 1$ + CALL BWRITE ;WRITE IT OUT +3$: .WAIT 13 ;QUIET DOWN + BCS OUTERR + TST EBFLG ;WERE WE IN EB? + BEQ OUTCLS ; IF NOT, JUST CLOSE OUTPUT + + .CLOSE 12 ;CLOSE INPUT FILE + MOV #OUTBLK+16,B ;POINT TO NEWNAME AREA + MOV #OUTBLK+6,A ;POINT TO OLD INPUT NAME + MOV (PC)+,@B ;SET NEW EXTENSION TO BAK + .RAD50 /BAK/ + MOV -(A),-(B) ;PUT IN REST OF NEW NAME + MOV -(A),-(B) + MOV -(A),-(B) + .RENAME 14 + CLR IBTOP ;SWITCH OFF INPUT FILE + CLR EBFLG ;NO LONGER IN EB +OUTCLS: .CLOSE 13 ;CLOSE THE OUTPUT FILE + CLR OBTOP ;SWITCH OFF OUTPUT FILE +; BR RELEAS ;DUMP HANDLER AND RETURN + .SBTTL RELEASE DEVICE HANDLER + +;RELEASE RELEASES A HANDLER FROM ITS AREA +;NOTHING IS DONE IF BOTH INPUT + OUTPUT NEED IT + +RELEAS: MOV #SCRACH,B ;SOME WORKING AREA + .DSTATU B,#INBLK ;GET STATUS OF INPUT DEVICE + MOV @B,-(SP) ;HOLD IT + CLR @B + .DSTATU B,#OUTBLK ;AND OF OUTPUT DEVICE + CMP @B,(SP)+ ;SAME? + BEQ ERTN + CMP @F,HAND1 ;DOES AREA 1 HAVE THE HANDLER? + BNE 1$ ;NO, TRY AGAIN + CLR HAND1 ;MARK IT NON-RESIDENT + BR 2$ ;AND GO TO FREE IT +1$: CMP @F,HAND2 ;DOES AREA 2 HAVE IT? + BNE ERTN ;NO, IT WAS RESIDENT + CLR HAND2 +2$: .RELEAS F ;PURGE IT +ERTN: RETURN + +OUTERR: ERROR OUT,<"OUTPUT ERROR"> + .SBTTL BWRITE - WRITE BLOCK TO OUTPUT FILE + +BWRITE: .WAIT 13 ;WAIT FOR PREVIOUS OP TO FINISH + BCS OUTERR ;MAKE SURE IT WAS GOOD + .WRITE 13,(E)+,#400,OBLKNM + MOV @E,E ;SET POINTER TO NEXT TOP + BCS OUTERR ;IF CARRY, ERROR + INC OBLKNM ;ELSE ADVANCE OUTPUT BLOCK NUMBER + RETURN + .SBTTL FNGET AND FETCH - CALL CSI, FETCH HANDLER + +;FNGET SCANS OFF THE FILE NAME INTO THE BUFFER AREA +;ASSOCIATED WITH THE BLOCK IN F. +;IT THEN CALLS THE CSI, AND FETCHES A HANDLER + +FNGET: TST C ;WAS NAME NULL? + BMI FNERR ;YES, THAT'S A NO-NO + .CSISPC F,#DEFEXT,#FILSPC + BCS FNERR ;ERROR IN NAME + TST (SP)+ ;NO SWITCHES ARE VALID! + BNE FNERR + +FETCH: MOV #HAND1,B ;POINT TO FIRST HANDLER AREA + TST (B)+ ;IS IT FREE? + BEQ 1$ + MOV #HAND2+2,B ;IF NOT, USE OTHER AREA +1$: .FETCH B,F ;GET THE HANDLER + BCS DEVERR ;SOME KIND OF ERROR + CMP A,B ;WAS IT ALREADY HERE? + BEQ 2$ ;IF SO, AREA IS STILL FREE + MOV @F,-(B) ;SAVE NAME OF DEVICE +2$: RTS PC +FNERR: ERROR IFN,<'FILE NAME "'<-2>'" INVALID'> +DEVERR: ERROR DEV,<'INVALID DEVICE "'<-2>'"'> +NOOFIL: ERROB NFO,<"NO OUTPUT FILE"> + .SBTTL INPSAV - SAVE INPUT FILE STATUS + +INPSAV: TST IBTOP ;IS THERE A FILE OPEN? + BEQ NOIFIL ;NO, GIVE AN ERROR + JSR F,SAVREG ;SAVE REGISTERS + MOV #SSBLOK,D ;POINT TO SAVED STATUS + .SAVES 12,D ;AND SAVE IT + MOV #EFFLG,F ;POINT TO OTHER STUFF TO SAVE + MOV (F)+,-(D) ;EOF FLAGS + MOV (F)+,-(D) ;BLOCK NUMBER + SUB #2,@D ;(WHICH WAS 2 TOO HIGH) + MOV (F)+,-(D) ;BUFFER POINTER + SUB @F,@D ;WHICH WE MAKE INTO BUFFER OFFSET + CLR (F)+ ;AND MARK INPUT FILE NOT THERE + MOV @F,-(D) ;FINALLY, DEVICE NAME + BR RELEAS ;NOW, GO GET RID OF HANDLER + .SBTTL GETBUF - READ A TECO BUFFER LOAD + +;GETBUF: +; READS BUFFER LOAD, AS PER TECO'S DESIRES + +GETBUF: TST IBTOP ;IS A FILE OPEN? + BEQ NOIFIL ;NO, RETURN AN ERROR + TST EOFLAG(F) ;ARE WE AT END-OF-FILE? + BNE 51$ ;YES, SAY SO + TST EFFLG ;ARE WE ABOUT TO BE AT EOF? + BGT 50$ ;YES, RETURN INDICATION + JSR F,SAVREG ;SAVE EVERYTHING + MOV A,C ;HOLD ON TO DESTINATION POINTER + CLR 6(SP) ;CLEAR RETURNED C FORM FEED FLAG + TST B ;DID THE FOOL WANT US TO READ 0? + BEQ 4$ ; WELL, THAT'S EASY + MOV A,-(SP) ;SAVE START FOR LENGTH COMPUTE + MOV #IBPTR,D ;GET POINTERS + MOV (D)+,F ;F -> BUFFER + MOV @D,E ;E -> TOP +1$: CMP E,F ;IS THE BUFFER EMPTY + BLOS 10$ ; IF SO, GO FILL IT + MOVB (F)+,A ;GET THE BYTE + BIC #177600,A ;MAKE IT GOOD ASCII + BEQ 1$ ;IGNORE NULLS + CMPB A,#RUBOUT ; AND RUBOUTS + BEQ 1$ + CMPB A,#FF ;IF FORM FEED + BEQ 30$ ; GO SET FLAG AND EXIT + MOVB A,(C)+ ;PUT BYTE, ADVANCE POINTER + DEC B ;IS THERE ANY ROOM LEFT + BEQ 3$ ;IF NOT, WE OUGHT TO LEAVE NOW + CMP B,#128. ;IF FEWER THAN 128 BYTES LEFT + BHIS 1$ ; KEEP GOING + CMP A,#LF ;ELSE STOP AT LINE FEED + BNE 1$ ; IF WE GOT ONE +3$: MOV E,@D ;SAVE NEW BUFFER TOP + MOV F,-(D) ; AND BUFFER POINTER + SUB (SP)+,C ;COMPUTE NUMBER OF CHARACTERS READ + MOV C,4(SP) ;RETURN IT IN B + BNE 4$ ;NO EOF IF WE GOT STUFF + TST EFFLG ;NULL PAGE: IS IT THE END? + BLE 4$ ; NO, JUST A NULL PAGE + MOV FREEST,F ;POINT TO RW AREA +50$: COM EOFLAG(F) ;TURN ON EOF INDICATION +51$: CLR B ;SET NO CHARACTERS + CLR C ;SET NO FORM FEED +4$: RETURN + +30$: COM 10(SP) ;SET FORM FEED FLAG (C) + BR 3$ ;EXIT (NOTE FF IS NOT IN BUFFER) + +10$: CALL BREAD ;GET BUFFER LOAD (NOTE E->TOP) +; ;E NOW -> TOP OF OTHER BUFFER + MOV @E,F ;POINT TO BOTTOM OF THAT BUFFER + TST EFFLG ;DID WE SWITCH TO EOF? + BLE 1$ ;NOPE + MOV F,E ;YEP, SET TO GIVE EOF NEXT TIME + BR 3$ ;AND GET OUT NOW +NOIFIL: ERROB NFI,<"NO INPUT FILE"> + .SBTTL PUTBUF - OUTPUT A TECO BUFFER LOAD + +;PUTBUF: +; OUTPUTS A BUFFER THE WAY TECO WANTS TO + +PUTBUF: TST OBTOP ;IS AN OUTPUT FILE OPEN? + BEQ NOOFIL ;ERROR IF NAE + JSR F,SAVREG ;SAVE REGS + ADD A,B ;POINT TO END OF TEXT STRING + TST C ;FF REQUIRED? + BMI 1$ ;GO IF YES + MOVB -(B),-(SP) ;SAVE LAST CHAR IN TEXT + BR 2$ +1$: MOVB @B,-(SP) ;SAVE CHAR AFTER LAST + MOVB #FF,@B ;AND REPLACE IT WITH FF +2$: MOV #OBPTR,D + MOV (D)+,F ;GET PTR INTO OUTPUT BUFFER + MOV @D,E ; AND BUFFER TOP + MOV A,C ;COPY TEXT POINTER +3$: CMP C,B ;END OF TEXT (B -> LAST)? + BHI 4$ ;YES, GO RESTORE LAST CHAR + MOVB (C)+,(F)+ ;GET NEXT BYTE + CMP F,E ;END OF BUFFER? + BLO 3$ ;NO, KEEP GOING + CALL BWRITE ;YES, PUT OUT THIS LOAD + MOV @E,F ;;E POINTS TO NEW TOP, F TO NEW BOTTOM + BR 3$ ;GO FOR MORE +4$: MOVB (SP)+,@B ;RESTORE LAST CHAR + MOV E,@D ;SAVE TOP + MOV F,-(D) ;BOTTOM +6$: RETURNîî .SBTTL DATA AREA + +; DATA AREA + +FREEST = .+2 ;TOP OF PROGRAM AFTER LINK + .LIMITS +LOCKFL: .WORD 0 ;FLAG FOR USR LOCKED IN +SPSAVE: .WORD 0 ;SP FOR ERROR RETURN +SCRACH: .BLKW 4 +DEFEXT: .WORD 0,0,0,0 +SSINFO: .WORD 0,0,0,0 ;DEV NAME, BUFFER OFFSET, BLOCK #, EOF +SSBLOK: .BLKW 5 ;SAVESTATUS STUFF +OUTFNM: .BLKB 12. ;SAVED OUTPUT FILE NAME IN ASCIZ + +; INPUT + +EBFLG: .WORD 0 +EFFLG: .WORD -1 +IBLKNM: .WORD 0 +IBPTR: .WORD 0 +IBTOP: .WORD 0 +INBLK: .BLKW 5 +IBUF1: .BLKW 256. + .WORD IBUF1 ;LINK TO THIS BUFFER START + .WORD IBUF2+512. ;LINK TO OTHER BUFFER TOP + +IBUF2: .BLKW 256. + .WORD IBUF2 ;LINK TO THIS BUFFER START + .WORD IBUF1+512. ;LINK TO OTHER BUFFER TOP + +; OUTPUT + +OBLKNM: .WORD 0 +OBPTR: .WORD 0 +OBTOP: .WORD 0 +OUTBLK: .BLKW 4 +FILENG: .WORD 0 +OBUF1: .BLKW 256. + .WORD OBUF1 ;LINK TO THIS BUFFER START + .WORD OBUF2+512. ;LINK TO NEXT BUFFER TOP + +OBUF2: .BLKW 256. + .WORD OBUF2 ;LINK TO THIS BUFFER START + .WORD OBUF1+512. ;LINK TO NEXT BUFFER TOP + + +; HANDLERS + +HAND1: .BLKW 130. +HAND2: .BLKW 130. + +.IF DF GT40 +DISBUF: .BLKB 2000. + +.ENDC +.NLIST BEX +MESSAG: .ASCIZ /[+2K CORE]/ +FILSPC: .BLKB 25 +.EVEN +.LIST BEX + .SBTTL START AND REENTER CODE + + BR GOTECO ;ON REENTRY, REENTER +START: .SRESET + MOV @#RMON,B ;POINT TO RMON + MOV USRBUF(B),B ;LEAVE USR RESIDENT + MOV FREEST,F ;WERE WE HERE BEFORE (SETTOP!) + MOV B,A + TST -(A) + .SETTOP + MOV F,C + MOV #RWSIZE,D ;GET SIZE OF R/W AREA + ASR D ;MAKE IT WORDS +SYMBOL: CLR (C)+ + DEC D + BNE SYMBOL + MOV C,TECOPD(F) ;START OF PUSH DOWN LIST + MOV C,PDL(F) ;AND AGAIN + ADD #SIZEPD,C ;SKIP OVER PD SPACE + MOV C,SCHBUF(F) ;START OF SEARCH BUFFER + MOVB #-1,@C ;SET UP A NULL SEARCH BUFFER + ADD #SCHSIZ,C ;SKIP OVER SEARCH BUFFER + MOV SP,TECOSP(F) ;START HIS STACK + MOV C,TXSTOR(F) ;START OF TEXT AREA + SUB C,B ;SIZE OF TEXT AND QREG AREAS + CLC + ROR B ;HALVSIES + MOV B,ZMAX(F) + MOV B,QMAX(F) + ADD B,C + MOV R2,QRSTOR(F) + CLR CURFRE(F) ;WE'VE GIVEN HIM ALL FOR NOW +GOTECO: MOV FREEST,F ;IN CASE OF REENTRY + CLR HAND1 ;NO HANDLERS ARE HERE + CLR HAND2 + CLR OBTOP ;NO FILE OPEN + CLR IBTOP + CLR EBFLG ;NO EB IN PROGRESS + BIS #TTYUSR+REENTR,@#JSW ;TURN ON OUR OWN I/O + MOV #1,B ;CHECK FOR CCL + BIT B,@#JSW ;CCL? + BEQ 1$ + BIC B,@#JSW + MOV #400,A + MOV A,E +2$: TSTB (E)+ ;COUNT IT + BNE 2$ + DEC E + SUB A,E ;LEAVE COUNT IN E + COM B + JSR PC,DOCCL ;DO THE EB + MOV #TECOCH,E + JSR PC,@'Y*2(E) ;DO THE YANK +1$: JMP TECO +  \ No newline at end of file