*M* RCVRIO RAD/DISC I/O ROUTINE FOR RECOVERY.
         DEF      CKRAD
*,*               ENTRY POINT OF ROUTINE TO CHECK VALIDITY OF SWAPPING
*,*               RAD SEEK ADDRESS.
         DEF      CLSPRI
*,*               CELL INDICATING IF R6 SHOULD BE USED AS A DCB
*,*               ADDRESS IN RCHKDA.
         DEF      DISCCU
*,*               DUMMY ENTRY POINT FOR BAD I/O POST PROCESSING.
         DEF      DPAKCU
*,*               DUMMY ENTRY POINT FOR DISK I/O POST PROCESSING.
         DEF      DSKABCU
*,*               DUMMY ENTRY POINT FOR DISK I/O POST PROCESSING.
         DEF      R:CHKDA
*,*               ENTRY POINT FOR ROUTINE TO CHECK VALIDITY OF
*,*               SYSTEM DISK ADDRESS.
         DEF      R:DSCCVT
*,*               ENTRY POINT OF ROUTINE TO CONVERT A SYSTEM DISK
*,*               ADDRESS TO SEEK ADDRESS.
         DEF      R:FNDHGP
*,*               ENTRY POINT OF ROUTINE TO FIND THE HGP ASSOCIATED
*,*               WITH A SYSTEM DA.
         DEF      R:TSTACK
*,*               TSTACK POINTER ADDRESS OF GENERAL STACK FOR
*,*               RECOVERY.
         DEF      RCHKDA
*,*               ENTRY POINT OF ROUTINE TO CHECK VALIDITY OF DA
*,*               WITH ASSOCIATED DCB.
         DEF      RDDISK
*,*               ENTRY POINT OF ROUTINE TO READ A SYSTEM DISK.
         DEF      WRDISK
*,*               ENTRY POINT OF ROUTINE TO WRITE A SYSTEM DISK.
         DEF      WRDISK1
*,*               ENTRY POINT OF ROUTINE TO WRITE A SYSTEM DISK.
         DEF      WRRAD
*,*               ENTRY POINT OF ROUTINE TO WRITE A SWAPPING RAD.
         DEF      WRRAD1
*,*               ENTRY POINT OF ROUTINE TO WRITE A SWAPPING RAD.
         DEF      WRRAD2
*,*               ENTRY POINT OF ROUTINE TO WRITE ROTATING DEVICE
*,*               CALLED BY IOQFLUSH.
         DEF      WRUSR1
*,*               ENTRY POINT OF ROUTINE TO WRITE THE PACK SWAPPER.
         DEF      RDDISK1
*,*               ENTRY POINT OF ROUTINE TO READ A SYSTEM DISK.
         DEF      RDRAD
*,*               ENTRY POINT OF ROUTINE TO READ A SWAPPING RAD
         DEF      RDRAD1
*,*               ENTRY POINT OF ROUTINE TO READ A SWAPPING RAD
         DEF      RDUSR1
*,*               ENTRY POINT OF ROUTINE TO READ THE PACK SWAPPER.
         DEF      RCVRIO:           PATCHING DEF
RCVRIO:  RES
MONPROC    SET       1
DISCBPROC SET     1                                                     DISCB
          SYSTEM   UTS
R0       EQU      0
R1       EQU      1
R2       EQU      2
R3       EQU      3
R4       EQU      4
R5       EQU      5
R6       EQU      6
R7       EQU      7
R8       EQU      8
R9       EQU      9
SR1      EQU      8
SR2      EQU      9
SR3      EQU      10
SR4      EQU      11
D1       EQU      12
D2       EQU      13
D3       EQU      14
D4       EQU      15
         TITLE    'RECOVERY I/O ROUTINES'
         SREF     R:DCT9
         REF      R:DISCLIMS
         REF      DCTSIZ
         REF      R:DCT22
         REF      R:NSPT
         REF      R:NCYL
         REF      R:NTPC
         REF      R:CYL%SHFT
         REF      R:TRK%SHFT
         REF      R:SEC%SHFT
         REF      R:NSPC
         REF      HGP
         REF      S:DP
         SREF     UB:C#,S:CYLSZ
         SREF     RCBUF
         REF      DCT1,DCT2,CIT1,R:HGP
         REF      SMUIS,UB:SWAPI,MB:GAM5,MB:GAM6
         REF      M:GATLIM,M:GASLIM,MB:SDI,JOVVP
         REF      R:JXCMAP
         REF      MAPFLG
         SREF     RCVCTL
         CLOSE    PUSH,PULL
PUSH     CNAME    X'0B'
PULL     CNAME    X'0A'
         PROC
LF       EQU      %
TMP      SET      -2
         DO       NUM(AF)>1
         DO       AF(1)<16
         LCI      AF(1)
         ELSE
         LCI      0
         FIN
TMP      SET      0
         FIN
         GEN,8,4,20 NAME+TMP,AF(NUM(AF)),R:TSTACK
         PEND
         PCC      0
M9       DATA     X'1FF'
M24      DATA     X'FFFFFF'
M13      DATA     X'1FFF'
         PAGE
*P*      NAME:    RCVRIO
*P*      PURPOSE:
*DO*
*P*
* DISK IO SUBROUTINES - FOR SWAPPER DA FORMAT OR NORMAL FORMAT
*FIN*
*P*      DESCRIPTION:
*DO*
*P*
* NORMAL ENTRY - PARAMETERS - SWAPPER FORMAT ENTRY
* RDDISK          SIZE IN 15        RDRAD
*                 BUF = RCBUF
*                 DA IN 8
*
* RDDISK1         SIZE IN 3         RDRAD1
*                 BUF IN 4
*                 DA IN 8
*
* WRDISK          SIZE = 1024       WRRAD
*                 BUF IN 4
*                 DA IN 8
*
* WRDISK1         SIZE IN 3         WRRAD1
*                 BUF IN 4
*                 DA IN 8
*
* NORMAL EXIT IS *(R11+1), ERROR EXIT IS *11
*FIN*
*F*      NAME:        RDDISK
*F*      PURPOSE:     READ UP TP ONE GRANULE FROM A ROTATING
*F*                   MEMORY DEVICE INTO THE BUFFER RCBUF.
*F*      DESCRIPTION: R8 MUST CONTAIN A SYSTEM DISK ADDRESS.
*F*                   R15 MUST CONTAIN THE RECORD SIZE IN
*F*                   BYTES.  THIS RUNTIME CAN ONLY BE CALLED
*F*                   BY RECOVER1.
RDDISK   PUSH     16,0
         LW,3     15
         LI,4     RCBUF             SET BUFFER ADDRESS
         B        RDDISK10
*F*      NAME:        RDDISK1
*F*      PURPOSE:     READ UP TO ONE GRANULE FROM A ROTATING
*F*                   MEMORY DEVICE.
*F*      DESCRIPTION: R3 MUST CONTAIN THE RECORD SIZE IN
*F*                   BYTES. R4 MUST CONTAIN THE BUFFER ADDRESS
*F*                   R8 MUST CONTAIN A SYSTEM DISK ADDRESS.
RDDISK1  PUSH     16,0
RDDISK10 LW,1     RDMBS             NUMBERS TO MOVE CLIST TO
         MBS,1    RDOFF             WORK AREA.  MOVE EM.
RDDISK20 LI,1     1
         STH,3    WRADCL+3,1        SET SIZE IN CLIST
         BAL,11   RCHKDA            CHK DA FOR VALIDITY
         BCR,15   RDEREX            BAD DA, EXIT
         LDCTX,1  8                 DCTX                                DISCB
         LH,11    DCT1,1            GET DEV ADDR
         STW,11   RDEVAD
         LW,SR4   R:DCT9,R1         POST PROCESSING ADDRESS
         STW,SR4  POSTPROC
         BAL,11   R:DSCCVT          CONVERT TO SEEK
         BCR,15   RDEREX            ERR FROM R:DSCCVT
         STW,8    RDSEEK
         B        RDDISK50          GO CHECK FOR MAP
*F*      NAME:        WRDISK
*F*      PURPOSE:     WRITE ONE SECTOR TO A ROTATING MEMORY
*F*                   DEVICE.
*F*      DESCRIPTION: R4 MUST CONTAIN THE BUFFER ADDRESS.
*F*                   R8 MUST CONTAIN A SYSTEM DISK ADDRESS.
WRDISK   LI,3     1024              SET SIZE
*F*      NAME:        WRDISK1
*F*      PURPOSE:     WRITE UP TO ONE GRANULE TO A ROTATING
*F*                   MEMORY DEVICE.
*F*      DESCRIPTION: R3 MUST CONTAIN THE RECORD SIZE IN BYTES.
*F*                   R4 MUST CONTAIN THE BUFFER ADDRESS.
*F*                   R8 MUST CONTAIN A SYSTEM DISK ADDRESS.
WRDISK1  PUSH     16,0
         LW,1     RDMBS
         MBS,1    WROFF             MOVE PROPER CLIST TO WORK AREA
         B        RDDISK20
*F*      NAME:        RDRAD
*F*      PURPOSE:     READ UP TO ONE GRANULE FROM A SWAP RAD
*F*                   INTO THE BUFFER RCBUF.
*F*      DESCRIPTION: R8 MUST CONTAIN A RAD SEEK ADDRESS WITH
*F*                   USER NUMBER OR SWAP INEX.
RDRAD    PUSH     16,0
         LW,3     15                MOVE SIZE TO NORMAL REG
         LI,4     RCBUF             SET BUFFER
         B        RDRAD10
*F*      NAME:        RDRAD1
*F*      PURPOSE:     READ UP TO ONE GRANULE FROM A SWAP RAD.
*F*      DESCRIPTION: R3 MUST CONTAIN THE RECORD SIZE IN BYTES
*F*                   R4 MUST CONTAIN THE BUFFER ADDRESS.
*F*                   R8 MUST CONTAIN A RAD SEEK ADDRESS WITH
*F*                   USER NUMBER OR SWAP INDEX.
RDRAD1   PUSH     16,0
RDRAD10  LW,1     RDMBS
         MBS,1    RDOFF
RDRAD20  LI,1     1
         STH,3    WRADCL+3,1        SET SIZE
         LI,0     RDDISK50          SET SUBR RETURN
CKRAD1   EQU      %
         LB,1     8                 GET USER #
         BNEZ     CKRAD11           YES
         LI,2     1                 NO-
         LB,2     8,2                  SWAPX FROM BYTE 1
         B        RDRAD30
CKRAD11  EQU      %
         CI,1     SMUIS             LEGAL NUMBER
         BG       RDEREX            BR IF NOT
         LB,2     UB:SWAPI,1        RAD PARAMETER TABLE INDEX
RDRAD30  LB,5     MB:GAM5,2         SHIFT COUNT
         INT,1    8                 AND ADDRESS
         SLS,1    0,5               RIGHT JUSTIFY TRACK #
         CW,1     M:GATLIM,2        VALID
         BG       RDEREX            NO, TAKE ERROR EXIT
         LB,1     MB:GAM6,2         SECTOR MASK
         AND,1    8
         CW,1     M:GASLIM,2        SECTOR VALID
         BG       RDEREX            NO, TAKE ERROR EXIT
         LB,1     MB:SDI,2          DCTX OF RAD
         LH,11    DCT1,1
         STW,11   RDEVAD            SET DEV ADDRESS
         LW,SR4   R:DCT9,R1         POST PROCEESING ADDRESS
         STW,SR4  POSTPROC
         STH,8    RDSEEK            AND SEEK ADDRESS
         B        *0                RETURN
*
*        R4 HAS BUFFER ADDRESS, SET IN CLIST AND
*        CHECK FOR MAPPING
*
RDDISK50 SLS,4    2                 BYTE ADDRESS
         LW,5     M24
         STS,4    WRADCL+2
         LW,5     MAPFLG            IS CORE MAPPED
         BEZ      NOMAP             NO
         STB,R1   RDEVAD            SAVE DCTX
         SLD,4    -11               PAGE NO. SAVE BITS IN 5
         AND,4    M13
         CI,4     JOVVP
         BL       NOMAP
         LOAD,R6  R:JXCMAP,R4
         STW,5    7
         SLD,6    11
         LW,7     M24
         STS,6    WRADCL+2
         SLD,4    11                VIRTUAL BYTE ADDRESS
         LW,7     4                 SAVE ADDR FOR POSSIBLE DATA CHAIN
         AW,4     3
         AI,4     -4                END ADDRESS
         SLS,4    -11
         LOAD,R5  R:JXCMAP,R4
         SLS,6    -11               FIRST PP
         CW,6     5
         BE       NOMAP
         SLS,4    11                YEA FOR DATA CHAIN
         SW,4     7                 BYTE COUNT IN FIRST PAGE
         LI,1     1
         STH,4    WRADCL+3,1
         SW,3     4                 BYTE COUNT IN SECOND PAGE
         STH,3    WRADCL+5,1
         LW,6     5                 PP OF SECOND PAGE
         SLS,6    11                BA OF SECOND PAGE
         LW,7     M24
         STS,6    WRADCL+4
         LI,7     X'80'
         STB,7    WRADCL+3          DATA CHAIN FLAG
NOMAP    LI,0     RCVCTL            RECOVER
         BNEZ     DOSIO             YES, SKIP RELOCATING CLIST
         LI,0     WRADCL            NO, MUST MAKE CLIST BE IN 1
         AND,0    M9                PAGE, AND GET THE PHYSICAL
         LI,3     WRADCL            ADDRESS OF CLIST.
         CI,0     512-6             ALREADY IN ONE PAGE
         BLE      NOMAP10           YES, GO RELOCATE
         LW,1     RELMBS            NO, MOVE CLIST TO NEW AREA
         MBS,1    6*4
         LI,3     WRADCL1           NEW CLIST ADDRESS
NOMAP10  SCD,2    -9                SAVE BITS, GET VIRT PAGE
         LOAD,R3  R:JXCMAP,R3       GET THE PHYSICAL PAGE
         SCD,2    8                 BACK TO DWD ADDRESS
         LW,0     3
         B        DOSIO1            GO DO THE IO
DOSIO    LI,0     DA(WRADCL)
DOSIO1   LI,1     RCVCTL
         BNEZ     DOSIO4
         LI,2     X'2000'           LOOP COUNTER
         LB,R3    RDEVAD            DCTX OF IO DEVICE
         LB,R3    DCT2,R3           CHANNEL INDEX OF THE FIRST SWAPPER
DOSIO2   DISABLE
         MTB,0    CIT1,R3           CHANNEL BUSY
         BEZ      DOSIO4            NO-START THE IO
         ENABLE
         LI,1     256               DEVICE IS BUSY, WAIT
         BDR,1    %
         BDR,2    DOSIO2
RDEREX   LI,0     RCVCTL
         BNEZ     %+2
         ENABLE
         PULL     16,0
         B        *11
DOSIO4   BAL,SR4  STRTIO            DO IO WITH ERROR CHECKING
         LI,1     RCVCTL
         BEZ      %+2               CANT POST PROCESS IN GHOST1
         B        *POSTPROC         GO TO POST PROCESSING ROUTINE
         ENABLE
DISCCU   EQU      %
POSTRTN  EQU      %
         PULL     16,0
         AI,11    1                 INCREMENT RETURN
         B        *11
*
STRTIO   EQU      %
         LI,R1    10                ERROR RE-TRY COUNT
RETRY    :SIO,0   *RDEVAD           START THE I/O
         BCS,12   RDEREX            ERROR, SIO REJECTED
         LI,R2    X'2000'           LOOP COUNTER
AGAIN3   LI,R4    41
         BDR,R4   %                 WAIT
         :TIO,R3  *RDEVAD           TEST I/O
         BCR,12   AGAIN4            I/O COMPLETE
         BDR,R2   AGAIN3
         :HIO,0   *RDEVAD           HALT THE DEVICE
         B        RDEREX            ERROR-TIME OUT
AGAIN4   EQU      %
         SLS,R3   -16               SHIFT OFF BYTE COUNT
         CI,R3    X'7E'             TIO RETURN ERRORS
         BAZ      *SR4              NO-RETURN
         BDR,R1   RETRY             YES-TRY AGAIN
         B        RDEREX            ERROR-RE-TRY COUNT EXCEDED
*
*
DPAKCU   EQU      %
DSKABCU  EQU      %
         :TDV,R1  *RDEVAD           GET DEVICE STATUS
         BCS,X'C' RDEREX            ERROR-TDV REJECTED
         LC       R1
         BCR,4    POSTRTN           NO FLAWED TRACK INDICATED
         LI,R0    DA(HEADERRD)      HEADER READ COMMAND
         BAL,SR4  STRTIO            GO READ HEADER BYTES
         LB,R1    HEADER
         CI,R1    X'FF'             FLAWED TRACK MARK
         BNE      RDEREX            NO-ERROR-NOT CORRECT HEADER
         LD,R2    HEADER
         SLD,R2   8
         CW,R2    RDSEEK            CORRECT HEADER
         BNE      RDEREX            NO-ERROR-NOT CORRECT HEADER
         LW,R2    HEADER+1
         AND,R2   =X'00FFFF00'      GET ALTERNATE CYLINDER AND HEAD
         CI,R2    X'8000'           MOVE HIGH ORDER BIT
         BAZ      %+3               NO
         EOR,R2   =X'8000'
         OR,R2    =X'1000000'       YES-MOVE TO HIGH END OF CYLINDER
         LW,R3    =X'01FFFF00'
         STS,R2   RDSEEK            UPDATE  SEEK WITH ALTERNATE: CYL, HEAD
         B        DOSIO             RE DO IO WITH NEW SEEK ADDRESS
         PAGE
*F*      NAME:        WRRAD
*F*      PURPOSE:     WRITE ONE SECTOR TO A SWAP RAD.
*F*      DESCRIPTION: R4 MUST CONTAIN THE BUFFER ADDRESS.
*F*                   R8 MUST CONTAIN A RAD SEEK ADDRESS WITH
*F*                   USER NUMBER OR SWAP INDEX.
WRRAD    LI,3     1024              SET SIZE
*F*      NAME:        WRRAD1
*F*      PURPOSE:     WRITE UP TO ONE GRANULE TO A SWAP RAD.
*F*      DESCRIPTION: R3 MUST CONTAIN THE RECORD SIZE IN BYTES.
*F*                   R4 MUST CONTAIN THE BUFFER ADDRESS.
*F*                   R8 MUST CONTAIN A RAD SEEK ADDRESS WITH
*F*                   USER NUMBER OR SWAP INDEX.
WRRAD1   PUSH     16,0
         LW,1     RDMBS
         MBS,1    WROFF             PROPER CLIST TO WORK AREA
         B        RDRAD20
*F*      NAME:        CKRAD
*F*      PURPOSE:     CHECK THE VALIDITY OF A SWAP RAD SEEK
*F*                   ADDRESS.
CKRAD    PUSH     16,0
         MTW,0    S:DP              PACK SWAPPER
         BNEZ     %+2               YES-RETURN
         BAL,0    CKRAD1
         PULL     16,0
         AI,11    1
         B        *0
*
         PAGE
*F*      NAME:        WRUSRI/RDUSRI
*F*      PURPOSE:     WRITE/READ UP TO A GRANULE WITH THE PACK
*F*                   SWPPER.
*F*      DESCRIPTION: R3 MUST CONTAIN TH RECORD SIZE IN BYTES.
*F*                   R4 MUST CONTAIN THE BUFFER ADDRESS.
*DO*
*F*
*  IF RAD SYS  8=DA AND GOES RIGHT TO RAD IO
*  IF DP SYS  CREATES REL SECT # FROM GRAN # REL TO BEG OF
*             USER'S CYL
*  I  7  = USER NUMBER
*  I  8  = REL GRAN # FROM BEG OF USERS CYL
*FIN*
WRUSR1   MTB,1    11
RDUSR1   EQU      %
         MTW,0    S:DP
         BNEZ     RDWRUSR2
         MTB,0    11
         BEZ      RDRAD1
         B        WRRAD1
RDWRUSR2 EQU      %
         PUSH     9
         LB,9     UB:C#,7
         BNEZ     %+2               NOT ALLYCAT
         AI,8     2                 ADD ACAT SECTOR BIAS
         MW,9     S:CYLSZ           9=# GRAN TO BEG OF USR CYL
         AW,8     9                 REL GRAN #
         SLS,8    1                 SECT
         LB,9     MB:SDI
         STH,9    8
         PULL     9
         MTB,0    11
         BEZ      RDDISK1
         B        WRDISK1
         PAGE
*F*      NAME:        WRRAD2
*F*      PURPOSE:     SPECIAL ENTRY POINT FOR IOQFLUSH TO
*F*                   COMPLETE QUED OUTPUT AT TIME OF RECOVERY.
*F*      DESCRIPTION:
*DO*
*F*
*                 2  - DCTX
*                 3  - SIZE
*                 4  - BA(BUFFER)
*                 8-   SEEK
*FIN*
WRRAD2   EQU      %
         PUSH     16,0              SAVE ALL REGISTERS
         BAL,11   CHKSEEK           GO-CHECK THE SEEK ADDRESS
         B        RDEREX            ERROR- SEEK NO GOOD
         LW,1     RDMBS
         MBS,1    WROFF             SET UP WRITE COMMAND LIST
         LI,1     1
         STH,3    WRADCL+3,1        PUT SIZE IN COMMAND LIST
         LH,11    DCT1,2            DEVICE ADDRESS
         STW,11   RDEVAD            FOR COMMAND LIST
         LW,SR4   R:DCT9,R2         POST PROCESSING ADDRESS
         STW,SR4  POSTPROC
         STW,8    RDSEEK            SEEK ADDRESS
         B        RDDISK50+1
         PAGE
*
RDSEEK   EQU      X'10'
RDEVAD   DATA     0
         BOUND    8
WRADCL1  RES      6                 ALTERNATE CLIST AREA
WRADCL   RES      6
WROFF    EQU      BA(%)-BA(WRADCL)
         GEN,8,24 3,4*RDSEEK
         GEN,8,24 X'2A',4
         GEN,8,24 1,0
         GEN,8,24 0,0
         GEN,8,24 1,0
         GEN,8,24 0,0
RDOFF    EQU      BA(%)-BA(WRADCL)
         GEN,8,24 3,4*RDSEEK
         GEN,8,24 X'2A',4
         GEN,8,24 2,0
         GEN,8,24 0,0
         GEN,8,24 2,0
         GEN,8,24 0,0
RDMBS    GEN,8,24 6*4,BA(WRADCL)
RELMBS   GEN,8,24 6*4,BA(WRADCL1)
*
*
         BOUND    8
HEADERRD GEN,8,24 3,4*RDSEEK
         GEN,8,24 X'2A',4
         GEN,8,24 X'0A',BA(HEADER)
         GEN,8,24 0,8
HEADER   DATA     0,0
POSTPROC DATA     0                 POST PROCESSING ROUTINE ADDRESS
         PAGE
         REF      AVRTBL,AVRTBLNE,AVRTBLSIZ
*F*      NAME:        RCHKDA
*F*      PURPOSE:     CHECK VALIDITY OF SYSTEM DISK ADDRESS
*F*                   WITH AN ASSOCIATED DCB.
*F*      DESCRIPTION: R6 MUST CONTAIN THE DCB ADDRESS.
*F*                   R8 MUST CONTAIN THE SYSTEM DISK ADDRESS.
RCHKDA   EQU      %
         PUSH     5,R3
         LI,R3    RCVCTL
         BEZ      R:CHKDA1          NO PRIVATE PACK I/O IN RECOVER2
         MTW,0    CLSPRI
         BEZ      R:CHKDA1          PRIVATE PACK NOT ALLOWED
         LI,R3    DCBPRIVBIT
         CW,R3    0,R6              IS IT PRIVATE
         BAZ      R:CHKDA1          NO
*
*  CONVERT PRIVATE DISC ADDRESS TO PUBLIC
*
         LDCTX,R3 R8                GET VOLUME #
         LI,R4    BAVSND
         LB,R4    *R6,R4            INDEX TO SN LIST
         AW,R4    FLP,R6            POINT TO SN LIST
         AND,R4   =X'1FFFF'         MASK BITS FOR BIG9
         LI,R5    2
         CB,R3    *R4,R5
         BG       CHKDA3            VOL # GREATER THAN # VOLUMES
*
         LI,R5    AVRTBLNE-AVRTBLSIZ+1
FND9     AI,R5    -1
         BEZ      CHKDA3            NO MORE AVR ENTRIES
         LD,R6    AVRTBL+AVRTBLSIZ+AVRTBLSIZ+2,R5
         INT,R7   R7                GET FLAGS AND HGP DISPL
         BCR,2    FND9              NOT AVR'D
         CW,R6    *R4,R3            CHECK FOR SERIAL # MATCH
         BNE      FND9              NO
         AI,R7    R:HGP             POINT TO HGP
         LI,R5    5
         LB,R5    *R7,R5            DCTX FROM HGP
         STDCTX,R5 R8               PUT IN DISC ADDRESS
         AI,R7    HGP-R:HGP         POINT TO IN-CORE HGP
         LW,R4    R6
         LW,R6    R7
         LI,R7    X'1FFFF'
         STS,R6   PAT,R4            SAVE HGP ADDRESS IN DCB
         B        R:PVCHKDA
*
CLSPRI   DATA     0
*F*      NAME:        R:CHKDA
*F*      PURPOSE: CHECK DA IN R8 FOR VALIDITY.
*F*      DESCRIPTION:
*DO*
*F*
*        CC = 0 IF DA IS BAD
*        CC = F IF DA IS NOT BAD
*        LINK R11
*        NO VOLATILE REGS
*FIN*
R:CHKDA  PUSH     5,3
R:CHKDA1 BAL,R3   R:FNDHGP          LOCATE THE HGP
         BEZ      CHKDA3            NO HGP IS AN ERROR
R:PVCHKDA EQU     %                                                     DISCB
*                                   R5 HAS DCT INDEX SET BY R:FNDHGP/FND9DISCB
         LB,3     R:DCT22,5         GET DISC SUBTYPE
         BNEZ     CHKDA2              OK                                DISCB
CHKDA3   PULL     5,3               ERROR EXIT
         LCI      0
         B        *11
CHKDA2   EQU      %                                                     DISCB
         LSECTA,5  8                GET RELATIVE SECTOR #               DISCB
         CW,5     R:DISCLIMS,3      TOO BIG IS AN ERROR
         BGE      CHKDA3
         PULL     5,3
         LCI      15
         B        *11
*
         PAGE
*F*      NAME:        R:FNDHGP
*F*      PURPOSE: FIND HGP FOR DA IN R8.
*F*      DESCRIPTION:
*DO*
*F*
*        RETURNS ADDRESS IN R7
*        LINK R3
*        SETS CC VIA LW,7     7  BEFORE EXITING
*        USES R5,R6
*FIN*
R:FNDHGP PUSH     R6
         LI,R6    5
         LI,7     R:HGP
         LDCTX,5  8                 GET DCT INDEX                       DISCB
FNDHGP1  CB,5     *7,6
         BE       FNDHGP2
         LW,7     0,7
         BNEZ     FNDHGP1
FNDHGP2  PULL     R6
         AI,R7    0                 SET CC
         B        0,3
         PAGE
****************************************************************
*
*F*      NAME:        R:DSCCVT
*F*      PURPOSE: CONVERT A SYSTEM DISK ADDRESS TO A SEEK ADDERSS.
*F*      DESCRIPTION:
*DO*
*F*
*
*        ENTRY POINT:               R:DSCCVT
*
*        CALLING SEQUENCE:          BAL,R11   R:DSCCVT
*
*        INPUT:                     R8 = INTERNAL DISC ADDRESS
*
*        OUTPUT:                    R8 = SEEK ADDRESS
*                                   CC = 0 ERROR
*                                   CC NOT = 0 OK
*
*        REGISTERS DESTROYED:       NONE
*FIN*
*
****************************************************************
*
*
R:DSCCVT EQU      %
         PUSH     2,R6              SAVE REGISTERS
         PUSH     R9
         LDCTX,R7 R8                GET DCT INDEX
         BLEZ     CONVERT%ERR       ZERO OR NEGATIVE--ERROR
         CI,R7    DCTSIZ            CHECK FOR VALID MAX
         BG       CONVERT%ERR         INVALID
         LB,R6    R:DCT22,R7        GET DISC SUB-TYPE
         BEZ      CONVERT%ERR         INVALID TYPE
         LSECTA,R9 R8               GET SECTOR ADDRESS
         CW,R9    R:DISCLIMS,R6     TEST FOR MAX ON DEVICE
         BL       CONVERT             VALID
*
CONVERT%ERR EQU   %
         LCI      0
         B        CONVERT%RETURN    RETURN WITH ERROR COND CODES
*
CONVERT   EQU       %
          LI,R8     0
*                   RELATIVE SECTOR NO. IN R9
          DW,R8     R:NSPC,R6           REL.SEC./NO.SEC.PER CYL
          LW,R7     R9
*                                       R7=CYLINDER NO.
*                                       REMAINDER<TRACKS& SECTORS>
          LW,R9     R8
          LI,R8     0
          DW,R8     R:NSPT,R6
*                                       R8=SECTOR NO.
*                                       R9=TRACK NO.
          EXU,0     R:CYL%SHFT,R6       PERFORM CYL. SHIFT
          EXU,0     R:TRK%SHFT,R6       PERFORM TRK SHIFT
          EXU,0     R:SEC%SHFT,R6       PERFORM SECTOR SHIFT
*
*         COMBINE CYL-TRK-SECTOR
*
          OR,R8     R7
          OR,R8     R9                  REAL SEEK ADDRESS TO R8
          LCI       3
CONVERT%RETURN EQU  %
         STCF     11                SAVE RETURN CONDITION CODES
         PULL     R9                RESTORE ALL
         PULL     2,R6                 REGISTERS
         LC       11                RESTORE  CONDITION CODES
         B        *11               RETURN
*
         PAGE
CHKSEEK  PUSH     16,R0             SAVE ALL REGISTERS
         LI,R1    5                 POINT TO DCT FIELD IN HGP
         LI,R3    R:HGP
KRD8     CB,R2    *R3,R1            DCTX MATCH
         BE       KRD9              YES-GET NST TO FIND DEVICE TABLES
         LW,R3    *R3               NO-FLINK TO NEXT HGP
         BNEZ     KRD8                 AND CHECK IT
ERRRTN   PULL     16,R0             ERROR-DCTX NOT FOUND IN HGPS
         B        *SR4              RETURN BAL+1
KRD9     EQU      %
         LB,R3    R:DCT22,R2        GET SUBTYPE OF DISC
         BEZ      ERRRTN             ERROR IF ZERO
         LW,R9    R8
         LI,R8    0
         LW,R4    R:NCYL,R3         GET # CYL ON DEVICE
         BEZ      NO%CYL%ON%DEV
         LI,R5    32                COMPUTE CYL SIZE
         LI,R6    X'7F'
         AND,R6   R:CYL%SHFT,R3     GET CYL SHIFT FACTOR
         SW,R5    R6                R5 = SIZE OF CYLIDER
         SLD,R8   0,R5              GET CYL PORTION IN R8
*        COMPUTE MAXIMUM ALTERNATE TRACK = # CYL / 16
         LW,R7    R4
         SLS,R7   -4                R7 = # CYL * 1/16
         AW,R4    R7
         CW,R8    R4                ACTUAL CYL VS. MAX COMPUTED CYL
         BG       ERRRTN            ACTUAL GREATER THAN MAX--ERROR
TRK%CHECK EQU     %
         LI,R5    X'7F'             COMPUTE TRACK SHFT AMT
         AND,R5   R:TRK%SHFT,R3
         SW,R6    R5                R5 = DIFF BETWEEN CYL + TRACK
         LI,R8    0
         SLD,R8   0,R6              R8 = TRK ADDRESS
         CW,R8    R:NTPC,R3         TEST AGAIST MAX
         BGE      ERRRTN            GREATER THAN OF EQUAL TO MAX
         LI,R6    X'7F'
         AND,R6   R:SEC%SHFT,R3
         SW,R5    R6                R5 = DIF BETWEEN TRK AND SEC
         LI,R8    0
         SLD,R8   0,R5
         CW,R8    R:NSPT,R3
         BGE      ERRRTN
RETURN   EQU      %
         PULL     16,R0
         AI,SR4   1
         B        *SR4
NO%CYL%ON%DEV EQU %
         LI,R6    32                SET UP FOR RAD
         B        TRK%CHECK
         PAGE
         BOUND    8
R:TSTACK DATA     %+1
         GEN,16,16 35,0
         RES      35
         END

