Diagnostics

Every message FantASM prints carries a level, a code and a position.

Anatomy of a Diagnostic

Error [E1003]: Undefined label or constant: `nowhere_at_all`
src/main.asm:12:6
  jp nowhere_at_all
     ^
  • Error is the level.
  • [E1003] is the level’s letter and the code. The letter matters — see below.
  • src/main.asm:12:6 is file, line, column.
  • The source line is quoted with a caret under the column, so you do not have to count.

Some diagnostics add more:

Hint: use @NAME to reach a constant outside this module

A hint says what to do about it. A note on a second location points at the other half of the problem — where a label was first defined, say, when you have defined it twice.

A diagnostic without a file:line is about the project file, not your source. The fault is in how fantasm.toml’s tables relate rather than at a point in any text, so there is no line to point at.

Levels

ShownMeaning
ErrorThe build failed. Nothing is written.
Fatal ErrorThe build failed and could not continue far enough to look for more problems.
WarningAssembled, but something is probably wrong.
InfoProgress and detail, shown with -v.
MessageYour own message directive.

The same code number can carry different levels. 1012 is a warning when a value is truncated to 16 bits and an error when the same value cannot be used at all. The level is decided where the diagnostic is raised, which is why the letter is printed and not just the number.

One number, one meaning. 1049 and 1060 each named two unrelated diagnostics, told apart only by the level letter — so looking one up found whichever entry came first. The address error moved to 1082 and the NEX entry-point warning to 1083; the two numbers now mean what most people already thought they meant.

A code that stood for several faults now stands for one. 1020 covered a bad option name, a bad option value and an unknown output format; 1058 covered five things at once. Each has its own code, so a [lint] entry or a search of a build log picks out the fault you mean rather than its family. The splits are 10201129, 1130, 1134, 1135; 1008 and 10051136, 1137; and 10581005, 1138, 1139, 1140, 1141, 1142.

The Unused-Label Sweep

-u turns on that one sweep and nothing else. Every other warning is shown whether or not you pass it, and --no-find-unused turns off only the sweep.

fantasm build src/main.asm -u

or in fantasm.toml:

[assembler]
find_unused = true

It was -W/--enable-warnings/--no-warnings and warnings until 2.0. Those still work, saying what replaced them once (W1103), and are withdrawn in 2.1.

W1049 unused label does not fire for a label that is KEEP-pinned, GLOBAL-exported, discarded by --gc-modules, or run into by the code above it — in none of those cases is there anything to act on.

Nor for any part of a STRUCT instance something touches. An instance is one object’s layout, so a reference to a member marks the instance and vice versa — ld hl,inst and then indexing through (hl) uses every field without naming one. Deleting a member to answer a warning would move the fields after it, so there is no change to make. An instance nothing touches at all is still reported.

Common Codes

E1003 Undefined label or constant. A typo, a missing INCLUDE, or a name you expected to reach out of a MODULE. Constants do not fall back to global scope from inside a module — use @NAME.

E1004 File not found. Check include_dirs. If the missing file is another target’s output, you get E1078 instead, which is more useful — see Building Several Images.

E1005 Syntax error and E1008 Invalid instruction. Usually a mnemonic that does not exist in the form you wrote it, or an operand the instruction cannot take. Where either can say more it adds it after a colon; a bare Syntax error means the line stopped making sense and there was nothing useful to name.

E1013 Attempt to redefine label or constant. The note points at the first definition.

E1016 Z80n extended instructions are not enabled. Set device = "zxnext", or z80n = true for a Z80N program on another machine.

E1020 is not an assembler option. The name after !opt. A value that option will not take is E1134 and an output format this build does not write is E1135 — both name what is actually wrong, rather than an option that was fine.

E1058 General error. Nothing in a source file raises it. It stood for a --test run’s failure count, an empty test body, a body with nowhere to go, a !rhai block missing its brace and two fantasm.toml target faults; those are E1138, E1139, E1140, E1005, E1141 and E1142.

E1036 Maximum code size exceeded. max_code_size limits how much code there is, not the address it reaches — a program ORGed at $8000 emitting 2 KB has used 2 KB of the budget. zx16 additionally refuses anything above $8000.

W1068 Code emitted in ROM and W1069 Code assembled before any ORG. Both usually mean a code-bearing INCLUDE sits above your ORG. Anything emitted before an origin lands at $0000.

E1060, E1061 Reserved word. A macro’s name and a macro’s parameters cannot be words the tokeniser has already claimed — see below. E1063 is the neighbouring case of a missing or malformed MODULE or !library name.

E1075 This is a string, which has no numeric value. __NAME__ and friends carry text. db __NAME__ assembles it; ld a, __NAME__ cannot.

E1200 Rhai error. A !rhai block failed to compile, or the engine ran into a fault. The position points inside the script, at the line you wrote rather than at the !rhai that opened it. What a script says on purpose — ctx.warn, ctx.error — is 1080 instead, in the script’s own words.

Reserved Words

A macro’s name and its parameters must be words the tokeniser has not already claimed. Every word below produces a keyword token instead, so using one there raises E1060 or E1061.

Position decides everywhere else, and most slots take these words happily. A label may be named after any of them, and so may a STRUCT member, an ENUM member or type, a MODULE and a !library: org: is legal, KEEP org pins it, hex equ 9 defines a constant called hex, and Device db is a struct member. A register or condition name still cannot be a constant — a equ 5 is E1005.

E1062 is withdrawn. It refused a module or library named after a reserved word, which is now allowed.

assert and debug are in this table like any other directive, and like any other they can still name a label, a STRUCT member and the rest. DEBUG equ 1 with ld b,DEBUG and IFDEF DEBUG all work.

FamilyWords
Directivesorg include binary incbin message db defb byte dw defw word ds block dh hex opt macro end endm dz if ifdef ifndef else endif global enum ende struct ends nex bank page slot sna device target format module endmodule library interface endinterface keep test endtest init_reg init_mem init_cycle_limit assert assert_reg assert_mem assert_cycles assert_checksum debug rhai rep endr
Opcodesevery Z80 and Z80N mnemonic — ld, nop, jr, mul, …
Registersa b c d e h l i r bc de hl sp ix iy af ixh ixl iyh iyl
Conditionsnz z nc c po pe p m
Operatorsequ
Optionsverbose cspect z80n maxcodesize case_insensitive device target format
Booleanson off true false yes no

Matching is case-insensitive, so Slot and SLOT are reserved too.

device joined this table in 2.0, and costs a struct nothing: a member may be named after any reserved word, being read only as Type.member. target is here only while !target is still accepted, and leaves in 2.1.

This is the first thing to check when a name behaves strangely. A module called A or a macro parameter called c is a register name, and the diagnostic that results rarely mentions registers. It costs nothing to rule out and saves a long search when it is the cause.

The Full Reference

The message text is what FantASM prints; stands for a name, file or value it fills in.

CodeMessage
1001Address overflow, PC > 65535
1002Invalid character in label
1003Undefined label or constant:
1004File not found: …
1005Syntax error: …
1006Bad constant definition
1007Invalid register pair
1008Invalid instruction: …
1009Integer out of range
1010Address is out of range, the value has been truncated
1011Integer has been truncated to 8 bits
1012Integer has been truncated to 16 bits
1013Attempt to redefine label or constant
1014Unexpected end of line
1015Invalid condition
1016Z80n extended instructions are not enabled
1017Unexpected closing parentheses
1018Unclosed parentheses
1019CSpect pseudo ops are not enabled
1020 is not an assembler option
1021Invalid number or expression
1022Invalid Hexadecimal string
1023Bit number is out of range and will be truncated
1024circular INCLUDE: …
1025Discarded extra characters at end of line
1026Encountered END without MACRO directive
1027ENDIF without IF
1028ELSE without IF
1029Invalid or missing macro name, found
1030Comma expected
1031Invalid or missing macro parameter name, found
1032Macros may not be nested
1033Incorrect number of macro parameters
1035Macro already defined
1036Maximum code size exceeded
1037 has no size that can be determined
1038String contains non-ascii characters…
1039Invalid 8-bit register
1040ENUM name expected
1041ENDE without ENUM
1042Enum member name is invalid
1043Enum step value cannot be zero
1044STRUCT name expected
1045ENDS without STRUCT
1046STRUCT member name is invalid
1047STRUCT member size suffix is invalid
1048STRUCT already defined
1049unused label … (a warning, from -u)
1050Invalid directive
1052Unknown SNA command: …
1053Unknown NEX command: …
1054Expected NEX command, found: …
1055Expected SNA command, found: …
1056Your own message directive
1057Shebang detected and ignored: …
1058General error: … — nothing in a source file raises it; see 1005 and 11381142
1059Memory region overlap detected
1060 is a reserved word and cannot be a macro name
1061 is a reserved word and cannot be a macro parameter name
1063Invalid or missing module name, found
1064ENDMODULE without MODULE
1065MODULE was never closed with ENDMODULE
1066Invalid or missing label after KEEP, found
1067KEEP names , which is not defined
1068Code emitted at … is in ROM and cannot run
1069Code assembled at …, before any ORG set an origin
1070Invalid or missing name after GLOBAL, found
1071GLOBAL names , which is not defined
1072Unknown escape \… in a string or character literal
1073A size computed from $ was settled at …, but the line was placed at …
1074… was never closed
1075 is the string “…”, which has no numeric value
1076A digit separator must be _, not ' — found after
1077Targets depend on each other in a cycle: …
1078… not found. It is the output of target , which does not list in depends
1079 is a macro; ifdef and ifndef test constants and cannot see one
1080What a script said through ctx.warn or ctx.error, in its own words
1081What a script printed — twenty lines a block, then a count of the rest
1082Invalid address or bank (was 1049, which the unused-label warning kept)
1083NEX entry point … has no code (was 1060, which the reserved-word error kept)
1084 is referenced only by a !test block and has been discarded by --gc-modules
1085Code between … and … is not contiguous: an ORG skipped a range, or two wrote to one address
1086 was worked out from a MODULE label before its body was placed; corrected, and said
1087if chose its branch from a MODULE label before its body was placed
1088 is not a function in any script loaded above this line
1089An !opt value names an address, which is not settled while options are read
1090Two loaded scripts define ; the later one is the one that will be called
1091A !test assertion did not hold: what it checked, and what it found
1092 names an address in a form relocation cannot patch (relocatable output only)
1093 is not an instruction, a directive or a macro — a label must start at column 0
1094 is a macro; at column 0 this defines a label rather than expanding it
1095A library is the whole of its file and cannot be declared inside anything
1096Library is already declared by … — two files claiming one name
1097INTERFACE belongs at the top level of a library
1098Library already declares an INTERFACE
1099ENDINTERFACE without INTERFACE
1100Library promises in its INTERFACE but never defines it
1101 is not in library ’s INTERFACE; @NAME goes round it
1102--reloc needs one image moved by one delta:
1103 is deprecated; use . The old spelling still works, and leaves in 2.1
1104 was still running after … T-states — no halt, or longer than the ceiling allows
1105 is not an option of ; the ones it takes are named
1106 is given twice on one
1107 takes positional arguments or name=value ones, not both on a line
1108 expected an option name — a trailing comma, or a value written without its name
1109 needs …: a span must say where it starts, how far it runs, and what it holds
1110 takes or , not both — two starts, or two sources for the bytes
1111The span … runs past the end of memory, which is … bytes. A phys span is refused, not wrapped
1112… is … bytes, and the span … runs past the end of it
1113A second ELSE for one IF; the first already names the alternative
1114 is not a NEX version; write V1.2 or V1.3
1115V1.2 was asked for, but this file uses …, which is a V1.3 feature
1116 is nested more than 64 macros deep; a macro that invokes itself never ends
1117!nex screen needs loading-screen data, which is not written
1118 cannot hold a ; a struct’s size would have no end
1119 is not a size or a struct type; a type must be defined above the member
1120 is recorded nowhere without an SLD file; name one with --sld <file>
1121A block of … bytes cannot be reserved; a count runs from 0 to 65536
1122 belongs between !test and !endtest; outside a block it runs against nothing
1123An index displacement of … does not fit; it runs from -128 to 127
1124 is not a fantasm.toml key
1125REP repeats an instruction, and is not one
1126REP cannot assemble … statements; a repetition runs from 0 to 65536
1127REP takes a count, a comma, then the instruction to repeat
1128ENDR closes a REP block, and none is open
1129 is not a machine this build knows; assembling for the default instead
1130page and slot are the Next’s 8K paging; pages in 16K banks, so use bank
1131[lint] … names no diagnostic
1132[lint] … is not a diagnostic a project may reconfigure
1133[lint] … = … is not allow, warn or deny
1134 does not take — the option is fine, the value is not
1135 is not an output format this build writes
1136 is not a directive has — bank or page on a machine without them
1137bank takes no slot on ; a 16K bank has one window
1138… tests failed — the count that fails the build, at the first failure
1139 has no body to run
1140There is no room to place : the program fills the address space
1141No target named . This project declares …
1142 depends on , which this project does not declare
1200A Rhai script failed to compile, or the engine raised a fault running one

Documentation