SkillAgentSearch skills...

Pasta80

Turbo Pascal 3.0-compatible compiler that generates machine code for classic and modern Z80 machines (currently CP/M, the Sinclair ZX Spectrum 48K/128K/Next, and the Agon Light/Console8).

Install / Use

/learn @pleumann/Pasta80
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Logo

PASTA/80

PASTA/80 is a simple Pascal cross compiler targeting the Z80 microprocessor. It generates code for these classic and modern machines:

The compiler follows the single-pass recursive-descent approach championed by Niklaus Wirth, inventor of Pascal, in his books and lectures. It doesn't have an explicit syntax tree, but instead generates code on the fly during parsing. As a result, the compiler might not always generate the most efficient code possible (it definitely cannot compete with LLVM and doesn't try to), but it's very fast.

Supported language elements

The supported Pascal dialect is an almost exact clone of the original Turbo Pascal 3.0 for CP/M (see this manual for details). So you have at your disposal the following language elements:

  • All the basic data types (Boolean, Byte, Char, Integer, Pointer, Real and String).
  • array of, record, set of, enumerations, subranges and pointers as a way of building new data types.
  • The decision-making elements if..then..else and case..of.
  • The loop elements for..do, while..do and repeat..until.
  • The with..do notation for "opening" records.
  • procedure and function including value and var parameters and nesting.
  • The standard procedures for screen input and output (i.e. ReadLn, WriteLn etc.).
  • All conversion and utility procedures and functions that Turbo Pascal 3.0 had.
  • The three kinds of disk files, that is untyped (file), typed (file of) and Text.
  • A dynamic heap of up to 32767 bytes with GetMem, FreeMem, New and Dispose.
  • Inline assembly (via opcodes, not via mnemonics, so this page might be handy).
  • Overlays (in memory, Spectrum 128K and Next only, see below).
  • Some compiler directives:
    • $i <file> for including Pascal source files (including nesting and cycle detection)
    • $l <file> for including an assembly file (aka "linking" a library)
    • $a(+/-) for enabling or disabling absolute mode (default is on, disable for recursion)
    • $i(+/-) for enabling or disabling IO checking (when off, check IOResult after calls)
    • $k(+/-) for enabling or disabling stack overflow checking
    • $u(+/-) for enabling or disabling Ctrl-C checking

The compiler also has some features that were borrowed from or inspired by later versions of Turbo Pascal:

  • C-style // one-line comments in addition to {..} and (*..*).
  • Binary literals (using a % prefix).
  • Break and Continue for loop control.
  • An optional parameter for Exit in functions that assigns the result (like Exit(42)).
  • Querying the keyboard via KeyPressed and ReadKey.
  • Color support via TextColor and TextBackground with constants for the 8 Spectrum Next colors.
  • Inc and Dec for more efficient increasing and decreasing of variables.
  • Include and Exclude for more efficient handling of sets.
  • Enumeration types can be used in Read[Ln], Write[Ln], Val and Str.
  • A simple Assert facility that counts passes/fails and shows the failed line number.
  • Breakpoints by means of Debug statements in the source code (which can optionally have a condition for the trigger).

Since that covers most of the functionality of Turbo Pascal 3 you might ask what is missing. These are the current limitations:

  • All the remaining compiler directives are not yet supported.
  • Mark/Release are not currently supported.
  • The standard files Input, Output, Kbd, Con and Lst are not supported.
  • Chain and Execute are not supported.
  • Add-on libraries from the PC version of Turbo Pascal 3.0 are not yet supported (although there are a few graphics primitives for the ZX targets).
  • The new instructions of the Z80N CPU inside the ZX Spectrum Next are not yet being leveraged.
  • No separate compilation. Everything is compiled from source, always.
  • Binary size is quite large compared to the original.

The runtime library, being partially written in Pascal itself, gets quite large when compiled. I hope to bring this down again by reimplementing more of it in Z80 assembly (or improve the code generator, which, although it has a peephole optimizer, is not generating super-efficient Z80 code).

Building and setting up the compiler

The compiler is itself written in Pascal. You can compile it with Free Pascal (I use version 3.2.2). Just run

$ fpc pasta

The Pascal compiler generates Z80 assembler code and relies on sjasmplus as a backend for the final translation step to binary. It can also, in --ide mode (see below), make use of various other external tools. The compiler tries to detect these external tools automatically (from your system's PATH), but sometimes it's best to create a file .pasta80.cfg in your home directory specifying necessary paths (there is a sample in misc that you can adapt).

# PASTA/80 config

HOME      = ~/Spectrum/pasta80
ASSEMBLER = ~/Spectrum/sjasmplus/sjasmplus
...

You can check your whole setup by calling the compiler with --config. It will show the full paths of all internal and external requirements and whether they are fulfilled.

Using the compiler

To run the compiler just invoke the executable with the name of a Pascal source file to translate.

CP/M target

The default target is CP/M. There is an optional parameter that enables some simple peephole optimizations and another one that uses dependency analysis to eliminate unused Pascal procedures and functions:

$ pasta hello.pas             # Compiles hello.pas to hello.com
$ pasta hello                 # Source file .pas suffix is optional
$ pasta --opt hello.pas       # Enables peephole optimizations
$ pasta --opt --dep hello.pas # The same plus dependency analysis

You can run the resulting .com files on a real CP/M machine or in a CP/M emulator. I recommend the excellent tnylpo. For programs that use VT52 control codes you have to start tnylpo in full-screen mode:

$ tnylpo hello                # Run in line-mode
$ tnylpo -s -t @ hello        # Monochrome full-screen, wait when finished
$ tnylpo -soy,4,0 -t @ hello  # Color full-screen, wait when finished

| "Hello, World" in line mode | "Hello, World" in full-screen | | :-------: | :----: | | Screenshot | Screenshot |

ZX Spectrum targets

To generate binaries for the ZX Spectrum 48K, 128K and Next targets, use the --zx48, --zx128 and --zxnext parameters, respectively.

$ pasta --zx48 hello.pas      # Compiles for ZX Spectrum 48K
$ pasta --zx128 hello.pas     # Compiles for ZX Spectrum 128K
$ pasta --zxnext hello.pas    # Compiles for ZX Spectrum Next

The main difference between the three (currently) is that the ZX Spectrum Next target supports file IO (on the SD card), while the other two do not. The remaining routines are mostly the same. Screen output is handled via rst $10 in the ROM. In both cases the binaries are expected to be run from address 0x8000.

Tapes, snapshots and runnable directories

The default output format for the ZX Spectrum targets is a simple binary file that contains exactly the bytes of the compiled program (plus a +3DOS header when compiling for the Spectrum Next). In addition to that (and for more complex cases involving overlays), the compiler can also generate snapshot files or tape files, the latter including a suitable BASIC loader:

$ pasta --zx48 --sna examples/hello.pas   # .sna file
$ pasta --zx48 --tap examples/jacques.pas # .tap file with BASIC loader

Being self-contained, snapshots and tapes are a convenient way to distribute your programs and to launch them an emulator, such as Fuse:

$ open -a Fuse examples/hello.sna         # Launch .sna file in FUSE (on Mac)
$ open -a Fuse examples/jacques.tap       # Launch .tap file in FUSE (on Mac)

| Hello world in FUSE | Frere Jacques in FUSE (yes, with sound!) | | :-------: | :----: | | Screenshot | Screenshot |

When compiling for the Next, another useful format is a runnable directory. It contains exactly the same files that would also be in the .tap file, including a BASIC loader named run.bas.

$ pasta --zxnext --run examples/pq.pas    # Results in directory named pq.run

The directory has the suffix .run. When attempting to enter such a directory in the Next's file browser, the loader is started automatically (press Symbol Shift + Enter to really see the contents). If you are a Mac user: Yes, it's a bit like an .app bundle.

Agon Light/Console8 target

To generate a MOS binary for the Agon target(s), use the --agon parameter.

The Agon target is more or less en par with the CP/M target, supporting all the core features plus files (all three types of) and command line parameters. There are also a few graphics primitives that would allow you to run or port some of the graphics examples (like the 3D hat or the Mandelbrot set). It is fully integrated into mini IDE and supports emulation and debugging (see below).

Note that t

Related Skills

View on GitHub
GitHub Stars166
CategoryProduct
Updated1d ago
Forks7

Languages

Pascal

Security Score

80/100

Audited on Mar 25, 2026

No findings