1/* $OpenBSD: pcdisplay_subr.c,v 1.14 2020/05/25 09:55:48 jsg 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 43void 44pcdisplay_cursor_reset(struct pcdisplayscreen *scr) 45{ 46#ifdef PCDISPLAY_SOFTCURSOR 47 pcdisplay_6845_write(scr->hdl, curstart, 0x20); 48 pcdisplay_6845_write(scr->hdl, curend, 0x00); 49#endif 50} 51 52void 53pcdisplay_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 83int 84pcdisplay_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 119done: 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 147int 148pcdisplay_putchar(void *id, int row, int col, u_int c, uint32_t attr) 149{ 150 struct pcdisplayscreen *scr = id; 151 bus_space_tag_t memt = scr->hdl->ph_memt; 152 bus_space_handle_t memh = scr->hdl->ph_memh; 153 int off; 154 int s; 155 156 off = row * scr->type->ncols + col; 157 158 s = spltty(); 159 if (scr->active) 160 bus_space_write_2(memt, memh, scr->dispoffset + off * 2, 161 c | (attr << 8)); 162 else 163 scr->mem[off] = c | (attr << 8); 164 splx(s); 165 166 return 0; 167} 168 169int 170pcdisplay_getchar(void *id, int row, int col, struct wsdisplay_charcell *cell) 171{ 172 struct pcdisplayscreen *scr = id; 173 bus_space_tag_t memt = scr->hdl->ph_memt; 174 bus_space_handle_t memh = scr->hdl->ph_memh; 175 int off; 176 int s; 177 u_int16_t data; 178 179 off = row * scr->type->ncols + col; 180 /* XXX bounds check? */ 181 182 s = spltty(); 183 if (scr->active) 184 data = (bus_space_read_2(memt, memh, 185 scr->dispoffset + off * 2)); 186 else 187 data = (scr->mem[off]); 188 splx(s); 189 190 cell->uc = data & 0xff; 191 cell->attr = data >> 8; 192 193 return (0); 194} 195 196int 197pcdisplay_copycols(void *id, int row, int srccol, int dstcol, int ncols) 198{ 199 struct pcdisplayscreen *scr = id; 200 bus_space_tag_t memt = scr->hdl->ph_memt; 201 bus_space_handle_t memh = scr->hdl->ph_memh; 202 bus_size_t srcoff, dstoff; 203 int s; 204 205 srcoff = dstoff = row * scr->type->ncols; 206 srcoff += srccol; 207 dstoff += dstcol; 208 209 s = spltty(); 210 if (scr->active) 211 bus_space_copy_2(memt, memh, 212 scr->dispoffset + srcoff * 2, 213 memh, scr->dispoffset + dstoff * 2, 214 ncols); 215 else 216 bcopy(&scr->mem[srcoff], &scr->mem[dstoff], ncols * 2); 217 splx(s); 218 219 return 0; 220} 221 222int 223pcdisplay_erasecols(void *id, int row, int startcol, int ncols, uint32_t fillattr) 224{ 225 struct pcdisplayscreen *scr = id; 226 bus_space_tag_t memt = scr->hdl->ph_memt; 227 bus_space_handle_t memh = scr->hdl->ph_memh; 228 bus_size_t off; 229 u_int16_t val; 230 int i; 231 int s; 232 233 off = row * scr->type->ncols + startcol; 234 val = (fillattr << 8) | ' '; 235 236 s = spltty(); 237 if (scr->active) 238 bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2, 239 val, ncols); 240 else 241 for (i = 0; i < ncols; i++) 242 scr->mem[off + i] = val; 243 splx(s); 244 245 return 0; 246} 247 248int 249pcdisplay_copyrows(void *id, int srcrow, int dstrow, int nrows) 250{ 251 struct pcdisplayscreen *scr = id; 252 bus_space_tag_t memt = scr->hdl->ph_memt; 253 bus_space_handle_t memh = scr->hdl->ph_memh; 254 int ncols = scr->type->ncols; 255 bus_size_t srcoff, dstoff; 256 int s; 257 258 srcoff = srcrow * ncols + 0; 259 dstoff = dstrow * ncols + 0; 260 261 s = spltty(); 262 if (scr->active) 263 bus_space_copy_2(memt, memh, 264 scr->dispoffset + srcoff * 2, 265 memh, scr->dispoffset + dstoff * 2, 266 nrows * ncols); 267 else 268 bcopy(&scr->mem[srcoff], &scr->mem[dstoff], 269 nrows * ncols * 2); 270 splx(s); 271 272 return 0; 273} 274 275int 276pcdisplay_eraserows(void *id, int startrow, int nrows, uint32_t fillattr) 277{ 278 struct pcdisplayscreen *scr = id; 279 bus_space_tag_t memt = scr->hdl->ph_memt; 280 bus_space_handle_t memh = scr->hdl->ph_memh; 281 bus_size_t off, count, n; 282 u_int16_t val; 283 int s; 284 285 off = startrow * scr->type->ncols; 286 count = nrows * scr->type->ncols; 287 val = (fillattr << 8) | ' '; 288 289 s = spltty(); 290 if (scr->active) 291 bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2, 292 val, count); 293 else 294 for (n = 0; n < count; n++) 295 scr->mem[off + n] = val; 296 splx(s); 297 298 return 0; 299} 300