1 /* $NetBSD: grfabs_tt.c,v 1.21 2009/07/19 05:43:22 tsutsui Exp $ */
4 * Copyright (c) 1995 Leo Weppelman.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: grfabs_tt.c,v 1.21 2009/07/19 05:43:22 tsutsui Exp $");
33 * atari abstract graphics driver: TT-interface
35 #include <sys/param.h>
36 #include <sys/queue.h>
37 #include <sys/malloc.h>
38 #include <sys/device.h>
39 #include <sys/systm.h>
41 #include <uvm/uvm_extern.h>
43 #include <machine/iomap.h>
44 #include <machine/video.h>
45 #include <machine/mfp.h>
46 #include <atari/atari/device.h>
47 #include <atari/atari/stalloc.h>
48 #include <atari/dev/grfabs_reg.h>
49 #include <atari/dev/grfabs_tt.h>
54 static void init_view(view_t
*, bmap_t
*, dmode_t
*, box_t
*);
55 static bmap_t
*alloc_bitmap(u_long
, u_long
, u_char
);
56 static colormap_t
*alloc_colormap(dmode_t
*);
57 static void free_bitmap(bmap_t
*);
58 static void tt_display_view(view_t
*);
59 static view_t
*tt_alloc_view(dmode_t
*, dimen_t
*, u_char
);
60 static void tt_free_view(view_t
*);
61 static void tt_remove_view(view_t
*);
62 static void tt_save_view(view_t
*);
63 static int tt_use_colormap(view_t
*, colormap_t
*);
66 * Our function switch table
68 struct grfabs_sw tt_vid_sw
= {
78 u_short tt_reg
; /* video mode-register TT */
80 #define vm_reg(dm) (((struct tt_hwregs*)(dm->data))->tt_reg)
83 * Note that the order of this table *must* match the order of
86 static struct tt_hwregs tt_hwregs
[] = {
95 static dmode_t vid_modes
[] = {
96 { { NULL
, NULL
}, "sthigh", { 640, 400 }, 1, NULL
, &tt_vid_sw
},
97 { { NULL
, NULL
}, "tthigh", { 1280, 960 }, 1, NULL
, &tt_vid_sw
},
98 { { NULL
, NULL
}, "stmid", { 640, 200 }, 2, NULL
, &tt_vid_sw
},
99 { { NULL
, NULL
}, "stlow", { 320, 200 }, 4, NULL
, &tt_vid_sw
},
100 { { NULL
, NULL
}, "ttmid", { 640, 480 }, 4, NULL
, &tt_vid_sw
},
101 { { NULL
, NULL
}, "ttlow", { 320, 480 }, 8, NULL
, &tt_vid_sw
},
102 { { NULL
, NULL
}, NULL
, }
106 * XXX: called from ite console init routine.
107 * Initialize list of possible video modes.
111 tt_probe_video(MODES
*modelp
)
118 * First find out what kind of monitor is attached. DMA-sound
119 * should be off because the 'sound-done' and 'monochrome-detect'
120 * are xor-ed together. I think that shutting it down here is the
123 has_mono
= (MFP
->mf_gpip
& IA_MONO
) == 0;
125 for (i
= 0; (dm
= &vid_modes
[i
])->name
!= NULL
; i
++) {
126 dm
->data
= (void *)&tt_hwregs
[i
];
127 if (has_mono
&& (vm_reg(dm
) != RES_TTHIGH
))
129 if (!has_mono
&& (vm_reg(dm
) == RES_TTHIGH
))
131 LIST_INSERT_HEAD(modelp
, dm
, link
);
134 for (i
=0; i
< 16; i
++)
135 VIDEO
->vd_tt_rgb
[i
] = CM_L2TT(gra_def_color16
[i
]);
139 tt_display_view(view_t
*v
)
141 dmode_t
*dm
= v
->mode
;
142 bmap_t
*bm
= v
->bitmap
;
144 if (dm
->current_view
) {
146 * Mark current view for this mode as no longer displayed
148 dm
->current_view
->flags
&= ~VF_DISPLAY
;
150 dm
->current_view
= v
;
151 v
->flags
|= VF_DISPLAY
;
153 tt_use_colormap(v
, v
->colormap
);
155 /* XXX: should use vbl for this */
156 VIDEO
->vd_tt_res
= vm_reg(dm
);
157 VIDEO
->vd_raml
= (u_long
)bm
->hw_address
& 0xff;
158 VIDEO
->vd_ramm
= ((u_long
)bm
->hw_address
>> 8) & 0xff;
159 VIDEO
->vd_ramh
= ((u_long
)bm
->hw_address
>> 16) & 0xff;
163 tt_remove_view(view_t
*v
)
165 dmode_t
*mode
= v
->mode
;
167 if (mode
->current_view
== v
) {
169 if (v
->flags
& VF_DISPLAY
)
170 panic("Cannot shutdown display"); /* XXX */
172 mode
->current_view
= NULL
;
174 v
->flags
&= ~VF_DISPLAY
;
178 tt_save_view(view_t
*v
)
183 tt_free_view(view_t
*v
)
187 if (v
->colormap
!= &gra_con_cmap
)
188 free(v
->colormap
, M_DEVBUF
);
189 free_bitmap(v
->bitmap
);
190 if (v
!= &gra_con_view
)
196 tt_use_colormap(view_t
*v
, colormap_t
*cm
)
199 volatile u_short
*creg
;
210 * I guess it seems reasonable to require the maps to be
211 * of the same type...
213 if (cm
->type
!= vcm
->type
)
217 * First figure out where the actual colormap resides and
218 * howmany colors are in it.
220 switch (vm_reg(dm
)) {
222 creg
= &VIDEO
->vd_tt_rgb
[0];
226 creg
= &VIDEO
->vd_tt_rgb
[0];
230 creg
= &VIDEO
->vd_tt_rgb
[254];
234 creg
= &VIDEO
->vd_tt_rgb
[0];
238 creg
= &VIDEO
->vd_tt_rgb
[0];
242 return(0); /* No colors */
244 panic("grf_tt:use_colormap: wrong mode!?");
247 /* If first entry specified beyond capabilities -> error */
248 if (cm
->first
>= ncreg
)
252 * A little tricky, the actual colormap pointer will be NULL
253 * when view is not displaying, valid otherwise.
255 if (v
->flags
& VF_DISPLAY
)
256 creg
= &creg
[cm
->first
];
259 vcreg
= &vcm
->entry
[cm
->first
];
261 if (cm
->size
> ncreg
)
265 for (i
= 0, src
= cm
->entry
; i
< ncreg
; i
++, vcreg
++) {
269 * If displaying, also update actual color registers.
272 *creg
++ = CM_L2TT(*vcreg
);
278 tt_alloc_view(dmode_t
*mode
, dimen_t
*dim
, u_char depth
)
283 if (!atari_realconfig
)
285 else v
= malloc(sizeof(*v
), M_DEVBUF
, M_NOWAIT
);
289 bm
= alloc_bitmap(mode
->size
.width
, mode
->size
.height
, mode
->depth
);
293 v
->colormap
= alloc_colormap(mode
);
295 INIT_BOX(&box
,0,0,mode
->size
.width
,mode
->size
.height
);
296 init_view(v
, bm
, mode
, &box
);
301 if (v
!= &gra_con_view
)
307 init_view(view_t
*v
, bmap_t
*bm
, dmode_t
*mode
, box_t
*dbox
)
312 memcpy(&v
->display
, dbox
, sizeof(box_t
));
315 /* bitmap functions */
318 alloc_bitmap(u_long width
, u_long height
, u_char depth
)
320 u_long total_size
, bm_size
;
325 * Sigh, it seems for mapping to work we need the bitplane data to
326 * 1: be aligned on a page boundry.
327 * 2: be n pages large.
329 * why? because the user gets a page aligned address, if this is before
330 * your allocation, too bad. Also it seems that the mapping routines
331 * do not watch to closely to the allowable length. so if you go over
332 * n pages by less than another page, the user gets to write all over
333 * the entire page. Since you did not allocate up to a page boundry
334 * (or more) the user writes into someone elses memory. -ch
336 bm_size
= m68k_round_page((width
* height
* depth
) / NBBY
);
337 total_size
= bm_size
+ sizeof(bmap_t
) + PAGE_SIZE
;
339 if ((bm
= (bmap_t
*)alloc_stmem(total_size
, &hw_address
)) == NULL
)
342 bm
->plane
= (u_char
*)bm
+ sizeof(bmap_t
);
343 bm
->plane
= (u_char
*)m68k_round_page(bm
->plane
);
344 bm
->hw_address
= (u_char
*)hw_address
+ sizeof(bmap_t
);
345 bm
->hw_address
= (u_char
*)m68k_round_page(bm
->hw_address
);
346 bm
->bytes_per_row
= (width
* depth
) / NBBY
;
352 bm
->phys_mappable
= (depth
* width
* height
) / NBBY
;
354 bm
->vga_address
= NULL
;
355 bm
->vga_mappable
= 0;
358 memset(bm
->plane
, 0, bm_size
);
363 free_bitmap(bmap_t
*bm
)
370 alloc_colormap(dmode_t
*dm
)
374 u_char type
= CM_COLOR
;
376 switch (vm_reg(dm
)) {
395 panic("grf_tt:alloc_colormap: wrong mode!?");
397 if (!atari_realconfig
) {
399 cm
->entry
= gra_con_colors
;
404 size
= sizeof(*cm
) + (nentries
* sizeof(cm
->entry
[0]));
405 cm
= malloc(size
, M_DEVBUF
, M_NOWAIT
);
408 cm
->entry
= (long *)&cm
[1];
411 if ((cm
->type
= type
) == CM_COLOR
)
412 cm
->red_mask
= cm
->green_mask
= cm
->blue_mask
= 0xf;
416 for (i
= 0; i
< nentries
; i
++)
417 cm
->entry
[i
] = gra_def_color16
[i
% 16];
420 #endif /* TT_VIDEO */