What precautions should I use when doing Sprite DMA ?

In order to do a sprite DMA you have to have a sprite table with address $xx00. (x = don't care) Depending on the address of this sprite table you have several options:

Sprite table not in video RAM ($8000-$9fff) - Most games do not put their sprite table in video RAM but rather usually use low RAM ($c000-$dfff). The reason for this is because you can write to low RAM at any time but video RAM is picky about writes when the screen is on.

When using sprite DMA ($ff46) with a sprite table that is not in video RAM, the code which performs this DMA function must be located in high RAM ($ff80-$fffe) because, except for video RAM, all other memory areas are disabled. The duration of sprite DMA is ~160 (80 in double speed) microseconds.

In order to do this you have to copy a small routine to high RAM containing the DMA command, a small delay loop, and a RET instruction to return to the main routine that called it. Interrupts MUST be disabled during non-video RAM sprite table DMAs. Example assembly code (rDMA=$ff46):

; $c000 ~ c09f --> OAM

        ld      a,$c0

        ld      [rDMA],a

        ld      a,40

.loop:

        dec     a

        jr      nz,.loop

        ret



Sprite table in video RAM ($8000-$9fff) - If you choose to put your sprite table in video RAM then you can perform sprite DMA using code in ROM (no need to call high RAM) and you don't have to wait for DMA completion. Also, interrupts don't have to be disabled to use sprite DMA in this case. Example assembly code (rDMA=$ff46):

; $9f00 ~ 9f9f --> OAM

        ld      a,$9f

        ld      [rDMA],a