! FILE 'PCLOCKS'
! PROGRAMMABLE CLOCK PROGRAM
! DATE: 5.MAR.81

%CONTROL K'100001'
%PERMROUTINESPEC SVC(%INTEGER EP, R0, R1)
%PERMINTEGERMAPSPEC INTEGER
%PERMBYTEINTEGERMAPSPEC BYTEINTEGER
%PERMINTEGERFNSPEC ADDR
%PERMINTEGERFNSPEC ACC
%BEGIN

%SYSTEMROUTINESPEC MAPHWR(%INTEGER SEG)
%SYSTEMROUTINESPEC LINKIN(%INTEGER NO)
      %CONSTBYTEINTEGERNAME INT = K'160060'

%RECORDFORMAT CLOCKF(%INTEGER STATUS, DATA)
%CONSTRECORD (CLOCKF) %NAME CLOCK = K'112540';   ! IN SEG 4

%RECORDFORMAT PF(%BYTEINTEGER SER, REPLY, %INTEGER A, B, C)
%RECORD (PF) P

%INTEGER I,J,K,N, SUM, MAXI, SUMN
%OWNINTEGER REPF
%INTEGERARRAY TASKS(0:75)

      %ROUTINE PRINT NAME(%INTEGER TASK)
         %CONSTINTEGER MAP PSECT = 16;     ! SUPERVISOR CALL TO MAP TO PSECT
         %RECORDFORMAT PSECTF(%BYTEINTEGER X, Y, ID, STATE, %BYTEINTEGERARRAY %C
           NAME(0:3), %BYTEINTEGER PRIO, %INTEGER POFFQ, %C
          %INTEGERARRAY R(0:8),  %C
          %INTEGER TRPV)
                         ! NB: R(0-8) ARE R0, R1, R2, R3, R4, R5, PC, PS, SP
    
         %RECORD (PSECTF) %NAME P
         %RECORDFORMAT D1F(%INTEGER X)
         %RECORDFORMAT D3F(%RECORD (PSECTF) %NAME P)
         %RECORD (D1F)D1
         %RECORD (D3F) %NAME D3
            %INTEGER PST, I
            %IF TASK < 30 %START
               %IF TASK = 1 %START
                  PRINTSTRING("SYS "); %RETURN
               %ELSE PRINTSTRING("SYSI") %AND %RETURN
            %FINISH

           D3 == D1
           SVC(MAP PSECT, TASK, 5)
           PST = ACC
            %IF PST = 0 %START
               PRINTSTRING("????")
               %RETURN
            %FINISH
           D1_X = PST
           P == D3_P
            PRINTSYMBOL(P_NAME(I)) %FOR I = 0, 1, 3
      %END

!      %ROUTINE OCTAL(%INTEGER I)
!         %INTEGER N
!         PRINTSYMBOL((I>>N)&7+'0') %FOR N = 15,-3,0
!      %END

   MAP HWR(4)
   LINKIN(-10)
   CLOCK_DATA = 23210;    ! INT EVERY 2.321 SECS
   CLOCK_STATUS = K'113';   ! COUNT DOWN, REPEATED, 10KHZ, RUN, INT
   %CYCLE
      P_SER = 0; POFF(P)

      %IF P_SER&X'80' # 0 %START
         %IF K'020000' <= P_B <= K'040000' %START
            %IF P_B = K'22756' %OR P_B=K'22744' %ORC
               P_B=K'23016' %OR P_B=K'23150' %THENC
               TASKS(1) = TASKS(1)+1 %AND %CONTINUE
         %FINISH

         I = P_C&X'FF';      !  TASK ID
         TASKS(I) = TASKS(I)+1
         N = N+1
         %IF REPF # 0 %AND N = 375 %THEN INT = '?'
         %UNLESS 0<=I<=75 %START
            PRINTSTRING("FUNNY TASK:"); WRITE(I, 1); NEWLINE
         %FINISH
      %FINISH

      %IF INT = 'S' %THEN CLOCK_STATUS = 0 %AND %STOP
      %IF INT = '?' %START
         WRITE(N, 1); NEWLINE
         SUM = 0; MAXI = 0
         %CYCLE I = 0, 1, 75
            J = TASKS(I)
            SUM = SUM+J
            %IF J > TASKS(MAXI) %THEN MAXI = I
            %IF J < 0 %THEN MAXI = I
         %REPEAT
         SUMN = SUM-TASKS(MAXI);  ! ASSUMED TO BE IDLE

         %CYCLE I = 0, 1, 75
            %IF TASKS(I) # 0 %START
               PRINT NAME(I)
               WRITE(TASKS(I), 5)
               WRITE((TASKS(I)*100)//SUM, 5); PRINTSYMBOL('%')
               %UNLESS I = MAXI %START
                  WRITE((TASKS(I)*100)//SUMN, 5); PRINTSTRING("%")
               %FINISH
               NEWLINE
            %FINISH
         %REPEAT
         INT = 0
      %FINISH
      %IF INT = 'R' %START
         REPF = REPF!!1
         INT = 0; N = 0
      %FINISH

      %IF INT = 'C' %START
         TASKS(I) = 0 %FOR I = 0, 1, 75
         INT = 0
      %FINISH
   %REPEAT
%ENDOFPROGRAM
         SUMN = SUM-TASKS(MAXI);  ! ASSUMED TO BE IDLE