08 March 2020, 16:05 | #1 |
Lemon. / Core Design
Join Date: Mar 2016
Location: Tier 5
Posts: 1,209
|
Displaying sprites without DMA
Currently I have a sprite the full height of the screen, shown with DMA, and I am adjusting the x position on each line using the copper, writing into SPRxPOS & SPRxCTRL
The sprite data is the same for each line (think of it as a vertical bar)... so I thought that I could actually do this without DMA, by just writing the data to SPRxDATA and SPRxDATB once, at the top of the frame, and disabling sprite DMA. However this just displays only one line (the first line) of the sprite. What could I be doing wrong? Or is this actually not possible (it's like SPRxDATA and SPRxDATB are being cleared after displaying the sprite) |
08 March 2020, 16:12 | #2 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,406
|
One question: do you have the SPRxPOS/SPRxCRTL set to display the sprite across the entire frame, or just one line?
See, I think it should be possible as IIRC disabling Sprite DMA at the correct time does exactly what you describe here (but for all sprites). Note I haven't tested this and am speaking from memory so take it as you will |
08 March 2020, 16:23 | #3 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,160
|
without DMA I think you have to advance sprite data manually, following VPOS. CPU intensive as hell !
http://www.stashofcode.fr/afficher-s...s-sur-amiga-1/ with my translation of the comments from french to something that looks like english Code:
_waitSpriteStart: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmpi.w #SPRITE_Y,d0 blt _waitSpriteStart ;display sprite.write into SPRxDATA last, because it triggers sprite display move.w #((SPRITE_Y&$FF)<<8)!(((SPRITE_X-1)&$1FE)>>1),SPR0POS(a5) move.w #(((SPRITE_Y+SPRITE_DY)&$FF)<<8)!((SPRITE_Y&$100)>>6)!(((SPRITE_Y+SPRITE_DY)&$100)>>7)!((SPRITE_X-1)&$1),SPR0CTL(a5) move.w #$0F0F,SPR0DATB(a5) move.w #$00FF,SPR0DATA(a5) ;wait the middle line of the sprite to reposition it horizontally (8 pixels to the right) and change data _waitSpriteMiddle: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmpi.w #SPRITE_Y+(SPRITE_DY>>1),d0 blt _waitSpriteMiddle move.w #((SPRITE_Y&$FF)<<8)!(((SPRITE_X+8-1)&$1FE)>>1),SPR0POS(a5) ;writing in SPRxCTL stops sprite display, which forbids to reposition the sprite horizontally with pixel precison, unless it's rearmed by rewriting to SPRxDATA, cos bit 0 of this position is in SPRxCTL. the 3 following lines are only necessary if the horiz position is odd. move.w #(((SPRITE_Y+SPRITE_DY)&$FF)<<8)!((SPRITE_Y&$100)>>6)!(((SPRITE_Y+SPRITE_DY)&$100)>>7)!((SPRITE_X+9-1)&$1),SPR0CTL(a5) move.w #$F0F0,SPR0DATB(a5) move.w #$FF00,SPR0DATA(a5) ;wait the last sprite line to stop displaying it by writing trash in SPRxCTL. _waitSpriteEnd: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmpi.w #SPRITE_Y+SPRITE_DY,d0 blt _waitSpriteEnd move.w #$0000,SPR0CTL(a5) |
08 March 2020, 16:25 | #4 |
Lemon. / Core Design
Join Date: Mar 2016
Location: Tier 5
Posts: 1,209
|
i am setting SPRxPOS/SPRxCTRL once on each line... basically, I want this "vertical" bar to not be vertical (ie.. i am skewing it)
I was sure it was possible too, due to the old "bug" of repeated verticl sprite mouse pointer... but seems that the write to SPRxPOS / SPRxCTRL seem to affect this, and I'm not getting the data repeated on the next line |
08 March 2020, 16:30 | #5 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
|
It is possible if you follow correct register update order:
Disable sprite DMA first. Set SPRxCTL (CTL write disable the sprite). Then update SPRxDATB and SPRxDATA (DATA last because it will enable the sprite). SPRxPOS when needed. Now you should have sprite that goes from top to bottom of screen. SPRxPOS can be written anytime to change horizontal position. Vertical values are ignored. Sprite vertical registers are in Agnus, horizontal is in Denise. EDIT: "enable" in this case means sprite's horizontal comparison is active. |
08 March 2020, 16:30 | #6 |
Lemon. / Core Design
Join Date: Mar 2016
Location: Tier 5
Posts: 1,209
|
But (for example) setting SPRxPOS / SPRxCTRL with the copper several times on the same line, can redisplay the contents of SPRxDATA and SPRxDATB without issue.
It seems that my issue is that the data is cleared on the next line |
08 March 2020, 16:31 | #7 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,406
|
From the HRM (http://amigadev.elowar.com/read/ADCD.../node00C8.html):
Code:
* Writing to the sprite control registers disables the horizontal comparator circuitry. This prevents the system from sending any output from the data registers to the serial converter or to the screen. * Writing to the sprite A data register enables the horizontal comparator. This enables output to the screen when the horizontal position of the video beam equals the horizontal value in the position register. * The data in the sprite data registers does not change. It is either rewritten by the user or modified under DMA control. Last edited by roondar; 08 March 2020 at 16:36. Reason: Corrected a small error - SPRxPOS has no bearing on this |
08 March 2020, 16:32 | #8 | |
Lemon. / Core Design
Join Date: Mar 2016
Location: Tier 5
Posts: 1,209
|
Quote:
will give it a try, and see if I can get it working... |
|
08 March 2020, 16:34 | #9 |
Lemon. / Core Design
Join Date: Mar 2016
Location: Tier 5
Posts: 1,209
|
so I can't write to SPRxCTRL each line for exact 1 pixel positioning ?
|
08 March 2020, 16:38 | #10 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,406
|
Nope. I guess this is because of how DMA based vertical multiplexing works. If writing to SPRxCTL would not disable the sprite, using the DMA multiplexer would mean the last line of a sprite would be repeated every time you vertically multiplex it.
|
08 March 2020, 16:40 | #11 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
|
|
08 March 2020, 16:48 | #12 |
Lemon. / Core Design
Join Date: Mar 2016
Location: Tier 5
Posts: 1,209
|
hmm.. ok.. it might be better for me to stick with DMA sprites... just that because the data is repeating, I hoped to eliminate that 1kb per sprite overhead (DMA and memory use)... but I really need the 1 pixel positioning.
But all the above info is really useful for future reference too |
08 March 2020, 17:39 | #13 |
Registered User
Join Date: Jan 2012
Location: USA
Posts: 372
|
From the reference manual:
http://amigadev.elowar.com/read/ADCD.../node02D6.html Notice the SR latch is reset when SPRxCTL is accessed disabling the sprite and access to SPRxDATA sets it and enables the sprite, as Toni wrote. Not sure why that was done. It is possible to change HPOS without disabling a sprite if you're willing to lose a bit of HPOS res. |
08 March 2020, 17:58 | #14 |
Lemon. / Core Design
Join Date: Mar 2016
Location: Tier 5
Posts: 1,209
|
I really need that pixel perfect x positioning unfortunately... so I will just have to continue using DMA sprites and take the extra memory and DMA hit (it's not huge, but every little helps as they say)
|
08 March 2020, 18:12 | #15 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
|
It makes DMA mode work without need for extra communication channel between Denise and Agnus. Denise has no idea if it is Agnus or CPU or copper doing sprite register writes. (It is same for bitplanes, Denise does not know or care where BPLxDAT writes come from)
Usual sprite DMA sequence goes like this: - Agnus DMA writes to SPRxPOS and SPRxCTL. CTL write -> Agnus sprite's DMA gets disabled and Denise disables sprite's horizontal comparison. - Each scanline, during sprite's DMA slot, Agnus compares sprite start and stop vertical positions. When start matches, Agnus re-enables sprite's DMA and starts doing SPRxDATA and SPRxDATB writes: Denise sprite's horizontal comparison is enabled (SPRxDATA write) and sprite is shifted out when it matches. When Agnus vertical stop matches: Agnus switches back to SPRxPOS and SPRxCTL writes and loads them again, both Agnus and Denise side sprite enable flags are cleared. This also explains why disabling sprite DMA causes full screen height sprite: Sprite stays active because only SPRxCTL write can disable Denise-side sprite output. Last edited by Toni Wilen; 08 March 2020 at 20:56. Reason: SPRxDATB->DATA |
08 March 2020, 20:02 | #16 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,214
|
Historical comment: Thie sprite engine of the Amiga is pretty much an enhanced version of the player/missle logic of the Atari 8 bit machines. There, the "DMA controller" ANTIC reads the player data (=sprite shape) at the start of the horizontal blank, and the display controller GTIA (lookalike of Denise) just listens to the bus, getting the data while ANTIC pulls it from memory. Of course the CPU can fill the Player shape data as well, and then you get a vertical bar.
As in the Amiga, the horizontal player comparison is done in the display generator (GTIA or Denise), the sprite refilling is done by the DMA processor (ANTIC of AGNUS). The new feature is that the DMA controller AGNUS received a vertical comparison register at which it starts or stops the DMA of the shape data. So, it was more or less done this way "because it was done this way already before". |
08 March 2020, 20:23 | #17 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
Quote:
(probably everyone do it because it's more useful and 'natural' to write to first plane data and clear the second). Edit: actually because it's the only way Last edited by ross; 08 March 2020 at 21:04. |
|
08 March 2020, 20:57 | #18 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
|
Only SPRxDATA enables it. It was correct in my first post but not in second post. Fixed.
|
08 March 2020, 21:01 | #19 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
|
08 March 2020, 21:24 | #20 | |
Registered User
Join Date: Jan 2012
Location: USA
Posts: 372
|
Quote:
Simplifies the logic. Helps understand how to vertically multiplex sprites using DMA without introducing an unusable scanline between them. So as long as SPRxPOS and SPRxCTL are changed sometime after the appearance of the sprite on the previous scanline and they contain the start VPOS of the next scanline before sprite DMA, DMA will continue to fetch DATA and DATB. Is that any help to you, DanScott? |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Displaying hardware sprites to the left of DDFSTART | DanScott | Coders. Asm / Hardware | 12 | 10 March 2019 20:37 |
Screen not displaying on 2.6.1 | Amiga1992 | support.WinUAE | 4 | 25 August 2013 17:50 |
Crystal Kingdom Dizzy sprites not displaying correctly | lesta_smsc | support.Games | 9 | 05 October 2012 22:53 |
Displaying images | Tiddlypeeps | Coders. Tutorials | 40 | 30 August 2012 10:11 |
Displaying sprites | Hewitson | Coders. General | 18 | 27 April 2011 16:35 |
|
|