@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP5123
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP5123
~S~M~OAP5 IMPLEMENTATION DESCRIPTION
~S~M~OSection 12 Version 3
~S~O12.1 ROM Drum Appendix (GEMSTONE)
~S1~O1. General Description
~BThis module implements polling type disc procedures for use
by the ROM monitor, the disc copy modle 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               AP5123
~V9 -1
~F
@TITLE AP512(3,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
GEMSTONE 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);
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.DISCS (INTEGER);
PSPEC DISC.TRAN (LOGICAL32, LOGICAL32, LOGICAL, LOGICAL, LOGICAL) / INTEGER;
PSPEC FORMAT (INTEGER);
PSPEC DISC.STATUS (LOGICAL8,LOGICAL8) / INTEGER;
PSPEC READ.SYSTEM (INTEGER, INTEGER) / ADDR;
PSPEC INIT.DISC () / INTEGER;
PROC INIT.DISC;
   INIT.DISCS (DEFAULT.D);
   DEFAULT.D => INIT.DISC;
END
#AP512.2
#AP512.3
#AP512.4
#AP512.5
#AP512.6
@BOX 4.1
*END
@END
@TITLE AP512/1(3,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
TYPE PACKET IS
   LOGICAL8 CMD1, CMD2, STATUS1, STATUS2
   LOGICAL32 SECTOR
   LOGICAL8 SECTOR.SIZE, NO.OF.SECTORS
   LOGICAL16 ZERO
   LOGICAL8 CMD.COUNT, DATACOUNT
   LOGICAL32 DATA.ADDR
   LOGICAL16 BYTE.COUNT;
*VTYPE LOGICAL;
VSTORE VERSION.NO %A0000;
VSTORE V.DRIVE.NO %80C02;
VSTORE V.DISC.TYPE %80C04
@BOX 3.1
LITERAL / LOGICAL8 CON = 1, SEL = 2, BSY = %10, BSY.CON = %11,
   H1S = 1, H3S = 4;
*GLOBAL 3;
LITERAL NUM.D.TYPES = 3;
LITERAL / LOGICAL READ = 0, WRITE = 1;
LITERAL / LOGICAL8 LF = %A;
LITERAL DEFAULT.D = 1;
INTEGER8 [NUM.D.TYPES] INIT.FLAG;
*GLOBAL 1;
DATAVEC DT0 (LOGICAL8)
   "Fixed, (Lotus)" LF
END
DATAVEC DT1 (LOGICAL8)
   "Fixed, (SCSI)" LF
END
DATAVEC DT2 (LOGICAL8)
   "Floppy" LF
END
DATAVEC DISC.TYPES (ADDR [LOGICAL8])
   DT0 DT1 DT2
END
DATAVEC DISC.PACKET (ADDR)
   %40D880
   %40D880
   %40DC80
END
DATAVEC CMD.REQUEST (ADDR)
   %685800
   %685800
   %685C00
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 512 512
END
DATAVEC S.SIZE (LOGICAL)
   %10 0 %20
END
DATAVEC MAX.SECTORS (INTEGER)
   %4000 %4000 1
END
*GLOBAL 3;
*CODE 1;
@BOX 4.1
::END
@END
@TITLE AP512.2(3,11)

@COL 1S-2R-3R-4R-5R-8R-10T-9F
@FLOW 1-2-3-4-5-8-10FINISHED-9
@FLOW 10-3
@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
SEND COMMAND PACKET
@BOX 5.0
WAIT FOR TRANSFER
TO COMPLETE
@BOX 8.0
GET STATUS
@BOX 9.0
END
@BOX 10.0
TRANSFER COMPLETE?
@BOX 1.1
PROC DISC.TRAN (D.ADDR, C.ADDR, DISC.TYPE, TRAN.SIZE, DIRN);
INTEGER I, SCALE;
LOGICAL8 [6] CMD.BUFFER;
ADDR PACKET PACK;
ADDR LOGICAL16 CMD;

IF DISC.TYPE /= 2 AND
   INIT.FLAG [DISC.TYPE] /= 1 THEN
   INIT.DISCS (DISC.TYPE);
FI
@BOX 2.1
SEC.SIZE [DISC.TYPE] / 256 => SCALE;
SCALE /> TRAN.SIZE;
SCALE /> D.ADDR;
MAKE (PACKET, 0, DISC.PACKET[DISC.TYPE]) => PACK;
MAKE  (LOGICAL16, 0, CMD.REQUEST[DISC.TYPE]) => CMD;
SELECT PACK^;
@BOX 3.1
%11 => CMD1;
(IF DIRN = READ THEN 2 ELSE 1) => CMD2;
%FF => STATUS1 => STATUS2;
D.ADDR => SECTOR;
IF TRANSIZE => NO.OF.SECTORS > MAX.SECTORS [DISC.TYPE] THEN
   MAX.SECTORS [DISC.TYPE] => NO.OF.SECTORS;
FI
S.SIZE [DISC.TYPE] => SECTOR.SIZE;
0 => ZERO => CMD.COUNT;
1 => DATA.COUNT;
C.ADDR => DATA.ADDR;
NO.OF.SECTORS * SEC.SIZE [DISC.TYPE] => BYTE.COUNT;
NO.OF.SECTORS -> TRAN.SIZE;
NO.OF.SECTORS +> D.ADDR;
BYTE.COUNT +> C.ADDR;
@BOX 4.1
0 => CMD^;
@BOX 5.1
WHILE STATUS2 = %FF DO OD
@BOX 8.1
DISC.STATUS (DIRN,DISC.TYPE) => DISC.TRAN;
@BOX 9.1
END
@BOX 10.1
IF DISC.TRAN = 0 AND TRAN.SIZE /= 0

@END
@TITLE AP512.3(3,11)
@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.STATUS (WRITE,DISC.TYPE);
@BOX 4.1
END
@END
@TITLE AP512.4(3,11)
@COL 1S-2R-5R-6R-3R-4F
@FLOW 1-2-5-6-3-4
@BOX 1.0
INIT.DISC
@BOX 2.0
SET UP COMMAND BUFFER
FOR INITIALISE COMMAND
@BOX 3.0
RETURN DEFAULT DISC TYPE
@BOX 4.0
END
@BOX 5.0
SEND COMMAND PACKET
@BOX 6.0
WAIT FOR INITIALISATION
TO COMPLETE
@BOX 1.1
PROC INIT.DISCS (D.TYPE);
ADDR LOGICAL16 CMD;
ADDR PACKET PACK;
@BOX 2.1
VSTORE CLEAR %704000;
VSTORE INT.NO %40DBFE;
0 => CLEAR => INT.NO;
MAKE (PACKET, 0, DISC.PACKET [D.TYPE]) => PACK;
MAKE (LOGICAL16, 0, CMD.REQUEST [D.TYPE]) => CMD;
SELECT PACK^;
%11 => CMD1;
%5 => CMD2;
%FF => STATUS1 => STATUS2;
0 => SECTOR => NO.OF.SECTORS => SECTOR.SIZE
   => ZERO;
1 => CMD.COUNT;
1 => DATA.COUNT;
%10000 => DATA.ADDR;
%100 => BYTE.COUNT;
@BOX 3.1
1 => INIT.FLAG [D.TYPE];
@BOX 4.1
END
@BOX 5.1
0 => CMD^;
@BOX 6.1
WHILE STATUS2 = %FF DO OD
@END
@TITLE AP512.5(3,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
$PR DISC.STATUS (IO.TYPE, DISC.TYPE);
ADDR PACKET PACK;
@BOX 2.1
MAKE (PACKET, 0, DISC.PACKET [DISC.TYPE]) => PACK;
SELECT PACK^;
IF STATUS.1 => DISC.STATUS = 0
@BOX 3.1
IF IO.TYPE = READ
  THEN PRINT (^READ.MSG)
  ELSE PRINT (^WRITE.MSG) FI;
PRINT (^ERROR.MESS);
PUT.HEX.CONS (STATUS.2,8);
PUT.CONS (LF);
L1: -> L1;
@BOX 4.1
END
@END
@TITLE AP512.6(3,11)

@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
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;
DISC.TYPE => V.DRIVE.NO;
DISC.TYPE => V.DISC.TYPE;
@BOX 5.1
CORE.ADDR^ [2] => READ.SYSTEM;
END
@END

