|
|
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: ims332.c ! 28: * Author: Alessandro Forin, Carnegie Mellon University ! 29: * Date: 1/92 ! 30: * ! 31: * Routines for the Inmos IMS-G332 Colour video controller ! 32: */ ! 33: ! 34: #include <platforms.h> ! 35: ! 36: #include <chips/ims332.h> ! 37: #include <chips/screen.h> ! 38: ! 39: #include <chips/xcfb_monitor.h> ! 40: ! 41: /* ! 42: * Generic register access ! 43: */ ! 44: typedef volatile unsigned char *ims332_padded_regmap_t; ! 45: ! 46: #ifdef MAXINE ! 47: ! 48: unsigned int ! 49: ims332_read_register(regs, regno) ! 50: unsigned char *regs; ! 51: { ! 52: unsigned char *rptr; ! 53: register unsigned int val, v1; ! 54: ! 55: /* spec sez: */ ! 56: rptr = regs + 0x80000 + (regno << 4); ! 57: val = * ((volatile unsigned short *) rptr ); ! 58: v1 = * ((volatile unsigned short *) regs ); ! 59: ! 60: return (val & 0xffff) | ((v1 & 0xff00) << 8); ! 61: } ! 62: ! 63: ims332_write_register(regs, regno, val) ! 64: unsigned char *regs; ! 65: register unsigned int val; ! 66: { ! 67: unsigned char *wptr; ! 68: ! 69: /* spec sez: */ ! 70: wptr = regs + 0xa0000 + (regno << 4); ! 71: * ((volatile unsigned int *)(regs)) = (val >> 8) & 0xff00; ! 72: * ((volatile unsigned short *)(wptr)) = val; ! 73: } ! 74: ! 75: #define assert_ims332_reset_bit(r) *r &= ~0x40 ! 76: #define deassert_ims332_reset_bit(r) *r |= 0x40 ! 77: ! 78: #else /*MAXINE*/ ! 79: ! 80: #define ims332_read_register(p,r) \ ! 81: ((unsigned int *)(p)) [ (r) ] ! 82: #define ims332_write_register(p,r,v) \ ! 83: ((unsigned int *)(p)) [ (r) ] = (v) ! 84: ! 85: #endif /*MAXINE*/ ! 86: ! 87: ! 88: /* ! 89: * Color map ! 90: */ ! 91: ims332_load_colormap( regs, map) ! 92: ims332_padded_regmap_t *regs; ! 93: color_map_t *map; ! 94: { ! 95: register int i; ! 96: ! 97: for (i = 0; i < 256; i++, map++) ! 98: ims332_load_colormap_entry(regs, i, map); ! 99: } ! 100: ! 101: ims332_load_colormap_entry( regs, entry, map) ! 102: ims332_padded_regmap_t *regs; ! 103: color_map_t *map; ! 104: { ! 105: /* ?? stop VTG */ ! 106: ims332_write_register(regs, IMS332_REG_LUT_BASE + (entry & 0xff), ! 107: (map->blue << 16) | ! 108: (map->green << 8) | ! 109: (map->red)); ! 110: } ! 111: ! 112: ims332_init_colormap( regs) ! 113: ims332_padded_regmap_t *regs; ! 114: { ! 115: color_map_t m; ! 116: ! 117: m.red = m.green = m.blue = 0; ! 118: ims332_load_colormap_entry( regs, 0, &m); ! 119: ! 120: m.red = m.green = m.blue = 0xff; ! 121: ims332_load_colormap_entry( regs, 1, &m); ! 122: ims332_load_colormap_entry( regs, 255, &m); ! 123: ! 124: /* since we are at it, also fix cursor LUT */ ! 125: ims332_load_colormap_entry( regs, IMS332_REG_CURSOR_LUT_0, &m); ! 126: ims332_load_colormap_entry( regs, IMS332_REG_CURSOR_LUT_1, &m); ! 127: /* *we* do not use this, but the prom does */ ! 128: ims332_load_colormap_entry( regs, IMS332_REG_CURSOR_LUT_2, &m); ! 129: } ! 130: ! 131: #if 1/*debug*/ ! 132: ims332_print_colormap( regs) ! 133: ims332_padded_regmap_t *regs; ! 134: { ! 135: register int i; ! 136: ! 137: for (i = 0; i < 256; i++) { ! 138: register unsigned int color; ! 139: ! 140: color = ims332_read_register( regs, IMS332_REG_LUT_BASE + i); ! 141: printf("%x->[x%x x%x x%x]\n", i, ! 142: (color >> 16) & 0xff, ! 143: (color >> 8) & 0xff, ! 144: color & 0xff); ! 145: } ! 146: } ! 147: #endif ! 148: ! 149: /* ! 150: * Video on/off ! 151: * ! 152: * It is unfortunate that X11 goes backward with white@0 ! 153: * and black@1. So we must stash away the zero-th entry ! 154: * and fix it while screen is off. Also must remember ! 155: * it, sigh. ! 156: */ ! 157: struct vstate { ! 158: ims332_padded_regmap_t *regs; ! 159: unsigned short off; ! 160: }; ! 161: ! 162: ims332_video_off(vstate, up) ! 163: struct vstate *vstate; ! 164: user_info_t *up; ! 165: { ! 166: register ims332_padded_regmap_t *regs = vstate->regs; ! 167: register unsigned *save, csr; ! 168: ! 169: if (vstate->off) ! 170: return; ! 171: ! 172: /* Yes, this is awful */ ! 173: save = (unsigned *)up->dev_dep_2.gx.colormap; ! 174: ! 175: *save = ims332_read_register(regs, IMS332_REG_LUT_BASE); ! 176: ! 177: ims332_write_register(regs, IMS332_REG_LUT_BASE, 0); ! 178: ! 179: ims332_write_register( regs, IMS332_REG_COLOR_MASK, 0); ! 180: ! 181: /* cursor now */ ! 182: csr = ims332_read_register(regs, IMS332_REG_CSR_A); ! 183: csr |= IMS332_CSR_A_DISABLE_CURSOR; ! 184: ims332_write_register(regs, IMS332_REG_CSR_A, csr); ! 185: ! 186: vstate->off = 1; ! 187: } ! 188: ! 189: ims332_video_on(vstate, up) ! 190: struct vstate *vstate; ! 191: user_info_t *up; ! 192: { ! 193: register ims332_padded_regmap_t *regs = vstate->regs; ! 194: register unsigned *save, csr; ! 195: ! 196: if (!vstate->off) ! 197: return; ! 198: ! 199: /* Like I said.. */ ! 200: save = (unsigned *)up->dev_dep_2.gx.colormap; ! 201: ! 202: ims332_write_register(regs, IMS332_REG_LUT_BASE, *save); ! 203: ! 204: ims332_write_register( regs, IMS332_REG_COLOR_MASK, 0xffffffff); ! 205: ! 206: /* cursor now */ ! 207: csr = ims332_read_register(regs, IMS332_REG_CSR_A); ! 208: csr &= ~IMS332_CSR_A_DISABLE_CURSOR; ! 209: ims332_write_register(regs, IMS332_REG_CSR_A, csr); ! 210: ! 211: vstate->off = 0; ! 212: } ! 213: ! 214: /* ! 215: * Cursor ! 216: */ ! 217: ims332_pos_cursor(regs,x,y) ! 218: ims332_padded_regmap_t *regs; ! 219: register int x,y; ! 220: { ! 221: ims332_write_register( regs, IMS332_REG_CURSOR_LOC, ! 222: ((x & 0xfff) << 12) | (y & 0xfff) ); ! 223: } ! 224: ! 225: ! 226: ims332_cursor_color( regs, color) ! 227: ims332_padded_regmap_t *regs; ! 228: color_map_t *color; ! 229: { ! 230: /* Bg is color[0], Fg is color[1] */ ! 231: ims332_write_register(regs, IMS332_REG_CURSOR_LUT_0, ! 232: (color->blue << 16) | ! 233: (color->green << 8) | ! 234: (color->red)); ! 235: color++; ! 236: ims332_write_register(regs, IMS332_REG_CURSOR_LUT_1, ! 237: (color->blue << 16) | ! 238: (color->green << 8) | ! 239: (color->red)); ! 240: } ! 241: ! 242: ims332_cursor_sprite( regs, cursor) ! 243: ims332_padded_regmap_t *regs; ! 244: unsigned short *cursor; ! 245: { ! 246: register int i; ! 247: ! 248: /* We *could* cut this down a lot... */ ! 249: for (i = 0; i < 512; i++, cursor++) ! 250: ims332_write_register( regs, ! 251: IMS332_REG_CURSOR_RAM+i, *cursor); ! 252: } ! 253: ! 254: /* ! 255: * Initialization ! 256: */ ! 257: ims332_init(regs, reset, mon) ! 258: ims332_padded_regmap_t *regs; ! 259: unsigned int *reset; ! 260: xcfb_monitor_type_t mon; ! 261: { ! 262: int shortdisplay, broadpulse, frontporch; ! 263: ! 264: assert_ims332_reset_bit(reset); ! 265: delay(1); /* specs sez 50ns.. */ ! 266: deassert_ims332_reset_bit(reset); ! 267: ! 268: /* CLOCKIN appears to receive a 6.25 Mhz clock --> PLL 12 for 75Mhz monitor */ ! 269: ims332_write_register(regs, IMS332_REG_BOOT, 12 | IMS332_BOOT_CLOCK_PLL); ! 270: ! 271: /* initialize VTG */ ! 272: ims332_write_register(regs, IMS332_REG_CSR_A, ! 273: IMS332_BPP_8 | IMS332_CSR_A_DISABLE_CURSOR); ! 274: delay(50); /* spec does not say */ ! 275: ! 276: /* datapath registers (values taken from prom's settings) */ ! 277: ! 278: frontporch = mon->line_time - (mon->half_sync * 2 + ! 279: mon->back_porch + ! 280: mon->frame_visible_width / 4); ! 281: ! 282: shortdisplay = mon->line_time / 2 - (mon->half_sync * 2 + ! 283: mon->back_porch + frontporch); ! 284: broadpulse = mon->line_time / 2 - frontporch; ! 285: ! 286: ims332_write_register( regs, IMS332_REG_HALF_SYNCH, mon->half_sync); ! 287: ims332_write_register( regs, IMS332_REG_BACK_PORCH, mon->back_porch); ! 288: ims332_write_register( regs, IMS332_REG_DISPLAY, ! 289: mon->frame_visible_width / 4); ! 290: ims332_write_register( regs, IMS332_REG_SHORT_DIS, shortdisplay); ! 291: ims332_write_register( regs, IMS332_REG_BROAD_PULSE, broadpulse); ! 292: ims332_write_register( regs, IMS332_REG_V_SYNC, mon->v_sync * 2); ! 293: ims332_write_register( regs, IMS332_REG_V_PRE_EQUALIZE, ! 294: mon->v_pre_equalize); ! 295: ims332_write_register( regs, IMS332_REG_V_POST_EQUALIZE, ! 296: mon->v_post_equalize); ! 297: ims332_write_register( regs, IMS332_REG_V_BLANK, mon->v_blank * 2); ! 298: ims332_write_register( regs, IMS332_REG_V_DISPLAY, ! 299: mon->frame_visible_height * 2); ! 300: ims332_write_register( regs, IMS332_REG_LINE_TIME, mon->line_time); ! 301: ims332_write_register( regs, IMS332_REG_LINE_START, mon->line_start); ! 302: ims332_write_register( regs, IMS332_REG_MEM_INIT, mon->mem_init); ! 303: ims332_write_register( regs, IMS332_REG_XFER_DELAY, mon->xfer_delay); ! 304: ! 305: ims332_write_register( regs, IMS332_REG_COLOR_MASK, 0xffffff); ! 306: ! 307: ims332_init_colormap( regs ); ! 308: ! 309: ims332_write_register(regs, IMS332_REG_CSR_A, ! 310: IMS332_BPP_8 | IMS332_CSR_A_DMA_DISABLE | IMS332_CSR_A_VTG_ENABLE); ! 311: ! 312: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.