English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 10 March 2020, 23:48   #1
DanielAllsopp
Registered User

DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 48
Resetting Sprite Pointers

You can tell I've got a bit time to get back to my 68k ASM hobby can't you Sorry guys, not too many more questions... I hope!

So, I'm trying to reuse some sprites set up in my copper list like this:

Code:
HUDPtrs:
  dc.w SPR0PTH,$0000
  dc.w SPR0PTL,$0000
  dc.w SPR1PTH,$0000
  dc.w SPR1PTL,$0000
  dc.w SPR2PTH,$0000
  dc.w SPR2PTL,$0000
  dc.w SPR3PTH,$0000
  dc.w SPR3PTL,$0000

ParallaxPtrs:
  dc.w SPR4PTH,$0000
  dc.w SPR4PTL,$0000
  dc.w SPR5PTH,$0000
  dc.w SPR5PTL,$0000
  dc.w SPR6PTH,$0000
  dc.w SPR6PTL,$0000
  dc.w SPR7PTH,$0000
  dc.w SPR7PTL,$0000

  dc.w $3805,$fffe
SpritePtrs:
  dc.w SPR0PTH,$0000
  dc.w SPR0PTL,$0000
  dc.w SPR1PTH,$0000
  dc.w SPR1PTL,$0000
What I'm basically doing is poking the address of two non-attached sprites in HUDPtrs label at the correct offsets for SPR0 and SPR1. Then I'm poking one attached sprite into ParallaxPtrs.

Any unused sprite pointers are being assigned a blank sprite.

As you can see at the bottom though, I'm waiting for line $38 and then re-setting up SPR0 and SPR1. These values are poked via the CPU, like the other sprites, from my main loop.

The problem is the sprite does not show at all. It is legal to reuse sprite pointers like this isn't it? If I remove the 'WAIT' command from the copper list, the sprite shows fine, but obviously the original 'HUD' ones then don't appear.
DanielAllsopp is offline  
Old 11 March 2020, 00:49   #2
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,710
Ah, vertical sprite re-use can't be done by just resetting the sprite pointers*. You'll also have to set the position & control registers to new values for the new sprite.

There's a couple of different ways to achieve vertical sprite re-use. The easiest by far is having the sprite hardware do it for you. You can also do it manually, which is slightly more complicated but is more flexible.

The hardware way works as follows:
  • point sprite pointer at an area in memory containing your sprite data
  • set the first word of data in this area to be the sprite position register content
  • set the second word of data to be the sprite control register content
  • next include the first image data
  • after the first image data is complete, the next word is the new sprite position value
  • then the new sprite control value
  • image data
  • etc
  • last sprite image of the set ends with two zeros
This works very well, but has two drawbacks: the first being that each new image requires an additional empty line, the second that each image needs to be in memory straight after the other. Edit: more info on the hardware sprite multiplexing method can be found here: http://amigadev.elowar.com/read/ADCD.../node00B9.html

The manual way of doing this is to set new sprite control & position values using the Copper (or CPU, but that is extremely wasteful as it needs interrupts) and then set new pointer values. The disadvantage is a more complicated Copper list that takes up a tiny bit more raster time than the hardware way. The advantages are that you need not have an empty line between images and that you can use different areas in memory for different images.

*) there is an exception to this, but I'm assuming your HUD sprites have a vertical stop prior to $38.

Last edited by roondar; 11 March 2020 at 01:24.
roondar is offline  
Old 11 March 2020, 02:21   #3
DanielAllsopp
Registered User

DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 48
Cool, thanks roondar. I've read a bit about manual sprites in the HRM, so with your information I'm starting to get somewhere.

Two questions before I hit the hay, regarding this code:

Code:
  dc.w $6007,$fffe
SpritePtrs:
  dc.w SPR0POS,$608c
  dc.w SPR0CTL,$9000
  dc.w SPR0DATB,$0000
  dc.w SPR0DATA,$0000
  dc.w SPR1POS,$608c
  dc.w SPR1CTL,$9080
  dc.w SPR1DATB,$0000
  dc.w SPR1DATA,$0000
If I have the the SPR0DATA and SPR1DATA in the copper list, but poke the values into them, will they be armed only after being written to by the CPU, or are they armed with these default values?

When you say you need interrupts, is this the code by which I need to use an interrupt, when I'm poking the values into DATB and DATA?

Also, the values I poke there, they are the same I would poke into the SPR0PTR registers?

I'm getting some output in the correct place, but it's not the sprite I'm expecting:



Thanks again!
DanielAllsopp is offline  
Old 11 March 2020, 09:27   #4
Rotareneg
Registered User
 
Join Date: Sep 2017
Location: Kansas, USA
Posts: 117
The horizontal comparator is armed by ANY write to DATA: CPU, DMA, copper, it doesn't matter. Likewise, any write to CTL from any source disarms the comparator.
Rotareneg is offline  
Old 11 March 2020, 12:46   #5
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,710
Quote:
Originally Posted by DanielAllsopp View Post
Cool, thanks roondar. I've read a bit about manual sprites in the HRM, so with your information I'm starting to get somewhere.

Two questions before I hit the hay, regarding this code:

Code:
  dc.w $6007,$fffe
SpritePtrs:
  dc.w SPR0POS,$608c
  dc.w SPR0CTL,$9000
  dc.w SPR0DATB,$0000
  dc.w SPR0DATA,$0000
  dc.w SPR1POS,$608c
  dc.w SPR1CTL,$9080
  dc.w SPR1DATB,$0000
  dc.w SPR1DATA,$0000
If I have the the SPR0DATA and SPR1DATA in the copper list, but poke the values into them, will they be armed only after being written to by the CPU, or are they armed with these default values?
Assuming the Copperlist executes, they will be armed with the "default" values. The Copper can write to sprite registers* without the CPU being required.
*) actually, it can write to any register it can access without the CPU being required

Do note that the order matters (as pointed out by Rotareneg): writes to SPRxCTL will disable the sprite comparator (which disables the sprite), writes to SPRxDATA will enable the sprite comparator (which enables the sprite). Not a big problem, your order is already correct.
Quote:
When you say you need interrupts, is this the code by which I need to use an interrupt, when I'm poking the values into DATB and DATA?
When I say interrupts I mean the distinction between using the Copper to write registers, or setting up a CPU interrupt and using the CPU to write the registers directly. I'd use the Copper if I were you, the CPU option is usually not needed on the Amiga - I merely mentioned it to be complete.

So no, this piece of Copper code is not an interrupt as I meant it.
Quote:
Also, the values I poke there, they are the same I would poke into the SPR0PTR registers?

Thanks again!
The SPRxPTR registers only contain pointers to memory, so no

I guess you mean to ask if the values for SPRxPOS/CTL/DATA/DATB are the same as using the sprite hardware in "automatic" mode. In which case the answer is yes.
roondar is offline  
Old 11 March 2020, 13:45   #6
DanielAllsopp
Registered User

DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 48
Quote:
Originally Posted by roondar View Post
Assuming the Copperlist executes, they will be armed with the "default" values. The Copper can write to sprite registers* without the CPU being required.
*) actually, it can write to any register it can access without the CPU being required
I guess I'm getting confused with how I would use the copper to look at the sprite data I have included into the app, which is output as ASM source code from piccon.

What I've done up to now is just poke the memory addresses into the relevant copper instructions from a label I have setup in the included sprite data.

Quote:
Originally Posted by roondar View Post
Do note that the order matters (as pointed out by Rotareneg): writes to SPRxCTL will disable the sprite comparator (which disables the sprite), writes to SPRxDATA will enable the sprite comparator (which enables the sprite). Not a big problem, your order is already correct.
When I say interrupts I mean the distinction between using the Copper to write registers, or setting up a CPU interrupt and using the CPU to write the registers directly. I'd use the Copper if I were you, the CPU option is usually not needed on the Amiga - I merely mentioned it to be complete.

So no, this piece of Copper code is not an interrupt as I meant it.
The SPRxPTR registers only contain pointers to memory, so no

I guess you mean to ask if the values for SPRxPOS/CTL/DATA/DATB are the same as using the sprite hardware in "automatic" mode. In which case the answer is yes.
Yup, I think I'm almost there, apart from the above question of how to use SPR0DATA and SPR0DATB with regards to an included sprite source resource. I couldn't find anything online on how to do this.

Sorry if I'm rambling, I'm currently in the middle of porting some Objective-C code to Swift, and trying to decipher 68k ASM in my head at the same time. It's rather confusing to say the least.

68k is way more interesting though!
DanielAllsopp is offline  
Old 11 March 2020, 14:10   #7
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,710
Quote:
Originally Posted by DanielAllsopp View Post
I guess I'm getting confused with how I would use the copper to look at the sprite data I have included into the app, which is output as ASM source code from piccon.

What I've done up to now is just poke the memory addresses into the relevant copper instructions from a label I have setup in the included sprite data.

Yup, I think I'm almost there, apart from the above question of how to use SPR0DATA and SPR0DATB with regards to an included sprite source resource. I couldn't find anything online on how to do this.
Well, I'm not sure I can totally fix this but let's see if I can't help out a bit.

The first thing is to realise that the SPRxDATA/SPRxDATB registers contain nothing more than a single line of sprite image data for a sprite. SPRxDATA contains the data for the first bitplane, SPRxDATB contains the data for the second bitplane. The second thing to realise is that this is identical to how hardware sprites work: every line of sprite data is two words - first the data for first bitplane, then the data for the second bitplane.

So an automatic mode sprite that looks like this in memory:
Code:
Sprite position value, Sprite control value
line 1 word 1, line 1 word 2
line 2 word 1, line 2 word 2
line 3 word 1, line 3 word 2
etc
Would look like this as a manual mode sprite
Code:
SPRxPOS=sprite position value
SPRxCTL=sprite control value
SPRxDATA=line 1 word 1
SPRXDATB=line 1 word 2
SPRxDATA=line 2 word 1
SPRXDATB=line 2 word 2
SPRxDATA=line 3 word 1
SPRXDATB=line 3 word 2
However, the above would not work if put in the Copper list - it updates the sprite data too quickly, causing only the last line to be visible. Instead, after each write to both SPRxDATA and SPRxDATB the Copper needs to wait until the next scanline of sprite data is needed:
Code:
WAIT VPOS=$60,HPOS=somewhere outside of visible display
SPRxPOS=sprite position value
SPRxCTL=sprite control value
SPRxDATA=line 1 word 1
SPRXDATB=line 1 word 2
WAIT VPOS=$61,HPOS=somewhere outside of visible display
SPRxDATA=line 2 word 1
SPRXDATB=line 2 word 2
WAIT VPOS=$62,HPOS=somewhere outside of visible display
SPRxDATA=line 3 word 1
SPRXDATB=line 3 word 2
etc
The last thing to realise is that the Copper list is just a block of memory from the perspective of CPU/Blitter, which means you can write to it using the CPU or Blitter as you see fit.

So, to update the sprite data to show what you want, you write the correct values for the image you want at the correct offsets in memory. You can use labels for this. It helps to write a Copperlist that has a set number of bytes between each sprite data value. This will allow you to use a loop or a blit.

For the above, that would be something like:
Code:
lea.l spr_data,a0
lea.l spr_data_copper_list_offset,a1
moveq #spr_height-1,d7
.lp
move.w (a0)+,(a1)
move.w (a0)+,4(a1)
lea.l 12(a1),a1
dbra d7,.lp
Assuming I counted the number of bytes between the copper list entries correctly - no guarantees there

Hope this helps a bit.
Quote:
Sorry if I'm rambling, I'm currently in the middle of porting some Objective-C code to Swift, and trying to decipher 68k ASM in my head at the same time. It's rather confusing to say the least.

68k is way more interesting though!
Heh, I get what you mean. I write SQL all day, which is a big downer on my Amiga output
roondar is offline  
Old 11 March 2020, 15:35   #8
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,442
Quote:
Originally Posted by roondar View Post
..I write SQL all day..
(only because there is not The Scream of Munch emoticon available)

ross is offline  
Old 12 March 2020, 12:11   #9
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,710
Quote:
Originally Posted by ross View Post
(only because there is not The Scream of Munch emoticon available)

Pfft, nothing wrong with a database. Full of goodness. Full of vitamins...
At any rate, my SQL stuff pays for my Amiga stuff so I can't really complain all that much
roondar is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
A1200 Resetting blade002 support.Hardware 6 22 April 2016 19:31
Resetting sprite problems Knocker Coders. Asm / Hardware 11 29 January 2016 01:30
A500: Trouble with resetting BYTEMAN support.Hardware 7 21 December 2008 04:57
Whdload games resetting Rave support.WinUAE 8 08 September 2004 21:38
HD games resetting under WinUAE Rave support.WinUAE 3 07 September 2004 23:53

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


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


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.
Page generated in 0.07032 seconds with 14 queries