@; veneer.s
@; --------
@; 12/3/23
@; Veneer for calling 'c' functions in other modules via their CMHG entry
@; points, from local 'c' functions in this module.
@; This is used for direct communication between the MidiSupport module
@; and its associated driver modules. In both directions so this veneer
@; is required in MidiSupport and also in driver modules that need to
@; talk directly to MidiSupport.

    .text
    .align 2

@; void module_call(int fn, _kernel_swi_regs *regs, int pw);

    .global module_call
module_call:
    @; r0 = fn entry point address in remote module
    @; r1 = regs address
    @; r2 = 'r12' value for remote module
    stmfd  sp!, {r1, r4-r12, lr}
    mov    r12, r2
    mov    r10, r0
    ldmia  r1, {r0-r9}
    mov    lr, pc
    mov    pc, r10
    ldr    r10, [sp], #4
    stmia  r10, {r0-r9}
    teq    pc, pc
    ldmeqfd  sp!, {r4-r12, pc}  @; 32 bit return
    ldmfd  sp!, {r4-r12, pc}^   @; 26 bit return

