English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General > Coders. Tutorials

 
 
Thread Tools
Old 20 May 2009, 20:24   #1
Vortex
Used Register
 
Vortex's Avatar
 
Join Date: Nov 2008
Location: Headvillage / The Nethervoids
Age: 50
Posts: 103
Post ASM: Copper Bars

Hi there,

I've been tinkering with assembler on my A500. Great fun, and funny how you sort of never forget. Much like riding a bike...
Anyway, to refresh my memory I wrote some silly copper bar stuff. used ASMOne V1.20 (not quite your XCode IDE ).
Perhaps it could be of use to someone.

Oh, there seems to be a problem in the clearCopperList routine when using #$0000 as color. As if that value is simply not written in the copper list. I have absolutely no clue what might go wrong here, so if one of the experts want to have a look... Be my guest.

Next up is messing around with bit planes and blitter I guess. Let me know if I should post some more in the future, or that this is all you can take...
Attached Files
File Type: zip cbars.zip (2.7 KB, 502 views)

Last edited by Vortex; 20 May 2009 at 20:35.
Vortex is offline  
Old 21 May 2009, 00:44   #2
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
The error with the black color is in this line:

DBEQ d1,_clearCopperListLoop

The previous move of D0 containing zero will set the zero flag to true, and DBEQ will then test true and terminate. You want to change it to DBF so it only tests the counter register.
Leffmann is offline  
Old 21 May 2009, 08:47   #3
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
Nice little routine Vortex - thanks for sharing it.

Glad to know there's more guys like me out there playing around and having fun with asm coding on the Amiga.

Keep it up - and keep the code coming!
pmc is offline  
Old 21 May 2009, 09:27   #4
Vortex
Used Register
 
Vortex's Avatar
 
Join Date: Nov 2008
Location: Headvillage / The Nethervoids
Age: 50
Posts: 103
Hi PMC,

Have been following your threads...
thanks and will keep the code coming..

Lars
Vortex is offline  
Old 21 May 2009, 09:30   #5
Vortex
Used Register
 
Vortex's Avatar
 
Join Date: Nov 2008
Location: Headvillage / The Nethervoids
Age: 50
Posts: 103
Hi Leffmann,

Thank you for having a peek at my source.
I guess I've been programming in C for too long and mistakenly 'read' DBEQ d1,loop as: Test d1, decrement d1, branch, instead of: Test flags (in this case Z), decrement d1, branch... Should have read 68000 instruction manual better ...

So, Here's what's happening (I think):

MOVE.w #COPPER_LINES-1,d1

This puts #219 in register d1, striking the Zero flag.

_clearCopperListLoop:
MOVE.w d0,(a4)

This puts #0 in the address stored in a4, setting the Zero flag in the process.

ADD.l #8,a4

(Question: ADD also affects the Zero flag according to 68K instr. manual. Why does adding 8 to a4 not strike the Zero flag?)

DBEQ d1,_clearCopperListLoop

This first tests if the Zero flag is set. Apparently it is, so it falls through to next instruction resulting in the immediate end of the loop.

RTS



If anyone has an answer to my ADD.l #8,a4 question it will be highly appreciated.


Lars
Vortex is offline  
Old 21 May 2009, 09:57   #6
Redwood
Registered User
 
Join Date: Jun 2008
Location: Sydney / Australia
Posts: 83
Hi Vortex,

I'm only a beginner when it comes to 68k coding, but my guess is that the assembler is converting your "ADD.l #8,a4" to "ADDA.l #8,a4". But ADDA does *not* affect the condition code register! Therefore the zero flag retains its value from the "MOVE.w d0,(a4)" instruction.
Redwood is offline  
Old 21 May 2009, 13:00   #7
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
Actually adding and subtracting from address registers usually optimize to LEA 8(A4),A4 but, either way, the CCR is still not affected by it.

Inserting a TST.L A4 should solve it.
Samurai_Crow is offline  
Old 21 May 2009, 13:04   #8
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by Samurai_Crow View Post
Actually adding and subtracting from address registers usually optimize to LEA 8(A4),A4.
It would be optimized to addq #8,a4 in this case.

Quote:
Originally Posted by Samurai_Crow View Post
Inserting a TST.L A4 should solve it.
And make the code crash on 68000 as that is an 68020+ instruction.
StingRay is offline  
Old 21 May 2009, 14:09   #9
Wepl
Moderator
 
Wepl's Avatar
 
Join Date: Nov 2001
Location: Germany
Posts: 866
all maths against address registers do not set the condition codes, because you normally do not use address registers for calculations.
the assemblers silently convert add/sub ea,an to adda/suba.
to set the ccs you could use move an,dn if you have a data register free.
Wepl is offline  
Old 21 May 2009, 22:41   #10
Vortex
Used Register
 
Vortex's Avatar
 
Join Date: Nov 2008
Location: Headvillage / The Nethervoids
Age: 50
Posts: 103
Thanks everybody for your thoughts.
I've been tinkering with all your suggestions and here's what I found.

ADD.l #8,a4 is indeed changed to ADDA.l ... (tested using disassemble)

Calculations in address register do not modify CCR.

Tried:
- MOVEQ #0,d2
- OR.b #0,d1
- TST.b D1

to set the Z flag...

Or just use DBF instead of DBEQ.

TST.l A4 generates an invalid addressing mode error with ASMOne V1.20


Thanks again, I'm already coding the next useless f*cking piece of sh*t...
( [ Show youtube player ] - I'm pretty sure you've already seen this... )
Vortex is offline  
Old 21 May 2009, 22:49   #11
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by Vortex View Post
TST.l A4 generates an invalid addressing mode error with ASMOne V1.20
It's not a valid 68000 instruction. You can use this only on CPU's >68020. On 68000 you would have to do move.l ax,dx or cmp.l #0,ax.
StingRay is offline  
Old 21 May 2009, 23:00   #12
Vortex
Used Register
 
Vortex's Avatar
 
Join Date: Nov 2008
Location: Headvillage / The Nethervoids
Age: 50
Posts: 103
Yup, understood that.

You can't use Address Register Direct or an Immediate value with TST according to the 68K instruction set manual I snatched from here...

Lars
Vortex is offline  
Old 22 May 2009, 05:57   #13
NovaCoder
Registered User
 
NovaCoder's Avatar
 
Join Date: Sep 2007
Location: Melbourne/Australia
Posts: 4,400
Thanks Vortex, nicely documented code which is great for a newbie like me

I'll have to grab myself a compiler and try to see if I get it going on my 1200.
NovaCoder is offline  
Old 23 May 2009, 08:50   #14
Anding
Users Awaiting Email Confirmation
 
Join Date: Nov 2008
Location: Hong Kong
Posts: 56
Hope this is no intrusion. I just found the thread and literally today was finishing off a very simple 'on-demand copper bars' demo called from the CLI, so I thought I would put it up. It seems to work.

>CopperBars StartColor Height ColorChange ColorSteps
StartColor is the RGB color of the first stripe
Height is the height of each stripe in pixels
ColourChange is the RGB value added with each stripe
ColorSteps is the number of stripes before the colors repeat
All values must be positive

Code:
; includes
	include exec/types.i
	include hardware/custom.i 
	include hardware/dmabits.i
	include hardware/hw_examples.i	
 	include exec/exec_lib.i
 	include graphics/graphics_lib.i
 	
SIGBREAKF_CTRL_C	equ	$1000	
ActiView		equ 	$22
copinit			equ 	$26
AttnFlags		equ 	$128

; Get the input parameters and convert to a machine numbers
input	cmp 	#1,d0		; d0 = length of input string, including /LF
	beq 	exit		; no input, just '/LF',$0
	move.l	d0,d7		; d7 = length of input string
	subq	#2,d7		; d7 = actual length of input parameter -1 
	lea	params+4,a1	; address of the first parmeter
	move.l	params,d2	; maximum number of parameters to accept
	subq	#1,d2		; Prepare to loop
loop0	clr.l	d0		; zero the accumulator	
loop1	clr.l 	d1		; clear the next byte
	move.b 	(a0)+,d1	; a0 points to the next byte of input string
	cmp	#' ',d1		; space separator
	beq	end
	cmp	#',',d1		; comma separator
	beq	end	
	cmp 	#'0',d1		; check byte is in the range 0-9
	bcs	loop1		; if d1 < '0' then loop1
	cmp 	#'9',d1
	bhi 	loop1		; if d1 > '9' then loop1
	and.b	#$0F,d1		; convert to BCD
	mulu	#10,d0		; multiply accumulator by 10
	add.l	d1,d0		; add BCD digit to accumulator
	dbf	d7,loop1	; iterate through the loop
	clr.l	d2		; end of string so last parameter
end	move.l	d0,(a1)+	; store the parameter
	dbf	d2,loop0	; next parameter

; prepare the copper list
copper  ; initialize	
	move.l	c_steps,d3	; d3 = color steps
	subq.l	#1,d3		; for looping
	move.l	height,d2	; d2 = height of each stripe
	subq	#1,d2		; for looping
	move.l	c_delta,d1	; d1 = delta color of each stripe
	move.l	c_base,d0	; d0 = color value
	move.l	#coplist,a0	; a0 = start of copperlist
	clr.l	d7		; d7 = curent Vp
	; store copper instruction	
loop2	move.w	#COLOR00,(a0)+	; MOVE1 (destination) = COLOR00
	move.w	d0,(a0)+	; MOVE2 (value) = current color
	move.b	d7,(a0)+	; HI byte of WAIT1 (Vp) = d7 AND $ff
	move.b	#$df,(a0)+	; LO byte of WAIT1 (Hp) = $df (off screen)
	move.w	#$fffe,(a0)+	; WAIT2 (mask) = $fffe
	; stripe control
	dbf	d2,next		; --d2 == -1 next
	add.l	d1,d0		; Stripe color += delta color
	move.l  height,d2	; d2 = reset stripe height counter
	subq	#1,d2		; for looping
	; color cycle control
	dbf	d3,next		; --d3 == -1 next	
	move.l	c_base,d0	; d0 = cycle back to first color
	move.l	c_steps,d3	; d3 = reset color cycle counter
	subq.l	#1,d3		; for looping
	; scan line control
next	addq	#1,d7		; Vp += 1
	cmp	#312,d7		; last line of the screen
	bcs	loop2		; if d7 < 312 loop2
	move.l	#$fffffffe,(a0)	; last line of copperlist is endless wait
	jmp	startup		; finished the copperlist

; startup code
	; open graphics.lib 
startup	move.l	$4,a6			; a6 = SysBase
	lea	gfxname,a1		; Open graphics.library
	moveq	#0,d0			; Any version
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,gfxbase

	; Save the current display 	
	move.l	gfxbase,a6		; a6 = gfxbase
	move.l	ActiView(a6),oldview	; Save copper list
	sub.l	a1,a1			; a1 = null
	jsr	_LVOLoadView(a6)	; Load a NULL view
	jsr	_LVOWaitTOF(a6)		; Wait for top of video frame
	jsr	_LVOWaitTOF(a6)		; Wait again in case interlaced

; demo code
	lea	CUSTOM,a0		; a0 = base address of custom chip registers
	lea	coplist,a1		; a1 = address of copperlist 1
	move.l	a1,COP1LC(a0)		; Load copperlist address to COP1
	
; wait for a CTRL-C
	move.l	4,a6			; system base
	move.l #SIGBREAKF_CTRL_C,d0	; signal on CTRL-C
	jsr _LVOWait(a6)		; wait for this signal
			
; closedown code
	; restore the system display
	move.l	gfxbase,a6
	jsr	_LVOWaitTOF(a6)	
	jsr	_LVOWaitTOF(a6)		; Wait for top of video frame	
	move.l	oldview,a1		; a1 = old copperlist
	jsr	_LVOLoadView(a6)	; Reload the old view
	move.l	copinit(a6),$dff080	; Bang it into COP1LC
	
	; close libraries
	move.l	$4.w,a6			; A6 = ExecBase
	move.l	gfxbase(pc),a1
	jsr	_LVOCloseLibrary(a6)	; close graphics.library

; exit
exit	moveq	#0,d0
	rts

; data
gfxbase	dc.l	0
oldview	dc.l	0
params	dc.l	4
height	dc.l	0
c_base	dc.l	0
c_delta	dc.l	0
c_steps	dc.l	0
	even
gfxname	dc.b	"graphics.library",0

	SECTION	main,code_c		; load into chip ram

; copper list
coplist	dc.l	$ffffffe		; default endless wait for safety
	ds.l	700			; actual copper list
Anding is offline  
Old 24 May 2009, 23:08   #15
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
Sorry to hijack this thread too but I made my own version of the copper bar wave routine from Flight Of Dreams II.

It seems to work OK *but* does anyone know why the second blue bar does a disappearance and reappearance half way down the screen?

Last edited by pmc; 26 May 2009 at 11:34.
pmc is offline  
Old 25 May 2009, 08:51   #16
Vortex
Used Register
 
Vortex's Avatar
 
Join Date: Nov 2008
Location: Headvillage / The Nethervoids
Age: 50
Posts: 103
No worries guys...

@pmc: I'll copy your .s file to my A500 tonight and run it. Perhaps I can find that blue bar problem if no one else beats me to it...

Lars
Vortex is offline  
Old 25 May 2009, 12:46   #17
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
@ Vortex. Cheers man.

One thing though, I know from various comments in the past from the guys who know that my code isn't the most clever or friendly in the way it takes the system so I checked to see if it would run on an emulated vanilla A500 setup - it runs but you just get a blank screen and no copper effect. If you wanna run it I think you'll be safest setting up an emulated A500+ under UAE as per the system settings described in the comments at the top of my code cos that way it'll work.

I'm starting to think it might be time to stop being lazy and work myself up some new "super system friendly cos it obeys all the best practice rules" startup code...
pmc is offline  
Old 25 May 2009, 13:04   #18
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by pmc View Post
I'm starting to think it might be time to stop being lazy and work myself up some new "super system friendly cos it obeys all the best practice rules" startup code...
If you don't feel like wasting time coding boring things like that you can use my ministartup that is attached to this post. Just include it as the first thing in your source and call your main routine "MAIN" as that's the name the startup expects. Hope that helps.

As for your Copperbars, I had a quick look, might be there's a bug in your blitter clear routine (even though it looks correct to me), when I replaced it by a CPU loop the bars were displayed correctly.

Edit: I didn't test your Copperbars on a plain A500/68000 config though (used 68040/AGA)
Attached Files
File Type: txt startup.i.txt (5.4 KB, 400 views)

Last edited by StingRay; 25 May 2009 at 13:17.
StingRay is offline  
Old 25 May 2009, 13:11   #19
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
Quote:
Originally Posted by pmc View Post
@ Vortex. Cheers man.

One thing though, I know from various comments in the past from the guys who know that my code isn't the most clever or friendly in the way it takes the system so I checked to see if it would run on an emulated vanilla A500 setup - it runs but you just get a blank screen and no copper effect. If you wanna run it I think you'll be safest setting up an emulated A500+ under UAE as per the system settings described in the comments at the top of my code cos that way it'll work.

I'm starting to think it might be time to stop being lazy and work myself up some new "super system friendly cos it obeys all the best practice rules" startup code...

These two are what I use. SetSystem.s is not finished and if some application is using the audio and timers and you poke them yourself, that application might glitch a bit but I don't think there's any safe way at all to avoid this since you can't save all these states properly. Other than that I've never had any problems with it on any system or configuration. Sources can be viewed properly in ASM-One or in any editor with a tab size of 10.
Attached Files
File Type: txt SetSystem.txt (9.8 KB, 562 views)
File Type: txt WBStartup.txt (1.4 KB, 336 views)
File Type: txt customregisters.txt (5.5 KB, 344 views)

Last edited by Leffmann; 25 May 2009 at 13:26.
Leffmann is offline  
Old 25 May 2009, 13:58   #20
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
Quote:
If you don't feel like wasting time coding boring things like that you can use my ministartup that is attached to this post. Just include it as the first thing in your source and call your main routine "MAIN" as that's the name the startup expects. Hope that helps.
StingRay, I've described you as a gent before and nothing's changed. Much appreciated. Top man.

Leffman, the same goes for you too, very much appreciated.

Quote:
As for your Copperbars, I had a quick look, might be there's a bug in your blitter clear routine (even though it looks correct to me), when I replaced it by a CPU loop the bars were displayed correctly.
Thanks for checking StingRay.

Hmmm, I just took the blitter routine that I had for clearing the screen in my sinescroll code and amended it so that it would clear the colours from the copper list in this routine. I'll play around and see what I can do.
pmc 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
Remember Bars 'N' Pipes? Mikey_C Amiga scene 19 04 January 2023 22:29
Combining copper scrolling with copper background phx Coders. Asm / Hardware 16 13 February 2021 12:41
Bars & Pipes Professional Ricebug New to Emulation or Amiga scene 0 08 February 2012 03:32
Dopus bars frikilokooo project.ClassicWB 11 12 April 2008 17:10
Bars and Pipes Frank New to Emulation or Amiga scene 2 01 March 2004 13:43

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 07:32.

Top

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