From 9c9abeb6c3c2cd49b95b878d0f55f25440f62711 Mon Sep 17 00:00:00 2001 From: leo Date: Sun, 20 Aug 1995 18:17:09 +0000 Subject: [PATCH] Add Falcon video support. Thanks to Thomas Gerner. --- sys/arch/atari/conf/ATARITT | 3 +- sys/arch/atari/conf/BOOT | 4 +- sys/arch/atari/conf/FALCON | 3 +- sys/arch/atari/conf/GENERIC | 4 +- sys/arch/atari/conf/files.atari | 4 +- sys/arch/atari/dev/grfabs.c | 401 +++++------------------------- sys/arch/atari/dev/grfabs_fal.c | 424 ++++++++++++++++++++++++++++++++ sys/arch/atari/dev/grfabs_reg.h | 59 ++++- sys/arch/atari/dev/grfabs_tt.c | 402 ++++++++++++++++++++++++++++++ 9 files changed, 947 insertions(+), 357 deletions(-) create mode 100644 sys/arch/atari/dev/grfabs_fal.c create mode 100644 sys/arch/atari/dev/grfabs_tt.c diff --git a/sys/arch/atari/conf/ATARITT b/sys/arch/atari/conf/ATARITT index d0a4ab37a283..511b1ceb420f 100644 --- a/sys/arch/atari/conf/ATARITT +++ b/sys/arch/atari/conf/ATARITT @@ -1,5 +1,5 @@ # -# $NetBSD: ATARITT,v 1.4 1995/08/11 20:01:15 leo Exp $ +# $NetBSD: ATARITT,v 1.5 1995/08/20 18:17:09 leo Exp $ # # ATARI-TT # @@ -78,6 +78,7 @@ options GENERIC # Mini-root boot support # Atari specific kernel options: # options TT_SCSI # SCSI-support for TT only +options TT_VIDEO # Graphics support for TT only # # Build one kernel that can boot from any disk. diff --git a/sys/arch/atari/conf/BOOT b/sys/arch/atari/conf/BOOT index c0ed25733153..38ea6acbd892 100644 --- a/sys/arch/atari/conf/BOOT +++ b/sys/arch/atari/conf/BOOT @@ -1,5 +1,5 @@ # -# $NetBSD: BOOT,v 1.2 1995/08/11 20:01:16 leo Exp $ +# $NetBSD: BOOT,v 1.3 1995/08/20 18:17:10 leo Exp $ # # BOOT # @@ -72,6 +72,8 @@ options GENERIC # Mini-root boot support options "ST_POOL_SIZE=22" # smallest that allows TT-HIGH options TT_SCSI # SCSI-support for TT options FALCON_SCSI # SCSI-support for Falcon +options TT_VIDEO # Graphics support for TT +options FALCON_VIDEO # Graphics support for FALCON # # Build one kernel that can boot from any disk. diff --git a/sys/arch/atari/conf/FALCON b/sys/arch/atari/conf/FALCON index 709f1080e24a..bfcb261d16bd 100644 --- a/sys/arch/atari/conf/FALCON +++ b/sys/arch/atari/conf/FALCON @@ -1,5 +1,5 @@ # -# $NetBSD: FALCON,v 1.1 1995/08/11 20:01:17 leo Exp $ +# $NetBSD: FALCON,v 1.2 1995/08/20 18:20:54 leo Exp $ # # ATARI-FALCON # @@ -64,6 +64,7 @@ options GENERIC # Mini-root boot support # Atari specific kernel options: # options FALCON_SCSI # SCSI-support for FACLON only +options FALCON_VIDEO # Graphics support for FALCON # # Build one kernel that can boot from any disk. diff --git a/sys/arch/atari/conf/GENERIC b/sys/arch/atari/conf/GENERIC index c2b599710e70..4cd439a82770 100644 --- a/sys/arch/atari/conf/GENERIC +++ b/sys/arch/atari/conf/GENERIC @@ -1,5 +1,5 @@ # -# $NetBSD: GENERIC,v 1.5 1995/08/11 20:01:18 leo Exp $ +# $NetBSD: GENERIC,v 1.6 1995/08/20 18:17:11 leo Exp $ # # Generic atari # @@ -86,6 +86,8 @@ options GENERIC # Mini-root boot support options "ST_POOL_SIZE=22" # smallest that allows TT-HIGH options TT_SCSI # SCSI-support for TT options FALCON_SCSI # SCSI-support for Falcon +options TT_VIDEO # Graphics support for TT +options FALCON_VIDEO # Graphics support for FALCON # # Build one kernel that can boot from any disk. diff --git a/sys/arch/atari/conf/files.atari b/sys/arch/atari/conf/files.atari index e6f7733800fe..80ec0022187e 100644 --- a/sys/arch/atari/conf/files.atari +++ b/sys/arch/atari/conf/files.atari @@ -1,5 +1,5 @@ # -# $NetBSD: files.atari,v 1.10 1995/08/11 20:01:19 leo Exp $ +# $NetBSD: files.atari,v 1.11 1995/08/20 18:17:12 leo Exp $ # maxpartitions 16 @@ -44,6 +44,8 @@ device grf at grfb {} file arch/atari/dev/grf.c grf needs-count file arch/atari/dev/ite_cc.c grf ite file arch/atari/dev/grfabs.c grf ite +file arch/atari/dev/grfabs_tt.c grf ite +file arch/atari/dev/grfabs_fal.c grf ite device ite at grf file arch/atari/dev/ite.c ite needs-flag diff --git a/sys/arch/atari/dev/grfabs.c b/sys/arch/atari/dev/grfabs.c index 4f2d60d680f6..951fb1a64218 100644 --- a/sys/arch/atari/dev/grfabs.c +++ b/sys/arch/atari/dev/grfabs.c @@ -1,4 +1,4 @@ -/* $NetBSD: grfabs.c,v 1.4 1995/05/21 10:54:44 leo Exp $ */ +/* $NetBSD: grfabs.c,v 1.5 1995/08/20 18:17:31 leo Exp $ */ /* * Copyright (c) 1995 Leo Weppelman. @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -46,62 +47,47 @@ * Function decls */ static dmode_t *get_best_display_mode __P((dimen_t *, int, dmode_t *)); -static view_t *alloc_view __P((dmode_t *, dimen_t *, u_char)); -static void init_view __P((view_t *, bmap_t *, dmode_t *, box_t *)); -static bmap_t *alloc_bitmap __P((u_long, u_long, u_char)); -static void free_bitmap __P((bmap_t *)); -static colormap_t *alloc_colormap __P((dmode_t *)); - -/* - * Ugh.. Stuff needed to allocate console structures before the VM-system - * is running. There is no malloc() available at that time. - */ -extern int atari_realconfig; /* 0 -> no malloc */ -static view_t con_view; -static colormap_t con_cmap; -static long con_colors[MAX_CENTRIES]; /* * List of available graphic modes */ -static LIST_HEAD(modelist, display_mode) modes; +static MODES modes; -static dmode_t vid_modes[] = { - { { NULL, NULL }, "sthigh", { 640, 400 }, 1, RES_STHIGH }, - { { NULL, NULL }, "tthigh", { 1280, 960 }, 1, RES_TTHIGH }, - { { NULL, NULL }, "stmid", { 640, 200 }, 2, RES_STMID }, - { { NULL, NULL }, "stlow", { 320, 200 }, 4, RES_STLOW }, - { { NULL, NULL }, "ttmid", { 640, 480 }, 4, RES_TTMID }, - { { NULL, NULL }, "ttlow", { 320, 480 }, 8, RES_TTLOW }, - { { NULL, NULL }, NULL, } -}; +/* + * Ugh.. Stuff needed to allocate console structures before the VM-system + * is running. There is no malloc() available at that time. + * Decision to use these: atari_realconfig == 0 + */ +view_t gra_con_view; +colormap_t gra_con_cmap; +long gra_con_colors[MAX_CENTRIES]; /* * Default colors..... - * Currently the TT-low (256 colors) just uses 16 time the 16-color default. + * Currently the TT-low (256 colors) just uses 16 times the 16-color default. * If you have a sensible 256 scale, feel free to add..... * The first 2 colors in all maps are {black,white}, so ite (text) displays * are initially readable. Also, this enables me to supply only 1 map. The * 4 color mode uses the first four entries of the 16 color mode thus giving * a gray scale display. (Maybe we can add an intensity bit to the ite...) */ -static u_short def_color16[16] = { - 0x000, /* black */ - 0xfff, /* white */ - 0xccc, /* light gray */ - 0x888, /* gray */ - 0x00c, /* blue */ - 0x0c0, /* green */ - 0x0cc, /* cyan */ - 0xc00, /* red */ - 0xc0c, /* magenta */ - 0xcc0, /* brown */ - 0x00f, /* light blue */ - 0x0f0, /* light green */ - 0x0ff, /* light cyan */ - 0xf00, /* light red */ - 0xf0f, /* light magenta */ - 0xff0 /* light brown */ +u_long gra_def_color16[16] = { + 0x00000000, /* black */ + 0x00ffffff, /* white */ + 0x00c0c0c0, /* light gray */ + 0x00808080, /* gray */ + 0x000000c0, /* blue */ + 0x0000c000, /* green */ + 0x0000c0c0, /* cyan */ + 0x00c00000, /* red */ + 0x00c000c0, /* magenta */ + 0x00c0c000, /* brown */ + 0x000000ff, /* light blue */ + 0x0000ff00, /* light green */ + 0x0000ffff, /* light cyan */ + 0x00ff0000, /* light red */ + 0x00ff00ff, /* light magenta */ + 0x00ffff00 /* light brown */ }; /* @@ -111,38 +97,23 @@ static u_short def_color16[16] = { int grfabs_probe() { - dmode_t *dm; - int i; - int has_mono; - static int inited = 0; + static int inited = 0; - if(inited) - return(1); /* Has to be done only once */ + if (inited) + return (1); /* Has to be done only once */ inited++; - /* - * First find out what kind of monitor is attached. Dma-sound - * should be off because the 'sound-done' and 'monochrome-detect' - * are xor-ed together. I think that shutting it down here is the - * wrong place. - */ - has_mono = (MFP->mf_gpip & IA_MONO) == 0; - LIST_INIT(&modes); - for(i = 0; (dm = &vid_modes[i])->name != NULL; i++) { - if(has_mono && (dm->vm_reg != RES_TTHIGH)) - continue; - if(!has_mono && (dm->vm_reg == RES_TTHIGH)) - continue; - LIST_INSERT_HEAD(&modes, dm, link); - } - /* - * This seems to prevent bordered screens. - */ - for(i=0; i < 16; i++) - VIDEO->vd_tt_rgb[i] = def_color16[i]; - return(1); +#ifdef FALCON_VIDEO + if (machineid & ATARI_FALCON) + falcon_probe_video(&modes); +#endif /* FALCON_VIDEO */ +#ifdef TT_VIDEO + if (machineid & ATARI_TT) + tt_probe_video(&modes); +#endif /* TT_VIDEO */ + return ((modes.lh_first == NULL) ? 0 : 1); } view_t * @@ -151,10 +122,10 @@ dmode_t *d; dimen_t *dim; u_char depth; { - if(!d) + if (!d) d = get_best_display_mode(dim, depth, NULL); - if(d) - return(alloc_view(d, dim, depth)); + if (d) + return ((d->grfabs_funcs->alloc_view)(d, dim, depth)); return(NULL); } @@ -163,61 +134,25 @@ grf_get_best_mode(dim, depth) dimen_t *dim; u_char depth; { - return(get_best_display_mode(dim, depth, NULL)); + return (get_best_display_mode(dim, depth, NULL)); } void grf_display_view(v) view_t *v; { - dmode_t *dm = v->mode; - bmap_t *bm = v->bitmap; - - if(dm->current_view) { - /* - * Mark current view for this mode as no longer displayed - */ - dm->current_view->flags &= ~VF_DISPLAY; - } - dm->current_view = v; - v->flags |= VF_DISPLAY; - - grf_use_colormap(v, v->colormap); - - /* XXX: should use vbl for this */ - VIDEO->vd_tt_res = dm->vm_reg; - VIDEO->vd_raml = (u_long)bm->hw_address & 0xff; - VIDEO->vd_ramm = ((u_long)bm->hw_address >> 8) & 0xff; - VIDEO->vd_ramh = ((u_long)bm->hw_address >> 16) & 0xff; + (v->mode->grfabs_funcs->display_view)(v); } void grf_remove_view(v) view_t *v; { - dmode_t *mode = v->mode; - - if(mode->current_view == v) { -#if 0 - if(v->flags & VF_DISPLAY) - panic("Cannot shutdown display\n"); /* XXX */ -#endif - mode->current_view = NULL; - } - v->flags &= ~VF_DISPLAY; + (v->mode->grfabs_funcs->remove_view)(v); } void grf_free_view(v) view_t *v; { - if(v) { - dmode_t *md = v->mode; - - grf_remove_view(v); - if(v->colormap != &con_cmap) - free(v->colormap, M_DEVBUF); - free_bitmap(v->bitmap); - if(v != &con_view) - free(v, M_DEVBUF); - } + (v->mode->grfabs_funcs->free_view)(v); } int @@ -243,9 +178,9 @@ colormap_t *cm; * Copy the colors */ bzero(cm->entry, cm->size * sizeof(long)); - for(i = 0; i < n; i++) + for (i = 0; i < n; i++) cm->entry[i] = gcm->entry[i]; - return(0); + return (0); } int @@ -253,83 +188,7 @@ grf_use_colormap(v, cm) view_t *v; colormap_t *cm; { - dmode_t *dm; - volatile u_short *creg; - u_long *src; - colormap_t *vcm; - u_long *vcreg; - u_short ncreg; - int i; - - dm = v->mode; - vcm = v->colormap; - - /* - * I guess it seems reasonable to require the maps to be - * of the same type... - */ - if(cm->type != vcm->type) - return(EINVAL); - - /* - * First figure out where the actual colormap resides and - * howmany colors are in it. - */ - switch(dm->vm_reg) { - case RES_STLOW: - creg = &VIDEO->vd_tt_rgb[0]; - ncreg = 16; - break; - case RES_STMID: - creg = &VIDEO->vd_tt_rgb[0]; - ncreg = 4; - break; - case RES_STHIGH: - creg = &VIDEO->vd_tt_rgb[254]; - ncreg = 2; - break; - case RES_TTLOW: - creg = &VIDEO->vd_tt_rgb[0]; - ncreg = 256; - break; - case RES_TTMID: - creg = &VIDEO->vd_tt_rgb[0]; - ncreg = 16; - break; - case RES_TTHIGH: - return(0); /* No colors */ - default: - panic("grf_get_colormap: wrong mode!?"); - } - - /* If first entry specified beyond capabilities -> error */ - if(cm->first >= ncreg) - return(EINVAL); - - /* - * A little tricky, the actual colormap pointer will be NULL - * when view is not displaying, valid otherwise. - */ - if(v->flags & VF_DISPLAY) - creg = &creg[cm->first]; - else creg = NULL; - - vcreg = &vcm->entry[cm->first]; - ncreg -= cm->first; - if(cm->size > ncreg) - return(EINVAL); - ncreg = cm->size; - - for(i = 0, src = cm->entry; i < ncreg; i++, vcreg++) { - *vcreg = *src++; - - /* - * If displaying, also update actual color register. - */ - if(creg != NULL) - *creg++ = CM_LTOW(*vcreg); - } - return(0); + return (v->mode->grfabs_funcs->use_colormap)(v, cm); } static dmode_t * @@ -344,7 +203,7 @@ dmode_t *curr_mode; save = NULL; dm = modes.lh_first; - while(dm != NULL) { + while (dm != NULL) { dx = abs(dm->size.width - dim->width); dy = abs(dm->size.height - dim->height); ct = dx + dy; @@ -358,162 +217,12 @@ dmode_t *curr_mode; /* * Did we do better than the current mode? */ - if((save != NULL) && (curr_mode != NULL)) { + if ((save != NULL) && (curr_mode != NULL)) { dx = abs(curr_mode->size.width - dim->width); dy = abs(curr_mode->size.height - dim->height); ct = dx + dy; - if(ct <= dt) - return(NULL); + if (ct <= dt) + return (NULL); } return (save); } - -static view_t * -alloc_view(mode, dim, depth) -dmode_t *mode; -dimen_t *dim; -u_char depth; -{ - view_t *v; - bmap_t *bm; - - if(!atari_realconfig) - v = &con_view; - else v = malloc(sizeof(*v), M_DEVBUF, M_NOWAIT); - if(v == NULL) - return(NULL); - - bm = alloc_bitmap(mode->size.width, mode->size.height, mode->depth); - if(bm) { - box_t box; - - v->colormap = alloc_colormap(mode); - if(v->colormap) { - INIT_BOX(&box,0,0,mode->size.width,mode->size.height); - init_view(v, bm, mode, &box); - return(v); - } - free_bitmap(bm); - } - if(v != &con_view) - free(v, M_DEVBUF); - return (NULL); -} - -static void -init_view(v, bm, mode, dbox) -view_t *v; -bmap_t *bm; -dmode_t *mode; -box_t *dbox; -{ - v->bitmap = bm; - v->mode = mode; - v->flags = 0; - bcopy(dbox, &v->display, sizeof(box_t)); -} - -/* bitmap functions */ - -static bmap_t * -alloc_bitmap(width, height, depth) -u_long width, height; -u_char depth; -{ - int i; - u_long total_size, bm_size; - void *hw_address; - bmap_t *bm; - - /* - * Sigh, it seems for mapping to work we need the bitplane data to - * 1: be aligned on a page boundry. - * 2: be n pages large. - * - * why? because the user gets a page aligned address, if this is before - * your allocation, too bad. Also it seems that the mapping routines - * do not watch to closely to the allowable length. so if you go over - * n pages by less than another page, the user gets to write all over - * the entire page. Since you did not allocate up to a page boundry - * (or more) the user writes into someone elses memory. -ch - */ - bm_size = atari_round_page((width * height * depth) / NBBY); - total_size = bm_size + sizeof(bmap_t) + NBPG; - - if((bm = (bmap_t*)alloc_stmem(total_size, &hw_address)) == NULL) - return(NULL); - - bm->plane = (u_char*)bm + sizeof(bmap_t); - bm->plane = (u_char*)atari_round_page(bm->plane); - bm->hw_address = (u_char*)hw_address + sizeof(bmap_t); - bm->hw_address = (u_char*)atari_round_page(bm->hw_address); - bm->bytes_per_row = (width * depth) / NBBY; - bm->rows = height; - bm->depth = depth; - - bzero(bm->plane, bm_size); - return(bm); -} - -static void -free_bitmap(bm) -bmap_t *bm; -{ - if(bm) - free_stmem(bm); -} - -static colormap_t * -alloc_colormap(dm) -dmode_t *dm; -{ - int nentries, i; - colormap_t *cm; - u_char type = CM_COLOR; - - switch(dm->vm_reg) { - case RES_STLOW: - case RES_TTMID: - nentries = 16; - break; - case RES_STMID: - nentries = 4; - break; - case RES_STHIGH: - nentries = 2; - break; - case RES_TTLOW: - nentries = 256; - break; - case RES_TTHIGH: - type = CM_MONO; - nentries = 0; - break; - default: - panic("grf:alloc_colormap: wrong mode!?"); - } - if(!atari_realconfig) { - cm = &con_cmap; - cm->entry = con_colors; - } - else { - int size; - - size = sizeof(*cm) + (nentries * sizeof(cm->entry[0])); - cm = malloc(size, M_DEVBUF, M_NOWAIT); - if(cm == NULL) - return(NULL); - cm->entry = (long *)&cm[1]; - - } - if((cm->type = type) == CM_COLOR) - cm->red_mask = cm->green_mask = cm->blue_mask = 0xf; - cm->first = 0; - cm->size = nentries; - - for(i = 0; i < nentries; i++) { - register short val = def_color16[i % 16]; - cm->entry[i] = CM_WTOL(val); - } - return(cm); -} diff --git a/sys/arch/atari/dev/grfabs_fal.c b/sys/arch/atari/dev/grfabs_fal.c new file mode 100644 index 000000000000..72b9f9da5a69 --- /dev/null +++ b/sys/arch/atari/dev/grfabs_fal.c @@ -0,0 +1,424 @@ +/* $NetBSD: grfabs_fal.c,v 1.1 1995/08/20 18:17:32 leo Exp $ */ + +/* + * Copyright (c) 1995 Leo Weppelman. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Leo Weppelman. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef FALCON_VIDEO +/* + * atari abstract graphics driver: Falcon-interface + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Function decls + */ +static void init_view __P((view_t *, bmap_t *, dmode_t *, box_t *)); +static bmap_t *alloc_bitmap __P((u_long, u_long, u_char)); +static colormap_t *alloc_colormap __P((dmode_t *)); +static void free_bitmap __P((bmap_t *)); +static void falcon_display_view __P((view_t *)); +static view_t *falcon_alloc_view __P((dmode_t *, dimen_t *, u_char)); +static void falcon_free_view __P((view_t *)); +static void falcon_remove_view __P((view_t *)); +static int falcon_use_colormap __P((view_t *, colormap_t *)); +static void falcon_dedect __P((dmode_t *)); + +/* + * Our function switch table + */ +struct grfabs_sw fal_vid_sw = { + falcon_display_view, + falcon_alloc_view, + falcon_free_view, + falcon_remove_view, + falcon_use_colormap +}; + +static dmode_t vid_modes[] = { + { { NULL, NULL }, "falauto",{ 0, 0 }, 0, RES_FALAUTO ,&fal_vid_sw}, + { { NULL, NULL }, "sthigh", { 640, 400 }, 1, RES_FAL_STHIGH ,&fal_vid_sw}, + { { NULL, NULL }, "stmid", { 640, 200 }, 2, RES_FAL_STMID ,&fal_vid_sw}, + { { NULL, NULL }, "stlow", { 320, 200 }, 4, RES_FAL_STLOW ,&fal_vid_sw}, + { { NULL, NULL }, "ttlow", { 320, 480 }, 8, RES_FAL_TTLOW ,&fal_vid_sw}, + { { NULL, NULL }, "vga2", { 640, 480 }, 1, RES_VGA2 ,&fal_vid_sw}, + { { NULL, NULL }, "vga4", { 640, 480 }, 2, RES_VGA4 ,&fal_vid_sw}, + { { NULL, NULL }, "vga16", { 640, 480 }, 4, RES_VGA16 ,&fal_vid_sw}, + { { NULL, NULL }, "vga256", { 640, 480 }, 8, RES_VGA256 ,&fal_vid_sw}, + { { NULL, NULL }, "highcol",{ 320, 200 }, 16, RES_DIRECT ,&fal_vid_sw}, + { { NULL, NULL }, NULL, } +}; + +/* + * XXX: called from ite console init routine. + * Initialize list of posible video modes. + */ +void +falcon_probe_video(modelp) +MODES *modelp; +{ + dmode_t *dm; + int i; + + /* Currently we support only one mode of the falcon video system. + * This is the mode that is initialized before NetBSD starts. This + * is possible since the bios has already done that work. + */ + + for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) { + if (dm->vm_reg == RES_FALAUTO) { + falcon_dedect(dm); + LIST_INSERT_HEAD(modelp, dm, link); + } + } + + /* + * This seems to prevent bordered screens. + */ + for (i=0; i < 16; i++) + VIDEO->vd_fal_rgb[i] = CM_L2FAL(gra_def_color16[i]); +} + +static void +falcon_dedect(dm) +dmode_t *dm; +{ + u_short falshift, stshift; + short interlace, doublescan; + + interlace = (VIDEO->vd_fal_ctrl & 0x2) >>1; + doublescan = VIDEO->vd_fal_ctrl & 0x1; + + /* + * Calculate the depth of the screen + */ + + falshift = VIDEO->vd_fal_res; + stshift = VIDEO->vd_st_res; + + if (falshift & 0x400) /* 2 color */ + dm->depth = 1; + else if (falshift & 0x100) /* high color, direct */ + dm->depth = 16; + else if (falshift & 0x10) /* 256 color */ + dm->depth = 8; + else if (stshift == 0) /* 16 color */ + dm->depth = 4; + else if (stshift == 1) /* 4 color */ + dm->depth = 2; + else dm->depth = 1; /* 2 color */ + + /* + * Now calculate the screen hight + */ + + dm->size.height = VIDEO->vd_v_dis_end - VIDEO->vd_v_dis_beg; + if (!interlace) dm->size.height >>=1; + if (doublescan) dm->size.height >>=1; + + /* + * And the width + */ + + dm->size.width = VIDEO->vd_vert_wrap * 16 / dm->depth; +} + +static void +falcon_display_view(v) +view_t *v; +{ + dmode_t *dm = v->mode; + bmap_t *bm = v->bitmap; + + if (dm->current_view) { + /* + * Mark current view for this mode as no longer displayed + */ + dm->current_view->flags &= ~VF_DISPLAY; + } + dm->current_view = v; + v->flags |= VF_DISPLAY; + + falcon_use_colormap(v, v->colormap); + + /* XXX: should use vbl for this */ + /* + * Falcon: here should set the videl to switch the video mode. + * This will be added later. + * At the moment we set only the video base. + */ + VIDEO->vd_raml = (u_long)bm->hw_address & 0xff; + VIDEO->vd_ramm = ((u_long)bm->hw_address >> 8) & 0xff; + VIDEO->vd_ramh = ((u_long)bm->hw_address >> 16) & 0xff; +} + +static void +falcon_remove_view(v) +view_t *v; +{ + dmode_t *mode = v->mode; + + if (mode->current_view == v) { +#if 0 + if (v->flags & VF_DISPLAY) + panic("Cannot shutdown display\n"); /* XXX */ +#endif + mode->current_view = NULL; + } + v->flags &= ~VF_DISPLAY; +} + +static void +falcon_free_view(v) +view_t *v; +{ + if (v) { + dmode_t *md = v->mode; + + falcon_remove_view(v); + if (v->colormap != &gra_con_cmap) + free(v->colormap, M_DEVBUF); + free_bitmap(v->bitmap); + if (v != &gra_con_view) + free(v, M_DEVBUF); + } +} + +static int +falcon_use_colormap(v, cm) +view_t *v; +colormap_t *cm; +{ + dmode_t *dm; + volatile u_short *creg; + volatile u_long *fcreg; + u_long *src; + colormap_t *vcm; + u_long *vcreg; + u_short ncreg; + int i; + + dm = v->mode; + vcm = v->colormap; + + /* + * I guess it seems reasonable to require the maps to be + * of the same type... + */ + if (cm->type != vcm->type) + return (EINVAL); + + /* + * First get the colormap addresses an calculate + * howmany colors are in it. + */ + if (dm->depth == 16) /* direct color, no colormap; + but also not (yet) supported */ + return(0); + fcreg = &VIDEO->vd_fal_rgb[0]; + creg = &VIDEO->vd_st_rgb[0]; + ncreg = 1 << dm->depth; + + /* If first entry specified beyond capabilities -> error */ + if (cm->first >= ncreg) + return (EINVAL); + + /* + * A little tricky, the actual colormap pointer will be NULL + * when view is not displaying, valid otherwise. + */ + if (v->flags & VF_DISPLAY) + creg = &creg[cm->first]; + else creg = NULL; + + vcreg = &vcm->entry[cm->first]; + ncreg -= cm->first; + if (cm->size > ncreg) + return (EINVAL); + ncreg = cm->size; + + for (i = 0, src = cm->entry; i < ncreg; i++, vcreg++) { + *vcreg = *src++; + + /* + * If displaying, also update actual color register. + */ + if (creg != NULL) { + *fcreg++ = CM_L2FAL(*vcreg); + if (i < 16 ) + *creg++ = CM_L2ST(*vcreg); + } + } + return (0); +} + +static view_t * +falcon_alloc_view(mode, dim, depth) +dmode_t *mode; +dimen_t *dim; +u_char depth; +{ + view_t *v; + bmap_t *bm; + + if (!atari_realconfig) + v = &gra_con_view; + else v = malloc(sizeof(*v), M_DEVBUF, M_NOWAIT); + if (v == NULL) + return(NULL); + + bm = alloc_bitmap(mode->size.width, mode->size.height, mode->depth); + if (bm) { + box_t box; + + v->colormap = alloc_colormap(mode); + if (v->colormap) { + INIT_BOX(&box,0,0,mode->size.width,mode->size.height); + init_view(v, bm, mode, &box); + return(v); + } + free_bitmap(bm); + } + if (v != &gra_con_view) + free(v, M_DEVBUF); + return (NULL); +} + +static void +init_view(v, bm, mode, dbox) +view_t *v; +bmap_t *bm; +dmode_t *mode; +box_t *dbox; +{ + v->bitmap = bm; + v->mode = mode; + v->flags = 0; + bcopy(dbox, &v->display, sizeof(box_t)); +} + +/* bitmap functions */ + +static bmap_t * +alloc_bitmap(width, height, depth) +u_long width, height; +u_char depth; +{ + int i; + u_long total_size, bm_size; + void *hw_address; + bmap_t *bm; + + /* + * Sigh, it seems for mapping to work we need the bitplane data to + * 1: be aligned on a page boundry. + * 2: be n pages large. + * + * why? because the user gets a page aligned address, if this is before + * your allocation, too bad. Also it seems that the mapping routines + * do not watch to closely to the allowable length. so if you go over + * n pages by less than another page, the user gets to write all over + * the entire page. Since you did not allocate up to a page boundry + * (or more) the user writes into someone elses memory. -ch + */ + bm_size = atari_round_page((width * height * depth) / NBBY); + total_size = bm_size + sizeof(bmap_t) + NBPG; + + if ((bm = (bmap_t*)alloc_stmem(total_size, &hw_address)) == NULL) + return(NULL); + + bm->plane = (u_char*)bm + sizeof(bmap_t); + bm->plane = (u_char*)atari_round_page(bm->plane); + bm->hw_address = (u_char*)hw_address + sizeof(bmap_t); + bm->hw_address = (u_char*)atari_round_page(bm->hw_address); + bm->bytes_per_row = (width * depth) / NBBY; + bm->rows = height; + bm->depth = depth; + + bzero(bm->plane, bm_size); + return (bm); +} + +static void +free_bitmap(bm) +bmap_t *bm; +{ + if (bm) + free_stmem(bm); +} + +static colormap_t * +alloc_colormap(dm) +dmode_t *dm; +{ + int nentries, i; + colormap_t *cm; + u_char type = CM_COLOR; + + if (dm->depth == 16) /* direct color, no colormap; + not (yet) supported */ + nentries = 0; + else + nentries = 1 << dm->depth; + + if (!atari_realconfig) { + cm = &gra_con_cmap; + cm->entry = gra_con_colors; + } + else { + int size; + + size = sizeof(*cm) + (nentries * sizeof(cm->entry[0])); + cm = malloc(size, M_DEVBUF, M_NOWAIT); + if (cm == NULL) + return(NULL); + cm->entry = (long *)&cm[1]; + + } + + if ((cm->type = type) == CM_COLOR) + cm->red_mask = cm->green_mask = cm->blue_mask = 0x3f; + + cm->first = 0; + cm->size = nentries; + + for (i = 0; i < nentries; i++) + cm->entry[i] = gra_def_color16[i % 16]; + return (cm); +} +#endif /* FALCON_VIDEO */ diff --git a/sys/arch/atari/dev/grfabs_reg.h b/sys/arch/atari/dev/grfabs_reg.h index 7e48fbf54252..7ae764debf81 100644 --- a/sys/arch/atari/dev/grfabs_reg.h +++ b/sys/arch/atari/dev/grfabs_reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: grfabs_reg.h,v 1.3 1995/05/21 10:55:57 leo Exp $ */ +/* $NetBSD: grfabs_reg.h,v 1.4 1995/08/20 18:17:33 leo Exp $ */ /* * Copyright (c) 1995 Leo Weppelman @@ -128,15 +128,40 @@ enum colormap_type { /* * Create a colormap entry */ -#define MAKE_COLOR_ENTRY(r,g,b) (((r & 0xff)<<16)|((g & 0xff)<<8)|(b & 0xf)) +#define MAKE_COLOR_ENTRY(r,g,b) (((r & 0xff)<<16)|((g & 0xff)<<8)|(b & 0xff)) #define MAKE_MONO_ENTRY(x) ((x) ? 1 : 0) #define MAKE_GREY_ENTRY(l) (l & 0xff) -#define CM_LTOW(v) \ - (((0x000f0000 & (v)) >> 8) | ((0x00000f00 & (v)) >> 4) | (0xf & (v))) -#define CM_WTOL(v) \ - (((0xf00 & (v)) << 8) | ((0x0f0 & (v)) << 4) | (0xf & (v))) +#define CM_L2TT(v) \ + (((0x00f00000 & (v)) >> 12) | ((0x0000f000 & (v)) >> 8) |\ + (0x000000f0 & (v)) >> 4) +#define CM_TT2L(v) \ + ((((0x00000f00 & (v)) * 0xff / 0xf) << 8) |\ + (((0x000000f0 & (v)) * 0xff / 0xf) << 4) |\ + (0x0000000f & (v)) * 0xff / 0xf) +#define CM_L2FAL(v) \ + (((0x00fc0000 & (v)) << 8) | ((0x0000fc00 & (v)) << 8) |\ + (0x000000fc & (v))) +#define CM_FAL2L(v) \ + (((((0xfc000000 & (v)) >> 10) * 0xff / 0x3f) & 0x00ff0000) |\ + ((((0x00fc0000 & (v)) >> 10) * 0xff / 0x3f) & 0x0000ff00) |\ + ((0x000000fc & (v)) >> 2) * 0xff / 0x3f) +#define CM_L2ST(v) \ + (((0x00e00000 & (v)) >> 13) | ((0x0000e000 & (v)) >> 9) |\ + (0x000000e0 & (v)) >> 5) +#define CM_ST2L(v) \ + (((((0x00000700 & (v)) * 0xff / 0x7) << 8) & 0x00ff0000) |\ + ((((0x00000070 & (v)) * 0xff / 0x7) << 4) & 0x0000ff00) |\ + (0x00000007 & (v)) * 0xff / 0x7) +struct grfabs_sw { + void (*display_view) __P((view_t*)); + view_t * (*alloc_view) __P((dmode_t *, dimen_t *, u_char)); + void (*free_view) __P((view_t *)); + void (*remove_view) __P((view_t *)); + int (*use_colormap) __P((view_t *, colormap_t *)); +}; + /* display mode */ struct display_mode { LIST_ENTRY(display_mode) link; @@ -144,9 +169,15 @@ struct display_mode { dimen_t size; /* screen size */ u_char depth; /* screen depth */ u_short vm_reg; /* video mode register */ + struct grfabs_sw *grfabs_funcs; /* hardware switch table */ view_t *current_view; /* view displaying me */ }; +/* + * Definition of available graphic mode list. + */ +typedef LIST_HEAD(modelist, display_mode) MODES; + /* * Misc draw related macros. */ @@ -158,9 +189,25 @@ struct display_mode { (b)->height = hh; \ } while(0) + +/* + * Common variables + */ +extern view_t gra_con_view; +extern colormap_t gra_con_cmap; +extern long gra_con_colors[MAX_CENTRIES]; +extern u_long gra_def_color16[16]; + /* * Prototypes: */ +#ifdef FALCON_VIDEO +void falcon_probe_video __P((MODES *)); +#endif /* FALCON_VIDEO */ +#ifdef TT_VIDEO +void tt_probe_video __P((MODES *)); +#endif /* TT_VIDEO */ + view_t *grf_alloc_view __P((dmode_t *d, dimen_t *dim, u_char depth)); dmode_t *grf_get_best_mode __P((dimen_t *dim, u_char depth)); void grf_display_view __P((view_t *v)); diff --git a/sys/arch/atari/dev/grfabs_tt.c b/sys/arch/atari/dev/grfabs_tt.c new file mode 100644 index 000000000000..65d2a8715855 --- /dev/null +++ b/sys/arch/atari/dev/grfabs_tt.c @@ -0,0 +1,402 @@ +/* $NetBSD: grfabs_tt.c,v 1.1 1995/08/20 18:17:34 leo Exp $ */ + +/* + * Copyright (c) 1995 Leo Weppelman. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Leo Weppelman. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef TT_VIDEO +/* + * atari abstract graphics driver: TT-interface + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Function decls + */ +static void init_view __P((view_t *, bmap_t *, dmode_t *, box_t *)); +static bmap_t *alloc_bitmap __P((u_long, u_long, u_char)); +static colormap_t *alloc_colormap __P((dmode_t *)); +static void free_bitmap __P((bmap_t *)); +static void tt_display_view __P((view_t *)); +static view_t *tt_alloc_view __P((dmode_t *, dimen_t *, u_char)); +static void tt_free_view __P((view_t *)); +static void tt_remove_view __P((view_t *)); +static int tt_use_colormap __P((view_t *, colormap_t *)); + +/* + * Our function switch table + */ +struct grfabs_sw tt_vid_sw = { + tt_display_view, + tt_alloc_view, + tt_free_view, + tt_remove_view, + tt_use_colormap +}; + +static dmode_t vid_modes[] = { + { { NULL, NULL }, "sthigh", { 640, 400 }, 1, RES_STHIGH, &tt_vid_sw }, + { { NULL, NULL }, "tthigh", { 1280, 960 }, 1, RES_TTHIGH, &tt_vid_sw }, + { { NULL, NULL }, "stmid", { 640, 200 }, 2, RES_STMID , &tt_vid_sw }, + { { NULL, NULL }, "stlow", { 320, 200 }, 4, RES_STLOW , &tt_vid_sw }, + { { NULL, NULL }, "ttmid", { 640, 480 }, 4, RES_TTMID , &tt_vid_sw }, + { { NULL, NULL }, "ttlow", { 320, 480 }, 8, RES_TTLOW , &tt_vid_sw }, + { { NULL, NULL }, NULL, } +}; + +/* + * XXX: called from ite console init routine. + * Initialize list of posible video modes. + */ +void +tt_probe_video(modelp) +MODES *modelp; +{ + dmode_t *dm; + int i; + int has_mono; + + /* + * First find out what kind of monitor is attached. Dma-sound + * should be off because the 'sound-done' and 'monochrome-detect' + * are xor-ed together. I think that shutting it down here is the + * wrong place. + */ + has_mono = (MFP->mf_gpip & IA_MONO) == 0; + + for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) { + if (has_mono && (dm->vm_reg != RES_TTHIGH)) + continue; + if (!has_mono && (dm->vm_reg == RES_TTHIGH)) + continue; + LIST_INSERT_HEAD(modelp, dm, link); + } + + for (i=0; i < 16; i++) + VIDEO->vd_tt_rgb[i] = CM_L2TT(gra_def_color16[i]); +} + +static void +tt_display_view(v) +view_t *v; +{ + dmode_t *dm = v->mode; + bmap_t *bm = v->bitmap; + + if (dm->current_view) { + /* + * Mark current view for this mode as no longer displayed + */ + dm->current_view->flags &= ~VF_DISPLAY; + } + dm->current_view = v; + v->flags |= VF_DISPLAY; + + tt_use_colormap(v, v->colormap); + + /* XXX: should use vbl for this */ + VIDEO->vd_tt_res = dm->vm_reg; + VIDEO->vd_raml = (u_long)bm->hw_address & 0xff; + VIDEO->vd_ramm = ((u_long)bm->hw_address >> 8) & 0xff; + VIDEO->vd_ramh = ((u_long)bm->hw_address >> 16) & 0xff; +} + +void +tt_remove_view(v) +view_t *v; +{ + dmode_t *mode = v->mode; + + if (mode->current_view == v) { +#if 0 + if (v->flags & VF_DISPLAY) + panic("Cannot shutdown display\n"); /* XXX */ +#endif + mode->current_view = NULL; + } + v->flags &= ~VF_DISPLAY; +} + +void +tt_free_view(v) +view_t *v; +{ + if(v) { + dmode_t *md = v->mode; + + tt_remove_view(v); + if (v->colormap != &gra_con_cmap) + free(v->colormap, M_DEVBUF); + free_bitmap(v->bitmap); + if (v != &gra_con_view) + free(v, M_DEVBUF); + } +} + +static int +tt_use_colormap(v, cm) +view_t *v; +colormap_t *cm; +{ + dmode_t *dm; + volatile u_short *creg; + u_long *src; + colormap_t *vcm; + u_long *vcreg; + u_short ncreg; + int i; + + dm = v->mode; + vcm = v->colormap; + + /* + * I guess it seems reasonable to require the maps to be + * of the same type... + */ + if (cm->type != vcm->type) + return(EINVAL); + + /* + * First figure out where the actual colormap resides and + * howmany colors are in it. + */ + switch (dm->vm_reg) { + case RES_STLOW: + creg = &VIDEO->vd_tt_rgb[0]; + ncreg = 16; + break; + case RES_STMID: + creg = &VIDEO->vd_tt_rgb[0]; + ncreg = 4; + break; + case RES_STHIGH: + creg = &VIDEO->vd_tt_rgb[254]; + ncreg = 2; + break; + case RES_TTLOW: + creg = &VIDEO->vd_tt_rgb[0]; + ncreg = 256; + break; + case RES_TTMID: + creg = &VIDEO->vd_tt_rgb[0]; + ncreg = 16; + break; + case RES_TTHIGH: + return(0); /* No colors */ + default: + panic("grf_tt:use_colormap: wrong mode!?"); + } + + /* If first entry specified beyond capabilities -> error */ + if (cm->first >= ncreg) + return(EINVAL); + + /* + * A little tricky, the actual colormap pointer will be NULL + * when view is not displaying, valid otherwise. + */ + if (v->flags & VF_DISPLAY) + creg = &creg[cm->first]; + else creg = NULL; + + vcreg = &vcm->entry[cm->first]; + ncreg -= cm->first; + if (cm->size > ncreg) + return(EINVAL); + ncreg = cm->size; + + for (i = 0, src = cm->entry; i < ncreg; i++, vcreg++) { + *vcreg = *src++; + + /* + * If displaying, also update actual color registers. + */ + if (creg != NULL) + *creg++ = CM_L2TT(*vcreg); + } + return (0); +} + +static view_t * +tt_alloc_view(mode, dim, depth) +dmode_t *mode; +dimen_t *dim; +u_char depth; +{ + view_t *v; + bmap_t *bm; + + if (!atari_realconfig) + v = &gra_con_view; + else v = malloc(sizeof(*v), M_DEVBUF, M_NOWAIT); + if(v == NULL) + return (NULL); + + bm = alloc_bitmap(mode->size.width, mode->size.height, mode->depth); + if (bm) { + box_t box; + + v->colormap = alloc_colormap(mode); + if (v->colormap) { + INIT_BOX(&box,0,0,mode->size.width,mode->size.height); + init_view(v, bm, mode, &box); + return (v); + } + free_bitmap(bm); + } + if (v != &gra_con_view) + free(v, M_DEVBUF); + return (NULL); +} + +static void +init_view(v, bm, mode, dbox) +view_t *v; +bmap_t *bm; +dmode_t *mode; +box_t *dbox; +{ + v->bitmap = bm; + v->mode = mode; + v->flags = 0; + bcopy(dbox, &v->display, sizeof(box_t)); +} + +/* bitmap functions */ + +static bmap_t * +alloc_bitmap(width, height, depth) +u_long width, height; +u_char depth; +{ + int i; + u_long total_size, bm_size; + void *hw_address; + bmap_t *bm; + + /* + * Sigh, it seems for mapping to work we need the bitplane data to + * 1: be aligned on a page boundry. + * 2: be n pages large. + * + * why? because the user gets a page aligned address, if this is before + * your allocation, too bad. Also it seems that the mapping routines + * do not watch to closely to the allowable length. so if you go over + * n pages by less than another page, the user gets to write all over + * the entire page. Since you did not allocate up to a page boundry + * (or more) the user writes into someone elses memory. -ch + */ + bm_size = atari_round_page((width * height * depth) / NBBY); + total_size = bm_size + sizeof(bmap_t) + NBPG; + + if ((bm = (bmap_t*)alloc_stmem(total_size, &hw_address)) == NULL) + return(NULL); + + bm->plane = (u_char*)bm + sizeof(bmap_t); + bm->plane = (u_char*)atari_round_page(bm->plane); + bm->hw_address = (u_char*)hw_address + sizeof(bmap_t); + bm->hw_address = (u_char*)atari_round_page(bm->hw_address); + bm->bytes_per_row = (width * depth) / NBBY; + bm->rows = height; + bm->depth = depth; + + bzero(bm->plane, bm_size); + return (bm); +} + +static void +free_bitmap(bm) +bmap_t *bm; +{ + if (bm) + free_stmem(bm); +} + +static colormap_t * +alloc_colormap(dm) +dmode_t *dm; +{ + int nentries, i; + colormap_t *cm; + u_char type = CM_COLOR; + + switch (dm->vm_reg) { + case RES_STLOW: + case RES_TTMID: + nentries = 16; + break; + case RES_STMID: + nentries = 4; + break; + case RES_STHIGH: + nentries = 2; + break; + case RES_TTLOW: + nentries = 256; + break; + case RES_TTHIGH: + type = CM_MONO; + nentries = 0; + break; + default: + panic("grf_tt:alloc_colormap: wrong mode!?"); + } + if (!atari_realconfig) { + cm = &gra_con_cmap; + cm->entry = gra_con_colors; + } + else { + int size; + + size = sizeof(*cm) + (nentries * sizeof(cm->entry[0])); + cm = malloc(size, M_DEVBUF, M_NOWAIT); + if (cm == NULL) + return (NULL); + cm->entry = (long *)&cm[1]; + + } + if ((cm->type = type) == CM_COLOR) + cm->red_mask = cm->green_mask = cm->blue_mask = 0xf; + cm->first = 0; + cm->size = nentries; + + for (i = 0; i < nentries; i++) + cm->entry[i] = gra_def_color16[i % 16]; + return (cm); +} +#endif /* TT_VIDEO */