Welcome, Guest. Please login or register.

Author Topic: Big restriction in AmigaOS for UserCopper lists ?  (Read 3610 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Big restriction in AmigaOS for UserCopper lists ?
« on: November 15, 2004, 06:54:06 PM »
Hi. I tried to compile the example in the RKM libraries to see if it looked how I expected it. After one or two error corrections (VBCC seems to be more types resctrict than SAS) it worked et voila... Then  decided to change it a bit to push the Copper resolution to the maximum (4HirRes pixels if I remember correctly, and eventhough that was for ECS, AGA's the same I think...). I made it change various successive pixels to see the result. You know what ? It was visisble on the screen that for color change it took more than eight lowres pixels (probably 16 HiRes ones or more :-o  :-o  :-x ) .

My question is, is this an AmigaOS restriction on Copper lists?
Is there any way of achieving the maximum resolution without banging directly the hardware?  :-(

Bellow is on of the the example versions (just modified the WAIT instruction values, and the colors used to make them more different from one another, so that I can see how many pixels it takes to change between them):

Code: [Select]
/*  The example program below shows the use of user Copper lists
    under Intuition.

    UserCopperExample.c
    User Copper List Example
    For SAS/C 5.10a,
    compile with:  LC -b1 -cfist -L -v -y UserCopperExample.c
    link with lc.lib and amiga.lib
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/copper.h>
#include <graphics/videocontrol.h>
#include <intuition/intuition.h>
#include <intuition/preferences.h>
#include <hardware/custom.h>
#include <libraries/dos.h>

#include <clib/exec_protos.h>           /*  Prototypes.  */
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/dos_protos.h>

#include <stdlib.h>

/*  Use this structure to gain access to the custom registers.  */
extern struct Custom far, custom;

/*  Global variables.  */
struct GfxBase        *GfxBase = NULL;
struct IntuitionBase  *IntuitionBase = NULL;
struct Screen         *screen = NULL;
struct Window         *window = NULL;

int main( VOID ), cleanExit( WORD );
WORD openAll( VOID ), loadCopper( VOID );


/*
 *   The main() routine -- just calls subroutines
 */
int main( VOID )
{
WORD ret_val;
struct IntuiMessage     *intuiMessage;

        /*  Open the libraries, a screen and a window.  */
        ret_val = openAll();
        if (RETURN_OK == ret_val)
        {
                /*  Create and attach the user Copper list.  */
                ret_val = loadCopper();
                if (RETURN_OK == ret_val)
                {
                        /*  Wait until the user clicks in the close gadget.  */
                        (VOID) Wait(1<<window->UserPort->mp_SigBit);

                        while (intuiMessage = (struct IntuiMessage *)GetMsg(window->UserPort))
                                ReplyMsg((struct Message *)intuiMessage);
                }
        }
        cleanExit(ret_val);
}


/*
 * openAll() -- opens the libraries, screen and window
 */
WORD openAll( VOID )
{
#define MY_WA_WIDTH 270 /*  Width of window.  */

        WORD ret_val = RETURN_OK;

        /*  Prepare to explicitly request Topaz 60 as the screen font.  */
        struct TextAttr topaz60 =
        {
                (STRPTR)&quot;topaz.font&quot;,
                (UWORD)TOPAZ_SIXTY, (UBYTE)0, (UBYTE)0
        };

        GfxBase = (struct GfxBase *)OpenLibrary(&quot;graphics.library&quot;, 37L);
        if (GfxBase == NULL)
                ret_val = ERROR_INVALID_RESIDENT_LIBRARY;
        else
        {
                IntuitionBase = (struct IntuitionBase *)
                        OpenLibrary(&quot;intuition.library&quot;, 37L);

                if (IntuitionBase == NULL)
                        ret_val = ERROR_INVALID_RESIDENT_LIBRARY;
                else
                {
                        screen = OpenScreenTags( NULL,
                                 SA_Overscan, OSCAN_STANDARD,
                                 SA_Title,    &quot;User Copper List Example&quot;,
                                 SA_Font,     (ULONG)&topaz60,
                                 TAG_DONE);

                        if (NULL == screen)
                                ret_val = ERROR_NO_FREE_STORE;
                        else
                        {
                                window = OpenWindowTags( NULL,
                                         WA_CustomScreen, screen,
                                         WA_Title,        &quot;<- Click here to quit.&quot;,
                                         WA_IDCMP,        CLOSEWINDOW,
                                         WA_Flags,        WINDOWDRAG|WINDOWCLOSE|INACTIVEWINDOW,
                                         WA_Left,         (screen->Width-MY_WA_WIDTH)/2,
                                         WA_Top,          screen->Height/2,
                                         WA_Height,       screen->Font->ta_YSize + 3,
                                         WA_Width,        MY_WA_WIDTH,
                                         TAG_DONE);

                                if (NULL == window)
                                        ret_val = ERROR_NO_FREE_STORE;
                        }
                }
        }

        return(ret_val);
}


/*
 * loadCopper() -- creates a Copper list program and adds it to the system
 */
WORD loadCopper( VOID )
{
register USHORT   i, scanlines_per_color;
         WORD     ret_val    = RETURN_OK;
struct   ViewPort *viewPort;
struct   UCopList *uCopList  = NULL;
struct   TagItem  uCopTags[] =
          {
               (LONG)VTAG_USERCLIP_SET, (LONG)NULL,
               (LONG)VTAG_END_CM,(LONG) NULL
          };

UWORD    spectrum[] =
          {
                0x0000, 0x0705, 0x1006, 0x1006, 0x1006, 0x1006, 0x1006,
                0x0000, 0x0612, 0x0613, 0x0614, 0x0615, 0x0616, 0x0617,
                0x0000, 0x0619, 0x0620, 0x0621, 0x0622, 0x0623, 0x0624,
                0x0000, 0x0626, 0x0627, 0x0628, 0x0629, 0x0630, 0x0631,
                0x0000, 0x0633, 0x0734, 0x0835
          };

#define NUMCOLORS 4

        /*  Allocate memory for the Copper list.  */
        /*  Make certain that the initial memory is cleared.  */
        uCopList = (struct UCopList *)
                AllocMem(sizeof(struct UCopList), MEMF_PUBLIC|MEMF_CLEAR);

        if (NULL == uCopList)
                ret_val = ERROR_NO_FREE_STORE;
        else
        {
                /*  Initialize the Copper list buffer.  */
                CINIT(uCopList, NUMCOLORS);

                scanlines_per_color = screen->Height/NUMCOLORS;

                /*  Load in each color.  */
                for (i=1; i<NUMCOLORS; i++)
                        {
                        CWAIT(uCopList, 100,(((BYTE)(100+i))));
                        CMOVE(uCopList, custom.color[0], spectrum[i]);
                        }

                CEND(uCopList); /*  End the Copper list  */

                viewPort = ViewPortAddress(window);     /*  Get a pointer to the ViewPort.  */
                Forbid();       /*  Forbid task switching while changing the Copper list.  */
                viewPort->UCopIns=uCopList;
                Permit();       /*  Permit task switching again.  */

                /*  Enable user copper list clipping for this ViewPort.  */
                (VOID) VideoControl( viewPort->ColorMap, uCopTags );

                RethinkDisplay();       /*  Display the new Copper list.  */

                return(ret_val);
        }
}


/*
 *  cleanExit() -- returns all resources that were used.
 */
VOID cleanExit( WORD retval )
{
struct ViewPort *viewPort;

if (NULL != IntuitionBase)
{
        if (NULL != screen)
        {
                if (NULL != window)
                {
                        viewPort = ViewPortAddress(window);
                        if (NULL != viewPort->UCopIns)
                        {
                                /*  Free the memory allocated for the Copper.  */
                                FreeVPortCopLists(viewPort);
                                RemakeDisplay();
                        }
                        CloseWindow(window);
                }
                CloseScreen(screen);
        }
        CloseLibrary((struct Library *)IntuitionBase);
}

if (NULL != GfxBase)
        CloseLibrary((struct Library *)GfxBase);

exit((int)retval);
}

\\"We made Amiga, they {bleep}ed it up\\"
 

Offline SamuraiCrow

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2281
  • Country: us
  • Gender: Male
    • Show only replies by SamuraiCrow
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #1 on: November 17, 2004, 08:23:10 PM »
IIRC the sharpest an ECS system can do for a copper-chunky display is 80x200x12bit high color (NTSC) and the sharpest an AGA system can do is 80x200x24bit true color (NTSC) or 320x200x12 bit high color.  This is assuming you just do move instructions back to back with no wait instructions in between.
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #2 on: November 17, 2004, 08:40:38 PM »
One small aside.

Shouldn't the copperlist be allocated with MEMF_CHIP ram rather than just any old MEMF_PUBLIC?
int p; // A
 

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show only replies by PiR
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #3 on: November 18, 2004, 06:02:57 PM »
Quote

Karlos wrote:
One small aside.

Shouldn't the copperlist be allocated with MEMF_CHIP ram rather than just any old MEMF_PUBLIC?


Ha. I've noticed that also. :-D
So, :rtfm: - RKRM

It looks like this is only for preparation of User Copper List, which is never executed by itself, but is being merged with the other Copper Lists into One Big Ugly Copper List and that one is finally executed, so only that one has to be in CHIP.

Now Piru says I'm right.
Thank you, thank you..
APPLAUSE!

Yours forever.
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #4 on: November 18, 2004, 06:21:43 PM »
Quote
It looks like this is only for preparation of User Copper List, which is never executed by itself, but is being merged with the other Copper Lists into One Big Ugly Copper List and that one is finally executed, so only that one has to be in CHIP.

Now Piru says I'm right.

You're right.

Anyone interested in learning how this all works should read intuition.library/RethinkDisplay and graphics.library/MrgCop and related autodocs.

Also, this merging might explain why there are additional limitations to what you can do in the user copper list.
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #5 on: November 19, 2004, 06:11:31 PM »
Hey all :-)

"Also, this merging might explain why there are additional limitations to what you can do in the user copper list.
"
Don't system copper lists only make changes between viewports to change resolution and color registers etc. ? If so, at least i the middle of a Viewport there shouldn't be any restrictions.

One thing I remembered is that the example above uses macros. Maybe there are limitations on those macros  :-?


@Samurai

Ok, taking off those WAIT instructions will improved it but since copper DMA Chip ram access is conditioned by DMA priorities and competes with other stuff how's one supposed to know where the changes end up occurig?

By the way, there are some programs that claim to manage more than 100 chages per line with just ECS

Hmm AGA can make 320 changes at 12 bit? That would be just great but the results I got with the above example were on a AGA machine  :-(


By the way, I was planning to use this on a little proggies I had planned...
I'm gonna check this out more a bit, I was hopping someone would spare me that hard work   8-)
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Thomas

Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #6 on: November 20, 2004, 09:11:06 AM »

Quote

 but since copper DMA Chip ram access is conditioned by DMA priorities and competes with other stuff how's one supposed to know where the changes end up occurig?


DMA cycles are reserved for their specific purpose. At least they are on OCS. I don't remember exactly, but I think there are five or six cycles for bitplanes, one for copper, one for sound and one for trackdisk. And in the beginning of each display row there are eight cyles for sprites.

Maybe on AGA some cycles are shared, so for example I could imagine that you loose some copper cycles if you use more than six bitplanes.

I know that on OCS the sprite cycles are shared with the display DMA, so you loose one sprite after another if you expand the bitfield to the left.

Perhaps the reservation is the reason why you are disappointed about the copper resolution. IIRC on OCS one copper instruction was four pixels wide (or eight high-res pixels).


Bye,
Thomas

Offline lordv

  • Full Member
  • ***
  • Join Date: Feb 2004
  • Posts: 124
    • Show only replies by lordv
    • http://lvd.nm.ru
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #7 on: November 20, 2004, 09:47:05 AM »
Quote

You know what ? It was visisble on the screen that for color change it took more than eight lowres pixels (probably 16 HiRes ones or more ).

My question is, is this an AmigaOS restriction on Copper lists?


It seems to be hardware restriction. The simple $180,0,$180,$fff,$180,0,$180,$fff-like copper instructions started in specific part of screen, display 8 lowres pixels wide strips.  When num of bitplanes increases for 0 to 8, some strips become longer (up to 12 or even 16 lowres pixels).

Quote

Is there any way of achieving the maximum resolution without banging directly the hardware?

My results were obtained on a 'banged' copper list without any intervention of system.

I don't quite understand why don't you want to 'bang the hardware'. If you're using copperlists even with library functions, your program won't work on video cards or different ppc-with-pc-peripherals boards. So the banging gives the same results in a simpler way. One can easily combine fully custom, hardware-banged screen with multitasking and even screen switching (lamiga-m).
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #8 on: November 21, 2004, 12:28:37 PM »
@lordv

Was that on AGA ? How many bitplanes?

I guess it's not worth to try to bang the hardware myself then if the results are the same

Question, why do some programs claim to make more than 100 changes per line then?

By the way, like Thomas said, the hardware manual mentions 4 horizontal pixels, or 8, for lo and hires screens respectively.

I've read the Hardware manual's part on the copper but it was more than 1 year ago and these macros and gfx library stuff is easy to use that's the reason I prefer it this way. I think using the macros and gfx.library functions it's quicker to do it, but if I have to bang the hardware so be it :-D

\\"We made Amiga, they {bleep}ed it up\\"
 

Offline lordv

  • Full Member
  • ***
  • Join Date: Feb 2004
  • Posts: 124
    • Show only replies by lordv
    • http://lvd.nm.ru
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #9 on: November 21, 2004, 12:56:01 PM »
Quote

Was that on AGA ? How many bitplanes?


Of course - aga with maximum burst mode possible (fmode=3). Bitplanes were varied from 0 to 8

Quote

I guess it's not worth to try to bang the hardware myself then if the results are the same

But hardware screens are smth easier to create, I guess. Absolutely no OS interferention and limitations, no tons of graphics.library calls. =)

Quote

Question, why do some programs claim to make more than 100 changes per line then?

Don't know. Maybe some magic with bplcon4 ?

Quote

By the way, like Thomas said, the hardware manual mentions 4 horizontal pixels, or 8, for lo and hires screens respectively.

If copper reads his words every 4 lores pixels, it needs 8 lores pixels to load 1 palette register.

...When changing from ecs/ocs, the only enhancement was 8 bpls and 32/64bit enhanced bitplane/sprite fetch modes. Unfortunately no enhancements were made for blitter or copper, so they became no faster... :(
 

Offline JoseTopic starter

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2871
    • Show only replies by Jose
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #10 on: November 21, 2004, 01:16:58 PM »
Just to make it clear here's the stuff I think is relevant from the hardware manual:

"...The horizontal beam position has a value of $0 to $E2. The least signifieant bit is not used in the comparison, so there are 113 positions available for Copper operations. This corresponds to 4 pixels in low resolution and 8 pixels in high resolution. ..."

"... All Copper instructions consist of two 16-bit words in sequential memory locations. Each time the Copper fetches an instruction, it fetches both words. The MOVE and SKIP instructions require two memory cycles and two instruction words. Because only the odd memory cycles are requested by
the Copper, four memory cycle times are required per instruction. The WAIT instruction requires three memory cycles and six memory cycle times; it takes one extra memory cycle to wake up."

They don't specify if it's 4 cycles to fetch the data or for the instruction to execute, reading it it seems one memory cycle to fetch (because it fetches both WORDS) and one to execute, but probably it's 4 cycles to fetch, 4 to execute, wich results in 8 pixels between instructions.. :-(
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline lordv

  • Full Member
  • ***
  • Join Date: Feb 2004
  • Posts: 124
    • Show only replies by lordv
    • http://lvd.nm.ru
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #11 on: November 21, 2004, 03:44:41 PM »
Yes, 4 lores pixels wait resolution and 8 lores pixels command execution. Somewhere near your citation point it must be written about length of memory cycle - 280ns (2 lores pixels). 8 lores pixels per move arise from here.
 

Offline PiR

  • Full Member
  • ***
  • Join Date: Apr 2003
  • Posts: 148
    • Show only replies by PiR
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #12 on: November 22, 2004, 05:47:26 PM »
Quote
I don't quite understand why don't you want to 'bang the hardware'.


Jose! Don't do it! Don't use the Dark Side of the Force! :-D

But really, I think it won't be any faster. After copper lists are merged it is just executed by copper which doesn't know if it was system-friendly copper list or hardware banged...

That's just the way I see it.
 

Offline darkcoder

  • Full Member
  • ***
  • Join Date: Sep 2002
  • Posts: 164
    • Show only replies by darkcoder
Re: Big restriction in AmigaOS for UserCopper lists ?
« Reply #13 on: December 07, 2004, 09:02:01 AM »
Hello

 as lordv said, a copper move requires 8 lores pixel.
 I think the "wait resolution" is actually 2 lores pixel,
 since, if I am not wrong, the copper can wait for any horizontal posizion of the beam counter (the values read from VPOSR are compared with the values inside the wait instruction) and 1 increment in VPOSR (or DDFxxxx) equals to 2 lores pixels. However, to accomplish the wait, the copper lose  one memory cycle, so when the wait is over, another 2 pixel are passed. But maybe I am wrong. For sure since the copper access ram only on odd (or only on even) VPOSR positinos, it read a word any 4 pixel. Since a copper move is formed by 2 words, you have the 8 pixels.
To have up to 100 copper moves per line, I think they change the "lenght" of the scanline, using programmable comparators
HSTART, HSTOP, etc. You can do this only on ECS and AGA (no OCS) and of course your display is not PAL anymore
The Dark Coder / Trinity