mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-01-27 07:30:12 +00:00
interlace: split off pt3_lib_decode_note.s
This commit is contained in:
parent
918d498415
commit
affccc522d
@ -46,7 +46,8 @@ RASTERBARS_SOUND: rasterbars_sound.o
|
||||
rasterbars_sound.o: rasterbars_sound.s gr_copy.s \
|
||||
rasterbars_screen.s rasterbars_table.s movement_table.s rb_bg.inc \
|
||||
pt3_lib_core.s pt3_lib_init.s pt3_lib_mockingboard.s \
|
||||
pt3_lib_sample_ornament.s pt3_write_frame.s pt3_lib_calculate_note.s
|
||||
pt3_lib_sample_ornament.s pt3_write_frame.s pt3_lib_calculate_note.s \
|
||||
pt3_lib_decode_note.s
|
||||
ca65 -o rasterbars_sound.o rasterbars_sound.s -l rasterbars_sound.lst
|
||||
|
||||
|
||||
|
@ -93,683 +93,7 @@ end_vars=$80+(NOTE_STRUCT_SIZE*3)
|
||||
|
||||
.include "pt3_lib_sample_ornament.s"
|
||||
.include "pt3_lib_calculate_note.s"
|
||||
|
||||
|
||||
|
||||
;=====================================
|
||||
; Decode Note
|
||||
;=====================================
|
||||
; X points to the note offset
|
||||
|
||||
; Note! These timings are out of date (FIXME)
|
||||
; Timings (from ===>)
|
||||
; 00: 14+30
|
||||
; 0X: 14+15
|
||||
; 10: 14+5 +124
|
||||
; 1X: 14+5 +193
|
||||
; 2X/3X: 14+5 +17
|
||||
; 4X: 14+5+5 + 111
|
||||
; 5X-BX: 14+5+5+ 102
|
||||
; CX:
|
||||
; DX/EX:
|
||||
; FX:
|
||||
|
||||
stop_decoding:
|
||||
|
||||
; we are still running, decrement and early return
|
||||
dec note_a+NOTE_LEN_COUNT,X ; 7
|
||||
rts ; 6
|
||||
|
||||
;=====================================
|
||||
; Decode Line
|
||||
;=====================================
|
||||
|
||||
pt3_decode_line:
|
||||
; decode_note(&pt3->a,&(pt3->a_addr),pt3);
|
||||
ldx #(NOTE_STRUCT_SIZE*0) ; 2
|
||||
jsr decode_note ; 6+??
|
||||
|
||||
; decode_note(&pt3->b,&(pt3->b_addr),pt3);
|
||||
ldx #(NOTE_STRUCT_SIZE*1) ; 2
|
||||
jsr decode_note ; 6+??
|
||||
|
||||
; decode_note(&pt3->c,&(pt3->c_addr),pt3);
|
||||
ldx #(NOTE_STRUCT_SIZE*2) ; 2
|
||||
;;jsr decode_note ; fall through
|
||||
|
||||
; if (pt3->a.all_done && pt3->b.all_done && pt3->c.all_done) {
|
||||
; return 1;
|
||||
; }
|
||||
|
||||
|
||||
;=================================
|
||||
;=================================
|
||||
; decode note
|
||||
;=================================
|
||||
;=================================
|
||||
|
||||
decode_note:
|
||||
|
||||
; Init vars
|
||||
|
||||
ldy #0 ; 2
|
||||
sty spec_command_smc+1 ; 4
|
||||
|
||||
; Skip decode if note still running
|
||||
lda note_a+NOTE_LEN_COUNT,X ; 4
|
||||
cmp #2 ; 2
|
||||
bcs stop_decoding ; blt, assume not negative ; 3
|
||||
; -1
|
||||
|
||||
keep_decoding:
|
||||
|
||||
lda note_a+NOTE_NOTE,X ; store prev note ; 4
|
||||
sta prev_note_smc+1 ; 4
|
||||
|
||||
lda note_a+NOTE_TONE_SLIDING_H,X ; store prev sliding ; 4
|
||||
sta prev_sliding_h_smc+1 ; 4
|
||||
lda note_a+NOTE_TONE_SLIDING_L,X ; 4
|
||||
sta prev_sliding_l_smc+1 ; 4
|
||||
|
||||
|
||||
note_decode_loop:
|
||||
lda note_a+NOTE_LEN,X ; re-up length count ; 4
|
||||
sta note_a+NOTE_LEN_COUNT,X ; 4
|
||||
|
||||
lda note_a+NOTE_ADDR_L,X ; 4
|
||||
sta PATTERN_L ; 3
|
||||
lda note_a+NOTE_ADDR_H,X ; 4
|
||||
sta PATTERN_H ; 3
|
||||
|
||||
; get next value
|
||||
lda (PATTERN_L),Y ; 5
|
||||
sta note_command_smc+1 ; save termporarily ; 4
|
||||
and #$0f ; 2
|
||||
sta note_command_bottom_smc+1 ; 4
|
||||
|
||||
note_command_smc:
|
||||
lda #$d1 ; 2
|
||||
|
||||
; Set up jump table that runs same speed on 6502 and 65c02
|
||||
|
||||
sty PT3_TEMP ; 3
|
||||
|
||||
and #$f0 ; 2
|
||||
lsr ; 2
|
||||
lsr ; 2
|
||||
lsr ; 2
|
||||
|
||||
tay ; 2
|
||||
lda decode_jump_table+1,y ; 4
|
||||
pha ; 3
|
||||
lda decode_jump_table,y ; 4
|
||||
pha ; 3
|
||||
|
||||
ldy PT3_TEMP ; 3
|
||||
|
||||
rts ; 6
|
||||
;=============
|
||||
; 23
|
||||
|
||||
|
||||
decode_jump_table:
|
||||
.word decode_case_0X,decode_case_1X,decode_case_2X,decode_case_3X
|
||||
.word decode_case_4X,decode_case_5X,decode_case_6X,decode_case_7X
|
||||
.word decode_case_8X,decode_case_9X,decode_case_AX,decode_case_BX
|
||||
.word decode_case_CX,decode_case_DX,decode_case_EX,decode_case_FX
|
||||
|
||||
decode_case_0X:
|
||||
;==============================
|
||||
; $0X set special effect
|
||||
;==============================
|
||||
|
||||
note_command_bottom_smc:
|
||||
lda #$d1 ; 2
|
||||
|
||||
; we can always store spec as 0 means no spec
|
||||
|
||||
; FIXME: what if multiple spec commands?
|
||||
; Doesn't seem to happen in practice
|
||||
; But AY_emul has code to handle it
|
||||
|
||||
sta spec_command_smc+1 ; 4
|
||||
|
||||
bne decode_case_0X_not_zero ; 2/3
|
||||
;=============
|
||||
; 8
|
||||
; 00 case
|
||||
; means end of pattern
|
||||
; -1
|
||||
sta note_a+NOTE_LEN_COUNT,X ; len_count=0; ; 4
|
||||
|
||||
dec pt3_pattern_done_smc+1 ; 6
|
||||
|
||||
jmp note_done_decoding ; 3
|
||||
|
||||
|
||||
decode_case_1X:
|
||||
;==============================
|
||||
; $1X -- Set Envelope Type
|
||||
;==============================
|
||||
|
||||
lda note_command_bottom_smc+1 ; 4
|
||||
bne decode_case_not_10 ; 3
|
||||
|
||||
decode_case_10:
|
||||
; 10 case - disable ; -1
|
||||
sta note_a+NOTE_ENVELOPE_ENABLED,X ; A is 0 ; 5
|
||||
beq decode_case_1x_common ; branch always ; 3
|
||||
|
||||
decode_case_not_10:
|
||||
; -1
|
||||
jsr set_envelope ; 6+64
|
||||
|
||||
decode_case_1x_common:
|
||||
|
||||
iny ; 2
|
||||
lda (PATTERN_L),Y ; 5+
|
||||
lsr ; 2
|
||||
jsr load_sample ; 6+86
|
||||
|
||||
lda #0 ; 2
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X ; ornament_position=0 ; 5
|
||||
|
||||
decode_case_0X_not_zero:
|
||||
|
||||
jmp done_decode_loop ; 3
|
||||
|
||||
decode_case_2X:
|
||||
decode_case_3X:
|
||||
;==============================
|
||||
; $2X/$3X set noise period
|
||||
;==============================
|
||||
|
||||
lda note_command_smc+1 ; 4
|
||||
adc #$e0 ; same as subtract $20 ; 2
|
||||
sta pt3_noise_period_smc+1 ; 3
|
||||
|
||||
jmp done_decode_loop ; 3
|
||||
;===========
|
||||
; 16
|
||||
|
||||
decode_case_4X:
|
||||
;==============================
|
||||
; $4X -- set ornament
|
||||
;==============================
|
||||
|
||||
lda note_command_bottom_smc+1; set ornament to bottom nibble; 4
|
||||
jsr load_ornament ; 6+93
|
||||
|
||||
jmp done_decode_loop ; 3
|
||||
;============
|
||||
; 110
|
||||
|
||||
decode_case_5X:
|
||||
decode_case_6X:
|
||||
decode_case_7X:
|
||||
decode_case_8X:
|
||||
decode_case_9X:
|
||||
decode_case_AX:
|
||||
|
||||
;==============================
|
||||
; $5X-$AX set note
|
||||
;==============================
|
||||
|
||||
lda note_command_smc+1 ; 4
|
||||
adc #$b0 ; 2
|
||||
sta note_a+NOTE_NOTE,X ; note=(current_val-0x50); ; 5
|
||||
|
||||
jsr reset_note ; 6+69
|
||||
|
||||
lda #1 ; 2
|
||||
sta note_a+NOTE_ENABLED,X ; enabled=1 ; 5
|
||||
|
||||
|
||||
bne note_done_decoding ; 3
|
||||
|
||||
decode_case_BX:
|
||||
;============================================
|
||||
; $BX -- note length or envelope manipulation
|
||||
;============================================
|
||||
|
||||
lda note_command_bottom_smc+1 ; 4
|
||||
beq decode_case_b0 ; 3
|
||||
; -1
|
||||
sbc #1 ; envelope_type=(current_val&0xf)-1; ; 2
|
||||
bne decode_case_bx_higher ; 3
|
||||
|
||||
decode_case_b1:
|
||||
; Set Length
|
||||
|
||||
; get next byte
|
||||
iny ; 2
|
||||
lda (PATTERN_L),Y ; 5
|
||||
|
||||
sta note_a+NOTE_LEN,X ; 5
|
||||
sta note_a+NOTE_LEN_COUNT,X ; 5
|
||||
bcs done_decode_loop ; branch always ; 3
|
||||
|
||||
decode_case_b0:
|
||||
; Disable envelope
|
||||
sta note_a+NOTE_ENVELOPE_ENABLED,X ; 5
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X ; 5
|
||||
beq done_decode_loop ; 3
|
||||
|
||||
|
||||
decode_case_bx_higher:
|
||||
|
||||
jsr set_envelope ; 6+64
|
||||
|
||||
bcs done_decode_loop ; branch always ; 3
|
||||
|
||||
decode_case_CX:
|
||||
;==============================
|
||||
; $CX -- set volume
|
||||
;==============================
|
||||
|
||||
lda note_command_bottom_smc+1 ; 4
|
||||
bne decode_case_cx_not_c0 ; 3
|
||||
; -1
|
||||
decode_case_c0:
|
||||
; special case $C0 means shut down the note
|
||||
|
||||
sta note_a+NOTE_ENABLED,X ; enabled=0 ; 5
|
||||
|
||||
jsr reset_note ; 6+69
|
||||
|
||||
beq note_done_decoding ; branch always ; 3
|
||||
|
||||
decode_case_cx_not_c0:
|
||||
sta note_a+NOTE_VOLUME,X ; volume=current_val&0xf; 5
|
||||
bne done_decode_loop ; branch always ; 3
|
||||
|
||||
decode_case_DX:
|
||||
decode_case_EX:
|
||||
;==============================
|
||||
; $DX/$EX -- change sample
|
||||
;==============================
|
||||
; D0 = special case (end note)
|
||||
; D1-EF = set sample to (value - $D0)
|
||||
|
||||
lda note_command_smc+1 ; 4
|
||||
sec ; 2
|
||||
sbc #$d0 ; 2
|
||||
beq note_done_decoding ; 3
|
||||
|
||||
decode_case_not_d0:
|
||||
; -1
|
||||
|
||||
jsr load_sample ; load sample in bottom nybble ; 6+??
|
||||
|
||||
bcc done_decode_loop; branch always ; 3
|
||||
|
||||
;========================
|
||||
; d0 case means end note
|
||||
;decode_case_d0:
|
||||
; jmp note_done_decoding
|
||||
|
||||
|
||||
;==============================
|
||||
; $FX - change ornament/sample
|
||||
;==============================
|
||||
decode_case_FX:
|
||||
; disable envelope
|
||||
lda #0 ; 2
|
||||
sta note_a+NOTE_ENVELOPE_ENABLED,X ; 5
|
||||
|
||||
; Set ornament to low byte of command
|
||||
lda note_command_bottom_smc+1 ; 4
|
||||
jsr load_ornament ; ornament to load in A ; 6+?
|
||||
|
||||
; Get next byte
|
||||
iny ; point to next byte ; 2
|
||||
lda (PATTERN_L),Y ; 5
|
||||
|
||||
; Set sample to value/2
|
||||
lsr ; divide by two ; 2
|
||||
jsr load_sample ; sample to load in A ; 6+?
|
||||
|
||||
; fallthrough
|
||||
|
||||
done_decode_loop:
|
||||
|
||||
iny ; point to next byte ; 2
|
||||
|
||||
jmp note_decode_loop ; 3
|
||||
|
||||
note_done_decoding:
|
||||
|
||||
iny ; point to next byte ; 2
|
||||
|
||||
;=================================
|
||||
; handle effects
|
||||
;=================================
|
||||
; Note, the AYemul code has code to make sure these are applied
|
||||
; In the same order they appear. We don't bother?
|
||||
handle_effects:
|
||||
|
||||
spec_command_smc:
|
||||
lda #$d1 ; 2
|
||||
|
||||
;==============================
|
||||
; Effect #1 -- Tone Down
|
||||
;==============================
|
||||
effect_1:
|
||||
cmp #$1 ; 2
|
||||
bne effect_2 ; 3
|
||||
; -1
|
||||
sta note_a+NOTE_SIMPLE_GLISS,X ; 5
|
||||
lsr ; 2
|
||||
sta note_a+NOTE_ONOFF,X ; 5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as slide delay ; 5
|
||||
iny ; 2
|
||||
|
||||
sta note_a+NOTE_TONE_SLIDE_DELAY,X ; 5
|
||||
sta note_a+NOTE_TONE_SLIDE_COUNT,X ; 5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as slide step low ; 5
|
||||
iny ; 2
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_L,X ; 5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as slide step high ; 5
|
||||
iny ; 2
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_H,X ; 5
|
||||
|
||||
jmp no_effect ; 3
|
||||
|
||||
;==============================
|
||||
; Effect #2 -- Portamento
|
||||
;==============================
|
||||
effect_2:
|
||||
cmp #$2 ; 2
|
||||
beq effect_2_small ; 3
|
||||
; -1
|
||||
jmp effect_3 ; 3
|
||||
effect_2_small: ; FIXME: make smaller
|
||||
lda #0 ; 2
|
||||
sta note_a+NOTE_SIMPLE_GLISS,X ; 5
|
||||
sta note_a+NOTE_ONOFF,X ; 5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as delay ; 5
|
||||
iny ; 2
|
||||
|
||||
sta note_a+NOTE_TONE_SLIDE_DELAY,X ; 5
|
||||
sta note_a+NOTE_TONE_SLIDE_COUNT,X ; 5
|
||||
|
||||
iny ; 2
|
||||
iny ; 2
|
||||
iny ; 2
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as slide_step high ; 5
|
||||
php ; 3
|
||||
|
||||
; 16-bit absolute value
|
||||
bpl slide_step_positive1 ; 3
|
||||
;-1
|
||||
eor #$ff ; 2
|
||||
|
||||
slide_step_positive1:
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_H,X ; 5
|
||||
dey ; 2
|
||||
lda (PATTERN_L),Y ; load byte, set as slide_step low ; 5
|
||||
plp ; 4
|
||||
clc ; 2
|
||||
bpl slide_step_positive2 ; 3
|
||||
;-1
|
||||
eor #$ff ; 2
|
||||
sec ; 2
|
||||
|
||||
slide_step_positive2:
|
||||
adc #$0 ; 2
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_L,X ; 5
|
||||
bcc skip_step_inc1 ; 3
|
||||
inc note_a+NOTE_TONE_SLIDE_STEP_H,X ; 7
|
||||
skip_step_inc1:
|
||||
|
||||
|
||||
iny ; moved here as it messed with flags ; 2
|
||||
iny ; 2
|
||||
|
||||
|
||||
; a->tone_delta=GetNoteFreq(a->note,pt3)-
|
||||
; GetNoteFreq(prev_note,pt3);
|
||||
|
||||
sty PT3_TEMP ; save Y
|
||||
prev_note_smc:
|
||||
ldy #$d1
|
||||
lda NoteTable_low,Y ; GetNoteFreq
|
||||
sta temp_word_l2_smc+1
|
||||
lda NoteTable_high,Y ; GetNoteFreq
|
||||
sta temp_word_h2_smc+1
|
||||
|
||||
ldy note_a+NOTE_NOTE,X
|
||||
lda NoteTable_low,Y ; GetNoteFreq
|
||||
|
||||
sec
|
||||
temp_word_l2_smc:
|
||||
sbc #$d1
|
||||
sta note_a+NOTE_TONE_DELTA_L,X
|
||||
lda NoteTable_high,Y ; GetNoteFreq
|
||||
temp_word_h2_smc:
|
||||
sbc #$d1
|
||||
sta note_a+NOTE_TONE_DELTA_H,X
|
||||
|
||||
; a->slide_to_note=a->note;
|
||||
lda note_a+NOTE_NOTE,X
|
||||
sta note_a+NOTE_SLIDE_TO_NOTE,X
|
||||
|
||||
ldy PT3_TEMP ; restore Y
|
||||
|
||||
; a->note=prev_note;
|
||||
lda prev_note_smc+1
|
||||
sta note_a+NOTE_NOTE,X
|
||||
|
||||
; implement file version 6 and above slide behavior
|
||||
; this is done by SMC at song init time
|
||||
version_smc:
|
||||
jmp weird_version ; (JMP to BIT via smc) ; 3
|
||||
|
||||
prev_sliding_l_smc:
|
||||
lda #$d1
|
||||
sta note_a+NOTE_TONE_SLIDING_L,X
|
||||
prev_sliding_h_smc:
|
||||
lda #$d1
|
||||
sta note_a+NOTE_TONE_SLIDING_H,X
|
||||
|
||||
weird_version:
|
||||
|
||||
; annoying 16-bit subtract, only care if negative
|
||||
; if ((a->tone_delta - a->tone_sliding) < 0) {
|
||||
sec
|
||||
lda note_a+NOTE_TONE_DELTA_L,X
|
||||
sbc note_a+NOTE_TONE_SLIDING_L,X
|
||||
lda note_a+NOTE_TONE_DELTA_H,X
|
||||
sbc note_a+NOTE_TONE_SLIDING_H,X
|
||||
bpl no_effect
|
||||
|
||||
; a->tone_slide_step = -a->tone_slide_step;
|
||||
|
||||
lda note_a+NOTE_TONE_SLIDE_STEP_L,X
|
||||
eor #$ff
|
||||
clc
|
||||
adc #$1
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_L,X
|
||||
lda note_a+NOTE_TONE_SLIDE_STEP_H,X
|
||||
eor #$ff
|
||||
adc #$0
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_H,X
|
||||
|
||||
jmp no_effect
|
||||
|
||||
;==============================
|
||||
; Effect #3 -- Sample Position
|
||||
;==============================
|
||||
effect_3:
|
||||
cmp #$3
|
||||
bne effect_4
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as sample position
|
||||
iny
|
||||
sta note_a+NOTE_SAMPLE_POSITION,X
|
||||
|
||||
bne no_effect ; branch always
|
||||
|
||||
;==============================
|
||||
; Effect #4 -- Ornament Position
|
||||
;==============================
|
||||
effect_4:
|
||||
cmp #$4
|
||||
bne effect_5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as ornament position
|
||||
iny
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X
|
||||
|
||||
bne no_effect ; branch always
|
||||
|
||||
;==============================
|
||||
; Effect #5 -- Vibrato
|
||||
;==============================
|
||||
effect_5:
|
||||
cmp #$5
|
||||
bne effect_8
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as onoff delay
|
||||
iny
|
||||
sta note_a+NOTE_ONOFF_DELAY,X
|
||||
sta note_a+NOTE_ONOFF,X
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as offon delay
|
||||
iny
|
||||
sta note_a+NOTE_OFFON_DELAY,X
|
||||
|
||||
lda #0
|
||||
sta note_a+NOTE_TONE_SLIDE_COUNT,X
|
||||
sta note_a+NOTE_TONE_SLIDING_L,X
|
||||
sta note_a+NOTE_TONE_SLIDING_H,X
|
||||
|
||||
beq no_effect ; branch always
|
||||
|
||||
;==============================
|
||||
; Effect #8 -- Envelope Down
|
||||
;==============================
|
||||
effect_8:
|
||||
cmp #$8
|
||||
bne effect_9
|
||||
|
||||
; delay
|
||||
lda (PATTERN_L),Y ; load byte, set as speed
|
||||
iny
|
||||
sta pt3_envelope_delay_smc+1
|
||||
sta pt3_envelope_delay_orig_smc+1
|
||||
|
||||
; low value
|
||||
lda (PATTERN_L),Y ; load byte, set as low
|
||||
iny
|
||||
sta pt3_envelope_slide_add_l_smc+1
|
||||
|
||||
; high value
|
||||
lda (PATTERN_L),Y ; load byte, set as high
|
||||
iny
|
||||
sta pt3_envelope_slide_add_h_smc+1
|
||||
|
||||
bne no_effect ; branch always
|
||||
|
||||
;==============================
|
||||
; Effect #9 -- Set Speed
|
||||
;==============================
|
||||
effect_9:
|
||||
cmp #$9
|
||||
bne no_effect
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as speed
|
||||
iny
|
||||
sta pt3_speed_smc+1
|
||||
|
||||
no_effect:
|
||||
|
||||
;================================
|
||||
; add y into the address pointer
|
||||
|
||||
clc
|
||||
tya
|
||||
adc note_a+NOTE_ADDR_L,X
|
||||
sta note_a+NOTE_ADDR_L,X
|
||||
lda #0
|
||||
adc note_a+NOTE_ADDR_H,X
|
||||
sta note_a+NOTE_ADDR_H,X
|
||||
sta PATTERN_H
|
||||
|
||||
rts
|
||||
|
||||
|
||||
;=======================================
|
||||
; Set Envelope
|
||||
;=======================================
|
||||
; pulls out common code from $1X and $BX
|
||||
; commands
|
||||
|
||||
; A = new envelope type
|
||||
|
||||
set_envelope:
|
||||
|
||||
sta pt3_envelope_type_smc+1 ; 4
|
||||
|
||||
; give fake old to force update? maybe only needed if printing?
|
||||
; pt3->envelope_type_old=0x78;
|
||||
|
||||
lda #$78 ; 2
|
||||
sta pt3_envelope_type_old_smc+1 ; 4
|
||||
|
||||
; get next byte
|
||||
iny ; 2
|
||||
lda (PATTERN_L),Y ; 5+
|
||||
sta pt3_envelope_period_h_smc+1 ; 4
|
||||
|
||||
iny ; 2
|
||||
lda (PATTERN_L),Y ; 5+
|
||||
sta pt3_envelope_period_l_smc+1 ; 4
|
||||
|
||||
lda #1 ; 2
|
||||
sta note_a+NOTE_ENVELOPE_ENABLED,X ; envelope_enabled=1 ; 5
|
||||
lsr ; 2
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X ; ornament_position=0 ; 5
|
||||
sta pt3_envelope_delay_smc+1 ; envelope_delay=0 ; 4
|
||||
sta pt3_envelope_slide_l_smc+1 ; envelope_slide=0 ; 4
|
||||
sta pt3_envelope_slide_h_smc+1 ; 4
|
||||
|
||||
rts ; 6
|
||||
;===========
|
||||
; 64
|
||||
|
||||
;========================
|
||||
; reset note
|
||||
;========================
|
||||
; common code from the decode note code
|
||||
|
||||
reset_note:
|
||||
lda #0 ; 2
|
||||
sta note_a+NOTE_SAMPLE_POSITION,X ; sample_position=0 ; 4
|
||||
sta note_a+NOTE_AMPLITUDE_SLIDING,X ; amplitude_sliding=0 ; 4
|
||||
sta note_a+NOTE_NOISE_SLIDING,X ; noise_sliding=0 ; 4
|
||||
sta note_a+NOTE_ENVELOPE_SLIDING,X ; envelope_sliding=0 ; 4
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X ; ornament_position=0 ; 4
|
||||
sta note_a+NOTE_TONE_SLIDE_COUNT,X ; tone_slide_count=0 ; 4
|
||||
sta note_a+NOTE_TONE_SLIDING_L,X ; tone_sliding=0 ; 4
|
||||
sta note_a+NOTE_TONE_SLIDING_H,X ; 4
|
||||
sta note_a+NOTE_TONE_ACCUMULATOR_L,X ; tone_accumulator=0 ; 4
|
||||
sta note_a+NOTE_TONE_ACCUMULATOR_H,X ; 4
|
||||
sta note_a+NOTE_ONOFF,X ; onoff=0; ; 4
|
||||
|
||||
rts ; 6
|
||||
;============
|
||||
; 52
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.include "pt3_lib_decode_note.s"
|
||||
|
||||
;=====================================
|
||||
; Set Pattern
|
||||
|
679
interlace_demo/pt3_lib_decode_note.s
Normal file
679
interlace_demo/pt3_lib_decode_note.s
Normal file
@ -0,0 +1,679 @@
|
||||
;========================================================================
|
||||
; EVERYTHING IS CYCLE COUNTED
|
||||
;========================================================================
|
||||
|
||||
;=====================================
|
||||
; Decode Note
|
||||
;=====================================
|
||||
; X points to the note offset
|
||||
|
||||
; Note! These timings are out of date (FIXME)
|
||||
; Timings (from ===>)
|
||||
; 00: 14+30
|
||||
; 0X: 14+15
|
||||
; 10: 14+5 +124
|
||||
; 1X: 14+5 +193
|
||||
; 2X/3X: 14+5 +17
|
||||
; 4X: 14+5+5 + 111
|
||||
; 5X-BX: 14+5+5+ 102
|
||||
; CX:
|
||||
; DX/EX:
|
||||
; FX:
|
||||
|
||||
stop_decoding:
|
||||
|
||||
; we are still running, decrement and early return
|
||||
dec note_a+NOTE_LEN_COUNT,X ; 7
|
||||
rts ; 6
|
||||
|
||||
;=====================================
|
||||
; Decode Line
|
||||
;=====================================
|
||||
|
||||
pt3_decode_line:
|
||||
; decode_note(&pt3->a,&(pt3->a_addr),pt3);
|
||||
ldx #(NOTE_STRUCT_SIZE*0) ; 2
|
||||
jsr decode_note ; 6+??
|
||||
|
||||
; decode_note(&pt3->b,&(pt3->b_addr),pt3);
|
||||
ldx #(NOTE_STRUCT_SIZE*1) ; 2
|
||||
jsr decode_note ; 6+??
|
||||
|
||||
; decode_note(&pt3->c,&(pt3->c_addr),pt3);
|
||||
ldx #(NOTE_STRUCT_SIZE*2) ; 2
|
||||
;;jsr decode_note ; fall through
|
||||
|
||||
; if (pt3->a.all_done && pt3->b.all_done && pt3->c.all_done) {
|
||||
; return 1;
|
||||
; }
|
||||
|
||||
|
||||
;=================================
|
||||
;=================================
|
||||
; decode note
|
||||
;=================================
|
||||
;=================================
|
||||
|
||||
decode_note:
|
||||
|
||||
; Init vars
|
||||
|
||||
ldy #0 ; 2
|
||||
sty spec_command_smc+1 ; 4
|
||||
|
||||
; Skip decode if note still running
|
||||
lda note_a+NOTE_LEN_COUNT,X ; 4
|
||||
cmp #2 ; 2
|
||||
bcs stop_decoding ; blt, assume not negative ; 3
|
||||
; -1
|
||||
|
||||
keep_decoding:
|
||||
|
||||
lda note_a+NOTE_NOTE,X ; store prev note ; 4
|
||||
sta prev_note_smc+1 ; 4
|
||||
|
||||
lda note_a+NOTE_TONE_SLIDING_H,X ; store prev sliding ; 4
|
||||
sta prev_sliding_h_smc+1 ; 4
|
||||
lda note_a+NOTE_TONE_SLIDING_L,X ; 4
|
||||
sta prev_sliding_l_smc+1 ; 4
|
||||
|
||||
|
||||
note_decode_loop:
|
||||
lda note_a+NOTE_LEN,X ; re-up length count ; 4
|
||||
sta note_a+NOTE_LEN_COUNT,X ; 4
|
||||
|
||||
lda note_a+NOTE_ADDR_L,X ; 4
|
||||
sta PATTERN_L ; 3
|
||||
lda note_a+NOTE_ADDR_H,X ; 4
|
||||
sta PATTERN_H ; 3
|
||||
|
||||
; get next value
|
||||
lda (PATTERN_L),Y ; 5
|
||||
sta note_command_smc+1 ; save termporarily ; 4
|
||||
and #$0f ; 2
|
||||
sta note_command_bottom_smc+1 ; 4
|
||||
|
||||
note_command_smc:
|
||||
lda #$d1 ; 2
|
||||
|
||||
; Set up jump table that runs same speed on 6502 and 65c02
|
||||
|
||||
sty PT3_TEMP ; 3
|
||||
|
||||
and #$f0 ; 2
|
||||
lsr ; 2
|
||||
lsr ; 2
|
||||
lsr ; 2
|
||||
|
||||
tay ; 2
|
||||
lda decode_jump_table+1,y ; 4
|
||||
pha ; 3
|
||||
lda decode_jump_table,y ; 4
|
||||
pha ; 3
|
||||
|
||||
ldy PT3_TEMP ; 3
|
||||
|
||||
rts ; 6
|
||||
;=============
|
||||
; 23
|
||||
|
||||
|
||||
decode_jump_table:
|
||||
.word decode_case_0X,decode_case_1X,decode_case_2X,decode_case_3X
|
||||
.word decode_case_4X,decode_case_5X,decode_case_6X,decode_case_7X
|
||||
.word decode_case_8X,decode_case_9X,decode_case_AX,decode_case_BX
|
||||
.word decode_case_CX,decode_case_DX,decode_case_EX,decode_case_FX
|
||||
|
||||
decode_case_0X:
|
||||
;==============================
|
||||
; $0X set special effect
|
||||
;==============================
|
||||
|
||||
note_command_bottom_smc:
|
||||
lda #$d1 ; 2
|
||||
|
||||
; we can always store spec as 0 means no spec
|
||||
|
||||
; FIXME: what if multiple spec commands?
|
||||
; Doesn't seem to happen in practice
|
||||
; But AY_emul has code to handle it
|
||||
|
||||
sta spec_command_smc+1 ; 4
|
||||
|
||||
bne decode_case_0X_not_zero ; 2/3
|
||||
;=============
|
||||
; 8
|
||||
; 00 case
|
||||
; means end of pattern
|
||||
; -1
|
||||
sta note_a+NOTE_LEN_COUNT,X ; len_count=0; ; 4
|
||||
|
||||
dec pt3_pattern_done_smc+1 ; 6
|
||||
|
||||
jmp note_done_decoding ; 3
|
||||
|
||||
|
||||
decode_case_1X:
|
||||
;==============================
|
||||
; $1X -- Set Envelope Type
|
||||
;==============================
|
||||
|
||||
lda note_command_bottom_smc+1 ; 4
|
||||
bne decode_case_not_10 ; 3
|
||||
|
||||
decode_case_10:
|
||||
; 10 case - disable ; -1
|
||||
sta note_a+NOTE_ENVELOPE_ENABLED,X ; A is 0 ; 5
|
||||
beq decode_case_1x_common ; branch always ; 3
|
||||
|
||||
decode_case_not_10:
|
||||
; -1
|
||||
jsr set_envelope ; 6+64
|
||||
|
||||
decode_case_1x_common:
|
||||
|
||||
iny ; 2
|
||||
lda (PATTERN_L),Y ; 5+
|
||||
lsr ; 2
|
||||
jsr load_sample ; 6+86
|
||||
|
||||
lda #0 ; 2
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X ; ornament_position=0 ; 5
|
||||
|
||||
decode_case_0X_not_zero:
|
||||
|
||||
jmp done_decode_loop ; 3
|
||||
|
||||
decode_case_2X:
|
||||
decode_case_3X:
|
||||
;==============================
|
||||
; $2X/$3X set noise period
|
||||
;==============================
|
||||
|
||||
lda note_command_smc+1 ; 4
|
||||
adc #$e0 ; same as subtract $20 ; 2
|
||||
sta pt3_noise_period_smc+1 ; 3
|
||||
|
||||
jmp done_decode_loop ; 3
|
||||
;===========
|
||||
; 16
|
||||
|
||||
decode_case_4X:
|
||||
;==============================
|
||||
; $4X -- set ornament
|
||||
;==============================
|
||||
|
||||
lda note_command_bottom_smc+1; set ornament to bottom nibble; 4
|
||||
jsr load_ornament ; 6+93
|
||||
|
||||
jmp done_decode_loop ; 3
|
||||
;============
|
||||
; 110
|
||||
|
||||
decode_case_5X:
|
||||
decode_case_6X:
|
||||
decode_case_7X:
|
||||
decode_case_8X:
|
||||
decode_case_9X:
|
||||
decode_case_AX:
|
||||
|
||||
;==============================
|
||||
; $5X-$AX set note
|
||||
;==============================
|
||||
|
||||
lda note_command_smc+1 ; 4
|
||||
adc #$b0 ; 2
|
||||
sta note_a+NOTE_NOTE,X ; note=(current_val-0x50); ; 5
|
||||
|
||||
jsr reset_note ; 6+69
|
||||
|
||||
lda #1 ; 2
|
||||
sta note_a+NOTE_ENABLED,X ; enabled=1 ; 5
|
||||
|
||||
|
||||
bne note_done_decoding ; 3
|
||||
|
||||
decode_case_BX:
|
||||
;============================================
|
||||
; $BX -- note length or envelope manipulation
|
||||
;============================================
|
||||
|
||||
lda note_command_bottom_smc+1 ; 4
|
||||
beq decode_case_b0 ; 3
|
||||
; -1
|
||||
sbc #1 ; envelope_type=(current_val&0xf)-1; ; 2
|
||||
bne decode_case_bx_higher ; 3
|
||||
|
||||
decode_case_b1:
|
||||
; Set Length
|
||||
|
||||
; get next byte
|
||||
iny ; 2
|
||||
lda (PATTERN_L),Y ; 5
|
||||
|
||||
sta note_a+NOTE_LEN,X ; 5
|
||||
sta note_a+NOTE_LEN_COUNT,X ; 5
|
||||
bcs done_decode_loop ; branch always ; 3
|
||||
|
||||
decode_case_b0:
|
||||
; Disable envelope
|
||||
sta note_a+NOTE_ENVELOPE_ENABLED,X ; 5
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X ; 5
|
||||
beq done_decode_loop ; 3
|
||||
|
||||
|
||||
decode_case_bx_higher:
|
||||
|
||||
jsr set_envelope ; 6+64
|
||||
|
||||
bcs done_decode_loop ; branch always ; 3
|
||||
|
||||
decode_case_CX:
|
||||
;==============================
|
||||
; $CX -- set volume
|
||||
;==============================
|
||||
|
||||
lda note_command_bottom_smc+1 ; 4
|
||||
bne decode_case_cx_not_c0 ; 3
|
||||
; -1
|
||||
decode_case_c0:
|
||||
; special case $C0 means shut down the note
|
||||
|
||||
sta note_a+NOTE_ENABLED,X ; enabled=0 ; 5
|
||||
|
||||
jsr reset_note ; 6+69
|
||||
|
||||
beq note_done_decoding ; branch always ; 3
|
||||
|
||||
decode_case_cx_not_c0:
|
||||
sta note_a+NOTE_VOLUME,X ; volume=current_val&0xf; 5
|
||||
bne done_decode_loop ; branch always ; 3
|
||||
|
||||
decode_case_DX:
|
||||
decode_case_EX:
|
||||
;==============================
|
||||
; $DX/$EX -- change sample
|
||||
;==============================
|
||||
; D0 = special case (end note)
|
||||
; D1-EF = set sample to (value - $D0)
|
||||
|
||||
lda note_command_smc+1 ; 4
|
||||
sec ; 2
|
||||
sbc #$d0 ; 2
|
||||
beq note_done_decoding ; 3
|
||||
|
||||
decode_case_not_d0:
|
||||
; -1
|
||||
|
||||
jsr load_sample ; load sample in bottom nybble ; 6+??
|
||||
|
||||
bcc done_decode_loop; branch always ; 3
|
||||
|
||||
;========================
|
||||
; d0 case means end note
|
||||
;decode_case_d0:
|
||||
; jmp note_done_decoding
|
||||
|
||||
|
||||
;==============================
|
||||
; $FX - change ornament/sample
|
||||
;==============================
|
||||
decode_case_FX:
|
||||
; disable envelope
|
||||
lda #0 ; 2
|
||||
sta note_a+NOTE_ENVELOPE_ENABLED,X ; 5
|
||||
|
||||
; Set ornament to low byte of command
|
||||
lda note_command_bottom_smc+1 ; 4
|
||||
jsr load_ornament ; ornament to load in A ; 6+?
|
||||
|
||||
; Get next byte
|
||||
iny ; point to next byte ; 2
|
||||
lda (PATTERN_L),Y ; 5
|
||||
|
||||
; Set sample to value/2
|
||||
lsr ; divide by two ; 2
|
||||
jsr load_sample ; sample to load in A ; 6+?
|
||||
|
||||
; fallthrough
|
||||
|
||||
done_decode_loop:
|
||||
|
||||
iny ; point to next byte ; 2
|
||||
|
||||
jmp note_decode_loop ; 3
|
||||
|
||||
note_done_decoding:
|
||||
|
||||
iny ; point to next byte ; 2
|
||||
|
||||
;=================================
|
||||
; handle effects
|
||||
;=================================
|
||||
; Note, the AYemul code has code to make sure these are applied
|
||||
; In the same order they appear. We don't bother?
|
||||
handle_effects:
|
||||
|
||||
spec_command_smc:
|
||||
lda #$d1 ; 2
|
||||
|
||||
;==============================
|
||||
; Effect #1 -- Tone Down
|
||||
;==============================
|
||||
effect_1:
|
||||
cmp #$1 ; 2
|
||||
bne effect_2 ; 3
|
||||
; -1
|
||||
sta note_a+NOTE_SIMPLE_GLISS,X ; 5
|
||||
lsr ; 2
|
||||
sta note_a+NOTE_ONOFF,X ; 5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as slide delay ; 5
|
||||
iny ; 2
|
||||
|
||||
sta note_a+NOTE_TONE_SLIDE_DELAY,X ; 5
|
||||
sta note_a+NOTE_TONE_SLIDE_COUNT,X ; 5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as slide step low ; 5
|
||||
iny ; 2
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_L,X ; 5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as slide step high ; 5
|
||||
iny ; 2
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_H,X ; 5
|
||||
|
||||
jmp no_effect ; 3
|
||||
|
||||
;==============================
|
||||
; Effect #2 -- Portamento
|
||||
;==============================
|
||||
effect_2:
|
||||
cmp #$2 ; 2
|
||||
beq effect_2_small ; 3
|
||||
; -1
|
||||
jmp effect_3 ; 3
|
||||
effect_2_small: ; FIXME: make smaller
|
||||
lda #0 ; 2
|
||||
sta note_a+NOTE_SIMPLE_GLISS,X ; 5
|
||||
sta note_a+NOTE_ONOFF,X ; 5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as delay ; 5
|
||||
iny ; 2
|
||||
|
||||
sta note_a+NOTE_TONE_SLIDE_DELAY,X ; 5
|
||||
sta note_a+NOTE_TONE_SLIDE_COUNT,X ; 5
|
||||
|
||||
iny ; 2
|
||||
iny ; 2
|
||||
iny ; 2
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as slide_step high ; 5
|
||||
php ; 3
|
||||
|
||||
; 16-bit absolute value
|
||||
bpl slide_step_positive1 ; 3
|
||||
;-1
|
||||
eor #$ff ; 2
|
||||
|
||||
slide_step_positive1:
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_H,X ; 5
|
||||
dey ; 2
|
||||
lda (PATTERN_L),Y ; load byte, set as slide_step low ; 5
|
||||
plp ; 4
|
||||
clc ; 2
|
||||
bpl slide_step_positive2 ; 3
|
||||
;-1
|
||||
eor #$ff ; 2
|
||||
sec ; 2
|
||||
|
||||
slide_step_positive2:
|
||||
adc #$0 ; 2
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_L,X ; 5
|
||||
bcc skip_step_inc1 ; 3
|
||||
inc note_a+NOTE_TONE_SLIDE_STEP_H,X ; 7
|
||||
skip_step_inc1:
|
||||
|
||||
|
||||
iny ; moved here as it messed with flags ; 2
|
||||
iny ; 2
|
||||
|
||||
|
||||
; a->tone_delta=GetNoteFreq(a->note,pt3)-
|
||||
; GetNoteFreq(prev_note,pt3);
|
||||
|
||||
sty PT3_TEMP ; save Y
|
||||
prev_note_smc:
|
||||
ldy #$d1
|
||||
lda NoteTable_low,Y ; GetNoteFreq
|
||||
sta temp_word_l2_smc+1
|
||||
lda NoteTable_high,Y ; GetNoteFreq
|
||||
sta temp_word_h2_smc+1
|
||||
|
||||
ldy note_a+NOTE_NOTE,X
|
||||
lda NoteTable_low,Y ; GetNoteFreq
|
||||
|
||||
sec
|
||||
temp_word_l2_smc:
|
||||
sbc #$d1
|
||||
sta note_a+NOTE_TONE_DELTA_L,X
|
||||
lda NoteTable_high,Y ; GetNoteFreq
|
||||
temp_word_h2_smc:
|
||||
sbc #$d1
|
||||
sta note_a+NOTE_TONE_DELTA_H,X
|
||||
|
||||
; a->slide_to_note=a->note;
|
||||
lda note_a+NOTE_NOTE,X
|
||||
sta note_a+NOTE_SLIDE_TO_NOTE,X
|
||||
|
||||
ldy PT3_TEMP ; restore Y
|
||||
|
||||
; a->note=prev_note;
|
||||
lda prev_note_smc+1
|
||||
sta note_a+NOTE_NOTE,X
|
||||
|
||||
; implement file version 6 and above slide behavior
|
||||
; this is done by SMC at song init time
|
||||
version_smc:
|
||||
jmp weird_version ; (JMP to BIT via smc) ; 3
|
||||
|
||||
prev_sliding_l_smc:
|
||||
lda #$d1
|
||||
sta note_a+NOTE_TONE_SLIDING_L,X
|
||||
prev_sliding_h_smc:
|
||||
lda #$d1
|
||||
sta note_a+NOTE_TONE_SLIDING_H,X
|
||||
|
||||
weird_version:
|
||||
|
||||
; annoying 16-bit subtract, only care if negative
|
||||
; if ((a->tone_delta - a->tone_sliding) < 0) {
|
||||
sec
|
||||
lda note_a+NOTE_TONE_DELTA_L,X
|
||||
sbc note_a+NOTE_TONE_SLIDING_L,X
|
||||
lda note_a+NOTE_TONE_DELTA_H,X
|
||||
sbc note_a+NOTE_TONE_SLIDING_H,X
|
||||
bpl no_effect
|
||||
|
||||
; a->tone_slide_step = -a->tone_slide_step;
|
||||
|
||||
lda note_a+NOTE_TONE_SLIDE_STEP_L,X
|
||||
eor #$ff
|
||||
clc
|
||||
adc #$1
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_L,X
|
||||
lda note_a+NOTE_TONE_SLIDE_STEP_H,X
|
||||
eor #$ff
|
||||
adc #$0
|
||||
sta note_a+NOTE_TONE_SLIDE_STEP_H,X
|
||||
|
||||
jmp no_effect
|
||||
|
||||
;==============================
|
||||
; Effect #3 -- Sample Position
|
||||
;==============================
|
||||
effect_3:
|
||||
cmp #$3
|
||||
bne effect_4
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as sample position
|
||||
iny
|
||||
sta note_a+NOTE_SAMPLE_POSITION,X
|
||||
|
||||
bne no_effect ; branch always
|
||||
|
||||
;==============================
|
||||
; Effect #4 -- Ornament Position
|
||||
;==============================
|
||||
effect_4:
|
||||
cmp #$4
|
||||
bne effect_5
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as ornament position
|
||||
iny
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X
|
||||
|
||||
bne no_effect ; branch always
|
||||
|
||||
;==============================
|
||||
; Effect #5 -- Vibrato
|
||||
;==============================
|
||||
effect_5:
|
||||
cmp #$5
|
||||
bne effect_8
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as onoff delay
|
||||
iny
|
||||
sta note_a+NOTE_ONOFF_DELAY,X
|
||||
sta note_a+NOTE_ONOFF,X
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as offon delay
|
||||
iny
|
||||
sta note_a+NOTE_OFFON_DELAY,X
|
||||
|
||||
lda #0
|
||||
sta note_a+NOTE_TONE_SLIDE_COUNT,X
|
||||
sta note_a+NOTE_TONE_SLIDING_L,X
|
||||
sta note_a+NOTE_TONE_SLIDING_H,X
|
||||
|
||||
beq no_effect ; branch always
|
||||
|
||||
;==============================
|
||||
; Effect #8 -- Envelope Down
|
||||
;==============================
|
||||
effect_8:
|
||||
cmp #$8
|
||||
bne effect_9
|
||||
|
||||
; delay
|
||||
lda (PATTERN_L),Y ; load byte, set as speed
|
||||
iny
|
||||
sta pt3_envelope_delay_smc+1
|
||||
sta pt3_envelope_delay_orig_smc+1
|
||||
|
||||
; low value
|
||||
lda (PATTERN_L),Y ; load byte, set as low
|
||||
iny
|
||||
sta pt3_envelope_slide_add_l_smc+1
|
||||
|
||||
; high value
|
||||
lda (PATTERN_L),Y ; load byte, set as high
|
||||
iny
|
||||
sta pt3_envelope_slide_add_h_smc+1
|
||||
|
||||
bne no_effect ; branch always
|
||||
|
||||
;==============================
|
||||
; Effect #9 -- Set Speed
|
||||
;==============================
|
||||
effect_9:
|
||||
cmp #$9
|
||||
bne no_effect
|
||||
|
||||
lda (PATTERN_L),Y ; load byte, set as speed
|
||||
iny
|
||||
sta pt3_speed_smc+1
|
||||
|
||||
no_effect:
|
||||
|
||||
;================================
|
||||
; add y into the address pointer
|
||||
|
||||
clc
|
||||
tya
|
||||
adc note_a+NOTE_ADDR_L,X
|
||||
sta note_a+NOTE_ADDR_L,X
|
||||
lda #0
|
||||
adc note_a+NOTE_ADDR_H,X
|
||||
sta note_a+NOTE_ADDR_H,X
|
||||
sta PATTERN_H
|
||||
|
||||
rts
|
||||
|
||||
|
||||
;=======================================
|
||||
; Set Envelope
|
||||
;=======================================
|
||||
; pulls out common code from $1X and $BX
|
||||
; commands
|
||||
|
||||
; A = new envelope type
|
||||
|
||||
set_envelope:
|
||||
|
||||
sta pt3_envelope_type_smc+1 ; 4
|
||||
|
||||
; give fake old to force update? maybe only needed if printing?
|
||||
; pt3->envelope_type_old=0x78;
|
||||
|
||||
lda #$78 ; 2
|
||||
sta pt3_envelope_type_old_smc+1 ; 4
|
||||
|
||||
; get next byte
|
||||
iny ; 2
|
||||
lda (PATTERN_L),Y ; 5+
|
||||
sta pt3_envelope_period_h_smc+1 ; 4
|
||||
|
||||
iny ; 2
|
||||
lda (PATTERN_L),Y ; 5+
|
||||
sta pt3_envelope_period_l_smc+1 ; 4
|
||||
|
||||
lda #1 ; 2
|
||||
sta note_a+NOTE_ENVELOPE_ENABLED,X ; envelope_enabled=1 ; 5
|
||||
lsr ; 2
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X ; ornament_position=0 ; 5
|
||||
sta pt3_envelope_delay_smc+1 ; envelope_delay=0 ; 4
|
||||
sta pt3_envelope_slide_l_smc+1 ; envelope_slide=0 ; 4
|
||||
sta pt3_envelope_slide_h_smc+1 ; 4
|
||||
|
||||
rts ; 6
|
||||
;===========
|
||||
; 64
|
||||
|
||||
;========================
|
||||
; reset note
|
||||
;========================
|
||||
; common code from the decode note code
|
||||
|
||||
reset_note:
|
||||
lda #0 ; 2
|
||||
sta note_a+NOTE_SAMPLE_POSITION,X ; sample_position=0 ; 4
|
||||
sta note_a+NOTE_AMPLITUDE_SLIDING,X ; amplitude_sliding=0 ; 4
|
||||
sta note_a+NOTE_NOISE_SLIDING,X ; noise_sliding=0 ; 4
|
||||
sta note_a+NOTE_ENVELOPE_SLIDING,X ; envelope_sliding=0 ; 4
|
||||
sta note_a+NOTE_ORNAMENT_POSITION,X ; ornament_position=0 ; 4
|
||||
sta note_a+NOTE_TONE_SLIDE_COUNT,X ; tone_slide_count=0 ; 4
|
||||
sta note_a+NOTE_TONE_SLIDING_L,X ; tone_sliding=0 ; 4
|
||||
sta note_a+NOTE_TONE_SLIDING_H,X ; 4
|
||||
sta note_a+NOTE_TONE_ACCUMULATOR_L,X ; tone_accumulator=0 ; 4
|
||||
sta note_a+NOTE_TONE_ACCUMULATOR_H,X ; 4
|
||||
sta note_a+NOTE_ONOFF,X ; onoff=0; ; 4
|
||||
|
||||
rts ; 6
|
||||
;============
|
||||
; 52
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user