xref: /original-bsd/sys/news3400/fb/fbbm_lcdm.c (revision 02e832b2)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * 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_lcdm.c,v 4.300 91/06/09 06:33:38 root Rel41 $ SONY
11  *
12  *	@(#)fbbm_lcdm.c	7.2 (Berkeley) 12/17/92
13  */
14 
15 /*
16  * LCD frame buffer driver
17  */
18 
19 #include <machine/fix_machine_type.h>
20 
21 #include "lfbm.h"
22 
23 #if NLFBM > 0
24 #ifdef mips
25 #ifndef news3200
26 #define news3200 1
27 #endif /* !news3200 */
28 #endif /* mips */
29 
30 #include <sys/param.h>
31 #include <news3400/iop/framebuf.h>
32 #include <news3400/iop/fbreg.h>
33 
34 #include <news3400/fb/fbdefs.h>
35 
36 extern int nofunc();
37 extern int error();
38 extern char *ext_fnt24_addr[];
39 extern char *ext_fnt_addr[];
40 
41 extern short zero[];
42 
43 extern unsigned int mfbmask32[];
44 extern unsigned int mfbrmask32[];
45 
46 #define NOP	for (j = 0; j < 40; j++)
47 
48 #ifdef news1200
49 #define LCD_CRTC	(unsigned char *)(0xe1480000)
50 #define LCD_PORT	(unsigned char *)(0xe1500002)
51 #define DIMMER_PORT	(unsigned char *)(0xe190000f)
52 #define KROM_START	(char *)(0xe2000000)
53 #define	VRAM_START	(unsigned long *)(0xe4000000)
54 #define VRAM_WIDTH	(1120/32)
55 #endif
56 
57 #ifdef news3200
58 #define LCD_PORT	(volatile unsigned long *)(0xb0000000)
59 #define DIMMER_PORT	(volatile unsigned long *)(0xb0100000)
60 #define LCD_CRTC	(volatile unsigned char *)(0xbff60000)
61 #define	KROM_START	(char *)(0x90000000)
62 #define	VRAM_START	(unsigned long *)(0x90200000)
63 #define VRAM_WIDTH	(1120/32)
64 #endif
65 
66 #ifdef news1200
67 static caddr_t
68 fblfbm_Krom_addr(fb, c, sr)
69 	struct fbdev *fb;
70 	register int c;
71 	lRectangle *sr;
72 {
73 	register caddr_t tmp;
74 
75 	if ((c >= 0x20) && (c <= 0x7e)) {
76 		/*
77 		 * ASCII char
78 		 */
79 		c -= ' ';
80 		c = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
81 		tmp =  (caddr_t)(c + fb->Krom_base + (sr->extent.y > 16 ? 0 : 96));
82 	} else if ((c >= 0xa1) && (c <= 0xdf)) {
83 		/*
84 		 * KANA char
85 		 */
86 		if (sr->extent.y > 16)
87 			tmp =  (caddr_t)ext_fnt24_addr[c + 64];
88 		else
89 			tmp =  (caddr_t)ext_fnt_addr[c + 64];
90 	} else if ((c >= 0x2020) && (c <= 0x7e7e)) {
91 		/*
92 		 * KANJI char
93 		 */
94 		switch (c & 0x7000) {
95 		case 0x2000:
96 			c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)) << 7;
97 			break;
98 		case 0x3000:
99 		case 0x4000:
100 			c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x4000) >> 3)) << 7;
101 			break;
102 		case 0x5000:
103 		case 0x6000:
104 			c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x2000) >> 2)
105 				| 0x1000) << 7;
106 			break;
107 		case 0x7000:
108 			c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)
109 				| 0x1000) << 7;
110 			break;
111 		}
112 		tmp =  (caddr_t)(c + fb->Krom_base + (sr->extent.y > 16 ? 0 : 96));
113 	} else {
114 		/*
115 		 * UNKNOWN char
116 		 */
117 		tmp =  (caddr_t)zero;
118 	}
119 	return (tmp);
120 }
121 #endif /* news1200 */
122 
123 #ifdef news3200
124 static caddr_t
125 fblfbm_Krom_addr(fb, c, sr)
126 	struct fbdev *fb;
127 	register int c;
128 	lRectangle *sr;
129 {
130 	register int i;
131 	register u_short *tmp;
132 	static int tmpfnt[24];
133 
134 	if ((c >= 0x20) && (c <= 0x7e)) {
135 		/*
136 		 * ASCII char
137 		 */
138 		c -= ' ';
139 		c = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
140 		tmp = (u_short *)(fb->Krom_base + (c + (sr->extent.y > 16 ? 0 : 96)) * 2);
141 	} else if ((c >= 0xa1) && (c <= 0xdf)) {
142 		/*
143 		 * KANA char
144 		 */
145 		if (sr->extent.y > 16)
146 			tmp =  (u_short *)ext_fnt24_addr[c + 64];
147 		else
148 			tmp =  (u_short *)ext_fnt_addr[c + 64];
149 	} else if ((c >= 0x2020) && (c <= 0x7e7e)) {
150 		/*
151 		 * KANJI char
152 		 */
153 		switch (c & 0x7000) {
154 		case 0x2000:
155 			c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)) << 7;
156 			break;
157 		case 0x3000:
158 		case 0x4000:
159 			c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x4000) >> 3)) << 7;
160 			break;
161 		case 0x5000:
162 		case 0x6000:
163 			c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x2000) >> 2)
164 				| 0x1000) << 7;
165 			break;
166 		case 0x7000:
167 			c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)
168 				| 0x1000) << 7;
169 			break;
170 		}
171 		tmp = (u_short *)(fb->Krom_base + (c + (sr->extent.y > 16 ? 0 : 96)) * 2);
172 	} else {
173 		/*
174 		 * UNKNOWN char
175 		 */
176 		return ((caddr_t)zero);
177 	}
178 
179 	if (sr->extent.y > 16) {
180 		for (i = 0; i < 24; i++) {
181 			tmpfnt[i] = (*tmp << 16) | *(tmp + 2);
182 			tmp += 4;
183 		}
184 	} else {
185 		for (i = 0; i < 16; i++) {
186 			tmpfnt[i] = (*tmp << 16) | *(tmp + 2);
187 			tmp += 4;
188 		}
189 	}
190 
191 	return ((caddr_t)tmpfnt);
192 }
193 #endif /* news3200 */
194 
195 static int
196 fblfbm_set_dimmer(fb, dim)
197 	struct fbdev *fb;
198 	int dim;
199 {
200 	int s;
201 
202 	fb->status_flag = dim ? 0xf1: 0xf0;
203 #ifdef news1200
204 	val_1185_ioptr = fb->status_flag;
205 	if (scsi_stat.ipc >= 0) {
206 		pend_1185_ioptr = 1;
207 	} else {
208 		pend_1185_ioptr = 0;
209 		*DIMMER_PORT = val_1185_ioptr;
210 	}
211 #endif
212 #ifdef news3200
213 	*DIMMER_PORT = fb->status_flag;
214 #endif
215 	return (FB_ROK);
216 }
217 
218 static int
219 fblfbm_get_dimmer(fb)
220 	struct fbdev *fb;
221 {
222 	return (fb->status_flag & 0x1);
223 }
224 
225 int
226 fblfbm_get_pixel(fb, pixel)
227 	struct fbdev *fb;
228 	register int pixel;
229 {
230 	return (pixel);
231 }
232 
233 int
234 fblfbm_get_page(fb, off)
235 	struct fbdev *fb;
236 	off_t off;
237 {
238 	if (off < 1120/8 * 930) {		/* X/8 * Y */
239 #ifdef news1200
240 		return (((unsigned int)VRAM_START + off) >> PGSHIFT);
241 #endif
242 #ifdef news3200
243 		return (((unsigned int)0x10200000 + off) >> PGSHIFT);
244 #endif
245 	} else
246 		return (-1);
247 }
248 
249 int
250 fblfbm_probe(unit)
251 	int unit;
252 {
253 #ifdef news1200
254 	if (unit < NLFBM) {
255 		if (badaddr(VRAM_START, 1))
256 			return 0;
257 		else
258 			return FB_LCDM;
259 	}
260 #endif /* news1200 */
261 #ifdef news3200
262 	if (unit < NLFBM) {
263 		if (badaddr(0xbff50000, 1))
264 			return 0;
265 		else {
266 			if (*(volatile u_char *)(0xbff50000) == 0xff)
267 				return FB_LCDM;
268 			else
269 				return 0;
270 		}
271 	}
272 #endif /* news3200 */
273 	return 0;
274 }
275 
276 void fbmem_rop_init();
277 void fbmem_rop_copy();
278 void fbmem_rop_winit();
279 void fbmem_rop_write();
280 void fbmem_rop_read();
281 void fbmem_rop_cinit();
282 void fbmem_rop_clear();
283 void fbmem_rop_vect();
284 void fbmem_rop_dot();
285 
286 struct fbdev_ops fblfbm_ops = {
287 	fbmem_rop_init,			/* (*fb_rop_init)() */
288 	fbmem_rop_copy,			/* (*fb_rop_copy)() */
289 	fbmem_rop_winit,		/* (*fb_rop_winit)() */
290 	fbmem_rop_write,		/* (*fb_rop_write)() */
291 	fbmem_rop_read,			/* (*fb_rop_read)() */
292 	fbmem_rop_cinit,		/* (*fb_rop_cinit)() */
293 	fbmem_rop_clear,		/* (*fb_rop_clear)() */
294 	fbmem_rop_vect,			/* (*fb_rop_vect)() */
295 	fbmem_rop_dot,			/* (*fb_rop_dot)() */
296 	(void (*)())nofunc,		/* (*fb_rop_fillscan)() */
297 	(void (*)())error,		/* (*fb_rop_wait)() */
298 	(void (*)())error,		/* (*fb_rop_reset)() */
299 	fblfbm_Krom_addr,		/* *(*fb_Krom_addr)() */
300 	(void (*)())error,		/* (*fb_init_palette)() */
301 	error,				/* (*fb_set_palette)() */
302 	error,				/* (*fb_get_palette)() */
303 	fblfbm_get_pixel,		/* (*fb_get_pixel)() */
304 	fblfbm_set_dimmer,		/* (*fb_set_dimmer)() */
305 	fblfbm_get_dimmer,		/* (*fb_get_dimmer)() */
306 	nofunc,				/* (*fb_open)() */
307 	nofunc,				/* (*fb_close)() */
308 	nofunc,				/* (*fb_ioctl)() */
309 	fblfbm_get_page,		/* (*fb_get_page)() */
310 	(void (*)())nofunc,		/* (*fb_cursor_set)() */
311 	(void (*)())nofunc,		/* (*fb_cursor_on)() */
312 	(void (*)())nofunc,		/* (*fb_cursor_off)() */
313 	(void (*)())nofunc,		/* (*fb_cursor_move)() */
314 };
315 
316 static char lctc_data[] = {
317 	0, 47,
318 	1, 35,
319 	9, 0,
320 	10, 0,
321 	11, 0,
322 	12, 0,
323 	13, 0,
324 	14, 0,
325 	15, 0,
326 	18, 35,
327 	19, 0x01,
328 	20, 0x85,
329 	21, 0,
330 	22, 0x10
331 };
332 
333 struct mfbdev fblcd = { (caddr_t)VRAM_START, VRAM_WIDTH };
334 
335 void
336 fblfbm_setup(fb)
337 	register struct fbdev *fb;
338 {
339 	register int i;
340 	register volatile unsigned char *lctreg = LCD_CRTC;
341 
342 	if (fb->type) {
343 		fb->Mono = 1;
344 		fb->Colorwidth = 1;
345 		fb->fbNplane = 1;
346 		fb->planemask = 0x1;
347 		fb->Dimmer = 1;
348 
349 		fb->FrameRect.origin.x = 0;
350 		fb->FrameRect.origin.y = 0;
351 		fb->FrameRect.extent.x = 1120;
352 		fb->FrameRect.extent.y = 930;
353 		fb->VisRect.origin.x = 0;
354 		fb->VisRect.origin.y = 0;
355 		fb->VisRect.extent.x = 1120;
356 		fb->VisRect.extent.y = 780;
357 		fb->Krom_BM0.type = BM_MEM;
358 		fb->Krom_BM0.depth = 1;
359 		fb->Krom_BM0.width = 1;
360 		fb->Krom_BM0.rect.origin.x = 0;
361 		fb->Krom_BM0.rect.origin.y = 0;
362 		fb->Krom_BM0.rect.extent.x = 16;
363 		fb->Krom_BM0.rect.extent.y = 16;
364 		fb->Krom_BM1.type = BM_MEM;
365 		fb->Krom_BM1.depth = 1;
366 		fb->Krom_BM1.width = 2;
367 		fb->Krom_BM1.rect.origin.x = 0;
368 		fb->Krom_BM1.rect.origin.y = 0;
369 		fb->Krom_BM1.rect.extent.x = 32;
370 		fb->Krom_BM1.rect.extent.y = 32;
371 		fb->Krom_base = KROM_START;
372 		fb->Krom_font_extent0.x = 16;
373 		fb->Krom_font_extent0.y = 16;
374 		fb->Krom_font_extent1.x = 24;
375 		fb->Krom_font_extent1.y = 24;
376 		fb->font_w = 12;
377 		fb->font_h = 24;
378 		fb->char_w = 12;
379 		fb->char_h = 26;
380 		fb->scr_w = 1120;
381 		fb->scr_h = 780;
382 		fb->ch_pos = 0;
383 		fb->ul_pos = 24;
384 		fb->x_offset = (1120 - (80 * 12)) / 2;
385 		fb->y_offset = ( 780 - (29 * 26)) / 2;
386 		fb->rit_m = 80;
387 		fb->btm_m = 29;
388 		fb->cursorSet = 0;
389 		fb->cursorVis = 0;
390 		fb->cursorShow = 0;
391 		fb->cursorP.x = 1120/2;
392 		fb->cursorP.y = 780/2;
393 		fb->status_flag = 1;
394 		fb->run_flag = 0;
395 		fb->hard_cursor = 0;
396 
397 		fb->fbbm_op = &fblfbm_ops;
398 
399 		fb->private = (caddr_t)&fblcd;
400 
401 		for (i = 0; i < 28; i++)
402 			*lctreg++ = lctc_data[i];
403 		for (i = 0; i < 500000; i ++)
404 			;
405 		*LCD_PORT = 1;
406 	}
407 }
408 #endif /* NLFBM > 0 */
409