📄 exa7.html
字号:
<h2>Callbacks</h2>The next step is to seperate the switching off from the switching on. The way we shall dothis is to set up a callback.<p>First, change:<pre> \ Invert EOR R1, R1, #2 ; Bit 1 is Scroll Lock, invert it.</pre>to:<pre> \ Switch on Scroll Lock ORR R1, R1, #2 ; Bit 1 is Scroll Lock, set it.</pre>Now after the "<code>\ Update keyboard LEDs</code>" code, add:<pre> \ Set up timed callback to switch LED off again MOV R0, #20 ; After 20 centiseconds ADR R1, callback_handler MOV R2, #0 SWI "OS_CallAfter"</pre>Then at the bottom add:<pre> .callback_handler \ This isn't quite interrupt-level code, but getting close! STMFD R13!, {R0 - R2, R14} \ Unset the keyboard LED \ Read MOV R0, #202 MOV R1, #0 MOV R2, #255 SWI "OS_Byte" \ Switch off Scroll Lock AND R1, R1, #253 ; 253 preserves every bit EXCEPT bit 2. \ Write MOV R2, #0 SWI "OS_Byte" \ Update LEDs MOV R0, #118 SWI "OS_Byte" \ Remove callback ADR R0, callback_handler MOV R1, #0 SWI "OS_RemoveTickerEvent" \ Return LDMFD R13!, {R0 - R2, PC}</pre>Assemble and run this.<br>Something is wrong, isn't it?<p>Go to the part where the timed callback is set up, and try for a shorter delay. Drasticallyshorter, like 2cs.<p> <p><h2>To wrap up...</h2>Well, I did intend to check if a callback was pending in the vector handler, but now I don'tthink I'll bother as this module now does exactly what I want.<p>All in an hour's work! :-)<p> <p>Please be aware that this utility, logically, will add a delay to file operations. I havemeasured the delay to be something in the region of 28%. I tried some optimisations suchas:<pre> LDMFD R13!, {R0-R2, PC}^</pre>rather than:<pre> LDMFD R13!, {R0-R2, R14} MOVS PC, R14</pre>but it made a negligible difference.<br>This is really a case of deciding if the delay introduced outweighs the benefit of having ablinking HD light. For me, it does. For you? Your choice...<br><font color="red">The <code>LDMFD R13!, { ... }^</code> is not 32-bit friendly.</font><p> <p><h2>Full listing of the module</h2>This is a full listing of the source required to create this module. It includes someadditional help... <font color="red">Oh, and it isn't 32-bit friendly.</font><p>You will need to set <code><DiscAcc$Dir></code>, or simply edit the code...<p><pre>REM >SourceCodeREMREM DiscAccess module sourceREMREM Version 0.01REMREM Assembler programming example 7REM Downloaded from: http://www.heyrick.co.uk/assembler/:ON ERROR PRINT REPORT$+" at "+STR$(ERL/10) : END:DIM code% 2048:FOR pass% = 4 TO 6 STEP 2P%=0O%=code%[ OPT pass% EQUD 0 ; Start-up code EQUD initialise ; Initialisation EQUD finalise ; Finalisation EQUD 0 ; Service call handler EQUD module_title ; Module title EQUD module_help ; Module help EQUD help_table ; Help and command decoding table EQUD 0 ; SWI chunk base number EQUD 0 ; SWI handling code EQUD 0 ; SWI decoding code EQUD 0 ; SWI decoding code .module_title EQUS "DiscAccess" EQUB 0 ALIGN .module_help EQUS "DiscAccess"+CHR$(9)+"0.01 (14 Oct 2000)" EQUB 0 ALIGN .help_table EQUS "DiscAccess" ; Keyword string EQUB 0 ALIGN EQUD 0 ; Pointer to code (there is no code!) EQUD 0 ; Parameter information (no parameters) EQUD 0 ; Pointer to syntax string EQUD discaccess_help ; Pointer to help string EQUD 0 ; End of command table .discaccess_help ; Only put a linefeed where one is required, else put a trailing space. ; RISC OS will wrap the text as appropriate to fit the dimensions in use... EQUS "DiscAccess is a simple little module that blinks your Scroll Lock " EQUS "key when files are accessed."+CHR$13 EQUS "It is designed to take the place of a dedicated HD indicator on " EQUS "machines that don't have such a thing (ie, the A3000); so you " EQUS "probably won't need it on a RiscPC!"+CHR$13+CHR$13 EQUS "DiscAccess was written by Richard Murray as a tutorial for the " EQUS CHR$34+"Teach yourself ARM assembler"+CHR$34+", which is freely " EQUS "available at:"+CHR$13 EQUS CHR$160+CHR$160+"http://www.heyrick.co.uk/assembler/"+CHR$13 EQUS CHR$160+CHR$160+"(this is example seven!)"+CHR$13+CHR$13 EQUB 0 ALIGN ; The hard spaces (CHR$160) force a small indent. .initialise STMFD R13!, {R14} \ Attach vector handler to the six vectors that deal with file ops. MOV R0, #&8 ; FileV ADR R1, vector_handler MOV R2, #0 SWI "OS_AddToVector" MOV R0, #&9 ; ArgsV ADR R1, vector_handler MOV R2, #0 SWI "OS_AddToVector" MOV R0, #&A ; BGetV ADR R1, vector_handler MOV R2, #0 SWI "OS_AddToVector" MOV R0, #&B ; BPutV ADR R1, vector_handler MOV R2, #0 SWI "OS_AddToVector" MOV R0, #&C ; GBPBV ADR R1, vector_handler MOV R2, #0 SWI "OS_AddToVector" MOV R0, #&D ; FindV ADR R1, vector_handler MOV R2, #0 SWI "OS_AddToVector" LDMFD R13!, {PC} .finalise STMFD R13!, {R14} MOV R0, #&8 ; FileV ADR R1, vector_handler MOV R2, #0 SWI "OS_Release" MOV R0, #&9 ; ArgsV ADR R1, vector_handler MOV R2, #0 SWI "OS_Release" MOV R0, #&A ; BGetV ADR R1, vector_handler MOV R2, #0 SWI "OS_Release" MOV R0, #&B ; BPutV ADR R1, vector_handler MOV R2, #0 SWI "OS_Release" MOV R0, #&C ; GBPBV ADR R1, vector_handler MOV R2, #0 SWI "OS_Release" MOV R0, #&D ; FindV ADR R1, vector_handler MOV R2, #0 SWI "OS_Release" LDMFD R13!, {PC} .vector_handler \ IMPORTANT! WE ARE IN SVC MODE! STMFD R13!, {R0 - R2, R14} ; Preserve registers \ Read MOV R0, #202 ; Update keyboard status, but using EOR MOV R1, #0 ; mask 0 and AND mask 255, we can read MOV R2, #255 ; the state... SWI "OS_Byte" ; New value in R1 \ Switch on Scroll Lock ORR R1, R1, #2 ; Bit 1 is Scroll Lock, set it. \ Write MOV R2, #0 ; AND mask is 0, so EOR value is used. SWI "OS_Byte" \ Update keyboard LEDs MOV R0, #118 SWI "OS_Byte" \ Set up timed callback to switch LED off again MOV R0, #2 ; After 2 centiseconds ADR R1, callback_handler MOV R2, #0 SWI "OS_CallAfter" LDMFD R13!, {R0 - R2, R14} ; Restore registers MOVS PC, R14 ; Pass this one on .callback_handler \ This isn't quite interrupt-level code, but getting close! STMFD R13!, {R0 - R2, R14} \ Unset the keyboard LED \ Read MOV R0, #202 MOV R1, #0 MOV R2, #255 SWI "OS_Byte" \ Switch off Scroll Lock AND R1, R1, #253 ; 253 preserves every bit EXCEPT bit 2. \ Write MOV R2, #0 SWI "OS_Byte" \ Update LEDs MOV R0, #118 SWI "OS_Byte" \ Remove callback ADR R0, callback_handler MOV R1, #0 SWI "OS_RemoveTickerEvent" \ Return LDMFD R13!, {R0 - R2, PC} .stuff_at_the_end EQUB 10 EQUB 10 EQUS "DiscAccess module
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -