DIRECTORY Atom,Basics,Dyn,Ports,Simul2Sender; Simul2SenderImpl: CEDAR PROGRAM IMPORTS Atom,Basics,Ports EXPORTS Simul2Sender ~ BEGIN 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 ANY _ NIL ] RETURNS []; bitSend: NAT=5; bitStop: NAT=6; ClrMsgSent: NAT=9; readBlockRequest: NAT = 0; writeBlockRequest: NAT = 2; 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 AllMsg: NAT = 13; NextLine: SimpleProc ~ { dynaport.testProcList _ dynaport.testProcList.rest; dynaport.countcycle _ 0; }; Jump: SimpleProc ~ { label: ATOM _ NARROW[params.first]; dynaport.testProcList _ NARROW[Atom.GetProp[$Simul2Sender, $PKList]]; WHILE dynaport.testProcList.first # label DO NextLine[dynaport]; ENDLOOP; }; Wait: SimpleProc ~ { countcycle: CARD _ NARROW[params.first, REF CARD]^; IF dynaport.countcycle < countcycle THEN dynaport.countcycle _ dynaport.countcycle + 1 ELSE NextLine[dynaport]; }; WaitMsgSent: SimpleProc ~ { IF dynaport.status[MsgSent] = H THEN NextLine[dynaport]; }; WaitMsgReceived: SimpleProc ~ { 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 ~ { 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~ { 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 [] ~ { 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 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~ { 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 ~ { address: CARD _ NARROW[params.first, REF CARD]^; 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~ { data0, data1, data2, data3: QWord; address: CARD _ NARROW[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]^; 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]}; 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. ςSimul2SenderImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Created by Jean Gastinel, October 26, 1987 3:31:27 pm PST Service Types HARDWARE DEFINITIONS Definition of the register rqlar Definition of the DynaBus Command Definition of the Status register Definition of the SendParam register Service Procs Jump to cycle line number : lnb This proc count "countcycle" cycle before going to the next instruction This proc tests the bit "MsgSent" of status, if it is H goto Nextline 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 This proc initialise the dynaport This proc initialise the "sendpar" for receiving all the messages This is the Proc which compute the command i=0 for the Header, i=1 for the Parity, i=2 & 3 for Spare With the bit "load" active, this proc set and reset the bit "send" This proc send a read command at the address "address" Set mode Request low priority: "10", Length 2 : This proc send a WriteBlock Request command at the address "address", with value "data" "address" is the first parameter, "data" is the second Set mode Request High priority: "11", Length 5 : Simulation Procs Κ »˜codešœ™Kšœ<™Kšœ˜K˜—Kšœ‘˜,Kšœ‘˜*K˜šœœœ ˜Kšœ;˜;Kšœ˜—šœœœ ˜Kšœ˜Kšœ˜—šœœœ ˜Kšœ7˜7Kšœ˜—K˜—K˜š  œœIœ˜fK˜Kšœœœ ˜DKšœœœ ˜DKšœœœ ˜DKšœœœ ˜DKšœœœ ˜DKšœœœ ˜DKšœœœ ˜DKšœœœ ˜DK˜šœ œ˜Kšœ‘œ‘œ‘™9Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ œ ˜Kšœ6˜6Kšœ6˜6Kšœ7˜7Kšœ9˜9Kšœ˜—šœ œ ˜Kšœ7˜7Kšœ7˜7Kšœ8˜8Kšœ:˜:Kšœ˜—K˜K˜K˜—Kš  œ˜˜K™Cšœ˜Kšœ3˜3Kšœ‘ ˜'Kšœ˜Kšœ3˜3Kšœ˜Kšœ1˜8Kšœ˜Kšœ˜—K˜K˜K˜—šΠbn œ˜Kšœ6™6Kš œ œœœœ˜0Kšœ™K™/Kšœ˜Kšœ˜Kšœ˜K˜KšœO˜OKšœJ˜JK˜Kšœ˜Kšœ˜K˜K˜—š  œ˜K˜KšœW™WK™6K™Kšœ"˜"Kš œ œœœœ˜0Kš œœœœœ˜$Kšœœ œ˜9Kšœœ œ˜9Kšœœ œ˜9Kšœœ œ ˜'K˜K™0Kšœ‘ ˜"Kšœ˜Kšœ‘ ˜ K˜KšœP˜PKšœJ˜JKšœ˜K˜K˜K˜—Kš œœœœœœ œœ˜?Kš Ÿœœ œœœ œ ˜Ahead™šŸœœœœ˜Ašœœœ˜%Kšœœ'˜EKšœ˜K˜—Kš˜˜š œœœ œœœœœœ˜MKšœ˜Kšœœœ%˜/šœœœ˜Kšœœœ˜ Kšœ˜Kšœœ˜ K˜—šœ˜Kšœ˜Kšœœ˜Kšœ˜—Kšœ˜K˜—šœœ˜,Kš œœœœœœ˜7š œœœœœ˜šœ œ˜Kš œœœ#œœ˜=Kšœœ˜—K˜—Kšœœ˜—Kšœ˜—K˜—K˜Kšœ#œ˜;Kšœ)œ˜GKšœ(œ˜EKšœ)œ˜GKšœ*œ˜IKšœ#œ˜;Kšœ*œ˜IKšœ.œ ˜QKšœ#œ˜;K˜šœ%œ˜*Kšœ˜Kšœ˜Kšœ ˜ K˜ Kšœ˜"Kšœ˜Kšœ ˜Kšœ†˜ŒKšœ˜Kšœ ˜Kšœ˜Kšœ˜—K™—Kšœ˜K™L™K™J˜—…—.»