DIRECTORY BitOps, Core, IO, Ports, Rosemary, RosemaryUser, TerminalIO; RadioTest: CEDAR PROGRAM IMPORTS BitOps, IO, Ports, Rosemary, RosemaryUser, TerminalIO = BEGIN OPEN Ports; SSCtlPorts: TYPE = REF SSCtlPortsRec; SSCtlPortsRec: TYPE = RECORD[ nBR, nBG, nReset, nSel, nAS, SClk, nLErr, nAck0, nAck1, nAck2, Siz, Read, PA, Data, TxClock, TxCode, TxData, TxEnb, RxClock, RxCode, RxData, Lock, SamClk, SamData, Illegal, T0, SRegOut, Ser0, SlipEnb: Port _ NIL]; Warning: SIGNAL = CODE; SSCtlTestProc: RosemaryUser.TestProc = { ports: SSCtlPorts _ SSCtlInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; txData: NAT = 0; txCtl: NAT = 1; rxData: NAT = 2; rxCtl: NAT = 3; serialCtl: NAT = 4; serialIntegrate: NAT = 0; serialDecay: NAT = 1; serialLockThreshold: NAT = 2; serialUnlockThreshold: NAT = 3; SBusStore: PROC [adr: NAT, value: NAT] = { PB[nSel, FALSE, force]; PB[nAS, FALSE, force]; PB[nLErr, TRUE, expect]; PB[nAck0, TRUE, expect]; PD[nAck1, inspect]; PB[nAck2, TRUE, expect]; PDW[Siz, 1, force]; PB[Read, FALSE, force]; PDW[PA, adr, force]; PDW[Data, BitOps.DShift[value, 24, 32], force]; THROUGH [1..255] DO SSCtlCycleClock[ports, Eval]; IF NOT GB[nAck1] THEN EXIT; REPEAT FINISHED => SIGNAL Warning; ENDLOOP; PB[nAS, TRUE, force]; SSCtlCycleClock[ports, Eval]; PB[nSel, TRUE, force]; SSCtlCycleClock[ports, Eval]; }; SBusFetch: PROC [adr: NAT] RETURNS [value: NAT] = { PB[nSel, FALSE, force]; PB[nAS, FALSE, force]; PB[nLErr, TRUE, expect]; PB[nAck0, TRUE, expect]; PD[nAck1, inspect]; PB[nAck2, TRUE, expect]; PDW[Siz, 1, force]; PB[Read, TRUE, force]; PDW[PA, adr, force]; PD[Data, inspect]; THROUGH [1..255] DO SSCtlCycleClock[ports, Eval]; IF NOT GB[nAck1] THEN EXIT; REPEAT FINISHED => SIGNAL Warning; ENDLOOP; value _ BitOps.ELFD[GDW[Data], 0, 8, 32]; PB[nAS, TRUE, force]; SSCtlCycleClock[ports, Eval]; PB[nSel, TRUE, force]; SSCtlCycleClock[ports, Eval]; }; serialBitCount: NAT = 12; SerialStore: PROC [value: NAT, reg: NAT] = { OPEN BitOps; serialCtlRegLen: NAT = 8; serialDoIt: NAT = 0; serialBitOfData: NAT = 1; serialRegAdr: NAT = 2; serialRegAdrLen: NAT = 2; serialBitAdr: NAT = 4; serialBitAdrLen: NAT = 4; d: BitWord _ BitWordZero; d _ ICIW[reg, d, serialRegAdr, serialRegAdrLen, serialCtlRegLen]; FOR bitIndex:NAT IN [0..serialBitCount) DO d _ IBIW[FALSE, d, serialDoIt, serialCtlRegLen]; d _ ICIW[bitIndex, d, serialBitAdr, serialBitAdrLen, serialCtlRegLen]; d _ IBIW[EBFW[value, serialBitCount-bitIndex-1, serialBitCount], d, serialBitOfData, serialCtlRegLen]; SBusStore[serialCtl, d]; d _ IBID[TRUE, d, serialDoIt, serialCtlRegLen]; SBusStore[serialCtl, d]; SSCtlCycleClock[ports, Eval, 2*serialBitCount]; ENDLOOP; }; PD[TxEnb, inspect]; SBusStore[txCtl, 40H]; IF NOT GB[TxEnb] THEN SIGNAL Warning; PD[Ser0, inspect]; SerialStore[00AH, serialIntegrate]; IF GDW[Ser0]#00AH THEN SIGNAL Warning; SBusStore[rxCtl, 32H]; SerialStore[004H, serialLockThreshold]; SerialStore[006H, serialUnlockThreshold]; SerialStore[001H, serialDecay]; SSCtlCycleClock[ports, Eval, 10*serialBitCount]; PB[Lock, TRUE, expect]; SSCtlCycleClock[ports, Eval]; PD[Lock, none]; THROUGH [1..10] DO PB[TxData, FALSE, none]; SSCtlCycleClock[ports, Eval, 16]; PB[TxData, TRUE, none]; SSCtlCycleClock[ports, Eval, 16]; PB[TxData, FALSE, none]; SSCtlCycleClock[ports, Eval, 16]; PB[TxData, TRUE, none]; SSCtlCycleClock[ports, Eval, 16]; ENDLOOP; PB[Lock, FALSE, expect]; SSCtlCycleClock[ports, Eval]; PD[Lock, none]; PD[TxData, inspect]; SSCtlCycleClock[ports, Eval, 510]; -- initialize receiver IF BitOps.EBFD[SBusFetch[txCtl], 0, 8] THEN SIGNAL Warning; -- tx already busy? SBusStore[txData, 55H]; IF NOT BitOps.EBFD[SBusFetch[txCtl], 0, 8] THEN SIGNAL Warning; -- tx failed to go busy? THROUGH [1..100] DO IF BitOps.EBFD[SBusFetch[rxCtl], 0, 8] THEN EXIT; REPEAT FINISHED => SIGNAL Warning; -- rx failed to go ready? ENDLOOP; IF SBusFetch[rxData]#55H THEN SIGNAL Warning; -- incorrect data? }}; SSCtlInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: SSCtlPorts]= { ports _ NEW[SSCtlPortsRec]; {OPEN ports; [nBR, nBG, nReset, nSel, nAS, SClk, nLErr, nAck0, nAck1, nAck2] _ Ports.BindPorts[public, p, "nBR", "nBG", "nReset", "nSel", "nAS", "SClk", "nLErr", "nAck0", "nAck1", "nAck2"]; [Siz, Read, PA, Data, TxClock, TxCode, TxData, TxEnb, RxClock, RxCode, RxData] _ Ports.BindPorts[public, p, "Siz", "Read", "PA", "Data", "TxClock", "TxCode", "TxData", "TxEnb", "RxClock", "RxCode", "RxData"]; [Lock, SamClk, SamData, Illegal, T0, SRegOut, Ser0, SlipEnb] _ Ports.BindPorts[public, p, "Lock", "SamClk", "SamData", "Illegal", "T0", "SRegOut", "Ser0", "SlipEnb"]; PB[nBR, TRUE, force]; PB[nBG, TRUE, force]; PB[nReset, TRUE, force]; PB[nSel, TRUE, force]; PB[nAS, TRUE, force]; PB[nLErr, TRUE, force]; PB[nAck0, TRUE, force]; PB[nAck1, TRUE, force]; PB[nAck2, TRUE, force]; PDW[Siz, 0, force]; PB[Read, TRUE, force]; PDW[PA, 0, force]; PDW[Data, 0, force]; PD[TxCode, none]; PD[TxData, none]; PD[TxEnb, none]; PD[RxCode, none]; PB[RxData, TRUE, force]; PD[Lock, none]; PD[SamClk, none]; PD[SamData, none]; PD[Illegal, none]; PD[T0, none]; PD[SRegOut, none]; PD[Ser0, none]; PB[SlipEnb, TRUE, force]; PB[TxClock, TRUE, force]; SSCtlCycleClock[ports, eval]; }}; SSCtlCycleClock: PROC [ports: SSCtlPorts, eval: RosemaryUser.TestEvalProc, count: NAT _ 1] = { OPEN ports; THROUGH [1..count] DO PB[RxData, NOT GB[TxData], force]; PB[SClk, FALSE, force]; PB[TxClock, NOT GB[TxClock], force]; PB[RxClock, FALSE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; PB[RxData, NOT GB[TxData], force]; PB[SClk, TRUE, force]; PB[RxClock, TRUE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; ENDLOOP; }; RecoverPorts: TYPE = REF RecoverPortsRec; RecoverPortsRec: TYPE = RECORD[ Signal, CK, Sample, Data: Port _ NIL]; RecoverTestProc: RosemaryUser.TestProc = { ports: RecoverPorts _ RecoverInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; RecoverCycleClock[ports, Eval, 21]; THROUGH [1..25] DO PB[Signal, FALSE, force]; RecoverCycleClock[ports, Eval, 25]; PB[Signal, TRUE, force]; RecoverCycleClock[ports, Eval, 25]; ENDLOOP; }}; RecoverInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: RecoverPorts]= { ports _ NEW[RecoverPortsRec]; {OPEN ports; [Signal, CK, Sample, Data] _ Ports.BindPorts[public, p, "Signal", "CK", "Sample", "Data"]; PB[Signal, FALSE, force]; PD[Sample, none]; PD[Data, none]; RecoverCycleClock[ports, eval]; }}; RecoverCycleClock: PROC [ports: RecoverPorts, eval: RosemaryUser.TestEvalProc, count: NAT _ 1] = { OPEN ports; THROUGH [1..count] DO PB[CK, FALSE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; PB[CK, TRUE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; ENDLOOP; }; LockPorts: TYPE = REF LockPortsRec; LockPortsRec: TYPE = RECORD[ Signal, CK, T0, Data, Sum: Port _ NIL]; LockTestProc: RosemaryUser.TestProc = { ports: LockPorts _ LockInitialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; DO LockCycleClock[ports, Eval, 13]; PB[Signal, NOT GB[Signal], force]; ENDLOOP; }}; LockInitialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: LockPorts]= { ports _ NEW[LockPortsRec]; {OPEN ports; [Signal, CK, T0, Data, Sum] _ Ports.BindPorts[public, p, "Signal", "CK", "T0", "Data", "Sum"]; PB[Signal, FALSE, force]; PD[T0, none]; PD[Data, none]; PD[Sum, none]; LockCycleClock[ports, eval]; }}; LockCycleClock: PROC [ports: LockPorts, eval: RosemaryUser.TestEvalProc, count: NAT _ 1] = { OPEN ports; THROUGH [1..count] DO PB[CK, FALSE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; PB[CK, TRUE, force]; eval[clockEval: TRUE]; eval[clockEval: FALSE]; ENDLOOP; }; Encode8to10Ports: TYPE = REF Encode8to10PortsRec; Encode8to10PortsRec: TYPE = RECORD[ i, o, Idle: Port _ NIL]; Encode8to10TestProc: RosemaryUser.TestProc = { ports: Encode8to10Ports _ Encode8to10Initialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; PB[Idle, FALSE, expect]; FOR input: BitOps.BitDWord IN [0..256) DO output: BitOps.BitDWord _ Encode[input]; PDW[i, input, force]; PDW[o, output, expect]; TerminalIO.PutF["\ni: %x, o: %x", IO.int[input], IO.int[output]]; Eval[]; IF output IN [336..352) AND input#6AH THEN ERROR; FOR check: BitOps.BitDWord IN [0..input) DO IF Encode[check]=output THEN ERROR; ENDLOOP; ENDLOOP; PD[o, none]; PB[Idle, TRUE, expect]; PDW[i, 155H, force]; Eval[]; PDW[i, 2AAH, force]; Eval[]; }}; Encode8to10Initialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: Encode8to10Ports]= { ports _ NEW[Encode8to10PortsRec]; {OPEN ports; [i, o, Idle] _ Ports.BindPorts[public, p, "i", "o", "Idle"]; PDW[i, 0, force]; PD[o, none]; PD[Idle, none]; eval[]; }}; Decode10to8Ports: TYPE = REF Decode10to8PortsRec; Decode10to8PortsRec: TYPE = RECORD[ i, o: Port _ NIL]; Decode10to8TestProc: RosemaryUser.TestProc = { ports: Decode10to8Ports _ Decode10to8Initialize[p, cellType.public, Eval ! Rosemary.Stop => IF reason = $BoolWireHasX THEN RESUME ELSE REJECT]; {OPEN ports; FOR output: BitOps.BitDWord IN [0..256) DO input: BitOps.BitDWord _ Encode[output]; PDW[i, input, force]; PDW[o, output, expect]; TerminalIO.PutF["\ni: %x, o: %x", IO.int[input], IO.int[output]]; Eval[]; ENDLOOP; }}; Decode10to8Initialize: PROC [p: Ports.Port, public: Core.Wire, eval: RosemaryUser.TestEvalProc] RETURNS [ports: Decode10to8Ports]= { ports _ NEW[Decode10to8PortsRec]; {OPEN ports; [i, o] _ Ports.BindPorts[public, p, "i", "o"]; PDW[i, 0, force]; PDW[o, 0, none]; eval[]; }}; Encode: PROC [input: BitOps.BitDWord] RETURNS [output: BitOps.BitDWord_BitOps.BitDWordZero] = { OPEN BitOps; SELECT ECFD[input, 0, 2, 8] FROM 0 => IF ECFD[input, 2, 2, 8]=1 THEN { output _ IBID[TRUE, output, 0, 10]; output _ IBID[EBFD[input, 5, 8], output, 1, 10]; output _ IBID[EBFD[input, 4, 8], output, 2, 10]; output _ IBID[EBFD[input, 6, 8], output, 3, 10]; output _ ICID[5, output, 4, 5, 10]; output _ IBID[EBFD[input, 7, 8], output, 9, 10]; } ELSE { output _ ICID[5, output, 0, 4, 10]; output _ ICID[ECFD[input, 2, 6, 8], output, 4, 6, 10]; }; 1 => IF ECFD[input, 2, 6, 8]=02AH THEN output _ 154H ELSE { output _ IBID[EBFD[input, 2, 8], output, 0, 10]; output _ ICID[5, output, 1, 4, 10]; output _ ICID[ECFD[input, 3, 5, 8], output, 5, 5, 10]; }; 2 => IF ECFD[input, 2, 2, 8]=1 THEN { output _ ICID[ECFD[input, 4, 2, 8], output, 0, 2, 10]; output _ ICID[0, output, 2, 2, 10]; output _ ICID[ECFD[input, 6, 2, 8], output, 4, 2, 10]; output _ ICID[5, output, 6, 4, 10]; } ELSE { output _ ICID[ECFD[input, 2, 2, 8], output, 0, 2, 10]; output _ ICID[5, output, 2, 4, 10]; output _ ICID[ECFD[input, 4, 4, 8], output, 6, 4, 10]; }; 3 => IF ECFD[input, 3, 2, 8]=1 THEN { output _ IBID[EBFD[input, 2, 8], output, 0, 10]; output _ IBID[EBFD[input, 5, 8], output, 1, 10]; output _ ICID[3, output, 2, 2, 10]; output _ ICID[ECFD[input, 6, 2, 8], output, 4, 2, 10]; output _ ICID[5, output, 6, 4, 10]; } ELSE { output _ ICID[ECFD[input, 2, 3, 8], output, 0, 3, 10]; output _ ICID[5, output, 3, 4, 10]; output _ ICID[ECFD[input, 5, 3, 8], output, 7, 3, 10]; }; ENDCASE => ERROR; }; RosemaryUser.RegisterTestProc["SSCtl", SSCtlTestProc]; RosemaryUser.RegisterTestProc["Recover", RecoverTestProc]; RosemaryUser.RegisterTestProc["Lock", LockTestProc]; RosemaryUser.RegisterTestProc["Encode8to10", Encode8to10TestProc]; RosemaryUser.RegisterTestProc["Decode10to8", Decode10to8TestProc]; END. ¦RadioTest.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Barth, February 23, 1990 5:24:55 pm PST SSCtl Recover Lock Encode8to10 Decode10to8 ΚL– "cedar" style˜codešœ™K™˜FKšœœœY˜fKšœ˜Kšœœœ"˜/Kšœ˜Kšœ/˜/Kšœ˜—K˜—Kšœ˜Kšœ˜Kš œœœœœ ˜%Kšœ˜Kšœ#˜#Kšœœ œœ ˜&Kšœ˜Kšœ'˜'Kšœ)˜)Kšœ˜Kšœ0˜0Kšœœ ˜Kšœ˜Kšœ ˜šœ ˜Kšœ œ˜Kšœ!˜!Kšœ œ˜Kšœ!˜!Kšœ œ˜Kšœ!˜!Kšœ œ˜Kšœ!˜!Kšœ˜—Kšœœ ˜Kšœ˜Kšœ ˜Kšœ˜Kšœ$Οc˜:Kš œœœœ Ÿ˜PKšœ˜Kš œœœœœ Ÿ˜Yšœ ˜Kšœœœœ˜1Kšœœœ Ÿ˜=Kšœ˜—Kšœœœ Ÿ˜@šœ˜K˜——šžœœEœ˜xKšœœ˜Kšœœ˜ Kšœ°˜°KšœΠ˜ΠKšœ¦˜¦Kšœœ ˜Kšœœ ˜Kšœ œ ˜Kšœœ ˜Kšœœ ˜Kšœœ ˜Kšœœ ˜Kšœœ ˜Kšœœ ˜Kšœ˜Kšœœ ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ œ ˜Kšœ ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜Kšœ œ ˜Kšœ œ ˜Kšœ˜K˜K˜—šžœœ=œ ˜^Kšœ˜ šœ ˜Kšœ œœ˜"Kšœœ ˜Kšœ œœ˜$Kšœ œ ˜Kšœœ˜Kšœœ˜Kšœ œœ˜"Kšœœ ˜Kšœ œ ˜Kšœœ˜Kšœœ˜Kšœ˜—Kšœ˜K˜——™Kšœœœ˜)šœœœ˜Kšœ!œ˜&K˜—šžœ˜*Kš œTœœœœœ˜‡Kšœœ˜ Kšœ#˜#šœ ˜Kšœ œ ˜Kšœ#˜#Kšœ œ ˜Kšœ#˜#Kšœ˜—šœ˜K˜——šžœœEœ˜|Kšœœ˜Kšœœ˜ KšœZ˜ZKšœ œ ˜Kšœ˜Kšœ ˜Kšœ˜K˜K˜—šžœœ?œ ˜bKšœ˜ šœ ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœ˜—Kšœ˜K˜——™Kšœ œœ˜#šœœœ˜Kšœ"œ˜'K˜—šž œ˜'Kš œNœœœœœ˜Kšœœ˜ š˜Kšœ ˜ Kšœ œœ˜"Kšœ˜—šœ˜K˜——šžœœEœ˜vKšœœ˜Kšœœ˜ Kšœ^˜^Kšœ œ ˜Kšœ ˜ Kšœ ˜Kšœ ˜Kšœ˜K˜K˜—šžœœ<œ ˜\Kšœ˜ šœ ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœœ ˜Kšœœ˜Kšœœ˜Kšœ˜—Kšœ˜K˜——™ Kšœœœ˜1šœœœ˜#Kšœœ˜K˜—šžœ˜.Kš œ\œœœœœ˜Kšœœ˜ Kšœœ ˜šœœ ˜)Kšœ(˜(Kšœ˜Kšœ˜K˜AKšœ˜Kš œœ œ œœ˜1šœœ ˜+Kšœœœ˜#Kšœ˜—Kšœ˜—Kšœ ˜ Kšœœ ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜šœ˜K˜——šžœœEœ˜„Kšœœ˜!Kšœœ˜ Kšœ<˜x