@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP2511
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP2511
~S~M~OAP2 IMPLEMENTATION DESCRIPTION
~S~M~OSection 51 Version 1
~S~O51.1 Monitor Drum Appendix (PDP11)
~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~
~
   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~
~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
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H               AP2511
~V9 -1
~F
@TITLE AP251(1,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
PDP11 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
@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;
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
*CODE 1;
#AP251/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;
#AP251.1
#AP251.2
#AP251.3
#AP251.4
#AP251.5
@BOX 4.1
*END
@END
@TITLE AP251.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
*VTYPE LOGICAL16;
VSTORE V.CSR %F900;
VSTORE V.CADDR %F902;
VSTORE V.DADDR %F904;
VSTORE V.MULTI %F906;
*VTYPE LOGICAL;
LITERAL / LOGICAL READ = 0, WRITE = 1, DEFAULT.D = 0;
@BOX 4.1
*#%15C6 %C000; ::MOV #%C000, R6;
PSPEC INIT.DISC () / INTEGER;
PSPEC DISC.TRAN (ADDR, ADDR, LOGICAL, LOGICAL, LOGICAL) / INTEGER;
#AP251.1
#AP251.2
@BOX 5.1
INIT.DISC ();
DISC.TRAN (4, %C000, 0, 32, READ);
*#%17C7 %C000; ::JMP @%C000;
::WRITE BOOTSTRAP TO DISC
*#%15C6 %C000;
DISC.TRAN (0, 0, 0, 36, WRITE);
*#%0000;
@BOX 6.1
*END
@END



@TITLE AP251/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 %0;
*VTYPE LOGICAL16;
VSTORE V.CSR %F900;
VSTORE V.CADDR %F902;
VSTORE V.DADDR %F904;
VSTORE V.MULTI %F906;
*VTYPE LOGICAL;
@BOX 3.1
LITERAL / LOGICAL READ = 0, WRITE = 1;
LITERAL / LOGICAL8 LF = %A;
LITERAL DEFAULT.D = 0;
*CODE 3;
*GLOBAL 1;
DATAVEC DT0 (LOGICAL8)
   "RL01/2" LF
END
DATAVEC DT1 (LOGICAL8)
   "RL01/2" LF
END
LITERAL NUM.D.TYPES = 2;
DATAVEC DISC.TYPES (ADDR [LOGICAL8])
   DT0 DT1
END
DATAVEC DISC.SIZE (LOGICAL)
   512 512
END
DATAVEC TRACK.SIZE (LOGICAL)
   40 40
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 AP251.1(1,11)
@COL 1S-3R-4F
@FLOW 1-3-4
@BOX 1.0
INIT.DISC
@BOX 3.0
RETURN DEFAULT DISC TYPE
@BOX 4.0
END
@BOX 1.1
PROC INIT.DISC;
@BOX 3.1
DEFAULT.D => INIT.DISC;
@BOX 4.1
END
@END
@TITLE AP251.2(1,11)

@COL 1S-2R-3R-4R-5R-6R-7R-8R-9R-11T-10F

@FLOW 1-2-3-4-5-6-7-8-9-11NO-10
@FLOW 11YES-2

@BOX 1.0
DISC TRANSFER (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN)
@BOX 2.0
SELECT DRIVE
@BOX 3.0
CLEAR ERRORS
@BOX 4.0
READ CURRENT POSITION
@BOX 5.0
COMPUTE DISTANCE TO
REQUIRED POSITION
@BOX 6.0
SEEK TO POSITION
@BOX 7.0
SET DISC REGISTERS
FOR TRANSFER
@BOX 8.0
WAIT FOR TRANSFER
TO COMPLETE
@BOX 9.0
READ STATUS
@BOX 10.0
END
@BOX 11.0
MORE TO TRANSFER?
@BOX 1.1
PROC DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN);
INTEGER CYL, DISC, DISP, TRACK, SECTOR, T.SIZE;
@BOX 2.1
DISC.TYPE <<- 8 => DISC => V.CSR;
WHILE V.CSR & %81 /= %81 DO OD
@BOX 3.1
%B => V.DADDR;
DISC + 4 => V.CSR;
WHILE V.CSR & %81 /= %81 DO OD
@BOX 4.1
DISC + 8 => V.CSR;
WHILE V.CSR & %81 /= %81 DO OD
@BOX 5.1
D.ADDR / 80 => CYL;
IF V.MULTI ->> 7 -: CYL <<- 7 => DISP =< 0 THEN
   0 -:> DISP;
ELSE
   4 +> DISP;
FI
IF D.ADDR / 40 & 1 => TRACK = 0 THEN
   1 +> DISP;
ELSE
   17 +> DISP;
FI
@BOX 6.1
DISP => V.DADDR;
DISC + 6 => V.CSR;
WHILE V.CSR & %81 /= %81 DO OD
@BOX 7.1
D.ADDR / 40 * 40 -: D.ADDR => SECTOR;
IF 40 - SECTOR => T.SIZE > TRAN.SIZE THEN
   TRAN.SIZE => T.SIZE;
FI
C.ADDR => V.CADDR;
-128 * T.SIZE => V.MULTI;
(TRACK <<- 6) + (CYL <<- 7) + SECTOR => V.DADDR;
(IF DIRN = READ THEN %C ELSE %A) +
   (C.ADDR ->> 12 & %30) + DISC => V.CSR;
@BOX 8.1
WHILE V.CSR & %81 /= %81 DO OD
@BOX 9.1
DISC.STATUS (DIRN, DISC.TYPE) => DISC.TRAN;
@BOX 10.1
END
@BOX 11.1
T.SIZE +> D.ADDR;
T.SIZE * 256 +> C.ADDR;
IF T.SIZE -> TRAN.SIZE > 0
@END
@TITLE AP251.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.CSR, 16);
%B => V.DADDR;
DISC.TYPE <<- 8 + 4 => V.CSR;
WHILE V.CSR & %81 /= %81 DO OD
PUT.HEX.CONS (V.MULTI, 16);
PUT.CONS (LF);
-1 => DISC.STATUS;
@BOX 4.1
END
@END
@TITLE AP251.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 AP251.5(1,11)

@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-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 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
@END

