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

 EXPORT Mem_Clear
 EXPORT Mem_FastClear
 EXPORT Mem_Move
 EXPORT Mem_FastMove

; default area assignment

 AREA |Assembler|,READONLY,CODE

;-------------------------------------------------------------------------------
; Mem_Clear
;
; In  - R0 pos
;       R1 len
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Mem_Clear _FNAME
 _DEFPROC "R0-R6"

 MOV     R3,#0
 MOV     R4,#0
 MOV     R5,#0
 MOV     R6,#0

Mem_Clear_StartLoop
 CMP     R1,#0
 BLE     Mem_Clear_End
 TST     R0,#&F
 STRNEB  R3,[R0],#1
 SUBNE   R1,R1,#1
 BNE     Mem_Clear_StartLoop
 AND     R2,R1,#&F
 MOVS    R1,R1,LSR #4
 BLE     Mem_Clear_EndLoopTest

Mem_Clear_MiddleLoop
 STMIA   R0!,{R3-R6}
; STR     R3,[R0],#4
; STR     R3,[R0],#4
; STR     R3,[R0],#4
; STR     R3,[R0],#4
 SUBS    R1,R1,#1
 BGT     Mem_Clear_MiddleLoop

Mem_Clear_EndLoopTest
 CMP     R2,#0
 BEQ     Mem_Clear_End

Mem_Clear_EndLoop
 STRB    R3,[R0],#1
 SUBS    R2,R2,#1
 BGT     Mem_Clear_EndLoop

Mem_Clear_End
 _ENDPROC

;-------------------------------------------------------------------------------
; Mem_FastClear
;
; In  - R0 pos word aligned
;       R1 len multiple of 32
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Mem_FastClear _FNAME
 CMP     R1,#0
 MOVLE   PC,R14
 _DEFPROC "R2-R9"

 MOV     R2,#0
 MOV     R3,#0
 MOV     R4,#0
 MOV     R5,#0
 MOV     R6,#0
 MOV     R7,#0
 MOV     R8,#0
 MOV     R9,#0

Mem_FastClear_Loop
 STMIA   R0!,{R2-R9}
 SUBS    R1,R1,#32
 BGT     Mem_FastClear_Loop

Mem_FastClear_End
 _ENDPROC

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

Mem_Move _FNAME
 CMP     R0,#0
 MOVEQ   PC,R14
 CMP     R2,#0
 MOVLE   PC,R14
 _DEFPROC "R0-R3"
 CMP     R0,R1
 BHI     Mem_Move_Reverse

Mem_Move_Loop
 LDRB    R3,[R1],#1
 SUBS    R2,R2,#1
 STRB    R3,[R0],#1
 BGT     Mem_Move_Loop
 _ENDPROC

Mem_Move_Reverse
 ADD     R1,R1,R2
 SUB     R1,R1,#1
 ADD     R0,R0,R2
 SUB     R0,R0,#1
Mem_Move_Reverse_Loop
 LDRB    R3,[R1],#-1
 SUBS    R2,R2,#1
 STRB    R3,[R0],#-1
 BGT     Mem_Move_Reverse_Loop
 _ENDPROC

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

Mem_FastMove _FNAME
 CMP     R0,#0
 MOVEQ   PC,R14
 CMP     R2,#0
 MOVLE   PC,R14
 _DEFPROC "R0-R3"
 CMP     R0,R1
 BHI     Mem_FastMove_Reverse

Mem_FastMove_Loop
 LDR     R3,[R1],#4
 SUBS    R2,R2,#4
 STR     R3,[R0],#4
 BGT     Mem_FastMove_Loop
 _ENDPROC

Mem_FastMove_Reverse
 ADD     R1,R1,R2
 SUB     R1,R1,#4
 ADD     R0,R0,R2
 SUB     R0,R0,#4
Mem_FastMove_Reverse_Loop
 LDR     R3,[R1],#-4
 SUBS    R2,R2,#4
 STR     R3,[R0],#-4
 BGT     Mem_FastMove_Reverse_Loop
 _ENDPROC

 END
