1 1.41 thorpej /* $NetBSD: grf_et.c,v 1.41 2023/12/20 00:40:42 thorpej Exp $ */ 2 1.1 veego 3 1.1 veego /* 4 1.9 veego * Copyright (c) 1997 Klaus Burkert 5 1.1 veego * Copyright (c) 1996 Tobias Abt 6 1.1 veego * Copyright (c) 1995 Ezra Story 7 1.1 veego * Copyright (c) 1995 Kari Mettinen 8 1.1 veego * Copyright (c) 1994 Markus Wild 9 1.1 veego * Copyright (c) 1994 Lutz Vieweg 10 1.1 veego * All rights reserved. 11 1.1 veego * 12 1.1 veego * Redistribution and use in source and binary forms, with or without 13 1.1 veego * modification, are permitted provided that the following conditions 14 1.1 veego * are met: 15 1.1 veego * 1. Redistributions of source code must retain the above copyright 16 1.1 veego * notice, this list of conditions and the following disclaimer. 17 1.1 veego * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 veego * notice, this list of conditions and the following disclaimer in the 19 1.1 veego * documentation and/or other materials provided with the distribution. 20 1.1 veego * 3. All advertising materials mentioning features or use of this software 21 1.1 veego * must display the following acknowledgement: 22 1.1 veego * This product includes software developed by Lutz Vieweg. 23 1.1 veego * 4. The name of the author may not be used to endorse or promote products 24 1.1 veego * derived from this software without specific prior written permission 25 1.1 veego * 26 1.1 veego * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 1.1 veego * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 1.1 veego * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 1.1 veego * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 1.1 veego * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 1.1 veego * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 1.1 veego * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 1.1 veego * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 1.1 veego * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 1.1 veego * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 1.1 veego */ 37 1.12 is #include "opt_amigacons.h" 38 1.14 aymeric 39 1.14 aymeric #include <sys/cdefs.h> 40 1.41 thorpej __KERNEL_RCSID(0, "$NetBSD: grf_et.c,v 1.41 2023/12/20 00:40:42 thorpej Exp $"); 41 1.14 aymeric 42 1.1 veego #include "grfet.h" 43 1.29 phx #include "ite.h" 44 1.33 phx #include "wsdisplay.h" 45 1.1 veego #if NGRFET > 0 46 1.1 veego 47 1.1 veego /* 48 1.1 veego * Graphics routines for Tseng ET4000 (&W32) boards, 49 1.1 veego * 50 1.1 veego * This code offers low-level routines to access Tseng ET4000 51 1.1 veego * graphics-boards from within NetBSD for the Amiga. 52 1.1 veego * No warranties for any kind of function at all - this 53 1.1 veego * code may crash your hardware and scratch your harddisk. Use at your 54 1.1 veego * own risk. Freely distributable. 55 1.1 veego * 56 1.1 veego * Modified for Tseng ET4000 from 57 1.1 veego * Kari Mettinen's Cirrus driver by Tobias Abt 58 1.1 veego * 59 1.9 veego * Fixed Merlin in Z-III, fixed LACE and DBLSCAN, added Domino16M proto 60 1.13 aymeric * and AT&T ATT20c491 DAC, added memory-size detection by Klaus Burkert. 61 1.13 aymeric * 62 1.1 veego * 63 1.1 veego * TODO: 64 1.1 veego * 65 1.1 veego */ 66 1.1 veego 67 1.1 veego #include <sys/param.h> 68 1.1 veego #include <sys/systm.h> 69 1.1 veego #include <sys/errno.h> 70 1.1 veego #include <sys/ioctl.h> 71 1.1 veego #include <sys/device.h> 72 1.40 riastrad #include <sys/device_impl.h> /* XXX autoconf abuse */ 73 1.1 veego 74 1.1 veego #include <machine/cpu.h> 75 1.1 veego #include <dev/cons.h> 76 1.33 phx #if NWSDISPLAY > 0 77 1.33 phx #include <dev/wscons/wsconsio.h> 78 1.33 phx #include <dev/wscons/wsdisplayvar.h> 79 1.33 phx #include <dev/rasops/rasops.h> 80 1.33 phx #include <dev/wscons/wsdisplay_vconsvar.h> 81 1.33 phx #endif 82 1.1 veego #ifdef TSENGCONSOLE 83 1.1 veego #include <amiga/dev/itevar.h> 84 1.1 veego #endif 85 1.1 veego #include <amiga/amiga/device.h> 86 1.1 veego #include <amiga/dev/grfioctl.h> 87 1.1 veego #include <amiga/dev/grfvar.h> 88 1.1 veego #include <amiga/dev/grf_etreg.h> 89 1.1 veego #include <amiga/dev/zbusvar.h> 90 1.1 veego 91 1.33 phx int et_mondefok(struct grfvideo_mode *); 92 1.33 phx void et_boardinit(struct grf_softc *); 93 1.33 phx static void et_CompFQ(u_int fq, u_char *, u_char *); 94 1.33 phx int et_getvmode(struct grf_softc *, struct grfvideo_mode *); 95 1.33 phx int et_setvmode(struct grf_softc *, unsigned int); 96 1.33 phx int et_toggle(struct grf_softc *, unsigned short); 97 1.33 phx int et_getcmap(struct grf_softc *, struct grf_colormap *); 98 1.33 phx int et_putcmap(struct grf_softc *, struct grf_colormap *); 99 1.1 veego #ifndef TSENGCONSOLE 100 1.33 phx void et_off(struct grf_softc *); 101 1.1 veego #endif 102 1.33 phx void et_inittextmode(struct grf_softc *); 103 1.33 phx int et_ioctl(register struct grf_softc *, u_long cmd, void *); 104 1.33 phx int et_getmousepos(struct grf_softc *, struct grf_position *); 105 1.33 phx void et_writesprpos(volatile char *ba, short, short); 106 1.33 phx int et_setmousepos(struct grf_softc *, struct grf_position *); 107 1.33 phx static int et_setspriteinfo(struct grf_softc *, struct grf_spriteinfo *); 108 1.33 phx int et_getspriteinfo(struct grf_softc *, struct grf_spriteinfo *); 109 1.33 phx static int et_getspritemax(struct grf_softc *, struct grf_position *); 110 1.33 phx int et_setmonitor(struct grf_softc *, struct grfvideo_mode *); 111 1.33 phx int et_blank(struct grf_softc *, int); 112 1.33 phx int et_isblank(struct grf_softc *); 113 1.33 phx static int et_getControllerType(struct grf_softc *); 114 1.33 phx static int et_getDACType(struct grf_softc *); 115 1.13 aymeric 116 1.30 chs int grfetmatch(device_t, cfdata_t, void *); 117 1.30 chs void grfetattach(device_t, device_t, void *); 118 1.13 aymeric int grfetprint(void *, const char *); 119 1.33 phx void et_memset(volatile unsigned char *, unsigned char, int); 120 1.33 phx 121 1.33 phx #if NWSDISPLAY > 0 122 1.33 phx /* wsdisplay acessops, emulops */ 123 1.33 phx static int et_wsioctl(void *, void *, u_long, void *, int, struct lwp *); 124 1.33 phx static int et_get_fbinfo(struct grf_softc *, struct wsdisplayio_fbinfo *); 125 1.33 phx 126 1.33 phx static void et_wscursor(void *, int, int, int); 127 1.33 phx static void et_wsputchar(void *, int, int, u_int, long); 128 1.33 phx static void et_wscopycols(void *, int, int, int, int); 129 1.33 phx static void et_wserasecols(void *, int, int, int, long); 130 1.33 phx static void et_wscopyrows(void *, int, int, int); 131 1.33 phx static void et_wseraserows(void *, int, int, long); 132 1.33 phx static int et_wsallocattr(void *, int, int, int, long *); 133 1.33 phx static int et_wsmapchar(void *, int, unsigned int *); 134 1.33 phx #endif /* NWSDISPLAY > 0 */ 135 1.1 veego 136 1.3 veego /* 137 1.3 veego * Graphics display definitions. 138 1.1 veego * These are filled by 'grfconfig' using GRFIOCSETMON. 139 1.1 veego */ 140 1.10 veego #define monitor_def_max 24 141 1.10 veego static struct grfvideo_mode monitor_def[24] = { 142 1.10 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, 143 1.10 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, 144 1.1 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} 145 1.1 veego }; 146 1.1 veego static struct grfvideo_mode *monitor_current = &monitor_def[0]; 147 1.1 veego 148 1.1 veego /* Console display definition. 149 1.1 veego * Default hardcoded text mode. This grf_et is set up to 150 1.1 veego * use one text mode only, and this is it. You may use 151 1.1 veego * grfconfig to change the mode after boot. 152 1.1 veego */ 153 1.1 veego /* Console font */ 154 1.1 veego #ifdef KFONT_8X11 155 1.1 veego #define TSENGFONT kernel_font_8x11 156 1.1 veego #define TSENGFONTY 11 157 1.1 veego #else 158 1.1 veego #define TSENGFONT kernel_font_8x8 159 1.1 veego #define TSENGFONTY 8 160 1.1 veego #endif 161 1.1 veego extern unsigned char TSENGFONT[]; 162 1.1 veego 163 1.1 veego struct grfettext_mode etconsole_mode = { 164 1.10 veego {255, "", 25000000, 640, 480, 4, 640/8, 680/8, 768/8, 800/8, 165 1.10 veego 481, 491, 493, 525, 0}, 166 1.1 veego 8, TSENGFONTY, 640 / 8, 480 / TSENGFONTY, TSENGFONT, 32, 255 167 1.1 veego }; 168 1.1 veego 169 1.1 veego /* Console colors */ 170 1.1 veego unsigned char etconscolors[3][3] = { /* background, foreground, hilite */ 171 1.1 veego {0, 0x40, 0x50}, {152, 152, 152}, {255, 255, 255} 172 1.1 veego }; 173 1.1 veego 174 1.1 veego int ettype = 0; /* oMniBus, Domino or Merlin */ 175 1.1 veego int etctype = 0; /* ET4000 or ETW32 */ 176 1.1 veego int etdtype = 0; /* Type of DAC (see grf_etregs.h) */ 177 1.1 veego 178 1.1 veego char etcmap_shift = 0; /* 6 or 8 bit cmap entries */ 179 1.1 veego unsigned char pass_toggle; /* passthru status tracker */ 180 1.1 veego 181 1.1 veego unsigned char Merlin_switch = 0; 182 1.1 veego 183 1.3 veego /* 184 1.3 veego * Because all Tseng-boards have 2 configdev entries, one for 185 1.1 veego * framebuffer mem and the other for regs, we have to hold onto 186 1.1 veego * the pointers globally until we match on both. This and 'ettype' 187 1.1 veego * are the primary obsticles to multiple board support, but if you 188 1.1 veego * have multiple boards you have bigger problems than grf_et. 189 1.1 veego */ 190 1.1 veego static void *et_fbaddr = 0; /* framebuffer */ 191 1.1 veego static void *et_regaddr = 0; /* registers */ 192 1.1 veego static int et_fbsize; /* framebuffer size */ 193 1.1 veego 194 1.1 veego /* current sprite info, if you add support for multiple boards 195 1.1 veego * make this an array or something 196 1.1 veego */ 197 1.1 veego struct grf_spriteinfo et_cursprite; 198 1.1 veego 199 1.1 veego /* sprite bitmaps in kernel stack, you'll need to arrayize these too if 200 1.1 veego * you add multiple board support 201 1.1 veego */ 202 1.1 veego static unsigned char et_imageptr[8 * 64], et_maskptr[8 * 64]; 203 1.1 veego static unsigned char et_sprred[2], et_sprgreen[2], et_sprblue[2]; 204 1.1 veego 205 1.33 phx #if NWSDISPLAY > 0 206 1.33 phx static struct wsdisplay_accessops et_accessops = { 207 1.33 phx .ioctl = et_wsioctl, 208 1.33 phx .mmap = grf_wsmmap 209 1.33 phx }; 210 1.33 phx 211 1.33 phx static struct wsdisplay_emulops et_textops = { 212 1.33 phx .cursor = et_wscursor, 213 1.33 phx .mapchar = et_wsmapchar, 214 1.33 phx .putchar = et_wsputchar, 215 1.33 phx .copycols = et_wscopycols, 216 1.33 phx .erasecols = et_wserasecols, 217 1.33 phx .copyrows = et_wscopyrows, 218 1.33 phx .eraserows = et_wseraserows, 219 1.33 phx .allocattr = et_wsallocattr 220 1.33 phx }; 221 1.33 phx 222 1.33 phx static struct wsscreen_descr et_defaultscreen = { 223 1.33 phx .name = "default", 224 1.33 phx .textops = &et_textops, 225 1.33 phx .fontwidth = 8, 226 1.33 phx .fontheight = TSENGFONTY, 227 1.33 phx .capabilities = WSSCREEN_HILIT | WSSCREEN_BLINK | 228 1.33 phx WSSCREEN_REVERSE | WSSCREEN_UNDERLINE 229 1.33 phx }; 230 1.33 phx 231 1.33 phx static const struct wsscreen_descr *et_screens[] = { 232 1.33 phx &et_defaultscreen, 233 1.33 phx }; 234 1.33 phx 235 1.33 phx static struct wsscreen_list et_screenlist = { 236 1.33 phx sizeof(et_screens) / sizeof(struct wsscreen_descr *), et_screens 237 1.33 phx }; 238 1.33 phx #endif /* NWSDISPLAY > 0 */ 239 1.33 phx 240 1.1 veego /* standard driver stuff */ 241 1.30 chs CFATTACH_DECL_NEW(grfet, sizeof(struct grf_softc), 242 1.18 thorpej grfetmatch, grfetattach, NULL, NULL); 243 1.3 veego 244 1.1 veego static struct cfdata *cfdata; 245 1.1 veego 246 1.1 veego int 247 1.30 chs grfetmatch(device_t parent, cfdata_t cf, void *aux) 248 1.1 veego { 249 1.1 veego struct zbus_args *zap; 250 1.9 veego static int regprod, regprod2 = 0, fbprod; 251 1.1 veego 252 1.30 chs zap = aux; 253 1.1 veego 254 1.1 veego #ifndef TSENGCONSOLE 255 1.1 veego if (amiga_realconfig == 0) 256 1.1 veego return (0); 257 1.1 veego #endif 258 1.1 veego 259 1.1 veego /* Grab the first board we encounter as the preferred one. This will 260 1.1 veego * allow one board to work in a multiple Tseng board system, but not 261 1.1 veego * multiple boards at the same time. */ 262 1.1 veego if (ettype == 0) { 263 1.1 veego switch (zap->manid) { 264 1.1 veego case OMNIBUS: 265 1.1 veego if (zap->prodid != 0) 266 1.1 veego return (0); 267 1.1 veego regprod = 0; 268 1.1 veego fbprod = 0; 269 1.1 veego break; 270 1.1 veego case DOMINO: 271 1.9 veego /* 2167/3 is Domino16M proto (crest) */ 272 1.9 veego if (zap->prodid != 3 && zap->prodid != 2 && zap->prodid != 1) 273 1.1 veego return (0); 274 1.1 veego regprod = 2; 275 1.9 veego regprod2 = 3; 276 1.1 veego fbprod = 1; 277 1.1 veego break; 278 1.1 veego case MERLIN: 279 1.1 veego if (zap->prodid != 3 && zap->prodid != 4) 280 1.1 veego return (0); 281 1.1 veego regprod = 4; 282 1.1 veego fbprod = 3; 283 1.1 veego break; 284 1.1 veego default: 285 1.1 veego return (0); 286 1.1 veego } 287 1.1 veego ettype = zap->manid; 288 1.1 veego } else { 289 1.1 veego if (ettype != zap->manid) { 290 1.1 veego return (0); 291 1.1 veego } 292 1.1 veego } 293 1.1 veego 294 1.1 veego /* Configure either registers or framebuffer in any order */ 295 1.1 veego /* as said before, oMniBus does not support ProdID */ 296 1.1 veego if (ettype == OMNIBUS) { 297 1.1 veego if (zap->size == 64 * 1024) { 298 1.1 veego /* register area */ 299 1.1 veego et_regaddr = zap->va; 300 1.1 veego } else { 301 1.1 veego /* memory area */ 302 1.1 veego et_fbaddr = zap->va; 303 1.1 veego et_fbsize = zap->size; 304 1.1 veego } 305 1.1 veego } else { 306 1.9 veego if (zap->prodid == regprod || zap->prodid == regprod2) { 307 1.1 veego et_regaddr = zap->va; 308 1.1 veego } else { 309 1.1 veego if (zap->prodid == fbprod) { 310 1.1 veego et_fbaddr = zap->va; 311 1.1 veego et_fbsize = zap->size; 312 1.1 veego } else { 313 1.1 veego return (0); 314 1.1 veego } 315 1.1 veego } 316 1.1 veego } 317 1.1 veego 318 1.1 veego #ifdef TSENGCONSOLE 319 1.1 veego if (amiga_realconfig == 0) { 320 1.30 chs cfdata = cf; 321 1.1 veego } 322 1.1 veego #endif 323 1.1 veego 324 1.1 veego return (1); 325 1.1 veego } 326 1.1 veego 327 1.1 veego 328 1.1 veego void 329 1.30 chs grfetattach(device_t parent, device_t self, void *aux) 330 1.1 veego { 331 1.1 veego static struct grf_softc congrf; 332 1.30 chs static char attachflag = 0; 333 1.30 chs struct device temp; 334 1.1 veego struct grf_softc *gp; 335 1.1 veego 336 1.7 christos printf("\n"); 337 1.1 veego 338 1.1 veego /* make sure both halves have matched */ 339 1.1 veego if (!et_regaddr || !et_fbaddr) 340 1.1 veego return; 341 1.1 veego 342 1.1 veego /* do all that messy console/grf stuff */ 343 1.30 chs if (self == NULL) { 344 1.1 veego gp = &congrf; 345 1.30 chs gp->g_device = &temp; 346 1.30 chs temp.dv_private = gp; 347 1.30 chs } else { 348 1.30 chs gp = device_private(self); 349 1.30 chs gp->g_device = self; 350 1.30 chs } 351 1.1 veego 352 1.30 chs if (self != NULL && congrf.g_regkva != 0) { 353 1.1 veego /* 354 1.1 veego * inited earlier, just copy (not device struct) 355 1.1 veego */ 356 1.28 cegger memcpy(&gp->g_display, &congrf.g_display, 357 1.1 veego (char *) &gp[1] - (char *) &gp->g_display); 358 1.1 veego } else { 359 1.23 christos gp->g_regkva = (volatile void *) et_regaddr; 360 1.23 christos gp->g_fbkva = (volatile void *) et_fbaddr; 361 1.1 veego 362 1.1 veego gp->g_unit = GRF_ET4000_UNIT; 363 1.1 veego gp->g_mode = et_mode; 364 1.29 phx #if NITE > 0 365 1.1 veego gp->g_conpri = grfet_cnprobe(); 366 1.29 phx #endif 367 1.1 veego gp->g_flags = GF_ALIVE; 368 1.1 veego 369 1.1 veego /* wakeup the board */ 370 1.1 veego et_boardinit(gp); 371 1.1 veego 372 1.1 veego #ifdef TSENGCONSOLE 373 1.33 phx #if NWSDISPLAY > 0 374 1.33 phx gp->g_accessops = &et_accessops; 375 1.33 phx gp->g_emulops = &et_textops; 376 1.33 phx gp->g_defaultscr = &et_defaultscreen; 377 1.33 phx gp->g_scrlist = &et_screenlist; 378 1.33 phx #else 379 1.29 phx #if NITE > 0 380 1.1 veego grfet_iteinit(gp); 381 1.29 phx #endif 382 1.33 phx #endif /* NWSDISPLAY > 0 */ 383 1.1 veego (void) et_load_mon(gp, &etconsole_mode); 384 1.1 veego #endif 385 1.1 veego } 386 1.1 veego 387 1.1 veego /* 388 1.1 veego * attach grf (once) 389 1.1 veego */ 390 1.37 thorpej if (amiga_config_found(cfdata, gp->g_device, gp, grfetprint, 391 1.38 thorpej CFARGS_NONE)) { 392 1.1 veego attachflag = 1; 393 1.7 christos printf("grfet: %dMB ", et_fbsize / 0x100000); 394 1.1 veego switch (ettype) { 395 1.1 veego case OMNIBUS: 396 1.7 christos printf("oMniBus"); 397 1.1 veego break; 398 1.1 veego case DOMINO: 399 1.7 christos printf("Domino"); 400 1.1 veego break; 401 1.1 veego case MERLIN: 402 1.7 christos printf("Merlin"); 403 1.1 veego break; 404 1.1 veego } 405 1.7 christos printf(" with "); 406 1.1 veego switch (etctype) { 407 1.1 veego case ET4000: 408 1.7 christos printf("Tseng ET4000"); 409 1.1 veego break; 410 1.1 veego case ETW32: 411 1.7 christos printf("Tseng ETW32"); 412 1.1 veego break; 413 1.1 veego } 414 1.7 christos printf(" and "); 415 1.1 veego switch (etdtype) { 416 1.1 veego case SIERRA11483: 417 1.7 christos printf("Sierra SC11483 DAC"); 418 1.1 veego break; 419 1.1 veego case SIERRA15025: 420 1.7 christos printf("Sierra SC15025 DAC"); 421 1.1 veego break; 422 1.1 veego case MUSICDAC: 423 1.7 christos printf("MUSIC DAC"); 424 1.1 veego break; 425 1.1 veego case MERLINDAC: 426 1.9 veego printf("BrookTree Bt482 DAC"); 427 1.9 veego break; 428 1.9 veego case ATT20C491: 429 1.9 veego printf("AT&T ATT20c491 DAC"); 430 1.1 veego break; 431 1.1 veego } 432 1.7 christos printf(" being used\n"); 433 1.1 veego } else { 434 1.1 veego if (!attachflag) 435 1.7 christos printf("grfet unattached!!\n"); 436 1.1 veego } 437 1.1 veego } 438 1.1 veego 439 1.1 veego 440 1.1 veego int 441 1.30 chs grfetprint(void *aux, const char *pnp) 442 1.1 veego { 443 1.1 veego if (pnp) 444 1.19 thorpej aprint_normal("ite at %s: ", pnp); 445 1.1 veego return (UNCONF); 446 1.1 veego } 447 1.1 veego 448 1.1 veego 449 1.1 veego void 450 1.13 aymeric et_boardinit(struct grf_softc *gp) 451 1.1 veego { 452 1.24 he volatile unsigned char *ba = gp->g_regkva; 453 1.1 veego int x; 454 1.1 veego 455 1.1 veego /* wakeup board and flip passthru OFF */ 456 1.1 veego 457 1.1 veego RegWakeup(ba); 458 1.1 veego RegOnpass(ba); 459 1.1 veego 460 1.1 veego if (ettype == MERLIN) { 461 1.3 veego /* Merlin needs some special initialisations */ 462 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 0); 463 1.3 veego delay(20000); 464 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 8); 465 1.3 veego delay(20000); 466 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 0); 467 1.3 veego delay(20000); 468 1.3 veego vgaw(ba, MERLIN_VDAC_DATA, 1); 469 1.3 veego 470 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x00); 471 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0xff); 472 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x01); 473 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x0f); 474 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x02); 475 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x42); 476 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x03); 477 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x00); 478 1.1 veego 479 1.3 veego vgaw(ba, MERLIN_VDAC_DATA, 0); 480 1.1 veego } 481 1.1 veego 482 1.13 aymeric 483 1.1 veego /* setup initial unchanging parameters */ 484 1.1 veego 485 1.3 veego vgaw(ba, GREG_HERCULESCOMPAT + ((ettype == DOMINO) ? 0x0fff : 0), 0x03); 486 1.1 veego vgaw(ba, GREG_DISPMODECONTROL, 0xa0); 487 1.1 veego vgaw(ba, GREG_MISC_OUTPUT_W, 0x63); 488 1.1 veego 489 1.3 veego if (ettype == DOMINO) 490 1.3 veego { 491 1.3 veego vgaw(ba, CRT_ADDRESS, CRT_ID_VIDEO_CONFIG1); 492 1.3 veego vgaw(ba, CRT_ADDRESS_W + 0x0fff, 493 1.3 veego 0xc0 | vgar(ba, CRT_ADDRESS_R + 0x0fff)); 494 1.3 veego } 495 1.3 veego 496 1.1 veego WSeq(ba, SEQ_ID_RESET, 0x03); 497 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21); /* 8 dot, Display off */ 498 1.1 veego WSeq(ba, SEQ_ID_MAP_MASK, 0x0f); 499 1.1 veego WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00); 500 1.1 veego WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e); 501 1.9 veego WSeq(ba, SEQ_ID_STATE_CONTROL, 0x00); 502 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4); 503 1.1 veego 504 1.1 veego WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00); 505 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, 0x00); 506 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, 0x08); 507 1.1 veego WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00); 508 1.1 veego WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00); 509 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00); 510 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00); 511 1.1 veego 512 1.9 veego WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x67); 513 1.9 veego WCrt(ba, CRT_ID_MODE_CONTROL, 0xc3); 514 1.9 veego WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); 515 1.9 veego 516 1.9 veego /* ET4000 special */ 517 1.1 veego WCrt(ba, CRT_ID_RASCAS_CONFIG, 0x28); 518 1.9 veego WCrt(ba, CRT_ID_EXT_START, 0x00); 519 1.1 veego WCrt(ba, CRT_ID_6845_COMPAT, 0x08); 520 1.9 veego 521 1.9 veego /* ET4000/W32 special (currently only for Merlin (crest) */ 522 1.9 veego if (ettype == MERLIN) { 523 1.9 veego WCrt(ba, CRT_ID_SEGMENT_COMP, 0x1c); 524 1.9 veego WCrt(ba, CRT_ID_GENERAL_PURPOSE, 0x00); 525 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x93); 526 1.9 veego } 527 1.9 veego else { 528 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3); 529 1.3 veego } 530 1.3 veego 531 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x0f); 532 1.1 veego WCrt(ba, CRT_ID_HOR_OVERFLOW, 0x00); 533 1.1 veego 534 1.9 veego vgaw(ba, GREG_SEGMENTSELECT, 0x00); 535 1.9 veego 536 1.1 veego WGfx(ba, GCT_ID_SET_RESET, 0x00); 537 1.1 veego WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00); 538 1.1 veego WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00); 539 1.1 veego WGfx(ba, GCT_ID_DATA_ROTATE, 0x00); 540 1.1 veego WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00); 541 1.9 veego WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x40); 542 1.1 veego WGfx(ba, GCT_ID_MISC, 0x01); 543 1.1 veego WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f); 544 1.1 veego WGfx(ba, GCT_ID_BITMASK, 0xff); 545 1.1 veego 546 1.1 veego for (x = 0; x < 0x10; x++) 547 1.1 veego WAttr(ba, x, x); 548 1.1 veego WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01); 549 1.1 veego WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00); 550 1.1 veego WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f); 551 1.1 veego WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00); 552 1.1 veego WAttr(ba, ACT_ID_COLOR_SELECT, 0x00); 553 1.1 veego WAttr(ba, ACT_ID_MISCELLANEOUS, 0x00); 554 1.1 veego 555 1.1 veego vgaw(ba, VDAC_MASK, 0xff); 556 1.1 veego delay(200000); 557 1.9 veego vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3); 558 1.1 veego 559 1.1 veego /* colors initially set to greyscale */ 560 1.1 veego switch(ettype) { 561 1.1 veego case MERLIN: 562 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, 0); 563 1.1 veego for (x = 255; x >= 0; x--) { 564 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x); 565 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x); 566 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x); 567 1.1 veego } 568 1.1 veego break; 569 1.1 veego default: 570 1.1 veego vgaw(ba, VDAC_ADDRESS_W, 0); 571 1.1 veego for (x = 255; x >= 0; x--) { 572 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x); 573 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x); 574 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x); 575 1.1 veego } 576 1.1 veego break; 577 1.1 veego } 578 1.1 veego /* set sprite bitmap pointers */ 579 1.1 veego /* should work like that */ 580 1.1 veego et_cursprite.image = et_imageptr; 581 1.1 veego et_cursprite.mask = et_maskptr; 582 1.1 veego et_cursprite.cmap.red = et_sprred; 583 1.1 veego et_cursprite.cmap.green = et_sprgreen; 584 1.1 veego et_cursprite.cmap.blue = et_sprblue; 585 1.9 veego 586 1.9 veego /* card specific initialisations */ 587 1.1 veego switch(ettype) { 588 1.1 veego case OMNIBUS: 589 1.1 veego etctype = et_getControllerType(gp); 590 1.1 veego etdtype = et_getDACType(gp); 591 1.1 veego break; 592 1.1 veego case MERLIN: 593 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x00); 594 1.9 veego if (((vgar(ba, GREG_FEATURE_CONTROL_R) & 12) | 595 1.9 veego (vgar(ba, GREG_STATUS0_R) & 0x60)) == 0x24) { 596 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x07); /* 1Mx4 RAM */ 597 1.9 veego et_fbsize = 0x400000; /* 4 MB */ 598 1.9 veego } 599 1.9 veego else { 600 1.9 veego /* check for 1MB or 2MB board (crest) */ 601 1.9 veego /* has there a 1MB Merlin ever been sold ??? */ 602 1.9 veego volatile unsigned long *et_fbtestaddr; 603 1.9 veego et_fbtestaddr = (volatile unsigned long *)gp->g_fbkva; 604 1.9 veego *et_fbtestaddr = 0x0; 605 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x11); /* 1MB offset */ 606 1.9 veego *et_fbtestaddr = 0x12345678; 607 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x00); 608 1.13 aymeric if (*et_fbtestaddr == 0x0) 609 1.9 veego et_fbsize = 0x200000; /* 2 MB */ 610 1.9 veego else 611 1.9 veego et_fbsize = 0x100000; /* 1 MB */ 612 1.9 veego } 613 1.9 veego /* ZorroII can map 2 MB max ... */ 614 1.24 he if (!iszthreepa(kvtop(__UNVOLATILE(gp->g_fbkva))) && 615 1.24 he et_fbsize == 0x400000) 616 1.9 veego et_fbsize = 0x200000; 617 1.1 veego etctype = ETW32; 618 1.1 veego etdtype = MERLINDAC; 619 1.3 veego break; 620 1.1 veego case DOMINO: 621 1.1 veego etctype = ET4000; 622 1.9 veego etdtype = et_getDACType(gp); 623 1.1 veego break; 624 1.1 veego } 625 1.1 veego } 626 1.1 veego 627 1.1 veego 628 1.1 veego int 629 1.13 aymeric et_getvmode(struct grf_softc *gp, struct grfvideo_mode *vm) 630 1.1 veego { 631 1.1 veego struct grfvideo_mode *gv; 632 1.1 veego 633 1.1 veego #ifdef TSENGCONSOLE 634 1.1 veego /* Handle grabbing console mode */ 635 1.1 veego if (vm->mode_num == 255) { 636 1.28 cegger memcpy(vm, &etconsole_mode, sizeof(struct grfvideo_mode)); 637 1.9 veego /* XXX so grfconfig can tell us the correct text dimensions. */ 638 1.1 veego vm->depth = etconsole_mode.fy; 639 1.9 veego } else 640 1.1 veego #endif 641 1.3 veego { 642 1.3 veego if (vm->mode_num == 0) 643 1.3 veego vm->mode_num = (monitor_current - monitor_def) + 1; 644 1.3 veego if (vm->mode_num < 1 || vm->mode_num > monitor_def_max) 645 1.3 veego return (EINVAL); 646 1.3 veego gv = monitor_def + (vm->mode_num - 1); 647 1.3 veego if (gv->mode_num == 0) 648 1.3 veego return (EINVAL); 649 1.3 veego 650 1.28 cegger memcpy(vm, gv, sizeof(struct grfvideo_mode)); 651 1.3 veego } 652 1.3 veego 653 1.3 veego /* adjust internal values to pixel values */ 654 1.3 veego 655 1.3 veego vm->hblank_start *= 8; 656 1.3 veego vm->hsync_start *= 8; 657 1.3 veego vm->hsync_stop *= 8; 658 1.3 veego vm->htotal *= 8; 659 1.3 veego 660 1.1 veego return (0); 661 1.1 veego } 662 1.1 veego 663 1.1 veego 664 1.1 veego int 665 1.13 aymeric et_setvmode(struct grf_softc *gp, unsigned mode) 666 1.1 veego { 667 1.1 veego if (!mode || (mode > monitor_def_max) || 668 1.1 veego monitor_def[mode - 1].mode_num == 0) 669 1.1 veego return (EINVAL); 670 1.1 veego 671 1.1 veego monitor_current = monitor_def + (mode - 1); 672 1.1 veego 673 1.1 veego return (0); 674 1.1 veego } 675 1.1 veego 676 1.1 veego 677 1.1 veego #ifndef TSENGCONSOLE 678 1.1 veego void 679 1.13 aymeric et_off(struct grf_softc *gp) 680 1.1 veego { 681 1.1 veego char *ba = gp->g_regkva; 682 1.1 veego 683 1.1 veego RegOnpass(ba); 684 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21); 685 1.1 veego } 686 1.1 veego #endif 687 1.1 veego 688 1.1 veego 689 1.1 veego int 690 1.33 phx et_blank(struct grf_softc *gp, int on) 691 1.33 phx { 692 1.33 phx 693 1.33 phx WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, on > 0 ? 0x01 : 0x21); 694 1.33 phx return 0; 695 1.33 phx } 696 1.33 phx 697 1.33 phx 698 1.33 phx int 699 1.33 phx et_isblank(struct grf_softc *gp) 700 1.1 veego { 701 1.33 phx int r; 702 1.33 phx 703 1.33 phx r = RSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE); 704 1.33 phx return (r & 0x20) != 0; 705 1.1 veego } 706 1.3 veego 707 1.1 veego 708 1.1 veego /* 709 1.1 veego * Change the mode of the display. 710 1.1 veego * Return a UNIX error number or 0 for success. 711 1.1 veego */ 712 1.1 veego int 713 1.13 aymeric et_mode(register struct grf_softc *gp, u_long cmd, void *arg, u_long a2, 714 1.13 aymeric int a3) 715 1.1 veego { 716 1.3 veego int error; 717 1.1 veego 718 1.1 veego switch (cmd) { 719 1.1 veego case GM_GRFON: 720 1.1 veego error = et_load_mon(gp, 721 1.1 veego (struct grfettext_mode *) monitor_current) ? 0 : EINVAL; 722 1.1 veego return (error); 723 1.1 veego 724 1.1 veego case GM_GRFOFF: 725 1.1 veego #ifndef TSENGCONSOLE 726 1.1 veego et_off(gp); 727 1.1 veego #else 728 1.1 veego et_load_mon(gp, &etconsole_mode); 729 1.1 veego #endif 730 1.1 veego return (0); 731 1.1 veego 732 1.1 veego case GM_GRFCONFIG: 733 1.1 veego return (0); 734 1.1 veego 735 1.1 veego case GM_GRFGETVMODE: 736 1.1 veego return (et_getvmode(gp, (struct grfvideo_mode *) arg)); 737 1.1 veego 738 1.1 veego case GM_GRFSETVMODE: 739 1.1 veego error = et_setvmode(gp, *(unsigned *) arg); 740 1.1 veego if (!error && (gp->g_flags & GF_GRFON)) 741 1.1 veego et_load_mon(gp, 742 1.1 veego (struct grfettext_mode *) monitor_current); 743 1.1 veego return (error); 744 1.1 veego 745 1.1 veego case GM_GRFGETNUMVM: 746 1.1 veego *(int *) arg = monitor_def_max; 747 1.1 veego return (0); 748 1.1 veego 749 1.1 veego case GM_GRFIOCTL: 750 1.1 veego return (et_ioctl(gp, a2, arg)); 751 1.1 veego 752 1.1 veego default: 753 1.1 veego break; 754 1.1 veego } 755 1.1 veego 756 1.15 atatat return (EPASSTHROUGH); 757 1.1 veego } 758 1.1 veego 759 1.3 veego 760 1.1 veego int 761 1.13 aymeric et_ioctl(register struct grf_softc *gp, u_long cmd, void *data) 762 1.1 veego { 763 1.1 veego switch (cmd) { 764 1.1 veego case GRFIOCGSPRITEPOS: 765 1.1 veego return (et_getmousepos(gp, (struct grf_position *) data)); 766 1.1 veego 767 1.1 veego case GRFIOCSSPRITEPOS: 768 1.1 veego return (et_setmousepos(gp, (struct grf_position *) data)); 769 1.1 veego 770 1.1 veego case GRFIOCSSPRITEINF: 771 1.1 veego return (et_setspriteinfo(gp, (struct grf_spriteinfo *) data)); 772 1.1 veego 773 1.1 veego case GRFIOCGSPRITEINF: 774 1.1 veego return (et_getspriteinfo(gp, (struct grf_spriteinfo *) data)); 775 1.1 veego 776 1.1 veego case GRFIOCGSPRITEMAX: 777 1.1 veego return (et_getspritemax(gp, (struct grf_position *) data)); 778 1.1 veego 779 1.1 veego case GRFIOCGETCMAP: 780 1.1 veego return (et_getcmap(gp, (struct grf_colormap *) data)); 781 1.1 veego 782 1.1 veego case GRFIOCPUTCMAP: 783 1.1 veego return (et_putcmap(gp, (struct grf_colormap *) data)); 784 1.1 veego 785 1.1 veego case GRFIOCBITBLT: 786 1.1 veego break; 787 1.1 veego 788 1.1 veego case GRFTOGGLE: 789 1.1 veego return (et_toggle(gp, 0)); 790 1.1 veego 791 1.1 veego case GRFIOCSETMON: 792 1.1 veego return (et_setmonitor(gp, (struct grfvideo_mode *) data)); 793 1.1 veego 794 1.3 veego case GRFIOCBLANK: 795 1.33 phx return (et_blank(gp, *(int *)data)); 796 1.1 veego } 797 1.15 atatat return (EPASSTHROUGH); 798 1.1 veego } 799 1.1 veego 800 1.1 veego 801 1.1 veego int 802 1.13 aymeric et_getmousepos(struct grf_softc *gp, struct grf_position *data) 803 1.1 veego { 804 1.1 veego data->x = et_cursprite.pos.x; 805 1.1 veego data->y = et_cursprite.pos.y; 806 1.3 veego 807 1.1 veego return (0); 808 1.1 veego } 809 1.1 veego 810 1.1 veego 811 1.1 veego void 812 1.13 aymeric et_writesprpos(volatile char *ba, short x, short y) 813 1.1 veego { 814 1.1 veego } 815 1.1 veego 816 1.1 veego 817 1.1 veego int 818 1.13 aymeric et_setmousepos(struct grf_softc *gp, struct grf_position *data) 819 1.1 veego { 820 1.1 veego volatile char *ba = gp->g_regkva; 821 1.32 christos short rx, ry; 822 1.1 veego 823 1.1 veego /* no movement */ 824 1.1 veego if (et_cursprite.pos.x == data->x && et_cursprite.pos.y == data->y) 825 1.1 veego return (0); 826 1.1 veego 827 1.3 veego /* current and previous real coordinates */ 828 1.1 veego rx = data->x - et_cursprite.hot.x; 829 1.1 veego ry = data->y - et_cursprite.hot.y; 830 1.1 veego 831 1.3 veego /* if we are/were on an edge, create (un)shifted bitmap -- 832 1.3 veego * ripped out optimization (not extremely worthwhile, 833 1.3 veego * and kind of buggy anyhow). 834 1.3 veego */ 835 1.1 veego 836 1.3 veego /* do movement, save position */ 837 1.3 veego et_writesprpos(ba, rx < 0 ? 0 : rx, ry < 0 ? 0 : ry); 838 1.1 veego et_cursprite.pos.x = data->x; 839 1.1 veego et_cursprite.pos.y = data->y; 840 1.1 veego 841 1.1 veego return (0); 842 1.1 veego } 843 1.1 veego 844 1.1 veego 845 1.1 veego int 846 1.13 aymeric et_getspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *data) 847 1.1 veego { 848 1.1 veego 849 1.1 veego return(EINVAL); 850 1.1 veego } 851 1.1 veego 852 1.1 veego 853 1.1 veego static int 854 1.13 aymeric et_setspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *data) 855 1.1 veego { 856 1.1 veego 857 1.1 veego return(EINVAL); 858 1.1 veego } 859 1.1 veego 860 1.1 veego 861 1.1 veego static int 862 1.13 aymeric et_getspritemax(struct grf_softc *gp, struct grf_position *data) 863 1.1 veego { 864 1.1 veego 865 1.1 veego return(EINVAL); 866 1.1 veego } 867 1.1 veego 868 1.1 veego 869 1.1 veego int 870 1.13 aymeric et_setmonitor(struct grf_softc *gp, struct grfvideo_mode *gv) 871 1.1 veego { 872 1.1 veego struct grfvideo_mode *md; 873 1.1 veego 874 1.3 veego if (!et_mondefok(gv)) 875 1.3 veego return(EINVAL); 876 1.1 veego 877 1.1 veego #ifdef TSENGCONSOLE 878 1.1 veego /* handle interactive setting of console mode */ 879 1.1 veego if (gv->mode_num == 255) { 880 1.28 cegger memcpy(&etconsole_mode.gv, gv, sizeof(struct grfvideo_mode)); 881 1.3 veego etconsole_mode.gv.hblank_start /= 8; 882 1.3 veego etconsole_mode.gv.hsync_start /= 8; 883 1.3 veego etconsole_mode.gv.hsync_stop /= 8; 884 1.3 veego etconsole_mode.gv.htotal /= 8; 885 1.1 veego etconsole_mode.rows = gv->disp_height / etconsole_mode.fy; 886 1.1 veego etconsole_mode.cols = gv->disp_width / etconsole_mode.fx; 887 1.1 veego if (!(gp->g_flags & GF_GRFON)) 888 1.1 veego et_load_mon(gp, &etconsole_mode); 889 1.29 phx #if NITE > 0 890 1.1 veego ite_reinit(gp->g_itedev); 891 1.29 phx #endif 892 1.1 veego return (0); 893 1.1 veego } 894 1.1 veego #endif 895 1.1 veego 896 1.1 veego md = monitor_def + (gv->mode_num - 1); 897 1.28 cegger memcpy(md, gv, sizeof(struct grfvideo_mode)); 898 1.1 veego 899 1.3 veego /* adjust pixel oriented values to internal rep. */ 900 1.1 veego 901 1.3 veego md->hblank_start /= 8; 902 1.3 veego md->hsync_start /= 8; 903 1.3 veego md->hsync_stop /= 8; 904 1.3 veego md->htotal /= 8; 905 1.1 veego 906 1.1 veego return (0); 907 1.1 veego } 908 1.1 veego 909 1.1 veego 910 1.1 veego int 911 1.13 aymeric et_getcmap(struct grf_softc *gfp, struct grf_colormap *cmap) 912 1.1 veego { 913 1.1 veego volatile unsigned char *ba; 914 1.3 veego u_char red[256], green[256], blue[256], *rp, *gp, *bp; 915 1.3 veego short x; 916 1.3 veego int error; 917 1.1 veego 918 1.1 veego if (cmap->count == 0 || cmap->index >= 256) 919 1.1 veego return 0; 920 1.1 veego 921 1.16 itojun if (cmap->count > 256 - cmap->index) 922 1.1 veego cmap->count = 256 - cmap->index; 923 1.1 veego 924 1.1 veego ba = gfp->g_regkva; 925 1.1 veego /* first read colors out of the chip, then copyout to userspace */ 926 1.1 veego x = cmap->count - 1; 927 1.1 veego 928 1.1 veego rp = red + cmap->index; 929 1.1 veego gp = green + cmap->index; 930 1.1 veego bp = blue + cmap->index; 931 1.1 veego 932 1.1 veego switch(ettype) { 933 1.1 veego case MERLIN: 934 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, cmap->index); 935 1.1 veego do { 936 1.1 veego *rp++ = vgar(ba, MERLIN_VDAC_COLORS); 937 1.1 veego *gp++ = vgar(ba, MERLIN_VDAC_COLORS); 938 1.1 veego *bp++ = vgar(ba, MERLIN_VDAC_COLORS); 939 1.1 veego } while (x-- > 0); 940 1.1 veego break; 941 1.1 veego default: 942 1.3 veego vgaw(ba, VDAC_ADDRESS_R+((ettype==DOMINO)?0x0fff:0), cmap->index); 943 1.1 veego do { 944 1.3 veego *rp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift; 945 1.3 veego *gp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift; 946 1.3 veego *bp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift; 947 1.1 veego } while (x-- > 0); 948 1.1 veego break; 949 1.1 veego } 950 1.1 veego 951 1.3 veego error = copyout(red + cmap->index, cmap->red, cmap->count); 952 1.3 veego if (!error) 953 1.3 veego error = copyout(green + cmap->index, cmap->green, cmap->count); 954 1.3 veego if (!error) 955 1.3 veego error = copyout(blue + cmap->index, cmap->blue, cmap->count); 956 1.1 veego 957 1.1 veego return (error); 958 1.1 veego } 959 1.1 veego 960 1.1 veego 961 1.1 veego int 962 1.13 aymeric et_putcmap(struct grf_softc *gfp, struct grf_colormap *cmap) 963 1.1 veego { 964 1.1 veego volatile unsigned char *ba; 965 1.3 veego u_char red[256], green[256], blue[256], *rp, *gp, *bp; 966 1.3 veego short x; 967 1.3 veego int error; 968 1.1 veego 969 1.1 veego if (cmap->count == 0 || cmap->index >= 256) 970 1.1 veego return (0); 971 1.1 veego 972 1.16 itojun if (cmap->count > 256 - cmap->index) 973 1.1 veego cmap->count = 256 - cmap->index; 974 1.1 veego 975 1.1 veego /* first copy the colors into kernelspace */ 976 1.3 veego if ((error = copyin(cmap->red, red + cmap->index, cmap->count))) 977 1.3 veego return (error); 978 1.3 veego 979 1.3 veego if ((error = copyin(cmap->green, green + cmap->index, cmap->count))) 980 1.3 veego return (error); 981 1.1 veego 982 1.3 veego if ((error = copyin(cmap->blue, blue + cmap->index, cmap->count))) 983 1.1 veego return (error); 984 1.3 veego 985 1.3 veego ba = gfp->g_regkva; 986 1.3 veego x = cmap->count - 1; 987 1.3 veego 988 1.3 veego rp = red + cmap->index; 989 1.3 veego gp = green + cmap->index; 990 1.3 veego bp = blue + cmap->index; 991 1.3 veego 992 1.3 veego switch(ettype){ 993 1.3 veego case MERLIN: 994 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, cmap->index); 995 1.3 veego do { 996 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *rp++); 997 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *gp++); 998 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *bp++); 999 1.3 veego } while (x-- > 0); 1000 1.3 veego break; 1001 1.3 veego default: 1002 1.3 veego vgaw(ba, VDAC_ADDRESS_W, cmap->index); 1003 1.3 veego do { 1004 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), 1005 1.3 veego *rp++ >> etcmap_shift); 1006 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), 1007 1.3 veego *gp++ >> etcmap_shift); 1008 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), 1009 1.3 veego *bp++ >> etcmap_shift); 1010 1.3 veego } while (x-- > 0); 1011 1.3 veego break; 1012 1.3 veego } 1013 1.3 veego 1014 1.3 veego return (0); 1015 1.1 veego } 1016 1.1 veego 1017 1.1 veego 1018 1.1 veego int 1019 1.13 aymeric et_toggle(struct grf_softc *gp, unsigned short wopp) 1020 1.13 aymeric /* (variable wopp) don't need that one yet, ill */ 1021 1.1 veego { 1022 1.1 veego volatile unsigned char *ba; 1023 1.1 veego 1024 1.1 veego ba = gp->g_regkva; 1025 1.1 veego 1026 1.1 veego if (pass_toggle) { 1027 1.1 veego RegOffpass(ba); 1028 1.1 veego } else { 1029 1.1 veego RegOnpass(ba); 1030 1.1 veego } 1031 1.1 veego return (0); 1032 1.1 veego } 1033 1.1 veego 1034 1.3 veego 1035 1.1 veego #define ET_NUMCLOCKS 32 1036 1.1 veego 1037 1.1 veego static u_char et_clocks[ET_NUMCLOCKS] = { 1038 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5, 1039 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5, 1040 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5, 1041 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5 1042 1.1 veego }; 1043 1.1 veego 1044 1.1 veego static u_char et_clockdividers[ET_NUMCLOCKS] = { 1045 1.1 veego 3, 3, 3, 3, 3, 3, 3, 3, 1046 1.1 veego 2, 2, 2, 2, 2, 2, 2, 2, 1047 1.1 veego 1, 1, 1, 1, 1, 1, 1, 1, 1048 1.1 veego 0, 0, 0, 0, 0, 0, 0, 0 1049 1.1 veego }; 1050 1.1 veego 1051 1.1 veego static u_int et_clockfreqs[ET_NUMCLOCKS] = { 1052 1.3 veego 6293750, 7080500, 7875000, 8125000, 1053 1.3 veego 9000000, 9375000, 10000000, 11225000, 1054 1.3 veego 12587500, 14161000, 15750000, 16250000, 1055 1.3 veego 18000000, 18750000, 20000000, 22450000, 1056 1.3 veego 25175000, 28322000, 31500000, 32500000, 1057 1.3 veego 36000000, 37500000, 40000000, 44900000, 1058 1.3 veego 50350000, 56644000, 63000000, 65000000, 1059 1.3 veego 72000000, 75000000, 80000000, 89800000 1060 1.1 veego }; 1061 1.1 veego 1062 1.1 veego 1063 1.1 veego static void 1064 1.13 aymeric et_CompFQ(u_int fq, u_char *num, u_char *denom) 1065 1.1 veego { 1066 1.1 veego int i; 1067 1.1 veego 1068 1.1 veego for (i=0; i < ET_NUMCLOCKS;) { 1069 1.1 veego if (fq <= et_clockfreqs[i++]) { 1070 1.1 veego break; 1071 1.1 veego } 1072 1.3 veego } 1073 1.1 veego 1074 1.1 veego *num = et_clocks[--i]; 1075 1.1 veego *denom = et_clockdividers[i]; 1076 1.1 veego 1077 1.1 veego return; 1078 1.1 veego } 1079 1.1 veego 1080 1.1 veego 1081 1.1 veego int 1082 1.13 aymeric et_mondefok(struct grfvideo_mode *gv) 1083 1.1 veego { 1084 1.9 veego unsigned long maxpix; 1085 1.3 veego 1086 1.1 veego if (gv->mode_num < 1 || gv->mode_num > monitor_def_max) 1087 1.3 veego if (gv->mode_num != 255 || gv->depth != 4) 1088 1.3 veego return(0); 1089 1.1 veego 1090 1.1 veego switch (gv->depth) { 1091 1.1 veego case 4: 1092 1.3 veego if (gv->mode_num != 255) 1093 1.3 veego return(0); 1094 1.1 veego case 1: 1095 1.1 veego case 8: 1096 1.9 veego maxpix = 85000000; 1097 1.9 veego break; 1098 1.1 veego case 15: 1099 1.1 veego case 16: 1100 1.9 veego maxpix = 45000000; 1101 1.9 veego break; 1102 1.1 veego case 24: 1103 1.9 veego maxpix = 28000000; 1104 1.9 veego break; 1105 1.9 veego case 32: 1106 1.9 veego maxpix = 21000000; 1107 1.9 veego break; 1108 1.1 veego default: 1109 1.10 veego printf("grfet: Illegal depth in mode %d\n", 1110 1.10 veego (int) gv->mode_num); 1111 1.1 veego return (0); 1112 1.1 veego } 1113 1.10 veego 1114 1.10 veego if (gv->pixel_clock > maxpix) { 1115 1.10 veego printf("grfet: Pixelclock too high in mode %d\n", 1116 1.10 veego (int) gv->mode_num); 1117 1.9 veego return (0); 1118 1.10 veego } 1119 1.10 veego 1120 1.10 veego if (gv->disp_flags & GRF_FLAGS_SYNC_ON_GREEN) { 1121 1.10 veego printf("grfet: sync-on-green is not supported\n"); 1122 1.10 veego return (0); 1123 1.10 veego } 1124 1.10 veego 1125 1.3 veego return (1); 1126 1.1 veego } 1127 1.1 veego 1128 1.1 veego 1129 1.1 veego int 1130 1.13 aymeric et_load_mon(struct grf_softc *gp, struct grfettext_mode *md) 1131 1.1 veego { 1132 1.1 veego struct grfvideo_mode *gv; 1133 1.1 veego struct grfinfo *gi; 1134 1.1 veego volatile unsigned char *ba; 1135 1.1 veego unsigned char num0, denom0; 1136 1.1 veego unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS, 1137 1.1 veego VSE, VT; 1138 1.10 veego unsigned char hvsync_pulse, seq; 1139 1.10 veego char TEXT; 1140 1.9 veego int hmul; 1141 1.1 veego 1142 1.1 veego /* identity */ 1143 1.1 veego gv = &md->gv; 1144 1.1 veego TEXT = (gv->depth == 4); 1145 1.1 veego 1146 1.1 veego if (!et_mondefok(gv)) { 1147 1.10 veego printf("grfet: Monitor definition not ok\n"); 1148 1.1 veego return (0); 1149 1.1 veego } 1150 1.10 veego 1151 1.1 veego ba = gp->g_regkva; 1152 1.1 veego 1153 1.22 wiz /* provide all needed information in grf device-independent locations */ 1154 1.23 christos gp->g_data = (void *) gv; 1155 1.1 veego gi = &gp->g_display; 1156 1.25 is gi->gd_regaddr = ztwopa(__UNVOLATILE(ba)); 1157 1.1 veego gi->gd_regsize = 64 * 1024; 1158 1.24 he gi->gd_fbaddr = (void *) kvtop(__UNVOLATILE(gp->g_fbkva)); 1159 1.1 veego gi->gd_fbsize = et_fbsize; 1160 1.1 veego gi->gd_colors = 1 << gv->depth; 1161 1.1 veego gi->gd_planes = gv->depth; 1162 1.1 veego gi->gd_fbwidth = gv->disp_width; 1163 1.1 veego gi->gd_fbheight = gv->disp_height; 1164 1.1 veego gi->gd_fbx = 0; 1165 1.1 veego gi->gd_fby = 0; 1166 1.1 veego if (TEXT) { 1167 1.1 veego gi->gd_dwidth = md->fx * md->cols; 1168 1.1 veego gi->gd_dheight = md->fy * md->rows; 1169 1.1 veego } else { 1170 1.1 veego gi->gd_dwidth = gv->disp_width; 1171 1.1 veego gi->gd_dheight = gv->disp_height; 1172 1.1 veego } 1173 1.1 veego gi->gd_dx = 0; 1174 1.1 veego gi->gd_dy = 0; 1175 1.1 veego 1176 1.1 veego /* get display mode parameters */ 1177 1.1 veego 1178 1.1 veego HBS = gv->hblank_start; 1179 1.1 veego HSS = gv->hsync_start; 1180 1.1 veego HSE = gv->hsync_stop; 1181 1.10 veego HBE = gv->htotal - 1; 1182 1.1 veego HT = gv->htotal; 1183 1.1 veego VBS = gv->vblank_start; 1184 1.1 veego VSS = gv->vsync_start; 1185 1.1 veego VSE = gv->vsync_stop; 1186 1.10 veego VBE = gv->vtotal - 1; 1187 1.1 veego VT = gv->vtotal; 1188 1.1 veego 1189 1.1 veego if (TEXT) 1190 1.1 veego HDE = ((gv->disp_width + md->fx - 1) / md->fx) - 1; 1191 1.1 veego else 1192 1.1 veego HDE = (gv->disp_width + 3) / 8 - 1; /* HBS; */ 1193 1.1 veego VDE = gv->disp_height - 1; 1194 1.1 veego 1195 1.9 veego /* adjustments (crest) */ 1196 1.9 veego switch (gv->depth) { 1197 1.9 veego case 15: 1198 1.10 veego case 16: 1199 1.10 veego hmul = 2; 1200 1.10 veego break; 1201 1.10 veego case 24: 1202 1.10 veego hmul = 3; 1203 1.10 veego break; 1204 1.10 veego case 32: 1205 1.10 veego hmul = 4; 1206 1.10 veego break; 1207 1.10 veego default: 1208 1.10 veego hmul = 1; 1209 1.10 veego break; 1210 1.9 veego } 1211 1.1 veego 1212 1.9 veego HDE *= hmul; 1213 1.9 veego HBS *= hmul; 1214 1.9 veego HSS *= hmul; 1215 1.9 veego HSE *= hmul; 1216 1.9 veego HBE *= hmul; 1217 1.9 veego HT *= hmul; 1218 1.9 veego 1219 1.10 veego if (gv->disp_flags & GRF_FLAGS_LACE) { 1220 1.10 veego VDE /= 2; 1221 1.10 veego VT = VT + 1; 1222 1.10 veego } 1223 1.10 veego 1224 1.10 veego if (gv->disp_flags & GRF_FLAGS_DBLSCAN) { 1225 1.10 veego VDE *= 2; 1226 1.10 veego VBS *= 2; 1227 1.9 veego VSS *= 2; 1228 1.9 veego VSE *= 2; 1229 1.9 veego VBE *= 2; 1230 1.10 veego VT *= 2; 1231 1.9 veego } 1232 1.9 veego 1233 1.1 veego WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e); 1234 1.1 veego 1235 1.1 veego WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00); 1236 1.1 veego WSeq(ba, SEQ_ID_MAP_MASK, (gv->depth == 1) ? 0x01 : 0xff); 1237 1.1 veego WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00); 1238 1.1 veego 1239 1.1 veego /* Set clock */ 1240 1.9 veego et_CompFQ( gv->pixel_clock * hmul, &num0, &denom0); 1241 1.1 veego 1242 1.10 veego /* Horizontal/Vertical Sync Pulse */ 1243 1.10 veego hvsync_pulse = 0xe3; 1244 1.10 veego if (gv->disp_flags & GRF_FLAGS_PHSYNC) 1245 1.10 veego hvsync_pulse &= ~0x40; 1246 1.10 veego else 1247 1.10 veego hvsync_pulse |= 0x40; 1248 1.10 veego if (gv->disp_flags & GRF_FLAGS_PVSYNC) 1249 1.10 veego hvsync_pulse &= ~0x80; 1250 1.10 veego else 1251 1.10 veego hvsync_pulse |= 0x80; 1252 1.10 veego 1253 1.10 veego vgaw(ba, GREG_MISC_OUTPUT_W, hvsync_pulse | ((num0 & 3) << 2)); 1254 1.1 veego WCrt(ba, CRT_ID_6845_COMPAT, (num0 & 4) ? 0x0a : 0x08); 1255 1.10 veego seq = RSeq(ba, SEQ_ID_CLOCKING_MODE); 1256 1.1 veego switch(denom0) { 1257 1.1 veego case 0: 1258 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xb4); 1259 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7); 1260 1.1 veego break; 1261 1.1 veego case 1: 1262 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4); 1263 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7); 1264 1.1 veego break; 1265 1.1 veego case 2: 1266 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf5); 1267 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7); 1268 1.1 veego break; 1269 1.1 veego case 3: 1270 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf5); 1271 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq | 0x08); 1272 1.1 veego break; 1273 1.9 veego } 1274 1.9 veego 1275 1.1 veego /* load display parameters into board */ 1276 1.1 veego WCrt(ba, CRT_ID_HOR_TOTAL, HT); 1277 1.1 veego WCrt(ba, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? HBS - 1 : HDE)); 1278 1.1 veego WCrt(ba, CRT_ID_START_HOR_BLANK, HBS); 1279 1.9 veego WCrt(ba, CRT_ID_END_HOR_BLANK, (HBE & 0x1f) | 0x80); 1280 1.1 veego WCrt(ba, CRT_ID_START_HOR_RETR, HSS); 1281 1.1 veego WCrt(ba, CRT_ID_END_HOR_RETR, 1282 1.1 veego (HSE & 0x1f) | 1283 1.1 veego ((HBE & 0x20) ? 0x80 : 0x00)); 1284 1.1 veego WCrt(ba, CRT_ID_VER_TOTAL, VT); 1285 1.1 veego WCrt(ba, CRT_ID_OVERFLOW, 1286 1.1 veego 0x10 | 1287 1.1 veego ((VT & 0x100) ? 0x01 : 0x00) | 1288 1.1 veego ((VDE & 0x100) ? 0x02 : 0x00) | 1289 1.1 veego ((VSS & 0x100) ? 0x04 : 0x00) | 1290 1.1 veego ((VBS & 0x100) ? 0x08 : 0x00) | 1291 1.1 veego ((VT & 0x200) ? 0x20 : 0x00) | 1292 1.1 veego ((VDE & 0x200) ? 0x40 : 0x00) | 1293 1.1 veego ((VSS & 0x200) ? 0x80 : 0x00)); 1294 1.1 veego 1295 1.1 veego WCrt(ba, CRT_ID_MAX_ROW_ADDRESS, 1296 1.9 veego 0x40 | /* splitscreen not visible */ 1297 1.10 veego ((gv->disp_flags & GRF_FLAGS_DBLSCAN) ? 0x80 : 0x00) | 1298 1.1 veego ((VBS & 0x200) ? 0x20 : 0x00) | 1299 1.1 veego (TEXT ? ((md->fy - 1) & 0x1f) : 0x00)); 1300 1.1 veego 1301 1.1 veego WCrt(ba, CRT_ID_MODE_CONTROL, 1302 1.1 veego ((TEXT || (gv->depth == 1)) ? 0xc3 : 0xab)); 1303 1.1 veego 1304 1.1 veego /* text cursor */ 1305 1.1 veego if (TEXT) { 1306 1.1 veego #if ET_ULCURSOR 1307 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2); 1308 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1); 1309 1.1 veego #else 1310 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, 0x00); 1311 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f); 1312 1.1 veego #endif 1313 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00); 1314 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00); 1315 1.1 veego } 1316 1.1 veego 1317 1.1 veego WCrt(ba, CRT_ID_UNDERLINE_LOC, ((md->fy - 1) & 0x1f) 1318 1.1 veego | ((TEXT || (gv->depth == 1)) ? 0x00 : 0x60)); 1319 1.1 veego 1320 1.1 veego WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00); 1321 1.1 veego WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00); 1322 1.1 veego 1323 1.1 veego WCrt(ba, CRT_ID_START_VER_RETR, VSS); 1324 1.1 veego WCrt(ba, CRT_ID_END_VER_RETR, (VSE & 0x0f) | 0x30); 1325 1.1 veego WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE); 1326 1.1 veego WCrt(ba, CRT_ID_START_VER_BLANK, VBS); 1327 1.1 veego WCrt(ba, CRT_ID_END_VER_BLANK, VBE); 1328 1.1 veego 1329 1.1 veego WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); 1330 1.1 veego 1331 1.1 veego WCrt(ba, CRT_ID_OVERFLOW_HIGH, 1332 1.3 veego ((VBS & 0x400) ? 0x01 : 0x00) | 1333 1.3 veego ((VT & 0x400) ? 0x02 : 0x00) | 1334 1.3 veego ((VDE & 0x400) ? 0x04 : 0x00) | 1335 1.3 veego ((VSS & 0x400) ? 0x08 : 0x00) | 1336 1.3 veego 0x10 | 1337 1.10 veego ((gv->disp_flags & GRF_FLAGS_LACE) ? 0x80 : 0x00)); 1338 1.3 veego 1339 1.3 veego WCrt(ba, CRT_ID_HOR_OVERFLOW, 1340 1.3 veego ((HT & 0x100) ? 0x01 : 0x00) | 1341 1.3 veego ((HBS & 0x100) ? 0x04 : 0x00) | 1342 1.3 veego ((HSS & 0x100) ? 0x10 : 0x00) 1343 1.3 veego ); 1344 1.1 veego 1345 1.1 veego /* depth dependent stuff */ 1346 1.1 veego 1347 1.1 veego WGfx(ba, GCT_ID_GRAPHICS_MODE, 1348 1.1 veego ((TEXT || (gv->depth == 1)) ? 0x00 : 0x40)); 1349 1.1 veego WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01)); 1350 1.1 veego 1351 1.1 veego vgaw(ba, VDAC_MASK, 0xff); 1352 1.1 veego vgar(ba, VDAC_MASK); 1353 1.1 veego vgar(ba, VDAC_MASK); 1354 1.1 veego vgar(ba, VDAC_MASK); 1355 1.1 veego vgar(ba, VDAC_MASK); 1356 1.1 veego switch (gv->depth) { 1357 1.1 veego case 1: 1358 1.1 veego case 4: /* text */ 1359 1.1 veego switch(etdtype) { 1360 1.1 veego case SIERRA11483: 1361 1.1 veego case SIERRA15025: 1362 1.1 veego case MUSICDAC: 1363 1.1 veego vgaw(ba, VDAC_MASK, 0); 1364 1.1 veego break; 1365 1.9 veego case ATT20C491: 1366 1.9 veego vgaw(ba, VDAC_MASK, 0x02); 1367 1.9 veego break; 1368 1.1 veego case MERLINDAC: 1369 1.1 veego setMerlinDACmode(ba, 0); 1370 1.1 veego break; 1371 1.1 veego } 1372 1.1 veego HDE = gv->disp_width / 16; 1373 1.1 veego break; 1374 1.1 veego case 8: 1375 1.1 veego switch(etdtype) { 1376 1.1 veego case SIERRA11483: 1377 1.1 veego case SIERRA15025: 1378 1.1 veego case MUSICDAC: 1379 1.1 veego vgaw(ba, VDAC_MASK, 0); 1380 1.1 veego break; 1381 1.9 veego case ATT20C491: 1382 1.9 veego vgaw(ba, VDAC_MASK, 0x02); 1383 1.9 veego break; 1384 1.1 veego case MERLINDAC: 1385 1.1 veego setMerlinDACmode(ba, 0); 1386 1.1 veego break; 1387 1.1 veego } 1388 1.1 veego HDE = gv->disp_width / 8; 1389 1.1 veego break; 1390 1.1 veego case 15: 1391 1.1 veego switch(etdtype) { 1392 1.1 veego case SIERRA11483: 1393 1.1 veego case SIERRA15025: 1394 1.1 veego case MUSICDAC: 1395 1.9 veego case ATT20C491: 1396 1.1 veego vgaw(ba, VDAC_MASK, 0xa0); 1397 1.1 veego break; 1398 1.1 veego case MERLINDAC: 1399 1.1 veego setMerlinDACmode(ba, 0xa0); 1400 1.1 veego break; 1401 1.1 veego } 1402 1.1 veego HDE = gv->disp_width / 4; 1403 1.1 veego break; 1404 1.1 veego case 16: 1405 1.1 veego switch(etdtype) { 1406 1.1 veego case SIERRA11483: 1407 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */ 1408 1.1 veego break; 1409 1.1 veego case SIERRA15025: 1410 1.1 veego vgaw(ba, VDAC_MASK, 0xe0); 1411 1.1 veego break; 1412 1.1 veego case MUSICDAC: 1413 1.9 veego case ATT20C491: 1414 1.1 veego vgaw(ba, VDAC_MASK, 0xc0); 1415 1.1 veego break; 1416 1.1 veego case MERLINDAC: 1417 1.1 veego setMerlinDACmode(ba, 0xe0); 1418 1.1 veego break; 1419 1.1 veego } 1420 1.1 veego HDE = gv->disp_width / 4; 1421 1.1 veego break; 1422 1.1 veego case 24: 1423 1.1 veego switch(etdtype) { 1424 1.1 veego case SIERRA11483: 1425 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */ 1426 1.1 veego break; 1427 1.1 veego case SIERRA15025: 1428 1.1 veego vgaw(ba, VDAC_MASK, 0xe1); 1429 1.1 veego break; 1430 1.1 veego case MUSICDAC: 1431 1.9 veego case ATT20C491: 1432 1.1 veego vgaw(ba, VDAC_MASK, 0xe0); 1433 1.1 veego break; 1434 1.1 veego case MERLINDAC: 1435 1.1 veego setMerlinDACmode(ba, 0xf0); 1436 1.1 veego break; 1437 1.1 veego } 1438 1.1 veego HDE = (gv->disp_width / 8) * 3; 1439 1.1 veego break; 1440 1.1 veego case 32: 1441 1.1 veego switch(etdtype) { 1442 1.1 veego case SIERRA11483: 1443 1.1 veego case MUSICDAC: 1444 1.9 veego case ATT20C491: 1445 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */ 1446 1.1 veego break; 1447 1.1 veego case SIERRA15025: 1448 1.1 veego vgaw(ba, VDAC_MASK, 0x61); 1449 1.1 veego break; 1450 1.1 veego case MERLINDAC: 1451 1.1 veego setMerlinDACmode(ba, 0xb0); 1452 1.1 veego break; 1453 1.1 veego } 1454 1.1 veego HDE = gv->disp_width / 2; 1455 1.1 veego break; 1456 1.1 veego } 1457 1.1 veego WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x0a : 0x01)); 1458 1.1 veego WAttr(ba, 0x20 | ACT_ID_COLOR_PLANE_ENA, 1459 1.1 veego (gv->depth == 1) ? 0x01 : 0x0f); 1460 1.1 veego 1461 1.1 veego WCrt(ba, CRT_ID_OFFSET, HDE); 1462 1.9 veego vgaw(ba, CRT_ADDRESS, CRT_ID_HOR_OVERFLOW); 1463 1.9 veego vgaw(ba, CRT_ADDRESS_W, 1464 1.9 veego (vgar(ba, CRT_ADDRESS_R) & 0x7f) 1465 1.9 veego | ((HDE & 0x100) ? 0x80: 0x00)); 1466 1.1 veego 1467 1.1 veego /* text initialization */ 1468 1.1 veego if (TEXT) { 1469 1.1 veego et_inittextmode(gp); 1470 1.1 veego } 1471 1.1 veego 1472 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x01); 1473 1.1 veego 1474 1.1 veego /* Pass-through */ 1475 1.1 veego RegOffpass(ba); 1476 1.1 veego 1477 1.1 veego return (1); 1478 1.1 veego } 1479 1.1 veego 1480 1.1 veego 1481 1.1 veego void 1482 1.13 aymeric et_inittextmode(struct grf_softc *gp) 1483 1.1 veego { 1484 1.1 veego struct grfettext_mode *tm = (struct grfettext_mode *) gp->g_data; 1485 1.1 veego volatile unsigned char *ba = gp->g_regkva; 1486 1.24 he volatile unsigned char *fb = gp->g_fbkva; 1487 1.24 he volatile unsigned char *c; 1488 1.24 he unsigned char *f, y; 1489 1.1 veego unsigned short z; 1490 1.1 veego 1491 1.1 veego 1492 1.3 veego /* 1493 1.3 veego * load text font into beginning of display memory. Each character 1494 1.3 veego * cell is 32 bytes long (enough for 4 planes) 1495 1.3 veego */ 1496 1.1 veego 1497 1.1 veego SetTextPlane(ba, 0x02); 1498 1.1 veego et_memset(fb, 0, 256 * 32); 1499 1.24 he c = fb + (32 * tm->fdstart); 1500 1.1 veego f = tm->fdata; 1501 1.1 veego for (z = tm->fdstart; z <= tm->fdend; z++, c += (32 - tm->fy)) 1502 1.1 veego for (y = 0; y < tm->fy; y++) 1503 1.1 veego *c++ = *f++; 1504 1.1 veego 1505 1.1 veego /* clear out text/attr planes (three screens worth) */ 1506 1.1 veego 1507 1.1 veego SetTextPlane(ba, 0x01); 1508 1.1 veego et_memset(fb, 0x07, tm->cols * tm->rows * 3); 1509 1.1 veego SetTextPlane(ba, 0x00); 1510 1.1 veego et_memset(fb, 0x20, tm->cols * tm->rows * 3); 1511 1.1 veego 1512 1.1 veego /* print out a little init msg */ 1513 1.1 veego 1514 1.24 he c = fb + (tm->cols - 16); 1515 1.24 he strcpy(__UNVOLATILE(c), "TSENG"); 1516 1.9 veego c[5] = 0x20; 1517 1.1 veego 1518 1.1 veego /* set colors (B&W) */ 1519 1.1 veego 1520 1.1 veego switch(ettype) { 1521 1.1 veego case MERLIN: 1522 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, 0); 1523 1.1 veego for (z = 0; z < 256; z++) { 1524 1.1 veego y = (z & 1) ? ((z > 7) ? 2 : 1) : 0; 1525 1.9 veego 1526 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][0]); 1527 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][1]); 1528 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][2]); 1529 1.1 veego } 1530 1.1 veego break; 1531 1.1 veego default: 1532 1.1 veego vgaw(ba, VDAC_ADDRESS_W, 0); 1533 1.1 veego for (z = 0; z < 256; z++) { 1534 1.1 veego y = (z & 1) ? ((z > 7) ? 2 : 1) : 0; 1535 1.9 veego 1536 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), 1537 1.3 veego etconscolors[y][0] >> etcmap_shift); 1538 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), 1539 1.3 veego etconscolors[y][1] >> etcmap_shift); 1540 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), 1541 1.3 veego etconscolors[y][2] >> etcmap_shift); 1542 1.1 veego } 1543 1.1 veego break; 1544 1.1 veego } 1545 1.1 veego } 1546 1.1 veego 1547 1.1 veego 1548 1.1 veego void 1549 1.24 he et_memset(volatile unsigned char *d, unsigned char c, int l) 1550 1.1 veego { 1551 1.1 veego for (; l > 0; l--) 1552 1.1 veego *d++ = c; 1553 1.1 veego } 1554 1.1 veego 1555 1.1 veego 1556 1.1 veego static int 1557 1.13 aymeric et_getControllerType(struct grf_softc *gp) 1558 1.1 veego { 1559 1.24 he volatile unsigned char *ba = gp->g_regkva; /* register base */ 1560 1.24 he volatile unsigned char *mem = gp->g_fbkva; /* memory base */ 1561 1.24 he volatile unsigned char *mmu = mem + MMU_APERTURE0; /* MMU aperture 0 base */ 1562 1.1 veego 1563 1.1 veego *mem = 0; 1564 1.1 veego 1565 1.1 veego /* make ACL visible */ 1566 1.10 veego if (ettype == MERLIN) { 1567 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xbb); 1568 1.10 veego } else { 1569 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xfb); 1570 1.9 veego } 1571 1.9 veego 1572 1.1 veego WIma(ba, IMA_PORTCONTROL, 0x01); 1573 1.1 veego 1574 1.24 he *((volatile unsigned long *)mmu) = 0; 1575 1.1 veego *(mem + 0x13) = 0x38; 1576 1.3 veego 1577 1.1 veego *mmu = 0xff; 1578 1.1 veego 1579 1.1 veego /* hide ACL */ 1580 1.1 veego WIma(ba, IMA_PORTCONTROL, 0x00); 1581 1.3 veego 1582 1.10 veego if (ettype == MERLIN) { 1583 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x93); 1584 1.10 veego } else { 1585 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3); 1586 1.9 veego } 1587 1.10 veego return ((*mem == 0xff) ? ETW32 : ET4000); 1588 1.1 veego } 1589 1.1 veego 1590 1.35 christos /* We MUST do 4 HW reads to switch into command mode */ 1591 1.35 christos static inline int vgar4HDR(volatile unsigned char *ba) 1592 1.35 christos { 1593 1.35 christos return vgar(ba, HDR) + vgar(ba, HDR) + vgar(ba, HDR) + vgar(ba, HDR); 1594 1.35 christos } 1595 1.1 veego 1596 1.1 veego static int 1597 1.13 aymeric et_getDACType(struct grf_softc *gp) 1598 1.1 veego { 1599 1.24 he volatile unsigned char *ba = gp->g_regkva; 1600 1.1 veego union { 1601 1.1 veego int tt; 1602 1.1 veego char cc[4]; 1603 1.1 veego } check; 1604 1.1 veego 1605 1.1 veego /* check for Sierra SC 15025 */ 1606 1.1 veego 1607 1.35 christos vgar4HDR(ba); 1608 1.35 christos vgaw(ba, VDAC_COMMAND, 0x10); /* set ERPF */ 1609 1.3 veego 1610 1.3 veego vgaw(ba, VDAC_XINDEX, 9); 1611 1.3 veego check.cc[0] = vgar(ba, VDAC_XDATA); 1612 1.3 veego vgaw(ba, VDAC_XINDEX, 10); 1613 1.3 veego check.cc[1] = vgar(ba, VDAC_XDATA); 1614 1.3 veego vgaw(ba, VDAC_XINDEX, 11); 1615 1.3 veego check.cc[2] = vgar(ba, VDAC_XDATA); 1616 1.3 veego vgaw(ba, VDAC_XINDEX, 12); 1617 1.3 veego check.cc[3] = vgar(ba, VDAC_XDATA); 1618 1.3 veego 1619 1.35 christos vgar4HDR(ba); 1620 1.34 mrg vgaw(ba, VDAC_COMMAND, 0x00); /* clear ERPF */ 1621 1.3 veego 1622 1.3 veego if (check.tt == 0x533ab141) { 1623 1.35 christos vgar4HDR(ba); 1624 1.34 mrg vgaw(ba, VDAC_COMMAND, 0x10); /* set ERPF */ 1625 1.3 veego 1626 1.3 veego /* switch to 8 bits per color */ 1627 1.3 veego vgaw(ba, VDAC_XINDEX, 8); 1628 1.3 veego vgaw(ba, VDAC_XDATA, 1); 1629 1.3 veego /* do not shift color values */ 1630 1.3 veego etcmap_shift = 0; 1631 1.3 veego 1632 1.35 christos vgar4HDR(ba); 1633 1.34 mrg vgaw(ba, VDAC_COMMAND, 0x00); /* clear ERPF */ 1634 1.3 veego 1635 1.3 veego vgaw(ba, VDAC_MASK, 0xff); 1636 1.3 veego return (SIERRA15025); 1637 1.3 veego } 1638 1.3 veego 1639 1.3 veego /* check for MUSIC DAC */ 1640 1.3 veego 1641 1.35 christos vgar4HDR(ba); 1642 1.34 mrg vgaw(ba, VDAC_COMMAND, 0x02); /* set some strange MUSIC mode (???) */ 1643 1.3 veego 1644 1.3 veego vgaw(ba, VDAC_XINDEX, 0x01); 1645 1.3 veego if (vgar(ba, VDAC_XDATA) == 0x01) { 1646 1.3 veego /* shift color values by 2 */ 1647 1.3 veego etcmap_shift = 2; 1648 1.1 veego 1649 1.3 veego vgaw(ba, VDAC_MASK, 0xff); 1650 1.3 veego return (MUSICDAC); 1651 1.9 veego } 1652 1.9 veego 1653 1.9 veego /* check for AT&T ATT20c491 DAC (crest) */ 1654 1.35 christos vgar4HDR(ba); 1655 1.9 veego vgaw(ba, HDR, 0xff); 1656 1.9 veego vgaw(ba, VDAC_MASK, 0x01); 1657 1.35 christos vgar4HDR(ba); 1658 1.9 veego if (vgar(ba, HDR) == 0xff) { 1659 1.9 veego /* do not shift color values */ 1660 1.9 veego etcmap_shift = 0; 1661 1.9 veego 1662 1.9 veego vgaw(ba, VDAC_MASK, 0xff); 1663 1.9 veego return (ATT20C491); 1664 1.9 veego } 1665 1.9 veego 1666 1.9 veego /* restore PowerUp settings (crest) */ 1667 1.35 christos vgar4HDR(ba); 1668 1.9 veego vgaw(ba, HDR, 0x00); 1669 1.3 veego 1670 1.3 veego /* 1671 1.3 veego * nothing else found, so let us pretend it is a stupid 1672 1.3 veego * Sierra SC 11483 1673 1.3 veego */ 1674 1.1 veego 1675 1.1 veego /* shift color values by 2 */ 1676 1.1 veego etcmap_shift = 2; 1677 1.3 veego 1678 1.1 veego vgaw(ba, VDAC_MASK, 0xff); 1679 1.9 veego return (SIERRA11483); 1680 1.1 veego } 1681 1.1 veego 1682 1.33 phx 1683 1.33 phx #if NWSDISPLAY > 0 1684 1.33 phx static void 1685 1.33 phx et_wscursor(void *c, int on, int row, int col) 1686 1.33 phx { 1687 1.33 phx struct rasops_info *ri; 1688 1.33 phx struct vcons_screen *scr; 1689 1.33 phx struct grf_softc *gp; 1690 1.33 phx volatile void *ba; 1691 1.33 phx int offs; 1692 1.33 phx 1693 1.33 phx ri = c; 1694 1.33 phx scr = ri->ri_hw; 1695 1.33 phx gp = scr->scr_cookie; 1696 1.33 phx ba = gp->g_regkva; 1697 1.33 phx 1698 1.33 phx if ((ri->ri_flg & RI_CURSOR) && !on) { 1699 1.33 phx /* cursor was visible, but we want to remove it */ 1700 1.33 phx /*WCrt(ba, CRT_ID_CURSOR_START, | 0x20);*/ 1701 1.33 phx ri->ri_flg &= ~RI_CURSOR; 1702 1.33 phx } 1703 1.33 phx 1704 1.33 phx ri->ri_crow = row; 1705 1.33 phx ri->ri_ccol = col; 1706 1.33 phx 1707 1.33 phx if (on) { 1708 1.33 phx /* move cursor to new location */ 1709 1.33 phx if (!(ri->ri_flg & RI_CURSOR)) { 1710 1.33 phx /*WCrt(ba, CRT_ID_CURSOR_START, | 0x20);*/ 1711 1.33 phx ri->ri_flg |= RI_CURSOR; 1712 1.33 phx } 1713 1.33 phx offs = gp->g_rowoffset[row] + col; 1714 1.33 phx WCrt(ba, CRT_ID_CURSOR_LOC_LOW, offs & 0xff); 1715 1.33 phx WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, (offs >> 8) & 0xff); 1716 1.33 phx WCrt(ba, CRT_ID_EXT_START, (offs >> (16-2)) & 0x0c); 1717 1.33 phx } 1718 1.33 phx } 1719 1.33 phx 1720 1.33 phx static void 1721 1.33 phx et_wsputchar(void *c, int row, int col, u_int ch, long attr) 1722 1.33 phx { 1723 1.33 phx struct rasops_info *ri; 1724 1.33 phx struct vcons_screen *scr; 1725 1.33 phx struct grf_softc *gp; 1726 1.33 phx volatile unsigned char *ba, *cp; 1727 1.33 phx 1728 1.33 phx ri = c; 1729 1.33 phx scr = ri->ri_hw; 1730 1.33 phx gp = scr->scr_cookie; 1731 1.33 phx ba = gp->g_regkva; 1732 1.33 phx cp = gp->g_fbkva; 1733 1.33 phx 1734 1.33 phx cp += gp->g_rowoffset[row] + col; 1735 1.33 phx SetTextPlane(ba, 0x00); 1736 1.33 phx *cp = ch; 1737 1.33 phx SetTextPlane(ba, 0x01); 1738 1.33 phx *cp = attr; 1739 1.33 phx } 1740 1.33 phx 1741 1.33 phx static void 1742 1.33 phx et_wscopycols(void *c, int row, int srccol, int dstcol, int ncols) 1743 1.33 phx { 1744 1.33 phx volatile unsigned char *ba, *dst, *src; 1745 1.33 phx struct rasops_info *ri; 1746 1.33 phx struct vcons_screen *scr; 1747 1.33 phx struct grf_softc *gp; 1748 1.33 phx int i; 1749 1.33 phx 1750 1.33 phx KASSERT(ncols > 0); 1751 1.33 phx ri = c; 1752 1.33 phx scr = ri->ri_hw; 1753 1.33 phx gp = scr->scr_cookie; 1754 1.33 phx ba = gp->g_regkva; 1755 1.33 phx src = gp->g_fbkva; 1756 1.33 phx 1757 1.33 phx src += gp->g_rowoffset[row]; 1758 1.33 phx dst = src; 1759 1.33 phx src += srccol; 1760 1.33 phx dst += dstcol; 1761 1.33 phx if (srccol < dstcol) { 1762 1.33 phx /* need to copy backwards */ 1763 1.33 phx src += ncols; 1764 1.33 phx dst += ncols; 1765 1.33 phx SetTextPlane(ba, 0x00); 1766 1.33 phx for (i = 0; i < ncols; i++) 1767 1.33 phx *(--dst) = *(--src); 1768 1.33 phx src += ncols; 1769 1.33 phx dst += ncols; 1770 1.33 phx SetTextPlane(ba, 0x01); 1771 1.33 phx for (i = 0; i < ncols; i++) 1772 1.33 phx *(--dst) = *(--src); 1773 1.33 phx } else { 1774 1.33 phx SetTextPlane(ba, 0x00); 1775 1.33 phx for (i = 0; i < ncols; i++) 1776 1.33 phx *dst++ = *src++; 1777 1.33 phx src -= ncols; 1778 1.33 phx dst -= ncols; 1779 1.33 phx SetTextPlane(ba, 0x01); 1780 1.33 phx for (i = 0; i < ncols; i++) 1781 1.33 phx *dst++ = *src++; 1782 1.33 phx } 1783 1.33 phx } 1784 1.33 phx 1785 1.33 phx static void 1786 1.33 phx et_wserasecols(void *c, int row, int startcol, int ncols, long fillattr) 1787 1.33 phx { 1788 1.33 phx volatile unsigned char *ba, *cp; 1789 1.33 phx struct rasops_info *ri; 1790 1.33 phx struct vcons_screen *scr; 1791 1.33 phx struct grf_softc *gp; 1792 1.33 phx int i; 1793 1.33 phx 1794 1.33 phx ri = c; 1795 1.33 phx scr = ri->ri_hw; 1796 1.33 phx gp = scr->scr_cookie; 1797 1.33 phx ba = gp->g_regkva; 1798 1.33 phx cp = gp->g_fbkva; 1799 1.33 phx 1800 1.33 phx cp += gp->g_rowoffset[row] + startcol; 1801 1.33 phx SetTextPlane(ba, 0x00); 1802 1.33 phx for (i = 0; i < ncols; i++) 1803 1.33 phx *cp++ = 0x20; 1804 1.33 phx cp -= ncols; 1805 1.33 phx SetTextPlane(ba, 0x01); 1806 1.33 phx for (i = 0; i < ncols; i++) 1807 1.33 phx *cp++ = 0x07; 1808 1.33 phx } 1809 1.33 phx 1810 1.33 phx static void 1811 1.33 phx et_wscopyrows(void *c, int srcrow, int dstrow, int nrows) 1812 1.33 phx { 1813 1.33 phx volatile unsigned char *ba, *dst, *src; 1814 1.33 phx struct rasops_info *ri; 1815 1.33 phx struct vcons_screen *scr; 1816 1.33 phx struct grf_softc *gp; 1817 1.33 phx int i, n; 1818 1.33 phx 1819 1.33 phx KASSERT(nrows > 0); 1820 1.33 phx ri = c; 1821 1.33 phx scr = ri->ri_hw; 1822 1.33 phx gp = scr->scr_cookie; 1823 1.33 phx ba = gp->g_regkva; 1824 1.33 phx src = dst = gp->g_fbkva; 1825 1.33 phx n = ri->ri_cols * nrows; 1826 1.33 phx 1827 1.33 phx if (srcrow < dstrow) { 1828 1.33 phx /* need to copy backwards */ 1829 1.33 phx src += gp->g_rowoffset[srcrow + nrows]; 1830 1.33 phx dst += gp->g_rowoffset[dstrow + nrows]; 1831 1.33 phx SetTextPlane(ba, 0x00); 1832 1.33 phx for (i = 0; i < n; i++) 1833 1.33 phx *(--dst) = *(--src); 1834 1.33 phx src += n; 1835 1.33 phx dst += n; 1836 1.33 phx SetTextPlane(ba, 0x01); 1837 1.33 phx for (i = 0; i < n; i++) 1838 1.33 phx *(--dst) = *(--src); 1839 1.33 phx } else { 1840 1.33 phx src += gp->g_rowoffset[srcrow]; 1841 1.33 phx dst += gp->g_rowoffset[dstrow]; 1842 1.33 phx SetTextPlane(ba, 0x00); 1843 1.33 phx for (i = 0; i < n; i++) 1844 1.33 phx *dst++ = *src++; 1845 1.33 phx src -= n; 1846 1.33 phx dst -= n; 1847 1.33 phx SetTextPlane(ba, 0x01); 1848 1.33 phx for (i = 0; i < n; i++) 1849 1.33 phx *dst++ = *src++; 1850 1.33 phx } 1851 1.33 phx } 1852 1.33 phx 1853 1.33 phx static void 1854 1.33 phx et_wseraserows(void *c, int row, int nrows, long fillattr) 1855 1.33 phx { 1856 1.33 phx volatile unsigned char *ba, *cp; 1857 1.33 phx struct rasops_info *ri; 1858 1.33 phx struct vcons_screen *scr; 1859 1.33 phx struct grf_softc *gp; 1860 1.33 phx int i, n; 1861 1.33 phx 1862 1.33 phx ri = c; 1863 1.33 phx scr = ri->ri_hw; 1864 1.33 phx gp = scr->scr_cookie; 1865 1.33 phx ba = gp->g_regkva; 1866 1.33 phx cp = gp->g_fbkva; 1867 1.33 phx 1868 1.33 phx cp += gp->g_rowoffset[row]; 1869 1.33 phx n = ri->ri_cols * nrows; 1870 1.33 phx SetTextPlane(ba, 0x00); 1871 1.33 phx for (i = 0; i < n; i++) 1872 1.33 phx *cp++ = 0x20; 1873 1.33 phx cp -= n; 1874 1.33 phx SetTextPlane(ba, 0x01); 1875 1.33 phx for (i = 0; i < n; i++) 1876 1.33 phx *cp++ = 0x07; 1877 1.33 phx } 1878 1.33 phx 1879 1.33 phx static int 1880 1.33 phx et_wsallocattr(void *c, int fg, int bg, int flg, long *attr) 1881 1.33 phx { 1882 1.33 phx 1883 1.33 phx /* XXX color support? */ 1884 1.33 phx *attr = (flg & WSATTR_REVERSE) ? 0x70 : 0x07; 1885 1.33 phx if (flg & WSATTR_UNDERLINE) *attr = 0x01; 1886 1.33 phx if (flg & WSATTR_HILIT) *attr |= 0x08; 1887 1.33 phx if (flg & WSATTR_BLINK) *attr |= 0x80; 1888 1.33 phx return 0; 1889 1.33 phx } 1890 1.33 phx 1891 1.33 phx /* our font does not support unicode extensions */ 1892 1.33 phx static int 1893 1.33 phx et_wsmapchar(void *c, int ch, unsigned int *cp) 1894 1.33 phx { 1895 1.33 phx 1896 1.33 phx if (ch > 0 && ch < 256) { 1897 1.33 phx *cp = ch; 1898 1.33 phx return 5; 1899 1.33 phx } 1900 1.33 phx *cp = ' '; 1901 1.33 phx return 0; 1902 1.33 phx } 1903 1.33 phx 1904 1.33 phx static int 1905 1.33 phx et_wsioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) 1906 1.33 phx { 1907 1.33 phx struct vcons_data *vd; 1908 1.33 phx struct grf_softc *gp; 1909 1.33 phx 1910 1.33 phx vd = v; 1911 1.33 phx gp = vd->cookie; 1912 1.33 phx 1913 1.33 phx switch (cmd) { 1914 1.33 phx case WSDISPLAYIO_GETCMAP: 1915 1.33 phx /* Note: wsdisplay_cmap and grf_colormap have same format */ 1916 1.33 phx if (gp->g_display.gd_planes == 8) 1917 1.33 phx return et_getcmap(gp, (struct grf_colormap *)data); 1918 1.33 phx return EINVAL; 1919 1.33 phx 1920 1.33 phx case WSDISPLAYIO_PUTCMAP: 1921 1.33 phx /* Note: wsdisplay_cmap and grf_colormap have same format */ 1922 1.33 phx if (gp->g_display.gd_planes == 8) 1923 1.33 phx return et_putcmap(gp, (struct grf_colormap *)data); 1924 1.33 phx return EINVAL; 1925 1.33 phx 1926 1.33 phx case WSDISPLAYIO_GVIDEO: 1927 1.33 phx if (et_isblank(gp)) 1928 1.33 phx *(u_int *)data = WSDISPLAYIO_VIDEO_OFF; 1929 1.33 phx else 1930 1.33 phx *(u_int *)data = WSDISPLAYIO_VIDEO_ON; 1931 1.33 phx return 0; 1932 1.33 phx 1933 1.33 phx case WSDISPLAYIO_SVIDEO: 1934 1.33 phx return et_blank(gp, *(u_int *)data == WSDISPLAYIO_VIDEO_ON); 1935 1.33 phx 1936 1.33 phx case WSDISPLAYIO_SMODE: 1937 1.33 phx if ((*(int *)data) != gp->g_wsmode) { 1938 1.33 phx if (*(int *)data == WSDISPLAYIO_MODE_EMUL) { 1939 1.33 phx /* load console text mode, redraw screen */ 1940 1.33 phx (void)et_load_mon(gp, &etconsole_mode); 1941 1.33 phx if (vd->active != NULL) 1942 1.33 phx vcons_redraw_screen(vd->active); 1943 1.33 phx } else { 1944 1.33 phx /* switch to current graphics mode */ 1945 1.33 phx if (!et_load_mon(gp, 1946 1.33 phx (struct grfettext_mode *)monitor_current)) 1947 1.33 phx return EINVAL; 1948 1.33 phx } 1949 1.33 phx gp->g_wsmode = *(int *)data; 1950 1.33 phx } 1951 1.33 phx return 0; 1952 1.33 phx 1953 1.33 phx case WSDISPLAYIO_GET_FBINFO: 1954 1.33 phx return et_get_fbinfo(gp, data); 1955 1.33 phx } 1956 1.33 phx 1957 1.39 andvar /* handle this command hw-independent in grf(4) */ 1958 1.33 phx return grf_wsioctl(v, vs, cmd, data, flag, l); 1959 1.33 phx } 1960 1.33 phx 1961 1.33 phx /* 1962 1.33 phx * Fill the wsdisplayio_fbinfo structure with information from the current 1963 1.33 phx * graphics mode. Even when text mode is active. 1964 1.33 phx */ 1965 1.33 phx static int 1966 1.33 phx et_get_fbinfo(struct grf_softc *gp, struct wsdisplayio_fbinfo *fbi) 1967 1.33 phx { 1968 1.33 phx struct grfvideo_mode *md; 1969 1.33 phx uint32_t rbits, gbits, bbits; 1970 1.33 phx 1971 1.33 phx md = monitor_current; 1972 1.33 phx 1973 1.33 phx switch (md->depth) { 1974 1.33 phx case 8: 1975 1.33 phx fbi->fbi_bitsperpixel = 8; 1976 1.33 phx rbits = gbits = bbits = 6; /* keep gcc happy */ 1977 1.33 phx break; 1978 1.33 phx case 15: 1979 1.33 phx fbi->fbi_bitsperpixel = 16; 1980 1.33 phx rbits = gbits = bbits = 5; 1981 1.33 phx break; 1982 1.33 phx case 16: 1983 1.33 phx fbi->fbi_bitsperpixel = 16; 1984 1.33 phx rbits = bbits = 5; 1985 1.33 phx gbits = 6; 1986 1.33 phx break; 1987 1.33 phx case 24: 1988 1.33 phx fbi->fbi_bitsperpixel = 24; 1989 1.33 phx rbits = gbits = bbits = 8; 1990 1.33 phx break; 1991 1.33 phx default: 1992 1.33 phx return EINVAL; 1993 1.33 phx } 1994 1.33 phx 1995 1.33 phx fbi->fbi_stride = (fbi->fbi_bitsperpixel / 8) * md->disp_width; 1996 1.33 phx fbi->fbi_width = md->disp_width; 1997 1.33 phx fbi->fbi_height = md->disp_height; 1998 1.33 phx 1999 1.33 phx if (md->depth > 8) { 2000 1.33 phx fbi->fbi_pixeltype = WSFB_RGB; 2001 1.33 phx fbi->fbi_subtype.fbi_rgbmasks.red_offset = bbits + gbits; 2002 1.33 phx fbi->fbi_subtype.fbi_rgbmasks.red_size = rbits; 2003 1.33 phx fbi->fbi_subtype.fbi_rgbmasks.green_offset = bbits; 2004 1.33 phx fbi->fbi_subtype.fbi_rgbmasks.green_size = gbits; 2005 1.33 phx fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 0; 2006 1.33 phx fbi->fbi_subtype.fbi_rgbmasks.blue_size = bbits; 2007 1.33 phx fbi->fbi_subtype.fbi_rgbmasks.alpha_offset = 0; 2008 1.33 phx fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 0; 2009 1.33 phx } else { 2010 1.33 phx fbi->fbi_pixeltype = WSFB_CI; 2011 1.33 phx fbi->fbi_subtype.fbi_cmapinfo.cmap_entries = 1 << md->depth; 2012 1.33 phx } 2013 1.33 phx 2014 1.33 phx fbi->fbi_flags = 0; 2015 1.33 phx fbi->fbi_fbsize = fbi->fbi_stride * fbi->fbi_height; 2016 1.33 phx fbi->fbi_fboffset = 0; 2017 1.33 phx return 0; 2018 1.33 phx } 2019 1.33 phx #endif /* NWSDISPLAY > 0 */ 2020 1.33 phx 2021 1.1 veego #endif /* NGRFET */ 2022