<> <> <> <<>> <<>> 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~ { <> <<"address" is the first parameter, "data" is the second>> <<>> 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. <<>> <<>> <<>>