Chapter 20
Error messages
When TATARA finds a mistake in a source, it prints one error message and stops. This chapter describes how to read the message, what TATARA leaves on the disk when it stops, and how to follow the trail of lines that comes after a message when the mistake is inside an include file, a macro or a repeat block. Appendix D lists every message, with its cause.
20.1 What a message says
A message names the file and the line of the mistake, and says what is wrong:
; LERR.AS - an error half way down a listing. cseg ld a,1 ld b,2 ld (bc),b ld c,3 end
A:\>tatara /l lerr.as lerr.tro lerr.lst Tatara MSX Macro-Assembler v1.2.0 Copyright (C) 2026 Javier Lavandeira https://tatara.tools LERR.AS(5): ERROR: not a form this instruction has.
- The file is the one that holds the line: the source named on the command line, an include file, or the file where a macro was defined. TATARA prints the name in capitals.
- The line is counted from 1 at the top of that file. The comment at the top of LERR.AS is line 1, so ld (bc),b is line 5.
- The text after ERROR: says what is wrong. Here ld (bc),b is written correctly, but the Z80 has no such instruction.
A definition or a conditional that is never closed is found only at the end of the source. Its message names the line that opened it, the MACRO or the IF, not the last line of the file.
Some messages have no line to name. A mistake on the command line is found before any file is read, and its message comes before the banner (section 5.6):
A:\>tatara /z good.as ERROR: unknown option.
A file that cannot be opened is named in the message itself, as in ERROR: cannot open NOTHERE.INC (chapter 13).
/Q leaves out the banner and the summary line, but never an error message:
A:\>tatara /q lerr.as LERR.AS(5): ERROR: not a form this instruction has.
20.2 TATARA stops at the first error
TATARA prints one message at a time. When it finds a mistake, it stops there, and does not look at the rest of the source. Correct the line, assemble again, and TATARA goes on to the next mistake, if there is one.
TATARA never leaves a half-written object file. What it leaves depends on when it found the mistake:
- On the first pass, where almost every mistake is found, TATARA has not yet created the object file. An object file of the same name from an earlier run is left as it was (chapter 5).
- On the second pass, TATARA has already created the new object file. It deletes it, so that no object file of that name is left, not even the one from an earlier run. Here GOOD.AS is a correct source, and PUB.AS has a name declared PUBLIC and never defined, which is found when the object file is finished:
A:\>tatara good.as pub.tro ... ended at GOOD.AS(5) A:\>dir pub.tro ... PUB TRO 46 26-09-30 9:04 46 bytes in 1 file 3800K free A:\>tatara pub.as pub.tro ... PUB.AS(7): ERROR: a PUBLIC name was never defined. A:\>dir pub.tro ... 0 bytes in 0 files 3808K free
In the first case, an old object file may still be there, and TANREN would link it without complaint. After an error, do not link until TATARA has assembled the source without one.
A listing is written on the second pass (chapter 18), so a mistake found on the first pass stops TATARA before any line of the listing is written. LERR.LST, named on the command line in section 20.1, is not created, and with /L and /P instead, LERR.AS prints only the message.
20.3 The trail
When the line with the mistake did not come straight from the source named on the command line, the message is followed by a trail: one line for each step that led TATARA to it, starting from the mistake and working outwards. Each line of the trail is indented by four spaces, and has one of these forms:
- included from FILE(line): the file above was included by the INCLUDE on that line (chapter 13).
- in NAME, called from FILE(line): the line above is part of the macro NAME, and that line used it (chapter 16).
- in a repeat block, called from FILE(line): the line above is part of the REPT, IRP or IRPC block on that line (chapter 17).
- in a redefined macro, called from FILE(line): as for a macro, but the macro has been given a new definition since it was used, so its name no longer belongs to it (section 16.7).
20.3.1 Reading a trail
This example has a mistake in a repeat block, inside the macro inner, which is used by the macro outer, which is used in an include file. MACS.INC defines the two macros:
; MACS.INC - two macros, one using the other, with a repeat block. outer macro nop inner endm inner macro rept 1 ld (bc),b endm endm
USE.INC uses outer on its line 2, and TRAIL.AS includes both files:
; TRAIL.AS - an error in a repeat block, in a macro, in a macro, in an ; include file. include macs.inc cseg include use.inc end
MACS.INC(8): ERROR: not a form this instruction has. in a repeat block, called from MACS.INC(7) in inner, called from MACS.INC(4) in outer, called from USE.INC(2) included from TRAIL.AS(5)
In figure 20.1, each line of the message has a number, and the source line it names has the same number.
Read the trail from the top down:
- The mistake is on line 8 of MACS.INC, ld (bc),b.
- That line is part of the repeat block that starts on line 7.
- The repeat block is part of inner, used on line 4, inside outer.
- outer was used on line 2 of USE.INC.
- USE.INC was included by line 5 of TRAIL.AS, the source named on the command line.
The first line says where the mistake is, and the last line is always in the source named on the command line. The lines in between show the way from one to the other.
Two things are not in the trail. USE.INC gets no included from line of its own for line 2, because called from USE.INC(2) has already named it. And include macs.inc on line 3 does not appear at all: the trail shows how TATARA reached the line with the mistake, and MACS.INC had been read to its end long before. Only the definition of the macros came from there.
20.3.2 A redefined macro
A macro that defines itself again while it runs (section 16.7) no longer has a name of its own in the trail:
; REDEF.AS - a macro that defines itself again, then fails. once macro once macro endm ld (bc),b endm cseg once end
REDEF.AS(5): ERROR: not a form this instruction has. in a redefined macro, called from REDEF.AS(8)
The name once now belongs to the empty macro defined on line 3, so the trail cannot use it for the one that is running.
20.4 Errors found on the second pass
TATARA reads the source twice (section 15.2). A few mistakes can be seen only on the second reading, when TATARA can compare it with the first:
- phase error - this label had a different value on pass 1. Something before the label assembled to a different size on the two passes, usually a conditional that gave a different answer (section 15.2).
- this label was defined on pass 1 and not on pass 2 - a conditional skipped it. As above, but the label was skipped altogether; the most common cause is a file included twice (section 13.6).
- a PUBLIC name was never defined. Found when the object file is finished, at the end of the second pass (chapter 12).
These are the errors after which TATARA deletes the object file it was writing (section 20.2).
20.5 Internal errors
A message that starts with internal -, such as internal - this line emitted more bytes than fit., is an internal error: TATARA has found a fault in itself, not in the source. Please report it, with:
- the source, and every file it includes;
- the command line;
- everything TATARA printed;
- the output of the same command with /F, or with /M if the line comes from a macro (section 19.4).
out of mapper memory. is not an internal error: the source needs more memory for TATARA’s tables than the memory mapper has.