! FILE 'CLI1S' ! 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 = 55 %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