Add files via upload
This commit is contained in:
commit
e82fb49c04
51
EYOSx86-main/Makefile
Normal file
51
EYOSx86-main/Makefile
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Define paths and files
|
||||||
|
IMAGE_SIZE_MB := 10
|
||||||
|
DISK_IMAGE := dist/x86_64/filesystem.img
|
||||||
|
KERNEL_BIN := dist/x86_64/kernel.bin
|
||||||
|
ISO_FILE := dist/x86_64/kernel.iso
|
||||||
|
ISO_DIR := targets/x86_64/iso
|
||||||
|
|
||||||
|
# List of object files
|
||||||
|
kernel_source_files := $(shell find src/impl/kernel -name *.c)
|
||||||
|
kernel_object_files := $(patsubst src/impl/kernel/%.c, build/kernel/%.o, $(kernel_source_files))
|
||||||
|
|
||||||
|
x86_64_c_source_files := $(shell find src/impl/x86_64 -name *.c)
|
||||||
|
x86_64_c_object_files := $(patsubst src/impl/x86_64/%.c, build/x86_64/%.o, $(x86_64_c_source_files))
|
||||||
|
|
||||||
|
x86_64_cpp_source_files := $(shell find src/impl/x86_64 -name *.cpp)
|
||||||
|
x86_64_cpp_object_files := $(patsubst src/impl/x86_64/%.cpp, build/x86_64/%.o, $(x86_64_cpp_source_files))
|
||||||
|
|
||||||
|
x86_64_asm_source_files := $(shell find src/impl/x86_64 -name *.asm)
|
||||||
|
x86_64_asm_object_files := $(patsubst src/impl/x86_64/%.asm, build/x86_64/%.o, $(x86_64_asm_source_files))
|
||||||
|
|
||||||
|
x86_64_object_files := $(x86_64_c_object_files) $(x86_64_cpp_object_files) $(x86_64_asm_object_files)
|
||||||
|
|
||||||
|
# Rule to compile C files for the kernel
|
||||||
|
$(kernel_object_files): build/kernel/%.o : src/impl/kernel/%.c
|
||||||
|
mkdir -p $(dir $@) && \
|
||||||
|
x86_64-elf-gcc -c -I src/intf -ffreestanding $(patsubst build/kernel/%.o, src/impl/kernel/%.c, $@) -o $@
|
||||||
|
|
||||||
|
# Rule to compile C files for x86_64
|
||||||
|
$(x86_64_c_object_files): build/x86_64/%.o : src/impl/x86_64/%.c
|
||||||
|
mkdir -p $(dir $@) && \
|
||||||
|
x86_64-elf-gcc -c -I src/intf -ffreestanding $(patsubst build/x86_64/%.o, src/impl/x86_64/%.c, $@) -o $@
|
||||||
|
|
||||||
|
# Rule to compile C++ files for x86_64
|
||||||
|
$(x86_64_cpp_object_files): build/x86_64/%.o : src/impl/x86_64/%.cpp
|
||||||
|
mkdir -p $(dir $@) && \
|
||||||
|
x86_64-elf-g++ -c -I src/intf -ffreestanding $(patsubst build/x86_64/%.o, src/impl/x86_64/%.cpp, $@) -o $@
|
||||||
|
|
||||||
|
# Rule to assemble ASM files for x86_64
|
||||||
|
$(x86_64_asm_object_files): build/x86_64/%.o : src/impl/x86_64/%.asm
|
||||||
|
mkdir -p $(dir $@) && \
|
||||||
|
nasm -f elf64 $(patsubst build/x86_64/%.o, src/impl/x86_64/%.asm, $@) -o $@
|
||||||
|
|
||||||
|
.PHONY: build-x86_64
|
||||||
|
build-x86_64: $(kernel_object_files) $(x86_64_object_files)
|
||||||
|
mkdir -p dist/x86_64 targets/x86_64/iso && \
|
||||||
|
x86_64-elf-ld -n -o $(KERNEL_BIN) -T targets/x86_64/linker.ld $(kernel_object_files) $(x86_64_object_files) && \
|
||||||
|
cp $(KERNEL_BIN) $(ISO_DIR)/boot/kernel.bin && \
|
||||||
|
dd if=/dev/zero of=$(DISK_IMAGE) bs=1M count=$(IMAGE_SIZE_MB) && \
|
||||||
|
mkfs.vfat -F 16 $(DISK_IMAGE) && \
|
||||||
|
mcopy -i $(DISK_IMAGE) filesystem/hello/hello.txt ::/ && \
|
||||||
|
grub-mkrescue -o $(ISO_FILE) $(ISO_DIR)
|
60
EYOSx86-main/README.md
Normal file
60
EYOSx86-main/README.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Write Your Own 64-bit Operating System Kernel From Scratch
|
||||||
|
|
||||||
|
This respository holds all the source code for [this YouTube tutorial series](https://www.youtube.com/playlist?list=PLZQftyCk7_SeZRitx5MjBKzTtvk0pHMtp).
|
||||||
|
|
||||||
|
You can find the revision for a specific episode on [this page](https://github.com/davidcallanan/yt-os-series/tags).
|
||||||
|
|
||||||
|
You can find pre-built ISO files for this kernel at [this repository](https://github.com/davidcallanan/os-series-isos).
|
||||||
|
|
||||||
|
Considering supporting this work via [my Patreon page](http://patreon.com/codepulse).
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- A text editor such as [VS Code](https://code.visualstudio.com/).
|
||||||
|
- [Docker](https://www.docker.com/) for creating our build-environment.
|
||||||
|
- [Qemu](https://www.qemu.org/) for emulating our operating system.
|
||||||
|
- Remember to add Qemu to the path so that you can access it from your command-line. ([Windows instructions here](https://dev.to/whaleshark271/using-qemu-on-windows-10-home-edition-4062))
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Build an image for our build-environment:
|
||||||
|
|
||||||
|
- `docker build buildenv -t myos-buildenv`
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Enter build environment:
|
||||||
|
|
||||||
|
- Linux or MacOS: `docker run --rm -it -v "$(pwd)":/root/env myos-buildenv`
|
||||||
|
- Windows (CMD): `docker run --rm -it -v "%cd%":/root/env myos-buildenv`
|
||||||
|
- Windows (PowerShell): `docker run --rm -it -v "${pwd}:/root/env" myos-buildenv`
|
||||||
|
- Please use the linux command if you are using `WSL`, `msys2` or `git bash`
|
||||||
|
- NOTE: If you are having trouble with an unshared drive, ensure your docker daemon has access to the drive you're development environment is in. For Docker Desktop, this is in "Settings > Shared Drives" or "Settings > Resources > File Sharing".
|
||||||
|
|
||||||
|
Build for x86 (other architectures may come in the future):
|
||||||
|
|
||||||
|
- `make build-x86_64`
|
||||||
|
- If you are using Qemu, please close it before running this command to prevent errors.
|
||||||
|
|
||||||
|
To leave the build environment, enter `exit`.
|
||||||
|
|
||||||
|
## Emulate
|
||||||
|
|
||||||
|
You can emulate your operating system using [Qemu](https://www.qemu.org/): (Don't forget to [add qemu to your path](https://dev.to/whaleshark271/using-qemu-on-windows-10-home-edition-4062#:~:text=2.-,Add%20Qemu%20path%20to%20environment%20variables%20settings,-Copy%20the%20Qemu)!)
|
||||||
|
|
||||||
|
- `qemu-system-x86_64 -cdrom dist/x86_64/kernel.iso`
|
||||||
|
- Note: Close the emulator when finished, so as to not block writing to `kernel.iso` for future builds.
|
||||||
|
|
||||||
|
If the above command fails, try one of the following:
|
||||||
|
|
||||||
|
- Windows: [`qemu-system-x86_64 -cdrom dist/x86_64/kernel.iso -L "C:\Program Files\qemu"`](https://stackoverflow.com/questions/66266448/qemu-could-not-load-pc-bios-bios-256k-bin)
|
||||||
|
- Linux: [`qemu-system-x86_64 -cdrom dist/x86_64/kernel.iso -L /usr/share/qemu/`](https://unix.stackexchange.com/questions/134893/cannot-start-kvm-vm-because-missing-bios)
|
||||||
|
- Alternatively, install a custom BIOS binary file and link it to Qemu using the `-L` option.
|
||||||
|
|
||||||
|
Alternatively, you should be able to load the operating system on a USB drive and boot into it when you turn on your computer. (I haven't actually tested this yet.)
|
||||||
|
|
||||||
|
## Cleanup
|
||||||
|
|
||||||
|
Remove the build-evironment image:
|
||||||
|
|
||||||
|
- `docker rmi myos-buildenv -f`
|
BIN
EYOSx86-main/build/kernel/main.o
Normal file
BIN
EYOSx86-main/build/kernel/main.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/boot/header.o
Normal file
BIN
EYOSx86-main/build/x86_64/boot/header.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/boot/isr.o
Normal file
BIN
EYOSx86-main/build/x86_64/boot/isr.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/boot/main.o
Normal file
BIN
EYOSx86-main/build/x86_64/boot/main.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/boot/main64.o
Normal file
BIN
EYOSx86-main/build/x86_64/boot/main64.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/disk_io.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/disk_io.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/fat.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/fat.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/fat12.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/fat12.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/fs.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/fs.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/idt.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/idt.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/io.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/io.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/irs.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/irs.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/keydriver.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/keydriver.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/memory.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/memory.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/print.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/print.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/vector.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/vector.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/driver/vga.o
Normal file
BIN
EYOSx86-main/build/x86_64/driver/vga.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/game.o
Normal file
BIN
EYOSx86-main/build/x86_64/game.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/stdopt.o
Normal file
BIN
EYOSx86-main/build/x86_64/stdopt.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/strings.o
Normal file
BIN
EYOSx86-main/build/x86_64/strings.o
Normal file
Binary file not shown.
BIN
EYOSx86-main/build/x86_64/window.o
Normal file
BIN
EYOSx86-main/build/x86_64/window.o
Normal file
Binary file not shown.
14
EYOSx86-main/buildenv/Dockerfile
Normal file
14
EYOSx86-main/buildenv/Dockerfile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
FROM randomdude/gcc-cross-x86_64-elf
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get upgrade -y
|
||||||
|
RUN apt-get install -y nasm
|
||||||
|
RUN apt-get install -y xorriso
|
||||||
|
RUN apt-get install -y grub-pc-bin
|
||||||
|
RUN apt-get install -y grub-common
|
||||||
|
RUN apt-get install -y dosfstools
|
||||||
|
RUN apt-get install -y mtools
|
||||||
|
|
||||||
|
|
||||||
|
VOLUME /root/env
|
||||||
|
WORKDIR /root/env
|
BIN
EYOSx86-main/dist/x86_64/filesystem.img
vendored
Normal file
BIN
EYOSx86-main/dist/x86_64/filesystem.img
vendored
Normal file
Binary file not shown.
BIN
EYOSx86-main/dist/x86_64/kernel.bin
vendored
Normal file
BIN
EYOSx86-main/dist/x86_64/kernel.bin
vendored
Normal file
Binary file not shown.
BIN
EYOSx86-main/dist/x86_64/kernel.iso
vendored
Normal file
BIN
EYOSx86-main/dist/x86_64/kernel.iso
vendored
Normal file
Binary file not shown.
1
EYOSx86-main/filesystem/hello/hello.txt
Normal file
1
EYOSx86-main/filesystem/hello/hello.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hello, World!
|
288
EYOSx86-main/src/impl/kernel/main.c
Normal file
288
EYOSx86-main/src/impl/kernel/main.c
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
#include "print.h"
|
||||||
|
#include "keydriver.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stdopt.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "vga.h"
|
||||||
|
#include "idt.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "window.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "fat12.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define COMMAND_BUFFER_SIZE 256 // Increase buffer size to handle longer commands
|
||||||
|
#define BACKSPACE_KEY 8
|
||||||
|
#define HISTORY_SIZE 10
|
||||||
|
#define COMMAND_BUFFER_SIZE 256
|
||||||
|
#define BUFFER_SIZE 4096
|
||||||
|
|
||||||
|
extern void kpanic(int error_code);
|
||||||
|
|
||||||
|
|
||||||
|
void shutdown_system() {
|
||||||
|
__asm__ (
|
||||||
|
"movl $1, %eax\n" // syscall number for sys_reboot (1 in this case)
|
||||||
|
"movl $0, %ebx\n" // reboot flags
|
||||||
|
"movl $0, %ecx\n" // no additional arguments
|
||||||
|
"movl $0, %edx\n" // no additional arguments
|
||||||
|
"int $0x80\n" // interrupt to invoke syscall
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char commandHistory[HISTORY_SIZE][COMMAND_BUFFER_SIZE];
|
||||||
|
int currentHistoryIndex = 0;
|
||||||
|
int historyCount = 0;
|
||||||
|
|
||||||
|
void add_to_history(const char* command) {
|
||||||
|
if (historyCount < HISTORY_SIZE) {
|
||||||
|
historyCount++;
|
||||||
|
} else {
|
||||||
|
for (int i = 1; i < HISTORY_SIZE; i++) {
|
||||||
|
strcpy(commandHistory[i - 1], commandHistory[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcpy(commandHistory[historyCount - 1], command);
|
||||||
|
currentHistoryIndex = historyCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* get_previous_command() {
|
||||||
|
if (currentHistoryIndex > 0) {
|
||||||
|
currentHistoryIndex--;
|
||||||
|
return commandHistory[currentHistoryIndex];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* get_next_command() {
|
||||||
|
if (currentHistoryIndex < historyCount - 1) {
|
||||||
|
currentHistoryIndex++;
|
||||||
|
return commandHistory[currentHistoryIndex];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const void clear()
|
||||||
|
{
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
||||||
|
|
||||||
|
move_print_cursor(0, 0);
|
||||||
|
move_cursor(0, 0);
|
||||||
|
print_clear();
|
||||||
|
print_setup_prompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void halt(){
|
||||||
|
print_str("[ WARN ] HALT\n");
|
||||||
|
while (1) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void commandHandler(char* command) {
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if (strcmp(command, "cls") == 0) {
|
||||||
|
clear();
|
||||||
|
} else if (strcmp(command, "knp") == 0) {
|
||||||
|
kpanic(1);
|
||||||
|
} else if (int_strncmp(command, "echo ", 5) == 0) {
|
||||||
|
char* message = command + 5; // Skip the "echo " part
|
||||||
|
print_str("\n");
|
||||||
|
print_str(message);
|
||||||
|
print_str("\n");
|
||||||
|
} else if (int_strncmp(command, "cwin", 4) == 0) {
|
||||||
|
// Define window properties
|
||||||
|
Window myWindow;
|
||||||
|
int x = 8; // X position of the window
|
||||||
|
int y = 4; // Y position of the window
|
||||||
|
int width = 30; // Width of the window
|
||||||
|
int height = 10; // Height of the window
|
||||||
|
uint8_t borderColor = PRINT_COLOR_RED; // Border color
|
||||||
|
uint8_t backgroundColor = PRINT_COLOR_BLUE; // Background color
|
||||||
|
|
||||||
|
// Create and display the window
|
||||||
|
create_window(&myWindow, x, y, width, height, borderColor, backgroundColor, "Main Window");
|
||||||
|
|
||||||
|
// Print text inside the window
|
||||||
|
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, 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else if (int_strncmp(command, "exit", 4) == 0) {
|
||||||
|
printf("Driver Call [ shutdown_system(); ] \n");
|
||||||
|
shutdown_system();
|
||||||
|
|
||||||
|
|
||||||
|
} else if (int_strncmp(command, "panic_test", 10) == 0) {
|
||||||
|
int _y = 1/0;
|
||||||
|
printf("Output %d\n", _y);
|
||||||
|
|
||||||
|
} else if (int_strncmp(command, "test", 4) == 0) {
|
||||||
|
|
||||||
|
//// Test custom malloc and free
|
||||||
|
//void* block1 = malloc(32);
|
||||||
|
//void* block2 = malloc(64);
|
||||||
|
//void* block3 = malloc(128);
|
||||||
|
//
|
||||||
|
//// List used blocks
|
||||||
|
//list_used_blocks();
|
||||||
|
//
|
||||||
|
//// Free a block and check again
|
||||||
|
//free(block2);
|
||||||
|
//printf("\nAfter freeing block2:\n");
|
||||||
|
//list_used_blocks();
|
||||||
|
//
|
||||||
|
//void* block4 = malloc(64);
|
||||||
|
//
|
||||||
|
//list_used_blocks();
|
||||||
|
|
||||||
|
|
||||||
|
create_game();
|
||||||
|
|
||||||
|
} else if (int_strncmp(command, "split", 5) == 0) {
|
||||||
|
printf("Kernel Call [ split_string(); ]\n");
|
||||||
|
|
||||||
|
// Check the length of the command string and use it properly
|
||||||
|
char** new_command = split_string(command, ",", strlen(command));
|
||||||
|
|
||||||
|
//char** new_command = {{NULL, NULL, NULL, NULL}};
|
||||||
|
|
||||||
|
if (new_command) {
|
||||||
|
// Add a loop to print all the elements in the new_command array for debugging
|
||||||
|
for (int i = 0; new_command[i] != NULL; i++) {
|
||||||
|
printf("new_command[%d]: %s\n", i, new_command[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//halt(); // Debug halt
|
||||||
|
|
||||||
|
// Ensure that new_command[1] exists before accessing it
|
||||||
|
if (new_command[1] != NULL) {
|
||||||
|
printf("%s\n", new_command[1]);
|
||||||
|
} else {
|
||||||
|
printf("Error: new_command[1] is NULL\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Error: split_string returned NULL\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Unknown command: %s\n", command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void print_setup_prompt() {
|
||||||
|
move_cursor(0, 0);
|
||||||
|
print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK);
|
||||||
|
print_str("-------------------- ");
|
||||||
|
print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK);
|
||||||
|
print_str("EYOS");
|
||||||
|
print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK);
|
||||||
|
print_str(" --------------------\n");
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
||||||
|
print_str("V 1.5.01\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void kernel_main() {
|
||||||
|
|
||||||
|
init_keyboard_driver();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
idt_install();
|
||||||
|
|
||||||
|
|
||||||
|
print_str("[ WARN ] Skipping File System Initialization...\n[ INFO ] Do [ fsinit ] to initalize the filesystem\n");
|
||||||
|
|
||||||
|
if (fat12_init() == 0) {
|
||||||
|
printf("Filesystem mounted\n");
|
||||||
|
|
||||||
|
fat12_read_root_directory();
|
||||||
|
|
||||||
|
fat12_dir_entry_t entry;
|
||||||
|
if (fat12_find_file("HELLOTXT", &entry)) {
|
||||||
|
printf("File found: HELLO.TXT\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
print_setup_prompt();
|
||||||
|
|
||||||
|
|
||||||
|
print_str(" > ");
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
char key;
|
||||||
|
bool keydown = false;
|
||||||
|
char commandBuffer[COMMAND_BUFFER_SIZE];
|
||||||
|
size_t commandLength = 0; // To track the length of the current command
|
||||||
|
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
key = read_key();
|
||||||
|
|
||||||
|
if (key != 0) {
|
||||||
|
if (!keydown) {
|
||||||
|
CursorPosition pos = get_print_cursor_pos();
|
||||||
|
move_cursor(pos.x,pos.y);
|
||||||
|
if (key == 10) { // Enter key
|
||||||
|
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
||||||
|
commandHandler(commandBuffer);
|
||||||
|
|
||||||
|
// Reset command buffer for the next input
|
||||||
|
commandLength = 0;
|
||||||
|
print_str(" > ");
|
||||||
|
|
||||||
|
} else if (key == BACKSPACE_KEY) { // Backspace key
|
||||||
|
if (commandLength > 0) {
|
||||||
|
// Remove the last character from the buffer
|
||||||
|
commandLength--;
|
||||||
|
commandBuffer[commandLength] = '0'; // Null-terminate after removal
|
||||||
|
|
||||||
|
// Clear the character from the screen (overwrite with space)
|
||||||
|
// Move cursor back one position
|
||||||
|
offset_print_cursor(-1,0);
|
||||||
|
print_char(' '); // Overwrite the character
|
||||||
|
offset_print_cursor(-1,0); // Move cursor back one position(because its moved left one by the rpintf)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (key >= 32 && key <= 126) { // 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
|
||||||
|
print_char(key); // Print key to the screen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keydown = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keydown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// int x = 100/0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kpanic(2);
|
||||||
|
|
||||||
|
}
|
16
EYOSx86-main/src/impl/x86_64/boot/header.asm
Normal file
16
EYOSx86-main/src/impl/x86_64/boot/header.asm
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
section .multiboot_header
|
||||||
|
header_start:
|
||||||
|
; magic number
|
||||||
|
dd 0xe85250d6 ; multiboot2
|
||||||
|
; architecture
|
||||||
|
dd 0 ; protected mode i386
|
||||||
|
; header length
|
||||||
|
dd header_end - header_start
|
||||||
|
; checksum
|
||||||
|
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))
|
||||||
|
|
||||||
|
; end tag
|
||||||
|
dw 0
|
||||||
|
dw 0
|
||||||
|
dd 8
|
||||||
|
header_end:
|
139
EYOSx86-main/src/impl/x86_64/boot/isr.asm
Normal file
139
EYOSx86-main/src/impl/x86_64/boot/isr.asm
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
; isr.asm - ISR assembly stubs
|
||||||
|
|
||||||
|
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
|
||||||
|
extern isr_common_handler
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
; ISRs 0 to 13 (no error code pushed by CPU)
|
||||||
|
isr0:
|
||||||
|
cli
|
||||||
|
push 0 ; Push error code (none for isr0)
|
||||||
|
push 0 ; Push interrupt number
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr1:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 1
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr2:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 2
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr3:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 3
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr4:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 4
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr5:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 5
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr6:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 6
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr7:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 7
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr8:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 8
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr9:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 9
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr10:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 10
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr11:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 11
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr12:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 12
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr13:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 13
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
; ISR 14 (Page Fault) requires error code pushed by CPU
|
||||||
|
isr14:
|
||||||
|
cli
|
||||||
|
push 14 ; Push interrupt number
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
; ISRs 15 to 31 (no error code pushed by CPU)
|
||||||
|
isr15:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 15
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr16:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 16
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr17:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 17
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr18:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 18
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr19:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 19
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
isr20:
|
||||||
|
cli
|
||||||
|
push 0
|
||||||
|
push 20
|
||||||
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
157
EYOSx86-main/src/impl/x86_64/boot/main.asm
Normal file
157
EYOSx86-main/src/impl/x86_64/boot/main.asm
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
global start
|
||||||
|
extern long_mode_start
|
||||||
|
extern idtp
|
||||||
|
extern handle_keypress
|
||||||
|
; idt_load.asm
|
||||||
|
global idt_load
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 32
|
||||||
|
start:
|
||||||
|
mov esp, stack_top
|
||||||
|
|
||||||
|
call check_multiboot
|
||||||
|
call check_cpuid
|
||||||
|
call check_long_mode
|
||||||
|
|
||||||
|
call setup_page_tables
|
||||||
|
call enable_paging
|
||||||
|
|
||||||
|
lgdt [gdt64.pointer]
|
||||||
|
jmp gdt64.code_segment:long_mode_start
|
||||||
|
|
||||||
|
hlt
|
||||||
|
|
||||||
|
; Load the IDT
|
||||||
|
idt_load:
|
||||||
|
lidt [idtp]
|
||||||
|
sti ; Enable interrupts
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
check_multiboot:
|
||||||
|
cmp eax, 0x36d76289
|
||||||
|
jne .no_multiboot
|
||||||
|
ret
|
||||||
|
.no_multiboot:
|
||||||
|
mov al, 'M'
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
check_cpuid:
|
||||||
|
pushfd
|
||||||
|
pop eax
|
||||||
|
mov ecx, eax
|
||||||
|
xor eax, 1 << 21
|
||||||
|
push eax
|
||||||
|
popfd
|
||||||
|
pushfd
|
||||||
|
pop eax
|
||||||
|
push ecx
|
||||||
|
popfd
|
||||||
|
cmp eax, ecx
|
||||||
|
je .no_cpuid
|
||||||
|
ret
|
||||||
|
.no_cpuid:
|
||||||
|
mov al, 'C'
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
check_long_mode:
|
||||||
|
mov eax, 0x80000000
|
||||||
|
cpuid
|
||||||
|
cmp eax, 0x80000001
|
||||||
|
jb .no_long_mode
|
||||||
|
|
||||||
|
mov eax, 0x80000001
|
||||||
|
cpuid
|
||||||
|
test edx, 1 << 29
|
||||||
|
jz .no_long_mode
|
||||||
|
|
||||||
|
ret
|
||||||
|
.no_long_mode:
|
||||||
|
mov al, 'L'
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
setup_page_tables:
|
||||||
|
mov eax, page_table_l3
|
||||||
|
or eax, 0b11 ; present, writable
|
||||||
|
mov [page_table_l4], eax
|
||||||
|
|
||||||
|
mov eax, page_table_l2
|
||||||
|
or eax, 0b11 ; present, writable
|
||||||
|
mov [page_table_l3], eax
|
||||||
|
|
||||||
|
mov ecx, 0 ; counter
|
||||||
|
.loop:
|
||||||
|
|
||||||
|
mov eax, 0x200000 ; 2MiB
|
||||||
|
mul ecx
|
||||||
|
or eax, 0b10000011 ; present, writable, huge page
|
||||||
|
mov [page_table_l2 + ecx * 8], eax
|
||||||
|
|
||||||
|
inc ecx ; increment counter
|
||||||
|
cmp ecx, 512 ; checks if the whole table is mapped
|
||||||
|
jne .loop ; if not, continue
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
enable_paging:
|
||||||
|
; pass page table location to cpu
|
||||||
|
mov eax, page_table_l4
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
|
; enable PAE
|
||||||
|
mov eax, cr4
|
||||||
|
or eax, 1 << 5
|
||||||
|
mov cr4, eax
|
||||||
|
|
||||||
|
; enable long mode
|
||||||
|
mov ecx, 0xC0000080
|
||||||
|
rdmsr
|
||||||
|
or eax, 1 << 8
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
; enable paging
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1 << 31
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
error:
|
||||||
|
; print "ERR: X" where X is the error code
|
||||||
|
mov dword [0xb8000], 0x4f524f45
|
||||||
|
mov dword [0xb8004], 0x4f3a4f52
|
||||||
|
mov dword [0xb8008], 0x4f204f20
|
||||||
|
mov byte [0xb800a], al
|
||||||
|
hlt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
; Reserve space for the IDT pointer
|
||||||
|
idtp:
|
||||||
|
resb 6 ; 2 bytes for limit + 4 bytes for base address
|
||||||
|
align 4096
|
||||||
|
page_table_l4:
|
||||||
|
resb 4096
|
||||||
|
page_table_l3:
|
||||||
|
resb 4096
|
||||||
|
page_table_l2:
|
||||||
|
resb 4096
|
||||||
|
stack_bottom:
|
||||||
|
resb 4096 * 4
|
||||||
|
stack_top:
|
||||||
|
|
||||||
|
section .rodata
|
||||||
|
gdt64:
|
||||||
|
dq 0 ; zero entry
|
||||||
|
.code_segment: equ $ - gdt64
|
||||||
|
dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment
|
||||||
|
.pointer:
|
||||||
|
dw $ - gdt64 - 1 ; length
|
||||||
|
dq gdt64 ; address
|
16
EYOSx86-main/src/impl/x86_64/boot/main64.asm
Normal file
16
EYOSx86-main/src/impl/x86_64/boot/main64.asm
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
global long_mode_start
|
||||||
|
extern kernel_main
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 64
|
||||||
|
long_mode_start:
|
||||||
|
; load null into all data segment registers
|
||||||
|
mov ax, 0
|
||||||
|
mov ss, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
call kernel_main
|
||||||
|
hlt
|
43
EYOSx86-main/src/impl/x86_64/driver/disk_io.c
Normal file
43
EYOSx86-main/src/impl/x86_64/driver/disk_io.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// disk_io.c
|
||||||
|
|
||||||
|
#include "disk_io.h"
|
||||||
|
#include "print.h" // Assuming you have a function for kernel printing
|
||||||
|
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
|
||||||
|
// Function to read sectors from disk
|
||||||
|
int disk_read(uint32_t lba, void *buffer, uint32_t size) {
|
||||||
|
// lba: logical block address
|
||||||
|
// buffer: where to store the read data
|
||||||
|
// size: number of bytes to read
|
||||||
|
|
||||||
|
if (size % SECTOR_SIZE != 0) {
|
||||||
|
printf("Read size must be a multiple of 512 bytes\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < size / SECTOR_SIZE; i++) {
|
||||||
|
// Placeholder for actual disk sector read. Replace with proper implementation
|
||||||
|
if (!bios_read_sector(lba + i, buffer + (i * SECTOR_SIZE))) {
|
||||||
|
printf("Error reading sector from disk\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder function to simulate reading sectors from the disk
|
||||||
|
// Replace this with actual disk reading logic depending on the platform
|
||||||
|
int bios_read_sector(uint32_t lba, void *buffer) {
|
||||||
|
// Simulate disk sector read
|
||||||
|
// 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 (int i = 0; i < SECTOR_SIZE; i++) {
|
||||||
|
((uint8_t*)buffer)[i] = 0; // Fill buffer with zeros
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; // Success
|
||||||
|
}
|
||||||
|
|
129
EYOSx86-main/src/impl/x86_64/driver/fat12.c
Normal file
129
EYOSx86-main/src/impl/x86_64/driver/fat12.c
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// fat12.c
|
||||||
|
|
||||||
|
#include "fat12.h"
|
||||||
|
#include "disk_io.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
|
#include "fat12.h"
|
||||||
|
#include "disk_io.h" // Assuming this contains `disk_read` for sector-level disk access
|
||||||
|
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
#define FAT12_CLUSTER_SIZE 1 // Usually 1 sector per cluster for FAT12
|
||||||
|
#define FAT12_EOC 0xFF8 // End of cluster chain marker in FAT12
|
||||||
|
|
||||||
|
// Function to convert a cluster number to an LBA (Logical Block Address)
|
||||||
|
static uint32_t cluster_to_lba(uint16_t cluster, const fat12_boot_sector_t *boot_sector) {
|
||||||
|
uint32_t first_data_sector = boot_sector->reserved_sectors +
|
||||||
|
(boot_sector->num_fats * boot_sector->fat_size_16) +
|
||||||
|
boot_sector->root_entry_count * 32 / SECTOR_SIZE;
|
||||||
|
return first_data_sector + (cluster - 2) * boot_sector->sectors_per_cluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to read the FAT to find the next cluster
|
||||||
|
static uint16_t fat12_get_next_cluster(uint16_t cluster, const fat12_boot_sector_t *boot_sector) {
|
||||||
|
uint32_t fat_offset = cluster + (cluster / 2); // FAT12 uses 12-bit entries
|
||||||
|
uint16_t next_cluster;
|
||||||
|
uint8_t fat_entry[2];
|
||||||
|
|
||||||
|
// Read the FAT sector where the current cluster is stored
|
||||||
|
uint32_t fat_sector = boot_sector->reserved_sectors + fat_offset / SECTOR_SIZE;
|
||||||
|
uint32_t fat_offset_in_sector = fat_offset % SECTOR_SIZE;
|
||||||
|
|
||||||
|
disk_read(fat_sector, fat_entry, sizeof(fat_entry));
|
||||||
|
|
||||||
|
if (cluster & 1) {
|
||||||
|
next_cluster = ((fat_entry[1] << 4) | (fat_entry[0] >> 4)) & 0xFFF; // Odd cluster number
|
||||||
|
} else {
|
||||||
|
next_cluster = ((fat_entry[1] << 8) | fat_entry[0]) & 0xFFF; // Even cluster number
|
||||||
|
}
|
||||||
|
|
||||||
|
return next_cluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fat12_read_file(fat12_dir_entry_t *entry, void *buffer) {
|
||||||
|
fat12_boot_sector_t boot_sector;
|
||||||
|
uint16_t current_cluster = entry->first_cluster_low;
|
||||||
|
uint32_t file_size = entry->file_size;
|
||||||
|
uint8_t *buf_ptr = (uint8_t *)buffer;
|
||||||
|
uint32_t bytes_read = 0;
|
||||||
|
|
||||||
|
// Load the boot sector (this would need to be done once in initialization, but for simplicity here)
|
||||||
|
disk_read(0, &boot_sector, sizeof(fat12_boot_sector_t));
|
||||||
|
|
||||||
|
// Read each cluster of the file
|
||||||
|
while (current_cluster < FAT12_EOC && bytes_read < file_size) {
|
||||||
|
// Calculate the LBA of the current cluster
|
||||||
|
uint32_t lba = cluster_to_lba(current_cluster, &boot_sector);
|
||||||
|
|
||||||
|
// Read the cluster (sector) into the buffer
|
||||||
|
disk_read(lba, buf_ptr, SECTOR_SIZE);
|
||||||
|
|
||||||
|
buf_ptr += SECTOR_SIZE;
|
||||||
|
bytes_read += SECTOR_SIZE;
|
||||||
|
|
||||||
|
// Get the next cluster in the FAT chain
|
||||||
|
current_cluster = fat12_get_next_cluster(current_cluster, &boot_sector);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we don’t read beyond the file size
|
||||||
|
if (bytes_read > file_size) {
|
||||||
|
bytes_read = file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes_read; // Return the number of bytes read
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static fat12_boot_sector_t boot_sector;
|
||||||
|
static fat12_dir_entry_t root_directory[ROOT_DIR_ENTRIES];
|
||||||
|
|
||||||
|
// FAT12 Initialization (called during filesystem mount)
|
||||||
|
int fat12_init(void) {
|
||||||
|
// Read boot sector
|
||||||
|
if (disk_read(0, &boot_sector, sizeof(fat12_boot_sector_t)) != 0) {
|
||||||
|
printf("Failed to read boot sector\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for FAT12 signature
|
||||||
|
if (*(uint16_t *)((char *)&boot_sector + 510) != FAT12_SIGNATURE) {
|
||||||
|
printf("Invalid FAT12 filesystem\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("FAT12 filesystem successfully mounted\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reads the root directory
|
||||||
|
int fat12_read_root_directory(void) {
|
||||||
|
uint32_t root_dir_lba = (boot_sector.reserved_sectors + boot_sector.num_fats * boot_sector.fat_size_16) * boot_sector.bytes_per_sector;
|
||||||
|
|
||||||
|
if (disk_read(root_dir_lba, root_directory, sizeof(root_directory)) != 0) {
|
||||||
|
printf("Failed to read root directory\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Root directory loaded\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a file by name in the root directory
|
||||||
|
int fat12_find_file(const char *filename, fat12_dir_entry_t *entry) {
|
||||||
|
for (int i = 0; i < ROOT_DIR_ENTRIES; i++) {
|
||||||
|
if (strncmp(root_directory[i].filename, filename, 8) == 0) {
|
||||||
|
*entry = root_directory[i];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("File not found\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
31
EYOSx86-main/src/impl/x86_64/driver/fs.c
Normal file
31
EYOSx86-main/src/impl/x86_64/driver/fs.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "fat12.h"
|
||||||
|
#include "disk_io.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
void fs_mount() {
|
||||||
|
// Load FAT12 boot sector
|
||||||
|
fat12_boot_sector_t boot_sector;
|
||||||
|
disk_read(0, &boot_sector, sizeof(boot_sector));
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize FAT12
|
||||||
|
fat12_init();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void fs_read_file(const char *filename) {
|
||||||
|
|
||||||
|
// Find file in FAT12 root directory and read its contents
|
||||||
|
fat12_dir_entry_t dir_entry;
|
||||||
|
|
||||||
|
fat12_find_file(filename, &dir_entry);
|
||||||
|
|
||||||
|
// Read file data
|
||||||
|
uint8_t buffer[dir_entry.file_size];
|
||||||
|
fat12_read_file(&dir_entry, buffer);
|
||||||
|
|
||||||
|
// Print or process the data
|
||||||
|
printf(buffer);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
196
EYOSx86-main/src/impl/x86_64/driver/idt.c
Normal file
196
EYOSx86-main/src/impl/x86_64/driver/idt.c
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "idt.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "vga.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define IDT_ENTRIES 256
|
||||||
|
// Declare the IDT and IDT pointer as external symbols
|
||||||
|
struct idt_entry_t idt[IDT_ENTRIES]; // Assuming 256 entries
|
||||||
|
struct idt_ptr_t idt_ptr;
|
||||||
|
|
||||||
|
|
||||||
|
// Declare ISRs implemented in assembly
|
||||||
|
extern void isr0();
|
||||||
|
extern void isr1();
|
||||||
|
extern void isr2();
|
||||||
|
extern void isr3();
|
||||||
|
extern void isr4();
|
||||||
|
extern void isr5();
|
||||||
|
extern void isr6();
|
||||||
|
extern void isr7();
|
||||||
|
extern void isr8();
|
||||||
|
extern void isr9();
|
||||||
|
extern void isr10();
|
||||||
|
extern void isr11();
|
||||||
|
extern void isr12();
|
||||||
|
extern void isr13();
|
||||||
|
extern void isr14();
|
||||||
|
extern void isr15();
|
||||||
|
extern void isr16();
|
||||||
|
extern void isr17();
|
||||||
|
extern void isr18();
|
||||||
|
extern void isr19();
|
||||||
|
extern void isr20();
|
||||||
|
// Continue up to the required number of ISRs
|
||||||
|
|
||||||
|
|
||||||
|
// IDT entry setup for 64-bit mode
|
||||||
|
void setup_idt_entry(int index, void (*handler)(), uint16_t selector, uint8_t type_attr) {
|
||||||
|
uint64_t handler_addr = (uint64_t)handler;
|
||||||
|
|
||||||
|
idt[index].offset_low = handler_addr & 0xFFFF; // Lower 16 bits of handler function address
|
||||||
|
idt[index].selector = selector; // Segment selector (kernel code segment)
|
||||||
|
idt[index].ist = 0; // Interrupt Stack Table (IST)
|
||||||
|
idt[index].type_attr = type_attr; // Type and attributes (P, DPL, S, Type)
|
||||||
|
idt[index].offset_mid = (handler_addr >> 16) & 0xFFFF; // Middle 16 bits of handler address
|
||||||
|
idt[index].offset_high = (handler_addr >> 32) & 0xFFFFFFFF; // Higher 32 bits of handler address (for 64-bit)
|
||||||
|
idt[index].zero = 0; // Reserved (set to 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the IDT
|
||||||
|
void init_idt() {
|
||||||
|
// Setup each IDT entry
|
||||||
|
setup_idt_entry(0, isr0, 0x08, 0x8E); // Divide-by-zero
|
||||||
|
setup_idt_entry(1, isr1, 0x08, 0x8E); // Debug
|
||||||
|
setup_idt_entry(2, isr2, 0x08, 0x8E); // Non-maskable interrupt
|
||||||
|
setup_idt_entry(3, isr3, 0x08, 0x8E); // Breakpoint
|
||||||
|
setup_idt_entry(4, isr4, 0x08, 0x8E); // Overflow
|
||||||
|
setup_idt_entry(5, isr5, 0x08, 0x8E); // Bound Range Exceeded
|
||||||
|
setup_idt_entry(6, isr6, 0x08, 0x8E); // Invalid Opcode
|
||||||
|
setup_idt_entry(7, isr7, 0x08, 0x8E); // Device Not Available
|
||||||
|
setup_idt_entry(8, isr8, 0x08, 0x8E); // Double Fault
|
||||||
|
setup_idt_entry(9, isr9, 0x08, 0x8E); // Coprocessor Segment Overrun
|
||||||
|
setup_idt_entry(10, isr10, 0x08, 0x8E); // Invalid TSS
|
||||||
|
setup_idt_entry(11, isr11, 0x08, 0x8E); // Segment Not Present
|
||||||
|
setup_idt_entry(12, isr12, 0x08, 0x8E); // Stack-Segment Fault
|
||||||
|
setup_idt_entry(13, isr13, 0x08, 0x8E); // General Protection Fault
|
||||||
|
setup_idt_entry(14, isr14, 0x08, 0x8E); // Page Fault
|
||||||
|
setup_idt_entry(15, isr15, 0x08, 0x8E); // Reserved
|
||||||
|
setup_idt_entry(16, isr16, 0x08, 0x8E); // x87 FPU Floating-Point Error
|
||||||
|
setup_idt_entry(17, isr17, 0x08, 0x8E); // Alignment Check
|
||||||
|
setup_idt_entry(18, isr18, 0x08, 0x8E); // Machine Check
|
||||||
|
setup_idt_entry(19, isr19, 0x08, 0x8E); // SIMD Floating-Point Exception
|
||||||
|
setup_idt_entry(20, isr20, 0x08, 0x8E); // Virtualization Exception
|
||||||
|
// Additional Reserved Entries as needed, or continue with ISR setup
|
||||||
|
|
||||||
|
// Load the IDT
|
||||||
|
// IDT pointer setup
|
||||||
|
idt_ptr.limit = sizeof(idt) - 1;
|
||||||
|
idt_ptr.base = (uint64_t)&idt;
|
||||||
|
|
||||||
|
// Load the IDT with the lidt instruction
|
||||||
|
__asm__ volatile ("lidt %0" : : "m"(idt_ptr));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void isr_common_handler(uint32_t isr_number) {
|
||||||
|
printf("Interrupt received: ");
|
||||||
|
printf("IDT: %d", isr_number); // To verify if the correct ISR is triggered
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
|
||||||
|
kpanic(isr_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Define kpanic to handle panic with BSOD and error messages
|
||||||
|
void kpanic(int error_code) {
|
||||||
|
// Set the background color to blue and text color to white
|
||||||
|
print_set_color(PRINT_COLOR_BLUE, PRINT_COLOR_BLUE);
|
||||||
|
move_print_cursor(0, 0);
|
||||||
|
|
||||||
|
// Fill the entire screen with the background color
|
||||||
|
for (int y = 0; y < 25; y++) { // Replace SCREEN_HEIGHT with the actual screen height
|
||||||
|
for (int x = 0; x < 80; x++) { // Replace SCREEN_WIDTH with the actual screen width
|
||||||
|
print_char(' '); // Print a space to fill the background
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the text color to white and background color to blue
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLUE);
|
||||||
|
move_print_cursor(0, 0);
|
||||||
|
|
||||||
|
// Print the text in the top left corner
|
||||||
|
print_str(" _ \n");
|
||||||
|
print_str(" / )\n");
|
||||||
|
print_str(" _ / / \n");
|
||||||
|
print_str(" (_)( ( \n");
|
||||||
|
print_str(" | | \n");
|
||||||
|
print_str(" _ ( ( \n");
|
||||||
|
print_str(" (_) \\ \\ \n");
|
||||||
|
print_str(" \\_)\n");
|
||||||
|
print_str("\n\n\n");
|
||||||
|
print_str(" KERNEL PANIC\n\n");
|
||||||
|
print_str(" ");
|
||||||
|
|
||||||
|
|
||||||
|
switch (error_code) {
|
||||||
|
case ERROR_DIVIDE_BY_ZERO:
|
||||||
|
print_str("Error: Divide-by-Zero Exception\n");
|
||||||
|
break;
|
||||||
|
case ERROR_DEBUG:
|
||||||
|
print_str("Error: Debug Exception\n");
|
||||||
|
break;
|
||||||
|
case ERROR_NMI:
|
||||||
|
print_str("Error: Non-Maskable Interrupt\n");
|
||||||
|
break;
|
||||||
|
case ERROR_BREAKPOINT:
|
||||||
|
print_str("Error: Breakpoint Exception\n");
|
||||||
|
break;
|
||||||
|
case ERROR_OVERFLOW:
|
||||||
|
print_str("Error: Overflow Exception\n");
|
||||||
|
break;
|
||||||
|
case ERROR_BOUND:
|
||||||
|
print_str("Error: Bound Range Exceeded\n");
|
||||||
|
break;
|
||||||
|
case ERROR_INVALID_OP:
|
||||||
|
print_str("Error: Invalid Opcode\n");
|
||||||
|
break;
|
||||||
|
case ERROR_DEVICE_NOT_AVAIL:
|
||||||
|
print_str("Error: Device Not Available\n");
|
||||||
|
break;
|
||||||
|
case ERROR_DOUBLE_FAULT:
|
||||||
|
print_str("Error: Double Fault\n");
|
||||||
|
break;
|
||||||
|
case ERROR_COPROCESSOR_OVERRUN:
|
||||||
|
print_str("Error: Coprocessor Segment Overrun\n");
|
||||||
|
break;
|
||||||
|
case ERROR_INVALID_TSS:
|
||||||
|
print_str("Error: Invalid TSS\n");
|
||||||
|
break;
|
||||||
|
case ERROR_SEGMENT_NOT_PRESENT:
|
||||||
|
print_str("Error: Segment Not Present\n");
|
||||||
|
break;
|
||||||
|
case ERROR_STACK_SEGMENT:
|
||||||
|
print_str("Error: Stack-Segment Fault\n");
|
||||||
|
break;
|
||||||
|
case ERROR_GENERAL_PROTECTION:
|
||||||
|
print_str("Error: General Protection Fault\n");
|
||||||
|
break;
|
||||||
|
case ERROR_PAGE_FAULT:
|
||||||
|
print_str("Error: Page Fault\n");
|
||||||
|
break;
|
||||||
|
case FILESYSTEM_ERROR:
|
||||||
|
print_str("Error: Filesystem Error\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Error: Unknown Exception '%d'\n", error_code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Halt the system
|
||||||
|
while (1) {}
|
||||||
|
}
|
||||||
|
void idt_install() {
|
||||||
|
print_set_color(PRINT_COLOR_LIGHT_GRAY, PRINT_COLOR_BLACK);
|
||||||
|
print_str("[ init ] IDT\n");
|
||||||
|
init_idt();
|
||||||
|
printf("IDT Base: %p\n", (void*)idt_ptr.base); // For pointer
|
||||||
|
printf("IDT Limit: %x\n", idt_ptr.limit); // Assuming limit is small enough for %x
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK);
|
||||||
|
print_str("[ OK ] IDT\n");
|
||||||
|
}
|
15
EYOSx86-main/src/impl/x86_64/driver/io.c
Normal file
15
EYOSx86-main/src/impl/x86_64/driver/io.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// io.c
|
||||||
|
|
||||||
|
#include "io.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
|
||||||
|
void outb(uint16_t port, uint8_t value) {
|
||||||
|
asm volatile ("outb %0, %1" : : "a"(value), "Nd"(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t inb(uint16_t port) {
|
||||||
|
uint8_t value;
|
||||||
|
asm volatile ("inb %1, %0" : "=a"(value) : "Nd"(port));
|
||||||
|
return value;
|
||||||
|
}
|
1
EYOSx86-main/src/impl/x86_64/driver/irs.c
Normal file
1
EYOSx86-main/src/impl/x86_64/driver/irs.c
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
152
EYOSx86-main/src/impl/x86_64/driver/keydriver.c
Normal file
152
EYOSx86-main/src/impl/x86_64/driver/keydriver.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include "keydriver.h"
|
||||||
|
#include "print.h" // Make sure you have a print function available
|
||||||
|
|
||||||
|
|
||||||
|
// Define the keyboard buffer and index
|
||||||
|
static char keyboard_buffer[KEYBOARD_BUFFER_SIZE];
|
||||||
|
static unsigned int buffer_index = 0;
|
||||||
|
static int shift_pressed = 0;
|
||||||
|
|
||||||
|
// Updated ASCII conversion table (scan code to ASCII)
|
||||||
|
const char ascii_table[128] =
|
||||||
|
{
|
||||||
|
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', // 9
|
||||||
|
'9', '0', '-', '=', '\b', // Backspace
|
||||||
|
'\t', // Tab
|
||||||
|
'q', 'w', 'e', 'r', // 19
|
||||||
|
't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', // Enter key
|
||||||
|
0, // 29 - Control
|
||||||
|
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 39
|
||||||
|
'\'', '`', 0, // Left shift
|
||||||
|
'\\', 'z', 'x', 'c', 'v', 'b', 'n', // 49
|
||||||
|
'm', ',', '.', '/', 0, // Right shift
|
||||||
|
'*',
|
||||||
|
0, // Alt
|
||||||
|
' ', // Space bar
|
||||||
|
0, // Caps lock
|
||||||
|
0, // 59 - F1 key ... >
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, // < ... F10
|
||||||
|
0, // 69 - Num lock
|
||||||
|
0, // Scroll Lock
|
||||||
|
0, // Home key
|
||||||
|
0, // Up Arrow
|
||||||
|
0, // Page Up
|
||||||
|
'-',
|
||||||
|
0, // Left Arrow
|
||||||
|
0,
|
||||||
|
0, // Right Arrow
|
||||||
|
'+',
|
||||||
|
0, // 79 - End key
|
||||||
|
0, // Down Arrow
|
||||||
|
0, // Page Down
|
||||||
|
0, // Insert Key
|
||||||
|
0, // Delete Key
|
||||||
|
0, 0, 0,
|
||||||
|
0, // F11 Key
|
||||||
|
0, // F12 Key
|
||||||
|
0, // All other keys are undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
// Uppercase ASCII conversion table (shift key pressed)
|
||||||
|
const char shift_ascii_table[128] =
|
||||||
|
{
|
||||||
|
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', // 9
|
||||||
|
'(', ')', '_', '+', '\b', // Backspace
|
||||||
|
'\t', // Tab
|
||||||
|
'Q', 'W', 'E', 'R', // 19
|
||||||
|
'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', // Enter key
|
||||||
|
0, // 29 - Control
|
||||||
|
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 39
|
||||||
|
'"', '~', 0, // Left shift
|
||||||
|
'|', 'Z', 'X', 'C', 'V', 'B', 'N', // 49
|
||||||
|
'M', '<', '>', '?', 0, // Right shift
|
||||||
|
'*',
|
||||||
|
0, // Alt
|
||||||
|
' ', // Space
|
||||||
|
0, // Caps lock
|
||||||
|
0, // 59 - F1 key ... >
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, // < ... F10
|
||||||
|
0, // 69 - Num lock
|
||||||
|
0, // Scroll Lock
|
||||||
|
0, // Home key
|
||||||
|
0, // Up Arrow
|
||||||
|
0, // Page Up
|
||||||
|
'-',
|
||||||
|
0, // Left Arrow
|
||||||
|
0,
|
||||||
|
0, // Right Arrow
|
||||||
|
'+',
|
||||||
|
0, // 79 - End key
|
||||||
|
0, // Down Arrow
|
||||||
|
0, // Page Down
|
||||||
|
0, // Insert Key
|
||||||
|
0, // Delete Key
|
||||||
|
0, 0, 0,
|
||||||
|
0, // F11 Key
|
||||||
|
0, // F12 Key
|
||||||
|
0, // All other keys
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize the keyboard driver
|
||||||
|
void init_keyboard_driver() {
|
||||||
|
print_set_color(PRINT_COLOR_LIGHT_GRAY, PRINT_COLOR_BLACK);
|
||||||
|
print_str("[ init ] KEYDRIVER\n");
|
||||||
|
|
||||||
|
buffer_index = 0;
|
||||||
|
shift_pressed = 0;
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK);
|
||||||
|
print_str("[ OK ] KEYDRIVER\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a single character from the keyboard
|
||||||
|
char read_key() {
|
||||||
|
char key = 0;
|
||||||
|
|
||||||
|
// Read a key from port 0x60
|
||||||
|
__asm__("inb $0x60, %0" : "=a"(key));
|
||||||
|
|
||||||
|
// Check for key release (scan codes 0x80 and above are typically releases)
|
||||||
|
if (key & 0x80) {
|
||||||
|
// Handle key release
|
||||||
|
key &= 0x7F; // Remove the high bit to get the original scan code
|
||||||
|
if (key == 0x2A || key == 0x36) { // Left or right shift
|
||||||
|
shift_pressed = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// Handle key press
|
||||||
|
if (key == 0x2A || key == 0x36) { // Left or right shift
|
||||||
|
shift_pressed = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert scan code to ASCII
|
||||||
|
if (key < 128) {
|
||||||
|
if (shift_pressed) {
|
||||||
|
key = shift_ascii_table[(unsigned char)key];
|
||||||
|
} else {
|
||||||
|
key = ascii_table[(unsigned char)key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the key in the buffer if there's space
|
||||||
|
if (buffer_index < KEYBOARD_BUFFER_SIZE) {
|
||||||
|
keyboard_buffer[buffer_index++] = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current buffer index
|
||||||
|
unsigned int get_buffer_index() {
|
||||||
|
return buffer_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the contents of the keyboard buffer
|
||||||
|
const char* get_keyboard_buffer() {
|
||||||
|
return keyboard_buffer;
|
||||||
|
}
|
116
EYOSx86-main/src/impl/x86_64/driver/memory.c
Normal file
116
EYOSx86-main/src/impl/x86_64/driver/memory.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include "memory.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "print.h"
|
||||||
|
#define MEMORY_POOL_SIZE 0xFFFFF // Define the size of the memory pool
|
||||||
|
static uint8_t memory_pool[MEMORY_POOL_SIZE]; // Static memory pool
|
||||||
|
static uint8_t* memory_pool_end = memory_pool; // Pointer to the end of allocated memory
|
||||||
|
|
||||||
|
// Block header to store size and free status
|
||||||
|
typedef struct block_header {
|
||||||
|
size_t size;
|
||||||
|
struct block_header* next; // For linking free blocks
|
||||||
|
int is_free;
|
||||||
|
} block_header_t;
|
||||||
|
|
||||||
|
#define HEADER_SIZE sizeof(block_header_t)
|
||||||
|
|
||||||
|
static block_header_t* free_list = NULL; // Head of the free list
|
||||||
|
|
||||||
|
// Custom malloc implementation with block headers
|
||||||
|
void* malloc(size_t size) {
|
||||||
|
size = (size + 3) & ~3; // Align size to 4 bytes
|
||||||
|
|
||||||
|
// First, check the free list for a suitable block
|
||||||
|
block_header_t* current = free_list;
|
||||||
|
block_header_t* prev = NULL;
|
||||||
|
|
||||||
|
while (current) {
|
||||||
|
if (current->is_free && current->size >= size) {
|
||||||
|
current->is_free = 0; // Mark as used
|
||||||
|
return (void*)((uint8_t*)current + HEADER_SIZE); // Return memory after header
|
||||||
|
}
|
||||||
|
prev = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No suitable block found in free list, allocate new memory from pool
|
||||||
|
if ((memory_pool_end + size + HEADER_SIZE) > (memory_pool + MEMORY_POOL_SIZE)) {
|
||||||
|
printf("Failed to allocate memory! Requested: %u bytes\n", size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
block_header_t* header = (block_header_t*)memory_pool_end;
|
||||||
|
header->size = size;
|
||||||
|
header->is_free = 0;
|
||||||
|
header->next = NULL;
|
||||||
|
|
||||||
|
memory_pool_end += size + HEADER_SIZE;
|
||||||
|
|
||||||
|
return (void*)((uint8_t*)header + HEADER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom free implementation to add block back to the free list
|
||||||
|
void free(void* ptr) {
|
||||||
|
if (!ptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the block header before the allocated memory
|
||||||
|
block_header_t* header = (block_header_t*)((uint8_t*)ptr - HEADER_SIZE);
|
||||||
|
header->is_free = 1;
|
||||||
|
|
||||||
|
// Add the block to the free list
|
||||||
|
header->next = free_list;
|
||||||
|
free_list = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void list_used_blocks() {
|
||||||
|
uint8_t* current_ptr = memory_pool;
|
||||||
|
|
||||||
|
printf("Listing all used blocks:\n");
|
||||||
|
|
||||||
|
// Traverse the memory pool and print each block's information
|
||||||
|
while (current_ptr < memory_pool_end) {
|
||||||
|
block_header_t* header = (block_header_t*)current_ptr;
|
||||||
|
if (!header->is_free) {
|
||||||
|
printf("Used block at %p | Size: %u bytes\n", (void*)(current_ptr + HEADER_SIZE), header->size);
|
||||||
|
}
|
||||||
|
current_ptr += HEADER_SIZE + header->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("End of used blocks.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void* memcpy(void* dst, const void* src, uint16_t num) {
|
||||||
|
uint8_t* d = (uint8_t*)dst;
|
||||||
|
const uint8_t* s = (const uint8_t*)src;
|
||||||
|
while (num--) {
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void* ptr, int value, uint16_t num) {
|
||||||
|
uint8_t* p = (uint8_t*)ptr;
|
||||||
|
while (num--) {
|
||||||
|
*p++ = (uint8_t)value;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void* ptr1, const void* ptr2, uint16_t num) {
|
||||||
|
const uint8_t* p1 = (const uint8_t*)ptr1;
|
||||||
|
const uint8_t* p2 = (const uint8_t*)ptr2;
|
||||||
|
while (num--) {
|
||||||
|
if (*p1 != *p2) {
|
||||||
|
return *p1 - *p2;
|
||||||
|
}
|
||||||
|
p1++;
|
||||||
|
p2++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
343
EYOSx86-main/src/impl/x86_64/driver/print.c
Normal file
343
EYOSx86-main/src/impl/x86_64/driver/print.c
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
#include "print.h"
|
||||||
|
#include "vga.h"
|
||||||
|
|
||||||
|
|
||||||
|
const static size_t NUM_COLS = 80;
|
||||||
|
const static size_t NUM_ROWS = 25;
|
||||||
|
|
||||||
|
struct Char {
|
||||||
|
uint8_t character;
|
||||||
|
uint8_t color;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct Char* buffer = (struct Char*) 0xb8000;
|
||||||
|
size_t col = 0;
|
||||||
|
size_t row = 0;
|
||||||
|
uint8_t color = PRINT_COLOR_WHITE | PRINT_COLOR_BLACK << 4;
|
||||||
|
|
||||||
|
void clear_row(size_t row) {
|
||||||
|
struct Char empty = (struct Char) {
|
||||||
|
character: ' ',
|
||||||
|
color: color,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t col = 0; col < NUM_COLS; col++) {
|
||||||
|
buffer[col + NUM_COLS * row] = empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_clear() {
|
||||||
|
for (size_t i = 0; i < NUM_ROWS; i++) {
|
||||||
|
clear_row(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//void print_newline() {
|
||||||
|
// col = 0;
|
||||||
|
//
|
||||||
|
// if (row < NUM_ROWS - 1) {
|
||||||
|
// row++;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (size_t row = 1; row < NUM_ROWS; row++) {
|
||||||
|
// for (size_t col = 0; col < NUM_COLS; col++) {
|
||||||
|
// struct Char character = buffer[col + NUM_COLS * row];
|
||||||
|
// buffer[col + NUM_COLS * (row - 1)] = character;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// clear_row(NUM_COLS - 1);
|
||||||
|
//}
|
||||||
|
|
||||||
|
void print_newline() {
|
||||||
|
row++;
|
||||||
|
col = 0;
|
||||||
|
|
||||||
|
// Check for scrolling
|
||||||
|
if (row >= NUM_ROWS) {
|
||||||
|
row = NUM_ROWS - 1;
|
||||||
|
// Scroll the screen up
|
||||||
|
// Copy lines up
|
||||||
|
// Clear the last line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorPosition get_print_cursor_pos() {
|
||||||
|
CursorPosition pos;
|
||||||
|
pos.x = col; // Use col for x
|
||||||
|
pos.y = row; // Use row for y
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_hex(unsigned int num) {
|
||||||
|
char buffer[9]; // Buffer to hold the hexadecimal string representation
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// Handle zero case
|
||||||
|
if (num == 0) {
|
||||||
|
print_char('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert integer to hexadecimal in reverse order
|
||||||
|
while (num > 0) {
|
||||||
|
int digit = num % 16;
|
||||||
|
if (digit < 10) {
|
||||||
|
buffer[i++] = digit + '0';
|
||||||
|
} else {
|
||||||
|
buffer[i++] = (digit - 10) + 'A';
|
||||||
|
}
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the hexadecimal number in correct order
|
||||||
|
for (int j = i - 1; j >= 0; j--) {
|
||||||
|
print_char(buffer[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_print_cursor(int x, int y) {
|
||||||
|
col = x;
|
||||||
|
row = y;
|
||||||
|
set_cursor_position(col, row); // Move cursor to new position
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void offset_print_cursor(int x, int y) {
|
||||||
|
col += x;
|
||||||
|
row += y;
|
||||||
|
set_cursor_position(col, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to print a single character
|
||||||
|
void print_char(char character) {
|
||||||
|
if (character == '\n') {
|
||||||
|
print_newline();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle wrapping
|
||||||
|
if (col >= NUM_COLS) {
|
||||||
|
print_newline();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the buffer
|
||||||
|
buffer[col + NUM_COLS * row] = (struct Char) {
|
||||||
|
.character = (uint8_t) character,
|
||||||
|
.color = color,
|
||||||
|
};
|
||||||
|
|
||||||
|
col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to print a string
|
||||||
|
void print_str(char* str) {
|
||||||
|
size_t i = 0;
|
||||||
|
while (str[i] != '\0') {
|
||||||
|
print_char(str[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_set_color(uint8_t foreground, uint8_t background) {
|
||||||
|
color = foreground + (background << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_int(int num) {
|
||||||
|
// Handle negative numbers
|
||||||
|
if (num < 0) {
|
||||||
|
print_char('-');
|
||||||
|
num = -num;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert number to string
|
||||||
|
char buffer[11]; // Buffer to hold integer string representation
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (num == 0) {
|
||||||
|
buffer[i++] = '0';
|
||||||
|
} else {
|
||||||
|
while (num > 0) {
|
||||||
|
buffer[i++] = (num % 10) + '0';
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the integer in correct order
|
||||||
|
for (int j = i - 1; j >= 0; j--) {
|
||||||
|
print_char(buffer[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
void print_formatted(const char* format, va_list args) {
|
||||||
|
while (*format) {
|
||||||
|
if (*format == '%') {
|
||||||
|
format++;
|
||||||
|
switch (*format) {
|
||||||
|
case 's': {
|
||||||
|
char* str = va_arg(args, char*);
|
||||||
|
print_str(str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'x': {
|
||||||
|
unsigned int num = va_arg(args, unsigned int);
|
||||||
|
print_hex(num);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'd': {
|
||||||
|
int num = va_arg(args, int);
|
||||||
|
print_int(num);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'c': {
|
||||||
|
char ch = (char) va_arg(args, int); // Promoted to int
|
||||||
|
print_char(ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'u': {
|
||||||
|
unsigned int num = va_arg(args, unsigned int);
|
||||||
|
print_uint(num); // Custom function for unsigned int
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'p': {
|
||||||
|
void* ptr = va_arg(args, void*);
|
||||||
|
print_pointer(ptr); // Custom function for pointers
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'f': {
|
||||||
|
double num = va_arg(args, double);
|
||||||
|
print_float(num); // Custom function for floating-point numbers
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
print_char('%');
|
||||||
|
print_char(*format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print_char(*format);
|
||||||
|
}
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void print_uint(unsigned int num) {
|
||||||
|
// Convert to string and print (implementation required)
|
||||||
|
char buffer[11]; // Enough for 32-bit unsigned int
|
||||||
|
int i = 0;
|
||||||
|
if (num == 0) {
|
||||||
|
print_char('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (num > 0) {
|
||||||
|
buffer[i++] = '0' + (num % 10);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
while (i > 0) {
|
||||||
|
print_char(buffer[--i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void print_pointer(void* ptr) {
|
||||||
|
unsigned long num = (unsigned long) ptr;
|
||||||
|
print_str("0x");
|
||||||
|
print_hex(num); // Assuming print_hex handles long
|
||||||
|
}
|
||||||
|
void print_float(double num) {
|
||||||
|
// Simple implementation of floating-point printing
|
||||||
|
int int_part = (int)num;
|
||||||
|
int frac_part = (int)((num - int_part) * 1000000); // Six decimal places
|
||||||
|
|
||||||
|
print_int(int_part);
|
||||||
|
print_char('.');
|
||||||
|
|
||||||
|
// Ensure fractional part is always printed with six digits
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
print_char('0' + (frac_part % 10));
|
||||||
|
frac_part /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sscanf(const char *str, const char *format, char *filename, char *content) {
|
||||||
|
const char *p = str;
|
||||||
|
char *f = filename;
|
||||||
|
char *c = content;
|
||||||
|
|
||||||
|
while (*format) {
|
||||||
|
if (*format == '%') {
|
||||||
|
format++;
|
||||||
|
if (*format == 's') {
|
||||||
|
// Copy the first string
|
||||||
|
while (*p && *p != ' ' && (f - filename) < MAX_STRING_LENGTH - 1) {
|
||||||
|
*f++ = *p++;
|
||||||
|
}
|
||||||
|
*f = '\0';
|
||||||
|
|
||||||
|
// Skip any whitespace
|
||||||
|
while (*p == ' ') p++;
|
||||||
|
|
||||||
|
// Copy the second string
|
||||||
|
while (*p && (c - content) < MAX_STRING_LENGTH - 1) {
|
||||||
|
*c++ = *p++;
|
||||||
|
}
|
||||||
|
*c = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int my_sscanf(const char *input, const char *format, char *output) {
|
||||||
|
const char *in_ptr = input;
|
||||||
|
const char *fmt_ptr = format;
|
||||||
|
char *out_ptr = output;
|
||||||
|
int match_count = 0;
|
||||||
|
|
||||||
|
// Skip any leading whitespace in the input
|
||||||
|
while (*in_ptr && (*in_ptr == ' ' || *in_ptr == '\t')) {
|
||||||
|
in_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the format string
|
||||||
|
while (*fmt_ptr) {
|
||||||
|
if (*fmt_ptr == '%' && *(fmt_ptr + 1) == 's') {
|
||||||
|
// Found a string specifier
|
||||||
|
fmt_ptr += 2; // Skip %s
|
||||||
|
|
||||||
|
// Copy input string to output until whitespace or end of input
|
||||||
|
while (*in_ptr && *in_ptr != ' ' && *in_ptr != '\t' && *in_ptr != '\n') {
|
||||||
|
*out_ptr++ = *in_ptr++;
|
||||||
|
}
|
||||||
|
*out_ptr = '\0'; // Null-terminate the output string
|
||||||
|
match_count++;
|
||||||
|
} else {
|
||||||
|
// Match literal characters in format string
|
||||||
|
if (*fmt_ptr == *in_ptr) {
|
||||||
|
fmt_ptr++;
|
||||||
|
in_ptr++;
|
||||||
|
} else {
|
||||||
|
// Literal character mismatch
|
||||||
|
return match_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printf(const char* format, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
print_formatted(format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
80
EYOSx86-main/src/impl/x86_64/driver/vector.c
Normal file
80
EYOSx86-main/src/impl/x86_64/driver/vector.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
// Initial capacity for a new vector
|
||||||
|
#define VECTOR_INITIAL_CAPACITY 4
|
||||||
|
|
||||||
|
// Create a new vector
|
||||||
|
vector* vector_create() {
|
||||||
|
vector* v = (vector*)malloc(sizeof(vector));
|
||||||
|
if (!v) return NULL; // Return NULL if allocation fails
|
||||||
|
|
||||||
|
v->capacity = VECTOR_INITIAL_CAPACITY;
|
||||||
|
v->size = 0;
|
||||||
|
v->items = (void**)malloc(sizeof(void*) * v->capacity);
|
||||||
|
if (!v->items) {
|
||||||
|
free(v); // Free the vector if item allocation fails
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy the vector and free allocated memory
|
||||||
|
void vector_destroy(vector* v) {
|
||||||
|
if (v) {
|
||||||
|
free(v->items);
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push an item to the back of the vector
|
||||||
|
int vector_push_back(vector* v, void* item) {
|
||||||
|
// Resize the vector if it's full
|
||||||
|
if (v->size == v->capacity) {
|
||||||
|
if (vector_resize(v, v->capacity * 2) != 0) {
|
||||||
|
return -1; // Return -1 on failure to resize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v->items[v->size++] = item; // Add the new item
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the item at a specific index
|
||||||
|
void* vector_get(vector* v, size_t index) {
|
||||||
|
if (index >= v->size) return NULL; // Return NULL if index is out of bounds
|
||||||
|
return v->items[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set an item at a specific index
|
||||||
|
int vector_set(vector* v, size_t index, void* item) {
|
||||||
|
if (index >= v->size) return -1; // Return -1 if index is out of bounds
|
||||||
|
v->items[index] = item;
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the size of the vector
|
||||||
|
size_t vector_size(vector* v) {
|
||||||
|
return v->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize the vector's internal array
|
||||||
|
int vector_resize(vector* v, size_t new_capacity) {
|
||||||
|
// Allocate new memory for the resized array
|
||||||
|
void** new_items = (void**)malloc(sizeof(void*) * new_capacity);
|
||||||
|
if (!new_items) return -1; // Return -1 on failure
|
||||||
|
|
||||||
|
// Copy the old items into the new array
|
||||||
|
for (size_t i = 0; i < v->size; i++) {
|
||||||
|
new_items[i] = v->items[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the old memory
|
||||||
|
free(v->items);
|
||||||
|
|
||||||
|
// Update the vector's internal state
|
||||||
|
v->items = new_items;
|
||||||
|
v->capacity = new_capacity;
|
||||||
|
|
||||||
|
return 0; // Success
|
||||||
|
}
|
29
EYOSx86-main/src/impl/x86_64/driver/vga.c
Normal file
29
EYOSx86-main/src/impl/x86_64/driver/vga.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "vga.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define VGA_PORT_INDEX 0x3D4
|
||||||
|
#define VGA_PORT_DATA 0x3D5
|
||||||
|
|
||||||
|
|
||||||
|
void move_cursor(int x, int y) {
|
||||||
|
uint16_t position = y * 80 + x; // Assuming 80 columns
|
||||||
|
outb(0x3D4, 0x0E); // VGA register for high byte
|
||||||
|
outb(0x3D5, (position >> 8) & 0xFF);
|
||||||
|
outb(0x3D4, 0x0F); // VGA register for low byte
|
||||||
|
outb(0x3D5, position & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void set_cursor_position(int x, int y) {
|
||||||
|
uint16_t position = y * 80 + x; // 80 columns in VGA text mode
|
||||||
|
outb(VGA_PORT_INDEX, 0x0E);
|
||||||
|
outb(VGA_PORT_DATA, (position >> 8) & 0xFF);
|
||||||
|
outb(VGA_PORT_INDEX, 0x0F);
|
||||||
|
outb(VGA_PORT_DATA, position & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
185
EYOSx86-main/src/impl/x86_64/game.c
Normal file
185
EYOSx86-main/src/impl/x86_64/game.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
#include "game.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "keydriver.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
// Define constants for the game
|
||||||
|
#define ROOM_COUNT 5
|
||||||
|
#define INVENTORY_SIZE 5
|
||||||
|
|
||||||
|
// Global variable to hold the game state
|
||||||
|
static GameState game_state;
|
||||||
|
|
||||||
|
// Room descriptions and connected rooms
|
||||||
|
typedef struct {
|
||||||
|
const char* description;
|
||||||
|
int north;
|
||||||
|
int south;
|
||||||
|
int east;
|
||||||
|
int west;
|
||||||
|
} Room;
|
||||||
|
|
||||||
|
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 on a beach. There is a cave to the west.", -1, 0, -1, 3 },
|
||||||
|
{ "You are inside a cave. It’s 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 shop filled with various items. The village is to the south.", -1, 3, -1, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Player's inventory
|
||||||
|
static const char* inventory[INVENTORY_SIZE];
|
||||||
|
static int inventory_count = 0;
|
||||||
|
|
||||||
|
// Command buffer
|
||||||
|
static char commandBuffer[MAX_COMMAND_LENGTH];
|
||||||
|
static size_t commandLength = 0;
|
||||||
|
|
||||||
|
bool keydown = false;
|
||||||
|
|
||||||
|
// Function to handle user input commands
|
||||||
|
void handle_command(const char* command) {
|
||||||
|
|
||||||
|
|
||||||
|
game_clear();
|
||||||
|
|
||||||
|
|
||||||
|
if (strcmp(command, "look") == 0) {
|
||||||
|
printf(rooms[game_state.current_room].description);
|
||||||
|
printf("\n");
|
||||||
|
} else if (strcmp(command, "north") == 0) {
|
||||||
|
if (rooms[game_state.current_room].north != -1) {
|
||||||
|
game_state.current_room = rooms[game_state.current_room].north;
|
||||||
|
printf("You walk north.\n");
|
||||||
|
printf("%s\n", rooms[game_state.current_room].description);
|
||||||
|
} else {
|
||||||
|
printf("You can't go that way.\n");
|
||||||
|
}
|
||||||
|
} else if (strcmp(command, "south") == 0) {
|
||||||
|
if (rooms[game_state.current_room].south != -1) {
|
||||||
|
game_state.current_room = rooms[game_state.current_room].south;
|
||||||
|
printf("You walk south.\n");
|
||||||
|
printf("%s\n", rooms[game_state.current_room].description);
|
||||||
|
} else {
|
||||||
|
printf("You can't go that way.\n");
|
||||||
|
}
|
||||||
|
} else if (strcmp(command, "east") == 0) {
|
||||||
|
if (rooms[game_state.current_room].east != -1) {
|
||||||
|
game_state.current_room = rooms[game_state.current_room].east;
|
||||||
|
printf("You walk east.\n");
|
||||||
|
printf("%s\n", rooms[game_state.current_room].description);
|
||||||
|
} else {
|
||||||
|
printf("You can't go that way.\n");
|
||||||
|
}
|
||||||
|
} else if (strcmp(command, "west") == 0) {
|
||||||
|
if (rooms[game_state.current_room].west != -1) {
|
||||||
|
game_state.current_room = rooms[game_state.current_room].west;
|
||||||
|
printf("You walk west.\n");
|
||||||
|
printf("%s\n", rooms[game_state.current_room].description);
|
||||||
|
} else {
|
||||||
|
printf("You can't go that way.\n");
|
||||||
|
}
|
||||||
|
} else if (strcmp(command, "inventory") == 0) {
|
||||||
|
printf("You are carrying:\n");
|
||||||
|
for (int i = 0; i < inventory_count; ++i) {
|
||||||
|
printf("- %s\n", inventory[i]);
|
||||||
|
}
|
||||||
|
if (inventory_count == 0) {
|
||||||
|
printf("Nothing.\n");
|
||||||
|
}
|
||||||
|
} else if (strcmp(command, "take key") == 0) {
|
||||||
|
if (game_state.current_room == 1) {
|
||||||
|
if (inventory_count < INVENTORY_SIZE) {
|
||||||
|
inventory[inventory_count++] = "key";
|
||||||
|
printf("You picked up a key.\n");
|
||||||
|
} else {
|
||||||
|
printf("Your inventory is full.\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("There is no key here.\n");
|
||||||
|
}
|
||||||
|
} else if (strcmp(command, "use key") == 0) {
|
||||||
|
bool has_key = false;
|
||||||
|
for (int i = 0; i < inventory_count; ++i) {
|
||||||
|
if (strcmp(inventory[i], "key") == 0) {
|
||||||
|
has_key = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (has_key && game_state.current_room == 2) {
|
||||||
|
printf("You unlock the door in the cave and find a treasure!\n");
|
||||||
|
game_state.game_active = false; // End the game
|
||||||
|
} else {
|
||||||
|
printf("You can't use the key here.\n");
|
||||||
|
}
|
||||||
|
} else if (strcmp(command, "quit") == 0) {
|
||||||
|
printf("You quit the game.\n");
|
||||||
|
game_state.game_active = false;
|
||||||
|
} else {
|
||||||
|
printf("Unknown command.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to print the prompt for the player
|
||||||
|
void print_prompt() {
|
||||||
|
printf(" > ");
|
||||||
|
}
|
||||||
|
|
||||||
|
const void game_clear()
|
||||||
|
{
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
||||||
|
|
||||||
|
move_print_cursor(0, 0);
|
||||||
|
move_cursor(0, 0);
|
||||||
|
print_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to initialize and run the game
|
||||||
|
void create_game() {
|
||||||
|
// Initialize the game state
|
||||||
|
game_state.current_room = 0;
|
||||||
|
game_state.game_active = true;
|
||||||
|
|
||||||
|
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("You can 'take key' or 'use key' in the appropriate places.\n");
|
||||||
|
|
||||||
|
print_prompt();
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (game_state.game_active) {
|
||||||
|
char key = read_key(); // Get key input
|
||||||
|
|
||||||
|
if (key != 0) {
|
||||||
|
if (!keydown) {
|
||||||
|
if (key == 10) { // Enter key
|
||||||
|
printf("\n");
|
||||||
|
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
||||||
|
handle_command(commandBuffer); // Process the command
|
||||||
|
commandLength = 0; // Reset command buffer
|
||||||
|
if (game_state.game_active) {
|
||||||
|
print_prompt(); // Print prompt for the next command
|
||||||
|
}
|
||||||
|
} else if (key == 8) { // Backspace key
|
||||||
|
if (commandLength > 0) {
|
||||||
|
commandLength--;
|
||||||
|
offset_print_cursor(-1, 0);
|
||||||
|
print_char(' '); // Overwrite the character
|
||||||
|
offset_print_cursor(-1, 0);
|
||||||
|
}
|
||||||
|
} else if (key >= 32 && key <= 126) { // Printable characters
|
||||||
|
if (commandLength < MAX_COMMAND_LENGTH - 1) {
|
||||||
|
commandBuffer[commandLength++] = key;
|
||||||
|
print_char(key); // Display the key on the screen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keydown = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keydown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Thanks for playing!\n");
|
||||||
|
}
|
127
EYOSx86-main/src/impl/x86_64/stdopt.c
Normal file
127
EYOSx86-main/src/impl/x86_64/stdopt.c
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "strings.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
|
||||||
|
void prepend(uint8_t* array, uint8_t c) {
|
||||||
|
// Ensure that size is within bounds and there's space to prepend
|
||||||
|
|
||||||
|
int size = sizeof(array);
|
||||||
|
|
||||||
|
// Shift all elements to the right
|
||||||
|
for (int i = size; i > 0; i--) {
|
||||||
|
array[i] = array[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the new character at the beginning
|
||||||
|
array[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(uint8_t* array, uint8_t c) {
|
||||||
|
// Ensure that size is within bounds and there's space to append
|
||||||
|
int size = sizeof(array);
|
||||||
|
|
||||||
|
// Insert the new character at the end
|
||||||
|
array[size] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void append_first(uint8_t* array, uint8_t c) {
|
||||||
|
// Shift all elements to the right
|
||||||
|
int size = sizeof(array);
|
||||||
|
for (int i = size - 1; i > 0; i--) {
|
||||||
|
array[i] = array[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the new character at the beginning
|
||||||
|
array[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void append_last(uint8_t* array, uint8_t c) {
|
||||||
|
int size = sizeof(array);
|
||||||
|
// Shift all elements to the left
|
||||||
|
|
||||||
|
for (int i = 0; i < size - 1; i++) {
|
||||||
|
array[i] = array[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the new character at the end
|
||||||
|
array[0] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char** split_string(const char* str, char delimiter) {
|
||||||
|
if (str == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of tokens
|
||||||
|
int* num_tokens = 1;
|
||||||
|
for (const char* p = str; *p; ++p) {
|
||||||
|
if (*p == delimiter) {
|
||||||
|
(*num_tokens)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Tokens: %d", num_tokens);
|
||||||
|
|
||||||
|
// Allocate memory for the array of char*
|
||||||
|
char** tokens = (char**)malloc((*num_tokens + 1) * sizeof(char*)); // +1 for NULL terminator
|
||||||
|
if (tokens == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for each token and split the string
|
||||||
|
size_t start = 0;
|
||||||
|
size_t end = 0;
|
||||||
|
int index = 0;
|
||||||
|
while (str[end] != '\0') {
|
||||||
|
if (str[end] == delimiter) {
|
||||||
|
size_t length = end - start;
|
||||||
|
tokens[index] = (char*)malloc((length + 1) * sizeof(char)); // +1 for null terminator
|
||||||
|
if (tokens[index] == NULL) {
|
||||||
|
// Free previously allocated memory in case of failure
|
||||||
|
for (int i = 0; i < index; i++) {
|
||||||
|
free(tokens[i]);
|
||||||
|
}
|
||||||
|
free(tokens);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strncpy(tokens[index], &str[start], length);
|
||||||
|
tokens[index][length] = '\0';
|
||||||
|
index++;
|
||||||
|
start = end + 1;
|
||||||
|
}
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the last token
|
||||||
|
size_t length = end - start;
|
||||||
|
tokens[index] = (char*)malloc((length + 1) * sizeof(char)); // +1 for null terminator
|
||||||
|
if (tokens[index] == NULL) {
|
||||||
|
// Free previously allocated memory in case of failure
|
||||||
|
for (int i = 0; i < index; i++) {
|
||||||
|
free(tokens[i]);
|
||||||
|
}
|
||||||
|
free(tokens);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strncpy(tokens[index], &str[start], length);
|
||||||
|
tokens[index][length] = '\0';
|
||||||
|
tokens[index + 1] = NULL; // Null-terminate the array
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to free the memory allocated for the array of strings
|
||||||
|
void free_split_strings(char** tokens, int num_tokens) {
|
||||||
|
if (tokens == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < num_tokens; i++) {
|
||||||
|
free(tokens[i]);
|
||||||
|
}
|
||||||
|
free(tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
92
EYOSx86-main/src/impl/x86_64/strings.c
Normal file
92
EYOSx86-main/src/impl/x86_64/strings.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "strings.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
int int_strncmp(const char* s1, const char* s2, size_t n) {
|
||||||
|
while (n > 0) {
|
||||||
|
if (*s1 != *s2) {
|
||||||
|
return (uint8_t)*s1 - (uint8_t)*s2;
|
||||||
|
}
|
||||||
|
if (*s1 == '\0') {
|
||||||
|
return 0; // End of both strings
|
||||||
|
}
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
return 0; // First n characters are equal
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int strcmp(const char *str1, const char *str2) {
|
||||||
|
while (*str1 && (*str1 == *str2)) {
|
||||||
|
str1++;
|
||||||
|
str2++;
|
||||||
|
}
|
||||||
|
return *(unsigned char *)str1 - *(unsigned char *)str2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void strcpy(char *dest, const char *src) {
|
||||||
|
while (*src) {
|
||||||
|
*dest = *src;
|
||||||
|
dest++;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
*dest = '\0'; // Ensure the destination string is null-terminated
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t strlen(const char *str) {
|
||||||
|
const char *s = str;
|
||||||
|
while (*s) {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return s - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char *strncpy(char *dest, const char *src, size_t n) {
|
||||||
|
char *d = dest;
|
||||||
|
while (n && (*d++ = *src++)) {
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
if (n) {
|
||||||
|
while (--n) {
|
||||||
|
*d++ = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char* strrchr(const char* str, char ch) {
|
||||||
|
char* result = NULL;
|
||||||
|
while (*str) {
|
||||||
|
if (*str == ch) {
|
||||||
|
result = (char*)str;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// In strings.c
|
||||||
|
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||||
|
while (n && *s1 && (*s1 == *s2)) {
|
||||||
|
++s1;
|
||||||
|
++s2;
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
if (n == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return (*(unsigned char *)s1 - *(unsigned char *)s2);
|
||||||
|
}
|
||||||
|
}
|
85
EYOSx86-main/src/impl/x86_64/window.c
Normal file
85
EYOSx86-main/src/impl/x86_64/window.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include "window.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
// Define the screen dimensions
|
||||||
|
#define SCREEN_WIDTH 80
|
||||||
|
#define SCREEN_HEIGHT 25
|
||||||
|
|
||||||
|
// Function to draw the border of the window
|
||||||
|
static void draw_border(const Window* win) {
|
||||||
|
// Set the color for the border
|
||||||
|
print_set_color(win->border_color, win->border_color);
|
||||||
|
|
||||||
|
// Draw top border
|
||||||
|
for (int i = 0; i < win->size_x; ++i) {
|
||||||
|
move_print_cursor(win->x + i, win->y);
|
||||||
|
print_char('#');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw bottom border
|
||||||
|
for (int i = 0; i < win->size_x; ++i) {
|
||||||
|
move_print_cursor(win->x + i, win->y + win->size_y - 1);
|
||||||
|
print_char('#');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw left and right borders
|
||||||
|
for (int i = 1; i < win->size_y - 1; ++i) {
|
||||||
|
move_print_cursor(win->x, win->y + i);
|
||||||
|
print_char('#');
|
||||||
|
move_print_cursor(win->x + win->size_x - 1, win->y + i);
|
||||||
|
print_char('#');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw title
|
||||||
|
if (win->title[0] != '\0') {
|
||||||
|
print_set_color(win->border_color, win->background_color);
|
||||||
|
move_print_cursor(win->x + 1, win->y);
|
||||||
|
print_str(win->title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to draw the background of the window
|
||||||
|
static void draw_background(const Window* win) {
|
||||||
|
// Set the color for the background
|
||||||
|
print_set_color(win->background_color, win->background_color);
|
||||||
|
|
||||||
|
for (int i = 1; i < win->size_y - 1; ++i) {
|
||||||
|
for (int j = 1; j < win->size_x - 1; ++j) {
|
||||||
|
move_print_cursor(win->x + j, win->y + i);
|
||||||
|
print_char(' '); // Background character
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to create a simple window with border, background, and title
|
||||||
|
void create_window(Window* win, int x, int y, int size_x, int size_y, uint8_t border_color, uint8_t background_color, const char* title) {
|
||||||
|
win->x = x;
|
||||||
|
win->y = y;
|
||||||
|
win->size_x = size_x;
|
||||||
|
win->size_y = size_y;
|
||||||
|
win->border_color = border_color;
|
||||||
|
win->background_color = background_color;
|
||||||
|
|
||||||
|
// Copy title to window struct
|
||||||
|
for (int i = 0; i < WINDOW_TITLE_MAX_LENGTH - 1 && title[i] != '\0'; ++i) {
|
||||||
|
win->title[i] = title[i];
|
||||||
|
}
|
||||||
|
win->title[WINDOW_TITLE_MAX_LENGTH - 1] = '\0'; // Ensure null-termination
|
||||||
|
|
||||||
|
// Draw the window
|
||||||
|
draw_background(win);
|
||||||
|
draw_border(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to print text inside the window
|
||||||
|
void print_text_in_window(const Window* win, int x, int y, const char* text) {
|
||||||
|
// Set the color for the text
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, win->background_color);
|
||||||
|
|
||||||
|
for (int i = 0; text[i] != '\0'; ++i) {
|
||||||
|
if (x + i < win->size_x - 1 && y < win->size_y - 1) {
|
||||||
|
move_print_cursor(win->x + x + i, win->y + y);
|
||||||
|
print_char(text[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
EYOSx86-main/src/intf/disk_io.h
Normal file
17
EYOSx86-main/src/intf/disk_io.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// disk_io.h
|
||||||
|
|
||||||
|
#ifndef DISK_IO_H
|
||||||
|
#define DISK_IO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Read sectors from the disk
|
||||||
|
int disk_read(uint32_t lba, void *buffer, uint32_t size);
|
||||||
|
|
||||||
|
// Optional: Write sectors to the disk (not implemented)
|
||||||
|
int disk_write(uint32_t lba, const void *buffer, uint32_t size);
|
||||||
|
|
||||||
|
|
||||||
|
int bios_read_sector(uint32_t lba, void *buffer);
|
||||||
|
|
||||||
|
#endif // DISK_IO_H
|
58
EYOSx86-main/src/intf/fat12.h
Normal file
58
EYOSx86-main/src/intf/fat12.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef FAT12_H
|
||||||
|
#define FAT12_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define FAT12_SIGNATURE 0xAA55
|
||||||
|
#define ROOT_DIR_ENTRIES 224
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t jmp_boot[3]; // Jump instruction
|
||||||
|
char oem_name[8]; // OEM Name
|
||||||
|
uint16_t bytes_per_sector;
|
||||||
|
uint8_t sectors_per_cluster;
|
||||||
|
uint16_t reserved_sectors;
|
||||||
|
uint8_t num_fats;
|
||||||
|
uint16_t root_entry_count;
|
||||||
|
uint16_t total_sectors_16;
|
||||||
|
uint8_t media;
|
||||||
|
uint16_t fat_size_16;
|
||||||
|
uint16_t sectors_per_track;
|
||||||
|
uint16_t num_heads;
|
||||||
|
uint32_t hidden_sectors;
|
||||||
|
uint32_t total_sectors_32;
|
||||||
|
uint8_t boot_signature;
|
||||||
|
uint32_t volume_id;
|
||||||
|
char volume_label[11];
|
||||||
|
char fs_type[8];
|
||||||
|
} __attribute__((packed)) fat12_boot_sector_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char filename[8];
|
||||||
|
char extension[3];
|
||||||
|
uint8_t attributes;
|
||||||
|
uint8_t reserved;
|
||||||
|
uint8_t creation_time_tenths;
|
||||||
|
uint16_t creation_time;
|
||||||
|
uint16_t creation_date;
|
||||||
|
uint16_t last_access_date;
|
||||||
|
uint16_t first_cluster_high;
|
||||||
|
uint16_t last_mod_time;
|
||||||
|
uint16_t last_mod_date;
|
||||||
|
uint16_t first_cluster_low;
|
||||||
|
uint32_t file_size;
|
||||||
|
} __attribute__((packed)) fat12_dir_entry_t;
|
||||||
|
|
||||||
|
// FAT12 Filesystem initialization
|
||||||
|
int fat12_init(void);
|
||||||
|
|
||||||
|
// Read the root directory
|
||||||
|
int fat12_read_root_directory(void);
|
||||||
|
|
||||||
|
// Find a file in the root directory
|
||||||
|
int fat12_find_file(const char *filename, fat12_dir_entry_t *entry);
|
||||||
|
|
||||||
|
// Read a file (to be implemented)
|
||||||
|
int fat12_read_file(fat12_dir_entry_t *entry, void *buffer);
|
||||||
|
|
||||||
|
#endif // FAT12_H
|
47
EYOSx86-main/src/intf/fs.h
Normal file
47
EYOSx86-main/src/intf/fs.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef FS_H
|
||||||
|
#define FS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "fat12.h"
|
||||||
|
#include "disk_io.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
#define BLOCK_SIZE 4096
|
||||||
|
#define MAX_FILE_NAME 255
|
||||||
|
#define MAX_FILES 128
|
||||||
|
|
||||||
|
// Declarations for block operations
|
||||||
|
void write_block(uint32_t block_index, const void *data, uint32_t size);
|
||||||
|
void read_block(uint32_t block_index, void *buffer, uint32_t size);
|
||||||
|
|
||||||
|
// Structure of the superblock
|
||||||
|
typedef struct {
|
||||||
|
uint32_t total_blocks;
|
||||||
|
uint32_t free_blocks;
|
||||||
|
uint32_t total_inodes;
|
||||||
|
uint32_t free_inodes;
|
||||||
|
} Superblock;
|
||||||
|
|
||||||
|
// Structure of an inode
|
||||||
|
typedef struct {
|
||||||
|
char name[MAX_FILE_NAME];
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t data_block_start;
|
||||||
|
uint32_t permissions;
|
||||||
|
} Inode;
|
||||||
|
|
||||||
|
// Structure of a directory entry
|
||||||
|
typedef struct {
|
||||||
|
char name[MAX_FILE_NAME];
|
||||||
|
uint32_t inode_index;
|
||||||
|
} DirectoryEntry;
|
||||||
|
|
||||||
|
// Filesystem operations
|
||||||
|
void fs_init();
|
||||||
|
int fs_create_file(const char *name, uint32_t size);
|
||||||
|
int fs_write_file(const char *name, const void *data, uint32_t size);
|
||||||
|
int fs_read_file(const char *name, void *buffer, uint32_t size);
|
||||||
|
int fs_delete_file(const char *name);
|
||||||
|
void list_files();
|
||||||
|
|
||||||
|
#endif // FS_H
|
25
EYOSx86-main/src/intf/game.h
Normal file
25
EYOSx86-main/src/intf/game.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Define the maximum length of a command
|
||||||
|
#define MAX_COMMAND_LENGTH 128
|
||||||
|
|
||||||
|
// Game state structure
|
||||||
|
typedef struct {
|
||||||
|
int current_room;
|
||||||
|
bool game_active;
|
||||||
|
} GameState;
|
||||||
|
|
||||||
|
// Function to initialize and run the game
|
||||||
|
void create_game();
|
||||||
|
|
||||||
|
// Function to handle the command input by the player
|
||||||
|
void handle_command(const char* command);
|
||||||
|
|
||||||
|
// Function to print the current prompt
|
||||||
|
void print_prompt();
|
||||||
|
|
||||||
|
#endif
|
46
EYOSx86-main/src/intf/idt.h
Normal file
46
EYOSx86-main/src/intf/idt.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef IDT_H
|
||||||
|
#define IDT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct idt_entry_t {
|
||||||
|
uint16_t offset_low; // Lower 16 bits of ISR address
|
||||||
|
uint16_t selector; // Kernel segment selector
|
||||||
|
uint8_t ist; // Interrupt Stack Table (for 64-bit)
|
||||||
|
uint8_t type_attr; // Type and attributes (P, DPL, S, Type)
|
||||||
|
uint16_t offset_mid; // Middle 16 bits of ISR address
|
||||||
|
uint32_t offset_high; // Upper 32 bits of ISR address (for 64-bit)
|
||||||
|
uint32_t zero; // Reserved
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct idt_ptr_t {
|
||||||
|
uint16_t limit; // Size of the IDT (bytes - 1)
|
||||||
|
uint64_t base; // Base address of the IDT
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define ERROR_DIVIDE_BY_ZERO 0
|
||||||
|
#define ERROR_DEBUG 1
|
||||||
|
#define ERROR_NMI 2
|
||||||
|
#define ERROR_BREAKPOINT 3
|
||||||
|
#define ERROR_OVERFLOW 4
|
||||||
|
#define ERROR_BOUND 5
|
||||||
|
#define ERROR_INVALID_OP 6
|
||||||
|
#define ERROR_DEVICE_NOT_AVAIL 7
|
||||||
|
#define ERROR_DOUBLE_FAULT 8
|
||||||
|
#define ERROR_COPROCESSOR_OVERRUN 9
|
||||||
|
#define ERROR_INVALID_TSS 10
|
||||||
|
#define ERROR_SEGMENT_NOT_PRESENT 11
|
||||||
|
#define ERROR_STACK_SEGMENT 12
|
||||||
|
#define ERROR_GENERAL_PROTECTION 13
|
||||||
|
#define ERROR_PAGE_FAULT 14
|
||||||
|
#define FILESYSTEM_ERROR 15 // Assuming this relates to your filesystem
|
||||||
|
|
||||||
|
|
||||||
|
#define ERROR_RESERVED 16 // Not implemented error
|
||||||
|
// Function prototypes
|
||||||
|
void setup_idt_entry(int index, void (*handler)(), uint16_t selector, uint8_t type_attr);
|
||||||
|
void init_idt();
|
||||||
|
|
||||||
|
#endif
|
11
EYOSx86-main/src/intf/io.h
Normal file
11
EYOSx86-main/src/intf/io.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// io.h
|
||||||
|
|
||||||
|
#ifndef IO_H
|
||||||
|
#define IO_H
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
void outb(uint16_t port, uint8_t value);
|
||||||
|
uint8_t inb(uint16_t port);
|
||||||
|
|
||||||
|
#endif // IO_H
|
18
EYOSx86-main/src/intf/keydriver.h
Normal file
18
EYOSx86-main/src/intf/keydriver.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef KEYDRIVER_H
|
||||||
|
#define KEYDRIVER_H
|
||||||
|
|
||||||
|
#define KEYBOARD_BUFFER_SIZE 128
|
||||||
|
|
||||||
|
// Initializes the keyboard driver
|
||||||
|
void init_keyboard_driver();
|
||||||
|
|
||||||
|
// Reads a single character from the keyboard and stores it in the buffer
|
||||||
|
char read_key();
|
||||||
|
|
||||||
|
// Gets the current index of the buffer
|
||||||
|
unsigned int get_buffer_index();
|
||||||
|
|
||||||
|
// Retrieves the contents of the keyboard buffer
|
||||||
|
const char* get_keyboard_buffer();
|
||||||
|
|
||||||
|
#endif // KEYDRIVER_H
|
9
EYOSx86-main/src/intf/memory.h
Normal file
9
EYOSx86-main/src/intf/memory.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
void* memcpy(void* dst, const void* src, uint16_t num);
|
||||||
|
void* memset(void* ptr, int value, uint16_t num);
|
||||||
|
int memcmp(const void* ptr1, const void* ptr2, uint16_t num);
|
||||||
|
void* malloc(size_t size);
|
||||||
|
void free(void* ptr);
|
41
EYOSx86-main/src/intf/print.h
Normal file
41
EYOSx86-main/src/intf/print.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#define MAX_STRING_LENGTH 100
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} CursorPosition;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PRINT_COLOR_BLACK = 0,
|
||||||
|
PRINT_COLOR_BLUE = 1,
|
||||||
|
PRINT_COLOR_GREEN = 2,
|
||||||
|
PRINT_COLOR_CYAN = 3,
|
||||||
|
PRINT_COLOR_RED = 4,
|
||||||
|
PRINT_COLOR_MAGENTA = 5,
|
||||||
|
PRINT_COLOR_BROWN = 6,
|
||||||
|
PRINT_COLOR_LIGHT_GRAY = 7,
|
||||||
|
PRINT_COLOR_DARK_GRAY = 8,
|
||||||
|
PRINT_COLOR_LIGHT_BLUE = 9,
|
||||||
|
PRINT_COLOR_LIGHT_GREEN = 10,
|
||||||
|
PRINT_COLOR_LIGHT_CYAN = 11,
|
||||||
|
PRINT_COLOR_LIGHT_RED = 12,
|
||||||
|
PRINT_COLOR_PINK = 13,
|
||||||
|
PRINT_COLOR_YELLOW = 14,
|
||||||
|
PRINT_COLOR_WHITE = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
void sscanf(const char *str, const char *format, char *filename, char *content);
|
||||||
|
int my_sscanf(const char *input, const char *format, char *output);
|
||||||
|
void print_clear();
|
||||||
|
void print_char(char character);
|
||||||
|
void print_str(char* string);
|
||||||
|
void printf(const char* format, ...);
|
||||||
|
void print_set_color(uint8_t foreground, uint8_t background);
|
||||||
|
void move_print_cursor(int x, int y);
|
||||||
|
void offset_print_cursor(int x, int y);
|
||||||
|
void print_hex(unsigned int num);
|
||||||
|
CursorPosition get_print_cursor_pos();
|
23
EYOSx86-main/src/intf/stdint.h
Normal file
23
EYOSx86-main/src/intf/stdint.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef signed char int8_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef signed short int16_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef signed long int int32_t;
|
||||||
|
typedef unsigned long int uint32_t;
|
||||||
|
typedef signed long long int int64_t;
|
||||||
|
typedef unsigned long long int uint64_t;
|
||||||
|
typedef uint32_t size_t; // Adjust size based on your platform; 32-bit or 64-bit
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint8_t bool;
|
||||||
|
|
||||||
|
#define false 0
|
||||||
|
#define true 1
|
||||||
|
|
||||||
|
#define NULL ((void*)0)
|
||||||
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
|
// Define size_t as an unsigned integer type for sizes and indices
|
49
EYOSx86-main/src/intf/stdopt.h
Normal file
49
EYOSx86-main/src/intf/stdopt.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef BUFFER_OPS_H
|
||||||
|
#define BUFFER_OPS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a character at the beginning of the array.
|
||||||
|
* Shifts all elements to the right and removes the last element if the array is full.
|
||||||
|
*
|
||||||
|
* @param array Pointer to the array.
|
||||||
|
* @param c Character to prepend.
|
||||||
|
*/
|
||||||
|
void prepend(uint8_t* array, uint8_t c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a character at the end of the array.
|
||||||
|
* Shifts all elements to the left and removes the first element if the array is full.
|
||||||
|
*
|
||||||
|
* @param array Pointer to the array.
|
||||||
|
* @param c Character to append.
|
||||||
|
*/
|
||||||
|
void append(uint8_t* array, uint8_t c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a character at the beginning of the array.
|
||||||
|
* Shifts all elements to the right. Note that this function assumes there is space
|
||||||
|
* at the beginning of the array.
|
||||||
|
*
|
||||||
|
* @param array Pointer to the array.
|
||||||
|
* @param c Character to insert at the beginning.
|
||||||
|
*/
|
||||||
|
void append_first(uint8_t* array, uint8_t c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a character at the end of the array.
|
||||||
|
* Shifts all elements to the left. Note that this function assumes there is space
|
||||||
|
* at the end of the array.
|
||||||
|
*
|
||||||
|
* @param array Pointer to the array.
|
||||||
|
* @param c Character to insert at the end.
|
||||||
|
*/
|
||||||
|
void append_last(uint8_t* array, uint8_t c);
|
||||||
|
|
||||||
|
|
||||||
|
char** split_string(const char* str, char delimiter, int* num_tokens);
|
||||||
|
void free_split_strings(char** tokens, int num_tokens);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BUFFER_OPS_H
|
12
EYOSx86-main/src/intf/strings.h
Normal file
12
EYOSx86-main/src/intf/strings.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
int strcmp(const char *str1, const char *str2);
|
||||||
|
size_t strlen(const char *str);
|
||||||
|
char *strncpy(char *dest, const char *src, size_t n);
|
||||||
|
int int_strncmp(const char* s1, const char* s2, size_t n);
|
||||||
|
void strcpy(char *dest, const char *src);
|
||||||
|
char* strrchr(const char* str, char ch);
|
||||||
|
|
||||||
|
int strncmp(const char *s1, const char *s2, size_t n);
|
22
EYOSx86-main/src/intf/vector.h
Normal file
22
EYOSx86-main/src/intf/vector.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef VECTOR_H
|
||||||
|
#define VECTOR_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Define the vector structure
|
||||||
|
typedef struct {
|
||||||
|
void** items; // Pointer to the array of items
|
||||||
|
size_t capacity; // Maximum number of items the vector can hold
|
||||||
|
size_t size; // Current number of items in the vector
|
||||||
|
} vector;
|
||||||
|
|
||||||
|
// Function prototypes
|
||||||
|
vector* vector_create();
|
||||||
|
void vector_destroy(vector* v);
|
||||||
|
int vector_push_back(vector* v, void* item);
|
||||||
|
void* vector_get(vector* v, size_t index);
|
||||||
|
int vector_set(vector* v, size_t index, void* item);
|
||||||
|
size_t vector_size(vector* v);
|
||||||
|
int vector_resize(vector* v, size_t new_capacity);
|
||||||
|
|
||||||
|
#endif
|
6
EYOSx86-main/src/intf/vga.h
Normal file
6
EYOSx86-main/src/intf/vga.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "stdint.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
|
||||||
|
void set_cursor_position(int x, int y);
|
||||||
|
void move_cursor(int x, int y);
|
19
EYOSx86-main/src/intf/window.h
Normal file
19
EYOSx86-main/src/intf/window.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define WINDOW_TITLE_MAX_LENGTH 20
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int size_x;
|
||||||
|
int size_y;
|
||||||
|
uint8_t border_color;
|
||||||
|
uint8_t background_color;
|
||||||
|
char title[WINDOW_TITLE_MAX_LENGTH];
|
||||||
|
} Window;
|
||||||
|
|
||||||
|
// Function to create and draw a simple window
|
||||||
|
void create_window(Window* win, int x, int y, int size_x, int size_y, uint8_t border_color, uint8_t background_color, const char* title);
|
||||||
|
void print_text_in_window(const Window* win, int x, int y, const char* text);
|
7
EYOSx86-main/targets/x86_64/iso/boot/grub/grub.cfg
Normal file
7
EYOSx86-main/targets/x86_64/iso/boot/grub/grub.cfg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
set timeout=0
|
||||||
|
set default=0
|
||||||
|
|
||||||
|
menuentry "my os" {
|
||||||
|
multiboot2 /boot/kernel.bin
|
||||||
|
boot
|
||||||
|
}
|
BIN
EYOSx86-main/targets/x86_64/iso/boot/kernel.bin
Normal file
BIN
EYOSx86-main/targets/x86_64/iso/boot/kernel.bin
Normal file
Binary file not shown.
16
EYOSx86-main/targets/x86_64/linker.ld
Normal file
16
EYOSx86-main/targets/x86_64/linker.ld
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
ENTRY(start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 1M;
|
||||||
|
|
||||||
|
.boot :
|
||||||
|
{
|
||||||
|
KEEP(*(.multiboot_header))
|
||||||
|
}
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user