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

 IMPORT IStream_Lister

 EXPORT IStream_ASM_Changer
 EXPORT IStream_ASM_Lister

 EXPORT check_hardware

 EXPORT CFN_mul16
 EXPORT Str_CopyAndStrip

; default area assignment

 AREA |Assembler|,READONLY,CODE

 _GENRETURNS

;-------------------------------------------------------------------------------
; IStream_Changer
;
; In  - R0 planned fill duration in 1/256 us
;       R12 file hdr ptr !!!
;
; Out - R0 fill duration limited by stream change
;-------------------------------------------------------------------------------
 ALIGN
IStream_ASM_Changer _FNAME
 MOV     PC,R14

;-------------------------------------------------------------------------------
; IStream_Lister
;
; In  - R0 fill duration in 1/256 us
;       R12 file hdr ptr !!!
;
; Out - R0 streams ptr
;       R1 nr of streams
;-------------------------------------------------------------------------------
IStream_Title
 = "DiskSample",0

 ALIGN
IStream_ASM_Lister _FNAME
 _DEFPROC "R7-R12"
 ; define C stack limit and read values
 MOV     R10,R13,LSR #20
 MOV     R10,R10,LSL #20
 LDMIA   R10,{R7,R8}
 ; 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
 ;
 LDR     R12,[R12,#0]
 LDMIB   R12,{R11,R12}
 STMIA   R10,{R11,R12}
 ADD     R10,R10,#&021C
 MOV     R11,#0
 ; call C function
 BL      IStream_Lister
; LDR     R1,[R13,#4]
; CMP     R1,#0
; BNE     Ignore
; ADR     R0, IStream_Title
; MOV     R1,#125
; MOV     R2,R13
; MOV     R3,#60
; MOV     R4,#-1
; SWI     &4c88a
Ignore
 ; read and release block
 LDMIA   R13!,{R0-R6}
 ; restore stack limit values
 SUB     R10,R10,#&021C
 STMIA   R10,{R7,R8}
 _ENDPROC

;-------------------------------------------------------------------------------
; parameters:
;  out: r0 = 0 if ok, error ptr otherwise

Err_StrongARM
	DCD     0
	= "Processor with 64-bit multiplication instructions (StrongARM or later) is required.",0
	ALIGN
check_hardware
; Check if CPU supports SMLA
	MOV     R0,#0
	MOV     R1,#0
	MOV     R2,#251
	MOV     R3,#241
	SMLAL   R0,R1,R2,R3
	MUL     R1,R2,R3
	CMP     R0,R1
	ADRNE   R0,Err_StrongARM
	MOVEQ   R0,#0
	MOV     PC,R14

;-------------------------------------------------------------------------------
; CFN_Mul16
;
; In - R0 = a
;      R1 = b
;
; Out - R0 = (a*b)>>16
;-------------------------------------------------------------------------------
 ALIGN
CFN_mul16 _FNAME
 _DEFPROCC "R4"
 _FNMul16 R0,R1,R2,R3,R4
 MOV     R0,R4
 _ENDPROC

;-------------------------------------------------------------------------------
; Str_CopyAndStrip
;
; In - R0 = ptr new
;      R1 = ptr old
;      R2 = len
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Str_CopyAndStrip _FNAME
 CMP     R0,#0
 MOVEQ   PC,R14
 _DEFPROCC "R4"

 MOV     R4,R0
 ADD     R2,R2,R1

Mem_CopyAndStrip_LeadLoop
 CMP     R1,R2
 BHS     Mem_CopyAndStrip_End
 LDRB    R3,[R1],#1
 CMP     R3,#32
 BLT     Mem_CopyAndStrip_End
 BEQ     Mem_CopyAndStrip_LeadLoop
 SUB     R1,R1,#1

 SUB     R2,R2,#1
Mem_CopyAndStrip_TrailLoop
 CMP     R1,R2
 BHS     Mem_CopyAndStrip_Copy
 LDRB    R3,[R2],#-1
 CMP     R3,#32
 BLE     Mem_CopyAndStrip_TrailLoop
 ADD     R2,R2,#1

Mem_CopyAndStrip_Copy
 ADD     R2,R2,#1
Mem_CopyAndStrip_CopyLoop
 LDRB    R3,[R1],#1
 CMP     R3,#32
 BLT     Mem_CopyAndStrip_End
 STRB    R3,[R0],#1
 CMP     R1,R2
 BLO     Mem_CopyAndStrip_CopyLoop

Mem_CopyAndStrip_End
 MOV     R3,#0
 STRB    R3,[R0]
 _ENDPROC

 END
