# HG changeset patch # User John Tsiombikas # Date 1501047920 -10800 # Node ID b5d609c7161d7790e5ecbfb621e75288d3f98385 # Parent e6fd570536278c4bfdc7d3c0b4f370259d86f08d copper diff -r e6fd57053627 -r b5d609c7161d Makefile --- a/Makefile Tue Jul 25 08:17:34 2017 +0300 +++ b/Makefile Wed Jul 26 08:45:20 2017 +0300 @@ -18,4 +18,5 @@ .PHONY: clean clean: - rm -f $(obj) $(bin) data/backdrop2.img + rm -f $(obj) $(bin) +#data/backdrop2.img diff -r e6fd57053627 -r b5d609c7161d src/copper.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/copper.c Wed Jul 26 08:45:20 2017 +0300 @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include "copper.h" +#include "hwregs.h" + +uint32_t *copperlist; +static uint32_t *copperlist_end; +static uint32_t *copmem, *curlist; +static void *savedlist, *savedview; +static int mode, copmem_size; + +struct GfxBase *GfxBase; + +int init_copper(int maxlist, int nlists) +{ + /* save copper list (TODO) */ + if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) { + savedlist = GfxBase->copinit; + savedview = GfxBase->ActiView; + LoadView(0); + WaitTOF(); + WaitTOF(); + + CloseLibrary(GfxBase); + GfxBase = 0; + } + + /* allocate and set new copper lists */ + if(maxlist <= 0) maxlist = 256; + mode = nlists >= COPPER_DOUBLE ? COPPER_DOUBLE : COPPER_SINGLE; + + copmem_size = maxlist * 4 * mode; + if(!(copmem = (uint32_t*)AllocMem(copmem_size, MEMF_CHIP))) { + printf("failed to allocate chip memory for %d copper lists of %d instructions\n", + mode, maxlist); + return -1; + } + + curlist = copperlist = copmem; + *curlist = COPPER_END; + + if(mode == COPPER_DOUBLE) { + copperlist = curlist + maxlist; + *copperlist = COPPER_END; + } + copperlist_end= copperlist; + + REG32_COP1LC = (uint32_t)curlist; + REG_COPJMP1 = 0; /* causes copper to read COP1LC */ + return 0; +} + +void cleanup_copper(void) +{ + /* restore copper list */ + REG32_COP1LC = (uint32_t)savedlist; + + if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) { + GfxBase->copinit = savedlist; + LoadView(savedview); + WaitTOF(); + WaitTOF(); + CloseLibrary(GfxBase); + GfxBase = 0; + } + + if(copmem) { + FreeMem(copmem, copmem_size); + } +} + +void enable_copper(void) +{ + REG_DMACON = SETBITS(DMA_COPPER); +} + +void disable_copper(void) +{ + REG_DMACON = CLRBITS(DMA_COPPER); +} + +void clear_copper(void) +{ + copperlist_end = copperlist; + *copperlist_end = COPPER_END; +} + +void add_copper(uint32_t cmd) +{ + *copperlist_end++ = cmd; +} + +void sort_copper(void) +{ + /* TODO */ +} + +void swap_copper(void) +{ + if(mode == COPPER_DOUBLE) { + uint32_t *tmpptr; + tmpptr = curlist; + curlist = copperlist; + copperlist = copperlist_end = tmpptr; + + REG32_COP1LC = (uint32_t)curlist; + REG_COPJMP1 = 0; + } else { + copperlist_end = curlist; + } + *copperlist_end = COPPER_END; +} diff -r e6fd57053627 -r b5d609c7161d src/copper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/copper.h Wed Jul 26 08:45:20 2017 +0300 @@ -0,0 +1,38 @@ +#ifndef COPPER_H_ +#define COPPER_H_ + +#include "inttypes.h" + +#define COPPER_MOVE(reg, data) (((uint32_t)(reg) << 16) | (data)) +#define COPPER_WAIT(x, y) \ + (0x0001fffe | ((uint32_t)((x) + 0x81) << 16) | ((uint32_t)((y) + 0x2c) << 24)) +#define COPPER_WAIT_OVERSCAN(x, y) \ + (0x0001fffe | ((uint32_t)(x) << 16) | ((uint32_t)(y) << 24)) +#define COPPER_VWAIT(s) (0x0001ff00 | ((uint32_t)((s) + 0x2c) << 24)) +#define COPPER_VWAIT_OVERSCAN(s) \ + (0x0001ff00 | ((uint32_t)(s) << 24)) +#define COPPER_END 0xfffffffe + +extern uint32_t *copperlist; + +enum { + COPPER_SINGLE = 1, + COPPER_DOUBLE = 2 +}; + +int init_copper(int maxlist, int nlists); +void cleanup_copper(void); + +/* enables copper DMA */ +void enable_copper(void); +/* disables copper DMA */ +void disable_copper(void); + +void clear_copper(void); +void add_copper(uint32_t cmd); +void sort_copper(void); /* TODO */ + +void swap_copper(void); + + +#endif /* COPPER_H_ */ diff -r e6fd57053627 -r b5d609c7161d src/hwregs.h --- a/src/hwregs.h Tue Jul 25 08:17:34 2017 +0300 +++ b/src/hwregs.h Wed Jul 26 08:45:20 2017 +0300 @@ -254,6 +254,13 @@ #define REGN_HCENTER 0x1e2 #define REGN_DIWHIGH 0x1e4 +#define REGN_COP1LCH 0x080 +#define REGN_COP1LCL 0x082 +#define REGN_COP2LCH 0x084 +#define REGN_COP2LCL 0x086 +#define REGN_COPJMP1 0x088 +#define REGN_COPJMP2 0x08a + #define REG(r) (*(volatile uint16_t*)(REG_BASE_ADDR | (r))) #define REG_CIAA_PORTA *(volatile uint8_t*)0xbfe001 @@ -327,6 +334,11 @@ #define REG_COLOR30 REG(REGN_COLOR30) #define REG_COLOR31 REG(REGN_COLOR31) +#define REG32_COP1LC *(volatile uint32_t*)(REG_BASE_ADDR | REGN_COP1LCH) +#define REG32_COP2LC *(volatile uint32_t*)(REG_BASE_ADDR | REGN_COP2LCH) +#define REG_COPJMP1 REG(REGN_COPJMP1) +#define REG_COPJMP2 REG(REGN_COPJMP2) + /* ------ bits ------- */ #define SETBITS(x) ((x) | 0x8000) #define CLRBITS(x) (x) diff -r e6fd57053627 -r b5d609c7161d src/main.c --- a/src/main.c Tue Jul 25 08:17:34 2017 +0300 +++ b/src/main.c Wed Jul 26 08:45:20 2017 +0300 @@ -2,6 +2,7 @@ #include #include #include "inttypes.h" +#include "copper.h" #include "mouse.h" #include "hwregs.h" @@ -46,6 +47,11 @@ Forbid(); + /* initialize copper */ + if(init_copper(0, 0) == -1) { + return -1; + } + prev_dmacon = REG_DMACONR; REG_DMACON = CLRBITS(DMA_ALL); @@ -71,8 +77,13 @@ wait_vblank(); REG32_BPL1PT = (uint32_t)&backdrop; - REG_DMACON = SETBITS(DMA_BPL | DMA_MASTER); + add_copper(COPPER_VWAIT(40)); + add_copper(COPPER_MOVE(REGN_COLOR1, 0xf80)); + add_copper(COPPER_VWAIT(45)); + add_copper(COPPER_MOVE(REGN_COLOR1, 0xfff)); + add_copper(COPPER_END); + REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER); return 0; } @@ -90,6 +101,7 @@ REG_INTENA = CLRBITS(INTEN_ALL); REG_INTENA = SETBITS(prev_intena); + cleanup_copper(); Permit(); }