#include <vc.h>
#include <mach_kdb.h>
#include <kern/spl.h>
#include <machine/machparam.h>
#include <types.h>
#include <ppc/iso_font.h>
#include <ppc/Firmware.h>
#include <ppc/POWERMAC/video_console_entries.h>
#include <ppc/POWERMAC/video_console.h>
#include <pexpert/pexpert.h>
#include <kern/time_out.h>
#include <kern/lock.h>
#include <kern/debug.h>
#define FAST_JUMP_SCROLL
#define CHARWIDTH 8
#define CHARHEIGHT 16
#define ATTR_NONE 0
#define ATTR_BOLD 1
#define ATTR_UNDER 2
#define ATTR_REVERSE 4
enum vt100state_e {
ESnormal,
ESesc,
ESsquare,
ESgetpars,
ESgotpars,
ESfunckey,
EShash,
ESsetG0,
ESsetG1,
ESask,
EScharsize,
ESignore
} vt100state = ESnormal;
struct vc_info vinfo;
static int vc_wrap_mode = 1, vc_relative_origin = 0;
static int vc_charset_select = 0, vc_save_charset_s = 0;
static int vc_charset[2] = { 0, 0 };
static int vc_charset_save[2] = { 0, 0 };
#define MAXPARS 16
static int x = 0, y = 0, savex, savey;
static int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
static char tab_stops[255];
static int scrreg_top, scrreg_bottom;
void vc_initialize(void);
void vc_flush_forward_buffer(void);
void vc_store_char(unsigned char);
void vcattach(void);
unsigned char vc_color_index_table[33] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
unsigned long vc_color_depth_masks[4] =
{ 0x000000FF, 0x00007FFF, 0x00FFFFFF };
unsigned long vc_colors[8][3] = {
{ 0xFFFFFFFF, 0x00000000, 0x00000000 },
{ 0x23232323, 0x7C007C00, 0x00FF0000 },
{ 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 },
{ 0x05050505, 0x7FE07FE0, 0x00FFFF00 },
{ 0xd2d2d2d2, 0x001f001f, 0x000000FF},
{ 0x18181818, 0x7C1F7C1F, 0x00FF00FF },
{ 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF },
{ 0x00000000, 0x7FFF7FFF, 0x00FFFFFF }
};
unsigned long vc_color_mask = 0;
unsigned long vc_color_fore = 0;
unsigned long vc_color_back = 0;
int vc_normal_background = 1;
#define VC_MAX_FORWARD_SIZE (100*36)
#define VC_CONSOLE_UPDATE_TIMEOUT 5
static unsigned char vc_forward_buffer[VC_MAX_FORWARD_SIZE];
static long vc_forward_buffer_size = 0;
static int vc_forward_buffer_enabled = 0;
static int vc_forward_buffer_busy = 0;
decl_simple_lock_data(,vc_forward_lock)
#ifdef FAST_JUMP_SCROLL
static void (*vc_forward_paintchar) (unsigned char c, int x, int y, int attrs);
static enum {
PFoff,
PFwind,
PFscroll,
PFunwind
} vc_forward_preflight_mode = PFoff;
static struct {
enum vt100state_e vt100state;
int vc_wrap_mode, vc_relative_origin;
int vc_charset_select, vc_save_charset_s;
int vc_charset[2];
int vc_charset_save[2];
int x, y, savex, savey;
int par[MAXPARS], numpars, hanging_cursor, attr, saveattr;
char tab_stops[255];
int scrreg_top, scrreg_bottom;
unsigned long vc_color_fore;
unsigned long vc_color_back;
} vc_forward_preflight_save;
static int vc_forward_scroll = 0;
#endif FAST_JUMP_SCROLL
static void (*vc_paintchar) (unsigned char c, int x, int y, int attrs);
#ifdef RENDERALLOCATE
unsigned char *renderedFont = NULL;
#else
#define REN_MAX_DEPTH 32
#define REN_MAX_SIZE (128L*1024)
unsigned char renderedFont[REN_MAX_SIZE];
#endif
unsigned long vc_rendered_font_size = REN_MAX_SIZE;
long vc_rendered_error = 0;
short vc_one_bit_reversed = 0;
int vc_rendered_char_size = 0;
#define VC_RESET_BACKGROUND 40
#define VC_RESET_FOREGROUND 37
static void vc_color_set(int color)
{
if (vinfo.v_depth < 8)
return;
if (color >= 30 && color <= 37)
vc_color_fore = vc_colors[color-30][vc_color_index_table[vinfo.v_depth]];
if (color >= 40 && color <= 47) {
vc_color_back = vc_colors[color-40][vc_color_index_table[vinfo.v_depth]];
vc_normal_background = color == 40;
}
}
static void vc_render_font(short olddepth, short newdepth)
{
int charIndex;
union {
unsigned char *charptr;
unsigned short *shortptr;
unsigned long *longptr;
} current;
unsigned char *theChar;
if (olddepth == newdepth && renderedFont) {
return;
}
if (olddepth != 1 && renderedFont) {
#ifdef RENDERALLOCATE
(void) kmem_free(kernel_map, (vm_offset_t*)renderedFont, vc_rendered_font_size);
#endif
}
vc_rendered_font_size = REN_MAX_SIZE;
if (newdepth == 1) {
#ifdef RENDERALLOCATE
renderedFont = iso_font;
#endif
vc_rendered_char_size = 16;
if (!vc_one_bit_reversed) {
int i;
for (i = 0; i < ((ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size); i++) {
if (iso_font[i]) {
unsigned char mask1 = 0x80;
unsigned char mask2 = 0x01;
unsigned char val = 0;
while (mask1) {
if (iso_font[i] & mask1)
val |= mask2;
mask1 >>= 1;
mask2 <<= 1;
}
renderedFont[i] = ~val;
} else renderedFont[i] = 0xff;
}
vc_one_bit_reversed = 1;
}
return;
}
{
long csize = newdepth / 8;
vc_rendered_char_size = csize ? CHARHEIGHT * (csize * CHARWIDTH) :
CHARHEIGHT * (CHARWIDTH/(6-newdepth));
csize = (ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size;
#ifndef RENDERALLOCATE
if (csize > vc_rendered_font_size) {
vc_rendered_error = csize;
return;
} else
vc_rendered_font_size = csize;
#else
vc_rendered_font_size = csize;
#endif
}
#ifdef RENDERALLOCATE
if (kmem_alloc(kernel_map,
(vm_offset_t *)&renderedFont,
vc_rendered_font_size) != KERN_SUCCESS) {
renderedFont = NULL;
vc_rendered_error = vc_rendered_font_size;
return;
}
#endif
current.charptr = renderedFont;
theChar = iso_font;
for (charIndex = ISO_CHAR_MIN; charIndex <= ISO_CHAR_MAX; charIndex++) {
int line;
for (line = 0; line < CHARHEIGHT; line++) {
unsigned char mask = 1;
do {
switch (newdepth) {
case 2: {
unsigned char value = 0;
if (*theChar & mask) value |= 0xC0; mask <<= 1;
if (*theChar & mask) value |= 0x30; mask <<= 1;
if (*theChar & mask) value |= 0x0C; mask <<= 1;
if (*theChar & mask) value |= 0x03;
value = ~value;
*current.charptr++ = value;
}
break;
case 4:
{
unsigned char value = 0;
if (*theChar & mask) value |= 0xF0; mask <<= 1;
if (*theChar & mask) value |= 0x0F;
value = ~value;
*current.charptr++ = value;
}
break;
case 8:
*current.charptr++ = (*theChar & mask) ? 0xff : 0;
break;
case 16:
*current.shortptr++ = (*theChar & mask) ? 0xFFFF : 0;
break;
case 32:
*current.longptr++ = (*theChar & mask) ? 0xFFFFFFFF : 0;
break;
}
mask <<= 1;
} while (mask);
theChar++;
}
}
}
#ifdef FAST_JUMP_SCROLL
static void vc_paint_char(unsigned char ch, int xx, int yy, int attrs)
{
switch (vc_forward_preflight_mode) {
case PFoff:
vc_forward_paintchar(ch, xx, yy, attrs);
break;
case PFwind:
break;
case PFscroll:
break;
case PFunwind:
if (yy >= scrreg_top && yy < scrreg_bottom) {
yy -= vc_forward_scroll;
if (yy < scrreg_top || yy >= scrreg_bottom)
break;
}
vc_forward_paintchar(ch, xx, yy, attrs);
break;
}
}
#endif FAST_JUMP_SCROLL
static void vc_paint_char1(unsigned char ch, int xx, int yy, int attrs)
{
unsigned char *theChar;
unsigned char *where;
int i;
theChar = (unsigned char*)(renderedFont + (ch * vc_rendered_char_size));
where = (unsigned char*)(vinfo.v_baseaddr +
(yy * CHARHEIGHT * vinfo.v_rowbytes) +
(xx));
if (!attrs) for (i = 0; i < CHARHEIGHT; i++) {
*where = *theChar++;
where = (unsigned char*)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < CHARHEIGHT; i++) {
unsigned char val = *theChar++, save = val;
if (attrs & ATTR_BOLD) {
unsigned char mask1 = 0xC0, mask2 = 0x40;
int bit = 0;
for (bit = 0; bit < 7; bit++) {
if ((save & mask1) == mask2)
val &= ~mask2;
mask1 >>= 1;
mask2 >>= 1;
}
}
if (attrs & ATTR_REVERSE) val = ~val;
if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
*where = val;
where = (unsigned char*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void vc_paint_char2(unsigned char ch, int xx, int yy, int attrs)
{
unsigned short *theChar;
unsigned short *where;
int i;
theChar = (unsigned short*)(renderedFont + (ch * vc_rendered_char_size));
where = (unsigned short*)(vinfo.v_baseaddr +
(yy * CHARHEIGHT * vinfo.v_rowbytes) +
(xx * 2));
if (!attrs) for (i = 0; i < CHARHEIGHT; i++) {
*where = *theChar++;
where = (unsigned short*)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < CHARHEIGHT; i++) {
unsigned short val = *theChar++, save = val;
if (attrs & ATTR_BOLD) {
unsigned short mask1 = 0xF000, mask2 = 0x3000;
int bit = 0;
for (bit = 0; bit < 7; bit++) {
if ((save & mask1) == mask2)
val &= ~mask2;
mask1 >>= 2;
mask2 >>= 2;
}
}
if (attrs & ATTR_REVERSE) val = ~val;
if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
*where = val;
where = (unsigned short*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void vc_paint_char4(unsigned char ch, int xx, int yy, int attrs)
{
unsigned long *theChar;
unsigned long *where;
int i;
theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
where = (unsigned long*)(vinfo.v_baseaddr +
(yy * CHARHEIGHT * vinfo.v_rowbytes) +
(xx * 4));
if (!attrs) for (i = 0; i < CHARHEIGHT; i++) {
*where = *theChar++;
where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < CHARHEIGHT; i++) {
unsigned long val = *theChar++, save = val;
if (attrs & ATTR_BOLD) {
unsigned long mask1 = 0xff000000, mask2 = 0x0F000000;
int bit = 0;
for (bit = 0; bit < 7; bit++) {
if ((save & mask1) == mask2)
val &= ~mask2;
mask1 >>= 4;
mask2 >>= 4;
}
}
if (attrs & ATTR_REVERSE) val = ~val;
if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
*where = val;
where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void vc_paint_char8c(unsigned char ch, int xx, int yy, int attrs)
{
unsigned long *theChar;
unsigned long *where;
int i;
theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
where = (unsigned long*)(vinfo.v_baseaddr +
(yy * CHARHEIGHT * vinfo.v_rowbytes) +
(xx * CHARWIDTH));
if (!attrs) for (i = 0; i < CHARHEIGHT; i++) {
unsigned long *store = where;
int x;
for (x = 0; x < 2; x++) {
unsigned long val = *theChar++;
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
}
where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < CHARHEIGHT; i++) {
unsigned long *store = where, lastpixel = 0;
int x;
for (x = 0 ; x < 2; x++) {
unsigned long val = *theChar++, save = val;
if (attrs & ATTR_BOLD) {
if (lastpixel && !(save & 0xFF000000))
val |= 0xff000000;
if ((save & 0xFFFF0000) == 0xFF000000)
val |= 0x00FF0000;
if ((save & 0x00FFFF00) == 0x00FF0000)
val |= 0x0000FF00;
if ((save & 0x0000FFFF) == 0x0000FF00)
val |= 0x000000FF;
}
if (attrs & ATTR_REVERSE) val = ~val;
if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
lastpixel = save & 0xff;
}
where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void vc_paint_char16c(unsigned char ch, int xx, int yy, int attrs)
{
unsigned long *theChar;
unsigned long *where;
int i;
theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
where = (unsigned long*)(vinfo.v_baseaddr +
(yy * CHARHEIGHT * vinfo.v_rowbytes) +
(xx * CHARWIDTH * 2));
if (!attrs) for (i = 0; i < CHARHEIGHT; i++) {
unsigned long *store = where;
int x;
for (x = 0; x < 4; x++) {
unsigned long val = *theChar++;
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
}
where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < CHARHEIGHT; i++) {
unsigned long *store = where, lastpixel = 0;
int x;
for (x = 0 ; x < 4; x++) {
unsigned long val = *theChar++, save = val;
if (attrs & ATTR_BOLD) {
if (save == 0xFFFF0000) val |= 0xFFFF;
else if (lastpixel && !(save & 0xFFFF0000))
val |= 0xFFFF0000;
}
if (attrs & ATTR_REVERSE) val = ~val;
if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
lastpixel = save & 0x7fff;
}
where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void vc_paint_char32c(unsigned char ch, int xx, int yy, int attrs)
{
unsigned long *theChar;
unsigned long *where;
int i;
theChar = (unsigned long*)(renderedFont + (ch * vc_rendered_char_size));
where = (unsigned long*)(vinfo.v_baseaddr +
(yy * CHARHEIGHT * vinfo.v_rowbytes) +
(xx * CHARWIDTH * 4));
if (!attrs) for (i = 0; i < CHARHEIGHT; i++) {
unsigned long *store = where;
int x;
for (x = 0; x < 8; x++) {
unsigned long val = *theChar++;
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
}
where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < CHARHEIGHT; i++) {
unsigned long *store = where, lastpixel = 0;
int x;
for (x = 0 ; x < 8; x++) {
unsigned long val = *theChar++, save = val;
if (attrs & ATTR_BOLD) {
if (lastpixel && !save)
val = 0xFFFFFFFF;
}
if (attrs & ATTR_REVERSE) val = ~val;
if (attrs & ATTR_UNDER && i == CHARHEIGHT-1) val = ~val;
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
lastpixel = save;
}
where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void reversecursor(void)
{
union {
unsigned char *charptr;
unsigned short *shortptr;
unsigned long *longptr;
} where;
int line, col;
where.longptr = (unsigned long*)(vinfo.v_baseaddr +
(y * CHARHEIGHT * vinfo.v_rowbytes) +
(x * vinfo.v_depth));
for (line = 0; line < CHARHEIGHT; line++) {
switch (vinfo.v_depth) {
case 1:
*where.charptr = ~*where.charptr;
break;
case 2:
*where.shortptr = ~*where.shortptr;
break;
case 4:
*where.longptr = ~*where.longptr;
break;
#ifdef VC_BINARY_REVERSE
case 8:
where.longptr[0] = ~where.longptr[0];
where.longptr[1] = ~where.longptr[1];
break;
case 16:
for (col = 0; col < 4; col++)
where.longptr[col] = ~where.longptr[col];
break;
case 32:
for (col = 0; col < 8; col++)
where.longptr[col] = ~where.longptr[col];
break;
#else
case 8:
for (col = 0; col < 8; col++)
where.charptr[col] = where.charptr[col] != (vc_color_fore & vc_color_mask) ?
vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
break;
case 16:
for (col = 0; col < 8; col++)
where.shortptr[col] = where.shortptr[col] != (vc_color_fore & vc_color_mask) ?
vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
break;
case 32:
for (col = 0; col < 8; col++)
where.longptr[col] = where.longptr[col] != (vc_color_fore & vc_color_mask) ?
vc_color_fore & vc_color_mask : vc_color_back & vc_color_mask;
break;
#endif
}
where.charptr += vinfo.v_rowbytes;
}
}
static void
scrollup(int num)
{
unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
linelongs = (vinfo.v_rowbytes * CHARHEIGHT) >> 2;
rowline = (vinfo.v_rowbytes) >> 2;
rowscanline = (vinfo.v_rowscanbytes) >> 2;
#ifdef FAST_JUMP_SCROLL
if (vc_forward_preflight_mode == PFwind) {
vc_forward_scroll += num;
return;
}
if (vc_forward_preflight_mode == PFscroll || vc_forward_preflight_mode == PFoff) {
#endif FAST_JUMP_SCROLL
to = (unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs);
from = to + (linelongs * num);
i = (scrreg_bottom - scrreg_top) - num;
while (i-- > 0) {
for (line = 0; line < CHARHEIGHT; line++) {
video_scroll_up((unsigned int) from,
(unsigned int) (from+(vinfo.v_rowscanbytes/4)),
(unsigned int) to);
from += rowline;
to += rowline;
}
}
to = ((unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs))
+ ((scrreg_bottom - scrreg_top - num) * linelongs);
#ifdef FAST_JUMP_SCROLL
if (vc_forward_preflight_mode == PFscroll)
return;
} else if (vc_forward_preflight_mode == PFunwind) {
long linestart, linelast;
vc_forward_scroll -= num;
linestart = scrreg_bottom - num - vc_forward_scroll;
linelast = linestart + num - 1;
if (linestart >= scrreg_bottom || linelast < scrreg_top)
return;
if (linelast >= scrreg_bottom)
linelast = scrreg_bottom - 1;
if (linestart < scrreg_top)
linestart = scrreg_top;
to = ((unsigned long *) vinfo.v_baseaddr) + (linelongs * linestart);
num = linelast - linestart + 1;
}
#endif FAST_JUMP_SCROLL
for (linelongs = CHARHEIGHT * num; linelongs-- > 0;) {
from = to;
for (i = 0; i < rowscanline; i++)
*to++ = vc_color_back;
to = from + rowline;
}
}
static void
scrolldown(int num)
{
unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
linelongs = (vinfo.v_rowbytes * CHARHEIGHT) >> 2;
rowline = (vinfo.v_rowbytes) >> 2;
rowscanline = (vinfo.v_rowscanbytes) >> 2;
#ifdef FAST_JUMP_SCROLL
if (vc_forward_preflight_mode == PFwind) {
vc_forward_scroll -= num;
return;
}
if (vc_forward_preflight_mode == PFscroll || vc_forward_preflight_mode == PFoff) {
#endif FAST_JUMP_SCROLL
to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_bottom)
- (rowline - rowscanline);
from = to - (linelongs * num);
i = (scrreg_bottom - scrreg_top) - num;
while (i-- > 0) {
for (line = 0; line < CHARHEIGHT; line++) {
video_scroll_down((unsigned int) from,
(unsigned int) (from-(vinfo.v_rowscanbytes/4)),
(unsigned int) to);
from -= rowline;
to -= rowline;
}
}
to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_top);
#ifdef FAST_JUMP_SCROLL
if (vc_forward_preflight_mode == PFscroll)
return;
} else if (vc_forward_preflight_mode == PFunwind) {
long linestart, linelast;
vc_forward_scroll += num;
linestart = scrreg_top - vc_forward_scroll;
linelast = linestart + num - 1;
if (linestart >= scrreg_bottom || linelast < scrreg_top)
return;
if (linelast >= scrreg_bottom)
linelast = scrreg_bottom - 1;
if (linestart < scrreg_top)
linestart = scrreg_top;
to = ((unsigned long *) vinfo.v_baseaddr) + (linelongs * linestart);
num = linelast - linestart + 1;
}
#endif FAST_JUMP_SCROLL
for (line = CHARHEIGHT * num; line > 0; line--) {
from = to;
for (i = 0; i < rowscanline; i++)
*(to++) = vc_color_back;
to = from + rowline;
}
}
static void
clear_line(int which)
{
int start, end, i;
switch (which) {
case 0:
start = x;
end = vinfo.v_columns-1;
break;
case 1:
start = 0;
end = x;
break;
case 2:
start = 0;
end = vinfo.v_columns-1;
break;
}
for (i = start; i <= end; i++) {
vc_paintchar(' ', i, y, ATTR_NONE);
}
}
static void
clear_screen(int which)
{
unsigned long *p, *endp, *row;
int linelongs, col;
int rowline, rowlongs;
rowline = vinfo.v_rowscanbytes / 4;
rowlongs = vinfo.v_rowbytes / 4;
p = (unsigned long*) vinfo.v_baseaddr;;
endp = (unsigned long*) vinfo.v_baseaddr;
linelongs = vinfo.v_rowbytes * CHARHEIGHT / 4;
switch (which) {
case 0:
clear_line(0);
if (y < vinfo.v_rows - 1) {
p += (y + 1) * linelongs;
endp += rowlongs * vinfo.v_height;
}
break;
case 1:
clear_line(1);
if (y > 1) {
endp += (y + 1) * linelongs;
}
break;
case 2:
endp += rowlongs * vinfo.v_height;
break;
}
for (row = p ; row < endp ; row += rowlongs) {
for (col = 0; col < rowline; col++)
*(row+col) = vc_color_back;
}
}
static void
reset_tabs(void)
{
int i;
for (i = 0; i<= vinfo.v_columns; i++) {
tab_stops[i] = ((i % 8) == 0);
}
}
static void
vt100_reset(void)
{
reset_tabs();
scrreg_top = 0;
scrreg_bottom = vinfo.v_rows;
attr = ATTR_NONE;
vc_charset[0] = vc_charset[1] = 0;
vc_charset_select = 0;
vc_wrap_mode = 1;
vc_relative_origin = 0;
vc_color_set(VC_RESET_BACKGROUND);
vc_color_set(VC_RESET_FOREGROUND);
}
static void
putc_normal(unsigned char ch)
{
switch (ch) {
case '\a':
{
extern int asc_ringbell(); int rang;
spl_t s;
rang = asc_ringbell();
if(!rang) {
unsigned long *ptr;
int i, j;
for (i = 0; i < 2 ; i++) {
for (ptr = (unsigned long*)vinfo.v_baseaddr;
ptr < (unsigned long*)(vinfo.v_baseaddr +
(vinfo.v_height * vinfo.v_rowbytes));
ptr += (vinfo.v_rowbytes /
sizeof (unsigned long*)))
for (j = 0;
j < vinfo.v_rowscanbytes /
sizeof (unsigned long*);
j++)
*(ptr+j) =~*(ptr+j);
}
}
}
break;
case 127:
case '\b':
if (hanging_cursor) {
hanging_cursor = 0;
} else
if (x > 0) {
x--;
}
break;
case '\t':
while (x < vinfo.v_columns && !tab_stops[++x]);
if (x >= vinfo.v_columns)
x = vinfo.v_columns-1;
break;
case 0x0b:
case 0x0c:
case '\n':
if (y >= scrreg_bottom -1 ) {
scrollup(1);
y = scrreg_bottom - 1;
} else {
y++;
}
break;
case '\r':
x = 0;
hanging_cursor = 0;
break;
case 0x0e:
vc_charset_select = 1;
break;
case 0x0f:
vc_charset_select = 0;
break;
case 0x18 :
case 0x1A :
break;
case '\033':
vt100state = ESesc;
hanging_cursor = 0;
break;
default:
if (ch >= ' ') {
if (hanging_cursor) {
x = 0;
if (y >= scrreg_bottom -1 ) {
scrollup(1);
y = scrreg_bottom - 1;
} else {
y++;
}
hanging_cursor = 0;
}
vc_paintchar((ch >= 0x60 && ch <= 0x7f) ? ch + vc_charset[vc_charset_select]
: ch, x, y, attr);
if (x == vinfo.v_columns - 1) {
hanging_cursor = vc_wrap_mode;
} else {
x++;
}
}
break;
}
}
static void
putc_esc(unsigned char ch)
{
vt100state = ESnormal;
switch (ch) {
case '[':
vt100state = ESsquare;
break;
case 'c':
vt100_reset();
clear_screen(2);
x = y = 0;
break;
case 'D':
case 'E':
if (y >= scrreg_bottom -1) {
scrollup(1);
y = scrreg_bottom - 1;
} else {
y++;
}
if (ch == 'E') x = 0;
break;
case 'H':
tab_stops[x] = 1;
break;
case 'M':
if (y <= scrreg_top) {
scrolldown(1);
y = scrreg_top;
} else {
y--;
}
break;
case '>':
vt100_reset();
break;
case '7':
savex = x;
savey = y;
saveattr = attr;
vc_save_charset_s = vc_charset_select;
vc_charset_save[0] = vc_charset[0];
vc_charset_save[1] = vc_charset[1];
break;
case '8':
x = savex;
y = savey;
attr = saveattr;
vc_charset_select = vc_save_charset_s;
vc_charset[0] = vc_charset_save[0];
vc_charset[1] = vc_charset_save[1];
break;
case 'Z':
break;
case '#':
vt100state = EScharsize;
break;
case '(':
vt100state = ESsetG0;
break;
case ')':
vt100state = ESsetG1;
break;
case '=':
break;
default:
break;
}
}
static void
putc_askcmd(unsigned char ch)
{
if (ch >= '0' && ch <= '9') {
par[numpars] = (10*par[numpars]) + (ch-'0');
return;
}
vt100state = ESnormal;
switch (par[0]) {
case 6:
vc_relative_origin = ch == 'h';
break;
case 7:
vc_wrap_mode = ch == 'h';
break;
default:
break;
}
}
static void
putc_charsizecmd(unsigned char ch)
{
vt100state = ESnormal;
switch (ch) {
case '3' :
case '4' :
case '5' :
case '6' :
break;
case '8' :
{
int xx, yy;
for (yy = 0; yy < vinfo.v_rows; yy++)
for (xx = 0; xx < vinfo.v_columns; xx++)
vc_paintchar('E', xx, yy, ATTR_NONE);
}
break;
}
}
static void
putc_charsetcmd(int charset, unsigned char ch)
{
vt100state = ESnormal;
switch (ch) {
case 'A' :
case 'B' :
default:
vc_charset[charset] = 0;
break;
case '0' :
case '2' :
vc_charset[charset] = 0x21;
break;
}
}
static void
putc_gotpars(unsigned char ch)
{
int i;
if (ch < ' ') {
putc_normal(ch);
vt100state = ESgotpars;
return;
}
vt100state = ESnormal;
switch (ch) {
case 'A':
y -= par[0] ? par[0] : 1;
if (y < scrreg_top)
y = scrreg_top;
break;
case 'B':
y += par[0] ? par[0] : 1;
if (y >= scrreg_bottom)
y = scrreg_bottom - 1;
break;
case 'C':
x += par[0] ? par[0] : 1;
if (x >= vinfo.v_columns)
x = vinfo.v_columns-1;
break;
case 'D':
x -= par[0] ? par[0] : 1;
if (x < 0)
x = 0;
break;
case 'H':
case 'f':
x = par[1] ? par[1] - 1 : 0;
y = par[0] ? par[0] - 1 : 0;
if (vc_relative_origin)
y += scrreg_top;
hanging_cursor = 0;
break;
case 'X':
if (numpars) {
int i;
for (i = x; i < x + par[0]; i++)
vc_paintchar(' ', i, y, ATTR_NONE);
}
break;
case 'J':
clear_screen(par[0]);
break;
case 'K':
clear_line(par[0]);
break;
case 'g':
switch (par[0]) {
case 1:
case 2:
break;
case 3:
{
int i;
for (i = 0; i <= vinfo.v_columns; i++)
tab_stops[i] = 0;
}
break;
case 0:
tab_stops[x] = 0;
break;
}
break;
case 'm':
for (i = 0; i < numpars; i++) {
switch (par[i]) {
case 0:
attr = ATTR_NONE;
vc_color_set(VC_RESET_BACKGROUND);
vc_color_set(VC_RESET_FOREGROUND);
break;
case 1:
attr |= ATTR_BOLD;
break;
case 4:
attr |= ATTR_UNDER;
break;
case 7:
attr |= ATTR_REVERSE;
break;
case 22:
attr &= ~ATTR_BOLD;
break;
case 24:
attr &= ~ATTR_UNDER;
break;
case 27:
attr &= ~ATTR_REVERSE;
break;
case 5:
case 25:
break;
default:
vc_color_set(par[i]);
break;
}
}
break;
case 'r':
x = y = 0;
if ((numpars > 0) && (par[0] < vinfo.v_rows)) {
scrreg_top = par[0] ? par[0] - 1 : 0;
if (scrreg_top < 0)
scrreg_top = 0;
} else {
scrreg_top = 0;
}
if ((numpars > 1) && (par[1] <= vinfo.v_rows) && (par[1] > par[0])) {
scrreg_bottom = par[1];
if (scrreg_bottom > vinfo.v_rows)
scrreg_bottom = vinfo.v_rows;
} else {
scrreg_bottom = vinfo.v_rows;
}
if (vc_relative_origin)
y = scrreg_top;
break;
}
}
static void
putc_getpars(unsigned char ch)
{
if (ch == '?') {
vt100state = ESask;
return;
}
if (ch == '[') {
vt100state = ESnormal;
return;
}
if (ch == ';' && numpars < MAXPARS - 1) {
numpars++;
} else
if (ch >= '0' && ch <= '9') {
par[numpars] *= 10;
par[numpars] += ch - '0';
} else {
numpars++;
vt100state = ESgotpars;
putc_gotpars(ch);
}
}
static void
putc_square(unsigned char ch)
{
int i;
for (i = 0; i < MAXPARS; i++) {
par[i] = 0;
}
numpars = 0;
vt100state = ESgetpars;
putc_getpars(ch);
}
void
vc_putchar(char ch)
{
if (!ch) {
return;
}
switch (vt100state) {
default:vt100state = ESnormal;
case ESnormal:
putc_normal(ch);
break;
case ESesc:
putc_esc(ch);
break;
case ESsquare:
putc_square(ch);
break;
case ESgetpars:
putc_getpars(ch);
break;
case ESgotpars:
putc_gotpars(ch);
break;
case ESask:
putc_askcmd(ch);
break;
case EScharsize:
putc_charsizecmd(ch);
break;
case ESsetG0:
putc_charsetcmd(0, ch);
break;
case ESsetG1:
putc_charsetcmd(1, ch);
break;
}
if (x >= vinfo.v_columns) {
x = vinfo.v_columns - 1;
}
if (x < 0) {
x = 0;
}
if (y >= vinfo.v_rows) {
y = vinfo.v_rows - 1;
}
if (y < 0) {
y = 0;
}
}
void vc_flush_forward_buffer(void)
{
int start = 0;
int todo = 0;
spl_t s;
assert(vc_forward_buffer_enabled);
s = splhigh();
simple_lock(&vc_forward_lock);
if (vc_forward_buffer_busy) {
simple_unlock(&vc_forward_lock);
splx(s);
return;
}
vc_forward_buffer_busy = 1;
while (todo < vc_forward_buffer_size) {
todo = vc_forward_buffer_size;
simple_unlock(&vc_forward_lock);
splx(s);
reversecursor();
do {
int i;
#ifdef FAST_JUMP_SCROLL
if ((todo - start) < 2) {
vc_putchar(vc_forward_buffer[start++]);
} else {
assert(vc_forward_scroll == 0);
vc_forward_preflight_save.vt100state = vt100state;
vc_forward_preflight_save.vc_wrap_mode = vc_wrap_mode;
vc_forward_preflight_save.vc_relative_origin = vc_relative_origin;
vc_forward_preflight_save.vc_charset_select = vc_charset_select;
vc_forward_preflight_save.vc_save_charset_s = vc_save_charset_s;
vc_forward_preflight_save.vc_charset[0] = vc_charset[0];
vc_forward_preflight_save.vc_charset[1] = vc_charset[1];
vc_forward_preflight_save.vc_charset_save[0] = vc_charset_save[0];
vc_forward_preflight_save.vc_charset_save[1] = vc_charset_save[1];
vc_forward_preflight_save.x = x;
vc_forward_preflight_save.y = y;
vc_forward_preflight_save.savex = savex;
vc_forward_preflight_save.savey = savey;
vc_forward_preflight_save.numpars = numpars;
vc_forward_preflight_save.hanging_cursor = hanging_cursor;
vc_forward_preflight_save.attr = attr;
vc_forward_preflight_save.saveattr = saveattr;
vc_forward_preflight_save.scrreg_top = scrreg_top;
vc_forward_preflight_save.scrreg_bottom = scrreg_bottom;
vc_forward_preflight_save.vc_color_fore = vc_color_fore;
vc_forward_preflight_save.vc_color_back = vc_color_back;
bcopy( (const char *) par,
(char *) vc_forward_preflight_save.par,
(vm_size_t) sizeof(par) );
bcopy( (const char *) tab_stops,
(char *) vc_forward_preflight_save.tab_stops,
(vm_size_t) sizeof(tab_stops) );
vc_forward_preflight_mode = PFwind;
for (i = start;
i < todo &&
vc_forward_preflight_save.scrreg_top == scrreg_top &&
vc_forward_preflight_save.scrreg_bottom == scrreg_bottom;
i++)
vc_putchar(vc_forward_buffer[i]);
vt100state = vc_forward_preflight_save.vt100state;
vc_wrap_mode = vc_forward_preflight_save.vc_wrap_mode;
vc_relative_origin = vc_forward_preflight_save.vc_relative_origin;
vc_charset_select = vc_forward_preflight_save.vc_charset_select;
vc_save_charset_s = vc_forward_preflight_save.vc_save_charset_s;
vc_charset[0] = vc_forward_preflight_save.vc_charset[0];
vc_charset[1] = vc_forward_preflight_save.vc_charset[1];
vc_charset_save[0] = vc_forward_preflight_save.vc_charset_save[0];
vc_charset_save[1] = vc_forward_preflight_save.vc_charset_save[1];
x = vc_forward_preflight_save.x;
y = vc_forward_preflight_save.y;
savex = vc_forward_preflight_save.savex;
savey = vc_forward_preflight_save.savey;
numpars = vc_forward_preflight_save.numpars;
hanging_cursor = vc_forward_preflight_save.hanging_cursor;
attr = vc_forward_preflight_save.attr;
saveattr = vc_forward_preflight_save.saveattr;
scrreg_top = vc_forward_preflight_save.scrreg_top;
scrreg_bottom = vc_forward_preflight_save.scrreg_bottom;
vc_color_fore = vc_forward_preflight_save.vc_color_fore;
vc_color_back = vc_forward_preflight_save.vc_color_back;
bcopy( (const char *) vc_forward_preflight_save.par,
(char *) par,
(vm_size_t) sizeof(par) );
bcopy( (const char *) vc_forward_preflight_save.tab_stops,
(char *) tab_stops,
(vm_size_t) sizeof(tab_stops) );
vc_forward_preflight_mode = PFscroll;
if (vc_forward_scroll > 0)
scrollup(vc_forward_scroll > scrreg_bottom - scrreg_top ?
scrreg_bottom - scrreg_top : vc_forward_scroll);
else if (vc_forward_scroll < 0)
scrolldown(-vc_forward_scroll > scrreg_bottom - scrreg_top ?
scrreg_bottom - scrreg_top : -vc_forward_scroll);
vc_forward_preflight_mode = PFunwind;
for (; start < i; start++)
vc_putchar(vc_forward_buffer[start]);
assert(vc_forward_scroll == 0);
vc_forward_preflight_mode = PFoff;
}
#else !FAST_JUMP_SCROLL
int plaintext = 1;
int drawlen = start;
int jump = 0;
int param = 0, changebackground = 0;
enum vt100state_e vtState = vt100state;
for (i = start; i < todo && plaintext; i++) {
drawlen++;
switch (vtState) {
case ESnormal:
switch (vc_forward_buffer[i]) {
case '\033':
vtState = ESesc;
break;
case '\n':
jump++;
break;
}
break;
case ESesc:
switch (vc_forward_buffer[i]) {
case '[':
vtState = ESgetpars;
param = 0;
changebackground = 0;
break;
default:
plaintext = 0;
break;
}
break;
case ESgetpars:
if ((vc_forward_buffer[i] >= '0' &&
vc_forward_buffer[i] <= '9') ||
vc_forward_buffer[i] == ';') {
if (vc_forward_buffer[i] >= '0' &&
vc_forward_buffer[i] <= '9')
param = (param*10)+(vc_forward_buffer[i]-'0');
else {
if (param >= 40 && param <= 47)
changebackground = 1;
if (!vc_normal_background &&
!param)
changebackground = 1;
param = 0;
}
break;
}
vtState = ESgotpars;
case ESgotpars:
switch (vc_forward_buffer[i]) {
case 'm':
vtState = ESnormal;
if (param >= 40 && param <= 47)
changebackground = 1;
if (!vc_normal_background &&
!param)
changebackground = 1;
if (changebackground) {
plaintext = 0;
jump = 0;
}
break;
default:
plaintext = 0;
break;
}
break;
default:
plaintext = 0;
break;
}
}
if (jump && (scrreg_bottom - scrreg_top) > 2) {
jump -= scrreg_bottom - y - 1;
if (jump > 0 ) {
if (jump >= scrreg_bottom - scrreg_top)
jump = scrreg_bottom - scrreg_top -1;
y -= jump;
scrollup(jump);
}
}
for (i = start; i < drawlen; i++)
vc_putchar(vc_forward_buffer[start++]);
for (i = start; i < todo &&
vt100state != ESnormal ; i++)
vc_putchar(vc_forward_buffer[start++]);
#endif !FAST_JUMP_SCROLL
} while (start < todo);
reversecursor();
s = splhigh();
simple_lock(&vc_forward_lock);
}
vc_forward_buffer_busy = 0;
vc_forward_buffer_size = 0;
simple_unlock(&vc_forward_lock);
splx(s);
}
int
vcputc(int l, int u, int c)
{
if (vc_forward_buffer_enabled)
vc_store_char(c);
else
vc_putchar(c);
return 0;
}
void
vc_store_char(unsigned char c)
{
int flush = 0;
spl_t s;
assert(vc_forward_buffer_enabled);
s = splhigh();
simple_lock(&vc_forward_lock);
while (vc_forward_buffer_size == VC_MAX_FORWARD_SIZE) {
simple_unlock(&vc_forward_lock);
splx(s);
s = splhigh();
simple_lock(&vc_forward_lock);
}
assert(vc_forward_buffer_size < VC_MAX_FORWARD_SIZE);
vc_forward_buffer[vc_forward_buffer_size++] = (unsigned char)c;
if (vc_forward_buffer_size == 1) {
if (debug_mode) {
flush = 1;
} else {
timeout((timeout_fcn_t)vc_flush_forward_buffer,
(void *)0,
VC_CONSOLE_UPDATE_TIMEOUT);
}
} else if (vc_forward_buffer_size == VC_MAX_FORWARD_SIZE || debug_mode) {
if (!vc_forward_buffer_busy) {
flush = 1;
untimeout((timeout_fcn_t)vc_flush_forward_buffer, (void *)0);
}
}
simple_unlock(&vc_forward_lock);
splx(s);
if (flush) {
vc_flush_forward_buffer();
}
}
void
vc_initialize(void)
{
#if 0
GratefulDebInit();
#endif
#if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
printf(" Video info: %d; video_board=%08X\n", i, vboard);
printf(" Video name: %s\n", vinfo.v_name);
printf(" height=%d; width=%d, depth=%d; rowbytes=%d; type=%08X\n",
vinfo.v_height, vinfo.v_width, vinfo.v_depth, vinfo.v_rowbytes, vinfo.v_type);
printf(" physical address=%08X\n", vinfo.v_physaddr);
#endif
vinfo.v_rows = vinfo.v_height / CHARHEIGHT;
vinfo.v_columns = vinfo.v_width / CHARWIDTH;
if (vinfo.v_depth >= 8) {
vinfo.v_rowscanbytes = (vinfo.v_depth / 8) * vinfo.v_width;
} else {
vinfo.v_rowscanbytes = vinfo.v_width / (8 / vinfo.v_depth);
}
#if DEBUG && SERIAL_CONSOLE_DEFAULT && !defined(MACH_PE)
printf(" inited=%d\n", vc_initted);
#endif
vc_render_font(1, vinfo.v_depth);
vc_color_mask = vc_color_depth_masks[vc_color_index_table[vinfo.v_depth]];
vt100_reset();
switch (vinfo.v_depth) {
default:
case 1:
vc_paintchar = vc_paint_char1;
break;
case 2:
vc_paintchar = vc_paint_char2;
break;
case 4:
vc_paintchar = vc_paint_char4;
break;
case 8:
vc_paintchar = vc_paint_char8c;
break;
case 16:
vc_paintchar = vc_paint_char16c;
break;
case 32:
vc_paintchar = vc_paint_char32c;
break;
}
#ifdef FAST_JUMP_SCROLL
vc_forward_paintchar = vc_paintchar;
vc_paintchar = vc_paint_char;
#endif FAST_JUMP_SCROLL
}
void
vcattach(void)
{
if (vinfo.v_depth >= 8)
printf("\033[31mC\033[32mO\033[33mL\033[34mO\033[35mR\033[0m ");
printf("video console at 0x%x (%dx%dx%d)\n", vinfo.v_baseaddr,
vinfo.v_width, vinfo.v_height, vinfo.v_depth);
simple_lock_init(&vc_forward_lock, ETAP_IO_TTY);
vc_forward_buffer_enabled = 1;
}
struct vc_progress_element {
unsigned int version;
unsigned int flags;
unsigned int time;
unsigned char count;
unsigned char res[3];
int width;
int height;
int dx;
int dy;
int transparent;
unsigned int res2[3];
unsigned char data[0];
};
typedef struct vc_progress_element vc_progress_element;
static vc_progress_element * vc_progress;
static unsigned char * vc_progress_data;
static boolean_t vc_progress_enable;
static unsigned char * vc_clut;
static unsigned int vc_progress_tick;
static boolean_t vc_graphics_mode;
static boolean_t vc_acquired;
static boolean_t vc_need_clear;
void vc_blit_rect_8c( int x, int y,
int width, int height,
int transparent, unsigned char * dataPtr )
{
volatile unsigned char * dst;
int line, col;
unsigned char data;
dst = (unsigned char *)(vinfo.v_baseaddr +
(y * vinfo.v_rowbytes) +
(x));
for( line = 0; line < height; line++) {
for( col = 0; col < width; col++) {
data = *dataPtr++;
if( data == transparent)
continue;
*(dst + col) = data;
}
dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
}
}
void vc_blit_rect_8m( int x, int y,
int width, int height,
int transparent, unsigned char * dataPtr )
{
volatile unsigned char * dst;
int line, col;
unsigned int data;
dst = (unsigned char *)(vinfo.v_baseaddr +
(y * vinfo.v_rowbytes) +
(x));
for( line = 0; line < height; line++) {
for( col = 0; col < width; col++) {
data = *dataPtr++;
if( data == transparent)
continue;
data *= 3;
*(dst + col) = ((19595 * vc_clut[data + 0] +
38470 * vc_clut[data + 1] +
7471 * vc_clut[data + 2] ) / 65536);
}
dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
}
}
void vc_blit_rect_16( int x, int y,
int width, int height,
int transparent, unsigned char * dataPtr )
{
volatile unsigned short * dst;
int line, col;
unsigned int data;
dst = (volatile unsigned short *)(vinfo.v_baseaddr +
(y * vinfo.v_rowbytes) +
(x * 2));
for( line = 0; line < height; line++) {
for( col = 0; col < width; col++) {
data = *dataPtr++;
if( data == transparent)
continue;
data *= 3;
*(dst + col) = ( (0xf8 & (vc_clut[data + 0])) << 7)
| ( (0xf8 & (vc_clut[data + 1])) << 2)
| ( (0xf8 & (vc_clut[data + 2])) >> 3);
}
dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
}
}
void vc_blit_rect_32( unsigned int x, unsigned int y,
unsigned int width, unsigned int height,
int transparent, unsigned char * dataPtr )
{
volatile unsigned int * dst;
int line, col;
unsigned int data;
dst = (volatile unsigned int *) (vinfo.v_baseaddr +
(y * vinfo.v_rowbytes) +
(x * 4));
for( line = 0; line < height; line++) {
for( col = 0; col < width; col++) {
data = *dataPtr++;
if( data == transparent)
continue;
data *= 3;
*(dst + col) = (vc_clut[data + 0] << 16)
| (vc_clut[data + 1] << 8)
| (vc_clut[data + 2]);
}
dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
}
}
void vc_blit_rect( int x, int y,
int width, int height,
int transparent, unsigned char * dataPtr )
{
switch( vinfo.v_depth) {
case 8:
vc_blit_rect_8c( x, y, width, height, transparent, dataPtr);
break;
case 16:
vc_blit_rect_16( x, y, width, height, transparent, dataPtr);
break;
case 32:
vc_blit_rect_32( x, y, width, height, transparent, dataPtr);
break;
}
}
void vc_progress_task( void * arg )
{
spl_t s;
int count = (int) arg;
int x, y, width, height;
unsigned char * data;
s = splhigh();
simple_lock(&vc_forward_lock);
if( vc_progress_enable) {
count++;
if( count >= vc_progress->count)
count = 0;
width = vc_progress->width;
height = vc_progress->height;
x = vc_progress->dx;
y = vc_progress->dy;
data = vc_progress_data;
data += count * width * height;
if( 1 & vc_progress->flags) {
x += (vinfo.v_width / 2);
x += (vinfo.v_height / 2);
}
vc_blit_rect( x, y, width, height,
vc_progress->transparent,data );
timeout( vc_progress_task, (void *) count,
vc_progress_tick );
}
simple_unlock(&vc_forward_lock);
splx(s);
}
void vc_display_icon( vc_progress_element * desc,
unsigned char * data )
{
int x, y, width, height;
if( vc_acquired && vc_graphics_mode && vc_clut) {
width = desc->width;
height = desc->height;
x = desc->dx;
y = desc->dy;
if( 1 & desc->flags) {
x += (vinfo.v_width / 2);
y += (vinfo.v_height / 2);
}
vc_blit_rect( x, y, width, height, desc->transparent, data );
}
}
boolean_t
vc_progress_set( boolean_t enable )
{
spl_t s;
if( !vc_progress)
return( FALSE );
s = splhigh();
simple_lock(&vc_forward_lock);
if( vc_progress_enable != enable) {
vc_progress_enable = enable;
if( enable)
timeout(vc_progress_task, (void *) 0,
vc_progress_tick );
else
untimeout( vc_progress_task, (void *) 0 );
}
simple_unlock(&vc_forward_lock);
splx(s);
return( TRUE );
}
boolean_t
vc_progress_initialize( vc_progress_element * desc,
unsigned char * data,
unsigned char * clut )
{
if( (!clut) || (!desc) || (!data))
return( FALSE );
vc_clut = clut;
vc_progress = desc;
vc_progress_data = data;
vc_progress_tick = vc_progress->time * hz / 1000;
return( TRUE );
}
Boot_Video boot_video_info;
extern int disableConsoleOutput;
void vc_clear_screen( void )
{
reversecursor();
vt100_reset();
x = y = 0;
clear_screen(2);
reversecursor();
};
void
initialize_screen(Boot_Video * boot_vinfo, unsigned int op)
{
if( boot_vinfo) {
bcopy( (const void *) boot_vinfo,
(void *) &boot_video_info,
sizeof( boot_video_info));
vinfo.v_name[0] = 0;
vinfo.v_width = boot_vinfo->v_width;
vinfo.v_height = boot_vinfo->v_height;
vinfo.v_depth = boot_vinfo->v_depth;
vinfo.v_rowbytes = boot_vinfo->v_rowBytes;
vinfo.v_physaddr = boot_vinfo->v_baseAddr;
vinfo.v_baseaddr = vinfo.v_physaddr;
vinfo.v_type = 0;
vc_initialize();
#if 0
GratefulDebInit((bootBumbleC *)boot_vinfo);
#endif
}
switch( op ) {
case kPEGraphicsMode:
vc_graphics_mode = TRUE;
disableConsoleOutput = TRUE;
vc_acquired = TRUE;
break;
case kPETextMode:
vc_graphics_mode = FALSE;
disableConsoleOutput = FALSE;
vc_acquired = TRUE;
vc_clear_screen();
break;
case kPETextScreen:
vc_progress_set( FALSE );
disableConsoleOutput = FALSE;
if( vc_need_clear) {
vc_need_clear = FALSE;
vc_clear_screen();
}
break;
case kPEEnableScreen:
if( vc_acquired) {
if( vc_graphics_mode)
vc_progress_set( TRUE );
else
vc_clear_screen();
}
break;
case kPEDisableScreen:
vc_progress_set( FALSE );
break;
case kPEAcquireScreen:
vc_need_clear = (FALSE == vc_acquired);
vc_acquired = TRUE;
vc_progress_set( vc_graphics_mode );
disableConsoleOutput = vc_graphics_mode;
if( vc_need_clear && !vc_graphics_mode) {
vc_need_clear = FALSE;
vc_clear_screen();
}
break;
case kPEReleaseScreen:
vc_acquired = FALSE;
vc_progress_set( FALSE );
disableConsoleOutput = TRUE;
#if 0
GratefulDebInit(0);
#endif
break;
}
#if 0
if( boot_vinfo) GratefulDebInit((bootBumbleC *)boot_vinfo);
#endif
}