mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-11-21 18:42:19 +00:00
refactor, new arch dirs, (wip) page alloc on write, hsv screen (convert to userspace later), other fixes
This commit is contained in:
parent
6d7a563d36
commit
90a6065691
27 changed files with 320 additions and 129 deletions
11
include/bochs.h
Normal file
11
include/bochs.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Loads the framebuffer
|
||||
* @param width - the width of the screen
|
||||
* @param height - the height of the screen
|
||||
*/
|
||||
uint32_t *bochs_init(uint16_t w, uint16_t h, uint8_t b);
|
|
@ -1,5 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int fb_init(uint16_t res_x, uint16_t res_y);
|
13
include/screen.h
Normal file
13
include/screen.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <shim.h>
|
||||
|
||||
/**
|
||||
* Initalizes the screen and framebuffer
|
||||
*/
|
||||
void screen_init(void);
|
||||
|
||||
/**
|
||||
* Redraws the screen
|
||||
*/
|
||||
void screen_redraw(void);
|
|
@ -15,16 +15,17 @@ struct memory_map {
|
|||
struct memory_segment entries[MMAP_MAX_ENTRY];
|
||||
};
|
||||
|
||||
//struct framebuffer {
|
||||
// uint64_t addr;
|
||||
// uint32_t pitch;
|
||||
// uint32_t width;
|
||||
// uint32_t height;
|
||||
// uint8_t bit_depth;
|
||||
//};
|
||||
struct framebuffer {
|
||||
uint64_t addr;
|
||||
uint32_t pitch;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint8_t bit_depth;
|
||||
};
|
||||
|
||||
struct boot_info {
|
||||
struct memory_map map;
|
||||
struct framebuffer fb;
|
||||
void *symbol_table;
|
||||
void *acpi_table;
|
||||
char cmdline[CMDLINE_MAX];
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
#include <acpi.h>
|
||||
#include <lib.h>
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <panic.h>
|
||||
|
||||
#include "bindings.h"
|
||||
#include "memory.h"
|
||||
|
||||
/* global state, idk a better way rn */
|
||||
struct acpi_state state;
|
||||
|
||||
struct acpi_header {
|
||||
char signature[4];
|
||||
|
@ -20,7 +18,7 @@ struct acpi_header {
|
|||
uint32_t oem_revision;
|
||||
uint32_t creator_id;
|
||||
uint32_t creator_revision;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
// root system descriptor pointer
|
||||
// ACPI 1.0
|
||||
|
@ -30,7 +28,7 @@ struct rsdp {
|
|||
char oemid[6];
|
||||
uint8_t revision;
|
||||
uint32_t rsdt_addr;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
// eXtended system descriptor pointer
|
||||
// ACPI 2.0
|
||||
|
@ -45,7 +43,7 @@ struct xsdp {
|
|||
uint64_t xsdt_addr;
|
||||
uint8_t extendeid_checksum;
|
||||
uint8_t reserved[3];
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
// root system descriptor table
|
||||
// ACPI 1.0
|
||||
|
@ -152,6 +150,9 @@ struct acpi_state {
|
|||
uint16_t SCI_EN;
|
||||
};
|
||||
|
||||
/* global state, idk a better way rn */
|
||||
static struct acpi_state state;
|
||||
|
||||
static bool checksum(uint8_t *data, size_t len) {
|
||||
unsigned char sum = 0;
|
||||
for (size_t i = 0; i < len; i++)
|
||||
|
@ -230,6 +231,9 @@ static void *acpi_find_table_xsdt(struct xsdt *xsdt, const char *identifier, int
|
|||
}
|
||||
|
||||
int acpi_init_rsdt(struct rsdt *rsdt) {
|
||||
|
||||
kprintf("RSDT: %#016lx\n", (size_t)rsdt);
|
||||
|
||||
rsdt = mmap(rsdt, sizeof(struct rsdt));
|
||||
|
||||
state.dst.rsdt = rsdt;
|
||||
|
@ -278,23 +282,35 @@ int acpi_init(void *rootsdp) {
|
|||
if (!checksum((uint8_t *)rsdp, sizeof(struct rsdp)))
|
||||
return -1;
|
||||
|
||||
if (strncmp(rsdp->signature, "RSD PTR ", 8) != 0) {
|
||||
panic("invalid acpi rsdp signature: %.*s\n", 8, rsdp->signature);
|
||||
}
|
||||
|
||||
int res;
|
||||
|
||||
if (rsdp->revision == 0) {
|
||||
kprintf("ACPI 1.0\n");
|
||||
kprintf("RSDP: %#016lx\n", (size_t)rsdp);
|
||||
res = acpi_init_rsdt(
|
||||
(struct rsdt *) (uintptr_t) rsdp->rsdt_addr
|
||||
);
|
||||
} else if (rsdp->revision == 2) {
|
||||
struct xsdp *xsdp = (struct xsdp *) rsdp;
|
||||
kprintf("ACPI 2.0\n");
|
||||
kprintf("XSDP: %#016lx\n", (size_t)xsdp);
|
||||
res = acpi_init_xsdt(
|
||||
(struct xsdt *) (uintptr_t) xsdp->xsdt_addr
|
||||
);
|
||||
} else {
|
||||
return -1;
|
||||
panic("invalid acpi rev: %d\n", rsdp->revision);
|
||||
}
|
||||
|
||||
if (res)
|
||||
if (res) {
|
||||
kprintf("...acpi failed to load\n\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
kprintf("\n\n");
|
||||
|
||||
int ret = read_s5_addr(&state);
|
||||
if (!ret)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stddef.h>
|
||||
#include <backtrace.h>
|
||||
#include <serial.h>
|
||||
|
||||
#include "debugger.h"
|
||||
|
||||
struct dr6 {
|
||||
|
@ -195,8 +196,8 @@ static int debugger_handle_bkp_cmd(char *msg) {
|
|||
const char *lenstrs[] = {"1", "2", "8", "4"};
|
||||
const char *rwstrs[] = {"x ", "w ", "io", "rw"};
|
||||
kprintf(
|
||||
"breakpoint %d: %#016lx len=%s trigger=%s instrlen=%01d %s\n",
|
||||
i,
|
||||
"breakpoint %d: %#016lx len=%s trigger=%s instrlen=%01d %s\n",
|
||||
i,
|
||||
bkp.addr,
|
||||
lenstrs[bkp.len],
|
||||
rwstrs[bkp.rw],
|
|
@ -3,7 +3,7 @@
|
|||
#include "idt.h"
|
||||
|
||||
#define DEBUG_INT3 0x00
|
||||
#define DEBUG_DBG 0x01
|
||||
#define DEBUG_DBG 0x01
|
||||
#define DEBUG_FAULT 0x02
|
||||
|
||||
void debugger(struct isr_regs *state, int cause);
|
|
@ -2,10 +2,10 @@
|
|||
#include <stddef.h>
|
||||
#include <lib.h>
|
||||
#include <panic.h>
|
||||
|
||||
#include "debugger.h"
|
||||
#include "idt.h"
|
||||
#include "pic.h"
|
||||
#include "debugger.h"
|
||||
#include "../paging.h"
|
||||
#include "../drivers/pic.h"
|
||||
|
||||
#define IDT_SIZE 256
|
||||
|
||||
|
@ -148,7 +148,7 @@ void idt_pic_timer(void) {
|
|||
// print a message once we know the timer works
|
||||
// but avoid spamming the logs
|
||||
if (counter == 3) {
|
||||
kputs("pic timer!\n");
|
||||
//kputs("pic timer!\n");
|
||||
}
|
||||
if (counter <= 3) {
|
||||
counter++;
|
||||
|
@ -158,4 +158,3 @@ void idt_pic_timer(void) {
|
|||
void idt_pic_keyboard(void) {}
|
||||
|
||||
void idt_pic_mouse(void) {}
|
||||
|
|
@ -3,8 +3,9 @@
|
|||
#include <stdint.h>
|
||||
#include <panic.h>
|
||||
#include <pci.h>
|
||||
#include <bochs.h>
|
||||
|
||||
#include "bindings.h"
|
||||
#include "../bindings.h"
|
||||
|
||||
#define INDEX 0x1CE
|
||||
#define DATA 0x1CF
|
||||
|
@ -52,38 +53,21 @@ static void set_mode(uint16_t width, uint16_t height, uint16_t bit_depth, int lf
|
|||
(clear ? 0 : DATA_NO_CLEAR_MEM));
|
||||
}
|
||||
|
||||
//static void set_bank(uint16_t bank) {
|
||||
// write(INDEX_BANK, bank);
|
||||
//}
|
||||
uint32_t* bochs_init(uint16_t width, uint16_t height, uint8_t bit_depth) {
|
||||
|
||||
int fb_init(uint16_t width, uint16_t height) {
|
||||
|
||||
set_mode(width, height, 32, true, true);
|
||||
set_mode(width, height, bit_depth, true, true);
|
||||
|
||||
if (!is_available())
|
||||
panic("bochs framebuffer not avaliable");
|
||||
return NULL;
|
||||
|
||||
struct pci_device bochs = {0};
|
||||
bool found = pci_findby_id(&bochs, BOCHS_PCI_DEVICE, BOCHS_PCI_VENDOR, NULL);
|
||||
if (!found)
|
||||
panic("bochs pci device not avaliable");
|
||||
return NULL;
|
||||
|
||||
uint32_t bar0 = pci_rcfg_d(bochs, PCI_BAR0_D);
|
||||
uint32_t *fb = (uint32_t*) (uintptr_t) bar0;
|
||||
fb = mmap(fb, width * height * 4);
|
||||
uint32_t *addr = (uint32_t*) (uintptr_t) bar0;
|
||||
addr = mmap(addr, width * height * bit_depth);
|
||||
|
||||
for (uint16_t y = 0; y < height; y++) {
|
||||
for (uint16_t x = 0; x < width; x++) {
|
||||
double dx = x / (double) width,
|
||||
dy = y / (double) height,
|
||||
dz = (2 - dx - dy) / 2;
|
||||
uint32_t r = (uint32_t)(dx * 255),
|
||||
g = (uint32_t)(dy * 255),
|
||||
b = (uint32_t)(dz * 255);
|
||||
fb[x + y * width] = (b << 0) | (g << 8) | (r << 16);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
return addr;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
#include <panic.h>
|
||||
#include <lib.h>
|
||||
|
||||
#include "bindings.h"
|
||||
#include "../bindings.h"
|
||||
|
||||
#define CONF_ADDR 0xCF8
|
||||
#define CONF_DATA 0xCFC
|
|
@ -1,4 +1,4 @@
|
|||
#include "bindings.h"
|
||||
#include "../bindings.h"
|
||||
#include "pic.h"
|
||||
|
||||
#define PIC1 0x20 /* IO base address for master PIC */
|
|
@ -1,5 +1,6 @@
|
|||
#include <serial.h>
|
||||
#include "bindings.h"
|
||||
|
||||
#include "../bindings.h"
|
||||
|
||||
#define PORT 0x3F8
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#include <fpu.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <lib.h>
|
||||
|
||||
void enable_fpu() {
|
||||
size_t cr4;
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
ENTRY(start)
|
||||
|
||||
SECTIONS {
|
||||
. = 1M;
|
||||
|
||||
kernel_start = .;
|
||||
|
||||
.boot BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.multiboot)
|
||||
}
|
||||
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
text_start = .;
|
||||
|
||||
.text BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
|
||||
text_end = .;
|
||||
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
kernel_end = .;
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#define MBOOT_CMDLINE 1
|
||||
#define MBOOT_MEMORY_MAP 6
|
||||
#define MBOOT_FRAMEBUFFER 8
|
||||
#define MBOOT_ELF_SYMBOLS 9
|
||||
#define MBOOT_OLD_RSDP 14
|
||||
#define MBOOT_NEW_RSDP 15
|
||||
|
@ -82,6 +83,18 @@ struct mboot_tag_cmdline {
|
|||
uint8_t cmdline[];
|
||||
};
|
||||
|
||||
struct mboot_tag_framebuffer {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint64_t framebuffer_addr;
|
||||
uint32_t framebuffer_pitch;
|
||||
uint32_t framebuffer_width;
|
||||
uint32_t framebuffer_height;
|
||||
uint8_t framebuffer_bpp;
|
||||
uint8_t framebuffer_type;
|
||||
uint16_t reserved;
|
||||
};
|
||||
|
||||
static void read_symbols(
|
||||
struct boot_info *shim_info,
|
||||
struct mboot_tag_elf_sections *sections
|
||||
|
@ -133,6 +146,17 @@ static void read_cmdline(
|
|||
shim_info->cmdline[size] = '\0';
|
||||
}
|
||||
|
||||
static void read_framebuffer(
|
||||
struct boot_info *shim_info,
|
||||
struct mboot_tag_framebuffer *framebuffer
|
||||
) {
|
||||
shim_info->fb.addr = framebuffer->framebuffer_addr;
|
||||
shim_info->fb.width = framebuffer->framebuffer_width;
|
||||
shim_info->fb.height = framebuffer->framebuffer_height;
|
||||
shim_info->fb.pitch = framebuffer->framebuffer_pitch;
|
||||
shim_info->fb.bit_depth = framebuffer->framebuffer_bpp;
|
||||
}
|
||||
|
||||
static const char *segment_type[] = {
|
||||
"Reserved",
|
||||
"Free",
|
||||
|
@ -217,6 +241,12 @@ void mboot_load_info(
|
|||
(struct mboot_tag_cmdline *) tag
|
||||
);
|
||||
break;
|
||||
case MBOOT_FRAMEBUFFER:
|
||||
read_framebuffer(
|
||||
shim_info,
|
||||
(struct mboot_tag_framebuffer *) tag
|
||||
);
|
||||
break;
|
||||
case MBOOT_MEMORY_MAP:
|
||||
read_memory_map(
|
||||
shim_info,
|
||||
|
|
|
@ -45,7 +45,8 @@ struct pde {
|
|||
// PAGE TABLE ENTRY
|
||||
struct pte {
|
||||
uint64_t flags : 9;
|
||||
uint64_t : 3;
|
||||
uint64_t loaded : 1;
|
||||
uint64_t : 2;
|
||||
uint64_t address : 40;
|
||||
uint64_t : 7;
|
||||
uint64_t protection_key : 4;
|
||||
|
@ -69,7 +70,7 @@ static struct pde *pd_mapped = (void *) (uintptr_t) 0x202000;
|
|||
static struct pte *pt_mapped = (void *) (uintptr_t) 0x203000;
|
||||
|
||||
static inline void invlpg(void *addr) {
|
||||
__asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
||||
__asm__ volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
||||
}
|
||||
|
||||
static void load_addr(void *phys_addr) {
|
||||
|
@ -297,6 +298,7 @@ static void unmap_page(
|
|||
|
||||
page->address = 0;
|
||||
page->flags = 0;
|
||||
page->loaded = 0;
|
||||
|
||||
try_unmap_pt();
|
||||
|
||||
|
@ -360,6 +362,7 @@ static void unmap_pages(
|
|||
|
||||
page->address = 0;
|
||||
page->flags = 0;
|
||||
page->loaded = 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -369,6 +372,31 @@ static void unmap_pages(
|
|||
return;
|
||||
}
|
||||
|
||||
static struct pte *get_page(
|
||||
struct pml4e *root,
|
||||
void *virt
|
||||
) {
|
||||
struct pdpte *pdpt;
|
||||
struct pde *pd;
|
||||
struct pte *pt;
|
||||
struct pte *page;
|
||||
|
||||
unsigned int df = 0;
|
||||
|
||||
if (select_pdpt(virt, df, root, &pdpt, false))
|
||||
return NULL;
|
||||
|
||||
if (select_pd(virt, df, pdpt, &pd, false))
|
||||
return NULL;
|
||||
|
||||
if (select_pt(virt, df, pd, &pt, false))
|
||||
return NULL;
|
||||
|
||||
select_page(virt, pt, &page);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
static int map_page(
|
||||
struct pml4e *root,
|
||||
void *virt,
|
||||
|
@ -382,6 +410,9 @@ static int map_page(
|
|||
|
||||
unsigned int df = F_WRITEABLE;
|
||||
|
||||
if (phys == NULL)
|
||||
df = 0; // alloc page on fault
|
||||
|
||||
if (select_pdpt(virt, df, root, &pdpt, true))
|
||||
return 1;
|
||||
|
||||
|
@ -393,9 +424,16 @@ static int map_page(
|
|||
|
||||
select_page(virt, pt, &page);
|
||||
|
||||
page->address = (uint64_t)phys >> 12;
|
||||
page->flags = F_PRESENT | flags;
|
||||
invlpg(virt);
|
||||
if (phys) {
|
||||
page->flags = F_PRESENT | flags;
|
||||
page->address = (uint64_t)phys >> 12;
|
||||
page->loaded = 1;
|
||||
invlpg(virt);
|
||||
} else {
|
||||
page->flags = flags;
|
||||
page->address = 0;
|
||||
page->loaded = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -424,6 +462,9 @@ static int map_pages(
|
|||
|
||||
unsigned int df = F_WRITEABLE;
|
||||
|
||||
if (phys_start == NULL)
|
||||
df = 0; // alloc page on fault
|
||||
|
||||
long i;
|
||||
for (i = 0; i < page_count; i++) {
|
||||
|
||||
|
@ -454,15 +495,22 @@ static int map_pages(
|
|||
|
||||
select_page(virt, pt, &page);
|
||||
|
||||
page->address = (uint64_t)phys >> 12;
|
||||
page->flags = F_PRESENT | flags;
|
||||
if (phys_start) {
|
||||
page->flags = F_PRESENT | flags;
|
||||
page->address = (uint64_t)phys >> 12;
|
||||
page->loaded = 1;
|
||||
} else {
|
||||
page->flags = flags;
|
||||
page->address = 0;
|
||||
page->loaded = 0;
|
||||
}
|
||||
|
||||
if (flags & F_GLOBAL)
|
||||
invlpg(virt);
|
||||
|
||||
}
|
||||
|
||||
__asm volatile("mov %cr3, %rax; mov %rax, %cr3;");
|
||||
__asm__ volatile("mov %cr3, %rax; mov %rax, %cr3;");
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -575,3 +623,21 @@ int kunmap_page(void *virt_addr) {
|
|||
unmap_page(kernel_pml4, virt_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kload_page(void *virt_addr) {
|
||||
struct pte *page = get_page(kernel_pml4, virt_addr);
|
||||
if (page == NULL)
|
||||
return -1;
|
||||
if (page->loaded)
|
||||
return -1;
|
||||
void *phys = alloc_phys_page();
|
||||
kprintf("0x%p\n", phys);
|
||||
if (phys == NULL)
|
||||
return -2;
|
||||
page->loaded = 1;
|
||||
page->address = (uint64_t)phys >> 12;
|
||||
page->flags |= F_PRESENT | F_WRITEABLE;
|
||||
invlpg(virt_addr);
|
||||
__asm__ volatile ("movq %cr3, %rax; movq %rax, %cr3;");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,3 +13,4 @@
|
|||
void paging_init(void);
|
||||
int kmap_page(void *virt_addr, void *phys_addr, unsigned int flags);
|
||||
int kunmap_page(void *virt_addr);
|
||||
int kload_page(void *virt_addr);
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "paging.h"
|
||||
#include "mboot.h"
|
||||
#include "idt.h"
|
||||
#include "pic.h"
|
||||
#include "cpu/idt.h"
|
||||
#include "drivers/pic.h"
|
||||
|
||||
static struct boot_info boot_info;
|
||||
|
||||
|
|
17
src/kmain.c
17
src/kmain.c
|
@ -1,28 +1,27 @@
|
|||
#include "fpu.h"
|
||||
#include <fpu.h>
|
||||
#include <acpi.h>
|
||||
#include <memory.h>
|
||||
#include <lib.h>
|
||||
#include <fb.h>
|
||||
#include <serial.h>
|
||||
#include <shim.h>
|
||||
#include <panic.h>
|
||||
#include <pci.h>
|
||||
#include <screen.h>
|
||||
|
||||
void kmain(struct boot_info *info) {
|
||||
enable_fpu();
|
||||
memory_init(&info->map);
|
||||
pci_init();
|
||||
fb_init(1024, 768);
|
||||
//acpi_init(info->acpi_table);
|
||||
screen_init();
|
||||
acpi_init(info->acpi_table);
|
||||
|
||||
kprintf("enterd kmain\n");
|
||||
|
||||
*(char *)(0xB8000 + 0x144) = 'h';
|
||||
*(char *)(0xB8000 + 0x146) = 'i';
|
||||
char *test = kalloc(5);
|
||||
*test = 1;
|
||||
|
||||
|
||||
while (1) {
|
||||
__asm__("hlt;");
|
||||
// loop so we dont halt
|
||||
// this allows interrupts to fire
|
||||
screen_redraw();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,9 @@ void *memmove(void *dest, const void *src, unsigned long n) {
|
|||
|
||||
void *memset(void *restrict dest, int c, unsigned long n) {
|
||||
unsigned char *d = dest;
|
||||
for (; n; n--) *d++ = c;
|
||||
for (; n; n--) {
|
||||
*d++ = c;
|
||||
};
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ void *kalloc_new(size_t size) {
|
|||
node = 0;
|
||||
}
|
||||
|
||||
memset(addr, 0, pages * PAGE_SIZE);
|
||||
memcpy(addr, 0, pages * PAGE_SIZE);
|
||||
struct page_header *header = addr;
|
||||
header->magic = 0xBEEFCAFE;
|
||||
header->used = size;
|
||||
|
|
35
src/print.c
35
src/print.c
|
@ -138,6 +138,7 @@ static struct format_precision read_precision(const char *format, const char **e
|
|||
if (c == '*' && precision.defined == false) {
|
||||
precision.defined = true;
|
||||
precision.varys = true;
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -336,7 +337,7 @@ static void print_unum(
|
|||
char buf[1024];
|
||||
char *str = get_decimal(
|
||||
num,
|
||||
buf,
|
||||
buf + 1023,
|
||||
sign,
|
||||
radix,
|
||||
base
|
||||
|
@ -457,11 +458,21 @@ void kvprintf(const char *format, va_list args) {
|
|||
char c;
|
||||
const char *str;
|
||||
void *ptr;
|
||||
} data;
|
||||
} data = {0};
|
||||
|
||||
int radix = 0;
|
||||
char base = 0;
|
||||
|
||||
if (width.varys) {
|
||||
int len = va_arg(args, int);
|
||||
width.value = len;
|
||||
}
|
||||
|
||||
if (precision.varys) {
|
||||
int len = va_arg(args, int);
|
||||
precision.value = len;
|
||||
}
|
||||
|
||||
switch (conversion) {
|
||||
case FMT_INT:
|
||||
if (modifier == MOD_NONE)
|
||||
|
@ -475,7 +486,15 @@ void kvprintf(const char *format, va_list args) {
|
|||
else if (modifier == MOD_LONG_LONG)
|
||||
data.l = va_arg(args, long long);
|
||||
radix = 10;
|
||||
goto printnum;
|
||||
print_num(
|
||||
data.l,
|
||||
flag,
|
||||
width,
|
||||
precision,
|
||||
radix,
|
||||
base
|
||||
);
|
||||
break;
|
||||
case FMT_UINT:
|
||||
case FMT_OCT:
|
||||
case FMT_HEX_UPPER:
|
||||
|
@ -503,6 +522,7 @@ void kvprintf(const char *format, va_list args) {
|
|||
base = 'A';
|
||||
}
|
||||
goto printunum;
|
||||
break;
|
||||
case FMT_PTR:
|
||||
case FMT_PTR_UPPER:
|
||||
flag |= FLG_ZERO;
|
||||
|
@ -513,15 +533,6 @@ void kvprintf(const char *format, va_list args) {
|
|||
else
|
||||
base = 'A';
|
||||
goto printunum;
|
||||
printnum:
|
||||
print_num(
|
||||
data.l,
|
||||
flag,
|
||||
width,
|
||||
precision,
|
||||
radix,
|
||||
base
|
||||
);
|
||||
break;
|
||||
printunum:
|
||||
print_unum(
|
||||
|
|
98
src/screen.c
Normal file
98
src/screen.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include <lib.h>
|
||||
#include <screen.h>
|
||||
#include <bochs.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define SCREEN_WIDTH 1024
|
||||
#define SCREEN_HEIGHT 768
|
||||
#define SCREEN_BIT_DEPTH 32
|
||||
|
||||
struct rgb {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
struct hsv {
|
||||
uint16_t h;
|
||||
uint16_t s;
|
||||
uint16_t v;
|
||||
};
|
||||
|
||||
static uint32_t *buffer = NULL;
|
||||
static uint32_t width, height;
|
||||
static uint8_t bit_depth;
|
||||
|
||||
static uint16_t angle;
|
||||
|
||||
static void set_pixel(struct rgb color, uint16_t x, uint16_t y) {
|
||||
uint32_t offset = y * width + x;
|
||||
buffer[offset] = (color.b << 0) | (color.g << 8) | (color.r << 16);
|
||||
}
|
||||
|
||||
static float fmod(float f, float m) {
|
||||
return f - (int)(f / m) * m;
|
||||
}
|
||||
|
||||
static float fabs(float f) {
|
||||
return f > 0 ? f : -f;
|
||||
}
|
||||
|
||||
static struct rgb htor(struct hsv hsv) {
|
||||
struct rgb rgb;
|
||||
float s = hsv.s / 100.0;
|
||||
float v = hsv.v / 100.0;
|
||||
float c = s * v;
|
||||
float x = c * (1-fabs(fmod(hsv.h/60.0, 2) - 1));
|
||||
float m = v - c;
|
||||
float r,g,b;
|
||||
|
||||
if (hsv.h < 60) {
|
||||
r = c; g = x; b = 0;
|
||||
} else if (hsv.h >= 60 && hsv.h < 120) {
|
||||
r = x; g = c; b = 0;
|
||||
} else if (hsv.h >= 120 && hsv.h < 180) {
|
||||
r = 0; g = c; b = x;
|
||||
} else if (hsv.h >= 180 && hsv.h < 240) {
|
||||
r = 0; g = x; b = c;
|
||||
} else if (hsv.h >= 240 && hsv.h < 300) {
|
||||
r = x; g = 0; b = c;
|
||||
} else {
|
||||
r = c; g = 0; b = x;
|
||||
}
|
||||
|
||||
rgb.r = (r + m) * 255;
|
||||
rgb.g = (g + m) * 255;
|
||||
rgb.b = (b + m) * 255;
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
static struct rgb get_color(uint16_t a, uint16_t x, uint16_t y) {
|
||||
struct hsv hsv = {
|
||||
.h = a,
|
||||
.s = x * 100.0 / width,
|
||||
.v = y * 100.0 / height,
|
||||
};
|
||||
return htor(hsv);
|
||||
}
|
||||
|
||||
void screen_init(void) {
|
||||
angle = 0;
|
||||
width = SCREEN_WIDTH;
|
||||
height = SCREEN_HEIGHT;
|
||||
bit_depth = SCREEN_BIT_DEPTH;
|
||||
buffer = bochs_init(width, height, bit_depth);
|
||||
}
|
||||
|
||||
void screen_redraw(void) {
|
||||
for (uint16_t y = 0; y < height; y++) {
|
||||
for (uint16_t x = 0; x < width; x++) {
|
||||
struct rgb color = get_color(angle, x, height - y);
|
||||
set_pixel(color, x, y);
|
||||
}
|
||||
}
|
||||
angle++;
|
||||
angle %= 360;
|
||||
}
|
Loading…
Reference in a new issue