! C runtime initialization for Prizm addins
! By Tari, based on Kristaba's reverse-engineered crt0.
 
    .extern _main
    .global initialize
   
    .section ".pretext"
    .align 2
initialize:
! Preserve things on the stack
    mov.l r14, @-r15    ! Frame pointer
    sts.l pr, @-r15     ! Return address
    mov.l r4, @-r15     ! Parameter 1
   
! Copy .data section into RAM
    mov.l v_bdata, r0       ! From
    mov.l v_ram_bdata, r2   ! To
    mov.l v_edata, r3       ! Limit
dataLoop:
    cmp/hs r3, r0
    bt dataDone             ! Stop when r0 >= r3
    mov.l @r0+, r1
    mov.l r1, @r2
    bra dataLoop
    add #4, r2              ! Delay slot
dataDone:
 
! Zero out .bss
    mov.l v_ram_ebss, r2    ! To
    mov.l v_ram_bbss, r3     ! Limit
    mov #0, r1              ! Constant
bssLoop:
    cmp/hs r3, r2
    bf bssDone              ! Stop when r2 < r3
    bra bssLoop
    mov.l r1, @-r2          ! Delay slot
bssDone:
   
! RAM is now initialized
 
    mov r5, r14             ! Save parameter 2
    mov #1, r6
    mov #0, r4
    bsr _GlibAddinAplExecutionCheck
    mov r6, r5
   
! main(r4, r5) with same state as input (returns to our caller)
   
    mov.l main, r7
    extu.w r14, r5
    mov.l @r15+, r5
    lds.l @r15+, pr
    jmp @r7
    mov.l @r15+, r14        ! Delay slot
   
_GlibAddinAplExecutionCheck:
    mov.l v_syscall, r2
    jmp @r2                 ! _GlibAddinAplExecutionCheck
    mov #0x29, r0           ! Delay slot
   
! Constants
    .align 4
main:
    .long _main
v_syscall:
    .long 0x80020070
 
v_bdata:
    .long _bdata
v_edata:
    .long _edata
v_ram_bdata:
    .long 0x8100000
   
v_ram_bbss:
    .long _bbss
v_ram_ebss:
    .long _ebss + 4
 