English Amiga Board

English Amiga Board (http://eab.abime.net/index.php)
-   Coders. Asm / Hardware (http://eab.abime.net/forumdisplay.php?f=112)
-   -   Bordersprites restrictions (AGA chipset) (http://eab.abime.net/showthread.php?t=85482)

dissident 09 January 2017 09:17

Bordersprites restrictions (AGA chipset)
 
2 Attachment(s)
On my original hardware, an Amiga 1200/020, a display error in conjunction with borderspriters in the left overscan-region occurs. As a change the error doesn’t exist on WinUAE (3.3.0). So lean back, Toni. ;)

The Routine
A horizontal starscrolling of vertical reused 1x bandwidth attached bordersprites which use hires/super-hires positioning on a 320x256 display with two colours in 4x fetchmode (DDFSTRT $38, DDFSTOP=$a0). All eight sprites are used. The starscrolling has four different planes with different speeds. The attached sprite pairs are SPR01 = foremost plane1 with the largest/fastest balls and priority over the rest of the sprites, SPR23=plane2, SPR45=Plane3, SPR67=most backward plane4 with the smallest/slowest balls and the lowest display priority.

The Display-Error
SPR4/5 and SPR6/7 are displayed with the wrong colours between the horizontal (lores) positions $5b-$68. After position $68 everything is fine. Sprite pair SPR 4/5 starts with this error earlier than SPR6/7. This effect appears during the whole display (all 256 rasterlines). The Sprites pairs 0/1 and 2/4 are not affected. Turning off the bitplane-DMA with zero bitplanes in BPLCON0 doesn’t have any influence on the display error.

Theory 1
My first theory is that the sprite-DMA seems not able to display these sprites correctly because it is blocked by other, higher priorized DMA devices. I’ve seen in the DMA time slot allocation diagram of the HRM that for Sprite 5-7 other DMA devices could also use their slots. I’ve marked them red.
https://www.dropbox.com/s/d3ipg357al...rites.JPG?dl=0https://www.dropbox.com/s/d3ipg357al...rites.JPG?dl=0HRM says that these slots are also available for Blitter, Copper and 680x0. But the blitter is not used and the copper doesn’t execute any commands in this display region. So only the 680x0 could steal these cycles from these sprites. But when I did the screenshot, I stopped the routine, so there is also no 680x0 activity. The diagram also confirms that the sprites 4/5 are blocked earlier that sprite 6/7.

Theory 2
My second theory is, that the display-error occurs if the sprite should be displayed in the same region while it is fetched there by DMA. For SPR4 this would be between lores position $4a-$50 , SPR5=position $52-$58, SPR6=position $5a-$60, SPR7=position $62-$68. Paired together in attached mode this would mean that SPR45 are loaded between position $4a-$58 and SPR67 between position $5a-$68. The sprites are visible before these regions because the fetched planedata of the previous line is used.

To make things clearer, I’ve also included a little video https://www.dropbox.com/s/llfcdahmpt...rites.AVI?dl=0 and a screenshot of this effect to show how it appears on my multisync monitor. I’ve manipulated the display with the BPLCON4 so that the background-colour within HSTART-HSTOP/DDFSTRT-DDFSTOP is changed to emphasize the left border area.

Maybe you, Toni, could explain this phenomenon.

Toni Wilen 09 January 2017 09:53

I think I have seen this effect previously in some of my bitplane/sprite tests but I forgot about it because I was always examining some other problem.

I am sure your theory #2 is correct. Sprite is not horizontally armed when horizontal comparison matches = sprite's shift register won't get loaded or only SPRxDATA gets loaded (and DATB gets previous line's data, I guess) if match position is after sprite's DATA DMA but before sprite's DATB DMA slot.

SPRxDATA write does the horizontal arming.

It can't be #1, copper, blitter or cpu can't steal sprite cycles. (Only bitplanes can steal sprite cycles).

Toni Wilen 09 January 2017 18:10

Do you have some example code that shows this (and does nothing else)? Because I am so lazy to test it myself.. You can email if you prefer to keep it secret. Executable only is fine, I don't need sources.

Toni Wilen 09 January 2017 20:38

My first guess can't be right, it has nothing to do with armed status. (It is always good idea to check HRM and current emulation code before guessing anything too weird..)

It is most likely really simple reason: horizontal comparison matches after DATA has been loaded but before DATB: DATB still has previous line's data.

dissident 09 January 2017 21:58

Quote:

Originally Posted by Toni Wilen (Post 1133453)
I am sure your theory #2 is correct. Sprite is not horizontally armed when horizontal comparison matches = sprite's shift register won't get loaded or only SPRxDATA gets loaded (and DATB gets previous line's data, I guess) if match position is after sprite's DATA DMA but before sprite's DATB DMA slot.

SPRxDATA write does the horizontal arming.

It can't be #1, copper, blitter or cpu can't steal sprite cycles. (Only bitplanes can steal sprite cycles).

Okay, thank you for your quick reply, Toni. So I was not totally wrong with my theories. Fine. :)

Quote:

Originally Posted by Toni Wilen (Post 1133542)
Do you have some example code that shows this (and does nothing else)? Because I am so lazy to test it myself.. You can email if you prefer to keep it secret. Executable only is fine, I don't need sources.

I've sent you an e-mail with the exe-file(s).

Quote:

Originally Posted by Toni Wilen (Post 1133577)
My first guess can't be right, it has nothing to do with armed status. (It is always good idea to check HRM and current emulation code before guessing anything too weird..)

It is most likely really simple reason: horizontal comparison matches after DATA has been loaded but before DATB: DATB still has previous line's data.

I guess I will change my routine that way, dropping the use of SPR6/7 to avoid the obvious display error in the overscan region. The error with SPR4/5 is not so obvious, because there, it's only at the beginning of the overscan region.

Toni Wilen 10 January 2017 22:37

Fixed. It wasn't even directly chipset emulation related, it was just a side-effect of lazy evaluation (delay something as long as possible until it really needs to be done) which assumed that DMA mode sprites can't have side-effects and can be delayed until end of scanline (or until next CPU or copper sprite-register access if earlier than end of scanline).

Fixed was very simple: test sprite's X-coordinate against sprite's SPRxDATB DMA slot in DMA emulation, if coordinate is smaller, do pending sprite decisions immediately. Test prevents useless CPU usage increase with "normally" positioned sprite.

dissident 11 January 2017 08:41

Quote:

Originally Posted by Toni Wilen (Post 1133840)
Fixed was very simple: test sprite's X-coordinate against sprite's SPRxDATB DMA slot in DMA emulation, if coordinate is smaller, do pending sprite decisions immediately. Test prevents useless CPU usage increase with "normally" positioned sprite.

Very good, Toni. :)

Quote:

Originally Posted by Toni Wilen (Post 414480)
This wasn't exactly right.

It is first write to BPL0DAT that also enables sprites.

Write to BPL0DAT enables bitplane shift registers inside Denise (this is nothing new, Agnus DMA does this automatically internally). My guess is that there is logic that outputs background color as long as BPL0DAT has not been written to.

Test used: DDFSTRT set to 0x80, put sprite on left side of screen. It is not visible. Use copper to write to BPL0DAT on left side of screen. Single raster line of sprite is now visible + 16 pixels of bitplane data that was written to BPL0DAT.

Perhaps useful for some weird tricks, not sure :)

I guess the OCS-hardware behaves the same way, if you do this trick with the write to the BPL0DAT register at the beginning of the scanline to display sprites outside the border in the blanked area to simulate "bordersprites" on OCS.

Toni Wilen 11 January 2017 09:32

Quote:

Originally Posted by dissident (Post 1133902)
I guess the OCS-hardware behaves the same way, if you do this trick with the write to the BPL0DAT register at the beginning of the scanline to display sprites outside the border in the blanked area to simulate "bordersprites" on OCS.

I didn't test but I am sure there are no differences between ocs/ecs/aga. It is just a side-effect of how sprite DMA fetches are done, single sprite line needs two separate fetches and sprite can be loaded to output shift register even if its data has not been fully loaded (or even not loaded at all)

I think it should be quite easy to work around it by having multiple sprites (one normal, one that has second plane shifted by one pixel vertically and so on) and selecting correct depending on sprite's x-coordinate.

dissident 11 January 2017 23:38

Quote:

Originally Posted by Toni Wilen (Post 1133907)
I didn't test but I am sure there are no differences between ocs/ecs/aga. It is just a side-effect of how sprite DMA fetches are done, single sprite line needs two separate fetches and sprite can be loaded to output shift register even if its data has not been fully loaded (or even not loaded at all)

I think it should be quite easy to work around it by having multiple sprites (one normal, one that has second plane shifted by one pixel vertically and so on) and selecting correct depending on sprite's x-coordinate.

I’ve changed my routine, so that the sprites are now visible in the border region without setting the bordersprite-bit in BPLCON3. Works fine on my original hardware, an A1200/020.

Between line $2c-$12b the copper sets with x-pos=$6 (minimum) the register BPL1DAT=0.

The display error at the left border can be prohibited, waiting with the copper for the x-pos=$38. But as a consequence, the left overscan region gets blanked and the sprites are disabled.

The values of these register remain the same: DDFSTRT=$38, DDFSTOP=$a0, FMODE=4x for one bitplane.

Important: To see the sprites outside the border, it is necessary to change the horizontal window-limits (DIWSTRT/DIWSTOP/DIWHIGH) to the overscan values HSTART=$5b and HSTOP=$1c7. Otherwise the sprites are only visible in the standart region if you use for example HSTART=$81, HSTOP=$1c1. The display error at the left border is the same as with real bordersprites. At the right border the sprites disappear much sooner like the real bordersprites, if you use HSTOP>=$1c8. It seems that they can’t have the horizontal lores-positions greater $1c7.

Toni, if you want, I could send you my revised routine by mail for testing purposes. Please remember, that my routine is AGA only. I haven’t got an init-routine for the OCS yet.

Toni Wilen 12 January 2017 12:00

I don't think I need any test cases anymore. Only remaining part is confirming that glitches happen exactly at right x coordinate positions. I'll do it later..

This test is needed because some sprite operations that happen exactly at the same time as DMA write use previous data and some use new data.

Toni Wilen 12 January 2017 23:14

Positioning is exactly correct in emulation but I found another side-effect (and confirmed it also happens on ECS A500):

If sprite start xpos is before xDATB/xCTL fetch, sprite's last line gets duplicated, line that normally would have been blank (line that DMA engine uses to fetch next xPOS and xCTL words) will have same sprite graphics as previous line.

It happens because condition that loads words to shift register is: must be "armed" and horizontal comparison matches. Sprite stays armed until next xCTL write, if horizontal comparison matches before xCTL DMA fetch, sprite is still armed and shift register will get loaded with previous line's xDATA and xDATB. Result is repeated extra line.

(This is not yet emulated, it is more tricky to implemented without other side-effects)

dissident 13 January 2017 10:09

Quote:

Originally Posted by Toni Wilen (Post 1134246)
Positioning is exactly correct in emulation

Sure, your emulation works correctly. My monitor seems to display more of the right border region than it is necessary. That's what I meant. :)

Quote:

Originally Posted by Toni Wilen (Post 1134246)
but I found another side-effect (and confirmed it also happens on ECS A500):

If sprite start xpos is before xDATB/xCTL fetch, sprite's last line gets duplicated, line that normally would have been blank (line that DMA engine uses to fetch next xPOS and xCTL words) will have same sprite graphics as previous line.

It happens because condition that loads words to shift register is: must be "armed" and horizontal comparison matches. Sprite stays armed until next xCTL write, if horizontal comparison matches before xCTL DMA fetch, sprite is still armed and shift register will get loaded with previous line's xDATA and xDATB. Result is repeated extra line.

(This is not yet emulated, it is more tricky to implemented without other side-effects)

If I'm right, this would confirm my secend theory that the sprites are visible in the overscan area before their data is fetched, because the fetched planedata of the previous line is used.

Toni Wilen 14 January 2017 16:13

Quote:

Originally Posted by dissident (Post 1134346)
If I'm right, this would confirm my secend theory that the sprites are visible in the overscan area before their data is fetched, because the fetched planedata of the previous line is used.

Exactly. Unfortunately this "feature" seems to be totally useless for anything interesting...

Last line doubling should be emulated properly now.

ross 09 January 2019 16:52

Hi Toni, there is something wrong in border sprite emulation, probably related to patch you have done here.

All 'bad' sprites behavior in low x-coordinates works only if BRDSPRT=1.
(tested on AGA 64bit sprites and latest WinUAE)

ross 09 January 2019 17:37

5 Attachment(s)
hmm, there is also something wrong with BRDSPRT=1.

I think that all the situations in attached images indicate something strange.
Sprites not y-multiplexed, latest image with BRDSPRT=0.

Attached also a little executable (joy button to toggle BRDSPRT bit).

Toni Wilen 11 January 2019 19:53

Fixed. I tried to optimize handling of this feature a bit too much..

ross 11 January 2019 22:19

Perfect! Now it behaves as I remember from the old days :).

Thank you,
ross

ross 31 January 2019 19:19

Quote:

Originally Posted by dissident (Post 1134068)
Important: To see the sprites outside the border, it is necessary to change the horizontal window-limits (DIWSTRT/DIWSTOP/DIWHIGH) to the overscan values HSTART=$5b and HSTOP=$1c7. Otherwise the sprites are only visible in the standart region if you use for example HSTART=$81, HSTOP=$1c1. The display error at the left border is the same as with real bordersprites. At the right border the sprites disappear much sooner like the real bordersprites, if you use HSTOP>=$1c8. It seems that they can’t have the horizontal lores-positions greater $1c7.

Hi Toni and dissident, i've to better understand the upper sentence...

My first DIWSTRT position for a full left overscan is value $5c, that correspond to a x sprite position = $5b.
Or are you saying that you have DIWSTRT = $5b? (one lo-res pixel more that WinUAE).

Regarding max x position.. in WinUAE I can set an x>$1c7 and the sprites do not disappears.
From this message seems that the sprites in real machine disappears. Can you enlighten me?

Thanks.

dissident 01 February 2019 09:34

Quote:

Originally Posted by ross (Post 1301544)
Hi Toni and dissident, i've to better understand the upper sentence...

My first DIWSTRT position for a full left overscan is value $5c, that correspond to a x sprite position = $5b.
Or are you saying that you have DIWSTRT = $5b? (one lo-res pixel more that WinUAE).

Regarding max x position.. in WinUAE I can set an x>$1c7 and the sprites do not disappears.
From this message seems that the sprites in real machine disappears. Can you enlighten me?

Thanks.

Hi ross, yes, DIWSTRT = $5b. I thought that this is the official left overscan value with HBSTOP = $5a.

DIWSTOP = $1c7 is the normal horizontal overscan value. Or did you set DIWSTOP = $1c8? Then you will get an extra wide display (left&right border will be extended to their maximum values) because of a hardware bug. And I guess then, sprites are also visible at a horizontal position >=$1c8.

ross 01 February 2019 12:05

Quote:

Originally Posted by dissident (Post 1301686)
Hi ross, yes, DIWSTRT = $5b. I thought that this is the official left overscan value with HBSTOP = $5a.

This is interesting.
Toni confirmed in an old message that first pixel is visible with DIWSTRT(<)=$5C for ECS and AGA, apart some early A1000 where DIWSTRT can be $60. So in WinUAE.

Quote:

DIWSTOP = $1c7 is the normal horizontal overscan value. Or did you set DIWSTOP = $1c8? Then you will get an extra wide display (left&right border will be extended to their maximum values) because of a hardware bug. And I guess then, sprites are also visible at a horizontal position >=$1c8.
Yes, I set DIWSTOP(>)=$1c8 to get the max wide display. And sprites are visible in this zone.
So I did not understand what you meant here:
"At the right border the sprites disappear much sooner like the real bordersprites, if you use HSTOP>=$1c8. It seems that they can’t have the horizontal lores-positions greater $1c7."
Can you elaborate please?

Thanks :)


All times are GMT +2. The time now is 09:37.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.

Page generated in 0.17197 seconds with 11 queries