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