it works
This commit is contained in:
commit
026b6f6f0d
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
.vamosrc
|
||||
activate
|
||||
*.o
|
||||
*.lnk
|
||||
*.uaem
|
||||
.ccls-cache/
|
240
blitter.s
Normal file
240
blitter.s
Normal file
@ -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
|
291
main.c
Normal file
291
main.c
Normal file
@ -0,0 +1,291 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <clib/exec_protos.h>
|
||||
#include <clib/graphics_protos.h>
|
||||
#include <exec/exec.h>
|
||||
|
||||
#include <hardware/custom.h>
|
||||
#include <hardware/dmabits.h>
|
||||
|
||||
extern struct Custom far custom;
|
||||
|
||||
struct ScreenSetup {
|
||||
short int width;
|
||||
short int height;
|
||||
short int bitplanes;
|
||||
unsigned char *memoryStart;
|
||||
};
|
||||
|
||||
typedef UWORD color_t;
|
||||
|
||||
extern void TakeOverSystem(void);
|
||||
extern void GiveBackSystem(void);
|
||||
extern void InitializeCopperlist(void *);
|
||||
extern void SetUpDisplay(struct ScreenSetup *);
|
||||
extern UWORD* AddDisplayToCopperlist(UWORD *copperlist, struct ScreenSetup *);
|
||||
extern UWORD* AddColorsToCopperlist(UWORD *copperlist, color_t[], int count);
|
||||
extern UWORD* EndCopperlist(UWORD *copperlist);
|
||||
|
||||
#define SCREEN_WIDTH (320)
|
||||
#define SCREEN_HEIGHT (256)
|
||||
|
||||
#define TOTAL_SCREEN_SETUP_SIZE(s) ((s->width / 8) * s->height * s->bitplanes)
|
||||
|
||||
void AllocateScreenMemory(struct ScreenSetup *screenSetup) {
|
||||
char *memory = (char *)AllocMem(
|
||||
TOTAL_SCREEN_SETUP_SIZE(screenSetup),
|
||||
MEMF_CLEAR | MEMF_CHIP
|
||||
);
|
||||
|
||||
screenSetup->memoryStart = memory;
|
||||
}
|
||||
|
||||
void FreeScreenMemory(struct ScreenSetup *screenSetup) {
|
||||
FreeMem(
|
||||
screenSetup->memoryStart,
|
||||
TOTAL_SCREEN_SETUP_SIZE(screenSetup)
|
||||
);
|
||||
}
|
||||
|
||||
#define COPPERLIST_SIZE (10000)
|
||||
|
||||
UWORD * PrepareNewCopperlist(void) {
|
||||
UWORD *copperlist = AllocMem(
|
||||
COPPERLIST_SIZE,
|
||||
MEMF_CHIP | MEMF_CLEAR
|
||||
);
|
||||
|
||||
InitializeCopperlist(copperlist);
|
||||
|
||||
return copperlist;
|
||||
}
|
||||
|
||||
void SetCopperlist(UWORD *copperlist) {
|
||||
custom.cop1lc = (ULONG)copperlist;
|
||||
}
|
||||
|
||||
void FreeCopperlist(UWORD *copperlist) {
|
||||
FreeMem(copperlist, COPPERLIST_SIZE);
|
||||
}
|
||||
|
||||
void WriteSomethingToScreen(struct ScreenSetup *screenSetup) {
|
||||
*(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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user