home *** CD-ROM | disk | FTP | other *** search
- ARMmaker
- An ARM assembler, including AOF and floating point assembly
- (C) Steven Haslam 1994
- -----------------------------------------------------------------------------
- This program may be used with Acorn Computers' Desktop Development
- Environment, but may also be used as a standalone for any suitable
- application, e.g. ANSI C release 3. It may also be used to assemble code to
- run from RiscOS without other supporting programs.
- -----------------------------------------------------------------------------
- All of the program code was written by Steven Haslam.
- Floating point instruction format deduced from BASIC library by TJ Chappell
- Coprocessor and SWP instruction format deduced from !AS by Niklas Röjemo
- My thanks to these authors.
- -----------------------------------------------------------------------------
- ARMmaker is "FreeWare": its copying and distribution are permitted provided
- that no profit is being made: see the end of the file for details.
- -----------------------------------------------------------------------------
-
- Programmers will be aware of the ARM assembler built into BBC BASIC. However,
- this assembler has limitations, including, but not limited to:
-
- Inability to export to AOF files: for use with C, Pascal or very large
- machine code projects.
- Floating point/coprocessor functions not built in.
- Range of ADR limited to single-instruction capability
-
- Of course, if you want a DDE assembler with all the features, you can buy
- Acorn's own Desktop Assembler. A snip; costs >=£100, I believe. By
- comparison, ARMmaker is *FREE* (see end of file for details).
-
- ARMmaker is not a mega-assembler. It's an assembler "what I wrote" to cover
- the points above (although all but AOF export can be handled (just about) in
- BASIC). It was written after I got fed up with "TLA", another PD AOF
- assembler (ok, but no floating-point, nasty syntax (IMHO), I keep losing the
- documentation, no throwback &c. &c.)
-
- Basically, ARMmaker can:
-
- Read an assembly listing from one or more files (using the INCLUDE command
- to read from a different file).
- Assemble the code, offering features such as macro expansion, symbol
- import and export (with AOF), register bindings, multiple areas (AOF),
- floating point instructions, local labels &c.
- Report errors in a vaguely sensible manner (mre detailed messages than
- with the BASIC assembler most of the time), including via the "throwback"
- mechanism where errors are sent to your text editor
- (SrcEdit/StrongED/Zap/DeskEdit &c.)
- Export the assembled machine code to any of the standard code formats on
- Risc-OS; i.e. straight code with types Utility, Module, Absolute, code with
- load/execution addresses set directly, or AOF (written as a Data-type file).
-
- ARMmaker is supplied as a DDE tool, the application !ARMmaker. This
- application contains the actual program, and includes some standard
- definitions that can be included into your source file.
-
- ARMmaker and the DDE
- ====================
-
- If you intend to use ARMmaker with the DDE, then you will want to copy the
- !ARMmaker application into your DDE directory, along with !CC, !Link and so
- on. You can add ARMmaker as a tool to !Make. Load the file
- "!Make.choices.tools" and go to the bottom of the file. Now add the following
- six lines to the end of the file:
-
- ARMmaker
- arm
- -d !Depend -t
- ARMmaker $(ARMmakerflags) -o $@ $<
- <ARMmaker$Dir>.Desc
- <ARMmaker$Dir>.!Setup
-
- Resave the file. You will have to quit !Make and re-run it before you can use
- the new option. ARMmaker files should go in a directory called "arm" (in the
- same directory as "c", "o" and "h") to be automatically recognised as
- ARMmaker source files.
-
- ARMmaker without the DDE
- ========================
-
- The !ARMmaker application defines an alias to run the ARMmaker executable
- from inside itself whenever the command "armmaker" is executed, e.g. from a
- makefile.
-
- The command to assemble a file is:
-
- armmaker <filename> [-o <outputfile>][-t]
-
- The "-t" option enables throwback.
- A default will be used if the "-o" option is omitted, but you will be warned.
-
- ARMmaker other details
- ======================
-
- ARMmaker is a one-pass assembler. Therefore, when you use a symbol that isn't
- understood, ARMmaker remembers the reference. When you finally define the
- symbol, all the references are put into the code (relocate branches, ADRs
- &c.) and then deactivated.
-
- One point is that if you do an ADR as a forward reference, and then when the
- symbol is defined it's out of range, it will only be detected at the symbol
- definition. However, ARMmaker WILL tell you the line number of the reference
- that cannot be resolved: but your throwback window will not necessarily have
- the line numbers is monotonically ascending order! You have been warned!
-
- ARMmaker source files
- =====================
-
- ARMmaker source files differ greatly from BASIC source code, being modelled
- more on the Desktop Assembler, itself modelled on the accepted layouts of
- assembler code on other platforms (ptui!).
-
- At any point in the file, a semicolon (';') indicates a comment, starting at
- and including the semicolon up to and excluding the end-of-line character.
-
- If the first character on a line is not a space or a tab (collectively called
- "whitespace") then it is the start of a label. Notice that labels are not
- preceded by a character (unlike BASIC) and must not be suffixed with a
- character (unlike TLA).
-
- The start of the line is called the label "field".
-
- After the label field is the "instruction/directive field". This is separated
- from the label field by whitespace. This field might be followed by a
- "parameter field" (separated, again, by whitespace).
-
- Let's see how that looks in practice. This is an example with all three
- fields:
-
- loop MOV R0, #0 ; This is a comment
-
- Because "loop" is right at the start of the line, it's a label definition.
- ARMmaker defines a symbol called "loop" and sets it to point to the current
- position in the file. You can't have another symbol called "loop"; if you
- want lots of loops in your code, use local labels (see below) or call them
- all something different (mind-boggling!).
-
- The instruction field is "MOV", which you should recognise as an ARM
- instruction. The parameters field is "R0, #0". The comment is stripped off
- before the fields are looked at.
-
- So, this line will define a label, called "loop". The first instruction of
- the loop will be "MOV R0, #0".
-
- Here is a silly chunk of code:
-
- label1 STMFD R13!, {R14}
- MOV R0, #32
- MOV R1, #127
- loop SWI "OS_WriteC"
- ADD R0, R0, #1
- CMP R0, R1
- ADDEQ R0, R0, #1
- CMP R0, #256
- BNE loop
- LDMFD R13!, {PC}^
-
- Try deciding what this piece of code does, and what ARMmaker does when it
- assembles it.
-
- It is perfectly OK to have just a label on a line, and no instruction. So,
- replacing the 3rd to 5th lines of the above code with the following four will
- actually have no effect on the finished machine code:
-
- MOV R1, #127
- loop
- SWI "OS_WriteC"
- ADD R0, R0, #1
-
- As well as machine code instructions, there are "directives" (as opposed to
- instructions) that are processed by ARMmaker. These may produce output
- directly, or may affect it in some more subtle way.
-
- Every properly-written source file will have some directives, certainly at
- the top of the file. You ought to have a directive telling ARMmaker what type
- of file you are making, for example.
-
- The first directive that I'll show you is called "OUTPUT". You use it just
- like an instruction called OUTPUT, except that you can't use it on the same
- line as a label, which wouldn't be very useful anyway.
-
- OUTPUT is to specify what kind of file you are making; you give it one
- parameter, which may be one of the following:
-
- ABSOLUTE Code that loads to and starts at address &8000, type &FF8.
- MODULE A relocatable module, type &FFA, with a special header.
- UTILITY Transient code that is must be completely relocatable, type
- &FFC.
- AOF Acorn Object File, an input file that is sent to "link",
- and contains functions that can be shared with C or Pascal programs.
- DIRECT "Directly executable" code that loads to a specific area of
- memory and starts at some user-specified point within memory. Also called
- "untyped" files, since they don't have a standard filetype.
-
- For example, to tell ARMmaker that you are writing an "Absolute" file, you
- would have this line at the top of your file:
-
- OUTPUT ABSOLUTE
-
- To "include" another file inside your source file (i.e. go process another
- file and then come back to the one before), use the "INCLUDE" directive. Give
- the name of the file as a parameter. ARMmaker will first look in the locality
- of the source file, and then on ARM$Path.
-
- INCLUDE inc.APCS-R
-
- If you are writing an AOF file, you will need to declare an area. All object
- files are separated into areas. Most have two: one for code, and one for
- data.
-
- Areas all have names, which are unique within an object file, and local to
- it. They are normally "<lang>$$Code" and "<lang>$$Data": C creates areas
- called "C$$Code" and "C$$Data", for example.
-
- Use the "AREA" directive to declare an area. You must give the areas name,
- and some flags telling ARMmaker (and therefore link) about the area.
-
- Generally, you will only need two, or maybe three kinds of areas. The first
- kind, a code area, is defined like this:
-
- AREA ARM$$Code:CODE,READONLY
-
- A data area is defined like this:
-
- AREA ARM$$Data:DATA
-
- The third kind of area is a zero-initialised area. This is slightly different
- in that you can't put code in a zero-initialised area, obviously. Instead,
- you must give the size of the area in the declaration, like this:
-
- AREA ARM$$ZIData:DATA,ZINIT,SIZE=512
-
- where 512 is replaced by the size of the zero-initialised data you want
- included.
-
- An important feature of AOF files is importing and exporting symbols between
- different object files. But you must tell ARMmaker to do this. If you want to
- use the symbol "printf" in your machine code function, you must tell ARMmaker
- to import it, using the "IMPORT" directive:
-
- IMPORT printf
-
- Similarly, if you want to use a machine code function (e.g. "armfunc")
- outside your object file (e.g. from a C program), you must tell ARMmaker to
- export it, using the "EXPORT" directive:
-
- EXPORT armfunc
-
- There are limits on what you can do when using imported symbols. You can
- always branch straight to an imported symbol: no problem. But you can't use
- it directly with ADR or LDR. For example, if you've imported printf as above,
- then
-
- BL printf
-
- will work but
-
- ADR R12, printf
-
- will not. What you can do, however, is store the address of printf inside
- your code area, and load that. For this, use the "DCD" directive, which is a
- bit like BASIC's EQUD.
-
- printf_ptr DCD printf
- ; And later on...
- LDR R12, printf_ptr
-
- The same thing even occurs when accessing data from your data area: it can't
- be accessed directly using ADR or LDR! You can either have a pointer to
- everything, or you can just store a pointer to your data area, and add offset
- to that, e.g.:
-
- data_ptr DCD ARM$$Data ; ARMmaker defines this label for you
- ; When you need data...
- LDR R12, data_ptr
- LDR R12, [data_ptr, #data_offset]
-
- You could even use the macro facilites of ARMmaker to do this more easily
- (see below).
-
- Now, I'll explain the "DC..." directives in more detail. These are for
- storing Data Constants in the output, and are like BASIC's EQUB, EQUD, EQUW,
- EQUS &c. with the addition also of "DCF" (there is no EQUF).
-
- DCD stores a 32-bit value, and can also store have the value of an imported
- symbol added to it during linking.
- DCW stores a 16-bit value, which must be a constant.
- DCB stores an 8-bit value, which must be a constant.
- DCS stores a string. It does not store a terminator.
- DCFS stores a single-precision floating point number.
- DCFD stores a double-precision floating point number.
- Storing extended-precision floating point numbers is not implemented.
-
- These directives may take multiple values separated by commas to save space.
- For example, to store three 32-bit words containing 0 you can write:
-
- DCD 0, 0, 0
-
- After you've used DCB, DCW or DCS you may want to word-align the current area
- offset. Use the "ALIGN" directive. You can align the offset to any multiple,
- not necessarily a power of 2 (although this is not brilliantly useful) by
- giving the multiple as a parameter. If you omit the parameter, "4" is
- assumed. e.g.:
- ALIGN 8 ; align to double word boundary
-
- You can reserve a block of memory using the "BLOCK" directive and giving a
- size. You can also give a byte to fill the block with. Examples:
- BLOCK 1024 ; 1k of zeroes
- BLOCK 512, &ff ; 0.5k of 1's
-
- You can also move up to a specific offset from the start of the current area.
- To do this, use the OFFSET directive giving the offset you wish to move to.
- An error will be reported if you are already past that offset. e.g.:
-
- OFFSET &100 ; Move to offset 256 in area
- label OFFSET &180 ; Set label to offset 384, assemble at 384 too.
-
- Finally, before I let the reference section out of its cage, here's an
- example C/ARM code program:
-
- arm.armcode:
-
- OUTPUT AOF
- INCLUDE APCS-R.inc
-
- AREA ARM$$Code:CODE,READONLY
-
- EXPORT armfunc
- IMPORT ARM$stack_overflow
- EXPORT floatout
-
- FNAME "armfunc"
- armfunc MOV ip, sp
- STMDB sp!, {fp, ip, lr, pc}
- SUB fp, ip, #4
- CMPS sp, sl
- BLLT ARM$stack_overflow
-
- EXPD f0, #1.0
- STFD f0, floatout
-
- LDMDB fp, {fp, sp, pc}^
-
- floatout DCFD 0
- ; EOF
-
- c.ccode:
-
- #include <stdio.h>
-
- extern void armfunc (void);
- extern double floatout;
-
- int main (void)
- {
- armfunc();
-
- printf ("The value of e is %g\n", floatout);
- }
-
- /* EOF */
-
- Remember: to assemble the file use "armmaker arm.armcode -o o.armcode -t" or
- use !ARMmaker or !Make if you have the DDE. Link the files with "C:o.stubs"
- and "ARM:o.ARMlib".
-
- REFERENCE SECTION
- =================
-
- Expression evaluation
- =====================
-
- Expressions are similar to BASIC's expressions, in the naming of operators
- and so on. The operator types, in ascending priority, are:
-
- Conditional
- Bitwise
- Shift
- Addition
- Multiplication
- Unary
- Primary
-
- Conditional is, in fact, the '?' operator from C. It is a ternary operator.
- Its syntax is "<expr> ? <choice1> : <choice2>". If <expr> is non-zero, then
- the value of the expression is <choice1>, otherwise it is <choice2>. You will
- be warned if <choice1> and <choice2> have different types.
-
- Bitwise comprises bitwise AND, OR and exclusive-OR. They are named "AND",
- "OR" and "EOR", just like BASIC, e.g. "3 OR 5" or "2 EOR (3 AND 1)".
-
- Shift operators are logical shift left and right, called "<<" and ">>", e.g.
- "1<<28".
-
- Addition operators are normal addition and subtraction.
-
- Multiplication operators comprise multiplication and division.
-
- The unary operators are "NOT", "+" and "-". "+" and "-" are just to allow
- signed expressions to be given (e.g. "1+(+2)"). "NOT" is a bitwise NOT, not a
- logical one.
-
- Primary expressions are literals and bracketed expressions. String literals
- are as in C (escapes, trigraphs and all) and are automatically concatenated,
- i.e. "ABC" "DEF" is identical to "ABCDEF". This actually makes addition of
- string redundant ("ABC"+"DEF" gives the same thing) but it's allowed anyway.
-
- Integer literals are an unholy combination of C, BASIC and TLA. They may be
- prefixed with "0x" or "&" for hexadecimal, "0" for octal or "%" for binary.
- They may be postfixed with "H" for hexadecimal. Examples:
-
- 12 Decimal 12
- 014 Same
- 0xa1 Hexadecimal 16_A1
- a1H Same
- &a1 Same
- %10 Decimal 2, given in binary
-
- Constants are evaulated where possible, and may be used in instructions,
- e.g.:
- ORRS PC, R14, #(1<<28)
-
- is a valid ARMmaker instruction.
-
- Macros
- ======
-
- ARMmaker allows you to define macros, sets of instructions/directives which
- are "expanded" into the file whenever you call on them.
-
- For example, the text editor Zap requires that extension modes call an offset
- into a table quite often. To make it easier to call this, and to make the
- code more readble, it is nice if you can write "CALLZAP ..." rather than
- several lines of code.
-
- To define a macro, give the macro name as a label, and use the directive
- "DEFM". Macros can take parameters: list the paramters' names in the
- parameters field, separated by commas. This particular example takes one
- parameter (the offset). So the first line of the definition is
-
- CALLZAP DEFM offset
-
- Now write the code that you want including whenever you ask for the macro. If
- you use a parameter ("offset" in this case) it will be replaced by the
- parameter value you give when you call the macro. (Don't Panic; all will
- become clear!).
-
- So, now write:
-
- LDR R14, [R12]
- ADD R14, R14, #offset
- STMFD R13!, {R14}
- MOV R14, PC
- LDMFD R13!, {PC}
-
- This is the end of the macro code, so tell ARMmaker by using the "ENDM"
- directive:
-
- ENDM
-
- Now, if you want to call the offset "Zap_AddMode" (where Zap_AddMode has
- been defined as a constant), you would write:
-
- CALLZAP Zap_AddMode
-
- When ARMmaker sees this, it looks up the macro and actually assembles this
- instead:
-
- LDR R14, [R12]
- ADD R14, R14, #Zap_AddMode
- STMFD R13!, {R14}
- MOV R14, PC
- LDMFD R13!, {PC}
-
- Another example is when you are writing a module, and wish to get the word at
- offset <x> in your workspace. You can define a macro for this. If you call it
- LDW, it will look like an instruction:
-
- LDW DEFM Rd, ofs
- LDR Rd, [R12, #ofs]
- ENDM
-
- And then you can use
-
- LDW R0, wkFlag
-
- Instruction set extensions
- ==========================
-
- There are several "extensions" made to the instruction set by ARMmaker. These
- are not actually new instructions, but a refined form of macro.
-
- One is a copy of BASIC'S ADR instruction. This instruction doesn't actually
- exist, as you may know, it is actually a "ADD Rd, PC, #const" or "SUB Rd, PC,
- #const" instruction.
-
- One problem with this is that the constant has a limited range of values. I
- call a constant that can't be put straight into an ADD or SUB "ill-formed".
- This is because it isn't just because the constant is too large (&ff000000 is
- not ill-formed), but because all the data must be in 8 consecutive bits,
- which must start at an even bit... it's nasty (but necessary).
-
- So, ARMmaker implements an "extended ADR", called "ADRL". This assembles to
- TWO instructions, the first loading the first 8 bits and the second, the
- second. In practice, this extends the addressing range of ADR to 64k, or 256k
- for word-aligned addresses. (Comparision: normal ADR's range is 256 bytes or
- 1k).
-
- Another useful addition is "MOVL". This is an extension of an immediate MOV
- "MOV Rd, #const" which will load any 32-bit constant in as few instructions
- as possible. I mean it: it will get &010801fc in in two instructions, unlike
- most implementations which require four. Although you'll rarely notice this.
-
- MOVL is invaluable in macros. Take an adaption of the LDW macro above. To
- make an ADW (load address of offset within workspace) you would use:
-
- ADW DEFM Rd, ofs
- ADD Rd, R12, #ofs
- ENDM
-
- But this would be limited to the first 256 bytes of workspace (1k for
- word-aligned data). This might not be a problem. If it is, you can use a MOVL
- to help you out:
-
- ADWL DEFM Rd, ofs
- MOVL Rd, #ofs
- ADD Rd, Rd, R12
- ENDM
-
- Which will work for any constant. Obviously, if the offset is not ill-formed,
- then this will waste an instruction, since it will compile to a normal MOV
- and the ADD.
-
- Register bindings
- =================
-
- By default, the registers are named R0 to R15 (and PC) and F0 to F7. These
- names can always be used. However, you can give alternative names using the
- BINDREG directive. Put the alternative name in the label field and the
- register name in the parameters field, e.g.:
-
- a1 BINDREG R0
- SP BINDREG R13
- LR BINDREG R14
- f0 BINDREG F0
- f5 BINDREG F5
- c3 BINDREG C3
-
- The file "inc.APCS-R" binds the registers to their APCS-R names.
-
- You may bind any of the sixteen CPU registers, the eight FPU registers or the
- sixteen coprocessor "registers" (how they relate to actual processor
- registers may vary, e.g. FPU uses bit 3 of some register fields to store
- rounding/precision, and also uses immediates...)
-
- Function names
- ==============
-
- The directive "FNAME" stores the string given as its parameter, followed by a
- zero and aligned to a word boundary. It then stores &ff000000 OR'ed with the
- length of the preceding string field. This is the same format used by the C
- compiler to store function names. Example:
-
- FNAME "myfunc"
- myfunc MOV ip, sp
- ; and so on...
-
-
- becomes
- DCS "myfunc"
- DCB 0
- ALIGN
- DCD &ff000008
- myfunc MOV ip, sp
-
- If you link an object file with the supplied file "ARM:o.ARMlib", then if
- your C program crashes (don't laugh) the stack backtrace function will be
- able to get the name of your function, e.g.:
-
- 80dc in ARM procedure myfunc
- 81b8 in function main
-
- etc..
-
- if you follow the APCS-R documentation given in the PRM and the DDE manuals,
- then you should get a proper backtrace (albeit with no arguments...)
-
- Local labels
- ============
-
- If you start a label with a backslash character "\", then it is called a
- "local label". It is internally renamed, including a sequence number. This
- sequence number is increased whenever a blank line is processed. The point is
- that you can have lots of labels called "loop", for example, without having
- to worry about naming them all ("serv_04_loop_1" &c.). So you can do:
-
- CodeStart ; some code
- \loop ;
- ; a loop
- BMB \loop ; Branch MayBe
-
- ; notice the blank line
- \loop ;
- ; another, separate loop
- ;
- BMB \loop ; goes to second "\loop"
-
- Supplied files
- ==============
-
- Inside !ARMmaker are files named "inc.APCS-x" which binds registers to their
- names under the relevant ARM Procedure Call Standard.
-
- There is a library file "o.ARMlib" which includes routines for use when
- exporting to link (obviously, wouldn't be much use otherwise...) including
- routines to allow your procedures to come up on the stack backtrace (see
- FNAME directive, above), a copy of the kernel (won't be loaded if you
- include C:o.stubs) and stack overflow handlers. For C users, there is a
- module called "fsutils" to provide utilities interfacing filing systems (also
- "h.fsutils": to include this, add "ARM:" to your include path, i.e. use
- parameter "-IC:,ARM:", or copy h.fsutils to your CLib directory).
-
- The library should be referred to as "ARM:o.ARMlib", and treated rather like
- C:o.stubs is within makefiles.
-
- The overflow handlers are called ARM$stack_overflow and
- ARM$stack_overflow_big: they act just like C's x$stack_overflow and
- x$stack_overflow_1, including the method of splitting stack frames; but using
- the ARM$... functions will ensure that the RTSK$$Data area for ARM areas is
- loaded.
-
- Endian-ness
- ===========
-
- ARM code is ordered as little-endian four-byte words; that is, groups
- ("words") of four bytes, least significant byte first. You can tell ARMmaker
- to write these words most-significant byte first ("big-endian" words) by
- adding "-fb" to the command line. This also affects the behaviour of the DCD
- and DCW directives, but not DCF.
-
- Summary list of directives
- ==========================
-
- OUTPUT <output> [<filetype>] Set output type to <params>, actual
- filetype to <filetype>
- BASE <number> Set output base (for DIRECT files only)
- ENTRY <label> Set entry point (DIRECT or AOF files)
- INCLUDE <filename> Include another source file
- <id> BINDREG <register> Allow <id> to be used to mean <register>
- AREA <areaname>[':'<attributes>] Define a new area
- IMPORT <label> Import a symbol
- EXPORT <label> Export a symbol (a label)
- XREF <label> Synonym for IMPORT
- XDEF <label> Synonym for EXPORT
- DCB <byte-val>[ <byte-val>]* Write byte values into output
- DCW <short-val>[ <short-val>]* Write short values into output
- DCD <word-val>[ <word-val>]* Write word values into output
- DCS <string> Write a string into output
- ALIGN [<alignment>] Align to a given alignment
- DCFD <double> Write a double-precision FP into output
- DCFS <float> Write a single-precision FP into output
- BLOCK <size>[,<byte-val>] Write an intialised block
- FNAME <string> Write a function name
- CONST <number> Define an internal constant
- GLOBAL <number> Define a global constant
- OFFSET <number> Move to an offset within an area
-
- And finally....
- ===============
-
- "ARMmaker" refers to the ARMmaker executable, the !ARMmaker application and
- contents, and this documentation.
-
- "You" refers to the user of ARMmaker.
-
- "I" refers to the copyright holder.
-
- ARMmaker is and remains copyright (C) Steven Haslam 1994.
-
- You may copy and distribute ARMmaker, so long as you do not do so for a
- profit.
-
- No charge is made by the copyright holder for the use of ARMmaker, nor may
- any third party make a charge for the use of ARMmaker.
-
- No warranty, express or implied, is supplied with this product, including,
- but not limited to, warranty of merchantability or suitability for a
- particular purpose. Use is entirely at your own risk, I cannot be held
- responsible for loss or damage due to the action or inaction of ARMmaker.
-
- .
-
- Right, boring stuff over. Wake up.
-
- ARMmaker is a "FreeWare" product. Your support and encouragement is welcome.
- The program isn't finished yet, so undoubtedly you'll find loads of things
- that will go wrong, or not work at all!
-
- If you do, or if you get stuck using ARMmaker, then please don't hesitate to
- write me at this address:
- Steven Haslam, 112 Keighley Road, Colne, Lancashire, BB8 0PH, ENGLAND
- Or, if you can take it, phone me on Colne (0282)-866835 (good luck).
-
- Known things that need doing:
-
- o DCFE, DCFP (?)
-
- o Improve syntax checking
-
- o Labels local to a macro
-
- o Tidy up include file paths & "work directory"
-
- o Allow binding coprocessor names? (from CP1 to FPU, CP15 to ARM3 etc.)
- e.g. MCR ARM3, 0, a1, ARM3ID, C0
-
- Questions:
-
- When I do a PCRelative coprocessor data transfer (ST[CF]/LD[CF), e.g. "LDF
- F0, mydata", the Debugger appears to get the address wrong... but I'm sure
- the offset's right! Even assembling instructions directly in the form "STFE
- F0,[PC,#12]" appears to give the "wrong" address (try it!). AFAICT, the
- Debugger does not multiply the offset by 4 to get words (I don't think it
- pays attention to the sign either). So now you know!
-
- Why does the debugger report a precision code on WFS/RFS/WFC/RFC? And why
- does it give the parameters to FLT the wrong way round? ("All this, and more,
- in your next <Acorn bollocking...>") (<thinks> probably because these are
- just fancy names for MRC CP1,x,Rn,Cn,... and MCR CP1,x,Rn,Cn,...)
-
- ARMmaker version 0.52
- Documentation: Aug 08 1994 22:13:23
-
- Revision history:
-
- 0.50 first version
- 0.50.1 Macro expansion on same line as label: label is now defined
- CMP .... now assembled as CMPS ...., CMPP still only CMPP.
- 0.52 Erk! "^" on LDM/STM didn't work
- Added OFFSET directive
- Fixed trying to match single quotes inside literal strings
- TEQP etc. now assembled as TEQPS (like BASIC)
-