DIRECTORY Ascii, Basics, Convert, EGlas, IO, Process, Rope, XBus; EGlasImpl: CEDAR PROGRAM IMPORTS Basics, Convert, IO, Process, Rope, XBus EXPORTS EGlas = BEGIN ROPE: TYPE = Rope.ROPE; scc0: LONG CARDINAL = 29000H; -- MultibusAddresses.scc2 chanB: LONG POINTER TO Words = LOOPHOLE[scc0 + 00H]; chanA: LONG POINTER TO Words = LOOPHOLE[scc0 + 10H]; chan: LONG POINTER TO Words _ chanA; -- Line 0 Words: TYPE = RECORD [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15: WORD]; initialized: BOOL _ FALSE; Load: PUBLIC PROCEDURE = { SendAndCheck["LD*", FALSE]; }; ZUp: PUBLIC PROCEDURE = { IF ~IsZUp[] THEN ToggleZ[]; }; ZDown: PUBLIC PROCEDURE = { IF IsZUp[] THEN ToggleZ[]; }; IsZUp: PROCEDURE RETURNS [BOOLEAN]= { status: INT; Send["?SA*"]; CheckResponse[2, "SA"]; IF (status _ GetInt[2,16]) > 15 THEN SynchError[]; -- high nibble should be zero CheckResponse[1, "*"]; RETURN[Basics.BITAND[status, 2]#0]; }; ToggleZ: PROCEDURE = { SendAndCheck["ZM*"]; Process.Pause[Process.SecondsToTicks[1]]; --Tak said this is a good idea }; TestStart: PUBLIC PROCEDURE = { SendAndCheck["TS*"]; }; Seek: PUBLIC PROCEDURE [x, y: REAL] = { s: ROPE _ IO.PutFR["SK%g-%g*", IO.real[x], IO.real[y]]; SendAndCheck[s]; Process.Pause[Process.SecondsToTicks[1]]; --Tak said this is a good idea }; GetDeviceCoordinates: PUBLIC PROCEDURE [] RETURNS [x, y: REAL] = { Send["?DC*"]; CheckResponse[2, "DC"]; x _ GetReal[5]; CheckResponse[1, "-"]; y _ GetReal[5]; CheckResponse[1, "*"]; }; SetDeviceCoordinates: PUBLIC PROCEDURE [x, y: REAL] = { s: ROPE _ IO.PutFR["DC%g-%g*", IO.real[x], IO.real[y]]; SendAndCheck[s]; }; SetDieSize: PUBLIC PROCEDURE [x, y: REAL] = { s: ROPE _ IO.PutFR["DS%g-%g*", IO.real[x], IO.real[y]]; SendAndCheck[s]; }; LampOn: PUBLIC PROCEDURE [] = { SendAndCheck["LO*"]; }; LampOff: PUBLIC PROCEDURE [] = { SendAndCheck["LF*"]; }; ManualMode: PUBLIC PROCEDURE [] = { SendAndCheck["EM*"]; }; GetInt: PROCEDURE [digits: CARDINAL, base: Convert.Base] RETURNS[i: INT] = { c: CHAR; s: IO.STREAM _ IO.ROS[]; FOR j: CARDINAL IN [0..digits) DO s.PutChar[c_GetChar[]]; ENDLOOP; RETURN[Convert.IntFromRope[IO.RopeFromROS[s], base]]; }; GetReal: PROCEDURE [digits: CARDINAL] RETURNS[r: REAL] = { c: CHAR; s: IO.STREAM _ IO.ROS[]; FOR j: CARDINAL IN [0..digits) DO s.PutChar[(c_GetChar[])]; ENDLOOP; RETURN[Convert.RealFromRope[IO.RopeFromROS[s]]]; }; CheckResponse: PROCEDURE [chars: CARDINAL, expected: ROPE] = { c: CHAR; s: IO.STREAM _ IO.ROS[]; FOR j: CARDINAL IN [0..chars) DO s.PutChar[(c_GetChar[])]; ENDLOOP; IF Rope.Compare[IO.RopeFromROS[s], expected, FALSE] # equal THEN SynchError[]; }; SendAndCheck: PROCEDURE [s: ROPE, retry: BOOL _ TRUE] = { c: CHAR; DO Send[s]; SELECT (c _ GetChar[]) FROM Ascii.ControlS => IF GetChar[] # '* THEN SynchError[] ELSE EXIT; '\021, '\022 => IF GetChar[] # '* THEN SynchError[] ELSE IF NOT retry THEN EXIT; ENDCASE => SynchError[]; ENDLOOP; }; Send: PROCEDURE [s: ROPE] = { FOR i:INT IN [0..s.Length[]) DO PutChar[s.Fetch[i]]; ENDLOOP; }; SynchError: PROCEDURE = { ERROR; }; PutChar: PROCEDURE [char: CHARACTER] = TRUSTED { IF ~initialized THEN Init[]; UNTIL ReadyToPut[] DO Process.CheckForAbort[]; ENDLOOP; IOWrite[@chan.r8, LOOPHOLE[char]]; }; ReadyToPut: PROCEDURE RETURNS [BOOLEAN] = TRUSTED { bits: WORD = IORead[@chan.r0]; RETURN[Basics.BITAND[bits, 4] # 0]; -- Tx Buffer Empty }; GetChar: PROCEDURE RETURNS [char: CHARACTER] = TRUSTED { IF ~initialized THEN Init[]; UNTIL ReadyToGet[] DO Process.CheckForAbort[]; ENDLOOP; char _ LOOPHOLE[Basics.BITAND[IORead[@chan.r8], 177B]]; }; ReadyToGet: PROCEDURE RETURNS [BOOLEAN] = TRUSTED { bits: WORD = IORead[@chan.r0]; RETURN[Basics.BITAND[bits, 1] # 0]; -- Rx Character Available }; Init: PUBLIC PROCEDURE = TRUSTED { IOWrite[@chanB.r0, 002H]; -- Shift Left (ADR0 is ignored) IOWrite[@chan.r9, 0C0H]; -- Hardware Reset IOWrite[@chan.r1, 000H]; -- No interrupts IOWrite[@chan.r3, 0C1H]; -- 8bits/char, RxE IOWrite[@chan.r4, 04AH]; -- 16xClock, 1.5 Stop Bits IOWrite[@chan.r5, 0EAH]; -- DTR, 8bits/char, TxE, RTS IOWrite[@chan.r11, 050H]; -- Clocks from BR Gen IOWrite[@chan.r12, 31]; -- Low byte of time constant IOWrite[@chan.r13, 000H]; -- High byte of time constant IOWrite[@chan.r14, 003H]; -- Enable Baud Rate Gen from PClk initialized _ TRUE; }; IORead: PROCEDURE [adr: LONG POINTER] RETURNS [data: CARDINAL] = TRUSTED { data _ XBus.IORead[LOOPHOLE[2*LOOPHOLE[adr, LONG CARDINAL], LONG POINTER]]; }; IOWrite: PROCEDURE [adr: LONG POINTER, data: CARDINAL] = TRUSTED { XBus.IOWrite[LOOPHOLE[2*LOOPHOLE[adr, LONG CARDINAL], LONG POINTER], data]; }; END.  EGlasImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Barth, September 18, 1985 3:15:56 pm PDT Last Edited by: Gasbarro February 21, 1986 2:47:56 pm PST [Indigo]11.1>Heads>Private>TTYPortHeadDicentra.mesa [Indigo]11.1>Heads>Friends>MultibusAddresses.mesa Krock: Use second connector because it doesn't fit. digits is the total of integer+deciamlPoint+fractional characters If the command succeeds a "^s*" is returned, if instead a "^q*" or "^r*" (\021 or \022) is returned then the prober went on/off-line during execution of the command. If the command can be retried it should be sent again. The probable cause of the prober being off-line during a load command is an auto-align failure. In this event the user finishes the load command manually. ΚQ˜šœ™Icodešœ Οmœ1™Jšœžœ˜Jš œžœžœžœžœ˜šžœžœžœ ž˜ Jšœ˜Kšžœ˜—Kšžœžœžœ žœ˜NJšœ˜J˜—š   œž œžœ žœžœ˜9Jšœžœ˜Jšœϊ™ϊšž˜Jšœ˜šžœž˜Kš œžœžœžœžœ˜@Kšœžœžœžœžœžœžœžœ˜PKšžœ˜—Kšžœ˜—Jšœ˜—š œž œžœ˜šžœžœžœž˜Jšœ˜Jšžœ˜—Jšœ˜—š  œž œ˜Jšžœ˜Jšœ˜—š œž œž œžœ˜0Jšžœžœ˜Jšžœžœžœ˜7Jšœžœ˜"Jšœ˜J˜—š   œž œžœžœžœ˜3Jšœžœ˜JšžœžœŸ˜7Jšœ˜J˜—š  œž œžœž œžœ˜8Jšžœžœ˜Jšžœžœžœ˜7Jšœžœžœ˜7Jšœ˜J˜—š   œž œžœžœžœ˜3Jšœžœ˜JšžœžœŸ˜>Jšœ˜J˜—š œžœžœ˜"JšœŸ˜:JšœŸ˜+JšœŸ˜*JšœŸ˜,JšœŸ˜4JšœŸ˜6JšœŸ˜0JšœŸ˜5JšœŸ˜8JšœŸ!˜