 GET TimLib:hdr.System
 GET TimLib:hdr.Macros
 GET TimLib:hdr.Multiplication
 GET TimLib:hdr.Division
 GET TimLib:hdr.Streams
 GET TimLib:hdr.Seq
 GET hdr.GlobHdr
 GET hdr.MemUtils

 EXPORT Seq_Init
 EXPORT Seq_DefaultConfig
 EXPORT Seq_AllowFinalise
 EXPORT Seq_SoundService
 EXPORT Seq_Configure
 EXPORT Seq_SetMixScale
 EXPORT Seq_GetMixingInfo
 EXPORT Seq_RegisterHandler
 EXPORT Seq_UnregisterHandler
 EXPORT Seq_GetSampleSize
 EXPORT Seq_ResetMaxWavePercentage
 EXPORT Seq_Filler_WAV
 EXPORT Seq_GetPlayingFrequency
 EXPORT Seq_SkipProcessStream
 EXPORT Seq_GetLogTable
 EXPORT Seq_GetTime

AGC_Recover         * 2
AGC_MaxVal          * &10000<<AGC_Recover

TimerType_None      * 0
TimerType_IOC       * 1
TimerType_HAL       * 2

Max_Equalizers      * 10

                    ^ 0
stream_info_vleft   # 4 ; [0...65536...]
stream_info_vright  # 4 ; [0...65536...]
size_stream_info    # 0

                    ^ 0
bandpass_par_c0     # 4
bandpass_par_c1     # 4
bandpass_par_c2     # 4
bandpass_par_d1     # 4
bandpass_par_d2     # 4
bandpass_save_x1L   # 4
bandpass_save_x2L   # 4
bandpass_save_y1L   # 4
bandpass_save_y2L   # 4
bandpass_save_x1R   # 4
bandpass_save_x2R   # 4
bandpass_save_y1R   # 4
bandpass_save_y2R   # 4
size_bandpass       # 0

                        ^ 0
data_TAG                # 4
data_EqualNr            # 4
data_EqualPars          # size_bandpass*Max_Equalizers
data_Filler_Mix_Scale   # 4 ; 100% = 65536
data_StereoSeparation   # 4 ; 100% = 256 [-1024, 1024]
data_Balance            # 4 ; 128 = center [left 0, right 255]
data_Status             # 4
data_SampleSize         # 4
data_Quality            # 4
data_FreqIndex          # 4 ; 16-bit mixing frequency index
data_FineQuality        # 4 ; in 1/2^8 us = 256*1000000/FMix
data_TimeStep           # 4 ; 2^40/Fmix (see R7 of filling routines)
data_SharedSoundHandler # 4
data_Stream_NrOfHandlers # 4
data_Stream_Handlers    # seq_max_handlers * 4
data_DMAConfig          # 4*5 ; R0-R4
data_VoicesBufferPtr    # 4
data_Buffer32           # 4
data_Buffer32_Equ       # 4
data_WAVBuffer          # 4
data_MaxReadWave        # 4 ; maximal seen wave amplitude
data_MaxWave            # 4 ; maximal wave amplitude for given volume setting,
                            ; used to trigger AGC if configured not to allow
                            ; sound to exceed given volume setting
data_AGC                # 4 ; current AGC wave amplitude scaling factor
data_MaxAGC             # 4 ; worst seen AGC wave amplitude scaling factor
data_WavePercentage     # 4 ; 100% * maximal wave / maximal seen wave
                            ; helps the user ajust songs relative volumes
data_TimerType          # 4 ; 0 None, 1 IOC, 2 HAL
data_TimerTicksPerSec   # 4
data_TimerPeriod        # 4
data_TimerStartValue    # 4
data_Filler_CPU         # 4
data_Filler_CPU1        # 4
data_Filler_CPUCount    # 4
data_Filler_MaxCPU      # 4
data_Filler_AllowedTime # 4
data_MaxNrOfStreams     # 4
data_MaxNrOfStreamsSeen # 4
data_NrOfStreams        # 4
data_Polyphony          # 4
data_StreamsPtr         # seq_max_streams*4
data_Streams_Info       # (size_stream_info * seq_max_streams)
size_data               # 0

; Macros used for interpolated sample data
; R0 last value
; R10 new value << 16
; RR3 new value - old value
	MACRO
	PROCConvertSampleByte $y
	[ "$y"="yes"
	ADD     R0,R0,R10
	]
	LDRB    R10,[R1,R5]
	MOV     R10,R10,LSL #24
	RSB     R10,R0,R10,ASR #16
	MEND

	MACRO
	PROCConvertSample2Byte $y
	[ "$y"="yes"
	ADD     R0,R0,R10
	]
	LDRB    R10,[R1,R5,LSL #1]
	MOV     R10,R10,LSL #24
	RSB     R10,R0,R10,ASR #16
	MEND

	MACRO
	PROCConvertSampleHalfWord $y
	[ "$y"="yes"
	ADD     R0,R0,R10
	]
	LDR     R10,[R1,R5,LSL #1]
	MOV     R10,R10,LSL #16
	RSB     R10,R0,R10,ASR #16
	MEND

	MACRO
	PROCConvertSample4HalfWord $y
	[ "$y"="yes"
	ADD     R0,R0,R10
	]
	LDR     R10,[R1,R5,LSL #2]
	MOV     R10,R10,LSL #16
	RSB     R10,R0,R10,ASR #16
	MEND

	MACRO
	PROCConvertHSampleHalfWord $y
	[ "$y"="yes"
	ADD     R0,R0,R10
	]
	MOV     R10,R5,LSL #1
	LDRSH   R10,[R1,R10]
	RSB     R10,R0,R10
	MEND

	MACRO
	PROCConvertHSample4HalfWord $y
	[ "$y"="yes"
	ADD     R0,R0,R10
	]
	MOV     R10,R5,LSL #2
	LDRSH   R10,[R1,R10]
	RSB     R10,R0,R10
	MEND

	MACRO
	PROCInterpol $x
	MOV     R9,R6,LSR #17
	MUL     R9,R10,R9
	ADD     $x,R0,R9,ASR #15
	MEND

; Macros used for checking next sample data to use

; Macros used for checking next sample data to use
	MACRO
	PROCPrepNext $next
 ; Prepare next value
	ADDS    R6,R6,R7,LSL #8
	[ "$next"="x"
	ADDCS   R5,R5,#1
	|
	BCC     $next
	ADD     R5,R5,#1
	]
	MEND

	MACRO
	PROCPrepareNext $next,$loop
 ; Prepare next value
	ADDS    R6,R6,R7,LSL #8
	BCC     $next
	ADDS    R5,R5,#1
 ; End of sample?
	BGE     $loop
	MEND

	MACRO
	PROCPrepareNextSimple $loop
 ; Prepare next value
	ADDS    R6,R6,R7,LSL #8
 ; End of sample?
	[ "$loop"="x"
	ADC     R5,R5,R7,LSR #24
	|
	ADCS    R5,R5,R7,LSR #24
	BGE     $loop
	]
	MEND

	MACRO
	PROCPrepareNextOver $loop
 ; Prepare next value
	ADDS    R6,R6,R7,LSL #7
 ; End of sample?
	[ "$loop"="x"
	ADC     R5,R5,R7,LSR #25
	|
	ADCS    R5,R5,R7,LSR #25
	BGE     $loop
	]
	MEND

	MACRO
	PROCPrepBNext $next
 ; Prepare next value
	ADDS    R6,R6,R7,LSL #8
	[ "$next"="x"
	SUBCS   R5,R5,#1
	|
	BCC     $next
	SUB     R5,R5,#1
	]
	MEND

	MACRO
	PROCPrepareBNext $next,$loop
 ; Prepare next value
	ADDS    R6,R6,R7,LSL #8
	BCC     $next
	SUBS    R5,R5,#1
 ; End of sample?
	BLE     $loop
	MEND

	MACRO
	PROCPrepareBNextSimple $loop
 ; Prepare next value
	ADDS    R6,R6,R7,LSL #8
	SUBCS   R5,R5,#1
 ; End of sample?
	[ "$loop"="x"
	SUB     R5,R5,R7,LSR #24
	|
	SUBS    R5,R5,R7,LSR #24
	BLE     $loop
	]
	MEND

	MACRO
	PROCPrepareBNextOver $loop
 ; Prepare next value
	ADDS    R6,R6,R7,LSL #7
	SUBCS   R5,R5,#1
 ; End of sample?
	[ "$loop"="x"
	SUB     R5,R5,R7,LSR #25
	|
	SUBS    R5,R5,R7,LSR #25
	BLE     $loop
	]
	MEND

 ; default area assignment

 AREA |Assembler|,READONLY,CODE

;-------------------------------------------------------------------------------
; Seq_Init
;
; In  - R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN
Seq_TAG
 = "SEQQ"

Seq_Init _FNAME
 _DEFPROCV "R1-R11"
 ; save R0
 MOV     R10,R0

 LDR     R11,[R12,#glbmem_seqdataptr]

 ; Initialise data area
 LDR     R0,Seq_TAG
 STR     R0,[R11,#data_TAG]
 MOV     R0,#1
 STR     R0,[R11,#data_MaxReadWave]
 RSB     R0,R0,#&8000
 STR     R0,[R11,#data_MaxWave]
 MOV     R0,#AGC_MaxVal
 STR     R0,[R11,#data_AGC]
 STR     R0,[R11,#data_MaxAGC]
 MOV     R0,#&2000
 STR     R0,[R11,#data_WavePercentage]

 ; Initialise timer
Seq_Init_TimerHAL
 ; Timer 0 can be read ?
 MOV     R0,#0
 MOV     R8,#0
 MOV     R9,#21
 SWI     XOS_Hardware
 BVS     Seq_Init_TimerNoHal
 ; Yes, get timer ticks per second and period
 MOV     R0,#0
 MOV     R8,#0
 MOV     R9,#19
 SWI     XOS_Hardware
 BVS     Seq_Init_TimerNoHal
 STR     R0,[R11,#data_TimerTicksPerSec]
 MOV     R0,#0
 MOV     R8,#0
 MOV     R9,#20
 SWI     XOS_Hardware
 BVS     Seq_Init_TimerNoHal
 STR     R0,[R11,#data_TimerPeriod]
 MOV     R0,#TimerType_HAL
 STR     R0,[R11,#data_TimerType]
 B       Seq_Init_TimerEnd
Seq_Init_TimerNoHal
 MOV     R0,#8
 SWI     XOS_ReadSysInfo
 BVS     Seq_Init_TimerIOC ; Pre-RPC
 CMP     R0,#3             ; RPC, A7000, ...
 BGT     Seq_Init_TimerNone; Iyonix, A9Home, ...
Seq_Init_TimerIOC
 MOV     R0,#TimerType_IOC
 STR     R0,[R11,#data_TimerType]
Seq_Init_TimerNone
 ; Initialise timer to 2000000
 MOV     R0,#&1E0000
 ORR     R0,R0,#&8400
 ORR     R0,R0,#&80
 STR     R0,[R11,#data_TimerTicksPerSec]
 MOV     R0,#&10000
 STR     R0,[R11,#data_TimerPeriod]
Seq_Init_TimerEnd

 ; Check if 16-bit is hardware present
 MOV     R0,#0
 SWI     XSound_Mode
 MOVVS   R0,#0
 CMP     R0,#0
 MOVNE   R0,#seq_status_16bit+seq_status_16bitpresent
 ORR     R0,R0,#seq_status_mixnorescale
 STR     R0,[R11,#data_Status]
 TST     R0,#seq_status_16bitpresent
 BEQ     Seq_Init_No16bit
 MOV     R0,#1
 SWI     XSound_SampleRate
 STR     R1,[R11,#data_FreqIndex]
Seq_Init_No16bit

 ; 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
 LDREQ   R0,[R11,#data_Status]
 ORREQ   R0,R0,#seq_status_SMLASupport
 STREQ   R0,[R11,#data_Status]

 ; Check if CPU supports LDRH
 MOV     R0,#0
 SWI     XOS_PlatformFeatures
 MOVVS   R0,#0
 TST     R0,#&80
 LDRNE   R0,[R11,#data_Status]
 ORRNE   R0,R0,#seq_status_LDRHSupport
 STRNE   R0,[R11,#data_Status]

 ; prepare 8bit dynamic handler
 ADD     R0,R12,#glbmem_8bit_dynamic
 ADRL    R1,Seq_Filler_8bit_Dynamic
 MOV     R2,#(Seq_Filler_8bit_Dynamic_End - Seq_Filler_8bit_Dynamic)
 BL      Mem_Move
 ADD     R0,R12,#glbmem_8bit_dynamic+8
 STR     R0,[R12,#glbmem_8bit_handler]
 STR     R11,[R12,#glbmem_8bit_dynamic+0]
 ADRL    R0,Seq_Filler_8bit
 STR     R0,[R12,#glbmem_8bit_dynamic+4]
 ; Synchronise areas
 MOV     R0,#1
 ADD     R1,R12,#glbmem_8bit_dynamic
 ADD     R2,R1,#(glbmem_8bit_dynamicend - glbmem_8bit_dynamic)
 SWI     XOS_SynchroniseCodeAreas

 BL      Seq_DefaultConfig

 ;restore R0
 MOV     R0,R10

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_DefaultConfig
;
; In  - R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_DefaultConfig _FNAME
 _DEFPROC "R0-R1,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]
 MOV     R0,#256
 STR     R0,[R11,#data_StereoSeparation]
 MOV     R0,#128
 STR     R0,[R11,#data_Balance]
 MOV     R0,#24
 STR     R0,[R11,#data_Quality]
 MOV     R0,#64
 STR     R0,[R11,#data_Polyphony]
 STR     R0,[R11,#data_MaxNrOfStreams]
 MOV     R0,#0
 STR     R0,[R11,#data_EqualNr]
 MOV     R0,#1
 MOV     R1,#0
 SWI     XSound_SampleRate
 STR     R1,[R11,#data_FreqIndex]

 LDR     R0,[R11,#data_Status]
 BIC     R0,R0,#seq_status_reset_mask1
 BIC     R0,R0,#seq_status_reset_mask3
 BIC     R0,R0,#seq_status_reset_mask4
 TST     R0,#seq_status_16bitpresent
 ORRNE   R0,R0,#seq_status_16bit
 ORR     R0,R0,#seq_status_mixnorescale
 STR     R0,[R11,#data_Status]

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Finalise
;
; In  - R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_AllowFinalise _FNAME
 _DEFPROCV "R11"
 LDR     R11,[R12,#glbmem_seqdataptr]
 CMP     R11,#0
 _ENDPROC EQ

 LDR     R0,[R11,#data_Stream_NrOfHandlers]
 CMP     R0,#0
 _ERROR  GT,Err_HandlerStillPlaying

 _ENDPROC
Err_HandlerStillPlaying
 DCD     1
 = "At least one handler is still active",0

;-------------------------------------------------------------------------------
; Seq_SoundService
;
; Note: We will handle module start if we detected module died first.
;       We won't attempt switched from one module to another.
;
; In  - R0  sound level starting/dying
;       R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_SoundService _FNAME
 _DEFPROC "R10-R11"

 LDR     R11,[R12,#glbmem_seqdataptr]
 CMP     R11,#0
 _ENDPROC EQ

 LDR     R10,[R11,#data_Status]

Seq_SoundService_DMAStarting
 CMP     R0,#0
 BNE     Seq_SoundService_DMADying
 TST     R10,#seq_status_handlerDMA16bit+seq_status_handlerDMA8bit
 TSTNE   R10,#seq_status_handlerdisconnected
 BEQ     Seq_SoundService_End
 ADRL    R0,Seq_SetHardVoices
 MOV     R1,R12
 SWI     XOS_AddCallBack
 B       Seq_SoundService_End

Seq_SoundService_DMADying
 CMP     R0,#1
 BNE     Seq_SoundService_ShareSoundStarting
 TST     R10,#seq_status_handlerDMA16bit+seq_status_handlerDMA8bit
 BEQ     Seq_SoundService_End
 ORR     R10,R10,#seq_status_handlerdisconnected
 STR     R10,[R11,#data_Status]
 B       Seq_SoundService_End

Seq_SoundService_ShareSoundStarting
 CMP     R0,#6
 BNE     Seq_SoundService_ShareSoundDying
 TST     R10,#seq_status_handlersharedsound
 TSTNE   R10,#seq_status_handlerdisconnected
 BEQ     Seq_SoundService_End
 BL      Seq_SetHardVoices
 B       Seq_SoundService_End

Seq_SoundService_ShareSoundDying
 CMP     R0,#7
 BNE     Seq_SoundService_End
 TST     R10,#seq_status_handlersharedsound
 BEQ     Seq_SoundService_End
 ORR     R10,R10,#seq_status_handlerdisconnected
 STR     R10,[R11,#data_Status]
 MOV     R10,#0
 STR     R10,[R11,#data_SharedSoundHandler]

Seq_SoundService_End
 _ENDPROC

;-------------------------------------------------------------------------------
; SWI Configure Seq part
;
; In  - R0  code
;       R1  value
;       R12 global memory ptr
;
; Out - R1  current value
;-------------------------------------------------------------------------------
 ALIGN

Seq_Configure _FNAME
 CMP     R0,#255
 BEQ     Seq_GetAGC
 CMP     R0,#254
 BEQ     Seq_EnableWAVFilling
 CMP     R0,#253
 BEQ     Seq_GetStatus
 CMP     R0,#(Seq_Configure_tableend-Seq_Configure_tablestart)/4
 ADDCC   PC,PC,R0,LSL#2
 B       Seq_Configure_tableend
Seq_Configure_tablestart
 B       Seq_HardwareSpeed
 B       Seq_InterpolMode
 B       Seq_Balance
 B       Seq_StereoSeparation
 B       Seq_Disable16bitMode
 B       Seq_HardwareFreq
 B       Seq_EqualizerBands
 B       Seq_EqualizerParams
 B       Seq_AGCMode
 B       Seq_MixScaling
 B       Seq_Interrupts
 B       Seq_DisableITFilters
 B       Seq_MixMono
 B       Seq_Polyphony
 B       Seq_EqualizerMode
Seq_Configure_tableend
 _ERRSWI unknown_configure_code
unknown_configure_code
 DCD     1
 = "Unknown Configuration code",0

;-------------------------------------------------------------------------------
; Seq_HardwareSpeed
;
; In  - R1  new hardware speed in us, <= 0 to read
;       R12 global memory ptr
;
; Out - R1  current hardware speed
;-------------------------------------------------------------------------------
 ALIGN

Seq_HardwareSpeed _FNAME
 _DEFPROCV "R0,R2-R4,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 SWI     XOS_IntOff
 CMP     R1,#0
 BLE     Seq_HardwareSpeed_End
 CMP     R1,#24
 MOVLT   R1,#24
 CMP     R1,#72
 MOVGT   R1,#72
 BIC     R1,R1,#7
 STR     R1,[R11,#data_Quality]
 LDR     R0,[R11,#data_Status]
 BIC     R0,R0,#seq_status_16bitconfig
 STR     R0,[R11,#data_Status]
 TST     R0,#seq_status_activehandler
 BEQ     Seq_HardwareSpeed_End
 BL      Seq_SetSampleRate
 BL      Seq_ResetMixingLimits

Seq_HardwareSpeed_End
 SWI     XOS_IntOn
 LDR     R1,[R11,#data_Quality]

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_InterpolMode
;
; In  - R1  1 on, 0 off, -1 read
;       R12 global memory ptr
;
; Out - R1  current status
;-------------------------------------------------------------------------------
 ALIGN

Seq_InterpolMode _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_InterpolMode_Read
 ORREQ   R0,R0,#seq_status_interpol
 BICNE   R0,R0,#seq_status_interpol
 STR     R0,[R11,#data_Status]
 BL      Seq_ResetMixingLimits

Seq_InterpolMode_Read
 TST     R0,#seq_status_interpol
 MOVNE   R1,#1
 MOVEQ   R1,#0

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Balance
;
; In  - R1  balance [left 0, right 255], 128 = center, -1 to read
;       R12 global memory ptr
;
; Out - R1  current balance
;-------------------------------------------------------------------------------
 ALIGN

Seq_Balance _FNAME
 _DEFPROCV "R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 CMP     R1,#0
 BLT     Seq_Balance_Read
 CMP     R1,#255
 BGT     Seq_Balance_Read
 STR     R1,[R11,#data_Balance]
 BL      Seq_ResetMixingLimits

Seq_Balance_Read
 LDR     R1,[R11,#data_Balance]

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_StereoSeparation
;
; In  - R1  stereo separation [-1024, 1024], 256 = normal, 1<<31 to read
;       R12 global memory ptr
;
; Out - R1  current stereo separation
;-------------------------------------------------------------------------------
 ALIGN

Seq_StereoSeparation _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 MOV     R0,#256*4
 CMP     R1,R0
 BGT     Seq_StereoSeparation_Read
 RSB     R0,R0,#0
 CMP     R1,R0
 BLT     Seq_StereoSeparation_Read
 STR     R1,[R11,#data_StereoSeparation]
 BL      Seq_ResetMixingLimits

Seq_StereoSeparation_Read
 LDR     R1,[R11,#data_StereoSeparation]

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Disable16bitMode
;
; In  - R1  1 on, 0 off, -1 read
;       R12 global memory ptr
;
; Out - R1 current status
;-------------------------------------------------------------------------------
 ALIGN

Seq_Disable16bitMode _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_Disable16bitMode_Read
 ORRNE   R0,R0,#seq_status_16bit
 BICEQ   R0,R0,#seq_status_16bit
 ; reset 16bit mode if no relevant hardware
 TST     R0,#seq_status_16bitpresent
 BICEQ   R0,R0,#seq_status_16bit
 STR     R0,[R11,#data_Status]

Seq_Disable16bitMode_Read
 TST     R0,#seq_status_16bit
 MOVEQ   R1,#1
 MOVNE   R1,#0
 TST     R0,#seq_status_16bitpresent
 MOVEQ   R1,#1

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_HardwareFreq
;
; In  - R1  new hardware frequency (Hz), <= 0 to read
;       R12 global memory ptr
;
; Out - R1  current frequency (Hz)
;-------------------------------------------------------------------------------
 ALIGN

Seq_HardwareFreq _FNAME
 _DEFPROCV "R0,R2-R4,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 SWI     XOS_IntOff
 CMP     R1,#0
 BLE     Seq_HardwareFreq_End
 ; find freq index corresponding to freq
 MOV     R4,R1
 ; read number of available freqs
 MOV     R0,#0
 SWI     XSound_SampleRate
 ; loop on index table
 MOV     R3,R1
 MOV     R1,#1
Seq_HardwareFreq_Loop
 MOV     R0,#2
 SWI     XSound_SampleRate
 CMP     R4,R2,LSR #10
 BLE     Seq_HardwareFreq_Loop_End
 ADD     R1,R1,#1
 CMP     R1,R3
 BLE     Seq_HardwareFreq_Loop
 MOV     R1,R3

Seq_HardwareFreq_Loop_End
 ; save found index
 STR     R1,[R11,#data_FreqIndex]
 LDR     R0,[R11,#data_Status]
 ORR     R0,R0,#seq_status_16bitconfig
 STR     R0,[R11,#data_Status]
 TST     R0,#seq_status_activehandler
 BEQ     Seq_HardwareFreq_End

 BL      Seq_SetSampleRate
 BL      Seq_ResetMixingLimits

Seq_HardwareFreq_End
 SWI     XOS_IntOn
 LDR     R1,[R11,#data_FreqIndex]
 MOV     R0,#2
 SWI     XSound_SampleRate
 MOV     R1,R2,LSR #10

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_EqualizerBands
;
; In  - R1  nr of bands, -1 to read
;       R12 global memory ptr
;
; Out - R1  nr of bands
;-------------------------------------------------------------------------------
 ALIGN

Seq_EqualizerBands _FNAME
 _DEFPROCV "R0,R2-R4,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 CMP     R1,#Max_Equalizers
 BHI     Seq_EqualizerBands_Read

 ; don't allow equalizer on CPU that doesn't support SMLA
 LDR     R0,[R11,#data_Status]
 TST     R0,#seq_status_SMLASupport
 BEQ     Seq_EqualizerBands_Read

 STR     R1,[R11,#data_EqualNr]

Seq_EqualizerBands_Read
 LDR     R1,[R11,#data_EqualNr]
 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_HardwareParams
;
; In  - R1  band nr
;       R2  c0
;       R3  c2
;       R4  d1
;       R5  d2
;       R6  a
;       R12 global memory ptr
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_EqualizerParams _FNAME
 _DEFPROCV "R0-R1,R10-R11"
 LDR     R11,[R12,#glbmem_seqdataptr]
 ANDS    R10,R1,#&80000000
 BIC     R1,R1,#&80000000
 CMP     R1,#Max_Equalizers
 BHS     Seq_EqualizerParams_End

 MOV     R0,#size_bandpass
 MUL     R1,R0,R1
 ADD     R0,R11,#data_EqualPars
 ADD     R0,R0,R1

 CMP     R10,#0
 BEQ     Seq_EqualizerParams_Write

 ; read params
 LDMIA   R0,{R2-R6}
 _ENDPROC

Seq_EqualizerParams_Write
 ; store params
 STMIA   R0!,{R2-R6}
 ; reset internal state (reinjected output values)
 _PUSH   "R1-R4"
 MOV     R1,#0
 MOV     R2,#0
 MOV     R3,#0
 MOV     R4,#0
 STMIA   R0!,{R1-R4}
 STMIA   R0!,{R1-R4}
 _PULL   "R1-R4"

Seq_EqualizerParams_End
 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_EnableWAVFilling
;
; In  - R1  1 enable, 0 disable, -1 read
;       R12 global memory ptr
;
; Out - R1  current status
;-------------------------------------------------------------------------------
 ALIGN

Seq_EnableWAVFilling _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_EnableWAVFilling_Read
 ORREQ   R0,R0,#seq_status_WAVFilling
 BICNE   R0,R0,#seq_status_WAVFilling
 STR     R0,[R11,#data_Status]

Seq_EnableWAVFilling_Read
 TST     R0,#seq_status_WAVFilling
 MOVNE   R1,#1
 MOVEQ   R1,#0

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_AGCMode
;
; In  - R1  1 full scale only, 0 normal, -1 read
;       R12 global memory ptr
;
; Out - R1  current status
;-------------------------------------------------------------------------------
 ALIGN

Seq_AGCMode _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_AGCMode_Read
 ORREQ   R0,R0,#seq_status_fullscaleAGC
 BICNE   R0,R0,#seq_status_fullscaleAGC
 STR     R0,[R11,#data_Status]
 BL      Seq_ResetMixingLimits

Seq_AGCMode_Read
 TST     R0,#seq_status_fullscaleAGC
 MOVNE   R1,#1
 MOVEQ   R1,#0

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_MixScaling
;
; In  - R1  1 full scale only, 0 normal, -1 read
;       R12 global memory ptr
;
; Out - R1  current status
;-------------------------------------------------------------------------------
 ALIGN

Seq_MixScaling _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_MixScaling_Read
 ORREQ   R0,R0,#seq_status_mixnorescale
 BICNE   R0,R0,#seq_status_mixnorescale
 STR     R0,[R11,#data_Status]
 BL      Seq_SetMixScale

Seq_MixScaling_Read
 TST     R0,#seq_status_mixnorescale
 MOVNE   R1,#1
 MOVEQ   R1,#0

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Interrupts
;
; In  - R1  1 on, 0 off, -1 read
;       R12 global memory ptr
;
; Out - R1 current status
;-------------------------------------------------------------------------------
 ALIGN

Seq_Interrupts _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_Interrupts_Read
 ORREQ   R0,R0,#seq_status_enableinterrupts
 BICNE   R0,R0,#seq_status_enableinterrupts
 STR     R0,[R11,#data_Status]

Seq_Interrupts_Read
 TST     R0,#seq_status_enableinterrupts
 MOVNE   R1,#1
 MOVEQ   R1,#0

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_DisableITFilters
;
; In  - R1  1 on, 0 off, -1 read
;       R12 global memory ptr
;
; Out - R1 current status
;-------------------------------------------------------------------------------
 ALIGN

Seq_DisableITFilters _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_DisableITFilters_Read
 ORREQ   R0,R0,#seq_status_disable_ITFilters
 BICNE   R0,R0,#seq_status_disable_ITFilters
 STR     R0,[R11,#data_Status]

Seq_DisableITFilters_Read
 TST     R0,#seq_status_disable_ITFilters
 MOVNE   R1,#1
 MOVEQ   R1,#0

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_MixMono
;
; In  - R1  1 on, 0 off, -1 read
;       R12 global memory ptr
;
; Out - R1 current status
;-------------------------------------------------------------------------------
 ALIGN

Seq_MixMono _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_MixMono_Read
 ORREQ   R0,R0,#seq_status_mix_mono
 BICNE   R0,R0,#seq_status_mix_mono
 STR     R0,[R11,#data_Status]

Seq_MixMono_Read
 TST     R0,#seq_status_mix_mono
 MOVNE   R1,#1
 MOVEQ   R1,#0

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Polyphony
;
; In  - R1  [4, 128], -1 read
;       R12 global memory ptr
;
; Out - R1 current value
;       R2 max value
;-------------------------------------------------------------------------------
 ALIGN

Seq_Polyphony _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 CMP     R1,#4
 BMI     Seq_Polyphony_Read
 CMP     R1,#seq_max_streams
 BHI     Seq_Polyphony_Read

 STR     R1,[R11,#data_Polyphony]
 STR     R1,[R11,#data_MaxNrOfStreams]

Seq_Polyphony_Read
 LDR     R1,[R11,#data_Polyphony]
 MOV     R2,#seq_max_streams

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_EqualizerMode
;
; In  - R1  1 serial, 0 parallel, -1 read
;       R12 global memory ptr
;
; Out - R1  current mode
;-------------------------------------------------------------------------------
 ALIGN

Seq_EqualizerMode _FNAME
 _DEFPROCV "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Status]

 CMP     R1,#1
 BHI     Seq_EqualizerMode_Read
 ORREQ   R0,R0,#seq_status_equalizer_serial
 BICNE   R0,R0,#seq_status_equalizer_serial
 STR     R0,[R11,#data_Status]

Seq_EqualizerMode_Read
 TST     R0,#seq_status_equalizer_serial
 MOVNE   R1,#1
 MOVEQ   R1,#0

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_GetPlayingFrequency
;
; In  - R12 global memory ptr
;
; Out - R0  Frequency in Hz (calculated from last buffer filling interrupt)
;-------------------------------------------------------------------------------
 ALIGN
Seq_GetPlayingFrequency _FNAME
 _DEFPROC "R1-R4,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]
 MOV     R1,#0
 MOV     R2,#1<<8
 LDR     R3,[R11,#data_TimeStep]
 _UDIV64 R0,R1,R2,R3,R4 ; 2^40/data_TimeStep
 _ENDPROC

BasePeriod
 DCD     256000000

;-------------------------------------------------------------------------------
; Seq_GetAGC
;
; In  - R12 global memory ptr
;
; Out - R1  AGC
;       R2  Max AGC
;       R3  Wave percentage
;-------------------------------------------------------------------------------
 ALIGN

Seq_GetAGC _FNAME
 _DEFPROC "R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R1,[R11,#data_AGC]
 LDR     R2,[R11,#data_MaxAGC]
 BL      Seq_CalcWavePercentage
 LDR     R3,[R11,#data_WavePercentage]

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_GetStatus
;
; In  - R12 global memory ptr
;
; Out - R1  Status
;-------------------------------------------------------------------------------
 ALIGN

Seq_GetStatus _FNAME
 _DEFPROC "R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R1,[R11,#data_Status]

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_CalcWavePercentage
;
; In  - R12 global memory ptr
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_CalcWavePercentage _FNAME
 _DEFPROC "R3-R6,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 ; build max allowed applification
 MOV     R3,#100
 LDR     R5,[R11,#data_MaxWave]
 CMP     R5,#16
 _ENDPROC LS
 LDR     R6,[R11,#data_MaxReadWave]
 CMP     R6,R5,LSR #3
 MOVLO   R6,R5,LSR #3
 MUL     R5,R3,R5
 _DIVIDE R3,R5,R6,R4
 LDR     R4,[R11,#data_WavePercentage]
 CMP     R3,R4
 STRLT   R3,[R11,#data_WavePercentage]

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_RegisterHandler
;
; In  - R0  Handler
;        R0 + 0 stream lister
;        R0 + 4 stream updater
;        R0 + 8 max nr of streams
;        R0 + C volume
;       R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------

 ALIGN
Err_TooManyHandlers
 DCD     1
 = "Too many registered stream handlers",0

 ALIGN
Seq_RegisterHandler _FNAME
 _DEFPROCV "R1-R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R1,[R11,#data_Stream_NrOfHandlers]
 CMP     R1,#seq_max_handlers
 _ERROR  GT,Err_TooManyHandlers

 SWI     XOS_IntOff
 ADD     R2,R11,#data_Stream_Handlers
 STR     R0,[R2,R1,LSL #2]
 ADD     R1,R1,#1
 STR     R1,[R11,#data_Stream_NrOfHandlers]
 BL      Seq_SetHardVoices
 SWI     XOS_IntOn

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_UnregisterHandler
;
; In  - R0  Handler
;       R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_UnregisterHandler _FNAME
 _DEFPROC "R0-R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R3,[R11,#data_Stream_NrOfHandlers]
 CMP     R3,#0
 _ENDPROC LE
 ; find handler in list
 ADD     R1,R11,#data_Stream_Handlers
 SUB     R2,R3,#1
Seq_UnregisterHandler_Loop
 LDR     R4,[R1],#4
 CMP     R0,R4
 BEQ     Seq_UnregisterHandler_RemoveHandler
 SUBS    R2,R2,#1
 BGE     Seq_UnregisterHandler_Loop

 ; not found
 _ENDPROC

 ; found
Seq_UnregisterHandler_RemoveHandler
 SWI     XOS_IntOff
 ; move end of list one up
 SUB     R0,R1,#4
 MOV     R2,R2,LSL #2
 BL      Mem_FastMove
 ; decrease counter
 SUB     R3,R3,#1
 STR     R3,[R11,#data_Stream_NrOfHandlers]
 MOV     R0,#0
 ADD     R1,R11,#data_Stream_Handlers
 STR     R0,[R1,R3,LSL #2]
 ; reset number of streams
 MOV     R0,#0
 STR     R0,[R11,#data_MaxNrOfStreamsSeen]
 ; maybe reset AGC
 CMP     R3,#0
 MOVEQ   R3,#AGC_MaxVal
 STREQ   R3,[R11,#data_AGC]
 STREQ   R3,[R11,#data_MaxAGC]
 ; update voices and mix scale
 BL      Seq_SetHardVoices
 SWI     XOS_IntOn

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_SetSampleRate
;
; In  - R12 global memory ptr
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_SetSampleRate _FNAME
 _DEFPROCV "R0-R4,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R4,[R11,#data_Status]

 ; alter frequency
 TST     R4,#seq_status_handlerWAV
 BNE     Seq_SetSampleRate_End

 TST     R4,#seq_status_handlersharedsound
 BEQ     Seq_SetSampleRate_DMA

Seq_SetSampleRate_SharedSound
 MOV     R0,#2
 LDR     R1,[R11,#data_FreqIndex]
 SWI     XSound_SampleRate
 MOV     R1,R2
 MOV     R0,#0
 SWI     XSharedSound_SampleRate
 ; work around a bug in SharedSound
 MOV     R0,#0
 MOV     R1,#0
 SWI     XSharedSound_SampleRate
 B       Seq_SetSampleRate_End

Seq_SetSampleRate_DMA
 TST     R4,#seq_status_handlerDMA8bit
 BNE     Seq_SetSampleRate_DMA_8bit

 TST     R4,#seq_status_16bitconfig
 BEQ     Seq_SetSampleRate_DMA_8bit

Seq_SetSampleRate_DMA_16bit
 MOV     R0,#3
 LDR     R1,[R11,#data_FreqIndex]
 SWI     XSound_SampleRate
 B       Seq_SetSampleRate_End

Seq_SetSampleRate_DMA_8bit
 MOV     R0,#0
 MOV     R1,#0
 LDR     R2,[R11,#data_Quality]
 MOV     R3,#0
 MOV     R4,#0
 SWI     XSound_Configure

Seq_SetSampleRate_End

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_GetSampleSize
;
; In  - R12 global memory pointer
;
; Out - R0  sample monitoring size
;-------------------------------------------------------------------------------

 ALIGN
Seq_GetSampleSize _FNAME
 LDR     R0,[R12,#glbmem_seqdataptr]
 LDR     R0,[R0,#data_SampleSize]
 MOV     PC,R14

;-------------------------------------------------------------------------------
; Seq_ResetMaxWavePercentage
;
; In  - R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------

 ALIGN
Seq_ResetMaxWavePercentage _FNAME
 _DEFPROC "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]
 MOV     R0,#1<<16 ; high enough value
 STR     R0,[R11,#data_WavePercentage]
 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_GetMixingInfo
;
; In  - R12 global memory pointer
;
; Out - R0 CPU usage in 1/1000
;       R1 Max CPU value encountred so far
;       R2 Number of sample mixed
;       R3 Max number of sample mixed so far
;       R4 Max number of sample limit
;-------------------------------------------------------------------------------
 ALIGN

Seq_GetMixingInfo _FNAME
 LDR     R4,[R12,#glbmem_seqdataptr]
 LDR     R0,[R4,#data_Filler_CPU]
 LDR     R1,[R4,#data_Filler_MaxCPU]
 LDR     R2,[R4,#data_NrOfStreams]
 LDR     R3,[R4,#data_MaxNrOfStreamsSeen]
 LDR     R4,[R4,#data_MaxNrOfStreams]
 MOV     PC,R14

;-------------------------------------------------------------------------------
; Seq_ResetMixingLimits
;
; In  - R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------

Seq_ResetMixingLimits _FNAME
 _DEFPROC "R0,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 LDR     R0,[R11,#data_Polyphony]
 STR     R0,[R11,#data_MaxNrOfStreams]
 ; reset CPU max
 MOV     R0,#0
 STR     R0,[R11,#data_Filler_MaxCPU]

 _ENDPROC

;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------

;-------------------------------------------------------------------------------
; Seq_ResetTimer
;
; In - R12 seq data ptr !!!
;
; Out -
;-------------------------------------------------------------------------------

Seq_ResetTimer _FNAME
 _DEFPROC "R0-R3,R8-R9,R11"
 LDR     R0,[R12,#data_TimerType]
 CMP     R0,#(Seq_ResetTimer_tableend-Seq_ResetTimer_tablestart)
 ADDCC   PC,PC,R0,LSL#2
 B       Seq_ResetTimer_tableend
Seq_ResetTimer_tablestart
 B       Seq_ResetTimer_tableend
 B       Seq_ResetTimer_IOC
 B       Seq_ResetTimer_HAL
Seq_ResetTimer_tableend
 _ENDPROC

Seq_ResetTimer_IOC
 MOV     R0,#&03200000
 MOV     R1,#&FF
 STRB    R1,[R0,#&50]
 STRB    R1,[R0,#&54]
 STRB    R1,[R0,#&58]
 _ENDPROC
Seq_ResetTimer_HAL
 MOV     R0,#0
 MOV     R8,#0
 MOV     R9,#21
 SWI     XOS_Hardware
 STR     R0,[R12,#data_TimerStartValue]
 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_GetTimer
;
; In  - R12 seq data ptr !!!
;
; Out - R0 timer
;-------------------------------------------------------------------------------
 ALIGN

Seq_GetTimer _FNAME
 _DEFPROC "R1-R3,R8-R9,R11"
 LDR     R0,[R12,#data_TimerType]
 CMP     R0,#(Seq_GetTimer_tableend-Seq_GetTimer_tablestart)
 ADDCC   PC,PC,R0,LSL#2
 B       Seq_GetTimer_tableend
Seq_GetTimer_tablestart
 B       Seq_GetTimer_tableend
 B       Seq_GetTimer_IOC
 B       Seq_GetTimer_HAL
Seq_GetTimer_tableend
 MOV     R0,#0
 _ENDPROC

Seq_GetTimer_IOC
 MOV     R0,#&03200000
 STRB    R1,[R0,#&5C]
 LDRB    R1,[R0,#&50]
 LDRB    R2,[R0,#&54]
; LDR     R0,Seq_IOCTimer
 ADD     R0,R1,R2,LSL #8
 RSB     R0,R0,#&00010000
; ADD     R0,R0,R2
 _ENDPROC

Seq_GetTimer_HAL
 MOV     R0,#0
 MOV     R8,#0
 MOV     R9,#21
 SWI     XOS_Hardware
 LDR     R1,[R12,#data_TimerStartValue]
 SUBS    R0,R1,R0
 LDRLE   R1,[R12,#data_TimerPeriod]
 ADDLE   R0,R0,R1
 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_GetTime
;
; In  - R12 global memory pointer
;
; Out - R0 monotonic time (in cs)
;       R1 timer
;       R2 timer frequency
;       R3 timer period
;-------------------------------------------------------------------------------
 ALIGN

Seq_GetTime _FNAME
 _DEFPROC "R4-R11"
 LDR     R11,[R12,#glbmem_seqdataptr]
 LDR     R0,[R11,#data_TimerType]
 CMP     R0,#(Seq_GetTime_tableend-Seq_GetTime_tablestart)
 ADDCC   PC,PC,R0,LSL#2
 B       Seq_GetTime_None
Seq_GetTime_tablestart
 B       Seq_GetTime_None
 B       Seq_GetTime_IOC
 B       Seq_GetTime_HAL
Seq_GetTime_tableend

Seq_GetTime_None
 MOV     R1,#0
 MOV     R2,#100
 MOV     R3,#1
 B       Seq_GetTime_Monotonic

Seq_GetTime_IOC
 MOV     R0,#&03200000
 STRB    R1,[R0,#&4C]
 LDRB    R1,[R0,#&40]
 LDRB    R2,[R0,#&44]
 ADD     R1,R1,R2,LSL #8
 LDR     R2,[R11,#data_TimerTicksPerSec]
 LDR     R3,=20000
; For some reason OSMonotonicTime give me problems on the RISC PC.
; Sucessive calls to this routine from seems to give at least a 2cs
; difference. It is not releated to the timer0 read as it occurs even
; when timer0 code is commented.
; B       Seq_GetTime_Monotonic
 MOV     R0,#0
 _ENDPROC

Seq_GetTime_HAL
 MOV     R0,#0
 MOV     R8,#0
 MOV     R9,#21
 SWI     XOS_Hardware
 MOV     R1,R0
 LDR     R2,[R11,#data_TimerTicksPerSec]
 LDR     R3,[R11,#data_TimerPeriod]

Seq_GetTime_Monotonic
 SWI     XOS_ReadMonotonicTime
 MOVVS   R0,#0
 _ENDPROC
 LTORG

;-------------------------------------------------------------------------------
; Seq_SetPanning
;
; In  - R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_SetPanning _FNAME
 _DEFPROC "R0-R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 MOV     R10,#2
 MOV     R0,#1
 MOV     R1,#127

Seq_SetPanning_Loop
 RSB     R1,R1,#0
 _TOSVC   R8,R9
 _PUSH   "R1"
 SWI     XSound_Stereo
 _PULL   "R1"
 _FROMSVC
 ADD     R0,R0,#1
 CMP     R10,R0
 BGE     Seq_SetPanning_Loop

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_SetHardVoices
;
; In  - R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------

 ALIGN
Const_SharedSound
 = "SharedSound",0

 ALIGN
Seq_SetHardVoices _FNAME
 _DEFPROC "R0-R11"

 ; R11 seq header
 ; R10 seq status
 LDR     R11,[R12,#glbmem_seqdataptr]
 LDR     R10,[R11,#data_Status]

 ; Do this before values changes
 BL      Seq_CalcWavePercentage

 ; Reset user amplification info
 MOV     R0,#0
 STR     R0,[R11,#data_MaxReadWave]

 ; Register handler?
 LDR     R1,[R11,#data_Stream_NrOfHandlers]
 CMP     R1,#0
 BLE     Seq_SetVoices_Release

 ; Yes, update DMA config

Seq_SetVoices_Register

 ; Reset handler info
 BIC     R10,R10,#seq_status_handlermask

 ; Yes, determine mix scale
 BL      Seq_SetMixScale

 TST     R10,#seq_status_WAVFilling
 BNE     Seq_SetVoices_Register_WAV
 TST     R10,#seq_status_16bit
 BNE     Seq_SetVoices_Register_SharedSound

 ; Check for SharedSound 1.03 or later
 ; Get pointer to module help string
 MOV     R0,#18
 ADR     R1,Const_SharedSound
 SWI     XOS_Module
 BVS     Seq_SetVoices_Register_DMA8bit
 LDR     R0,[R3,#&14]
 ADD     R3,R3,R0
 ; Skip characters till TAB
Seq_SetVoices_Help_Loop
 LDRB    R0,[R3],#1
 CMP     R0,#32
 BGE     Seq_SetVoices_Help_Loop
 CMP     R0,#9   ; TAB
 BNE     Seq_SetVoices_Register_DMA8bit
 LDRB    R0,[R3,#1]
 CMP     R0,#&2E ; '.'
 BNE     Seq_SetVoices_Register_DMA8bit
 ; Extract version
 LDRB    R0,[R3,#0]
 SUB     R0,R0,#&30
 MOV     R1,#10
 MUL     R2,R0,R1
 LDRB    R0,[R3,#2]
 SUB     R0,R0,#&30
 ADD     R0,R0,R2
 MUL     R2,R0,R1
 LDRB    R0,[R3,#3]
 SUB     R0,R0,#&30
 ADD     R0,R0,R2
 CMP     R0,#103
 BLT     Seq_SetVoices_Register_DMA8bit
 B       Seq_SetVoices_Register_SharedSound

Seq_SetVoices_Register_WAV
 ORR     R10,R10,#seq_status_handlerWAV
 ; disable timing
 MOV     R0,#TimerType_None
 STR     R0,[R11,#data_TimerType]
 B       Seq_SetVoices_Register_End

Seq_SetVoices_Register_SharedSound
 ADRL    R0,Seq_Filler_SharedSound
 MOV     R1,R11
 MOV     R2,#1
 LDR     R3,[R12,#glbmem_modnameptr]
 MOV     R4,#0
 SWI     XSharedSound_InstallHandler
 BVS     Seq_SetVoices_Register_DMA16bit
 STR     R0,[R11,#data_SharedSoundHandler]

 ORR     R10,R10,#seq_status_handlersharedsound
 B       Seq_SetVoices_Register_End

Seq_SetVoices_Register_DMA16bit
 STR     R10,[R11,#data_Status]
 MOV     R0,#1
 ADRL    R1,Seq_Filler16
 MOV     R2,R11
 SWI     XSound_LinearHandler
 BVS     Seq_SetVoices_Register_DMA8bit
 ADRL    R5,Seq_Filler16
 CMP     R1,R5
 ADDNE   R5,R11,#data_DMAConfig
 STMNEIA R5,{R1-R2}

 ORR     R10,R10,#seq_status_handlerDMA16bit
 B       Seq_SetVoices_Register_End

Seq_SetVoices_Register_DMA8bit
 ; configure sound
 MOV     R0,#2
 MOV     R1,#0;seq_hard_buf_len
 LDR     R2,[R11,#data_Quality]
 ADD     R3,R12,#glbmem_8bit_handler
 MOV     R4,#0
 SWI     XSound_Configure
 ADD     R5,R12,#glbmem_8bit_handler
 CMP     R5,R3
 ADDNE   R5,R11,#data_DMAConfig
 STMNEIA R5,{R0-R4}
 BL      Seq_SetPanning

 ORR     R10,R10,#seq_status_handlerDMA8bit
 B       Seq_SetVoices_Register_End

Seq_SetVoices_Register_End
 ORR     R10,R10,#seq_status_activehandler
 STR     R10,[R11,#data_Status]

 BL      Seq_SetSampleRate
 B       Seq_SetVoices_End

 ;-------------------------------------------
 ; No, release handler and restore old config

Seq_SetVoices_Release

 ; Have we a registred handler
 TST     R10,#seq_status_activehandler
 BEQ     Seq_SetVoices_End

 ; Yes, wait for filler to clear buffers
 MOV     R0,#19
 SWI     XOS_Byte ; Wait
 SWI     XOS_Byte ; Wait

 TST     R10,#seq_status_handlerWAV
 BNE     Seq_SetVoices_Release_WAV
 TST     R10,#seq_status_handlersharedsound
 BNE     Seq_SetVoices_Release_SharedSound
 TST     R10,#seq_status_handlerDMA16bit
 BNE     Seq_SetVoices_Release_DMA16bit

Seq_SetVoices_Release_DMA8bit
 ; Are we still in control?  (someone may have taken control from us)
 MOV     R0,#0
 MOV     R1,#0
 MOV     R2,#0
 MOV     R3,#0
 MOV     R4,#0
 SWI     XSound_Configure
 ADD     R0,R12,#glbmem_8bit_handler
 CMP     R0,R3
 BNE     Seq_SetVoices_Release_End;DMA8bit_End
 ; Restore old handler and config
 ADD     R5,R11,#data_DMAConfig
 LDMIA   R5,{R0-R4}
 SWI     XSound_Configure
Seq_SetVoices_Release_DMA8bit_End
 MOV     R0,#0
 MOV     R1,#0
 MOV     R2,#0
 MOV     R3,#0
 MOV     R4,#0
 STMIA   R5,{R0-R4}
 B       Seq_SetVoices_Release_End

Seq_SetVoices_Release_WAV
 B       Seq_SetVoices_Release_End

Seq_SetVoices_Release_SharedSound
 LDR     R0,[R11,#data_SharedSoundHandler]
 CMP     R0,#0
 SWINE   XSharedSound_RemoveHandler
 B       Seq_SetVoices_Release_End

Seq_SetVoices_Release_DMA16bit
 ; Still us in command?
 MOV     R0,#0
 SWI     XSound_LinearHandler
 ADR     R2,Seq_Filler16
 CMP     R1,R2
 BNE     Seq_SetVoices_Release_DMA16bit_End
 MOV     R0,#1
 ADD     R5,R11,#data_DMAConfig
 LDMIA   R5,{R1-R2}
 SWI     XSound_LinearHandler
Seq_SetVoices_Release_DMA16bit_End
 MOV     R1,#0
 MOV     R2,#0
 STMIA   R5,{R1-R2}

Seq_SetVoices_Release_End
 ; Mark that no handler is active
 BIC     R10,R10,#seq_status_handlermask
 STR     R10,[R11,#data_Status]
 MOV     R0,#0
 STR     R0,[R11,#data_Filler_CPU]

Seq_SetVoices_End
 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_SetMixScale
;
; In  - R12 global memory pointer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_SetMixScale _FNAME
 _DEFPROC "R0-R7,R11"
 LDR     R11,[R12,#glbmem_seqdataptr]

 ; count voices
 LDR     R0,[R11,#data_Stream_NrOfHandlers]
 CMP     R0,#0
 _ENDPROC LE

 ; do this before values changes
 BL      Seq_CalcWavePercentage

 ADD     R1,R11,#data_Stream_Handlers

 LDR     R2,[R11,#data_Status]
 TST     R2,#seq_status_mixnorescale
 BNE     Seq_SetMixScaleNoRescale

 ; R2 total nr of streams
 ; R3 total of streams*volumes
 MOV     R2,#0
 MOV     R3,#0

Seq_SetMixScale_Loop
 LDR     R4,[R1],#4
 LDR     R5,[R4,#shandler_maxstreams]
 LDR     R6,[R4,#shandler_volume]
 ADD     R2,R2,R5
 MLA     R3,R5,R6,R3
 SUBS    R0,R0,#1
 BGT     Seq_SetMixScale_Loop

Seq_SetMixScale_Loop_End
 CMP     R2,#0
 _ENDPROC LE

 ; (&7fff * mean volume)/max volume
 MOV     R6,#&7F00
 ORR     R6,R6,#&FF
 MOV     R0,R6
 MOV     R1,R2
 _DIVIDE R4,R0,R1,R5
 MUL     R3,R4,R3
 MOV     R3,R3,LSR #8
 ADD     R3,R3,#1 ; allow some imprecision
 CMP     R3,#16
 MOVLT   R3,#0
 CMP     R3,R6
 STRLT   R3,[R11,#data_MaxWave]
 STRGE   R6,[R11,#data_MaxWave]
 MOV     R0,#1
 STR     R0,[R11,#data_MaxReadWave]

 MOV     R0,#&10000
 LDR     R1,[R11,#data_Stream_NrOfHandlers]
 _DIVIDE R4,R0,R1,R5
Seq_SetMixScale_Store
 STR     R4,[R11,#data_Filler_Mix_Scale]

 _ENDPROC

Seq_SetMixScaleNoRescale
 MOV     R6,#&7F00
 ORR     R6,R6,#&FF
 STR     R6,[R11,#data_MaxWave]

Seq_SetMixScaleNoRescale_Loop
 LDR     R4,[R1],#4
 LDR     R2,[R4,#shandler_maxstreams]
 LDR     R3,[R4,#shandler_volume]
 CMP     R2,#0
 BLE     Seq_SetMixScaleNoRescale_Next
 MUL     R3,R2,R3

 ; (&7fff * mean volume)/max volume
 MOV     R7,R6
 _DIVIDE R4,R7,R2,R5
 MUL     R3,R4,R3
 MOV     R3,R3,LSR #8
 ADD     R3,R3,#1 ; allow some imprecision
 CMP     R3,#16
 MOVLT   R3,#0
 LDR     R7,[R11,#data_MaxWave]
 CMP     R3,R7
 STRLT   R3,[R11,#data_MaxWave]

Seq_SetMixScaleNoRescale_Next
 SUBS    R0,R0,#1
 BGT     Seq_SetMixScaleNoRescale_Loop

 MOV     R0,#1
 STR     R0,[R11,#data_MaxReadWave]

 MOV     R4,#&10000
 STR     R4,[R11,#data_Filler_Mix_Scale]

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Filler_8bit_Dynamic
;
; In  - R10 DMA buffer end
;       R11 number of channels/step between values
;       R12 DMA buffer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Const_QualityFactor
 DCD     1099512 ; 2^40/1000000

; dynamic routine copied into RMA workspace
Seq_Filler_8bit_Dynamic
Seq_Filler_8bit_Dynamic_R12
 DCD     0
Seq_Filler_8bit_Dynamic_PC
 DCD     0
Seq_Filler_8bit_Dynamic_Routine
 MOV     R1,R12
 MOV     R2,R10
 LDR     R12,Seq_Filler_8bit_Dynamic_R12
 LDR     PC,Seq_Filler_8bit_Dynamic_PC
Seq_Filler_8bit_Dynamic_End

;-------------------------------------------------------------------------------
; Seq_Filler_8bit
;
; In  - R1  DMA buffer
;       R2  DMA buffer end
;       R11 number of channels/step between values
;       R12 seq data ptr
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_Filler_8bit _FNAME
 _DEFPROC

 ; fill sample rate info
 LDR     R4,[R12,#data_Quality]
 MOV     R5,R4,LSL #8
 STR     R5,[R12,#data_FineQuality]
 LDR     R5,Const_QualityFactor
 MUL     R5,R4,R5
 STR     R5,[R12,#data_TimeStep]

 ; set number of values to fill
 SUB     R9,R2,R1
 MOV     R9,R9,LSR #1

 ; check if the handler is as we defined, then call the filler
 CMP     R11,#2
 MOVEQ   R0,#0
 MOVNE   R0,#1
 MOV     R3,#0
 BL      Seq_Filler

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Filler_16bit
;
; In  - R0 parameter (R12)
;       R1 DMA buffer
;       R2 DMA buff end
;       R3 flags bits
;           0 If on mix, else overwrite
;       R4 sample rate 1/1024Hz
;
; Out - R11-R13 must be preserved
;
;       FineQuality = 256*1000000/Fmix
;       TimeStep    = 2^40/Fmix
;-------------------------------------------------------------------------------
 ALIGN

Seq_Filler16 _FNAME
 _DEFPROCS "R0-R2,R4-R12"

 ; R12 is seq data ptr
 MOV     R12,R0

 ; set number of values to fill
 SUB     R9,R2,R1
 MOV     R9,R9,LSR #2

 ; fill sample rate info
 MOV     R4,R4,LSR #10
 MOV     R5,#1<<30
 MOV     R6,R4
 _DIVIDE R7,R5,R6,R8
 MOV     R7,R7,LSL #10
 STR     R7,[R12,#data_TimeStep]
 MOV     R10,#&F400000
 ORR     R10,R10,#&24000
 _DIVIDE R5,R10,R4,R6
 STR     R5,[R12,#data_FineQuality]

 MOV     R0,#0
 BL      Seq_Filler

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Filler_WAV
;
; In  - R1 DMA buffer
;       R2 DMA buff end
;       R3 flags bits (unused)
;       R4 sample rate 1/1024Hz
;       R12 global memory pointer
;
; Out - All registers must be preserved
;
;       FineQuality = 256*1000000/Fmix
;       TimeStep    = 2^40/Fmix
;-------------------------------------------------------------------------------
 ALIGN

Seq_Filler_WAV _FNAME
 _DEFPROCS "R0-R12"

 ; R12 is seq data ptr
 LDR     R12,[R12,#glbmem_seqdataptr]

 SUB     R9,R2,R1
 MOV     R9,R9,LSR #2

 ; fill sample rate info
 MOV     R4,R4,LSR #10
 MOV     R5,#1<<30
 MOV     R6,R4
 _DIVIDE R7,R5,R6,R8
 MOV     R7,R7,LSL #10
 STR     R7,[R12,#data_TimeStep]
 MOV     R10,#&F400000
 ORR     R10,R10,#&24000
 _DIVIDE R5,R10,R4,R6
 STR     R5,[R12,#data_FineQuality]

 MOV     R0,#0
 MOV     R3,#0
 BL      Seq_Filler

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Filler_SharedSound
;
; In  - R0 parameter (R12)
;       R1 DMA buffer
;       R2 DMA buff end
;       R3 flags bits
;           0   If on mix, else overwrite
;           1   If set, interpol
;           3-7 0, No over-run
;               1-30, nr of over-runs
;               31, more than 30 over-runs
;           29  If set, invert stereo
;           30  If set, use volume in R7
;           31  If set, mute sound
;       R4 sample rate 1/1024Hz
;       R5 sample period
;       R6 fractionnal step
;       R7 LR volume
;
; Out - R11-R13 must be preserved
;       R3 updated on exit
;
;       FineQuality = 256*1000000/Fmix
;       TimeStep    = 2^40/Fmix
;-------------------------------------------------------------------------------
 ALIGN

Seq_Filler_SharedSound _FNAME
 _DEFPROCS "R0-R2,R4-R12"

 ; R12 is seq data ptr
 MOV     R12,R0

 SUB     R9,R2,R1
 MOV     R9,R9,LSR #2

 ; fill sample rate info
 MOV     R4,R4,LSR #10
 MOV     R5,#1<<30
 MOV     R6,R4
 _DIVIDE R7,R5,R6,R8
 MOV     R7,R7,LSL #10
 STR     R7,[R12,#data_TimeStep]
 MOV     R10,#&F400000
 ORR     R10,R10,#&24000
 _DIVIDE R5,R10,R4,R6
 STR     R5,[R12,#data_FineQuality]

 MOV     R0,#0
 BL      Seq_Filler

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_Filler
;
; In  - R0  0 OK, else no play
;       R1  DMA buffer
;       R2  DMA buff end
;       R3  flags bits
;       R9  Number of values to fill
;       R12 seq data ptr
;
; Out - R3  updated
;-------------------------------------------------------------------------------

Seq_Filler _FNAME
 _DEFPROC

 ; Fill only when playing

 CMP     R0,#0
 BNE     Seq_Filler_NoPlay

 LDR     R0,[R12,#data_Status]
 TST     R0,#seq_status_filling
 BNE     Seq_Filler_NoPlay
 ORR     R0,R0,#seq_status_filling
 STR     R0,[R12,#data_Status]

 TST     R0,#seq_status_handlerWAV
 BNE     Seq_Filler_ToSVCEnd

Seq_Filler_ToSVC
 ; Switch to SVC mode and enable interrupts
 _TOSVC   R4,R5
 _PUSH   "R4-R5"
 TST     R0,#seq_status_enableinterrupts
 SWINE   XOS_IntOn
Seq_Filler_ToSVCEnd

 BL      Seq_ResetTimer

 ; Fill 32-bit buffer

 LDR     R10,[R12,#data_Buffer32]
 BL      Seq_Filler_Play
 _PUSH   "R1-R3"

 ; Process with Equalizer

 LDR     R2,[R12,#data_EqualNr]
 CMP     R2,#0
 BLE     Seq_Filler_Equalizer_End
 LDR     R0,[R12,#data_Status]
 TST     R0,#seq_status_equalizer_serial
 BNE     Seq_Filler_Equalizer_Serial

 ; Parallel Equalizer, same input for all filters, output merged in new buffer
 LDR     R11,[R12,#data_Buffer32_Equ]
 MOV     R0,R11
 MOV     R1,R9,LSL #3
 BL      Mem_FastClear
 ADD     R0,R12,#data_EqualPars
Seq_Filler_BandPass_Loop
 BL      Seq_BandPass
 ADD     R0,R0,#size_bandpass
 SUBS    R2,R2,#1
 BGT     Seq_Filler_BandPass_Loop
 ; Use output buffer of Equalizer
 MOV     R10,R11
 B       Seq_Filler_Equalizer_End

 ; Serial Equalizer, input is output of previous filter
Seq_Filler_Equalizer_Serial
 ADD     R0,R12,#data_EqualPars
Seq_Filler_BandPass_SerialLoop
 BL      Seq_BandPass_Serial
 ADD     R0,R0,#size_bandpass
 SUBS    R2,R2,#1
 BGT     Seq_Filler_BandPass_SerialLoop

Seq_Filler_Equalizer_End

 ; Get max wave value and AGC

Seq_Filler_BuildAGC
 MOV     R0,R10
 MOV     R1,R0
 ADD     R2,R1,R9,LSL #3
 MOV     R3,#0
Seq_Filler_BuildAGC_Loop
 LDMIA   R1!,{R4-R11}
 ; A >= 0 ? A : -1-A is ~= ABS(A)
 EOR     R4,R4,R4,ASR #31
 EOR     R5,R5,R5,ASR #31
 EOR     R6,R6,R6,ASR #31
 EOR     R7,R7,R7,ASR #31
 EOR     R8,R8,R8,ASR #31
 EOR     R9,R9,R9,ASR #31
 EOR     R10,R10,R10,ASR #31
 EOR     R11,R11,R11,ASR #31
 CMP     R3,R4
 MOVLT   R3,R4
 CMP     R3,R5
 MOVLT   R3,R5
 CMP     R3,R6
 MOVLT   R3,R6
 CMP     R3,R7
 MOVLT   R3,R7
 CMP     R3,R8
 MOVLT   R3,R8
 CMP     R3,R9
 MOVLT   R3,R9
 CMP     R3,R10
 MOVLT   R3,R10
 CMP     R3,R11
 MOVLT   R3,R11
 CMP     R1,R2
 BLO     Seq_Filler_BuildAGC_Loop

 LDR     R4,[R12,#data_Status]
 TST     R4,#seq_status_fullscaleAGC
 LDREQ   R8,[R12,#data_MaxWave]
 MOVNE   R8,#&7F00
 ORRNE   R8,R8,#&FF
 LDR     R4,[R12,#data_MaxReadWave]
 CMP     R4,R3
 MOVLT   R4,R3
 STRLT   R4,[R12,#data_MaxReadWave]
 CMP     R3,R8
 MOVLT   R3,R8
 ; Invert value
 MOV     R4,R8
 CMP     R4,#0
 BEQ     Seq_Filler_ApplyAGC
 MOV     R4,R4,LSL #15
 MOV     R3,R3,LSR #1
 _DIVIDE R5,R4,R3,R6
 ; store new attenuation
 ; but slowly remove it
 MOV     R5,R5,LSL #AGC_Recover
 LDR     R6,[R12,#data_AGC]
 CMP     R6,#AGC_MaxVal
 ADDLT   R6,R6,#1
 CMP     R5,R6
 STRGT   R6,[R12,#data_AGC]
 STRLE   R5,[R12,#data_AGC]

 ; fill into hardware buffer

Seq_Filler_ApplyAGC
 LDR     R3,[R12,#data_AGC]
 LDR     R5,[R12,#data_MaxAGC]
 CMP     R3,R5
 STRLT   R3,[R12,#data_MaxAGC]
 MOV     R3,R3,LSR #AGC_Recover
 CMP     R3,#&10000
 BHS     Seq_Filler_NoAGC

Seq_Filler_AGC
 MOV     R1,R0
Seq_Filler_AGC_Loop
 LDMIA   R1,{R4-R11}
 MUL     R4,R3,R4
 MUL     R5,R3,R5
 MUL     R6,R3,R6
 MUL     R7,R3,R7
 MUL     R8,R3,R8
 MUL     R9,R3,R9
 MUL     R10,R3,R10
 MUL     R11,R3,R11
 MOV     R4,R4,ASR #16
 MOV     R5,R5,ASR #16
 MOV     R6,R6,ASR #16
 MOV     R7,R7,ASR #16
 MOV     R8,R8,ASR #16
 MOV     R9,R9,ASR #16
 MOV     R10,R10,ASR #16
 MOV     R11,R11,ASR #16
 STMIA   R1!,{R4-R11}
 CMP     R1,R2
 BLO     Seq_Filler_AGC_Loop

Seq_Filler_NoAGC
 MOV     R10,R0
 _PULL   "R1-R3"
 LDR     R0,[R12,#data_Status]
 TST     R0,#seq_status_handlerDMA8bit
 BEQ     Seq_Filler_NoAGC16bit

 BL      Seq_GetLogTable

 MOV     R14,R10
Seq_Filler_NoAGC8bit_Loop
 LDMIA   R14!,{R4-R11}
 MOV     R4,R4,LSL #16
 LDRB    R4,[R0,R4,LSR #19]
 MOV     R5,R5,LSL #16
 LDRB    R5,[R0,R5,LSR #19]
 MOV     R6,R6,LSL #16
 LDRB    R6,[R0,R6,LSR #19]
 MOV     R7,R7,LSL #16
 LDRB    R7,[R0,R7,LSR #19]
 ORR     R4,R4,R5,LSL #8
 ORR     R4,R4,R6,LSL #16
 ORR     R4,R4,R7,LSL #24
 STR     R4,[R1],#4
 MOV     R8,R8,LSL #16
 LDRB    R8,[R0,R8,LSR #19]
 MOV     R9,R9,LSL #16
 LDRB    R9,[R0,R9,LSR #19]
 MOV     R10,R10,LSL #16
 LDRB    R10,[R0,R10,LSR #19]
 MOV     R11,R11,LSL #16
 LDRB    R11,[R0,R11,LSR #19]
 ORR     R8,R8,R9,LSL #8
 ORR     R8,R8,R10,LSL #16
 ORR     R8,R8,R11,LSL #24
 STR     R8,[R1],#4
 CMP     R1,R2
 BLO     Seq_Filler_NoAGC8bit_Loop

 B       Seq_Filler_Timing

Seq_Filler_NoAGC16bit
 MOV     R0,#&FF00
 ORR     R0,R0,#&FF

 TST     R3,#1
 BNE     Seq_Filler_NoAGCMerge

 MOV     R14,R10
Seq_Filler_NoAGC16bit_Loop
 LDMIA   R14!,{R4-R11}
 AND     R5,R5,R0
 ORR     R5,R5,R4,LSL #16
 AND     R7,R7,R0
 ORR     R7,R7,R6,LSL #16
 AND     R9,R9,R0
 ORR     R9,R9,R8,LSL #16
 AND     R11,R11,R0
 ORR     R11,R11,R10,LSL #16
 STMIA   R1!,{R5,R7,R9,R11}
 CMP     R1,R2
 BLO     Seq_Filler_NoAGC16bit_Loop

 ORR     R3,R3,#1

 B       Seq_Filler_Timing

Seq_Filler_NoAGCMerge
 MOV     R14,R10
Seq_Filler_NoAGCMerge_Loop
 LDMIA   R1,{R5,R7}
 LDMIA   R14!,{R8-R11}
 MOV     R4,R5,ASR #16
 AND     R5,R5,R0
 MOV     R6,R7,ASR #16
 AND     R7,R7,R0
 ADD     R4,R4,R8
 ADD     R5,R5,R9
 ADD     R6,R6,R10
 ADD     R7,R7,R11
 AND     R5,R5,R0
 ORR     R5,R5,R4,LSL #16
 AND     R7,R7,R0
 ORR     R7,R7,R6,LSL #16
 STMIA   R1!,{R5,R7}
 CMP     R1,R2
 BLO     Seq_Filler_NoAGCMerge_Loop

Seq_Filler_Timing
 ; get used time and transform it into CPU usage
 BL      Seq_GetTimer

 LDR     R1,[R12,#data_Filler_AllowedTime]
 ; get a /1000 value vs real time
 MOV     R2,#1000
 MUL     R0,R2,R0
 _DIVIDE R2,R0,R1,R4
 STR     R2,[R12,#data_Filler_CPU]
 LDR     R1,[R12,#data_Filler_MaxCPU]
 CMP     R1,R2
 STRLT   R2,[R12,#data_Filler_MaxCPU]
 [ Seq_TimingCheck=1
 ; CPU >= 9x% ? => Decrease polyphony limit
 MOV     R1,#948
 CMP     R2,R1
 BGE     Seq_Filler_SlowProcessor

 ; CPU < 9x%, Increase polyphony limit?
Seq_Filler_CheckAccident
 LDR     R4,[R12,#data_MaxNrOfStreams]
 LDR     R5,[R12,#data_Polyphony]
 ; limit = max, do not touch
 CMP     R4,R5
 BHS     Seq_Filler_End
 ; playing < limit, do not touch
 LDR     R0,[R12,#data_NrOfStreams]
 CMP     R0,R4
 BLT     Seq_Filler_End
 ; playing > max, playing = max
 CMP     R0,R5
 MOVGT   R0,R5
 ; 0%? Must be a bug or an emulator
 CMP     R2,#0
 BEQ     Seq_Filler_Fix
 ; less than 25%, reset limit to max
 CMP     R2,#250
 STRLE   R5,[R12,#data_MaxNrOfStreams]
 BLE     Seq_Filler_End
 ; above 75%, do not touch
 CMP     R2,#748
 MOVGE   R4,#0
 STRGE   R4,[R12,#data_Filler_CPUCount]
 BGE     Seq_Filler_End
 ; 25% <= CPU < 75%, slowly increase limit
Seq_Filler_Fix
 LDR     R4,[R12,#data_Filler_CPUCount]
 ADD     R4,R4,#1
 TST     R4,#&3
 MOVEQ   R4,#0
 STR     R4,[R12,#data_Filler_CPUCount]
 BNE     Seq_Filler_End
 ADD     R0,R0,#1
 STR     R0,[R12,#data_MaxNrOfStreams]
 B       Seq_Filler_End

Seq_Filler_SlowProcessor
 ; slow processor, we need to minimise the number of channels
 LDR     R0,[R12,#data_NrOfStreams]
 MUL     R1,R0,R1
 _DIVIDE R4,R1,R2,R5
 CMP     R0,R4
 SUBLE   R4,R0,#1
 CMP     R4,#2
 MOVLE   R4,#2
 STR     R4,[R12,#data_MaxNrOfStreams]
 ]

Seq_Filler_End
 LDR     R0,[R12,#data_Status]

 TST     R0,#seq_status_handlerWAV
 BNE     Seq_Filler_FromSVCEnd
Seq_Filler_FromSVC
 ; Restore processor mode and interrupts state
 _PULL   "R4-R5"
 _FROMSVC
Seq_Filler_FromSVCEnd

 LDR     R0,[R12,#data_Status]
 BIC     R0,R0,#seq_status_filling
 STR     R0,[R12,#data_Status]

 _ENDPROC

Seq_Filler_NoPlay
 ; Don't do anything if mixing
 TST     R3,#1
 BNE     Seq_Filler_Timing

 ; Clear the data
 MOV     R0,#0
Seq_Filler_NoPlayLoop
 STR     R0,[R1],#4
 STR     R0,[R1],#4
 STR     R0,[R1],#4
 STR     R0,[R1],#4
 CMP     R1,R2
 BLO     Seq_Filler_NoPlayLoop

 B       Seq_Filler_Timing

;-------------------------------------------------------------------------------

 ; R9, R10, R12
Seq_Filler_Play _FNAME
 _DEFPROC "R7-R10"

 LDR     R4,[R12,#data_TimeStep]
 LDR     R5,[R12,#data_TimerTicksPerSec]
 _FNMul32 R4,R5,R6,R7,R8
 MUL     R8,R9,R8
 MOV     R8,R8,LSR #8
 STR     R8,[R12,#data_Filler_AllowedTime]

 LDR     R7,[R12,#data_FineQuality]
 MOV     R8,R9
 MOV     R9,#seq_soft_buf_size
Seq_Filler_Play_Loop
 ; R7  = quality in 1/256 us
 ; R8  = number of values remaining to fill
 ; R9  = voice buffer size (in nr of values)
 ; R10 = buffer ptr
 ; R11 = number of values to fill before stream change
 ; Update R11
 CMP     R8,R9
 MOVGT   R11,R9
 MOVLE   R11,R8
 ; Updates R11
 BL      Seq_CallChangers
 ; Update stream list
 BL      Seq_CallListers
 ; Fill buffers from streams
 BL      Voices_Fill
 ; Mix buffers, updates R10
 BL      Voices_Mix
 SUBS    R8,R8,R11
 BGT     Seq_Filler_Play_Loop

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_BandPass
;
; In  - R0  Bandpass parameters and old values
;       R9  buffer size (in nr of values)
;       R10 source buffer
;       R11 destination buffer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_BandPass _FNAME
 _DEFPROC "R0-R12"

 ADD     R12,R10,R9,LSL #3
 ; read filter parameters
 LDMIA   R0!,{R5-R9}

 ; read left saved values
 _PUSH   "R0,R10-R11"
 LDMIA   R0,{R1-R4}
Seq_BandPass_LoopLeft
 SMULL   R2,R14,R7,R2
 LDR     R0,[R10],#8
 SMLAL   R2,R14,R6,R1
 SMLAL   R2,R14,R5,R0
 SMLAL   R2,R14,R8,R3
 SMLAL   R2,R14,R9,R4
 LDR     R4,[R11]
 MOV     R2,R2,LSR #24
 ORRS    R2,R2,R14,ASL #8
 ADDLT   R2,R2,#1 ; cf rounding error of shift for negative
 ADD     R4,R4,R2
 STR     R4,[R11],#8
 MOV     R4,R3
 MOV     R3,R2
 MOV     R2,R1
 MOV     R1,R0
 CMP     R10,R12
 BLO     Seq_BandPass_LoopLeft
 _PULL   "R0,R10-R11"
 STMIA   R0!,{R1-R4}

 ; read right saved values
 _PUSH   "R0"
 LDMIA   R0,{R1-R4}
 ADD     R10,R10,#4
 ADD     R11,R11,#4
Seq_BandPass_LoopRight
 SMULL   R2,R14,R7,R2
 LDR     R0,[R10],#8
 SMLAL   R2,R14,R6,R1
 SMLAL   R2,R14,R5,R0
 SMLAL   R2,R14,R8,R3
 SMLAL   R2,R14,R9,R4
 LDR     R4,[R11]
 MOV     R2,R2,LSR #24
 ORRS    R2,R2,R14,ASL #8
 ADDLT   R2,R2,#1 ; cf rounding error of shift for negative
 ADD     R4,R4,R2
 STR     R4,[R11],#8
 MOV     R4,R3
 MOV     R3,R2
 MOV     R2,R1
 MOV     R1,R0
 CMP     R10,R12
 BLO     Seq_BandPass_LoopRight
 _PULL   "R0"
 STMIA   R0,{R1-R4}

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_BandPass_Serial
;
; In  - R0  Bandpass parameters and old values
;       R9  buffer size (in nr of values)
;       R10 source buffer = destination buffer
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Seq_BandPass_Serial _FNAME
 _DEFPROC "R0-R12"

 ADD     R12,R10,R9,LSL #3
 ; read filter parameters
 LDMIA   R0!,{R5-R9}

 ; read left saved values
 _PUSH   "R0,R10"
 LDMIA   R0,{R1-R4}
Seq_BandPass_Serial_LoopLeft
 SMULL   R2,R14,R7,R2
 LDR     R0,[R10]
 SMLAL   R2,R14,R6,R1
 SMLAL   R2,R14,R5,R0
 SMLAL   R2,R14,R8,R3
 SMLAL   R2,R14,R9,R4
 MOV     R2,R2,LSR #24
 ORRS    R2,R2,R14,ASL #8
 ADDLT   R2,R2,#1 ; cf rounding error of shift for negative
 STR     R2,[R10],#8
 MOV     R4,R3
 MOV     R3,R2
 MOV     R2,R1
 MOV     R1,R0
 CMP     R10,R12
 BLO     Seq_BandPass_Serial_LoopLeft
 _PULL   "R0,R10"
 STMIA   R0!,{R1-R4}

 ; read right saved values
 _PUSH   "R0"
 LDMIA   R0,{R1-R4}
 ADD     R10,R10,#4
Seq_BandPass_Serial_LoopRight
 SMULL   R2,R14,R7,R2
 LDR     R0,[R10]
 SMLAL   R2,R14,R6,R1
 SMLAL   R2,R14,R5,R0
 SMLAL   R2,R14,R8,R3
 SMLAL   R2,R14,R9,R4
 MOV     R2,R2,LSR #24
 ORRS    R2,R2,R14,ASL #8
 ADDLT   R2,R2,#1 ; cf rounding error of shift for negative
 STR     R2,[R10],#8
 MOV     R4,R3
 MOV     R3,R2
 MOV     R2,R1
 MOV     R1,R0
 CMP     R10,R12
 BLO     Seq_BandPass_Serial_LoopRight
 _PULL   "R0"
 STMIA   R0,{R1-R4}

 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_CallChangers
;
; In  - R7 quality in 1/256 us
;       R11 number of values to fill in buffer
;       R12 seq data ptr
;
; Out - R11 number of values to fill in buffer before any stream change
;-------------------------------------------------------------------------------
 ALIGN

Seq_CallChangers _FNAME
 _DEFPROC "R0-R4,R12"

 MUL     R0,R11,R7
 LDR     R2,[R12,#data_Stream_NrOfHandlers]
 CMP     R2,#0
 BEQ     Seq_CallChangers_Done
 ADD     R3,R12,#data_Stream_Handlers

Seq_CallChangers_Loop
 LDR     R4,[R3],#4
 LDR     R12,[R4,#shandler_R12]
 MOV     R14,PC
 LDR     PC,[R4,#shandler_changer]
Seq_CallChangers_Return
 SUBS    R2,R2,#1
 BGT     Seq_CallChangers_Loop

 ; the following seems a lot faster than a divide for our value range
 MOV     R11,#0
Seq_CallChangers_Loop2
 ADD     R11,R11,#4
 SUBS    R0,R0,R7,LSL #2 ; multiple of 4
 BGT     Seq_CallChangers_Loop2

Seq_CallChangers_Done
 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_CallListers
;
; In  - R11 number of values to fill in buffer
;       R12 seq data ptr
;
; Out - List of streams is generated
;-------------------------------------------------------------------------------
 ALIGN

Seq_CallListers _FNAME
 _DEFPROC "R0-R11"

 ; R10 handlers ptr
 ; R9  number of handlers
 ; R8  number of main streams
 ; R7  number of streams (total to mix, not total mixed)
 LDR     R9,[R12,#data_Stream_NrOfHandlers]
 MOV     R8,#0
 MOV     R7,#0
 CMP     R9,#0
 BEQ     Seq_CallListers_Done
 ADD     R10,R12,#data_Stream_Handlers

Seq_CallListers_HandlersLoop
 _PUSH   "R12"
 LDR     R1,[R12,#data_FineQuality]
 MUL     R0,R11,R1
 LDR     R1,[R10],#4
 LDR     R12,[R1,#shandler_R12]
 MOV     R14,PC
 LDR     PC,[R1,#shandler_lister]
Seq_CallListers_HandlerReturn
 _PULL   "R12"
 ; on exit
 ; R0 new list ptr
 ; R1 nr of streams in new list
 ADD     R7,R7,R1
 CMP     R1,#0
 BLE     Seq_CallListers_NextHandler

 ; insert streams in list sorted on volume
 ; R2 new stream volume
 ; R3 old stream volume
 ; R4 pos
 ; R5 min pos
 ; R6 max pos
 ; R7 new stream ptr
 _PUSH   "R7,R9"
Seq_CallListers_StreamsLoop
 LDR     R7,[R0],#4
 ; Ignore streams which don't play anything
 LDR     R2,[R7,#stream_pos]
 CMN     R2,#1
 BEQ     Seq_CallListers_NextStream
 ; R9 stream list ptr
 ADD     R9,R12,#data_StreamsPtr
 LDR     R2,[R7,#stream_volume]
 CMP     R2,#0
 BEQ     Seq_CallListers_SkipProcessStream
 MOV     R5,#0
 MOV     R6,R8
Seq_CallListers_InsertStream_Loop
 ADD     R4,R5,R6
 MOV     R4,R4,LSR #1
 CMP     R5,R6
 BGE     Seq_CallListers_InsertStream_Insert
 LDR     R3,[R9,R4,LSL #2]
 LDR     R3,[R3,#stream_volume]
 CMP     R2,R3
 MOVGT   R6,R4
 ADDLE   R5,R4,#1
 B       Seq_CallListers_InsertStream_Loop
Seq_CallListers_InsertStream_Insert
 ; R3 last stream in main list
 ; R4 insert pos
 ; R5 max nr of streams
 ; R6 copy of R8
 ; R7 new stream ptr
 LDR     R5,[R12,#data_MaxNrOfStreams]
 CMP     R4,R5
 BGE     Seq_CallListers_SkipProcessStream
Seq_CallListers_InsertStream_InsertOK
 MOV     R6,R8
 _PUSH   "R0-R1"
 ; move the pointers one down
 CMP     R8,R5
 SUBGE   R8,R8,#1
 ; keep trace of last stream in list
 LDRGE   R3,[R9,R8,LSL #2]
 SUB     R2,R8,R4
 MOV     R2,R2,LSL #2
 ADD     R1,R9,R4,LSL #2
 ADD     R0,R1,#4
 BL      Mem_FastMove
 ; store new pointer
 STR     R7,[R1]
 _PULL   "R0-R1"

 ADD     R8,R8,#1
 CMP     R6,R5
 BLT     Seq_CallListers_NextStream
 ; process the stream we have moved out of the list
 MOV     R7,R3
Seq_CallListers_SkipProcessStream
 _PUSH   "R0-R2"
 MOV     R0,R7
 MOV     R2,#0
 STR     R2,[R0,#stream_pbuffer]
 LDR     R1,[R12,#data_TimeStep]
 MOV     R2,R11
 BL      Seq_SkipProcessStream
 _PULL   "R0-R2"

Seq_CallListers_NextStream
 SUBS    R1,R1,#1
 BGT     Seq_CallListers_StreamsLoop
 _PULL   "R7,R9"

Seq_CallListers_NextHandler
 SUBS    R9,R9,#1
 BGT     Seq_CallListers_HandlersLoop

Seq_CallListers_Done
 STR     R8,[R12,#data_NrOfStreams]
 LDR     R0,[R12,#data_MaxNrOfStreamsSeen]
 CMP     R0,R7
 STRLT   R7,[R12,#data_MaxNrOfStreamsSeen]

 _ENDPROC

;-------------------------------------------------------------------------------
; Voices_Mix
;
; In  - R10 start of 32-bit stereo buffer
;       R11 number of values to mix (must be even)
;       R12 seq data ptr
;
; Out - R10 updated, buffer filled
;-------------------------------------------------------------------------------

 ALIGN
Voices_Mix _FNAME
 _DEFPROC "R0-R9,R11"

 LDR     R4,[R12,#data_NrOfStreams]
 ADD     R8,R12,#(data_Streams_Info+stream_info_vleft):AND:&ff
 ADD     R8,R8,#(data_Streams_Info+stream_info_vleft):AND:&ff00
 LDR     R9,[R12,#data_VoicesBufferPtr]
 ADD     R11,R10,R11,LSL #3; 2 words

 LDR     R0,[R12,#data_Status]
 TST     R0,#seq_status_mix_mono
 BNE     Voices_MixMono
 TST     R0,#seq_status_SMLASupport
 BNE     Voices_MixStereoSMLA

Voices_MixStereo
 CMP     R4,#1
 BLT     Voices_Mix_Clear
 BEQ     Voices_MixStereo_1Voice

;---------------------------------------------------------
; R0  = smp 1
; R1  = smp 2
; R2  = tmp1
; R3  = volume, tmp2
; R4  = left sum1
; R5  = right sum1
; R6  = left sum2
; R7  = right sum2
; R8  = volume ptr
; R9  = soft buffers
; R10 = start of 32 bit buffer
; R11 = end of 32 bit buffer
; R14 = number of channels, max of 256

Voices_MixStereo_Loop
 _PUSH   "R8,R9"
 LDR     R14,[R12,#data_NrOfStreams]
 SUB     R14,R14,#1

 ; Read n 2x16 bit values
 LDR     R0,[R9],#seq_soft_buf_len
 LDR     R2,[R8,#4] ; read right volume
 MOV     R1,R0,ASR #16
 MOV     R0,R0,LSL #16
 MOV     R0,R0,ASR #16
 ; mix them in [R4,R5], and [R6,R7]
 MUL     R3,R1,R2
 MUL     R2,R0,R2
 MOV     R7,R3,ASR #11
 MOV     R5,R2,ASR #11
 LDR     R3,[R8],#size_stream_info ; read left volume
 MUL     R2,R0,R3
 MUL     R3,R1,R3
 MOV     R4,R2,ASR #11
 MOV     R6,R3,ASR #11

Voices_MixStereo_Loop_Mix
 ; Read n 2x16 bit values
 LDR     R0,[R9],#seq_soft_buf_len
 LDR     R2,[R8,#4] ; read right volume
 MOV     R1,R0,ASR #16
 MOV     R0,R0,LSL #16
 MOV     R0,R0,ASR #16
 ; mix them in [R4,R5], and [R6,R7]
 MUL     R3,R1,R2
 MUL     R2,R0,R2
 ADD     R7,R7,R3,ASR #11
 ADD     R5,R5,R2,ASR #11
 LDR     R3,[R8],#size_stream_info ; read left volume
 MUL     R2,R0,R3
 MUL     R3,R1,R3
 ADD     R4,R4,R2,ASR #11
 ADD     R6,R6,R3,ASR #11
 SUBS    R14,R14,#1
 BGT     Voices_MixStereo_Loop_Mix

Voices_MixStereo_Loop_Store
 MOVS    R4,R4,ASR #5
 ADC     R4,R4,#0
 MOVS    R5,R5,ASR #5
 ADC     R5,R5,#0
 MOVS    R6,R6,ASR #5
 ADC     R6,R6,#0
 MOVS    R7,R7,ASR #5
 ADC     R7,R7,#0
 STMIA   R10!,{R4-R7}

 _PULL   "R8,R9"
 ADD     R9,R9,#4

 CMP     R10,R11
 BLO     Voices_MixStereo_Loop

 _ENDPROC

; 1 voice

Voices_MixStereo_1Voice
 LDR     R2,[R8,#4] ; read right volume
 LDR     R3,[R8] ; read left volume

Voices_MixStereo_1Voice_Loop
 ; Read n 2x16 bit values
 LDR     R0,[R9],#4
 MOV     R1,R0,ASR #16
 MOV     R0,R0,LSL #16
 MOV     R0,R0,ASR #16
 ; mix them in [R4,R5], and [R6,R7]
 MUL     R5,R0,R2
 MUL     R7,R1,R2
 MOVS    R5,R5,ASR #16
 ADC     R5,R5,#0
 MOVS    R7,R7,ASR #16
 ADC     R7,R7,#0
 MUL     R4,R0,R3
 MUL     R6,R1,R3
 MOVS    R4,R4,ASR #16
 ADC     R4,R4,#0
 MOVS    R6,R6,ASR #16
 ADC     R6,R6,#0
 ; store
 STMIA   R10!,{R4-R7}

 CMP     R10,R11
 BLO     Voices_MixStereo_1Voice_Loop

 _ENDPROC

Voices_MixStereoSMLA
 CMP     R4,#1
 BLT     Voices_Mix_Clear
 BEQ     Voices_MixStereoSMLA_1Voice

;---------------------------------------------------------
; R0  = smp 1
; R1  = smp 2
; R2  = tmp1
; R3  = volume, tmp2
; R4  = left sum1
; R5  = right sum1
; R6  = left sum2
; R7  = right sum2
; R8  = volume ptr
; R9  = soft buffers
; R10 = start of 32 bit buffer
; R11 = end of 32 bit buffer
; R14 = number of channels, max of 256

Voices_MixStereoSMLA_Loop
 _PUSH   "R8,R9"
 LDR     R14,[R12,#data_NrOfStreams]
 SUB     R14,R14,#1

 ; Read n 2x16 bit values, put them in top bits
 LDR     R0,[R9],#seq_soft_buf_len
 LDR     R2,[R8,#4] ; read right volume
 MOV     R1,R0,ASR #16
 MOV     R1,R1,LSL #16
 MOV     R0,R0,LSL #16
 ; mix them in [R4,R5], and [R6,R7]
 SMULL   R3,R7,R1,R2
 SMULL   R3,R5,R0,R2
 LDR     R2,[R8],#size_stream_info ; read left volume
 SMULL   R3,R4,R0,R2
 SMULL   R3,R6,R1,R2

Voices_MixStereoSMLA_Loop_Mix
 ; Read n 2x16 bit values
 LDR     R0,[R9],#seq_soft_buf_len
 LDR     R2,[R8,#4] ; read right volume
 MOV     R1,R0,ASR #16
 MOV     R1,R1,LSL #16
 MOV     R0,R0,LSL #16
 ; mix them in [R4,R5], and [R6,R7]
 MOV     R3,#0
 SMLAL   R3,R7,R1,R2
 MOV     R3,#0
 SMLAL   R3,R5,R0,R2
 LDR     R2,[R8],#size_stream_info ; read left volume
 MOV     R3,#0
 SMLAL   R3,R4,R0,R2
 MOV     R3,#0
 SMLAL   R3,R6,R1,R2
 SUBS    R14,R14,#1
 BGT     Voices_MixStereoSMLA_Loop_Mix

Voices_MixStereoSMLA_Loop_Store
 STMIA   R10!,{R4-R7}

 _PULL   "R8,R9"
 ADD     R9,R9,#4

 CMP     R10,R11
 BLO     Voices_MixStereoSMLA_Loop

 _ENDPROC

; 1 voice

Voices_MixStereoSMLA_1Voice
 LDR     R2,[R8,#4] ; read right volume
 LDR     R3,[R8] ; read left volume

Voices_MixStereoSMLA_1Voice_Loop
 ; Read n 2x16 bit values
 LDR     R0,[R9],#4
 MOV     R1,R0,ASR #16
 MOV     R1,R1,LSL #16
 MOV     R0,R0,LSL #16
 ; mix them in [R4,R5], and [R6,R7]
 SMULL   R14,R5,R0,R2
 SMULL   R14,R7,R1,R2
 SMULL   R14,R4,R0,R3
 SMULL   R14,R6,R1,R3
 ; store
 STMIA   R10!,{R4-R7}

 CMP     R10,R11
 BLO     Voices_MixStereoSMLA_1Voice_Loop

 _ENDPROC

Voices_MixMono
 CMP     R4,#1
 BLT     Voices_Mix_Clear
 BEQ     Voices_MixMono_1Voice

;---------------------------------------------------------
; R0  = smp 1
; R1  = smp 2
; R2  = volume
; R3  = sum1
; R4  = sum2
; R5  =
; R6  = current volume ptr
; R7  = current soft buffer
; R8  = volume ptr
; R9  = soft buffers
; R10 = start of 32 bit buffer
; R11 = end of 32 bit buffer
; R14 = number of channels, max of 256

Voices_MixMono_Loop
 MOV     R6,R8
 MOV     R7,R9
 LDR     R14,[R12,#data_NrOfStreams]
 SUB     R14,R14,#1

 ; Read n 2x16 bit values
 LDR     R0,[R7],#seq_soft_buf_len
 LDR     R2,[R6],#size_stream_info ; read left volume
 MOV     R1,R0,ASR #16
 MOV     R0,R0,LSL #16
 MOV     R0,R0,ASR #16
 ; mix them in [R3,R4]
 MUL     R1,R2,R1
 MUL     R0,R2,R0
 MOV     R4,R1,ASR #11
 MOV     R3,R0,ASR #11

Voices_MixMono_Loop_Mix
 ; Read n 2x16 bit values
 LDR     R0,[R7],#seq_soft_buf_len
 LDR     R2,[R6],#size_stream_info ; read left volume
 MOV     R1,R0,ASR #16
 MOV     R0,R0,LSL #16
 MOV     R0,R0,ASR #16
 ; mix them in [R3,R4]
 MUL     R1,R2,R1
 MUL     R0,R2,R0
 ADD     R4,R4,R1,ASR #11
 ADD     R3,R3,R0,ASR #11
 SUBS    R14,R14,#1
 BGT     Voices_MixMono_Loop_Mix

Voices_MixMono_Loop_Store
 MOVS    R3,R3,ASR #5
 ADC     R3,R3,#0
 MOVS    R4,R4,ASR #5
 ADC     R4,R4,#0
 MOV     R1,R3
 MOV     R2,R4
 STMIA   R10!,{R1-R4}

 ADD     R9,R9,#4

 CMP     R10,R11
 BLO     Voices_MixMono_Loop

 _ENDPROC

; 1 voice

Voices_MixMono_1Voice
 LDR     R2,[R8] ; read left volume

Voices_MixMono_1Voice_Loop
 ; Read n 2x16 bit values
 LDR     R0,[R9],#4
 MOV     R1,R0,ASR #16
 MOV     R0,R0,LSL #16
 MOV     R0,R0,ASR #16
 ; mix them
 MUL     R1,R2,R1
 MUL     R0,R2,R0
 MOVS    R1,R1,ASR #16
 ADC     R1,R1,#0
 MOVS    R0,R0,ASR #16
 ADC     R0,R0,#0
 MOV     R2,R0
 MOV     R3,R1
 ; store
 STMIA   R10!,{R0-R3}

 CMP     R10,R11
 BLO     Voices_MixMono_1Voice_Loop

 _ENDPROC

; 0 voices

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

Voices_Mix_Clear_Loop
 STMIA   R10!,{R3-R6}
 CMP     R10,R11
 BLO     Voices_Mix_Clear_Loop

 _ENDPROC

;-------------------------------------------------------------------------------
; Voices_Fill (soft buffers)
;
; In  - R9  length of a buffer (nr of bytes/2)
;       R11 number of values to fill for each stream
;       R12 seq data ptr
;-------------------------------------------------------------------------------
 ALIGN

Voices_Fill _FNAME
 _DEFPROC "R0-R8,R10"

 ; R0 stream ptr
 ; R1 stream info ptr
 ; R2 mix scale
 ; R4 stereo separation
 ; R5 balance * 256
 ; R6 stream list ptr
 ; R7 nr of streams
 ; R8 fill buffer ptr
 ; R10 time step between values (2^40/Fmix)
 LDR     R7,[R12,#data_NrOfStreams]
 CMP     R7,#0
 BLE     Voices_Fill_End

 LDR     R10,[R12,#data_TimeStep]

 STR     R9,[R12,#data_SampleSize]

 ADD     R1,R12,#data_Streams_Info:AND:&FF
 ADD     R1,R1,#data_Streams_Info:AND:&FF00
 ; read output volume
 LDR     R2,[R12,#data_Filler_Mix_Scale]
 ; R12 buffers ptr (buffers are following each other)
 LDR     R4,[R12,#data_StereoSeparation]
 LDR     R5,[R12,#data_Balance]
 MOV     R5,R5,LSL #8
 ADD     R6,R12,#data_StreamsPtr
 LDR     R8,[R12,#data_VoicesBufferPtr]

Voices_Fill_LoopOnStreams
 LDR     R0,[R6],#4
 ; Update stream buffer info
 STR     R8,[R0,#stream_pbuffer]
 BL      Voice_Fill
 BL      Voice_ITFilter
Voices_Fill_NextStream
 SUBS    R7,R7,#1
 ADDGT   R8,R8,R9,LSL #1
 ADDGT   R1,R1,#size_stream_info
 BGT     Voices_Fill_LoopOnStreams

Voices_Fill_End
 _ENDPROC

;-------------------------------------------------------------------------------
; Voice_ITFilter
;
; Filter in the form y0 = a0 * x0 + b1 * y1 + b2 * y2
; where xi is in(-i*T), yi is out(-i*T), ai and bj are in 1.24 fixed point
;
; In  - R0  stream ptr
;       R11 buffer size (in nr of values), must be multiple of 2
;       R12 seq data ptr
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Voice_ITFilter _FNAME
 _DEFPROC "R0-R8,R11-R12"

 ; Do nothing if no SMLA support
 LDR     R1,[R12,#data_Status]
 TST     R1,#seq_status_SMLASupport
 _ENDPROC EQ
 TST     R1,#seq_status_disable_ITFilters
 _ENDPROC NE
 ; Nothing to do if no filter
 LDRB    R1,[R0,#stream_flags]
 TST     R1,#stream_flag_filter
 _ENDPROC EQ
 ; R12 = ptr start, R11 = ptr end
 LDR     R12,[R0,#stream_pbuffer]
 ADD     R11,R12,R11,LSL #1
 ; R0 = old values and filter parameters
 ADD     R0,R0,#stream_filter_y1
 ; read saved values
 ; read filter parameters
 LDMIA   R0,{R3-R4,R5-R7}
 MOV     R8,#&8000

Voice_ITFilter_Loop
 ; read two samples
 LDR     R1,[R12]
 MOV     R2,R1,ASR #16
 MOV     R1,R1,LSL #16
 MOV     R1,R1,ASR #16
 ; process first sample
 SMULL   R4,R14,R7,R4
 SMLAL   R4,R14,R6,R3
 SMLAL   R4,R14,R5,R1
 MOV     R14,R14,ASL #4
 ORRS    R4,R14,R4,LSR #28
 ADDLT   R4,R4,#1 ; cf rounding error of shift for negative
 ; process second sample
 SMULL   R3,R14,R7,R3
 SMLAL   R3,R14,R6,R4
 SMLAL   R3,R14,R5,R2
 MOV     R14,R14,ASL #4
 ORRS    R3,R14,R3,LSR #28
 ADDLT   R3,R3,#1 ; cf rounding error of shift for negative
 ; Even if sum of coefficients is one, due to one negative coefficient
 ; samples may locally be amplified
 ; so divide output by 4 to avoid saturation.
 ; We will mix these filtered note at twice the volume to compensate.
 MOVS    R1,R4,ASR #2
 ADC     R1,R1,#0
 MOVS    R2,R3,ASR #2
 ADC     R2,R2,#0
 ; clip values
 CMP     R1,R8
 SUBGE   R1,R8,#1
 CMN     R1,R8
 MOVLT   R1,R8
 CMP     R2,R8
 SUBGE   R2,R8,#1
 CMN     R2,R8
 MOVLT   R2,R8
 ; store output values
 MOV     R1,R1,LSL #16
 MOV     R1,R1,LSR #16
 ORR     R1,R1,R2,LSL #16
 STR     R1,[R12],#4
 CMP     R12,R11
 BLO     Voice_ITFilter_Loop
 ; save old values

 STMIA   R0,{R3-R4}

 _ENDPROC

;-------------------------------------------------------------------------------
; Voice_Fill
;
; In  - R0  stream ptr
;       R1  stream info ptr
;       R2  mix scale (&10000/n)
;       R4  stereo separation [-256, 256]
;       R5  balance * 256 [0, 256*256]
;       R10 time step between values (2^40/FMix)
;       R11 count
;       R12 seq data ptr
; Out -
;-------------------------------------------------------------------------------
 ALIGN

Voice_Fill _FNAME
 _DEFPROC "R0-R12"

 ;
 ; Update stream volume info for mixing
 ;
 LDR     R3,[R0,#stream_panning]
 LDR     R6,[R0,#stream_volume]
 _FNMul16 R2,R6,R7,R9,R8
 ; test for mix in mono
 LDR     R7,[R12,#data_Status]
 TST     R7,#seq_status_mix_mono
 MOVNE   R6,R8,LSR #1
 MOVNE   R4,R8,LSR #1
 BNE     Voice_Fill_Scale_Store
 ; test for surround
 CMP     R3,#256
 MOVHI   R6,R8,LSR #1
 RSBHI   R4,R6,#0
 BHI     Voice_Fill_Scale_Store
 ; no surround
 SUB     R3,R3,#128
 MUL     R3,R4,R3
 ADDS    R3,R3,R5
 MOVLT   R3,#0
 CMP     R3,#1<<16
 MOVGT   R3,#1<<16
 MOV     R3,R3,LSR #8
 MUL     R4,R8,R3
 MOV     R4,R4,LSR #8
 SUB     R6,R8,R4
Voice_Fill_Scale_Store
 ; amplify by 2 filtered notes
 EOR     R7,R7,#seq_status_disable_ITFilters ;for the test that follows
 TST     R7,#seq_status_disable_ITFilters
 LDRNEB  R7,[R0,#stream_flags]
 TSTNE   R7,#stream_flag_filter
 MOVNE   R6,R6,ASL #2
 MOVNE   R4,R4,ASL #2
 STR     R6,[R1,#stream_info_vleft]
 STR     R4,[R1,#stream_info_vright]

 ;
 ; Fill voice
 ;

 ; R14   buffer for 2 16-bit values
 ; R12   buf
 ; R11   count
 ; R10   (new value - oldvalue)
 ; R9    interpolated value
 ; R8    0xFFFF
 ; R7    step in 1/2^24 sample values (2^24*Fsample/Fmix)
 ; R6    stream_fpos
 ; R5    stream_pos
 ; R4    stream_flags
 ; R3    stream_smp_lend, tmp
 ; R2    stream_smp_lstart
 ; R1    stream_smp_ptr
 ; R0    old value
 LDR     R2,[R0,#stream_frequency]
 _FNMul16 R10,R2,R3,R4,R7
 ; R1-R6
 LDMIA   R0,{R1-R6}
 SUB     R2,R3,R2
 SUB     R5,R5,R3
 _PUSH   "R0,R3"

 AND     R9,R4,#stream_flag_isbackward+stream_flag_16bit+stream_flag_interlaced
 LDR     R14,[R12,#data_Status]
 TST     R14,#seq_status_interpol
 ORRNE   R9,R9,#&40
 TST     R14,#seq_status_LDRHSupport
 ORRNE   R9,R9,#&80
 CMP     R7,#&1000000
 ORRHS   R9,R9,#&20 ; non-interpolated
 BICEQ   R9,R9,#&40 ; force simple mode if step is unit

 LDR     R12,[R0,#stream_pbuffer]

 MOV     R8,#&FF
 ORR     R8,R8,#&FF00
 LDR     R0,[R0,#stream_last_smp_value]

 ADD     PC,PC,R9
 MOV     R0,R0
Voice_Fill_Dispatch               ; B 16 X O I H * X8bit needs changes
 B       FFill_NoInterpol         ;
 B       BFill_NoInterpol         ; x
 B       FFill16_NoInterpol       ;    x
 B       BFill16_NoInterpol       ; x  x
 B       FFillX_NoInterpol        ;      x
 B       BFillX_NoInterpol        ; x    x
 B       FFill16X_NoInterpol      ;    x x
 B       BFill16X_NoInterpol      ; x  x x
 B       FFill_Simple             ;        x
 B       BFill_Simple             ; x      x
 B       FFill16_Simple           ;    x   x
 B       BFill16_Simple           ; x  x   x
 B       FFillX_Simple            ;      x x
 B       BFillX_Simple            ; x    x x
 B       FFill16X_Simple          ;    x x x
 B       BFill16X_Simple          ; x  x x x
 B       FFill_Interpol           ;          x
 B       BFill_Interpol           ; x        x
 B       FFill16_Interpol         ;    x     x
 B       BFill16_Interpol         ; x  x     x
 B       FFillX_Interpol          ;      x   x
 B       BFillX_Interpol          ; x    x   x
 B       FFill16X_Interpol        ;    x x   x
 B       BFill16X_Interpol        ; x  x x   x
 B       FFill_Oversampled        ;        x x
 B       BFill_Oversampled        ; x      x x
 B       FFill16_Oversampled      ;    x   x x
 B       BFill16_Oversampled      ; x  x   x x
 B       FFillX_Oversampled       ;      x x x
 B       BFillX_Oversampled       ; x    x x x
 B       FFill16X_Oversampled     ;    x x x x
 B       BFill16X_Oversampled     ; x  x x x x
 B       FFill_NoInterpol         ;            x
 B       BFill_NoInterpol         ; x          x
 B       FFillH_NoInterpol        ;    x       x
 B       BFillH_NoInterpol        ; x  x       x
 B       FFillX_NoInterpol        ;      x     x
 B       BFillX_NoInterpol        ; x    x     x
 B       FFillHX_NoInterpol       ;    x x     x
 B       BFillHX_NoInterpol       ; x  x x     x
 B       FFill_Simple             ;        x   x
 B       BFill_Simple             ; x      x   x
 B       FFillH_Simple            ;    x   x   x
 B       BFillH_Simple            ; x  x   x   x
 B       FFillX_Simple            ;      x x   x
 B       BFillX_Simple            ; x    x x   x
 B       FFillHX_Simple           ;    x x x   x
 B       BFillHX_Simple           ; x  x x x   x
 B       FFill_Interpol           ;          x x
 B       BFill_Interpol           ; x        x x
 B       FFillH_Interpol          ;    x     x x
 B       BFillH_Interpol          ; x  x     x x
 B       FFillX_Interpol          ;      x   x x
 B       BFillX_Interpol          ; x    x   x x
 B       FFillHX_Interpol         ;    x x   x x
 B       BFillHX_Interpol         ; x  x x   x x
 B       FFill_Oversampled        ;        x x x
 B       BFill_Oversampled        ; x      x x x
 B       FFillH_Oversampled       ;    x   x x x
 B       BFillH_Oversampled       ; x  x   x x x
 B       FFillX_Oversampled       ;      x x x x
 B       BFillX_Oversampled       ; x    x x x x
 B       FFillHX_Oversampled      ;    x x x x x
 B       BFillHX_Oversampled      ; x  x x x x x

 ;------------------------------------------------------------------------------
 ; 8 bit sample - NoInterpol (R7 < &1000000)
 ;------------------------------------------------------------------------------

 ;-------------
 ; Forward Fill

FFill_NoInterpol _FNAME
 ADD     R1,R1,R3
 LDRB    R0,[R1,R5]
 _PUSH   "R2,R4"
 B       FFill_NoInterpolF_End
 ; Fast mode, 8 samples in one go
FFill_NoInterpolF1
 MOV     R2,R0,LSL #8
 PROCPrepNext x
 LDRCSB  R0,[R1,R5]
 ORR     R2,R2,R0,LSL #24
 PROCPrepNext x
 LDRCSB  R0,[R1,R5]
 MOV     R3,R0,LSL #8
 PROCPrepNext x
 LDRCSB  R0,[R1,R5]
 ORR     R3,R3,R0,LSL #24
 PROCPrepNext x
 LDRCSB  R0,[R1,R5]
 MOV     R4,R0,LSL #8
 PROCPrepNext x
 LDRCSB  R0,[R1,R5]
 ORR     R4,R4,R0,LSL #24
 PROCPrepNext x
 LDRCSB  R0,[R1,R5]
 MOV     R14,R0,LSL #8
 PROCPrepNext x
 LDRCSB  R0,[R1,R5]
 ORR     R14,R14,R0,LSL #24
 PROCPrepNext x
 LDRCSB  R0,[R1,R5]
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFill_NoInterpolF_End
 SUBS    R11,R11,#8
 BLT     FFill_NoInterpolFF
 ADDS    R9,R5,#9
 BLT     FFill_NoInterpolF1

FFill_NoInterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFill_NoInterpol1
 MOV     R14,R0,LSL #8
 PROCPrepareNext FFill_NoInterpol2,FFill_NoInterpol1_Loop
FFill_NoInterpol1_Sample
 LDRB    R0,[R1,R5]
FFill_NoInterpol2
 ORR     R14,R14,R0,LSL #24
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFill_NoInterpol_End,FFill_NoInterpol2_Loop
FFill_NoInterpol2_Sample
 LDRB    R0,[R1,R5]
FFill_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill_NoInterpol1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill_NoInterpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_NoInterpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill_NoInterpol1_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_NoInterpol1_Sample

FFill_NoInterpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_NoInterpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFill_NoInterpol2_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_NoInterpol2_Sample

 ;--------------
 ; Backward Fill

BFill_NoInterpol _FNAME
 ADD     R1,R1,R3
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 LDRB    R0,[R1,R5]
 _PUSH   "R2,R4"
 B       BFill_NoInterpolF_End
 ; Fast mode, 8 samples in one go
BFill_NoInterpolF1
 MOV     R2,R0,LSL #8
 PROCPrepBNext x
 LDRCSB  R0,[R1,R5]
 ORR     R2,R2,R0,LSL #24
 PROCPrepBNext x
 LDRCSB  R0,[R1,R5]
 MOV     R3,R0,LSL #8
 PROCPrepBNext x
 LDRCSB  R0,[R1,R5]
 ORR     R3,R3,R0,LSL #24
 PROCPrepBNext x
 LDRCSB  R0,[R1,R5]
 MOV     R4,R0,LSL #8
 PROCPrepBNext x
 LDRCSB  R0,[R1,R5]
 ORR     R4,R4,R0,LSL #24
 PROCPrepBNext x
 LDRCSB  R0,[R1,R5]
 MOV     R14,R0,LSL #8
 PROCPrepBNext x
 LDRCSB  R0,[R1,R5]
 ORR     R14,R14,R0,LSL #24
 PROCPrepBNext x
 LDRCSB  R0,[R1,R5]
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFill_NoInterpolF_End
 SUBS    R11,R11,#8
 BLT     BFill_NoInterpolFF
 SUBS    R9,R5,#9
 BGT     BFill_NoInterpolF1

BFill_NoInterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFill_NoInterpol1
 MOV     R14,R0,LSL #8
 PROCPrepareBNext BFill_NoInterpol2,BFill_NoInterpol1_Loop
BFill_NoInterpol1_Sample
 LDRB    R0,[R1,R5]
BFill_NoInterpol2
 ORR     R14,R14,R0,LSL #24
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFill_NoInterpol_End,BFill_NoInterpol2_Loop
BFill_NoInterpol2_Sample
 LDRB    R0,[R1,R5]
BFill_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill_NoInterpol1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill_NoInterpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_NoInterpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill_NoInterpol1_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_NoInterpol1_Sample

BFill_NoInterpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_NoInterpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFill_NoInterpol2_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_NoInterpol2_Sample

 ;------------------------------------------------------------------------------
 ; 8 bit sample - Simple (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFill_Simple _FNAME
 ADD     R1,R1,R3
 _PUSH   "R2,R4"
 B       FFill_SimpleF_End
 ; Fast mode, 8 samples in one go
FFill_SimpleF1
 LDRB    R9,[R1,R5]
 PROCPrepareNextSimple x
 LDRB    R0,[R1,R5]
 MOV     R2,R9,LSL #8
 ORR     R2,R2,R0,LSL #24
 PROCPrepareNextSimple x
 LDRB    R9,[R1,R5]
 PROCPrepareNextSimple x
 LDRB    R0,[R1,R5]
 MOV     R3,R9,LSL #8
 ORR     R3,R3,R0,LSL #24
 PROCPrepareNextSimple x
 LDRB    R9,[R1,R5]
 PROCPrepareNextSimple x
 LDRB    R0,[R1,R5]
 MOV     R4,R9,LSL #8
 ORR     R4,R4,R0,LSL #24
 PROCPrepareNextSimple x
 LDRB    R9,[R1,R5]
 PROCPrepareNextSimple x
 LDRB    R0,[R1,R5]
 MOV     R14,R9,LSL #8
 ORR     R14,R14,R0,LSL #24
 PROCPrepareNextSimple x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFill_SimpleF_End
 SUBS    R11,R11,#8
 BLT     FFill_SimpleFF
 ADD     R9,R5,R7,LSR #(24-3)
 ADDS    R9,R9,#2
 BLT     FFill_SimpleF1

FFill_SimpleFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFill_Simple1
 LDRB    R9,[R1,R5]
 PROCPrepareNextSimple FFill_Simple1_Loop
FFill_Simple2
 LDRB    R0,[R1,R5]
 MOV     R14,R9,LSL #8
 ORR     R14,R14,R0,LSL #24
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextSimple FFill_Simple2_Loop
FFill_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill_Simple1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill_Simple1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_Simple1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_Simple2
 ; no loop? store last value and clear the rest
 MOV     R14,R9,LSL #8
 STR     R14,[R12],#4
 B       Fill_Clear
FFill_Simple1_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_Simple2

FFill_Simple2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_Simple2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
FFill_Simple2_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_Simple_End

 ;--------------
 ; Backward Fill

BFill_Simple _FNAME
 ADD     R1,R1,R3
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 _PUSH   "R2,R4"
 B       BFill_SimpleF_End
 ; Fast mode, 8 samples in one go
BFill_SimpleF1
 LDRB    R9,[R1,R5]
 PROCPrepareBNextSimple x
 LDRB    R0,[R1,R5]
 MOV     R2,R9,LSL #8
 ORR     R2,R2,R0,LSL #24
 PROCPrepareBNextSimple x
 LDRB    R9,[R1,R5]
 PROCPrepareBNextSimple x
 LDRB    R0,[R1,R5]
 MOV     R3,R9,LSL #8
 ORR     R3,R3,R0,LSL #24
 PROCPrepareBNextSimple x
 LDRB    R9,[R1,R5]
 PROCPrepareBNextSimple x
 LDRB    R0,[R1,R5]
 MOV     R4,R9,LSL #8
 ORR     R4,R4,R0,LSL #24
 PROCPrepareBNextSimple x
 LDRB    R9,[R1,R5]
 PROCPrepareBNextSimple x
 LDRB    R0,[R1,R5]
 MOV     R14,R9,LSL #8
 ORR     R14,R14,R0,LSL #24
 PROCPrepareBNextSimple x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFill_SimpleF_End
 SUBS    R11,R11,#8
 BLT     BFill_SimpleFF
 SUB     R9,R5,R7,LSR #(24-3)
 SUBS    R9,R9,#2
 BGT     BFill_SimpleF1

BFill_SimpleFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFill_Simple1
 LDRB    R9,[R1,R5]
 PROCPrepareBNextSimple BFill_Simple1_Loop
BFill_Simple2
 LDRB    R0,[R1,R5]
 MOV     R14,R9,LSL #8
 ORR     R14,R14,R0,LSL #24
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextSimple BFill_Simple2_Loop
BFill_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill_Simple1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill_Simple1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_Simple1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_Simple2
 ; no loop? store last value and clear the rest
 MOV     R14,R9,LSL #8
 STR     R14,[R12],#4
 B       Fill_Clear
BFill_Simple1_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_Simple2

BFill_Simple2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_Simple2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
BFill_Simple2_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_Simple_End

 ;------------------------------------------------------------------------------
 ; 8 bit sample - Interpol (R7 < &1000000)

 ;-------------
 ; Forward Fill

FFill_Interpol _FNAME
 ADD     R1,R1,R3
 PROCConvertSampleByte no
 _PUSH   "R2,R4"
 B       FFill_InterpolF_End
 ; Fast mode, 8 samples in one go
FFill_InterpolF1
 PROCInterpol R2
 PROCPrepNext FFill_InterpolF2
 PROCConvertSampleByte yes
FFill_InterpolF2
 PROCInterpol R9
 AND     R2,R2,R8
 ORR     R2,R2,R9,LSL #16
 PROCPrepNext FFill_InterpolF3
 PROCConvertSampleByte yes
FFill_InterpolF3
 PROCInterpol R3
 PROCPrepNext FFill_InterpolF4
 PROCConvertSampleByte yes
FFill_InterpolF4
 PROCInterpol R9
 AND     R3,R3,R8
 ORR     R3,R3,R9,LSL #16
 PROCPrepNext FFill_InterpolF5
 PROCConvertSampleByte yes
FFill_InterpolF5
 PROCInterpol R4
 PROCPrepNext FFill_InterpolF6
 PROCConvertSampleByte yes
FFill_InterpolF6
 PROCInterpol R9
 AND     R4,R4,R8
 ORR     R4,R4,R9,LSL #16
 PROCPrepNext FFill_InterpolF7
 PROCConvertSampleByte yes
FFill_InterpolF7
 PROCInterpol R14
 PROCPrepNext FFill_InterpolF8
 PROCConvertSampleByte yes
FFill_InterpolF8
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 PROCPrepNext FFill_InterpolF9
 PROCConvertSampleByte yes
FFill_InterpolF9
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFill_InterpolF_End
 SUBS    R11,R11,#8
 BLT     FFill_InterpolFF
 ADDS    R9,R5,#9
 BLT     FFill_InterpolF1

FFill_InterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R0
 BEQ     FFill_StorePos
 ; process remaining samples

FFill_Interpol1
 PROCInterpol R14
 PROCPrepareNext FFill_Interpol2,FFill_Interpol1_Loop
FFill_Interpol1_Sample
 PROCConvertSampleByte yes
FFill_Interpol2
 PROCInterpol R9
 ; Store value
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 STR     R14,[R12],#4
 PROCPrepareNext FFill_Interpol_End,FFill_Interpol2_Loop
FFill_Interpol2_Sample
 PROCConvertSampleByte yes
FFill_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill_Interpol1
 MOV     R14,R0
 B       FFill_StorePos

FFill_Interpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_Interpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
FFill_Interpol1_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_Interpol1_Sample

FFill_Interpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_Interpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFill_Interpol2_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_Interpol2_Sample

 ;--------------
 ; Backward Fill

BFill_Interpol _FNAME
 ADD     R1,R1,R3
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 PROCConvertSampleByte no
 _PUSH   "R2,R4"
 B       BFill_InterpolF_End
 ; Fast mode, 8 samples in one go
BFill_InterpolF1
 PROCInterpol R2
 PROCPrepBNext BFill_InterpolF2
 PROCConvertSampleByte yes
BFill_InterpolF2
 PROCInterpol R9
 AND     R2,R2,R8
 ORR     R2,R2,R9,LSL #16
 PROCPrepBNext BFill_InterpolF3
 PROCConvertSampleByte yes
BFill_InterpolF3
 PROCInterpol R3
 PROCPrepBNext BFill_InterpolF4
 PROCConvertSampleByte yes
BFill_InterpolF4
 PROCInterpol R9
 AND     R3,R3,R8
 ORR     R3,R3,R9,LSL #16
 PROCPrepBNext BFill_InterpolF5
 PROCConvertSampleByte yes
BFill_InterpolF5
 PROCInterpol R4
 PROCPrepBNext BFill_InterpolF6
 PROCConvertSampleByte yes
BFill_InterpolF6
 PROCInterpol R9
 AND     R4,R4,R8
 ORR     R4,R4,R9,LSL #16
 PROCPrepBNext BFill_InterpolF7
 PROCConvertSampleByte yes
BFill_InterpolF7
 PROCInterpol R14
 PROCPrepBNext BFill_InterpolF8
 PROCConvertSampleByte yes
BFill_InterpolF8
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 PROCPrepBNext BFill_InterpolF9
 PROCConvertSampleByte yes
BFill_InterpolF9
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFill_InterpolF_End
 SUBS    R11,R11,#8
 BLT     BFill_InterpolFF
 SUBS    R9,R5,#9
 BGT     BFill_InterpolF1

BFill_InterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R0
 BEQ     BFill_StorePos
 ; process remaining samples

BFill_Interpol1
 PROCInterpol R14
 PROCPrepareBNext BFill_Interpol2,BFill_Interpol1_Loop
BFill_Interpol1_Sample
 PROCConvertSampleByte yes
BFill_Interpol2
 PROCInterpol R9
 ; Store value
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 STR     R14,[R12],#4
 PROCPrepareBNext BFill_Interpol_End,BFill_Interpol2_Loop
BFill_Interpol2_Sample
 PROCConvertSampleByte yes
BFill_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill_Interpol1
 MOV     R14,R0
 B       BFill_StorePos

BFill_Interpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_Interpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
BFill_Interpol1_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_Interpol1_Sample

BFill_Interpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_Interpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFill_Interpol2_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_Interpol2_Sample

 ;------------------------------------------------------------------------------
 ; 8 bit sample - Oversampled (2x, take mean of 2 samples, R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFill_Oversampled _FNAME
 ADD     R1,R1,R3
 _PUSH   "R2,R4"
 B       FFill_OversampledF_End
 ; Fast mode, 8 samples in one go
FFill_OversampledF1
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R2,R0,LSR #16
 PROCPrepareNextOver x
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R2,R2,R0
 PROCPrepareNextOver x
FFill_OversampledF3
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R3,R0,LSR #16
 PROCPrepareNextOver x
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R3,R3,R0
 PROCPrepareNextOver x
FFill_OversampledF5
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R4,R0,LSR #16
 PROCPrepareNextOver x
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R4,R4,R0
 PROCPrepareNextOver x
FFill_OversampledF7
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R14,R0,LSR #16
 PROCPrepareNextOver x
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R14,R14,R0
 PROCPrepareNextOver x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFill_OversampledF_End
 SUBS    R11,R11,#8
 BLT     FFill_OversampledFF
 ADD     R9,R5,R7,LSR #(24-3)
 ADDS    R9,R9,#2
 BLT     FFill_OversampledF1

FFill_OversampledFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFill_Oversampled1
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver FFill_Oversampled1_Loop
FFill_Oversampled2
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R14,R0,LSR #16
 PROCPrepareNextOver FFill_Oversampled2_Loop
FFill_Oversampled3
 LDRB    R9,[R1,R5]
 PROCPrepareNextOver FFill_Oversampled3_Loop
FFill_Oversampled4
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R14,R14,R0
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextOver FFill_Oversampled4_Loop
FFill_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill_Oversampled1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill_Oversampled1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_Oversampled1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
FFill_Oversampled1_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_Oversampled2

FFill_Oversampled2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_Oversampled2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill_Oversampled2_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_Oversampled3

FFill_Oversampled3_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_Oversampled3_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill_Oversampled3_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_Oversampled4

FFill_Oversampled4_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill_Oversampled4_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
FFill_Oversampled4_Loop_Back
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill_Oversampled_End

 ;--------------
 ; Backward Fill

BFill_Oversampled _FNAME
 ADD     R1,R1,R3
 SUB     R1,R1,R2
 SUB     R1,R1,#1
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 _PUSH   "R2,R4"
 B       BFill_OversampledF_End
 ; Fast mode, 8 samples in one go
BFill_OversampledF1
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R2,R0,LSR #16
 PROCPrepareBNextOver x
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R2,R2,R0
 PROCPrepareBNextOver x
BFill_OversampledF3
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R3,R0,LSR #16
 PROCPrepareBNextOver x
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R3,R3,R0
 PROCPrepareBNextOver x
BFill_OversampledF5
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R4,R0,LSR #16
 PROCPrepareBNextOver x
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R4,R4,R0
 PROCPrepareBNextOver x
BFill_OversampledF7
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R14,R0,LSR #16
 PROCPrepareBNextOver x
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver x
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R14,R14,R0
 PROCPrepareBNextOver x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFill_OversampledF_End
 SUBS    R11,R11,#8
 BLT     BFill_OversampledFF
 SUB     R9,R5,R7,LSR #(24-3)
 SUBS    R9,R9,#2
 BGT     BFill_OversampledF1

BFill_OversampledFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFill_Oversampled1
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver BFill_Oversampled1_Loop
BFill_Oversampled2
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R14,R0,LSR #16
 PROCPrepareBNextOver BFill_Oversampled2_Loop
BFill_Oversampled3
 LDRB    R9,[R1,R5]
 PROCPrepareBNextOver BFill_Oversampled3_Loop
BFill_Oversampled4
 LDRB    R0,[R1,R5]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R14,R14,R0
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextOver BFill_Oversampled4_Loop
BFill_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill_Oversampled1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill_Oversampled1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_Oversampled1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
BFill_Oversampled1_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_Oversampled2

BFill_Oversampled2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_Oversampled2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill_Oversampled2_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_Oversampled3

BFill_Oversampled3_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_Oversampled3_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill_Oversampled3_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_Oversampled4

BFill_Oversampled4_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill_Oversampled4_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
BFill_Oversampled4_Loop_Forward
 ADD     R1,R1,R2
 ADD     R1,R1,#1
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill_Oversampled_End

 ;------------------------------------------------------------------------------
 ; 8 bit sample interlaced - NoInterpol (R7 < &1000000)
 ;------------------------------------------------------------------------------

 ;-------------
 ; Forward Fill

FFillX_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #1
 LDRB    R0,[R1,R5,LSL #1]
FFillX_NoInterpol1
 MOV     R14,R0,LSL #8
 PROCPrepareNext FFillX_NoInterpol2,FFillX_NoInterpol1_Loop
FFillX_NoInterpol1_Sample
 LDRB    R0,[R1,R5,LSL #1]
FFillX_NoInterpol2
 ORR     R14,R14,R0,LSL #24
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFillX_NoInterpol_End,FFillX_NoInterpol2_Loop
FFillX_NoInterpol2_Sample
 LDRB    R0,[R1,R5,LSL #1]
FFillX_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillX_NoInterpol1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillX_NoInterpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_NoInterpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillX_NoInterpol1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_NoInterpol1_Sample

FFillX_NoInterpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_NoInterpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFillX_NoInterpol2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_NoInterpol2_Sample

 ;--------------
 ; Backward Fill

BFillX_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 LDRB    R0,[R1,R5,LSL #1]
BFillX_NoInterpol1
 MOV     R14,R0,LSL #8
 PROCPrepareBNext BFillX_NoInterpol2,BFillX_NoInterpol1_Loop
BFillX_NoInterpol1_Sample
 LDRB    R0,[R1,R5,LSL #1]
BFillX_NoInterpol2
 ORR     R14,R14,R0,LSL #24
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFillX_NoInterpol_End,BFillX_NoInterpol2_Loop
BFillX_NoInterpol2_Sample
 LDRB    R0,[R1,R5,LSL #1]
BFillX_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillX_NoInterpol1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillX_NoInterpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_NoInterpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillX_NoInterpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_NoInterpol1_Sample

BFillX_NoInterpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_NoInterpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFillX_NoInterpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_NoInterpol2_Sample

 ;------------------------------------------------------------------------------
 ; 8 bit sample interlaced - Simple (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFillX_Simple _FNAME
 ADD     R1,R1,R3,LSL #1
FFillX_Simple1
 LDRB    R9,[R1,R5,LSL #1]
 PROCPrepareNextSimple FFillX_Simple1_Loop
FFillX_Simple2
 LDRB    R0,[R1,R5,LSL #1]
 MOV     R14,R9,LSL #8
 ORR     R14,R14,R0,LSL #24
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextSimple FFillX_Simple2_Loop
FFillX_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillX_Simple1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillX_Simple1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_Simple1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_Simple2
 ; no loop? store last value and clear the rest
 MOV     R14,R9,LSL #8
 STR     R14,[R12],#4
 B       Fill_Clear
FFillX_Simple1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_Simple2

FFillX_Simple2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_Simple2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
FFillX_Simple2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_Simple_End

 ;--------------
 ; Backward Fill

BFillX_Simple _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
BFillX_Simple1
 LDRB    R9,[R1,R5,LSL #1]
 PROCPrepareBNextSimple BFillX_Simple1_Loop
BFillX_Simple2
 LDRB    R0,[R1,R5,LSL #1]
 MOV     R14,R9,LSL #8
 ORR     R14,R14,R0,LSL #24
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextSimple BFillX_Simple2_Loop
BFillX_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillX_Simple1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillX_Simple1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_Simple1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_Simple2
 ; no loop? store last value and clear the rest
 MOV     R14,R9,LSL #8
 STR     R14,[R12],#4
 B       Fill_Clear
BFillX_Simple1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_Simple2

BFillX_Simple2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_Simple2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
BFillX_Simple2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_Simple_End

 ;------------------------------------------------------------------------------
 ; 8 bit sample interlaced - Interpol (R7 < &1000000)

 ;-------------
 ; Forward Fill

FFillX_Interpol _FNAME
 ADD     R1,R1,R3,LSL #1
 PROCConvertSample2Byte no
FFillX_Interpol1
 PROCInterpol R14
 PROCPrepareNext FFillX_Interpol2,FFillX_Interpol1_Loop
FFillX_Interpol1_Sample
 PROCConvertSample2Byte yes
FFillX_Interpol2
 PROCInterpol R9
 ; Store value
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 STR     R14,[R12],#4
 PROCPrepareNext FFillX_Interpol_End,FFillX_Interpol2_Loop
FFillX_Interpol2_Sample
 PROCConvertSample2Byte yes
FFillX_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillX_Interpol1
 MOV     R14,R0
 B       FFill_StorePos

FFillX_Interpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_Interpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
FFillX_Interpol1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_Interpol1_Sample

FFillX_Interpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_Interpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFillX_Interpol2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_Interpol2_Sample

 ;--------------
 ; Backward Fill

BFillX_Interpol _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 PROCConvertSample2Byte no
BFillX_Interpol1
 PROCInterpol R14
 PROCPrepareBNext BFillX_Interpol2,BFillX_Interpol1_Loop
BFillX_Interpol1_Sample
 PROCConvertSample2Byte yes
BFillX_Interpol2
 PROCInterpol R9
 ; Store value
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 STR     R14,[R12],#4
 PROCPrepareBNext BFillX_Interpol_End,BFillX_Interpol2_Loop
BFillX_Interpol2_Sample
 PROCConvertSample2Byte yes
BFillX_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillX_Interpol1
 MOV     R14,R0
 B       BFill_StorePos

BFillX_Interpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_Interpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
BFillX_Interpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_Interpol1_Sample

BFillX_Interpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_Interpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFillX_Interpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_Interpol2_Sample

 ;------------------------------------------------------------------------------
 ; 8 bit sample interlaced - Oversampled (R7 > &1000000)

 ;-------------
 ; Forward Fill

FFillX_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #1
FFillX_Oversampled1
 LDRB    R9,[R1,R5,LSL #1]
 PROCPrepareNextOver FFillX_Oversampled1_Loop
FFillX_Oversampled2
 LDRB    R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R14,R0,LSR #16
 PROCPrepareNextOver FFillX_Oversampled2_Loop
FFillX_Oversampled3
 LDRB    R9,[R1,R5,LSL #1]
 PROCPrepareNextOver FFillX_Oversampled3_Loop
FFillX_Oversampled4
 LDRB    R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R14,R14,R0
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextOver FFillX_Oversampled4_Loop
FFillX_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillX_Oversampled1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillX_Oversampled1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_Oversampled1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
FFillX_Oversampled1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_Oversampled2

FFillX_Oversampled2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_Oversampled2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillX_Oversampled2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_Oversampled3

FFillX_Oversampled3_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_Oversampled3_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillX_Oversampled3_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_Oversampled4

FFillX_Oversampled4_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillX_Oversampled4_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillX_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
FFillX_Oversampled4_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillX_Oversampled_End

 ;--------------
 ; Backward Fill

BFillX_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
BFillX_Oversampled1
 LDRB    R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver BFillX_Oversampled1_Loop
BFillX_Oversampled2
 LDRB    R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 MOV     R14,R0,LSL #16
 PROCPrepareBNextOver BFillX_Oversampled2_Loop
BFillX_Oversampled3
 LDRB    R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver BFillX_Oversampled3_Loop
BFillX_Oversampled4
 LDRB    R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #24
 MOV     R9,R9,ASR #1
 MOV     R0,R0,LSL #24
 ADD     R0,R9,R0,ASR #1
 ORR     R14,R14,R0
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextOver BFillX_Oversampled4_Loop
BFillX_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillX_Oversampled1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillX_Oversampled1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_Oversampled1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
BFillX_Oversampled1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_Oversampled2

BFillX_Oversampled2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_Oversampled2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillX_Oversampled2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_Oversampled3

BFillX_Oversampled3_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_Oversampled3_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillX_Oversampled3_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_Oversampled4

BFillX_Oversampled4_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillX_Oversampled4_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillX_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
BFillX_Oversampled4_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillX_Oversampled_End

 ;------------------------------------------------------------------------------
 ; 16 bit sample - NoInterpol (R7 < &1000000)
 ;------------------------------------------------------------------------------

 ;-------------
 ; Forward Fill

FFill16_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #1
 LDR     R0,[R1,R5,LSL #1]
 _PUSH   "R2,R4"
 B       FFill16_NoInterpolF_End
 ; Fast mode, 8 samples in one go
FFill16_NoInterpolF1
 AND     R2,R0,R8
 PROCPrepNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ORR     R2,R2,R0,LSL #16
 PROCPrepNext x
 LDRCS   R0,[R1,R5,LSL #1]
 AND     R3,R0,R8
 PROCPrepNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ORR     R3,R3,R0,LSL #16
 PROCPrepNext x
 LDRCS   R0,[R1,R5,LSL #1]
 AND     R4,R0,R8
 PROCPrepNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ORR     R4,R4,R0,LSL #16
 PROCPrepNext x
 LDRCS   R0,[R1,R5,LSL #1]
 AND     R14,R0,R8
 PROCPrepNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ORR     R14,R14,R0,LSL #16
 PROCPrepNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFill16_NoInterpolF_End
 SUBS    R11,R11,#8
 BLT     FFill16_NoInterpolFF
 ADDS    R9,R5,#9
 BLT     FFill16_NoInterpolF1

FFill16_NoInterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFill16_NoInterpol1
 AND     R14,R0,R8
 PROCPrepareNext FFill16_NoInterpol2,FFill16_NoInterpol1_Loop
FFill16_NoInterpol1_Sample
 LDR     R0,[R1,R5,LSL #1]
FFill16_NoInterpol2
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFill16_NoInterpol_End,FFill16_NoInterpol2_Loop
FFill16_NoInterpol2_Sample
 LDR     R0,[R1,R5,LSL #1]
FFill16_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill16_NoInterpol1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill16_NoInterpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_NoInterpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16_NoInterpol1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_NoInterpol1_Sample

FFill16_NoInterpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_NoInterpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFill16_NoInterpol2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_NoInterpol2_Sample

 ;--------------
 ; Backward Fill

BFill16_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 LDR     R0,[R1,R5,LSL #1]
 _PUSH   "R2,R4"
 B       BFill16_NoInterpolF_End
 ; Fast mode, 8 samples in one go
BFill16_NoInterpolF1
 AND     R2,R0,R8
 PROCPrepBNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ORR     R2,R2,R0,LSL #16
 PROCPrepBNext x
 LDRCS   R0,[R1,R5,LSL #1]
 AND     R3,R0,R8
 PROCPrepBNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ORR     R3,R3,R0,LSL #16
 PROCPrepBNext x
 LDRCS   R0,[R1,R5,LSL #1]
 AND     R4,R0,R8
 PROCPrepBNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ORR     R4,R4,R0,LSL #16
 PROCPrepBNext x
 LDRCS   R0,[R1,R5,LSL #1]
 AND     R14,R0,R8
 PROCPrepBNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ORR     R14,R14,R0,LSL #16
 PROCPrepBNext x
 LDRCS   R0,[R1,R5,LSL #1]
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFill16_NoInterpolF_End
 SUBS    R11,R11,#8
 BLT     BFill16_NoInterpolFF
 SUBS    R9,R5,#9
 BGT     BFill16_NoInterpolF1

BFill16_NoInterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFill16_NoInterpol1
 AND     R14,R0,R8
 PROCPrepareBNext BFill16_NoInterpol2,BFill16_NoInterpol1_Loop
BFill16_NoInterpol1_Sample
 LDR     R0,[R1,R5,LSL #1]
BFill16_NoInterpol2
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFill16_NoInterpol_End,BFill16_NoInterpol2_Loop
BFill16_NoInterpol2_Sample
 LDR     R0,[R1,R5,LSL #1]
BFill16_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill16_NoInterpol1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill16_NoInterpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_NoInterpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16_NoInterpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_NoInterpol1_Sample

BFill16_NoInterpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_NoInterpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFill16_NoInterpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_NoInterpol2_Sample

 ;------------------------------------------------------------------------------
 ; 16 bit sample - Simple (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFill16_Simple _FNAME
 ADD     R1,R1,R3,LSL #1
 _PUSH   "R2,R4"
 B       FFill16_SimpleF_End
 ; Fast mode, 8 samples in one go
FFill16_SimpleF1
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextSimple x
 LDR     R0,[R1,R5,LSL #1]
 AND     R2,R9,R8
 ORR     R2,R2,R0,LSL #16
 PROCPrepareNextSimple x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextSimple x
 LDR     R0,[R1,R5,LSL #1]
 AND     R3,R9,R8
 ORR     R3,R3,R0,LSL #16
 PROCPrepareNextSimple x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextSimple x
 LDR     R0,[R1,R5,LSL #1]
 AND     R4,R9,R8
 ORR     R4,R4,R0,LSL #16
 PROCPrepareNextSimple x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextSimple x
 LDR     R0,[R1,R5,LSL #1]
 AND     R14,R9,R8
 ORR     R14,R14,R0,LSL #16
 PROCPrepareNextSimple x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFill16_SimpleF_End
 SUBS    R11,R11,#8
 BLT     FFill16_SimpleFF
 ADD     R9,R5,R7,LSR #(24-3)
 ADDS    R9,R9,#2
 BLT     FFill16_SimpleF1

FFill16_SimpleFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFill16_Simple1
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextSimple FFill16_Simple1_Loop
FFill16_Simple2
 LDR     R0,[R1,R5,LSL #1]
 AND     R14,R9,R8
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextSimple FFill16_Simple2_Loop
FFill16_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill16_Simple1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill16_Simple1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_Simple1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_Simple2
 ; no loop? store last value and clear the rest
 AND     R14,R9,R8
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16_Simple1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_Simple2

FFill16_Simple2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_Simple2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
FFill16_Simple2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_Simple_End

 ;--------------
 ; Backward Fill

BFill16_Simple _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 _PUSH   "R2,R4"
 B       BFill16_SimpleF_End
 ; Fast mode, 8 samples in one go
BFill16_SimpleF1
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextSimple x
 LDR     R0,[R1,R5,LSL #1]
 AND     R2,R9,R8
 ORR     R2,R2,R0,LSL #16
 PROCPrepareBNextSimple x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextSimple x
 LDR     R0,[R1,R5,LSL #1]
 AND     R3,R9,R8
 ORR     R3,R3,R0,LSL #16
 PROCPrepareBNextSimple x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextSimple x
 LDR     R0,[R1,R5,LSL #1]
 AND     R4,R9,R8
 ORR     R4,R4,R0,LSL #16
 PROCPrepareBNextSimple x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextSimple x
 LDR     R0,[R1,R5,LSL #1]
 AND     R14,R9,R8
 ORR     R14,R14,R0,LSL #16
 PROCPrepareBNextSimple x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFill16_SimpleF_End
 SUBS    R11,R11,#8
 BLT     BFill16_SimpleFF
 SUB     R9,R5,R7,LSR #(24-3)
 SUBS    R9,R9,#2
 BGT     BFill16_SimpleF1

BFill16_SimpleFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFill16_Simple1
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextSimple BFill16_Simple1_Loop
BFill16_Simple2
 LDR     R0,[R1,R5,LSL #1]
 AND     R14,R9,R8
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextSimple BFill16_Simple2_Loop
BFill16_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill16_Simple1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill16_Simple1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_Simple1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_Simple2
 ; no loop? store last value and clear the rest
 AND     R14,R9,R8
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16_Simple1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_Simple2

BFill16_Simple2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_Simple2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
BFill16_Simple2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_Simple_End

 ;------------------------------------------------------------------------------
 ; 16 bit sample - Interpol (R7 < &1000000)

 ;-------------
 ; Forward Fill

FFill16_Interpol _FNAME
 ADD     R1,R1,R3,LSL #1
 PROCConvertSampleHalfWord no
 _PUSH   "R2,R4"
 B       FFill16_InterpolF_End
 ; Fast mode, 8 samples in one go
FFill16_InterpolF1
 PROCInterpol R2
 PROCPrepNext FFill16_InterpolF2
 PROCConvertSampleHalfWord yes
FFill16_InterpolF2
 PROCInterpol R9
 AND     R2,R2,R8
 ORR     R2,R2,R9,LSL #16
 PROCPrepNext FFill16_InterpolF3
 PROCConvertSampleHalfWord yes
FFill16_InterpolF3
 PROCInterpol R3
 PROCPrepNext FFill16_InterpolF4
 PROCConvertSampleHalfWord yes
FFill16_InterpolF4
 PROCInterpol R9
 AND     R3,R3,R8
 ORR     R3,R3,R9,LSL #16
 PROCPrepNext FFill16_InterpolF5
 PROCConvertSampleHalfWord yes
FFill16_InterpolF5
 PROCInterpol R4
 PROCPrepNext FFill16_InterpolF6
 PROCConvertSampleHalfWord yes
FFill16_InterpolF6
 PROCInterpol R9
 AND     R4,R4,R8
 ORR     R4,R4,R9,LSL #16
 PROCPrepNext FFill16_InterpolF7
 PROCConvertSampleHalfWord yes
FFill16_InterpolF7
 PROCInterpol R14
 PROCPrepNext FFill16_InterpolF8
 PROCConvertSampleHalfWord yes
FFill16_InterpolF8
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 PROCPrepNext FFill16_InterpolF9
 PROCConvertSampleHalfWord yes
FFill16_InterpolF9
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFill16_InterpolF_End
 SUBS    R11,R11,#8
 BLT     FFill16_InterpolFF
 ADDS    R9,R5,#9
 BLT     FFill16_InterpolF1

FFill16_InterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R0
 BEQ     FFill_StorePos
 ; process remaining samples

FFill16_Interpol1
 PROCInterpol R14
 PROCPrepareNext FFill16_Interpol2,FFill16_Interpol1_Loop
FFill16_Interpol1_Sample
 PROCConvertSampleHalfWord yes
FFill16_Interpol2
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFill16_Interpol_End,FFill16_Interpol2_Loop
FFill16_Interpol2_Sample
 PROCConvertSampleHalfWord yes
FFill16_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill16_Interpol1
 MOV     R14,R0
 B       FFill_StorePos

FFill16_Interpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_Interpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16_Interpol1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_Interpol1_Sample

FFill16_Interpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_Interpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFill16_Interpol2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_Interpol2_Sample

 ;--------------
 ; Backward Fill

BFill16_Interpol _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 PROCConvertSampleHalfWord no
 _PUSH   "R2,R4"
 B       BFill16_InterpolF_End
 ; Fast mode, 8 samples in one go
BFill16_InterpolF1
 PROCInterpol R2
 PROCPrepBNext BFill16_InterpolF2
 PROCConvertSampleHalfWord yes
BFill16_InterpolF2
 PROCInterpol R9
 AND     R2,R2,R8
 ORR     R2,R2,R9,LSL #16
 PROCPrepBNext BFill16_InterpolF3
 PROCConvertSampleHalfWord yes
BFill16_InterpolF3
 PROCInterpol R3
 PROCPrepBNext BFill16_InterpolF4
 PROCConvertSampleHalfWord yes
BFill16_InterpolF4
 PROCInterpol R9
 AND     R3,R3,R8
 ORR     R3,R3,R9,LSL #16
 PROCPrepBNext BFill16_InterpolF5
 PROCConvertSampleHalfWord yes
BFill16_InterpolF5
 PROCInterpol R4
 PROCPrepBNext BFill16_InterpolF6
 PROCConvertSampleHalfWord yes
BFill16_InterpolF6
 PROCInterpol R9
 AND     R4,R4,R8
 ORR     R4,R4,R9,LSL #16
 PROCPrepBNext BFill16_InterpolF7
 PROCConvertSampleHalfWord yes
BFill16_InterpolF7
 PROCInterpol R14
 PROCPrepBNext BFill16_InterpolF8
 PROCConvertSampleHalfWord yes
BFill16_InterpolF8
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 PROCPrepBNext BFill16_InterpolF9
 PROCConvertSampleHalfWord yes
BFill16_InterpolF9
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFill16_InterpolF_End
 SUBS    R11,R11,#8
 BLT     BFill16_InterpolFF
 SUBS    R9,R5,#9
 BGT     BFill16_InterpolF1

BFill16_InterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R0
 BEQ     BFill_StorePos
 ; process remaining samples

BFill16_Interpol1
 PROCInterpol R14
 PROCPrepareBNext BFill16_Interpol2,BFill16_Interpol1_Loop
BFill16_Interpol1_Sample
 PROCConvertSampleHalfWord yes
BFill16_Interpol2
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFill16_Interpol_End,BFill16_Interpol2_Loop
BFill16_Interpol2_Sample
 PROCConvertSampleHalfWord yes
BFill16_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill16_Interpol1
 MOV     R14,R0
 B       BFill_StorePos

BFill16_Interpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_Interpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16_Interpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_Interpol1_Sample

BFill16_Interpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_Interpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFill16_Interpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_Interpol2_Sample

 ;------------------------------------------------------------------------------
 ; 16 bit sample - Oversampled (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFill16_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #1
 _PUSH   "R2,R4"
 B       FFill16_OversampledF_End
 ; Fast mode, 8 samples in one go
FFill16_OversampledF1
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R2,R0,R8
 PROCPrepareNextOver x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R2,R2,R0,LSL #16
 PROCPrepareNextOver x
FFill16_OversampledF3
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R3,R0,R8
 PROCPrepareNextOver x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R3,R3,R0,LSL #16
 PROCPrepareNextOver x
FFill16_OversampledF5
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R4,R0,R8
 PROCPrepareNextOver x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R4,R4,R0,LSL #16
 PROCPrepareNextOver x
FFill16_OversampledF7
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R14,R0,R8
 PROCPrepareNextOver x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R14,R14,R0,LSL #16
 PROCPrepareNextOver x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFill16_OversampledF_End
 SUBS    R11,R11,#8
 BLT     FFill16_OversampledFF
 ADD     R9,R5,R7,LSR #(24-3)
 ADDS    R9,R9,#2
 BLT     FFill16_OversampledF1

FFill16_OversampledFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFill16_Oversampled1
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver FFill16_Oversampled1_Loop
FFill16_Oversampled2
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R14,R0,R8
 PROCPrepareNextOver FFill16_Oversampled2_Loop
FFill16_Oversampled3
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareNextOver FFill16_Oversampled3_Loop
FFill16_Oversampled4
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextOver FFill16_Oversampled4_Loop
FFill16_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill16_Oversampled1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill16_Oversampled1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_Oversampled1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16_Oversampled1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_Oversampled2

FFill16_Oversampled2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_Oversampled2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16_Oversampled2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_Oversampled3

FFill16_Oversampled3_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_Oversampled3_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16_Oversampled3_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_Oversampled4

FFill16_Oversampled4_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16_Oversampled4_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
FFill16_Oversampled4_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16_Oversampled_End

 ;--------------
 ; Backward Fill

BFill16_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 _PUSH   "R2,R4"
 B       BFill16_OversampledF_End
 ; Fast mode, 8 samples in one go
BFill16_OversampledF1
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R2,R0,R8
 PROCPrepareBNextOver x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R2,R2,R0,LSL #16
 PROCPrepareBNextOver x
BFill16_OversampledF3
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R3,R0,R8
 PROCPrepareBNextOver x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R3,R3,R0,LSL #16
 PROCPrepareBNextOver x
BFill16_OversampledF5
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R4,R0,R8
 PROCPrepareBNextOver x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R4,R4,R0,LSL #16
 PROCPrepareBNextOver x
BFill16_OversampledF7
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R14,R0,R8
 PROCPrepareBNextOver x
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver x
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R14,R14,R0,LSL #16
 PROCPrepareBNextOver x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFill16_OversampledF_End
 SUBS    R11,R11,#8
 BLT     BFill16_OversampledFF
 SUB     R9,R5,R7,LSR #(24-3)
 SUBS    R9,R9,#2
 BGT     BFill16_OversampledF1

BFill16_OversampledFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFill16_Oversampled1
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver BFill16_Oversampled1_Loop
BFill16_Oversampled2
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R14,R0,R8
 PROCPrepareBNextOver BFill16_Oversampled2_Loop
BFill16_Oversampled3
 LDR     R9,[R1,R5,LSL #1]
 PROCPrepareBNextOver BFill16_Oversampled3_Loop
BFill16_Oversampled4
 LDR     R0,[R1,R5,LSL #1]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextOver BFill16_Oversampled4_Loop
BFill16_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill16_Oversampled1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill16_Oversampled1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_Oversampled1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16_Oversampled1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_Oversampled2

BFill16_Oversampled2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_Oversampled2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16_Oversampled2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_Oversampled3

BFill16_Oversampled3_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_Oversampled3_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16_Oversampled3_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_Oversampled4

BFill16_Oversampled4_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16_Oversampled4_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
BFill16_Oversampled4_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16_Oversampled_End

 ;------------------------------------------------------------------------------
 ; 16 bit sample interlaced - NoInterpol (R7 < &1000000)
 ;------------------------------------------------------------------------------

 ;-------------
 ; Forward Fill

FFill16X_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #2
 LDR     R0,[R1,R5,LSL #2]
FFill16X_NoInterpol1
 AND     R14,R0,R8
 PROCPrepareNext FFill16X_NoInterpol2,FFill16X_NoInterpol1_Loop
FFill16X_NoInterpol1_Sample
 LDR     R0,[R1,R5,LSL #2]
FFill16X_NoInterpol2
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFill16X_NoInterpol_End,FFill16X_NoInterpol2_Loop
FFill16X_NoInterpol2_Sample
 LDR     R0,[R1,R5,LSL #2]
FFill16X_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill16X_NoInterpol1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill16X_NoInterpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_NoInterpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16X_NoInterpol1_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_NoInterpol1_Sample

FFill16X_NoInterpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_NoInterpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFill16X_NoInterpol2_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_NoInterpol2_Sample

 ;--------------
 ; Backward Fill

BFill16X_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #2
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 LDR     R0,[R1,R5,LSL #2]
BFill16X_NoInterpol1
 AND     R14,R0,R8
 PROCPrepareBNext BFill16X_NoInterpol2,BFill16X_NoInterpol1_Loop
BFill16X_NoInterpol1_Sample
 LDR     R0,[R1,R5,LSL #2]
BFill16X_NoInterpol2
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFill16X_NoInterpol_End,BFill16X_NoInterpol2_Loop
BFill16X_NoInterpol2_Sample
 LDR     R0,[R1,R5,LSL #2]
BFill16X_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill16X_NoInterpol1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill16X_NoInterpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_NoInterpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16X_NoInterpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_NoInterpol1_Sample

BFill16X_NoInterpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_NoInterpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFill16X_NoInterpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_NoInterpol2_Sample

 ;------------------------------------------------------------------------------
 ; 16 bit sample interlaced - Simple (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFill16X_Simple _FNAME
 ADD     R1,R1,R3,LSL #2
FFill16X_Simple1
 LDR     R9,[R1,R5,LSL #2]
 PROCPrepareNextSimple FFill16X_Simple1_Loop
FFill16X_Simple2
 LDR     R0,[R1,R5,LSL #2]
 AND     R14,R9,R8
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextSimple FFill16X_Simple2_Loop
FFill16X_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill16X_Simple1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill16X_Simple1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_Simple1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_Simple2
 ; no loop? store last value and clear the rest
 AND     R14,R9,R8
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16X_Simple1_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_Simple2

FFill16X_Simple2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_Simple2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
FFill16X_Simple2_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_Simple_End

 ;--------------
 ; Backward Fill

BFill16X_Simple _FNAME
 ADD     R1,R1,R3,LSL #2
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 ADD     R5,R5,R2
 ADD     R5,R5,#1
BFill16X_Simple1
 LDR     R9,[R1,R5,LSL #2]
 PROCPrepareBNextSimple BFill16X_Simple1_Loop
BFill16X_Simple2
 LDR     R0,[R1,R5,LSL #2]
 AND     R14,R9,R8
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextSimple BFill16X_Simple2_Loop
BFill16X_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill16X_Simple1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill16X_Simple1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_Simple1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_Simple2
 ; no loop? store last value and clear the rest
 AND     R14,R9,R8
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16X_Simple1_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_Simple2

BFill16X_Simple2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_Simple2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
BFill16X_Simple2_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_Simple_End

 ;------------------------------------------------------------------------------
 ; 16 bit sample interlaced - Interpol (R7 < &1000000)

 ;-------------
 ; Forward Fill

FFill16X_Interpol _FNAME
 ADD     R1,R1,R3,LSL #2
 PROCConvertSample4HalfWord no
FFill16X_Interpol1
 PROCInterpol R14
 PROCPrepareNext FFill16X_Interpol2,FFill16X_Interpol1_Loop
FFill16X_Interpol1_Sample
 PROCConvertSample4HalfWord yes
FFill16X_Interpol2
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFill16X_Interpol_End,FFill16X_Interpol2_Loop
FFill16X_Interpol2_Sample
 PROCConvertSample4HalfWord yes
FFill16X_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill16X_Interpol1
 MOV     R14,R0
 B       FFill_StorePos

FFill16X_Interpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_Interpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16X_Interpol1_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_Interpol1_Sample

FFill16X_Interpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_Interpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFill16X_Interpol2_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_Interpol2_Sample

 ;--------------
 ; Backward Fill

BFill16X_Interpol _FNAME
 ADD     R1,R1,R3,LSL #2
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 PROCConvertSample4HalfWord no
BFill16X_Interpol1
 PROCInterpol R14
 PROCPrepareBNext BFill16X_Interpol2,BFill16X_Interpol1_Loop
BFill16X_Interpol1_Sample
 PROCConvertSample4HalfWord yes
BFill16X_Interpol2
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFill16X_Interpol_End,BFill16X_Interpol2_Loop
BFill16X_Interpol2_Sample
 PROCConvertSample4HalfWord yes
BFill16X_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill16X_Interpol1
 MOV     R14,R0
 B       BFill_StorePos

BFill16X_Interpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_Interpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16X_Interpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_Interpol1_Sample

BFill16X_Interpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_Interpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFill16X_Interpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_Interpol2_Sample

 ;------------------------------------------------------------------------------
 ; 16 bit sample interlaced - Oversampled (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFill16X_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #2
FFill16X_Oversampled1
 LDR     R9,[R1,R5,LSL #2]
 PROCPrepareNextOver FFill16X_Oversampled1_Loop
FFill16X_Oversampled2
 LDR     R0,[R1,R5,LSL #2]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R14,R0,R8
 PROCPrepareNextOver FFill16X_Oversampled2_Loop
FFill16X_Oversampled3
 LDR     R9,[R1,R5,LSL #2]
 PROCPrepareNextOver FFill16X_Oversampled3_Loop
FFill16X_Oversampled4
 LDR     R0,[R1,R5,LSL #2]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextOver FFill16X_Oversampled4_Loop
FFill16X_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFill16X_Oversampled1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFill16X_Oversampled1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_Oversampled1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16X_Oversampled1_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_Oversampled2

FFill16X_Oversampled2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_Oversampled2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16X_Oversampled2_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_Oversampled3

FFill16X_Oversampled3_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_Oversampled3_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFill16X_Oversampled3_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_Oversampled4

FFill16X_Oversampled4_Loop
 TST     R4,#stream_flag_backward
 BNE     FFill16X_Oversampled4_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFill16X_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
FFill16X_Oversampled4_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFill16X_Oversampled_End

 ;--------------
 ; Backward Fill

BFill16X_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #2
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 ADD     R5,R5,R2
 ADD     R5,R5,#1
BFill16X_Oversampled1
 LDR     R9,[R1,R5,LSL #2]
 PROCPrepareBNextOver BFill16X_Oversampled1_Loop
BFill16X_Oversampled2
 LDR     R0,[R1,R5,LSL #2]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 AND     R14,R0,R8
 PROCPrepareBNextOver BFill16X_Oversampled2_Loop
BFill16X_Oversampled3
 LDR     R9,[R1,R5,LSL #2]
 PROCPrepareBNextOver BFill16X_Oversampled3_Loop
BFill16X_Oversampled4
 LDR     R0,[R1,R5,LSL #2]
 MOV     R9,R9,LSL #16
 MOV     R9,R9,ASR #17
 MOV     R0,R0,LSL #16
 ADD     R0,R9,R0,ASR #17
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextOver BFill16X_Oversampled4_Loop
BFill16X_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFill16X_Oversampled1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFill16X_Oversampled1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_Oversampled1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16X_Oversampled1_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_Oversampled2

BFill16X_Oversampled2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_Oversampled2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16X_Oversampled2_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_Oversampled3

BFill16X_Oversampled3_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_Oversampled3_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFill16X_Oversampled3_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_Oversampled4

BFill16X_Oversampled4_Loop
 TST     R4,#stream_flag_forward
 BNE     BFill16X_Oversampled4_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFill16X_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
BFill16X_Oversampled4_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFill16X_Oversampled_End

 ;------------------------------------------------------------------------------
 ; LDRH 16 bit sample - NoInterpol (R7 < &1000000)
 ;------------------------------------------------------------------------------

 ;-------------
 ; Forward Fill

FFillH_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #1
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 _PUSH   "R2,R4"
 B       FFillH_NoInterpolF_End
 ; Fast mode, 8 samples in one go
FFillH_NoInterpolF1
 AND     R2,R0,R8
 PROCPrepNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ORR     R2,R2,R0,LSL #16
 PROCPrepNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 AND     R3,R0,R8
 PROCPrepNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ORR     R3,R3,R0,LSL #16
 PROCPrepNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 AND     R4,R0,R8
 PROCPrepNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ORR     R4,R4,R0,LSL #16
 PROCPrepNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 AND     R14,R0,R8
 PROCPrepNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ORR     R14,R14,R0,LSL #16
 PROCPrepNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFillH_NoInterpolF_End
 SUBS    R11,R11,#8
 BLT     FFillH_NoInterpolFF
 ADDS    R9,R5,#9
 BLT     FFillH_NoInterpolF1

FFillH_NoInterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFillH_NoInterpol1
 AND     R14,R0,R8
 PROCPrepareNext FFillH_NoInterpol2,FFillH_NoInterpol1_Loop
FFillH_NoInterpol1_Sample
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
FFillH_NoInterpol2
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFillH_NoInterpol_End,FFillH_NoInterpol2_Loop
FFillH_NoInterpol2_Sample
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
FFillH_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillH_NoInterpol1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillH_NoInterpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_NoInterpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillH_NoInterpol1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_NoInterpol1_Sample

FFillH_NoInterpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_NoInterpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFillH_NoInterpol2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_NoInterpol2_Sample

 ;--------------
 ; Backward Fill

BFillH_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 _PUSH   "R2,R4"
 B       BFillH_NoInterpolF_End
 ; Fast mode, 8 samples in one go
BFillH_NoInterpolF1
 AND     R2,R0,R8
 PROCPrepBNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ORR     R2,R2,R0,LSL #16
 PROCPrepBNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 AND     R3,R0,R8
 PROCPrepBNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ORR     R3,R3,R0,LSL #16
 PROCPrepBNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 AND     R4,R0,R8
 PROCPrepBNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ORR     R4,R4,R0,LSL #16
 PROCPrepBNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 AND     R14,R0,R8
 PROCPrepBNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ORR     R14,R14,R0,LSL #16
 PROCPrepBNext x
 MOVCS   R0,R5,LSL #1
 LDRCSH  R0,[R1,R0]
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFillH_NoInterpolF_End
 SUBS    R11,R11,#8
 BLT     BFillH_NoInterpolFF
 SUBS    R9,R5,#9
 BGT     BFillH_NoInterpolF1

BFillH_NoInterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFillH_NoInterpol1
 AND     R14,R0,R8
 PROCPrepareBNext BFillH_NoInterpol2,BFillH_NoInterpol1_Loop
BFillH_NoInterpol1_Sample
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
BFillH_NoInterpol2
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFillH_NoInterpol_End,BFillH_NoInterpol2_Loop
BFillH_NoInterpol2_Sample
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
BFillH_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillH_NoInterpol1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillH_NoInterpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_NoInterpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillH_NoInterpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_NoInterpol1_Sample

BFillH_NoInterpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_NoInterpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFillH_NoInterpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_NoInterpol2_Sample

 ;------------------------------------------------------------------------------
 ; LDRH 16 bit sample - Simple (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFillH_Simple _FNAME
 ADD     R1,R1,R3,LSL #1
 _PUSH   "R2,R4"
 B       FFillH_SimpleF_End
 ; Fast mode, 8 samples in one go
FFillH_SimpleF1
 MOV     R0,R5,LSL #1
 LDRH    R2,[R1,R0]
 PROCPrepareNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ORR     R2,R2,R0,LSL #16
 PROCPrepareNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R3,[R1,R0]
 PROCPrepareNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ORR     R3,R3,R0,LSL #16
 PROCPrepareNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R4,[R1,R0]
 PROCPrepareNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ORR     R4,R4,R0,LSL #16
 PROCPrepareNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R14,[R1,R0]
 PROCPrepareNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ORR     R14,R14,R0,LSL #16
 PROCPrepareNextSimple x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFillH_SimpleF_End
 SUBS    R11,R11,#8
 BLT     FFillH_SimpleFF
 ADD     R9,R5,R7,LSR #(24-3)
 ADDS    R9,R9,#2
 BLT     FFillH_SimpleF1

FFillH_SimpleFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFillH_Simple1
 MOV     R0,R5,LSL #1
 LDRH    R14,[R1,R0]
 PROCPrepareNextSimple FFillH_Simple1_Loop
FFillH_Simple2
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ; Store value
 ORR     R14,R14,R0,LSL #16
 STR     R14,[R12],#4
 PROCPrepareNextSimple FFillH_Simple2_Loop
FFillH_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillH_Simple1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillH_Simple1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_Simple1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_Simple2
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillH_Simple1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_Simple2

FFillH_Simple2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_Simple2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
FFillH_Simple2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_Simple_End

 ;--------------
 ; Backward Fill

BFillH_Simple _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 _PUSH   "R2,R4"
 B       BFillH_SimpleF_End
 ; Fast mode, 8 samples in one go
BFillH_SimpleF1
 MOV     R0,R5,LSL #1
 LDRH    R2,[R1,R0]
 PROCPrepareBNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ORR     R2,R2,R0,LSL #16
 PROCPrepareBNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R3,[R1,R0]
 PROCPrepareBNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ORR     R3,R3,R0,LSL #16
 PROCPrepareBNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R4,[R1,R0]
 PROCPrepareBNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ORR     R4,R4,R0,LSL #16
 PROCPrepareBNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R14,[R1,R0]
 PROCPrepareBNextSimple x
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ORR     R14,R14,R0,LSL #16
 PROCPrepareBNextSimple x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFillH_SimpleF_End
 SUBS    R11,R11,#8
 BLT     BFillH_SimpleFF
 SUB     R9,R5,R7,LSR #(24-3)
 SUBS    R9,R9,#2
 BGT     BFillH_SimpleF1

BFillH_SimpleFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFillH_Simple1
 MOV     R0,R5,LSL #1
 LDRH    R14,[R1,R0]
 PROCPrepareBNextSimple BFillH_Simple1_Loop
BFillH_Simple2
 MOV     R0,R5,LSL #1
 LDRH    R0,[R1,R0]
 ; Store value
 ORR     R14,R14,R0,LSL #16
 STR     R14,[R12],#4
 PROCPrepareBNextSimple BFillH_Simple2_Loop
BFillH_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillH_Simple1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillH_Simple1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_Simple1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_Simple2
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillH_Simple1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_Simple2

BFillH_Simple2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_Simple2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
BFillH_Simple2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_Simple_End

 ;------------------------------------------------------------------------------
 ; LDRH 16 bit sample - Interpol (R7 < &1000000)

 ;-------------
 ; Forward Fill

FFillH_Interpol _FNAME
 ADD     R1,R1,R3,LSL #1
 PROCConvertHSampleHalfWord no
 _PUSH   "R2,R4"
 B       FFillH_InterpolF_End
 ; Fast mode, 8 samples in one go
FFillH_InterpolF1
 PROCInterpol R2
 PROCPrepNext FFillH_InterpolF2
 PROCConvertHSampleHalfWord yes
FFillH_InterpolF2
 PROCInterpol R9
 AND     R2,R2,R8
 ORR     R2,R2,R9,LSL #16
 PROCPrepNext FFillH_InterpolF3
 PROCConvertHSampleHalfWord yes
FFillH_InterpolF3
 PROCInterpol R3
 PROCPrepNext FFillH_InterpolF4
 PROCConvertHSampleHalfWord yes
FFillH_InterpolF4
 PROCInterpol R9
 AND     R3,R3,R8
 ORR     R3,R3,R9,LSL #16
 PROCPrepNext FFillH_InterpolF5
 PROCConvertHSampleHalfWord yes
FFillH_InterpolF5
 PROCInterpol R4
 PROCPrepNext FFillH_InterpolF6
 PROCConvertHSampleHalfWord yes
FFillH_InterpolF6
 PROCInterpol R9
 AND     R4,R4,R8
 ORR     R4,R4,R9,LSL #16
 PROCPrepNext FFillH_InterpolF7
 PROCConvertHSampleHalfWord yes
FFillH_InterpolF7
 PROCInterpol R14
 PROCPrepNext FFillH_InterpolF8
 PROCConvertHSampleHalfWord yes
FFillH_InterpolF8
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 PROCPrepNext FFillH_InterpolF9
 PROCConvertHSampleHalfWord yes
FFillH_InterpolF9
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFillH_InterpolF_End
 SUBS    R11,R11,#8
 BLT     FFillH_InterpolFF
 ADDS    R9,R5,#9
 BLT     FFillH_InterpolF1

FFillH_InterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R0
 BEQ     FFill_StorePos
 ; process remaining samples

FFillH_Interpol1
 PROCInterpol R14
 PROCPrepareNext FFillH_Interpol2,FFillH_Interpol1_Loop
FFillH_Interpol1_Sample
 PROCConvertHSampleHalfWord yes
FFillH_Interpol2
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFillH_Interpol_End,FFillH_Interpol2_Loop
FFillH_Interpol2_Sample
 PROCConvertHSampleHalfWord yes
FFillH_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillH_Interpol1
 MOV     R14,R0
 B       FFill_StorePos

FFillH_Interpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_Interpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
FFillH_Interpol1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_Interpol1_Sample

FFillH_Interpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_Interpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFillH_Interpol2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_Interpol2_Sample

 ;--------------
 ; Backward Fill

BFillH_Interpol _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 PROCConvertHSampleHalfWord no
 _PUSH   "R2,R4"
 B       BFillH_InterpolF_End
 ; Fast mode, 8 samples in one go
BFillH_InterpolF1
 PROCInterpol R2
 PROCPrepBNext BFillH_InterpolF2
 PROCConvertHSampleHalfWord yes
BFillH_InterpolF2
 PROCInterpol R9
 AND     R2,R2,R8
 ORR     R2,R2,R9,LSL #16
 PROCPrepBNext BFillH_InterpolF3
 PROCConvertHSampleHalfWord yes
BFillH_InterpolF3
 PROCInterpol R3
 PROCPrepBNext BFillH_InterpolF4
 PROCConvertHSampleHalfWord yes
BFillH_InterpolF4
 PROCInterpol R9
 AND     R3,R3,R8
 ORR     R3,R3,R9,LSL #16
 PROCPrepBNext BFillH_InterpolF5
 PROCConvertHSampleHalfWord yes
BFillH_InterpolF5
 PROCInterpol R4
 PROCPrepBNext BFillH_InterpolF6
 PROCConvertHSampleHalfWord yes
BFillH_InterpolF6
 PROCInterpol R9
 AND     R4,R4,R8
 ORR     R4,R4,R9,LSL #16
 PROCPrepBNext BFillH_InterpolF7
 PROCConvertHSampleHalfWord yes
BFillH_InterpolF7
 PROCInterpol R14
 PROCPrepBNext BFillH_InterpolF8
 PROCConvertHSampleHalfWord yes
BFillH_InterpolF8
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 PROCPrepBNext BFillH_InterpolF9
 PROCConvertHSampleHalfWord yes
BFillH_InterpolF9
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFillH_InterpolF_End
 SUBS    R11,R11,#8
 BLT     BFillH_InterpolFF
 SUBS    R9,R5,#9
 BGT     BFillH_InterpolF1

BFillH_InterpolFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R0
 BEQ     BFill_StorePos
 ; process remaining samples

BFillH_Interpol1
 PROCInterpol R14
 PROCPrepareBNext BFillH_Interpol2,BFillH_Interpol1_Loop
BFillH_Interpol1_Sample
 PROCConvertHSampleHalfWord yes
BFillH_Interpol2
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFillH_Interpol_End,BFillH_Interpol2_Loop
BFillH_Interpol2_Sample
 PROCConvertHSampleHalfWord yes
BFillH_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillH_Interpol1
 MOV     R14,R0
 B       BFill_StorePos

BFillH_Interpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_Interpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
BFillH_Interpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_Interpol1_Sample

BFillH_Interpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_Interpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFillH_Interpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_Interpol2_Sample

 ;------------------------------------------------------------------------------
 ; LDRH 16 bit sample - Oversampled (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFillH_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #1
 _PUSH   "R2,R4"
 B       FFillH_OversampledF_End
 ; Fast mode, 8 samples in one go
FFillH_OversampledF1
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R2,R8,R9,ASR #1
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R2,R2,R9,LSL #16
 PROCPrepareNextOver x
FFillH_OversampledF3
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R3,R8,R9,ASR #1
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R3,R3,R9,LSL #16
 PROCPrepareNextOver x
FFillH_OversampledF5
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R4,R8,R9,ASR #1
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R4,R4,R9,LSL #16
 PROCPrepareNextOver x
FFillH_OversampledF7
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R14,R8,R9,ASR #1
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R14,R14,R9,LSL #16
 PROCPrepareNextOver x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
FFillH_OversampledF_End
 SUBS    R11,R11,#8
 BLT     FFillH_OversampledFF
 ADD     R9,R5,R7,LSR #(24-3)
 ADDS    R9,R9,#2
 BLT     FFillH_OversampledF1

FFillH_OversampledFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     FFill_StorePos
 ; process remaining samples

FFillH_Oversampled1
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver FFillH_Oversampled1_Loop
FFillH_Oversampled2
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R14,R8,R9,ASR #1
 PROCPrepareNextOver FFillH_Oversampled2_Loop
FFillH_Oversampled3
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver FFillH_Oversampled3_Loop
FFillH_Oversampled4
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextOver FFillH_Oversampled4_Loop
FFillH_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillH_Oversampled1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillH_Oversampled1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_Oversampled1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
FFillH_Oversampled1_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_Oversampled2

FFillH_Oversampled2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_Oversampled2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillH_Oversampled2_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_Oversampled3

FFillH_Oversampled3_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_Oversampled3_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillH_Oversampled3_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_Oversampled4

FFillH_Oversampled4_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillH_Oversampled4_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillH_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
FFillH_Oversampled4_Loop_Back
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillH_Oversampled_End

 ;--------------
 ; Backward Fill

BFillH_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #1
 SUB     R1,R1,R2,LSL #1
 SUB     R1,R1,#2
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 _PUSH   "R2,R4"
 B       BFillH_OversampledF_End
 ; Fast mode, 8 samples in one go
BFillH_OversampledF1
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R2,R8,R9,ASR #1
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R2,R2,R9,LSL #16
 PROCPrepareBNextOver x
BFillH_OversampledF3
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R3,R8,R9,ASR #1
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R3,R3,R9,LSL #16
 PROCPrepareBNextOver x
BFillH_OversampledF5
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R4,R8,R9,ASR #1
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R4,R4,R9,LSL #16
 PROCPrepareBNextOver x
BFillH_OversampledF7
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R14,R8,R9,ASR #1
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver x
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R14,R14,R9,LSL #16
 PROCPrepareBNextOver x
 ; Store value
 STMIA   R12!,{R2-R4,R14}
BFillH_OversampledF_End
 SUBS    R11,R11,#8
 BLT     BFillH_OversampledFF
 SUB     R9,R5,R7,LSR #(24-3)
 SUBS    R9,R9,#2
 BGT     BFillH_OversampledF1

BFillH_OversampledFF
 ; between [-1, -8]
 _PULL   "R2,R4"
 ADDS    R11,R11,#8
 MOVEQ   R14,R14,ASR #16
 BEQ     BFill_StorePos
 ; process remaining samples

BFillH_Oversampled1
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver BFillH_Oversampled1_Loop
BFillH_Oversampled2
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R14,R8,R9,ASR #1
 PROCPrepareBNextOver BFillH_Oversampled2_Loop
BFillH_Oversampled3
 MOV     R0,R5,LSL #1
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver BFillH_Oversampled3_Loop
BFillH_Oversampled4
 MOV     R0,R5,LSL #1
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextOver BFillH_Oversampled4_Loop
BFillH_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillH_Oversampled1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillH_Oversampled1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_Oversampled1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
BFillH_Oversampled1_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_Oversampled2

BFillH_Oversampled2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_Oversampled2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillH_Oversampled2_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_Oversampled3

BFillH_Oversampled3_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_Oversampled3_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillH_Oversampled3_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_Oversampled4

BFillH_Oversampled4_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillH_Oversampled4_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillH_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
BFillH_Oversampled4_Loop_Forward
 ADD     R1,R1,R2,LSL #1
 ADD     R1,R1,#2
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillH_Oversampled_End

 ;------------------------------------------------------------------------------
 ; LDRH 16 bit sample interlaced - NoInterpol (R7 < &1000000)
 ;------------------------------------------------------------------------------

 ;-------------
 ; Forward Fill

FFillHX_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #2
 MOV     R0,R5,LSL #2
 LDRH    R0,[R1,R0]
FFillHX_NoInterpol1
 AND     R14,R0,R8
 PROCPrepareNext FFillHX_NoInterpol2,FFillHX_NoInterpol1_Loop
FFillHX_NoInterpol1_Sample
 MOV     R0,R5,LSL #2
 LDRH    R0,[R1,R0]
FFillHX_NoInterpol2
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFillHX_NoInterpol_End,FFillHX_NoInterpol2_Loop
FFillHX_NoInterpol2_Sample
 MOV     R0,R5,LSL #2
 LDRH    R0,[R1,R0]
FFillHX_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillHX_NoInterpol1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillHX_NoInterpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_NoInterpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillHX_NoInterpol1_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_NoInterpol1_Sample

FFillHX_NoInterpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_NoInterpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFillHX_NoInterpol2_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_NoInterpol2_Sample

 ;--------------
 ; Backward Fill

BFillHX_NoInterpol _FNAME
 ADD     R1,R1,R3,LSL #2
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 MOV     R0,R5,LSL #2
 LDRH    R0,[R1,R0]
BFillHX_NoInterpol1
 AND     R14,R0,R8
 PROCPrepareBNext BFillHX_NoInterpol2,BFillHX_NoInterpol1_Loop
BFillHX_NoInterpol1_Sample
 MOV     R0,R5,LSL #2
 LDRH    R0,[R1,R0]
BFillHX_NoInterpol2
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFillHX_NoInterpol_End,BFillHX_NoInterpol2_Loop
BFillHX_NoInterpol2_Sample
 MOV     R0,R5,LSL #2
 LDRH    R0,[R1,R0]
BFillHX_NoInterpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillHX_NoInterpol1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillHX_NoInterpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_NoInterpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_NoInterpol1_Sample
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillHX_NoInterpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_NoInterpol1_Sample

BFillHX_NoInterpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_NoInterpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_NoInterpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFillHX_NoInterpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_NoInterpol2_Sample

 ;------------------------------------------------------------------------------
 ; 16 bit sample interlaced - Simple (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFillHX_Simple _FNAME
 ADD     R1,R1,R3,LSL #2
FFillHX_Simple1
 MOV     R0,R5,LSL #2
 LDRH    R14,[R1,R0]
 PROCPrepareNextSimple FFillHX_Simple1_Loop
FFillHX_Simple2
 MOV     R0,R5,LSL #2
 LDRH    R0,[R1,R0]
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextSimple FFillHX_Simple2_Loop
FFillHX_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillHX_Simple1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillHX_Simple1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_Simple1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_Simple2
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillHX_Simple1_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_Simple2

FFillHX_Simple2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_Simple2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
FFillHX_Simple2_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_Simple_End

 ;--------------
 ; Backward Fill

BFillHX_Simple _FNAME
 ADD     R1,R1,R3,LSL #2
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 ADD     R5,R5,R2
 ADD     R5,R5,#1
BFillHX_Simple1
 MOV     R0,R5,LSL #2
 LDRH    R14,[R1,R0]
 PROCPrepareBNextSimple BFillHX_Simple1_Loop
BFillHX_Simple2
 MOV     R0,R5,LSL #2
 LDRH    R0,[R1,R0]
 ORR     R14,R14,R0,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextSimple BFillHX_Simple2_Loop
BFillHX_Simple_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillHX_Simple1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillHX_Simple1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_Simple1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_Simple2
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillHX_Simple1_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_Simple2

BFillHX_Simple2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_Simple2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_Simple_End
 ; no loop? clear the rest
 B       Fill_Clear
BFillHX_Simple2_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_Simple_End

 ;------------------------------------------------------------------------------
 ; LDRH 16 bit sample interlaced - Interpol (R7 < &1000000)

 ;-------------
 ; Forward Fill

FFillHX_Interpol _FNAME
 ADD     R1,R1,R3,LSL #2
 PROCConvertHSample4HalfWord no
FFillHX_Interpol1
 PROCInterpol R14
 PROCPrepareNext FFillHX_Interpol2,FFillHX_Interpol1_Loop
FFillHX_Interpol1_Sample
 PROCConvertHSample4HalfWord yes
FFillHX_Interpol2
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNext FFillHX_Interpol_End,FFillHX_Interpol2_Loop
FFillHX_Interpol2_Sample
 PROCConvertHSample4HalfWord yes
FFillHX_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillHX_Interpol1
 MOV     R14,R0
 B       FFill_StorePos

FFillHX_Interpol1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_Interpol1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
FFillHX_Interpol1_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_Interpol1_Sample

FFillHX_Interpol2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_Interpol2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
FFillHX_Interpol2_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_Interpol2_Sample

 ;--------------
 ; Backward Fill

BFillHX_Interpol _FNAME
 ADD     R1,R1,R3,LSL #2
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 PROCConvertHSample4HalfWord no
BFillHX_Interpol1
 PROCInterpol R14
 PROCPrepareBNext BFillHX_Interpol2,BFillHX_Interpol1_Loop
BFillHX_Interpol1_Sample
 PROCConvertHSample4HalfWord yes
BFillHX_Interpol2
 PROCInterpol R9
 AND     R14,R14,R8
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNext BFillHX_Interpol_End,BFillHX_Interpol2_Loop
BFillHX_Interpol2_Sample
 PROCConvertHSample4HalfWord yes
BFillHX_Interpol_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillHX_Interpol1
 MOV     R14,R0
 B       BFill_StorePos

BFillHX_Interpol1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_Interpol1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_Interpol1_Sample
 ; no loop? store last value and clear the rest
 AND     R14,R14,R8
 STR     R14,[R12],#4
 B       Fill_Clear
BFillHX_Interpol1_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_Interpol1_Sample

BFillHX_Interpol2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_Interpol2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_Interpol2_Sample
 ; no loop? clear the rest
 B       Fill_Clear
BFillHX_Interpol2_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_Interpol2_Sample

 ;------------------------------------------------------------------------------
 ; LDRH 16 bit sample interlaced - Oversampled (R7 >= &1000000)

 ;-------------
 ; Forward Fill

FFillHX_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #2
FFillHX_Oversampled1
 MOV     R0,R5,LSL #2
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver FFillHX_Oversampled1_Loop
FFillHX_Oversampled2
 MOV     R0,R5,LSL #2
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R14,R8,R9,ASR #1
 PROCPrepareNextOver FFillHX_Oversampled2_Loop
FFillHX_Oversampled3
 MOV     R0,R5,LSL #2
 LDRSH   R9,[R1,R0]
 PROCPrepareNextOver FFillHX_Oversampled3_Loop
FFillHX_Oversampled4
 MOV     R0,R5,LSL #2
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareNextOver FFillHX_Oversampled4_Loop
FFillHX_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     FFillHX_Oversampled1
 MOV     R14,R14,ASR #16
 B       FFill_StorePos

FFillHX_Oversampled1_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_Oversampled1_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
FFillHX_Oversampled1_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_Oversampled2

FFillHX_Oversampled2_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_Oversampled2_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillHX_Oversampled2_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_Oversampled3

FFillHX_Oversampled3_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_Oversampled3_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
FFillHX_Oversampled3_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_Oversampled4

FFillHX_Oversampled4_Loop
 TST     R4,#stream_flag_backward
 BNE     FFillHX_Oversampled4_Loop_Back
 SUBS    R5,R5,R2 ; move to start of sample
 BLT     FFillHX_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
FFillHX_Oversampled4_Loop_Back
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 SUB     R5,R2,R5 ; reverse R5 and add R2
 B       BFillHX_Oversampled_End

 ;--------------
 ; Backward Fill

BFillHX_Oversampled _FNAME
 ADD     R1,R1,R3,LSL #2
 SUB     R1,R1,R2,LSL #2
 SUB     R1,R1,#4
 ADD     R5,R5,R2
 ADD     R5,R5,#1
BFillHX_Oversampled1
 MOV     R0,R5,LSL #2
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver BFillHX_Oversampled1_Loop
BFillHX_Oversampled2
 MOV     R0,R5,LSL #2
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R14,R8,R9,ASR #1
 PROCPrepareBNextOver BFillHX_Oversampled2_Loop
BFillHX_Oversampled3
 MOV     R0,R5,LSL #2
 LDRSH   R9,[R1,R0]
 PROCPrepareBNextOver BFillHX_Oversampled3_Loop
BFillHX_Oversampled4
 MOV     R0,R5,LSL #2
 LDRSH   R0,[R1,R0]
 ADD     R9,R0,R9
 AND     R9,R8,R9,ASR #1
 ORR     R14,R14,R9,LSL #16
 ; Store value
 STR     R14,[R12],#4
 PROCPrepareBNextOver BFillHX_Oversampled4_Loop
BFillHX_Oversampled_End
 ; Loop on row
 SUBS    R11,R11,#2
 BGT     BFillHX_Oversampled1
 MOV     R14,R14,ASR #16
 B       BFill_StorePos

BFillHX_Oversampled1_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_Oversampled1_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_Oversampled2
 ; no loop? store last value and clear the rest
 MOV     R14,#0
 STR     R14,[R12],#4
 B       Fill_Clear
BFillHX_Oversampled1_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_Oversampled2

BFillHX_Oversampled2_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_Oversampled2_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_Oversampled3
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillHX_Oversampled2_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_Oversampled3

BFillHX_Oversampled3_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_Oversampled3_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_Oversampled4
 ; no loop? store last value and clear the rest
 STR     R14,[R12],#4
 B       Fill_Clear
BFillHX_Oversampled3_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_Oversampled4

BFillHX_Oversampled4_Loop
 TST     R4,#stream_flag_forward
 BNE     BFillHX_Oversampled4_Loop_Forward
 ADDS    R5,R5,R2 ; move to end of sample
 BGT     BFillHX_Oversampled_End
 ; no loop? clear the rest
 B       Fill_Clear
BFillHX_Oversampled4_Loop_Forward
 ADD     R1,R1,R2,LSL #2
 ADD     R1,R1,#4
 RSB     R5,R5,#0
 SUB     R5,R5,R2
 B       FFillHX_Oversampled_End

 ;------------------------------------------------------------------------------

FFill_StorePos
 _PULL   "R0,R3"
 STR     R14,[R0,#stream_last_smp_value]
 LDRB    R1,[R0,#stream_flags]
 BIC     R1,R1,#stream_flag_isbackward
 STRB    R1,[R0,#stream_flags]
 ; Store value
 ADD     R5,R5,R3
 CMP     R5,R3
 MOVGE   R5,#-&1
 STR     R5,[R0,#stream_pos]
 STR     R6,[R0,#stream_fpos]
 _ENDPROC

BFill_StorePos
 _PULL   "R0,R3"
 STR     R14,[R0,#stream_last_smp_value]
 LDRB    R1,[R0,#stream_flags]
 ORR     R1,R1,#stream_flag_isbackward
 STRB    R1,[R0,#stream_flags]
 ; Store value
 SUB     R5,R5,R2
 SUB     R5,R5,#1
 ADDS    R5,R5,R3
 MOVLT   R5,#-&1
 STR     R5,[R0,#stream_pos]
 STR     R6,[R0,#stream_fpos]
 _ENDPROC

Fill_Clear
 _PULL   "R0,R3"

 MOV     R14,#0
Fill_Clear_Loop
 SUBS    R11,R11,#2
 STRGT   R14,[R12],#4
 BGT     Fill_Clear_Loop

 STR     R14,[R0,#stream_last_smp_value]
 ; Store position
 MOV     R5,#-1
 STR     R5,[R0,#stream_pos]
 _ENDPROC

;-------------------------------------------------------------------------------
; Seq_SkipProcessStream
; In  - R0 stream ptr
;       R1 time step in 2^40/FMix
;       R2 nr of samples
;
; Out -
;-------------------------------------------------------------------------------
 ALIGN
Seq_SkipProcessStream _FNAME
 _DEFPROC "R1-R6"

 ; convert time into sample nr of values and fraction(?)
 LDR     R3,[R0,#stream_frequency]
 _FNMul16 R1,R3,R4,R5,R6 ; R6 = 2^24*Fsample/FMix
 MOV     R3,R6,LSR #16
 MUL     R3,R2,R3 ; High 2^8
 MOV     R4,R6,LSL #16
 MOV     R4,R4,LSR #16
 MUL     R4,R2,R4 ; Low  2^24
 MOV     R5,R4,LSL #8
 MOV     R6,R3,LSL #24
 ADDS    R5,R5,R6 ; Low  2^32
 MOV     R1,R4,LSR #24
 ADC     R1,R1,R3,LSR #8 ; High 2^0
 LDR     R6,[R0,#stream_fpos]
 ADDS    R6,R6,R5
 ADC     R1,R1,#0
 STR     R6,[R0,#stream_fpos]

 LDR     R5,[R0,#stream_pos]
 LDR     R2,[R0,#stream_smp_lstart]
 LDR     R3,[R0,#stream_smp_lend]
 LDRB    R4,[R0,#stream_flags]
 SUB     R2,R3,R2 ; R2 = loop size
 SUB     R5,R5,R3
 TST     R4,#stream_flag_isbackward
 BNE     Seq_BSkipProcessStream

Seq_FSkipProcessStream
 ; R5 = pos relative to loop end
 ADDS    R5,R5,R1
 BLT     Seq_FSkipProcessStream_Store
 ; No loop?
 CMP     R2,#0
 BEQ     Seq_SkipProcessStream_Clear
Seq_FSkipProcessStream_Loop
 ; Ping-pong?
 TST     R4,#stream_flag_backward
 RSBNE   R5,R5,#0
; ADDNE   R5,R5,R2 ; done in SkipLoop
 BNE     Seq_BSkipProcessStream_Loop_SkipLoop
 ; No
Seq_FSkipProcessStream_Loop_SkipLoop
 SUBS    R5,R5,R2
 BLT     Seq_FSkipProcessStream_Store
 B       Seq_FSkipProcessStream_Loop

Seq_BSkipProcessStream
 ; R5 = pos relative to loop start - 1
 ADD     R5,R5,R2
 ADD     R5,R5,#1
 SUBS    R5,R5,R1
 BGT     Seq_BSkipProcessStream_Store
 ; No loop?
 CMP     R2,#0
 BEQ     Seq_SkipProcessStream_Clear
Seq_BSkipProcessStream_Loop
 ; Ping-pong?
 TST     R4,#stream_flag_forward
 RSBNE   R5,R5,#0
; SUBNE   R5,R5,R2 ; done in SkipLoop
 BNE     Seq_FSkipProcessStream_Loop_SkipLoop
 ; No
Seq_BSkipProcessStream_Loop_SkipLoop
 ADDS    R5,R5,R2
 BGT     Seq_BSkipProcessStream_Store
 B       Seq_BSkipProcessStream_Loop

Seq_FSkipProcessStream_Store
 LDRB    R1,[R0,#stream_flags]
 BIC     R1,R1,#stream_flag_isbackward
 STRB    R1,[R0,#stream_flags]
 ; Store position translated back
 ADD     R5,R5,R3 ; rel. to loop end -> rel. to 0
 CMP     R5,R3    ; after loop? stop note
 MOVGE   R5,#-&1
 STR     R5,[R0,#stream_pos]
 MOV     R5,#0
 STR     R5,[R0,#stream_last_smp_value]
 _ENDPROC

Seq_BSkipProcessStream_Store
 LDRB    R1,[R0,#stream_flags]
 ORR     R1,R1,#stream_flag_isbackward
 STRB    R1,[R0,#stream_flags]
 ; Store position translated back
 SUB     R5,R5,R2 ; rel. to loop start -1 -> rel. to loop end
 SUB     R5,R5,#1
 ADDS    R5,R5,R3 ; rel. to loop end -> rel. to 0
 MOVLT   R5,#-&1
 STR     R5,[R0,#stream_pos]
 MOV     R5,#0
 STR     R5,[R0,#stream_last_smp_value]
 _ENDPROC

Seq_SkipProcessStream_Clear
 MOV     R5,#-1
 STR     R5,[R0,#stream_pos]
 MOV     R5,#0
 STR     R5,[R0,#stream_last_smp_value]
 _ENDPROC

;------------------------
Seq_GetLogTable _FNAME
 ADR     R0,Const_LogTable
 MOV     PC,R14

;---------------------------------------------------------
; signed 32 bit Linear to 8-bit log conversion table:
;  sign and 12 significant bits, which means &2000 bytes
;---------------------------------------------------------
Const_LogTable
 DCB     &00,&02,&04,&06,&08,&0A,&0C,&0E,&10,&12,&14,&16,&18,&1A,&1C,&1E
 DCB     &20,&22,&22,&24,&24,&26,&26,&28,&28,&2A,&2A,&2C,&2C,&2E,&2E,&30
 DCB     &30,&32,&32,&34,&34,&36,&36,&38,&38,&3A,&3A,&3C,&3C,&3E,&3E,&40
 DCB     &40,&42,&42,&42,&42,&44,&44,&44,&44,&46,&46,&46,&46,&48,&48,&48
 DCB     &48,&4A,&4A,&4A,&4A,&4C,&4C,&4C,&4C,&4E,&4E,&4E,&4E,&50,&50,&50
 DCB     &50,&52,&52,&52,&52,&54,&54,&54,&54,&56,&56,&56,&56,&58,&58,&58
 DCB     &58,&5A,&5A,&5A,&5A,&5C,&5C,&5C,&5C,&5E,&5E,&5E,&5E,&60,&60,&60
 DCB     &60,&62,&62,&62,&62,&62,&62,&62,&62,&64,&64,&64,&64,&64,&64,&64
 DCB     &64,&66,&66,&66,&66,&66,&66,&66,&66,&68,&68,&68,&68,&68,&68,&68
 DCB     &68,&6A,&6A,&6A,&6A,&6A,&6A,&6A,&6A,&6C,&6C,&6C,&6C,&6C,&6C,&6C
 DCB     &6C,&6E,&6E,&6E,&6E,&6E,&6E,&6E,&6E,&70,&70,&70,&70,&70,&70,&70
 DCB     &70,&72,&72,&72,&72,&72,&72,&72,&72,&74,&74,&74,&74,&74,&74,&74
 DCB     &74,&76,&76,&76,&76,&76,&76,&76,&76,&78,&78,&78,&78,&78,&78,&78
 DCB     &78,&7A,&7A,&7A,&7A,&7A,&7A,&7A,&7A,&7C,&7C,&7C,&7C,&7C,&7C,&7C
 DCB     &7C,&7E,&7E,&7E,&7E,&7E,&7E,&7E,&7E,&80,&80,&80,&80,&80,&80,&80
 DCB     &80,&82,&82,&82,&82,&82,&82,&82,&82,&82,&82,&82,&82,&82,&82,&82
 DCB     &82,&84,&84,&84,&84,&84,&84,&84,&84,&84,&84,&84,&84,&84,&84,&84
 DCB     &84,&86,&86,&86,&86,&86,&86,&86,&86,&86,&86,&86,&86,&86,&86,&86
 DCB     &86,&88,&88,&88,&88,&88,&88,&88,&88,&88,&88,&88,&88,&88,&88,&88
 DCB     &88,&8A,&8A,&8A,&8A,&8A,&8A,&8A,&8A,&8A,&8A,&8A,&8A,&8A,&8A,&8A
 DCB     &8A,&8C,&8C,&8C,&8C,&8C,&8C,&8C,&8C,&8C,&8C,&8C,&8C,&8C,&8C,&8C
 DCB     &8C,&8E,&8E,&8E,&8E,&8E,&8E,&8E,&8E,&8E,&8E,&8E,&8E,&8E,&8E,&8E
 DCB     &8E,&90,&90,&90,&90,&90,&90,&90,&90,&90,&90,&90,&90,&90,&90,&90
 DCB     &90,&92,&92,&92,&92,&92,&92,&92,&92,&92,&92,&92,&92,&92,&92,&92
 DCB     &92,&94,&94,&94,&94,&94,&94,&94,&94,&94,&94,&94,&94,&94,&94,&94
 DCB     &94,&96,&96,&96,&96,&96,&96,&96,&96,&96,&96,&96,&96,&96,&96,&96
 DCB     &96,&98,&98,&98,&98,&98,&98,&98,&98,&98,&98,&98,&98,&98,&98,&98
 DCB     &98,&9A,&9A,&9A,&9A,&9A,&9A,&9A,&9A,&9A,&9A,&9A,&9A,&9A,&9A,&9A
 DCB     &9A,&9C,&9C,&9C,&9C,&9C,&9C,&9C,&9C,&9C,&9C,&9C,&9C,&9C,&9C,&9C
 DCB     &9C,&9E,&9E,&9E,&9E,&9E,&9E,&9E,&9E,&9E,&9E,&9E,&9E,&9E,&9E,&9E
 DCB     &9E,&A0,&A0,&A0,&A0,&A0,&A0,&A0,&A0,&A0,&A0,&A0,&A0,&A0,&A0,&A0
 DCB     &A0,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2
 DCB     &A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2,&A2
 DCB     &A2,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4
 DCB     &A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4,&A4
 DCB     &A4,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6
 DCB     &A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6,&A6
 DCB     &A6,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8
 DCB     &A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8,&A8
 DCB     &A8,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA
 DCB     &AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA
 DCB     &AA,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC
 DCB     &AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC,&AC
 DCB     &AC,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE
 DCB     &AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE,&AE
 DCB     &AE,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0
 DCB     &B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0,&B0
 DCB     &B0,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2
 DCB     &B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2,&B2
 DCB     &B2,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4
 DCB     &B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4,&B4
 DCB     &B4,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6
 DCB     &B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6,&B6
 DCB     &B6,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8
 DCB     &B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8,&B8
 DCB     &B8,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA
 DCB     &BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA,&BA
 DCB     &BA,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC
 DCB     &BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC,&BC
 DCB     &BC,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE
 DCB     &BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE,&BE
 DCB     &BE,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0
 DCB     &C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0,&C0
 DCB     &C0,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2
 DCB     &C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2
 DCB     &C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2
 DCB     &C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2,&C2
 DCB     &C2,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4
 DCB     &C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4
 DCB     &C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4
 DCB     &C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4,&C4
 DCB     &C4,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6
 DCB     &C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6
 DCB     &C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6
 DCB     &C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6,&C6
 DCB     &C6,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8
 DCB     &C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8
 DCB     &C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8
 DCB     &C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8,&C8
 DCB     &C8,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA
 DCB     &CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA
 DCB     &CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA
 DCB     &CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA,&CA
 DCB     &CA,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC
 DCB     &CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC
 DCB     &CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC
 DCB     &CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC,&CC
 DCB     &CC,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE
 DCB     &CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE
 DCB     &CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE
 DCB     &CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE,&CE
 DCB     &CE,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0
 DCB     &D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0
 DCB     &D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0
 DCB     &D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0,&D0
 DCB     &D0,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2
 DCB     &D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2
 DCB     &D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2
 DCB     &D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2,&D2
 DCB     &D2,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4
 DCB     &D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4
 DCB     &D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4
 DCB     &D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4,&D4
 DCB     &D4,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6
 DCB     &D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6
 DCB     &D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6
 DCB     &D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6,&D6
 DCB     &D6,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8
 DCB     &D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8
 DCB     &D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8
 DCB     &D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8,&D8
 DCB     &D8,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA
 DCB     &DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA
 DCB     &DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA
 DCB     &DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA,&DA
 DCB     &DA,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC
 DCB     &DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC
 DCB     &DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC
 DCB     &DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC,&DC
 DCB     &DC,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE
 DCB     &DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE
 DCB     &DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE
 DCB     &DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE,&DE
 DCB     &DE,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0
 DCB     &E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0
 DCB     &E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0
 DCB     &E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0,&E0
 DCB     &E0,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2
 DCB     &E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2
 DCB     &E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2
 DCB     &E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2
 DCB     &E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2
 DCB     &E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2
 DCB     &E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2
 DCB     &E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2,&E2
 DCB     &E2,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4
 DCB     &E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4
 DCB     &E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4
 DCB     &E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4
 DCB     &E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4
 DCB     &E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4
 DCB     &E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4
 DCB     &E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4,&E4
 DCB     &E4,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6
 DCB     &E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6
 DCB     &E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6
 DCB     &E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6
 DCB     &E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6
 DCB     &E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6
 DCB     &E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6
 DCB     &E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6,&E6
 DCB     &E6,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8
 DCB     &E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8
 DCB     &E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8
 DCB     &E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8
 DCB     &E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8
 DCB     &E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8
 DCB     &E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8
 DCB     &E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8,&E8
 DCB     &E8,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA
 DCB     &EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA
 DCB     &EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA
 DCB     &EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA
 DCB     &EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA
 DCB     &EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA
 DCB     &EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA
 DCB     &EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA,&EA
 DCB     &EA,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC
 DCB     &EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC
 DCB     &EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC
 DCB     &EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC
 DCB     &EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC
 DCB     &EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC
 DCB     &EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC
 DCB     &EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC,&EC
 DCB     &EC,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE
 DCB     &EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE
 DCB     &EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE
 DCB     &EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE
 DCB     &EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE
 DCB     &EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE
 DCB     &EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE
 DCB     &EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE,&EE
 DCB     &EE,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0
 DCB     &F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0
 DCB     &F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0
 DCB     &F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0
 DCB     &F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0
 DCB     &F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0
 DCB     &F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0
 DCB     &F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0,&F0
 DCB     &F0,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2
 DCB     &F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2
 DCB     &F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2
 DCB     &F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2
 DCB     &F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2
 DCB     &F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2
 DCB     &F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2
 DCB     &F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2,&F2
 DCB     &F2,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4
 DCB     &F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4
 DCB     &F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4
 DCB     &F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4
 DCB     &F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4
 DCB     &F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4
 DCB     &F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4
 DCB     &F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4,&F4
 DCB     &F4,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6
 DCB     &F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6
 DCB     &F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6
 DCB     &F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6
 DCB     &F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6
 DCB     &F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6
 DCB     &F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6
 DCB     &F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6,&F6
 DCB     &F6,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8
 DCB     &F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8
 DCB     &F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8
 DCB     &F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8
 DCB     &F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8
 DCB     &F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8
 DCB     &F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8
 DCB     &F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8,&F8
 DCB     &F8,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA
 DCB     &FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA
 DCB     &FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA
 DCB     &FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA
 DCB     &FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA
 DCB     &FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA
 DCB     &FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA
 DCB     &FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA,&FA
 DCB     &FA,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC
 DCB     &FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC
 DCB     &FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC
 DCB     &FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC
 DCB     &FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC
 DCB     &FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC
 DCB     &FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC
 DCB     &FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC,&FC
 DCB     &FC,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE,&FE
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF
 DCB     &FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD
 DCB     &FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD
 DCB     &FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD
 DCB     &FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD
 DCB     &FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD
 DCB     &FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD
 DCB     &FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD
 DCB     &FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD,&FD
 DCB     &FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB
 DCB     &FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB
 DCB     &FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB
 DCB     &FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB
 DCB     &FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB
 DCB     &FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB
 DCB     &FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB
 DCB     &FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB,&FB
 DCB     &F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9
 DCB     &F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9
 DCB     &F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9
 DCB     &F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9
 DCB     &F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9
 DCB     &F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9
 DCB     &F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9
 DCB     &F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9,&F9
 DCB     &F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7
 DCB     &F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7
 DCB     &F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7
 DCB     &F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7
 DCB     &F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7
 DCB     &F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7
 DCB     &F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7
 DCB     &F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7,&F7
 DCB     &F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5
 DCB     &F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5
 DCB     &F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5
 DCB     &F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5
 DCB     &F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5
 DCB     &F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5
 DCB     &F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5
 DCB     &F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5,&F5
 DCB     &F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3
 DCB     &F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3
 DCB     &F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3
 DCB     &F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3
 DCB     &F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3
 DCB     &F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3
 DCB     &F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3
 DCB     &F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3,&F3
 DCB     &F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1
 DCB     &F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1
 DCB     &F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1
 DCB     &F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1
 DCB     &F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1
 DCB     &F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1
 DCB     &F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1
 DCB     &F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1,&F1
 DCB     &EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF
 DCB     &EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF
 DCB     &EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF
 DCB     &EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF
 DCB     &EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF
 DCB     &EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF
 DCB     &EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF
 DCB     &EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF,&EF
 DCB     &ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED
 DCB     &ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED
 DCB     &ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED
 DCB     &ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED
 DCB     &ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED
 DCB     &ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED
 DCB     &ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED
 DCB     &ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED,&ED
 DCB     &EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB
 DCB     &EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB
 DCB     &EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB
 DCB     &EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB
 DCB     &EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB
 DCB     &EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB
 DCB     &EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB
 DCB     &EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB,&EB
 DCB     &E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9
 DCB     &E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9
 DCB     &E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9
 DCB     &E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9
 DCB     &E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9
 DCB     &E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9
 DCB     &E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9
 DCB     &E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9,&E9
 DCB     &E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7
 DCB     &E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7
 DCB     &E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7
 DCB     &E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7
 DCB     &E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7
 DCB     &E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7
 DCB     &E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7
 DCB     &E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7,&E7
 DCB     &E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5
 DCB     &E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5
 DCB     &E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5
 DCB     &E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5
 DCB     &E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5
 DCB     &E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5
 DCB     &E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5
 DCB     &E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5,&E5
 DCB     &E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3
 DCB     &E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3
 DCB     &E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3
 DCB     &E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3
 DCB     &E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3
 DCB     &E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3
 DCB     &E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3
 DCB     &E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3,&E3
 DCB     &E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1
 DCB     &E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1
 DCB     &E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1
 DCB     &E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1,&E1
 DCB     &DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF
 DCB     &DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF
 DCB     &DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF
 DCB     &DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF,&DF
 DCB     &DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD
 DCB     &DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD
 DCB     &DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD
 DCB     &DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD,&DD
 DCB     &DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB
 DCB     &DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB
 DCB     &DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB
 DCB     &DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB,&DB
 DCB     &D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9
 DCB     &D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9
 DCB     &D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9
 DCB     &D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9,&D9
 DCB     &D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7
 DCB     &D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7
 DCB     &D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7
 DCB     &D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7,&D7
 DCB     &D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5
 DCB     &D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5
 DCB     &D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5
 DCB     &D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5,&D5
 DCB     &D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3
 DCB     &D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3
 DCB     &D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3
 DCB     &D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3,&D3
 DCB     &D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1
 DCB     &D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1
 DCB     &D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1
 DCB     &D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1,&D1
 DCB     &CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF
 DCB     &CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF
 DCB     &CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF
 DCB     &CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF,&CF
 DCB     &CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD
 DCB     &CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD
 DCB     &CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD
 DCB     &CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD,&CD
 DCB     &CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB
 DCB     &CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB
 DCB     &CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB
 DCB     &CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB,&CB
 DCB     &C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9
 DCB     &C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9
 DCB     &C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9
 DCB     &C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9,&C9
 DCB     &C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7
 DCB     &C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7
 DCB     &C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7
 DCB     &C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7,&C7
 DCB     &C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5
 DCB     &C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5
 DCB     &C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5
 DCB     &C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5,&C5
 DCB     &C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3
 DCB     &C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3
 DCB     &C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3
 DCB     &C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3,&C3
 DCB     &C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1
 DCB     &C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1,&C1
 DCB     &BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF
 DCB     &BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF,&BF
 DCB     &BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD
 DCB     &BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD,&BD
 DCB     &BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB
 DCB     &BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB,&BB
 DCB     &B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9
 DCB     &B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9,&B9
 DCB     &B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7
 DCB     &B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7,&B7
 DCB     &B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5
 DCB     &B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5,&B5
 DCB     &B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3
 DCB     &B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3,&B3
 DCB     &B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1
 DCB     &B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1,&B1
 DCB     &AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF
 DCB     &AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF,&AF
 DCB     &AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD
 DCB     &AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD,&AD
 DCB     &AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB
 DCB     &AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB,&AB
 DCB     &A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9
 DCB     &A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9,&A9
 DCB     &A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7
 DCB     &A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7,&A7
 DCB     &A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5
 DCB     &A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5,&A5
 DCB     &A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3
 DCB     &A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3,&A3
 DCB     &A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1,&A1
 DCB     &9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F,&9F
 DCB     &9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D,&9D
 DCB     &9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B,&9B
 DCB     &99,&99,&99,&99,&99,&99,&99,&99,&99,&99,&99,&99,&99,&99,&99,&99
 DCB     &97,&97,&97,&97,&97,&97,&97,&97,&97,&97,&97,&97,&97,&97,&97,&97
 DCB     &95,&95,&95,&95,&95,&95,&95,&95,&95,&95,&95,&95,&95,&95,&95,&95
 DCB     &93,&93,&93,&93,&93,&93,&93,&93,&93,&93,&93,&93,&93,&93,&93,&93
 DCB     &91,&91,&91,&91,&91,&91,&91,&91,&91,&91,&91,&91,&91,&91,&91,&91
 DCB     &8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F,&8F
 DCB     &8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D,&8D
 DCB     &8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B,&8B
 DCB     &89,&89,&89,&89,&89,&89,&89,&89,&89,&89,&89,&89,&89,&89,&89,&89
 DCB     &87,&87,&87,&87,&87,&87,&87,&87,&87,&87,&87,&87,&87,&87,&87,&87
 DCB     &85,&85,&85,&85,&85,&85,&85,&85,&85,&85,&85,&85,&85,&85,&85,&85
 DCB     &83,&83,&83,&83,&83,&83,&83,&83,&83,&83,&83,&83,&83,&83,&83,&83
 DCB     &81,&81,&81,&81,&81,&81,&81,&81,&7F,&7F,&7F,&7F,&7F,&7F,&7F,&7F
 DCB     &7D,&7D,&7D,&7D,&7D,&7D,&7D,&7D,&7B,&7B,&7B,&7B,&7B,&7B,&7B,&7B
 DCB     &79,&79,&79,&79,&79,&79,&79,&79,&77,&77,&77,&77,&77,&77,&77,&77
 DCB     &75,&75,&75,&75,&75,&75,&75,&75,&73,&73,&73,&73,&73,&73,&73,&73
 DCB     &71,&71,&71,&71,&71,&71,&71,&71,&6F,&6F,&6F,&6F,&6F,&6F,&6F,&6F
 DCB     &6D,&6D,&6D,&6D,&6D,&6D,&6D,&6D,&6B,&6B,&6B,&6B,&6B,&6B,&6B,&6B
 DCB     &69,&69,&69,&69,&69,&69,&69,&69,&67,&67,&67,&67,&67,&67,&67,&67
 DCB     &65,&65,&65,&65,&65,&65,&65,&65,&63,&63,&63,&63,&63,&63,&63,&63
 DCB     &61,&61,&61,&61,&5F,&5F,&5F,&5F,&5D,&5D,&5D,&5D,&5B,&5B,&5B,&5B
 DCB     &59,&59,&59,&59,&57,&57,&57,&57,&55,&55,&55,&55,&53,&53,&53,&53
 DCB     &51,&51,&51,&51,&4F,&4F,&4F,&4F,&4D,&4D,&4D,&4D,&4B,&4B,&4B,&4B
 DCB     &49,&49,&49,&49,&47,&47,&47,&47,&45,&45,&45,&45,&43,&43,&43,&43
 DCB     &41,&41,&3F,&3F,&3D,&3D,&3B,&3B,&39,&39,&37,&37,&35,&35,&33,&33
 DCB     &31,&31,&2F,&2F,&2D,&2D,&2B,&2B,&29,&29,&27,&27,&25,&25,&23,&23
 DCB     &21,&1F,&1D,&1B,&19,&17,&15,&13,&11,&0F,&0D,&0B,&09,&07,&05,&03

 END
