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