On the Commodore 128, the built-in BASIC saves programs tokenized. How can I save (and then later load) the programs as ASCII instead?

For example, like the ",A" option in GW-BASIC or the LIST/ENTER commands offered by Atari BASIC.

  • What does "tokenized" mean in this context?
    – d-b
    Mar 14, 2021 at 17:57
  • 9
    @d-b Tokenized - Key words are replaced with binary representations (instead of being spelled out) even though text portions are still in PET(A)SCII Mar 14, 2021 at 18:26

3 Answers 3


(This answer is about using the built-in methods on real hardware. If it's about conversion of emulator files, then Brian's solution may be more suitable.)


Saving a program as text onto a disk file (real or emulated) is essentially listing it, but redirecting output to a file - much like when printing it (on a real printer):

OPEN 1, 8, 2, "0:filename, S, W" : CMD 1 : LIST

This should work for all Commodore machines (*1).

In Detail:

  • OPEN 1, 8, 2, "0:filename, S, W"

    OPENs a file, using handle 1, on device 8 (first drive on a C64/128), for writing (2). The file is to be located on drive 0: (can be omitted on regular 1541 drives) and named filename. It is to be handled as Sequential file (records ending with CR) and Written, i.e. it's written from start and overwritten if already existing.

  • CMD 1

    CMD (Change Main Device) redirects all following output to the handle given. Here, that's the file we just opened.

  • LIST

    Well, LISTs your program

(At this point I always use a second line, if I don't do each separately anyway. I really don't remember why. Maybe some C= buff knows?)

  • PRINT#1

    PRINTing an empty line to handle 1 redirects default output back to the screen (and adds a CR at the end).

  • CLOSE 1

    CLOSEing the handle will flush whatever might be left in drive buffers

If the file you're saving onto is in some emulation or on a SD card or the like, it's ready to be used.


Keep in mind that the output will be in PETSCII encoding (*2), plus some quirks added due to the way this works, like (IIRC)

  • a line spelling 'Ready' at the end,
  • optional empty lines and
  • leading spaces.

So whatever you use for further processing might need to take care of that and translating to standard ASCII (or whatever the target system uses) as well.

*1 - 8-bit ones, that is :))

*2 - Michael Steil has, as so often the most comprehensive tables for all Commodore(*1) variants including screen and keyboard codes.

  • 1
    Technically, this doesn't answer the question; the question asks for ASCII, but PETSCII. I know they're mostly the same, but technically… Plus, I get the impression that pi might be mapped to 0xFF in this listing.
    – wizzwizz4
    Mar 14, 2021 at 13:07
  • 1
    This doesn't work on my Commodore Amiga.
    – Tim Locke
    Mar 14, 2021 at 13:33
  • 1
    @TimLocke True. Was waiting for that ... or alternative PC-10 or CBM900 :)) But yeah, Amiga BASIC just needs an attached ,A to get it done - in rather plain ASCII if I may add .
    – Raffzahn
    Mar 14, 2021 at 14:22
  • 1
    @BrianKnoblauch I installed Vice (will delete it soon) and played a bit. Seems that the problem is due to the 'true drive emulation' setting. (Setting->Perhiperal devices->Drives). Clearing that flag makes it work without error message and a sequential file will show up.
    – Raffzahn
    Mar 14, 2021 at 20:05
  • 1
    Interesting. I'll have to play around with it some more. I have TrueDrive off already, but I have host filesystem on, I wonder if that's the issue with my setup. Strange thing to have issues with. Very interesting. Mar 15, 2021 at 22:04

If you have a mechanism for moving files to and from a modern computer, then you can use bastext to transcode most variations of Commodore 8-bit BASIC between ASCII and tokenized forms.

This is an open source project found on Github. The options it provides should meet most needs. Note the -7 option if you want to force the use of the BASIC 7.0 syntax. This is only needed if, for some reason, your .PRG file doesn't have the normal C128 BASIC load address of $1C01.

$ ./bastext -h
Usage: ./bastext -i|-o|-h [modifiers] infile(s) outfile

 Mode (one of these required):
  -i    Input mode (binary to text)
  -o    Output mode (text to binary)
  -h    Print help page

 General modfiers:
  -t    T64 mode (in: reads from specified T64 archive(s)
                  out: creates/appends to bastext.t64)

 Input mode modfiers:
  -a    Convert all, not just recognized start addresses
  -s    Strict tok64 compatibility
  -d fn Send output to file fn

 Output mode modifiers:
  -2    Force C64 BASIC 2.0 interpretation
  -3    Force C64 TFC3 interpretation
  -5    Force C64 Graphics52 interpretation
  -7    Force C128 BASIC 7.0 interpretation
  -1    Force C128 BASIC 7.1 interpretation
  • Interesting. Not an ideal fit for the pipeline I have in mind, but I may end up using it, thanks! Mar 14, 2021 at 15:33

As an alternative to Brian H's answer, I should also point out the petcat tool which comes with the VICE emulator and supports converting between tokenized Commodore BASIC, PETSCII, and ASCII with PETSCII special characters replaced with mnemonics like {left}.

        petcat V2.21 PL 1 -- Basic list/crunch utility.
        Part of vice 2.4.25

Usage:  petcat  [-c | -nc]  [-h | -nh]  [-text | -<version> | -w<version>]
                [-skip <bytes>] [-l <hex>]  [--] [file list]

   -help -?     Output this help screen here
   -v           verbose output
   -c           controls (interpret also control codes) <default if textmode>
   -nc          no controls (suppress control codes in printout)
                <default if non-textmode>
   -ic          interpret control codes case-insensitive
   -qc          convert all non alphanumeric characters inside quotes into controlcodes
   -d           output raw codes in decimal
   -h           write header <default if output is stdout>
   -nh          no header <default if output is a file>
   -skip <n>    Skip <n> bytes in the beginning of input file. Ignored on P00.
   -text        Force text mode
   -<version>   use keywords for <version> instead of the v7.0 ones
   -w<version>  tokenize using keywords on specified Basic version.
   -k<version>  list all keywords for the specified Basic version
   -k           list all Basic versions available.
   -l           Specify load address for program (in hex, no leading chars!).
   -o <name>    Specify the output file name
   -f           Force overwritten the output file
                The default depends on the BASIC version.

        1       PET Basic v1.0
        2       Basic v2.0
        superexp        Basic v2.0 with Super Expander (VIC20)
        turtle  Basic v2.0 with Turtle Basic v1.0 (VIC20)
        simon   Basic v2.0 with Simon's Basic (C64)
        speech  Basic v2.0 with Speech Basic v2.7 (C64)
        a       Basic v2.0 with @Basic (C64)
        40      Basic v4.0 (PET)
        4e      Basic v4.0 extension (C64)
        3       Basic v3.5 (C16)
        70      Basic v7.0 (C128)
        10      Basic v10.0 (C65/C64DX)
        f       Basic v2.0 with Final Cartridge III (C64)
        ultra   Basic v2.0 with Ultrabasic-64 (C64)
        graph   Basic v2.0 with Graphics basic (C64)
        wsb     Basic v2.0 with WS basic (C64)
        mighty  Basic v2.0 with Mighty Basic (VIC20)
        pegasus Basic v2.0 with Pegasus basic v4.0 (C64)
        xbasic  Basic v2.0 with Xbasic (C64)
        drago   Basic v2.0 with Drago basic v2.2 (C64)
        reu     Basic v2.0 with REU-basic (C64)
        lightning       Basic v2.0 with Basic Lightning (C64)
        71      Basic v7.1 (C128)
        magic   Basic v2.0 with Magic Basic (C64)
        easy    Basic v2.0 with Easy Basic (VIC20)
        blarg   Basic v2.0 with Blarg (C64)
        4v      Basic v4.0 (VIC20)
        5       Basic v5.0 (VIC20)
        wsf     Basic v2.0 with WS basic final (C64)
        game    Basic v2.0 with Game Basic (C64)
        bsx     Basic v2.0 with Basex (C64)
        superbas        Basic v2.0 with Super Basic (C64)
        exp64   Basic v2.0 with Expanded Basic (C64)
        sxc     Basic v2.0 with Super Expander Chip (C64)
        warsaw  Basic v2.0 with Warsaw Basic (C64)
        exp20   Basic v2.0 with Expanded Basic (VIC20)
        supergra        Basic v2.0 with Supergrafik 64 (C64)
        k       Basic v2.0 with Kipper Basic (C64)
        bb      Basic v2.0 with Basic on Bails (C64)
        eve     Basic v2.0 with Eve Basic (C64)
        tt64    Basic v2.0 with The Tool 64 (C64)

        Usage examples:
        petcat -2 -o outputfile.txt -- inputfile.prg
                De-tokenize, convert inputfile.prg to a text file
                in outputfile.txt, using BASIC V2 only
        petcat -wsimon -o outputfile.prg -- inputfile.txt
                Tokenize, convert inputfile.txt to a PRG file
                in outputfile.prg, using Simon's BASIC
        petcat -text -o outputfile.txt -- inputfile.seq
                Convert inputfile.seq to a Ascii text file
                in outputfile.txt.
        petcat -text -w2 -o outputfile.seq -- inputfile.txt
                Convert inputfile.txt to a Petscii text SEQ file
                in outputfile.seq.
  • Oh, I like that idea if I can't get the direct write to disk working. Easier than getting setup with gcc so I could compile bastext too! Mar 15, 2021 at 22:05
  • 1
    @BrianKnoblauch If generating a disk image would help, the "code in Vim, run in VICE" setup I've been meaning to get back to for experimenting with C64 programming (I'm more a "write utilities for platforms like DOS and Win16" retro-programmer) pairs it with c1541, another tool that comes with VICE for constructing/manipulating Commodore disk images. (c1541 -format "${PRG_NAME},id" d64 "${PRG_NAME}.d64" -attach "${PRG_NAME}.d64" -write "${PRG_NAME}.prg" "${PRG_NAME}.d64" "${PRG_NAME}" assuming I didn't transcribe my c64_bas_to_vice.py script to shell incorrectly.)
    – ssokolow
    Mar 16, 2021 at 1:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .