← CharsetsGlobal Game Jam 2018 →
  Oric graphics in details
Sat 8th April 2017   
This article was first written in July 2002 as a 'how to' for the artists working on our first big Defence-Force demo, was translated to english in 2005, but was never really officially published until today.


The oric very does not have a very conventional video system.

It is possible to achieve very decent results, but that implies to fully understand the way the oric video system works.

This document is a long, but should be sufficient (after a serious reading) to make it possible to whoever to make colorful graphs on ORIC.

The idea is to make it the definitive guide to all things graphical on the Oric, which means it will be extended, correct, etc... over time.

If you have suggestions about how to make this article better, don't hesitate to contact me!

Yessagician, by Dbug
Yessagician, by Dbug

One last note: This document will contain numerical values. When they are preceded by a # or $ symbol the value is expressed in hexadecimal (base 16), else they are just decimal.

Virtual video modes

If for some reason you listened to the Oric user manual, you would think that the Oric has four distinct video modes:

4 video modes

You should recognize without too much problem the video modes called TEXT (blue border), LORES 0 (purple border), and HIRES (yellow border).

The last one, outlined in green, is the LORES 1 mode showing its funny mosaic character set.

To access these modes you just have to type in their name at the BASIC prompt. but well...

I will not prolongate the suspense any longer: there are no such things as 4 different video modes on the Oric.

The Oric video display chip is able to display text and graphics, so we can say that only two video modes exist on this machine, and even then what separate them is quite slim.

Text modes

The TEXT mode is used by default when you boot the computer.

You can also invoke it using the TEXT command in Basic, as well as LORES 0 and LORES 1 which are just minor variants of TEXT.

In general, the first line - called the status line - is reserved by the system to display information like the name and type of the file being loaded or the status of the CapsLock key, but this is just enforced by software: You are free to use it as any other line on the screen.

From a memory point of view, TEXT mode requires 1120 bytes for display (28 lines of 40 columns), and 1920 bytes for storing the character set:
  • 1120 bytes for the screen (from #BB80 to #BFDF)
  • 1024 bytes for the default character set (from #B400 to #B7FF)
  • 896 bytes for the secondary ("alternate") character set (from #B800 to #BB7F)
This makes a total of 3040 bytes.

TEXT mode video mapping

The way it works is quite standard: Each byte in the screen memory contains a value which is the ASCII value of the character that should be displayed there, and this value is used as an index in the character set.

So if the first byte of the screen (#BB80), contains the value 65 (ASCII code for the upper case A letter), we know that this block of 6x8 pixels will be filled with graphical information stored at the address #B400+(8*65).

This is, by the way, how most of the Oric games are working: They are using TEXT mode to display fast animated elements, except that they redefined the graphical representation of characters so they look like maze walls, cars or parts of a Pac Man character.

Hires mode

You can switch to the HIRES mode using the Basic HIRES command.

Structurally it is very similar to the TEXT mode, with 40 bytes per line, with each byte representing 6 pixels for a total of 240 pixels in width.

The main difference is that each line is only one pixel tall instead of 8, so there are 200 of these.

The actual graphical resolution is 240x200, but the screen has an additional area at the bottom containing 3 lines of TEXT mode.

HIRES mode video mapping

From a memory point of view, HIRES mode is much more voracious:
  • 8000 bytes for the HIRES part of the screen (from #A000 to #BF3F)
  • 120 bytes for the TEXT part of the screen screen (from #BF68 to #BFDF)
  • 42 bytes lost between the HIRES and TEXT parts of the screen (from #BF40 to #BF67)
  • 1024 bytes for the default character set (from #9800 to #9BFF)
  • 1024 bytes for the secondary ("alternate") character set (from #9C00 to #9FFF)
This makes a total of 10210 bytes.

Let's now address this "6 pixels" per byte issue.

My bytes have 6 bits

The natural memory unit on a 8bit computer is the BYTE. Which is why it's called "8 bit" computer in first place.

The logical consequence is that these computers tend to use 8x8 pixels as the natural font size, and tend to pack pixels by groups of 8.

The Oric on the other hand only has 6x8 characters, and a weird 240x224 graphical resolution: The reason is that each byte of the video memory contains reserved codes that limit the number of displayable values.

Most machines have some I/O registers that can be used to change colors, switch video modes or read the position of the video beam. They also often have separate video memory buffers for bitmap data, color data, sprite data, etc...

On the Oric there is no such thing: There is only one area of video memory, and all the commands sent to the graphic chip are done by writing directly commands inside the video memory by using some reserved control codes different from actual bitmap data.

The main consequence is of course that this interferes with what is on the screen: You cannot have a byte on the screen that both represent something to display and be also a control code. It's either-or.

A corollary is also the reduction of available bits to represent visual data since some of the bit are used to identify Attributes.

As a general rule, any value in the 0 to 31 range has to be considered as an Attribute1, and any value above 127 is using the Inverse Video mode.

I will detail these later.

Monochrome graphics

If the byte value happens to not be an attribute, then it means it contains a displayable value - either a character ASCII code if you are in TEXT mode, or some bitmap representation if you are in HIRES - ultimately represented on screen as 6 pixels:
  • each 0 bit will be drawn using the PAPER (background) color
  • each 1 bit will be drawn using the INK (foreground) color
When the oric starts to display one of the 200 scanlines, the value of PAPER is always reset to BLACK, and the value of INK is always reset to WHITE.

So without doing anything special you can draw monochrome pictures in 240x200 resolution by using the default BLACK and WHITE colors.

Beast, by Twilighte
Beast, by Twilighte

The complications come when one wants to change the colors:)

Serial Attributes

I will now explain in details what is probably the most complicated part of the Oric way of doing things: The Serial Attributes.

Here is the list of all possible attributes:

Change Ink (foreground) color
0 Change INK to BLACK
1 Change INK to RED
2 Change INK to GREEN
3 Change INK to YELLOW
4 Change INK to BLUE
5 Change INK to MAGENTA
6 Change INK to CYAN
7 Change INK to WHITE
Character Set modifier
8 Use Standard Charset
9 Use Alternate Charset
10 Use Double Size Standard Charset
11 Use Double Size Alternate Charset
12 Use Blinking Standard Charset
13 Use Blinking Alternate Charset
14 Use Double Size Blinking Standard Charset
15 Use Double Size Blinking Alternate Charset
Change Paper (background) color
16 Change PAPER to BLACK
17 Change PAPER to RED
18 Change PAPER to GREEN
19 Change PAPER to YELLOW
20 Change PAPER to BLUE
21 Change PAPER to MAGENTA
22 Change PAPER to CYAN
23 Change PAPER to WHITE
Video control attributes
24 Switch to TEXT mode (60 Hz)
26 Switch to TEXT mode (50 Hz)
28 Switch to HIRES mode (60 Hz)
30 Switch to HIRES mode (50 Hz)

The reason these attributes are called "Serial", is that they are valid only on the scanline they are present (the frequency change is the exception), and only impact what is on their right.

Using these values, you should be able to achieve any possible trick known by Oric developer: Mixing character sets, changing the size of characters, having parts of the screen blink, change colors and display rasters, and mix and match different screen modes.

It's by using the Color Change attributes that you can get colors on your screen.

Frequency change

As you probably noticed on the previous table, the ULA can output pictures at 50hz or 60hz.

If no frequency change attribute is used, the system will keep using whatever frequency was used to display the last image.

Some of you have been playing on the Commodore 64 and Atari ST, writing values to the video registers while the image was being generated, changing frequency on the fly, resulting in fancy new video modes, distorted displays, border removal, or fancy hardware scrolling.

Unfortunately, when it encounters one of the video mode control code the ULA only seem to store the value internally and use whatever was there on the next frame.

Another difficulty - if one was trying to experiment with these fancy control codes - is that there is no vertical synchronization register available on the machine: You don't know where the electron beam is. 2

Paper and Ink color

Technically, a colored Oric picture is just a monochrome picture which happens to have the PAPER and INK values changed here and there.

Think of it like if you made a 2 colors picture on an Atari ST or Amiga, and then you used some interruption/Copper to change the color registers values at specific point in time: It would appear as a multi-color picture but bitmap wise it would still be stored as a 1 bit bitmap.

The way we achieve that on the Oric is by inserting color change attributes in the picture:
  • if the attribute value is between 0 and 7, then the current INK value is changed
  • if the attribute value is between 16 and 23, then it's the new PAPER value (minus 16)
Now of course that causes some problems, because you can only change one color at a time, and during that time you can't display graphics.

It is for this reason that that by default the oric does not make it possible to trace graphics in the 12 first pixels of the screen when colors are placed:

TEXT mode protected columns
TEXT mode protected columns

The text on the picture is starting two characters away from the left border3 simply to allow you later to change the color of the PAPER or INK without erasing what is already written on the screen:
  • 6 pixels (or one character) are used to define the color of the PAPER
  • 6 other pixels (or one character) are used for defines the color of the INK
The direct consequence of that, is that the effective resolution for a two-tone image (nonwhite and black) is limited to 228x200 pixels because of the 12 lost pixels on the left side.

HIRES mode protected columns
HIRES mode protected columns

On this picture the diagonal line does not reach the top left corner because of the CYAN ink and BLUE paper attribute changes.

This should also make it clear about what happens on the screen when we place an Attribute: The 6 pixels at this location will use the PAPER color4.

For aesthetical reasons, I give you an advice:

If you want to display nicer colored text try to put the INK attribute first, and then the PAPER attribute. The result is the same, except that the first column is black.
This way it look like if only ONE column is unusable.

You can do the same thing in HIRES, it reduces the shocking effect of graphics starting very far from the left of the screen.

Video Inversion

The bit 7 is all about video inversion.

7 6 5 4 3 2 1 0
I . . . . . . .

When the video inverse bit is set, the value on screen is shown in inverted colors, which means that each color component of the foreground and background color is inverted: BLACK (000) become WHITE (111), RED (100) become CYAN (011), etc...

Original Color Inverted Color

Using the Video Inversion makes it possible to considerably improve the quality of coloring, or hide some attribute changes which would otherwise look ugly5.

The video inversion can be used to obtain additional colors without having the constraints of the attributes placement: If you are drawing with RED and YELLOW colors you can invert some bytes to draw 6 pixels blocks using BLUE and CYAN instead.

This is often used in arcade games such as Magnetix or Ghost Gobbler to provide additional colors without having to use Attributes:

Ghost Gobbler
Ghost Gobbler

Here the game is using GREEN PAPER and BLUE INK to draw the game background and the maze walls, and by using the INVERSION you get the MAGENTA PAPER and the YELLOW INK to draw the moving elements.


A similar method is used here, with BLACK PAPER and YELLOW INK are used inverted to draw the WHITE and BLUE border elements.


As written earlier, there are more than one charset available, so we need to be able to select the one we want to use: You do that - again - by using the Serial Attributes system.

On the previous table, the values 8 to 15 are the ones we need: Using them we can select between the Alternate and Standard character set, but also enable the Double Size or Blinking display mode.

All you need to do is to make sure one of these Attribute value is present before the characters you want to effect, on the same line of the screen.

Here is what they look like in action:

Fun With Charset
Fun With Charset

Both charset are initialized during the boot sequence:
  • The normal charset is copied from the ROM to the RAM area
  • The alternate charset is procedurally generated by a ROM routine.

Alternate Characters

The Alternate Charset looks like a 2x3 blocs matrices, each bloc made of about 3x3 pixels6, organized the following way:

01 02
04 08
16 64

Just add the values to select the "pixels" you want to highlight, and add 32 to the result and write it to the screen.

If you want to draw a character with the top-left, middle-right, and bottom-left blocs activated, you have to display the character with the ASCII value of:

32+1+8+16 = 17

This can be used for generating a pseudo 79x817 graphical mode.

Double Height

Double height allows the video controller to display only one of the halves of a character with a vertical stretching effect.

Since the attributes never specify if you want to display the top or bottom part of the character, the ULA must decides itself.

The choices is based on the index of the text line being displayed:
  • If the number is EVEN it will display the upper part
  • if it's ODD it will be the lower part
If you want to scroll the screen, make sure you scroll them by a multiple of two else you will see all your texts displayed incorrectly every second frames...


The last effect is the blinking.

You cannot change the speed of the blinking, because it is based on an internal computation made by the ULA.

I suppose that tricking with 50hz and 60hz attributes will change the speed of a 5/6 or 6/5 ratio, but the only sure result is that your TV display will jump.

The only effect of blinking is to force foreground pixels (ink) to background when the blink is ON; the background color is never altered by a blinking effect.

Hybrid video modes

On the Oric, it is not really possible to achieve hi-tech tricks for doing hardware-scrolling, fullscreen, using more colors, or even display pixels at the same locations than attributes.

I hope that the future will prove me I was wrong, but for the moment take this as the Truth8.

Anyway, it's possible to mix video modes.

After you start your Oric, enter the following line of code and press RETURN:


Then type the following key combination:


you will see something like this:

Example of mixed mode
Example of mixed mode

When you type ESC+], you just put a 50 Hertz graphics attribute at the position under the cursor.

When the ULA reads this character, it switches to the HIRES drawing mode.

Then at some point toward the middle of the screen it encounters some values interpreted as a 50 Hertz text attribute and reverts to TEXT mode.

The trick is to find a way to move freely between HIRES and TEXT while avoid the traps and sinkhole laying around in memory.

In order to mix and match video modes, all you can do is to use attributes at the location you want to force the ULA to start reading information from where you want it to, which means that you need to know the memory layout of both video modes to avoid conflicts.

The ULA will fetch the next byte to interpret based on the current pixel position on screen, and the current graphic mode:
  • HIRES: Current Byte = PEEK(#A000+(Y*40)+(X/6))
  • TEXT: Current Byte = PEEK(#BB80+((Y/8)*40)+(X/6))
Knowing this formula, you can easily predict where the next byte will be fetched from9.

Let practice a bit.

Advanced examples

Imagine you want to display colorful text, changing the color each pixel line instead of each character line.

The idea is simple, all you have to do is on each line of the screen:
  • Switch to HIRES
  • Change the INK or the PAPER (or both)
  • Switch back to TEXT

You could do that with this small Basic10 program
FOR Y=0 TO 24
: POKE #BB80+(Y*40)+0,30 ' Switch to HIRES
FOR Y=0 TO 199
: POKE #A000+(Y*40)+1,Y AND 7 ' Change INK color
: POKE #A000+(Y*40)+2,26 ' Switch to TEXT
The trick is to remember that as soon as you change resolution, the next byte will be read from the other memory area

If everything goes well, you should get something similar to that:

Text mode with Hires raster
Text mode with Hires raster

You probably noticed that some characters were corrupted.

The reason is simply that when writing the INK and TEXT attributes in memory, around the line 100 the address collided with the character set area.

The address of theses CharSet tables are $B400 for the standard charset, and $B800 for the alternate charset, which happens to be right in the middle of the memory used by HIRES display.

Now, some simple calculations for knowing how many HIRES scan lines it is possible to display without interfering with the CharSet area:
$B400 (CharSet base adress) - $A000 (HIRES screen base adress) = 5120 bytes
5120 / 40 (size of a scan line) = 128 lines.

128 lines, is exactly where the screen started corrupted on the first mix screen example screenshot.

The important thing to realize is that because a character representation is 8 bytes long they actually fit nicely laid out in scanlines. Each line of the screen overlaps the definition of 40/8 = 5 characters.

What this means, is that if you know which bytes of the screen you are going to patch with attributes, then you know which characters are going to be corrupted.

In this example, we are writing to the offsets 1 and 2 of each scanline, which means we are altering two lines of every fifth character: A, F, K, P, U, Z, etc... out of 96 characters, 76 remain usable normally.

And finally a last example that shows that a HIRES window can be inserted in a standard TEXT mode.

Text mode with Hires window
Text mode with Hires window

Potential applications could be Role Playing Games, documentation or HTML viewers, or really any application where you want to combine the speed of the TEXT display, with the graphical capabilities of the HIRES mode.


For a long time, the most advanced oric graphics were still using very basic graphics, were monochromatic, or were suffering for heavy attribute color fighting when things moved around.

A typical example of Oric game, would be Breakout:

Super Advanced Breakout (Tansoft 1983)
Super Advanced Breakout (Tansoft 1983)

This game plays well, it's smooth and fast, but it's not particularly pretty.

What the designer did is to set the two first columns of the screen with RED INK and YELLOW PAPER attributes, and then use video inversion to get the BLUE and CYAN bricks.

When he was working on his Oric port of the Pulsoids game Jonathan Bristow (aka Twilighte) wanted to achieve something that would look a lot more similar to the original graphics of the Commodore 64 game.

After a bit of brainstorming he came with the idea of Alternate Inverted Colors, and gave us that game:

Pulsoids (Twilighte 2002)
Pulsoids (Twilighte 2002)

There are obviously many more colors and patterns on the screen compared to the original Breakout game11.

What Twilighte did is similar to the method used on Breakout, but instead of using only one combination of main colors and inverted colors for the entire screen, he decided to use two sets of color combinations, inverted every second line.

In both cases the paper is set to BLACK, so the only change is the INK, which alternates between YELLOW and CYAN, which gives us the following organization:

Original Color Inverted Color

Here is a zoomed out fragment of Pulsoids graphics where this representation of colors is easy to see:


By carefully using video inversion on some of the segments, he was able significant extend the number of recognizable bricks.

Since then, there are been quite many games released using variants of this methods, with the same or with different color combinations depending of the context.

Here comes the gallery!

Stormlord (Twilighte 2010)
Stormlord (Twilighte 2010)

Stormlord features some large sprites and bitmaps, and like Pulsoids used the BLACK color for the paper on all lines.

Impossible Mission (Twilighte 2010)
Impossible Mission (Twilighte 2010)

Impossible Mission shown it was working also quite well with much smaller and detailed graphics, including complicated animations.

SkoolDaze (Chema 2012)
SkoolDaze (Chema 2012)

Skool Daze shows brilliantly that using AIC also provides advantages when you want to scroll the game area - as long as you do it on a multiple of 6 pixels horizontally - since there are nothing in particular to do with the attributes except making sure to not scroll them away with the picture itself.

Gamejam 2015 (Dbug 2015)
Gamejam 2015 (Dbug 2015)

The Global Game Jam 2015 entry was originally supposed to have transitions between the various locations depending of the transportation method you choose.

This screenshot shows an Oslo metro station, with the animated advertisement screens scrolling up and down to show new ads.

Blake's 7 (Chema 2017)
Blake's 7 (Chema 2017)

And finally, the latest point'n click game from Chema, Blake's 7, still in production today, but which hopefully be released in 2017!

If you want to learn more about AIC, I recommend you just look closely to screenshots of existing AIC games, using a 6 pixels wide grid to see where the blocks of pixels start and end.

Hopefully this long article provided some answers to questions you had, and maybe gave you some ideas about designing the next Oric killer application!

1. As well as the same value with the bit 7 set - they are just video inverted attributes.
2. That being said, there is a hacky way to get this information: If you connect the vertical synchronization pin of the RGB output connector to the input pin of the TAPE connector you are then able to detect the vertical sync impulse by reading the right registers of the VIA.
3. The greyed out area is not normally visible, it's just for illustration purpose
4. If the attribute was a PAPER color change, the new PAPER color is immediately used
5. Unfortunately with default screen colors (BLACK and WHITE) the video inversion is useless: We got WHITE and BLACK....
6. Except the middle line that is only 3x2 pixels 3+3+3 does not fit in 8 scanlines
7. You lose one column for the attribute, and can be 79x84 if you use the status line
8. If you manage to do things like that, I will be very happy!
9. The fact that the address is always computed and not only incremented explains why it is not possible to do hardware scrolling.
10. Thanks to JiBé who spotted a mistake
11. The size of the play area is not a limitation of the method, it could have easily been using the entire screen area
comments powered by Disqus

Coverity Scan Build Status