Skip to content

System Takeover

Disable AmigaOS interrupts and DMA to take full control of the hardware. Required for bare-metal game programming.

Taught in Game 1, Unit 1systeminitializationdmainterrupts

Overview

To program the Amiga’s custom chips directly, you must first disable AmigaOS. This means turning off all interrupts and DMA channels, then selectively enabling only what your program needs. Without this, the OS will interfere with your hardware access.

Code

; =============================================================================
; SYSTEM TAKEOVER - AMIGA
; Disable OS and take control of hardware
; Taught: Game 1 (Signal), Unit 1
; CPU: ~50 cycles | Memory: ~30 bytes
; =============================================================================

CUSTOM      equ $dff000

; Register offsets from CUSTOM base
DMACON      equ $096            ; DMA control
DMACONR     equ $002            ; DMA control read
INTENA      equ $09a            ; Interrupt enable
INTENAR     equ $01c            ; Interrupt enable read
INTREQ      equ $09c            ; Interrupt request

            section code,code_c

start:
            lea     CUSTOM,a5           ; Custom chip base in A5

            ; === Save system state (for clean exit) ===
            move.w  DMACONR(a5),d0
            or.w    #$8000,d0           ; Set bit 15 for later restore
            move.w  d0,saved_dmacon

            move.w  INTENAR(a5),d0
            or.w    #$8000,d0
            move.w  d0,saved_intena

            ; === Disable everything ===
            move.w  #$7fff,INTENA(a5)   ; Disable all interrupts
            move.w  #$7fff,INTREQ(a5)   ; Clear pending interrupts
            move.w  #$7fff,DMACON(a5)   ; Disable all DMA

            ; === Your game setup here ===
            ; Install copper list, set up sprites, etc.

            ; === Enable only what you need ===
            move.w  #$83a0,DMACON(a5)   ; Master + Copper + Sprites + Bitplanes

            ; ... game code ...

            ; === Restore system before exit ===
            move.w  #$7fff,DMACON(a5)
            move.w  #$7fff,INTENA(a5)
            move.w  saved_dmacon,DMACON(a5)
            move.w  saved_intena,INTENA(a5)

            rts

saved_dmacon:   dc.w    0
saved_intena:   dc.w    0

Trade-offs

Aspect Cost
CPU ~50 cycles
Memory ~30 bytes + 4 bytes for saved state
Limitation Must restore before returning to OS

When to use: Every Amiga game or demo that accesses hardware directly.

When to avoid: Programs that want to coexist with the OS (use system-friendly methods instead).

How DMACON/INTENA Work

These registers use a SET/CLEAR mechanism controlled by bit 15:

  • Bit 15 = 0: CLEAR the specified bits (disable)
  • Bit 15 = 1: SET the specified bits (enable)
move.w  #$7fff,DMACON(a5)   ; Clear bits 0-14 (disable all)
move.w  #$83a0,DMACON(a5)   ; Set bits 5,7,8,9,15 (enable selected)

DMACON Bit Reference

Bit Name Purpose
15 SET/CLR 1=set bits, 0=clear bits
9 DMAEN Master DMA enable
8 BPLEN Bitplane DMA
7 COPEN Copper DMA
6 BLTEN Blitter DMA
5 SPREN Sprite DMA
4 DSKEN Disk DMA
3-0 AUDxEN Audio channels 0-3

Common DMACON Values

Value Bits set Enables
$83a0 15, 9, 8, 7, 5 Master + Copper + Sprites + Bitplanes
$8380 15, 9, 8, 7 Master + Copper + Bitplanes (no sprites)
$83e0 15, 9, 8, 7, 6, 5 Master + Copper + Sprites + Bitplanes + Blitter
$87e0 15, 10, 9, 8, 7, 6, 5 Above + BLITHOG (Blitter takes all CPU cycles when running, faster but starves CPU)
$83ef 15, 9, 8, 7, 6, 5, 3-0 Above + all four audio channels

The bit-15 SET/CLR protocol means a single value writes only the bits you want to change:

  • Write $0001 → clears AUD0EN (disables audio channel 0). Other bits unaffected.
  • Write $8001 → sets AUD0EN (enables audio channel 0). Other bits unaffected.
  • Write $7FFF → clears bits 14-0 (disables everything). Atomic full-disable.
  • Write $BFFF → sets bits 14-0 (enables everything including reserved bits — usually wrong).

Saving and restoring exception vectors

For thorough takeover (especially on 68010+ machines that may have a relocated vector base via VBR), save and restore the exception vectors you change. AmigaOS uses level-3 (VBlank) and level-6 (CIA timers) interrupts; if your handlers replace those, save the old vectors before installing yours and restore on exit.

; Save the level-3 vector (VBlank IRQ, autovector at $6c)
        move.l  $6c.w,saved_vbl_vector

        ; ... install our handler ...
        move.l  #my_vbl_handler,$6c.w

        ; ... game runs ...

        ; Restore on exit
        move.l  saved_vbl_vector,$6c.w

On a plain 68000 the vector table is fixed at $0–$3FF, so direct address writes work. On 68010+ with a movable VBR, fetch VBR first via MOVEC.L VBR,A0. Most Amiga games target 68000 and skip the VBR step.

Patterns: VBlank Game Loop, Copper List Basics

Vault: Commodore Amiga | Amiga Chipset