Interrupts

by Ciaran McCreesh
Created: 28th November 1999
Last Modified: 28th November 1999

This page will explain interrupts in mode im1. It will also explain the theory behind greyscale.

What are Interrupts?

It may come as a surprise to you that in the middle of your program the CPU might suddenly start executing some completely different code before returning to your program. This does in fact happen about 200 times a second (the exact value depends on how much power is left in your batteries - I get 210 times a second with fresh alkaline batteries and as low as 150 times a second with nearly flat batteries). You may have noticed the run indicator (the moving dots at the top right of the screen) is still visible when you run an assembly program. The run indicator is not hardware based - it is one of the things that is done by the calculator during the time it is not running your program.

Every 200th of a second a signal is sent to one of the pins on the processor by another mini-circuit within the calculator. The pin's name is IRQ (this should have a line over it, your browser may not support the CSS I used to do this), which is short for 'Interrupt Request'. When the CPU receives this signal it completes the current instruction then calls memory location $38 if interrupts are enabled. You can disable interrupts by using the instruction di (certain ROM calls won't work after this) and enable them the instruction ei.

As you might know, memory locations $0000 to $7fff are in the ROM, so you can't modify them. So why not just disable interrupts at the start of the program since they waste time? Well, although $38 is in ROM part of the code contained shortly after that checks a memory location in the RAM and if it is a certain value it calls memory location $d2fe. As there are 200 bytes of unused memory starting there you can create your own interrupt code.

What Can They Do?

The most common use of interrupts is to create greyscale (American: grayscale) graphics. The basic idea of greyscale is simple. Normally the screen is drawn according to the memory starting at $fc00 and going through to $ffff. However, we can actually change this to a certain extent.

There are a series of instructions to do with something called ports. The details of all these instructions can be found in the instruction reference under IO Instructions. In the mean time I will explain what the more common forms do.

A port is how the processor communicates with the outside world. There are a number of these ports on the ti86 - the z80 allows a potential 256 different ones, however the ti86 only uses the first few (the Zilog z80 Technical Data contains details of the hardware side of this if you're interested). The ports on the ti86 are used for a wide variety of jobs. The most obvious one is port 7 which controls the link port. Other uses include port 2, which sets the contrast, and port 1, which allows direct reading of the keypad. The port used to change the screen offset is port 0.

Port 0

Writing a value to Port 0 changes the memory location that the screen is taken from. The location is determined using the following formula:

Location = (Value Out Of Port 0 + $c0) × $100

The value written to Port 0 must be between $00 and $3c. The default value is $3c, which makes the screen point to $fc00. To set the value to something else, use out (0),a, which sends the value of a out of Port 0.

Greyscale

Normally the screen can display two 'colours' - 'Black' (1) and 'White' (0). With greyscale we can display 4, 'Black', 'Dark Grey', 'Light Grey' and 'White'. It is even possible to display 8 colours, but this uses a lot of memory and slows the program down significantly. How does this work, since the screen can only display two colours at once? Using interrupts we change the screen offset quickly between two areas of memory. This provides three 'colours', 'Black' (on), 'White' (off) and 'Grey' (half on). To get four colours all we have to do is double the time the screen spends at one of the two memory locations.

Diagram of the four greyscale colours

The second memory location used starts at $ca00. It is used by the calculator to store the graph screen, but it can be erased as long as you tell the calculator to redraw the graph screen when it is next required. The code to do this is set graphdraw,(iy + graphflags), the equates are defined in the standard include file.

The next page contains a demonstration greyscale routine along with how to use it.