FantASM 2.0.0 is available
FantASM 2.0.0 is available to download. The editor now answers with what the build answers. Libraries get a real interface, tests get spans and checksums, and 59 new diagnostic codes say what is wrong rather than sharing one number between five faults.
This is a major version and the breaking changes are worth reading before you upgrade — most of them refuse source that used to assemble, quietly, into something you did not mean.
Breaking
- The machine is a
device, not atarget.-d/--device,!device,[assembler] deviceand{_device}replace thetargetspellings. Each old one still works, says so once (W1103), and goes in 2.1.[[target]]is unchanged. - The unused-label sweep is
--find-unused, not--enable-warnings.-u,--no-find-unusedandfind_unusedreplace thewarningsspellings, which never turned any other warning on or off. INCLUDEno longer searches the working directory first. A basename finds the file beside the including source, so a build is the same whereverfantasmis run from. Name the directory, or add it with-I.- A
binwhose code is not contiguous is refused (E1085). It used to write a file where a label pointed at the wrong byte. Assemble each region separately and combine them. - A label must start at column 0 (
E1093). An indented name that is no instruction, directive or macro is refused. Locals, constants and names inside a macro body are unaffected. - A macro’s name at column 0 defines a label rather than expanding (
W1094). Indent the call. repis a directive, so it may not name a macro (E1060). Rename the macro; labels andSTRUCTmembers still take the word.assertanddebugare directives, so neither may name a macro (E1060). Same fix, same exemptions.- An index displacement outside -128 to 127 is refused (
E1123).ld a,(ix+200)used to assemble asld a,(ix-56)in silence. - A
!testcommand outside a!testblock is refused (E1122). They were accepted anywhere and discarded, so an assertion past its!endtestpassed without running. - An undefined name in an
ENUMmember’s value is refused (E1003). The member used to take the next counter value silently. - Two targets may not share an artifact path. A project-wide
[artifacts]with onelabelskey left a file holding only the last target’s symbols. Move the key into each[target.artifacts]. !nex screenis refused for anything but0(E1117). No screen was ever written, so the flag sent a loader into the program.- A
.nexis taggedV1.2unless it needsV1.3. It was alwaysV1.3, which a core older than 3.x refuses to load. init --forcehas no short form.-fis--formateverywhere else.init -fstill works and says so.-vvvis refused. There are two levels of-vand it silently meant-vv.
13 more breaking changes to the Rust API are recorded in the project’s own history, which the published changelog leaves out. The crate is not on crates.io and makes no semantic-version promise; only a program embedding it is affected.
Added
- A language server worth using — rename across the project, call hierarchy, quick fixes from a diagnostic’s hint, a nested outline, folding, inlay hints, clickable
INCLUDEs. It reads yourfantasm.toml, and a file a[[target]]includes is analysed as part of that target. - Libraries —
!librarymakes a file a namespace with its own include guard,INTERFACEsays what is public, and--gc-librariesdiscards what nothing calls without touching a placementMODULE. REP <count>, <instruction>, and aREP/ENDRblock, for unrolling withoutldir’s loop overhead.- Tests that check memory —
assert_memandinit_memtake a run, a fill, a file to compare against or a physical address;assert_checksumfolds a run into a CRC-32C;init_cycle_limitandassert_cyclesbudget the time. - Debugger annotations —
!assertand!debugrecord a claim into the--sldfile, emitting nothing. - A
[lint]table infantasm.tomlsets what each warning is filed as, by code [w1049 = "deny"]. - Nested structs,
--relocfor relocatable images,--report-discards,--color, and Rhai scripts asinclude "x.rhai"withrhai.file.fn()calls. - These notes ship with the build —
RELEASE-NOTES.md, beside the licence in every package.
46 additions in all.
Fixed
113 fixes, and the worst of each group:
- 2 crashes —
ds -1anddb (1<<63)/-1aborted the assembler outright. - 24 wrong output, silently — a bank’s code written twice into a
.nex,add hl,ixassembling asadd hl,hl,db 1<2<3giving 8, seven block-graphics characters emitting the wrong code. - 24 sources that should have assembled, or should not have — an
IFinside a branch that was not being assembled having its condition evaluated anyway, a!testbody inside aMODULEunable to use that scope’s own names, a macro parameter inside brackets never substituted. - 37 in output and tooling — colour written into a redirected log, only the first error of a build reported however many it found, no two
--sldfiles matching between builds. - 19 diagnostics that named the wrong thing, or put the caret at the end of the statement rather than on the name.
- 5 in the language server, and 2 in the documentation.
26 of those 113 are the editor’s, spread across the groups rather than gathered in one: it disagreed with the build on any file holding a MODULE, opening a second file of one program filled the screen with faults in correct source, and an accented character in a comment took the server down.
59 new diagnostic codes, 84 to 140, and three withdrawn — E1034, I1051 and E1062 documented rules the assembler did not have. Test coverage expanded from 742 to 1,432 tests, and every combination of the nex, sna, lsp and update-check features builds and passes.
Every change is in the full changelog under [2.0.0], and the documentation has been rewritten to match — including a new page on libraries.
Get it from the Downloads page.