The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/pcdisplay_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: pcdisplay_subr.c,v 1.36 2022/03/25 12:24:44 uwe 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/cdefs.h>
   31 __KERNEL_RCSID(0, "$NetBSD: pcdisplay_subr.c,v 1.36 2022/03/25 12:24:44 uwe Exp $");
   32 
   33 #include "opt_wsmsgattrs.h" /* for WSDISPLAY_CUSTOM_OUTPUT */
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/device.h>
   38 #include <sys/bus.h>
   39 
   40 #include <dev/ic/mc6845reg.h>
   41 #include <dev/ic/pcdisplayvar.h>
   42 #include <dev/wscons/wsconsio.h>
   43 
   44 #include <dev/wscons/wsdisplayvar.h>
   45 
   46 void
   47 pcdisplay_cursor_init(struct pcdisplayscreen *scr, int existing)
   48 {
   49 #ifdef PCDISPLAY_SOFTCURSOR
   50         bus_space_tag_t memt;
   51         bus_space_handle_t memh;
   52         int off;
   53 
   54         /* Disable the hardware cursor */
   55         pcdisplay_6845_write(scr->hdl, curstart, 0x20);
   56         pcdisplay_6845_write(scr->hdl, curend, 0x00);
   57 
   58         if (existing) {
   59                 /*
   60                  * This is the first screen. At this point, scr->mem is NULL
   61                  * (no backing store), so we can't use pcdisplay_cursor() to
   62                  * do this.
   63                  */
   64                 memt = scr->hdl->ph_memt;
   65                 memh = scr->hdl->ph_memh;
   66                 off = (scr->cursorrow * scr->type->ncols + scr->cursorcol) * 2
   67                     + scr->dispoffset;
   68 
   69                 scr->cursortmp = bus_space_read_2(memt, memh, off);
   70                 bus_space_write_2(memt, memh, off, scr->cursortmp ^ 0x7700);
   71         } else
   72                 scr->cursortmp = 0;
   73 #else
   74         /*
   75          * Firmware might not have initialized the cursor shape.  Make
   76          * sure there's something we can see.
   77          * Don't touch the hardware if this is not the first screen.
   78          */
   79         if (existing) {
   80                 pcdisplay_6845_write(scr->hdl, curstart,
   81                                      scr->type->fontheight - 2);
   82                 pcdisplay_6845_write(scr->hdl, curend,
   83                                      scr->type->fontheight - 1);
   84         }
   85 #endif
   86         scr->cursoron = 1;
   87 }
   88 
   89 void
   90 pcdisplay_cursor(void *id, int on, int row, int col)
   91 {
   92 #ifdef PCDISPLAY_SOFTCURSOR
   93         struct pcdisplayscreen *scr = id;
   94         bus_space_tag_t memt = scr->hdl->ph_memt;
   95         bus_space_handle_t memh = scr->hdl->ph_memh;
   96         int off;
   97 
   98         /* Remove old cursor image */
   99         if (scr->cursoron) {
  100                 off = scr->cursorrow * scr->type->ncols + scr->cursorcol;
  101                 if (scr->active)
  102                         bus_space_write_2(memt, memh, scr->dispoffset + off * 2,
  103                             scr->cursortmp);
  104                 else
  105                         scr->mem[off] = scr->cursortmp;
  106         }
  107 
  108         scr->cursorrow = row;
  109         scr->cursorcol = col;
  110 
  111         if ((scr->cursoron = on) == 0)
  112                 return;
  113 
  114         off = (scr->cursorrow * scr->type->ncols + scr->cursorcol);
  115         if (scr->active) {
  116                 off = off * 2 + scr->dispoffset;
  117                 scr->cursortmp = bus_space_read_2(memt, memh, off);
  118                 bus_space_write_2(memt, memh, off, scr->cursortmp ^ 0x7700);
  119         } else {
  120                 scr->cursortmp = scr->mem[off];
  121                 scr->mem[off] = scr->cursortmp ^ 0x7700;
  122         }
  123 #else   /* PCDISPLAY_SOFTCURSOR */
  124         struct pcdisplayscreen *scr = id;
  125         int pos;
  126 
  127         scr->cursorrow = row;
  128         scr->cursorcol = col;
  129         scr->cursoron = on;
  130 
  131         if (scr->active) {
  132                 if (!on)
  133                         pos = 0x3fff;
  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 #endif  /* PCDISPLAY_SOFTCURSOR */
  142 }
  143 
  144 #if 0
  145 unsigned int
  146 pcdisplay_mapchar_simple(void *id, int uni)
  147 {
  148         if (uni < 128)
  149                 return (uni);
  150 
  151         return (1); /* XXX ??? smiley */
  152 }
  153 #endif
  154 
  155 void
  156 pcdisplay_putchar(void *id, int row, int col, unsigned int c, long attr)
  157 {
  158         struct pcdisplayscreen *scr = id;
  159         bus_space_tag_t memt = scr->hdl->ph_memt;
  160         bus_space_handle_t memh = scr->hdl->ph_memh;
  161         size_t off;
  162 
  163         off = row * scr->type->ncols + col;
  164 
  165         /* check for bogus row and column sizes */
  166         if (__predict_false(off >= (scr->type->ncols * scr->type->nrows)))
  167                 return;
  168 
  169         if (scr->active)
  170                 bus_space_write_2(memt, memh, scr->dispoffset + off * 2,
  171                                   c | (attr << 8));
  172         else
  173                 scr->mem[off] = c | (attr << 8);
  174 
  175         scr->visibleoffset = scr->dispoffset;
  176 }
  177 
  178 void
  179 pcdisplay_copycols(void *id, int row, int srccol, int dstcol, int ncols)
  180 {
  181         struct pcdisplayscreen *scr = id;
  182         bus_space_tag_t memt = scr->hdl->ph_memt;
  183         bus_space_handle_t memh = scr->hdl->ph_memh;
  184         bus_size_t srcoff, dstoff;
  185 
  186         srcoff = dstoff = row * scr->type->ncols;
  187         srcoff += srccol;
  188         dstoff += dstcol;
  189 
  190         if (scr->active)
  191                 bus_space_copy_region_2(memt, memh,
  192                                         scr->dispoffset + srcoff * 2,
  193                                         memh, scr->dispoffset + dstoff * 2,
  194                                         ncols);
  195         else
  196                 memcpy(&scr->mem[dstoff], &scr->mem[srcoff], ncols * 2);
  197 }
  198 
  199 void
  200 pcdisplay_erasecols(void *id, int row, int startcol, int ncols, long fillattr)
  201 {
  202         struct pcdisplayscreen *scr = id;
  203         bus_space_tag_t memt = scr->hdl->ph_memt;
  204         bus_space_handle_t memh = scr->hdl->ph_memh;
  205         bus_size_t off;
  206         u_int16_t val;
  207         int i;
  208 
  209         off = row * scr->type->ncols + startcol;
  210 
  211         val = (fillattr << 8) | ' ';
  212 
  213         if (scr->active)
  214                 bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2,
  215                                        val, ncols);
  216         else
  217                 for (i = 0; i < ncols; i++)
  218                         scr->mem[off + i] = val;
  219 }
  220 
  221 void
  222 pcdisplay_copyrows(void *id, int srcrow, int dstrow, int nrows)
  223 {
  224         struct pcdisplayscreen *scr = id;
  225         bus_space_tag_t memt = scr->hdl->ph_memt;
  226         bus_space_handle_t memh = scr->hdl->ph_memh;
  227         int ncols = scr->type->ncols;
  228         bus_size_t srcoff, dstoff;
  229 
  230         srcoff = srcrow * ncols + 0;
  231         dstoff = dstrow * ncols + 0;
  232 
  233         if (scr->active)
  234                 bus_space_copy_region_2(memt, memh,
  235                                         scr->dispoffset + srcoff * 2,
  236                                         memh, scr->dispoffset + dstoff * 2,
  237                                         nrows * ncols);
  238         else
  239                 memcpy(&scr->mem[dstoff], &scr->mem[srcoff],
  240                       nrows * ncols * 2);
  241 }
  242 
  243 void
  244 pcdisplay_eraserows(void *id, int startrow, int nrows, long fillattr)
  245 {
  246         struct pcdisplayscreen *scr = id;
  247         bus_space_tag_t memt = scr->hdl->ph_memt;
  248         bus_space_handle_t memh = scr->hdl->ph_memh;
  249         bus_size_t off, count;
  250         u_int16_t val;
  251         u_int i;
  252 
  253         off = startrow * scr->type->ncols;
  254         count = nrows * scr->type->ncols;
  255 
  256         val = (fillattr << 8) | ' ';
  257 
  258         if (scr->active)
  259                 bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2,
  260                                        val, count);
  261         else
  262                 for (i = 0; i < count; i++)
  263                         scr->mem[off + i] = val;
  264 }
  265 
  266 #ifdef WSDISPLAY_CUSTOM_OUTPUT
  267 void
  268 pcdisplay_replaceattr(void *id, long oldattr, long newattr)
  269 {
  270         struct pcdisplayscreen *scr = id;
  271         bus_space_tag_t memt = scr->hdl->ph_memt;
  272         bus_space_handle_t memh = scr->hdl->ph_memh;
  273         int off;
  274         uint16_t chardata;
  275 
  276         if (scr->active)
  277                 for (off = 0; off < scr->type->nrows * scr->type->ncols;
  278                      off++) {
  279                         chardata = bus_space_read_2(memt, memh,
  280                                                     scr->dispoffset + off * 2);
  281                         if ((long)(chardata >> 8) == oldattr)
  282                                 bus_space_write_2(memt, memh,
  283                                                   scr->dispoffset + off * 2,
  284                                                   ((u_int16_t)(newattr << 8)) |
  285                                                   (chardata & 0x00FF));
  286                 }
  287         else
  288                 for (off = 0; off < scr->type->nrows * scr->type->ncols;
  289                      off++) {
  290                         chardata = scr->mem[off];
  291                         if ((long)(chardata >> 8) == oldattr)
  292                                 scr->mem[off] = ((u_int16_t)(newattr << 8)) |
  293                                                 (chardata & 0x00FF);
  294                 }
  295 }
  296 #endif /* WSDISPLAY_CUSTOM_OUTPUT */
  297 
  298 int
  299 pcdisplay_getwschar(struct pcdisplayscreen *scr, struct wsdisplay_char *wschar)
  300 {
  301         size_t off;
  302         uint16_t chardata;
  303         uint8_t attrbyte;
  304 
  305         KASSERT(scr != NULL && wschar != NULL);
  306 
  307         off = wschar->row * scr->type->ncols + wschar->col;
  308         if (off >= scr->type->ncols * scr->type->nrows)
  309                 return EINVAL;
  310 
  311         if (scr->active)
  312                 chardata = bus_space_read_2(scr->hdl->ph_memt,
  313                     scr->hdl->ph_memh, scr->dispoffset + off * 2);
  314         else
  315                 chardata = scr->mem[off];
  316 
  317         wschar->letter = (chardata & 0x00FF);
  318         wschar->flags = 0;
  319         attrbyte = (chardata & 0xFF00) >> 8;
  320         if ((attrbyte & 0x08)) wschar->flags |= WSDISPLAY_CHAR_BRIGHT;
  321         if ((attrbyte & 0x80)) wschar->flags |= WSDISPLAY_CHAR_BLINK;
  322         wschar->foreground = attrbyte & 0x07;
  323         wschar->background = (attrbyte >> 4) & 0x07;
  324 
  325         return 0;
  326 }
  327 
  328 int
  329 pcdisplay_putwschar(struct pcdisplayscreen *scr, struct wsdisplay_char *wschar)
  330 {
  331         size_t off;
  332         uint16_t chardata;
  333         uint8_t attrbyte;
  334 
  335         KASSERT(scr != NULL && wschar != NULL);
  336 
  337         off = wschar->row * scr->type->ncols + wschar->col;
  338         if (off >= (scr->type->ncols * scr->type->nrows))
  339                 return EINVAL;
  340 
  341         attrbyte = wschar->background & 0x07;
  342         if (wschar->flags & WSDISPLAY_CHAR_BLINK) attrbyte |= 0x08;
  343         attrbyte <<= 4;
  344         attrbyte |= wschar->foreground & 0x07;
  345         if (wschar->flags & WSDISPLAY_CHAR_BRIGHT) attrbyte |= 0x08;
  346         chardata = (attrbyte << 8) | wschar->letter;
  347 
  348         if (scr->active)
  349                 bus_space_write_2(scr->hdl->ph_memt, scr->hdl->ph_memh,
  350                     scr->dispoffset + off * 2, chardata);
  351         else
  352                 scr->mem[off] = chardata;
  353 
  354         return 0;
  355 }

Cache object: adec5e5e4cf913e08ceb8e4cebda0f4a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.