-- MouseChipImpl.mesa
-- created by Haeberli: 30-Sep-81 13:15:07
DIRECTORY
InlineDefs USING [BITAND, BITOR, LowHalf],
Mouse,
Storage,
Tester;
MouseChipImpl: PROGRAM IMPORTS InlineDefs, Storage, Tester EXPORTS Mouse =
{
OPEN Mouse;
StepMax: CARDINAL = 1000;
StepCount: TYPE = [0..1000);
StepControl: TYPE = CARDINAL [0..16);
DataCount: TYPE = [0..4000);
PatEntry: TYPE = WORD;
PatRecord: TYPE = RECORD[stepCount: StepCount ← 0, control: LONG POINTER TO PACKED ARRAY [0..0) OF StepControl ← NIL, dataCount: DataCount ← 8,
data: LONG POINTER TO ARRAY [0..0) OF PatEntry ← NIL];
patterns: ARRAY Pattern OF PatRecord;
currentPattern: Pattern;
recording: BOOLEAN ← FALSE;
tempPatRecord: PatRecord ← [stepCount: 0, control: Words[(StepMax/4)+1], dataCount: 0, data: Words[SIZE[PatEntry] * StepMax]];
testerStep: WORD = 100000B;
testerNoop: WORD = 000000B;
currentPinMap: Mouse.PinMap ← ALL[0];
EndRecordPat: PUBLIC PROCEDURE = {
OPEN patterns[currentPattern];
EnterStep[testerStep];
-- return old data;
IF control # NIL THEN Free[control]; control ← NIL;
IF data # NIL THEN Free[data]; data ← NIL;
stepCount ← tempPatRecord.stepCount;
control ← Words[(stepCount/4)+1];
FOR i:StepCount IN [0..stepCount) DO control[i] ← tempPatRecord.control[i] ENDLOOP;
tempPatRecord.stepCount ← 0;
dataCount ← tempPatRecord.dataCount;
data ← Words[SIZE[PatEntry] * dataCount];
FOR i:StepCount IN [0..dataCount) DO data[i] ← tempPatRecord.data[i] ENDLOOP;
tempPatRecord.dataCount ← 8;
blockCount ← 0;
recording ← FALSE};
GetPin: PUBLIC PROCEDURE [pin: Mouse.Pin] RETURNS [value: Mouse.Value] = {
RETURN[Tester.GetChannelValue[currentPinMap[pin]]]};
PlayPat: PUBLIC PROCEDURE [pat: Pattern] = {
OPEN patterns[pat];
actualStepCount: StepCount ← 0;
Tester.DoOutput[testerStep, 1];
actualStepCount ← Tester.DoTest[c: stepCount, control: control, data: data];
IF actualStepCount # 0 THEN ERROR;
Tester.DoOutput[testerStep, 1];
};
RecordPat: PUBLIC PROCEDURE [pat: Pattern] = {
currentPattern ← pat;
tempPatRecord.stepCount ← 0;
tempPatRecord.dataCount ← 8;
blockCount ← 0;
recording ← TRUE};
Reset: PUBLIC PROCEDURE = {Tester.Reset};
SetPin: PUBLIC PROCEDURE [pin: Mouse.Pin, value: Mouse.Value] = {
IF recording THEN {
first, second: WORD;
[first, second] ← Tester.SetChannelValueCommands[currentPinMap[pin], value];
EnterStep[first]; EnterStep[second]
}
ELSE Tester.SetChannelValue[currentPinMap[pin], value]};
SetPinMap: PUBLIC PROCEDURE [pinMap: Mouse.PinMap] = {currentPinMap ← pinMap};
blockCount: CARDINAL ← 0;
EnterStep: PROCEDURE [w: WORD] = {
OPEN tempPatRecord;
data[dataCount] ← InlineDefs.BITAND[w, 077777B];
dataCount ← dataCount + 1;
blockCount ← blockCount + 1;
IF InlineDefs.BITAND[w, testerStep] # 0 THEN -- block done
{
--fill out block to 4 or 8 words (with nops);
UNTIL ((blockCount > 0) AND ((blockCount MOD 4) = 0)) DO
data[dataCount] ← testerNoop;
dataCount ← dataCount + 1;
blockCount ← blockCount + 1
ENDLOOP;
data[dataCount - 1] ← InlineDefs.BITOR[data[dataCount - 1], testerStep];
--if we have more than 4 blocks in a step, we have to do multiple
-- steps
UNTIL blockCount <= 16 DO
control[stepCount] ← 14B; -- tell tester to do 4 blocks
stepCount ← stepCount + 1;
blockCount ← blockCount - 16;
ENDLOOP;
blockCount ← blockCount - 4; --control is biased
control[stepCount] ← LOOPHOLE[blockCount, StepControl];
stepCount ← stepCount + 1;
blockCount ← 0
};
};
SetVersion: PUBLIC PROCEDURE [version: ChipVersion] = {};
Free: PROCEDURE [lp: LONG POINTER TO UNSPECIFIED] = {
Storage.FreeWords[InlineDefs.LowHalf[lp]]
};
Words: PROCEDURE [length: CARDINAL] RETURNS [lp: LONG POINTER TO UNSPECIFIED] = {
lp ← Storage.Words[length];
RETURN[lp]
};
Reset;
}.
MPH 30-Sep-81 13:23:48
created initially