#include #include #include "serial.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 init_serial() { 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(char 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, (uint8_t)b); } void soutsz(const char *s) { while (*s) sout(*(s++)); } void soutsn(const char *s, uint8_t n) { while (n--) sout(*(s++)); } char sin() { if (error) return 0; while (!(inb(CP_1 | CP_LINE_S) & CLS_READ)) ;//spin return (char)inb(CP_1 | CP_DATA); } void sinsn(char *s, uint8_t n) { while (n--) *(s++) = sin(); }