-- File: [Indigo]<Sakura>Dragon>DragonProcessorImpl6.sak
-- Dragon processor with random fetch
-- 10-Mar-82 12:36:24
DIRECTORY
DragonCache: TYPE,
DragonProcessor: TYPE,
SakuraRT: TYPE,
SimIO: TYPE;
DragonProcessorImpl6: MONITOR
IMPORTS DragonCache, SakuraRT, SimIO
EXPORTS DragonProcessor
= BEGIN
Processor: PUBLIC PROC
[ClockA, ClockB, Fault, Reject: SakuraRT.Handle, InData: SakuraRT.Handle,
Op: SakuraRT.Handle, RQ: SakuraRT.Handle, OutData: SakuraRT.Handle] = {
Store: PROC [loc: CARDINAL, data: LONG CARDINAL] = {
vp: LONG CARDINAL;
bl: INTEGER [0..37B];
word: INTEGER [0..3];
printval: LONG CARDINAL;
[vp, bl, word] ← SplitAddress[loc];
printval ← word + bl * 4 + vp * 128;
SakuraRT.GetNew[ClockB, TRUE];
{SakuraRT.Put[RQ, NEW[BOOLEAN ← TRUE]];
SakuraRT.Put[Op, NEW[DragonCache.PbusOp ← Store]];
SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Instruction[vp, bl, word]]]]};
DO SakuraRT.GetNew[ClockA, TRUE];
IF NOT NARROW[SakuraRT.Get[Reject], REF BOOLEAN]↑ THEN EXIT
ENDLOOP;
SimIO.WF1[" Proc1: Store started %ld*n", @printval];
SakuraRT.GetNew[ClockB, TRUE];
SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Data[data]]]];
-- Match
SakuraRT.GetNew[ClockB, TRUE]; SakuraRT.Put[RQ, NEW[BOOLEAN ← FALSE]];
SimIO.WF1[" Proc1: Store finished %ld*n", @printval]};
StoreAndRead: PROC [loc, prevloc: CARDINAL, data, prevdata: LONG CARDINAL] = {
vp, prevvp: LONG CARDINAL;
bl, prevbl: INTEGER [0..37B];
word, prevword: INTEGER [0..3];
printval: LONG CARDINAL;
[vp, bl, word] ← SplitAddress[loc];
printval ← word + bl * 4 + vp * 128;
SakuraRT.GetNew[ClockB, TRUE];
{SakuraRT.Put[RQ, NEW[BOOLEAN ← TRUE]];
SakuraRT.Put[Op, NEW[DragonCache.PbusOp ← Store]];
SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Instruction[vp, bl, word]]]]};
DO SakuraRT.GetNew[ClockA, TRUE];
IF NOT NARROW[SakuraRT.Get[Reject], REF BOOLEAN]↑ THEN EXIT
ENDLOOP;
[prevvp, prevbl, prevword] ← SplitAddress[prevloc];
SakuraRT.Delay[40];
DragonCache.CheckVal[prevvp, prevbl, prevword, prevdata];
SimIO.WF1[" Proc1: Store started %ld*n", @printval];
SakuraRT.GetNew[ClockB, TRUE];
SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Data[data]]]];
-- Match
SakuraRT.GetNew[ClockB, TRUE]; SakuraRT.Put[RQ, NEW[BOOLEAN ← FALSE]];
SimIO.WF1[" Proc1: Store finished %ld*n", @printval]};
Fetch: PROC [loc: CARDINAL] = {
vp: LONG CARDINAL;
bl: INTEGER [0..37B];
word: INTEGER [0..3];
printval: LONG CARDINAL;
[vp, bl, word] ← SplitAddress[loc];
printval ← word + bl * 4 + vp * 128;
SakuraRT.GetNew[ClockB, TRUE];
{SakuraRT.Put[RQ, NEW[BOOLEAN ← TRUE]];
SakuraRT.Put[Op, NEW[DragonCache.PbusOp ← Fetch]];
SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Instruction[vp, bl, word]]]]};
DO SakuraRT.GetNew[ClockA, TRUE];
IF NOT NARROW[SakuraRT.Get[Reject], REF BOOLEAN]↑ THEN EXIT
ENDLOOP;
SimIO.WF1[" Proc1: Fetch started %ld*n", @printval];
SakuraRT.GetNew[ClockB, TRUE]; SakuraRT.Put[RQ, NEW[BOOLEAN ← FALSE]];
SimIO.WF1[" Proc1: Fetch finished %ld*n", @printval]};
FetchAndRead: PROC [loc: CARDINAL, data: CARDINAL] = {
vp: LONG CARDINAL;
bl: INTEGER [0..37B];
word: INTEGER [0..3];
printval: LONG CARDINAL;
[vp, bl, word] ← SplitAddress[loc];
printval ← word + bl * 4 + vp * 128;
SakuraRT.Put[RQ, NEW[BOOLEAN ← TRUE]];
SakuraRT.Put[Op, NEW[DragonCache.PbusOp ← Fetch]];
SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Instruction[vp, bl, word]]]];
DO SakuraRT.GetNew[ClockA, TRUE];
IF NOT NARROW[SakuraRT.Get[Reject], REF BOOLEAN]↑ THEN EXIT
ENDLOOP;
SimIO.WF1[" Proc1: Fetch started %ld*n", @printval];
SakuraRT.GetNew[ClockB, TRUE];
{SakuraRT.Delay[30];
WITH b: NARROW[SakuraRT.Get[InData], REF DragonCache.PbusType]↑ SELECT FROM
Data => IF data # b.data THEN ERROR
ENDCASE => ERROR;
SakuraRT.Put[RQ, NEW[BOOLEAN ← FALSE]]};
SimIO.WF1[" Proc1: Fetch finished %ld*n", @printval]};
Read: PROC [prevloc: CARDINAL, prevdata: LONG CARDINAL] = {
prevvp: LONG CARDINAL;
prevbl: INTEGER [0..37B];
prevword: INTEGER [0..3];
DO SakuraRT.GetNew[ClockA, TRUE];
IF NOT NARROW[SakuraRT.Get[Reject], REF BOOLEAN]↑ THEN EXIT
ENDLOOP;
[prevvp, prevbl, prevword] ← SplitAddress[prevloc];
SakuraRT.Delay[40];
DragonCache.CheckVal[prevvp, prevbl, prevword, prevdata]};
SplitAddress: PROC [loc: CARDINAL] RETURNS [vp: LONG CARDINAL,
bl: INTEGER [0..37B],
word: INTEGER [0..3]] = {
word ← loc MOD 4;
loc ← loc / 4;
bl ← loc MOD 40B;
vp ← loc / 40B};
i: CARDINAL;
{ENABLE {ABORTED => GO TO Aborted};
SakuraRT.Put[RQ, NEW[BOOLEAN ← FALSE]];
SakuraRT.GetNew[ClockB, TRUE]; NULL;
SakuraRT.GetNew[ClockB, TRUE]; NULL;
Store[0, 0];
FOR i IN [1..300) DO
StoreAndRead[i, i - 1, i * 2, i * 2 - 2]
ENDLOOP;
Fetch[0];
FOR i IN [1..300) DO
FetchAndRead[i, i * 2 - 2]
ENDLOOP;
Read[299, 299 * 2];
SimIO.WF0["Proc1: +++++++++++++++++++++++++++++++++++++++++++++++++++*n1000"];
SakuraRT.ProcessEnd[]}
EXITS
Aborted => SakuraRT.AbortAll[]};
END.