General Information#

Author: David Plotkin
Language: ACTION!
Compiler/Interpreter: ACTION
Published: Antic July 1984

Interrupts in ACTION#

Synopsis
This article discusses advanced programming techniques using the ACTION! language. To use the accompanying listings, you must have the ACTION! cartridge from Optimized Systems Software.

An "interrupt" takes place in a computer system whenever one process takes precedence over a process that is being executed. It interrupts the lower-priority process so that it (the interrupt) can be executed first. Several interrupts are available on the Atari computers, including the display-list interrupt (DLI), the vertical-blank interrupt (VBI), and the system-timer interrupt, which was discussed in the January issue (Antic, "Page Flipping!" P. 34).

Before ACTION! came along, you had to be able to program in machine language to use these interrupts. Clinton Parker, ACTION!'s author, may have envisioned that ACTION! programmers would continue to use machine code to write interrupt routines, installing blocks of machine-language codes generated by their assemblers into their ACTION! programs. But ACTlON! is so fast that you call actually write a VBI or a system-timer interrupt in this high-level language, which is much easier than writing it in machine language.

Unfortunately when an ACTION! VBI interrupts an ACTION! program, the two use the same space in memory to hold temporary math variables for calculation. Because of this, the interrupt routine can alter the variables from the interrupted routine. As a result, results can be quite unpredictable.

Mike Fitch of Optimized Systems Software (OSS), ACTION!'s publisher, has solved this dilemma with two short machine-language routines that save the contents of the temporary math registers to the stack at the beginning of the interrupt, and then restore them just before the interrupt ends. Mike calls these routines SAVETEMPS and GETTEMPS.

You use the DEFINE command to assign machine-language code blocks to SAVETEMPS and GETTEMPS. The accompanying ACTION! program demonstrates the use of GETTEMPS and SAVETEMPS in a VBI. It also produces an interesting effect on the screen. These routines are just what you need if you want to use interrupts written in ACTION!

David Plotkin is a chemical engineer with Standard Oil Company of California and an avid game programmer.

MODULE; VBI DEMO FOR ANTIC
DEFINE RTI="$40",
       PHA="$48",
       PLA="$68",
       TXA="$8A",
       TAX="$AA",
       TYA="$98",
       TAY="$A8",
       JMP="$4C",
       XITVBV="$E462",

SAVETEMPS="[$A2 $07 $B5 $C0 $48 $B5
    $A8 $48 $B5 $A0 $48 $B5 $80 $48  
    $CA $10 $F1 $A5 $D3 $48]",
GETTEMPS="[$68 $85 $D3 $A2 $00 $68
    $95 $80 $68 $95 $A0 $68 $95 $A8
    $68 $95 $C0 $E8 $E0 $08 $D0 $EF]"
CARD SDLST=560,VDSLST=512,
               VVBLKD=$224
BYTE NMIEN=$D40E,COLBK=$D01A,
     WSYNC=$D40A,COUNT=[0]
BYTE ARRAY DLIST
BYTE ARRAY CLRS(0)=[64 66 68 70 72 74
     72 70 68 66  64  66  68  70  72
     74  72  70  68  66  64  66  68
     70 72 74 76 ]

PROC DLINT(); a DLI written in ACTION!
    BYTE DUM
    [PHA TXA PHA TYA PHA]
    IF COUNT=26 THEN DUM=0
    ELSE DUM=CLRS(COUNT) FI
    WSYNC=1
    COLBK=DUM
    COUNT=COUNT+1
    IF COUNT=27
    THEN COUNT=0
    FI
    [PLA TAY PLA TAX PLA RTI]

PROC INIT7()
    GRAPHICS(7)
    SETCOLOR(0,2,10)
    SETCOLOR(1,5,12)
    SETCOLOR(2,0,0)
RETURN

PROC DLSETUP(); custom Display List
    BYTE I
    INIT7()
    NMIEN=$40
    DLIST=SDLST  
    VDSLST=DLINT
    FOR I=30 TO 40
    DO DLIST(I)=141 OD
    FOR I=42 TO 54 STEP 2
    DO DLIST(I)=141 OD
    FOR I=57 TO 72 STEP 3
    DO DLIST(I)=141 OD
    FOR I=76 TO 84 STEP 4
    DO DLIST(I)=141 OD
    NMIEN=$C0
RETURN

PROC ROTATE(); the VBI routine
    BYTE HOLD,CTR,CNTR
    SAVETEMPS; save the temp registers
    HOLD=CLRS(26); save the last element
    FOR CTR=0 TO 25; the loop
    DO CNTR=25-CTR; to count backwards, Action! has no STEP-1 statement
    CLRS(CNTR+1)=CLRS(CNTR) OD; rotate
    CLRS(0)=HOLD; put the last element into the first
    GETTEMPS; get the temp registers
    [JMP XITVBV]; exit the VBI

PROC VBINST(); install the VBI
    NMIEN=0; turn off the interrupts
    VVBLKD=ROTATE; vector to PROC ROTATE
    NMIEN=$40; turn the interrupts back on
RETURN

PROC DJD(); the driver routine, named for a famous computer genius
    BYTE CRSINH=752
    VBINST(); install the VBI
    DLSETUP(); set up the Display List
    CRSINH=1
    PRINTE()
    PRINTE("Áîôéã Interrupts in ACTION!")
    PRINT("           by DAVID PLOTKIN")
    DO OD; an endless loop...
RETURN