~kernel/kernel.cr
.cr
Crystal
(text/x-crystal)
lib LibBootstrap
  @[Packed]
  struct StartInfo
    multiboot_ptr : UInt32
    end_of_kernel : UInt32
  end
end

fun kearly(info_ptr: LibBootstrap::StartInfo*)

  # Get the startup info
  info = info_ptr.value

  # Initialize stuff
  # GDT.init
  # Heap.init info.end_of_kernel
  # PIC.remap
  # PIC.enable
  # IDT.init
end

def outb(port : UInt16, value : UInt8)
  asm (%(outb %al, %dx) : : "a"(value), "Nd"(port))
end

def set_cursor_position(row : Int32, col : Int32)
  position = (80 * row + col).to_u16

  # # Write the high byte
  # outb(0x3D4_u16, 0x0E_u8);
  # outb(0x3D5_u16, ((position >> 8) & 0xFF).to_u8);

  # # Write the low byte
  # outb(0x3D4_u16, 0x0F_u8);
  # outb(0x3D5_u16, (position & 0xFF).to_u8);
end

def clear_screen
  video_memory = Pointer(UInt8).new(0xB8000_u64)
  screen_size = 80 * 25
  i = 0
  while i < screen_size
    (video_memory + (i * 2)).value = " ".to_unsafe.value
    (video_memory + (i * 2) + 1).value = 0x07_u8
    i += 1
  end
end

fun kmain
  # IDT.enable_interrupts
  # kprint "Hello from Fluorite."

  message = "[CrystalOS Kernel] Hello from Crystal"
  
  clear_screen
  set_cursor_position(0, 0)

  _str : Pointer(UInt8) = message.to_unsafe
  video_memory = Pointer(UInt8).new(0xB8000_u64)
  i = 0
  ch = _str.value
  while ch > 0
    ch = (_str + i).value
    break if ch == 0
    (video_memory + (i * 2)).value = ch
    (video_memory + (i * 2) + 1).value = 0xB0_u8
    i += 1
  end

  while true
  end
end