diff options
author | Benji Dial <benji3.141@gmail.com> | 2020-05-24 11:02:43 -0400 |
---|---|---|
committer | Benji Dial <benji3.141@gmail.com> | 2020-05-24 11:02:43 -0400 |
commit | 02f14113cbf14c6f842fb43ecbc68d0c851ef3b0 (patch) | |
tree | 75d2d943d9822b3f945fd947e9b91eec1d68e900 /src/kernel/serial.c | |
parent | 31d8ae388a7ded576abd3e3d99c3d9193ea6d704 (diff) | |
download | portland-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.c | 100 |
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 |