First Steps with DMA
Posted: Fri Jan 25, 2013 9:44 pm
This is the first time I'm attempting to write a game in straight 68k assembly (using ASM68k), having used SGDK in the past. So far, I've succeeded in loading a palette into CRAM; now I am attempting to use DMA to transfer an 8x8 tile into the first area of VRAM. But the correct way to do this eludes me.
This is the tile I'm attempting to load into VRAM:
Here is the code I have to initialize the VDP and prepare it for DMA. This is information I got out of the Genesis/Megadrive Software Manual. For clarity, I'll explain every line so you don't have to sit and figure out the hex.
As you can see, I'm attempting to add the low byte of a0 to $9500, so I can poke the low byte of the tile address into register #21. Being somewhat new to 68k assembly, I'm not sure if I'm missing some kind of addressing mode or something I can be using here, but I cannot for the life of me figure out how to segment the location of the A tile data. My original plan was to use the "LSR" instruction to give me access to the next byte to load into registers #22 and #23.
Upon assembly, and consultation of my 68k Quick Reference, "LSR" cannot be used on address registers, and "lsr #8,a0" was therefore not doable. So, I'm not immediately sure how to gain access to specific bytes in an address register word/longword.
If that's what I need to even do. In fact, I'm not even certain if any of this is correct. The Genesis programmer's manual gives me a warning about "occasional DMA failure" when transferring ROM->VRAM so does it have to go into RAM first?
In short, I really don't know what I'm doing. That's my shot at it. If someone has an example of DMA being done, or can tell me how I can shift an address register, I would appreciate that.
This is the tile I'm attempting to load into VRAM:
Code: Select all
A:
dc.l $00077000
dc.l $07700770
dc.l $07700770
dc.l $07777770
dc.l $07700770
dc.l $07700770
dc.l $00000000
dc.l $00000000
Code: Select all
move.w #$8F02, ($C00004) ; VDP Register #15, Increment by 2
move.w #$8174, ($C00004) ; VDP Register #1, Enable DMA
move.w #$9310, ($C00004) ; VDP Register #19, Transfer 16 words
move.w #$9400, ($C00004) ; VDP Register #20, Transfer 16 words (upper bytes 0, don't need greater than $FF words)
lea A, a0 ; Load the location of the A tile
move.w #$9500, d0 ; VDP Register #21, low byte
add a0, d0
move.w d0, ($C00004)
;;; THIS IS THE TROUBLE SPOT, MED AND HIGH BYTES
move.l #$40000080, ($C00004) ; Begin DMA Transfer
; << 68k Frozen?? >>
move.w #$8164, ($C00004) ; End DMA Transfer
Upon assembly, and consultation of my 68k Quick Reference, "LSR" cannot be used on address registers, and "lsr #8,a0" was therefore not doable. So, I'm not immediately sure how to gain access to specific bytes in an address register word/longword.
If that's what I need to even do. In fact, I'm not even certain if any of this is correct. The Genesis programmer's manual gives me a warning about "occasional DMA failure" when transferring ROM->VRAM so does it have to go into RAM first?
In short, I really don't know what I'm doing. That's my shot at it. If someone has an example of DMA being done, or can tell me how I can shift an address register, I would appreciate that.