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}