|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: ! 27: /* ********************************************************************** ! 28: File: blit.c ! 29: Description: Device Driver for Bell Tech Blit card ! 30: ! 31: $ Header: $ ! 32: ! 33: Copyright Ing. C. Olivetti & C. S.p.A. 1988, 1989. ! 34: All rights reserved. ! 35: ********************************************************************** */ ! 36: /* ! 37: Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc., ! 38: Cupertino, California. ! 39: ! 40: All Rights Reserved ! 41: ! 42: Permission to use, copy, modify, and distribute this software and ! 43: its documentation for any purpose and without fee is hereby ! 44: granted, provided that the above copyright notice appears in all ! 45: copies and that both the copyright notice and this permission notice ! 46: appear in supporting documentation, and that the name of Olivetti ! 47: not be used in advertising or publicity pertaining to distribution ! 48: of the software without specific, written prior permission. ! 49: ! 50: OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ! 51: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, ! 52: IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR ! 53: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 54: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, ! 55: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION ! 56: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 57: */ ! 58: ! 59: /* ! 60: Copyright 1988, 1989 by Intel Corporation, Santa Clara, California. ! 61: ! 62: All Rights Reserved ! 63: ! 64: Permission to use, copy, modify, and distribute this software and ! 65: its documentation for any purpose and without fee is hereby ! 66: granted, provided that the above copyright notice appears in all ! 67: copies and that both the copyright notice and this permission notice ! 68: appear in supporting documentation, and that the name of Intel ! 69: not be used in advertising or publicity pertaining to distribution ! 70: of the software without specific, written prior permission. ! 71: ! 72: INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ! 73: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, ! 74: IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR ! 75: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 76: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, ! 77: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION ! 78: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 79: */ ! 80: ! 81: #ifdef MACH_KERNEL ! 82: #include <sys/types.h> ! 83: #include <device/errno.h> ! 84: #else MACH_KERNEL ! 85: #include <sys/types.h> ! 86: #include <sys/errno.h> ! 87: #include <sys/param.h> ! 88: #include <sys/dir.h> ! 89: #include <sys/signal.h> ! 90: #include <sys/user.h> ! 91: #endif MACH_KERNEL ! 92: #include <vm/vm_kern.h> ! 93: #include <mach/vm_param.h> ! 94: #include <machine/machspl.h> ! 95: ! 96: #include <i386at/blitreg.h> ! 97: #include <i386at/blitvar.h> ! 98: #include <i386at/blituser.h> ! 99: #include <i386at/kd.h> ! 100: #include <i386at/kdsoft.h> ! 101: ! 102: #include <blit.h> ! 103: ! 104: ! 105: /* ! 106: * This driver really only supports 1 card, though parts of it were ! 107: * written to support multiple cards. If you want to finish the job ! 108: * and really support multiple cards, then you'll have to: ! 109: * ! 110: * (1) make sure that driver functions pass around a pointer telling ! 111: * which card they're talking about. ! 112: * ! 113: * (2) coordinate things with the kd driver, so that one card is used ! 114: * for the console and the other is simply an additional display. ! 115: */ ! 116: #define MAXBLITS 1 ! 117: ! 118: #if NBLIT > MAXBLITS ! 119: /* oh, no, you don't want to do this...; */ ! 120: ! 121: #else ! 122: #if NBLIT > 0 ! 123: ! 124: #define AUTOINIT 0 ! 125: ! 126: /* ! 127: * Forward Declarations ! 128: */ ! 129: static tiledesc(); ! 130: static loadall(); ! 131: ! 132: #if AUTOINIT ! 133: int blitattach(), blitprobe(); ! 134: #endif ! 135: ! 136: int blitioctl(), blitopen(), blitclose(), blitmmap(); ! 137: ! 138: ! 139: static void setstatus(); ! 140: #define CARD_RESET 0 ! 141: #define CARD_MAPPED 1 ! 142: #define CARD_MAYBE_PRESENT 2 ! 143: #define CARD_PRESENT 3 ! 144: #define BIU_INIT 4 ! 145: #define UNUSED1 5 ! 146: #define DP_INIT 6 ! 147: #define UNUSED2 7 ! 148: ! 149: ! 150: #if AUTOINIT ! 151: struct mb_device *blitinfo[NBLIT]; ! 152: ! 153: struct mb_driver blitdriver = { ! 154: blitprobe, ! 155: 0, /* slave routine */ ! 156: blitattach, ! 157: 0, 0, 0, /* go, done, intr routines */ ! 158: BLIT_MAPPED_SIZE, ! 159: "blit", blitinfo, /* device info */ ! 160: 0, 0, /* no controller */ ! 161: 0 /* no flags */ ! 162: /* rest zeros */ ! 163: }; ! 164: #endif /* AUTOINIT */ ! 165: ! 166: ! 167: /* ! 168: * Per-card bookkeeping information for driver. ! 169: * ! 170: * "scrstrip" and "dpctlregs" point to data areas that are passed to ! 171: * the Display Processor. They are allocated out of the spare ! 172: * graphics memory. "scrstrip" is used to describe an entire screen. ! 173: * "dpctlregs" contains assorted parameters for the display ! 174: * controller. ! 175: * ! 176: * "firstfree" is an offset into the graphics memory. Memory starting ! 177: * there can be allocated by users. ! 178: */ ! 179: ! 180: struct blitsoft { ! 181: struct blitdev *blt; /* ptr to mapped card */ ! 182: caddr_t physaddr; /* start of mapped card */ ! 183: boolean_t open; /* is device open? */ ! 184: struct screen_descrip *scrstrip; ! 185: DPCONTROLBLK *dpctlregs; ! 186: int firstfree; ! 187: } blitsoft[NBLIT]; ! 188: ! 189: ! 190: /* ! 191: * The following array contains the initial settings for ! 192: * the Display Processor Control Block Registers. ! 193: * The video timing signals in this array are for the ! 194: * Bell Technologies Blit Express running in 1664 x 1200 x 1 mode. ! 195: * Please treat as read-only. ! 196: */ ! 197: ! 198: DPCONTROLBLK blit_mparm = { ! 199: DP_DSP_ON, /* video status */ ! 200: 0x00ff, /* interrupt mask - all disabled */ ! 201: 0x0010, /* trip point */ ! 202: 0x00ff, /* frame interrupt interval */ ! 203: 0x0000, /* reserved */ ! 204: CRTM_NONINTER | CRTM_SUPHIGH_SPEED, /* CRT controller mode */ ! 205: 41, /* horizontal synch stop */ ! 206: 57, /* horiz field start */ ! 207: 265, /* horiz field stop */ ! 208: 265, /* line length */ ! 209: 15, /* vert synch stop */ ! 210: 43, /* vert field start */ ! 211: 1243, /* vert field stop */ ! 212: 1244, /* frame length */ ! 213: 0x0000, 0x0000, /* descriptor pointer */ ! 214: 0x0000, /* reserved */ ! 215: 0x0101, /* x, y zoom factors */ ! 216: 0x0000, /* FldColor */ ! 217: 0x00ff, /* BdrColor */ ! 218: 0x0000, /* 1Bpp Pad */ ! 219: 0x0000, /* 2Bpp Pad */ ! 220: 0x0000, /* 4Bpp Pad */ ! 221: DP_CURSOR_CROSSHAIR, /* cursor style & mode */ ! 222: 0x00A0, 0x0050, /* cursor x & y loc. */ ! 223: /* cursor pattern */ ! 224: 0xfffe, 0xfffc, 0xc018, 0xc030, 0xc060, 0xc0c0, 0xc0c0, 0xc060, ! 225: 0xc430, 0xce18, 0xdb0c, 0xf186, 0xe0c3, 0xc066, 0x803c, 0x0018 ! 226: }; ! 227: ! 228: void blitreboot(); ! 229: ! 230: /*********** ! 231: * ! 232: * Initialization. ! 233: * ! 234: ***********/ ! 235: ! 236: ! 237: /* ! 238: * Probe - is the board there? ! 239: * ! 240: * in: reg = start of mapped Blit memory. ! 241: * ! 242: * out: returns size of mapped Blit memory if the board is present, ! 243: * 0 otherwise. ! 244: * ! 245: * effects: if the board is present, it is reset and left visible in ! 246: * Unix mode. ! 247: */ ! 248: ! 249: #if AUTOINIT ! 250: /*ARGSUSED*/ ! 251: int ! 252: blitprobe(reg, unit) ! 253: caddr_t reg; ! 254: int unit; ! 255: { ! 256: struct blitdev *blt = (struct blitdev *)reg; ! 257: ! 258: if (blit_present()) ! 259: return(BLIT_MAPPED_SIZE); /* go */ ! 260: else ! 261: return(0); /* no-go */ ! 262: } ! 263: #endif /* AUTOINIT */ ! 264: ! 265: ! 266: /* ! 267: * Temporary initialization routine. This will go away when we have ! 268: * autoconfig. ! 269: */ ! 270: ! 271: blitinit() ! 272: { ! 273: if (!blit_present()) ! 274: return; ! 275: ! 276: blit_init(); ! 277: } ! 278: ! 279: ! 280: /* ! 281: * Allocate needed objects from Blit's memory. ! 282: */ ! 283: blit_memory_init(bs) ! 284: struct blitsoft *bs; ! 285: { ! 286: struct blitdev *blt = bs->blt; ! 287: struct blitmem *bm = (struct blitmem *)blt->graphmem; ! 288: u_char *p = bm->spare; ! 289: ! 290: if ((int)p % 2 == 1) ! 291: ++p; ! 292: ! 293: bs->scrstrip = (struct screen_descrip *)p; ! 294: p += sizeof(struct screen_descrip); ! 295: if ((int)p % 2 == 1) ! 296: ++p; ! 297: ! 298: bs->dpctlregs = (DPCONTROLBLK *)p; ! 299: p += sizeof(DPCONTROLBLK); ! 300: if ((int)p % 2 == 1) ! 301: ++p; ! 302: ! 303: /* ! 304: * Note: if you use the 786 graphics processor for character ! 305: * processing, you should copy the font from the ROM into ! 306: * graphics memory and change font_start to point to it. ! 307: * Otherwise, the 786 will have problems accessing the font. ! 308: */ ! 309: ! 310: bs->firstfree = p - blt->graphmem; ! 311: } ! 312: ! 313: ! 314: /* ! 315: * Reset the Blit board and leave it visible. ! 316: */ ! 317: ! 318: blit_reset_board() ! 319: { ! 320: union blit_config_reg config; ! 321: ! 322: config.byte = inb(BLIT_CONFIG_ADDR); ! 323: config.reg.reset = 1; ! 324: outb(BLIT_CONFIG_ADDR, config.byte); ! 325: config.reg.reset = 0; ! 326: config.reg.mode = BLIT_UNIX_MODE; ! 327: config.reg.invisible = BLIT_VISIBLE; ! 328: outb(BLIT_CONFIG_ADDR, config.byte); ! 329: setstatus(CARD_RESET); ! 330: } ! 331: ! 332: ! 333: #if AUTOINIT ! 334: /* ! 335: * Attach - finish initialization by setting up the 786. ! 336: */ ! 337: ! 338: blitattach(md) ! 339: struct mb_device *md; ! 340: { ! 341: struct blitdev *blt = (struct blitdev *)md->md_addr; ! 342: ! 343: blit_init(xyz); ! 344: } ! 345: #endif /* AUTOINIT */ ! 346: ! 347: ! 348: /* ! 349: * Initialize Bus Interface Unit. ! 350: */ ! 351: ! 352: init_biu(blt) ! 353: struct blitdev *blt; ! 354: { ! 355: WRITEREG8(blt, INTER_RELOC, 0); ! 356: WRITEREG8(blt, BIU_CONTROL, BIU_16BIT); ! 357: ! 358: /* WRITEREG16(blt, DRAM_REFRESH, 0x003f); */ ! 359: WRITEREG16(blt, DRAM_REFRESH, 0x0018); /* refresh rate */ ! 360: WRITEREG16(blt, DRAM_CONTROL, ! 361: MEMROWS1 | FASTPG_INTERLV | HEIGHT_256K); ! 362: WRITEREG16(blt, DP_PRIORITY, (7 << 3) | 7); /* max pri */ ! 363: WRITEREG16(blt, GP_PRIORITY, (1 << 3) | 1); /* almost min pri */ ! 364: WRITEREG16(blt, EXT_PRIORITY, 5 << 3); ! 365: ! 366: /* now freeze the settings */ ! 367: WRITEREG16(blt, BIU_CONTROL, BIU_16BIT | BIU_WP1); ! 368: ! 369: /* Put graphics processor into Poll state. */ ! 370: WRITEREG16(blt, GP_OPCODE_REG, (OP_LINK|GECL)); ! 371: } ! 372: ! 373: ! 374: /* ! 375: * Initialize the Display Processor. ! 376: * XXX - assumes only 1 card is installed, assumes monochrome display. ! 377: */ ! 378: ! 379: init_dp(bs) ! 380: struct blitsoft *bs; ! 381: { ! 382: struct blitdev *blt = bs->blt; ! 383: struct blitmem *bm = (struct blitmem *)blt->graphmem; ! 384: ! 385: /* ! 386: * Set up strip header and tile descriptor for the whole ! 387: * screen. It's not clear why the C bit should be turned on, ! 388: * but it seems to get rid of the nasty flickering you can get ! 389: * by positioning an xterm window along the top of the screen. ! 390: */ ! 391: bs->scrstrip->strip.lines = BLIT_MONOHEIGHT - 1; ! 392: bs->scrstrip->strip.linkl = 0; ! 393: bs->scrstrip->strip.linkh = 0; ! 394: bs->scrstrip->strip.tiles = DP_C_BIT | (1 - 1); ! 395: tiledesc(&bs->scrstrip->tile, ! 396: 0, 0, /* x, y */ ! 397: BLIT_MONOWIDTH, /* width of strip */ ! 398: BLIT_MONOWIDTH, /* width of bitmap */ ! 399: VM_TO_ADDR786(bm->fb.mono_fb, blt), /* the actual bitmap */ ! 400: 1); /* bits per pixel */ ! 401: ! 402: /* Copy into DP register block. */ ! 403: *(bs->dpctlregs) = blit_mparm; ! 404: bs->dpctlregs->descl = DP_ADDRLOW(VM_TO_ADDR786(bs->scrstrip, blt)); ! 405: bs->dpctlregs->desch = DP_ADDRHIGH(VM_TO_ADDR786(bs->scrstrip, blt)); ! 406: ! 407: /* Load the DP with the register block */ ! 408: loadall(blt, bs->dpctlregs); ! 409: } ! 410: ! 411: ! 412: /* ! 413: * Fill in a tile descriptor. ! 414: */ ! 415: ! 416: static ! 417: tiledesc(tile, x, y, w, ww, adx, bpp) ! 418: TILEDESC *tile; /* pointer to tile descriptor */ ! 419: int x; /* starting x in bitmap */ ! 420: int y; /* starting y in bitmap */ ! 421: int w; /* width of strip (in bits_) */ ! 422: int ww; /* actual width of bitmap (bits) */ ! 423: addr786_t adx; /* start of bitmap */ ! 424: int bpp; /* bits per pixel */ ! 425: { ! 426: u_short bm_width; ! 427: short rghtp; ! 428: short adr_left, adr_right; ! 429: addr786_t bmstadr; ! 430: u_short start_stop_bit; ! 431: ! 432: bm_width = 2 * (((ww + 1) * bpp) / 16); ! 433: rghtp = x + w - 1; ! 434: adr_left = ((x * bpp) / 16) * 2; ! 435: adr_right = ((rghtp * bpp) / 16) * 2; ! 436: bmstadr = (ww * y) + adr_left + (int)adx; ! 437: start_stop_bit = ((((16 - 1) - ((x * bpp) % 16)) << 4) + ! 438: ((16 - ((rghtp + 1) * bpp) % 16) % 16) + ! 439: (bpp << 8)); ! 440: ! 441: tile->bitmapw = bm_width; ! 442: tile->meml = DP_ADDRLOW(bmstadr); ! 443: tile->memh = DP_ADDRHIGH(bmstadr); ! 444: tile->bppss = start_stop_bit; ! 445: tile->fetchcnt = adr_right - adr_left; ! 446: tile->flags = 0; ! 447: } ! 448: ! 449: ! 450: /* ! 451: * Cause the Display Processor to load its Control Registers from ! 452: * "vm_addr". ! 453: */ ! 454: ! 455: static ! 456: loadall(blt, vm_addr) ! 457: struct blitdev *blt; ! 458: DPCONTROLBLK *vm_addr; ! 459: { ! 460: addr786_t blit_addr = VM_TO_ADDR786(vm_addr, blt); ! 461: int i; ! 462: ! 463: /* set up dp address */ ! 464: WRITEREG16(blt, DP_PARM1_REG, DP_ADDRLOW(blit_addr)); ! 465: WRITEREG16(blt, DP_PARM2_REG, DP_ADDRHIGH(blit_addr)); ! 466: ! 467: /* set blanking video */ ! 468: WRITEREG16(blt, DEF_VIDEO_REG, 0); ! 469: ! 470: /* load opcode to start dp */ ! 471: WRITEREG16(blt, DP_OPCODE_REG, DP_LOADALL); ! 472: ! 473: /* wait for acceptance */ ! 474: for (i = 0; i < DP_RDYTIMEOUT; ++i) ! 475: if (READREG(blt, DP_OPCODE_REG) & DECL) ! 476: break; ! 477: ! 478: if (i >= DP_RDYTIMEOUT) { ! 479: printf("Blit Display Processor timeout (loading registers)\n"); ! 480: hang: ! 481: goto hang; ! 482: } ! 483: ! 484: #ifdef notdef ! 485: /* wait for acceptance */ ! 486: CDELAY((READREG(blt, DP_OPCODE_REG) & DECL) != 0, DP_RDYTIMEOUT); ! 487: if ((READREG(blt, DP_OPCODE_REG) & DECL) == 0) { ! 488: printf("Blit Display Processor timeout (loading registers)\n"); ! 489: hang: ! 490: goto hang; ! 491: } ! 492: #endif /* notdef */ ! 493: } ! 494: ! 495: ! 496: /* ! 497: * blit_present: returns YES if Blit is present. For the first call, ! 498: * the hardware is probed. After that, a flag is used. ! 499: * Sets blitsoft[0].blt and blitsoft[0].physaddr. ! 500: */ ! 501: ! 502: #define TEST_BYTE 0xa5 /* should not be all 0's or 1's */ ! 503: ! 504: boolean_t ! 505: blit_present() ! 506: { ! 507: static boolean_t present = FALSE; ! 508: static boolean_t initialized = FALSE; ! 509: struct blitdev *blt; ! 510: boolean_t blit_rom_ok(); ! 511: struct blitdev *mapblit(); ! 512: void freeblit(); ! 513: ! 514: /* ! 515: * We set "initialized" early on so that if the Blit init. code ! 516: * fails, kdb will still be able to use the EGA or VGA display ! 517: * (if present). ! 518: */ ! 519: if (initialized) ! 520: return(present); ! 521: initialized = TRUE; ! 522: ! 523: blit_reset_board(); ! 524: blt = mapblit((caddr_t)BLIT_BASE_ADDR, BLIT_MAPPED_SIZE); ! 525: setstatus(CARD_MAPPED); ! 526: if (blt == NULL) ! 527: panic("blit: can't map display"); ! 528: blt->graphmem[0] = TEST_BYTE; ! 529: present = FALSE; ! 530: if (blt->graphmem[0] == TEST_BYTE) { ! 531: setstatus(CARD_MAYBE_PRESENT); ! 532: present = blit_rom_ok(blt); ! 533: } ! 534: if (present) { ! 535: blitsoft[0].blt = blt; ! 536: blitsoft[0].physaddr = (caddr_t)BLIT_BASE_ADDR; ! 537: setstatus(CARD_PRESENT); ! 538: } ! 539: else ! 540: freeblit((vm_offset_t)blt, BLIT_MAPPED_SIZE); ! 541: return(present); ! 542: } ! 543: ! 544: #undef TEST_BYTE ! 545: ! 546: ! 547: /* ! 548: * mapblit: map the card into kernel vm and return the (virtual) ! 549: * address. ! 550: */ ! 551: struct blitdev * ! 552: mapblit(physaddr, length) ! 553: caddr_t physaddr; /* start of card */ ! 554: int length; /* num bytes to map */ ! 555: { ! 556: vm_offset_t vmaddr; ! 557: #ifdef MACH_KERNEL ! 558: vm_offset_t io_map(); ! 559: #else MACH_KERNEL ! 560: vm_offset_t pmap_map_bd(); ! 561: #endif MACH_KERNEL ! 562: ! 563: if (physaddr != (caddr_t)trunc_page(physaddr)) ! 564: panic("Blit card not on page boundary"); ! 565: ! 566: #ifdef MACH_KERNEL ! 567: vmaddr = io_map((vm_offset_t)physaddr, length); ! 568: if (vmaddr == 0) ! 569: #else MACH_KERNEL ! 570: if (kmem_alloc_pageable(kernel_map, ! 571: &vmaddr, round_page(BLIT_MAPPED_SIZE)) ! 572: != KERN_SUCCESS) ! 573: #endif MACH_KERNEL ! 574: panic("can't alloc VM for Blit card"); ! 575: ! 576: (void)pmap_map_bd(vmaddr, (vm_offset_t)physaddr, ! 577: (vm_offset_t)physaddr+length, ! 578: VM_PROT_READ | VM_PROT_WRITE); ! 579: return((struct blitdev *)vmaddr); ! 580: } ! 581: ! 582: ! 583: /* ! 584: * freeblit: free card from memory. ! 585: * XXX - currently a no-op. ! 586: */ ! 587: void ! 588: freeblit(va, length) ! 589: vm_offset_t va; /* virt addr start of card */ ! 590: int length; ! 591: { ! 592: } ! 593: ! 594: ! 595: /* ! 596: * blit_init: initialize globals & hardware, and set cursor. Could be ! 597: * called twice, once as part of kd initialization and once as part of ! 598: * blit initialization. Should not be called before blit_present() is ! 599: * called. ! 600: */ ! 601: ! 602: void ! 603: blit_init() ! 604: { ! 605: static boolean_t initialized = FALSE; ! 606: struct blitmem *gmem; /* start of blit graphics memory */ ! 607: int card; ! 608: void getfontinfo(), clear_blit(); ! 609: ! 610: if (initialized) ! 611: return; ! 612: ! 613: for (card = 0; card < NBLIT; ++card) { ! 614: if (card > 0) { ! 615: blitsoft[card].blt = NULL; ! 616: blitsoft[card].physaddr = NULL; ! 617: } ! 618: blitsoft[card].open = FALSE; ! 619: blitsoft[card].scrstrip = NULL; ! 620: blitsoft[card].dpctlregs = NULL; ! 621: blitsoft[card].firstfree = 0; ! 622: } ! 623: ! 624: /* ! 625: * blit_memory_init allocates memory used by the Display Processor, ! 626: * so it comes before the call to init_dp. blit_memory_init ! 627: * potentially copies the font from ROM into the graphics memory, ! 628: * so it comes after the call to getfontinfo. ! 629: */ ! 630: getfontinfo(blitsoft[0].blt); /* get info & check assumptions */ ! 631: blit_memory_init(&blitsoft[0]); ! 632: ! 633: /* init 786 */ ! 634: init_biu(blitsoft[0].blt); ! 635: setstatus(BIU_INIT); ! 636: init_dp(&blitsoft[0]); ! 637: setstatus(DP_INIT); ! 638: ! 639: gmem = (struct blitmem *)blitsoft[0].blt->graphmem; ! 640: vid_start = gmem->fb.mono_fb; ! 641: kd_lines = 25; ! 642: kd_cols = 80; ! 643: kd_attr = KA_NORMAL; ! 644: ! 645: /* ! 646: * Use generic bitmap routines, no 786 assist (see ! 647: * blit_memory_init). ! 648: */ ! 649: kd_dput = bmpput; ! 650: kd_dmvup = bmpmvup; ! 651: kd_dmvdown = bmpmvdown; ! 652: kd_dclear = bmpclear; ! 653: kd_dsetcursor = bmpsetcursor; ! 654: kd_dreset = blitreboot; ! 655: ! 656: clear_blit(blitsoft[0].blt); ! 657: (*kd_dsetcursor)(0); ! 658: ! 659: initialized = TRUE; ! 660: } ! 661: ! 662: ! 663: /* ! 664: * blit_rom_ok: make sure we're looking at the ROM for a monochrome ! 665: * Blit. ! 666: */ ! 667: ! 668: boolean_t ! 669: blit_rom_ok(blt) ! 670: struct blitdev *blt; ! 671: { ! 672: short magic; ! 673: short bpp; ! 674: ! 675: magic = READROM(blt->eprom, EP_MAGIC1); ! 676: if (magic != EP_MAGIC1_VAL) { ! 677: #ifdef notdef ! 678: printf("blit: magic1 bad (0x%x)\n", magic); ! 679: #endif ! 680: return(FALSE); ! 681: } ! 682: magic = READROM(blt->eprom, EP_MAGIC2); ! 683: if (magic != EP_MAGIC2_VAL) { ! 684: #ifdef notdef ! 685: printf("blit: magic2 bad (0x%x)\n", magic); ! 686: #endif ! 687: return(FALSE); ! 688: } ! 689: bpp = READROM(blt->eprom, EP_BPP); ! 690: if (bpp != 1) { ! 691: #ifdef notdef ! 692: printf("blit: not monochrome board (bpp = 0x%x)\n", bpp); ! 693: #endif ! 694: return(FALSE); ! 695: } ! 696: ! 697: return(TRUE); ! 698: } ! 699: ! 700: ! 701: /* ! 702: * getfontinfo: get information about the font and make sure that ! 703: * our simplifying assumptions are valid. ! 704: */ ! 705: ! 706: void ! 707: getfontinfo(blt) ! 708: struct blitdev *blt; ! 709: { ! 710: u_char *rom = blt->eprom; ! 711: short fontoffset; ! 712: short pick_cursor_height(); ! 713: ! 714: fb_width = BLIT_MONOWIDTH; ! 715: fb_height = BLIT_MONOHEIGHT; ! 716: chars_in_font = READROM(rom, EP_NUMCHARS); ! 717: char_width = READROM(rom, EP_CHARWIDTH); ! 718: char_height = READROM(rom, EP_CHARHEIGHT); ! 719: fontoffset = READROM(rom, EP_FONTSTART); ! 720: xstart = READROM(rom, EP_XSTART); ! 721: ystart = READROM(rom, EP_YSTART); ! 722: char_black = BLIT_BLACK_BYTE; ! 723: char_white = BLIT_WHITE_BYTE; ! 724: ! 725: font_start = rom + fontoffset; ! 726: ! 727: /* ! 728: * Check byte-alignment assumption. ! 729: * XXX - does it do any good to panic when initializing the ! 730: * console driver? ! 731: */ ! 732: if (char_width % 8 != 0) ! 733: panic("blit: char width not integral num of bytes"); ! 734: if (xstart % 8 != 0) { ! 735: /* move it to a more convenient location */ ! 736: printf("blit: console corner moved.\n"); ! 737: xstart = 8 * (xstart/8); ! 738: } ! 739: ! 740: cursor_height = pick_cursor_height(); ! 741: char_byte_width = char_width / 8; ! 742: fb_byte_width = BLIT_MONOWIDTH / 8; ! 743: font_byte_width = char_byte_width * chars_in_font; ! 744: } ! 745: ! 746: ! 747: /* ! 748: * pick_cursor_height: pick a size for the cursor, based on the font ! 749: * size. ! 750: */ ! 751: ! 752: short ! 753: pick_cursor_height() ! 754: { ! 755: int scl_avail; /* scan lines available for console */ ! 756: int scl_per_line; /* scan lines per console line */ ! 757: ! 758: /* ! 759: * scan lines avail. = total lines - top margin; ! 760: * no bottom margin (XXX). ! 761: */ ! 762: scl_avail = BLIT_MONOHEIGHT - ystart; ! 763: ! 764: scl_per_line = scl_avail / kd_lines; ! 765: if (scl_per_line < char_height) ! 766: return(1); ! 767: else ! 768: return(scl_per_line - char_height); ! 769: } ! 770: ! 771: ! 772: /* ! 773: * setstatus: Give a status indication to the user. Ideally, we'd ! 774: * just set the 3 user-controlled LED's. Unfortunately, that doesn't ! 775: * seem to work. So, we ring the bell. ! 776: */ ! 777: ! 778: static void ! 779: setstatus(val) ! 780: int val; ! 781: { ! 782: union blit_diag_reg diag; ! 783: ! 784: diag.byte = inb(BLIT_DIAG_ADDR); ! 785: diag.reg.led0 = (val & 1) ? BLIT_LED_ON : BLIT_LED_OFF; ! 786: diag.reg.led1 = (val & 2) ? BLIT_LED_ON : BLIT_LED_OFF; ! 787: diag.reg.led2 = (val & 4) ? BLIT_LED_ON : BLIT_LED_OFF; ! 788: outb(BLIT_DIAG_ADDR, diag.byte); ! 789: ! 790: #ifdef DEBUG ! 791: for (val &= 7; val > 0; val--) { ! 792: feep(); ! 793: pause(); ! 794: } ! 795: for (val = 0; val < 10; val++) { ! 796: pause(); ! 797: } ! 798: #endif ! 799: } ! 800: ! 801: ! 802: ! 803: /*********** ! 804: * ! 805: * Other (non-initialization) routines. ! 806: * ! 807: ***********/ ! 808: ! 809: ! 810: /* ! 811: * Open - Verify that minor device is OK and not in use, then clear ! 812: * the screen. ! 813: */ ! 814: ! 815: /*ARGSUSED*/ ! 816: int ! 817: blitopen(dev, flag) ! 818: dev_t dev; ! 819: int flag; ! 820: { ! 821: void clear_blit(); ! 822: int which = minor(dev); ! 823: ! 824: if (!blit_present() || which >= NBLIT) ! 825: return(ENXIO); ! 826: if (blitsoft[which].open) ! 827: return(EBUSY); ! 828: ! 829: clear_blit(blitsoft[which].blt); ! 830: blitsoft[which].open = TRUE; ! 831: return(0); /* ok */ ! 832: } ! 833: ! 834: ! 835: /* ! 836: * Close - free any kernel memory structures that were allocated while ! 837: * the device was open (currently none). ! 838: */ ! 839: ! 840: /*ARGSUSED*/ ! 841: blitclose(dev, flag) ! 842: dev_t dev; ! 843: int flag; ! 844: { ! 845: int which = minor(dev); ! 846: ! 847: if (!blitsoft[which].open) ! 848: panic("blit: closing not-open device??"); ! 849: blitsoft[which].open = FALSE; ! 850: } ! 851: ! 852: ! 853: /* ! 854: * Mmap. ! 855: */ ! 856: ! 857: /*ARGSUSED*/ ! 858: int ! 859: blitmmap(dev, off, prot) ! 860: dev_t dev; ! 861: off_t off; ! 862: int prot; ! 863: { ! 864: if ((u_int) off >= BLIT_MAPPED_SIZE) ! 865: return(-1); ! 866: ! 867: /* Get page frame number for the page to be mapped. */ ! 868: return(i386_btop(blitsoft[minor(dev)].physaddr + off)); ! 869: } ! 870: ! 871: ! 872: /* ! 873: * Ioctl. ! 874: */ ! 875: ! 876: #ifdef MACH_KERNEL ! 877: io_return_t blit_get_stat(dev, flavor, data, count) ! 878: dev_t dev; ! 879: int flavor; ! 880: int *data; /* pointer to OUT array */ ! 881: unsigned int *count; /* OUT */ ! 882: { ! 883: int which = minor(dev); ! 884: ! 885: switch (flavor) { ! 886: case BLIT_1ST_UNUSED: ! 887: if (*count < 1) ! 888: return (D_INVALID_OPERATION); ! 889: *data = blitsoft[which].firstfree; ! 890: *count = 1; ! 891: break; ! 892: default: ! 893: return (D_INVALID_OPERATION); ! 894: } ! 895: return (D_SUCCESS); ! 896: } ! 897: #else MACH_KERNEL ! 898: /*ARGSUSED*/ ! 899: int ! 900: blitioctl(dev, cmd, data, flag) ! 901: dev_t dev; ! 902: int cmd; ! 903: caddr_t data; ! 904: int flag; ! 905: { ! 906: int which = minor(dev); ! 907: int err = 0; ! 908: ! 909: switch (cmd) { ! 910: case BLIT_1ST_UNUSED: ! 911: *(int *)data = blitsoft[which].firstfree; ! 912: break; ! 913: default: ! 914: err = ENOTTY; ! 915: } ! 916: ! 917: return(err); ! 918: } ! 919: #endif MACH_KERNEL ! 920: ! 921: /* ! 922: * clear_blit: clear blit's screen. ! 923: */ ! 924: ! 925: void ! 926: clear_blit(blt) ! 927: struct blitdev *blt; ! 928: { ! 929: (*kd_dclear)(0, kd_lines*kd_cols, KA_NORMAL); ! 930: } ! 931: ! 932: /* ! 933: * Put the board into DOS mode in preparation for rebooting. ! 934: */ ! 935: ! 936: void ! 937: blitreboot() ! 938: { ! 939: union blit_config_reg config; ! 940: ! 941: config.byte = inb(BLIT_CONFIG_ADDR); ! 942: config.reg.mode = BLIT_DOS_MODE; ! 943: config.reg.invisible = BLIT_VISIBLE; ! 944: outb(BLIT_CONFIG_ADDR, config.byte); ! 945: } ! 946: ! 947: #endif /* NBLIT > 0 */ ! 948: #endif /* NBLIT > MAXBLITS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.