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