@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP5023
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP5023
~S1~MAP5 IMPLEMENTATION DESCRIPTION~
~S1~MSection 2  Version 3~
~S1Section 2.3 Drum Appendix (GEMSTONE)~
~S11. General Description~
~BThis module is concerned with driving the 'drum'
described in SYS Section 3 (Drum Manager). The 'drum' in this
instance is a
Locust Winchester disc driven by a Gemstone auxiliary line
module.
~S12. Interfaces~
~
Other modules used~
   SYS Section 1 (Coordinator)~
   SYS Section 12 (System Error)~
   SYS Section 14 (Virtual Store Manager)~
Ideal hardware registers used~
   V.DISC.CONTROL~
   V.DISC.SIZE~
   V.DISC.C.ADDRESS~
   V.DISC.D.ADDRESS~
Interrupt procedures~
   GEM.DISC.INT (DUMMY)~
Interface procedures~
   None~
Interface variables~
   None~
Configuration parameters~
   None~
~P~S12.1 MUSS Interface~
~BThe ideal hardware registers are
described in SYS Section 3.~
~S13. Implementation~
~S13.1 Outline of Implementation~
~BThe following procedures are private to this module.
~S11) DISC.CONTROL.POST.PROC~
~BThis procedure translates ideal
drum commands into line module commands.~
~S12) CMD (UNIT, CMD1, CMD2, DISC ADDR, CORE ADDR, SIZE)~
~BThis procedure sends a command packet to the line module
controlling the specified disc.
~S13.2 Data Structures~
~T# 30
~
~
DISC.STATUS~IA logical variable giving the status of the disc.~
HW.INT.COUNT~IThe number of ideal disc interrupts pending for
the drum activity.~
UNIT~IThe drive selected for the current ideal disc command.~
~S13.3 Special Notes~
~BThe information concerning the disc type (Logical
Unit No) and the drive number are passed to this Appendix
in the variables DISC.TYPE and DRIVE.NO which are initialised
by the system bootstrap using information received from the initial
bootstrap.
~BThe default interrupt vector set for the disc on the
auxilliary line module is
%48.  The row interrupt code to service a disc interrupt
is vectored through this, but subsequently, the disc and
other appendix code behaves as if the interrupt came through
Autovector level 5 (vector number %1D).
~Y
~V9 -1
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H               AP5023
~V9 -1
~F
@TITLE AP502(3,11)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
MC68000 GEMSTONE DISC APPENDIX
@BOX 4.0
PROCEDURES IN MODULE:
   1 DISC CONTROL POST PROC
   2 GEM DISC INT
   3 CMD
@BOX 6.0
*END
@BOX 1.1
#AP502/1
MODULE (V.DISC.CONTROL, V.DISC.D.ADDRESS, V.DISC.C.ADDRESS, V.DISC.SIZE,
   V.DRUM.CONTROL, V.DRUM.D.ADDRESS, V.DRUM.C.ADDRESS, V.DRUM.SIZE,
   V.DRUM.SECTION, GEM.DISC.INT);
@BOX 2.1
TYPE PACKET IS
   LOGICAL8 CMD1, CMD2, STATUS1, STATUS2
   LOGICAL32 SECTOR
   LOGICAL8 CONTROL, NO.OF.SECTORS
   LOGICAL16 ZERO
   LOGICAL8 CMD.COUNT, DATA.COUNT
   LOGICAL32 DATA.ADDR
   LOGICAL16 BYTE.COUNT;
TYPE DISC.VARS.TYPE IS
   LOGICAL DISC.STATUS, SECTOR.SIZE, C.ADDR, SECTOR.COUNT, MAX.SECT
   LOGICAL32 SECTORS.PER.DRIVE, D.ADDR, SECTORS.PER.DISC
   ADDR PACKET DISC.PACKET
   ADDR LOGICAL16 CMD.REQUEST;
@BOX 3.1
*GLOBAL 5;
LOGICAL [SYS05.NO.OF.ED.UNITS] VV.DISC.CONTROL,
   VV.DISC.C.ADDRESS, VV.DISC.SIZE;
LOGICAL32 [SYS05.NO.OF.ED.UNITS]  VV.DISC.D.ADDRESS;
VSTORE V.DISC.CONTROL [SYS05.NO.OF.ED.UNITS] VV.DISC.CONTROL > DISC.CONTROL.POST
.PROC;
VSTORE V.DISC.D.ADDRESS [SYS05.NO.OF.ED.UNITS] VV.DISC.D.ADDRESS;
VSTORE V.DISC.C.ADDRESS [SYS05.NO.OF.ED.UNITS] VV.DISC.C.ADDRESS;
VSTORE V.DISC.SIZE [SYS05.NO.OF.ED.UNITS] VV.DISC.SIZE;
LOGICAL VV.DRUM.CONTROL, VV.DRUM.C.ADDRESS, VV.DRUM.SIZE, VV.DRUM.SECTION;
LOGICAL32  VV.DRUM.D.ADDRESS;
VSTORE V.DRUM.CONTROL VV.DRUM.CONTROL > DRUM.CONTROL.POST.PROC;
VSTORE V.DRUM.D.ADDRESS VV.DRUM.D.ADDRESS;
VSTORE V.DRUM.C.ADDRESS VV.DRUM.C.ADDRESS;
VSTORE V.DRUM.SIZE VV.DRUM.SIZE;
VSTORE V.DRUM.SECTION VV.DRUM.SECTION;
INTEGER HW.INT.COUNT, UNIT;
DISC.VARS.TYPE [NO.OF.DISCS] DISC.VARS;
@BOX 4.1
*CODE 2;
::PSPEC DRUM.CONTROL.POST.PROC ();
::PSPEC DISC.CONTROL.POST.PROC ();
PSPEC GEM.DISC.INT (INTEGER);
PSPEC START.TRANSFER (INTEGER);
*CODE 2;
   #AP502.1
   #AP502.2
   #AP502.3
   #AP502.4
@BOX 5.1
*CODE 7;
BEGIN
TYPE LAB.ADDR IS
   LABEL L
OR
   LOGICAL32 CONTEXT, L.ADDR;
LAB.ADDR VEC;
ADDR ADDR INT.VEC;
FOR UNIT < NO.OF.DISCS DO
   SELECT DISC.VARS [UNIT];
   MAKE (PACKET, 0, (DISC.PORT [UNIT] <<- 10) + (DISC.CHANNEL [UNIT] <<- 7) + %4
0C080) => DISC.PACKET;
   MAKE (LOGICAL16, 0, (DISC.PORT [UNIT] <<- 10) + (DISC.CHANNEL [UNIT] <<- 16)
+ %684000) => CMD.REQUEST;
   DRIVE.SIZE [UNIT] => SECTORS.PER.DRIVE;
   SECT.SIZE [UNIT] => SECTOR.SIZE;
   DISC.SIZES [UNIT] => SECTORS.PER.DISC;
   MAX.SECTORS [UNIT] => MAX.SECT;
   MAKE (ADDR, 0, DISC.VEC [UNIT]) => INT.VEC;
   ALTERNATIVE UNIT FROM
      GEM.INT.0 => L OF VEC;
      GEM.INT.1 => L OF VEC;
   END
   L.ADDR OF VEC => INT.VEC^;
   IF UNIT /= 0 THEN
      %8000 => VV.DISC.CONTROL [UNIT - 1] => DISC.STATUS;
      SECTORS.PER.DISC - 1 => VV.DISC.DADDRESS [UNIT - 1];
      SECTOR.SIZE => VV.DISC.SIZE [UNIT - 1];
   FI
OD
END
@BOX 6.1
*END
@END
@TITLE AP502/1(3,11)
@COL 1S-2R-3R-4R
@FLOW 1-2-3-4
@BOX 1.0
OTHER MODULES REFERENCED
@BOX 4.0
SYS01 COORDINATOR
SYS03 DRUM MANAGER
SYS14 VIRTUAL STORE MANAGER
@BOX 1.1
:: EXTERNAL ENVIRONMENT
@BOX 2.1
IMPORT VSTORE LOGICAL ALLOW.INTERRUPTS, INHIBIT.INTERRUPTS;
IMPORT LITERAL NO.OF.DISCS, SYS05.NO.OF.ED.UNITS;
INTEGER32 [NO.OF.DISCS] DISC.PORT, DISC.CHANNEL, DISC.VEC,
   DRIVE.SIZE, SECT.SIZE, DISC.SIZES, MAX.SECTORS;
@BOX 3.1
PSPEC SET.HW.INT (LOGICAL);
PSPEC CLEAR.HW.INT (LOGICAL);
@BOX 4.1
IMPORT LITERAL LOGICAL SYS01.DRUM.ACTIVITY, SYS01.DISC.ACTIVITY;
IMPORT LITERAL INTEGER SYS14.PAGE.SHIFT;
@END
@TITLE AP502.1(3,11)
@COL 1S-2R-3R-6R-7F
@FLOW 1-2-3-6-7
@BOX 1.0
DRUM CONTROL POST PROC
@BOX 2.0
INHIBIT INTERRUPTS
@BOX 3.0
NOTE DRUM COMMAND
@BOX 6.0
ALLOW INTERRUPTS
@BOX 7.0
END
@BOX 1.1
PROC DRUM.CONTROL.POST.PROC;
PSPEC NOTE.DRUM.COMMAND ();
#AP502.1.1
@BOX 2.1
INHIBIT.INTERRUPTS;
@BOX 3.1
NOTE.DRUM.COMMAND ();
@BOX 6.1
ALLOW.INTERRUPTS;
@BOX 7.1
END
@END
@TITLE AP502.1.1(3,11)
@COL 1S-3R-4T-5R-7F
@FLOW 1-3-4NO-5-7
@FLOW 4YES-7
@BOX 1.0
NOTE DRUM COMMAND
@BOX 3.0
CLEAR HW INT
[AP501]
@BOX 4.0
COMMAND BITS CLEAR?
@BOX 5.0
START TRANSFER
[AP502.3]
@BOX 7.0
END
@BOX 1.1
PROC NOTE.DRUM.COMMAND;
@BOX 3.1
SELECT DISC.VARS [0];
IF DISC.STATUS & %F00 /= 0 THEN
   CLEAR.HW.INT (SYS01.DRUM.ACTIVITY);
FI
@BOX 4.1
DISC.STATUS & %8000 ! VV.DRUM.CONTROL => DISC.STATUS;
IF DISC.STATUS & 3 = 0
@BOX 5.1
VV.DRUM.D.ADDRESS => D.ADDR;
VV.DRUM.C.ADDRESS => C.ADDR;
VV.DRUM.SIZE => SECTOR.COUNT;
START.TRANSFER (0);
@BOX 7.1
END
@END
@TITLE AP502.2(3,11)
@COL 1S-2R-3R-6R-7F
@FLOW 1-2-3-6-7
@BOX 1.0
DISC CONTROL POST PROC
@BOX 2.0
INHIBIT INTERRUPTS
@BOX 3.0
NOTE DISC COMMAND
@BOX 6.0
ALLOW INTERRUPTS
@BOX 7.0
END
@BOX 1.1
PROC DISC.CONTROL.POST.PROC;
PSPEC NOTE.DISC.COMMAND ();
#AP502.2.1
@BOX 2.1
VSUB => UNIT;
INHIBIT.INTERRUPTS;
@BOX 3.1
NOTE.DISC.COMMAND ();
@BOX 6.1
ALLOW.INTERRUPTS;
@BOX 7.1
END
@END
@TITLE AP502.2.1(3,11)
@COL 1S-3R-4T-5R-7F
@COL 8R

@FLOW 1-3-4NO-5-7
@FLOW 4YES-8-7
@BOX 1.0
NOTE DISC COMMAND
@BOX 3.0
CLEAR HW INT
[AP501]
@BOX 4.0
COMMAND BITS CLEAR?
@BOX 5.0
START TRANSFER
[AP502.3]
@BOX 7.0
END
@BOX 8.0
RETURN STATUS
@BOX 1.1
PROC NOTE.DISC.COMMAND;
@BOX 3.1
SELECT DISC.VARS [UNIT + 1];
IF DISC.STATUS & %F00 /= 0 AND
   1 -> HW.INT.COUNT = 0 THEN
   CLEAR.HW.INT (SYS01.DISC.ACTIVITY);
FI
@BOX 4.1
DISC.STATUS & %8000 ! VV.DISC.CONTROL [UNIT] => DISC.STATUS;
IF DISC.STATUS & 3 = 0
@BOX 5.1
VV.DISC.D.ADDRESS [UNIT] => D.ADDR;
VV.DISC.C.ADDRESS [UNIT] => C.ADDR;
VV.DISC.SIZE [UNIT] => SECTOR.COUNT;
START.TRANSFER (UNIT + 1);
@BOX 7.1
END
@BOX 8.1
DISC.STATUS & %8000 => VV.DISC.CONTROL [UNIT];
SECTORS.PER.DISC - 1 => VV.DISC.D.ADDRESS [UNIT];
SECTOR.SIZE => VV.DISC.SIZE [UNIT];
@END
@TITLE AP502.3(3,11)
@COL 8N-9R-10N
@COL 1S-2T-3T-11T-4R-5R-6F
@COL 7R

@ROW 4-7
@ROW 2-8
@ROW 4-9

@FLOW 1-2NO-3NO-11FINISHED-4-5-6
@FLOW 2YES-8-10-6
@FLOW 3YES-7-5
@FLOW 11-9-10
@BOX 1.0
GEM DISC INTERRUPT
@BOX 2.0
DISC INACTIVE?
@BOX 3.0
DISC IN ERROR?
@BOX 4.0
NOTE TRANSFER COMPLETE
@BOX 5.0
SET HW INT
[AP501]
@BOX 6.0
END
@BOX 7.0
NOTE TRANSFER FAILED
@BOX 9.0
START TRANSFER
@BOX 11.0
TRANSFER FINISHED
@BOX 1.1
GEM.INT.0:
*#%3F3C %0000; ::MOVW #0, -(A7);
*#%2F3C %0000 %001D; ::MOVL #29, -(A7);
*#%4EF9 %0080 %0000; ::JMP ENTRY CODE;
GEM.INT.1:
*#%3F3C %0001; ::MOVW #1, -(A7);
*#%2F3C %0000 %001D; ::MOVL #29, -(A7);
*#%4EF9 %0080 %0000; ::JMP ENTRY CODE;
PROC GEM.DISC.INT (DISC.UNIT);
@BOX 2.1
SELECT DISC.VARS [DISC.UNIT];
IF DISC.STATUS & 3 = 0
@BOX 3.1
SELECT DISC.PACKET^;
IF STATUS1 /= 0
@BOX 4.1
%100 !> DISC.STATUS;
@BOX 5.1
IF DISC.UNIT = 0 THEN
   DISC.STATUS => VV.DRUM.CONTROL;
   SET.HW.INT (SYS01.DRUM.ACTIVITY);
ELSE
   DISC.STATUS => VV.DISC.CONTROL [DISC.UNIT - 1];
   IF 1 +> HW.INT.COUNT = 1 THEN
      SET.HW.INT (SYS01.DISC.ACTIVITY);
   FI
FI
@BOX 6.1
END
@BOX 7.1
%200 !> DISC.STATUS;
@BOX 9.1
START.TRANSFER (DISC.UNIT);
@BOX 11.1
IF SECTOR.COUNT /= 0
@END

@TITLE AP502.4(3,11)

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

@FLOW 1-2-3-4

@BOX 1.0
START TRANSFER (DISC UNIT)
@BOX 2.0
INITIALISE PACKET
@BOX 3.0
SEND COMMAND
@BOX 4.0
END
@BOX 1.1
PROC START.TRANSFER (DISC.UNIT);
INTEGER TRAN.SIZE;
@BOX 2.1
SELECT DISC.VARS [DISC.UNIT];
SELECT DISC.PACKET^;
%11 => CMD1;
DISC.STATUS & 3 -= 3 => CMD2;
0 => STATUS1 => STATUS2;
D.ADDR => SECTOR;
IF DISC.UNIT = 0 THEN
   %2000 / SECTOR.SIZE +> SECTOR;
FI
IF SECTORS.PER.DRIVE = 0 THEN
   SECTOR.SIZE / 256 * %10 => CONTROL;
ELSE
   SECTOR / SECTORS.PER.DRIVE => CONTROL *
      SECTORS.PER.DRIVE -> SECTOR;
FI
IF SECTOR.COUNT => TRAN.SIZE > MAX.SECT THEN
   MAX.SECT => TRAN.SIZE;
FI
TRAN.SIZE => NO.OF.SECTORS;
0 => ZERO => CMD.COUNT;
1 => DATA.COUNT;
C.ADDR * SECTOR.SIZE => DATA.ADDR;
TRAN.SIZE * SECTOR.SIZE => BYTE.COUNT;
TRAN.SIZE -> SECTOR.COUNT;
TRAN.SIZE +> C.ADDR;
TRAN.SIZE +> D.ADDR;
@BOX 3.1
0 => CMD.REQUEST^;
@BOX 4.1
END
@END


