@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP5121
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP5121
~S~M~OAP5 IMPLEMENTATION DESCRIPTION
~S~M~OSection 12 Version 1
~S~O12.1 ROM Drum Appendix (ATV)
~S1~O1. General Description
~BThis module implements polling type disc procedures for use
by the ROM 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
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H               AP5121
~V9 -1
~F
@TITLE AP512(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
RTV MONITOR DISC MODULE
@BOX 2.0
DECLARATIONS
@BOX 3.0
IN THIS MODULE
   DISC.TRAN
   FORMAT
@BOX 4.0
END
@BOX 1.1
PSPEC PRINT (ADDR [LOGICAL8]);
PSPEC PUT.HEX.CONS (LOGICAL32, INTEGER);
PSPEC PUT.CONS (LOGICAL);
PSPEC GET.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, SEC.SIZE,
   READ.SYSTEM, NUM.D.TYPES, DEFAULT.D);
@BOX 2.1
#AP512/1
@BOX 3.1
PSPEC INIT.DISC () / INTEGER;
PSPEC DISC.TRAN (LOGICAL32, LOGICAL32, LOGICAL, LOGICAL, LOGICAL) / INTEGER;
PSPEC FORMAT (INTEGER);
PSPEC DISC.COMMAND (ADDR [LOGICAL8]);
PSPEC DISC.STATUS (LOGICAL8,LOGICAL8) / INTEGER;
PSPEC READ.SYSTEM (INTEGER, INTEGER) / ADDR;
PSPEC INIT.NEWBURY ();
#AP512.1
#AP512.2
#AP512.3
#AP512.4
#AP512.5
#AP512.6
#AP512.7
@BOX 4.1
*END
@END
@TITLE AP512/1(1,10)
@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
*VTYPE LOGICAL8;
VSTORE V.DISC.DATA %5000;
VSTORE V.DISC.CS   %5001;
*VTYPE LOGICAL;
VSTORE VERSION.NO %A0000;
VSTORE V.DRIVE.NO %80C02;
VSTORE V.DISC.TYPE %80C04;
@BOX 3.1
LITERAL / LOGICAL8 CON=%10, SEL=%40, BSY=%80, BSY.CON=%90, REQ.CON=%50,
   REQ=%40, BSY.CON.REQ=%D0;
*GLOBAL 3;
LITERAL / LOGICAL READ = 0, WRITE = 1;
LITERAL / LOGICAL8 LF = %A;
LITERAL DEFAULT.D = 0;
INTEGER NEWBURY.INIT;
*GLOBAL 1;
DATAVEC DT0 (LOGICAL8)
   "Fixed, (Winchester)" LF
END
DATAVEC DT1 (LOGICAL8)
   "Floppy, Single density" LF
END
DATAVEC DT2 (LOGICAL8)
   "Floppy, Double density)" LF
END
DATAVEC DT3 (LOGICAL8)
   "Fixed, (Newbury)" LF
END
DATAVEC DT4 (LOGICAL8)
   "Exchangeable, (Newbury)" LF
END
LITERAL NUM.D.TYPES = 5;
DATAVEC DISC.TYPES (ADDR [LOGICAL8])
   DT0 DT1 DT2 DT3 DT4
END
DATAVEC CMD.TEMP.WIN (LOGICAL8)
   4 2 0 %1C 15 8
END
DATAVEC CMD.TEMP.SD (LOGICAL8)
   4 %40 0 0 4 4
END
DATAVEC CMD.TEMP.DD (LOGICAL8)
   4 %40 0 0 4 0
END
DATAVEC CMD.TEMP.FN (LOGICAL8)
   4 %20 0 0 8 0
END
DATAVEC CMD.TEMP.EN (LOGICAL8)
   4 %00 0 0 8 0
END
DATAVEC CMD.TYPE (ADDR [LOGICAL8])
   CMD.TEMP.WIN  CMD.TEMP.SD  CMD.TEMP.DD
   CMD.TEMP.FN   CMD.TEMP.EN
END
DATAVEC ERROR.MESS (LOGICAL8)
   " Error = "
END
DATAVEC READ.MSG($LO8)
   LF "Read"
END
DATAVEC WRITE.MSG($LO8)
   LF "Write"
END
DATAVEC SEC.SIZE (LOGICAL)
   256 128 256 256 256
END
DATAVEC DEV.ADD ($LO8)
  0 64 64 %20 0
END
*GLOBAL 3;
*CODE 1;
@BOX 4.1
::END
@END
@TITLE AP512.1(1,10)

@COL 1S-4R-5R-8R-6R-7F
@FLOW 1-4-5-8-6-7
@BOX 1.0
DISC COMMAND (CMD PTR)
@BOX 4.0
SELECTION SEQUENCE
@BOX 5.0
COMMAND TRANSFER SEQUENCE
@BOX 6.0
@BOX 7.0
END
@BOX 8.0
@BOX 1.1
PROC DISC.COMMAND (CMD.PTR);
INTEGER I;
@BOX 4.1
WHILE V.DISC.CS /=0 DO OD
1 => V.DISC.DATA;
SEL => V.DISC.CS;
WHILE V.DISC.CS & BSY.CON =0 DO OD
@BOX 5.1
FOR I < 6 DO
   WHILE V.DISC.CS & REQ.CON /= REQ.CON DO OD
   CMD.PTR^ [I] => V.DISC.DATA;
OD
@BOX 7.1
END
@END
@TITLE AP512.2(1,10)

@COL 1S-2R-3R-4R-5R-7R-8R-10R-6R-9F
@COL 13C-14R
@ROW 5-13
@FLOW 1-2-3-4-5-7-8-10-6-9
@FLOW 13-14-8
@BOX 1.0
DISC TRANSFER (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN)
@BOX 2.0
INITIALIZE VARIABLES
FOR TRANSFER
@BOX 3.0
SET UP COMMAND BUFFER
@BOX 4.0
@BOX 5.0
COMMAND TRANSFER SEQUENCE
@BOX 6.0
@BOX 7.0
TRANSFER DATA
@BOX 8.0
GET STATUS
@BOX 9.0
END
@BOX 10.0
@BOX 13.0
ERROR
@BOX 14.0
@BOX 1.1
PROC DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN);
INTEGER AMOUNT, I, SCALE;
LOGICAL8 [6] CMD.BUFFER;
ADDR [LOGICAL8] CORE;
DATAVEC DEV.FM ($LO8)
  0 4 0 0 0
END;
IF DISC.TYPE > 2 AND NEWBURY.INIT = 0 THEN
   INIT.NEWBURY ();
FI
@BOX 2.1
IF SEC.SIZE [DISC.TYPE] >= 256 THEN
   SEC.SIZE [DISC.TYPE] / 256 => SCALE;
   SCALE /> TRAN.SIZE;
   SCALE /> D.ADDR;
ELSE
   256 / SEC.SIZE [DISC.TYPE] => SCALE;
   SCALE *> TRAN.SIZE;
   SCALE *> D.ADDR;
FI
MAKE (LOGICAL8, TRAN.SIZE * SEC.SIZE [DISC.TYPE] => AMOUNT, C.ADDR) => CORE;
@BOX 3.1
(IF DIRN = READ THEN 8 ELSE %A) => CMD.BUFFER [0];
DEV.ADD [DISC.TYPE] ! (D.ADDR ->> 16 & %1F) => CMD.BUFFER [1];
D.ADDR ->> 8 => CMD.BUFFER [2];
D.ADDR => CMD.BUFFER [3];
TRAN.SIZE => CMD.BUFFER [4];
DEV.FM [DISC.TYPE] => CMD.BUFFER [5];
@BOX 4.1
@BOX 5.1
DISC.COMMAND (^CMD.BUFFER);
WHILE V.DISC.CS & CON /= 0 DO OD
@BOX 7.1
IF DIRN = READ THEN
   FOR I < AMOUNT DO
      WHILE V.DISC.CS & REQ = 0 DO OD
      IF V.DISC.CS & CON /= 0, -> ERROR;
      V.DISC.DATA => CORE^ [I];
   OD
ELSE
   FOR I < AMOUNT DO
      WHILE V.DISC.CS & REQ = 0 DO OD
      IF V.DISC.CS & CON /= 0, -> ERROR;
      CORE^ [I] => V.DISC.DATA;
   OD
FI
@BOX 8.1
DISC.STATUS (DIRN,DISC.TYPE) => DISC.TRAN;
@BOX 9.1
END
@BOX 10.1
@BOX 13.1
ERROR:
@BOX 14.1
@END
@TITLE AP512.3(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
FORMAT DISK
@BOX 2.0
@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);
IF DISC.TYPE > 2 AND NEWBURY.INIT = 0 THEN
   INIT.NEWBURY ();
FI
@BOX 2.1
@BOX 3.1
DISC.COMMAND (CMD.TYPE[DISC.TYPE]);
DISC.STATUS (WRITE,DISC.TYPE);
@BOX 4.1
END
@END
@TITLE AP512.4(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
INIT.DISC
@BOX 2.0
INITIALISE DISC PARAMETERS
@BOX 3.0
RETURN DEFAULT DISC TYPE
@BOX 4.0
END
@BOX 1.1
PROC INIT.DISC;
@BOX 2.1
@BOX 3.1
DEFAULT.D => INIT.DISC;
@BOX 4.1
END
@END
@TITLE AP512.5(1,10)
@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
READ DISK STATUS
PRINT ERROR MESSAGE
@BOX 4.0
END
@BOX 1.1
$PR DISC.STATUS (IO.TYPE,DISC.TYPE);
LOGICAL8 [6] STAT.REQ;
INTEGER I;
@BOX 2.1
WHILE V.DISC.CS & BSY.CON.REQ /= BSY.CON.REQ DO OD
V.DISC.DATA & 7 => DISC.STATUS;
WHILE V.DISC.CS & BSY.CON.REQ /= BSY.CON.REQ DO OD
V.DISC.DATA;
IF DISC.STATUS = 0
@BOX 3.1
3 => STAT.REQ[0];
DEV.ADD[DISC.TYPE] => STAT.REQ[1];
0 => STAT.REQ[5];
DISC.COMMAND (^STAT.REQ);
WHILE V.DISC.CS & CON /= 0 DO OD
FOR I < 6 DO
  WHILE V.DISC.CS & REQ =0 DO OD
  V.DISC.DATA => STAT.REQ[I];
OD;
IF IO.TYPE = READ
  THEN PRINT (^READ.MSG)
  ELSE PRINT (^WRITE.MSG) FI;
PRINT (^ERROR.MESS);
PUT.HEX.CONS (STAT.REQ[0],8);
PUT.CONS (LF);
@BOX 4.1
END
@END
@TITLE AP512.6(1,10)

@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
READ SYSTEM (VERSION, DRIVE, DISC)
@BOX 2.0
INITIALIZE 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;
DATAVEC CONFIG.MSG (LOGICAL8)
   "DRUM CONFIGURATION:" LF
   "   1: FIXED DISC ONLY" LF
   "   2: FIXED AND REMOVABLE DISC" LF
END

@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
8 => SECTOR.SHIFT;
SYS14.PAGE.SHIFT - SECTOR.SHIFT => SCALE;
FOR I < NO.BOOT.SEGS DO
   DISC.ADDR^ [I] <<- SCALE + 32 => D.ADDR;
   CORE.ADDR^ [I] => C.ADDR;
   TRAN.SIZE^ [I] <<- SCALE => T.SIZE;
   WHILE T.SIZE > 64 DO
      DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, 64, READ);
      64 -> T.SIZE;
      64 +> D.ADDR;
      64 <<- SECTOR.SHIFT +> C.ADDR;
   OD
   DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, T.SIZE, READ);
OD
@BOX 4.1
VERSION - 1 => VERSION.NO;
IF DISC.TYPE < 2 THEN
   0 => V.DISC.TYPE;
ELSE
   WHILE 1 = 1 DO
      PRINT (^CONFIG.MSG);
      GET.CONS () - "0" => V.DISC.TYPE;
      IF V.DISC.TYPE > 0 < 3, -> OUT;
   OD
   OUT:
FI
@BOX 5.1
CORE.ADDR^ [2] => READ.SYSTEM;
END
@END
@TITLE AP512.7(11,1)
@COL 1S-2R-3R-4R-6T-5F

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

@BOX 1.0
INITIALISE NEWBURY
@BOX 2.0
TRANSFER COMMAND
@BOX 3.0
TRANSFER PARAMETERS
@BOX 4.0
CHECK STATUS
@BOX 5.0
END
@BOX 6.0
BOTH LUN'S INITIALISED
@BOX 1.1
PROC INIT.NEWBURY;
INTEGER I;
LOGICAL8 [6] CMD;
DATAVEC INIT.CMD (LOGICAL8)
   %C2 0 0 0 0 0
END
DATAVEC INIT.PARAM (LOGICAL8)
   %01 %01 %00 %01
   %01 %3F %00 %28
   %20 %00
END
FOR I < 6 DO
   INIT.CMD [I] => CMD [I];
OD
@BOX 2.1
DISC.COMMAND (^CMD);
WHILE V.DISC.CS & CON /= 0 DO OD
@BOX 3.1
FOR I < 10 DO
   WHILE V.DISC.CS & REQ = 0 DO OD
   IF V.DISC.CS & CON /= 0, -> ERROR;
   INIT.PARAM [I] => V.DISC.DATA;
OD
ERROR:
@BOX 4.1
DISC.STATUS (0, 3);
1 => NEWBURY.INIT;
@BOX 5.1
END
@BOX 6.1
IF %20 +> CMD [1] < %40
@END



