1 1.8 he /* $NetBSD: ite_cv.c,v 1.8 2007/03/05 20:29:07 he Exp $ */ 2 1.1 veego 3 1.1 veego /* 4 1.1 veego * Copyright (c) 1995 Michael Teske 5 1.1 veego * All rights reserved. 6 1.1 veego * 7 1.1 veego * Redistribution and use in source and binary forms, with or without 8 1.1 veego * modification, are permitted provided that the following conditions 9 1.1 veego * are met: 10 1.1 veego * 1. Redistributions of source code must retain the above copyright 11 1.1 veego * notice, this list of conditions and the following disclaimer. 12 1.1 veego * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 veego * notice, this list of conditions and the following disclaimer in the 14 1.1 veego * documentation and/or other materials provided with the distribution. 15 1.1 veego * 3. All advertising materials mentioning features or use of this software 16 1.1 veego * must display the following acknowledgement: 17 1.2 veego * This product includes software developed by Christian E. Hopps, 18 1.2 veego * Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg 19 1.2 veego * and Michael Teske. 20 1.1 veego * 4. The name of the author may not be used to endorse or promote products 21 1.1 veego * derived from this software without specific prior written permission 22 1.1 veego * 23 1.1 veego * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 1.1 veego * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 1.1 veego * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 1.1 veego * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 1.1 veego * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 1.1 veego * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 1.1 veego * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 1.1 veego * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 1.1 veego * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 1.1 veego * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 1.1 veego */ 34 1.2 veego 35 1.1 veego /* 36 1.3 veego * This code is based on ite_cl.c and ite_rh.c by 37 1.2 veego * Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg. 38 1.1 veego */ 39 1.2 veego 40 1.4 is #include "opt_amigacons.h" 41 1.6 aymeric 42 1.6 aymeric #include <sys/cdefs.h> 43 1.8 he __KERNEL_RCSID(0, "$NetBSD: ite_cv.c,v 1.8 2007/03/05 20:29:07 he Exp $"); 44 1.6 aymeric 45 1.1 veego #include "grfcv.h" 46 1.1 veego #if NGRFCV > 0 47 1.2 veego 48 1.1 veego #include <sys/param.h> 49 1.1 veego #include <sys/conf.h> 50 1.1 veego #include <sys/proc.h> 51 1.1 veego #include <sys/device.h> 52 1.1 veego #include <sys/ioctl.h> 53 1.1 veego #include <sys/tty.h> 54 1.1 veego #include <sys/systm.h> 55 1.1 veego #include <sys/queue.h> 56 1.1 veego #include <sys/termios.h> 57 1.1 veego #include <sys/malloc.h> 58 1.1 veego #include <dev/cons.h> 59 1.1 veego #include <machine/cpu.h> 60 1.1 veego #include <amiga/dev/itevar.h> 61 1.1 veego #include <amiga/dev/iteioctl.h> 62 1.5 aymeric #include <amiga/amiga/device.h> 63 1.1 veego #include <amiga/dev/grfioctl.h> 64 1.1 veego #include <amiga/dev/grfvar.h> 65 1.1 veego #include <amiga/dev/grf_cvreg.h> 66 1.1 veego 67 1.5 aymeric void cv_ite_init(struct ite_softc *); 68 1.5 aymeric void cv_ite_deinit(struct ite_softc *); 69 1.5 aymeric static void cv_cursor(struct ite_softc *, int); 70 1.5 aymeric static void cv_putc(struct ite_softc *, int, int, int, int); 71 1.5 aymeric static void cv_clear(struct ite_softc *, int, int, int, int); 72 1.5 aymeric static void cv_scroll(struct ite_softc *, int, int, int, int); 73 1.2 veego 74 1.1 veego /* 75 1.1 veego * called from grf_cv to return console priority 76 1.1 veego */ 77 1.1 veego int 78 1.5 aymeric grfcv_cnprobe(void) 79 1.1 veego { 80 1.1 veego static int done; 81 1.1 veego int rv; 82 1.2 veego 83 1.2 veego if (done == 0) 84 1.1 veego #ifdef CV64CONSOLE 85 1.2 veego rv = CN_INTERNAL; 86 1.1 veego #else 87 1.1 veego rv = CN_DEAD; 88 1.1 veego #endif 89 1.1 veego else 90 1.1 veego #ifdef CV64CONSOLE 91 1.1 veego rv = CN_NORMAL; 92 1.1 veego #else 93 1.1 veego rv = CN_DEAD; 94 1.1 veego #endif 95 1.1 veego done = 1; 96 1.1 veego return(rv); 97 1.1 veego } 98 1.2 veego 99 1.1 veego 100 1.1 veego /* 101 1.1 veego * called from grf_cv to init ite portion of 102 1.1 veego * grf_softc struct 103 1.1 veego */ 104 1.1 veego void 105 1.5 aymeric grfcv_iteinit(struct grf_softc *gp) 106 1.1 veego { 107 1.1 veego gp->g_itecursor = cv_cursor; 108 1.1 veego gp->g_iteputc = cv_putc; 109 1.1 veego gp->g_iteclear = cv_clear; 110 1.1 veego gp->g_itescroll = cv_scroll; 111 1.1 veego gp->g_iteinit = cv_ite_init; 112 1.1 veego gp->g_itedeinit = cv_ite_deinit; 113 1.1 veego } 114 1.1 veego 115 1.2 veego 116 1.1 veego void 117 1.5 aymeric cv_ite_deinit(struct ite_softc *ip) 118 1.1 veego { 119 1.2 veego ip->flags &= ~ITE_INITED; 120 1.1 veego } 121 1.2 veego 122 1.2 veego 123 1.3 veego static unsigned short cv_rowc[MAXCOLS*(MAXROWS+1)]; 124 1.3 veego 125 1.3 veego /* 126 1.3 veego * Console buffer to avoid the slow reading from gfx mem. 127 1.3 veego */ 128 1.3 veego 129 1.3 veego static unsigned short *console_buffer; 130 1.3 veego 131 1.1 veego void 132 1.5 aymeric cv_ite_init(register struct ite_softc *ip) 133 1.1 veego { 134 1.2 veego struct grfcvtext_mode *md; 135 1.1 veego int i; 136 1.3 veego static char first = 1; 137 1.3 veego volatile unsigned short *fb = (volatile unsigned short *)ip->grf->g_fbkva; 138 1.3 veego unsigned short *buffer; 139 1.3 veego 140 1.2 veego 141 1.2 veego ip->priv = ip->grf->g_data; 142 1.1 veego md = (struct grfcvtext_mode *) ip->grf->g_data; 143 1.2 veego 144 1.1 veego ip->cols = md->cols; 145 1.1 veego ip->rows = md->rows; 146 1.3 veego 147 1.3 veego /* alloc buffers */ 148 1.3 veego 149 1.3 veego #if 0 /* XXX malloc seems not to work in early init :( */ 150 1.3 veego if (cv_rowc) 151 1.3 veego free(cv_rowc, M_DEVBUF); 152 1.5 aymeric 153 1.3 veego /* alloc all in one */ 154 1.3 veego cv_rowc = malloc(sizeof(short) * (ip->rows + 1) * (ip->cols + 2), 155 1.3 veego M_DEVBUF, M_WAITOK); 156 1.3 veego if (!cv_rowc) 157 1.3 veego panic("No buffers for ite_cv!"); 158 1.3 veego #endif 159 1.5 aymeric 160 1.3 veego console_buffer = cv_rowc + ip->rows + 1; 161 1.3 veego 162 1.2 veego 163 1.2 veego for (i = 0; i < ip->rows; i++) 164 1.2 veego cv_rowc[i] = i * ip->cols; 165 1.3 veego 166 1.3 veego if (first) { 167 1.3 veego for (i = 0; i < ip->rows * ip->cols; i++) 168 1.3 veego console_buffer[i] = 0x2007; 169 1.3 veego first = 0; 170 1.3 veego } else { /* restore console */ 171 1.3 veego buffer = console_buffer; 172 1.3 veego for (i = 0; i < ip->rows * ip->cols; i++) { 173 1.3 veego *fb++ = *buffer++; 174 1.3 veego *fb++; 175 1.3 veego } 176 1.3 veego } 177 1.1 veego } 178 1.1 veego 179 1.2 veego 180 1.1 veego void 181 1.5 aymeric cv_cursor(struct ite_softc *ip, int flag) 182 1.1 veego { 183 1.7 christos volatile void *ba = ip->grf->g_regkva; 184 1.2 veego 185 1.2 veego switch (flag) { 186 1.2 veego case DRAW_CURSOR: 187 1.2 veego /*WCrt(ba, CRT_ID_CURSOR_START, & ~0x20); */ 188 1.2 veego case MOVE_CURSOR: 189 1.2 veego flag = ip->curx + ip->cury * ip->cols; 190 1.2 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, flag & 0xff); 191 1.2 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, flag >> 8); 192 1.2 veego ip->cursorx = ip->curx; 193 1.2 veego ip->cursory = ip->cury; 194 1.2 veego break; 195 1.2 veego case ERASE_CURSOR: 196 1.2 veego /*WCrt(ba, CRT_ID_CURSOR_START, | 0x20); */ 197 1.2 veego case START_CURSOROPT: 198 1.2 veego case END_CURSOROPT: 199 1.2 veego default: 200 1.2 veego break; 201 1.1 veego } 202 1.1 veego } 203 1.1 veego 204 1.1 veego 205 1.1 veego void 206 1.5 aymeric cv_putc(struct ite_softc *ip, int c, int dy, int dx, int mode) 207 1.2 veego { 208 1.8 he volatile char *fb = ip->grf->g_fbkva; 209 1.2 veego unsigned char attr; 210 1.8 he volatile unsigned char *cp; 211 1.2 veego 212 1.2 veego attr = (unsigned char) ((mode & ATTR_INV) ? (0x70) : (0x07)); 213 1.2 veego if (mode & ATTR_UL) attr = 0x01; 214 1.2 veego if (mode & ATTR_BOLD) attr |= 0x08; 215 1.2 veego if (mode & ATTR_BLINK) attr |= 0x80; 216 1.2 veego 217 1.2 veego cp = fb + ((cv_rowc[dy] + dx) << 2); /* *4 */ 218 1.2 veego *cp++ = (unsigned char) c; 219 1.2 veego *cp = (unsigned char) attr; 220 1.3 veego 221 1.2 veego cp = (unsigned char *) &console_buffer[cv_rowc[dy]+dx]; 222 1.2 veego *cp++ = (unsigned char) c; 223 1.2 veego *cp = (unsigned char) attr; 224 1.1 veego } 225 1.1 veego 226 1.1 veego 227 1.1 veego void 228 1.5 aymeric cv_clear(struct ite_softc *ip, int sy, int sx, int h, int w) 229 1.2 veego { 230 1.2 veego /* cv_clear and cv_scroll both rely on ite passing arguments 231 1.2 veego * which describe continuous regions. For a VT200 terminal, 232 1.2 veego * this is safe behavior. 233 1.2 veego */ 234 1.8 he volatile unsigned short *dst; 235 1.2 veego int len; 236 1.1 veego 237 1.8 he dst = (volatile unsigned short *) 238 1.8 he ((volatile char*)ip->grf->g_fbkva + 239 1.8 he (((sy * ip->cols) + sx) << 2)); 240 1.1 veego 241 1.3 veego for (len = w * h; len > 0 ; len--) { 242 1.2 veego *dst = 0x2007; 243 1.2 veego dst +=2; 244 1.2 veego } 245 1.1 veego 246 1.2 veego dst = &console_buffer[(sy * ip->cols) + sx]; 247 1.3 veego for (len = w * h; len > 0 ; len--) { 248 1.2 veego *dst++ = 0x2007; 249 1.2 veego } 250 1.1 veego } 251 1.1 veego 252 1.2 veego void 253 1.5 aymeric cv_scroll(struct ite_softc *ip, int sy, int sx, int count, int dir) 254 1.2 veego { 255 1.8 he volatile unsigned short *src, *dst, *dst2; 256 1.2 veego int i; 257 1.2 veego int len; 258 1.1 veego 259 1.8 he src = (volatile unsigned short *) 260 1.8 he ((volatile char*)ip->grf->g_fbkva + (cv_rowc[sy] << 2)); 261 1.1 veego 262 1.1 veego switch (dir) { 263 1.2 veego case SCROLL_UP: 264 1.3 veego dst = src - ((cv_rowc[count])<<1); 265 1.3 veego 266 1.3 veego len = cv_rowc[(ip->bottom_margin + 1 - sy)]; 267 1.3 veego src = &console_buffer[cv_rowc[sy]]; 268 1.3 veego 269 1.2 veego if (count > sy) { /* boundary checks */ 270 1.2 veego dst2 = console_buffer; 271 1.8 he dst = (volatile unsigned short *)(ip->grf->g_fbkva); 272 1.3 veego len -= cv_rowc[(count - sy)]; 273 1.3 veego src += cv_rowc[(count - sy)]; 274 1.3 veego } else 275 1.3 veego dst2 = &console_buffer[cv_rowc[(sy-count)]]; 276 1.3 veego 277 1.8 he bcopy (__UNVOLATILE(src), __UNVOLATILE(dst2), len << 1); 278 1.2 veego 279 1.2 veego for (i = 0; i < len; i++) { 280 1.2 veego *dst++ = *dst2++; 281 1.2 veego dst++; 282 1.2 veego } 283 1.1 veego break; 284 1.2 veego case SCROLL_DOWN: 285 1.3 veego dst = src + ((cv_rowc[count]) << 1); 286 1.3 veego 287 1.3 veego len = cv_rowc[(ip->bottom_margin + 1 - (sy + count))]; 288 1.3 veego src = &console_buffer[cv_rowc[sy]]; 289 1.3 veego dst2 = &console_buffer[cv_rowc[(sy + count)]]; 290 1.3 veego 291 1.3 veego if (len < 0) 292 1.3 veego return; /* do some boundary check */ 293 1.3 veego 294 1.8 he bcopy (__UNVOLATILE(src), __UNVOLATILE(dst2), len << 1); 295 1.2 veego 296 1.2 veego for (i = 0; i < len; i++) { 297 1.2 veego *dst++ = *dst2++; 298 1.2 veego dst++; 299 1.2 veego } 300 1.1 veego break; 301 1.2 veego case SCROLL_RIGHT: 302 1.2 veego dst = src + ((sx+count)<<1); 303 1.3 veego src = &console_buffer[cv_rowc[sy] + sx]; 304 1.2 veego len = ip->cols - (sx + count); 305 1.3 veego dst2 = &console_buffer[cv_rowc[sy] + sx + count]; 306 1.8 he bcopy (__UNVOLATILE(src), __UNVOLATILE(dst2), len << 1); 307 1.2 veego 308 1.2 veego for (i = 0; i < len; i++) { 309 1.2 veego *dst++ = *dst2++; 310 1.2 veego dst++; 311 1.2 veego } 312 1.1 veego break; 313 1.2 veego case SCROLL_LEFT: 314 1.2 veego dst = src + ((sx - count)<<1); 315 1.3 veego src = &console_buffer[cv_rowc[sy] + sx]; 316 1.2 veego len = ip->cols - sx; 317 1.3 veego dst2 = &console_buffer[cv_rowc[sy] + sx - count]; 318 1.8 he bcopy (__UNVOLATILE(src), __UNVOLATILE(dst2), len << 1); 319 1.2 veego 320 1.2 veego for (i = 0; i < len; i++) { 321 1.2 veego *dst++ = *dst2++; 322 1.2 veego dst++; 323 1.2 veego } 324 1.1 veego } 325 1.1 veego } 326 1.2 veego 327 1.1 veego #endif /* NGRFCV */ 328