[comp.sys.amiga.tech] Blitter problem

SXA00051@BAGAMCOK.BITNET (Mitchell Morris) (06/07/88)

Regardless of which compiler you're using, AllocRaster() and FreeRaster()
require LONG arguments, not WORDS.  There may be more to your problem
than this (my Amiga is at home), but you need to fix those calls before
anything else.

Use "AllocRaster (ptr, (LONG) width, (LONG) height);" or declare
width and height as LONG variables to start with.

                                      Mitch

FATQW@USU.BITNET (Bryan Ford) (06/09/88)

>Hmm.  First comment is that you only need to allocate and use one
>bit plane...

OK, thanks.

>Second thing is make sure you WaitBlit() *after* the final blit
>before using the result.

OK, I fixed that too.

Unfortunately, it still does the same thing.  Updated version follows.

                                Bryan Ford (FATQW@USU.BITNET)

/* MakeColorMask - Create a color mask for a BitMap - Bryan Ford */

#include <exec/types.h>
#include <graphics/gfx.h>
#include <hardware/blit.h>
#include <hardware/custom.h>

IMPORT struct Custom custom;

PLANEPTR MakeColorMask(BitMap,Color,Invert)
struct BitMap *BitMap;
UBYTE Color;
BOOL Invert;
{
    WORD Width = BitMap->BytesPerRow*8,
        Height = BitMap->Rows,
        Depth = BitMap->Depth;
    PLANEPTR Plane;
    COUNT i;

    if ((Plane = (PLANEPTR)AllocRaster(Width,Height)) == NULL)
        return(NULL);
    OwnBlitter();

    for(i = 0;i < Depth;i++) {
        WaitBlit();
        custom.bltapt = (APTR)BitMap->Planes[i];
        custom.bltdpt = (APTR)Plane;
        custom.bltafwm = custom.bltalwm = 0xffff;
        custom.bltamod = custom.bltbmod = custom.bltdmod = custom.bltcon1 = 0;
        if (i != 0) {
            custom.bltbpt = (APTR)Plane;
            custom.bltcon0 = BC0F_SRCA | BC0F_SRCB | BC0F_DEST |
                (Color & 1 ? ABC | ABNC : NABC | NABNC);
        } else {
            custom.bltcon0 = BC0F_SRCA | BC0F_DEST |
                (Color & 1 ? ABC | ABNC | ANBC | ANBNC :
                NABC | NABNC | NANBC | NANBNC);
        }
        custom.bltsize = (Height << 6) | (Width >> 4);
        Color >>= 1;
    }

    if (Invert) {
        WaitBlit();
        custom.bltapt = custom.bltdpt = (APTR)Plane;
        custom.bltamod = custom.bltdmod = custom.bltcon1 = 0;
        custom.bltafwm = 0xffff;
        custom.bltalwm = 0xffff << (((Width+15)&~15)-Width);
        custom.bltcon0 = BC0F_SRCA | BC0F_DEST | NABC | NANBC | NABNC | NANBNC;
        custom.bltsize = (Height << 6) | (Width >> 4);
    }

    WaitBlit();
    DisownBlitter();
    return(Plane);
}

dale@boing.UUCP (Dale Luck) (06/11/88)

In article <8806090704.AA14228@jade.berkeley.edu> FATQW@USU.BITNET (Bryan Ford) writes:
>    OwnBlitter();
>
>    for(i = 0;i < Depth;i++) {
>        WaitBlit();
>        custom.bltapt = (APTR)BitMap->Planes[i];
>        custom.bltdpt = (APTR)Plane;
>        custom.bltafwm = custom.bltalwm = 0xffff;

   Not a good idea to use these kind of statements when talking to
   amiga custom chips. The writable registers are not readable and some
   compilers will generate:
     move.w	#0,custom.bltalwm
     move.w	custom.bltalwm,custom.bltafwm
   You should use seperate statements for each register load.

>        custom.bltamod = custom.bltbmod = custom.bltdmod = custom.bltcon1 = 0;

   Again not a good idea.
   See previous statement

>        if (i != 0) {
>            custom.bltbpt = (APTR)Plane;
>            custom.bltcon0 = BC0F_SRCA | BC0F_SRCB | BC0F_DEST |
>                (Color & 1 ? ABC | ABNC : NABC | NABNC);
>        } else {
>            custom.bltcon0 = BC0F_SRCA | BC0F_DEST |
>                (Color & 1 ? ABC | ABNC | ANBC | ANBNC :
>                NABC | NABNC | NANBC | NANBNC);
>        }
>        custom.bltsize = (Height << 6) | (Width >> 4);

         If your width is 1024, this will cause a 1 to be ored into
         the rows count, you should use (0x3f & (Width>>4))

>        Color >>= 1;
>    }
>
>    WaitBlit();

     This statement is not necessary as long as you do a WaitBlit before
     using the data. This will give you a little more parallelism.

>    DisownBlitter();

     Good boy

>    return(Plane);
>}

I haven't actually looked at you algorithm for lagic problems like
bad choice of minterms. I will tell you though that the flood fill
routine in the graphics library does something similar but it does it
a little more optimally. But takes more work to figure it out.
  
Basically if you have 3 or fewer bitplanes it only takes 1 blit.

If you have 4-5 bitplanes it takes 2 blits

If you have 6-7 bitplanes it takes 3 blits.
......



-- 
Dale Luck     Boing, Inc.
Although I do contract work for Amiga-LosGatos, my opinions probably
don't represent those of Commodore or its management or it's engineers,
but I think the world would be a better place if they did.

dale@boing.UUCP (Dale Luck) (06/11/88)

In article <323@boing.UUCP> dale@boing.UUCP (Dale Luck) writes:
>In article <8806090704.AA14228@jade.berkeley.edu> FATQW@USU.BITNET (Bryan Ford) writes:
>>        custom.bltafwm = custom.bltalwm = 0xffff;
>
>     move.w	#0,custom.bltalwm
>   You should use seperate statements for each register load.

I hate it when I don't pay close attention. You of cource caught my
typo, that #0 should be a #$ffff in metacomco asm of 0xffff is asm
understands c constants.
Feeling dumb.

-- 
Dale Luck     Boing, Inc.
Although I do contract work for Amiga-LosGatos, my opinions probably
don't represent those of Commodore or its management or it's engineers,
but I think the world would be a better place if they did.

FATQW@USU.BITNET (Bryan Ford) (06/14/88)

I've fixed the problem.  Thanks very much for all the help, especially
from Tom Rokicki.  I *still* don't know what the problem was, but it
seems like a small rewrite is what was necessary.

The working version follows, if anyone is interested.  I'm using
Lattice 3.03  (32 bit ints), so you'll have to stick an L beside
several of the values if you try compiling it using 16 bit ints.

/* MakeColorMask - Create a color mask for a BitMap - Bryan Ford */

/*
 *  FUNCTION
 *      MakeColorMask - Make a mask of a certain color in a BitMap
 *
 *  SYNOPSIS
 *      MakeColorMask(BitMap,Plane,Color)
 *
 *  DESCRIPTION
 *      Generates a mask of all the pixels in the BitMap which
 *      have the same color number as Color.  The result is
 *      stored in Plane, which must be the same size as the
 *      BitMap.
 *
 *  INPUTS
 *      BitMap - Pointer to the BitMap
 *      Plane - Destination plane
 *      Color - Color number
 *
 */

#include <exec/types.h>
#include <graphics/gfx.h>
#include <hardware/blit.h>
#include <hardware/custom.h>

IMPORT struct Custom custom;

VOID MakeColorMask(BitMap,Plane,Color)
struct BitMap *BitMap;
PLANEPTR Plane;
UBYTE Color;
{
    WORD Width = BitMap->BytesPerRow * 8,
        Height = BitMap->Rows,
        Depth = BitMap->Depth;
    REGISTER COUNT i;

    OwnBlitter();
    for(i = 0;i < Depth;i++) {
        WaitBlit();
        custom.bltapt = (APTR)BitMap->Planes[i];
        custom.bltdpt = (APTR)Plane;
        custom.bltafwm = custom.bltalwm = 0xffff;
        custom.bltamod = custom.bltbmod = custom.bltdmod = custom.bltcon1 = 0;
        if (i != 0) {
            custom.bltbpt = (APTR)Plane;
            custom.bltcon0 = BC0F_SRCA | BC0F_SRCB | BC0F_DEST |
                (Color & 1 ? ABC | ABNC : NABC | NABNC);
        } else {
            custom.bltcon0 = BC0F_SRCA | BC0F_DEST |
                (Color & 1 ? ABC | ABNC | ANBC | ANBNC :
                NABC | NABNC | NANBC | NANBNC);
        }
        custom.bltsize = (Height << 6) | (Width >> 4);
        Color >>= 1;
    }
    WaitBlit();
    DisownBlitter();
    return(Plane);
}

************

                                Bryan