From 232e333a62248057e2c672dae347f2e081f9dd11 Mon Sep 17 00:00:00 2001 From: Xnoe Date: Sun, 20 Feb 2022 11:30:39 +0000 Subject: [PATCH] Added VGA Mode Terminal. Updated context_switch and isr.S.base to perform the actual context switch during catchall_return. Program the PIT properly. Implemented timed events. Updated process.cpp. Added a font. Fixed bug in CircularRWBuffer. --- Makefile | 2 +- src/boot_stage2/main.c | 8 +- src/kernel/font.h | 135 ++++++++++++++++++++++ src/kernel/idt.cpp | 47 +++++--- src/kernel/idt.h | 3 + src/kernel/isr.S.base | 21 +++- src/kernel/keyboard.cpp | 3 +- src/kernel/kmain.cpp | 2 +- src/kernel/process.cpp | 5 - src/kernel/stdio/circularrwbuffer.cpp | 2 +- src/kernel/terminal.cpp | 158 ++++++++++++++++++++++++-- src/kernel/terminal.h | 33 +++++- src/world/world.c | 77 +++++++------ 13 files changed, 422 insertions(+), 74 deletions(-) create mode 100644 src/kernel/font.h diff --git a/Makefile b/Makefile index 86b6492..661d128 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ run: disk.img debug: disk.img qemu-system-i386 -s -S -no-reboot -no-shutdown disk.img & gdb --command=gdbscript -disk.img: clean prepare build/boot/boot.bin build/boot_stage2/boot.bin $(DISK_IMG_FILES) build/world/world.bin +disk.img: prepare build/boot/boot.bin build/boot_stage2/boot.bin $(DISK_IMG_FILES) build/world/world.bin dd if=/dev/zero of=disk.img count=43 bs=100k dd if=build/boot/boot.bin of=disk.img conv=notrunc dd obs=512 seek=1 if=build/boot_stage2/boot.bin of=disk.img conv=notrunc diff --git a/src/boot_stage2/main.c b/src/boot_stage2/main.c index e2a77ae..d2d4231 100644 --- a/src/boot_stage2/main.c +++ b/src/boot_stage2/main.c @@ -148,17 +148,21 @@ void main() { uint8_t* kernel_location = 0x542000; // Just load it at 0x524000 for now mark_unavailble(kernel_location, 0x10000, bitmap); // Just treat the kernel as not growing beyond 32k for now. - map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 0x10); // Map 8 pages from 0x522000 to 0xc0000000; + map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 0x10); // Map 16 pages from 0x522000 to 0xc0000000; map_4k_phys_to_virt((uint32_t)kernel_page_directory, 0xc0100000, kernel_page_directory, kernel_page_tables); // Map the page directory to 0xc0100000 map_many_4k_phys_to_virt(0x121000, 0xc0101000, kernel_page_directory, kernel_page_tables, 1024); // Map 1024 pages from 0x121000 to 0xc0101000 map_4k_phys_to_virt(0xb8000, 0xc0501000, kernel_page_directory, kernel_page_tables); // Map 0xb8000 (video) to 0xc0501000 map_4k_phys_to_virt(0x521000, 0xc0502000, kernel_page_directory, kernel_page_tables); // Map the PTE** data, we'll need to convert the pointers to point at kernel space at some point. + map_many_4k_phys_to_virt(0xa0000, 0xc07a0000, kernel_page_directory, kernel_page_tables, 0x20); // Map 32 pages from 0xa0000 to 0xa0000 + mark_unavailble(0xa0000, 0x20000, bitmap); + + uint8_t* vm_bitmap = 0x522000; mark_unavailble(vm_bitmap, 0x20000, bitmap); memset(vm_bitmap, 0x20000, 0xff); - + mark_unavailble(0xc07a0000, 0x20000, vm_bitmap); mark_unavailble(0xc0000000, 0x10000, vm_bitmap); mark_unavailble(0xc0100000, 0x1000, vm_bitmap); mark_unavailble(0xc0101000, 0x400000, vm_bitmap); diff --git a/src/kernel/font.h b/src/kernel/font.h new file mode 100644 index 0000000..fe1ff14 --- /dev/null +++ b/src/kernel/font.h @@ -0,0 +1,135 @@ +#ifndef FONT_H +#define FONT_H + +static const uint8_t font[128][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; + +#endif \ No newline at end of file diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 2a115a2..cf38ebb 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -91,7 +91,7 @@ void context_switch(frame_struct* frame) { } if (Global::currentProcValid) - asm ("mov %%esp, %0" : "=a" (Global::currentProc->kernelStackPtr):); + Global::currentProc->kernelStackPtr = frame->new_esp; // This cursed bit of code first determines if the processes list is longer than 1 and if it is // - Determines if it has 2 or more elements @@ -123,25 +123,35 @@ void context_switch(frame_struct* frame) { Global::currentProc = processes->start->elem; // Select the next processes page directory - asm volatile ("mov %0, %%cr3" : : "r" (Global::currentProc->PD->phys_addr)); + frame->new_cr3 = Global::currentProc->PD->phys_addr; // Restore kernelStackPtr of the new process. - asm volatile ("mov %0, %%esp" : : "m" (Global::currentProc->kernelStackPtr)); - - // At this point interrupts are disabled till iret so we can safely set - // Global::tss->esp0 to the new Process's kernelStackPtrDefault + frame->new_esp = Global::currentProc->kernelStackPtr; Global::tss->esp0 = Global::currentProc->kernelStackPtrDefault; // Set the current proc to valid Global::currentProcValid = true; +} - if (Global::currentProc->firstRun) { - Global::currentProc->firstRun = false; - asm("add $4, %esp"); - asm("ret"); - } else { - asm("add $28, %esp"); - asm("ret"); +namespace Timer { + using TimedEvent = xnoe::tuple; + xnoe::linkedlist timed_events; + void tick(frame_struct* frame) { + xnoe::linkedlistelem* current = timed_events.start; + while (current) { + TimedEvent t = current->elem; + uint32_t count = xnoe::get<0>(t); + if (--count == 0) { + xnoe::get<2>(t)(frame, xnoe::get<3>(t)); + count = xnoe::get<1>(t); + } + current->elem = TimedEvent(count, xnoe::get<1>(t), xnoe::get<2>(t), xnoe::get<3>(t)); + current = current->next; + } + } + + void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary) { + timed_events.append(TimedEvent(milliseconds, milliseconds, function, auxiliary)); } } @@ -330,11 +340,12 @@ void init_idt() { for (int i=0; i<256; i++) gates[i] = &ignore_interrupt; - gates[32] = &context_switch; + gates[32] = &Timer::tick; gates[0] = &handle_fault; gates[5] = &handle_fault; gates[6] = &handle_fault; gates[7] = &handle_fault; + gates[8] = &handle_fault; gates[9] = &handle_fault; gates[10] = &handle_fault; gates[11] = &handle_fault; @@ -363,6 +374,14 @@ void init_idt() { outb(0xA1, 0x01); outb(0x21, 0x00); outb(0xA1, 0x00); + + // Program the PIT + uint16_t counter = 1193; + uint8_t* _counter = (uint8_t*)&counter; + outb(0x40, _counter[0]); + outb(0x40, _counter[1]); + + Timer::register_event(30, &context_switch, 0); } void enable_idt() { diff --git a/src/kernel/idt.h b/src/kernel/idt.h index cffb2b1..2f7a852 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -9,6 +9,9 @@ #include "stdio/circularrwbuffer.h" struct __attribute__((packed)) frame_struct { + uint32_t new_cr3; + uint32_t new_esp; + uint32_t edi; uint32_t esi; uint32_t ebp; diff --git a/src/kernel/isr.S.base b/src/kernel/isr.S.base index f22c79a..3a5c3c5 100644 --- a/src/kernel/isr.S.base +++ b/src/kernel/isr.S.base @@ -5,8 +5,17 @@ global isrs global catchall_return catchall: ; At this point the gate number has been pushed to the stack - pushad ; Pushed 32 bytes - mov eax, [esp+32] + pushad + + push esp + sub esp, 4 + push eax + mov eax, cr3 + mov [esp+4], eax + pop eax + + ; Pushed 40 bytes + mov eax, [esp+40] mov ebx, gates mov eax, [ebx+4*eax] push esp @@ -20,7 +29,15 @@ catchall_return: call outb add esp, 8 + push eax + mov eax, [esp+4] + mov cr3, eax + pop eax + add esp, 4 + pop esp + popad + mov esp, ebp pop ebp iret diff --git a/src/kernel/keyboard.cpp b/src/kernel/keyboard.cpp index 36c9225..e51433e 100644 --- a/src/kernel/keyboard.cpp +++ b/src/kernel/keyboard.cpp @@ -24,7 +24,7 @@ char key_to_char_shift[128] = { 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', - 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, + 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 @@ -64,7 +64,6 @@ void keyboard_interrupt(frame_struct* frame) { } void init_keyboard() { - //set_entry(0x21, 0x08, &keyboard_interrupt, 0x8E); gates[0x21] = &keyboard_interrupt; while (inb(0x64) & 1) { diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 5375daf..2121f93 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -31,7 +31,7 @@ int main() { kernel.init_kernel(); init_atapio(); - TextModeTerminal* term = new TextModeTerminal(0xc0501000); + VGAModeTerminal* term = new VGAModeTerminal(0xc07a0000); kernel.terminal = term; diff --git a/src/kernel/process.cpp b/src/kernel/process.cpp index 30cc680..3eee21e 100644 --- a/src/kernel/process.cpp +++ b/src/kernel/process.cpp @@ -72,7 +72,6 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uin uint32_t rEBP = stack32; - //stack32--; *(--stack32) = 0; // EAX *(--stack32) = 0; // ECX *(--stack32) = 0; // EDX @@ -81,13 +80,9 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uin *(--stack32) = rEBP; // EBP *(--stack32) = 0; // ESI *(--stack32) = 0; // EDI - stack32--; - *(--stack32) = &catchall_return; // cachall_return - stack32--; this->kernelStackPtr = stack32; - //load_file(filename, program_data); filereader->read(filesize, program_data); asm ("mov %0, %%cr3" : : "r" (pCR3)); diff --git a/src/kernel/stdio/circularrwbuffer.cpp b/src/kernel/stdio/circularrwbuffer.cpp index cb0f497..8167c70 100644 --- a/src/kernel/stdio/circularrwbuffer.cpp +++ b/src/kernel/stdio/circularrwbuffer.cpp @@ -28,7 +28,7 @@ uint32_t CircularRWBuffer::read(uint32_t count, uint8_t* buffer) { int i=0; while (i < count) { if (this->readPtr == this->writePtr) - return 0; + return i; buffer[i] = this->buffer[this->readPtr]; this->readPtr++; diff --git a/src/kernel/terminal.cpp b/src/kernel/terminal.cpp index eff258b..a76ce47 100644 --- a/src/kernel/terminal.cpp +++ b/src/kernel/terminal.cpp @@ -183,13 +183,6 @@ void Terminal::printf(const char* string, ...) { } uint32_t Terminal::write(uint32_t count, uint8_t* string) { - /*char* buf = new char[count+1]; - for (int i=0;itext_mode_pointer = text_mode_pointer; +} + +void VGAModeTerminal::update() { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + putchar_internal(y * width + x, (uint8_t)(current_page_pointer[y * width + x]), 0); + } + } +} + +void VGAModeTerminal::update_cur() { + // Todo: Implement cursor for VGAModeTerminal +} + +void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) { + uint32_t col = ptr % width; + uint32_t row = ptr / width; + + uint32_t sx = col * 8; + uint32_t sy = row * 8; + + if (c>127) + return; + uint8_t* char_data = font[c]; + + for (int y=0; y<8; y++) { + //for (int x=0; x<8; x++) { + put_pixels_byte(sx, sy+y, 15, char_data[y]); + //} + } +} + +void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte) { + uint32_t pixel = y * 720 + x; + uint32_t pixelindex = pixel / 8; + + uint8_t trbyte = 0; + for (int i=0; i<8; i++) { + trbyte <<= 1; + trbyte += (pixel_byte>>i)&1; + } + + for (int i=0; i<4; i++) { + if (color & (1<planes[i][pixelindex] = trbyte; + else + this->planes[i][pixelindex] = 0; + } +} + +void VGAModeTerminal::put_pixel(uint32_t x, uint32_t y, uint8_t color) { + // For any pixel we need to write 1 bit to planes 0, 1, 2, and 3 + + uint32_t pixel = y * 720 + x; + uint32_t pixelindex = pixel / 8; + uint32_t pixelbitindex = pixel % 8; + + for (int i=0; i<4; i++) { + if (color & (1<planes[i][pixelindex] |= (1<<(7-pixelbitindex)); + else + this->planes[i][pixelindex] &= ~(1<<(7-pixelbitindex)); + } +} + +static void VGAModeTerminal::bufferToVRAM(frame_struct* frame, VGAModeTerminal* terminal) { + uint32_t count4 = (720 * 480) / 8 / 4; + for (int i=0; i<4; i++) { + outb(0x3c4, 2); + outb(0x3c5, 1<vga_pointer)[c] = ((uint32_t*)terminal->planes[i])[c]; + } + } +} + +VGAModeTerminal::VGAModeTerminal(uint8_t* vga_pointer): Terminal(90, 60, 1) { + this->vga_pointer = vga_pointer; + + for (int i=0; i<4; i++) { + this->planes[i] = new uint8_t[720 * 480 / 8]; + } + + unsigned char g_720x480x16[] = + { + /* MISC */ + 0xE7, + /* SEQ */ + 0x03, 0x01, 0x08, 0x00, 0x06, + /* CRTC */ + 0x6B, 0x59, 0x5A, 0x82, 0x60, 0x8D, 0x0B, 0x3E, + 0x00, 0x40, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x2D, 0x08, 0xE8, 0x05, 0xE3, + 0xFF, + /* GC */ + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0F, + 0xFF, + /* AC */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x01, 0x00, 0x0F, 0x00, 0x00, + }; + + uint8_t* creg = g_720x480x16; + + outb(0x3c2, *(creg++)); + for (int i=0; i<5; i++) { + outb(0x3c4, i); + outb(0x3c5, *(creg++)); + } + outb(0x3d4, 0x3); + outb(0x3d5, inb(0x3d5) | 0x80); + outb(0x3d4, 0x11); + outb(0x3d5, inb(0x3d5) & ~0x80); + + creg[0x03] = creg[0x03] | 0x80; + creg[0x11] = creg[0x11] & ~0x80; + + for (int i=0; i<25; i++) { + outb(0x3d4, i); + outb(0x3d5, *(creg++)); + } + + for (int i=0; i<9; i++) { + outb(0x3ce, i); + outb(0x3cf, *(creg++)); + } + + for (int i=0; i<21; i++) { + inb(0x3da); + outb(0x3c0, i); + outb(0x3c1, *(creg++)); + } + + inb(0x3da); + outb(0x3c0, 0x20); + + uint32_t width4 = 480 / 8 / 4; + uint32_t height4 = 720 / 8 / 4; + uint32_t total4 = width4 * height4; + + for (int plane=0; plane<4; plane++) { + outb(0x3c4, 2); + outb(0x3c5, 1<vga_pointer)[i] = 0; + } + } + + Timer::register_event(16, &VGAModeTerminal::bufferToVRAM, this); } \ No newline at end of file diff --git a/src/kernel/terminal.h b/src/kernel/terminal.h index 5ee063e..731367f 100644 --- a/src/kernel/terminal.h +++ b/src/kernel/terminal.h @@ -7,9 +7,16 @@ #include "types.h" #include "strings.h" #include "io.h" +#include "font.h" #include "stdio/readwriter.h" +struct frame_struct; + +namespace Timer { + void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary); +} + class Terminal: public ReadWriter { private: virtual void update(); @@ -53,13 +60,31 @@ public: class TextModeTerminal : public Terminal { private: - void update() override; - void update_cur() override; - void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07) override; + void update() override; + void update_cur() override; + void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07) override; - uint16_t* text_mode_pointer; + uint16_t* text_mode_pointer; public: TextModeTerminal(uint16_t* text_mode_pointer); }; + +class VGAModeTerminal : public Terminal { +private: + void update() override; + void update_cur() override; + void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07) override; + + void put_pixel(uint32_t x, uint32_t y, uint8_t color); + void put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte); + + static void bufferToVRAM(frame_struct* frame, VGAModeTerminal* terminal); + +public: + uint8_t* vga_pointer; + uint8_t* planes[4]; + + VGAModeTerminal(uint8_t* vga_pointer); +}; #endif \ No newline at end of file diff --git a/src/world/world.c b/src/world/world.c index 4f7a618..ab46aba 100644 --- a/src/world/world.c +++ b/src/world/world.c @@ -11,12 +11,12 @@ typedef struct { } procbuffer; void scrollBuffer(char* buf) { - for (int y=0; y<21; y++) - for (int x=0; x<38; x++) - if (y != 20) - buf[y*38+x] = buf[(y+1)*38+x]; + for (int y=0; y<56; y++) + for (int x=0; x<43; x++) + if (y != 55) + buf[y*43+x] = buf[(y+1)*43+x]; else - buf[y*38+x] = ' '; + buf[y*43+x] = ' '; } void writeToBuf(char c, procbuffer* buf) { @@ -30,27 +30,33 @@ void writeToBuf(char c, procbuffer* buf) { if (buf->x > 0) buf->x--; else if (buf->y > 0) { - buf->x = 37; + buf->x = 42; buf->y--; } - buf->buffer[buf->y*38+buf->x] = ' '; + buf->buffer[buf->y*43+buf->x] = ' '; break; default: - buf->buffer[buf->y*38+buf->x++] = c; + buf->buffer[buf->y*43+buf->x++] = c; } - if (buf->x == 38) { + if (buf->x == 43) { buf->x = 0; buf->y++; } - if (buf->y == 21) { + if (buf->y == 56) { buf->y--; scrollBuffer(buf->buffer); } } +void writeCountToBuf(int count, char* c, procbuffer* buf) { + while (count--) { + writeToBuf(*(c++), buf); + } +} + void clearBuf(procbuffer* buf) { - for (int i=0; i<21*38;i++) { + for (int i=0; i<56*43;i++) { buf->buffer[i] = ' '; } buf->x = 0; @@ -79,9 +85,9 @@ void displayBuf(procbuffer* b, int dx, int dy) { pset[5]++; } } - for (int i=0; i<21; i++) { + for (int i=0; i<56; i++) { print(pset); - write(38, 0, b->buffer+(38*i)); + write(43, 0, b->buffer+(43*i)); pset[3]++; if (pset[3] == 0x3a) { pset[3] = 0x30; @@ -164,16 +170,16 @@ int main() { write(1, 0, &space); print("\x1b[1;1H"); - char* mid = "+ ++ +"; - char* bottom = "+ +"; - for (int i=0; i<80;i++) + char* mid = "+ ++ +"; + char* bottom = "+ +"; + for (int i=0; i<90;i++) write(1, 0, &plus); - for (int i=0; i<21;i++) - write(80, 0, mid); - for (int i=0; i<80;i++) + for (int i=0; i<56;i++) + write(90, 0, mid); + for (int i=0; i<90;i++) write(1, 0, &plus); - write(80, 0, bottom); - for (int i=0; i<80;i++) + write(90, 0, bottom); + for (int i=0; i<90;i++) write(1, 0, &plus); uint32_t program = fopen("hello.bin"); @@ -188,7 +194,7 @@ int main() { fclose(program); procbuffer b1 = { - .buffer = localalloc(21 * 38), + .buffer = localalloc(56 * 43), .x = 0, .y = 0, .process = p1, @@ -197,7 +203,7 @@ int main() { }; procbuffer b2 = { - .buffer = localalloc(21 * 38), + .buffer = localalloc(56 * 43), .x = 0, .y = 0, .process = p2, @@ -207,22 +213,23 @@ int main() { procbuffer* selectedBuf = &b1; - writeStrToBuf("XoSH (Xnoe SHell) v0.0.1\nPress : to use commands.\n :help for help.\n", &b1); + writeStrToBuf("XoSH (XOS SHell) v0.0.1\nPress : to use commands.\n :help for help.\n", &b1); while (1) { - char c; + char c[128]; + int succ = 0; if (b1.process) - if (read(1, b1.stdout, &c)) - writeToBuf(c, &b1); + if (succ = read(128, b1.stdout, c)) + writeCountToBuf(succ, c, &b1); if (b2.process) - if (read(1, b2.stdout, &c)) - writeToBuf(c, &b2); - if (read(1, 1, &c)) { - if (c == ':') { + if (succ = read(128, b2.stdout, c)) + writeCountToBuf(succ, c, &b2); + if (read(1, 1, c)) { + if (c[0] == ':') { char buf[32] = {0}; - print("\x1b[24;2H"); + print("\x1b[59;2H"); print(": "); - print("\x1b[24;3H"); + print("\x1b[59;3H"); readline(32, buf); if (strcmpcnt(6, buf, "switch")) { if (selectedBuf == &b1) { @@ -266,11 +273,11 @@ int main() { } } else { if (selectedBuf->process) - write(1, selectedBuf->stdin, &c); + write(1, selectedBuf->stdin, c); } } displayBuf(&b1, 2, 2); - displayBuf(&b2, 42, 2); + displayBuf(&b2, 47, 2); } } \ No newline at end of file