VDP Variables
VDP variables provide a way to both read and change the state of the VDP. They can be used to enable an experimental feature, read or change the current state of the VDP, or store information for use in a buffered command sequence.
VDU variables are 16-bit values, although some variables may only use the lower 8 bits. Whilst natively variables are stored as unsigned values, the VDP will interpret them as signed values where appropriate; for instance graphics coordinates can be negative, and the VDP will interpret them as such.
Variables are currently split into three general categories: test flags, system settings, and VDU variables. In the future we will add more variables to expose the state of the audio system. These categorites are given some broad ranges of variable IDs to allow for future expansion, and to allow for easy identification of the type of variable.
Test flags are used to enable a feature that may either be experimental, not yet fully implemented, have an API that might change, or are not fully tested.
System settings variables provide access to VDP system information, such as memory usage, real-time clock data, and keyboard settings.
VDU variables provide access to the graphics system state, including context-specific information that may change when switching context.
The VDP variables system was added in Console8 VDP 2.9.0, and was initially used only for test flags.
The Console8 VDP 2.12.0 release has added many new variables that expose the state of the VDP, and allow for changes to be made to that state. It is also now possible to use VDP variables in buffered commands. This allows for conditional commands to be used to check against a variable, and the contents of a variable to be read into a buffer.
Further extensions to the VDP variables system were made in VDP 2.15.0, exposing more information, and functionality related to VDP events.
Variable APIs
There are just two API calls to directly work with VDP variables, one to set a variable, and another to clear it. As of VDP 2.12.0 the buffered command API also allows for the reading of variables into a buffer, and for conditional commands to be used to perform their checks against a variable.
The commands to set and clear variables are documented in the system commands documentation. Briefly they are:
VDU 23, 0, &F8, variableId; value;: Set a VDP VariableVDU 23, 0, &F9, variableId;: Clear a VDP Variable
The buffered commands API has also been updated to support the use of variables. All conditional commands, such as the conditional call and conditional jump to an offset, can support conditions to be checked against VDP variables. A new command to read the value of a VDP variable and store it in a buffer has also been added which can be used to insert variable values into command sequences.
Variable ID ranges
All variables listed are available from VDP 2.12.0 onwards. Variables that were introduced in 2.9.0 and 2.11.0 are marked as such.
The broad ranges of variable IDs are as follows:
| Variable ID range | Description |
|---|---|
| 0x0001-0x00FF | Test flags |
| 0x0100-0x0FFF | System variables |
| 0x1000-0x1FFF | VDU variables (graphics/text system) |
| 0x2000-0x2FFF | Reserved for audio system variables |
| 0x3000-0x3FFF | Reserved for future use |
| 0x4000-0xFFFF | Available for general use |
The system will not prevent you from using variables in reserved ranges, although inside the "VDU variables" range values that the system does not directly support will not be stored, and cannot be read.
Test Flags
In general, test flags are used to enable features that are not yet fully implemented, or may be considered experimental with an API that may change. A new feature will typically require a test flag to be set to enable it until the feature is fully implemented and considered stable, at which point a program will not be required to set the flag to use the feature. As a feature develops over time, programs may need to change the value they set the test flag to in order to opt in to new API changes. It is possible that a new feature may continue to recognise its test flag after it has been fully implemented to allow for programs that used older versions of their API to continue to work, but this is not guaranteed.
Test flags are essentially just simple variables. Setting a test flag for a feature that has already been fully implemented and no longer requires the flag to be set therefore will have no harmful effect. The test flag will be ignored, and the feature will work as normal.
As of Console8 VDP 2.9.0 the following test flags are supported:
| Variable ID | Value | Description |
|---|---|---|
| 1 | 0 (any) | Enable the Affine Transforms feature (available from 2.9.0) |
| 2 | 0 (any) | Enable hardware sprites |
If a flag is set that is not recognised then it will have no effect. This means that if a feature graduates from being a test feature and no longer requires a flag to be set for use then, so long as the API for the feature remains the same, software that sets the flag to enable the feature will still work.
For the current test flags that the VDP supports, any value can be set to enable the feature, but you are strongly advised to use set their flags with a value of zero. Future flags may require specific values to be set to control how the feature works.
(Some features that may be considered experimental use variables outside of this range to enable them. In general this is because the feature may use a variable to control how it works, which will still be required after the feature is fully implemented. In general though this practice will be avoided.)
System Variables
Broadly speaking, system variables are used to read and change the state and configuration of the VDP that are not directly related to the current graphics context state or screen mode. Within the system variables block there are sub-blocks for different types of system information.
The sub-ranges within system variables are broadly as follows:
| Block | Description |
|---|---|
| 0x0100-0x01FF | Communications system settings |
| 0x0200-0x0208 | Real-time clock data |
| 0x0209-0x020F | Reserved for future use |
| 0x0210-0x021F | VDP memory information |
| 0x0220-0x022F | Keyboard settings |
| 0x0230-0x023F | Context management |
| 0x0240-0x024F | Mouse settings * |
| 0x0250-0x025F | Keyboard event info |
| 0x0250-0x02FF | Reserved for future use |
| 0x0300-0x03FF | Graphical system enhancement settings/flags |
| 0x0400-0x04FF | Bitmap/Sprite system control settings |
| 0x0500-0x05FF | Last value variables |
| 0x0600-0x07FF | Reserved for future use |
| 0x0800-0x08FF | Keyboard map |
| 0x0900-0x0FFF | Reserved for future use |
* The mouse settings variables were added to this range in VDP 2.15.0, as these represent global settings for the mouse system.
Many system variables can be set and adjusted by other VDU commands
As of Console8 VDP 2.12.0 the following system variables are supported:
Communications system settings
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0101 | 0/1 | X | Full duplex UART hardware flow control flag. This is intended for internal use by MOS. NB setting this flag will break communications with MOS unless a suitable version of MOS that supports full duplex flow control. The first version of MOS to support this is MOS 3.0 alpha 3 | |
| 0x0102 | n/a | X | Reserved for future use (Buffer size on MOS for VDP protocol packets) | |
| 0x0103 | X | Suppress the next VDP protocol packet. This variable is automatically cleared after the next attempt to send a VDP protocol packet (added in VDP 2.15.0) | ||
| 0x0110 | 0/1 | X | Reserved for future use (Echo back received data, for redirect/spool, with a suitable version of MOS that supports this feature) |
Setting variable 0x0103 to any value will cause the next VDP protocol packet that would be sent to MOS to be suppressed and discarded. This can be used to prevent specific events from sending data to MOS, which could be useful in some circumstances. For example a VDP-resident "mouse-keys" implementation that intercepts keyboard events to move the mouse cursor could use this to prevent applicable keyboard events from being sent to MOS.
Real-time clock data
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0200 | 0-999 | Real-time clock year | ||
| 0x0201 | 1-12 | Real-time clock month | ||
| 0x0202 | 1-31 | Real-time clock day | ||
| 0x0203 | 0-23 | Real-time clock hour | ||
| 0x0204 | 0-59 | Real-time clock minute | ||
| 0x0205 | 0-59 | Real-time clock second | ||
| 0x0206 | 0-999 | X | Real-time clock millisecond | |
| 0x0207 | 0-6 | X | Real-time clock weekday | |
| 0x0208 | 0-366 | X | Real-time clock day of year |
VDP memory information
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0210 | X | Free PSRAM low bytes | ||
| 0x0211 | X | Free PSRAM high bytes | ||
| 0x0212 | X | Number of buffers used |
Keyboard settings
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0220 | 0-17 | Keyboard layout (setting to an invalid number will set to zero) | ||
| 0x0221 | 0/1 | Control keys on/off (setting to any non-zero value sets to 1) | ||
| 0x0222 | 240-1000 | Keyboard repeat delay (milliseconds, rounded to nearest 250) | ||
| 0x0223 | 33-500 | Keyboard repeat rate (characters per second) | ||
| 0x0224 | 0-7 | Keyboard LED status (bitmask, combined values of NumLock, CapsLock and ScrollLock) | ||
| 0x0225 | 0/1 | Keyboard NumLock LED status (1=on, 0=off) | ||
| 0x0226 | 0/1 | Keyboard CapsLock LED status (1=on, 0=off) | ||
| 0x0227 | 0/1 | Keyboard ScrollLock LED status (1=on, 0=off) |
Context management
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0230 | 0-255 | Current active context ID |
Mouse settings
Support for mouse settings in this range was added in VDP 2.15.
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0240 | X | Mouse cursor ID * | ||
| 0x0241 | 0/1 | X | Mouse enabled. The mouse can only be enabled if a mouse is physically connected to your Agon's PS/2 mouse port | |
| 0x0242 | Mouse cursor X position in screen coordinates | |||
| 0x0243 | Mouse cursor Y position in screen coordinates | |||
| 0x0244 | 0-7 | X | Mouse cursor button status. Bit 0 indicates left button pressed, bit 1 the right button, and bit 2 the middle button | |
| 0x0245 | X | Mouse wheel delta | ||
| 0x0246 | Mouse sample rate | |||
| 0x0247 | Mouse resolution | |||
| 0x0248 | Mouse scaling | |||
| 0x0249 | Mouse acceleration | |||
| 0x024A | Mouse wheel acceleration | |||
| 0x024B | 0/1 | X | Mouse cursor visible |
* Setting the mouse cursor ID to a valid cursor ID will (as of VDP 2.15) always show the mouse cursor, and setting to an invalid ID will hide it, but not change the stored value. Clearing the value will reset the mouse cursor ID to the default (0) and hide the cursor. This will also affect the "mouse cursor visible" variable accordingly.
Keyboard event info
Support for keyboard event/state info in this range was added in VDP 2.15.
Values in this range provide information on the last keyboard event that occurred. This includes all the data sent to MOS when a key is pressed, plus some more information.
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0250 | X | Lower byte last ASCII keycode value sent to MOS * Upper byte raw ASCII value from latest key event |
||
| 0x0251 | X | FabGL Virtual keycode | ||
| 0x0252 | X | Key down flag (1) or up (0) | ||
| 0x0253 | X | Key modifiers byte (Shift, Ctrl, Alt, etc) | ||
| 0x0254 | X | CTRL key state (1=pressed, 0=not pressed) | ||
| 0x0255 | X | SHIFT key state (1=pressed, 0=not pressed) | ||
| 0x0256 | X | LEFT ALT key state (1=pressed, 0=not pressed) | ||
| 0x0257 | X | RIGHT ALT key state (1=pressed, 0=not pressed) | ||
| 0x0258 | X | CAPSLOCK key state (1=pressed, 0=not pressed) | ||
| 0x0259 | X | NUMLOCK key state (1=pressed, 0=not pressed) | ||
| 0x025A | X | SCROLLLOCK key state (1=pressed, 0=not pressed) | ||
| 0x025B | X | GUI key state (1=pressed, 0=not pressed) | ||
| 0x025C | X | Raw PS/2 key scancode value, bytes 1 and 2 | ||
| 0x025D | X | Scancode bytes 3 and 4 | ||
| 0x025E | X | Scancode bytes 5 and 6 | ||
| 0x025F | X | Scancode bytes 7 and 8 |
* The Agon VDP makes some minor adjustments to the keycode value it sends to MOS; it sets specific values for all four arrow keys, plus the tab and backspace keys. The raw value before these adjustments were made is available in the upper byte of this variable. Reading the two bytes stored in this variable separately is possible using the read VDP variable command. If you request the variable as an 8-bit value in big-endian order, it will read the upper byte containing the raw value. Reading as an 8-bit value in little-endian order then you will return the lower byte containing the adjusted value.
General Poll byte
Support for the general poll byte variable was added in VDP 2.15.
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0280 | 0-255 | X | General poll byte. This will be the last byte value received with the general poll command, and/or as returned back to MOS in the corresponding VDP protocol response packet |
In most circumstances setting this variable will have no effect. However, a callback event handler listening for event 0x100 will see this variable as the value that was received as part of the general poll command, and can modify the value before it is sent back to MOS. This potentially means that an inventive programmer could use the "general poll" command as a way to send data from the VDP to MOS, one byte at a time...
Graphical system enhancement settings/flags
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0300 | 0 (any) | X | Tile engine flag (enables layers commands, available from VDP 2.11.0) | |
| 0x0310 | 0 (any) | X | Enables copper features flag |
Bitmap/Sprite system control settings
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0400 | 0 (any) | X | Prefer hardware sprites flag. When set, all sprites will be set to be hardware sprites after calling the "Reset sprites" API, if the "Enable hardware sprites" test flag has also been set |
Last value variables
Support for these variables were added in VDP 2.15.
Variables in this range are used to store the recent values related to a command or event that has occurred on the VDP. This provides a way to see responses or results of VDU commands that may not otherwise be available as VDU variables. At this time, the following commands will cause these variables to be updated:
- Get the value of a character on screen using text coordinates
- Get the value of a character on screen using graphics coordinate
- Get colour of pixel at a graphics coordinate
- Read colour palette entry
- Change a colour palette entry
- Resetting the palette
When any of these commands are successfully executed the corresponding variables described below will be updated. With the exception of the commands to change a colour palette entry and reset the palette, they will also send a VDP Protocol data packet back to MOS with response data. You can prevent the VDP Protocol data packet from being sent by temporarily changing the output stream to 65535, and then restoring it back to the original stream by setting it back to 0 (the default stream). This will prevent the VDP from sending the data packet, but the variables will still be set.
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x0500 | 0-255 | X | Last character value read | |
| 0x0510 | 0-255 | X | Last colour red value | |
| 0x0511 | 0-255 | X | Last colour green value | |
| 0x0512 | 0-255 | X | Last colour blue value | |
| 0x0513 | 0-63 | X | Last colour logical colour value (it's palette index) | |
| 0x0514 | 0-63 | X | Last colour physical colour value (RGB222 equivalent of variables 0x0510-0x0512) | |
| 0x0515 | X | X coordinate of the last colour (graphics coordinates) | ||
| 0x0516 | X | Y coordinate of the last colour (graphics coordinates, ) |
In the case of the command to read a colour palette entry, the palette can already be read from VDU variables, but that will only provide you with the physical colour value for a palette entry. The command can also read the currently selected text and graphics foreground and background colours, which are otherwise only available as their logical colour values.
Palette changes from VDU 19 or VDU 20 will update the last colour variables and also perform any callbacks looking for a "palette change" event. In the case of a palette reset, the last colour variable values for red, green, and blue will all be set to 0, and the logical and physical colour values will be set to 255. As those are not valid values for logical or physical colours this can be used to detect a palette reset.
Command that read or set palette entries will set the last colour X and Y coordinate variables to 32768.
Setting a palette entry by directly changing the corresponding VDU variable will cause the palette to be updated correctly, but will not update the last colour variables, or cause a palette change event.
Keyboard map
Variables from ID 0x0800 onwards for a total of 259 variables contain a map of values that relate to the keyboard. The index into this range is the FabGL virtual keycode value. It should be noted that this is not the ASCII value of a key.
Within this range, the variable's lower-byte is a boolean that will indicate whether that virtual key is currently pressed/down (1) or not (0). The upper byte provides the the current ASCII equivalent to the virtual keycode, if applicable. This value may be adjusted by a modifier key being pressed such as the Ctrl key. Keycodes that do not have an ASCII equivalent, such as modifier keys, function keys, or keys that are not mapped in your currently selected keyboard layout, will have the upper byte set to 0.
All of the values in this range are read-only.
VDU Variables
VDU variables are numbered in the range &1000-&1FFF and are used to expose information on the current graphics system state. This includes both information about the current screen mode, and the current context state.
The set of variables are loosely based on the VDU variables available in Acorn's RISC OS operating system, and where appropriate they are numbered the same. The Agon VDP includes many extensions to include additional information that is specific to the Agon platform.
In general, most of the variables within this range are specific to the currently selected graphics context. This means that when the context is changed, the values of these variables may change. Within this range are some variables specific to the current screen mode which will not change when the context changes, plus variables that are derived from both the current context and the screen mode, such as the number of text columns and rows; in general these variables are read-only.
Some information is specific to the current screen mode and will not change if the context is changed. This includes the screen width and height, the number of screen banks, and the maximum logical colour number for the current screen mode, and the graphics palette definition. Some information is derived from both the current context and the screen mode, such as the number of text columns and rows.
All variables within this range are reserved for use by the VDU system. Any values that are not recognised will not be stored, and cannot be read.
Flag variables use values 0 to indicate disabled, and 1 to indicate enabled. Setting a flag to any non-zero value is counted as if setting to 1.
Some variables provide coordinates. For those variables that are marked as "screen coordinates", the origin is at the top-left of the screen, and the location is measured in pixels. For those variables that are marked as "character coordinates", the origin is at the top-left of the screen, and the location is measured in characters. Variables shown as "OS coordinates" will reflect the currently selected coordinate system, as defined in variable &1057. When the default coordinate system is selected, the origin is at the bottom-left of the screen, and the location is measured in OS units, where the screen is defined as 0-1279 for X and 0-1023 for Y.
| Variable ID | Value | Read-only | Clearable | Description |
|---|---|---|---|---|
| 0x1001 | X | Screen text columns - (characters) | ||
| 0x1002 | X | Screen text rows - (characters) | ||
| 0x1003 | 1/3/15/63 | X | Max logical colour number for current screen mode | |
| 0x100B | X | Screen width in pixels - 1 | ||
| 0x100C | X | Screen height in pixels - 1 | ||
| 0x100D | 1/2 | X | Number of screen banks (1 for single-buffered modes, 2 for double-buffered) | |
| 0x1017 | 0-255 | Current line thickness (pixels) | ||
| 0x1018 | Text cursor, absolute X position (chars) | |||
| 0x1019 | Text cursor, absolute Y position (chars) | |||
| 0x1020 | Frame counter low word (the frame counter is a 32-bit value) | |||
| 0x1021 | Frame counter high word | |||
| 0x1022 | Number of frames to pause on newline when the "Ctrl" key is held * | |||
| 0x1023 | Current number of frames being waited for * | |||
| 0x1055 | X | Current screen mode number | ||
| 0x1056 | 0/1 | Legacy modes flag | ||
| 0x1057 | 0/1 | Coordinate system (0 = screen/pixel coordinates, 1 = logical/OS (default)) | ||
| 0x1058 | 0/1/2/3 | Paged mode flag (0 = disabled, 1 = enabled, 2 = disabled, but temporary paged mode is on , 3 = enabled, and temporary paged mode is on ) | ||
| 0x1059 | Paged mode context row count * | |||
| 0x1066 | 0-255 | Cursor behaviour flags byte, as set via VDU 23,16,setting,mask | ||
| 0x1067 | 0/1 | Text cursor visibility | ||
| 0x1068 | Text cursor block horizontal start column | |||
| 0x1069 | Text cursor block horizontal end column | |||
| 0x106A | 0-31 | Text cursor block vertical start row | ||
| 0x106B | Text cursor block vertical end row | |||
| 0x106C | 0-3 | Text cursor appearance, write only (0 = steady, 1 = off, 2 = fast blink, 3 = slow blink) | ||
| 0x1070 | X | Active cursor type (0 = Text cursor, 1 = Graphics cursor) | ||
| 0x1080 | Graphics window, LH column, screen coordinates | |||
| 0x1081 | Graphics window, Bottom row, screen coordinates | |||
| 0x1082 | Graphics window, RH column, screen coordinates | |||
| 0x1083 | Graphics window, Top row, screen coordinates | |||
| 0x1084 | Text window, LH column, character coordinates | |||
| 0x1085 | Text window, Bottom row, character coordinates | |||
| 0x1086 | Text window, RH column, character coordinates | |||
| 0x1087 | Text window, Top row, character coordinates | |||
| 0x1088 | Graphics origin, X, OS coordinates | |||
| 0x1089 | Graphics origin, Y, OS coordinates | |||
| 0x108A | Graphics cursor, X, OS coordinates | |||
| 0x108B | Graphics cursor, Y, OS coordinates | |||
| 0x108C | Oldest Graphics cursor, X, screen coordinates | |||
| 0x108D | Oldest Graphics cursor, Y, screen coordinates | |||
| 0x108E | Previous Graphics cursor, X, screen coordinates | |||
| 0x108F | Previous Graphics cursor, Y, screen coordinates | |||
| 0x1090 | Graphics cursor, X, screen coordinates | |||
| 0x1091 | Graphics cursor, Y, screen coordinates | |||
| 0x1097 | 0-7 | GCOL action for foreground colour | ||
| 0x1098 | 0-7 | GCOL action for background colour | ||
| 0x1099 | 0-63 | Graphics foreground (logical) colour | ||
| 0x109A | 0-63 | Graphics background (logical) colour | ||
| 0x109B | 0-63 | Text foreground (logical) colour | ||
| 0x109C | 0-63 | Text background (logical) colour | ||
| 0x10A1 | X | Max mode number (not double-buffered) | ||
| 0x10A2 | X | X font size, graphics cursor | ||
| 0x10A3 | X | Y font size, graphics cursor | ||
| 0x10A4 | X | X font spacing, graphics cursor | ||
| 0x10A5 | X | Y font spacing, graphics cursor | ||
| 0x10A7 | X | X font size, text cursor | ||
| 0x10A8 | X | Y font size, text cursor | ||
| 0x10A9 | X | X font spacing, text cursor | ||
| 0x10AA | X | Y font spacing, text cursor | ||
| 0x10F2 | Dotted line pattern length | |||
| 0x10F3 | Line pattern, bytes 0-1 | |||
| 0x10F4 | Line pattern, bytes 2-3 | |||
| 0x10F5 | Line pattern, bytes 4-5 | |||
| 0x10F6 | Line pattern, bytes 6-7 | |||
| 0x1100 | Width of text window in chars | |||
| 0x1101 | Height of text window in chars | |||
| 0x1118 | X position of text cursor within text window | |||
| 0x1119 | Y position of text cursor within text window | |||
| 0x111A | X position of text cursor in screen coordinates | |||
| 0x111B | Y position of text cursor in screen coordinates | |||
| 0x1200-0x123F | 0-63 | Palette entries. Maps logical colours to physical screen colours. The entries used will depend on the number of colours in the current screen mode | ||
| 0x1300-0x13FF | Character to bitmap mapping. Value is a 16-bit bitmap ID, or 65535 if character is not mapped. See VDU 23, 0, &92, char, bitmapId; |
|||
| 0x1400 | Currently selected bitmap ID (16-bit bitmap ID) | |||
| 0x1401 | X | Count of bitmaps used | ||
| 0x1402 | Current bitmap transform ID. Must be set to a buffer ID containing a valid affine transform. The affine transforms flag must be set to change this value | |||
| 0x1410 | 0-255 | Current sprite ID | ||
| 0x1411 | X | Number of sprites active (not necessarily visible) | ||
| 0x1440 | Mouse cursor ID ** | |||
| 0x1441 | 0/1 | Mouse enabled. The mouse can only be enabled if a mouse is physically connected to your Agon's PS/2 mouse port ** | ||
| 0x1442 | Mouse cursor X position in screen coordinates ** | |||
| 0x1443 | Mouse cursor Y position in screen coordinates ** | |||
| 0x1444 | 0-7 | X | Mouse cursor button status. Bit 0 indicates left button pressed, bit 1 the right button, and bit 2 the middle button ** | |
| 0x1445 | X | Mouse wheel delta ** | ||
| 0x1446 | Mouse sample rate ** | |||
| 0x1447 | Mouse resolution ** | |||
| 0x1448 | Mouse scaling ** | |||
| 0x1449 | Mouse acceleration ** | |||
| 0x144A | Mouse wheel acceleration ** |
* Support for these variables was added in VDP 2.14.0
** As of VDP 2.15.0 the mouse cursor variables in this range are deprecated; you are advised to use the equivalent mouse system variables. On earlier versions of the VDP setting the mouse cursor ID would only work if the mouse was enabled