grfabs_cc.c revision 1.1 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.1 1994/02/13 21:10:31 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
40 #include <amiga/amiga/custom.h>
41 #include <amiga/amiga/dlists.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 extern dll_list_t *monitors;
55
56 #if defined (GRF_PAL)
57 # if defined (GRF_A2024)
58 dmode_t pal_a2024_mode;
59 dmdata_t pal_a2024_mode_data;
60 cop_t *pal_a2024_frames[F_QD_TOTAL];
61 u_char *hedley_init; /* init bitplane. */
62 dmode_t *p24_this;
63 dmdata_t *p24_this_data;
64
65 dmode_t pal_hires_dlace_mode;
66 dmdata_t pal_hires_dlace_mode_data;
67 cop_t *pal_hires_dlace_frames[F_LACE_TOTAL];
68 dmode_t *phdl_this;
69 dmdata_t *phdl_this_data;
70 # endif /* GRF_A2024 */
71
72 dmode_t pal_hires_lace_mode;
73 dmdata_t pal_hires_lace_mode_data;
74 cop_t *pal_hires_lace_frames[F_LACE_TOTAL];
75 dmode_t *phl_this;
76 dmdata_t *phl_this_data;
77
78 dmode_t pal_hires_mode;
79 dmdata_t pal_hires_mode_data;
80 cop_t *pal_hires_frames[F_TOTAL];
81 dmode_t *ph_this;
82 dmdata_t *ph_this_data;
83 #endif /* PAL */
84
85 #if defined (GRF_NTSC)
86 # if defined (GRF_A2024)
87 dmode_t a2024_mode;
88 dmdata_t a2024_mode_data;
89 cop_t *a2024_frames[F_QD_TOTAL];
90 u_char *hedley_init; /* init bitplane. */
91 dmode_t *a24_this;
92 dmdata_t *a24_this_data;
93
94 dmode_t hires_dlace_mode;
95 dmdata_t hires_dlace_mode_data;
96 cop_t *hires_dlace_frames[F_LACE_TOTAL];
97 dmode_t *hdl_this;
98 dmdata_t *hdl_this_data;
99 # endif /* GRF_A2024 */
100
101 dmode_t hires_lace_mode;
102 dmdata_t hires_lace_mode_data;
103 cop_t *hires_lace_frames[F_LACE_TOTAL];
104 dmode_t *hl_this;
105 dmdata_t *hl_this_data;
106
107 void display_hires_view(view_t * v);
108 dmode_t hires_mode;
109 dmdata_t hires_mode_data;
110 cop_t *hires_frames[F_TOTAL];
111 dmode_t *h_this;
112 dmdata_t *h_this_data;
113 #endif /* GRF_NTSC */
114
115
116 /* monitor functions. */
117 monitor_t *
118 cc_init_monitor()
119 {
120 if (!m_this) {
121 cop_t *cp;
122 cc_monitor = m_this = &monitor;
123
124 /* turn sprite DMA off. we don't support them yet. */
125 custom.dmacon = DMAF_SPRITE;
126
127 m_this->node.next = m_this->node.prev = NULL;
128 m_this->name = monitor_name;
129 m_this_data = m_this->data = &monitor_data;
130
131 m_this->get_current_mode = get_current_mode;
132 m_this->vbl_handler = (vbl_handler_func *) monitor_vbl_handler;
133 m_this->get_next_mode = get_next_mode;
134 m_this->get_best_mode = get_best_mode;
135
136 m_this->alloc_bitmap = alloc_bitmap;
137 m_this->free_bitmap = free_bitmap;
138
139 m_this_data->current_mode = NULL;
140 dinit_list(&m_this_data->modes);
141
142 cp = null_mode_copper_list = alloc_chipmem(sizeof(cop_t) * 4);
143 if (!cp) {
144 panic("no chipmem for grf.");
145 }
146 CMOVE(cp, R_COLOR00, 0x0000); /* background is black */
147 CMOVE(cp, R_BPLCON0, 0x0000); /* no planes to fetch from */
148 CWAIT(cp, 255, 255); /* COPEND */
149 CWAIT(cp, 255, 255); /* COPEND really */
150
151 /* install m_this list and turn DMA on */
152 custom.cop1lc = PREP_DMA_MEM(null_mode_copper_list);
153 custom.copjmp1 = 0;
154 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER \
155 |DMAF_COPPER;
156
157 cc_init_modes();
158 dadd_tail(monitors, &m_this->node);
159 }
160 return (m_this);
161 }
162
163 void
164 monitor_vbl_handler(m)
165 monitor_t *m;
166 {
167 if (m_this_data->current_mode) {
168 DMDATA(m_this_data->current_mode)->vbl_handler(m_this_data->current_mode);
169 }
170 }
171
172 dmode_t *
173 get_current_mode()
174 {
175 if (m_this_data->current_mode) {
176 return (m_this_data->current_mode);
177 } else {
178 return (NULL);
179 }
180 }
181
182 dmode_t *
183 get_next_mode(d)
184 dmode_t *d;
185 {
186 if (d) {
187 if (d->node.next->next) {
188 return ((dmode_t *) d->node.next);
189 }
190 } else
191 if (m_this_data->modes.head->next) {
192 return ((dmode_t *) m_this_data->modes.head);
193 } else {
194 return (NULL);
195 }
196 }
197
198 /* XXX needs to have more control attributes */
199 dmode_t *
200 get_best_mode(size, depth)
201 dimen_t *size;
202 u_char depth;
203 {
204 dmode_t *save = NULL;
205 dmode_t *m = (dmode_t *) m_this_data->modes.head;
206 long dt;
207
208 while (m->node.next) {
209 long dx, dy, ct;
210 dmdata_t *dmd = m->data;
211
212 if (depth > dmd->max_depth || depth < dmd->min_depth) {
213 m = (dmode_t *) m->node.next;
214 continue;
215 }
216 if (size->width > dmd->max_size.width ||
217 size->height > dmd->max_size.height) {
218 m = (dmode_t *) m->node.next;
219 continue;
220 }
221 if (size->width < dmd->min_size.width ||
222 size->height < dmd->min_size.height) {
223 m = (dmode_t *) m->node.next;
224 continue;
225 }
226 dx = abs(m->nominal_size.width - size->width);
227 dy = abs(m->nominal_size.height - size->height);
228 ct = dx + dy;
229
230 if (ct < dt || save == NULL) {
231 save = m;
232 dt = ct;
233 }
234 m = (dmode_t *) m->node.next;
235 }
236 return (save);
237 }
238 /* bitmap functions */
239 bmap_t *
240 alloc_bitmap(width, height, depth, flags)
241 u_short width, height, depth, flags;
242 {
243 int i;
244 u_long total_size;
245 u_short lwpr = (width + 31) / 32;
246 u_short wpr = lwpr << 1;
247 u_short bpr = wpr << 1;
248 u_short array_size = sizeof(u_char *) * depth;
249 u_long plane_size = bpr * height;
250 u_short temp_size = bpr + sizeof(u_long);
251 bmap_t *bm;
252
253 /* note the next allocation will give everything, also note that all
254 * the stuff we want (including bitmaps) will be long short aligned.
255 * M_This is a function of the data being allocated and the fact that
256 * alloc_chipmem() returns long short aligned data. note also that
257 * each row of the bitmap is long word aligned and made of exactly n
258 * longwords. -ch */
259
260 /* Sigh, it seems for mapping to work we need the bitplane data to 1:
261 * be aligned on a page boundry. 2: be n pages large.
262 *
263 * why? becuase the user gets a page aligned address, if m_this is before
264 * your allocation, too bad. Also it seems that the mapping routines
265 * do not watch to closely to the allowable length. so if you go over
266 * n pages by less than another page, the user gets to write all over
267 * the entire page. Since you did not allocate up to a page boundry
268 * (or more) the user writes into someone elses memory. -ch */
269 total_size = amiga_round_page(plane_size * depth) + /* for length */
270 (temp_size) + (array_size) + sizeof(bmap_t) +
271 NBPG; /* for alignment */
272 bm = alloc_chipmem(total_size);
273 if (bm) {
274 if (flags & BMF_CLEAR) {
275 bzero(bm, total_size);
276 }
277 bm->bytes_per_row = bpr;
278 bm->rows = height;
279 bm->depth = depth;
280 bm->flags = flags;
281 bm->plane = (u_char **) & bm[1];
282 bm->blit_temp = ((u_char *) bm->plane) + array_size;
283 bm->plane[0] = (u_char *) amiga_round_page((u_long) (bm->blit_temp + temp_size));
284 if (flags & BMF_INTERLEAVED) {
285 bm->row_mod = bm->bytes_per_row * (depth - 1);
286 for (i = 1; i < depth; i++) {
287 bm->plane[i] = bm->plane[i - 1] + bpr;
288 }
289 } else {
290 bm->row_mod = 0;
291 for (i = 1; i < depth; i++) {
292 bm->plane[i] = bm->plane[i - 1] + plane_size;
293 }
294 }
295 bm->hardware_address = PREP_DMA_MEM(bm->plane[0]);
296 return (bm);
297 }
298 return (NULL);
299 }
300
301
302 void
303 free_bitmap(bm)
304 bmap_t *bm;
305 {
306 if (bm)
307 free_chipmem(bm);
308 }
309 /* load a new mode into the current display, if NULL shut display off. */
310 void
311 cc_load_mode(d)
312 dmode_t *d;
313 {
314 if (d) {
315 m_this_data->current_mode = d;
316 return;
317 }
318 /* turn off display */
319 m_this_data->current_mode = NULL;
320 wait_tof();
321 wait_tof();
322 custom.cop1lc = PREP_DMA_MEM(null_mode_copper_list);
323 }
324 /*
325 * CC Mode Stuff.
326 */
327
328 dmode_t *(*mode_init_funcs[]) (void) = {
329 #if defined (GRF_NTSC)
330 #if defined (GRF_A2024)
331 cc_init_ntsc_a2024,
332 cc_init_ntsc_hires_dlace,
333 #endif /* GRF_A2024 */
334 cc_init_ntsc_hires_lace,
335 cc_init_ntsc_hires,
336 #endif /* GRF_NTSC */
337 #if defined (GRF_PAL)
338 #if defined (GRF_A2024)
339 cc_init_pal_a2024,
340 cc_init_pal_hires_dlace,
341 #endif /* GRF_A2024 */
342 cc_init_pal_hires_lace,
343 cc_init_pal_hires,
344 #endif /* GRF_PAL */
345 NULL
346 };
347
348 int
349 cc_init_modes()
350 {
351 int i = 0;
352 int error = 0;
353 while (mode_init_funcs[i]) {
354 mode_init_funcs[i] ();
355 i++;
356 }
357 return (error);
358 }
359
360 monitor_t *
361 cc_get_monitor(d)
362 dmode_t *d;
363 {
364 return (DMDATA(d)->monitor);
365 }
366
367 view_t *
368 cc_get_current_view(d)
369 dmode_t *d;
370 {
371 return (DMDATA(d)->current_view);
372 }
373
374
375 view_t *
376 cc_alloc_view(mode, dim, depth)
377 dmode_t *mode;
378 dimen_t *dim;
379 u_char depth;
380 {
381 view_t *v = alloc_chipmem(sizeof(*v) + sizeof(vdata_t));
382 if (v) {
383 bmap_t *bm = cc_monitor->alloc_bitmap(dim->width, dim->height, depth, BMF_CLEAR);
384 if (bm) {
385 int i;
386 box_t box;
387
388 v->data = &v[1]; /* at the end of view */
389 VDATA(v)->colormap = DMDATA(mode)->alloc_colormap(depth);
390 if (VDATA(v)->colormap) {
391 INIT_BOX(&box, 0, 0, dim->width, dim->height);
392 cc_init_view(v, bm, mode, &box);
393 return (v);
394 }
395 cc_monitor->free_bitmap(bm);
396 }
397 free_chipmem(v);
398 }
399 return (NULL);
400 }
401
402 colormap_t *
403 cc_alloc_colormap(depth)
404 int depth;
405 {
406 u_long size = 1U << depth, i;
407 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm));
408
409 if (cm) {
410 cm->type = CM_COLOR;
411 cm->red_mask = 0x0F;
412 cm->green_mask = 0x0F;
413 cm->blue_mask = 0x0F;
414 cm->first = 0;
415 cm->size = size;
416 cm->entry = (u_long *) & cm[1]; /* table directly after. */
417 for (i = 0; i < min(size, 32); i++) {
418 cm->entry[i] = CM_WTOL(cc_default_colors[i]);
419 }
420 return (cm);
421 }
422 return (NULL);
423 }
424
425 int
426 cc_colormap_checkvals(vcm, cm, use)
427 colormap_t *vcm, *cm;
428 int use;
429 {
430 if (use) {
431 /* check to see if its the view's colormap, if so just do
432 * update. */
433 if (vcm != cm) {
434 if (cm->first >= vcm->size || (cm->first + cm->size) > (cm->first + vcm->size) ||
435 cm->type != vcm->type) {
436 return (0);
437 }
438 switch (vcm->type) {
439 case CM_COLOR:
440 if (cm->red_mask != vcm->red_mask ||
441 cm->green_mask != vcm->green_mask ||
442 cm->blue_mask != vcm->blue_mask) {
443 return (0);
444 }
445 break;
446 case CM_GREYSCALE:
447 if (cm->grey_mask != vcm->grey_mask) {
448 return (0);
449 }
450 break;
451 }
452 }
453 } else {
454 if (cm->first >= vcm->size || (cm->first + cm->size) > (cm->first + vcm->size)) {
455 return (0);
456 }
457 }
458 return (1);
459 }
460 /* does sanity check on values */
461 int
462 cc_get_colormap(v, cm)
463 view_t *v;
464 colormap_t *cm;
465 {
466 colormap_t *vcm = VDATA(v)->colormap;
467 int i;
468
469 if (!cc_colormap_checkvals(vcm, cm, 0)) {
470 return (EINVAL);
471 }
472 cm->type = vcm->type;
473
474 switch (vcm->type) {
475 case CM_COLOR:
476 cm->red_mask = vcm->red_mask;
477 cm->green_mask = vcm->green_mask;
478 cm->blue_mask = vcm->blue_mask;
479 break;
480 case CM_GREYSCALE:
481 cm->grey_mask = vcm->grey_mask;
482 break;
483 }
484
485 /* copy entries into colormap. */
486 for (i = cm->first; i < (cm->first + cm->size); i++) {
487 cm->entry[i] = vcm->entry[i];
488 }
489 return (0);
490 }
491
492 /* does sanity check on values */
493 int
494 cc_use_colormap(v, cm)
495 view_t *v;
496 colormap_t *cm;
497 {
498 colormap_t *vcm = VDATA(v)->colormap;
499 int s, i;
500
501 if (!cc_colormap_checkvals(vcm, cm, 1)) {
502 return (EINVAL);
503 }
504 /* check to see if its the view's colormap, if so just do update. */
505 if (vcm != cm) {
506 /* copy entries into colormap. */
507 for (i = cm->first; i < (cm->first + cm->size); i++) {
508 vcm->entry[i] = cm->entry[i];
509 }
510 }
511 s = spltty();
512
513 /* is view currently being displayed? */
514 if (VDATA(v)->flags & VF_DISPLAY) {
515 /* yes, update the copper lists */
516 cop_t *tmp, *cp;
517 int nframes = 1, j;
518
519 if (DMDATA(VDATA(v)->mode)->flags & DMF_INTERLACE) {
520 nframes = 2;
521 }
522 for (i = 0; i < nframes; i++) {
523 cp = DMDATA(VDATA(v)->mode)->frames[i];
524
525 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR07));
526 tmp -= 7;
527
528 for (j = 0; j < 16; j++) {
529 CMOVE(tmp, R_COLOR00 + (j << 1), CM_LTOW(vcm->entry[j]));
530 }
531 }
532 }
533 splx(s);
534 return (0);
535 }
536 #if defined (GRF_A2024)
537 colormap_t *
538 cc_a2024_alloc_colormap(depth)
539 int depth;
540 {
541 u_long size = 1U << depth, i;
542 colormap_t *cm = alloc_chipmem(sizeof(u_long) * size + sizeof(*cm));
543
544 if (cm) {
545 cm->type = CM_GREYSCALE;
546 cm->grey_mask = 0x03;
547 cm->first = 0;
548 cm->size = size;
549 cm->entry = (u_long *) & cm[1]; /* table directly after. */
550 for (i = 0; i < size; i++) {
551 cm->entry[i] = CM_WTOL(cc_a2024_default_colors[i]);
552 }
553 return (cm);
554 }
555 return (NULL);
556 }
557
558 int
559 cc_a2024_get_colormap(v, cm)
560 view_t *v;
561 colormap_t *cm;
562 {
563 /* there are no differences (yet) in the way the cm's are stored */
564 return (cc_get_colormap(v, cm));
565 }
566
567 int
568 cc_a2024_use_colormap(v, cm)
569 view_t *v;
570 colormap_t *cm;
571 {
572 colormap_t *vcm = VDATA(v)->colormap;
573 int s, i;
574
575 if (!cc_colormap_checkvals(vcm, cm, 1)) {
576 return (EINVAL);
577 }
578 /* check to see if its the view's colormap, if so just do update. */
579 if (vcm != cm) {
580 /* copy entries into colormap. */
581 for (i = cm->first; i < (cm->first + cm->size); i++) {
582 vcm->entry[i] = cm->entry[i];
583 }
584 }
585 s = spltty();
586
587 /* is view currently being displayed? */
588 if (VDATA(v)->flags & VF_DISPLAY) {
589 /* yes, update the copper lists */
590 cop_t *tmp, *cp;
591 int nframes = 2, nregs = cm->size == 4 ? 16 : 8, j;
592
593 if (DMDATA(VDATA(v)->mode)->flags & DMF_HEDLEY_EXP) {
594 nframes = 4;
595 }
596 for (i = 0; i < nframes; i++) {
597 cp = DMDATA(VDATA(v)->mode)->frames[i];
598
599 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR07));
600 tmp -= 7;
601
602 for (j = 0; j < nregs; j++) {
603 CMOVE(tmp, R_COLOR00 + (j << 1), A2024_CM_TO_CR(vcm, j));
604 }
605 }
606 }
607 splx(s);
608 return (0);
609 }
610 #endif /* GRF_A2024 */
611
612
613 /*
614 * CC View stuff.
615 */
616
617 void
618 cc_init_view(v, bm, mode, dbox)
619 view_t *v;
620 bmap_t *bm;
621 dmode_t *mode;
622 box_t *dbox;
623 {
624 vdata_t *vd = VDATA(v);
625 v->bitmap = bm;
626 vd->mode = mode;
627 bcopy(dbox, &v->display, sizeof(box_t));
628
629 v->display_view = DMDATA(vd->mode)->display_view;
630 v->use_colormap = DMDATA(vd->mode)->use_colormap;
631 v->get_colormap = DMDATA(vd->mode)->get_colormap;
632 v->free_view = cc_free_view;
633 v->get_display_mode = cc_get_display_mode;
634 v->remove_view = cc_remove_view;
635 }
636
637 void
638 cc_free_view(v)
639 view_t *v;
640 {
641 if (v) {
642 vdata_t *vd = VDATA(v);
643 dmode_t *md = vd->mode;
644 v->remove_view(v);
645 cc_monitor->free_bitmap(v->bitmap);
646 free_chipmem(v);
647 }
648 }
649
650 void
651 cc_remove_view(v)
652 view_t *v;
653 {
654 dmode_t *mode = VDATA(v)->mode;
655
656 if (MDATA(cc_monitor)->current_mode == mode) {
657 if (DMDATA(mode)->current_view == v) {
658 cc_load_mode(NULL);
659 }
660 }
661 if (DMDATA(mode)->current_view == v) {
662 DMDATA(mode)->current_view = NULL;
663 }
664 VDATA(v)->flags &= ~VF_DISPLAY;
665 }
666
667 dmode_t *
668 cc_get_display_mode(v)
669 view_t *v;
670 {
671 return (VDATA(v)->mode);
672 }
673
674 void
675 cc_mode_vbl_handler(d)
676 dmode_t *d;
677 {
678 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
679
680 if (vp < 12) {
681 custom.cop1lc = PREP_DMA_MEM(h_this_data->frames[F_LONG]);
682 custom.copjmp1 = 0;
683 }
684 }
685
686 void
687 cc_lace_mode_vbl_handler(d)
688 dmode_t *d;
689 {
690 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
691
692 if (vp < 12) {
693 if (custom.vposr & 0x8000) {
694 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LACE_LONG]);
695 } else {
696 custom.cop1lc = PREP_DMA_MEM(DMDATA(d)->frames[F_LACE_SHORT]);
697 }
698 custom.copjmp1 = 0;
699 }
700 }
701
702 /*
703 * Modes. (ick)
704 */
705
706 /*
707 * NTSC Modes
708 */
709
710 #if defined (GRF_NTSC)
711
712 dmode_t *
713 cc_init_ntsc_hires()
714 {
715 /* h_this function should only be called once. */
716 if (!h_this) {
717 u_short len = std_copper_list_len;
718 cop_t *cp;
719
720 h_this = &hires_mode;
721 h_this_data = &hires_mode_data;
722 bzero(h_this, sizeof(dmode_t));
723 bzero(h_this_data, sizeof(dmdata_t));
724
725 h_this->name = "ntsc: hires interlace";
726 h_this->nominal_size.width = 640;
727 h_this->nominal_size.height = 200;
728 h_this_data->max_size.width = 724;
729 h_this_data->max_size.height = 242;
730 h_this_data->min_size.width = 320;
731 h_this_data->min_size.height = 100;
732 h_this_data->min_depth = 1;
733 h_this_data->max_depth = 4;
734 h_this->data = h_this_data;
735
736 h_this->get_monitor = cc_get_monitor;
737 h_this->alloc_view = cc_alloc_view;
738 h_this->get_current_view = cc_get_current_view;
739
740 h_this_data->use_colormap = cc_use_colormap;
741 h_this_data->get_colormap = cc_get_colormap;
742 h_this_data->alloc_colormap = cc_alloc_colormap;
743 h_this_data->display_view = display_hires_view;
744 h_this_data->monitor = cc_monitor;
745
746 h_this_data->frames = hires_frames;
747 h_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL);
748 if (!h_this_data->frames[F_LONG]) {
749 panic("couldn't get chipmem for copper list");
750 }
751 h_this_data->frames[F_STORE_LONG] = &h_this_data->frames[F_LONG][len];
752
753 bcopy(std_copper_list, h_this_data->frames[F_STORE_LONG], std_copper_list_size);
754 bcopy(std_copper_list, h_this_data->frames[F_LONG], std_copper_list_size);
755
756 h_this_data->bplcon0 = 0x8200 | USE_CON3; /* hires, color
757 * composite enable,
758 * lace. */
759 h_this_data->std_start_x = STANDARD_VIEW_X;
760 h_this_data->std_start_y = STANDARD_VIEW_Y;
761 h_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler;
762 #if defined (GRF_ECS)
763 h_this_data->beamcon0 = STANDARD_NTSC_BEAMCON;
764 #endif
765
766 dadd_head(&MDATA(cc_monitor)->modes, &h_this->node);
767 }
768 return (h_this);
769 }
770
771 void
772 display_hires_view(v)
773 view_t *v;
774 {
775 if (h_this_data->current_view != v) {
776 vdata_t *vd = VDATA(v);
777 monitor_t *monitor = h_this_data->monitor;
778 cop_t *cp = h_this_data->frames[F_STORE_LONG], *tmp;
779 int depth = v->bitmap->depth, i;
780 int hstart, hstop, vstart, vstop, j;
781 int x, y, w = v->display.width, h = v->display.height;
782 u_short ddfstart, ddfwidth, con1;
783
784 /* round down to nearest even width */
785 /* w &= 0xfffe; */
786
787
788 /* calculate datafetch width. */
789
790 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
791
792 /* H_This will center the any overscanned display */
793 /* and allow user to modify. */
794 x = v->display.x + h_this_data->std_start_x - ((w - 640) >> 2);
795 y = v->display.y + h_this_data->std_start_y - ((h - 200) >> 1);
796
797 if (y & 1)
798 y--;
799
800 if (!(x & 1))
801 x--;
802
803 hstart = x;
804 hstop = x + (w >> 1);
805 vstart = y;
806 vstop = y + h;
807 ddfstart = (hstart - 9) >> 1;
808
809 /* check for hardware limits, AGA may allow more..? */
810 /* anyone got a 4000 I can borrow :^) -ch */
811 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
812 int d = 0;
813
814 /* XXX anyone know the equality properties of
815 * intermixed logial AND's */
816 /* XXX and arithmetic operators? */
817 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
818 d++;
819 }
820
821 ddfstart -= d;
822 hstart -= d << 1;
823 hstop -= d << 1;
824 }
825 /* correct the datafetch to proper limits. */
826 /* delay the actual display of the data until we need it. */
827 ddfstart &= 0xfffc;
828 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
829
830 if (h_this_data->current_view) {
831 VDATA(h_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
832 /* displayed. */
833 }
834 h_this_data->current_view = v;
835
836 cp = h_this_data->frames[F_STORE_LONG];
837 #if defined GRF_ECS
838 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
839 tmp->cp.inst.operand = h_this_data->beamcon0;
840 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
841 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
842 #endif /* ECS */
843 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
844 tmp->cp.inst.operand = h_this_data->bplcon0 | ((depth & 0x7) << 12);
845 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
846 tmp->cp.inst.operand = con1;
847 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
848 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
849 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
850 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
851 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
852 tmp->cp.inst.operand = ddfstart;
853 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
854 tmp->cp.inst.operand = ddfstart + ddfwidth;
855
856 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
857 for (i = 0, j = 0; i < depth; j += 2, i++) {
858 /* update the plane pointers */
859 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
860 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
861 }
862
863 /* set mods correctly. */
864 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
865 tmp[0].cp.inst.operand = v->bitmap->row_mod;
866 tmp[1].cp.inst.operand = v->bitmap->row_mod;
867
868 /* set next pointers correctly */
869 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
870 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(h_this_data->frames[F_STORE_LONG]));
871 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(h_this_data->frames[F_STORE_LONG]));
872
873 cp = h_this_data->frames[F_LONG];
874 h_this_data->frames[F_LONG] = h_this_data->frames[F_STORE_LONG];
875 h_this_data->frames[F_STORE_LONG] = cp;
876
877 vd->flags |= VF_DISPLAY;
878
879 cc_use_colormap(v, vd->colormap);
880 }
881 cc_load_mode(h_this);
882 }
883
884 dmode_t *
885 cc_init_ntsc_hires_lace()
886 {
887 /* hl_this function should only be called once. */
888 if (!hl_this) {
889 u_short len = std_copper_list_len;
890 cop_t *cp;
891
892 hl_this = &hires_lace_mode;
893 hl_this_data = &hires_lace_mode_data;
894 bzero(hl_this, sizeof(dmode_t));
895 bzero(hl_this_data, sizeof(dmdata_t));
896
897 hl_this->name = "ntsc: hires interlace";
898 hl_this->nominal_size.width = 640;
899 hl_this->nominal_size.height = 400;
900 hl_this_data->max_size.width = 724;
901 hl_this_data->max_size.height = 482;
902 hl_this_data->min_size.width = 320;
903 hl_this_data->min_size.height = 200;
904 hl_this_data->min_depth = 1;
905 hl_this_data->max_depth = 4;
906 hl_this->data = hl_this_data;
907
908 hl_this->get_monitor = cc_get_monitor;
909 hl_this->alloc_view = cc_alloc_view;
910 hl_this->get_current_view = cc_get_current_view;
911
912 hl_this_data->use_colormap = cc_use_colormap;
913 hl_this_data->get_colormap = cc_get_colormap;
914 hl_this_data->alloc_colormap = cc_alloc_colormap;
915 hl_this_data->display_view = display_hires_lace_view;
916 hl_this_data->monitor = cc_monitor;
917
918 hl_this_data->flags |= DMF_INTERLACE;
919
920 hl_this_data->frames = hires_lace_frames;
921 hl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL);
922 if (!hl_this_data->frames[F_LACE_LONG]) {
923 panic("couldn't get chipmem for copper list");
924 }
925 hl_this_data->frames[F_LACE_SHORT] = &hl_this_data->frames[F_LACE_LONG][len];
926 hl_this_data->frames[F_LACE_STORE_LONG] = &hl_this_data->frames[F_LACE_SHORT][len];
927 hl_this_data->frames[F_LACE_STORE_SHORT] = &hl_this_data->frames[F_LACE_STORE_LONG][len];
928
929 bcopy(std_copper_list, hl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size);
930 bcopy(std_copper_list, hl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size);
931 bcopy(std_copper_list, hl_this_data->frames[F_LACE_LONG], std_copper_list_size);
932 bcopy(std_copper_list, hl_this_data->frames[F_LACE_SHORT], std_copper_list_size);
933
934 hl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
935 * composite enable,
936 * lace. */
937 hl_this_data->std_start_x = STANDARD_VIEW_X;
938 hl_this_data->std_start_y = STANDARD_VIEW_Y;
939 hl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler;
940 #if defined (GRF_ECS)
941 hl_this_data->beamcon0 = STANDARD_NTSC_BEAMCON;
942 #endif
943
944 dadd_head(&MDATA(cc_monitor)->modes, &hl_this->node);
945 }
946 return (hl_this);
947 }
948
949 void
950 display_hires_lace_view(v)
951 view_t *v;
952 {
953 if (hl_this_data->current_view != v) {
954 vdata_t *vd = VDATA(v);
955 monitor_t *monitor = hl_this_data->monitor;
956 cop_t *cp = hl_this_data->frames[F_LACE_STORE_LONG], *tmp;
957 int depth = v->bitmap->depth, i;
958 int hstart, hstop, vstart, vstop, j;
959 int x, y, w = v->display.width, h = v->display.height;
960 u_short ddfstart, ddfwidth, con1;
961
962 /* round down to nearest even width */
963 /* w &= 0xfffe; */
964
965
966 /* calculate datafetch width. */
967
968 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
969
970 /* Hl_This will center the any overscanned display */
971 /* and allow user to modify. */
972 x = v->display.x + hl_this_data->std_start_x - ((w - 640) >> 2);
973 y = v->display.y + hl_this_data->std_start_y - ((h - 400) >> 2);
974
975 if (y & 1)
976 y--;
977
978 if (!(x & 1))
979 x--;
980
981 hstart = x;
982 hstop = x + (w >> 1);
983 vstart = y;
984 vstop = y + (h >> 1);
985 ddfstart = (hstart - 9) >> 1;
986
987 /* check for hardware limits, AGA may allow more..? */
988 /* anyone got a 4000 I can borrow :^) -ch */
989 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
990 int d = 0;
991
992 /* XXX anyone know the equality properties of
993 * intermixed logial AND's */
994 /* XXX and arithmetic operators? */
995 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
996 d++;
997 }
998
999 ddfstart -= d;
1000 hstart -= d << 1;
1001 hstop -= d << 1;
1002 }
1003 /* correct the datafetch to proper limits. */
1004 /* delay the actual display of the data until we need it. */
1005 ddfstart &= 0xfffc;
1006 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
1007
1008 if (hl_this_data->current_view) {
1009 VDATA(hl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
1010 /* displayed. */
1011 }
1012 hl_this_data->current_view = v;
1013
1014 cp = hl_this_data->frames[F_LACE_STORE_LONG];
1015 #if defined GRF_ECS
1016 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
1017 tmp->cp.inst.operand = hl_this_data->beamcon0;
1018 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
1019 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
1020 #endif /* ECS */
1021 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
1022 tmp->cp.inst.operand = hl_this_data->bplcon0 | ((depth & 0x7) << 12);
1023 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
1024 tmp->cp.inst.operand = con1;
1025 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
1026 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
1027 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
1028 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
1029 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
1030 tmp->cp.inst.operand = ddfstart;
1031 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
1032 tmp->cp.inst.operand = ddfstart + ddfwidth;
1033
1034 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1035 for (i = 0, j = 0; i < depth; j += 2, i++) {
1036 /* update the plane pointers */
1037 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
1038 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
1039 }
1040
1041 /* set mods correctly. */
1042 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
1043 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1044 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1045
1046 /* set next pointers correctly */
1047 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1048 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_SHORT]));
1049 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_SHORT]));
1050
1051
1052 bcopy(hl_this_data->frames[F_LACE_STORE_LONG], hl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size);
1053
1054 /* these are the only ones that are different from long frame. */
1055 cp = hl_this_data->frames[F_LACE_STORE_SHORT];
1056 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1057 for (i = 0, j = 0; i < depth; j += 2, i++) {
1058 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1059 /* update plane pointers. high and low. */
1060 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
1061 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
1062 }
1063
1064 /* set next pointers correctly */
1065 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1066 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_LONG]));
1067 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hl_this_data->frames[F_LACE_STORE_LONG]));
1068
1069
1070 cp = hl_this_data->frames[F_LACE_LONG];
1071 hl_this_data->frames[F_LACE_LONG] = hl_this_data->frames[F_LACE_STORE_LONG];
1072 hl_this_data->frames[F_LACE_STORE_LONG] = cp;
1073
1074 cp = hl_this_data->frames[F_LACE_SHORT];
1075 hl_this_data->frames[F_LACE_SHORT] = hl_this_data->frames[F_LACE_STORE_SHORT];
1076 hl_this_data->frames[F_LACE_STORE_SHORT] = cp;
1077
1078 vd->flags |= VF_DISPLAY;
1079
1080 cc_use_colormap(v, vd->colormap);
1081 }
1082 cc_load_mode(hl_this);
1083 }
1084 #if defined (GRF_A2024)
1085
1086 dmode_t *
1087 cc_init_ntsc_hires_dlace()
1088 {
1089 /* hdl_this function should only be called once. */
1090 if (!hdl_this) {
1091 u_short len = std_dlace_copper_list_len;
1092 cop_t *cp;
1093
1094 hdl_this = &hires_dlace_mode;
1095 hdl_this_data = &hires_dlace_mode_data;
1096 bzero(hdl_this, sizeof(dmode_t));
1097 bzero(hdl_this_data, sizeof(dmdata_t));
1098
1099 hdl_this->name = "ntsc: hires double interlace";
1100 hdl_this->nominal_size.width = 640;
1101 hdl_this->nominal_size.height = 800;
1102 hdl_this_data->max_size.width = 724;
1103 hdl_this_data->max_size.height = 800;
1104 hdl_this_data->min_size.width = 320;
1105 hdl_this_data->min_size.height = 400;
1106 hdl_this_data->min_depth = 1;
1107 hdl_this_data->max_depth = 2;
1108 hdl_this->data = hdl_this_data;
1109
1110 hdl_this->get_monitor = cc_get_monitor;
1111 hdl_this->alloc_view = cc_alloc_view;
1112 hdl_this->get_current_view = cc_get_current_view;
1113
1114 hdl_this_data->use_colormap = cc_a2024_use_colormap;
1115 hdl_this_data->get_colormap = cc_a2024_get_colormap;
1116 hdl_this_data->alloc_colormap = cc_a2024_alloc_colormap;
1117 hdl_this_data->display_view = display_hires_dlace_view;
1118 hdl_this_data->monitor = cc_monitor;
1119
1120 hdl_this_data->flags |= DMF_INTERLACE;
1121
1122 hdl_this_data->frames = hires_dlace_frames;
1123 hdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL);
1124 if (!hdl_this_data->frames[F_LACE_LONG]) {
1125 panic("couldn't get chipmem for copper list");
1126 }
1127 hdl_this_data->frames[F_LACE_SHORT] = &hdl_this_data->frames[F_LACE_LONG][len];
1128 hdl_this_data->frames[F_LACE_STORE_LONG] = &hdl_this_data->frames[F_LACE_SHORT][len];
1129 hdl_this_data->frames[F_LACE_STORE_SHORT] = &hdl_this_data->frames[F_LACE_STORE_LONG][len];
1130
1131 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size);
1132 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size);
1133 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list_size);
1134 bcopy(std_dlace_copper_list, hdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list_size);
1135
1136 hdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
1137 * composite enable,
1138 * dlace. */
1139 hdl_this_data->std_start_x = STANDARD_VIEW_X;
1140 hdl_this_data->std_start_y = STANDARD_VIEW_Y;
1141 hdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler;
1142 #if defined (GRF_ECS)
1143 hdl_this_data->beamcon0 = STANDARD_NTSC_BEAMCON;
1144 #endif
1145 dadd_head(&MDATA(cc_monitor)->modes, &hdl_this->node);
1146 }
1147 return (hdl_this);
1148 }
1149
1150 void
1151 display_hires_dlace_view(v)
1152 view_t *v;
1153 {
1154 if (hdl_this_data->current_view != v) {
1155 vdata_t *vd = VDATA(v);
1156 monitor_t *monitor = hdl_this_data->monitor;
1157 cop_t *cp = hdl_this_data->frames[F_LACE_STORE_LONG], *tmp;
1158 int depth = v->bitmap->depth, i;
1159 int hstart, hstop, vstart, vstop, j;
1160 int x, y, w = v->display.width, h = v->display.height;
1161 u_short ddfstart, ddfwidth, con1;
1162 u_short mod1l, mod2l;
1163
1164 /* round down to nearest even width */
1165 /* w &= 0xfffe; */
1166
1167 /* calculate datafetch width. */
1168
1169 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
1170
1171 /* Hdl_This will center the any overscanned display */
1172 /* and allow user to modify. */
1173 x = v->display.x + hdl_this_data->std_start_x - ((w - 640) >> 2);
1174 y = v->display.y + hdl_this_data->std_start_y - ((h - 800) >> 3);
1175
1176 if (y & 1)
1177 y--;
1178
1179 if (!(x & 1))
1180 x--;
1181
1182 hstart = x;
1183 hstop = x + (w >> 1);
1184 vstart = y;
1185 vstop = y + (h >> 2);
1186
1187 ddfstart = (hstart - 9) >> 1;
1188
1189 /* check for hardware limits, AGA may allow more..? */
1190 /* anyone got a 4000 I can borrow :^) -ch */
1191 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
1192 int d = 0;
1193
1194 /* XXX anyone know the equality properties of
1195 * intermixed logial AND's */
1196 /* XXX and arithmetic operators? */
1197 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
1198 d++;
1199 }
1200
1201 ddfstart -= d;
1202 hstart -= d << 1;
1203 hstop -= d << 1;
1204 }
1205 /* correct the datafetch to proper limits. */
1206 /* delay the actual display of the data until we need it. */
1207 ddfstart &= 0xfffc;
1208 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
1209
1210 if (hdl_this_data->current_view) {
1211 VDATA(hdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
1212 /* displayed. */
1213 }
1214 hdl_this_data->current_view = v;
1215
1216 cp = hdl_this_data->frames[F_LACE_STORE_LONG];
1217 #if defined GRF_ECS
1218 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
1219 tmp->cp.inst.operand = hdl_this_data->beamcon0;
1220 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
1221 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
1222 #endif /* ECS */
1223 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
1224 tmp->cp.inst.operand = hdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */
1225 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
1226 tmp->cp.inst.operand = con1;
1227 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
1228 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
1229 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
1230 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
1231 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
1232 tmp->cp.inst.operand = ddfstart;
1233 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
1234 tmp->cp.inst.operand = ddfstart + ddfwidth;
1235
1236 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1237 mod2l = mod1l << 1;
1238
1239 /* update plane pointers. */
1240 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1241 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0]));
1242 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0]));
1243 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l]));
1244 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l]));
1245 if (depth == 2) {
1246 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0]));
1247 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0]));
1248 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l]));
1249 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l]));
1250 }
1251 /* set modulos. */
1252 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
1253 tmp[0].cp.inst.operand = mod2l + mod1l;
1254 tmp[1].cp.inst.operand = mod2l + mod1l;
1255
1256
1257 /* set next coper list pointers */
1258 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1259 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_SHORT]));
1260 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_SHORT]));
1261
1262 bcopy(hdl_this_data->frames[F_LACE_STORE_LONG], hdl_this_data->frames[F_LACE_STORE_SHORT],
1263 std_dlace_copper_list_size);
1264
1265 /* these are the only ones that are different from long frame. */
1266 cp = hdl_this_data->frames[F_LACE_STORE_SHORT];
1267 /* update plane pointers. */
1268 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1269 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l]));
1270 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l]));
1271 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l]));
1272 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l]));
1273 if (depth == 2) {
1274 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l]));
1275 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l]));
1276 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l]));
1277 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l]));
1278 }
1279 /* set next copper list pointers */
1280 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1281 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_LONG]));
1282 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hdl_this_data->frames[F_LACE_STORE_LONG]));
1283
1284 cp = hdl_this_data->frames[F_LACE_LONG];
1285 hdl_this_data->frames[F_LACE_LONG] = hdl_this_data->frames[F_LACE_STORE_LONG];
1286 hdl_this_data->frames[F_LACE_STORE_LONG] = cp;
1287
1288 cp = hdl_this_data->frames[F_LACE_SHORT];
1289 hdl_this_data->frames[F_LACE_SHORT] = hdl_this_data->frames[F_LACE_STORE_SHORT];
1290 hdl_this_data->frames[F_LACE_STORE_SHORT] = cp;
1291
1292 vd->flags |= VF_DISPLAY;
1293 cc_a2024_use_colormap(v, vd->colormap);
1294 }
1295 cc_load_mode(hdl_this);
1296 }
1297
1298
1299 dmode_t *
1300 cc_init_ntsc_a2024()
1301 {
1302 /* a24_this function should only be called once. */
1303 if (!a24_this) {
1304 int i;
1305 u_short len = std_a2024_copper_list_len;
1306 cop_t *cp;
1307
1308 a24_this = &a2024_mode;
1309 a24_this_data = &a2024_mode_data;
1310 bzero(a24_this, sizeof(dmode_t));
1311 bzero(a24_this_data, sizeof(dmdata_t));
1312
1313 a24_this->name = "ntsc: A2024 15khz";
1314 a24_this->nominal_size.width = 1024;
1315 a24_this->nominal_size.height = 800;
1316 a24_this_data->max_size.width = 1024;
1317 a24_this_data->max_size.height = 800;
1318 a24_this_data->min_size.width = 1024;
1319 a24_this_data->min_size.height = 800;
1320 a24_this_data->min_depth = 1;
1321 a24_this_data->max_depth = 2;
1322 a24_this->data = a24_this_data;
1323
1324 a24_this->get_monitor = cc_get_monitor;
1325 a24_this->alloc_view = cc_alloc_view;
1326 a24_this->get_current_view = cc_get_current_view;
1327
1328 a24_this_data->use_colormap = cc_a2024_use_colormap;
1329 a24_this_data->get_colormap = cc_a2024_get_colormap;
1330 a24_this_data->display_view = display_a2024_view;
1331 a24_this_data->alloc_colormap = cc_a2024_alloc_colormap;
1332 a24_this_data->monitor = cc_monitor;
1333
1334 a24_this_data->flags |= DMF_HEDLEY_EXP;
1335
1336 a24_this_data->frames = a2024_frames;
1337 a24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_a2024_copper_list_size * F_QD_TOTAL);
1338 if (!a24_this_data->frames[F_QD_QUAD0]) {
1339 panic("couldn't get chipmem for copper list");
1340 }
1341 /* setup the hedley init bitplane. */
1342 hedley_init = alloc_chipmem(128);
1343 if (!hedley_init) {
1344 panic("couldn't get chipmem for hedley init bitplane");
1345 }
1346 for (i = 1; i < 128; i++)
1347 hedley_init[i] = 0xff;
1348 hedley_init[0] = 0x03;
1349
1350 /* copy image of standard copper list. */
1351 bcopy(std_a2024_copper_list, a24_this_data->frames[0], std_a2024_copper_list_size);
1352
1353 /* set the init plane pointer. */
1354 cp = find_copper_inst(a24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH));
1355 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init));
1356 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init));
1357
1358 for (i = 1; i < F_QD_TOTAL; i++) {
1359 a24_this_data->frames[i] = &a24_this_data->frames[i - 1][len];
1360 bcopy(a24_this_data->frames[0], a24_this_data->frames[i], std_a2024_copper_list_size);
1361 }
1362
1363 a24_this_data->bplcon0 = 0x8200; /* hires */
1364 a24_this_data->vbl_handler = (vbl_handler_func *) a2024_mode_vbl_handler;
1365
1366
1367 dadd_head(&MDATA(cc_monitor)->modes, &a24_this->node);
1368 }
1369 return (a24_this);
1370 }
1371
1372 void
1373 display_a2024_view(v)
1374 view_t *v;
1375 {
1376 if (a24_this_data->current_view != v) {
1377 vdata_t *vd = VDATA(v);
1378 monitor_t *monitor = a24_this_data->monitor;
1379 cop_t *cp, *tmp;
1380 u_char *inst_plane[2];
1381 u_char **plane = inst_plane;
1382 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1383 u_long half_plane = full_line * v->bitmap->rows / 2;
1384
1385 int line_mod = 0xbc; /* standard 2024 15khz mod. */
1386 int depth = v->bitmap->depth, i, j;
1387
1388 plane[0] = v->bitmap->plane[0];
1389 if (depth == 2) {
1390 plane[1] = v->bitmap->plane[1];
1391 }
1392 if (a24_this_data->current_view) {
1393 VDATA(a24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer
1394 * displayed. */
1395 }
1396 cp = a24_this_data->frames[F_QD_STORE_QUAD0];
1397 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F));
1398 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */
1399 tmp->cp.inst.operand = a24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */
1400
1401 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD1], std_a2024_copper_list_size);
1402 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD2], std_a2024_copper_list_size);
1403 bcopy(a24_this_data->frames[F_QD_STORE_QUAD0], a24_this_data->frames[F_QD_STORE_QUAD3], std_a2024_copper_list_size);
1404
1405 /*
1406 * Mark Id's
1407 */
1408 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 21));
1409 CBUMP(tmp);
1410 CMOVE(tmp, R_COLOR01, QUAD1_ID);
1411 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 21));
1412 CBUMP(tmp);
1413 CMOVE(tmp, R_COLOR01, QUAD2_ID);
1414 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 21));
1415 CBUMP(tmp);
1416 CMOVE(tmp, R_COLOR01, QUAD3_ID);
1417
1418 plane[0]--;
1419 plane[0]--;
1420 if (depth == 2) {
1421 plane[1]--;
1422 plane[1]--;
1423 }
1424 /*
1425 * Set bitplane pointers.
1426 */
1427 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2));
1428 CBUMP(tmp);
1429 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0])));
1430 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0])));
1431 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line])));
1432 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line])));
1433 if (depth == 2) {
1434 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0])));
1435 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0])));
1436 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line])));
1437 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line])));
1438 }
1439 #if defined (GRF_ECS)
1440 CMOVE(tmp, R_DIWHIGH, 0x2000);
1441 #endif
1442 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD1])));
1443 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD1])));
1444 CEND(tmp);
1445 CEND(tmp);
1446
1447 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2));
1448 CBUMP(tmp);
1449 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
1450 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
1451 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
1452 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
1453 if (depth == 2) {
1454 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
1455 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
1456 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
1457 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
1458 }
1459 #if defined (GRF_ECS)
1460 CMOVE(tmp, R_DIWHIGH, 0x2000);
1461 #endif
1462 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD2])));
1463 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD2])));
1464 CEND(tmp);
1465 CEND(tmp);
1466
1467 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2));
1468 CBUMP(tmp);
1469 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane])));
1470 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane])));
1471 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
1472 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
1473 if (depth == 2) {
1474 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane])));
1475 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane])));
1476 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
1477 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
1478 }
1479 #if defined (GRF_ECS)
1480 CMOVE(tmp, R_DIWHIGH, 0x2000);
1481 #endif
1482 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD3])));
1483 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD3])));
1484 CEND(tmp);
1485 CEND(tmp);
1486
1487 tmp = find_copper_inst(a24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2));
1488 CBUMP(tmp);
1489 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE])));
1490 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE])));
1491 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE])));
1492 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE])));
1493 if (depth == 2) {
1494 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE])));
1495 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE])));
1496 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE])));
1497 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE])));
1498 }
1499 #if defined (GRF_ECS)
1500 CMOVE(tmp, R_DIWHIGH, 0x2000);
1501 #endif
1502 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD0])));
1503 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(a24_this_data->frames[F_QD_STORE_QUAD0])));
1504 CEND(tmp);
1505 CEND(tmp);
1506
1507 /* swap new pointers in. */
1508 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0;
1509 i <= F_QD_STORE_QUAD3; i++, j++) {
1510 cp = a24_this_data->frames[j];
1511 a24_this_data->frames[j] = a24_this_data->frames[i];
1512 a24_this_data->frames[i] = cp;
1513 }
1514
1515 a24_this_data->current_view = v;
1516 vd->flags |= VF_DISPLAY;
1517
1518 cc_a2024_use_colormap(v, vd->colormap);
1519 }
1520 cc_load_mode(a24_this);
1521 }
1522
1523 void
1524 a2024_mode_vbl_handler(d)
1525 dmode_t *d;
1526 {
1527 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
1528
1529 if (vp < 12) {
1530 custom.cop1lc = PREP_DMA_MEM(a24_this_data->frames[a24_this_data->hedley_current]);
1531 custom.copjmp1 = 0;
1532 }
1533 a24_this_data->hedley_current++;
1534 a24_this_data->hedley_current &= 0x3; /* if 4 then 0. */
1535 }
1536 #endif /* GRF_A2024 */
1537 #endif /* GRF_NTSC */
1538
1539 /*
1540 * PAL modes.
1541 */
1542
1543 #if defined (GRF_PAL)
1544
1545 dmode_t *
1546 cc_init_pal_hires()
1547 {
1548 /* ph_this function should only be called once. */
1549 if (!ph_this) {
1550 u_short len = std_copper_list_len;
1551 cop_t *cp;
1552
1553 ph_this = &pal_hires_mode;
1554 ph_this_data = &pal_hires_mode_data;
1555 bzero(ph_this, sizeof(dmode_t));
1556 bzero(ph_this_data, sizeof(dmdata_t));
1557
1558 ph_this->name = "pal: pal_hires interlace";
1559 ph_this->nominal_size.width = 640;
1560 ph_this->nominal_size.height = 256;
1561 ph_this_data->max_size.width = 724;
1562 ph_this_data->max_size.height = 289;
1563 ph_this_data->min_size.width = 320;
1564 ph_this_data->min_size.height = 244;
1565 ph_this_data->min_depth = 1;
1566 ph_this_data->max_depth = 4;
1567 ph_this->data = ph_this_data;
1568
1569 ph_this->get_monitor = cc_get_monitor;
1570 ph_this->alloc_view = cc_alloc_view;
1571 ph_this->get_current_view = cc_get_current_view;
1572
1573 ph_this_data->use_colormap = cc_use_colormap;
1574 ph_this_data->get_colormap = cc_get_colormap;
1575 ph_this_data->alloc_colormap = cc_alloc_colormap;
1576 ph_this_data->display_view = display_pal_hires_view;
1577 ph_this_data->monitor = cc_monitor;
1578
1579 ph_this_data->frames = pal_hires_frames;
1580 ph_this_data->frames[F_LONG] = alloc_chipmem(std_copper_list_size * F_TOTAL);
1581 if (!ph_this_data->frames[F_LONG]) {
1582 panic("couldn't get chipmem for copper list");
1583 }
1584 ph_this_data->frames[F_STORE_LONG] = &ph_this_data->frames[F_LONG][len];
1585
1586 bcopy(std_copper_list, ph_this_data->frames[F_STORE_LONG], std_copper_list_size);
1587 bcopy(std_copper_list, ph_this_data->frames[F_LONG], std_copper_list_size);
1588
1589 ph_this_data->bplcon0 = 0x8200 | USE_CON3; /* pal_hires, color
1590 * composite enable,
1591 * lace. */
1592 ph_this_data->std_start_x = STANDARD_VIEW_X;
1593 ph_this_data->std_start_y = STANDARD_VIEW_Y;
1594 ph_this_data->vbl_handler = (vbl_handler_func *) cc_mode_vbl_handler;
1595 #if defined (GRF_ECS)
1596 ph_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
1597 #endif
1598
1599 dadd_head(&MDATA(cc_monitor)->modes, &ph_this->node);
1600 }
1601 return (ph_this);
1602 }
1603
1604 void
1605 display_pal_hires_view(v)
1606 view_t *v;
1607 {
1608 if (ph_this_data->current_view != v) {
1609 vdata_t *vd = VDATA(v);
1610 monitor_t *monitor = ph_this_data->monitor;
1611 cop_t *cp = ph_this_data->frames[F_STORE_LONG], *tmp;
1612 int depth = v->bitmap->depth, i;
1613 int hstart, hstop, vstart, vstop, j;
1614 int x, y, w = v->display.width, h = v->display.height;
1615 u_short ddfstart, ddfwidth, con1;
1616
1617 /* round down to nearest even width */
1618 /* w &= 0xfffe; */
1619
1620 /* calculate datafetch width. */
1621 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
1622
1623 /* Ph_This will center the any overscanned display */
1624 /* and allow user to modify. */
1625 x = v->display.x + ph_this_data->std_start_x - ((w - 640) >> 2);
1626 y = v->display.y + ph_this_data->std_start_y - ((h - 256) >> 1);
1627
1628 if (y & 1)
1629 y--;
1630
1631 if (!(x & 1))
1632 x--;
1633
1634 hstart = x;
1635 hstop = x + (w >> 1);
1636 vstart = y;
1637 vstop = y + h;
1638 ddfstart = (hstart - 9) >> 1;
1639 /* check for hardware limits, AGA may allow more..? */
1640 /* anyone got a 4000 I can borrow :^) -ch */
1641 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
1642 int d = 0;
1643
1644 /* XXX anyone know the equality properties of
1645 * intermixed logial AND's */
1646 /* XXX and arithmetic operators? */
1647 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
1648 d++;
1649 }
1650
1651 ddfstart -= d;
1652 hstart -= d << 1;
1653 hstop -= d << 1;
1654 }
1655 /* correct the datafetch to proper limits. */
1656 /* delay the actual display of the data until we need it. */
1657 ddfstart &= 0xfffc;
1658 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
1659
1660 if (ph_this_data->current_view) {
1661 VDATA(ph_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
1662 /* displayed. */
1663 }
1664 ph_this_data->current_view = v;
1665
1666 cp = ph_this_data->frames[F_STORE_LONG];
1667 #if defined GRF_ECS
1668 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
1669 tmp->cp.inst.operand = ph_this_data->beamcon0;
1670 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
1671 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
1672 #endif /* ECS */
1673 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
1674 tmp->cp.inst.operand = ph_this_data->bplcon0 | ((depth & 0x7) << 12);
1675 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
1676 tmp->cp.inst.operand = con1;
1677 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
1678 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
1679 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
1680 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
1681 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
1682 tmp->cp.inst.operand = ddfstart;
1683 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
1684 tmp->cp.inst.operand = ddfstart + ddfwidth;
1685
1686 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1687 for (i = 0, j = 0; i < depth; j += 2, i++) {
1688 /* update the plane pointers */
1689 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
1690 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
1691 }
1692
1693 /* set mods correctly. */
1694 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
1695 tmp[0].cp.inst.operand = v->bitmap->row_mod;
1696 tmp[1].cp.inst.operand = v->bitmap->row_mod;
1697
1698 /* set next pointers correctly */
1699 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1700 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG]));
1701 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(ph_this_data->frames[F_STORE_LONG]));
1702
1703 cp = ph_this_data->frames[F_LONG];
1704 ph_this_data->frames[F_LONG] = ph_this_data->frames[F_STORE_LONG];
1705 ph_this_data->frames[F_STORE_LONG] = cp;
1706
1707 vd->flags |= VF_DISPLAY;
1708 cc_use_colormap(v, vd->colormap);
1709 }
1710 cc_load_mode(ph_this);
1711 }
1712
1713 dmode_t *
1714 cc_init_pal_hires_lace()
1715 {
1716 /* phl_this function should only be called once. */
1717 if (!phl_this) {
1718 u_short len = std_copper_list_len;
1719 cop_t *cp;
1720
1721 phl_this = &pal_hires_lace_mode;
1722 phl_this_data = &pal_hires_lace_mode_data;
1723 bzero(phl_this, sizeof(dmode_t));
1724 bzero(phl_this_data, sizeof(dmdata_t));
1725
1726 phl_this->name = "pal: hires interlace";
1727 phl_this->nominal_size.width = 640;
1728 phl_this->nominal_size.height = 512;
1729 phl_this_data->max_size.width = 724;
1730 phl_this_data->max_size.height = 578;
1731 phl_this_data->min_size.width = 320;
1732 phl_this_data->min_size.height = 484;
1733 phl_this_data->min_depth = 1;
1734 phl_this_data->max_depth = 4;
1735 phl_this->data = phl_this_data;
1736
1737 phl_this->get_monitor = cc_get_monitor;
1738 phl_this->alloc_view = cc_alloc_view;
1739 phl_this->get_current_view = cc_get_current_view;
1740
1741 phl_this_data->use_colormap = cc_use_colormap;
1742 phl_this_data->get_colormap = cc_get_colormap;
1743 phl_this_data->alloc_colormap = cc_alloc_colormap;
1744 phl_this_data->display_view = display_pal_hires_lace_view;
1745 phl_this_data->monitor = cc_monitor;
1746
1747 phl_this_data->flags |= DMF_INTERLACE;
1748
1749 phl_this_data->frames = pal_hires_lace_frames;
1750 phl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_copper_list_size * F_LACE_TOTAL);
1751 if (!phl_this_data->frames[F_LACE_LONG]) {
1752 panic("couldn't get chipmem for copper list");
1753 }
1754 phl_this_data->frames[F_LACE_SHORT] = &phl_this_data->frames[F_LACE_LONG][len];
1755 phl_this_data->frames[F_LACE_STORE_LONG] = &phl_this_data->frames[F_LACE_SHORT][len];
1756 phl_this_data->frames[F_LACE_STORE_SHORT] = &phl_this_data->frames[F_LACE_STORE_LONG][len];
1757
1758 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_LONG], std_copper_list_size);
1759 bcopy(std_copper_list, phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size);
1760 bcopy(std_copper_list, phl_this_data->frames[F_LACE_LONG], std_copper_list_size);
1761 bcopy(std_copper_list, phl_this_data->frames[F_LACE_SHORT], std_copper_list_size);
1762
1763 phl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
1764 * composite enable,
1765 * lace. */
1766 phl_this_data->std_start_x = STANDARD_VIEW_X;
1767 phl_this_data->std_start_y = STANDARD_VIEW_Y;
1768 phl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler;
1769 #if defined (GRF_ECS)
1770 phl_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
1771 #endif
1772
1773 dadd_head(&MDATA(cc_monitor)->modes, &phl_this->node);
1774 }
1775 return (phl_this);
1776 }
1777
1778 void
1779 display_pal_hires_lace_view(v)
1780 view_t *v;
1781 {
1782 if (phl_this_data->current_view != v) {
1783 vdata_t *vd = VDATA(v);
1784 monitor_t *monitor = phl_this_data->monitor;
1785 cop_t *cp = phl_this_data->frames[F_LACE_STORE_LONG], *tmp;
1786 int depth = v->bitmap->depth, i;
1787 int hstart, hstop, vstart, vstop, j;
1788 int x, y, w = v->display.width, h = v->display.height;
1789 u_short ddfstart, ddfwidth, con1;
1790
1791 /* round down to nearest even width */
1792 /* w &= 0xfffe; */
1793
1794 /* calculate datafetch width. */
1795 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
1796
1797 /* Phl_This will center the any overscanned display */
1798 /* and allow user to modify. */
1799 x = v->display.x + phl_this_data->std_start_x - ((w - 640) >> 2);
1800 y = v->display.y + phl_this_data->std_start_y - ((h - 512) >> 2);
1801
1802 if (y & 1)
1803 y--;
1804
1805 if (!(x & 1))
1806 x--;
1807
1808 hstart = x;
1809 hstop = x + (w >> 1);
1810 vstart = y;
1811 vstop = y + (h >> 1);
1812 ddfstart = (hstart - 9) >> 1;
1813
1814 /* check for hardware limits, AGA may allow more..? */
1815 /* anyone got a 4000 I can borrow :^) -ch */
1816 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
1817 int d = 0;
1818
1819 /* XXX anyone know the equality properties of
1820 * intermixed logial AND's */
1821 /* XXX and arithmetic operators? */
1822 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
1823 d++;
1824 }
1825
1826 ddfstart -= d;
1827 hstart -= d << 1;
1828 hstop -= d << 1;
1829 }
1830 /* correct the datafetch to proper limits. */
1831 /* delay the actual display of the data until we need it. */
1832 ddfstart &= 0xfffc;
1833 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
1834
1835 if (phl_this_data->current_view) {
1836 VDATA(phl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
1837 /* displayed. */
1838 }
1839 phl_this_data->current_view = v;
1840
1841 cp = phl_this_data->frames[F_LACE_STORE_LONG];
1842 #if defined GRF_ECS
1843 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
1844 tmp->cp.inst.operand = phl_this_data->beamcon0;
1845 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
1846 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
1847 #endif /* ECS */
1848 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
1849 tmp->cp.inst.operand = phl_this_data->bplcon0 | ((depth & 0x7) << 12);
1850 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
1851 tmp->cp.inst.operand = con1;
1852 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
1853 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
1854 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
1855 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
1856 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
1857 tmp->cp.inst.operand = ddfstart;
1858 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
1859 tmp->cp.inst.operand = ddfstart + ddfwidth;
1860
1861 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1862 for (i = 0, j = 0; i < depth; j += 2, i++) {
1863 /* update the plane pointers */
1864 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
1865 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(v->bitmap->plane[i]));
1866 }
1867
1868 /* set mods correctly. */
1869 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
1870 tmp[0].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1871 tmp[1].cp.inst.operand = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1872
1873 /* set next pointers correctly */
1874 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1875 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT]));
1876 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_SHORT]));
1877
1878
1879 bcopy(phl_this_data->frames[F_LACE_STORE_LONG], phl_this_data->frames[F_LACE_STORE_SHORT], std_copper_list_size);
1880
1881 /* these are the only ones that are different from long frame. */
1882 cp = phl_this_data->frames[F_LACE_STORE_SHORT];
1883 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
1884 for (i = 0, j = 0; i < depth; j += 2, i++) {
1885 u_short mod = v->bitmap->bytes_per_row + v->bitmap->row_mod;
1886 /* update plane pointers. high and low. */
1887 tmp[j].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
1888 tmp[j + 1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[i][mod]));
1889 }
1890
1891 /* set next pointers correctly */
1892 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
1893 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG]));
1894 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phl_this_data->frames[F_LACE_STORE_LONG]));
1895
1896
1897 cp = phl_this_data->frames[F_LACE_LONG];
1898 phl_this_data->frames[F_LACE_LONG] = phl_this_data->frames[F_LACE_STORE_LONG];
1899 phl_this_data->frames[F_LACE_STORE_LONG] = cp;
1900
1901 cp = phl_this_data->frames[F_LACE_SHORT];
1902 phl_this_data->frames[F_LACE_SHORT] = phl_this_data->frames[F_LACE_STORE_SHORT];
1903 phl_this_data->frames[F_LACE_STORE_SHORT] = cp;
1904
1905 vd->flags |= VF_DISPLAY;
1906 cc_use_colormap(v, vd->colormap);
1907 }
1908 cc_load_mode(phl_this);
1909 }
1910 #if defined (GRF_A2024)
1911
1912 dmode_t *
1913 cc_init_pal_hires_dlace()
1914 {
1915 /* phdl_this function should only be called once. */
1916 if (!phdl_this) {
1917 u_short len = std_dlace_copper_list_len;
1918 cop_t *cp;
1919
1920 phdl_this = &pal_hires_dlace_mode;
1921 phdl_this_data = &pal_hires_dlace_mode_data;
1922 bzero(phdl_this, sizeof(dmode_t));
1923 bzero(phdl_this_data, sizeof(dmdata_t));
1924
1925 phdl_this->name = "pal: hires double interlace";
1926 phdl_this->nominal_size.width = 640;
1927 phdl_this->nominal_size.height = 1024;
1928 phdl_this_data->max_size.width = 724;
1929 phdl_this_data->max_size.height = 1024;
1930 phdl_this_data->min_size.width = 320;
1931 phdl_this_data->min_size.height = 512;
1932 phdl_this_data->min_depth = 1;
1933 phdl_this_data->max_depth = 2;
1934 phdl_this->data = phdl_this_data;
1935
1936 phdl_this->get_monitor = cc_get_monitor;
1937 phdl_this->alloc_view = cc_alloc_view;
1938 phdl_this->get_current_view = cc_get_current_view;
1939
1940 phdl_this_data->use_colormap = cc_a2024_use_colormap;
1941 phdl_this_data->get_colormap = cc_a2024_get_colormap;
1942 phdl_this_data->alloc_colormap = cc_a2024_alloc_colormap;
1943 phdl_this_data->display_view = display_pal_hires_dlace_view;
1944 phdl_this_data->monitor = cc_monitor;
1945
1946 phdl_this_data->flags |= DMF_INTERLACE;
1947
1948 phdl_this_data->frames = pal_hires_dlace_frames;
1949 phdl_this_data->frames[F_LACE_LONG] = alloc_chipmem(std_dlace_copper_list_size * F_LACE_TOTAL);
1950 if (!phdl_this_data->frames[F_LACE_LONG]) {
1951 panic("couldn't get chipmem for copper list");
1952 }
1953 phdl_this_data->frames[F_LACE_SHORT] = &phdl_this_data->frames[F_LACE_LONG][len];
1954 phdl_this_data->frames[F_LACE_STORE_LONG] = &phdl_this_data->frames[F_LACE_SHORT][len];
1955 phdl_this_data->frames[F_LACE_STORE_SHORT] = &phdl_this_data->frames[F_LACE_STORE_LONG][len];
1956
1957 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_LONG], std_dlace_copper_list_size);
1958 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size);
1959 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_LONG], std_dlace_copper_list_size);
1960 bcopy(std_dlace_copper_list, phdl_this_data->frames[F_LACE_SHORT], std_dlace_copper_list_size);
1961
1962 phdl_this_data->bplcon0 = 0x8204 | USE_CON3; /* hires, color
1963 * composite enable,
1964 * dlace. */
1965 phdl_this_data->std_start_x = STANDARD_VIEW_X;
1966 phdl_this_data->std_start_y = STANDARD_VIEW_Y;
1967 phdl_this_data->vbl_handler = (vbl_handler_func *) cc_lace_mode_vbl_handler;
1968 #if defined (GRF_ECS)
1969 phdl_this_data->beamcon0 = STANDARD_PAL_BEAMCON;
1970 #endif
1971
1972 dadd_head(&MDATA(cc_monitor)->modes, &phdl_this->node);
1973 }
1974 return (phdl_this);
1975 }
1976
1977 void
1978 display_pal_hires_dlace_view(v)
1979 view_t *v;
1980 {
1981 if (phdl_this_data->current_view != v) {
1982 vdata_t *vd = VDATA(v);
1983 monitor_t *monitor = phdl_this_data->monitor;
1984 cop_t *cp = phdl_this_data->frames[F_LACE_STORE_LONG], *tmp;
1985 int depth = v->bitmap->depth, i;
1986 int hstart, hstop, vstart, vstop, j;
1987 int x, y, w = v->display.width, h = v->display.height;
1988 u_short ddfstart, ddfwidth, con1;
1989 u_short mod1l, mod2l;
1990
1991 /* round down to nearest even width */
1992 /* w &= 0xfffe; */
1993
1994 /* calculate datafetch width. */
1995 ddfwidth = ((v->bitmap->bytes_per_row >> 1) - 2) << 2;
1996
1997 /* Phdl_This will center the any overscanned display */
1998 /* and allow user to modify. */
1999 x = v->display.x + phdl_this_data->std_start_x - ((w - 640) >> 2);
2000 y = v->display.y + phdl_this_data->std_start_y - ((h - 1024) >> 3);
2001
2002 if (y & 1)
2003 y--;
2004
2005 if (!(x & 1))
2006 x--;
2007
2008 hstart = x;
2009 hstop = x + (w >> 1);
2010 vstart = y;
2011 vstop = y + (h >> 2);
2012 ddfstart = (hstart - 9) >> 1;
2013
2014 /* check for hardware limits, AGA may allow more..? */
2015 /* anyone got a 4000 I can borrow :^) -ch */
2016 if ((ddfstart & 0xfffc) + ddfwidth > 0xd8) {
2017 int d = 0;
2018
2019 /* XXX anyone know the equality properties of
2020 * intermixed logial AND's */
2021 /* XXX and arithmetic operators? */
2022 while (((ddfstart & 0xfffc) + ddfwidth - d) > 0xd8) {
2023 d++;
2024 }
2025
2026 ddfstart -= d;
2027 hstart -= d << 1;
2028 hstop -= d << 1;
2029 }
2030 /* correct the datafetch to proper limits. */
2031 /* delay the actual display of the data until we need it. */
2032 ddfstart &= 0xfffc;
2033 con1 = ((hstart - 9) - (ddfstart << 1)) | (((hstart - 9) - (ddfstart << 1)) << 4);
2034
2035 if (phdl_this_data->current_view) {
2036 VDATA(phdl_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer */
2037 /* displayed. */
2038 }
2039 phdl_this_data->current_view = v;
2040
2041 cp = phdl_this_data->frames[F_LACE_STORE_LONG];
2042 #if defined GRF_ECS
2043 tmp = find_copper_inst(cp, CI_MOVE(R_BEAMCON0));
2044 tmp->cp.inst.operand = phdl_this_data->beamcon0;
2045 tmp = find_copper_inst(cp, CI_MOVE(R_DIWHIGH));
2046 tmp->cp.inst.operand = CALC_DIWHIGH(hstart, vstart, hstop, vstop);
2047 #endif /* ECS */
2048 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON0));
2049 tmp->cp.inst.operand = phdl_this_data->bplcon0 | ((depth & 0x7) << 13); /* times two. */
2050 tmp = find_copper_inst(cp, CI_MOVE(R_BPLCON1));
2051 tmp->cp.inst.operand = con1;
2052 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTART));
2053 tmp->cp.inst.operand = ((vstart & 0xff) << 8) | (hstart & 0xff);
2054 tmp = find_copper_inst(cp, CI_MOVE(R_DIWSTOP));
2055 tmp->cp.inst.operand = ((vstop & 0xff) << 8) | (hstop & 0xff);
2056 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTART));
2057 tmp->cp.inst.operand = ddfstart;
2058 tmp = find_copper_inst(cp, CI_MOVE(R_DDFSTOP));
2059 tmp->cp.inst.operand = ddfstart + ddfwidth;
2060
2061 mod1l = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2062 mod2l = mod1l << 1;
2063
2064 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2065 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* update plane
2066 * pointers. */
2067 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][0])); /* high and low. */
2068 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* update plane
2069 * pointers. */
2070 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod1l])); /* high and low. */
2071 if (depth == 2) {
2072 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* update plane
2073 * pointers. */
2074 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][0])); /* high and low. */
2075 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* update plane
2076 * pointers. */
2077 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod1l])); /* high and low. */
2078 }
2079 /* set mods correctly. */
2080 tmp = find_copper_inst(cp, CI_MOVE(R_BPL1MOD));
2081 tmp[0].cp.inst.operand = mod2l + mod1l;
2082 tmp[1].cp.inst.operand = mod2l + mod1l;
2083
2084 /* set next pointers correctly */
2085 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2086 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT]));
2087 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_SHORT]));
2088
2089 bcopy(phdl_this_data->frames[F_LACE_STORE_LONG], phdl_this_data->frames[F_LACE_STORE_SHORT], std_dlace_copper_list_size);
2090
2091 /* these are the only ones that are different from long frame. */
2092 cp = phdl_this_data->frames[F_LACE_STORE_SHORT];
2093 tmp = find_copper_inst(cp, CI_MOVE(R_BPL0PTH));
2094 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* update plane
2095 * pointers. */
2096 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l])); /* high and low. */
2097 tmp[2].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* update plane
2098 * pointers. */
2099 tmp[3].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[0][mod2l + mod1l])); /* high and low. */
2100 if (depth == 2) {
2101 tmp[4].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* update plane
2102 * pointers. */
2103 tmp[5].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l])); /* high and low. */
2104 tmp[6].cp.inst.operand = HIADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* update plane
2105 * pointers. */
2106 tmp[7].cp.inst.operand = LOADDR(PREP_DMA_MEM(&v->bitmap->plane[1][mod2l + mod1l])); /* high and low. */
2107 }
2108 /* set next pointers correctly */
2109 tmp = find_copper_inst(cp, CI_MOVE(R_COP1LCH));
2110 tmp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG]));
2111 tmp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(phdl_this_data->frames[F_LACE_STORE_LONG]));
2112
2113 cp = phdl_this_data->frames[F_LACE_LONG];
2114 phdl_this_data->frames[F_LACE_LONG] = phdl_this_data->frames[F_LACE_STORE_LONG];
2115 phdl_this_data->frames[F_LACE_STORE_LONG] = cp;
2116
2117 cp = phdl_this_data->frames[F_LACE_SHORT];
2118 phdl_this_data->frames[F_LACE_SHORT] = phdl_this_data->frames[F_LACE_STORE_SHORT];
2119 phdl_this_data->frames[F_LACE_STORE_SHORT] = cp;
2120
2121 vd->flags |= VF_DISPLAY;
2122
2123 cc_a2024_use_colormap(v, vd->colormap);
2124 }
2125 cc_load_mode(phdl_this);
2126 }
2127
2128 dmode_t *
2129 cc_init_pal_a2024()
2130 {
2131 /* p24_this function should only be called once. */
2132 if (!p24_this) {
2133 int i;
2134 u_short len = std_pal_a2024_copper_list_len;
2135 cop_t *cp;
2136
2137 p24_this = &pal_a2024_mode;
2138 p24_this_data = &pal_a2024_mode_data;
2139 bzero(p24_this, sizeof(dmode_t));
2140 bzero(p24_this_data, sizeof(dmdata_t));
2141
2142 p24_this->name = "pal: A2024 15khz";
2143 p24_this->nominal_size.width = 1024;
2144 p24_this->nominal_size.height = 1024;
2145 p24_this_data->max_size.width = 1024;
2146 p24_this_data->max_size.height = 1024;
2147 p24_this_data->min_size.width = 1024;
2148 p24_this_data->min_size.height = 1024;
2149 p24_this_data->min_depth = 1;
2150 p24_this_data->max_depth = 2;
2151 p24_this->data = p24_this_data;
2152
2153 p24_this->get_monitor = cc_get_monitor;
2154 p24_this->alloc_view = cc_alloc_view;
2155 p24_this->get_current_view = cc_get_current_view;
2156
2157 p24_this_data->use_colormap = cc_a2024_use_colormap;
2158 p24_this_data->get_colormap = cc_a2024_get_colormap;
2159 p24_this_data->display_view = display_pal_a2024_view;
2160 p24_this_data->alloc_colormap = cc_a2024_alloc_colormap;
2161 p24_this_data->monitor = cc_monitor;
2162
2163 p24_this_data->flags |= DMF_HEDLEY_EXP;
2164
2165 p24_this_data->frames = pal_a2024_frames;
2166 p24_this_data->frames[F_QD_QUAD0] = alloc_chipmem(std_pal_a2024_copper_list_size * F_QD_TOTAL);
2167 if (!p24_this_data->frames[F_QD_QUAD0]) {
2168 panic("couldn't get chipmem for copper list");
2169 }
2170 /* setup the hedley init bitplane. */
2171 hedley_init = alloc_chipmem(128);
2172 if (!hedley_init) {
2173 panic("couldn't get chipmem for hedley init bitplane");
2174 }
2175 for (i = 1; i < 128; i++)
2176 hedley_init[i] = 0xff;
2177 hedley_init[0] = 0x03;
2178
2179 /* copy image of standard copper list. */
2180 bcopy(std_pal_a2024_copper_list, p24_this_data->frames[0], std_pal_a2024_copper_list_size);
2181
2182 /* set the init plane pointer. */
2183 cp = find_copper_inst(p24_this_data->frames[F_QD_QUAD0], CI_MOVE(R_BPL0PTH));
2184 cp[0].cp.inst.operand = HIADDR(PREP_DMA_MEM(hedley_init));
2185 cp[1].cp.inst.operand = LOADDR(PREP_DMA_MEM(hedley_init));
2186
2187 for (i = 1; i < F_QD_TOTAL; i++) {
2188 p24_this_data->frames[i] = &p24_this_data->frames[i - 1][len];
2189 bcopy(p24_this_data->frames[0], p24_this_data->frames[i], std_pal_a2024_copper_list_size);
2190 }
2191
2192 p24_this_data->bplcon0 = 0x8200; /* hires */
2193 p24_this_data->vbl_handler = (vbl_handler_func *) pal_a2024_mode_vbl_handler;
2194
2195
2196 dadd_head(&MDATA(cc_monitor)->modes, &p24_this->node);
2197 }
2198 return (p24_this);
2199 }
2200
2201 void
2202 display_pal_a2024_view(v)
2203 view_t *v;
2204 {
2205 if (p24_this_data->current_view != v) {
2206 vdata_t *vd = VDATA(v);
2207 monitor_t *monitor = p24_this_data->monitor;
2208 cop_t *cp, *tmp;
2209 u_char *inst_plane[2];
2210 u_char **plane = inst_plane;
2211 u_long full_line = v->bitmap->bytes_per_row + v->bitmap->row_mod;
2212 u_long half_plane = full_line * v->bitmap->rows / 2;
2213
2214 int line_mod = 0xbc; /* standard 2024 15khz mod. */
2215 int depth = v->bitmap->depth, i, j;
2216
2217 plane[0] = v->bitmap->plane[0];
2218 if (depth == 2) {
2219 plane[1] = v->bitmap->plane[1];
2220 }
2221 if (p24_this_data->current_view) {
2222 VDATA(p24_this_data->current_view)->flags &= ~VF_DISPLAY; /* mark as no longer
2223 * displayed. */
2224 }
2225 cp = p24_this_data->frames[F_QD_STORE_QUAD0];
2226 tmp = find_copper_inst(cp, CI_MOVE(R_COLOR1F));
2227 tmp = find_copper_inst(tmp, CI_MOVE(R_BPLCON0)); /* grab third one. */
2228 tmp->cp.inst.operand = p24_this_data->bplcon0 | ((depth & 0x7) << 13); /* times 2 */
2229
2230 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD1], std_pal_a2024_copper_list_size);
2231 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD2], std_pal_a2024_copper_list_size);
2232 bcopy(p24_this_data->frames[F_QD_STORE_QUAD0], p24_this_data->frames[F_QD_STORE_QUAD3], std_pal_a2024_copper_list_size);
2233
2234 /*
2235 * Mark Id's
2236 */
2237 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_WAIT(126, 29));
2238 CBUMP(tmp);
2239 CMOVE(tmp, R_COLOR01, QUAD1_ID);
2240 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_WAIT(126, 29));
2241 CBUMP(tmp);
2242 CMOVE(tmp, R_COLOR01, QUAD2_ID);
2243 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_WAIT(126, 29));
2244 CBUMP(tmp);
2245 CMOVE(tmp, R_COLOR01, QUAD3_ID);
2246
2247 plane[0]--;
2248 plane[0]--;
2249 if (depth == 2) {
2250 plane[1]--;
2251 plane[1]--;
2252 }
2253 /*
2254 * Set bitplane pointers.
2255 */
2256 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD0], CI_MOVE(R_BPLMOD2));
2257 CBUMP(tmp);
2258 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][0])));
2259 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][0])));
2260 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line])));
2261 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line])));
2262 if (depth == 2) {
2263 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][0])));
2264 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][0])));
2265 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line])));
2266 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line])));
2267 }
2268 #if defined (GRF_ECS)
2269 CMOVE(tmp, R_DIWHIGH, 0x2100);
2270 #endif
2271 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1])));
2272 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD1])));
2273 CEND(tmp);
2274 CEND(tmp);
2275
2276 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD1], CI_MOVE(R_BPLMOD2));
2277 CBUMP(tmp);
2278 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
2279 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][HALF_2024_LINE])));
2280 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
2281 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][full_line + HALF_2024_LINE])));
2282 if (depth == 2) {
2283 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
2284 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][HALF_2024_LINE])));
2285 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
2286 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][full_line + HALF_2024_LINE])));
2287 }
2288 #if defined (GRF_ECS)
2289 CMOVE(tmp, R_DIWHIGH, 0x2100);
2290 #endif
2291 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2])));
2292 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD2])));
2293 CEND(tmp);
2294 CEND(tmp);
2295
2296 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD2], CI_MOVE(R_BPLMOD2));
2297 CBUMP(tmp);
2298 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane])));
2299 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane])));
2300 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
2301 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line])));
2302 if (depth == 2) {
2303 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane])));
2304 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane])));
2305 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
2306 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line])));
2307 }
2308 #if defined (GRF_ECS)
2309 CMOVE(tmp, R_DIWHIGH, 0x2100);
2310 #endif
2311 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3])));
2312 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD3])));
2313 CEND(tmp);
2314 CEND(tmp);
2315
2316 tmp = find_copper_inst(p24_this_data->frames[F_QD_STORE_QUAD3], CI_MOVE(R_BPLMOD2));
2317 CBUMP(tmp);
2318 CMOVE(tmp, R_BPL0PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE])));
2319 CMOVE(tmp, R_BPL0PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + HALF_2024_LINE])));
2320 CMOVE(tmp, R_BPL1PTH, HIADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE])));
2321 CMOVE(tmp, R_BPL1PTL, LOADDR(PREP_DMA_MEM(&plane[0][half_plane + full_line + HALF_2024_LINE])));
2322 if (depth == 2) {
2323 CMOVE(tmp, R_BPL2PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE])));
2324 CMOVE(tmp, R_BPL2PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + HALF_2024_LINE])));
2325 CMOVE(tmp, R_BPL3PTH, HIADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE])));
2326 CMOVE(tmp, R_BPL3PTL, LOADDR(PREP_DMA_MEM(&plane[1][half_plane + full_line + HALF_2024_LINE])));
2327 }
2328 #if defined (GRF_ECS)
2329 CMOVE(tmp, R_DIWHIGH, 0x2100);
2330 #endif
2331 CMOVE(tmp, R_COP1LCH, HIADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0])));
2332 CMOVE(tmp, R_COP1LCL, LOADDR(PREP_DMA_MEM(p24_this_data->frames[F_QD_STORE_QUAD0])));
2333 CEND(tmp);
2334 CEND(tmp);
2335
2336 /* swap new pointers in. */
2337 for (i = F_QD_STORE_QUAD0, j = F_QD_QUAD0;
2338 i <= F_QD_STORE_QUAD3; i++, j++) {
2339 cp = p24_this_data->frames[j];
2340 p24_this_data->frames[j] = p24_this_data->frames[i];
2341 p24_this_data->frames[i] = cp;
2342 }
2343
2344 p24_this_data->current_view = v;
2345 vd->flags |= VF_DISPLAY;
2346
2347 cc_a2024_use_colormap(v, vd->colormap);
2348 }
2349 cc_load_mode(p24_this);
2350 }
2351
2352 void
2353 pal_a2024_mode_vbl_handler(d)
2354 dmode_t *d;
2355 {
2356 u_short vp = ((custom.vposr & 0x0007) << 8) | ((custom.vhposr) >> 8);
2357
2358 if (vp < 20) {
2359 custom.cop1lc = PREP_DMA_MEM(p24_this_data->frames[p24_this_data->hedley_current]);
2360 custom.copjmp1 = 0;
2361 }
2362 p24_this_data->hedley_current++;
2363 p24_this_data->hedley_current &= 0x3; /* if 4 then 0. */
2364 }
2365 #endif /* GRF_PAL */
2366 #endif /* GRF_A2024 */
2367