did some more work on keyboard.c and bootloader and moved and other random stuff

This commit is contained in:
Gregory Kenneth Bowne 2024-03-26 00:59:15 -07:00
parent f4c5d59d8e
commit ad70cfd836
13 changed files with 303 additions and 166 deletions

BIN
.vscode/browse.vc.db vendored

Binary file not shown.

Binary file not shown.

View File

@ -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

BIN
src/boot/boot.bin Normal file

Binary file not shown.

BIN
src/boot/boot2.bin Normal file

Binary file not shown.

View File

@ -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

View File

@ -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
}
#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
}

View File

@ -1,28 +1,28 @@
#ifndef IO_H
#define IO_H
#include <stdint.h>
// 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 */
#ifndef IO_H
#define IO_H
#include <stdint.h>
// 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 */

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -1,41 +1,42 @@
#include <stdint.h>
// 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 ..
#include <stdint.h>
// 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 ..

View File

@ -1,23 +1,40 @@
#include "exceptions.h"
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
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");
}
// printf("General Protection Fault Exception");
}

View File

@ -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;
}
}