amiga_cyberspace
diff src/copper.c @ 1:b5d609c7161d
copper
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 26 Jul 2017 08:45:20 +0300 |
parents | |
children | b98fa9b135ea |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/copper.c Wed Jul 26 08:45:20 2017 +0300 1.3 @@ -0,0 +1,114 @@ 1.4 +#include <stdio.h> 1.5 +#include <exec/memory.h> 1.6 +#include <exec/libraries.h> 1.7 +#include <graphics/gfxbase.h> 1.8 +#include "copper.h" 1.9 +#include "hwregs.h" 1.10 + 1.11 +uint32_t *copperlist; 1.12 +static uint32_t *copperlist_end; 1.13 +static uint32_t *copmem, *curlist; 1.14 +static void *savedlist, *savedview; 1.15 +static int mode, copmem_size; 1.16 + 1.17 +struct GfxBase *GfxBase; 1.18 + 1.19 +int init_copper(int maxlist, int nlists) 1.20 +{ 1.21 + /* save copper list (TODO) */ 1.22 + if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) { 1.23 + savedlist = GfxBase->copinit; 1.24 + savedview = GfxBase->ActiView; 1.25 + LoadView(0); 1.26 + WaitTOF(); 1.27 + WaitTOF(); 1.28 + 1.29 + CloseLibrary(GfxBase); 1.30 + GfxBase = 0; 1.31 + } 1.32 + 1.33 + /* allocate and set new copper lists */ 1.34 + if(maxlist <= 0) maxlist = 256; 1.35 + mode = nlists >= COPPER_DOUBLE ? COPPER_DOUBLE : COPPER_SINGLE; 1.36 + 1.37 + copmem_size = maxlist * 4 * mode; 1.38 + if(!(copmem = (uint32_t*)AllocMem(copmem_size, MEMF_CHIP))) { 1.39 + printf("failed to allocate chip memory for %d copper lists of %d instructions\n", 1.40 + mode, maxlist); 1.41 + return -1; 1.42 + } 1.43 + 1.44 + curlist = copperlist = copmem; 1.45 + *curlist = COPPER_END; 1.46 + 1.47 + if(mode == COPPER_DOUBLE) { 1.48 + copperlist = curlist + maxlist; 1.49 + *copperlist = COPPER_END; 1.50 + } 1.51 + copperlist_end= copperlist; 1.52 + 1.53 + REG32_COP1LC = (uint32_t)curlist; 1.54 + REG_COPJMP1 = 0; /* causes copper to read COP1LC */ 1.55 + return 0; 1.56 +} 1.57 + 1.58 +void cleanup_copper(void) 1.59 +{ 1.60 + /* restore copper list */ 1.61 + REG32_COP1LC = (uint32_t)savedlist; 1.62 + 1.63 + if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) { 1.64 + GfxBase->copinit = savedlist; 1.65 + LoadView(savedview); 1.66 + WaitTOF(); 1.67 + WaitTOF(); 1.68 + CloseLibrary(GfxBase); 1.69 + GfxBase = 0; 1.70 + } 1.71 + 1.72 + if(copmem) { 1.73 + FreeMem(copmem, copmem_size); 1.74 + } 1.75 +} 1.76 + 1.77 +void enable_copper(void) 1.78 +{ 1.79 + REG_DMACON = SETBITS(DMA_COPPER); 1.80 +} 1.81 + 1.82 +void disable_copper(void) 1.83 +{ 1.84 + REG_DMACON = CLRBITS(DMA_COPPER); 1.85 +} 1.86 + 1.87 +void clear_copper(void) 1.88 +{ 1.89 + copperlist_end = copperlist; 1.90 + *copperlist_end = COPPER_END; 1.91 +} 1.92 + 1.93 +void add_copper(uint32_t cmd) 1.94 +{ 1.95 + *copperlist_end++ = cmd; 1.96 +} 1.97 + 1.98 +void sort_copper(void) 1.99 +{ 1.100 + /* TODO */ 1.101 +} 1.102 + 1.103 +void swap_copper(void) 1.104 +{ 1.105 + if(mode == COPPER_DOUBLE) { 1.106 + uint32_t *tmpptr; 1.107 + tmpptr = curlist; 1.108 + curlist = copperlist; 1.109 + copperlist = copperlist_end = tmpptr; 1.110 + 1.111 + REG32_COP1LC = (uint32_t)curlist; 1.112 + REG_COPJMP1 = 0; 1.113 + } else { 1.114 + copperlist_end = curlist; 1.115 + } 1.116 + *copperlist_end = COPPER_END; 1.117 +}