VRamImpl.mesa
Copyright © 1988 by Xerox Corporation. All rights reserved.
Last Edited by: Gasbarro June 20, 1988 4:30:17 pm PDT
DIRECTORY
Basics, CardTab, Core, CoreClasses, CoreCreate, IO, Ports, Rope, Rosemary;
VRamImpl: CEDAR PROGRAM
IMPORTS Basics, CardTab, CoreClasses, CoreCreate, IO, Ports, Rosemary
~ BEGIN
Data, ColPDBb, ColPDB, ColPDA, RowPD0, RowPD1, RowPD2, EvenClkb, OddClkb, preb, preClkb, pullSense2Low, VRamWriteEn, wlLow, DummyGnd, Vdd, Gnd: NATLAST[NAT];
ROPE: TYPE = Core.ROPE;
Port: TYPE = Ports.Port;
addWidth: CARDINAL = 40;
Address: TYPE = [0..1024);
dataWidth: CARDINAL = 40;
Handle: TYPE = REF HandleRec;
HandleRec: TYPE = RECORD [
prevClk: Ports.Level,
master: Ports.LevelSequence,
storage: CardTab.Ref ← NIL
];
BITSHIFT: PROC [value: WORD, count: INTEGER] RETURNS [WORD] = Basics.BITSHIFT;
BITAND: Basics.BitOp = Basics.BITAND;
BITOR: Basics.BitOp = Basics.BITOR;
BITNOT: PROC [WORD] RETURNS [WORD] = Basics.BITNOT;
VRamError: SIGNAL [msg: Rope.ROPE] = CODE;
InitPortIndicies: PROC [ct: Core.CellType] = {
[Data, ColPDBb, ColPDB, ColPDA, RowPD0, RowPD1, RowPD2, EvenClkb, OddClkb] ← Ports.PortIndexes[ct.public, "Data", "ColPDBb", "ColPDB", "ColPDA", "RowPD0", "RowPD1", "RowPD2", "EvenClkb", "OddClkb"];
[preb, preClkb, pullSense2Low, VRamWriteEn, wlLow, DummyGnd, Vdd, Gnd] ← Ports.PortIndexes[ct.public, "preb", "preClkb", "pullSense2Low", "VRamWriteEn", "wlLow", "DummyGnd", "Vdd", "Gnd"];
};
Create: PUBLIC PROC [] RETURNS [ct: Core.CellType] = {
ct ← CoreClasses.CreateUnspecified[
public: CoreCreate.WireList[LIST[CoreCreate.Seq["Data", dataWidth], "ColPDBb", "ColPDB", CoreCreate.Seq["ColPDA", 4], CoreCreate.Seq["RowPD0", 4], CoreCreate.Seq["RowPD1", 4], CoreCreate.Seq["RowPD2", 4], "EvenClkb", "OddClkb", "preb", "preClkb", "pullSense2Low", "VRamWriteEn", "wlLow", "DummyGnd", "Vdd", "Gnd"], "VRam", NIL],
name: vRamName
];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: vRamName];
[] ← Ports.InitPorts[ct, l, none, "ColPDBb", "ColPDB", "EvenClkb", "OddClkb", "preClkb", "pullSense2Low", "VRamWriteEn"];
[] ← Ports.InitPorts[ct, l, drive, "preb", "wlLow"];
[] ← Ports.InitPorts[ct, ls, none, "ColPDA"];
[] ← Ports.InitPorts[ct, ls, none, "RowPD0"];
[] ← Ports.InitPorts[ct, ls, none, "RowPD1"];
[] ← Ports.InitPorts[ct, ls, none, "RowPD2"];
[] ← Ports.InitPorts[ct, ls, none, "Data"];
};
VRamInit: Rosemary.InitProc = {
h: Handle ← NEW[HandleRec];
InitPortIndicies[cellType];
h.storage ← CardTab.Create[];
h.master ← NEW[Ports.LevelSequenceRec[dataWidth]];
stateAny ← h;
};
VRamSimple: Rosemary.EvalProc = {
--PROC [p: Ports.Port, stateAny: REF ANY]--
h: Handle ← NARROW[stateAny];
clk: Ports.Level ← Ports.AndL[p[EvenClkb].l, p[OddClkb].l];
p[preb].l ← p[preClkb].l;
p[wlLow].l ← clk;
p[Data].d ← IF p[VRamWriteEn].l=H THEN none ELSE drive;
IF clk=H THEN BusToMaster[h, p];
IF clk=L AND h.prevClk=H AND p[VRamWriteEn].l=H THEN MasterToStorage[h, p];
IF clk=L AND h.prevClk=H AND p[VRamWriteEn].l=L THEN StorageToBus[h, p];
h.prevClk ← clk;
};
BusToMaster: PROC [h: Handle, p: Port] ~ {
Ports.CopyLS[p[Data].ls, h.master];
};
MasterToStorage: PROC [h: Handle, p: Port] ~ {
ls: Ports.LevelSequence ← NEW[Ports.LevelSequenceRec[dataWidth]];
Ports.CopyLS[p[Data].ls, ls];
[] ← CardTab.Store[h.storage, Add[p], ls];
};
StorageToBus: PROC [h: Handle, p: Port] ~ {
found: BOOLFALSE;
val: REFNIL;
[found, val] ← CardTab.Fetch[h.storage, Add[p]];
IF found THEN Ports.CopyLS[NARROW[val, Ports.LevelSequence], p[Data].ls] ELSE
Ports.SetLS[p[Data].ls, X];
};
Add: PROC [p: Port] RETURNS [add: CARDINAL] ~ {
c: CARDINAL ← 0;
add ← IF p[EvenClkb].l = L THEN 1 ELSE 0;
c ← Demux[Ports.LSToLC[p[RowPD2].ls], FALSE];
add ← BITOR[add, BITSHIFT[c, 1]];
c ← Demux[Ports.LSToLC[p[RowPD1].ls], FALSE];
add ← BITOR[add, BITSHIFT[c, 3]];
c ← Demux[Ports.LSToLC[p[RowPD0].ls], FALSE];
add ← BITOR[add, BITSHIFT[c, 5]];
c ← Demux[Ports.LSToLC[p[ColPDA].ls]];
add ← BITOR[add, BITSHIFT[c, 7]];
c ← IF p[ColPDBb].l = L THEN 1 ELSE 0;
add ← BITOR[add, BITSHIFT[c, 9]];
};
Demux: PROC [c: CARDINAL, pos: BOOLTRUE] RETURNS [CARDINAL] ~ {
SELECT c FROM
0 => IF pos THEN RETURN[0] ELSE ERROR;
1 => IF pos THEN RETURN[3] ELSE ERROR;
2 => IF pos THEN RETURN[2] ELSE ERROR;
4 => IF pos THEN RETURN[1] ELSE ERROR;
8 => IF pos THEN RETURN[0] ELSE ERROR;
0fh => IF NOT pos THEN RETURN[0] ELSE ERROR;
0eh => IF NOT pos THEN RETURN[3] ELSE ERROR;
0dh => IF NOT pos THEN RETURN[2] ELSE ERROR;
0bh => IF NOT pos THEN RETURN[1] ELSE ERROR;
07h => IF NOT pos THEN RETURN[0] ELSE ERROR;
ENDCASE => ERROR;
};
PrintStorage: PROC [s: IO.STREAM, h: Handle] ~ {
PrintIt: CardTab.EachPairAction ~ {
IO.PutF[s, "Add: %x, Data: %g\n", IO.card[key], IO.rope[Ports.LSToRope[NARROW[val, Ports.LevelSequence]]]];
RETURN[FALSE];
};
[] ← CardTab.Pairs[h.storage, PrintIt];
};
vRamName: ROPE = Rosemary.Register[roseClassName: "VRam", init: VRamInit, evalSimple: VRamSimple];
END.