SALFAA v2.0 by B.Poot / J.Jobse
With SALFAA, developed by B.Poot, and later expanded by J.Jobse, it is
possible to enter assembler language programs is a very user friendly
The layout of the translation-listing can be made according to your own
preferences. Behind the directives .FIRST, .LIST and .HARD parameters are
allowed. The most expanded form looks like this:
The switch parameter must be one of only two values: 1=ON and 0=OFF.
The tab parameters point to starting position on the line where the
respective variable will be printed. If the first parameter is larger than
1, it is automatically interpreted as label-tab. De switch value takes its
default value of 1. A few examples:
.LIST 1 or .LIST - screen on, tabs unaltered
.LIST 0 - screen off, tabs unaltered
.LIST 0,26,28,40 - screen off, ltab=26, itab=28, ctab=40
.LIST 30,34,48 - screen on, ltab=30, itab=34, ctab=48
.LIST 1,25 - screen on, ltab=25, rest unaltered
The directive tab always equals the itab-1. If comment is the first item on
the line of after a semi-colon, the itab applies to it.
With the .OPTIONS directive, immediate addressing and in declarations,
binary numbers and ASCII characters are allowed. They may, however, not
be used in expressions. A few examples:
:two = :10 LDA @:01101011 :comma = ";"
:five = 7-two LDX @thousand%256 CMP @";"
:thousand = five*200 LDY @thousand/256 CMP @CH"A"-1
If memory is not reserved using .TABLE or .XTERN, then automatically a new
symbol table will be initialized at the default lower boundary (#8200). The
easiest and most common situation is a single table, to which during the
first pass new symbol are added, and from which during the second pass
symbols are read. This read/write table is called the active symbol table.
It is, however, also possible to use existing tables. These can be standard
tables or tables that have been produced by other modules (program parts).
Such an external table can only be read. Een external table differs from an
active table, because the external table is not "forgotten" with repeated
Of course, during the construction, the external table is an active table.
It can be made external, using ASM-XTERN. Using ASM-TABLE, the start and
end address can be inquired, e.g. 8200 83A0 9000, after which the table
can be written with *SAVE"NAME.TBL"8200 83A0.
On the next occasion, it must be loaded direcly from the lower boundary into
the reserved memory area, e.g. *LOAD"NAME.TBL"8600.
Using, for example, .XTERN #8600,#8C00, at the top address of the external
table (#87A0) a new table will be initialized.
It is possible to use more than one external table at a time. They must be
loaded from the lower boundary, right behind each other. The start address of
a table must be equal to the end address of the previous one.
After developing a program, using one or more external tables, it can become
handy to print the integral, sorted table. This is possible by using
ASM-JOIN, which merges the last two present table to one external table.
When there are more external tables, repeat this action.
It is advised, when printing, to select a line width of 16, 32, 48 etc.
When an error occurs, the line number is automatically shown on screen. There
is one error that deserves extra attention: UNMATCHED LABEL VALUE. This error
is generated when the assembler during the second pass notices a movement of
the CODE pointer in relation to the first pass. This happens with so called
"zero page forward references". This means that a symbolic zero page address
is used as an operand in an instruction, before it is declared. This can be
avoided by making all 8-bit declations at the start of a program.
In addition, there can be error messages without an explanation (the ATOMs
traditional way). Their meaning can be found in standard ATOM documentation.
The page cross message is the only one in the form of a warning.
7 0=6502 mode 1=R65C02 mode
6 0=P-CHARME at #1000 1=no P-CHARME
5 0=no page cross messages 1=page cross messages
4 0=don't print RAM-pointer 1=print RAM-pointer
1 0=write code to memory 1=don't write code
0 0=first pass (pass0) 1=second pass (pass1)
Symbols can be composed from: A..Z a..z 0..9 ' en _ (underscore).
The following restriction must be taken into account:
1. A symbol may not start with a number
2. A symbol may not exist of only one capital
3. If a symbol starts with a capital, then:
a. the second character must be a capital too
b. the second character may not be the same as the first one
c. the symbol may not start with an existing BASIC function
Examples: wrong: 1st correct: '1st
A single capital in an expresion IS allowed, because then it is interpreted
as a BASIC variable. The 6502 register may be refered to with capitals
(A,X,Y) as well as with lower case letters (a,x,y). This implies that BASIC
variable A and the symbol a, may not be used as an operand address in an
SALFAA - prints all SALFAA statements and their entry points.
PASS expr - copies the two lowest bits of the expression into the STATUS
CALL expr - sets new BRK-vector (1). Further, acts exactly the same as
LINK. In addition, the least significant bit of the variable C
is copied into the 6502 carry flag.
SYM expr - sets new BRK-vector (1) and prints the value of the (symbolic)
expression hexadecimally. This statement is especially designed
for usage in direct mode.
(x - opens long comment, until closure x) is encountered, where x
is any character.
\ - opens short comment, until semi-colon (;) or carriage return.
ASM-stat - executes the assembler statement, specified in the first letter
after the -. The rest is regarded as comment until ; or CR.
ASM-BEGIN - is the same as ASM-INIT, followed by ASM-CONTINUE
ASM-CONTINE - turns off screen, sets new BRK-vector (1) and turns on SALFAA
ASM-END - restores previous value of the BRK-vector (2)
ASM-INIT - initializes symbol table boundaries var S at #8200,#9000
initializes CODE-pointer var P at #9000
initializes RAM-poitner var O at #0000
initializes ltab, itab, ctab at resp. 22,24,39
resets internal table flag during first pass: If a symbol
table was present, it will be forgotten.
ASM-JOIN - merges the last two tables to one external table.
ASM-LAST - prints the last symbol table, followed by ASM-WARNINGS.
ASM-SYMBOL - prints complete symbol table, followed by ASM-WARNINGS.
ASM-TABLE - prints symbol table boundaries, with in between table-top(s).
ASM-UNRAVEL - sorts the last symboltable.
ASM-VERSION - prints the SALFAA version number.
ASM-WARNINGS - prints the number of warnings.
ASM-XTERN - converts the active table to external table.
(1) The BRK-vector is compared to the SALFAA-BRK. If not equal, the current
value is saved first.
(2) It is checked that the BRK-vector compares to the SALFAA-BRK.
A directive consists of a dot, followed by one or more characters. The first
character behind the dot, decides which directive it is. The rest is ignored.
.ASCII data - puts 8-bit data into memory. (1)
example: .ASCII 6,"text",cr,lf,"more text", etc.
.BYTE data - identical to .ASCII.
.CODE expr - places the value of expression into the CODE-pointer, var P.
.DBYTE data - puts 16-bit data into memory, high byte first. (1)
example: .DBYTE "TEXT",address, etc.
.END - turns off printer, turns on screen, puts SALFAA back into
.FIRST par - turns on screen during first pass (par: see LISTING).
.GOTO line - jumps to specified line (number of label).
.HARD par - turns on printer during second pass (par: see LISTING).
.IF expr - executes rest of the line only, if (testable) expression is
TRUE (non-zero result).
.LIST par - turns on screen during second pass (par: see LISTING).
.NEWLINE expr - prints the number of line feeds specified in expr.
.OPTION expr - copies the highest 6 bits from expr into the STATUS BYTE.
.PRINTe,e... - sends 7-bit codes to the printer (also 2,3 and ?#FE)
.RAM expr - places the value of expression into the RAM-pointer, var O.
.SYMBOL - prints the complete symbol table and warnings, during second
pass. With LAST as parameter, only the last table will be
.TABLE e1,e2 - reserves memory for the symbol table. The first expression is
the lower boundary, the second the upper boundary. If no
upper boundary is specified, then the present RAM memory will
decide the upper boundary. Both values will be placed in the
var S. During the first pass, at the lower boundary an empty
active table will be initialized.
.UNRAVEL - sorts the last symbol table during the second pass.
.VERSION - prints SALFAA version number.
.WORD data - puts 16-bit data into memory, low byte first. (1)
example: .WORD address,"TEXT", etc.
.XTERN e1,e2 - same as .TABLE, but this directive initializes a table behind
the present external table(s).
(1) Data may consist of strings, expression separated by a comma.
In assembler mode there are the following possibilities:
instr - 6502 or R65C02 instruction
!instr - SWEET16 instruction
.dir - directive
:symbol=expr - declares a symbol, which gets the value of the expression
:label - declares a label, which gets the value of CODE-pointer
\comment - short comment, until ; or CR
(x - long comment until x)
*stat - asterisk-statement