#include #include #include #include #include #include #include #include "blitter.h" #include "copper.h" #include "screen.h" #include "types.h" #include "system.h" extern struct Custom far custom; extern unsigned char far coolbun[]; void writeSomethingToScreen(struct ScreenSetup *screenSetup) { *(screenSetup->memoryStart) = 255; *(screenSetup->memoryStart + 8) = 0xAA; *(screenSetup->memoryStart + 16) = 0xF0; *(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) { uint16_t *copperlist, *currentCopperlist; int i, x, y, plane, result; int blitShiftRight, memoryXOffset, blitWidth; int bunPosition = -31; color_t colors[16]; unsigned char *currentCoolBunArea, *currentCoolBun; coolbunArea = AllocMem(COOL_BUN_MEMORY_SIZE, MEMF_CHIP | MEMF_CLEAR); currentCoolBun = coolbun; 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); currentCoolBunArea = coolbunArea; 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++); } } } // blitter copy the first bitplane row down to the second copperlist = prepareNewCopperlist(); takeOverSystem(); setCopperlist(copperlist); setUpDisplay(&screenSetup); currentCopperlist = addDisplayToCopperlist(copperlist, &screenSetup); currentCopperlist = addColorsToCopperlist(currentCopperlist, colors, 16); endCopperlist(currentCopperlist); 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(); } /* 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(); } 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(); */ 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 < 100; ++i) { WaitTOF(); } giveBackSystem(); freeScreenMemory(&screenSetup); freeCopperlist(copperlist); 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("\n"); } printf("%d\n", 16 & 15); FreeMem(coolbunArea, COOL_BUN_MEMORY_SIZE); FreeMem(scratchArea, SCRATCH_AREA_MEMORY_SIZE); return 0; }