Started Implementing a BASIC interpriter

This commit is contained in:
OusmBlueNinja 2024-12-30 15:52:32 -06:00
parent e82fb49c04
commit 3eee0f8269
73 changed files with 984 additions and 644 deletions

22
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,22 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${default}",
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.22621.0",
"compilerPath": "C:/msys64/mingw64/bin/gcc.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}

Binary file not shown.

Binary file not shown.

BIN
build/x86_64/basic.o Normal file

Binary file not shown.

BIN
build/x86_64/strings.o Normal file

Binary file not shown.

BIN
dist/x86_64/kernel.bin vendored Normal file

Binary file not shown.

View File

@ -10,11 +10,9 @@
#include "window.h" #include "window.h"
#include "fs.h" #include "fs.h"
#include "fat12.h" #include "fat12.h"
#include "basic.h"
#define COMMAND_BUFFER_SIZE 256 // Increase buffer size to handle longer commands
#define COMMAND_BUFFER_SIZE 256 // Increase buffer size to handle longer commands
#define BACKSPACE_KEY 8 #define BACKSPACE_KEY 8
#define HISTORY_SIZE 10 #define HISTORY_SIZE 10
#define COMMAND_BUFFER_SIZE 256 #define COMMAND_BUFFER_SIZE 256
@ -22,29 +20,31 @@
extern void kpanic(int error_code); extern void kpanic(int error_code);
void shutdown_system()
void shutdown_system() { {
__asm__ ( __asm__(
"movl $1, %eax\n" // syscall number for sys_reboot (1 in this case) "movl $1, %eax\n" // syscall number for sys_reboot (1 in this case)
"movl $0, %ebx\n" // reboot flags "movl $0, %ebx\n" // reboot flags
"movl $0, %ecx\n" // no additional arguments "movl $0, %ecx\n" // no additional arguments
"movl $0, %edx\n" // no additional arguments "movl $0, %edx\n" // no additional arguments
"int $0x80\n" // interrupt to invoke syscall "int $0x80\n" // interrupt to invoke syscall
); );
} }
char commandHistory[HISTORY_SIZE][COMMAND_BUFFER_SIZE]; char commandHistory[HISTORY_SIZE][COMMAND_BUFFER_SIZE];
int currentHistoryIndex = 0; int currentHistoryIndex = 0;
int historyCount = 0; int historyCount = 0;
void add_to_history(const char* command) { void add_to_history(const char *command)
if (historyCount < HISTORY_SIZE) { {
if (historyCount < HISTORY_SIZE)
{
historyCount++; historyCount++;
} else { }
for (int i = 1; i < HISTORY_SIZE; i++) { else
{
for (int i = 1; i < HISTORY_SIZE; i++)
{
strcpy(commandHistory[i - 1], commandHistory[i]); strcpy(commandHistory[i - 1], commandHistory[i]);
} }
} }
@ -52,23 +52,26 @@ void add_to_history(const char* command) {
currentHistoryIndex = historyCount; currentHistoryIndex = historyCount;
} }
const char* get_previous_command() { const char *get_previous_command()
if (currentHistoryIndex > 0) { {
if (currentHistoryIndex > 0)
{
currentHistoryIndex--; currentHistoryIndex--;
return commandHistory[currentHistoryIndex]; return commandHistory[currentHistoryIndex];
} }
return NULL; return NULL;
} }
const char* get_next_command() { const char *get_next_command()
if (currentHistoryIndex < historyCount - 1) { {
if (currentHistoryIndex < historyCount - 1)
{
currentHistoryIndex++; currentHistoryIndex++;
return commandHistory[currentHistoryIndex]; return commandHistory[currentHistoryIndex];
} }
return NULL; return NULL;
} }
const void clear() const void clear()
{ {
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
@ -79,113 +82,127 @@ const void clear()
print_setup_prompt(); print_setup_prompt();
} }
void halt()
{
void halt(){
print_str("[ WARN ] HALT\n"); print_str("[ WARN ] HALT\n");
while (1) {} while (1)
{
}
} }
void commandHandler(char* command) { void commandHandler(char *command)
{
printf("\n"); printf("\n");
if (strcmp(command, "cls") == 0) { if (strcmp(command, "cls") == 0)
{
clear(); clear();
} else if (strcmp(command, "knp") == 0) { }
else if (strcmp(command, "knp") == 0)
{
kpanic(1); kpanic(1);
} else if (int_strncmp(command, "echo ", 5) == 0) { }
char* message = command + 5; // Skip the "echo " part else if (int_strncmp(command, "echo ", 5) == 0)
{
char *message = command + 5; // Skip the "echo " part
print_str("\n"); print_str("\n");
print_str(message); print_str(message);
print_str("\n"); print_str("\n");
} else if (int_strncmp(command, "cwin", 4) == 0) { }
else if (int_strncmp(command, "cwin", 4) == 0)
{
// Define window properties // Define window properties
Window myWindow; Window myWindow;
int x = 8; // X position of the window int x = 8; // X position of the window
int y = 4; // Y position of the window int y = 4; // Y position of the window
int width = 30; // Width of the window int width = 30; // Width of the window
int height = 10; // Height of the window int height = 10; // Height of the window
uint8_t borderColor = PRINT_COLOR_RED; // Border color uint8_t borderColor = PRINT_COLOR_RED; // Border color
uint8_t backgroundColor = PRINT_COLOR_BLUE; // Background color uint8_t backgroundColor = PRINT_COLOR_BLUE; // Background color
// Create and display the window // Create and display the window
create_window(&myWindow, x, y, width, height, borderColor, backgroundColor, "Main Window"); create_window(&myWindow, x, y, width, height, borderColor, backgroundColor, "Main Window");
// Print text inside the window // Print text inside the window
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLUE); // Set text color print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLUE); // Set text color
print_text_in_window(&myWindow, 2, 2, "Window Manager is a "); print_text_in_window(&myWindow, 2, 2, "Window Manager is a ");
print_text_in_window(&myWindow, 2, 3, "Work in progress, Sorry :("); // Print text inside the window print_text_in_window(&myWindow, 2, 3, "Work in progress, Sorry :("); // Print text inside the window
print_text_in_window(&myWindow, 2, 4, "do [ cls ] to clear"); // Print text inside the window print_text_in_window(&myWindow, 2, 4, "do [ cls ] to clear"); // Print text inside the window
}
else if (int_strncmp(command, "exit", 4) == 0)
{
} else if (int_strncmp(command, "exit", 4) == 0) {
printf("Driver Call [ shutdown_system(); ] \n"); printf("Driver Call [ shutdown_system(); ] \n");
shutdown_system(); shutdown_system();
}
else if (int_strncmp(command, "panic_test", 10) == 0)
} else if (int_strncmp(command, "panic_test", 10) == 0) { {
int _y = 1/0; int _y = 1 / 0;
printf("Output %d\n", _y); printf("Output %d\n", _y);
}
} else if (int_strncmp(command, "test", 4) == 0) { else if (int_strncmp(command, "test", 4) == 0)
{
//// Test custom malloc and free //// Test custom malloc and free
//void* block1 = malloc(32); // void* block1 = malloc(32);
//void* block2 = malloc(64); // void* block2 = malloc(64);
//void* block3 = malloc(128); // void* block3 = malloc(128);
// //
//// List used blocks //// List used blocks
//list_used_blocks(); // list_used_blocks();
// //
//// Free a block and check again //// Free a block and check again
//free(block2); // free(block2);
//printf("\nAfter freeing block2:\n"); // printf("\nAfter freeing block2:\n");
//list_used_blocks(); // list_used_blocks();
// //
//void* block4 = malloc(64); // void* block4 = malloc(64);
// //
//list_used_blocks(); // list_used_blocks();
create_game(); create_game();
}
} else if (int_strncmp(command, "split", 5) == 0) { else if (int_strncmp(command, "split", 5) == 0)
{
printf("Kernel Call [ split_string(); ]\n"); printf("Kernel Call [ split_string(); ]\n");
// Check the length of the command string and use it properly // Check the length of the command string and use it properly
char** new_command = split_string(command, ",", strlen(command)); char **new_command = split_string(command, ",", strlen(command));
//char** new_command = {{NULL, NULL, NULL, NULL}}; // char** new_command = {{NULL, NULL, NULL, NULL}};
if (new_command) { if (new_command)
{
// Add a loop to print all the elements in the new_command array for debugging // Add a loop to print all the elements in the new_command array for debugging
for (int i = 0; new_command[i] != NULL; i++) { for (int i = 0; new_command[i] != NULL; i++)
{
printf("new_command[%d]: %s\n", i, new_command[i]); printf("new_command[%d]: %s\n", i, new_command[i]);
} }
//halt(); // Debug halt // halt(); // Debug halt
// Ensure that new_command[1] exists before accessing it // Ensure that new_command[1] exists before accessing it
if (new_command[1] != NULL) { if (new_command[1] != NULL)
{
printf("%s\n", new_command[1]); printf("%s\n", new_command[1]);
} else { }
else
{
printf("Error: new_command[1] is NULL\n"); printf("Error: new_command[1] is NULL\n");
} }
} else { }
printf("Error: split_string returned NULL\n"); else
{
printf("Error: split_string returned NULL\n");
}
} }
else
{
} else {
printf("Unknown command: %s\n", command); printf("Unknown command: %s\n", command);
} }
} }
void print_setup_prompt()
{
void print_setup_prompt() {
move_cursor(0, 0); move_cursor(0, 0);
print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK); print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK);
print_str("-------------------- "); print_str("-------------------- ");
@ -197,34 +214,58 @@ void print_setup_prompt() {
print_str("V 1.5.01\n"); print_str("V 1.5.01\n");
} }
int test_basic()
{
InterpreterState state;
init_state(&state);
const char *program[] = {
"LET A = 10",
"LET B = 20",
"PRINT A + B",
"LET A = \"Hello\"",
"LET B = \" World\"",
"PRINT A + B",
"END",
};
for (size_t i = 0; i < sizeof(program) / sizeof(program[0]); i++)
{
execute_line(&state, program[i]);
if (!state.running)
break;
}
return 0;
}
void kernel_main()
{
void kernel_main() {
init_keyboard_driver(); init_keyboard_driver();
idt_install(); idt_install();
print_str("[ WARN ] Skipping File System Initialization...\n[ INFO ] Do [ fsinit ] to initalize the filesystem\n"); print_str("[ WARN ] Skipping File System Initialization...\n[ INFO ] Do [ fsinit ] to initalize the filesystem\n");
if (fat12_init() == 0) { if (fat12_init() == 0)
{
printf("Filesystem mounted\n"); printf("Filesystem mounted\n");
fat12_read_root_directory(); fat12_read_root_directory();
fat12_dir_entry_t entry; fat12_dir_entry_t entry;
if (fat12_find_file("HELLOTXT", &entry)) { if (fat12_find_file("HELLOTXT", &entry))
{
printf("File found: HELLO.TXT\n"); printf("File found: HELLO.TXT\n");
} }
} }
clear();
print_setup_prompt();
test_basic();
print_setup_prompt();
print_str(" > "); print_str(" > ");
@ -232,57 +273,64 @@ void kernel_main() {
char key; char key;
bool keydown = false; bool keydown = false;
char commandBuffer[COMMAND_BUFFER_SIZE]; char commandBuffer[COMMAND_BUFFER_SIZE];
size_t commandLength = 0; // To track the length of the current command size_t commandLength = 0; // To track the length of the current command
while (1)
while (1) { {
key = read_key(); key = read_key();
if (key != 0) { if (key != 0)
if (!keydown) { {
if (!keydown)
{
CursorPosition pos = get_print_cursor_pos(); CursorPosition pos = get_print_cursor_pos();
move_cursor(pos.x,pos.y); move_cursor(pos.x, pos.y);
if (key == 10) { // Enter key if (key == 10)
commandBuffer[commandLength] = '\0'; // Null-terminate the command { // Enter key
commandBuffer[commandLength] = '\0'; // Null-terminate the command
commandHandler(commandBuffer); commandHandler(commandBuffer);
// Reset command buffer for the next input // Reset command buffer for the next input
commandLength = 0; commandLength = 0;
print_str(" > "); print_str(" > ");
}
} else if (key == BACKSPACE_KEY) { // Backspace key else if (key == BACKSPACE_KEY)
if (commandLength > 0) { { // Backspace key
if (commandLength > 0)
{
// Remove the last character from the buffer // Remove the last character from the buffer
commandLength--; commandLength--;
commandBuffer[commandLength] = '0'; // Null-terminate after removal commandBuffer[commandLength] = '0'; // Null-terminate after removal
// Clear the character from the screen (overwrite with space) // Clear the character from the screen (overwrite with space)
// Move cursor back one position // Move cursor back one position
offset_print_cursor(-1,0); offset_print_cursor(-1, 0);
print_char(' '); // Overwrite the character print_char(' '); // Overwrite the character
offset_print_cursor(-1,0); // Move cursor back one position(because its moved left one by the rpintf) offset_print_cursor(-1, 0); // Move cursor back one position(because its moved left one by the rpintf)
} }
}
} else { else
if (key >= 32 && key <= 126) { // Check if the key is a printable character {
if (commandLength < COMMAND_BUFFER_SIZE - 1) { if (key >= 32 && key <= 126)
commandBuffer[commandLength++] = key; // Append character to buffer { // Check if the key is a printable character
if (commandLength < COMMAND_BUFFER_SIZE - 1)
{
commandBuffer[commandLength++] = key; // Append character to buffer
commandBuffer[commandLength] = '\0'; // Null-terminate the buffer commandBuffer[commandLength] = '\0'; // Null-terminate the buffer
print_char(key); // Print key to the screen print_char(key); // Print key to the screen
} }
} }
} }
keydown = true; keydown = true;
} }
} else { }
else
{
keydown = false; keydown = false;
} }
// int x = 100/0; // int x = 100/0;
} }
kpanic(2); kpanic(2);
} }

184
src/impl/x86_64/basic.c Normal file
View File

@ -0,0 +1,184 @@
#include "memory.h"
#include "print.h"
#include "strings.h"
#include "stdint.h"
#include "stddef.h"
#include "basic.h"
// Utility: Find or create a variable by name
Variable* get_variable(InterpreterState* state, const char* name) {
for (size_t i = 0; i < state->variable_count; i++) {
if (strcmp(state->variables[i].name, name) == 0) {
return &state->variables[i];
}
}
if (state->variable_count < MAX_VARIABLES) {
Variable* var = &state->variables[state->variable_count++];
strncpy(var->name, name, sizeof(var->name) - 1);
var->name[sizeof(var->name) - 1] = '\0';
var->value = 0;
var->str_value = NULL;
return var;
}
return NULL; // No space for more variables
}
// Parse an integer from a string, skipping leading whitespace
int parse_int(const char* str) {
while (*str == ' ') str++; // Skip leading spaces
int result = 0;
int sign = 1;
if (*str == '-') {
sign = -1;
str++;
}
while (*str >= '0' && *str <= '9') {
result = result * 10 + (*str - '0');
str++;
}
return result * sign;
}
const char* evaluate_expression(InterpreterState* state, const char* expr) {
char buffer[64];
strncpy(buffer, expr, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
char* plus = strrchr(buffer, '+');
if (plus) {
*plus = '\0';
// Evaluate the left and right sides only once
const char* left = evaluate_expression(state, buffer);
const char* right = evaluate_expression(state, plus + 1);
// Debug output
printf("DEBUG: Left operand: %s\n", left);
printf("DEBUG: Right operand: %s\n", right);
// Check if both sides are numeric
int left_is_number = (left[0] >= '0' && left[0] <= '9') || (left[0] == '-' && left[1] >= '0' && left[1] <= '9');
int right_is_number = (right[0] >= '0' && right[0] <= '9') || (right[0] == '-' && right[1] >= '0' && right[1] <= '9');
static char result[128];
if (left_is_number && right_is_number) {
// Parse the left and right operands
int left_value = parse_int(left);
int right_value = parse_int(right);
// Correct addition logic
int sum = left_value + right_value;
// Debug addition
printf("DEBUG: Adding %d + %d = %d\n", left_value, right_value, sum);
// Format the result as a string
snprintf(result, sizeof(result), "%d", sum);
} else {
// Concatenate strings
snprintf(result, sizeof(result), "%s%s", left, right);
// Debug string concatenation
printf("DEBUG: Concatenating strings: %s + %s = %s\n", left, right, result);
}
return result;
}
// Trim leading and trailing spaces
const char* start = buffer;
while (*start == ' ') start++;
char* end = buffer + strlen(buffer) - 1;
while (end > start && *end == ' ') *end-- = '\0';
if (start[0] >= 'A' && start[0] <= 'Z') {
Variable* var = get_variable(state, start);
if (var) {
static char var_result[64];
if (var->str_value) {
strncpy(var_result, var->str_value, sizeof(var_result) - 1);
var_result[sizeof(var_result) - 1] = '\0';
return var_result;
} else {
snprintf(var_result, sizeof(var_result), "%d", var->value);
return var_result;
}
}
}
if (start[0] == '"') {
// String literal
size_t len = strlen(start);
if (start[len - 1] == '"') {
static char str_result[64];
strncpy(str_result, start + 1, len - 2);
str_result[len - 2] = '\0';
return str_result;
}
}
static char int_result[16];
snprintf(int_result, sizeof(int_result), "%d", parse_int(start));
return int_result;
}
// Interpret a single line of code
void interpret_line(InterpreterState* state, const char* line) {
if (strncmp(line, "LET", 3) == 0) {
const char* rest = line + 3;
while (*rest == ' ') rest++;
const char* equals = strchr(rest, '=');
if (!equals) return;
char var_name[16];
strncpy(var_name, rest, equals - rest);
var_name[equals - rest] = '\0';
// Trim trailing spaces from var_name
size_t len = strlen(var_name);
while (len > 0 && var_name[len - 1] == ' ') {
var_name[--len] = '\0';
}
Variable* var = get_variable(state, var_name);
if (var) {
const char* value = evaluate_expression(state, equals + 1);
if (value[0] >= '0' && value[0] <= '9') {
var->value = parse_int(value);
var->str_value = NULL;
} else {
var->str_value = malloc(strlen(value) + 1);
strcpy(var->str_value, value);
}
}
} else if (strncmp(line, "PRINT", 5) == 0) {
const char* rest = line + 5;
while (*rest == ' ') rest++;
const char* value = evaluate_expression(state, rest);
printf("%s\n", value);
} else if (strncmp(line, "END", 3) == 0) {
printf("Program terminated.\n");
state->running = 0;
}
}
// Initialize interpreter state
void init_state(InterpreterState* state) {
state->variable_count = 0;
state->running = 1;
}
// Execute a single line in the context of a state
void execute_line(InterpreterState* state, const char* line) {
printf("Executing line: %s\n", line); // Debugging
interpret_line(state, line);
}

View File

@ -1,139 +1,139 @@
; isr.asm - ISR assembly stubs ; isr.asm - ISR assembly stubs
global isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15 global isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15
global isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31 global isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31
extern isr_common_handler extern isr_common_handler
section .text section .text
; ISRs 0 to 13 (no error code pushed by CPU) ; ISRs 0 to 13 (no error code pushed by CPU)
isr0: isr0:
cli cli
push 0 ; Push error code (none for isr0) push 0 ; Push error code (none for isr0)
push 0 ; Push interrupt number push 0 ; Push interrupt number
jmp isr_common_handler jmp isr_common_handler
isr1: isr1:
cli cli
push 0 push 0
push 1 push 1
jmp isr_common_handler jmp isr_common_handler
isr2: isr2:
cli cli
push 0 push 0
push 2 push 2
jmp isr_common_handler jmp isr_common_handler
isr3: isr3:
cli cli
push 0 push 0
push 3 push 3
jmp isr_common_handler jmp isr_common_handler
isr4: isr4:
cli cli
push 0 push 0
push 4 push 4
jmp isr_common_handler jmp isr_common_handler
isr5: isr5:
cli cli
push 0 push 0
push 5 push 5
jmp isr_common_handler jmp isr_common_handler
isr6: isr6:
cli cli
push 0 push 0
push 6 push 6
jmp isr_common_handler jmp isr_common_handler
isr7: isr7:
cli cli
push 0 push 0
push 7 push 7
jmp isr_common_handler jmp isr_common_handler
isr8: isr8:
cli cli
push 0 push 0
push 8 push 8
jmp isr_common_handler jmp isr_common_handler
isr9: isr9:
cli cli
push 0 push 0
push 9 push 9
jmp isr_common_handler jmp isr_common_handler
isr10: isr10:
cli cli
push 0 push 0
push 10 push 10
jmp isr_common_handler jmp isr_common_handler
isr11: isr11:
cli cli
push 0 push 0
push 11 push 11
jmp isr_common_handler jmp isr_common_handler
isr12: isr12:
cli cli
push 0 push 0
push 12 push 12
jmp isr_common_handler jmp isr_common_handler
isr13: isr13:
cli cli
push 0 push 0
push 13 push 13
jmp isr_common_handler jmp isr_common_handler
; ISR 14 (Page Fault) requires error code pushed by CPU ; ISR 14 (Page Fault) requires error code pushed by CPU
isr14: isr14:
cli cli
push 14 ; Push interrupt number push 14 ; Push interrupt number
jmp isr_common_handler jmp isr_common_handler
; ISRs 15 to 31 (no error code pushed by CPU) ; ISRs 15 to 31 (no error code pushed by CPU)
isr15: isr15:
cli cli
push 0 push 0
push 15 push 15
jmp isr_common_handler jmp isr_common_handler
isr16: isr16:
cli cli
push 0 push 0
push 16 push 16
jmp isr_common_handler jmp isr_common_handler
isr17: isr17:
cli cli
push 0 push 0
push 17 push 17
jmp isr_common_handler jmp isr_common_handler
isr18: isr18:
cli cli
push 0 push 0
push 18 push 18
jmp isr_common_handler jmp isr_common_handler
isr19: isr19:
cli cli
push 0 push 0
push 19 push 19
jmp isr_common_handler jmp isr_common_handler
isr20: isr20:
cli cli
push 0 push 0
push 20 push 20
jmp isr_common_handler jmp isr_common_handler

View File

@ -1,43 +1,43 @@
// disk_io.c // disk_io.c
#include "disk_io.h" #include "disk_io.h"
#include "print.h" // Assuming you have a function for kernel printing #include "print.h" // Assuming you have a function for kernel printing
#define SECTOR_SIZE 512 #define SECTOR_SIZE 512
// Function to read sectors from disk // Function to read sectors from disk
int disk_read(uint32_t lba, void *buffer, uint32_t size) { int disk_read(uint32_t lba, void *buffer, uint32_t size) {
// lba: logical block address // lba: logical block address
// buffer: where to store the read data // buffer: where to store the read data
// size: number of bytes to read // size: number of bytes to read
if (size % SECTOR_SIZE != 0) { if (size % SECTOR_SIZE != 0) {
printf("Read size must be a multiple of 512 bytes\n"); printf("Read size must be a multiple of 512 bytes\n");
return -1; return -1;
} }
for (uint32_t i = 0; i < size / SECTOR_SIZE; i++) { for (uint32_t i = 0; i < size / SECTOR_SIZE; i++) {
// Placeholder for actual disk sector read. Replace with proper implementation // Placeholder for actual disk sector read. Replace with proper implementation
if (!bios_read_sector(lba + i, buffer + (i * SECTOR_SIZE))) { if (!bios_read_sector(lba + i, buffer + (i * SECTOR_SIZE))) {
printf("Error reading sector from disk\n"); printf("Error reading sector from disk\n");
return -1; return -1;
} }
} }
return 0; return 0;
} }
// Placeholder function to simulate reading sectors from the disk // Placeholder function to simulate reading sectors from the disk
// Replace this with actual disk reading logic depending on the platform // Replace this with actual disk reading logic depending on the platform
int bios_read_sector(uint32_t lba, void *buffer) { int bios_read_sector(uint32_t lba, void *buffer) {
// Simulate disk sector read // Simulate disk sector read
// In an actual kernel, you'd use interrupts or other mechanisms to read from disk // In an actual kernel, you'd use interrupts or other mechanisms to read from disk
// For now, just zero out the buffer to simulate // For now, just zero out the buffer to simulate
for (int i = 0; i < SECTOR_SIZE; i++) { for (int i = 0; i < SECTOR_SIZE; i++) {
((uint8_t*)buffer)[i] = 0; // Fill buffer with zeros ((uint8_t*)buffer)[i] = 0; // Fill buffer with zeros
} }
return 1; // Success return 1; // Success
} }

View File

@ -334,6 +334,48 @@ int my_sscanf(const char *input, const char *format, char *output) {
return match_count; return match_count;
} }
snprintf(char* buffer, size_t size, const char* format, ...) {
va_list args;
va_start(args, format);
const char* traverse = format;
size_t written = 0;
while (*traverse && written < size - 1) {
if (*traverse == '%' && *(traverse + 1)) {
traverse++;
if (*traverse == 's') {
const char* str = va_arg(args, const char*);
while (*str && written < size - 1) {
buffer[written++] = *str++;
}
} else if (*traverse == 'd') {
int num = va_arg(args, int);
char num_buffer[16];
int num_len = 0;
if (num < 0) {
if (written < size - 1) buffer[written++] = '-';
num = -num;
}
do {
num_buffer[num_len++] = '0' + (num % 10);
num /= 10;
} while (num > 0);
while (num_len > 0 && written < size - 1) {
buffer[written++] = num_buffer[--num_len];
}
}
} else {
buffer[written++] = *traverse;
}
traverse++;
}
buffer[written] = '\0';
va_end(args);
return written;
}
void printf(const char* format, ...) { void printf(const char* format, ...) {
va_list args; va_list args;

View File

@ -1,80 +1,80 @@
#include "vector.h" #include "vector.h"
// Initial capacity for a new vector // Initial capacity for a new vector
#define VECTOR_INITIAL_CAPACITY 4 #define VECTOR_INITIAL_CAPACITY 4
// Create a new vector // Create a new vector
vector* vector_create() { vector* vector_create() {
vector* v = (vector*)malloc(sizeof(vector)); vector* v = (vector*)malloc(sizeof(vector));
if (!v) return NULL; // Return NULL if allocation fails if (!v) return NULL; // Return NULL if allocation fails
v->capacity = VECTOR_INITIAL_CAPACITY; v->capacity = VECTOR_INITIAL_CAPACITY;
v->size = 0; v->size = 0;
v->items = (void**)malloc(sizeof(void*) * v->capacity); v->items = (void**)malloc(sizeof(void*) * v->capacity);
if (!v->items) { if (!v->items) {
free(v); // Free the vector if item allocation fails free(v); // Free the vector if item allocation fails
return NULL; return NULL;
} }
return v; return v;
} }
// Destroy the vector and free allocated memory // Destroy the vector and free allocated memory
void vector_destroy(vector* v) { void vector_destroy(vector* v) {
if (v) { if (v) {
free(v->items); free(v->items);
free(v); free(v);
} }
} }
// Push an item to the back of the vector // Push an item to the back of the vector
int vector_push_back(vector* v, void* item) { int vector_push_back(vector* v, void* item) {
// Resize the vector if it's full // Resize the vector if it's full
if (v->size == v->capacity) { if (v->size == v->capacity) {
if (vector_resize(v, v->capacity * 2) != 0) { if (vector_resize(v, v->capacity * 2) != 0) {
return -1; // Return -1 on failure to resize return -1; // Return -1 on failure to resize
} }
} }
v->items[v->size++] = item; // Add the new item v->items[v->size++] = item; // Add the new item
return 0; // Success return 0; // Success
} }
// Get the item at a specific index // Get the item at a specific index
void* vector_get(vector* v, size_t index) { void* vector_get(vector* v, size_t index) {
if (index >= v->size) return NULL; // Return NULL if index is out of bounds if (index >= v->size) return NULL; // Return NULL if index is out of bounds
return v->items[index]; return v->items[index];
} }
// Set an item at a specific index // Set an item at a specific index
int vector_set(vector* v, size_t index, void* item) { int vector_set(vector* v, size_t index, void* item) {
if (index >= v->size) return -1; // Return -1 if index is out of bounds if (index >= v->size) return -1; // Return -1 if index is out of bounds
v->items[index] = item; v->items[index] = item;
return 0; // Success return 0; // Success
} }
// Get the size of the vector // Get the size of the vector
size_t vector_size(vector* v) { size_t vector_size(vector* v) {
return v->size; return v->size;
} }
// Resize the vector's internal array // Resize the vector's internal array
int vector_resize(vector* v, size_t new_capacity) { int vector_resize(vector* v, size_t new_capacity) {
// Allocate new memory for the resized array // Allocate new memory for the resized array
void** new_items = (void**)malloc(sizeof(void*) * new_capacity); void** new_items = (void**)malloc(sizeof(void*) * new_capacity);
if (!new_items) return -1; // Return -1 on failure if (!new_items) return -1; // Return -1 on failure
// Copy the old items into the new array // Copy the old items into the new array
for (size_t i = 0; i < v->size; i++) { for (size_t i = 0; i < v->size; i++) {
new_items[i] = v->items[i]; new_items[i] = v->items[i];
} }
// Free the old memory // Free the old memory
free(v->items); free(v->items);
// Update the vector's internal state // Update the vector's internal state
v->items = new_items; v->items = new_items;
v->capacity = new_capacity; v->capacity = new_capacity;
return 0; // Success return 0; // Success
} }

View File

@ -1,185 +1,185 @@
#include "game.h" #include "game.h"
#include "print.h" #include "print.h"
#include "keydriver.h" #include "keydriver.h"
#include "strings.h" #include "strings.h"
#include "stdint.h" #include "stdint.h"
// Define constants for the game // Define constants for the game
#define ROOM_COUNT 5 #define ROOM_COUNT 5
#define INVENTORY_SIZE 5 #define INVENTORY_SIZE 5
// Global variable to hold the game state // Global variable to hold the game state
static GameState game_state; static GameState game_state;
// Room descriptions and connected rooms // Room descriptions and connected rooms
typedef struct { typedef struct {
const char* description; const char* description;
int north; int north;
int south; int south;
int east; int east;
int west; int west;
} Room; } Room;
static const Room rooms[ROOM_COUNT] = { static const Room rooms[ROOM_COUNT] = {
{ "You are in a dark forest. There are paths to the north and east.", 1, -1, 2, -1 }, { "You are in a dark forest. There are paths to the north and east.", 1, -1, 2, -1 },
{ "You are on a beach. There is a cave to the west.", -1, 0, -1, 3 }, { "You are on a beach. There is a cave to the west.", -1, 0, -1, 3 },
{ "You are inside a cave. Its damp and dark.", -1, -1, -1, 0 }, { "You are inside a cave. Its damp and dark.", -1, -1, -1, 0 },
{ "You are in a small village. There's a shop to the north and a forest to the east.", 4, -1, -1, -1 }, { "You are in a small village. There's a shop to the north and a forest to the east.", 4, -1, -1, -1 },
{ "You are in a shop filled with various items. The village is to the south.", -1, 3, -1, -1 } { "You are in a shop filled with various items. The village is to the south.", -1, 3, -1, -1 }
}; };
// Player's inventory // Player's inventory
static const char* inventory[INVENTORY_SIZE]; static const char* inventory[INVENTORY_SIZE];
static int inventory_count = 0; static int inventory_count = 0;
// Command buffer // Command buffer
static char commandBuffer[MAX_COMMAND_LENGTH]; static char commandBuffer[MAX_COMMAND_LENGTH];
static size_t commandLength = 0; static size_t commandLength = 0;
bool keydown = false; bool keydown = false;
// Function to handle user input commands // Function to handle user input commands
void handle_command(const char* command) { void handle_command(const char* command) {
game_clear(); game_clear();
if (strcmp(command, "look") == 0) { if (strcmp(command, "look") == 0) {
printf(rooms[game_state.current_room].description); printf(rooms[game_state.current_room].description);
printf("\n"); printf("\n");
} else if (strcmp(command, "north") == 0) { } else if (strcmp(command, "north") == 0) {
if (rooms[game_state.current_room].north != -1) { if (rooms[game_state.current_room].north != -1) {
game_state.current_room = rooms[game_state.current_room].north; game_state.current_room = rooms[game_state.current_room].north;
printf("You walk north.\n"); printf("You walk north.\n");
printf("%s\n", rooms[game_state.current_room].description); printf("%s\n", rooms[game_state.current_room].description);
} else { } else {
printf("You can't go that way.\n"); printf("You can't go that way.\n");
} }
} else if (strcmp(command, "south") == 0) { } else if (strcmp(command, "south") == 0) {
if (rooms[game_state.current_room].south != -1) { if (rooms[game_state.current_room].south != -1) {
game_state.current_room = rooms[game_state.current_room].south; game_state.current_room = rooms[game_state.current_room].south;
printf("You walk south.\n"); printf("You walk south.\n");
printf("%s\n", rooms[game_state.current_room].description); printf("%s\n", rooms[game_state.current_room].description);
} else { } else {
printf("You can't go that way.\n"); printf("You can't go that way.\n");
} }
} else if (strcmp(command, "east") == 0) { } else if (strcmp(command, "east") == 0) {
if (rooms[game_state.current_room].east != -1) { if (rooms[game_state.current_room].east != -1) {
game_state.current_room = rooms[game_state.current_room].east; game_state.current_room = rooms[game_state.current_room].east;
printf("You walk east.\n"); printf("You walk east.\n");
printf("%s\n", rooms[game_state.current_room].description); printf("%s\n", rooms[game_state.current_room].description);
} else { } else {
printf("You can't go that way.\n"); printf("You can't go that way.\n");
} }
} else if (strcmp(command, "west") == 0) { } else if (strcmp(command, "west") == 0) {
if (rooms[game_state.current_room].west != -1) { if (rooms[game_state.current_room].west != -1) {
game_state.current_room = rooms[game_state.current_room].west; game_state.current_room = rooms[game_state.current_room].west;
printf("You walk west.\n"); printf("You walk west.\n");
printf("%s\n", rooms[game_state.current_room].description); printf("%s\n", rooms[game_state.current_room].description);
} else { } else {
printf("You can't go that way.\n"); printf("You can't go that way.\n");
} }
} else if (strcmp(command, "inventory") == 0) { } else if (strcmp(command, "inventory") == 0) {
printf("You are carrying:\n"); printf("You are carrying:\n");
for (int i = 0; i < inventory_count; ++i) { for (int i = 0; i < inventory_count; ++i) {
printf("- %s\n", inventory[i]); printf("- %s\n", inventory[i]);
} }
if (inventory_count == 0) { if (inventory_count == 0) {
printf("Nothing.\n"); printf("Nothing.\n");
} }
} else if (strcmp(command, "take key") == 0) { } else if (strcmp(command, "take key") == 0) {
if (game_state.current_room == 1) { if (game_state.current_room == 1) {
if (inventory_count < INVENTORY_SIZE) { if (inventory_count < INVENTORY_SIZE) {
inventory[inventory_count++] = "key"; inventory[inventory_count++] = "key";
printf("You picked up a key.\n"); printf("You picked up a key.\n");
} else { } else {
printf("Your inventory is full.\n"); printf("Your inventory is full.\n");
} }
} else { } else {
printf("There is no key here.\n"); printf("There is no key here.\n");
} }
} else if (strcmp(command, "use key") == 0) { } else if (strcmp(command, "use key") == 0) {
bool has_key = false; bool has_key = false;
for (int i = 0; i < inventory_count; ++i) { for (int i = 0; i < inventory_count; ++i) {
if (strcmp(inventory[i], "key") == 0) { if (strcmp(inventory[i], "key") == 0) {
has_key = true; has_key = true;
break; break;
} }
} }
if (has_key && game_state.current_room == 2) { if (has_key && game_state.current_room == 2) {
printf("You unlock the door in the cave and find a treasure!\n"); printf("You unlock the door in the cave and find a treasure!\n");
game_state.game_active = false; // End the game game_state.game_active = false; // End the game
} else { } else {
printf("You can't use the key here.\n"); printf("You can't use the key here.\n");
} }
} else if (strcmp(command, "quit") == 0) { } else if (strcmp(command, "quit") == 0) {
printf("You quit the game.\n"); printf("You quit the game.\n");
game_state.game_active = false; game_state.game_active = false;
} else { } else {
printf("Unknown command.\n"); printf("Unknown command.\n");
} }
} }
// Function to print the prompt for the player // Function to print the prompt for the player
void print_prompt() { void print_prompt() {
printf(" > "); printf(" > ");
} }
const void game_clear() const void game_clear()
{ {
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
move_print_cursor(0, 0); move_print_cursor(0, 0);
move_cursor(0, 0); move_cursor(0, 0);
print_clear(); print_clear();
} }
// Function to initialize and run the game // Function to initialize and run the game
void create_game() { void create_game() {
// Initialize the game state // Initialize the game state
game_state.current_room = 0; game_state.current_room = 0;
game_state.game_active = true; game_state.game_active = true;
printf("Welcome to the text adventure game!\n"); printf("Welcome to the text adventure game!\n");
printf("Type 'look' to see where you are, 'north', 'south', 'east', 'west' to move, or 'quit' to exit.\n"); printf("Type 'look' to see where you are, 'north', 'south', 'east', 'west' to move, or 'quit' to exit.\n");
printf("You can 'take key' or 'use key' in the appropriate places.\n"); printf("You can 'take key' or 'use key' in the appropriate places.\n");
print_prompt(); print_prompt();
// Main game loop // Main game loop
while (game_state.game_active) { while (game_state.game_active) {
char key = read_key(); // Get key input char key = read_key(); // Get key input
if (key != 0) { if (key != 0) {
if (!keydown) { if (!keydown) {
if (key == 10) { // Enter key if (key == 10) { // Enter key
printf("\n"); printf("\n");
commandBuffer[commandLength] = '\0'; // Null-terminate the command commandBuffer[commandLength] = '\0'; // Null-terminate the command
handle_command(commandBuffer); // Process the command handle_command(commandBuffer); // Process the command
commandLength = 0; // Reset command buffer commandLength = 0; // Reset command buffer
if (game_state.game_active) { if (game_state.game_active) {
print_prompt(); // Print prompt for the next command print_prompt(); // Print prompt for the next command
} }
} else if (key == 8) { // Backspace key } else if (key == 8) { // Backspace key
if (commandLength > 0) { if (commandLength > 0) {
commandLength--; commandLength--;
offset_print_cursor(-1, 0); offset_print_cursor(-1, 0);
print_char(' '); // Overwrite the character print_char(' '); // Overwrite the character
offset_print_cursor(-1, 0); offset_print_cursor(-1, 0);
} }
} else if (key >= 32 && key <= 126) { // Printable characters } else if (key >= 32 && key <= 126) { // Printable characters
if (commandLength < MAX_COMMAND_LENGTH - 1) { if (commandLength < MAX_COMMAND_LENGTH - 1) {
commandBuffer[commandLength++] = key; commandBuffer[commandLength++] = key;
print_char(key); // Display the key on the screen print_char(key); // Display the key on the screen
} }
} }
keydown = true; keydown = true;
} }
} else { } else {
keydown = false; keydown = false;
} }
} }
printf("Thanks for playing!\n"); printf("Thanks for playing!\n");
} }

View File

@ -89,4 +89,14 @@ int strncmp(const char *s1, const char *s2, size_t n) {
} else { } else {
return (*(unsigned char *)s1 - *(unsigned char *)s2); return (*(unsigned char *)s1 - *(unsigned char *)s2);
} }
} }
char* strchr(const char* str, int ch) {
while (*str) {
if (*str == (char)ch) {
return (char*)str;
}
str++;
}
return NULL;
}

32
src/intf/basic.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef BASIC_INTERPRETER_H
#define BASIC_INTERPRETER_H
#include "stdint.h"
#include "stddef.h"
#define MAX_LINE_LENGTH 128
#define MAX_VARIABLES 32
typedef struct {
char name[16];
int value;
char* str_value;
} Variable;
typedef struct {
Variable variables[MAX_VARIABLES];
size_t variable_count;
int running;
} InterpreterState;
// Initialize the interpreter state
void init_state(InterpreterState* state);
// Execute a single line of code in the context of a state
void execute_line(InterpreterState* state, const char* line);
// Utility to evaluate an expression (exposed for potential reuse)
const char* evaluate_expression(InterpreterState* state, const char* expr);
#endif // BASIC_INTERPRETER_H

View File

@ -1,17 +1,17 @@
// disk_io.h // disk_io.h
#ifndef DISK_IO_H #ifndef DISK_IO_H
#define DISK_IO_H #define DISK_IO_H
#include <stdint.h> #include <stdint.h>
// Read sectors from the disk // Read sectors from the disk
int disk_read(uint32_t lba, void *buffer, uint32_t size); int disk_read(uint32_t lba, void *buffer, uint32_t size);
// Optional: Write sectors to the disk (not implemented) // Optional: Write sectors to the disk (not implemented)
int disk_write(uint32_t lba, const void *buffer, uint32_t size); int disk_write(uint32_t lba, const void *buffer, uint32_t size);
int bios_read_sector(uint32_t lba, void *buffer); int bios_read_sector(uint32_t lba, void *buffer);
#endif // DISK_IO_H #endif // DISK_IO_H

View File

@ -1,25 +1,25 @@
#ifndef GAME_H #ifndef GAME_H
#define GAME_H #define GAME_H
#include "stdint.h" #include "stdint.h"
// Define the maximum length of a command // Define the maximum length of a command
#define MAX_COMMAND_LENGTH 128 #define MAX_COMMAND_LENGTH 128
// Game state structure // Game state structure
typedef struct { typedef struct {
int current_room; int current_room;
bool game_active; bool game_active;
} GameState; } GameState;
// Function to initialize and run the game // Function to initialize and run the game
void create_game(); void create_game();
// Function to handle the command input by the player // Function to handle the command input by the player
void handle_command(const char* command); void handle_command(const char* command);
// Function to print the current prompt // Function to print the current prompt
void print_prompt(); void print_prompt();
#endif #endif

View File

@ -29,6 +29,7 @@ enum {
}; };
void sscanf(const char *str, const char *format, char *filename, char *content); void sscanf(const char *str, const char *format, char *filename, char *content);
snprintf(char* buffer, size_t size, const char* format, ...);
int my_sscanf(const char *input, const char *format, char *output); int my_sscanf(const char *input, const char *format, char *output);
void print_clear(); void print_clear();
void print_char(char character); void print_char(char character);

View File

@ -5,8 +5,9 @@
int strcmp(const char *str1, const char *str2); int strcmp(const char *str1, const char *str2);
size_t strlen(const char *str); size_t strlen(const char *str);
char *strncpy(char *dest, const char *src, size_t n); char *strncpy(char *dest, const char *src, size_t n);
int int_strncmp(const char* s1, const char* s2, size_t n); int int_strncmp(const char *s1, const char *s2, size_t n);
void strcpy(char *dest, const char *src); void strcpy(char *dest, const char *src);
char* strrchr(const char* str, char ch); char *strrchr(const char *str, char ch);
int strncmp(const char *s1, const char *s2, size_t n); int strncmp(const char *s1, const char *s2, size_t n);
char *strchr(const char *str, int ch);

View File

@ -1,22 +1,22 @@
#ifndef VECTOR_H #ifndef VECTOR_H
#define VECTOR_H #define VECTOR_H
#include <stddef.h> #include <stddef.h>
// Define the vector structure // Define the vector structure
typedef struct { typedef struct {
void** items; // Pointer to the array of items void** items; // Pointer to the array of items
size_t capacity; // Maximum number of items the vector can hold size_t capacity; // Maximum number of items the vector can hold
size_t size; // Current number of items in the vector size_t size; // Current number of items in the vector
} vector; } vector;
// Function prototypes // Function prototypes
vector* vector_create(); vector* vector_create();
void vector_destroy(vector* v); void vector_destroy(vector* v);
int vector_push_back(vector* v, void* item); int vector_push_back(vector* v, void* item);
void* vector_get(vector* v, size_t index); void* vector_get(vector* v, size_t index);
int vector_set(vector* v, size_t index, void* item); int vector_set(vector* v, size_t index, void* item);
size_t vector_size(vector* v); size_t vector_size(vector* v);
int vector_resize(vector* v, size_t new_capacity); int vector_resize(vector* v, size_t new_capacity);
#endif #endif

Binary file not shown.