@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP2023
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP2023
~S1~M~OAP2 IMPLEMENTATION DESCRIPTION~
~S1~M~OSection 2  Version 3~
~S1~OSection 2.3 Drum Appendix (RK07)~
~S1~O1. General Description~
~BThis module is concerned with driving the disc interface
described in SYS Section 3 (Drum Manager). The disc in this
instance is an RK07 disc subsystem, which is
described in Digital's "Peripherals Handbook 1980".~
~S1~O2. Interfaces~
Other modules used~
   SYS Section 1 (Coordinator)~
   SYS Section 12 (System Error)~
   SYS Section 14 (Virtual Store Manager)~
Ideal hardware registers used~
   V.DRUM.CONTROL~
   V.DRUM.SIZE~
   V.DRUM.C.ADDRESS~
   V.DRUM.D.ADDRESS~
RK07 hardware registers used~
   (AP2 name)              (DEC name)~
   V.RK07.CSR                 RKCS1~
   V.RK07.COUNT               RKWC~
   V.RK07.CADRR               RKBA~
   V.RK07.DADDR               RKDA~
   V.RK07.STAT1               RKCS2~
   V.RK07.STAT2               RKDS~
   V.RK07.CYL                 RKDC~
Interrupt procedures~
   RK07.DISC.INT (DUMMY)~
Interface procedures~
   None~
Interface variables~
   None~
Configuration parameters~
   MAX.BLOCK.DRUM.XFER~
   DRUM.FIRST.UNIBUS.PAGE.NO~
~S1~O2.1 MUSS Interface~
~S1~O2.1.1 Hardware Interface~
~BThe ideal hardware registers are
described in SYS Section 3.~
~S1~O2.1.2 Software Interface~
~S11) RK07.DISC.INT (DUMMY)~
~BThis procedure services RK07 interrupts
and is called by the system when such an
interrupt is detected.~
~S1~O2.2 RK07 Interface~
~BSee Peripherals Handbook.~
~S1~O3. Implementation~
~S1~O3.1 Outline of Implementation~
~BThe procedures which are private to this module are of two
kinds: those which are common to the VAX and PDP11 implementations
and those which are specific to the VAX.~
~S1~O3.1.1 Machine Independent Procedures~
~S11) DISC.CONTROL.POST.PROC~
~BThis procedure translates ideal
disc commands into RK07 commands.~
~S12) START.TRANSFER ()~
~BThis procedure evaluates the drum
and UNIBUS addresses and initiates the transfer.~
~S1~O3.1.2 VAX Procedures~
~S13) DRUM.C.ADDRESS.POST.PROC~
~BThis procedure loads the number of
the page to be transferred into a
page map register and replaces it
with the UNIBUS 'page number'
associated with that map register.~
~S14) CLEAR.DRUM.BUFFERS.PRE.PROC~
~BThis procedure sets the page map registers used in a transfer
to 'invalid' and clears any associated error flags.~
~S1~O3.2 Data Structures~
~T%37
~
~
SCALE~IAn integer 'constant' giving the page size / sector size ratio.~
~
DISC.STATUS~IA logical variable giving the status of the disc
as follows,~
~I0 = IDLE, 1 IN TRANSFER.~
~
C.ADDRESS~IA logical variable used in DRUM.C.ADDRESS.POST.PROC.~
~
COUNT~IAn integer variable used in DRUM.C.ADDRESS.POST.PROC and
 CLEAR.DRUM.BUFFERS.PRE.PROC.~
~
V.CLEAR.DRUM.BUFFERS~IVAX - A V-line used to invoke
CLEAR.DRUM.BUFFERS.PRE.PROC.~
~IPDP11 - A logical dummy variable.~
~S1~O3.3 Special Notes~
~BThe machine-dependent code used in
driving the 'drum' is contained in the
machine functions:~
~
~MINHIBIT.INTERRUPTS~
~NALLOW.INTERRUPTS~
~NMAP.IO.APP
~NUNMAP.IO.APP
~BMAP.IO.APP and UNMAP.IO.APP simulate paging of the IO Appendix on
the PDP 11/34, which is an unpaged machine. They have no action on the
VAX which is a paged machine.~
~BThis implementation uses Bufferred Data Path 1 (BDP1)
of the VAX data paths for drum transfers. The mask 80200000}16{ in
DRUM.C.ADDRESS.POST.PROC sets the appropriate page map register
to use this data path.~
~Y
~V9 -1
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H               AP2023
~V9 -1
~F
@TITLE AP202.VAX(3,10)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
VAX11 (RK07) DRUM APPENDIX
@BOX 4.0
PROCEDURES IN MODULE:
   1 DRUM CONTROL POST PROC
   2 DISC CONTROL POST PROC
   3 SET TRAN MAP PRE PROC
   4 CLEAR TRAN MAP PRE PROC
   5 RK07 DISC INT
   6 START TRANSFER
   7 RK07 POLL
@BOX 6.0
END
@BOX 1.1
#AP202/1
MODULE (V.DISC.CONTROL, V.DISC.DADDRESS, V.DISC.CADDRESS, V.DISC.SIZE,
   RK07.DISC.INT, RK07.POLL, V.DRUM.CONTROL, V.DRUM.DADDRESS, V.DRUM.CADDRESS,
   V.DRUM.SIZE, V.DRUM.SECTION);
@BOX 2.1
TYPE BAD.BLOCKS.TYPE IS
   LOGICAL [NO.OF.BAD.BLOCKS] BAD.BLOCK, SUBSTITUTE.BLOCK
   INTEGER BAD.BLOCK.COUNT;
@BOX 3.1
*GLOBAL 5;
LITERAL / INTEGER SECTOR.SIZE = 512, RK07.SIZE = 53790;
LOGICAL [NO.OF.RK07S] DISC.CONTROL, DISC.DADDRESS, DISC.CADDRESS,
   DISC.SIZE;
LOGICAL VV.DRUM.CONTROL, VV.DRUM.DADDRESS, VV.DRUM.CADDRESS,
   VV.DRUM.SIZE, VV.DRUM.SECTION;
LOGICAL [NO.OF.ED.UNITS] VV.DISC.CONTROL, VV.DISC.DADDRESS, VV.DISC.CADDRESS,
   VV.DISC.SIZE;
LOGICAL DUMMY;
VSTORE V.DISC.CONTROL [NO.OF.ED.UNITS] VV.DISC.CONTROL > DISC.CONTROL.POST.PROC;
VSTORE V.DISC.DADDRESS [NO.OF.ED.UNITS] VV.DISC.DADDRESS;
VSTORE V.DISC.CADDRESS [NO.OF.ED.UNITS] VV.DISC.CADDRESS;
VSTORE V.DISC.SIZE [NO.OF.ED.UNITS] VV.DISC.SIZE;
VSTORE V.DRUM.CONTROL VV.DRUM.CONTROL > DRUM.CONTROL.POST.PROC;
VSTORE V.DRUM.DADDRESS VV.DRUM.DADDRESS;
VSTORE V.DRUM.CADDRESS VV.DRUM.CADDRESS;
VSTORE V.DRUM.SIZE VV.DRUM.SIZE;
VSTORE V.DRUM.SECTION VV.DRUM.SECTION;
VSTORE SET.TRAN.MAP DUMMY < SET.TRAN.MAP.PRE.PROC;
VSTORE CLEAR.TRAN.MAP DUMMY < CLEAR.TRAN.MAP.PRE.PROC;
*VTYPE LOGICAL16;
VSTORE V.RK07.CSR %80001F20;
VSTORE V.RK07.COUNT %80001F22;
VSTORE V.RK07.CADDR %80001F24;
VSTORE V.RK07.DADDR %80001F26;
VSTORE V.RK07.STAT1 %80001F28;
VSTORE V.RK07.STAT2 %80001F2A;
VSTORE V.RK07.ATTN %80001F2E;
VSTORE V.RK07.CYL %80001F30;
*VTYPE LOGICAL;
LOGICAL TRAN.STATUS, C.ADDRESS;
LOGICAL [NO.OF.RK07S] DISC.STATUS;
INTEGER [NO.OF.RK07S] SEEK.TIMEOUT;
INTEGER COUNT, DISC.UNIT, TRAN.UNIT, TRAN.SIZE, HW.INT.COUNT,
   POLL.COUNT;
LOGICAL [NO.OF.BAD.BLOCKS] BAD.BLOCK, SUBSTITUTE.BLOCK;
LOGICAL8 [NO.OF.ED.UNITS] POLL.REQ;
BAD.BLOCKS.TYPE [NO.OF.DRUM.SECTIONS] BAD.BLOCKS;
@BOX 4.1
*CODE 2;
:: PSPEC DRUM.CONTROL.POST.PROC ();
:: PSPEC DISC.CONTROL.POST.PROC ();
:: PSPEC SET.TRAN.MAP.PRE.PROC ();
:: PSPEC CLEAR.TRAN.MAP.PRE.PROC ();
PSPEC RK07.DISC.INT (INTEGER);
PSPEC START.TRANSFER ();
PSPEC RK07.POLL ();
   #AP202.1
   #AP202.2
   #AP202.3
   #AP202.4
*CODE 23;
   #AP202.5
   #AP202.6
   #AP202.7
@BOX 5.1
*CODE 7;
BEGIN
PSPEC INIT.AP202 ();
PROC INIT.AP202;
INTEGER I, UNIT, DRIVE.STATE;
TYPE BAD.BLOCK.TABLE.TYPE IS LOGICAL BAD.BLK, SUBST.BLK
   OR LOGICAL TABLE.SIZE;
ADDR [BAD.BLOCK.TABLE.TYPE] BAD.BLOCK.TABLE;
FOR UNIT < NO.OF.DRUM.SECTIONS DO
   IF DRUM.SECTION.AVAILABLE [UNIT] /= 0 THEN
      MAKE (BAD.BLOCK.TABLE.TYPE, NO.OF.BAD.BLOCKS,UNIT * SECTOR.SIZE
          + BAD.BLOCK.TABLE.ADDR)=> BAD.BLOCK.TABLE;
      SELECT BAD.BLOCKS [UNIT];
      FOR I < NO.OF.BAD.BLOCKS DO
         -1 => BAD.BLOCK [I];
      OD
      TABLE.SIZE OF BAD.BLOCK.TABLE^ [NO.OF.BAD.BLOCKS - 1] => BAD.BLOCK.COUNT;
      FOR I < BAD.BLOCK.COUNT DO
         BAD.BLK OF BAD.BLOCK.TABLE^ [I] => BAD.BLOCK [I];
         SUBST.BLK OF BAD.BLOCK.TABLE^ [I] => SUBSTITUTE.BLOCK [I];
      OD
   FI
OD
FOR I < NO.OF.ED.UNITS DO
   IF I + 1 => UNIT > NO.OF.DRUM.SECTIONS OR
      DRUM.SECTION.AVAILABLE [UNIT] = 0 THEN
      %8000 => DISC.STATUS [UNIT] => VV.DISC.CONTROL [I];
   FI
OD
END
INIT.AP202 ();
END
@BOX 6.1
*END
@END
@TITLE AP202.PDP11(3,10)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
PDP11 (RK07) DISC APPENDIX
@BOX 4.0
PROCEDURES IN MODULE:
   1 DISC CONTROL POST PROC
   4 RK07 DISC INT
   5 START TRANSFER
@BOX 6.0
END
@BOX 1.1
#AP202/1
MODULE (V.DISC.CONTROL, V.DISC.DADDRESS, V.DISC.CADDRESS, V.DISC.SIZE, RK07.DISC
.INT);
@BOX 3.1
*GLOBAL 5;
LOGICAL VV.DISC.CONTROL, VV.DISC.DADDRESS, VV.DISC.CADDRESS, VV.DISC.SIZE;
VSTORE V.DISC.CONTROL VV.DISC.CONTROL > DISC.CONTROL.POST.PROC;
VSTORE V.DISC.DADDRESS VV.DISC.DADDRESS;
VSTORE V.DISC.CADDRESS VV.DISC.CADDRESS;
VSTORE V.DISC.SIZE VV.DISC.SIZE;
LOGICAL V.CLEAR.DISC.BUFFERS;:: DUMMY REGISTER
VSTORE V.RK07.CSR %FF20;
VSTORE V.RK07.COUNT %FF22;
VSTORE V.RK07.CADDR %FF24;
VSTORE V.RK07.DADDR %FF26;
VSTORE V.RK07.STAT1 %FF28;
VSTORE V.RK07.STAT2 %FF2A;
VSTORE V.RK07.CYL %FF30;
LOGICAL DISC.STATUS;
INTEGER SCALE;
@BOX 4.1
*CODE 2;
:: PSPEC DISC.CONTROL.POST.PROC ();
PSPEC RK07.DISC.INT (INTEGER);
PSPEC START.TRANSFER ();
   #AP202.1
*CODE 23;
   #AP202.4
   #AP202.5
@BOX 5.1
*CODE 7;
BEGIN
SYS14.PAGE.SIZE / 512 => SCALE;
END
@BOX 6.1
*END
@END
@TITLE AP202/1(3,10)
@COL 1S-2R-3R-4R
@FLOW 1-2-3-4
@BOX 1.0
OTHER MODULES REFERENCED
@BOX 4.0
SYS01 COORDINATOR
SYS12 SYSTEM ERROR
SYS14 VIRTUAL STORE MANAGER
@BOX 1.1
:: EXTERNAL ENVIRONMENT
@BOX 2.1
IMPORT LITERAL DRUM.FIRST.UNIBUS.PAGE.NO, MAX.BLOCKS.DRUM.XFER,
   NO.OF.RK07S, NO.OF.ED.UNITS, NO.OF.DRUM.SECTIONS;
IMPORT LITERAL NO.OF.BAD.BLOCKS, BAD.BLOCK.TABLE.ADDR;
IMPORT VSTORE V.DRUM.PAGE.MAP [], V.DRUM.BDP.CSR;
IMPORT VSTORE ALLOW.INTERRUPTS, INHIBIT.INTERRUPTS, MAP.IO.APP, UNMAP.IO.APP;
LOGICAL8 [NO.OF.DRUM.SECTIONS] DRUM.SECTION.AVAILABLE;
@BOX 3.1
PSPEC SET.HW.INT (LOGICAL);
PSPEC CLEAR.HW.INT (LOGICAL);
@BOX 4.1
IMPORT LITERAL SYS01.DRUM.ACTIVITY, SYS01.DISC.ACTIVITY;
PSPEC SYS12.SYSTEM.ERROR (INTEGER);
IMPORT LITERAL SYS14.PAGE.SIZE;
@END
@TITLE AP202.1(3,11)
@COL 1S-2R-3R-4T-5R-6R-7F
@FLOW 1-2-3-4NO-5-6-7
@FLOW 4YES-6
@BOX 1.0
DRUM CONTROL POST PROC
@BOX 2.0
INHIBIT INTERRUPTS
@BOX 3.0
CLEAR HW INT
[AP201]
@BOX 4.0
COMMAND BITS CLEAR?
@BOX 5.0
NOTE CORE ADDRESS, DISC ADDRESS
AND DISC SIZE.
START TRANSFER
[AP202.3]
@BOX 6.0
ALLOW INTERRUPTS
@BOX 7.0
END
@BOX 1.1
PROC DRUM.CONTROL.POST.PROC;
@BOX 2.1
INHIBIT.INTERRUPTS;
@BOX 3.1
CLEAR.HW.INT (SYS01.DRUM.ACTIVITY);
@BOX 4.1
VV.DRUM.SECTION => DISC.UNIT;
DISC.STATUS [DISC.UNIT] & %8000 ! VV.DRUM.CONTROL => DISC.STATUS [DISC.UNIT];
IF VV.DRUM.CONTROL & 3 = 0
@BOX 5.1
VV.DRUM.CONTROL => DISC.CONTROL [DISC.UNIT];
IF DISC.UNIT /= 0 THEN
   22 +> VV.DRUM.DADDRESS;
FI
VV.DRUM.D.ADDRESS => DISC.D.ADDRESS [DISC.UNIT];
VV.DRUM.C.ADDRESS => DISC.C.ADDRESS [DISC.UNIT];
VV.DRUM.SIZE => DISC.SIZE [DISC.UNIT];
MAP.IO.APP;
START.TRANSFER ();
UNMAP.IO.APP;
@BOX 6.1
ALLOW.INTERRUPTS;
@BOX 7.1
END
@END
@TITLE AP202.2(3,11)
@COL 1S-2R-3R-4T-5R-6R-7F
@FLOW 1-2-3-4NO-5-6-7
@FLOW 4YES-6
@BOX 1.0
DISC CONTROL POST PROC
@BOX 2.0
INHIBIT INTERRUPTS
@BOX 3.0
CLEAR HW INT
[AP201]
@BOX 4.0
COMMAND BITS CLEAR?
@BOX 5.0
NOTE CORE ADDRESS, DISC ADDRESS
AND DISC SIZE.
START TRANSFER
[AP202.3]
@BOX 6.0
ALLOW INTERRUPTS
@BOX 7.0
END
@BOX 1.1
PROC DISC.CONTROL.POST.PROC;
@BOX 2.1
INHIBIT.INTERRUPTS;
@BOX 3.1
IF DISC.STATUS [VSUB => DISC.UNIT + 1] & %F00 /= 0
  AND 1 -> HW.INT.COUNT = 0 THEN
   CLEAR.HW.INT (SYS01.DISC.ACTIVITY);
FI
@BOX 4.1
DISC.STATUS [DISC.UNIT + 1] & %8000 ! VV.DISC.CONTROL [DISC.UNIT]
   => DISC.STATUS [DISC.UNIT + 1];
IF VV.DISC.CONTROL [DISC.UNIT] & 3 = 0
@BOX 5.1
VV.DISC.CONTROL [DISC.UNIT] => DISC.CONTROL [DISC.UNIT + 1];
VV.DISC.D.ADDRESS [DISC.UNIT] => DISC.D.ADDRESS [DISC.UNIT + 1];
VV.DISC.C.ADDRESS [DISC.UNIT] => DISC.C.ADDRESS [DISC.UNIT + 1];
VV.DISC.SIZE [DISC.UNIT] => DISC.SIZE [DISC.UNIT + 1];
MAP.IO.APP;
START.TRANSFER ();
UNMAP.IO.APP;
@BOX 6.1
ALLOW.INTERRUPTS;
@BOX 7.1
END
@END
@TITLE AP202.3(3,11)
@COL 1S-3R-5F
@FLOW 1-3-5
@BOX 1.0
SET TRAN MAP PRE PROC
@BOX 3.0
SET UP TRANSFER MAP FROM CORE ADDRESS
AND TRANSFER SIZE
@BOX 5.0
END
@BOX 1.1
PROC SET.TRAN.MAP.PRE.PROC;
@BOX 3.1
%80200000 !> C.ADDRESS;
-1 => COUNT;
WHILE 1 +> COUNT < TRAN.SIZE DO
   C.ADDRESS => V.DRUM.PAGE.MAP [COUNT];
   1 +> C.ADDRESS;
OD
DRUM.FIRST.UNIBUS.PAGE.NO => CADDRESS;
@BOX 5.1
END
@END
@TITLE AP202.4(3,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
CLEAR TRAN MAP PRE PROC
@BOX 2.0
PURGE BDP AND CLEAR ANY ERRORS
@BOX 3.0
SET MAP 'REGISTERS' TO INVALID
@BOX 4.0
END
@BOX 1.1
PROC CLEAR.TRAN.MAP.PRE.PROC;
@BOX 2.1
%60000001 => V.DRUM.BDP.CSR;
@BOX 3.1
-1 => COUNT;
WHILE 1 +> COUNT < MAX.BLOCKS.DRUM.XFER DO
   0 => V.DRUM.PAGE.MAP [COUNT];
OD
@BOX 4.1
END
@END
@TITLE AP202.5(3,11)
@COL 1S-17T-2T-3T-4T-13R-14R-15R-18R-5R-6N-7F
@COL 8N-9R-11R-16N
@ROW 2-8
@ROW 11-4
@ROW 6-16
@FLOW 1-17NO-2NO-3NO-4NO-13-14-15-18-5-6-7
@FLOW 17YES-18
@FLOW 2YES-9-16-6
@FLOW 3YES-11-14
@FLOW 4YES-15
@BOX 1.0
RK07 DISC INT
@BOX 2.0
UNEXPECTED INTERRUPT?
@BOX 3.0
DISC IN ERROR
@BOX 4.0
TRANSFER CONTINUING?
@BOX 5.0
START TRANSFER
[AP202.3]
@BOX 7.0
END
@BOX 9.0
HALT
@BOX 11.0
NOTE TRANSFER FAIL
@BOX 13.0
NOTE TRANSFER COMPLETE
@BOX 14.0
CLEAR DISC BUFFERS
SET HW INT
[AP201]
@BOX 15.0
CLEAR TRANSFER INDICATOR
@BOX 17.0
DRIVE BASED INTERRUPT?
@BOX 18.0
NOTE WHETHER SEEKS COMPLETE
@BOX 1.1
PROC RK07.DISC.INT (DUMMY);
LOGICAL16 ATTENTION;
INTEGER ATTN.DRIVE.NO;
@BOX 2.1
IF TRAN.STATUS = 0
@BOX 3.1
IF V.RK07.CSR & %8080 /= %80
@BOX 4.1
IF DISC.SIZE [TRAN.UNIT] /= 0
@BOX 5.1
START.TRANSFER ();
@BOX 7.1
END
@BOX 9.1
*#%0000;
@BOX 11.1
%200 !> DISC.STATUS [TRAN.UNIT] => DISC.CONTROL [TRAN.UNIT];
@BOX 13.1
%100 !> DISC.STATUS [TRAN.UNIT] => DISC.CONTROL [TRAN.UNIT];
@BOX 14.1
CLEAR.TRAN.MAP;
IF TRAN.UNIT < NO.OF.DRUM.SECTIONS AND
   DRUM.SECTION.AVAILABLE [TRAN.UNIT] /= 0 THEN
   DISC.CONTROL [TRAN.UNIT] => VV.DRUM.CONTROL;
   DISC.D.ADDRESS [TRAN.UNIT]=> VV.DRUM.D.ADDRESS;
   DISC.C.ADDRESS [TRAN.UNIT] => VV.DRUM.C.ADDRESS;
   DISC.SIZE [TRAN.UNIT] => VV.DRUM.SIZE;
   IF DISC.STATUS [TRAN.UNIT] & %800 = 0 THEN
      SET.HW.INT (SYS01.DRUM.ACTIVITY);
   FI
ELSE
   DISC.CONTROL [TRAN.UNIT] => VV.DISC.CONTROL [TRAN.UNIT - 1];
   DISC.D.ADDRESS [TRAN.UNIT]=> VV.DISC.D.ADDRESS [TRAN.UNIT - 1];
   DISC.C.ADDRESS [TRAN.UNIT] => VV.DISC.C.ADDRESS [TRAN.UNIT - 1];
   DISC.SIZE [TRAN.UNIT] => VV.DISC.SIZE [TRAN.UNIT - 1];
   IF DISC.STATUS [TRAN.UNIT] & %800 = 0 AND
      1 +> HW.INT.COUNT = 1 THEN
      SET.HW.INT (SYS01.DISC.ACTIVITY);
   FI
FI
@BOX 15.1
0 => TRAN.STATUS;
@BOX 17.1
IF TRAN.STATUS = 0 AND
   V.RK07.CSR & %4080 = %4080
@BOX 18.1
V.RK07.ATTN => ATTENTION;
FOR ATTN.DRIVE.NO < NO.OF.RK07S DO
   IF ATTENTION ->> ATTN.DRIVE.NO & %100 /= 0 THEN
      %20 !> DISC.STATUS [ATTN.DRIVE.NO];
      0 => SEEK.TIMEOUT [ATTN.DRIVE.NO];
   FI
OD
@END
@TITLE AP202.6(3,10)

@COL 1S-2T-3R-4R-5T-6R-7F

@FLOW 1-2NO-3-4-5OK-6-7
@FLOW 2YES-7
@FLOW 5FAIL-7

@BOX 1.0
START TRANSFER
@BOX 2.0
TRANSFER ALREADY IN PROGRESS?
@BOX 3.0
CHECK STATUS OF UNITS
@BOX 4.0
START ANY SEEKS REQUIRED
@BOX 5.0
FIND UNIT READY TO TRANSFER
@BOX 6.0
BEGIN TRANSFER
@BOX 7.0
END
@BOX 1.1
PROC START.TRANSFER;
INTEGER DISC.NO, DISC.STATE, COUNT, CYL, TRACK, D.ADDR, SECTOR,
   STORE.EXTENSION, I, TEMP;
LOGICAL16 DRIVE.STATE;
@BOX 2.1
IF TRAN.STATUS /= 0
@BOX 3.1
FOR DISC.NO < NO.OF.ED.UNITS DO
   IF POLL.REQ [DISC.NO] /= 0 AND
      DISC.STATUS [DISC.NO + 1] => DISC.STATE & %F00 = 0 AND
      DISC.STATE & %30 /= %10 AND
      DISC.STATE -= VV.DISC.CONTROL [DISC.NO] & 3 = 0 THEN
      0 => POLL.REQ [DISC.NO];
      %8000 => V.RK07.CSR;
      DISC.NO + 1 => V.RK07.STAT1;
      %405 => V.RK07.CSR;
      WHILE V.RK07.CSR & %80 = 0 DO OD
      V.RK07.STAT2 => DRIVE.STATE;
      IF DISC.STATE & %8000 = 0 THEN
         IF DRIVE.STATE & %80C0 /= %80C0 THEN
            %8800 !> DISC.STATE;
         FI
      ELSE
         IF DRIVE.STATE & %8080 = %8080 THEN
            %8000 -=> DISC.STATE;
            %800 !> DISC.STATE;
            %8000 => V.RK07.CSR;
            DISC.NO => V.RK07.STAT1;
            %403 => V.RK07.CSR;
            WHILE V.RK07.CSR & %80 = 0 DO OD
            SECTOR.SIZE => VV.DISC.SIZE [DISC.NO];
            RK07.SIZE => VV.DISC.DADDRESS [DISC.NO];
         FI
      FI
      IF DISC.STATE & %800 /= 0 THEN
         IF DISC.STATE & %3 /= 0 THEN
            %200 !> DISC.STATE;
         FI
         IF 1 +> HW.INT.COUNT = 1 THEN
            SET.HW.INT (SYS01.DISC.ACTIVITY);
         FI
      FI
      DISC.STATE => DISC.STATUS [DISC.NO + 1]
       => DISC.CONTROL [DISC.NO + 1] => VV.DISC.CONTROL [DISC.NO];
   FI
OD
@BOX 4.1
%8000 => V.RK07.CSR;
FOR DISC.NO < NO.OF.RK07S DO
   IF DISC.STATUS [DISC.NO] & %8F33 => DISC.STATE = 1 OR
      DISC.STATE = 2 THEN
      DISC.NO => V.RK07.STAT1;
      DISC.DADDRESS [DISC.NO] / 66 => V.RK07.CYL;
      %40F => V.RK07.CSR;
      WHILE V.RK07.CSR & %80 = 0 DO OD
      %10 !> DISC.STATUS [DISC.NO];
   FI
OD
%0040 => V.RK07.CSR;
@BOX 5.1
-1 => COUNT;
IF 1 +> TRAN.UNIT = NO.OF.RK07S THEN
   0 => TRAN.UNIT;
FI
WHILE 1 +> COUNT < NO.OF.RK07S AND
   DISC.STATUS [TRAN.UNIT] & %8F33 /= %31 /= %32 DO
   IF 1 +> TRAN.UNIT = NO.OF.RK07S THEN
      0 => TRAN.UNIT;
   FI
 OD
IF COUNT = NO.OF.RK07S
@BOX 6.1
IF DISC.SIZE [TRAN.UNIT] => TRAN.SIZE > MAX.BLOCKS.DRUM.XFER THEN
   MAX.BLOCKS.DRUM.XFER => TRAN.SIZE;
FI
DISC.D.ADDRESS [TRAN.UNIT] => D.ADDR / 22 * 22 -: D.ADDR
   => SECTOR;
IF TRAN.SIZE + SECTOR > 22 THEN
   22 - SECTOR => TRAN.SIZE;
FI
IF TRAN.UNIT < NO.OF.DRUM.SECTIONS AND
   DRUM.SECTION.AVAILABLE [TRAN.UNIT] /= 0 THEN
   SELECT BAD.BLOCKS [TRAN.UNIT];
   FOR I < BAD.BLOCK.COUNT DO
      IF D.ADDR = BAD.BLOCK [I] THEN
         SUBSTITUTE.BLOCK [I] => D.ADDR;
         1 => TRAN.SIZE;
      ELSE
         IF BAD.BLOCK [I] > D.ADDR < D.ADDR + TRAN.SIZE THEN
            BAD.BLOCK [I] - D.ADDR => TRAN.SIZE;
         FI
      FI
   OD
FI
%8000 => V.RK07.CSR;
-256 * TRAN.SIZE => V.RK07.COUNT;
D.ADDR / 66 => CYL * 66 -> D.ADDR / 22
   => TRACK * 22 -> D.ADDR => SECTOR;
CYL => V.RK07.CYL;
TRACK <<- 8 ! SECTOR => V.RK07.DADDR;
DISC.CADDRESS [TRAN.UNIT] => CADDRESS;
SET.TRAN.MAP;
CADDRESS * 512 => V.RK07.CADDR;
CADDRESS & %180 <<- 1 => STORE.EXTENSION;
TRAN.UNIT => V.RK07.STAT1;
IF DISC.CONTROL [TRAN.UNIT] & 1 /= 0 THEN
   %451 ! STORE.EXTENSION => V.RK07.CSR;
ELSE
   %453 ! STORE.EXTENSION => V.RK07.CSR;
FI
TRAN.SIZE -> DISC.SIZE [TRAN.UNIT];
TRAN.SIZE +> DISC.D.ADDRESS [TRAN.UNIT];
TRAN.SIZE +> DISC.CADDRESS [TRAN.UNIT];
1 => TRAN.STATUS;
@BOX 7.1
END
@END
@TITLE AP202.7(3,11)

@COL 1S-2R-3R-4F

@FLOW 1-2-3-4

@BOX 1.0
RK07 POLL
@BOX 2.0
CHECK TIMEOUT FOR OUTSTANDING
SEEKS
@BOX 3.0
START TRANSFER TO CHECK DISC STATES
[AP202.6]
@BOX 4.0
END
@BOX 1.1
PROC RK07.POLL;
INTEGER DISC.NO;
@BOX 2.1
FOR DISC.NO < NO.OF.RK07S DO
   IF DISC.STATUS [DISC.NO] & %30 = %10
   AND 1 +> SEEK.TIMEOUT [DISC.NO] > 2 THEN
      %20 !> DISC.STATUS [DISC.NO];
   FI
OD
@BOX 3.1
IF 1 +> POLL.COUNT > 10 THEN
   0 => POLL.COUNT;
   FOR DISC.NO < NO.OF.ED.UNITS DO
      IF DISC.NO + 1 > NO.OF.DRUM.SECTIONS OR
         DRUM.SECTION.AVAILABLE [DISC.NO + 1] = 0 THEN
         1 => POLL.REQ [DISC.NO];
         1 +> POLL.COUNT;
      FI
   OD
FI
START.TRANSFER ();
@BOX 4.1
END
@END

