Import of InfoZIP

Peter Naulls peter at
Wed Dec 19 03:08:26 PST 2001

In message <Pine.LNX.4.33.0112191039570.21520-100000 at>
          Nick Burrett <nick at> wrote:

> > I suggest the follow patch.  In fact, you don't even need to use the
> > final /riscos-dist in this case.
> This seems reasonable.  I will install it this afternoon, when I'm back
> in the office.
> Is there an updated SharedUnixLib module to go with this patch ?

Yes, below.

Unfortunately, since this was finished in the wee hours, no one but me
has tested it.   I'll put up a binary here:

Which is this program:

   #include <stdio.h>

   int main(void) {
     puts("empty loop");

(The program itself is called test, so calls itself), which provokes the
upcall, and is hopefully sufficient grounds for testing.  If everyone
who's able can test this, and make sure it seems to behave then that
would be great.

Ian's pointed out one issue with the module, that of global storage for
the module and use of R12.  It could be fixed, and will be for next
release, but I'm of course loathe to change it right now when its
current intended functionality is properly met.

I've also moved the call to DeRegister from _exit in unix.c, where it
didn't really belong to __exit, just before escape is reenable.  i.e.:

	MOV	v1, a1
	BL	|__dynamic_area_exit|
	LDR	a3, =|__sharedunixlibrary_key|
	LDR	a3, [a3]
	SWI	XSharedUnixLibrary_DeRegisterUpCall
	; re-enable Escape (in case SIGINT handler fired in ttyicanon)
	MOV	a1, #229



; $Source$
; $Date$
; $Revision$
; $State$
; $Author$

        GET     clib/unixlib/asm_dec.s


chunk   EQU     0x55c80    ; SharedUnixLibrary SWI Chunk 
error   EQU     0x0081a400 ; SharedUnixLibrary Error block

        DCD     0                          ; Start code
        DCD     init_code   - module_start ; Initialisation code
        DCD     final_code  - module_start ; Finalisation code
        DCD     0                          ; Service handler
        DCD     title       - module_start ; Title string
        DCD     help        - module_start ; Help string
        DCD     0                          ; Command table
        DCD     chunk                      ; SWI Base
        DCD     swi_handler - module_start ; SWI Handler
        DCD     swi_table   - module_start ; SWI Table
        DCD     0                          ; SWI Decoder

        DCB     "SharedUnixLibrary", 9, "1.00 (16 Dec 2001) (C) Peter Naulls, 2001 ", 0

        DCB     "SharedUnixLibrary", 0
        DCB     "RegisterUpCall", 0
        DCB     "DeRegisterUpCall", 0
        DCB     0

        DCD     error + 0
        DCB     "Unknown SharedUnixLibrary SWI call", 0

        DCD     error + 1
        DCB     "Unknown SharedUnixLibrary Key", 0

        DCD     error + 2
        DCB     "There are still clients active", 0

        CMP     r11, #0
        BEQ     register
        CMP     r11, #1
        BEQ     deregister
        ADR     r0, error_swi - module_start
        ORRS    pc, lr, #VFlag

        ; Application UpCall handler, PRM 1-291
        ; The address of this handler is passed back via The RegisterUpCall SWI.
        ; The caller application then provides that address to OS_ChangeEnvironment
        ; Having this handler in a module enables it to be validly called when
        ; the application isn't paged in.  This is despite the fact that most of
        ; the UpCalls we are not interested in at all.

        TEQ     r0, #256          ; New Application UpCall
        MOVNES  pc, lr            ; Otherwise exit quickly

        STMFD   sp!, {r0-r3, lr}  ; Save SVC_R14 and registers during environment handler

        MOV     r2, r12           ; Key passed to handler in R12
        LDR     r3,  [r2, #4]     ; Get handler address
        LDR     r12, [r2, #8]     ; Get module's private word

        BL      |delink|          ; Delink the handler
        CMP     r2, #0            ; Didn't find the key
        MOV     r12, r3
        LDMEQFD sp!, {r0-r3, pc}^ ; So exit handler

        LDMFD   sp!, {r0-r3, lr}  ; Restore SVC_R14 and registers

        MOV     pc, r12           ; Jump to application handler

        ; Register an application with the module.
        ; This SWI registers an application as an intended recipient of UpCalls
        ; After calling this method, it should then call OS_ChangeEnvironment
        ; with R0 = 16, and values returned from this SWI.
        ; The application may deregister its interest by calling DeRegister_UpCall,
        ; such as during an application's Exit and Error handlesr, or for other reasons.
        ; It is important that the application does so, as the module will not
        ; exit if any claimants remain.
        ; The is no need to deregister if UpCall 256 occurs; the module will do
        ; that automatically.
        ; Entry
        ;    R1 = Address of application's handler function
        ; Exit
        ;    R1 = Address of UpCall handler to pass in R1 to OS_ChangeEnvironment
        ;    R2 = SharedUnixLibrary key, required for deregistration, and
        ;         passed in R2 to OS_ChangeEnvironment 

        STMFD   sp!, {r0, r3, lr}

        ; The memory claimed for now merely provides a way validate a caller.
        ; Later on, it will be used to store information on a per-client basis.

        MOV     r0, #6
        MOV     r3, #12           
        SWI     XOS_Module         ; Claim memory to use

        LDMVSFD sp!, {r2, r3, lr}  ; Return to caller if error
        ORRVSS  pc, lr, #VFlag     ; Return error

        ; result in R2, return to caller at end
        LDR     r0,  [r12, #0]    ; Get head of list
        STR     r0,  [r2, #0]     ; Store in new block
        STR     r2,  [r12, #0]    ; Set to head of list

        STR     r1,  [r2, #4]     ; Set handler function address
        STR     r12, [r2, #8]     ; Set pointer to head of list

        ; return UpCall handler address in R1
        ADR     r1, upcall_handler - module_start

        LDMFD   sp!, {r0, r3, pc}^

        ; Deregister a previously registered handler
        ; Entry
        ;    R2 = Key provided when registering
        ; Exit
        ;    R2 = 1
        ; An error will be generated if the key is invalid, for example
        ; if the handler has already been deregistered.

        STMFD   sp!, {lr}
        BL      |delink|
        LDMFD   sp!, {lr}

        CMP     r2, #0
        ADREQ   r0, error_unknown - module_start ; Unable to find key
        ORREQS  pc, lr, #VFlag                   ; Return error

        MOVS    pc, lr

        ; Delink the handler
        ; Entry
        ;    R2 = Key
        ; Exit
        ;    R2 - 1 = Success, 0 = Key not found

        STMFD   sp!, {r0-r1, lr}

        ; Try to find reference
        MOV     r1, r12           ; Set to previous point in list
        LDR     r0, [r12, #0]     ; Get first item in list

        CMP     r0, #0
        MOVEQ   r2, #0
        LDMEQFD sp!, {r0-r1, pc}^ ; End of list, not found

        CMP     r0, r2            ; Compare passed key
        MOVNE   r1, r0            ; Set to current point in list
        LDR     r0, [r0, #0]      ; Get next item
        BNE     |delink_find|

        STR     r0, [r1, #0]      ; Fix up next pointer at previous point in list

        MOV     r0, #7
        SWI     XOS_Module        ; Free block

        MOV     r2, #1
        LDMFD   sp!, {r0-r1, pc}^

        ; Module initialisation

        MOVS    pc, lr

        ; Module finalisation
        ; Only allow exit if there are no claimants

        STMFD   sp!, {r0, lr}

        LDR     r0, [r12, #0]
        CMP     r0, #0                          ; Is head of list set?

        ADRNE   r0, error_active - module_start ; If so, set error and
                                                ; disallow module finalisation
        ADDNE   sp, sp, #4
        LDMNEFD sp!, {lr}
        ORRNES  pc, lr, #VFlag

        LDMFD   sp!, {r0, pc}^


 Peter Naulls - peter at
 RISC OS Projects Initiative  -
 Java for RISC OS and ARM     -
 Debian Linux on RiscPCs      -

More information about the gcc mailing list