A.D.A. Amiga Demoscene Archive

        Welcome guest!

  

  

  

log in with SceneID

  

Demos Amiga Demoscene Archive Forum / Coding / OCS copper chunky newbie questions

 

Author Message
jar
Member
#1 - Posted: 20 Mar 2017 12:27
Reply Quote
Hi everybody,

I am still very new to amiga programming and am trying to understand how to implement a OCS "copper chunky" mode in more detail. So far I could only find rather brief explanations.

From what I grasped, the basic concept is to fill a huge copper list with MOVE-instructions to set the color register value for each "chunky" pixel. Due to bus bandwidth/timing restrictions the copper can change the color only every 8 pixels, resulting in a horizontal resolution of 40 chunky pixels.

My questions:

- I would guess the copperlist also needs to include a WAIT-instruction for each rasterline to ensure a stable timing. Or is it sufficient to just wait for the first line and then just do all the MOVEs?

- when filling the "chunky buffer": Do you write the color values directly into the prepared copperlist, i.e. poke the color values directly into the "dc.w $0180,$0xxx" command stream? I would assume it is best to use two copperlists (one is currently executed while the beam is running, the other being filled for the next frame, then swap the two on vsync)? Or fill a intermediate WORD-buffer first and then copy values into the copperlist during vblank?

- sometimes I read about 3x2 copper chunky modes or similar - what is meant by this? I thought you can change the pixel color only every 8 pixels? Are these modes using some kind of blitter filling to set additional pixels?

- Using medres/hires to visually reduce the blockiness of the copper "pixels" would be too slow?

Maybe someone of you could give some hints :) Are there some other "best practices" I should be aware of?

Angry Retired Bastard
Member
#2 - Posted: 20 Mar 2017 13:02
Reply Quote
jar:
- I would guess the copperlist also needs to include a WAIT-instruction for each rasterline to ensure a stable timing. Or is it sufficient to just wait for the first line and then just do all the MOVEs?

Do a wait for the start of each line as well.

jar:
I would assume it is best to use two copperlists (one is currently executed while the beam is running, the other being filled for the next frame, then swap the two on vsync)?

Yes. :)
In some cases you might do with a single-buffered list, but this is mainly the way to do it.

Having an intermediate buffer is a waste of (a lot of) cycles unless you need the buffer for something else.

jar:
sometimes I read about 3x2 copper chunky modes or similar - what is meant by this?

Instead of changing the _same_ color register over and over again (which'll give you a minimum horizontal resolution of 8 pix) you draw vertical lines in different colors and then set different color registers per pixel on a line. As long as the color register is written before its corresponding pixels is drawn you're good.
This gives you more control over the horizontal per-pixel resolution but you trade it against the maximum number of chunky pixels per scanline. (Enabling more bitplanes will steal DMA-time).
Depending on your specific case you can of course play around with different trade-offs and variations.
Using multiple bitplanes for your chunky pixels is of course also a nice way of dithering the boundaries between the chunky pixels.


jar:
- Using medres/hires to visually reduce the blockiness of the copper "pixels" would be too slow?

It's the copper-write-delay that limits you to 8pix, not the resolution, so this would have no effect there.
Also, the additional DMA traffic would likely slow you down as well.
jar
Member
#3 - Posted: 20 Mar 2017 13:26
Reply Quote
wow, thanks slummy, these are some very detailed answers!
I am very grateful, this clears up a lot of question marks. I guess now it's my turn to experiment a bit in real code :)
todi
Member
#4 - Posted: 20 Mar 2017 13:28 - Edited
Reply Quote
There is a good thread about copper chunky here, maybe a little bit to technical to begin with, but you will soon get there...
Angry Retired Bastard
Member
#5 - Posted: 20 Mar 2017 14:49
Reply Quote
@jar: Happy to help. :)
One thing I forgot to mention: If you intend for your chunky pixels to be higher than 1 scanline then you should look into doing copper jumps (or "copper subroutine calls" if you will) using the 2 different copperpointers.
jar
Member
#6 - Posted: 20 Mar 2017 15:48
Reply Quote
cool, thanks.
this article about exact copper timing was also quite useful to me.
rloaderror
Member
#7 - Posted: 20 May 2017 13:51 - Edited
Reply Quote
I can't seem to change more than 16 colors per scanline. I used to think this was because I was changing AGA colors, but switching to OCS hoping to double the amount didn't give the expected boost.

If it is as you say that one can change 1 color per 8-th pixel I would think I could get 320/8 = 40 changes in one scanline.

Some setup which might be relevant:
- 8 bitplanes in use
- DMACONR is 0x2d0 (dmaenable set. Copper, disk, bitplanes, blitter dma enabled. Sprites, audio dma disabled)
- FMODE is 0xf ( 64-bit sprite fetch mode and 64-bit bitplane fetch mode
- None of the colors I'm changing are shown on the line where the changes are being done. They appear first on the next line.

I read about people changing 50 colors per scanline so I'm wondering what I'm missing? I just turned off sprite DMA, but seems no effect. Disabling bitplanes would make me sad.

Here is a snippet for 1 line of copper attempting 17 color changes.
BPLCON3 is the AGA bank switching since I'm using 256 colors throughout the frame.
Just using OCS colors now so not setting the low bits of the color.


dc.w 2cd9, fffe ; cop-wait @ 00032bdc
dc.w 0106, 0ca0 ; BPLCON3 @ 00032be0
dc.w 0180, 0f76 ; COLOR00 @ 00032be4
dc.w 0182, 0e64 ; COLOR01 @ 00032be8
dc.w 0184, 0d54 ; COLOR02 @ 00032bec
dc.w 0186, 0c53 ; COLOR03 @ 00032bf0
dc.w 0188, 0b53 ; COLOR04 @ 00032bf4
dc.w 018a, 0f76 ; COLOR05 @ 00032bf8
dc.w 018c, 0e75 ; COLOR06 @ 00032bfc
dc.w 018e, 0d53 ; COLOR07 @ 00032c00
dc.w 0190, 0b53 ; COLOR08 @ 00032c04
dc.w 0192, 0b64 ; COLOR09 @ 00032c08
dc.w 0194, 0c96 ; COLOR10 @ 00032c0c
dc.w 0196, 0f76 ; COLOR11 @ 00032c10
dc.w 0198, 0f76 ; COLOR12 @ 00032c14
dc.w 019c, 0e65 ; COLOR14 @ 00032c18
dc.w 019e, 0d64 ; COLOR15 @ 00032c1c
dc.w 01a0, 0d53 ; COLOR16 @ 00032c20
dc.w 2dd9, fffe ; cop-wait @ 00032c24
dc.w 018a, 0e88 ; COLOR05 @ 00032c28
:
: repeats for the whole screen
:


*edit after reading article pointed to by Jar*

"MOVE INSTRUCTION TIMING

During horizontal blanking, MOVEs take 8 cycles (pixels) to execute. During DMA activity, MOVEs will take 12 or 16 (but no more than 16). A typical example is between DDFSTRT and DDFSTOP when bitplane DMA has to be read and output to the screen. Here, 3 bitplanes will increase the timing to 12px and 4 (or more) bitplanes will increase it to 16."

It doesn't say how much 8 biplanes is going to affect the timing, but if using positive thinking, the problem should go away after >7 bitplanes are enabled.

Still 16 seems to be achievable during horizontal blank alone, so this must be absolute minimum.

*double edit.. I'm retarded.. It was a different bug causing the corruption*
kuro
Member
#8 - Posted: 23 Jun 2017 09:52
Reply Quote
8 bitplanes steals more DMA cycles... You can actually avoid using bitplane DMA entirely. Just use a fixed mask of bitplanes written directly to the buffer registers with DMA turned off.

 

  Please log in to comment

  

  

  

 

A.D.A. Amiga Demoscene Archive, Version 3.0