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
[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: 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] = {
digits is the total of integer+deciamlPoint+fractional characters
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;
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.