forked from PoliEcho-holding-org/kern
79 lines
1.8 KiB
C
79 lines
1.8 KiB
C
#include "errno.h"
|
|
#include <vsnprintf.h>
|
|
#include <kernel.h>
|
|
#include <system.h>
|
|
#include <serial.h>
|
|
|
|
int serial_init(int dev) {
|
|
outb(dev + 1, 0x00); // Disable serial interrupts
|
|
outb(dev + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
|
outb(dev + 0, 0x03); // Set divisor to 3 (low byte) 38400 baud
|
|
outb(dev + 1, 0x00); // (high byte)
|
|
outb(dev + 3, 0x03); // 8 bits, no parity, one stop bit
|
|
outb(dev + 2, 0xC7); // Enable FIFO, clear them, with 14 byte threshold
|
|
outb(dev + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
|
|
|
outb(dev + 4, 0x1E); // Set in loopback mode, test the serial chip
|
|
outb(dev + 0, 0xAE); // Test serial chip (send byte 0xAE and check if it returns)
|
|
if (inb(dev + 0) != 0xAE) return -ENODEV;
|
|
|
|
outb(dev + 4, 0x0F); // non-loopback, IRQs enabled, OUT#1 and OUT#2 bits enabled
|
|
|
|
serial_cls(COM1);
|
|
serial_puts(COM1, "Serial display (COM1)\n\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int serial_txem(int dev) {
|
|
return inb(dev + 5) & 0x20;
|
|
}
|
|
|
|
void serial_send(int dev, char data) {
|
|
while (serial_txem(dev) == 0);
|
|
outb(dev, data);
|
|
}
|
|
|
|
int serial_rcvd(int dev) {
|
|
return inb(dev + 5) & 1;
|
|
}
|
|
|
|
char serial_recv(int dev) {
|
|
while (serial_rcvd(dev) == 0);
|
|
return inb(dev);
|
|
}
|
|
|
|
void serial_write(int dev, const char* buf, size_t len) {
|
|
for (size_t i = 0; i < len; i++) {
|
|
if (buf[i] == '\n') serial_send(dev, '\r');
|
|
serial_send(dev, buf[i]);
|
|
}
|
|
}
|
|
|
|
void serial_puts(int dev, const char* s) {
|
|
size_t len = 0;
|
|
const char* p = s;
|
|
while (*p++ != '\0') len++;
|
|
serial_write(dev, s, len);
|
|
}
|
|
|
|
void serial_cls(int dev) {
|
|
serial_write(dev, "\x1b[H\x1b[J", 6);
|
|
}
|
|
|
|
int debugf(const char* fmt, ...) {
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
int ret = vdebugf(fmt, args);
|
|
va_end(args);
|
|
return ret;
|
|
}
|
|
|
|
int vdebugf(const char* fmt, va_list args) {
|
|
char buf[DF_BUF_LEN];
|
|
int len = vsnprintf(buf, DF_BUF_LEN, fmt, args);
|
|
serial_write(COM1, buf, len);
|
|
return len;
|
|
}
|
|
|