<> <> <> <<>> <<>> DIRECTORY Atom, Basics, PCConex, PCEmul, Ports, Rope; PCEmulImpl: CEDAR PROGRAM IMPORTS Atom, Basics, Ports EXPORTS PCEmul ~ BEGIN <> <<>> Mismatch: SIGNAL [msg: Rope.ROPE]= CODE; PCEvent: SIGNAL [msg: Rope.ROPE]= CODE; 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[pcemul: PCConex.PCEmulState, params: LIST OF REF ANY _ NIL ] RETURNS []; <> <<>> <> DSerialOut: NAT= 8; nDReset: NAT= 10; nDFreeze: NAT= 11; DExecute: NAT= 12; DSerialIn: NAT= 13; DAddress: NAT= 14; DShiftCk: NAT= 15; <
> dRegister: NAT=600FH; <> <<>> <<>> <> <<>> StopSimul: SimpleProc ~ { SIGNAL PCEvent["End of Simulation"]; NextLine[pcemul]; }; NextLine: SimpleProc ~ { pcemul.testProcList _ pcemul.testProcList.rest; pcemul.countcycle _ 0; }; Jump: SimpleProc ~ { <> label: ATOM _ NARROW[params.first]; pcemul.testProcList _ NARROW[Atom.GetProp[$PCEmul, $PKList]]; WHILE pcemul.testProcList.first # label DO NextLine[pcemul]; ENDLOOP; }; B: PROC [b: BOOL] RETURNS [rb: REF ANY] = {rb _ NEW[BOOL _ b]}; <<>> <> <<>> WaitSync: SimpleProc ~ { <> Flag: ATOM _ NARROW[params.first]; Cond: BOOL ; IF Atom.GetProp[$Sync,Flag]=NIL THEN Cond _ FALSE ELSE Cond _ NARROW[Atom.GetProp[$Sync,Flag],REF BOOL]^; IF Cond THEN NextLine[pcemul]; }; SetFlag: SimpleProc ~ { <> Flag: ATOM _ NARROW[params.first]; Atom.PutProp[$Sync,Flag, B[TRUE]]; NextLine[pcemul]; }; ClearFlag: SimpleProc ~ { <> Flag: ATOM _ NARROW[params.first]; Atom.PutProp[$Sync,Flag, B[FALSE]]; NextLine[pcemul]; }; Wait: SimpleProc ~ { <> countcycle: CARD _ NARROW[params.first, REF CARD]^; IF pcemul.countcycle < countcycle THEN pcemul.countcycle _ pcemul.countcycle + 1 ELSE NextLine[pcemul]; }; Init: SimpleProc~ { <> pcemul.dataout[nDReset] _ L; pcemul.dataout[nDFreeze] _ H; pcemul.dataout[DExecute] _ L; pcemul.dataout[DSerialIn] _ L; pcemul.dataout[DAddress] _ L; pcemul.dataout[DShiftCk] _ L; pcemul.nIORPC _ H; Ports.CToLS[dRegister,pcemul.address]; SELECT pcemul.countcycle FROM 0 => { pcemul.nIOWPC _ L; pcemul.countcycle_ pcemul.countcycle+1} ENDCASE => { pcemul.nIOWPC _ H; NextLine[pcemul]} }; Reset: SimpleProc~ { <> IF pcemul.nIOWPC=H THEN { pcemul.nIOWPC_ L; SELECT pcemul.countcycle FROM 0 => { pcemul.dataout[nDReset] _ L; pcemul.dataout[DShiftCk] _ H; pcemul.countcycle_ pcemul.countcycle+1}; IN [1..6] => { pcemul.dataout[DShiftCk] _ L; pcemul.countcycle_ pcemul.countcycle+1}; 7=> { pcemul.dataout[nDReset] _ H; pcemul.countcycle_ pcemul.countcycle+1}; ENDCASE => { pcemul.dataout[DShiftCk] _ L; NextLine[pcemul]}; } ELSE pcemul.nIOWPC_ H; }; ResetOn: SimpleProc~ { <> IF pcemul.nIOWPC=H THEN { pcemul.nIOWPC_ L; SELECT pcemul.countcycle FROM 0 => { pcemul.dataout[nDReset] _ L; pcemul.dataout[DShiftCk] _ H; pcemul.countcycle_ pcemul.countcycle+1}; 1 => { pcemul.dataout[DShiftCk] _ L; pcemul.countcycle_ pcemul.countcycle+1}; ENDCASE => { pcemul.dataout[DShiftCk] _ L; NextLine[pcemul]}; } ELSE pcemul.nIOWPC_ H; }; ResetOff: SimpleProc~ { <> IF pcemul.nIOWPC=H THEN { pcemul.nIOWPC_ L; SELECT pcemul.countcycle FROM 0 => { pcemul.dataout[nDReset] _ H; pcemul.dataout[DShiftCk] _ H; pcemul.countcycle_ pcemul.countcycle+1}; 1 => { pcemul.dataout[DShiftCk] _ L; pcemul.countcycle_ pcemul.countcycle+1}; ENDCASE => { pcemul.dataout[DShiftCk] _ L; NextLine[pcemul]}; } ELSE pcemul.nIOWPC_ H; }; SendDBusAddress: SimpleProc ~ { <> adrs: CARDINAL _ NARROW[params.first, REF CARDINAL]^; adrsbits: WordAsBits _ LOOPHOLE[adrs]; IF pcemul.nIOWPC=H THEN { pcemul.nIOWPC_ L; SELECT pcemul.countcycle FROM IN [0..32) => { pcemul.dataout[DAddress] _ H; IF (pcemul.countcycle MOD 2)=0 THEN { pcemul.dataout[DShiftCk] _ L; pcemul.dataout[DSerialIn] _ IF adrsbits[pcemul.countcycle/2] THEN H ELSE L} ELSE pcemul.dataout[DShiftCk] _ H; pcemul.countcycle_ pcemul.countcycle+1; }; ENDCASE => { pcemul.countcycle_ pcemul.countcycle+1; pcemul.dataout[DAddress] _ L; pcemul.dataout[DShiftCk] _ L}; } ELSE IF pcemul.countcycle < 33 THEN pcemul.nIOWPC_ H ELSE { pcemul.nIOWPC_ H; NextLine[pcemul]}; }; SendDBusData: SimpleProc ~ { <> nb: CARDINAL _ NARROW[params.rest.first, REF CARDINAL]^; --number of bits to send data: CARD _ NARROW[params.first, REF CARD]^; databits: DWAsBits_ LOOPHOLE[Basics.SwapHalves[LOOPHOLE[data]]]; IF pcemul.nIOWPC=H THEN { pcemul.nIOWPC_ L; IF pcemul.countcycle < 2*nb THEN { IF (pcemul.countcycle MOD 2)=0 THEN { pcemul.dataout[DShiftCk] _ L; pcemul.dataout[DSerialIn] _ IF databits[32-nb+pcemul.countcycle/2] THEN H ELSE L} ELSE pcemul.dataout[DShiftCk] _ H; pcemul.countcycle_ pcemul.countcycle+1} ELSE { pcemul.countcycle_ pcemul.countcycle+1; pcemul.dataout[DShiftCk] _ L; }; } ELSE IF pcemul.countcycle < 2*nb+1 THEN pcemul.nIOWPC_ H ELSE { pcemul.nIOWPC_ H; NextLine[pcemul]}; }; ReadDBusAndCheck: SimpleProc ~ { <> nb: CARDINAL _ NARROW[params.rest.first, REF CARDINAL]^; --number of bits to read value: CARD _ NARROW[params.first, REF CARD]^; valuebits: DWAsBits_ LOOPHOLE[Basics.SwapHalves[LOOPHOLE[value]]]; IF pcemul.nIOWPC=H AND pcemul.nIORPC=H THEN { pcemul.nIOWPC_ L; pcemul.nIORPC _ H; IF pcemul.countcycle < 2*nb THEN { IF (pcemul.countcycle MOD 2)=0 THEN pcemul.dataout[DShiftCk] _ L ELSE pcemul.dataout[DShiftCk] _ H; pcemul.countcycle_ pcemul.countcycle+1} ELSE { pcemul.countcycle_ pcemul.countcycle+1; pcemul.dataout[DShiftCk] _ L; }; } ELSE { IF pcemul.countcycle < 2*nb+1 THEN { pcemul.nIOWPC_ H; IF (pcemul.countcycle MOD 2)=1 THEN IF pcemul.nIORPC=H THEN pcemul.nIORPC _ L ELSE { IF pcemul.datain[DSerialOut] ~= (IF valuebits[32-nb+pcemul.countcycle/2] THEN H ELSE L) THEN SIGNAL Mismatch["Error compare data"]; pcemul.nIORPC _ H}; } ELSE { pcemul.nIOWPC_ H; pcemul.nIORPC _ H; NextLine[pcemul];} }; }; A: PROC [c: CARD] RETURNS [rc: REF ANY] = {rc _ NEW[CARD _ c]}; Q: PROC [c: QWord] RETURNS [rc: REF ANY] = {rc _ NEW[QWord _ c]}; <> <> Emul: PUBLIC PROC [pcemul: PCConex.PCEmulState] RETURNS [] ~ { IF pcemul.testProcList = NIL THEN { pcemul.testProcList _ NARROW[Atom.GetProp[$PCEmul, $PKList]]; }; DO AtomDidSomething: PROC [atom: ATOM, params: LIST OF REF ANY] RETURNS [BOOL] = { v: REF ANY = Atom.GetProp[$PCEmul, atom]; IF v # NIL THEN { spr: REF SimpleProc = NARROW[v]; spr^[pcemul, params]; RETURN[TRUE]; } ELSE { NextLine[pcemul]; RETURN[FALSE]; }; }; WITH pcemul.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[$PCEmul, $Wait, NEW[SimpleProc _ Wait]]; Atom.PutProp[$PCEmul, $Jump, NEW[SimpleProc _ Jump]]; Atom.PutProp[$PCEmul, $Init, NEW[SimpleProc _ Init]]; Atom.PutProp[$PCEmul, $Reset, NEW[SimpleProc _ Reset]]; Atom.PutProp[$PCEmul, $ResetOn, NEW[SimpleProc _ ResetOn]]; Atom.PutProp[$PCEmul, $ResetOff, NEW[SimpleProc _ ResetOff]]; Atom.PutProp[$PCEmul, $StopSimul, NEW[SimpleProc _ StopSimul]]; Atom.PutProp[$PCEmul, $WaitSync, NEW[SimpleProc _ WaitSync]]; Atom.PutProp[$PCEmul, $SetFlag, NEW[SimpleProc _ SetFlag]]; Atom.PutProp[$PCEmul, $ClearFlag, NEW[SimpleProc _ ClearFlag]]; Atom.PutProp[$PCEmul, $SendDBusAddress, NEW[SimpleProc _ SendDBusAddress]]; Atom.PutProp[$PCEmul, $SendDBusData, NEW[SimpleProc _ SendDBusData]]; Atom.PutProp[$PCEmul, $ReadDBusAndCheck, NEW[SimpleProc _ ReadDBusAndCheck]]; <> <<$Nop,>> << LIST[$Jump, $Nop]>> <<]];>> END. <<>> <<>> <<>> <<>>