📄 exa5.html
字号:
<!doctype html public "-//W3C//DTD HTML 3.2//EN"><html><head><title>Example 5: A mouse test</title><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /><meta http-equiv="content-language" content="en" /><meta name="resource-type" content="document"><meta name="copyright" content="This document copyright 2001 by Richard Murray. Use for non-profit and education purposes explicitly granted."><meta name="author" content="Richard Murray"><meta name="rating" content="general"></head><!-- /assembler/exa5.html --><!-- --><!-- (C) Copyright 2000 Richard Murray --><!-- Designed by Richard Murray --><!-- rmurray@heyrick.co.uk --><!-- --><body bgcolor="#f0f0f0" text="#000000" link="#0022dd" vlink="#002288"><table border = "0" width="100%"> <tr> <td align=center width=100> <img src="arm3.gif" width=79 height=78 align = middle> </td> <td> <h1 align="center"><font color="#800080">Example 5<br>A mouse test</font></h1> </td> <td align=center width=100> <img src="arm3.gif" width=79 height=78 align = middle> </td></table><p> <p>For this example, we are going to implement a simple program...<p><pre>10 MODE 12 20 OFF 30 MOUSE ON 40 50 REPEAT 60 MOUSE X%, Y%, Z% 70 PRINT TAB(0,0);X%, y%, Z% 80 UNTIL Z% = 7 90 MOUSE OFF 100 END</pre>But why stop there? Let's have a little fun. Include the following...<pre> 75 IF Z% = 4 OR Z% = 1 THEN PROCplot 110 : 120 DEFPROCplot 130 IF Z% = 4 THEN colour = 3 ELSE colour = 0 140 GCOL colour 150 POINT X%, Y% 160 ENDPROC</pre>Now, holding down SELECT will draw yellow dots, and ADJUST will draw black dots (a sort of primative 'erase').<p> <p>Okay, no BASIC, so you can forget about the DIMs and the OPT and the FOR NEXT loop.<br>Ready?<p> <p> <p><pre>; mousetest;; Version 0.01 8th July 2000; by Richard Murray;; Downloaded from http://www.heyrick.co.uk/assembler/;</pre>Always write a header to tell you what is going on. Some people include version changes in theheader but I prefer a seperate file. Personal choice really, if I had 2Mb of comments, the finalprogram wouldn't be affected - but I might need a pretty beefy computer to assemble it all!<p><pre>a1 RN 0a2 RN 1a3 RN 2a4 RN 3v6 RN 9sp RN 13lr RN 14pc RN 15</pre>Definitions for the registers that we shall be using.<br>a1 to a4 (R0-R3) are general purpose registers.<br>v6 (R9) is a pointer to the storage area.<br>sp, lr, and pc (R13, R14 and R15) have the expected usage.<p><pre> AREA |asmcode|, CODE, READONLY ENTRY</pre>Defines the area, and sets this as the program entry point.<br>Note that this is, in fact, an error. The code area is defined as READONLY but later on we writeto it (for the storage area and the string). However, it seems the system is pretty relaxedabout things like this - however it is useful to keep an eye out for such things. Don't juststick in a standard area definition without thinking...like I just did.<br>(I shall consider myself bollocked, then, shall I? <grin>)<p><pre> ; Store registers that must be preserved MOV sp, a2 STMFD sp!, {v6, lr}</pre>The initial value of the stack pointer is passed to the application in R1. Actually, this is theRAM limit for the application (refer to OS_GetEnv), but it works for a fully descending stacksuch as that which is used by convention on RISC OS.<br>Remember, you are 'real' assembler programmer when you move away from BASIC. You cannot justassume the the stack pointer actually points to anything.<br>This, incidently, applies for pure assembler code written in BASIC but run in a stand-alonefashion - such as the <a href="exa2.html">compressed image loader</a>.<p>By now, you should be able to follow assembler without so many descriptions, so here goes...<pre> ; Set v6 to point to variable storage ADR v6, storage ; Select MODE 12 (VDU 22, 12) SWI 256 + 22 SWI 256 + 12 ; OFF SWI &36 ; OS_RemoveCursors ; MOUSE ON MOV a1, #106 ; Set mouse state MOV a2, #1 ; 1 = on SWI &06 ; OS_Byte ; REPEATrepeat ; MOUSE x%, y%, z% SWI &1C ; OS_Mouse STMIA v6, {a1-a3} ; Store X%, Y%, Z% ; PRINT TAB(0,0); SWI 256 + 31 ; VDU 31, 0, 0 SWI 256 SWI 256 ; PRINT x%, y%, z% LDR a1, [v6, #0] ; Retrieve X% BL print_integer LDR a1, [v6, #4] ; Retrieve Y% BL print_integer LDR a1, [v6, #8] ; Retrieve Z% BL print_integer ; Something extra... LDR a1, [v6, #8] ; Retrieve Z% CMP a1, #4 ; Is it 4? [SELECT] CMPNE a1, #1 ; If not, is it 1? [ADJUST] BLEQ plot ; If either, then go to plot ; UNTIL z% = 7 (all buttons pressed) LDR a1, [v6, #8] ; Retrieve Z% CMP a1, #7 ; Is it 7? [SELECT, MENU, ADJUST] BLNE check_escape ; If not, check for Esc press BNE repeat ; If not, repeat ; MOUSE OFF MOV a1, #106 ; Set mouse state MOV a2, #0 ; 0 = off SWI &06 ; OS_Byte ; END SWI &37 ; OS_RestoreCursors LDMFD sp!, {v6, pc} SWI &11 ; OS_Exit (only, we shouldn't come to here...)</pre>Of note, in this lot, are:<ul> <li> OS_WriteC optimisations, calling OS_WriteI+ASCII. Does the same thing in only one instruction. <br> <br> <li> The button check optimisation. Is button SELECT? If not, is it ADJUST? If either, plot. So we implemented <code>IF Z% = 4 OR Z% = 1 THEN PROCplot</code> in only four instructions. <li> The '^' in the LDM instruction. This causes the PSR bits to be restored, thus the program exits with the processor in the same state that it was in when it was entered. Though, you won't often be calling programs in a processor mode other than User mode.</ul><p><pre>storage DCD 0 DCD 0 DCD 0string DCD 0 DCD 0</pre>Storage. Roughly in the middle, so it doesn't get too far for an ADR instruction to cope with.I'm not sure if <i>objasm</i> automatically does long ADRs, but it is something to be aware of asother assemblers may require an ADRL instruction instead, if they do it at all.<p>This next routine prints an integer in much the same way that BASIC does when you tell it to<code>PRINT X%</code>.<p><pre>print_integer ADR a2, string ; Get address of buffer MOV a3, #8 ; Length of buffer SWI &28 ; OS_BinaryToDecimal ; Integer has been converted to a string, a3 gives size. RSBS a4, a3, #10 ; How many spaces left? BEQ no_spaces ; print leading spaces MOV a1, #32 ; ASCII 32 = spacespaces_loop SWI &00 ; OS_WriteC SUBS a4, a4, #1 ; Print until none left BNE spaces_loopno_spaces ADR a2, string ; print_loop LDRB a1, [a2], #1 SWI &00 ; OS_WriteC SUBS a3, a3, #1 BNE print_loop MOV pc, lr</pre>This code might seem odd, why not simply OS_Write0?<br>The string conversion SWI doesn't terminate the string, it instead gives a length count. Youcould OS_WriteN with a count, or you could do the above...<p>Because we aren't in BASIC any more, we can't rely on an Escape press having any effect. While itis inefficient to check the escape state in every loop, it isn't that much faster to maintain aloop count and do it every X times round. So, in the spirit of keeping things simple...<p><pre>check_escape SWI &2C ; OS_ReadEscapeState BCS escape_code ; If Carry (Esc pressed), abort. MOV pc, lrerrblock DCD 17 = "Escape", 0 ALIGNescape_code MOV a1, #126 ; Ack. Escape condition SWI &06 ; OS_Byte SWI &37 ; OS_RestoreCursors ADR a1, errblock SWI &2B ; OS_GenerateError</pre>Our way out is through OS_GenerateError. That causes the stored entry point to be restored (thisis done by RISC OS, and used for things like when OS_Exit is called).<p>Next comes the plot routine.<pre>plot MOVEQ a2, #256 ; Set colour to be black CMP a1, #4 ; If SELECT pressed, ADDEQ a2, a2, #3 ; Set colour to be yellow. SWI 256 + 18 ; Set graphics colour SWI 256 MOV a1, a2 SWI &00 ; OS_WriteC MOV a1, #69 ; Point, absolute, foreground LDMIA v6, {a2-a3} ; Load X% and Y% for plot SWI &45 ; OS_Plot MOV pc, lr</pre>And, guess what? That's it!<pre> END</pre>To make a program:<ol> <li> Load !ObjAsm <li> Load !Link <li> Ensure the 'o' subdirectory exists. Create it if it doesn't. <li> Drag your source to ObjAsm. Switch off ThrowBack if you don't have a capable editor loaded. <li> Click on Run. <li> Drag the Data file that appears into the 'o' subdirectory. <li> Now, get that Data file and drag it to Link. <li> Click on Run. <li> Save the Absolute file that appears.</ol>This can be automated partially with an Obey file, or automated more using a MakeFile. However,this is'nt so important at this time - when you have an application with twenty odd sources invarious languages - that is when you really need a MakeFile!<p> <p><div align = right><a href="sw/mousetest.txt"><i>Download example: mousetest.txt</i></a></div><p><hr size = "3"><a href="index.html#15">Return to assembler index</a><hr size = "3"><address>Copyright © 2000 Richard Murray</address></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -