SOMETHING ABOUT INTERRUPTS by Mark van de Boer
Originally published in ST NEWS Volume 1 Issue 5, launched on
October 5th 1986.
On the ST there are some different types of interrupts. In this
piece of writing I will discuss some ways to program timed
interrupts. Maybe some other time I will discuss the other kinds
of interrupts.
But first another problem arises: In which language should I
program interrupts? There are two languages suitable for the
job, C and 68000 machine language. Advantages of C: Easier and
faster to write programs in. Disadvantages of C: Not as fast as
machine language and also you need to know which overhead is
produced by the C-compiler when translating a function. There is
also no easy way in C to execute the RTE instruction (ReTurn
from exception). I will give an example of a C-interrupt routine
later. Advantages of machine language: Fast and more efficient.
Disadvantages of machine language: Harder to understand than C
and it also takes more time to write a routine than in C.
Personally I prefer machine language to program interrupts
because I think that the disadvantages of C are too big. By the
way: When you have written an interrupt routine in machine
language it is still possible to call this routine from a
program written in C. This can be done by linking the assembled
machine language routine together with your compiled C program.
Now for the 'real' work, how to get the machine executing your
interrupt routine. Two types of timed interrupts can be
programmed on the ST: start your own timer and synchronize your
routine with the system interrupt.
Starting your own timer: First I will show a little program from
which I will explain what to do to get the interrupt running.
*
* Interrupt routine written in 68000
*
_interrupt:
* always put an underscore in front of the interrupt routine
* otherwise it is impossible to call this routine from C.
* C compilers put an underscore before every variable or
* function
addq.w #1,_var * some variable to count interrupts
* between here and the RTE-instruction can be a lot of
* instructions, including privileged ones, because an inter-
* rupt is always executed in supervisor mode.
bclr #4,$fffffa11 * interrupt no longer in service
rte * ReTurn form Exception (interrupt)
/* now some C code */
#include <osbind.h>
long int var=0;
insttimer()
{ Xbtimer(3,0x6,0xff,interrupt);
/* 3: timer D
0x6: value of control register
0xff: value for data register
interrupt: address of interrupt routine
*/
}
main()
{ insttimer(); /* start timed interrupt */
Cconin();
printf("I executed %d interrupts",var);
Jdisint(4); /* disable interrupt */
Cconin(); /* give chance to read text */
}
Xbtimer starts the desired timer and installs the interrupt
routine. For more information about Xbtimer and its parameters,
refer to page 217-218,47-48-49,272,81-82. Never forget to clear
the according bit in the interrupt-in-service register, or your
interrupt will occur only once.
(Editorial comment: The pages that Mark refers to, are in "ST
Intern" from Data Becker).
Synchronizing a routine with the system interrupt: This is a
very simple thing to do and it can be done very easily from C.
On the ST NEWS disk you'll find another C program ("IRQ.C")
that does the job...
Ohh, uhh, yes, you might say if you had a look at it, but you
shouldbn't panic.
In the ST a VBL (Vertical BLank) routine is executed every 1/60
th of a second. It is called vertical blank because at the time
when the interrupt occurs your ST has drawn all lines on the
screen from top to bottom. During this VBL interrupt some things
which are essential for your ST's behavior are done. After
having done this the ST checks a table which contains eight
addresses of subroutines (pointers to functions). The 4-byte
address of this table is at address $456 and address $454
contains the maximum number of routines in the table. There are
two kinds of entries in this table: entries that contains zero
and the others, containing non-zero. If an entry (which are of
course 4 bytes) is zero then it won't be executed, however if an
entry is non zero then a Jump to SubRoutine is executed to the
address at that entry.
Well, now you'll understand what the synchronize function does,
don't you? It searches for a free entry in the table, if it
found one it installs the routine and sets the variable index to
the number of the entry. If it didn't find one it will tell you
and abort the program (Of course there is a solution to this
problem but it is very unlikely that there are no free entries
in the table, so I won't discuss this).
The rmsync function just sets the entry at which the address of
your routine stood to zero, so it won't be executed anymore.
Well, that's it for this time. Maybe I will tell you something
more about the ST in forthcoming editions of ST NEWS, but that
also depends on the chief-editor, designer, writer etc., also
called Cronos. So if you liked it, let him now, and he can
contact (sooiks) me. Nano nano.
(Editorial comment: The C-Compiler Mark used was the Digital
Research C-Compiler of the Atari Developer's Package).
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.