@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP5124
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP5124
~S~M~OAP5 IMPLEMENTATION DESCRIPTION
~S~M~OSection 12 Version 4
~S~O12.1 ROM Drum Appendix (DMA-PV)
~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               AP5124
~V9 -1
~F
@TITLE AP512(4,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
PTV MONITOR DISC MODULE
@BOX 2.0
DECLARATIONS
@BOX 3.0
IN THIS MODULE
   INIT.DISC
   DISC.TRAN
   FORMAT
   DISC.COMMAND
   DISC.STATUS
   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, 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;
#AP512.1
#AP512.2
#AP512.3
#AP512.4
#AP512.5
#AP512.6
@BOX 4.1
*END
@END
@TITLE AP512/1(4,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 %2841;
VSTORE V.DISC.CS  %2840;
VSTORE V.DMAC.CSR %2900;
VSTORE V.DMAC.DCR %2904;
VSTORE V.DMAC.OCR %2905;
VSTORE V.DMAC.SCR %2906;
VSTORE V.DMAC.CCR %2907;
VSTORE V.DMAC.CPR %292D;
VSTORE V.DMAC.GCR %29FF;
*VTYPE $LO16;
VSTORE V.DMAC.MTC %290A;
*VTYPE $LO32;
VSTORE V.DMAC.MAR %290C;
*VTYPE LOGICAL;
VSTORE VERSION.NO %A0000;
VSTORE V.DRIVE.NO %A0002;
VSTORE V.DISC.TYPE %A0004;
@BOX 3.1
LITERAL / LOGICAL8 SEL = 4, BSY = %80, BSY.CON.REQ = %D0,
   REQ = %40, ERR.PCT = %12, DMA = 1, CTL.ID = 1,BSY.REQ = %C0;
*GLOBAL 3;
LITERAL / LOGICAL READ = 0, WRITE = 1;
LITERAL / LOGICAL8 LF = %A;
LITERAL DEFAULT.D = 0;
*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
LITERAL NUM.D.TYPES = 3;
DATAVEC DISC.TYPES (ADDR [LOGICAL8])
   DT0 DT1 DT2
END
DATAVEC CMD.TEMP.WIN (LOGICAL8)
   4 2 0 %1C 2 8
END
DATAVEC CMD.TEMP.SD (LOGICAL8)
   4 %40 0 0 1 4
END
DATAVEC CMD.TEMP.DD (LOGICAL8)
   4 %40 0 0 1 0
END
DATAVEC CMD.TYPE (ADDR [LOGICAL8])
   CMD.TEMP.WIN  CMD.TEMP.SD  CMD.TEMP.DD
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
END
DATAVEC DEV.ADD ($LO8)
 0 64 64
END
*GLOBAL 3;
*CODE 1;
@BOX 4.1
::END
@END
@TITLE AP512.1(4,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 & BSY = 0 DO OD
CTL.ID => V.DISC.DATA;
SEL => V.DISC.CS;
WHILE V.DISC.CS & BSY /= 0 DO OD
0=>V.DISC.CS;
@BOX 5.1
CMD.PTR^[0] & %0F => I;
IF I=8 OR I=%A THEN DMA=>V.DISC.CS;FI;

FOR I < 6 DO
   WHILE V.DISC.CS & BSY.CON.REQ /= 0 DO OD
   CMD.PTR^ [I] => V.DISC.DATA;
OD
@BOX 7.1
END
@END
@TITLE AP512.2(4,10)

@COL 1S-2R-3R-4R-5R-7R-8R-10R-6R-9F
@FLOW 1-2-3-4-5-7-8-10-6-9
@BOX 1.0
DISC TRANSFER (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN)
@BOX 2.0
@BOX 3.0
SET UP COMMAND BUFFER
@BOX 4.0
INITIALIZE DMAC
@BOX 5.0
COMMAND TRANSFER SEQUENCE
TRANSFER DATA
@BOX 6.0
@BOX 7.0
@BOX 8.0
GET STATUS
@BOX 9.0
END
@BOX 10.0
@BOX 1.1
PROC DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN);
LITERAL/$IN SECTOR.SIZE = 256;
INTEGER AMOUNT, I;
LOGICAL8 [6] CMD.BUFFER;
DATAVEC DEV.FM ($LO8)
  %10 %14 %10
END;
@BOX 2.1
@BOX 3.1
(IF DIRN = READ THEN %18 ELSE %1A) => 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
%F2 => V.DMAC.CSR;
C.ADDR => V.DMAC.MAR;
TRAN.SIZE * SECTOR.SIZE ->> 1 => V.DMAC.MTC;
(IF DIRN = READ THEN %92 ELSE %12) => V.DMAC.OCR;
%80 => V.DMAC.CCR;
@BOX 5.1
DISC.COMMAND (^CMD.BUFFER);
@BOX 7.1
@BOX 8.1
DISC.STATUS (DIRN,DISC.TYPE) => DISC.TRAN;
@BOX 9.1
END
@BOX 10.1
@END
@TITLE AP512.3(4,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);
@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(4,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
%EB => V.DMAC.DCR;
5   => V.DMAC.SCR;
0   => V.DMAC.CPR;
%FF => V.DMAC.CSR;
@BOX 3.1
DEFAULT.D => INIT.DISC;
@BOX 4.1
END
@END
@TITLE AP512.5(4,10)
@COL 1S-2T-3R-4F
@FLOW 1-2-3-4
@FLOW 2YES-4
@BOX 1.0
COLLECT DISC.STATUS
@BOX 2.0
ERROR STATUS = 0?
@BOX 3.0
GET ERROR 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 /= 0 DO OD
0=>V.DISC.CS;
V.DISC.DATA & 7 => DISC.STATUS;
WHILE V.DISC.CS & BSY.CON.REQ /= 0 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);
FOR I < 6 DO
  WHILE V.DISC.CS & BSY.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(4,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;
@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
(IF SEC.SIZE [DISC.TYPE] = 256 THEN 8 ELSE 7) => 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;
DISC.TYPE => V.DRIVE.NO;
DISC.TYPE => V.DISC.TYPE;
@BOX 5.1
CORE.ADDR^ [2] => READ.SYSTEM;
END
@END

