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