DIRECTORY Multibus, MultibusRpcControl, Rope, SageFace, SageFaceRpcControl, ViewRec; SageTest: CEDAR PROGRAM IMPORTS Multibus, MultibusRpcControl, SageFace, SageFaceRpcControl, ViewRec = BEGIN OPEN SageFace; 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]; 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] = { 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. ˜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 *** I'm not sure about this next line, data may be reversed...JAG *** 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. Κ ΰ˜Icodešœ ™ K™6K™9K˜šΟk ˜ K˜ Kšœ˜Kšœ˜K˜ Kšœ˜Kšœ˜K˜—šœ œœ˜KšœF˜M—K˜Kš˜K˜šœ ˜K˜—Kšœ œœ ˜šœ œœ˜Kšœ œ œ˜!Kšœ œ œ ˜$Kšœ œ œ ˜$Kšœœ œœ˜!Kšœ œœ˜Kšœ œœ˜Kšœœœ˜KšΟn œœ˜!Kšž œœ˜!Kšœ˜—K˜Kš œ œ œœ œ ˜=K˜š œœœ œœ˜4K˜Kšœ!˜!—K˜š œœœ œœ˜7Kšœ˜Kšœœœ˜$Kšœœœ˜K˜—š œœœ œœ˜0K˜Kšœœœ˜ Kšœœœ˜$Kšœœœ˜%K˜—š œœœ œœ˜/K˜Kšœœœ˜!Kšœ%˜%Kšœ%˜%—K˜Kšœ œ ˜Kšœ œ ˜Kšœ œ ˜Kšœœ ˜Kšœ œ ˜Kšœ œ ˜Kš œ œœœœ˜K˜K˜;K˜CJ˜IK˜8K˜K˜Kšœ˜K˜Kšœœ3˜EK˜Kšœ œ˜š œ œœ œœ˜+Kšœ#˜#Kš œœœ œœ˜:—Kšœ œ˜#K˜Kšœ5˜5Kšœ8œœ˜FKšœ*œœœ˜?K˜šžœ œ œœ˜.šœ˜ Kšœ3œ ˜?Kšœ3œ ˜?Kšœ˜—Kšœ œ:˜KKšœ œ@˜QKšœ œ.˜?K˜K˜—šž œ œ˜*šœ ˜KšœTœ˜cKšœ˜—K˜K˜—šž œ œ˜+Kšœœ˜Kšœ˜Kšœ˜Kšœ˜Kšœœ˜šœœ ˜!Kšœ5˜5Kšœ˜—šœ œ ˜Kšœ3œQ˜ˆKšœ˜—Kšœ˜Kšœ ˜ Kš œ%œœœœ˜yšœœ ˜"KšœI˜IKšœ˜Kšœ˜—K˜K˜—šž œœ,œ˜Dš žœœœœœ˜3Kšœœœœ˜Kšœœ ˜K˜—Kšœ.˜.Kšœ$˜$Kšœœ˜"Kšœ!œ˜'Kšœ,˜,KšœDœ œœ:˜žKšœ˜K™—šžœœ˜3š œœ œœ ˜1š œœ œœ ˜4Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜šœœœ˜Kšœ(˜(Kšœ˜Kšœ˜—Kšœu˜uKšœ˜—Kšœ˜—Kšœ˜K™—šžœ œTœ˜|Kšœ œ&˜7Kšœ œ&˜8K˜K™EKšœ œ=œ œœœ œœœœ œœ˜΄š˜Kšœ œ œ<œ œœœ œœœœ œœ˜ΒKšœ<œ œœœ œœœœ œœ˜ͺ—Kšœ˜K˜—šž œœ œ œ˜RKšœΚ™ΚKš œœ œœ œœ7˜mKšœ˜ Kšœ˜K˜—šžœ œ œ˜)Kšœ(˜(Kšœ œ:˜KK˜K˜—šž œ œ!œœ˜Fšœ˜Kšœ?˜?Kšœ/˜/Kšœ&œ ˜3Kšœ8˜8Kšœ8˜8Kšœœ˜—Kš œœœ œ@œ œ.˜ΉK˜—K˜šžœ œ%˜?Kšœ,˜,K˜K˜—šžœ œ6œ˜ZKšœ œ&œ œœœ œœ œ œœœœ œœ˜ΑK˜K˜—šžœ œœœ˜ZKšœœ%œ œœœ œœœœ œœ˜‘Kšœ˜K˜—šžœ œ œœœœœ˜PKšœœ ˜*Kšœ˜K˜—š žœ œœ œœœ˜HKšœœ œœ ˜@K˜K˜—Kšœœ ˜K˜Kšœ˜Kšœ œ˜šœœ ˜!Kšœ˜Kšœ˜—Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜šœ œ ˜Kšœ˜Kšœ˜šœœ ˜"Kš œ œœœœœœ˜*Kšœ˜—Kšœ˜—Kšœ˜KšœFœMœœ˜ΐKšœ˜—…—*