lib KernelShim
fun hide_cursor()
fun show_cursor()
fun set_cursor_pos(
row : UInt32,
col : UInt32
)
end
struct VGACursor
@col : Int32 = 0
property col
@row : Int32 = 0
property row
end
module VGA
VGA_ADDRESS = 0xB8000_u64
VGA_BUFFER = Pointer(UInt8).new(VGA_ADDRESS)
VGA_WIDTH = 80
VGA_HEIGHT = 25
VGA_SIZE = VGA_WIDTH * VGA_HEIGHT
VGA_CURSOR = VGACursor.new
DEFAULT_COLOR = 0x07_u8
module Colors
DEFAULT = 0x07_u8
BLACK_ON_CYAN = 0xB0_u8
BLACK_ON_LIME = 0xA0_u8
end
def self.init : Nil
clear
end
def self.clear : Nil
i = 0
while i < VGA_SIZE
(VGA_BUFFER + (i * 2)).value = " ".to_unsafe.value
(VGA_BUFFER + (i * 2) + 1).value = Colors::DEFAULT
i += 1
end
col = 0
row = 0
end
def self.hide_cursor
KernelShim.hide_cursor
end
def self.show_cursor
KernelShim.show_cursor
end
def self.set_cursor(
col : Int32,
next_row : Int32
) : Nil
KernelShim
.set_cursor_pos(next_row.to_u32, col.to_u32)
@@row = next_row
end
@@puts_count = 0
property puts_count
@@col = 0
class_property col
@@row = 0
class_property row
def self.putchar(
ch : UInt8,
i : Int32? = 0,
line : Int32? = 0,
color : UInt8? = Colors::DEFAULT
) : Nil
@@col ||= i || 0
@@row ||= line || 0
if ch == 0x0A_u8
@@col = 0
@@row += 1
if @@row >= VGA_HEIGHT
@@row = VGA_HEIGHT - 1
end
end
offset = (@@row * VGA_WIDTH + @@col) * 2
(VGA_BUFFER + offset).value = ch
(VGA_BUFFER + offset + 1).value = color
@@col += 1
if @@col >= VGA_WIDTH
@@col = 0
@@row += 1
if @@row >= VGA_HEIGHT
@@row = VGA_HEIGHT - 1
end
end
end
def self.puts(
str : String,
color : UInt8? = Colors::DEFAULT,
line : Int32? = nil,
) : Nil
i = 0
@@row ||= (line || 0)
while i < str.size
ch = (str.to_unsafe + i).value
if ch == 0x0A_u8
@@row += 1
@@col = 0
i += 1
next
end
putchar(ch, i, @@row, color)
i += 1
end
VGA.set_cursor(0, @@row)
end
end