summaryrefslogtreecommitdiffstats
path: root/sys/dev/syscons/syscons.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/syscons/syscons.c')
-rw-r--r--sys/dev/syscons/syscons.c199
1 files changed, 131 insertions, 68 deletions
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index b208bbf..5a40045 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.129 1995/11/20 12:13:32 phk Exp $
+ * $Id: syscons.c,v 1.130 1995/11/24 14:56:00 bde Exp $
*/
#include "sc.h"
@@ -158,6 +158,35 @@ static struct cdevsw scdevsw = {
ttselect, scmmap, nostrategy,
};
+/*
+ * Calculate hardware attributes word using logical attributes mask and
+ * hardware colors
+ */
+
+static int
+mask2attr(struct term_stat *term)
+{
+ int attr, mask = term->attr_mask;
+
+ if (mask & REVERSE_ATTR) {
+ attr = ((mask & BACKGROUND_CHANGED) ?
+ ((term->cur_color & 0xF000) >> 4) :
+ (term->rev_color & 0x0F00)) |
+ ((mask & FOREGROUND_CHANGED) ?
+ ((term->cur_color & 0x0F00) << 4) :
+ (term->rev_color & 0xF000));
+ } else
+ attr = term->cur_color;
+
+ /* XXX: underline mapping for Hercules adapter can be better */
+ if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
+ attr ^= 0x0800;
+ if (mask & BLINK_ATTR)
+ attr ^= 0x8000;
+
+ return attr;
+}
+
int
scprobe(struct isa_device *dev)
{
@@ -657,10 +686,10 @@ set_mouse_pos:
ptr->mv_row = scp->ypos;
ptr->mv_csz = scp->xsize;
ptr->mv_rsz = scp->ysize;
- ptr->mv_norm.fore = (scp->term.std_attr & 0x0f00)>>8;
- ptr->mv_norm.back = (scp->term.std_attr & 0xf000)>>12;
- ptr->mv_rev.fore = (scp->term.rev_attr & 0x0f00)>>8;
- ptr->mv_rev.back = (scp->term.rev_attr & 0xf000)>>12;
+ ptr->mv_norm.fore = (scp->term.std_color & 0x0f00)>>8;
+ ptr->mv_norm.back = (scp->term.std_color & 0xf000)>>12;
+ ptr->mv_rev.fore = (scp->term.rev_color & 0x0f00)>>8;
+ ptr->mv_rev.back = (scp->term.rev_color & 0xf000)>>12;
ptr->mv_grfc.fore = 0; /* not supported */
ptr->mv_grfc.back = 0; /* not supported */
ptr->mv_ovscan = scp->border;
@@ -1237,7 +1266,7 @@ static void
clear_screen(scr_stat *scp)
{
move_crsr(scp, 0, 0);
- fillw(scp->term.cur_attr | scr_map[0x20], scp->scr_buf,
+ fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf,
scp->xsize * scp->ysize);
mark_all(scp);
}
@@ -1368,7 +1397,7 @@ scan_esc(scr_stat *scp, u_char c)
else {
bcopyw(scp->scr_buf, scp->scr_buf + scp->xsize,
(scp->ysize - 1) * scp->xsize * sizeof(u_short));
- fillw(scp->term.cur_attr | scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->scr_buf, scp->xsize);
mark_all(scp);
}
@@ -1457,14 +1486,14 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0];
switch (n) {
case 0: /* clear form cursor to end of display */
- fillw(scp->term.cur_attr | scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->cursor_pos,
scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->xsize * scp->ysize);
break;
case 1: /* clear from beginning of display to cursor */
- fillw(scp->term.cur_attr | scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->scr_buf,
scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, 0);
@@ -1483,7 +1512,7 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0];
switch (n) {
case 0: /* clear form cursor to end of line */
- fillw(scp->term.cur_attr | scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->cursor_pos,
scp->xsize - scp->xpos);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
@@ -1491,14 +1520,14 @@ scan_esc(scr_stat *scp, u_char c)
scp->xsize - scp->xpos);
break;
case 1: /* clear from beginning of line to cursor */
- fillw(scp->term.cur_attr|scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->cursor_pos - (scp->xsize - scp->xpos),
(scp->xsize - scp->xpos) + 1);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
break;
case 2: /* clear entire line */
- fillw(scp->term.cur_attr|scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->cursor_pos - (scp->xsize - scp->xpos),
scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
@@ -1515,7 +1544,7 @@ scan_esc(scr_stat *scp, u_char c)
dst = src + n * scp->xsize;
count = scp->ysize - (scp->ypos + n);
bcopyw(src, dst, count * scp->xsize * sizeof(u_short));
- fillw(scp->term.cur_attr | scr_map[0x20], src,
+ fillw(scp->term.cur_color | scr_map[0x20], src,
n * scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, scp->xsize * scp->ysize);
@@ -1530,7 +1559,7 @@ scan_esc(scr_stat *scp, u_char c)
count = scp->ysize - (scp->ypos + n);
bcopyw(src, dst, count * scp->xsize * sizeof(u_short));
src = dst + count * scp->xsize;
- fillw(scp->term.cur_attr | scr_map[0x20], src,
+ fillw(scp->term.cur_color | scr_map[0x20], src,
n * scp->xsize);
mark_for_update(scp, scp->ypos * scp->xsize);
mark_for_update(scp, scp->xsize * scp->ysize);
@@ -1545,7 +1574,7 @@ scan_esc(scr_stat *scp, u_char c)
count = scp->xsize - (scp->xpos + n);
bcopyw(src, dst, count * sizeof(u_short));
src = dst + count;
- fillw(scp->term.cur_attr | scr_map[0x20], src, n);
+ fillw(scp->term.cur_color | scr_map[0x20], src, n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
break;
@@ -1558,7 +1587,7 @@ scan_esc(scr_stat *scp, u_char c)
dst = src + n;
count = scp->xsize - (scp->xpos + n);
bcopyw(src, dst, count * sizeof(u_short));
- fillw(scp->term.cur_attr | scr_map[0x20], src, n);
+ fillw(scp->term.cur_color | scr_map[0x20], src, n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
break;
@@ -1570,7 +1599,7 @@ scan_esc(scr_stat *scp, u_char c)
bcopyw(scp->scr_buf + (scp->xsize * n),
scp->scr_buf,
scp->xsize * (scp->ysize - n) * sizeof(u_short));
- fillw(scp->term.cur_attr | scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->scr_buf + scp->xsize * (scp->ysize - n),
scp->xsize * n);
mark_all(scp);
@@ -1584,7 +1613,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->scr_buf + (scp->xsize * n),
scp->xsize * (scp->ysize - n) *
sizeof(u_short));
- fillw(scp->term.cur_attr | scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->scr_buf, scp->xsize * n);
mark_all(scp);
break;
@@ -1593,7 +1622,7 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0]; if (n < 1) n = 1;
if (n > scp->xsize - scp->xpos)
n = scp->xsize - scp->xpos;
- fillw(scp->term.cur_attr | scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->scr_buf + scp->xpos +
((scp->xsize*scp->ypos) * sizeof(u_short)), n);
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
@@ -1633,40 +1662,49 @@ scan_esc(scr_stat *scp, u_char c)
case 'm': /* change attribute */
if (scp->term.num_param == 0) {
- scp->term.cur_attr = scp->term.std_attr;
+ scp->term.attr_mask = NORMAL_ATTR;
+ scp->term.cur_attr =
+ scp->term.cur_color = scp->term.std_color;
break;
}
for (i = 0; i < scp->term.num_param; i++) {
switch (n = scp->term.param[i]) {
case 0: /* back to normal */
- scp->term.cur_attr = scp->term.std_attr;
+ scp->term.attr_mask = NORMAL_ATTR;
+ scp->term.cur_attr =
+ scp->term.cur_color = scp->term.std_color;
break;
- case 1: /* highlight (bold) */
- scp->term.cur_attr &= 0xFF00;
- scp->term.cur_attr |= 0x0800;
+ case 1: /* bold */
+ scp->term.attr_mask |= BOLD_ATTR;
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
- case 4: /* highlight (underline) */
- scp->term.cur_attr &= 0xFF00;
- scp->term.cur_attr |= 0x0800;
+ case 4: /* underline */
+ scp->term.attr_mask |= UNDERLINE_ATTR;
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 5: /* blink */
- scp->term.cur_attr &= 0xFF00;
- scp->term.cur_attr |= 0x8000;
+ scp->term.attr_mask |= BLINK_ATTR;
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 7: /* reverse video */
- scp->term.cur_attr = scp->term.rev_attr;
+ scp->term.attr_mask |= REVERSE_ATTR;
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 30: case 31: /* set fg color */
case 32: case 33: case 34:
case 35: case 36: case 37:
- scp->term.cur_attr =
- (scp->term.cur_attr&0xF8FF) | (ansi_col[(n-30)&7]<<8);
+ scp->term.attr_mask |= FOREGROUND_CHANGED;
+ scp->term.cur_color =
+ (scp->term.cur_color&0xF000) | (ansi_col[(n-30)&7]<<8);
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 40: case 41: /* set bg color */
case 42: case 43: case 44:
case 45: case 46: case 47:
- scp->term.cur_attr =
- (scp->term.cur_attr&0x8FFF) | (ansi_col[(n-40)&7]<<12);
+ scp->term.attr_mask |= BACKGROUND_CHANGED;
+ scp->term.cur_color =
+ (scp->term.cur_color&0x0F00) | (ansi_col[(n-40)&7]<<12);
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
}
}
@@ -1679,37 +1717,48 @@ scan_esc(scr_stat *scp, u_char c)
n = scp->term.param[0];
switch (n) {
case 0: /* reset attributes */
- scp->term.cur_attr = scp->term.std_attr =
- current_default->std_attr;
- scp->term.rev_attr = current_default->rev_attr;
+ scp->term.attr_mask = NORMAL_ATTR;
+ scp->term.cur_attr =
+ scp->term.cur_color = scp->term.std_color =
+ current_default->std_color;
+ scp->term.rev_color = current_default->rev_color;
break;
case 1: /* set ansi background */
- scp->term.cur_attr = scp->term.std_attr =
- (scp->term.std_attr & 0x0F00) |
+ scp->term.attr_mask &= ~BACKGROUND_CHANGED;
+ scp->term.cur_color = scp->term.std_color =
+ (scp->term.std_color & 0x0F00) |
(ansi_col[(scp->term.param[1])&0x0F]<<12);
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 2: /* set ansi foreground */
- scp->term.cur_attr = scp->term.std_attr =
- (scp->term.std_attr & 0xF000) |
+ scp->term.attr_mask &= ~FOREGROUND_CHANGED;
+ scp->term.cur_color = scp->term.std_color =
+ (scp->term.std_color & 0xF000) |
(ansi_col[(scp->term.param[1])&0x0F]<<8);
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 3: /* set ansi attribute directly */
- scp->term.cur_attr = scp->term.std_attr =
+ scp->term.attr_mask &= ~(FOREGROUND_CHANGED|BACKGROUND_CHANGED);
+ scp->term.cur_color = scp->term.std_color =
(scp->term.param[1]&0xFF)<<8;
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 5: /* set ansi reverse video background */
- scp->term.rev_attr =
- (scp->term.rev_attr & 0x0F00) |
+ scp->term.rev_color =
+ (scp->term.rev_color & 0x0F00) |
(ansi_col[(scp->term.param[1])&0x0F]<<12);
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 6: /* set ansi reverse video foreground */
- scp->term.rev_attr =
- (scp->term.rev_attr & 0xF000) |
+ scp->term.rev_color =
+ (scp->term.rev_color & 0xF000) |
(ansi_col[(scp->term.param[1])&0x0F]<<8);
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
case 7: /* set ansi reverse video directly */
- scp->term.rev_attr =
+ scp->term.rev_color =
(scp->term.param[1]&0xFF)<<8;
+ scp->term.cur_attr = mask2attr(&scp->term);
break;
}
break;
@@ -1776,31 +1825,41 @@ scan_esc(scr_stat *scp, u_char c)
break;
case 'F': /* set ansi foreground */
- if (scp->term.num_param == 1)
- scp->term.cur_attr = scp->term.std_attr =
- (scp->term.std_attr & 0xF000)
+ if (scp->term.num_param == 1) {
+ scp->term.attr_mask &= ~FOREGROUND_CHANGED;
+ scp->term.cur_color = scp->term.std_color =
+ (scp->term.std_color & 0xF000)
| ((scp->term.param[0] & 0x0F) << 8);
+ scp->term.cur_attr = mask2attr(&scp->term);
+ }
break;
case 'G': /* set ansi background */
- if (scp->term.num_param == 1)
- scp->term.cur_attr = scp->term.std_attr =
- (scp->term.std_attr & 0x0F00)
+ if (scp->term.num_param == 1) {
+ scp->term.attr_mask &= ~BACKGROUND_CHANGED;
+ scp->term.cur_color = scp->term.std_color =
+ (scp->term.std_color & 0x0F00)
| ((scp->term.param[0] & 0x0F) << 12);
+ scp->term.cur_attr = mask2attr(&scp->term);
+ }
break;
case 'H': /* set ansi reverse video foreground */
- if (scp->term.num_param == 1)
- scp->term.rev_attr =
- (scp->term.rev_attr & 0xF000)
+ if (scp->term.num_param == 1) {
+ scp->term.rev_color =
+ (scp->term.rev_color & 0xF000)
| ((scp->term.param[0] & 0x0F) << 8);
+ scp->term.cur_attr = mask2attr(&scp->term);
+ }
break;
case 'I': /* set ansi reverse video background */
- if (scp->term.num_param == 1)
- scp->term.rev_attr =
- (scp->term.rev_attr & 0x0F00)
+ if (scp->term.num_param == 1) {
+ scp->term.rev_color =
+ (scp->term.rev_color & 0x0F00)
| ((scp->term.param[0] & 0x0F) << 12);
+ scp->term.cur_attr = mask2attr(&scp->term);
+ }
break;
}
}
@@ -1956,7 +2015,7 @@ outloop:
}
bcopyw(scp->scr_buf + scp->xsize, scp->scr_buf,
scp->xsize * (scp->ysize - 1) * sizeof(u_short));
- fillw(scp->term.cur_attr | scr_map[0x20],
+ fillw(scp->term.cur_color | scr_map[0x20],
scp->scr_buf + scp->xsize * (scp->ysize - 1),
scp->xsize);
scp->cursor_pos -= scp->xsize;
@@ -2052,9 +2111,11 @@ scinit(void)
for (i=1; i<MAXCONS; i++)
console[i] = NULL;
kernel_console.esc = 0;
- kernel_console.std_attr = kernel_default.std_attr;
- kernel_console.rev_attr = kernel_default.rev_attr;
- kernel_console.cur_attr = kernel_default.std_attr;
+ kernel_console.attr_mask = NORMAL_ATTR;
+ kernel_console.cur_attr =
+ kernel_console.cur_color = kernel_console.std_color =
+ kernel_default.std_color;
+ kernel_console.rev_color = kernel_default.rev_color;
/* initialize mapscrn array to a one to one map */
for (i=0; i<sizeof(scr_map); i++)
scr_map[i] = i;
@@ -2090,9 +2151,11 @@ init_scp(scr_stat *scp)
scp->start = COL * ROW;
scp->end = 0;
scp->term.esc = 0;
- scp->term.std_attr = current_default->std_attr;
- scp->term.rev_attr = current_default->rev_attr;
- scp->term.cur_attr = scp->term.std_attr;
+ scp->term.attr_mask = NORMAL_ATTR;
+ scp->term.cur_attr =
+ scp->term.cur_color = scp->term.std_color =
+ current_default->std_color;
+ scp->term.rev_color = current_default->rev_color;
scp->border = BG_BLACK;
scp->cursor_start = *(char *)pa_to_va(0x461);
scp->cursor_end = *(char *)pa_to_va(0x460);
@@ -3092,10 +3155,10 @@ blink_screen(scr_stat *scp)
{
if (blink_in_progress > 1) {
if (blink_in_progress & 1)
- fillw(kernel_default.std_attr | scr_map[0x20],
+ fillw(kernel_default.std_color | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
else
- fillw(kernel_default.rev_attr | scr_map[0x20],
+ fillw(kernel_default.rev_color | scr_map[0x20],
Crtat, scp->xsize * scp->ysize);
blink_in_progress--;
timeout((timeout_func_t)blink_screen, scp, hz/10);
OpenPOWER on IntegriCloud