Reference tables for terminal character sets used by retro and modern hardware.
Appendix A: ASCII Hex Table
The complete 7-bit ASCII character set (0x00-0x7F). Control characters (0x00-0x1F) and DEL (0x7F) are non-printable.
Control Characters (0x00-0x1F)
| Hex | Dec | Name | Description |
| 0x00 | 0 | NUL | Null |
| 0x01 | 1 | SOH | Start of Heading |
| 0x02 | 2 | STX | Start of Text |
| 0x03 | 3 | ETX | End of Text |
| 0x04 | 4 | EOT | End of Transmission |
| 0x05 | 5 | ENQ | Enquiry |
| 0x06 | 6 | ACK | Acknowledge |
| 0x07 | 7 | BEL | Bell |
| 0x08 | 8 | BS | Backspace |
| 0x09 | 9 | HT | Horizontal Tab |
| 0x0A | 10 | LF | Line Feed |
| 0x0B | 11 | VT | Vertical Tab |
| 0x0C | 12 | FF | Form Feed |
| 0x0D | 13 | CR | Carriage Return |
| 0x0E | 14 | SO | Shift Out |
| 0x0F | 15 | SI | Shift In |
| 0x10 | 16 | DLE | Data Link Escape |
| 0x11 | 17 | DC1 | Device Control 1 (XON) |
| 0x12 | 18 | DC2 | Device Control 2 |
| 0x13 | 19 | DC3 | Device Control 3 (XOFF) |
| 0x14 | 20 | DC4 | Device Control 4 |
| 0x15 | 21 | NAK | Negative Acknowledge |
| 0x16 | 22 | SYN | Synchronous Idle |
| 0x17 | 23 | ETB | End of Trans. Block |
| 0x18 | 24 | CAN | Cancel |
| 0x19 | 25 | EM | End of Medium |
| 0x1A | 26 | SUB | Substitute |
| 0x1B | 27 | ESC | Escape |
| 0x1C | 28 | FS | File Separator |
| 0x1D | 29 | GS | Group Separator |
| 0x1E | 30 | RS | Record Separator |
| 0x1F | 31 | US | Unit Separator |
Printable Characters (0x20-0x7E)
| Hex | Dec | Char | Hex | Dec | Char | Hex | Dec | Char |
| 0x20 | 32 | (space) | 0x40 | 64 | @ | 0x60 | 96 | ` |
| 0x21 | 33 | ! | 0x41 | 65 | A | 0x61 | 97 | a |
| 0x22 | 34 | " | 0x42 | 66 | B | 0x62 | 98 | b |
| 0x23 | 35 | # | 0x43 | 67 | C | 0x63 | 99 | c |
| 0x24 | 36 | $ | 0x44 | 68 | D | 0x64 | 100 | d |
| 0x25 | 37 | % | 0x45 | 69 | E | 0x65 | 101 | e |
| 0x26 | 38 | & | 0x46 | 70 | F | 0x66 | 102 | f |
| 0x27 | 39 | ' | 0x47 | 71 | G | 0x67 | 103 | g |
| 0x28 | 40 | ( | 0x48 | 72 | H | 0x68 | 104 | h |
| 0x29 | 41 | ) | 0x49 | 73 | I | 0x69 | 105 | i |
| 0x2A | 42 | * | 0x4A | 74 | J | 0x6A | 106 | j |
| 0x2B | 43 | + | 0x4B | 75 | K | 0x6B | 107 | k |
| 0x2C | 44 | , | 0x4C | 76 | L | 0x6C | 108 | l |
| 0x2D | 45 | - | 0x4D | 77 | M | 0x6D | 109 | m |
| 0x2E | 46 | . | 0x4E | 78 | N | 0x6E | 110 | n |
| 0x2F | 47 | / | 0x4F | 79 | O | 0x6F | 111 | o |
| 0x30 | 48 | 0 | 0x50 | 80 | P | 0x70 | 112 | p |
| 0x31 | 49 | 1 | 0x51 | 81 | Q | 0x71 | 113 | q |
| 0x32 | 50 | 2 | 0x52 | 82 | R | 0x72 | 114 | r |
| 0x33 | 51 | 3 | 0x53 | 83 | S | 0x73 | 115 | s |
| 0x34 | 52 | 4 | 0x54 | 84 | T | 0x74 | 116 | t |
| 0x35 | 53 | 5 | 0x55 | 85 | U | 0x75 | 117 | u |
| 0x36 | 54 | 6 | 0x56 | 86 | V | 0x76 | 118 | v |
| 0x37 | 55 | 7 | 0x57 | 87 | W | 0x77 | 119 | w |
| 0x38 | 56 | 8 | 0x58 | 88 | X | 0x78 | 120 | x |
| 0x39 | 57 | 9 | 0x59 | 89 | Y | 0x79 | 121 | y |
| 0x3A | 58 | : | 0x5A | 90 | Z | 0x7A | 122 | z |
| 0x3B | 59 | ; | 0x5B | 91 | [ | 0x7B | 123 | { |
| 0x3C | 60 | < | 0x5C | 92 | \ | 0x7C | 124 | | |
| 0x3D | 61 | = | 0x5D | 93 | ] | 0x7D | 125 | } |
| 0x3E | 62 | > | 0x5E | 94 | ^ | 0x7E | 126 | ~ |
| 0x3F | 63 | ? | 0x5F | 95 | _ | 0x7F | 127 | DEL |
History
1963 — ASA X3.4.
ASCII (American Standard Code for Information Interchange) was published in
1963 by the American Standards Association's X3.4 committee, with significant
design contributions from Bob Bemer at IBM — widely
credited as "the father of ASCII" for proposing the escape character, the
backslash, and the case-toggle bit alignment. The committee was a
cross-vendor effort (Teletype, IBM, AT&T, Burroughs, RCA, and others) and
its task was to replace a patchwork of incompatible 5-bit teleprinter codes
(Baudot/ITA2), 6-bit military codes (FIELDATA), and IBM's own 6-bit BCDIC.
The first published version had only uppercase letters; lowercase was added
in the 1967 revision (USASCII), which is the table you see above.
The 7-bit choice.
Seven bits was a compromise: 6 bits couldn't fit upper- and lowercase plus
digits and punctuation, while 8 bits would have wasted a bit on serial
lines that already paid for a parity bit. The 8th bit (0x80-0xFF) was
originally a parity bit, which is why ASCII proper stops at 0x7F —
the upper half was reserved for transmission integrity, not characters.
This is also why so many later codepages (Latin-1, PETSCII, ATASCII) bolt
their additions onto 0x80-0xFF: that range was free real estate once
parity moved out of band.
Why DEL is at 0x7F.
DEL (delete) sits at 0x7F — all seven bits set — because on
paper tape you "deleted" a character by punching all seven holes through
it. There was no way to un-punch a hole, so the convention was to
over-punch the position to a known sentinel. 0x00 (NUL) and 0x7F (DEL)
are the two values that look "blank" on punched tape: NUL is no holes,
DEL is all holes.
Internationalization and the 1980s.
ISO 646 (first edition 1973) generalized ASCII as a national-variant
standard: countries could replace 12 specific positions (notably 0x23,
0x24, 0x40, 0x5B-0x5E, 0x60, 0x7B-0x7E) with their own letters. The
German variant (DIN 66003) put Ä at 0x5B (where [ is in ASCII) and
ä at 0x7B (where { is); the French variant (AFNOR NF Z 62-010) put
à at 0x40 (where @ is) and é at 0x7B (where { is); and so
on — which is why C source code from that era sometimes contains
alarming-looking accented characters in place of the punctuation the
language actually wanted. ISO 8859-1 (Latin-1, 1987) and finally
Unicode/UTF-8 (1992) ended the variant chaos by giving every script its
own codepoint.
Today.
ASCII is still the lingua franca: UTF-8 was deliberately designed so that
any 7-bit ASCII file is also a valid UTF-8 file with identical bytes.
Every modern text format — HTTP, email headers, JSON, source code
— is ASCII-compatible at the byte level. You're reading ASCII
right now.
Appendix B: ANSI Escape Sequences
ANSI escape sequences are used to control text formatting, colors, and cursor positioning on compatible terminals. All sequences begin with the escape character (0x1B) followed by a left bracket '[', known as the Control Sequence Introducer (CSI).
Sequence Format
The general format is: ESC [ <parameters> <command>
Where ESC is 0x1B (decimal 27), parameters are optional numbers separated by semicolons, and the command is a single letter.
Cursor Control
| Sequence | Name | Description |
| ESC[H | CUP | Cursor Home - Move cursor to row 1, column 1 |
| ESC[n;mH | CUP | Cursor Position - Move cursor to row n, column m |
| ESC[n;mf | HVP | Horizontal Vertical Position - Same as CUP |
| ESC[nA | CUU | Cursor Up - Move cursor up n rows (default 1) |
| ESC[nB | CUD | Cursor Down - Move cursor down n rows (default 1) |
| ESC[nC | CUF | Cursor Forward - Move cursor right n columns (default 1) |
| ESC[nD | CUB | Cursor Back - Move cursor left n columns (default 1) |
| ESC[nE | CNL | Cursor Next Line - Move to beginning of line n down |
| ESC[nF | CPL | Cursor Previous Line - Move to beginning of line n up |
| ESC[nG | CHA | Cursor Horizontal Absolute - Move to column n |
| ESC[6n | DSR | Device Status Report - Reports cursor position as ESC[n;mR |
| ESC[s | SCP | Save Cursor Position |
| ESC[u | RCP | Restore Cursor Position |
| ESC 7 | DECSC | Save Cursor (DEC private) |
| ESC 8 | DECRC | Restore Cursor (DEC private) |
Erase Functions
| Sequence | Name | Description |
| ESC[J | ED | Erase Display - Clear from cursor to end of screen |
| ESC[0J | ED | Erase Display - Clear from cursor to end of screen |
| ESC[1J | ED | Erase Display - Clear from beginning of screen to cursor |
| ESC[2J | ED | Erase Display - Clear entire screen |
| ESC[3J | ED | Erase Display - Clear entire screen and scrollback buffer |
| ESC[K | EL | Erase Line - Clear from cursor to end of line |
| ESC[0K | EL | Erase Line - Clear from cursor to end of line |
| ESC[1K | EL | Erase Line - Clear from beginning of line to cursor |
| ESC[2K | EL | Erase Line - Clear entire line |
Text Attributes (SGR - Select Graphic Rendition)
Format: ESC[nm or ESC[n;n;...m for multiple attributes
| Code | Name | Description |
| 0 | Reset | Reset all attributes to default |
| 1 | Bold | Bold or increased intensity |
| 2 | Dim | Faint or decreased intensity |
| 3 | Italic | Italic (not widely supported) |
| 4 | Underline | Underlined text |
| 5 | Blink | Slow blink (less than 150 per minute) |
| 6 | Rapid Blink | Rapid blink (150+ per minute, rarely supported) |
| 7 | Reverse | Swap foreground and background colors |
| 8 | Hidden | Concealed/invisible text |
| 9 | Strikethrough | Crossed-out text |
| 21 | Double Underline | Double underlined (or bold off on some terminals) |
| 22 | Normal Intensity | Neither bold nor dim |
| 23 | Not Italic | Disable italic |
| 24 | Not Underlined | Disable underline |
| 25 | Not Blinking | Disable blink |
| 27 | Not Reversed | Disable reverse video |
| 28 | Reveal | Disable hidden |
| 29 | Not Strikethrough | Disable strikethrough |
Standard Foreground Colors (30-37)
| Code | Color | Code | Color (Bright/Bold) |
| 30 | Black | 90 | Bright Black (Gray) |
| 31 | Red | 91 | Bright Red |
| 32 | Green | 92 | Bright Green |
| 33 | Yellow | 93 | Bright Yellow |
| 34 | Blue | 94 | Bright Blue |
| 35 | Magenta | 95 | Bright Magenta |
| 36 | Cyan | 96 | Bright Cyan |
| 37 | White | 97 | Bright White |
| 39 | Default | | Reset to default foreground |
Standard Background Colors (40-47)
| Code | Color | Code | Color (Bright) |
| 40 | Black | 100 | Bright Black (Gray) |
| 41 | Red | 101 | Bright Red |
| 42 | Green | 102 | Bright Green |
| 43 | Yellow | 103 | Bright Yellow |
| 44 | Blue | 104 | Bright Blue |
| 45 | Magenta | 105 | Bright Magenta |
| 46 | Cyan | 106 | Bright Cyan |
| 47 | White | 107 | Bright White |
| 49 | Default | | Reset to default background |
256-Color Mode
Extended color support using 256-color palette:
| Sequence | Description |
| ESC[38;5;nm | Set foreground to color n (0-255) |
| ESC[48;5;nm | Set background to color n (0-255) |
Color ranges:
- 0-7: Standard colors (same as 30-37)
- 8-15: High-intensity colors (same as 90-97)
- 16-231: 216 colors (6x6x6 color cube)
- 232-255: Grayscale (24 shades from dark to light)
24-bit True Color Mode
| Sequence | Description |
| ESC[38;2;r;g;bm | Set foreground to RGB color (0-255 each) |
| ESC[48;2;r;g;bm | Set background to RGB color (0-255 each) |
Screen Modes
| Sequence | Description |
| ESC[?25h | Show cursor (DECTCEM) |
| ESC[?25l | Hide cursor (DECTCEM) |
| ESC[?47h | Save screen and switch to alternate buffer |
| ESC[?47l | Restore screen from alternate buffer |
| ESC[?1049h | Enable alternate screen buffer (saves cursor too) |
| ESC[?1049l | Disable alternate screen buffer (restores cursor) |
| ESC[?7h | Enable line wrapping |
| ESC[?7l | Disable line wrapping |
Scrolling
| Sequence | Description |
| ESC[nS | Scroll up n lines (default 1) |
| ESC[nT | Scroll down n lines (default 1) |
| ESC[t;br | Set scrolling region from line t to line b |
Line and Character Operations
| Sequence | Description |
| ESC[nL | Insert n blank lines at cursor position |
| ESC[nM | Delete n lines starting at cursor position |
| ESC[n@ | Insert n blank characters at cursor position |
| ESC[nP | Delete n characters at cursor position |
| ESC[nX | Erase n characters at cursor position |
Common Escape Sequences Quick Reference
| Sequence | Hex Bytes | Description |
| ESC[2J | 1B 5B 32 4A | Clear entire screen |
| ESC[H | 1B 5B 48 | Move cursor to home (1,1) |
| ESC[2J ESC[H | 1B 5B 32 4A 1B 5B 48 | Clear screen and home cursor |
| ESC[0m | 1B 5B 30 6D | Reset all attributes |
| ESC[1m | 1B 5B 31 6D | Bold on |
| ESC[31m | 1B 5B 33 31 6D | Red foreground |
| ESC[44m | 1B 5B 34 34 6D | Blue background |
| ESC[1;31m | 1B 5B 31 3B 33 31 6D | Bold red foreground |
| ESC[?25l | 1B 5B 3F 32 35 6C | Hide cursor |
| ESC[?25h | 1B 5B 3F 32 35 68 | Show cursor |
C0 Control Characters Used with ANSI
| Hex | Dec | Name | Description |
| 0x07 | 7 | BEL | Bell - Terminal bell/alert |
| 0x08 | 8 | BS | Backspace - Move cursor left one position |
| 0x09 | 9 | HT | Horizontal Tab - Move to next tab stop |
| 0x0A | 10 | LF | Line Feed - Move cursor down one line |
| 0x0B | 11 | VT | Vertical Tab - Move cursor down (treated as LF) |
| 0x0C | 12 | FF | Form Feed - Clear screen on some terminals |
| 0x0D | 13 | CR | Carriage Return - Move cursor to column 1 |
| 0x1B | 27 | ESC | Escape - Starts escape sequences |
Note: "ANSI escape codes" is colloquial. The actual standard is ECMA-48 (1976, fifth edition 1991) — later adopted as ISO/IEC 6429 and as the now-withdrawn ANSI X3.64. Support varies between emulators; the de-facto reference is the DEC VT100 family. Ethernet Gateway uses a subset for screen clearing (ESC[2J ESC[H), cursor positioning, and color output on ANSI terminals.
History
Pre-history: ASCII control codes weren't enough.
The 33 ASCII control codes (0x00-0x1F plus 0x7F) cover the basics
— CR, LF, BEL, BS, TAB — but they have no way to say
"move the cursor to row 5 column 12" or "draw the next word in
red." Early CRT terminals (the ADM-3A, the Hazeltine 1500, the
Lear-Siegler) each invented their own escape sequences, and none
of them agreed. Software either had to ship a termcap database
with hundreds of entries or be limited to the lowest common
denominator.
1976 — ECMA-48.
The European Computer Manufacturers Association published
ECMA-48: Control Functions for Coded Character Sets
in 1976 to standardize the soup. It defined the Control Sequence
Introducer (CSI = ESC [), the parameter format, the cursor-motion
command set, and Select Graphic Rendition (SGR) for text
attributes. ANSI adopted it as X3.64 in 1979,
and ISO as ISO/IEC 6429 in 1983. ANSI X3.64 was
withdrawn in 1997, but the "ANSI" name stuck because that's what
U.S. terminal manuals called it.
1978 — the DEC VT100.
Digital Equipment Corporation shipped the VT100, an early
microprocessor-based terminal that implemented an ANSI-conformant
subset (with some DEC-private extensions like DECSC/DECRC and the
scrolling region). The VT100 became so dominant that
"VT100-compatible" became the practical definition of an ANSI
terminal. Its successors — VT102, VT220, VT320, VT420
— layered on more features (8-bit codes, soft fonts,
sixel graphics) but stayed compatible. To this day, when you
tell ssh or screen your terminal type, you're probably saying
xterm or vt100.
The xterm era.
xterm was originally written at MIT in 1984 by Mark Vandevoorde
(initially for the VS100 stand-alone terminal) and then ported
to the X Window System by Jim Gettys, who maintained and
extended it for decades. It implemented VT102 emulation
faithfully and then kept adding features: 256-color mode
(1999, via the ESC[38;5;nm extension),
24-bit truecolor
(ESC[38;2;r;g;bm),
mouse reporting, bracketed paste, OSC 52 clipboard. Modern
terminals (iTerm2, Alacritty, kitty, Windows Terminal, GNOME
Terminal) all implement the xterm extension set, often with
their own additions. There is no committee shepherding this
anymore — the de facto standard is "what xterm does."
Today.
ANSI escape sequences run the modern terminal: every TUI tool
(vim, htop, tmux, fzf), every CI log with colored output, every
progress bar, every git diff. Windows finally added
native ANSI/VT support to its console host in Windows 10
(Threshold 2, late 2015), opt-in via the
ENABLE_VIRTUAL_TERMINAL_PROCESSING mode flag, ending
decades of having to ship an ANSI-to-Win32-Console translator
like ANSICON; the modern Windows Terminal app (2019) made it the
default. The single biggest practical limitation is still
which extensions a given terminal implements
— truecolor support, in particular, varies wildly across
SSH-into-tmux-into-screen chains.
Appendix C: PETSCII Hex Table
The Commodore 64 PETSCII character set. PETSCII differs from ASCII in several ways: control codes, graphics characters, and case handling (uppercase/lowercase are swapped compared to standard ASCII).
PETSCII Control Characters (0x00-0x1F)
| Hex | Dec | Name | Description |
| 0x00 | 0 | - | (Unused) |
| 0x01 | 1 | - | (Unused) |
| 0x02 | 2 | - | (Unused) |
| 0x03 | 3 | STOP | Run/Stop |
| 0x04 | 4 | - | (Unused) |
| 0x05 | 5 | WHT | White |
| 0x06 | 6 | - | (Unused) |
| 0x07 | 7 | BELL | Bell |
| 0x08 | 8 | DISH | Disable Shift+C= |
| 0x09 | 9 | ENSH | Enable Shift+C= |
| 0x0A | 10 | - | (Unused) |
| 0x0B | 11 | - | (Unused) |
| 0x0C | 12 | - | (Unused) |
| 0x0D | 13 | CR | Carriage Return |
| 0x0E | 14 | LOWR | Switch to Lowercase |
| 0x0F | 15 | - | (Unused) |
| 0x10 | 16 | - | (Unused) |
| 0x11 | 17 | DOWN | Cursor Down |
| 0x12 | 18 | RVON | Reverse On |
| 0x13 | 19 | HOME | Cursor Home |
| 0x14 | 20 | DEL | Delete (Backspace) |
| 0x15 | 21 | - | (Unused) |
| 0x16 | 22 | - | (Unused) |
| 0x17 | 23 | - | (Unused) |
| 0x18 | 24 | - | (Unused) |
| 0x19 | 25 | - | (Unused) |
| 0x1A | 26 | - | (Unused) |
| 0x1B | 27 | - | (Unused - no native ESC) |
| 0x1C | 28 | RED | Red |
| 0x1D | 29 | RIGHT | Cursor Right |
| 0x1E | 30 | GRN | Green |
| 0x1F | 31 | BLU | Blue |
PETSCII Printable Characters (0x20-0x3F)
| Hex | Dec | Char | Description |
| 0x20 | 32 | (space) | Space |
| 0x21 | 33 | ! | Exclamation Mark |
| 0x22 | 34 | " | Quotation Mark |
| 0x23 | 35 | # | Number Sign |
| 0x24 | 36 | $ | Dollar Sign |
| 0x25 | 37 | % | Percent Sign |
| 0x26 | 38 | & | Ampersand |
| 0x27 | 39 | ' | Apostrophe |
| 0x28 | 40 | ( | Left Parenthesis |
| 0x29 | 41 | ) | Right Parenthesis |
| 0x2A | 42 | * | Asterisk |
| 0x2B | 43 | + | Plus Sign |
| 0x2C | 44 | , | Comma |
| 0x2D | 45 | - | Hyphen-Minus |
| 0x2E | 46 | . | Full Stop |
| 0x2F | 47 | / | Solidus (Slash) |
| 0x30 | 48 | 0 | Digit Zero |
| 0x31 | 49 | 1 | Digit One |
| 0x32 | 50 | 2 | Digit Two |
| 0x33 | 51 | 3 | Digit Three |
| 0x34 | 52 | 4 | Digit Four |
| 0x35 | 53 | 5 | Digit Five |
| 0x36 | 54 | 6 | Digit Six |
| 0x37 | 55 | 7 | Digit Seven |
| 0x38 | 56 | 8 | Digit Eight |
| 0x39 | 57 | 9 | Digit Nine |
| 0x3A | 58 | : | Colon |
| 0x3B | 59 | ; | Semicolon |
| 0x3C | 60 | < | Less-Than Sign |
| 0x3D | 61 | = | Equals Sign |
| 0x3E | 62 | > | Greater-Than Sign |
| 0x3F | 63 | ? | Question Mark |
PETSCII Uppercase Letters (0x40-0x5F)
Note: In PETSCII uppercase mode, these are uppercase letters. In lowercase mode, these become graphics characters.
| Hex | Dec | Char | Description |
| 0x40 | 64 | @ | Commercial At |
| 0x41 | 65 | A | Latin Capital Letter A |
| 0x42 | 66 | B | Latin Capital Letter B |
| 0x43 | 67 | C | Latin Capital Letter C |
| 0x44 | 68 | D | Latin Capital Letter D |
| 0x45 | 69 | E | Latin Capital Letter E |
| 0x46 | 70 | F | Latin Capital Letter F |
| 0x47 | 71 | G | Latin Capital Letter G |
| 0x48 | 72 | H | Latin Capital Letter H |
| 0x49 | 73 | I | Latin Capital Letter I |
| 0x4A | 74 | J | Latin Capital Letter J |
| 0x4B | 75 | K | Latin Capital Letter K |
| 0x4C | 76 | L | Latin Capital Letter L |
| 0x4D | 77 | M | Latin Capital Letter M |
| 0x4E | 78 | N | Latin Capital Letter N |
| 0x4F | 79 | O | Latin Capital Letter O |
| 0x50 | 80 | P | Latin Capital Letter P |
| 0x51 | 81 | Q | Latin Capital Letter Q |
| 0x52 | 82 | R | Latin Capital Letter R |
| 0x53 | 83 | S | Latin Capital Letter S |
| 0x54 | 84 | T | Latin Capital Letter T |
| 0x55 | 85 | U | Latin Capital Letter U |
| 0x56 | 86 | V | Latin Capital Letter V |
| 0x57 | 87 | W | Latin Capital Letter W |
| 0x58 | 88 | X | Latin Capital Letter X |
| 0x59 | 89 | Y | Latin Capital Letter Y |
| 0x5A | 90 | Z | Latin Capital Letter Z |
| 0x5B | 91 | [ | Left Square Bracket |
| 0x5C | 92 | £ | Pound Sign |
| 0x5D | 93 | ] | Right Square Bracket |
| 0x5E | 94 | ↑ | Up Arrow |
| 0x5F | 95 | ← | Left Arrow (used as ESC equivalent) |
PETSCII Graphics/Lowercase (0x60-0x7F)
Note: In uppercase mode, these are graphics characters. In lowercase mode, 0x61-0x7A become lowercase letters.
| Hex | Dec | Upper Mode | Lower Mode |
| 0x60 | 96 | Horizontal Line | Horizontal Line |
| 0x61 | 97 | Spade | a |
| 0x62 | 98 | Vertical Line Left | b |
| 0x63 | 99 | Horizontal Line Bottom | c |
| 0x64 | 100 | Horizontal Line Top/Bottom | d |
| 0x65 | 101 | Horizontal Line Top | e |
| 0x66 | 102 | Vertical Line Right Top | f |
| 0x67 | 103 | Vertical Line Right Bottom | g |
| 0x68 | 104 | Vertical Line Left Bottom | h |
| 0x69 | 105 | Corner Round Right Bottom | i |
| 0x6A | 106 | Corner Round Right Top | j |
| 0x6B | 107 | Corner Round Left Top | k |
| 0x6C | 108 | Half Block Bottom Right | l |
| 0x6D | 109 | Corner Round Left Bottom | m |
| 0x6E | 110 | Half Block Upper Right | n |
| 0x6F | 111 | Half Block Lower Left | o |
| 0x70 | 112 | Half Block Lower Right | p |
| 0x71 | 113 | Circle | q |
| 0x72 | 114 | Half Block Upper Left | r |
| 0x73 | 115 | Heart | s |
| 0x74 | 116 | Vertical Line Left Top | t |
| 0x75 | 117 | Cross | u |
| 0x76 | 118 | Diamond | v |
| 0x77 | 119 | Cross | w |
| 0x78 | 120 | Vertical Line | x |
| 0x79 | 121 | Club | y |
| 0x7A | 122 | Vertical Line Right | z |
| 0x7B | 123 | Cross | Cross |
| 0x7C | 124 | Half Block Upper | Half Block Upper |
| 0x7D | 125 | Pi Symbol | Pi Symbol |
| 0x7E | 126 | Half Block Lower | Half Block Lower |
| 0x7F | 127 | Half Block Left | Half Block Left |
PETSCII High Control Characters (0x80-0x9F)
| Hex | Dec | Name | Description |
| 0x80 | 128 | - | (Unused) |
| 0x81 | 129 | ORG | Orange |
| 0x82 | 130 | - | (Unused) |
| 0x83 | 131 | - | (Unused) |
| 0x84 | 132 | - | (Unused) |
| 0x85 | 133 | F1 | Function Key 1 |
| 0x86 | 134 | F3 | Function Key 3 |
| 0x87 | 135 | F5 | Function Key 5 |
| 0x88 | 136 | F7 | Function Key 7 |
| 0x89 | 137 | F2 | Function Key 2 |
| 0x8A | 138 | F4 | Function Key 4 |
| 0x8B | 139 | F6 | Function Key 6 |
| 0x8C | 140 | F8 | Function Key 8 |
| 0x8D | 141 | SHRET | Shift+Return |
| 0x8E | 142 | UPPR | Switch to Uppercase |
| 0x8F | 143 | - | (Unused) |
| 0x90 | 144 | BLK | Black |
| 0x91 | 145 | UP | Cursor Up |
| 0x92 | 146 | RVOF | Reverse Off |
| 0x93 | 147 | CLR | Clear Screen |
| 0x94 | 148 | INST | Insert |
| 0x95 | 149 | BRN | Brown |
| 0x96 | 150 | LTRD | Light Red (Pink) |
| 0x97 | 151 | GRY1 | Dark Gray |
| 0x98 | 152 | GRY2 | Medium Gray |
| 0x99 | 153 | LTGR | Light Green |
| 0x9A | 154 | LTBL | Light Blue |
| 0x9B | 155 | GRY3 | Light Gray |
| 0x9C | 156 | PUR | Purple |
| 0x9D | 157 | LEFT | Cursor Left |
| 0x9E | 158 | YEL | Yellow |
| 0x9F | 159 | CYN | Cyan |
PETSCII Shifted Graphics (0xA0-0xBF)
| Hex | Dec | Description |
| 0xA0 | 160 | Shifted Space |
| 0xA1 | 161 | Vertical Bar Left |
| 0xA2 | 162 | Horizontal Bar Bottom |
| 0xA3 | 163 | Horizontal Bar Top |
| 0xA4 | 164 | Horizontal Bar |
| 0xA5 | 165 | Horizontal Bar Left |
| 0xA6 | 166 | Checkerboard |
| 0xA7 | 167 | Vertical Bar Right |
| 0xA8 | 168 | Vertical Bar Bottom |
| 0xA9 | 169 | Corner Lower Right |
| 0xAA | 170 | Corner Upper Right |
| 0xAB | 171 | Corner Upper Left |
| 0xAC | 172 | Quarter Block Lower Right |
| 0xAD | 173 | Corner Lower Left |
| 0xAE | 174 | Quarter Block Upper Right |
| 0xAF | 175 | Quarter Block Lower Left |
| 0xB0 | 176 | Quarter Block Lower Right |
| 0xB1 | 177 | Vertical Bar Left Bottom |
| 0xB2 | 178 | Quarter Block Upper Left |
| 0xB3 | 179 | Vertical Bar Top |
| 0xB4 | 180 | Vertical Bar Bottom |
| 0xB5 | 181 | T Junction Left |
| 0xB6 | 182 | Vertical Bar |
| 0xB7 | 183 | T Junction Top |
| 0xB8 | 184 | T Junction Bottom |
| 0xB9 | 185 | Half Block Right |
| 0xBA | 186 | T Junction Right |
| 0xBB | 187 | Cross Junction |
| 0xBC | 188 | Upper Half Block |
| 0xBD | 189 | Pi Symbol |
| 0xBE | 190 | Lower Half Block |
| 0xBF | 191 | Half Block Left |
PETSCII Shifted Letters/Graphics (0xC0-0xDF)
Note: In uppercase mode, these match 0x60-0x7F graphics. In lowercase mode, 0xC1-0xDA are uppercase letters.
| Hex | Dec | Upper Mode | Lower Mode |
| 0xC0 | 192 | Horizontal Line | Horizontal Line |
| 0xC1 | 193 | Spade | A |
| 0xC2 | 194 | Vertical Line Left | B |
| 0xC3 | 195 | Horizontal Line Bottom | C |
| 0xC4 | 196 | Line Horizontal | D |
| 0xC5 | 197 | Horizontal Line Top | E |
| 0xC6 | 198 | Vertical Line Right Top | F |
| 0xC7 | 199 | Vertical Line Right Bottom | G |
| 0xC8 | 200 | Vertical Line Left Bottom | H |
| 0xC9 | 201 | Corner Round Right Bottom | I |
| 0xCA | 202 | Corner Round Right Top | J |
| 0xCB | 203 | Corner Round Left Top | K |
| 0xCC | 204 | Half Block Bottom Right | L |
| 0xCD | 205 | Corner Round Left Bottom | M |
| 0xCE | 206 | Half Block Upper Right | N |
| 0xCF | 207 | Half Block Lower Left | O |
| 0xD0 | 208 | Half Block Lower Right | P |
| 0xD1 | 209 | Circle | Q |
| 0xD2 | 210 | Half Block Upper Left | R |
| 0xD3 | 211 | Heart | S |
| 0xD4 | 212 | Vertical Line Left Top | T |
| 0xD5 | 213 | Cross | U |
| 0xD6 | 214 | Diamond | V |
| 0xD7 | 215 | Cross | W |
| 0xD8 | 216 | Vertical Line | X |
| 0xD9 | 217 | Club | Y |
| 0xDA | 218 | Vertical Line Right | Z |
| 0xDB | 219 | Cross | Cross |
| 0xDC | 220 | Half Block Upper | Half Block Upper |
| 0xDD | 221 | Pi Symbol | Pi Symbol |
| 0xDE | 222 | Half Block Lower | Half Block Lower |
| 0xDF | 223 | Half Block Left | Half Block Left |
PETSCII High Graphics (0xE0-0xFF)
| Hex | Dec | Description |
| 0xE0 | 224 | Shifted Space |
| 0xE1 | 225 | Vertical Bar Left |
| 0xE2 | 226 | Horizontal Bar Bottom |
| 0xE3 | 227 | Horizontal Bar Top |
| 0xE4 | 228 | Horizontal Bar |
| 0xE5 | 229 | Horizontal Bar Left |
| 0xE6 | 230 | Checkerboard |
| 0xE7 | 231 | Vertical Bar Right |
| 0xE8 | 232 | Vertical Bar Bottom |
| 0xE9 | 233 | Corner Lower Right |
| 0xEA | 234 | Corner Upper Right |
| 0xEB | 235 | Corner Upper Left |
| 0xEC | 236 | Quarter Block Lower Right |
| 0xED | 237 | Corner Lower Left |
| 0xEE | 238 | Quarter Block Upper Right |
| 0xEF | 239 | Quarter Block Lower Left |
| 0xF0 | 240 | Quarter Block Lower Right |
| 0xF1 | 241 | Vertical Bar Left Bottom |
| 0xF2 | 242 | Quarter Block Upper Left |
| 0xF3 | 243 | Vertical Bar Top |
| 0xF4 | 244 | Vertical Bar Bottom |
| 0xF5 | 245 | T Junction Left |
| 0xF6 | 246 | Vertical Bar |
| 0xF7 | 247 | T Junction Top |
| 0xF8 | 248 | T Junction Bottom |
| 0xF9 | 249 | Half Block Right |
| 0xFA | 250 | T Junction Right |
| 0xFB | 251 | Cross Junction |
| 0xFC | 252 | Upper Half Block |
| 0xFD | 253 | Pi Symbol |
| 0xFE | 254 | Lower Half Block |
| 0xFF | 255 | Half Block Left |
Note: PETSCII has two character modes controlled by codes 0x0E (lowercase mode) and 0x8E (uppercase mode). In uppercase mode, codes 0x41-0x5A display uppercase letters and codes 0x61-0x7A display graphics. In lowercase mode, 0x41-0x5A display lowercase letters and 0x61-0x7A display uppercase letters. Ethernet Gateway swaps case in software for PETSCII output (see send() / send_line()) so the same uppercase-by-default logic works on a C64 in either character mode.
History
1977 — the Commodore PET.
PETSCII (PET Standard Code of Information Interchange) was
designed for the Commodore PET 2001, unveiled at the Winter
CES in January 1977 and shipped in volume that October —
making it, alongside the Apple II and the TRS-80, one of the
"1977 Trinity" of consumer personal computers. Commodore
engineer Chuck Peddle — who had led the
6502 CPU design at MOS Technology before Commodore acquired
the chipmaker — was the architect of the PET. PETSCII
was based on ASCII but extended with a full set of monochrome
block-graphics characters, chosen so that the PET could draw
boxes, charts, and simple game graphics without a separate
graphics chip.
The case-swap quirk.
PETSCII has two display modes selected by sending 0x8E (uppercase
mode, the boot default) or 0x0E (lowercase mode). In
uppercase mode, codes 0x41-0x5A render as A-Z (matching
ASCII visually) and codes 0x61-0x7A render as graphics characters.
In lowercase mode, the same bytes flip: 0x41-0x5A render
as lowercase a-z, and 0x61-0x7A render as
uppercase A-Z — effectively swapped from ASCII.
The net effect is that any ASCII text printed verbatim on a C64
in lowercase mode comes out CASE-INVERTED. Every BBS terminal,
every cross-platform tool, every emulator handles this differently.
Ethernet Gateway swaps case in software so a telnet user on a C64
sees the right thing without configuration.
The shared-platform legacy.
PETSCII outlived the PET. It carried over with minor
adjustments to the VIC-20 (1980), the Commodore 64 (1982,
which sold ~17 million units — the best-selling single
computer model in history), the C128 (1985), and the Plus/4
and C16 (1984). Color codes (0x05, 0x1C-0x1F, 0x81, 0x90-0x9F)
were added on color-capable models; the PET itself was
monochrome and ignored them.
Reverse-video and cursor codes inline.
Unlike ANSI, PETSCII doesn't use multi-byte escape sequences:
every effect is a single byte. 0x12 turns reverse video on,
0x92 turns it off; 0x11/0x91/0x1D/0x9D are cursor down/up/
right/left; 0x93 clears the screen; 0x0E/0x8E switch case mode.
This made it trivial to print formatted text from BASIC
(PRINT CHR$(147) = clear screen) but means
PETSCII files are not portable to ANSI terminals without
translation.
Still alive in the BBS scene.
PETSCII never died. The Commodore BBS scene of the 1980s is
still active: dozens of PETSCII boards run today on real
hardware (via WiFi modem cartridges like the WiFi Modem 232 and
the Userport Hub) or in emulators, dialing each other up via
telnet. Modern PETSCII art has its own demoscene, and tools
like petmate and PETSCII Editor target both retro hardware and
modern displays. Ethernet Gateway's PETSCII support exists
specifically so a real C64 with a WiFi modem can use a modern
telnet/SSH gateway as if it were a 1985-era BBS.
Appendix D: ATASCII Hex Table
The ATASCII character set used by Atari 8-bit computers (400, 800, XL, XE series). ATASCII is similar to ASCII but has unique control codes and graphics characters. Codes 0x80-0xFF are inverse video versions of 0x00-0x7F.
ATASCII Control Characters (0x00-0x1F)
| Hex | Dec | Name | Description |
| 0x00 | 0 | - | (Null/Heart graphics) |
| 0x01 | 1 | - | (Ctrl+A graphics) |
| 0x02 | 2 | - | (Ctrl+B graphics) |
| 0x03 | 3 | - | (Ctrl+C graphics) |
| 0x04 | 4 | - | (Ctrl+D graphics) |
| 0x05 | 5 | - | (Ctrl+E graphics) |
| 0x06 | 6 | - | (Ctrl+F graphics) |
| 0x07 | 7 | BELL | Bell (buzzer) |
| 0x08 | 8 | - | (Ctrl+H graphics) |
| 0x09 | 9 | - | (Ctrl+I graphics) |
| 0x0A | 10 | - | (Ctrl+J graphics) |
| 0x0B | 11 | - | (Ctrl+K graphics) |
| 0x0C | 12 | - | (Ctrl+L graphics) |
| 0x0D | 13 | - | (Ctrl+M graphics) |
| 0x0E | 14 | - | (Ctrl+N graphics) |
| 0x0F | 15 | - | (Ctrl+O graphics) |
| 0x10 | 16 | - | (Ctrl+P graphics) |
| 0x11 | 17 | - | (Ctrl+Q graphics) |
| 0x12 | 18 | - | (Ctrl+R graphics) |
| 0x13 | 19 | - | (Ctrl+S graphics) |
| 0x14 | 20 | - | (Ctrl+T graphics) |
| 0x15 | 21 | - | (Ctrl+U graphics) |
| 0x16 | 22 | - | (Ctrl+V graphics) |
| 0x17 | 23 | - | (Ctrl+W graphics) |
| 0x18 | 24 | - | (Ctrl+X graphics) |
| 0x19 | 25 | - | (Ctrl+Y graphics) |
| 0x1A | 26 | - | (Ctrl+Z graphics) |
| 0x1B | 27 | ESC | Escape |
| 0x1C | 28 | UP | Cursor Up |
| 0x1D | 29 | DOWN | Cursor Down |
| 0x1E | 30 | LEFT | Cursor Left |
| 0x1F | 31 | RIGHT | Cursor Right |
ATASCII Printable Characters (0x20-0x5F)
| Hex | Dec | Char | Hex | Dec | Char |
| 0x20 | 32 | (space) | 0x40 | 64 | @ |
| 0x21 | 33 | ! | 0x41 | 65 | A |
| 0x22 | 34 | " | 0x42 | 66 | B |
| 0x23 | 35 | # | 0x43 | 67 | C |
| 0x24 | 36 | $ | 0x44 | 68 | D |
| 0x25 | 37 | % | 0x45 | 69 | E |
| 0x26 | 38 | & | 0x46 | 70 | F |
| 0x27 | 39 | ' | 0x47 | 71 | G |
| 0x28 | 40 | ( | 0x48 | 72 | H |
| 0x29 | 41 | ) | 0x49 | 73 | I |
| 0x2A | 42 | * | 0x4A | 74 | J |
| 0x2B | 43 | + | 0x4B | 75 | K |
| 0x2C | 44 | , | 0x4C | 76 | L |
| 0x2D | 45 | - | 0x4D | 77 | M |
| 0x2E | 46 | . | 0x4E | 78 | N |
| 0x2F | 47 | / | 0x4F | 79 | O |
| 0x30 | 48 | 0 | 0x50 | 80 | P |
| 0x31 | 49 | 1 | 0x51 | 81 | Q |
| 0x32 | 50 | 2 | 0x52 | 82 | R |
| 0x33 | 51 | 3 | 0x53 | 83 | S |
| 0x34 | 52 | 4 | 0x54 | 84 | T |
| 0x35 | 53 | 5 | 0x55 | 85 | U |
| 0x36 | 54 | 6 | 0x56 | 86 | V |
| 0x37 | 55 | 7 | 0x57 | 87 | W |
| 0x38 | 56 | 8 | 0x58 | 88 | X |
| 0x39 | 57 | 9 | 0x59 | 89 | Y |
| 0x3A | 58 | : | 0x5A | 90 | Z |
| 0x3B | 59 | ; | 0x5B | 91 | [ |
| 0x3C | 60 | < | 0x5C | 92 | \ |
| 0x3D | 61 | = | 0x5D | 93 | ] |
| 0x3E | 62 | > | 0x5E | 94 | ^ |
| 0x3F | 63 | ? | 0x5F | 95 | _ |
ATASCII Lowercase and Graphics (0x60-0x7F)
| Hex | Dec | Char | Description |
| 0x60 | 96 | ♦ | Diamond |
| 0x61 | 97 | a | Lowercase a |
| 0x62 | 98 | b | Lowercase b |
| 0x63 | 99 | c | Lowercase c |
| 0x64 | 100 | d | Lowercase d |
| 0x65 | 101 | e | Lowercase e |
| 0x66 | 102 | f | Lowercase f |
| 0x67 | 103 | g | Lowercase g |
| 0x68 | 104 | h | Lowercase h |
| 0x69 | 105 | i | Lowercase i |
| 0x6A | 106 | j | Lowercase j |
| 0x6B | 107 | k | Lowercase k |
| 0x6C | 108 | l | Lowercase l |
| 0x6D | 109 | m | Lowercase m |
| 0x6E | 110 | n | Lowercase n |
| 0x6F | 111 | o | Lowercase o |
| 0x70 | 112 | p | Lowercase p |
| 0x71 | 113 | q | Lowercase q |
| 0x72 | 114 | r | Lowercase r |
| 0x73 | 115 | s | Lowercase s |
| 0x74 | 116 | t | Lowercase t |
| 0x75 | 117 | u | Lowercase u |
| 0x76 | 118 | v | Lowercase v |
| 0x77 | 119 | w | Lowercase w |
| 0x78 | 120 | x | Lowercase x |
| 0x79 | 121 | y | Lowercase y |
| 0x7A | 122 | z | Lowercase z |
| 0x7B | 123 | ♠ | Spade |
| 0x7C | 124 | | | Vertical Bar |
| 0x7D | 125 | CLR | Clear Screen |
| 0x7E | 126 | BS | Backspace |
| 0x7F | 127 | TAB | Tab |
ATASCII Inverse Control Characters (0x80-0x9F)
These are inverse video versions of 0x00-0x1F graphics characters.
| Hex | Dec | Name | Description |
| 0x80 | 128 | - | Inverse Heart |
| 0x81 | 129 | - | Inverse Ctrl+A |
| 0x82 | 130 | - | Inverse Ctrl+B |
| 0x83 | 131 | - | Inverse Ctrl+C |
| 0x84 | 132 | - | Inverse Ctrl+D |
| 0x85 | 133 | - | Inverse Ctrl+E |
| 0x86 | 134 | - | Inverse Ctrl+F |
| 0x87 | 135 | - | Inverse Ctrl+G |
| 0x88 | 136 | - | Inverse Ctrl+H |
| 0x89 | 137 | - | Inverse Ctrl+I |
| 0x8A | 138 | - | Inverse Ctrl+J |
| 0x8B | 139 | - | Inverse Ctrl+K |
| 0x8C | 140 | - | Inverse Ctrl+L |
| 0x8D | 141 | - | Inverse Ctrl+M |
| 0x8E | 142 | - | Inverse Ctrl+N |
| 0x8F | 143 | - | Inverse Ctrl+O |
| 0x90 | 144 | - | Inverse Ctrl+P |
| 0x91 | 145 | - | Inverse Ctrl+Q |
| 0x92 | 146 | - | Inverse Ctrl+R |
| 0x93 | 147 | - | Inverse Ctrl+S |
| 0x94 | 148 | - | Inverse Ctrl+T |
| 0x95 | 149 | - | Inverse Ctrl+U |
| 0x96 | 150 | - | Inverse Ctrl+V |
| 0x97 | 151 | - | Inverse Ctrl+W |
| 0x98 | 152 | - | Inverse Ctrl+X |
| 0x99 | 153 | - | Inverse Ctrl+Y |
| 0x9A | 154 | - | Inverse Ctrl+Z |
| 0x9B | 155 | EOL | End of Line (Return) |
| 0x9C | 156 | DELLN | Delete Line |
| 0x9D | 157 | INSLN | Insert Line |
| 0x9E | 158 | CLRTAB | Clear Tab Stop |
| 0x9F | 159 | SETTAB | Set Tab Stop |
ATASCII Inverse Printable Characters (0xA0-0xDF)
These are inverse video versions of 0x20-0x5F.
| Hex | Dec | Char | Hex | Dec | Char |
| 0xA0 | 160 | Inv (space) | 0xC0 | 192 | Inv @ |
| 0xA1 | 161 | Inv ! | 0xC1 | 193 | Inv A |
| 0xA2 | 162 | Inv " | 0xC2 | 194 | Inv B |
| 0xA3 | 163 | Inv # | 0xC3 | 195 | Inv C |
| 0xA4 | 164 | Inv $ | 0xC4 | 196 | Inv D |
| 0xA5 | 165 | Inv % | 0xC5 | 197 | Inv E |
| 0xA6 | 166 | Inv & | 0xC6 | 198 | Inv F |
| 0xA7 | 167 | Inv ' | 0xC7 | 199 | Inv G |
| 0xA8 | 168 | Inv ( | 0xC8 | 200 | Inv H |
| 0xA9 | 169 | Inv ) | 0xC9 | 201 | Inv I |
| 0xAA | 170 | Inv * | 0xCA | 202 | Inv J |
| 0xAB | 171 | Inv + | 0xCB | 203 | Inv K |
| 0xAC | 172 | Inv , | 0xCC | 204 | Inv L |
| 0xAD | 173 | Inv - | 0xCD | 205 | Inv M |
| 0xAE | 174 | Inv . | 0xCE | 206 | Inv N |
| 0xAF | 175 | Inv / | 0xCF | 207 | Inv O |
| 0xB0 | 176 | Inv 0 | 0xD0 | 208 | Inv P |
| 0xB1 | 177 | Inv 1 | 0xD1 | 209 | Inv Q |
| 0xB2 | 178 | Inv 2 | 0xD2 | 210 | Inv R |
| 0xB3 | 179 | Inv 3 | 0xD3 | 211 | Inv S |
| 0xB4 | 180 | Inv 4 | 0xD4 | 212 | Inv T |
| 0xB5 | 181 | Inv 5 | 0xD5 | 213 | Inv U |
| 0xB6 | 182 | Inv 6 | 0xD6 | 214 | Inv V |
| 0xB7 | 183 | Inv 7 | 0xD7 | 215 | Inv W |
| 0xB8 | 184 | Inv 8 | 0xD8 | 216 | Inv X |
| 0xB9 | 185 | Inv 9 | 0xD9 | 217 | Inv Y |
| 0xBA | 186 | Inv : | 0xDA | 218 | Inv Z |
| 0xBB | 187 | Inv ; | 0xDB | 219 | Inv [ |
| 0xBC | 188 | Inv < | 0xDC | 220 | Inv \ |
| 0xBD | 189 | Inv = | 0xDD | 221 | Inv ] |
| 0xBE | 190 | Inv > | 0xDE | 222 | Inv ^ |
| 0xBF | 191 | Inv ? | 0xDF | 223 | Inv _ |
ATASCII Inverse Lowercase and Graphics (0xE0-0xFF)
These are inverse video versions of 0x60-0x7F.
| Hex | Dec | Char | Description |
| 0xE0 | 224 | Inv ♦ | Inverse Diamond |
| 0xE1 | 225 | Inv a | Inverse Lowercase a |
| 0xE2 | 226 | Inv b | Inverse Lowercase b |
| 0xE3 | 227 | Inv c | Inverse Lowercase c |
| 0xE4 | 228 | Inv d | Inverse Lowercase d |
| 0xE5 | 229 | Inv e | Inverse Lowercase e |
| 0xE6 | 230 | Inv f | Inverse Lowercase f |
| 0xE7 | 231 | Inv g | Inverse Lowercase g |
| 0xE8 | 232 | Inv h | Inverse Lowercase h |
| 0xE9 | 233 | Inv i | Inverse Lowercase i |
| 0xEA | 234 | Inv j | Inverse Lowercase j |
| 0xEB | 235 | Inv k | Inverse Lowercase k |
| 0xEC | 236 | Inv l | Inverse Lowercase l |
| 0xED | 237 | Inv m | Inverse Lowercase m |
| 0xEE | 238 | Inv n | Inverse Lowercase n |
| 0xEF | 239 | Inv o | Inverse Lowercase o |
| 0xF0 | 240 | Inv p | Inverse Lowercase p |
| 0xF1 | 241 | Inv q | Inverse Lowercase q |
| 0xF2 | 242 | Inv r | Inverse Lowercase r |
| 0xF3 | 243 | Inv s | Inverse Lowercase s |
| 0xF4 | 244 | Inv t | Inverse Lowercase t |
| 0xF5 | 245 | Inv u | Inverse Lowercase u |
| 0xF6 | 246 | Inv v | Inverse Lowercase v |
| 0xF7 | 247 | Inv w | Inverse Lowercase w |
| 0xF8 | 248 | Inv x | Inverse Lowercase x |
| 0xF9 | 249 | Inv y | Inverse Lowercase y |
| 0xFA | 250 | Inv z | Inverse Lowercase z |
| 0xFB | 251 | Inv ♠ | Inverse Spade |
| 0xFC | 252 | Inv | | Inverse Vertical Bar |
| 0xFD | 253 | BELL | Bell (buzzer) |
| 0xFE | 254 | DEL | Delete Character |
| 0xFF | 255 | INS | Insert Character |
Key ATASCII Codes Reference
| Function | Hex | Dec | Notes |
| Escape | 0x1B | 27 | Same as ASCII |
| Return/EOL | 0x9B | 155 | End of logical line |
| Backspace | 0x7E | 126 | Delete character left |
| Delete | 0xFE | 254 | Delete character at cursor |
| Insert | 0xFF | 255 | Insert mode toggle |
| Clear Screen | 0x7D | 125 | Clear and home cursor |
| Cursor Up | 0x1C | 28 | |
| Cursor Down | 0x1D | 29 | |
| Cursor Left | 0x1E | 30 | |
| Cursor Right | 0x1F | 31 | |
| Tab | 0x7F | 127 | Move to next tab stop |
| Bell | 0xFD | 253 | Also 0x07 |
| Delete Line | 0x9C | 156 | |
| Insert Line | 0x9D | 157 | |
Note: ATASCII uses 0x9B (155) for end-of-line instead of the standard ASCII 0x0D (13). The upper 128 characters (0x80-0xFF) are inverse video versions of the lower 128 (0x00-0x7F), except for certain control codes in the 0x9B-0x9F and 0xFD-0xFF ranges which have special functions.
History
1979 — the Atari 400 and 800.
ATASCII (Atari Standard Code for Information Interchange) was
introduced with the Atari 400 and 800 in November 1979 —
the same year as the TI-99/4. The character set was designed
by Atari's Home Computer Division under Jay Miner, who would
later design the Amiga's custom chips. The Atari 8-bits
(400/800/1200XL/600XL/800XL/65XE/130XE/XEGS) all used
ATASCII unchanged from 1979 to the line's discontinuation in
1992 — an unusually long character-set lifetime for a
home-computer family.
The 0x9B EOL problem.
ATASCII's most infamous quirk is using 0x9B
(155, "EOL") as end-of-line instead of CR/LF. This was a
deliberate choice — 0x9B is a single byte, doesn't
require pairing CR with LF, and falls in a range Atari
considered "safe" because they didn't use the 0x80-0xFF
inverse range for printable text. The downside was severe:
every cross-platform file transfer (ASCII mode FTP, BBS
uploads, modem terminal programs) had to translate 0x9B to
0x0D 0x0A on the way out and back on the way in. A
generation of Atari users learned what "ATASCII translation"
meant the hard way after losing line breaks on cross-platform
files. The Ethernet Gateway's terminal-detection logic
specifically watches for ATASCII-style line endings.
Inverse video as a parallel character set.
The Atari ANTIC graphics chip rendered character cells with a
hardware inverse-video bit (bit 7 of the screen-memory byte).
ATASCII exploits this directly: the upper 128 codes
(0x80-0xFF) are not new characters — they're the lower
128 with inverse video applied. This means an Atari programmer
could highlight a word in a status line by simply ORing 0x80
into each byte. Six positions (0x9B-0x9F, 0xFD-0xFF) were
stolen back as control codes (EOL, delete-line, insert-line,
tab-stop set/clear, bell, delete-char, insert-char), so those
don't have inverse equivalents.
The Atari BBS scene.
Atari BBSes (running software like AMIS, FoReM, BBS Express!)
were a parallel ecosystem to the Commodore boards. ATASCII
art and animations — using the cursor-control codes to
move around and the inverse-video range for color
— were a recognizable style, distinct from PETSCII or
ANSI art. Commercial online services that catered to Atari users
included The Source (a Reader's Digest
subsidiary, later acquired by CompuServe) and CompuServe itself,
both of which published Atari-specific terminal programs that
translated ATASCII to and from ASCII at the gateway.
Today.
ATASCII survives in emulators (Altirra, Atari800), in modern
cartridges and SD-based loaders that let real 8-bit hardware
connect to modern networks (FujiNet, SIO2PC), and in the
small but persistent Atari demoscene. The character set is
also still used by some specialty software for Atari ST and
Falcon machines that retained 8-bit-mode compatibility.
Appendix E: Baudot (ITA2) Code Table
Emile Baudot devised his 5-bit telegraph encoding in the 1870s. The CCITT adopted a refined version as International Telegraph Alphabet No. 2 (ITA2) in 1932, and it remained the standard teleprinter code worldwide until ASCII took over in the 1960s. The unit of signaling speed, the "baud," takes its name from Baudot.
How Baudot Works
With only 5 bits, Baudot can represent 32 unique codes (0-31). To encode letters, numbers, and punctuation, Baudot uses two "shift" states:
- Letters Shift (LTRS) - Codes produce uppercase letters A-Z
- Figures Shift (FIGS) - Codes produce numbers and punctuation
The receiver maintains the current shift state. Sending LTRS (code 31) or FIGS (code 27) changes the state for all subsequent characters until another shift code is received.
ITA2 Code Table
| Binary | Dec | Hex | Letters (LTRS) | Figures (FIGS) |
| 00000 | 0 | 0x00 | NUL (Null) | NUL (Null) |
| 00001 | 1 | 0x01 | E | 3 |
| 00010 | 2 | 0x02 | LF (Line Feed) | LF (Line Feed) |
| 00011 | 3 | 0x03 | A | - |
| 00100 | 4 | 0x04 | SP (Space) | SP (Space) |
| 00101 | 5 | 0x05 | S | ' |
| 00110 | 6 | 0x06 | I | 8 |
| 00111 | 7 | 0x07 | U | 7 |
| 01000 | 8 | 0x08 | CR (Carriage Return) | CR (Carriage Return) |
| 01001 | 9 | 0x09 | D | ENQ (Who Are You?) |
| 01010 | 10 | 0x0A | R | 4 |
| 01011 | 11 | 0x0B | J | BEL (Bell) |
| 01100 | 12 | 0x0C | N | , |
| 01101 | 13 | 0x0D | F | ! |
| 01110 | 14 | 0x0E | C | : |
| 01111 | 15 | 0x0F | K | ( |
| 10000 | 16 | 0x10 | T | 5 |
| 10001 | 17 | 0x11 | Z | + |
| 10010 | 18 | 0x12 | L | ) |
| 10011 | 19 | 0x13 | W | 2 |
| 10100 | 20 | 0x14 | H | £ |
| 10101 | 21 | 0x15 | Y | 6 |
| 10110 | 22 | 0x16 | P | 0 |
| 10111 | 23 | 0x17 | Q | 1 |
| 11000 | 24 | 0x18 | O | 9 |
| 11001 | 25 | 0x19 | B | ? |
| 11010 | 26 | 0x1A | G | & |
| 11011 | 27 | 0x1B | FIGS (Shift to Figures) | FIGS (Shift to Figures) |
| 11100 | 28 | 0x1C | M | . |
| 11101 | 29 | 0x1D | X | / |
| 11110 | 30 | 0x1E | V | = |
| 11111 | 31 | 0x1F | LTRS (Shift to Letters) | LTRS (Shift to Letters) |
Control Characters
| Code | Name | Description |
| 0 (00000) | NUL | Null - No operation, used for timing/padding |
| 2 (00010) | LF | Line Feed - Move paper up one line |
| 4 (00100) | SP | Space - Blank character, advances position |
| 8 (01000) | CR | Carriage Return - Return print head to start of line |
| 27 (11011) | FIGS | Figures Shift - Switch to figures mode |
| 31 (11111) | LTRS | Letters Shift - Switch to letters mode |
Figures Mode Special Codes
| Code | Character | Notes |
| 9 (01001) | ENQ | "Who Are You?" - Requests station identification |
| 11 (01011) | BEL | Bell - Rings the teleprinter bell |
US TTY Variant
The United States used a variant called US TTY (Teletypewriter) with some different figure assignments:
| Code | ITA2 | US TTY |
| 5 (00101) | ' (apostrophe) | BEL (bell) |
| 11 (01011) | BEL (bell) | ' (apostrophe) |
| 20 (10100) | £ (pound) | $ (dollar) |
Encoding Example
To send "HELLO 123":
| Character | Shift State | Code Sent | Binary |
| LTRS | - | 31 | 11111 |
| H | Letters | 20 | 10100 |
| E | Letters | 1 | 00001 |
| L | Letters | 18 | 10010 |
| L | Letters | 18 | 10010 |
| O | Letters | 24 | 11000 |
| SP | Letters | 4 | 00100 |
| FIGS | - | 27 | 11011 |
| 1 | Figures | 23 | 10111 |
| 2 | Figures | 19 | 10011 |
| 3 | Figures | 1 | 00001 |
Quick Reference: Letters Mode
| A | B | C | D | E | F | G | H | I | J | K | L | M |
| 3 | 25 | 14 | 9 | 1 | 13 | 26 | 20 | 6 | 11 | 15 | 18 | 28 |
| N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
| 12 | 24 | 22 | 23 | 10 | 5 | 16 | 7 | 30 | 19 | 29 | 21 | 17 |
Quick Reference: Figures Mode (Digits)
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 22 | 23 | 19 | 1 | 10 | 16 | 21 | 7 | 6 | 24 |
History
1870s — Émile Baudot.
French telegraph engineer Émile Baudot
patented his 5-bit code in 1874 to replace the older Morse
code on multi-channel telegraph circuits. Morse was
variable-length and asynchronous, which made it impossible to
multiplex efficiently; Baudot's fixed-width code let multiple
operators share a single wire by time-division multiplexing,
dramatically increasing the throughput of telegraph offices.
Baudot also invented a five-key piano-like keyboard
specifically tuned to enter his code — the operator
played each character as a five-finger chord. The unit of
signaling speed, the "baud," is named for him.
1901-1932 — Donald Murray and ITA2.
New Zealand-born engineer Donald Murray
redesigned Baudot's code in 1901 to better suit
keyboard-driven typewriters: he reassigned codes so that
common letters required less mechanical wear on the
print mechanism, and added punctuation. The CCITT
(Consultative Committee on International Telephony and
Telegraphy, predecessor to the ITU-T) standardized Murray's
scheme as International Telegraph Alphabet No. 2
(ITA2) in 1932. ITA1 was the original Baudot;
ITA2 (Murray's revision) is what almost everyone calls
"Baudot" today, including this table.
The shift-state trick.
Five bits gives only 32 codes. To represent 26 letters, 10
digits, and punctuation, Baudot/ITA2 uses two
shift states — LTRS (code 31) and
FIGS (code 27). Each one switches the meaning of all
subsequent codes until the other shift is sent. This is
why a hardware glitch on a teleprinter line could turn an
entire message into nonsense: if the receiver missed an
LTRS or FIGS shift, every following character was
mis-decoded. Operators developed a habit of repeating
shifts every few words for resync.
Mechanical speeds.
Baudot ran at 45.45, 50, 56.9, 75, or 100 baud on
mechanical teleprinters — speeds chosen to match
the resonant frequency of the Teletype's spring-driven
type-bar mechanism. Each character was one start bit,
five data bits, and 1.5 stop bits (the half-bit stop was
a clever way to keep the receiver in sync without a
full-bit gap). At 50 baud, that gave roughly 6.7
characters per second — about 400 characters per
minute, fast enough for live typed conversation.
Telex and TWX.
From the 1930s through the 1980s, Baudot/ITA2 was the
backbone of the global Telex network
(international) and TWX (Teletypewriter
Exchange Service, North America). At its peak in the
1980s, Telex linked over 2 million machines worldwide
and was the primary medium for legally-binding
international business communication — faster than
mail, more durable than phone, and accepted in court as
documentary evidence. Telex didn't begin its decline
until fax (1980s) and email (1990s) took over.
TDD/TTY for the deaf.
After commercial Telex died, Baudot lived on in
telecommunication devices for the deaf. The
TDD/TTY (Telecommunication Device for
the Deaf, also called Teletypewriter) protocol used
ITA2 with US TTY variant figure assignments at 45.45
or 50 baud over the regular phone network, with
distinctive "warble" tones (1400/1800 Hz). TDD/TTY
usage held on into the 2000s before being replaced by
video relay services and SMS. Some emergency 911
systems still accept TDD calls today as a regulatory
accessibility requirement.
Why no lowercase?
Mechanical teleprinters had a single set of physical
type-bars per character position — adding
lowercase would have doubled the mechanism cost and
paper-tape width. By the time printing technology made
mixed case practical (the 1960s), 7-bit ASCII was
already taking over, so Baudot remained an uppercase-only
standard throughout its commercial life.
Appendix F: ZX Spectrum Character Set
The Sinclair ZX Spectrum (1982) used a custom character set based on ASCII but with unique additions. It shared standard ASCII printable characters (0x20-0x7F) with two notable exceptions, and added block graphics characters and BASIC keyword tokens in the upper range.
Control Characters (0x00-0x1F)
The ZX Spectrum uses several custom control codes. Most codes below 0x06 are not used.
| Hex | Dec | Name | Description |
| 0x06 | 6 | COMMA | PRINT comma control (move to next print zone) |
| 0x08 | 8 | LEFT | Cursor Left (Backspace) |
| 0x09 | 9 | RIGHT | Cursor Right |
| 0x0A | 10 | DOWN | Cursor Down |
| 0x0B | 11 | UP | Cursor Up |
| 0x0C | 12 | DELETE | Delete |
| 0x0D | 13 | ENTER | Enter / Newline |
| 0x10 | 16 | INK | Set ink (foreground) color (next byte = 0-7) |
| 0x11 | 17 | PAPER | Set paper (background) color (next byte = 0-7) |
| 0x12 | 18 | FLASH | Set flash attribute (next byte = 0 or 1) |
| 0x13 | 19 | BRIGHT | Set bright attribute (next byte = 0 or 1) |
| 0x14 | 20 | INVERSE | Set inverse attribute (next byte = 0 or 1) |
| 0x15 | 21 | OVER | Set overprint mode (next byte = 0 or 1) |
| 0x16 | 22 | AT | Position cursor (next 2 bytes = row, column) |
| 0x17 | 23 | TAB | Tab to column (next 2 bytes = column number) |
Character Set Differences from ASCII
The ZX Spectrum printable range (0x20-0x7F) matches standard ASCII except for two positions:
| Hex | Dec | ASCII | ZX Spectrum |
| 0x60 | 96 | ` (backtick) | £ (pound sterling) |
| 0x7F | 127 | DEL | © (copyright symbol) |
ZX Spectrum Colors
Used with the INK (0x10) and PAPER (0x11) control codes:
| Value | Color | Bright Color |
| 0 | Black | Black |
| 1 | Blue | Bright Blue |
| 2 | Red | Bright Red |
| 3 | Magenta | Bright Magenta |
| 4 | Green | Bright Green |
| 5 | Cyan | Bright Cyan |
| 6 | Yellow | Bright Yellow |
| 7 | White | Bright White |
Block Graphics Characters (0x80-0x8F)
The ZX Spectrum's distinctive block graphics divide each character cell into four quadrants (2×2 grid). Each of the 16 combinations represents a different pattern of filled and empty quadrants. These were widely used for games and UI elements.
| Hex | Dec | Pattern | Description |
| 0x80 | 128 | | All empty (space) |
| 0x81 | 129 | ▗ | Bottom-right quadrant |
| 0x82 | 130 | ▖ | Bottom-left quadrant |
| 0x83 | 131 | ▄ | Bottom half |
| 0x84 | 132 | ▝ | Top-right quadrant |
| 0x85 | 133 | ▐ | Right half |
| 0x86 | 134 | ▞ | Top-right + bottom-left (diagonal) |
| 0x87 | 135 | ▟ | Top-right + bottom half |
| 0x88 | 136 | ▘ | Top-left quadrant |
| 0x89 | 137 | ▚ | Top-left + bottom-right (diagonal) |
| 0x8A | 138 | ▌ | Left half |
| 0x8B | 139 | ▙ | Top-left + bottom half |
| 0x8C | 140 | ▀ | Top half |
| 0x8D | 141 | ▜ | Top half + bottom-right |
| 0x8E | 142 | ▛ | Top half + bottom-left |
| 0x8F | 143 | █ | Full block (all filled) |
User Defined Graphics (0x90-0xA4)
Characters 0x90-0xA4 (144-164) are User Defined Graphics (UDG) slots A through U. These are customizable 8×8 pixel characters that programs can redefine. By default, they display as letters A-U, but games and applications typically redefine them for custom sprites and icons.
| Hex | Dec | UDG Letter | Hex | Dec | UDG Letter | Hex | Dec | UDG Letter |
| 0x90 | 144 | A | 0x97 | 151 | H | 0x9E | 158 | O |
| 0x91 | 145 | B | 0x98 | 152 | I | 0x9F | 159 | P |
| 0x92 | 146 | C | 0x99 | 153 | J | 0xA0 | 160 | Q |
| 0x93 | 147 | D | 0x9A | 154 | K | 0xA1 | 161 | R |
| 0x94 | 148 | E | 0x9B | 155 | L | 0xA2 | 162 | S |
| 0x95 | 149 | F | 0x9C | 156 | M | 0xA3 | 163 | T |
| 0x96 | 150 | G | 0x9D | 157 | N | 0xA4 | 164 | U |
BASIC Keyword Tokens (0xA5-0xFF)
The ZX Spectrum stored BASIC keywords as single-byte tokens to save memory. When listed, each token expands to the full keyword. This is a selection of the most commonly used tokens:
| Hex | Dec | Keyword | Hex | Dec | Keyword |
| 0xA5 | 165 | RND | 0xD7 | 215 | BEEP |
| 0xA6 | 166 | INKEY$ | 0xD9 | 217 | INK |
| 0xA7 | 167 | PI | 0xDA | 218 | PAPER |
| 0xAB | 171 | ATTR | 0xE0 | 224 | LPRINT |
| 0xAC | 172 | AT | 0xE1 | 225 | LLIST |
| 0xAF | 175 | CODE | 0xE3 | 227 | READ |
| 0xB0 | 176 | VAL | 0xE7 | 231 | BORDER |
| 0xB1 | 177 | LEN | 0xEC | 236 | GO TO |
| 0xBE | 190 | PEEK | 0xED | 237 | GO SUB |
| 0xC0 | 192 | USR | 0xEE | 238 | INPUT |
| 0xC2 | 194 | CHR$ | 0xEF | 239 | LOAD |
| 0xCA | 202 | LINE | 0xF4 | 244 | POKE |
| 0xCB | 203 | THEN | 0xF5 | 245 | PRINT |
| 0xCC | 204 | TO | 0xF9 | 249 | RANDOMIZE |
| 0xCD | 205 | STEP | 0xFA | 250 | IF |
| 0xD1 | 209 | MOVE | 0xFB | 251 | CLS |
History
1982 — Sinclair Research, Cambridge.
Sir Clive Sinclair's Sinclair Research
launched the ZX Spectrum on April 23, 1982 at the Earls Court
Computer Fair in London. The 16K model cost £125 and the
48K model £175 — roughly half the price
of an Acorn BBC Micro and a third of an Apple II. This
aggressive pricing was Sinclair's signature move; he had
already shipped the calculator-style ZX80 (1980) and ZX81
(1981) on the same philosophy. The Spectrum's distinctive
grey-with-rainbow case was designed by industrial designer
Rick Dickinson, who also did the ZX81.
The dead-flesh keyboard.
The original Spectrum used a flat rubber membrane keyboard
— nicknamed "dead flesh" by the British computing press
— in which each key had up to five different
functions printed on it: the letter, a BASIC keyword, an
extended-mode command, and two symbols. Pressing K alone
entered the LIST keyword; SHIFT+K entered the symbol "+";
SYMBOL SHIFT+K entered "+"; EXTENDED MODE then K entered the
keyword TAN. This crowding was a memory-saving trick —
the BASIC interpreter could store entire keywords as
single-byte tokens (0xFB = CLS,
0xF5 = PRINT) without a parser, because the user
literally couldn't type a keyword character-by-character.
Color attribute clash.
The Spectrum's display was 256x192 monochrome pixels overlaid
with a 32x24 grid of color attributes — each
character cell could pick its own ink and
paper from the 8-color palette, but only one ink/paper combo
per cell. This produced the infamous "attribute clash" where
two sprites overlapping in the same character cell forced
their colors to merge. Game programmers turned the limitation
into an aesthetic: classics like Knight Lore,
Manic Miner, and Jet Set Willy have an
unmistakable look that comes directly from working within (or
against) the attribute grid.
The block graphics range.
Codes 0x80-0x8F are 16 block-graphics glyphs
covering every combination of a 2x2 quadrant grid. They
doubled the effective screen resolution to 512x384 "pixels"
for character-mode rendering — useful for charts, BASIC
graphics, and simple games that didn't need pixel-exact
sprites. The 21 User Defined Graphics slots (0x90-0xA4) let
programs install their own 8x8 glyphs into BASIC's character
set, which is how nearly every Spectrum game drew its sprites.
Sales and the British games industry.
The Spectrum sold roughly 5 million units
worldwide, the bulk of them in the UK, where it dominated the
home-computer market through the mid-1980s. It birthed an
entire British games industry: Ultimate Play the Game (later
Rare), Ocean Software, Imagine, Codemasters, and dozens of
bedroom developers shipped games on cassette tapes that
loaded for five minutes from screeching audio over the
machine's EAR jack. Many of those developers are still active
in the modern industry. Sinclair sold the Spectrum business
to Amstrad in 1986, which kept producing it (the Spectrum
+2, +3) until 1992.
Modern revival.
The Spectrum has one of the most active retro communities of
any vintage platform. Modern hardware reproductions (the
ZX Spectrum Next, an FPGA-based reimplementation funded on
Kickstarter in 2017, and the ZX-Uno) sell in the tens of
thousands. The annual Crash Live and Spectrum demoscene
events still draw crowds, and new commercial games for the
original Spectrum still ship on cassette every year. The
machine's character set, including its block graphics and
keyword tokens, is still natively supported by emulators
like Fuse, ZEsarUX, and Spectaculator.
Appendix G: TRS-80 Character Set
The Tandy/Radio Shack TRS-80 (1977) used a custom character set. The lower range (0x00-0x7F) follows ASCII for standard characters. The upper range (0x80-0xFF) contains the TRS-80's distinctive semigraphics characters — block graphics formed by dividing each character cell into a 2×3 grid of six independently controllable pixels.
Control Characters (0x00-0x1F)
The TRS-80 uses standard ASCII control characters. Most are not printable. Key codes relevant to terminal operation:
| Hex | Dec | Name | Description |
| 0x08 | 8 | BS | Backspace (cursor left) |
| 0x09 | 9 | HT | Horizontal Tab |
| 0x0A | 10 | LF | Line Feed (cursor down) |
| 0x0D | 13 | CR | Carriage Return (Enter) |
| 0x0E | 14 | SO | Cursor On (Model III/4) |
| 0x0F | 15 | SI | Cursor Off (Model III/4) |
| 0x17 | 23 | ETB | Cursor right (Model III/4) |
| 0x18 | 24 | CAN | Backspace and erase |
| 0x1A | 26 | SUB | Cursor up (Model III/4) |
| 0x1B | 27 | ESC | Escape (Model III/4 only) |
| 0x1C | 28 | FS | Home cursor |
| 0x1D | 29 | GS | Cursor right |
| 0x1E | 30 | RS | Cursor down |
| 0x1F | 31 | US | Clear screen and home (Model I: home only) |
Printable Characters (0x20-0x5F)
Standard ASCII digits, punctuation, and uppercase letters. The TRS-80 Model I did not have lowercase letters — positions 0x60-0x7F were unused or mapped to additional graphics. The Model III and Model 4 added lowercase in this range.
| Hex | Dec | Char | Hex | Dec | Char | Hex | Dec | Char |
| 0x20 | 32 | (space) | 0x30 | 48 | 0 | 0x40 | 64 | @ |
| 0x21 | 33 | ! | 0x31 | 49 | 1 | 0x41 | 65 | A |
| 0x22 | 34 | " | 0x32 | 50 | 2 | 0x42 | 66 | B |
| 0x23 | 35 | # | 0x33 | 51 | 3 | 0x43 | 67 | C |
| 0x24 | 36 | $ | 0x34 | 52 | 4 | 0x44 | 68 | D |
| 0x25 | 37 | % | 0x35 | 53 | 5 | 0x45 | 69 | E |
| 0x26 | 38 | & | 0x36 | 54 | 6 | 0x46 | 70 | F |
| 0x27 | 39 | ' | 0x37 | 55 | 7 | 0x47 | 71 | G |
| 0x28 | 40 | ( | 0x38 | 56 | 8 | 0x48 | 72 | H |
| 0x29 | 41 | ) | 0x39 | 57 | 9 | 0x49 | 73 | I |
| 0x2A | 42 | * | 0x3A | 58 | : | 0x4A | 74 | J |
| 0x2B | 43 | + | 0x3B | 59 | ; | 0x4B | 75 | K |
| 0x2C | 44 | , | 0x3C | 60 | < | 0x4C | 76 | L |
| 0x2D | 45 | - | 0x3D | 61 | = | 0x4D | 77 | M |
| 0x2E | 46 | . | 0x3E | 62 | > | 0x4E | 78 | N |
| 0x2F | 47 | / | 0x3F | 63 | ? | 0x4F | 79 | O |
| | | | | | 0x50 | 80 | P |
| | | | | | 0x51 | 81 | Q |
| | | | | | 0x52 | 82 | R |
| | | | | | 0x53 | 83 | S |
| | | | | | 0x54 | 84 | T |
| | | | | | 0x55 | 85 | U |
| | | | | | 0x56 | 86 | V |
| | | | | | 0x57 | 87 | W |
| | | | | | 0x58 | 88 | X |
| | | | | | 0x59 | 89 | Y |
| | | | | | 0x5A | 90 | Z |
| | | | | | 0x5B | 91 | [ |
| | | | | | 0x5C | 92 | \ |
| | | | | | 0x5D | 93 | ] |
| | | | | | 0x5E | 94 | ^ |
| | | | | | 0x5F | 95 | _ |
Lowercase Characters (0x60-0x7F) — Model III/4 Only
The TRS-80 Model I lacked lowercase letters entirely. The Model III (1980) and Model 4 (1983) added lowercase in the 0x60-0x7F range, matching standard ASCII for 0x60-0x7E. Position 0x7F is non-printing and is treated as DEL in software but displays as a small block glyph (often used as a cursor) on the Model III/4 character generator ROMs.
| Hex | Dec | Char | Hex | Dec | Char | Hex | Dec | Char |
| 0x60 | 96 | ` | 0x6B | 107 | k | 0x76 | 118 | v |
| 0x61 | 97 | a | 0x6C | 108 | l | 0x77 | 119 | w |
| 0x62 | 98 | b | 0x6D | 109 | m | 0x78 | 120 | x |
| 0x63 | 99 | c | 0x6E | 110 | n | 0x79 | 121 | y |
| 0x64 | 100 | d | 0x6F | 111 | o | 0x7A | 122 | z |
| 0x65 | 101 | e | 0x70 | 112 | p | 0x7B | 123 | { |
| 0x66 | 102 | f | 0x71 | 113 | q | 0x7C | 124 | | |
| 0x67 | 103 | g | 0x72 | 114 | r | 0x7D | 125 | } |
| 0x68 | 104 | h | 0x73 | 115 | s | 0x7E | 126 | ~ |
| 0x69 | 105 | i | 0x74 | 116 | t | 0x7F | 127 | DEL / cursor block |
| 0x6A | 106 | j | 0x75 | 117 | u | | | |
Semigraphics Characters (0x80-0xBF)
The TRS-80's most distinctive feature: 64 block graphics characters formed by dividing each character cell into a 2×3 grid of six pixels. Each pixel can be on (white) or off (black), giving 26 = 64 possible patterns. The pixel positions are numbered as bits:
| Pixel Layout | Bit Weight |
| Top-left | Top-right | 1, 2 |
| Middle-left | Middle-right | 4, 8 |
| Bottom-left | Bottom-right | 16, 32 |
The character code is calculated as: 0x80 + (sum of active pixel bit weights)
For example: top-left (1) + middle-right (8) + bottom-left (16) = 0x80 + 25 = 0x99
| Hex | Dec | Active Pixels | Description |
| 0x80 | 128 | (none) | Empty block (all pixels off) |
| 0x81 | 129 | 1 | Top-left only |
| 0x82 | 130 | 2 | Top-right only |
| 0x83 | 131 | 1+2 | Top row |
| 0x84 | 132 | 4 | Middle-left only |
| 0x85 | 133 | 1+4 | Left column top two |
| 0x88 | 136 | 8 | Middle-right only |
| 0x8C | 140 | 4+8 | Middle row |
| 0x90 | 144 | 16 | Bottom-left only |
| 0x93 | 147 | 1+2+16 | Top row + bottom-left |
| 0xA0 | 160 | 32 | Bottom-right only |
| 0xA1 | 161 | 1+32 | Top-left + bottom-right (diagonal) |
| 0xB0 | 176 | 16+32 | Bottom row |
| 0xB3 | 179 | 1+2+16+32 | Top + bottom rows |
| 0xBC | 188 | 4+8+16+32 | Middle + bottom rows |
| 0xBF | 191 | 1+2+4+8+16+32 | Full block (all pixels on) |
Common Semigraphics Patterns
A quick reference for frequently used block patterns in TRS-80 programs:
| Pattern | Hex | Bits | Use |
| Full block | 0xBF | 63 | Solid fill, walls |
| Left half | 0x95 | 1+4+16 | Vertical dividers |
| Right half | 0xAA | 2+8+32 | Vertical dividers |
| Top half | 0x8F | 1+2+4+8 | Horizontal dividers |
| Bottom half | 0xB0 | 16+32 | Horizontal dividers, underlines |
| Checkerboard A | 0x99 | 1+8+16 | Shading, dithering |
| Checkerboard B | 0xA6 | 2+4+32 | Shading, dithering |
| Top row | 0x83 | 1+2 | Thin top border |
| Middle row | 0x8C | 4+8 | Thin middle line |
| Bottom row | 0xB0 | 16+32 | Thin bottom border |
Extended Characters (0xC0-0xFF) — Model III/4
On the TRS-80 Model I, codes 0xC0-0xFF were mirrors of the semigraphics range (0x80-0xBF). On the Model III and Model 4, this range was repurposed for additional characters including international and special symbols. A selection of commonly used codes:
| Hex | Dec | Char | Description |
| 0xC0 | 192 | ♠ | Spade |
| 0xC1 | 193 | ♥ | Heart |
| 0xC2 | 194 | ♦ | Diamond |
| 0xC3 | 195 | ♣ | Club |
| 0xC4 | 196 | ↑ | Up Arrow |
| 0xC5 | 197 | ↓ | Down Arrow |
| 0xC6 | 198 | ← | Left Arrow |
| 0xC7 | 199 | → | Right Arrow |
| 0xCB | 203 | £ | Pound Sterling |
| 0xCC | 204 | ¥ | Yen |
| 0xCF | 207 | © | Copyright |
| 0xD0 | 208 | ® | Registered |
| 0xD3 | 211 | ¼ | One Quarter |
| 0xD4 | 212 | ½ | One Half |
| 0xDB | 219 | ─ | Horizontal Line |
| 0xDC | 220 | │ | Vertical Line |
| 0xDD | 221 | ┌ | Top-Left Corner |
| 0xDE | 222 | ┐ | Top-Right Corner |
| 0xDF | 223 | └ | Bottom-Left Corner |
| 0xE0 | 224 | ┘ | Bottom-Right Corner |
| 0xE1 | 225 | ┼ | Cross (intersection) |
| 0xE2 | 226 | ├ | Left T-junction |
| 0xE3 | 227 | ┤ | Right T-junction |
| 0xE4 | 228 | ┬ | Top T-junction |
| 0xE5 | 229 | ┴ | Bottom T-junction |
History
August 1977 — Tandy/Radio Shack.
The TRS-80 Model I shipped on August 3, 1977 — about
two months after the Apple II began shipping and roughly two
months before the Commodore PET 2001 reached
customers (the PET had been announced in January 1977 but
didn't ship in volume until October). Tandy Corporation's
electronics chain Radio Shack already had
over 3,000 retail stores in the U.S., which gave the Model I
instant distribution that Apple and Commodore couldn't match.
It was designed by Steve Leininger in Fort
Worth, Texas, on the staff of Don French (the Radio Shack
buyer who championed the project). The "TRS" stood for Tandy
Radio Shack; "80" referenced the Z80 CPU.
The "1977 Trinity."
Byte magazine retroactively named the Apple II,
TRS-80 Model I, and Commodore PET the "1977 Trinity" —
the three machines that turned the personal computer from a
hobbyist kit (Altair 8800, IMSAI 8080, KIM-1) into a
consumer product you could plug in and use. Of the three,
the TRS-80 was by far the cheapest at $599 (Model I, 4K) and
had the most retail presence. From 1977 to 1981 it
outsold both rivals; estimates put the Model I and Model III
combined at roughly 250,000 units.
The 2x3 semigraphics trick.
The TRS-80's video hardware had no dedicated graphics chip
and no bitmap mode — just a character-cell display.
Leininger's solution was elegant: codes 0x80-0xBF in the
character set are 64 block-graphics glyphs
covering every possible combination of six pixels arranged
in a 2x3 grid inside a single character cell. With a
64-column by 16-row text display, that gave an effective
128x48 "graphics" resolution for free,
using only the text-mode hardware. Every TRS-80 game, every
chart, every menu border was drawn this way. The technique
was so effective that the later CoCo (Color Computer)
inherited a similar scheme.
The "Trash-80" reputation.
Competitors and the computing press derisively nicknamed it
the "Trash-80" — partly because of the cheap-feeling
silver-and-black plastic case, partly because of the famous
silver-mylar keyboard reliability problems on the Model I,
and partly because Tandy's tape-loading was notoriously
unreliable (the cassette interface clipped at strange audio
levels). Despite that, it was solid-enough that an enormous
third-party market sprang up to fix or upgrade it: Percom
disk drives, Lobo controllers, lowercase-character
modification kits, and a thriving software market that
survived into the late 1980s.
Model I → III → 4.
The Model I was discontinued in 1981 because it failed FCC
radio-frequency emission rules — its bare-PCB-on-desk
design leaked Z80 clock harmonics across the AM radio band.
The Model III (1980) was a redesign in a
single integrated case that passed FCC, added lowercase
(the original Model I had no lowercase letters; positions
0x60-0x7F were unused or duplicated graphics), and bumped
RAM. The Model 4 (1983) added an 80-column
mode, more RAM, and CP/M compatibility — a tacit
admission that the IBM PC had taken over the business
market. The 4P (1983) was a "luggable" portable variant.
Color Computer (CoCo) and after.
Tandy's TRS-80 Color Computer (1980) shared
the TRS-80 brand but was an entirely different machine
architecturally — a Motorola 6809 with a Motorola
graphics chip, no relation to the Model I/III/4 line. The
Z80-based TRS-80 Model 4 was the last machine in the
original lineage; Tandy quietly dropped the Z80 line in
1991 and focused on IBM-compatible PCs (the Tandy 1000
family). The Model 4 character set described in this
appendix is the most complete; the Model I was a strict
subset (no lowercase, semigraphics-only upper range).
Today.
The TRS-80 retro community is smaller than the C64 or
Spectrum scenes but very active. Emulators (TRS80gp, MAME,
sdltrs) cover all four models faithfully, and projects like
the Model 1 reproduction PCB and
FreHD (a CompactFlash-based hard-disk
replacement) keep real hardware running. The 1977
Computer History Museum exhibit in Mountain View
permanently displays a working Model I as part of its
personal-computer-revolution gallery.
← Back to User Manual