49,9 → 49,6 |
#include <ipc/ns.h> |
#include <ipc/services.h> |
#include <libarch/ddi.h> |
#include <io/style.h> |
#include <io/color.h> |
#include <sys/types.h> |
|
#include "ega.h" |
#include "../console/screenbuffer.h" |
64,14 → 61,13 |
|
saved_screen saved_screens[MAX_SAVED_SCREENS]; |
|
#define EGA_IO_BASE ((ioport8_t *) 0x3d4) |
#define EGA_IO_ADDRESS 0x3d4 |
#define EGA_IO_SIZE 2 |
|
int ega_normal_color = 0x0f; |
int ega_inverted_color = 0xf0; |
#define NORMAL_COLOR 0x0f |
#define INVERTED_COLOR 0xf0 |
|
#define NORMAL_COLOR ega_normal_color |
#define INVERTED_COLOR ega_inverted_color |
#define EGA_STYLE(fg,bg) ((fg) > (bg) ? NORMAL_COLOR : INVERTED_COLOR) |
|
/* Allow only 1 connection */ |
static int client_connected = 0; |
78,16 → 74,13 |
|
static unsigned int scr_width; |
static unsigned int scr_height; |
static uint8_t *scr_addr; |
static char *scr_addr; |
|
static unsigned int style; |
static unsigned int style = NORMAL_COLOR; |
|
static unsigned attr_to_ega_style(const attrs_t *a); |
static uint8_t ega_glyph(wchar_t ch); |
|
static void clrscr(void) |
{ |
unsigned i; |
int i; |
|
for (i = 0; i < scr_width * scr_height; i++) { |
scr_addr[i * 2] = ' '; |
95,16 → 88,16 |
} |
} |
|
static void cursor_goto(unsigned int col, unsigned int row) |
static void cursor_goto(unsigned int row, unsigned int col) |
{ |
int ega_cursor; |
|
ega_cursor = col + scr_width * row; |
|
pio_write_8(EGA_IO_BASE, 0xe); |
pio_write_8(EGA_IO_BASE + 1, (ega_cursor >> 8) & 0xff); |
pio_write_8(EGA_IO_BASE, 0xf); |
pio_write_8(EGA_IO_BASE + 1, ega_cursor & 0xff); |
outb(EGA_IO_ADDRESS, 0xe); |
outb(EGA_IO_ADDRESS + 1, (ega_cursor >> 8) & 0xff); |
outb(EGA_IO_ADDRESS, 0xf); |
outb(EGA_IO_ADDRESS + 1, ega_cursor & 0xff); |
} |
|
static void cursor_disable(void) |
111,10 → 104,10 |
{ |
uint8_t stat; |
|
pio_write_8(EGA_IO_BASE, 0xa); |
stat = pio_read_8(EGA_IO_BASE + 1); |
pio_write_8(EGA_IO_BASE, 0xa); |
pio_write_8(EGA_IO_BASE + 1, stat | (1 << 5)); |
outb(EGA_IO_ADDRESS, 0xa); |
stat=inb(EGA_IO_ADDRESS + 1); |
outb(EGA_IO_ADDRESS, 0xa); |
outb(EGA_IO_ADDRESS + 1, stat | (1 << 5)); |
} |
|
static void cursor_enable(void) |
121,24 → 114,23 |
{ |
uint8_t stat; |
|
pio_write_8(EGA_IO_BASE, 0xa); |
stat = pio_read_8(EGA_IO_BASE + 1); |
pio_write_8(EGA_IO_BASE, 0xa); |
pio_write_8(EGA_IO_BASE + 1, stat & (~(1 << 5))); |
outb(EGA_IO_ADDRESS, 0xa); |
stat=inb(EGA_IO_ADDRESS + 1); |
outb(EGA_IO_ADDRESS, 0xa); |
outb(EGA_IO_ADDRESS + 1, stat & (~(1 << 5))); |
} |
|
static void scroll(int rows) |
{ |
unsigned i; |
|
int i; |
if (rows > 0) { |
memmove(scr_addr, ((char *) scr_addr) + rows * scr_width * 2, |
memcpy(scr_addr, ((char *) scr_addr) + rows * scr_width * 2, |
scr_width * scr_height * 2 - rows * scr_width * 2); |
for (i = 0; i < rows * scr_width; i++) |
(((short *) scr_addr) + scr_width * scr_height - rows * |
scr_width)[i] = ((style << 8) + ' '); |
} else if (rows < 0) { |
memmove(((char *)scr_addr) - rows * scr_width * 2, scr_addr, |
memcpy(((char *)scr_addr) - rows * scr_width * 2, scr_addr, |
scr_width * scr_height * 2 + rows * scr_width * 2); |
for (i = 0; i < -rows * scr_width; i++) |
((short *)scr_addr)[i] = ((style << 8 ) + ' '); |
145,38 → 137,22 |
} |
} |
|
static void printchar(wchar_t c, unsigned int col, unsigned int row) |
static void printchar(char c, unsigned int row, unsigned int col) |
{ |
scr_addr[(row * scr_width + col) * 2] = ega_glyph(c); |
scr_addr[(row * scr_width + col) * 2] = c; |
scr_addr[(row * scr_width + col) * 2 + 1] = style; |
|
cursor_goto(col + 1, row); |
cursor_goto(row, col + 1); |
} |
|
/** Draw text data to viewport. |
* |
* @param vport Viewport id |
* @param data Text data. |
* @param x Leftmost column of the area. |
* @param y Topmost row of the area. |
* @param w Number of rows. |
* @param h Number of columns. |
*/ |
static void draw_text_data(keyfield_t *data, unsigned int x, |
unsigned int y, unsigned int w, unsigned int h) |
static void draw_text_data(keyfield_t *data) |
{ |
unsigned int i, j; |
keyfield_t *field; |
uint8_t *dp; |
int i; |
|
for (j = 0; j < h; j++) { |
for (i = 0; i < w; i++) { |
field = &data[j * w + i]; |
dp = &scr_addr[2 * ((y + j) * scr_width + (x + i))]; |
|
dp[0] = ega_glyph(field->character); |
dp[1] = attr_to_ega_style(&field->attrs); |
} |
for (i = 0; i < scr_width * scr_height; i++) { |
scr_addr[i * 2] = data[i].character; |
scr_addr[i * 2 + 1] = EGA_STYLE(data[i].style.fg_color, |
data[i].style.bg_color); |
} |
} |
|
205,72 → 181,15 |
return i; |
} |
|
static int style_to_ega_style(int style) |
{ |
unsigned int ega_style; |
|
switch (style) { |
case STYLE_NORMAL: |
ega_style = INVERTED_COLOR; |
break; |
case STYLE_EMPHASIS: |
ega_style = INVERTED_COLOR | 4; |
break; |
default: |
return INVERTED_COLOR; |
} |
|
return ega_style; |
} |
|
static unsigned int color_to_ega_style(int fg_color, int bg_color, int attr) |
{ |
unsigned int style; |
|
style = (fg_color & 7) | ((bg_color & 7) << 4); |
if (attr & CATTR_BRIGHT) |
style = style | 0x08; |
|
return style; |
} |
|
static unsigned int rgb_to_ega_style(uint32_t fg, uint32_t bg) |
{ |
return (fg > bg) ? NORMAL_COLOR : INVERTED_COLOR; |
} |
|
static unsigned attr_to_ega_style(const attrs_t *a) |
{ |
switch (a->t) { |
case at_style: |
return style_to_ega_style(a->a.s.style); |
case at_rgb: |
return rgb_to_ega_style(a->a.r.fg_color, a->a.r.bg_color); |
case at_idx: |
return color_to_ega_style(a->a.i.fg_color, |
a->a.i.bg_color, a->a.i.flags); |
default: |
return INVERTED_COLOR; |
} |
} |
|
static uint8_t ega_glyph(wchar_t ch) |
{ |
if (ch >= 0 && ch < 128) |
return ch; |
|
return '?'; |
} |
|
static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
int retval; |
ipc_callid_t callid; |
ipc_call_t call; |
wchar_t c; |
unsigned int row, col, w, h; |
int bg_color, fg_color, attr; |
uint32_t bg_rgb, fg_rgb; |
char c; |
unsigned int row, col; |
int bgcolor,fgcolor; |
keyfield_t *interbuf = NULL; |
size_t intersize = 0; |
int i; |
301,27 → 220,16 |
retval = EINVAL; |
break; |
case FB_DRAW_TEXT_DATA: |
col = IPC_GET_ARG1(call); |
row = IPC_GET_ARG2(call); |
w = IPC_GET_ARG3(call); |
h = IPC_GET_ARG4(call); |
if (!interbuf) { |
retval = EINVAL; |
break; |
} |
if (col + w > scr_width || row + h > scr_height) { |
retval = EINVAL; |
break; |
} |
draw_text_data(interbuf, col, row, w, h); |
draw_text_data(interbuf); |
retval = 0; |
break; |
case FB_GET_CSIZE: |
ipc_answer_2(callid, EOK, scr_width, scr_height); |
ipc_answer_2(callid, EOK, scr_height, scr_width); |
continue; |
case FB_GET_COLOR_CAP: |
ipc_answer_1(callid, EOK, FB_CCAP_INDEXED); |
continue; |
case FB_CLEAR: |
clrscr(); |
retval = 0; |
328,28 → 236,28 |
break; |
case FB_PUTCHAR: |
c = IPC_GET_ARG1(call); |
col = IPC_GET_ARG2(call); |
row = IPC_GET_ARG3(call); |
row = IPC_GET_ARG2(call); |
col = IPC_GET_ARG3(call); |
if (col >= scr_width || row >= scr_height) { |
retval = EINVAL; |
break; |
} |
printchar(c, col, row); |
printchar(c, row, col); |
retval = 0; |
break; |
case FB_CURSOR_GOTO: |
col = IPC_GET_ARG1(call); |
row = IPC_GET_ARG2(call); |
row = IPC_GET_ARG1(call); |
col = IPC_GET_ARG2(call); |
if (row >= scr_height || col >= scr_width) { |
retval = EINVAL; |
break; |
} |
cursor_goto(col, row); |
cursor_goto(row, col); |
retval = 0; |
break; |
case FB_SCROLL: |
i = IPC_GET_ARG1(call); |
if (i > (int) scr_height || i < -((int) scr_height)) { |
if (i > scr_height || i < -((int) scr_height)) { |
retval = EINVAL; |
break; |
} |
357,7 → 265,7 |
retval = 0; |
break; |
case FB_CURSOR_VISIBILITY: |
if (IPC_GET_ARG1(call)) |
if(IPC_GET_ARG1(call)) |
cursor_enable(); |
else |
cursor_disable(); |
364,22 → 272,11 |
retval = 0; |
break; |
case FB_SET_STYLE: |
style = style_to_ega_style(IPC_GET_ARG1(call)); |
fgcolor = IPC_GET_ARG1(call); |
bgcolor = IPC_GET_ARG2(call); |
style = EGA_STYLE(fgcolor, bgcolor); |
retval = 0; |
break; |
case FB_SET_COLOR: |
fg_color = IPC_GET_ARG1(call); |
bg_color = IPC_GET_ARG2(call); |
attr = IPC_GET_ARG3(call); |
style = color_to_ega_style(fg_color, bg_color, attr); |
retval = 0; |
break; |
case FB_SET_RGB_COLOR: |
fg_rgb = IPC_GET_ARG1(call); |
bg_rgb = IPC_GET_ARG2(call); |
style = rgb_to_ega_style(fg_rgb, bg_rgb); |
retval = 0; |
break; |
case FB_VP_DRAW_PIXMAP: |
i = IPC_GET_ARG2(call); |
retval = print_screen(i); |
399,12 → 296,9 |
} |
retval = 0; |
break; |
case FB_SCREEN_YIELD: |
case FB_SCREEN_RECLAIM: |
retval = EOK; |
break; |
|
default: |
retval = EINVAL; |
retval = ENOENT; |
} |
ipc_answer_0(callid, retval); |
} |
418,22 → 312,13 |
ega_ph_addr = (void *) sysinfo_value("fb.address.physical"); |
scr_width = sysinfo_value("fb.width"); |
scr_height = sysinfo_value("fb.height"); |
iospace_enable(task_get_id(), (void *) EGA_IO_ADDRESS, 2); |
|
if (sysinfo_value("fb.blinking")) { |
ega_normal_color &= 0x77; |
ega_inverted_color &= 0x77; |
} |
|
style = NORMAL_COLOR; |
|
iospace_enable(task_get_id(), (void *) EGA_IO_BASE, 2); |
|
sz = scr_width * scr_height * 2; |
scr_addr = as_get_mappable_page(sz); |
|
if (physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >> |
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0) |
return -1; |
physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >> |
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE); |
|
async_set_client_connection(ega_client_connection); |
|
441,6 → 326,6 |
} |
|
|
/** |
/** |
* @} |
*/ |