1 /* $NetBSD: ite_cv3d.c,v 1.6 2007/03/04 05:59:22 christos Exp $ */
4 * Copyright (c) 1995 Michael Teske
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.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christian E. Hopps,
18 * Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * This code is based on ite_cl.c and ite_rh.c by
37 * Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg.
40 #include "opt_amigacons.h"
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: ite_cv3d.c,v 1.6 2007/03/04 05:59:22 christos Exp $");
48 #include <sys/param.h>
51 #include <sys/device.h>
52 #include <sys/ioctl.h>
54 #include <sys/systm.h>
55 #include <sys/queue.h>
56 #include <sys/termios.h>
57 #include <sys/malloc.h>
59 #include <machine/cpu.h>
60 #include <amiga/dev/itevar.h>
61 #include <amiga/dev/iteioctl.h>
62 #include <amiga/amiga/device.h>
63 #include <amiga/dev/grfioctl.h>
64 #include <amiga/dev/grfvar.h>
65 #include <amiga/dev/grf_cv3dreg.h>
67 void cv3d_ite_init(struct ite_softc
*);
68 void cv3d_ite_deinit(struct ite_softc
*);
69 static void cv3d_cursor(struct ite_softc
*, int);
70 static void cv3d_putc(struct ite_softc
*, int, int, int, int);
71 static void cv3d_clear(struct ite_softc
*, int, int, int, int);
72 static void cv3d_scroll(struct ite_softc
*, int, int, int, int);
75 * called from grf_cv3d to return console priority
101 * called from grf_cv3d to init ite portion of
105 grfcv3d_iteinit(struct grf_softc
*gp
)
107 gp
->g_itecursor
= cv3d_cursor
;
108 gp
->g_iteputc
= cv3d_putc
;
109 gp
->g_iteclear
= cv3d_clear
;
110 gp
->g_itescroll
= cv3d_scroll
;
111 gp
->g_iteinit
= cv3d_ite_init
;
112 gp
->g_itedeinit
= cv3d_ite_deinit
;
117 cv3d_ite_deinit(struct ite_softc
*ip
)
119 ip
->flags
&= ~ITE_INITED
;
123 static unsigned short cv3d_rowc
[MAXCOLS
*(MAXROWS
+1)];
126 * Console buffer to avoid the slow reading from gfx mem.
129 static unsigned short *console_buffer
;
132 cv3d_ite_init(register struct ite_softc
*ip
)
134 struct grfcv3dtext_mode
*md
;
136 static char first
= 1;
137 volatile unsigned short *fb
= (volatile unsigned short *)ip
->grf
->g_fbkva
;
138 unsigned short *buffer
;
141 ip
->priv
= ip
->grf
->g_data
;
142 md
= (struct grfcv3dtext_mode
*) ip
->grf
->g_data
;
149 #if 0 /* XXX malloc seems not to work in early init :( */
151 free(cv3d_rowc
, M_DEVBUF
);
153 /* alloc all in one */
154 cv3d_rowc
= malloc(sizeof(short) * (ip
->rows
+ 1) * (ip
->cols
+ 2),
157 panic("No buffers for ite_cv3d!");
160 console_buffer
= cv3d_rowc
+ ip
->rows
+ 1;
163 for (i
= 0; i
< ip
->rows
; i
++)
164 cv3d_rowc
[i
] = i
* ip
->cols
;
167 for (i
= 0; i
< ip
->rows
* ip
->cols
; i
++)
168 console_buffer
[i
] = 0x2007;
170 } else { /* restore console */
171 buffer
= console_buffer
;
172 for (i
= 0; i
< ip
->rows
* ip
->cols
; i
++) {
181 cv3d_cursor(struct ite_softc
*ip
, int flag
)
183 volatile void *ba
= ip
->grf
->g_regkva
;
187 /*WCrt(ba, CRT_ID_CURSOR_START, & ~0x20); */
189 flag
= ip
->curx
+ ip
->cury
* ip
->cols
;
190 WCrt(ba
, CRT_ID_CURSOR_LOC_LOW
, flag
& 0xff);
191 WCrt(ba
, CRT_ID_CURSOR_LOC_HIGH
, flag
>> 8);
192 ip
->cursorx
= ip
->curx
;
193 ip
->cursory
= ip
->cury
;
196 /*WCrt(ba, CRT_ID_CURSOR_START, | 0x20); */
197 case START_CURSOROPT
:
206 cv3d_putc(struct ite_softc
*ip
, int c
, int dy
, int dx
, int mode
)
208 volatile void *fb
= ip
->grf
->g_fbkva
;
210 volatile unsigned char *cp
;
212 attr
= (unsigned char) ((mode
& ATTR_INV
) ? (0x70) : (0x07));
213 if (mode
& ATTR_UL
) attr
= 0x01;
214 if (mode
& ATTR_BOLD
) attr
|= 0x08;
215 if (mode
& ATTR_BLINK
) attr
|= 0x80;
217 cp
= (volatile char*)fb
+ ((cv3d_rowc
[dy
] + dx
) << 2); /* *4 */
218 *cp
++ = (unsigned char) c
;
219 *cp
= (unsigned char) attr
;
221 cp
= (volatile unsigned char *) &console_buffer
[cv3d_rowc
[dy
]+dx
];
222 *cp
++ = (unsigned char) c
;
223 *cp
= (unsigned char) attr
;
228 cv3d_clear(struct ite_softc
*ip
, int sy
, int sx
, int h
, int w
)
230 /* cv3d_clear and cv3d_scroll both rely on ite passing arguments
231 * which describe continuous regions. For a VT200 terminal,
232 * this is safe behavior.
234 volatile unsigned short *dst
;
237 dst
= (volatile unsigned short *)
238 ((volatile char*)ip
->grf
->g_fbkva
+
239 (((sy
* ip
->cols
) + sx
) << 2));
241 for (len
= w
* h
; len
> 0 ; len
--) {
246 dst
= &console_buffer
[(sy
* ip
->cols
) + sx
];
247 for (len
= w
* h
; len
> 0 ; len
--) {
253 cv3d_scroll(struct ite_softc
*ip
, int sy
, int sx
, int count
, int dir
)
255 volatile unsigned short *src
, *dst
, *dst2
;
259 src
= (volatile unsigned short *)
260 ((volatile char*)ip
->grf
->g_fbkva
+ (cv3d_rowc
[sy
] << 2));
264 dst
= src
- ((cv3d_rowc
[count
])<<1);
266 len
= cv3d_rowc
[(ip
->bottom_margin
+ 1 - sy
)];
267 src
= &console_buffer
[cv3d_rowc
[sy
]];
269 if (count
> sy
) { /* boundary checks */
270 dst2
= console_buffer
;
271 dst
= (volatile unsigned short *)(ip
->grf
->g_fbkva
);
272 len
-= cv3d_rowc
[(count
- sy
)];
273 src
+= cv3d_rowc
[(count
- sy
)];
275 dst2
= &console_buffer
[cv3d_rowc
[(sy
-count
)]];
277 bcopy (__UNVOLATILE(src
), __UNVOLATILE(dst2
), len
<< 1);
279 for (i
= 0; i
< len
; i
++) {
285 dst
= src
+ ((cv3d_rowc
[count
]) << 1);
287 len
= cv3d_rowc
[(ip
->bottom_margin
+ 1 - (sy
+ count
))];
288 src
= &console_buffer
[cv3d_rowc
[sy
]];
289 dst2
= &console_buffer
[cv3d_rowc
[(sy
+ count
)]];
292 return; /* do some boundary check */
294 bcopy (__UNVOLATILE(src
), __UNVOLATILE(dst2
), len
<< 1);
296 for (i
= 0; i
< len
; i
++) {
302 dst
= src
+ ((sx
+count
)<<1);
303 src
= &console_buffer
[cv3d_rowc
[sy
] + sx
];
304 len
= ip
->cols
- (sx
+ count
);
305 dst2
= &console_buffer
[cv3d_rowc
[sy
] + sx
+ count
];
306 bcopy (__UNVOLATILE(src
), __UNVOLATILE(dst2
), len
<< 1);
308 for (i
= 0; i
< len
; i
++) {
314 dst
= src
+ ((sx
- count
)<<1);
315 src
= &console_buffer
[cv3d_rowc
[sy
] + sx
];
317 dst2
= &console_buffer
[cv3d_rowc
[sy
] + sx
- count
];
318 bcopy (__UNVOLATILE(src
), __UNVOLATILE(dst2
), len
<< 1);
320 for (i
= 0; i
< len
; i
++) {
327 #endif /* NGRFCV3D */