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/Pasta80README

PASTA/80
PASTA/80 is a simple Pascal cross compiler targeting the Z80 microprocessor. It generates code for these classic and modern machines:
- CP/M
- ZX Spectrum 48K
- ZX Spectrum 128K
- ZX Spectrum Next
- Agon Light/Console8 (early access, please expect issues)
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,RealandString). array of,record,set of, enumerations, subranges and pointers as a way of building new data types.- The decision-making elements
if..then..elseandcase..of. - The loop elements
for..do,while..doandrepeat..until. - The
with..donotation for "opening" records. procedureandfunctionincluding value andvarparameters and nesting.- The standard procedures for screen input and output (i.e.
ReadLn,WriteLnetc.). - 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) andText. - A dynamic heap of up to 32767 bytes with
GetMem,FreeMem,NewandDispose. - 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, checkIOResultafter 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). BreakandContinuefor loop control.- An optional parameter for
Exitin functions that assigns the result (likeExit(42)). - Querying the keyboard via
KeyPressedandReadKey. - Color support via
TextColorandTextBackgroundwith constants for the 8 Spectrum Next colors. IncandDecfor more efficient increasing and decreasing of variables.IncludeandExcludefor more efficient handling of sets.- Enumeration types can be used in
Read[Ln],Write[Ln],ValandStr. - A simple
Assertfacility that counts passes/fails and shows the failed line number. - Breakpoints by means of
Debugstatements 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/Releaseare not currently supported.- The standard files
Input,Output,Kbd,ConandLstare not supported. ChainandExecuteare 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 |
| :-------: | :----: |
|
|
|
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!) |
| :-------: | :----: |
|
|
|
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
pestel-analysis
Analyze political, economic, social, technological, environmental, and legal forces
orbit-planning
O.R.B.I.T. - strategic project planning before you build. Objective, Requirements, Blueprint, Implementation Roadmap, Track.
next
A beautifully designed, floating Pomodoro timer that respects your workspace.
product-manager-skills
26PM skill for Claude Code, Codex, Cursor, and Windsurf: diagnose SaaS metrics, critique PRDs, plan roadmaps, run discovery, and coach PM career transitions.
