<> <> <> <> <> <<>> <<>> DIRECTORY Atom, PBusConex, PBusEmul, Ports, Rope; PBusEmulImpl: CEDAR PROGRAM IMPORTS Atom, Ports EXPORTS PBusEmul ~ BEGIN <> <<>> PBusEvent: 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[pbusemul: PBusConex.PBusEmulState, params: LIST OF REF ANY _ NIL ] RETURNS []; <> <<>> <> PCmdRead: NAT= 8; PCmdWrite: NAT= 9; PCmdIORead: NAT= 12; PCmdIOWrite: NAT= 13; PCmdBIOWrite: NAT= 15; PCmdCWS: NAT= 10; PCmdDeMap: NAT= 11; PCmdClearVP: NAT= 14; <> <<>> StopSimul: SimpleProc ~ { SIGNAL PBusEvent["End of Simulation"]; NextLine[pbusemul]; }; NextLine: SimpleProc ~ { pbusemul.testProcList _ pbusemul.testProcList.rest; pbusemul.cycleCount _ 0; }; Jump: SimpleProc ~ { <> label: ATOM _ NARROW[params.first]; pbusemul.testProcList _ NARROW[Atom.GetProp[$PBusEmul, $PKList]]; WHILE pbusemul.testProcList.first # label DO NextLine[pbusemul]; ENDLOOP; Emul[pbusemul]; }; 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 IF pbusemul.numClockEdges MOD 4 = 3 THEN NextLine[pbusemul]; }; SkipIfTrue: 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]^; NextLine[pbusemul]; IF Cond THEN NextLine[pbusemul]; Emul[pbusemul] ; }; SetFlag: SimpleProc ~ { <> Flag: ATOM _ NARROW[params.first]; Atom.PutProp[$Sync,Flag, B[TRUE]]; NextLine[pbusemul]; Emul[pbusemul] }; ClearFlag: SimpleProc ~ { <> Flag: ATOM _ NARROW[params.first]; Atom.PutProp[$Sync,Flag, B[FALSE]]; NextLine[pbusemul]; Emul[pbusemul] }; Wait: SimpleProc ~ { <> pbusCycles: CARD _ NARROW[params.first, REF CARD]^; IF pbusemul.cycleCount < pbusCycles*4 THEN pbusemul.cycleCount _ pbusemul.cycleCount+1 ELSE NextLine[pbusemul]; }; SetMode: SimpleProc ~ { <> Mode: CARD _ NARROW[params.first, REF CARD]^; IF Mode=0 THEN pbusemul.PMode _ L ELSE pbusemul.PMode _ H; NextLine[pbusemul]; Emul[pbusemul] }; SetByteSelect: SimpleProc ~ { <> <<>> ByteSelect: CARD _ NARROW[params.first, REF CARD]^; Ports.LCToLS[ByteSelect,pbusemul.PByteSel]; -- 0FH =Word selection NextLine[pbusemul]; Emul[pbusemul] }; CheckPFault: PROC [pbusemul: PBusConex.PBusEmulState , faultCheck : CARD] RETURNS [] ~ { <> faultCode : CARD; faultCode _ 0; IF pbusemul.PFault = H THEN { faultCode _ 16 + Ports.LSToLC[pbusemul.PFaultCode]; IF faultCode ~= faultCheck THEN SIGNAL PBusEvent["Error PFault Code"]; <> }; }; ReadAndCheck: SimpleProc ~ { <> <<>> address, data, dataread, faultCheck : CARD; par1 : LIST OF REF ANY _ params; address _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; data _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; IF par1 = NIL THEN faultCheck _0 ELSE faultCheck _ NARROW[par1.first, REF CARD]^; Ports.LCToLS[PCmdRead,pbusemul.PCmd]; -- Command SELECT pbusemul.cycleCount FROM 0,1 => { Ports.LCToLS[address,pbusemul.PDataOut]; -- Send Address pbusemul.cycleCount_ pbusemul.cycleCount+1 }; 2 => pbusemul.cycleCount_ pbusemul.cycleCount+1; 3 => { CheckPFault[pbusemul,faultCheck]; IF pbusemul.PReject=L THEN { ENABLE Ports.ConversionError => {SIGNAL PBusEvent["X in input"]; NextLine[pbusemul]; GOTO Done}; dataread _ Ports.LSToLC[pbusemul.PDataIn]; IF (data~=dataread) THEN SIGNAL PBusEvent["Error Read Compare Data"]; <> NextLine[pbusemul] } ELSE pbusemul.cycleCount _0; }; ENDCASE => ERROR; EXITS Done => NULL }; Write: SimpleProc ~ { <> <<>> address, data, faultCheck : CARD; par1 : LIST OF REF ANY _ params; address _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; data _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; IF par1 = NIL THEN faultCheck _0 ELSE faultCheck _ NARROW[par1.first, REF CARD]^; Ports.LCToLS[PCmdWrite,pbusemul.PCmd]; -- Command SELECT pbusemul.cycleCount FROM 0,1 => { Ports.LCToLS[address,pbusemul.PDataOut]; -- Send Address pbusemul.cycleCount_ pbusemul.cycleCount+1 }; 2 => { Ports.LCToLS[data,pbusemul.PDataOut]; pbusemul.cycleCount_ pbusemul.cycleCount+1}; 3 => { CheckPFault[pbusemul,faultCheck]; IF pbusemul.PReject=L THEN { Ports.LCToLS[data,pbusemul.PDataOut]; NextLine[pbusemul] } ELSE pbusemul.cycleCount _0; }; ENDCASE => ERROR; }; IOReadAndCheck: SimpleProc ~ { <> data, dataread, address, faultCheck : CARD; par1 : LIST OF REF ANY _ params; address _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; data _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; IF par1 = NIL THEN faultCheck _0 ELSE faultCheck _ NARROW[par1.first, REF CARD]^; Ports.LCToLS[PCmdIORead,pbusemul.PCmd]; -- Command SELECT pbusemul.cycleCount FROM 0,1 => { Ports.LCToLS[address,pbusemul.PDataOut]; -- Send Address pbusemul.cycleCount_ pbusemul.cycleCount+1 }; 2 => pbusemul.cycleCount_ pbusemul.cycleCount+1; 3 => { CheckPFault[pbusemul,faultCheck]; IF pbusemul.PReject=L THEN { ENABLE Ports.ConversionError => {SIGNAL PBusEvent["X in input"]; NextLine[pbusemul]; GOTO Done}; dataread _ Ports.LSToLC[pbusemul.PDataIn]; IF (data~=dataread) THEN SIGNAL PBusEvent["Error Read Compare Data"]; NextLine[pbusemul] } ELSE pbusemul.cycleCount _0; }; ENDCASE => ERROR; <<>> EXITS Done => NULL }; IOWrite: SimpleProc ~ { <> data , address, faultCheck : CARD; par1 : LIST OF REF ANY _ params; address _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; data _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; IF par1 = NIL THEN faultCheck _0 ELSE faultCheck _ NARROW[par1.first, REF CARD]^; Ports.LCToLS[PCmdIOWrite,pbusemul.PCmd]; -- Command SELECT pbusemul.cycleCount FROM 0,1 => { Ports.LCToLS[address,pbusemul.PDataOut]; -- Send Address pbusemul.cycleCount_ pbusemul.cycleCount+1 }; 2 => { Ports.LCToLS[data,pbusemul.PDataOut]; pbusemul.cycleCount_ pbusemul.cycleCount+1} ; 3 => { CheckPFault[pbusemul,faultCheck]; IF pbusemul.PReject=L THEN { Ports.LCToLS[data,pbusemul.PDataOut]; NextLine[pbusemul] } ELSE pbusemul.cycleCount _0; }; ENDCASE => ERROR; }; BIOWrite: SimpleProc ~ { <> data , address, faultCheck : CARD; par1 : LIST OF REF ANY _ params; address _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; data _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; IF par1 = NIL THEN faultCheck _0 ELSE faultCheck _ NARROW[par1.first, REF CARD]^; Ports.LCToLS[PCmdBIOWrite,pbusemul.PCmd]; -- Command SELECT pbusemul.cycleCount FROM 0,1 => { Ports.LCToLS[address,pbusemul.PDataOut]; -- Send Address pbusemul.cycleCount_ pbusemul.cycleCount+1 }; 2 => { Ports.LCToLS[data,pbusemul.PDataOut]; pbusemul.cycleCount_ pbusemul.cycleCount+1} ; 3 => { CheckPFault[pbusemul,faultCheck]; IF pbusemul.PReject=L THEN { Ports.LCToLS[data,pbusemul.PDataOut]; NextLine[pbusemul] } ELSE pbusemul.cycleCount _0; }; ENDCASE => ERROR; }; PBusCmd: SimpleProc ~ { <> }; CondWriteSingleAndCheck: SimpleProc ~ { <> <<>> address, data, dataread, faultCheck : CARD; par1 : LIST OF REF ANY _ params; address _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; data _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; IF par1 = NIL THEN faultCheck _0 ELSE faultCheck _ NARROW[par1.first, REF CARD]^; Ports.LCToLS[PCmdCWS,pbusemul.PCmd]; -- Command SELECT pbusemul.cycleCount FROM 0,1 => { Ports.LCToLS[address,pbusemul.PDataOut]; -- Send Address pbusemul.cycleCount_ pbusemul.cycleCount+1 }; 2 => pbusemul.cycleCount_ pbusemul.cycleCount+1; 3 => { CheckPFault[pbusemul,faultCheck]; IF pbusemul.PReject=L THEN { ENABLE Ports.ConversionError => {SIGNAL PBusEvent["X in input"]; NextLine[pbusemul]; GOTO Done}; dataread _ Ports.LSToLC[pbusemul.PDataIn]; IF (data~=dataread) THEN SIGNAL PBusEvent["Error Read Compare Data"]; <> NextLine[pbusemul] } ELSE pbusemul.cycleCount _0; }; ENDCASE => ERROR; EXITS Done => NULL }; DeMap: SimpleProc ~ { <> address, faultCheck : CARD; par1 : LIST OF REF ANY _ params; address _ NARROW[par1.first, REF CARD]^; par1 _ par1.rest; IF par1 = NIL THEN faultCheck _0 ELSE faultCheck _ NARROW[par1.first, REF CARD]^; Ports.LCToLS[PCmdDeMap,pbusemul.PCmd]; -- Command SELECT pbusemul.cycleCount FROM 0,1 => { Ports.LCToLS[address,pbusemul.PDataOut]; -- Send Address pbusemul.cycleCount_ pbusemul.cycleCount+1 }; 2 => pbusemul.cycleCount_ pbusemul.cycleCount+1; 3 => { CheckPFault[pbusemul,faultCheck]; IF pbusemul.PReject=L THEN { Ports.LCToLS[0,pbusemul.PDataOut]; NextLine[pbusemul] } ELSE pbusemul.cycleCount _0; }; ENDCASE => ERROR; }; ClearVP: SimpleProc ~ { <> faultCheck : CARD; par1 : LIST OF REF ANY _ params; IF par1 = NIL THEN faultCheck _0 ELSE faultCheck _ NARROW[par1.first, REF CARD]^; Ports.LCToLS[PCmdClearVP,pbusemul.PCmd]; -- Command SELECT pbusemul.cycleCount FROM 0,1 => { Ports.LCToLS[0,pbusemul.PDataOut]; -- Send Address pbusemul.cycleCount_ pbusemul.cycleCount+1 }; 2 => pbusemul.cycleCount_ pbusemul.cycleCount+1; 3 => { CheckPFault[pbusemul,faultCheck]; IF pbusemul.PReject=L THEN { Ports.LCToLS[0,pbusemul.PDataOut]; NextLine[pbusemul] } ELSE pbusemul.cycleCount _0; }; ENDCASE => ERROR; }; A: PROC [c: CARD] RETURNS [rc: REF ANY] = {rc _ NEW[CARD _ c]}; <> <> AtomDidSomething: PROC [pbusemul: PBusConex.PBusEmulState, atom: ATOM, params: LIST OF REF ANY] RETURNS [BOOL] = { v: REF ANY = Atom.GetProp[$PBusEmul, atom]; IF v # NIL THEN { spr: REF SimpleProc = NARROW[v]; spr^[pbusemul, params]; RETURN[TRUE]; } ELSE { NextLine[pbusemul]; RETURN[FALSE]; }; }; Emul: PUBLIC PROC [pbusemul: PBusConex.PBusEmulState] ~ { IF pbusemul.testProcList = NIL THEN { pbusemul.testProcList _ NARROW[Atom.GetProp[$PBusEmul, $PKList]]; }; DO WITH pbusemul.testProcList.first SELECT FROM atom: ATOM => IF AtomDidSomething[pbusemul, atom, NIL] THEN EXIT; list: LIST OF REF ANY => { WITH list.first SELECT FROM atom: ATOM => IF AtomDidSomething[pbusemul, atom, list.rest] THEN EXIT; ENDCASE => ERROR; }; ENDCASE => ERROR; ENDLOOP; }; Atom.PutProp[$PBusEmul, $StopSimul, NEW[SimpleProc _ StopSimul]]; Atom.PutProp[$PBusEmul, $Wait, NEW[SimpleProc _ Wait]]; Atom.PutProp[$PBusEmul, $Jump, NEW[SimpleProc _ Jump]]; Atom.PutProp[$PBusEmul, $WaitSync, NEW[SimpleProc _ WaitSync]]; Atom.PutProp[$PBusEmul, $SetFlag, NEW[SimpleProc _ SetFlag]]; Atom.PutProp[$PBusEmul, $ClearFlag, NEW[SimpleProc _ ClearFlag]]; Atom.PutProp[$PBusEmul, $SkipIfTrue, NEW[SimpleProc _ SkipIfTrue]]; Atom.PutProp[$PBusEmul, $ReadAndCheck, NEW[SimpleProc _ ReadAndCheck]]; Atom.PutProp[$PBusEmul, $Write, NEW[SimpleProc _ Write]]; Atom.PutProp[$PBusEmul, $IOReadAndCheck, NEW[SimpleProc _ IOReadAndCheck]]; Atom.PutProp[$PBusEmul, $IOWrite, NEW[SimpleProc _ IOWrite]]; Atom.PutProp[$PBusEmul, $BIOWrite, NEW[SimpleProc _ BIOWrite]]; Atom.PutProp[$PBusEmul, $PBusCmd, NEW[SimpleProc _ PBusCmd]]; Atom.PutProp[$PBusEmul, $CondWriteSingleAndCheck, NEW[SimpleProc _ CondWriteSingleAndCheck]]; Atom.PutProp[$PBusEmul, $DeMap, NEW[SimpleProc _ DeMap]]; Atom.PutProp[$PBusEmul, $ClearVP, NEW[SimpleProc _ ClearVP]]; Atom.PutProp[$PBusEmul, $SetMode, NEW[SimpleProc _ SetMode]]; Atom.PutProp[$PBusEmul, $SetByteSelect, NEW[SimpleProc _ SetByteSelect]]; <> <<$Nop,>> << LIST[$Jump, $Nop]>> <<]];>> END. <<>> <<>> <<>> <<>>