# Copyright 2008 Castle Technology Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#


Document Status
---------------
  Distribution:  Company Confidential
         Title:  Makefile migration (aasm -> objasm)
Drawing Number:  2503,105/T
         Issue:  1
     Author(s):  Stewart Brodie
          Date:  2001-04-11
 Change Number:  N/A
    Last Issue:  1


Contents
--------
Document Status
Issue History
Introduction
Changes
Makefile
Assembler



Issue History
-------------

1       11/04/01        Original version


Introduction
------------

This document describes, in outline, the changes that must be made to RISC OS
components currently built with aasm to permit them to build using the shared
makefiles and objasm.  It assumes that the reader has some knowledge of the
RISC OS system and ARM assembler.

THIS IS NOT A REVIEWED DOCUMENT - MERELY NOTES TO PROGRAMMERS WHO NEED THE
BENEFIT OF OUR PRIOR EXPERIENCES.

Because of this, not all the technical terms are explained fully, and there
is no glossary.


Changes
-------

The key features are:

* Avoid duplication by using shared rules in AAsmModule makefile fragment
* Avoid conflicts with build system macros by only defining them to be the
  same as srcbuild defines them.
* Permit building with objasm, to permit cross-compilation (no sources to
  aasm and no Solaris version)
  
AAsm also does not support the full ARM instruction set as required by lots
of our assembler source code nowadays either, instead requiring complex
macros to encode various instructions like MRS and MSR.


========
Makefile
========

In the best cases, the makefile can be just three lines:


COMPONENT = ...component name...
include StdTools
include AAsmModule


In practice, this is only possible for modules which have resources (e.g.
messages files), have TARGET the same as COMPONENT, export no headers and do
not require exotic switches to objasm/link.

COMPONENT and TARGET should be set based on the first and fifth fields of the
module's entry in the ModuleDB file.  If TARGET is the same as COMPONENT (as
is the case for many components), then TARGET need not be defined -
AAsmModule will default it to whatever COMPONENT is.

A lot of the information in this section is informational.  You should be
aware of it, but most will be irrelevant for many modules.


AAsmModule
----------

The AAsmModule makefile fragment (look at it) defines an awful lot of rules
and macros.  Many of them are there to be useful defaults.  In most cases,
rules are defined using double-colon notation to permit you to add extra
commands to be executed for those cases.  This could be useful for rules such
as "clean", where you want AAsmModule to clean all the standard stuff that it
has created, but you need to do some extra cleaning.  The top-level makefile
can just say:

clean::
  ${RM} myotherfile
  
and this will be executed IN ADDITION to the ones in AAsmModule.  [Note that
if you use macros defined by StdTools, such as RM in this example, you need
to put these rules at the end of the file after the two includes.]

It is assumed that the reader has a copy of the AAsmModule makefile fragment
available (from RiscOS.BuildSys.Makefiles) for reference.  Not all the macro
definitions are going to be explained - work the details out for yourself.


Clean
-----

See previous section.  clean does *not* remove the rm directory.  Use a
supplementary rule to remove it if you need to get rid of it (most don't want
this).


Resources
---------

If the component has resources that are in the standard form
(Resources.<Locale>.Messages), then no action need be taken - AAsmModule will
handle this for you.  It will also handle appending of CmdHelp files
containing the syntax and help messages for *-commands in the module - it
looks for LocalRes:CmdHelp.  Some modules have called this file Syntax and
have it in the root of the component.  If this is the case, copy it into
Resources.UK as CmdHelp and cvs add it, cvs remove the original file in the
root.

AAsmModule provides the "resources" rule invoked by srcbuild to export
resources.  If you want to prevent AAsmModule's rule from being invoked, you
must define the macro CUSTOMRES to "custom".  AAsmModule defines a
rule for "resources${CUSTOMRES}", so by setting CUSTOMRES, you change the
rule that it is defining, thus allowing you to substitute your own resources
rule.
If there are no resources, simply define CUSTOMRES as "no".  AAsmModule will
then provide a rule that echos a message saying that there are no resources
for this component during builds.

Supplementing the resources rule may actually be more worthwhile in many
cases.  You can supplement resources_common, resources-, resources-None or
resources.  This scheme works by allowing srcbuild to set CMDHELP=None on the
make command line to avoid getting the syntax and help messages in the
Messages file.

The 'resources' rules provided assume that the ResourceFS target directory
for any messages is Resources.${TARGET}.  If it is not this, then you must
set the macro RESFSDIR to be the target directory.  You can use the macro
RESDIR in your definition (it will point to the Resources directory - hence
the default of ${RESDIR}.${TARGET}).


Export
------

AAsmModule can export headers automatically.  There are three classes of
header file: assembler, C and assembler that needs translating into C.

To export headers, place these macro definitions before the inclusion of the
sub-makefiles.

assembler: "HEADER1=leafname"  This copies hdr.leafname to
${EXP_HDR}.leafname (which should mean Export.<APCS>.Hdr.Interface)

C: "CHEADER1=lefaname"  This copies h.leafname to ${C_EXP_HDR}.leafname
(which should mean Export.<APCS>.C.Interface.h.leafname)

assembler->C: "ASMCHEADER1=leafname"  This runs the Hdr2H script on
hdr.leafname to generate ${C_EXP_HDR}.leafname.

Each of the three methods supports up to three header files (HEADER1,
HEADER2, HEADER3; CHEADER1, .. etc.)


ROM / Standalone / Debug
------------------------

The 'rom' rule assembles the module destined for ROM.

The 'standalone' rule assembles the module destined for softload (or
extension ROM or expansion card).  The (logical) assembler macro 'standalone'
is initialised to true, and the string macro MergedMsgs is set to the
filename of the messages file to be embedded in the module

The 'debug' rule assembles a standalone module with debugging enabled (the
(logical) assembler macro 'debugging' is initialised to true)

NOTE:  Not all modules support standalone - they never have their resources
embedded in them.  Even fewer support debugging.


The single source file is assumed to be "s.${TARGET}", but if this is not the
case, then you must supply a macro definition ROM_SOURCE which is the name of
the source file.  Use the UNIX notation for the filename "leafname.s" rather
than "s.leafname".

The output object file is ROM_OBJECT, SA_OBJECT, DBG_OBJECT for rom,
standalone & debug targets respectively.  These are all defaulted.

The final built image is ROM_MODULE, SA_MODULE & DBG_MODULE for rom,
standalone & debug targets respectively.  These are all defaulted.



install_rom
-----------

This rule copies ROM_TARGET to ${INSTDIR}.${TARGET}.  This is correct and
should not be changed.


Tokenisation
------------

Some components run the tokenise tool to tokenise their help messages.  This
is automated by AAsmModule, but you must supply two macro definitions to
enable it:

TOKHELPSRC = ${TOKENSOURCE}
HELPSRC    = untokenised file

The former is required (exactly as shown) to ensure that the object files are
declared to be dependent on the tokenised message source file; the latter
indicates the file containing the untokenised messages that are to be
tokenised.  TOKENSOURCE itself is defaulted (to s.TokHelpSrc). 
${TOKENSOURCE} is DELETED during the default clean phase.


=========
Assembler
=========

Once the Makefile has been redesigned, attention should turn to the source
files.  It may be easier to simply attempt builds of the module and let
objasm report all the things it doesn't like.  However, you should read
through this list first to help you recognise the things that get thrown up. 
Some errors (like the LEADR one) will require fixing before the others become
apparent, so the process will be iterative.


LEADR
-----

This line will be faulted by objasm - delete it.  Replace it with an AREA
declaration.  It is suggested that something like:

  AREA |modulename$$Code|, CODE, READONLY, PIC
  
is suitable.  You won't get very far until you fix this one.  If you start
getting errors about declarations not inside areas, you need to move the AREA
declaration closer to the start of the file (maybe into ${ROM_SOURCE} itself)


GET/LNK
-------

The single source file (ROM_SOURCE - see above) may have a whole string of
GET instructions to pull in all the component's source files (assuming there
is more than 1!) or it may GET or LNK to one other and each source file will
simply GET/LNK the next one at the end.   You should change all of these
local GET/LNKs to use UNIX-style notation (Foo.s, instead of s.Foo). 
Although this isn't faulted, it will aid the cross-compilation effort later
on.


MRS/MSR
-------

aasm did not support the MRS and MSR instructions, so macros mrs and msr were
developed to permit this instruction to be encoded by aasm-based modules. 
These must be converted to the upper-case forms to avoid clashes with the
macros, plus the condition code (if any) needs to be appended to the opcode
e.g.

  mrs   ,r9,CPSR      -->   MRS    r9, CPSR
  mrs NE,r8,SPSR      -->   MRSNE  r8, SPSR
  
Note the potentially empty field in the macro usage for holding the condition
code, hence the odd looking comma before the register number.


ORG
---

This is not permitted for relocatable code - it should not be there.  If you
find this in a component, either stop fiddling with the kernel or ASK A GURU.


ResourceFile
------------

This is a macro which is usually used in standalone builds to define a
ResourceFS-compatible data block for an embedded messages file.  However,
instead of naming Resources.<Locale>.Messages or LocalRes:Messages as the
file to embed, it needs to simply use $MergedMsgs instead.  The Makefile sets
this when building 'standalone' or 'debug' modules to the name of the merged
messages+cmdhelp file.


standalone / Standalone / other options
---------------------------------------

Many modules have the capability to build standalone modules (ie. with their
resources bundled in, code to handle ResourceFS (de|re)registration etc., but
not always based on the symbol name 'standalone'.  It is suggested that you
insert the following change (shown by example of a module that uses the macro
'resources' to determine its build type)

            GBLL    resources
resources   SETL    {FALSE}         ; {TRUE} to include resources

... changes to ...

            GBLL    resources
    [ :DEF: standalone
resources   SETL    standalone
    |
resources   SETL    {FALSE}         ; {TRUE} to include resources
    ]

Although this may seem complex, it does simplify non-build system builds (ie.
by using !Mk as it does not rely on standalone being set by the !Mk script)

It is recommended that you not bother adding standalone capability to modules
that do not already have it.


ENTRY
=====

These must be converted to Entry, as ENTRY is a reserved word in objasm.  Be
wary of doing a global search & replace, because you don't want to change any
occurrence of ALTENTRY.


\
=

Backslashes were not special characters in aasm, but they are the escape
character in objasm.  You will need to double any \ characters:

  TEQ  r0, "\"   -->   TEQ  r0, "\\".
  
Also watch out for \ at the end of comments.  Since these are usually part
of ASCII art, usually a suitable replacement character can be substituted
(+ can be a good choice).


Non-aligned instructions
========================

AAsm would automatically align the program counter to the next word boundary
before generating code after inlined data.  objasm requires an explicit ALIGN
after such data:

helpstring DCB "MyModule", TAB, "$Module_HelpVersion", 0
mycode
        MOV     r0, #0

If the data at helpstring is not an exact multipe of 4, then you will get
an error about mycode being non-aligned.  Simply insert an ALIGN directive
before the mycode definition.

helpstring DCB "MyModule", TAB, "$Module_HelpVersion", 0

        ALIGN
mycode
        MOV     r0, #0



==END==
