!c
glass,plank:2,glass,lime_lumar,red_doped_wafer,glass,ribbon_cable,plank=monitor;

Overview

The monitor is a Redbus slave device that provides the ability to display text and simple graphical characters, as well as read input from the player’s keyboard. A monitor must be placed in the world and attached to a computer, either by placing it adjacent to the computer or by connecting the two with ribbon cable. To interact with the monitor, right-click it. To close the monitor, press Escape. The block texture in the world is purely stylistic and does not reflect the text displayed on the monitor; the only way to see the text on the monitor is to open it.

The screen is character-based, not pixel-based. It provides a rectangular array of characters with 80 columns and 50 rows. Coordinates are measured with row 0 at the top of the monitor and column 0 at the left.

The keyboard is not shown onscreen; rather, it accepts input from the player’s physical keyboard. Keys are delivered by the hardware into a 16-byte circular buffer where they can be retrieved by a computer; if the circular buffer becomes full (defined as containing 15 bytes), the keyboard stops accepting input and additional keystrokes are discarded.

Redbus interface

A newly-placed monitor has Redbus slave ID 1; this can be changed by shift+right-clicking the monitor with a screwdriver in hand.

The monitor exposes the following memory locations over Redbus:
Offset
Length
Function
0x00
1
Framebuffer access row
0x01
1
Cursor X position
0x02
1
Cursor Y position
0x03
1
Cursor style
0x04
1
Keyboard buffer tail pointer
0x05
1
Keyboard buffer head pointer
0x06
1
Keyboard buffer data window
0x07
1
Blitter command
0x08
1
Blitter source rectangle X or fill character
0x09
1
Blitter source rectangle Y
0x0A
1
Blitter destination rectangle X
0x0B
1
Blitter destination rectangle Y
0x0C
1
Blitter rectangle width
0x0D
1
Blitter rectangle height
0x10
80
Framebuffer data window

Reading the keyboard

The keyboard is managed through three registers, 0x04, 0x05, and 0x06. The monitor has a built-in 16-byte circular buffer with head and tail pointers. When the monitor is constructed, the head and tail pointers are both zero. The buffer is empty when [Head] = [Tail], and full when [Head] + 1 = [Tail] (mod 16). When a key is typed, the hardware stores the key code in the circular buffer at location [Head], then sets [Head] to [Head] + 1 (mod 16). The [Data] location always contains the value at location [Tail] in the buffer; to process a keystroke, after checking that the buffer is nonempty, software should first copy the key code from [Data] into internal storage, then increment [Tail] to consume the keystroke and clear space in the buffer. Software does not have to reduce [Tail] mod 16 as this is done in hardware.

On a test with a standard US-layout PC (non-Mac) keyboard, all the printable characters were reported normally (including shifted characters) as their ASCII codes, Ctrl plus a letter key reported values 1 through 26 (as was often the case in DOS and is still the case for many such characters under Linux in some situations), Enter reported as 13, Backspace reported as 8, and Delete reported as 127. Other keys (such as arrow keys, function keys, cursor control keys, PrtScr/SysRq, and Pause/Break) did not report at all. Other modifier combinations with otherwise-reporting keys generally did not change the reports described earlier in this paragraph; for example, Alt+A was reported as 97, the same as unmodified A, and Ctrl+1 was reported as 49, the same as 1.

Controlling the cursor

The monitor can display a cursor in one position onscreen. The position of the cursor is controlled by setting the [X] and [Y] registers. The [Style] register controls what type of cursor is displayed:
Value
Function
0
Target character cell blinks between normal and reverse video
1
Target character cell is shown in reverse video
2
Target character cell blinks between normal and reverse video
3
Cursor is not displayed

Reading and writing the framebuffer

Placing characters on the screen, or reading which characters are already on the screen, is done in two steps. First, the software selects which line, from 0 to 49, it wishes to access, by writing that number into [Framebuffer access row]. Once this is done, [Framebuffer data window] contains the ASCII codes of the characters on that line. No extended ASCII codes are provided in RedPower Control; instead, if the most significant bit of a byte in the framebuffer is set, that character is rendered in reverse video (black on green, instead of green on black). Thus writing 0x41 to the framebuffer will place an "A" on the screen, while writing 0xC1 (0x41 OR 0x80) will place an inverted "A".

The following is a screenshot showing the characters rendered by all 256 possible byte values (shown here in hexadecimal), as of RedPower 2 prerelease 6:
charset.png

Using the blitter

The monitor includes a hardware blitter, a device capable of asynchronously manipulating large blocks of character cells while the CPU is doing other work. To use the blitter, first program the parameters of the operation to be performed into the [Source X] or [Fill Character], [Source Y], [Destination X], [Destination Y], [Width], and [Height] registers, then write the command number for the desired operation into [Command]. Blitting commands do not execute immediately; once a command has finished executing, the blitter changes the [Command] register to 0x00. Because blitting commands take at least one world tick to perform, using the blitter to manipulate small regions of the screen is probably counterproductive.

The blitter understands three commands, detailed below:
Command
Function
0x01
Fill
0x02
Invert
0x03
Copy

Fill

The fill command operates on the rectangle defined by [Destination X], [Destination Y], [Width], and [Height]. The blitter replaces every character in that rectangle with the value in [Fill Character]. This may be useful to clear the screen, by filling with character 0x20 (space).

Invert

The invert command operates on the rectangle defined by [Destination X], [Destination Y], [Width], and [Height]. The blitter flips the most significant bit of every character in the rectangle, thus turning all normal characters into reverse video and vice versa.

Copy

The copy command operates on a source rectangle defined by [Source X], [Source Y], [Width], and [Height]; and a destination rectangle defined by [Destination X], [Destination Y], [Width], and [Height]. The blitter copies the contents of the source rectangle and stores those characters in the destination rectangle.

Copying is not performed as an atomic block copy; rather, it is as though individual characters were copied one by one, always from left to right then from top to bottom of the rectangle. This may cause unexpected results if the source and destination rectangles overlap! Moving text up, to the left, or a combination thereof will work as expected, because old characters will be read before they are overwritten by new data. Moving text down or to the right, on the other hand, will overwrite old characters before they are themselves copied, which is probably undesirable.

The copy command does not clear its source rectangle after executing. Using it for scrolling old text off the top of the screen is a suitable application, but be sure to clear the bottom row after performing the scroll or else it will be duplicated.

Examples

Set whole display to reverse video using the blitter (FORTH)

PAGE (Ensure we're entering lines near the top of the screen. Scrolling uses the blitter and will mess up our settings.)
HEX
0 308 C! (Set origin to top left.)
0 309 C!
0 30A C! (Set offset to 0.)
0 30B C!
50 30C C! (80 columns is 50 hex.)
32 30D C! (50 lines is 32 hex.)
2 307 C! (2 inverts.)
Note: When testing, the PAGE command helps avoid entering text near the bottom of the screen where scrolling uses the blitter and will mess up the test values.