grfabs_cc.c revision 1.11 1 /* $NetBSD: grfabs_cc.c,v 1.11 1996/04/21 21:11:28 veego 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 aga_this_data->std_start_x = 0x4f /*STANDARD_VIEW_X*/;
1846 aga_this_data->std_start_y = 0x2b /*STANDARD_VIEW_Y*/;
1847 aga_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler;
1848 aga_this_data->beamcon0 = SPECIAL_BEAMCON ^ VSYNCTRUE;
1849
1850 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes,
1851 aga_this, link);
1852 }
1853 return (aga_this);
1854 }
1855
1856 /* static, so I can patch and play */
1857
1858 int AGA_htotal = 0x79;
1859 int AGA_hsstrt = 0xe;
1860 int AGA_hsstop = 0x1c;
1861 int AGA_hbstrt = 0x8;
1862 int AGA_hbstop = 0x1e;
1863 int AGA_vtotal = 0x1ec;
1864 int AGA_vsstrt = 0x3;
1865 int AGA_vsstop = 0x6;
1866 int AGA_vbstrt = 0x0;
1867 int AGA_vbstop = 0x19;
1868 int AGA_hcenter = 0x4a;
1869
1870 void
1871 display_aga_view(v)
1872 view_t *v;
1873 {
1874 if (aga_this_data->current_view != v) {
1875 vdata_t *vd = VDATA(v);
1876 cop_t *cp = aga_this_data->frames[F_STORE_LONG], *tmp;
1877 int depth = v->bitmap->depth, i;
1878 int hstart, hstop, vstart, vstop, j;
1879 int x, y, w = v->display.width, h = v->display.height;
1880 u_short ddfstart, ddfwidth, con1;
1881
1882 #ifdef DEBUG
1883 if (aga_enable & AGA_TRACE)
1884 printf("display_aga_view(%dx%dx%d) %p\n", w, h,
1885 depth, v);
1886 #endif
1887 /* round down to nearest even width */
1888 /* w &= 0xfffe; */
1889 /* calculate datafetch width. */
1890
1891 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 4) << 1;
1892
1893 /* this will center the any overscanned display */
1894 /* and allow user to modify. */
1895 x = v->display.x + aga_this_data->std_start_x - ((w - 640) >> 3);
1896 y = v->display.y + aga_this_data->std_start_y - ((h - 400) >> 1);
1897
1898 if (y & 1)
1899 y--;
1900
1901 if (!(x & 1))
1902 x--;
1903
1904 hstart = x;
1905 hstop = x + (w >> 2);
1906 vstart = y;
1907 vstop = y + (h >> 0);
1908 ddfstart = (hstart >> 1) - 8;
1909
1910 #ifdef DEBUG
1911 if (aga_enable & AGA_TRACE2) {
1912 printf (" ddfwidth %04x x %04x y %04x", ddfwidth,
1913 x, y);
1914 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n",
1915 hstart, hstop, vstart, vstop, ddfstart);
1916 }
1917 #endif
1918 /* check for hardware limits, AGA may allow more..? */
1919 /* anyone got a 4000 I can borrow :^) -ch */
1920 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
1921 int d = 0;
1922
1923 /* XXX anyone know the equality properties of
1924 * intermixed logial AND's */
1925 /* XXX and arithmetic operators? */
1926 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
1927 d++;
1928 }
1929
1930 ddfstart -= d;
1931 hstart -= d << 1;
1932 hstop -= d << 1;
1933 }
1934 /* correct the datafetch to proper limits. */
1935 /* delay the actual display of the data until we need it. */
1936 ddfstart &= 0xfffc;
1937 #ifdef DEBUG
1938 if (aga_enable & AGA_TRACE2) {
1939 printf (" ddfwidth %04x x %04x y %04x", ddfwidth,
1940 x, y);
1941 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n",
1942 hstart, hstop, vstart, vstop, ddfstart);
1943 }
1944 #endif
1945 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
1946
1947 if (aga_this_data->current_view) {
1948 VDATA(aga_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
1949 /* displayed. */
1950 }
1951 aga_this_data->current_view = v;
1952
1953 cp = aga_this_data->frames[F_STORE_LONG];
1954 tmp = cp;
1955 for (i = 0; i < 8; ++i) {
1956 if (tmp == NULL)
1957 break;
1958 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
1959 if (tmp == NULL)
1960 break;
1961 tmp->cp.inst.operand = 0x0ca1 | (i << 13);
1962 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
1963 if (tmp == NULL)
1964 break;
1965 tmp->cp.inst.operand = 0x0ea1 | (i << 13);
1966 }
1967 if (tmp)
1968 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
1969 if (tmp)
1970 tmp->cp.inst.operand = 0x0ca1;
1971 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
1972 tmp->cp.inst.operand = 0x8003;
1973 tmp = find_copper_inst(cp, CI_MOVE(R_HTOTAL));
1974 tmp->cp.inst.operand = AGA_htotal; /* 81/71/73/79? */
1975 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTRT));
1976 tmp->cp.inst.operand = AGA_hbstrt; /* 0x0008 */
1977 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTRT));
1978 tmp->cp.inst.operand = AGA_hsstrt; /* 0x000e */
1979 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTOP));
1980 tmp->cp.inst.operand = AGA_hsstop; /* 0x001c */
1981 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTOP));
1982 tmp->cp.inst.operand = AGA_hsstop; /* 0x001e */
1983 tmp = find_copper_inst(cp, CI_MOVE(R_HCENTER));
1984 tmp->cp.inst.operand = AGA_hcenter; /*AGA_htotal / 2 + AGA_hsstrt */
1985 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTRT));
1986 tmp->cp.inst.operand = AGA_vbstrt; /* 0x0000 */
1987 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTRT));
1988 tmp->cp.inst.operand = AGA_vsstrt; /* 0x016b / AGA_htotal */
1989 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTOP));
1990 tmp->cp.inst.operand = AGA_vsstop; /* 0x02d6 / AGA_htotal */
1991 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTOP));
1992 tmp->cp.inst.operand = AGA_vbstop; /* 0x0bd1 / AGA_htotal */
1993 tmp = find_copper_inst(cp, CI_MOVE(R_VTOTAL));
1994 tmp->cp.inst.operand = AGA_vtotal;
1995 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
1996 tmp->cp.inst.operand = aga_this_data->beamcon0;
1997 #ifdef DEBUG
1998 if (aga_enable & AGA_TRACE2)
1999 printf(" beamcon0 %04x", tmp->cp.inst.operand);
2000 #endif
2001 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2002 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2003 #ifdef DEBUG
2004 if (aga_enable & AGA_TRACE2)
2005 printf(" diwhigh %04x>", tmp->cp.inst.operand);
2006 #endif
2007 #if 0
2008 tmp->cp.inst.operand = (vstop & 0x0700) | ((hstop & 0x0100) << 5);
2009 #endif
2010 #ifdef DEBUG
2011 if (aga_enable & AGA_TRACE2)
2012 printf("%04x", tmp->cp.inst.operand);
2013 #endif
2014 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2015 tmp->cp.inst.operand = aga_this_data->bplcon0 |
2016 ((depth & 0x7) << 12) | ((depth & 0x8) << 1);
2017 #ifdef DEBUG
2018 if (aga_enable & AGA_TRACE2)
2019 printf(" bplcon0 %04x", tmp->cp.inst.operand);
2020 #endif
2021 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2022 tmp->cp.inst.operand = con1;
2023 #ifdef DEBUG
2024 if (aga_enable & AGA_TRACE2)
2025 printf(" bplcon1 %04x>0000\n", con1);
2026 #endif
2027 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2028 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2029 #ifdef DEBUG
2030 if (aga_enable & AGA_TRACE2)
2031 printf(" diwstart %04x", tmp->cp.inst.operand);
2032 #endif
2033 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2034 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2035 #ifdef DEBUG
2036 if (aga_enable & AGA_TRACE2)
2037 printf(" diwstop %04x", tmp->cp.inst.operand);
2038 #endif
2039 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2040 tmp->cp.inst.operand = ddfstart;
2041 #ifdef DEBUG
2042 if (aga_enable & AGA_TRACE2)
2043 printf(" ddfstart %04x", tmp->cp.inst.operand);
2044 #endif
2045 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2046 tmp->cp.inst.operand = ddfstart + ddfwidth;
2047 #ifdef DEBUG
2048 if (aga_enable & AGA_TRACE2)
2049 printf(" ddfstop %04x", tmp->cp.inst.operand);
2050 #endif
2051
2052 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2053 for (i = 0, j = 0; i < depth; j += 2, i++) {
2054 /* update the plane pointers */
2055 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2056 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2057 #ifdef DEBUG
2058 if (aga_enable & AGA_TRACE2)
2059 printf (" bpl%dpth %p", i, v->bitmap->plane[i]);
2060 #endif
2061 }
2062
2063 /* set mods correctly. */
2064 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2065 tmp[0].cp.inst.operand = v->bitmap->row_mod;
2066 tmp[1].cp.inst.operand = v->bitmap->row_mod;
2067 #ifdef DEBUG
2068 if (aga_enable & AGA_TRACE2)
2069 printf(" bplxmod %04x\n", v->bitmap->row_mod);
2070 #endif
2071
2072 /* set next pointers correctly */
2073 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2074 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(aga_this_data->frames[F_STORE_LONG]));
2075 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(aga_this_data->frames[F_STORE_LONG]));
2076
2077 cp = aga_this_data->frames[F_LONG];
2078 aga_this_data->frames[F_LONG] = aga_this_data->frames[F_STORE_LONG];
2079 aga_this_data->frames[F_STORE_LONG] = cp;
2080
2081 vd->flags |= VF_DISPLAY;
2082
2083 cc_use_aga_colormap(v, vd->colormap);
2084 }
2085 cc_load_mode(aga_this);
2086 #ifdef DEBUG
2087 if (aga_enable & AGA_TRACE)
2088 aga_enable |= AGA_TRACE2; /* XXXX */
2089 #endif
2090 }
2091
2092 #endif /* GRF_AGA */
2093 #endif /* GRF_NTSC */
2094
2095 /*
2096 * PAL modes.
2097 */
2098
2099 #if defined (GRF_PAL)
2100
2101 dmode_t *
2102 cc_init_pal_hires()
2103 {
2104 /* this function should only be called once. */
2105 if (!ph_this) {
2106 u_short len = std_copper_list_len;
2107
2108 ph_this = &pal_hires_mode;
2109 ph_this_data = &pal_hires_mode_data;
2110 bzero(ph_this, sizeof(dmode_t));
2111 bzero(ph_this_data, sizeof(dmdata_t));
2112
2113 ph_this->name = "pal: hires";
2114 ph_this->nominal_size.width = 640;
2115 ph_this->nominal_size.height = 256;
2116 ph_this_data->max_size.width = 724;
2117 ph_this_data->max_size.height = 289;
2118 ph_this_data->min_size.width = 320;
2119 ph_this_data->min_size.height = 244;
2120 ph_this_data->min_depth = 1;
2121 ph_this_data->max_depth = 4;
2122 ph_this->data = ph_this_data;
2123
2124 ph_this->get_monitor = cc_get_monitor;
2125 ph_this->alloc_view = cc_alloc_view;
2126 ph_this->get_current_view = cc_get_current_view;
2127
2128 ph_this_data->use_colormap = cc_use_colormap;
2129 ph_this_data->get_colormap = cc_get_colormap;
2130 ph_this_data->alloc_colormap = cc_alloc_colormap;
2131 ph_this_data->display_view = display_pal_hires_view;
2132 ph_this_data->monitor = cc_monitor;
2133
2134 ph_this_data->frames = pal_hires_frames;
2135 ph_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL);
2136 if (!ph_this_data->frames[F_LONG]) {
2137 panic("couldn't get chipmem for copper list");
2138 }
2139 ph_this_data->frames[F_STORE_LONG] = &ph_this_data->frames[F_LONG][len];
2140
2141 bcopy(std_copper_list, ph_this_data->frames[F_STORE_LONG], std_copper_list_size);
2142 bcopy(std_copper_list, ph_this_data->frames[F_LONG], std_copper_list_size);
2143
2144 ph_this_data->bplcon0 = 0x8200 | USE_CON3; /* pal_hires, color
2145 * composite enable,
2146 * lace. */
2147 ph_this_data->std_start_x = STANDARD_VIEW_X;
2148 ph_this_data->std_start_y = STANDARD_VIEW_Y;
2149 ph_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler;
2150 #if defined (GRF_ECS) || defined (GRF_AGA)
2151 ph_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
2152 #endif
2153
2154 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, ph_this, link);
2155 }
2156 return (ph_this);
2157 }
2158
2159 void
2160 display_pal_hires_view(v)
2161 view_t *v;
2162 {
2163 if (ph_this_data->current_view != v) {
2164 vdata_t *vd = VDATA(v);
2165 cop_t *cp = ph_this_data->frames[F_STORE_LONG], *tmp;
2166 int depth = v->bitmap->depth, i;
2167 int hstart, hstop, vstart, vstop, j;
2168 int x, y, w = v->display.width, h = v->display.height;
2169 u_short ddfstart, ddfwidth, con1;
2170
2171 /* round down to nearest even width */
2172 /* w &= 0xfffe; */
2173
2174 /* calculate datafetch width. */
2175 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
2176
2177 /* This will center the any overscanned display */
2178 /* and allow user to modify. */
2179 x = v->display.x + ph_this_data->std_start_x - ((w - 640) >> 2);
2180 y = v->display.y + ph_this_data->std_start_y - ((h - 256) >> 1);
2181
2182 if (y & 1)
2183 y--;
2184
2185 if (!(x & 1))
2186 x--;
2187
2188 hstart = x;
2189 hstop = x + (w >> 1);
2190 vstart = y;
2191 vstop = y + h;
2192 ddfstart = (hstart - 9) >> 1;
2193 /* check for hardware limits, AGA may allow more..? */
2194 /* anyone got a 4000 I can borrow :^) -ch */
2195 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
2196 int d = 0;
2197
2198 /* XXX anyone know the equality properties of
2199 * intermixed logial AND's */
2200 /* XXX and arithmetic operators? */
2201 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
2202 d++;
2203 }
2204
2205 ddfstart -= d;
2206 hstart -= d << 1;
2207 hstop -= d << 1;
2208 }
2209 /* correct the datafetch to proper limits. */
2210 /* delay the actual display of the data until we need it. */
2211 ddfstart &= 0xfffc;
2212 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
2213
2214 if (ph_this_data->current_view) {
2215 VDATA(ph_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
2216 /* displayed. */
2217 }
2218 ph_this_data->current_view = v;
2219
2220 cp = ph_this_data->frames[F_STORE_LONG];
2221 #if defined (GRF_ECS) || defined (GRF_AGA)
2222 #if defined GRF_AGA
2223 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
2224 tmp->cp.inst.operand = 0;
2225 #endif
2226 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
2227 tmp->cp.inst.operand = ph_this_data->beamcon0;
2228 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2229 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2230 #endif /* ECS */
2231 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2232 tmp->cp.inst.operand = ph_this_data->bplcon0 | ((depth & 0x7) << 12);
2233 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2234 tmp->cp.inst.operand = con1;
2235 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2236 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2237 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2238 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2239 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2240 tmp->cp.inst.operand = ddfstart;
2241 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2242 tmp->cp.inst.operand = ddfstart + ddfwidth;
2243
2244 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2245 for (i = 0, j = 0; i < depth; j += 2, i++) {
2246 /* update the plane pointers */
2247 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2248 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2249 }
2250
2251 /* set mods correctly. */
2252 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2253 tmp[0].cp.inst.operand = v->bitmap->row_mod;
2254 tmp[1].cp.inst.operand = v->bitmap->row_mod;
2255
2256 /* set next pointers correctly */
2257 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2258 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG]));
2259 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG]));
2260
2261 cp = ph_this_data->frames[F_LONG];
2262 ph_this_data->frames[F_LONG] = ph_this_data->frames[F_STORE_LONG];
2263 ph_this_data->frames[F_STORE_LONG] = cp;
2264
2265 vd->flags |= VF_DISPLAY;
2266 cc_use_colormap(v, vd->colormap);
2267 }
2268 cc_load_mode(ph_this);
2269 }
2270
2271 dmode_t *
2272 cc_init_pal_hires_lace()
2273 {
2274 /* this function should only be called once. */
2275 if (!phl_this) {
2276 u_short len = std_copper_list_len;
2277
2278 phl_this = &pal_hires_lace_mode;
2279 phl_this_data = &pal_hires_lace_mode_data;
2280 bzero(phl_this, sizeof(dmode_t));
2281 bzero(phl_this_data, sizeof(dmdata_t));
2282
2283 phl_this->name = "pal: hires interlace";
2284 phl_this->nominal_size.width = 640;
2285 phl_this->nominal_size.height = 512;
2286 phl_this_data->max_size.width = 724;
2287 phl_this_data->max_size.height = 578;
2288 phl_this_data->min_size.width = 320;
2289 phl_this_data->min_size.height = 484;
2290 phl_this_data->min_depth = 1;
2291 phl_this_data->max_depth = 4;
2292 phl_this->data = phl_this_data;
2293
2294 phl_this->get_monitor = cc_get_monitor;
2295 phl_this->alloc_view = cc_alloc_view;
2296 phl_this->get_current_view = cc_get_current_view;
2297
2298 phl_this_data->use_colormap = cc_use_colormap;
2299 phl_this_data->get_colormap = cc_get_colormap;
2300 phl_this_data->alloc_colormap = cc_alloc_colormap;
2301 phl_this_data->display_view = display_pal_hires_lace_view;
2302 phl_this_data->monitor = cc_monitor;
2303
2304 phl_this_data->flags |= DMF_INTERLACE;
2305
2306 phl_this_data->frames = pal_hires_lace_frames;
2307 phl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL);
2308 if (!phl_this_data->frames[F_LACE_LONG]) {
2309 panic("couldn't get chipmem for copper list");
2310 }
2311 phl_this_data->frames[F_LACE_SHORT] = &phl_this_data->frames[F_LACE_LONG][len];
2312 phl_this_data->frames[F_LACE_STORE_LONG] = &phl_this_data->frames[F_LACE_SHORT][len];
2313 phl_this_data->frames[F_LACE_STORE_SHORT] = &phl_this_data->frames[F_LACE_STORE_LONG][len];
2314
2315 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size);
2316 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size);
2317 bcopy(std_copper_list, phl_this_data->frames[F_LACE_LONG], std_copper_list_size);
2318 bcopy(std_copper_list, phl_this_data->frames[F_LACE_SHORT], std_copper_list_size);
2319
2320 phl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
2321 * composite enable,
2322 * lace. */
2323 phl_this_data->std_start_x = STANDARD_VIEW_X;
2324 phl_this_data->std_start_y = STANDARD_VIEW_Y;
2325 phl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler;
2326 #if defined (GRF_ECS) || defined (GRF_AGA)
2327 phl_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
2328 #endif
2329
2330 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phl_this, link);
2331 }
2332 return (phl_this);
2333 }
2334
2335 void
2336 display_pal_hires_lace_view(v)
2337 view_t *v;
2338 {
2339 if (phl_this_data->current_view != v) {
2340 vdata_t *vd = VDATA(v);
2341 cop_t *cp = phl_this_data->frames[F_LACE_STORE_LONG], *tmp;
2342 int depth = v->bitmap->depth, i;
2343 int hstart, hstop, vstart, vstop, j;
2344 int x, y, w = v->display.width, h = v->display.height;
2345 u_short ddfstart, ddfwidth, con1;
2346
2347 /* round down to nearest even width */
2348 /* w &= 0xfffe; */
2349
2350 /* calculate datafetch width. */
2351 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
2352
2353 /* This will center the any overscanned display */
2354 /* and allow user to modify. */
2355 x = v->display.x + phl_this_data->std_start_x - ((w - 640) >> 2);
2356 y = v->display.y + phl_this_data->std_start_y - ((h - 512) >> 2);
2357
2358 if (y & 1)
2359 y--;
2360
2361 if (!(x & 1))
2362 x--;
2363
2364 hstart = x;
2365 hstop = x + (w >> 1);
2366 vstart = y;
2367 vstop = y + (h >> 1);
2368 ddfstart = (hstart - 9) >> 1;
2369
2370 /* check for hardware limits, AGA may allow more..? */
2371 /* anyone got a 4000 I can borrow :^) -ch */
2372 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
2373 int d = 0;
2374
2375 /* XXX anyone know the equality properties of
2376 * intermixed logial AND's */
2377 /* XXX and arithmetic operators? */
2378 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
2379 d++;
2380 }
2381
2382 ddfstart -= d;
2383 hstart -= d << 1;
2384 hstop -= d << 1;
2385 }
2386 /* correct the datafetch to proper limits. */
2387 /* delay the actual display of the data until we need it. */
2388 ddfstart &= 0xfffc;
2389 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
2390
2391 if (phl_this_data->current_view) {
2392 VDATA(phl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
2393 /* displayed. */
2394 }
2395 phl_this_data->current_view = v;
2396
2397 cp = phl_this_data->frames[F_LACE_STORE_LONG];
2398 #if defined (GRF_ECS) || defined (GRF_AGA)
2399 #if defined GRF_AGA
2400 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
2401 tmp->cp.inst.operand = 0;
2402 #endif
2403 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
2404 tmp->cp.inst.operand = phl_this_data->beamcon0;
2405 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2406 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2407 #endif /* ECS */
2408 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2409 tmp->cp.inst.operand = phl_this_data->bplcon0 | ((depth & 0x7) << 12);
2410 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2411 tmp->cp.inst.operand = con1;
2412 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2413 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2414 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2415 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2416 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2417 tmp->cp.inst.operand = ddfstart;
2418 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2419 tmp->cp.inst.operand = ddfstart + ddfwidth;
2420
2421 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2422 for (i = 0, j = 0; i < depth; j += 2, i++) {
2423 /* update the plane pointers */
2424 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2425 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
2426 }
2427
2428 /* set mods correctly. */
2429 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2430 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2431 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2432
2433 /* set next pointers correctly */
2434 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2435 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT]));
2436 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT]));
2437
2438
2439 bcopy(phl_this_data->frames[F_LACE_STORE_LONG], phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size);
2440
2441 /* these are the only ones that are different from long frame. */
2442 cp = phl_this_data->frames[F_LACE_STORE_SHORT];
2443 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2444 for (i = 0, j = 0; i < depth; j += 2, i++) {
2445 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2446 /* update plane pointers. high and low. */
2447 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
2448 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
2449 }
2450
2451 /* set next pointers correctly */
2452 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2453 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG]));
2454 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG]));
2455
2456
2457 cp = phl_this_data->frames[F_LACE_LONG];
2458 phl_this_data->frames[F_LACE_LONG] = phl_this_data->frames[F_LACE_STORE_LONG];
2459 phl_this_data->frames[F_LACE_STORE_LONG] = cp;
2460
2461 cp = phl_this_data->frames[F_LACE_SHORT];
2462 phl_this_data->frames[F_LACE_SHORT] = phl_this_data->frames[F_LACE_STORE_SHORT];
2463 phl_this_data->frames[F_LACE_STORE_SHORT] = cp;
2464
2465 vd->flags |= VF_DISPLAY;
2466 cc_use_colormap(v, vd->colormap);
2467 }
2468 cc_load_mode(phl_this);
2469 }
2470 #if defined (GRF_A2024)
2471
2472 dmode_t *
2473 cc_init_pal_hires_dlace()
2474 {
2475 /* this function should only be called once. */
2476 if (!phdl_this) {
2477 u_short len = std_dlace_copper_list_len;
2478
2479 phdl_this = &pal_hires_dlace_mode;
2480 phdl_this_data = &pal_hires_dlace_mode_data;
2481 bzero(phdl_this, sizeof(dmode_t));
2482 bzero(phdl_this_data, sizeof(dmdata_t));
2483
2484 phdl_this->name = "pal: hires double interlace";
2485 phdl_this->nominal_size.width = 640;
2486 phdl_this->nominal_size.height = 1024;
2487 phdl_this_data->max_size.width = 724;
2488 phdl_this_data->max_size.height = 1024;
2489 phdl_this_data->min_size.width = 320;
2490 phdl_this_data->min_size.height = 512;
2491 phdl_this_data->min_depth = 1;
2492 phdl_this_data->max_depth = 2;
2493 phdl_this->data = phdl_this_data;
2494
2495 phdl_this->get_monitor = cc_get_monitor;
2496 phdl_this->alloc_view = cc_alloc_view;
2497 phdl_this->get_current_view = cc_get_current_view;
2498
2499 phdl_this_data->use_colormap = cc_a2024_use_colormap;
2500 phdl_this_data->get_colormap = cc_a2024_get_colormap;
2501 phdl_this_data->alloc_colormap = cc_a2024_alloc_colormap;
2502 phdl_this_data->display_view = display_pal_hires_dlace_view;
2503 phdl_this_data->monitor = cc_monitor;
2504
2505 phdl_this_data->flags |= DMF_INTERLACE;
2506
2507 phdl_this_data->frames = pal_hires_dlace_frames;
2508 phdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL);
2509 if (!phdl_this_data->frames[F_LACE_LONG]) {
2510 panic("couldn't get chipmem for copper list");
2511 }
2512 phdl_this_data->frames[F_LACE_SHORT] = &phdl_this_data->frames[F_LACE_LONG][len];
2513 phdl_this_data->frames[F_LACE_STORE_LONG] = &phdl_this_data->frames[F_LACE_SHORT][len];
2514 phdl_this_data->frames[F_LACE_STORE_SHORT] = &phdl_this_data->frames[F_LACE_STORE_LONG][len];
2515
2516 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size);
2517 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size);
2518 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list_size);
2519 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list_size);
2520
2521 phdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
2522 * composite enable,
2523 * dlace. */
2524 phdl_this_data->std_start_x = STANDARD_VIEW_X;
2525 phdl_this_data->std_start_y = STANDARD_VIEW_Y;
2526 phdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler;
2527 #if defined (GRF_ECS) || defined (GRF_AGA)
2528 phdl_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
2529 #endif
2530
2531 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, phdl_this, link);
2532 }
2533 return (phdl_this);
2534 }
2535
2536 void
2537 display_pal_hires_dlace_view(v)
2538 view_t *v;
2539 {
2540 if (phdl_this_data->current_view != v) {
2541 vdata_t *vd = VDATA(v);
2542 cop_t *cp = phdl_this_data->frames[F_LACE_STORE_LONG], *tmp;
2543 int depth = v->bitmap->depth;
2544 int hstart, hstop, vstart, vstop;
2545 int x, y, w = v->display.width, h = v->display.height;
2546 u_short ddfstart, ddfwidth, con1;
2547 u_short mod1l, mod2l;
2548
2549 /* round down to nearest even width */
2550 /* w &= 0xfffe; */
2551
2552 /* calculate datafetch width. */
2553 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
2554
2555 /* This will center the any overscanned display */
2556 /* and allow user to modify. */
2557 x = v->display.x + phdl_this_data->std_start_x - ((w - 640) >> 2);
2558 y = v->display.y + phdl_this_data->std_start_y - ((h - 1024) >> 3);
2559
2560 if (y & 1)
2561 y--;
2562
2563 if (!(x & 1))
2564 x--;
2565
2566 hstart = x;
2567 hstop = x + (w >> 1);
2568 vstart = y;
2569 vstop = y + (h >> 2);
2570 ddfstart = (hstart - 9) >> 1;
2571
2572 /* check for hardware limits, AGA may allow more..? */
2573 /* anyone got a 4000 I can borrow :^) -ch */
2574 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
2575 int d = 0;
2576
2577 /* XXX anyone know the equality properties of
2578 * intermixed logial AND's */
2579 /* XXX and arithmetic operators? */
2580 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
2581 d++;
2582 }
2583
2584 ddfstart -= d;
2585 hstart -= d << 1;
2586 hstop -= d << 1;
2587 }
2588 /* correct the datafetch to proper limits. */
2589 /* delay the actual display of the data until we need it. */
2590 ddfstart &= 0xfffc;
2591 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
2592
2593 if (phdl_this_data->current_view) {
2594 VDATA(phdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
2595 /* displayed. */
2596 }
2597 phdl_this_data->current_view = v;
2598
2599 cp = phdl_this_data->frames[F_LACE_STORE_LONG];
2600 #if defined (GRF_ECS) || defined (GRF_AGA)
2601 #if defined GRF_AGA
2602 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
2603 tmp->cp.inst.operand = 0;
2604 #endif
2605 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
2606 tmp->cp.inst.operand = phdl_this_data->beamcon0;
2607 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2608 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2609 #endif /* ECS */
2610 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2611 tmp->cp.inst.operand = phdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */
2612 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2613 tmp->cp.inst.operand = con1;
2614 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2615 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2616 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2617 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2618 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2619 tmp->cp.inst.operand = ddfstart;
2620 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2621 tmp->cp.inst.operand = ddfstart + ddfwidth;
2622
2623 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2624 mod2l = mod1l << 1;
2625
2626 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2627 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* update plane
2628 * pointers. */
2629 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* high and low. */
2630 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* update plane
2631 * pointers. */
2632 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* high and low. */
2633 if (depth == 2) {
2634 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* update plane
2635 * pointers. */
2636 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* high and low. */
2637 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* update plane
2638 * pointers. */
2639 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* high and low. */
2640 }
2641 /* set mods correctly. */
2642 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2643 tmp[0].cp.inst.operand = mod2l + mod1l;
2644 tmp[1].cp.inst.operand = mod2l + mod1l;
2645
2646 /* set next pointers correctly */
2647 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2648 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT]));
2649 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT]));
2650
2651 bcopy(phdl_this_data->frames[F_LACE_STORE_LONG], phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size);
2652
2653 /* these are the only ones that are different from long frame. */
2654 cp = phdl_this_data->frames[F_LACE_STORE_SHORT];
2655 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2656 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* update plane
2657 * pointers. */
2658 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* high and low. */
2659 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* update plane
2660 * pointers. */
2661 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* high and low. */
2662 if (depth == 2) {
2663 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* update plane
2664 * pointers. */
2665 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* high and low. */
2666 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* update plane
2667 * pointers. */
2668 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* high and low. */
2669 }
2670 /* set next pointers correctly */
2671 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2672 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG]));
2673 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG]));
2674
2675 cp = phdl_this_data->frames[F_LACE_LONG];
2676 phdl_this_data->frames[F_LACE_LONG] = phdl_this_data->frames[F_LACE_STORE_LONG];
2677 phdl_this_data->frames[F_LACE_STORE_LONG] = cp;
2678
2679 cp = phdl_this_data->frames[F_LACE_SHORT];
2680 phdl_this_data->frames[F_LACE_SHORT] = phdl_this_data->frames[F_LACE_STORE_SHORT];
2681 phdl_this_data->frames[F_LACE_STORE_SHORT] = cp;
2682
2683 vd->flags |= VF_DISPLAY;
2684
2685 cc_a2024_use_colormap(v, vd->colormap);
2686 }
2687 cc_load_mode(phdl_this);
2688 }
2689
2690 dmode_t *
2691 cc_init_pal_a2024()
2692 {
2693 /* this function should only be called once. */
2694 if (!p24_this) {
2695 int i;
2696 u_short len = std_pal_a2024_copper_list_len;
2697 cop_t *cp;
2698
2699 p24_this = &pal_a2024_mode;
2700 p24_this_data = &pal_a2024_mode_data;
2701 bzero(p24_this, sizeof(dmode_t));
2702 bzero(p24_this_data, sizeof(dmdata_t));
2703
2704 p24_this->name = "pal: A2024 15khz";
2705 p24_this->nominal_size.width = 1024;
2706 p24_this->nominal_size.height = 1024;
2707 p24_this_data->max_size.width = 1024;
2708 p24_this_data->max_size.height = 1024;
2709 p24_this_data->min_size.width = 1024;
2710 p24_this_data->min_size.height = 1024;
2711 p24_this_data->min_depth = 1;
2712 p24_this_data->max_depth = 2;
2713 p24_this->data = p24_this_data;
2714
2715 p24_this->get_monitor = cc_get_monitor;
2716 p24_this->alloc_view = cc_alloc_view;
2717 p24_this->get_current_view = cc_get_current_view;
2718
2719 p24_this_data->use_colormap = cc_a2024_use_colormap;
2720 p24_this_data->get_colormap = cc_a2024_get_colormap;
2721 p24_this_data->display_view = display_pal_a2024_view;
2722 p24_this_data->alloc_colormap = cc_a2024_alloc_colormap;
2723 p24_this_data->monitor = cc_monitor;
2724
2725 p24_this_data->flags |= DMF_HEDLEY_EXP;
2726
2727 p24_this_data->frames = pal_a2024_frames;
2728 p24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_pal_a2024_copper_list_size * F_QD_TOTAL);
2729 if (!p24_this_data->frames[F_QD_QUAD0]) {
2730 panic("couldn't get chipmem for copper list");
2731 }
2732 /* setup the hedley init bitplane. */
2733 hedley_init = alloc_chipmem(128);
2734 if (!hedley_init) {
2735 panic("couldn't get chipmem for hedley init bitplane");
2736 }
2737 for (i = 1; i < 128; i++)
2738 hedley_init[i] = 0xff;
2739 hedley_init[0] = 0x03;
2740
2741 /* copy image of standard copper list. */
2742 bcopy(std_pal_a2024_copper_list, p24_this_data->frames[0], std_pal_a2024_copper_list_size);
2743
2744 /* set the init plane pointer. */
2745 cp = find_copper_inst(p24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH));
2746 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init));
2747 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init));
2748
2749 for (i = 1; i < F_QD_TOTAL; i++) {
2750 p24_this_data->frames[i] = &p24_this_data->frames[i - 1][len];
2751 bcopy(p24_this_data->frames[0], p24_this_data->frames[i], std_pal_a2024_copper_list_size);
2752 }
2753
2754 p24_this_data->bplcon0 = 0x8200; /* hires */
2755 p24_this_data->vbl_handler = (vbl_handler_func *) pal_a2024_mode_vbl_handler;
2756
2757
2758 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes, p24_this, link);
2759 }
2760 return (p24_this);
2761 }
2762
2763 void
2764 display_pal_a2024_view(v)
2765 view_t *v;
2766 {
2767 if (p24_this_data->current_view != v) {
2768 vdata_t *vd = VDATA(v);
2769 cop_t *cp, *tmp;
2770 u_char *inst_plane[2];
2771 u_char **plane = inst_plane;
2772 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2773 u_long half_plane = full_line * v->bitmap->rows / 2;
2774
2775 int depth = v->bitmap->depth, i, j;
2776
2777 plane[0] = v->bitmap->plane[0];
2778 if (depth == 2) {
2779 plane[1] = v->bitmap->plane[1];
2780 }
2781 if (p24_this_data->current_view) {
2782 VDATA(p24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer
2783 * displayed. */
2784 }
2785 cp = p24_this_data->frames[F_QD_STORE_QUAD0];
2786 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F));
2787 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */
2788 tmp->cp.inst.operand = p24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */
2789
2790 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD1], std_pal_a2024_copper_list_size);
2791 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD2], std_pal_a2024_copper_list_size);
2792 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD3], std_pal_a2024_copper_list_size);
2793
2794 /*
2795 * Mark Id's
2796 */
2797 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 29));
2798 CBUMP(tmp);
2799 CMOVE(tmp, R_COLOR01, QUAD1_ID);
2800 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 29));
2801 CBUMP(tmp);
2802 CMOVE(tmp, R_COLOR01, QUAD2_ID);
2803 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 29));
2804 CBUMP(tmp);
2805 CMOVE(tmp, R_COLOR01, QUAD3_ID);
2806
2807 plane[0]--;
2808 plane[0]--;
2809 if (depth == 2) {
2810 plane[1]--;
2811 plane[1]--;
2812 }
2813 /*
2814 * Set bitplane pointers.
2815 */
2816 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2));
2817 CBUMP(tmp);
2818 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0])));
2819 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0])));
2820 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line])));
2821 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line])));
2822 if (depth == 2) {
2823 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0])));
2824 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0])));
2825 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line])));
2826 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line])));
2827 }
2828 #if defined (GRF_ECS) || defined (GRF_AGA)
2829 CMOVE(tmp, R_DIWHIGH, 0x2100);
2830 #endif
2831 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1])));
2832 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1])));
2833 CEND(tmp);
2834 CEND(tmp);
2835
2836 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2));
2837 CBUMP(tmp);
2838 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
2839 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
2840 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
2841 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
2842 if (depth == 2) {
2843 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
2844 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
2845 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
2846 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
2847 }
2848 #if defined (GRF_ECS) || defined (GRF_AGA)
2849 CMOVE(tmp, R_DIWHIGH, 0x2100);
2850 #endif
2851 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2])));
2852 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2])));
2853 CEND(tmp);
2854 CEND(tmp);
2855
2856 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2));
2857 CBUMP(tmp);
2858 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane])));
2859 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane])));
2860 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
2861 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
2862 if (depth == 2) {
2863 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane])));
2864 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane])));
2865 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
2866 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
2867 }
2868 #if defined (GRF_ECS) || defined (GRF_AGA)
2869 CMOVE(tmp, R_DIWHIGH, 0x2100);
2870 #endif
2871 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3])));
2872 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3])));
2873 CEND(tmp);
2874 CEND(tmp);
2875
2876 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2));
2877 CBUMP(tmp);
2878 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE])));
2879 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE])));
2880 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE])));
2881 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE])));
2882 if (depth == 2) {
2883 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE])));
2884 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE])));
2885 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE])));
2886 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE])));
2887 }
2888 #if defined (GRF_ECS) || defined (GRF_AGA)
2889 CMOVE(tmp, R_DIWHIGH, 0x2100);
2890 #endif
2891 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0])));
2892 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0])));
2893 CEND(tmp);
2894 CEND(tmp);
2895
2896 /* swap new pointers in. */
2897 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0;
2898 i <= F_QD_STORE_QUAD3; i++, j++) {
2899 cp = p24_this_data->frames[j];
2900 p24_this_data->frames[j] = p24_this_data->frames[i];
2901 p24_this_data->frames[i] = cp;
2902 }
2903
2904 p24_this_data->current_view = v;
2905 vd->flags |= VF_DISPLAY;
2906
2907 cc_a2024_use_colormap(v, vd->colormap);
2908 }
2909 cc_load_mode(p24_this);
2910 }
2911
2912 void
2913 pal_a2024_mode_vbl_handler(d)
2914 dmode_t *d;
2915 {
2916 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
2917
2918 if (vp < 20) {
2919 custom.cop1lc = PREP_DMA_MEM(p24_this_data->frames[p24_this_data->hedley_current]);
2920 custom.copjmp1 = 0;
2921 }
2922 p24_this_data->hedley_current++;
2923 p24_this_data->hedley_current &= 0x3; /* if 4 then 0. */
2924 }
2925 #endif /* GRF_A2024 */
2926
2927 #if defined (GRF_AGA)
2928
2929 dmode_t *
2930 cc_init_pal_aga()
2931 {
2932 /* this function should only be called once. */
2933 if (!paga_this && (custom.deniseid & 0xff) == 0xf8 &&
2934 aga_enable & AGA_ENABLE) {
2935 u_short len = aga_copper_list_len;
2936
2937 paga_this = &paga_mode;
2938 paga_this_data = &paga_mode_data;
2939 bzero(paga_this, sizeof(dmode_t));
2940 bzero(paga_this_data, sizeof(dmdata_t));
2941
2942 paga_this->name = "pal: AGA dbl";
2943 paga_this->nominal_size.width = 640;
2944 paga_this->nominal_size.height = 512;
2945 paga_this_data->max_size.width = 720;
2946 paga_this_data->max_size.height = 564;
2947 paga_this_data->min_size.width = 320;
2948 paga_this_data->min_size.height = 200;
2949 paga_this_data->min_depth = 1;
2950 paga_this_data->max_depth = 8;
2951 paga_this->data = paga_this_data;
2952
2953 paga_this->get_monitor = cc_get_monitor;
2954 paga_this->alloc_view = cc_alloc_view;
2955 paga_this->get_current_view = cc_get_current_view;
2956
2957 paga_this_data->use_colormap = cc_use_aga_colormap;
2958 paga_this_data->get_colormap = cc_get_colormap;
2959 paga_this_data->alloc_colormap = cc_alloc_aga_colormap;
2960 paga_this_data->display_view = display_pal_aga_view;
2961 paga_this_data->monitor = cc_monitor;
2962
2963 paga_this_data->frames = paga_frames;
2964 paga_this_data->frames[F_LONG] = alloc_chipmem(aga_copper_list_size * F_TOTAL);
2965 if (!paga_this_data->frames[F_LONG]) {
2966 panic("couldn't get chipmem for copper list");
2967 }
2968 paga_this_data->frames[F_STORE_LONG] = &paga_this_data->frames[F_LONG][len];
2969
2970 bcopy(aga_copper_list, paga_this_data->frames[F_STORE_LONG], aga_copper_list_size);
2971 bcopy(aga_copper_list, paga_this_data->frames[F_LONG], aga_copper_list_size);
2972
2973 paga_this_data->bplcon0 = 0x0240 | USE_CON3; /* color composite
2974 * enable,
2975 * shres. */
2976 paga_this_data->std_start_x = 0x4f /*STANDARD_VIEW_X*/;
2977 paga_this_data->std_start_y = 0x2b /*STANDARD_VIEW_Y*/;
2978 paga_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler;
2979 paga_this_data->beamcon0 = STANDARD_PAL_BEAMCON | (SPECIAL_BEAMCON ^ VSYNCTRUE);
2980
2981 LIST_INSERT_HEAD(&MDATA(cc_monitor)->modes,
2982 paga_this, link);
2983 }
2984 return (paga_this);
2985 }
2986
2987 /* static, so I can patch and play (VGAOnly is commented-out) */
2988
2989 int pAGA_htotal = 0x081; /* 0x079 */
2990 int pAGA_hsstrt = 0x00f; /* 0x00f */
2991 int pAGA_hsstop = 0x019; /* 0x019 */
2992 int pAGA_hbstrt = 0x001; /* 0x001 */
2993 int pAGA_hbstop = 0x021; /* 0x021 */
2994 int pAGA_vtotal = 0x23d; /* 0x24d */
2995 int pAGA_vsstrt = 0x001; /* 0x001 */
2996 int pAGA_vsstop = 0x008; /* 0x008 */
2997 int pAGA_vbstrt = 0x000; /* 0x000 */
2998 int pAGA_vbstop = 0x017; /* 0x019 */
2999 int pAGA_hcenter = 0x04f; /* 0x04b */
3000
3001 void
3002 display_pal_aga_view(v)
3003 view_t *v;
3004 {
3005 if (paga_this_data->current_view != v) {
3006 vdata_t *vd = VDATA(v);
3007 cop_t *cp = paga_this_data->frames[F_STORE_LONG], *tmp;
3008 int depth = v->bitmap->depth, i;
3009 int hstart, hstop, vstart, vstop, j;
3010 int x, y, w = v->display.width, h = v->display.height;
3011 u_short ddfstart, ddfwidth, con1;
3012
3013 #ifdef DEBUG
3014 if (aga_enable & AGA_TRACE)
3015 printf("display_aga_view(%dx%dx%d) %p\n", w, h,
3016 depth, v);
3017 #endif
3018 /* round down to nearest even width */
3019 /* w &= 0xfffe; */
3020 /* calculate datafetch width. */
3021
3022 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 4) << 1;
3023
3024 /* this will center the any overscanned display */
3025 /* and allow user to modify. */
3026 x = v->display.x + paga_this_data->std_start_x - ((w - 640) >> 3);
3027 y = v->display.y + paga_this_data->std_start_y - ((h - 512) >> 1);
3028
3029 if (y & 1)
3030 y--;
3031
3032 if (!(x & 1))
3033 x--;
3034
3035 hstart = x;
3036 hstop = x + (w >> 2);
3037 vstart = y;
3038 vstop = y + (h >> 0);
3039 ddfstart = (hstart >> 1) - 8;
3040
3041 #ifdef DEBUG
3042 if (aga_enable & AGA_TRACE2) {
3043 printf (" ddfwidth %04x x %04x y %04x", ddfwidth,
3044 x, y);
3045 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n",
3046 hstart, hstop, vstart, vstop, ddfstart);
3047 }
3048 #endif
3049 /* check for hardware limits, AGA may allow more..? */
3050 /* anyone got a 4000 I can borrow :^) -ch */
3051 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
3052 int d = 0;
3053
3054 /* XXX anyone know the equality properties of
3055 * intermixed logial AND's */
3056 /* XXX and arithmetic operators? */
3057 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
3058 d++;
3059 }
3060
3061 ddfstart -= d;
3062 hstart -= d << 1;
3063 hstop -= d << 1;
3064 }
3065 /* correct the datafetch to proper limits. */
3066 /* delay the actual display of the data until we need it. */
3067 ddfstart &= 0xfffc;
3068 #ifdef DEBUG
3069 if (aga_enable & AGA_TRACE2) {
3070 printf (" ddfwidth %04x x %04x y %04x", ddfwidth,
3071 x, y);
3072 printf (" hstart %04x hstop %04x vstart %04x vstop %04x ddfstart %04x\n",
3073 hstart, hstop, vstart, vstop, ddfstart);
3074 }
3075 #endif
3076 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
3077
3078 if (paga_this_data->current_view) {
3079 VDATA(paga_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
3080 /* displayed. */
3081 }
3082 paga_this_data->current_view = v;
3083
3084 cp = paga_this_data->frames[F_STORE_LONG];
3085 tmp = cp;
3086 for (i = 0; i < 8; ++i) {
3087 if (tmp == NULL)
3088 break;
3089 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
3090 if (tmp == NULL)
3091 break;
3092 tmp->cp.inst.operand = 0x0ca1 | (i << 13);
3093 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
3094 if (tmp == NULL)
3095 break;
3096 tmp->cp.inst.operand = 0x0ea1 | (i << 13);
3097 }
3098 if (tmp)
3099 tmp = find_copper_inst(tmp + 1, CI_MOVE(R_BPLCON3));
3100 if (tmp)
3101 tmp->cp.inst.operand = 0x0ca1;
3102 tmp = find_copper_inst(cp, CI_MOVE(R_FMODE));
3103 tmp->cp.inst.operand = 0x8003;
3104 tmp = find_copper_inst(cp, CI_MOVE(R_HTOTAL));
3105 tmp->cp.inst.operand = pAGA_htotal; /* 81/71/73/79? */
3106 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTRT));
3107 tmp->cp.inst.operand = pAGA_hbstrt; /* 0x0008 */
3108 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTRT));
3109 tmp->cp.inst.operand = pAGA_hsstrt; /* 0x000e */
3110 tmp = find_copper_inst(cp, CI_MOVE(R_HSSTOP));
3111 tmp->cp.inst.operand = pAGA_hsstop; /* 0x001c */
3112 tmp = find_copper_inst(cp, CI_MOVE(R_HBSTOP));
3113 tmp->cp.inst.operand = pAGA_hsstop; /* 0x001e */
3114 tmp = find_copper_inst(cp, CI_MOVE(R_HCENTER));
3115 tmp->cp.inst.operand = pAGA_hcenter; /*AGA_htotal / 2 + AGA_hsstrt */
3116 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTRT));
3117 tmp->cp.inst.operand = pAGA_vbstrt; /* 0x0000 */
3118 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTRT));
3119 tmp->cp.inst.operand = pAGA_vsstrt; /* 0x016b / AGA_htotal */
3120 tmp = find_copper_inst(cp, CI_MOVE(R_VSSTOP));
3121 tmp->cp.inst.operand = pAGA_vsstop; /* 0x02d6 / AGA_htotal */
3122 tmp = find_copper_inst(cp, CI_MOVE(R_VBSTOP));
3123 tmp->cp.inst.operand = pAGA_vbstop; /* 0x0bd1 / AGA_htotal */
3124 tmp = find_copper_inst(cp, CI_MOVE(R_VTOTAL));
3125 tmp->cp.inst.operand = pAGA_vtotal;
3126 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
3127 tmp->cp.inst.operand = paga_this_data->beamcon0;
3128 #ifdef DEBUG
3129 if (aga_enable & AGA_TRACE2)
3130 printf(" beamcon0 %04x", tmp->cp.inst.operand);
3131 #endif
3132 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
3133 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
3134 #ifdef DEBUG
3135 if (aga_enable & AGA_TRACE2)
3136 printf(" diwhigh %04x>", tmp->cp.inst.operand);
3137 #endif
3138 #if 0
3139 tmp->cp.inst.operand = (vstop & 0x0700) | ((hstop & 0x0100) << 5);
3140 #endif
3141 #ifdef DEBUG
3142 if (aga_enable & AGA_TRACE2)
3143 printf("%04x", tmp->cp.inst.operand);
3144 #endif
3145 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
3146 tmp->cp.inst.operand = paga_this_data->bplcon0 |
3147 ((depth & 0x7) << 12) | ((depth & 0x8) << 1);
3148 #ifdef DEBUG
3149 if (aga_enable & AGA_TRACE2)
3150 printf(" bplcon0 %04x", tmp->cp.inst.operand);
3151 #endif
3152 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
3153 tmp->cp.inst.operand = con1;
3154 #ifdef DEBUG
3155 if (aga_enable & AGA_TRACE2)
3156 printf(" bplcon1 %04x>0000\n", con1);
3157 #endif
3158 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
3159 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
3160 #ifdef DEBUG
3161 if (aga_enable & AGA_TRACE2)
3162 printf(" diwstart %04x", tmp->cp.inst.operand);
3163 #endif
3164 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
3165 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
3166 #ifdef DEBUG
3167 if (aga_enable & AGA_TRACE2)
3168 printf(" diwstop %04x", tmp->cp.inst.operand);
3169 #endif
3170 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
3171 tmp->cp.inst.operand = ddfstart;
3172 #ifdef DEBUG
3173 if (aga_enable & AGA_TRACE2)
3174 printf(" ddfstart %04x", tmp->cp.inst.operand);
3175 #endif
3176 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
3177 tmp->cp.inst.operand = ddfstart + ddfwidth;
3178 #ifdef DEBUG
3179 if (aga_enable & AGA_TRACE2)
3180 printf(" ddfstop %04x", tmp->cp.inst.operand);
3181 #endif
3182
3183 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
3184 for (i = 0, j = 0; i < depth; j += 2, i++) {
3185 /* update the plane pointers */
3186 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
3187 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
3188 #ifdef DEBUG
3189 if (aga_enable & AGA_TRACE2)
3190 printf (" bpl%dpth %p", i, v->bitmap->plane[i]);
3191 #endif
3192 }
3193
3194 /* set mods correctly. */
3195 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
3196 tmp[0].cp.inst.operand = v->bitmap->row_mod;
3197 tmp[1].cp.inst.operand = v->bitmap->row_mod;
3198 #ifdef DEBUG
3199 if (aga_enable & AGA_TRACE2)
3200 printf(" bplxmod %04x\n", v->bitmap->row_mod);
3201 #endif
3202
3203 /* set next pointers correctly */
3204 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
3205 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(paga_this_data->frames[F_STORE_LONG]));
3206 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(paga_this_data->frames[F_STORE_LONG]));
3207
3208 cp = paga_this_data->frames[F_LONG];
3209 paga_this_data->frames[F_LONG] = paga_this_data->frames[F_STORE_LONG];
3210 paga_this_data->frames[F_STORE_LONG] = cp;
3211
3212 vd->flags |= VF_DISPLAY;
3213
3214 cc_use_aga_colormap(v, vd->colormap);
3215 }
3216 cc_load_mode(paga_this);
3217 #ifdef DEBUG
3218 if (aga_enable & AGA_TRACE)
3219 aga_enable |= AGA_TRACE2; /* XXXX */
3220 #endif
3221 }
3222
3223 #endif /* GRF_AGA */
3224 #endif /* GRF_PAL */
3225