Funciona Systems

FSterm — User Guide v1.2.4

Applies to FSterm v1.2.4. Pick a topic from the Contents tree on the left. This guide is a self-contained file — you can open or share it without the application.

FS
New in v1.2.0

Pictures and graphics on a serial terminal? YES.

GrafANSI© — Graphics and ANSI, working together. That's what it's all about.

FSterm supports all the standard ANSI functions you already rely on — and now extends them to PNG / JPEG display, drawing primitives, layers & compositing, chroma-key transparency, and much more.

PNG & JPEG lines, boxes, circles arrow & hand pointers stacked layers see-through color show / hide layers zoom & pan device-triggered sounds 24-bit color text no display HW needed works over plain serial links. UDP and TCP links too!

A cheaper and simpler way to get a decent UI out of serial-connected devices and test fixtures.

Read the Graphics chapter →

Overview

FSterm is a small, portable Windows terminal. It talks to a device over a serial (COM) port or a network link (LAN mode: TCP client or UDP listener), shows what the device sends, and transmits what you type. The display is a character-cell terminal — 80×25 by default, with 80×24, 132×24 and 132×25 also available — with VT100-style cursor control, 16 colors, 24-bit “truecolor” text, and selectable color palettes.

Beyond plain text it can render incoming bytes three ways (ANSI, raw ASCII, or a HEX view), capture a session to a file, and play back a text file to the device with adjustable timing.

Version 1.2.0 also adds GrafANSI© — a way for your device to put real pictures and drawings on the terminal screen, on top of a photo if you like. If that is what you came for, jump to What GrafANSI© is.

FeatureSummary
Connection modesSerial (COM port) or LAN (TCP client / UDP listener), chosen with the Mode selector.
PortsLists every serial (COM) port currently present on the system; Refresh re-scans.
Line settingsBaud 150–921600; framing 8N1 / 7E1 / 8E1 / 8N2.
Terminal size80×24, 80×25, 132×24, or 132×25, from the Terminal menu.
DisplayANSI (interpreted), ASCII (raw with control tokens), or HEX dump.
PalettesCampbell, VGA, or PuTTY 16-color sets, plus 24-bit truecolor text.
Graphics (GrafANSI©)PNG/JPEG pictures, drawn shapes, pointers, layers, and see-through color.
Background imageA permanent PNG/JPEG wallpaper behind the terminal, with fit and opacity (no device command can touch it).
CursorBlock, outline, or double-underline, blinking or steady.
MouseDrag to select text; right-click for Copy / Select All.
Capture / playbackRecord to a file (raw or hex dump); replay a text file to the device.
ScreenshotsSave the terminal grid as a PNG/JPEG — auto-numbered or single-shot, with selectable layers — from a button, F12, or the command line.
AutomationEvery setting and most actions driveable from the command line; a running window can be remote-controlled and locked. See Command-line & automation.
PortabilitySingle executable; preferences saved in FSterm.ini next to it.

What's new

New in v1.2.4

  • Faster, smoother display. Screen rendering is roughly 30–40% faster, for noticeably smoother scrolling and less screen-lag — especially with large windows and busy serial output — plus snappier keyboard response.
  • Screenshots. Save the terminal as a PNG or JPEG from the Screenshot button, File → Take screenshot, the F12 key, or the command line. A new File → Screenshot setup… dialog sets a destination folder and base name, then either auto-numbers shots (name_001, name_002, …) or takes a single named shot (after which it asks where to save, so nothing is overwritten). Choose the format, and pick which layers to include — background image, glass (placed pictures/drawings), or text-only. Captures are the terminal grid only (no margin) at on-screen resolution, framed with a 1 px black border; the saved shot's number appears briefly in the status line (or on the canvas in slim mode). See Screenshots.
  • Permanent background image. Load a PNG or JPEG wallpaper that sits behind the terminal as a fixed bottom layer, from File → Load background image…. Choose how it fills the screen (Stretch to fill, Lock aspect ratio, or Center) under File → Background fit, and set its transparency with a live opacity slider under File → Background opacity…. The image shows through wherever the screen is blank; text, drawings, and GrafANSI pictures all sit on top of it. It belongs to the application, so no serial command can move, cover, or erase it, and it is remembered in FSterm.ini. See Background image.
  • Cursor style & blink. The Terminal → Cursor menu chooses a solid block, a hollow outline, or a double underline, and a Blink toggle turns the flash on or off. See Cursor style & blink.
  • All standard baud rates. The Baud list now runs from 150 to 921600. Rates of 230400 and above carry a “(May be HW limited)” note — they are standard and fully selectable, but whether they run cleanly depends on your USB-serial adapter and the device at the other end. See Baud rate & framing.
  • Fully automated control via command-line options. Every setting and most actions can be driven from the command line, and a running FSterm can be remote-controlled by launching FSterm.exe again with options — change the baud, connect, play a file, take a screenshot, or close it, all from a batch script with no clicking. The window can even be locked so nothing disturbs an unattended run. This has its own chapter: Command-line & automation.

New in v1.2.2

  • Optimized performance. After a lot of testing and tweaking, v1.2.2 offers optimized performance — and greatly decreased screen-lag — when using serial links.

New in v1.2.1

  • Slim GUI mode. A one-key (F11) view that hides everything except the terminal canvas inside a thin blue border. Move the mouse to the top edge to slide the controls back for a moment, then away to hide them again. See Slim GUI mode.
  • The window follows the terminal size. Changing the geometry now re-shapes the whole window to match the new grid — and a larger grid is kept within the current window footprint, so it cannot run off the edge of a small screen. This works whether you change the size from the menu or the device requests it. See Terminal size (geometry).
  • Smoother serial. Background serial-port and modem-line polling no longer runs while a port is open, removing a periodic stall that could make typing and incoming text feel laggy on some USB-serial adapters.

The v1.2.0 graphics release

Version 1.2.0 is the graphics release. Everything from earlier versions still works exactly as before — plain text, colors, capture, playback, serial and LAN are unchanged. What is new is that a device can now draw pictures and shapes on the screen, and that the terminal itself picked up several conveniences.

Graphics: GrafANSI©

  • Pictures on screen. Your device can send a PNG or JPEG down the same cable it already uses for text, and FSterm displays it. See Sending pictures.
  • Drawing. Lines, rectangles, circles, and ellipses, in any color, drawn either onto a picture or onto a blank see-through sheet. See Drawing shapes.
  • Pointers. Two ready-made shapes — an arrow and a pointing hand — that can face any of 8 directions, for calling out a spot on a photo. See Pointers & line width.
  • Line width. Every line and outline can be made thicker.
  • Layers. Several pictures and drawings can stack on top of each other, so you can put a diagram over a photograph. See Layers & z-order.
  • Show / hide layers. Any layer can be switched out of view and back with a very short command, keeping its picture, its artwork, and its place in the stack. Whole screens can be built invisibly and then flipped into existence at once. See Showing and hiding a layer.
  • See-through color. One color is treated as “invisible,” which is how shapes get transparent backgrounds and how text shows through artwork. See See-through color.
  • Zoom. A very large picture — a full-size schematic, say — can be shown whole, then zoomed into one corner, with no re-sending. See Zooming into a big picture.
  • Device-triggered sounds. A device can play a .wav from your media-repo folder — a specific alarm per fault, say. Audio is never sent over the cable; the device can only name a file you put there. See Playing sounds.
  • Media cache & media repo. Pictures are remembered on disk so the second time your device asks for one it appears almost instantly, and you can pre-load your own picture files into a folder so they never have to travel over the cable at all. See Media cache & media repo.

Terminal improvements

  • Four terminal sizes. A new Terminal menu offers 80×24, 80×25, 132×24, and 132×25. Your device can also request a size itself. See Terminal size (geometry).
  • Mouse selection and copy. Drag across the screen to select text, then right-click for Copy or Select All (or press Ctrl+Shift+C / Ctrl+Shift+A). See Selecting & copying text.
  • Truecolor text. Text is no longer limited to 16 colors — a device can ask for any 24-bit color.
  • The bell works. The BEL character (0x07) now does something — a system ding, a .wav of your choosing, a silent on-screen bell icon, or nothing, whichever you prefer. See The bell (BEL).
  • Much fuller ANSI support. Scrolling regions, the alternate screen buffer, insert and delete of lines and characters, adjustable tab stops, autowrap and origin modes, cursor position reporting, and the faint / italic / blink / strikethrough attributes. See ANSI command summary.
  • Smoother screen. The display is now drawn off-screen and swapped in one piece, so fast-updating screens no longer flicker.
  • Tidier window. The area around the terminal is dark gray rather than black, so the live screen area is easy to see at a glance.

Carried over from v1.1.0

  • LAN mode (TCP / UDP). The Mode selector at the top-left switches between Serial and LAN. TCP connects to a server as a client; UDP binds and listens on the chosen port. See LAN mode (TCP / UDP).
  • UDP listen-and-reply and UDP broadcast, plus the <none> EOL option for protocols that frame their own messages.

Quick start

  1. Plug your device into a USB or serial port and launch FSterm.exe.
  2. Pick the device's port from the Port dropdown (click Refresh if it isn't listed).
  3. Choose the baud rate and framing the device uses (commonly 115200 and 8N1).
  4. Click Connect. Incoming text appears in the terminal; type to send.
  5. Click Disconnect when done. Your settings are remembered for next time.

Installation

FSterm is a single portable Windows application — there is no installer and nothing is added to the system. Copy the files to a folder and run the executable.

What you need

  • A Windows PC (64-bit).
  • A serial device and its USB or serial cable.
  • The FSterm package: FSterm.exe and, optionally, this FSterm_Help.html.

Install & run

  1. Keep FSterm.exe and its companion files together in one folder.
  2. Double-click FSterm.exe to launch — no admin rights and no runtime downloads.
  3. Connect the device by USB. Windows assigns it a COM port (visible in Device Manager under “Ports (COM & LPT)”).
First launch: the first time you run FSterm, an End-User Disclaimer appears. Read it and click I Accept to continue, or Decline and Exit to close. You are asked only once; your acceptance is recorded in FSterm.ini. You can re-read the text any time from Help → End-User Disclaimer or the link in Help → About.

USB drivers

Devices with an FTDI, CH340, CP210x, or genuine-Arduino USB bridge appear as a COM port. A clone bridge may need its vendor driver installed once before the port shows up.

FSterm lists all present serial ports without guessing which is your device — if several are shown, match the one that appears/disappears as you unplug and replug the cable, or check Device Manager.

The window at a glance

The terminal fills the window. Three control rows sit above it and a status bar runs along the bottom.

Row 1 — serial connection

ControlPurpose
PortDropdown of the serial ports currently present on the system, each labelled with its driver description (the same text Device Manager shows), e.g. COM5 - USB-SERIAL CH340. The list re-probes Windows automatically whenever you open it or a device is plugged/unplugged.
RefreshForce an immediate re-scan for ports (rarely needed — the list refreshes itself).
BaudLine speed, 150–921600.
FramingData/parity/stop bits: 8N1, 7E1, 8E1, 8N2.
Connect / DisconnectOpen or close the selected port.
ClearBlank the terminal screen.

Row 2 — file capture & playback

ControlPurpose
CaptureStart/stop recording the session to a file.
PlaybackChoose the text file to send (does not start it). The chosen filename is shown at the end of this row.
Play / StopStart sending the chosen file, or stop a playback in progress. Grayed out until a file is chosen.
Char msInter-character delay during playback, 0–500 ms (0 = no delay, send as fast as possible).
EOLLine ending transmitted at the end of each line during playback: CR, LF, or CRLF.
Line msEnd-of-line delay during playback, 0–500 ms (0 = none).

Row 3 — terminal options

ControlPurpose
ScreenshotSave a screenshot of the terminal grid using the current setup (also F12). See Screenshots.
Input:How typing is transmitted — char: each byte is sent as soon as it is typed; line: typing is buffered and sent when you press Enter.
EOL Mode:What is transmitted when you press Enter: CR (one CR), LF (one LF), CRLF (both), or — in LAN mode only — <none> (no terminator). Applies in both char and line mode. (Playback has its own EOL, above.)
EchoLocal echo: show what you type in the terminal.
Auto-scrollKeep the newest output in view.
DisplayHow incoming bytes are rendered: ANSI, ASCII, or HEX.
PaletteTerminal color set: Campbell, VGA, or PuTTY.

RS-232 signal LEDs

A compact strip of eight indicators sits at the right end of the terminal-options row. Each is a small labelled box showing the state of one RS-232 line: bright green = asserted / active, grey = inactive.

LEDDirectionMeaning
TXoutputFlashes when FSterm transmits bytes.
RXoutput → inFlashes when bytes arrive from the device.
RTSoutputRequest To Send — a line you drive. Click this LED to toggle it.
CTSinputClear To Send from the device.
DTRoutputData Terminal Ready — a line you drive. Click this LED to toggle it.
DSRinputData Set Ready from the device.
DCDinputData Carrier Detect from the device.
RIinputRing Indicator from the device.

The RTS and DTR boxes are shown in a darker frame and act as toggles — click one (while connected) to flip that output line. The change is applied to the hardware immediately and is remembered in FSterm.ini, so it is re-applied the next time a port opens.

When no port is connected the whole strip is grayed out (washed-out light grey) and the RTS/DTR toggles are disabled — a clear sign the terminal is not live. The LEDs come back to life the moment a port opens.
DTR & auto-reset: on many microcontroller boards, toggling DTR resets the board. DTR defaults to asserted; click the DTR LED to toggle it.

Selecting a port & connecting

Choose the device from the Port dropdown. If it isn't listed, plug in the cable and click Refresh. Click Connect to open the port; the button then reads Disconnect.

  • Only one program can hold a serial port at a time. If Connect fails, another application (or another FSterm window) may already own the port.
  • The last port you used is remembered and pre-selected next launch.
  • Changing baud or framing while connected reopens the port automatically so the change takes effect immediately.

Automatic reconnect

Working on an embedded project usually means unplugging the USB cable to reset the board. Windows immediately drops the COM port that went with it — and most terminal programs leave you to notice, then click Reconnect, or cycle the port closed and open again. Every single time.

FSterm watches for it instead. Once a COM port is connected it is monitored continuously and reopened automatically the moment it comes back, with the screen contents kept. A simple feature, but it removes one of those little time-vampires from your development day.

What you see when it happens:

  • The Port box grays out and the status bar shows “COMx disconnected – waiting to reconnect…”. No error dialog appears.
  • As soon as the same port comes back, FSterm reopens it automatically, the Port box un-grays, and the status bar shows “Reconnected COMx”. The screen contents are kept.
  • To stop waiting, click Disconnect.

Baud rate & framing

Set the baud and framing to match the device exactly — a mismatch produces garbage characters or nothing at all.

FramingData bitsParityStop bits
8N18none1
7E17even1
8E18even1
8N28none2

Available baud rates: 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600. The default is 115200.

High speeds. Rates of 230400 and above are shown with a “(May be HW limited)” note in the dropdown. They are standard and fully selectable, but whether they run cleanly depends on your USB-serial adapter and the device at the other end — if a fast rate drops or garbles characters, step down to the next one.

LAN mode (TCP / UDP)

The Mode selector at the left of the top row switches the transport between Serial and LAN. In LAN mode the Port/Baud/Framing controls are replaced by an Address field, a Port field, and a TCP / UDP selector. Everything else — the terminal canvas, display/palette/EOL/echo controls, capture, and playback — works exactly as it does over serial. (The RS-232 signal LEDs apply only to a serial port, so they are hidden in LAN mode.)

The Address, Port, and TCP / UDP fields can only be edited while idle; they are locked (grayed) while connected or listening, since changing the target mid-session would have no effect. Disconnect to change them.

ProtocolButtonBehavior
TCPConnectConnects to the server at Address : Port as a client. If the host can't be reached, the attempt gives up after about 5 seconds and the status bar reports the failure. If the server later closes the connection, FSterm disconnects (no automatic reconnect).
UDPListenBinds and listens on the given Port for incoming datagrams. Typed or played-back bytes are sent to Address : Port until the first datagram arrives, after which replies follow whatever peer last sent to you (listen-and-reply).

UDP broadcast

To receive broadcast traffic, enter a broadcast address as the Address — either the limited broadcast 255.255.255.255 or a subnet-directed broadcast such as 192.168.1.255 — with the port to listen on, and click Listen. FSterm binds the port and shows every broadcast datagram that arrives on it. For a broadcast address the port is opened as shareable, so FSterm can listen alongside other programs (or a second FSterm) bound to the same broadcast port on the same machine. A normal unicast address keeps an exclusive bind, so a port already in use is still reported as an error.

Broadcast to 255.255.255.255 travels over the active LAN/Wi-Fi adapter, not the loopback interface. If a same-machine test shows nothing, use your subnet's directed broadcast (e.g. 192.168.1.255) instead.

Example — talk to a TCP service: choose LAN, TCP, enter 127.0.0.1 and 5000, click Connect, then type. For UDP, enter the port to listen on and click Listen. The test_servers folder beside the app has ready-made TCP/UDP/broadcast test peers (with double-click .bat launchers).

The terminal

The terminal is a character grid — 80×25 out of the box — rendered in a fixed-pitch font that scales to fill the window. It interprets a practical subset of ANSI/VT100 (see ANSI / VT100 support) so colored, cursor-addressed output from a device is shown as intended.

  • Click the terminal to give it keyboard focus; a highlighted cursor cell marks the caret.
  • Keystrokes are sent to the device only while connected.
  • While no port is connected, the terminal canvas is grayed out to show it is not live; it returns to normal as soon as you connect.
  • Drag with the mouse to select text — see Selecting & copying text.
  • The screen shows the visible grid only. There is no scrollback buffer: once a line scrolls off the top it is gone. If you need a permanent record, use Capture to file.

Terminal size (geometry)

The Terminal menu picks how many columns and rows the screen has. The current choice has a dot next to it, and it is remembered for next time.

SizeTypical use
80 × 24The classic VT100 size. Use it if your device was written for a real terminal.
80 × 25The PC text-mode size. This is the default.
132 × 24Wide mode — good for tables and log output.
132 × 25Wide mode with the extra PC row.
The menu is grayed out while you are connected. Resizing the screen mid-session would scramble whatever the device had already drawn, so Disconnect first, change the size, then connect again.

Your device can change it too

A device can request a size by sending the standard sequence ESC [ 8 ; rows ; cols t. Only the four sizes above are accepted; anything else is ignored. This is the reliable way to do it — a program that needs 132 columns should ask for them rather than hope you set the menu correctly.

A device can also ask what the size currently is, and adapt itself to the answer. If a program you are running draws in the wrong place after you change the size, that program is assuming a fixed size instead of asking — see Cells vs. pixels.

Slim GUI mode

Slim GUI mode strips the window down to just the terminal canvas inside a thin blue border — no menu bar, no control rows, no status bar, no title bar. It is for when you have the connection set the way you want and simply want to watch the screen, giving the most pixels to the terminal and the least to everything else.

Press F11 to enter it, and F11 again to return to the normal window. The mode is never remembered between runs — FSterm always starts in the normal window.

The window fits the terminal exactly

The window takes on the exact shape of the current terminal size: an 80-column screen is a tall, narrow window and a 132-column screen a wide one, with no wasted margin around the text. Change the geometry — before entering slim mode, or from the peeked menu below — and the slim window re-shapes itself to match.

Getting the controls back for a moment (peek)

You do not have to leave slim mode to reach the menu or the controls. Move the mouse to the very top of the canvas and a panel slides down over the top of the screen, carrying the title bar (with the minimize / maximize / close buttons), the menu bar, and the full set of connection and terminal controls. Use whatever you need; when the mouse moves back off the panel it slides away again and you are left with the bare canvas. The terminal underneath never moves or resizes while the panel is showing — it is simply covered for a moment.

A small dead strip is left at the very top edge so you can still grab the window's top resize border without the panel dropping down. Aim a few pixels lower to trigger the peek.

Moving and resizing

  • Move — drag the thin blue border, or drag the title bar while the panel is peeked.
  • Resize — drag any edge or corner, exactly like a normal window. The text always keeps whole character cells, so the window steps in cell-sized increments and never shows a partial row or column. (Because of that, dragging an edge only a few pixels may not change the size until you cross into the next whole cell.)
  • Maximize, from the peeked title bar, returns to the normal window, maximized.

Good to know

  • The connection keeps running the whole time — entering or leaving slim mode does not touch the serial or LAN link.
  • The status bar is hidden, so the “disconnected / reconnecting” line is not shown; the canvas still dims when the link drops, as usual.
  • Everything else behaves the same as in the normal window — typing, selection and copy, GrafANSI© graphics, capture and playback all work identically.

Selecting & copying text

You can lift text off the screen and paste it into an email, a bug report, or a document.

  1. Press and hold the left mouse button where you want to start.
  2. Drag to the end of what you want. The selected text highlights as you go.
  3. Release, then right-click and choose Copy — or just press Ctrl+Shift+C.

Select All (right-click menu, or Ctrl+Shift+A) grabs the whole visible screen.

ActionHow
Select a rangeClick and drag.
CopyRight-click → Copy, or Ctrl+Shift+C.
Select everythingRight-click → Select All, or Ctrl+Shift+A.
Clear the selectionClick once anywhere on the terminal.
Why Ctrl+Shift+C and not plain Ctrl+C? In a terminal, plain Ctrl+C has to keep its original job — sending the interrupt byte (0x03) to your device to stop a running program. Adding Shift keeps both behaviors available.
Copying takes the visible screen only, because that is all FSterm keeps (there is no scrollback). Trailing blanks at the end of each line are trimmed, and each row becomes one line of text.

The bell (BEL)

Terminals have had a bell since the teletype era. A device sends the single byte 0x07 — called BEL — to get your attention: a test has finished, a limit was exceeded, something needs looking at.

FSterm gives you four ways to answer it, on the Terminal → Bell menu. Your choice is remembered.

SettingWhat happens on BEL
Off (ignore BEL) Nothing at all. The byte is swallowed — it never appears on screen.
Ding (system sound) Your Windows default notification sound. This is the default setting.
Sound file… Opens a file picker so you can choose any .wav. It plays once when you pick it, so you know it works, and from then on for every bell.
Visual only (bell icon) No sound. A small amber bell appears in the top-right corner of the screen for about three-quarters of a second. Use this in a shared office, or when the PC has no speakers.
Bells are limited to about five a second. A device dumping a log full of BELs — or a binary file arriving by mistake — would otherwise machine-gun your speakers. Extra bells inside that window are dropped, not queued, so the sound never runs on after the burst has stopped.

If your chosen .wav is later moved or deleted, FSterm falls back to the system ding rather than going silent — you still get the alert.

For firmware authors

Send a bare 0x07. There is no escape sequence and nothing to set up:

putchar(0x07);          /* ding */

A device cannot tell which mode the user picked, and cannot override it. If you want a sound you control, see Playing sounds instead.

BEL is also used to end a window-title sequence (ESC ] 2 ; title BEL). FSterm recognizes that case and does not ring the bell for it, so setting a title is silent.

Display modes

The Display dropdown changes how incoming bytes are shown — it does not change what the device sends.

ModeWhat you see
ANSIEscape sequences are interpreted: colors, bold/underline, cursor moves, screen/line erase, and DEC line-drawing all render. This is the normal mode.
ASCIIRaw text with control bytes shown as tokens (<cr>, <lf>, <tab>, <esc>); other non-printables appear as [HH]. Good for seeing exactly which control characters arrive.
HEXEvery byte is shown as [HH]. A raw byte-level view for protocol debugging.

High-bit bytes (0x80–0xFF) in ANSI mode render as their CP437 glyphs — box-drawing, blocks, shading, arrows — in the colors the device selected, exactly like ASCII characters. See Character set — CP437.

Palettes

The Palette dropdown selects the 16-color set used for ANSI colors:

  • Campbell — the modern Windows Terminal scheme (default).
  • VGA — the classic PC text-mode colors.
  • PuTTY — the familiar PuTTY defaults.

Input modes & echo

Input mode (char vs. line)

The Input: dropdown controls how your typing is transmitted:

  • char — each byte is sent as soon as it is typed. Best for interactive shells and menus.
  • line — typing is buffered and sent only when you press Enter, followed by the selected EOL. Backspace edits the pending line.

EOL Mode

The EOL Mode: dropdown sets what is transmitted when you press Enter (in either input mode): CR = a single \r, LF = a single \n, CRLF = both \r\n. (Playback has its own independent EOL selector.)

In LAN mode the dropdown also offers <none>: pressing Enter sends the typed line with no terminator at all — useful for TCP/UDP protocols that frame messages themselves. <none> is not offered in Serial mode; if it was chosen in LAN and you switch to Serial, EOL falls back to CR (and returns to <none> when you switch back to LAN).

Local echo

With Echo on, characters you type are also drawn in the terminal. Turn it on when the device does not echo your input; turn it off if you see every character doubled.

Capture to file

Click Capture to record everything the device sends. Choose a file in the Save dialog; the button changes to Stop while recording. Capture appends to the chosen file.

  • Raw (default) — the received bytes are written verbatim.
  • Hex dump — tick “Save as HEX DUMP” in the Save dialog to write a DEBUG-style listing with offset, hex bytes, and an ASCII column.

Click Stop (or close the app) to finish and flush the file.

Playback from file

Playback sends a text file to the device, one character at a time, with adjustable pacing. The controls sit together on the file row:

  1. Click Playback and choose the text file. (This only selects it; nothing is sent yet.) The chosen filename appears at the end of the file row and Play becomes enabled.
  2. Set the pacing and line ending:
    • Char ms — delay between characters, 0–500 ms (0 = no delay).
    • EOL — what to transmit at the end of each line: CR, LF, or CRLF. Any CR/LF/CRLF endings in the file are normalized first, then re-emitted as this selection.
    • Line ms — extra delay after each line, 0–500 ms (0 = none).
  3. Click Play to start (the port must be connected). The button changes to Stop; click it to abort. The status bar shows Playing… and then Playback finished (or stopped).

The pacing and EOL choices are remembered in FSterm.ini. Playback also stops automatically if the port disconnects.

Clear

Clear blanks the terminal display. It does not affect the device or any capture file.

Background image

FSterm can display a permanent background image — a wallpaper that sits behind the terminal as the bottom-most layer. It is a convenience for the operator (a logo, a labelled panel drawing, a reference photo), entirely separate from the pictures a device can draw with GrafANSI©: it belongs to the application, not to the serial link, so no command from the device can move, cover, or remove it.

Loading and clearing

  • File → Load background image… — pick a PNG or JPEG. It appears immediately and is remembered for next time.
  • File → Clear background image — remove it.

Fit

File → Background fit chooses how the image fills the screen:

FitWhat it does
Stretch to fillScales the image to cover the whole screen, ignoring its aspect ratio.
Lock aspect ratioScales the image as large as it will go while keeping its proportions, centered, with plain margins (letterbox) around it.
CenterShows the image at its native pixel size, centered (and cropped if it is larger than the screen).

Opacity

File → Background opacity… opens a slider (1–100%). Drag it and the wallpaper fades in real time — useful for dropping a busy image back so the text over it stays easy to read. The little dialog can stay open while you work.

How it composites

The wallpaper is the bottom layer, and it is visible wherever the screen is blank — that is, through the default background of empty cells. Everything drawn on top covers it: text (a cell painted with a background color hides the part of the image under it), GrafANSI pictures and drawings, and the cursor. This is the same “see-through-where-blank” behavior the chroma key uses, applied automatically to the whole screen.

The image path, fit, and opacity are all saved in FSterm.ini, and can also be set from the command line (-bgimage, -bgfit, -bgopacity) — see Command reference.

Cursor style & blink

The Terminal → Cursor menu sets how the text cursor looks and whether it blinks. The choice is remembered in FSterm.ini.

StyleAppearance
BlockA solid filled cell — the classic terminal cursor (default).
OutlineA hollow box — the cell outline only, so the character under it stays readable.
Double underlineTwo thin lines along the bottom of the cell.

Blink (a checkbox on the same menu) turns the flashing on or off; with it off the cursor is shown steadily. All three shapes are drawn by inverting the pixels beneath them, so the cursor is always legible over any color, character, or the background image.

Both can be set from the command line as well: -cursor block|outline|double and -cursorblink on|off.

Screenshots

FSterm saves an image of just the terminal grid — the character area only, with no margin and no scaling — at its exact on-screen pixel size (which grows with the window), framed with a 1 px black border. This works for any screen size (80×24/25, 132×24/25). The canvas is re-rendered for the capture rather than copied from the screen, so it works even when the window is minimized or partly covered.

Taking a screenshot

  • The Screenshot button at the left of the third control row, File → Take screenshot, or the F12 key.
  • The command line: -snap takes one using your saved setup (below), or -screenshot <file> saves to an explicit path — both work against a running window, so a script can drive the device and then capture the result. See Command reference.

The saved shot's number (or name) appears briefly in the status line — or, in slim GUI mode where there is no status line, as a short message on the canvas.

Screenshot setup

File → Screenshot setup… configures where and how shots are saved (it does not take one). Settings are remembered in FSterm.ini.

  • Folder & base filename — the destination folder (with a Browse… button) and a base name such as scrsession.
  • Auto-number — when ticked, each shot is saved as base_001, base_002, …; FSterm scans the folder and continues from the highest number already there. When unticked (single-shot), the first press saves base once; a second press opens a Save As dialog so the previous shot is never overwritten. (If no base name is set, the button always opens Save As.)
  • Format — PNG or JPEG.
  • Layers to include — Background image and/or Glass (placed pictures and drawings). With both off, the shot is the text layer on a black background (all its colors preserved).

All of these are also settable from the command line (-ssfolder, -ssname, -ssautonumber, -ssformat, -sswithbg, -sswithglass). See Command reference.

Command-line & automation

Why automate?

The point of the command line is to drive a remote device with no human at the keyboard. A PowerShell or CMD batch file can open the connection to a serial- or LAN-connected device, send it commands, and capture everything it sends back — either as a data capture file or as a screenshot of the terminal — for later inspection or an audit log. Anything a person could do sitting at the terminal, the CLI can do too. That opens up situations that are awkward or impossible by hand, for example:

  • Provisioning network & embedded gear — push a saved configuration to a router, switch, modem, or embedded controller over its serial console, then capture the result to confirm it took — the same script for every unit.
  • Production-line setup & test — configure, program, exercise, and screenshot each product identically and hands-free as it comes down the line, leaving a per-unit record.
  • Repeatable test sequences — send the exact same stimulus to a device every time and capture its response, so results can be compared run to run.
  • Unattended & scheduled runs — kick off a device self-test overnight, or on a timer, and leave a screenshot and a capture file behind as the record.
  • Audit trails — keep a timestamped capture and a screenshot of what a device reported, as evidence of what was done and what it answered.
  • Kiosk / display use — bring up a locked, full-screen terminal (optionally over a background image) that shows a device's output and cannot be tampered with.

These are just examples — the applications are numerous. Any task that involves talking to a serial or LAN device and reacting to what it says can be turned into a repeatable, logged, hands-free script.

Everything you can set in the window can also be set from the command line, and most actions (connect, play a file, take a screenshot, close the program) can be triggered the same way. This makes FSterm scriptable: a batch file can bring up a terminal exactly the way you want, drive a test, and tear it down again with no clicking.

Options are written as -name (a leading /name works too) and are case-insensitive. Options that take a value are followed by it as the next argument, e.g. -baud 115200. Wrap any value containing spaces in quotes, e.g. -bgimage "C:\pics\my logo.png".

FSterm.exe -port COM5 -baud 115200 -connect
Run FSterm.exe -help (or -?) to print the full option list to the console, or, if there is no console, in a message box.

Remote-controlling a running window

FSterm is single-instance. The first launch opens the window and owns it. Every later launch of FSterm.exe — with whatever options you give — does not open a second window: it hands those options to the window that is already open, applies them live, and exits. That is what makes remote control work.

  • Change a setting live: FSterm.exe -baud 9600 re-tunes the open window (and reopens the port if it is connected).
  • Trigger an action: FSterm.exe -screenshot shot.png captures the running window's canvas.
  • Close it: FSterm.exe -exit closes the running window. If none is running it simply succeeds — safe to put at the end of a script unconditionally.

Locking the window for unattended runs

-lock disables the whole GUI — every control, the menus, and typing into the terminal — so an operator cannot disturb an automated session. The window keeps showing live data; only input is blocked. The frame's [X] close button stays active as a manual escape hatch. -unlock restores normal use.

Window state

-minimize, -restore, and -maximize control the window; -slim switches to Slim GUI mode. These work against the running window too.

A minimized window is fully live — it still receives, parses, replies, captures, and plays back. Only the on-screen drawing is skipped while minimized.

Option order & sessions

Two rules make scripting predictable:

  • Options apply strictly left to right. Order matters when one depends on another. To change the baud on an open connection, disconnect, change it, then reconnect — all on one line, in that order:
    FSterm.exe -disconnect -baud 230400 -connect
    Put a -play or -send last, after every setting that should be in effect while it runs.
  • Changes are for this session only, unless you add -save. By default a command-line change affects the running program but is not written to FSterm.ini, so the next normal launch is unaffected. Add -save to write the current settings to the ini and make them the new defaults. (Changes you make in the GUI by hand are always saved, as before.)

Command reference

Every option is listed below. Values shown as a|b|c are the accepted choices.

Connection

OptionValueEffect
-serial / -lan—Connection mode.
-portCOMxSerial port to use.
-hostaddressLAN target address.
-netportnumberLAN target / listen port.
-prototcp|udpLAN protocol.
-baud150–921600Line speed.
-framing8N1|7E1|8E1|8N2Data / parity / stop bits.

Terminal

OptionValueEffect
-paletteCampbell|VGA|PuTTYColor palette.
-echoon|offLocal echo.
-inputmodechar|lineSend each key, or buffer until Enter.
-linetermcr|lf|crlfWhat Enter transmits.
-autoscrollon|offKeep newest output in view.
-displaymodeansi|ascii|hexHow incoming bytes are shown.
-geometry80x25|80x24|132x25|132x24Screen size (grid).
-cursorblock|outline|doubleCursor shape.
-cursorblinkon|offCursor blink.
-belloff|ding|wav|visualBell (BEL) response.
-bellwavfileThe .wav for bell mode wav.
-rtson|offRTS output line.
-dtron|offDTR output line.

Background image

OptionValueEffect
-bgimagefile, or noneSet (or clear) the wallpaper. See Background image.
-bgfitstretch|aspect|centerHow it fills the screen.
-bgopacity0–100Opacity, percent.

Screenshot setup

OptionValueEffect
-ssfolderfolderDestination folder (default: the exe folder).
-ssnamebase nameBase filename, no extension.
-ssautonumberon|offOn: base_001, base_002, …. Off: single-shot, then Save As.
-ssformatpng|jpgOutput image format.
-sswithbgon|offInclude the background-image layer.
-sswithglasson|offInclude the glass layer (placed pictures/drawings). Both off = text on black.

GrafANSI & playback

OptionValueEffect
-mediacacheon|offOn-disk picture cache.
-mediarepoon|offAllow reads from the media-repo folder.
-soundson|offAllow device-triggered .wav playback.
-playchardelay0–500 msInter-character delay for playback.
-playeoldelay0–500 msEnd-of-line delay for playback.
-playeolcr|lf|crlfLine ending used during playback.
-capturehexon|offCapture as a hex dump instead of raw bytes.

Window & lock

OptionValueEffect
-maximize / -minimize / -restore—Window state.
-sizeWxHWindow size in pixels (e.g. 1200x800).
-slim—Slim GUI mode (canvas only).
-lock / -unlock—Disable / re-enable all GUI input (the [X] stays active).

Actions (run in command-line order)

OptionValueEffect
-connect / -disconnect—Open / close the connection.
-capturefileStart capturing to a file (appends; honors -capturehex).
-playfileStart playing a text file to the device (returns right away).
-sendfilePlay a file and wait until it finishes before returning — for scripts that must send in sequence.
-snap—Take one screenshot using the Screenshot-setup config (auto-number / single-shot / Save As). See Screenshots.
-screenshotfileSave the terminal grid to an explicit path (PNG/JPEG by extension), grid-only with a 1px black border and the configured layers. See Screenshots.
-clearcache—Delete every cached picture (silent).

Program

OptionValueEffect
-save—Write the current settings to FSterm.ini.
-exit—Close the running window (succeeds even if none is running).
-help / -?—Print the option list and exit.
About -send and waiting: a batch file (cmd.exe) that runs FSterm.exe -send file directly waits for the playback to finish before the next line, because -send keeps the launched process alive until it is done. From PowerShell, which does not wait on GUI programs, use Start-Process FSterm.exe -ArgumentList '-send','file' -Wait.

Batch examples

Open a terminal, connect, and lock it for an unattended display:

FSterm.exe -port COM5 -baud 115200 -framing 8N1 -displaymode ansi -connect -lock

Show a branded wallpaper behind the terminal, dimmed:

FSterm.exe -bgimage "C:\panel\backdrop.png" -bgfit stretch -bgopacity 40

Re-tune an already-open window, then grab a screenshot of the result:

FSterm.exe -disconnect -baud 9600 -connect
FSterm.exe -screenshot C:\logs\after.png

Send a script to the device and wait for it to finish, then close everything (a full run in a .bat):

FSterm.exe -port COM5 -baud 115200 -connect
FSterm.exe -playchardelay 0 -send C:\tests\stimulus.txt
FSterm.exe -screenshot C:\tests\result.png
FSterm.exe -exit

Because the middle line uses -send, the batch does not reach the screenshot until the whole file has been transmitted.

Let an AI write your scripts

To help you leverage AI for generating FSterm automation scripts, an AI-readable user guide is also provided alongside this document: FSterm_AI_UG.md. It is a condensed, machine-friendly version of everything in the Command-line & automation chapter — every option, its values and defaults, the single-instance rules, the CMD-vs-PowerShell waiting behavior, and ready-made example scripts.

Just direct your chosen AI assistant to read that file, then describe what you want to automate in plain language. With the full command reference in front of it, generating even complex PowerShell or CMD batch scripts becomes considerably easier — and the results are far more likely to be correct the first time.

FSterm_AI_UG.md ships next to FSterm.exe and this help file. It is plain Markdown, so you can open it in any text editor as well.

What GrafANSI© is

A normal terminal can only show letters and numbers. GrafANSI© — Graphics and ANSI, working together — lets the device on the other end of the cable also show pictures and drawings: a photo of a circuit board, a wiring diagram, a needle on a gauge, a blinking dot where an LED is.

It does this without a second cable or a special driver. Your device sends short bursts of special characters mixed in with its normal text, exactly the way it already sends the codes that make text turn red or the cursor jump to the top of the screen. FSterm notices those bursts and draws.

Who does what. The device (an Arduino, a Raspberry Pi Pico, a test fixture, a PC program) decides what to draw and sends the commands. FSterm just obeys. So if a picture lands in the wrong place, the fix is almost always in the device's program — not in a setting here.

Nothing about GrafANSI© gets in the way of ordinary use. If your device never sends GrafANSI© commands, FSterm behaves exactly like the plain terminal it has always been.

What it can do

  • Show PNG and JPEG pictures, anywhere on the screen, at any size.
  • Draw lines, rectangles, circles, ellipses, and two kinds of pointer.
  • Stack several of these, so a drawing sits on top of a photo.
  • Make one color see-through, so layers and text show through each other.
  • Zoom into part of a very large picture.
  • Remember pictures on disk so they do not have to be sent twice.

Plain ANSI vs. GrafANSI© — side by side

A plain ANSI terminal can already do more than people expect, and GrafANSI© does not replace any of it. This table shows where the line falls.

What you wantStandard ANSIWith GrafANSI©
Print text Yes — one character per cell. Unchanged. GrafANSI© never touches how text works.
Color text 16 colors, plus 24-bit truecolor. Unchanged, and text can additionally be made see-through.
Position something By whole row and column only. Down to a percentage of a cell, so artwork is not snapped to the grid.
Draw a box Only with box-drawing characters, so corners land on cell boundaries and the line thickness is whatever the font gives you. A real rectangle at any pixel position, any color, any border width.
Draw a circle, an ellipse, a diagonal line Not possible. Yes.
Show a photograph or a schematic Not possible. PNG and JPEG, at any size.
Put one thing on top of another Not possible — there is one grid, and writing a cell replaces it. Stacked layers with a controllable order.
Transparency Not possible. One color is treated as see-through (chroma key).
Show or hide part of the display instantly Redraw it, or clear and reprint. One short command hides or shows a whole layer.
Zoom into detail Not possible. Pan and zoom within a loaded picture, with nothing re-sent.
Keep a header still while content scrolls Yes — a scrolling region. Unchanged. Graphics simply do not participate in scrolling at all.
Full-screen program behavior Alternate screen, insert/delete lines, cursor reporting. Unchanged.
Make a sound One bell character — whatever sound the user has chosen. The device picks which .wav to play, from files you placed on the PC in advance.

What GrafANSI© does not do

Just as important, so you do not design around something that is not there:

Not availableDetail
Text inside a picture There is no “draw this word onto the image” command. Labels are ordinary terminal text placed on top — which is usually crisper anyway, since it is not scaled. If you need a label baked into artwork, put it there before sending the file.
Partial transparency A pixel is either fully visible or fully see-through. No fading, no soft shadows, no translucent overlays.
Rotation Pictures are placed square to the screen. Only the two pointer shapes rotate, and only to 8 fixed directions.
Free stretching You give a width; the height follows the picture's own proportions. A picture cannot be deliberately squashed.
Drawing directly on the screen Shapes are drawn into a picture or a blank canvas, which is then placed. There is no “draw a line across the screen” command — make a full-screen canvas instead.
Scrolling graphics Pictures sit at fixed positions. When text scrolls underneath, they stay put.
Mouse input Your device is never told about clicks. The mouse selects text for you, not for the device.
Video Animation is done by redrawing or by hiding and showing layers — effective for indicators and gauges, not for playback.
Sending sound A device can play a .wav, but only one you have already put in the media-repo folder — audio is never transferred over the cable. See Playing sounds.

The rest of this chapter explains the ideas you need to make sense of all that. The most important one — and the one that trips people up — is cells vs. pixels.

The grid and the glass

Picture the screen as two sheets, one behind the other.

The back sheet is the grid: rows and columns of equal-sized boxes called character cells. Every letter your device prints goes into exactly one cell. On an 80×25 screen there are 80 cells across and 25 down — 2,000 boxes, all the same size.

In front of it is the glass: one big clear sheet covering the whole screen. Pictures and drawings live on the glass. The glass does not care about the grid at all — something on the glass can sit halfway across a cell, or cover forty cells at once.

FSterm paints in three passes, back to front:

S T A T U S : O K 3. Text the characters, painted last so they sit on top of everything 2. The glass your pictures and drawings (this is where GrafANSI© works) 1. Backdrop plain black, painted first painted in this order
The screen seen edge-on. Lower layers are painted first, so higher layers cover them.

Two useful consequences fall straight out of that picture:

  • Text always wins. Because characters are painted last, a status line stays readable even if a photo is sitting underneath it.
  • Graphics do not disturb text. Drawing a picture never moves the cursor, never scrolls the screen, and never overwrites a character. The two live on different sheets.
The glass is not really one sheet — it is a stack of them, and your device decides the order. That is z-order. And “text wins” has a deliberate escape hatch, so artwork can show through the text when you want it to — that is chroma key.

Cells vs. pixels — the important one

GrafANSI© uses two different ways of measuring, and mixing them up is the single most common source of confusion. Here is the rule in one line:

Outside a picture you count in cells (rows and columns). Inside a picture you count in pixels (x and y).
OUTSIDE — the grid: rows & columns whole boxes; column across, row down 1 2 3 4 5 6 7 8 column → 1 2 3 4 5 row ↓ A row 3, column 5 one whole box Row 1, column 1 is the TOP-LEFT box. Counting starts at 1. INSIDE — a picture: x & y single dots; x across, y down 0,0 x → y ↓ x=110, y=70 The corner of the PICTURE is 0,0 — not the corner of the screen. Counting starts at 0. A pixel is one tiny dot of color.
Two rulers, two jobs. Where a picture goes is measured in cells; what is drawn on it is measured in pixels.

Why two systems?

Because they answer different questions.

  • “Where on the screen?” is answered in cells, so a picture can line up with your text. If you print a label in row 4 and put a picture at row 5, they line up — on any screen, at any window size, because the cell is the unit text already uses.
  • “Where in the artwork?” is answered in pixels, because that is what a photo is made of. A dot 110 pixels in from the left edge of a photo stays in the same spot on that photo no matter where on screen the photo ends up, or how big it is drawn.

Half-cells: fractions

Whole cells are a coarse ruler — the grid is only 80 boxes wide. So every cell measurement comes in two parts: the cell number, and a percentage from 0 to 99 saying how far into that cell to go.

column 5, fraction 0    →  exactly at the left edge of column 5
column 5, fraction 50   →  halfway across column 5
column 5, fraction 75   →  three-quarters of the way across column 5

Rows work the same way. This lets a picture sit anywhere, while still being anchored to the text grid.

Size is measured in cells too

A picture's width is given in columns (also with a fraction). Its height is then worked out automatically so the picture keeps its correct shape and does not look stretched.

So “20 columns wide” means the picture spans 20 character cells no matter whether it is a 100-pixel thumbnail or a 6000-pixel schematic. FSterm scales it to fit.

The trap to avoid

A program written for 80 columns will draw in the wrong place on a 132-column screen if it has the number 80 buried in it. The picture typically slides off to the left. This is not a fault in FSterm — the device is using a ruler that no longer matches the screen. The cure is for the device to ask the terminal how big it is at startup, or to set the size it wants (see Terminal size), and to work out its positions from that answer.

Layers & z-order

The glass is really a stack of sheets. Each picture or drawing lives in its own numbered slot, and slots are painted one after another. Whatever is painted later covers whatever was painted earlier — exactly like laying photographs on a table.

That front-to-back ordering is called z-order.

slot 0 — the photo placed 1st slot 1 — the drawing placed 2nd — covers slot 0 slot 2 — the pointer placed 3rd — on top of all back front — toward you
Later placements sit in front. Re-placing a slot moves it to the front of the stack.

The rules are short:

  • Order of placement decides the stacking, not the slot number. Slot 7 placed before slot 2 ends up behind slot 2.
  • Placing a slot again moves it to the front. This is how a device brings a highlight or a warning banner forward.
  • Drawing into a slot does not change its position in the stack. You can update the dots on an overlay every tenth of a second and it stays exactly where it was.

The pattern almost everyone wants

Put a photo underneath and a clear drawing sheet on top. The photo never changes; the drawing sheet gets erased and redrawn as often as you like.

slot 0   the photo of the circuit board      ← sent once, then left alone
slot 1   a blank see-through sheet, same size  ← erased and redrawn constantly

A test fixture uses this to simulate LEDs: the board photo sits in slot 0, and slot 1 gets a filled circle drawn over each LED position — green when the real LED is on, dark when it is off. Because only the thin top sheet is redrawn, the blinking is fast and the photo never has to be sent again.

Showing and hiding a layer

A layer can be taken out of the picture and put back without disturbing anything else:

ESC [ = slot;0 S      hide that one layer
ESC [ = slot;1 S      show it again
ESC [ = 0 S           hide ALL layers
ESC [ = 1 S           show ALL layers

Hiding is not the same as deleting. A hidden layer keeps everything:

Kept when hiddenWhy it matters
Its picture, fully decodedNothing is re-sent over the cable.
Anything drawn on itYour shapes are still there when it comes back.
Its position and sizeIt reappears exactly where it was.
Its place in the stackIt comes back at the same depth, not on top.

That last one is the important difference from re-placing a layer. A place command always moves a layer to the front of the stack; show and hide never do. So you can flick a middle layer on and off all day and the stack stays exactly as you built it.

Because nothing has to be re-loaded or re-scaled, showing a hidden layer is effectively instant — fast enough to flash a whole layer as an alarm indicator.

Building a scene in secret

There is a catch when you assemble something complicated: normally a layer appears the moment it is placed. Build a five-layer scene and the viewer watches it being assembled, piece by piece.

Staging mode fixes that. Turn it on, and layers you place are put in position but stay invisible until you say otherwise.

ESC [ = 1 H           staging ON  — placed layers stay hidden
ESC [ = 0 H           staging OFF — back to normal
Built in secret (staging mode ON) scene 1 scene 3 scene 2 loaded, drawn, positioned — but not shown ESC[=2;1 S one short command On screen, instantly scene 2, complete — no assembly seen
Whole scenes can be prepared off-stage, then flipped into existence with one short command.

Example — a three-screen “slide deck”, prepared once

ESC [ = 1 H                    go dark — nothing placed from here on will show

…load the photo for screen 1, place it, draw its overlay…
…load screen 2, place it, draw on it…
…load screen 3, place it, draw on it…       still nothing on screen

ESC [ = 0 H                    staging off
ESC [ = 3;1 S                  screen 1 appears, complete

Afterwards, switching screens costs almost nothing

ESC [ = 0 S   ESC [ = 5;1 S     hide everything, show screen 2

Send those two together in a single burst. FSterm redraws the whole stack once per batch of received data, so a hide and a show that arrive together produce one clean change of picture. Sent far enough apart, you may catch a blank screen in between.

If nothing appears at all, staging mode was probably left switched on. Send ESC [ = 0 H to go back to normal placement, or show the layers you want with S. Staging mode also switches itself off when the graphics state is reset.
Placing is always visible outside staging mode. If staging is off, a place command shows the layer — even one that was hidden a moment ago. This is deliberate: it means a stray hide can never leave a layer stuck invisible with no way to tell why.

See-through color (chroma key)

Computer pictures are rectangles. But you rarely want to see a rectangle — you want a circle over a photo, with the photo showing around it.

GrafANSI© solves this the same way a TV weather forecast does. The weather presenter stands in front of a bright green wall; the studio computer is told “green means see-through,” and replaces every green dot with the map. GrafANSI© picks one color and calls it the transparent key. Wherever that exact color appears, nothing is drawn — whatever is behind shows through.

The default key is bright magenta (red 255, green 0, blue 255), a color almost nothing uses by accident. Your device can change it.

The drawing sheet magenta background + a yellow circle over What is behind a photo of the board = What you see the magenta vanished; only the circle remains
Magenta is the “invisible” color. Everywhere it appears, the layer behind shows through.

Where you meet it

  • A blank drawing sheet starts out completely filled with the key color, which is why a fresh sheet is invisible until you draw on it.
  • Erasing part of a sheet means painting the key color back over it — that is how the old LED dot disappears before the new one is drawn.
  • Text can be see-through too. A character whose background is set to the key color shows the artwork behind it instead of a colored box, so a label can be written straight over a photo. Set the character's foreground to the key color instead and the letter shape itself disappears, leaving only its background — a trick for punching a colored block into a line of text.
The one gotcha: if a photo happens to contain that exact shade of magenta, those dots will be see-through too, leaving speckled holes. It is rare, but if you see it, have the device pick a different key color — any color the artwork does not use.

Sending pictures

How the commands look

Every GrafANSI© command is a short run of characters starting with the Escape character — byte 27, written here as ESC. You never type these; your device sends them. They are shown in this guide so you can recognize them in a capture file or check what your firmware is doing.

ESC [ = numbers separated by semicolons letter

The = is what marks a command as GrafANSI© rather than ordinary ANSI, and the final letter says what to do. For example D means “display,” C means “circle.” Picture data itself is bulkier and travels in a slightly different wrapper, but the idea is the same.

These sequences are documented in full, with every parameter, in GrafANSI_spec.md — the companion document for people writing device firmware. This chapter explains the concepts; the spec is the exact reference.

Slots

FSterm holds pictures in numbered slots. A slot is just a labeled shelf: your device says “put this photo in slot 0,” and afterwards refers to it as slot 0 forever. Slots let a device send a picture once and then move, resize, redraw, or hide it many times without sending the picture again.

Getting a picture in

There are three ways, from slowest to fastest:

WayWhat happensSpeed
Send it over the cable The device transmits the whole PNG or JPEG file, in pieces, as text. Slow the first time — a big photo on a slow link takes a while.
Reuse a cached copy The device asks “do you already have this one?” and if FSterm does, nothing is sent. Fast.
Load from the repo folder The device names a file you put on the PC yourself; nothing travels over the cable at all. Fastest.

All three are covered in Media cache & media repo.

Formats

  • PNG — best for diagrams, screenshots, and anything with sharp edges or flat color. Also the only one of the two that supports see-through areas.
  • JPEG — best for photographs. Much smaller than PNG for a photo, which matters a great deal when it has to crawl down a serial cable.
Rule of thumb for firmware authors: photo → JPEG; drawing → PNG. A 640×480 photo saved as PNG can easily be five times bigger than the same photo as JPEG, which is five times the transfer time.

Placing it

Sending a picture does not display it. It goes into a slot, and a separate place command says where and how big. That separation is deliberate — it is what lets a device slide a picture around, or swap which of several loaded pictures is showing, instantly.

Example — display slot 3, 20 columns wide, near the top-left

ESC [ = 3;2;0;5;0;20;0 D

Reading that: slot 3, at row 2 (fraction 0), column 5 (fraction 0), 20 columns wide (fraction 0). The height follows automatically from the picture's shape.

A blank sheet to draw on

You do not need a picture file at all. A device can ask for an empty see-through sheet of any pixel size, then draw on it. That is the top layer in the photo + overlay pattern.

Example — make slot 1 a blank 640×480 sheet

ESC [ = 1;640;480 I

How fast is it?

Picture data has to be turned into plain text to survive a terminal link, which makes it about a third bigger than the file on disk. Add that to a serial link's speed and you get the real answer:

LinkEffective rateA 60 KB JPEG (≈80 KB encoded) takes roughly
9,600 baud serial~960 B/sabout 1 minute 25 seconds
115,200 baud serial~11 KB/sabout 7 seconds
921,600 baud serial~92 KB/sabout 1 second
USB (virtual COM port)megabytes/sa fraction of a second
LAN — Wi-Fi (54 Mbit typical)~2–5 MB/sunder 50 ms
LAN — 100 Mbit Ethernet~11 MB/sabout 10 ms
LAN — gigabit or localhost>100 MB/sabout 1 ms
The LAN figures are wire time only, worked out from the link rate rather than measured on your network. Latency, other traffic, and how your device chunks its output can all add to them — but the conclusion holds: on a LAN the transfer essentially stops mattering.

That changes where the time goes. On a serial link, the cable is the bottleneck and the media cache is what saves you. Over LAN the cable is free, and what remains is decoding — turning the encoded text back into bytes, and those bytes into pixels. For a large picture that can easily outweigh the transfer.

FSterm handles that second bottleneck separately: decoded pictures are kept in memory, keyed by identity, so re-showing one is a pixel copy with no decode at all. See Media cache & media repo.

This is exactly why the cache and the repo exist — so you pay that cost once, or never.

Media cache & media repo

These are two folders that make pictures appear faster. They sound similar and do different jobs, so here is the difference in one line each:

  • media-cache — FSterm fills this in automatically. It is a memory of pictures your device has already sent, so it never has to send them twice.
  • media-repo — you fill this in yourself. It is a library of pictures — and sounds — your device can call up by name, which never travel over the cable at all. This is what the “media” in the name is for: the folder is not limited to images.
Your device (Pico, Arduino…) cable (slow) FSterm decodes & draws the picture media-cache folder FSterm saves a copy here, by itself media-repo folder YOU copy your own files here board.jpg, schematics\sheet1.png … the device only sends the NAME — 20 bytes, instant Automatic. You never touch this folder. Yours. Put anything you like in it.
Two routes to the same picture. The cache saves a repeat trip; the repo skips the trip entirely.

Where the folders are

FSterm creates both folders the first time it runs, so there is nothing to set up. They sit next to FSterm.exe:

…\FSterm.exe
…\media-cache\
…\media-repo\

If that folder cannot be written to — for example FSterm is on a read-only network share or in Program Files — the folders are created in your personal app-data area instead:

C:\Users\<you>\AppData\Local\FSterm\media-cache\
C:\Users\<you>\AppData\Local\FSterm\media-repo\

The media-cache, in detail

Before sending a picture, a well-written device first offers it: “I am about to send a picture. Here is its size and a short fingerprint of its contents. Do you already have it?” FSterm looks in the cache folder and answers yes or no.

  • No → the device sends the picture, and FSterm saves a copy for next time.
  • Yes → the device sends nothing at all. FSterm loads its own copy.

The “fingerprint” is a checksum — a number calculated from every byte of the file. Two different pictures essentially never produce the same one, so a cached file can be trusted to be the picture that was asked for. Cache files are named after that fingerprint and the file's length, which is why they look like this:

FS_8A3F19C2_L61440.jpg

Nothing needs to be done with those names — they are for FSterm's bookkeeping.

What you should expect to see. The first time your device shows a picture, it takes as long as the cable allows. Every time after that — including after you close and reopen FSterm, or reboot the PC — it should be dramatically faster, because nothing is being transmitted.

Clear media cache on the GrafANSI menu deletes the lot. Do that if you are short on disk space, or if you have edited a picture on the device and want to be certain you are seeing the new one.

The media-repo, in detail

The repo is yours. Copy PNG and JPEG files into it — and .wav files, if you want your device to be able to play sounds — using whatever names and subfolders you like. A device then asks for one by name:

board.jpg
schematics\power-supply.png
rev-c\top-side.jpg

Because the file is already on the PC, there is no transfer at all — the picture appears as fast as the PC can read and decode it. This is the right choice for anything big: full-size schematics, high-resolution board photos, reference drawings.

It also means you can change the artwork without touching the firmware. Drop a new board.jpg into the folder and the device shows the new one next time it asks.

Names are the contract. Subfolders are entirely your choice — FSterm creates none and expects none — but the device asks for files by name, so whatever structure you pick, the firmware has to use the same one. Replacing a file's contents needs no firmware change; renaming or moving it does.

If a repo file is missing

Rather than showing nothing — which looks identical to a crash — FSterm draws a placeholder rectangle in the spot where the picture should have been, and tells the device the file was not found. If you see an empty outlined box, check the spelling of the filename and that the file really is in media-repo.

Safety: the repo is a sealed box

A device can only read files inside media-repo. Names are checked before anything is opened, and any attempt to climb out of the folder — a ..\, a drive letter, a network path, an absolute path — is rejected outright. A misbehaving or badly written device therefore cannot be used to read your documents. Names are always relative to the repo folder, so plain board.jpg is correct; there is never any need for a .\ in front.

Turning them off

Both are on by default and both can be unticked on the GrafANSI menu.

  • Untick Enable media-cache and nothing is written to or read from the cache folder; every picture is sent over the cable every time. Useful when you are actively changing a picture and want to be sure you are seeing the latest.
  • Untick Enable media-repo and requests for repo files are refused. Useful if you would rather no attached device could read files from the PC at all.

Playing sounds

A device can ask FSterm to play a sound file — a specific alarm, a spoken warning, a distinctive tone per failure type. This is separate from the bell, which is one fixed sound the user chooses; here the device chooses.

The rule: the file must already be on the PC

A device can only name a sound, never send one. The file has to be sitting in your media-repo folder already. There is no transfer path for audio at all — nothing arrives over the cable, and nothing is ever written to the media cache.

That is a deliberate limit. It means an attached device can play only the sounds you chose to put there, and the same sealed-box protection that covers pictures covers sounds: any attempt to name a file outside the folder is rejected before anything is opened.

Setting it up

  1. Copy your .wav files into media-repo.
  2. Make sure GrafANSI → Enable device sounds is ticked (it is by default).
  3. Have the device name the file without the .wav.
media-repo\
    alarm.wav
    test-passed.wav
    board.jpg

What the device sends

ESC _ G i=1 , op=play , path=alarm ; ESC \             plays alarm.wav
ESC _ G i=1 , op=stop ; ESC \                          stop whatever is playing
ESC _ G i=1 , op=play , path=alarm , loop=1 ; ESC \    repeat until stopped
Subfolders are optional. Sounds and pictures can sit loose in media-repo, or you can organize them into subfolders however you like — audio\, rev-c\, whatever suits you. FSterm does not create or expect any particular subfolder. Whatever you choose, the device has to know it: the name it sends must match your folder and file names exactly, so if you reorganize the folder, the firmware has to be updated to match.
ESC _ G i=1 , op=play , path=audio\siren ; ESC \       only if you made an audio\ folder

The extension is left off because a sound is always a .wav — there is nothing to choose, so there is nothing to send. (A device that sends alarm.wav anyway still works; the extra extension is ignored rather than doubled.)

Playback does not hold anything up — the terminal keeps receiving and drawing while a sound plays. Asking for a new sound replaces the one currently playing.

Looping — and how to stop it

Adding loop=1 makes the sound repeat until something stops it — useful for a continuous alarm that should keep going until the fault is cleared. Leave it off (or send loop=0) and the sound plays once, which is the default.

You are never stuck with a looping sound. A device that starts a loop and then crashes, wedges, or gets unplugged cannot leave it playing — FSterm gives you several ways out, and stops the sound by itself when the link goes away.
Way to stop itWho does it
op=stopThe device.
GrafANSI© → Stop soundYou, from the menu.
Ctrl+Shift+SYou, from the keyboard.
Disconnect — or the cable being pulledAutomatic.
Unticking Enable device soundsYou.

The shortcut uses Shift for the same reason Copy does: plain Ctrl+S belongs to the device, as the traditional “pause output” control byte.

Turning it off

Untick GrafANSI → Enable device sounds and requests are refused; anything playing at that moment stops immediately. Sounds are also refused when Enable media-repo is unticked, because playing a file is reading one from that folder — switching the repo off means no attached device reads anything from your PC, sounds included.

If it does not play

FSterm tells the device exactly what went wrong, so a well-written firmware can report it. The codes are listed under the command summary. In practice:

SymptomUsual cause
Nothing happens, no errorEnable device sounds or Enable media-repo is unticked.
Device reports “not found”Check the spelling, and that the file really is in media-repo. Remember the device sends the name without .wav.
Device reports “rejected”The name tried to leave the folder — a ..\, a drive letter, or a network path.
Device reports “unplayable”The file is not a real WAVE file, or is truncated. Try playing it in Windows first.
Only .wav is supported — no MP3, no OGG. WAVE files are played by Windows itself, with no extra software. Convert other formats first; for short alerts the size difference does not matter, and the file never travels over the cable anyway.

Drawing shapes

Anything in a slot can be drawn on — a photo you sent, a file from the repo, or a blank see-through sheet. Drawing happens in the picture's own pixels (see cells vs. pixels), and it is permanent: the shape becomes part of that slot's artwork until it is erased or the slot is reused.

Two colors are in play

Before drawing, a device sets up to two colors, which then apply to every shape until changed:

ColorUsed forSet withTurn off
StrokeLines and outlines. ESC [ = r;g;b RESC [ = R
FillThe inside of a shape. ESC [ = r;g;b FESC [ = F

Turning one off is how you get a hollow shape (no fill) or a solid shape with no outline (no stroke). Each color is given as three numbers 0–255 for red, green, and blue.

The shapes

ShapeCommandMeaning
LineESC [ = slot;x0;y0;x1;y1[;w] L From one point to another.
RectangleESC [ = slot;x;y;wide;high[;w] B Top-left corner, then size.
CircleESC [ = slot;cx;cy;r[;w] C Center, then radius.
EllipseESC [ = slot;cx;cy;rx;ry[;w] E Center, then the two radii.
EraseESC [ = slot;x;y;wide;high X Wipe a rectangle back to see-through. Leave off the size to wipe the whole sheet.

The [;w] at the end is the optional line width — see the next topic. Leave it out and lines are one pixel thick.

A complete worked example

This is the LED-simulator pattern from Layers, start to finish.

Once, at startup

ESC [ = 0;…board.jpg from the repo…          load the photo into slot 0
ESC [ = 1;800;600 I                        slot 1 = a blank see-through sheet
ESC [ = 0;1;0;1;0;40;0 D                   place the photo,  40 columns wide
ESC [ = 1;1;0;1;0;40;0 D                   place the sheet on top, same spot

Every time an LED changes

ESC [ = 1;300;180;40;40 X                  erase the old dot
ESC [ = 0;255;0 F                          fill = bright green
ESC [ = 1;320;200;14 C                     filled circle where the LED is

Notice that only the second block repeats. The photo is loaded once and never touched again, which is what makes this fast enough to animate.

Things worth knowing

  • Anything off the edge is cropped, cleanly. A shape half outside its sheet shows the half that fits; it never wraps around or crashes.
  • Shapes scale with the picture. They are drawn into the artwork at its own resolution and then the whole thing is scaled to the screen. Draw on a small sheet and blow it up, and your lines look chunky — so if you want crisp overlay graphics, ask for a larger blank sheet than you think you need.
  • Colors are fixed at the moment you draw. Changing the stroke color afterwards does not recolor shapes already drawn; erase and draw again.

Pointers & line width

Line width

Every line and outline can be made thicker by adding one more number to the command. Leave it out and you get the old behavior — one pixel — so nothing that already worked changes.

Which way the extra thickness grows depends on what you are drawing, and the difference matters:

A line — grows BOTH ways the path you asked for half above half below Centred on the path. Good — a wire or pointer line stays where you drew it. An outline — grows INWARD only outer edge never moves The box keeps the exact size you gave it, however thick the border gets.
Lines thicken evenly about their path. Closed outlines — rectangles, circles, ellipses, pointers — thicken inward, so the shape never grows.

The inward rule is there so a highlight box stays put. A rectangle drawn at a certain size occupies exactly that space whether its border is 1 pixel or 12, so you can thicken a callout without it creeping over the artwork next to it, and without doing any arithmetic to compensate.

Example — a thin box and a heavy box, same size

ESC [ = 1;100;100;200;120 B        1-pixel border (width left out)
ESC [ = 1;100;100;200;120;8 B      8-pixel border — identical outer edge

If you ask for a width bigger than the shape itself, the shape simply fills in solid.

Pointers

Two ready-made shapes for the very common job of saying “this one, right here” on a photo or a diagram:

  • Arrow — a mouse-cursor style pointer. Command letter M.
  • Hand — a pointing finger. Command letter N.

You give the spot to point at, how big to draw it, and which of eight directions it faces:

ESC [ = slot;x;y;size;direction[;width] M
The 8 directions 0 N 1 NE 2 E 3 SE 4 S 5 SW 6 W 7 NW x,y is the TIP dir 3 = SE dir 1 = NE the spot — both tips land here Change direction and the tip does not move. Same x,y — no arithmetic needed.
Directions run clockwise from North = 0. The point you give is the pointer's tip, which is what it rotates around.

Anchoring on the tip is the whole trick. To label a test point from whichever side happens to have room, you send the same spot every time and only change the direction number — there is no table of offsets to work out for each direction.

Pointers use the same stroke and fill colors as every other shape, which gives three looks:

Colors setResult
Both fill and strokeA solid pointer with an outline — most readable over a busy photo.
Stroke only (fill off)A hollow outline; the artwork shows through.
Fill only (stroke off)A plain silhouette.

Example — a yellow arrow with a dark outline, pointing at a component

ESC [ = 40;40;40 R                 outline: near-black
ESC [ = 255;230;0 F                fill: yellow
ESC [ = 1;412;188;56;3;2 M         arrow, tip at (412,188), 56 px long,
                                   direction 3 = SE, 2-pixel outline
Choosing between them: the hand needs to be reasonably large — about 40 pixels or more — before the fingers are recognizable. Below that, use the arrow, which stays clear at any size.

Zooming into a big picture

Some pictures are far bigger than the screen. A full-size D-sheet schematic scanned at normal quality can be six thousand pixels wide — hundreds of times more detail than the terminal can show at once.

GrafANSI© handles this with a viewport: a rectangle that selects which part of the picture to show. Everything outside it is ignored, and the selected part is scaled up to fill whatever space you placed the picture in.

Shrink the viewport and you zoom in. That is all there is to it.

The picture, at its own size 6600 × 10200 px — a D-size schematic the V rectangle 900 × 700 px Everything outside the rectangle is ignored. scaled up to fill the placed area On the terminal 70 columns wide — about 4× magnified now readable
The viewport picks a region of the full-size picture; that region is scaled to fill the space the picture was placed in. Nothing is re-sent — only the rectangle changes.
ESC [ = slot;x;y;wide;high V     show only this part of the picture
ESC [ = slot V                          go back to showing the whole thing

Example — whole schematic, then zoom to the power supply

ESC [ = 2 V                        the whole sheet — a bird's-eye view
ESC [ = 2;1;0;1;0;70;0 D           placed 70 columns wide

ESC [ = 2;3300;1200;900;700 V      just that region of the original
ESC [ = 2;1;0;1;0;70;0 D           same 70 columns — now about 4x magnified
Nothing is re-sent. The picture stays where it is in memory; only the “which part” rectangle changes. Panning and zooming around a big drawing is therefore instant, even over a slow serial link.

Two practical notes:

  • Zooming out very far is not magic — a schematic reduced to fit 70 character cells will show the shape of the drawing but not the text on it. That is the point of a bird's-eye view: get your bearings, then zoom in to read.
  • Very large pictures are best kept in the media-repo folder rather than sent over the cable, for obvious reasons.

The GrafANSI menu

Three items, all optional — the defaults are what most people want.

ItemDefaultWhat it does
Enable media-cacheticked Lets FSterm remember pictures on disk so repeat displays are near-instant. Untick while you are editing a picture and want to be certain you are seeing the newest version.
Enable media-repoticked Lets a device display picture files from the media-repo folder. Untick if you would rather no attached device could read any file from the PC.
Clear media cache— Deletes every remembered picture — done at once, without a prompt (it is harmless), with the count noted on the status bar. Frees disk space; the next display of each picture is slow again.

Both tick boxes are remembered in FSterm.ini.

The cache tick box is the master switch for all picture remembering — the folder on disk and the copies FSterm keeps in memory. Turn it off and every picture, including repo files, is re-read and re-decoded each time it is used.

Keyboard

While the terminal has focus and the port is connected, keys are translated to bytes and sent:

KeySent
Printable charactersThe character (char mode) or buffered (line mode).
EnterThe selected EOL Mode (CR, LF, CRLF, or <none> in LAN mode) — in line mode it follows the buffered line.
Backspace / Tab / Esc\b / \t / ESC (0x1B).
Ctrl+A … Ctrl+ZControl codes 0x01–0x1A (e.g. Ctrl+C = 0x03).
Arrows / Home / EndANSI cursor sequences (ESC [ A/B/C/D/H/F).

Shortcuts handled by FSterm (not sent to the device)

KeyAction
Ctrl+Shift+CCopy the selected text to the Windows clipboard.
Ctrl+Shift+ASelect the whole visible screen.
Ctrl+Shift+SStop any device-triggered sound, including a looping one. See Playing sounds.
F11Toggle Slim GUI mode — the canvas-only view. Works from anywhere in the window, connected or not.

These use Shift so that plain Ctrl+C keeps its terminal meaning — sending the interrupt byte 0x03 to stop a running program on the device. See Selecting & copying text.

ANSI / VT100 support

In ANSI display mode FSterm interprets a practical subset of VT100/ANSI escapes:

  • SGR colors & attributes — 16 foreground/background colors (30–37, 90–97, 40–47, 100–107), bold, underline, reverse, and reset.
  • Cursor movement — up/down/left/right (A B C D), absolute position (H/f), save/restore (s/u and ESC 7/ESC 8).
  • Erase — in display (J), in line (K), and erase-characters (X).
  • Cursor show/hide — ESC[?25h / ESC[?25l.
  • DEC line-drawing — ESC(0 selects the box-drawing G0 set; ESC(B returns to ASCII.
  • Full reset — ESC c.

Added in v1.2.0

  • Scrolling region — ESC[top;bottomr, so a header or status line can stay still while the middle of the screen scrolls. With it come index / next-line / reverse-index (ESC D, ESC E, ESC M) and scroll up / down.
  • Insert and delete — lines (L, M) and characters (@, P).
  • Alternate screen buffer — ESC[?1049h / l, so a full-screen program can take over and then give your previous output back.
  • Adjustable tab stops — ESC H, ESC[0g, ESC[3g, and tab-forward / tab-backward. The default is still every 8 columns.
  • Autowrap and origin mode — ESC[?7h/l and ESC[?6h/l.
  • Cursor position reporting — ESC[6n answers ESC[row;colR; ESC[5n answers ESC[0n.
  • More text attributes — faint, italic, blink, and strikethrough (SGR 2, 3, 5, 9), each with its own off-switch.
  • Window-title sequences (OSC) are now consumed properly instead of spilling their text onto the screen.
  • Truecolor text — ESC[38;2;r;g;bm for foreground and ESC[48;2;r;g;bm for background give any 24-bit color, not just the 16 palette entries. The 256-color forms (ESC[38;5;nm / ESC[48;5;nm) are accepted too. ESC[39m and ESC[49m return to the palette defaults.
  • Device Attributes — ESC[c is answered with ESC[?62;4;9001c. The 9001 is how a device detects that this terminal speaks GrafANSI©; a terminal that does not simply omits it.
  • Window size — ESC[8;rows;colst sets the screen size to any of the four supported geometries. See Terminal size.
  • Erase honors the background color — erasing to the end of a line or the screen now paints the currently selected background color, as a real VT does, rather than always painting black.
  • GrafANSI© graphics — a private command space marked by ESC[=, plus a bulk data channel for picture bytes. Fully described in the Graphics chapter and, at the byte level, in GrafANSI_spec.md.
FSterm implements the escapes most device firmware uses for menus and status displays. It is not a full DEC VT terminal — advanced/rare sequences are ignored rather than printed.

ANSI command summary

Everything FSterm understands that is not part of the GrafANSI© extension — the ordinary terminal control a device uses for menus, status screens, and colored text. These work in ANSI display mode.

Notation

Both this section and the GrafANSI© summary use the same conventions. Read them the way you would a C function prototype:

SymbolMeans
<name>A required numeric parameter you supply.
[ ... ]Optional — may be omitted entirely.
a | bAlternative forms; use one or the other.
...The preceding item may repeat.
ESCThe Escape character, byte 27 (0x1B).
STString Terminator, written ESC \ (two bytes).

Spaces in the synopses are for readability only — send no spaces. Parameters are decimal ASCII digits separated by semicolons. An omitted parameter takes its default. Sequences FSterm does not implement are swallowed, not printed, so an unsupported escape leaves no garbage on the screen.

Complete sequence index

Every escape sequence in one table. The Class column says where each one comes from and whether FSterm acts on it:

  • ANSI — standard ANSI / VT, supported.
  • ANSI — no — standard ANSI / VT that FSterm does not implement. Consumed silently; never printed as stray characters.
  • GrafANSI© — the graphics extension. Detailed in the GrafANSI© command summary.
SequenceName ClassNotes
Control characters
0x07BELANSIRings the bell — sound, glyph, or nothing per Terminal → Bell.
0x08BS — backspaceANSICursor left one column; does not erase.
0x09HT — tabANSITo the next tab stop; never wraps.
0x0ALF — line feedANSIScrolls at the bottom margin.
0x0DCR — carriage returnANSITo column 1.
0x7FDELANSIIgnored.
ESC-level sequences
ESC cRIS — full resetANSIDoes not disturb graphics; use ESC[=Z for that.
ESC 7DECSC — save cursorANSISame store as ESC[s.
ESC 8DECRC — restore cursorANSI
ESC DIND — indexANSIDown one line, scrolling at the margin.
ESC ENEL — next lineANSICR + index.
ESC MRI — reverse indexANSIUp one line, scrolling down at the top margin.
ESC HHTS — set tab stopANSIAt the current column.
ESC ( 0SCS — DEC line drawingANSIG0 charset.
ESC ( BSCS — US-ASCIIANSIThe default.
ESC ] <ps> ; <text> BEL|STOSC — window titleANSIConsumed; ps 0/1/2 recorded but not displayed.
ESC _ G … STAPC — bulk dataGrafANSI©Image transfer, media-repo load, sound play/stop.
ESC # 8DECALN — alignment testANSI — no
ESC = / ESC >DECKPAM / DECKPNMANSI — noKeypad application mode.
ESC P … STDCS — incl. SixelANSI — noGrafANSI© is FSterm's graphics answer.
Cursor movement (CSI)
ESC [ <n> ACUU — cursor upANSIStops at the top margin.
ESC [ <n> BCUD — cursor downANSIStops at the bottom margin.
ESC [ <n> CCUF — cursor forwardANSI
ESC [ <n> DCUB — cursor backANSI
ESC [ <r> ; <c> HCUP — cursor positionANSIRegion-relative while origin mode is on.
ESC [ <r> ; <c> fHVPANSIIdentical to H.
ESC [ <n> ICHT — forward tabANSI
ESC [ <n> ZCBT — back tabANSI
ESC [ sSCP — save cursorANSI
ESC [ uRCP — restore cursorANSI
ESC [ <n> GCHA — absolute columnANSI — noUse CUP instead.
ESC [ <n> dVPA — absolute rowANSI — noUse CUP instead.
ESC [ <n> `HPAANSI — no
ESC [ <n> E / FCNL / CPLANSI — noNext / previous line, column 1.
Erasing and editing (CSI)
ESC [ <n> JED — erase in displayANSIPaints the current background.
ESC [ <n> KEL — erase in lineANSIPaints the current background.
ESC [ <n> XECH — erase charactersANSI
ESC [ <n> LIL — insert linesANSIInside the scrolling region only.
ESC [ <n> MDL — delete linesANSIInside the scrolling region only.
ESC [ <n> @ICH — insert charactersANSIRight-hand end is lost, never wrapped.
ESC [ <n> PDCH — delete charactersANSI
ESC [ <n> bREP — repeat characterANSI — no
Scrolling (CSI)
ESC [ <t> ; <b> rDECSTBM — scrolling regionANSINo parameters resets to full screen.
ESC [ <n> SSU — scroll upANSI
ESC [ <n> TSD — scroll downANSI
Tabs, attributes, status (CSI)
ESC [ <n> gTBC — clear tab stopANSI0 at cursor, 3 all.
ESC [ <p> … mSGR — attributes and colorANSI0 1 2 3 4 5 7 9, 22–29, 30–37, 39, 40–47, 49, 90–97, 100–107.
ESC [ 38;2;r;g;b mSGR — truecolor fgANSIAlso 48;2 for background.
ESC [ 38;5;n mSGR — xterm-256 fgANSIAlso 48;5.
SGR 8 / 21 / 53conceal / double underline / overlineANSI — noAccepted and ignored.
ESC [ 5 nDSR — status reportANSIAnswers ESC[0n.
ESC [ 6 nDSR — cursor positionANSIAnswers ESC[<r>;<c>R.
ESC [ cDA — device attributesANSIAnswers ESC[?62;4;9001c; 9001 = GrafANSI©.
ESC [ > cDA2 — secondary attributesANSI — noConsumed, no reply.
ESC [ 8 ; <r> ; <c> tXTWINOPS — set sizeANSI80×24, 80×25, 132×24, 132×25 only.
ESC [ ! pDECSTR — soft resetANSI — noUse ESC c.
Private modes (CSI ?)
ESC [ ? 25 h / lDECTCEM — cursor visibleANSI
ESC [ ? 7 h / lDECAWM — autowrapANSIOn by default.
ESC [ ? 6 h / lDECOM — origin modeANSIRow addressing relative to the region.
ESC [ ? 1049 h / lAlternate screen + cursorANSIWhat full-screen programs use.
ESC [ ? 1047 / 47 h / lAlternate screen (older forms)ANSI
ESC [ ? 1048 h / lSave / restore cursorANSI
ESC [ ? 1000/1002/1003/1006 hMouse reportingANSI — noThe mouse selects text for you, not the device.
ESC [ ? 2004 h / lBracketed pasteANSI — no
GrafANSI© — images and slots
ESC [ = nGeometry queryGrafANSI©Answers ESC[=<rows>;<cols>y.
ESC [ = cTertiary DAGrafANSI©Reserved; no reply.
ESC [ = <idx>;<w>;<h> IBlank canvasGrafANSI©See-through drawing sheet.
ESC [ = <idx> K  |  ESC [ = KFree slot / free allGrafANSI©
ESC [ = <idx>;…7 params… DPlace imageGrafANSI©Cell-centric anchor + width; raises to front.
ESC [ = <idx>;<sx>;<sy>;<sw>;<sh> VSource viewportGrafANSI©Pan / zoom; ESC[=<idx>V resets.
ESC [ = <state> SShow / hide all layersGrafANSI©Keeps z-order.
ESC [ = <idx>;<state> SShow / hide one layerGrafANSI©
ESC [ = <state> HStaging modeGrafANSI©Placements arrive hidden.
ESC [ = <grow>;… OGlobal offset (GOFF)GrafANSI©Live pan of every placed layer.
GrafANSI© — color and drawing
ESC [ = <r>;<g>;<b> RStroke colorGrafANSI©ESC[=R = none.
ESC [ = <r>;<g>;<b> FFill colorGrafANSI©ESC[=F = none.
ESC [ = <r>;<g>;<b> TTransparent keyGrafANSI©Default 255;0;255.
ESC [ = <idx>;…[;<lw>] LLineGrafANSI©Width grows both ways.
ESC [ = <idx>;…[;<lw>] BRectangleGrafANSI©Border grows inward.
ESC [ = <idx>;…[;<lw>] CCircleGrafANSI©Border grows inward.
ESC [ = <idx>;…[;<lw>] EEllipseGrafANSI©Border grows inward.
ESC [ = <idx>;…;<dir>[;<lw>] MArrow pointerGrafANSI©8 directions; x,y is the tip.
ESC [ = <idx>;…;<dir>[;<lw>] NHand pointerGrafANSI©8 directions; x,y is the tip.
ESC [ = <idx>;… XClear to keyGrafANSI©Region, or whole sheet with idx alone.
GrafANSI© — frame, state, replies
ESC [ = PPresent / flushGrafANSI©Accepted; compositing is already atomic.
ESC [ = ZReset graphics stateGrafANSI©Text grid untouched.
ESC [ = <rows> ; <cols> yGeometry reportGrafANSI©Terminal → host.
ESC [ = <type>;<idx>;<code> wAsset statusGrafANSI©Terminal → host. Types 1–5.
Anything not in this table is consumed and discarded. An unsupported escape never leaves stray characters on the screen, so a program written for a fuller terminal degrades quietly rather than making a mess.

1. Control characters

ByteNameEffect
0x07BELRings the bell — a sound, an on-screen bell icon, or nothing, per Terminal → Bell. Never printed. See The bell (BEL).
0x08BSCursor left one column. Stops at column 1; does not erase.
0x09TABTo the next tab stop (section 3). Never past the last column, and never onto the next line.
0x0ALFNext line, scrolling if already on the bottom margin.
0x0DCRTo column 1 of the current line.
0x7FDELIgnored.

Other bytes below 0x20 are ignored. Bytes 0x80–0xFF are CP437 characters — see section 9.

2. Cursor movement

ESC [ [ <n> ] A                    up    <n> rows      (default 1)
ESC [ [ <n> ] B                    down  <n> rows      (default 1)
ESC [ [ <n> ] C                    right <n> columns   (default 1)
ESC [ [ <n> ] D                    left  <n> columns   (default 1)

ESC [ [ <row> ] ; [ <col> ] H       go to row, column   (default 1;1)
ESC [ [ <row> ] ; [ <col> ] f       identical to H

ESC [ s     |  ESC 7                save cursor position
ESC [ u     |  ESC 8                restore cursor position

ESC D                              index         — down one line, scrolling if needed
ESC E                              next line     — carriage return + index
ESC M                              reverse index — up one line, scrolling if needed

Rows and columns count from 1 at the top-left. Movement is clamped to the screen — a cursor pushed past an edge stops there rather than wrapping. Up and down movement also stops at the scrolling margins (section 6) when the cursor starts inside them.

3. Tab stops

ESC H                              set a tab stop at the current column
ESC [ [ 0 ] g                      clear the tab stop at the current column
ESC [ 3 g                          clear ALL tab stops
ESC [ [ <n> ] I                    forward  <n> tab stops   (default 1)
ESC [ [ <n> ] Z                    backward <n> tab stops   (default 1)

Stops start out every 8 columns, which is what most software expects. They return to that default on a full reset and whenever the terminal size changes. A TAB with no stop left on the line parks the cursor on the last column.

4. Erasing

ESC [ [ <n> ] J                    erase in display     (default 0)
ESC [ [ <n> ] K                    erase in line        (default 0)
ESC [ [ <n> ] X                    erase <n> characters (default 1)
nJ — displayK — line
0Cursor to end of screen.Cursor to end of line.
1Start of screen to cursor.Start of line to cursor.
2The whole screen.The whole line.
Erasing paints the current background color, as a real VT does — not always black. Select a background with SGR before erasing and you get a colored panel in one step. The cursor does not move.

5. Inserting and deleting

ESC [ [ <n> ] L                    insert <n> blank lines at the cursor row
ESC [ [ <n> ] M                    delete <n> lines at the cursor row
ESC [ [ <n> ] @                    insert <n> blanks at the cursor
ESC [ [ <n> ] P                    delete <n> characters at the cursor

Line insert and delete work inside the scrolling region and leave the cursor at column 1; lines pushed past the bottom margin are lost. Character insert and delete shift the rest of the line and never wrap — characters pushed off the right edge are lost.

6. Scrolling region

ESC [ <top> ; <bottom> r           limit scrolling to these rows
ESC [ r                            back to the whole screen

ESC [ [ <n> ] S                    scroll the region up   <n> lines
ESC [ [ <n> ] T                    scroll the region down <n> lines

A scrolling region is how you keep a header or a status line still while the middle of the screen scrolls. Rows outside the region are never moved by a line feed.

Setting a region moves the cursor to the top-left. The region must be at least two rows; an impossible request is ignored rather than half-applied.

Example — a fixed title row and a fixed status row

ESC [ 1;1H  TEMPERATURE LOG           title on row 1
ESC [ 25;1H STATUS: RUNNING           status on row 25
ESC [ 2;24r                           scroll only rows 2..24
ESC [ 2;1H                            park the cursor in the region
...now just print lines; the title and status stay put...

7. Colors and attributes — SGR

ESC [ <p> [ ; <p> ]... m           set graphic rendition
ESC [ m                            same as ESC [ 0 m

Several parameters may be combined in one sequence, applied left to right.

OnOffEffect
0—Reset everything to default.
122Bold.
222Faint — drawn halfway between the foreground and background.
323Italic.
424Underline.
525Blink, about twice a second.
727Reverse video.
929Strikethrough.
ParameterEffect
30–37Foreground, the 8 normal colors.
90–97Foreground, the 8 bright colors.
40–47Background, the 8 normal colors.
100–107Background, the 8 bright colors.
39 / 49Foreground / background back to default.

The color order for the 8 base colors is black, red, green, yellow, blue, magenta, cyan, white. Which actual shades appear depends on the Palette setting.

ESC [ 38 ; 2 ; <r> ; <g> ; <b> m    foreground, 24-bit truecolor
ESC [ 48 ; 2 ; <r> ; <g> ; <b> m    background, 24-bit truecolor
ESC [ 38 ; 5 ; <n> m               foreground, xterm-256 index
ESC [ 48 ; 5 ; <n> m               background, xterm-256 index

Components are 0–255; the 256-color index is 0–255. Setting any ordinary indexed color afterwards cancels the truecolor override on that channel.

8. Modes

ESC [ ? 25 h   |  ESC [ ? 25 l      show   | hide the cursor
ESC [ ? 7 h    |  ESC [ ? 7 l       autowrap on | off
ESC [ ? 6 h    |  ESC [ ? 6 l       origin mode on | off
ESC [ ? 1049 h |  ESC [ ? 1049 l    alternate screen on | off
ESC [ ? 1047 h |  ESC [ ? 47 h      older alternate-screen forms
ESC [ ? 1048 h |  ESC [ ? 1048 l    save | restore the cursor position
ModeWhat it does
AutowrapOn (the default), a character typed in the last column moves the cursor to the start of the next line. Off, the cursor stays and further characters overwrite the last column — useful when you are filling a line exactly and do not want an accidental scroll.
Origin modeMakes H address rows relative to the scrolling region, so “row 1” means the first row of the region rather than of the screen.
Alternate screenSwitches to a blank scratch screen, keeping the original. Switching back restores it exactly. This is what full-screen programs use so your previous output reappears when they exit. 1049 also saves and restores the cursor position.

9. Character set — CP437

FSterm is a byte-oriented, extended-ASCII terminal. Bytes 0x20–0x7E are ordinary ASCII, and bytes 0x80–0xFF are the CP437 character set — the original IBM PC set, with box-drawing lines, block and shading characters, arrows, and Greek letters.

This is a deliberate choice, not a missing feature. CP437 gives an embedded device a complete set of framing and bar-graph characters at one byte per character, with no multi-byte encoder needed in the firmware and no question about how many columns a character occupies.

FSterm does not decode UTF-8. Send UTF-8 text and each byte is drawn as its own CP437 glyph, producing the familiar garbled result. Send CP437 byte values directly instead.

ESC ( 0                            G0 = DEC line-drawing set
ESC ( B                            G0 = US-ASCII (the default)

The DEC line-drawing set is a second way to get box characters: while it is selected, the ASCII range _ to ~ maps to box-drawing glyphs. It exists for compatibility with older software — for new firmware, CP437 bytes are simpler.

CP437 characters take colors exactly like ASCII ones. Every printable byte — 0x20–0x7E and 0x80–0xFF alike — is drawn in whatever foreground and background were last selected, from the 16-color set, the 256-color set, or truecolor. So a red alarm frame or a green bar graph works the way you would expect.

Example — a red double-line frame in CP437

ESC [ 31 m          red
0xC9 0xCD 0xCD 0xCD 0xBB      ╔═══╗
0xBA 0x20 0x20 0x20 0xBA      ║   ║
0xC8 0xCD 0xCD 0xCD 0xBC      ╚═══╝

10. Reset, query, and status

ESC c                              full reset

ESC [ c
        → ESC [ ? 62 ; 4 ; 9001 c       reply; 9001 = GrafANSI© supported

ESC [ 5 n   → ESC [ 0 n            "are you there?" — always answered OK
ESC [ 6 n   → ESC [ <row> ; <col> R   report the cursor position

ESC [ 8 ; <rows> ; <cols> t         set the terminal size

ESC c clears the screen, homes the cursor, restores default colors, resets tab stops and the scrolling region, makes the cursor visible, and returns G0 to ASCII. It does not disturb loaded graphics — use ESC [ = Z for that.

Only 80×24, 80×25, 132×24 and 132×25 are accepted by t; other sizes are ignored. Asking for the size you already have is an accepted no-op and does not clear the screen.

Replies arrive on the same channel as your typing. Firmware that asks for the cursor position must expect the answer to turn up mixed in with ordinary keyboard input.

11. Window title (OSC)

ESC ] 0 ; <text> BEL               set icon name and window title
ESC ] 2 ; <text> BEL               set window title
ESC ] <ps> ; <text> ESC \          ST-terminated form of the same thing

FSterm records the title but does not currently display it — the window caption shows the connection state instead. The important part is that the sequence is fully consumed, so an OSC from a program that assumes a desktop terminal never spills its text onto your screen.

12. Not implemented

FSterm covers what device firmware actually uses. These are silently discarded — they will not appear as stray characters, but they will not do anything either:

SequenceWould have been
ESC [ ? 1000 h familyMouse reporting to the device.
ESC [ ? 2004 hBracketed paste.
ESC [ <n> bRepeat the previous character.
ESC [ > cSecondary device attributes.
Sixel, ReGISOther terminal graphics protocols — GrafANSI© is FSterm's answer here.
UTF-8Out of scope by design — see section 9.

GrafANSI© command summary

Every GrafANSI© sequence, in one place, for people writing device firmware. These are the graphics extension; the ordinary terminal control is in the ANSI command summary above. The byte-level reference with full rationale is GrafANSI_spec.md.

The same notation applies. All GrafANSI© commands are ignored silently if a required parameter is missing, so a malformed sequence never corrupts the screen.

1. Detection and geometry

ESC [ c
        → ESC [ ? 62 ; 4 ; 9001 c            reply; 9001 = GrafANSI© supported

ESC [ = n
        → ESC [ = <rows> ; <cols> y            reply; current geometry

ESC [ 8 ; <rows> ; <cols> t                    set geometry

ESC [ = c                                    reserved (no reply)
ParameterRange
rows, cols Only 80×24, 80×25, 132×24, 132×25 are accepted; anything else is ignored.

2. Image transfer — the bulk channel

Picture bytes travel in an APC string rather than a CSI, because they are far too big for parameters. The general form is:

ESC _ G <key>=<value> [ , <key>=<value> ]... ; <base64-data> ST
KeyValueUsed for
islot numberRequired on every form.
m1 = more chunks follow, 0 = last chunkData transfer.
nchunk sequence numberEchoed back in the chunk ACK.
fpng | jpegFirst chunk. Advisory — the real format is auto-detected.
w, hpixel dimensionsFirst chunk, optional hint.
crcCRC-32 of the whole fileOffer only.
lenfile length in bytesOffer only.
opoff | use | repo | play | stopSelects a non-transfer operation.
pathname relative to media-repoop=repo (with extension) and op=play (without).
loop1 = repeat until stopped, 0 = onceop=play only. Default 0.

The four operations, written out:

ESC _ G i=<idx> , f=<fmt> [ , w=<w> ] [ , h=<h> ] , m=1 [ , n=<seq> ] ; <base64> ST
ESC _ G i=<idx> , m=1 , n=<seq> ; <base64> ST          middle chunks
ESC _ G i=<idx> , m=0 [ , n=<seq> ] ; <base64> ST      final chunk → decode

ESC _ G i=<idx> , op=off , crc=<crc32> , len=<bytes> [ , f=<fmt> ] ; ST
        → ESC [ = 2 ; <idx> ; 0 w      not cached — send it
        → ESC [ = 2 ; <idx> ; 1 w      already cached — send op=use instead

ESC _ G i=<idx> , op=use ; ST                          load the cached copy

ESC _ G i=<idx> , op=repo , path=<name> ; ST           load from media-repo

ESC _ G i=<idx> , op=play , path=<name> [ , loop=1 ] ; ST   play <name>.wav from media-repo
ESC _ G i=<idx> , op=stop ; ST                             stop playback

op=play takes the name without the .wav — audio is always a WAVE file, so the extension carries no information. i= identifies nothing here; it is echoed back in the reply so you can match it to your request. Audio is never transferred — the file must already be in the folder. See Playing sounds.

The path is sandboxed. It is always relative to the media-repo folder, so board.jpg or schematics\sheet1.png are correct. A leading .\ is unnecessary, and anything that tries to leave the folder — ..\, a drive letter, a UNC path — is rejected.

3. Slots and placement

ESC [ = <idx> ; <w> ; <h> I                   blank see-through canvas, w x h pixels

ESC [ = <idx> K | ESC [ = K                   free one slot | free all slots

ESC [ = <idx> ; <row> ; <rfrac> ; <col> ; <cfrac> ; <wcols> ; <wfrac> D

ESC [ = <idx> ; <sx> ; <sy> ; <sw> ; <sh> V | ESC [ = <idx> V

ESC [ = <grow> ; <grfrac> ; <gcol> ; <gcfrac> O
ParameterMeaning
idxSlot number. Any non-negative integer.
row, colCell position, counting from 1 at the top-left.
rfrac, cfracPercentage 0–99 further into that cell.
wcols, wfracWidth in cells plus a 0–99 fraction. Height follows from the aspect ratio.
sx, sy, sw, shViewport rectangle in the picture's own pixels; clamped to the picture.
grow…gcfracGlobal offset. Neutral is (rows, 0, cols, 0); resets to neutral on a geometry change.

D also accepts a 9-parameter form with an explicit height. The two extra parameters are currently accepted and ignored — placement is aspect-preserving. Re-placing a slot removes its old entry and appends, so it moves to the front of the stack and becomes visible.

4. Color state

ESC [ = <r> ; <g> ; <b> R | ESC [ = R          stroke color | stroke off
ESC [ = <r> ; <g> ; <b> F | ESC [ = F          fill color   | fill off
ESC [ = <r> ; <g> ; <b> T                       transparent key (default 255;0;255)

Components are 0–255. These are state: they persist until changed and apply to every shape drawn afterwards. Text color uses standard SGR, not these:

ESC [ 38 ; 2 ; <r> ; <g> ; <b> m              text foreground, 24-bit
ESC [ 48 ; 2 ; <r> ; <g> ; <b> m              text background, 24-bit
ESC [ 38 ; 5 ; <n> m | ESC [ 48 ; 5 ; <n> m    xterm-256 index
ESC [ 39 m | ESC [ 49 m                       back to palette default

5. Drawing primitives

ESC [ = <idx> ; <x0> ; <y0> ; <x1> ; <y1> [ ; <lw> ] L        line
ESC [ = <idx> ; <x> ; <y> ; <w> ; <h> [ ; <lw> ] B            rectangle
ESC [ = <idx> ; <cx> ; <cy> ; <r> [ ; <lw> ] C               circle
ESC [ = <idx> ; <cx> ; <cy> ; <rx> ; <ry> [ ; <lw> ] E       ellipse
ESC [ = <idx> ; <x> ; <y> ; <size> ; <dir> [ ; <lw> ] M      arrow pointer
ESC [ = <idx> ; <x> ; <y> ; <size> ; <dir> [ ; <lw> ] N      hand pointer
ESC [ = <idx> ; <x> ; <y> ; <w> ; <h> X | ESC [ = <idx> X     clear to key
ParameterMeaning
all coordinatesThe target picture's own pixels, 0,0 at its top-left.
lwLine width. Omitted, 0, or negative all mean 1. Clamped to 256. Grows both ways on L; inward only on B C E M N, so the outer edge never moves. A width exceeding the shape fills it.
sizePointer length along its axis. The hand needs roughly 40 or more to be legible.
dir0=N 1=NE 2=E 3=SE 4=S 5=SW 6=W 7=NW. Masked to 3 bits, so 8 wraps to 0.
x, y (M, N)The pointer's tip — also the point it rotates about.

L uses stroke only. B C E M N fill first, then stroke, so turning one off with ESC[=R or ESC[=F gives an outline-only or fill-only shape. Everything is clipped to the picture's bounds.

6. Layer visibility

ESC [ = <0|1> S                               hide | show ALL layers
ESC [ = <idx> ; <0|1> S                       hide | show one layer
ESC [ = <0|1> H                               staging mode off | on

The two S forms are told apart by parameter count: one parameter is global, two is per-layer. Hiding preserves the layer's picture, its artwork, its position, and its depth in the stack — unlike D, which raises a layer to the front. While staging mode is on, D places layers hidden, so a scene can be assembled off-screen.

A bare ESC[=S or ESC[=H with no parameter is ignored, so a truncated sequence cannot blank the screen.

7. Frame and state

ESC [ = P                                     present / flush (accepted, no-op)
ESC [ = Z                                     reset all GrafANSI© state

Z clears the display list, frees all slots and in-flight transfers, and restores stroke, fill, key color, staging mode, and the global offset to their defaults. The text grid is not touched. The in-memory decoded-picture cache deliberately survives, so reloads stay fast.

8. Replies from the terminal

All replies are asynchronous — they arrive on the same channel as your keystrokes, so a firmware reader must be prepared to see them mixed into normal input.

ESC [ ? 62 ; 4 ; 9001 c                       device attributes
ESC [ = <rows> ; <cols> y                     geometry report
ESC [ = <type> ; <idx> ; <code> w             asset status
TypeMeaningCodes
1Repo request result 0 loaded · 1 not found or unreadable · 2 path rejected · 3 could not decode · 4 media-repo disabled
2Offer response 0 not cached, send it · 1 already cached, send op=use
3Chunk acknowledged The chunk's n= sequence number. Sent only for offered transfers — use it to throttle on slow links.
4Transfer or cache-load result 0 loaded · 1 CRC or length mismatch · 2 could not decode · 3 cache load failed
5Sound result (op=play / op=stop) 0 playing or stopped · 1 not found · 2 path rejected · 3 found but unplayable · 4 media-repo disabled · 5 device sounds disabled

On any type 1 failure the slot still receives a visible placeholder rectangle, so a missing asset shows as an outlined box rather than as nothing at all.

9. Limits

LimitValue
Base64 payload per transfer32 MB
Decoded picture size64 megapixels
On-screen scaled size16 megapixels — a wildly oversized placement is skipped, not drawn
In-memory decoded cache1 GB, least-recently-used eviction
Line width256
Color components0–255
Cell fractions0–99

Settings file

Preferences are stored in a small FSterm.ini kept next to FSterm.exe, so the app is fully portable. Missing keys fall back to defaults; a read-only folder simply means each session starts at defaults.

SectionKeys
[last]port — last-used serial port.
[network]mode (serial/lan), host, port, proto (TCP/UDP) — LAN-mode target.
[window]geom — window size/position (WxH+X+Y).
[legal]accepted_disclaimer_version — the end-user disclaimer version you have accepted (see below).
[terminal]baud, framing, palette, display_mode, input_mode, line_terminator, local_echo, auto_scroll, capture_hex, play_char_delay_ms, play_eol_delay_ms, play_eol, rts, dtr (output-line state), geometry — screen size, one of 80x24, 80x25, 132x24, 132x25; cursor_style — block / outline / double; cursor_blink (true/false); bell_mode — off / ding / wav / visual; bell_wav — the chosen sound file.
[grafansi]media_cache, media_repo, sounds — the three tick boxes on the GrafANSI menu (true/false).
[background]image — wallpaper file path (empty = none); fit — stretch / aspect / center; opacity — 0–100. See Background image.
[screenshot]folder, basename, autonumber (true/false), format (png/jpg), withbg, withglass. See Screenshots.

Folders created next to the executable

On first run FSterm also creates two folders for graphics. They are described in Media cache & media repo.

FolderContents
media-cache\Managed automatically by FSterm. Safe to delete at any time, or empty it from GrafANSI → Clear media cache.
media-repo\Yours. Put PNG and JPEG files here for devices to display by name. Subfolders are allowed.

If the folder holding FSterm.exe is read-only, both are created under %LOCALAPPDATA%\FSterm\ instead.

Troubleshooting

  • Port not listed — plug in the USB cable and click Refresh; install the bridge chip's driver if Windows shows no COM port.
  • Connect fails — another program (or a second FSterm window) may hold the port; close it and try again.
  • Garbage characters — the baud rate or framing doesn't match the device; correct them (the port reopens automatically).
  • Every character is doubled — turn Echo off; the device is already echoing.
  • You type but nothing happens — click the terminal to focus it, and confirm you are connected; in line mode input is sent only on Enter.
  • "Help file not found" — keep FSterm_Help.html next to FSterm.exe, or in the FSTerm_Documents folder.

Terminal size

  • The Terminal menu is grayed out — you are connected. Disconnect first; the size cannot change while a session is live. See Terminal size.
  • Your device's output wraps in the wrong place — the device and the terminal disagree about the width. Set the size the device expects, or have the device ask.

Graphics (GrafANSI©)

  • No pictures at all, just stray characters on screen — the Display mode is set to ASCII or HEX. GrafANSI© only renders in ANSI mode.
  • Graphics appear shifted off to the left — the device is assuming 80 columns while the screen is set to 132 (or the reverse). The device's program has the width built into it instead of asking. See Cells vs. pixels.
  • Nothing appears, even though the device says it placed a picture — staging mode is switched on, so placed layers are being held invisible. Send ESC[=0 H, or show them with ESC[=1 S. See Building a scene in secret.
  • A layer jumps in front of the others when it comes back — it is being re-placed rather than shown. Use ESC[=slot;1 S, which keeps its depth; a place command always raises a layer to the top.
  • A brief blank flash when switching screens — the hide and show commands are arriving in separate bursts. Send them in one write.
  • An empty outlined box where a picture should be — a repo file was not found. Check the spelling, and that the file really is in media-repo. Check too that Enable media-repo is ticked.
  • Pictures are slow every single time — Enable media-cache is unticked, or the device is not using the offer handshake and simply re-sends the picture each time. Large pictures belong in media-repo.
  • An edited picture still shows the old version — the cached copy is being used. Run GrafANSI → Clear media cache.
  • Speckled see-through holes in a photo — the photo contains the exact magenta used as the transparent key. Have the device choose a different key color. See See-through color.
  • A drawing looks chunky or jagged — it was drawn on a small sheet and then scaled up. Ask for a larger blank sheet. See Drawing shapes.
  • Text is invisible over a picture — the character's colors match the transparent key, which makes them see-through by design. Pick different text colors.

Sound

  • No ding when the device sends BEL — check Terminal → Bell is not set to Off, and that the PC's volume is up. In Visual only mode there is no sound by design.
  • The chosen bell .wav stopped playing — the file was moved or deleted, so FSterm fell back to the system ding. Pick it again from Terminal → Bell → Sound file….
  • A device-triggered sound does nothing — GrafANSI → Enable device sounds or Enable media-repo is unticked. Both must be on.
  • A device-triggered sound is not found — the file must be in media-repo, and the device names it without the .wav. See Playing sounds.
  • A sound keeps repeating — the device started it with loop=1. Press Ctrl+Shift+S, or use GrafANSI© → Stop sound. Disconnecting also stops it.
  • Bells sound sluggish during a flood — deliberate. Bells are capped at about five a second so a burst cannot machine-gun the speakers.

Text and characters

  • Accented or non-English characters come out garbled — the device is sending UTF-8. FSterm is an extended-ASCII (CP437) terminal; send CP437 byte values instead. See Character set — CP437.
  • Box-drawing characters are the wrong color — check the SGR color is set before the characters are sent. CP437 characters take the current colors like any other; there is no special case for them.
  • A full-screen program looks wrong — most now work, but mouse reporting and bracketed paste are still unsupported, and anything expecting UTF-8 will not render correctly.

About

FSterm — a portable native-Windows serial terminal. For sales and support contact sales@funcionasystems.com or visit www.funcionasystems.com.

© Funciona Systems, 2026.