💾 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
--------

















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



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 *