vt100/src/vt100.h
vt_key vt100
1/* A DEC VT100, emulated from DEC's own documentation:2 * VT100 User Guide (EK-VT100-UG) - codes the keyboard sends, control sequences3 * VT100 Technical Manual (EK-VT100-TM), chapter 4 - raster, dot stretcher, attributes,4 * blink rates, bell, keyclick, auto repeat5 * Basic VT100 without the Advanced Video Option is what matters here, but the AVO attributes6 * (bold, blink, underline, reverse on any character) are implemented too. 80 columns only. */7#pragma once8#include <stdbool.h>9#include <stddef.h>10#include <stdint.h>1112#define VT_COLS 8013#define VT_ROWS 2414#define VT_CELL_DOTS 10 /* "each character ... is made up of a matrix of dots, ten wide and ten high" */15#define VT_CELL_SCANS 1016#define VT_DOTS (VT_COLS * VT_CELL_DOTS) /* "There are 800 dots in a scan" */17#define VT_SCANS (VT_ROWS * VT_CELL_SCANS) /* "and the raster is made of 240 scans" */1819/* Keys, by position on the VT100 keyboard. The typewriter keys are named by the character they20 * send unshifted ('a', '1', '[', ' ' ...); everything else has a code here. */21enum vt_key {22 VK_RETURN = 0x100,23 VK_LINEFEED,24 VK_BACKSPACE,25 VK_DELETE,26 VK_TAB,27 VK_ESC,28 VK_BREAK,29 VK_NOSCROLL,30 VK_SETUP,31 VK_UP,32 VK_DOWN,33 VK_LEFT,34 VK_RIGHT,35 VK_PF1,36 VK_PF2,37 VK_PF3,38 VK_PF4,39 VK_KP0, /* VK_KP0 + n for digit n */40 VK_KP9 = VK_KP0 + 9,41 VK_KP_MINUS,42 VK_KP_COMMA,43 VK_KP_PERIOD,44 VK_KP_ENTER,45 VK_SHIFT,46 VK_CTRL,47 VK_CAPSLOCK48};4950/* character attributes */51#define VT_ATTR_BOLD 152#define VT_ATTR_UNDERLINE 253#define VT_ATTR_BLINK 454#define VT_ATTR_REVERSE 85556/* line attributes */57enum { VT_LINE_NORMAL, VT_LINE_DOUBLE_WIDTH, VT_LINE_DOUBLE_TOP, VT_LINE_DOUBLE_BOTTOM };5859/* LEDs, bit numbers in vt100.leds */60enum { VT_LED_ONLINE, VT_LED_LOCAL, VT_LED_KBDLOCKED, VT_LED_L1, VT_LED_L2, VT_LED_L3, VT_LED_L4 };6162typedef struct {63 uint8_t glyph; /* index into the character ROM (graphics characters are 0x01-0x1F there) */64 uint8_t attr;65} vt_cell;6667typedef struct {68 int row, col;69 uint8_t attr;70 bool origin_mode;71 uint8_t g[2];72 int gl;73} vt_saved_cursor;7475typedef struct vt100 {76 vt_cell cells[VT_ROWS][VT_COLS];77 uint8_t line_attr[VT_ROWS];78 int row, col;79 bool wrap_pending; /* the VT100 stays on the last column until the next printable character */80 uint8_t attr;81 int top, bottom; /* scrolling region, inclusive, 0-based */82 bool tabs[VT_COLS];83 uint8_t g[2]; /* designated character sets: 'B' ASCII, 'A' UK, '0' special graphics */84 int gl; /* 0 = G0 (SI), 1 = G1 (SO) */85 vt_saved_cursor saved;8687 /* modes */88 bool lnm, decckm, decawm, decom, decscnm, deckpam, decarm;89 bool block_cursor; /* SET-UP: blinking block (true) or blinking underline */90 bool keyclick;9192 /* parser */93 int state;94 int params[16];95 int nparams;96 bool private_marker; /* '?' */97 uint8_t intermediate;9899 /* keyboard */100 bool shift, ctrl, caps;101 int held_key; /* the key being auto-repeated, 0 if none */102 int keys_down;103 double repeat_at; /* when the held key is sent again */104 bool xoff_sent; /* NO SCROLL */105106 /* to the host (serial line), filled by the keyboard and by answers to DA/DSR */107 uint8_t tx[256];108 int tx_len;109110 /* sounds for the host page to play, counted since the last vt_take_sounds */111 int clicks, bells;112113 uint8_t leds;114115 /* 800 x 240 dots, each 0 (black), 1 (dim), 2 (normal), 3 (bright) - the four levels the116 * DC012 video processor can put out */117 uint8_t raster[VT_SCANS][VT_DOTS];118 bool dirty; /* cells changed since the last render */119 int last_phase; /* blink/cursor phase of the last render */120 bool raster_changed; /* set by vt_render when the raster was redrawn */121} vt100;122123void vt_init(vt100 *t);124/* bytes from the host */125void vt_receive(vt100 *t, uint8_t byte);126void vt_receive_buf(vt100 *t, const uint8_t *buf, size_t n);127/* keyboard; now_ms drives auto repeat */128void vt_key(vt100 *t, int key, bool down, double now_ms);129void vt_tick(vt100 *t, double now_ms);130/* bytes to send to the host; returns how many were copied (and removes them) */131int vt_take_tx(vt100 *t, uint8_t *out, int max);132/* redraws the raster if anything visible changed; returns true if it did */133bool vt_render(vt100 *t, double now_ms);134/* the 24 lines as text (for tests and the screen-reader mirror); out must hold 24*81 bytes */135void vt_text(const vt100 *t, char *out);