vt100/src/serial.c
serial_init serial_put serial_get serial_set_paused
1#include "serial.h"23void serial_init(serial_line *l, int baud) {4 l->head = l->tail = 0;5 l->char_ms = baud > 0 ? 10.0 * 1000.0 / baud : 0.0;6 l->busy_until = 0;7 l->paused = false;8}910bool serial_empty(const serial_line *l) { return l->head == l->tail; }1112bool serial_put(serial_line *l, uint8_t b, double now_ms) {13 unsigned next = (l->tail + 1) % SERIAL_BUF;14 if (next == l->head) return false;15 if (serial_empty(l) && l->busy_until < now_ms) l->busy_until = now_ms + l->char_ms; /* line idle */16 l->buf[l->tail] = b;17 l->tail = next;18 return true;19}2021int serial_get(serial_line *l, double now_ms) {22 if (serial_empty(l) || l->busy_until > now_ms) return -1;23 int b = l->buf[l->head];24 l->head = (l->head + 1) % SERIAL_BUF;25 if (!serial_empty(l)) {26 if (l->paused) {27 l->busy_until = 1e300; /* resumes on XON */28 } else {29 l->busy_until += l->char_ms;30 }31 }32 return b;33}3435void serial_set_paused(serial_line *l, bool paused, double now_ms) {36 l->paused = paused;37 if (!paused && l->busy_until > 1e299) l->busy_until = now_ms + l->char_ms;38}