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