Espresso 0.0.2a

This commit is contained in:
2025-10-20 21:57:30 -05:00
parent 102d517097
commit ff6cba1164
59 changed files with 29272 additions and 773 deletions

View File

@ -13,10 +13,10 @@
elf_executable_t* load_elf32(void* elf_data)
{
Elf32_Ehdr* ehdr = (Elf32_Ehdr*)elf_data;
/*Elf32_Ehdr* ehdr = (Elf32_Ehdr*)elf_data;*/
/* Check ELF magic */
if (memcmp(ehdr->e_ident, (uint8_t*)("\x7F""ELF"), 4) != 0)
/*if (memcmp(ehdr->e_ident, (uint8_t*)("\x7F""ELF"), 4) != 0)
{
printf("Invalid ELF file\n");
return NULL;
@ -58,6 +58,8 @@ elf_executable_t* load_elf32(void* elf_data)
elf_executable_t* result = malloc(sizeof(elf_executable_t));
result->entry_point = (void*)(uintptr_t)ehdr->e_entry;
return result;
return result;*/
return NULL;
}

117
drivers/fs/ssfs.c Normal file
View File

@ -0,0 +1,117 @@
#include <types.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <drivers/ide.h>
#include <fs/ssfs.h>
#define SSFS_START_LBA 16
#define SSFS_FILE_HEADER_SIZE_BYTES 32
int ssfs_read_file(const char* name, void* buffer, int size)
{
if (strlen(name) > 15)
{
return -1;
}
uint8_t header_buf[512];
int r = read_sector(16, header_buf);
if (r != 0)
{
return -2;
}
ssfs_file_header_t f;
memcpy(&f, header_buf, sizeof(f));
if (strncmp(f.filename, name, 15) != 0)
{
return -3;
}
/* Clamp read size to actual file size */
if (size > (int)f.num_bytes)
size = (int)f.num_bytes;
int total_read = 0;
int sector_count = div_round_up(size, 512);
uint8_t sector_data[512];
for (int k = 0; k < sector_count; k++)
{
r = read_sector(f.start_sector + k, sector_data);
if (r != 0)
{
return -4; /* I/O error */
}
int to_copy = size - total_read;
if (to_copy > 512)
{
to_copy = 512;
}
memcpy((uint8_t*)buffer + total_read, sector_data, to_copy);
total_read += to_copy;
}
return 0;
}
/* size is number of bytes */
int ssfs_write_file(const char* name, void* data, int size)
{
ssfs_file_header_t* f = (ssfs_file_header_t*) malloc(sizeof(ssfs_file_header_t));
memset(f, 0, sizeof(ssfs_file_header_t));
if (strlen(name) > 15)
{
return -1;
}
strcpy(f->filename, name);
f->num_sectors = 0;
int sector_count = div_round_up(size, 512);
uint8_t* buffer = (uint8_t*) malloc(sector_count * 512);
memset(buffer, 0, sector_count * 512);
memcpy(buffer, data, (size_t) size);
int r = 0;
f->start_sector = 32;
for (int k = 0; k < sector_count; k++)
{
r = write_sector(f->start_sector + k, buffer + (k * 512));
if (r != 0)
{
break;
}
}
f->num_sectors = sector_count;
f->num_bytes = (uint32_t) size;
uint8_t header_buf[512];
memset(header_buf, 0, 512);
memcpy(header_buf, f, sizeof(*f));
write_sector(16, header_buf);
free(buffer);
free(f);
return 0;
}

View File

@ -63,10 +63,16 @@ int32_t ide_identify(uint8_t drive, uint16_t* buffer)
return 0;
}
void ide_initialize(void) {
void ide_initialize(void)
{
#ifdef _DEBUG
printf("[ IDE ] Initializing IDE system...\n");
#endif
outb(ATA_PRIMARY_CTRL, 0x02); /* Disable IRQs from IDE disk controllers TODO: should probably use IRQs soon */
uint16_t identify_buf[256];
volatile uint16_t identify_buf[256];
if (ide_identify(0, identify_buf) == 0)
{
char model[41];
@ -78,9 +84,18 @@ void ide_initialize(void) {
model[40] = 0;
printf("Disk model: %s\n", model);
}
else
{
printf("ide_initialize(): ide_identify(0, identify_buf) did NOT return 0!\n");
}
#ifdef _DEBUG
printf("[ IDE ] IDE initialized\n");
#endif
}
int32_t ide_read48(uint8_t drive, uint64_t lba, uint8_t sector_count, void* buffer) {
int32_t ide_read48(uint8_t drive, uint64_t lba, uint8_t sector_count, void* buffer)
{
if (sector_count == 0)
{
return -1;

View File

@ -1,13 +1,13 @@
#include <stdio.h>
#include <drivers/ps2_keyboard.h>
#include <drivers/pit.h>
#include <port_io.h>
#include <drivers/irq.h>
#define NUM_IRQS 0x90
irq_func_t func_list[NUM_IRQS];
irq_func_t aux_func_list[NUM_IRQS];
@ -15,9 +15,10 @@ static volatile uint32_t num_irqs_missed = 0;
void irq_init(void)
{
memset(func_list, 0x0, NUM_IRQS);
memset(aux_func_list, 0x0, NUM_IRQS);
for (int i = 0; i < NUM_IRQS; i++)
{
func_list[i] = 0x0;
}
set_irq_handler(0, (irq_func_t*)pit_handler);
set_irq_handler(1, (irq_func_t*)keyboard_handler);
}
@ -29,10 +30,7 @@ void irq_handler(uint8_t irq_number)
if (func_list[irq_number])
{
func_list[irq_number]();
}
else if (aux_func_list[irq_number])
{
aux_func_list[irq_number]();
outb(0x20, 0x20); /* Acknowledge the IRQ to PIC */
}
else
{
@ -48,21 +46,3 @@ void set_irq_handler(uint32_t num, irq_func_t* handler)
func_list[num] = (irq_func_t)handler;
}
}
void add_irq_handler(uint32_t num, irq_func_t* handler)
{
if (num < NUM_IRQS)
{
if (func_list[num] != 0x0)
{
if (aux_func_list[num] == 0x0)
{
aux_func_list[num] = (irq_func_t)handler;
}
return;
}
func_list[num] = (irq_func_t)handler;
}
}

View File

@ -58,6 +58,18 @@ void pci_config_read_block(uint8_t bus, uint8_t device, uint8_t function, uint8_
}
}
void pci_init(void)
{
#ifdef _DEBUG
printf("[ PCI ] Initializing PCI...\n");
#endif
pci_enumerate();
#ifdef _DEBUG
printf("[ PCI ] PCI initialized\n");
#endif
}
void pci_enumerate(void)
{
@ -77,7 +89,7 @@ void pci_enumerate(void)
if (pre_header.class_code == 0xB)
{
printf("Processor found on PCI bus, what?!?!\n");
printf("Processor found on PCI bus, what?!?!\n"); /* For some stupid reason, processors can be on the PCI bus? */
continue;
}
@ -90,6 +102,9 @@ void pci_enumerate(void)
{
/*configure_ahci_controller(hdr);*/
}
/*printf("PCI device: cc: %x sc: %x pi: %x b: %x d: %x f: %x int: %x\n", hdr.class_code, hdr.subclass, hdr.prog_if, bus, device, function, (uint32_t) hdr.interrupt_line);*/
}
}
}

View File

@ -14,7 +14,11 @@ volatile uint64_t pit_ticks = 0;
bool pit_initialized = false;
void pit_init(void)
{
{
#ifdef _DEBUG
printf("[ PIT ] Initializing the PIT...\n");
#endif
uint16_t divisor = (uint16_t)1193;
/* Send command byte */
@ -25,6 +29,10 @@ void pit_init(void)
outb(PIT_CHANNEL0, (uint8_t)((divisor >> 8) & 0xFF)); /* High byte */
pit_initialized = true;
#ifdef _DEBUG
printf("[ PIT ] PIT Initialized\n");
#endif
}
void pit_handler(void)

View File

@ -2,7 +2,7 @@
#include <port_io.h>
#include <tty.h>
#include <stdlib.h>
#include <ksymtab.h>
#include <drivers/ps2_keyboard.h>
@ -29,6 +29,8 @@
#define KEYBOARD_IRQ 1
#define RETURN_STI() do { _sti_asm(); return; } while (0)
bool ps2keyboard_initialized = false;
/* State for shift key */
@ -41,14 +43,25 @@ static bool capslock_pressed = false;
static bool extended = false;
static bool is_new_char = false;
static bool is_new_key = false;
static bool is_new_key = false;
static bool gets_called = false;
static volatile bool gets_finished = false;
volatile unsigned char current_char;
volatile char* current_string = NULL;
volatile char* current_string = NULL;
volatile char* gets_string = NULL;
volatile int32_t current_length = 0;
volatile int32_t capacity = 0;
volatile int32_t gets_length = 0;
volatile int32_t capacity = 0;
volatile int32_t gets_capacity = 0;
volatile uint16_t current_key;
volatile ps2_hook_t* hooks = NULL;
volatile int hook_count = 0;
extern void _cli_asm(void);
extern void _sti_asm(void);
static const char scancode_map[128] = {
0, 27, '1','2','3','4','5','6','7','8','9','0','-','=','\b', /* Backspace */
@ -69,15 +82,134 @@ static const char scancode_map[128] = {
void keyboard_init(void)
{
#ifdef _DEBUG
printf("[ PS/2 KBD ] Initializing the PS/2 keyboard...\n");
#endif
outb(0x64, 0xAE); /* Enable keyboard interface (often optional, but here for safety) */
hooks = (ps2_hook_t*) malloc(sizeof(ps2_hook_t) * hook_count);
ps2keyboard_initialized = true;
#ifdef _DEBUG
printf("[ PS/2 KBD ] PS/2 Keyboard initialized\n");
#endif
}
bool setup_hook(ps2_hook_t func)
{
_cli_asm();
ps2_hook_t* copy = malloc(sizeof(ps2_hook_t) * hook_count);
if (hook_count > 0 && copy == NULL)
{
return false;
}
if (hook_count > 0)
{
memcpy(copy, hooks, sizeof(ps2_hook_t) * hook_count);
}
free((void*) hooks);
hooks = malloc(sizeof(ps2_hook_t) * (hook_count + 1));
if (hooks == NULL)
{
return false;
}
if (hook_count > 0)
{
memcpy((void*) hooks, copy, sizeof(ps2_hook_t) * hook_count);
}
free(copy);
hooks[hook_count] = func;
hook_count++;
_sti_asm();
return true;
}
bool remove_hook(ps2_hook_t func)
{
_cli_asm();
int index = -1;
for (int i = 0; i < hook_count; i++)
{
if (hooks[i] == func)
{
index = i;
break;
}
}
if (index == -1)
{
return false;
}
for (int i = index; i < hook_count - 1; i++)
{
hooks[i] = hooks[i + 1];
}
hook_count--;
if (hook_count == 0)
{
free((void*) hooks);
hooks = NULL;
return false;
}
ps2_hook_t* smaller = malloc(sizeof(ps2_hook_t) * hook_count);
if (smaller == NULL)
{
return false;
}
memcpy(smaller, (void*) hooks, sizeof(ps2_hook_t) * hook_count);
free((void*) hooks);
hooks = smaller;
_sti_asm();
return true;
}
void call_hooks(char c)
{
_cli_asm();
if (hook_count == 0)
{
return;
}
for (int i = 0; i < hook_count; i++)
{
hooks[i](c);
}
_sti_asm();
}
char get_char(void)
{
/*
ASCII code 5 (Enquiry) is/was used in legacy systems meant for requesting a response from a remote terminal or device.
For example, one system might send ENQ (ASCII 5), and the receiver could reply with ACK (ASCII 6) to indicate its ready or still online.
For example, one system might send ENQ (ASCII 5), and the receiver could reply with ACK (ASCII 6) to indicate it's ready or still online.
In modern computing, ENQ is largely obsolete:
@ -87,16 +219,13 @@ char get_char(void)
- It may still appear in legacy systems, embedded devices, or proprietary serial protocols, but that's niche.
*/
char temp = 5;
if (is_new_char)
if (!is_new_char)
{
temp = current_char;
return 5;
}
is_new_char = false;
return temp;
return current_char;
}
uint16_t get_key(void)
@ -122,39 +251,184 @@ char* get_string(void)
return current_string;
}
static void append_char(char c)
char* kbd_gets(void)
{
gets_called = true;
gets_finished = false;
while (gets_finished != true)
{
sleep(1);
}
char* result = strdup(gets_string); /* Could be NULL, that is checked below */
free(gets_string);
gets_string = NULL;
gets_capacity = 0;
gets_length = 0;
gets_called = false;
return result == NULL ? "" : result;
}
void gets_append_char(unsigned char c)
{
_cli_asm();
if (!gets_string && gets_capacity > 0)
{
printf("[keyboard] ERROR: gets_string is NULL but capacity > 0!\n");
RETURN_STI();
}
if (c == KEY_ARROW_UP || c == KEY_ARROW_DOWN || c == KEY_ARROW_RIGHT || c == KEY_ARROW_LEFT)
{
gets_string[1] = '\0';
char tc = '\0';
switch (c)
{
case KEY_ARROW_UP:
tc = KEY_UP;
break;
case KEY_ARROW_DOWN:
tc = KEY_DOWN;
break;
case KEY_ARROW_RIGHT:
tc = KEY_RIGHT;
break;
case KEY_ARROW_LEFT:
tc = KEY_LEFT;
break;
default:
tc = '\0';
break;
}
gets_string[0] = tc;
gets_finished = true;
RETURN_STI();
}
else if (c == '\n')
{
/* The returned string must/will not have newlines in it, so we return here after setting gets_finished to 'true'. */
gets_finished = true;
printf("\n");
RETURN_STI();
}
else if (c == 27) /* ASCII escape, here it's used to cancel input. */
{
gets_finished = true;
gets_string[0] = '\0';
RETURN_STI();
}
else if (c == '\b')
{
if (gets_length < 1)
{
RETURN_STI();
}
gets_length--;
gets_string[gets_length] = '\0';
printf("\b \b");
RETURN_STI();
}
if ((gets_length) >= gets_capacity)
{
int new_capacity = (gets_capacity == 0) ? 64 : gets_capacity * 2;
char* new_str = (char*) malloc(new_capacity);
if (!new_str)
{
RETURN_STI();
}
if (gets_string)
{
for (int i = 0; i < gets_length; i++)
{
new_str[i] = gets_string[i];
}
new_str[gets_length] = '\0';
free(gets_string);
}
gets_string = new_str;
gets_capacity = new_capacity;
}
if (!gets_string)
{
RETURN_STI();
}
gets_string[gets_length] = (char) c;
gets_length++;
gets_string[gets_length] = '\0';
printf("%c", c);
RETURN_STI();
}
void append_char(char c)
{
_cli_asm();
if (current_length + 1 >= capacity)
{
/* Need more space (+1 for the null zero) */
int new_capacity = (capacity == 0) ? 16 : capacity * 2;
char* new_str = (char*)malloc(new_capacity);
if (!new_str) {
char* new_str = (char*) malloc(new_capacity);
if (!new_str)
{
printf("[keyboard] ERROR: malloc failed for new input buffer\n");
return;
}
if (current_string)
{
memcpy(new_str, current_string, current_length);
free(current_string);
}
if (!current_string)
{
return;
}
current_string = new_str;
capacity = new_capacity;
}
if (!current_string)
{
return;
}
current_string[current_length] = c;
current_length++;
current_string[current_length] = '\0'; /* Maintain null terminator */
current_string[current_length] = '\0';
_sti_asm();
}
static void free_current_string(void)
void free_current_string(void)
{
if (current_string)
{
@ -198,8 +472,8 @@ void keyboard_handler(void)
}
else
{
uint16_t c = (uint16_t)scancode_map[scancode];
if ((shift_pressed ^ capslock_pressed) && ((char)c >= 'a') && ((char)c <= 'z'))
uint16_t c = (uint16_t) scancode_map[scancode];
if ((shift_pressed ^ capslock_pressed) && ((char) c >= 'a') && ((char) c <= 'z'))
{
c -= 32; /* Convert to uppercase */
}
@ -208,11 +482,10 @@ void keyboard_handler(void)
c = (uint16_t) terminal_get_shifted((unsigned char) c);
}
/*if (scancode == 0x1C) {
printf("\n");
return;
}*/
if (hook_count > 0)
{
call_hooks(c);
}
if (extended)
{
@ -235,6 +508,13 @@ void keyboard_handler(void)
break;
}
if (gets_called)
{
gets_append_char(c);
return;
}
current_key = c;
is_new_key = true;
@ -242,20 +522,35 @@ void keyboard_handler(void)
return;
}
if (gets_called)
{
gets_append_char(c);
return;
}
if (c)
{
if (c != '\n')
{
append_char(c);
}
current_char = c;
is_new_char = true;
if (c == '\n')
{
/*append_char(c);
current_char = c;
is_new_char = true;*/
free_current_string();
}
append_char(c);
}
}
}

88
drivers/serio.c Normal file
View File

@ -0,0 +1,88 @@
/*
Driver for serial output.
Mostly useful for debug output because QEMU allows the redirection of serial output to either stdio or a file on the host computer.
*/
#include <types.h>
#include <port_io.h>
#include <string.h>
#include <drivers/serio.h>
#define COM1_IO_ADDR 0x3F8
#define COM2_IO_ADDR 0x2F8
#define COM1_IRQ 0x4
#define COM2_IRQ 0x3
#define COM1_LCR (COM1_IO_ADDR + 3)
#define COM2_LCR (COM2_IO_ADDR + 3)
#define BAUD 57600
#define DIVISOR 2
int serial_init(void)
{
/* The following is taken from https://wiki.osdev.org/Serial_Ports */
outb(COM1_IO_ADDR + 1, 0x00); // Disable all interrupts
outb(COM1_IO_ADDR + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(COM1_IO_ADDR + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(COM1_IO_ADDR + 1, 0x00); // (hi byte)
outb(COM1_IO_ADDR + 3, 0x03); // 8 bits, no parity, one stop bit
outb(COM1_IO_ADDR + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(COM1_IO_ADDR + 4, 0x0B); // IRQs enabled, RTS/DSR set
outb(COM1_IO_ADDR + 4, 0x1E); // Set in loopback mode, test the serial chip
outb(COM1_IO_ADDR + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
// Check if serial is faulty (i.e: not same byte as sent)
if(inb(COM1_IO_ADDR + 0) != 0xAE)
{
return 1;
}
// If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
outb(COM1_IO_ADDR + 4, 0x0F);
return 0;
}
static int is_transmit_empty(void)
{
return inb(COM1_IO_ADDR + 5) & 0x20;
}
static int serial_received(void)
{
return inb(COM1_IO_ADDR + 5) & 1;
}
void serial_write(char a)
{
while (is_transmit_empty() == 0);
outb(COM1_IO_ADDR, a);
}
void serial_puts(const char* s)
{
for (int i = 0; i < (int) strlen(s); i++)
{
serial_write(s[i]);
}
}
char serial_read(void)
{
while (serial_received() == 0);
return inb(COM1_IO_ADDR);
}
bool use_serial(void)
{
return true;
}

View File

@ -1,16 +1,21 @@
#include <string.h>
#include <vga/vga.h>
#include <stdio.h>
#include <port_io.h>
#include <tty.h>
static size_t terminal_row;
static size_t terminal_column;
static uint8_t terminal_color;
static uint16_t* terminal_buffer;
size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;
void terminal_initialize(void)
{
terminal_initializec(0x00);
terminal_update_cursor();
}
void terminal_initializec(uint8_t color)
@ -22,11 +27,13 @@ void terminal_initializec(uint8_t color)
{
terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
}
else {
else
{
terminal_color = color;
}
terminal_buffer = VGA_MEMORY;
for (size_t y = 0; y < VGA_HEIGHT; y++)
{
for (size_t x = 0; x < VGA_WIDTH; x++)
@ -55,6 +62,7 @@ void terminal_putentryat(unsigned char c, uint8_t color, size_t x, size_t y)
void terminal_putchar(const char c)
{
unsigned char uc = c;
if (uc == '\n')
@ -62,9 +70,21 @@ void terminal_putchar(const char c)
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
{
terminal_scroll();
terminal_row = VGA_HEIGHT - 1;
if (1)
{
terminal_scroll();
terminal_row = VGA_HEIGHT - 1;
}
else
{
terminal_clear();
terminal_row = 0;
}
}
terminal_update_cursor();
return;
}
else if (uc == '\t')
@ -76,28 +96,35 @@ void terminal_putchar(const char c)
terminal_putchar('\n');
}
terminal_update_cursor();
return;
}
else if (uc == '\b')
{
if (terminal_column == 0)
{
terminal_row -= 1;
if (terminal_row == (size_t)-1)
if (terminal_row > 0)
{
terminal_row = 0;
terminal_row--;
terminal_column = VGA_WIDTH - 1;
}
else
{
terminal_update_cursor(); /* For good measure */
terminal_column = VGA_WIDTH;
terminal_putentryat(' ', terminal_getcolor(), (size_t)terminal_column, (size_t)terminal_row);
return;
}
}
else
{
terminal_putentryat(' ', terminal_getcolor(), (size_t)--terminal_column, (size_t)terminal_row);
terminal_column--;
}
terminal_putentryat(' ', terminal_color, terminal_column, terminal_row);
terminal_update_cursor();
return;
}
@ -110,9 +137,10 @@ void terminal_putchar(const char c)
if (++terminal_row == VGA_HEIGHT)
{
terminal_scroll();
terminal_row = VGA_HEIGHT - 1;
}
}
terminal_update_cursor();
}
void terminal_write(const char* data, size_t size)
@ -157,7 +185,7 @@ void terminal_clear(void)
void terminal_clearl(size_t num_lines)
{
if (num_lines == (size_t)-1)
if (num_lines == (size_t) -1)
{
terminal_initializec(terminal_getcolor());
}
@ -182,20 +210,18 @@ void terminal_clearl(size_t num_lines)
void terminal_scroll(void)
{
for (size_t y = 1; y < VGA_HEIGHT; y++)
memmove(
terminal_buffer,
terminal_buffer + VGA_WIDTH,
sizeof(uint16_t) * VGA_WIDTH * (VGA_HEIGHT/* + 1*/)
);
terminal_row = VGA_HEIGHT - 1;
for (int32_t k = 0; k < (int32_t)VGA_WIDTH; k++)
{
for (size_t x = 0; x < VGA_WIDTH; x++)
{
const size_t src_index = y * VGA_WIDTH + x;
const size_t dst_index = (y - 1) * VGA_WIDTH + x;
terminal_buffer[dst_index] = terminal_buffer[src_index];
}
}
for (size_t x = 0; x < VGA_WIDTH; x++)
{
const size_t index = (VGA_HEIGHT - 1) * VGA_WIDTH + x;
terminal_buffer[index] = (terminal_color << 8) | ' ';
terminal_putentryat((unsigned char)' ', terminal_getcolor(), (size_t)terminal_row, (size_t)k);
}
}
@ -208,7 +234,7 @@ unsigned char terminal_get_shifted(unsigned char uc)
unsigned char syms1[] = { ',', '.', '/', ';', '\'', '[', ']', '`', '-', '=', '\\', '\0' };
unsigned char syms2[] = { '<', '>', '?', ':', '\"', '{', '}', '~', '_', '+', '|', '\0' };
for (int32_t i = 0; i < (int32_t)(strlen((char*)lowerc)); ++i)
for (int32_t i = 0; i < (int32_t) (strlen((char*)lowerc)); ++i)
{
if (uc == lowerc[i])
{
@ -220,7 +246,7 @@ unsigned char terminal_get_shifted(unsigned char uc)
}
}
for (int32_t i = 0; i < (int32_t)(strlen((char*)nums)); ++i)
for (int32_t i = 0; i < (int32_t) (strlen((char*)nums)); ++i)
{
if (uc == nums[i])
{
@ -232,7 +258,7 @@ unsigned char terminal_get_shifted(unsigned char uc)
}
}
for (int32_t i = 0; i < (int32_t)(strlen((char*)syms1)); ++i)
for (int32_t i = 0; i < (int32_t) (strlen((char*) syms1)); ++i)
{
if (uc == syms1[i])
{
@ -251,7 +277,20 @@ void terminal_set_cursor(uint16_t row, uint16_t column)
{
if (row < VGA_HEIGHT && column < VGA_WIDTH)
{
terminal_row = (size_t)row;
terminal_column = (size_t)column;
terminal_row = (size_t) row;
terminal_column = (size_t) column;
}
terminal_update_cursor();
}
void terminal_update_cursor(void)
{
uint16_t pos = terminal_row * VGA_WIDTH + terminal_column;
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t) (pos & 0xFF));
outb(0x3D4, 0x0E);
outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF));
}