#undef RGB
#define RGB(r,g,b)          ((r)+((g)<<5)+((b)<<10))

unsigned short *MemVideo = (unsigned short*)0x6000000;
unsigned short *Palette = (unsigned short*)0x5000000;

unsigned short *FrontBuffer = (unsigned short *)0x6000000;
unsigned short *BackBuffer = (unsigned short *)0x600a000;
volatile unsigned short *CompteurScanline = (volatile unsigned short *)0x4000006;

typedef unsigned char car;

void Mode4_DessPixel(unsigned short x, unsigned short y, unsigned char couleur)     {
    unsigned short temp;

    if (x>=240 || y>=160)           //Hors de l'écran (ne peut être négatif donc <0)
        return;

    //Récupération de la valeur déjà présente
    temp=MemVideo[(y*240+x)>>1];

    if (x&1)    {
        //Coordonnée paire => Masquer l'octet de poids fort
        temp &= 0x00ff;
        temp |= couleur<<8;
    }
    else        {
        //Coordonnée impaire => Masquer l'octet de poids faible
        temp &= 0xff00;
        temp |= couleur;
    }
    MemVideo[(y*240+x)>>1]=temp;
}

void ChargePalette(unsigned char *palette, unsigned char debut, unsigned char fin, short GAMMA)        {
    short rouge,vert,bleu,x,temp;

    for (x=debut;x<=fin;x++)     {
        temp=palette[x];
        bleu=(temp&0x7C00)>>10;
        vert=(temp&0x3E0)>>5;
        rouge=(temp&0x1F);
        if (rouge+GAMMA>31)
            rouge=31;
        else if (rouge+GAMMA<0)
            rouge=0;
        else
            rouge+=GAMMA;
        if (vert+GAMMA>31)
            vert=31;
        else if (vert+GAMMA<0)
            vert=0;
        else
            vert+=GAMMA;
        if (bleu+GAMMA>31)
            bleu=31;
        else if (bleu+GAMMA<0)
            bleu=0;
        else
            bleu+=GAMMA;
        Palette[x]=RGB(rouge,vert,bleu);
    }
}

void AttendVSync()     {
    while (*CompteurScanline>=160);
    while (*CompteurScanline<160);
}

void BasculePages()      {
    if (REG_DISPCNT & 0x10)     {
        REG_DISPCNT &= ~0x10;
        MemVideo = BackBuffer;
    }
    else    {
        REG_DISPCNT |= 0x10;
        MemVideo = FrontBuffer;
    }
}

void DessineBoite(car x0, car y0, car x1, car y1, car couleur)      {
    int x,y;

    for (y=y0;y<=y1;y++)
        for (x=x0;x<=x1;x++)
            Mode4_DessPixel(x,y,couleur);
}

void CopieDMA (void *source, void *dest, unsigned int nbval, unsigned int mode)     {
    if (mode==DMA_16im || mode==DMA_32im)        {
        REG_DMA3SAD = (unsigned int) source;
        REG_DMA3DAD = (unsigned int) dest;
        REG_DMA3CNT = nbval | mode;
    }
}


