Having trouble programming the Oric? Let Bob Maunder show you how to use high-resolution graphics.
Oric for Hi-Res
Having trouble programming the Oric? Let Bob Maunder show you how to use high-resolution graphics
The Oric micros are economical in their use of memory, but the trade-off is that they can be difficult to program. This is particularly obvious when you're creating graphics. Here you face a struggle against PLOT$, POINT$, serial attributes, and their confederates. But with a little thought the basics of high-resolution displays can still be mastered.
Two graphics resolutions, how and high, are provided on the Oric 1 and the Atmos. The famous (or notorious) teletext-style graphics are handled in low-resolution. This mode is ideal for displaying text or for the kind of block drawings used by Ceefax and Oracle. High-resolution is designed for more detailed drawing.
The instruction HIRES invokes this mode, causing the top part of the screen to clear to black. The bottom three lines stay in the previous background colour. this base area is for text messages - the programmer cannot use PRINT @ or PLOT on the high resolution screen, and any messages from PRINT or INPUT instructions will appear in this text area.
HIRES utilities a grid of picture elements, or pixels. The grid size is 240 by 200 with x values ranging between 0 and 239 and y values between 0 and 199 increasing downwards. There is no top line for system messages and all columns are accessible.
The high-resolution display area takes up more memory than the equivalent low-resolution version. If the GRAB instruction has previously been used to claim the memory area normally holding the high-resolution screen for use by a Basic program and data then RELEASE must reallocate this to the HIRES screen. This area lies between addresses 40960 and 49119. There are 40 memory locations for each of the 200 y-positions or lines, and patterns are drawn on the high-resolution display by using the last six bits of each location. A binary 1 indicates a pixel in foreground colour while 0 indicates a background pixel.
But the high-resolution area also needs to hold colours and other display attributes. As with low-resolution, these serial attributes take up one byte, but there must be some way of distinguishing a pattern byte from an attribute byte. The second and third bits of a memory location give a non-zero value if its contents are a pattern. If both bits are zero the contents are an attribute.
Listing 1 demonstrates the difference between patterns and attributes placed in the HIRES memory area.
Numbers 15 and 22 are attributes, while 115 and 127 are patterns (in binary 01110011 and 01111111 respectively).
The overall colour of the high-resolution display is set by PAPER and INK. PAPER sets the background colour of the screen and INK the foreground or writing colour according to the values:
0 | - | black |
1 | - | red |
2 | - | green |
3 | - | yellow |
4 | - | blue |
5 | - | magenta |
6 | - | cyan |
7 | - | white |
The instructions take effect immediately - the screen does not need to be cleared first. Both result in an attribute byte being placed in the first two column positions of all screen lines.
Listing 2 illustrates the PAPER colours.
A variety of instructions can be used to draw on the high-resolution screen. All use a parameter known as the 'FB' value. This determines how points are drawn according to:
FB = 0 drawn in background colour
FB = 1 drawn in foreground colour
FB = 2 drawn inversely
FB = 3 not drawn but the drawing position is moved
Drawing Instructions
Drawing instructions may operate within the absolute coordinates of the display area, namely x values ranging between 0 and 239 and y values between 0 and 199. Alternatively, they may operate relative to the current drawing position.
CURSET sets the drawing position or cursor to an absolute coordinate. When HIRES is entered, the cursor is automatically set to (0,0). Many high-resolution programs do not require drawing to start at this point, so CURSET is used to position the cursor initially. Subsequently, the instruction is used whenever an absolute cursor setting is needed.
Once the right starting position is achieved the DRAW instruction can be used to plot a figure. DRAW X,Y,FB draws a line from the current cursor position to a position X away on the x-axis and Y away on the y-axis, with a given FB code: thus relative coordinates are used.
Listing 3 employs CURSET and DRAW to plot 'snowflakes' randomly on the screen until the S key is pressed.
DRAW normally draws solid lines but the PATTERN instruction can be used to give a different layout to the lines drawn. PATTERN is followed by a value between 0 and 255 which determines the level of solidity, giving, for example, dotted or dashed lines. The pattern of lines is determined by the binary layout of the integer in the PATTERN instruction. For example, lines with long dashes may be achieved by PATTERN 231 (binary is 11100111) Listing 4 shows the effect of any given pattern value. Sometimes you may want to move the cursor relative to its current placing. This is done by CURMOV. The instruction's format resembles CURSET, coordinates are not absolute. The difference is illustrated in the following example, which also introduces the CIRCLE instruction. This command has a format of CIRCLE R,FB where R is the radius of the circle drawn, its centre being at the current drawing position. Listing 5 fills the screen with circles.
CIRCLE is also affected by the current PATTERN setting, so normally we reset a PATTERN of 255 if dashed lines have previously been used.
Although HIRES is designed for drawing rather than printing, text can be displayed, using the CHAR instruction. This has three parameters. The first defines the character to be plotted as an ASCII value; the second determines whether it is to be in the standard (0) or alternate (1) character set, and the third is the FB code. The character is plotted at the current cursor position, so CURMOV or CURSET should accompany CHAR. For example, to place a text message M$ on the HIRES screen starting at the current position, the following routine could be used:
FOR C=1 TO LEN(M$):CHAR ASC(MID$(M$,C,1)),0,1:CURMOV 6,0,0:NEXT
As well as printing text, CHAR can also plot attributes. However, the FILL instruction is generally better equipped for this task. This command has the form FILL L,B,N: it fills L lines of B bytes with the value N, starting at the current cursor position. Oric 1 owners should be a little wary here since FILL does not necessarily update the cursor position correctly.
Listing 6 places random foreground colour attributes in byte 1 of all lines, and then draws a solid circle to show the colours.
Another keyword that gets down to the byte level is POINT. POINT (X,Y) examines the pixel (X,Y) and returns a value 0 if it is in background colour or -1 if it is foreground. The POINT function actually examines one of the bits in a pattern byte, retuning 0 if the bit is 0, and -1 if the bit is 1. In Listing 7 the cursor moves in a random way inside a circle and the POINT function is used to test when it hits the circle border. Notice that, in line 80, POINT is used as a logical value: Oric Basic takes 01 as TRUE and 0 as FALSE.
Using the Instructions
We can now integrate some of these features into a more substantial program. The Bottle program draws bottles at varied positions, and in different sizes and colours. The user enters the coordinates of the top left-hand corner of each bottle, within the limits of the 200 x 240 high-resolution screen. The size of the bottle must also be allowed for: this is about 30 x 10 in size one, increasing proportionately up to 150 x 50 in size five. The colour of the bottle is input as an integer between 0 and 7, representing black, red, green, yellow, blue, magenta, cyan and white respectively. The screen background is set to red by line 10, so a bottle of colour 1 will be invisible.
The modules of the program are arranged in the following way:
Lines 10-140: | Main section. Repeated drawing of a bottle according to use inputs, until the S key is pressed. |
Subroutine 450: | Reads coordinates of the bottle shape; x coordinates are stored in array A, y coordinates in array B. |
Subroutine 600: | Draws a bottle with its origin at (OX,OY). Lines 640-680 display the bottle's contents at a random level. |
Subroutine 700: | Scales the A and B coordinate arrays by S, storing the resultant arrays in X and Y. |
Subroutine 800: | Places attribute characters in front of the bottle to give the required colour COL. |