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 1 systeminitializationdmainterrupts

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

AspectCost
CPU~50 cycles
Memory~30 bytes + 4 bytes for saved state
LimitationMust 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

BitNamePurpose
15SET/CLR1=set bits, 0=clear bits
9DMAENMaster DMA enable
8BPLENBitplane DMA
7COPENCopper DMA
6BLTENBlitter DMA
5SPRENSprite DMA
4DSKENDisk DMA
3-0AUDxENAudio channels 0-3

Common DMACON Values

ValueBits setEnables
$83a015, 9, 8, 7, 5Master + Copper + Sprites + Bitplanes
$838015, 9, 8, 7Master + Copper + Bitplanes (no sprites)
$83e015, 9, 8, 7, 6, 5Master + Copper + Sprites + Bitplanes + Blitter
$87e015, 10, 9, 8, 7, 6, 5Above + BLITHOG (Blitter takes all CPU cycles when running, faster but starves CPU)
$83ef15, 9, 8, 7, 6, 5, 3-0Above + 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