1 /* $OpenBSD: pcdisplay_subr.c,v 1.11 2011/04/11 19:11:01 matthew Exp $ */ 2 /* $NetBSD: pcdisplay_subr.c,v 1.16 2000/06/08 07:01:19 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 6 * All rights reserved. 7 * 8 * Author: Chris G. Demetriou 9 * 10 * Permission to use, copy, modify and distribute this software and 11 * its documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * Carnegie Mellon requests users of this software to return to 21 * 22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23 * School of Computer Science 24 * Carnegie Mellon University 25 * Pittsburgh PA 15213-3890 26 * 27 * any improvements or extensions that they make and grant Carnegie the 28 * rights to redistribute these changes. 29 */ 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/kernel.h> 34 #include <sys/device.h> 35 #include <machine/bus.h> 36 37 #include <dev/ic/mc6845reg.h> 38 #include <dev/ic/pcdisplayvar.h> 39 40 #include <dev/wscons/wsconsio.h> 41 #include <dev/wscons/wsdisplayvar.h> 42 43 void 44 pcdisplay_cursor_reset(struct pcdisplayscreen *scr) 45 { 46 #ifdef PCDISPLAY_SOFTCURSOR 47 pcdisplay_6845_write(scr->hdl, curstart, 0x10); 48 pcdisplay_6845_write(scr->hdl, curend, 0x10); 49 #endif 50 } 51 52 void 53 pcdisplay_cursor_init(struct pcdisplayscreen *scr, int existing) 54 { 55 #ifdef PCDISPLAY_SOFTCURSOR 56 bus_space_tag_t memt; 57 bus_space_handle_t memh; 58 int off; 59 #endif 60 61 pcdisplay_cursor_reset(scr); 62 63 #ifdef PCDISPLAY_SOFTCURSOR 64 if (existing) { 65 /* 66 * This is the first screen. At this point, scr->active is 67 * false and scr->mem is NULL (no backing store), so we 68 * can't use pcdisplay_cursor() to do this. 69 */ 70 memt = scr->hdl->ph_memt; 71 memh = scr->hdl->ph_memh; 72 off = (scr->vc_crow * scr->type->ncols + scr->vc_ccol) * 2 + 73 scr->dispoffset; 74 75 scr->cursortmp = bus_space_read_2(memt, memh, off); 76 bus_space_write_2(memt, memh, off, scr->cursortmp ^ 0x7700); 77 } else 78 scr->cursortmp = 0; 79 #endif 80 scr->cursoron = 1; 81 } 82 83 int 84 pcdisplay_cursor(void *id, int on, int row, int col) 85 { 86 #ifdef PCDISPLAY_SOFTCURSOR 87 struct pcdisplayscreen *scr = id; 88 bus_space_tag_t memt = scr->hdl->ph_memt; 89 bus_space_handle_t memh = scr->hdl->ph_memh; 90 int off; 91 int s = spltty(); 92 93 /* Remove old cursor image */ 94 if (scr->cursoron) { 95 off = scr->vc_crow * scr->type->ncols + scr->vc_ccol; 96 if (scr->active) 97 bus_space_write_2(memt, memh, scr->dispoffset + off * 2, 98 scr->cursortmp); 99 else 100 scr->mem[off] = scr->cursortmp; 101 } 102 103 scr->vc_crow = row; 104 scr->vc_ccol = col; 105 106 if ((scr->cursoron = on) == 0) 107 goto done; 108 109 off = (scr->vc_crow * scr->type->ncols + scr->vc_ccol); 110 if (scr->active) { 111 off = off * 2 + scr->dispoffset; 112 scr->cursortmp = bus_space_read_2(memt, memh, off); 113 bus_space_write_2(memt, memh, off, scr->cursortmp ^ 0x7700); 114 } else { 115 scr->cursortmp = scr->mem[off]; 116 scr->mem[off] = scr->cursortmp ^ 0x7700; 117 } 118 119 done: 120 splx(s); 121 return 0; 122 #else /* PCDISPLAY_SOFTCURSOR */ 123 struct pcdisplayscreen *scr = id; 124 int pos; 125 int s = spltty(); 126 127 scr->vc_crow = row; 128 scr->vc_ccol = col; 129 scr->cursoron = on; 130 131 if (scr->active) { 132 if (!on) 133 pos = 0x1010; 134 else 135 pos = scr->dispoffset / 2 136 + row * scr->type->ncols + col; 137 138 pcdisplay_6845_write(scr->hdl, cursorh, pos >> 8); 139 pcdisplay_6845_write(scr->hdl, cursorl, pos); 140 } 141 142 splx(s); 143 return 0; 144 #endif /* PCDISPLAY_SOFTCURSOR */ 145 } 146 147 #if 0 148 unsigned int 149 pcdisplay_mapchar_simple(void *id, int uni) 150 { 151 if (uni < 128) 152 return (uni); 153 154 return (1); /* XXX ??? smiley */ 155 } 156 #endif 157 158 int 159 pcdisplay_putchar(void *id, int row, int col, u_int c, long attr) 160 { 161 struct pcdisplayscreen *scr = id; 162 bus_space_tag_t memt = scr->hdl->ph_memt; 163 bus_space_handle_t memh = scr->hdl->ph_memh; 164 int off; 165 int s; 166 167 off = row * scr->type->ncols + col; 168 169 s = spltty(); 170 if (scr->active) 171 bus_space_write_2(memt, memh, scr->dispoffset + off * 2, 172 c | (attr << 8)); 173 else 174 scr->mem[off] = c | (attr << 8); 175 splx(s); 176 177 return 0; 178 } 179 180 int 181 pcdisplay_getchar(void *id, int row, int col, struct wsdisplay_charcell *cell) 182 { 183 struct pcdisplayscreen *scr = id; 184 bus_space_tag_t memt = scr->hdl->ph_memt; 185 bus_space_handle_t memh = scr->hdl->ph_memh; 186 int off; 187 int s; 188 u_int16_t data; 189 190 off = row * scr->type->ncols + col; 191 /* XXX bounds check? */ 192 193 s = spltty(); 194 if (scr->active) 195 data = (bus_space_read_2(memt, memh, 196 scr->dispoffset + off * 2)); 197 else 198 data = (scr->mem[off]); 199 splx(s); 200 201 cell->uc = data & 0xff; 202 cell->attr = data >> 8; 203 204 return (0); 205 } 206 207 int 208 pcdisplay_copycols(void *id, int row, int srccol, int dstcol, int ncols) 209 { 210 struct pcdisplayscreen *scr = id; 211 bus_space_tag_t memt = scr->hdl->ph_memt; 212 bus_space_handle_t memh = scr->hdl->ph_memh; 213 bus_size_t srcoff, dstoff; 214 int s; 215 216 srcoff = dstoff = row * scr->type->ncols; 217 srcoff += srccol; 218 dstoff += dstcol; 219 220 s = spltty(); 221 if (scr->active) 222 bus_space_copy_2(memt, memh, 223 scr->dispoffset + srcoff * 2, 224 memh, scr->dispoffset + dstoff * 2, 225 ncols); 226 else 227 bcopy(&scr->mem[srcoff], &scr->mem[dstoff], ncols * 2); 228 splx(s); 229 230 return 0; 231 } 232 233 int 234 pcdisplay_erasecols(void *id, int row, int startcol, int ncols, long fillattr) 235 { 236 struct pcdisplayscreen *scr = id; 237 bus_space_tag_t memt = scr->hdl->ph_memt; 238 bus_space_handle_t memh = scr->hdl->ph_memh; 239 bus_size_t off; 240 u_int16_t val; 241 int i; 242 int s; 243 244 off = row * scr->type->ncols + startcol; 245 val = (fillattr << 8) | ' '; 246 247 s = spltty(); 248 if (scr->active) 249 bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2, 250 val, ncols); 251 else 252 for (i = 0; i < ncols; i++) 253 scr->mem[off + i] = val; 254 splx(s); 255 256 return 0; 257 } 258 259 int 260 pcdisplay_copyrows(void *id, int srcrow, int dstrow, int nrows) 261 { 262 struct pcdisplayscreen *scr = id; 263 bus_space_tag_t memt = scr->hdl->ph_memt; 264 bus_space_handle_t memh = scr->hdl->ph_memh; 265 int ncols = scr->type->ncols; 266 bus_size_t srcoff, dstoff; 267 int s; 268 269 srcoff = srcrow * ncols + 0; 270 dstoff = dstrow * ncols + 0; 271 272 s = spltty(); 273 if (scr->active) 274 bus_space_copy_2(memt, memh, 275 scr->dispoffset + srcoff * 2, 276 memh, scr->dispoffset + dstoff * 2, 277 nrows * ncols); 278 else 279 bcopy(&scr->mem[srcoff], &scr->mem[dstoff], 280 nrows * ncols * 2); 281 splx(s); 282 283 return 0; 284 } 285 286 int 287 pcdisplay_eraserows(void *id, int startrow, int nrows, long fillattr) 288 { 289 struct pcdisplayscreen *scr = id; 290 bus_space_tag_t memt = scr->hdl->ph_memt; 291 bus_space_handle_t memh = scr->hdl->ph_memh; 292 bus_size_t off, count, n; 293 u_int16_t val; 294 int s; 295 296 off = startrow * scr->type->ncols; 297 count = nrows * scr->type->ncols; 298 val = (fillattr << 8) | ' '; 299 300 s = spltty(); 301 if (scr->active) 302 bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2, 303 val, count); 304 else 305 for (n = 0; n < count; n++) 306 scr->mem[off + n] = val; 307 splx(s); 308 309 return 0; 310 } 311