diff --git a/include/ports.h b/include/ports.h new file mode 100644 index 0000000..252f72b --- /dev/null +++ b/include/ports.h @@ -0,0 +1,65 @@ +#ifndef FROSTBYTE_PORTS_H +#define FROSTBYTE_PORTS_H + +#include "types.h" + +static inline void outb(uint16 port, uint8 value) +{ + __asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port)); +} + +static inline uint8 inb(uint16 port) +{ + uint8 value; + __asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port)); + return value; +} + +static inline void outw(uint16 port, uint16 value) +{ + __asm__ volatile("outw %0, %1" : : "a"(value), "Nd"(port)); +} + +static inline uint16 inw(uint16 port) +{ + uint16 value; + __asm__ volatile("inw %1, %0" : "=a"(value) : "Nd"(port)); + return value; +} + +static inline void ioWait(void) +{ + outb(0x80, 0); +} + +static inline uint64 readFlags(void) +{ + uint64 flags; + __asm__ volatile("pushfq; popq %0" : "=r"(flags)); + return flags; +} + +static inline void enableInterrupts(void) +{ + __asm__ volatile("sti"); +} + +static inline uint64 saveAndDisableInterrupts(void) +{ + uint64 flags = readFlags(); + __asm__ volatile("cli"); + return flags; +} + +static inline void restoreInterrupts(uint64 flags) +{ + if (flags & (1u << 9)) + __asm__ volatile("sti"); +} + +static inline void halt(void) +{ + __asm__ volatile("hlt"); +} + +#endif diff --git a/include/serial.h b/include/serial.h new file mode 100644 index 0000000..6fa9756 --- /dev/null +++ b/include/serial.h @@ -0,0 +1,10 @@ +#ifndef FROSTBYTE_SERIAL_H +#define FROSTBYTE_SERIAL_H + +#include "types.h" + +void serialInit(void); +void serialWrite(char c); +void serialWriteString(const char* str); + +#endif diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 0000000..2cb7f21 --- /dev/null +++ b/src/serial.c @@ -0,0 +1,36 @@ +#include "serial.h" +#include "ports.h" + +#define comPort1 0x3F8 + +static bool transmitEmpty(void) +{ + return (inb(comPort1 + 5) & 0x20) != 0; +} + +void serialInit(void) +{ + outb(comPort1 + 1, 0x00); + outb(comPort1 + 3, 0x80); + outb(comPort1 + 0, 0x01); + outb(comPort1 + 1, 0x00); + outb(comPort1 + 3, 0x03); + outb(comPort1 + 2, 0xC7); + outb(comPort1 + 4, 0x0B); +} + +void serialWrite(char c) +{ + if (c == '\n') { + while (!transmitEmpty()) { } + outb(comPort1, '\r'); + } + while (!transmitEmpty()) { } + outb(comPort1, (uint8)c); +} + +void serialWriteString(const char* str) +{ + while (*str) + serialWrite(*str++); +}