xref: /original-bsd/sys/news3400/fb/fbbm_253.c (revision 3705696b)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: fbbm_253.c,v 4.300 91/06/09 06:33:12 root Rel41 $ SONY;
11  *
12  *	@(#)fbbm_253.c	8.1 (Berkeley) 06/11/93
13  */
14 
15 /*
16  * NWB-253 frame buffer driver
17  */
18 
19 #include "nwb253.h"
20 
21 #if NNWB253 > 0
22 #include <sys/param.h>
23 #include <news3400/iop/framebuf.h>
24 #include <news3400/iop/fbreg.h>
25 
26 #include <news3400/fb/fbdefs.h>
27 
28 extern int error();
29 extern int nofunc();
30 extern char *ext_fnt24_addr[];
31 extern char *ext_fnt_addr[];
32 
33 extern short zero[];
34 
35 #define NOP		{ int j; for (j = 0; j < 40; j++); }
36 
37 #define	VRAM_START	(unsigned int *)(0x88000000)
38 #define VRAM_WIDTH	(2048/32)
39 
40 void
41 nwb253attach(i)
42 {
43 	/* temporary hack for pseudo-device initialization */;
44 }
45 
46 static caddr_t
47 fb253_Krom_addr(fb, c, sr)
48 	struct fbdev *fb;
49 	register int c;
50 	lRectangle *sr;
51 {
52 	unsigned int cvcode16();
53 
54 	if ((c >= 0x20) && (c <= 0x7e)) {
55 		/*
56 		 * ASCII char
57 		 */
58 		c -= ' ';
59 		c = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
60 		return (caddr_t)(c + fb->Krom_base + (sr->extent.y > 16 ? 0 : 96));
61 	} else if ((c >= 0xa1) && (c <= 0xdf)) {
62 		/*
63 		 * KANA char
64 		 */
65 		if (sr->extent.y > 16)
66 			return ((caddr_t)ext_fnt24_addr[c + 64]);
67 		else
68 			return ((caddr_t)ext_fnt_addr[c + 64]);
69 	} else if ((c >= 0x2020) && (c <= 0x7e7e)) {
70 		/*
71 		 * KANJI char
72 		 */
73 		switch (c & 0x7000) {
74 		case 0x2000:
75 			c = ((c&0x1f)|((c&0x60)<<5)|((c&0x700)>>1))<<7;
76 			break;
77 		case 0x3000:
78 		case 0x4000:
79 			c = ((c&0x7f)|((c&0xf00)>>1)|((c&0x4000)>>3))<<7;
80 			break;
81 		case 0x5000:
82 		case 0x6000:
83 			c = ((c&0x7f)|((c&0xf00)>>1)|((c&0x2000)>>2)|0x1000)<<7;
84 			break;
85 		case 0x7000:
86 			c = ((c&0x1f)|((c&0x60)<<5)|((c&0x700)>>1)|0x1000)<<7;
87 			break;
88 		}
89 		return (caddr_t)(c + fb->Krom_base + (sr->extent.y > 16 ? 0 : 96));
90 	} else {
91 		/*
92 		 * UNKNOWN char
93 		 */
94 		return (caddr_t)zero;
95 	}
96 }
97 
98 static int
99 fb253_set_dimmer(fb, dim)
100 	struct fbdev *fb;
101 	int dim;
102 {
103 	int s;
104 
105 	fb->status_flag = (fb->status_flag & 0xf3) | ((dim & 3) << 2);
106 	*(volatile u_short *)(0xb8ff0000) = fb->status_flag;
107 
108 	return (FB_ROK);
109 }
110 
111 static int
112 fb253_get_dimmer(fb)
113 	struct fbdev *fb;
114 {
115 	int dim;
116 
117 	dim = (fb->status_flag >> 2) & 3;
118 	return (dim);
119 }
120 
121 int
122 fb253_get_pixel(fb, pixel)
123 	struct fbdev *fb;
124 	register int pixel;
125 {
126 	return (pixel);
127 }
128 
129 fb253_ioctl(fb, cmd, data)
130 	struct fbdev *fb;
131 	int cmd;
132 	int *data;
133 {
134 	register int result = 0;
135 
136 	switch (cmd) {
137 	case FB_INTCHECK:
138 		if (*(volatile u_short *)(0xb8ff0000) & 0x08)
139 			result |= FB_INT_VSYNC;
140 		break;
141 	case FB_INTENABLE:
142 		if (*data & FB_INT_VSYNC) {
143 			fb->status_flag |= 1;
144 			*(volatile u_short *)(0xb8ff0000) = fb->status_flag;
145 			WB_FLUSH;
146 		}
147 		break;
148 	case FB_INTCLEAR:
149 		if (*data & FB_INT_VSYNC) {
150 			fb->status_flag &= ~1;
151 			*(volatile u_short *)(0xb8ff0000) = fb->status_flag;
152 			WB_FLUSH;
153 		}
154 		break;
155 	case FB_STATUSCHECK:
156 		break;
157 	default:
158 		result = -1;
159 	}
160 	return (result);
161 }
162 
163 int
164 fb253_get_page(fb, off)
165 	struct fbdev *fb;
166 	off_t off;
167 {
168 	if (off < 2048/8 * 2048)		/* X/8 * Y */
169 		return (((unsigned int)0x8000000 + off) >> PGSHIFT);
170 	else
171 		return (-1);
172 }
173 
174 int
175 fb253_probe(unit)
176 	int unit;
177 {
178 	if (unit >= NNWB253)
179 		return 0;
180 	if (badaddr(0xb8ff0000, 2) || badaddr(0xb8e00000, 2))
181 		return 0;
182 	if ((*(volatile u_short *)(0xb8ff0000) & 7) == 4)
183 		return FB_NWB253;
184 	return 0;
185 }
186 
187 void fbmem_rop_init();
188 void fbmem_rop_copy();
189 void fbmem_rop_winit();
190 void fbmem_rop_write();
191 void fbmem_rop_read();
192 void fbmem_rop_cinit();
193 void fbmem_rop_clear();
194 void fbmem_rop_vect();
195 void fbmem_rop_dot();
196 
197 static struct fbdev_ops
198 fb253_ops = {
199 	fbmem_rop_init,
200 	fbmem_rop_copy,
201 	fbmem_rop_winit,
202 	fbmem_rop_write,
203 	fbmem_rop_read,
204 	fbmem_rop_cinit,
205 	fbmem_rop_clear,
206 	fbmem_rop_vect,
207 	fbmem_rop_dot,
208 	(void (*)())nofunc,
209 	(void (*)())error,
210 	(void (*)())error,
211 	fb253_Krom_addr,
212 	(void (*)())error,
213 	error,
214 	error,
215 	fb253_get_pixel,
216 	fb253_set_dimmer,
217 	fb253_get_dimmer,
218 	nofunc,
219 	nofunc,
220 	fb253_ioctl,
221 	fb253_get_page,
222 	(void (*)())nofunc,
223 	(void (*)())nofunc,
224 	(void (*)())nofunc,
225 	(void (*)())nofunc,
226 };
227 
228 static u_short
229 nwp512_data1[] = {
230 	0x00, 0x44,
231 	0x01, 0x33,
232 	0x02, 0x3c,
233 	0x03, 0x38,
234 	0x04, 0x84,
235 	0x05, 0x03,
236 	0x06, 0x80,
237 	0x07, 0x80,
238 	0x08, 0x10,
239 	0x09, 0x07,
240 	0x0a, 0x20,
241 	0x0c, 0x00,
242 	0x0d, 0x00,
243 	0x1b, 0x03
244 };
245 
246 static u_short
247 nwp512_data2[] = {
248 	0x1e, 0x08,
249 	0x20, 0x08,
250 	0x21, 0x0d
251 };
252 
253 static u_short
254 nwp518_data1[] = {
255 	0x00, 0x52,
256 	0x01, 0x40,
257 	0x02, 0x4a,
258 	0x03, 0x49,
259 	0x04, 0x63,
260 	0x05, 0x02,
261 	0x06, 0x60,
262 	0x07, 0x60,
263 	0x08, 0x10,
264 	0x09, 0x07,
265 	0x0a, 0x20,
266 	0x0c, 0x00,
267 	0x0d, 0x00,
268 	0x1b, 0x04
269 };
270 
271 static u_short
272 nwp518_data2[] = {
273 	0x1e, 0x08,
274 	0x20, 0x00,
275 	0x21, 0x00
276 };
277 
278 static u_short
279 nwe501_data1[] = {
280 	0x00, 0x4b,
281 	0x01, 0x40,
282 	0x02, 0x4a,
283 	0x03, 0x43,
284 	0x04, 0x64,
285 	0x05, 0x02,
286 	0x06, 0x60,
287 	0x07, 0x60,
288 	0x08, 0x10,
289 	0x09, 0x07,
290 	0x0a, 0x20,
291 	0x0c, 0x00,
292 	0x0d, 0x00,
293 	0x1b, 0x04
294 };
295 
296 static u_short
297 nwe501_data2[] = {
298 	0x1e, 0x08,
299 	0x20, 0x00,
300 	0x21, 0x00
301 };
302 
303 static u_short
304 *crtc_data[3][2] = {
305 	nwp512_data1, nwp512_data2,
306 	nwp518_data1, nwp518_data2,
307 	nwe501_data1, nwe501_data2,
308 };
309 
310 static void
311 fb253_init(fb, id)
312 	struct fbdev *fb;
313 	int id;
314 {
315 	register int i;
316 	register volatile u_short *ctlreg = (u_short *)(0xb8ff0000);
317 	register volatile u_short *crtreg = (u_short *)(0xb8fe0000);
318 	register volatile u_short *p;
319 	u_short	dummy;
320 
321 	*ctlreg = 0;			/* stop crtc */
322 	NOP;
323 
324 	/* initialize crtc without R3{0,1,2} */
325 	p = crtc_data[id][0];
326 	for (i = 0; i < 28; i++) {
327 		*crtreg++ = *p++;
328 		NOP;
329 	}
330 
331 	*ctlreg = 0x02;			/* start crtc */
332 	NOP;
333 
334 	/* set crtc control reg */
335 	p = crtc_data[id][1];
336 	for (i = 0; i < 6; i++) {
337 		*crtreg++ = *p++;
338 		NOP;
339 	}
340 }
341 
342 struct mfbdev fb253 = { (caddr_t)VRAM_START, VRAM_WIDTH };
343 
344 void
345 fb253_setup(fb)
346 	struct fbdev *fb;
347 {
348 	int id;
349 
350 	if (fb->type) {
351 		fb->Mono = 1;
352 		fb->Colorwidth = 1;
353 		fb->fbNplane = 1;
354 		fb->planemask = 0x1;
355 		fb->Dimmer = 1;
356 
357 		id = ((*(volatile u_short *)(0xb8ff0000)) >> 8) & 0xf;
358 
359 		switch (id) {
360 		case 0:
361 			fb->FrameRect.extent.x = 2048;
362 			fb->FrameRect.extent.y = 2048;
363 			fb->VisRect.extent.x = 816;
364 			fb->VisRect.extent.y = 1024;
365 			fb->cursorP.x = 816/2;
366 			fb->cursorP.y = 1024/2;
367 			fb->font_w = 8;
368 			fb->font_h = 16;
369 			fb->char_w = 10;
370 			fb->char_h = 24;
371 			fb->scr_w = 816;
372 			fb->scr_h = 1024;
373 			fb->ch_pos = 5;
374 			fb->ul_pos = 22;
375 			fb->x_offset = 8;
376 			fb->y_offset = 8;
377 			fb->rit_m = 80;
378 			fb->btm_m = 42;
379 			break;
380 		case 1:
381 		case 2:
382 			fb->FrameRect.extent.x = 2048;
383 			fb->FrameRect.extent.y = 2048;
384 			fb->VisRect.extent.x = 1024;
385 			fb->VisRect.extent.y = 768;
386 			fb->cursorP.x = 1024/2;
387 			fb->cursorP.y = 768/2;
388 			fb->font_w = 8;
389 			fb->font_h = 16;
390 			fb->char_w = 12;
391 			fb->char_h = 22;
392 			fb->scr_w = 1024;
393 			fb->scr_h = 768;
394 			fb->ch_pos = 2;
395 			fb->ul_pos = 20;
396 			fb->x_offset = 32;
397 			fb->y_offset = 21;
398 			fb->rit_m = 80;
399 			fb->btm_m = 33;
400 			break;
401 		}
402 		fb->FrameRect.origin.x = 0;
403 		fb->FrameRect.origin.y = 0;
404 		fb->VisRect.origin.x = 0;
405 		fb->VisRect.origin.y = 0;
406 		fb->Krom_BM0.type = BM_MEM;
407 		fb->Krom_BM0.depth = 1;
408 		fb->Krom_BM0.width = 1;
409 		fb->Krom_BM0.rect.origin.x = 0;
410 		fb->Krom_BM0.rect.origin.y = 0;
411 		fb->Krom_BM0.rect.extent.x = 16;
412 		fb->Krom_BM0.rect.extent.y = 16;
413 		fb->Krom_BM1.type = BM_MEM;
414 		fb->Krom_BM1.depth = 1;
415 		fb->Krom_BM1.width = 2;
416 		fb->Krom_BM1.rect.origin.x = 0;
417 		fb->Krom_BM1.rect.origin.y = 0;
418 		fb->Krom_BM1.rect.extent.x = 24;
419 		fb->Krom_BM1.rect.extent.y = 24;
420 		fb->Krom_base = (char *)(0xb8e00000);
421 		fb->Krom_font_extent0.x = 16;
422 		fb->Krom_font_extent0.y = 16;
423 		fb->Krom_font_extent1.x = 24;
424 		fb->Krom_font_extent1.y = 24;
425 		fb->cursorSet = 0;
426 		fb->cursorVis = 0;
427 		fb->cursorShow = 0;
428 		fb->status_flag = 2;
429 		fb->run_flag = 0;
430 		fb->hard_cursor = 0;
431 
432 		fb->fbbm_op = &fb253_ops;
433 
434 		fb->private = (caddr_t)&fb253;
435 
436 		fb253_init(fb, id);
437 	}
438 }
439 #endif /* NNWB253 > 0 */
440