; MOSTLY gratuitously stolen from X-Files :-)


V_bit   *   1 :SHL: 28

; set up

   IMPORT   |Image$$RO$$Base|
   IMPORT   |_Lib$Reloc$Off$DP|

   AREA     VeneerCode, CODE, READONLY

SavedSPaddr
   &        0


; Call C function (address in R8)
wrapper
   STMFD    sp!, {r0-r9, sl, fp, ip, lr}

   MOV      r5, pc         ; **************
   ORR      r4, r5, #3     ; NOT 32 BIT !!!
   TEQP     r4, #0         ; **************
   MOV      r0, r0
   STMFD    sp!, {r4, r5, lr}

   MOV      sl, sp, LSR #20
   MOV      sl, sl, LSL #20
   LDMIA    sl, {v1, v2}
   LDR      r12, [r12]
   LDMIB    r12, {fp, r12}
   STMIA    sl, {fp, r12}
   MOV      fp, #0          ; halt C backtrace here!

   DCD      |_Lib$Reloc$Off$DP| + &E28AA000

   DCD      |_Lib$Reloc$Off$DP| + &E24AC000
   LDR      ip, [ip, #4]
   LDR      a1, SavedSPaddr
   ADD      a1, ip, a1
   STR      sp, [a1]

   ADD      a1, sp, #4 * 3
   MOV      lr, pc
   MOV      pc, r8

wrapperX
   DCD      |_Lib$Reloc$Off$DP| + &E24AA000

   STMIA    sl, {v1, v2}

   LDMFD    sp!, {r4, r5, lr}
   TEQP     r5, #0 ; is this a problem with 32bit?
   MOV      r0, r0

   TEQ      a1, #0
   STRNE    a1, [sp]

   LDMFD    sp!, {r0-r9, sl, fp, ip, lr}
   ORRNES   pc, lr, #V_bit
   BICS     pc, lr, #V_bit


; Veneer generates two labels, for example
   MACRO
   Veneer   $name
   EXPORT   entry_$name
   IMPORT   fsfs_$name

entry_$name
   STMFD          sp!, {r8-r12, lr}
   LDR            r8, =fsfs_$name
   BL             wrapper
   LDMFD          sp!, {r8-r12, lr}
   ORRVSS         pc, lr, #V_bit
   BICS           pc, lr, #V_bit

   LTORG
   MEND

   Veneer   Open
   Veneer   GetBytes
   Veneer   PutBytes
   Veneer   Args
   Veneer   Close
   Veneer   File
   Veneer   Func

   END
