GitFOSS
refactor(kernel): move old c/cpp code into archive folder
+ 74
- 47
kernel/entry.o -> kernel/archive/c/entry.o
kernel/idt.c -> kernel/archive/c/idt.c
kernel/idt.h -> kernel/archive/c/idt.h
kernel/idt.o -> kernel/archive/c/idt.o
kernel/idt_asm.o -> kernel/archive/c/idt_asm.o
kernel/main.c -> kernel/archive/c/main.c
@@ -101,6 +101,6 @@ void kmain(void) {
 
     /* Idle loop */
     while (1) {
-        asm volatile ("hlt");
+      asm volatile ("hlt");
     }
 }

kernel/main.o -> kernel/archive/c/main.o
kernel/module.h -> kernel/archive/c/module.h
kernel/multiboot.o -> kernel/archive/c/multiboot.o
kernel/pmm.c -> kernel/archive/c/pmm.c
kernel/pmm.h -> kernel/archive/c/pmm.h
kernel/pmm.o -> kernel/archive/c/pmm.o
kernel/ps2.c -> kernel/archive/c/ps2.c
kernel/ps2.o -> kernel/archive/c/ps2.o
kernel/timer.c -> kernel/archive/c/timer.c
kernel/timer.h -> kernel/archive/c/timer.h
kernel/timer.o -> kernel/archive/c/timer.o
kernel/vga.c -> kernel/archive/c/vga.c
kernel/vga.o -> kernel/archive/c/vga.o
kernel/kernel.cpp -> kernel/archive/cpp/kernel.cpp
kernel/system/common.hpp -> kernel/archive/cpp/system/common.hpp
kernel/unityBuild.cpp -> kernel/archive/cpp/unityBuild.cpp
@@ -4,7 +4,8 @@
 
 /* Minimal ISR handlers for linking */
 isr_handler_common:
-    ret
+  ret
 
 irq_handler_common:
-    ret
+  jmp irq_common_entry
+  ret

kernel/ps2.cr -> kernel/irq.cr
@@ -2,35 +2,24 @@ lib KernelShim
   fun outb(port : UInt16, value : UInt8) : Void
 end
 
-module PS2
+module IRQ
   IRQ_COUNT = 16
   HANDLERS = StaticArray(Proc(UInt8, Void)?, IRQ_COUNT).new()
   
   def self.init
-    self.register_keyboard
-    puts "PS/2 initialized!\n"
-  end
-  
-  private def self.register_keyboard
-    # todo: handle keyboard events
-    register(1, # IRQ 1 = keyboard
-    ->(scan_code : UInt8) {
-      if scan_code == 0x1C
-        puts "Enter\n"
-      end
-      # do smth
-      puts "keyboard event\n"
-    })
+    puts "IRQ initialized!\n"
   end
 
   def self.register(irq : Int32, handler : Proc(UInt8, Void)) : Proc(UInt8, Void)?
     return nil if irq < 0 || irq >= IRQ_COUNT
     prev = HANDLERS[irq]
     HANDLERS[irq] = handler
+    puts "irq handler registered\n"
     prev
   end
 
   def self.dispatcher(irq : UInt32)
+    puts "irq dispatcher called ...\n"
     i = irq.to_u8
     if handler = HANDLERS[i]
       handler.call(i)

...
@@ -40,7 +29,7 @@ end
 
 fun irq_dispatcher_c(irq : UInt32)
   puts "irq_dispatcher_c\n"
-  PS2.dispatcher(irq)
+  IRQ.dispatcher(irq)
 end
 
 fun pic_send_eoi(irq : UInt32)

@@ -1,6 +1,7 @@
 require "./vga.cr"
 require "./tiny_alloc_i386.cr"
-require "./ps2.cr"
+require "./irq.cr"
+require "./timer.cr"
 # require "./pmm.cr"
 
 lib LibBootstrap

...
@@ -24,9 +25,15 @@ fun kmain
   )
   # PMM.init # Physical Memory Init
   TinyAllocI386.init
-  PS2.init
-  puts("weeeeeeee\n")
+  IRQ.init
+  Timer.init
+  # Net.init
+  # PS2.init
+  # Audio.init
+  # Display.init
+  # WM.init
 
+  puts("weeeeeeee\n")
   VGA.puts("Can print on multiple lines\n", color: VGA::Colors::BLACK_ON_LIME)
   VGA.puts("\nWe still don't have a heap, but now the puts stores the last row and col so it can call the putchar method with the \x1b[32mright\x1b[0m col / row instead of overlaying subsequent calls on-top one of another (this is super long line to test word wrap).\n")
   VGA.puts "\nFeatures:\n"

...
@@ -39,6 +46,22 @@ fun kmain
   VGA.puts("\tCan use custom colors", VGA::Colors::RED_ON_BLACK)
   VGA.puts("\tCan use another custom color\n", VGA::Colors::GREEN_ON_BLACK)
   VGA.puts("\tCan use lot of custom color\n", VGA::Colors::CYAN_ON_BLACK)
+  
+  puts "\nPress [enter] to boot into graphical mode\n\n"
+  
+  IRQ.register(0, ->(data : UInt8) {
+    puts "timer handler called ...\n"
+    Timer.irq_handler(data)
+    return
+  })
+  
+  IRQ.register(1, ->(scan_code : UInt8) {
+    puts "keyboard handler called ...\n"
+    if scan_code == 0x1C
+      puts "Enter\n"
+    end
+    return
+  })
 
   # VGA.set_cursor(0, 5)
   # VGA.hide_cursor

@@ -1,18 +1,32 @@
 require "./vga.cr"
 
+lib KernelShim
+  # External assembly ISR for timer
+  fun timer_isr_common : Void
+  fun outb(port : UInt16, value: UInt8) : Void
+end
+
 # Timer module - System timer
 module Timer
   TIMER_FREQ = 1000_u32
-
-  # External assembly ISR for timer
-  fun timer_isr_common : Void
+  
+  @@tick_count : UInt64 = 0
+  class_property tick_count
 
   def self.init : Nil
+    # PIT channel 0, mode 3 (square wave), lobyte/hibyte access
+    KernelShim.outb(0x43, 0x36)
+    # Frequency: 1193182 Hz / divisor = desired frequency (e.g., 100 Hz)
+    divisor = 11931 # 1193182 / 100 ≈ 11931
+    KernelShim.outb(0x40, divisor & 0xFF)
+    KernelShim.outb(0x40, (divisor >> 8) & 0xFF)
+    
     # Set up PIT or HPET here (placeholder)
-    VGA.puts("Timer initialized\n")
+    VGA.puts("Timer initialized!\n")
   end
-
-  def self.enable : Nil
-    # Enable timer IRQ
+  
+  def self.irq_handler(data : UInt8)
+    @@tick_count += 1
+    # Could print a dot or update something; for now just increment.
   end
-end
+end

@@ -23,9 +23,7 @@ require "./prelude/crystal_core/range"
 require "./prelude/crystal_core/string"
 require "./prelude/crystal_core/reference"
 require "./prelude/crystal_core/static_array"
-
-# needs support for pmm first
-# require "./prelude/crystal_core/array"
+require "./prelude/crystal_core/array"
 
 # crystal api
 require "./prelude/puts"

@@ -1,30 +1,23 @@
 #!/bin/bash
 
-# Flags
-
-CC_FLAGS="-ffreestanding -nostdinc -nostdinc++ \
-					-Wall -Wextra \
-					-o ./bin/kernel.bin -target i386-pc-none-elf \
-					-I ./kernel/"
-LD_FLAGS="-nostdlib -Wl,--oformat=binary,-T./kernel/linker.ld"
-CPP_FILES="./kernel/unityBuild.cpp ./build/kernelEntryPoint.o"
-
 # Build
 
 mkdir {bin,build} 2> /dev/null
 
-echo -e "Cleaning..."
+echo -e "Cleaning artifacts..."
 rm *.bin *.img *.iso *.o *.vmdk 2> /dev/null
 
-echo -e "\nBuilding..."
+echo -e "Building bootloader (asm)..."
 nasm ./boot/bootloader.asm -I ./boot/ -o ./bin/bootloader.bin || exit 1
+
+echo -e "Building kernel (asm)..."
 nasm -felf32 ./kernel/entry.asm -I ./kernel/ -o ./build/kernelEntryPoint.o || exit 1
 
 use_crystal_kernel=${USE_CRYSTAL_KERNEL:-true}
-
 if [ "$use_crystal_kernel" = true ]
 then
 	# Build crystal kernel without stdlib, using the custom prelude, and targeting i386-unknown-linux-elf
+  echo -e "Building kernel (crystal)..."
 	crystal build \
 		--no-debug \
 		--cross-compile \

...
@@ -34,6 +27,7 @@ then
 		-o ./build/kernel ./kernel/kernel.cr || exit 1
 
 	# Link the kernel into an ELF executable, then convert it to a flat binary for the bootloader.
+	echo -e "Linking kernel.elf (ld)..."
 	ld \
 	  -m elf_i386 \
 	  -nostdlib \

...
@@ -41,18 +35,27 @@ then
 	  -o ./bin/kernel.elf ./build/kernelEntryPoint.o ./build/kernel.o || exit 1
 	
 	# Copy kernel.elf to kernel.bin properly.
+	echo -e "Building kernel.bin (objcopy)..."
 	objcopy \
 	  -O binary ./bin/kernel.elf ./bin/kernel.bin || exit 1
 else
+  # Flags
+  CC_FLAGS="-ffreestanding -nostdinc -nostdinc++ -Wall -Wextra -o ./bin/kernel.bin -target i386-pc-none-elf -I ./kernel/archive/cpp/"
+  LD_FLAGS="-nostdlib -Wl,--oformat=binary,-T./kernel/linker.ld"
+  CPP_FILES="./kernel/archive/cpp/unityBuild.cpp ./build/kernelEntryPoint.o"
+
   # Build c++ kernel without stdlib, using the custom prelude, and targeting i386-unknown-linux-elf
+  echo -e "Building kernel (cpp)..."
 	clang++ -v \
 	  $CC_FLAGS \
 	  $LD_FLAGS \
 	  $CPP_FILES || exit 1
 fi
 
+echo -e "Copy kernel.bin into iso/boot/"
 cp ./bin/kernel.bin ./iso/boot/kernel.bin || exit 1
 
+echo -e "Make bootable crystalos.img (genVDisk)..."
 ./tools/genVDisk \
   --output "crystalos" \
   --floppy \

...
@@ -61,10 +64,9 @@ cp ./bin/kernel.bin ./iso/boot/kernel.bin || exit 1
 
 # Run
 
-echo -e "\nRunning..."
+echo -e "Booting into crystalos.img (qemu)..."
 
 use_vnc=${USE_VNC:-false}
-
 if [ "$use_vnc" = true ]
 then
   qemu-system-i386 -drive if=floppy,index=0,format=raw,file=crystalos.img || exit 1