English Amiga Board


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

 
 
Thread Tools
Old 25 August 2019, 22:41   #1
MrGuppy
Registered User
 
Join Date: May 2019
Location: Stenungsund/Sweden
Posts: 5
Flickering sprites::..

Hi!


Trying to learn about sprites and how to move them. The problem occurres when I try to move the sprite vertically, it starts to flicker and the data looks messy, horizontally it looks OK?
Sorry for the swedish code comments!

Code:
		************************************************
	*****************Initiera värden före mainloop*********************** 	
		************************************************


	********************
	* Allokera minne
	********************
	SECTION Sprite,CODE	; Allokera minne för koden
	JUMPPTR init		; Hoppa till init


		****************************************
	********************** Konstanter ******************************
		****************************************


	****************************
	* Konstanter för skärmen
	****************************
bplsize	=10240		; Skärmstorleken på bitplanet -> 320*256/8
		


		****************************************	
	************************ INIT *************************************
		****************************************

	

init:
	*******************************
	* Spara undan Default COPPER	
	*******************************
	moveq #0,d7		; Flagga för spritens rörelse


	moveq #9,d6		; Sprite_flag
	move.l 4.w,a6		; För att kunna öppna ett LIBRARY -> execbase
	clr.l d0
	move.l #gfxname,a1	; "gfxname" -> biblioteket vi vill öppna
				; "gfxname" är deklarerad längre ned i
				; koden
				 
	jsr -408(a6)		; Hoppa till "Open Library" i execbase, dvs
				; funktionen "oldopenlibrary()"
				; Nu har vi hamnat i "Graphics library", start
				; adressen läggs i d0
	move.l d0,a1
	move.l 38(a1),d4	; Fånga nuvarande "copper pointer" och
				; spara i d4

	jsr -414(a6)		; Hoppa till "Close Library" i execbase,
				; funktionen "closelibray()"
			
	************************
	* Hantera interrupts
	************************
	move.w $dff01c,d5	; Läs av alla interrupts och lägg i d5,
				; dessa	behövs senare när vi hoppar ur 
				; vår demo  

	move.w $dff002,d3	; $dff002 -> Läser innehållet från DMACON
				; Läs DMACON och lägg i d3

			
	********************************
	* "Wait for end of frame"
	* Efter detta kan man börja 
	* läsa in sprites osv
	********************************
	move.w #$138,d0		; #$138 ->312
	bsr.w waitraster	; Hoppa till "waitraster"
				; Waits for end of frame!	
				; Tar bort "Sprite flickers"!!!

	move.w #$7fff,$dff09a	; Stäng av alla interuppts, mus osv!!!
				; Disable all bits in INTENA	 
				; $dff01c -> Läser interrupts, PEEK
				; $dff09a -> Sätter interrupts, POKE

	move.w #$7fff,$dff09c	; Stäng av alla "Interuppts Requests"
	move.w #$7fff,$dff09c	; Görs 2 ggr så att demon även funkar på A4000
	move.w #$87e0,$dff096	; Stäng av alla "DMA" inklusive "COPPER DMA"
				; (DMACON)
				; $dff096 -> Skriver till DMACON
				
	
hwinit:	
	*****************************
	* Hardware Init	
	*****************************
	movem.l d0-a6,-(sp)	; Lägg alla variabler på stacken	
	
	lea screen,a1		; lea -> Load the Effective Adress
				; a1 kommer att peka på det
				; reserverade minnet "screen"
				
	move.w #bplsize-1,d0	; 10240 -> d0

.l:	move.b #0,(a1)+		; Fyll "screen" med 0 

	dbf d0,.l		; Upprepa 10240 ggr		
	
	************************
	* Läs in spritedata 
	* till sprite pointers
	************************
	lea SprP,a1		; Peka på "sprite pointers"
	lea spr,a0		; Peka på "sprite data"

	move.l a0,d1
	swap d1
	move.w d1,2(a1)		; Flytta skärmdata till SprP1, hi word 
	swap d1
	move.w d1,6(a1)		; Flytta skärmdata till SprP1, lo word

	************************
	* Fyll resterande 7  
	* sprites med 0
	************************
	lea Nullspr,a0		; Peka till adressen "Nullspr"
	move.l a0,d1

	moveq #7-1,d0		; Antal loopningar
	
.sprpl:	addq.w #8,a1		; Hoppa till nästa sprite
	swap d1
	move.w d1,2(a1)		; Flytta skärmdata till SprP, hi word 
	swap d1
	move.w d1,6(a1)		; Flytta skärmdata till SprP, lo word
	
	DBF d0,.sprpl		; Loopa 7 ggr		


	*********************
	* Enable COPPER DMA	; <- OBS! Super viktig!!!
	*********************
	move.w #$87e0,$dff096	; Enable COPPER DMA -> Allt som behövs
				; för att göra en demo, sprites, musik osv

	
	************************
	* Peka på COPPER
	************************
	move.l #copper,$dff080	; $dff080 = "Copper first location register"
				; move.l -> #copper = "Long Word" adress
				; Ändra COPPER till vår egna modifierade COPPER



		*********************************
	******************** Mainloop ***************************
		*********************************


mainloop:

	****************************************
	* Avvakta med att gå vidare med koden
	* då raster är utanför skärmen, om inte
	* detta görs skapas flimmer på sprites
	****************************************
waitframe:
	btst #0,$dff005		; Är raster längst till vänster 
				; på skärmen?
	bne.s waitframe
		
	cmp.b #$2a,$dff006	; Är rastern högst upp på skärmen? 
				; Vänta till Y-pos $2a eftersom
				; copper börjar på $2b		
	bne.s waitframe
waitframe2:
	cmp.b #$2a,$dff006	; Är rastern högst upp på skärmen? 
	beq.s waitframe2	
	
	****************************************
	* Sätt Sprite 1 i rörelse
	* Origin x- and y-pos -> $6496,$7400
	* Y-pos #$64 ->100
	* X-pos #$96 ->150
	****************************************
	cmp #1,d7	; Är flaggan för "up" satt?
	beq.s up	

	lea.l spr,a1	; Peka på spritedata

	cmp.b #$e6,(a1)	; Är Y-pos=230?
	beq.s up_flagga 

down:
	;add.w #1,(a1)	; X-pos
	addq.b #1,(a1)	; Y-pos
	addq.b #1,2(a1)	; Y-pos
	bra.s continue

up:
	lea.l spr,a1	; Peka på spritedata

	cmp.b #$64,(a1)	; Är Y-pos=100?
	beq.s down_flagga 

	add.b #-1,(a1)	; Y-pos
	add.b #-1,2(a1)	; Y-pos

continue:
	*******************************
	* Vänster musknapp nedtryckt?
	*******************************
	btst #6,$bfe001	; Testa om vänster musknapp är nedtryckt
	bne.s mainloop	; Om inte gå till "waitmouse"


	
exit:
	************************
	* Exit
	************************
	move.w #$7fff,$dff096	; Stäng av alla "DMA" inklusive "COPPER DMA"
				; (DMACON)
		
	or.w #$8200,d3		; Bit 9
	move.w d3,$dff096	; Sätt bit 9 i DMACON	
	move.l d4,$dff080	; Lägg tillbaks "copper pointer" som
				; vi sparade undan i d4 
	or #$c000,d5		; Sätt bit 14 o 15 -> ?1<<14+1<<15
				; Detta sätter på interruptsen igen! 
	move d5,$dff09a
	rts



		**************************************
	*********************** ROUTINES *****************************
		**************************************


******************************
* Wait for end of frame
* Tar bort sprite flimmer
******************************
waitraster:
	move.l #$1ff00,d2	; Masken läggs i d2
	lsl.l #8,d0		; d0 -> Y-pos($138 = 312)
				; lsl -> Shifts bits to the left
	and.l d2,d0		; "Maska" d0 med d2
	
	lea $dff004,a0		; Read from Vertical 
				; and horizontal register and put it in a0
				 	
.wr	move.l (a0),d1
	and.l d2,d1		; Maska även denna
	cmp.l d1,d0
	bne.s .wr
	rts


up_flagga:
	moveq #1,d7	
	bra.s continue

down_flagga:
	moveq #0,d7	
	jmp continue

		********************************
	**************Deklarera "gfxname"******************
		********************************
gfxname:
	dc.b "graphics.library",0



	
		*********************************
	**************COPPER - CO PROCESSOR*******************
		*********************************

	SECTION Sprite_Data,DATA_C	; Allokera minne för all grafik(Copper)
					
				 


spr:
	************************
	* Sprite Data
	* Sprites är endast 
	* 16 bitar bred 
	************************	
	dc.w $6450,$7400	; Start pos för Y och X -> $6496 
				; -> $64=Y-pos -> 100
				; -> $96=X-pos -> 150

				; Stop pos för Y och X -> $7400  
				; -> $74=Y-pos + sprite hight(16 hög)

				; -> $00
				; Formel för X-pos: %A0000SEH
				; %A0000SEH -> 64 32 16 8 4 2 1		
				; H=1, E=2, S=4
				; S->Start, E->End, H->Horizontal 

				; -> A = Attach bit, sätts till $00  
				; om man inte vill kombinera två sprites
				 
	dc.w %0000000000000000,%0000000000000000
	dc.w %0000000000000000,%0000000000000000
	dc.w %0000000000000000,%0000000000000000
	dc.w %0000000000000000,%0000000011000000
	dc.w %0000000000000000,%0000001111000000
	dc.w %0000000000000000,%0000111111000000
	dc.w %0000011111110000,%0001100000000000
	dc.w %0001111111001000,%1100000000000000
	dc.w %0011111111001100,%1100000000000000
	dc.w %0011111111110000,%1100000000000000
	dc.w %0011111111111100,%0100000000000000
	dc.w %0001111111111000,%1100000000000000
	dc.w %0000111111100000,%0000000000000000
	dc.w %0000000000000000,%0000001111000000
	dc.w %0000000000000000,%0000000011000000
	dc.w %0000000000000000,%0000000000000000
	dc.w 0,0

Nullspr:				; Dummy Sprite
	dc.w $2a20,$2b00		; Outside screen
	dc.w 0,0
	dc.w 0,0

Copper:
	dc.w $1fc,0		; Slow Fetch Mode -> AGA kompatibel(A1200)
				; dc = define constant

	dc.w $100,$0200		; $100 = $dff100
				; $dff100 = "Bitplane enable register"
				; $100,$0200 -> Stänger av alla Bitplanes

	***************************
	* Sprite colors
	***************************
	dc.w $1a2,$f00		; Dessa tre färgregister används för 
	dc.w $1a4,$fa0		; sprite 0($122) och sprite 1($124) 
	dc.w $1a6,$fff
				; För sprite 2($128) och 3($12c) använd 
				; färgregister $1a8, $1aa och $1ac
				; osv.....................
	
SprP:
	***************************
	* Deklararera minne 
	* till sprites 
	* SpritePointers 
	***************************
	dc.w $120,0			; Peka på vår sprite data, "high word"
	dc.w $122,0			; Sprite 0($122), "low word"
					
	dc.w $124,0			; Alla sprites pekare måste sättas,
	dc.w $126,0			; man kan inte bara sätta en
					; 8 sprites totalt!
	dc.w $128,0	
	dc.w $12a,0

	dc.w $12c,0
	dc.w $12e,0

	dc.w $130,0	
	dc.w $132,0

	dc.w $134,0	
	dc.w $136,0

	dc.w $138,0	
	dc.w $13a,0

	dc.w $13c,0	
	dc.w $13e,0
	

	dc.w $180,$000		; Svart bakgrund		


	dc.w $100,$1200		; Aktivera ett bitplan
	
	dc.w $ffdf,$fffe	; Vänta med att sätta bakgrunds färg tills
				; vi kommit till Y-pos $ff(256)
				; och X-pos $df(223) 
				; Detta sätter färg "utanför" skärmens	
				; upplösning
				

	dc.w $ffff,$fffe	; Väntar på en omöjlig rasterlinje, $ffff 

	SECTION spritebss,BSS_C

Screen:
	ds.b bplsize			; Skärmstorleken på bitplanet
					; -> 320*256/8, ej "interleaved" 
					; ds -> "Declare Space"

..::Mr Guppy
Attached Files
File Type: s flickering_sprite.S (9.6 KB, 14 views)

Last edited by MrGuppy; 25 August 2019 at 22:51.
MrGuppy is offline  
Old 26 August 2019, 12:11   #2
phx
Natteravn

phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 1,425
Quote:
Originally Posted by MrGuppy View Post
The problem occurres when I try to move the sprite vertically, it starts to flicker and the data looks messy, horizontally it looks OK?
Hmm. The only real bug that I see is that you don't set BPL1PT in your copper list, although you did enable one bitplane. When I assemble and test your code I see the background flicker, because the bitplane pointer runs wild through Chip RAM. No idea why it should flicker on vetical movement only. Don't see that here.

Quote:
Sorry for the swedish code comments!
I understand danish. So not a big problem.
phx is offline  
Old 27 August 2019, 00:54   #3
MrGuppy
Registered User
 
Join Date: May 2019
Location: Stenungsund/Sweden
Posts: 5
Do I add the BPL1PT like this?:
Code:
	****************************
	* Konstanter för skärmen
	****************************
bplsize	=10240		; Skärmstorleken på bitplanet -> 320*256/8
screen_m   =$60000 		

--------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------

copperBplP:

        dc.w $e0,(Screen_m>>16)&$ffff
	dc.w $e2,(Screen_m)&$ffff

	dc.w $180,$000		; Svart bakgrund		
	dc.w $100,$1200		; Aktivera ett bitplan
	dc.w $ffdf,$fffe	; Vänta med att sätta bakgrunds färg tills
				; vi kommit till Y-pos $ff(256)
				; och X-pos $df(223) 
				; Detta sätter färg "utanför" skärmens	
				; upplösning
	dc.w $ffff,$fffe	; Väntar på en omöjlig rasterlinje, $ffff
MrGuppy is offline  
Old 27 August 2019, 09:05   #4
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,281
That should work, yes

...though it's probably best to make sure the memory used is actually allocated for when you want to start drawing stuff ...

For tests like this, I'd use an extra section of type chip (usually anyway, sometimes it's data_c - it depends a bit on assembler used). For bigger programs launched from the OS, I normally just allocate the memory using the OS.
roondar is offline  
Old 27 August 2019, 12:11   #5
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 1,842
And alway remember to reset stack if you want a clean exit
Code:
	movem.l d0-a6,-(sp)	; Lägg alla variabler på stacken
ross is offline  
Old 27 August 2019, 17:36   #6
phx
Natteravn

phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 1,425
Quote:
Originally Posted by MrGuppy View Post
Do I add the BPL1PT like this?:
You already had your bitplane defined under the label "screen" in a Chip-RAM BSS section, which is absolutely correct. I would use this area by patching the address of screen into your copper list, like you did with sprP for the sprites.

Quote:
Originally Posted by ross View Post
And alway remember to reset stack if you want a clean exit
Wow... missed that. Good catch!

Last edited by phx; 27 August 2019 at 17:42. Reason: typo
phx is offline  
Old 27 August 2019, 18:14   #7
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,281
Quote:
Originally Posted by phx View Post
You already had your bitplane defined under the label "screen" in a Chip-RAM BSS section, which is absolutely correct. I would use this area by patching the address of screen into your copper list, like you did with sprP for the sprites.
I completely missed that in the original source. Turns out you need to scroll down to the bottom. Not a skill I have it seems.

Forget my comments about allocating then.
roondar is offline  
Old 27 August 2019, 21:28   #8
MrGuppy
Registered User
 
Join Date: May 2019
Location: Stenungsund/Sweden
Posts: 5
As mentioned I had forgot to restore the variabels when exit!
Code:
movem.l (sp)+,d0-a6
MrGuppy is offline  
Old 28 August 2019, 00:02   #9
MrGuppy
Registered User
 
Join Date: May 2019
Location: Stenungsund/Sweden
Posts: 5
phx, is this the right way?

Code:
lea copperBplP,a1
lea screen,a0

move.l a0,d1
swap d1
move.w d1,2(a1)
swap d1
move.w d1,6(a1)

-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------

copperBplP:
           dc.w $e0,0
           dc.w $e2,0
MrGuppy is offline  
Old 28 August 2019, 15:14   #10
phx
Natteravn

phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 1,425
Looking good.
Hint: You can save one "swap d1" when you write to 6(a1) first.
phx is offline  
Old 28 August 2019, 21:12   #11
MrGuppy
Registered User
 
Join Date: May 2019
Location: Stenungsund/Sweden
Posts: 5
Nice, thanks for the help!
MrGuppy 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
Flickering 3d objects Foebane support.WinUAE 40 04 October 2018 17:27
Kick off 2 flickering msayed1977 support.WinUAE 24 05 April 2013 20:42
hires flickering... sometimes Tony Landais support.WinUAE 11 17 July 2006 16:10
Flickering sprites in Quik the Thunderrabbit Tim Janssen support.Games 3 08 May 2003 08:12
Flickering sprites Mr Softy support.WinUAE 2 17 December 2002 12:56

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 12:41.


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