diff --git a/.ccls b/.ccls index 814530d..aa8c065 100644 --- a/.ccls +++ b/.ccls @@ -1,3 +1,2 @@ clang -%h -x c++-header -I/otherhome/john/Amiga/Development/NDKs/3.9/Include/include_h diff --git a/.gitignore b/.gitignore index 9773373..e41400e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ activate *.lnk *.uaem .ccls-cache/ +*.lib +.ccls +ccls.log +cutest diff --git a/blitter_speed_test b/blitter_speed_test new file mode 100755 index 0000000..d76f104 Binary files /dev/null and b/blitter_speed_test differ diff --git a/blitter_speed_test.c b/blitter_speed_test.c new file mode 100644 index 0000000..0942e08 --- /dev/null +++ b/blitter_speed_test.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +extern struct GfxBase *GfxBase; +extern far struct Custom custom; + +#define COPIES (100) + +int main(void) { + // reserve two 320x200 bitplanes + // take over the system + // for 1000 loops + // * run blitter copies, setting up new registers each time + // * do CPU copies + // give the system back + // print the timings of each + + struct View *OldView; + ULONG OldCopper; + UWORD OldDMACON, OldINTENA, OldINTREQ, OldADKCON; + unsigned int startTime[2], blitTime[2], copyTime[2]; + + unsigned char *source, *target, check; + + ULONG blitTimeFinal, copyTimeFinal; + + int i, j; + + OldView = ((struct GfxBase *)GfxBase)->ActiView; + OldCopper = (ULONG)((struct GfxBase *)GfxBase)->copinit; + + LoadView(NULL); + WaitTOF(); + WaitTOF(); + OwnBlitter(); + WaitBlit(); + Forbid(); + + OldDMACON = custom.dmaconr | 0x8000; + OldINTENA = custom.intenar | 0x8000; + OldINTREQ = custom.intreqr | 0x8000; + OldADKCON = custom.adkconr | 0x8000; + + custom.dmacon = DMAF_SETCLR | DMAF_BLITTER; + custom.dmacon = DMAF_AUDIO | DMAF_DISK | DMAF_SPRITE | DMAF_COPPER | DMAF_RASTER; + + source = AllocMem(320 * 200 / 8, MEMF_CHIP | MEMF_CLEAR); + target = AllocMem(320 * 200 / 8, MEMF_CHIP | MEMF_CLEAR); + + *(source) = 1; + + timer(startTime); + + for (i = 0; i < COPIES; ++i) { + // a and d + custom.bltcon0 = (1 << 8) + (1 << 11); + custom.bltcon1 = 0; + custom.bltapt = source; + custom.bltdpt = target; + custom.bltamod = 0; + custom.bltdmod = 0; + custom.bltsize = (320 / 16) + (200 << 6); + + WaitBlit(); + } + + timer(blitTime); + + for (i = 0; i < COPIES; ++i) { + for (j = 0; j < (320 * 200 / 8); ++j) { + target[j] = source[j]; + } + } + + timer(copyTime); + + check = *(source); + + FreeMem(source, 320 * 200 / 8); + FreeMem(target, 320 * 200 / 8); + + custom.dmacon = 0x7FFF; + custom.dmacon = OldDMACON; + + custom.intena = 0x7FFF; + custom.intena = OldINTENA; + + custom.intreq = 0x7FFF; + custom.intreq = OldINTREQ; + + custom.adkcon = 0x7FFF; + custom.adkcon = OldADKCON; + + custom.cop1lc = OldCopper; + LoadView(OldView); + WaitTOF(); + WaitTOF(); + WaitBlit(); + DisownBlitter(); + Permit(); + + blitTimeFinal = (blitTime[0] - startTime[0]) * 1000000 + (blitTime[1] - startTime[1]); + copyTimeFinal = (copyTime[0] - blitTime[0]) * 1000000 + (copyTime[1] - blitTime[1]); + + printf("Number of 320x200/8 copies: %d\n", COPIES); + printf("Blitter (microsecond): %d\n", blitTimeFinal); + printf("CPU (microsecond): %d\n", copyTimeFinal); + + return 0; +} diff --git a/blitter_test b/blitter_test new file mode 100755 index 0000000..0209481 Binary files /dev/null and b/blitter_test differ diff --git a/blitter_test.c b/blitter_test.c new file mode 100644 index 0000000..ccc5a49 --- /dev/null +++ b/blitter_test.c @@ -0,0 +1,316 @@ +#include + +#include "blitter.h" +#include "cutest/CuTest.h" + +struct BlitAreaDetails blitAreaDetails; + +void TMarquee_ZeroOnWordEdges(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 0, + 0, + 207, + 7, + 0, + 8 + ); + + // no shift + CuAssertIntEquals(tc, 0, blitGenericData.shift); + + // only need 13 words + CuAssertIntEquals(tc, 26, blitGenericData.width); + + // right side has no shift so it will be treated as ascending + CuAssertIntEquals(tc, 0, blitGenericData.wordSource); + CuAssertIntEquals(tc, 0, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0xffff, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0xffff, blitGenericData.lastWordMask); +} + +void TMarquee_ZeroOnePixelOver(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 0, + 0, + 208, + 7, + 0, + 8 + ); + + // no shift + CuAssertIntEquals(tc, 0, blitGenericData.shift); + + // we ned 14 words because of an extra pixel + CuAssertIntEquals(tc, 28, blitGenericData.width); + + // right side has no shift so it will be treated as ascending + CuAssertIntEquals(tc, 0, blitGenericData.wordSource); + CuAssertIntEquals(tc, 0, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0xffff, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0x8000, blitGenericData.lastWordMask); +} + +void TMarquee_ZeroOnePixelUnder(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 0, + 0, + 206, + 7, + 0, + 8 + ); + + // no shift + CuAssertIntEquals(tc, 0, blitGenericData.shift); + + // 13 words + CuAssertIntEquals(tc, 26, blitGenericData.width); + + // right side has no shift so it will be treated as ascending + CuAssertIntEquals(tc, 0, blitGenericData.wordSource); + CuAssertIntEquals(tc, 0, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0xffff, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0xfffe, blitGenericData.lastWordMask); +} + +void TMarquee_LeftOneOnePixelUnder(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 1, + 0, + 207, + 7, + 0, + 8 + ); + + // a left shift of 1 on the right side + CuAssertIntEquals(tc, -1, blitGenericData.shift); + + // 13 words + CuAssertIntEquals(tc, 26, blitGenericData.width); + + // this is descending now + CuAssertIntEquals(tc, 24, blitGenericData.wordSource); + CuAssertIntEquals(tc, 24, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0xffff, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0x7fff, blitGenericData.lastWordMask); +} + +void TMarquee_MoveRightOnePixel(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 0, + 0, + 207, + 7, + 1, + 8 + ); + + // a right shift of 1 on the right side + CuAssertIntEquals(tc, 1, blitGenericData.shift); + + // 14 words + CuAssertIntEquals(tc, 28, blitGenericData.width); + + // ascending + CuAssertIntEquals(tc, 0, blitGenericData.wordSource); + CuAssertIntEquals(tc, 0, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0xffff, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0x0000, blitGenericData.lastWordMask); +} + +void TMarquee_MoveRight16Px(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 0, + 0, + 207, + 7, + 16, + 8 + ); + + // no shift + CuAssertIntEquals(tc, 0, blitGenericData.shift); + + // 13 words + CuAssertIntEquals(tc, 26, blitGenericData.width); + + // ascending + CuAssertIntEquals(tc, 0, blitGenericData.wordSource); + CuAssertIntEquals(tc, 2, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0xffff, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0xffff, blitGenericData.lastWordMask); +} + +void TMarquee_MoveRight8Px(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 0, + 0, + 207, + 7, + 8, + 8 + ); + + // shift 8 + CuAssertIntEquals(tc, 8, blitGenericData.shift); + + // 14 words + CuAssertIntEquals(tc, 28, blitGenericData.width); + + // ascending + CuAssertIntEquals(tc, 0, blitGenericData.wordSource); + CuAssertIntEquals(tc, 0, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0xffff, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0x0000, blitGenericData.lastWordMask); +} + +void TMarquee_ClipLeft10Px(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 40, + 0, + 112, + 7, + 0, + 8 + ); + + CuAssertIntEquals(tc, -2, blitGenericData.shift); + + // 10 words + CuAssertIntEquals(tc, 14, blitGenericData.width); + + // descending + CuAssertIntEquals(tc, 12, blitGenericData.wordSource); + CuAssertIntEquals(tc, 12, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0x8000, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0x3fff, blitGenericData.lastWordMask); +} + + +void TMarquee_ClipLeft20Px(CuTest *tc) { + struct BlitGenericData blitGenericData; + + blitAreaDetails.drawAreaWidth = 320; + blitAreaDetails.target = 0; + + blit_buildGenericBlitData( + &blitAreaDetails, + &blitGenericData, + 20, + 0, + 99, + 7, + 0, + 8 + ); + + // shift -4 + CuAssertIntEquals(tc, -4, blitGenericData.shift); + + // 10 words + shift + CuAssertIntEquals(tc, 10, blitGenericData.width); + + // descending + CuAssertIntEquals(tc, 12, blitGenericData.wordSource); + CuAssertIntEquals(tc, 8, blitGenericData.wordTarget); + + CuAssertIntEquals(tc, 0xf000, blitGenericData.firstWordMask); + CuAssertIntEquals(tc, 0x0fff, blitGenericData.lastWordMask); +} + +CuSuite *BlitterSuite() { + CuSuite *suite = CuSuiteNew(); + /* + SUITE_ADD_TEST(suite, TMarquee_ZeroOnWordEdges); + SUITE_ADD_TEST(suite, TMarquee_ZeroOnePixelOver); + SUITE_ADD_TEST(suite, TMarquee_ZeroOnePixelUnder); + SUITE_ADD_TEST(suite, TMarquee_LeftOneOnePixelUnder); + SUITE_ADD_TEST(suite, TMarquee_MoveRightOnePixel); + SUITE_ADD_TEST(suite, TMarquee_MoveRight16Px); + SUITE_ADD_TEST(suite, TMarquee_MoveRight8Px); + SUITE_ADD_TEST(suite, TMarquee_ClipLeft20Px); + */ + SUITE_ADD_TEST(suite, TMarquee_ClipLeft10Px); + + return suite; +} + +int main(void) { + CuString *output = CuStringNew(); + CuSuite *suite = CuSuiteNew(); + + CuSuiteAddSuite(suite, BlitterSuite()); + + CuSuiteRun(suite); + CuSuiteSummary(suite, output); + CuSuiteDetails(suite, output); + printf("%s\n", output->buffer); + + return 0; +} diff --git a/images.s b/images.s new file mode 100644 index 0000000..cf0c8c5 --- /dev/null +++ b/images.s @@ -0,0 +1,4 @@ + XDEF _coolbun + +_coolbun: + INCBIN "images/bun small.raw" diff --git a/images/bun small.png b/images/bun small.png new file mode 100644 index 0000000..7baf7f7 Binary files /dev/null and b/images/bun small.png differ diff --git a/images/bun small.raw b/images/bun small.raw new file mode 100644 index 0000000..8e404e1 Binary files /dev/null and b/images/bun small.raw differ diff --git a/images/bun.png b/images/bun.png new file mode 100644 index 0000000..19bf5eb Binary files /dev/null and b/images/bun.png differ diff --git a/main b/main index 5695407..0235b98 100755 Binary files a/main and b/main differ diff --git a/main.c b/main.c index 67a4718..4d0ef5a 100644 --- a/main.c +++ b/main.c @@ -7,6 +7,8 @@ #include #include +#include + #include "blitter.h" #include "copper.h" #include "screen.h" @@ -14,6 +16,7 @@ #include "system.h" extern struct Custom far custom; +extern unsigned char far coolbun[]; void writeSomethingToScreen(struct ScreenSetup *screenSetup) { *(screenSetup->memoryStart) = 255; @@ -22,36 +25,246 @@ void writeSomethingToScreen(struct ScreenSetup *screenSetup) { *(screenSetup->memoryStart + SCREEN_WIDTH * SCREEN_HEIGHT / 8 + 4) = 255; } +// [ ] increase the size of the bun area +// [ ] ensure the area has the correct data +// [ ] fix existing edge writes to work +// [ ] change non-edge write to use only bun area + +#define COOL_BUN_WIDTH (32) +#define COOL_BUN_WIDTH_BYTES (COOL_BUN_WIDTH / 8) +#define COOL_BUN_HEIGHT (32) +#define COOL_BUN_PLANES (2) + +#define COOL_BUN_PLANE_SIZE (COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT) +#define COOL_BUN_MEMORY_SIZE (COOL_BUN_PLANE_SIZE * COOL_BUN_PLANES) + +// this should be large enough to hold one bitplane of the largest object +// you are blitting, plus one additional word on each side +#define SCRATCH_AREA_WIDTH_BYTES (8) +#define SCRATCH_AREA_HEIGHT_ROWS (34) +#define SCRATCH_AREA_MEMORY_SIZE (SCRATCH_AREA_WIDTH_BYTES * SCRATCH_AREA_HEIGHT_ROWS) + +volatile short *dbg = (volatile short *)0x100; + +unsigned char *coolbunArea; +unsigned char *scratchArea; +struct ScreenSetup screenSetup; + +void clearScratchArea() { + custom.bltcon0 = 0xf0 + (1 << 8); + custom.bltcon1 = 0; + + custom.bltadat = 0x0000; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + + custom.bltdpt = scratchArea; + + custom.bltamod = 0; + custom.bltdmod = 0; + + custom.bltsize = (4) + (32 << 6); + + WaitBlit(); +} + +void bun_offRightSide(int plusXValue, int y) { + uint8_t i, plane = 0; + uint8_t shift = plusXValue & 15; + uint8_t wordShift = (plusXValue >> 4); + uint16_t bltalwm; + + for (plane = 0; plane < 2; ++plane) { + clearScratchArea(); + // step 2: copy bun to scratch area that aligns right edge to word edge + // right shift so it's ascending. + custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12); + custom.bltcon1 = (shift << 12); + + custom.bltadat = 0xffff; + custom.bltafwm = 0xffff; + + bltalwm = 0xffff; + for (i = 0; i < shift; ++i) { + bltalwm -= (1 << i); + } + custom.bltalwm = bltalwm; + + custom.bltbpt = coolbunArea + (plane * COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT); + custom.bltdpt = scratchArea + 2 + (wordShift * 2); + + custom.bltamod = 0; + custom.bltbmod = wordShift * 2; + custom.bltdmod = SCRATCH_AREA_WIDTH_BYTES - 4 + (wordShift * 2); + + // TODO: [ ] handle a scroll larger than 16px + custom.bltsize = (2 - wordShift) + (32 << 6); + + WaitBlit(); + + // step 3: copy the cropped bun image to the main screen, already left + // aligned and with no fear of wraparound + // since buns are the back layer, we shouldn't need to preserve the + // background, so no c channel needed. + // + // y repeats go here. all buns are x aligned for simplicity. + custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11); + custom.bltcon1 = 0; + + custom.bltapt = scratchArea + 2 + (wordShift * 2); + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltdpt = screenSetup.memoryStart + 30 + (wordShift * 2) + (screenSetup.nextBitplaneAdvance * plane) + (screenSetup.width / 8 * y); + + custom.bltamod = 4 + (wordShift * 2); + custom.bltdmod = (screenSetup.width / 8) - 4 + (wordShift * 2); + + custom.bltsize = (2 - wordShift) + (32 << 6); + + WaitBlit(); + } +} + +void bun_offLeftSide(int minusXValue, int y) { + unsigned char plane; + uint8_t shift = minusXValue & 15; + uint8_t wordShift = (minusXValue >> 4); + uint8_t i; + uint16_t bltalwm; + /** + * This is a three step process, repeated for each bitplane: + * + * * clean out the scratch plane + * * copy the bun graphic shifted left so that the third blit... + * * can pick up just that area and stamp it down. + */ + + for (plane = 0; plane < 2; ++plane) { + // step 1: clear the scratch area + // no modifications here! + clearScratchArea(); + + // step 2: copy the bun image to the scratch area in a way that aligns + // the cutoff point to a word edge. this requires a left shift, so + // it's descending. + custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12); + custom.bltcon1 = (1 << 1) + (shift << 12); + + custom.bltadat = 0xffff; + custom.bltafwm = 0xffff; + + bltalwm = 0xffff; + for (i = 0; i < shift; ++i) { + bltalwm -= (1 << (15 - i)); + } + custom.bltalwm = bltalwm; + + // TODO: [ ] handle a scroll larger than 16px + custom.bltbpt = coolbunArea + 2 + ((COOL_BUN_HEIGHT - 1) * COOL_BUN_WIDTH_BYTES) + (plane * COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT); + custom.bltdpt = scratchArea + 4 - (wordShift * 2) + ((COOL_BUN_HEIGHT - 1) * SCRATCH_AREA_WIDTH_BYTES); + + custom.bltamod = 0; + custom.bltbmod = wordShift * 2; + custom.bltdmod = SCRATCH_AREA_WIDTH_BYTES - 4 + (wordShift * 2); + + // TODO: [ ] handle a scroll larger than 16px + custom.bltsize = (2 - wordShift) + (32 << 6); + + WaitBlit(); + + // step 3: copy the cropped bun image to the main screen, already left + // aligned and with no fear of wraparound + // since buns are the back layer, we shouldn't need to preserve the + // background, so no c channel needed. + // + // y repeats go here. all buns are x aligned for simplicity. + custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11); + custom.bltcon1 = 0; + + custom.bltapt = scratchArea + 2; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltdpt = screenSetup.memoryStart + (screenSetup.nextBitplaneAdvance * plane) + (screenSetup.width / 8 * y); + + custom.bltamod = 4 + (wordShift * 2); + custom.bltdmod = (screenSetup.width / 8) - 4 + (wordShift * 2); + + custom.bltsize = (2 - wordShift) + (32 << 6); + + WaitBlit(); + } +} + +void bun_anywhere(int x, int y) { + uint8_t plane; + uint8_t shift = x & 15; + uint8_t needsExtraWord = shift != 0; + + for (plane = 0; plane < 2; ++plane) { + // if we extend the bun area by a word, we only need one write + + // buns will never interfere with a background so they don't need a mask + // they do need the scratch area though + custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11) + (shift << 12); + custom.bltcon1 = 0; + + custom.bltapt = coolbunArea + (COOL_BUN_HEIGHT * COOL_BUN_WIDTH_BYTES * plane); + custom.bltdpt = scratchArea + 2; + // custom.bltdpt = screenSetup.memoryStart; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltamod = 0; + custom.bltdmod = 4 - (needsExtraWord * 2); + custom.bltsize = (2 + needsExtraWord) + (32 << 6); + + WaitBlit(); + + custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11); + custom.bltcon1 = 0; + custom.bltapt = scratchArea + 2; + custom.bltdpt = screenSetup.memoryStart + WORD_ALIGNED_BYTE_POSITION(screenSetup.width, x, y) + (screenSetup.nextBitplaneAdvance * plane); + custom.bltamod = 2; + custom.bltdmod = 40 - 6; + custom.bltsize = (3) + (32 << 6); + + WaitBlit(); + } +} + int main(void) { - struct ScreenSetup screenSetup; uint16_t *copperlist, *currentCopperlist; - int i, result; + int i, x, y, plane, result; + int blitShiftRight, memoryXOffset, blitWidth; + + int bunPosition = -31; + color_t colors[16]; - struct BlitDrawLineSetup setup; - struct BlitAreaDetails blitAreaDetails, sourceBlitCopyDetails; + unsigned char *currentCoolBunArea, *currentCoolBun; - unsigned char *polygonScratchArea; + coolbunArea = AllocMem(COOL_BUN_MEMORY_SIZE, MEMF_CHIP | MEMF_CLEAR); + currentCoolBun = coolbun; - colors[0] = 0x0200; - colors[1] = 0x0f00; - colors[2] = 0x0f0f; + scratchArea = AllocMem(SCRATCH_AREA_MEMORY_SIZE, MEMF_CHIP | MEMF_CLEAR); + + colors[0] = 0x09b8; + colors[1] = 0x0000; + colors[2] = 0x0fff; colors[3] = 0x000f; prepareScreen(&screenSetup, SCREEN_WIDTH, SCREEN_HEIGHT, 4); allocateScreenMemory(&screenSetup); - blit_fillAreaDetailsFromScreenSetup( - &screenSetup, - &blitAreaDetails - ); + currentCoolBunArea = coolbunArea; - blit_fillAreaDetailsFromScreenSetup( - &screenSetup, - &sourceBlitCopyDetails - ); + for (plane = 0; plane < COOL_BUN_PLANES; ++plane) { + for (y = 0; y < COOL_BUN_HEIGHT; ++y) { + for (x = 0; x < COOL_BUN_WIDTH_BYTES; ++x) { + *(currentCoolBunArea++) = *(currentCoolBun++); + } + } + } - polygonScratchArea = AllocMem(SCREEN_WIDTH * SCREEN_HEIGHT / 8, MEMF_CHIP | MEMF_CLEAR); // blitter copy the first bitplane row down to the second @@ -66,33 +279,198 @@ int main(void) { currentCopperlist = addColorsToCopperlist(currentCopperlist, colors, 16); endCopperlist(currentCopperlist); - // blit a line to the scratch area - // blit the scratch area over + custom.bltcon0 = 0xc0 + (1 << 10) + (1 << 8); + custom.bltcon1 = (8 << 12); + custom.bltadat = 0xffff; + custom.bltafwm = 0x00ff; + custom.bltalwm = 0x0000; + custom.bltbpt = coolbunArea; + custom.bltdpt = screenSetup.memoryStart + (40 * 10 + 36); + + custom.bltbmod = -2; + custom.bltdmod = 40 - 6; + + custom.bltsize = (3) + (32 << 6); + + WaitBlit(); + + custom.bltcon0 = 0xc0 + (1 << 10) + (1 << 8); + custom.bltcon1 = (15 << 12); + custom.bltadat = 0xffff; + custom.bltafwm = 0x0001; + custom.bltalwm = 0x0000; + custom.bltbpt = coolbunArea; + custom.bltdpt = screenSetup.memoryStart + (40 * 45 + 36); + + custom.bltbmod = -2; + custom.bltdmod = 40 - 6; + + custom.bltsize = (3) + (32 << 6); + + WaitBlit(); + + custom.bltcon0 = 0xc0 + (1 << 10) + (1 << 8); + custom.bltcon1 = (8 << 12); + custom.bltadat = 0xffff; + custom.bltafwm = 0x00ff; + custom.bltalwm = 0x0000; + custom.bltbpt = coolbunArea; + custom.bltdpt = screenSetup.memoryStart + (40 * 80 + 38); + + custom.bltbmod = 0; + custom.bltdmod = 40 - 4; + + custom.bltsize = (2) + (32 << 6); + + WaitBlit(); + /* + + for (bunPosition = -31; bunPosition < screenSetup.width + 31; ++bunPosition) { + for (plane = 0; plane < 2; ++plane) { + custom.bltcon0 = 0xf0 + (1 << 11); + custom.bltcon1 = 0; + custom.bltadat = 0x0000; + custom.bltdpt = screenSetup.memoryStart; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltsize = (20) + (256 << 6); + WaitBlit(); + } + + if (bunPosition < 0) { + //bun_offLeftSide(abs(bunPosition), 100); + } else if (bunPosition >= screenSetup.width) { + //bun_offRightSide(bunPosition - screenSetup.width - 1, 100); + } else { + bun_anywhere(bunPosition, 100); + } + + WaitTOF(); + WaitTOF(); + } + /* - blit_drawLine(&blitAreaDetails, &setup, 0, 0, 0, 40, 1); - blit_drawLine(&blitAreaDetails, &setup, 1, 0, 1, 40, 3); - blit_drawLine(&blitAreaDetails, &setup, 15, 0, 15, 40, 3); - */ - //blit_drawLine(&blitAreaDetails, &setup, 16, 10, 16, 40, 3); - //blit_drawLine(&blitAreaDetails, &setup, 50, 10, 50, 40, 1); - //blit_drawLine(&blitAreaDetails, &setup, 79, 80, 79, 120, 3); + for (i = 0; i < 32; ++i) { + for (plane = 0; plane < 2; ++plane) { + custom.bltcon0 = 0xf0 + (1 << 8); + custom.bltcon1 = 0; + custom.bltadat = 0x0000; + custom.bltdpt = screenSetup.memoryStart; + custom.bltafwm = 0x0000; + custom.bltalwm = 0x0000; + custom.bltsize = (20) + (256 << 6); + WaitBlit(); + } - blit_howDoesFWMandLWMWork(&blitAreaDetails); + bun_offLeftSide(i, 100); + bun_offRightSide(i, 100); + + WaitTOF(); + WaitTOF(); + } + + /* + // left shift this over 8 so it's "against the edge" + custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (1 << 11) + (0 << 12); + custom.bltcon1 = (1 << 1) + (0 << 12); + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltapt = coolbunScratchArea + 4 + (32 * 8); + custom.bltbpt = coolbunScratchArea + 4 + (31 * 8); + custom.bltdpt = screenSetup.memoryStart + 2 + (32 * 40); + custom.bltamod = -4; + custom.bltbmod = 4; + custom.bltdmod = 40 - 4; + custom.bltsize = (2) + (32 << 6); WaitBlit(); /* + // left shift this over 8 so it's "against the edge" + custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (1 << 11) + (abs(x) << 12); + custom.bltcon1 = (1 << 1) + (abs(x) << 12); + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltapt = coolbunScratchArea + 2 + (32 * 8) + 4; + custom.bltbpt = coolbunScratchArea + 2 + 4 + (31 * 8); + custom.bltdpt = screenSetup.memoryStart + 4 + (31 * 40); + custom.bltamod = -6; + custom.bltbmod = 2; + custom.bltdmod = 40 - 6; + custom.bltsize = (1) + (32 << 6); + WaitBlit(); +*/ - blit_copyOneToOne( - &blitAreaDetails, - &blitAreaDetails, - 1, 0, 24, 16, 80, 80 - ); + WaitTOF(); + + /* + for (x = -15; x < 0; ++x) { + custom.bltcon0 = 0xf0 + (1 << 8); + custom.bltcon1 = 0; + custom.bltadat = 0xffff; + + result = 0xffff; + + for (i = 0; i < abs(x); ++i) { + result -= (1 << (15 - i)); + } + + custom.bltafwm = result; + + custom.bltalwm = 0xffff; + custom.bltdpt = coolbunScratchArea + 2 + (32 * 8); + custom.bltsize = (2) + (1 << 6); + + WaitBlit(); + + // left shift this over 8 so it's "against the edge" + custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (1 << 11) + (abs(x) << 12); + custom.bltcon1 = (1 << 1) + (abs(x) << 12); + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltapt = coolbunScratchArea + 2 + (32 * 8) + 4; + custom.bltbpt = coolbunScratchArea + 2 + 4 + (31 * 8); + custom.bltdpt = screenSetup.memoryStart + 4 + (31 * 40); + custom.bltamod = -6; + custom.bltbmod = 2; + custom.bltdmod = 40 - 6; + custom.bltsize = (3) + (32 << 6); + + WaitBlit(); + + WaitTOF(); + } + + /* + + for (x = 15; x < 17; ++x) { + for (plane = 0; plane < COOL_BUN_PLANES; ++plane) { + blitShiftRight = x & 15; + memoryXOffset = (x >> 3) & 0xfffe; + + blitWidth = (blitShiftRight > 0) ? 6 : 4; + + custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11) + (blitShiftRight << 12); + custom.bltcon1 = 0; + custom.bltapt = coolbunScratchArea + 2 + (COOL_BUN_PLANE_SIZE * plane); + + custom.bltdpt = screenSetup.memoryStart + memoryXOffset + screenSetup.nextBitplaneAdvance * plane; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltamod = 8 - blitWidth; + custom.bltdmod = 40 - blitWidth; + custom.bltsize = (blitWidth / 2) + (32 << 6); + + WaitBlit(); + } + + WaitTOF(); + } */ - for (i = 0; i < 200; ++i) { + for (i = 0; i < 100; ++i) { WaitTOF(); } @@ -101,14 +479,19 @@ int main(void) { freeScreenMemory(&screenSetup); freeCopperlist(copperlist); - FreeMem(polygonScratchArea, SCREEN_WIDTH * SCREEN_HEIGHT / 8); - printf("Hello from C\n"); + for (y = 0; y < 32; ++y) { + for (x = 0; x < SCRATCH_AREA_WIDTH_BYTES; ++x) { + printf("%d ", scratchArea[y * SCRATCH_AREA_WIDTH_BYTES + x]); + } - printf("%d %d\n", setup.dx, setup.dy); - printf("%d %d %d\n", setup.sud, setup.sul, setup.aul); + printf("\n"); + } - printf("%d %d\n", setup.accumulator, setup.sign); + printf("%d\n", 16 & 15); + + FreeMem(coolbunArea, COOL_BUN_MEMORY_SIZE); + FreeMem(scratchArea, SCRATCH_AREA_MEMORY_SIZE); return 0; } diff --git a/marquee.svg b/marquee.svg new file mode 100644 index 0000000..bad98b2 --- /dev/null +++ b/marquee.svg @@ -0,0 +1,1604 @@ + + + + + + + + + + + + + + + Wow this is some text cool! + + + + + + + + + + + + + + + + + + 215 + + 223 + + 100 + + 0 + A start + (14 words - 1) = 208 bytes + Wow this is some text cool! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Shift needed + Left = descending + Length + 8 words + First word mask + 0b1111111100000000 + Last word mask + 0b0000111111111111 + same as shift distance + Shift distance + (floor(100 / 16) * 16) - 100 = -4 bits + unneeded area + Wow this is some text cool! + D start + (8 words - 1) = 112 bytes + A start + 0 words = 0 bytes + Shift needed + Right = ascending + Length + 7 words + First word mask + 0b1111111111111111 + Last word mask + 0b1111000000000000 + same as shift distance + Shift distance + 100 - (floor(100 / 16) * 16) = +4 bits + unneeded area + D start + (8 words - 1) = 112 bytes + Wow this is some text cool! + + + + + + + + + + + + + + + + + + 215 + + 223 + + 100 + + 0 + A start + (14 words - 1) = 208 bytes + Wow this is some text cool! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Shift needed + right = ascending + Length + 8 words + First word mask + 0b1111111100000000 + Last word mask + 0b0000111111111111 + same as shift distance + Shift distance + (floor(100 / 16) * 16) - 100 + 8 = 4 bits + unneeded area + Wow this is some text cool! + D start + (8 words - 1) = 112 bytes + A start + 0 words = 0 bytes + Shift needed + Right = ascending + Length + 7 words + First word mask + 0b1111111111111111 + Last word mask + 0b1111000000000000 + same as shift distance + Shift distance + 100 - (floor(100 / 16) * 16) + 8 = 12 bits + unneeded area + D start + (8 words - 1) = 112 bytes + tx = 8 + Wow this is some text cool! + + diff --git a/old/other_blitter.c b/old/other_blitter.c new file mode 100644 index 0000000..5153b47 --- /dev/null +++ b/old/other_blitter.c @@ -0,0 +1,386 @@ +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; + } +} + diff --git a/other_blitter.c b/other_blitter.c deleted file mode 100644 index fe48286..0000000 --- a/other_blitter.c +++ /dev/null @@ -1,124 +0,0 @@ -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); -} - diff --git a/smakefile b/smakefile index 0cbc79e..cb94cdf 100644 --- a/smakefile +++ b/smakefile @@ -6,5 +6,12 @@ all: main .s.o: genam -l $*.s -main: main.o system.o blitter.o screen.o copper.o - sc link to main main.o system.o blitter.o screen.o copper.o +system.lib: system/system.o system/copper.o system/blitter.o + sc objectlibrary=system.lib system/system.o system/copper.o system/blitter.o + +main: main.o images.o system.lib screen.o + sc link to main main.o system.lib screen.o images.o + +test: blitter_test.o blitter.o system.o + sc link to blitter_test identifierlength=32 math=standard blitter_test.o blitter.o cutest/CuTest.c system.o + diff --git a/blitter.c b/system/blitter.c similarity index 54% rename from blitter.c rename to system/blitter.c index c6d5cac..8a5d4a6 100644 --- a/blitter.c +++ b/system/blitter.c @@ -3,7 +3,7 @@ #include "blitter.h" #include "system.h" -#include "types.h" +#include "../types.h" extern struct Custom far custom; @@ -63,16 +63,6 @@ void blit_drawSingleLine( 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, @@ -99,99 +89,6 @@ void blit_drawLine( } } -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, diff --git a/blitter.h b/system/blitter.h similarity index 71% rename from blitter.h rename to system/blitter.h index 68da825..48a4b4e 100644 --- a/blitter.h +++ b/system/blitter.h @@ -5,6 +5,7 @@ #include "screen.h" #define WORD_ALIGNED_BYTE_POSITION(width, x, y) (((width * y + x) >> 3) & 0xfffe) +#define WORD_ALIGNED_BYTE_X(x) (((x) >> 3) & 0xfffe) struct BlitAreaDetails { unsigned char *target; @@ -56,7 +57,25 @@ void blit_copyOneToOne( ); void blit_howDoesFWMandLWMWork( + struct BlitAreaDetails *source, struct BlitAreaDetails *target ); +struct BlitGenericData { + int8_t shift, leftShift; + uint16_t width, height; + uint16_t heightStart, targetHeightStart; + uint16_t wordSource, wordTarget; + uint16_t firstWordMask, lastWordMask; +}; + +void blit_marquee( + struct BlitAreaDetails *source, + struct BlitGenericData *data, + uint16_t splitPoint, + uint16_t ex, + uint16_t ey, + uint16_t ty +); + #endif diff --git a/copper.c b/system/copper.c similarity index 100% rename from copper.c rename to system/copper.c diff --git a/copper.h b/system/copper.h similarity index 90% rename from copper.h rename to system/copper.h index 8285d2e..0ce5e3c 100644 --- a/copper.h +++ b/system/copper.h @@ -3,7 +3,7 @@ #define COPPERLIST_SIZE (10000) -#include "types.h" +#include "../types.h" uint16_t * prepareNewCopperlist(void); void setCopperlist(uint16_t *copperlist); diff --git a/system/smakefile b/system/smakefile new file mode 100644 index 0000000..9bdee46 --- /dev/null +++ b/system/smakefile @@ -0,0 +1,8 @@ +.s.o: + genam -l $*.s + +.c.o: + sc $@ $*.c + +system.lib: system.o + sv objectlibrary=system.library system.o diff --git a/system.h b/system/system.h similarity index 100% rename from system.h rename to system/system.h diff --git a/system.s b/system/system.s similarity index 100% rename from system.s rename to system/system.s