292 lines
7.0 KiB
C
292 lines
7.0 KiB
C
|
#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;
|
||
|
}
|