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