pm100 wrote
OUTPUT_FIRST is a label, it is at offset 10 thats why the assembler inserts 10 there, same for OUTPUT_D
You need to distingush between @<label> @<number> and @<variable>
When you hit @xxx you need to check to see if there is a (xx) if so then insert the offset of xx, otherwise generate a new variable address starting at 16
Just to clarify things a bit:
You need to make two passes through the code. On the first pass, you identify all of the labels and associated a number with each that represents the ROM address at which the next instruction will be stored.
On the second pass, when you encounter a symbol, you first check to see if it is one of the predefined symbols and, if so, replace it with the associated value. If it is not, you check to see if it is already defined as a label from the first pass and, if so, replace it with the associated value. If it is not, you check to see if it is already a defined variable and, if so, replace it with the associated value. If you have gotten to this point, THEN you know you have encountered a new variable for the first time and you assign it a new address, starting at 16.
While this is the conceptual logic, it can be significantly streamlined (as recommended in the text) by recognizing that, fundamentally, labels and variables are the same things -- namely symbols that need to be replaced by the numerical equivalent that is stored in a symbol table.
So you can have a single symbol table and this table does not need to track whether each entry is pre-defined, a label, or a variable. The symbol is either in the table or it isn't, and if it is, it has a single number associated with it that is used to replace the symbol in the instruction.
So you can initialize the symbol table with all of the pre-defined symbols. Then make your first pass and do nothing except add an entry for each label. Then, on your second pass, you check each use of a symbol (which can only appear in @xxx instructions) and if it is already in the symbol table (doesn't matter how or when it got there), you replace it. Otherwise, you add it using the next available RAM address and then replace it.