home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-03 | 161.5 KB | 3,436 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.54
-
-
-
- The Simple Assembler for the Archimedes
-
-
-
- Copyright David Holden 1991,92,93,94
-
-
- _______
- ____|__ | (R)
- --| | |-------------------
- | ____|__ | Association of
- | | |_| Shareware
- |__| o | Professionals
- -----| | |---------------------
- |___|___| MEMBER
-
-
-
-
-
- CONTENTS
- Page
- Preliminaries
- Introduction ........ 1
- Licence to Use ........ 2
- How to Register ........ 2
- Advantages of Registration ...... 2
- Licence to Copy ........ 3
-
- Using SAsm
- Use with floppy discs ........ 4
- Command line syntax ........ 5
- Null Parameters ........ 6
- Source Filenames ........ 7
- Reconciliation of Wildcards ..... 8
- Order of Assembly ........ 9
- Length of Source File ........ 9
- Line number space ......... 9
- A short demonstration ........ 10
-
- The Source File
- Source File Syntax ........ 11
- General ........ 11
- Important warning ........ 11
- Warnings and Errors ........ 12
- Comments ........ 12
- Descriptive text ........ 13
- Large source files ........ 14
- Basic keywords accepted ........ 14
- Directives ........ 15
- Basic variables ........ 16
- #ORG ........ 16
- #SIZE ........ 16
- #END ........ 16
- #TYPE ........ 17
- #OBJ ........ 17
- #ERRFILE ........ 17
- #LIB ........ 17
- #VERBOSE ........ 17
- #QUIET ........ 18
- #INCLUDE ........ 18
- #INSERT ........ 19
- #AREA ........ 19
- Multiple data areas ........ 21
- #LISTON ........ 22
- #LISTOF ........ 22
- #NOENHANCE ........ 22
- #ENHANCE ........ 22
- #XREF ........ 22
- #NOXREF ........ 22
- #XRFILE ........ 23
- #SWION ........ 24
- #SWIOFF ........ 24
- #CLI ........ 24
- #LABELFILE ........ 25
-
-
-
-
- CONTENTS
- Page
-
-
- Defining registers etc. ........ 26
- Defining constants ........ 26
- Conditional Assembly ........ 27
- LDM/STM with Writeback ........ 28
- Assembly Loops ........ 28
- Using the OSET variable ........ 29
- Assembly Listing ........ 30
- Creating a Listing file ........ 31
- Listing file directives ........ 31
- Scope of listing ........ 31
-
- Labels
- Global Labels ........ 32
- Local Labels ........ 32
- Local Label Scope ........ 32
- Local Label Example ........ 34
- Forward Branch to 00 ........ 34
-
- Enhanced 2nd Operand ........ 35
-
- Extra Mnemonics
- DW and DD ........ 36
- DB ........ 37
- Basic variables and DB ........ 38
- ADRL ........ 39
- MOVL ........ 39
- DIV ........ 40
-
- Macros
- Macro Functions - Pro/Con ...... 42
- Expanded Macros - Pro/Con ...... 42
- Macro Names ........ 42
-
- Expanded Macros
- Defining expanded macros ........ 43
- Macro parameters ........ 43
- Local labels in macros ........ 44
- Special features ........ 44
- Examples ........ 45
- Errors in expanded macros ....... 46
-
- Macro Functions
- General ........ 47
- Built-in Functions ........ 47
- FNgap ........ 48
- FNset ........ 48
- FNadr ........ 48
- FNmov ........ 48
-
-
-
- CONTENTS
- Page
-
- The Macro Library
- Using the Macro Library ........ 49
- The 'L' parameter ........ 49
- The 'V' parameter ........ 50
- SAsm$Lib OS variable ........ 50
- Preparing a Library ........ 51
- Length of Library file ........ 51
-
- SAsm and the Desktop
- New features ........ 52
- Using from the desktop ........ 53
-
- Problems and Questions
- Reporting and diagnostic ........ 54
- Speed of operation ........ 55
- Memory usage ........ 55
- Notes on Local Labels ........ 56
- Common problems ........ 56
-
- Release History ........ 60
- Registration Form ........ Endpiece
-
-
- Page 1
-
-
- -=O=- INTRODUCTION -=O=-
-
- 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, for many purposes, 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 and 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 for the Archimedes
-
- 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 (APDL disc B150) 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 actually 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
-
- Page 2
-
- SAsm is SHAREWARE, it is NOT Public Domain
-
- 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
-
-
- -=O=- LICENCE TO USE -=O=-
-
- This program is distributed as SHAREWARE. It is NOT Public Domain. This
- means that you are only licensed to use it for a period of THIRTY DAYS.
- At the end of that time you must either stop using it or REGISTER.
- Failure to comply with this condition is a Breach of Copyright and is
- now recognised in almost all countries as an offence.
-
- Use of ANY version of SAsm for any TRAINING or EDUCATIONAL purposes
- without payment of the Registration Fee is ABSOLUTELY FORBIDDEN.
-
-
- -=O=- HOW TO REGISTER -=O=-
-
- Registration costs just Eight Pounds. 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
-
-
- Advantages of Registration
- --------------------------
- The first advantage is that you will not, of course, be breaking the
- law. Registration costs just eight 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 which will let you 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.
-
- 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'.
- Page 3
-
-
- -=O=- LICENCE TO COPY -=O=-
-
- 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.
-
- 4. 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.
-
- 5. 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'.
-
- 6. You must not distribute any version of the 'MakeLib'
- application. This is for the use of Registered users ONLY.
-
-
- 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.
-
- David Holden
- 39 Knighton Park Road
- Sydenham
- London SE26 5RN
-
- 081 778 2659
-
- SAsm was produced by a member of the Association of Shareware
- Professionals (ASP) who want 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.
- Page 4
-
-
- -=O=- USING SASM -=O=-
-
- SAsm is a 'Transient' program. This means that when it is invoked by
- typing it's name at the OS '*' prompt it is loaded from disc and Run.
- This is not normally a problem because SAsm is quite compact, about
- 25K. If you have a hard disc put SAsm in your Library directory. If you
- have only a single floppy drive then copy SAsm to each working disc, it
- won't take up much disc space.
-
- From version 1.30 onward you will find two versions of SAsm on the
- distribution disc. One is the transient application and this is
- probably the best way to use SAsm if you have a hard disc as you can
- simply copy it to your Library directory and it will automatically Run
- whenever you type its name. The other version is a Relocatable Module
- called SAsmMod. This will be the preferred method if you don't have a
- hard disc. Just 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.
-
- I anticipate that a version of SAsm with a complete desktop 'front end'
- will appear in the near future but for the present you can run it from
- within a 'Task' window if you wish.
-
-
- Use from floppy discs
- ---------------------
- Although SAsm will obviously operate much faster from a hard disc it is
- perfectly satisfactory when used on a machine without one. In fact it
- was deliberately designed with floppy disc operation in mind. If you
- have enough memory then you could create a large RAM disc to hold all
- your files. The disadvantage of this is that if you modify the source
- files and suffer some sort of crash before you remember to save the
- modified files to disc you could lose part of your work.
-
- Because SAsm uses only fast 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 therefore to direct all of these to the RAM disc
- where the operations will be very 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.
-
- Page 5
-
-
- 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. This means
- 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 your 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. It may seem strange
- that you should wish to do this but 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 soon
- scroll off the screen and get lost. If you define a name for an error
- file all the error messages will be sent to the file. This can be
- loaded them into your 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 can 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 any 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' is used to force 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' will make 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.
- Page 6
-
-
- 'A' makes SAsm 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 will be
- 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
-
-
- Null Parameters
- ---------------
- You will notice that these names must appear in order. So what do you
- do if you want 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.
-
- Page 7
-
-
- 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.
- Page 8
-
-
- Reconciliation of Wildcards
- ---------------------------
- It might appear that no 'filtering' of wildcards in filenames is
- necessary. If you put all the source files in sub-directory 'Source' of
- the CSD then typing *SASM Source.* Code would assemble them all
- into the object file Code with no problems. In real life things aren't
- that simple. For example, if you make an alteration to one of your
- source files but want to 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 problem by moving the original to another directory but this would
- soon become very tedious.
-
- SAsm has a rigid system of deciding which files to assemble. This was
- designed to work with the way I write my 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 a lot of 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) or
- 'Data' (FFD). 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
- then 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 or &FFD.
-
- 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. This system
- operates beautifully with TWIN (Acorns non-desktop text editor) because
- if I type 'Name*' as the filename to load into TWIN it will load the
- one with the lowest number, ie. the latest. 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.
-
- Page 9
-
-
- 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 you
- don't need any complicated 'make' utilities to assemble a long list of
- source files. In fact the additional facilities offered by the INCLUDE
- directive make this even simpler.
-
-
- 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
- you are writing programs which need more than this then perhaps you
- should be writing your own assembler and trying to sell it to me!
-
-
- 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 available 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.
-
- Page 10
-
- 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 manner.
- Page 11
-
- -=O=- THE SOURCE FILE -=O=-
-
-
- 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 if you have previously used the
- Basic Editor the source files for SAsm, like all assemblers, are TEXT
- files and must NOT have line numbers.
-
- One of the nice 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 Archimedes
- '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.
-
-
- General
- -------
- In the following section you will find references to various commands
- being separated by spaces. In general 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.
-
-
- 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.
-
- Page 12
-
-
- 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.
-
-
- 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 a ':', even if the ':' is in a comment. For
- example the following line using the Basic assembler;
-
- mov r1,#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 r1,#1 as
- everything on the line after the '\' is a comment.
-
- The exception to this 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. If you do 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.
- Page 13
-
- Descriptive text
- ----------------
- Sometimes you may want to put a block of descriptive text somewhere 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 terminating } will then be completely ignored. The opening { can be
- followed by text on the same line or 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 may also 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 easier to avoid assembling
- debugging code, etc. when you no longer need it but to restore it
- simply when you do. If you use this feature for this 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 {, the closing
- one will be ignored.
-
- Obviously if a } with a preceding space exists in the section you want
- to blank out then you may get unexpected errors. The most likely cause
- of this is a } in a comment, but this should be easy to check.
-
- In normal use only problems you are likely to encounter is if you
- forget the closing } or if you don't precede it with a space. In this
- case SAsm will either completely 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 }.
- Page 14
-
-
- Large source files
- ------------------
- Archimedes 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.
-
- For this reason if a file is longer than about 6500 lines it is
- necessary for SAsm to tokenise it instead of leaving this process to
- Basic. This is completely automatic, smaller programs will be left
- untouched and larger ones will be tokenised. However 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 Basic operators AND, EOR and
- OR and the assembler mnemonics AND, EOR and ORR. In theory the SAsm
- tokeniser can distinguish between these when used as mnemonics and when
- used as 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 very much faster.
-
- There is also room for confusion if you use any 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 capitals as word delimiters but you should be aware of
- the possibility of problems.
-
-
- 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
-
- Page 15
-
-
- Directives
- ----------
- It is possible to include 'Directives' in your source. In fact some
- directives are necessary for the proper operation of SAsm. Any line in
- which the first non-space character is '#' is a directive. If SAsm
- doesn't recognise what follows the '#' it will assume it is a valid
- Basic statement and the line after the '#' will be passed to Basic.
-
- You can use SAsm without any preliminary directives in your source
- file. Unlike the Basic assembler you can begin by writing mnemonics
- straight away. If you do this SAsm will start assembling your code to
- run from '0000'. This doesn't matter as SAsm will normally 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 the line. Directives should be the only item on
- the line although you may include comments.
-
- All directives are case insensitive. Where a directive is to be passed
- to Basic it's 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, but see
- the note under 'Comments' above.
-
- There must be at least one space after a directive where it is followed
- by one or more parameters.
-
-
- Directives and Basic variables
- ------------------------------
- Because of the way that 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
-
- would also be OK because in all cases there is no space following
- 'include' as required by SAsm.
- Page 16
-
-
- 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.
-
-
- #ORG
-
- Defines the address the code will be assembled to run at. The syntax is
- # ORG <number> where <number> is a valid address. <number> will be
- assumed to be in hex whether or not it is preceded by a '&' character.
-
- If no #ORG directive is found assembly will start at location 0 and a
- warning message will be displayed. The #ORG directive must obviously
- appear before the first assembler statement. If an #ORG directive is
- found after this a warning message 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, which are 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 the following directives.
-
- Note - ORG replaces the ADDR directive used in early versions. ADDR is
- still supported for backwards compatibility but ORG should be used in
- new work as ADDR may be dropped in the future.
-
-
- #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.
-
- If there is no #SIZE directive before the first assembler statement a
- warning will be given and 64K will be allocated for the code. Any #SIZE
- directives after the first assembler statement will be ignored.
-
-
- #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.
- Page 17
-
-
- #TYPE
-
- This defines the filetype you wish your assembled code to have. Syntax
- is #TYPE <filetype> where <filetype> is a valid Archimedes filetype. If
- <filetype> is a number it should 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.
-
-
- #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.
-
-
- #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.
-
-
- #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.
-
-
- # 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.
-
- Page 18
-
-
- # 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.
-
-
- #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_*
-
- Page 19
-
-
- #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.
-
-
- #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]
-
- 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 during the running of the program. 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 is designed to make 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.
-
- At present (version 1.53) this directive works perfectly but it may not
- be very 'robust' and so it is possible that if you use it wrongly you
- might get strange errors. I will try to introduce more error trapping
- in future and add some extra features.
-
- Page 20
-
- 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 can
- introduce a series of 'pointers' into this 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 exactly 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. Note that te 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 word size section will be word aligned. This
- can be done in the normal way with an ALIGN instruction. In fact this
- instruction works differently when used in this context but its action
- is the same as usual.
-
- Page 21
-
- 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 permitted. 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. However 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.
-
-
- Multiple data areas
- -------------------
- You may have realised that every offset defined by the AREA directive
- becomes a Global Variable. This makes it possible to define a series of
- identical data areas and use the same offsets to access them. This
- would be 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.
-
-
- Page 22
-
- #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)
-
-
- #LISTOFF
-
- Marks the point at which the assembler listing file will cease.
-
-
- #LISTFILE
-
- Sets the name to be used for an assembler listing file.
-
-
- #NOENHANCE
-
- Switches off the second operand enhancements (see later). Included for
- untidy programmers who insist upon using instructions like MOV 1,2.
-
-
- #ENHANCE
-
- Switches second operator enhancements on again. This is the default.
-
-
- #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.
-
-
- #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.
- Page 23
-
-
- #XRFILE
-
- Followed by a filename this sets the name to be used for the label
- x-ref file if this is required. If duplicate labels are to be 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.
-
- Note that this directive doesn't actually initiate the x-ref function.
- It just ensures that if the operation is enabled either 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.
-
-
- Page 24
-
-
- #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 works because the names
- of all Archimedes SWI calls 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 it will not be recognised and will produce an
- error. The more likely problem would arise if you define constants for
- some SWI numbers. All will be well if you give these 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.
-
- In general you should not experience any difficulties if you ensure
- that if you do wish to use a SWI name which begins with a lower case
- letter you enclose its name in quotes and if you define constants for
- any SWI numbers you make sure that their name does not begin with a
- capital letter.
-
-
- #SWIOFF
-
- Switches off SWI name processing described above.
-
-
- #CLI
-
- Anything on the line after this directive will be passed DIRECTLY to
- the Archimedes 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.
-
- Page 25
-
-
- #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 but without a
- following name then the default name 'LabelFile' will be used.
-
- This directive does not actually initiate a label listing, it just
- ensures that if you do want one it will go to a file and not to the
- screen. You can therefore 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 the 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.
-
- Page 26
-
-
- 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 as these are the normal definitions for these registers. 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.
-
-
- Defining constants
- ------------------
- Most source 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.
-
- There is one unusual feature of SAsm that you must remember. 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 is
- not normally of any consequence 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.
- Page 27
-
-
- Conditional Assembly
- --------------------
- This works as with the Basic assembler. The most common method is using
- IF THEN, (ELSE), ENDIF. If you are unfamiliar with this technique
- please read the 'Tutorial' file which explains it.
-
- 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.
-
- Page 28
-
-
- LDM and STM instructions with Writeback
- ---------------------------------------
-
- The LDM/STM instructions are primarily 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> !,{ <register list> }
-
- Using the Basic assembler it is necessary to leave a space between
- <reg> and the '!' character. If this is not done then 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 your 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.
-
-
-
- Assembly Loops
- --------------
- When using the Basic assembler it is common to use FOR-NEXT loops to
- fill an area of memory, eg.
-
- ........ ;normal code
- ] :REM exit assembler
- FOR I%=0 TO 255
- [ OPT PASS
- EQUB &FF ;fill 256 bytes with &FF
- ]
- NEXT
- [ OPT PASS ;back to assembler again
- ........ ;normal code
-
- 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 fill an area of memory with a
- value by using the DB mnemonic.
- Page 29
-
-
- Using the OSET variable
- -----------------------
- With the Basic assembler it is sometimes required to 'poke' values into
- a data area after assembly. Alternatively you may wish to modify some
- data in some way. Ad you will 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 that you wish to
- change. With SAsm the actual address of a location is hidden from the
- user and so the variable OSET is set to give you a 'base' to use for
- these purposes.
-
- During assembly OSET is set in such a way 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, of course, contrived and the same results
- could be more efficiently be produced by other means.
-
- The most likely use for this would be to 'disguise' some text in your
- code in some way. This makes it possible to compose it in plain
- language when writing the code but garble it after assembly.
-
-
- Page 30
-
-
- Assembly Listing
- ----------------
- SAsm will 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 the code rather cramped and difficult
- to read but it will be less than half the size of a Formatted file.
- This method 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 the 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 not saved as a 'block' but 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.
-
-
- 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 then the default name of 'ListFile' will be used and
- the file will be created in the Currently Selected Directory on the
- current filing system.
- Page 31
-
-
- Assuming that no other directives are used this will result in a
- listing file consisting of all the source files used. If you have also
- used the 'F' parameter then this will be a Formatted file, if not it
- will be in the compact format.
-
-
- Listing file directives
- -----------------------
- Assembler listing files can be produced instead of or in addition to
- Object and/or Error files.
-
- There are three directives which relate to listing files, these are
- LISTON, LISTOFF and LISTFILE. As their names imply 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 should, of course, be 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 will begin 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.
-
-
- Scope of a listing file
- -----------------------
- It is important to understand exactly how these commands and directives
- work in order 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 statement. 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.
- Page 32
-
-
- -=O=- LABELS -=O=-
-
- Global Labels
- -------------
- All labels and constants are common throughout all files. It is
- important to remember this or some very strange things can happen. With
- SAsm you don't need to declare labels external, they are ALWAYS global.
-
- Adding the suffix 'X' to the command line invokes the label cross
- reference. This will check all labels and report multiple definitions.
-
- For reasons previously explained multiple definitions of a label are
- classed as Warnings only and not Errors. If like me you repeatedly use
- labels like 'loop' or 'bak' to form short loops you will need to
- visually check the list of duplicates for 'foreign' names.
-
-
- Local Labels
- ------------
- Since it could become 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 exactly 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.
-
-
- Local label scope
- -----------------
- You start each 'set' of local labels with a label '00' When SAsm finds
- label 00 if 'forgets' all previous local labels. You can therefore use
- the numbers 00 to 99 repeatedly and each local label will only apply
- within its own section. Each time you start a new section of code or
- sub-routine make the first label in that section 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.
-
- 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 'real' labels
- which define entry points and complete routines stand out.
-
- Page 33
-
-
- Using local lables
- ------------------
- There are some features of local labels which you should be aware of.
- Firstly they cannot be used as the operand of some instructions or
- psuedo opcodes. As has already been mentioned 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 then 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 up to 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 would use 00-09, the next 10-19, then
- 20-29 etc. This not only makes the code easier to read it ensures that
- there are plenty of 'spare' labels in each set if I need to add extra
- code later. You don't, of course, 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. This is because a
- branch to a low number will go back to 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 accidentally
- use the same local label within its 'set' you will get the same
- problems as can exist with any other duplicate label. This should not
- be a problem in practice, especially if you define labels in numeric
- order, because each set of labels will normally fit within a couple of
- 'screens' of code and any duplicate or out of sequence labels can be
- plainly seen.
-
- The maximum number of 'sets' of local labels allowed is over 2700,
- which should be enough for any eventuality.
-
- Page 34
-
-
- Example
- -------
- Any Branch instruction will only reach back to the last 00 label and
- forward to (but not including) the next. 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 ........
-
-
-
- Forward branch to 00
- --------------------
- 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. You can
- NEVER branch forward to a 00 label.
-
- There are two ways to produce the desired result. You you could insert
- a 'dummy' label somewhere before the branch instruction to 'reset' the
- local label system, for example -
-
- .00 cmp r0,#32
- bne 01
- ........
- ........ ;code to be skipped if r0 not 32
- .01 ........ ;rest of code
- Page 35
-
-
- The 00 label is not used but it resets the local label system so that
- the branch is correctly interpreted.
-
- An alternative is to insert a label specifically for the forward branch
- just before the next 00 label.
-
- cmp r0,#32
- bne 90
- ........
- ........ ;code to be skipped if r0 not 32
- .90 ;empty line with just a label
- .00 ........ ;rest of code
-
- 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 : .00
-
- wouldn't work. The two labels must be on separate lines.
- Page 36
-
-
- -=O=- ENHANCED 2nd OPERAND -=O=-
-
- 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 an immediate number
-
- As you can see this makes the code easier to read and also avoids
- errors when you forget to include 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 the '#'.
-
- 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 sort of ambiguity it is usual when writing ARM code to
- always 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.
-
- Page 37
-
- -=O=- EXTRA MNEMONICS -=O=-
-
-
- These are not actually mnemonics but are macros which are expanded by
- the preprocessor. They are written into the code just like normal
- opcodes and so this distinction can normally be ignored. One important
- difference is that unlike all normal mnemonics some CANNOT have
- conditional suffixes.
-
- Some of these call the built-in macro functions and reference should be
- made to these for further clarification if required.
-
- They may all be written in upper or lower case like normal assembler
- mnemonics.
-
-
- DW and DD
- ---------
- These are expansions of the normal EQUD and EQUW codes 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 codes (and the
- DB mnemonic which follows) to cause the line to 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 that 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.
-
- Page 38
-
-
- 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 acts exactly like DW and DB but with byte
- sized sections as a multiple EQUB. However 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 mixed with control codes
- much easier. For example -
-
- DB 7,"This is some text",10,13,"A new line",0
-
- would be expanded to -
-
- EQUB 7:EQUS"This is some text":EQUB 10:EQUB 13: EQUS"A 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 the next 100 bytes of memory as a data area and load them
- with the value 32, a space character.
-
- This can be mixed in 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.
- Page 39
-
-
- Basic variables and DB
- ----------------------
- It is possible to 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>
-
- You will notice that 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 problems please
- tell me.
-
- Page 40
-
-
- 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.
-
- Note that there MUST be a space between ADRL and <register> and that it
- CAN now be made conditional
-
-
- 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 <register>,<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 does not always produce the most
- efficient code for loading a given value. If speed or code length is
- paramount it may often be possible to reduce the number of operations
- by hand coding.
-
- Note that there MUST be a space between MOVL and <register> and that it
- CAN now be made conditional
-
- Page 41
-
-
- 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.
-
- Note that 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 then 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.
-
- Page 42
-
-
- -=O=- MACROS -=O=-
-
-
- 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.
-
-
- Macro Functions - Pro/Con
- -------------------------
- These are normal Basic Functions and their use and format is fully
- 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 always 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 that no matter how many times you call it it doesn't
- take any more memory. The second advantage is a consequence of this and
- 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.
-
-
- Expanded Macros - Pro/Con
- -------------------------
- These are short sections of code which are physically 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.
-
-
- Macro Names
- -----------
- Because Macro Functions and Expanded Macros are completely 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.
- Page 43
-
- -=O=- EXPANDED MACROS -=O=-
-
-
- An Expanded Macro must be defined before it is used. If you use a Macro
- Library it may be defined there and SAsm will load it from the Library.
-
- If you define a macro in your source file and one of the same name
- exists in the Library then the macro in the source file will be used in
- preference to the one in the Library.
-
-
- Defining 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, with any
- parameters, is case sensitive. As with other SAsm directives the '#'
- used by #SM (Start Macro) and #EM (End Macro) must be the first
- non-space 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, which is defined in the usual way by preceding
- it with ';' or '\'.
-
- Whenever SAsm encounters a '@' it will match the following name with
- any previously defined macros. When it finds one it will physically
- insert a copy of the code into the file. If there are any LOCAL labels
- in a macro they will be unique within that definition, but all
- non-local labels will be global.
-
-
- Macro Parameters
- ----------------
- You can pass parameters of almost any type to an Expanded Macro. The
- full syntax of the defining line of the start of a macro is -
-
- # sm <name> <param name 1> , <param name 2> , <param name 3> ....
-
- and of the calling line -
-
- @ <name> <param value 1> , <param value 2> , <param value 3> ....
-
- where <name> is the actual name given to the macro, <param name> is the
- name given to each parameter and <param value> is the value that each
- parameter will be assigned when the macro is expanded.
- Page 44
-
-
- A parameter is actually a Global Variable and should conform to the
- variable type that Basic would use for the type of value that it will
- hold. It can be an Integer, String or Floating Point variable. 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.
-
- There must be at least one space between <name> and the first parameter
- and parameters are separated by commas.
-
- In fact you will recognise that the syntax has deliberately been made
- identical to the way that parameters are passed to Basic Functions and
- Procedures except that there are no brackets.
-
-
- Local Labels in Expanded Macros
- -------------------------------
- You can use local labels in expanded macros and these should conform to
- the syntax used elsewhere. You MUST start any local labels in a macro
- definition with '00' to ensure that the labels used 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 therefore exist within the area of 'normal'
- local labels without confusion. In practical terms this simply 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.
-
-
- Special features of Expanded macros
- -----------------------------------
- The most obvious advantage of expanded macros is that you can take
- advantage of all the special features of SAsm when using them. The
- ADRL, MOVL DB, DW and DD pseudo-ops can all 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
- possible (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 obviously
- set up an infinite loop which would cause all available memory to be
- filled. This is another reason for limiting the nesting of macros
- because if this is done by accident an error will be flagged long
- before this stage is reached.
-
- Page 45
-
-
- 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.
-
- Page 46
-
-
- 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.
-
-
- Errors in Expanded macros
- -------------------------
- SAsm will normally be able to recover from errors in expanded macros.
- In this case the error message will be slightly different from normal
- and in the form;
-
- Error <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 a bit 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 discovered by inspection but I may improve upon it in a
- later version.
-
- Page 47
-
-
- -=O=- MACRO FUNCTIONS -=O=-
-
- General
- -------
- 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'.
-
- Briefly a Macro Function is a Basic Function who's definition, as with
- functions in a normal Basic program, must appear after the #END
- directive. You use it by simply writing FN<name>, where <name> is the
- name of your function, in your assembler source. Most Macro Functions
- will require parameters and these are passed by being 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 statements 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
- therefore use either of these when defining Macro Functions although I
- suggest that you use PASS as its purpose is more obvious. The only time
- you need to depart from this is if you are using a forward branch in
- the macro. In this case you will need to define a two-pass loop within
- the macro and so you MUST define your own OPT variable. In theory 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 probably
- safer to use an independent variable. However it is very important that
- you do NOT modify in any way the Basic Integer variable Q%.
-
- WARNING - You cannot use the SAsm 'extra' mnemonics DB, DW, DD, DIV,
- ADRL, MOVL or the enhanced immediate 2nd operands in Functions. These
- are ONLY available in the main body of the code or within Expanded
- Macros before the #END directive. 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.
-
-
- 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.
- Page 48
-
-
- 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.
-
-
- FNset ( <size>,<value> )
- ------------------------
- Similar to FNgap except that the memory is preset to <value>. Use the
- DB mnemonic in preference wherever possible.
-
-
- 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 and two only if absolutely necessary.
-
- This is equivalent to the ADRL expanded mnemonic which should be used
- in preference.
-
-
- 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.
-
- Page 49
-
-
- -=O=- THE MACRO LIBRARY -=O=-
-
-
- --** This facility is available only to REGISTERED users **--
-
-
- 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 special 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 will be used in
- preference to one of the same name in the Library. If a macro is
- defined part way through the source files then any 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.
-
-
- The 'L' parameter
- -----------------
- If you are using 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 your command line to tell SAsm NOT to
- use the Library, even if SAsm$Lib (see later) is defined.
-
- Page 50
-
-
- 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 be classed as an error but it
- will become one during assembly because the macro will be missing.
-
-
- 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.
-
- When SAsm can't find a macro definition in the source files it has
- loaded it will check to see if a Library has been defined. If it is it
- 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 the definition of a macro in the source files 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
- required macros exist in the source it is best to use the 'L' parameter
- to ensure that this doesn't happen.
-
- Page 51
-
-
- Preparing a Macro Library
- -------------------------
- First create a source file of Macro Functions and/or Expanded Macros.
- These are macro definitions definitions exactly like the ones you would
- normally use in your source files.
-
- Each Expanded Macro should begin with the #SM directive and end with
- the #EM directive.
-
- In earlier versions of SAsm it was stated that each Macro Function
- definition should end with an '=' as the first character on a line but
- this is no longer required.
-
- 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. Now 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 of course 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.
-
-
- Length of Library file
- ----------------------
- The source for your Library file can be any length and can have as many
- comments ay you like. As with normal 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 which should be
- enough for anyone. 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.
-
- Page 52
-
- -=O=- SASM AND THE DESKTOP -=O=-
-
- 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 is still not integrated into the desktop
- environment Versions after 1.40 have features which help them to be
- used in this way.
-
-
- The new features
- ----------------
- The changes which have been introduced are described in the section on
- directives. They enable all of the parameters which previously had to
- be typed at the command line (and more) to be inluded in the file as
- Directives. This should mean 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. The next step is to write a desktop 'front end'
- for SAsm which will enable programs to be assembled within the desktop
- in a similar manner to Acorns (unbelievably expensive) DDE and this
- will be appearing soon (I hope!).
-
- Even without the 'front end' you can now use SAsm within the desktop
- very easily and assemble projects by clicking on a single 'Obey' file.
- You will not now need to set the CSD as you will be able to use the
- <Obey$Dir> OS variable to define the 'start point' of your project
- directory structure.
-
-
- Using SAsm from the Desktop
- ---------------------------
- You can now include everything needed to assemble an extensive project
- in a single short 'make' file. This would normally be a text file and
- will 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. 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.
-
- Page 53
-
- 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.
-
- Your 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 will have to wait for the new 'front end' to have messages trapped
- in a desktop window, at present they'll just appear in a Command
- window.
-
-
- You can, of course, use SAsm in a 'Task' window but this means you will
- need to define directories and type filenames again. In fact this is
- the way that I normally use it but I am accustomed to operating with
- set directories. 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.
-
- Page 54
-
- -=O=- PROBLEMS and QUESTIONS -=O=-
-
-
- At present SAsm is entirely Command Line driven and doesn't have a
- desktop 'front end'. There is no reason why this can't be done, in fact
- a P.D. version has already been written by Ainsley Pereira and you may
- have found a copy of this with your copy of SAsm. As soon as I feel
- that the 'core' program is stable I shall write one so that you can
- work entirely within the desktop if you wish.
-
-
- 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 your
- bug reports and suggestions that I can keep improving it.
-
-
- Reporting and diagnosing problems
- ---------------------------------
- Tell me which version of SAsm you are using. You may have experienced a
- 'bug' which has already been fixed. It can save me a lot of time trying
- to reproduce an error which can't occur on a later version. Ideally
- send the version of SAsm that you are using. I may no longer have a
- copy of that version (there have been quite a few updates!)
-
- Please 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. Especially 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 you can please '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 any problem 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 find you can produce a perfectly good 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 that all this isn't necessary because I should be able to
- reproduce the problems that you have experienced. Unfortunately this
- may not be so. I have sometimes 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 was crashing,
- 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.
- Page 55
-
-
- I use SAsm a lot myself and so it -*should*- be bug free because 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 and others almost never. Experience has shown that there is
- always someone who does something that I have never thought of. Often
- this is quite legitimate, sometimes downright weird, but it just
- introduces a variation that I haven't allowed for. Most modifications
- to SAsm consist of 'fixes' and improvements to accommodate the way that
- other people write code.
-
-
- One possibility that can happen with both SAsm and the Basic asembler
- is that labels, constants and register names are all 'normal' global
- variables. Most assemblers, such as Acorns AAsm, treat register names,
- labels and constants differently. You must therefore 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 that 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 simply pressing RETURN when you type the
- command, hold down both SHIFT keys and press the keypad ENTER. This
- will stop any assembly taking place and will save 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.
- Page 56
-
-
- 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
- distributed version.
-
- The source for SAsm consists of more than 7000 lines split over eight
- 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. These times
- assume operation direct from the CLI and are slightly longer if a Task
- window is used. I think this is fast enough for most purposes.
-
- Naturally if you didn't have a hard disc the time taken would be quite
- a bit longer but as SAsm can easily use a RAM disc this shouldn't be a
- serious problem 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.
-
-
- Memory usage
- ------------
- SAsm does not use any Heap or WimpSlot calls. It works with whatever
- memory you have chosen to give it by way of the 'Next' slider on the
- Task Display. I don't intend to change this in the CLI driven program
- because I feel that this is something that should be under the
- operators control. If you are writing machine code you are not a novice
- user and should be capable of managing such things.
-
- 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 then 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 then 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.
-
- Page 57
-
-
- 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.
-
-
- The most common problems
- ------------------------
- There are a few 'features' of SAsm which can cause trouble. Some are
- minor bugs that are not important 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
- which have been raised by users in the hope that it will avoid others
- experiencing the same problems.
-
- Before you decide that it's a bug in SAsm that's making things go wrong
- PLEASE read through these and assure yourself that none of them could
- possibly apply. Most of the 'problem code' that I am sent displays one
- or more of these errors.
-
- Because of the way in which SAsm operates it does not have perfect
- control over assembly and there will always be things which can make it
- crash. As time goes on 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'.
- Page 58
-
-
- 4. You cannot use local labels, DB, DW, DD, ADRL, MOVL, DIV or any of
- the enhanced second operator functions after the #END directive.
- This means you can't use them within Macro Functions. You can,
- however, 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 processes a file
- but other operations expand it. Normally the contraction is greater
- than the expansion so the file shrinks. As each file is loaded a 16K
- 'overhead' is allowed in case the file does grow. Normally this is
- plenty but in extreme cases of large individual files without spare
- spaces or comments the program could crash. I will add routines to
- guard against this when I get time but I do not regard it as a
- serious fault because a major 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 this by loading the file into your editor and pressing
- CTRL-Down Arrow 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 enought 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 much greater
- than the length of the file where the error occurred. Usually this
- means that the error happened inside a Macro Function. This is
- always a problem with Basic Functions and Procedures and there is no
- simple solution. Often the only way of discovering the actual error
- is to examine every FN call in the file in which the error occurred.
- The filename given will be the name of the file from which the
- function was called, and if the function 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.
- Page 59
-
-
- 11. If SAsm 'crashes' for any reason (it can happen, although the things
- causing it are slowly being eliminated) then it can leave the error
- or x-ref file open. Normally if there is a fatal error these files
- are closed but obviously if SAsm itself crashes this may not happen.
- You are unlikely to be aware of this until you try to run SAsm again
- when the 'file open' error will occur as SAsm tries to open an error
- file which is already open. 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 does happen then you will actually
- have lost the first error message although the error will have been
- counted). Source or Object files cannot be left open because these
- are only accessed as whole files. The error could occur with a
- listing file but this is unlikely. It is possible that some filing
- systems may not return the 'standard' error number and so 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 you are 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 else 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. SAsm does not mind whether you use LF (ascii 10) or CR (ascii 13)
- characters at the end of each line. Most Archimedes text editors use
- LF's but some, such as StrongEd, 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 the code check that you
- haven't put 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.
-
- Page 60
-
-
- -=O=- RELEASE HISTORY -=O=-
-
- 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 system 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 now be run from
- the RMA for floppy disc users.
-
- 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
- Page 61
-
-
- 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
-
-
-
- Registration Form for SAsm
-
-
- Please complete this and post it with your cheque for Eight Pounds to;
-
- David Holden, 39 Knighton Park Road, Sydenham, London SE26 5RN
- ____________________________________________________________________
- Name and Address:
-
-
-
-
-
-
-
- ____________________________________________________________________
- Where did you obtain SAsm:
-
-
-
-
-
-
-
- ____________________________________________________________________
- Have you had any problems:
-
-
-
-
-
-
-
-
-
-
- ____________________________________________________________________
- What additional features would you like:
-