diff --git a/src/drivers/bus.h b/src/drivers/bus.h index 50dcbfb..8922ebf 100644 --- a/src/drivers/bus.h +++ b/src/drivers/bus.h @@ -19,6 +19,10 @@ struct _ukBus { ukBus * (*init)(void); + int (*read8)(ukBus * bus, ukBusAddress * address, uint8_t * value); + int (*read16)(ukBus * bus, ukBusAddress * address, uint16_t * value); + int (*read32)(ukBus * bus, ukBusAddress * address, uint32_t * value); + int (*write8)(ukBus * bus, ukBusAddress * address, uint8_t value); int (*write16)(ukBus * bus, ukBusAddress * address, uint16_t value); int (*write32)(ukBus * bus, ukBusAddress * address, uint32_t value); diff --git a/src/drivers/bus/ioport.S b/src/drivers/bus/ioport.S index d65735e..cc19176 100644 --- a/src/drivers/bus/ioport.S +++ b/src/drivers/bus/ioport.S @@ -7,6 +7,20 @@ #if defined(__amd64__) || defined(__i386__) /* functions */ .section .text +/* ioport_bus_read8 */ +.global ioport_bus_read8 +.type ioport_bus_read8, @function +ioport_bus_read8: + mov 0x8(%esp), %dx /* address */ + movl 0xc(%esp), %ecx /* return address */ + inb %dx, %al + mov %al, (%ecx) + + /* return 0 */ + mov $0x0, %eax + ret + + /* ioport_bus_write8 */ .global ioport_bus_write8 .type ioport_bus_write8, @function diff --git a/src/drivers/bus/ioport.c b/src/drivers/bus/ioport.c index 56cecbc..e70a2e8 100644 --- a/src/drivers/bus/ioport.c +++ b/src/drivers/bus/ioport.c @@ -15,6 +15,12 @@ typedef struct _ukBus IOPortBus; /* prototypes */ static IOPortBus * _ioport_bus_init(void); +extern int ioport_bus_read8(IOPortBus * bus, ukBusAddress * address, + uint8_t * value); +static int _ioport_bus_read16(IOPortBus * bus, ukBusAddress * address, + uint16_t * value); +static int _ioport_bus_read32(IOPortBus * bus, ukBusAddress * address, + uint32_t * value); extern int ioport_bus_write8(IOPortBus * bus, ukBusAddress * address, uint8_t value); static int _ioport_bus_write16(IOPortBus * bus, ukBusAddress * address, @@ -27,6 +33,9 @@ static int _ioport_bus_write32(IOPortBus * bus, ukBusAddress * address, static IOPortBus _ioport_bus = { _ioport_bus_init, + ioport_bus_read8, + _ioport_bus_read16, + _ioport_bus_read32, ioport_bus_write8, _ioport_bus_write16, _ioport_bus_write32, @@ -44,6 +53,30 @@ static IOPortBus * _ioport_bus_init(void) } +/* ioport_bus_read16 */ +static int _ioport_bus_read16(IOPortBus * bus, ukBusAddress * address, + uint16_t * value) +{ + (void) bus; + (void) address; + (void) value; + + return -ENOTSUP; +} + + +/* ioport_bus_read32 */ +static int _ioport_bus_read32(IOPortBus * bus, ukBusAddress * address, + uint32_t * value) +{ + (void) bus; + (void) address; + (void) value; + + return -ENOTSUP; +} + + /* ioport_bus_write16 */ static int _ioport_bus_write16(IOPortBus * bus, ukBusAddress * address, uint16_t value) diff --git a/src/drivers/bus/tty.c b/src/drivers/bus/tty.c index 65d5aeb..5ea2aee 100644 --- a/src/drivers/bus/tty.c +++ b/src/drivers/bus/tty.c @@ -16,6 +16,13 @@ typedef struct _ukBus TTYBus; /* prototypes */ static TTYBus * _tty_bus_init(void); +static int _tty_bus_read8(TTYBus * bus, ukBusAddress * address, + uint8_t * value); +static int _tty_bus_read16(TTYBus * bus, ukBusAddress * address, + uint16_t * value); +static int _tty_bus_read32(TTYBus * bus, ukBusAddress * address, + uint32_t * value); + static int _tty_bus_write8(TTYBus * bus, ukBusAddress * address, uint8_t value); static int _tty_bus_write16(TTYBus * bus, ukBusAddress * address, uint16_t value); @@ -23,6 +30,7 @@ static int _tty_bus_write32(TTYBus * bus, ukBusAddress * address, uint32_t value); /* XXX make this more elegant */ +extern int read(int fd, char const * buf, size_t len); extern int write(int fd, char const * buf, size_t len); @@ -30,6 +38,9 @@ extern int write(int fd, char const * buf, size_t len); static TTYBus _tty_bus = { _tty_bus_init, + _tty_bus_read8, + _tty_bus_read16, + _tty_bus_read32, _tty_bus_write8, _tty_bus_write16, _tty_bus_write32, @@ -47,6 +58,36 @@ static TTYBus * _tty_bus_init(void) } +/* tty_bus_read8 */ +static int _tty_bus_read8(TTYBus * bus, ukBusAddress * address, + uint8_t * value) +{ + (void) bus; + + return read((int)address, (char const *)value, sizeof(value)); +} + + +/* tty_bus_read16 */ +static int _tty_bus_read16(TTYBus * bus, ukBusAddress * address, + uint16_t * value) +{ + (void) bus; + + return read((int)address, (char const *)value, sizeof(value)); +} + + +/* tty_bus_read32 */ +static int _tty_bus_read32(TTYBus * bus, ukBusAddress * address, + uint32_t * value) +{ + (void) bus; + + return read((int)address, (char const *)value, sizeof(value)); +} + + /* tty_bus_write8 */ static int _tty_bus_write8(TTYBus * bus, ukBusAddress * address, uint8_t value) { diff --git a/src/drivers/console/vga.c b/src/drivers/console/vga.c index 2c1928c..7c31601 100644 --- a/src/drivers/console/vga.c +++ b/src/drivers/console/vga.c @@ -1,6 +1,8 @@ /* $Id$ */ /* Copyright (c) 2018 Pierre Pronchery */ /* This file is part of DeforaOS uKernel */ +/* TODO: + * - document the values used */ @@ -24,6 +26,8 @@ typedef struct _ukConsoleData uint8_t color_bg; uint8_t color_fg; + bool cursor; + uint8_t pos_x; uint8_t pos_y; @@ -56,6 +60,7 @@ static ukConsoleData _vga_console_data = (uint16_t *)VGA_ADDRESS_BASE, VGA_TEXT_COLOR_BLACK, VGA_TEXT_COLOR_WHITE, + false, 0, 0, NULL @@ -77,6 +82,9 @@ static ukConsole * _vga_console_init(ukBus * bus) { _vga_console_data.bus = bus; _vga_console_clear(&_vga_console); + /* reset the cursor */ + _vga_cursor_set(&_vga_console, !_vga_console_data.cursor, 0, 0); + _vga_cursor_set(&_vga_console, true, 0, 0); return &_vga_console; } @@ -119,7 +127,7 @@ static void _vga_console_print(VGAConsole * console, char const * str, _vga_scroll(console, 1); _vga_print(console, str[i], data->pos_y, data->pos_x++); } - _vga_cursor_set(console, true, data->pos_y, min(data->pos_x, + _vga_cursor_set(console, data->cursor, data->pos_y, min(data->pos_x, VGA_TEXT_COLUMNS)); } @@ -132,13 +140,37 @@ static void _vga_cursor_set(VGAConsole * console, bool enabled, { VGAConsoleData * data = console->data; uint16_t pos = row * VGA_TEXT_COLUMNS + column; + uint8_t u8; - if(row >= VGA_TEXT_ROWS || column >= VGA_TEXT_COLUMNS) + if(enabled == false) + { + /* disable the cursor if necessary */ + if(data->cursor == false) + return; + data->bus->write8(data->bus, (ukBusAddress *)0x3d4, 0x0a); + data->bus->read8(data->bus, (ukBusAddress *)0x3d5, &u8); + data->bus->write8(data->bus, (ukBusAddress *)0x3d5, u8 | 0x20); + } + else if(row >= VGA_TEXT_ROWS || column >= VGA_TEXT_COLUMNS) return; - data->bus->write8(data->bus, (ukBusAddress *)0x3d4, 0x0f); - data->bus->write8(data->bus, (ukBusAddress *)0x3d5, pos & 0xff); - data->bus->write8(data->bus, (ukBusAddress *)0x3d4, 0x0e); - data->bus->write8(data->bus, (ukBusAddress *)0x3d5, pos >> 8); + else + { + /* position the cursor */ + data->bus->write8(data->bus, (ukBusAddress *)0x3d4, 0x0f); + data->bus->write8(data->bus, (ukBusAddress *)0x3d5, pos & 0xff); + data->bus->write8(data->bus, (ukBusAddress *)0x3d4, 0x0e); + data->bus->write8(data->bus, (ukBusAddress *)0x3d5, pos >> 8); + /* enable the cursor if necessary */ + if(data->cursor == false) + { + data->bus->write8(data->bus, (ukBusAddress *)0x3d4, + 0x0a); + data->bus->read8(data->bus, (ukBusAddress *)0x3d5, &u8); + data->bus->write8(data->bus, (ukBusAddress *)0x3d5, + u8 & ~0x20); + } + } + data->cursor = enabled; } diff --git a/tools/arch/i386/start.S b/tools/arch/i386/start.S index 0841cee..fafca85 100644 --- a/tools/arch/i386/start.S +++ b/tools/arch/i386/start.S @@ -22,6 +22,14 @@ _exit: jmp _syscall +/* read */ +.global read +.type read, @function +read: + mov $0x3, %eax + jmp _syscall + + /* start */ _start: /* reset the stack */