! FILE 'BTT7S' !************** !* BTT7S * !*DA:24.FEB.81* !************** %CONTROL K'100001'; ! 'SYSTEM' PROGRAM (FAST ROUTINE ENTRY/EXIT) %PERMROUTINESPEC SVC(%INTEGER EP, P1, P2) %BEGIN %SYSTEMINTEGERFNSPEC MAP VIRT(%INTEGER ID, FROM SEG, TO SEG) %SYSTEMROUTINESPEC MAPHWR(%INTEGER SEGS) %SYSTEMROUTINESPEC LINKIN(%INTEGER SER) %RECORDFORMAT PF(%BYTEINTEGER SERVICE, REPLY, %C %INTEGER A1, A2, A3) %RECORDFORMAT TTF(%INTEGER KBS, KBD, TTS, TTD) %RECORDFORMAT BUFF(%INTEGER PT, LAST, %BYTEINTEGERARRAYNAME B) %RECORDFORMAT BUFFX(%INTEGER PT, LAST, ARRAYPT) %CONSTRECORD (BUFFX) %NAME NULL = 0 %CONSTINTEGER RUBOUT=K'177' %CONSTINTEGER CAN=24 %CONSTINTEGER CR=13 %CONSTINTEGER BELL=7 %CONSTINTEGER ESC=K'33' %CONSTINTEGER SI=K'17'; ! SHIFT INTO LOWER MODE (CTRL O) %CONSTINTEGER SO=K'16'; ! SHIFT OUT (CTRL N) %CONSTINTEGER DLE=K'20'; ! (CTRL P) %CONSTINTEGER EOT = K'04'; ! EOF (CTRL D) %CONSTINTEGER DC1=K'21'; ! CANCEL OUTPUT (CTRL Q) %CONSTINTEGER TAB = 9; ! TAB (IMPLEMENTED AS 3 SPACES) %OWNRECORD (TTF) %NAME TT=K'137560' %OWNINTEGER KBINT=-2 %OWNINTEGER TTINT=-1 %OWNINTEGER TTSER=1; ! ??? %OWNINTEGER CLIID=2 %OWNINTEGER TT STATUS=0, UPPER=32, TT IDLE=0, E PT=0, EFPT=0 %RECORD (PF) P2 %OWNRECORD (PF) %NAME P %CONSTINTEGER NO OF SPECS = 6 %OWNBYTEINTEGERARRAY SPECS(0:NO OF SPECS) = RUBOUT, CAN, ESC, CR, SI, SO, TAB %CONSTINTEGER ECHO OFF = 10; ! COMMAND TO PUT ECHO OFF %INTEGER CHAR, I, IN MODE, E LAST, ECHOFL %INTEGER OUTID, SEG, CLI FLAG, CID, CADR %OWNRECORD (BUFF) OUT, INH %RECORD (BUFFX) %NAME BUFX, INX %RECORDFORMAT HF(%RECORD (HF) %NAME H, %RECORD (PF) P) %RECORDFORMAT QF(%RECORD (HF) %NAME H) %OWNRECORD (HF) %ARRAY HA(0:15) %OWNRECORD (HF) %NAME H %OWNRECORD (QF) HI, HO %OWNRECORD (QF) FREE %OWNINTEGER FIRST, LAST, CURR %OWNBYTEINTEGERARRAY BUFFER(0:255) %OWNBYTEINTEGERARRAY ECHOB(1:40) %SWITCH INS(0:NO OF SPECS), STATE(0:7) %ROUTINESPEC DRIVE TT(%INTEGER CHAR) %ROUTINESPEC ECHO(%INTEGER X) %ROUTINESPEC ECHO BELL %ROUTINESPEC TRANSFER INPUT %ROUTINESPEC OUTPUT REPLY %ROUTINESPEC PLANT(%INTEGER N) !! %CONSTBYTEINTEGERARRAY CANM(0:3)= 3, '#', CR, NL !! %CONSTBYTEINTEGERARRAY CLIM(0:3)= 3, '<', 8, '>' %CONSTINTEGER MYSEG=4, MSA=K'100000' %CONSTINTEGER MYISEG=3, MISA=K'060000' MAPHWR(5); ! MAP REGS TO SEG 5 LINKIN(TTSER); LINKIN(KBINT); LINKIN(TTINT) TT_KBS=K'100' BUFX==OUT INX==INH %CYCLE I = 15, -1, 0 PUSH(FREE, HA(I)) %REPEAT %CYCLE %IF OUTID=0 %AND %NOT HO_H == NULL %START H == POP(HO); PUSH(FREE, H) P == H_P %ELSE P == P2 P_SERVICE = 0 POFF(P) %FINISH %IF P_SERVICE=KBINT&X'FF' %START CHAR=TT_KBD&127; ! STRIP PARITY BIT %CYCLE I=NO OF SPECS, -1, 0 ->INS(I) %IF CHAR=SPECS(I) %REPEAT !! NORMAL CHAR %IF CHAR>='A'+K'40' %AND CHAR<='Z'+K'40' %THENC CHAR=CHAR-UPPER; ! TURN TO UPPER PLANT(CHAR) %CONTINUE INS(0): ! RUBOUT %IF LAST#CURR %START LAST = (LAST-1)&255 ECHO('\') %ELSE ECHO BELL %CONTINUE INS(1): ! CANCEL %IF LAST#CURR %START LAST = CURR ECHO('#'); ECHO(CR); ECHO(NL); E LAST=E PT %ELSE ECHO BELL %CONTINUE INS(2): ! ESCAPE - GO TO CLI CLI FLAG = 1 LAST = 0; CURR = 0; FIRST = 0 INS2: ECHO('<'); ECHO(13); ECHO('>') %CONTINUE INS(4): ! SHIFT IN UPPER = 0; %CONTINUE INS(5): ! SHIFT OUT UPPER = 32; %CONTINUE INS(6): ! TAB PLANT(' '); PLANT(' '); PLANT(' '); %CONTINUE INS(3): ! CR ECHOFL = 0; ! ECHO TURNED ON AT NL PLANT(NL); CURR = LAST TRANSFER INPUT E LAST=E PT; ! ALLOW IT TO DO OUTPUT NOW %ELSE %IF P_SERVICE=TT INT&X'FF' %START ->STATE(TT STATUS) DO OUT: STATE(5): ! GOING IDLE TT STATUS=0 %IF E PT>0 %THEN TT STATUS=2 %ELSESTART %IF OUT_LAST#0 %THEN TT STATUS=1 %FINISH ->STATE(TT STATUS) STATE(1): ! NORMAL OP CHAR=OUT_B(OUT_PT); OUT_PT=OUT_PT+1 %IF OUT_PT>=OUT_LAST %THEN TT STATUS=5 %AND OUTPUT REPLY DRIVE TT(CHAR) STATE(0): %CONTINUE STATE(2): ! ECHO OP %IF EFPTDO OUT %FINISH %FINISH %IF EFPT=E PT %THEN E PT=0 %AND EFPT=0 %CONTINUE STATE(3): ! NORMAL CR STATE(4): ! ECHO CR STATE(7): ! END OF LINE - NEWLINE TT STATUS=5 DRIVE TT(NL+128) %CONTINUE STATE(6): ! IN ECHO LINE %CYCLE; %REPEAT %ELSE %IF P_SERVICE=TT SER %START; ! USER REQUEST %IF P_A1=1 %START; ! OUTPUT REQUEST %IF OUTID#0 %START H == POP(FREE) %IF H == NULL %START REJ: P_SERVICE= P_REPLY; P_REPLY = TT SER P_A1 = 1; PON(P) %CONTINUE %FINISH H_P = P; ! COPY P INTO SAFE PLACE PUSH(HO, H); ! AND QUEUE IT %CONTINUE %FINISH OUTID=P_REPLY SEG=P_A2>>13; ! SEG NO OF BUFFER I = MAP VIRT(OUTID, SEG, MY SEG) %CONTINUE %IF I = 0 BUFX_ARRAYPT=MSA+(P_A2&K'17777') OUT_PT=0; OUT_LAST=P_A3; ! LENGTH %IF OUT_LAST=0 %THEN OUTPUT REPLY %ELSESTART ->DO OUT %IF TT STATUS=0; ! TT IDLE %FINISH %ELSE !! INPUT REQUEST %IF P_A1 = ECHO OFF %THEN ECHO FL = ECHO FL+1 %ANDCONTINUE %IF P_A1 # 0 %START CID = P_REPLY; CADR = P_A2 %CONTINUE %IF P_A3 # 0; ! JUST READ FROM CLI %FINISH H == POP(FREE) -> REJ %IF H == NULL H_P = P; ! COPY P INTO A SAFE PLACE PUSH(HI, H); ! AND Q IT %IF P_A1#0 %AND FIRST=LAST %THEN -> INS2 %IF FIRST#CURR %START; ! NON EMPTY LINE TRANSFER INPUT %FINISH %FINISH %FINISH %REPEAT %ROUTINE DRIVE TT(%INTEGER CHAR) %IF CHAR=NL %START TT STATUS=TT STATUS+2 CHAR=CR %FINISH TT_TTD=CHAR TT_TTS=TT_TTS!K'100'; ! INTS ON %END %ROUTINE ECHO(%INTEGER X) %RETURN %IF E PT>40 %OR ECHO FL # 0 E PT=E PT+1; ECHOB(E PT)=X %IF TT STATUS=0 %OR TT STATUS=6 %START TT STATUS=2 DRIVE TT(X) EFPT=1 %FINISH %END %ROUTINE ECHO BELL ECHO(BELL); E LAST=E PT %END %ROUTINE PLANT(%INTEGER CHAR) BUFFER(LAST) = CHAR LAST = (LAST+1)&255 ECHO(CHAR) %END %ROUTINE TRANSFER INPUT %INTEGER SEG, I, ID, ADR, N RETRY: %IF CLI FLAG # 0 %START; ! PREEMPTED BY CLI ID = CID; ADR = C ADR; CLI FLAG = 0 %ELSE %IF HI_H == NULL %THEN %RETURN H == POP(HI); PUSH(FREE, H) ID = H_P_REPLY; ADR = H_P_A2 %FINISH %IF ID#0 %START SEG=ADR>>13 I = MAP VIRT(ID, SEG, MYISEG) -> RETRY %IF I = 0; ! TASK HAS GONE AWAY/ILLEGAL ADDR INX_ARRAY PT=MISA+(ADR&K'17777') %CYCLE I = 0, 1, 80 N = BUFFER(FIRST) INH_B(I) = N FIRST = (FIRST+1)&255 %EXIT %IF N = NL %REPEAT P_SERVICE=ID; P_REPLY=TTSER P_A1=I+1 PON(P) I =MAP VIRT(0, -1, MYISEG) %FINISH %END %ROUTINE OUTPUT REPLY %INTEGER I I = MAP VIRT(0, -1, MYSEG) P_SERVICE=OUTID; P_REPLY=TTSER P_A1=0 PON(P) OUTID=0; OUT_LAST = 0 %END %ENDOFPROGRAM