; $Id: s.interface 3.1 93/03/09 23:38:13 brian Exp $
r0      RN      0
r1      RN      1
r2      RN      2
r3      RN      3
r4      RN      4
r5      RN      5
r6      RN      6
r7      RN      7
r8      RN      8
r9      RN      9
r10     RN     10
r11     RN     11
r12     RN     12
r13     RN     13
r14     RN     14
r15     RN     15

a1      RN      0
a2      RN      1
a3      RN      2
a4      RN      3

v1      RN      4
v2      RN      5
v3      RN      6
v4      RN      7
v5      RN      8
v6      RN      9

sl      RN     10
fp      RN     11
ip      RN     12
sp      RN     13
lr      RN     14
pc      RN     15

C_bit   *       1 :SHL: 29
V_bit   *       1 :SHL: 28

        IMPORT  |Image$$RO$$Base|
        IMPORT  |_Lib$Reloc$Off$DP|
        IMPORT  fsentry_open
        IMPORT  fsentry_getbytes
        IMPORT  fsentry_putbytes
        IMPORT  fsentry_args
        IMPORT  fsentry_close
        IMPORT  fsentry_file
        IMPORT  fsentry_func
        IMPORT  fsentry_gbpb
        IMPORT  fsentry_free

        EXPORT  veneer_fsentry_open
        EXPORT  veneer_fsentry_getbytes
        EXPORT  veneer_fsentry_putbytes
        EXPORT  veneer_fsentry_args
        EXPORT  veneer_fsentry_close
        EXPORT  veneer_fsentry_file
        EXPORT  veneer_fsentry_func
        EXPORT  veneer_fsentry_gbpb
        EXPORT  veneer_fsentry_free
        EXPORT  Image_RO_Base


        AREA    FSEntry_Interfaces,REL,CODE,READONLY

        LTORG

veneer_fsentry_open
        MOV     r8, #fsentry_branchtable - %F10 + 4*0
        B       fsentry_common
veneer_fsentry_getbytes
        MOV     r8, #fsentry_branchtable - %F10 + 4*1
        B       fsentry_common
veneer_fsentry_putbytes
        MOV     r8, #fsentry_branchtable - %F10 + 4*2
        B       fsentry_common
veneer_fsentry_args
        MOV     r8, #fsentry_branchtable - %F10 + 4*3
        B       fsentry_common
veneer_fsentry_close
        MOV     r8, #fsentry_branchtable - %F10 + 4*4
        B       fsentry_common
veneer_fsentry_file
        MOV     r8, #fsentry_branchtable - %F10 + 4*5
        B       fsentry_common
veneer_fsentry_func
        MOV     r8, #fsentry_branchtable - %F10 + 4*6
        B       fsentry_common
veneer_fsentry_gbpb
        MOV     r8, #fsentry_branchtable - %F10 + 4*7
        B       fsentry_common
veneer_fsentry_free
        MOV     r8, #fsentry_branchtable - %F10 + 4*8
        MOV     lr,pc
        TST     lr,#3
        LDMNEFD sp!,{lr}
        BNE     fsentry_common
        SWI     &16     ;OS_EnterOS
        BL      fsentry_common
        MOV     lr,pc
        TEQP    lr,#3
        ANDEQ   r0,r0,r0
        LDMFD   sp!,{pc}

fsentry_common  ; os_error *fsentry_common( Parameter_Block * )

        ; Store the input registers onto the stack
        STMFD   sp!,{r0-r12,lr}

        MOV     sl, sp, LSR #20
        MOV     sl, sl, LSL #20         ; SP_LWM
        LDMIA   sl, {v1, v2}            ; save old reloc modifiers over fn call
        LDR     r12, [r12]              ; private word pointer
        LDMIB   r12, {fp, r12}          ; new relocation modifiers
        STMIA   sl,  {fp, r12}          ; set by module init
        MOV     fp, #0                  ; halt C backtrace here!

        ; This is equivalent of 'ADD r10, r10, #0' + |_Lib$Reloc$Off$DP|
        DCD     |_Lib$Reloc$Off$DP| + &E28AA000

        ; Pass a pointer to the structure on the stack
        MOV     a1, sp

        ; BL    fsentry_branchtable[r8]
        MOV     lr, pc
        ADD     pc, pc, r8

        ; This is equivalent of 'SUB r10, r10, #0' + |_Lib$Reloc$Off$DP|
        DCD     |_Lib$Reloc$Off$DP| + &E24AA000

10      ; This label must be the 2nd instructions past the above ADD pc, pc, r8

        STMIA   sl, {v1, v2}            ; restore old reloc modifiers

        ; Save the returned value in r8
        MOVS    lr, r0
        ; Get the stuff off the stack
        LDMFD   sp!, {r0-r12}
        ; If returned value indicates an error, then set the overflow and put it back in r0
        MOVNE   r0, lr

        ; Mess about with the flag bits in lr
        MOV     lr, pc
        BIC     lr, lr, #C_bit + V_bit
        ORRNE   lr, lr, #V_bit          ; V = err != 0
        TST     r1, r1                  ; C = r1 == 0
        ORREQ   lr, lr, #C_bit

        ; Move the flag bits into psr
        TEQP    lr, #0
        LDMFD   sp!,{pc}

fsentry_branchtable
        B       fsentry_open
        B       fsentry_getbytes
        B       fsentry_putbytes
        B       fsentry_args
        B       fsentry_close
        B       fsentry_file
        B       fsentry_func
        B       fsentry_gbpb
        B       fsentry_free

; Give RM base address to C program

        AREA    Code_Description, DATA, REL
Image_RO_Base   DCD     |Image$$RO$$Base|

        END
