! 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