1 /* $NetBSD: ite_et.c,v 1.26 2009/07/19 05:43:22 tsutsui Exp $ */
4 * Copyright (c) 1996 Leo Weppelman.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: ite_et.c,v 1.26 2009/07/19 05:43:22 tsutsui Exp $");
31 #include <sys/param.h>
32 #include <sys/systm.h>
34 #include <sys/ioctl.h>
35 #include <sys/malloc.h>
36 #include <sys/device.h>
39 #include <machine/cpu.h>
41 #include <atari/atari/device.h>
43 #include <atari/dev/itevar.h>
44 #include <atari/dev/iteioctl.h>
45 #include <atari/dev/grfioctl.h>
46 #include <atari/dev/grf_etreg.h>
47 #include <atari/dev/grfabs_reg.h>
48 #include <atari/dev/grfabs_et.h>
49 #include <atari/dev/grfvar.h>
50 #include <atari/dev/font.h>
51 #include <atari/dev/viewioctl.h>
52 #include <atari/dev/viewvar.h>
57 * This is what ip->priv points to;
58 * it contains local variables for custom-chip ites.
61 volatile u_char
*regkva
;
64 typedef struct ite_priv ipriv_t
;
66 static ipriv_t con_ipriv
;
69 static u_char etconscolors
[3][3] = { /* background, foreground, hilite */
70 {0x0, 0x0, 0x0}, {0x30, 0x30, 0x30}, { 0x3f, 0x3f, 0x3f}
73 /* XXX: Shouldn't these be in font.h???? */
74 extern font_info font_info_8x8
;
75 extern font_info font_info_8x16
;
77 static void grfet_iteinit(struct grf_softc
*);
78 static void view_init(struct ite_softc
*);
79 static void view_deinit(struct ite_softc
*);
80 static int iteet_ioctl(struct ite_softc
*, u_long
, void *, int,
82 static int ite_newsize(struct ite_softc
*, struct itewinsize
*);
83 static void et_inittextmode(struct ite_softc
*, et_sv_reg_t
*, int);
84 void et_cursor(struct ite_softc
*ip
, int flag
);
85 void et_clear(struct ite_softc
*ip
, int sy
, int sx
, int h
, int w
);
86 void et_putc(struct ite_softc
*ip
, int c
, int dy
, int dx
, int mode
);
87 void et_scroll(struct ite_softc
*ip
, int sy
, int sx
, int count
,
93 void grfetattach(struct device
*, struct device
*, void *);
94 int grfetmatch(struct device
*, struct cfdata
*, void *);
95 int grfetprint(void *, const char *);
97 CFATTACH_DECL(grfet
, sizeof(struct grf_softc
),
98 grfetmatch
, grfetattach
, NULL
, NULL
);
101 * only used in console init.
103 static struct cfdata
*cfdata_grf
= NULL
;
106 grfetmatch(struct device
*pdp
, struct cfdata
*cfp
, void *auxp
)
108 static int card_probed
= -1;
109 static int did_consinit
= 0;
110 grf_auxp_t
*grf_auxp
= auxp
;
111 extern const struct cdevsw view_cdevsw
;
113 if (card_probed
<= 0) {
114 if (card_probed
== 0) /* Probed but failed */
119 * Check if the layers we depend on exist
121 if(!(machineid
& ATARI_HADES
))
123 if (!et_probe_card())
125 if (grfabs_probe(&et_probe_video
) == 0)
128 card_probed
= 1; /* Probed and found */
131 if (atari_realconfig
== 0) {
133 * Early console init. Only match first unit.
137 if ((*view_cdevsw
.d_open
)(cfp
->cf_unit
, 0, 0, NULL
))
145 * Normal config. When we are called directly from the grfbus,
146 * we only match the first unit. The attach function will call us for
147 * the other configured units.
149 if (grf_auxp
->from_bus_match
150 && ((did_consinit
> 1) || !et_probe_card()))
153 if (!grf_auxp
->from_bus_match
&& (grf_auxp
->unit
!= cfp
->cf_unit
))
157 * Final constraint: each grf needs a view....
159 if((cfdata_grf
== NULL
) || (did_consinit
> 1)) {
160 if((*view_cdevsw
.d_open
)(cfp
->cf_unit
, 0, 0, NULL
))
168 * attach: initialize the grf-structure and try to attach an ite to us.
169 * note : dp is NULL during early console init.
172 grfetattach(struct device
*pdp
, struct device
*dp
, void *auxp
)
174 static struct grf_softc congrf
;
175 static int first_attach
= 1;
176 grf_auxp_t
*grf_bus_auxp
= auxp
;
178 struct grf_softc
*gp
;
180 extern const struct cdevsw grf_cdevsw
;
183 * find our major device number
185 maj
= cdevsw_lookup_major(&grf_cdevsw
);
188 * Handle exeption case: early console init
191 congrf
.g_unit
= cfdata_grf
->cf_unit
;
192 congrf
.g_grfdev
= makedev(maj
, congrf
.g_unit
);
193 congrf
.g_itedev
= (dev_t
)-1;
194 congrf
.g_flags
= GF_ALIVE
;
195 congrf
.g_mode
= grf_mode
;
196 congrf
.g_conpri
= CN_INTERNAL
;
197 congrf
.g_viewdev
= congrf
.g_unit
;
198 grfet_iteinit(&congrf
);
199 grf_viewsync(&congrf
);
201 /* Attach console ite */
202 atari_config_found(cfdata_grf
, NULL
, &congrf
, grfetprint
);
206 gp
= (struct grf_softc
*)dp
;
207 gp
->g_unit
= device_unit(&gp
->g_device
);
208 grfsp
[gp
->g_unit
] = gp
;
210 if((cfdata_grf
!= NULL
) && (gp
->g_unit
== congrf
.g_unit
)) {
212 * We inited earlier just copy the info, take care
213 * not to copy the device struct though.
215 memcpy(&gp
->g_display
, &congrf
.g_display
,
216 (char *)&gp
[1] - (char *)&gp
->g_display
);
219 gp
->g_grfdev
= makedev(maj
, gp
->g_unit
);
220 gp
->g_itedev
= (dev_t
)-1;
221 gp
->g_flags
= GF_ALIVE
;
222 gp
->g_mode
= grf_mode
;
224 gp
->g_viewdev
= gp
->g_unit
;
229 printf(": %dx%d", gp
->g_display
.gd_dwidth
, gp
->g_display
.gd_dheight
);
230 if(gp
->g_display
.gd_colors
== 2)
231 printf(" monochrome\n");
232 else printf(" colors %d\n", gp
->g_display
.gd_colors
);
235 * try and attach an ite
237 config_found(dp
, gp
, grfetprint
);
240 * If attaching the first unit, go ahead and 'find' the rest of us
244 grf_auxp
.from_bus_match
= 0;
245 for (grf_auxp
.unit
=0; grf_auxp
.unit
< NGRFET
; grf_auxp
.unit
++) {
246 config_found(pdp
, (void*)&grf_auxp
, grf_bus_auxp
->busprint
);
252 grfetprint(void *auxp
, const char *pnp
)
255 aprint_normal("ite at %s", pnp
);
260 * Init ite portion of grf_softc struct
263 grfet_iteinit(struct grf_softc
*gp
)
266 gp
->g_itecursor
= et_cursor
;
267 gp
->g_iteputc
= et_putc
;
268 gp
->g_iteclear
= et_clear
;
269 gp
->g_itescroll
= et_scroll
;
270 gp
->g_iteinit
= view_init
;
271 gp
->g_itedeinit
= view_deinit
;
275 view_deinit(struct ite_softc
*ip
)
277 ip
->flags
&= ~ITE_INITED
;
281 view_init(register struct ite_softc
*ip
)
283 struct itewinsize wsz
;
286 save_area_t
*et_save
;
288 if((cci
= ip
->priv
) != NULL
)
291 ip
->itexx_ioctl
= iteet_ioctl
;
293 #if defined(KFONT_8X8)
294 ip
->font
= font_info_8x8
;
296 ip
->font
= font_info_8x16
;
299 /* Find the correct set of rendering routines for this font. */
300 if(ip
->font
.width
!= 8)
301 panic("kernel font size not supported");
303 if(!atari_realconfig
)
304 ip
->priv
= cci
= &con_ipriv
;
305 else ip
->priv
= cci
= (ipriv_t
*)malloc(sizeof(*cci
), M_DEVBUF
,M_WAITOK
);
307 panic("No memory for ite-view");
308 memset(cci
, 0, sizeof(*cci
));
310 wsz
.x
= ite_default_x
;
311 wsz
.y
= ite_default_y
;
312 wsz
.width
= ite_default_width
;
313 wsz
.height
= ite_default_height
;
314 wsz
.depth
= ite_default_depth
;
316 ite_newsize (ip
, &wsz
);
318 view
= viewview(ip
->grf
->g_viewdev
);
319 cci
->regkva
= view
->bitmap
->regs
;
322 * Only console will be turned on by default..
324 if(ip
->flags
& ITE_ISCONS
)
325 ip
->grf
->g_mode(ip
->grf
, GM_GRFON
, NULL
, 0, 0);
328 * Activate text-mode settings
330 et_save
= (save_area_t
*)view
->save_area
;
332 et_inittextmode(ip
, NULL
, view
->flags
& VF_DISPLAY
);
334 et_inittextmode(ip
, &et_save
->sv_regs
, view
->flags
&VF_DISPLAY
);
335 et_save
->fb_size
= ip
->cols
* ip
->rows
;
340 ite_newsize(struct ite_softc
*ip
, struct itewinsize
*winsz
)
344 save_area_t
*et_save
;
346 extern const struct cdevsw view_cdevsw
;
350 vs
.width
= winsz
->width
;
351 vs
.height
= winsz
->height
;
352 vs
.depth
= winsz
->depth
;
354 error
= (*view_cdevsw
.d_ioctl
)(ip
->grf
->g_viewdev
, VIOCSSIZE
,
355 (void *)&vs
, 0, NOLWP
);
356 view
= viewview(ip
->grf
->g_viewdev
);
359 * Reinitialize our structs
361 ip
->cols
= view
->display
.width
/ ip
->font
.width
;
362 ip
->rows
= view
->display
.height
/ ip
->font
.height
;
365 * save new values so that future opens use them
366 * this may not be correct when we implement Virtual Consoles
368 ite_default_height
= view
->display
.height
;
369 ite_default_width
= view
->display
.width
;
370 ite_default_x
= view
->display
.x
;
371 ite_default_y
= view
->display
.y
;
372 ite_default_depth
= view
->bitmap
->depth
;
374 et_save
= (save_area_t
*)view
->save_area
;
376 et_inittextmode(ip
, NULL
, view
->flags
& VF_DISPLAY
);
378 et_inittextmode(ip
, &et_save
->sv_regs
, view
->flags
& VF_DISPLAY
);
379 et_save
->fb_size
= ip
->cols
* ip
->rows
;
381 et_clear(ip
, 0, 0, ip
->rows
, ip
->cols
);
387 iteet_ioctl(struct ite_softc
*ip
, u_long cmd
, void * addr
, int flag
, struct lwp
*l
)
390 struct itewinsize
*is
;
392 view_t
*view
= viewview(ip
->grf
->g_viewdev
);
393 extern const struct cdevsw ite_cdevsw
;
394 extern const struct cdevsw view_cdevsw
;
398 is
= (struct itewinsize
*)addr
;
400 if(ite_newsize(ip
, is
))
403 view
= viewview(ip
->grf
->g_viewdev
);
404 ws
.ws_row
= ip
->rows
;
405 ws
.ws_col
= ip
->cols
;
406 ws
.ws_xpixel
= view
->display
.width
;
407 ws
.ws_ypixel
= view
->display
.height
;
410 * XXX tell tty about the change
411 * XXX this is messy, but works
413 (*ite_cdevsw
.d_ioctl
)(ip
->grf
->g_itedev
, TIOCSWINSZ
,
420 * XXX watchout for that NOLWP. its not really the kernel
421 * XXX talking these two commands don't use the proc pointer
424 error
= (*view_cdevsw
.d_ioctl
)(ip
->grf
->g_viewdev
, cmd
, addr
,
428 error
= EPASSTHROUGH
;
435 et_cursor(struct ite_softc
*ip
, int flag
)
441 ba
= ((ipriv_t
*)ip
->priv
)->regkva
;
442 v
= viewview(ip
->grf
->g_viewdev
);
445 * Don't update the cursor when not on display
447 if (!(v
->flags
& VF_DISPLAY
))
452 /*WCrt(ba, CRT_ID_CURSOR_START, & ~0x20); */
454 cpos
= RCrt(ba
, CRT_ID_START_ADDR_LOW
) & 0xff;
455 cpos
|= (RCrt(ba
, CRT_ID_START_ADDR_HIGH
) & 0xff) << 8;
456 cpos
+= ip
->curx
+ ip
->cury
* ip
->cols
;
457 WCrt(ba
, CRT_ID_CURSOR_LOC_LOW
, cpos
& 0xff);
458 WCrt(ba
, CRT_ID_CURSOR_LOC_HIGH
, (cpos
>> 8) & 0xff);
459 WCrt(ba
, CTR_ID_EXT_START
, (cpos
>> (16-2)) & 0x0c);
461 ip
->cursorx
= ip
->curx
;
462 ip
->cursory
= ip
->cury
;
465 /*WCrt(ba, CRT_ID_CURSOR_START, | 0x20); */
466 case START_CURSOROPT
:
474 et_putc(struct ite_softc
*ip
, int c
, int dy
, int dx
, int mode
)
476 view_t
*v
= viewview(ip
->grf
->g_viewdev
);
480 attr
= (unsigned char) ((mode
& ATTR_INV
) ? (0x70) : (0x07));
481 if (mode
& ATTR_UL
) attr
|= 0x01;
482 if (mode
& ATTR_BOLD
) attr
|= 0x08;
483 if (mode
& ATTR_BLINK
) attr
|= 0x80;
485 cp
= (u_short
*)v
->bitmap
->plane
;
486 cp
[(dy
* ip
->cols
) + dx
] = (c
<< 8) | attr
;
490 et_clear(struct ite_softc
*ip
, int sy
, int sx
, int h
, int w
)
492 /* et_clear and et_scroll both rely on ite passing arguments
493 * which describe continuous regions. For a VT200 terminal,
494 * this is safe behavior.
496 view_t
*v
= viewview(ip
->grf
->g_viewdev
);
500 dest
= (u_short
*)v
->bitmap
->plane
+ (sy
* ip
->cols
) + sx
;
501 for(len
= w
* h
; len
-- ;)
506 et_scroll(struct ite_softc
*ip
, int sy
, int sx
, int count
, int dir
)
508 view_t
*v
= viewview(ip
->grf
->g_viewdev
);
513 fb
= (u_short
*)v
->bitmap
->plane
+ sy
* ip
->cols
;
517 dst
= fb
- count
* ip
->cols
;
518 len
= (ip
->bottom_margin
+ 1 - sy
) * ip
->cols
;
522 dst
= fb
+ count
* ip
->cols
;
523 len
= (ip
->bottom_margin
+ 1 - (sy
+ count
)) * ip
->cols
;
527 dst
= fb
+ sx
+ count
;
528 len
= ip
->cols
- sx
+ count
;
532 dst
= fb
+ sx
- count
;
551 et_inittextmode(struct ite_softc
*ip
, et_sv_reg_t
*etregs
, int loadfont
)
559 view_t
*v
= viewview(ip
->grf
->g_viewdev
);
560 et_sv_reg_t loc_regs
;
562 if (etregs
== NULL
) {
567 ba
= ((ipriv_t
*)ip
->priv
)->regkva
;
568 fb
= v
->bitmap
->plane
;
570 #if defined(KFONT_8X8)
573 fd
= &font_info_8x16
;
576 if (loadfont
) { /* XXX: We should set the colormap */
580 vgaw(ba
, VDAC_ADDRESS_W
, 0);
581 for (z
= 0; z
< 256; z
++) {
582 y
= (z
& 1) ? ((z
> 7) ? 2 : 1) : 0;
584 vgaw(ba
, VDAC_DATA
, etconscolors
[y
][0]);
585 vgaw(ba
, VDAC_DATA
, etconscolors
[y
][1]);
586 vgaw(ba
, VDAC_DATA
, etconscolors
[y
][2]);
590 * Enter a suitable mode to download the font. This
591 * basically means sequential addressing mode
595 WAttr(ba
, 0x20 | ACT_ID_ATTR_MODE_CNTL
, 0x0a);
596 WSeq(ba
, SEQ_ID_MAP_MASK
, 0x04);
597 WSeq(ba
, SEQ_ID_MEMORY_MODE
, 0x06);
598 WGfx(ba
, GCT_ID_READ_MAP_SELECT
, 0x02);
599 WGfx(ba
, GCT_ID_GRAPHICS_MODE
, 0x00);
600 WGfx(ba
, GCT_ID_MISC
, 0x04);
604 * load text font into beginning of display memory. Each
605 * character cell is 32 bytes long (enough for 4 planes)
607 for (z
= 0, c
= fb
; z
< 256 * 32; z
++)
610 c
= (unsigned char *) (fb
) + (32 * fd
->font_lo
);
613 for (; z
<= fd
->font_hi
; z
++, c
+= (32 - fd
->height
))
614 for (y
= 0; y
< fd
->height
; y
++) {
620 * Odd/Even addressing
622 etregs
->seq
[SEQ_ID_MAP_MASK
] = 0x03;
623 etregs
->seq
[SEQ_ID_MEMORY_MODE
] = 0x03;
624 etregs
->grf
[GCT_ID_READ_MAP_SELECT
] = 0x00;
625 etregs
->grf
[GCT_ID_GRAPHICS_MODE
] = 0x10;
626 etregs
->grf
[GCT_ID_MISC
] = 0x06;
629 * Font height + underline location
631 tmp
= etregs
->crt
[CRT_ID_MAX_ROW_ADDRESS
] & 0xe0;
632 etregs
->crt
[CRT_ID_MAX_ROW_ADDRESS
] = tmp
| (fd
->height
- 1);
633 tmp
= etregs
->crt
[CRT_ID_UNDERLINE_LOC
] & 0xe0;
634 etregs
->crt
[CRT_ID_UNDERLINE_LOC
] = tmp
| (fd
->height
- 1);
639 etregs
->crt
[CRT_ID_CURSOR_START
] = 0x00;
640 etregs
->crt
[CRT_ID_CURSOR_END
] = fd
->height
- 1;
641 etregs
->crt
[CRT_ID_CURSOR_LOC_HIGH
] = 0x00;
642 etregs
->crt
[CRT_ID_CURSOR_LOC_LOW
] = 0x00;
647 etregs
->crt
[CRT_ID_MODE_CONTROL
] = 0xa3;
648 etregs
->attr
[ACT_ID_ATTR_MODE_CNTL
] = 0x0a;
651 if (loadfont
|| (etregs
== &loc_regs
))
653 if (etregs
== &loc_regs
)