amiga_cyberspace
changeset 1:b5d609c7161d
copper
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 26 Jul 2017 08:45:20 +0300 |
parents | e6fd57053627 |
children | b98fa9b135ea |
files | Makefile src/copper.c src/copper.h src/hwregs.h src/main.c |
diffstat | 5 files changed, 179 insertions(+), 2 deletions(-) [+] |
line diff
1.1 --- a/Makefile Tue Jul 25 08:17:34 2017 +0300 1.2 +++ b/Makefile Wed Jul 26 08:45:20 2017 +0300 1.3 @@ -18,4 +18,5 @@ 1.4 1.5 .PHONY: clean 1.6 clean: 1.7 - rm -f $(obj) $(bin) data/backdrop2.img 1.8 + rm -f $(obj) $(bin) 1.9 +#data/backdrop2.img
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/copper.c Wed Jul 26 08:45:20 2017 +0300 2.3 @@ -0,0 +1,114 @@ 2.4 +#include <stdio.h> 2.5 +#include <exec/memory.h> 2.6 +#include <exec/libraries.h> 2.7 +#include <graphics/gfxbase.h> 2.8 +#include "copper.h" 2.9 +#include "hwregs.h" 2.10 + 2.11 +uint32_t *copperlist; 2.12 +static uint32_t *copperlist_end; 2.13 +static uint32_t *copmem, *curlist; 2.14 +static void *savedlist, *savedview; 2.15 +static int mode, copmem_size; 2.16 + 2.17 +struct GfxBase *GfxBase; 2.18 + 2.19 +int init_copper(int maxlist, int nlists) 2.20 +{ 2.21 + /* save copper list (TODO) */ 2.22 + if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) { 2.23 + savedlist = GfxBase->copinit; 2.24 + savedview = GfxBase->ActiView; 2.25 + LoadView(0); 2.26 + WaitTOF(); 2.27 + WaitTOF(); 2.28 + 2.29 + CloseLibrary(GfxBase); 2.30 + GfxBase = 0; 2.31 + } 2.32 + 2.33 + /* allocate and set new copper lists */ 2.34 + if(maxlist <= 0) maxlist = 256; 2.35 + mode = nlists >= COPPER_DOUBLE ? COPPER_DOUBLE : COPPER_SINGLE; 2.36 + 2.37 + copmem_size = maxlist * 4 * mode; 2.38 + if(!(copmem = (uint32_t*)AllocMem(copmem_size, MEMF_CHIP))) { 2.39 + printf("failed to allocate chip memory for %d copper lists of %d instructions\n", 2.40 + mode, maxlist); 2.41 + return -1; 2.42 + } 2.43 + 2.44 + curlist = copperlist = copmem; 2.45 + *curlist = COPPER_END; 2.46 + 2.47 + if(mode == COPPER_DOUBLE) { 2.48 + copperlist = curlist + maxlist; 2.49 + *copperlist = COPPER_END; 2.50 + } 2.51 + copperlist_end= copperlist; 2.52 + 2.53 + REG32_COP1LC = (uint32_t)curlist; 2.54 + REG_COPJMP1 = 0; /* causes copper to read COP1LC */ 2.55 + return 0; 2.56 +} 2.57 + 2.58 +void cleanup_copper(void) 2.59 +{ 2.60 + /* restore copper list */ 2.61 + REG32_COP1LC = (uint32_t)savedlist; 2.62 + 2.63 + if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) { 2.64 + GfxBase->copinit = savedlist; 2.65 + LoadView(savedview); 2.66 + WaitTOF(); 2.67 + WaitTOF(); 2.68 + CloseLibrary(GfxBase); 2.69 + GfxBase = 0; 2.70 + } 2.71 + 2.72 + if(copmem) { 2.73 + FreeMem(copmem, copmem_size); 2.74 + } 2.75 +} 2.76 + 2.77 +void enable_copper(void) 2.78 +{ 2.79 + REG_DMACON = SETBITS(DMA_COPPER); 2.80 +} 2.81 + 2.82 +void disable_copper(void) 2.83 +{ 2.84 + REG_DMACON = CLRBITS(DMA_COPPER); 2.85 +} 2.86 + 2.87 +void clear_copper(void) 2.88 +{ 2.89 + copperlist_end = copperlist; 2.90 + *copperlist_end = COPPER_END; 2.91 +} 2.92 + 2.93 +void add_copper(uint32_t cmd) 2.94 +{ 2.95 + *copperlist_end++ = cmd; 2.96 +} 2.97 + 2.98 +void sort_copper(void) 2.99 +{ 2.100 + /* TODO */ 2.101 +} 2.102 + 2.103 +void swap_copper(void) 2.104 +{ 2.105 + if(mode == COPPER_DOUBLE) { 2.106 + uint32_t *tmpptr; 2.107 + tmpptr = curlist; 2.108 + curlist = copperlist; 2.109 + copperlist = copperlist_end = tmpptr; 2.110 + 2.111 + REG32_COP1LC = (uint32_t)curlist; 2.112 + REG_COPJMP1 = 0; 2.113 + } else { 2.114 + copperlist_end = curlist; 2.115 + } 2.116 + *copperlist_end = COPPER_END; 2.117 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/copper.h Wed Jul 26 08:45:20 2017 +0300 3.3 @@ -0,0 +1,38 @@ 3.4 +#ifndef COPPER_H_ 3.5 +#define COPPER_H_ 3.6 + 3.7 +#include "inttypes.h" 3.8 + 3.9 +#define COPPER_MOVE(reg, data) (((uint32_t)(reg) << 16) | (data)) 3.10 +#define COPPER_WAIT(x, y) \ 3.11 + (0x0001fffe | ((uint32_t)((x) + 0x81) << 16) | ((uint32_t)((y) + 0x2c) << 24)) 3.12 +#define COPPER_WAIT_OVERSCAN(x, y) \ 3.13 + (0x0001fffe | ((uint32_t)(x) << 16) | ((uint32_t)(y) << 24)) 3.14 +#define COPPER_VWAIT(s) (0x0001ff00 | ((uint32_t)((s) + 0x2c) << 24)) 3.15 +#define COPPER_VWAIT_OVERSCAN(s) \ 3.16 + (0x0001ff00 | ((uint32_t)(s) << 24)) 3.17 +#define COPPER_END 0xfffffffe 3.18 + 3.19 +extern uint32_t *copperlist; 3.20 + 3.21 +enum { 3.22 + COPPER_SINGLE = 1, 3.23 + COPPER_DOUBLE = 2 3.24 +}; 3.25 + 3.26 +int init_copper(int maxlist, int nlists); 3.27 +void cleanup_copper(void); 3.28 + 3.29 +/* enables copper DMA */ 3.30 +void enable_copper(void); 3.31 +/* disables copper DMA */ 3.32 +void disable_copper(void); 3.33 + 3.34 +void clear_copper(void); 3.35 +void add_copper(uint32_t cmd); 3.36 +void sort_copper(void); /* TODO */ 3.37 + 3.38 +void swap_copper(void); 3.39 + 3.40 + 3.41 +#endif /* COPPER_H_ */
4.1 --- a/src/hwregs.h Tue Jul 25 08:17:34 2017 +0300 4.2 +++ b/src/hwregs.h Wed Jul 26 08:45:20 2017 +0300 4.3 @@ -254,6 +254,13 @@ 4.4 #define REGN_HCENTER 0x1e2 4.5 #define REGN_DIWHIGH 0x1e4 4.6 4.7 +#define REGN_COP1LCH 0x080 4.8 +#define REGN_COP1LCL 0x082 4.9 +#define REGN_COP2LCH 0x084 4.10 +#define REGN_COP2LCL 0x086 4.11 +#define REGN_COPJMP1 0x088 4.12 +#define REGN_COPJMP2 0x08a 4.13 + 4.14 #define REG(r) (*(volatile uint16_t*)(REG_BASE_ADDR | (r))) 4.15 4.16 #define REG_CIAA_PORTA *(volatile uint8_t*)0xbfe001 4.17 @@ -327,6 +334,11 @@ 4.18 #define REG_COLOR30 REG(REGN_COLOR30) 4.19 #define REG_COLOR31 REG(REGN_COLOR31) 4.20 4.21 +#define REG32_COP1LC *(volatile uint32_t*)(REG_BASE_ADDR | REGN_COP1LCH) 4.22 +#define REG32_COP2LC *(volatile uint32_t*)(REG_BASE_ADDR | REGN_COP2LCH) 4.23 +#define REG_COPJMP1 REG(REGN_COPJMP1) 4.24 +#define REG_COPJMP2 REG(REGN_COPJMP2) 4.25 + 4.26 /* ------ bits ------- */ 4.27 #define SETBITS(x) ((x) | 0x8000) 4.28 #define CLRBITS(x) (x)
5.1 --- a/src/main.c Tue Jul 25 08:17:34 2017 +0300 5.2 +++ b/src/main.c Wed Jul 26 08:45:20 2017 +0300 5.3 @@ -2,6 +2,7 @@ 5.4 #include <proto/exec.h> 5.5 #include <exec/memory.h> 5.6 #include "inttypes.h" 5.7 +#include "copper.h" 5.8 #include "mouse.h" 5.9 #include "hwregs.h" 5.10 5.11 @@ -46,6 +47,11 @@ 5.12 5.13 Forbid(); 5.14 5.15 + /* initialize copper */ 5.16 + if(init_copper(0, 0) == -1) { 5.17 + return -1; 5.18 + } 5.19 + 5.20 prev_dmacon = REG_DMACONR; 5.21 REG_DMACON = CLRBITS(DMA_ALL); 5.22 5.23 @@ -71,8 +77,13 @@ 5.24 wait_vblank(); 5.25 REG32_BPL1PT = (uint32_t)&backdrop; 5.26 5.27 - REG_DMACON = SETBITS(DMA_BPL | DMA_MASTER); 5.28 + add_copper(COPPER_VWAIT(40)); 5.29 + add_copper(COPPER_MOVE(REGN_COLOR1, 0xf80)); 5.30 + add_copper(COPPER_VWAIT(45)); 5.31 + add_copper(COPPER_MOVE(REGN_COLOR1, 0xfff)); 5.32 + add_copper(COPPER_END); 5.33 5.34 + REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER); 5.35 return 0; 5.36 } 5.37 5.38 @@ -90,6 +101,7 @@ 5.39 REG_INTENA = CLRBITS(INTEN_ALL); 5.40 REG_INTENA = SETBITS(prev_intena); 5.41 5.42 + cleanup_copper(); 5.43 Permit(); 5.44 } 5.45