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