#include "GlobalData.h"
#include "generic.h"
static __inline void set8(volatile unsigned char *addr, unsigned char mask,
unsigned char val)
{
if (mask == 0)
*addr = val;
else
*addr = (*addr & mask) | (val & ~mask);
}
static __inline unsigned char get8(volatile unsigned char *addr)
{
return *addr;
}
static __inline void et6000aclTerminate(void) {
set8(mmRegs+0x31, 0xef, 0x10);
et6000aclWaitIdle();
set8(mmRegs+0x30, 0, 0x00);
set8(mmRegs+0x30, 0, 0x01);
et6000aclWaitIdle();
set8(mmRegs+0x30, 0, 0x00);
set8(mmRegs+0x30, 0, 0x10);
et6000aclWaitIdle();
set8(mmRegs+0x30, 0, 0x00);
}
void et6000aclInit(uint8 bpp) {
et6000aclTerminate();
set8(mmRegs+0x31, 0xef, 0x10);
set8(mmRegs+0x32, 0x99, 0x00);
set8(mmRegs+0x8e, 0xcf, (bpp - 1) << 4);
set8(mmRegs+0x91, 0x80, 0x00);
set8(mmRegs+0x9d, 0x00, 0x00);
}
void et6000aclWaitIdle(void) {
while ((get8(mmRegs+0x36) & 0x02) == 0x02);
}
static __inline void et6000aclWaitQueueNotFull(void) {
while ((get8(mmRegs+0x36) & 0x01) == 0x01);
}
void SCREEN_TO_SCREEN_BLIT(engine_token *et,
blit_params *list,
uint32 count)
{
uint16 screenWidth = si->dm.virtual_width;
uint8 bpp = si->bytesPerPixel;
uint8 bltDir;
uint16 src_left, src_top, dest_left, dest_top, width, height;
uint32 srcAddr = 0, destAddr = 0;
et6000aclWaitQueueNotFull();
set8(mmRegs+0x92, 0x80, 0x77);
set8(mmRegs+0x9c, 0x00, 0x33);
set8(mmRegs+0x9f, 0x00, 0xcc);
*((vuint16 *)(mmRegs+0x8a)) = screenWidth * bpp - 1;
*((vuint16 *)(mmRegs+0x8c)) = screenWidth * bpp - 1;
while(count--) {
src_left = list->src_left;
src_top = list->src_top;
dest_left = list->dest_left;
dest_top = list->dest_top;
width = list->width;
height = list->height;
et6000aclWaitQueueNotFull();
bltDir = 0x00;
if (src_left < dest_left) bltDir |= 0x01;
if (src_top < dest_top) bltDir |= 0x02;
set8(mmRegs+0x8f, 0x3c, bltDir);
*((vuint16 *)(mmRegs+0x98)) = (width + 1) * bpp - 1;
*((vuint16 *)(mmRegs+0x9a)) = height;
switch (bltDir & 0x03) {
case 0x00:
srcAddr = (src_top * screenWidth + src_left) * bpp;
destAddr = (dest_top * screenWidth + dest_left) * bpp;
break;
case 0x01:
srcAddr = (src_top * screenWidth + src_left + width) * bpp + bpp-1;
destAddr = (dest_top * screenWidth + dest_left + width) * bpp + bpp-1;
break;
case 0x02:
srcAddr = ((src_top + height)*screenWidth + src_left) * bpp;
destAddr = ((dest_top + height)*screenWidth + dest_left) * bpp;
break;
case 0x03:
srcAddr = ((src_top + height)*screenWidth + src_left + width) * bpp + bpp-1;
destAddr = ((dest_top + height)*screenWidth + dest_left + width) * bpp + bpp-1;
break;
}
*((vuint32 *)(mmRegs+0x84)) = srcAddr;
*((vuint32 *)(mmRegs+0xa0)) = destAddr;
list++;
}
si->engine.count++;
}
void FILL_RECTANGLE(engine_token *et,
uint32 color,
fill_rect_params *list,
uint32 count)
{
uint16 screenWidth = si->dm.virtual_width;
uint8 bpp = si->bytesPerPixel;
uint16 left, top, right, bottom;
uint32 srcAddr;
uint8 i;
if (bpp == 2)
et6000aclWaitQueueNotFull();
else
et6000aclWaitIdle();
srcAddr = (uint32)si->framebuffer - (uint32)si->memory +
si->dm.virtual_width * si->dm.virtual_height * bpp;
switch(bpp) {
case 2:
set8(mmRegs+0x92, 0x80, 0x02);
for (i = 0; i < 2; i++)
((vuint16 *)((uint32)si->memory + srcAddr))[i] = (uint16)color;
break;
case 3:
set8(mmRegs+0x92, 0x80, 0x0a);
for (i = 0; i < 3; i++)
((vuint8 *)((uint32)si->memory + srcAddr))[i] = ((uint8 *)&color)[i];
break;
}
set8(mmRegs+0x9c, 0x00, 0x33);
set8(mmRegs+0x9f, 0x00, 0xcc);
*((vuint16 *)(mmRegs+0x8a)) = screenWidth * bpp - 1;
*((vuint16 *)(mmRegs+0x8c)) = screenWidth * bpp - 1;
set8(mmRegs+0x8f, 0x18, 0x40);
set8(mmRegs+0x93, 0x1a, 0x00);
*((vuint16 *)(mmRegs+0xac)) = 0;
*((vuint16 *)(mmRegs+0xb4)) = 0;
while(count--) {
left = list->left;
top = list->top;
right = list->right;
bottom = list->bottom;
et6000aclWaitQueueNotFull();
*((vuint16 *)(mmRegs+0x98)) = (right-left+1)*bpp - 1;
*((vuint16 *)(mmRegs+0x9a)) = bottom-top;
*((vuint16 *)(mmRegs+0xae)) = bottom-top;
*((vuint16 *)(mmRegs+0xb6)) = bottom-top;
*((vuint32 *)(mmRegs+0x84)) = srcAddr;
*((vuint32 *)(mmRegs+0xa0)) = (top * screenWidth + left) * bpp;
list++;
}
si->engine.count++;
}