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