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