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]]; END. ήPBusEmulImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Created by Jean Gastinel, April 21, 1988 11:05:27 am PDT Pradeep Sindhu May 4, 1988 0:28:50 am PDT Jean Gastinel June 7, 1988 6:34:14 pm PDT Service Types HARDWARE DEFINITIONS Definition of the PCmd format Service Procs Jump to cycle line number : lnb Interprocess Synchronisation This proc is use for synchronisation. It tests the value of a parameter atom $Flag. During the wait, a nop command is generated This proc is used for synchronisation. It tests the value of the parameter atom $Flag. If the parameter is True, the next instruction is skiped. If it is Not True the following instructions are normally executed. This proc is use for synchronisation. It Set the value of a parameter atom $Flag to TRUE This proc is use for synchronisation. It Clears the value of a parameter atom $Flag to FALSE This proc advances cycleCount to pbusCycles (pbusCycle=4*dynabusCycle) This proc set the Mode output at "Kernel" if the parameter =0, at User if not. This proc set the ByteSelect output with the value of the parameter. This proc Check the value of the Fault Bus. pbusemul.PFaultChecked _ TRUE; This proc send a read command. The first parameter is the Address, the second, the expected data. IF faultCheck ~= 0 THEN IF pbusemul.PFaultChecked = FALSE THEN SIGNAL PBusEvent["No PFault occurs"]; This proc send a Write command. The first parameter is the Address, the second is the Data sent. This proc send a IORead command. The first parameter is the Address, the second, the expected data. This proc send a IOWrite command.The first parameter is the Address, the second is the Data sent. This proc send a BIOWrite command.The first parameter is the Address, the second is the Data sent. This proc generate any command on the PCBus This proc send a read command. The first parameter is the Address, the second, the expected data. IF faultCheck ~= 0 THEN IF pbusemul.PFaultChecked = FALSE THEN SIGNAL PBusEvent["No PFault occurs"]; This proc send a DeMap command. The first parameter is the Address. This proc send a ClearVP command. No parameter. Simulation Procs Interpretation Motor Atom.PutProp[$PBusEmul, $PKList, LIST[ $Nop, LIST[$Jump, $Nop] ]]; Κπ˜šœ™Icode™