Introduction
EPO provides module Texts
which hard-wires the serial device that writes text to the Astrobe terminal. The Texts.Writer
parameter that is passed to all output procedures is kept for compatibility, but not actually used.
Texts.Write
is the basis for all text output:
PROCEDURE Write*(VAR W: Writer; ch: CHAR)
CONST data = -56; stat = -52;
BEGIN
REPEAT UNTIL SYSTEM.BIT(stat, 1);
SYSTEM.PUT(data, ORD(ch))
END Write;
Texts.Writer Reborn
To be able to use Texts
for formatted output to other devices, for example additional serial terminals or LCD screens, it is extended and changed as follows:
TYPE
TextDevice* = POINTER TO TextDeviceDesc;
TextDeviceDesc* = RECORD END;
PutCharProc* = PROCEDURE(dev: TextDevice; ch: CHAR);
Writer* = RECORD
device: TextDevice;
putChar: PutCharProc
END;
PROCEDURE OpenWriter(VAR W: Writer; dev: TextDevice; pcp: PutCharProc)
BEGIN
W.device := dev;
W.putChar := pcp
END OpenWriter;
PROCEDURE Write(VAR W: Writer; ch: CHAR);
BEGIN
W.putChar(W.device, ch)
END Write;
Now any device that extends Texts.TextDevice
can be “plugged” into a Texts.Writer
, and all output procedures of Texts
can be used to write formatted text to that device.
For example, the RS232 device is defined like so in module RS232dev
:
TYPE
Device* = POINTER TO DeviceDesc;
DeviceDesc* = RECORD(Texts.TextDeviceDesc)
(* ... *)
END;
With RS232dev.Dev0
being the actual serial device connected to the Astrobe terminal, and RS232.PutChar
the single character output procedure over this serial line, the following code makes a corresponding Texts.Writer
available to other modules, such as System
.
VAR
W*: Texts.Writer;
dev: RS232dev.Device;
NEW(dev); RS232dev.Init(dev, RS232dev.Dev0);
Texts.OpenWriter(W, dev, RS232.PutChar)
See Console.
Similarly, the driver for LC displays uses this structure:
TYPE
Display* = POINTER TO DisplayDesc;
DisplayDesc* = RECORD(Texts.TextDeviceDesc)
W*: Texts.Writer;
(* ... *)
END;
Hence Texts
can be used to output to the LC display.
Other Changes
Texts.WriteClock
is modified to print in this format:
yyyy-mm-dd hh:mm:ss
Possible Improvements
The current implementation relies on the single character output procedure Texts.Write
for all output. This could be improved as follows:
- Filling the output buffer could be more efficient if the multi-character output procedures of the underlying serial driver could be used, eg.
RS232b.PutBytes
. - Busy-waiting when the output buffer is full could be avoided if the outputting process could yield control to other processes until output is possible again when the buffer is emptied. While this could be achieved in each outputting process itself, it should be solved on the serial driver level once and for all.