English Amiga Board


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

 
 
Thread Tools
Old 24 January 2016, 00:14   #1
Knocker
Registered User
 
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
Resetting sprite problems

Hello everyone. I've been working on a simple game, but I've gotten stuck. For some reason I can't get my scoring/reset sprite code to work. I've trimmed down the problematic code into a simple program (attached - Vanilla A500/Devpac 3.02).

This is the desired behavior:
Sprite0 moves towards Sprite2. Upon collision the sprite stops and a dot ("score") is drawn. When you press F1 the sprite goes back to the starting point and starts moving again. After each collision another dot is drawn. After restarting program all state is cleared.

But this is the behavior I'm getting:
First time program runs: Sprite0 moves towards Sprite2. Upon collision the sprite stops and a dot is drawn (so far so good). When you press F1 sprite0 goes back to the starting point, but doesn't move and another dot is drawn!? When pressing F1 again sprite starts moving but upon collision score isn't increased. After restarting program, state isn't cleared (dot still shown and sprite doesn't move).

Not sure if I'm misunderstanding something with sprite collision, if sprite1 is somehow interfering, or if the way I use keyboard is wrong. I've really tried but I've run out of ideas now.

I'd be eternally grateful* if someone could help. General comments on the program is also welcome.

Thanks!

Knocker

*Well, at least until the singularity hits us
Attached Files
File Type: s SpriteScore.s (4.7 KB, 138 views)
Knocker is offline  
Old 24 January 2016, 09:59   #2
thomas
Registered User
 
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 6,985
I don't know how to program collision detection on the Amiga, but to me your description sounds like you have to reset the collision bit after you checked it. It seems to stay set even if you move the sprite to another position.
thomas is offline  
Old 24 January 2016, 17:36   #3
Knocker
Registered User
 
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
Thanks thomas. The bit should be cleared automatically upon being read, see doc.
Knocker is offline  
Old 24 January 2016, 18:22   #4
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
You need to read CLXDAT after reseting the sprite position to clear previous collision state. Hardware collision checks are immediate, for example if you read CLXDAT when sprite is being drawn, collision bits gets set again immediately after you have read it.

btw, code has some oddities.

- saving SR in interrupt is not needed, SR is automatically saved and RTE automatically restores it from stack.

- clr.l $dff08a

- bset #15,OldINTENA. Yes, it does work in this case but I am quite sure it does not work like you expected it to work.

(I don't comment about system take over part because obviously it is just a test program )
Toni Wilen is offline  
Old 27 January 2016, 07:16   #5
Knocker
Registered User
 
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
Thanks Toni, I got it to work after moving the sprite and then reading CLXDAT again. Really appreciate the response, and thanks a bunch for all the excellent work on WinUAE!

What did you mean to say about "clr.l $dff08a"? Not needed?
Also, what do you think I intended to do with "bset #15,OldINTENA"? I actually didn't write the VBL interrupt code myself, so to be honest I'm not quite sure what the intention was. What do you recommend I do instead?
Knocker is offline  
Old 27 January 2016, 12:06   #6
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
Quote:
Originally Posted by Knocker View Post
What did you mean to say about "clr.l $dff08a"? Not needed?
It is word wide register. Not long word. Also technically clr is not good choice for strobe registers because clr <any memory address> on 68000 (only on 68000) does read first and then writes zero. It will strobe copper twice but it rarely causes problems (unless first copper instruction is MOVE that does something critical, like write to BLTSIZ) , it is just technically wrong

Quote:
Also, what do you think I intended to do with "bset #15,OldINTENA"? I actually didn't write the VBL interrupt code myself, so to be honest I'm not quite sure what the intention was. What do you recommend I do instead?
bset (and similar instructions) is byte wide when accessesing memory. bset #15 is exactly same as bset #7 or bset #31 and so on. (It is only 32 bit wide when target is data register)

bset #15-8,OldINTENA is more clear and makes it less likely to accidentally write (for example) bset #0,OldINTENA when you wanted to clear word wide bit 0, which would be bset #0,OldINTENA+1
Toni Wilen is offline  
Old 28 January 2016, 00:31   #7
Knocker
Registered User
 
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
Thanks again Toni. Later versions of Devpac actually gives you an error if you try to set bit > 7 with bset. What I don't understand though is how my code can actually work, when it is setting bit 7, which is AUD0?!

So to really set bit 15 (the SET/CLR bit) I should do this?
or.w #%1000000000000000,OldINTENA

I tried bset #7,OldINTENA+1 - but that didn't work...
Knocker is offline  
Old 28 January 2016, 10:12   #8
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,408
Quote:
Originally Posted by Knocker View Post
Thanks again Toni. Later versions of Devpac actually gives you an error if you try to set bit > 7 with bset. What I don't understand though is how my code can actually work, when it is setting bit 7, which is AUD0?!

So to really set bit 15 (the SET/CLR bit) I should do this?
or.w #%1000000000000000,OldINTENA

I tried bset #7,OldINTENA+1 - but that didn't work...
Like Toni said, BSET only works on bytes if used on a memory address.
The 68000 stores words and longs in memory starting with the highest byte, so a word is stored bits 15-8 in address given +0 and bits 7-0 in address given +1.

Furthermore, if you use BSET with a higher bit than 7 on a memory adress, the 68000 only looks at the 7 lowest bits in the given byte.

So, if you say BSET #15,OldINTENA, it alters bits for the given adress - OldINTENA. This contains the top byte of the word as I explained above. Now, the 68000 can't set bit 15 of a byte. To fix this, internally the processor does an AND #7 on the given bit number.

Take it all together and BSET #15,OldINTENA does the following:

1) Take the byte at OldINTENA, which contains bits 15-8 of the word stored at OldINTENA and OldINTENA+1
2) Change bit #15 AND #7 to 1 (changing bit #7 of the byte at OldINTENA)
3) Store it back at OldINTENA

Hopefully this helps explain why doing BSET #15,OldINTENA does what you want.

Last edited by roondar; 28 January 2016 at 11:18.
roondar is offline  
Old 28 January 2016, 10:28   #9
hooverphonique
ex. demoscener "Bigmama"
 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
Quote:
Originally Posted by Knocker View Post
Thanks again Toni. Later versions of Devpac actually gives you an error if you try to set bit > 7 with bset. What I don't understand though is how my code can actually work, when it is setting bit 7, which is AUD0?!

So to really set bit 15 (the SET/CLR bit) I should do this?
or.w #%1000000000000000,OldINTENA

I tried bset #7,OldINTENA+1 - but that didn't work...
what you did originally references the correct bit... If you don't understand why, look up the difference between big endian and little endian (the 68k is big endian).
hooverphonique is offline  
Old 28 January 2016, 11:50   #10
Apollo
Registered User
 
Apollo's Avatar
 
Join Date: Sep 2008
Location: Germany
Age: 49
Posts: 137
The SET/CLR bit decides if the bits are set or cleared in the register (this is true for all amiga custom registers using a SET/CLR bit)

examples

%1000000000000000 -> would no nothing (despite that you wrote a WORD into the register) because you say with the '1' in the 16th bit that you want to set a '1' to any bit which has a '1'

%1000000000000001 -> would set the first bit of the register to '1' because you set the SET/CLR bit to '1' and set the first bit to '1', all other bits remain unchanged

%1000000000000101 -> would set the first and third bit of the register to '1', again, all other bits remain unchanged

%1111111111111111 -> would set all bits in the register to '1' except the 16th bit, because this is 'only' the SET/CLR bit

setting the 16th bit to '0'

%0000000000000001 -> would clear the first bit to '0' und would not change any other bit

%0000000010100001 -> would clear the first, sixth and eight bit to '0' and would not change anything else


or a more real world example
If the register has the following value

%0000000000111001

and you would write the following into it:

%1000000000000010 (SET/CLR is active saying 'i want to set bits')

then it would be afterwards:

%0000000000111011 (hence the second bit is now set)

now you write the following

%0000000000111000

then it is:

%0000000000000011 (hence, the 4th,5th and 6th bit are cleared now)

I hope this helped a bit.
Apollo is offline  
Old 28 January 2016, 12:49   #11
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
Quote:
Originally Posted by Apollo View Post
The SET/CLR bit decides if the bits are set or cleared in the register (this is true for all amiga custom registers using a SET/CLR bit)
This is about modifying memory addresses, not custom registers (where byte access would be wrong anyway)
Toni Wilen is offline  
Old 29 January 2016, 00:30   #12
Knocker
Registered User
 
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
Thanks all. I should have been able to figure this out myself. Pretty "interesting" that bset behavior depends on the destination. Definitely something to watch out for.
Knocker 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
FS-UAE 2.6.2 in OS X El Capitan - Workbench keep resetting WeiXing3D support.FS-UAE 0 15 November 2015 07:47
Mani Pulite sprite problems (A500 mode) andreas support.WinUAE 17 22 January 2015 14:41
A500: Trouble with resetting BYTEMAN support.Hardware 7 21 December 2008 03:57
Whdload games resetting Rave support.WinUAE 8 08 September 2004 20:38
HD games resetting under WinUAE Rave support.WinUAE 3 07 September 2004 22: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 13:03.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.11313 seconds with 16 queries