Espresso 0.0.1d

This commit is contained in:
2025-07-03 20:30:21 -05:00
parent 8648637b51
commit 078ca8169b
14 changed files with 337 additions and 28 deletions

View File

@ -4,26 +4,63 @@
#include <drivers/irq.h> #include <drivers/irq.h>
irq_func_t func_list[64]; #define NUM_IRQS 0x90
irq_func_t func_list[NUM_IRQS];
irq_func_t aux_func_list[NUM_IRQS];
static volatile uint32_t num_irqs_missed = 0;
void irq_init(void) void irq_init(void)
{ {
memset(func_list, 0x0, NUM_IRQS);
memset(aux_func_list, 0x0, NUM_IRQS);
set_irq_handler(0, (irq_func_t*)pit_handler); set_irq_handler(0, (irq_func_t*)pit_handler);
set_irq_handler(1, (irq_func_t*)keyboard_handler); set_irq_handler(1, (irq_func_t*)keyboard_handler);
} }
void irq_handler(uint8_t irq_number) void irq_handler(uint8_t irq_number)
{ {
if (irq_number < 64 && func_list[irq_number]) if (irq_number < NUM_IRQS)
{
if (func_list[irq_number])
{ {
func_list[irq_number](); func_list[irq_number]();
} }
else if (aux_func_list[irq_number])
{
aux_func_list[irq_number]();
}
else
{
num_irqs_missed++;
}
}
} }
void set_irq_handler(uint32_t num, irq_func_t* handler) void set_irq_handler(uint32_t num, irq_func_t* handler)
{ {
if (num < 64) if (num < NUM_IRQS)
{ {
func_list[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

@ -36,15 +36,22 @@ static bool shift_pressed = false;
/* State for caps-lock key */ /* State for caps-lock key */
static bool capslock_pressed = false; static bool capslock_pressed = false;
volatile char current_char; /* Used for arrow keys among others */
static bool extended = false;
static bool is_new_char = false;
static bool is_new_key = false;
volatile unsigned char current_char;
volatile char* current_string = NULL; volatile char* current_string = NULL;
volatile int32_t current_length = 0; volatile int32_t current_length = 0;
volatile int32_t capacity = 0; volatile int32_t capacity = 0;
volatile uint16_t current_key;
static const char scancode_map[128] = { static const char scancode_map[128] = {
0, 27, '1','2','3','4','5','6','7','8','9','0','-','=','\b', /* Backspace */ 0, 27, '1','2','3','4','5','6','7','8','9','0','-','=','\b', /* Backspace */
'\t', // Tab '\t', /* Tab */
'q','w','e','r','t','y','u','i','o','p','[',']','\n', /* Enter */ 'q','w','e','r','t','y','u','i','o','p','[',']','\n', /* Enter */
0, /* Control */ 0, /* Control */
'a','s','d','f','g','h','j','k','l',';','\'','`', 'a','s','d','f','g','h','j','k','l',';','\'','`',
@ -67,7 +74,46 @@ void keyboard_init(void)
char get_char(void) char get_char(void)
{ {
return current_char; /*
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.
In modern computing, ENQ is largely obsolete:
- Terminal emulators, shells, operating systems, and network protocols generally do not use ENQ.
- It's not used in text files, programming, or standard communications.
- It may still appear in legacy systems, embedded devices, or proprietary serial protocols, but that's niche.
*/
char temp = 5;
if (is_new_char)
{
temp = current_char;
}
is_new_char = false;
return temp;
}
uint16_t get_key(void)
{
uint16_t temp = 0xFFFA;
if (is_new_key)
{
temp = current_key;
is_new_key = false;
}
else if (is_new_char)
{
temp = (uint16_t)current_char;
is_new_char = false;
}
return temp;
} }
char* get_string(void) char* get_string(void)
@ -118,7 +164,8 @@ static void free_current_string(void)
} }
} }
void keyboard_handler(void) { void keyboard_handler(void)
{
uint8_t scancode = inb(PS2_DATA_PORT); uint8_t scancode = inb(PS2_DATA_PORT);
/* Handle shift press/release */ /* Handle shift press/release */
@ -137,41 +184,76 @@ void keyboard_handler(void) {
capslock_pressed = !capslock_pressed; capslock_pressed = !capslock_pressed;
return; return;
} }
else if (scancode == 0xE0)
{
extended = true;
return;
}
if (scancode & 0x80) if (scancode & 0x80)
{ {
/* Key release event, ignore for now */ extended = false;
} else }
else
{
uint16_t c = (uint16_t)scancode_map[scancode];
if ((shift_pressed ^ capslock_pressed) && ((char)c >= 'a') && ((char)c <= 'z'))
{ {
char c = scancode_map[scancode];
if ((shift_pressed ^ capslock_pressed) && c >= 'a' && c <= 'z') {
c -= 32; /* Convert to uppercase */ c -= 32; /* Convert to uppercase */
} }
else if (shift_pressed) else if (shift_pressed)
{ {
c = (char) terminal_get_shifted((unsigned char) c); c = (uint16_t) terminal_get_shifted((unsigned char) c);
} }
if (scancode == 0x1C) { /*if (scancode == 0x1C) {
printf("\n"); printf("\n");
return; return;
}*/
if (extended)
{
switch (scancode)
{
case 0x48:
c = KEY_ARROW_UP;
break;
case 0x50:
c = KEY_ARROW_DOWN;
break;
case 0x4B:
c = KEY_ARROW_LEFT;
break;
case 0x4D:
c = KEY_ARROW_RIGHT;
break;
default:
c = KEY_NONE;
break;
} }
current_key = c;
is_new_key = true;
extended = false;
return;
}
if (c) if (c)
{ {
current_char = c; current_char = c;
is_new_char = true;
if (c == '\n') if (c == '\n')
{ {
free_current_string(); free_current_string();
} }
else
{
append_char(c); append_char(c);
printf("%c", c);
}
} }
} }
} }

View File

@ -247,3 +247,11 @@ unsigned char terminal_get_shifted(unsigned char uc)
return '\0'; return '\0';
} }
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;
}
}

View File

@ -0,0 +1,8 @@
#ifndef _MINER_H
#define _MINER_H
#include <types.h>
void miner_main(void);
#endif

View File

@ -6,7 +6,10 @@
typedef void (*irq_func_t)(void); typedef void (*irq_func_t)(void);
void irq_init(void); void irq_init(void);
void irq_handler(uint8_t irq_number); void irq_handler(uint8_t irq_number);
void set_irq_handler(uint32_t num, irq_func_t* handler); void set_irq_handler(uint32_t num, irq_func_t* handler);
void add_irq_handler(uint32_t num, irq_func_t* handler);
#endif #endif

View File

@ -3,10 +3,20 @@
#include <types.h> #include <types.h>
typedef enum {
KEY_NONE = 0,
KEY_ARROW_UP = 0xAA0,
KEY_ARROW_DOWN,
KEY_ARROW_LEFT,
KEY_ARROW_RIGHT,
/* Note: add more special keys here */
} special_key;
void keyboard_init(void); void keyboard_init(void);
void keyboard_handler(void); void keyboard_handler(void);
char get_char(void); char get_char(void);
uint16_t get_key(void);
char* get_string(void); char* get_string(void);
#endif #endif

6
include/ksymtab.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _KSYMTAB_H
#define _KSYMTAB_H
#include <types.h>
#endif

View File

@ -24,8 +24,8 @@ char lower(char c);
char toupper(char c); char toupper(char c);
char lower(char c); char lower(char c);
void *memset(void *dst, char c, uint32_t n); void* memset(void *dst, char c, uint32_t n);
void *memcpy(void *dst, const void *src, uint32_t n); void* memcpy(void *dst, const void *src, uint32_t n);
int32_t memcmp(const void *s1, const void *s2, size_t n); int32_t memcmp(const void *s1, const void *s2, size_t n);
void* memclr(void* m_start, size_t m_count); void* memclr(void* m_start, size_t m_count);

View File

@ -25,4 +25,6 @@ void terminal_scroll(void);
unsigned char terminal_get_shifted(unsigned char uc); unsigned char terminal_get_shifted(unsigned char uc);
void terminal_set_cursor(uint16_t row, uint16_t column);
#endif #endif

View File

@ -5,4 +5,11 @@
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
typedef unsigned char uchar;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
#endif #endif

View File

@ -37,6 +37,8 @@
#include <kernel/intro.h> #include <kernel/intro.h>
#include <builtin_games/miner.h>
#define DEBUG #define DEBUG
@ -44,12 +46,12 @@ extern void _hang_asm(void);
extern void _sti_asm(void); extern void _sti_asm(void);
void kernel_main(multiboot_info_t* mbd, unsigned int magic) void kernel_main(multiboot_info_t* mbd, uint32_t magic)
{ {
/* --- BEGIN INITIALIZATION SECTION --- */ /* --- BEGIN INITIALIZATION SECTION --- */
const char* espresso_kernel_version = "0.0.0f"; const char* espresso_kernel_version = "0.0.1d";
/* We need to initialize the terminal so that any error/debugging messages show. */ /* We need to initialize the terminal so that any error/debugging messages show. */
terminal_initialize(); terminal_initialize();
@ -78,7 +80,7 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
idt_init(); idt_init();
_sti_asm(); _sti_asm();
irq_init(); /* MUST be done after pci_remap() and idt_init() */ irq_init(); /* MUST be done after pic_remap() and idt_init() */
terminal_setcolor(VGA_COLOR_GREEN); terminal_setcolor(VGA_COLOR_GREEN);
@ -132,7 +134,6 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
printd("PCI initialized\n"); printd("PCI initialized\n");
/* --- END INITIALIZATION SECTION --- */ /* --- END INITIALIZATION SECTION --- */
terminal_setcolor(VGA_COLOR_LIGHT_GREEN); terminal_setcolor(VGA_COLOR_LIGHT_GREEN);
@ -141,14 +142,14 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
/*pit_sleep(4000); /*pit_sleep(4000);
begin_anim(espresso_kernel_version);*/ begin_anim(espresso_kernel_version);*/
printf("Guten tag and welcome to Espresso\n");
/*printf("here\n"); /*printf("here\n");
printf("%i\n", sfs_init(false)); printf("%i\n", sfs_init(false));
printf("here\n");*/ printf("here\n");*/
printf("Guten tag and welcome to Espresso\n");
while (true) while (true)
{ {

0
ksymtab.s Normal file
View File

76
lib/builtin_games/miner.c Normal file
View File

@ -0,0 +1,76 @@
#include <tty.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <drivers/ps2_keyboard.h>
#include <builtin_games/miner.h>
#define PLAYER '@'
#define SHOP '$'
#define STONE '#'
#define IRON ';'
#define COAL ':'
#define COPPER '^'
#define GOLD '%'
#define RUBY '*'
#define DIAMOND '~'
#define PLATINUM '&'
#define NOTHING ' '
/*
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
*/
void miner_main(void)
{
terminal_clear();
printf("\n\tMiner\n\t\tMine ores to sell for money and upgrade your drone\n\n\n\t\t\tHIT ENTER TO CONTINUE, TAB TO EXIT\n");
char b = get_char();
while (b != '\n' && b != '\t')
{
sleep(10);
b = get_char();
}
if (b == '\t')
{
return;
}
uint16_t c = 0x0;
terminal_clear();
while (true)
{
sleep(10);
c = get_key();
if (c == 0xFFFA || c == 0x0)
{
continue;
}
break;
}
b = getchar();
while (b == 0x5)
{
sleep(10);
b = getchar();
}
terminal_clear();
}

69
lib/ksymtab.c Normal file
View File

@ -0,0 +1,69 @@
#include <ksymtab.h>
typedef struct kfunc {
/*
Bit 31 = 1 -> driver/module function, Bit 31 = 0 -> kernel function
Bits 30-20 -> module/driver ID (11 bits)
Bits 19-0 -> function ID (20 bits)
*/
uint32_t id;
uint32_t addr; /* Pointer to function, 0x0 if nonexistent */
} kfunc_t;
#define KFUNC_TABLE_ADDRESS 0xC0101000
#define KFUNC_TABLE_SIZE (2 ^ 31) /* Maybe? who knows? */
#define IS_MODULE_FUNC(id) ((id) & 0x80000000)
#define GET_MODULE_ID(id) (((id) >> 20) & 0x7FF)
#define GET_FUNC_ID(id) ((id) & 0xFFFFF)
#define EXISTS(id) ((id) > 0x0)
#define MAKE_KERNEL_FUNC(id) ((id) & 0x7FFFFFFF)
#define MAKE_MODULE_FUNC(mid, fid) (0x80000000 | ((mid) << 20) | ((fid) & 0xFFFFF))
kfunc_t* kfunc_table = (kfunc_t*)KFUNC_TABLE_ADDRESS;
uint64_t kfunc_call(kfunc_t* func, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
{
uint32_t eax_ret, edx_ret;
asm volatile (
"push %[d]\n\t"
"push %[c]\n\t"
"push %[b]\n\t"
"push %[a]\n\t"
"call *%[fn]\n\t"
"add $16, %%esp\n\t" /* clean up stack (4 args * 4 bytes) */
: "=a"(eax_ret), "=d"(edx_ret)
: [a]"r"(a), [b]"r"(b), [c]"r"(c), [d]"r"(d), [fn]"r"(func->addr)
: "memory"
);
return ((uint64_t)edx_ret << 32) | eax_ret;
}
uint64_t call_kfunc_by_id(uint32_t id, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
{
for (int i = 0; i < KFUNC_TABLE_SIZE; i++)
{
if (kfunc_table[i].id == id)
{
if (kfunc_table[i].addr == 0x0)
{
return -1;
}
return kfunc_call(&kfunc_table[i], a, b, c, d);
}
}
return -1;
}