## Asm tuts

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

### Re: Asm tuts

Thanks dex. I totally agree, the only way to learn is to copy, adapt and practise! After all, how often am I likely to "invent" an algorithm?

I was dead pleased with myself when I tried using ORR to add 48 to my "digits" to get the ascii code. You learn most from just trying stuff.

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

### Re: Asm tuts

Hi, I hope you are still subscribed to this thread, DexOS!

I am reading Knuth's TAOCP and he gives an exercise to make a magic square with n = 23.

I thought I'd use an array of 16-bit numbers, but I am having problems. Here's what I have so far (I was using n=5 while I tried to get it working).

Code: Select all

``````
@ magic.s
@ print magic square, n = 5
@ based on Knuth TAOCP vol. 1 1.3.2 ex 21

.section	.bss
.comm   array 50	@ reserve space for the array

.section	.data
.align 2
n:
.long   5
spc:			@ a space
.byte   0x20

nl: 			@ a newline
.byte   0xA

limit:			@ length of array last square
.long 25

.section .text
.globl	_start
_start:
m1:                     @ initialise array
ldr r0, =array      @ r0 holds address of array
ldr r2, =limit
ldr r1, [r2]     	@ r1 holds number of elements

m2:                     @ initialisation loop
strh r2, [r0], #2	@ store a half-word
sub r1, r1, \$1
cmp r1, \$0
bgt m2

m6:
ldr r5, =limit
ldr r4, [r5]      	@ length of array
mov r5, \$0          @ how many numbers printed in current row
ldr r7, =n
ldr r6, [r7]        @ length of line
ldr r8, =array
ldrh r3, [r8]	@ load first value

m7:
bl print_num        @ function call
ldrh r3, [r8]       @ load next number
subs r4, \$1		@ take one from counter
beq exit		@ if done, exit
cmp r5, r6		@ are we at the end of a row?
moveq r5, \$0        @ reset counter
beq m9		@ print a newline

m8:
mov r0, \$1
ldr r1, =spc	@ print space
mov r2, \$1
mov r7, \$4
svc \$0
bal m7

m9:
mov r0, \$1
ldr r1, =nl
mov r2, \$1
mov r7, \$4
svc \$0
bal m7		@ continue printing

@@@@@@@@@@@@@@@@@@@@@@
@ print_num function @
@@@@@@@@@@@@@@@@@@@@@@

print_num:
stmfd sp!, {r0-r9, lr}	@ push regs to stack
mov r4, \$0 		@ set division counter to zero
mov r5, \$0		@ set char counter to zero

loop:				@ division routine
cmp r3, \$10
blt stackPush		@ if r3 < 10, call stackPush
sub r3, r3, \$10		@ else, subtract 10 from r3
bal loop		@ repeat

stackPush:
add r5, r5, \$1		@ increment char counter
orr r0, r3, \$0x30	@ logical OR - add 48 to digit to get ascii code
stmfd	sp!, {r0}	@ push onto stack
cmp r4, \$0		@ if the div. counter is zero ...
beq printChars		@ branch to print
mov r3, r4		@ else, load div. count into r3
mov r4, \$0		@ reset div. counter

printChars:
mov r1, sp		@ use stack pointer to provide ascii code

mov r0, \$1		@ stdout is file descriptor 1
mov r2, \$1		@ length to print is 1
mov r7, \$4		@ write syscall
svc \$0			@ wake kernel

subs r5, r5, \$1		@ decrement string counter and set flag
blt return		@ return if done
ldmfd sp!, {r0}		@ pull next char from from stack
bal printChars		@ get next char
return:
ldmfd sp!, {r0-r9, pc}	@ restore registers

exit:
mov r0, \$1			@ print a newline
ldr r1, =nl
mov r2, \$1
mov r7, \$4
svc \$0
mov r7, \$1			@ exit
svc \$0

.end
``````
The main problem so far is that when it prints the array, I get a strange character after the first number in the first row. I'm guessing there's a bug in my printNum function, but I can't work out what it is.

Also I tried changing the initialisation of the array so that it put the numbers from 25 down to 1 in the cells instead - as an experiment - and it didn't work.

mark

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

### Re: Asm tuts

I've realised one problem - I wasn't updating the address from which I loaded my numbers. Here's what the output looks like:

Code: Select all

``````[root@alarmpi asm]# ld -o magic magic.o
[root@alarmpi asm]# ./magic
25Ò24 23 22 21
20 19 18 17 16
15 14 13 12 11
10 9 8 7 6
5 4 3 2 1
[root@alarmpi asm]#
``````

I haven't written the "magic" bit yet, obviously. And I will also look into spacing the numbers more neatly. At the moment, I am just upset about that 'Ò'.
mark

rufus
Posts: 3
Joined: Sat Mar 31, 2012 12:58 am

### Re: Asm tuts

Hi DexOS,
I have been running Tut1-3 in accordance with your instructions but have only produced so far, a blank screen with flashing lines along the bottom. Could you offer any suggestions as to where I go next, please?

DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

### Re: Asm tuts

@antiloquax, Glad you fixed it ,

@rufus, can you give me a little more info so i can try see where the problem could be.

First what ver of fasmarm are you using ?
Do the files assemble OK ?
What ver of linux are you using on your PI
Also you are running the assembled file like this ./fileName <enter> ?

Note: some of those demos will need to be run as root.

I can post pre assembled ver for you to test if it helps ?
Batteries not included, Some assembly required.

rufus
Posts: 3
Joined: Sat Mar 31, 2012 12:58 am

### Re: Asm tuts

Hi DexOS,
First your queries: fasmarm v. 1.69.39. The files appear to be assembling correctly. Linux ver. raspian wheezy. Your last question as to whether I am running using ./filename puzzles me. I have read your instructions to mean the four boot directory files are alone on the disk. Your question implies that raspian wheezy is also on the disk and running. With this in mind, I attempted to add the boot directory files on to a raspian formatted disk and run it. This involved replacing the namesakes already part of raspian but the result failed anyway. Other attempts to repeat the whole process also failed.
Would you clarify whether the disk should contain only the four boot files or whether they should be added to a working raspian disk. A preassembled version would be of interest but I would also like to sort out my errors. Thanks for your continued interest.

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

sej7278 wrote:
jamesh wrote:
sej7278 wrote:
that's for riscos so won't do you much good.
Why not? The underlying assembly language is exactly the same between RISCOS and Linux (and anything else on the Raspi) so all the principles apply. And it's so easy to move to and from OS's on the Raspi..
its the os-specific bits that will be the problem though - you'd have to convert SWI calls to their linux equivalents, which for graphics/sound would be a nightmare;
Actually this is why we modularize our code using multiple files for different things in a project, and using Macros. The nightmare is non existent for good assembly.

Yes there are different APIs and ABIs between the OSes, and yes there would be a bit to learn differently.

And yes if you want to learn ARM Assembly for Linux first, you should begin with a book targetted at ARM Linux.

Though most of the basics will carry acrossed for regardless of the OS as it is ARM assembly.
floating point would be interesting as essentially its not there on riscos. riscos is 26-bit armv3 or earlier not 64-bit armv6 so you're limiting register usage and missing a lot of useful instructions and addresses would be different.
RISC OS is running on an ARMv6 on the RPi. The ARMv6 has floating point and VFP thus you can use them in RISC OS. And the ARMv6 can not even run 26-bit only code that relies on the status bits in R15, same for RISC OS 5.x.

Further almost every still maintained assembler for RISC OS supports Floating point and VFP mnemonics and outputs the correct opcodes. And that includes the BBC BASIC V assembler in RISC OS 5.21 .

ALSO: The ARMv6 is a 32-bit processor. I have no idea where you get this 64-bit idea from. The as yet not produced ARMv8 will be the first 64-bit ARM, and that is not in the RPi.
with riscos you generally run assembler from the basic interpreter rather than building it with gcc/binutils so where would you learn that?
Most assembly on RISC OS is done using a proper assembler, like ExtASM, ObjASM, AsASM, ASM, etc.

It is true that when first learning assembly on RISC OS it is common to use the BBC BASIC V assembler. This is because it is included in RISC OS and thus easily available with out having to install anything extra. And if some one is just learning Assembly they probably do not want to track down some assembler and install it.

And there is still a (different) build process involved with the BBC BASIC V Assembler, in that you must tell basic to write your assembled code to disk with the correct file type and header. Ok the header is usualy done in the assembly listing part in BBC BASIC V assembly.

So you feel that binutils gas is the only linux assembler?

I feel that gas is the worste Linux assembler. Though that is a personal opinion.
i'd love to see a single program (even hello world!) that could run on linux and riscos without modification.
Not possible with out reassmbling. Though the same is true of a C program on any two different OSes.

As for source compatability, can we use Macros? And conditional assembly? If yes that is easy with 99% of the assembled code identicle.
a linux assembler book would be better for learning linux assembler, even an android assembler book would be better than riscos.
And the above mentioned book, is for RISC OS. Though the author did a version of the same book for Linux, so problem solved.
don't get me wrong, i learnt arm assembler on riscos, but today its just a pointless place to start.
I learned ARM assembler on Arthur OS. I have not yet learnt anything have learned much. I make spelling errors all of the time. THough a wrong word in this context is worth pointing out in case of a typo.

To each his own opinion. All of the concepts carry over. Just because the API changes for a different OS does not mean that it is unusable.

========================================================================
It is also true that assembly written for ARM Linux may not run on two versions of ARM Linux with out modification (SWI 0x900000+n versus SWI 0 with R0=n).
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

DexOS wrote:
antiloquax wrote:And thank you to dexOS for your words of encouragement. Is it okay with you if I post up versions of your examples (once I've got to grips with them and got them working with GAS)?
mark
Sure that will be fine .

I have just done my first RiscOS hello world using FasmArm, which was not simple as it does not output the right file format, but luckly i found a example of the smallest header needed on the net and converted it to fasmarm.
In case it helps others:

Code: Select all

``````format binary as ''

OS_Write0 = 0x02    ; Define the two system calls
OS_Exit   = 0x11    ; used in this code
;
org 0x8000          ; org (may not be needed ?
use32               ; use 32bit
mov r0,r0           ; Decompression code call
mov r0,r0           ; Self-relocation code call
mov r0,r0           ; Zero initialisation code call
bl  start           ; Program entry call
swi OS_Exit         ; Fall-out trap to force exit
dw  0x20            ; Read-write area size (code)
dw  0               ; Debug area size
dw  0               ; Zero initialisation size
dw  0               ; Debug type
dw  0x8000          ; Current base of absolute
dw  0               ; Workspace required
dw  32              ; Flag software as 32 bit PCR okay
dw  0               ; Reserved header (should be zero)
dw  0               ; Reserved header (should be zero)
message:
db "Hello World! :-)",0xa ,0
align 4
start:
adr r0,message      ; Pointer to message
swi OS_Write0       ; OS call writes until null byte
mov r0,0            ; Define return code
swi OS_Exit         ; And exit.
``````
You may like to know that you can get away with no header at all. While this is not recomended it works for teaching Assembly with out having to worry about the Header for a while.

Just make sure that the origin is 0x8000, output a raw binary, make sure that the file begins at the origin, save it with a filetpe of absolute (Hex FF8) and you should be good to go.

The method that I mention here is technicaly Depricated, though it still works. I would only recomend this for learning ARM assembly.

Later it can be taught to always use the AIF file format.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

@Dex OS:
I would like to do a few things with your example code. Is it ok if I do the following?
• 1. I could convert these to assemble with ExtAsm if that would be ok. At least that way they could be assembled on the RPi for people with out a x86 computer (I have ran accrossed a few for whom there RPi is there only computer), even though it would mean using RISC OS to assemble Linux programs.

2.Also now that I have found some references to Linux system calls on the ARM (Finaly): Would you mind if I were to redo these to show the use of the SWI 0x900000+n/SWI &900000[1] method of calling the OS as used by some Linux Kernels? I would include versions that use the SWI 0 with R0 = n versions so that no matter which kernel it would teach the use of Linux system calls.

3. Since AsAsm can be compiled and run on ARM Linux, I could convert the examples to AsAsm form if that would be more acceptable (though I do not use that one much, I believe that it supports macros [going to have to double check]). Would this be acceptable?

[1] Depending on the syntax of the assembler. Some use the C styled 0x prefix for Hexadecimal, while others use the more traditional & prefix for Hexadecimal. Of cource some assemblers support either notation for Hexadecimal numbers.
This is like the use of the C style prefix 0x for hexadecimal on some x86 assemblers versus the use of the more traditional h postfix for hexadecimal in x86 assemblers.

==================================================================================

@DexOS:

Thank you for this thread. I think in the future I will refer those that use Linux to this thread when ever the issue of ARM Assembly comes up. You are a good instructor in this area.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

### Re: Asm tuts

@DavidS, Thanks for the info on that, its possible to run files on RiscOS without headers on them (if you need a quick test).

Your more than welcome to convert the above demo's as you see fit, the more asm examples with different assemblers the better.
I think if you can convert the server demo to RiscOS that would be useful.

I did a lot more asm demo's for RPI linux, but lost most of them when my hard drive died (should have backed up ).
I even got a cut down ver of linux to boot in less then 3 seconds into a DexOS gui.
Using the linux FB.
Here's the gui http://www.dex-os.com/MiniDos/fb.zip
I also have the code somewhere.
But if anyone tests it under linux, make sure you do it from the command line, NOT in a terminal under X, because this is working lower than X and as such any movement of the mouse will draw funny pattens on the screen etc.
Batteries not included, Some assembly required.

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

DexOS wrote: Your more than welcome to convert the above demo's as you see fit, the more asm examples with different assemblers the better.
I think if you can convert the server demo to RiscOS that would be usef
Thank you. Had been a bit bussy. Though after the USB stick crash last night I will be spending a few days doing little things.

As such this morning I am looking at your code. I intend to port all of your examples over to RISC OS, including most of the DexBASIC Macros. I will do so using ExtASM, ASM and a simple convertion for AsAsm (ObjASM syntax). The initial port in each case will be done using ASM.

ASM is my faverate (though unfortunately not all that up to date),, The archive opens with SparkFS:
http://tigger.orpheusweb.co.uk/programs/misc.html

For ExtASM:

And AsAsm:

The linker that I use is DrLink and is available as part of GCC 3.4.6 for RISC OS. This used to be available as a seperate download and not associated with GCC, though I can no longer find it seperately. I am thinking about putting togather a package including AsAsm, and DrLink along with there source (to honer the GPL) and posthing on my web site.

GCC 3.4.6 for RISC OS:

========================================================================

As I complete each conversion I will post it here.

I think that it will be fun converting the DexBASIC Stuff that is intended to be for bare metel over to run under RISC OS .

I also think that I will learn a bit more by studdying your coding style.

I just hope that this will help some more people that are just getting started with ARM Assembly.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

ertresvag
Posts: 39
Joined: Sun Oct 27, 2013 1:04 pm

### Re: Asm tuts

malakai wrote:I would love to see some. I still have this book on my things to get list http://www.amazon.com/Raspberry-Pi-Asse ... 148112790X I think maybe some easy games or anything could be helpful.
This link points to the Blue book from Bruce Smith, that book is for RISC OS. The Green book from Bruce Smith is for Raspian. I can recommend the book for Raspian.

DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

### Re: Asm tuts

DavidS wrote:
DexOS wrote: Your more than welcome to convert the above demo's as you see fit, the more asm examples with different assemblers the better.
I think if you can convert the server demo to RiscOS that would be usef
Thank you. Had been a bit bussy. Though after the USB stick crash last night I will be spending a few days doing little things.

As such this morning I am looking at your code. I intend to port all of your examples over to RISC OS, including most of the DexBASIC Macros. I will do so using ExtASM, ASM and a simple convertion for AsAsm (ObjASM syntax). The initial port in each case will be done using ASM.

ASM is my faverate (though unfortunately not all that up to date),, The archive opens with SparkFS:
http://tigger.orpheusweb.co.uk/programs/misc.html

For ExtASM:

And AsAsm:

The linker that I use is DrLink and is available as part of GCC 3.4.6 for RISC OS. This used to be available as a seperate download and not associated with GCC, though I can no longer find it seperately. I am thinking about putting togather a package including AsAsm, and DrLink along with there source (to honer the GPL) and posthing on my web site.

GCC 3.4.6 for RISC OS:

========================================================================

As I complete each conversion I will post it here.

I think that it will be fun converting the DexBASIC Stuff that is intended to be for bare metel over to run under RISC OS .

I also think that I will learn a bit more by studdying your coding style.

I just hope that this will help some more people that are just getting started with ARM Assembly.
Cool and thanks for the links, i have been using fasmarm and swap between a x86 linux PC and riscos, i do not mind too much as i love how fasmarm works, also i am working on porting fasmarm to riscos so it should not be for so long.
But i think it only fair to test some of the other assemblers for riscos, you never know i may decide to use one instead.

I must say, i am really enjoying programming on riscos, its like what linux is for C programmer, but riscos is for assembly programmers.
I think it need more things to help new programmers, like the stuff you posted about above.
At the moment i am just learning and testing how things are done from a programming point of view in riscos.
One of my ideas for a project is to make it easier to for coders to make gui apps, in single tasking mode.
They are just too complicated, it should be possible to make a 4 line assembly gui app, with the right includes.

I am going to set up a web site and forum just for info about assembly programming in riscos, i hope you will add your work.
And maybe if we come up with a big project, we can work on it together.

PS: Is there any way in riscos CLI to auto type what you have already typed in the CLI ?, like you can in windows cmd with right arrow key or up arrow key in linux, if not i will have to find away to add that.
Batteries not included, Some assembly required.

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

DexOS wrote: Cool and thanks for the links, i have been using fasmarm and swap between a x86 linux PC and riscos, i do not mind too much as i love how fasmarm works, also i am working on porting fasmarm to riscos so it should not be for so long.
But i think it only fair to test some of the other assemblers for riscos, you never know i may decide to use one instead.
I think that you will find them quite capable. There are of cource some differences.
I must say, i am really enjoying programming on riscos, its like what linux is for C programmer, but riscos is for assembly programmers.
I think it need more things to help new programmers, like the stuff you posted about above.
At the moment i am just learning and testing how things are done from a programming point of view in riscos.
One of my ideas for a project is to make it easier to for coders to make gui apps, in single tasking mode.
They are just too complicated, it should be possible to make a 4 line assembly gui app, with the right includes.
I think that each Assembly programmer has his own includes for the WIMP. And yes it can be done in 3 to four lines of code (a simple WIMP program) so long as the Data structures are defined.

In RISC OS the GUI system is refered to as the WIMP.
I am going to set up a web site and forum just for info about assembly programming in riscos, i hope you will add your work.
And maybe if we come up with a big project, we can work on it together.
The site sounds cool. I will definitely try to contribute something.
PS: Is there any way in riscos CLI to auto type what you have already typed in the CLI ?, like you can in windows cmd with right arrow key or up arrow key in linux, if not i will have to find away to add that.
Not directly though through a temp file:

Code: Select all

``````*MyCommand1 My Parameters { > TempFile }
*MyCommand2 My Parameters { < TempFile }
``````
That is good if you are doing it for a Obey File (RISC OS script).

There whas a redirector that did pseudo pipes for redirecting the output of one command to the input of another command. This is a module that I can not remember the name of at this time.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

Ok here is the hello world aplication converted.

I also included a zip containing the application Directory as an example of how to set it up to work with ASM.

Code: Select all

``````;A simple Hello World styled application.  Displays some text and exits.
;This code is based on the Linux Hello world from DexOS.
AREA main, CODE
ENTRY start

start:
SWI "OS_PrettyPrint" ;Call OS_PrettyPrint, to display our text.

MOV R0,#0            ;No error block.
SWI "OS_Exit"        ;Call OS_Exit to Exit to the system.

MyHello:
DCS "Hello from AsAsm, on the Raspberry Pi." ;Our text.
DCB &0D              ;Include a Caradge Return charactor.
DCB 0                ;Indicates the end of the text.
ALIGN                ;We have to keep things alligned.

END
``````
I included a !Help in the included directory to give instructions for assembling, and linking. The instructions do require that you have drlink and it is in a directory in your path. I also made the assumption that the user knows the basics of using star commands in RISC OS.

Here is that !Help file:

Code: Select all

``````This is a simple Hello World application.  It does nothing other than to display some text.

To assemble open the application directory, open the A directory, and drag the File 'Hello' onto the ASM IconBar Icon, select ARMv5E and choose RUN.

Then you must link, to do so:
At the * prompt change to the application directory and enter:

Then you can run the application by double clicking on the application directory.
``````
NOTE: The listed ARM 6 and ARM 7 are not the same as ARMv6/7; ther refer to much older ARM CPUs, the ARM610 through ARM7500. These predate the ARMv5.

The atached Zip file must be opened in RISC OS. Do not attempt to extract in a different OS. You must extract the files (coppy them out of the Zip) before you make any changes.
Attachments
HelloSample.zip
Hello World for RISC OS.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

Here is a simple input sample application. This shows how to get user input in the form of a string, and display the resaulting string.

In this one I changed things a little. Now it uses the standard !RunImage as the executable image, this is the standard/Correct way of doing it on RISC OS.

This is a single tasking application, while running everything else will pause running.

Here is the source (in A.InputTest)

Code: Select all

``````;A simple Example of getting user input in text mode.  Thsi is not very effecient.
AREA main, CODE
ENTRY start

start:
SWI "OS_WriteS"      ;Display the inline Text imediately after this.
DCS "Enter some text followed by enter:"
ALIGN

ADR R0,ABuffer       ;Point to our buffer.
MOV R1,#50           ;Give a buffer size of 50 bytes.
MOV R2,#32           ;Allow characters in the range of 32 [space] through
MOV R3,#126          ; the top of standard ASCII characters.

SWI "OS_NewLine"     ;Skip a line.
ADR R0,ABuffer       ;Point at our new string.
SWI "OS_PrettyPrint" ;Display our new string.

MOV R0,#0            ;No error block.
SWI "OS_Exit"        ;Call OS_Exit to Exit to the system.

ABuffer:    ; The easy we are just using an string of spaces for the buffer.
DCS "                                                                     "
DCB &0D  ;We need a CR.
DCB 0    ;Terminate the sting for Pretty Print.
``````
And here is the !Help:

Code: Select all

``````This is a simple Input String sample application.

To assemble open the application directory, open the A directory, and drag the File 'InputTest' onto the ASM IconBar Icon, select ARMv5E and choose RUN.

Then you must link, to do so:
At the * prompt change to the application directory and enter:

Then you can run the application by double clicking on the application directory.
``````
And again you must unzip this in RISC OS, and you must copy it out of the zip before making any changes.
Attachments
InputTest.zip
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

@DexOS:

I have began to convert the DexBASIC macros, though this is a slow process. I noticed that many of them use other macros such as for push, pop,imm32. This is not a huge issue just slows things down a bit.

Not seeing a definition for the PUSH and POP macros I am just replacing the instructions with LDMFD/STMFD on R13 (R13 is the most common StackPointer used in ARM code) I do hope that this is correct.

I do like your imm32 Macro though.

Though as example on the issue of PUSH/POP:
THIS:

Code: Select all

``````macro screen _scrX, _scrY, _bpp
{
push   (r0)
push   (r1)
push   (r2)
push   (r10)
imm32  r0,_scrX
imm32  r1,_scrY
imm32  r0,_bpp
imm32  r10,SetScreenRes
ldr    r10,[r10]
blx    r10
pop    (r10)
pop    (r2)
pop    (r1)
pop    (r0)
}
``````
Gets changed to:

Code: Select all

``````  MACRO screen _scrX, _scrY, _bpp
STMFD R13!,{R0-R2,R10}
imm32 R0,_scrX
imm32 R1,_scry
imm32 R2,_bpp
imm32 R10,SetScreenRes
LDR   R10,[R10]
BLX   R10
LDMFD R13!,{R0-R2,R10}
ENDM
``````
Also what is the reason of a double use of R0 like that? Would not that just overwrite the contents just loaded? Or just a typo?

Assuming that you ment R2 in the second case I changed it to R2.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

Just took a few minutes to grab the sources to drlink. I was going to put it up here though the forum sais that the maximum file size is 64k.

RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

My web host decided to dissallow the downloading of files that are not embeded in HTML . Well it is a free Web Host so I can not complain to much. This did not used to be a problem, they changed the rules.

Does any one have somewhere for me to upload?
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

### Re: Asm tuts

DavidS wrote:@DexOS:

I have began to convert the DexBASIC macros, though this is a slow process. I noticed that many of them use other macros such as for push, pop,imm32. This is not a huge issue just slows things down a bit.

Not seeing a definition for the PUSH and POP macros I am just replacing the instructions with LDMFD/STMFD on R13 (R13 is the most common StackPointer used in ARM code) I do hope that this is correct.

I do like your imm32 Macro though.

Though as example on the issue of PUSH/POP:
THIS:

Code: Select all

``````macro screen _scrX, _scrY, _bpp
{
push   (r0)
push   (r1)
push   (r2)
push   (r10)
imm32  r0,_scrX
imm32  r1,_scrY
imm32  r0,_bpp
imm32  r10,SetScreenRes
ldr    r10,[r10]
blx    r10
pop    (r10)
pop    (r2)
pop    (r1)
pop    (r0)
}
``````
Gets changed to:

Code: Select all

``````  MACRO screen _scrX, _scrY, _bpp
STMFD R13!,{R0-R2,R10}
imm32 R0,_scrX
imm32 R1,_scry
imm32 R2,_bpp
imm32 R10,SetScreenRes
LDR   R10,[R10]
BLX   R10
LDMFD R13!,{R0-R2,R10}
ENDM
``````
Also what is the reason of a double use of R0 like that? Would not that just overwrite the contents just loaded? Or just a typo?

Assuming that you ment R2 in the second case I changed it to R2.
Glad to see that there's not much to change and most assemblers have built in macro, that coders are not a where of.
Its a typo in the include file it should be

Code: Select all

``````; -----------------------------------------------------  ;
; Screen                                                 ;
; -----------------------------------------------------  ;
; Set res of screen X Y BPP                              ;
;                                                        ;
; -----------------------------------------------------  ;
macro screen _scrX, _scrY, _bpp 			 ;
{							 ;
push   (r0)					 ;
push   (r1)					 ;
push   (r2)					 ;
push   (r10)					 ;
imm32  r0,_scrX 				 ;
imm32  r1,_scrY 				 ;
imm32  r2,_bpp					 ;
imm32  r10,SetScreenRes 			 ;
ldr    r10,[r10]				 ;
blx    r10					 ;
pop    (r10)					 ;
pop    (r2)					 ;
pop    (r1)					 ;
pop    (r0)					 ;
}							 ;
``````
I note it's still in the one on the web site i will need to fix it, note that is the only typo, so you should be good to go.
One thing about fasmArm is that its a x86 assembler with a added module to convert it to arm, so there are work a rounds.
Here's some little test program that i have coded for riscos so far.
Mouse test app

Code: Select all

``````;=========================================== ;
; basic mouse X Y Button demo, for riscos    ;
; By Craig Bamford                           ;
;=========================================== ;
format binary as ''
include 'FasmArmMacros\FasmArm.inc'
XOS_Bit    = 0x020000      ;
OS_Memory  = 0x68          ;
OS_ReadC   = 0x04          ; The purpose of this call is to read a character from the input stream.
OS_Write0  = 0x02          ; Define the two system calls
OS_WriteC  = 0x00          ;
OS_WriteI  = 0x100         ;
OS_Byte    = 0x06          ;
OS_Exit    = 0x11          ; used in this code
OS_Mouse   = 0x1c          ; The purpose of this call is to return the current mouse status.
OS_ReadEscapeState = 0x2c  ; The purpose of this call is to check whether an escape condition has occurred
OS_BinaryToDecimal = 0x28  ; The purpose of this call is to convert a 32-bit integer to a string.
OS_ConvertInteger4 = 0xdc  ;
OS_ConvertInteger2 = 0xda  ;
OS_ConvertHex8  = 0xd4     ;
OS_NewLine      = 0x03     ;
Ysize           = 768-1    ; temp
;========================= ;
;========================= ;
org 0x8000                 ; org (may not be needed ?
use32                      ; use 32bit
mov   r0,r0                ; Decompression code call
mov   r0,r0                ; Self-relocation code call
mov   r0,r0                ; Zero initialisation code call
bl    start                ; Program entry call
swi   OS_Exit              ; Fall-out trap to force exit
dw    StackBuffer-start    ; 0x200                ; Read-write area size (code)
dw    0                    ; Debug area size
dw    0                    ; Zero initialisation size
dw    0                    ; Debug type
dw    0x8000               ; Current base of absolute
dw    0                    ; Workspace required
dw    32                   ; Flag software as 32 bit PCR okay
dw    0                    ; Reserved header (should be zero)
dw    0                    ; Reserved header (should be zero
message:                   ;
db "Press anykey to test mouse,then Escape to exit",0xa ,0,0,0
align 4                    ;
;========================= ;
; start                    ;
;========================= ;
start:                     ;
adr   r0,message           ; Pointer to message
swi   OS_Write0            ; OS call writes until null byte
IMM32 r13,StackBuffer      ; set stack up
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
swi   OS_NewLine           ;
mov   r0,134               ; Read text cursor position
swi   OS_Byte              ;
IMM32 r3,textXstore        ;
str   r1,[r3]              ; store text X
IMM32 r3,textYstore        ;
str   r2,[r3]              ; store text Y
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
swi   OS_ReadC             ; wait for keypress
align 4                    ;
;========================= ;
; main loop                ;
;========================= ;
loopAgain:                 ; main loop
swi   OS_Mouse             ;
mov   r5,0
mov   r0,r0,lsr 1          ; dvi X by 2
IMM32 r3,Xstore            ;
str   r0,[r3],4            ; store X
ldr   r4,[r3]              ;
cmp   r0,r4                ;
beq   tryY                 ;
str   r0,[r3]              ; store X
mov   r5,1                 ;
tryY:                      ;
mov   r1,r1, lsr 1         ; dvi Y by 2
;========================= ;
; make top left 0 0        ;
;========================= ;
IMM32 r3,Ysize             ; Note: to craig, add function to get screen Y from OS
sub   r3,r3,r1             ;
mov   r1,r3                ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IMM32 r3,Ystore            ;
str   r1,[r3],4            ; store Y
ldr   r4,[r3]              ;
cmp   r1,r4                ;
beq   tryB                 ;
str   r1,[r3]              ;
mov   r5,1                 ;
tryB:                      ;
IMM32 r3,Bstore            ;
str   r2,[r3],4            ; store button press
ldr   r4,[r3]              ;
cmp   r2,r4                ;
beq   TestChangeX          ;
str   r2,[r3]              ;
mov   r5,1                 ;
TestChangeX:               ;
cmp   r5,0                 ;
beq   NoChange             ;
bl    PrintMouse           ;
NoChange:                  ;
;========================= ;
; Test for exit            ;
;========================= ;
bcc   loopAgain            ; exit if Escape pressed
;========================= ;
; Exit                     ;
;========================= ;
mov   r0,0                 ; Define return code
swi   OS_Exit              ; And exit.
;
align 4                    ;
; -----------------------  ;
; print mouse X Y Button   ;
; -----------------------  ;
PrintMouse:                ;
stmfd sp!,{r0-r8, r12, lr} ; Store registers
SWI  OS_WriteI+31          ;
IMM32 r0,textXstore        ;
ldr   r0,[r0]              ;
swi  OS_WriteC             ;
IMM32 r0,textYstore        ;
ldr   r0,[r0]              ;
swi  OS_WriteC             ;
IMM32 r0,Xstore            ;
ldr   r0,[r0]              ;
IMM32 r1,hexstring1        ;
IMM32 r2,hexstring1end- hexstring1
swi OS_ConvertInteger2     ; The purpose of this call is to convert a value into a signed string of decimal characters.
IMM32 r0,Ystore            ;
ldr   r0,[r0]              ;
IMM32 r1,hexstring2        ;
IMM32 r2,hexstring2end- hexstring2
swi OS_ConvertInteger2     ; The purpose of this call is to convert a value into a signed string of decimal characters.
IMM32 r0,Bstore            ;
ldr   r0,[r0]              ;
IMM32 r1,hexstring3        ;
IMM32 r2,hexstring3end- hexstring3
swi   OS_BinaryToDecimal   ;  The purpose of this call is to convert a 32-bit integer to a string
swi   OS_NewLine           ;
adr   r0,hexstring1a       ; Pointer to X value
swi   OS_Write0            ; OS call writes until null byte
swi   OS_Write0            ; OS call writes until null byte
swi   OS_NewLine           ;
adr   r0,hexstring2a       ; Pointer to Y value
swi   OS_Write0            ; OS call writes until null byte
swi   OS_Write0            ; OS call writes until null byte
swi   OS_NewLine           ;
adr   r0,hexstring3a       ; Pointer to button value
swi   OS_Write0            ; OS call writes until null byte

ldmfd sp!,{r0-r8, r12, pc} ; Restore registers and return
;========================= ;
; Data                     ;
;========================= ;
align 4                    ;
abc        dw 0
textXstore dw 0            ; text x store
textYstore dw 0            ; text y store
Xstore     dw 0,0          ; store X
Ystore     dw 0,0          ; store Y
Bstore     dw 0,0          ; store Button
Clearstring db "     ",0   ;
hexstring1a db "  Mouse X = "
hexstring1 db "     ",0    ; X string
hexstring1end:             ;
align 4                    ;
hexstring2a db "  Mouse Y = "
hexstring2 db "     ",0   ;Y string
hexstring2end:             ;
align 4                    ;
hexstring3a  db "  Mouse Button = "
hexstring3 db 0,0,0,0,0,0,0,0,0 ,0  ; Button string
hexstring3end:             ;
rb   0x1000                ;
StackBuffer:  dw   0       ;``````
Assemble with fasmarm and once placed on the riscos, middle click the mouse over the file and change type to "Absolute", than double click to test.

Note: unless you covert it to assemble with another other assembler like those suggested by DavidS, you need to run fasmarm on a x86 pc.

Using GPIO under riscos without any module
(Flash OK Led)

Code: Select all

``````format binary as ''
include 'FasmArmMacros\FasmArm.inc'
OS_Memory  = 0x68          ;
OS_ReadC   = 0x04          ; The purpose of this call is to read a character from the input stream.
OS_Write0  = 0x02          ; Define the two system calls
OS_Exit    = 0x11          ; used in this code
OS_ReadEscapeState = 0x2c  ; The purpose of this call is to check whether an escape condition has occurred
;
;========================= ;
;========================= ;
org 0x8000                 ; org (may not be needed ?
use32                      ; use 32bit
mov   r0,r0                ; Decompression code call
mov   r0,r0                ; Self-relocation code call
mov   r0,r0                ; Zero initialisation code call
bl    start                ; Program entry call
swi   OS_Exit              ; Fall-out trap to force exit
dw    StackBuffer-start    ; 0x200                ; Read-write area size (code)
dw    0                    ; Debug area size
dw    0                    ; Zero initialisation size
dw    0                    ; Debug type
dw    0x8000               ; Current base of absolute
dw    0                    ; Workspace required
dw    32                   ; Flag software as 32 bit PCR okay
dw    0                    ; Reserved header (should be zero)
dw    0                    ; Reserved header (should be zero
message:                   ;
db "Press anykey to start led flashing,then Escape to exit",0xa ,0,0,0
align 4                    ;
;========================= ;
; start                    ;
;========================= ;
start:                     ;
adr   r0,message           ; Pointer to message
swi   OS_Write0            ; OS call writes until null byte
IMM32 r13,StackBuffer      ; set stack up
;========================= ;
; Map GPIO                 ;
;========================= ;
mov   r0,1                 ;
mov   r0,r0,lsl 17         ; 13
add   r0,0x0d              ; Reason Code "Map in IO temporary"
IMM32 r1,GPIO_BASE         ; Physical address to map in
IMM32 r2,4096              ;
swi   OS_Memory            ; The purpose of this call is to perform various operations for memory management.
;
IMM32 r1,GpioBase          ;
str   r3,[r1]              ; save pointer to the mapped area
;========================= ;
; Map ARM TIMER            ;
;========================= ;
mov   r0,1                 ;
mov   r0,r0,lsl 17         ; 13
add   r0,0x0d              ; Reason Code "Map in IO temporary"
IMM32 r1,ARM_TIMER_BASE    ; Physical address to map in
IMM32 r2,4096              ;
swi   OS_Memory            ; The purpose of this call is to perform various operations for memory management.
;
IMM32 r1,ArmTimerBase      ;
str   r3,[r1]              ; save pointer to the mapped area
bl    SetGPIOfunction      ; Set the GPIO function select
swi   OS_ReadC             ; wait for keypress
align 4                    ;
loopAgain:                 ; main loop
;========================= ;
; Turn led on              ;
;========================= ;
bl    SetLow               ; call turn on led function
;========================= ;
; Delay 1 second           ;
;========================= ;
IMM32 r0,1000000           ; delay one second
bl    DelayFunction        ;
;========================= ;
; Turn led off             ;
;========================= ;
bl    SetHigh              ; call turn off led function
;========================= ;
; Delay 1 second           ;
;========================= ;
IMM32 r0,1000000           ; delay one second
bl    DelayFunction        ;
;========================= ;
; Test for exit            ;
;========================= ;
bcc   loopAgain            ; exit if Escape pressed
;========================= ;
; Exit                     ;
;========================= ;
mov   r0,0                 ; Define return code
swi   OS_Exit              ; And exit.
;
align 4                    ;
GpioBase        dw  0      ; GpioBase mmap address
ArmTimerBase    dw  0      ; ArmTimerBase mmap address
;
align 4                    ;
; -----------------------  ;
; Set GPIO function select ;
; -----------------------  ;
SetGPIOfunction:           ;  Set the GPIO function select
stmfd sp!,{r0-r8, r12, lr} ; Store registers
;
ldr   r0,[GpioBase]        ; = 0x20200000
ldr   r1,[r0,GPFSEL1]      ; = 0x20200004
bic   r1,r1,0x1c0000       ;
orr   r1,r1,0x40000        ;
ldr   r0,[GpioBase]        ; = 0x20200000
str   r1,[r0,GPFSEL1]      ; = 0x20200004
;
ldmfd sp!,{r0-r8, r12, pc} ; Restore registers and return
align 4                    ;
; -----------------------  ;
; Turn off OK led          ; Set GPIO 16 to high, causing the LED to turn off.
; -----------------------  ;
SetHigh:                   ;
stmfd sp!,{r0-r8, r12, lr} ; Store registers
;
ldr   r0,[GpioBase]        ; = 0x20200000
add   r0,r0, GPSET0        ; = 0x2020001C
IMM32 r1,0x10000           ;
str   r1,[r0]              ;
ldmfd sp!,{r0-r8, r12, pc} ; Restore registers and return
; -----------------------  ;
; Turn on OK led           ; Set GPIO 16 to low, causing the LED to turn on.
; -----------------------  ;
SetLow:                    ;
stmfd sp!,{r0-r8, r12, lr} ; Store registers
;
ldr   r0,[GpioBase]        ; = 0x20200000
IMM32 r1,0x10000           ;
str   r1,[r0]              ;
;
ldmfd sp!,{r0-r8, r12, pc} ; Restore registers and return
align 4                    ;
; ------------------------ ;
; DelayFunction            ;
; ------------------------ ;
; Delay = r0               ;
; 1000000 = 1 second       ;
; ------------------------ ;
DelayFunction:             ;
stmfd sp!,{r0-r11, r12, lr}; Store registers
ldr   r1,[ArmTimerBase]    ;
IMM32 r2,TimerVar1         ;
str   r2,[r1,ARM_TIMER_CTL];
IMM32 r2,TimerVar2         ;
str   r2,[r1,ARM_TIMER_CTL];
ldr   r1,[ArmTimerBase]    ;
ldr   r2,[r1,ARM_TIMER_CNT];
align 4                    ;
DelayFunctionLoop:         ;
ldr   r3,[r1,ARM_TIMER_CNT];
cmp   r3,r2                ;
blt   DelayFunctionLoop    ;
ldmfd sp!,{r0-r11, r12, pc}; Restore registers and return
align 4                    ;
;========================= ;
; Delay = r4         temp  ;
;========================= ;
Delay:                     ;
stmfd sp!, {r0-r8, r12, lr}; Store registers
mov   r2,r4                ; mov delay to r2
Delayloop:                 ;
subs  r2,r2,1              ;
bne   Delayloop            ;
ldmfd sp!, {r0-r8, r12, pc}; Restore registers and return
;========================= ;
; Data                     ;
;========================= ;
rb   0x1000                ;
StackBuffer:  dw   0       ;
``````

The above code also users the Arm timer.

Also be careful about the comments in the code, as i re use snippets of my code in other code.
Batteries not included, Some assembly required.

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

@DexOS:
Cool.

Would you like me to convert your FasmArm code targeting RISC OS to ASM format so that you can have a better comparison?

Also AsAsm and ObjAsm have very similar formats. All of them, except ObjAsm support automatic translation of SWI names to the SWI number. Some use the quoted style like ASM, and some do so with out quotes. There are services built into RISC OS to allow for SWI Name to Number translation and this is how most of the assemblers do it.
=============================================================================
Also: I have started a thread in the RISC OS section here to teach assembly on RISC OS by example, using the ASM assember:
http://www.raspberrypi.org/phpBB3/viewt ... 55&t=59473
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

Realized that my last post was not very clear, I meant:

All of the assemblers for RISC OS have very similar syntax. Kind of like all of the Intel Syntax assemblers for the x86 have very similar Syntax. Though in this case even macros are quite similar.

Of course there are small differences between them, though these are minor.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

### Re: Asm tuts

"Would you like me to convert your FasmArm code targeting RISC OS to ASM format so that you can have a better comparison?"
Sure that would be great .
Got extasm to assemble "Vector" in the example folder, that came with it, but just got a blank screen when i ran the test app, it did exit ok with mouse press and give no errors.

Is there any arm assemblers that you use, that have open licence and have asm source, as i may try and port one to my OS, once i have add a file sys.
Batteries not included, Some assembly required.

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

DexOS wrote:"Would you like me to convert your FasmArm code targeting RISC OS to ASM format so that you can have a better comparison?"
Sure that would be great .
Ok will do.
Got extasm to assemble "Vector" in the example folder, that came with it, but just got a blank screen when i ran the test app, it did exit ok with mouse press and give no errors.
Yea the samples with ExtASM are not that great. If you do not mind the lack of ARMv6 specific instructions ASM can be much better, I may attempt to see if we can get it open sourced, so it can be updated.
Is there any arm assemblers that you use, that have open licence and have asm source, as i may try and port one to my OS, once i have add a file sys.
Unfortunately no. Most RISC OS assemblers are written in C (much as Fasm and Nasm are). The few that I am aware of that were written in assembly were written so long ago that they will not run on RISC OS 5. This is because they use the Status bits in R15 (PC) in 26-bit addressing mode. And of cource they do not support any of the newer opcodes.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

### Re: Asm tuts

Here is your Mouse Test. I am a bit dissapointed though as it causes a buffer overflow error every time ran, and I am to tired to night to figure out the source of the error.

It took about ten minutes to convert it (once I realized you are using your imm32 macro to suplant the psudo instruction ADDRL), and anothe hour to remove all of the hard spaces added by the forum. In the futrure would you please include a downloadable copy?

I had to remove the comments in order to get rid of the Hard Spaces that were causing the assembler fits.

Code: Select all

``````  AREA main, code
ENTRY start

message:
DCS "Press anykey to test mouse,then Escape to exit \x0A\x00\x00\x00"
ALIGN

Ysize = 767

;=========================   ;
; start                      ;
;=========================   ;
start:
swi "OS_Write0"

swi "OS_NewLine"
mov R0,#134
swi "OS_Byte"
str R1,[r3]
str R2,[r3]

;=========================   ;
; main loop                  ;
;=========================   ;
loopAgain:
swi "OS_Mouse"
mov r5,#0
mov r0,r0,lsr #1
str r0,[r3],#4
ldr r4,[r3]
cmp r0,r4
beq tryY
str r0,[r3]
mov r5,#1
tryY:
mov r1,r1, lsr #1
;=========================   ;
; make top left 0 0          ;
;=========================   ;
sub r3,r3,r1
mov r1,r3

str r1,[r3],#4
ldr r4,[r3]
cmp r1,r4
beq tryB
str r1,[r3]
mov r5,#1
tryB:
str r2,[r3],#4
ldr r4,[r3]
cmp r2,r4
beq TestChangeX
str r2,[r3]
mov r5,#1
TestChangeX:
cmp r5,#0
beq NoChange
bl  PrintMouse
NoChange:
;=========================   ;
; Test for exit              ;
;=========================   ;
bcc loopAgain
;=========================   ;
; Exit                       ;
;=========================   ;
mov r0,#0
swi "OS_Exit"

; -----------------------  ;
; print mouse X Y Button   ;
; -----------------------  ;
PrintMouse:
stmfd sp!,{r0-r8, r12, lr}
SWI &11F
ldr r0,[r0]
swi "OS_WriteC"
ldr r0,[r0]
swi "OS_WriteC"
ldr r0,[r0]
MOV R2,#6
swi "OS_ConvertInteger2"
ldr R0,[R0]
MOV r2,#6
swi "OS_ConvertInteger2"
ldr r0,[r0]
MOV r2,#10
swi "OS_BinaryToDecimal"
swi "OS_NewLine"
swi "OS_Write0"
swi "OS_Write0"
swi "OS_NewLine"
swi "OS_Write0"
swi "OS_Write0"
swi "OS_NewLine"
swi "OS_Write0"

ldmfd sp!,{r0-r8, r12, pc}

;========================= ;
; Data                     ;
;========================= ;
align
abc:
DCD 0
textXstore:
DCD 0
textYstore:
dcd 0
Xstore:
DCD 0
DCD 0
Ystore:
dcd 0
DCD 0
Bstore:
dcd 0
dcd 0
Clearstring:
dcs "     \x00"
hexstring1a:
dcs "  Mouse X = "
hexstring1:
dcs "     \x00"
hexstring1end:
align
hexstring2a:
dcs "  Mouse Y = "
hexstring2:
dcs "     \x00"
hexstring2end:
align
hexstring3a:
dcs "  Mouse Button = "
hexstring3:
dcs "x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
ALIGN
hexstring3end:
resb &1000
StackBuffer:
DCD 0

END

``````
And in a zip (extract only in RISC OS, copy out of the zip before modifying).
Attachments
MouseTest.zip
Mouse test by DexOS, converted by DavidS.