|
|
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.