amiga_imgv
diff src/amiga/gfx.c @ 0:a4788c959918
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 25 Oct 2017 19:34:53 +0300 |
parents | |
children | 663471a80c21 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/amiga/gfx.c Wed Oct 25 19:34:53 2017 +0300 1.3 @@ -0,0 +1,203 @@ 1.4 +#include <stdio.h> 1.5 +#include <proto/exec.h> 1.6 +#include "gfx.h" 1.7 +#include "copper.h" 1.8 +#include "hwregs.h" 1.9 +#include "logger.h" 1.10 + 1.11 +static int scr_width, scr_height; 1.12 +static int fb_width, fb_height; 1.13 +static int num_bitplanes; 1.14 +static uint16_t prev_intena, prev_intreq, prev_adkcon, prev_dmacon; 1.15 + 1.16 +static unsigned char *framebuf; 1.17 +static unsigned long fbsize; 1.18 +static int own_framebuf; 1.19 + 1.20 +int gfx_init(int nbpl, unsigned int flags) 1.21 +{ 1.22 + uint16_t bplcon0; 1.23 + 1.24 + num_bitplanes = nbpl; 1.25 + scr_width = fb_width = (flags & GFX_HIRES) ? 640 : 320; 1.26 + scr_height = fb_height = (flags & GFX_ILACE) ? 512 : 256; 1.27 + 1.28 + Forbid(); 1.29 + 1.30 + prev_dmacon = REG_DMACONR; 1.31 + REG_DMACON = CLRBITS(DMA_ALL); 1.32 + 1.33 + prev_intena = REG_INTENAR; 1.34 + prev_intreq = REG_INTREQR; 1.35 + prev_adkcon = REG_ADKCONR; 1.36 + 1.37 + if(init_copper(0, 0) == -1) { 1.38 + return -1; 1.39 + } 1.40 + 1.41 + if(!gfx_set_framebuffer(0, scr_width, scr_height)) { 1.42 + gfx_shutdown(); 1.43 + return -1; 1.44 + } 1.45 + 1.46 + bplcon0 = BPLCON0_COUNT(nbpl) | BPLCON0_COLOR; 1.47 + if(flags & GFX_HIRES) bplcon0 |= BPLCON0_HIRES; 1.48 + if(flags & GFX_ILACE) bplcon0 |= BPLCON0_LACE; 1.49 + if(flags & GFX_HAM) bplcon0 |= BPLCON0_HOMOD; 1.50 + if(flags & GFX_DBLPF) bplcon0 |= BPLCON0_DBLPF; 1.51 + 1.52 + REG_BPLCON0 = bplcon0; 1.53 + REG_BPLCON1 = 0; /* h-scroll */ 1.54 + REG_DIWSTART = 0x2c81; /* 81h horiz start, 2ch vertical start */ 1.55 + REG_DIWSTOP = 0x2cc1; 1.56 + REG_DDFSTART = (flags & GFX_HIRES) ? 0x3c : 0x38; 1.57 + REG_DDFSTOP = (flags & GFX_HIRES) ? 0xd4 : 0xd0; 1.58 + 1.59 + gfx_wait_vblank(); 1.60 + gfx_begin_copperlist(); 1.61 + add_copper(COPPER_END); 1.62 + 1.63 + REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER); 1.64 + return 0; 1.65 +} 1.66 + 1.67 +void gfx_shutdown(void) 1.68 +{ 1.69 + REG_DMACON = CLRBITS(DMA_ALL); 1.70 + REG_DMACON = SETBITS(prev_dmacon); 1.71 + 1.72 + REG_INTREQ = CLRBITS(0x7fff); 1.73 + REG_INTREQ = SETBITS(prev_intreq); 1.74 + 1.75 + REG_ADKCON = CLRBITS(0x7fff); 1.76 + REG_ADKCON = SETBITS(prev_adkcon); 1.77 + 1.78 + REG_INTENA = CLRBITS(INTEN_ALL); 1.79 + REG_INTENA = SETBITS(prev_intena); 1.80 + 1.81 + if(framebuf && own_framebuf) { 1.82 + FreeMem(framebuf, fbsize); 1.83 + } 1.84 + framebuf = 0; 1.85 + 1.86 + cleanup_copper(); 1.87 + Permit(); 1.88 +} 1.89 + 1.90 +int gfx_screen_width(void) 1.91 +{ 1.92 + return scr_width; 1.93 +} 1.94 + 1.95 +int gfx_screen_height(void) 1.96 +{ 1.97 + return scr_height; 1.98 +} 1.99 + 1.100 +void *gfx_set_framebuffer(void *fb, int width, int height) 1.101 +{ 1.102 + /*unsigned int bpl_scanline_sz = width / 8;*/ 1.103 + unsigned long sz = width * height / 8 * num_bitplanes; 1.104 + uint32_t bpladdr; 1.105 + uint16_t bplmod; 1.106 + 1.107 + if(framebuf && own_framebuf) { 1.108 + FreeMem(framebuf, fbsize); 1.109 + } 1.110 + 1.111 + if(fb) { 1.112 + framebuf = fb; 1.113 + own_framebuf = 0; 1.114 + } else { 1.115 + if(!(framebuf = AllocMem(sz, MEMF_CHIP))) { 1.116 + logmsg("gfx_set_framebuffer failed to allocate %lu bytes of chip mem for framebuffer\n", sz); 1.117 + return 0; 1.118 + } 1.119 + own_framebuf = 1; 1.120 + } 1.121 + 1.122 + fb_width = width; 1.123 + fb_height = height; 1.124 + fbsize = sz; 1.125 + 1.126 + bpladdr = (uint32_t)framebuf; 1.127 + logmsg("bitplane address: %lx\n", (unsigned long)bpladdr); 1.128 + 1.129 + bplmod = (fb_width - scr_width) / 8 + fb_width / 8 * num_bitplanes; 1.130 + REG_BPL1MOD = bplmod; 1.131 + REG_BPL2MOD = bplmod; 1.132 + 1.133 + /* 1.134 + REG32_BPL1PT = bpladdr; bpladdr += bpl_scanline_sz; 1.135 + REG32_BPL2PT = bpladdr; bpladdr += bpl_scanline_sz; 1.136 + REG32_BPL3PT = bpladdr; bpladdr += bpl_scanline_sz; 1.137 + REG32_BPL4PT = bpladdr; bpladdr += bpl_scanline_sz; 1.138 + REG32_BPL5PT = bpladdr; bpladdr += bpl_scanline_sz; 1.139 + REG32_BPL6PT = bpladdr; 1.140 + */ 1.141 + return framebuf; 1.142 +} 1.143 + 1.144 +void *gfx_get_framebuffer(void) 1.145 +{ 1.146 + return framebuf; 1.147 +} 1.148 + 1.149 +int gfx_framebuffer_width(void) 1.150 +{ 1.151 + return fb_width; 1.152 +} 1.153 + 1.154 +int gfx_framebuffer_height(void) 1.155 +{ 1.156 + return fb_height; 1.157 +} 1.158 + 1.159 +void gfx_begin_copperlist(void) 1.160 +{ 1.161 + static const uint16_t bplptr[] = { 1.162 + REGN_BPL1PTH, REGN_BPL2PTH, REGN_BPL3PTH, REGN_BPL4PTH, REGN_BPL5PTH, REGN_BPL6PTH 1.163 + }; 1.164 + int i; 1.165 + uint32_t bpladdr; 1.166 + bpladdr = (uint32_t)framebuf; 1.167 + 1.168 + for(i=0; i<num_bitplanes; i++) { 1.169 + add_copper(COPPER_MOVE(bplptr[i], bpladdr >> 16)); 1.170 + add_copper(COPPER_MOVE(bplptr[i] + 2, bpladdr)); 1.171 + bpladdr += fb_width / 8 * num_bitplanes; 1.172 + } 1.173 +} 1.174 + 1.175 +static int mouse_bnstate(void) 1.176 +{ 1.177 + return (REG_CIAA_PORTA & CIAA_PA_FIR0) ? 0 : 1; 1.178 +} 1.179 + 1.180 +int gfx_next_event(union gfx_event *ev, int block) 1.181 +{ 1.182 + /* TODO */ 1.183 + if(block) { 1.184 + while(!mouse_bnstate()); 1.185 + ev->type = GFX_EV_QUIT; 1.186 + return 1; 1.187 + } 1.188 + 1.189 + if(mouse_bnstate()) { 1.190 + ev->type = GFX_EV_QUIT; 1.191 + return 1; 1.192 + } 1.193 + 1.194 + return 0; 1.195 +} 1.196 + 1.197 +void gfx_wait_vpos(int x) 1.198 +{ 1.199 + x <<= 8; 1.200 + while((REG32_VPOSR & 0x1ff00) < x); 1.201 +} 1.202 + 1.203 +void gfx_wait_vblank(void) 1.204 +{ 1.205 + gfx_wait_vpos(300); 1.206 +}