An assembler statement for the original KIM ASSEBLER for 6502 from 1977 had the format
(label) opcode (operand) (comments)
as follows:
Blanks are used as separator between the fields
The label did NOT have to begin in column 1. Instead it had to be different from all the opcodes (ADC, AND,……,TYA) and could not be any of the special single characters A, S, P, X, Y (reserved). The first character had further to be alphabetic
In the operand field expressions consisting of symbols and constants separated by operands +, -, *, / were allowed. Constants could be in hex, octal, binary or decimal format
There were certainly little practical advantages of allowing a label to start at any columns. I think that nowadays it generally accepted that a label always should start in column 1 and that this is the way to distinguish a label from an opcode thats starts in column 2 or later. Like this any string of characters (not containing the field separator ‘ ‘ or any of +, -, *, / ) can be used as label, the coding get less error prone and also the design of the assembler program itself gets simpler and more elegant.
I also think that experience has also shown that it is better to always stick to hex for addresses and that shifts following + or – in always is in decimal, i.e.
LDA $ABAB (not LDA 43947 , not LDA @125653, not LDA %10111…..)
and
LDA $ABAB-13, X (not $ABAB - $D,X)
With symbols one then writes:
LDA MYLABEL
LDA MYLABEL+3,Y
It is very seldom useful to form the difference between labels to positions in memory, i.e.
LABEL2 – LABEL1
( but see example below)
and I think that the construction LABEL2 + LABEL1 where LABEL2 and LABEL1 are actual (2 byte) addresses NEVER makes sense!
If such differences/sums of symbols is not allowed numerical labels not starting with an alphabetic character can be allowed, i.e
Code:
*=$6000
1 NOP
.BYTE $AB
2 LDA 1 + 1
results in that the byte $AB resident at address $6001 gets loaded to the accumulator. With the original KIM ASSEMBLER
LDA 1 + 1
would instead result in that the byte in address $0002 is loaded and a number like 1 is not allowed as label
For immediate addressing one would in the same way use (only)
LDA #$FF
LDA #<MYLABEL
LDA #>MYLABEL
LDX #<MYLABEL - 1
i.e. using hexadecimal format for addresses and decimal notation for shifts. Like this the first character ($ or something else) is the way to distinguish between constants and symbols. These examples should cover all what is needed or useful
Sometimes (but seldom) it can be useful to form statements of type
LDX # LABEL2 - LABEL1
LDX # LABEL2 - LABEL1 + 1
This only make sense if 0 <= LABEL2 - LABEL1 <= 255 and the only application I can imagine is to move a portion of the code to a new area (for example from ROM to RAM) as follows :
(This code only works if LABEL2-LABEL1<=128, otherwise only one value would be moved!)
Code:
LABEL1 .BYTE $0A
.BYTE $0B
…..
LABEL2 .BYTE $FF
START LDX # LABEL2-LABEL1
LOOP LDA LABEL1,X
STA $0200,X
DEX
BPL LOOP
This type of coding is used in EhBASIC of Lee Davidson and this is one of the reasons why this program could not be assembled with my or Daryl Richters assembler (Lee uses TASS)
But this could alternatively have been coded as follows:
(ZP is an address in the zero page)
Code:
LDA #<LABEL1
STA ZP
LDA #>LABEL1
STA ZP +1
LDA #<LABEL2
PHA
LDX #$00
LOOP LDA (ZP)
STA $0200,X
INX
INC ZP
BNE 1
INC ZP+1
1 PLA
CMP ZP
BNE LOOP
This is a bit longer but considering how unfrequent this situation is I think this is a worthwhile price for allowing numerical labels. And this code is good for up to 256 values to transfer instead of only 128.
Note the use of the numerical label 1!
These are the coding conventions I use and my assembler program is designed to these conventions.
Does anybody have any comment on this design?