starting on the real thing

This commit is contained in:
John Bintz 2024-05-27 14:58:13 -04:00
parent af744a3469
commit 2b24ebc602
23 changed files with 2891 additions and 270 deletions

1
.ccls
View File

@ -1,3 +1,2 @@
clang
%h -x c++-header
-I/otherhome/john/Amiga/Development/NDKs/3.9/Include/include_h

4
.gitignore vendored
View File

@ -4,3 +4,7 @@ activate
*.lnk
*.uaem
.ccls-cache/
*.lib
.ccls
ccls.log
cutest

BIN
blitter_speed_test Executable file

Binary file not shown.

118
blitter_speed_test.c Normal file
View File

@ -0,0 +1,118 @@
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <graphics/gfxbase.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <exec/memory.h>
#include <time.h>
#include <stdio.h>
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;
}

BIN
blitter_test Executable file

Binary file not shown.

316
blitter_test.c Normal file
View File

@ -0,0 +1,316 @@
#include <stdio.h>
#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;
}

4
images.s Normal file
View File

@ -0,0 +1,4 @@
XDEF _coolbun
_coolbun:
INCBIN "images/bun small.raw"

BIN
images/bun small.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
images/bun small.raw Normal file

Binary file not shown.

BIN
images/bun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
main

Binary file not shown.

461
main.c
View File

@ -7,6 +7,8 @@
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <graphics/gfx.h>
#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;
}
int main(void) {
// [ ] 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, 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);
blit_copyOneToOne(
&blitAreaDetails,
&blitAreaDetails,
1, 0, 24, 16, 80, 80
);
WaitBlit();
*/
for (i = 0; i < 200; ++i) {
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();
}
@ -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;
}

1604
marquee.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 62 KiB

386
old/other_blitter.c Normal file
View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -3,7 +3,7 @@
#define COPPERLIST_SIZE (10000)
#include "types.h"
#include "../types.h"
uint16_t * prepareNewCopperlist(void);
void setCopperlist(uint16_t *copperlist);

8
system/smakefile Normal file
View File

@ -0,0 +1,8 @@
.s.o:
genam -l $*.s
.c.o:
sc $@ $*.c
system.lib: system.o
sv objectlibrary=system.library system.o