home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-02 | 151.9 KB | 3,177 lines |
-
-
-
-
-
-
-
-
-
-
-
- SSSSS AAAA
- SS AA AA
- SS AA AA SSSSS mmm mmm
- SSSS AA AA SS mm mmmm mm
- SS AAAAAAAA SSSSS mm mm mm
- SS AA AA SS mm mm mm
- SSSSS AA AA SSSSS mm mm mm
-
-
- Version 1.73
-
-
-
- Macro Assembler for the Archimedes
-
-
-
- Copyright David Holden 1991,92,93,94,95
-
-
- _______
- ____|__ | (R)
- --| | |-------------------
- | ____|__ | Association of
- | | |_| Shareware
- |__| o | Professionals
- -----| | |---------------------
- |___|___| MEMBER
-
-
- Contents
-
- Section 1 - Preliminaries
- Introduction 1.1
- Licence to Use 1.2
- How to Register 1.3
- Advantages of Registration 1.4
- Licence to Copy 1.5
- Section 2 - Using SAsm
- Use with floppy discs 2.1
- Command line syntax 2.2
- Null Parameters 2.3
- Source Filenames 2.4
- Reconciliation of Wildcards 2.5
- Order of Assembly 2.6
- Length of Source File 2.7
- Line number space 2.8
- A short demonstration 2.9
- Section 3 - The Source File
- Source File Syntax 3.1
- General 3.2
- Important warning 3.3
- Warnings and Errors 3.4
- Comments 3.5
- Descriptive text 3.6
- Large source files 3.7
- Basic keywords accepted 3.8
- Directives 3.9
- Basic variables 3.10
- #ORG 3.11
- #SIZE 3.12
- #END 3.13
- #TYPE 3.14
- #OBJ 3.15
- #ERRFILE 3.16
- #LIB 3.17
- #VERBOSE 3.18
- #QUIET 3.19
- #INCLUDE 3.20
- #INSERT 3.21
- #AREA 3.22
- Multiple data areas 3.23
- #STRUC 3.24
- #LISTON 3.25
- #LISTOF 3.26
- #LISTFILE 3.27
- #NOENHANCE 3.28
- #ENHANCE 3.29
- #XREF 3.30
- #NOXREF 3.31
- #XRFILE 3.32
- #LABELFILE 3.33
- #SWION 3.34
- #SWIOFF 3.35
- #CLI 3.36
- Labels and Variables 3.37
- Defining registers etc. 3.38
- Defining constants 3.39
- Conditional Assembly 3.40
- LDM/STM with Writeback 3.41
- Assembly Loops 3.42
- The OSET variable 3.43
- Assembly Listing 3.44
- Creating a Listing file 3.45
- Listing file directives 3.46
- Scope of listing 3.47
- Section 4 - Labels
- Global Labels 4.1
- Local Labels 4.2
- Local Label Scope 4.3
- Using Local labels 4.4
- Previous or Next set 4.5
- Local Label Example 4.6
- Examples with Prev/Next 4.7
- Forward Branch to 00 4.8
- problems with Local Labels 4.9
- Section 5 - Special features
- Enhanced 2nd Operand 5.1
- Extra Mnemonics 5.2
- DW and DD 5.3
- DB 5.4
- Basic variables and DB 5.5
- ADRL 5.6
- MOVL 5.7
- DIV 5.8
- Section 6 - Macros
- Macro Functions - Pro/Con 6.1
- Expanded Macros - Pro/Con 6.2
- Macro Names 6.3
- Expanded Macros 6.4
- Defining expanded macros 6.5
- Macro parameters 6.6
- Local labels in macros 6.7
- Special features 6.8
- Examples 6.9
- Errors in expanded macros 6.10
- Macro Functions 6.11
- Built-in Functions 6.12
- FNgap 6.13
- FNset 6.14
- FNadr 6.15
- FNmov 6.16
- Section 7 - The Macro Library
- Using the Macro Library 7.1
- The 'L' parameter 7.2
- The 'V' parameter 7.3
- SAsm$Lib OS variable 7.4
- Preparing a Library 7.5
- Length of Library file 7.6
- Section 8 - SAsm and the Desktop
- New features 8.1
- Using from the desktop 8.2
- Section 9 - Problems and Questions
- Reporting and diagnostic 9.1
- The SASM_ERR variable 9.2
- Speed of operation 9.3
- Memory usage 9.4
- Notes on Local Labels 9.5
- Common problems 9.6
- Appendices
- Release History
- Registration Form
-
- Introduction
- ============
- A long time ago when I found I needed more facilities than the Basic
- assembler offers I tried Acorn's AASM. My personal opinion of AASM is
- that it is overpriced, clumsy and, in some ways, less powerful than the
- (free!) Basic assembler. I therefore decided to write my own,
- provisionally titled BAsm. As usual it had to be fitted in with other
- things, and meanwhile I needed an assembler. I continued to use the
- Basic assembler for short utilities and AASM for longer ones. Soon I
- found I was using AASM less as I gradually added bits to the Basic
- assembler to give the additional facilities I needed.
-
- To make life easier I wrote a 'pre-processor' for the Basic assembler as
- a stop-gap until I finished BAsm. Gradually it was improved and with
- each improvement the need for BAsm receded and work on it assumed a
- lower priority. Eventually my stop-gap program assumed a life of it's
- own and had become so powerful that it could do just about everything I
- wanted. At this point I realised it would be useful to others as well. I
- re-wrote the program, making lot's of improvements, and named it SASM -
- Simple ASseMbler
-
- Don't be put off by the word 'Simple'. Unless you are re-writing
- Impression SAsm will probably fulfil all your needs. Simple is intended
- to describe its ease of use. Its main limitation is that it cannot
- produce output in AOF (Acorn Object Format) for linking to 'C' or other
- languages. If you want to write in 'C' I'm afraid you are stuck with
- ObjAsm or !AS until I get around to finishing BAsm. It also cannot
- assemble Floating Point opcodes although you could add Macros to do
- this. If you really must use them (I've never found the need) ask and I
- will try to include them.
-
- SAsm is not an assembler. It is a pre-processor for the Basic assembler.
- Don't worry about this. As far as the user is concerned SAsm works with
- Text source files and behaves like a 'proper' assembler. It has lots of
- facilities that the Basic assembler normally lacks, local labels,
- multi-file assembly, error reovery, etc. yet at the same time the syntax
- will be familiar to anyone who has used the Basic assembler. You also
- have the power of Basic available with its Mathematical, Conditional
- Assembly and Expression Evaluation abilities
-
- If you are not an expert at using the Basic assembler I suggest you read
- the file 'Tutorial'. It won't teach you to write machine code but it
- explains the use of Macro Function and Conditional Assembly with the
- Basic assembler helps you understand SAsm better. (SAsm actually has
- another, better, Macro system as well as Basic style Functions).
-
- Please read carefully the 'Licence to Use' and 'Licence to Copy' before
- you use/copy SAsm.
-
- David Holden
- 39 Knighton Park Road
- Sydenham
- London SE26 5RN
- 081 778 2659
-
- If you have any problems or suggestions for improvements to SAsm please
- write or phone. If you write with an enquiry please enclose an SAE. If
- you prefer to telephone I am normally available on weekday evenings.
-
- SAsm was produced by a member of the Association of Shareware
- Professionals (ASP). ASP wants to make sure that the Shareware principle
- works for you. If you are unable to resolve a Shareware related problem
- with an ASP member by contacting the member directly, ASP may be able to
- help. The ASP Ombudsman can help you resolve a dispute or problem with
- an ASP member, but does not provide technical support for members'
- products. Please write to the ASP Ombudsman at 545 Grover Road,
- Muskegon, MI 49442-9427, U.S.A. or send a CompuServe message via
- CompuServe Mail to ASP Ombudsman 70007,3536 or FAX 616-788-2765.
-
- This program is not Public Domain, it is
-
- ssss h h aaa rrrr eeeee w w aaa rrrr eeeee
- s h h a a r r e w w a a r r e
- ssss hhhhh a a rrrr eeee w w w a a rrrr eeee
- s h h aaaaa r r e w w w aaaaa r r e
- ssss h h a a r r eeeee ww ww a a r r eeeee
-
- 1.2 Licence to Use
-
- This program is distributed as Shareware. It is not Public Domain.
- Shareware is not a type of software, it is a means of distributing
- commercial software on a 'try before you buy' basis. Unless you have
- already Registered you have not paid for the program, even if you paid a
- fee to a PD Library or BBS for your copy. You are only licensed to use
- SAsm for a period of Thirty Days. The trial period enables you to decide
- if SAsm is suitable for you, and at the end of that time you must either
- stop using it or Register. If you decide not to register you must stop
- using SAsm immediately. Failure to comply with this condition is a
- Breach of Copyright and recognised in almost all countries as Software
- Piracy and therefore an offence.
-
- 1.3 How to Register
-
- Registration costs just Ten Pounds, plus Two Pounds if you require a
- laser printed manual. I have made the last page of this Manual a
- Registration Form. Please use it when you register as it helps me to
- keep my records tidy. Fill it in, preferably adding comments, and post
- it to me. Don't forget your cheque for Eight Pounds. Write as much as
- you wish, I do take notice of comments and suggestions.
-
- Each assembler for the ARM processor will produce slightly different hex
- values for the same assembler mnemonics. SAsm leaves its 'fingerprints'
- on the code produced. I can tell if a program was assembled using SAsm.
- I will take action against ANYONE who uses SAsm and distributes code
- WITHOUT REGISTRATION in breach of this licence
-
- 1.4 Advantages of Registration
-
- The first advantage is that you will not, of course, be breaking the
- law. Registration costs just Ten Pounds, so it's not expensive. However
- there are some material advantages.
-
- When you register you will receive your personal copy of the latest
- version of SAsm which can use external Macro Libraries This enables SAsm
- to load Macros automatically during assembly. You will also receive the
- tools to create Macro Libraries. This makes your code simpler because
- you don't need to include all the macro definitions within it before you
- call them. For an extra two pounds you can have a laser printed manual.
-
- You will also have the right to FREE UPDATES. Once you have registered
- you can return your ORIGINAL copy of SAsm to me with a stamped, self
- addressed label at any time for a copy of the latest version. To take
- advantage of this offer you MUST return your ORIGINAL disc with your
- personal copy of SAsm, not just a blank disc. You will also be entitled
- to free or very low cost upgrades to any future assemblers or compilers
- that I produce even if these are not part of the SAsm 'family'.
-
- 1.5 Licence to Copy
-
- If you are a Sysop or run a PD or Shareware library READ THIS CAREFULLY.
-
- 1. The Author retains full copyright to this program and all the
- material and documentation associated with it.
-
- 2. Any private individual may give copies of the unregistered
- version of SAsm to his/her friends. Only PD or Shareware libraries
- and BBS's which have been given permission by the Author are
- permitted to distribute SAsm. Any distribution by any organisation
- or for any reward whatsoever whether in fee or in kind without
- permission is forbidden and will be treated as Breach of Copyright
- even if the fee is merely intended to cover costs.
-
- 3. You may not make any changes to the program or documentation and you
- must include the Examples directory and its contents and the
- Tutorial, Manual and all other associated files. You may not make
- any charge for this program or for any additional material you
- supply. You may charge a reasonable fee to cover copying, media,
- postage, overheads, etc.
-
- 4. You may not under any circumstances distribute copies of any
- registered version of SAsm. These can be distinguished because they
- display the name of the registered user after the copyright message
- whereas the version which may be freely distributed displays the
- word 'Unregistered'.
-
- 5. You must not distribute any version of the 'MakeLib' application.
- This is for the use of Registered users ONLY.
-
- 6. It is absolutely forbidden to distribute or copy any printed or
- hardcopy version of the documentation, either in whole or in part.
- The printed version of the Manual is for the personal use of
- registered users only.
-
- David Holden
- 39 Knighton Park Road
- Sydenham
- London SE26 5RN
- 081 778 2659
-
- Using SAsm
- ==========
- SAsm is a 'Transient' program. When it is invoked by typing it's name at
- the OS '*' prompt it is loaded from disc and Run. You will find two
- versions of SAsm on the distribution disc. One is the transient
- application, and the other is a Relocatable Module called SAsmMod. This
- will be the preferred method if you don't have a hard disc. Load the
- Module by double-clicking on it and it will then run from the RMA
- whenever you type 'SASM' in exactly the same way as the transient
- program runs from disc. The only disadvantage of the Module is that it
- will take up an extra 25K or so of RAM in the RMA.
-
- Note that the Module version of SAsm does not actually run from the RMA.
- When you invoke it the program code is copied down to &8000 and run from
- there. It will therefore have the amount of RAM available that you have
- set for the 'Next Slot' in the Task window. There is functionally no
- difference between the two versions.
-
- From version 1.70 there is a desktop application !SAsm which will do
- most of the work required to enable you to assemble complex projects
- within the desktop. This lets you avoid using the CLI parameters and
- switches described in the following section. However, you should read
- through this as it will help you to understand how SAsm works, even
- though you may never need to use them.
-
- 2.1 Use from floppy discs
-
- Although SAsm will work much faster with a hard disc it is perfectly
- satisfactory when used without one. In fact it was deliberately designed
- with floppy disc operation in mind. If you have enough memory you can
- use a RAM disc to hold all your files. The disadvantage of this is that
- if you modify a source files and suffer a crash before you remember to
- save the modified files you could lose part of your work.
-
- As SAsm uses only block file operations to load the source and save the
- object files it will still operate quite fast from floppy discs. If you
- use the Module version of SAsm this will save the time overhead of
- loading the assembler itself each time. The slowest file operations are
- associated with error, listing and label cross-reference files as these
- are written line by line. The obvious solution is to direct all these to
- the RAM disc which will be much faster than a floppy. As these files are
- normally only needed temporarily it will not matter if they are lost. To
- further reduce disc access time you could save the object file to the
- RAM disc and copy your macro library (if used) there.
-
- 2.2 Command line syntax
-
- The full syntax of the command string for SAsm is;
-
- SASM <source file list> [object filename] [error filename] [LXVQSNFA]
-
- Only <source file> is compulsory, the others are optional. So, after
- *SASM leave one or more spaces and then type the name of your source
- file(s). You can have as many as you like, separated by commas. The full
- meaning of <source file list> is quite complex and for the complete
- explanation read the section titled 'Source Filenames'.
-
- Because SAsm uses spaces a delimiters between command line fields you
- must NOT put any spaces in your source file list.
-
- After the source file(s) leave a space then type the name of the Object
- File. This is the name that will be given to the assembled code when it
- is saved. If you don't type an Object Filename SAsm will assemble all
- the files but won't save the finished product. You may wish to do this
- if you just want to check for errors or find out how long the finished
- code is it can be useful.
-
- The next parameter is the name of the Error File. Unlike the Basic
- assembler SAsm will display error messages and try to continue with
- assembly if it can. If you have many errors the first ones will scroll
- off the screen and get lost. If you define a name for an error file all
- error messages will be sent to the file. This can be loaded into an
- Editor with the source code in another window so you can find and
- correct them. If you use a Task Window you could 'capture' error
- messages in this but a separate error file is neater.
-
- After the three filenames you can type one or more single letter
- parameters or 'switches'. These may be in in upper or lower case. If you
- use more than one they should be separated by spaces. Most of these
- duplicate or interreact with Directives in the files and so the
- descriptions here are rather brief because more information will be
- found in the section on Directives.
-
- The 'X' parameter will cross reference (X-ref) all labels in the source
- and report duplicates. If a duplicate is found a warning message is
- displayed with the name of the label and the line number at which it
- occurs. You can include this each time but normally it is only needed
- the first time you link all your files as sometimes a duplicate label is
- perfectly valid. For example I often use 'loop' or 'bak' repeatedly and
- don't want a screen full of warnings. You can create a list of duplicate
- names as a file by use of the #XRFILE directive (see later).
-
- 'L' forces SAsm NOT to load any Macro definitions from the Library, even
- if one exists. See the section on the Macro Library for an explanation
- of this.
-
- 'V' makes SAsm 'verbose' when loading Expanded Macros from a Library. As
- each macro is loaded it's name is displayed. This is not normally needed
- but it is included in case you want to check whether SAsm is using a
- macro defined in the file or from the Library.
-
- 'A' will produce an Assembler Listing file. If 'A' is followed by a
- filename this will be used, otherwise it will be saved to the current
- directory with the name 'ListFile'. If you do wish to use the default
- name for a listing file make sure that the 'A' command is the last item
- on the line, otherwise it will 'grab' the next parameter as a filename.
- You will find more information on assembler listing files later. (NB-
- The more obvious 'L' isn't used for a listing file because it was
- already allocated by the time this feature was included.)
-
- 'F' formats an assembler listing file with labels at the left and
- instructions indented.
-
- 'S' switches on processing of SWI names. This is described fully in the
- section on the SWION/SWIOFF directives.
-
- 'Q' makes SAsm Quit after pre-processing is complete but before
- assembly. This is useful if you get a serious error during assembly as
- it lets you produce a listing without the possibility of a complete
- crash during assembly.
-
- 'N' will list all global label Names after pre-processing. This is in
- the form of list on the screen in alphabetical order. This switch will
- stop a label cross-reference check so don't use 'X' and 'N' at the same
- time. As this list is likely to be rather long you can use the LABELFILE
- directive to save it to a file if you wish
-
- 2.3 Null Parameters
-
- You will notice that these names must appear in order. So can you
- produce an error file but no object file?, or a X-ref but no Error or
- Object file? If these switches are defined within the source there is no
- problem but most of the time this will not be the case as you would only
- need x-ref or listing files for de-bugging purposes. To permit switches
- to be used at the command line when one or more of the file names is not
- present SAsm accepts the ~ character or any filename beginning with ~ as
- the equivalent of no filename.
-
- For example, to assemble the source file 'My_Prog' without producing an
- object file but listing all errors in the file 'Errors' you could use -
-
- *SASM MyProg ~ Errors
-
- If you use the '~' character in the object filename position you will
- not get an object file even if a name is defined in the source file.
- There is therefore a further alternative. If you use '!' as an object
- filename SAsm will only produce an object file if the name is defined in
- the source. The '!' character is interpreted as 'only produce an object
- file when an OBJ directive exists'. This permits you to use switches and
- an object file without needing to type a source file name.
-
- 2.4 Source Filenames
-
- The source filename list can be a single filename or a series of names
- separated by commas. Don't use spaces to separate the names because SAsm
- regards a space as a field delimiter. This is important because if you
- do use a space between source filenames and if SAsm is able to
- successfully assemble the first file(s) the next name will be taken as
- the object filename. This will result in the code being saved with this
- name which will destroy the source file of the same name. Normally this
- can't happen because the fact that some of the files aren't loaded will
- produce errors but it could, so beware!
-
- Most users will probably use a 'make' file with 'INCLUDE' filenames to
- assemble a project but you should understand the full command line
- syntax to ensure that you know exactly how SAsm operates with wildcarded
- filenames.
-
- To assemble the files Start, Middle and End in that order into the
- object file Code you would use;
-
- *SASM Start,Middle,End Code
-
- This assumes the files are in the Currently Selected Directory (CSD).
- Each name can of course have a path as well. If you have some standard
- sub-routines called Subs in directory $.Source.Routines you could use;
-
- *SASM Start,Middle,$.Source.Routines.Subs,End Code
-
- SAsm loads the files in the order in which the names appear and treats
- them as if they were one big file. You can therefore break the source up
- into small chunks and sub routines which are easily edited. You may find
- you have lots of standard routines that you want to assemble with your
- program and you can put these in one or more separate files and
- assembles them with each project.
-
- The easiest way to avoid all this typing is to program a function key
- with the command. For the previous example if you type;
-
- *Key 5 *SASM Start,Middle,$.Source.Routines.Subs,End Code|M
-
- you need only press F5 to assemble your code. This saves the repetitive
- typing but as the length of a function key string is limited to 255
- characters it may not be enough to accommodate a long list of
- path/filenames. SAsm therefore accepts wildcards in the source file
- list. If you use a common part in all the filenames for a project this
- feature can often enable you to assemble all the required files with
- just a single wildcarded name.
-
- 2.5 Reconciliation of Wildcards
-
- It might appear that 'filtering' of wildcards in filenames is
- unnecessary. If you put all the source files in sub-directory 'Source'
- of the CSD then typing *SASM Source.* Code should assemble them all
- into the object file Code. In real life things aren't that simple. For
- example, if you want to alter one of the source files but keep the
- original in case the change doesn't work (always to be advised!). You
- make the alterations, change the name of the original, and assemble the
- code. The only problem is that SAsm would assemble BOTH files, the
- original and the new. You could avoid this by moving the original to
- another directory but this soon becomes very tedious.
-
- SAsm has a rigid system of deciding which files to assemble. It was
- designed to work with the way I name source files. If you don't like it
- let me know and I will try to accommodate your preferences, but please
- try my way first, it's the result of much experience and you might find
- you like it.
-
- SAsm works it's way through the list in order. It first finds all the
- names which fit the wildcarded first name in your file list.
-
- SAsm rejects any file that doesn't have a filetype of 'Text' (FFF),
- 'Data' (FFD) or SAsm Make files (&2EF). This avoids trying to load a
- previous object file or other non-source file if it was saved to the
- same directory. As all text editors on the Archimedes save output as
- 'Text' by default this should not be a problem. If you do import a file
- from some other source its type will probably be 'Data' and if not you
- can easily change it. If you get a 'File not found' error but can see
- that the file exists it is probably because its filetype is not &FFF,
- &FFD or &2EF.
-
- The remaining files which fit the wildcarded name are then examined and
- loaded IN ALPHABETICAL ORDER. Any file which has a digit 0-9 at the end
- of its name is examined and if it has the same name as the previous file
- but with a different number it is ignored.
-
- What this means is that if you give all your source files a name ending
- in a number, the file with the LOWEST number will be loaded and the rest
- ignored. This works because the lowest number is also the first
- alphabetically. I start out at 99 and work my way down, so each version
- is progressively called Name_99, Name_98, Name_97 etc. Within the
- desktop the latest version will always be the first file in the
- directory viewer.
-
- When all the files with names which fit a wildcarded filename have been
- loaded SAsm will get the next name on the list and so on until all the
- names have been dealt with.
-
- 2.6 Order of Assembly
-
- Remember that SAsm assembles the files which can be matched to each
- wildcarded name alphabetically. To return to the previous list with
- 'Start, Middle and End' if you use '*' to match all of these files then
- they will be assembled in the order 'End, Middle, Start' which is not
- what is required. As it is normally only the first and sometimes last
- files whose order is important it is fairly easy to ensure that they are
- assembled in the correct order by placing an extra digit at the start of
- the name. For example renaming the files 'aStart, Middle, zEnd' would
- ensure that they are assembled in the correct order while retaining
- meaningful names.
-
- Since SAsm expands and reconciles wildcarded filenames in this way it is
- mot essential to use a 'make' utility to assemble a long list of source
- files. In fact the additional facilities offered by the INCLUDE
- directive make this even simpler.
-
- 2.7 Length of Source Files
-
- Because SAsm loads all the files into memory at once in might seem that
- the total length of these files could not exceed the usual 640K (or
- whatever you have set 'Next Slot' to) which is available as a Task. In
- fact this is not the case. As SAsm loads each file it removes all the
- spare spaces and assembler comments. If, like me, you indent every line
- and use lots of comments you will probably find your source files shrink
- to about 60% of their original size. Even allowing for the memory
- required for variables, the assembler commands etc. you should find that
- SAsm can load over 1MB of source with the usual 640K slot. If this isn't
- sufficient SAsm can extend the slot, but the ability to operate with
- minimum memory allows SAsm to operate very fast even on a 1Mb machine.
-
- 2.8 Line number space
-
- When the pre-processed code is passed to the Basic assembler it must be
- given line numbers so that Basic can understand it. This means that 3
- bytes must be added to the start of each line. If there is not enough
- room for this SAsm will attempt to relocate the file in memory. This is
- unlikely to happen unless you have more than about 10,000 lines.
-
- It is possible that there isn't enough RAM for relocation and in this
- case SAsm will be unable to continue. If this happens there are two
- possible solutions. The simplest is to make more RAM available. Bring up
- the Task Manager window on the desktop and increase the size of the
- 'Next Task' allocation. On a 1Mb machine you may need to 'kill off' some
- tasks to be able to do this. If you cannot make more RAM available you
- will need to reduce the number of lines in your source file. There is no
- point in removing comments, column indents etc. because by the time this
- error occurs they will all have been stripped by SAsm anyway. However
- each line removed saves only three bytes so you will need to remove a
- lot of them to make any real difference.
-
- 2.9 A short demonstration
-
- Copy the file SAsm and the complete 'Example' directory to a blank disc
- in drive 0. Now press F12 to leave the desktop or CTRL-F12 to open a
- Task Window and type 'MOUNT :0' at the OS '*' prompt. To assemble the
- demonstration program type;
-
- SASM Example.H* Hello
-
- The disc drive will start and after the SAsm copyright line you should
- see the messages;
-
- Loading Source Files:
- Example.Hello_A
- Example.Hello_B
- Example.Hello_C_50
- Pre-processing completed - starting assembly
- Pass 1
- Pass 2
- 0 Errors
- Code &xx bytes - Saved as 'Hello'
-
- You will find that a new file 'Hello' has appeared on the disc. To run
- this program, which just displays a couple of messages, type 'Hello'.
-
- If you examine the contents of the directory Examples you will find that
- as well as Hello_A, Hello_B and Hello_C_50 (and several other files)
- there is Hello_C_52. Since this file has a higher number than Hello_C_50
- it was ignored.
-
- Now repeat the exercise but hold down the SHIFT key when you press
- RETURN after entering the SAsm command line as previously. Everything
- will seem as before but this time when you type *Hello to RUN the Object
- code some of the messages will be different. This is a simple example of
- Conditional Assembly, some of the code being changed if the SHIFT key is
- held down during asssembly.
-
- I suggest that you load these three files into Edit and examine them.
- They are not a good example of compact or well written code but they do
- illustrate the layout of a multiple SAsm source file. You will notice
- the use of the Conditional Assembly section which produces the two
- different versions. Note also that branch instructions can be used to a
- label in another file demonstrating that labels are global.
-
- You will also see the use of a Macro Function 'print_string'. This would
- be more efficiently coded using OS_Write0 but it illustrates how Macros
- Functions are written and used.
-
- The files 'Local' and 'Immed' are examples to illustrate the use of
- local labels, SAsm's simplified 2nd operand instructions and Expanded
- Macro's. These may be assembled and examined in a similar maner.
-
- The Source File
- ===============
-
- 3.1 Source file Syntax
-
- I will assume that the reader is familiar with the Basic Assembler.
- Reference will be made to it and attention drawn to differences between
- it and SAsm where they occur. Although the syntax used by SAsm is
- similar to the Basic Assembler this applies only to the actual assembly
- language itself. You can forget about square brackets, OPT, P%, O% and
- all the things that are necessary before you can use the Basic
- Assembler. The biggest change is that the source files for SAsm are TEXT
- files and must NOT have line numbers.
-
- One of the features of SAsm is this similarity. This isn't an accident.
- Firstly SAsm actually uses the Basic assembler to do much of the work.
- Secondly it was designed from the start to be a 'step up' from the Basic
- assembler so even it's most advanced features will be very quickly
- mastered by anyone who is familiar with the 'built-in' assembler. You
- won't therefore need to spend ages learning a whole new language and you
- will be able to convert your old Basic assembler programs into SAsm
- format very easily and quickly. Normally this takes only a few minutes
- with a straightforward program.
-
- 3.2 General
-
- In the following section you will find references to various commands
- being separated by spaces. If your Editor uses a Tab character (ascii 9)
- to separate text into columns this character will also be accepted. This
- may not be specified each time to avoid constant repetition. If you do
- find that a Tab character won't work but a space will please tell me and
- I'll try to make it work.
-
- In this Manual references are made to the 'hash' character '#' (the
- character above the '3' on the main keyboard). If that appeared in your
- printout as a pound sign then your printer is set to the English
- character set so you will just have to read the file as if it had
- printed a hash. There are no pound characters in this Manual.
-
- 3.3 Important Warning
-
- SAsm makes use of the Basic integer variables O%, P% and Q%
-
- O% and P% are used conventionally by the Basic assembler. Q% defines the
- OPT setting during assembly. It is therefore vital that you do NOT use
- or manipulate any of these variables unless you are absolutely sure of
- what you are doing.
-
- Similarly the upper case names ADDR, TYPE, OSET and SIZE are reserved
- words and must not be used as Basic variables.
-
- 3.4 Warnings and Errors
-
- In the following sections reference will be made to Warnings, Errors and
- Fatal Errors.
-
- Warnings are issued if SAsm finds you have omitted or wrongly placed a
- directive. The code will still be assembled and saved. Warnings will not
- be written to the Error file.
-
- Errors are faults from which SAsm can recover but which make the code
- useless. Unlike the Basic assembler SAsm will try to continue after an
- error as there may be others to report, but the assembled code will not
- be viable so no Object file will be produced. However if a Listing file
- was specified then this will be produced. If SAsm finds an error in the
- first pass it will not attempt a second pass. You may therefore need two
- attempts to correct all the errors.
-
- A Fatal Error is an error from which SAsm cannot recover or which is so
- serious that there is no point in continuing. An error in a Macro
- Function or a missing file are examples of Fatal Errors.
-
- 3.5 Comments
-
- SAsm defines a comment as EVERYTHING on a line after a semi-colon ';' or
- a backslash '\'. SAsm therefore conforms to the syntax used by most
- assemblers which differs from the Basic assembler. The Basic assembler
- is almost unique in using the colon ':' as a statement delimiter. While
- SAsm still recognises ':' and allows more than one mnemonic on a line
- Basic regards ':' as the end of a comment and tries to assemble anything
- on the line after it even if the ':' is in a comment. For example the
- following line using the Basic assembler;
-
- mov r0,#0 : \ mov r1,#1 : mov r2,#2
-
- would be assembled as mov r0,#0 followed by mov r2,#2 The middle
- instruction would be ignored because Basic recognises the '\' and
- regards it as a comment but continues assembling when it finds the ':'
- later in the line. Using SAsm you would get ONLY mov r0,#0 as
- everything on the line after the '\' is a comment.
-
- The exception is where a semi colon (;) is not preceded by a space or a
- Tab character (ascii 9). This has been done so that you can use ';' in
- Basic PRINT statements to display information during assembly. When you
- use ';' in a line to define a comment make sure that it is preceded by a
- space or a Tab or it will cause an error.
-
- If you want to use more text than can be fitted into a normal comment
- then see the next section.
-
- 3.6 Descriptive text
-
- Sometimes you may want to put a block of descriptive text in a source
- file. This is often required before a major routine to describe what it
- does, entry conditions, register state on exit, etc. Normally this is
- done by preceding each line of the text with a ';' or '\' but this is
- rather tedious, and it's easy to miss a ';' and get assembler errors. It
- is also a nuisance if you want to edit it later because you must fiddle
- about with all the ;'s if you reformat it.
-
- Most high level compilers permit blocks of descriptive text between
- certain markers and the text is ignored by the compiler. This is very
- convenient and I have therefore introduced this feature into SAsm using
- the curly brackets, { and }, as the delimiters.
-
- The { must be the first non space character on a line. Everything up to
- the closing } will then be ignored. The opening { may be followed by
- text on the same line or be on a line of its own.
-
- There is an important proviso with the closing bracket. It MUST be
- preceded by a space, Tab, or be the first character on a line. If this
- is not done it won't be recognised as terminating a descriptive text
- insert and you'll get errors.
-
- The reason for this is that these two characters could be used to 'blank
- out' sections of code you don't want to assemble. Instead of needing a
- ';' in front of every line you can enclose the entire block between {and
- }. This makes it a lot simpler to avoid assembling debugging code, etc.
- when you no longer need it but to restore it when you do. If you use
- this feature for that purpose then, if the requirement for a space
- before the closing } did not exist, there would be a problem with LDM
- and STM instructions where the register list is enclosed in the same
- characters. If you make sure that you don't have a space before the
- closing } with your LDM and STM instructions (not difficult) then you
- can use these characters to blank out code containing those
- instructions.
-
- To make this even easier SAsm will ignore a closing } if it is the first
- character on a line, unless, of course, it is actually the terminator of
- a pair of {}'s. This would be an error under all normal circumstances so
- it would never exist naturally. If you do use this feature to blank out
- a section of code then to bring the code back into use you need only
- delete (or 'comment out') the opening {and the closing one will be
- ignored.
-
- Obviously if a } with a preceding space exists in the section you want
- to blank out you may get errors. The most likely cause of this is a } in
- a comment, but this should be easy to check.
-
- In normal use the only problems you are likely to encounter is if you
- forget the closing } or if you don't precede it with a space. SAsm will
- then wipe out all the code up to the next closing } it finds, which will
- probably produce a whole series of errors, or it will quit with a Fatal
- Error if it comes to the end of the file before it finds a closing }.
-
- 3.7 Large source files
-
- Basic can load files in text format and this is the way that SAsm
- normally operates. However Basic always insists upon numbering programs
- in this format in 10's. The trouble with this is that Basic can't accept
- line numbers greater than about 65,000 so this would limit the maximum
- source file size to around 6500 lines. This only applies to programs in
- text format, if the program is numbered in 1's instead of 10's then it
- can be over 65,000 lines long which is big enough for any eventuality.
-
- If a file is longer than about 6500 lines it is necessary for SAsm to
- tokenise it instead of leaving this to Basic. This is completely
- automatic, smaller programs will be left untouched and larger ones will
- be tokenised. In order to simplify the SAsm code and to make the
- operation as fast as possible this routine is not nearly as
- comprehensive as the system used by basic itself. This is not normally a
- problem as most of the Basic keywords would never be used in an
- assembler source file. All of the graphics commands and many others have
- been omitted and will produce errors if they are used.
-
- There is a possible conflict between the operators AND, EOR and OR and
- assembler mnemonics AND, EOR and ORR. In theory the SAsm tokeniser can
- distinguish between these when used as mnemonics or operators but
- circumstances could exist where it could become confused. Obviously this
- can't happen if the mnemonics are written in lower case. In fact with
- larger programs you are advised to use lower case for ALL mnemonics as
- this makes the tokenising faster.
-
- There is also room for confusion if you use variables with names that
- include Basic keywords. Basic itself will always recognist 'theORy' as a
- variable but the SAsm tokeniser might, under some circumstances, try to
- tokenise the 'OR'. With well written source code this shouldn't be a
- problem as normally variables have lower case letters or use only single
- capitals as word delimiters but you should be aware of the possibility
- of problems.
-
- 3.8 Basic keywords accepted
-
- These are the only Basic keywords that can be used in an SAsm source
- file longer than 6500 lines. There is no reason why others can't be
- added, I just couldn't think of any reason to include them. If you do
- have a real need then please tell me.
-
- ABS, AND, ASC, CALL, CASE, DATA, DEF, DIV, ELSE, ENDCASE, ENDIF,
- ENDPROC, ENDWHILE, EOR, EVAL, FALSE, FN, FOR, GET, IF, INKEY, INSTR,
- LEFT$, LOCAL, MID$, MOD, NEXT, NOT, OF, ON, OR, OTHERWISE, PRINT, PROC,
- READ, REM, REPEAT, RESTORE, RIGHT$, SPC, STEP, STR$, STRING$, SYS, THEN,
- TO, TRUE, UNTIL, VAL, WHEN, WHILE
-
- 3.9 Directives
-
- You can include Directives in your source, some are necessary for the
- proper operation of SAsm. A line where the first character is '#' is a
- directive. If SAsm doesn't recognise what follows the '#' it assumes it
- is a Basic statement and the line after the '#' will be passed to Basic.
-
- You can use SAsm without any preliminary directives in the source file.
- Unlike the Basic assembler you can begin writing code straight away. If
- you do this SAsm will start assembling the code to run from '0000'. This
- doesn't matter as SAsm will produce position independent code unless you
- have included specific references to addresses within your source.
-
- The '#' character can have spaces before and after it to improve
- legibility if you wish, they will be ignored, but it MUST be the first
- non-space character on a line. Directives should be the only item on the
- line although you may follow them with comments.
-
- All directives are case insensitive. In the following pages they are
- normally shown in upper case for clarity, but you may use lower case if
- you prefer. Where a directive is to be passed to Basic its case and
- syntax must conform to that required by Basic. Where a comment is
- included in a directive which is to be passed to Basic it can still be
- preceded by ';' or '\' rather than REM, and this is actually preferred.
-
- There must be a space after a directive where it is followed by
- parameters.
-
- 3.10 Directives and Basic variables
-
- Because SAsm passes unrecognised directives to Basic this could create
- difficulties if you use any of the SAsm directives as Basic variables.
- This will not of itself cause problems, for example, there is no reason
- why you could not have a register called 'org'. However you should be
- careful how you define such items, eg. using -
-
- # include = 7
-
- to set a Basic variable 'include' to 7 would create difficulties because
- SAsm would recognise 'include' as one of its own directives and try to
- interpret it. However -
-
- # fred = 6 : include = 7
-
- would be OK, because SAsm wouldn't recognise 'fred'. Similarly -
-
- # include=7
- # include%=7
- # include_it = 7
-
- are OK because there is no space following 'include' as required by SAsm
-
- In general you are advised to avoid using any SAsm directives as
- variables or constants because this could be a source of strange errors.
- Remember also that all SAsm directives are case insensitive so this
- would apply to include, INCLUDE, Include, etc.
-
- The upper case versions of the directives ADDR, TYPE and SIZE, are
- reserved words and must not be used as variables anywhere in your code.
-
- 3.11 #ORG
-
- Defines the address the code will be assembled to run at. The syntax is
- # ORG <number> where <number> is a valid address. <number> is assumed to
- be hex whether or not it is preceded by '&'.
-
- If no #ORG directive is found assembly will start at location 0 and a
- warning will be displayed. The #ORG directive must appear before the
- first assembler statement. If an #ORG directive is found after this a
- warning will be displayed and the code will be assembled to start at
- location 0. This does not apply if you have defined TYPE (see later) as
- 'Absolute', 'Module' or 'Utility' because these filetypes, the most
- commonly used, all have 'standard' load and execution addresses.
-
- There must be at least one space between the word 'org' and the number
- which follows. This applies to all directives.
-
- 3.12 #SIZE
-
- This advises SAsm of the expected size of the code so it can reserve a
- large enough buffer for it. The full syntax is #SIZE <number> where
- <number> is the estimated maximum size of the code. <number> will be
- assumed to be in hex whether or not it is preceded by a '&' character.
- Alternatively the number can be followed by the letter K in which case
- it will be assumed to be a decimal number of Kilobytes (eg. 64K). There
- must not be a space between the number and the K.
-
- If there is no #SIZE directive before the first assembler statement a
- warning is given and 64K is allocated for the code. A #SIZE directives
- after the first assembler statement is ignored.
-
- 3.13 #END
-
- This takes no parameters and should be placed at the end of your
- assembler and before any Macro Function definitions. Anything after #END
- will be passed to Basic without the need for a '#' at the beginning of
- the line. When SAsm finds #END it assumes it has reached the end of the
- code and everything else is Macro Function definitions
-
- If DEFFN is found at the start of a line indicating that a Macro
- Function definition has been found before an #END directive a warning
- will be given and all subsequent lines will be passed to Basic.
-
- 3.14 #TYPE
-
- This defines the filetype for the assembled code. Syntax is #TYPE
- <filetype> where <filetype> is a valid filetype. If <filetype> is a
- number it must be in hex, though it need not be preceded by a '&'
- character. If it is a textual representation of a filetype it may or may
- not be in quotes, for example -
-
- # type FF8
- # type "Absolute"
- # type Module
-
- If you do not include #TYPE the assembled code will be saved as an
- absolute block of memory with no filetype. The most common filetypes are
- &FFC for a position independent Utility, &FF8 for an Application to be
- loaded and Run at &8000 and &FFA for a Relocatable Module.
-
- Unlike the previous examples #TYPE can appear anywhere in the source. If
- more than one #TYPE directive appears the last one will be used.
-
- 3.15 #OBJ
-
- Defines the name of the Object file. The syntax is #OBJ <filename> where
- <filename> can be any valid path/filename. If you type an object name at
- the Command Line it will override any #OBJ directive. You can therefore
- include an #OBJ directive in the source but assemble a different version
- if you choose by typing an Object name at the CLI.
-
- 3.16 #ERRFILE
-
- Followed by a path/file name this defines the error filename to be used.
- Again an error filename typed at the command line will override this
- directive.
-
- 3.17 #LIB
-
- Defines the Library file to be used. LIB should be followed by a
- path/file name. This overrides any Library defined in the SAsm$Lib
- variable.
-
- Using #LIB without a filename will force SAsm NOT to use a Library and
- so is equivalent to the command line 'L' switch.
-
- 3.18 # VERBOSE
-
- Equivalent to the command line 'V' switch to force display of names of
- macros inserted from a Library. The advantage over the 'V' command line
- switch is that it can be inserted at any point and so need not show all
- the expanded macros, only those used after the directive is used.
-
- 3.19 # QUIET
-
- Switches off display of macro names. You can use this with 'verbose' as
- often as you wish to switch on and off display of expanded macro names.
-
- 3.20 #INCLUDE
-
- This allows additional files to be 'included' as well as the ones
- specified at the command line. The word INCLUDE should be followed by at
- least one space and then a single filename. Unlike files loaded from the
- command line only the FIRST file which matches the required name will be
- used and no checks will be made on its filetype.
-
- The INCLUDE directive in SAsm is different from its equivalent in 'C'.
- SAsm does NOT 'insert' the file at the point at which the directive
- occurs. There is another directive INSERT which performs this function
- but this is not intended to be used for assembler source files.
-
- INCLUDE creates a 'queue' of INCLUDE filenames. When it reaches the end
- of the current file it goes to this list and loads the first name in the
- queue. When that file has been dealt with it loads the next name and so
- on until the queue is empty. If one of the 'include' files contains more
- INCLUDE directives these names are added to the END of the queue. When
- the queue is empty SAsm returns to the filenames specified at the
- command line and carries on as before.
-
- INCLUDE files can therefore have further INCLUDE directives which can
- contain their own INCLUDE's and so on.
-
- If you have a complex program which consists of lots of small pieces of
- code and sub-routines you can create a 'master' file which will contain
- the #ORG, #TYPE etc. directives and then a list of #INCLUDE directives
- to define the files required to make up the program. This operates in
- the same way as 'Make' files for other assemblers and compilers. SAsm
- will simply load each INCLUDE file in your 'primary' file in the order
- in which you have listed them. As INCLUDE files are subject to similar
- discrimination to filenames typed at the command line the 'trailing
- number suffix' system can be used to assemble the latest versions.
-
- For example, a file containing just the following would assemble the
- named files with the lowest trailing numbers in the chosen order.
-
- # type Absolute
- # size 1000
- # include start_*
- # include middle_*
- # include end_*
-
- 3.21 #INSERT
-
- This is used to 'insert' the file whose name follows into the code at
- that point. Unlike INCLUDE it is inserted directly into the code at the
- point at which the directive occurs. No filetype checking is carried out
- and only the first file found with a matching name is loaded. The file
- is not inserted during preprocessing but during assembly. It therefore
- cannot contain SAsm format assembler source but would normally consist
- of data required by the code. This could be sprites, screen images,
- templates, text or any other form of data. It could even be
- pre-assembled machine code although this is not likely to be usual.
-
- To reduce disc access the assembler merely 'makes room' on the first
- pass and actually loads the data on the second. Code or data following
- an INSERT directive will automatically be double-word aligned in case
- the file is of 'odd' size.
-
- 3.22 #AREA
-
- This is intended to simplify setting up Data Area consisting of a series
- of bytes or words to be accessed using LDR Rx,[<reg>,#<offset]. Normally
- this is done by reserving an area of memory in some way and defining
- each individual offset line like this -
-
- .my_data db *80,? ;reserve 80 bytes
- # first = 4
- # second = 8
- # third = 12
-
- and so on. You would then use instructions such as -
-
- ADR R8,label ;make R8 point to the data
- LDR R4,[R8,#second]
- STR R2,[R8,#third]
- LDR R1,my_data+second ;without using a 'pointer' register
-
- The problem with this method of setting up a data area is that every
- offset must be calculated 'by hand' and if you make a mistake the data
- can become corrupted at runtime. Also if you want to change the size of
- an item, for example, to increase a byte sized item to a word, then
- every other offset will need to be recalculated. Not only tedious but
- easily leading to mistakes.
-
- The AREA directive makes this type of data area much easier to define.
- It automatically sets the value of each offset and calculates and
- allocates the amount of space required. The syntax is very simple, but
- you will need to take careful note of exactly how it works to avoid
- errors.
-
- A data area is declared by the #AREA directive and this is followed by
- the name to be used to refer to it and the size of the first item, eg -
-
- # area my_data 4
-
- 'my_data' will then become a normal Global Label and can be addressed
- just like any other label. You can use LDR/STR instructions with it if
- you wish or ADR/ADRL to make a register point to it.
-
- The important part comes next. Following the first line you introduce a
- series of 'pointers' into the data area, defining the size of each as
- you do so. Note that unlike the normal method of doing this you define
- the SIZE of each item, not its offset from the start. To reproduce the
- previous example using the AREA directive -
-
- # area my_data 4
- first 4
- second 4
- third 4
- # ea
-
- Note that the AREA block is terminated by an #EA (End Area) directive.
-
- This will produce the same results as the previous example but it is
- much easier to set up. Instead of working out the offset of each pointer
- all you need to do is to follow its name with the size of the item that
- you want to put there. In this example each item will have four bytes
- allocated. If you wanted single bytes you would use -
-
- # area my_data 1
- first 1
- second 1
- third 1
- # ea
-
- Obviously sizes can be mixed. Only numerical values, in hex or
- decimal, can be used, variables will produce an error. Note that the
- number in the first declaration line defines the size of the first item
- which would normally be accessed by -
-
- LDR R0,[<reg>] or LDR R0,[my_data]
-
- As this item has an offset of 0 there is no need to define one for it.
- If you really do want to always refer to the first item with an offset
- then simply set the 'size' of this item to '0' so that the pointer
- defined on the following line will have an offset of 0.
-
- If you mix the sizes of items within a data area you may need to reset
- the pointer to ensure that sections are be word aligned. This can be
- done in the normal way with an ALIGN instruction. In fact ALIGN works
- differently when used in this context but its action is the same as
- usual.
-
- To illustrate this using mixed sizes as in the previous example -
-
- # area my_data 1
- first 1
- align
- second 4
- third 4
- # ea
-
- This will ensure that 'second' and 'third' have word aligned values.
-
- Note that this will ONLY be true if the START of the data area is word
- aligned. This will normally be the case but if in doubt use 'align' on
- the line BEFORE the #AREA directive. Similarly if you have used odd
- sizes items in your data area you should follow it with 'align' to
- ensure that any code or data which follows is word aligned.
-
- Within the confines of an AREA directive, ie. between #area and #ea,
- only the structures shown above are permitted. No assembler mnemonics or
- any other directives or statements are allowed. Items must be placed one
- per line exactly as shown. You can have comments, preceded by the usual
- ';' or '\', either following an item on the same line or on lines of
- their own. You can have blank lines if you wish.
-
- If any line in an AREA begins with a '#' character that will terminate
- the area. In fact, you don't really need an #ea directive, # on its own
- will do but you are advised to use #ea for clarity. If an AREA operation
- is terminated before the end because of an error you may get various
- error messages depending upon exactly what the cause was. You may also
- get an '#EA directive found when not in Data Area' message.
-
- At present the data in the area is not preset to any value. I may add a
- feature to do this at some time in the future.
-
- 3.23 Multiple data areas
-
- You can see that offset defined using #AREA become Global Variables.
- This makes it possible to define a series of identical data areas and
- use the same offsets to access them. This is particularly useful in
- programs which operate upon more than one set of data at the same time.
-
- To return to the previous example if you subsequently used -
-
- .label_2 db *40,?
-
- to reserve some space for a second area. Now -
-
- ADRL R8, label_2
- LDR R1,[R8,#second]
-
- will address an identical offset in the second area, but it may be better
- to use #STRUC for this
-
- 3.24 #STRUC
-
- This has almost the same syntax as #AREA exacept that it ends with #ES
- instead of #EA. The difference is that it does NOT reserve any memory,
- it just sets up the offsets and creates a 'structure' which can be
- transferred to RAM allocated elsewhere. These can then be used to
- address affsets in any data area, eg. in an extension of the Wimpslot,
- in a file header etc.
-
- Because #STRUC does not actually reserve any memory it can't use the
- label on the first line to point to it, as is done with #AREA. Therefore
- EVERYTHING after #AREA on the line is ignored. So, for example -
-
- # area
- first 4
- second &40
- third 28
- forth 4
- # es
- Would set up the variables first, second, third and forth such that if a
- register was set to point to a certain piece of memory then -
-
- <instruction>,[<reg>,#first] points to <reg>+0
- <instruction>,[<reg>,#second] points to <reg>+4
- <instruction>,[<reg>,#third] points to <reg>+&44
- <instruction>,[<reg>,#forth] points to <reg>+96
-
- and the entire data area would take 100 bytes. As you can see, this is
- extremely useful, and has equivalents in many high level languages. If
- you had wanted 'first' to have an offset this should have been placed on
- the first line after #STRUC.
-
- 3.25 #LISTON
-
- This will create a file which will contain an assembler listing. It may
- be followed by an 'F' which will produce a 'formatted' listing. The
- listing file will not start at the beginning of the source code but at
- the point at which the LISTON directive occurs. (See later section on
- Assembler Listing)
-
- 3.26 #LISTOFF
-
- Marks the point at which the assembler listing file will cease.
-
- 3.27 #LISTFILE
-
- Followed by a filename this sets the name to be used for an assembler
- listing file.
-
- 3.28 #NOENHANCE
-
- Switches off the second operand enhancements (see later). Included for
- untidy programmers who insist upon using instructions like MOV 1,2.
-
- 3.29 #ENHANCE
-
- Switches second operator enhancements on again. This is the default.
-
- 3.30 #XREF
-
- Switches on label cross reference. Once again the advantage of this over
- the 'X' switch is that it only takes effect from the point at which it
- appears.
-
- 3.31 #NOXREF
-
- Switches off label cross reference. Can be used as often as required
- with the previous command to toggle x-ref on and off.
-
- There is an obvious interaction between the 'X' command line parameter,
- the XREF directive and this directive. The x-ref will begin at the XREF
- directive unless the 'X' command line parameter is used, in which case
- it will start at the beginning of the first file. It will finish at the
- NOXREF directive if one appears, if not at the end of the last file.
-
- XREF and NOXREF can appear more than once in the files. The function
- will simply be switched on or off as they are encountered. Beware of
- leaving NOXREF directives scattered in your files. They could cause the
- x-ref to be disabled without you realising it and therefore prevent
- duplicate labels from being revealed.
-
- 3.32 #XRFILE
-
- Followed by a filename this sets the name for the label x-ref file if
- this is required. If duplicate labels are saved as a file they will not
- be displayed on screen, only the total number of duplicated names found
- will be shown. If no x-ref filename directive appears the listing will
- appear only on screen. If the XRFILE directive appears without a
- following filename then the default filename of 'xr_file" will be used.
-
- When shown on screen SAsm prints a message in the form -
-
- Warning : Duplicate label '<label>' at line <line number>
-
- where <label> is the duplicated label and <line number> is the number of
- the line on which the duplicate was found. There is no need to show the
- name of the file in which the duplicate was found because this will
- already have been displayed as SAsm loaded it. However when a duplicate
- list is saved as a file these filenames don't appear and so the name of
- the file in which each duplicate was discovered will also be shown.
-
- This directive doesn't initiate the x-ref, it just ensures that if it
- is enabledr from the command line or by the XREF directive then a file
- will be created. The directive must appear before the first label in the
- file or the file will not be created until the directive does appear.
- The obvious place for it is at the start of the file so that if you do
- invoke the x-ref function at any time the file will be available.
-
- 3.33 #LABELFILE
-
- The 'N' command line switch has already been described. This switch will
- produce a sorted list on screen of all the global labels that SAsm finds
- in the source files. Obviously this list can be very long and so the
- LABELFILE directive allows the label list to be sent to a file.
-
- As with other filename directives it should be followed by at least one
- space and then a path/file name. If the directive appears a following
- name then the default name 'LabelFile' will be used.
-
- This directive does not initiate a label listing, it just ensures that
- if you do want one it will go to a file and not to screen. You can place
- it in your source and if you do need a label listing at any time it will
- be in the form of a file. If the list is to be sent to a file the
- message-
-
- Creating label list file '<filename>'
-
- will be displayed and the label list will not be displayed on screen.
-
- As with screen display of labels they are arranged one per line in
- alphabetical order. The 'sorting' of names is case sensitive so 'Exit'
- will come before 'exit' and 'aAdvark' before 'aadvark'.
-
- As well as the 'N' switch there is a 'shortcut' which will produce a
- label list. If you hold down both SHIFT keys as you press RETURN when
- you type the SAsm command line this will initiate a label list just as
- if you had used the 'N' switch. As usual whether the list is to screen
- or a file will depend upon whether you have included the LABELFILE
- directive or not.
-
- 3.34 #SWION
-
- This switches on processing of SWI names. Normally if you wish to use
- the textual version of a SWI it must be enclosed in double quotes, eg
-
- SWI "OS_WriteC"
-
- Once this command or the command line 'S' switch has been used there is
- no need for the quotes, so you can simply use -
-
- SWI OS_WriteC
-
- It will also interpret any SWI number beginning with a '0' as a hex
- number, so that 'SWI 020' would be number 20 hex, 32 decimal, and not 20
- decimal.
-
- There are potential problems with this system which is why it is not
- made the default but must be deliberately activated. SAsm assumes that
- the parameter following a SWI instruction is a string if the first
- character is an upper case letter (A-Z). This should work because the
- names of all Acorn SWI's begin with a capital letter. So far as I am
- aware this also applies to all third-party modules. If a name begins
- with a lower case letter or a non-standard character such as an
- underscore it will not be recognised. The more likely problem would
- arise if you define constants for some SWI numbers. All is well if you
- give them names beginning with a lower case letter but if a name begins
- with a capital letter SAsm would regard it as a text version of a SWI
- and this would again produce an error. I have therefore decided that it
- is safer to make the user deliberately switch this on so that a program
- 'converted' from 'raw' Basic assembler should (!) always work without
- error. The user can then modify the source file and use this feature at
- his/her discretion.
-
- In general you should not experience difficulties if you ensure that if
- you do use a SWI name which begins with a lower case letter you enclose
- its name in quotes and if you define constants for SWI numbers you make
- sure that their name does not begin with a capital letter.
-
- 3.35 #SWIOFF
-
- Switches off SWI name processing described above.
-
- 3.36 #CLI
-
- Anything on the line after this directive will be passed DIRECTLY to the
- operating system Command Line Interpreter. It is equivalent to a '*'
- command used in a Basic program. It is not like the Basic 'OSCLI'
- command as no substitution is carried out first. You should not put
- comments on the line after a #CLI directive, it won't bother SAsm but it
- might confuse the OS.
-
- 3.37 Labels and Variables
-
- A label in SAsm is no different from any other variable. You must be
- careful not to use the same name for a label as a variable. I advise you
- use Basic Integer Variables for variables to minimise the possibility of
- problems. You should try to decide upon a 'system' so you don't
- inadvertently cause a conflict. I use only lower case letters in labels,
- but if I wish to create a variable I use an upper case character as the
- first letter of its name. This makes it obvious to me when reading code
- or comments whether I am referring to a variable or a label.
-
- Obviously variables will not be shown in the Label List, so if your code
- misbehaves and shows all the symptoms of a duplicate label but x-ref
- can't find it, examine your variables.
-
- 3.38 Defining Registers
-
- To simplify writing code it is normal to give the C.P.U. registers names
- and define various other constants. In Basic this is done by assigning
- the chosen name a number using the syntax <name>=<number>. The same
- method is used with SAsm except that you must precede your definitions
- with '#'. For example, to define register 5 as 'count' and register 6 as
- 'flag'
-
- # count = 5
- # flag = 6
-
- or alternatively
-
- # count=5:flag=6
-
- R13,R14 and R15 are pre-defined as 'sp', 'link' and 'pc' in upper and
- lower case. All registers are pre defined as their equivalent 'r' and
- 'R' numbers. Basic doesn't recognise a number like 'r4' as meaning
- register number 4 except when it is an assembler operand. If you try to
- pass 'r4' as a parameter an error would be generated. With SAsm you can
- use r0-r15 or R0-R15 as they have been pre defined.
-
- You can use this method to define SWI's, offsets in a data area, in fact
- anything you wish. Since these are normal Basic variables you can use
- integer and string variables if required.
-
- 3.39 Defining constants
-
- Most code begins with a long list of constant definitions. For example,
- you will probably want to give names to registers, use variables to
- define the size of data areas and buffers, string variables for program
- version and support file names etc. This could, of course, be done as
- described above with a series of '#' statements but it is more elegant
- to use a standard Basic procedure.
-
- Remember that everything after the #END statement is just normal Basic.
- Therefore you can write a perfectly ordinary procedure after #END to
- define all your constants. Then, at the start of the first file, before
- the first assembler statement, put a call to this procedure, eg.
-
- # PROCdefine
-
- This will call the procedure and define all your constants.
-
- One thing you should be aware of is that everything from the start of
- the file up to the END directive is within the assembler loop. As it is
- a two pass assembler all constant declarations and procedures are
- enacted before each assembler pass. In the previous example PROCdefine
- would also be called before the second pass. This does not matter unless
- you have deliberately altered a variable at some stage in the program.
- If you have done so you should be aware that it will be reset before the
- second pass. If you particularly want a variable to be set only during
- the first pass then you could check the state if the variable PASS to
- ensure that the variable is not reset during the second pass.
-
- 3.40 Conditional Assembly
-
- This works as with the Basic assembler, normally using IF THEN, (ELSE),
- ENDIF. If you are unfamiliar with this please read the 'Tutorial' file.
- With SAsm there is no need to bother with assembler brackets, etc. Just
- put '#' in front of the lines which form the conditional block.
-
- # IF <condition> THEN
- ......... ; some code
- .........
- .........
- # ELSE
- ......... ; the alternative code
- .........
- .........
- # ENDIF
-
- Don't forget the 'THEN' at the end of the 'IF' line. The 'ELSE' section
- is of course optional.
-
- If an error occurs in a conditional section you may find subsequent
- 'ELSE found without IF' or 'ENDIF found without IF' errors occurring.
- This is not significant, it just means the assembler has 'forgotten' it
- was in a conditional section when the original error was discovered.
-
- There is no reason why you cannot use other methods for more complex
- multiple choice options. For example the CASE statement could be used.
-
- # CASE <condition> OF
- # WHEN <condition 1>
- ......... ; some code
- .........
- .........
- # WHEN <condition 2>
- ......... ; some code
- .........
- .........
- # WHEN <condition 3>
- ......... ; some code
- .........
- .........
- # OTHERWISE
- ......... ; the alternative code
- .........
- .........
- # ENDCASE
-
- The OTHERWISE section is, of course, optional.
-
- 3.41 LDM and STM instructions with Writeback
-
- LDM/STM are mainly used for stack management although they can be used
- for multiple register transfer to and from memory. Usually they will be
- used with Writeback in the form -
-
- LDMIA <reg> !,{<list>}
-
- With the Basic assembler it is necessary to leave a space between <reg>
- and the '!' character if a name has been assigned to the stack pointer
- register. Otherwise the Basic assembler isn't bright enough to interpret
- the instruction correctly and assumes that you are using some sort of
- contorted indirection to define the pointer register and tries to
- interpret the '!' as an indirection operator. This means that something
- like -
-
- STMIA sp !,{pc ,link}
-
- is required with a space before the '!'
-
- On the assumption that you are probably not doing anything like this
- SAsm permits the use of the '!' character without an intervening space
- so that the more natural -
-
- STMIA sp!,{pc ,link}
-
- is permitted.
-
- 3.42 Assembly Loops
-
- With the Basic assembler it is common to use FOR-NEXT loops to fill an
- area of memory, eg.
-
- ] :REM exit assembler
- FOR I%=0 TO 255
- [ OPT PASS
- EQUB &FF ;fill 256 bytes with &FF
- ]
- NEXT
- [ OPT PASS ;back to assembler again
-
- You could still use this method with SAsm if you wish but it is simpler
-
- ........ ;normal code
- # FOR I%=0 TO 255
- EQUB &FF
- # NEXT
- ........ ;normal code again
-
- In fact SAsm has a much better way to assign and fill an area of memory
- using the DB mnemonic.
-
- 3.43 The OSET variable
-
- With the Basic assembler you may want to 'poke' values into a data area
- after assembly, or you may wish to modify data in some way. As you would
- be aware of the address of the start of your code in memory, the offset
- used by the O% variable, and you will presumably have inserted a label
- at some convenient point as a marker, you would be able to calculate the
- exact location you wish to change. With SAsm the actual address of a
- location is hidden from the user so the variable OSET is set to give you
- a 'base' to use for these purposes.
-
- During assembly OSET is set such that OSET+<label> where <label> is any
- normal global label will point to the location IN MEMORY of <label>. For
- example, to 'poke' the string 'version$' into the location defined by
- the label 'version' you would use -
-
- # $(OSET+version) = version$
-
- You can, of course, add an offset to <label> if you wish. For example,
- to 'blank' 256 bytes from the label 'buffer' you could use
-
- # FOR I%=buffer TO buffer+255
- # ?(OSET+I%)=0
- # NEXT
-
- Both of these examples are contrived and the same results could be more
- efficiently be produced by other means. The most likely use for the OSET
- variable would be to disguise particular data in your code in some way.
- This makes it possible to compose text in plain language when writing
- the code but garble it after assembly.
-
- 3.44 Assembly Listing
-
- SAsm does not normally produce an assembly listing. Not only would this
- obscure any Error or Warning messages it also slows down assembly.
-
- It can be useful to to see exactly what has happened to the source code
- after pre-processing. For example, to check that a macro has been
- expanded or a complex DB statement properly interpreted. SAsm has no
- provision for displaying an assembler listing on screen. This could be
- done by altering the OPT setting, directly manipulating the variable Q%,
- and programmers experienced in using the Basic assembler will be able to
- do this. This is not normally to be advised. Instead SAsm allows an
- assembler listing file to be created. This can be loaded into a text
- editor and examined at leisure. Two different layouts are available,
- Standard and Formatted.
-
- The Standard format produces a 'compact' listing with no spare spaces or
- column indenting. This makes it rather cramped and difficult to read but
- less than half the size of a Formatted file. This may be best if you are
- using floppy discs and require a listing of all or a large part of your
- code.
-
- The Formatted listing produces a file with labels in the left hand
- column. Mnemonics are indented by 24 spaces and operands indented by a
- further eight places. This makes the code much easier to read but it
- will probably double or treble the size of the file.
-
- In both cases only lines containing assembler are reproduced and all
- comments are stripped. All other lines, including blank lines, are
- ignored. There is therefore no direct line-to-line correlation with the
- original source file(s). (I'll include a switch to change this later).
-
- The listing file is written one line at a time so the operation is
- slower than other SAsm file operations. Using a hard disc or RAM disc
- even a large file will only take one or two second but with a floppy
- disc it could take several. The message 'Creating listing file' will
- appear at the start of the operation and it's end is signalled when the
- message 'Pre processing completed - starting assembly' appears.
-
- 3.45 Creating a listing file
-
- Listing files are created by typing the parameters at the command line,
- by inserting suitable directives, or by a combination of both methods.
-
- The command line parameter is 'A' (for Assembler). This should be
- followed by the filename required. Remember that whatever follows the
- 'A' parameter will become the filename so if, for example, you also want
- a label cross-reference and type an 'X' after the 'A' you won't get a
- x-ref but you will get a listing file called 'X'.
-
- If you don't follow the 'A' with a filename and it is the last parameter
- typed a default name of 'ListFile' will be used and the file will be
- created in the Currently Selected Directory. Assuming no other
- directives are used this will result in a listing file consisting of all
- the source files. If you have used the 'F' parameter this will be a
- Formatted file, if not it will be compact.
-
- 3.46 Listing file directives
-
- Assembler listing files can be produced instead of or in addition to
- Object and/or Error files.
-
- There are three directives relating to listing files, LISTON, LISTOFF
- and LISTFILE. These are used to define the start point in the code from
- which a listing file will be created, the end point at which the listing
- file will finish, and the name to be given to the file.
-
- LISTFILE is followed by the path/name you wish to assign to the file. As
- the listing file is not created until all source files have been loaded
- it does not matter where in the source the LISTFILE directive appears.
- If there is more than one LISTFILE directive the last one found will
- apply. Any filename typed at the command line will override a directive
- filename and in this case a message to this effect will be displayed.
-
- By default a listing file begins with the first assembler statement and
- finish with the END directive. Most of the time you will only need to
- see a small part of the code and so LISTON and LISTOFF are used to mark
- the beginning and end of the file.
-
- If LISTON is followed by an 'F' or if an 'F' parameter was used at the
- command line then the file will be formatted.
-
- Note that LISTFILE of itself does not produce a listing file, it merely
- defines the filename which will be used if a file is required.
-
- 3.47 Scope of a listing file
-
- You should understand how these commands and directives work to ensure
- that you get a listing of the required section of code. By default the
- listing file starts with the first assembler statement and stops with
- the #END directive. These start and end points are modified each time
- SAsm encounters a LISTON or LISTOFF directive. If there is more than one
- of either or both then the last one encountered will be the one which
- applies. It is therefore possible if a LISTON directive is encountered
- after the last LISTOFF directive for the required start of the listing
- to apparently be after the end. In this case SAsm will not be able to
- produce the file and will simply display an error message.
-
- If there is no LISTON directive the listing file will begin at the first
- assembler directive and continue until the LISTOFF directive. If there
- is no LISTOFF directive it will begin at the LISTON directive and
- continue until the END directive.
-
- Labels
- ======
- 4.1 Global Labels
-
- All labels and variables are common throughout all files. You must
- remember this or strange things can happen. With SAsm you don't need to
- declare labels external, they are ALWAYS global.
-
- Adding the parameter 'X' to the command line invokes the label cross
- reference. This checks all labels and reports multiple definitions. For
- reasons already explained multiple definitions of a label are classed as
- Warnings only and not Errors. If you use labels like 'loop' or 'bak' to
- form short loops you will need to visually check the list of duplicates
- for 'foreign' names.
-
- 4.2 Local Labels
-
- Since it is tedious to invent names for all the labels you need to make
- short jumps and loops a system of Local Labels has been included. These
- are defined in the same way as normal labels, ie. by preceding the label
- with a full stop. Local labels MUST be defined at the start of the line,
- which is good practice anyway, and consist of a two digit decimal number
- 00-99.
-
- You are advised to read the following section carefully and ensure that
- you understand exactly how this system operates. It's perfectly
- straightforward and easy to use but if you don't use it properly you
- will get repeated errors or branches to the wrong destination.
-
- 4.3 Local label scope
-
- You start each set of local labels with label '00' When SAsm finds
- label 00 it forgets all previous local labels. You can therefore use the
- numbers 00 to 99 repeatedly and each label will only apply within its
- own section. When you start a new section of code or sub-routine make
- the first label 00 You can use label 00 even where a label is not
- actually needed to ensure that the scope of the current set of local
- labels is ended. Normally a reference to a local label will only apply
- to the label within that 'set', but you can refer to the previous and
- next sets and this will be described later
-
- Local labels can ONLY be used with Branch (or BL) and as the second
- operand in LDR and STR instructions, with or without conditions, and
- with the ADR or ADRL pseudo-opcode. They cannot be used within Macro
- Functions but they can be used in Expanded macros. You will soon find
- that you will use local labels for all the loops and short jumps in a
- section, using meaningful labels where appropriate. This makes the code
- much easier to follow because the main labels which define entry points
- and complete routines stand out.
-
- 4.4 Using local lables
-
- There are some restrictions upon local labels which you should be aware
- of. They cannot be used as the operand of some instructions or psuedo
- opcodes. They can be used with all branch instructions, ADR, ADRL, LDR
- and STR. They cannot be passed as parameters to functions or expanded
- macros. They cannot be used in Macro Functions or anywhere after the END
- directive.
-
- A local label only has a meaningful value when used in the correct
- manner within its own scope. If you define labels 00, 01 and 02 in one
- section an attempt to branch to 03 within that section will produce an
- error, not a branch to 03 in the previous or next section.
-
- Although there are 100 individual labels available in any section this
- is far more than you should ever need. I find it best to divide each set
- into sub-sections so that each loop or sub-sub-routine has its own
- sub-set of labels. The first uses 00-09, the next 10-19, then 20-29 etc.
- This makes the code easier to read and ensures that there are spare
- labels in each sub-set if I need to add extra code later. You don't need
- to define the labels in any particular order provided you start at 00,
- it just looks neater and makes it easier to follow the flow of the code
- because a branch to a low number will go back towards the beginning of
- the section and to a high number forward to the end.
-
- Local labels are not checked by the x-ref routine. If you duplicate a
- local label within its set you will get the same problems as with any
- other duplicate label. This should not be a problem in practice,
- especially if you define labels in numerical order, because each set of
- labels will normally fit within a couple of 'screens' of code and
- duplicate or out of sequence labels can be plainly seen.
-
- The maximum number of sets of local labels is over 2700, which is enough
- for any eventuality.
-
- 4.5 Previous or Next sets of labels
-
- It is possible to refer to a local label in the previous or next 'set'.
- Normally a reference to a local label would only apply to the label
- within its own set, but by preceding the label number with a '>' or '<'
- character you can refer to the next or previous set respectively. There
- must not be a space between the '>' or '<' and the first digit of the
- label number.
-
- Obviously for this to work the label must exist in the set referred to
- or you will get an error
-
- 4.6 Example
-
- Any Branch instruction will only reach back to the last 00 label and
- forward to (but not including) the next, except where the '>' and '<'
- modifiers are used. There can be no overlapping of local label sets. The
- following example should make this clear.
-
- .00 ........ ; some code
- ........
- .01 ........
- ........
- ........
- .02 BNE 01 ; This will branch BACK to the last 01
- ........
- ........
- .00 ........ ; This starts a new section of labels
- BGT 01 ; Branch FORWARD to 01 in this section
- ........
- ........
- .01 ........
- BEQ 02 ; This will produce an error as 02 is
- ........ ; not defined in this section
- ........
- BLT 00 ; Branch BACK to the last 00
- .00 ........ ; Start another section
- ........
- ADR r1,00 ; Put address of the LAST 00 in R1
- ADR r2,01 ; put address of the NEXT 01 in R2
- ........
- .01 ........
-
- 4.7 Examples with prev/next set
-
- You can refer to a local label in the next or previous set by using the
- '>' and '<' characters as modifiers. For example -
-
- ADR r1,>01
-
- would make r1 point to '01' in the NEXT set of local labels, and -
-
- ADR r1,<04
-
- would make it point to '04' in the PREVIOUS set.
-
- Modifiers can be employed wherever a local label can be used. Note that
- there must not be a space between the prefix and the label number. It is
- particularly useful for separating data and code. You can use a
- different set of labels for each to minimise the chance of errors but,
- providing the data immediately precedes or follows the code which uses
- it, it can still be accessed.
-
- Although modifiers can be used within expanded macros they must only
- refer to label sets defined within that macro. They cannot be used to
- refer to a label set in code before or after the macro itself.
-
- 4.8 Forward branch to 00
-
- This was previously a source of many errors as experienced programmers
- are used to being able to branch forward to a label, especially if they
- can actually see it in front of them on the screen.
-
- Consider this short piece of code;
-
- cmp r0,#32
- bne 00
- ........ ;code to be skipped if r0 not 32
- ........
- .00 ........ ;rest of code
-
- This won't work. The branch would go BACKWARDS to the last 00. To branch
- forward to '00'. However, it is now possible to achieve the desired
- object by using the '>' prefix, for example -
-
- bne >00
-
- would work properly.
-
- 4.9 Problems with local labels
-
- The most common problems occur when users do not understand the scope of
- a local label. This has been covered fully and is very simple, but it
- still seems to cause problems, so check this first.
-
- Remember that a local label must be defined at the beginning of the
- line. With the Basic assembler you could use -
-
- .label_1 mov r0,#4 : mov r1,#5 : .label_2
-
- This will still work with SAsm but NOT if the second label is a local
- label. From the earlier example you can see that -
-
- .90 : mov r0,#4 : mov r1,#5 : .00
-
- wouldn't work. The two labels must be on separate lines.
-
- Special Features
- ================
- 5.1 Enhanced 2nd operand
-
- This operates on the second operand of instructions CMP, MOV, TST and
- TEQ. It will work whether or not the instruction is conditional but it
- can NOT be used with CMN or MVN (yet!). For it to work there must be a
- space between the opcode and the first operand.
-
- The aim is to make it easier when the second operand is an immediate
- value rather than another register. The Basic assembler requires the
- second operand to have a leading '#' character for it to be recognised
- as an immediate value. SAsm will accept this but will also recognise
- most immediate numeric operands.
-
- If the second operand begins with a digit 0-9, an '&', a '%' or is
- enclosed in double quotes SAsm will assume that it is an immediate value
- whether or not it is preceded by '#'. There is also no need to use the
- Basic 'ASC' prefix if a character is enclosed in double quotation marks.
- For example -
-
- SAsm Basic Assembler equivalent
-
- cmp r0,"A" cmp r0,#ASC"A"
- mov r0,020 mov r0,#&20
- mov r2,"z"+1 mov r2,#ASC"z"+1
- mov r2,1+"z" !Error - won't recognize "z" as an ascii value
- cmpne r0,13 cmpne r0,#13
- teq r0,"m" teq r0,#ASC"m"
- cmp r0,%110 cmp r0,#%110
- mov r0,&A4 mov r0,#&A4
- mov r0,0A4 mov r0,#&A4
- mov r0,A4 !Error - A4 won't be recognised as a number
-
- As you can see this makes the code easier to read and also avoids errors
- if you forget the '#'.
-
- Note that you can ONLY use these shortcuts when the number is obviously
- an immediate value. If it is a variable you must still use '#'.
-
- WARNING - With this system an actual number in the second operand
- position is always assumed to be an immediate value. If you really DO
- mean a register you will have problems. For example, the instruction
- 'mov 1,3' is interpreted by the Basic assembler as 'copy the contents of
- register r3 into register r1' but by SAsm as 'load register r1 with the
- immediate value 3'.
-
- To avoid this ambiguity it is usual when writing ARM code to prefix
- register numbers with 'r' or 'R', but this is not compulsory and the
- Basic assembler doesn't require it. If you have fallen into bad habits
- and just use a simple register number then you will have problems.
-
- There are two possible solutions. Firstly you could mend your ways and
- refer to registers properly like everyone else. Secondly you could use
- the #NOENHANCE directive to disable this feature.
-
- 5.2 Extra mnemonics
-
- These are not actually mnemonics but macros which are expanded by the
- preprocessor. They are used in the code just like normal opcodes and so
- the distinction can normally be ignored. One important difference is
- that unlike normal mnemonics some CANNOT have conditional suffixes.
-
- Some call the built-in macro functions and you should refer to these for
- clarification if required.
-
- They may all be written in upper or lower case like normal assembler
- mnemonics.
-
- 5.3 DW and DD
-
- These are expansions of EQUD and EQUW and in fact are translated into
- these when expanded. The main advantage is that DW and DD can be used to
- reserve a series of words or double words and not just one at a time.
- These follow the mnemonic as a comma separated list. For example -
-
- DD 1,2,3,4,5,6
-
- would be expanded by the preprocessor to -
-
- EQUD 1:EQUD 2:EQUD 3:EQUD 4:EQUD 5:EQUD 6
-
- which can save a lot of typing.
-
- Because the line will actually become longer, which is obvious from
- looking at the above example, it is possible for these (and DB which
- follows) to make the line expand beyond the permitted limit of 255
- characters. You should therefore avoid putting too many items on a
- single line.
-
- If any of the numbers begin with a zero SAsm will assume the number is
- in hex format, whether or not it is preceded by an '&' character. For
- example '20' would be decimal 20 but '020' would be translated as &20,
- eg. hex 20 which is decimal 32.
-
- 5.4 DB
-
- This is a general purpose macro which replaces EQUB and EQUS and also
- allows an area of memory to be reserved for data and preset to any value
- if required.
-
- In it's simplest form DB is like DW and DB but with bytes as a multiple
- EQUB. If the parameter is a string enclosed in double quotes it acts
- like EQUS. These can be mixed in the same DB command which makes
- defining strings with control codes much easier. For example -
-
- DB 7,"Some text",10,13,"New line",0
-
- would be expanded to -
-
- EQUB 7:EQUS "Some text":EQUB 10:EQUB 13:EQUS "New line":EQUB 0
-
- As with DW and DD beware of allowing the line to become too long.
-
- Again numbers beginning with a zero will be regarded as hexadecimal.
-
- DB can be used with a multiplier to reserve an area of memory and set it
- to any value. If a parameter begins with '*' then the following number
- is taken as a multiplier and the number after that as the value to be
- inserted. For example -
-
- DB *100,32 (which could also be written as DB *100," " )
-
- would reserve 100 bytes as a data area and load them with the value 32,
- a space character.
-
- This can be mixed with strings and single bytes and can be used rather
- like SPC or STRING$ in Basic. For example -
-
- DB "1",*10,32,*8,".",*10,32,"First Menu Item",0
-
- would be expanded to the zero terminated string -
-
- 1 ........ First Menu Item
-
- One advantage of this is that the multiplier need not be an actual
- number but could be an expression. This makes it a lot easier to change
- the size of data areas or the length of strings by simply altering the
- value of the variable.
-
- If you just wish to reserve an area of memory and do not need it to be
- set to any particular value then using a question mark as the value
- after the multiplier will do so. For example
-
- DB *100,?
-
- would reserve 100 bytes but leave the area set to whatever random data
- already existed there.
-
- 5.5 Basic variables and DB
-
- You can use variables instead of constants with DB. With the Basic
- assembler you could use -
-
- EQUD <var1> : EQUB <var2> : EQUB <var3>
-
- so with SAsm you could use -
-
- DB <var1>, <var2>, <var3>
-
- The previous examples using strings have shown an immediate string
- enclosed in double quotes. With the Basic assembler it is possible to
- use a Basic string variable with EQUS, eg.
-
- EQUS version$
-
- In earlier versions of SAsm this couldn't be done with DB but it is now
- permitted. SAsm will recognise any variable ending in the '$' character
- as a string so the 'DB variable$' will now equate to EQUS variable$. You
- can also use string concatenation, eg.
-
- DB prog_name$ + version$
- DB prog_name$ + " Version "+version$
- DB prog_name$ + STR$(version_number)
- DB "A String"+CHR$(7)
-
- although in the last case it would actually be neater to use -
-
- DB "A String",7
-
- For string concatenation to work with immediate strings the '+' must
- IMMEDIATELY follow the closing quotes as in the above examples.
-
- Immediate strings must be enclosed in double quotes. It would be
- possible to modify SAsm to allow single quotes as in many other
- assemblers but this would then make it impossible to permit this
- character inside immediate strings.
-
- SAsm will not recognise Basic strings defined with the '$' indirection
- indicator. With the Basic assembler you could use -
-
- EQUS $location%
-
- which would use the cr terminated string at 'location%'. This won't work
- using DB but it is so unlikely that it would be needed that I don't
- regard this as a problem. There may be other combinations of variables
- that won't work with DB, if you do have any difficulties please tell me.
-
- 5.6 ADRL
-
- This is a two instruction 16 bit ADR directive. It takes the same
- parameters as the normal ADR directive, that is the syntax is -
-
- ADRL <register>,<location>
-
- ADRL will always assemble two instructions when <location> is greater
- then the current address. This is because the exact position of
- <location> will not be determined until the second pass. However if
- <location> is before the current address it's position will already be
- known and so a single instruction will be assembled whenever possible.
-
- If code length or speed is important you could use the ADR instruction
- until you get an 'out of range' error to ensure that no superfluous
- instructions are included.
-
- There MUST be a space between ADRL and <register> and it can be
- conditional
-
- 5.7 MOVL
-
- This is a method of loading a large immediate number into a register. A
- series of ADD or SUB instructions will be assembled to load the value.
- The syntax is MOVL <reg>,<number>. If <number> begins with a zero it
- will be regarded as hexadecimal. <number> can of course be positive or
- negative. If it is negative then MVN instructions may be used by the
- macro but DO NOT adjust the number to allow for this as is required by
- the normal MVN instruction. The macro will make all the adjustments
- necessary so just write the actual number you require.
-
- This macro is fairly simple and may not produce the most efficient code
- for loading a given value. If speed or code length is paramount it may
- be possible to reduce the number of operations by hand coding.
-
- There MUST be a space between MOVL and <reg> and it can be conditional
-
- 5.8 DIV
-
- This macro will perform a 32 bit integer division. The full syntax is;
-
- DIV <dividend reg>,<divider reg>,<quotient reg>,<temp reg>
-
- It therefore requires four DIFFERENT registers as its parameters and you
- are responsible for loading the correct values into the registers before
- using DIV. The results returned are;
-
- <quotient reg> = <dividend reg> DIV <divider reg>
- <dividend reg> = <dividend reg> MOD <divider reg>
-
- The <temp reg> is used for working only and will be corrupted.
-
- For example, to divide a number in R0 by a number in R1 and return the
- result in R2 using R3 as temporary workspace use;
-
- div r0,r1,r2,r3
-
- On exit r1 will be unchanged and r0 will contain the remainder if the
- number did not divide exactly.
-
- There MUST be a space between DIV and <register> and that because it
- expands to a large section of code it CANNOT be made conditional.
-
- Note -
-
- I have received complaints informing me that DIV doesn't work and just
- gives error messages. It does work perfectly. Most of these complaints
- turned out to be from people who hadn't read (or hadn't understood) the
- instructions. The parameters passed to DIV are the numbers of the
- REGISTERS it will use, not the actual numbers to be divided. You are
- responsible for writing code to load the actual values into these
- registers before using DIV to do the division. There is also no error
- checking. If you try to do something silly like divide by zero you could
- end up with your code either crashing or going into an infinite loop.
-
- If you want a general purpose division routine I suggest you write a
- sub-routine or expanded macro which deals with all of these things and
- uses DIV to do the actual work.
-
- Macros
- ======
-
- Sasm supports two types of Macros. Expanded Macros and Macro Functions.
- There are advantages and disadvantages with each type. Both can be
- included in your Macro Library.
-
- 6.1 Macro Functions - Pro/Con
-
- These are normal Basic Functions and their use and format is described
- in the 'Tutorial'. They have two disadvantages. Firstly, because they
- are Basic Functions you must include assembler brackets, OPT setting,
- etc. and forward branches are awkward. Secondly it is not possible to
- use any of the special features of SAsm such as local labels, db, adrl,
- movl, etc. within a Macro Function. Also you cannot call or define an
- Expanded Macro from within a Macro Function.
-
- A serious disadvantage is that SAsm cannot recover from an error in a
- Macro Function. Such errors are Fatal and will produce an error message
- giving a line number that does not exist in the file.
-
- The first advantage is that this type of macro is not expanded by the
- pre processor so no matter how many times you use it no more memory is
- used. The second advantage will only apply if you use a Macro Library
- without a hard disc. This is because a Macro Function only appears once,
- at the end of the code, and so only one disc access to load it from the
- Library will be required.
-
- 6.2 Expanded Macros - Pro/Con
-
- These are sections of code which are inserted into the file each time
- the Macro is invoked. The big advantage with this method is that you can
- use all the special features of SAsm, local labels, etc. You can also
- call Macro Functions or other Expanded Macros from within this type of
- macro.
-
- Because Expanded Macros become part of the normal code SAsm can normally
- recover from errors in them in the same way as it can recover from most
- other errors.
-
- The disadvantage is that an Expanded Macro must be defined before it is
- used, although it can be defined in your Macro Library. Also as the
- macro code is inserted into your source each time it is used more memory
- is required, although this unlikely to be a problem in practice.
-
- 6.3 Macro Names
-
- Because Macro Functions and Expanded Macros are different they can have
- the same name. You can even have Expanded Macros and Macro Functions
- with the same name in your Library. SAsm will sort out which to use.
-
- 6.4 Expanded Macros
-
- An Expanded Macro must be defined before it is used. If you use a Macro
- Library it may be defined there and it will be loaded from the Library.
- If you define a macro in the source file and one of the same name exists
- in the Library then the macro in the source file will be used.
-
- 6.5 Defining Expanded Macros
-
- An expanded macro is defined as follows.
-
- # SM <name>
- ........ \
- ........ > Normal SAsm code
- ........ /
- # EM
-
- and invoked by -
-
- @ <name>
-
- In each case <name> is the name given to the macro and, like the
- parameters, is case sensitive. Like other SAsm directives the '#' used
- by #SM (Start Macro) and #EM (End Macro) must be the first characters on
- the line. The '@' character should be the first non-space character on
- the line or, if the line starts with a label, the first non space
- character after the label. There must not be ANYTHING on the line after
- the macro call except a comment, defined in the usual way.
-
- When SAsm encounters '@' it tries to match the following name with a
- previously defined macro. When found it inserts a copy of the code into
- the file. If there are locaL labels in a macro they will be unique
- within that definition, but non-local labels will be global.
-
- 6.6 Macro Parameters
-
- You can pass parameters of almost any type to an Expanded Macro. The
- syntax of the defining line of the start of a macro is -
-
- # sm <name> <param 1> , <param 2> , <param 3> ....
-
- and of the calling line -
-
- @ <name> <param val 1> , <param val 2> , <param val 3> ....
-
- where <name> is the name given to the macro, <param> is the name given
- to a parameter and <param val> is the value the parameter will be given
- when the macro is expanded. There must be at least one space between
- <name> and the first parameter and parameters are separated by commas.
-
- A parameter is a Global Variable and must conform to the Basic variable
- type for the value it will hold. It can be Integer, String or Floating
- Point. The parameter passed must be suitable for that type of variable.
- It need not be a constant value. Any expression which can be evaluated
- during assembly to the correct type of variable may be used.
-
- You may recognise that the syntax has been made identical to the way
- that parameters are passed to Basic Functions and Procedures except that
- there are no brackets.
-
- 6.7 Local Labels in Expanded Macros
-
- Local labels can be used in expanded macros and these must conform to
- the syntax used elsewhere. You MUST start local labels in a macro
- definition with '00' to ensure that the labels will be unique.
-
- When the macro expansion ends the 'flow' of local labels in the main
- code before the macro was used will be restored. A macro, with its own
- set of local labels, can exist within the area of normal local labels
- without confusion. In practical terms this means that, provided you
- ensure that any local labels used in a macro start with '00', you can
- ignore the fact that a macro exists for the purposes of local labels in
- the main code.
-
- Similarly if expanded macros are nested then any local labels defined
- will be unique within that invocation and the labels in the calling
- macro will branch around labels in the called macro.
-
- Remember that, like all non local labels, any other labels defined in an
- expanded macro will become global and will assume the value assigned in
- the current invocation.
-
- You should understand that the '<' and '>' modifiers will only apply to
- the previous and next sets of local labels within the actual macro. They
- cannot be used to access code outside the macro, and any attempt to do
- so will produce an error.
-
- 6.8 Special features of Expanded macros
-
- The biggest advantage of expanded macros is that you can take advantage
- of the special features of SAsm when using them. The ADRL, MOVL DB, DW
- and DD pseudo-ops can be used if required.
-
- You can call Macro Functions and other Expanded Macros can be invoked
- from within macros. Expanded Macros can be 'nested' to a maximum depth
- of twenty. In theory this could be greater but I couldn't think of any
- (non-contrived) circumstance when I would need more than four or five so
- I limited it to twenty.
-
- Expanded Macros must NOT be invoked recursively. This would set up an
- infinite loop which would cause all available memory to be filled. This
- is another reason for limiting nesting of macros because if this is done
- by accident an error will be flagged long before this stage is reached.
-
- 6.9 Example
-
- This is an example of how you could use a macro to print a string at any
- location on the screen. Note that as usual I have used more spaces than
- are actually necessary to make things clearer.
-
- # SM print_tab x_pos , y_pos , display$
- swi 256+31
- swi 256+x_pos
- swi 256+y_pos
- swi OS_WriteS
- equs display$
- equb 0
- align
- # EM
-
- The operation of the code should be obvious. Firstly there is the
- equivalent of 'VDU 31, x_pos, y_pos' to position the text cursor where
- required. OS_WriteS is then used to print the text which is placed in
- memory immediately after it.
-
- So, to print 'This is a test' at column 10, line 4 you would use
-
- @ print_tab 10,4,"This is a test"
-
- To illustrate nesting macros the following example splits this procedure
- into two separate macros, one of which uses the other.
-
- # SM do_tab x , y
- swi 256+31
- swi 256+x
- swi 256+y
- # EM
- # SM print_tab x_pos , y_pos , display$
- @ do_tab x_pos, y_pos
- swi OS_WriteS
- equs display$
- equb 0
- align
- # EM
-
- This would be used in exactly the same way as the previous example, but
- note that as 'print_tab' uses 'do_tab' then 'do_tab' must be defined
- before it can be used in 'print_tab'.
-
- @ print_tab 10,4,"This is a test"
-
- Would give the same results, and in this instance the code actually
- assembled would be exactly the same.
-
- In fact, it could be split still more. Leaving the macro 'do_tab' as
- previously defined;
-
- # SM print_string string$
- swi OS_WriteS
- equs string$
- equb 0
- align
- # EM
- # SM print_tab x_pos , y_pos , display$
- @ do_tab x_pos,y_pos
- @ print_string display$
- # EM
-
- Once again exactly the same actual code would be assembled.
-
- 6.10 Errors in Expanded macros
-
- SAsm should be able to recover from errors in expanded macros. The error
- message will be slightly different from normal and in the form;
-
- Error <message> at line <number> in Macro <macro name> at line
- <line number> in file <file name>
-
- The line number in the file will be the line where the macro was
- invoked. The line number within the macro will be the offset from the
- start of the macro where the error occurred. If this was the invoking
- line then the error will be shown as having occurred in line 0.
-
- This can appear strange if the macro invokes other macros. When the
- error happens the macro has been expanded, so the line number may be
- greater than the apparent size of the macro. For instance, in the final
- example shown above if an error occurred in the line which invoked
- 'print_string' in the macro 'print_tab' the error would be shown as
- having occurred not at line 2, but at line 5.
-
- This is not normally a problem is practice because the actual error can
- usually be found by inspection but I may improve upon it later.
-
- 6.11 Macro Functions
-
- Macro Functions are defined and used exactly as in the Basic assembler.
- If you don't know how this works I refer you to the 'Tutorial'.
-
- A Macro Function is a Basic Function who's definition, as in a normal
- Basic program, appears after the #END directive. You use it by writing
- FN<name>, where <name> is the name of the function, in the assembler
- source. Most Macro Functions will require parameters and these are
- passed, enclosed in brackets after the function name, in the usual way.
-
- You must remember when defining a Macro Function that when it is called
- you have quit the assembler and are back in normal Basic. As a macro
- will probably include assembly code you will need to use the square
- brackets and define the OPT setting to re-enter assembler.
-
- SAsm uses two variables to define the OPT setting, Q% and PASS. You can
- use either of these when defining Macro Functions although I suggest you
- use PASS as its purpose is more obvious. The only time you need depart
- from this is if you are using a forward branch in the macro. In this
- case you must set a two-pass loop within the macro and you MUST define
- your own OPT variable. You could modify PASS because although it is set
- by SAsm at the beginning of each assembler pass it is not actually used,
- but it is safer to use an independent variable. It is very important
- that you do NOT modify in any way the Basic Integer variable Q%.
-
- WARNING - You cannot use the extra mnemonics DB, DW, DD, DIV, ADRL, MOVL
- or the enhanced immediate 2nd operands in Functions. These can only be
- used in the main body of the code or within Expanded Macros. You can
- call functions FNadr, FNmov, FNdiv and FNset as alternatives if
- required. These will be retained in later versions for this purpose.
- These restrictions will not be removed in later versions of SAsm since
- whenever possible you are advised to use Expanded Macros instead.
-
- 6.12 The Built-In Functions
-
- SAsm has a number of pre-defined Macro Functions and the following
- section describes them. Do not to use them in new work except when
- called from within other Macro Functions as the extra mnemonics ADRL,
- MOVL, DIV, DB, DW and DD should be used instead.
-
- As well as the functions described there are two others FNadrc and
- FNmovc. These should not be used directly and so are not documented but
- do not create your own functions with these names or conditional ADRL
- and MOVL will not work correctly.
-
- NOTE - The old functions FNdb, FNdw and FNdd have now been deleted.
-
- 6.13 FNgap ( <size> )
-
- Defines a gap in the code for use as a data area of <size> bytes. The
- memory is not pre set to any value. If <size> is not exactly divisible
- by 4 and you intend to follow FNgap with an opcode you should use ALIGN
- to ensure that further assembly occurs on a word boundry. Use 'DB' for
- preference unless within a Macro Function.
-
- 6.14 FNset ( <size>,<value> )
-
- Similar to FNgap except that the memory is preset to <value>. Use the DB
- mnemonic in preference wherever possible.
-
- 6.15 FNadr ( <register>,<location> )
-
- FNadr is an expansion of the ADR pseudo-opcode. Its syntax is the same
- except that the parameters must be enclosed in brackets. It can reach
- any byte within 64K or within 256K if <location> falls on a word
- boundry. If <location> is a forward reference FNadr always assembles two
- instruction. If a backward reference FNadr assembles a single
- instruction if possible.
-
- This is equivalent to the ADRL expanded mnemonic which should be used in
- preference.
-
- 6.16 FNmov ( <register>,<value> )
-
- This is an expansion of the MOV opcode to load a register with an
- immediate value. Unlike the normal MOV this will generate sufficient ADD
- opcodes after the initial MOV to load any 32 bit number. If <value> is a
- negative number then MVN and SUB will be used. Note that when using
- negative numbers you do not need to subtract 1 as you do with MVN. eg.
- to load r3 with -123456 just use FNmov (3,-123456)
-
- Use the MOVL mnemonic for preference unless within a Macro Function.
-
- The Macro Library
- =================
- ** This facility is available only to REGISTERED users **
-
- 7.1 Using the Macro Library
-
- The Registered version of SAsm can record every Macro Function or
- Expanded Macro call in your source file. If it is an Expanded Macro and
- it has not been previously defined somewhere in your code then it can be
- loaded from a Library file and inserted in the source. If it is a Macro
- Function it will be checked against the definitions found after the #END
- directive. If one or more definitions cannot be found it will try to
- load the missing definitions from a Library file.
-
- For Macro Functions the Library is only checked after all the source
- files have been loaded so a Macro Function in a source file will
- 'override' a macro of the same name in the Library.
-
- If an Expanded Macro is defined in the source file it is used in
- preference to one of the same name in the Library. If a macro is defined
- part way through the source files then calls to that macro before it is
- defined will be loaded from the Library and those after will use the
- version in the source file.
-
- 7.2 The 'L' parameter
-
- If you have a hard disc this operation is so fast that the only way you
- know it is happening is that SAsm will tell you that it is loading Macro
- Functions or that the Library isn't required. If you are using a single
- floppy drive you may have your Library file on another disc. When you
- know that no Library macros are required it is annoying to have to
- change discs and allow SAsm to satisfy itself that the (probably
- misspelt) missing Macro isn't in the Library. You can therefore add the
- suffix 'L' to the command line to tell SAsm NOT to use the Library, even
- if SAsm$Lib (see later) is defined.
-
- 7.3 Use of the 'V' parameter
-
- If you have used the 'V' (verbose) parameter then as each Expanded Macro
- is being searched for a message is displayed. Normally this takes the
- form -
-
- Searching Library for Macro <macro name> - Loaded
-
- But if the macro cannot be found in the Library it will say -
-
- Searching Library for Macro <macro name> - Not found in Library
-
- At this stage a missing macro will not produce an error but it will
- become one during assembly.
-
- 7.4 The SAsm$Lib OS variable
-
- To tell SAsm that a Library exists you should either create an OS
- variable 'SAsm$Lib' with the path/file name of the Library or use the
- #LIB directive within the source file. To use the SAsm$Lib variable type
- at the OS '*' prompt 'Set SAsm$Lib <filename>' where <filename> is the
- path/file name of your Macro Library or put this command in your !Boot
- file. You can of course have more than one Macro Library and just change
- SAsm$Lib to refer to the one in current use.
-
- If SAsm can't find a macro definition in the source files it will check
- to see if a Library has been defined. If so will extract the 'index'
- which MakeLib has created. This will be checked against any missing
- definition and if these appear in the Library they will be included.
-
- If SAsm can't find a macro in the source and the 'L' parameter hasn't
- been used but a Library hasn't been defined then an Error message will
- be displayed. If you are sure that all the macros exist in the source it
- is best to use the 'L' parameter to ensure that this doesn't happen.
-
- 7.5 Preparing a Macro Library
-
- First create a file of Macro Functions and/or Expanded Macros. These are
- macro definitions exactly like the ones you would use in source files.
-
- Each Expanded Macro should begin with the #SM directive and end with the
- #EM directive.
-
- On your program disc you will find an application called 'MakeLib'. Copy
- this to a blank disc and *MOUNT the disc or copy it to the Library
- directory of your hard disc. At the OS '*' prompt type;
-
- *MakeLib <source filename> <Library filename>
-
- where <source filename> is the full path/file name of your Macro
- definition file and <Library filename> is the path/file name that you
- wish to call the actual Library file that SAsm will use.
-
- MakeLib will load your Macro source file and prepare it for use by SAsm.
- Once MakeLib has created the Library file the original source is no
- longer required but you should keep it so that you can add new macros
- and update your Library in the future.
-
- The present version of MakeLib can only accept a single source file but
- I intend to improve it to accept wildcards in a similar manner to SAsm.
-
- 7.6 Length of Library file
-
- The source for a Library file can be any length and have as many
- comments ay you like. As with SAsm source files these will all be
- stripped before the routines are added to the actual Library.
-
- The Library file can hold about 200 Macro definitions. I suggest that in
- practice you only put the macros you frequently require in your Library
- and use INCLUDE files for those only rarely needed. This will make the
- search time shorter and also probably allow you to put your Library on
- your normal working disc if you are using a single floppy.
-
- SAsm and the Desktop
- ====================
-
- SAsm was originally intended to be used at the OS command line prompt.
- However, the introduction of good text editors such as !Zap and other
- tools now make it possible to to develop programs within the Archimedes
- desktop. Although SAsm itself is not integrated into the desktop
- environment versions after 1.40 have features which help them to be used
- in this way. The introduction of the desktop Front End program !SAsm
- enables SAsm to be used entirely within the desktop environment. I shall
- refer to the front end program as !SAsm to distinguish it from SAsm
- itself. !SAsm should have been included with your copy of SAsm, and it
- has its own separate instructions so I shall not go into it in detail
- here.
-
- 8.1 The new features
-
- The changes which have been introduced are described in the section on
- directives. They enable all the parameters which previously had to be
- typed at the command line (and more) to be inluded in the file as
- Directives. This means that only the name of a single 'make' file needs
- to be typed and this file can contain all other data needed to assemble
- the program.
-
- Even without the 'front end' you can use SAsm within the desktop very
- easily and assemble projects by clicking on a single 'Obey' file. You do
- not need to set the CSD as you will can use the <Obey$Dir> OS variable
- to define the start point of your project directory structure.
-
- 8.2 Using SAsm from the Desktop
-
- You can include everything needed to assemble an extensive project in a
- single short 'make' file. This would contain all the preliminary
- directives (org, size, type, etc) plus directives to define the object
- and error filenames and the library to be used. Following these will
- come a list of Include files to be assembled. The main advantage of this
- system for desktop use is that it enables an Obey file to run SAsm. In
- fact !SAsm can create a suitable Obey file so you can assemble a project
- without actually loading !SAsm itself. For example, to assemble a
- desktop project you should set up a directory structure as shown.
-
- root
- |
- |
- -----------------------------
- | |
- source !app
-
- The 'root' directory would contain your 'make' file and the Obey file
- which will run it. It need not, of course, be the actual root directory
- of a disc, it is just the root directory of your project. The !App
- directory will be the RiscOS application directory for your project. The
- 'Source' directory will contain all of your source files. You could, of
- course, also have other directories to hold special library files, error
- files, notes, etc. if required.
-
- Assuming the Make file is simply called 'Make' the Obey file would
- contain just two lines -
-
- Set Project$Dir <Obey$Dir>
- Sasm <Project$Dir>.Make
-
- When you double-click on this file it will atomatically create an OS
- variable 'Project$Dir (or whatever you want) and set it to 'Obey$Dir',
- ie. to the 'root' directory of your project. It will then Run SAsm
- (either from the RMA if you have loaded the Module version or from disc)
- with the filename of the Make file.
-
- The Make file should define the various parameters to assemble the
- program using the <Project$Dir> variable. Alternatively you could set
- the OS variable using the CLI directive from within the Make file. It
- would also contain directives to define the error file, library and
- object file, for example -
-
- # errfile <Project$Dir>.err
- # obj <Project$Dir>.!App.!Runimage
-
- and the files to be assembled would be -
-
- # include <Project$Dir>.source.first_*
- # include <Project$Dir>.source.second_*
- # include <Project$Dir>.source.third_*
-
- or whatever they are called. Note that you can still use the 'descending
- trailing digits' wildcard to assemble the latest version.
-
- The Make file need not, of course, be in the 'root' directory, it could
- be in the source directory if you prefer, (it is, technically, just
- another source file). If you don't have a hard disc you will probably
- prefer to have your source files (and certainly the error file) on the
- RAM disc. As SAsm doesn't create any temporary files you don't need much
- spare space.
-
- To assemble a project in this way just double-click on the Obey file.
-
- You can, of course, use SAsm in a 'Task' window but this means you will
- need to define directories and type filenames again. The biggest
- advantage of using a task Window is that if SAsm does crash the Wimp
- will normally allow you to close the window, thus killing the task. This
- is very useful when I'm using SAsm for development work on SAsm where
- this can happen. A disadvantage of a Task Window is that on ARM 2
- machines it does slow up operation.
-
- Problems and Questions
- ======================
- Important
-
- I'm continually trying to improve SAsm. Please tell me if you have any
- problems, even if you haven't registered. It's only by acting on bug
- reports and suggestions that I can keep improving it.
-
- 9.1 Reporting and diagnosing problems
-
- Tell me which version of SAsm you are using, you may have experienced a
- 'bug' which has already been fixed. A lot of time can be wasted trying
- to reproduce an error which can't occur on a later version. Ideally send
- the version of SAsm you are using. I may no longer have a copy of that
- version (there have been quite a few updates!)
-
- Send a copy of the source file(s) that caused the problem, preferably
- all files not just the one that gave the error, plus any error files
- generated or other information. I need to know exactly how the program
- failed, 'it wouldn't work with this' isn't very helpful! If you use SAsm
- in a Task Window then if possible 'Save' the contents and include it. If
- you don't normally run SAsm from a Task Window then if possible please
- do so that you can send me the file.
-
- Try to create listing and error files. If SAsm produces an uncorrupted
- listing file it indicates the problem isn't in preprocessing. This
- doesn't mean that something in preprocessing isn't causing a problem for
- the assembler, but it does indicate that it will probably be easy to
- spot and solve. Sometimes SAsm will produce a valid listing or error
- file but it's type will be Data and not Text. Once again this is a
- valuable pointer to the likely source of the problem.
-
- You may be able to produce a listing file by using a 'null' object
- filename (~) even though you can't get an object file. If you can do
- this you may be able to examine it and discover the problem.
-
- You may feel all this isn't necessary because I should be able to
- reproduce the problems that you have experienced, but this may not be
- possible. I have often been sent source code which assembled perfectly
- when I tried it. On one occaision it wouldn't work on the users machine
- because he was trying to run it in a P.D. Task Window program using
- RiscOS 2 and it was the Task Window that had crashed, not SAsm. There
- was no way that I could have reproduced this except that the user
- enclosed a screen 'grabbed' from the desktop and I recognised the non
- standard window.
-
- I use SAsm a lot so it *should* be bug free since it gets a lot of
- testing, not least because I use it to assemble SAsm itself. However,
- like most programmers I write code in a fairly consistent way and to a
- regular format. I use some features a lot, some rarely, others almost
- never. Experience shows that there is always someone who does something
- that I have never thought of. Often this is quite legitimate, sometimes
- downright weird, but it may introduce a variation I haven't allowed for.
- Most changes to SAsm are 'fixes' and improvements to accommodate the way
- that other people work.
-
- One thing that can happen with both SAsm and the Basic asembler is that
- labels, constants and register names are all 'normal' global variables.
- Most assemblers and compilers treat register names, labels and constants
- differently. You must be careful not to use the same name for more than
- one item. It is very easy to define a label and a register or an offset
- into a data area with the same name and disastrous consequences.
-
- You may find that with a complex program it is best to use some sort of
- prefix or suffix for data offsets and registers. Using names like r_ptr
- for a register and d_offset for a data area offset will avoid this sort
- of problem. Another solution is to use upper case names (beware the SAsm
- reserved variables) or names beginning with a capital letter for
- constants. As most constants will be integers a good solution is to make
- them all Basic integer variables by ending the name with % because
- 'number' and 'number%' are different variables. No doubt you will devise
- your own method of sorting the various names into easily identified
- categories.
-
- If you suspect this might be the trouble then list out all your labels
- to a file and check them against register names and constants. That's
- why this function was included and it can save a lot of time.
-
- If all else fails there is one final thing you can try. The registered
- version of SAsm can save the fully processed data as a file before
- assembly. You can do this either by using a 'p' parameter at the command
- line or, instead of pressing RETURN when you type the command, hold down
- both SHIFT keys and press the keypad ENTER. This stops any assembly
- taking place and saves the whole file with whatever you had assigned as
- the object filename.
-
- This function was included for my own purposes when debugging SAsm
- itself. The resulting file is difficult to understand but it may help
- you (or me) to discover what is happening. It is only mentioned as a
- tool of last resort because it is really intended to show up
- shortcomings in SAsm.
-
- 9.2 The SASM_ERR variable
-
- It was suggested by a user that it would be very useful if the SAsm
- error count were made available to other routines. Errors are now
- counted in the variable SASM_ERR (I know it's upper case and FP, but
- it's more obvious and there's less chance of a clash).
-
- If, for example, you have a routine that would only need to be called if
- there's benn no errors during assembly then you could check that
- SASM_ERR is 0 before you call it. Similarly if you have 'internal' error
- checks in your own routines and you want to make sure that the error is
- counted 'officially' then you can increase the count (#SASM_ERR+=1).
-
- This is particularly useful after the #END directive as it enables you
- to write LOCAL error handlers in functions and still record the errors.
- In the main part of the code you can still, as always, use ERROR
- <num>,<message> and the SAsm error handler will intercept it.
-
- 9.3 Speed of operation
-
- The two questions I am most often asked about SAsm are 'what language is
- it written in?' and 'how fast is it?'.
-
- These can most easily be answered together. SAsm is written in machine
- code using SAsm. Each version is assembled using the previous version.
- The source code is then changed to take advantage of any new features
- and re-assembled. I therefore test SAsm by 'self assembling'.
-
- The source for SAsm consists of more than 7000 lines split over eleven
- files. These are loaded from disc, assembled, and the source file saved
- to disc in less than seven seconds on an A440 with an ARM 2 processor
- and an ST506 hard disc or about three seconds on an A5000 or Risc PC. I
- think this is fast enough for most purposes.
-
- Without a hard disc the time taken would be quite a bit longer, but as
- SAsm can use a RAM disc this shouldn't be a difficulty unless you are
- trying to write long programs on a 1Mb machine. Unlike most assemblers
- and compilers SAsm doesn't use much memory for its own purposes.
-
- 9.4 Memory usage
-
- SAsm starts by using whatever RAM is made available by the NEXT TASK
- allocation. If this is insufficient it will try to grab more from the
- Wimp Pool. If this is successful it will eventually hand all of this
- over to Basic for the actual assembly. Normally this will allow enough
- overhead for the Basic Heap, but if there are a lot of variables this
- may not be the case. If you do get a Basic error message implying that
- there isn't enough room the solution is to start out with a large
- allocation by dragging the 'NEXT' slider. In extreme cases this problem
- could cause a complete hang-up because there may not be enough memory
- available to report the error, so Basic calls the error handler, but
- there isn't enough memory to report the error, so......
-
- Whichever version of SAsm you are using the SAsm application code itself
- will be located at &8000. After the application code space is allocated
- for data areas used by SAsm. A 16K 'buffer' is allowed and the first
- file is loaded above this space. This will probably be about 50K above
- the start of the 'slot' at &8000 and this is the only RAM normally used
- by SAsm. As the file is processed it is copied down to the start of this
- buffer. Obviously the 'tail' of the processed file will eventually
- overlay the beginning of the 'raw' file, but this is not of any
- consequence. When the first file has been processed a new 16K buffer is
- allocated after its end and the next file is loaded and processed. This
- continues until all the files are completed.
-
- With smaller programs this is passed to Basic in this form for assembly.
- However Basic can't cope with untokenised programs in excess of about
- 6500 lines, so anything larger than this must be tokenised by SAsm. If
- this is necessary you will see a message to this effect.
-
- 9.5 Some notes on Local Labels
-
- I shall describe briefly how SAsm handles local labels as is is
- possible, although unlikely, for it to conflict with other variables.
-
- You will be aware that Basic does not permit variable names to begin
- with a number. SAsm therefore adds a two letter prefix to each local
- label. This is given a wide spread to speed up access by Basic. The
- prefix starts at 'zz' and reduces to 'Az', then 'zy' to 'Ay' etc. The
- label prefix is reset each time a '00' label is encountered. You can see
- exactly how this works by examining any Listing file where local labels
- have been used. Where local labels are used in expanded macros a similar
- method is used but with a three character prefix.
-
- The system is simple and is designed to be very fast for Basic to use.
- However it is possible for conflicts to exist if you have defined a
- label or other variable in this form, eg. a variable 'xy10' could cause
- problems. To avoid this you are strongly advised to ensure that your own
- variables and labels don't use this form, eg. 'xy_10' couldn't possibly
- cause a problem.
-
- 9.6 The most common problems
-
- There are a few 'features' of SAsm which can cause trouble. Some are
- minor bugs that are unimportant once you know about them and will be
- fixed when I have time. Others are errors which can occur because of
- changes in the syntax used by SAsm. I will record some of the queries
- raised by users to help others avoid the same problems.
-
- Before you decide it's a bug in SAsm that's making things go wrong
- PLEASE read these and assure yourself that none of them could possibly
- apply. Most 'problem code' I am sent display one or more of these errors
-
- Because of the way SAsm operates it does not have perfect control over
- assembly and there will always be things which can make it crash. These
- are slowly being eliminated and the error trapping is being improved so
- that things which could cause a crash or a 'lock up' in earlier versions
- are now either accepted or just give an error message.
-
- 1. There MUST be a space between the mnemonic and the first operand for
- many of SAsm's functions to work. This is not always essential with
- the Basic assembler but it is good practice so I make no apologies.
-
- 2. MOVL, ADRL and DIV are actually macro's and not assembler mnemonics.
- ADRL and MOVL can be made conditional but because DIV expands to many
- lines of code with internal compare instructions it cannot.
-
- 3. Make sure that you start every set of local labels with '00'.
-
- 4. You cannot use local labels, DB, DW, DD, ADRL, MOVL, DIV or the
- enhanced second operator functions after the #END directive, so you
- can't use them within Macro Functions. You can use them within
- Expanded Macros because these are defined before the #END statement.
-
- 5. Because DB, DW and DD instructions may expand considerably they can
- cause a 'line too long' error if you put too much on one line.
-
- 6. SAsm removes redundant spaces and comments as it works but other
- operations expand it. Normally the contraction is greater than the
- expansion so the file shrinks. As a file is loaded a 16K 'overhead'
- is allowed in case the file grows. This should be plenty, but in
- extreme cases of large files without spare spaces or comments the
- program could crash. I will add routines to guard against this when I
- get time but I don't regard it as a major fault since one aim of SAsm
- is to let you split up and spread out your source files.
-
- 7. SAsm regards a ';' as defining a comment so if you insert a line of
- Basic which has a PRINT statement that includes the ';' character
- with a preceding space it will be 'cut off'.
-
- 8. There must be a CR or LF at the end of the last line of each file.
- Check by loading the file into your editor and pressing CTRL-DOWN
- to move the cursor or caret to the end of the file. It should be on a
- blank line below the last line. If it appears at the end of the last
- line there isn't a final terminator and you'll have problems.
-
- 9. SAsm can abort with an error if there is not enough space for line
- numbers. This is because after SAsm has finished with the files Basic
- will need to add 3 bytes to each line for the line number and length
- byte. The solution is to make more memory available.
-
- 10.SAsm can quit with a fatal error giving a line number greater
- than the length of the file the error occurred in. Usually this means
- the error happened inside a Macro Function. This is always a problem
- with Basic Functions and there is no simple solution. Often the only
- way of discovering the error is to examine every FN call in the file
- where the error occurred. The filename given will be the name of the
- file from which the function was called, and if it is used elsewhere
- the most probable cause is an error in one of the parameters passed.
- If it persists you could try splitting up the offending file into
- smaller sections to help you to 'zero in' on the problem.
-
- 11.If SAsm crashes for any reason it can leave an error or x-ref file
- open. If there is a fatal error these files should be closed but if
- SAsm itself crashes this may not happen. You won't be aware of this
- until you run SAsm again when the 'file open' error will occur as
- SAsm tries to open an already open error file. IN THEORY you should
- just get a 'beep' and a warning message telling you that the error
- file was open and assembly will proceed. If this happens you will
- have lost the first error message although the error will be counted.
- Source or Object files can't be left open as these are only accessed
- as whole files. If a filing system doesn't give the standard error
- number this error won't be intercepted. In this case the program will
- go into an infinite loop because every time it tries to report the
- 'file open' error it will generate ...... a file open error! If this
- happens when using a Task Window try pressing F12 and typing 'SHUT'.
-
- 12.The parameters passed to the DIV macro are the register numbers it
- will use, not the values operated upon. You are responsible for
- loading the values into the respective registers before using the
- macro. Don't forget that these registers will be altered afterwards.
- This macro has no error checking. If you try to divide by zero or do
- something stupid it may crash or go into an infinite loop. It works
- well, but it's dumb, so it's up to you to use it properly.
-
- 13.It doesn't matter whether you use a LF (ascii 10) or CR (ascii 13)
- at the end of each line. Most text editors use LF's but some can use
- either or even a LF/CR combination as is used on PC's. SAsm will not
- work with a LF/CR or CR/LF combination. All textural output from SAsm
- such as Listing and Error files conforms to the standard Archimedes
- format of a LF terminating each line.
-
- 14.If assembly appears to stop part way through check you don't have an
- #END directive before the real end. This can happen if you re-arrange
- the order of the files or if the last file is loaded out of sequence.
-
- 15.Check that wildcarded filenames only apply to one file or you will
- get some files assembled twice! This can cause the previous error.
-
- 16.If you have a data area and the first 'instruction' immediately
- following this is ADRL then you MUST ensure that the end of the data
- area is ALIGN'ed. Otherwise the address might be calculated from an
- 'odd' base which will introduce errors.
-
- 17.The Basic Tokenising routine is NOT comprehensive. It should cope
- with all simple Basic constructs of the type likely to be used in an
- assembler source file. In theory it should distinguish between AND
- and EOR when used as mnemonics or as operators. If in doubt use the
- lower case versions of the mnemonics.
-
- Release History
- ==============
-
- 1.0 Oct. 91 First release
- 1.1 Nov. 91 Functionally as 1.0
- Bug fixes
- X-ref and Macro Library functions re-written
- 1.2 Nov. 91 Bug fixes
- Much improved error handling
- INCLUDE directive added
- 1.21 Jan 92 Restrictions on INCLUDE directive with
- Shareware version removed.
- 1.22 Mar 92 Improved error handler
- 1.23 May 92 Minor bug fixes
- 1.24 June 92 Line numbering rewritten, dramatic speed increase for
- large files
- Line number space relocation added
- 1.25 July 92 adrl, movl, div, db, dw, dd, added
- Enhanced immediate 2nd operand
- 1.26 Feb 93 Bug in adrl in some examples of 1.25 fixed.
- No public release of this version.
- 1.30 Mar 93 Expanded macros introduced.
- db *xx,? to reserve area without setting
- New Makelib tool for expanded macros
- Module provided so SAsm can be run from the RMA
- 1.31 Apr 93 ADRL and MOVL can be conditional
- 1.32 Jun 93 Bug fixed in expanded macro stack.
- 1.41 Aug 93 #obj, #lib, #errfile, #cli, #verbose, #quiet,
- #xref and #noxref directives introduced.
- Tab characters accepted as delimiters.
- 1.42 Sep 93 Bug with DB, DD and DW in upper case fixed.
- Bug with comment on Macro call line fixed.
- 'Line Too Long' trapped during preprocessing
- 1.43 Dec 93 Expanded macro call permitted after label
- Minor bug fixes
- 1.44 Dec 93 #enhance and #noenhance directives introduced
- 1.45 Dec 93 Bug in macro call with no params fixed
- 1.46 Dec 93 'P' parameter introduced
- #insert directive introduced
- 1.50 Jan 94 x-ref list to file
- x-ref bug fix with label same as opcode
- Assembler listing file
- Added short help text
- SWI name processing
- Local labels with LDR and STR
- String variables accepted by DB
- 'Q' switch added to quit before assembly
- 'N' switch added to list label names
- #LABELFILE to send labels to file
- 1.51 Mar 94 Minor bug in #SWION fixed
- reg! permitted without space for LDM/STM
- More improvements to error trapping
- DIV now included in unregistered version
- 1.52 Mar 94 Filetypes Module and Utility don't need ORG
- Bug with obj filename starting with '!' fixed
- Added 'demo' application
-
- 1.53 Mar 94 Labels now listed alpahbetically, not reverse
- FNdb, FNdd, FNdw removed
- #AREA directive introduced
- Descriptive text between {and } allowed
- OSET variable implemented
- Bug in trapping open Error File error fixed
- 1.54 Apr 94 Basic tokenising introduced with large files
- Corrected bug with ':' in INCLUDE filenames
- 1.55 Jun 94 Fixed bug which sometimes gave errors with some
- conditional ADRL instructions
- 1.56 Jul 94 dynamic memory management introduced
- 1.60 Feb 95 Bug in #include introduced in 1.54 fixed
- First line of an #AREA directive no longer needs an
- offset
- Missing number after a name in an #AREA is now a
- recoverable error
- '>' and '<' modifiers for local label introduced
- 1.70 July 95 Major internal rewrite for messages.
- #size directive can now be in the form '50K' etc.
- !SAsm desktop front end supplied
- 1.71 Aug 95 #STRUC directive introduced
- 1.73 Sept 95 HS and LO accepted as conditions with ADRL etc.
- SASM_ERR variable introduced.
-
-
- Registration Form for SAsm
-
- Registration costs Ten Pounds, a laser printed Manual costs a further
- Two Pounds if required. Please post this form with your cheque to;
-
- David Holden, 39 Knighton Park Road, Sydenham, London SE26 5RN
- ____________________________________________________________________
- Name and Address:
-
-
-
-
-
-
-
-
-
- Do you require a printed Manual (£2 extra) -
- ____________________________________________________________________
- Where did you obtain SAsm:
-
-
-
-
-
-
-
- ____________________________________________________________________
- Have you had any problems:
-
-
-
-
-
-
-
-
-
-
- ____________________________________________________________________
- What additional features would you like:
-