 GET TimLib:hdr.System
 GET TimLib:hdr.Macros
 GET hdr.GlobHdr

 EXPORT ASM_SaveStackLimit
 EXPORT ASM_Song_Changer
 EXPORT ASM_Song_Lister

 IMPORT Song_Changer
 IMPORT Song_Lister

; default area assignment

 AREA |Assembler|,READONLY,CODE

 ALIGN
Saved_SL
 DCD 0
ASM_SaveStackLimit _FNAME
 STR     R10,Saved_SL
 MOV     PC,R14

;-------------------------------------------------------------------------------
; ASM_Song_Changer
;
; In  - R0 planned fill duration in 1/256 us
;       R12 song hdr ptr
;
; Out - R0 fill duration limited by stream change
;-------------------------------------------------------------------------------
 ALIGN
ASM_Song_Changer _FNAME
 _DEFPROC "R1-R12"
 ; function(ISong*, int)
 MOV     R1,R0
 MOV     R0,R12
 LDR     R12,[R12,#0] ; C GlbPtr
 LDR     R12,[R12,#glbmem_cpw] ; C pw
 CMP     R12,#0
 BNE     ASM_Song_Changer_FromModule
 ; call C function
 LDR     R10,Saved_SL
 MOV     R11,#0
 BL      Song_Changer
 _ENDPROC
ASM_Song_Changer_FromModule
 ; define C stack limit and read values
 MOV     R10,R13,LSR #20
 MOV     R10,R10,LSL #20
 LDMIA   R10,{R7,R8}
 LDR     R12,[R12,#0]
 LDMIB   R12,{R11,R12}
 STMIA   R10,{R11,R12}
 ADD     R10,R10,#&021C
 MOV     R11,#0
 ; call C function
 BL      Song_Changer
 ; restore stack limit values
 SUB     R10,R10,#&021C
 STMIA   R10,{R7,R8}
 _ENDPROC

;-------------------------------------------------------------------------------
; ASM_Song_Lister
;
; In  - R0 fill duration in 1/256 us
;       R12 song hdr ptr
;
; Out - R0 streams ptr
;       R1 nr of streams
;-------------------------------------------------------------------------------

 ALIGN
ASM_Song_Lister _FNAME
 _DEFPROC "R7-R12"
 ; reserve block for _kernel_swi_regs and push values
 STMDB   R13!,{R0-R6}
 ; function(_kernel_swi_regs*, void*)
 MOV     R0,R13
 MOV     R1,R12
 LDR     R12,[R12,#0] ; C GlbPtr
 LDR     R12,[R12,#glbmem_cpw] ; C pw
 CMP     R12,#0
 BNE     ASM_Song_Lister_FromModule
 ; call C function
 LDR     R10,Saved_SL
 MOV     R11,#0
 BL      Song_Lister
 ; read and release block
 LDMIA   R13!,{R0-R6}
 _ENDPROC
ASM_Song_Lister_FromModule
 ; define C stack limit and read values
 MOV     R10,R13,LSR #20
 MOV     R10,R10,LSL #20
 LDMIA   R10,{R7,R8}
 LDR     R12,[R12,#0]
 LDMIB   R12,{R11,R12}
 STMIA   R10,{R11,R12}
 ADD     R10,R10,#&021C
 MOV     R11,#0
 ; call C function
 BL      Song_Lister
 ; read and release block
 LDMIA   R13!,{R0-R6}
 ; restore stack limit values
 SUB     R10,R10,#&021C
 STMIA   R10,{R7,R8}
 _ENDPROC

 END
