mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2024-11-24 06:46:53 -08:00
did some more work on keyboard.c and bootloader and moved and other random stuff
This commit is contained in:
parent
f4c5d59d8e
commit
ad70cfd836
BIN
.vscode/browse.vc.db
vendored
BIN
.vscode/browse.vc.db
vendored
Binary file not shown.
BIN
.vscode/browse.vc.db-shm
vendored
BIN
.vscode/browse.vc.db-shm
vendored
Binary file not shown.
@ -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
|
||||
|
||||
|
BIN
src/boot/boot.bin
Normal file
BIN
src/boot/boot.bin
Normal file
Binary file not shown.
BIN
src/boot/boot2.bin
Normal file
BIN
src/boot/boot2.bin
Normal file
Binary file not shown.
@ -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
|
||||
|
@ -6,58 +6,53 @@
|
||||
COM2: 0x2F8
|
||||
COM3: 0x3E8
|
||||
COM4: 0x2E8
|
||||
COM5: 0x5F8
|
||||
COM6: 0x4F8
|
||||
COM7: 0x5E8
|
||||
COM8: 0x4E8
|
||||
LPT1: 0x378
|
||||
LPT2: 0x278
|
||||
LPT3: 0x3BC
|
||||
*/
|
||||
|
||||
// Function to initialize the COM and LPT ports
|
||||
// Function to initialize the ports before reading or writing
|
||||
void io_init()
|
||||
{
|
||||
// TODO: Initialize the COM and LPT ports
|
||||
// Set up any necessary configuration or control operations
|
||||
// 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()
|
||||
{
|
||||
// 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
|
||||
// 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)
|
||||
{
|
||||
// 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
|
||||
// Write to COM1 port 0x3F8
|
||||
outb(0x3F8, data); // Write data to COM1 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
|
||||
// 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)
|
||||
{
|
||||
// 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
|
||||
// Write to LPT1 port 0x378
|
||||
outb(0x378, data); // Write data to LPT1 port
|
||||
}
|
@ -23,6 +23,6 @@ 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));
|
||||
void install_interrupt_handler(uint8_t interrupt, void (*handler)(void));
|
||||
|
||||
#endif /* IO_H */
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -13,29 +13,30 @@
|
||||
|
||||
// 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
|
||||
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) {
|
||||
// Read from the register
|
||||
// This will depend on your specific hardware interface
|
||||
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);
|
||||
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);
|
||||
// Set up the packet buffer
|
||||
ne2000_write_reg(base_addr, NE2000_PSTART, 0x40);
|
||||
ne2000_write_reg(base_addr, NE2000_PSTOP, 0x80);
|
||||
|
||||
// ... more initialization ...
|
||||
// ... more initialization ...
|
||||
|
||||
// Start the NE2000 card
|
||||
ne2000_write_reg(base_addr, NE2000_COMMAND, NE2000_CMD_START);
|
||||
// Start the NE2000 card
|
||||
ne2000_write_reg(base_addr, NE2000_COMMAND, NE2000_CMD_START);
|
||||
}
|
||||
|
||||
// ... more driver functions ..
|
@ -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");
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user