!* VERSION FOR UNIT 2 & 3 DEV MACHINE ONLY  (SEE ADDRESS)
!************
!*  TU58S   *
!*31.OCT.80*
!* UNIT 2   *
!* VERSION  *
!************
!* UNIT 4 ADDED

CONTROL  K'100001';                    ! 'SYSTEM' PROGRAM+MUL+TRUSTED

BEGIN 
     SYSTEMINTEGERFNSPEC  GETID
     SYSTEMROUTINESPEC  LINKIN(INTEGER  SER)
      SYSTEMINTEGERFNSPEC  MAP ABS(INTEGER  ADR, LEN, REQ ID)
     PERMINTEGERFNSPEC  SVC(INTEGER  EP, R0, R1)
     SYSTEMINTEGERFNSPEC  MAP VIRT(INTEGER  WHO, HSEG, MYSEG)
     SYSTEMROUTINESPEC  MAPHWR(INTEGER  SEGS)

     RECORDFORMAT  PF(BYTEINTEGER  SERVICE, REPLY, INTEGER  A1, A2, A3)
     RECORDFORMAT  P2F(INTEGER  D)

     RECORDFORMAT  TU58F(INTEGER  RSR, RDB, TSR, TDB)
     CONSTRECORD  (TU58F) NAME  TU58 = K'116160'

    RECORDFORMAT  DESF(INTEGER  PT, STATE, MAXLN, P1, MODE, SEG, COU, VEC, C 
        INTEGERARRAY  COMM(0:6), IN(0:7))

   OWNRECORD  (DESF) NAME  DES

     CONSTINTEGERNAME  PS = K'117776'
     CONSTINTEGERNAME  CS = K'140016';      ! HOLD THE CRC

     CONSTINTEGER  TU58TOP = 512
     OWNINTEGER  TU58 BOT = 0

     CONSTINTEGER  TU58 INT = -8;      ! ????


     RECORD  (PF)P, PX
     RECORD  (P2F) NAME  P2

     INTEGER  PAR, ID, BLOCK, COMM, BL, I, DRIVE
     INTEGER  DAR, COMM2, MID, FAULT, REPLY
     INTEGER  ACT, SECTOR, TRACK, DIFF, SURFACE, N

      RECORDFORMAT  R1F(BYTEINTEGERARRAYNAME  A)
      RECORDFORMAT  R2F(INTEGER  X)
      RECORDFORMAT  R3F(INTEGERARRAYNAME  A)
   RECORDFORMAT  R4F(RECORD  (DESF) NAME  DES)

      RECORD  (R1F) R1; RECORD  (R2F) NAME  R2; RECORD  (R3F) NAME  R3
     RECORD  (R4F) NAME  R4


      OWNINTEGERARRAY  READC(1:7) = K'5002', 2, 0, 0, 0, 0, 0
      OWNINTEGERARRAY  WRITEC(1:7) = K'5002', 3, 0, 0, 0, 0, 0
      OWNBYTEINTEGERARRAY  BUFF(0:13)

     ROUTINE  TX(INTEGER  N)
         WHILE  TU58_TSR&K'200' = 0 CYCLE ; REPEAT 
        N = N&X'FF'
         TU58_TDB = N
     END 

      INTEGERFN  RX
         INTEGER  I, X, Y
         X = 30000; Y = 50
         WHILE  TU58_RSR&K'200' = 0 CYCLE 
            X = X-1
            IF  X = 0 START 
               Y = Y-1; RESULT  = -1 IF  Y = 0
               X = 30000
            FINISH 
         REPEAT 
         I = TU58_RDB
         RESULT  = I&X'FF'
      END 

     ROUTINE  SEND COMMAND(INTEGERARRAYNAME  COMM)
         INTEGER  I,J,K
         CONSTINTEGERNAME  CS = K'140016';  ! HOLDS CHECKSUM

         CS = 0
         CYCLE  I = 1, 1, 6
            TX(COMM(I)); TX(COMM(I)>>8)
            CS = CS+COMM(I)
            *K'005737'; *K'140016';  ! ADC CS
         REPEAT 
         TX(CS); TX(CS>>8)
      END 

      INTEGERFN  READ COMMAND(INTEGER  N)
         INTEGER  I, J, K
         BUFF(0) = N
         CYCLE  I = 1, 1, 13
            J = RX
            EXIT  IF  J<0
            BUFF(I) = J
         REPEAT 
         IF  J < 0 THEN  PRINTSTRING("TIMEOUT
")
         IF  BUFF(3) = 0 THEN  RESULT  = 0
         CYCLE  I = 0, 1, 13
            WRITE(BUFF(I), 2)
         REPEAT 
        NEWLINE
      RESULT  = BUFF(3)
       END 
      ROUTINE  POWER UP
         INTEGER  I
         TU58_TSR = TU58_TSR!1
         TX(0); TX(0)
         WHILE  TU58_TSR&K'200' = 0 CYCLE ; REPEAT 
         TU58_TSR = TU58_TSR&(¬1); ! CLEAR IT AGAIN
      END 

      ROUTINE  INIT


         !! INITIALISATION
         TX(4); ! INIT CHAR
         TX(4)
         UNTIL  RX = K'20' CYCLE ; REPEAT 
      END 



     P2 == PX
      R2 == R1;  R3 == R2;  R4 == R3
     MID = GETID
     LINKIN(8);                       ! MAIN DISC SERVICE
      LINKIN(14);                        ! UNIT 3
      LINKIN(TU58 INT);                     ! INT SERVICE
     MAPHWR(4)
     PS = PS&K'177400';              ! UNTIL SUPERVISOR CHANGED
      I = SVC(22, 0, 0);    ! FIND ABS ADDR
      R2_X = I&K'77'
      DES == R4_DES


      !! POWER UP SEQUENCE
      POWER UP
      INIT
       PRINTSTRING("TU58 READY
")

     CYCLE 
        P_SERVICE = 0
        POFF(P)
        FAULT = 0
        ID = P_REPLY;  REPLY = P_SERVICE
        IF  P_A2 = 0 START 
           TU58 BOT = 0;  FAULT = 9
        ELSE 
           DRIVE = 0;                  ! NORMALLY DRIVE 0
            IF  REPLY = 14 THEN  DRIVE = 1;  ! UNIT 3
            PAR = MAP ABS(P_A2, 512, ID)
           IF  PAR = 0 THEN  FAULT = 1 ELSESTART 
             I = SVC(22, 0, 0)
              BLOCK = P_A3

             IF  BLOCK < TU58 BOT OR  BLOCK > TU58 TOP THEN  FAULT = 4 C 
               ELSE  START 

                R2_X = K'140000'!(P_A2&K'17777');   ! ADDR IN SEG 6
AGN:


            DES_COMM(2) = DRIVE
            DES_COMM(4) = 512
            DES_COMM(5) = BLOCK

            IF  P_A1&1 = 0 THEN  DES_COMM(1) = 2 ELSE  C 
              DES_COMM(1) = 3

            DES_MODE = R2_X;      ! ADDR IN SEG
            DES_SEG = PAR
            DES_COU = 10+1;      ! INITIAL LEN
            DES_P1 = K'5002'
            DES_STATE = 1

            TU58_TDB = 2;     ! 1ST BYTE OF COMMAND
            TU58_TSR = TU58_TSR!K'100'

            P2_D = (-8)&X'FF';  POFF(P2)
            I = DES_IN(0)>>8
            IF  I # 0 AND  DES_MODE = 0 START 
               PRINTSTRING("ERROR FLAG:"); WRITE(I, 1); NEWLINE
              DES_MODE = I
            FINISH 

           IF  DES_MODE # 0 START 
               WRITE(DES_MODE, 1)
               WRITE(DES_STATE, 1); WRITE(DES_SEG, 1); WRITE(DES_COU, 1); NEWLINE



FLTR:               PX_SERVICE = 7;  PX_REPLY = MID
                    PX_A1 = P_A1;  PX_A3 = BLOCK
                    PONOFF(PX)
                                       ! ISSUE RESET
                     POWER UP; INIT
                    FAULT = 5 AND  -> FLT IF  PX_A1 # 0
                    -> AGN
                 FINISH 
              FINISH 
           FINISH 
FLT:       PAR = MAP ABS(P_A2, 0, ID); ! RELEASE SEG
        FINISH 
        P_A1 = FAULT
        P_SERVICE = ID;  P_REPLY = REPLY
        PON(P)
     REPEAT 
ENDOFPROGRAM