amiga-agnus-copperbars/chunky vertical.c

161 lines
4.1 KiB
C

/**
* Chunky vertical copperbars demo
* Copyright 2023 John Bintz
* Licensed under the MIT License
* https://theindustriousrabbit.com
*/
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <graphics/GfxBase.h>
#include <exec/memory.h>
#include <hardware/cia.h>
#include <hardware/dmabits.h>
#include <stdio.h>
extern struct GfxBase *GfxBase;
extern struct Custom far custom;
extern struct CIA far ciaa, ciab;
// this is faster than
// custom.vhposr + (custom.vposr << 16)
static volatile ULONG *custom_vposr = (volatile ULONG *)0xdff004;
#define offsetof(s, m) &((struct s *)0)->m
#define BITPLANE_SIZE (320/8)*256
#define BPLCON0_COLOR (0x200)
#define BPLCON0_BPU_1 (0x1000)
static UWORD colors[] = {0xf00,0x0f0,0xff0,0x0ff};
int main(void) {
struct View *OldView = ((struct GfxBase *)GfxBase)->ActiView;
ULONG OldCopper = (ULONG)((struct GfxBase *)GfxBase)->copinit;
ULONG OldDMACON, OldINTENA, OldINTREQ, OldADKCON;
int currentY, colorBar, xPos;
void *copperlist;
UWORD *copperlist_ptr;
APTR *bitplane;
// how much can we avoid hard coding into our code?
UWORD custom_bplpt = (UWORD)offsetof(Custom, bplpt);
UWORD custom_color = (UWORD)offsetof(Custom, color);
LoadView(NULL);
WaitTOF();
WaitTOF();
OwnBlitter();
WaitBlit();
Forbid();
OldDMACON = custom.dmaconr | 0x8000;
OldINTENA = custom.intenar | 0x8000;
OldINTREQ = custom.intreqr | 0x8000;
OldADKCON = custom.adkconr | 0x8000;
// disable interrupts
custom.intena = 0xc000;
custom.intena = 0x3fff;
// set up dma
custom.dmacon = DMAF_SETCLR | DMAF_COPPER | DMAF_RASTER;
custom.dmacon = DMAF_AUDIO | DMAF_DISK | DMAF_SPRITE | DMAF_BLITTER;
// 4 bars = WAIT + MOVE (8 bytes) 8 times * 312 + ~100 for setup = 21000 should do it
copperlist = AllocMem(21000, MEMF_CHIP | MEMF_CLEAR);
bitplane = (APTR *)AllocMem(BITPLANE_SIZE, MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
// default copperlist has just STOP
((ULONG *)copperlist)[0] = 0xfffffffe;
// set up 1 bitplane pal display
custom.bplcon0 = BPLCON0_COLOR | BPLCON0_BPU_1;
custom.bplcon1 = 0;
custom.bpl1mod = 0;
custom.diwstrt = 0x2c21;
custom.diwstop = 0x2cc1;
custom.ddfstrt = 0x0038;
custom.ddfstop = 0x00d0;
// substitute our minimal copperlist now
custom.cop1lc = (ULONG)copperlist;
// neither HID button 0 is down
while ((ciaa.ciapra >> 6) == 3) {
// rebuild copperlist
copperlist_ptr = (UWORD *)copperlist;
// bpl1pth
*(copperlist_ptr++) = custom_bplpt;
*(copperlist_ptr++) = ((ULONG)bitplane >> 16) & 0xffff;
// bpl1ptl
*(copperlist_ptr++) = custom_bplpt + 2;
*(copperlist_ptr++) = (ULONG)bitplane & 0xffff;
*(copperlist_ptr++) = custom_color;
*(copperlist_ptr++) = 0x0f00;
for (currentY = 0; currentY < 312; currentY++) {
for (colorBar = 0; colorBar < 4; colorBar++) {
xPos = 0x68 + (colorBar * 24);
*(copperlist_ptr++) = ((currentY & 0xff) << 8) | xPos | 0x1;
*(copperlist_ptr++) = 0xfffe;
*(copperlist_ptr++) = custom_color;
*(copperlist_ptr++) = colors[colorBar];
*(copperlist_ptr++) = ((currentY & 0xff) << 8) | xPos + 2 | 0x1;
*(copperlist_ptr++) = 0xfffe;
*(copperlist_ptr++) = custom_color;
*(copperlist_ptr++) = 0x000;
}
// PAL workaround
if (currentY == 255) {
*(copperlist_ptr++) = 0xffdf;
*(copperlist_ptr++) = 0xfffe;
}
}
// end the copperlist
*(copperlist_ptr++) = 0xffff;
*(copperlist_ptr++) = 0xfffe;
// vbl wait
// this will not work on NTSC!
while ((*custom_vposr & 0x1FF00) != (300 << 8)) {}
}
FreeMem(bitplane, BITPLANE_SIZE);
FreeMem(copperlist, 21000);
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();
}