DisplayModelImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Written By: Pradeep Sindhu, September 20, 1986 11:55:00 am PDT
Pradeep Sindhu, September 26, 1986 11:16:21 pm PDT
Last Edited by: Louis Monier September 24, 1986 3:56:59 pm PDT
Russ Atkinson (RRA) September 25, 1986 7:01:52 pm PDT
DIRECTORY
Convert, DynaStats, DisplayModel, DynaSeer, FIFO, IO, Real;
DisplayModelImpl: CEDAR PROGRAM
IMPORTS Convert, DynaStats, DynaSeer, FIFO, IO, Real
EXPORTS DisplayModel
~ BEGIN OPEN DisplayModel;
DisplayState: TYPE = REF DisplayStateRec;
DisplayStateRec: TYPE = RECORD [
displayAddress: INT ← 0,
underflowCount: INT ← 0,
cyclesToMonitorRequest: INT ← 0,
monitorRequestInterval: INT ← 0, -- 0 => display inactive
inputFIFO: FIFO.FIFO,
fifoLowWaterMark, fifoHighWaterMark, fifoSize: INT ← 0
];
mri: INT ← 0;
defaultMri: INT = Real.Fix[625/DynaSeer.busCycle];
fifoLWM, fifoHWM, fifoS: INT ← 0;
Exported Procedures
Init: PUBLIC PROC [handle: Handle] = {
mri ← DynaSeer.GetIntParm[handle.in, handle.out, "\nInterval (in cycles) between monitor requests (0 => display inactive):", defaultMri];
IF mri=0 THEN RETURN;
fifoLWM ← DynaSeer.GetIntParm[handle.in, handle.out, "Fifo low-water-mark (#entries)", 4];
WHILE (fifoHWM ← DynaSeer.GetIntParm[handle.in, handle.out, "Fifo high-water-mark (#entries)", 8]) < fifoLWM DO
IO.PutRope[handle.out, "\nfifoHighWaterMark must be >= fifoLowWaterMark"];
ENDLOOP;
WHILE (fifoS ← DynaSeer.GetIntParm[handle.in, handle.out, "Fifo size (#entries)", 12]) < fifoHWM DO
IO.PutRope[handle.out, "\fifoSize must be >= fifoHighWaterMark"];
ENDLOOP;
};
CreateDisplay: PUBLIC PROC [deviceId: DeviceId] RETURNS [device: Device] = {
device ← DynaSeer.CreateDevice[];
device.deviceId ← deviceId;
device.state ← NEW [DisplayStateRec];
device.init ← InitDisplay;
device.cycle ← CycleDisplay;
};
InitDisplay: PUBLIC DynaSeer.InitProc = {
cs: DisplayState ← NARROW[device.state];
cs.displayAddress ← 0;
cs.underflowCount ← 0;
cs.cyclesToMonitorRequest ← cs.monitorRequestInterval ← mri;
cs.inputFIFO ← FIFO.Create[];
cs.fifoLowWaterMark ← fifoLWM;
cs.fifoHighWaterMark ← fifoHWM;
cs.fifoSize ← fifoS;
};
CycleDisplay: PUBLIC DynaSeer.CycleProc = {
myState: DisplayState ← NARROW[device.state];
myId: DeviceId ← device.deviceId;
GenerateDisplayRequest: PROC [p: Priority] RETURNS [Request] = {
rbRqstCycle: Cycle ← DynaSeer.MakeCycle[RBRqst, myId, myId, myState.displayAddress];
myState.displayAddress ← myState.displayAddress+1;
RETURN [DynaSeer.MakeRequest[Two, rbRqstCycle, p]];
};
TreatBusCycle: PROC [cycle: Cycle] = {
IF cycle.cmd=RBRply AND cycle.deviceId=myId THEN {
IF FIFO.Size[myState.inputFIFO] > myState.fifoSize THEN IO.PutRope[handle.out, "\n**Display FIFO overflow**"];
FIFO.Put[myState.inputFIFO, cycle];
}
};
CheckMonitorRequest: PROC [] = {
IF (myState.cyclesToMonitorRequest ← myState.cyclesToMonitorRequest-1)<=0 THEN {
fifoCycle: Cycle ← NARROW[FIFO.Get[myState.inputFIFO]];
IF fifoCycle=NIL THEN {
myState.underflowCount ← myState.underflowCount + 1;
IO.PutF[handle.out, "\n**Display FIFO underflow** (count: %g, cycle: %g)",
[integer[myState.underflowCount]],
[integer[handle.cycleNumber]] ];
};
myState.cyclesToMonitorRequest ← myState.monitorRequestInterval
}
};
IF myState.monitorRequestInterval=0 THEN RETURN;
TreatBusCycle[cycle];
CheckMonitorRequest[];
IF DynaStats.PrintIt[handle] THEN {
IO.PutRope[handle.out, " Display FIFO: "];
IO.PutRope[handle.out, Convert.RopeFromInt[FIFO.Size[myState.inputFIFO]]]
};
IF FIFO.Size[myState.inputFIFO]<myState.fifoLowWaterMark
THEN
IF handle.displayHPRequest=NIL
THEN {
IF handle.displayLPRequest#NIL
THEN {
handle.displayHPRequest ← handle.displayLPRequest;
handle.displayHPRequest.priority ← High;
handle.displayLPRequest ← NIL}
ELSE handle.displayHPRequest ← GenerateDisplayRequest[High];
}
ELSE handle.displayHPRequest.cycles.first.grantLatency ← handle.displayHPRequest.cycles.first.grantLatency+1
ELSE
IF FIFO.Size[myState.inputFIFO]<myState.fifoHighWaterMark
THEN
IF handle.displayLPRequest=NIL
THEN handle.displayLPRequest ← GenerateDisplayRequest[Low]
ELSE handle.displayLPRequest.cycles.first.grantLatency ← handle.displayLPRequest.cycles.first.grantLatency+1
};
END.