Step31: VBL and IRQ

Let’s talk about the basic structure of a good program on Amiga. Usually games and demos are fully sequenced using the display. As we already saw before, the Amiga is able to synchronise code with the electron beam. When a screen display is done, electron beam will go from bottom of screen to top of screen. Display of next screen then begin. This is called the «VBL» («Vertical Blank Line«) on Amiga. (Aka «VBI», «VBLANK»).

On amiga, there is a complete system of «interruptions» (called «IRQ»). You can ask amiga to wake up a part of code when an event occurs. The VBL is one of these events.

So basically, the code structure of a demo is:

—————

(Start of demo)
– Doing some init
– Define VBL interrupt, associate code to execute
– Infinit loop (waiting for mouse for example).
(end of demo)

– Code to execute when VBL interrupt is called.

—————

The VBL is the good time for changing things in relation to the display. At that moment, the electron beam is offscreen, so you can safely do some stuff. But remember, you also have the copper list to perfectly synchronise your registers modifications with the display. So why is the VBL really useful ?

In fact, the VBL is synchronised with the video display. Pal amiga display rate is 50Hz. Ntsc is 60Hz. That means you’ll have 50 VBL per seconds. That also means you have 20ms between two VBL. If your code is fast enough to be executed in less than 20ms, then your demo will be smooth. In french we say «à la frame» (means, «in the frame» , «frame» = one screen display, 50 screens per seconds, 50 FPS).

Let’s take a reak example:

—————

(Start of demo)
; Doing some init

; Define VBL interrupt, associate code to execute
LEA $DFF000,A6
MOVE.W #$c020,$9A(A6) ; Interrupt enable bits (clear or set bits). INTENA
; This enable : Set VBL irw
MOVE.L #MYIRQ,$6C ; level 3 – vector $6c : Vbl/Copper/Blitter
; infinit loop (waiting for mouse for example).
WAIT:
BTST #6,$BFE001
BNE WAIT
(end of demo)

;Code to execute when VBL interrupt is called.
MYIRQ:
MOVEM.L D0-D7/A0-A5,-(SP) ; Save all register because interupt will «interrupt»
; main code. Not much in this case (wait for mouse).
….. ; Do your code here
MOVEM.L (SP)+,D0-D7/A0-A5
RTE
—————

«RTE» is like «RTS» (Return from subroutine) but for interuptions.

In my code, I’m not using the VBL interrupt, but the one just after, which is the «Copper» interrupt. In fact, the register INTENA is set directly from the copper list. with this line:
DC.L $009C8010

This will generate a level 3 interrupt and call the code.

Here is a full interruption code:

—————
IRQ:
MOVE.L D0,-(SP) ; Save D0, because we think this is the only register that need to be save.
MOVE.W $DFF01C,D0 ; Verify which interript have been raised.
AND.W $DFF01E,D0
BTST #4,D0 ; Test copper interrupt
BEQ ENDIRQ

; Do here you computing

MOVE.W #$10,$DFF09C ; Clear interrupt flasg before exiting
ENDIRQ:
MOVE.L (SP)+,D0
RTE
—————

So here is how a demo (or a game) is structured. You can have the same result by testing the value of electron beam in the infinite loop (using the $DFF006 register), but using interruptions is much more clever.

Cool demo of that time

Vision – Megademo IV – Amiga Demo

Part3 is very nice (starting a 12′). The module contain classic house/acid samples of that time.

Step30 Step32