@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP3511
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP3511
~S~M~OAP3 IMPLEMENTATION DESCRIPTION
~S~M~OSection 51 Version 1
~S~O51.1 Monitor Drum Appendix (VAX)
~S1~O1. General Description
~BThis module implements polling type disc procedures for use
by the monitor, the disc copy module and other similar
utilities.
~S1~O2. Interfaces
~S1~O2.2 Software Interface~
~3
~
   1) DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRECTION)~
   2) FORMAT (DISC.TYPE)~
   3) READ.SYSTEM (VERSION, DISC.TYPE)~
   4) DISC.TYPES~
   5) SECTOR.SIZE~
~0
~S1~O3. Implementation
~S1~O3.1 Outline of Operation
~S1~O3.2 Data Structures
~T% 20
~
~
DISC.TYPES~IThis is a datavec containing the addresses
of other datavectors which specify the disc options
provided by this module.~
~
DT0/DT1/DT2~IThese are datavecs containing the names of the
disc options.~
~S1~O3.3 Special Notes
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H               AP3511
~V9 -1
~F
@TITLE AP351(1,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
VAX MONITOR DISC MODULE
@BOX 2.0
DECLARATIONS
@BOX 3.0
PROCEDURES IN THIS MODULE
   1 INIT DISC
   2 DISC TRAN
   3 DISC STATUS
   4 FORMAT
   5 READ SYSTEM
   6 SELECT DRIVE
@BOX 4.0
END
@BOX 1.1
PSPEC PRINT (ADDR [LOGICAL8]);
PSPEC PUT.HEX.CONS (LOGICAL32, INTEGER);
PSPEC PUT.CONS (LOGICAL);
IMPORT LITERAL NO.V1.SEGS, NO.V2.SEGS, SYS14.PAGE.SHIFT, BAD.BLOCK.TABLE.SIZE;
IMPORT LITERAL INTEGER32 BAD.BLOCK.TABLE, BAD.BLOCK.CORE.ADDR;
LOGICAL [NO.V1.SEGS] V1.TRAN.SIZE;
ADDR [NO.V1.SEGS] V1.DISC.ADDR, V1.CORE.ADDR;
LOGICAL [NO.V2.SEGS] V2.TRAN.SIZE;
ADDR [NO.V2.SEGS] V2.DISC.ADDR, V2.CORE.ADDR;
MODULE (INIT.DISC, DISC.TRAN, FORMAT, DISC.TYPES,
   READ.SYSTEM, NUM.D.TYPES, DEFAULT.D, DISC.SIZE, TRACK.SIZE);
@BOX 2.1
#AP351/1
@BOX 3.1
PSPEC INIT.DISC () / INTEGER;
PSPEC DISC.TRAN (LOGICAL32, LOGICAL32, LOGICAL, LOGICAL, LOGICAL) / INTEGER;
PSPEC DISC.STATUS (LOGICAL8, LOGICAL8) / INTEGER;
PSPEC FORMAT (INTEGER);
PSPEC READ.SYSTEM (INTEGER, INTEGER) / ADDR;
PSPEC SELECT.DRIVE (LOGICAL);
#AP351.1
#AP351.2
#AP351.3
#AP351.4
#AP351.5
#AP351.6
@BOX 4.1
*END
@END
@TITLE AP351.INIT(1,11)

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

@FLOW 1-2-3-4-5-6

@BOX 1.0
INITIAL BOOTSTRAP
@BOX 4.0
PROCEDURES USED
   1 INIT DISC
   2 DISC TRAN
@BOX 6.0
END
@BOX 1.1
MODULE;
@BOX 3.1
VSTORE V.UNIBUS.MAP [%100] %F30800;
*VTYPE LOGICAL16;
VSTORE V.CSR %FFFF20;
VSTORE V.COUNT %FFFF22;
VSTORE V.CADDR %FFFF24;
VSTORE V.DADDR %FFFF26;
VSTORE V.STAT1 %FFFF28;
VSTORE V.STAT2 %FFFF2A;
VSTORE V.CYL %FFFF30;
*VTYPE LOGICAL;
LITERAL / LOGICAL READ = 0, WRITE = 1, DEFAULT.D = 0;
@BOX 4.1
*#%00 %00 %00 %00 %00 %00;
*#%00 %00 %00 %00 %00 %00;
*#%D0 %8F %00 %F0 %03 %00 %5E; ::MOVL #3F000, SP;
PSPEC INIT.DISC () / INTEGER;
PSPEC DISC.TRAN (LOGICAL32, LOGICAL32, LOGICAL, LOGICAL, LOGICAL) / INTEGER;
#AP351.1
#AP351.2
@BOX 5.1
INIT.DISC ();
DISC.TRAN (2, %1000, 0, 32, READ);
*#%17 %9F %00 %10 %00 %00; ::JMP %1000;
@BOX 6.1
*END
@END



@TITLE AP351/1(1,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
DECLARATIONS
@BOX 2.0
VSTORE
@BOX 3.0
LITERALS AND DATAVECS
@BOX 4.0
END
@BOX 1.1
::DECLARATIONS
@BOX 2.1
VSTORE VERSION.NO %20010;
VSTORE AVAILABLE.DISCS %200F0;
VSTORE V.UNIBUS.MAP [%100] %F30800;
*VTYPE LOGICAL16;
VSTORE V.CSR %FFFF20;
VSTORE V.COUNT %FFFF22;
VSTORE V.CADDR %FFFF24;
VSTORE V.DADDR %FFFF26;
VSTORE V.STAT1 %FFFF28;
VSTORE V.STAT2 %FFFF2A;
VSTORE V.CYL %FFFF30;
*VTYPE LOGICAL;
@BOX 3.1
*GLOBAL 3;
LITERAL / LOGICAL READ = 0, WRITE = 1;
LITERAL / LOGICAL8 LF = %A;
LITERAL DEFAULT.D = 0;
*GLOBAL 1;
DATAVEC DT0 (LOGICAL8)
   "RK07" LF
END
DATAVEC DT1 (LOGICAL8)
   "RK07" LF
END
LITERAL NUM.D.TYPES = 2;
DATAVEC DISC.TYPES (ADDR [LOGICAL8])
   DT0 DT1
END
DATAVEC DISC.SIZE (LOGICAL)
   2445 2445
END
DATAVEC TRACK.SIZE (LOGICAL)
   44 44
END
DATAVEC ERROR.MESS (LOGICAL8)
   " Error = "
END
DATAVEC READ.MSG(LOGICAL8)
   LF "Read"
END
DATAVEC WRITE.MSG(LOGICAL8)
   LF "Write"
END
DATAVEC NOT.IMPL (LOGICAL8)
   LF "Not implemented" LF
END
*GLOBAL 3;
*CODE 1;
@BOX 4.1
::END
@END
@TITLE AP351.1(1,11)
@COL 1S-2R-6R-3R-4F
@FLOW 1-2-6-3-4
@BOX 1.0
INIT.DISC
@BOX 2.0
SEND DRIVE CLEAR
COMMAND
@BOX 3.0
RETURN DEFAULT DISC TYPE
@BOX 4.0
END
@BOX 6.0
WAIT FOR INITIALISATION
TO COMPLETE
@BOX 1.1
PROC INIT.DISC;
@BOX 2.1
%8000 => V.CSR;
0 => V.STAT1;
%405 => V.CSR;
@BOX 3.1
DEFAULT.D => INIT.DISC;
@BOX 4.1
END
@BOX 6.1
WHILE V.CSR & %80 = 0 DO OD
@END
@TITLE AP351.2(1,11)

@COL 1S-6T-2R-3R-4R-5R-8R-9F
@FLOW 1-6-2-3-4-5-6NONE-8-9
@BOX 1.0
DISC TRANSFER (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN)
@BOX 2.0
INITIALISE UNIBUS MAP
FOR TRANSFER
@BOX 3.0
SET DISC REGISTERS
FOR TRANSFER
@BOX 4.0
SEND COMMAND
@BOX 5.0
WAIT FOR TRANSFER
TO COMPLETE
@BOX 6.0
CALCULATE NUMBER OF
SECTORS TO TRANSFER
@BOX 8.0
GET STATUS
@BOX 9.0
END
@BOX 1.1
PROC DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN);
INTEGER I, CYL, TRACK, SECTOR, T.SIZE, DISC.ADDR;
D.ADDR + 1 ->> 1 => D.ADDR;
TRAN.SIZE + 1 ->> 1 => TRAN.SIZE;
@BOX 2.1
FOR I < T.SIZE DO
   C.ADDR ->> 9 ! %80000000 => V.UNIBUS.MAP [I];
   512 +> C.ADDR;
OD
@BOX 3.1
SELECT.DRIVE (DISC.TYPE);
D.ADDR => DISC.ADDR + T.SIZE => D.ADDR;
DISC.ADDR / 66 => CYL => V.CYL;
CYL * 66 -> DISC.ADDR / 22 => TRACK;
TRACK <<- 8 ! SECTOR => V.DADDR;
-256 * T.SIZE => V.COUNT;
0 => V.CADDR;
@BOX 4.1
(IF DIRN = READ THEN %411 ELSE %413) => V.CSR;
@BOX 5.1
WHILE V.CSR & %80 /= %80 OR
   V.STAT2 & %8000 /= %8000 DO OD
@BOX 6.1
D.ADDR / 22 * 22 -: D.ADDR => SECTOR;
IF TRAN.SIZE => T.SIZE + SECTOR > 22 THEN
   22 - SECTOR => T.SIZE;
FI
T.SIZE -> TRAN.SIZE;
IF T.SIZE = 0
@BOX 8.1
DISC.STATUS (DIRN, DISC.TYPE) => DISC.TRAN;
@BOX 9.1
END
@END
@TITLE AP351.3(1,11)
@COL 1S-2T-3R-4F
@FLOW 1-2-3-4
@FLOW 2YES-4
@BOX 1.0
DISC.STATUS
@BOX 2.0
ERROR STATUS = 0?
@BOX 3.0
GET ERROR STATUS
PRINT ERROR MESSAGE
@BOX 4.0
END
@BOX 1.1
PROC DISC.STATUS (IO.TYPE, DISC.TYPE);
0 => DISC.STATUS;
@BOX 2.1
IF V.CSR >= 0
@BOX 3.1
IF IO.TYPE = READ THEN
   PRINT (^READ.MSG);
ELSE
   PRINT (^WRITE.MSG);
FI
PRINT (^ERROR.MESS);
PUT.HEX.CONS (V.STAT2, 16);
PUT.CONS (LF);
-1 => DISC.STATUS;
@BOX 4.1
END
@END
@TITLE AP351.4(1,11)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
FORMAT DISK
@BOX 3.0
OBTAIN DISK TYPE
ISSUE FORMAT COMMAND
@BOX 4.0
END
@BOX 5.0
OUTPUT ERROR MESSAGE
@BOX 1.1
PROC FORMAT (DISC.TYPE);
@BOX 3.1
DISC.STATUS (WRITE, DISC.TYPE);
PRINT (^NOT.IMPL);
@BOX 4.1
END
@END
@TITLE AP351.5(1,11)

@COL 1S-2R-3R-6R-4R-5F
@FLOW 1-2-3-6-4-5
@BOX 1.0
READ SYSTEM (VERSION, DRIVE, DISC)
@BOX 2.0
INITIALISE POINTERS
@BOX 3.0
READ IN SYSTEM
@BOX 4.0
SET VERSION AND DISC NUMBERS
@BOX 5.0
END
@BOX 6.0
READ BAD BLOCK TABLE
FOR EACH AVAILABLE DISC
@BOX 1.1
PROC READ.SYSTEM (VERSION, DISC.TYPE);
INTEGER SECTOR.SHIFT, I, T.SIZE, SCALE;
INTEGER NO.BOOT.SEGS;
ADDR C.ADDR, D.ADDR;
ADDR [LOGICAL] TRAN.SIZE;
ADDR [ADDR] CORE.ADDR, DISC.ADDR;
@BOX 2.1
IF VERSION = 1 THEN
   ^V1.DISC.ADDR => DISC.ADDR;
   ^V1.TRAN.SIZE => TRAN.SIZE;
   ^V1.CORE.ADDR => CORE.ADDR;
   NO.V1.SEGS => NO.BOOT.SEGS;
ELSE
   ^V2.DISC.ADDR => DISC.ADDR;
   ^V2.TRAN.SIZE => TRAN.SIZE;
   ^V2.CORE.ADDR => CORE.ADDR;
   NO.V2.SEGS => NO.BOOT.SEGS;
FI
@BOX 3.1
SYS14.PAGE.SHIFT - 8 => SCALE;
FOR I < NO.BOOT.SEGS DO
   DISC.ADDR^ [I] <<- SCALE => D.ADDR;
   CORE.ADDR^ [I] => C.ADDR;
   TRAN.SIZE^ [I] <<- SCALE => T.SIZE;
   DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, T.SIZE, READ);
OD
@BOX 4.1
VERSION - 1 => VERSION.NO;
@BOX 5.1
CORE.ADDR^ [2] => READ.SYSTEM;
END
@BOX 6.1
0 => AVAILABLE.DISCS;
BAD.BLOCK.CORE.ADDR => C.ADDR;
FOR I < 8 DO
   %8000 => V.CSR;
   I => V.STAT1;
   %405 => V.CSR;
   WHILE V.CSR & %80 = 0 DO OD
   IF V.STAT2 & %8080 = %8080 THEN
      1 <<- I !> AVAILABLE.DISCS;
      DISC.TRAN (BAD.BLOCK.TABLE.SIZE * 2 - 2 + BAD.BLOCK.TABLE,
         C.ADDR, I, 2, READ);
   FI
   512 +> C.ADDR;
OD
@END
@TITLE AP351.6(1,11)

@COL 1S-2R-3F

@FLOW 1-2-3

@BOX 1.0
SELECT DRIVE (UNIT)
@BOX 2.0
SELECT DRIVE UNIT
@BOX 3.0
END
@BOX 1.1
PROC SELECT.DRIVE (UNIT);
@BOX 2.1
%8000 => V.CSR;
UNIT => V.STAT1;
%8001 => V.CSR;
UNIT => V.STAT1;
%403 => V.CSR;
WHILE V.CSR & %80 = 0 DO OD
%8000 => V.CSR;
UNIT => V.STAT1;
@BOX 3.1
END
@END


