A.D.A. Amiga Demoscene Archive

  Welcome guest! Please register a new account or log in




log in with SceneID


Demos Amiga Demoscene Archive Forum / Coding / Shearing just past line 200?


Author Message
#1 - Posted: 15 Mar 2007 18:03
Reply Quote

I've knocked up a little interference circles effect in winUAE that I'm seeing some tearing with. Implementation wise, I decided to HW scroll the bottom bitplane, and use a blitter copy into the second bit plane - mainly as I'd not done anything with the playfield until now so it was something else to learn...

The problem I've got is that the HW scrolled bitplane shears just past the NTSC line, which looks pretty poor.

Does anyone know why this is? Everything else *seems* ok under E-UAE so I can't work out if this is something I'm missing from my Pal copper list, a UAE thing, or something else.

The code is up here...:


I'd be grateful for any pointers cos I'd prefer to do full screen pal all the time if pos... :)

Thanks :D
#2 - Posted: 15 Mar 2007 18:37
Reply Quote
Are you sure that it is the HW scrolled bitplane that is shearing? I could imagine that the following happens:

* Wait_VBL doesn't wait for vertical retrace -- instead it waits for line 255 on-screen (check how you read VPOSR & VHPOSR)
* Blitting starts near-immediately after this, so you get tearing a few lines later, when the blitter catches up with display DMA

Also, "clearing sprite ptrs" by setting them to 0 will not disable sprites. It will cause sprite DMA to fetch control words from address 0.

Clear them by doing either:
1) point all Sprite DMA channels to a cleared longword of chipmem
2) disable sprite DMA via DMACON, then write to SPRxCTL for all sprites (the 2nd step disables the sprites, the 1st keeps them from getting re-enabled)
#3 - Posted: 15 Mar 2007 20:13
Reply Quote
Yeah, it's the HW plane - that's the plane I got working first and I noticed the problem then. I thought it might be a more global issue until the blitted plane was working. That doesn't shear at all.

Wait_VBL is:

wait_VBL: macro
cmp.b #$ff, vhposr(a6) ; Wait for VBL
bne.b wvbl\@

Cheers for the sprite tips. You're spot on, I'd just not noticed. Thanks :D
#4 - Posted: 15 Mar 2007 23:58
Reply Quote

1) Wait_VBL waits for line 255 on screen, not the actual VBL. Look at the full VPOSR+VHPOSR register to determine when you wrap around.

Example (untested code):

moveq #100,d0
bne.s .delay1
move.l vposr(a6),d0
and.l #$1ff00,d0
cmp.l #$0c000,d0
blo.s .upperHalf

moveq #100,d0
bne.s .delay2
move.l vposr(a6),d0
and.l #$1ff00,d0
cmp.l #$0c000,d0
bhs.s .lowerHalf


The first loop waits until the raster beam has left the upper half of the screen; the second loop waits until the raster beam has left the lower half of the screen. By not waiting for a specific scanline, the code is resistant against slow interrupt handlers. The nop-loops are there to stop the CPU from hammering the chipmem bus (thereby stealing bus cycles from the blitter).

A more robust and efficient solution is to install a VBI handler which sets a flag, and have Wait_VBL spinlock on that flag (which should be located in fastmem).

2) Some display registers are written from the copperlist, other are written directly from the CPU's code. The tearing you're seeing is because bplcon1 & bpl1mod are being updated mid-frame. It is good practice to do all the display register writes from the copperlist, to avoid this sort of problems.

3) Once you have a proper Wait_VBL mechanism in place, you have another race condition to handle. The CPU will update the copperlist shortly after the VBI, and the copper will start executing the copper-instructions shortly after the VBI.
You want to ensure that the updates of the copperlist happen *entirely* before or after the copper has run through that batch of instructions. The CPU updating bitplane-ptrs in copperlist at the same time as the copper is reading them is the number 1 reason why you occasionally see a single frame of broken graphics in demos: one bitplane happens to use BPLxPTH from the previous update but BPLxPTL from the current update.

There are three solutions to the CPU/copper race condition.
* Either have two copperlists. CPU writes to copperlist 1 while copper executes copperlist 2. Then, at VBI time, the two lists are swapped. This solution requires most work out of the three.
* Or, have a wait at the beginning of the copperlist (say $10 lines) and ensure that you do all the copperlist updates really early in your program.
* Or, ensure that the copperlist runs through rather quickly, and have the CPU wait (say $10 lines) after the VBI before it begins to write to the copperlist.
#5 - Posted: 16 Mar 2007 09:58
Reply Quote
Thank you Kalms. That's a great bit information and makes a hell of a lot of sense.

I'll re-write my code once I get back from my trip. :)


  Please register a new account or log in to comment





A.D.A. Amiga Demoscene Archive, Version 3.0