Skip to content
Techniques & Technology

Memory Mapping

Addresses for everything

Memory-mapped I/O places hardware registers at specific addresses, allowing software to control graphics, sound, and input by reading and writing memory locations.

commodore-64nintendo-entertainment-systemcommodore-amigahardwareprogramminglow-level

Memory mapping assigns specific memory addresses to hardware registers, allowing programs to control peripherals through normal load/store operations rather than special I/O instructions. This approach defined how programmers interacted with 8-bit and 16-bit hardware.

Examples

Commodore 64:

  • $D000-$D3FF: VIC-II graphics chip (47 registers + mirrors)
  • $D400-$D7FF: SID sound chip (29 registers + mirrors)
  • $D800-$DBFF: colour RAM (1 KB, 4-bit-wide chip)
  • $DC00-$DCFF: CIA#1 (keyboard, joystick, IRQ source)
  • $DD00-$DDFF: CIA#2 (serial bus, RS-232, NMI source, VIC bank select)

NES:

  • $2000-$2007: PPU registers (mirrored every 8 bytes through $3FFF)
  • $4000-$4017: APU and I/O ($4014 = OAMDMA, $4016/$4017 = controllers)

Amiga:

  • $DFF000-$DFF1FE: custom chip registers (Agnus, Denise, Paula, Copper, Blitter)
  • $BFE001: CIA-A PRA (joystick fire buttons, parallel port)
  • $BFD000: CIA-B (serial port, disk control, mouse)

Memory-mapped vs port-mapped I/O

Most 8-bit and 16-bit systems use memory-mapped I/O — hardware registers live in the same address space as RAM, accessed by normal LDA/STA (or equivalent). The 6502, 6510, 6809, and 68000 have no separate I/O instructions, so memory mapping is the only option.

The Z80 is different: it has dedicated IN and OUT instructions that access a separate I/O port address space (256 ports on a basic Z80, 65,536 with the indirect form). The ZX Spectrum, Amstrad CPC, MSX, and Z80-based arcade boards all use port-mapped I/O for hardware control. Memory-mapped accesses to the same hardware on those systems would require dedicated address decoding and aren’t typically used.

Hybrid systems (like Sega Master System with Z80 + memory-mapped VDP) place graphics in memory space but sound in port space, mixing both styles.

The C64’s page of I/O

Commodore’s Programmer’s Reference Guide draws the 4K at $D000-$DFFF as a single block of I/O: 1K each for the VIC-II, the SID and colour RAM (“1K Nybbles” — the chip is four bits wide), 256 bytes each for the two CIAs, and two “open I/O slots” at $DE00 and $DF00 that the manual says were “tentatively designated for enabling the Z-80 cartridge (CP/M option) and for interfacing to a low-cost high-speed disk system”. The chips do not fill their blocks — the VIC-II has 47 registers, the SID 29 — so the rest of each 1K is mirrors.

The same 4K is also where the character generator ROM lives, and what the processor sees there depends on the CHAREN bit of the 6510’s port at $01: set “as is normal”, the I/O appears; cleared, “the character ROM appears in the processor address space, and the I/O devices are not accessible”. Memory-mapped I/O on the C64 is therefore one layer of a bank-switched map, not a fixed feature of the address.

Programming Model

; C64: Set border colour to black
LDA #$00
STA $D020    ; Border colour register

; C64: Set volume
LDA #$0F
STA $D418    ; SID volume register

Advantages

  • Consistent programming model
  • Works with all CPU instructions
  • No special I/O instructions needed
  • Debuggers can monitor register access

See also

Not yet fact-checked. This entry was drafted by an AI and nobody has verified it. The dates, figures and technical details may be wrong. Use it to find your bearings, then confirm anything that matters against a primary source.