#include #include #include "blitter.h" #include "system.h" #include "types.h" extern struct Custom far custom; /** * @param setup Data about the line's draw properties are injected into this struct. */ void blit_calculateLineBlit( struct BlitDrawLineSetup *setup, uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey ) { uint16_t i; setup->sx = sx; setup->dx = ex - sx; setup->dy = ey - sy; if (setup->dx == 0 && setup->dy == 0) return; setup->sud = abs(setup->dy) < abs(setup->dx); if (!setup->sud) { i = setup->dx; setup->dx = setup->dy; setup->dy = i; } setup->sul = setup->dy < 0; setup->dy = abs(setup->dy); setup->aul = setup->dx < 0; setup->dx = abs(setup->dx); setup->accumulator = 4 * setup->dy - 2 * setup->dx; setup->sign = setup->accumulator < 0; } void blit_drawSingleLine( struct BlitAreaDetails *blitAreaDetails, struct BlitDrawLineSetup *setup ) { custom.bltadat = 0x8000; custom.bltbdat = setup->linePattern; custom.bltafwm = 0xffff; custom.bltalwm = 0xffff; custom.bltamod = 4 * (setup->dy - setup->dx); custom.bltbmod = 4 * setup->dy; custom.bltcmod = blitAreaDetails->drawAreaWidth / 8; custom.bltdmod = blitAreaDetails->drawAreaWidth / 8; custom.bltapt = setup->accumulator; custom.bltcpt = setup->target; custom.bltdpt = setup->target; custom.bltcon0 = ((setup->sx % 16) << 12) + (11 << 8) + 0xca; custom.bltcon1 = 1 + (setup->aul << 2) + (setup->sul << 3) + (setup->sud << 4) + (setup->sign << 6); custom.bltsize = 0x02 + ((setup->dx + 1) << 6); } 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_drawLine( struct BlitAreaDetails *blitAreaDetails, struct BlitDrawLineSetup *setup, uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint8_t color ) { int i; blit_calculateLineBlit(setup, sx, sy, ex, ey); setup->target = blitAreaDetails->target + WORD_ALIGNED_BYTE_POSITION(blitAreaDetails->drawAreaWidth, sx, sy); for (i = 0; i < blitAreaDetails->contiguousBitplanes; ++i) { setup->linePattern = ((color & 1) == 1) ? 0xffff : 0; blit_drawSingleLine(blitAreaDetails, setup); setup->target += blitAreaDetails->nextBitplaneAdvance; color >>= 1; WaitBlit(); } } 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 *target ) { // data in a // setting fwm and lwm to mask that // dma enabled for only D custom.bltcon0 = 0xF0 + (1 << 8); custom.bltcon1 = 0; custom.bltadat = 0xffff; custom.bltafwm = 0x0ff0; custom.bltalwm = 0xf0f0; custom.bltdpt = target->target; custom.bltamod = 0; custom.bltbmod = 0; custom.bltsize = (2) + (1 << 6); } // 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; } } void blit_fillPolygon( struct ScreenSetup *screenSetup, uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint8_t color ) { // use a standard copy blit // set bltadat to 0xffff // set bltdpt to the top left corner of the zone // width is dx / 8 // height is dy // enable descending mode // enable inclusive fill for now uint16_t dx = ex - sx; uint16_t dy = ey - sy; unsigned char *source = screenSetup->memoryStart + ((((ey * screenSetup->width + ex) >> 3) - 2) & 0xfffe); unsigned char *target = screenSetup->memoryStart + (((((ey + 100) * screenSetup->width + ex) >> 3) - 2) & 0xfffe); custom.bltcon0 = (1 << 11) + (1 << 8) + 0xF0; // we don't want to copy anything so we only enable target custom.bltcon1 = (1 << 1) + (1 << 3); custom.bltapt = source; custom.bltdpt = target; custom.bltamod = ((screenSetup->width - dx) >> 3) + 1; custom.bltdmod = ((screenSetup->width - dx) >> 3) + 1; custom.bltafwm = 0xffff; custom.bltalwm = 0xffff; custom.bltsize = (dx / 16) + (dy << 6); }