DIRECTORY Ascii USING [ BS, ControlA, ControlR, ControlQ, ControlV, ControlW, ControlX, CR, DEL, ESC, FF, SP, TAB], BitBlt USING [AlignedBBTable, BBptr, BBTableSpace, BITBLT], Environment USING [BitAddress], Format USING [ Date, Decimal, LongDecimal, LongNumber, LongOctal, LongSubStringItem, Number, Octal, SubString], Inline USING [BITAND], Process USING [Detach, SetPriority], Runtime USING [GetTableBase], SpecialSpace USING [ MakeGlobalFrameResident, --MakeGlobalFrameSwappable,-- MakeProcedureResident], String USING [ AppendChar, AppendLongNumber, AppendNumber, StringToLongNumber, StringToNumber, SubString], TerminalMultiplex USING [InputController, RegisterInputController, SelectTerminal], Time USING [Packed], TTY USING [DateFormat, Handle, LongSubString, NumberFormat], UserTerminal USING [ Coordinate, cursor, GetBitBltTable, keyboard, mouse, screenHeight, screenWidth, SetMousePosition, SetState, SetBackground, WaitForScanLine]; MockingbirdTTY: MONITOR LOCKS m USING m: POINTER TO MONITORLOCK IMPORTS BitBlt, Format, Inline, Process, Runtime, SpecialSpace, String, TerminalMultiplex, UserTerminal EXPORTS TTY = BEGIN OPEN Ascii, BitBlt; screenLock: MONITORLOCK; keyboardLock: MONITORLOCK; shuttingDown: BOOLEAN _ FALSE; shutDown: CONDITION _ [timeout: 0]; startingUp: BOOLEAN _ FALSE; startUp: CONDITION _ [timeout: 0]; noTrack: CARDINAL _ 0; Initialize: PROCEDURE = { IF ~TerminalMultiplex.SelectTerminal[alternate] THEN ERROR; TerminalMultiplex.RegisterInputController[InputController]; InputController[enable]}; InputController: TerminalMultiplex.InputController = { SELECT action FROM enable => {IF useCount = 0 THEN TurnOnTerminal[]; StartTerminal[]}; disable => TurnOffTerminal[]; ENDCASE}; TurnOnTerminal: PROCEDURE = { TurnOnInternal: ENTRY PROC [m: POINTER TO MONITORLOCK] = { IF ~font.newStyle OR font.indexed OR font.min NOT IN [0C..177C] OR font.max+1 NOT IN [0C..177C] THEN ERROR; WHILE shuttingDown DO WAIT shutDown ENDLOOP; SpecialSpace.MakeProcedureResident[ProcessKeyboard]; SpecialSpace.MakeGlobalFrameResident[MockingbirdTTY]; CDT _ FALSE; echo _ TRUE; in _ out _ 0; [] _ UserTerminal.SetState[on]; [] _ UserTerminal.SetBackground[white]; ClearScreen[]; -- to force init of bbPtr (since may have changed) Process.Detach[FORK ProcessKeyboard]}; TurnOnInternal[@keyboardLock]}; StartTerminal: PROCEDURE = { StartInternal: ENTRY PROC [m: POINTER TO MONITORLOCK] = { startingUp _ TRUE; BROADCAST startUp}; StartInternal[@keyboardLock]}; TurnOffTerminal: PROCEDURE = { TurnOffInternal: ENTRY PROC [m: POINTER TO MONITORLOCK] = { shuttingDown _ TRUE; WHILE shuttingDown DO WAIT shutDown ENDLOOP}; TurnOffInternal[@keyboardLock]}; EnableCursorTracking: PUBLIC PROCEDURE = { EnableInternal: ENTRY PROC [m: POINTER TO MONITORLOCK] = { IF (noTrack _ noTrack - 1) = 0 THEN doBlink _ TRUE}; EnableInternal[@keyboardLock]}; DisableCursorTracking: PUBLIC PROCEDURE = { DisableInternal: ENTRY PROC [m: POINTER TO MONITORLOCK] = { IF (noTrack _ noTrack + 1) ~= 0 THEN doBlink _ FALSE}; DisableInternal[@keyboardLock]}; font: LONG POINTER TO MACHINE DEPENDENT RECORD [ newStyle(0:0..0): BOOLEAN, indexed(0:1..1): BOOLEAN, fixed(0:2..2): BOOLEAN, kerned(0:3..3): BOOLEAN, pad(0:4..15): [0..7777B], min(1): CHARACTER, -- limits of chars in font max(2): CHARACTER, -- limits of chars in font maxwidth(3): CARDINAL, length(4): CARDINAL, ascent(5): CARDINAL, descent(6): CARDINAL, xoffset(7): CARDINAL, raster(8): CARDINAL, chars(9:0..63): SELECT OVERLAID * FROM hasBoundingBox => [ boundingBox(9:0..63): RECORD [FontBBox, FontBBoy, FontBBdx, FontBBDy: INTEGER], BBBitmap(13): ARRAY [0..0) OF WORD], noBoundingBox => [bitmap(9): ARRAY [0..0) OF WORD], ENDCASE] = GetFont[]; bitmap: LONG POINTER = IF font.kerned THEN @font.BBBitmap ELSE @font.bitmap; xInSegment: LONG POINTER TO ARRAY CHARACTER [0C..0C) OF CARDINAL = bitmap + font.raster*FontHeight[] - (font.min-0C); height: INTEGER[0..LAST[INTEGER]] = FontHeight[]; CharWidth: PROC [char: CHARACTER] RETURNS [[0..LAST[INTEGER]]] = INLINE BEGIN IF char NOT IN [font.min..font.max] THEN char _ font.max+1; RETURN[xInSegment[char+1] - xInSegment[char]] END; FontHeight: PROC RETURNS [[0..LAST[INTEGER]]] = INLINE {RETURN[font.ascent+font.descent]}; downUp: TYPE = {down, up}; keycount: CARDINAL = 80; -- must be 0 mod 16 Keyarray: TYPE = MACHINE DEPENDENT RECORD [SELECT OVERLAID * FROM b => [bits: PACKED ARRAY [0..keycount) OF downUp], wds => [wds: ARRAY [0..keycount/16) OF WORD], ENDCASE]; KeyItem: TYPE = RECORD [ Letter: BOOLEAN, ShiftCode: CHARACTER [0C..177C], NormalCode: CHARACTER [0C..377C]]; ctrl: CARDINAL = 52; leftShift: CARDINAL = 57; shiftLock: CARDINAL = 72; rightShift: CARDINAL = 76; spare3: CARDINAL = 77; KeyTable: ARRAY [16..keycount) OF KeyItem = [ [FALSE, 45C, 65C], -- %,5 [FALSE, 44C, 64C], -- $,4 [FALSE, 176C, 66C], -- ~,6 [TRUE, 105C, 145C], -- E [FALSE, 46C, 67C], -- &,7 [TRUE, 104C, 144C], -- D [TRUE, 125C, 165C], -- U [TRUE, 126C, 166C], -- V [FALSE, 51C, 60C], -- ),0 [TRUE, 113C, 153C], -- K [FALSE, 30C, 55C], -- `,- [TRUE, 120C, 160C], -- P [FALSE, 77C, 57C], -- ?,/ [FALSE, 174C, 134C], -- |,\ [FALSE, 12C, 12C], -- LF [FALSE, 10C, 10C], -- BS [FALSE, 43C, 63C], -- #,3 [FALSE, 100C, 62C], -- @,2 [TRUE, 127C, 167C], -- W [TRUE, 121C, 161C], -- Q [TRUE, 123C, 163C], -- S [TRUE, 101C, 141C], -- A [FALSE, 50C, 71C], -- (,9 [TRUE, 111C, 151C], -- I [TRUE, 130C, 170C], -- X [TRUE, 117C, 157C], -- O [TRUE, 114C, 154C], -- L [FALSE, 74C, 54C], -- <,, [FALSE, 42C, 47C], -- ",' [FALSE, 175C, 135C], --},] [FALSE, 0C, 0C], -- SPARE2 [FALSE, 0C, 0C], -- SPARE1 [FALSE, 41C, 61C], -- !,1 [FALSE, 33C, 33C], -- ESCAPE [FALSE, 11C, 11C], -- TAB [TRUE, 106C, 146C], -- F [FALSE, 0C, 0C], -- CONTROL [TRUE, 103C, 143C], -- C [TRUE, 112C, 152C], -- J [TRUE, 102C, 142C], -- B [TRUE, 132C, 172C], -- Z [FALSE, 0C, 0C], -- SHIFT [FALSE, 76C, 56C], -- >,. [FALSE, 72C, 73C], -- :,; [FALSE, 15C, 15C], -- CR [FALSE, 136C, 137C], -- ^,_ [FALSE, 177C, 177C], -- DEL [FALSE, 0C, 0C], -- NOT USED (FL3) [TRUE, 122C, 162C], -- R [TRUE, 124C, 164C], -- T [TRUE, 107C, 147C], -- G [TRUE, 131C, 171C], -- Y [TRUE, 110C, 150C], -- H [FALSE, 52C, 70C], -- *,8 [TRUE, 116C, 156C], -- N [TRUE, 115C, 155C], -- M [FALSE, 0C, 0C], -- LOCK [FALSE, 40C, 40C], -- SPACE [FALSE, 173C, 133C], -- {,[ [FALSE, 53C, 75C], -- +,= [FALSE, 0C, 0C], -- Shift [FALSE, 0C, 0C], -- Spare3 [FALSE, 0C, 0C], -- not user (FR4) [FALSE, 0C, 0C]]; -- not user (FR5) useCount: CARDINAL _ 0; Create: PUBLIC PROC [STRING] RETURNS [TTY.Handle] = BEGIN useCount _ useCount + 1; RETURN[LOOPHOLE[100000B]] END; Destroy: PUBLIC PROC [TTY.Handle] = BEGIN useCount _ useCount - 1; END; CDT: BOOLEAN; charactersAvailable: CONDITION; echo: BOOLEAN; CtrlChar: PROC [c: CHARACTER] RETURNS [CHARACTER] = INLINE {RETURN[LOOPHOLE[Inline.BITAND[c, 37B]]]}; ProcessKeyboard: PROC = BEGIN old, new: Keyarray; kp: LONG POINTER TO Keyarray = LOOPHOLE[UserTerminal.keyboard]; blinkCount: CARDINAL _ 33; GoAway: ENTRY PROC [m: POINTER TO MONITORLOCK] RETURNS [BOOLEAN] = INLINE { IF shuttingDown THEN {shuttingDown _ FALSE; BROADCAST shutDown; RETURN[TRUE]} ELSE RETURN[FALSE]}; WaitStart: ENTRY PROC [m: POINTER TO MONITORLOCK] = INLINE { WHILE ~startingUp DO WAIT startUp; ENDLOOP}; Process.SetPriority[6]; new _ kp^; WHILE TRUE DO Brdcst: ENTRY PROC [m: POINTER TO MONITORLOCK] = INLINE {BROADCAST charactersAvailable}; charsSeen: BOOLEAN _ FALSE; IF GoAway[@keyboardLock] THEN WaitStart[@keyboardLock]; startingUp _ FALSE; old _ new; UserTerminal.WaitForScanLine[0]; new _ kp^; TrackCursor[@keyboardLock]; IF (blinkCount_blinkCount-1) = 0 THEN {BlinkCursor[]; blinkCount _ 34}; FOR i: CARDINAL IN [1..keycount/16) DO IF old.wds[i]#new.wds[i] THEN FOR j: CARDINAL IN [i*16..(i+1)*16) DO char: CHARACTER; entry: KeyItem; IF new.bits[j]=up OR old.bits[j]=down THEN LOOP; IF (char _ (entry_KeyTable[j]).NormalCode)#0C THEN BEGIN SELECT TRUE FROM new.bits[ctrl]=down => IF char=177C THEN {CDT _ TRUE; LOOP} ELSE char _ CtrlChar[char]; new.bits[leftShift]=down, new.bits[rightShift]=down => char _ entry.ShiftCode; new.bits[shiftLock]=down AND entry.Letter => char _ entry.ShiftCode; ENDCASE; StuffBuffer[char, @keyboardLock]; charsSeen _ TRUE END; ENDLOOP ENDLOOP; IF charsSeen THEN Brdcst[@keyboardLock]; ENDLOOP END; SetEcho: PUBLIC PROC [h: TTY.Handle, new: BOOLEAN] RETURNS [old: BOOLEAN] = BEGIN SetEntry: ENTRY PROC [m: POINTER TO MONITORLOCK] = INLINE {old _ echo; echo _ new}; SetEntry[@keyboardLock] END; TrackCursor: ENTRY PROC [m: POINTER TO MONITORLOCK] = INLINE BEGIN mouse: UserTerminal.Coordinate _ UserTerminal.mouse^; IF noTrack > 0 THEN RETURN; mouse.x _ MIN[MAX[0, mouse.x], UserTerminal.screenWidth]; mouse.y _ MIN[MAX[0, mouse.y], UserTerminal.screenHeight]; UserTerminal.cursor^ _ mouse; UserTerminal.SetMousePosition[mouse] END; in, out: CARDINAL; buffer: PACKED ARRAY [0..50) OF CHARACTER; CharsAvailable: PUBLIC PROC [h: TTY.Handle] RETURNS [CARDINAL] = BEGIN P: ENTRY PROC [m: POINTER TO MONITORLOCK] RETURNS [CARDINAL] = INLINE {RETURN[IF in>=out THEN in-out ELSE in+LENGTH[buffer]-out]}; RETURN[P[@keyboardLock]] END; GetChar: PUBLIC PROC [h: TTY.Handle] RETURNS [c: CHARACTER] = BEGIN P: ENTRY PROC [m: POINTER TO MONITORLOCK] = INLINE BEGIN WHILE in=out DO WAIT charactersAvailable ENDLOOP; c _ buffer[out]; IF (out_out+1) = LENGTH[buffer] THEN out _ 0; END; P[@keyboardLock] END; PutBackChar: PUBLIC PROC [h: TTY.Handle, c: CHARACTER] = BEGIN P: ENTRY PROC [m: POINTER TO MONITORLOCK] = INLINE BEGIN newout: CARDINAL = IF out=0 THEN LENGTH[buffer]-1 ELSE out-1; IF newout#in THEN {buffer[out _ newout] _ c; BROADCAST charactersAvailable}; END; P[@keyboardLock] END; ResetUserAbort: PUBLIC PROC = BEGIN CDResetEntry: ENTRY PROC [m: POINTER TO MONITORLOCK] = INLINE {CDT _ FALSE}; CDResetEntry[@keyboardLock] END; StuffBuffer: ENTRY PROC [c: CHARACTER, m: POINTER TO MONITORLOCK] = INLINE BEGIN newin: CARDINAL; IF (newin_in+1) = LENGTH[buffer] THEN newin _ 0; IF newin#out THEN {buffer[in] _ c; in _ newin}; END; UserAbort: PUBLIC PROC RETURNS [BOOLEAN] = {RETURN[CDT]}; BBTable: BBTableSpace; bbPtr: BBptr = AlignedBBTable[@BBTable]; charPos, line, nCharPos, nLines: CARDINAL; firstLine, thisLine: Environment.BitAddress; bitsPerTextLine: CARDINAL; -- = screenWidth*font.height doBlink: BOOLEAN _ FALSE; GetBitAddress: PROC [p: LONG POINTER, o: CARDINAL] RETURNS [Environment.BitAddress] = {RETURN[[p+o/16, 0, o MOD 16]]}; PutBlanks: PUBLIC PROC [h: TTY.Handle, n: CARDINAL] = {THROUGH [0..n) DO PutChar[h, ' ] ENDLOOP}; BlinkCursor: PUBLIC PROC = BEGIN BlinkCursorEntry: ENTRY PROC [m: POINTER TO MONITORLOCK] = BEGIN blinker: CARDINAL _ 60000B; IF doBlink THEN BEGIN bbPtr.src _ [@blinker, 0, 0]; bbPtr.srcDesc _ [gray[[0, 0, 0, 0]]]; bbPtr.flags _ [gray: TRUE, dstFunc: xor]; BITBLT[bbPtr]; bbPtr.srcDesc _ [srcBpl[font.raster*16]]; bbPtr.flags _ []; END; END; IF doBlink THEN BlinkCursorEntry[@screenLock]; END; NewLine: PUBLIC PROC [TTY.Handle] RETURNS [BOOLEAN] = {RETURN[charPos=0]}; PutChar: PUBLIC PROC [h: TTY.Handle, c: CHARACTER] = BEGIN PutCharEntry: ENTRY PROC [m: POINTER TO MONITORLOCK] = INLINE {doBlink _ FALSE; ClearThisChar[]; DisplayChar[c]; doBlink _ TRUE}; END; PutLongString: PUBLIC PROC [h: TTY.Handle, s: LONG STRING] = {IF s#NIL THEN FOR i: CARDINAL IN [0..s.length) DO PutChar[h, s[i]] ENDLOOP}; PutString: PUBLIC PROC [h: TTY.Handle, s: STRING] = {PutLongString[h, s]}; Backup: INTERNAL PROC = BEGIN t: CARDINAL = bbPtr.dst.bit+16-font.maxwidth; IF charPos=0 THEN RETURN; charPos _ charPos - 1; bbPtr.dst.word _ bbPtr.dst.word + t/16 - 1; bbPtr.dst.bit _ t MOD 16; END; ClearScreen: INTERNAL PROC = BEGIN zero: CARDINAL _ 0; bbPtr^ _ UserTerminal.GetBitBltTable[]; bitsPerTextLine _ bbPtr.dstBpl*height; firstLine _ thisLine _ GetBitAddress[ bbPtr.dst.word, bbPtr.dst.bit+8+8*bbPtr.dstBpl]; charPos _ 0; line _ 1; nCharPos _ (bbPtr.width-16)/font.maxwidth; nLines _ (bbPtr.height-16)/height; bbPtr.src _ [@zero, 0, 0]; bbPtr.srcDesc _ [gray[[0, 0, 0, 0]]]; bbPtr.flags _ [gray: TRUE]; BITBLT[bbPtr]; bbPtr.dst _ firstLine; bbPtr.srcDesc _ [srcBpl[font.raster*16]]; bbPtr.height _ height; bbPtr.width _ font.maxwidth; bbPtr.flags _ []; END; ClearThisChar: INTERNAL PROC = BEGIN zero: CARDINAL _ 0; bbPtr.src _ [@zero, 0, 0]; bbPtr.srcDesc _ [gray[[0, 0, 0, 0]]]; bbPtr.flags _ [gray: TRUE]; BITBLT[bbPtr]; bbPtr.srcDesc _ [srcBpl[font.raster*16]]; bbPtr.flags _ []; END; DisplayChar: INTERNAL PROC [c: CHARACTER] = BEGIN SELECT c FROM IN (SP..'~] => BEGIN IF c NOT IN [font.min..font.max] THEN c _ font.max+1; bbPtr.src _ GetBitAddress[bitmap, xInSegment[c]]; BitBlt.BITBLT[bbPtr]; END; SP => NULL; CR => {Newline[]; RETURN}; BS => {Backup[]; ClearThisChar[]; RETURN}; TAB => {UNTIL (charPos MOD 8)=0 DO DisplayChar[SP] ENDLOOP; RETURN}; FF => {ClearScreen[]; RETURN}; IN [0C..SP) => {DisplayChar['^]; DisplayChar[c+('A-1C)]; RETURN}; ENDCASE => RETURN; IF (charPos_charPos+1)>=nCharPos THEN Newline[] ELSE bbPtr.dst _ GetBitAddress[bbPtr.dst.word, bbPtr.dst.bit+font.maxwidth]; END; Newline: INTERNAL PROC = BEGIN IF line SIGNAL Rubout; ControlA, BS => -- backspace IF s.length > 0 THEN {IF echo THEN PutChar[h, BS]; s.length _ s.length - 1}; ControlW, ControlQ => -- backword BEGIN state: {ti, v, li} _ ti; FOR i: CARDINAL DECREASING IN [0..s.length) DO SELECT s[i] FROM IN ['A..'Z], IN ['a..'z], IN ['0..'9] => IF state = ti THEN state _ v; ENDCASE => IF state = v THEN state _ li; IF state = li THEN GO TO Done; IF echo THEN PutChar[h, BS]; REPEAT Done => s.length _ i + 1; FINISHED => s.length _ 0; ENDLOOP; END; ControlX => -- back everything BEGIN IF echo THEN FOR i: CARDINAL IN [0..s.length) DO PutChar[h, BS] ENDLOOP; s.length _ 0; END; ControlR => -- refresh-- IF echo THEN {PutChar[h, CR]; PutString[h, s]}; ControlV => -- dont parse next char BEGIN WHILE s.length >= s.maxlength DO s _ SIGNAL LineOverflow[s] ENDLOOP; s[s.length] _ c _ GetChar[h]; s.length _ s.length + 1; IF echo THEN PutChar[h, c] END; ENDCASE => BEGIN WHILE s.length >= s.maxlength DO s _ SIGNAL LineOverflow[s] ENDLOOP; s[s.length] _ c; s.length _ s.length + 1; IF echo THEN PutChar[h, c]; END; c _ GetChar[h]; ENDLOOP; END; IsAtom: PROC [c: CHARACTER] RETURNS [BOOLEAN] = {RETURN[c = SP OR c = CR]}; IsCR: PROC [c: CHARACTER] RETURNS [BOOLEAN] = {RETURN[c = CR]}; OutString: PROC [s: STRING] = {PutLongString[LOOPHOLE[0], s]}; PutDate: PUBLIC PROC [h: TTY.Handle, gmt: Time.Packed, format: TTY.DateFormat] = {Format.Date[gmt, format, OutString]}; PutDecimal: PUBLIC PROC [h: TTY.Handle, n: INTEGER] = {Format.Decimal[n, OutString]}; PutLongDecimal: PUBLIC PROC [h: TTY.Handle, n: LONG INTEGER] = {Format.LongDecimal[n, OutString]}; PutLongNumber: PUBLIC PROC [h: TTY.Handle, n: LONG UNSPECIFIED, format: TTY.NumberFormat] = {Format.LongNumber[n, format, OutString]}; PutLongOctal: PUBLIC PROC [h: TTY.Handle, n: LONG UNSPECIFIED] = {Format.LongOctal[n, OutString]}; PutNumber: PUBLIC PROC [h: TTY.Handle, n: UNSPECIFIED, format: TTY.NumberFormat] = {Format.Number[n, format, OutString]}; PutOctal: PUBLIC PROC [h: TTY.Handle, n: UNSPECIFIED] = {Format.Octal[n, OutString]}; PutLongSubString: PUBLIC PROC [h: TTY.Handle, ss: TTY.LongSubString] = {Format.LongSubStringItem[ss, OutString]}; PutSubString: PUBLIC PROC [h: TTY.Handle, ss: String.SubString] = {Format.SubString[ss, OutString]}; Initialize[]; END. MockingbirdTTY.mesa Derived from MockingbirdTTY.mesa last edited by Forrest January 6, 1981 7:28 PM last edited by Levin on 14-Apr-82 18:02:39 last edited by McGregor on April 22, 1982 4:23 pm last gutted by Maxwell on May 20, 1982 10:02 am This module also implements non-basic tty features (see end of code). if these are not needed, String and Format may be left unbound Pilot doesn't do this right: SpecialSpace.MakeGlobalFrameSwappable[MockingbirdTTY]; SpecialSpace.MakeProcedureSwappable[ProcessKeyboard]; [] _ UserTerminal.SetState[disconnected]}; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FONT Definitions and variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Keyboard Definitions and Constants ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Keyboard Info Index [0..15] mouse, etc Index [16..31] Index [32..47] Index [48..63] Index [64..79] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Simple TTY Procedures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Keyboard Implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTERNAL PROCEDURES ENTRY PROCEDURES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Keyboard RingBuffer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ perhaps this should be monitored, but since it is a snapshot... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DISPLAY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTERNAL DISPLAY PROCEDURES ENTRY DISPLAY PROCEDURES PutCharEntry[@screenLock]; INTERNAL DISPLAY PROCEDURES set up standard arguments for character painting bbPtr.dstBpl set bbPtr.src set when proc called ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ non-basic tty features ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ text to be backed up is of the form ...
  • , the and are to be removed. extended output procedures Ê"3˜Jšœ™Jšœ!™!Jšœ0™0Jšœ*™*Jšœ1™1Jšœ/™/J˜J˜JšœE™EJšœ>™>J˜šÏk ˜ šœœ˜ Jšœ>œœ˜HJšœœœœ˜—Jšœœ'œ˜;Jšœ œ˜šœœ˜J˜EJ˜—Jšœœœ˜Jšœœ˜$Jšœœ˜šœ œ˜JšœÏc˜6J˜—šœœ˜J˜+J˜/—Jšœœ<˜SJšœœ ˜Jšœœ3˜<šœ œ˜J˜BJ˜7J˜J˜——šœ˜Jš œœœœ ˜'š˜J˜7J˜'—Jšœœ˜ J˜—Jšœœ˜J˜Jšœ œ˜Jšœ œ˜J˜Jšœœœ˜Jšœ œ˜#Jšœ œœ˜Jšœ œ˜"J˜Jšœ œ˜J˜šÏn œ œ˜Jšœ.œœ˜;J˜;J˜J˜—˜6šœ˜Jšœ œœ$˜CJ˜Jšœ˜ J˜——šŸœ œ˜š Ÿœœœœœ œ˜:š œœœ œœ ˜@Jš œ œœ œœ˜+—Jšœœœ œ˜,J˜4J˜5Jšœœ˜ Jšœœ˜ J˜ J˜J˜'Jšœž2˜AJšœœ˜&—J˜J˜—šŸ œ œ˜š Ÿ œœœœœ œ˜9Jšœ œ œ ˜&—J˜J˜—šŸœ œ˜š Ÿœœœœœ œ˜;Jšœœ˜Jšœœœ œ˜-JšœS™SJšœ5™5Jšœ*™*—J˜ J˜—šŸœœ œ˜*š Ÿœœœœœ œ˜:Jšœœ œ˜4—J˜J˜—šŸœœ œ˜+š Ÿœœœœœ œ˜;Jšœœ œ˜6—J˜ J˜—Jšœ%™%Jšœ™Jšœ%™%š œœœœœ œœ˜0Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜J˜Jšœ œž˜/Jšœ œž˜/Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜šœœœ˜&˜Jšœœ*œ˜OJšœœœœ˜$—Jšœœœœ˜3Jšœ˜J˜——Jš œœœœ œœ˜Lšœ œœœœ œ œœ˜BJ˜2—Jšœœœœ˜1J˜š Ÿ œœ œœœœ˜@Jšœ˜ Jšœœœœ˜;Jšœ'˜-Jšœ˜J˜—JšŸ œœœœœœœ˜ZJ˜Jšœ%™%Jšœ"™"Jšœ%™%Jšœœ˜Jšœ œž˜,šœ œœ œœœœ˜AJšœ œœœ ˜2Jšœ œœœ˜-Jšœ˜ J˜—šœ œœ˜Jšœœ œ œ ˜TJ˜—Jšœ ™ Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜J˜šœ œœ ˜-Jšœ™Jšœ™Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœ™Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž ˜Jšœœž ˜Jšœ™Jšœœž˜Jšœœž ˜Jšœœž˜Jšœœž˜Jšœœž ˜ Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜'Jšœ™Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž˜Jšœœž ˜Jšœœž˜'Jšœœž˜(J˜—Jšœ%™%Jšœ™Jšœ%™%J˜Jšœ œ˜J˜š Ÿœœœœœœ ˜4Jš˜J˜Jšœœ ˜Jšœ˜J˜—šŸœœœœ ˜$Jš˜J˜Jšœ˜J˜—Jšœ%™%Jšœ™Jšœ%™%J˜Jšœœ˜ Jšœ œ˜Jšœœ˜J˜Jšœ™JšŸœœ œœ œœœœœ ˜eJ˜Jšœ™šŸœœ˜Jš˜J˜Jš œœœœ œ˜?Jšœ œ˜šŸœœœœœ œœœœ˜Kšœ˜Jš œœ œ œœ˜=Jšœœœ˜——šŸ œœœœœ œœ˜Jš œœœ œœœ˜C—Jšœœ˜Jšœ˜J˜—š Ÿœœœœ œ œ˜=Jš˜š œœœœœ œ˜+Jšœ˜ Jšœœœœ˜1J˜Jšœœ œ ˜-Jšœ˜—Jšœ˜Jšœ˜J˜—š Ÿ œœœœ œ˜8Jš˜š œœœœœ œ˜+Jšœ˜ Jš œœœœœ œ˜=Jšœ œ œ˜LJšœ˜—Jšœ˜Jšœ˜J˜—šŸœœœ˜Jš˜JšŸ œœœœœ œœœœ˜LJ˜Jšœ˜J˜—šŸ œœœ œœœ œ˜CJšœ˜ Jšœœ˜Jšœœ œ ˜0Jšœ œ˜/Jšœ˜J˜—Jšœ?™?JšŸ œœœœœœœ˜9J˜Jšœ%™%Jšœ™Jšœ%™%J˜J˜(Jšœ!œ˜*J˜,Jšœœž˜8Jšœ œœ˜J˜Jšœ™š Ÿ œœœœœœ˜UJšœœœ˜ J˜—š Ÿ œœœœ œ˜5Jšœœœœ˜+J˜—Jšœ™šŸ œœœ˜Jš˜š Ÿœœœœœ œ˜:Jš˜Jšœ œ ˜šœ ˜Jš˜J˜J˜%Jšœœ˜)Jšœ˜J˜)J˜Jšœ˜—Jšœ˜—Jšœ œ˜.Jšœ˜J˜—JšŸœœœœ œœœ ˜JJ˜š Ÿœœœœ œ˜4Jš˜š Ÿ œœœœœ œ˜6Jšœ œ-œ˜J—Jšœ™Jšœ˜J˜—š Ÿ œœœœ œœ˜J˜š Ÿœœœœ#œ˜PJ˜&J˜—Jš Ÿ œœœœ œ#˜UJ˜š Ÿœœœœ œœ˜>J˜#J˜—šŸ œœœœ œ œ œ˜[J˜*J˜—š Ÿ œœœœ œ œ˜@J˜!J˜—š Ÿ œœœœ œ œ˜RJ˜&J˜—Jš Ÿœœœœ œ!˜UJ˜š Ÿœœœœ œ˜FJ˜*J˜—šŸ œœœœ ˜AJ˜"J˜——J˜ J˜Jšœ˜J˜—…—g€Ï