; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; OSS Message file handling code, created for Internationalisation. ; I can't use the workspace in Sprite Extend as R12 does not always point at ; the workspace. ; ; ; Amusing rant censored by Big Brother at ROOL - sorry folks! ; ; ; ; The problem with all this is that "Sprite doesn't exist" is a very ; heavily used error. The Wimp uses it when searching through its different ; sprite pools (RAM and ROM). The Filer uses it when displaying small ; icons. In fact, it is so heavily used that it needs to be as fast as ; possible, so it is cached. All the other errors are real genuine errors ; and there is no problem with them being a bit slow. ; OSS Free the cached "Sprite doesn't exist" error block. ; MUST preserve R0 and the V flag. free_sprite_doesnt_exist_error EntryS "r0-r2" LDR r2, sprite_doesnt_exist_error TEQ r2, #0 ; Check if it needs freeing EXITS EQ ; Doesn't need freeing MOV r0, #ModHandReason_Free SWI XOS_Module ; Free it MOV r2, #0 STR r2, sprite_doesnt_exist_error ; Ensure not freed again EXITS ; Ignore errors ; OSS Cache (or re-cache) the "Sprite doesn't exist" error block cache_sprite_doesnt_exist_error Entry "r0-r7" BL free_sprite_doesnt_exist_error ; Free it if already cached BLVC open_message_file_stack ; Open file on stack STRVS r0, [sp] EXIT VS ; We got an error ; From here on remember to unwind stack (ie. call close) on error MOV r0, sp ; Pointer to file handle ADR r1, ErrorBlock_DoesntExist+4 ; Pointer to token MOV r2, #0 ; No buffer - direct pointer MOV r4, #0 ; No %0 (should be Title) MOV r5, #0 ; No %1 MOV r6, #0 ; No %2 MOV r7, #0 ; No %3 SWI XMessageTrans_Lookup BVS error_while_file_open ; R3 is now length not including termination. Need to add 1 for terminator, ; another 4 for the error number, subtract 2 for the %0, and add the length ; of the module title which will go in place of the %0. 1+4-2+title = ; 3+length of module title. ADD r3, r3, #(3+EndTitle-Title) MOV r0, #ModHandReason_Claim SWI XOS_Module BVS error_while_file_open STR r2, sprite_doesnt_exist_error ; Save pointer to block LDR r0, ErrorBlock_DoesntExist ; Get error number STR r0, [r2] ; Put number in new block ADD r2, r2, #4 ; Skip past error number SUB r3, r3, #4 ; Reduce length for number MOV r0, sp ; Pointer to file handle ADR r1, ErrorBlock_DoesntExist+4 ; Pointer to token addr r4, Title ; %0 -> Module title SWI XMessageTrans_Lookup BVS error_while_file_open ; Implies got length wrong BL close_message_file_stack ; Close and unwind stack EXIT ; OSS Both of the functions called here preserve R0 and the V bit. error_while_file_open BL free_sprite_doesnt_exist_error ; Free block if necessary BL close_message_file_stack ; Close and unwind stack STR r0, [sp] ; Original error into stack R0 EXIT ; OSS Special error block with a long meaningful token. This is in case ; we fail to cache it so the token returned is fairly helpful. ErrorBlock_DoesntExist DCD ErrorNumber_Sprite_DoesntExist DCB "NoSprit", 0 ALIGN ; OSS Function to return a "Sprite doesn't exist" error block. In the case ; that it is not cached, there was an error earlier. We do NOT try to ; re-cache it, because we will almost certainly get the same error again. ; Instead we return a pointer to the token error block. It is important ; that this error is ALWAYS returned with the correct error number, even ; when the Messages file is missing and similar problems. Otherwise the ; Wimp does not move onto the ROM sprite pool and hence the pointer and ; half the icons on the icon bar disappear! Fortunately this is not a problem, ; as the cached error always has the correct number and the default ; error block returned in the case it isn't cached (ie. file/token not ; found) has the correct error number in too. get_sprite_doesnt_exist_error ROUT LDR r0, sprite_doesnt_exist_error ; Cached block TEQ r0, #0 ADREQ r0, ErrorBlock_DoesntExist ; Token block SETV MOV pc, lr ; OSS Translate an error block, with one substituted parameter. ; In: r0 -> Error block containing the token ; r1 -> %0 parameter to substitute ; Out: r0 -> Translated error block or another error (token no found etc.) ; All other registers preserved, V always set, other flags undefined copy_error_one Entry "r2-r7" MOV r4, r1 ; Move input %0 BL open_message_file_stack ; Open the file EXIT VS ; Return the error MOV r1, sp ; Messages file handl on stack MOV r2, #0 ; Use MessageTrans buffer MOV r5, #0 ; No %1 MOV r6, #0 ; No %2 MOV r7, #0 ; No %3 SWI XMessageTrans_ErrorLookup ; Always sets the V flag MOV r1, r4 ; Preserve input r1 BL close_message_file_stack ; Close the file EXIT message_filename [ localmessages DCB "LocalRes:Messages", 0 | DCB "Resources:$.Resources.SprExtend.Messages", 0 ] ALIGN ; Carve the message file block off the stack, open the Messages file, ; and exit with the open file block on the stack unless there was an error. ; Preserves r0 (token to be looked up) unless error. Trashes R1, R2, R6, R7. open_message_file_stack ROUT MOV r7, lr ; Save LR MOV r6, r0 ; Save token/error block SUB sp, sp, #16 ; Carve message file handle off stack MOV r0, sp ; File handle on stack ADR r1, message_filename ; Filename MOV r2, #0 ; Direct access/buffer in RMA SWI XMessageTrans_OpenFile ; Open the file ADDVS sp, sp, #16 ; Error - put stack back MOVVC r0, r6 ; Not error - restore token block MOV pc, r7 ; Return ; Close the message file block on the stack, restore the stack, and return. ; Preserves R0 (error block) and V bit. Trashes R5-R7. close_message_file_stack ROUT [ :LNOT: No32bitCode SavePSR r5 ; Save CPSR ] MOV r7, lr ; Save LR (and V bit) MOV r6, r0 ; Save translated error block MOV r0, sp ; Message file block is on stack SWI XMessageTrans_CloseFile ; Close the file (ignore error) ADD sp, sp, #16 ; Put stack back MOV r0, r6 ; Restore translated error [ No32bitCode MOVS pc, r7 ; Return and preserve V bit | RestPSR r5,,f ; Preserve V bit MOV pc, r7 ; Return ] END