...
This commit is contained in:
4
makefile
4
makefile
@@ -6,8 +6,8 @@ CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 -g
|
|||||||
LDFLAGS = -g
|
LDFLAGS = -g
|
||||||
ASFLAGS = -f elf64 -g -F dwarf
|
ASFLAGS = -f elf64 -g -F dwarf
|
||||||
|
|
||||||
SRC_C := src/kernel.c src/string.c src/vga.c
|
SRC_C := src/kernel.c src/string.c src/vga.c src/idt.c src/keyboard.c
|
||||||
SRC_ASM := src/boot.asm
|
SRC_ASM := src/boot.asm src/idt_stub.asm
|
||||||
|
|
||||||
OBJ_C := $(SRC_C:src/%.c=.build/%.o)
|
OBJ_C := $(SRC_C:src/%.c=.build/%.o)
|
||||||
OBJ_ASM := $(SRC_ASM:src/%.asm=.build/%.o)
|
OBJ_ASM := $(SRC_ASM:src/%.asm=.build/%.o)
|
||||||
|
|||||||
39
src/idt.c
39
src/idt.c
@@ -1,8 +1,5 @@
|
|||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define IDT_SIZE 256
|
#define IDT_SIZE 256
|
||||||
|
|
||||||
@@ -13,19 +10,19 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t address_low;
|
u16 address_low;
|
||||||
uint16_t selector;
|
u16 selector;
|
||||||
uint8_t ist;
|
u8 ist;
|
||||||
uint8_t flags;
|
u8 flags;
|
||||||
uint16_t address_mid;
|
u16 address_mid;
|
||||||
uint32_t address_high;
|
u32 address_high;
|
||||||
uint32_t reserved;
|
u32 reserved;
|
||||||
} __attribute__((packed)) interrupt_descriptor;
|
} __attribute__((packed)) interrupt_descriptor;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t limit;
|
u16 limit;
|
||||||
uint64_t base;
|
u64 base;
|
||||||
} __attribute__((packed)) idtr_t;
|
} __attribute__((packed)) idtr_t;
|
||||||
|
|
||||||
extern void* isr_stub_table[];
|
extern void* isr_stub_table[];
|
||||||
@@ -70,7 +67,7 @@ static interrupt_descriptor idt[IDT_SIZE];
|
|||||||
|
|
||||||
static void pic_remap(int offset1, int offset2)
|
static void pic_remap(int offset1, int offset2)
|
||||||
{
|
{
|
||||||
uint8_t a1, a2;
|
u8 a1, a2;
|
||||||
|
|
||||||
a1 = inb(PIC1_DATA);
|
a1 = inb(PIC1_DATA);
|
||||||
a2 = inb(PIC2_DATA);
|
a2 = inb(PIC2_DATA);
|
||||||
@@ -91,7 +88,7 @@ static void pic_remap(int offset1, int offset2)
|
|||||||
outb(PIC2_DATA, a2);
|
outb(PIC2_DATA, a2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pic_send_eoi(uint8_t irq)
|
static void pic_send_eoi(u8 irq)
|
||||||
{
|
{
|
||||||
if (irq >= 8)
|
if (irq >= 8)
|
||||||
{
|
{
|
||||||
@@ -101,18 +98,18 @@ static void pic_send_eoi(uint8_t irq)
|
|||||||
outb(PIC1_COMMAND, 0x20);
|
outb(PIC1_COMMAND, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_irq_handler(uint8_t irq, irq_handler_t handler)
|
void register_irq_handler(u8 irq, irq_handler_t handler)
|
||||||
{
|
{
|
||||||
irq_handlers[irq] = handler;
|
irq_handlers[irq] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl)
|
static inline void idt_set_descriptor(u8 vector, void* handler, u8 dpl)
|
||||||
{
|
{
|
||||||
interrupt_descriptor* entry = &idt[vector];
|
interrupt_descriptor* entry = &idt[vector];
|
||||||
|
|
||||||
entry->address_low = (uint64_t)handler & 0xFFFF;
|
entry->address_low = (u64)handler & 0xFFFF;
|
||||||
entry->address_mid = ((uint64_t)handler >> 16) & 0xFFFF;
|
entry->address_mid = ((u64)handler >> 16) & 0xFFFF;
|
||||||
entry->address_high = (uint64_t)handler >> 32;
|
entry->address_high = (u64)handler >> 32;
|
||||||
entry->selector = 0x08;
|
entry->selector = 0x08;
|
||||||
entry->flags = 0b1110 | ((dpl & 0b11) << 5) | (1 << 7);
|
entry->flags = 0b1110 | ((dpl & 0b11) << 5) | (1 << 7);
|
||||||
entry->ist = 0;
|
entry->ist = 0;
|
||||||
@@ -130,7 +127,7 @@ void init_idt(void)
|
|||||||
|
|
||||||
idtr_t idtr = {
|
idtr_t idtr = {
|
||||||
.base = (uintptr_t)&idt[0],
|
.base = (uintptr_t)&idt[0],
|
||||||
.limit = (uint16_t)sizeof(interrupt_descriptor) * IDT_SIZE - 1,
|
.limit = (u16)sizeof(interrupt_descriptor) * IDT_SIZE - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
__asm__ volatile("lidt %0" : : "m"(idtr));
|
__asm__ volatile("lidt %0" : : "m"(idtr));
|
||||||
@@ -155,7 +152,7 @@ void handle_isr(isr_frame_t* frame)
|
|||||||
}
|
}
|
||||||
else if (frame->int_no < 48)
|
else if (frame->int_no < 48)
|
||||||
{
|
{
|
||||||
uint8_t irq = frame->int_no - 32;
|
u8 irq = frame->int_no - 32;
|
||||||
|
|
||||||
if (irq_handlers[irq])
|
if (irq_handlers[irq])
|
||||||
{
|
{
|
||||||
|
|||||||
20
src/idt.h
20
src/idt.h
@@ -1,30 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "typedef.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
|
u64 r15, r14, r13, r12, r11, r10, r9, r8;
|
||||||
uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax;
|
u64 rbp, rdi, rsi, rdx, rcx, rbx, rax;
|
||||||
uint64_t int_no;
|
u64 int_no;
|
||||||
uint64_t err_code;
|
u64 err_code;
|
||||||
uint64_t rip, cs, rflags, rsp, ss;
|
u64 rip, cs, rflags, rsp, ss;
|
||||||
} __attribute__((packed)) isr_frame_t;
|
} __attribute__((packed)) isr_frame_t;
|
||||||
|
|
||||||
typedef void (*irq_handler_t)(const isr_frame_t*);
|
typedef void (*irq_handler_t)(const isr_frame_t*);
|
||||||
|
|
||||||
void init_idt(void);
|
void init_idt(void);
|
||||||
|
|
||||||
static inline void outb(uint16_t port, uint8_t val)
|
static inline void outb(u16 port, u8 val)
|
||||||
{
|
{
|
||||||
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t inb(uint16_t port)
|
static inline u8 inb(u16 port)
|
||||||
{
|
{
|
||||||
uint8_t ret;
|
u8 ret;
|
||||||
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_irq_handler(uint8_t irq, irq_handler_t handler);
|
void register_irq_handler(u8 irq, irq_handler_t handler);
|
||||||
109
src/idt_stub.asm
Normal file
109
src/idt_stub.asm
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
extern handle_isr
|
||||||
|
|
||||||
|
isr_common:
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push rbp
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
|
||||||
|
mov rdi, rsp
|
||||||
|
call handle_isr
|
||||||
|
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rbp
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
|
||||||
|
add rsp, 16
|
||||||
|
iretq
|
||||||
|
|
||||||
|
%macro ISR_NOERR 1
|
||||||
|
isr_stub_%1:
|
||||||
|
push qword 0
|
||||||
|
push qword %1
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro ISR_ERR 1
|
||||||
|
isr_stub_%1:
|
||||||
|
push qword %1
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
; CPU exceptions 0-31
|
||||||
|
ISR_NOERR 0
|
||||||
|
ISR_NOERR 1
|
||||||
|
ISR_NOERR 2
|
||||||
|
ISR_NOERR 3
|
||||||
|
ISR_NOERR 4
|
||||||
|
ISR_NOERR 5
|
||||||
|
ISR_NOERR 6
|
||||||
|
ISR_NOERR 7
|
||||||
|
ISR_ERR 8
|
||||||
|
ISR_NOERR 9
|
||||||
|
ISR_ERR 10
|
||||||
|
ISR_ERR 11
|
||||||
|
ISR_ERR 12
|
||||||
|
ISR_ERR 13
|
||||||
|
ISR_ERR 14
|
||||||
|
ISR_NOERR 15
|
||||||
|
ISR_NOERR 16
|
||||||
|
ISR_ERR 17
|
||||||
|
ISR_NOERR 18
|
||||||
|
ISR_NOERR 19
|
||||||
|
ISR_NOERR 20
|
||||||
|
ISR_NOERR 21
|
||||||
|
ISR_NOERR 22
|
||||||
|
ISR_NOERR 23
|
||||||
|
ISR_NOERR 24
|
||||||
|
ISR_NOERR 25
|
||||||
|
ISR_NOERR 26
|
||||||
|
ISR_NOERR 27
|
||||||
|
ISR_NOERR 28
|
||||||
|
ISR_NOERR 29
|
||||||
|
ISR_ERR 30
|
||||||
|
ISR_NOERR 31
|
||||||
|
|
||||||
|
%macro GENERATE_ISRS 2
|
||||||
|
%assign i %1
|
||||||
|
%rep (%2 - %1 + 1)
|
||||||
|
ISR_NOERR i
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
GENERATE_ISRS 32, 255
|
||||||
|
|
||||||
|
%macro GENERATE_ISR_TABLE 2
|
||||||
|
%assign i %1
|
||||||
|
%rep (%2 - %1 + 1)
|
||||||
|
dq isr_stub_%[i]
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
global isr_stub_table
|
||||||
|
isr_stub_table:
|
||||||
|
GENERATE_ISR_TABLE 0, 255
|
||||||
15
src/kernel.c
15
src/kernel.c
@@ -1,15 +1,22 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "multiboot.h"
|
#include "idt.h"
|
||||||
|
#include "keyboard.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void kernel_main(multiboot_info_t* multiboot_info)
|
void kernel_main()
|
||||||
{
|
{
|
||||||
vga_clear();
|
vga_clear();
|
||||||
vga_print_success();
|
vga_print_success();
|
||||||
vga_print(" VGA intialzied\n");
|
vga_print(" VGA intialzied\n");
|
||||||
|
|
||||||
|
init_idt();
|
||||||
|
vga_print_success();
|
||||||
|
vga_print(" IDT intialzied\n");
|
||||||
|
|
||||||
|
init_keyboard();
|
||||||
|
vga_print_success();
|
||||||
|
vga_print(" Keyboard intialzied\n");
|
||||||
|
|
||||||
vga_print("\nWelcome to nub OS\n");
|
vga_print("\nWelcome to nub OS\n");
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void kernel_panic();
|
void kernel_panic();
|
||||||
@@ -2,8 +2,6 @@
|
|||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define SCANCODE_LEFT_SHIFT 42
|
#define SCANCODE_LEFT_SHIFT 42
|
||||||
#define SCANCODE_RIGHT_SHIFT 54
|
#define SCANCODE_RIGHT_SHIFT 54
|
||||||
@@ -34,7 +32,7 @@ bool caps_lock = false;
|
|||||||
static keyboard_handler_t keyboard_handlers[KEYBOARD_HANDLERS_LENGTH];
|
static keyboard_handler_t keyboard_handlers[KEYBOARD_HANDLERS_LENGTH];
|
||||||
static int handler_index = 0;
|
static int handler_index = 0;
|
||||||
|
|
||||||
char scan_code_to_ascii(uint8_t scan_code)
|
char scan_code_to_ascii(u8 scan_code)
|
||||||
{
|
{
|
||||||
if (scan_code >= 128)
|
if (scan_code >= 128)
|
||||||
{
|
{
|
||||||
@@ -53,8 +51,8 @@ char scan_code_to_ascii(uint8_t scan_code)
|
|||||||
|
|
||||||
void handle_keyboard(const isr_frame_t* frame)
|
void handle_keyboard(const isr_frame_t* frame)
|
||||||
{
|
{
|
||||||
uint8_t code = inb(0x60);
|
u8 code = inb(0x60);
|
||||||
uint8_t scan_code = code & 0x7F;
|
u8 scan_code = code & 0x7F;
|
||||||
bool pressed = (code & 0x80) == 0;
|
bool pressed = (code & 0x80) == 0;
|
||||||
|
|
||||||
switch (scan_code)
|
switch (scan_code)
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include "typedef.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t scan_code;
|
u8 scan_code;
|
||||||
bool pressed;
|
bool pressed;
|
||||||
bool shift;
|
bool shift;
|
||||||
bool caps_lock;
|
bool caps_lock;
|
||||||
@@ -16,4 +15,4 @@ typedef void (*keyboard_handler_t)(const keyboard_event_t*);
|
|||||||
|
|
||||||
void init_keyboard();
|
void init_keyboard();
|
||||||
void register_keypress_handler(keyboard_handler_t handler);
|
void register_keypress_handler(keyboard_handler_t handler);
|
||||||
char scan_code_to_ascii(uint8_t scan_code);
|
char scan_code_to_ascii(u8 scan_code);
|
||||||
@@ -1,58 +1,59 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
|
||||||
|
#include "typedef.h"
|
||||||
|
|
||||||
typedef struct multiboot_info
|
typedef struct multiboot_info
|
||||||
{
|
{
|
||||||
uint32_t flags; // required
|
u32 flags; // required
|
||||||
|
|
||||||
// Available if flags[0] is set
|
// Available if flags[0] is set
|
||||||
uint32_t mem_lower;
|
u32 mem_lower;
|
||||||
uint32_t mem_upper;
|
u32 mem_upper;
|
||||||
|
|
||||||
// Available if flags[1] is set
|
// Available if flags[1] is set
|
||||||
uint32_t boot_device;
|
u32 boot_device;
|
||||||
|
|
||||||
// Available if flags[2] is set
|
// Available if flags[2] is set
|
||||||
uint32_t cmdline;
|
u32 cmdline;
|
||||||
|
|
||||||
// Available if flags[3] is set
|
// Available if flags[3] is set
|
||||||
uint32_t mods_count;
|
u32 mods_count;
|
||||||
uint32_t mods_addr;
|
u32 mods_addr;
|
||||||
|
|
||||||
// Available if flags[4] or flags[5] is set
|
// Available if flags[4] or flags[5] is set
|
||||||
uint8_t syms[16]; // 28 - 40 bytes, exact layout may differ depending on a.out or ELF
|
u8 syms[16]; // 28 - 40 bytes, exact layout may differ depending on a.out or ELF
|
||||||
|
|
||||||
// Available if flags[6] is set
|
// Available if flags[6] is set
|
||||||
uint32_t mmap_length;
|
u32 mmap_length;
|
||||||
uint32_t mmap_addr;
|
u32 mmap_addr;
|
||||||
|
|
||||||
// Available if flags[7] is set
|
// Available if flags[7] is set
|
||||||
uint32_t drives_length;
|
u32 drives_length;
|
||||||
uint32_t drives_addr;
|
u32 drives_addr;
|
||||||
|
|
||||||
// Available if flags[8] is set
|
// Available if flags[8] is set
|
||||||
uint32_t config_table;
|
u32 config_table;
|
||||||
|
|
||||||
// Available if flags[9] is set
|
// Available if flags[9] is set
|
||||||
uint32_t boot_loader_name;
|
u32 boot_loader_name;
|
||||||
|
|
||||||
// Available if flags[10] is set
|
// Available if flags[10] is set
|
||||||
uint32_t apm_table;
|
u32 apm_table;
|
||||||
|
|
||||||
// Available if flags[11] is set
|
// Available if flags[11] is set
|
||||||
uint32_t vbe_control_info;
|
u32 vbe_control_info;
|
||||||
uint32_t vbe_mode_info;
|
u32 vbe_mode_info;
|
||||||
uint16_t vbe_mode;
|
u16 vbe_mode;
|
||||||
uint16_t vbe_interface_seg;
|
u16 vbe_interface_seg;
|
||||||
uint16_t vbe_interface_off;
|
u16 vbe_interface_off;
|
||||||
uint16_t vbe_interface_len;
|
u16 vbe_interface_len;
|
||||||
|
|
||||||
// Available if flags[12] is set
|
// Available if flags[12] is set
|
||||||
uint64_t framebuffer_addr; // 64-bit for large memory addresses
|
u64 framebuffer_addr; // 64-bit for large memory addresses
|
||||||
uint32_t framebuffer_pitch;
|
u32 framebuffer_pitch;
|
||||||
uint32_t framebuffer_width;
|
u32 framebuffer_width;
|
||||||
uint32_t framebuffer_height;
|
u32 framebuffer_height;
|
||||||
uint8_t framebuffer_bpp;
|
u8 framebuffer_bpp;
|
||||||
uint8_t framebuffer_type;
|
u8 framebuffer_type;
|
||||||
uint8_t color_info[6]; // 110-115 bytes
|
u8 color_info[6]; // 110-115 bytes
|
||||||
} __attribute__((packed)) multiboot_info_t;
|
} __attribute__((packed)) multiboot_info_t;
|
||||||
11
src/string.c
11
src/string.c
@@ -1,5 +1,4 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
int strcmp(const char* a, const char* b)
|
int strcmp(const char* a, const char* b)
|
||||||
{
|
{
|
||||||
@@ -26,7 +25,7 @@ void reverse(char* str, size_t length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int uitoa(uint32_t value, char* buffer)
|
int uitoa(u64 value, char* buffer)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
@@ -47,7 +46,7 @@ int uitoa(uint32_t value, char* buffer)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int itoa(int32_t value, char* buffer)
|
int itoa(i64 value, char* buffer)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -59,16 +58,16 @@ int itoa(int32_t value, char* buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
uint32_t v;
|
u64 v;
|
||||||
|
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
{
|
{
|
||||||
negative = true;
|
negative = true;
|
||||||
v = (uint32_t)(-value);
|
v = (u64)(-value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v = (uint32_t)value;
|
v = (u64)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (v > 0)
|
while (v > 0)
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h>
|
#include "typedef.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
int strcmp(const char* a, const char* b);
|
int strcmp(const char* a, const char* b);
|
||||||
void reverse(char* str, size_t length);
|
void reverse(char* str, size_t length);
|
||||||
int uitoa(uint32_t value, char* buffer);
|
int uitoa(u64 value, char* buffer);
|
||||||
int itoa(int32_t value, char* buffer);
|
int itoa(i64 value, char* buffer);
|
||||||
16
src/typedef.h
Normal file
16
src/typedef.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef signed char i8;
|
||||||
|
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef signed short i16;
|
||||||
|
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef signed int i32;
|
||||||
|
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
typedef signed long long i64;
|
||||||
|
|
||||||
|
typedef u64 size_t;
|
||||||
|
typedef u64 uintptr_t;
|
||||||
35
src/vga.c
35
src/vga.c
@@ -1,37 +1,34 @@
|
|||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define ROWS 25
|
#define ROWS 25
|
||||||
#define COLUMNS 80
|
#define COLUMNS 80
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t character;
|
u8 character;
|
||||||
uint8_t color;
|
u8 color;
|
||||||
} vga_char;
|
} vga_char;
|
||||||
|
|
||||||
vga_char* vga_buffer = (vga_char*)0xb8000;
|
vga_char* vga_buffer = (vga_char*)0xb8000;
|
||||||
uint8_t cursor_row = 0;
|
u8 cursor_row = 0;
|
||||||
uint8_t cursor_col = 0;
|
u8 cursor_col = 0;
|
||||||
|
|
||||||
void vga_set_char(uint8_t row, uint8_t col, vga_char character)
|
void vga_set_char(u8 row, u8 col, vga_char character)
|
||||||
{
|
{
|
||||||
vga_buffer[COLUMNS * row + col] = character;
|
vga_buffer[COLUMNS * row + col] = character;
|
||||||
}
|
}
|
||||||
|
|
||||||
vga_char vga_char_at(uint8_t row, uint8_t col)
|
vga_char vga_char_at(u8 row, u8 col)
|
||||||
{
|
{
|
||||||
return vga_buffer[COLUMNS * row + col];
|
return vga_buffer[COLUMNS * row + col];
|
||||||
}
|
}
|
||||||
|
|
||||||
void vga_clear(void)
|
void vga_clear(void)
|
||||||
{
|
{
|
||||||
for (uint8_t row = 0; row < ROWS; row++)
|
for (u8 row = 0; row < ROWS; row++)
|
||||||
{
|
{
|
||||||
for (uint8_t col = 0; col < COLUMNS; col++)
|
for (u8 col = 0; col < COLUMNS; col++)
|
||||||
{
|
{
|
||||||
vga_char character = {
|
vga_char character = {
|
||||||
.character = ' ',
|
.character = ' ',
|
||||||
@@ -45,7 +42,7 @@ void vga_clear(void)
|
|||||||
cursor_col = 0;
|
cursor_col = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vga_set_cursor_position(uint8_t row, uint8_t col)
|
void vga_set_cursor_position(u8 row, u8 col)
|
||||||
{
|
{
|
||||||
if (row < ROWS && col < COLUMNS)
|
if (row < ROWS && col < COLUMNS)
|
||||||
{
|
{
|
||||||
@@ -71,7 +68,7 @@ void vga_print_char_colored(char character, vga_color_t color)
|
|||||||
}
|
}
|
||||||
case '\t':
|
case '\t':
|
||||||
{
|
{
|
||||||
uint8_t remainter = cursor_col % 4;
|
u8 remainter = cursor_col % 4;
|
||||||
cursor_col += remainter == 0 ? 4 : remainter;
|
cursor_col += remainter == 0 ? 4 : remainter;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -95,15 +92,15 @@ void vga_print_char_colored(char character, vga_color_t color)
|
|||||||
|
|
||||||
if (cursor_row >= ROWS)
|
if (cursor_row >= ROWS)
|
||||||
{
|
{
|
||||||
for (uint8_t row = 1; row < ROWS; row++)
|
for (u8 row = 1; row < ROWS; row++)
|
||||||
{
|
{
|
||||||
for (uint8_t col = 0; col < COLUMNS; col++)
|
for (u8 col = 0; col < COLUMNS; col++)
|
||||||
{
|
{
|
||||||
vga_set_char(row - 1, col, vga_char_at(row, col));
|
vga_set_char(row - 1, col, vga_char_at(row, col));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t col = 0; col < COLUMNS; col++)
|
for (u8 col = 0; col < COLUMNS; col++)
|
||||||
{
|
{
|
||||||
vga_char c = {
|
vga_char c = {
|
||||||
.character = ' ',
|
.character = ' ',
|
||||||
@@ -118,7 +115,7 @@ void vga_print_char_colored(char character, vga_color_t color)
|
|||||||
|
|
||||||
void vga_print_colored(const char* string, vga_color_t color)
|
void vga_print_colored(const char* string, vga_color_t color)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; string[i] != '\0'; i++)
|
for (u8 i = 0; string[i] != '\0'; i++)
|
||||||
{
|
{
|
||||||
vga_print_char_colored(string[i], color);
|
vga_print_char_colored(string[i], color);
|
||||||
}
|
}
|
||||||
@@ -138,14 +135,14 @@ void vga_print_error(void)
|
|||||||
vga_print(" ]");
|
vga_print(" ]");
|
||||||
}
|
}
|
||||||
|
|
||||||
void vga_print_uint(uint32_t value)
|
void vga_print_uint(u32 value)
|
||||||
{
|
{
|
||||||
char buffer[11];
|
char buffer[11];
|
||||||
uitoa(value, buffer);
|
uitoa(value, buffer);
|
||||||
vga_print(buffer);
|
vga_print(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vga_print_int(int32_t value)
|
void vga_print_int(i32 value)
|
||||||
{
|
{
|
||||||
char buffer[12];
|
char buffer[12];
|
||||||
itoa(value, buffer);
|
itoa(value, buffer);
|
||||||
|
|||||||
10
src/vga.h
10
src/vga.h
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "typedef.h"
|
||||||
|
|
||||||
#define VGA_BLACK 0
|
#define VGA_BLACK 0
|
||||||
#define VGA_BLUE 1
|
#define VGA_BLUE 1
|
||||||
@@ -19,10 +19,10 @@
|
|||||||
#define VGA_YELLOW 14
|
#define VGA_YELLOW 14
|
||||||
#define VGA_WHITE 15
|
#define VGA_WHITE 15
|
||||||
|
|
||||||
typedef uint8_t vga_color_t;
|
typedef u8 vga_color_t;
|
||||||
|
|
||||||
void vga_clear(void);
|
void vga_clear(void);
|
||||||
void vga_set_cursor_position(uint8_t row, uint8_t col);
|
void vga_set_cursor_position(u8 row, u8 col);
|
||||||
|
|
||||||
void vga_print_char_colored(char character, vga_color_t color);
|
void vga_print_char_colored(char character, vga_color_t color);
|
||||||
void vga_print_colored(const char* string, vga_color_t color);
|
void vga_print_colored(const char* string, vga_color_t color);
|
||||||
@@ -30,8 +30,8 @@ void vga_print_colored(const char* string, vga_color_t color);
|
|||||||
void vga_print_success(void);
|
void vga_print_success(void);
|
||||||
void vga_print_error(void);
|
void vga_print_error(void);
|
||||||
|
|
||||||
void vga_print_uint(uint32_t value);
|
void vga_print_uint(u32 value);
|
||||||
void vga_print_int(int32_t value);
|
void vga_print_int(i32 value);
|
||||||
|
|
||||||
static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color)
|
static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user