summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <me@liz.coffee>2026-10-07 09:17:15 -0700
committerElizabeth Alexander Hunt <me@liz.coffee>2026-10-07 21:51:59 -0700
commite5890fd8f723a948fffb28cc73990c6749f36260 (patch)
tree69e3ec61677a2cbed37057ef1043d0ec3577f829 /src
parent4d21315f667c03eaf44a580c3435f73853b53dbf (diff)
downloadmacaroni-e5890fd8f723a948fffb28cc73990c6749f36260.tar.gz
macaroni-e5890fd8f723a948fffb28cc73990c6749f36260.zip
VBE attempt 1
Diffstat (limited to 'src')
-rw-r--r--src/boot.asm25
-rw-r--r--src/kernel.c150
2 files changed, 145 insertions, 30 deletions
diff --git a/src/boot.asm b/src/boot.asm
index cbf57d6..c88f08c 100644
--- a/src/boot.asm
+++ b/src/boot.asm
@@ -1,20 +1,37 @@
;> The Multiboot header must be contained completely within the first 8192 bytes of the OS
;> image, and must be longword (32-bit) aligned.
MULTIBOOT_ALIGN_TO_PAGE: equ 1 << 0
-MULTIBOOT_MEMORY_DESCRIBE: equ 1 << 2
+MULTIBOOT_MEMORY_DESCRIBE: equ 1 << 1
+MULTIBOOT_VIDEO_MODE: equ 1 << 2
MULTIBOOT_MAGIC: equ 0x1BADB002
-MULTIBOOT_FLAGS: equ (MULTIBOOT_ALIGN_TO_PAGE | MULTIBOOT_MEMORY_DESCRIBE)
+MULTIBOOT_FLAGS: equ (MULTIBOOT_ALIGN_TO_PAGE | MULTIBOOT_MEMORY_DESCRIBE | MULTIBOOT_VIDEO_MODE)
MULTIBOOT_CHECKSUM: equ -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS)
-section .multiboot_header
+MULTIBOOT_VIDEO_TYPE: equ 0
+MULTIBOOT_GODS_WIDTH: equ 640
+MULTIBOOT_GODS_HEIGHT: equ 480
+MULTIBOOT_VIDEO_BPP: equ 16
+
+; We don't set flags[16] because we assemble to ELF32 so header_addr, etc is useless to us
+; (at least at the moment).
+UNUSED_BYTES_COUNT: equ 5*4
+section .multiboot_header:
+; I guess multiboot 2 requires a length field and we might migrate to that in the future.
+multiboot_header_start:
align 4
dd MULTIBOOT_MAGIC
dd MULTIBOOT_FLAGS
dd MULTIBOOT_CHECKSUM
+ times UNUSED_BYTES_COUNT db 0
+ dd MULTIBOOT_VIDEO_TYPE
+ dd MULTIBOOT_GODS_WIDTH
+ dd MULTIBOOT_GODS_HEIGHT
+ dd MULTIBOOT_VIDEO_BPP
+multiboot_header_end:
STACK_SIZE: equ (1 << 14)
section .bss
align 16
-stack_bottom:
+stack_bottom: ; ("haha bottom" somewhere in there??)
resb STACK_SIZE
stack_top:
diff --git a/src/kernel.c b/src/kernel.c
index 1459f73..917c07e 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -1,36 +1,134 @@
#include <stddef.h>
#include <stdint.h>
+#include <stdbool.h>
-#define WIDTH 80
-#define HEIGHT 25
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
-#define BLACK 0
-#define BLUE 1
-#define GREEN 2
-#define RED 4
-#define MAGENTA 13
-#define WHITE 15
+#ifndef asm
+#define asm __asm__ volatile
+#endif
-int strlen(char* s) {
- int n = 0;
- char* s_ptr = s;
- while (*(s_ptr++)) {
- n++;
- }
- return n;
+struct __attribute__((packed)) multiboot_info
+{
+ /* Multiboot info version number */
+ u32 flags;
+
+ /* Available memory from BIOS */
+ u32 mem_lower;
+ u32 mem_upper;
+
+ /* "root" partition */
+ u32 boot_device;
+
+ /* Kernel command line */
+ u32 cmdline;
+
+ /* Boot-Module list */
+ u32 mods_count;
+ u32 mods_addr;
+
+// union
+// {
+// multiboot_aout_symbol_table_t aout_sym;
+// multiboot_elf_section_header_table_t elf_sec;
+// } u;
+ u32 unused_1;
+ u32 unused_2;
+ u32 unused_3;
+ u32 unused_4;
+
+ /* Memory Mapping buffer */
+ u32 mmap_length;
+ u32 mmap_addr;
+
+ /* Drive Info buffer */
+ u32 drives_length;
+ u32 drives_addr;
+
+ /* ROM configuration table */
+ u32 config_table;
+
+ /* Boot Loader Name */
+ u32 boot_loader_name;
+
+ /* APM table */
+ u32 apm_table;
+
+ /* Video */
+ u32 vbe_control_info;
+ u32 vbe_mode_info;
+ u16 vbe_mode;
+ u16 vbe_interface_seg;
+ u16 vbe_interface_off;
+ u16 vbe_interface_len;
+
+ u64 framebuffer_addr;
+ u32 framebuffer_pitch;
+ u32 framebuffer_width;
+ u32 framebuffer_height;
+ u8 framebuffer_bpp;
+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
+ u8 framebuffer_type;
+ union
+ {
+ struct
+ {
+ u32 framebuffer_palette_addr;
+ u16 framebuffer_palette_num_colors;
+ };
+ struct
+ {
+ u8 framebuffer_red_field_position;
+ u8 framebuffer_red_mask_size;
+ u8 framebuffer_green_field_position;
+ u8 framebuffer_green_mask_size;
+ u8 framebuffer_blue_field_position;
+ u8 framebuffer_blue_mask_size;
+ };
+ };
+};
+typedef struct multiboot_info multiboot_info_t;
+
+u8 inportb(u16 port) {
+ u8 r;
+ asm("inb %1, %0" : "=a" (r) : "dN" (port));
+ return r;
+}
+
+void outportb(u16 port, u8 data) {
+ asm("outb %1, %0" : : "dN" (port), "a" (data));
+}
+
+// TODO: Why won't this work? void macaroni_panic(char* msg) {
+void macaroni_panic() {
+ // we'll do something with msg later.
+ while(true){ asm("nop\n\t"); }
+}
+
+void macaroni_assert(bool condition) {
+ if (condition) {
+ return;
+ }
+ macaroni_panic();
}
void cmain(void) {
- uint16_t* vgamem = (uint16_t*) 0xB8000;
- uint16_t vgacolors[6] = {WHITE | RED << 4, WHITE | GREEN << 4, WHITE | BLUE << 4, BLACK | RED << 4, BLACK | GREEN << 4, BLACK | BLUE << 4};
- char* s = "Hello world!";
- int i,j,k;
- for (k = 0; k >= 0; ++k) {
- k = (k % 5);
- j = 0;
- while (j < 100000000) { j++; } // Since we don't have an interrupt descriptor table we can't use the PIC; this emulates "sleeping"
- for (i = 0; i < WIDTH*HEIGHT; i++) {
- vgamem[i] = s[i % strlen(s)] | vgacolors[(i+k) % 6] << 8;
+ u32 magic_response = 0x1;
+ multiboot_info_t* p_multiboot_info;
+ asm("\t movl %%eax,%0" : "=r"(magic_response));
+ asm("\t movl %%ebx,%0" : "=r"(p_multiboot_info));
+
+ void *fb = (void *) (unsigned long) p_multiboot_info->framebuffer_addr;
+ u8* pixel = fb;
+ for (int i = 0; i < 10000; i++) {
+ *(pixel + i) = i * 2;
}
- }
+
+ macaroni_assert(magic_response == 0x2BADB002);
+ //asm("int $0x13");
} \ No newline at end of file