|
|
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: * File: pm_misc.c ! 28: * Author: Alessandro Forin, Carnegie Mellon University ! 29: * Date: 9/90 ! 30: * ! 31: * Driver for the VFB01/02 Mono/Color framebuffer (pmax) ! 32: * Hardware-independent operations, mostly shared with ! 33: * the CFB driver (see each individual function header), ! 34: * and possibly others. ! 35: */ ! 36: ! 37: ! 38: #include <platforms.h> ! 39: ! 40: #include <fb.h> ! 41: ! 42: #if defined(DECSTATION) || defined(FLAMINGO) ! 43: #include <cfb.h> ! 44: #include <mfb.h> ! 45: #include <xcfb.h> ! 46: #include <sfb.h> ! 47: #define NPM (NFB+NCFB+NMFB+NXCFB+NSFB) ! 48: #endif /*DECSTATION*/ ! 49: ! 50: #ifdef VAXSTATION ! 51: #define NPM (NFB) ! 52: #endif /*VAXSTATION*/ ! 53: ! 54: ! 55: #if (NPM > 0) ! 56: ! 57: #include <mach/vm_param.h> /* PAGE_SIZE */ ! 58: #include <device/device_types.h> ! 59: #include <vm/vm_map.h> /* kernel_pmap */ ! 60: ! 61: #include <chips/screen_defs.h> ! 62: #include <chips/pm_defs.h> ! 63: ! 64: ! 65: #ifdef DECSTATION ! 66: #define machine_btop mips_btop ! 67: #define MONO_BM (256*1024) ! 68: #endif /*DECSTATION*/ ! 69: ! 70: #ifdef VAXSTATION ! 71: #define machine_btop vax_btop ! 72: /* ! 73: For now we use the last page of the frame for ! 74: the user_info structure. ! 75: */ ! 76: #define MONO_BM (256*1024-PAGE_SIZE) ! 77: #endif /*VAXSTATION*/ ! 78: ! 79: #ifdef FLAMINGO ! 80: #define machine_btop alpha_btop ! 81: #define MONO_BM (256*1024) ! 82: #define LOG2_SIZEOF_LONG 3 /* 64bit archies */ ! 83: #endif /* FLAMINGO */ ! 84: ! 85: #ifndef LOG2_SIZEOF_LONG ! 86: #define LOG2_SIZEOF_LONG 2 /* 32bit archies */ ! 87: #endif ! 88: ! 89: ! 90: /* Hardware state */ ! 91: pm_softc_t pm_softc_data[NPM]; ! 92: ! 93: pm_softc_t* ! 94: pm_alloc( ! 95: int unit, ! 96: char *cur, ! 97: unsigned char *fb, ! 98: unsigned char *pl) ! 99: { ! 100: pm_softc_t *pm = &pm_softc_data[unit]; ! 101: ! 102: pm->cursor_registers = cur; ! 103: pm->framebuffer = fb; ! 104: pm->plane_mask = pl; ! 105: pm->vdac_registers = 0; /* later, if ever */ ! 106: ! 107: screen_attach(unit, (char *) pm); ! 108: ! 109: return pm; ! 110: } ! 111: ! 112: ! 113: /* ! 114: * Routine to paint a char on a simple framebuffer. ! 115: * This is common to the pm, fb and cfb drivers. ! 116: */ ! 117: pm_char_paint( ! 118: screen_softc_t sc, ! 119: int c, ! 120: int row, ! 121: int col) ! 122: { ! 123: register int incr; ! 124: int line_size; ! 125: register unsigned char *font, *bmap; ! 126: pm_softc_t *pm = (pm_softc_t*)sc->hw_state; ! 127: ! 128: /* ! 129: * Here are the magic numbers that drive the loops below: ! 130: * incr bytes between scanlines of the glyph ! 131: * line_size bytes in a row, using the system font ! 132: * ! 133: * This code has been optimized to avoid multiplications, ! 134: * and is therefore much less obvious than it could be. ! 135: */ ! 136: if (sc->flags & MONO_SCREEN) { ! 137: /* ! 138: * B&W screen: 1 bit/pixel ! 139: * incr --> 1 * BytesPerLine, with possible stride ! 140: */ ! 141: incr = sc->frame_scanline_width >> 3; ! 142: } else { ! 143: /* ! 144: * Color screen: 8 bits/pixel ! 145: * incr --> 8 * BytesPerLine, with possible stride ! 146: */ ! 147: incr = sc->frame_scanline_width; ! 148: col <<= 3; ! 149: } ! 150: ! 151: /* not all compilers are smart about multiply by 15 */ ! 152: #if (KfontHeight==15) ! 153: # define TIMES_KfontHeight(w) (((w)<<4)-(w)) ! 154: #else ! 155: # define TIMES_KfontHeight(w) ((w)*KfontHeight) ! 156: #endif ! 157: line_size = TIMES_KfontHeight(incr); ! 158: ! 159: bmap = pm->framebuffer + col + (row * line_size); ! 160: font = &kfont_7x14[ (int)(c - ' ') * 15]; ! 161: if (sc->flags & MONO_SCREEN) { ! 162: /* ! 163: * Unroll simple loops, take note of common cases ! 164: */ ! 165: if (sc->standout) { ! 166: # define mv() *bmap = ~*font++; bmap += incr; ! 167: mv();mv();mv();mv();mv();mv();mv();mv(); ! 168: mv();mv();mv();mv();mv();mv();mv(); ! 169: # undef mv ! 170: } else if (c == ' ') { ! 171: # define mv() *bmap = 0; bmap += incr; ! 172: mv();mv();mv();mv();mv();mv();mv();mv(); ! 173: mv();mv();mv();mv();mv();mv();mv(); ! 174: # undef mv ! 175: } else { ! 176: # define mv() *bmap = *font++; bmap += incr; ! 177: mv();mv();mv();mv();mv();mv();mv();mv(); ! 178: mv();mv();mv();mv();mv();mv();mv(); ! 179: # undef mv ! 180: } ! 181: } else { ! 182: /* ! 183: * 8 bits per pixel --> paint one byte per each font bit. ! 184: * In order to spread out the 8 bits of a glyph line over ! 185: * the 64 bits per scanline use a simple vector multiply, ! 186: * taking 4 bits at a time to get the two resulting words ! 187: */ ! 188: static unsigned int spread[16] = { ! 189: 0x00000000, 0x00000001, 0x00000100, 0x00000101, ! 190: 0x00010000, 0x00010001, 0x00010100, 0x00010101, ! 191: 0x01000000, 0x01000001, 0x01000100, 0x01000101, ! 192: 0x01010000, 0x01010001, 0x01010100, 0x01010101, ! 193: }; ! 194: register int rev_video = sc->standout; ! 195: register int j; ! 196: for (j = 0; j < KfontHeight; j++) { ! 197: register unsigned char c = *font++; ! 198: if (rev_video) c = ~c; ! 199: #if (LOG2_SIZEOF_LONG==3) ! 200: *((long*)bmap) = (long)spread[ c & 0xf ] | ! 201: ((long)(spread[ (c>>4) & 0xf ]) << 32); ! 202: #else ! 203: ((int*)bmap)[0] = spread[ c & 0xf ]; ! 204: ((int*)bmap)[1] = spread[ (c>>4) & 0xf ]; ! 205: #endif ! 206: bmap += incr; ! 207: } ! 208: } ! 209: } ! 210: ! 211: /* ! 212: * Delete the line at the given row. ! 213: * This is common to the pm, fb and cfb drivers. ! 214: */ ! 215: pm_remove_line( ! 216: screen_softc_t sc, ! 217: short row) ! 218: { ! 219: register long *dest, *src; ! 220: register long *end; ! 221: register long temp0,temp1,temp2,temp3; ! 222: register long i, scaninc, blockcnt; ! 223: long line_size, incr; ! 224: unsigned char *framebuffer; ! 225: pm_softc_t *pm = (pm_softc_t*)sc->hw_state; ! 226: long CharRows, CharCols; ! 227: ! 228: CharRows = sc->up->max_row; ! 229: CharCols = sc->up->max_col; ! 230: framebuffer = pm->framebuffer; ! 231: ! 232: /* Inner loop works 4 long words at a time (writebuffer deep) */ ! 233: # define BlockSizeShift (2+LOG2_SIZEOF_LONG) ! 234: ! 235: /* To copy one (MONO) line, we need to iterate this many times */ ! 236: # define Blocks (CharCols>>BlockSizeShift) ! 237: ! 238: /* Skip this many bytes to get to the next line */ ! 239: # define Slop(w) ((w) - (blockcnt<<BlockSizeShift)) ! 240: ! 241: if (sc->flags & MONO_SCREEN) { ! 242: blockcnt = Blocks; ! 243: /* See comments in pm_char_paint() */ ! 244: incr = sc->frame_scanline_width >> 3; ! 245: } else { ! 246: blockcnt = Blocks << 3; ! 247: /* See comments in pm_char_paint() */ ! 248: incr = sc->frame_scanline_width; ! 249: } ! 250: line_size = TIMES_KfontHeight(incr); ! 251: ! 252: scaninc = (Slop(incr)) >> LOG2_SIZEOF_LONG; /* pointers are long* */ ! 253: ! 254: dest = (long *)(framebuffer + row * line_size); ! 255: src = (long *)((char*)dest + line_size); ! 256: end = (long *)(framebuffer + CharRows * line_size); ! 257: while (src < end) { ! 258: i = 0; ! 259: do { ! 260: temp0 = src[0]; ! 261: temp1 = src[1]; ! 262: temp2 = src[2]; ! 263: temp3 = src[3]; ! 264: dest[0] = temp0; ! 265: dest[1] = temp1; ! 266: dest[2] = temp2; ! 267: dest[3] = temp3; ! 268: dest += 4; ! 269: src += 4; ! 270: i++; ! 271: } while (i < blockcnt); ! 272: src += scaninc; ! 273: dest += scaninc; ! 274: } ! 275: ! 276: /* Now zero out the last line */ ! 277: bzero(framebuffer + (CharRows - 1) * line_size, line_size); ! 278: ! 279: ascii_screen_rem_update(sc, row); ! 280: } ! 281: ! 282: ! 283: /* ! 284: * Open a new blank line at the given row. ! 285: * This is common to the pm, fb and cfb drivers. ! 286: */ ! 287: pm_insert_line( ! 288: screen_softc_t sc, ! 289: short row) ! 290: { ! 291: register long *dest, *src; ! 292: register long *end; ! 293: register long temp0,temp1,temp2,temp3; ! 294: register long i, scaninc, blockcnt; ! 295: long line_size, incr; ! 296: unsigned char *framebuffer; ! 297: pm_softc_t *pm = (pm_softc_t*)sc->hw_state; ! 298: long CharRows, CharCols; ! 299: ! 300: CharRows = sc->up->max_row; ! 301: CharCols = sc->up->max_col; ! 302: ! 303: framebuffer = pm->framebuffer; ! 304: ! 305: /* See above for comments */ ! 306: if (sc->flags & MONO_SCREEN) { ! 307: blockcnt = Blocks; ! 308: /* See comments in pm_char_paint() */ ! 309: incr = sc->frame_scanline_width >> 3; ! 310: } else { ! 311: blockcnt = Blocks << 3; ! 312: /* See comments in pm_char_paint() */ ! 313: incr = sc->frame_scanline_width; ! 314: } ! 315: line_size = TIMES_KfontHeight(incr); ! 316: ! 317: scaninc = Slop(incr) + ((2 * blockcnt) << BlockSizeShift); ! 318: scaninc >>= LOG2_SIZEOF_LONG; /* pointers are long* */ ! 319: dest = (long *)(framebuffer + (CharRows - 1) * line_size); ! 320: src = (long *)((char*)dest - line_size); ! 321: end = (long *)(framebuffer + row * line_size); ! 322: while (src >= end) { ! 323: i = 0; ! 324: do { ! 325: temp0 = src[0]; ! 326: temp1 = src[1]; ! 327: temp2 = src[2]; ! 328: temp3 = src[3]; ! 329: dest[0] = temp0; ! 330: dest[1] = temp1; ! 331: dest[2] = temp2; ! 332: dest[3] = temp3; ! 333: dest += 4; ! 334: src += 4; ! 335: i++; ! 336: } while (i < blockcnt); ! 337: src -= scaninc; ! 338: dest -= scaninc; ! 339: } ! 340: ! 341: /* Now zero out the line being opened */ ! 342: bzero(framebuffer + row * line_size, line_size); ! 343: ! 344: ascii_screen_ins_update(sc, row); ! 345: } ! 346: ! 347: #undef Slop ! 348: ! 349: ! 350: /* ! 351: * Initialize screen parameters in the ! 352: * user-mapped descriptor. ! 353: * This is common to various drivers. ! 354: */ ! 355: pm_init_screen_params( ! 356: screen_softc_t sc, ! 357: user_info_t *up) ! 358: { ! 359: register int vis_x, vis_y; ! 360: ! 361: up->frame_scanline_width = sc->frame_scanline_width; ! 362: up->frame_height = sc->frame_height; ! 363: ! 364: vis_x = sc->frame_visible_width; ! 365: vis_y = sc->frame_visible_height; ! 366: ! 367: up->max_x = vis_x; ! 368: up->max_y = vis_y; ! 369: up->max_cur_x = vis_x - 1; ! 370: up->max_cur_y = vis_y - 1; ! 371: up->min_cur_x = -15; ! 372: up->min_cur_y = -15; ! 373: up->max_row = vis_y / KfontHeight; ! 374: up->max_col = vis_x / KfontWidth; ! 375: ! 376: up->version = 11; ! 377: ! 378: up->mouse_threshold = 4; ! 379: up->mouse_scale = 2; ! 380: ! 381: up->dev_dep_2.pm.tablet_scale_x = ((vis_x - 1) * 1000) / 2200; ! 382: up->dev_dep_2.pm.tablet_scale_y = ((vis_y - 1) * 1000) / 2200; ! 383: } ! 384: ! 385: /* ! 386: * Clear the screen ! 387: * Used by pm, fb and cfb ! 388: */ ! 389: pm_clear_bitmap( ! 390: screen_softc_t sc) ! 391: { ! 392: pm_softc_t *pm = (pm_softc_t *) sc->hw_state; ! 393: unsigned int screen_size; ! 394: ! 395: /* Do not touch the non visible part */ ! 396: screen_size = sc->frame_scanline_width * sc->frame_visible_height; ! 397: blkclr((char *)pm->framebuffer, ! 398: (sc->flags & MONO_SCREEN) ? (screen_size>>3) : screen_size); ! 399: ! 400: /* clear ascii screenmap */ ! 401: ascii_screen_fill(sc, ' '); ! 402: } ! 403: ! 404: ! 405: /* ! 406: * Size of the user-mapped structure ! 407: * Used by both pm and cfb ! 408: */ ! 409: pm_mem_need() ! 410: { ! 411: return USER_INFO_SIZE; ! 412: } ! 413: ! 414: /* ! 415: * Device-specific get status. ! 416: * Used by fb and cfb also. ! 417: */ ! 418: pm_get_status( ! 419: screen_softc_t sc, ! 420: dev_flavor_t flavor, ! 421: dev_status_t status, ! 422: natural_t *status_count) ! 423: { ! 424: if (flavor == SCREEN_GET_OFFSETS) { ! 425: unsigned *offs = (unsigned *) status; ! 426: ! 427: offs[0] = PM_SIZE(sc); /* virtual size */ ! 428: offs[1] = 0; /* offset of user_info_t */ ! 429: *status_count = 2; ! 430: return D_SUCCESS; ! 431: } else ! 432: return D_INVALID_OPERATION; ! 433: } ! 434: ! 435: /* ! 436: * Driver-specific set status ! 437: * Only partially used by fb and cfb. ! 438: */ ! 439: pm_set_status( ! 440: screen_softc_t sc, ! 441: dev_flavor_t flavor, ! 442: dev_status_t status, ! 443: natural_t status_count) ! 444: { ! 445: switch (flavor) { ! 446: case SCREEN_ADJ_MAPPED_INFO: { ! 447: unsigned user_addr = *(unsigned *) status; ! 448: user_info_t *up = sc->up; ! 449: ! 450: /* Make it point to the event_queue, in user virtual */ ! 451: up->evque.events = (screen_event_t *)(user_addr + ! 452: ((char*)up->event_queue - (char*)up)); ! 453: ! 454: /* Make it point to the point_track, in user virtual */ ! 455: up->evque.track = (screen_timed_point_t *)(user_addr + ! 456: ((char*)up->point_track - (char*)up)); ! 457: ! 458: up->dev_dep_1.pm.planemask = (unsigned char *)(user_addr + USER_INFO_SIZE); ! 459: ! 460: up->dev_dep_1.pm.bitmap = up->dev_dep_1.pm.planemask + PMASK_SIZE; ! 461: ! 462: break; ! 463: } ! 464: ! 465: case SCREEN_LOAD_CURSOR: { ! 466: ! 467: sc->flags |= SCREEN_BEING_UPDATED; ! 468: dc503_load_cursor(sc->hw_state, (unsigned short*)status); ! 469: sc->flags &= ~SCREEN_BEING_UPDATED; ! 470: ! 471: break; ! 472: } ! 473: ! 474: #ifdef DECSTATION ! 475: case SCREEN_SET_CURSOR_COLOR: { ! 476: pm_softc_t *pm = (pm_softc_t*) sc->hw_state; ! 477: ! 478: sc->flags |= SCREEN_BEING_UPDATED; ! 479: bt478_cursor_color (pm->vdac_registers, (cursor_color_t*) status); ! 480: sc->flags &= ~SCREEN_BEING_UPDATED; ! 481: ! 482: break; ! 483: } ! 484: ! 485: case SCREEN_SET_CMAP_ENTRY: { ! 486: pm_softc_t *pm = (pm_softc_t*) sc->hw_state; ! 487: color_map_entry_t *e = (color_map_entry_t*) status; ! 488: ! 489: if (e->index < 256) { ! 490: sc->flags |= SCREEN_BEING_UPDATED; ! 491: bt478_load_colormap_entry( pm->vdac_registers, e->index, &e->value); ! 492: sc->flags &= ~SCREEN_BEING_UPDATED; ! 493: } ! 494: ! 495: break; ! 496: } ! 497: #endif /*DECSTATION*/ ! 498: default: ! 499: return D_INVALID_OPERATION; ! 500: } ! 501: return D_SUCCESS; ! 502: } ! 503: ! 504: /* ! 505: * Map pages to user space ! 506: */ ! 507: vm_offset_t pm_map_page_empty = (vm_offset_t) 0; ! 508: ! 509: integer_t ! 510: pm_map_page( ! 511: screen_softc_t sc, ! 512: vm_offset_t off, ! 513: int prot) ! 514: { ! 515: int bitmapsize; ! 516: integer_t addr; ! 517: pm_softc_t *pm = (pm_softc_t *)sc->hw_state; ! 518: extern vm_offset_t pmap_extract( pmap_t map, vm_offset_t addr); ! 519: ! 520: bitmapsize = BITMAP_SIZE(sc); ! 521: ! 522: #define OFF0 USER_INFO_SIZE /* user mapped info */ ! 523: #define OFF1 OFF0+PMASK_SIZE /* plane mask register */ ! 524: #define OFF2 OFF1+bitmapsize /* frame buffer mem */ ! 525: ! 526: if (off < OFF0) ! 527: #ifdef DECSTATION ! 528: addr = kvtophys(sc->up); ! 529: #else ! 530: addr = (integer_t) pmap_extract(kernel_pmap, ! 531: (vm_offset_t)sc->up); ! 532: #endif ! 533: else ! 534: if (off < OFF1) { ! 535: #ifdef VAXSTATION ! 536: if (pm_map_page_empty == 0) { ! 537: pm_map_page_empty = vm_page_grab_phys_addr(); ! 538: } ! 539: addr = (integer_t)pmap_extract(kernel_pmap, pm_map_page_empty); ! 540: #else ! 541: addr = (integer_t) pm->plane_mask; ! 542: #endif ! 543: off -= OFF0; ! 544: } else ! 545: if (off < OFF2) { ! 546: #ifdef DECSTATION ! 547: addr = (integer_t)pm->framebuffer; ! 548: #else ! 549: addr = (integer_t)pmap_extract(kernel_pmap, ! 550: (vm_offset_t)pm->framebuffer); ! 551: #endif ! 552: off -= OFF1; ! 553: } else ! 554: return D_INVALID_SIZE; /* ??? */ ! 555: ! 556: addr = machine_btop(addr + off); ! 557: return (addr); ! 558: } ! 559: ! 560: ! 561: /* ! 562: *----------------------------------------------------------- ! 563: * The rest of this file is stricly pmax/pvax-specific ! 564: *----------------------------------------------------------- ! 565: */ ! 566: #if (NFB > 0) ! 567: ! 568: /* ! 569: * Do what's needed when the X server exits ! 570: */ ! 571: pm_soft_reset( ! 572: screen_softc_t sc) ! 573: { ! 574: pm_softc_t *pm = (pm_softc_t*) sc->hw_state; ! 575: user_info_t *up = sc->up; ! 576: ! 577: /* ! 578: * Restore params in mapped structure ! 579: */ ! 580: pm_init_screen_params(sc, up); ! 581: up->row = up->max_row - 2; ! 582: dc503_init(pm); ! 583: ! 584: #ifdef DECSTATION ! 585: if (sc->flags & MONO_SCREEN) ! 586: bt478_init_bw_map(pm->vdac_registers, pm->plane_mask); ! 587: else ! 588: bt478_init_color_map(pm->vdac_registers, pm->plane_mask); ! 589: #endif /*DECSTATION*/ ! 590: } ! 591: #endif /* NFB > 0 */ ! 592: ! 593: ! 594: #endif /* NPM > 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.