Edit: updated the link. Most likely gonna fine-tune the guide though using what OrionNavattan provided me. For now, you newbies can use this at your own will. =) I'm not going to go into detail technical specs of the new DMA queue besides the fact that it's heavily optimized which surpasses Sonic 2's and Sonic and Knuckles's DMA queue by a long shot. If you want to know more about what it does, click on this link. This tutorial targets the ASM68K GitHub disassembly but should work with any other disassembly if you know what you're doing. This has been tested on Hivebrain 2005 however idk about Hivebrain's modern disassemblies at this time of writing. If the guide works with that disassembly in mind, let me know. AS assemblers may follow this guide, but it's best if you use the link above instead of the one below. Before we get started, if you already have Sonic 2's DMA queue installed because you ported the spindash, then you'll have to replace the code with what I'm about to give you. There are a few steps that you can skip if you already changed a few lines here and there, but it's best if you double-check if you added the code in. (trust me, it's worth checking along the way because you'll definitely have to change a few lines here and there) Firstly, we're going to add the DMA Queue itself. Let's create a file called DMA Queue.asm. Here's the version that'll work under ASM68K disassemblies in mind. (click me). I think it's based on a slightly older version of the DMA Queue however I'm not entirely sure at the moment. From there, you can save the file to your disassembly. I'll place it in the "_inc" folder in my case. The next step is to include the file in your disassembly so let's open up sonic.asm and make a line that includes the aforementioned .asm file. it doesn't matter where you put it exactly although I recommend placing it above the line that includes the Nemesis Decompression file like so: Code: include "_inc\DMA Queue.asm" include "_inc\Nemesis Decompression.asm" Before we do anything else in sonic.asm, we need to understand the fact that flamewing's DMA queue is only recognized by AS assemblers and since we're dealing with an ASM68K assembler, we need to make a few changes in order to get the file working. If you're using an AS disassembly, you can skip this section. Above your added line, insert this: Code: pusho ; buffer local label symbol config opt ws+ ; change local label symbol to '.' and below it: Code: popo ; buffer local label symbol config So you should get this: Code: pusho ; buffer local label symbol config opt ws+ ; change local label symbol to '.' include "_inc\DMA Queue.asm" popo ; buffer local label symbol config The first two lines of code that we added will make sure the default labelling scheme would use dots as prefixes than @. "popo" will revert the local label to @ so no, it won't affect the rest of your disassembly. (AS disassembly users, come back) If you check the code, you can see that VDP_Command_Buffer and VDP_Command_Buffer_Slot aren't defined. So let's define them, shall we? =V Go to Variables.asm and insert this: Code: VDP_Command_Buffer: equ $FFFFC800 VDP_Command_Buffer_Slot: equ VDP_Command_Buffer+7*$12*2 If you done this correctly, the ROM should build although we need to initalize the DMA queue and put it into good use. Firstly, let's go to GameInit and above: Code: bsr.w VDPSetupGame insert this: Code: bsr.w InitDMAQueue This will load the DMA queue upon startup. Next, let's replace a bunch of VBlank junk that makes the game load Sonic's sprites using a shit-ton of RAM ($200 of RAM between $FFFFC900 to $FFFFCAFF). Find these four lines of code: Code: tst.b (f_sonframechg).w ; has Sonic's sprite changed? beq.s @nochg ; if not, branch writeVRAM v_sgfx_buffer,$2E0,vram_sonic ; load new Sonic gfx move.b #0,(f_sonframechg).w and replace it with: Code: jsr ProcessDMAQueue(pc) You can find these instances at VBla_08, VBla_0A, VBla_0C and VBla_16. Now let's load the DMA every time the game loads a new game mode. Inset this line: Code: ResetDMAQueue at the following: At GM_Sega, GM_Title, GM_Continue, GM_Credits, TryAgainEnd => insert this line under: Code: bsr.w ClearScreen At Level_ClrVars3 and End_ClrRam3, under: Code: move.w (v_hbla_hreg).w,(a6) And at loc_47D4 under: Code: jsr Hud_Base Caution: if you ported Sonic 2's DMA queue (which is the code used from that spindash guide), replace these lines: Code: clr.w ($FFFFC800).w move.l #$FFFFC800,($FFFFC8FC).w with ResetDMAQueue. They can be found at loc_47D4 and Level_ClrVars3. Finally, let's make the game load Sonic's art via DMA. Let's head over to "_incObj/Sonic LoadGfx.asm" and replace everything with this: Spoiler: Large piece of code Code: ; --------------------------------------------------------------------------- ; Sonic graphics loading subroutine ; --------------------------------------------------------------------------- ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| Sonic_LoadGfx: ; XREF: Obj01_Control; et al moveq #0,d0 move.b obFrame(a0),d0 ; load frame number cmp.b (v_sonframenum).w,d0 ; has frame changed? beq.s @nochange ; if not, branch move.b d0,(v_sonframenum).w lea (SonicDynPLC).l,a2 ; load PLC script add.w d0,d0 adda.w (a2,d0.w),a2 moveq #0,d5 move.b (a2)+,d5 ; read "number of entries" value subq.w #1,d5 bmi.s @nochange ; if zero, branch move.w #$F000,d4 move.l #Art_Sonic,d6 @readentry: moveq #0,d1 move.b (a2)+,d1 lsl.w #8,d1 move.b (a2)+,d1 move.w d1,d3 lsr.w #8,d3 andi.w #$F0,d3 addi.w #$10,d3 andi.w #$FFF,d1 lsl.l #5,d1 add.l d6,d1 move.w d4,d2 add.w d3,d4 add.w d3,d4 jsr (QueueDMATransfer).l dbf d5,@readentry ; repeat for number of entries @nochange: rts ; End of function Sonic_LoadGfx From there, you can save, build and test your hack and it should load just fine. If there are any questions related to this, then please let me know.
Alright, alright, relax. Don't worry, this wasn't intentional. I must've overlooked it when cross-posting my guide from SonicRetro. Check if it works now.