amiga_cyberspace

view 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 source
1 #include <stdio.h>
2 #include <exec/memory.h>
3 #include <exec/libraries.h>
4 #include <graphics/gfxbase.h>
5 #include "copper.h"
6 #include "hwregs.h"
8 uint32_t *copperlist;
9 static uint32_t *copperlist_end;
10 static uint32_t *copmem, *curlist;
11 static void *savedlist, *savedview;
12 static int mode, copmem_size;
14 struct GfxBase *GfxBase;
16 int init_copper(int maxlist, int nlists)
17 {
18 /* save copper list (TODO) */
19 if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) {
20 savedlist = GfxBase->copinit;
21 savedview = GfxBase->ActiView;
22 LoadView(0);
23 WaitTOF();
24 WaitTOF();
26 CloseLibrary(GfxBase);
27 GfxBase = 0;
28 }
30 /* allocate and set new copper lists */
31 if(maxlist <= 0) maxlist = 256;
32 mode = nlists >= COPPER_DOUBLE ? COPPER_DOUBLE : COPPER_SINGLE;
34 copmem_size = maxlist * 4 * mode;
35 if(!(copmem = (uint32_t*)AllocMem(copmem_size, MEMF_CHIP))) {
36 printf("failed to allocate chip memory for %d copper lists of %d instructions\n",
37 mode, maxlist);
38 return -1;
39 }
41 curlist = copperlist = copmem;
42 *curlist = COPPER_END;
44 if(mode == COPPER_DOUBLE) {
45 copperlist = curlist + maxlist;
46 *copperlist = COPPER_END;
47 }
48 copperlist_end= copperlist;
50 REG32_COP1LC = (uint32_t)curlist;
51 REG_COPJMP1 = 0; /* causes copper to read COP1LC */
52 return 0;
53 }
55 void cleanup_copper(void)
56 {
57 /* restore copper list */
58 REG32_COP1LC = (uint32_t)savedlist;
60 if((GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0))) {
61 GfxBase->copinit = savedlist;
62 LoadView(savedview);
63 WaitTOF();
64 WaitTOF();
65 CloseLibrary(GfxBase);
66 GfxBase = 0;
67 }
69 if(copmem) {
70 FreeMem(copmem, copmem_size);
71 }
72 }
74 void enable_copper(void)
75 {
76 REG_DMACON = SETBITS(DMA_COPPER);
77 }
79 void disable_copper(void)
80 {
81 REG_DMACON = CLRBITS(DMA_COPPER);
82 }
84 void clear_copper(void)
85 {
86 copperlist_end = copperlist;
87 *copperlist_end = COPPER_END;
88 }
90 void add_copper(uint32_t cmd)
91 {
92 *copperlist_end++ = cmd;
93 }
95 void sort_copper(void)
96 {
97 /* TODO */
98 }
100 void swap_copper(void)
101 {
102 if(mode == COPPER_DOUBLE) {
103 uint32_t *tmpptr;
104 tmpptr = curlist;
105 curlist = copperlist;
106 copperlist = copperlist_end = tmpptr;
108 REG32_COP1LC = (uint32_t)curlist;
109 REG_COPJMP1 = 0;
110 } else {
111 copperlist_end = curlist;
112 }
113 *copperlist_end = COPPER_END;
114 }