2005-12-11 15:16:03 +03:00
|
|
|
/* $NetBSD: pcdisplay_subr.c,v 1.29 2005/12/11 12:21:28 christos Exp $ */
|
1998-05-28 20:48:40 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Author: Chris G. Demetriou
|
2005-02-27 03:26:58 +03:00
|
|
|
*
|
1998-05-28 20:48:40 +04:00
|
|
|
* Permission to use, copy, modify and distribute this software and
|
|
|
|
* its documentation is hereby granted, provided that both the copyright
|
|
|
|
* notice and this permission notice appear in all copies of the
|
|
|
|
* software, derivative works or modified versions, and any portions
|
|
|
|
* thereof, and that both notices appear in supporting documentation.
|
2005-02-27 03:26:58 +03:00
|
|
|
*
|
|
|
|
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
|
|
|
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
|
1998-05-28 20:48:40 +04:00
|
|
|
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
2005-02-27 03:26:58 +03:00
|
|
|
*
|
1998-05-28 20:48:40 +04:00
|
|
|
* Carnegie Mellon requests users of this software to return to
|
|
|
|
*
|
|
|
|
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
|
|
|
* School of Computer Science
|
|
|
|
* Carnegie Mellon University
|
|
|
|
* Pittsburgh PA 15213-3890
|
|
|
|
*
|
|
|
|
* any improvements or extensions that they make and grant Carnegie the
|
|
|
|
* rights to redistribute these changes.
|
|
|
|
*/
|
|
|
|
|
2001-11-13 16:14:31 +03:00
|
|
|
#include <sys/cdefs.h>
|
2005-12-11 15:16:03 +03:00
|
|
|
__KERNEL_RCSID(0, "$NetBSD: pcdisplay_subr.c,v 1.29 2005/12/11 12:21:28 christos Exp $");
|
Implement support to dynamically change wscons console and kernel colors.
Two new ioctls are added to the wsdisplay device, named WSDISPLAY_GMSGATTRS
and WSDISPLAY_SMSGATTRS, used to retrieve the actual values and set them,
respectively (the name, if you are wondering, comes from "message attributes").
A new emulop is added to the underlying display driver (only vga, for now)
which sets the new attribute for the whole screen, without having to clear
it. This is optional, which means that this also works with other drivers
that don't have this new operation.
Five new kernel options have been added, although only documented in
i386 kernels (for now):
- WSDISPLAY_CUSTOM_OUTPUT, which enables the ioctls described above to
change the colors dynamically from userland. This is enabled by default
in the GENERIC kernel (as well as others) but disabled on all INSTALL*
kernels (as this feature is useless there).
- WS_DEFAULT_COLATTR, WS_DEFAULT_MONOATTR, WS_DEFAULT_BG and WS_DEFAULT_FG,
which specify the default colors for the console at boot time. These have
the same meaning as the (already existing) WS_KERNEL_* variables.
wsconsctl is modified to add msg.default.{attrs,bg,fg} and
msg.kernel.{attrs,bg,fg} to the display part, so that colors can be changed
after boot.
Tested on NetBSD/i386 with vga (and vga in mono mode), and on NetBSD/mac68k.
No objections in tech-kern@.
2004-07-28 16:34:02 +04:00
|
|
|
|
|
|
|
#include "opt_wsdisplay_compat.h" /* for WSDISPLAY_CHARFUNCS */
|
|
|
|
#include "opt_wsmsgattrs.h" /* for WSDISPLAY_CUSTOM_OUTPUT */
|
2001-11-13 16:14:31 +03:00
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/device.h>
|
|
|
|
#include <machine/bus.h>
|
|
|
|
|
|
|
|
#include <dev/ic/mc6845reg.h>
|
|
|
|
#include <dev/ic/pcdisplayvar.h>
|
2002-06-27 03:05:33 +04:00
|
|
|
#include <dev/wscons/wsconsio.h>
|
1998-05-28 20:48:40 +04:00
|
|
|
|
|
|
|
#include <dev/wscons/wsdisplayvar.h>
|
|
|
|
|
2000-01-05 19:14:35 +03:00
|
|
|
void
|
2000-01-25 05:44:03 +03:00
|
|
|
pcdisplay_cursor_init(scr, existing)
|
2000-01-05 19:14:35 +03:00
|
|
|
struct pcdisplayscreen *scr;
|
2000-01-25 05:44:03 +03:00
|
|
|
int existing;
|
2000-01-05 19:14:35 +03:00
|
|
|
{
|
|
|
|
#ifdef PCDISPLAY_SOFTCURSOR
|
2000-01-25 05:44:03 +03:00
|
|
|
bus_space_tag_t memt;
|
|
|
|
bus_space_handle_t memh;
|
|
|
|
int off;
|
|
|
|
|
2000-01-12 17:42:21 +03:00
|
|
|
pcdisplay_6845_write(scr->hdl, curstart, 0x10);
|
|
|
|
pcdisplay_6845_write(scr->hdl, curend, 0x10);
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2000-01-25 05:44:03 +03:00
|
|
|
if (existing) {
|
|
|
|
/*
|
2001-09-04 21:14:49 +04:00
|
|
|
* This is the first screen. At this point, scr->mem is NULL
|
|
|
|
* (no backing store), so we can't use pcdisplay_cursor() to
|
|
|
|
* do this.
|
2000-01-25 05:44:03 +03:00
|
|
|
*/
|
|
|
|
memt = scr->hdl->ph_memt;
|
|
|
|
memh = scr->hdl->ph_memh;
|
2002-07-07 10:36:32 +04:00
|
|
|
off = (scr->cursorrow * scr->type->ncols + scr->cursorcol) * 2
|
|
|
|
+ scr->dispoffset;
|
2000-01-25 05:44:03 +03:00
|
|
|
|
|
|
|
scr->cursortmp = bus_space_read_2(memt, memh, off);
|
|
|
|
bus_space_write_2(memt, memh, off, scr->cursortmp ^ 0x7700);
|
2000-01-26 04:23:32 +03:00
|
|
|
} else
|
|
|
|
scr->cursortmp = 0;
|
2001-07-05 20:45:23 +04:00
|
|
|
#else
|
|
|
|
/*
|
|
|
|
* Firmware might not have initialized the cursor shape. Make
|
|
|
|
* sure there's something we can see.
|
2001-09-04 21:14:49 +04:00
|
|
|
* Don't touch the hardware if this is not the first screen.
|
2001-07-05 20:45:23 +04:00
|
|
|
*/
|
2001-09-04 21:14:49 +04:00
|
|
|
if (existing) {
|
|
|
|
pcdisplay_6845_write(scr->hdl, curstart,
|
|
|
|
scr->type->fontheight - 2);
|
|
|
|
pcdisplay_6845_write(scr->hdl, curend,
|
|
|
|
scr->type->fontheight - 1);
|
|
|
|
}
|
2000-01-05 19:14:35 +03:00
|
|
|
#endif
|
2000-01-25 05:44:03 +03:00
|
|
|
scr->cursoron = 1;
|
2000-01-05 19:14:35 +03:00
|
|
|
}
|
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
void
|
|
|
|
pcdisplay_cursor(id, on, row, col)
|
|
|
|
void *id;
|
|
|
|
int on, row, col;
|
|
|
|
{
|
1999-09-20 01:48:08 +04:00
|
|
|
#ifdef PCDISPLAY_SOFTCURSOR
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
|
|
|
int off;
|
|
|
|
|
|
|
|
/* Remove old cursor image */
|
|
|
|
if (scr->cursoron) {
|
2002-07-07 10:36:32 +04:00
|
|
|
off = scr->cursorrow * scr->type->ncols + scr->cursorcol;
|
1999-09-20 01:48:08 +04:00
|
|
|
if (scr->active)
|
|
|
|
bus_space_write_2(memt, memh, scr->dispoffset + off * 2,
|
|
|
|
scr->cursortmp);
|
|
|
|
else
|
|
|
|
scr->mem[off] = scr->cursortmp;
|
|
|
|
}
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2002-07-07 10:36:32 +04:00
|
|
|
scr->cursorrow = row;
|
|
|
|
scr->cursorcol = col;
|
1999-09-20 01:48:08 +04:00
|
|
|
|
|
|
|
if ((scr->cursoron = on) == 0)
|
|
|
|
return;
|
|
|
|
|
2002-07-07 10:36:32 +04:00
|
|
|
off = (scr->cursorrow * scr->type->ncols + scr->cursorcol);
|
1999-09-20 03:00:04 +04:00
|
|
|
if (scr->active) {
|
2000-01-25 05:44:03 +03:00
|
|
|
off = off * 2 + scr->dispoffset;
|
|
|
|
scr->cursortmp = bus_space_read_2(memt, memh, off);
|
|
|
|
bus_space_write_2(memt, memh, off, scr->cursortmp ^ 0x7700);
|
1999-09-20 03:00:04 +04:00
|
|
|
} else {
|
|
|
|
scr->cursortmp = scr->mem[off];
|
1999-09-29 21:26:06 +04:00
|
|
|
scr->mem[off] = scr->cursortmp ^ 0x7700;
|
1999-09-20 03:00:04 +04:00
|
|
|
}
|
1999-09-20 01:48:08 +04:00
|
|
|
#else /* PCDISPLAY_SOFTCURSOR */
|
1998-05-28 20:48:40 +04:00
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
int pos;
|
|
|
|
|
2002-07-07 10:36:32 +04:00
|
|
|
scr->cursorrow = row;
|
2002-07-07 14:52:18 +04:00
|
|
|
scr->cursorcol = col;
|
1998-05-28 20:48:40 +04:00
|
|
|
scr->cursoron = on;
|
|
|
|
|
|
|
|
if (scr->active) {
|
1999-09-20 01:48:08 +04:00
|
|
|
if (!on)
|
2001-09-04 21:14:49 +04:00
|
|
|
pos = 0x3fff;
|
1999-09-20 01:48:08 +04:00
|
|
|
else
|
1998-07-24 20:12:18 +04:00
|
|
|
pos = scr->dispoffset / 2
|
|
|
|
+ row * scr->type->ncols + col;
|
1998-05-28 20:48:40 +04:00
|
|
|
|
|
|
|
pcdisplay_6845_write(scr->hdl, cursorh, pos >> 8);
|
|
|
|
pcdisplay_6845_write(scr->hdl, cursorl, pos);
|
|
|
|
}
|
1999-09-20 01:48:08 +04:00
|
|
|
#endif /* PCDISPLAY_SOFTCURSOR */
|
1998-05-28 20:48:40 +04:00
|
|
|
}
|
|
|
|
|
1998-06-27 01:05:20 +04:00
|
|
|
#if 0
|
|
|
|
unsigned int
|
|
|
|
pcdisplay_mapchar_simple(id, uni)
|
|
|
|
void *id;
|
|
|
|
int uni;
|
1998-06-21 01:55:05 +04:00
|
|
|
{
|
1998-06-27 01:05:20 +04:00
|
|
|
if (uni < 128)
|
|
|
|
return (uni);
|
|
|
|
|
|
|
|
return (1); /* XXX ??? smiley */
|
|
|
|
}
|
|
|
|
#endif
|
1998-06-21 01:55:05 +04:00
|
|
|
|
1998-05-28 20:48:40 +04:00
|
|
|
void
|
1998-06-21 01:55:05 +04:00
|
|
|
pcdisplay_putchar(id, row, col, c, attr)
|
1998-05-28 20:48:40 +04:00
|
|
|
void *id;
|
|
|
|
int row, col;
|
1998-06-21 01:55:05 +04:00
|
|
|
u_int c;
|
1998-05-28 20:48:40 +04:00
|
|
|
long attr;
|
|
|
|
{
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
1998-06-21 01:55:05 +04:00
|
|
|
int off;
|
1998-05-28 20:48:40 +04:00
|
|
|
|
1998-06-21 01:55:05 +04:00
|
|
|
off = row * scr->type->ncols + col;
|
1998-05-28 20:48:40 +04:00
|
|
|
|
1998-06-21 01:55:05 +04:00
|
|
|
if (scr->active)
|
1998-07-24 20:12:18 +04:00
|
|
|
bus_space_write_2(memt, memh, scr->dispoffset + off * 2,
|
1998-06-27 01:05:20 +04:00
|
|
|
c | (attr << 8));
|
1998-06-21 01:55:05 +04:00
|
|
|
else
|
1998-06-27 01:05:20 +04:00
|
|
|
scr->mem[off] = c | (attr << 8);
|
2004-05-29 01:42:29 +04:00
|
|
|
|
|
|
|
scr->visibleoffset = scr->dispoffset;
|
1998-05-28 20:48:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pcdisplay_copycols(id, row, srccol, dstcol, ncols)
|
|
|
|
void *id;
|
|
|
|
int row, srccol, dstcol, ncols;
|
|
|
|
{
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
|
|
|
bus_size_t srcoff, dstoff;
|
|
|
|
|
|
|
|
srcoff = dstoff = row * scr->type->ncols;
|
|
|
|
srcoff += srccol;
|
|
|
|
dstoff += dstcol;
|
|
|
|
|
|
|
|
if (scr->active)
|
1998-07-24 20:12:18 +04:00
|
|
|
bus_space_copy_region_2(memt, memh,
|
|
|
|
scr->dispoffset + srcoff * 2,
|
|
|
|
memh, scr->dispoffset + dstoff * 2,
|
|
|
|
ncols);
|
1998-05-28 20:48:40 +04:00
|
|
|
else
|
2001-07-07 19:53:13 +04:00
|
|
|
memcpy(&scr->mem[dstoff], &scr->mem[srcoff], ncols * 2);
|
1998-05-28 20:48:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pcdisplay_erasecols(id, row, startcol, ncols, fillattr)
|
|
|
|
void *id;
|
|
|
|
int row, startcol, ncols;
|
|
|
|
long fillattr;
|
|
|
|
{
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
|
|
|
bus_size_t off;
|
|
|
|
u_int16_t val;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
off = row * scr->type->ncols + startcol;
|
|
|
|
|
|
|
|
val = (fillattr << 8) | ' ';
|
|
|
|
|
|
|
|
if (scr->active)
|
1998-07-24 20:12:18 +04:00
|
|
|
bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2,
|
|
|
|
val, ncols);
|
1998-05-28 20:48:40 +04:00
|
|
|
else
|
|
|
|
for (i = 0; i < ncols; i++)
|
|
|
|
scr->mem[off + i] = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pcdisplay_copyrows(id, srcrow, dstrow, nrows)
|
|
|
|
void *id;
|
|
|
|
int srcrow, dstrow, nrows;
|
|
|
|
{
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
|
|
|
int ncols = scr->type->ncols;
|
|
|
|
bus_size_t srcoff, dstoff;
|
|
|
|
|
|
|
|
srcoff = srcrow * ncols + 0;
|
|
|
|
dstoff = dstrow * ncols + 0;
|
|
|
|
|
|
|
|
if (scr->active)
|
1998-07-24 20:12:18 +04:00
|
|
|
bus_space_copy_region_2(memt, memh,
|
|
|
|
scr->dispoffset + srcoff * 2,
|
|
|
|
memh, scr->dispoffset + dstoff * 2,
|
|
|
|
nrows * ncols);
|
1998-05-28 20:48:40 +04:00
|
|
|
else
|
2001-07-07 19:53:13 +04:00
|
|
|
memcpy(&scr->mem[dstoff], &scr->mem[srcoff],
|
1998-05-28 20:48:40 +04:00
|
|
|
nrows * ncols * 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pcdisplay_eraserows(id, startrow, nrows, fillattr)
|
|
|
|
void *id;
|
|
|
|
int startrow, nrows;
|
|
|
|
long fillattr;
|
|
|
|
{
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
|
|
|
bus_size_t off, count;
|
|
|
|
u_int16_t val;
|
2002-08-25 23:11:16 +04:00
|
|
|
u_int i;
|
1998-05-28 20:48:40 +04:00
|
|
|
|
|
|
|
off = startrow * scr->type->ncols;
|
|
|
|
count = nrows * scr->type->ncols;
|
|
|
|
|
|
|
|
val = (fillattr << 8) | ' ';
|
|
|
|
|
|
|
|
if (scr->active)
|
1998-07-24 20:12:18 +04:00
|
|
|
bus_space_set_region_2(memt, memh, scr->dispoffset + off * 2,
|
|
|
|
val, count);
|
1998-05-28 20:48:40 +04:00
|
|
|
else
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
scr->mem[off + i] = val;
|
|
|
|
}
|
2002-06-27 03:05:33 +04:00
|
|
|
|
Implement support to dynamically change wscons console and kernel colors.
Two new ioctls are added to the wsdisplay device, named WSDISPLAY_GMSGATTRS
and WSDISPLAY_SMSGATTRS, used to retrieve the actual values and set them,
respectively (the name, if you are wondering, comes from "message attributes").
A new emulop is added to the underlying display driver (only vga, for now)
which sets the new attribute for the whole screen, without having to clear
it. This is optional, which means that this also works with other drivers
that don't have this new operation.
Five new kernel options have been added, although only documented in
i386 kernels (for now):
- WSDISPLAY_CUSTOM_OUTPUT, which enables the ioctls described above to
change the colors dynamically from userland. This is enabled by default
in the GENERIC kernel (as well as others) but disabled on all INSTALL*
kernels (as this feature is useless there).
- WS_DEFAULT_COLATTR, WS_DEFAULT_MONOATTR, WS_DEFAULT_BG and WS_DEFAULT_FG,
which specify the default colors for the console at boot time. These have
the same meaning as the (already existing) WS_KERNEL_* variables.
wsconsctl is modified to add msg.default.{attrs,bg,fg} and
msg.kernel.{attrs,bg,fg} to the display part, so that colors can be changed
after boot.
Tested on NetBSD/i386 with vga (and vga in mono mode), and on NetBSD/mac68k.
No objections in tech-kern@.
2004-07-28 16:34:02 +04:00
|
|
|
#ifdef WSDISPLAY_CUSTOM_OUTPUT
|
|
|
|
void
|
|
|
|
pcdisplay_replaceattr(id, oldattr, newattr)
|
|
|
|
void *id;
|
|
|
|
long oldattr, newattr;
|
|
|
|
{
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
|
|
|
int off;
|
|
|
|
uint16_t chardata;
|
|
|
|
|
|
|
|
if (scr->active)
|
|
|
|
for (off = 0; off < scr->type->nrows * scr->type->ncols;
|
|
|
|
off++) {
|
|
|
|
chardata = bus_space_read_2(memt, memh,
|
|
|
|
scr->dispoffset + off * 2);
|
|
|
|
if ((long)(chardata >> 8) == oldattr)
|
|
|
|
bus_space_write_2(memt, memh,
|
|
|
|
scr->dispoffset + off * 2,
|
|
|
|
((u_int16_t)(newattr << 8)) |
|
|
|
|
(chardata & 0x00FF));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
for (off = 0; off < scr->type->nrows * scr->type->ncols;
|
|
|
|
off++) {
|
|
|
|
chardata = scr->mem[off];
|
|
|
|
if ((long)(chardata >> 8) == oldattr)
|
|
|
|
scr->mem[off] = ((u_int16_t)(newattr << 8)) |
|
|
|
|
(chardata & 0x00FF);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* WSDISPLAY_CUSTOM_OUTPUT */
|
|
|
|
|
2002-07-01 17:17:48 +04:00
|
|
|
#ifdef WSDISPLAY_CHARFUNCS
|
2002-06-27 03:05:33 +04:00
|
|
|
int
|
|
|
|
pcdisplay_getwschar(id, wschar)
|
|
|
|
void *id;
|
|
|
|
struct wsdisplay_char *wschar;
|
|
|
|
{
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
|
|
|
int off;
|
|
|
|
uint16_t chardata;
|
|
|
|
uint8_t attrbyte;
|
|
|
|
|
|
|
|
off = wschar->row * scr->type->ncols + wschar->col;
|
|
|
|
if (off >= scr->type->ncols * scr->type->nrows)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (scr->active)
|
|
|
|
chardata = bus_space_read_2(memt, memh,
|
|
|
|
scr->dispoffset + off * 2);
|
|
|
|
else
|
|
|
|
chardata = scr->mem[off];
|
|
|
|
|
|
|
|
wschar->letter = (chardata & 0x00FF);
|
|
|
|
wschar->flags = 0;
|
|
|
|
attrbyte = (chardata & 0xFF00) >> 8;
|
|
|
|
if ((attrbyte & 0x08)) wschar->flags |= WSDISPLAY_CHAR_BRIGHT;
|
|
|
|
if ((attrbyte & 0x80)) wschar->flags |= WSDISPLAY_CHAR_BLINK;
|
|
|
|
wschar->foreground = attrbyte & 0x07;
|
|
|
|
wschar->background = (attrbyte >> 4) & 0x07;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
pcdisplay_putwschar(id, wschar)
|
|
|
|
void *id;
|
|
|
|
struct wsdisplay_char *wschar;
|
|
|
|
{
|
|
|
|
struct pcdisplayscreen *scr = id;
|
|
|
|
bus_space_tag_t memt = scr->hdl->ph_memt;
|
|
|
|
bus_space_handle_t memh = scr->hdl->ph_memh;
|
|
|
|
int off;
|
|
|
|
uint16_t chardata;
|
|
|
|
uint8_t attrbyte;
|
|
|
|
|
|
|
|
off = wschar->row * scr->type->ncols + wschar->col;
|
|
|
|
if (off >= (scr->type->ncols * scr->type->nrows))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
attrbyte = wschar->background & 0x07;
|
|
|
|
if (wschar->flags & WSDISPLAY_CHAR_BLINK) attrbyte |= 0x08;
|
|
|
|
attrbyte <<= 4;
|
|
|
|
attrbyte |= wschar->foreground & 0x07;
|
|
|
|
if (wschar->flags & WSDISPLAY_CHAR_BRIGHT) attrbyte |= 0x08;
|
|
|
|
chardata = (attrbyte << 8) | wschar->letter;
|
|
|
|
|
|
|
|
if (scr->active)
|
|
|
|
bus_space_write_2(memt, memh, scr->dispoffset + off * 2,
|
|
|
|
chardata);
|
|
|
|
else
|
|
|
|
scr->mem[off] = chardata;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2002-07-01 17:17:48 +04:00
|
|
|
#endif /* WSDISPLAY_CHARFUNCS */
|