; Copyright 1999 Pace Micro Technology plc ; ; 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. ; ; Title: s.ddeutils ; Purpose: Assembler source for DDEUtils module ; Author: ; History: Used to live on Aquarius SrcFiler ; GET VersionASM ^ 0,r12 chain # 4 fname_buffer # 4 cli_buffer # 4 cli_size # 4 receiver_id # 4 workspace_end # 0 ; JRF: Debugging GBLL DEBUG ; turn this off for ROMing DEBUG SETL {FALSE} ; JRF: Don't make it work on pre-RO4 GBLL RO4Only RO4Only SETL {FALSE} ; JRF: Switch added to allow longer filenames to be 'handled'. This may ; not necessarily fix all the problems that DDEUtils has with them, ; but will alleviate the majority. Problems may still lie in the ; throwback handler. GBLL LongFilenames LongFilenames SETL {TRUE} ; JRF: Set this to the length of filenames that is the maximum you wish ; to handle [ LongFilenames FilenameLength EQU 1024 | FilenameLength EQU 256 ] ; JRF: Turn this on and all prefixes passed will be canonicalised for you GBLL CanonicalisePath CanonicalisePath SETL {TRUE} ; JRF: We should /really/ be checking the strings fit our CL buffer! GBLL CheckBufferSize CheckBufferSize SETL {TRUE} GBLL AllowDirectoryChanging AllowDirectoryChanging SETL {TRUE} ; JRF: Allow a lot of the later image file extensions ; This has NOT been tested and it's a little too late to add them GBLL HandleImages HandleImages SETL {FALSE} os_writec EQU 0 os_writes EQU 1 os_write0 EQU 2 os_newline EQU 3 xos_module EQU &2001e xos_claim EQU &2001f xos_release EQU &20020 xos_fscontrol EQU &20029 xos_file EQU &20008 xos_changeenvironment EQU &20040 xos_readsysinfo EQU &20058 xos_enteros EQU &20016 os_exit EQU &11 os_generateerror EQU &2b xwimp_readsysinfo EQU &600f2 xwimp_sendmessage EQU &600e7 xmessagetrans_errorlookup EQU &61506 xos_setvarval EQU &20024 xos_word EQU &20007 os_converthex8 EQU &d4 zp_wimpdomain EQU &ff8 n_module_claim EQU 6 n_module_free EQU 7 n_filev EQU &08 n_gbpbv EQU &0c n_findv EQU &0d n_fscontrolv EQU &0f n_error_h EQU 6 n_exit_h EQU 11 ddeutils_swibase EQU &42580 xddeutils_swibase EQU &62580 ddeutils_prefix EQU 0 ; + ddeutils_swibase ddeutils_setclsize EQU 1 ddeutils_setcl EQU 2 ddeutils_getclsize EQU 3 ddeutils_getcl EQU 4 ddeutils_throwbackregister EQU 5 ddeutils_throwbackunregister EQU 6 ddeutils_throwbackstart EQU 7 ddeutils_throwbacksend EQU 8 ddeutils_throwbackend EQU 9 ddeutils_readprefix EQU 10 reason_processing EQU 0 reason_errordetails EQU 1 reason_infodetails EQU 2 overflow EQU &10000000 carry EQU &20000000 ddeutils_errbase EQU &20600 unk_swi_error EQU ddeutils_errbase + 0 no_cli_buffer_error EQU ddeutils_errbase + 1 not_desktop_error EQU ddeutils_errbase + 2 no_task_error EQU ddeutils_errbase + 3 already_reg_error EQU ddeutils_errbase + 4 not_reg_error EQU ddeutils_errbase + 5 buffer_too_short EQU ddeutils_errbase + 6 ddeutils_msgbase EQU ddeutils_swibase ddeutils_msgbase_h EQU &42000 ddeutils_msgbase_l EQU &580 msg_throwback_start EQU 0 ; + ddeutils_msgbase msg_throwback_processingfile EQU 1 msg_throwback_errorsin EQU 2 msg_throwback_errordetails EQU 3 msg_throwback_end EQU 4 msg_throwback_infoforfile EQU 5 msg_throwback_infodetails EQU 6 service_reset EQU &27 service_wimpclosedown EQU &53 o_next EQU &00 ASSERT :INDEX: o_next = 0 o_wimpdomain EQU &04 o_prefix EQU &08 IMPORT |__RelocCode| AREA |!|, CODE, READONLY module_start EQU . DCD 0 ; Run DCD init - module_start ; Init DCD finish - module_start ; Finish DCD service - module_start ; Service call DCD title - module_start ; Title DCD help - module_start ; Help DCD cmd_table - module_start ; *commands DCD ddeutils_swibase ; SWI Base DCD do_swi - module_start ; SWI Handler DCD swi_table - module_start ; SWI Table DCD 0 ; SWI Decoder DCD 0 ; Messages filename DCD flags - module_start ; Module flags help DCB "DDEUtils", 9 DCB Module_MajorVersion, " (", Module_Date, ")", 0 [ Module_MinorVersion <> "" DCB " ", Module_MinorVersion | ] DCB 0 title ; DCB "DDEUtils", 0 swi_table DCB "DDEUtils", 0 DCB "Prefix", 0 DCB "SetCLSize", 0 DCB "SetCL", 0 DCB "GetCLSize", 0 DCB "GetCl", 0 DCB "ThrowbackRegister", 0 DCB "ThrowbackUnRegister", 0 DCB "ThrowbackStart", 0 DCB "ThrowbackSend", 0 DCB "ThrowbackEnd", 0 DCB "ReadPrefix", 0 DCB 0 cmd_table DCB "Prefix", 0 ALIGN DCD prefix_cmd - module_start DCB 0 ; Min. parameters DCB 1 ; GSTrans map DCB 1 ; Max. parameters DCB 0 ; Flags DCD prefix_syn - module_start ; Syntax message DCD prefix_help - module_start ; Help message DCD 0 ; End of command table prefix_help DCB "*Prefix selects a directory as the current directory unique to the currently executing task. *Prefix with no arguments sets the current directory back to the systemwide default (as set with *Dir).", 13 prefix_syn DCB "Syntax: *Prefix [<directory>]", 0 ALIGN flags DCD 1 ; 32-bit compatible ;Ursula format ; ASSERT service_reset < service_wimpclosedown ; UServTab DCD 0 ;flags DCD UService - module_start DCD service_reset DCD service_wimpclosedown DCD 0 ;terminator DCD UServTab - module_start ;anchor service [ RO4Only MOV r0,r0 ;magic instruction TEQNE r1,#service_reset TEQNE r1,#service_wimpclosedown MOVNE pc,lr B service | MOV r0,r0 ;magic instruction TEQ r1, #service_reset TEQNE r1, #service_wimpclosedown MOVNE pc,lr ] UService TEQ r1,#service_reset LDREQ r12,[r12] BEQ reset CMP r0, #0 MOVNE pc, lr STMFD sp!, {r0, lr} MOV r0, #0 SWI xddeutils_swibase + ddeutils_prefix LDMFD sp!, {r0, pc} ; Really should clear the chain here... reset STMFD sp!, {r0, lr} BL claimvectors LDMFD sp!, {r0, pc} filetype_fd3 DCB "File$Type_FD3", 0 debimage DCB "DebImage", 0 runtype_fd3 DCB "Alias$@RunType_FD3", 0 debugaif DCB "DebugAIF %*0", 0 loadtype_fd3 DCB "Alias$@LoadType_FD3", 0 loadaif DCB "Load %0 8000", 0 filetype_fe1 DCB "File$Type_FE1", 0 makefile DCB "Makefile", 0 runtype_fe1 DCB "Alias$@RunType_FE1", 0 make DCB "DDE:!Make %*0", 0 prefix_dir DCB "Prefix$Dir", 0 ALIGN n_vartype_code EQU 16 init STMFD sp!, {r7, r8, r9, r10, r11, lr} [ RO4Only MOV r0,#9 MOV r1,#0 SWI xos_readsysinfo MOVVS pc,#0 ] ADR r0, filetype_fd3 ADR r1, debimage BL initvar ADR r0, runtype_fd3 ADR r1, debugaif BL initvar ADR r0, loadtype_fd3 ADR r1, loadaif BL initvar ADR r0, filetype_fe1 ADR r1, makefile BL initvar ADR r0, runtype_fe1 ADR r1, make BL initvar MOV r0, #n_module_claim MOV r3, #:INDEX: workspace_end SWI xos_module ; claim our module workspace STRVC r2,[r12] MOVVC r12,r2 MOVVC r0,#0 STRVC r0, chain STRVC r0, cli_buffer STRVC r0, cli_size STRVC r0, receiver_id BLVC claimvectors ; MOVVC r2, r12 MOVVC r0, #n_module_claim MOVVC r3, #FilenameLength * 2 SWIVC xos_module STRVC r2, fname_buffer ADRVC r0, prefix_dir ADRVC r1, prefix_dir_code MOVVC r2, #prefix_dir_code_end - prefix_dir_code MOVVC r3, #0 MOVVC r4, #n_vartype_code SWIVC xos_setvarval LDMFD sp!, {r7, r8, r9, r10, r11, lr} xferv TEQ pc, pc MOVEQ pc, lr ORRVS lr, lr, #overflow MOVS pc, lr xfervc TEQ pc, pc MOVEQ pc, lr BIC lr, lr, #carry ORRCS lr, lr, #carry ORRVS lr, lr, #overflow MOVS pc, lr claimvectors STMFD sp!, {r2,r3,lr} MOV r2,r12 MOV r0, #n_filev TEQ pc, pc ADREQL r1, file_handler_32 ADRNEL r1, file_handler_26 SWI xos_claim MOVVS r3, r0 BVS %FT01 MOV r0, #n_gbpbv TEQ pc, pc ADREQL r1, gbpb_handler_32 ADRNEL r1, gbpb_handler_26 SWI xos_claim MOVVS r3, r0 BVS %FT02 MOV r0, #n_findv TEQ pc, pc ADREQL r1, find_handler_32 ADRNEL r1, find_handler_26 SWI xos_claim MOVVS r3, r0 BVS %FT03 MOV r0, #n_fscontrolv TEQ pc, pc ADREQL r1, fscontrol_handler_32 ADRNEL r1, fscontrol_handler_26 SWI xos_claim MOVVS r3, r0 BVS %FT04 LDMFD sp!, {r2,r3,pc} ; these are the failure cases 04 MOV r0, #n_findv TEQ pc, pc ADREQL r1, find_handler_32 ADRNEL r1, find_handler_26 SWI xos_release 03 MOV r0, #n_gbpbv TEQ pc, pc ADREQL r1, gbpb_handler_32 ADRNEL r1, gbpb_handler_26 SWI xos_release 02 MOV r0, #n_filev TEQ pc, pc ADREQL r1, file_handler_32 ADRNEL r1, file_handler_26 SWI xos_release 01 LDMFD sp!, {r2,r3,lr} MOV r0,r3 TEQ pc, pc ORRNES pc,lr,#overflow MSR CPSR_f, #overflow MOV pc, lr prefix_dir_code B dir_code_write ; prefix_dir read code ; <= r0-> value STMFD sp!, {lr} MOV r0,#0 SWI xddeutils_swibase + ddeutils_readprefix MOVVS r0,#0 CMP r0,#0 ; was it invalid ? MOVEQ r0,#0 MOVEQ r2,#0 LDMEQFD sp!, {pc} ; yes ; now we need to find the length of the directory MOV r1,r0 01 LDRB r2,[r1],#1 CMP r2,#31 BGT %BT01 SUB r2,r1,r0 SUB r2,r2,#1 ; and we increased over the terminator LDMFD sp!, {pc} dir_code_write STMFD sp!, {r0, lr} MOV r0, r1 SWI xddeutils_swibase + ddeutils_prefix ADDS r0, r0, #0 ; clear V LDMFD sp!, {r0, pc} prefix_dir_code_end finish MOV r6, lr LDR r12, [r12] MOV r0, #n_module_free LDR r2, fname_buffer CMP r2, #0 SWINE xos_module LDR r2, cli_buffer CMP r2, #0 SWINE xos_module LDR r2, chain MOV r1, #0 STR r1, chain STR r1, fname_buffer STR r1, cli_buffer STR r1, cli_size STR r1, receiver_id finish1 CMP r2, #0 BEQ finish2 LDR r5, [r2,#o_next] MOV r0, #n_module_free SWI xos_module MOV r2, r5 BVC finish1 finish2 MOV r2, r12 MOV r0, #n_filev TEQ pc, pc ADREQL r1, file_handler_32 ADRNEL r1, file_handler_26 SWI xos_release MOV r0, #n_gbpbv TEQ pc, pc ADREQ r1, gbpb_handler_32 ADRNE r1, gbpb_handler_26 SWI xos_release MOV r0, #n_findv TEQ pc, pc ADREQ r1, find_handler_32 ADRNE r1, find_handler_26 SWI xos_release MOV r0, #n_fscontrolv TEQ pc, pc ADREQL r1, fscontrol_handler_32 ADRNEL r1, fscontrol_handler_26 SWI xos_release MOV r2, r12 ; free our main workspace MOV r0, #n_module_free SWI xos_module MOVS pc, r6 ; Input: R0: task handle or 0 for current task ; Output: R0: pointer to prefix dir for that task or 0 if none. doswi_readprefix MOVS r11, r0, lsl #16 LDREQ r11, [r11, #zp_wimpdomain] MOVEQ r11, r11, ror #16 MOV r0, #0 STMFD sp!, {r1, r2, r3, r8, lr} LDR r8, chain doswi_readprefix1 CMP r8, #0 LDMEQFD sp!, {r1, r2, r3, r8, pc} LDR r2, [r8,#o_next] LDR r1, [r8, #o_wimpdomain] CMP r11, r1, ror #16 ADDEQ r0, r8, #o_prefix LDMEQFD sp!, {r1, r2, r3, r8, pc} MOV r8, r2 B doswi_readprefix1 do_swi STR lr,[sp,#-4]! LDR r12,[r12] ; read workspace pointer BL do_swi_orig TEQ pc, pc LDREQ pc,[sp],#4 ; 32-bit return corrupting flags LDMVCFD sp!,{pc}^ ; 26-bit return without error LDR lr,[sp],#4 ; 26-bit return with error ORRS pc,lr,#overflow do_swi_orig CMP r11,#11 ADDLT pc,pc,r11,LSL #2 B module_swierror ; ***** SWI jump table B doswi_prefix B doswi_setclsize B doswi_setcl B doswi_getclsize B doswi_getcl B doswi_throwbackregister B doswi_throwbackunregister B doswi_throwbackstart B doswi_throwbacksend B doswi_throwbackend B doswi_readprefix module_swierror STMFD sp!,{r1-r4,lr} ADR r0,msg_swierror MOV r1,#0 MOV r2,#0 ADRL r4,title SWI xmessagetrans_errorlookup LDMFD sp!,{r1-r4,pc} msg_swierror DCD &1E6 DCB "BadSWI",0 ALIGN doswi_prefix MOV r10, r0 STMFD sp!, {r1, r2, r3, r8, lr} TEQ r0,#0 BEQ %FT01 ; they gave 0 LDRB r0,[r10] CMP r0,#32 BLO %FT01 ; it was a null command [ CanonicalisePath STMFD sp!, { r4, r5 } MOV r0,#37 MOV r1,r10 LDR r2,fname_buffer MOV r3,#0 ; no path var MOV r4,#0 ; 0 MOV r5,#FilenameLength SWI xos_fscontrol ; canonicalise it! LDRVC r10,fname_buffer LDMFD sp!, { r4, r5 } 01 ] [ DEBUG STMFD sp!,{r0,r2} ; Stack registers SWI os_writes DCB 4, "attempting to set prefix: ", 0 MOV r2, r10 01 LDRB r0, [r2], #1 CMP r0, #' '+1 SWICS os_writec CMP r0, #' '+1 BCS %BT01 SWI os_newline LDMFD sp!,{r0,r2} ; Unstack registers ] ASSERT ddeutils_prefix = 0 LDR r11, [r11, #zp_wimpdomain] ADR r8, chain LDR r2, chain do_swi1 TEQ r2, #0 BEQ do_swi2 LDR r1, [r2, #o_wimpdomain] TEQ r1, r11 ADDNE r8, r2, #o_next ; r8 = last next pointer addr LDRNE r2, [r2, #o_next] ; r2 = this pointer BNE do_swi1 LDR r3, [r2, #o_next] ; read this next STR r3, [r8] ; store as last next MOV r0, #n_module_free SWI xos_module MOVVC r2,r3 BVC do_swi1 LDMFD sp!, {r1, r2, r3, r8, pc} ; V set do_swi2 ADDS r0, r10, #0 LDMEQFD sp!, {r1, r2, r3, r8, pc} ; V clear LDRB r1, [r0] CMP r1, #' ' + 1 LDMLOFD sp!, {r1, r2, r3, r8, pc} ; V clear MOV r3, #0 do_swi3 LDRB r1, [r0], #1 ADD r3, r3, #1 CMP r1, #' ' + 1 BCS do_swi3 ADD r3, r3, #o_prefix MOV r0, #n_module_claim SWI xos_module LDMVSFD sp!, {r1, r2, r3, r8, pc} ; V set STR r2, [r8] ; store over last next pointer (!) MOV r0, #0 STR r0, [r2], #4 ; next STR r11, [r2], #4 ; domain ; prefix follows MOV r0, r10 do_swi4 LDRB r1, [r10], #1 STRB r1, [r2], #1 CMP r1, #' ' + 1 MOVHS r3, r1 BHS do_swi4 CMP r3, #'.' STREQB r1, [r2, #-2] MOV r3,#0 STRB r3, [r2, #-1] ; store it as terminated LDMFD sp!, {r1, r2, r3, r8, pc} ; V clear strip_hats SUBS r0, r0, #0 ; set carry B strip_hats0 ; Entry: VC ; R1 = Filename ; R11 = Filename buffer ; R8 = Task block ; Exit: R11, LR = ??? ; R1 = Preserved ; R11 = Preserved ; R8 = New Filename (R1 or R11 on entry) ; CS => No prefix added (filename contained root char) add_prefix SUBS r0, r0, #0 ; set C add_prefix0 STMFD sp!, {r0, r1, r2, r3, r4, r5, lr} ; r5 is placeholder MRS lr, CPSR ; NOP on old machine STR lr, [sp, #20] [ DEBUG STMFD sp!, {r0-r2} SWI os_writes DCB "Before add_prefix: ", 0 MOV r2, r1 write_name0 LDRB r0, [r2], #1 CMP r0, #' '+1 SWICS os_writec CMP r0, #' '+1 BCS write_name0 SWI os_newline LDMFD sp!,{r0-r2} ] MOV r2, r1 add_prefix1 LDRB r0, [r2], #1 CMP r0, #':' CMPNE r0, #'$' CMPNE r0, #'&' CMPNE r0, #'%' CMPNE r0, #'<' MOVEQ r8, r1 BEQ add_prefix5 CMP r0, #' ' + 1 BCS add_prefix1 MOV r2, r1 LDRB r0, [r2] CMP r0, #'@' BNE add_prefix2 LDRB r0, [r2, #1]! CMP r0, #'.' ADDEQ r2, r2, #1 add_prefix2 MOV r3, r11 ADD r8, r8, #o_prefix add_prefix3 LDRB r0, [r8], #1 CMP r0, #' ' + 1 STRCSB r0, [r3], #1 BCS add_prefix3 LDRB r0, [r2] CMP r0, #' ' + 1 MOVCS r0, #'.' STRCSB r0, [r3], #1 add_prefix4 LDRB r0, [r2], #1 CMP r0, #' ' + 1 MOVCC r0, #0 STRB r0, [r3], #1 BCS add_prefix4 MOV r8, r11 [ DEBUG SWI os_writes DCB 4, "After add_prefix: ", 0 MOV r2, r8 01 LDRB r0, [r2], #1 CMP r0, #' '+1 SWICS os_writec CMP r0, #' '+1 BCS %BT01 SWI os_newline ] LDMFD sp, {r0, r1, r2, r3, r4, lr} BIC lr, lr, #carry STR lr, [sp, #20] B add_prefix5 strip_hats0 STMFD sp!, {r0, r1, r2, r3, r4, r5, lr} MRS lr, CPSR ; NOP on old machine STR lr, [sp, #20] add_prefix5 MOV r2, r8 MOV r1, r11 MOV r3, r1 MOV r4, r3 add_prefix6 LDRB r0, [r2], #1 STRB r0, [r1], #1 CMP r0, #'.' LDREQB lr, [r2] CMPEQ lr, #'^' BNE add_prefix9 LDRB lr, [r3] CMP lr, #'$' CMPNE lr, #'@' CMPNE lr, #'%' CMPNE lr, #'&' CMPNE lr, #'<' CMPNE lr, #'^' MOVEQ r0, #'!' ; R0 > ' ' and != '.' BEQ add_prefix9 add_prefix7 LDRB lr, [r2], #1 CMP lr, #'.' CMPNE lr, #' ' BHI add_prefix7 SUB r2, r2, #1 CMP r3, r4 STREQB lr, [r3] add_prefix8 LDRB lr, [r2], #1 STRNEB lr, [r3], #1 CMP lr, #' ' BHI add_prefix8 MOV r8, r11 LDR r2, [sp, #20] BIC r2, r2, #carry STR r2, [sp, #20] B add_prefix5 add_prefix9 CMP r0, #':' MOVEQ r4, r1 MOVEQ r3, r1 CMP r0, #'.' SUBEQ r3, r1, #1 CMP r0, #' ' BHI add_prefix6 [ DEBUG SWI os_writes DCB 4, "After stripping ^s ", 0 SWI os_newline MOV r2, r8 write_name1 LDRB r0, [r2], #1 CMP r0, #' '+1 SWICS os_writec CMP r0, #' '+1 BCS write_name1 SWI os_newline ] LDMFD sp!, {r0, r1, r2, r3, r4, lr} TEQ pc, pc BNE add_prefix_ret_26 MSR CPSR_f, lr LDR pc, [sp], #4 add_prefix_ret_26 TEQP pc, lr LDR pc, [sp], #4 find_handler_26 STR lr, [sp, #-4]! STR pc, [sp, #-4]! BL find_handler_32 NOP ADD sp, sp, #4 LDMVCFD sp!, {pc}^ LDR lr, [sp], #4 ORRS pc, lr, #overflow find_handler_32 CMP r0, #&40 BHS file_handler_external_entry CMP r0, #0 ; clear V MOV pc, lr gbpb_handler_26 STR lr, [sp, #-4]! STR pc, [sp, #-4]! BL gbpb_handler_32 NOP ADD sp, sp, #4 LDMVCFD sp!, {pc}^ LDR lr, [sp], #4 ORRS pc, lr, #overflow gbpb_handler_32 CMP r0, #9 MOVLO pc, lr ; V clear CMP r0, #13 BLO file_handler_external_entry CMP r0, #0 ; V clear MOV pc, lr file_handler_26 STR lr, [sp, #-4]! STR pc, [sp, #-4]! BL file_handler_32 NOP ADD sp, sp, #4 LDMVCFD sp!, {pc}^ LDR lr, [sp], #4 ORRS pc, lr, #overflow [ DEBUG file_handler_external_entry STMFD sp!, {r8, r11, lr} B %FT02 file_handler_32 STMFD sp!, {r8, r11, lr} STMFD sp!, {r0,r1} SWI os_writes DCB 4, "file_handler: ", 0 01 LDRB r0, [r1], #1 CMP r0, #' '+1 SWICS os_writec CMP r0, #' '+1 BHS %BT01 SWI os_newline LDMFD sp!, {r0,r1} 02 | file_handler_external_entry file_handler_32 STMFD sp!, {r8, r11, lr} ] LDR r8, chain MOV lr, #0 LDR lr, [lr, #zp_wimpdomain] ; lr = domainid file_handler1 CMP r8, #0 BEQ file_handler2 LDR r11, [r8, #o_wimpdomain] CMP r11, lr LDRNE r8, [r8, #o_next] BNE file_handler1 LDR r11, fname_buffer BL add_prefix file_handler3 MOV r12,r8 ; hold dir block otherwise this gets very icky LDMFD sp!, {r8, r11, lr} MOVCS pc, lr TEQ pc, pc LDRNE lr, [sp, #8] ;get real pass-on address from 26-bit veneer TEQNEP pc, lr STR r1, [sp, #-4]! MOV r1, r12 STR pc, [sp, #-4]! ;store PC+8 (Architecture 4) or PC+12 MOV pc, lr NOP ;so that PC+8 is ok file_upcall LDMFD sp!, {r1, lr} ;target of stored PC B xfervc file_handler2 LDR r11, fname_buffer MOV r8, r1 BL strip_hats B file_handler3 fscontrol_handler_26 STR lr, [sp, #-4]! STR pc, [sp, #-4]! BL fscontrol_handler_32 NOP ADD sp, sp, #4 LDMVCFD sp!, {pc}^ LDR lr, [sp], #4 ORRS pc, lr, #overflow fscontrol_handler_32 CMP r0, #25 ; Rename objects BLO fscontrol_handler1 CMP r0, #27 ; Copy objects BLO copy_or_rename CMPNE r0, #28 ; Count objects CMPNE r0, #32 ; *FileInfo CMPNE r0, #37 ; Canonicalise [ HandleImages CMPNE r0, #41 ; return defects for image CMPNE r0, #42 ; map out defects for image CMPNE r0, #46 ; return used space map for image CMPNE r0, #47 ; read boot for disc/image CMPNE r0, #48 ; write boot for disc/image CMPNE r0, #49 ; read free space for disc/image CMPNE r0, #50 ; rename disc/image ; (should already be canonical, I think - JRF) ; CMPNE r0, #51 ; update stamp CMPNE r0, #52 ; find object at offset CMPNE r0, #55 ; read freespace (large) CMPNE r0, #56 ; read defects (large) CMPNE r0, #57 ; map out defect (large) ] BEQ file_handler_external_entry [ AllowDirectoryChanging CMP r0, #53 BEQ set_given_dir CMP r0, #43 BEQ unset_dir ] CMP r0, r0 MOV pc, lr fscontrol_handler1 CMP r0, #5 ; *. CMPNE r0, #6 ; *Ex CMPNE r0, #9 ; *Info CMPNE r0, #24 ; *Access BEQ file_handler_external_entry [ AllowDirectoryChanging CMP r0, #0 BEQ change_dir ] CMP r0, r0 MOV pc, lr [ AllowDirectoryChanging unset_dir STMFD sp!, {r0,lr} MOV r0,#0 SWI xddeutils_swibase + ddeutils_readprefix ;read context BVS %FT01 TEQ r0,#0 LDMEQFD sp!, {r0,pc} MOV r0,#0 SWI xddeutils_swibase + ddeutils_prefix 01 LDMVCFD sp!, {r0,lr,pc} ADDVS sp,sp,#4 LDMFD sp!, {lr,pc} set_given_dir CMP r2,#0 MOVNE pc,lr ; only process if 'set CSD' STMFD sp!, {r0,lr} MOV r0,#0 SWI xddeutils_swibase + ddeutils_readprefix ;read context BVS %FT01 CMP r0,#0 LDMEQFD sp!, {r0,pc} MOV r0,r1 SWI xddeutils_swibase + ddeutils_prefix 01 LDMVCFD sp!, {r0,lr,pc} ADDVS sp,sp,#4 LDMFD sp!, {lr,pc} change_dir STMFD sp!, {r0-r5,lr} MOV r0,#0 SWI xddeutils_swibase + ddeutils_readprefix ;read context BVS %FT01 TEQ r0,#0 LDMEQFD sp!, {r0-r5,pc} MOV r0,#5 SWI xos_file TST r0,#2 BEQ %FT02 MOV r0,r1 SWI xddeutils_swibase + ddeutils_prefix 01 LDMVCFD sp!, {r0-r5,lr,pc} ADDVS sp,sp,#4 LDMFD sp!, {r1-r5,lr,pc} 02 MOV r0,#19 MOV r2,#&100 ; Directory 'wibble' not found SWI xos_file ADD sp,sp,#4 ; skip r0 LDMFD sp!, {r1-r5,lr,pc} ] copy_or_rename STMFD sp!, {r1, r2} STMFD sp!, {r8, r9, r10, r11, lr, pc} ;store PC+8 or PC+12 B copy_or_rename1 NOP ;so that PC+8 is ok copy_or_rename_upcall ;target of stored PC LDMFD sp!, {r1, r2, lr} B xfervc copy_or_rename1 ; [ DEBUG ; STMFD sp!, {r0,r1} ; SWI os_writes ; DCB 4, "copy_or_rename1: ", 0 ; 01 LDRB r0, [r1], #1 ; CMP r0, #' '+1 ; SWICS os_writec ; CMP r0, #' '+1 ; BCS %BT01 ; SWI os_newline ; LDMFD sp!, {r0,r1} ; ] ADR r8, chain copy_or_rename1b LDR r8, [r8] CMP r8, #0 BEQ copy_or_rename2 MOV lr, #0 LDR lr, [lr, #zp_wimpdomain] LDR r11, [r8, #o_wimpdomain] CMP r11, lr BNE copy_or_rename1b LDR r11, fname_buffer MOV r9, r8 BL add_prefix MOV r10, r8 MOV r8, r9 ADD r11, r11, #FilenameLength MOV r9, r1 MOV r1, r2 BL add_prefix0 copy_or_rename3 MOV r1, r9 MOVCC r2, r8 MOVCC r1, r10 LDMFD sp!, {r8, r9, r10, r11, lr} ADDCS sp, sp, #12 MOVCS pc, lr TEQ pc, pc LDRNE lr, [sp, #16] ;get real pass-on address from 26-bit veneer MOVNES pc, lr MOV pc, lr copy_or_rename2 LDR r11, fname_buffer MOV r8, r1 BL strip_hats MOV r10, r8 ADD r11, r11, #FilenameLength MOV r9, r1 MOV r8, r2 BL strip_hats0 B copy_or_rename3 ; SWI DDEUtils_GetClSize doswi_getclsize LDR r0, cli_size MOV pc, lr ; SWI DDEUtils_GetCl doswi_getcl LDR r11, cli_buffer CMP r11, #0 MOVEQ r12, #0 STREQB r12, [r0] MOVEQ pc, lr STMFD sp!, {r2, r8, lr} MOV r8, #0 STR r8, cli_buffer STR r8, cli_size MOV r2, r11 MOV r8, r0 getcl1 LDRB r10, [r11], #1 STRB r10, [r0], #1 CMP r10, #' ' BHS getcl1 MOV r10, #0 STRB r10, [r0, #-1] MOV r0, #n_module_free SWI xos_module MOVVC r0, r8 LDMFD sp!, {r2, r8, lr} B xferv ; SWI DDEUtils_SetClSize doswi_setclsize STMFD sp!, {r1, r2, r3, lr} MOV r3, r0 LDR r2, cli_buffer CMP r2, #0 MOVNE r0, #n_module_free SWINE xos_module LDMVSFD sp!, {r1, r2, r3, pc} [ 0 = 1 CMP r3, #0 LDMEQFD sp!, {r1, r2, r3, pc} ] MOV r0, #n_module_claim SWI xos_module MOVVS r1, #0 STRVS r1, cli_buffer STRVS r1, cli_size STRVC r2, cli_buffer STRVC r3, cli_size MOVVC r0, r2 LDMFD sp!, {r1, r2, r3, lr} B xferv no_cli_buffer_msg DCD no_cli_buffer_error DCB "CLI buffer not set", 0 ALIGN do_no_cli_buffer ADR r0, no_cli_buffer_msg TEQ pc, pc ORRNES pc, lr, #overflow MSR CPSR_f, #overflow MOV pc, lr ; SWI DDEUtils_SetCl doswi_setcl LDR r11, cli_buffer CMP r11, #0 BEQ do_no_cli_buffer STMFD sp!, {r0, r1, lr} LDR r1, cli_size setcl1 LDRB r10, [r0], #1 STRB r10, [r11], #1 [ CheckBufferSize SUBS r1,r1,#1 BMI do_buffer_too_short ] CMP r10, #' ' BCS setcl1 LDMFD sp!, {r0, r1, pc} [ CheckBufferSize do_buffer_too_short LDMFD sp!, {r0, r1, lr} ADR r0, buffer_too_short_msg TEQ pc, pc ORRNES pc, lr, #overflow MSR CPSR_f, #overflow MOV pc, lr buffer_too_short_msg DCD buffer_too_short DCB "CLI buffer too short", 0 ] prefix_cmd MOV r6, lr SWI xddeutils_swibase + ddeutils_prefix MOV pc, r6 not_desktop_msg DCD not_desktop_error DCB "Throwback not available outside the desktop", 0 ALIGN no_task_msg DCD no_task_error DCB "No task registered for throwback", 0 ALIGN already_reg_msg DCD already_reg_error DCB "Another task is registered for throwback", 0 ALIGN not_reg_msg DCD not_reg_error DCB "Task not registered for throwback", 0 ALIGN ; check if we're in the desktop or not checkactivetasks STMFD sp!, {r0, lr} MOV r0, #0 SWI xwimp_readsysinfo MOVVS r0, #0 CMP r0, #0 LDMFD sp!, {r0, lr} MOVNE pc, lr ADR r0, not_desktop_msg TEQ pc, pc ORRNES pc, lr, #overflow MSR CPSR_f, #overflow MOV pc, lr do_no_task ADR r0, no_task_msg return_setv TEQ pc, pc ORRNES pc, lr, #overflow MSR CPSR_f, #overflow MOV pc, lr ; SWI DDEUtils_ThrowbackEnd doswi_throwbackend STMFD sp!, {r0-r4, r9, lr} BL checkactivetasks ADDVS sp,sp,#4 LDMVSFD sp!, {r1-r4, r9, pc} LDR r9, receiver_id CMP r9, #0 LDMEQFD sp!, {r0-r4, r9, lr} BEQ do_no_task MOV r0, #msg_throwback_end startorendmsg MOV r1, #0 ; No string stringonlymsg1 MVN r3, #0 ; No line no. MVN r4, #0 ; No error level BL sendmessage throwback_vsret ADDVS sp, sp, #4 LDRVC r0, [sp], #4 LDMFD sp!, {r1-r4, r9, lr} B xferv stringonlymsg STMFD sp!, {r0-r4, r9, lr} B stringonlymsg1 throwback_err DCB "Throwback error", 13, 10, 0 ALIGN ; SWI DDEUtils_ThrowbackRegister doswi_throwbackregister STMFD sp!, {r0, r9, lr} BL checkactivetasks ADDVS sp,sp,#4 LDMVSFD sp!, {r9, pc} LDR r9, receiver_id CMP r9, #0 LDMFD sp!, {r0, r9, lr} ADRNE r0, already_reg_msg BNE return_setv STR r0, receiver_id MOVS pc, lr ; SWI DDEUtils_ThrowbackUnregister doswi_throwbackunregister STMFD sp!, {r0, r9, lr} BL checkactivetasks ADDVS sp,sp,#4 LDMVSFD sp!, {r9, pc} LDR r9, receiver_id CMP r9, r0 MOVEQ r0, #0 STREQ r0, receiver_id LDMFD sp!, {r0, r9, lr} ADRNE r0, not_reg_msg BNE return_setv MOV pc, lr ; SWI DDEUtils_ThrowbackStart doswi_throwbackstart STMFD sp!, {r0-r4, r9, lr} BL checkactivetasks ADDVS sp,sp,#4 LDMVSFD sp!, {r1-r4, r9, pc} LDR r9, receiver_id CMP r9, #0 LDMEQFD sp!, {r0-r4, r9, lr} BEQ do_no_task MOV r0, #msg_throwback_start B startorendmsg ; support for ThrowbackSend throwback_add_prefix STMFD sp!, {lr} MOV r1, r2 BL file_handler_external_entry STMFD sp!, {r0, r3, r4} MOV lr, r0 CMP lr, #reason_infodetails MOVEQ r0, #msg_throwback_infoforfile CMP lr, #reason_processing MOVEQ r0, #msg_throwback_processingfile CMP lr, #reason_errordetails MOVEQ r0, #msg_throwback_errorsin BL stringonlymsg LDRVC r0, [sp], #4 ADDVS sp, sp, #4 LDMFD sp!, {r3, r4} BVS throwback_add_prefix1 CMP r0, #reason_processing LDMEQFD sp!, {pc} CMP r0, #reason_infodetails MOVEQ r0, #msg_throwback_infodetails MOVNE r0, #msg_throwback_errordetails MOV r1, r5 BL sendmessage throwback_add_prefix1 LDMFD sp!, {lr} B xferv ; DDEUtils_ThrowbackSend doswi_throwbacksend STMFD sp!, {r0-r4, r9, lr} BL checkactivetasks ADDVS sp,sp,#4 LDMVSFD sp!, {r1-r4, r9, pc} LDR r9, receiver_id CMP r9, #0 LDMEQFD sp!, {r0-r4, r9, lr} BEQ do_no_task BL throwback_add_prefix B throwback_vsret ; R0 = message id ; R1 = string 0 => no string ; R3 = line no -1 => no line no ; R4 = error level -1 => no errorlevel sendmessage STMFD sp!, {lr} [ DEBUG STMFD sp!, {r0, r1, r2, r3} MOV r3, r1 SWI os_writes DCB 4, "Message id = ", 0 ADR r1, hbuff MOV r2, #12 SWI os_converthex8 SWI os_write0 SWI os_writes DCB 13, 10, 0 MOV r0, r3 SWI os_write0 SWI os_writes DCB 13, 10, 5, 0 LDMFD sp!, {r0, r1, r2, r3} B %FT01 hbuff % 256 01 ] MOV r2, r1 MOVS lr, r1 BEQ sendmessage2 sendmessage1 LDRB r2, [lr], #1 CMP r2, #0 BNE sendmessage1 SUB r2, lr, r1 sendmessage2 ADD r2, r2, #31 BIC r2, r2, #3 MOV lr, sp SUB sp, sp, r2 STR r2, [sp] ADD r2, sp, #12 STMFD sp!, {lr} MOV lr, #0 STR lr, [r2], #4 ADD r0, r0, #ddeutils_msgbase_l ADD r0, r0, #ddeutils_msgbase_h STR r0, [r2], #4 CMN r3, #1 STRNE r3, [r2], #4 CMN r4, #1 STRNE r4, [r2], #4 CMP r1, #0 BEQ sendmessage4 sendmessage3 LDRB lr, [r1], #1 STRB lr, [r2], #1 CMP lr, #0 BNE sendmessage3 sendmessage4 MOV r0, #17 ADD r1, sp, #4 MOV r2, r9 ; IDJ/NK 4-Jan-95: AQU-00756 - truncate if message text too long LDR lr, [r1] ; length of msg CMP lr, #256 MOVGT lr, #256 STRGT lr, [r1] ; 256 is max size of msg MOVGT lr, #0 STRGTB lr, [r1, #255] SWI xwimp_sendmessage LDR sp, [sp] LDMFD sp!, {lr} B xferv initvar STMFD sp!, {r4, lr} MOV r3, r1 initvar1 LDRB r2, [r3], #1 CMP r2, #' ' BCS initvar1 SUB r2, r3, r1 MOV r3, #0 MOV r4, #0 SWI xos_setvarval LDMFD sp!, {r4, pc} END