summaryrefslogtreecommitdiff
path: root/src/kernel/libs/drivers/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/libs/drivers/serial.c')
-rw-r--r--src/kernel/libs/drivers/serial.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/kernel/libs/drivers/serial.c b/src/kernel/libs/drivers/serial.c
new file mode 100644
index 0000000..665f06c
--- /dev/null
+++ b/src/kernel/libs/drivers/serial.c
@@ -0,0 +1,43 @@
+#include <stdint.h>
+#include <serial.h>
+//you can add more options if you need to later
+// PORT + 3: values are from bit zero (right) to left
+// dlab(1) | misteryyy bone(1) | paraty(3) | stop bits (1) | character length (2)
+static inline void outb(uint16_t port, uint8_t value) {
+ //here "a" is the a register, and "Nd" is inteter (I think?) in the d register
+ asm volatile(
+ "outb %0, %1" :: "a"(value), "Nd"(port)
+ );
+}
+
+static inline uint8_t inb(uint16_t port) {
+ uint8_t ret;
+ asm volatile(
+ "inb %1, %0" : "=a"(ret) : "Nd"(port)
+ );
+ return(ret);
+}
+
+int init_serial(uint16_t port) {
+ outb(port + 1, 0x00); // disable them fuckin interupts
+ outb(port + 3, 0x80); // sets dlab, allowing custom serial speeds
+ outb(port + 0, 0x06); // speed is 115200/6
+ outb(port + 1, 0x00);
+ outb(port + 3, 0x03); // disables dlab, as well as 8 bit char len, 1 stop bit, no paraty, no mystery
+ outb(port + 2, 0xc7); // I have no fucking clue what this means
+ outb(port + 4, 0x0b); // don't know what this means eather... delete if you can
+ outb(port + 4, 0x1e); // loopback mode (where the hell is this documented????)
+
+ outb(port + 0, 0xae); // test char
+
+ if(inb(port + 0) != 0xae)
+ return 1;
+
+ outb(port + 4, 0x0f); // dissable interupts
+ return 0;
+}
+
+void _putchar_serial(uint16_t port, char msg) {
+ while(!(inb(port + 5) & 0x20)); //wait for transmit to be doneroni
+ outb(port, msg);
+}