EmDM2500:
CEDAR
PROGRAM
IMPORTS DisplayControllers, DisplayControllerSteps, Rope, TermProgs
= {OPEN DisplayControllers, DisplayControllerSteps, TermProgs;
DisplayDetails: TYPE = CharDisplays.DisplayDetails;
DMState: TYPE = REF DMStateRep;
DMStateRep:
TYPE =
RECORD [
didCRLF: BOOL ← FALSE,
colData: SEQUENCE cols: NAT OF ColData];
ColData:
TYPE =
RECORD [
tabStopHere: BOOL ← FALSE];
InitDM2500:
PROC [dc: DisplayController] = {
dms: DMState ← NEW [DMStateRep[dc.cd.det.columns]];
dc.cps.clientData ← dms;
FOR c:
NAT
IN [0 .. dms.cols)
DO
dms.colData[c] ← [];
ENDLOOP;
};
InitDMWaits:
PROC [dc: DisplayController] = {
InitDM2500[dc];
dc.cd.class.SetFont[dc.cd, "SAIL"];
};
MakeDM:
PROC [flavor:
ATOM, autoMargins:
BOOL]
RETURNS [t: Term] = {
t ←
NEW [TermRep ← [
det: [autoMargins: autoMargins, scrollsVariable: TRUE],
cp: NewControlProgram[
SELECT flavor
FROM
$waits => InitDMWaits,
$Twenty500 => InitDM2500,
ENDCASE => ERROR]
]];
FOR c:
CHAR
IN
CHAR
DO
AddInstruction[t.cp, LIST[Rope.FromChar[c]], [DMPrint, flavor, TRUE]];
ENDLOOP;
FOR c: CHAR IN CHAR DO
AddInstruction[t.cp, LIST[Rope.Cat["\033", Rope.FromChar[c]]], [DMPrint, flavor, FALSE]];
ENDLOOP;
AddInstruction[t.cp, LIST["\000"], [Naught]];
AddInstruction[t.cp, LIST["\002"], [DMHome]];
AddInstruction[t.cp, LIST["\014\002"], [DMHome]];
AddInstruction[t.cp, LIST["\007"], [DMFlash]];
AddInstruction[t.cp, LIST["\010"], [DMBackspace]];
AddInstruction[t.cp, LIST["\011"], [DMTab]];
AddInstruction[t.cp, LIST["\012"], [DMLinefeed]];
AddInstruction[t.cp, LIST["\013"], [DMTabSet, $clear]];
AddInstruction[t.cp,
LIST["\014",
NEW [DecodeRep ← [reg: col, base: 96, org: 0C, xor: 0140B, len: 1]],
NEW [DecodeRep ← [reg: line, base: 96, org: 0C, xor: 0140B, len: 1]] ],
[DMJumpCursor, $hv]];
AddInstruction[t.cp,
LIST["\014\014",
NEW [DecodeRep ← [reg: col, base: 96, org: 0C, xor: 0140B, len: 1]],
NEW [DecodeRep ← [reg: line, base: 96, org: 0C, xor: 0140B, len: 1]] ],
[DMJumpCursor, $hv]];
AddInstruction[t.cp, LIST["\015"], [DMCarriageReturn]];
AddInstruction[t.cp, LIST["\016"], [DMSetEmph, $boldOn]];
AddInstruction[t.cp, LIST["\017"], [DMSetEmph, $italicOn]];
AddInstruction[t.cp, LIST["\020"], [DMSetMode, $insdel]];
AddInstruction[t.cp, LIST["\027"], [DMClrTo, $eol]];
AddInstruction[t.cp, LIST["\030"], [DMCancel, $cancel]];
AddInstruction[t.cp, LIST["\014\030"], [DMCancel, $cancel]];
AddInstruction[t.cp, LIST["\031"], [DMTabSet, $set]];
AddInstruction[t.cp, LIST["\032"], [DMCtlZ]];
AddInstruction[t.cp, LIST["\033"], [Naught]];
AddInstruction[t.cp, LIST["\034"], [DMRight, flavor]];
AddInstruction[t.cp, LIST["\035"], [DMSetMode, $roll]];
AddInstruction[t.cp, LIST["\036"], [DMCancel, $masterClear]];
AddInstruction[t.cp, LIST["\014\036"], [DMCancel, $masterClear]];
AddInstruction[t.cp, LIST["\037"], [DMCancel, $eraseScreen]];
AddInstruction[t.cp, LIST["\014\037"], [DMCancel, $eraseScreen]];
AddInstruction[t.cp, LIST["\177"], [Naught]];
AddInstruction[t.cp, LIST["\200"], [Naught]];
AddInstruction[t.cp, LIST["\377"], [Naught]];
};
MakeDMDD:
PROC
RETURNS [t: Term] = {
t ← MakeDM[$Twenty500, FALSE];
t.det.lines ← 38;
};
DMPrint: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
dc.cd.class.TakeChar[
dc.cd,
dc.cps.chars[dc.cps.chars.length-1],
SELECT clientData
FROM
$waits => FALSE,
$Twenty500 => dc.cps.modes[insert],
ENDCASE => ERROR];
};
DMHome: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
Home[dc, clientData]};
DMFlash: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
Flash[dc, clientData]};
DMBackspace: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
IF dc.cps.modes[insert]
THEN dc.cd.class.DeleteChar[dc.cd]
ELSE {
IF dc.cd.col > 0 THEN dc.cd.class.CursorMove[dc.cd, 0, -1, TRUE];
};
};
DMTab: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
c: NAT;
dms.didCRLF ← FALSE;
FOR c ← dc.cd.col+1, c+1 WHILE c < dc.cd.det.columns AND NOT dms.colData[c].tabStopHere DO NULL ENDLOOP;
dc.cd.class.CursorMove[dc.cd, 0, c, FALSE, FALSE, TRUE];
};
DMLinefeed: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
IF dc.cps.modes[insert] THEN Line[dc, $ins] ELSE IF NOT dms.didCRLF THEN SkipCursor[dc, $down];
dms.didCRLF ← FALSE;
};
DMTabSet: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
set:
BOOL ←
SELECT clientData
FROM
$clear => FALSE,
$set => TRUE,
ENDCASE => ERROR;
dms.didCRLF ← FALSE;
dms.colData[dc.cd.col].tabStopHere ← set;
};
DMJumpCursor: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
JumpCursor[dc, clientData]};
DMCarriageReturn: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
CarriageReturn[dc, NIL];
SkipCursor[dc, $down];
dms.didCRLF ← TRUE;
};
DMSetEmph: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
SetEmph[dc, clientData]};
DMSetMode: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
SELECT clientData
FROM
$insdel => dc.cps.modes[insert] ← dc.cps.modes[delete] ← TRUE;
$roll => {det: DisplayDetails ← dc.cd.det;
det.scrolls ← TRUE;
dc.cd.class.ChangeDetails[dc.cd, det];
};
ENDCASE => ERROR;
};
DMCancel: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
clearRoll: BOOL ← FALSE;
clearScreen: BOOL ← TRUE;
clearTabs: BOOL ← FALSE;
dms.didCRLF ← FALSE;
SELECT clientData
FROM
$cancel => {clearRoll ← TRUE; clearScreen ← FALSE};
$masterClear => {clearTabs ← TRUE};
$eraseScreen => {};
ENDCASE => ERROR;
dc.cps.modes[insert] ← dc.cps.modes[delete] ← FALSE;
dc.cd.class.SetEmph[dc.cd, bold, FALSE];
dc.cd.class.SetEmph[dc.cd, italic, FALSE];
IF clearRoll
THEN {det: DisplayDetails ← dc.cd.det;
det.scrolls ← FALSE;
dc.cd.class.ChangeDetails[dc.cd, det]};
IF clearTabs
THEN {
FOR c: NAT IN [0 .. dms.cols) DO dms.colData[c].tabStopHere ← FALSE ENDLOOP;
};
IF clearScreen THEN ClearScreen[dc, clientData];
};
DMClrTo: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
ClrTo[dc, clientData]};
DMCtlZ: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
IF dc.cps.modes[insert] THEN Line[dc, $del] ELSE SkipCursor[dc, $up];
};
DMRight: ActionProc = {
dms: DMState ← NARROW[dc.cps.clientData];
dms.didCRLF ← FALSE;
IF dc.cps.modes[insert]
THEN {
dc.cd.class.TakeChar[dc.cd, ' , TRUE];
dc.cd.class.CursorMove[dc.cd, 0, -1, TRUE]}
ELSE SkipCursor[dc, $right];
};
RegTerm["dm2500", MakeDM[$Twenty500, FALSE]];
RegTerm["dm2500w", MakeDM[$Twenty500, TRUE]];
RegTerm["dmwaits", MakeDM[$waits, FALSE]];
RegTerm["dmdd", MakeDMDD[]];
}.