💾 Archived View for mirrors.apple2.org.za › archive › ground.icaen.uiowa.edu › upl1998 › Nov98 › SAL… captured on 2024-12-18 at 01:57:31.
View Raw
More Information
-=-=-=-=-=-=-
SALP ver 1.0
Structured Assembly Language Preprocessor
Public Domain
No Rights Reserved
Unlimited Distribution is Encouraged
"We are tied down to a language
which makes up in obscurity
what it lacks in style."
-- T. Stoppard
Introduction
------------
SALP will take a structured assembly source file as input and create an assembly source file as output. It will give your assembler the ability to use structured assembly language.
An assembler is still needed to produce machine code. This means the development cycle now has an extra step. Instead of edit-assemble-test or edit-assemble-link-test, it is now edit-preprocess-assemble-test or edit-preprocess-assemble-link-test.
SALP requires the 65C02 processor and ProDOS 8. As distributed, version 1.0 only works with the Merlin assembler.
All SALP command lines start with "*!" (asterisk exclamation-point, or star-bang). This lets you assemble your source code to check for errors before using SALP, since these lines are treated by the assembler as comments. There cannot be blank spaces before the asterisk or between the asterisk and exclamation-point. No comments are allowed on SALP command lines.
All lines of code added by SALP end in ";!" (semi-colon exclamation-point, or semi-bang). Any lines read in by SALP that end this way are removed. This lets you run source code through SALP over and over without generating more and more extraneous code. Do not end any of your lines this way!
SALP reserves all four-character labels starting with "Z" from "Z000" through "ZZZZ" for a total of 46,656 possible labels. The large number is adequate for any reasonable program. The short length conserves symbol table space.
The only code produced by SALP are branches and labels. No registers or flags are changed.
SALP liberates you from the tyranny of the column-oriented assemblers that are the legacy of the computer punched card. Source code can be formatted so the structure is visually striking and helps to understand the code in less time.
Please questions, comments, and BUG REPORTS to the author:
Paul R. Santa-Maria
P.O. Box 924
Monroe, MI 48161
Use
---
When you run SALP, it looks for a file named "SOURCE.A" in the current directory and reads that file first. I recommend you keep "SOURCE.A" small. It should contain only the CPU command and a list of FILE commands.
Keep a copy of SALP in the same directory as your assembler. Keep the "SOURCE.A" file with your source files. When you want to use SALP, either copy SALP to your source directory or copy the "SOURCE.A" file to your assembler directory.
Every SALP file name should end in ".A", but the ".A" should not be in the FILE command. SALP will append the ".A". The ".A" stands for "Assembly" source code.
The SALP 1.0 distribution disk contains all the source code for SALP written in SALP itself. There is an appropriate "SOURCE.A" file. Study the disk and you will see how to use SALP.
Commands
--------
- ! IF <condition> {length}
- ! ELSE {length}
- ! ENDIF
- ! LOOP
- ! AGAIN <condition> {length}
- ! WHILE <condition> {length}
- ! UNTIL <condition> {length}
- ! FOREVER {length}
- ! CPU 6502|65C02|65802|65816
Condition Codes
---------------
The following condition codes are used in SALP:
flag clear flag set
------------------------- -----------------------
<NE> not equal (Z=0) <EQ> equal (Z=1)
<CC> carry clear (C=0) <CS> carry set (C=1)
<PL> plus (N=0) <MI> minus (N=1)
<VC> overflow clear (V=0) <VS> overflow set (V=1)
unsigned comparisons signed comparisons
---------------------- ----------------------
<HI> higher <GT> greater than
<HS> higher or same <GE> greater or equal
<EQ> equal (same) <EQ> equal
<NE> not equal (not same) <NE> not equal
<LS> lower or same <LE> less or equal
<LO> lower <LT> less than
There are sixteen different condition codes. Note that <EQ> and <NE> do triple duty as flag, signed comparison, and unsigned comparison conditions.
The 6502 has no standard way to distinguish between branches for signed and unsigned comparisons. Some assemblers allow BGE and BLT as synonyms for BCS and BCC for use after unsigned comparisons, which conflicts with SALP.
(The 6800, 6809, 68000, and 80X86 have always used the same conventions for signed comparisons as SALP.)
Lengths
-------
SALP assumes all branches are NEAR branches.
For unconditional branches, SALP uses the following table:
CPU
| 6502 65C02 65802 65816
------+------------------------------
Length NEAR | JMP BRA BRA BRA
FAR | JMP JMP BRL BRL
IF-ELSE-ENDIF
-------------
The IF command will execute the code following it if the condition is true. The ELSE is optional.
Example:
LDA DataByte
CMP #TestValue
DEC Counter
INC Counter
The "IF <EQ> FAR" will generate a long branch to the ELSE. The ELSE will generate a short branch to the ENDIF. The final code would look like this in column format:
LDA DataByte
CMP #TestValue
BEQ Z000
JMP Z001
Z000
DEC Counter
BRA Z002
Z001
INC Counter
Z002
LOOP
----
The two basic forms of loops are
- ! LOOP
- ! UNTIL <condition>
and
The first will continue looping as long as the condition is true. The second will loop forever. The two options within the loop are AGAIN and WHILE. AGAIN will return to the top of the loop if the condition is true, and continue below itself if the condition is false. WHILE will continue below itself if the condition is true, and jump past the UNTIL or FOREVER if the condition is false.
Keywords
--------
The conditions. To generate the reverse condition, flip bit 0 of the token.
Keyword Description
------- ----------------
<CC> carry clear
<CS> carry set
<PL> plus
<MI> minus
<VC> overflow clear
<VS> overflow set
<NE> not equal
<EQ> equal
<LO> lower (unsigned)
<HS> higher or same (unsigned)
<LS> lower or same (unsigned)
<HI> higher (unsigned)
<LT> less than (signed)
<GE> greater or equal (signed)
<LE> less or equal (signed)
<GT> greater than (signed)
The commands. These immediately follow the "*!".
IF
ELSE
ENDIF
LOOP
AGAIN
WHILE
UNTIL
FOREVER
FILE
CPU
The modifiers. These are used inside a command.
NEAR
FAR
6502
65C02
65802
65816
Flag branches
-------------
The near version is on the left; the far version is on the right.
branch if carry clear <cc> (C flag = 0)
BCC YES | BCS Z000
| JMP YES
| Z000 EQU *
branch if carry set <cs> (C flag = 1)
BCS YES | BCC Z000
| JMP YES
| Z000 EQU *
branch if plus <pl> (N flag = 0)
BPL YES | BMI Z000
| JMP YES
| Z000 EQU *
branch if minus <mi> (N flag = 1)
BMI YES | BPL Z000
| JMP YES
| Z000 EQU *
branch if overflow clear <vc> (V flag = 0)
BVC YES | BVS Z000
| JMP YES
| Z000 EQU *
branch if overflow set <vs> (V flag = 1)
BVS YES | BVC Z000
| JMP YES
| Z000 EQU *
branch if not equal <ne> (Z flag = 0)
BNE YES | BEQ Z000
| JMP YES
| Z000 EQU *
branch if equal <eq> (Z flag = 1)
BEQ YES | BNE Z000
| JMP YES
| Z000 EQU *
Unsigned branches
-----------------
branch if lower <lo>
BCC YES | BCS Z000
| JMP YES
| Z000 EQU *
branch if higher or same <hs>
BCS YES | BCC Z000
| JMP YES
| Z000 EQU *
branch if lower or same <ls>
BCC YES | BCC Z000
BEQ YES | BNE Z001
| Z000 JMP YES
| Z001 EQU *
branch if higher <hi>
BCC Z000 | BCC Z001
BNE YES | BEQ Z001
Z000 EQU * | Z000 JMP YES
| Z001 EQU *
Signed branches
---------------
branch if less than <lt>
BVC Z000 | BVC Z001
BMI Z001 | BMI Z002
BPL YES | Z000 JMP YES
Z000 BMI YES | Z001 BMI Z000
Z001 EQU * | Z002 EQU *
branch if greater or equal <ge>
BVC Z000 | BVC Z001
BPL Z001 | BPL Z002
BMI YES | Z000 JMP YES
Z000 BPL YES | Z001 BPL Z000
Z001 EQU * | Z002 EQU *
branch if less or equal <le>
BEQ YES | BEQ Z000
BVC Z000 | BVC Z001
BMI Z001 | BMI Z002
BPL YES | Z000 JMP YES
Z000 BMI YES | Z001 BMI Z000
Z001 EQU * | Z002 EQU *
branch if greater than <gt>
BEQ Z001 | BEQ Z002
BVC Z000 | BVC Z001
BPL Z001 | BPL Z002
BMI YES | Z000 JMP YES
Z000 BPL YES | Z001 BPL Z000
Z001 EQU * | Z002 EQU *