From 2b24ebc602bc76f40d6edb42f14ddc9d994e673a Mon Sep 17 00:00:00 2001 From: John Bintz Date: Mon, 27 May 2024 14:58:13 -0400 Subject: [PATCH] starting on the real thing --- .ccls | 1 - .gitignore | 4 + blitter_speed_test | Bin 0 -> 7824 bytes blitter_speed_test.c | 118 +++ blitter_test | Bin 0 -> 22896 bytes blitter_test.c | 316 +++++++ images.s | 4 + images/bun small.png | Bin 0 -> 2394 bytes images/bun small.raw | Bin 0 -> 256 bytes images/bun.png | Bin 0 -> 2892 bytes main | Bin 9620 -> 9940 bytes main.c | 459 +++++++++- marquee.svg | 1604 +++++++++++++++++++++++++++++++++ old/other_blitter.c | 386 ++++++++ other_blitter.c | 124 --- smakefile | 11 +- blitter.c => system/blitter.c | 105 +-- blitter.h => system/blitter.h | 19 + copper.c => system/copper.c | 0 copper.h => system/copper.h | 2 +- system/smakefile | 8 + system.h => system/system.h | 0 system.s => system/system.s | 0 23 files changed, 2891 insertions(+), 270 deletions(-) create mode 100755 blitter_speed_test create mode 100644 blitter_speed_test.c create mode 100755 blitter_test create mode 100644 blitter_test.c create mode 100644 images.s create mode 100644 images/bun small.png create mode 100644 images/bun small.raw create mode 100644 images/bun.png create mode 100644 marquee.svg create mode 100644 old/other_blitter.c delete mode 100644 other_blitter.c rename blitter.c => system/blitter.c (54%) rename blitter.h => system/blitter.h (71%) rename copper.c => system/copper.c (100%) rename copper.h => system/copper.h (90%) create mode 100644 system/smakefile rename system.h => system/system.h (100%) rename system.s => system/system.s (100%) 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 0000000000000000000000000000000000000000..d76f1047e4bf3cfe23567ca3b5397db33cc9e1bf GIT binary patch literal 7824 zcma)B4R934m3}iCt%hYK7Fj5AAf_4Cva~F_Ya~EXshruB5aUIxWJx&d95Ev!?MSdl z<3+;6r6Z#su&{+oHa^PExqQ?Wb%!09QgzkdDtz1Oc>L^;2s^iRrsbBG+>sQ)vd2(XAK=VOl3X7=3h zXdb%%kDSuCo22!qi7ZL128e(zmY#lKGBsP?D8|a8Vp(aoP{dZyxZ#=}VJa)5%IOi^ z!4`~tpQ@Dw&svTFjIzo@V(Y{>9c^!AK04~KY@8}KDK#XJ5PdCG9kC1&3(Hlp;bw2^ z6hLw2r?I=NC4fs?&J1#bbE{m0HAo|)D9$oaSkVOO30jsicu{AS7;{D-qF<}zs zp&&(HyYW*lZ|!yAH508b&Vi>V?l9YRqEE`V)AM3y}Sfrl+og$7hHsLiPA+!`7#h+@Qw%Vtr43=*oD3K}01TdcDK3y%?@ zHVEB)zVHMwUdLBq;=&&=V!{LOr2gPWJ0R zJN=2SN0M#H?+`5O1gxiK0{h%S^WJ}HmMXQGZ&YIShrOMo_{*p?{EuxUt^t$+6aWDV z0B)0lU#AP7ilkcPqfBcFZ+Ww=yLc-}t2mvTLKaobS}N*?DrSWr@~{5{Y*y5EFIB&x z(&lf3sH%;GpO&g~c(hM?)MC(SJrrys>1^Xwa))21D%b0fy`8EORTZ=I2;9{0cTk3x z|2xX28LyaKRRmlN9HY$`ub%|R25=mVHQvTgL8}tGTj{chmZ}NYqJNS} zCXA`nFWDo{Vq_ggYD-(Fj!Pey-$r!Jt~pV=6s-Afs^S!8J5=#wyX5unRs5@6^7@Mv zSEniC=%Y~{%RF{Tc3EbZm3CQTmvwfj z+NIkr$!udiB!!QXv`iy8HnL2P_Q8jNgG916lT+*`GsUgftHD~|?58CZ+1Jx*DsvH` zR7G5?f*(8CPgvepRGRmdev(KImmECf{xL?KzegoE%ZKf6KMe{P(0ssg=90eLZu>;+$(88cBHb=RJczyT+oT@ zVorVmT>ON&OIco8;`A6h78f#gVL#=OeD8WHT(*%4Tq>7Ax6(2M3KWgaGfIN}sgyFZ zT;sC_%gOd-KAUd~pDU2JhhpP&L@$Z>#NBZz@?c9o z&GP(9`M8G~Lwv_J`$r5n`wnWc=os`UnMGWRSYxy=L(vHeIZMIu(MPozLGt#Hi*1aQ z#AjPZp81JihE^{N=i6uj*Ui@u4?ksj4Hp>J5`7f$!>!FMDB5t9f_q5ES!LdRoZ{P{ zCm;OASAv+~mXhsb14d2Kg|gtAmf`p-fL>qvZGDaJYmeuxzlu2SNG>=v5V}s^dhb;6 z*rk0fdt08`_DMKE%h9`7FJNB_;R}Cwj<>n*r5=nmeq`wd%}?+d(h?RV=jM%5Y8RKY z>{HmWJK7h#cU48@>NRVtz8(tK)~%~2f+ZAt6Joz!WEM@mN>bVyN;mNx@NQuF@k==U z`e8ZPd8LPBd+%lU&*QU9Zs9u#JLb569I>LCQlBY}35R=@R@PZbXY{R{i;fTl3r}-> zxqtb?Gx6(THOAOYNQr|H7kXqqX#ctwK7VWGb}{VJ7& zUnLhnHpy$-DE!!A3gs$|L6es5F&(EswaJQ?u$3f@y-IGQKv_vkPKVeIa%2Bu-c8W# zId6jAfV~8Lpo%z*LfJu5+!f5zPT?dPj*jUZBjP+YUk>@Os_*ASBSO>6fCC_xSjo|I)yA%JavVvq!eraAt!YPHCE#qM( z=%z2P)al7TG{`Bkz32;LFCTts$Q~!};+fl&Hv+sjbcF=Y9TLBfOvM>L^=00ml9)p; z&T#98%Mu*>gGY% zdwZ#)Wr%CtlU>zGzN&a3WVPqKsjV{RFq|!x4KDqwEKe_H!qgMGn~(0LQZXaxN$i&` z8)8M1HWOS^d!2?&J2&Pzq%DKPMAQ~y*!#`M6U$O5Ce&V~5|>(duElD<9$s5g@;C4J zHX;U;lxy@Z_ln-XerEFQ;I6XT%XD`AWx52*KVow!gf3k0`KD-}*UMUZ+qQ0Jjk`LM z@kGyK%5CyrdE>u4X+YCh{}PSU2a!MK=MM4U%v1_tt;fV z>mR@H5bCO3pMGIeZ6vfE6#w}`OKm0n`luEThkyNwR%@MJLqV}JM+?1udTfyMXsMkV zK$exG)y^E()YGBTrF<3$>=R>>DtzWwqt|bYp$%IIz>0rgpN;Q`c|FLc#>Ekr+I+yh zD9I)SUBj*3Pso2@_h#b>t4H(^ ztp6V7n6v-Rdk&t-oB-#U8aYbi9@U8AMl(KbG1Xf}RdETneK@ig`O zQ|f3QT6%(`1cEBR$Dp*4*)EU&qeg zj&|EaYa64j_eVFaBMOBZn_I~XM-C@D+O}7-KjF8wjpr-GqgP~LyW`k6P3&-*^X$lo ziTO{QUoDq`OouP;B_(Xlw{Q;x>uuELvR$>O!wH zJzBX+lf29eEkERKlU8WV zQT+2|z#!gXoc#h)l-@<2xpO^o8{v6CR=aq==+kEITlJtNTB%fO7WY0OHH#;m<9KK3 z$9JL>b0Oj!Rca?7K{wx>-eWJ5D_*wlV{%8Dx4Z4NXEZi3-1F6Rd%HY6y6&1L=^tVZ zWW<$P{iOT}*Z%rzvJ~DsF>KWMq!+D+_QfS8>A{OnXEajJZ_yVItgR<;Ei8ZaIuak3 zBK6w~vKk)^uimFg;3^-o4((lDi|o@Gv#`E?coT8Cx8Ws#`pYP-0WNVy3wR%jJMFc* zL{ooPQTZB{Cq!gGc$4X0UPlsIz2qvD4(&C{9vU({od5c3F==(b1-)K8z~$j`U3`ja zEm~VkqFxk+W-|SwSu2^7iR+x-C;a412o1W73{Z-W**V;2=^KPje{4_ZqV~N*!)=P_ zuo;@NcorG=VT8N(3bMS(@C)IU#1MH-A!E&>#fC$E6=E$$DIvNOjp9aEWYi(+bZv7a zX+;QmA?ijMvXPtF=kL$kxr{7dL6)~zcO64E3r?7U7O%iuxUT|Z2JP7kvoo2qJoCl- zPbmP=M6{5(7Gb^;1NS7{MCx$vhy*%HUPYqrXe`{lZ<)_FKMmHk)n}PYYm&F(P9f|YsXu$0Qm(NSLARgbP zXpuW{PuuU24^H|vl+IJ~z;kNu_Est@d7gZZ!#ET5OxDRIz**V;K3)M+)%K_ll?`cY zx$(%sGl=BplaDiXS%{uP%pOI|##_LxFG;m+-S_me9G#3)kK ztZdIr;=DZ!IKoHRu|LmGMl5NZ9N5v6eEj4Xiipe+@=BJTgircf!9rS%0e6~1eHLG!?3!v{pnS(I@qS+ut%08 zyEF9N^>hrkW^Qk@XVarhTA{+qVYe$ZlDM@`zy}i5z(~#T3zp}$@O6Qs0~`yI&XWUi z+2-)94{t5t=78tCfz{?gPeiYPQUs-+%L9H(k^*dOK^tBBdmq08Wc?<|9LW0s31nW(C|1gdrM(s2^D9{M1hjYJZ+~L@amFLfz`;pn9xz)y z^Cp5N6jwG}7fhQIf8|ZEF7n{TRhskFvm=HcDx{GZ<_Jup()dX&g`G%846zsv(htZnj11zYTfUj5PXCh4cK5fg*UkU!ZA5u-k z3*e9E6gj&h`7%!K*AJe7?@pw%R}bE{Zy@`$xm>{u`4RElvTb-KJ%W)(lx$AP`JRfa zz&&}B+bKN=zVC2N;rn)m1L#1t?IzWfEko;E`$1%KCL!lKj(i)@(L$C*A$W{R;qbU{ zwmc+EB?Xk9C&hAAxQ4%P@V|55oeD8aiuN`3^_qRXc<;Esp_*{I1`2M?qL(Gab7V)6 z=%a|dmkEIYfZw8zP&fc+J6-|20eBWL0v!K)j}ssPM0~CTenpfEdg-^ooSK&M_|J+ZQ{d2v4X`gMA zt~9k!hk1hl8Ex1T{Q|((XaW*|PJj;B48We*c8ERXvI@rm47iH`TmKn5{21+`K!Fdh z#9~>)RoE@}|7w1+LZ2BtF#Q~pZ7X +#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 0000000000000000000000000000000000000000..0209481359cae917be8d58fd8922d1d8a68dd11e GIT binary patch literal 22896 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 + +#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 0000000000000000000000000000000000000000..7baf7f775c9e2983357bac81ade20fa7619ad526 GIT binary patch literal 2394 zcmV-g38nUlP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1e=mgXi5{Ld+J1a`r3*z{g*kmIKWc=^`p%%nZt z##jbPC6&ae@z39^{=$#5-YXv{#T=u?kIz2afL~zj&pvkTPEANAk%9Brsp%Ps1A%qwxq>w|2F8UZ^j1(mo3pw%> zC=yYkOeMMGQ%EsUN-3wJvds>;8gk5(Q_i^*Y+A5#!Pg}fOjKK4^)=L3sivB1X$YU@ zTWGOSOD(sey6vv}9(wH5Q_sB&GZ0F{k1*n(kwzYc5o+w%bKuCti8GfIwTY^F!0Z*d z@2HuL8URxhGY_EyHB1v7OBkV(AeaF$>kSYmK>z`51v8zD_g0Wof|<@1SrII>3<6F! zf*26=!`Q&)#O^}w1viDf|6Sbd9XTb?{U69Ff$j}*ueiNItqZ?5$wLidlQa~kYKQde zq1aSxWrQzVxJsVDgD-a$B?la^2UR5^#?I6#2RACG;P8xHdj-q@8F*5+HLweF;DH%& z!`sXwnHGrI4pKb&kPmwGb2n^}VU=DF`p0+mUq5)hi)k`cg}ZIsDRBug-E2?P8ri`m zljYi}c1Q?jxeg#eCYKQc_slKBCR7mwR=CL+AMg)hKv}P`{>feaRPgPcS`QN#YDy+) zF)D=_7K@$bne1LOex6fvntm>oKG)6K~&8#NM_%SM5hVt zOW$rXDpQP(gM3S|1G#`bv2uW3-Beq!I#=&9_l67z4+51(9g;AW)qn}Uanzi&J+miW z=F~dPDWWZP}EOW$~MAMq8TD=R1veP2g5_IFIWbybLD@{yeHG7C1rh;4f8AupSG5{4Q;R3YK7BvpDLIpw*cqvq{iQoaA;_ih< zAHb*wWVSk|UK^j25A`ecO`wEo2^E^+!YMAC$j>;RI2lQV4HIveZtpir$a;me|FiP3 zYlr%i;&E|5ddQRF{*d8>*zCb=_Mp2lYiN>SJ6TZcNeLp5*6<-J)rUfS(xm_|4{y2S zMjh&rJFwI{_Lv0;M&*{m%1mK?fLK-o;(%I17o!m^Gm=Vy=iGeRGRjqrt0RJP!U|4w z{LnwC=f=ratiO^ilO!A9M=k+e(r0f`I*a3I*Q~)05cl6Sq6Y6gHB#-+7yk*qk(Z_PTg*NXz zv(R+;eH(aH-Amp>2Q8Ed89e9JZ-X^sKLRv*&JTUOx;ON0mE^0TA8tBQIuh|?5kH}< z!cWq06c?8x!Ldov^d(xC2N|*UGH~QP+G`}`FQS&ot!4dwc}VY$?kil{qdnAUBemEvQO)pTM}i}_eCB{T}EMKgGhw`uygu zv_sK?nEDqUd)F5ro=j!{000S4OjJbx{Qv*}0RR90=d;d90001;Nkl{$V~n|({w}Z=xDL}gl-Gd0 z7H=q5m>o&8dO~fpnRwGaiW?`d5+}xKina(tY=Jufd6c0R$cSYqF(Ri^-3a(71RVG( zs2d8Cf-bfLs8p5)!d=OSrYsZRu?2y&v`>a_`Gd3@-Lm(~=JoFze&^FX^(^sZ+W-In M07*qoM6N<$f>>64J^%m! literal 0 HcmV?d00001 diff --git a/images/bun small.raw b/images/bun small.raw new file mode 100644 index 0000000000000000000000000000000000000000..8e404e19630fdfdec050b725169ab71ed8bf7f5b GIT binary patch literal 256 zcmZ9{v1-Cl6vpxYH6aNYa<90=NpY4EsE9*RCm*0s;HI;agP1EFx^ylb`Uri1ZpJ5Y z?cm^0@EL@V^rSlZ!H>f^!#NygKqV1F(Gz_!fKwAz4R|n?$M{I=XG5^6g>I~#Jk+m4 z@~-U15}Q4fO}etDMh6)S!xp1nFwT_N`=q53>h?smw**r;uol(PyBO(%n^0;5MnmX> z=Ue>O9Oqo1$|9ybEJ){Xq~kBfyCdx~|EHzua)U0`==>Z1GQ%q}+*B5hMD^%3f1oii A_W%F@ literal 0 HcmV?d00001 diff --git a/images/bun.png b/images/bun.png new file mode 100644 index 0000000000000000000000000000000000000000..19bf5ebd27c5da58e5173fd4678b2814e0d44fb4 GIT binary patch literal 2892 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 delta 4911 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 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