Add interrupts and keyboard driver

This commit is contained in:
2025-11-20 21:13:50 +01:00
parent 2d52c45915
commit 18092face9
19 changed files with 1259 additions and 7 deletions

View File

@@ -1,7 +1,9 @@
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <duktape.h>
#include "embedded_js.h"
#include "interrupt/isr.h"
#define WHITE_TXT 0x0F
@@ -56,6 +58,35 @@ duk_ret_t native_ptout(duk_context *ctx)
return 0;
}
duk_ret_t native_byte_in(duk_context *ctx)
{
// Get the port (first argument)
uint16_t port = (uint16_t)duk_to_uint32(ctx, 0);
uint8_t result;
__asm__ volatile("inb %1, %0"
: "=a"(result)
: "Nd"(port));
duk_push_uint(ctx, (duk_uint_t)result);
return 1;
}
duk_ret_t native_byte_out(duk_context *ctx)
{
// Get the port (first argument)
uint16_t port = (uint16_t)duk_to_uint32(ctx, 0);
// Get the value to write (second argument)
uint8_t value = (uint8_t)duk_to_uint32(ctx, 1);
__asm__ volatile("outb %0, %1"
:
: "a"(value), "Nd"(port));
return 0;
}
duk_ret_t native_dword_in(duk_context *ctx)
{
// Get the port (first argument)
@@ -85,10 +116,90 @@ duk_ret_t native_dword_out(duk_context *ctx)
return 0;
}
// Global context for IRQ handlers
duk_context *global_ctx = NULL;
// JavaScript IRQ wrapper
void js_irq_callback(registers_t *r)
{
if (global_ctx == NULL)
return;
// Get IRQ number
u8 irq_no = r->int_no - 32;
// Build the key for this IRQ handler manually (avoid snprintf in interrupt)
char key[32] = "irq_handler_";
int key_len = 12;
if (irq_no >= 10)
{
key[key_len++] = '0' + (irq_no / 10);
key[key_len++] = '0' + (irq_no % 10);
}
else
{
key[key_len++] = '0' + irq_no;
}
key[key_len] = '\0';
// Call the JavaScript handler
duk_push_global_stash(global_ctx);
if (duk_get_prop_string(global_ctx, -1, key))
{
// Function found, call it with IRQ number
duk_push_uint(global_ctx, irq_no);
// Try protected call with error handler
duk_int_t rc = duk_pcall(global_ctx, 1);
duk_pop(global_ctx); // Pop result or error
}
else
{
duk_pop(global_ctx); // Pop undefined value
}
duk_pop(global_ctx); // Pop stash
}
// Native function to register IRQ from JavaScript
duk_ret_t native_irq_register(duk_context *ctx)
{
// Get the IRQ number
u8 irq = (u8)duk_to_uint32(ctx, 0);
// Get the handler function
if (!duk_is_function(ctx, 1))
{
duk_push_boolean(ctx, 0);
return 1;
}
// Store function in global stash
char key[32];
snprintf(key, sizeof(key), "irq_handler_%d", irq);
duk_push_global_stash(ctx);
duk_dup(ctx, 1); // Duplicate the function
duk_put_prop_string(ctx, -2, key);
duk_pop(ctx); // Pop stash
// Register the C wrapper
irq_register_handler(irq, js_irq_callback);
duk_push_boolean(ctx, 1);
return 1;
}
void kmain()
{
// Initialize IDT and ISRs
isr_install();
irq_install();
// Initialize Duktape heap
ctx = duk_create_heap_default();
global_ctx = ctx;
// Register native memory write function
duk_push_c_function(ctx, native_addrw, 2);
@@ -102,6 +213,14 @@ void kmain()
duk_push_c_function(ctx, native_ptout, 2);
duk_put_global_string(ctx, "$ptout");
// Register native byte in function
duk_push_c_function(ctx, native_byte_in, 1);
duk_put_global_string(ctx, "$bytein");
// Register native byte out function
duk_push_c_function(ctx, native_byte_out, 2);
duk_put_global_string(ctx, "$byteout");
// Register native dword in function
duk_push_c_function(ctx, native_dword_in, 1);
duk_put_global_string(ctx, "$dwordin");
@@ -110,6 +229,13 @@ void kmain()
duk_push_c_function(ctx, native_dword_out, 2);
duk_put_global_string(ctx, "$dwordout");
// Register native IRQ registration function
duk_push_c_function(ctx, native_irq_register, 2);
duk_put_global_string(ctx, "$irqregister");
// Enable interrupts before JavaScript execution
__asm__ volatile("sti");
// Execute embedded JavaScript code from build/index.js
duk_push_string(ctx, embedded_js_code);
duk_int_t returnCode = duk_peval(ctx);