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.
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;
Here are the 3 procs
PCEDef: PUBLIC PROC [] RETURNS [ct: CellType] ~ {
Here is where the name and the size of public wires must be given
public: Wire ← CoreCreate.WireList[
LIST[
CoreCreate.Seq["Address",20],
CoreCreate.Seq["DataOut",16],
"nIOWPC",
"nIORPC",
CoreCreate.Seq["DataIn",16],
"CkIn"
]];
This creates a celltype
ct ← CoreClasses.CreateUnspecified[public: public];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: PCConnexion];
Now the type of each pins
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 = {
--PROC [cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANY ← NIL] RETURNS [stateAny: REF ANY ← NIL]--
Init the state
pcemul: PCEmulState← IF oldStateAny=NIL THEN NEW[PCEmulRec]
ELSE
NARROW[oldStateAny, PCEmulState];
Create the pointers on different sequences
pcemul.address ← NEW[Ports.LevelSequenceRec[20]];
pcemul.dataout ← NEW[Ports.LevelSequenceRec[16]];
pcemul.datain ← NEW[Ports.LevelSequenceRec[16]];
Init the value
Ports.SetLS[pcemul.address, X];
Ports.SetLS[pcemul.dataout, X];
pcemul.nIOWPC ← X;
pcemul.nIORPC ← X;
Take the indice of each pins
[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𡤀 --is used for loops inside procs
pcemul.labelcycle𡤀 --is used for detecting edge of ckin
pcemul.testProcList ← NIL;
stateAny← pcemul;
};
PCEEval: PUBLIC Rosemary.EvalProc = {
--PROC [p: Ports.Port, stateAny: REF ANY, clockEval: BOOL]--
pcemul: PCEmulState ← NARROW[stateAny];
Assign the values of input pins to variables
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];
};
Assign the values of variables to the output wires:
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𡤍rive;
};
PCConnexion: Core.ROPE = Rosemary.Register[roseClassName: "PCEDef", init: PCEInit, evalSimple: PCEEval, scheduleIfClockEval: TRUE];
END.