chrisly42
9c48c11cd1
- Bugfix: WaitForFrame was completely broken. Now also caters for race-condition that would have waited one extra frame. - Bugfix: InitPart would overwrite innocent memory (reported by Gigabates and Losso) - Bugfix: Palette LERP had wrong bias. - Removed extra paths in include statement, use default include paths instead - Added Raspberry Casket no-jitter background calc mode (FW_MUSIC_PLAYER_CHOICE = 6) - Updated Raspberry Casket to V2.0 presto branch (WIP) - Removed fw_FrameCounterLong, use fw_FrameCounter-2 for debug purposes - Support for blue noise palette LERPing (like in Is Real). Provide your own blue noise table (4 KB), stuff it into fw_BlueNoiseTablePtr, set FW_PALETTE_LERP_SUPPORT to 2 - Music tick routine is now replaceable during runtime (fw_MusicTickRoutine) - Support for softints and audio interrupts - LMB exit can also be disabled dynamically when using FW_LMB_EXIT_SUPPORT = 2 and fw_DisableLMBExit != 0 - Added LSP Micro support and LSP Nano (custom format that uses note pitches instead of periods) - Minor other things
1295 lines
33 KiB
NASM
1295 lines
33 KiB
NASM
|
|
CLIPTO8BIT MACRO
|
|
cmp.w #-$80,\1
|
|
bge.s .nominclip\@
|
|
moveq.l #-$80,\1
|
|
.nominclip\@
|
|
cmp.w #$7f,\1
|
|
ble.s .nomaxclip\@
|
|
moveq.l #$7f,\1
|
|
.nomaxclip\@
|
|
ENDM
|
|
|
|
CLIPORTRUNC8BIT MACRO
|
|
beq.s .unboosted\@
|
|
asr.l #6,\1
|
|
cmp.w #-$80,\1
|
|
bge.s .nominclip\@
|
|
moveq.l #-$80,\1
|
|
.nominclip\@
|
|
cmp.w #$7f,\1
|
|
ble.s .nomaxclip\@
|
|
moveq.l #$7f,\1
|
|
bra.s .nomaxclip\@
|
|
.unboosted\@
|
|
asr.l #8,\1
|
|
.nomaxclip\@
|
|
ENDM
|
|
|
|
CLIPTO8BITAFTERADD MACRO
|
|
bvc.s .noclip\@
|
|
spl \1
|
|
eor.b #$7f,\1
|
|
.noclip\@
|
|
ENDM
|
|
|
|
; ----------------------------------------
|
|
; proposed register assignment:
|
|
; a1 = Wave table order
|
|
; a4 = MyPlayer
|
|
; a6 = MySong / waveinfo
|
|
pre_WaveGen:
|
|
; ----------------------------------------
|
|
|
|
lea .pre_log12_table(pc),a0 ; 128, 121, 114, 107, 102, 96, 90, 85, 80, 76, 72, 67
|
|
lea pv_osc_buffers+owb_sqr_waves(a4),a3
|
|
moveq.l #NOTES_IN_OCTAVE-1,d7
|
|
.noteloop
|
|
swap d7
|
|
moveq.l #0,d6
|
|
move.w d6,d7 ; tabpos
|
|
move.b (a0)+,d6 ; period
|
|
|
|
move.l #$ff00,d5
|
|
divu d6,d5 ; frac increment
|
|
|
|
move.w d6,d4
|
|
lsr.w #1,d4 ; half-period
|
|
move.w d4,d3
|
|
lsr.w #1,d3 ; quarter-period
|
|
|
|
moveq.l #0,d0 ; acc
|
|
lea (a3,d6.w),a2
|
|
lea owb_tri_waves-owb_sqr_waves(a2),a2
|
|
suba.w d3,a2
|
|
.notewaveloop
|
|
move.w d0,d2
|
|
lsr.w #8,d2
|
|
|
|
moveq.l #$7f,d1
|
|
sub.b d2,d1
|
|
move.b d1,owb_saw_waves-owb_sqr_waves(a3,d7.w)
|
|
|
|
add.b d2,d2
|
|
cmp.w d7,d3 ; tabpos == negquarter
|
|
bne.s .nowrapback
|
|
suba.w d6,a2 ; go back to start of period
|
|
.nowrapback
|
|
cmp.w d0,d7
|
|
ble.s .otherhalf
|
|
moveq.l #$7f,d1
|
|
sub.b d2,d1
|
|
move.b d1,(a2)+
|
|
bra.s .clip80
|
|
|
|
.otherhalf
|
|
add.b #$80,d2
|
|
move.b d2,(a2)+
|
|
moveq.l #$7f,d2
|
|
cmp.w d7,d4
|
|
bne.s .noclip80
|
|
.clip80 moveq.l #-$80,d2
|
|
.noclip80
|
|
move.b d2,owb_sqr_waves-owb_sqr_waves(a3,d7.w)
|
|
|
|
add.w d5,d0 ; increment acc by frac
|
|
addq.w #1,d7 ; increment pos
|
|
|
|
cmp.w d7,d6
|
|
bne.s .notewaveloop
|
|
|
|
swap d7
|
|
lea owb_SIZEOF(a3),a3
|
|
dbra d7,.noteloop
|
|
|
|
; ----------------------------------------
|
|
; proposed register assignment:
|
|
; a0 = sample output
|
|
; a1 = scratch
|
|
; a3 = waveinfo
|
|
; a4 = MyPlayer
|
|
; a6 = MySong / waveinfo
|
|
.wavegenloop
|
|
;movea.l pv_my_song(a4),a6
|
|
moveq.l #0,d1
|
|
move.b (a1)+,d1 ; apply wave order redirection
|
|
move.l a1,-(sp) ; what used to be sv_wavegen_order_table
|
|
IFNE PRETRACKER_PARANOIA_MODE ; same wave for mixing cannot be selected in Pretracker
|
|
move.b d1,pv_wg_curr_wave_num_b(a4)
|
|
ENDC
|
|
lsl.w #2,d1
|
|
move.l pv_wave_sample_table(a4,d1.w),a0
|
|
move.l a0,pv_wg_curr_sample_ptr(a4)
|
|
|
|
IFND PRESTO_UNIFIED_STRUCT
|
|
add.w #sv_wavelength_table,d1
|
|
adda.w d1,a6
|
|
move.l sv_wavelength_table-sv_wavelength_table(a6),d0
|
|
move.l d0,pv_wg_curr_sample_len_l(a4)
|
|
IFNE PRETRACKER_PROGRESS_SUPPORT
|
|
move.l sv_wavetotal_table-sv_wavelength_table(a6),pv_precalc_sample_size(a4)
|
|
ENDC
|
|
move.l sv_waveinfo_table-sv_wavelength_table(a6),a3
|
|
ELSE ; PRESTO_UNIFIED_STRUCT
|
|
; Presto has no MySong structure
|
|
lea pv_wavelength_table(a4,d1.w),a6
|
|
|
|
; copied from raspberry_casket
|
|
moveq.l #0,d0
|
|
move.b wi_sam_len_b(a3),d0
|
|
addq.w #1,d0
|
|
lsl.w #7,d0
|
|
move.l d0,pv_wavelength_table-pv_wavelength_table(a6)
|
|
move.l d0,d1
|
|
btst #2,wi_flags_b(a3)
|
|
beq.s .onlythreeocts
|
|
mulu #15,d1
|
|
lsr.l #3,d1 ; * 1.875
|
|
.onlythreeocts
|
|
move.l d1,pv_wavetotal_table-pv_wavelength_table(a6)
|
|
; end stuff
|
|
move.l d0,pv_wg_curr_sample_len_l(a4)
|
|
IFNE PRETRACKER_PROGRESS_SUPPORT
|
|
move.l d1,pv_precalc_sample_size(a4)
|
|
ENDC
|
|
move.l pv_waveinfo_table-pv_wavelength_table(a6),a3
|
|
ENDC ; PRESTO_UNIFIED_STRUCT
|
|
|
|
; clear sample data (a0 and d0 from above)
|
|
bsr pre_MemClr
|
|
move.l a0,pv_wg_curr_samend_ptr(a4)
|
|
|
|
; read out chord information
|
|
lea wi_chord_note1_b(a3),a1
|
|
move.b (a1)+,d1
|
|
move.b (a1)+,d2
|
|
move.b (a1)+,d3
|
|
|
|
moveq.l #0,d4
|
|
move.b d1,d4
|
|
or.b d2,d4
|
|
or.b d3,d4
|
|
seq d4
|
|
neg.b d4
|
|
move.w d4,pv_wg_chord_flag_w(a4) ; has chord flag (0/1)
|
|
|
|
move.b wi_osc_basenote_b(a3),d0
|
|
add.b d0,d1
|
|
add.b d0,d2
|
|
add.b d0,d3
|
|
lea pv_wg_chord_pitches(a4),a1
|
|
move.b d0,(a1)+
|
|
move.b d1,(a1)+
|
|
move.b d2,(a1)+
|
|
move.b d3,(a1)+
|
|
|
|
clr.w pv_wg_chord_note_num_b(a4) ; and pv_wg_chord_note_num_b
|
|
|
|
.wavegen_chordloop
|
|
lea pv_wg_chord_pitches(a4),a1
|
|
moveq.l #0,d1
|
|
move.b pv_wg_chord_note_num_b(a4),d1 ; chord note counter
|
|
move.b (a1,d1.w),d0 ; get chord note
|
|
ext.w d0
|
|
|
|
tst.w d1
|
|
beq.s .base_note_is_never_skipped ; is base note?
|
|
cmp.b wi_osc_basenote_b(a3),d0
|
|
beq .wave_gen_tone_done ; skip chord notes that are same as base note
|
|
.base_note_is_never_skipped
|
|
moveq.l #0,d5
|
|
moveq.l #NOTES_IN_OCTAVE,d2
|
|
move.w d0,d5
|
|
move.w d0,a2 ; save base note, used later (much later, noise generator)!
|
|
add.w #NOTES_IN_OCTAVE*NOTES_IN_OCTAVE,d5 ; make sure we don't run into negative modulo
|
|
divu d2,d5
|
|
sub.w d2,d5 ; restore octave, result may be negative
|
|
move.w d5,d1 ; +-octave
|
|
swap d5 ; note within octave
|
|
|
|
moveq.l #0,d7
|
|
move.b .pre_log12_table(pc,d5.w),d7 ; 128, 121, 114, 107, 102, 96, 90, 85, 80, 76, 72, 67
|
|
|
|
moveq.l #3,d0
|
|
mulu d0,d5
|
|
and.b wi_flags_b(a3),d0
|
|
beq.s .osc_selected
|
|
addq.w #2,d5
|
|
subq.w #1,d0
|
|
beq.s .osc_selected
|
|
subq.w #1,d5
|
|
subq.w #1,d0
|
|
.osc_selected
|
|
lea pv_osc_buffers+owb_saw_waves(a4),a6
|
|
lsl.w #7,d5
|
|
adda.w d5,a6
|
|
|
|
; ----------------------------------------
|
|
; pitch ramp
|
|
move.b wi_pitch_ramp_b(a3),d2
|
|
ext.w d2
|
|
ext.l d2
|
|
btst #4,wi_flags_b(a3) ; pitch linear flag
|
|
beq.s .pitch_not_linear
|
|
tst.w d2
|
|
bgt.s .pitch_ramp_positive
|
|
|
|
; FIXME what happens if d1 is negative? rolls out by 63?
|
|
lsl.l d1,d2
|
|
add.l d2,d2
|
|
bra.s .pitch_ramp_cont
|
|
|
|
.pre_log12_table
|
|
dc.b $400000/$8000,$400000/$871d,$400000/$8f2f,$400000/$97b7,$400000/$9fc4,$400000/$a9de
|
|
dc.b $400000/$b505,$400000/$bf49,$400000/$cb31,$400000/$d645,$400000/$e215,$400000/$f1a0
|
|
|
|
.pitch_not_linear
|
|
tst.w d2
|
|
ble.s .pitch_ramp_cont
|
|
.pitch_ramp_positive
|
|
muls d2,d2
|
|
.pitch_ramp_cont
|
|
lsl.l #8,d2
|
|
lsl.l #2,d2
|
|
|
|
; check whether we have a noise oscillator or something else
|
|
tst.w d0
|
|
beq .no_noise
|
|
|
|
; ----------------------------------------
|
|
; d0 = scratch
|
|
; d1 = octave
|
|
; d2 = pitch ramping value
|
|
; d4 = scratch
|
|
; a2 = base note
|
|
.gen_noise
|
|
suba.l a6,a6
|
|
IFNE PRETRACKER_PARANOIA_MODE
|
|
tst.w pv_wg_curr_sample_len_w(a4)
|
|
beq .wave_gen_tone_done
|
|
ENDC
|
|
|
|
moveq.l #1,d5
|
|
ror.w #1,d5 ; $00008000
|
|
move.l d5,a5
|
|
tst.w d1
|
|
bge.s .gen_noise_positive_octave
|
|
|
|
.gen_noise_negative_octave
|
|
moveq.l #NOTES_IN_OCTAVE,d1
|
|
move.l a2,d3
|
|
neg.l d3
|
|
move.l d3,d0
|
|
divu d1,d0
|
|
IFNE PRETRACKER_PARANOIA_MODE
|
|
bvs.s .divisionoverflow
|
|
ENDC
|
|
addq.w #1,d0
|
|
lsr.w d0,d5
|
|
moveq.l #0,d0
|
|
move.w d5,d0
|
|
divu d1,d0
|
|
moveq.l #0,d4
|
|
move.w d0,d4
|
|
IFNE PRETRACKER_PARANOIA_MODE
|
|
bra.s .returnfromoverflow
|
|
.divisionoverflow
|
|
move.l #$AAA,d4 ; some dummy value, I would expect
|
|
.returnfromoverflow
|
|
ENDC
|
|
moveq.l #0,d0
|
|
move.w d3,d0
|
|
.cheap_mod12
|
|
sub.w d1,d0
|
|
bpl.s .cheap_mod12
|
|
neg.w d0
|
|
mulu d4,d0
|
|
add.l d0,d5
|
|
|
|
.gen_noise_positive_octave
|
|
moveq.l #0,d0
|
|
move.b wi_osc_phase_min_b(a3),d0
|
|
moveq.l #0,d1
|
|
move.b wi_chord_shift_b(a3),d1
|
|
add.w d1,d0
|
|
addq.w #1,d0
|
|
|
|
; sum of phase min and shift are used as root for noise
|
|
|
|
movea.l d5,a1
|
|
movea.l pv_wg_curr_sample_ptr(a4),a0
|
|
moveq.l #0,d1
|
|
moveq.l #0,d6
|
|
moveq.l #0,d3
|
|
move.b wi_osc_gain_b(a3),d3
|
|
|
|
.gen_noise_outerloop
|
|
move.w d0,d1 ; random noise generator
|
|
lsl.w #8,d1
|
|
lsl.w #5,d1
|
|
eor.w d1,d0
|
|
|
|
move.w d0,d1
|
|
lsr.w #8,d1
|
|
lsr.w #1,d1
|
|
eor.w d1,d0
|
|
|
|
move.w d0,d1
|
|
lsl.w #7,d1
|
|
eor.w d1,d0
|
|
|
|
move.b d0,d1 ; take the random seed
|
|
ext.w d1
|
|
muls d3,d1 ; multiply by gain
|
|
asr.w #7,d1
|
|
CLIPTO8BIT d1
|
|
add.b (a0),d1
|
|
|
|
move.w a5,d4
|
|
subq.w #1,d4
|
|
and.w #$7fff,d4
|
|
move.w d4,a5
|
|
addq.w #1,a5
|
|
|
|
.gen_noise_innerloop
|
|
move.b d1,(a0)+
|
|
cmp.l pv_wg_curr_samend_ptr(a4),a0
|
|
beq .wave_gen_tone_done
|
|
|
|
adda.l a1,a5
|
|
|
|
tst.l d2
|
|
beq.s .gen_noise_no_pitch_ramping
|
|
add.l d2,d6
|
|
move.l d6,d4
|
|
asr.l #8,d4
|
|
asr.l #2,d4
|
|
add.l d5,d4
|
|
movea.l d4,a1
|
|
|
|
btst #4,wi_flags_b(a3) ; pitch linear flag
|
|
beq.s .noise_nonlinear_pitch
|
|
move.l d2,d4 ; filter pitch speed
|
|
asr.l #7,d4
|
|
sub.l d4,d2
|
|
.noise_nonlinear_pitch
|
|
|
|
cmp.w #$1ff,a1
|
|
bgt.s .gen_noise_no_end_of_pitch_ramp
|
|
moveq.l #0,d2 ; stop pitch ramping
|
|
move.l d2,a5
|
|
movea.w #$200,a1
|
|
.gen_noise_no_end_of_pitch_ramp
|
|
.gen_noise_no_pitch_ramping
|
|
cmp.w a5,a5
|
|
beq.s .gen_noise_innerloop
|
|
|
|
bra .gen_noise_outerloop
|
|
|
|
; ----------------------------------------
|
|
; d1 = octave
|
|
; d2 = pitch ramping value
|
|
; d5 = osc phase speed
|
|
; a2 = base note
|
|
|
|
.no_noise
|
|
moveq.l #15,d5
|
|
lsl.l d5,d7
|
|
|
|
sub.w d1,d5 ; 15-octave
|
|
lsl.w #3,d5
|
|
|
|
moveq.l #0,d3
|
|
move.b wi_osc_phase_min_b(a3),d3
|
|
mulu d5,d3
|
|
lsl.l #6,d3
|
|
|
|
moveq.l #0,d0
|
|
move.b wi_osc_phase_max_b(a3),d0
|
|
mulu d5,d0
|
|
lsl.l #6,d0
|
|
move.l d0,a5
|
|
|
|
moveq.l #0,d5
|
|
move.b wi_osc_phase_spd_b(a3),d5
|
|
lsl.l #8,d5
|
|
lsl.l #3,d5
|
|
|
|
cmp.l d3,d0
|
|
bge.s .osc_with_positive_phase_speed
|
|
neg.l d5
|
|
|
|
movea.l d3,a5
|
|
bra.s .osc_continue
|
|
.osc_with_positive_phase_speed
|
|
move.l d3,d0
|
|
|
|
.osc_continue
|
|
move.l d0,pv_wg_osc_speed_l(a4)
|
|
|
|
; I think this calculates the base oscillator speed for higher and lower octaves
|
|
moveq.l #1,d6
|
|
moveq.l #15,d0
|
|
add.w d1,d0
|
|
lsl.l d0,d6
|
|
|
|
; d0 = d6 * chord_shift * chordnum + d6 * phase_min = d6 * (chord_shift * chordnum + phase_min)
|
|
|
|
moveq.l #0,d4
|
|
move.b wi_chord_shift_b(a3),d4
|
|
move.w pv_wg_chord_flag_w(a4),d0
|
|
add.b pv_wg_chord_note_num_b(a4),d0
|
|
mulu d0,d4
|
|
moveq.l #0,d0
|
|
move.b wi_osc_phase_min_b(a3),d0
|
|
add.w d0,d4
|
|
move.l d6,d0
|
|
lsr.l #4,d0
|
|
lsl.l #4,d4
|
|
mulu d4,d0
|
|
|
|
.osc_loop_until_in_range
|
|
sub.l d7,d0
|
|
bgt.s .osc_loop_until_in_range
|
|
add.l d7,d0
|
|
|
|
move.l d6,d1
|
|
tst.b pv_wg_unisono_run_b(a4)
|
|
beq.s .is_not_in_unisono
|
|
|
|
moveq.l #3<<3,d1
|
|
and.b wi_mod_density_b(a3),d1
|
|
lsr.w #3,d1
|
|
moveq.l #9,d4
|
|
sub.w d1,d4
|
|
|
|
move.l d6,d1
|
|
asr.l d4,d1
|
|
add.l d6,d1
|
|
.is_not_in_unisono
|
|
|
|
IFNE PRETRACKER_PARANOIA_MODE
|
|
tst.w pv_wg_curr_sample_len_w(a4)
|
|
beq .wave_gen_tone_done
|
|
ENDC
|
|
|
|
; ----------------------------------------
|
|
; chord gen
|
|
; in: d0/d1/d2/d3/d5/d7
|
|
; in: a0
|
|
move.l d3,a1
|
|
movea.l pv_wg_curr_sample_ptr(a4),a0
|
|
suba.l a2,a2
|
|
|
|
.chordtoneloop
|
|
move.l d0,d4
|
|
sub.l a1,d4
|
|
bpl.s .noclip_osc_phase
|
|
moveq.l #0,d4
|
|
.noclip_osc_phase
|
|
asr.l #8,d4
|
|
asr.l #7,d4
|
|
move.b (a6,d4.w),d4 ; fetch precalced sample
|
|
ext.w d4
|
|
|
|
moveq.l #0,d3
|
|
move.b wi_osc_gain_b(a3),d3
|
|
muls d4,d3
|
|
asr.w #7,d3
|
|
|
|
move.b (a0),d4
|
|
ext.w d4
|
|
add.w d3,d4
|
|
CLIPTO8BIT d4
|
|
move.b d4,(a0)+
|
|
|
|
add.l d1,d0
|
|
cmp.l d7,d0
|
|
blt.s .lbC0025A2
|
|
sub.l d7,d0
|
|
add.l d5,a1
|
|
cmp.l a5,a1
|
|
blt.s .lbC00259A
|
|
neg.l d5
|
|
move.l a5,a1
|
|
.lbC00259A
|
|
cmp.l pv_wg_osc_speed_l(a4),a1
|
|
bgt.s .lbC0025A2
|
|
neg.l d5
|
|
move.l pv_wg_osc_speed_l(a4),a1
|
|
.lbC0025A2
|
|
tst.l d2
|
|
beq.s .chordtone_done
|
|
adda.l d2,a2
|
|
move.l a2,d1
|
|
asr.l #8,d1
|
|
asr.l #2,d1
|
|
add.l d6,d1
|
|
|
|
btst #4,wi_flags_b(a3) ; pitch linear flag
|
|
beq.s .no_linear_pitch
|
|
move.l d2,d4
|
|
asr.l #7,d4
|
|
sub.l d4,d2
|
|
.no_linear_pitch
|
|
cmp.l d7,d1
|
|
bcs.s .chordtone_done
|
|
moveq.l #0,d2
|
|
moveq.l #0,d1
|
|
.chordtone_done
|
|
cmp.l pv_wg_curr_samend_ptr(a4),a0
|
|
bne.s .chordtoneloop
|
|
|
|
.wave_gen_tone_done
|
|
addq.b #1,pv_wg_chord_note_num_b(a4)
|
|
cmp.b #4,pv_wg_chord_note_num_b(a4)
|
|
bne .wavegen_chordloop
|
|
|
|
moveq.l #3<<3,d0
|
|
and.b wi_mod_density_b(a3),d0 ; unisono
|
|
beq.s .chords_done
|
|
move.l a6,d1
|
|
beq.s .chords_done
|
|
tst.b pv_wg_unisono_run_b(a4)
|
|
bne.s .chords_done
|
|
move.w #$0001,pv_wg_chord_note_num_b(a4) ; sets also pv_wg_unisono_run_b
|
|
bra .wavegen_chordloop
|
|
|
|
.chords_done
|
|
; ----------------------------------------
|
|
; filters
|
|
; proposed register assignment:
|
|
; a0 = sample output
|
|
; a1 = end of filter chunk
|
|
; a2 = filter func
|
|
; d7/a6 = filter start
|
|
; a4 = MyPlayer
|
|
; a5 = unused
|
|
; a3 = waveinfo
|
|
; d3/d4/d5/d6 = filter taps
|
|
; d0/d1/d7 = scratch
|
|
|
|
moveq.l #0,d0
|
|
move.b wi_flt_type_b(a3),d0
|
|
beq .filter_done
|
|
|
|
IFNE PRETRACKER_PARANOIA_MODE
|
|
tst.w pv_wg_curr_sample_len_w(a4)
|
|
beq .filter_done
|
|
ENDC
|
|
|
|
add.w d0,d0
|
|
lea .filterfunc_jmptable(pc),a2
|
|
add.w -1*2(a2,d0.w),a2
|
|
|
|
moveq.l #0,d4 ; filter tap values
|
|
moveq.l #0,d5 ; filter tap values
|
|
movem.l d4-d5,pv_wg_flt_taps(a4)
|
|
|
|
lea wi_flt_start_b(a3),a0
|
|
moveq.l #0,d0
|
|
move.b (a0)+,d0 ; wi_flt_start_b
|
|
lsl.w #8,d0
|
|
|
|
move.b (a0)+,d4 ; wi_flt_min_b
|
|
lsl.w #8,d4 ; flt_min*256
|
|
|
|
move.b (a0)+,d5 ; wi_flt_max_b
|
|
lsl.w #8,d5 ; flt_max*256
|
|
|
|
move.b (a0)+,d3 ; wi_flt_speed_b
|
|
ext.w d3
|
|
ext.l d3 ; flt_speed*128
|
|
lsl.l #7,d3
|
|
|
|
movea.l pv_wg_curr_sample_ptr(a4),a0
|
|
|
|
.entry_to_filter_loop
|
|
move.l d0,a6
|
|
move.l d3,d1 ; flt_speed_b*128
|
|
adda.l d1,a6 ; suppress M68kUnexpectedConditionalInstruction
|
|
bgt.s .filter_speed_pos
|
|
|
|
.filter_speed_neg
|
|
move.l d4,d1 ; flt_min*256
|
|
cmp.l d1,d0
|
|
blt.s .lbC002790
|
|
cmp.l d1,a6
|
|
bgt.s .lbC002936
|
|
move.l d1,a6
|
|
cmp.l d5,d1 ; flt_max*256
|
|
beq.s .filter_load_min
|
|
neg.l d3 ; flt_speed_b*128
|
|
bra.s .filter_load_min
|
|
|
|
.filterfunc_jmptable
|
|
dc.w .lowpassfilter-.filterfunc_jmptable
|
|
dc.w .highpassfilter-.filterfunc_jmptable
|
|
dc.w .bandpassfilter-.filterfunc_jmptable
|
|
dc.w .notchfilter-.filterfunc_jmptable
|
|
|
|
.lbC002790
|
|
tst.l d0
|
|
blt.s .lbC002936
|
|
move.l a6,d7
|
|
bgt.s .lbC002936
|
|
neg.l d3 ; flt_speed_b*128
|
|
move.w #$FF,d2
|
|
move.w d2,d1
|
|
sub.l a6,a6
|
|
bra.s .filter_cont
|
|
|
|
.filter_speed_pos
|
|
cmp.l d5,d0 ; flt_max*256
|
|
bgt.s .lbC002D2A
|
|
cmp.l d5,a6 ; flt_max*256
|
|
blt.s .lbC002936
|
|
move.l d4,d2 ; flt_min*256
|
|
cmp.l d5,d2 ; flt_max*256
|
|
beq.s .filter_load_max_no_flip
|
|
neg.l d3 ; flt_speed_b*128
|
|
move.l d5,a6 ; flt_max*256
|
|
bra.s .filter_load_max
|
|
|
|
.lbC002D2A
|
|
cmpi.l #$FF00,d0
|
|
bgt.s .lbC002936
|
|
cmp.l #$FEFF,a6
|
|
ble.s .lbC002936
|
|
neg.l d3 ; flt_speed_b*128
|
|
moveq.l #0,d2
|
|
move.l #$FF00,a6
|
|
bra.s .filter_cont
|
|
|
|
.lbC002936
|
|
move.w a6,d2
|
|
lsr.w #8,d2
|
|
not.b d2
|
|
bra.s .filter_cont
|
|
|
|
.filter_load_max_no_flip
|
|
movea.l d2,a6
|
|
.filter_load_max
|
|
moveq.l #0,d2
|
|
move.b wi_flt_max_b(a3),d2
|
|
not.b d2
|
|
bra.s .filter_cont
|
|
|
|
.filter_load_min
|
|
moveq.l #0,d2
|
|
move.b wi_flt_min_b(a3),d2
|
|
not.b d2
|
|
|
|
.filter_cont
|
|
btst #0,wi_flt_type_b(a3)
|
|
bne.s .not_notch_or_highpass
|
|
.highpass_or_notch ; entered for 2 or 4
|
|
not.b d2
|
|
.not_notch_or_highpass ; entered for 1 or 3
|
|
move.w d2,d0
|
|
add.w d0,d0
|
|
|
|
moveq.l #0,d7
|
|
move.b wi_flt_resonance_b(a3),d7
|
|
beq.s .filter_no_resonance
|
|
move.w d2,d1
|
|
ext.l d1
|
|
lsl.l #8,d1
|
|
|
|
moveq.l #$B6/2,d0
|
|
sub.w d7,d0
|
|
add.w d0,d0
|
|
|
|
cmpi.w #$36,d0
|
|
bge.s .filter_no_clip_resonance
|
|
moveq.l #$36,d0
|
|
.filter_no_clip_resonance
|
|
divu d0,d1
|
|
move.w d2,d0
|
|
add.w d1,d0
|
|
.filter_no_resonance
|
|
lea $40(a0),a1 ; end of sample chunk
|
|
|
|
movem.l d3-d5,-(sp)
|
|
movem.w pv_wg_flt_taps(a4),d3-d6
|
|
|
|
; d0/d2 relevant for inner loop
|
|
.filter_innerloop
|
|
move.b (a0),d1
|
|
ext.w d1
|
|
|
|
move.w d4,d7
|
|
sub.w d5,d7
|
|
muls d0,d7
|
|
asr.l #8,d7
|
|
sub.w d4,d7
|
|
|
|
add.w d1,d7
|
|
muls d2,d7
|
|
asr.l #8,d7
|
|
add.w d7,d4
|
|
move.w d4,d7
|
|
|
|
sub.w d5,d7
|
|
muls d2,d7
|
|
asr.l #8,d7
|
|
add.w d7,d5
|
|
move.w d5,d7
|
|
|
|
sub.w d6,d7
|
|
muls d2,d7
|
|
asr.l #8,d7
|
|
add.w d7,d6
|
|
move.w d6,d7
|
|
|
|
sub.w d3,d7
|
|
muls d2,d7
|
|
asr.l #8,d7
|
|
add.w d7,d3
|
|
move.w d3,d7
|
|
|
|
jmp (a2)
|
|
|
|
.highpassfilter
|
|
sub.w d1,d7
|
|
bra.s .filterclipresult
|
|
|
|
.bandpassfilter
|
|
sub.w d4,d7
|
|
sub.w d5,d7
|
|
sub.w d6,d7
|
|
asr.w #1,d7
|
|
bra.s .filterclipresult
|
|
|
|
.notchfilter
|
|
sub.w d4,d7
|
|
neg.w d7
|
|
|
|
.lowpassfilter
|
|
.filterclipresult
|
|
CLIPTO8BIT d7
|
|
.filter_outputbyte
|
|
move.b d7,(a0)+
|
|
cmp.l a0,a1
|
|
bne.s .filter_innerloop
|
|
|
|
.filterloop_end_test
|
|
movem.w d3-d6,pv_wg_flt_taps(a4)
|
|
movem.l (sp)+,d3-d5
|
|
|
|
cmp.l pv_wg_curr_samend_ptr(a4),a0
|
|
bhs.s .filter_done
|
|
move.l a6,d0
|
|
bra .entry_to_filter_loop
|
|
|
|
.filter_done
|
|
; ----------------------------------------
|
|
; Optional Pre-Modulator
|
|
btst #5,wi_mod_density_b(a3) ; post bit
|
|
bne.s .nopremodulator
|
|
bsr pre_Modulator
|
|
.nopremodulator
|
|
|
|
; ----------------------------------------
|
|
; start with volume envelope
|
|
; a0 = output sample buffer
|
|
; d0 = scratch (e.g. sample)
|
|
; d1 = increment for attack phase
|
|
; d3 = current volume for attack and decay phases
|
|
; d4 = remaining sample length - 1
|
|
; a3 = wave info
|
|
|
|
.vol_do_envelope
|
|
move.l pv_wg_curr_sample_ptr(a4),a0 ; load buffer pointer
|
|
move.w pv_wg_curr_sample_len_w(a4),d4 ; load length
|
|
IFNE PRETRACKER_PARANOIA_MODE
|
|
beq .vol_envelope_finished ; paranoia
|
|
ENDC
|
|
subq.w #1,d4 ; we use length-1, <0 is end
|
|
|
|
moveq.l #2,d1 ; turns into $20000 through swap
|
|
moveq.l #0,d0
|
|
move.b wi_vol_attack_b(a3),d0
|
|
bne.s .has_attack_volume
|
|
cmp.b #$ff,wi_vol_sustain_b(a3)
|
|
beq .vol_envelope_finished
|
|
; no attack but not full sustain -> go to delay
|
|
;move.l #$100<<16,d3
|
|
bra.s .vol_skip_attack
|
|
|
|
.vol_avoid_overflow_with_1
|
|
moveq.l #1,d1
|
|
bra.s .cont_vol_envelope
|
|
.has_attack_volume
|
|
moveq.l #0,d3
|
|
cmp.w #1,d0
|
|
beq.s .cont_vol_envelope
|
|
cmp.w #2,d0
|
|
beq.s .vol_avoid_overflow_with_1
|
|
swap d1 ; turn into $20000
|
|
divu d0,d1
|
|
swap d1
|
|
clr.w d1
|
|
; swap is done below
|
|
.cont_vol_envelope
|
|
swap d1 ; move to high word (should be max $20000 then)
|
|
btst #5,wi_flags_b(a3) ; vol fast flag
|
|
beq.s .vol_no_fast
|
|
lsl.l #4,d1 ; multiply speed by 16
|
|
.vol_no_fast
|
|
add.l d1,d3 ; increase volume
|
|
cmp.l #$ffffff,d3
|
|
ble.s .vol_do_attack ; first step overshooting?
|
|
.vol_skip_attack
|
|
btst #3,wi_flags_b(a3) ; boost flag
|
|
bne.s .vol_delay_boosted
|
|
bra.s .vol_delay_normal
|
|
|
|
.vol_do_attack
|
|
btst #3,wi_flags_b(a3) ; boost flag
|
|
bne.s .vol_attack_boosted
|
|
|
|
; ----------------------------------------
|
|
; attack phase with volume boosted
|
|
.vol_attack_normal
|
|
.vol_attack_normal_loop
|
|
move.b (a0),d0
|
|
ext.w d0
|
|
swap d3
|
|
muls d3,d0
|
|
swap d3
|
|
asr.w #8,d0
|
|
move.b d0,(a0)+
|
|
|
|
subq.w #1,d4
|
|
bmi .vol_envelope_finished
|
|
add.l d1,d3 ; increase volume
|
|
cmp.l #$ffffff,d3
|
|
ble.s .vol_attack_normal_loop
|
|
|
|
; ----------------------------------------
|
|
; delay phase (normal)
|
|
|
|
.vol_delay_normal ; moved this label two inst up, didn't make sense there
|
|
moveq.l #0,d0
|
|
move.b wi_vol_delay_b(a3),d0
|
|
lsl.w #4,d0
|
|
|
|
IFNE PRETRACKER_FASTER_CODE
|
|
; skip the delay -- we don't change the volume for this section
|
|
addq.w #1,d0
|
|
sub.w d0,d4
|
|
bmi .vol_envelope_finished
|
|
lea 1(a0,d0.w),a0
|
|
ELSE
|
|
lea 2(a0,d0.w),a1
|
|
|
|
move.w #$ff,d3 ; FIXME I don't think that this is quite right. Shouldn't the max volume NOT change the value?
|
|
.vol_delay_normal_loop
|
|
move.b (a0),d0
|
|
IFNE 1
|
|
ext.w d0
|
|
muls d3,d0
|
|
asr.w #8,d0
|
|
ELSE
|
|
; this should be the same as above (*(256-1))
|
|
spl d3
|
|
add.b d3,d0
|
|
ENDC
|
|
move.b d0,(a0)+
|
|
|
|
cmp.l a1,a0
|
|
dbeq d4,.vol_delay_normal_loop
|
|
bne .vol_envelope_finished
|
|
ENDC
|
|
|
|
bra.s .vol_delay_end_reached
|
|
|
|
; ----------------------------------------
|
|
; attack with volume boosted
|
|
|
|
.vol_attack_boosted
|
|
.vol_attack_boosted_loop
|
|
move.b (a0),d0
|
|
ext.w d0
|
|
swap d3
|
|
muls d3,d0
|
|
swap d3
|
|
asr.w #6,d0
|
|
CLIPTO8BIT d0
|
|
move.b d0,(a0)+
|
|
|
|
subq.w #1,d4
|
|
bmi .vol_envelope_finished
|
|
add.l d1,d3
|
|
cmp.l #$ffffff,d3
|
|
ble.s .vol_attack_boosted_loop
|
|
|
|
; ----------------------------------------
|
|
; delay with max volume boosted
|
|
|
|
.vol_delay_boosted
|
|
moveq.l #0,d0
|
|
move.b wi_vol_delay_b(a3),d0
|
|
lsl.w #4,d0
|
|
|
|
lea 2(a0,d0.w),a1
|
|
|
|
IFNE PRETRACKER_FASTER_CODE
|
|
.vol_delay_boosted_loop
|
|
move.b (a0),d0
|
|
add.b d0,d0
|
|
CLIPTO8BITAFTERADD d0
|
|
add.b d0,d0
|
|
CLIPTO8BITAFTERADD d0
|
|
ELSE
|
|
move.w #$ff,d3 ; FIXME I don't think that this is quite right. It should be $100 to boost by full volume
|
|
.vol_delay_boosted_loop
|
|
move.b (a0),d0
|
|
ext.w d0
|
|
muls d3,d0
|
|
asr.w #6,d0
|
|
CLIPTO8BIT d0
|
|
ENDC
|
|
move.b d0,(a0)+
|
|
|
|
cmp.l a1,a0
|
|
dbeq d4,.vol_delay_boosted_loop
|
|
bne .vol_envelope_finished
|
|
|
|
.vol_delay_end_reached
|
|
subq.w #1,d4
|
|
|
|
; ----------------------------------------
|
|
; decay phase
|
|
; d0 = scratch
|
|
; d1 = current volume decrement
|
|
; d2 = table index boundary
|
|
; d3 = 16:16 decay pos
|
|
; d4 = sample length counter
|
|
; d5 = volume
|
|
; d6 = scratch
|
|
; d7 = decay increment
|
|
; a0 = sample pointer
|
|
; a1 = (current) roll off table pointer (points to upper bound)
|
|
; a2 = lower bound
|
|
|
|
.vol_do_decay
|
|
moveq.l #0,d3
|
|
move.b wi_vol_decay_b(a3),d3
|
|
beq .vol_do_sustain
|
|
move.w d3,d7
|
|
mulu d7,d7
|
|
lsr.w #2,d7
|
|
add.w d3,d7 ; d7 = (d3^2)/4+d3 (<= 16511)
|
|
|
|
btst #5,wi_flags_b(a3) ; vol fast flag
|
|
beq.s .vol_decay_not_fast
|
|
moveq.l #0,d3 ; will cause a5=$400,a2=$200,d2=0, decay value has no effect on the ramp used
|
|
.vol_decay_not_fast
|
|
lsl.w #8,d3
|
|
lsl.l #4,d3
|
|
move.l d3,d2
|
|
swap d2
|
|
lea pre_roll_off_table(pc),a1
|
|
add.w d2,d2
|
|
adda.w d2,a1
|
|
move.w (a1)+,a2 ; first index in table
|
|
lsr.w #1,d2 ; update next boundary
|
|
|
|
moveq.l #0,d1 ; current volume decrement
|
|
moveq.l #0,d5
|
|
not.w d5 ; set maximum volume
|
|
.vol_decay_normal_loop
|
|
add.l d7,d3 ; increment position in decay
|
|
swap d3
|
|
|
|
cmp.w #$8e,d3 ; pos in table where it makes no sense to do lerp anymore
|
|
bhi.s .vol_keep_voldec
|
|
cmp.w d2,d3
|
|
bls.s .vol_do_lerp
|
|
|
|
.vol_lerp_next_section
|
|
move.w (a1),a2
|
|
IFNE PRETRACKER_BUGFIX_CODE
|
|
lea pre_roll_off_table+2(pc),a1 ; Take the right boundary value
|
|
ELSE
|
|
lea pre_roll_off_table(pc),a1 ; This will set a wrong boundary and thus plateau the slope decay speed
|
|
ENDC
|
|
add.w d3,a1
|
|
add.w d3,a1
|
|
|
|
move.w d3,d2 ; update next boundary
|
|
|
|
.vol_do_lerp ; ((lowerbound-upperbound)*(d3<<8))>>8 + upperbound
|
|
move.w a2,d1
|
|
move.w (a1),d0
|
|
sub.w d1,d0 ; delta between lower and upper bound (negative value)
|
|
beq.s .vol_skip_lerp
|
|
|
|
swap d3
|
|
move.w d3,d1
|
|
lsr.w #8,d1
|
|
muls d0,d1
|
|
asr.l #8,d1
|
|
add.w a2,d1
|
|
swap d3
|
|
|
|
.vol_keep_voldec
|
|
.vol_skip_lerp
|
|
swap d3
|
|
sub.w d1,d5
|
|
bls.s .vol_do_sustain
|
|
|
|
move.w d5,d6
|
|
lsr.w #8,d6
|
|
|
|
cmp.b wi_vol_sustain_b(a3),d6
|
|
bls.s .vol_do_sustain
|
|
|
|
move.b (a0),d0
|
|
ext.w d0
|
|
muls d6,d0
|
|
btst #3,wi_flags_b(a3) ; boost flag
|
|
CLIPORTRUNC8BIT d0
|
|
move.b d0,(a0)+
|
|
|
|
dbra d4,.vol_decay_normal_loop
|
|
bra.s .vol_envelope_finished
|
|
|
|
; ----------------------------------------
|
|
; sustain phase
|
|
.vol_do_sustain
|
|
moveq.l #0,d3
|
|
move.b wi_vol_sustain_b(a3),d3
|
|
beq.s .vol_sustain_silence
|
|
|
|
btst #3,wi_flags_b(a3) ; boost flag
|
|
beq.s .vol_sustain_normal
|
|
.vol_sustain_boosted
|
|
.vol_sustain_boosted_loop
|
|
move.b (a0),d0
|
|
ext.w d0
|
|
muls d3,d0
|
|
asr.w #6,d0
|
|
|
|
CLIPTO8BIT d0
|
|
move.b d0,(a0)+
|
|
dbra d4,.vol_sustain_boosted_loop
|
|
bra.s .vol_envelope_finished
|
|
|
|
.vol_sustain_silence
|
|
moveq.l #0,d0
|
|
.vol_sustain_silence_loop
|
|
move.b d0,(a0)+
|
|
dbra d4,.vol_sustain_silence_loop
|
|
bra.s .vol_envelope_finished
|
|
|
|
.vol_sustain_normal
|
|
IFNE PRETRACKER_FASTER_CODE
|
|
cmp.b #$ff,d3
|
|
beq.s .vol_envelope_finished
|
|
ENDC
|
|
|
|
.vol_sustain_normal_loop
|
|
move.b (a0),d0
|
|
ext.w d0
|
|
muls d3,d0
|
|
asr.w #8,d0
|
|
move.b d0,(a0)+
|
|
dbra d4,.vol_sustain_normal_loop
|
|
|
|
.vol_envelope_finished
|
|
|
|
; ----------------------------------------
|
|
; Optional Post-Modulator
|
|
|
|
btst #5,wi_mod_density_b(a3) ; post bit
|
|
beq.s .nopostmodulator
|
|
bsr.s pre_Modulator
|
|
.nopostmodulator
|
|
|
|
; ----------------------------------------
|
|
; wave mixing (removed some code here that was doing nothing as result
|
|
; because below higher octaves code would overwrite it anyway).
|
|
IFND PRESTO_UNIFIED_STRUCT
|
|
movea.l pv_my_song(a4),a6
|
|
ENDC
|
|
|
|
moveq.l #0,d0
|
|
move.b wi_mix_wave_b(a3),d0
|
|
beq.s .mix_no_wave_mixing ; no mixing selected
|
|
subq.b #1,d0
|
|
IFNE PRETRACKER_PARANOIA_MODE ; same wave for mixing cannot be selected in Pretracker
|
|
cmp.b pv_wg_curr_wave_num_b(a4),d0
|
|
beq .mix_no_wave_mixing ; same wave number!
|
|
ENDC
|
|
|
|
lsl.w #2,d0
|
|
move.l pv_wave_sample_table(a4,d0.w),a1
|
|
IFND PRESTO_UNIFIED_STRUCT
|
|
add.w #sv_wavelength_table,d0
|
|
move.l (a6,d0.w),d3
|
|
ELSE
|
|
move.l pv_wavelength_table(a4,d0.w),d3
|
|
ENDC
|
|
|
|
move.w pv_wg_curr_sample_len_w(a4),d4 ; length of the sample to mix to
|
|
cmp.w d3,d4
|
|
ble.s .mix_picked_shorter
|
|
move.w d3,d4
|
|
.mix_picked_shorter
|
|
|
|
move.l pv_wg_curr_sample_ptr(a4),a0
|
|
|
|
subq.w #1,d4
|
|
.mix_mixloop
|
|
move.b (a0),d0
|
|
add.b (a1)+,d0
|
|
CLIPTO8BITAFTERADD d0
|
|
move.b d0,(a0)+
|
|
dbra d4,.mix_mixloop
|
|
.mix_no_wave_mixing
|
|
|
|
; ----------------------------------------
|
|
; create higher octaves (this has been massively shortened)
|
|
|
|
btst #2,wi_flags_b(a3)
|
|
beq.s .oct_has_no_extra_octaves
|
|
|
|
move.l pv_wg_curr_sample_len_l(a4),d4
|
|
IFNE PRETRACKER_PARANOIA_MODE
|
|
beq.s .oct_has_no_extra_octaves
|
|
ENDC
|
|
|
|
movea.l pv_wg_curr_sample_ptr(a4),a1
|
|
lea (a1,d4.l),a0 ; needs to be .l due to 32678 max length
|
|
|
|
mulu #7,d4
|
|
lsr.l #3,d4 ; * 0.875
|
|
subq.w #1,d4
|
|
.oct_downsample_loop
|
|
move.b (a1),(a0)+
|
|
addq.l #2,a1
|
|
dbra d4,.oct_downsample_loop
|
|
|
|
.oct_has_no_extra_octaves
|
|
; ----------------------------------------
|
|
IFNE PRETRACKER_PROGRESS_SUPPORT
|
|
move.l pv_precalc_progress_ptr(a4),d0
|
|
beq.s .no_progress_out
|
|
move.l d0,a0
|
|
move.l pv_precalc_sample_size(a4),d0
|
|
add.l d0,(a0)
|
|
.no_progress_out
|
|
ENDC
|
|
move.l (sp)+,a1
|
|
subq.w #1,pv_wg_wave_counter_w(a4)
|
|
bgt .wavegenloop
|
|
|
|
rts
|
|
|
|
;--------------------------------------------------------------------
|
|
; a3: waveinfo
|
|
;
|
|
; uses all data registers and a0-a1 (a2/a3 unchanged)
|
|
pre_Modulator:
|
|
tst.b wi_mod_wetness_b(a3)
|
|
beq.s .earlyexit
|
|
moveq.l #7,d0
|
|
and.b wi_mod_density_b(a3),d0
|
|
bne.s .has_density
|
|
.earlyexit
|
|
rts
|
|
.has_density
|
|
move.l pv_wg_curr_sample_ptr(a4),a0
|
|
move.w pv_wg_curr_sample_len_w(a4),d4
|
|
IFNE PRETRACKER_PARANOIA_MODE
|
|
bne.s .not_zero
|
|
rts
|
|
.not_zero
|
|
ENDC
|
|
moveq.l #0,d6
|
|
move.b wi_mod_wetness_b(a3),d6
|
|
|
|
moveq.l #0,d7
|
|
|
|
lea pre_modulator_ramp_8(pc),a1
|
|
.loop moveq.l #0,d5
|
|
move.b wi_mod_length_b(a3),d5
|
|
mulu (a1)+,d5 ; result is a long value
|
|
|
|
moveq.l #0,d1
|
|
move.b wi_mod_predelay_b(a3),d1
|
|
|
|
btst #5,wi_mod_density_b(a3) ; post-modulator?
|
|
bne.s .factor1_256
|
|
; factor 1/4 and 64
|
|
lsr.l #2,d5
|
|
lsl.l #6,d1
|
|
bra.s .cont
|
|
|
|
.factor1_256
|
|
lsl.w #8,d1
|
|
.cont add.l d1,d5 ; sum up length and predelay
|
|
|
|
moveq.l #0,d2
|
|
moveq.l #0,d3
|
|
|
|
.innerloop
|
|
moveq.l #0,d1
|
|
add.w d7,d3
|
|
addq.w #8,d3
|
|
smi d1
|
|
ext.w d1
|
|
eor.w d3,d1 ; flip order if it was negative
|
|
lsr.w #6,d1 ; 4 bit key is bits 14 to 11, needs to be 8 to 5
|
|
and.w #15<<5,d1
|
|
|
|
add.l d5,d1
|
|
lsr.l #6,d1
|
|
|
|
move.w d2,d0
|
|
sub.w d1,d0
|
|
bmi.s .is_outside_sample
|
|
|
|
move.b (a0,d0.w),d1
|
|
ext.w d1
|
|
btst #0,d7
|
|
beq.s .keep_dc
|
|
neg.w d1
|
|
.keep_dc
|
|
|
|
muls d6,d1
|
|
asr.w #8,d1
|
|
add.b (a0,d2.w),d1
|
|
|
|
CLIPTO8BITAFTERADD d1
|
|
move.b d1,(a0,d2.w)
|
|
.is_outside_sample
|
|
addq.w #1,d2
|
|
cmp.w d4,d2
|
|
bcs.s .innerloop
|
|
|
|
.restartloop
|
|
addq.w #1,d7
|
|
moveq.l #7,d0
|
|
and.b wi_mod_density_b(a3),d0
|
|
cmp.w d0,d7
|
|
bcs.s .loop
|
|
rts
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
|
|
pre_MemClr
|
|
lsr.w #1,d0
|
|
subq.w #1,d0
|
|
bmi.s .skipmemclr
|
|
moveq.l #0,d1
|
|
.fillmemloop
|
|
move.w d1,(a0)+
|
|
dbra d0,.fillmemloop
|
|
.skipmemclr
|
|
rts
|