! FILE 'CLI1S' !************** !* CLI1S * !* 16.JUN.80 * !************** PERMINTEGERFNSPEC SVC(INTEGER EP, INTEGER P1, INTEGER P2) PERMINTEGERMAPSPEC INTEGER(INTEGER X) PERMBYTEINTEGERMAPSPEC BYTEINTEGER(INTEGER X) PERMINTEGERFNSPEC ADDR(INTEGERNAME X) SYSTEMINTEGERFNSPEC GETID CONTROL K'101011'; ! TRUSTED RECORDFORMAT DUMREC(INTEGER X) CONSTRECORD (DUMREC) NAME NULL = 0 BEGIN CONSTINTEGER DELETE = 5 CONSTINTEGER SCHEDULE = 9 CONSTINTEGER MAP PSECT = 16 CONSTINTEGER TASK LOW LIMIT = 30 ! SEE SUPERVISOR FOR UPDATES OWNINTEGER TASK LIMIT = 70 CONSTINTEGER T POFF = 2 OWNINTEGER TT SER = 1; ! TT HANDLER (SHAREABLE CODE !!) CONSTINTEGER LOAD SER = 5; ! MAIN LOADER SERVICE RECORDFORMAT UREGSF(INTEGER R0, R1, R2, R3, R4, R5, PC, PS, SP) RECORDFORMAT SEGF(INTEGER PAR, PDR, DADD, USE) RECORDFORMAT PSECTF(INTEGER Q, C BYTEINTEGER ID, STATE, BYTEINTEGERARRAY C NAME(0:3), BYTEINTEGER PRIO, INTEGER POFFQ, RECORD (UREGSF C )URS, INTEGER TRAPV, RECORD (SEGF) ARRAY SEG(0:7)) RECORDFORMAT PF(BYTEINTEGER SERVICE, REPLY, INTEGER A, B, C) RECORDFORMAT P2F(BYTEINTEGER SERVICE, REPLY, A1, A2, C BYTEINTEGERNAME B, BYTEINTEGER C1, C2) CONSTBYTEINTEGERNAME INT CHAR = K'100060'; ! IN SEG 4 !!! CONSTBYTEINTEGERNAME CHANGE OUT ZERO = K'160310' RECORDFORMAT D1F(INTEGER X) RECORDFORMAT D2F(BYTEINTEGERNAME B) RECORDFORMAT D3F(INTEGERNAME Z) RECORDFORMAT D4F(RECORD (PSECTF) NAME PST) RECORD (PF)P RECORD (P2F) NAME P2 INTEGER ID, INPT INTEGER NCHAR, OSEG, CKSM OWNINTEGER READ FLAG = 0, FSYS = 0, PROG = 1 OWNBYTEINTEGERARRAY STORE(0:70) = 0, 'L', 'O', 'A', 'D', 'U', 'P', NL, 0(0) ROUTINESPEC PRI ROUTINESPEC RELEASE(INTEGER SEG) ROUTINESPEC PUT READ ON(INTEGER TYPE) ROUTINESPEC OCTAL(INTEGER N) RECORD (PSECTF) MAP SPEC GET PSECT(INTEGER ID) RECORD (PSECTF) MAP SPEC GET NAME(BYTEINTEGERNAME ST) ROUTINESPEC PNAME(BYTEINTEGERARRAYNAME NAME) INTEGERFNSPEC CLI RECORD (D1F)D1 RECORD (D2F) NAME D2 RECORD (D3F) NAME D3 D2 == D1; D3 == D2; P2 == P IF TT SER#1 START CHANGE OUT ZERO = TT SER; ! SWITCH TO NEW CONSOLE STORE(6) = 'U'; ! LOADES 'LOADUU' FINISH ID = GETID -> FROM OUT; ! INITIAL SPECS LOAD CYCLE PUT READ ON(0) IF READ FLAG = 0 P_SERVICE = 0 POFF(P) IF P_REPLY = TT SER START ; ! REPLY FROM KEYBOARD NCHAR = P_A; ! GET NO OF CHARS READ FLAG = 0 IF STORE(1) = NL THENCONTINUE PROG = PROG+1; ! COUNT LOADED PROGS FROM OUT: ! ENTRY FOR EXTERNAL CALLS IF CLI = 0 THEN PROG = PROG-1 AND CONTINUE ! NOT AN INSTRUCTION, SO PASS TO LOADER P_SERVICE = LOAD SER; P_REPLY = ID D2_B == STORE(1) P2_A1 = 1; P2_A2 = FSYS; P_B = D1_X P2_C1 = 0; P2_C2 = TT SER PON(P2) ELSE IF P_A = 3 START ; ! LOADED EXTRA PROG PROG = PROG+1 CONTINUE FINISH IF P_A = 2 START ; ! PROG STOPPING IF P_C = 0 START IF PROG # 1 THEN PRINTSTRING('stopped ') ELSE IF P_C #- 2 START PRINTSTRING('F A U L T '); WRITE(P_C, 1) ELSE PRINTSTRING("term req.") FINISH NEWLINE FINISH ELSE IF P_A = 0 START IF P_B = 3 START PRINTSTRING("*no "); PRI ELSE PRINTSYMBOL('*'); PRI PRINTSTRING(" fault ") PRINTSYMBOL(P_B+'0') FINISH NEWLINE FINISH FINISH PROG = PROG-1 IF PROG <= 0 THEN PROG = 0 AND PUT READ ON(1) FINISH REPEAT ROUTINE PRI INTEGER I, J CYCLE I = 1, 1, 6 J = STORE(I) EXIT IF J<= ' ' PRINTSYMBOL(J) REPEAT END ROUTINE RELEASE(INTEGER SEG) IF SEG #- 1 START MAP VIRT(0, -1, 4); ! ALWAYS RELEASE LOADER SEG 4 FINISH END ROUTINE PUT READ ON(INTEGER TYPE) RECORDFORMAT P3F(BYTEINTEGER SERVICE, REPLY, INTEGER A, C BYTEINTEGERNAME B, INTEGER C) RECORD (P3F)P3 P3_SERVICE = TT SER; P3_REPLY = ID P3_B == STORE(1) IF TYPE = 0 THEN P3_A = 2 ELSE P3_A = 5 IF PROG < 0 THEN PROG = 0 P3_C = PROG; ! SYSTEM IDLE FLAG READ FLAG = 1; ! WAITING FOR REPLY PON(P3) END ROUTINE OCTAL(INTEGER N) INTEGER I SPACE PRINTSYMBOL(N >> I&7+'0') FOR I = 15, -3, 0 END RECORD (PSECTF) MAP GET PSECT(INTEGER ID) INTEGER N RECORD (D4F) NAME D4; RECORD (D1F)D1 D4 == D1 N = SVC(MAP PSECT, ID, 5); ! MAP TO MY K'100000' D1_X = N RESULT == D4_PST END RECORD (PSECTF) MAP GET NAME(BYTEINTEGERNAME ST) RECORD (PSECTF) NAME PST INTEGER PT, ID, J, CHAR, MATCH RECORDFORMAT D5F(BYTEINTEGERARRAYNAME STR) RECORD (D2F) NAME D2; RECORD (D5F) D5 D2 == D5 D2_B == ST CYCLE ID = TASK LOW LIMIT, 1, TASK LIMIT PST == GET PSECT(ID) UNLESS PST == NULL START CYCLE J = 0, 1, 3 CHAR = D5_STR(J); MATCH = PST_NAME(J) EXITIF CHAR <= ' ' >= MATCH -> NO IF CHAR # MATCH REPEAT RESULT == PST UNLESS PST_STATE = 0 FINISH NO: REPEAT RESULT == NULL END ROUTINE PNAME(BYTEINTEGERARRAYNAME NAME) INTEGER I PRINTSYMBOL(NAME(I)) FOR I = 0, 1, 3 END INTEGERFN CLI RECORDFORMAT D1F(STRINGNAME S) RECORDFORMAT D2F(BYTEINTEGERNAME N) RECORD (D1F)D1 RECORD (D2F) NAME D2 RECORD (PSECTF) NAME PST INTEGER I, J, K, ID, CHAR, TYPE CONSTINTEGER COM LIMIT = 10 CONSTSTRING (5) ARRAY COMMS(0:COM LIMIT) = 'LOGON', C 'TASKS', 'REGS', 'SEGS', 'PURGE', 'KILL', 'FREE', 'HOLD', 'INT', 'KICK', 'ABORT' SWITCH COMSW(0:COM LIMIT) RECORDFORMAT REGF(INTEGERARRAY R(0:8)) RECORD (REGF) NAME REG CONSTSTRING (2) ARRAY REGS(0:8) = 'R0', 'R1', 'R2', 'R3', C 'R4', 'R5', 'PC', 'PS', 'SP' RECORD (SEGF) NAME SEG INPT = 1 INPT = INPT+1 WHILE 'A' <= STORE(INPT) <= 'Z' AND INPT <= C NCHAR STORE(0) = INPT-1 D2 == D1 D2_N == STORE(0) CYCLE I = 0, 1, COM LIMIT IF COMMS(I) = D1_S START IF I = 8 START CHAR = STORE(INPT+1); INPT = INPT+2 FINISH IF I >= 2 START PST == GET NAME(STORE(INPT+1)) IF PST == NULL START PRINTSTRING('TASK? ') RESULT = 0 FINISH FINISH -> COMSW(I) FINISH REPEAT RESULT = 1 COMSW(1): ! TASKS CYCLE ID = TASK LOW LIMIT, 1, TASK LIMIT PST == GET PSECT(ID) UNLESS PST == NULL START PNAME(PST_NAME) OCTAL(PST_ID); OCTAL(PST_STATE) NEWLINE FINISH REPEAT -> OK COMSW(2): ! REGS OF NOMINATED TASK REG == PST_URS CYCLE I = 0, 1, 8 PRINTSTRING(REGS(I)); OCTAL(REG_R(I)); SPACE NEWLINE IF I = 4 REPEAT NEWLINE -> OK COMSW(3): ! SEGS CYCLE I = 0, 1, 7 SEG == PST_SEG(I) OCTAL(SEG_PAR); OCTAL(SEG_PDR) OCTAL(SEG_DADD); NEWLINE REPEAT OK: RESULT = 0 COMSW(4): ! PURGE PROG = PROG-1 I = SVC(SCHEDULE, PST_ID, 1); ! HOLD IT PNAME(PST_NAME) PRINTSTRING(' purged ') I = SVC(DELETE, PST_ID, 0) -> OK COMSW(5): ! KILL I = SVC(SCHEDULE, PST_ID, 1) I = SVC(SCHEDULE, PST_ID, K'020000') -> OK COMSW(0): ! LOG FSYS = (STORE(INPT+1)-'0') << 3+STORE(INPT+2)-'0' NEWLINE -> OK COMSW(6): ! FREE TASK (PUT ON CPUQ COMSW(9): ! KICK TASK TYPE = 0 KICK IT: I = SVC(SCHEDULE, PST_ID, 0); ! REMOVE HOLD IF PST_STATE # T POFF THEN ->OK P_SERVICE = PST_ID; P_REPLY = 7; P_A = TYPE; PON(P) -> OK COMSW(10): ! ABORT TASK TYPE = 1 -> KICK IT COMSW(7): ! WAIT PROCESS I = SVC(SCHEDULE, PST_ID, 1); ! HOLD IT -> OK COMSW(8): ! INT 'CHAR' 'TASK' IF PST_ID > K'42' START ; ! NOT SYSTEM TASKS MAP VIRT(PST_ID, 7, 4) INT CHAR = CHAR RELEASE(0); ! RELEASE THE SEG FINISH -> OK END ENDOFPROGRAM