#define MODULE_BIT 0x00080000
#include "mga_std.h"
#define ACCW_YDSTLEN(dst, len) do { \
if (si->engine.y_lin) { \
ACCW(YDST,((dst)* (si->fbc.bytes_per_row / (si->engine.depth >> 3))) >> 5); \
ACCW(LEN,len); \
} else ACCW(YDSTLEN,((dst)<<16)|(len)); \
} while (0)
status_t gx00_acc_wait_idle()
{
while (ACCR(STATUS) & 0x00010000)
{
snooze (100);
}
return B_OK;
}
status_t gx00_acc_init()
{
uint32 maccess = 0x00000000;
if ((si->ps.card_type >= G450) && (si->ps.pins_status == B_OK))
{
maccess |= ((((uint32)si->ps.v5_mem_type) & 0x80) >> 1);
}
si->engine.y_lin = 0x00;
si->engine.depth = 0;
ACCW(OPMODE,0);
ACCW(ZORG,0);
switch(si->dm.space)
{
case B_CMAP8:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x00));
si->engine.depth = 8;
break;
case B_RGB15_LITTLE:case B_RGB16_LITTLE:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x01));
si->engine.depth = 16;
break;
case B_RGB32_LITTLE:case B_RGBA32_LITTLE:
ACCW(MACCESS, ((maccess & 0xfffffffc) | 0x02));
si->engine.depth = 32;
break;
default:
LOG(8,("ACC: init, invalid bit depth\n"));
return B_ERROR;
}
switch (si->ps.card_type)
{
case MIL1:
switch (si->fbc.bytes_per_row / (si->engine.depth >> 3))
{
case 640:
case 768:
case 800:
case 960:
case 1024:
case 1152:
case 1280:
case 1600:
case 1920:
case 2048:
break;
default:
si->engine.y_lin = 0x01;
LOG(8,("ACC: using software adress linearisation\n"));
break;
}
ACCW(PITCH, (si->engine.y_lin << 15) |
((si->fbc.bytes_per_row / (si->engine.depth >> 3)) & 0x0FFF));
break;
case MIL2:
switch (si->fbc.bytes_per_row / (si->engine.depth >> 3))
{
case 512:
case 640:
case 768:
case 800:
case 832:
case 960:
case 1024:
case 1152:
case 1280:
case 1600:
case 1664:
case 1920:
case 2048:
break;
default:
si->engine.y_lin = 0x01;
LOG(8,("ACC: using software adress linearisation\n"));
break;
}
ACCW(PITCH, (si->engine.y_lin << 15) |
((si->fbc.bytes_per_row / (si->engine.depth >> 3)) & 0x0FFF));
break;
case G100:
ACCW(PITCH, ((si->fbc.bytes_per_row / (si->engine.depth >> 3)) & 0x0FFF));
break;
default:
ACCW(PITCH, ((si->fbc.bytes_per_row / (si->engine.depth >> 3)) & 0x1FFF));
break;
}
ACCW(PLNWT,0x00000000);
ACCW(PLNWT,0xffffffff);
if (si->ps.card_type >= G200) {
ACCW(DSTORG,((uint8*)si->fbc.frame_buffer) - ((uint8*)si->framebuffer));
ACCW(SRCORG,((uint8*)si->fbc.frame_buffer) - ((uint8*)si->framebuffer));
}
si->engine.src_dst = 0;
ACCW(YDSTORG, si->engine.src_dst);
if ((si->ps.card_type == G100) && (si->settings.hardcursor))
{
switch (si->dm.space)
{
case B_CMAP8:
si->engine.src_dst = 1024 / 1;
break;
case B_RGB15_LITTLE:
case B_RGB16_LITTLE:
si->engine.src_dst = 1024 / 2;
break;
case B_RGB32_LITTLE:
si->engine.src_dst = 1024 / 4;
break;
default:
LOG(8,("ACC: G100 hardcursor not supported for current colorspace\n"));
return B_ERROR;
}
}
ACCW(YDSTORG, si->engine.src_dst);
ACCW(CXBNDRY,(((si->fbc.bytes_per_row / (si->engine.depth >> 3)) - 1) << 16) | (0));
ACCW(YTOP, 0 + si->engine.src_dst);
ACCW(YBOT,((si->dm.virtual_height - 1) *
(si->fbc.bytes_per_row / (si->engine.depth >> 3))) + si->engine.src_dst);
return B_OK;
}
void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
{
uint32 t_start,t_end,offset;
uint32 b_start,b_end;
int i = 0;
offset = (si->fbc.bytes_per_row / (si->engine.depth >> 3));
while (count--)
{
t_end = t_start =
list[i].src_left + (offset * list[i].src_top) + si->engine.src_dst;
t_end += list[i].width;
b_end = b_start =
list[i].src_left + (offset * (list[i].src_top + list[i].height)) + si->engine.src_dst;
b_end += list[i].width;
ACCW(DWGCTL, 0x00000000);
switch((list[i].dest_top > list[i].src_top) | ((list[i].dest_left > list[i].src_left) << 1))
{
case 0:
ACCW(SGN, 0);
ACCW(AR3, t_start);
ACCW(AR0, t_end);
ACCW(AR5, offset);
ACCW_YDSTLEN(list[i].dest_top, list[i].height + 1);
break;
case 1:
ACCW(SGN, 4);
ACCW(AR3, b_start);
ACCW(AR0, b_end);
ACCW(AR5, -offset);
ACCW_YDSTLEN(list[i].dest_top + list[i].height, list[i].height + 1);
break;
case 2:
ACCW(SGN, 1);
ACCW(AR3, t_end);
ACCW(AR0, t_start);
ACCW(AR5, offset);
ACCW_YDSTLEN(list[i].dest_top, list[i].height + 1);
break;
case 3:
ACCW(SGN, 5);
ACCW(AR3, b_end);
ACCW(AR0, b_start);
ACCW(AR5, -offset);
ACCW_YDSTLEN(list[i].dest_top + list[i].height, list[i].height + 1);
break;
}
ACCW(FXBNDRY,((list[i].dest_left + list[i].width) << 16) | list[i].dest_left);
ACCGO(DWGCTL, 0x040c4018);
i++;
}
}
void SCREEN_TO_SCREEN_TRANSPARENT_BLIT(engine_token *et, uint32 transparent_colour, blit_params *list, uint32 count)
{
uint32 t_start,t_end,offset;
uint32 b_start,b_end;
int i = 0;
offset = (si->fbc.bytes_per_row / (si->engine.depth >> 3));
while (count--)
{
t_end = t_start =
list[i].src_left + (offset * list[i].src_top) + si->engine.src_dst;
t_end += list[i].width;
b_end = b_start =
list[i].src_left + (offset * (list[i].src_top + list[i].height)) + si->engine.src_dst;
b_end += list[i].width;
ACCW(DWGCTL, 0x00000000);
switch((list[i].dest_top > list[i].src_top) | ((list[i].dest_left > list[i].src_left) << 1))
{
case 0:
ACCW(SGN, 0);
ACCW(AR3, t_start);
ACCW(AR0, t_end);
ACCW(AR5, offset);
ACCW_YDSTLEN(list[i].dest_top, list[i].height + 1);
break;
case 1:
ACCW(SGN, 4);
ACCW(AR3, b_start);
ACCW(AR0, b_end);
ACCW(AR5, -offset);
ACCW_YDSTLEN(list[i].dest_top + list[i].height, list[i].height + 1);
break;
case 2:
ACCW(SGN, 1);
ACCW(AR3, t_end);
ACCW(AR0, t_start);
ACCW(AR5, offset);
ACCW_YDSTLEN(list[i].dest_top, list[i].height + 1);
break;
case 3:
ACCW(SGN, 5);
ACCW(AR3, b_end);
ACCW(AR0, b_start);
ACCW(AR5, -offset);
ACCW_YDSTLEN(list[i].dest_top + list[i].height, list[i].height + 1);
break;
}
ACCW(FXBNDRY,((list[i].dest_left + list[i].width) << 16) | list[i].dest_left);
ACCW(FCOL, transparent_colour);
ACCW(BCOL, 0xffffffff);
ACCGO(DWGCTL, 0x440c4018);
i++;
}
}
void SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT(engine_token *et, scaled_blit_params *list, uint32 count)
{
int i = 0;
while (count--)
{
i++;
}
}
void FILL_RECTANGLE(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count)
{
int i = 0;
while (count--)
{
ACCW(FXBNDRY, (((list[i].right + 1) << 16) | list[i].left));
ACCW_YDSTLEN(list[i].top, ((list[i].bottom - list[i].top) + 1));
ACCW(FCOL, colorIndex);
if ((si->dm.space == B_CMAP8) || si->ps.sdram)
{
ACCGO(DWGCTL, 0x400c7814);
}
else
{
ACCGO(DWGCTL, 0x400c7844);
}
i++;
}
}
void FILL_SPAN(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
{
int i = 0;
while (count--)
{
ACCW(FXBNDRY, ((list[i + 2] + 1) << 16)| list[i + 1]);
ACCW_YDSTLEN(list[i], 1);
ACCW(FCOL, colorIndex);
if ((si->dm.space == B_CMAP8) || si->ps.sdram)
{
ACCGO(DWGCTL, 0x400c7814);
}
else
{
ACCGO(DWGCTL, 0x400c7844);
}
i += 3;
}
}
void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count)
{
int i = 0;
while (count--)
{
ACCW(FXBNDRY, (((list[i].right) + 1) << 16) | list[i].left);
ACCW_YDSTLEN(list[i].top, ((list[i].bottom - list[i].top) + 1));
ACCW(FCOL, 0);
ACCGO(DWGCTL, 0x40057814);
i++;
}
}