summaryrefslogtreecommitdiff
path: root/src/kernel/serial.c
diff options
context:
space:
mode:
authorBenji Dial <benji3.141@gmail.com>2020-05-24 11:02:43 -0400
committerBenji Dial <benji3.141@gmail.com>2020-05-24 11:02:43 -0400
commit02f14113cbf14c6f842fb43ecbc68d0c851ef3b0 (patch)
tree75d2d943d9822b3f945fd947e9b91eec1d68e900 /src/kernel/serial.c
parent31d8ae388a7ded576abd3e3d99c3d9193ea6d704 (diff)
downloadportland-os-02f14113cbf14c6f842fb43ecbc68d0c851ef3b0.tar.gz
very basic vga, ata, serial drivers. start of fat and fs drivers
Diffstat (limited to 'src/kernel/serial.c')
-rw-r--r--src/kernel/serial.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/kernel/serial.c b/src/kernel/serial.c
new file mode 100644
index 0000000..b88c7ec
--- /dev/null
+++ b/src/kernel/serial.c
@@ -0,0 +1,100 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include "util.h"
+
+enum {
+ CP_DATA = 0x0,
+ CP_INT = 0x1,
+ CP_FIFO = 0x2,
+ CP_LINE = 0x3,
+ CP_MODEM = 0x4,
+ CP_LINE_S = 0x5,
+ CP_MODEM_S = 0x6,
+
+ CP_DIVLOW = 0x0,
+ CP_DIVHIGH = 0x1,
+
+ CP_1 = 0x03f8,
+ CP_2 = 0x02f8,
+ CP_3 = 0x03e8,
+ CP_4 = 0x02e8
+};
+
+enum {
+ CL_BAUD = 0x80,
+
+ CL_PODD = 0x08,
+ CL_PEVEN = 0x0c,
+ CL_PON = 0x18,
+ CL_POFF = 0x1c,
+
+ CL_LSTOP = 0x4,
+
+ CL_5BIT = 0x0,
+ CL_6BIT = 0x1,
+ CL_7BIT = 0x2,
+ CL_8BIT = 0x3
+};
+
+enum {
+ CLS_B_ERR = 0x80,
+ CLS_IDLE = 0x40,
+ CLS_WRITE = 0x20,
+ CLS_BREAK = 0x10,
+ CLS_FRAME = 0x08,
+ CLS_PAR = 0x04,
+ CLS_OVER = 0x02,
+ CLS_READ = 0x01
+};
+
+bool error;
+#define SERIAL_SPIN_LIMIT 65535
+
+bool serr() {
+ return error;
+}
+
+void sinit() {
+ error = false;
+ outb(CP_1 | CP_INT, 0);
+ outb(CP_1 | CP_LINE, CL_BAUD);
+ outb(CP_1 | CP_DIVLOW, 0x03);//38400
+ outb(CP_1 | CP_DIVHIGH, 0x00);//baud
+ outb(CP_1 | CP_LINE, CL_8BIT);
+ outb(CP_1 | CP_FIFO, 0xc7);//?
+}
+
+void sout(uint8_t b) {
+ if (error)
+ return;
+ uint16_t s = SERIAL_SPIN_LIMIT;
+ while (!(inb(CP_1 | CP_LINE_S) & CLS_WRITE))
+ if (!--s) {
+ error = true;
+ return;
+ }
+ outb(CP_1 | CP_DATA, b);
+}
+
+void soutsz(uint8_t *s) {
+ while (*s)
+ sout(*(s++));
+}
+
+void soutsn(uint8_t *s, uint8_t n) {
+ while (n--)
+ sout(*(s++));
+}
+
+uint8_t sin() {
+ if (error)
+ return 0;
+ while (!(inb(CP_1 | CP_LINE_S) & CLS_READ))
+ ;//spin
+ return inb(CP_1 | CP_DATA);
+}
+
+void sinsn(uint8_t *s, uint8_t n) {
+ while (n--)
+ *(s++) = sin();
+} \ No newline at end of file