!************** !* BVT1S * !*DA:09.APR.80* !************** CONTROL K'100001'; ! 'SYSTEM' PROGRAM (FAST ROUTINE ENTRY/EXIT) PERMROUTINESPEC SVC(INTEGER EP, P1, P2) BEGIN 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 INTEGER CHAR, I, IN MODE, E LAST 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(8); ECHO(' '); ECHO(8) 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 BELL 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 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 EFPT<E PT START EFPT=EFPT+1 CHAR=ECHOB(EFPT) IF EFPT=E LAST THEN TT STATUS=5 AND E LAST=-1 DRIVE TT (CHAR) ELSE TT STATUS = 6 IF EFPT=E LAST START E LAST=-1; E PT=0; EFPT=0 ->DO 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 MAP VIRT(OUTID, SEG, MY SEG) 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 # 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 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 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 MAP VIRT(ID, SEG, MYISEG) 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) MAP VIRT(0, -1, MYISEG) FINISH END ROUTINE OUTPUT REPLY MAP VIRT(0, -1, MYSEG) P_SERVICE=OUTID; P_REPLY=TTSER P_A1=0 PON(P) OUTID=0; OUT_LAST = 0 END ENDOFPROGRAM