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