Tatara

Chapter 12
Defining and sharing symbols

A symbol is a name that stands for a number (chapter 2). This chapter describes the three ways a name gets its value, the rule that a name has only one value, the directives that let modules share names, and END, which ends a source and names where the program starts.

12.1 Three ways to give a name a value

Table 12.1 lists them.

Written as Its value Can change
name: the location counter at that line no
name equ value the value given no
name defl value the value given yes
Table 12.1: Three ways to give a name a value.

A name for a number makes a program easier to read and to change. ld c,_STROUT says what it does, where ld c,9 does not; and if the number ever changes, only the line that defines the name has to change with it. The names in MSXDOS.INC are defined with EQU for exactly this reason (chapter 14).

12.2 Labels

A label takes the value of the location counter at the line where it is written: the address of the first byte that line produces (chapter 10). A label is defined once. A second label of the same name stops TATARA:

LABTWICE.AS(3): ERROR: this name already has a value.
 

12.3 EQU

EQU gives a name a fixed value, the value of the expression after it:

five            equ     5 
screen          equ     4000h 
here            equ     $               ; an address in the code
 

The name is written without a colon: with one, TATARA takes it for a label, and the EQU is left with no name. five: equ 5 stops TATARA with EQU, DEFL and MACRO take a name, not a label.

The value can be any expression (chapter 8), including an address, as here shows: it is relocatable, like a label in the same place. It cannot be an external name, which has no value until the program is linked.

A name defined with EQU can be used before the line that defines it. In this source, later is used on the line before its EQU, and TATARA assembles it correctly as 0Ah:

                ld      de,later 
later           equ     five*2
 

EQU gives a name its value for good. Defining the same name again with the same value is accepted, but with a different value TATARA stops with this name already has a value.

12.4 DEFL

DEFL also gives a name a value, but the name can be given a new value later, as often as the source needs. Each line that uses the name sees the value it has at that point in the source:

count           defl    0 
                db      count           ; 00 
count           defl    count+1 
                db      count           ; 01 
count           defl    count+1 
                db      count           ; 02
 

A name defined with DEFL is sometimes called a variable symbol, and the symbol table marks it var. It cannot share its name with a label or an EQU: n equ 1 followed by n defl 2 stops TATARA with this name already has a value. Like EQU, it takes a name without a colon.

DEFL is most useful in conditional assembly and in macros, as a counter or a switch that changes as the source is read (chapters 15 to 17).

Note.  Readers who know M80 from other computers may expect a SET directive as another name for DEFL. Neither M80 in Z80 mode nor TATARA has one, because set is the Z80 instruction that sets a bit: x set 5 is read as that instruction, and stops TATARA with not a form this instruction has. DEFL is the only symbol that can be redefined. (A macro can be redefined too; that is a different matter, described in chapter 16.)

In the same way, TATARA has no .Z80 directive. M80 needed it to accept Z80 mnemonics; TATARA accepts nothing else, and has no mode to switch. A source written for M80 that starts with .Z80 stops on that line with not a directive, a macro or an instruction., and the line can simply be deleted.

12.5 Sharing names between modules

Chapter 2 explained that a program can be made of several modules, and that a module offers names to the others with PUBLIC and uses theirs with EXTRN. Each takes a list of names separated by commas, and each has a second name: ENTRY for PUBLIC, and EXT for EXTRN. A label written with two colons, as in both::, is made public as well (chapter 6).

This module offers four names, one written each way:

                public  greet,value 
                entry   other 
                cseg 
greet:          ret 
other:          ret 
both::          ret 
value           equ     5
 

PUBLIC can come before the definition, as it does here, or after it. Labels and EQU values can be public, and so can a DEFL name. The symbol table marks each public name:

ASEG - absolute 
 
0005h  public     value 
 
CSEG - default code segment, 0003h bytes 
 
0000h  public     greet 
0001h  public     other 
0002h  public     both
 

This module uses them:

                extrn   greet,value 
                ext     other,both 
                cseg 
start:          call    greet 
                call    other 
                call    both 
                ld      hl,value 
                ret 
                end     start
 

TATARA knows nothing about an external name except that another module defines it, so the symbol table lists the four under EXTERNAL - resolved by the linker. An external value is finished by TANREN, so it can go only where two bytes hold it, as in ld hl,value; in one byte, such as ld a,value, it is refused (section 8.6). Linked together, the two modules give a complete program:

A:\>tanren /o:use.com use.tro pub.tro 
Tatara MSX Linker v1.2.0 
Copyright (C) 2026 Javier Lavandeira 
https://tatara.tools 
 
2 modules, 20 records, ends at EOF. 
Wrote USE.COM, 0100-010F (16 bytes), entry 0100.
 

Two mistakes are caught by TATARA itself:

Mistakes that involve more than one module, such as a name that no module defines, are found by TANREN (chapter 27).

12.6 END and the start address

END ends the source. TATARA reads nothing after it, not even the rest of a file that included the one containing it (chapter 13). A source with no END is accepted too: it ends where the file ends.

The operand of END, if there is one, names the start address of the program: where it begins to run. TATARA writes it into the object file, and TANREN shows it as entry in its summary line (chapter 4).

Warning.  MSX-DOS2 always starts a .COM program at 0100h, the first byte of the file, whatever END says. In a .COM program, the label named by END must therefore be at the very start of the code. If data comes first, as in this source, the program runs the data as if it were instructions and crashes. TANREN writes the file all the same, but warns that the start address is not where the program will be entered:

                cseg 
msg:            db      'Started at start.',13,10,'$' 
start:          ld      de,msg 
                ... 
                end     start
 
WARNING: ENTRY.COM is entered at 0100, not at 0114. 
1 modules, 7 records, ends at EOF. 
Wrote ENTRY.COM, 0100-0120 (33 bytes), entry 0114.
 

When TANREN gives this warning for a .COM program, move the code named by END to the start, or put the data in the data segment (chapter 10).

12.7 Messages

Table 12.2 lists the messages about defining and sharing symbols, each with a line that causes it.

Line

Message

five: equ 5

EQU, DEFL and MACRO take a name, not a label.

five equ 6 after five equ 5; a label twice; n defl 2 after n equ 1; a name both EXTRN and defined

this name already has a value.

x equ far, far external

an external symbol may not be used here.

public with no names

bad PUBLIC or EXTRN list.

public nowhere, never defined

a PUBLIC name was never defined.

x set 5

not a form this instruction has.

Table 12.2: Messages about symbols.

One more message belongs here, although a correct source never causes it:

phase error - this label had a different value on pass 1.
 

TATARA reads the source twice, and a label must get the same value both times. Chapter 20 describes when it can happen.