diff --git a/.vscode/browse.vc.db b/.vscode/browse.vc.db index 0da4a0d..6ddf39b 100644 Binary files a/.vscode/browse.vc.db and b/.vscode/browse.vc.db differ diff --git a/.vscode/browse.vc.db-shm b/.vscode/browse.vc.db-shm index 795ab0e..c21ceaf 100644 Binary files a/.vscode/browse.vc.db-shm and b/.vscode/browse.vc.db-shm differ diff --git a/src/boot/boot.asm b/src/boot/boot.asm index 926dd31..9bb09e7 100644 --- a/src/boot/boot.asm +++ b/src/boot/boot.asm @@ -26,7 +26,7 @@ jmp start ; Data ; ;;;;;;;; ; fdd geometry & options -fddsamt db 8 ; how many sectors to load +fddsamt db 1 ; how many sectors to load fddretr db 5 ; max retries for fdd operations fddcretr db 0 ; current retries left @@ -76,52 +76,51 @@ start: hddload: mov si, diskhdd ; print disk type call printstr - - jmp halt ; not implemented! + jmp load_onto_reset fddload: mov si, diskfdd ; print disk type call printstr -fddload_onto_reset: +load_onto_reset: mov ah, [fddretr] ; load max retries in memory mov [fddcretr], ah -fddload_reset: +load_reset: mov si, fdderes ; load error message pointer dec byte [fddcretr] ; decrement the retries counter - jz fddload_err ; if it is 0, we stop trying + jz load_err ; if it is 0, we stop trying mov ah, 0x00 ; otherwise, reset function (int 0x13) int 0x13 - jc fddload_reset ; if jc (error), we try again + jc load_reset ; if jc (error), we try again -fddload_onto_load: +load_onto_load: mov ah, [fddretr] ; reset retries counter mov [fddcretr], ah - mov ax, 0x1000 ; need to stay within real mode limits + mov ax, 0x8000 ; need to stay within real mode limits mov es, ax -fddload_load: ; loads 512*fddsamt bytes from sector 2 on. +load_load: ; loads 512*fddsamt bytes from sector 2 on. mov si, fddeload dec byte [fddcretr] - jz fddload_err + jz load_err mov dh, 0 ; head 0 mov ch, 0 ; cyl/track 0 mov cl, 2 ; start sector - mov bx, 0 ; memory location + mov bx, 0x8000 ; memory location mov al, [fddsamt] ; how many sectors to read mov ah, 0x02 ; read function (int 0x13) int 0x13 - jc fddload_load ; if jc (error), we try again + jc load_load ; if jc (error), we try again cmp al, [fddsamt] ; also if al is not 1, we have a problem - jnz fddload_load + jnz load_load -fddload_done: +load_done: mov si, loaded ; we have successfully loaded the data call printstr - jmp halt ; this will be jmp 0x1000:0x0000 + jmp 0x8000:0x0000 ; this will be jmp 0x1000:0x0000 -fddload_err: +load_err: call printstr ; print jmp halt ; and die @@ -163,4 +162,4 @@ times 510 - ($ - $$) db 0x00 ;;;;;;;;;;;;;;;;;; ; BIOS signature ; ;;;;;;;;;;;;;;;;;; -dw 0xAA55 +dw 0xAA55 \ No newline at end of file diff --git a/src/boot/boot.bin b/src/boot/boot.bin new file mode 100644 index 0000000..f866128 Binary files /dev/null and b/src/boot/boot.bin differ diff --git a/src/boot/boot2.bin b/src/boot/boot2.bin new file mode 100644 index 0000000..4b83fe4 Binary files /dev/null and b/src/boot/boot2.bin differ diff --git a/src/drivers/io/io.asm b/src/drivers/io/io.asm index 3716ae1..d7a332c 100644 --- a/src/drivers/io/io.asm +++ b/src/drivers/io/io.asm @@ -16,7 +16,7 @@ inb: outb: PUSH DX ; Preserve DX PUSH AX ; Preserve AX - MOV DX, [ESP + 4] ; Get port number from stack + MOV DX, [ESP + 6] ; Get port number from stack MOV AL, [ESP + 6] ; Get data from stack OUT DX, AL ; Write to port POP AX ; Restore AX diff --git a/src/drivers/io/io.c b/src/drivers/io/io.c index 28a0753..fc278da 100644 --- a/src/drivers/io/io.c +++ b/src/drivers/io/io.c @@ -1,63 +1,58 @@ -#include "io.h" - -/* - Common Ports - COM1: 0x3F8 - COM2: 0x2F8 - COM3: 0x3E8 - COM4: 0x2E8 - LPT1: 0x378 - LPT2: 0x278 - LPT3: 0x3BC -*/ - -// Function to initialize the COM and LPT ports -void io_init() -{ - // TODO: Initialize the COM and LPT ports - // Set up any necessary configuration or control operations -} - -// Function to read from the COM port -char io_read_com() -{ - // TODO: Read from the COM port - // Use the appropriate memory or I/O address to read from the port - // Return the read data - - char data = 0; // Initialize the variable to store the read data - - // Read from the COM port and assign the read value to the 'data' variable - - return data; // Return the read data -} - -// Function to write to the COM port -void io_write_com(char data) -{ - // TODO: Write to the COM port - // Use the appropriate memory or I/O address to write to the port - // Write the provided data to the port -} - -// Function to read from the LPT port -char io_read_lpt() -{ - // TODO: Read from the LPT port - // Use the appropriate memory or I/O address to read from the port - // Return the read data - - char data = 0; // Initialize the variable to store the read data - - // Read from the LPT port and assign the read value to the 'data' variable - - return data; // Return the read data -} - -// Function to write to the LPT port -void io_write_lpt(char data) -{ - // TODO: Write to the LPT port - // Use the appropriate memory or I/O address to write to the port - // Write the provided data to the port -} \ No newline at end of file +#include "io.h" + +/* + Common Ports + COM1: 0x3F8 + COM2: 0x2F8 + COM3: 0x3E8 + COM4: 0x2E8 + COM5: 0x5F8 + COM6: 0x4F8 + COM7: 0x5E8 + COM8: 0x4E8 + LPT1: 0x378 + LPT2: 0x278 + LPT3: 0x3BC +*/ + +// Function to initialize the ports before reading or writing +void io_init() +{ + // Initialize COM1 port (0x3F8) - You can add more port initializations here if needed + + // Example initialization for COM1 port (9600 baud, 8N1) + outb(0x3F8 + 1, 0x00); // Disable all interrupts + outb(0x3F8 + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(0x3F8 + 0, 0x03); // Set divisor to 3 (lo byte) for 9600 baud rate + outb(0x3F8 + 1, 0x00); // Set divisor to hi byte for 9600 baud rate (default) + outb(0x3F8 + 3, 0x03); // Set data format to 8N1 (8 data bits, no parity, one stop bit) + +} + +// Function to read from the COM port +char io_read_com() +{ + // Read from COM1 port 0x3F8 + return inb(0x3F8); // Read data from COM1 port +} + +// Function to write to the COM port +void io_write_com(char data) +{ + // Write to COM1 port 0x3F8 + outb(0x3F8, data); // Write data to COM1 port +} + +// Function to read from the LPT port +char io_read_lpt() +{ + // Read from LPT1 port 0x378 + return inb(0x378); // Read data from LPT1 port +} + +// Function to write to the LPT port +void io_write_lpt(char data) +{ + // Write to LPT1 port 0x378 + outb(0x378, data); // Write data to LPT1 port +} diff --git a/src/drivers/io/io.h b/src/drivers/io/io.h index 09bd4bc..3f72309 100644 --- a/src/drivers/io/io.h +++ b/src/drivers/io/io.h @@ -1,28 +1,28 @@ -#ifndef IO_H -#define IO_H - -#include - -// Function to initialize the COM and LPT ports -void io_init(); - -// Function to read from the COM port -char io_read_com(); - -// Function to write to the COM port -void io_write_com(char data); - -// Function to read from the LPT port -char io_read_lpt(); - -// Function to write to the LPT port -void io_write_lpt(char data); - -// Function declarations for keyboard.c -extern uint8_t inb(uint16_t port); - -extern void outb(uint16_t port, uint8_t data); - -void install_interrupt_handler(uint8_t interrupt, void (*handler)(void)); - -#endif /* IO_H */ \ No newline at end of file +#ifndef IO_H +#define IO_H + +#include + +// Function to initialize the COM and LPT ports +void io_init(); + +// Function to read from the COM port +char io_read_com(); + +// Function to write to the COM port +void io_write_com(char data); + +// Function to read from the LPT port +char io_read_lpt(); + +// Function to write to the LPT port +void io_write_lpt(char data); + +// Function declarations for keyboard.c +extern uint8_t inb(uint16_t port); + +extern void outb(uint16_t port, uint8_t data); + +void install_interrupt_handler(uint8_t interrupt, void (*handler)(void)); + +#endif /* IO_H */ diff --git a/src/drivers/keyboard/keyboard.c b/src/drivers/keyboard/keyboard.c index e5771ea..87e0b98 100644 --- a/src/drivers/keyboard/keyboard.c +++ b/src/drivers/keyboard/keyboard.c @@ -9,7 +9,6 @@ #define KEYBOARD_DATA_PORT 0x60 #define KEYBOARD_INTERRUPT_VECTOR 0x09 #define KEYBOARD_COMMAND_PORT 0x64 -#define KEYBOARD_DATA_PORT 0x60 #define KEYBOARD_ENABLE_COMMAND 0xAE #define KEYBOARD_ENABLE_SCANCODE 0xF4 #define KEYBOARD_ACKNOWLEDGE_SCANCODE 0xFA @@ -33,6 +32,21 @@ void KeyboardInterruptHandler() keyboard_buffer_head = (keyboard_buffer_head + 1) % KEYBOARD_BUFFER_SIZE; } +// Function to translate the combined extended scancode (first byte + second byte) +uint8_t translate_extended_scancode(uint8_t second_scancode) +{ + uint16_t combined_scancode = (0xE0 << 8) | second_scancode; + + switch(combined_scancode) + { + case 0xE04D: + return KEYCODE_PRINT_SCREEN; + // Add more cases for other extended scancodes here + default: + return KEYCODE_UNKNOWN; + } +} + uint8_t translate_scancode_to_keycode(uint8_t scancode) { static uint8_t keycode_map[128] = { @@ -50,19 +64,109 @@ uint8_t translate_scancode_to_keycode(uint8_t scancode) [0x0C] = KEYCODE_MINUS, [0x0D] = KEYCODE_EQUALS, [0x0E] = KEYCODE_BACKSPACE, + [0x0F] = KEYCODE_TAB, + [0x10] = KEYCODE_Q, + [0x11] = KEYCODE_W, + [0x12] = KEYCODE_E, + [0x13] = KEYCODE_R, + [0x14] = KEYCODE_T, + [0x15] = KEYCODE_Y, + [0x16] = KEYCODE_U, + [0x17] = KEYCODE_I, + [0x18] = KEYCODE_O, + [0x19] = KEYCODE_P, + [0x1A] = KEYCODE_LEFT_BRACKET, + [0x1B] = KEYCODE_RIGHT_BRACKET, + [0x1C] = KEYCODE_ENTER, + [0x1D] = KEYCODE_LEFT_CTRL, + [0x1E] = KEYCODE_A, + [0x1F] = KEYCODE_S, + [0x20] = KEYCODE_D, + [0x21] = KEYCODE_F, + [0x22] = KEYCODE_G, + [0x23] = KEYCODE_H, + [0x24] = KEYCODE_J, + [0x25] = KEYCODE_K, + [0x26] = KEYCODE_L, + [0x27] = KEYCODE_SEMICOLON, + [0x28] = KEYCODE_APOSTROPHE, + [0x29] = KEYCODE_GRAVE_ACCENT, + [0x2A] = KEYCODE_LEFT_SHIFT, + [0x2B] = KEYCODE_BACKSLASH, + [0x2C] = KEYCODE_Z, + [0x2D] = KEYCODE_X, + [0x2E] = KEYCODE_C, + [0x2F] = KEYCODE_V, + [0x30] = KEYCODE_B, + [0x31] = KEYCODE_N, + [0x32] = KEYCODE_M, + [0x33] = KEYCODE_COMMA, + [0x34] = KEYCODE_DOT, + [0x35] = KEYCODE_FORWARD_SLASH, + [0x36] = KEYCODE_RIGHT_SHIFT, + [0x37] = KEYCODE_PRINT_SCREEN, // Example extended scancode (replace with more) + [0x38] = KEYCODE_LEFT_ALT, + [0x39] = KEYCODE_SPACE, + [0x3A] = KEYCODE_CAPS_LOCK, + [0x3B] = KEYCODE_F1, + [0x3C] = KEYCODE_F2, + [0x3D] = KEYCODE_F3, + [0x3E] = KEYCODE_F4, + [0x3F] = KEYCODE_F5, + [0x40] = KEYCODE_F6, + [0x41] = KEYCODE_F7, + [0x41] = KEYCODE_F7, + [0x42] = KEYCODE_F8, + [0x43] = KEYCODE_F9, + [0x44] = KEYCODE_F10, + [0x45] = KEYCODE_NUM_LOCK, // Extended scancode + [0x46] = KEYCODE_SCROLL_LOCK, // Extended scancode + [0x47] = KEYCODE_HOME, + [0x48] = KEYCODE_UP, + [0x49] = KEYCODE_PAGE_UP, + [0x4A] = KEYCODE_MINUS_PAD, + [0x4B] = KEYCODE_LEFT_ARROW, + [0x4C] = KEYCODE_5_PAD, + [0x4D] = KEYCODE_RIGHT_ARROW, + [0x4E] = KEYCODE_PLUS_PAD, + [0x4F] = KEYCODE_END, + [0x50] = KEYCODE_DOWN_ARROW, + [0x51] = KEYCODE_PAGE_DOWN, + [0x52] = KEYCODE_INSERT, + [0x53] = KEYCODE_DELETE, + // ... (complete the rest based on the scancode table) [0xE0] = 0, // Handle extended scancodes (e.g., Print Screen) separately }; - if (scancode < sizeof(keycode_map)) + static bool extended_scancode = false; + static uint8_t second_scancode; + + if (extended_scancode) { - // Map scancode directly to keycode - return keycode_map[scancode]; + // Handle second byte of extended scancode + extended_scancode = false; + return translate_extended_scancode(scancode); // Implement separate function for extended keycode translation + } + else if (scancode == 0xE0) + { + // First byte of extended scancode sequence + extended_scancode = true; + return 0; // Indicate incomplete scancode (waiting for second byte) } else { - // Handle unknown scancode - return KEYCODE_UNKNOWN; // Or return a special keycode indicating error + // Regular scancode + if (scancode < sizeof(keycode_map)) + { + // Map scancode directly to keycode + return keycode_map[scancode]; + } + else + { + // Handle unknown scancode + return KEYCODE_UNKNOWN; + } } } diff --git a/src/drivers/keyboard/keyboard.h b/src/drivers/keyboard/keyboard.h index 97960e1..7579c08 100644 --- a/src/drivers/keyboard/keyboard.h +++ b/src/drivers/keyboard/keyboard.h @@ -6,10 +6,11 @@ void KeyboardInterruptHandler(); -void keyboard_init(); -bool keyboard_buffer_empty(); +void keyboard_init(); +bool keyboard_buffer_empty(); uint8_t keyboard_read_scancode(); -void set_interrupt_vector(uint8_t vector, void (*handler)()); -void enable_interrupt(uint8_t vector); +void set_interrupt_vector(uint8_t vector, void (*handler)()); +void enable_interrupt(uint8_t vector); uint8_t translate_scancode_to_keycode(uint8_t scancode); +uint8_t translate_extended_scancode(uint8_t second_scancode); #endif diff --git a/src/drivers/network/ne2000.c b/src/drivers/network/ne2000.c index 048ac62..30877ad 100644 --- a/src/drivers/network/ne2000.c +++ b/src/drivers/network/ne2000.c @@ -1,41 +1,42 @@ -#include - -// NE2000 registers -#define NE2000_COMMAND 0x00 -#define NE2000_PSTART 0x01 -#define NE2000_PSTOP 0x02 -// ... more registers ... - -// NE2000 commands -#define NE2000_CMD_START 0x02 -#define NE2000_CMD_STOP 0x01 -// ... more commands ... - -// Write a value to a NE2000 register -void ne2000_write_reg(uint16_t base_addr, uint8_t reg, uint8_t value) { - // Write to the register - // This will depend on your specific hardware interface -} - -// Read a value from a NE2000 register -uint8_t ne2000_read_reg(uint16_t base_addr, uint8_t reg) { - // Read from the register - // This will depend on your specific hardware interface -} - -// Initialize the NE2000 card -void ne2000_init(uint16_t base_addr) { - // Stop the NE2000 card - ne2000_write_reg(base_addr, NE2000_COMMAND, NE2000_CMD_STOP); - - // Set up the packet buffer - ne2000_write_reg(base_addr, NE2000_PSTART, 0x40); - ne2000_write_reg(base_addr, NE2000_PSTOP, 0x80); - - // ... more initialization ... - - // Start the NE2000 card - ne2000_write_reg(base_addr, NE2000_COMMAND, NE2000_CMD_START); -} - -// ... more driver functions .. \ No newline at end of file +#include + +// NE2000 registers +#define NE2000_COMMAND 0x00 +#define NE2000_PSTART 0x01 +#define NE2000_PSTOP 0x02 +// ... more registers ... + +// NE2000 commands +#define NE2000_CMD_START 0x02 +#define NE2000_CMD_STOP 0x01 +// ... more commands ... + +// Write a value to a NE2000 register +void ne2000_write_reg(uint16_t base_addr, uint8_t reg, uint8_t value) { + volatile uint8_t *ne2000_reg = (volatile uint8_t *)(base_addr + reg); + *ne2000_reg = value; +} + +// Read a value from a NE2000 register +uint8_t ne2000_read_reg(uint16_t base_addr, uint8_t reg) { + volatile uint8_t *ne2000_reg = (volatile uint8_t *)(base_addr + reg); + return *ne2000_reg; +} + +// Initialize the NE2000 card +void ne2000_init(uint16_t base_addr) +{ + // Stop the NE2000 card + ne2000_write_reg(base_addr, NE2000_COMMAND, NE2000_CMD_STOP); + + // Set up the packet buffer + ne2000_write_reg(base_addr, NE2000_PSTART, 0x40); + ne2000_write_reg(base_addr, NE2000_PSTOP, 0x80); + + // ... more initialization ... + + // Start the NE2000 card + ne2000_write_reg(base_addr, NE2000_COMMAND, NE2000_CMD_START); +} + +// ... more driver functions .. diff --git a/src/kernel/arch/x86/isr/exceptions.c b/src/kernel/arch/x86/isr/exceptions.c index 0b35e7b..f0a197a 100644 --- a/src/kernel/arch/x86/isr/exceptions.c +++ b/src/kernel/arch/x86/isr/exceptions.c @@ -1,23 +1,40 @@ #include "exceptions.h" +#include +#include #include +#include void DivideByZero() { - //printf("Divide By Zero Exception"); + // Add logic to handle Divide By Zero Exception + printf("Divide By Zero Exception\n"); + + // Additional Exception Handling Logic: + // Example: Perform specific actions for Divide By Zero scenario + // - Log the exception to a file + FILE *logFile = fopen("error.log", "a"); + if (logFile != NULL) { + fprintf(logFile, "Divide By Zero Exception occurred\n"); + fclose(logFile); + } + + // - Gracefully terminate the kernel + printf("Exiting kernel due to Divide By Zero Exception\n"); + exit(EXIT_FAILURE); } void DoubleFault() { - //printf("Double Fault Exception"); + // printf("Double Fault Exception"); } void PageFault() { - //printf("Page Fault Exception"); + // printf("Page Fault Exception"); } void GeneralProtectionFault() { - //printf("General Protection Fault Exception"); -} \ No newline at end of file + // printf("General Protection Fault Exception"); +} diff --git a/src/kernel/arch/x86/isr/isr.c b/src/kernel/arch/x86/isr/isr.c index ecb5624..5f8d426 100644 --- a/src/kernel/arch/x86/isr/isr.c +++ b/src/kernel/arch/x86/isr/isr.c @@ -1 +1,21 @@ #include "isr.h" + +void isr_handler(struct isr_regs regs) { + switch(regs.int_no) { + case DIVIDE_BY_ZERO_INTERRUPT: + // Handle Divide By Zero Interrupt + break; + case DOUBLE_FAULT_INTERRUPT: + // Handle Double Fault Interrupt + break; + case PAGE_FAULT_INTERRUPT: + // Handle Page Fault Interrupt + break; + case GENERAL_PROTECTION_FAULT_INTERRUPT: + // Handle General Protection Fault Interrupt + break; + default: + // Handle other interrupts or implement error handling + break; + } +}