161 lines
4.1 KiB
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();
|
|
}
|