ô >SourceCode ô *ô DiscAccess module source [revisited] (ô 2ô Version 0.10 <ô F3ô Extended from assembler programming example 7 P:ô Downloaded from: http://www.heyrick.co.uk/assembler/ Zô d: nî … ñ ö$+" at "+Ã(ž/10) : à x: ‚Þ code% 2048 Œ: –ã pass% = 4 ¸ 6 ˆ 2  P%=0 ª O%=code% ´[ OPT pass% ¾F EQUD 0 ; Start-up code ÈG EQUD initialise ; Initialisation ÒE EQUD finalise ; Finalisation ÜM EQUD 0 ; Service call handler æE EQUD module_title ; Module title ðD EQUD module_help ; Module help úX EQUD help_table ; Help and command decoding table N EQUD 0 ; SWI chunk base number J EQUD 0 ; SWI handling code J EQUD 0 ; SWI decoding code "J EQUD 0 ; SWI decoding code , 6 @ .module_title J EQUS "DiscAccess" T EQUB 0 ^ ALIGN h r | .module_help †\ EQUS "DiscAccess"+½(9)+"0.10 (28 Feb 2002) [http://www.heyrick.co.uk/assembler/]"  EQUB 0 š ALIGN ¤ ® ¸ .help_table ÂG EQUS "DiscAccess" ; Keyword string Ì EQUB 0 Ö ALIGN à\ EQUD 0 ; Pointer to code (there is no code!) ê^ EQUD 0 ; Parameter information (no parameters) ôQ EQUD 0 ; Pointer to syntax string þO EQUD discaccess_help ; Pointer to help string M EQUD 0 ; End of command table   & .initialise 0 STR R14, [R13, #-4]! : D \ Set up the OS version N BL get_os_version XM \ Use "MOV R2, R0" instead of the BL if you don't want hacky. b lK \ Attach vector handler to the six vectors that deal with file ops. v8 \ Using OS_Claim now, instead of OS_AddToVector. € Š \ Constants... ”" ADR R1, vector_handler ž ADR R0, release_code ¨ STR R2, [R0] ² ¼> MOV R0, #&8 ; FileV Æ SWI "OS_Claim" Ð BVS release_eight Ú ä> MOV R0, #&9 ; ArgsV î SWI "OS_Claim" ø BVS release_nine   > MOV R0, #&A ; BGetV  SWI "OS_Claim"   BVS release_ten * 4> MOV R0, #&B ; BPutV > SWI "OS_Claim" H BVS release_eleven R \> MOV R0, #&C ; GBPBV f SWI "OS_Claim" p BVS release_twelve z „> MOV R0, #&D ; FindV Ž SWI "OS_Claim" ˜ BVS release_thirteen ¢ ¬ LDMFD R13!, {PC} ¶ À Ê .vector_handler Ô% \ IMPORTANT! WE ARE IN SVC ë! Þ è3 \ MAKE THIS *FAST* - NO BRANCHES (AT ALL) ã ò/ \ FASTEST VARIANT... ü K STMFD R13!, {R0 - R2, R14} ; Preserve registers  A \ Check LED state - if LED currently on, skip all this... $ MOV R0, #1 . LDR R0, led_state 8 CMP R0, #1 B# BEQ vector_handler_exit L V CMP R12, #0 `! B update_old_method j t ; Set Scroll Lock bit ~ LDRB R0, [R12, #0] ˆU „R R0, R0, #2 ; Bit 1 is Scroll Lock, set it. ’ STRB R0, [R12, #0] œ ¦& ; Force keyboard status update ° MOV R0, #118 º SWI "OS_Byte" Ä Î ; Flag LEDs are on Ø MOV R0, #1 â STR R0, led_state ì ö5 ; Exit point here, so we can lose one branch. $ LDMFD R13!, {R0 - R2, R14}  S MOVS PC, R14 ; Got to keep V and C flags.   ( .update_old_method 2 \ Read <\ MOV R0, #202 ; Update keyboard status, but using ‚ F[ MOV R1, #0 ; mask 0 and € mask 255, we can read PE MOV R2, #255 ; the state... ZH SWI "OS_Byte" ; New value in R1 d n \ Switch on Scroll Lock xU „R R1, R1, #2 ; Bit 1 is Scroll Lock, set it. ‚ Œ \ Write –Y MOV R2, #0 ; € mask is 0, so ‚ value is used.   SWI "OS_Byte" ª ´ \ Update keyboard LEDs ¾ MOV R0, #118 È SWI "OS_Byte" Ò Ü \ Flag LEDs are on æ MOV R0, #1 ð STR R0, led_state ú 7 \ Set up timed callback to switch LED off again O MOV R0, #10 ; After 10 centiseconds # ADR R1, callback_handler " MOV R2, #0 , SWI "OS_CallAfter" 6 @ .vector_handler_exit JJ LDMFD R13!, {R0 - R2, R14} ; Restore registers T^ MOVS PC, R14 ; Pass this one on (preserving V and C) ^ h r .callback_handler |$ 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 à\ € R1, R1, #253 ; 253 preserves every bit EXCEPT bit 2. ê ô \ Write þ MOV R2, #0  SWI "OS_Byte"   \ Update LEDs & MOV R0, #118 0 SWI "OS_Byte" : D \ Flag LEDs are off N MOV R0, #0 X ADR R1, led_state b STR R0, [R1] l v \ Remove callback €$ ADR R0, callback_handler Š MOV R1, #0 ”& SWI "OS_RemoveTickerEvent" ž ¨ \ Return ²# LDMFD R13!, {R0 - R2, PC} ¼ Æ Ð .finalise Ú STR R14, [R13, #-4]! ä î" ADR R1, vector_handler ø ADR R0, release_code  LDR R2, [R0]   > MOV R0, #&8 ; FileV  " ADR R1, vector_handler * SWI "OS_Release" 4 BVS frelease_failed > H> MOV R0, #&9 ; ArgsV R SWI "OS_Release" \ BVS frelease_failed f p> MOV R0, #&A ; BGetV z SWI "OS_Release" „ BVS frelease_failed Ž ˜> MOV R0, #&B ; BPutV ¢ SWI "OS_Release" ¬ BVS frelease_failed ¶ À> MOV R0, #&C ; GBPBV Ê SWI "OS_Release" Ô BVS frelease_failed Þ è> MOV R0, #&D ; FindV ò SWI "OS_Release" ü BVS frelease_failed   LDR PC, [R13], #4  $ . .get_os_version 8 STR R14, [R13, #-4]! B L MOV R0, #129 V MOV R1, #0 ` MOV R2, #255 j SWI "OS_Byte" tO MOVVS R0, #0 ; Can this OS_Byte fail? ~ ˆ CMP R0, #&A4 ’ B status_address œ CMP R0, #&A5 ¦ B status_address ° CMP R0, #&A6 º B status_address Ä CMP R0, #&A7 Î B status_address Ø CMP R0, #&A8 âN B status_address ; And RISC OS 4.00 IIRC ì öM MOV R2, #0 ; OS version not known  LDR PC, [R13], #4    .status_address (^ MOV R2, #&900 ; Keyboard status byte is &9C4, byte 0. 2 ADD R2, R2, #&C4 < LDR PC, [R13], #4 F P Z .led_state d EQUD 0 n x .release_code ‚ EQUD 0 Œ –   \ Error release ª .release_thirteen ´ MOV R0, #&C ¾ SWI "OS_Release" È BVS release_failed Ò Ü .release_twelve æ MOV R0, #&B ð SWI "OS_Release" ú BVS release_failed   .release_eleven  MOV R0, #&A " SWI "OS_Release" , BVS release_failed 6 @ .release_ten J MOV R0, #&9 T SWI "OS_Release" ^ BVS release_failed h r .release_nine | MOV R0, #&8 † SWI "OS_Release"  BVS release_failed š ¤ .release_eight ®& ADR R0, claim_fail_message ¸ LDR R14, [R13], #4  „RS PC, R14, #1<<28 Ì Ö .release_failed à( ADR R0, release_fail_message ê LDR R14, [R13], #4 ô „RS PC, R14, #1<<28 þ  .frelease_failed ) ADR R0, frelease_fail_message  LDR R14, [R13], #4 & „RS PC, R14, #1<<28 0 : D .claim_fail_message N EQUD 17 XH EQUS "Unable to claim required vectors, cannot start." + ½(0) b ALIGN l v € .release_fail_message Š EQUD 17 ”_ EQUS "Unable to claim required vectors, and unable to release those claimed. Uh-oh!" ž EQUB 0 ¨ ALIGN ² ¼ .frelease_fail_message Æ EQUD 17 Ð; EQUS "Unable to release claimed vectors. Uh-oh!" Ú EQUB 0 ä ALIGN î ø .discaccess_help O ; Only put a linefeed where one is required, else put a trailing space. Z ; RISC OS will wrap the text as appropriate to fit the screen dimensions in use... ] EQUS "DiscAccess is a simple little module that blinks your Scroll Lock key when " ) EQUS "files are accessed."+½13 *` EQUS "It is designed to take the place of a dedicated HD indicator on machines that " 4^ EQUS "don't have such a thing (ie, the A3000); so you probably won't need it on a " >! EQUS "RiscPC!"+½13+½13 H^ EQUS "DiscAccess was written by Richard Murray as a tutorial for the "+½34+"Teach " RR EQUS "yourself ARM assembler"+½34+", which is freely available at:"+½13 \C EQUS ½160+½160+"http://www.heyrick.co.uk/assembler/"+½13 fT EQUS ½160+½160+"(this is the extended version of example seven!)"+½13+½13 p EQUB 0 z ALIGN „6 ; The hard spaces (½160) force a small indent. Ž ˜ ¢ .stuff_at_the_end ¬ EQUB 10 ¶ EQUB 10 À9 EQUS "DiscAccess module © 2002 Richard Murray" Ê EQUB 10 ÔB EQUS "http://www.heyrick.co.uk/assembler/ (example 7)" Þ EQUB 10 è] ò í pass% ü: 9ÿ("Save .DiscAccess "+Ã~code%+" +"+Ã~P%) -ÿ("SetType .DiscAccess FFA") : $à ÿ