Views: 807,868,958
26 users online: aknightofwands, algae5, Arobam, chickaDEE Magazine, Darkbloom, Disolv, faloppa, Fullcannon, Gamma V, Green Jerry, HLXY, Insanit,  KevinM, Magmatic,  MarioFanGamer,  MM102, Mr. MS, Mrmariobros222, om_nomnom, PPDude, RudeGuy, rvx, Rykon-V73, Samuel Zuccati, Sixcorby, StackDino - Guests: 94 - Bots: 156 Users: 42,411 (1,993 active)
Latest: Inertiaddict
Tip: The multiple midpoints patch can also be used to move a level's normal midpoint.Not logged in.
Example of "double buffering" an hdma table?
Forum Index - SMW Hacking - SMW Hacking Help - ASM & Related Topics - Example of "double buffering" an hdma table?
Pages: « 1 »
I recently ran into some problems with an HDMA code. While running, layer 3 flickers a bunch. Prior to using LM 3.0 it was working fine. Looking for answers I came across this thread and skimmed through it to if there was anything about it. And this seemed to be relevant:

Originally posted by Kaijyuu
If you're purposefully changing scanline counts every frame, there's something you should know. HDMA doesn't take the table and store it somewhere else at the start of the frame. It reads it when it needs to.

Levelasm and sprites are run while the screen is being drawn. So, if your code changes the table, a glitch can occur where it is using the values set the previous frame on part of the screen, and the values set this frame on the rest. This is most noticeable with scanline count changes because the effect can "flicker" up and down. What you need to do to fix this is "double buffer" your table. That means upload it in two places and alternate each frame which you change. Because changes to $43x2-4 don't take effect until the next frame, you can effectively avoid the glitch entirely.

I'm not quite sure what this means though. Should I run a copy of this on another channel? Another copy running in NMI? Since this happens with even a generic code from Effect Tool lets take that for an example (table excluded). How would I "double buffer" this?

   REP #$20                             ; | 
   LDA #$0F42                           ; | Use indirect and mode 2 on register 210F
   STA $4330                            ; | 4330 = Mode, 4331 = Register
   LDA #ParallaxTable        ; | Address of HDMA table, get high and low byte
   STA $4332                            ; | 4332 = Low-Byte of table, 4333 = High-Byte of table
   SEP #$20                             ; | 
   LDA.b #ParallaxTable>>16   ; | Address of HDMA table, get bank byte
   STA $4334                            ; | 4334 = Bank-Byte of table
   LDA #$7F                             ; | Address of indirect table in RAM bank byte
   STA $4337                            ; | 4334 = Bank-Byte of indirect table
   LDA #$08                             ; | 
   TSB $6D9F                            ; | Enable HDMA channel 3     
   REP #$20                             ;/  16 bit action starts here. (To load the x position of the BG)
   LDA $1E                              ;\  Load BG x Position
   ASL #0                               ; | Multiplied by 1
   STA $7FB700                          ;/  Store to FreeRAM for indirect HDMA
   LDA $1E                              ;\  Load BG x Position
   STA $7FB702                          ;/  Store to FreeRAM for indirect HDMA
   SEP #$20                             ; Back to 8bit
   RTL                                  ; Return
The idea is that since we're racing against the electron beam, every code is dependent on it and failing so will result in screen tearing (think of it as rolling stutter but between frames). If the frame didn't finish to process before the electron beam reached the point, so the screen partially unpdates. Now, this usually doesn't matter since most registers are h-/v-/f-blank locked but this still can happen with HDMA where its table can be located in RAM and that can be written everytime.

The effect doesn't happen in SMW hacking because there is so much NMI time left, screen tearing generally won't appear or isn't noticable and the HDMA effects are generally simple (there also is the fact that getting some time). Even if that happens, this generally isn't appearant on most HDMA effects (such as gradients or parallax in general) but certain other effects such as windowing of fixed shapes or fast changes are noticable.
Note that this doesn't apply to changes in the scanline but changes to the HDMA table in general (including the value).

Now you understand what screen tearing is but it also doesn't seem to be related to your problem, though.

Okay, my layout looks ugly.
Would still like an example of this if anyone knows how to double buffer a table.
Double buffer is pretty simple, actually: As the name implies, you have two buffers (let's call one of them buffer A and the other one buffer B). Buffer A is the table where you construct the HDMA table but don't take it as the HDMA source. Instead, the HDMA takes buffer B as the source and you copy all of buffer A to buffer B in v-blank to prevent screen tearing.

One example which comes into my mind are Yoshi's Island parallax HDMA tables. For example, the code at $01D7CD (there are plenty of them) calls the GSU to construct the HDMA table at buffer A. After that, it jumps to $00BE71 which doesn't upload it but rather sets a DMA queue to copy from $7036BA (buffer A) to $7E51E4 (buffer B). The DMA queue runs at the NMI routine $00DE18 (don't be confused at the RAM addreses, DP is set to $420B) which then results in the copy from buffer A to buffer B.

Okay, my layout looks ugly.
Late response, but this is exactly what I was looking for, thanks MFG.
Pages: « 1 »
Forum Index - SMW Hacking - SMW Hacking Help - ASM & Related Topics - Example of "double buffering" an hdma table?

The purpose of this site is not to distribute copyrighted material, but to honor one of our favourite games.

Copyright © 2005 - 2020 - SMW Central
Legal Information - Privacy Policy - Link To Us

Total queries: 7


Follow Us On

  • YouTube
  • Twitch
  • Twitter


  • Super Mario Bros. X Community
  • Mario Fan Games Galaxy