1 /* $NetBSD: grfabs_cc.c,v 1.39 2023/07/12 05:16:42 mlelstv Exp $ */
2
3 /*
4 * Copyright (c) 1994 Christian E. Hopps
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christian E. Hopps.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * abstract interface for custom chips to the amiga abstract graphics driver.
35 *
36 */
37
38 #include "opt_amigaccgrf.h"
39
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: grfabs_cc.c,v 1.39 2023/07/12 05:16:42 mlelstv Exp $");
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/errno.h>
46 #include <sys/queue.h>
47 #include <sys/intr.h>
48
49 #include <amiga/amiga/custom.h>
50 #include <amiga/amiga/cc.h>
51
52 #include <amiga/dev/grfabs_reg.h>
53 #include <amiga/dev/grfabs_ccreg.h>
54
55 monitor_t *m_this;
56 mdata_t *m_this_data;
57 const char *monitor_name = "CCMONITOR";
58 monitor_t monitor;
59 mdata_t monitor_data;
60 cop_t *null_mode_copper_list;
61
62 #if defined (GRF_PAL)
63 # if defined (GRF_A2024)
64 dmode_t pal_a2024_mode;
65 dmdata_t pal_a2024_mode_data;
66 cop_t *pal_a2024_frames[F_QD_TOTAL];
67 u_char *hedley_init; /* init bitplane. */
68 dmode_t *p24_this;
69 dmdata_t *p24_this_data;
70
71 dmode_t pal_hires_dlace_mode;
72 dmdata_t pal_hires_dlace_mode_data;
73 cop_t *pal_hires_dlace_frames[F_LACE_TOTAL];
74 dmode_t *phdl_this;
75 dmdata_t *phdl_this_data;
76 # endif /* GRF_A2024 */
77
78 # if defined (GRF_AGA)
79 dmode_t paga_mode;
80 dmdata_t paga_mode_data;
81 cop_t *paga_frames[F_TOTAL];
82 dmode_t *paga_this;
83 dmdata_t *paga_this_data;
84
85 # endif /* GRF_AGA */
86
87 dmode_t pal_hires_lace_mode;
88 dmdata_t pal_hires_lace_mode_data;
89 cop_t *pal_hires_lace_frames[F_LACE_TOTAL];
90 dmode_t *phl_this;
91 dmdata_t *phl_this_data;
92
93 dmode_t pal_hires_mode;
94 dmdata_t pal_hires_mode_data;
95 cop_t *pal_hires_frames[F_TOTAL];
96 dmode_t *ph_this;
97 dmdata_t *ph_this_data;
98 #endif /* PAL */
99
100 #if defined (GRF_NTSC)
101 # if defined (GRF_A2024)
102 dmode_t a2024_mode;
103 dmdata_t a2024_mode_data;
104 cop_t *a2024_frames[F_QD_TOTAL];
105 u_char *hedley_init; /* init bitplane. */
106 dmode_t *a24_this;
107 dmdata_t *a24_this_data;
108
109 dmode_t hires_dlace_mode;
110 dmdata_t hires_dlace_mode_data;
111 cop_t *hires_dlace_frames[F_LACE_TOTAL];
112 dmode_t *hdl_this;
113 dmdata_t *hdl_this_data;
114 # endif /* GRF_A2024 */
115
116 # if defined (GRF_AGA)
117 dmode_t aga_mode;
118 dmdata_t aga_mode_data;
119 cop_t *aga_frames[F_TOTAL];
120 dmode_t *aga_this;
121 dmdata_t *aga_this_data;
122
123 #if defined (GRF_SUPER72)
124 dmode_t super72_mode;
125 dmdata_t super72_mode_data;
126 cop_t *super72_frames[F_LACE_TOTAL];
127 dmode_t *super72_this;
128 dmdata_t *super72_this_data;
129 #endif /* GRF_SUPER72 */
130
131 # endif /* GRF_AGA */
132
133 dmode_t hires_lace_mode;
134 dmdata_t hires_lace_mode_data;
135 cop_t *hires_lace_frames[F_LACE_TOTAL];
136 dmode_t *hl_this;
137 dmdata_t *hl_this_data;
138
139 void display_hires_view(view_t * v);
140 dmode_t hires_mode;
141 dmdata_t hires_mode_data;
142 cop_t *hires_frames[F_TOTAL];
143 dmode_t *h_this;
144 dmdata_t *h_this_data;
145 #endif /* GRF_NTSC */
146
147 #ifdef GRF_AGA
148 #define AGA_ENABLE 0x0001
149 #define AGA_ENABLE2 0x0002
150 #define AGA_TRACE 0x0004
151 #define AGA_TRACE2 0x0008
152 #define AGA_VGAONLY 0x0010
153 #define AGA_VGA31KHZ 0x0020
154
155 int aga_enable = 0; /* set by start_c(), or can be patched */
156 colormap_t *cc_alloc_aga_colormap(int);
157 int cc_use_aga_colormap(view_t *, colormap_t *);
158 #endif
159
160 /* monitor functions. */
161 monitor_t *
cc_init_monitor(void)162 cc_init_monitor(void)
163 {
164 cop_t *cp;
165
166 if (m_this)
167 return(m_this);
168
169 cc_monitor = m_this = &monitor;
170 /* turn sprite DMA off. we don't support them yet. */
171 custom.dmacon = DMAF_SPRITE;
172
173 /* make sure sprite data registers are clear as well */
174 custom.spr[0].data = 0;
175 custom.spr[0].datb = 0;
176
177 m_this->name = monitor_name;
178 m_this_data = m_this->data = &monitor_data;
179
180 m_this->get_current_mode = get_current_mode;
181 m_this->vbl_handler = (vbl_handler_func *) monitor_vbl_handler;
182 m_this->get_next_mode = get_next_mode;
183 m_this->get_best_mode = get_best_mode;
184
185 m_this->alloc_bitmap = alloc_bitmap;
186 m_this->free_bitmap = free_bitmap;
187
188 m_this_data->current_mode = NULL;
189 LIST_INIT(&m_this_data->modes);
190
191 cp = null_mode_copper_list = alloc_chipmem(sizeof(cop_t) * 4);
192 if (!cp)
193 panic("no chipmem for grf.");
194
195 CMOVE(cp, R_COLOR00, 0x0000); /* background is black */
196 CMOVE(cp, R_BPLCON0, 0x0000); /* no planes to fetch from */
197 CWAIT(cp, 255, 255); /* COPEND */
198 CWAIT(cp, 255, 255); /* COPEND really */
199
200 /* install this list and turn DMA on */
201 custom.cop1lc = PREP_DMA_MEM(null_mode_copper_list);
202 custom.copjmp1 = 0;
203 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER \
204 |DMAF_COPPER;
205
206 cc_init_modes();
207 LIST_INSERT_HEAD(monitors, m_this, link);
208 return (m_this);
209 }
210
211 void
monitor_vbl_handler(monitor_t * m)212 monitor_vbl_handler(monitor_t *m)
213 {
214 dmdata_t *dmd;
215
216 if (m_this_data->current_mode == NULL)
217 return;
218
219 dmd = DMDATA(m_this_data->current_mode);
220 if (dmd)
221 dmd->vbl_handler(m_this_data->current_mode);
222 }
223
224 dmode_t *
get_current_mode(void)225 get_current_mode(void)
226 {
227 if (m_this_data->current_mode)
228 return(m_this_data->current_mode);
229 else
230 return(NULL);
231 }
232
233 dmode_t *
get_next_mode(dmode_t * d)234 get_next_mode(dmode_t *d)
235 {
236 if (d)
237 return(d->link.le_next);
238 return(m_this_data->modes.lh_first);
239 }
240
241 /* XXX needs to have more control attributes */
242 dmode_t *
get_best_mode(dimen_t * size,u_char depth)243 get_best_mode(dimen_t *size, u_char depth)
244 {
245 dmode_t *save;
246 dmode_t *dm;
247 long dt = 0, dx, dy, ct;
248 dmdata_t *dmd;
249
250 save = NULL;
251 dm = m_this_data->modes.lh_first;
252 while (dm != NULL) {
253 dmd = dm->data;
254 if (depth > dmd->max_depth || depth < dmd->min_depth) {
255 dm = dm->link.le_next;
256 continue;
257 } else if (size->width > dmd->max_size.width ||
258 size->height > dmd->max_size.height) {
259 dm = dm->link.le_next;
260 continue;
261 } else if (size->width < dmd->min_size.width ||
262 size->height < dmd->min_size.height) {
263 dm = dm->link.le_next;
264 continue;
265 }
266 dx = abs(dm->nominal_size.width - size->width);
267 dy = abs(dm->nominal_size.height - size->height);
268 ct = dx + dy;
269
270 if (ct < dt || save == NULL) {
271 save = dm;
272 dt = ct;
273 }
274 dm = dm->link.le_next;
275 }
276 return (save);
277 }
278 /* bitmap functions */
279 bmap_t *
alloc_bitmap(u_short width,u_short height,u_short depth,u_short flags)280 alloc_bitmap(u_short width, u_short height, u_short depth, u_short flags)
281 {
282 int i;
283 u_long total_size;
284 #ifdef GRF_AGA
285 u_short lwpr = (flags & BMF_ALIGN64) ? ((width + 63) / 64) * 2 :
286 (width + 31) / 32; /* AGA needs 64 bit align */
287 #else
288 u_short lwpr = (width + 31) / 32;
289 #endif
290 u_short wpr = lwpr << 1;
291 u_short bpr = wpr << 1;
292 u_short array_size = sizeof(u_char *) * depth;
293 u_long plane_size = bpr * height;
294 u_short temp_size = bpr + sizeof(u_long);
295 bmap_t *bm;
296
297 /* note the next allocation will give everything, also note that all
298 * the stuff we want (including bitmaps) will be long short aligned.
299 * This is a function of the data being allocated and the fact that
300 * alloc_chipmem() returns long short aligned data. note also that
301 * each row of the bitmap is long word aligned and made of exactly n
302 * longwords. -ch */
303
304 /* Sigh, it seems for mapping to work we need the bitplane data to 1:
305 * be aligned on a page boundary. 2: be n pages large.
306 *
307 * why? because the user gets a page aligned address, if this is before
308 * your allocation, too bad. Also it seems that the mapping routines
309 * do not watch to closely to the allowable length. so if you go over
310 * n pages by less than another page, the user gets to write all over
311 * the entire page. Since you did not allocate up to a page boundary
312 * (or more) the user writes into someone elses memory. -ch */
313 #ifdef __powerpc__
314 #define m68k_round_page(x) ((((unsigned)(x)) + PGOFSET) & ~PGOFSET)
315 #endif
316 total_size = m68k_round_page(plane_size * depth) + /* for length */
317 (temp_size) + (array_size) + sizeof(bmap_t) +
318 PAGE_SIZE; /* for alignment */
319 bm = alloc_chipmem(total_size);
320 if (bm) {
321 if (flags & BMF_CLEAR) {
322 memset(bm, 0, total_size);
323 }
324 bm->bytes_per_row = bpr;
325 bm->rows = height;
326 bm->depth = depth;
327 bm->flags = flags;
328 bm->plane = (u_char **) & bm[1];
329 bm->blit_temp = ((u_char *) bm->plane) + array_size;
330 bm->plane[0] = (u_char *) m68k_round_page((u_long)
331 (bm->blit_temp + temp_size));
332 if (flags & BMF_INTERLEAVED) {
333 bm->row_mod = bm->bytes_per_row * (depth - 1);
334 for (i = 1; i < depth; i++) {
335 bm->plane[i] = bm->plane[i - 1] + bpr;
336 }
337 } else {
338 bm->row_mod = 0;
339 for (i = 1; i < depth; i++) {
340 bm->plane[i] = bm->plane[i - 1] + plane_size;
341 }
342 }
343 bm->hardware_address = PREP_DMA_MEM(bm->plane[0]);
344 return (bm);
345 }
346 return (NULL);
347 }
348
349
350 void
free_bitmap(bmap_t * bm)351 free_bitmap(bmap_t *bm)
352 {
353 if (bm)
354 free_chipmem(bm);
355 }
356 /* load a new mode into the current display, if NULL shut display off. */
357 void
cc_load_mode(dmode_t * d)358 cc_load_mode(dmode_t *d)
359 {
360 if (d) {
361 m_this_data->current_mode = d;
362 #ifdef __powerpc__ /* XXX ???? */
363 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LONG]);
364 custom.copjmp1 = 0;
365 #endif
366 return;
367 }
368 /* turn off display */
369 m_this_data->current_mode = NULL;
370 wait_tof();
371 wait_tof();
372 custom.cop1lc = PREP_DMA_MEM(null_mode_copper_list);
373 custom.copjmp1 = 0;
374 }
375 /*
376 * CC Mode Stuff.
377 */
378
379 dmode_t *(*mode_init_funcs[]) (void) = {
380 #if defined (GRF_NTSC)
381 #if defined (GRF_A2024)
382 cc_init_ntsc_a2024,
383 cc_init_ntsc_hires_dlace,
384 #endif /* GRF_A2024 */
385 cc_init_ntsc_hires_lace,
386 cc_init_ntsc_hires,
387 #if defined (GRF_AGA)
388 cc_init_ntsc_aga,
389 #if defined (GRF_SUPER72)
390 cc_init_super72,
391 #endif /* GRF_SUPER72 */
392 #endif /* GRF_AGA */
393 #endif /* GRF_NTSC */
394 #if defined (GRF_PAL)
395 #if defined (GRF_A2024)
396 cc_init_pal_a2024,
397 cc_init_pal_hires_dlace,
398 #endif /* GRF_A2024 */
399 cc_init_pal_hires_lace,
400 cc_init_pal_hires,
401 #if defined (GRF_AGA)
402 cc_init_pal_aga,
403 #endif /* GRF_AGA */
404 #endif /* GRF_PAL */
405 NULL
406 };
407
408 int
cc_init_modes(void)409 cc_init_modes(void)
410 {
411 int i = 0;
412 int error = 0;
413 while (mode_init_funcs[i]) {
414 mode_init_funcs[i] ();
415 i++;
416 }
417 return (error);
418 }
419
420 monitor_t *
cc_get_monitor(dmode_t * d)421 cc_get_monitor(dmode_t *d)
422 {
423 return (DMDATA(d)->monitor);
424 }
425
426 view_t *
cc_get_current_view(dmode_t * d)427 cc_get_current_view(dmode_t *d)
428 {
429 return (DMDATA(d)->current_view);
430 }
431
432
433 view_t *
cc_alloc_view(dmode_t * mode,dimen_t * dim,u_char depth)434 cc_alloc_view(dmode_t *mode, dimen_t *dim, u_char depth)
435 {
436 view_t *v = alloc_chipmem(sizeof(*v) + sizeof(vdata_t));
437 if (v) {
438 bmap_t *bm = cc_monitor->alloc_bitmap(dim->width, dim->height,
439 depth, BMF_CLEAR | (DMDATA(mode)->max_depth == 8 ? BMF_ALIGN64 : 0));
440 if (bm) {
441 box_t box;
442
443 v->data = &v[1]; /* at the end of view */
444 VDATA(v)->colormap = DMDATA(mode)->alloc_colormap(depth);
445 if (VDATA(v)->colormap) {
446 INIT_BOX(&box, 0, 0, dim->width, dim->height);
447 cc_init_view(v, bm, mode, &box);
448 return (v);
449 }
450 cc_monitor->free_bitmap(bm);
451 }
452 free_chipmem(v);
453 }
454 return (NULL);
455 }
456
457 colormap_t *
cc_alloc_colormap(int depth)458 cc_alloc_colormap(int depth)
459 {
460 u_long size = 1U << depth, i;
461 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm));
462
463 if (cm) {
464 cm->type = CM_COLOR;
465 cm->red_mask = 0x0F;
466 cm->green_mask = 0x0F;
467 cm->blue_mask = 0x0F;
468 cm->first = 0;
469 cm->size = size;
470 cm->entry = (u_long *) & cm[1]; /* table directly after. */
471 for (i = 0; i < size; i++) {
472 cm->entry[i] = CM_WTOL(cc_default_colors[i&31]);
473 }
474 return (cm);
475 }
476 return (NULL);
477 }
478
479 #ifdef GRF_AGA
480 colormap_t *
cc_alloc_aga_colormap(int depth)481 cc_alloc_aga_colormap(int depth)
482 {
483 u_long size = 1U << depth, i;
484 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm));
485
486 if (cm) {
487 cm->type = CM_COLOR;
488 cm->red_mask = 0x0FF;
489 cm->green_mask = 0x0FF;
490 cm->blue_mask = 0x0FF;
491 cm->first = 0;
492 cm->size = size;
493 cm->entry = (u_long *) & cm[1]; /* table directly after. */
494 for (i = 0; i < size; i++) {
495 cm->entry[i] = CM_WTOL(cc_default_colors[i&31]) |
496 (CM_WTOL(cc_default_colors[i&31]) << 4);
497 }
498 return (cm);
499 }
500 return (NULL);
501 }
502 #endif
503
504 int
cc_colormap_checkvals(colormap_t * vcm,colormap_t * cm,int use)505 cc_colormap_checkvals(colormap_t *vcm, colormap_t *cm, int use)
506 {
507 if (use) {
508 /* check to see if its the view's colormap, if so just do
509 * update. */
510 if (vcm != cm) {
511 if (cm->first >= vcm->size ||
512 (cm->first + cm->size) > (cm->first + vcm->size) ||
513 cm->type != vcm->type) {
514 return (0);
515 }
516 switch (vcm->type) {
517 case CM_COLOR:
518 if (cm->red_mask != vcm->red_mask ||
519 cm->green_mask != vcm->green_mask ||
520 cm->blue_mask != vcm->blue_mask) {
521 return (0);
522 }
523 break;
524 case CM_GREYSCALE:
525 if (cm->grey_mask != vcm->grey_mask) {
526 return (0);
527 }
528 break;
529 }
530 }
531 } else {
532 if (cm->first >= vcm->size ||
533 (cm->first + cm->size) > (cm->first + vcm->size)) {
534 return (0);
535 }
536 }
537 return (1);
538 }
539
540 /* does sanity check on values */
541 int
cc_get_colormap(view_t * v,colormap_t * cm)542 cc_get_colormap(view_t *v, colormap_t *cm)
543 {
544 colormap_t *vcm = VDATA(v)->colormap;
545 int i;
546
547 if (!cc_colormap_checkvals(vcm, cm, 0)) {
548 return (EINVAL);
549 }
550 cm->type = vcm->type;
551
552 switch (vcm->type) {
553 case CM_COLOR:
554 cm->red_mask = vcm->red_mask;
555 cm->green_mask = vcm->green_mask;
556 cm->blue_mask = vcm->blue_mask;
557 break;
558 case CM_GREYSCALE:
559 cm->grey_mask = vcm->grey_mask;
560 break;
561 }
562
563 /* copy entries into colormap. */
564 for (i = cm->first; i < (cm->first + cm->size); i++) {
565 cm->entry[i] = vcm->entry[i];
566 }
567 return (0);
568 }
569
570 /* does sanity check on values */
571 int
cc_use_colormap(view_t * v,colormap_t * cm)572 cc_use_colormap(view_t *v, colormap_t *cm)
573 {
574 colormap_t *vcm = VDATA(v)->colormap;
575 int s, i;
576
577 if (!cc_colormap_checkvals(vcm, cm, 1)) {
578 return (EINVAL);
579 }
580 /* check to see if its the view's colormap, if so just do update. */
581 if (vcm != cm) {
582 /* copy entries into colormap. */
583 for (i = cm->first; i < (cm->first + cm->size); i++) {
584 vcm->entry[i] = cm->entry[i];
585 }
586 }
587 s = spltty();
588
589 /* is view currently being displayed? */
590 if (VDATA(v)->flags & VF_DISPLAY) {
591 /* yes, update the copper lists */
592 cop_t *tmp, *cp;
593 int nframes = 1, j;
594
595 if (DMDATA(VDATA(v)->mode)->flags & DMF_INTERLACE) {
596 nframes = 2;
597 }
598 for (i = 0; i < nframes; i++) {
599 cp = DMDATA(VDATA(v)->mode)->frames[i];
600
601 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR07));
602 tmp -= 7;
603
604 for (j = 0; j < 32; j++) {
605 CMOVE(tmp, (R_COLOR00 + (j << 1)),
606 CM_LTOW(vcm->entry[j]));
607 }
608 }
609 }
610 splx(s);
611 return (0);
612 }
613
614 #ifdef GRF_AGA
615 /* does sanity check on values */
616 int
cc_use_aga_colormap(view_t * v,colormap_t * cm)617 cc_use_aga_colormap(view_t *v, colormap_t *cm)
618 {
619 colormap_t *vcm = VDATA(v)->colormap;
620 int s, i;
621
622 if (!cc_colormap_checkvals(vcm, cm, 1)) {
623 return (EINVAL);
624 }
625 /* check to see if its the view's colormap, if so just do update. */
626 if (vcm != cm) {
627 /* copy entries into colormap. */
628 for (i = cm->first; i < (cm->first + cm->size); i++) {
629 vcm->entry[i] = cm->entry[i];
630 }
631 }
632 s = spltty();
633
634 /* is view currently being displayed? */
635 if (VDATA(v)->flags & VF_DISPLAY) {
636 /* yes, update the copper lists */
637 cop_t *tmp, *cp;
638 int nframes = 1, j;
639
640 if (DMDATA(VDATA(v)->mode)->flags & DMF_INTERLACE) {
641 nframes = 2;
642 }
643 for (i = 0; i < nframes; i++) {
644 cp = DMDATA(VDATA(v)->mode)->frames[i];
645
646 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR00));
647 for (j = 0; j < vcm->size; j += 32) {
648 int k;
649
650 for (k = 0; k < 32; k++) {
651 int ce = vcm->entry[j + k] >> 4;
652 CMOVE(tmp, (R_COLOR00 + (k << 1)),
653 CM_LTOW(ce));
654 }
655 tmp++;
656 for (k = 0; k < 32; k++) {
657 int ce =vcm->entry[j + k];
658 CMOVE(tmp, (R_COLOR00 + (k << 1)),
659 CM_LTOW(ce));
660 }
661 tmp++;
662 }
663 }
664 }
665 splx(s);
666 return (0);
667 }
668 #endif
669
670 #if defined (GRF_A2024)
671 colormap_t *
cc_a2024_alloc_colormap(int depth)672 cc_a2024_alloc_colormap(int depth)
673 {
674 u_long size = 1U << depth, i;
675 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm));
676
677 if (cm) {
678 cm->type = CM_GREYSCALE;
679 cm->grey_mask = 0x03;
680 cm->first = 0;
681 cm->size = size;
682 cm->entry = (u_long *) & cm[1]; /* table directly after. */
683 for (i = 0; i < size; i++) {
684 cm->entry[i] = CM_WTOL(cc_a2024_default_colors[i]);
685 }
686 return (cm);
687 }
688 return (NULL);
689 }
690
691 int
cc_a2024_get_colormap(view_t * v,colormap_t * cm)692 cc_a2024_get_colormap(view_t *v, colormap_t *cm)
693 {
694 /* there are no differences (yet) in the way the cm's are stored */
695 return (cc_get_colormap(v, cm));
696 }
697
698 int
cc_a2024_use_colormap(view_t * v,colormap_t * cm)699 cc_a2024_use_colormap(view_t *v, colormap_t *cm)
700 {
701 colormap_t *vcm = VDATA(v)->colormap;
702 int s, i;
703
704 if (!cc_colormap_checkvals(vcm, cm, 1)) {
705 return (EINVAL);
706 }
707 /* check to see if its the view's colormap, if so just do update. */
708 if (vcm != cm) {
709 /* copy entries into colormap. */
710 for (i = cm->first; i < (cm->first + cm->size); i++) {
711 vcm->entry[i] = cm->entry[i];
712 }
713 }
714 s = spltty();
715
716 /* is view currently being displayed? */
717 if (VDATA(v)->flags & VF_DISPLAY) {
718 /* yes, update the copper lists */
719 cop_t *tmp, *cp;
720 int nframes = 2, nregs = cm->size == 4 ? 16 : 8, j;
721
722 if (DMDATA(VDATA(v)->mode)->flags & DMF_HEDLEY_EXP) {
723 nframes = 4;
724 }
725 for (i = 0; i < nframes; i++) {
726 cp = DMDATA(VDATA(v)->mode)->frames[i];
727
728 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR07));
729 tmp -= 7;
730
731 for (j = 0; j < nregs; j++) {
732 CMOVE(tmp, (R_COLOR00 + (j << 1)),
733 A2024_CM_TO_CR(vcm, j));
734 }
735 }
736 }
737 splx(s);
738 return (0);
739 }
740 #endif /* GRF_A2024 */
741
742
743 /*
744 * CC View stuff.
745 */
746
747 void
cc_init_view(view_t * v,bmap_t * bm,dmode_t * mode,box_t * dbox)748 cc_init_view(view_t *v, bmap_t *bm, dmode_t *mode, box_t *dbox)
749 {
750 vdata_t *vd = VDATA(v);
751 v->bitmap = bm;
752 vd->mode = mode;
753 memcpy(&v->display, dbox, sizeof(box_t));
754
755 v->display_view = DMDATA(vd->mode)->display_view;
756 v->use_colormap = DMDATA(vd->mode)->use_colormap;
757 v->get_colormap = DMDATA(vd->mode)->get_colormap;
758 v->free_view = cc_free_view;
759 v->get_display_mode = cc_get_display_mode;
760 v->remove_view = cc_remove_view;
761 }
762
763 void
cc_free_view(view_t * v)764 cc_free_view(view_t *v)
765 {
766 if (v) {
767 v->remove_view(v);
768 free_chipmem(VDATA(v)->colormap);
769 cc_monitor->free_bitmap(v->bitmap);
770 free_chipmem(v);
771 }
772 }
773
774 void
cc_remove_view(view_t * v)775 cc_remove_view(view_t *v)
776 {
777 dmode_t *mode = VDATA(v)->mode;
778
779 if (MDATA(cc_monitor)->current_mode == mode) {
780 if (DMDATA(mode)->current_view == v) {
781 cc_load_mode(NULL);
782 }
783 }
784 if (DMDATA(mode)->current_view == v) {
785 DMDATA(mode)->current_view = NULL;
786 }
787 VDATA(v)->flags &= ~VF_DISPLAY;
788 }
789
790 dmode_t *
cc_get_display_mode(view_t * v)791 cc_get_display_mode(view_t *v)
792 {
793 return (VDATA(v)->mode);
794 }
795
796 void
cc_mode_vbl_handler(dmode_t * d)797 cc_mode_vbl_handler(dmode_t *d)
798 {
799 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
800
801 if (vp < 12) {
802 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LONG]);
803 custom.copjmp1 = 0;
804 }
805 }
806
807 void
cc_lace_mode_vbl_handler(dmode_t * d)808 cc_lace_mode_vbl_handler(dmode_t *d)
809 {
810 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
811
812 if (vp < 12) {
813 if (custom.vposr & 0x8000) {
814 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LACE_LONG]);
815 } else {
816 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LACE_SHORT]);
817 }
818 custom.copjmp1 = 0;
819 }
820 }
821
822 /*
823 * Modes. (ick)
824 */
825
826 /*
827 * NTSC Modes
828 */
829
830 #if defined (GRF_NTSC)
831
832 dmode_t *
cc_init_ntsc_hires(void)833 cc_init_ntsc_hires(void)
834 {
835 /* this function should only be called once. */
836 if (!h_this) {
837 u_short len = std_copper_list_len;
838
839 h_this = &hires_mode;
840 h_this_data = &hires_mode_data;
841 memset(h_this, 0, sizeof(dmode_t));
842 memset(h_this_data, 0, sizeof(dmdata_t));
843
844 h_this->name = "ntsc: hires";
845 h_this->nominal_size.width = 640;
846 h_this->nominal_size.height = 200;
847 h_this_data->max_size.width = 724;
848 h_this_data->max_size.height = 242;
849 h_this_data->min_size.width = 320;
850 h_this_data->min_size.height = 100;
851 h_this_data->min_depth = 1;
852 h_this_data->max_depth = 4;
853 h_this->data = h_this_data;
854
855 h_this->get_monitor = cc_get_monitor;
856 h_this->alloc_view = cc_alloc_view;
857 h_this->get_current_view = cc_get_current_view;
858
859 h_this_data->use_colormap = cc_use_colormap;
860 h_this_data->get_colormap = cc_get_colormap;
861 h_this_data->alloc_colormap = cc_alloc_colormap;
862 h_this_data->display_view = display_hires_view;
863 h_this_data->monitor = cc_monitor;
864
865 h_this_data->frames = hires_frames;
866 h_this_data->frames[F_LONG] =
867 alloc_chipmem(std_copper_list_size * F_TOTAL);
868 if (!h_this_data->frames[F_LONG]) {
869 panic("couldn't get chipmem for copper list");
870 }
871 h_this_data->frames[F_STORE_LONG] =
872 &h_this_data->frames[F_LONG][len];
873
874 memcpy(h_this_data->frames[F_STORE_LONG], std_copper_list,
875 std_copper_list_size);
876 memcpy(h_this_data->frames[F_LONG], std_copper_list,
877 std_copper_list_size);
878
879 h_this_data->bplcon0 = 0x8200 | USE_CON3; /* hires, color
880 * composite enable */
881 h_this_data->std_start_x = STANDARD_VIEW_X;
882 h_this_data->std_start_y = STANDARD_VIEW_Y;
883 h_this_data->vbl_handler =
884 (vbl_handler_func *) cc_mode_vbl_handler;
885 #if defined (GRF_ECS) || defined (GRF_AGA)
886 h_this_data->beamcon0 = STANDARD_NTSC_BEAMCON;
887 #endif
888
889 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, h_this, link);
890 }
891 return (h_this);
892 }
893
894 void
display_hires_view(view_t * v)895 display_hires_view(view_t *v)
896 {
897 if (h_this_data->current_view != v) {
898 vdata_t *vd = VDATA(v);
899 cop_t *cp = h_this_data->frames[F_STORE_LONG], *tmp;
900 int depth = v->bitmap->depth, i;
901 int hstart, hstop, vstart, vstop, j;
902 int x, y, w = v->display.width, h = v->display.height;
903 u_short ddfstart, ddfwidth, con1;
904
905 /* round down to nearest even width */
906 /* w &= 0xfffe; */
907 /* calculate datafetch width. */
908
909 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
910
911 /* This will center the any overscanned display */
912 /* and allow user to modify. */
913 x = v->display.x + h_this_data->std_start_x - ((w - 640) >> 2);
914 y = v->display.y + h_this_data->std_start_y - ((h - 200) >> 1);
915
916 if (y & 1)
917 y--;
918
919 if (!(x & 1))
920 x--;
921
922 hstart = x;
923 hstop = x + (w >> 1);
924 vstart = y;
925 vstop = y + h;
926 ddfstart = (hstart - 9) >> 1;
927
928 /* check for hardware limits, AGA may allow more..? */
929 /* anyone got a 4000 I can borrow :^) -ch */
930 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
931 int d = 0;
932
933 /* XXX anyone know the equality properties of
934 * intermixed logical AND's */
935 /* XXX and arithmetic operators? */
936 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
937 d++;
938 }
939
940 ddfstart -= d;
941 hstart -= d << 1;
942 hstop -= d << 1;
943 }
944 /* correct the datafetch to proper limits. */
945 /* delay the actual display of the data until we need it. */
946 ddfstart &= 0xfffc;
947 con1 = ((hstart - 9) - (ddfstart << 1)) |
948 (((hstart - 9) - (ddfstart << 1)) << 4);
949
950 if (h_this_data->current_view) {
951 VDATA(h_this_data->current_view)->flags &=
952 ~VF_DISPLAY; /* mark as no longer displayed. */
953 }
954 h_this_data->current_view = v;
955
956 cp = h_this_data->frames[F_STORE_LONG];
957 #if defined (GRF_ECS) || defined (GRF_AGA)
958 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON3));
959 tmp->cp.inst.operand = 0x0020;
960 #if defined (GRF_AGA)
961 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
962 tmp->cp.inst.operand = 0;
963 #endif
964 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
965 tmp->cp.inst.operand = h_this_data->beamcon0;
966 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
967 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
968 #endif /* ECS */
969 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
970 tmp->cp.inst.operand = h_this_data->bplcon0 | ((depth & 0x7) << 12);
971 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
972 tmp->cp.inst.operand = con1;
973 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
974 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
975 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
976 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
977 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
978 tmp->cp.inst.operand = ddfstart;
979 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
980 tmp->cp.inst.operand = ddfstart + ddfwidth;
981
982 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
983 for (i = 0, j = 0; i < depth; j += 2, i++) {
984 /* update the plane pointers */
985 tmp[j].cp.inst.operand =
986 HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
987 tmp[j + 1].cp.inst.operand =
988 LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
989 }
990
991 /* set mods correctly. */
992 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
993 tmp[0].cp.inst.operand = v->bitmap->row_mod;
994 tmp[1].cp.inst.operand = v->bitmap->row_mod;
995
996 /* set next pointers correctly */
997 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
998 tmp[0].cp.inst.operand =
999 HIADDR(PREP_DMA_MEM(h_this_data->frames[F_STORE_LONG]));
1000 tmp[1].cp.inst.operand =
1001 LOADDR(PREP_DMA_MEM(h_this_data->frames[F_STORE_LONG]));
1002
1003 cp = h_this_data->frames[F_LONG];
1004 h_this_data->frames[F_LONG] = h_this_data->frames[F_STORE_LONG];
1005 h_this_data->frames[F_STORE_LONG] = cp;
1006
1007 vd->flags |= VF_DISPLAY;
1008
1009 cc_use_colormap(v, vd->colormap);
1010 }
1011 cc_load_mode(h_this);
1012 }
1013
1014 dmode_t *
cc_init_ntsc_hires_lace(void)1015 cc_init_ntsc_hires_lace(void)
1016 {
1017 /* this function should only be called once. */
1018 if (!hl_this) {
1019 u_short len = std_copper_list_len;
1020
1021 hl_this = &hires_lace_mode;
1022 hl_this_data = &hires_lace_mode_data;
1023 memset(hl_this, 0, sizeof(dmode_t));
1024 memset(hl_this_data, 0, sizeof(dmdata_t));
1025
1026 hl_this->name = "ntsc: hires interlace";
1027 hl_this->nominal_size.width = 640;
1028 hl_this->nominal_size.height = 400;
1029 hl_this_data->max_size.width = 724;
1030 hl_this_data->max_size.height = 482;
1031 hl_this_data->min_size.width = 320;
1032 hl_this_data->min_size.height = 200;
1033 hl_this_data->min_depth = 1;
1034 hl_this_data->max_depth = 4;
1035 hl_this->data = hl_this_data;
1036
1037 hl_this->get_monitor = cc_get_monitor;
1038 hl_this->alloc_view = cc_alloc_view;
1039 hl_this->get_current_view = cc_get_current_view;
1040
1041 hl_this_data->use_colormap = cc_use_colormap;
1042 hl_this_data->get_colormap = cc_get_colormap;
1043 hl_this_data->alloc_colormap = cc_alloc_colormap;
1044 hl_this_data->display_view = display_hires_lace_view;
1045 hl_this_data->monitor = cc_monitor;
1046
1047 hl_this_data->flags |= DMF_INTERLACE;
1048
1049 hl_this_data->frames = hires_lace_frames;
1050 hl_this_data->frames[F_LACE_LONG] =
1051 alloc_chipmem(std_copper_list_size * F_LACE_TOTAL);
1052 if (!hl_this_data->frames[F_LACE_LONG]) {
1053 panic("couldn't get chipmem for copper list");
1054 }
1055 hl_this_data->frames[F_LACE_SHORT] =
1056 &hl_this_data->frames[F_LACE_LONG][len];
1057 hl_this_data->frames[F_LACE_STORE_LONG] =
1058 &hl_this_data->frames[F_LACE_SHORT][len];
1059 hl_this_data->frames[F_LACE_STORE_SHORT] =
1060 &hl_this_data->frames[F_LACE_STORE_LONG][len];
1061
1062 memcpy(hl_this_data->frames[F_LACE_STORE_LONG], std_copper_list,
1063 std_copper_list_size);
1064 memcpy(hl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list,
1065 std_copper_list_size);
1066 memcpy(hl_this_data->frames[F_LACE_LONG], std_copper_list,
1067 std_copper_list_size);
1068 memcpy(hl_this_data->frames[F_LACE_SHORT], std_copper_list,
1069 std_copper_list_size);
1070
1071 hl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
1072 * composite enable,
1073 * lace. */
1074 hl_this_data->std_start_x = STANDARD_VIEW_X;
1075 hl_this_data->std_start_y = STANDARD_VIEW_Y;
1076 hl_this_data->vbl_handler =
1077 (vbl_handler_func *) cc_lace_mode_vbl_handler;
1078 #if defined (GRF_ECS) || defined (GRF_AGA)
1079 hl_this_data->beamcon0 = STANDARD_NTSC_BEAMCON;
1080 #endif
1081
1082 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, hl_this, link);
1083 }
1084 return (hl_this);
1085 }
1086
1087 void
display_hires_lace_view(view_t * v)1088 display_hires_lace_view(view_t *v)
1089 {
1090 if (hl_this_data->current_view != v) {
1091 vdata_t *vd = VDATA(v);
1092 cop_t *cp = hl_this_data->frames[F_LACE_STORE_LONG], *tmp;
1093 int depth = v->bitmap->depth, i;
1094 int hstart, hstop, vstart, vstop, j;
1095 int x, y, w = v->display.width, h = v->display.height;
1096 u_short ddfstart, ddfwidth, con1;
1097
1098 /* round down to nearest even width */
1099 /* w &= 0xfffe; */
1100
1101
1102 /* calculate datafetch width. */
1103
1104 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
1105
1106 /* This will center the any overscanned display */
1107 /* and allow user to modify. */
1108 x = v->display.x + hl_this_data->std_start_x - ((w - 640) >> 2);
1109 y = v->display.y + hl_this_data->std_start_y - ((h - 400) >> 2);
1110
1111 if (y & 1)
1112 y--;
1113
1114 if (!(x & 1))
1115 x--;
1116
1117 hstart = x;
1118 hstop = x + (w >> 1);
1119 vstart = y;
1120 vstop = y + (h >> 1);
1121 ddfstart = (hstart - 9) >> 1;
1122
1123 /* check for hardware limits, AGA may allow more..? */
1124 /* anyone got a 4000 I can borrow :^) -ch */
1125 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
1126 int d = 0;
1127
1128 /* XXX anyone know the equality properties of
1129 * intermixed logial AND's */
1130 /* XXX and arithmetic operators? */
1131 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
1132 d++;
1133 }
1134
1135 ddfstart -= d;
1136 hstart -= d << 1;
1137 hstop -= d << 1;
1138 }
1139 /* correct the datafetch to proper limits. */
1140 /* delay the actual display of the data until we need it. */
1141 ddfstart &= 0xfffc;
1142 con1 = ((hstart - 9) - (ddfstart << 1)) |
1143 (((hstart - 9) - (ddfstart << 1)) << 4);
1144
1145 if (hl_this_data->current_view) {
1146 VDATA(hl_this_data->current_view)->flags &=
1147 ~VF_DISPLAY; /* mark as no longer displayed. */
1148 }
1149 hl_this_data->current_view = v;
1150
1151 cp = hl_this_data->frames[F_LACE_STORE_LONG];
1152 #if defined (GRF_ECS) || defined (GRF_AGA)
1153 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON3));
1154 tmp->cp.inst.operand = 0x0020;
1155 #if defined (GRF_AGA)
1156 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
1157 tmp->cp.inst.operand = 0;
1158 #endif
1159 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
1160 tmp->cp.inst.operand = hl_this_data->beamcon0;
1161 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
1162 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
1163 #endif /* ECS */
1164 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
1165 tmp->cp.inst.operand = hl_this_data->bplcon0 | ((depth & 0x7) << 12);
1166 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
1167 tmp->cp.inst.operand = con1;
1168 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
1169 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
1170 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
1171 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
1172 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
1173 tmp->cp.inst.operand = ddfstart;
1174 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
1175 tmp->cp.inst.operand = ddfstart + ddfwidth;
1176
1177 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1178 for (i = 0, j = 0; i < depth; j += 2, i++) {
1179 /* update the plane pointers */
1180 tmp[j].cp.inst.operand =
1181 HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
1182 tmp[j + 1].cp.inst.operand =
1183 LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
1184 }
1185
1186 /* set mods correctly. */
1187 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
1188 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1189 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1190
1191 /* set next pointers correctly */
1192 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1193 tmp[0].cp.inst.operand =
1194 HIADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_SHORT]));
1195 tmp[1].cp.inst.operand =
1196 LOADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_SHORT]));
1197
1198
1199 bcopy(hl_this_data->frames[F_LACE_STORE_LONG],
1200 hl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size);
1201
1202 /* these are the only ones that are different from long frame. */
1203 cp = hl_this_data->frames[F_LACE_STORE_SHORT];
1204 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1205 for (i = 0, j = 0; i < depth; j += 2, i++) {
1206 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1207 /* update plane pointers. high and low. */
1208 tmp[j].cp.inst.operand =
1209 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
1210 tmp[j + 1].cp.inst.operand =
1211 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
1212 }
1213
1214 /* set next pointers correctly */
1215 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1216 tmp[0].cp.inst.operand =
1217 HIADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_LONG]));
1218 tmp[1].cp.inst.operand =
1219 LOADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_LONG]));
1220
1221
1222 cp = hl_this_data->frames[F_LACE_LONG];
1223 hl_this_data->frames[F_LACE_LONG] =
1224 hl_this_data->frames[F_LACE_STORE_LONG];
1225 hl_this_data->frames[F_LACE_STORE_LONG] = cp;
1226
1227 cp = hl_this_data->frames[F_LACE_SHORT];
1228 hl_this_data->frames[F_LACE_SHORT] =
1229 hl_this_data->frames[F_LACE_STORE_SHORT];
1230 hl_this_data->frames[F_LACE_STORE_SHORT] = cp;
1231
1232 vd->flags |= VF_DISPLAY;
1233
1234 cc_use_colormap(v, vd->colormap);
1235 }
1236 cc_load_mode(hl_this);
1237 }
1238 #if defined (GRF_A2024)
1239
1240 dmode_t *
cc_init_ntsc_hires_dlace(void)1241 cc_init_ntsc_hires_dlace(void)
1242 {
1243 /* this function should only be called once. */
1244 if (!hdl_this) {
1245 u_short len = std_dlace_copper_list_len;
1246
1247 hdl_this = &hires_dlace_mode;
1248 hdl_this_data = &hires_dlace_mode_data;
1249 memset(hdl_this, 0, sizeof(dmode_t));
1250 memset(hdl_this_data, 0, sizeof(dmdata_t));
1251
1252 hdl_this->name = "ntsc: hires double interlace";
1253 hdl_this->nominal_size.width = 640;
1254 hdl_this->nominal_size.height = 800;
1255 hdl_this_data->max_size.width = 724;
1256 hdl_this_data->max_size.height = 800;
1257 hdl_this_data->min_size.width = 320;
1258 hdl_this_data->min_size.height = 400;
1259 hdl_this_data->min_depth = 1;
1260 hdl_this_data->max_depth = 2;
1261 hdl_this->data = hdl_this_data;
1262
1263 hdl_this->get_monitor = cc_get_monitor;
1264 hdl_this->alloc_view = cc_alloc_view;
1265 hdl_this->get_current_view = cc_get_current_view;
1266
1267 hdl_this_data->use_colormap = cc_a2024_use_colormap;
1268 hdl_this_data->get_colormap = cc_a2024_get_colormap;
1269 hdl_this_data->alloc_colormap = cc_a2024_alloc_colormap;
1270 hdl_this_data->display_view = display_hires_dlace_view;
1271 hdl_this_data->monitor = cc_monitor;
1272
1273 hdl_this_data->flags |= DMF_INTERLACE;
1274
1275 hdl_this_data->frames = hires_dlace_frames;
1276 hdl_this_data->frames[F_LACE_LONG] =
1277 alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL);
1278 if (!hdl_this_data->frames[F_LACE_LONG]) {
1279 panic("couldn't get chipmem for copper list");
1280 }
1281 hdl_this_data->frames[F_LACE_SHORT] =
1282 &hdl_this_data->frames[F_LACE_LONG][len];
1283 hdl_this_data->frames[F_LACE_STORE_LONG] =
1284 &hdl_this_data->frames[F_LACE_SHORT][len];
1285 hdl_this_data->frames[F_LACE_STORE_SHORT] =
1286 &hdl_this_data->frames[F_LACE_STORE_LONG][len];
1287
1288 bcopy(std_dlace_copper_list,
1289 hdl_this_data->frames[F_LACE_STORE_LONG],
1290 std_dlace_copper_list_size);
1291 bcopy(std_dlace_copper_list,
1292 hdl_this_data->frames[F_LACE_STORE_SHORT],
1293 std_dlace_copper_list_size);
1294 bcopy(std_dlace_copper_list,
1295 hdl_this_data->frames[F_LACE_LONG],
1296 std_dlace_copper_list_size);
1297 bcopy(std_dlace_copper_list,
1298 hdl_this_data->frames[F_LACE_SHORT],
1299 std_dlace_copper_list_size);
1300
1301 hdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
1302 * composite enable,
1303 * dlace. */
1304 hdl_this_data->std_start_x = STANDARD_VIEW_X;
1305 hdl_this_data->std_start_y = STANDARD_VIEW_Y;
1306 hdl_this_data->vbl_handler =
1307 (vbl_handler_func *) cc_lace_mode_vbl_handler;
1308 #if defined (GRF_ECS) || defined (GRF_AGA)
1309 hdl_this_data->beamcon0 = STANDARD_NTSC_BEAMCON;
1310 #endif
1311 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, hdl_this, link);
1312 }
1313 return (hdl_this);
1314 }
1315
1316 void
display_hires_dlace_view(view_t * v)1317 display_hires_dlace_view(view_t *v)
1318 {
1319 if (hdl_this_data->current_view != v) {
1320 vdata_t *vd = VDATA(v);
1321 cop_t *cp = hdl_this_data->frames[F_LACE_STORE_LONG], *tmp;
1322 int depth = v->bitmap->depth;
1323 int hstart, hstop, vstart, vstop;
1324 int x, y, w = v->display.width, h = v->display.height;
1325 u_short ddfstart, ddfwidth, con1;
1326 u_short mod1l, mod2l;
1327
1328 /* round down to nearest even width */
1329 /* w &= 0xfffe; */
1330
1331 /* calculate datafetch width. */
1332
1333 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
1334
1335 /* This will center the any overscanned display */
1336 /* and allow user to modify. */
1337 x = v->display.x + hdl_this_data->std_start_x - ((w - 640) >> 2);
1338 y = v->display.y + hdl_this_data->std_start_y - ((h - 800) >> 3);
1339
1340 if (y & 1)
1341 y--;
1342
1343 if (!(x & 1))
1344 x--;
1345
1346 hstart = x;
1347 hstop = x + (w >> 1);
1348 vstart = y;
1349 vstop = y + (h >> 2);
1350
1351 ddfstart = (hstart - 9) >> 1;
1352
1353 /* check for hardware limits, AGA may allow more..? */
1354 /* anyone got a 4000 I can borrow :^) -ch */
1355 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
1356 int d = 0;
1357
1358 /* XXX anyone know the equality properties of
1359 * intermixed logial AND's */
1360 /* XXX and arithmetic operators? */
1361 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
1362 d++;
1363 }
1364
1365 ddfstart -= d;
1366 hstart -= d << 1;
1367 hstop -= d << 1;
1368 }
1369 /* correct the datafetch to proper limits. */
1370 /* delay the actual display of the data until we need it. */
1371 ddfstart &= 0xfffc;
1372 con1 = ((hstart - 9) - (ddfstart << 1)) |
1373 (((hstart - 9) - (ddfstart << 1)) << 4);
1374
1375 if (hdl_this_data->current_view) {
1376 VDATA(hdl_this_data->current_view)->flags &=
1377 ~VF_DISPLAY; /* mark as no longer displayed. */
1378 }
1379 hdl_this_data->current_view = v;
1380
1381 cp = hdl_this_data->frames[F_LACE_STORE_LONG];
1382 #if defined (GRF_ECS) || defined (GRF_AGA)
1383 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON3));
1384 tmp->cp.inst.operand = 0x0020;
1385 #if defined (GRF_AGA)
1386 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
1387 tmp->cp.inst.operand = 0;
1388 #endif
1389 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
1390 tmp->cp.inst.operand = hdl_this_data->beamcon0;
1391 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
1392 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
1393 #endif /* ECS */
1394 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
1395 tmp->cp.inst.operand =
1396 hdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */
1397 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
1398 tmp->cp.inst.operand = con1;
1399 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
1400 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
1401 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
1402 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
1403 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
1404 tmp->cp.inst.operand = ddfstart;
1405 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
1406 tmp->cp.inst.operand = ddfstart + ddfwidth;
1407
1408 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1409 mod2l = mod1l << 1;
1410
1411 /* update plane pointers. */
1412 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1413 tmp[0].cp.inst.operand =
1414 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0]));
1415 tmp[1].cp.inst.operand =
1416 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0]));
1417 tmp[2].cp.inst.operand =
1418 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l]));
1419 tmp[3].cp.inst.operand =
1420 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l]));
1421 if (depth == 2) {
1422 tmp[4].cp.inst.operand =
1423 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0]));
1424 tmp[5].cp.inst.operand =
1425 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0]));
1426 tmp[6].cp.inst.operand =
1427 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l]));
1428 tmp[7].cp.inst.operand =
1429 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l]));
1430 }
1431 /* set modulos. */
1432 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
1433 tmp[0].cp.inst.operand = mod2l + mod1l;
1434 tmp[1].cp.inst.operand = mod2l + mod1l;
1435
1436
1437 /* set next coper list pointers */
1438 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1439 tmp[0].cp.inst.operand =
1440 HIADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_SHORT]));
1441 tmp[1].cp.inst.operand =
1442 LOADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_SHORT]));
1443
1444 bcopy(hdl_this_data->frames[F_LACE_STORE_LONG],
1445 hdl_this_data->frames[F_LACE_STORE_SHORT],
1446 std_dlace_copper_list_size);
1447
1448 /* these are the only ones that are different from long frame. */
1449 cp = hdl_this_data->frames[F_LACE_STORE_SHORT];
1450 /* update plane pointers. */
1451 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1452 tmp[0].cp.inst.operand =
1453 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l]));
1454 tmp[1].cp.inst.operand =
1455 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l]));
1456 tmp[2].cp.inst.operand =
1457 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l]));
1458 tmp[3].cp.inst.operand =
1459 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l]));
1460 if (depth == 2) {
1461 tmp[4].cp.inst.operand =
1462 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l]));
1463 tmp[5].cp.inst.operand =
1464 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l]));
1465 tmp[6].cp.inst.operand =
1466 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l]));
1467 tmp[7].cp.inst.operand =
1468 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l]));
1469 }
1470 /* set next copper list pointers */
1471 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1472 tmp[0].cp.inst.operand =
1473 HIADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_LONG]));
1474 tmp[1].cp.inst.operand =
1475 LOADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_LONG]));
1476
1477 cp = hdl_this_data->frames[F_LACE_LONG];
1478 hdl_this_data->frames[F_LACE_LONG] =
1479 hdl_this_data->frames[F_LACE_STORE_LONG];
1480 hdl_this_data->frames[F_LACE_STORE_LONG] = cp;
1481
1482 cp = hdl_this_data->frames[F_LACE_SHORT];
1483 hdl_this_data->frames[F_LACE_SHORT] =
1484 hdl_this_data->frames[F_LACE_STORE_SHORT];
1485 hdl_this_data->frames[F_LACE_STORE_SHORT] = cp;
1486
1487 vd->flags |= VF_DISPLAY;
1488 cc_a2024_use_colormap(v, vd->colormap);
1489 }
1490 cc_load_mode(hdl_this);
1491 }
1492
1493
1494 dmode_t *
cc_init_ntsc_a2024(void)1495 cc_init_ntsc_a2024(void)
1496 {
1497 /* this function should only be called once. */
1498 if (!a24_this) {
1499 int i;
1500 u_short len = std_a2024_copper_list_len;
1501 cop_t *cp;
1502
1503 a24_this = &a2024_mode;
1504 a24_this_data = &a2024_mode_data;
1505 memset(a24_this, 0, sizeof(dmode_t));
1506 memset(a24_this_data, 0, sizeof(dmdata_t));
1507
1508 a24_this->name = "ntsc: A2024 15 kHz";
1509 a24_this->nominal_size.width = 1024;
1510 a24_this->nominal_size.height = 800;
1511 a24_this_data->max_size.width = 1024;
1512 a24_this_data->max_size.height = 800;
1513 a24_this_data->min_size.width = 1024;
1514 a24_this_data->min_size.height = 800;
1515 a24_this_data->min_depth = 1;
1516 a24_this_data->max_depth = 2;
1517 a24_this->data = a24_this_data;
1518
1519 a24_this->get_monitor = cc_get_monitor;
1520 a24_this->alloc_view = cc_alloc_view;
1521 a24_this->get_current_view = cc_get_current_view;
1522
1523 a24_this_data->use_colormap = cc_a2024_use_colormap;
1524 a24_this_data->get_colormap = cc_a2024_get_colormap;
1525 a24_this_data->display_view = display_a2024_view;
1526 a24_this_data->alloc_colormap = cc_a2024_alloc_colormap;
1527 a24_this_data->monitor = cc_monitor;
1528
1529 a24_this_data->flags |= DMF_HEDLEY_EXP;
1530
1531 a24_this_data->frames = a2024_frames;
1532 a24_this_data->frames[F_QD_QUAD0] =
1533 alloc_chipmem(std_a2024_copper_list_size * F_QD_TOTAL);
1534 if (!a24_this_data->frames[F_QD_QUAD0]) {
1535 panic("couldn't get chipmem for copper list");
1536 }
1537 /* setup the hedley init bitplane. */
1538 hedley_init = alloc_chipmem(128);
1539 if (!hedley_init) {
1540 panic("couldn't get chipmem for hedley init bitplane");
1541 }
1542 for (i = 1; i < 128; i++)
1543 hedley_init[i] = 0xff;
1544 hedley_init[0] = 0x03;
1545
1546 /* copy image of standard copper list. */
1547 memcpy(a24_this_data->frames[0], std_a2024_copper_list,
1548 std_a2024_copper_list_size);
1549
1550 /* set the init plane pointer. */
1551 cp = find_copper_inst(a24_this_data->frames[F_QD_QUAD0],
1552 CI_MOVE(R_BPL0PTH));
1553 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init));
1554 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init));
1555
1556 for (i = 1; i < F_QD_TOTAL; i++) {
1557 a24_this_data->frames[i] = &a24_this_data->frames[i - 1][len];
1558 bcopy(a24_this_data->frames[0],
1559 a24_this_data->frames[i],
1560 std_a2024_copper_list_size);
1561 }
1562
1563 a24_this_data->bplcon0 = 0x8200; /* hires */
1564 a24_this_data->vbl_handler =
1565 (vbl_handler_func *) a2024_mode_vbl_handler;
1566
1567
1568 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, a24_this, link);
1569 }
1570 return (a24_this);
1571 }
1572
1573 void
display_a2024_view(view_t * v)1574 display_a2024_view(view_t *v)
1575 {
1576 if (a24_this_data->current_view != v) {
1577 vdata_t *vd = VDATA(v);
1578 cop_t *cp, *tmp;
1579 u_char *inst_plane[2] = { NULL, NULL };
1580 u_char **plane = inst_plane;
1581 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1582 u_long half_plane = full_line * v->bitmap->rows / 2;
1583
1584 int depth = v->bitmap->depth, i, j;
1585
1586 plane[0] = v->bitmap->plane[0];
1587 if (depth == 2) {
1588 plane[1] = v->bitmap->plane[1];
1589 }
1590 if (a24_this_data->current_view) {
1591 VDATA(a24_this_data->current_view)->flags &=
1592 ~VF_DISPLAY; /* mark as no longer displayed. */
1593 }
1594 cp = a24_this_data->frames[F_QD_STORE_QUAD0];
1595 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F));
1596 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */
1597 tmp->cp.inst.operand = a24_this_data->bplcon0 |
1598 ((depth & 0x7) << 13); /* times 2 */
1599
1600 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0],
1601 a24_this_data->frames[F_QD_STORE_QUAD1],
1602 std_a2024_copper_list_size);
1603 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0],
1604 a24_this_data->frames[F_QD_STORE_QUAD2],
1605 std_a2024_copper_list_size);
1606 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0],
1607 a24_this_data->frames[F_QD_STORE_QUAD3],
1608 std_a2024_copper_list_size);
1609
1610 /*
1611 * Mark Id's
1612 */
1613 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD1],
1614 CI_WAIT(126, 21));
1615 CBUMP(tmp);
1616 CMOVE(tmp, R_COLOR01, QUAD1_ID);
1617 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD2],
1618 CI_WAIT(126, 21));
1619 CBUMP(tmp);
1620 CMOVE(tmp, R_COLOR01, QUAD2_ID);
1621 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD3],
1622 CI_WAIT(126, 21));
1623 CBUMP(tmp);
1624 CMOVE(tmp, R_COLOR01, QUAD3_ID);
1625
1626 plane[0]--;
1627 plane[0]--;
1628 if (depth == 2) {
1629 plane[1]--;
1630 plane[1]--;
1631 }
1632 /*
1633 * Set bitplane pointers.
1634 */
1635 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD0],
1636 CI_MOVE(R_BPLMOD2));
1637 CBUMP(tmp);
1638 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0])));
1639 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0])));
1640 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line])));
1641 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line])));
1642 if (depth == 2) {
1643 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0])));
1644 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0])));
1645 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line])));
1646 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line])));
1647 }
1648 #if defined (GRF_ECS) || defined (GRF_AGA)
1649 CMOVE(tmp, R_DIWHIGH, 0x2000);
1650 #endif
1651 CMOVE(tmp, R_COP1LCH,
1652 HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD1])));
1653 CMOVE(tmp, R_COP1LCL,
1654 LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD1])));
1655 CEND(tmp);
1656 CEND(tmp);
1657
1658 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD1],
1659 CI_MOVE(R_BPLMOD2));
1660 CBUMP(tmp);
1661 CMOVE(tmp, R_BPL0PTH,
1662 HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
1663 CMOVE(tmp, R_BPL0PTL,
1664 LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
1665 CMOVE(tmp, R_BPL1PTH,
1666 HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
1667 CMOVE(tmp, R_BPL1PTL,
1668 LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
1669 if (depth == 2) {
1670 CMOVE(tmp, R_BPL2PTH,
1671 HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
1672 CMOVE(tmp, R_BPL2PTL,
1673 LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
1674 CMOVE(tmp, R_BPL3PTH,
1675 HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
1676 CMOVE(tmp, R_BPL3PTL,
1677 LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
1678 }
1679 #if defined (GRF_ECS) || defined (GRF_AGA)
1680 CMOVE(tmp, R_DIWHIGH, 0x2000);
1681 #endif
1682 CMOVE(tmp, R_COP1LCH,
1683 HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD2])));
1684 CMOVE(tmp, R_COP1LCL,
1685 LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD2])));
1686 CEND(tmp);
1687 CEND(tmp);
1688
1689 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD2],
1690 CI_MOVE(R_BPLMOD2));
1691 CBUMP(tmp);
1692 CMOVE(tmp, R_BPL0PTH,
1693 HIADDR(PREP_DMA_MEM(&plane[0][half_plane])));
1694 CMOVE(tmp, R_BPL0PTL,
1695 LOADDR(PREP_DMA_MEM(&plane[0][half_plane])));
1696 CMOVE(tmp, R_BPL1PTH,
1697 HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
1698 CMOVE(tmp, R_BPL1PTL,
1699 LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
1700 if (depth == 2) {
1701 CMOVE(tmp, R_BPL2PTH,
1702 HIADDR(PREP_DMA_MEM(&plane[1][half_plane])));
1703 CMOVE(tmp, R_BPL2PTL,
1704 LOADDR(PREP_DMA_MEM(&plane[1][half_plane])));
1705 CMOVE(tmp, R_BPL3PTH,
1706 HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
1707 CMOVE(tmp, R_BPL3PTL,
1708 LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
1709 }
1710 #if defined (GRF_ECS) || defined (GRF_AGA)
1711 CMOVE(tmp, R_DIWHIGH, 0x2000);
1712 #endif
1713 CMOVE(tmp, R_COP1LCH,
1714 HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD3])));
1715 CMOVE(tmp, R_COP1LCL,
1716 LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD3])));
1717 CEND(tmp);
1718 CEND(tmp);
1719
1720 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD3],
1721 CI_MOVE(R_BPLMOD2));
1722 CBUMP(tmp);
1723 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(
1724 &plane[0][half_plane + HALF_2024_LINE])));
1725 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(
1726 &plane[0][half_plane + HALF_2024_LINE])));
1727 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(
1728 &plane[0][half_plane + full_line + HALF_2024_LINE])));
1729 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(
1730 &plane[0][half_plane + full_line + HALF_2024_LINE])));
1731 if (depth == 2) {
1732 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(
1733 &plane[1][half_plane + HALF_2024_LINE])));
1734 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(
1735 &plane[1][half_plane + HALF_2024_LINE])));
1736 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(
1737 &plane[1][half_plane + full_line + HALF_2024_LINE])));
1738 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(
1739 &plane[1][half_plane + full_line + HALF_2024_LINE])));
1740 }
1741 #if defined (GRF_ECS) || defined (GRF_AGA)
1742 CMOVE(tmp, R_DIWHIGH, 0x2000);
1743 #endif
1744 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(
1745 a24_this_data->frames[F_QD_STORE_QUAD0])));
1746 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(
1747 a24_this_data->frames[F_QD_STORE_QUAD0])));
1748 CEND(tmp);
1749 CEND(tmp);
1750
1751 /* swap new pointers in. */
1752 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0;
1753 i <= F_QD_STORE_QUAD3; i++, j++) {
1754 cp = a24_this_data->frames[j];
1755 a24_this_data->frames[j] = a24_this_data->frames[i];
1756 a24_this_data->frames[i] = cp;
1757 }
1758
1759 a24_this_data->current_view = v;
1760 vd->flags |= VF_DISPLAY;
1761
1762 cc_a2024_use_colormap(v, vd->colormap);
1763 }
1764 cc_load_mode(a24_this);
1765 }
1766
1767 void
a2024_mode_vbl_handler(dmode_t * d)1768 a2024_mode_vbl_handler(dmode_t *d)
1769 {
1770 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
1771
1772 if (vp < 12) {
1773 custom.cop1lc =
1774 PREP_DMA_MEM(a24_this_data->frames[a24_this_data->hedley_current]);
1775 custom.copjmp1 = 0;
1776 }
1777 a24_this_data->hedley_current++;
1778 a24_this_data->hedley_current &= 0x3; /* if 4 then 0. */
1779 }
1780 #endif /* GRF_A2024 */
1781
1782 #if defined (GRF_AGA)
1783
1784 dmode_t *
cc_init_ntsc_aga(void)1785 cc_init_ntsc_aga(void)
1786 {
1787 /* this function should only be called once. */
1788 if (!aga_this && (custom.deniseid & 0xff) == 0xf8 &&
1789 aga_enable & AGA_ENABLE) {
1790 u_short len = aga_copper_list_len;
1791
1792 aga_this = &aga_mode;
1793 aga_this_data = &aga_mode_data;
1794 memset(aga_this, 0, sizeof(dmode_t));
1795 memset(aga_this_data, 0, sizeof(dmdata_t));
1796
1797 aga_this->name = "ntsc: AGA dbl";
1798 aga_this->nominal_size.width = 640;
1799 aga_this->nominal_size.height = 400;
1800 aga_this_data->max_size.width = 724;
1801 aga_this_data->max_size.height = 482;
1802 aga_this_data->min_size.width = 320;
1803 aga_this_data->min_size.height = 200;
1804 aga_this_data->min_depth = 1;
1805 aga_this_data->max_depth = 8;
1806 aga_this->data = aga_this_data;
1807
1808 aga_this->get_monitor = cc_get_monitor;
1809 aga_this->alloc_view = cc_alloc_view;
1810 aga_this->get_current_view = cc_get_current_view;
1811
1812 aga_this_data->use_colormap = cc_use_aga_colormap;
1813 aga_this_data->get_colormap = cc_get_colormap;
1814 aga_this_data->alloc_colormap = cc_alloc_aga_colormap;
1815 aga_this_data->display_view = display_aga_view;
1816 aga_this_data->monitor = cc_monitor;
1817
1818 aga_this_data->frames = aga_frames;
1819 aga_this_data->frames[F_LONG] = alloc_chipmem(aga_copper_list_size * F_TOTAL);
1820 if (!aga_this_data->frames[F_LONG]) {
1821 panic("couldn't get chipmem for copper list");
1822 }
1823 aga_this_data->frames[F_STORE_LONG] = &aga_this_data->frames[F_LONG][len];
1824
1825 memcpy(aga_this_data->frames[F_STORE_LONG], aga_copper_list, aga_copper_list_size);
1826 memcpy(aga_this_data->frames[F_LONG], aga_copper_list, aga_copper_list_size);
1827
1828 aga_this_data->bplcon0 = 0x0240 | USE_CON3; /* color composite
1829 * enable,
1830 * shres. */
1831 #ifdef GRF_AGA_VGA
1832 aga_this_data->std_start_x = 0x40 /*STANDARD_VIEW_X*/;
1833 #else
1834 aga_this_data->std_start_x = 0x4f /*STANDARD_VIEW_X*/;
1835 #endif
1836 aga_this_data->std_start_y = 0x2b /*STANDARD_VIEW_Y*/;
1837 aga_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler;
1838 aga_this_data->beamcon0 = SPECIAL_BEAMCON ^ VSYNCTRUE;
1839
1840 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes,
1841 aga_this, link);
1842 }
1843 return (aga_this);
1844 }
1845
1846 /* static, so I can patch and play */
1847
1848 #ifdef GRF_AGA_VGA
1849 int AGA_htotal = 0x71;
1850 int AGA_hsstrt = 0xc;
1851 int AGA_hsstop = 0x16;
1852 int AGA_hbstrt = 0x5;
1853 int AGA_vtotal = 0x1c1;
1854 #else
1855 int AGA_htotal = 0x79;
1856 int AGA_hsstrt = 0xe;
1857 int AGA_hsstop = 0x1c;
1858 int AGA_hbstrt = 0x8;
1859 int AGA_vtotal = 0x1ec;
1860 #endif
1861 int AGA_hbstop = 0x1e;
1862 int AGA_vsstrt = 0x3;
1863 int AGA_vsstop = 0x6;
1864 int AGA_vbstrt = 0x0;
1865 int AGA_vbstop = 0x19;
1866 int AGA_hcenter = 0x4a;
1867
1868 void
display_aga_view(view_t * v)1869 display_aga_view(view_t *v)
1870 {
1871 if (aga_this_data->current_view != v) {
1872 vdata_t *vd = VDATA(v);
1873 cop_t *cp = aga_this_data->frames[F_STORE_LONG], *tmp;
1874 int depth = v->bitmap->depth, i;
1875 int hstart, hstop, vstart, vstop, j;
1876 int x, y, w = v->display.width, h = v->display.height;
1877 u_short ddfstart, ddfwidth, con1;
1878
1879 #ifdef DEBUG
1880 if (aga_enable & AGA_TRACE)
1881 printf("display_aga_view(%dx%dx%d) %p\n", w, h,
1882 depth, v);
1883 #endif
1884 /* round down to nearest even width */
1885 /* w &= 0xfffe; */
1886 /* calculate datafetch width. */
1887
1888 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 4) << 1;
1889
1890 /* this will center the any overscanned display */
1891 /* and allow user to modify. */
1892 x = v->display.x + aga_this_data->std_start_x - ((w - 640) >> 3);
1893 y = v->display.y + aga_this_data->std_start_y - ((h - 400) >> 1);
1894
1895 if (y & 1)
1896 y--;
1897
1898 if (!(x & 1))
1899 x--;
1900
1901 hstart = x;
1902 hstop = x + (w >> 2);
1903 vstart = y;
1904 vstop = y + (h >> 0);
1905 ddfstart = (hstart >> 1) - 8;
1906
1907 #ifdef DEBUG
1908 if (aga_enable & AGA_TRACE2) {
1909 printf (" ddfwidth %04x x %04x y %04x", ddfwidth,
1910 x, y);
1911 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n",
1912 hstart, hstop, vstart, vstop, ddfstart);
1913 }
1914 #endif
1915 /* check for hardware limits, AGA may allow more..? */
1916 /* anyone got a 4000 I can borrow :^) -ch */
1917 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
1918 int d = 0;
1919
1920 /* XXX anyone know the equality properties of
1921 * intermixed logial AND's */
1922 /* XXX and arithmetic operators? */
1923 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
1924 d++;
1925 }
1926
1927 ddfstart -= d;
1928 hstart -= d << 1;
1929 hstop -= d << 1;
1930 }
1931 /* correct the datafetch to proper limits. */
1932 /* delay the actual display of the data until we need it. */
1933 ddfstart &= 0xfffc;
1934 #ifdef DEBUG
1935 if (aga_enable & AGA_TRACE2) {
1936 printf (" ddfwidth %04x x %04x y %04x", ddfwidth,
1937 x, y);
1938 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n",
1939 hstart, hstop, vstart, vstop, ddfstart);
1940 }
1941 #endif
1942 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
1943
1944 if (aga_this_data->current_view) {
1945 VDATA(aga_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
1946 /* displayed. */
1947 }
1948 aga_this_data->current_view = v;
1949
1950 cp = aga_this_data->frames[F_STORE_LONG];
1951 tmp = cp;
1952 for (i = 0; i < 8; ++i) {
1953 if (tmp == NULL)
1954 break;
1955 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
1956 if (tmp == NULL)
1957 break;
1958 tmp->cp.inst.operand = 0x0ca1 | (i << 13);
1959 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
1960 if (tmp == NULL)
1961 break;
1962 tmp->cp.inst.operand = 0x0ea1 | (i << 13);
1963 }
1964 if (tmp)
1965 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
1966 if (tmp)
1967 tmp->cp.inst.operand = 0x0ca1;
1968 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
1969 tmp->cp.inst.operand = 0x8003;
1970 tmp = find_copper_inst(cp, CI_MOVE(R_HTOTAL));
1971 tmp->cp.inst.operand = AGA_htotal; /* 81/71/73/79? */
1972 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTRT));
1973 tmp->cp.inst.operand = AGA_hbstrt; /* 0x0008 */
1974 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTRT));
1975 tmp->cp.inst.operand = AGA_hsstrt; /* 0x000e */
1976 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTOP));
1977 tmp->cp.inst.operand = AGA_hsstop; /* 0x001c */
1978 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTOP));
1979 tmp->cp.inst.operand = AGA_hsstop; /* 0x001e */
1980 tmp = find_copper_inst(cp, CI_MOVE(R_HCENTER));
1981 tmp->cp.inst.operand = AGA_hcenter; /*AGA_htotal / 2 + AGA_hsstrt */
1982 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTRT));
1983 tmp->cp.inst.operand = AGA_vbstrt; /* 0x0000 */
1984 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTRT));
1985 tmp->cp.inst.operand = AGA_vsstrt; /* 0x016b / AGA_htotal */
1986 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTOP));
1987 tmp->cp.inst.operand = AGA_vsstop; /* 0x02d6 / AGA_htotal */
1988 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTOP));
1989 tmp->cp.inst.operand = AGA_vbstop; /* 0x0bd1 / AGA_htotal */
1990 tmp = find_copper_inst(cp, CI_MOVE(R_VTOTAL));
1991 tmp->cp.inst.operand = AGA_vtotal;
1992 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
1993 tmp->cp.inst.operand = aga_this_data->beamcon0;
1994 #ifdef DEBUG
1995 if (aga_enable & AGA_TRACE2)
1996 printf(" beamcon0 %04x", tmp->cp.inst.operand);
1997 #endif
1998 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
1999 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2000 #ifdef DEBUG
2001 if (aga_enable & AGA_TRACE2)
2002 printf(" diwhigh %04x>", tmp->cp.inst.operand);
2003 #endif
2004 #if 0
2005 tmp->cp.inst.operand = (vstop & 0x0700) | ((hstop & 0x0100) << 5);
2006 #endif
2007 #ifdef DEBUG
2008 if (aga_enable & AGA_TRACE2)
2009 printf("%04x", tmp->cp.inst.operand);
2010 #endif
2011 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2012 tmp->cp.inst.operand = aga_this_data->bplcon0 |
2013 ((depth & 0x7) << 12) | ((depth & 0x8) << 1);
2014 #ifdef DEBUG
2015 if (aga_enable & AGA_TRACE2)
2016 printf(" bplcon0 %04x", tmp->cp.inst.operand);
2017 #endif
2018 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2019 tmp->cp.inst.operand = con1;
2020 #ifdef DEBUG
2021 if (aga_enable & AGA_TRACE2)
2022 printf(" bplcon1 %04x>0000\n", con1);
2023 #endif
2024 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2025 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2026 #ifdef DEBUG
2027 if (aga_enable & AGA_TRACE2)
2028 printf(" diwstart %04x", tmp->cp.inst.operand);
2029 #endif
2030 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2031 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2032 #ifdef DEBUG
2033 if (aga_enable & AGA_TRACE2)
2034 printf(" diwstop %04x", tmp->cp.inst.operand);
2035 #endif
2036 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2037 tmp->cp.inst.operand = ddfstart;
2038 #ifdef DEBUG
2039 if (aga_enable & AGA_TRACE2)
2040 printf(" ddfstart %04x", tmp->cp.inst.operand);
2041 #endif
2042 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2043 tmp->cp.inst.operand = ddfstart + ddfwidth;
2044 #ifdef DEBUG
2045 if (aga_enable & AGA_TRACE2)
2046 printf(" ddfstop %04x", tmp->cp.inst.operand);
2047 #endif
2048
2049 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2050 for (i = 0, j = 0; i < depth; j += 2, i++) {
2051 /* update the plane pointers */
2052 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2053 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2054 #ifdef DEBUG
2055 if (aga_enable & AGA_TRACE2)
2056 printf (" bpl%dpth %p", i, v->bitmap->plane[i]);
2057 #endif
2058 }
2059
2060 /* set mods correctly. */
2061 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2062 tmp[0].cp.inst.operand = v->bitmap->row_mod;
2063 tmp[1].cp.inst.operand = v->bitmap->row_mod;
2064 #ifdef DEBUG
2065 if (aga_enable & AGA_TRACE2)
2066 printf(" bplxmod %04x\n", v->bitmap->row_mod);
2067 #endif
2068
2069 /* set next pointers correctly */
2070 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2071 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(aga_this_data->frames[F_STORE_LONG]));
2072 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(aga_this_data->frames[F_STORE_LONG]));
2073
2074 cp = aga_this_data->frames[F_LONG];
2075 aga_this_data->frames[F_LONG] = aga_this_data->frames[F_STORE_LONG];
2076 aga_this_data->frames[F_STORE_LONG] = cp;
2077
2078 vd->flags |= VF_DISPLAY;
2079
2080 cc_use_aga_colormap(v, vd->colormap);
2081 }
2082 cc_load_mode(aga_this);
2083 #ifdef DEBUG
2084 if (aga_enable & AGA_TRACE)
2085 aga_enable |= AGA_TRACE2; /* XXXX */
2086 #endif
2087 }
2088
2089 /*
2090 * SUPER72 Mode
2091 */
2092
2093 #if defined (GRF_SUPER72)
2094 dmode_t *
cc_init_super72(void)2095 cc_init_super72(void)
2096 {
2097 /* this function should only be called once. */
2098 if (!super72_this && (custom.deniseid & 0xff) == 0xf8) {
2099 u_short len = aga_copper_list_len;
2100
2101 super72_this = &super72_mode;
2102 super72_this_data = &super72_mode_data;
2103 memset(super72_this, 0, sizeof(dmode_t));
2104 memset(super72_this_data, 0, sizeof(dmdata_t));
2105
2106 super72_this->name = "super72: superhires interlace";
2107 super72_this->nominal_size.width = 800;
2108 super72_this->nominal_size.height = 600;
2109 super72_this_data->max_size.width = 848;
2110 super72_this_data->max_size.height = 614;
2111 super72_this_data->min_size.width = 320;
2112 super72_this_data->min_size.height = 484;
2113 super72_this_data->min_depth = 1;
2114 super72_this_data->max_depth = 8;
2115 super72_this->data = super72_this_data;
2116
2117 super72_this->get_monitor = cc_get_monitor;
2118 super72_this->alloc_view = cc_alloc_view;
2119 super72_this->get_current_view = cc_get_current_view;
2120
2121 super72_this_data->use_colormap = cc_use_aga_colormap;
2122 super72_this_data->get_colormap = cc_get_colormap;
2123 super72_this_data->alloc_colormap = cc_alloc_aga_colormap;
2124 super72_this_data->display_view = display_super72_view;
2125 super72_this_data->monitor = cc_monitor;
2126
2127 super72_this_data->flags |= DMF_INTERLACE;
2128
2129 super72_this_data->frames = super72_frames; /* MAY NEED TO CHANGE COPLIST */
2130 super72_this_data->frames[F_LACE_LONG] =
2131 alloc_chipmem(aga_copper_list_size * F_LACE_TOTAL);
2132 if (!super72_this_data->frames[F_LACE_LONG]) {
2133 panic("couldn't get chipmem for copper list");
2134 }
2135 super72_this_data->frames[F_LACE_SHORT] =
2136 &super72_this_data->frames[F_LACE_LONG][len];
2137 super72_this_data->frames[F_LACE_STORE_LONG] =
2138 &super72_this_data->frames[F_LACE_SHORT][len];
2139 super72_this_data->frames[F_LACE_STORE_SHORT] =
2140 &super72_this_data->frames[F_LACE_STORE_LONG][len];
2141
2142 bcopy(aga_copper_list,
2143 super72_this_data->frames[F_LACE_STORE_LONG],
2144 aga_copper_list_size);
2145 bcopy(aga_copper_list,
2146 super72_this_data->frames[F_LACE_STORE_SHORT],
2147 aga_copper_list_size);
2148 bcopy(aga_copper_list,
2149 super72_this_data->frames[F_LACE_LONG],
2150 aga_copper_list_size);
2151 bcopy(aga_copper_list,
2152 super72_this_data->frames[F_LACE_SHORT],
2153 aga_copper_list_size);
2154
2155 super72_this_data->bplcon0 = 0x0244 | USE_CON3; /* color
2156 * composite enable,
2157 * shres
2158 * lace. */
2159 #if 0 /* patchable variables for testing */
2160 super72_this_data->std_start_x = 0x6c;
2161 super72_this_data->std_start_y = 0x1b;
2162 #endif
2163 super72_this_data->vbl_handler =
2164 (vbl_handler_func *) cc_lace_mode_vbl_handler;
2165 super72_this_data->beamcon0 = (SPECIAL_BEAMCON ^ VSYNCTRUE) |
2166 DISPLAYPAL | 0x4000;
2167 super72_this_data->beamcon0 = 0x5bb0;
2168
2169 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, super72_this, link);
2170 }
2171 return (super72_this);
2172 }
2173
2174 /* Super72 83Hz hack monitor values */
2175 /*int super72_htotal = 0x083;
2176 int super72_hsstrt = 0x00d;
2177 int super72_hsstop = 0x01b;
2178 int super72_hbstrt = 0x001;
2179 int super72_hbstop = 0x021;
2180 int super72_vtotal = 0x148;
2181 int super72_vsstrt = 0x2d5;
2182 int super72_vsstop = 0x3ca;
2183 int super72_vbstrt = 0x000;
2184 int super72_vbstop = 0xfdc;
2185 int super72_hcenter = 0x04e;
2186 */
2187
2188 /* Super72 standard monitor values */
2189 int super72_htotal = 154; /* 0x099*/
2190 int super72_hsstrt = 17; /* 0x01c*/
2191 int super72_hsstop = 27; /* 0x038*/
2192 int super72_hbstrt = 154; /* 0x008*/
2193 int super72_hbstop = 55; /* 0x01e*/
2194 int super72_vtotal = 328; /* 0x147*/
2195 int super72_vsstrt = 11; /* 0x030*/
2196 int super72_vsstop = 18; /* 0x033*/
2197 int super72_vbstrt = 327; /* 0x000*/
2198 int super72_vbstop = 27; /* 0x019*/
2199 int super72_hcenter = 94; /* 0x057*/
2200 int super72_startx = 100;
2201 int super72_starty = 27;
2202
2203 void
display_super72_view(view_t * v)2204 display_super72_view(view_t *v)
2205 {
2206 if (super72_this_data->current_view != v) {
2207 vdata_t *vd = VDATA(v);
2208 cop_t *cp = super72_this_data->frames[F_LACE_STORE_LONG], *tmp;
2209 int depth = v->bitmap->depth, i;
2210 int hstart, hstop, vstart, vstop, j;
2211 int x, y, w = v->display.width, h = v->display.height;
2212 u_short ddfstart, ddfwidth, con1;
2213
2214 /* round down to nearest even width */
2215 /* w &= 0xfffe; */
2216
2217 /* calculate datafetch width. */
2218 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 4) << 1;
2219
2220 /* This will center any overscanned display */
2221 /* and allow user to modify. */
2222 x = (v->display.x >> 1) + super72_startx - ((w - 800) >> 3);
2223 y = v->display.y + super72_starty - ((h - 600) >> 2);
2224
2225 hstart = x;
2226 hstop = x + (w >> 2);
2227 vstart = y;
2228 vstop = y + (h >> 1);
2229 ddfstart = (hstart >> 1) - 16;
2230
2231 ddfstart = (hstart << 2) - 4;
2232 con1 = ddfstart & 63;
2233 ddfstart = (ddfstart & -64) - 64;
2234 ddfwidth = ((w + 64 - 1) & -64) - 64;
2235 ddfwidth = ddfwidth >> 3;
2236 ddfstart = ddfstart >> 3;
2237 super72_hbstrt = ((x << 2) + w + 4) >> 3;
2238 super72_hbstop = (hstart + 1) >> 1;
2239 super72_vbstrt = vstop;
2240 super72_vbstop = vstart - 2;
2241
2242 if ((hstop >> 1) > super72_htotal) {
2243 int d;
2244
2245 d = (hstop >> 1) - super72_htotal;
2246 ddfstart -= d;
2247 hstart -= d << 1;
2248 hstop -= d << 1;
2249 }
2250 if (vstop >= super72_vtotal) {
2251 int d;
2252 d = (vstop - super72_vtotal + 1);
2253 vstart -= d;
2254 vstop -= d;
2255 }
2256 con1 = ((con1 >> 2) & 0x000f) | /* PF1H2-PF1H5 */
2257 ((con1 << 8) & 0x0300) | /* PF1H0-PF1H2 */
2258 ((con1 << 4) & 0x0c00); /* PF1H6-PF1H7 */
2259 con1 |= con1 << 4; /* PF2H2-PF2H7 */
2260
2261 if (super72_this_data->current_view) {
2262 VDATA(super72_this_data->current_view)->flags &=
2263 ~VF_DISPLAY; /* mark as no longer */
2264 /* displayed. */
2265 }
2266 super72_this_data->current_view = v;
2267
2268 cp = super72_this_data->frames[F_LACE_STORE_LONG];
2269 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
2270 tmp->cp.inst.operand = 0x8003;
2271 tmp = find_copper_inst(cp, CI_MOVE(R_HTOTAL));
2272 tmp->cp.inst.operand = super72_htotal;
2273 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTRT));
2274 tmp->cp.inst.operand = super72_hbstrt;
2275 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTRT));
2276 tmp->cp.inst.operand = super72_hsstrt;
2277 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTOP));
2278 tmp->cp.inst.operand = super72_hsstop;
2279 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTOP));
2280 tmp->cp.inst.operand = super72_hbstop;
2281 tmp = find_copper_inst(cp, CI_MOVE(R_HCENTER));
2282 tmp->cp.inst.operand = super72_hcenter;
2283 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTRT));
2284 tmp->cp.inst.operand = super72_vbstrt;
2285 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTRT));
2286 tmp->cp.inst.operand = super72_vsstrt;
2287 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTOP));
2288 tmp->cp.inst.operand = super72_vsstop;
2289 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTOP));
2290 tmp->cp.inst.operand = super72_vbstop;
2291 tmp = find_copper_inst(cp, CI_MOVE(R_VTOTAL));
2292 tmp->cp.inst.operand = super72_vtotal;
2293
2294 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
2295 tmp->cp.inst.operand = super72_this_data->beamcon0;
2296 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2297 tmp->cp.inst.operand =
2298 CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2299 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2300 tmp->cp.inst.operand = super72_this_data->bplcon0 |
2301 ((depth & 0x7) << 12) | ((depth & 0x8) << 1);
2302 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2303 tmp->cp.inst.operand = con1;
2304 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2305 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2306 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2307 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2308 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2309 tmp->cp.inst.operand = ddfstart;
2310 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2311 tmp->cp.inst.operand = ddfstart + ddfwidth;
2312
2313 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2314 for (i = 0, j = 0; i < depth; j += 2, i++) {
2315 /* update the plane pointers */
2316 tmp[j].cp.inst.operand =
2317 HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2318 tmp[j + 1].cp.inst.operand =
2319 LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2320 }
2321
2322 /* set mods correctly. */
2323 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2324 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row +
2325 v->bitmap->row_mod;
2326 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row +
2327 v->bitmap->row_mod;
2328
2329 /* set next pointers correctly */
2330 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2331 tmp[0].cp.inst.operand =
2332 HIADDR(PREP_DMA_MEM(super72_this_data->frames[F_LACE_STORE_SHORT]));
2333 tmp[1].cp.inst.operand =
2334 LOADDR(PREP_DMA_MEM(super72_this_data->frames[F_LACE_STORE_SHORT]));
2335
2336 bcopy(super72_this_data->frames[F_LACE_STORE_LONG],
2337 super72_this_data->frames[F_LACE_STORE_SHORT],
2338 aga_copper_list_size);
2339
2340 /* these are the only ones that are different from long frame. */
2341 cp = super72_this_data->frames[F_LACE_STORE_SHORT];
2342 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2343 for (i = 0, j = 0; i < depth; j += 2, i++) {
2344 u_short mod = v->bitmap->bytes_per_row +
2345 v->bitmap->row_mod;
2346 /* update plane pointers. high and low. */
2347 tmp[j].cp.inst.operand =
2348 HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
2349 tmp[j + 1].cp.inst.operand =
2350 LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
2351 }
2352
2353 /* set next pointers correctly */
2354 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2355 tmp[0].cp.inst.operand =
2356 HIADDR(PREP_DMA_MEM(super72_this_data->frames[F_LACE_STORE_LONG]));
2357 tmp[1].cp.inst.operand =
2358 LOADDR(PREP_DMA_MEM(super72_this_data->frames[F_LACE_STORE_LONG]));
2359
2360 cp = super72_this_data->frames[F_LACE_LONG];
2361 super72_this_data->frames[F_LACE_LONG] =
2362 super72_this_data->frames[F_LACE_STORE_LONG];
2363 super72_this_data->frames[F_LACE_STORE_LONG] = cp;
2364
2365 cp = super72_this_data->frames[F_LACE_SHORT];
2366 super72_this_data->frames[F_LACE_SHORT] =
2367 super72_this_data->frames[F_LACE_STORE_SHORT];
2368 super72_this_data->frames[F_LACE_STORE_SHORT] = cp;
2369
2370 vd->flags |= VF_DISPLAY;
2371 cc_use_aga_colormap(v, vd->colormap);
2372 }
2373 cc_load_mode(super72_this);
2374 }
2375 #endif /* GRF_SUPER72 */
2376
2377 #endif /* GRF_AGA */
2378 #endif /* GRF_NTSC */
2379
2380 /*
2381 * PAL modes.
2382 */
2383
2384 #if defined (GRF_PAL)
2385
2386 dmode_t *
cc_init_pal_hires(void)2387 cc_init_pal_hires(void)
2388 {
2389 /* this function should only be called once. */
2390 if (!ph_this) {
2391 u_short len = std_copper_list_len;
2392
2393 ph_this = &pal_hires_mode;
2394 ph_this_data = &pal_hires_mode_data;
2395 memset(ph_this, 0, sizeof(dmode_t));
2396 memset(ph_this_data, 0, sizeof(dmdata_t));
2397
2398 ph_this->name = "pal: hires";
2399 ph_this->nominal_size.width = 640;
2400 ph_this->nominal_size.height = 256;
2401 ph_this_data->max_size.width = 724;
2402 ph_this_data->max_size.height = 289;
2403 ph_this_data->min_size.width = 320;
2404 ph_this_data->min_size.height = 244;
2405 ph_this_data->min_depth = 1;
2406 ph_this_data->max_depth = 4;
2407 ph_this->data = ph_this_data;
2408
2409 ph_this->get_monitor = cc_get_monitor;
2410 ph_this->alloc_view = cc_alloc_view;
2411 ph_this->get_current_view = cc_get_current_view;
2412
2413 ph_this_data->use_colormap = cc_use_colormap;
2414 ph_this_data->get_colormap = cc_get_colormap;
2415 ph_this_data->alloc_colormap = cc_alloc_colormap;
2416 ph_this_data->display_view = display_pal_hires_view;
2417 ph_this_data->monitor = cc_monitor;
2418
2419 ph_this_data->frames = pal_hires_frames;
2420 ph_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL);
2421 if (!ph_this_data->frames[F_LONG]) {
2422 panic("couldn't get chipmem for copper list");
2423 }
2424 ph_this_data->frames[F_STORE_LONG] = &ph_this_data->frames[F_LONG][len];
2425
2426 memcpy(ph_this_data->frames[F_STORE_LONG], std_copper_list, std_copper_list_size);
2427 memcpy(ph_this_data->frames[F_LONG], std_copper_list, std_copper_list_size);
2428
2429 ph_this_data->bplcon0 = 0x8200 | USE_CON3; /* pal_hires, color
2430 * composite enable,
2431 * lace. */
2432 ph_this_data->std_start_x = STANDARD_VIEW_X;
2433 ph_this_data->std_start_y = STANDARD_VIEW_Y;
2434 ph_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler;
2435 #if defined (GRF_ECS) || defined (GRF_AGA)
2436 ph_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
2437 #endif
2438
2439 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, ph_this, link);
2440 }
2441 return (ph_this);
2442 }
2443
2444 void
display_pal_hires_view(view_t * v)2445 display_pal_hires_view(view_t *v)
2446 {
2447 if (ph_this_data->current_view != v) {
2448 vdata_t *vd = VDATA(v);
2449 cop_t *cp = ph_this_data->frames[F_STORE_LONG], *tmp;
2450 int depth = v->bitmap->depth, i;
2451 int hstart, hstop, vstart, vstop, j;
2452 int x, y, w = v->display.width, h = v->display.height;
2453 u_short ddfstart, ddfwidth, con1;
2454
2455 /* round down to nearest even width */
2456 /* w &= 0xfffe; */
2457
2458 /* calculate datafetch width. */
2459 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
2460
2461 /* This will center the any overscanned display */
2462 /* and allow user to modify. */
2463 x = v->display.x + ph_this_data->std_start_x - ((w - 640) >> 2);
2464 y = v->display.y + ph_this_data->std_start_y - ((h - 256) >> 1);
2465
2466 if (y & 1)
2467 y--;
2468
2469 if (!(x & 1))
2470 x--;
2471
2472 hstart = x;
2473 hstop = x + (w >> 1);
2474 vstart = y;
2475 vstop = y + h;
2476 ddfstart = (hstart - 9) >> 1;
2477 /* check for hardware limits, AGA may allow more..? */
2478 /* anyone got a 4000 I can borrow :^) -ch */
2479 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
2480 int d = 0;
2481
2482 /* XXX anyone know the equality properties of
2483 * intermixed logial AND's */
2484 /* XXX and arithmetic operators? */
2485 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
2486 d++;
2487 }
2488
2489 ddfstart -= d;
2490 hstart -= d << 1;
2491 hstop -= d << 1;
2492 }
2493 /* correct the datafetch to proper limits. */
2494 /* delay the actual display of the data until we need it. */
2495 ddfstart &= 0xfffc;
2496 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
2497
2498 if (ph_this_data->current_view) {
2499 VDATA(ph_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
2500 /* displayed. */
2501 }
2502 ph_this_data->current_view = v;
2503
2504 cp = ph_this_data->frames[F_STORE_LONG];
2505 #if defined (GRF_ECS) || defined (GRF_AGA)
2506 #if defined (GRF_AGA)
2507 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
2508 tmp->cp.inst.operand = 0;
2509 #endif
2510 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
2511 tmp->cp.inst.operand = ph_this_data->beamcon0;
2512 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2513 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2514 #endif /* ECS */
2515 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2516 tmp->cp.inst.operand = ph_this_data->bplcon0 | ((depth & 0x7) << 12);
2517 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2518 tmp->cp.inst.operand = con1;
2519 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2520 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2521 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2522 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2523 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2524 tmp->cp.inst.operand = ddfstart;
2525 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2526 tmp->cp.inst.operand = ddfstart + ddfwidth;
2527
2528 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2529 for (i = 0, j = 0; i < depth; j += 2, i++) {
2530 /* update the plane pointers */
2531 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2532 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2533 }
2534
2535 /* set mods correctly. */
2536 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2537 tmp[0].cp.inst.operand = v->bitmap->row_mod;
2538 tmp[1].cp.inst.operand = v->bitmap->row_mod;
2539
2540 /* set next pointers correctly */
2541 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2542 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG]));
2543 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG]));
2544
2545 cp = ph_this_data->frames[F_LONG];
2546 ph_this_data->frames[F_LONG] = ph_this_data->frames[F_STORE_LONG];
2547 ph_this_data->frames[F_STORE_LONG] = cp;
2548
2549 vd->flags |= VF_DISPLAY;
2550 cc_use_colormap(v, vd->colormap);
2551 }
2552 cc_load_mode(ph_this);
2553 }
2554
2555 dmode_t *
cc_init_pal_hires_lace(void)2556 cc_init_pal_hires_lace(void)
2557 {
2558 /* this function should only be called once. */
2559 if (!phl_this) {
2560 u_short len = std_copper_list_len;
2561
2562 phl_this = &pal_hires_lace_mode;
2563 phl_this_data = &pal_hires_lace_mode_data;
2564 memset(phl_this, 0, sizeof(dmode_t));
2565 memset(phl_this_data, 0, sizeof(dmdata_t));
2566
2567 phl_this->name = "pal: hires interlace";
2568 phl_this->nominal_size.width = 640;
2569 phl_this->nominal_size.height = 512;
2570 phl_this_data->max_size.width = 724;
2571 phl_this_data->max_size.height = 578;
2572 phl_this_data->min_size.width = 320;
2573 phl_this_data->min_size.height = 484;
2574 phl_this_data->min_depth = 1;
2575 phl_this_data->max_depth = 4;
2576 phl_this->data = phl_this_data;
2577
2578 phl_this->get_monitor = cc_get_monitor;
2579 phl_this->alloc_view = cc_alloc_view;
2580 phl_this->get_current_view = cc_get_current_view;
2581
2582 phl_this_data->use_colormap = cc_use_colormap;
2583 phl_this_data->get_colormap = cc_get_colormap;
2584 phl_this_data->alloc_colormap = cc_alloc_colormap;
2585 phl_this_data->display_view = display_pal_hires_lace_view;
2586 phl_this_data->monitor = cc_monitor;
2587
2588 phl_this_data->flags |= DMF_INTERLACE;
2589
2590 phl_this_data->frames = pal_hires_lace_frames;
2591 phl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL);
2592 if (!phl_this_data->frames[F_LACE_LONG]) {
2593 panic("couldn't get chipmem for copper list");
2594 }
2595 phl_this_data->frames[F_LACE_SHORT] = &phl_this_data->frames[F_LACE_LONG][len];
2596 phl_this_data->frames[F_LACE_STORE_LONG] = &phl_this_data->frames[F_LACE_SHORT][len];
2597 phl_this_data->frames[F_LACE_STORE_SHORT] = &phl_this_data->frames[F_LACE_STORE_LONG][len];
2598
2599 memcpy(phl_this_data->frames[F_LACE_STORE_LONG], std_copper_list, std_copper_list_size);
2600 memcpy(phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list, std_copper_list_size);
2601 memcpy(phl_this_data->frames[F_LACE_LONG], std_copper_list, std_copper_list_size);
2602 memcpy(phl_this_data->frames[F_LACE_SHORT], std_copper_list, std_copper_list_size);
2603
2604 phl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
2605 * composite enable,
2606 * lace. */
2607 phl_this_data->std_start_x = STANDARD_VIEW_X;
2608 phl_this_data->std_start_y = STANDARD_VIEW_Y;
2609 phl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler;
2610 #if defined (GRF_ECS) || defined (GRF_AGA)
2611 phl_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
2612 #endif
2613
2614 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phl_this, link);
2615 }
2616 return (phl_this);
2617 }
2618
2619 void
display_pal_hires_lace_view(view_t * v)2620 display_pal_hires_lace_view(view_t *v)
2621 {
2622 if (phl_this_data->current_view != v) {
2623 vdata_t *vd = VDATA(v);
2624 cop_t *cp = phl_this_data->frames[F_LACE_STORE_LONG], *tmp;
2625 int depth = v->bitmap->depth, i;
2626 int hstart, hstop, vstart, vstop, j;
2627 int x, y, w = v->display.width, h = v->display.height;
2628 u_short ddfstart, ddfwidth, con1;
2629
2630 /* round down to nearest even width */
2631 /* w &= 0xfffe; */
2632
2633 /* calculate datafetch width. */
2634 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
2635
2636 /* This will center the any overscanned display */
2637 /* and allow user to modify. */
2638 x = v->display.x + phl_this_data->std_start_x - ((w - 640) >> 2);
2639 y = v->display.y + phl_this_data->std_start_y - ((h - 512) >> 2);
2640
2641 if (y & 1)
2642 y--;
2643
2644 if (!(x & 1))
2645 x--;
2646
2647 hstart = x;
2648 hstop = x + (w >> 1);
2649 vstart = y;
2650 vstop = y + (h >> 1);
2651 ddfstart = (hstart - 9) >> 1;
2652
2653 /* check for hardware limits, AGA may allow more..? */
2654 /* anyone got a 4000 I can borrow :^) -ch */
2655 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
2656 int d = 0;
2657
2658 /* XXX anyone know the equality properties of
2659 * intermixed logial AND's */
2660 /* XXX and arithmetic operators? */
2661 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
2662 d++;
2663 }
2664
2665 ddfstart -= d;
2666 hstart -= d << 1;
2667 hstop -= d << 1;
2668 }
2669 /* correct the datafetch to proper limits. */
2670 /* delay the actual display of the data until we need it. */
2671 ddfstart &= 0xfffc;
2672 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
2673
2674 if (phl_this_data->current_view) {
2675 VDATA(phl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
2676 /* displayed. */
2677 }
2678 phl_this_data->current_view = v;
2679
2680 cp = phl_this_data->frames[F_LACE_STORE_LONG];
2681 #if defined (GRF_ECS) || defined (GRF_AGA)
2682 #if defined (GRF_AGA)
2683 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
2684 tmp->cp.inst.operand = 0;
2685 #endif
2686 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
2687 tmp->cp.inst.operand = phl_this_data->beamcon0;
2688 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2689 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2690 #endif /* ECS */
2691 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2692 tmp->cp.inst.operand = phl_this_data->bplcon0 | ((depth & 0x7) << 12);
2693 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2694 tmp->cp.inst.operand = con1;
2695 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2696 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2697 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2698 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2699 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2700 tmp->cp.inst.operand = ddfstart;
2701 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2702 tmp->cp.inst.operand = ddfstart + ddfwidth;
2703
2704 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2705 for (i = 0, j = 0; i < depth; j += 2, i++) {
2706 /* update the plane pointers */
2707 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2708 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2709 }
2710
2711 /* set mods correctly. */
2712 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2713 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2714 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2715
2716 /* set next pointers correctly */
2717 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2718 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT]));
2719 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT]));
2720
2721
2722 memcpy(phl_this_data->frames[F_LACE_STORE_SHORT], phl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size);
2723
2724 /* these are the only ones that are different from long frame. */
2725 cp = phl_this_data->frames[F_LACE_STORE_SHORT];
2726 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2727 for (i = 0, j = 0; i < depth; j += 2, i++) {
2728 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2729 /* update plane pointers. high and low. */
2730 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
2731 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
2732 }
2733
2734 /* set next pointers correctly */
2735 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2736 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG]));
2737 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG]));
2738
2739
2740 cp = phl_this_data->frames[F_LACE_LONG];
2741 phl_this_data->frames[F_LACE_LONG] = phl_this_data->frames[F_LACE_STORE_LONG];
2742 phl_this_data->frames[F_LACE_STORE_LONG] = cp;
2743
2744 cp = phl_this_data->frames[F_LACE_SHORT];
2745 phl_this_data->frames[F_LACE_SHORT] = phl_this_data->frames[F_LACE_STORE_SHORT];
2746 phl_this_data->frames[F_LACE_STORE_SHORT] = cp;
2747
2748 vd->flags |= VF_DISPLAY;
2749 cc_use_colormap(v, vd->colormap);
2750 }
2751 cc_load_mode(phl_this);
2752 }
2753 #if defined (GRF_A2024)
2754
2755 dmode_t *
cc_init_pal_hires_dlace(void)2756 cc_init_pal_hires_dlace(void)
2757 {
2758 /* this function should only be called once. */
2759 if (!phdl_this) {
2760 u_short len = std_dlace_copper_list_len;
2761
2762 phdl_this = &pal_hires_dlace_mode;
2763 phdl_this_data = &pal_hires_dlace_mode_data;
2764 memset(phdl_this, 0, sizeof(dmode_t));
2765 memset(phdl_this_data, 0, sizeof(dmdata_t));
2766
2767 phdl_this->name = "pal: hires double interlace";
2768 phdl_this->nominal_size.width = 640;
2769 phdl_this->nominal_size.height = 1024;
2770 phdl_this_data->max_size.width = 724;
2771 phdl_this_data->max_size.height = 1024;
2772 phdl_this_data->min_size.width = 320;
2773 phdl_this_data->min_size.height = 512;
2774 phdl_this_data->min_depth = 1;
2775 phdl_this_data->max_depth = 2;
2776 phdl_this->data = phdl_this_data;
2777
2778 phdl_this->get_monitor = cc_get_monitor;
2779 phdl_this->alloc_view = cc_alloc_view;
2780 phdl_this->get_current_view = cc_get_current_view;
2781
2782 phdl_this_data->use_colormap = cc_a2024_use_colormap;
2783 phdl_this_data->get_colormap = cc_a2024_get_colormap;
2784 phdl_this_data->alloc_colormap = cc_a2024_alloc_colormap;
2785 phdl_this_data->display_view = display_pal_hires_dlace_view;
2786 phdl_this_data->monitor = cc_monitor;
2787
2788 phdl_this_data->flags |= DMF_INTERLACE;
2789
2790 phdl_this_data->frames = pal_hires_dlace_frames;
2791 phdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL);
2792 if (!phdl_this_data->frames[F_LACE_LONG]) {
2793 panic("couldn't get chipmem for copper list");
2794 }
2795 phdl_this_data->frames[F_LACE_SHORT] = &phdl_this_data->frames[F_LACE_LONG][len];
2796 phdl_this_data->frames[F_LACE_STORE_LONG] = &phdl_this_data->frames[F_LACE_SHORT][len];
2797 phdl_this_data->frames[F_LACE_STORE_SHORT] = &phdl_this_data->frames[F_LACE_STORE_LONG][len];
2798
2799 memcpy(phdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list, std_dlace_copper_list_size);
2800 memcpy(phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list, std_dlace_copper_list_size);
2801 memcpy(phdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list, std_dlace_copper_list_size);
2802 memcpy(phdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list, std_dlace_copper_list_size);
2803
2804 phdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
2805 * composite enable,
2806 * dlace. */
2807 phdl_this_data->std_start_x = STANDARD_VIEW_X;
2808 phdl_this_data->std_start_y = STANDARD_VIEW_Y;
2809 phdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler;
2810 #if defined (GRF_ECS) || defined (GRF_AGA)
2811 phdl_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
2812 #endif
2813
2814 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phdl_this, link);
2815 }
2816 return (phdl_this);
2817 }
2818
2819 void
display_pal_hires_dlace_view(view_t * v)2820 display_pal_hires_dlace_view(view_t *v)
2821 {
2822 if (phdl_this_data->current_view != v) {
2823 vdata_t *vd = VDATA(v);
2824 cop_t *cp = phdl_this_data->frames[F_LACE_STORE_LONG], *tmp;
2825 int depth = v->bitmap->depth;
2826 int hstart, hstop, vstart, vstop;
2827 int x, y, w = v->display.width, h = v->display.height;
2828 u_short ddfstart, ddfwidth, con1;
2829 u_short mod1l, mod2l;
2830
2831 /* round down to nearest even width */
2832 /* w &= 0xfffe; */
2833
2834 /* calculate datafetch width. */
2835 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
2836
2837 /* This will center the any overscanned display */
2838 /* and allow user to modify. */
2839 x = v->display.x + phdl_this_data->std_start_x - ((w - 640) >> 2);
2840 y = v->display.y + phdl_this_data->std_start_y - ((h - 1024) >> 3);
2841
2842 if (y & 1)
2843 y--;
2844
2845 if (!(x & 1))
2846 x--;
2847
2848 hstart = x;
2849 hstop = x + (w >> 1);
2850 vstart = y;
2851 vstop = y + (h >> 2);
2852 ddfstart = (hstart - 9) >> 1;
2853
2854 /* check for hardware limits, AGA may allow more..? */
2855 /* anyone got a 4000 I can borrow :^) -ch */
2856 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
2857 int d = 0;
2858
2859 /* XXX anyone know the equality properties of
2860 * intermixed logial AND's */
2861 /* XXX and arithmetic operators? */
2862 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
2863 d++;
2864 }
2865
2866 ddfstart -= d;
2867 hstart -= d << 1;
2868 hstop -= d << 1;
2869 }
2870 /* correct the datafetch to proper limits. */
2871 /* delay the actual display of the data until we need it. */
2872 ddfstart &= 0xfffc;
2873 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
2874
2875 if (phdl_this_data->current_view) {
2876 VDATA(phdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
2877 /* displayed. */
2878 }
2879 phdl_this_data->current_view = v;
2880
2881 cp = phdl_this_data->frames[F_LACE_STORE_LONG];
2882 #if defined (GRF_ECS) || defined (GRF_AGA)
2883 #if defined (GRF_AGA)
2884 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
2885 tmp->cp.inst.operand = 0;
2886 #endif
2887 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
2888 tmp->cp.inst.operand = phdl_this_data->beamcon0;
2889 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2890 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2891 #endif /* ECS */
2892 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2893 tmp->cp.inst.operand = phdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */
2894 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2895 tmp->cp.inst.operand = con1;
2896 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2897 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2898 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2899 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2900 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2901 tmp->cp.inst.operand = ddfstart;
2902 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2903 tmp->cp.inst.operand = ddfstart + ddfwidth;
2904
2905 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2906 mod2l = mod1l << 1;
2907
2908 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2909 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* update plane
2910 * pointers. */
2911 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* high and low. */
2912 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* update plane
2913 * pointers. */
2914 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* high and low. */
2915 if (depth == 2) {
2916 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* update plane
2917 * pointers. */
2918 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* high and low. */
2919 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* update plane
2920 * pointers. */
2921 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* high and low. */
2922 }
2923 /* set mods correctly. */
2924 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2925 tmp[0].cp.inst.operand = mod2l + mod1l;
2926 tmp[1].cp.inst.operand = mod2l + mod1l;
2927
2928 /* set next pointers correctly */
2929 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2930 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT]));
2931 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT]));
2932
2933 memcpy(phdl_this_data->frames[F_LACE_STORE_SHORT], phdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size);
2934
2935 /* these are the only ones that are different from long frame. */
2936 cp = phdl_this_data->frames[F_LACE_STORE_SHORT];
2937 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2938 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* update plane
2939 * pointers. */
2940 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* high and low. */
2941 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* update plane
2942 * pointers. */
2943 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* high and low. */
2944 if (depth == 2) {
2945 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* update plane
2946 * pointers. */
2947 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* high and low. */
2948 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* update plane
2949 * pointers. */
2950 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* high and low. */
2951 }
2952 /* set next pointers correctly */
2953 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2954 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG]));
2955 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG]));
2956
2957 cp = phdl_this_data->frames[F_LACE_LONG];
2958 phdl_this_data->frames[F_LACE_LONG] = phdl_this_data->frames[F_LACE_STORE_LONG];
2959 phdl_this_data->frames[F_LACE_STORE_LONG] = cp;
2960
2961 cp = phdl_this_data->frames[F_LACE_SHORT];
2962 phdl_this_data->frames[F_LACE_SHORT] = phdl_this_data->frames[F_LACE_STORE_SHORT];
2963 phdl_this_data->frames[F_LACE_STORE_SHORT] = cp;
2964
2965 vd->flags |= VF_DISPLAY;
2966
2967 cc_a2024_use_colormap(v, vd->colormap);
2968 }
2969 cc_load_mode(phdl_this);
2970 }
2971
2972 dmode_t *
cc_init_pal_a2024(void)2973 cc_init_pal_a2024(void)
2974 {
2975 /* this function should only be called once. */
2976 if (!p24_this) {
2977 int i;
2978 u_short len = std_pal_a2024_copper_list_len;
2979 cop_t *cp;
2980
2981 p24_this = &pal_a2024_mode;
2982 p24_this_data = &pal_a2024_mode_data;
2983 memset(p24_this, 0, sizeof(dmode_t));
2984 memset(p24_this_data, 0, sizeof(dmdata_t));
2985
2986 p24_this->name = "pal: A2024 15 kHz";
2987 p24_this->nominal_size.width = 1024;
2988 p24_this->nominal_size.height = 1024;
2989 p24_this_data->max_size.width = 1024;
2990 p24_this_data->max_size.height = 1024;
2991 p24_this_data->min_size.width = 1024;
2992 p24_this_data->min_size.height = 1024;
2993 p24_this_data->min_depth = 1;
2994 p24_this_data->max_depth = 2;
2995 p24_this->data = p24_this_data;
2996
2997 p24_this->get_monitor = cc_get_monitor;
2998 p24_this->alloc_view = cc_alloc_view;
2999 p24_this->get_current_view = cc_get_current_view;
3000
3001 p24_this_data->use_colormap = cc_a2024_use_colormap;
3002 p24_this_data->get_colormap = cc_a2024_get_colormap;
3003 p24_this_data->display_view = display_pal_a2024_view;
3004 p24_this_data->alloc_colormap = cc_a2024_alloc_colormap;
3005 p24_this_data->monitor = cc_monitor;
3006
3007 p24_this_data->flags |= DMF_HEDLEY_EXP;
3008
3009 p24_this_data->frames = pal_a2024_frames;
3010 p24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_pal_a2024_copper_list_size * F_QD_TOTAL);
3011 if (!p24_this_data->frames[F_QD_QUAD0]) {
3012 panic("couldn't get chipmem for copper list");
3013 }
3014 /* setup the hedley init bitplane. */
3015 hedley_init = alloc_chipmem(128);
3016 if (!hedley_init) {
3017 panic("couldn't get chipmem for hedley init bitplane");
3018 }
3019 for (i = 1; i < 128; i++)
3020 hedley_init[i] = 0xff;
3021 hedley_init[0] = 0x03;
3022
3023 /* copy image of standard copper list. */
3024 memcpy(p24_this_data->frames[0], std_pal_a2024_copper_list, std_pal_a2024_copper_list_size);
3025
3026 /* set the init plane pointer. */
3027 cp = find_copper_inst(p24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH));
3028 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init));
3029 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init));
3030
3031 for (i = 1; i < F_QD_TOTAL; i++) {
3032 p24_this_data->frames[i] = &p24_this_data->frames[i - 1][len];
3033 memcpy(p24_this_data->frames[i], p24_this_data->frames[0], std_pal_a2024_copper_list_size);
3034 }
3035
3036 p24_this_data->bplcon0 = 0x8200; /* hires */
3037 p24_this_data->vbl_handler = (vbl_handler_func *) pal_a2024_mode_vbl_handler;
3038
3039
3040 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, p24_this, link);
3041 }
3042 return (p24_this);
3043 }
3044
3045 void
display_pal_a2024_view(view_t * v)3046 display_pal_a2024_view(view_t *v)
3047 {
3048 if (p24_this_data->current_view != v) {
3049 vdata_t *vd = VDATA(v);
3050 cop_t *cp, *tmp;
3051 u_char *inst_plane[2] = { NULL, NULL };
3052 u_char **plane = inst_plane;
3053 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod;
3054 u_long half_plane = full_line * v->bitmap->rows / 2;
3055
3056 int depth = v->bitmap->depth, i, j;
3057
3058 plane[0] = v->bitmap->plane[0];
3059 if (depth == 2) {
3060 plane[1] = v->bitmap->plane[1];
3061 }
3062 if (p24_this_data->current_view) {
3063 VDATA(p24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer
3064 * displayed. */
3065 }
3066 cp = p24_this_data->frames[F_QD_STORE_QUAD0];
3067 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F));
3068 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */
3069 tmp->cp.inst.operand = p24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */
3070
3071 memcpy(p24_this_data->frames[F_QD_STORE_QUAD1], p24_this_data->frames[F_QD_STORE_QUAD0], std_pal_a2024_copper_list_size);
3072 memcpy(p24_this_data->frames[F_QD_STORE_QUAD2], p24_this_data->frames[F_QD_STORE_QUAD0], std_pal_a2024_copper_list_size);
3073 memcpy(p24_this_data->frames[F_QD_STORE_QUAD3], p24_this_data->frames[F_QD_STORE_QUAD0], std_pal_a2024_copper_list_size);
3074
3075 /*
3076 * Mark Id's
3077 */
3078 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 29));
3079 CBUMP(tmp);
3080 CMOVE(tmp, R_COLOR01, QUAD1_ID);
3081 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 29));
3082 CBUMP(tmp);
3083 CMOVE(tmp, R_COLOR01, QUAD2_ID);
3084 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 29));
3085 CBUMP(tmp);
3086 CMOVE(tmp, R_COLOR01, QUAD3_ID);
3087
3088 plane[0]--;
3089 plane[0]--;
3090 if (depth == 2) {
3091 plane[1]--;
3092 plane[1]--;
3093 }
3094 /*
3095 * Set bitplane pointers.
3096 */
3097 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2));
3098 CBUMP(tmp);
3099 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0])));
3100 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0])));
3101 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line])));
3102 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line])));
3103 if (depth == 2) {
3104 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0])));
3105 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0])));
3106 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line])));
3107 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line])));
3108 }
3109 #if defined (GRF_ECS) || defined (GRF_AGA)
3110 CMOVE(tmp, R_DIWHIGH, 0x2100);
3111 #endif
3112 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1])));
3113 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1])));
3114 CEND(tmp);
3115 CEND(tmp);
3116
3117 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2));
3118 CBUMP(tmp);
3119 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
3120 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
3121 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
3122 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
3123 if (depth == 2) {
3124 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
3125 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
3126 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
3127 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
3128 }
3129 #if defined (GRF_ECS) || defined (GRF_AGA)
3130 CMOVE(tmp, R_DIWHIGH, 0x2100);
3131 #endif
3132 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2])));
3133 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2])));
3134 CEND(tmp);
3135 CEND(tmp);
3136
3137 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2));
3138 CBUMP(tmp);
3139 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane])));
3140 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane])));
3141 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
3142 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
3143 if (depth == 2) {
3144 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane])));
3145 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane])));
3146 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
3147 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
3148 }
3149 #if defined (GRF_ECS) || defined (GRF_AGA)
3150 CMOVE(tmp, R_DIWHIGH, 0x2100);
3151 #endif
3152 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3])));
3153 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3])));
3154 CEND(tmp);
3155 CEND(tmp);
3156
3157 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2));
3158 CBUMP(tmp);
3159 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE])));
3160 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE])));
3161 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE])));
3162 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE])));
3163 if (depth == 2) {
3164 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE])));
3165 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE])));
3166 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE])));
3167 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE])));
3168 }
3169 #if defined (GRF_ECS) || defined (GRF_AGA)
3170 CMOVE(tmp, R_DIWHIGH, 0x2100);
3171 #endif
3172 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0])));
3173 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0])));
3174 CEND(tmp);
3175 CEND(tmp);
3176
3177 /* swap new pointers in. */
3178 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0;
3179 i <= F_QD_STORE_QUAD3; i++, j++) {
3180 cp = p24_this_data->frames[j];
3181 p24_this_data->frames[j] = p24_this_data->frames[i];
3182 p24_this_data->frames[i] = cp;
3183 }
3184
3185 p24_this_data->current_view = v;
3186 vd->flags |= VF_DISPLAY;
3187
3188 cc_a2024_use_colormap(v, vd->colormap);
3189 }
3190 cc_load_mode(p24_this);
3191 }
3192
3193 void
pal_a2024_mode_vbl_handler(dmode_t * d)3194 pal_a2024_mode_vbl_handler(dmode_t *d)
3195 {
3196 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
3197
3198 if (vp < 20) {
3199 custom.cop1lc = PREP_DMA_MEM(p24_this_data->frames[p24_this_data->hedley_current]);
3200 custom.copjmp1 = 0;
3201 }
3202 p24_this_data->hedley_current++;
3203 p24_this_data->hedley_current &= 0x3; /* if 4 then 0. */
3204 }
3205 #endif /* GRF_A2024 */
3206
3207 #if defined (GRF_AGA)
3208
3209 dmode_t *
cc_init_pal_aga(void)3210 cc_init_pal_aga(void)
3211 {
3212 /* this function should only be called once. */
3213 if (!paga_this && (custom.deniseid & 0xff) == 0xf8 &&
3214 aga_enable & AGA_ENABLE) {
3215 u_short len = aga_copper_list_len;
3216
3217 paga_this = &paga_mode;
3218 paga_this_data = &paga_mode_data;
3219 memset(paga_this, 0, sizeof(dmode_t));
3220 memset(paga_this_data, 0, sizeof(dmdata_t));
3221
3222 paga_this->name = "pal: AGA dbl";
3223 paga_this->nominal_size.width = 640;
3224 paga_this->nominal_size.height = 512;
3225 paga_this_data->max_size.width = 720;
3226 paga_this_data->max_size.height = 564;
3227 paga_this_data->min_size.width = 320;
3228 paga_this_data->min_size.height = 200;
3229 paga_this_data->min_depth = 1;
3230 paga_this_data->max_depth = 8;
3231 paga_this->data = paga_this_data;
3232
3233 paga_this->get_monitor = cc_get_monitor;
3234 paga_this->alloc_view = cc_alloc_view;
3235 paga_this->get_current_view = cc_get_current_view;
3236
3237 paga_this_data->use_colormap = cc_use_aga_colormap;
3238 paga_this_data->get_colormap = cc_get_colormap;
3239 paga_this_data->alloc_colormap = cc_alloc_aga_colormap;
3240 paga_this_data->display_view = display_pal_aga_view;
3241 paga_this_data->monitor = cc_monitor;
3242
3243 paga_this_data->frames = paga_frames;
3244 paga_this_data->frames[F_LONG] = alloc_chipmem(aga_copper_list_size * F_TOTAL);
3245 if (!paga_this_data->frames[F_LONG]) {
3246 panic("couldn't get chipmem for copper list");
3247 }
3248 paga_this_data->frames[F_STORE_LONG] = &paga_this_data->frames[F_LONG][len];
3249
3250 memcpy(paga_this_data->frames[F_STORE_LONG], aga_copper_list, aga_copper_list_size);
3251 memcpy(paga_this_data->frames[F_LONG], aga_copper_list, aga_copper_list_size);
3252
3253 paga_this_data->bplcon0 = 0x0240 | USE_CON3; /* color composite
3254 * enable,
3255 * shres. */
3256 paga_this_data->std_start_x = 0x4f /*STANDARD_VIEW_X*/;
3257 paga_this_data->std_start_y = 0x2b /*STANDARD_VIEW_Y*/;
3258 paga_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler;
3259 paga_this_data->beamcon0 = STANDARD_PAL_BEAMCON | (SPECIAL_BEAMCON ^ VSYNCTRUE);
3260
3261 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes,
3262 paga_this, link);
3263 }
3264 return (paga_this);
3265 }
3266
3267 /* static, so I can patch and play */
3268
3269 #ifdef GRF_AGA_VGA
3270 int pAGA_htotal = 0x079;
3271 int pAGA_vtotal = 0x24d;
3272 int pAGA_vbstop = 0x019;
3273 int pAGA_hcenter = 0x04b;
3274 #else
3275 int pAGA_htotal = 0x081;
3276 int pAGA_vtotal = 0x23d;
3277 int pAGA_vbstop = 0x017;
3278 int pAGA_hcenter = 0x04f;
3279 #endif
3280 int pAGA_hsstrt = 0x00f;
3281 int pAGA_hsstop = 0x019;
3282 int pAGA_hbstrt = 0x001;
3283 int pAGA_hbstop = 0x021;
3284 int pAGA_vsstrt = 0x001;
3285 int pAGA_vsstop = 0x008;
3286 int pAGA_vbstrt = 0x000;
3287
3288 void
display_pal_aga_view(view_t * v)3289 display_pal_aga_view(view_t *v)
3290 {
3291 if (paga_this_data->current_view != v) {
3292 vdata_t *vd = VDATA(v);
3293 cop_t *cp = paga_this_data->frames[F_STORE_LONG], *tmp;
3294 int depth = v->bitmap->depth, i;
3295 int hstart, hstop, vstart, vstop, j;
3296 int x, y, w = v->display.width, h = v->display.height;
3297 u_short ddfstart, ddfwidth, con1;
3298
3299 #ifdef DEBUG
3300 if (aga_enable & AGA_TRACE)
3301 printf("display_aga_view(%dx%dx%d) %p\n", w, h,
3302 depth, v);
3303 #endif
3304 /* round down to nearest even width */
3305 /* w &= 0xfffe; */
3306 /* calculate datafetch width. */
3307
3308 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 4) << 1;
3309
3310 /* this will center the any overscanned display */
3311 /* and allow user to modify. */
3312 x = v->display.x + paga_this_data->std_start_x - ((w - 640) >> 3);
3313 y = v->display.y + paga_this_data->std_start_y - ((h - 512) >> 1);
3314
3315 if (y & 1)
3316 y--;
3317
3318 if (!(x & 1))
3319 x--;
3320
3321 hstart = x;
3322 hstop = x + (w >> 2);
3323 vstart = y;
3324 vstop = y + (h >> 0);
3325 ddfstart = (hstart >> 1) - 8;
3326
3327 #ifdef DEBUG
3328 if (aga_enable & AGA_TRACE2) {
3329 printf (" ddfwidth %04x x %04x y %04x", ddfwidth,
3330 x, y);
3331 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n",
3332 hstart, hstop, vstart, vstop, ddfstart);
3333 }
3334 #endif
3335 /* check for hardware limits, AGA may allow more..? */
3336 /* anyone got a 4000 I can borrow :^) -ch */
3337 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
3338 int d = 0;
3339
3340 /* XXX anyone know the equality properties of
3341 * intermixed logial AND's */
3342 /* XXX and arithmetic operators? */
3343 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
3344 d++;
3345 }
3346
3347 ddfstart -= d;
3348 hstart -= d << 1;
3349 hstop -= d << 1;
3350 }
3351 /* correct the datafetch to proper limits. */
3352 /* delay the actual display of the data until we need it. */
3353 ddfstart &= 0xfffc;
3354 #ifdef DEBUG
3355 if (aga_enable & AGA_TRACE2) {
3356 printf (" ddfwidth %04x x %04x y %04x", ddfwidth,
3357 x, y);
3358 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n",
3359 hstart, hstop, vstart, vstop, ddfstart);
3360 }
3361 #endif
3362 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
3363
3364 if (paga_this_data->current_view) {
3365 VDATA(paga_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
3366 /* displayed. */
3367 }
3368 paga_this_data->current_view = v;
3369
3370 cp = paga_this_data->frames[F_STORE_LONG];
3371 tmp = cp;
3372 for (i = 0; i < 8; ++i) {
3373 if (tmp == NULL)
3374 break;
3375 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
3376 if (tmp == NULL)
3377 break;
3378 tmp->cp.inst.operand = 0x0ca1 | (i << 13);
3379 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
3380 if (tmp == NULL)
3381 break;
3382 tmp->cp.inst.operand = 0x0ea1 | (i << 13);
3383 }
3384 if (tmp)
3385 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
3386 if (tmp)
3387 tmp->cp.inst.operand = 0x0ca1;
3388 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
3389 tmp->cp.inst.operand = 0x8003;
3390 tmp = find_copper_inst(cp, CI_MOVE(R_HTOTAL));
3391 tmp->cp.inst.operand = pAGA_htotal; /* 81/71/73/79? */
3392 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTRT));
3393 tmp->cp.inst.operand = pAGA_hbstrt; /* 0x0008 */
3394 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTRT));
3395 tmp->cp.inst.operand = pAGA_hsstrt; /* 0x000e */
3396 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTOP));
3397 tmp->cp.inst.operand = pAGA_hsstop; /* 0x001c */
3398 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTOP));
3399 tmp->cp.inst.operand = pAGA_hsstop; /* 0x001e */
3400 tmp = find_copper_inst(cp, CI_MOVE(R_HCENTER));
3401 tmp->cp.inst.operand = pAGA_hcenter; /*AGA_htotal / 2 + AGA_hsstrt */
3402 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTRT));
3403 tmp->cp.inst.operand = pAGA_vbstrt; /* 0x0000 */
3404 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTRT));
3405 tmp->cp.inst.operand = pAGA_vsstrt; /* 0x016b / AGA_htotal */
3406 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTOP));
3407 tmp->cp.inst.operand = pAGA_vsstop; /* 0x02d6 / AGA_htotal */
3408 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTOP));
3409 tmp->cp.inst.operand = pAGA_vbstop; /* 0x0bd1 / AGA_htotal */
3410 tmp = find_copper_inst(cp, CI_MOVE(R_VTOTAL));
3411 tmp->cp.inst.operand = pAGA_vtotal;
3412 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
3413 tmp->cp.inst.operand = paga_this_data->beamcon0;
3414 #ifdef DEBUG
3415 if (aga_enable & AGA_TRACE2)
3416 printf(" beamcon0 %04x", tmp->cp.inst.operand);
3417 #endif
3418 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
3419 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
3420 #ifdef DEBUG
3421 if (aga_enable & AGA_TRACE2)
3422 printf(" diwhigh %04x>", tmp->cp.inst.operand);
3423 #endif
3424 #if 0
3425 tmp->cp.inst.operand = (vstop & 0x0700) | ((hstop & 0x0100) << 5);
3426 #endif
3427 #ifdef DEBUG
3428 if (aga_enable & AGA_TRACE2)
3429 printf("%04x", tmp->cp.inst.operand);
3430 #endif
3431 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
3432 tmp->cp.inst.operand = paga_this_data->bplcon0 |
3433 ((depth & 0x7) << 12) | ((depth & 0x8) << 1);
3434 #ifdef DEBUG
3435 if (aga_enable & AGA_TRACE2)
3436 printf(" bplcon0 %04x", tmp->cp.inst.operand);
3437 #endif
3438 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
3439 tmp->cp.inst.operand = con1;
3440 #ifdef DEBUG
3441 if (aga_enable & AGA_TRACE2)
3442 printf(" bplcon1 %04x>0000\n", con1);
3443 #endif
3444 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
3445 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
3446 #ifdef DEBUG
3447 if (aga_enable & AGA_TRACE2)
3448 printf(" diwstart %04x", tmp->cp.inst.operand);
3449 #endif
3450 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
3451 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
3452 #ifdef DEBUG
3453 if (aga_enable & AGA_TRACE2)
3454 printf(" diwstop %04x", tmp->cp.inst.operand);
3455 #endif
3456 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
3457 tmp->cp.inst.operand = ddfstart;
3458 #ifdef DEBUG
3459 if (aga_enable & AGA_TRACE2)
3460 printf(" ddfstart %04x", tmp->cp.inst.operand);
3461 #endif
3462 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
3463 tmp->cp.inst.operand = ddfstart + ddfwidth;
3464 #ifdef DEBUG
3465 if (aga_enable & AGA_TRACE2)
3466 printf(" ddfstop %04x", tmp->cp.inst.operand);
3467 #endif
3468
3469 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
3470 for (i = 0, j = 0; i < depth; j += 2, i++) {
3471 /* update the plane pointers */
3472 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
3473 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
3474 #ifdef DEBUG
3475 if (aga_enable & AGA_TRACE2)
3476 printf (" bpl%dpth %p", i, v->bitmap->plane[i]);
3477 #endif
3478 }
3479
3480 /* set mods correctly. */
3481 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
3482 tmp[0].cp.inst.operand = v->bitmap->row_mod;
3483 tmp[1].cp.inst.operand = v->bitmap->row_mod;
3484 #ifdef DEBUG
3485 if (aga_enable & AGA_TRACE2)
3486 printf(" bplxmod %04x\n", v->bitmap->row_mod);
3487 #endif
3488
3489 /* set next pointers correctly */
3490 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
3491 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(paga_this_data->frames[F_STORE_LONG]));
3492 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(paga_this_data->frames[F_STORE_LONG]));
3493
3494 cp = paga_this_data->frames[F_LONG];
3495 paga_this_data->frames[F_LONG] = paga_this_data->frames[F_STORE_LONG];
3496 paga_this_data->frames[F_STORE_LONG] = cp;
3497
3498 vd->flags |= VF_DISPLAY;
3499
3500 cc_use_aga_colormap(v, vd->colormap);
3501 }
3502 cc_load_mode(paga_this);
3503 #ifdef DEBUG
3504 if (aga_enable & AGA_TRACE)
3505 aga_enable |= AGA_TRACE2; /* XXXX */
3506 #endif
3507 }
3508
3509 #endif /* GRF_AGA */
3510 #endif /* GRF_PAL */
3511