commit 026b6f6f0d2f5ae0e3dc0aac790436f29566a476 Author: John Bintz Date: Mon Apr 29 22:12:48 2024 -0400 it works diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9773373 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.vamosrc +activate +*.o +*.lnk +*.uaem +.ccls-cache/ diff --git a/blitter.s b/blitter.s new file mode 100644 index 0000000..22d2c51 --- /dev/null +++ b/blitter.s @@ -0,0 +1,240 @@ + XDEF _TakeOverSystem + XDEF _GiveBackSystem + XDEF _InitializeCopperlist + XDEF _SetUpDisplay + XDEF _AddDisplayToCopperlist + XDEF _AddColorsToCopperlist + XDEF _EndCopperlist + + XREF _custom + +FUNC_CNT SET -30 +FUNCDEF MACRO +_LVO\1 EQU FUNC_CNT +FUNC_CNT SET FUNC_CNT-6 + ENDM + + INCDIR "include_i_39:" + INCDIR "extra_lvos_39:" + INCLUDE "exec/exec_lib.i" + INCLUDE "exec/types.i" + INCLUDE "exec/libraries.i" # get the CALLLIB macro + INCLUDE "graphics/gfxbase.i" + INCLUDE "graphics_lvo.i" + INCLUDE "hardware/custom.i" + INCLUDE "hardware/dmabits.i" + +; @param 1 Pointer to numm terminated name of library +; @param 2 Minimum version of library, 0 for any +; @outreg D0 pointer to library in memory +OpenLibrary MACRO + MOVE.L 4,A6 + MOVEM.L A1,-(SP) + MOVE.L \1,A1 + MOVE.L \2,D0 + CALLLIB _LVOOpenLibrary + MOVEM.L (SP)+,A1 + ENDM + +PreserveRegister MACRO + MOVE.L D0,-(SP) + LEA _custom,A0 + MOVE.W \1r(A0),D0 + OR.W #$8000,D0 + MOVE.W D0,Old\1 + MOVE.L (SP)+,D0 + ENDM + +RestoreRegister MACRO + MOVE.W #$7FFF,\1(A0) + MOVE.W Old\1,\1(A0) + ENDM + + STRUCTURE ScreenSetup,0 + UWORD ScreenSetup_width + UWORD ScreenSetup_height + UWORD ScreenSetup_bitplanes + ULONG ScreenSetup_memoryStart + LABEL ScreenSetup_SIZEOF + +BPLCON0_COLOR EQU $200 + +_TakeOverSystem: + MOVE.L A6,-(SP) + OpenLibrary #GraphicsLibrary,#0 + MOVE.L D0,GraphicsBase + MOVE.L D0,A6 + + MOVE.L gb_ActiView(A6),OldView + MOVE.L gb_copinit(A6),OldCopper + + LEA _custom,A0 + + PreserveRegister dmacon + PreserveRegister intena + PreserveRegister intreq + PreserveRegister adkcon + + ; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0036.html + MOVE.W #$C000,intena(A0) ; enable master interrupt + MOVE.W #$3FFF,intena(A0) ; disable every other interrupt + + MOVE.W #DMAF_SETCLR|DMAF_COPPER|DMAF_RASTER|DMAF_BLITTER,dmacon(A0) + MOVE.W #DMAF_AUDIO|DMAF_DISK|DMAF_SPRITE,dmacon(A0) + + MOVE.L #0,A1 + CALLLIB _LVOLoadView + CALLLIB _LVOWaitTOF + CALLLIB _LVOWaitTOF + CALLLIB _LVOOwnBlitter + CALLLIB _LVOWaitBlit + + MOVE.L $4,A6 + CALLLIB _LVOForbid + MOVE.L (SP)+,A6 + RTS + +_GiveBackSystem: + MOVE.L A6,-(SP) + LEA _custom,A0 + + RestoreRegister dmacon + RestoreRegister intena + RestoreRegister intreq + RestoreRegister adkcon + + MOVE.L OldCopper,cop1lc(A0) + MOVE.L GraphicsBase,A6 + MOVE.L OldView,A1 + CALLLIB _LVOLoadView + CALLLIB _LVOWaitTOF + CALLLIB _LVOWaitTOF + CALLLIB _LVOWaitBlit + CALLLIB _LVODisownBlitter + + MOVE.L $4,A6 + CALLLIB _LVOPermit + MOVE.L (SP)+,A6 + RTS + +; @stack *copperlist Pointer to copperlist +_InitializeCopperlist: + MOVE.L 4(A7),A0 + MOVE.L #$FFFFFFFE,(A0) + + RTS + +; @stack *copperlist Pointer to copperlist +; @stack ScreenSetup Pointer to screensetup struct +_AddDisplayToCopperlist: + MOVE.L 4(A7),A0 ; copperlist + MOVE.L 8(A7),A1 ; struct + + ; A2,D2,D3 + MOVEM.L A2/D2/D3,-(SP) + MOVE.W ScreenSetup_bitplanes(A1),D0 + MOVE.L ScreenSetup_memoryStart(A1),A2 + + ; get bitplane offset + MOVEQ #0,D2 + MOVE.W ScreenSetup_width(A1),D2 + ROR.W #3,D2 + MULU ScreenSetup_height(A1),D2 + + SUBQ #1,D0 +.continue: + ; set up bplpt + MOVEQ #0,D1 + MOVE.L D0,D1 + ROL.L #2,D1 + ADD.W #bplpt,D1 + + ; set up bitplane pointer + MOVE.L D0,D3 + MULU D2,D3 + ADD.L A2,D3 + + ; low + SWAP D3 + MOVE.W D1,(A0)+ + MOVE.W D3,(A0)+ + ; high + SWAP D3 + ADDQ #2,D1 + MOVE.W D1,(A0)+ + MOVE.W D3,(A0)+ + DBRA D0,.continue + MOVE.L A0,D0 + MOVEM.L (SP)+,A2/D2/D3 + + RTS + +; @stack *copperlist +; @stack *colors +; @stach count +_AddColorsToCopperlist: + MOVE.L 4(A7),A0 ; copperlist + MOVE.L 8(A7),A1 ; colors + MOVE.L 12(A7),D0 ; count + + MOVEM.L A2/D2,-(SP) + LEA _custom,A2 + MOVE.L #color,D2 + ADD.L D2,A2 + + SUBQ #1,D0 +.continue: + MOVE.W (A1)+,(A2)+ + DBRA D0,.continue + MOVE.L A2,D0 + MOVEM.L (SP)+,A2/D2 + + RTS + +; @stack *copperlist +_EndCopperlist: + MOVE.L 4(A7),A0 + + MOVE.W #$ffff,(A0)+ + MOVE.W #$fffe,(A0)+ + MOVE.L A0,D0 + + RTS + +; @stack *ScreenSetup +_SetUpDisplay: + MOVE.L 4(A7),A0 + + LEA _custom,A1 + + MOVEQ #0,D0 + MOVE.W #BPLCON0_COLOR,D0 + MOVEQ #0,D1 + MOVE.W ScreenSetup_bitplanes(A0),D1 + AND.W #$7,D1 + ROL.W #8,D1 + ROL.W #4,D1 + ADD.W D1,D0 + MOVE.W D0,bplcon0(A1) + + MOVE.W #0,bplcon1(A1) + MOVE.W #0,bpl1mod(A1) + MOVE.W #$2c21,diwstrt(A1) + MOVE.W #$2cc1,diwstop(A1) + MOVE.W #$0038,ddfstrt(A1) + MOVE.W #$00d0,ddfstop(A1) + + RTS + + CNOP 0,4 +OldView dc.l 0 +OldCopper dc.l 0 +GraphicsBase dc.l 0 + +Olddmacon dc.w 0 +Oldintena dc.w 0 +Oldintreq dc.w 0 +Oldadkcon dc.w 0 + + CNOP 0,4 +GraphicsLibrary GRAPHICSNAME diff --git a/main b/main new file mode 100755 index 0000000..a617893 Binary files /dev/null and b/main differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..aedf711 --- /dev/null +++ b/main.c @@ -0,0 +1,291 @@ +#include + +#include +#include +#include + +#include +#include + +extern struct Custom far custom; + +struct ScreenSetup { + short int width; + short int height; + short int bitplanes; + unsigned char *memoryStart; +}; + +typedef UWORD color_t; + +extern void TakeOverSystem(void); +extern void GiveBackSystem(void); +extern void InitializeCopperlist(void *); +extern void SetUpDisplay(struct ScreenSetup *); +extern UWORD* AddDisplayToCopperlist(UWORD *copperlist, struct ScreenSetup *); +extern UWORD* AddColorsToCopperlist(UWORD *copperlist, color_t[], int count); +extern UWORD* EndCopperlist(UWORD *copperlist); + +#define SCREEN_WIDTH (320) +#define SCREEN_HEIGHT (256) + +#define TOTAL_SCREEN_SETUP_SIZE(s) ((s->width / 8) * s->height * s->bitplanes) + +void AllocateScreenMemory(struct ScreenSetup *screenSetup) { + char *memory = (char *)AllocMem( + TOTAL_SCREEN_SETUP_SIZE(screenSetup), + MEMF_CLEAR | MEMF_CHIP + ); + + screenSetup->memoryStart = memory; +} + +void FreeScreenMemory(struct ScreenSetup *screenSetup) { + FreeMem( + screenSetup->memoryStart, + TOTAL_SCREEN_SETUP_SIZE(screenSetup) + ); +} + +#define COPPERLIST_SIZE (10000) + +UWORD * PrepareNewCopperlist(void) { + UWORD *copperlist = AllocMem( + COPPERLIST_SIZE, + MEMF_CHIP | MEMF_CLEAR + ); + + InitializeCopperlist(copperlist); + + return copperlist; +} + +void SetCopperlist(UWORD *copperlist) { + custom.cop1lc = (ULONG)copperlist; +} + +void FreeCopperlist(UWORD *copperlist) { + FreeMem(copperlist, COPPERLIST_SIZE); +} + +void WriteSomethingToScreen(struct ScreenSetup *screenSetup) { + *(screenSetup->memoryStart) = 255; + *(screenSetup->memoryStart + 8) = 0xAA; + *(screenSetup->memoryStart + 16) = 0xF0; + *(screenSetup->memoryStart + SCREEN_WIDTH * SCREEN_HEIGHT / 8 + 4) = 255; +} + +void BlitFirstPlaneFirstRowToSecondRow(struct ScreenSetup *screenSetup) { + unsigned char *source = screenSetup->memoryStart; + unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 2 / 8); + + // copy a to d + // $09F0 + custom.bltcon0 = 0x09f0; + custom.bltcon1 = 0; + custom.bltapt = source; + custom.bltdpt = target; + custom.bltamod = 0; + custom.bltdmod = 0; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltsize = 0x0041; +} + +void BlitShiftFirstPlaneFirstRowToThirdRow(struct ScreenSetup *screenSetup) { + unsigned char *source = screenSetup->memoryStart; + unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 4 / 8); + + custom.bltcon0 = 0x49f0; + custom.bltcon1 = 0; + custom.bltapt = source; + custom.bltdpt = target; + custom.bltamod = 0; + custom.bltdmod = 0; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltsize = 0x0041; +} + +void BlitWithMaskInBChannel(struct ScreenSetup *screenSetup) { + unsigned char *source = screenSetup->memoryStart; + unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 6 / 8); + unsigned char *mask = (screenSetup->memoryStart + 8); + + // a is source + // b is mask + // d is destination + + // so I want AB + + custom.bltcon0 = 0x0dc0; + custom.bltcon1 = 0; + custom.bltapt = mask; + custom.bltbpt = source; + custom.bltdpt = target; + custom.bltamod = 0; + custom.bltdmod = 0; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltsize = 0x0041; +} + +void BlitWithMaskInBDataInCChannel(struct ScreenSetup *screenSetup) { + unsigned char *source = screenSetup->memoryStart; + unsigned char *target = (screenSetup->memoryStart + SCREEN_WIDTH * 8 / 8); + unsigned char *mask = (screenSetup->memoryStart + 8); + unsigned char *background = (screenSetup->memoryStart + 16); + + // a is source + // b is mask + // c is background + // d is destination + + // so I want AB+`AC + + custom.bltcon0 = 0x0fca; + custom.bltcon1 = 0; + custom.bltapt = mask; + custom.bltbpt = source; + custom.bltcpt = background; + custom.bltdpt = target; + custom.bltamod = 0; + custom.bltbmod = 0; + custom.bltcmod = SCREEN_WIDTH / 8; + custom.bltdmod = SCREEN_WIDTH / 8; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltsize = 0x0041; +} + +void BlitDrawHorizontalLine(struct ScreenSetup *screenSetup) { + + // i want to draw a line from 20,20 to 50,80 + // i need to get dx and dy + // dx is 30, dy is 60 + // the shift value is 20 mod 15 = 5 + // a data register gets $8000 + // b data register gets $ffff + // text shift is 0 + // c and d pointers get the word containing the first pixel, so + // screenSetup->memoryStart + 320 * 20 / 8 + 2 + // module registers get width of bitplane in bytes + // blit height is dx + 1 so 31 + // blit width = 2 + // logic is ab+'a, so 6, 7, 2, 3, 1, 0 + + char *target = screenSetup->memoryStart + (320 * 20 + 20) / 8; + int dx = 10; + int dy = 60; + int tmp; + + if (dx < dy) { + tmp = dx; + dx = dy; + dy = tmp; + } + + custom.bltcon0 = (5 << 12) + (11 << 8) + 0xca; + custom.bltcon1 = 1; + custom.bltapt = 4 * dy - 2 * dx; + custom.bltadat = 0x8000; + custom.bltbdat = 0xffff; + custom.bltcpt = target; + custom.bltdpt = target; + custom.bltamod = 4 * (dy - dx); + custom.bltbmod = 4 * dy; + custom.bltcmod = 320 / 8; + custom.bltdmod = 320 / 8; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltsize = 0x02 + (dx + 1 << 7); +} + +void BlitClearScreen(struct ScreenSetup *screenSetup, int color) { + unsigned char *target = screenSetup->memoryStart; + int i; + + // a is source + // b is mask + // c is background + // d is destination + + // so I want AB+`AC + + for (i = 0; i < screenSetup->bitplanes; ++i) { + custom.bltcon0 = (0x01 << 8) + 0xf0; + custom.bltcon1 = 0; + custom.bltadat = color & 1 == 1 ? 0xffff : 0; + custom.bltdpt = target + (320 * 256 / 8) * i; + custom.bltamod = 0; + custom.bltdmod = 0; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltsize = (256 << 7) + (320 / 8); + + color >>= 1; + WaitBlit(); + } +} + +int main(void) { + struct ScreenSetup screenSetup = { SCREEN_WIDTH, SCREEN_HEIGHT, 4, 0 }; + struct ScreenSetup *s = &screenSetup; + UWORD *copperlist, *currentCopperlist; + int i, result; + color_t colors[16]; + + colors[0] = 0x0200; + colors[1] = 0x0f00; + colors[2] = 0x0f0f; + colors[3] = 0x000f; + + SetUpDisplay(&screenSetup); + + AllocateScreenMemory(&screenSetup); + WriteSomethingToScreen(&screenSetup); + + // blitter copy the first bitplane row down to the second + + copperlist = PrepareNewCopperlist(); + + TakeOverSystem(); + + /* + BlitFirstPlaneFirstRowToSecondRow(&screenSetup); + WaitBlit(); + BlitShiftFirstPlaneFirstRowToThirdRow(&screenSetup); + WaitBlit(); + BlitWithMaskInBChannel(&screenSetup); + WaitBlit(); + BlitWithMaskInBDataInCChannel(&screenSetup); + WaitBlit(); + BlitDrawHorizontalLine(&screenSetup); + WaitBlit(); + */ + + BlitClearScreen(&screenSetup, 2); + WaitBlit(); + + SetCopperlist(copperlist); + + SetUpDisplay(&screenSetup); + + currentCopperlist = AddDisplayToCopperlist(copperlist, &screenSetup); + currentCopperlist = AddColorsToCopperlist(currentCopperlist, colors, 16); + EndCopperlist(currentCopperlist); + + for (i = 0; i < 100; ++i) { + WaitTOF(); + } + + GiveBackSystem(); + + FreeScreenMemory(&screenSetup); + + FreeCopperlist(copperlist); + + printf("Hello from C\n"); + + return 0; +} diff --git a/smakefile b/smakefile new file mode 100644 index 0000000..d03ec97 --- /dev/null +++ b/smakefile @@ -0,0 +1,10 @@ +all: main + +.c.o: + sc $@ $*.c + +.s.o: + genam -l $*.s + +main: main.o blitter.o + sc link to main main.o blitter.o