-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuart.zig
80 lines (62 loc) · 1.74 KB
/
uart.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
const std = @import("std");
const arch = @import("arch.zig");
const lazy = @import("lazy.zig");
//
const outb = arch.x86_64.outb;
const inb = arch.x86_64.inb;
const hcf = arch.hcf;
//
var uart_lazy_init = lazy.Lazy(void).new();
pub fn print(comptime fmt: []const u8, args: anytype) void {
_ = uart_lazy_init.waitOrInit(lazy.fnPtrAsInit(void, Uart.init));
const UartWriter = struct {
pub const Error = error{};
pub const Self = @This();
pub fn writeAll(_: *const Self, bytes: []const u8) !void {
Uart.writeAll(bytes);
}
pub fn writeBytesNTimes(self: *const Self, bytes: []const u8, n: usize) !void {
for (0..n) |_| {
try self.writeAll(bytes);
}
}
};
std.fmt.format(UartWriter{}, fmt, args) catch {};
}
const Uart = struct {
const PORT: u16 = 0x3f8;
const Self = @This();
fn init() void {
outb(PORT + 1, 0x00);
outb(PORT + 3, 0x80);
outb(PORT + 0, 0x03);
outb(PORT + 1, 0x00);
outb(PORT + 3, 0x03);
outb(PORT + 2, 0xc7);
outb(PORT + 4, 0x0b);
outb(PORT + 4, 0x1e);
outb(PORT + 0, 0xae);
if (inb(PORT + 0) != 0xAE) {
hcf();
}
outb(PORT + 4, 0x0f);
}
fn readByte() u8 {
while (inb(PORT + 5) & 1 == 0) {}
return inb(PORT);
}
fn writeByte(byte: u8) void {
while (inb(PORT + 5) & 0x20 == 0) {}
outb(PORT, byte);
}
fn writeAll(bytes: []const u8) void {
for (bytes) |byte| {
Self.writeByte(byte);
}
}
fn writeBytesNTimes(bytes: []const u8, times: usize) void {
for (0..times) |_| {
Self.writeAll(bytes);
}
}
};