Showing changes from revision #12 to #13:
Added | Removed | Changed
Value | Name | Meaning |
---|---|---|
0 | ModeFlags | Assorted flags |
1 | ScrRCol | Number of text columns -1 |
2 | ScrBRow | Number of text rows -1 |
3 | NColour | Maximum logical colour |
4 | XEigFactor | Conversion factor between OS units and pixels |
5 | YEigFactor | Conversion factor between OS units and pixels |
6 | LineLength | Number of bytes per pixel row |
7 | ScreenSize | Number of bytes for entire screen display |
8 | YShiftSize | Deprecated. Do not use |
9 | Log2BPP | Log base 2 of bits per pixel |
10 | Log2BPC | Log base 2 of bytes per character |
11 | XWindLimit | Number of x pixels on screen -1 |
12 | YWindLimit | Number of y pixels on screen -1 |
13 | MinScreenBanks | Minimum number of screen banks |
Mode variables (apart from some bits within Mode Flags) represent immutable properties of a screen mode. I.e. the only time they will change is when the screen mode changes or when output is redirected to a sprite.
OS_ScreenMode and Wimp_SetMode allow you to directly or indirectly specify some of the mode variables when changing screen mode. OS_ReadModeVariable and OS_ReadVduVariables can be used to read mode variables for a mode.
XEigFactor and YEigFactor are used to convert between the “OS unit” coordinate system and screen pixels. The conversion is applied as follows:
pixels = os_units >> eigen_factor
The OS only supports eigen factors in the range 0-3
OS units are intended to represent a real-world scale of 180 DPI (i.e. one inch is equivalent to 180 OS units). This also suggests that you should be able to deduce the DPI of a user’s display by looking at the eigen values of the screen mode (e.g. an eigen value of 1 represents 90 DPI ). However However, the limited number of scaling factors available via the eigen system means that at best this is nothing more than a rough estimate.
Ordinarily, the Log2BPP and Log2BPC values match, as each text character is eight pixels wide. However However, in screen modes 2, 5 and 10, characters are sixteen pixels wide, and so Log2BPC takes the value of Log2BPP+1. This discrepancy is due to the way thatBBC Micro modes 2 and 5 are emulated. On BBC hardware hardware, the modes are 160×256 pixels in size, and the hardware stretches the pixels in order to provide an image at the correct aspect ratio. On Archimedes hardware (and above) the modes are physically 320×256 pixels in size, and the OS doubles the pixels in software in order to provide an emulated 160×256 pixel resolution. This pixel doubling is applied in all OS rendering APIs, including plain text output,OS_Plot VDU primitives, and sprite rendering.
The LineLength variable stores the “row stride” of the framebuffer: The byte-wise address offset between pixel N of row M and pixel N of row M+1.
In most screen modes, screen memory is tightly packed so that there is no “wasted space”. E.g. a 320×256 8bpp screen mode will have a LineLength of 320, and a ScreenSize of 320×256 = 81920.
However, there are some situations where it’s necessary to insert extra padding between rows. For example, when screen output is redirected to a sprite , there may be up to one word of padding between screen rows due to the requirement that sprite rows must start on word boundaries. Some video hardware may also have restrictions on the stride or alignment of rows, forcing the OS to use a padded framebuffer in order to display the mode. In these cases cases, both LineLength and ScreenSize will be larger than expected. E.g. a 319×256 8bpp sprite will still have a LineLength of 320.
The presence of padding between rows, and the length of that padding, can be determined by comparing the LineLength value against ((XWindLimit+1) << Log2BPC) >> 3
. If the values are identical, no padding is present, and the framebuffer pixels are arranged contiguously in memory. If the values differ differ, then padding will be present at the end of each row.
If padding bytes are present, they do not constitute valid screen pixels, and software should avoid reading or writing to them.
This is a new mode variable, primarily intended to allow mode selection and overlay creation to request that enough memory is reserved to allow for a guaranteed number of screen banks/buffers to be available.