rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <proto/exec.h>
|
nuclear@0
|
3 #include "gfx.h"
|
nuclear@0
|
4 #include "copper.h"
|
nuclear@0
|
5 #include "hwregs.h"
|
nuclear@0
|
6 #include "logger.h"
|
nuclear@4
|
7 #include "image.h"
|
nuclear@0
|
8
|
nuclear@0
|
9 static int scr_width, scr_height;
|
nuclear@0
|
10 static int fb_width, fb_height;
|
nuclear@0
|
11 static int num_bitplanes;
|
nuclear@0
|
12 static uint16_t prev_intena, prev_intreq, prev_adkcon, prev_dmacon;
|
nuclear@0
|
13
|
nuclear@0
|
14 static unsigned char *framebuf;
|
nuclear@0
|
15 static unsigned long fbsize;
|
nuclear@0
|
16 static int own_framebuf;
|
nuclear@0
|
17
|
nuclear@0
|
18 int gfx_init(int nbpl, unsigned int flags)
|
nuclear@0
|
19 {
|
nuclear@0
|
20 uint16_t bplcon0;
|
nuclear@0
|
21
|
nuclear@0
|
22 num_bitplanes = nbpl;
|
nuclear@0
|
23 scr_width = fb_width = (flags & GFX_HIRES) ? 640 : 320;
|
nuclear@0
|
24 scr_height = fb_height = (flags & GFX_ILACE) ? 512 : 256;
|
nuclear@0
|
25
|
nuclear@0
|
26 Forbid();
|
nuclear@0
|
27
|
nuclear@0
|
28 prev_dmacon = REG_DMACONR;
|
nuclear@0
|
29 REG_DMACON = CLRBITS(DMA_ALL);
|
nuclear@0
|
30
|
nuclear@0
|
31 prev_intena = REG_INTENAR;
|
nuclear@0
|
32 prev_intreq = REG_INTREQR;
|
nuclear@0
|
33 prev_adkcon = REG_ADKCONR;
|
nuclear@0
|
34
|
nuclear@0
|
35 if(init_copper(0, 0) == -1) {
|
nuclear@0
|
36 return -1;
|
nuclear@0
|
37 }
|
nuclear@0
|
38
|
nuclear@0
|
39 if(!gfx_set_framebuffer(0, scr_width, scr_height)) {
|
nuclear@0
|
40 gfx_shutdown();
|
nuclear@0
|
41 return -1;
|
nuclear@0
|
42 }
|
nuclear@0
|
43
|
nuclear@0
|
44 bplcon0 = BPLCON0_COUNT(nbpl) | BPLCON0_COLOR;
|
nuclear@0
|
45 if(flags & GFX_HIRES) bplcon0 |= BPLCON0_HIRES;
|
nuclear@0
|
46 if(flags & GFX_ILACE) bplcon0 |= BPLCON0_LACE;
|
nuclear@0
|
47 if(flags & GFX_HAM) bplcon0 |= BPLCON0_HOMOD;
|
nuclear@0
|
48 if(flags & GFX_DBLPF) bplcon0 |= BPLCON0_DBLPF;
|
nuclear@0
|
49
|
nuclear@0
|
50 REG_BPLCON0 = bplcon0;
|
nuclear@0
|
51 REG_BPLCON1 = 0; /* h-scroll */
|
nuclear@0
|
52 REG_DIWSTART = 0x2c81; /* 81h horiz start, 2ch vertical start */
|
nuclear@0
|
53 REG_DIWSTOP = 0x2cc1;
|
nuclear@0
|
54 REG_DDFSTART = (flags & GFX_HIRES) ? 0x3c : 0x38;
|
nuclear@0
|
55 REG_DDFSTOP = (flags & GFX_HIRES) ? 0xd4 : 0xd0;
|
nuclear@0
|
56
|
nuclear@0
|
57 gfx_wait_vblank();
|
nuclear@0
|
58 gfx_begin_copperlist();
|
nuclear@0
|
59 add_copper(COPPER_END);
|
nuclear@0
|
60
|
nuclear@3
|
61 logmsg("starting DMA\n");
|
nuclear@0
|
62 REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER);
|
nuclear@0
|
63 return 0;
|
nuclear@0
|
64 }
|
nuclear@0
|
65
|
nuclear@0
|
66 void gfx_shutdown(void)
|
nuclear@0
|
67 {
|
nuclear@0
|
68 REG_DMACON = CLRBITS(DMA_ALL);
|
nuclear@0
|
69 REG_DMACON = SETBITS(prev_dmacon);
|
nuclear@0
|
70
|
nuclear@0
|
71 REG_INTREQ = CLRBITS(0x7fff);
|
nuclear@0
|
72 REG_INTREQ = SETBITS(prev_intreq);
|
nuclear@0
|
73
|
nuclear@0
|
74 REG_ADKCON = CLRBITS(0x7fff);
|
nuclear@0
|
75 REG_ADKCON = SETBITS(prev_adkcon);
|
nuclear@0
|
76
|
nuclear@0
|
77 REG_INTENA = CLRBITS(INTEN_ALL);
|
nuclear@0
|
78 REG_INTENA = SETBITS(prev_intena);
|
nuclear@0
|
79
|
nuclear@0
|
80 if(framebuf && own_framebuf) {
|
nuclear@0
|
81 FreeMem(framebuf, fbsize);
|
nuclear@0
|
82 }
|
nuclear@0
|
83 framebuf = 0;
|
nuclear@0
|
84
|
nuclear@0
|
85 cleanup_copper();
|
nuclear@0
|
86 Permit();
|
nuclear@0
|
87 }
|
nuclear@0
|
88
|
nuclear@0
|
89 int gfx_screen_width(void)
|
nuclear@0
|
90 {
|
nuclear@0
|
91 return scr_width;
|
nuclear@0
|
92 }
|
nuclear@0
|
93
|
nuclear@0
|
94 int gfx_screen_height(void)
|
nuclear@0
|
95 {
|
nuclear@0
|
96 return scr_height;
|
nuclear@0
|
97 }
|
nuclear@0
|
98
|
nuclear@0
|
99 void *gfx_set_framebuffer(void *fb, int width, int height)
|
nuclear@0
|
100 {
|
nuclear@0
|
101 /*unsigned int bpl_scanline_sz = width / 8;*/
|
nuclear@0
|
102 unsigned long sz = width * height / 8 * num_bitplanes;
|
nuclear@0
|
103 uint32_t bpladdr;
|
nuclear@0
|
104 uint16_t bplmod;
|
nuclear@0
|
105
|
nuclear@0
|
106 if(framebuf && own_framebuf) {
|
nuclear@0
|
107 FreeMem(framebuf, fbsize);
|
nuclear@0
|
108 }
|
nuclear@0
|
109
|
nuclear@0
|
110 if(fb) {
|
nuclear@0
|
111 framebuf = fb;
|
nuclear@0
|
112 own_framebuf = 0;
|
nuclear@0
|
113 } else {
|
nuclear@0
|
114 if(!(framebuf = AllocMem(sz, MEMF_CHIP))) {
|
nuclear@0
|
115 logmsg("gfx_set_framebuffer failed to allocate %lu bytes of chip mem for framebuffer\n", sz);
|
nuclear@0
|
116 return 0;
|
nuclear@0
|
117 }
|
nuclear@0
|
118 own_framebuf = 1;
|
nuclear@0
|
119 }
|
nuclear@0
|
120
|
nuclear@0
|
121 fb_width = width;
|
nuclear@0
|
122 fb_height = height;
|
nuclear@0
|
123 fbsize = sz;
|
nuclear@0
|
124
|
nuclear@0
|
125 bpladdr = (uint32_t)framebuf;
|
nuclear@0
|
126 logmsg("bitplane address: %lx\n", (unsigned long)bpladdr);
|
nuclear@0
|
127
|
nuclear@4
|
128 bplmod = (fb_width - scr_width) / 8 + fb_width / 8 * (num_bitplanes - 1);
|
nuclear@0
|
129 REG_BPL1MOD = bplmod;
|
nuclear@0
|
130 REG_BPL2MOD = bplmod;
|
nuclear@0
|
131
|
nuclear@0
|
132 /*
|
nuclear@0
|
133 REG32_BPL1PT = bpladdr; bpladdr += bpl_scanline_sz;
|
nuclear@0
|
134 REG32_BPL2PT = bpladdr; bpladdr += bpl_scanline_sz;
|
nuclear@0
|
135 REG32_BPL3PT = bpladdr; bpladdr += bpl_scanline_sz;
|
nuclear@0
|
136 REG32_BPL4PT = bpladdr; bpladdr += bpl_scanline_sz;
|
nuclear@0
|
137 REG32_BPL5PT = bpladdr; bpladdr += bpl_scanline_sz;
|
nuclear@0
|
138 REG32_BPL6PT = bpladdr;
|
nuclear@0
|
139 */
|
nuclear@0
|
140 return framebuf;
|
nuclear@0
|
141 }
|
nuclear@0
|
142
|
nuclear@0
|
143 void *gfx_get_framebuffer(void)
|
nuclear@0
|
144 {
|
nuclear@0
|
145 return framebuf;
|
nuclear@0
|
146 }
|
nuclear@0
|
147
|
nuclear@0
|
148 int gfx_framebuffer_width(void)
|
nuclear@0
|
149 {
|
nuclear@0
|
150 return fb_width;
|
nuclear@0
|
151 }
|
nuclear@0
|
152
|
nuclear@0
|
153 int gfx_framebuffer_height(void)
|
nuclear@0
|
154 {
|
nuclear@0
|
155 return fb_height;
|
nuclear@0
|
156 }
|
nuclear@0
|
157
|
nuclear@0
|
158 void gfx_begin_copperlist(void)
|
nuclear@0
|
159 {
|
nuclear@0
|
160 static const uint16_t bplptr[] = {
|
nuclear@0
|
161 REGN_BPL1PTH, REGN_BPL2PTH, REGN_BPL3PTH, REGN_BPL4PTH, REGN_BPL5PTH, REGN_BPL6PTH
|
nuclear@0
|
162 };
|
nuclear@0
|
163 int i;
|
nuclear@0
|
164 uint32_t bpladdr;
|
nuclear@0
|
165 bpladdr = (uint32_t)framebuf;
|
nuclear@0
|
166
|
nuclear@0
|
167 for(i=0; i<num_bitplanes; i++) {
|
nuclear@0
|
168 add_copper(COPPER_MOVE(bplptr[i], bpladdr >> 16));
|
nuclear@0
|
169 add_copper(COPPER_MOVE(bplptr[i] + 2, bpladdr));
|
nuclear@5
|
170 bpladdr += fb_width / 8;
|
nuclear@0
|
171 }
|
nuclear@0
|
172 }
|
nuclear@0
|
173
|
nuclear@0
|
174 static int mouse_bnstate(void)
|
nuclear@0
|
175 {
|
nuclear@0
|
176 return (REG_CIAA_PORTA & CIAA_PA_FIR0) ? 0 : 1;
|
nuclear@0
|
177 }
|
nuclear@0
|
178
|
nuclear@0
|
179 int gfx_next_event(union gfx_event *ev, int block)
|
nuclear@0
|
180 {
|
nuclear@0
|
181 /* TODO */
|
nuclear@0
|
182 if(block) {
|
nuclear@0
|
183 while(!mouse_bnstate());
|
nuclear@0
|
184 ev->type = GFX_EV_QUIT;
|
nuclear@0
|
185 return 1;
|
nuclear@0
|
186 }
|
nuclear@0
|
187
|
nuclear@0
|
188 if(mouse_bnstate()) {
|
nuclear@0
|
189 ev->type = GFX_EV_QUIT;
|
nuclear@0
|
190 return 1;
|
nuclear@0
|
191 }
|
nuclear@0
|
192
|
nuclear@0
|
193 return 0;
|
nuclear@0
|
194 }
|
nuclear@0
|
195
|
nuclear@0
|
196 void gfx_wait_vpos(int x)
|
nuclear@0
|
197 {
|
nuclear@0
|
198 x <<= 8;
|
nuclear@0
|
199 while((REG32_VPOSR & 0x1ff00) < x);
|
nuclear@0
|
200 }
|
nuclear@0
|
201
|
nuclear@0
|
202 void gfx_wait_vblank(void)
|
nuclear@0
|
203 {
|
nuclear@0
|
204 gfx_wait_vpos(300);
|
nuclear@0
|
205 }
|
nuclear@3
|
206
|
nuclear@3
|
207 void gfx_show_image(struct ham_image *img)
|
nuclear@3
|
208 {
|
nuclear@4
|
209 int i, j, k, fbwidth, fbheight, ncolors, prev_line;
|
nuclear@4
|
210 unsigned char *fbptr = gfx_get_framebuffer();
|
nuclear@4
|
211 struct palchange *chg = img->chglist;
|
nuclear@4
|
212
|
nuclear@4
|
213 fbwidth = gfx_framebuffer_width();
|
nuclear@4
|
214 fbheight = gfx_framebuffer_height();
|
nuclear@4
|
215
|
nuclear@4
|
216 logmsg("showing ham image %dx%d\n", fbwidth, fbheight);
|
nuclear@4
|
217
|
nuclear@4
|
218 memcpy(fbptr, img->pixels, fbwidth * fbheight / 8 * num_bitplanes);
|
nuclear@4
|
219
|
nuclear@4
|
220 /* create copper list that handles the palette */
|
nuclear@4
|
221 clear_copper();
|
nuclear@4
|
222 gfx_begin_copperlist();
|
nuclear@4
|
223 /* initial palette at the start of frame */
|
nuclear@4
|
224 for(i=0; i<16; i++) {
|
nuclear@4
|
225 add_copper(COPPER_MOVE(REGN_COLOR(i), img->palette[i]));
|
nuclear@4
|
226 logmsg("copper palette[%d]: %x\n", i, (unsigned int)img->palette[i]);
|
nuclear@4
|
227 }
|
nuclear@4
|
228 #if 0
|
nuclear@4
|
229 /* add copper instructions for palette changes according to the image changelist */
|
nuclear@4
|
230 prev_line = -1;
|
nuclear@4
|
231 while(chg) {
|
nuclear@4
|
232 assert(chg->line >= prev_line);
|
nuclear@4
|
233 if(chg->line != prev_line) {
|
nuclear@4
|
234 prev_line = chg->line;
|
nuclear@4
|
235 add_copper(COPPER_VWAIT(chg->line));
|
nuclear@4
|
236 }
|
nuclear@4
|
237 add_copper(COPPER_MOVE(REGN_COLOR(chg->entry >> 12), chg->entry & 0xfff));
|
nuclear@4
|
238 }
|
nuclear@4
|
239 #endif
|
nuclear@4
|
240 add_copper(COPPER_END);
|
nuclear@3
|
241 }
|