<> <> <> <> DIRECTORY CharDisplays, DisplayControllers, DisplayControllerSteps, Rope, TermProgs; <> 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[ Init: SELECT flavor FROM $waits => InitDMWaits, $Twenty500 => InitDM2500, ENDCASE => ERROR, bits: 7 ] ]]; FOR c: CHAR IN CHAR DO AddInstruction[t.cp, LIST[Rope.FromChar[c]], [DMPrint, flavor, TRUE]]; 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"], [DMBeep]]; 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]}; DMBeep: ActionProc = { dms: DMState _ NARROW[dc.cps.clientData]; dms.didCRLF _ FALSE; Beep[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, TRUE, 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, TRUE, TRUE]} ELSE SkipCursor[dc, $right]; }; RegTerm["dm2500", MakeDM[$Twenty500, FALSE]]; RegTerm["dm2500w", MakeDM[$Twenty500, TRUE]]; RegTerm["dmwaits", MakeDM[$waits, FALSE]]; RegTerm["dmdd", MakeDMDD[]]; }.