English Amiga Board


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

 
 
Thread Tools
Old 22 January 2019, 23:44   #1
mcgeezer
Registered User

 
Join Date: Oct 2017
Location: Sunderland, England
Posts: 848
Copper NOP and COPPER2

Hi all,

I'm hoping the wiz coders here can give me a couple of pointers with a couple of copper related questions...

Question 1 is related to using dummy copper instructions, as I'm using AGA am i able to simply use $01fe0000 in my copper to make a nop, later I'll poke the list with a $01800ffff to change the Colour 0 to White? Is there a better way.

Question 2 is a bit more problematic I think...

If I use 2 copper lists and wait for vertical positions in copper list 1, then jump to copper list 2 and wait for different (higher vertical) positions... I take it that won't work? (I have a feeling this is to do with interlacing)...

I need to dynamically change the copper lists at different points in my project but and it would be useful to be able to what I stated - so is that possible? I've read the HRM but it isn't quite too clear and gives a bit of a silly example of changing every 16th line.

Any help appreciated.

Geezer
mcgeezer is offline  
Old 23 January 2019, 00:12   #2
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 745
Quote:
Originally Posted by mcgeezer View Post
Hi all,

I'm hoping the wiz coders here can give me a couple of pointers with a couple of copper related questions...

Question 1 is related to using dummy copper instructions, as I'm using AGA am i able to simply use $01fe0000 in my copper to make a nop, later I'll poke the list with a $01800ffff to change the Colour 0 to White? Is there a better way.
I'm not sure what you wish to achieve here, but it is indeed possible to use $1fe as a Copper NOP and change it to be something else later dynamically.

Regarding a 'better way', that would depend on what you want to do - if you have a whole bunch of Copper instructions you wish to change dynamically, I'd personally use the Copper location registers and Copper jumping to get to different sub lists that contain what I'd want. Can get a bit tricky if you want multiple jumps, but it can be done.

Another option is to have a double buffered Copper list, where you dynamically generate (part of) a new list while displaying the other one. But again, it depends on what you want to do what is 'best'
Quote:
Question 2 is a bit more problematic I think...

If I use 2 copper lists and wait for vertical positions in copper list 1, then jump to copper list 2 and wait for different (higher vertical) positions... I take it that won't work? (I have a feeling this is to do with interlacing)...

I need to dynamically change the copper lists at different points in my project but and it would be useful to be able to what I stated - so is that possible? I've read the HRM but it isn't quite too clear and gives a bit of a silly example of changing every 16th line.

Any help appreciated.

Geezer
Copper waits will never 'halt' or 'wait' if encountered while the position being waited on is lower than the current raster position. So waiting on a vertical position higher up the screen in a second list will simply cause the wait to be ignored. Such a wait instruction will still cost the same number of DMA cycles as a wait that actually has to wait though - it merely returns immediately.

On the other hand, if you meant waiting on a position lower on the screen than the current raster position (this wasn't 100% clear to me when reading your post), jumping will not affect such a wait. Copper waits always wait until the position is met or exceeded and then they stop waiting.

Last edited by roondar; 23 January 2019 at 00:17. Reason: Made the text a bit more clear
roondar is offline  
Old 23 January 2019, 05:55   #3
Hewitson
Registered User
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 36
Posts: 2,789
Well, I have never even thought about a double buffered copperlist. I'm sure it's been done plenty of times though (any good examples)?
Hewitson is offline  
Old 23 January 2019, 06:39   #4
arcanist
Registered User
 
Join Date: Dec 2017
Location: Austin, TX
Age: 36
Posts: 135
Quote:
Originally Posted by Hewitson View Post
Well, I have never even thought about a double buffered copperlist. I'm sure it's been done plenty of times though (any good examples)?
My new game does.

The 3D effects are all copper-based. Double-buffering the copperlist gives the CPU a full frame to update the copper instructions, rather than having to race the raster. At the end of each frame I update COP1LC to point to the "back" copperlist and swap the two around.
arcanist is online now  
Old 23 January 2019, 07:31   #5
Hewitson
Registered User
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 36
Posts: 2,789
How do you handle collisions with moving objects that are displayed by the copper?
Hewitson is offline  
Old 23 January 2019, 07:52   #6
a/b
Registered User

 
Join Date: Jun 2016
Location: europe
Posts: 83
$01fe,xxx works fine as a (temporary) NOP on OCS/ECS/AGA.
You can switch copper lists as many times as you want (in a single frame). You simply set either pointer and then hit the corresponding trigger ($088 or $08a). Copper will immediately switch, and you can do whatever you want in the second copper list. Basically it doesn't matter if it's one or two or N lists, you can look at it as a big single list.
If you are simply doing double buffering, you just set the pointer ($080/$082) to your other list, and $088 will be auto-triggered during next vertical blanking.
a/b is offline  
Old 23 January 2019, 08:58   #7
Steril707
OCS rocks!

 
Join Date: Sep 2016
Location: Amiga Island
Posts: 619
Quote:
Originally Posted by Hewitson View Post
How do you handle collisions with moving objects that are displayed by the copper?
Like any other?
Steril707 is offline  
Old 23 January 2019, 09:37   #8
StingRay
move.l #$c0ff33,throat

StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,198
Quote:
Originally Posted by Hewitson View Post
Well, I have never even thought about a double buffered copperlist. I'm sure it's been done plenty of times though (any good examples)?

Any demos which use copper blits for example.
StingRay is offline  
Old 23 January 2019, 10:11   #9
mcgeezer
Registered User

 
Join Date: Oct 2017
Location: Sunderland, England
Posts: 848
Quote:
Originally Posted by roondar View Post
I'm not sure what you wish to achieve here, but it is indeed possible to use $1fe as a Copper NOP and change it to be something else later dynamically.

Regarding a 'better way', that would depend on what you want to do - if you have a whole bunch of Copper instructions you wish to change dynamically, I'd personally use the Copper location registers and Copper jumping to get to different sub lists that contain what I'd want. Can get a bit tricky if you want multiple jumps, but it can be done.

Another option is to have a double buffered Copper list, where you dynamically generate (part of) a new list while displaying the other one. But again, it depends on what you want to do what is 'best'

Copper waits will never 'halt' or 'wait' if encountered while the position being waited on is lower than the current raster position. So waiting on a vertical position higher up the screen in a second list will simply cause the wait to be ignored. Such a wait instruction will still cost the same number of DMA cycles as a wait that actually has to wait though - it merely returns immediately.

On the other hand, if you meant waiting on a position lower on the screen than the current raster position (this wasn't 100% clear to me when reading your post), jumping will not affect such a wait. Copper waits always wait until the position is met or exceeded and then they stop waiting.

Thanks Roondar, Consider the sanctuary/temple scene in Rygar. Currently I use a background colour gradient with a copper list for the sky during a round which obviously requires waiting for different Y points on the display. When in the temple scene this gradient isn't displayed so isn't required, however I do need another copper to change the colour of the text that appears as part of the bonus points.

So one solution is to put a copper NOP at the start of the main copper list which is then replaced with a jump to another copper list which switches the colours then switches back to the main copper list.

I hope that makes sense.

Cheers,
Geezer
mcgeezer is offline  
Old 23 January 2019, 11:25   #10
ross
Sum, ergo Cogito

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 48
Posts: 1,441
Quote:
Originally Posted by mcgeezer View Post
Thanks Roondar, Consider the sanctuary/temple scene in Rygar. Currently I use a background colour gradient with a copper list for the sky during a round which obviously requires waiting for different Y points on the display. When in the temple scene this gradient isn't displayed so isn't required, however I do need another copper to change the colour of the text that appears as part of the bonus points.

So one solution is to put a copper NOP at the start of the main copper list which is then replaced with a jump to another copper list which switches the colours then switches back to the main copper list.

I hope that makes sense.

Cheers,
Geezer
Code:
c1: copper start
c1: shared copper setup
c1: strobe COPJMP2 (the previous setup) -> fork to right copper list for the frame
--[a full frame to, in case, CPU write to copper list for different COP2LC* setup next frame]
c2: natural copper list
c2: wait somewhere near last line
c2: write to COP2LC* (the next real frame copper setup)
c2: cend
EDIT: written quickly, but ask if I have not been clear

Last edited by ross; 23 January 2019 at 11:36.
ross is offline  
Old 23 January 2019, 11:47   #11
Steril707
OCS rocks!

 
Join Date: Sep 2016
Location: Amiga Island
Posts: 619
This thread and its posed question is interesting for me as well for Inviyya.

There areas where I'd like to switch off the sprite background layer, since I need to blit shitloads of bytes for larger enemies, for example.

At the moment I am handling two copperlists and switching between them, which is kind of too much overhead, since I need to change anything in the other copperlist as well if change it in the normal one. And you can easily forget that while in "deep coding mode".

So, thanks for any ideas presented here...
Steril707 is offline  
Old 23 January 2019, 12:21   #12
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 745
Quote:
Originally Posted by mcgeezer View Post
So one solution is to put a copper NOP at the start of the main copper list which is then replaced with a jump to another copper list which switches the colours then switches back to the main copper list.
Yes, that'll work. It's probably how I'd do it (unless the difference between lists is huge, then I'd prefer simply having to different lists in memory).

Quote:
Originally Posted by ross View Post
Code:
c1: copper start
c1: shared copper setup
c1: strobe COPJMP2 (the previous setup) -> fork to right copper list for the frame
--[a full frame to, in case, CPU write to copper list for different COP2LC* setup next frame]
c2: natural copper list
c2: wait somewhere near last line
c2: write to COP2LC* (the next real frame copper setup)
c2: cend
EDIT: written quickly, but ask if I have not been clear
That basic idea will work, but do note here that the Amiga automatically reverts to COP1LC at the end of a frame:

Quote:
Originally Posted by HRM
About Copper restart.

At the start of each vertical blanking interval, COP1LC is automatically used to start the program counter. That is, no matter what the Copper is doing, when the end of vertical blanking occurs, the Copper is automatically forced to restart its operations at the address contained in COP1LC.
I ran into that a while back so I figured it'd be handy to keep in mind

Also note that there is nothing stopping you from simply updating COP1LC and strobing COPJMP1 when you wish to jump. This does require you to set COP1LC back to the correct start address at the end of the list, but it's definitely possible.
roondar is offline  
Old 23 January 2019, 12:51   #13
ross
Sum, ergo Cogito

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 48
Posts: 1,441
Quote:
Originally Posted by roondar View Post
That basic idea will work, but do note here that the Amiga automatically reverts to COP1LC at the end of a frame
Yes, and this is the very same reason I call the COP2LC write with the same copper2 list.
You should touch/modify COP1LC (and make sub-list with it) only if you know exactly what you are doing.
You have no idea how many problems are by improper use (a libertine COPJMP1 usage...), and race condition on fast machines.

If for some reason your CPU/Blitter code is not fast enough to complete the job in one frame also the write to copper list is done the next frame so simply you have a one frame slow down (you do not risk a glitch).

Even jumping around is simple if you use a master copper and (some) sub-copper lists (to make a sliced video setup) in race-beam order.

The master obviously need to be the C1 as is auto-strobed at VB and the various COP2LC are setup inside the C2 list and strobed in the right point (the fact that pointers are buffered is great )
Anyway you normally are in a double buffered environment so this is a natural behaviour.

@Steril707
Even the double setup is a relative and maneageable problem since some copper use is shared betwhen frames, so you can simply recycle the existing ones and jump around.

The only thing you need to do is chain the list in the previous frame (a job that you sure can complete in one/few video line/s).
To be really sure you can use the copper in a low video line to call an high IRQ and complete the setup or you can avoid this using a master switch (disable IRQ, switch all the requirement for next frame, enable).
The disable is for the module replayer (IRQ6..) than can break your setup.


Sorry for the fast and/or imprecise post, i'm in hurry

Cheers.
ross is offline  
Old 23 January 2019, 13:11   #14
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 745
Quote:
Originally Posted by ross View Post
Yes, and this is the very same reason I call the COP2LC write with the same copper2 list.
Right and I had misread what you did there. It's a rather interesting idea to have a 'master' copper list in COP1LC and a 'frame specific' one in COP2LC. Doing things this way does prevent a number of potential race conditions, which is always great news!

Quote:
the fact that pointers are buffered is great
100% true! It makes life so much easier that you can simply write to COP1LC and know it'll only change next frame.
roondar is offline  
Old 23 January 2019, 16:31   #15
arcanist
Registered User
 
Join Date: Dec 2017
Location: Austin, TX
Age: 36
Posts: 135
Quote:
Originally Posted by Hewitson View Post
How do you handle collisions with moving objects that are displayed by the copper?
The objects are represented by a start/end in X and Z space. I compare that with the camera X/Z position to see if they intersect.

There's no sprite/raster collision test here. That wouldn't be possible because both the objects and background have the same color index. The copper is just changing the color value per-scanline.
arcanist is online now  
Old 23 January 2019, 21:01   #16
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 43
Posts: 22,334
If you do lots of copper jumps/frame, it is good idea to relocate whole copper list in single 64k aligned chip memory block. This way only COPxLCL needs to be modified when jumping. Saves one MOVE. COPJMP is also slower than normal MOVE. (It is MOVE + extra idle copper cycle)

btw, never CPU write to COPJMP if blitter is active and copper is WAITing, it can trigger chipset bug: blitter pointer gets replaced with new copper pointer value.
Toni Wilen is online now  
Old 23 January 2019, 21:44   #17
ross
Sum, ergo Cogito

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 48
Posts: 1,441
Quote:
Originally Posted by Toni Wilen View Post
btw, never CPU write to COPJMP if blitter is active and copper is WAITing, it can trigger chipset bug: blitter pointer gets replaced with new copper pointer value.
This is another reason why I defer the COPJMP write through copper list itself.

Thanks Toni for reminding us of this thing.
ross is offline  
Old 24 January 2019, 00:12   #18
Asman
68k

Asman's Avatar
 
Join Date: Sep 2005
Location: Somewhere
Posts: 665
I want to fully understand - just to be sure. It's mean that if I have COPJMP in copperlist and blitter is active (doing some work ) when copper performs that COPJMP then this situation trigger this bug, right ?

If the answer is yes than I understand why big copperlists are used (risky woods for example) instead of using skip + copjmp copper feature.
Asman is offline  
Old 24 January 2019, 00:31   #19
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 745
Quote:
Originally Posted by Asman View Post
I want to fully understand - just to be sure. It's mean that if I have COPJMP in copperlist and blitter is active (doing some work ) when copper performs that COPJMP then this situation trigger this bug, right ?

If the answer is yes than I understand why big copperlists are used (risky woods for example) instead of using skip + copjmp copper feature.
No, the problem occurs when the CPU writes to copjmp while the Copper is waiting and the Blitter is running.

Using the Copper to write to copjmp is always safe.
roondar is offline  
Old 24 January 2019, 01:36   #20
ross
Sum, ergo Cogito

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 48
Posts: 1,441
Quote:
Originally Posted by Asman View Post
I want to fully understand - just to be sure. It's mean that if I have COPJMP in copperlist and blitter is active (doing some work ) when copper performs that COPJMP then this situation trigger this bug, right ?

If the answer is yes than I understand why big copperlists are used (risky woods for example) instead of using skip + copjmp copper feature.
Probably I've used an inappropriate word.
I simply meant that the COPJMP strobe is done in copper list and not by CPU (like roondar has already clarified).
This is a sneaky bug because it depends on a triplet that depends on many variables. On some configuration all seems ok, but..
If I can I completely avoid COPJMP(1) strobe (VB anyway do the job) and C2 related work is always in a complex self-triggered setup.

Cheers.
ross 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
Using the Copper guy lateur Coders. C/C++ 22 26 July 2017 20:29
Best way to mix blitting with copper and copper effects roondar Coders. Asm / Hardware 3 12 September 2016 14:12
copper ? turrican3 Coders. Asm / Hardware 10 27 January 2016 10:10
Combining copper scrolling with copper background phx Coders. Asm / Hardware 14 16 June 2013 08:26
Short branch converted to NOP jman Coders. Tutorials 3 22 August 2011 09:22

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 17:56.


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