Skip to content

Instantly share code, notes, and snippets.

@drhelius
Last active June 23, 2021 13:11
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drhelius/3394856 to your computer and use it in GitHub Desktop.
Save drhelius/3394856 to your computer and use it in GitHub Desktop.
GameBoy Color DMA-Transfers
GameBoy Color DMA-Transfers v0.0.1 13.04.2000/GPZ-HIT
-------------------------------------------------------------------------------
"old" DMA Transfer (aka 'OAM-DMA')
----------------------------------
source: - anywhere from $0000 to $dfff
- must be page-aligned
destination: - always OAM-Ram at $fe00 - $fe8f
length: - always 4*40 (=160 / $a0) bytes
- when cpu speed is 2x, transfer speed is also 2x
- transfer takes 671 cycles (160 microseconds)
rDMA $FF46 - source LSB
CAUTION:
- dma should be executed during v-blank period
- no memory except for HRAM is available for the cpu while DMA is in progress,
the common method is to place this routine in HRAM:
dma:
ld a,$c0 ; oam-buffer is at $c000
ld [rDMA],a
ld a,$28 ; wait until DMA completes (160 microseconds)
.lp
dec a
jr nz,.lp
ret
"new" DMA Transfer
------------------
source: - from $0000 to $7fff and $a000-$dfff
- must be page-aligned
destination: - always in VRAM at $8000-$9fff
- must be page-aligned
length: - can be set in 16-bytes increments (ie, its ALWAYS n*16 long),
(1*16)=$0010 to (128*16)=$0800 bytes
- DMA speed is constant regardless of CPU-Speed
- cpu is halted during dma transfer
- transfer takes 220+n*7,68 microseconds (1x speed)
110+n*7,68 microseconds (2x speed)
- has 2 different modes:
1) Horizontal blanking DMA (aka 'HDMA')
- transfers 16 bytes at each horizontal blank
- can be stopped/restarted at each h-blank period
2) General Purpose DMA (aka 'GDMA')
- can not be stopped or suspended once started
rHDMA1 $ff51 bit 7-0 bit 7-0 of Source MSB
rHDMA2 $ff52 bit 7-4 bit 7-4 of Source LSB
bit 3-0 unused (set to 0)
rHDMA3 $ff53 bit 7-5 unused (set to 0)
bit 4-0 bit 4-0 of Destination MSB
rHDMA4 $ff54 bit 7-4 bit 7-4 of Destination LSB
bit 3-0 unused (set to 0)
rHDMA5 $ff55 bit 7 DMA Mode / Control
read:
0 : DMA in progress
1 : DMA completed
write:
- after set to 0, GDMA starts
- after set to 1, HDMA starts at next h-blank
- once started, HDMA can be stopped at next
h-blank by setting this bit to 0
bit 6-0 length (number of 16-byte blocks - 1)
- amount of bytes transferred is (n+1)*$10
CAUTION:
- don't switch ROM banks if DMA source is in the range of $4000-$7fff
- don't switch ROM banks if DMA source is in the range of $d000-$dfff
- don't switch VRAM banks until DMA has completed
- halt can not be used while a DMA is in progress
- dma must have completed before another dma is started or registers are
altered
- display must be enabled for a HDMA transfer taking place
- GDMA is only reliable during v-blank when display is enabled
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment