Skip to content

PETSCII (Commodore) Callers

ENiGMA½ can serve Commodore-style terminals that speak PETSCII in place of ANSI: SyncTERM and IcyTerm in their C64 or C128 modes, and terminal programs on real Commodore hardware.

This is early support. The board is still ANSI inside: menus, prompts and views are translated on the way out. Art can be native PETSCII (.seq files, see Native PETSCII art), and ENiGMA½ comes with a small set of starter menus and a theme laid out for a 40 column screen. A board with no PETSCII theme at all shows PETSCII callers its ANSI menus and art, translated: art drawn for an 80 column ANSI screen does not look right on a 40 column PETSCII one, but the caller gets something rather than a blank screen. Nothing changes for ANSI callers.

A session is PETSCII in either of two ways:

  • The terminal says so. SyncTERM and IcyTerm send the Telnet terminal type PETSCII when set to a Commodore mode. In SyncTERM that means setting the directory entry’s Screen Mode to a C64 or C128 mode. Choosing only a Commodore font leaves SyncTERM an ANSI terminal.
  • The port says so. Terminal programs on real Commodore hardware usually connect as plain TCP and announce nothing. Give them their own port with an additional Telnet listener:
{
loginServers: {
telnet: {
listeners: {
c64: {
port: 6400
emulation: petscii
}
}
}
}
}

Every caller on that port is treated as PETSCII, whatever its terminal announces. A listener may also name its own firstMenu, for example the first menu of the starter menus.

The stock menus are drawn for 80 column ANSI screens and are far too many to redraw for a Commodore one. ENiGMA½ ships a small, separate menu tree for PETSCII callers instead, and a starter theme with art for exactly those menus:

  • Connect screen and login matrix: log in, apply, log off. New user applications are not offered to PETSCII callers yet: “apply” tells the caller to apply from an ANSI terminal and goes back to the matrix.
  • Login, including two-factor (2FA/OTP) login for accounts that use it, and short screens for an account that is already logged in, locked, disabled or not yet active.
  • Last callers after login, then the offer of a new-message scan, then a main menu with messages, who’s online, last callers and log off.
  • Messages: join a conference, pick a message area, list the area’s messages, read them (next, previous, reply, quit), and post a new message or a reply, quoting lines from the message, with the full-screen editor. See Messages.

The menus are in misc/menu_templates/petscii.in.hjson, every one named petscii...; none of them leads to a stock menu. The theme is in misc/petscii_starter/ (info.emulation: petscii). Its art is plain placeholder screens, generated by dev_util/petscii_art/. Besides the starter menus’ own art it has CONNECT.seq (the stock connect menu’s art, so a PETSCII caller’s first screen is PETSCII), IDLELOG.seq (the idle logoff screen) and pause.seq (the system pause prompt).

oputil.js config new asks:

Include starter menus and theme for PETSCII (Commodore 64/128) callers? (y/N)

The answer defaults to no, which produces exactly what it always has. On yes it also:

  1. copies petscii.in.hjson into config/menus/ as <board>-petscii.hjson and adds it to the main menu file’s includes;
  2. writes <board>-login.hjson with the PETSCII branch on telnetConnected (below);
  3. copies misc/petscii_starter/ to art/themes/petscii_starter/ (an existing directory of that name is left alone);
  4. sets theme.emulations.petscii in config.hjson:
theme: {
emulations: {
petscii: {
default: petscii_starter
preLogin: petscii_starter
}
}
}

Nothing is changed for you; the same four steps by hand:

  1. Copy misc/menu_templates/petscii.in.hjson to your menus directory (for example config/menus/myboard-petscii.hjson) and add that file name to the includes list in your main menu file.

  2. Branch the connect menu. In telnetConnected (in myboard-login.hjson on a board made by config new), replace next: matrix with:

    next: [
    {
    acs: TE[petscii]
    next: petsciiMatrix
    }
    {
    next: matrix
    }
    ]

    If your telnetConnected goes somewhere other than matrix, keep that as the second entry.

  3. Copy the directory misc/petscii_starter/ into your themes directory as petscii_starter (art/themes/petscii_starter/ unless you set paths.themes).

  4. Add theme.emulations.petscii to config.hjson as shown above.

Then run ./oputil.js config validate, and restart ENiGMA½ so that the new theme is loaded.

  • On the main Telnet port, the telnetConnected branch sends a session whose terminal announced PETSCII (the TE[petscii] ACS code) to petsciiMatrix; everyone else goes on to the stock matrix as before. The connect screen itself is telnetConnected’s CONNECT art, which the starter theme has as CONNECT.seq, so a PETSCII caller sees only the version banner line before it and no ANSI art. WebSocket callers enter telnetConnected too and take the same branch.

  • On a port of its own, an additional Telnet listener with emulation: petscii and firstMenu: petsciiConnected (the same connect screen, then the matrix). No menu changes are needed for this route, and every caller on the port is PETSCII, which is what real Commodore hardware needs:

    loginServers: {
    telnet: {
    listeners: {
    c64: {
    port: 6400
    emulation: petscii
    firstMenu: petsciiConnected
    }
    }
    }
    }

    Without firstMenu, the listener’s callers enter telnetConnected and take the branch, if you added it.

  • SSH is not routed to the starter menus: SSH logs the caller in, and picks the user’s theme, before the session’s emulation is known, so a PETSCII caller over SSH keeps today’s translated ANSI menus.

After login, a PETSCII caller is asked whether to look for new messages (Y or N). On yes, every area with something new is listed in turn (petsciiNewScanMessageList): RETURN reads a message, Q goes on to the next area, X stops the scan, M marks the area read. The scan is the stock new_scan module with skipFileBase: true, so it does not go on to the file base, which has no PETSCII menus; see New Scan. The message menu offers the same scan as N.

From the main menu, M opens the message menu, which shows the current conference and area: N scans for new messages, L lists the area’s messages, P posts a message, A picks another area of the conference, J joins another conference, Q goes back. In the message list, RETURN reads the message in focus and P posts a new one.

These are the stock message modules (msg_conf_list, msg_area_list, msg_list, msg_area_view_fse, msg_area_post_fse) with 40 column art. The full-screen editor’s screen is put together from pieces of art: a header (PMSGEHDR writing, PMSGVHDR reading), the body (PMSGBODY, shared), and a footer below it (PMSGEFTR while typing, PMSGEMFT for the editor menu, PMSGVFTR while reading, PMSGFIND while asking what to find). Both headers are six rows high so the one body fits under either; the footer starts on the body’s last row. The quote builder (PMSGQUOT) is drawn below the header. When you redraw these, keep the heights, or adjust the view heights in the theme to match.

Keys for PETSCII callers, all on a Commodore keyboard:

WhereKeyDoes
Editorcursor keys, HOME, CLR (shift HOME), INST, DEL, RETURNmove, start and end of the line, insert or overwrite, delete left, new line
EditorF3, F5page up, page down
EditorF1the editor menu: S save, D discard, Q quote (replies), ? or H help; F1 again goes back to typing
EditorCTRL Ffind: type the text and RETURN; the cursor goes to the first match (the editor keeps no list of matches to step through; the stock editor behaves the same); F1 cancels
EditorCTRL Y, CTRL A, CTRL Odelete the line; edit the subject; help
HeaderRETURNnext field (To, then Subject, then the body); F1 leaves without saving
Quote builderRETURN, F1add the line in focus; done
Readercursor up and down; F3, F5scroll; page up, page down
Readercursor left and right, RETURNpick from the menu at the bottom
ReaderN, P, R, Q or F1, ?next, previous, reply, back to the list, help
ReaderCTRL Ffind: type the text and RETURN; every match is marked, the one in focus in reverse
ReaderCTRL G, CTRL Pnext match, previous match
ReaderCTRL F, then F1stop finding (clears the marks)
Lists and menuscursor keys, F3 and F5, RETURN, the bracketed letter; Q or F1move, page, pick; go back

F3 and F5 are Page Up and Page Down because the PETSCII input decoder reports them so (see What is translated). The stock menus find the next match with CTRL N, which is a cursor key on a Commodore keyboard; the starter menus use CTRL G instead.

Left out on purpose, because they need keys a Commodore keyboard does not have or lead out of the PETSCII menus: the editor’s quick-save (CTRL S is HOME there), uploading a message body, and adding a message to the download queue. Not in the starter menus yet: message search, private mail and deleting from the list.

On a board with ActivityPub areas, the new-message scan shows those areas in the same plain message list and reader as any other area, without threads, attachments or reactions, and counts what it shows as read. There is no PETSCII version of the ActivityPub browser.

Add menus to your copy of petscii.in.hjson the way you would to any menu file, using the stock menus as examples, and keep every next and action inside the PETSCII tree: a stock menu has no art in a PETSCII theme. For each new menu, add its art to the theme as a .seq file and its view layout (widths, heights, item formats) under customization.menus in the theme’s theme.hjson. Lay views out for 40 columns, and prefer vertical menus to horizontal ones.

The starter art is functional placeholder art: a title band, some text and the MCI codes the menus need. Draw your own in a PETSCII editor, save each screen under the same name as a .seq file in your copy of the theme, and adjust the layouts in its theme.hjson to match. If you make a set you are happy to share, please offer it to the project so ENiGMA½ can ship real PETSCII art.

Editors that save .seq files:

ToolNotes
PetmatePETSCII editor for Linux, macOS and Windows. Exports and imports SEQ.
Icy DrawPart of icy_tools, alongside IcyTerm. Saves PETSCII as .seq.
petcat, from VICECommand line conversion between text and SEQ files.

A .seq file is the raw PETSCII a Commodore terminal would be sent, with no header, so screens saved from a Commodore BBS work as well. See Native PETSCII art for what ENiGMA½ expects, including where to type MCI codes. The starter’s own screens are generated by dev_util/petscii_art/build.js from the descriptions in screens.js, which is one more way to make simple ones.

Art made with a PETSCII editor, or taken from a Commodore BBS, can be shown to PETSCII callers as it is. Save it as a .seq file (a Commodore sequential file: the raw PETSCII bytes, as PETSCII editors export them) under the same name as the ANSI piece it replaces, in a theme for PETSCII callers:

art/themes/my_c64_theme/theme.hjson info: { name: "My C64 Theme", emulation: petscii }
art/themes/my_c64_theme/MATRIX.seq
art/themes/my_c64_theme/LOGIN.seq
  • Selection. A PETSCII caller is given NAME.seq in preference to any other file called NAME in the same place, with the usual random selection (NAME1.seq, NAME2.seq, …). The search still goes one place at a time (theme, then default theme, then art/general), so a NAME.ans in the caller’s theme is used before a NAME.seq in the default theme: keep a PETSCII theme’s art in that theme. Translated ANSI art only reaches a PETSCII caller from those same places: once the caller has a PETSCII theme, the ANSI theme’s art is not looked at, so every menu the caller can reach needs its art in the PETSCII theme (or art/general). See Starter menus and theme. Making the art is up to you; the stock ANSI art is not designed for 40 columns.

  • ANSI callers never get .seq art. A .seq file sitting beside .ans files changes nothing for them, even in a theme they use. Art named with its extension (art: MATRIX.seq) shown to an ANSI caller anyway is shown as plain text, never as PETSCII bytes.

  • The bytes go out as they are. Colours, reverse video, cursor movement, HOME and CLR in the file all work as on a Commodore. ENiGMA½ follows them so that views drawn afterwards land in the right place. Art is not paged (pause: pageBreak shows it whole), and no ANSI preparation is applied to it.

  • Screen size. Draw for 40x25 (C64) unless you know your callers use 80 columns. The Commodore screen wraps to the next row as soon as the last column is written, and writing the bottom row’s last cell scrolls the screen; a RETURN at the very end of the file is dropped when it would scroll.

  • Character set. A Commodore screen shows one of two character sets at a time: lower/upper case (ENiGMA½’s default) or upper case and graphics. A .seq file is drawn in lower/upper unless it says otherwise, either with its own set switch byte (0x0E lower/upper, 0x8E upper/graphics) or through the art’s encodedAs option, set in the menu’s config block (in menu.hjson, or in the theme’s entry for that menu):

    encodedAsCharacter set
    petscii or petscii_lower (default)lower/upper case
    petscii_upperupper case and graphics

    The set applies to the whole screen, so art drawn in upper/graphics keeps it until the next clear screen; text ENiGMA½ writes over it in the meantime is shown in capitals. The clear switches back to lower/upper. A menu that uses encodedAs: petscii_upper and falls back to an ANSI file ignores the setting.

  • MCI codes are typed into the art as ordinary characters, as in ANSI art: %TL1, %ET2, %VM1, and so on (see MCI Codes). The letters may be typed shifted or not; in the lower/upper set either way works, %tl1 is %TL1. In upper/graphics, type them unshifted (shifted letters are graphics there). A view takes the colour and reverse video in effect where its code was typed. PETSCII has no background colour.

  • SAUCE is not expected in .seq files; if one is present it is removed and not shown. Trailing 0x1A bytes (the padding an XMODEM transfer adds) are removed too.

You do not need a Commodore to try this.

  • SyncTERM: edit the directory entry and set Screen Mode to C64, C128 (40col) or C128 (80col), with Connection Type Telnet. That is what makes SyncTERM a PETSCII terminal and announce itself as one. Choosing only a Commodore Font and leaving Screen Mode alone gives an ANSI terminal drawn in a Commodore font: ENiGMA½ sees an ANSI caller, and letter keys may do nothing.
  • IcyTerm: choose the PETSCII emulation for the entry, with Telnet.
  • A dedicated port (an additional listener with emulation: petscii) treats every caller as PETSCII whatever the terminal announces, which is the quickest way to tell a detection problem from a display problem.

To see what a session was given, look in the log for the caller’s terminal type and emulation: a session that asked for an emulation ENiGMA½ does not have is logged as falling back to ANSI.

Keys to know when testing: F1 is Escape, F3 and F5 are Page Up and Page Down. IcyTerm sends its function keys in a different order from a Commodore and SyncTERM, so in IcyTerm paging is on F2 and F3. SyncTERM’s End key sends the Commodore CLR code, which ENiGMA½ treats as End.

  • Text is mapped to PETSCII’s lower and upper case character set. Box and block drawing characters become the nearest PETSCII graphics; a character with no equivalent becomes ?.
  • Colour. The 16 ANSI foreground colours map to the 16 Commodore colours. PETSCII has no background colour, so a background is shown as reverse video in that colour.
  • Cursor movement. PETSCII has no “go to row, column”. ENiGMA½ tracks the cursor and sends relative moves.
  • Screen size is what the terminal reports, otherwise 40x25.
  • Keys. Cursor keys, HOME, INST/DEL (backspace), RETURN, F2, F4, F6, F7 and F8 work as their ANSI equivalents. CLR, which SyncTERM sends for the End key, is End.
  • F1 is Escape; F3 and F5 are Page Up and Page Down. A Commodore keyboard has no Escape, Page Up or Page Down key, and ENiGMA½ reaches some things only through them (the full-screen editor’s menu and backing out of a form; paging through a message or a list). For a PETSCII caller, F1 is the Escape key, F3 is Page Up and F5 is Page Down. A terminal that also sends a real Escape byte (SyncTERM and IcyTerm do) works too. This holds for every PETSCII session, whatever menus it is in: the starter menus, menus of your own behind a PETSCII listener, or the stock menus. F1, F3 and F5 as such are therefore not available to PETSCII callers, so do not bind anything a PETSCII caller needs to f1, f3 or f5. (IcyTerm numbers its function keys in a row, so for its users Page Up and Page Down are on F2 and F3.)
  • Nothing is asked of the terminal at connect, so there is no feature detection pause.
  • The stock menus and art are laid out for ANSI. On a board with no PETSCII theme, expect wrapped art on a 40 column screen. The starter menus cover connecting, logging in, messages, who’s online and last callers; anything more needs menus and art of your own. A theme declares emulation: petscii in its info block to be used for these callers.
  • A form is chosen by the MCI codes in its art: a 40 column screen that leaves a view out needs a matching form in the theme.
  • Art that is not shown through a menu or prompt (achievement and node message headers and footers, for example) uses the ANSI art, translated, or plain text from a .seq file named with its extension.
  • No hyperlinks, fonts, blink or underline.
  • The bottom right screen cell is never drawn, because writing it scrolls a Commodore screen.
  • Some control key combinations do not exist on a Commodore keyboard: Ctrl with E, N, Q, R, S or T share their codes with colour, cursor and delete keys. Nor do Page Up, Page Down (F3 and F5 stand in for them), Delete (as opposed to backspace) or function keys other than F1 to F8, and F1 is Escape. Menus for PETSCII callers should not rely on any of them.
  • Doors expect an ANSI terminal. A door’s output is translated like any other output, but its input is not: the door receives PETSCII key codes, so cursor and function keys will not work in it, and most doors assume 80 columns. Use the TE ACS code to keep doors away from PETSCII callers, for example TE[ansi] on a door menu entry.
  • File transfers, and bridged connections such as the Telnet bridge and door networks, are passed through untranslated in both directions.
  • A window resize during a session is not followed; the size is settled at connect, up to 160x100.