lib KernelShim
fun hide_cursor()
fun show_cursor()
fun set_cursor_pos(
row : UInt32,
col : UInt32
)
end
struct VGACursor
col : Int32 = 0
row : Int32 = 0
def initialize
@col = 0
@row = 0
end
def col : Int32
@col
end
def col=(c : Int32)
@col = c
end
def col_incr(c : Int32)
@col += c
end
def row : Int32
@row
end
def row=(r : Int32)
@row = r
end
def row_incr(r : Int32)
@row += r
end
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
VGA_CURSOR.col = 0
VGA_CURSOR.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,
row : Int32
) : Nil
KernelShim
.set_cursor_pos(row.to_u32, col.to_u32)
end
def self.putchar(
ch : UInt8,
i : Int32? = 0,
line : Int32? = 0,
color : UInt8? = Colors::DEFAULT
) : Nil
VGA_CURSOR.col = i
VGA_CURSOR.row = line
if ch == 0x0A_u8
VGA_CURSOR.row += 1
if VGA_CURSOR.row >= VGA_HEIGHT
VGA_CURSOR.row = VGA_HEIGHT - 1
end
ch = " ".to_unsafe.value
end
offset = (VGA_CURSOR.row * VGA_WIDTH + VGA_CURSOR.col) * 2
(VGA_BUFFER + offset).value = ch
(VGA_BUFFER + offset + 1).value = color
VGA_CURSOR.col += 1
if VGA_CURSOR.col >= VGA_WIDTH
VGA_CURSOR.col = 0
VGA_CURSOR.row += 1
if VGA_CURSOR.row >= VGA_HEIGHT
VGA_CURSOR.row = VGA_HEIGHT - 1
end
end
end
def self.puts(
str : String,
color : UInt8? = Colors::DEFAULT,
line : Int32? = 0,
) : Nil
i = 0
while i < str.size - 1
ch = (str.to_unsafe + i).value
putchar(ch, i, line, color)
i += 1
end
end
end