Command Line

fantasm [command] [options] <source> [output]

Both command and output are optional, so the shortest useful invocation is fantasm main.asm. In a directory holding a fantasm.toml, fantasm build is enough.

fantasm with no arguments at all prints a usage summary and builds nothing, even with a project file beside it. Any argument is enough to start a build — fantasm build, fantasm -n and fantasm --all all assemble — but the bare word does not.

Anything given here beats the same setting in the project file. fantasm --help prints the same list in brief.

Commands

Command
buildAssemble. This is the default, so it can be left out.
initCreate a fantasm.toml and a stub source file.

Output Destination

fantasm build main.asm            # -> main.bin
fantasm build main.asm game.nex   # -> game.nex

The second positional argument names the output. Left out, the name comes from the source’s stem and the format’s extension.

Naming a source turns off project-file auto-detection. fantasm build one.asm in a directory containing fantasm.toml ignores the file. Pass -p fantasm.toml if you meant to use both.

The Machine

Option
-d, --devicezx16, zx48, zx128 or zxnext. zxnext enables Z80N.
--ramRAM variant: 2mb, 1mb, 512k, or a bare number in KiB.
-f, --formatbin, hex, sna or nex.

The machine is a device, and a target is an image the project builds. -t, --target, !target and the target key were all the machine; each still works and says what replaced it once (W1103), and each is withdrawn in 2.1. [[target]] is unchanged.

The unused-label sweep was likewise renamed-W, --enable-warnings, --no-warnings and the warnings key became -u, --find-unused, --no-find-unused and find_unused, on the same terms.

-I and -e were considered and kept. -I, --include takes a directory where INCLUDE takes a file — but -I is the spelling every C compiler and Z80 assembler uses, and its help now says what it takes. -e, --export-labels is a verb where --sld and --reloc are nouns, and grouping the three under one heading already made them read as a family; --labels would say less about what lands in the file.

device is now a reserved word, and costs almost nothing. A label, a STRUCT member, an ENUM member, a MODULE and a !library may all still be called device; only a macro’s name and a macro’s parameters may not. See Diagnostics for the whole table.

An unknown machine is a warning, not an error. -d zx81 builds, having said so once. If a build behaves as though the setting never took, check the spelling.

--ram narrows the paging range rather than describing the hardware, so a bank beyond it becomes an assembly error — --ram 512k allows banks 0–31 and refuses bank 32. Set it to the smallest machine you intend to support and the build tells you when you exceed it, instead of the machine’s owner doing so.

Assembly Options

Option
-I, --includeAdd a directory to search for INCLUDE and INCBIN. Repeatable.
-D, --defineDefine a constant. Repeatable.
-O, --originWhere assembly starts, if the source has no ORG.
-M, --max-code-sizeRefuse a build emitting more code than this.
-N, --z80nZ80N extended instructions.
-c, --cspectCSpect’s exit and break pseudo-ops.
-i, --case-insensitiveTreat Loop and loop as one name.
--gc-modulesDiscard MODULE code the program never reaches.
--gc-librariesThe same for !library code alone, leaving a placement MODULE.

-O and -M take a number written any way the source may write one36864, 0x9000, $9000, 9000h, %1001, with _ between digits. See Writing Source. --ram is the exception, being a size with a unit rather than a number.

-D takes three forms:

fantasm main.asm -D DEBUG=1        # a number, hex accepted: -D BASE=0x4000
fantasm main.asm -D NAME=nightly   # text, assemblable with db and dz
fantasm main.asm -D FLAG           # no value, for IFDEF

--gc-modules is off unless asked for: a wrongly discarded routine is a crash at run time rather than a failure at build time, so it is not something to have on by accident. Pin anything reached only indirectly with KEEP.

Output and Artifacts

Option
-e, --export-labelsWrite a symbol list to this file.
--sldWrite Source Level Debugging data to this file.
--relocWrite what a loader must patch to relocate the image.
--report-discardsWrite what the dead-code sweep removed to this file.

-e writes only GLOBAL symbols. The file is empty until something is exported — that is intended, and the .sld file is what a debugger reads.

Project File Options

Option
-p, --projectUse this fantasm.toml.
--onlyBuild only this target and what it depends on. Repeatable.
--allBuild every target, including those marked default = false.

See The Project File and Building Several Images.

The --no- Forms

Every option carrying an [assembler] setting has a --no- twin:

--no-z80n  --no-cspect  --no-case-insensitive  --no-find-unused  --no-verbose
--no-gc-modules  --no-gc-libraries

They exist because the project file could otherwise only ever turn a setting on. With gc_modules = true in fantasm.toml, one build without it used to mean editing the file:

fantasm --no-gc-modules

The last flag given wins, so --gc-modules --no-gc-modules is off.

Diagnostics and Output

Option
-u, --find-unusedRun the unused-label sweep.
-v, --verbosePer-file progress, timings and task echo. Twice for what the build decided.
-n, --nologoSuppress the banner.
--colorauto, always or never.

--color defaults to auto, which is colour to a terminal and none to anything else. A build piped into a file or another program carries no escape sequences, so a log stays greppable; always keeps them for a pager that understands them.

-u turns on that one sweep, and --no-find-unused turns off that one sweep. Neither reaches any other warning, all of which are shown regardless. It was spelt -W/--enable-warnings/--no-warnings until 2.0, which read as all warnings on and all warnings off and never meant either. See Diagnostics.

It sits with the sweeps rather than with -v because it decides what is computed: finding unused labels means walking every recorded usage, which a build does not do unless asked.

-v is a progress log; -vv is what the build decided. One says what the assembler is doing, the other what it worked out and could not otherwise be asked:

Detail: Code size 9 of 65536 bytes (0%), against this machine's ceiling
Detail: Gfx placed at 0x8007..0x8008, 1 byte

The ceiling named is the machine’s, or -M’s where that asked for less. A MODULE or !library body is placed after the program, so the address it runs at is not the one you read in the source — see Modules.

A project file’s verbose = true means one level. Only -vv reaches the second; a file cannot ask for it.

-n is what a script wants. It suppresses the banner, and also the throttled update notice, which is not something a build log should carry. There is no -q: a build that succeeds under -n says nothing already.

Testing

Option
--testRun !test blocks against the emulated CPU after assembling.

With several targets, counts are reported against the target the tests came from — see Building Several Images.

Standalone Actions

Option
-V, --versionPrint the version and exit.
-h, --helpPrint the option list and exit.
--lspStart the language server on stdio.
--check-updatesCheck for a newer release and exit.

--lsp is how an editor drives FantASM. It speaks JSON-RPC over stdin and stdout; the banner is not printed in this mode and logging goes to stderr, so --nologo is not needed. See The Language Server.

init

fantasm init
fantasm init --name starfield --device zxnext --format nex --main src/main.asm
Option
--nameProject name.
--deviceDefault machine.
--formatDefault output format.
--mainEntry-point filename.
--forceOverwrite existing files without asking.

Anything not given is asked for. FANTASM_INTERACTIVE=false suppresses every prompt and takes the defaults instead, which is what a script wants. Without --force, an existing fantasm.toml or source file stops it.

--force has no short form. -f is --format everywhere else, and one letter meaning two things is unlearnable however unambiguous each use is on its own. init -f still works and says so (W1103), and is withdrawn in 2.1.

Environment

Variable
Z80_INCLUDEColon-separated directories added to the include search path.
FANTASM_INTERACTIVEfalse suppresses init’s prompts.
FANTASM_NO_UPDATE_CHECKSet to disable the startup update notice.

Exit Status

0 on success. Non-zero if anything failed — including, with several targets, if any target failed or was skipped.

Documentation