EGlasImpl.mesa
Copyright © 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
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;
[Indigo]<Dicentra>11.1>Heads>Private>TTYPortHeadDicentra.mesa
[Indigo]<Dicentra>11.1>Heads>Friends>MultibusAddresses.mesa
Krock: Use second connector because it doesn't fit.
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: BOOLFALSE;
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: ROPEIO.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: ROPEIO.PutFR["DC%g-%g*", IO.real[x], IO.real[y]];
SendAndCheck[s];
};
SetDieSize: PUBLIC PROCEDURE [x, y: REAL] = {
s: ROPEIO.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.STREAMIO.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] = {
digits is the total of integer+deciamlPoint+fractional characters
c: CHAR;
s: IO.STREAMIO.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.STREAMIO.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: BOOLTRUE] = {
c: CHAR;
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.
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.