DIRECTORY Core, CoreClasses, CoreCreate, Dyn, Ports, Rope, Rosemary, RosemaryUser, PCConex, PCEmul; PCConexImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, Ports, PCEmul, Rosemary EXPORTS PCConex ~ BEGIN OPEN PCConex; PCEDef: PUBLIC PROC [] RETURNS [ct: CellType] ~ { public: Wire _ CoreCreate.WireList[ LIST[ CoreCreate.Seq["Address",20], CoreCreate.Seq["DataOut",16], "nIOWPC", "nIORPC", CoreCreate.Seq["DataIn",16], "CkIn" ]]; ct _ CoreClasses.CreateUnspecified[public: public]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: PCConnexion]; Ports.InitPorts[ct, ls, drive,"Address"]; Ports.InitPorts[ct, ls, drive,"DataOut"]; Ports.InitPorts[ct, l, drive,"nIOWPC"]; Ports.InitPorts[ct, l, drive,"nIORPC"]; Ports.InitPorts[ct, ls, none,"DataIn"]; Ports.InitPorts[ct, l, none,"CkIn"]; }; PCEInit: PUBLIC Rosemary.InitProc = { pcemul: PCEmulState_ IF oldStateAny=NIL THEN NEW[PCEmulRec] ELSE NARROW[oldStateAny, PCEmulState]; pcemul.address _ NEW[Ports.LevelSequenceRec[20]]; pcemul.dataout _ NEW[Ports.LevelSequenceRec[16]]; pcemul.datain _ NEW[Ports.LevelSequenceRec[16]]; Ports.SetLS[pcemul.address, X]; Ports.SetLS[pcemul.dataout, X]; pcemul.nIOWPC _ X; pcemul.nIORPC _ X; [pcemul.ADDRESS] _ Ports.PortIndexes[cellType.public,"Address"]; [pcemul.DATAOUT] _ Ports.PortIndexes[cellType.public,"DataOut"]; [pcemul.NIOWPC] _ Ports.PortIndexes[cellType.public,"nIOWPC"]; [pcemul.NIORPC] _ Ports.PortIndexes[cellType.public,"nIORPC"]; [pcemul.DATAIN] _ Ports.PortIndexes[cellType.public,"DataIn"]; [pcemul.CKIN] _ Ports.PortIndexes[cellType.public,"CkIn"]; pcemul.countcycle_0; --is used for loops inside procs pcemul.labelcycle_0; --is used for detecting edge of ckin pcemul.testProcList _ NIL; stateAny_ pcemul; }; PCEEval: PUBLIC Rosemary.EvalProc = { pcemul: PCEmulState _ NARROW[stateAny]; pcemul.ckin _ p[pcemul.CKIN].l; Ports.CopyLS[from: p[pcemul.DATAIN].ls, to: pcemul.datain]; IF ~clockEval AND pcemul.ckin=L AND pcemul.labelcycle=1 THEN pcemul.labelcycle _ 0; -- for detecting positive edge of ckin IF ~clockEval AND pcemul.ckin=H AND pcemul.labelcycle=0 THEN{ pcemul.labelcycle _ 1; PCEmul.Emul[pcemul]; }; Ports.CopyLS[from: pcemul.address, to: p[pcemul.ADDRESS].ls]; Ports.CopyLS[from: pcemul.dataout, to: p[pcemul.DATAOUT].ls]; p[pcemul.NIOWPC].l _ pcemul.nIOWPC; p[pcemul.NIORPC].l _ pcemul.nIORPC; IF pcemul.nIORPC=L THEN p[pcemul.DATAOUT].d_none ELSE p[pcemul.DATAOUT].d_drive; }; PCConnexion: Core.ROPE = Rosemary.Register[roseClassName: "PCEDef", init: PCEInit, evalSimple: PCEEval, scheduleIfClockEval: TRUE]; END. PCConexImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Created by Jean Gastinel, November 2, 1987 7:45:23 pm PST This program emulates a very small part of the PC interface. Actually it manages only simple Read and Write on the PC bus. Here are the 3 procs Here is where the name and the size of public wires must be given This creates a celltype Now the type of each pins --PROC [cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANY _ NIL] RETURNS [stateAny: REF ANY _ NIL]-- Init the state Create the pointers on different sequences Init the value Take the indice of each pins --PROC [p: Ports.Port, stateAny: REF ANY, clockEval: BOOL]-- Assign the values of input pins to variables Assign the values of variables to the output wires: ΚW˜™Icode™Kšœœ0˜>Kšœœ0˜>Kšœœ.˜:K™Kšœ  ˜5Kšœ $˜9Kšœœ˜K˜Kšœ˜K˜K˜K˜KšŸœœ˜%Kš *œ  ™—š œ œœœ œ˜=Kšœœ˜Kšœ˜K˜K˜—Icomment™3Kšœ0œ˜=Kšœ0œ˜=Kšœ œ˜#Kšœ œ˜#Kš œœ œ œ œ ˜RK˜K˜K˜K˜—Kšœœgœ˜ƒKšœ˜˜K˜M™M™K˜K™K˜K˜K˜˜˜K˜———K™—…— }