-- 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