212 lines
5.6 KiB
C
212 lines
5.6 KiB
C
// console.c
|
|
// Author: Josh Holtrop
|
|
// Date: 08/02/04
|
|
// Modified: 08/03/04
|
|
|
|
#include "char/console.h"
|
|
#include "hos_defines.h"
|
|
#include "fs/devices.h"
|
|
#include "mm/vmm.h"
|
|
#include "lang/asmfuncs.h"
|
|
|
|
console_t *consoles[256];
|
|
int activeConsole;
|
|
|
|
void console_put_char(minor_t id, int c);
|
|
void console_write_cursor(minor_t id, u16_t position);
|
|
void console_refresh();
|
|
|
|
// initialization routine for consoles module
|
|
int console_init(u32_t num, int width, int height)
|
|
{
|
|
activeConsole = 0;
|
|
dev_driver_t *console_driver = New(dev_driver_t);
|
|
console_driver->block_read = NULL;
|
|
console_driver->block_write = NULL;
|
|
console_driver->char_read = NULL;
|
|
console_driver->char_write = console_char_write;
|
|
devices_register_major('c', MAJOR_CONSOLE, console_driver);
|
|
kfree(console_driver);
|
|
for (; num > 1; num--)
|
|
{
|
|
if (( consoles[num] = New(console_t) ))
|
|
{
|
|
if (( consoles[num]->buffer = kmalloc(width * height) ))
|
|
{
|
|
consoles[num]->cursorPosition = 0;
|
|
consoles[num]->width = width;
|
|
consoles[num]->height = height;
|
|
consoles[num]->cursorStackPosition = 0;
|
|
consoles[num]->escapeLevel = 0;
|
|
consoles[num]->escapePosition = 0;
|
|
memsetd(consoles[num]->escapeValue, 0, 8);
|
|
consoles[num]->attribute = 0x07;
|
|
memsetw(consoles[num]->buffer, 0x0720, width * height);
|
|
}
|
|
else
|
|
{
|
|
kfree(consoles[num]);
|
|
return -2;
|
|
}
|
|
}
|
|
else
|
|
return -1;
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int console_activate(int num)
|
|
{
|
|
if (consoles[num])
|
|
{
|
|
activeConsole = num;
|
|
memcpyw((void*)CONSOLE_MEMORY, consoles[num]->buffer, consoles[num]->width * consoles[num]->height);
|
|
writeCursorPosition(consoles[num]->cursorPosition);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
int console_char_write(minor_t id, u64_t position, int c)
|
|
{
|
|
if (!consoles[id])
|
|
return -1;
|
|
int cursorY = consoles[id]->cursorPosition / consoles[id]->width;
|
|
int cursorX = consoles[id]->cursorPosition % consoles[id]->width;
|
|
switch (consoles[id]->escapeLevel)
|
|
{
|
|
case 2:
|
|
if (c >= '0' && c <= '9') // c is part of an escape value
|
|
{
|
|
consoles[id]->escapeValue[consoles[id]->escapePosition] *= 10;
|
|
consoles[id]->escapeValue[consoles[id]->escapePosition] += c - '0';
|
|
return 0;
|
|
}
|
|
else if (c == ';')
|
|
{
|
|
if (consoles[id]->escapePosition < 7)
|
|
consoles[id]->escapePosition++;
|
|
return 0;
|
|
}
|
|
switch (c)
|
|
{
|
|
case 'A': // move cursor up n rows
|
|
cursorY -= consoles[id]->escapeValue[0];
|
|
if (cursorY < 0)
|
|
cursorY = 0;
|
|
console_write_cursor(id, cursorY * consoles[id]->width + cursorX);
|
|
break;
|
|
case 'B': // move cursor down n rows
|
|
cursorY += consoles[id]->escapeValue[0];
|
|
if (cursorY >= consoles[id]->height)
|
|
cursorY = consoles[id]->height - 1;
|
|
console_write_cursor(id, cursorY * consoles[id]->width + cursorX);
|
|
break;
|
|
case 'C': // move cursor right n columns
|
|
cursorX -= consoles[id]->escapeValue[0];
|
|
if (cursorX < 0)
|
|
cursorX = 0;
|
|
console_write_cursor(id, cursorY * consoles[id]->width + cursorX);
|
|
break;
|
|
case 'D': // move cursor left n columns
|
|
cursorX += consoles[id]->escapeValue[0];
|
|
if (cursorX >= consoles[id]->width)
|
|
cursorX = consoles[id]->width - 1;
|
|
console_write_cursor(id, cursorY * consoles[id]->width + cursorX);
|
|
break;
|
|
case 'H':
|
|
case 'f': // move cursor to position (x,y) upper left is (1,1)
|
|
cursorX = consoles[id]->escapeValue[0] - 1;
|
|
cursorY = consoles[id]->escapeValue[1] - 1;
|
|
if (cursorY < 0)
|
|
cursorY = 0;
|
|
if (cursorY >= consoles[id]->height)
|
|
cursorY = consoles[id]->height - 1;
|
|
if (cursorX < 0)
|
|
cursorX = 0;
|
|
if (cursorX >= consoles[id]->width)
|
|
cursorX = consoles[id]->width - 1;
|
|
console_write_cursor(id, 0);
|
|
break;
|
|
case 'J': // clear screen, home cursor
|
|
memsetw(consoles[id]->buffer, 0x0720, consoles[id]->width * consoles[id]->height);
|
|
console_refresh();
|
|
console_write_cursor(id, 0);
|
|
break;
|
|
case 'K': // erase line from cursor position (including char. under cursor) to end of line
|
|
memsetw(consoles[id]->buffer + consoles[id]->cursorPosition, 0x0720, consoles[id]->width - cursorX);
|
|
console_refresh();
|
|
break;
|
|
case 's': // push cursor position on an internal stack
|
|
if (consoles[id]->cursorStackPosition < 16)
|
|
consoles[id]->cursorStack[consoles[id]->cursorStackPosition++] = consoles[id]->cursorPosition;
|
|
break;
|
|
case 'u': // pop cursor position from stack
|
|
if (consoles[id]->cursorStackPosition > 0)
|
|
consoles[id]->cursorPosition = consoles[id]->cursorStack[--consoles[id]->cursorStackPosition];
|
|
break;
|
|
case 'm': // set text attributes
|
|
for (; consoles[id]->escapePosition >= 0; consoles[id]->escapePosition--)
|
|
{
|
|
switch (consoles[id]->escapeValue[consoles[id]->escapePosition])
|
|
{
|
|
case 0:
|
|
consoles[id]->attribute = 0x07;
|
|
break;
|
|
case 1:
|
|
case 5:
|
|
case 7:
|
|
case 30:
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
memsetd(consoles[id]->escapeValue, 0, 8);
|
|
consoles[id]->escapePosition = 0;
|
|
consoles[id]->escapeLevel = 0;
|
|
return 0;
|
|
case 1:
|
|
if (c == '[')
|
|
consoles[id]->escapeLevel = 2;
|
|
break;
|
|
consoles[id]->escapeLevel = 0;
|
|
return 0; // invalid escape sequence
|
|
default:
|
|
if (c == '\e')
|
|
{
|
|
consoles[id]->escapeLevel = 1;
|
|
return 0;
|
|
}
|
|
console_put_char(id, c);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void console_put_char(minor_t id, int c)
|
|
{
|
|
|
|
}
|
|
|
|
void console_write_cursor(minor_t id, u16_t position)
|
|
{
|
|
consoles[id]->cursorPosition = position;
|
|
if (activeConsole == id)
|
|
writeCursorPosition(position);
|
|
}
|
|
|
|
void console_refresh()
|
|
{
|
|
if (activeConsole > 0)
|
|
{
|
|
memcpyw((void*)CONSOLE_MEMORY, consoles[activeConsole]->buffer, consoles[activeConsole]->width * consoles[activeConsole]->height);
|
|
writeCursorPosition(consoles[activeConsole]->cursorPosition);
|
|
}
|
|
}
|
|
|
|
|
|
|