SageTest.mesa
Last edited by Barth, November 13, 1984 1:57:14 pm PST
Last Edited by: Gasbarro, January 11, 1985 3:46:35 pm PST
DIRECTORY
Multibus,
MultibusRpcControl,
Rope,
SageFace,
SageFaceRpcControl,
ViewRec;
SageTest:
CEDAR
PROGRAM
IMPORTS Multibus, MultibusRpcControl, SageFace, SageFaceRpcControl, ViewRec =
BEGIN
UserHandle: TYPE = REF UserRec;
UserRec:
TYPE =
RECORD [
pulseTap: ARRAY PulseLine OF Tap,
outPair: ARRAY Channel OF PulsePair,
inPulse: ARRAY Channel OF PulseLine,
inData: ARRAY InputStage OF BOOL,
bigChip: BOOL ← FALSE,
continuous: BOOL ← FALSE,
quit: BOOL ← FALSE,
FoolAround: PROC[uh: UserHandle],
SetChannels: PROC[uh: UserHandle]
];
data: PACKED ARRAY Channel OF ARRAY ShiftStage OF DriveState;
PulseGenCounterReg:
TYPE =
MACHINE
DEPENDENT
RECORD[
null(0: 0..11): [0..4096) ← 0,
counter(0: 12..15): [0..16) ← 0];
PulseGenCounterCtlReg:
TYPE =
MACHINE
DEPENDENT
RECORD[
null(0: 0..13): [0..16384) ← 0,
continuous(0: 14..14): BOOL ← FALSE,
go(0: 15..15): BOOL ← FALSE];
PulseGenCtlReg:
TYPE =
MACHINE
DEPENDENT
RECORD[
null(0: 0..12): [0..8192) ← 0,
nReset(0: 13..13): BOOL ← FALSE,
feedBack15(0: 14..14): BOOL ← FALSE,
globalHold(0: 15..15): BOOL ← FALSE];
ChannelCtlReg:
TYPE =
MACHINE
DEPENDENT
RECORD[
null(0: 0..7): [0..256) ← 0,
localHold(0: 8..8): BOOL ← FALSE,
inPulseLine(0: 9..12): PulseLine ← 0,
outPulsePair(0: 13..15): [0..8) ← 0];
PulseLine: TYPE = [0..16);
PulsePair: TYPE = [0..8);
Channel: TYPE = [0..64);
Tap: TYPE = [0..64);
ShiftStage: TYPE = [0..32);
InputStage: TYPE = [0..16);
DriveState: TYPE = {H, L, T};
PulseGenTapAddress: MultibusAddress = SageDeviceAddress+0H;
PulseGenCounterRegAddress: MultibusAddress = SageDeviceAddress+10H;
PulseGenCounterRegHackAddress: MultibusAddress = SageDeviceAddress+01E0H;
ChannelAddress: MultibusAddress = SageDeviceAddress+20H;
WidthPulseLine: PulseLine = 7;
CyclePulseLine: PulseLine = 15;
ControlValue: TYPE = {continuous, go, reset, feedBack15, globalHold};
InputCount: CARDINAL = 8;
InputData:
TYPE =
MACHINE
DEPENDENT
RECORD[
null(0: 0..InputCount-1): [0..256),
bits(0: InputCount..15): PACKED ARRAY InputIndex OF BOOL];
InputIndex: TYPE = [0..InputCount);
pulseGenCounterRegState: PulseGenCounterReg ← [0, 0];
pulseGenCounterCtlRegState: PulseGenCounterCtlReg ← [0, FALSE, FALSE];
pulseGenCtlRegState: PulseGenCtlReg ← [0, FALSE, FALSE, FALSE];
Start:
PROCEDURE [name: Rope.
ROPE] =
TRUSTED {
TRUSTED {
MultibusRpcControl.ImportInterface[interfaceName: [NIL, name]];
SageFaceRpcControl.ImportInterface[interfaceName: [NIL, name]];
};
DoOutput[LOOPHOLE[pulseGenCounterRegState], PulseGenCounterRegHackAddress];
DoOutput[LOOPHOLE[pulseGenCounterCtlRegState], PulseGenCounterCtlRegHackAddress];
DoOutput[LOOPHOLE[pulseGenCtlRegState], PulseGenCtlRegAddress];
};
FoolAround:
PROCEDURE [uh: UserHandle] = {
UNTIL uh.quit
DO
TRUSTED {SageFace.Start[firstCounterCtlReg: 2, newCtlReg: 4, secondCounterCtlReg: 3, wait: FALSE]};
ENDLOOP;
};
SetChannels:
PROCEDURE [uh: UserHandle] = {
SetControl[go, FALSE];
SetControl[continuous];
SetControl[globalHold];
SetControl[reset];
SetControl[reset, FALSE];
FOR pl: PulseLine
IN PulseLine
DO
SetPulseLineTap[pulseLine: pl, tap: uh.pulseTap[pl]];
ENDLOOP;
FOR c: Channel
IN Channel
DO
SetChannelCtlReg[channel: c, register: [localHold: TRUE, inPulseLine: uh.inPulse[c], outPulsePair: uh.outPair[c]], bigChip: uh.bigChip];
ENDLOOP;
LoadOutputShiftRegisters[uh];
SetCount[0];
FaceStart[cont1: uh.continuous, go1: FALSE, globalHold: FALSE, cont2: uh.continuous, go2: TRUE, wait: NOT uh.continuous];
FOR i: InputStage
IN InputStage
DO
data: InputData ← ReadChannelOctetData[channel0: 0, bigChip: uh.bigChip];
uh.inData[i] ← data.bits[1];
ENDLOOP;
};
FaceStart:
PROC [cont1, go1, globalHold, cont2, go2, wait:
BOOL] = {
ToCard:
PROC [c,g:
BOOL]
RETURNS [foo:
CARDINAL] = {
foo ← IF c THEN 2 ELSE 0;
IF g THEN foo ← foo+1;
};
pulseGenCounterCtlRegState.continuous ← cont2;
pulseGenCounterCtlRegState.go ← go2;
pulseGenCtlRegState.nReset ← TRUE;
pulseGenCtlRegState.feedBack15 ← FALSE;
pulseGenCtlRegState.globalHold ← globalHold;
TRUSTED {SageFace.Start[firstCounterCtlReg: ToCard[cont1, go1], newCtlReg: IF globalHold THEN 5 ELSE 4, secondCounterCtlReg: ToCard[cont2, go2], wait: wait]};
};
LoadOutputShiftRegisters:
PROC [uh: UserHandle] = {
FOR c:
CARDINAL ← 0, c+2
UNTIL c>
LAST[Channel]
DO
FOR i:
CARDINAL ← 0, i+2
UNTIL i>
LAST[ShiftStage]
DO
dl0, dh0, dl1, dh1: DriveState;
dl0 ← data[c][i];
dh0 ← data[c][i+1];
dl1 ← data[c+1][i];
dh1 ← data[c+1][i+1];
IF i
MOD 4 #0
THEN {
t: DriveState ← dl0; dl0 ← dh0; dh0 ← t;
t ← dl1; dl1 ← dh1; dh1 ← t;
};
WriteChannelPairData[channel0: c, dataLow0: dl0, dataHigh0: dh0, dataLow1: dl1, dataHigh1: dh1, bigChip: uh.bigChip];
ENDLOOP;
ENDLOOP;
};
WriteChannelPairData:
PROCEDURE [channel0: Channel, dataLow0, dataHigh0, dataLow1, dataHigh1: DriveState, bigChip:
BOOL] = {
dataLow: CARDINAL ← ConvertToBits[dataLow0, dataHigh0];
dataHigh: CARDINAL ← ConvertToBits[dataLow1, dataHigh1];
*** I'm not sure about this next line, data may be reversed...JAG ***
IF bigChip THEN DoOutput[16*dataLow + dataHigh, ChannelAddress + (channel0/(IF bigChip THEN 32 ELSE 16))*(IF bigChip THEN 40H ELSE 20H) + channel0 MOD (IF bigChip THEN 32 ELSE 16)]
ELSE
IF (channel0 MOD 16) < 8 THEN DoOutput[16*dataLow + dataHigh, ChannelAddress + (channel0/(IF bigChip THEN 32 ELSE 16))*(IF bigChip THEN 40H ELSE 20H) + channel0 MOD (IF bigChip THEN 32 ELSE 16)]
ELSE DoOutput[dataLow + 16*dataHigh, ChannelAddress + (channel0/(IF bigChip THEN 32 ELSE 16))*(IF bigChip THEN 40H ELSE 20H) + channel0 MOD (IF bigChip THEN 32 ELSE 16)];
};
ConvertToBits:
PROC[dataLow, dataHigh: DriveState]
RETURNS [dataOut:
CARDINAL] = {
01 => H, 10 => L, 11 => T, dataLow goes in bits 1 and 3 of a nibble, dataHigh goes in bits 0 and 2 of the nibble, numbering the nibble bits from left to right, 0 to 3, high order to low order of course.
Bits: ARRAY DriveState OF ARRAY DriveState OF CARDINAL = [[03H, 09H, 0BH], [06H, 0CH, 0EH], [07H, 0DH, 0FH]];
RETURN[Bits[dataLow][dataHigh]];
};
SetCount:
PROCEDURE [value:
CARDINAL] = {
pulseGenCounterRegState.counter ← value;
DoOutput[LOOPHOLE[pulseGenCounterRegState], PulseGenCounterRegHackAddress];
};
SetControl:
PROCEDURE [value: ControlValue, newValue:
BOOL ←
TRUE] = {
SELECT value
FROM
continuous => pulseGenCounterCtlRegState.continuous ← newValue;
go => pulseGenCounterCtlRegState.go ← newValue;
reset => pulseGenCtlRegState.nReset ← NOT newValue;
feedBack15 => pulseGenCtlRegState.feedBack15 ← newValue;
globalHold => pulseGenCtlRegState.globalHold ← newValue;
ENDCASE => ERROR;
IF value IN [continuous .. go] THEN DoOutput[LOOPHOLE[pulseGenCounterCtlRegState], PulseGenCounterCtlRegHackAddress] ELSE DoOutput[LOOPHOLE[pulseGenCtlRegState], PulseGenCtlRegAddress];
};
SetPulseLineTap:
PROCEDURE [pulseLine: PulseLine, tap: Tap] = {
DoOutput[tap, PulseGenTapAddress+pulseLine];
};
SetChannelCtlReg:
PROCEDURE [channel: Channel, register: ChannelCtlReg, bigChip:
BOOL] = {
DoOutput[LOOPHOLE[register], ChannelAddress + (channel/(IF bigChip THEN 32 ELSE 16))*(IF bigChip THEN 40H ELSE 20H) + (IF bigChip THEN 20H ELSE 10H) + channel MOD (IF bigChip THEN 32 ELSE 16)];
};
ReadChannelOctetData:
PROCEDURE [channel0: Channel, bigChip:
BOOL]
RETURNS [InputData] = {
RETURN[ LOOPHOLE [DoInput[ChannelAddress + (channel0/(IF bigChip THEN 32 ELSE 16))*(IF bigChip THEN 40H ELSE 20H) + channel0 MOD (IF bigChip THEN 32 ELSE 16)]]];
};
DoInput:
PROCEDURE [address:
LONG
CARDINAL]
RETURNS [word:
CARDINAL] =
TRUSTED {
RETURN[Multibus.Input[LOOPHOLE[address]]];
};
DoOutput:
PROCEDURE [word:
CARDINAL, address:
LONG
CARDINAL] =
TRUSTED {
Multibus.Output[LOOPHOLE[word, UNSPECIFIED], LOOPHOLE[address]];
};
h: UserHandle ← NEW [UserRec];
h.FoolAround ← FoolAround;
h.SetChannels ← SetChannels;
h.quit ← FALSE;
FOR pl: PulseLine
IN PulseLine
DO
h.pulseTap[pl] ← 4*pl;
ENDLOOP;
h.pulseTap[WidthPulseLine] ← 1;
h.pulseTap[CyclePulseLine] ← 60;
h.pulseTap[0] ← 47;
h.pulseTap[8] ← 63;
FOR c: Channel
IN Channel
DO
h.outPair[c] ← 2;
h.inPulse[c] ← 3;
FOR s: ShiftStage
IN ShiftStage
DO
data[c][s] ← IF s MOD 2 = 0 THEN L ELSE H;
ENDLOOP;
ENDLOOP;
h.outPair[1] ← 0;
[] ← ViewRec.ViewRef[agg: h, specs: ViewRec.BindAllOfATypeFromRefs[h, NEW[UserHandle ← h]], createOptions: [maxEltsHeight: 320], viewerInit: [iconic: FALSE, name: "Sage Tester"], paint: TRUE];
END.