amiga_cyberspace

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