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