FantASM 1.9.0 is available
FantASM 1.9.0 is available to download. One project file can now build several images, the language server finally knows what machine you’re targeting, and there are four breaking changes — read those first.
The documentation has been rewritten alongside it.
Breaking changes
- Invalid address or bank is now
E1082, notE1049.1049named both that error and the unused label warning, so looking it up found whichever entry came first. The warning keeps the number. - NEX entry point … has no code is now
W1083, notW1060. Same story:1060named both that warning and reserved word used as a macro name. The error keeps the number. [assembler] formatnow takes effect. It was parsed and ignored, so a project file sayingformat = "nex"produced whatever the output extension implied. Check any project file whoseformatand output extension disagree;-fstill wins.Assembler::parsed_lines()and theParsedLinetype are removed. Only a Rust program embedding FantASM is affected — the command line is unchanged.
Several images from one project file
A program that is more than one file — a payload and the loader that incbins it, or a release and a debug variant — can now be declared once and built in one run:
[[target]]
name = "loader"
main = "src/loader.asm"
output = "build/game.nex"
depends = ["payload"]One fantasm builds every target in dependency order. --only NAME builds one and what it depends on; --all adds targets marked default = false. A target that fails skips its dependents and nothing else, naming each skipped one with its reason. Dependency cycles are refused (E1077), as is an incbin of a target’s output left out of depends (E1078), or two targets writing the same file. A project file with no [[target]] is unaffected.
Also new
- The language server takes a target from the editor, via
initializationOptions—{"target": "zxnext"}. A Next project no longer showsE1016on every Z80N instruction. --gc-moduleswith--testsays when a routine only a!testcalls has been swept (W1084), instead of leaving the test to fail with Execution timed out or failed to halt.- A
printin a!rhaiblock files a diagnostic, so it shows in your editor rather than only in the language server’s output pane. - Digit separators —
65_536,0b1010_1010,$FF_FF. EQUholds and joins text —BANNER equ __NAME__ + " v" + __VERSION__— andSIZEOFanswers its length in the bytesdbwould emit.- A
--no-form for every valueless flag, so a setting turned on in[assembler]can be turned off from the command line. The last flag given wins. #ifexists, completing the#-prefixed conditionals, andIFtakes an expression rather than onlyIF <constant> = <value>.- A failing
--testnames the test and what it expected against what it got, without needing-v.
Fixed
The ones that were wrong output, silently:
- A label called
pageorbankwas silently replaced by the builtin of that name, socall pageassembled a call to the current page number instead of to your label. - A constant or label named after a directive —
message,end,block,hex— worked in some operand positions and not others:call messageassembled whileld hl,messagewasE1005. --sldrecorded aMODULEbody where it was written rather than where it was placed, so a breakpoint inside a module went to ROM and never hit.!nex bank <n>was ignored for every bank but10,5,2and the one currently selected.!messagediscarded anything after its template, so!message "T States: ", _tstatesprinted the string and dropped the value.
The full changelog has the rest. Test coverage expanded from 575 to 742 tests.
New documentation
The docs have been rewritten and restructured — including a page on using FantASM as a library from Rust, and how assembly works, which explains why most surprising behaviour is the gather/decide/emit pipeline showing through. Code samples throughout are now highlighted with the same grammar the 0x1DE editor extension uses.
Get it from the Downloads page.