/* $NetBSD: video.c,v 1.7 2005/12/11 12:17:04 christos Exp $ */ /*- * Copyright (C) 1995-1997 Gary Thomas (gdt@linuxppc.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Gary Thomas. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef CONS_BE #include #include "boot.h" #include "iso_font.h" #define FONT_WIDTH 8 #define FONT_HEIGHT 16 #define VRAM_WIDTH 640 #define VRAM_HEIGHT 480 #define VRAM_SIZE (VRAM_WIDTH * VRAM_HEIGHT) #define ROW (VRAM_WIDTH / FONT_WIDTH) #define COL (VRAM_HEIGHT / FONT_HEIGHT) u_char *VramBase; u_char save_cursor[FONT_WIDTH]; /* * The current state of virtual displays */ struct screen { enum state { NORMAL, /* no pending escape */ ESC, /* saw ESC */ EBRAC, /* saw ESC[ */ EBRACEQ /* saw ESC[= */ } state; /* command parser state */ int cx; /* the first escape seq argument */ int cy; /* the second escap seq argument */ int *accp; /* pointer to the current processed argument */ int row; int col; u_char fgcolor; u_char bgcolor; } screen; void video_init(u_char *buffer) { struct screen *d = &screen; VramBase = buffer; d->fgcolor = 0x1f; /* WHITE */ d->bgcolor = 0x00; /* BLACK */ d->row = 0; d->col = 0; d->state = NORMAL; memset(VramBase, d->bgcolor, VRAM_SIZE); memset(save_cursor, d->bgcolor, FONT_WIDTH); } static void wrtchar(u_char c, struct screen *d) { u_char *p = VramBase + (d->col * VRAM_WIDTH * FONT_HEIGHT) + (d->row * FONT_WIDTH); int fontbase = c * 16; int x, y; for (y = 0; y < FONT_HEIGHT; y++) { for (x = 0; x < FONT_WIDTH; x++) { if ((font[fontbase + y] >> (FONT_WIDTH - x)) & 1) *(p + x + (y * VRAM_WIDTH)) = d->fgcolor; else *(p + x + (y * VRAM_WIDTH)) = d->bgcolor; } } d->row++; } static void cursor(struct screen *d, int flag) { int x; int y = FONT_HEIGHT - 1; u_char *p = VramBase + (d->col * VRAM_WIDTH * FONT_HEIGHT) + (d->row * FONT_WIDTH); for (x = 0; x < FONT_WIDTH - 1; x++) { if (flag) { save_cursor[x] = *(p + x + (y * VRAM_WIDTH)); *(p + x + (y * VRAM_WIDTH)) = d->fgcolor; } else { *(p + x + (y * VRAM_WIDTH)) = save_cursor[x]; } } } /* * vga_putc (nee sput) has support for emulation of the 'ibmpc' termcap entry. * This is a bare-bones implementation of a bare-bones entry * One modification: Change li#24 to li#25 to reflect 25 lines * "ca" is the color/attributes value (left-shifted by 8) * or 0 if the current regular color for that screen is to be used. */ void video_putc(int c) { struct screen *d = &screen; cursor(d, 0); switch (d->state) { case NORMAL: switch (c) { case 0x0: /* Ignore pad characters */ return; case 0x1B: d->state = ESC; break; case '\t': do { wrtchar(' ', d); } while (d->row % 8); break; case '\b': /* non-destructive backspace */ d->row--; if (d->row < 0) { if (d->col > 0) { d->col--; d->row += ROW; /* prev column */ } else { d->row = 0; } } break; case '\n': d->col++; /* FALLTHROUGH */ case '\r': d->row = 0; break; case '\007': break; default: wrtchar(c, d); if (d->row >= ROW) { d->row = 0; d->col++; } break; } break; case ESC: case EBRAC: case EBRACEQ: break; } if (d->col >= COL) { /* scroll check */ memcpy(VramBase, VramBase + VRAM_WIDTH * FONT_HEIGHT, VRAM_SIZE - VRAM_WIDTH * FONT_WIDTH); memset(VramBase + VRAM_SIZE - VRAM_WIDTH * FONT_HEIGHT, d->bgcolor, VRAM_WIDTH * FONT_HEIGHT); d->col = COL - 1; } cursor(d, 1); } #endif