cool-bun-demo/old/other_blitter.c

387 lines
9.9 KiB
C

void BlitFirstPlaneFirstRowToSecondRow(struct ScreenSetup *screenSetup) {
unsigned char *source = screenSetup->memoryStart;
unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 2 / 8);
custom.bltcon0 = 0x09f0;
custom.bltcon1 = 0;
custom.bltapt = source;
custom.bltdpt = target;
custom.bltamod = 0;
custom.bltdmod = 0;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = 0x0041;
}
void BlitShiftFirstPlaneFirstRowToThirdRow(struct ScreenSetup *screenSetup) {
unsigned char *source = screenSetup->memoryStart;
unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 4 / 8);
custom.bltcon0 = 0x49f0;
custom.bltcon1 = 0;
custom.bltapt = source;
custom.bltdpt = target;
custom.bltamod = 0;
custom.bltdmod = 0;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = 0x0041;
}
void BlitWithMaskInBChannel(struct ScreenSetup *screenSetup) {
unsigned char *source = screenSetup->memoryStart;
unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 6 / 8);
unsigned char *mask = (screenSetup->memoryStart + 8);
// a is source
// b is mask
// d is destination
// so I want AB
custom.bltcon0 = 0x0dc0;
custom.bltcon1 = 0;
custom.bltapt = mask;
custom.bltbpt = source;
custom.bltdpt = target;
custom.bltamod = 0;
custom.bltdmod = 0;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = 0x0041;
}
void BlitWithMaskInBDataInCChannel(struct ScreenSetup *screenSetup) {
unsigned char *source = screenSetup->memoryStart;
unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 8 / 8);
unsigned char *mask = (screenSetup->memoryStart + 8);
unsigned char *background = (screenSetup->memoryStart + 16);
// a is source
// b is mask
// c is background
// d is destination
// so I want AB+`AC
custom.bltcon0 = 0x0fca;
custom.bltcon1 = 0;
custom.bltapt = mask;
custom.bltbpt = source;
custom.bltcpt = background;
custom.bltdpt = target;
custom.bltamod = 0;
custom.bltbmod = 0;
custom.bltcmod = SCREEN_WIDTH / 8;
custom.bltdmod = SCREEN_WIDTH / 8;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = 0x0041;
}
void BlitDrawHorizontalLine(struct ScreenSetup *screenSetup) {
// i want to draw a line from 20,20 to 50,80
// i need to get dx and dy
// dx is 30, dy is 60
// the shift value is 20 mod 15 = 5
// a data register gets $8000
// b data register gets $ffff
// text shift is 0
// c and d pointers get the word containing the first pixel, so
// screenSetup->memoryStart + 320 * 20 / 8 + 2
// module registers get width of bitplane in bytes
// blit height is dx + 1 so 31
// blit width = 2
// logic is ab+'a, so 6, 7, 2, 3, 1, 0
char *target = screenSetup->memoryStart + (320 * 20 + 20) / 8;
int dx = 10;
int dy = 60;
int tmp;
if (dx < dy) {
tmp = dx;
dx = dy;
dy = tmp;
}
custom.bltcon0 = (5 << 12) + (11 << 8) + 0xca;
custom.bltcon1 = 1;
custom.bltapt = 4 * dy - 2 * dx;
custom.bltadat = 0x8000;
custom.bltbdat = 0xffff;
custom.bltcpt = target;
custom.bltdpt = target;
custom.bltamod = 4 * (dy - dx);
custom.bltbmod = 4 * dy;
custom.bltcmod = 320 / 8;
custom.bltdmod = 320 / 8;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = 0x02 + (dx + 1 << 7);
}
void blit_buildGenericBlitData(
struct BlitAreaDetails *source,
struct BlitGenericData *data,
uint16_t sx,
uint16_t sy,
uint16_t ex,
uint16_t ey,
uint16_t tx,
uint16_t ty
) {
int8_t shift = (sx & 0xfff0) - sx + (tx & 15);
uint8_t needsDescending = shift < 0;
uint8_t i;
uint8_t firstWordPixelMask;
uint8_t lastWordPixelMask;
uint16_t firstWordMask = 0xFFFF;
uint16_t lastWordMask = 0xFFFF;
uint16_t wordSource, wordTarget;
uint16_t heightStart;
uint16_t targetHeightStart;
// this is correct, there will always be at least two bytes
uint16_t width = WORD_ALIGNED_BYTE_X(ex - sx + abs(shift)) + 2;
uint16_t height = ey;
//printf("%d %d %d\n", wordStart, wordEnd, width);
data->shift = shift;
data->width = width;
data->height = height;
firstWordMask = 0x0000;
lastWordMask = 0x0000;
if (needsDescending) {
wordSource = WORD_ALIGNED_BYTE_X(sx) + width - 2;
wordTarget = WORD_ALIGNED_BYTE_X(tx) + width - 2;
heightStart = WORD_ALIGNED_BYTE_X(source->drawAreaWidth * ey);
targetHeightStart = WORD_ALIGNED_BYTE_X(source->drawAreaWidth * (ty + height));
// this needs to be more precise
// using x positions and not this niave approach
firstWordPixelMask = (ex & 15) + 1;
lastWordPixelMask = 16 - (sx & 15);
for (i = 0; i < lastWordPixelMask; ++i) {
uint16_t bit = (1 << i);
lastWordMask += bit;
}
for (i = 0; i < firstWordPixelMask; ++i) {
uint16_t bit = (1 << (15 - i));
firstWordMask += bit;
}
} else {
wordSource = WORD_ALIGNED_BYTE_X(sx);
wordTarget = WORD_ALIGNED_BYTE_X(tx);
heightStart = WORD_ALIGNED_BYTE_X(0);
targetHeightStart = WORD_ALIGNED_BYTE_X(source->drawAreaWidth * ty);
firstWordPixelMask = 16 - (sx & 15);
lastWordPixelMask = (ex & 15) + 1 - shift;
for (i = 0; i < firstWordPixelMask; ++i) {
uint16_t bit = (1 << i);
firstWordMask += bit;
}
for (i = 0; i < lastWordPixelMask; ++i) {
uint16_t bit = (1 << (15 - i));
lastWordMask += bit;
}
}
data->heightStart = heightStart;
data->targetHeightStart = targetHeightStart;
data->wordSource = wordSource;
data->wordTarget = wordTarget;
data->firstWordMask = firstWordMask;
data->lastWordMask = lastWordMask;
}
void blit_generic(
struct BlitAreaDetails *source,
struct BlitGenericData *blitGenericData,
uint16_t sx,
uint16_t sy,
uint16_t ex,
uint16_t ey,
uint16_t tx,
uint16_t ty
) {
uint8_t needsDescending;
blit_buildGenericBlitData(
source,
blitGenericData,
sx, sy, ex, ey, tx, ty
);
needsDescending = blitGenericData->shift < 0;
custom.bltcon0 = 0xF0 + (1 << 8) + (1 << 11) + (abs(blitGenericData->shift) << 12);
custom.bltcon1 = (needsDescending << 1);
custom.bltadat = 0xFFFF;
custom.bltafwm = blitGenericData->firstWordMask;
custom.bltalwm = blitGenericData->lastWordMask;
custom.bltapt = source->target + blitGenericData->heightStart + blitGenericData->wordSource;
custom.bltdpt = source->target + blitGenericData->targetHeightStart + blitGenericData->wordTarget;
custom.bltamod = source->drawAreaWidth / 8 - blitGenericData->width;
custom.bltdmod = source->drawAreaWidth / 8 - blitGenericData->width;
custom.bltsize = (blitGenericData->width / 2) + ((blitGenericData->height + 1) << 6);
WaitBlit();
}
void blit_fillAreaDetailsFromScreenSetup(
struct ScreenSetup *screenSetup,
struct BlitAreaDetails *blitAreaDetails
) {
blitAreaDetails->target = screenSetup->memoryStart;
blitAreaDetails->drawAreaWidth = screenSetup->width;
blitAreaDetails->nextBitplaneAdvance = screenSetup->nextBitplaneAdvance;
blitAreaDetails->contiguousBitplanes = screenSetup->bitplanes;
}
void blit_copyOneToOne(
struct BlitAreaDetails *source,
struct BlitAreaDetails *target,
uint16_t sx,
uint16_t sy,
uint16_t ex,
uint16_t ey,
uint16_t tx,
uint16_t ty
) {
uint16_t dx = ex - sx;
uint16_t dy = ey - sy;
// 23 = 2
// 24 = 3
// 0-15 has to equal 2
// 16-31 has to equal 4
//
// 23 = ((23 / 8) & fffe) + 2 =
uint16_t aModulo = (source->drawAreaWidth / 8) - (((dx + 16) >> 3) & 0xfffe);
uint16_t dModulo = (target->drawAreaWidth / 8) - (((dx + 16) >> 3) & 0xfffe);
uint8_t shiftA = sx % 16;
unsigned char *aPointer = source->target + WORD_ALIGNED_BYTE_POSITION(source->drawAreaWidth, sx, sy);
unsigned char *dPointer = target->target + WORD_ALIGNED_BYTE_POSITION(target->drawAreaWidth, tx, ty);
custom.bltcon0 = (1 << 11) + (1 << 8) + 0xca;
custom.bltcon1 = (1 << 1);
//custom.bltapt = aPointer;
//custom.bltdpt = dPointer;
custom.bltapt = aPointer + WORD_ALIGNED_BYTE_POSITION(source->drawAreaWidth, dx, dy);
custom.bltdpt = dPointer + WORD_ALIGNED_BYTE_POSITION(target->drawAreaWidth, dx, dy);
custom.bltamod = aModulo;
custom.bltdmod = dModulo;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = (dx / 16) + 1 + (dy << 6);
}
void blit_howDoesFWMandLWMWork(
struct BlitAreaDetails *source,
struct BlitAreaDetails *target
) {
// goal: shift over one pixel to right
// width: 32px + 1px shift = 33 = 3 words
// fw mask = 0xffff -- copy everything
// lw mask = 0x0000 -- do not copy anything
// enable a, b, and c
custom.bltcon0 = 0xF0 + (1 << 8) + (1 << 11) + (1 << 12);
custom.bltcon1 = 0;
custom.bltadat = 0xffff;
custom.bltafwm = 0xffff;
custom.bltalwm = 0x0000;
custom.bltapt = source->target;
custom.bltdpt = target->target + 40;
custom.bltamod = source->drawAreaWidth ;
custom.bltbmod = target->drawAreaWidth;
custom.bltsize = (3) + (1 << 6);
WaitBlit();
// this will need to go in reverse so i can shift left
custom.bltcon0 = 0xF0 + (1 << 8) + (1 << 11) + (1 << 12);
custom.bltcon1 = (1 << 1);
custom.bltadat = 0x0000;
custom.bltafwm = 0xffff;
custom.bltalwm = 0x0000;
custom.bltapt = source->target + 10 + 2;
custom.bltdpt = target->target + 40 + 10 + 2;
custom.bltamod = source->drawAreaWidth;
custom.bltdmod = target->drawAreaWidth;
custom.bltsize = (3) + (1 << 6);
WaitBlit();
}
// TODO: blit_drawRectangle
void blit_clearScreen(struct ScreenSetup *screenSetup, int color) {
unsigned char *target = screenSetup->memoryStart;
int i;
// a is source
// b is mask
// c is background
// d is destination
// so I want AB+`AC
custom.bltcon0 = (0x01 << 8) + 0xf0;
custom.bltcon1 = 0;
custom.bltamod = 0;
custom.bltdmod = 0;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
for (i = 0; i < screenSetup->bitplanes; ++i) {
custom.bltadat = color & 1 == 1 ? 0xffff : 0;
custom.bltdpt = target + (320 * 256 / 8) * i;
custom.bltsize = (256 << 7) + (320 / 8);
myWaitBlit();
color >>= 1;
}
}