Simul2SenderImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Created by Jean Gastinel, October 26, 1987 3:31:27 pm PST
DIRECTORY
Atom,Basics,Dyn,Ports,Simul2Sender;
Simul2SenderImpl: CEDAR PROGRAM
IMPORTS Atom,Basics,Ports
EXPORTS Simul2Sender
~ BEGIN
Service Types
QWord: TYPE = ARRAY [0 .. 2) OF CARD;
WordAsBits: TYPE = PACKED ARRAY [0..16) OF BOOL;
DWAsBits: TYPE = PACKED ARRAY [0..32) OF BOOL;
SimpleProc: TYPE = PROC[dynaport: Dyn.DynaPortState, params: LIST OF REF ANYNIL ] RETURNS [];
HARDWARE DEFINITIONS
Definition of the register rqlar
bitSend: NAT=5;
bitStop: NAT=6;
ClrMsgSent: NAT=9;
Definition of the DynaBus Command
readBlockRequest: NAT = 0;
writeBlockRequest: NAT = 2;
Definition of the Status register
MsgSent: NAT = 0; -- this bit is set when a message has been sent
MsgHere: NAT = 1; -- this bit is set when a message is received
Definition of the SendParam register
AllMsg: NAT = 13;
Service Procs
NextLine: SimpleProc ~ {
dynaport.testProcList ← dynaport.testProcList.rest;
dynaport.countcycle ← 0;
};
Jump: SimpleProc ~ {
Jump to cycle line number : lnb
label: ATOMNARROW[params.first];
dynaport.testProcList ← NARROW[Atom.GetProp[$Simul2Sender, $PKList]];
WHILE dynaport.testProcList.first # label DO
NextLine[dynaport];
ENDLOOP;
};
Wait: SimpleProc ~ {
This proc count "countcycle" cycle before going to the next instruction
countcycle: CARDNARROW[params.first, REF CARD]^;
IF dynaport.countcycle < countcycle THEN dynaport.countcycle ← dynaport.countcycle + 1
ELSE NextLine[dynaport];
};
WaitMsgSent: SimpleProc ~ {
This proc tests the bit "MsgSent" of status, if it is H goto Nextline
IF dynaport.status[MsgSent] = H THEN NextLine[dynaport];
};
WaitMsgReceived: SimpleProc ~ {
This proc tests the bit "MsgHere" of status, if it is H goto Nextline
After clear this bit in setting and resetting the bit "ClrMsgSent" of the rqlar register
IF dynaport.status[MsgHere] = H AND dynaport.countcycle =0
THEN {
dynaport.countcycle ← 1;
dynaport.rqlar[ClrMsgSent] ← H;
dynaport.load ← H }
ELSE
IF dynaport.countcycle =1
THEN{
dynaport.countcycle ← 2;
dynaport.rqlar[ClrMsgSent] ← L}
ELSE IF dynaport.countcycle=2 THEN{
dynaport.load ← L;
NextLine[dynaport]};
};
Init: SimpleProc ~ {
This proc initialise the dynaport
Ports.LCToLS[0,dynaport.rqlar];
Ports.LCToLS[0,dynaport.sendpar];
dynaport.send ← H; -- for this version send is not useful (only for DbugBus)
Ports.LCToLS[0,dynaport.alpha];
Ports.LCToLS[11111111H,dynaport.beta];
Ports.LCToLS[22222222H,dynaport.gama];
Ports.LCToLS[33333333H,dynaport.delta];
Ports.LCToLS[44444444H,dynaport.epsilon];
IF dynaport.countcycle<4 THEN
{ dynaport.countcycle ← dynaport.countcycle+1;
dynaport.load ← H }
ELSE
{ dynaport.countcycle ← 0;
dynaport.load ← L };
NextLine[dynaport];
};
ReceiveAll:SimpleProc~ {
This proc initialise the "sendpar" for receiving all the messages
dynaport.sendpar[AllMsg] ← H;
NextLine[dynaport];
};
StartStop: SimpleProc ~ {
SELECT dynaport.countcycle FROM
<5 => {
dynaport.rqlar[bitStop] ← L;
dynaport.countcycle ← dynaport.countcycle+1;
dynaport.load← H };
IN [5..16] => {
dynaport.rqlar[bitStop] ← H;
dynaport.countcycle ← dynaport.countcycle+1;
dynaport.load← H};
ENDCASE => {
dynaport.rqlar[bitStop] ← L;
dynaport.countcycle ← dynaport.countcycle+1;
dynaport.load ← L;
NextLine[dynaport] };
};
MergeCom: PROC [dynaport: Dyn.DynaPortState, cmd: NAT, deviceId: NAT, adrs: CARD] RETURNS [] ~ {
This is the Proc which compute the command
cmdbits: WordAsBits ← LOOPHOLE[cmd];
deviceIdbits: WordAsBits ← LOOPHOLE[deviceId];
adrsbits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[adrs]]];
dynaport.alpha[0] ← H; -- For the Header
dynaport.alpha[1] ← L; -- For the Parity
dynaport.alpha[2] ← L; -- For Spare
dynaport.alpha[3] ← L; -- For Spare
FOR bit: INT IN [4..9) DO
dynaport.alpha[bit] ← Ports.ToLevel[cmdbits[bit+7]]; -- -4+11
ENDLOOP;
dynaport.alpha[9] ← L; -- For the Mode/Fault
dynaport.alpha[10] ← L; -- For Rply/Shared
FOR bit: INT IN [11..21) DO
dynaport.alpha[bit] ← Ports.ToLevel[deviceIdbits[bit-10]];
ENDLOOP;
FOR bit: INT IN [21..36) DO
dynaport.alpha[bit] ← L;
ENDLOOP;
FOR bit: INT IN [36..68) DO
dynaport.alpha[bit] ← Ports.ToLevel[adrsbits[bit-36]];
ENDLOOP;
};
MergeData: PROC [dynaport: Dyn.DynaPortState, d0: QWord,d1: QWord, d2: QWord,d3:QWord ] RETURNS [] ~ {
dataH0bits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[d0[0]]]];
dataL0bits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[d0[1]]]];
dataH1bits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[d1[0]]]];
dataL1bits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[d1[1]]]];
dataH2bits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[d2[0]]]];
dataL2bits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[d2[1]]]];
dataH3bits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[d3[0]]]];
dataL3bits: DWAsBits ← LOOPHOLE[Basics.SwapHalves[LOOPHOLE[d3[1]]]];
FOR bit: NAT IN [0..4) DO
i=0 for the Header, i=1 for the Parity, i=2 & 3 for Spare
dynaport.beta[bit] ← L;
dynaport.gama[bit] ← L;
dynaport.delta[bit] ← L;
dynaport.epsilon[bit] ← L;
ENDLOOP;
FOR bit: NAT IN [4..36) DO
dynaport.beta[bit] ← Ports.ToLevel[dataH0bits[bit-4]];
dynaport.gama[bit] ← Ports.ToLevel[dataH1bits[bit-4]];
dynaport.delta[bit] ← Ports.ToLevel[dataH2bits[bit-4]];
dynaport.epsilon[bit] ← Ports.ToLevel[dataH3bits[bit-4]];
ENDLOOP;
FOR bit: NAT IN [36..68) DO
dynaport.beta[bit] ← Ports.ToLevel[dataL0bits[bit-36]];
dynaport.gama[bit] ← Ports.ToLevel[dataL1bits[bit-36]];
dynaport.delta[bit] ← Ports.ToLevel[dataL2bits[bit-36]];
dynaport.epsilon[bit] ← Ports.ToLevel[dataL3bits[bit-36]];
ENDLOOP;
};
SendRequest: SimpleProc~ {
With the bit "load" active, this proc set and reset the bit "send"
SELECT dynaport.countcycle FROM
0 => { dynaport.countcycle ← dynaport.countcycle+1;
dynaport.rqlar[bitSend] ← H; --bit send
dynaport.load ← H; };
1 => { dynaport.countcycle ← dynaport.countcycle+1;
dynaport.rqlar[bitSend] ← L };
ENDCASE => {dynaport.countcycle ← dynaport.countcycle+1;
dynaport.load ← L;
NextLine[dynaport] };
};
ReadMemory: SimpleProc ~ {
This proc send a read command at the address "address"
address: CARDNARROW[params.first, REF CARD]^;
Set mode Request low priority: "10", Length 2 :
dynaport.rqlar[0] ← H;
dynaport.rqlar[1] ← L;
dynaport.rqlar[2] ← L;
MergeCom[dynaport: dynaport,cmd: readBlockRequest, deviceId: 0, adrs: address];
MergeData[dynaport: dynaport, d0: [0,0], d1: [0,0], d2: [0,0], d3: [0,0]];
SendRequest[dynaport]
};
WriteMemory: SimpleProc~ {
This proc send a WriteBlock Request command at the address "address", with value "data"
"address" is the first parameter, "data" is the second
data0, data1, data2, data3: QWord;
address: CARDNARROW[params.first, REF CARD]^;
par1: LIST OF REF ANY ← params.rest;
data0 ← NARROW[par1.first, REF QWord]^; par1 ← par1.rest;
data1 ← NARROW[par1.first, REF QWord]^; par1 ← par1.rest;
data2 ← NARROW[par1.first, REF QWord]^; par1 ← par1.rest;
data3 ← NARROW[par1.first, REF QWord]^;
Set mode Request High priority: "11", Length 5 :
dynaport.rqlar[0] ← H; -- priority
dynaport.rqlar[1] ← H;
dynaport.rqlar[2] ← H; -- length
MergeCom[dynaport: dynaport,cmd: writeBlockRequest, deviceId: 0, adrs: address];
MergeData[dynaport: dynaport, d0: data0, d1: data1, d2: data2, d3: data3];
SendRequest[dynaport]
};
A: PROC [c: CARD] RETURNS [rc: REF ANY] = {rc ← NEW[CARD ← c]};
Q: PROC [c: QWord] RETURNS [rc: REF ANY] = {rc ← NEW[QWord ← c]};
Simulation Procs
SendBus: PUBLIC PROC [dynaport: Dyn.DynaPortState] RETURNS [] ~ {
IF dynaport.testProcList = NIL THEN {
dynaport.testProcList ← NARROW[Atom.GetProp[$Simul2Sender, $PKList]];
};
DO
AtomDidSomething: PROC [atom: ATOM, params: LIST OF REF ANY] RETURNS [BOOL] =
{
v: REF ANY = Atom.GetProp[$Simul2Sender, atom];
IF v # NIL THEN {
spr: REF SimpleProc = NARROW[v];
spr^[dynaport, params];
RETURN[TRUE];
}
ELSE {
NextLine[dynaport];
RETURN[FALSE];
};
};
WITH dynaport.testProcList.first SELECT FROM
atom: ATOM => IF AtomDidSomething[atom, NIL] THEN EXIT;
list: LIST OF REF ANY => {
WITH list.first SELECT FROM
atom: ATOM => IF AtomDidSomething[atom, list.rest] THEN EXIT;
ENDCASE => ERROR;
};
ENDCASE => ERROR;
ENDLOOP;
};
Atom.PutProp[$Simul2Sender, $Init, NEW[SimpleProc ← Init]];
Atom.PutProp[$Simul2Sender, $ReceiveAll, NEW[SimpleProc ← ReceiveAll]];
Atom.PutProp[$Simul2Sender, $StartStop, NEW[SimpleProc ← StartStop]];
Atom.PutProp[$Simul2Sender, $ReadMemory, NEW[SimpleProc ← ReadMemory]];
Atom.PutProp[$Simul2Sender, $WriteMemory, NEW[SimpleProc ← WriteMemory]];
Atom.PutProp[$Simul2Sender, $Wait, NEW[SimpleProc ← Wait]];
Atom.PutProp[$Simul2Sender, $WaitMsgSent, NEW[SimpleProc ← WaitMsgSent]];
Atom.PutProp[$Simul2Sender, $WaitMsgReceived, NEW[SimpleProc ← WaitMsgReceived]];
Atom.PutProp[$Simul2Sender, $Jump, NEW[SimpleProc ← Jump]];
Atom.PutProp[$Simul2Sender, $PKList, LIST[
$Init,
$ReceiveAll,
$StartStop,
$Restart,
LIST[$ReadMemory, A[01234567H]],
$WaitMsgReceived,
$WaitMsgSent,
LIST[$WriteMemory, A[01ABCDEF],
Q[[11223344H,55667788H]],Q[[22334455H,66778899H]],
Q[[33445566H,77889900H]],Q[[44556677H,88990011H]]],
$WaitMsgReceived,
$WaitMsgSent,
LIST[$Jump, $Restart]
]];
END.