Espresso 0.0.1d
This commit is contained in:
@ -4,26 +4,63 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
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(1, (irq_func_t*)keyboard_handler);
|
||||
}
|
||||
|
||||
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]();
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (num < 64)
|
||||
if (num < NUM_IRQS)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -36,15 +36,22 @@ static bool shift_pressed = false;
|
||||
/* State for caps-lock key */
|
||||
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 int32_t current_length = 0;
|
||||
volatile int32_t capacity = 0;
|
||||
volatile uint16_t current_key;
|
||||
|
||||
|
||||
static const char scancode_map[128] = {
|
||||
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 */
|
||||
0, /* Control */
|
||||
'a','s','d','f','g','h','j','k','l',';','\'','`',
|
||||
@ -67,7 +74,46 @@ void keyboard_init(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 it’s 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)
|
||||
@ -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);
|
||||
|
||||
/* Handle shift press/release */
|
||||
@ -137,41 +184,76 @@ void keyboard_handler(void) {
|
||||
capslock_pressed = !capslock_pressed;
|
||||
return;
|
||||
}
|
||||
else if (scancode == 0xE0)
|
||||
{
|
||||
extended = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (scancode & 0x80)
|
||||
{
|
||||
/* Key release event, ignore for now */
|
||||
} else
|
||||
extended = false;
|
||||
}
|
||||
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 */
|
||||
}
|
||||
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");
|
||||
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)
|
||||
{
|
||||
current_char = c;
|
||||
|
||||
is_new_char = true;
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
free_current_string();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
append_char(c);
|
||||
printf("%c", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,3 +247,11 @@ unsigned char terminal_get_shifted(unsigned char uc)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
8
include/builtin_games/miner.h
Normal file
8
include/builtin_games/miner.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _MINER_H
|
||||
#define _MINER_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
void miner_main(void);
|
||||
|
||||
#endif
|
@ -6,7 +6,10 @@
|
||||
typedef void (*irq_func_t)(void);
|
||||
|
||||
void irq_init(void);
|
||||
|
||||
void irq_handler(uint8_t irq_number);
|
||||
|
||||
void set_irq_handler(uint32_t num, irq_func_t* handler);
|
||||
void add_irq_handler(uint32_t num, irq_func_t* handler);
|
||||
|
||||
#endif
|
||||
|
@ -3,10 +3,20 @@
|
||||
|
||||
#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_handler(void);
|
||||
|
||||
char get_char(void);
|
||||
uint16_t get_key(void);
|
||||
char* get_string(void);
|
||||
|
||||
#endif
|
||||
|
6
include/ksymtab.h
Normal file
6
include/ksymtab.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _KSYMTAB_H
|
||||
#define _KSYMTAB_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#endif
|
@ -24,8 +24,8 @@ char lower(char c);
|
||||
char toupper(char c);
|
||||
char lower(char c);
|
||||
|
||||
void *memset(void *dst, char c, uint32_t n);
|
||||
void *memcpy(void *dst, const void *src, uint32_t n);
|
||||
void* memset(void *dst, char c, 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);
|
||||
void* memclr(void* m_start, size_t m_count);
|
||||
|
||||
|
@ -25,4 +25,6 @@ void terminal_scroll(void);
|
||||
|
||||
unsigned char terminal_get_shifted(unsigned char uc);
|
||||
|
||||
void terminal_set_cursor(uint16_t row, uint16_t column);
|
||||
|
||||
#endif
|
||||
|
@ -5,4 +5,11 @@
|
||||
#include <stddef.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
|
||||
|
@ -37,6 +37,8 @@
|
||||
|
||||
#include <kernel/intro.h>
|
||||
|
||||
#include <builtin_games/miner.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
|
||||
@ -44,12 +46,12 @@ extern void _hang_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 --- */
|
||||
|
||||
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. */
|
||||
terminal_initialize();
|
||||
@ -78,7 +80,7 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
|
||||
idt_init();
|
||||
_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);
|
||||
|
||||
@ -132,7 +134,6 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
|
||||
printd("PCI initialized\n");
|
||||
|
||||
|
||||
|
||||
/* --- END INITIALIZATION SECTION --- */
|
||||
|
||||
terminal_setcolor(VGA_COLOR_LIGHT_GREEN);
|
||||
@ -141,14 +142,14 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
|
||||
/*pit_sleep(4000);
|
||||
begin_anim(espresso_kernel_version);*/
|
||||
|
||||
printf("Guten tag and welcome to Espresso\n");
|
||||
|
||||
/*printf("here\n");
|
||||
|
||||
printf("%i\n", sfs_init(false));
|
||||
|
||||
printf("here\n");*/
|
||||
|
||||
printf("Guten tag and welcome to Espresso\n");
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
|
76
lib/builtin_games/miner.c
Normal file
76
lib/builtin_games/miner.c
Normal 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
69
lib/ksymtab.c
Normal 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user