diff --git a/.ccls b/.ccls new file mode 100644 index 0000000..814530d --- /dev/null +++ b/.ccls @@ -0,0 +1,3 @@ +clang +%h -x c++-header +-I/otherhome/john/Amiga/Development/NDKs/3.9/Include/include_h diff --git a/blitter.c b/blitter.c new file mode 100644 index 0000000..c6d5cac --- /dev/null +++ b/blitter.c @@ -0,0 +1,226 @@ +#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); +} diff --git a/blitter.h b/blitter.h new file mode 100644 index 0000000..68da825 --- /dev/null +++ b/blitter.h @@ -0,0 +1,62 @@ +#ifndef __BLITTER_H__ +#define __BLITTER_H__ + +#include "types.h" +#include "screen.h" + +#define WORD_ALIGNED_BYTE_POSITION(width, x, y) (((width * y + x) >> 3) & 0xfffe) + +struct BlitAreaDetails { + unsigned char *target; + uint16_t drawAreaWidth; + uint16_t nextBitplaneAdvance; + uint8_t contiguousBitplanes; +}; + +struct BlitDrawLineSetup { + uint16_t linePattern; + unsigned char *target; + + int dx, dy, sx; + int sud, sul, aul, accumulator, sign; +}; + +void blit_fillAreaDetailsFromScreenSetup( + struct ScreenSetup *screenSetup, + struct BlitAreaDetails *blitAreaDetails +); + +void blit_calculateLineBlit( + struct BlitDrawLineSetup *setup, + uint16_t sx, + uint16_t sy, + uint16_t ex, + uint16_t ey +); + +void blit_drawLine( + struct BlitAreaDetails *blitAreaDetails, + struct BlitDrawLineSetup *setup, + uint16_t sx, + uint16_t sy, + uint16_t ex, + uint16_t ey, + uint8_t color +); + +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 +); + +void blit_howDoesFWMandLWMWork( + struct BlitAreaDetails *target +); + +#endif diff --git a/copper.c b/copper.c new file mode 100644 index 0000000..1d5711a --- /dev/null +++ b/copper.c @@ -0,0 +1,27 @@ +#include "copper.h" +#include "system.h" + +#include +#include +#include + +extern struct Custom far custom; + +uint16_t * prepareNewCopperlist(void) { + uint16_t *copperlist = AllocMem( + COPPERLIST_SIZE, + MEMF_CHIP | MEMF_CLEAR + ); + + initializeCopperlist(copperlist); + + return copperlist; +} + +void setCopperlist(uint16_t *copperlist) { + custom.cop1lc = copperlist; +} + +void freeCopperlist(uint16_t *copperlist) { + FreeMem(copperlist, COPPERLIST_SIZE); +} diff --git a/copper.h b/copper.h new file mode 100644 index 0000000..8285d2e --- /dev/null +++ b/copper.h @@ -0,0 +1,12 @@ +#ifndef __COPPER_H__ +#define __COPPER_H__ + +#define COPPERLIST_SIZE (10000) + +#include "types.h" + +uint16_t * prepareNewCopperlist(void); +void setCopperlist(uint16_t *copperlist); +void freeCopperlist(uint16_t *copperlist); + +#endif diff --git a/main b/main index a617893..5695407 100755 Binary files a/main and b/main differ diff --git a/main.c b/main.c index aedf711..67a4718 100644 --- a/main.c +++ b/main.c @@ -7,285 +7,108 @@ #include #include +#include "blitter.h" +#include "copper.h" +#include "screen.h" +#include "types.h" +#include "system.h" + extern struct Custom far custom; -struct ScreenSetup { - short int width; - short int height; - short int bitplanes; - unsigned char *memoryStart; -}; - -typedef UWORD color_t; - -extern void TakeOverSystem(void); -extern void GiveBackSystem(void); -extern void InitializeCopperlist(void *); -extern void SetUpDisplay(struct ScreenSetup *); -extern UWORD* AddDisplayToCopperlist(UWORD *copperlist, struct ScreenSetup *); -extern UWORD* AddColorsToCopperlist(UWORD *copperlist, color_t[], int count); -extern UWORD* EndCopperlist(UWORD *copperlist); - -#define SCREEN_WIDTH (320) -#define SCREEN_HEIGHT (256) - -#define TOTAL_SCREEN_SETUP_SIZE(s) ((s->width / 8) * s->height * s->bitplanes) - -void AllocateScreenMemory(struct ScreenSetup *screenSetup) { - char *memory = (char *)AllocMem( - TOTAL_SCREEN_SETUP_SIZE(screenSetup), - MEMF_CLEAR | MEMF_CHIP - ); - - screenSetup->memoryStart = memory; -} - -void FreeScreenMemory(struct ScreenSetup *screenSetup) { - FreeMem( - screenSetup->memoryStart, - TOTAL_SCREEN_SETUP_SIZE(screenSetup) - ); -} - -#define COPPERLIST_SIZE (10000) - -UWORD * PrepareNewCopperlist(void) { - UWORD *copperlist = AllocMem( - COPPERLIST_SIZE, - MEMF_CHIP | MEMF_CLEAR - ); - - InitializeCopperlist(copperlist); - - return copperlist; -} - -void SetCopperlist(UWORD *copperlist) { - custom.cop1lc = (ULONG)copperlist; -} - -void FreeCopperlist(UWORD *copperlist) { - FreeMem(copperlist, COPPERLIST_SIZE); -} - -void WriteSomethingToScreen(struct ScreenSetup *screenSetup) { +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; } -void BlitFirstPlaneFirstRowToSecondRow(struct ScreenSetup *screenSetup) { - unsigned char *source = screenSetup->memoryStart; - unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 2 / 8); - - // copy a to d - // $09F0 - 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 BlitClearScreen(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 - - for (i = 0; i < screenSetup->bitplanes; ++i) { - custom.bltcon0 = (0x01 << 8) + 0xf0; - custom.bltcon1 = 0; - custom.bltadat = color & 1 == 1 ? 0xffff : 0; - custom.bltdpt = target + (320 * 256 / 8) * i; - custom.bltamod = 0; - custom.bltdmod = 0; - custom.bltafwm = 0xffff; - custom.bltalwm = 0xffff; - custom.bltsize = (256 << 7) + (320 / 8); - - color >>= 1; - WaitBlit(); - } -} - int main(void) { - struct ScreenSetup screenSetup = { SCREEN_WIDTH, SCREEN_HEIGHT, 4, 0 }; - struct ScreenSetup *s = &screenSetup; - UWORD *copperlist, *currentCopperlist; + struct ScreenSetup screenSetup; + uint16_t *copperlist, *currentCopperlist; int i, result; color_t colors[16]; + struct BlitDrawLineSetup setup; + struct BlitAreaDetails blitAreaDetails, sourceBlitCopyDetails; + + unsigned char *polygonScratchArea; + colors[0] = 0x0200; colors[1] = 0x0f00; colors[2] = 0x0f0f; colors[3] = 0x000f; - SetUpDisplay(&screenSetup); + prepareScreen(&screenSetup, SCREEN_WIDTH, SCREEN_HEIGHT, 4); + allocateScreenMemory(&screenSetup); - AllocateScreenMemory(&screenSetup); - WriteSomethingToScreen(&screenSetup); + blit_fillAreaDetailsFromScreenSetup( + &screenSetup, + &blitAreaDetails + ); + + blit_fillAreaDetailsFromScreenSetup( + &screenSetup, + &sourceBlitCopyDetails + ); + + polygonScratchArea = AllocMem(SCREEN_WIDTH * SCREEN_HEIGHT / 8, MEMF_CHIP | MEMF_CLEAR); // blitter copy the first bitplane row down to the second - copperlist = PrepareNewCopperlist(); + copperlist = prepareNewCopperlist(); - TakeOverSystem(); + takeOverSystem(); + + setCopperlist(copperlist); + setUpDisplay(&screenSetup); + + currentCopperlist = addDisplayToCopperlist(copperlist, &screenSetup); + currentCopperlist = addColorsToCopperlist(currentCopperlist, colors, 16); + endCopperlist(currentCopperlist); + + // blit a line to the scratch area + // blit the scratch area over /* - BlitFirstPlaneFirstRowToSecondRow(&screenSetup); - WaitBlit(); - BlitShiftFirstPlaneFirstRowToThirdRow(&screenSetup); - WaitBlit(); - BlitWithMaskInBChannel(&screenSetup); - WaitBlit(); - BlitWithMaskInBDataInCChannel(&screenSetup); - WaitBlit(); - BlitDrawHorizontalLine(&screenSetup); + 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); + + blit_howDoesFWMandLWMWork(&blitAreaDetails); + WaitBlit(); + + /* + + + blit_copyOneToOne( + &blitAreaDetails, + &blitAreaDetails, + 1, 0, 24, 16, 80, 80 + ); */ - BlitClearScreen(&screenSetup, 2); - WaitBlit(); - - SetCopperlist(copperlist); - - SetUpDisplay(&screenSetup); - - currentCopperlist = AddDisplayToCopperlist(copperlist, &screenSetup); - currentCopperlist = AddColorsToCopperlist(currentCopperlist, colors, 16); - EndCopperlist(currentCopperlist); - - for (i = 0; i < 100; ++i) { + for (i = 0; i < 200; ++i) { WaitTOF(); } - GiveBackSystem(); + giveBackSystem(); - FreeScreenMemory(&screenSetup); + freeScreenMemory(&screenSetup); - FreeCopperlist(copperlist); + freeCopperlist(copperlist); + FreeMem(polygonScratchArea, SCREEN_WIDTH * SCREEN_HEIGHT / 8); printf("Hello from C\n"); + printf("%d %d\n", setup.dx, setup.dy); + printf("%d %d %d\n", setup.sud, setup.sul, setup.aul); + + printf("%d %d\n", setup.accumulator, setup.sign); + return 0; } diff --git a/other_blitter.c b/other_blitter.c new file mode 100644 index 0000000..fe48286 --- /dev/null +++ b/other_blitter.c @@ -0,0 +1,124 @@ +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/screen.c b/screen.c new file mode 100644 index 0000000..76ff954 --- /dev/null +++ b/screen.c @@ -0,0 +1,33 @@ +#include "screen.h" +#include "types.h" + +#include +#include + +void allocateScreenMemory(struct ScreenSetup *screenSetup) { + char *memory = (char *)AllocMem( + TOTAL_SCREEN_SETUP_SIZE(screenSetup), + MEMF_CLEAR | MEMF_CHIP + ); + + screenSetup->memoryStart = memory; +} + +void freeScreenMemory(struct ScreenSetup *screenSetup) { + FreeMem( + screenSetup->memoryStart, + TOTAL_SCREEN_SETUP_SIZE(screenSetup) + ); +} + +void prepareScreen( + struct ScreenSetup *screenSetup, + uint16_t width, + uint16_t height, + uint8_t bitplanes +) { + screenSetup->width = width; + screenSetup->height = height; + screenSetup->bitplanes = bitplanes; + screenSetup->nextBitplaneAdvance = width * height / 8; +} diff --git a/screen.h b/screen.h new file mode 100644 index 0000000..597622e --- /dev/null +++ b/screen.h @@ -0,0 +1,29 @@ +#ifndef __SCREEN_H__ +#define __SCREEN_H__ + +#include "types.h" + +struct ScreenSetup { + short int width; + short int height; + short int bitplanes; + unsigned char *memoryStart; + short int nextBitplaneAdvance; +}; + + +#define SCREEN_WIDTH (320) +#define SCREEN_HEIGHT (256) + +#define TOTAL_SCREEN_SETUP_SIZE(s) ((s->width / 8) * s->height * s->bitplanes) + +void allocateScreenMemory(struct ScreenSetup *screenSetup); +void freeScreenMemory(struct ScreenSetup *screenSetup); +void prepareScreen( + struct ScreenSetup *screenSetup, + uint16_t width, + uint16_t height, + uint8_t bitplanes +); + +#endif diff --git a/smakefile b/smakefile index d03ec97..0cbc79e 100644 --- a/smakefile +++ b/smakefile @@ -6,5 +6,5 @@ all: main .s.o: genam -l $*.s -main: main.o blitter.o - sc link to main main.o blitter.o +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 diff --git a/system.h b/system.h new file mode 100644 index 0000000..f9c868b --- /dev/null +++ b/system.h @@ -0,0 +1,21 @@ +#ifndef __SYSTEM_H__ +#define __SYSTEM_H__ + +#include "types.h" +#include "screen.h" + +// this needs to be kept in sync with the XDEFs in system.s + +// copperlist +extern void initializeCopperlist(void *copperlist); +extern uint16_t* endCopperlist(uint16_t *copperlist); +extern uint16_t* addDisplayToCopperlist(uint16_t *copperlist, struct ScreenSetup *); +extern uint16_t* addColorsToCopperlist(uint16_t *copperlist, color_t[], int count); + +extern void takeOverSystem(void); +extern void giveBackSystem(void); +extern void setUpDisplay(struct ScreenSetup *); + +extern void myWaitBlit(void); + +#endif diff --git a/blitter.s b/system.s similarity index 86% rename from blitter.s rename to system.s index 22d2c51..6d75809 100644 --- a/blitter.s +++ b/system.s @@ -1,10 +1,11 @@ - XDEF _TakeOverSystem - XDEF _GiveBackSystem - XDEF _InitializeCopperlist - XDEF _SetUpDisplay - XDEF _AddDisplayToCopperlist - XDEF _AddColorsToCopperlist - XDEF _EndCopperlist + XDEF _takeOverSystem + XDEF _giveBackSystem + XDEF _initializeCopperlist + XDEF _setUpDisplay + XDEF _addDisplayToCopperlist + XDEF _addColorsToCopperlist + XDEF _endCopperlist + XDEF _myWaitBlit XREF _custom @@ -24,7 +25,7 @@ FUNC_CNT SET FUNC_CNT-6 INCLUDE "hardware/custom.i" INCLUDE "hardware/dmabits.i" -; @param 1 Pointer to numm terminated name of library +; @param 1 Pointer to null terminated name of library ; @param 2 Minimum version of library, 0 for any ; @outreg D0 pointer to library in memory OpenLibrary MACRO @@ -59,7 +60,7 @@ RestoreRegister MACRO BPLCON0_COLOR EQU $200 -_TakeOverSystem: +_takeOverSystem: MOVE.L A6,-(SP) OpenLibrary #GraphicsLibrary,#0 MOVE.L D0,GraphicsBase @@ -94,7 +95,7 @@ _TakeOverSystem: MOVE.L (SP)+,A6 RTS -_GiveBackSystem: +_giveBackSystem: MOVE.L A6,-(SP) LEA _custom,A0 @@ -118,7 +119,7 @@ _GiveBackSystem: RTS ; @stack *copperlist Pointer to copperlist -_InitializeCopperlist: +_initializeCopperlist: MOVE.L 4(A7),A0 MOVE.L #$FFFFFFFE,(A0) @@ -126,7 +127,7 @@ _InitializeCopperlist: ; @stack *copperlist Pointer to copperlist ; @stack ScreenSetup Pointer to screensetup struct -_AddDisplayToCopperlist: +_addDisplayToCopperlist: MOVE.L 4(A7),A0 ; copperlist MOVE.L 8(A7),A1 ; struct @@ -154,16 +155,18 @@ _AddDisplayToCopperlist: MULU D2,D3 ADD.L A2,D3 - ; low + ; high byte SWAP D3 MOVE.W D1,(A0)+ MOVE.W D3,(A0)+ - ; high + ; low byte SWAP D3 ADDQ #2,D1 MOVE.W D1,(A0)+ MOVE.W D3,(A0)+ DBRA D0,.continue + + ; current copperlist position MOVE.L A0,D0 MOVEM.L (SP)+,A2/D2/D3 @@ -171,8 +174,8 @@ _AddDisplayToCopperlist: ; @stack *copperlist ; @stack *colors -; @stach count -_AddColorsToCopperlist: +; @stack count +_addColorsToCopperlist: MOVE.L 4(A7),A0 ; copperlist MOVE.L 8(A7),A1 ; colors MOVE.L 12(A7),D0 ; count @@ -192,7 +195,7 @@ _AddColorsToCopperlist: RTS ; @stack *copperlist -_EndCopperlist: +_endCopperlist: MOVE.L 4(A7),A0 MOVE.W #$ffff,(A0)+ @@ -202,7 +205,7 @@ _EndCopperlist: RTS ; @stack *ScreenSetup -_SetUpDisplay: +_setUpDisplay: MOVE.L 4(A7),A0 LEA _custom,A1 @@ -226,6 +229,20 @@ _SetUpDisplay: RTS +_myWaitBlit: + LEA _custom,A0 + + BTST.B #DMAB_BLTDONE-8,dmaconr(A0) + BTST.B #DMAB_BLTDONE-8,dmaconr(A0) + BEQ .done + +.loop: + BTST.B #DMAB_BLTDONE-8,dmaconr(A0) + BNE .loop + +.done: + RTS + CNOP 0,4 OldView dc.l 0 OldCopper dc.l 0 diff --git a/types.h b/types.h new file mode 100644 index 0000000..6e14f83 --- /dev/null +++ b/types.h @@ -0,0 +1,11 @@ +#ifndef __TYPES_H__ +#define __TYPES_H__ + +#include + +typedef unsigned short color_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +typedef signed char int8_t; + +#endif