don't click here

Changing Sonic 2's level format

Discussion in 'Engineering & Reverse Engineering' started by jman2050, Dec 27, 2005.

  1. jman2050

    jman2050

    Teh Sonik Haker Tech Member
    634
    4
    18
    I think he meant logically. Obviously, it's technically possible as it only takes a single VBlank to DMA all the art over before refreshing the screen, but it would look weird in-game if EHZ suddenly shifted to CPZ instantly :P

    EDIT - Oh, and btw, I fixed the VRAM bug LocalH was talking about. Turns out it wasn't a VRAM issue at all; it was a DMA issue. More specifically, a bug in the game itself. Basically, in order to load level art into VRAM, it does it backwards. It uses the ending address of the decompressed data in RAM and derives the length in words of the first DMA transfer. It does this by using the lower 12 bits (if the ending address were $6C00, it uses $C00, and right shifts it to get the DMA length). Then after the initial transfer it loads the rest of the art backwards by $1000 byte chunks until it reaches $0000.

    The problem with this code is that it assumes it's going to find a length. If the decompressed art ends at an address divisible by $1000 (as it does in my case), what happens is that the game uses a length of 0 for the first DMA transfer. Gens apparantly ignores DMA transfers of zero length, but the Genesis (and Kega) don't, and it screws everything up as a result. It's an easy fix too: Right before the call to the subroutine $144E around offset 4F1A, just test d3 for zero, and skip the call to $144E if that's the case. Bug fixed, problem solved.

    And a new rom to be uploaded for testing just for you LocalH :)
     
  2. LocalH

    LocalH

    roxoring your soxors Tech Member
    Yeah, that's pretty much what I meant. Using the method #2 I mentioned, you couldn't reload all the art because some of it would be used on-screen at that moment.
     
  3. jman2050

    jman2050

    Teh Sonik Haker Tech Member
    634
    4
    18
    nvm - New ROM uploaded
     
  4. Sonic Hachelle-Bee

    Sonic Hachelle-Bee

    Taking a Sand Shower Tech Member
    807
    200
    43
    Lyon, France
    Sonic 2 Long Version
    Yes, it's obvious... You are right. =P
     
  5. Varion Icaria

    Varion Icaria

    He's waiting.... Tech Member
    1,019
    11
    18
    S4: Cybernetic Outbreak
    Sorry for the bump but since the topic currently is on DMA's I have a question, How would I get the DMA to load art that gets decompressed by one of the decompression routines? There should be a way to do it [S3 does it somehow] so I was wondering if any of you know how?
     
  6. StephenUK

    StephenUK

    Liquor in the front, poker in the rear Tech Member
    1,678
    0
    16
    Manchester, UK
    Quackshot Disassembly
    You've just been told by me and Ultima about an hour ago how to do it. You need to decompress it to a buffer (and you claim to know what one is) and then from there you send it to VDP by programming the registers as you've been told by both of us, and by sending information to the control and data ports.
     
  7. Tweaker

    Tweaker

    Banned
    12,387
    2
    0
    Christ, just make a fucking pattern load cue. End.
     
  8. StephenUK

    StephenUK

    Liquor in the front, poker in the rear Tech Member
    1,678
    0
    16
    Manchester, UK
    Quackshot Disassembly
    Or just use the dynamic load cues. IIRC, LOst told you how they work.
     
  9. drx

    drx

    mfw Researcher
    2,254
    350
    63
    :rolleyes:
    Stolen from Sonic 3: (yeah, my disassembly)

    Code (Text):
    1. ; -----------------------------------------------------
    2. ;  This    subroutine sets the DMA (Direct Memory Access) to 68k to VRAM
    3. ;
    4. ;   d1.l - DMA source address (in 68k memory)
    5. ;   d2.w - DMA destination address (in VRAM)
    6. ;   d3.w - DMA length
    7. ; -----------------------------------------------------
    8.  
    9. SetupDMA_68kToVRam:  ; CODE XREF: KosinskiModDec_Decompress+72p
    10.     ; ROM:00003676p ...
    11.   movea.l  ($FFFFFBFC).w,a1
    12.   cmpa.w   #$FBFC,a1
    13.   beq.s    SetupDMA_NoDMA
    14.  
    15.   move.w   #$9300,d0
    16.   move.b   d3,d0
    17.   move.w   d0,(a1)+; setup VDP register $13 - DMA length bits 7-0
    18.  
    19.   move.w   #$9400,d0
    20.   lsr.w    #8,d3
    21.   move.b   d3,d0
    22.   move.w   d0,(a1)+; setup VDP register $14 - DMA length bits 15-8
    23.  
    24.   move.w   #$9500,d0
    25.   lsr.l    #1,d1
    26.   move.b   d1,d0
    27.   move.w   d0,(a1)+; setup VDP register $15 - 68k addr bits 8-1 (remember, the bit 0 is always %0!)
    28.  
    29.   move.w   #$9600,d0
    30.   lsr.l    #8,d1
    31.   move.b   d1,d0
    32.   move.w   d0,(a1)+; setup VDP register $16 - 68k addr bits 16-9
    33.  
    34.   move.w   #$9700,d0
    35.   lsr.l    #8,d1
    36.   andi.b   #$7F,d1; ''
    37.   move.b   d1,d0
    38.   move.w   d0,(a1)+; setup VDP register $17 - 68k addr bits 23-17
    39.  
    40.   andi.l   #$FFFF,d2; VRAM destination address
    41.   lsl.l    #2,d2
    42.   lsr.w    #2,d2
    43.   swap d2  ; VRAM destination address, edited to suit VDP =P
    44.   ori.l    #$40000080,d2; set up the 68k to VRAM DMA, start it
    45.   move.l   d2,(a1)+
    46.   move.l   a1,($FFFFFBFC).w
    47.  
    48. loc_1806:
    49.   cmpa.w   #$FBFC,a1
    50.   beq.s    SetupDMA_NoDMA
    51.   move.w   #0,(a1)
    52.  
    53. SetupDMA_NoDMA:      ; CODE XREF: SetupDMA_68kToVRam+8j
    54.     ; SetupDMA_68kToVRam+5Aj
    55.   rts 
    56. ; End of function SetupDMA_68kToVRam