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