include "banks.asm"
include "defs.asm"
include "macros.asm"
include "notes.asm"
include "notes_unison.asm"
include "samplegen.asm"
include "smc.asm"

CHANNEL_A_MUTE = 0
CHANNEL_B_MUTE = 0
CHANNEL_C_MUTE = 0
CHANNEL_D_MUTE = 0

; ============================================

; IMPORTANT!
;
; Since RRA is used to reduce the volume of
; bass unison samples, any bass unison samples
; used should not go above half volume. Otherwise
; they will carry and this will introduce clicking.

; ============================================
; calculating song speed:
;
; main loop runs at 331 T-states per sample
;
; CPU is clocked at 3546900 MHz (Spectrum 128)
;
; so samples per minute
; = (60 * 3546900 / 331) ~= 642942.60
;
; sample buffer consists of 60 samples
; so buffers per minute
; = (3546900 / 331) ~= 10715.71
;
; a song at 60bpm will therefore require
; = (3546900 / 331 / 60) ~= 178.60 buffers per beat
;
; FORMULA:
; buffers per beat = (3546900 / 331 / bpm)
;
; buffers per division = (3546900 / 331 / bpm / divisions_per_beat)
;
; a song at 119.657bpm with 16th divisions (or 4 divisions per beat):
;
; 3546900 / 331 / 119.657 / 4 = 22.3884 buffers per division
;
; where:
; 22 corresponds to 121.769bpm
; 23 corresponds to 116.475bpm
;
; so choose 22.

; ============================================

zoStrictSyntax = true

Zeus_PC equ entry
Zeus_IE equ false

; ============================================

; On a 128K machine the memory paging port is:
;
; 0--- ---- ---- --0-
;
; If we set bit 14 to 1, we will incur I/O contention
; delays since the high byte is in the $4000-$7fff
; range. Therefore the port we will use for paging is:
;
; 0011 1111 1111 1101
;
; which is $3ffd in hex.
;
; On a +2A/+3 machine however, the memory paging
; port is:
;
; 01-- ---- ---- --0-
;
; so we are forced to use port $7ffd on the Amstrad
; models. However, sources claim that the Amstrad
; machines do not suffer from I/O contention delays,
; so using this port should not be a problem.
;
; If paging is used, the song/instrument data and
; other essential data should be kept in bank 2 so
; they don't get paged out, unless we add some
; mechanism to avoid this.

; ============================================

; I misread the documents about I/O contention.
; Apparently, I/O contention is applied if at
; least one of the following hold:
;
; The low bit of the port is reset (e.g. a ULA
; access. This does not apply here unless we
; decide to use the beeper.)
;
; The high byte of the port is in the range
; $40 to $7f. This does not apply here if we
; can avoid it. However, the paging port has
; a high byte of $7f.
;
; The high byte of the port is in the range
; $c0 to $ff *and* a contention memory bank
; is paged in. This could potentially affect
; us, but since we ideally do not page in
; contended memory banks, we should be safe
; from this as well.
;
; Therefore, the only way we should be
; affected by I/O contention is if we use
; the beeper (unlikely) or memory paging
; (more likely, but does not occur often).
;
; Additionally, I/O contention should not
; occur on a +2A/+3 Spectrum. (?)
;
; The contention effects that were being
; measured were more likely due to screen
; accesses when drawing the waveform, but
; this should be confirmed.

; ============================================

BEGIN_BANK(5)

; ============================================

zeusassert ($ & $ff) = 0
mod_waveform_data:

sawtooth_waveform_mod_data:
    import_bin "../bin/mod/AKWF_theremin_0008.0.raw"

waveform_data:

bass_waveform_data:
    import_bin "../bin/waves/AKWF_ebass_0001.f.raw"
theremin_waveform_data:
    import_bin "../bin/waves/AKWF_theremin_0008.f.raw"
epiano_waveform_1_data:
    import_bin "../bin/waves/AKWF_epiano_0002.1.raw"
epiano_waveform_3_data:
    import_bin "../bin/waves/AKWF_epiano_0002.3.raw"
epiano_waveform_5_data:
    import_bin "../bin/waves/AKWF_epiano_0002.5.raw"
epiano_waveform_7_data:
    import_bin "../bin/waves/AKWF_epiano_0002.7.raw"
epiano_waveform_9_data:
    import_bin "../bin/waves/AKWF_epiano_0002.9.raw"
epiano_waveform_b_data:
    import_bin "../bin/waves/AKWF_epiano_0002.b.raw"
epiano_waveform_d_data:
    import_bin "../bin/waves/AKWF_epiano_0002.d.raw"
epiano_waveform_f_data:
    import_bin "../bin/waves/AKWF_epiano_0002.f.raw"
waveform_data_end:

; ============================================

entry:

    ; copy bank 0 datablock to correct location
    ld hl, bank_start_5_fin+bank_size_5_fin+bank_size_2_fin+bank_size_0_fin-1
    ld de, bank_start_0_fin+bank_size_0_fin-1
    ld bc, bank_size_0_fin
    lddr

    ; copy bank 2 datablock to correct location
    ld hl, bank_start_5_fin+bank_size_5_fin+bank_size_2_fin-1
    ld de, bank_start_2_fin+bank_size_2_fin-1
    ld bc, bank_size_2_fin
    lddr

    ; black border
    xor a
    out ($fe), a

determine_machine_type:

    ; the 'official' paging port
    ld bc, $7ffd

    ; address to check
    ld hl, $c000
    push hl

    ; page in bank 0
    xor a
    out (c), a

    ; save bank 0 byte
    ld d, (hl)
    ; place marker
    ld (hl), a

    ; page in bank 1
    inc a
    out (c), a

    ; save bank 1 byte
    ld e, (hl)
    ; place marker
    ld (hl), a

    ; the paging port $3ffd, which only works
    ; on a 128K machine
    ld b, $3f

    ; try to page in bank 0
    xor a
    out (c), a

    ; check whether that worked
    ; (if it did, we are using a 128K machine)
    ld a, (hl)
    or a

    ; an enum for the machine type
    ld a, MACHINE_TYPE_SINCLAIR

    ; a copy of the functioning paging port
    ld h, b
    ld l, c

    ; jump if the page worked (it's a Sinclair machine)
    jr z, determine_machine_type_continue

    ; the page didn't work (it's an Amstrad machine)
    ; ld a, MACHINE_TYPE_AMSTRAD
    inc a

    ; we have to use the official paging port
    ld h, $7f

determine_machine_type_continue:

    ld (machine_type), a
    ld (paging_port), hl

    ; pop $c000
    pop hl

    ; put things back to normal
    ld b, $7f

    ; put page 1 byte back
    ld a, 1
    out (c), a
    ld (hl), e

    ; put page 0 byte back
    ld a, $10   ; select ROM
    out (c), a
    ld (hl), d

    ; bank 0 is now paged in

    ; decode waveform data
    ld b, a
    ld hl, sawtooth_waveform_mod_data
    ld de, sawtooth_waveform_mod
    call decode_dpcm

    ; number of waveforms to decode (each is 128 bytes)
    ld b, (waveform_data_end - waveform_data) / $80
decode_waveform_loop:
        push bc

        ; DC offset
        ld b, $20

        ; next waveform
        inc hl
        inc d

        ; decode it
        call decode_dpcm

        pop bc

    djnz decode_waveform_loop

    ld hl, callback
    ld (callback_target), hl

    ld a, $32
    ld (select_index), a

    xor a
    ld (chip_type), a
    ld (chip_stereo), a
    ld (output_stereo), a

    ld a, $08
    ld (chan_l), a

    ld a, $0a
    ld (chan_r), a

    ld hl, $bfdf
    ld (dac_port), hl

    call reset_song

    ld hl, $4826
    ld bc, str_chip_select  ; $32
    call print_string

    ld hl, $4853
    ld bc, str_mono         ; $52
    call print_string

    ld hl, $4869
    ld bc, str_dac_port     ; $72
    call print_string

    ld hl, $48ab
    ld bc, str_output       ; $b2
    call print_string

    ld hl, $5068
    ld bc, str_keys
    call print_string

    ld hl, $5081
    ld bc, str_keys2
    call print_string

    ld hl, $50c1
    ld bc, str_note
    call print_string

    ld hl, $50e4
    ld bc, str_zx0
    call print_string

    ld a, 6
    ld hl, $5932
    call print_selection

    ld a, OUTPUT_AY_MONO
    call SampleOut_setup

    ; reading starts from buf0
    ld hl, buf0

    ld iy, empty_sample_def

    ld d, HIGH vol_table_ay

    jp mainloop

; ============================================

    ;  A = attr
    ; HL = attr address
print_selection:
    ld b, 12

print_selection_loop:
    ld (hl), a
    inc l

    djnz print_selection_loop

    ret

; ============================================

    ; BC = zero-terminated string
    ; HL = screen address
print_string:

    ; get character
    ld a, (bc)

    ; return if done
    or a
    ret z

    ; next character
    inc bc

    ; multiply by 8
    rlca
    rlca
    rlca

    ; calculate font address
    ld d, a
    and $f8
    ld e, a
    xor d
    add a, $3c
    ld d, a

    ; print character
    push hl
    push bc

    ld b, 8
print_string_loop:
    ld a, (de)
    ld (hl), a
    inc e
    inc h

    djnz print_string_loop

    pop bc
    pop hl

    inc l

    jr print_string

; ============================================

reset_song:

    ld hl, buf1
    ld (write_buffer_offset), hl

    ld a, SONG_START-5
    ld (pattern_pos), a

    ld a, SONG_SPEED
    ld (song_speed0), a
    ld (song_speed1), a
    ld (song_speed2), a
    ld (song_speed3), a
    ld (song_speed4), a
    ld (song_speed5), a

    ld a, 60
    ld (write_buffer_add), a

    ; ensure notes don't play at the start
    xor a
    ld (ch_a_note_timer), a
    ld (ch_b_note_timer), a
    ld (ch_c_note_timer), a
    ld (ch_d_note_timer), a
    ld (event_timer), a

    ld (ch_a_note_value), a
    ld (ch_b_note_value), a
    ld (ch_c_note_value), a

    ld (ch_a_ins_timer), a
    ld (ch_b_ins_timer), a
    ld (ch_c_ins_timer), a

    ld (ch_b_osc_sync_pos), a

    ld (ch_a_orn_initial), a
    ld (ch_b_orn_initial), a
    ld (ch_b_orn_initial2), a
    ld (ch_c_orn_initial), a

    ld h, a
    ld l, a
    ld (ch_a_note), hl
    ld (ch_b_note), hl
    ld (ch_c_note), hl
    ld (ch_a_pos), hl
    ld (ch_b_pos), hl
    ld (ch_c_pos), hl
    ld (ch_b_osc_sync_pitch), hl
    ld (ch_b_osc_sync_bend), hl
    ld (ch_a_bend), hl
    ld (ch_b_bend), hl
    ld (ch_c_bend), hl
    ld (ch_a_bend_accum), hl
    ld (ch_b_bend_accum), hl
    ld (ch_b_bend_accum2), hl
    ld (ch_c_bend_accum), hl

    inc a
    ld (song_timer), a
    ld (pattern_timer), a
    ld (sample_counter), a

    ld a, $dd               ; IX prefix
    ld (ch_a_pos_prefix), a

    ld hl, channel_a_bass_fm
    ld (channel_a_samplegen), hl

    ld hl, channel_b_fm_setup
    ld (channel_b_samplegen), hl

    ld hl, empty_instrument
    ld (ch_a_ins_cur_ptr), hl
    ld (ch_b_ins_cur_ptr), hl
    ld (ch_c_ins_cur_ptr), hl
    ld (ch_a_ins_next_ptr), hl
    ld (ch_b_ins_next_ptr), hl
    ld (ch_c_ins_next_ptr), hl

    ld hl, empty_instrument_osc_sync
    ld (ch_b_osc_ins_cur_ptr), hl
    ; yeah I know... this isn't oscillator sync
    ld (ch_a_u_ins_cur_ptr), hl

    ld hl, ch_a_orn
    ld (orn_target), hl

    ld hl, empty_ornament
    ld (ch_a_orn_ptr), hl
    ld (ch_a_orn_loop_ptr), hl
    ld (ch_a_orn_ptr_initial), hl
    ld (ch_b_orn_ptr), hl
    ld (ch_b_orn_loop_ptr), hl
    ld (ch_b_orn_ptr_initial), hl
    ld (ch_b_orn_ptr_initial2), hl
    ld (ch_c_orn_ptr), hl
    ld (ch_c_orn_loop_ptr), hl
    ld (ch_c_orn_ptr_initial), hl

    ld hl, channel_b_song_timer_continue
    ld (channel_b_fm_jp), hl
    ld hl, channel_b_osc_song_timer_continue
    ld (channel_b_osc_sync_jp), hl

    ld a, HIGH pitch_table
    ld (ch_a_orn_pitch_table), a

    ret

; ============================================

MACHINE_TYPE_SINCLAIR   equ 0
MACHINE_TYPE_AMSTRAD    equ 1

machine_type:
    db -1

; ============================================

SampleOut_setup:

    push af

    ld l, a
    ld h, HIGH sample_out_table

    ; routine 0
    ld e, (hl)
    inc l
    ld d, (hl)
    inc l

    ld (sample_out_routine_0), de

    ; routine 1
    ld e, (hl)
    inc l
    ld d, (hl)
    inc l

    ld (sample_out_routine_1), de

    ; IY offset
    ld a, (hl)

    ld (sample_out_offset_smc), a

    ld hl, sample_out_patch_table

    ld b, SAMPLE_OUT_COUNT

SampleOut_setup_loop:

        push bc

            ; get address to patch
            ld a, (hl)
            inc hl
            ld e, a

            ld a, (hl)
            inc hl
            ld d, a

            ; get count parameter
            ld a, (hl)
            inc hl

                ; temporarily save patch table pointer
                push hl

                    ; save target pointer
                    push de

                        ; temporarily save count parameter
                        push af

                        ; load address of routine depending on count
                        SMC_LD(hl, "sample_out_routine_0")

                        rra
                        jr nc, SampleOut_setup_continue

                        SMC_LD(hl, "sample_out_routine_1")

SampleOut_setup_continue:

                        ; copy the routine
                        ld bc, SAMPLE_OUT_ROUTINE_SIZE
                        ldir

                        ; restore count parameter
                        pop af

                    ; load old target pointer
                    pop ix

                    ; set count parameter
sample_out_offset_smc equ $+2
                    ld (ix+0), a

                ; restore patch table pointer
                pop hl

        pop bc

    djnz SampleOut_setup_loop

    ; set up variables
    pop af

    cp OUTPUT_SPECDRUM
    jr z, setup_specdrum

        push af

        ; select AY mixer register
        ld bc, $fffd
        ld a, 7
        out (c), a

        ; tone and noise off
        ld b, $bf
        ld a, $3f
        out (c), a

        ld b, $ff

        pop af

    cp OUTPUT_AY_MONO
    ret nz

    ; ready for writing to channel A volume
    ; (for AY mono output)
    ld a, $08
    out (c), a

    ret

setup_specdrum:

    ; select SpecDrum port
    ; (We can use any low byte we choose,
    ; but it should be chosen to reduce
    ; or eliminate any I/O contention.)
    SMC_LD(bc, "dac_port")

setup_continue:

    ret

; ============================================

decode_dpcm:

    ; Note: decoding is destructive -
    ; the original data is cleared!

    ;  B = DC offset to add
    ; HL = address to start decoding
    ;   (must be $xx00 or $xx80)
    ; DE = destination address
    ;   (must be $xx00)

    ; on return:
    ; HL = address of last byte read
    ; DE = unchanged

    ; initialise delta
    xor a
    ld c, a

    ; get first sample
    rld

    ; get A in range [-8, 8)
    sub $08

dpcm_loop:

    ; update sample
    add a, b
    ld b, a

    ; store sample
    ld (de), a
    inc e

    ; return if done
    ret z

    ; keep source ptr in sync with destination ptr
    rl l
    ld l, e
    rr l

    ; get second order delta
    xor a
    rld

    ; get A in range [-8, 8)
    sub $08

    ; update delta
    add a, c
    ld c, a

    jr dpcm_loop

; ============================================

SAMPLE_OUT_ROUTINE_SIZE equ 25

SAMPLE_OUT_AY_MONO_IY_OFFSET equ 4
SAMPLE_OUT_AY_STEREO_IY_OFFSET equ 11

sample_out_routine_ay_mono_0:

    ; get sample data
    ld a, (hl)          ;  7 /   7      ; 1 /  1
    inc l               ;  4 /  11      ; 1 /  2

    add a, (iy+0)       ; 19 /  30      ; 3 /  5
    ld e, a             ;  4 /  34      ; 1 /  6

    ; out channel A
    ld a, (de)          ;  7 /  41      ; 1 /  7
    out ($fd), a        ; 11 /  52      ; 2 /  9
    inc d               ;  4 /  56      ; 1 / 10

    ; out channel B
    ld a, $09           ;  7 /  63      ; 2 / 12
    out (c), a          ; 12 /  75      ; 2 / 14
    ld a, (de)          ;  7 /  82      ; 1 / 15
    out ($fd), a        ; 11 /  93      ; 2 / 17
    inc d               ;  4 /  97      ; 1 / 18

    ; out channel C
    ld a, $0a           ;  7 / 104      ; 2 / 20
    out (c), a          ; 12 / 116      ; 2 / 22
    ld a, (de)          ;  7 / 123      ; 1 / 23
    out ($fd), a        ; 11 / 134      ; 2 / 25

; ============================================

noflow

BEGIN_PAGE_TABLE("string_data", false)

chip_select_table:
    db str_chip_ay-$
    db str_chip_ym-$
    db str_chip_dac-$

chip_stereo_table:
    db str_mono-$
    db str_abc_stereo-$
    db str_acb_stereo-$
    db str_bac_stereo-$

dac_port_table:
    db str_specdrum-$
    db str_covox-$

output_table:
    db str_mono-$
    db str_stereo-$

; ============================================

str_chip_select:
    db "Chip select: "
str_chip_ay:
    db "AY ", 0
str_chip_ym:
    db "YM ", 0
str_chip_dac:
    db "DAC", 0

str_dac_port:
    db "DAC port: "
str_specdrum:
    db "SpecDrum", 0
str_covox:
    db "Covox   ", 0

str_output:
    db "Output: "
str_mono:
    db "Mono      ", 0
str_abc_stereo:
    db "ABC "
str_stereo:
    db "Stereo", 0
str_acb_stereo:
    db "ACB Stereo", 0
str_bac_stereo:
    db "BAC Stereo", 0

str_keys:
    db "Q/A to navigate,", 0
str_keys2:
    db "enter/space to change option.", 0

str_note:
    db "Use mono chip for best results.", 0
str_zx0:
    db "ZX0 is by Einar Saukas.", 0

END_PAGE_TABLE("string_data")

; ============================================

sample_out_routine_ay_mono_1:

    ; get sample data
    ld a, (hl)          ;  7 /   7      ; 1 /  1
    inc l               ;  4 /  11      ; 1 /  2

    add a, (iy+0)       ; 19 /  30      ; 3 /  5
    ld e, a             ;  4 /  34      ; 1 /  6

    ; out channel C
    ld a, (de)          ;  7 /  41      ; 1 /  7
    out ($fd), a        ; 11 /  52      ; 2 /  9
    dec d               ;  4 /  56      ; 1 / 10

    ; out channel B
    ld a, $09           ;  7 /  63      ; 2 / 12
    out (c), a          ; 12 /  75      ; 2 / 14
    ld a, (de)          ;  7 /  82      ; 1 / 15
    out ($fd), a        ; 11 /  93      ; 2 / 17
    dec d               ;  4 /  97      ; 1 / 18

    ; out channel A
    ld a, $08           ;  7 / 104      ; 2 / 20
    out (c), a          ; 12 / 116      ; 2 / 22
    ld a, (de)          ;  7 / 123      ; 1 / 23
    out ($fd), a        ; 11 / 134      ; 2 / 25

; ============================================

sample_out_routine_specdrum:

    ; get sample data
    ld a, (hl)          ;  7 /   7      ; 1 /  1
    inc l               ;  4 /  11      ; 1 /  2

    add a, (iy+0)       ; 19 /  30      ; 3 /  5

    out (c), a          ; 12 /  42      ; 2 /  7

    ; timewasting
    cp (hl)             ;  7 /  49      ; 1 /  8
    cp (hl)             ;  7 /  56      ; 1 /  9
    cp (hl)             ;  7 /  63      ; 1 / 10
    cp (hl)             ;  7 /  70      ; 1 / 11
    cp (hl)             ;  7 /  77      ; 1 / 12
    cp (hl)             ;  7 /  84      ; 1 / 13
    cp (hl)             ;  7 /  91      ; 1 / 14

    or 0                ;  7 /  98      ; 2 / 16

    nop                 ;  4 / 102      ; 1 / 17
    nop                 ;  4 / 106      ; 1 / 18
    nop                 ;  4 / 110      ; 1 / 19
    nop                 ;  4 / 114      ; 1 / 20
    nop                 ;  4 / 118      ; 1 / 21
    nop                 ;  4 / 122      ; 1 / 22
    nop                 ;  4 / 126      ; 1 / 23
    nop                 ;  4 / 130      ; 1 / 24
    nop                 ;  4 / 134      ; 1 / 25

; ============================================

sample_out_routine_ay_mono_4bit:

    ; get sample data
    ld a, (hl)          ;  7 /   7      ; 1 /  1
    inc l               ;  4 /  11      ; 1 /  2

    add a, (iy+0)       ; 19 /  30      ; 3 /  5
    ld e, a             ;  4 /  34      ; 1 /  6

    ; out channel B
    SMC_LD(a, "port_4b");  7 /  41      ; 2 /  8
    out (c), a          ; 12 /  53      ; 2 / 10
    ld a, (de)          ;  7 /  60      ; 1 / 11
    out ($fd), a        ; 11 /  71      ; 2 / 13

    ; timewasting
    cp (hl)             ;  7 /  78      ; 1 / 14
    cp (hl)             ;  7 /  85      ; 1 / 15
    cp (hl)             ;  7 /  92      ; 1 / 16
    cp (hl)             ;  7 /  99      ; 1 / 17
    cp (hl)             ;  7 / 106      ; 1 / 18

    nop                 ;  4 / 110      ; 1 / 19
    nop                 ;  4 / 114      ; 1 / 20
    nop                 ;  4 / 118      ; 1 / 21
    nop                 ;  4 / 122      ; 1 / 22
    nop                 ;  4 / 126      ; 1 / 23
    nop                 ;  4 / 130      ; 1 / 24
    nop                 ;  4 / 134      ; 1 / 25

; ============================================

sample_out_routine_ay_stereo:

    ; get left channel sample data
    ld e, (hl)          ;  7 /   7      ; 1 /  1
    inc l               ;  4 /  11      ; 1 /  2

    ; out channel A
    SMC_LD(a, "chan_l") ;  7 /  18      ; 2 /  4
    out (c), a          ; 12 /  30      ; 2 /  6
    ld a, (de)          ;  7 /  37      ; 1 /  7
    out ($fd), a        ; 11 /  48      ; 2 /  9

    ; get right channel sample data
    ld e, (iy+0)        ; 19 /  67      ; 3 / 12

    ; output channel C
    SMC_LD(a, "chan_r") ;  7 /  74      ; 2 / 14
    out (c), a          ; 12 /  86      ; 2 / 16
    ld a, (de)          ;  7 /  93      ; 1 / 17
    out ($fd), a        ; 11 / 104      ; 2 / 19

    ; timewasting
    cp (hl)             ;  7 / 111      ; 1 / 20
    cp (hl)             ;  7 / 118      ; 1 / 21

    nop                 ;  4 / 122      ; 1 / 22
    nop                 ;  4 / 126      ; 1 / 23
    nop                 ;  4 / 130      ; 1 / 24
    nop                 ;  4 / 134      ; 1 / 25

; ============================================

    noflow

BEGIN_PAGE_TABLE("sample_out_table", false)

    OUTPUT_AY_MONO      equ LOW $   ; 8-bit sound on mono chip

    dw sample_out_routine_ay_mono_0
    dw sample_out_routine_ay_mono_1
    db SAMPLE_OUT_AY_MONO_IY_OFFSET

    OUTPUT_AY_MONO_4BIT equ LOW $   ; 4-bit sound on mono chip

    dw sample_out_routine_ay_mono_4bit
    dw sample_out_routine_ay_mono_4bit
    db SAMPLE_OUT_AY_MONO_IY_OFFSET

    OUTPUT_AY_STEREO    equ LOW $   ; stereo across two channels

    dw sample_out_routine_ay_stereo
    dw sample_out_routine_ay_stereo
    db SAMPLE_OUT_AY_STEREO_IY_OFFSET

    OUTPUT_SPECDRUM     equ LOW $   ; 8-bit sound on SpecDrum DAC

    dw sample_out_routine_specdrum
    dw sample_out_routine_specdrum
    db SAMPLE_OUT_AY_MONO_IY_OFFSET

END_PAGE_TABLE("sample_out_table")

; ============================================

SAMPLE_OUT_COUNT equ 103

    noflow

sample_out_patch_table:
    org sample_out_patch_table + 3*SAMPLE_OUT_COUNT

; ============================================
; time for SampleOut = 134Ts
; time for SampleGen = 63Ts (one sample)
; time for exx = 4Ts each

; total time between samples:
; 134 + 3*63 + 2*4 = 331Ts

; total time = 60*331 = 19860
; ============================================

END_BANK(5)

safe_stack_begin:
    ds 256
safe_stack_end:

noflow
BEGIN_BANK(2)

; ============================================

; Data that needs to be aligned goes first.

; ============================================

empty_sample_def:
empty_waveform:
    empty_sample(256, $80, 0, 4)

; ============================================

vol_table_ay:
    include "../bin/ay_table.asm"

vol_table_ay_4bit:
    include "../bin/ay_table_4bit.asm"

; ============================================

vol_table_ym:
    include "../bin/ym_table.asm"

vol_table_ym_4bit:
    include "../bin/ym_table_4bit.asm"

; ============================================

BEGIN_PAGE_TABLE("pitch_table", false)

    ; ensure no note has the value 0
    ; (reserved for note offs)
if (LOW $) = 0
    db 0
endif

pitch_table_base:

import_bin "../bin/pitch_table.bin"

END_PAGE_TABLE("pitch_table")

; ============================================

mainloop:

    SampleOut(0)                                ; 134 / 134
    exx                                         ;   4 / 138

    ld a, (song_timer)                          ;  13 / 151
    SMC_CP("song_speed0")                       ;   7 / 158
    jp nz, event_song_timer_continue            ;  10 / 168

    SMC_LD(a, "event_timer")                    ;   7 / 175
    dec a                                       ;   4 / 179
    jp nz, event_timer_continue                 ;  10 / 189

    SMC_LD(de, "event_pattern_ptr")             ;  10 / 199

    ; get event length
    ld a, (de)                                  ;   7 / 206
    inc de                                      ;   6 / 212
    ld (event_timer), a                         ;  13 / 225

    ; get event type (premultiplied)
    ld a, (de)                                  ;   7 / 232
    inc de                                      ;   6 / 238

    ld (event_jp_smc), a                        ;  13 / 251

    ; NOTE
event_jp_smc equ $+1
    ld hl, (event_jp_table)                     ;  16 / 267

    jp (hl)                                     ;   4 / 271

; ============================================

event_song_timer_continue:                      ;     / 168

    ; timewasting
    jr $+2                                      ;  12 / 180
    jr $+2                                      ;  12 / 192

    jp event_song_skip                          ;  10 / 202

event_timer_continue:                           ;     / 189

    ld (event_timer), a                         ;  13 / 202

event_song_skip:                                ;     / 202

    SMC_JP("orn_target")                        ;  10 / 212

; ============================================

event_return_192:                               ;     / 192

    ; timewasting
    cpi                                         ;  16 / 208

event_return_208:                               ;     / 208

    ; timewasting
    inc hl                                      ;   6 / 214
    nop                                         ;   4 / 218

event_return_218:                               ;     / 218

    ; timewasting
    nop                                         ;   4 / 222

event_return_222:                               ;     / 222

    ; timewasting
    nop                                         ;   4 / 226

event_return_226:                               ;     / 226

    ; timewasting
    nop                                         ;   4 / 230
    inc hl                                      ;   6 / 236

event_return_236:                               ;     / 236

    ; timewasting
    nop                                         ;   4 / 240

    ld a, r                                     ;   9 / 249

event_return_249:                               ;     / 249

    ; timewasting
    add hl, hl                                  ;  11 / 260

event_return_260:                               ;     / 260

    ; timewasting
    add hl, hl                                  ;  11 / 271

event_return_271:                               ;     / 271

    ; timewasting
    nop                                         ;   4 / 275

event_return:                                   ;     / 275

    SMC_JP("channel_a_samplegen")               ;  10 / 285

; ============================================

channel_a_bass_fm:                              ;     / 285

    ; prepare for bass generation
    ;
    ; BC = mod waveform
    ; DE = carrier waveform
    ; HL = write buffer
    ; IX = counter
    ; SP = pitch

    ld a, (song_timer)                          ;  13 / 298
    SMC_CP("song_speed1")                       ;   7 / 305
    jp nz, channel_a_song_timer_continue        ;  10 / 315

    ; timewasting
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(2)                                ; 134 / 134
    exx                                         ;   4 / 138

    SMC_LD(a, "ch_a_note_timer")                ;   7 / 145
    dec a                                       ;   4 / 149
    jp nz, channel_a_note_timer_continue        ;  10 / 159

    SMC_LD(hl, "ch_a_pattern_ptr")              ;  10 / 169

    ld a, (hl)  ; get note length               ;   7 / 176
    inc hl                                      ;   6 / 182
    ld (ch_a_note_timer), a                     ;  13 / 195

    ld a, (hl)  ; get note value                ;   7 / 202
    inc hl                                      ;   6 / 208

    ld (ch_a_pattern_ptr), hl                   ;  16 / 224

    ; save note value
    ld (ch_a_note_value), a                     ;  13 / 237

    or a                                        ;   4 / 241
    jp z, channel_a_reset_pos                   ;  10 / 251

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 256

    ; add ornament
    SMC_ADD_A("ch_a_orn_initial")               ;   7 / 263

    ld l, a                                     ;   4 / 267

    ; look up note pitch
    ld h, HIGH pitch_table                      ;   7 / 274

    ld sp, hl                                   ;   6 / 280
    pop hl                                      ;  10 / 290

    ; add pitch bend
    SMC_LD(de, "ch_a_bend_accum")               ;  10 / 300
    add hl, de                                  ;  11 / 311

    ld (ch_a_note), hl                          ;  16 / 327

    exx                                         ;   4 / 331
    SampleOut(3)                                ; 134 / 134
    exx                                         ;   4 / 138

    ld sp, hl                                   ;   6 / 144

    ; restart ornament
    SMC_LD(hl, "ch_a_orn_ptr_initial")          ;  10 / 154
    ld (ch_a_orn_ptr), hl                       ;  16 / 170

    ; restart instrument
    SMC_LD(hl, "ch_a_ins_initial")              ;  10 / 180
    ld (ch_a_ins_cur_ptr), hl                   ;  16 / 196

    SMC_LD(b, "ch_a_mod_initial")               ;   7 / 203
    SMC_LD(d, "ch_a_carrier_initial")           ;   7 / 210

    SMC_LD(a, "ch_a_ins_timer_initial")         ;   7 / 217
    ld (ch_a_ins_timer), a                      ;  13 / 230

channel_a_do_samplegen:                         ;     / 230

    SMC_LD(ix, "ch_a_pos")                      ;  14 / 244

    ld hl, (write_buffer_offset)                ;  16 / 260

    ; samplegen

    ; samples 0, 1
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 2, 3
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(4)                                ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 2, 3 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 4, 5
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 6, 7
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 8, 9
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(5)                                ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 8, 9 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 10, 11
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 12, 13
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 14, 15
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(6)                                ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 14, 15 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 16, 17
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 18, 19
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 20, 21
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(7)                                ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 20, 21 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 22, 23
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 24, 25
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 26, 27
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(8)                                ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 26, 27 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 28, 29
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 30, 31
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 32, 33
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(9)                                ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 32, 33 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 34, 35
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 36, 37
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 38, 39
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(10)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 38, 39 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 40, 41
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 42, 43
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 44, 45
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(11)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 44, 45 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 46, 47
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 48, 49
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 50, 51
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(12)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 50, 51 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 52, 53
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; samples 54, 55
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    inc l                                       ;   4 / 297
    ld (hl), a                                  ;   7 / 304
    add ix, sp                                  ;  15 / 319

    ; samples 56, 57
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(13)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; samples 56, 57 cont.
    ld a, (bc)                                  ;   7 / 149
    ld e, a                                     ;   4 / 153
    ld a, (de)                                  ;   7 / 160
    ld (hl), a                                  ;   7 / 167
    inc l                                       ;   4 / 171
    ld (hl), a                                  ;   7 / 178
    inc l                                       ;   4 / 182
    add ix, sp                                  ;  15 / 197

    ; samples 58, 59
    ld c, ixh                                   ;   8 / 205
    ld a, (bc)                                  ;   7 / 212
    ld e, a                                     ;   4 / 216
    ld a, (de)                                  ;   7 / 223
    ld (hl), a                                  ;   7 / 230
    inc l                                       ;   4 / 234
    ld (hl), a                                  ;   7 / 241

    add ix, sp                                  ;  15 / 256

    ; jump back

    jp channel_b_branch                         ;  10 / 266

; ============================================

channel_b_branch:                               ;     / 266

    ; timewasting
    nop                                         ;   4 / 270

ch_a_pos_prefix:
    ld (ch_a_pos), ix                           ;  20 / 290

    SMC_JP("channel_b_samplegen")               ;  10 / 300

; ============================================

channel_b_song_timer_continue:                  ;     / 310

    ; timewasting
    add hl, hl                                  ;  11 / 321
    inc hl                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(14)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting
    add hl, hl                                  ;  11 / 149
    inc hl                                      ;   6 / 155
    nop                                         ;   4 / 159

    jp channel_b_do_instrument                  ;  10 / 169

; ============================================

    ; prepare for FM generation
    ;
    ; BC = mod waveform
    ; DE = carrier waveform
    ; HL = write buffer
    ; IX = counter
    ; SP = pitch

channel_b_fm_setup:                             ;     / 300

    SMC_JP("channel_b_fm_jp")                   ;  10 / 310

; ============================================

channel_b_song_timer_no_continue:               ;     / 310

    SMC_LD(a, "ch_b_note_timer")                ;   7 / 317

    ; save flags
    ex af, af'                                  ;   4 / 321

    ; timewasting
    inc hl                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(14)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; restore flags
    ex af, af'                                  ;   4 / 142

    dec a                                       ;   4 / 146
    jp nz, channel_b_note_timer_continue        ;  10 / 156

    ld hl, (ch_b_pattern_ptr)                   ;  16 / 172

    ld a, (hl)  ; get note length               ;   7 / 179
    inc hl                                      ;   6 / 185
    ld (ch_b_note_timer), a                     ;  13 / 198

    ld a, (hl)  ; get note value                ;   7 / 205
    inc hl                                      ;   6 / 211

    ld (ch_b_pattern_ptr), hl                   ;  16 / 227

    ; save note value
    ld (ch_b_note_value), a                     ;  13 / 240

    or a                                        ;   4 / 244
    jr z, channel_b_reset_pos                   ;   7 / 251 [256 taken]

    ; add ornament
    SMC_ADD_A("ch_b_orn_initial")               ;   7 / 258

    ; look up note pitch
    ld h, HIGH pitch_table                      ;   7 / 265
    ld l, a                                     ;   4 / 269

    ld sp, hl                                   ;   6 / 275
    pop hl                                      ;  10 / 285

    ; add pitch bend
    SMC_LD(de, "ch_b_bend_accum")               ;  10 / 295
    add hl, de                                  ;  11 / 306

    ld sp, hl                                   ;   6 / 312

    SMC_LD(b, "ch_b_mod_initial")               ;   7 / 319

    ; timewasting
    nop                                         ;   4 / 323
    nop                                         ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    ld (ch_b_note), hl                          ;  16 / 154

    ; restart ornament
    SMC_LD(hl, "ch_b_orn_ptr_initial")          ;  10 / 164
    ld (ch_b_orn_ptr), hl                       ;  16 / 180

    ; restart instrument
    SMC_LD(hl, "ch_b_ins_initial")              ;  10 / 190
    ld (ch_b_ins_cur_ptr), hl                   ;  16 / 206

    SMC_LD(d, "ch_b_carrier_initial")           ;   7 / 213

    SMC_LD(a, "ch_b_ins_timer_initial")         ;   7 / 220
    ld (ch_b_ins_timer), a                      ;  13 / 233

channel_b_do_samplegen:                         ;     / 233

    ld ix, (ch_b_pos)                           ;  20 / 253

    ; timewasting
    add hl, hl                                  ;  11 / 264

    ; reset carry flag - important
    xor a                                       ;   4 / 268

    ex af, af'                                  ;   4 / 272

    ld hl, (write_buffer_offset)                ;  16 / 288

    ; timewasting
    jp $+3                                      ;  10 / 298

    jp samplegen_fm                             ;  10 / 308

; ============================================

channel_b_reset_pos:                            ;     / 256

    ; we know A = 0

    ld h, a                                     ;   4 / 260
    ld l, a                                     ;   4 / 264

    inc a                                       ;   4 / 268
    ld (ch_b_ins_timer), a                      ;  13 / 281

    ld (ch_b_pos), hl                           ;  16 / 297
    ld (ch_b_note), hl                          ;  16 / 313
    ld sp, hl                                   ;   6 / 319

    ; timewasting
    nop                                         ;   4 / 323
    nop                                         ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting (HL and SP point to ROM)
    cp (hl)                                     ;   7 / 145
    ex (sp), hl                                 ;  19 / 164
    ex (sp), hl                                 ;  19 / 183

    ; Set up the empty instrument.

    ld b, EMPTY_INS_MOD                         ;   7 / 190

    ld d, EMPTY_INS_CARRIER                     ;   7 / 197

    ld hl, empty_instrument                     ;  10 / 207
    ld (ch_b_ins_next_ptr), hl                  ;  16 / 223

    jp channel_b_do_samplegen                   ;  10 / 233

; ============================================

channel_c_song_timer_continue:                  ;     / 253

    ; timewasting
    add hl, hl                                  ;  11 / 264
    nop                                         ;   4 / 268
    nop                                         ;   4 / 272

    jp channel_c_do_instrument                  ;  10 / 282

; ============================================

channel_c_reset_pos:                            ;     / 185

    ; we know A = 0
    ld h, a                                     ;   4 / 189
    ld l, a                                     ;   4 / 193

    inc a                                       ;   4 / 197
    ld (ch_c_ins_timer), a                      ;  13 / 210

    ld (ch_c_pos), hl                           ;  16 / 226
    ld (ch_c_note), hl                          ;  16 / 242
    ld sp, hl                                   ;   6 / 248

    ; Set up the empty instrument.

    ld b, EMPTY_INS_MOD                         ;   7 / 255
    ld d, EMPTY_INS_CARRIER                     ;   7 / 262

    ld hl, empty_instrument                     ;  10 / 272
    ld (ch_c_ins_next_ptr), hl                  ;  16 / 288

    ; timewasting
    add hl, hl                                  ;  11 / 299
    add hl, hl                                  ;  11 / 310
    add hl, hl                                  ;  11 / 321
    inc hl                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting
    jr $+2                                      ;  12 / 150
    nop                                         ;   4 / 154

    jp channel_c_do_samplegen                   ;  10 / 164

; ============================================

channel_b_fm_continue:                          ;     / 196

    ; NOTE
    ld de, 36-14                                ;  10 / 206
    add iy, de                                  ;  15 / 221

    ; prepare for FM generation
    ;
    ; BC = mod waveform
    ; DE = carrier waveform
    ; HL = write buffer
    ; IX = counter
    ; SP = pitch

    ld a, (song_timer)                          ;  13 / 234
    SMC_CP("song_speed3")                       ;   7 / 241
    jr nz, channel_c_song_timer_continue        ;   7 / 248 [253 taken]

    SMC_LD(a, "ch_c_note_timer")                ;   7 / 255
    dec a                                       ;   4 / 259
    jp nz, channel_c_note_timer_continue        ;  10 / 269

    ; timewasting [CAUTION!]
    ret nz                                      ;   5 / 274

    SMC_LD(hl, "ch_c_pattern_ptr")              ;  10 / 284

    ld a, (hl)  ; get note length               ;   7 / 291
    inc hl                                      ;   6 / 297
    ld (ch_c_note_timer), a                     ;  13 / 310

    ld a, (hl)  ; get note value                ;   7 / 317
    inc hl                                      ;   6 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(14)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ld (ch_c_pattern_ptr), hl                   ;  16 / 158

    ; save note value
    ld (ch_c_note_value), a                     ;  13 / 171

    or a                                        ;   4 / 175
    jp z, channel_c_reset_pos                   ;  10 / 185

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 190

    ; add ornament
    SMC_ADD_A("ch_c_orn_initial")               ;   7 / 197

    ; look up note pitch
    ld h, HIGH pitch_table                      ;   7 / 204
    ld l, a                                     ;   4 / 208

    ld sp, hl                                   ;   6 / 214
    pop hl                                      ;  10 / 224

    ; add pitch bend
    SMC_LD(de, "ch_c_bend_accum")               ;  10 / 234
    add hl, de                                  ;  11 / 245

    ld sp, hl                                   ;   6 / 251
    ld (ch_c_note), hl                          ;  16 / 267

    ; restart instrument
    SMC_LD(hl, "ch_c_ins_initial")              ;  10 / 277
    ld (ch_c_ins_cur_ptr), hl                   ;  16 / 293

    SMC_LD(a, "ch_c_ins_timer_initial")         ;   7 / 300
    ld (ch_c_ins_timer), a                      ;  13 / 313

    SMC_LD(b, "ch_c_mod_initial")               ;   7 / 320
    SMC_LD(d, "ch_c_carrier_initial")           ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; restart ornament
    SMC_LD(hl, "ch_c_orn_ptr_initial")          ;  10 / 148
    ld (ch_c_orn_ptr), hl                       ;  16 / 164

channel_c_do_samplegen:                         ;     / 164

    SMC_LD(hl, "write_buffer_offset")           ;  10 / 174

    ld (ch_b_pos), ix                           ;  20 / 194

    SMC_LD(ix, "ch_c_pos")                      ;  14 / 208

    ; set carry flag - important
    scf                                         ;   4 / 212
    ex af, af'                                  ;   4 / 216

    SMC_JP("callback_target")                   ;  10 / 226

callback:                                       ;     / 226
    ; available registers: A, C, E

    ; run the action on every 16th call
    SMC_LD(a, "callback_timer")                 ;   7 / 233
    inc a                                       ;   4 / 237
    ld (callback_timer), a                      ;  13 / 250

    and $0f                                     ;   7 / 257
    jp nz, callback_ret                         ;  10 / 267

    ; read the keyboard
    in a, ($fe)                                 ;  11 / 278
    cpl                                         ;   4 / 282
    and $1f                                     ;   7 / 289

    ; jump if a key was (or was not) pressed
callback_jp:
    jp nz, run_callback                         ;  10 / 299

    ; timewasting
    ld a, r                                     ;   9 / 308

samplegen_fm:                                   ;     / 308

    ; samplegen

    ; sample 0
    ld c, ixh                                   ;   8 / 316
    ld a, (bc)                                  ;   7 / 323
    ld e, a                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(16)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 0 cont.
    ld a, (de)                                  ;   7 / 145
    add a, (hl)                                 ;   7 / 152
    ld (hl), a                                  ;   7 / 159
    inc l                                       ;   4 / 163
    add ix, sp                                  ;  15 / 178

    ; sample 1
    ld c, ixh                                   ;   8 / 186
    ld a, (bc)                                  ;   7 / 193
    ld e, a                                     ;   4 / 197
    ld a, (de)                                  ;   7 / 204
    add a, (hl)                                 ;   7 / 211
    ld (hl), a                                  ;   7 / 218
    inc l                                       ;   4 / 222

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 227

    add ix, sp                                  ;  15 / 242

    ; sample 2
    ld c, ixh                                   ;   8 / 250
    ld a, (bc)                                  ;   7 / 257
    ld e, a                                     ;   4 / 261
    ld a, (de)                                  ;   7 / 268
    add a, (hl)                                 ;   7 / 275
    ld (hl), a                                  ;   7 / 282
    ; inc l
    add ix, sp                                  ;  15 / 297

    ; sample 3
    ld c, ixh                                   ;   8 / 305
    ld a, (bc)                                  ;   7 / 312
    ld e, a                                     ;   4 / 316
    ld a, (de)                                  ;   7 / 323

    ld e, a                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(17)                               ; 134 / 134
    exx                                         ;   4 / 138

    ld a, e                                     ;   4 / 142

    ; sample 3 cont.
    inc l                                       ;   4 / 146

    add a, (hl)                                 ;   7 / 153
    ld (hl), a                                  ;   7 / 160
    inc l                                       ;   4 / 164
    add ix, sp                                  ;  15 / 179

    ; sample 4
    ld c, ixh                                   ;   8 / 187
    ld a, (bc)                                  ;   7 / 194
    ld e, a                                     ;   4 / 198
    ld a, (de)                                  ;   7 / 205
    add a, (hl)                                 ;   7 / 212
    ld (hl), a                                  ;   7 / 219
    inc l                                       ;   4 / 223
    add ix, sp                                  ;  15 / 238

    ; sample 5
    ld c, ixh                                   ;   8 / 246
    ld a, (bc)                                  ;   7 / 253
    ld e, a                                     ;   4 / 257
    ld a, (de)                                  ;   7 / 264
    add a, (hl)                                 ;   7 / 271
    ld (hl), a                                  ;   7 / 278
    inc l                                       ;   4 / 282
    add ix, sp                                  ;  15 / 297

    ; sample 6
    ld c, ixh                                   ;   8 / 305
    ld a, (bc)                                  ;   7 / 312
    ld e, a                                     ;   4 / 316
    ld a, (de)                                  ;   7 / 323

    ld e, a                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(18)                               ; 134 / 134
    exx                                         ;   4 / 138

    ld a, e                                     ;   4 / 142

    ; sample 6 cont.
    add a, (hl)                                 ;   7 / 149
    ld (hl), a                                  ;   7 / 156
    inc l                                       ;   4 / 160
    add ix, sp                                  ;  15 / 175

    ; sample 7
    ld c, ixh                                   ;   8 / 183
    ld a, (bc)                                  ;   7 / 190
    ld e, a                                     ;   4 / 194
    ld a, (de)                                  ;   7 / 201
    add a, (hl)                                 ;   7 / 208
    ld (hl), a                                  ;   7 / 215
    inc l                                       ;   4 / 219
    add ix, sp                                  ;  15 / 234

    ; sample 8
    ld c, ixh                                   ;   8 / 242
    ld a, (bc)                                  ;   7 / 249
    ld e, a                                     ;   4 / 253
    ld a, (de)                                  ;   7 / 260
    add a, (hl)                                 ;   7 / 267
    ld (hl), a                                  ;   7 / 274
    inc l                                       ;   4 / 278
    add ix, sp                                  ;  15 / 293

    ; sample 9
    ld c, ixh                                   ;   8 / 301
    ld a, (bc)                                  ;   7 / 308
    ld e, a                                     ;   4 / 312

    add ix, sp                                  ;  15 / 327

    exx                                         ;   4 / 331
    SampleOut(19)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 9 cont.
    ld a, (de)                                  ;   7 / 145
    add a, (hl)                                 ;   7 / 152
    ld (hl), a                                  ;   7 / 159
    inc l                                       ;   4 / 163

    ; sample 10
    ld c, ixh                                   ;   8 / 171
    ld a, (bc)                                  ;   7 / 178
    ld e, a                                     ;   4 / 182
    ld a, (de)                                  ;   7 / 189
    add a, (hl)                                 ;   7 / 196
    ld (hl), a                                  ;   7 / 203
    inc l                                       ;   4 / 207
    add ix, sp                                  ;  15 / 222

    ; sample 11
    ld c, ixh                                   ;   8 / 230
    ld a, (bc)                                  ;   7 / 237
    ld e, a                                     ;   4 / 241
    ld a, (de)                                  ;   7 / 248
    add a, (hl)                                 ;   7 / 255
    ld (hl), a                                  ;   7 / 262
    inc l                                       ;   4 / 266
    add ix, sp                                  ;  15 / 281

    ; sample 12
    ld c, ixh                                   ;   8 / 289
    ld a, (bc)                                  ;   7 / 296
    ld e, a                                     ;   4 / 300
    ld a, (de)                                  ;   7 / 307
    add a, (hl)                                 ;   7 / 314
    ld (hl), a                                  ;   7 / 321
    inc hl                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(20)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 12 cont.
    add ix, sp                                  ;  15 / 153

    ; sample 13
    ld c, ixh                                   ;   8 / 161
    ld a, (bc)                                  ;   7 / 168
    ld e, a                                     ;   4 / 172
    ld a, (de)                                  ;   7 / 179
    add a, (hl)                                 ;   7 / 186
    ld (hl), a                                  ;   7 / 193
    inc l                                       ;   4 / 197
    add ix, sp                                  ;  15 / 212

    ; sample 14
    ld c, ixh                                   ;   8 / 220
    ld a, (bc)                                  ;   7 / 227
    ld e, a                                     ;   4 / 231
    ld a, (de)                                  ;   7 / 238
    add a, (hl)                                 ;   7 / 245
    ld (hl), a                                  ;   7 / 252
    inc l                                       ;   4 / 256
    add ix, sp                                  ;  15 / 271

    ; sample 15
    ld c, ixh                                   ;   8 / 279
    ld a, (bc)                                  ;   7 / 286
    ld e, a                                     ;   4 / 290
    ld a, (de)                                  ;   7 / 297
    add a, (hl)                                 ;   7 / 304
    ld (hl), a                                  ;   7 / 311
    inc l                                       ;   4 / 315

    ; timewasting
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(21)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 15 cont.
    add ix, sp                                  ;  15 / 153

    ; sample 16
    ld c, ixh                                   ;   8 / 161
    ld a, (bc)                                  ;   7 / 168
    ld e, a                                     ;   4 / 172
    ld a, (de)                                  ;   7 / 179
    add a, (hl)                                 ;   7 / 186
    ld (hl), a                                  ;   7 / 193
    inc l                                       ;   4 / 197
    add ix, sp                                  ;  15 / 212

    ; sample 17
    ld c, ixh                                   ;   8 / 220
    ld a, (bc)                                  ;   7 / 227
    ld e, a                                     ;   4 / 231
    ld a, (de)                                  ;   7 / 238
    add a, (hl)                                 ;   7 / 245
    ld (hl), a                                  ;   7 / 252
    inc l                                       ;   4 / 256
    add ix, sp                                  ;  15 / 271

    ; sample 18
    ld c, ixh                                   ;   8 / 279
    ld a, (bc)                                  ;   7 / 286
    ld e, a                                     ;   4 / 290
    ld a, (de)                                  ;   7 / 297
    add a, (hl)                                 ;   7 / 304
    ld (hl), a                                  ;   7 / 311
    inc l                                       ;   4 / 315

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 320

    ld e, (hl)                                  ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(22)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 18 cont.
    add ix, sp                                  ;  15 / 153

    ; sample 19
    ld c, ixh                                   ;   8 / 161
    ld a, (bc)                                  ;   7 / 168

    ld c, e                                     ;   4 / 172
    ld e, a                                     ;   4 / 176

    ld a, (de)                                  ;   7 / 183
    add a, c                                    ;   4 / 187
    ld (hl), a                                  ;   7 / 194
    inc l                                       ;   4 / 198
    add ix, sp                                  ;  15 / 213

    ; sample 20
    ld c, ixh                                   ;   8 / 221
    ld a, (bc)                                  ;   7 / 228
    ld e, a                                     ;   4 / 232
    ld a, (de)                                  ;   7 / 239
    add a, (hl)                                 ;   7 / 246
    ld (hl), a                                  ;   7 / 253
    inc l                                       ;   4 / 257
    add ix, sp                                  ;  15 / 272

    ; sample 21
    ld c, ixh                                   ;   8 / 280
    ld a, (bc)                                  ;   7 / 287
    ld e, a                                     ;   4 / 291
    ld a, (de)                                  ;   7 / 298
    add a, (hl)                                 ;   7 / 305
    ld (hl), a                                  ;   7 / 312
    ; inc l
    add ix, sp                                  ;  15 / 327

    exx                                         ;   4 / 331
    SampleOut(23)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; sample 22
    ld c, ixh                                   ;   8 / 150
    ld a, (bc)                                  ;   7 / 157
    ld e, a                                     ;   4 / 161
    ld a, (de)                                  ;   7 / 168
    add a, (hl)                                 ;   7 / 175
    ld (hl), a                                  ;   7 / 182
    inc l                                       ;   4 / 186
    add ix, sp                                  ;  15 / 201

    ; sample 23
    ld c, ixh                                   ;   8 / 209
    ld a, (bc)                                  ;   7 / 216
    ld e, a                                     ;   4 / 220
    ld a, (de)                                  ;   7 / 227
    add a, (hl)                                 ;   7 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; sample 24
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    add a, (hl)                                 ;   7 / 293
    ld (hl), a                                  ;   7 / 300
    inc l                                       ;   4 / 304
    add ix, sp                                  ;  15 / 319

    ; sample 25
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(24)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 25 cont.
    ld a, (bc)                                  ;   7 / 145
    ld e, a                                     ;   4 / 149
    ld a, (de)                                  ;   7 / 156
    add a, (hl)                                 ;   7 / 163
    ld (hl), a                                  ;   7 / 170
    inc l                                       ;   4 / 174
    add ix, sp                                  ;  15 / 189

    ; sample 26
    ld c, ixh                                   ;   8 / 197
    ld a, (bc)                                  ;   7 / 204
    ld e, a                                     ;   4 / 208
    ld a, (de)                                  ;   7 / 215
    add a, (hl)                                 ;   7 / 222
    ld (hl), a                                  ;   7 / 229
    inc l                                       ;   4 / 233

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 238

    add ix, sp                                  ;  15 / 253

    ; sample 27
    ld c, ixh                                   ;   8 / 261
    ld a, (bc)                                  ;   7 / 268
    ld e, a                                     ;   4 / 272
    ld a, (de)                                  ;   7 / 279
    add a, (hl)                                 ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    ; inc l
    add ix, sp                                  ;  15 / 308

    ; sample 28
    ld c, ixh                                   ;   8 / 316
    ld a, (bc)                                  ;   7 / 323
    ld e, a                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(25)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; sample 28 cont.
    ld a, (de)                                  ;   7 / 149
    add a, (hl)                                 ;   7 / 156
    ld (hl), a                                  ;   7 / 163
    inc l                                       ;   4 / 167
    add ix, sp                                  ;  15 / 182

    ; sample 29
    ld c, ixh                                   ;   8 / 190
    ld a, (bc)                                  ;   7 / 197
    ld e, a                                     ;   4 / 201
    ld a, (de)                                  ;   7 / 208
    add a, (hl)                                 ;   7 / 215
    ld (hl), a                                  ;   7 / 222
    inc l                                       ;   4 / 226
    add ix, sp                                  ;  15 / 241

    ; sample 30
    ld c, ixh                                   ;   8 / 249
    ld a, (bc)                                  ;   7 / 256
    ld e, a                                     ;   4 / 260
    ld a, (de)                                  ;   7 / 267
    add a, (hl)                                 ;   7 / 274
    ld (hl), a                                  ;   7 / 281
    inc l                                       ;   4 / 285
    add ix, sp                                  ;  15 / 300

    ; sample 31
    ld c, ixh                                   ;   8 / 308
    ld a, (bc)                                  ;   7 / 315
    ld e, a                                     ;   4 / 319

    ; timewasting
    nop                                         ;   4 / 323
    nop                                         ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(26)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 31 cont.
    ld a, (de)                                  ;   7 / 145
    add a, (hl)                                 ;   7 / 152
    ld (hl), a                                  ;   7 / 159
    inc l                                       ;   4 / 163
    add ix, sp                                  ;  15 / 178

    ; sample 32
    ld c, ixh                                   ;   8 / 186
    ld a, (bc)                                  ;   7 / 193
    ld e, a                                     ;   4 / 197
    ld a, (de)                                  ;   7 / 204
    add a, (hl)                                 ;   7 / 211
    ld (hl), a                                  ;   7 / 218
    inc l                                       ;   4 / 222

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 227

    add ix, sp                                  ;  15 / 242

    ; sample 33
    ld c, ixh                                   ;   8 / 250
    ld a, (bc)                                  ;   7 / 257
    ld e, a                                     ;   4 / 261
    ld a, (de)                                  ;   7 / 268
    add a, (hl)                                 ;   7 / 275
    ld (hl), a                                  ;   7 / 282
    ; inc l
    add ix, sp                                  ;  15 / 297

    ; sample 34
    ld c, ixh                                   ;   8 / 305
    ld a, (bc)                                  ;   7 / 312
    ld e, a                                     ;   4 / 316
    ld a, (de)                                  ;   7 / 323

    ld e, a                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(27)                               ; 134 / 134
    exx                                         ;   4 / 138

    ld a, e                                     ;   4 / 142

    inc l                                       ;   4 / 146

    ; sample 34 cont.
    add a, (hl)                                 ;   7 / 153
    ld (hl), a                                  ;   7 / 160
    inc l                                       ;   4 / 164
    add ix, sp                                  ;  15 / 179

    ; sample 35
    ld c, ixh                                   ;   8 / 187
    ld a, (bc)                                  ;   7 / 194
    ld e, a                                     ;   4 / 198
    ld a, (de)                                  ;   7 / 205
    add a, (hl)                                 ;   7 / 212
    ld (hl), a                                  ;   7 / 219
    inc l                                       ;   4 / 223
    add ix, sp                                  ;  15 / 238

    ; sample 36
    ld c, ixh                                   ;   8 / 246
    ld a, (bc)                                  ;   7 / 253
    ld e, a                                     ;   4 / 257
    ld a, (de)                                  ;   7 / 264
    add a, (hl)                                 ;   7 / 271
    ld (hl), a                                  ;   7 / 278
    inc l                                       ;   4 / 282
    add ix, sp                                  ;  15 / 297

    ; sample 37
    ld c, ixh                                   ;   8 / 305
    ld a, (bc)                                  ;   7 / 312
    ld e, a                                     ;   4 / 316
    ld a, (de)                                  ;   7 / 323

    ld e, a                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(28)                               ; 134 / 134
    exx                                         ;   4 / 138

    ld a, e                                     ;   4 / 142

    ; sample 37 cont.
    add a, (hl)                                 ;   7 / 149
    ld (hl), a                                  ;   7 / 156
    inc l                                       ;   4 / 160
    add ix, sp                                  ;  15 / 175

    ; sample 38
    ld c, ixh                                   ;   8 / 183
    ld a, (bc)                                  ;   7 / 190
    ld e, a                                     ;   4 / 194
    ld a, (de)                                  ;   7 / 201
    add a, (hl)                                 ;   7 / 208
    ld (hl), a                                  ;   7 / 215
    inc l                                       ;   4 / 219
    add ix, sp                                  ;  15 / 234

    ; sample 39
    ld c, ixh                                   ;   8 / 242
    ld a, (bc)                                  ;   7 / 249
    ld e, a                                     ;   4 / 253
    ld a, (de)                                  ;   7 / 260
    add a, (hl)                                 ;   7 / 267
    ld (hl), a                                  ;   7 / 274
    inc l                                       ;   4 / 278
    add ix, sp                                  ;  15 / 293

    ; sample 40
    ld c, ixh                                   ;   8 / 301
    ld a, (bc)                                  ;   7 / 308
    ld e, a                                     ;   4 / 312

    add ix, sp                                  ;  15 / 327

    exx                                         ;   4 / 331
    SampleOut(29)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 40 cont.
    ld a, (de)                                  ;   7 / 145
    add a, (hl)                                 ;   7 / 152
    ld (hl), a                                  ;   7 / 159
    inc l                                       ;   4 / 163

    ; sample 41
    ld c, ixh                                   ;   8 / 171
    ld a, (bc)                                  ;   7 / 178
    ld e, a                                     ;   4 / 182
    ld a, (de)                                  ;   7 / 189
    add a, (hl)                                 ;   7 / 196
    ld (hl), a                                  ;   7 / 203
    inc l                                       ;   4 / 207
    add ix, sp                                  ;  15 / 222

    ; sample 42
    ld c, ixh                                   ;   8 / 230
    ld a, (bc)                                  ;   7 / 237
    ld e, a                                     ;   4 / 241
    ld a, (de)                                  ;   7 / 248
    add a, (hl)                                 ;   7 / 255
    ld (hl), a                                  ;   7 / 262
    inc l                                       ;   4 / 266
    add ix, sp                                  ;  15 / 281

    ; sample 43
    ld c, ixh                                   ;   8 / 289
    ld a, (bc)                                  ;   7 / 296
    ld e, a                                     ;   4 / 300
    ld a, (de)                                  ;   7 / 307
    add a, (hl)                                 ;   7 / 314
    ld (hl), a                                  ;   7 / 321
    inc hl                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(30)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 43 cont.
    add ix, sp                                  ;  15 / 153

    ; sample 44
    ld c, ixh                                   ;   8 / 161
    ld a, (bc)                                  ;   7 / 168
    ld e, a                                     ;   4 / 172
    ld a, (de)                                  ;   7 / 179
    add a, (hl)                                 ;   7 / 186
    ld (hl), a                                  ;   7 / 193
    inc l                                       ;   4 / 197
    add ix, sp                                  ;  15 / 212

    ; sample 45
    ld c, ixh                                   ;   8 / 220
    ld a, (bc)                                  ;   7 / 227
    ld e, a                                     ;   4 / 231
    ld a, (de)                                  ;   7 / 238
    add a, (hl)                                 ;   7 / 245
    ld (hl), a                                  ;   7 / 252
    inc l                                       ;   4 / 256
    add ix, sp                                  ;  15 / 271

    ; sample 46
    ld c, ixh                                   ;   8 / 279
    ld a, (bc)                                  ;   7 / 286
    ld e, a                                     ;   4 / 290
    ld a, (de)                                  ;   7 / 297
    add a, (hl)                                 ;   7 / 304
    ld (hl), a                                  ;   7 / 311
    inc l                                       ;   4 / 315

    ; timewasting
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(31)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 46 cont.
    add ix, sp                                  ;  15 / 153

    ; sample 47
    ld c, ixh                                   ;   8 / 161
    ld a, (bc)                                  ;   7 / 168
    ld e, a                                     ;   4 / 172
    ld a, (de)                                  ;   7 / 179
    add a, (hl)                                 ;   7 / 186
    ld (hl), a                                  ;   7 / 193
    inc l                                       ;   4 / 197
    add ix, sp                                  ;  15 / 212

    ; sample 48
    ld c, ixh                                   ;   8 / 220
    ld a, (bc)                                  ;   7 / 227
    ld e, a                                     ;   4 / 231
    ld a, (de)                                  ;   7 / 238
    add a, (hl)                                 ;   7 / 245
    ld (hl), a                                  ;   7 / 252
    inc l                                       ;   4 / 256
    add ix, sp                                  ;  15 / 271

    ; sample 49
    ld c, ixh                                   ;   8 / 279
    ld a, (bc)                                  ;   7 / 286
    ld e, a                                     ;   4 / 290
    ld a, (de)                                  ;   7 / 297
    add a, (hl)                                 ;   7 / 304
    ld (hl), a                                  ;   7 / 311
    inc l                                       ;   4 / 315

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 320

    ld e, (hl)                                  ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(32)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 49 cont.
    add ix, sp                                  ;  15 / 153

    ; sample 50
    ld c, ixh                                   ;   8 / 161
    ld a, (bc)                                  ;   7 / 168

    ld c, e                                     ;   4 / 172
    ld e, a                                     ;   4 / 176

    ld a, (de)                                  ;   7 / 183
    add a, c                                    ;   4 / 187
    ld (hl), a                                  ;   7 / 194
    inc l                                       ;   4 / 198
    add ix, sp                                  ;  15 / 213

    ; sample 51
    ld c, ixh                                   ;   8 / 221
    ld a, (bc)                                  ;   7 / 228
    ld e, a                                     ;   4 / 232
    ld a, (de)                                  ;   7 / 239
    add a, (hl)                                 ;   7 / 246
    ld (hl), a                                  ;   7 / 253
    inc l                                       ;   4 / 257
    add ix, sp                                  ;  15 / 272

    ; sample 52
    ld c, ixh                                   ;   8 / 280
    ld a, (bc)                                  ;   7 / 287
    ld e, a                                     ;   4 / 291
    ld a, (de)                                  ;   7 / 298
    add a, (hl)                                 ;   7 / 305
    ld (hl), a                                  ;   7 / 312
    ; inc l
    add ix, sp                                  ;  15 / 327

    exx                                         ;   4 / 331
    SampleOut(33)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; sample 53
    ld c, ixh                                   ;   8 / 150
    ld a, (bc)                                  ;   7 / 157
    ld e, a                                     ;   4 / 161
    ld a, (de)                                  ;   7 / 168
    add a, (hl)                                 ;   7 / 175
    ld (hl), a                                  ;   7 / 182
    inc l                                       ;   4 / 186
    add ix, sp                                  ;  15 / 201

    ; sample 54
    ld c, ixh                                   ;   8 / 209
    ld a, (bc)                                  ;   7 / 216
    ld e, a                                     ;   4 / 220
    ld a, (de)                                  ;   7 / 227
    add a, (hl)                                 ;   7 / 234
    ld (hl), a                                  ;   7 / 241
    inc l                                       ;   4 / 245
    add ix, sp                                  ;  15 / 260

    ; sample 55
    ld c, ixh                                   ;   8 / 268
    ld a, (bc)                                  ;   7 / 275
    ld e, a                                     ;   4 / 279
    ld a, (de)                                  ;   7 / 286
    add a, (hl)                                 ;   7 / 293
    ld (hl), a                                  ;   7 / 300
    inc l                                       ;   4 / 304
    add ix, sp                                  ;  15 / 319

    ; sample 56
    ld c, ixh                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(34)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 56 cont.
    ld a, (bc)                                  ;   7 / 145
    ld e, a                                     ;   4 / 149
    ld a, (de)                                  ;   7 / 156
    add a, (hl)                                 ;   7 / 163
    ld (hl), a                                  ;   7 / 170
    inc l                                       ;   4 / 174
    add ix, sp                                  ;  15 / 189

    ; sample 57
    ld c, ixh                                   ;   8 / 197
    ld a, (bc)                                  ;   7 / 204
    ld e, a                                     ;   4 / 208
    ld a, (de)                                  ;   7 / 215
    add a, (hl)                                 ;   7 / 222
    ld (hl), a                                  ;   7 / 229
    inc l                                       ;   4 / 233

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 238

    add ix, sp                                  ;  15 / 253

    ; sample 58
    ld c, ixh                                   ;   8 / 261
    ld a, (bc)                                  ;   7 / 268
    ld e, a                                     ;   4 / 272
    ld a, (de)                                  ;   7 / 279
    add a, (hl)                                 ;   7 / 286
    ld (hl), a                                  ;   7 / 293
    ; inc l
    add ix, sp                                  ;  15 / 308

    ; sample 59
    ld c, ixh                                   ;   8 / 316
    ld a, (bc)                                  ;   7 / 323
    ld e, a                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(35)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc l                                       ;   4 / 142

    ; sample 59 cont.
    ld a, (de)                                  ;   7 / 149
    add a, (hl)                                 ;   7 / 156
    ld (hl), a                                  ;   7 / 163
    add ix, sp                                  ;  15 / 178

    ; timewasting
    nop                                         ;   4 / 182

    ex af, af'                                  ;   4 / 186
    jp nc, channel_b_fm_continue                ;  10 / 196

channel_c_fm_continue:                          ;     / 196

    SMC_LD(a, "song_timer")                     ;   7 / 203
    dec a                                       ;   4 / 207
    jp nz, song_timer_continue                  ;  10 / 217

    SMC_LD(a, "song_speed4")                    ;   7 / 224
    ld (song_timer), a                          ;  13 / 237

    SMC_LD(a, "pattern_timer")                  ;   7 / 244
    dec a                                       ;   4 / 248
    jp nz, pattern_continue                     ;  10 / 258

    ; since this is the rare case, we can (mostly) ignore
    ; timing for this part

    SMC_LD(a, "pattern_pos")
    ; pattern table entries are 5 bytes
    add a, 5
    cp END_PATTERN_POS
    jr nz, song_continue

    ld a, PATTERN_POS_LOOP_START

song_continue:
    ld (pattern_pos), a

    ld c, a
    ld b, HIGH song_table

    ; copy pattern ptrs
    ld h, HIGH pattern_table

if (CHANNEL_A_MUTE = 0)

    ; get pattern number for channel A
    ld a, (bc)

    ; look up address of pattern in table
    ld l, a
    ld sp, hl
    pop de

    ; copy note timer
    ld a, (de)
    inc de
    ld (ch_a_note_timer), a

    ; save pattern ptr for later
    ld (ch_a_pattern_ptr), de

else

    xor a
    ld (ch_a_note_timer), a

endif

    inc c

if (CHANNEL_B_MUTE = 0)

    ; get pattern number for channel B
    ld a, (bc)

    ; look up address of pattern in table
    ld l, a
    ld sp, hl
    pop de

    ; copy note timer
    ld a, (de)
    inc de
    ld (ch_b_note_timer), a

    ; save pattern ptr for later
    ld (ch_b_pattern_ptr), de

else

    xor a
    ld (ch_b_note_timer), a

endif

    inc c

if (CHANNEL_C_MUTE = 0)

    ; get pattern number for channel C
    ld a, (bc)

    ; look up address of pattern in table
    ld l, a
    ld sp, hl
    pop de

    ; copy note timer
    ld a, (de)
    inc de
    ld (ch_c_note_timer), a

    ; save pattern ptr for later
    ld (ch_c_pattern_ptr), de

else

    xor a
    ld (ch_c_note_timer), a

endif

    inc c

    ; get pattern number for channel D
    ld a, (bc)
    inc c

    ; look up address of pattern in table
    ld l, a
    ld sp, hl
    pop de

    ; copy note timer

if (CHANNEL_D_MUTE = 0)
    ld a, (de)
else
    xor a
endif
    inc de
    ld (ch_d_note_timer), a

    ; get pattern length from channel d
    ld a, (de)
    inc de

    ; IMPORTANT
    ex af, af'

    ; save pattern ptr for later
    ld (ch_d_pattern_ptr), de

    ; get pattern number for channel E (event)
    ld a, (bc)

    ; look up address of pattern in table
    ; [TODO: since event patterns are incompatible,
    ; maybe use an alternate table for them, freeing
    ; up more song positions.]
    ld l, a
    ld sp, hl
    pop de

    ; copy event timer
    ld a, (de)
    inc de
    ld (event_timer), a

    ; save pattern ptr for later
    ld (event_pattern_ptr), de

    ; IMPORTANT
    ex af, af'

pattern_continue:                               ;     / 258 [from jump]
    ld (pattern_timer), a                       ;  13 / 271

    ; channel D code
    SMC_LD(a, "ch_d_note_timer")                ;   7 / 278
    dec a                                       ;   4 / 282
    jp nz, channel_d_skip_note                  ;  10 / 292

    ; timewasting [CAUTION!]
    ret nz                                      ;   5 / 297

    SMC_LD(hl, "ch_d_pattern_ptr")              ;  10 / 307

    ld a, (hl)  ; get note length               ;   7 / 314
    ld (ch_d_note_timer), a                     ;  13 / 327

    exx                                         ;   4 / 331
    SampleOut(36)                               ; 134 / 134
    exx                                         ;   4 / 138

    inc hl                                      ;   6 / 144

    ld a, (hl)  ; get sample number             ;   7 / 151
    inc hl                                      ;   6 / 157

    ld (ch_d_pattern_ptr), hl                   ;  16 / 173

    ld h, HIGH sample_table                     ;   7 / 180
    ld l, a                                     ;   4 / 184

    ; get sample address
    ld e, (hl)                                  ;   7 / 191
    inc hl                                      ;   6 / 197

    ld d, (hl)                                  ;   7 / 204
    inc hl                                      ;   6 / 210

    ; get sample length
    ld a, (hl)                                  ;   7 / 217

    ; save it
    ld (sample_counter), a                      ;  13 / 230

    ; timewasting (don't change sample pointer yet)
    cpi                                         ;  16 / 246
    add hl, hl                                  ;  11 / 257
    add hl, hl                                  ;  11 / 268
    add hl, hl                                  ;  11 / 279

    ld hl, write_buffer_add                     ;  10 / 289
    ld a, (hl)                                  ;   7 / 296
    xor 60 ^ -60                                ;   7 / 303
    ld (hl), a                                  ;   7 / 310

    ; a hack
    ld a, (song_timer)                          ;  13 / 323
    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(37)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; load it
    ld iy, 0                                    ;  14 / 152

ch_d_continue:                                  ;     / 152

    ; advance sample pointer
    add iy, de                                  ;  15 / 167

    ; a hack
    ex af, af'                                  ;   4 / 171
    SMC_CP("song_speed2")                       ;   7 / 178
    jp nz, hack_song_timer_continue             ;  10 / 188

    ld hl, channel_b_song_timer_no_continue     ;  10 / 198
    ld (channel_b_fm_jp), hl                    ;  16 / 214

    ld hl, channel_b_osc_song_timer_no_continue ;  10 / 224
    ld (channel_b_osc_sync_jp), hl              ;  16 / 240

    ; timewasting
    inc hl                                      ;   6 / 246
    nop                                         ;   4 / 250

hack_return:                                    ;     / 250

    ; timewasting
    inc hl                                      ;   6 / 256
    nop                                         ;   4 / 260

    exx                                         ;   4 / 264

    ld a, (write_buffer_offset)                 ;  13 / 277
    ld l, a                                     ;   4 / 281

    SMC_ADD_A("write_buffer_add")               ;   7 / 288
    ld (write_buffer_offset), a                 ;  13 / 301

    ; save channel C position
    ld (ch_c_pos), ix                           ;  20 / 321

    jp mainloop                                 ;  10 / 331

; ============================================

BEGIN_PAGE_TABLE("unison_pitch_table", false)

    ; ensure no note has the value 0
    ; (reserved for note offs)
if (LOW $) = 0
    db 0
endif

unison_pitch_table_base:

import_bin "../bin/unison_pitch_table.bin"

END_PAGE_TABLE("unison_pitch_table")

; ============================================

hack_song_timer_continue:                       ;     / 188

    ld hl, channel_b_song_timer_continue        ;  10 / 198
    ld (channel_b_fm_jp), hl                    ;  16 / 214

    ld hl, channel_b_osc_song_timer_continue    ;  10 / 224
    ld (channel_b_osc_sync_jp), hl              ;  16 / 240

    ; these branches could stay diverged to save time

    jp hack_return                              ;  10 / 250

; ============================================

channel_a_song_timer_continue:                  ;     / 315

    ; timewasting
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(2)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting
    jr $+2                                      ;  12 / 150
    jr $+2                                      ;  12 / 162

    jp channel_a_do_instrument                  ;  10 / 172

; ============================================

channel_a_note_timer_continue:                  ;     / 159

    ld (ch_a_note_timer), a                     ;  13 / 172

channel_a_do_instrument:                        ;     / 172

    SMC_LD(a, "ch_a_ins_timer")                 ;   7 / 179
    dec a                                       ;   4 / 183
    jr nz, channel_a_ins_timer_continue         ;   7 / 190 [195 taken]

    ; move to the next row of the instrument

    SMC_LD(hl, "ch_a_ins_next_ptr")             ;  10 / 200

    ; get length
    ; (use length of 0 to denote instrument end)
    ld a, (hl)                                  ;   7 / 207

    or a                                        ;   4 / 211
    jp nz, channel_a_ins_continue               ;  10 / 221

    inc hl                                      ;   6 / 227

    ; load loop pointer
    ld sp, hl                                   ;   6 / 233
    pop hl                                      ;  10 / 243

    ; get length
    ld a, (hl)                                  ;   7 / 250

channel_a_ins_return:                           ;     / 250

    ; save the new current pointer
    ld (ch_a_ins_cur_ptr), hl                   ;  16 / 266

    ; set new timer value
    ld (ch_a_ins_timer), a                      ;  13 / 279

    inc hl                                      ;   6 / 285

    ; load waveforms

    ; load carrier
    ld d, (hl)                                  ;   7 / 292
    inc hl                                      ;   6 / 298

    ; load mod
    ld b, (hl)                                  ;   7 / 305
    inc hl                                      ;   6 / 311

    ; save instrument pointer (and update current)
    ld (ch_a_ins_next_ptr), hl                  ;  16 / 327

    exx                                         ;   4 / 331
    SampleOut(3)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting [CAREFUL!]
    ld sp, hl                                   ;   6 / 144
    ex (sp), hl                                 ;  19 / 163
    ex (sp), hl                                 ;  19 / 182
    add hl, hl                                  ;  11 / 193
    add hl, hl                                  ;  11 / 204
    inc hl                                      ;   6 / 210

    SMC_LD(sp, "ch_a_note")                     ;  10 / 220

    jp channel_a_do_samplegen                   ;  10 / 230

; ============================================

    ; remain on the same instrument row
channel_a_ins_timer_continue:                   ;     / 195

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 200
    add hl, hl                                  ;  11 / 211

    SMC_LD(hl, "ch_a_ins_cur_ptr")              ;  10 / 221

channel_a_ins_continue:                         ;     / 221

    ; timewasting (make sure to preserve A)
    add ix, ix                                  ;  15 / 236
    nop                                         ;   4 / 240

    jp channel_a_ins_return                     ;  10 / 250

; ============================================

channel_b_note_timer_continue:                  ;     / 156

    ld (ch_b_note_timer), a                     ;  13 / 169

channel_b_do_instrument:                        ;     / 169

    SMC_LD(a, "ch_b_ins_timer")                 ;   7 / 176
    dec a                                       ;   4 / 180
    jr nz, channel_b_ins_timer_continue         ;   7 / 187 [192 taken]

    ; move to the next row of the instrument

    SMC_LD(hl, "ch_b_ins_next_ptr")             ;  10 / 197

    ; get length
    ; (use a length of 0 to denote instrument end)
    ld a, (hl)                                  ;   7 / 204

    or a                                        ;   4 / 208
    jr nz, channel_b_ins_continue               ;   7 / 215 [220 taken]

    inc hl                                      ;   6 / 221

    ; load loop pointer
    ld sp, hl                                   ;   6 / 227
    pop hl                                      ;  10 / 237

    ; get length
    ld a, (hl)                                  ;   7 / 244

channel_b_ins_return:                           ;     / 244

    ; save the new current pointer
    ld (ch_b_ins_cur_ptr), hl                   ;  16 / 260

    inc hl                                      ;   6 / 266

    ; set new timer value
    ld (ch_b_ins_timer), a                      ;  13 / 279

    ; load waveforms

    ; load carrier
    ld d, (hl)                                  ;   7 / 286
    inc hl                                      ;   6 / 292

    ; load mod
    ld b, (hl)                                  ;   7 / 299
    inc hl                                      ;   6 / 305

    ; save instrument pointer (and update current)
    ld (ch_b_ins_next_ptr), hl                  ;  16 / 321

    ; timewasting
    dec hl                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting [CAREFUL!]
    ld sp, hl                                   ;   6 / 144
    ex (sp), hl                                 ;  19 / 163
    ex (sp), hl                                 ;  19 / 182
    add hl, hl                                  ;  11 / 193
    inc hl                                      ;   6 / 199
    nop                                         ;   4 / 203

    ld sp, (ch_b_note)                          ;  20 / 223

    jp channel_b_do_samplegen                   ;  10 / 233

; ============================================

    ; remain on the same instrument row
channel_b_ins_timer_continue:                   ;     / 192

    ; timewasting
    add hl, hl                                  ;  11 / 203

    SMC_LD(hl, "ch_b_ins_cur_ptr")              ;  10 / 213

    ; timewasting
    cp (hl)                                     ;   7 / 220

channel_b_ins_continue:                         ;     / 220

    ; timewasting (make sure to preserve A)
    cp (hl)                                     ;   7 / 227
    cp (hl)                                     ;   7 / 234

    jp channel_b_ins_return                     ;  10 / 244

; ============================================

channel_c_note_timer_continue:                  ;     / 269

    ld (ch_c_note_timer), a                     ;  13 / 282

channel_c_do_instrument:                        ;     / 282

    SMC_LD(a, "ch_c_ins_timer")                 ;   7 / 289
    dec a                                       ;   4 / 293
    jr nz, channel_c_ins_timer_continue         ;   7 / 300 [305 taken]

    ; move to the next row of the instrument

    SMC_LD(hl, "ch_c_ins_next_ptr")             ;  10 / 310

    ; get length
    ; (use a length of 0 to denote instrument end)
    ld a, (hl)                                  ;   7 / 317
    inc hl                                      ;   6 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(14)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    or a                                        ;   4 / 146
    jp nz, channel_c_ins_continue               ;  10 / 156

    ; load loop pointer
    ld sp, hl                                   ;   6 / 162
    pop hl                                      ;  10 / 172

    ; get length
    ld a, (hl)                                  ;   7 / 179

channel_c_ins_return:                           ;     / 179

    ; save the new current pointer
    ld (ch_c_ins_cur_ptr), hl                   ;  16 / 195

    inc hl                                      ;   6 / 201

    ; set new timer value
    ld (ch_c_ins_timer), a                      ;  13 / 214

    ; load waveforms

    ; load carrier
    ld d, (hl)                                  ;   7 / 221

    ; timewasting & inc hl
    cpi                                         ;  16 / 237

    ; load mod
    ld b, (hl)                                  ;   7 / 244
    inc hl                                      ;   6 / 250

    ; save instrument pointer (and update current)
    ld (ch_c_ins_next_ptr), hl                  ;  16 / 266

    ; timewasting [CAREFUL!]
    ld sp, hl                                   ;   6 / 272
    ex (sp), hl                                 ;  19 / 291
    ex (sp), hl                                 ;  19 / 310
    add hl, hl                                  ;  11 / 321
    inc hl                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    SMC_LD(sp, "ch_c_note")                     ;  10 / 148

    ; timewasting
    inc hl                                      ;   6 / 154

    jp channel_c_do_samplegen                   ;  10 / 164

; ============================================

    ; remain on the same instrument row
channel_c_ins_timer_continue:                   ;     / 305

    SMC_LD(hl, "ch_c_ins_cur_ptr")              ;  10 / 315

    ; timewasting
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(14)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting
    jr $+2                                      ;  12 / 150

    inc hl                                      ;   6 / 156

channel_c_ins_continue:                         ;     / 156

    ; we accidentally incremented HL just now (oops)
    ; so let's undo that
    dec hl                                      ;   6 / 162

    ; timewasting (make sure to preserve A)
    cp (hl)                                     ;   7 / 169

    jp channel_c_ins_return                     ;  10 / 179

; ============================================

channel_d_skip_note:                            ;     / 292

    ld (ch_d_note_timer), a                     ;  13 / 305

channel_d_continue:                             ;     / 305

    ; timewasting
    inc de                                      ;   6 / 311

    ; load sample pointer
    ld d, iyh                                   ;   8 / 319
    ld e, iyl                                   ;   8 / 327

    exx                                         ;   4 / 331
    SampleOut(36)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; amount to advance sample pointer
    ld hl, 60-(36-14)                           ;  10 / 148

    SMC_LD(a, "sample_counter")                 ;   7 / 155
    dec a                                       ;   4 / 159

    jp nz, update_sample_counter_skip           ;  10 / 169

    ; reset carry flag
    add a, 1                                    ;   7 / 176
    ld hl, empty_sample_def                     ;  10 / 186

    sbc hl, de                                  ;  15 / 201

update_sample_counter:                          ;     / 201

    ld (sample_counter), a                      ;  13 / 214

    ; load sample pointer back into DE
    ex de, hl                                   ;   4 / 218

    ld hl, write_buffer_add                     ;  10 / 228
    ld a, (hl)                                  ;   7 / 235
    xor 60 ^ -60                                ;   7 / 242
    ld (hl), a                                  ;   7 / 249

    ; a hack
    ld a, (song_timer)                          ;  13 / 262
    ex af, af'                                  ;   4 / 266

    ; timewasting [CAREFUL!]
    cp (hl)                                     ;   7 / 273
    ld sp, hl                                   ;   6 / 279
    ex (sp), hl                                 ;  19 / 298
    ex (sp), hl                                 ;  19 / 317
    pop hl                                      ;  10 / 327

    exx                                         ;   4 / 331
    SampleOut(37)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting
    nop                                         ;   4 / 142

    jp ch_d_continue                            ;  10 / 152

; ============================================

update_sample_counter_skip:                     ;     / 169

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 174
    ret z                                       ;   5 / 179
    jr $+2                                      ;  12 / 191

    jp update_sample_counter                    ;  10 / 201

; ============================================

channel_a_reset_pos:                            ;     / 251

    ; we know A = 0

    ; timewasting [CAUTION!]
    ret nz                                      ;   5 / 256

    ld h, a                                     ;   4 / 260
    ld l, a                                     ;   4 / 264

    inc a                                       ;   4 / 268
    ld (ch_a_ins_timer), a                      ;  13 / 281

    ld (ch_a_pos), hl                           ;  16 / 297

    ld (ch_a_note), hl                          ;  16 / 313

    ; Set up the empty instrument.
    ld b, EMPTY_INS_MOD                         ;   7 / 320

    ld d, EMPTY_INS_CARRIER                     ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(3)                                ; 134 / 134
    exx                                         ;   4 / 138

    ld sp, hl                                   ;   6 / 144

    ld hl, empty_instrument                     ;  10 / 154
    ld (ch_a_ins_next_ptr), hl                  ;  16 / 170

    ; timewasting (SP points to ROM)
    ex (sp), hl                                 ;  19 / 189
    ex (sp), hl                                 ;  19 / 208
    jr $+2                                      ;  12 / 220

    jp channel_a_do_samplegen                   ;  10 / 230

; ============================================

song_timer_continue:                            ;     / 217

    ld (song_timer), a                          ;  13 / 230

    ; timewasting [CAREFUL!]
    ld sp, hl                                   ;   6 / 236
    ex (sp), hl                                 ;  19 / 255
    ex (sp), hl                                 ;  19 / 274
    add hl, hl                                  ;  11 / 285
    inc hl                                      ;   6 / 291
    nop                                         ;   4 / 295

    jp channel_d_continue                       ;  10 / 305

; ============================================

channel_b_osc_reset_pos:                        ;     / 250

    ; we know A = 0

    ld h, a                                     ;   4 / 254
    ld l, a                                     ;   4 / 258

    inc a                                       ;   4 / 262
    ld (ch_b_osc_ins_timer), a                  ;  13 / 275

    ld (ch_b_pos), hl                           ;  16 / 291
    ld (ch_b_note), hl                          ;  16 / 307
    ld sp, hl                                   ;   6 / 313

    ; Set up the empty instrument.

    ld d, EMPTY_INS_CARRIER                     ;   7 / 320

    ; timewasting
    cp (hl)                                     ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    ld hl, empty_instrument_osc_sync            ;  10 / 148
    ld (ch_b_osc_ins_next_ptr), hl              ;  16 / 164

    ; timewasting (SP points to ROM)
    ex (sp), hl                                 ;  19 / 183
    ex (sp), hl                                 ;  19 / 202

    jp channel_b_osc_do_samplegen               ;     / 212

; ============================================

    ; prepare for Osc. Sync generation
    ;
    ;  C = carrier pitch
    ; DE = waveform
    ; HL = write buffer
    ; IX = counter
    ; SP = pitch

    ; Note: we get these variables from the existing FM instead
    ; of creating new ones. Otherwise we would have to redirect
    ; channel D pattern code to use them, and switching
    ; samplegen type might go wrong unless we copy over the
    ; old value (assuming we didn't switch from the same type
    ; to itself)

channel_b_osc_sync_setup:                       ;     / 300

    SMC_JP("channel_b_osc_sync_jp")             ;  10 / 310

; ============================================

channel_b_osc_song_timer_no_continue:           ;     / 310

    ld a, (ch_b_note_timer)                     ;  13 / 323

    ; save timer and flags
    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(14)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; restore timer and flags
    ex af, af'                                  ;   4 / 142

    dec a                                       ;   4 / 146
    jp nz, channel_b_note_timer_osc_continue    ;  10 / 156

    SMC_LD(hl, "ch_b_pattern_ptr")              ;  10 / 166

    ld a, (hl)  ; get note length               ;   7 / 173
    inc hl                                      ;   6 / 179
    ld (ch_b_note_timer), a                     ;  13 / 192

    ld a, (hl)  ; get note value                ;   7 / 199
    inc hl                                      ;   6 / 205

    ld (ch_b_pattern_ptr), hl                   ;  16 / 221

    ; save note value
    ld (ch_b_note_value), a                     ;  13 / 234

    or a                                        ;   4 / 238
    jr z, channel_b_osc_reset_pos               ;   7 / 245 [250 taken]

    ; add ornament
    SMC_ADD_A("ch_b_orn_initial2")              ;   7 / 252

    ; look up note pitch
    ld h, HIGH pitch_table                      ;   7 / 259
    ld l, a                                     ;   4 / 263

    ld sp, hl                                   ;   6 / 269
    pop hl                                      ;  10 / 279

    ; add pitch bend
    SMC_LD(de, "ch_b_bend_accum2")              ;  10 / 289
    add hl, de                                  ;  11 / 300

    SMC_LD(d, "ch_b_osc_wave_initial")          ;   7 / 307

    SMC_LD(a, "ch_b_osc_ins_timer_initial")     ;   7 / 314
    ld (ch_b_osc_ins_timer), a                  ;  13 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    ld sp, hl                                   ;   6 / 144
    ld (ch_b_note), hl                          ;  16 / 160

    ; restart ornament
    SMC_LD(hl, "ch_b_orn_ptr_initial2")         ;  10 / 170
    ld (ch_b_orn_ptr), hl                       ;  16 / 186

    ; restart instrument
    SMC_LD(hl, "ch_b_osc_ins_initial")          ;  10 / 196
    ld (ch_b_osc_ins_cur_ptr), hl               ;  16 / 212

channel_b_osc_do_samplegen:                     ;     / 212

    SMC_LD(ix, "ch_b_pos")                      ;  14 / 226

    SMC_LD(hl, "ch_b_osc_sync_bend")            ;  10 / 236
    SMC_LD(bc, "ch_b_osc_sync_pitch")           ;  10 / 246

    add hl, bc                                  ;  11 / 257

    ld (ch_b_osc_sync_pitch), hl                ;  16 / 273

    ; NOTE - this value should be kept stable
    ; (not changed unless necessary), as it is
    ; used to maintain the phase position.
    SMC_LD(e, "ch_b_osc_sync_pos")              ;   7 / 280

    ; timewasting
    add hl, hl                                  ;  11 / 291
    add hl, hl                                  ;  11 / 302
    ld a, r                                     ;   9 / 311

    ld hl, (write_buffer_offset)                ;  16 / 327

    exx                                         ;   4 / 331
    SampleOut(16)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; samplegen

    ; sample 0
    add ix, sp                                  ;  15 / 153
    sbc a, a                                    ;   4 / 157
    and e                                       ;   4 / 161
    add a, b                                    ;   4 / 165
    ld e, a                                     ;   4 / 169
    ld a, (de)                                  ;   7 / 176
    add a, (hl)                                 ;   7 / 183
    ld (hl), a                                  ;   7 / 190
    inc l                                       ;   4 / 194

    ; sample 1
    add ix, sp                                  ;  15 / 209
    sbc a, a                                    ;   4 / 213
    and e                                       ;   4 / 217
    add a, b                                    ;   4 / 221
    ld e, a                                     ;   4 / 225
    ld a, (de)                                  ;   7 / 232
    add a, (hl)                                 ;   7 / 239
    ld (hl), a                                  ;   7 / 246
    inc l                                       ;   4 / 250

    ; sample 2
    add ix, sp                                  ;  15 / 265
    sbc a, a                                    ;   4 / 269
    and e                                       ;   4 / 273
    add a, b                                    ;   4 / 277
    ld e, a                                     ;   4 / 281
    ld a, (de)                                  ;   7 / 288
    add a, (hl)                                 ;   7 / 295
    ld (hl), a                                  ;   7 / 302
    inc hl                                      ;   6 / 308

    ; sample 3
    add ix, sp                                  ;  15 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(17)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ; sample 3 cont.
    sbc a, a                                    ;   4 / 146
    and e                                       ;   4 / 150
    add a, b                                    ;   4 / 154
    ld e, a                                     ;   4 / 158
    ld a, (de)                                  ;   7 / 165
    add a, (hl)                                 ;   7 / 172
    ld (hl), a                                  ;   7 / 179
    inc l                                       ;   4 / 183

    ; sample 4
    add ix, sp                                  ;  15 / 198
    sbc a, a                                    ;   4 / 202
    and e                                       ;   4 / 206
    add a, b                                    ;   4 / 210
    ld e, a                                     ;   4 / 214
    ld a, (de)                                  ;   7 / 221
    add a, (hl)                                 ;   7 / 228
    ld (hl), a                                  ;   7 / 235
    inc l                                       ;   4 / 239

    ; sample 5
    add ix, sp                                  ;  15 / 254
    sbc a, a                                    ;   4 / 258
    and e                                       ;   4 / 262
    add a, b                                    ;   4 / 266
    ld e, a                                     ;   4 / 270
    ld a, (de)                                  ;   7 / 277
    add a, (hl)                                 ;   7 / 284
    ld (hl), a                                  ;   7 / 291
    inc l                                       ;   4 / 295

    ; sample 6
    add ix, sp                                  ;  15 / 310
    sbc a, a                                    ;   4 / 314
    and e                                       ;   4 / 318

    ; timewasting [CAUTION!]
    ret c                                       ;   5 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(18)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ; sample 6 cont.
    add a, b                                    ;   4 / 146
    ld e, a                                     ;   4 / 150
    ld a, (de)                                  ;   7 / 157
    add a, (hl)                                 ;   7 / 164
    ld (hl), a                                  ;   7 / 171
    inc l                                       ;   4 / 175

    ; sample 7
    add ix, sp                                  ;  15 / 190
    sbc a, a                                    ;   4 / 194
    and e                                       ;   4 / 198
    add a, b                                    ;   4 / 202
    ld e, a                                     ;   4 / 206
    ld a, (de)                                  ;   7 / 213
    add a, (hl)                                 ;   7 / 220
    ld (hl), a                                  ;   7 / 227
    inc l                                       ;   4 / 231

    ; sample 8
    add ix, sp                                  ;  15 / 246
    sbc a, a                                    ;   4 / 250
    and e                                       ;   4 / 254
    add a, b                                    ;   4 / 258
    ld e, a                                     ;   4 / 262
    ld a, (de)                                  ;   7 / 269
    add a, (hl)                                 ;   7 / 276
    ld (hl), a                                  ;   7 / 283
    inc l                                       ;   4 / 287

    ; sample 9
    add ix, sp                                  ;  15 / 302
    sbc a, a                                    ;   4 / 306
    and e                                       ;   4 / 310
    add a, b                                    ;   4 / 314
    ld e, a                                     ;   4 / 318

    ; timewasting
    ld a, r                                     ;   9 / 327

    exx                                         ;   4 / 331
    SampleOut(19)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 9 cont.
    ld a, (de)                                  ;   7 / 145
    add a, (hl)                                 ;   7 / 152
    ld (hl), a                                  ;   7 / 159
    inc l                                       ;   4 / 163

    ; sample 10
    add ix, sp                                  ;  15 / 178
    sbc a, a                                    ;   4 / 182
    and e                                       ;   4 / 186
    add a, b                                    ;   4 / 190
    ld e, a                                     ;   4 / 194
    ld a, (de)                                  ;   7 / 201
    add a, (hl)                                 ;   7 / 208
    ld (hl), a                                  ;   7 / 215
    inc l                                       ;   4 / 219

    ; sample 11
    add ix, sp                                  ;  15 / 234
    sbc a, a                                    ;   4 / 238
    and e                                       ;   4 / 242
    add a, b                                    ;   4 / 246
    ld e, a                                     ;   4 / 250
    ld a, (de)                                  ;   7 / 257
    add a, (hl)                                 ;   7 / 264
    ld (hl), a                                  ;   7 / 271
    inc l                                       ;   4 / 275

    ; sample 12
    add ix, sp                                  ;  15 / 290
    sbc a, a                                    ;   4 / 294
    and e                                       ;   4 / 298
    add a, b                                    ;   4 / 302
    ld e, a                                     ;   4 / 306
    ld a, (de)                                  ;   7 / 313
    add a, (hl)                                 ;   7 / 320
    ld (hl), a                                  ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(20)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 12 cont.
    inc l                                       ;   4 / 142

    ; sample 13
    add ix, sp                                  ;  15 / 157
    sbc a, a                                    ;   4 / 161
    and e                                       ;   4 / 165
    add a, b                                    ;   4 / 169
    ld e, a                                     ;   4 / 173
    ld a, (de)                                  ;   7 / 180
    add a, (hl)                                 ;   7 / 187
    ld (hl), a                                  ;   7 / 194
    inc l                                       ;   4 / 198

    ; sample 14
    add ix, sp                                  ;  15 / 213
    sbc a, a                                    ;   4 / 217
    and e                                       ;   4 / 221
    add a, b                                    ;   4 / 225
    ld e, a                                     ;   4 / 229
    ld a, (de)                                  ;   7 / 236
    add a, (hl)                                 ;   7 / 243
    ld (hl), a                                  ;   7 / 250
    inc l                                       ;   4 / 254

    ; sample 15
    add ix, sp                                  ;  15 / 269
    sbc a, a                                    ;   4 / 273
    and e                                       ;   4 / 277
    add a, b                                    ;   4 / 281
    ld e, a                                     ;   4 / 285
    ld a, (de)                                  ;   7 / 292
    add a, (hl)                                 ;   7 / 299
    ld (hl), a                                  ;   7 / 306
    inc l                                       ;   4 / 310

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 315
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(21)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 16
    add ix, sp                                  ;  15 / 153
    sbc a, a                                    ;   4 / 157
    and e                                       ;   4 / 161
    add a, b                                    ;   4 / 165
    ld e, a                                     ;   4 / 169
    ld a, (de)                                  ;   7 / 176
    add a, (hl)                                 ;   7 / 183
    ld (hl), a                                  ;   7 / 190
    inc l                                       ;   4 / 194

    ; sample 17
    add ix, sp                                  ;  15 / 209
    sbc a, a                                    ;   4 / 213
    and e                                       ;   4 / 217
    add a, b                                    ;   4 / 221
    ld e, a                                     ;   4 / 225
    ld a, (de)                                  ;   7 / 232
    add a, (hl)                                 ;   7 / 239
    ld (hl), a                                  ;   7 / 246
    inc l                                       ;   4 / 250

    ; sample 18
    add ix, sp                                  ;  15 / 265
    sbc a, a                                    ;   4 / 269
    and e                                       ;   4 / 273
    add a, b                                    ;   4 / 277
    ld e, a                                     ;   4 / 281
    ld a, (de)                                  ;   7 / 288
    add a, (hl)                                 ;   7 / 295
    ld (hl), a                                  ;   7 / 302
    inc hl                                      ;   6 / 308

    ; sample 19
    add ix, sp                                  ;  15 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(22)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ; sample 19 cont.
    sbc a, a                                    ;   4 / 146
    and e                                       ;   4 / 150
    add a, b                                    ;   4 / 154
    ld e, a                                     ;   4 / 158
    ld a, (de)                                  ;   7 / 165
    add a, (hl)                                 ;   7 / 172
    ld (hl), a                                  ;   7 / 179
    inc l                                       ;   4 / 183

    ; sample 20
    add ix, sp                                  ;  15 / 198
    sbc a, a                                    ;   4 / 202
    and e                                       ;   4 / 206
    add a, b                                    ;   4 / 210
    ld e, a                                     ;   4 / 214
    ld a, (de)                                  ;   7 / 221
    add a, (hl)                                 ;   7 / 228
    ld (hl), a                                  ;   7 / 235
    inc l                                       ;   4 / 239

    ; sample 21
    add ix, sp                                  ;  15 / 254
    sbc a, a                                    ;   4 / 258
    and e                                       ;   4 / 262
    add a, b                                    ;   4 / 266
    ld e, a                                     ;   4 / 270
    ld a, (de)                                  ;   7 / 277
    add a, (hl)                                 ;   7 / 284
    ld (hl), a                                  ;   7 / 291
    inc l                                       ;   4 / 295

    ; sample 22
    add ix, sp                                  ;  15 / 310
    sbc a, a                                    ;   4 / 314
    and e                                       ;   4 / 318

    ; timewasting [CAUTION!]
    ret c                                       ;   5 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(23)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ; sample 22 cont.
    add a, b                                    ;   4 / 146
    ld e, a                                     ;   4 / 150
    ld a, (de)                                  ;   7 / 157
    add a, (hl)                                 ;   7 / 164
    ld (hl), a                                  ;   7 / 171
    inc l                                       ;   4 / 175

    ; sample 23
    add ix, sp                                  ;  15 / 190
    sbc a, a                                    ;   4 / 194
    and e                                       ;   4 / 198
    add a, b                                    ;   4 / 202
    ld e, a                                     ;   4 / 206
    ld a, (de)                                  ;   7 / 213
    add a, (hl)                                 ;   7 / 220
    ld (hl), a                                  ;   7 / 227
    inc l                                       ;   4 / 231

    ; sample 24
    add ix, sp                                  ;  15 / 246
    sbc a, a                                    ;   4 / 250
    and e                                       ;   4 / 254
    add a, b                                    ;   4 / 258
    ld e, a                                     ;   4 / 262
    ld a, (de)                                  ;   7 / 269
    add a, (hl)                                 ;   7 / 276
    ld (hl), a                                  ;   7 / 283
    inc l                                       ;   4 / 287

    ; sample 25
    add ix, sp                                  ;  15 / 302
    sbc a, a                                    ;   4 / 306
    and e                                       ;   4 / 310
    add a, b                                    ;   4 / 314
    ld e, a                                     ;   4 / 318

    ; timewasting
    ld a, r                                     ;   9 / 327

    exx                                         ;   4 / 331
    SampleOut(24)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 25 cont.
    ld a, (de)                                  ;   7 / 145
    add a, (hl)                                 ;   7 / 152
    ld (hl), a                                  ;   7 / 159
    inc l                                       ;   4 / 163

    ; sample 26
    add ix, sp                                  ;  15 / 178
    sbc a, a                                    ;   4 / 182
    and e                                       ;   4 / 186
    add a, b                                    ;   4 / 190
    ld e, a                                     ;   4 / 194
    ld a, (de)                                  ;   7 / 201
    add a, (hl)                                 ;   7 / 208
    ld (hl), a                                  ;   7 / 215
    inc l                                       ;   4 / 219

    ; sample 27
    add ix, sp                                  ;  15 / 234
    sbc a, a                                    ;   4 / 238
    and e                                       ;   4 / 242
    add a, b                                    ;   4 / 246
    ld e, a                                     ;   4 / 250
    ld a, (de)                                  ;   7 / 257
    add a, (hl)                                 ;   7 / 264
    ld (hl), a                                  ;   7 / 271
    inc l                                       ;   4 / 275

    ; sample 28
    add ix, sp                                  ;  15 / 290
    sbc a, a                                    ;   4 / 294
    and e                                       ;   4 / 298
    add a, b                                    ;   4 / 302
    ld e, a                                     ;   4 / 306
    ld a, (de)                                  ;   7 / 313
    add a, (hl)                                 ;   7 / 320
    ld (hl), a                                  ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(25)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 28 cont.
    inc l                                       ;   4 / 142

    ; sample 29
    add ix, sp                                  ;  15 / 157
    sbc a, a                                    ;   4 / 161
    and e                                       ;   4 / 165
    add a, b                                    ;   4 / 169
    ld e, a                                     ;   4 / 173
    ld a, (de)                                  ;   7 / 180
    add a, (hl)                                 ;   7 / 187
    ld (hl), a                                  ;   7 / 194
    inc l                                       ;   4 / 198

    ; sample 30
    add ix, sp                                  ;  15 / 213
    sbc a, a                                    ;   4 / 217
    and e                                       ;   4 / 221
    add a, b                                    ;   4 / 225
    ld e, a                                     ;   4 / 229
    ld a, (de)                                  ;   7 / 236
    add a, (hl)                                 ;   7 / 243
    ld (hl), a                                  ;   7 / 250
    inc l                                       ;   4 / 254

    ; sample 31
    add ix, sp                                  ;  15 / 269
    sbc a, a                                    ;   4 / 273
    and e                                       ;   4 / 277
    add a, b                                    ;   4 / 281
    ld e, a                                     ;   4 / 285
    ld a, (de)                                  ;   7 / 292
    add a, (hl)                                 ;   7 / 299
    ld (hl), a                                  ;   7 / 306
    inc l                                       ;   4 / 310

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 315
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(26)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 32
    add ix, sp                                  ;  15 / 153
    sbc a, a                                    ;   4 / 157
    and e                                       ;   4 / 161
    add a, b                                    ;   4 / 165
    ld e, a                                     ;   4 / 169
    ld a, (de)                                  ;   7 / 176
    add a, (hl)                                 ;   7 / 183
    ld (hl), a                                  ;   7 / 190
    inc l                                       ;   4 / 194

    ; sample 33
    add ix, sp                                  ;  15 / 209
    sbc a, a                                    ;   4 / 213
    and e                                       ;   4 / 217
    add a, b                                    ;   4 / 221
    ld e, a                                     ;   4 / 225
    ld a, (de)                                  ;   7 / 232
    add a, (hl)                                 ;   7 / 239
    ld (hl), a                                  ;   7 / 246
    inc l                                       ;   4 / 250

    ; sample 34
    add ix, sp                                  ;  15 / 265
    sbc a, a                                    ;   4 / 269
    and e                                       ;   4 / 273
    add a, b                                    ;   4 / 277
    ld e, a                                     ;   4 / 281
    ld a, (de)                                  ;   7 / 288
    add a, (hl)                                 ;   7 / 295
    ld (hl), a                                  ;   7 / 302
    inc hl                                      ;   6 / 308

    ; sample 35
    add ix, sp                                  ;  15 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(27)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ; sample 35 cont.
    sbc a, a                                    ;   4 / 146
    and e                                       ;   4 / 150
    add a, b                                    ;   4 / 154
    ld e, a                                     ;   4 / 158
    ld a, (de)                                  ;   7 / 165
    add a, (hl)                                 ;   7 / 172
    ld (hl), a                                  ;   7 / 179
    inc l                                       ;   4 / 183

    ; sample 36
    add ix, sp                                  ;  15 / 198
    sbc a, a                                    ;   4 / 202
    and e                                       ;   4 / 206
    add a, b                                    ;   4 / 210
    ld e, a                                     ;   4 / 214
    ld a, (de)                                  ;   7 / 221
    add a, (hl)                                 ;   7 / 228
    ld (hl), a                                  ;   7 / 235
    inc l                                       ;   4 / 239

    ; sample 37
    add ix, sp                                  ;  15 / 254
    sbc a, a                                    ;   4 / 258
    and e                                       ;   4 / 262
    add a, b                                    ;   4 / 266
    ld e, a                                     ;   4 / 270
    ld a, (de)                                  ;   7 / 277
    add a, (hl)                                 ;   7 / 284
    ld (hl), a                                  ;   7 / 291
    inc l                                       ;   4 / 295

    ; sample 38
    add ix, sp                                  ;  15 / 310
    sbc a, a                                    ;   4 / 314
    and e                                       ;   4 / 318

    ; timewasting [CAUTION!]
    ret c                                       ;   5 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(28)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ; sample 38 cont.
    add a, b                                    ;   4 / 146
    ld e, a                                     ;   4 / 150
    ld a, (de)                                  ;   7 / 157
    add a, (hl)                                 ;   7 / 164
    ld (hl), a                                  ;   7 / 171
    inc l                                       ;   4 / 175

    ; sample 39
    add ix, sp                                  ;  15 / 190
    sbc a, a                                    ;   4 / 194
    and e                                       ;   4 / 198
    add a, b                                    ;   4 / 202
    ld e, a                                     ;   4 / 206
    ld a, (de)                                  ;   7 / 213
    add a, (hl)                                 ;   7 / 220
    ld (hl), a                                  ;   7 / 227
    inc l                                       ;   4 / 231

    ; sample 40
    add ix, sp                                  ;  15 / 246
    sbc a, a                                    ;   4 / 250
    and e                                       ;   4 / 254
    add a, b                                    ;   4 / 258
    ld e, a                                     ;   4 / 262
    ld a, (de)                                  ;   7 / 269
    add a, (hl)                                 ;   7 / 276
    ld (hl), a                                  ;   7 / 283
    inc l                                       ;   4 / 287

    ; sample 41
    add ix, sp                                  ;  15 / 302
    sbc a, a                                    ;   4 / 306
    and e                                       ;   4 / 310
    add a, b                                    ;   4 / 314
    ld e, a                                     ;   4 / 318

    ; timewasting
    ld a, r                                     ;   9 / 327

    exx                                         ;   4 / 331
    SampleOut(29)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 41 cont.
    ld a, (de)                                  ;   7 / 145
    add a, (hl)                                 ;   7 / 152
    ld (hl), a                                  ;   7 / 159
    inc l                                       ;   4 / 163

    ; sample 42
    add ix, sp                                  ;  15 / 178
    sbc a, a                                    ;   4 / 182
    and e                                       ;   4 / 186
    add a, b                                    ;   4 / 190
    ld e, a                                     ;   4 / 194
    ld a, (de)                                  ;   7 / 201
    add a, (hl)                                 ;   7 / 208
    ld (hl), a                                  ;   7 / 215
    inc l                                       ;   4 / 219

    ; sample 43
    add ix, sp                                  ;  15 / 234
    sbc a, a                                    ;   4 / 238
    and e                                       ;   4 / 242
    add a, b                                    ;   4 / 246
    ld e, a                                     ;   4 / 250
    ld a, (de)                                  ;   7 / 257
    add a, (hl)                                 ;   7 / 264
    ld (hl), a                                  ;   7 / 271
    inc l                                       ;   4 / 275

    ; sample 44
    add ix, sp                                  ;  15 / 290
    sbc a, a                                    ;   4 / 294
    and e                                       ;   4 / 298
    add a, b                                    ;   4 / 302
    ld e, a                                     ;   4 / 306
    ld a, (de)                                  ;   7 / 313
    add a, (hl)                                 ;   7 / 320
    ld (hl), a                                  ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(30)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 44 cont.
    inc l                                       ;   4 / 142

    ; sample 45
    add ix, sp                                  ;  15 / 157
    sbc a, a                                    ;   4 / 161
    and e                                       ;   4 / 165
    add a, b                                    ;   4 / 169
    ld e, a                                     ;   4 / 173
    ld a, (de)                                  ;   7 / 180
    add a, (hl)                                 ;   7 / 187
    ld (hl), a                                  ;   7 / 194
    inc l                                       ;   4 / 198

    ; sample 46
    add ix, sp                                  ;  15 / 213
    sbc a, a                                    ;   4 / 217
    and e                                       ;   4 / 221
    add a, b                                    ;   4 / 225
    ld e, a                                     ;   4 / 229
    ld a, (de)                                  ;   7 / 236
    add a, (hl)                                 ;   7 / 243
    ld (hl), a                                  ;   7 / 250
    inc l                                       ;   4 / 254

    ; sample 47
    add ix, sp                                  ;  15 / 269
    sbc a, a                                    ;   4 / 273
    and e                                       ;   4 / 277
    add a, b                                    ;   4 / 281
    ld e, a                                     ;   4 / 285
    ld a, (de)                                  ;   7 / 292
    add a, (hl)                                 ;   7 / 299
    ld (hl), a                                  ;   7 / 306
    inc l                                       ;   4 / 310

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 315
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(31)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 48
    add ix, sp                                  ;  15 / 153
    sbc a, a                                    ;   4 / 157
    and e                                       ;   4 / 161
    add a, b                                    ;   4 / 165
    ld e, a                                     ;   4 / 169
    ld a, (de)                                  ;   7 / 176
    add a, (hl)                                 ;   7 / 183
    ld (hl), a                                  ;   7 / 190
    inc l                                       ;   4 / 194

    ; sample 49
    add ix, sp                                  ;  15 / 209
    sbc a, a                                    ;   4 / 213
    and e                                       ;   4 / 217
    add a, b                                    ;   4 / 221
    ld e, a                                     ;   4 / 225
    ld a, (de)                                  ;   7 / 232
    add a, (hl)                                 ;   7 / 239
    ld (hl), a                                  ;   7 / 246
    inc l                                       ;   4 / 250

    ; sample 50
    add ix, sp                                  ;  15 / 265
    sbc a, a                                    ;   4 / 269
    and e                                       ;   4 / 273
    add a, b                                    ;   4 / 277
    ld e, a                                     ;   4 / 281
    ld a, (de)                                  ;   7 / 288
    add a, (hl)                                 ;   7 / 295
    ld (hl), a                                  ;   7 / 302
    inc hl                                      ;   6 / 308

    ; sample 51
    add ix, sp                                  ;  15 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(32)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ; sample 51 cont.
    sbc a, a                                    ;   4 / 146
    and e                                       ;   4 / 150
    add a, b                                    ;   4 / 154
    ld e, a                                     ;   4 / 158
    ld a, (de)                                  ;   7 / 165
    add a, (hl)                                 ;   7 / 172
    ld (hl), a                                  ;   7 / 179
    inc l                                       ;   4 / 183

    ; sample 52
    add ix, sp                                  ;  15 / 198
    sbc a, a                                    ;   4 / 202
    and e                                       ;   4 / 206
    add a, b                                    ;   4 / 210
    ld e, a                                     ;   4 / 214
    ld a, (de)                                  ;   7 / 221
    add a, (hl)                                 ;   7 / 228
    ld (hl), a                                  ;   7 / 235
    inc l                                       ;   4 / 239

    ; sample 53
    add ix, sp                                  ;  15 / 254
    sbc a, a                                    ;   4 / 258
    and e                                       ;   4 / 262
    add a, b                                    ;   4 / 266
    ld e, a                                     ;   4 / 270
    ld a, (de)                                  ;   7 / 277
    add a, (hl)                                 ;   7 / 284
    ld (hl), a                                  ;   7 / 291
    inc l                                       ;   4 / 295

    ; sample 54
    add ix, sp                                  ;  15 / 310
    sbc a, a                                    ;   4 / 314
    and e                                       ;   4 / 318

    ; timewasting [CAUTION!]
    ret c                                       ;   5 / 323

    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(33)                               ; 134 / 134
    exx                                         ;   4 / 138

    ex af, af'                                  ;   4 / 142

    ; sample 54 cont.
    add a, b                                    ;   4 / 146
    ld e, a                                     ;   4 / 150
    ld a, (de)                                  ;   7 / 157
    add a, (hl)                                 ;   7 / 164
    ld (hl), a                                  ;   7 / 171
    inc l                                       ;   4 / 175

    ; sample 55
    add ix, sp                                  ;  15 / 190
    sbc a, a                                    ;   4 / 194
    and e                                       ;   4 / 198
    add a, b                                    ;   4 / 202
    ld e, a                                     ;   4 / 206
    ld a, (de)                                  ;   7 / 213
    add a, (hl)                                 ;   7 / 220
    ld (hl), a                                  ;   7 / 227
    inc l                                       ;   4 / 231

    ; sample 56
    add ix, sp                                  ;  15 / 246
    sbc a, a                                    ;   4 / 250
    and e                                       ;   4 / 254
    add a, b                                    ;   4 / 258
    ld e, a                                     ;   4 / 262
    ld a, (de)                                  ;   7 / 269
    add a, (hl)                                 ;   7 / 276
    ld (hl), a                                  ;   7 / 283
    inc l                                       ;   4 / 287

    ; sample 57
    add ix, sp                                  ;  15 / 302
    sbc a, a                                    ;   4 / 306
    and e                                       ;   4 / 310
    add a, b                                    ;   4 / 314
    ld e, a                                     ;   4 / 318

    ; timewasting
    ld a, r                                     ;   9 / 327

    exx                                         ;   4 / 331
    SampleOut(34)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; sample 57 cont.
    ld a, (de)                                  ;   7 / 145
    add a, (hl)                                 ;   7 / 152
    ld (hl), a                                  ;   7 / 159
    inc l                                       ;   4 / 163

    ; sample 58
    add ix, sp                                  ;  15 / 178
    sbc a, a                                    ;   4 / 182
    and e                                       ;   4 / 186
    add a, b                                    ;   4 / 190
    ld e, a                                     ;   4 / 194
    ld a, (de)                                  ;   7 / 201
    add a, (hl)                                 ;   7 / 208
    ld (hl), a                                  ;   7 / 215
    inc l                                       ;   4 / 219

    ; sample 59
    add ix, sp                                  ;  15 / 234
    sbc a, a                                    ;   4 / 238
    and e                                       ;   4 / 242
    add a, b                                    ;   4 / 246

    ld (ch_b_osc_sync_pos), a                   ;  13 / 259

    ld e, a                                     ;   4 / 263
    ld a, (de)                                  ;   7 / 270
    add a, (hl)                                 ;   7 / 277
    ld (hl), a                                  ;   7 / 284

    ; done

    ; timewasting [CAREFUL!]
    ld sp, hl                                   ;   6 / 290
    add hl, hl                                  ;  11 / 301
    ex (sp), hl                                 ;  19 / 320
    ld a, (de)                                  ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(35)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting [CAREFUL!]
    ex (sp), hl                                 ;  19 / 157
    add hl, hl                                  ;  11 / 168
    add hl, hl                                  ;  11 / 179
    ld a, (de)                                  ;   7 / 186

    jp channel_b_fm_continue                    ;  10 / 196

; ============================================

channel_b_osc_song_timer_continue:              ;     / 310

    ; timewasting
    add hl, hl                                  ;  11 / 321
    inc hl                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(14)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting
    add hl, hl                                  ;  11 / 149
    inc hl                                      ;   6 / 155
    nop                                         ;   4 / 159

    jp channel_b_osc_do_instrument              ;  10 / 169

; ============================================

channel_b_note_timer_osc_continue:              ;     / 156

    ld (ch_b_note_timer), a                     ;  13 / 169

channel_b_osc_do_instrument:                    ;     / 169

    SMC_LD(a, "ch_b_osc_ins_timer")             ;   7 / 176
    dec a                                       ;   4 / 180
    jr nz, channel_b_osc_ins_timer_continue     ;   7 / 187 [192 taken]

    ; move to the next row of the instrument

    SMC_LD(hl, "ch_b_osc_ins_next_ptr")         ;  10 / 197

    ; get length
    ; (use a length of 0 to denote instrument end)
    ld a, (hl)                                  ;   7 / 204

    or a                                        ;   4 / 208
    jp nz, channel_b_osc_ins_continue           ;  10 / 218

    inc hl                                      ;   6 / 224

    ; load loop pointer
    ld sp, hl                                   ;   6 / 230
    pop hl                                      ;  10 / 240

    ; get length
    ld a, (hl)                                  ;   7 / 247

channel_b_osc_ins_return:                       ;     / 247

    ; save the next current pointer
    ld (ch_b_osc_ins_cur_ptr), hl               ;  16 / 263

    inc hl                                      ;   6 / 269

    ; set new timer value
    ld (ch_b_osc_ins_timer), a                  ;  13 / 282

    ; load waveform
    ld d, (hl)                                  ;   7 / 289

    ; timewasting & inc hl
    cpi                                         ;  16 / 305

    ; save instrument pointer
    ld (ch_b_osc_ins_next_ptr), hl              ;  16 / 321

    ; timewasting
    ld sp, hl                                   ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(15)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting [CAREFUL!]
    cpd                                         ;  16 / 154
    ex (sp), hl                                 ;  19 / 173
    ex (sp), hl                                 ;  19 / 192

    SMC_LD(sp, "ch_b_note")                     ;  10 / 202

    jp channel_b_osc_do_samplegen               ;  10 / 212

; ============================================

    ; remain on the same instrument row
channel_b_osc_ins_timer_continue:               ;     / 192

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 197
    add hl, hl                                  ;  11 / 208

    SMC_LD(hl, "ch_b_osc_ins_cur_ptr")          ;  10 / 218

channel_b_osc_ins_continue:                     ;     / 218

    ; timewasting (make sure to preserve A)
    jr $+2                                      ;  12 / 230
    cp (hl)                                     ;   7 / 237

    jp channel_b_osc_ins_return                 ;  10 / 247

; ============================================

channel_a_unison_setup:                         ;     / 285

    ; prepare for bass generation
    ;
    ; BC = write buffer
    ; DE = waveform
    ; HL = counter
    ; SP = pitch

    ld a, (song_timer)                          ;  13 / 298
    SMC_CP("song_speed5")                       ;   7 / 305
    jp nz, channel_a_unison_song_timer_continue ;  10 / 315

    ; timewasting
    jr ($+2)                                    ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(2)                                ; 134 / 134
    exx                                         ;   4 / 138

    ld a, (ch_a_note_timer)                     ;  13 / 151
    dec a                                       ;   4 / 155
    jp nz, channel_a_unison_note_timer_continue ;  10 / 165

    ld hl, (ch_a_pattern_ptr)                   ;  16 / 181

    ld a, (hl)  ; get note length               ;   7 / 188
    inc hl                                      ;   6 / 194
    ld (ch_a_note_timer), a                     ;  13 / 207

    ld a, (hl)  ; get note value                ;   7 / 214
    inc hl                                      ;   6 / 220

    ld (ch_a_pattern_ptr), hl                   ;  16 / 236

    ; save note value
    ld (ch_a_note_value), a                     ;  13 / 249

    or a                                        ;   4 / 253
    jp z, channel_a_unison_reset_pos            ;  10 / 263

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 268

    ; look up note pitch
    ld h, HIGH unison_pitch_table               ;   7 / 275
    ld l, a                                     ;   4 / 279

    ld sp, hl                                   ;   6 / 285
    pop hl                                      ;  10 / 295

    ld sp, hl                                   ;   6 / 301

    ld (ch_a_note), hl                          ;  16 / 317

    ; restart instrument
    SMC_LD(hl, "ch_a_u_ins_initial")            ;  10 / 327

    exx                                         ;   4 / 331
    SampleOut(3)                                ; 134 / 134
    exx                                         ;   4 / 138

    ld (ch_a_u_ins_cur_ptr), hl                 ;  16 / 154

    SMC_LD(d, "ch_a_u_waveform_initial")        ;  7 / 161

    SMC_LD(a, "ch_a_u_ins_timer_initial")       ;   7 / 168
    ld (ch_a_u_ins_timer), a                    ;  13 / 181

    ; timewasting
    inc hl                                      ;   6 / 187
    nop                                         ;   4 / 191

channel_a_unison_do_samplegen:                  ;     / 191

    ; timewasting
    add hl, hl                                  ;  11 / 202
    add hl, hl                                  ;  11 / 213

    ld hl, (ch_a_pos)                           ;  16 / 229

    ld bc, (write_buffer_offset)                ;  20 / 249

    ; timewasting
    ld a, (de)                                  ;   7 / 256

    ; samplegen

    ; samples 0, 1
    ld e, h                                     ;   4 / 260
    ld a, (de)                                  ;   7 / 267
    ld e, l                                     ;   4 / 271
    add hl, sp                                  ;  11 / 282
    ex de, hl                                   ;   4 / 286
    add a, (hl)                                 ;   7 / 293
    rra                                         ;   4 / 297
    ld (bc), a                                  ;   7 / 304
    inc bc                                      ;   6 / 310
    ld (bc), a                                  ;   7 / 317
    inc bc                                      ;   6 / 323

    ; samples 2, 3
    ld l, d                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(4)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 2, 3 cont.
    ld a, (hl)                                  ;   7 / 145
    ld l, e                                     ;   4 / 149
    add a, (hl)                                 ;   7 / 156
    rra                                         ;   4 / 160
    ld (bc), a                                  ;   7 / 167
    inc c                                       ;   4 / 171
    ld (bc), a                                  ;   7 / 178
    inc c                                       ;   4 / 182
    ex de, hl                                   ;   4 / 186
    add hl, sp                                  ;  11 / 197

    ; samples 4, 5
    ld e, h                                     ;   4 / 201
    ld a, (de)                                  ;   7 / 208
    ld e, l                                     ;   4 / 212
    add hl, sp                                  ;  11 / 223
    ex de, hl                                   ;   4 / 227
    add a, (hl)                                 ;   7 / 234
    rra                                         ;   4 / 238
    ld (bc), a                                  ;   7 / 245
    inc c                                       ;   4 / 249
    ld (bc), a                                  ;   7 / 256
    inc c                                       ;   4 / 260

    ; samples 6, 7
    ld l, d                                     ;   4 / 264
    ld a, (hl)                                  ;   7 / 271
    ld l, e                                     ;   4 / 275
    add a, (hl)                                 ;   7 / 282
    rra                                         ;   4 / 286
    ld (bc), a                                  ;   7 / 293
    inc c                                       ;   4 / 297
    ld (bc), a                                  ;   7 / 304
    inc c                                       ;   4 / 308
    ex de, hl                                   ;   4 / 312
    add hl, sp                                  ;  11 / 323

    ; samples 8, 9
    ld e, h                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(5)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 8, 9 cont.
    ld a, (de)                                  ;   7 / 145
    ld e, l                                     ;   4 / 149
    add hl, sp                                  ;  11 / 160
    ex de, hl                                   ;   4 / 164
    add a, (hl)                                 ;   7 / 171
    rra                                         ;   4 / 175
    ld (bc), a                                  ;   7 / 182
    inc c                                       ;   4 / 186
    ld (bc), a                                  ;   7 / 193
    inc c                                       ;   4 / 197

    ; samples 10, 11
    ld l, d                                     ;   4 / 201
    ld a, (hl)                                  ;   7 / 208
    ld l, e                                     ;   4 / 212
    add a, (hl)                                 ;   7 / 219
    rra                                         ;   4 / 223
    ld (bc), a                                  ;   7 / 230
    inc c                                       ;   4 / 234
    ld (bc), a                                  ;   7 / 241
    inc c                                       ;   4 / 245
    ex de, hl                                   ;   4 / 249
    add hl, sp                                  ;  11 / 260

    ; samples 12, 13
    ld e, h                                     ;   4 / 264
    ld a, (de)                                  ;   7 / 271
    ld e, l                                     ;   4 / 275
    add hl, sp                                  ;  11 / 286
    ex de, hl                                   ;   4 / 290
    add a, (hl)                                 ;   7 / 297
    rra                                         ;   4 / 301
    ld (bc), a                                  ;   7 / 308
    inc c                                       ;   4 / 312
    ld (bc), a                                  ;   7 / 319
    inc c                                       ;   4 / 323

    ; samples 14, 15
    ld l, d                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(6)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 14, 15 cont.
    ld a, (hl)                                  ;   7 / 145
    ld l, e                                     ;   4 / 149
    add a, (hl)                                 ;   7 / 156
    rra                                         ;   4 / 160
    ld (bc), a                                  ;   7 / 167
    inc c                                       ;   4 / 171
    ld (bc), a                                  ;   7 / 178
    inc c                                       ;   4 / 182
    ex de, hl                                   ;   4 / 186
    add hl, sp                                  ;  11 / 197

    ; samples 16, 17
    ld e, h                                     ;   4 / 201
    ld a, (de)                                  ;   7 / 208
    ld e, l                                     ;   4 / 212
    add hl, sp                                  ;  11 / 223
    ex de, hl                                   ;   4 / 227
    add a, (hl)                                 ;   7 / 234
    rra                                         ;   4 / 238
    ld (bc), a                                  ;   7 / 245
    inc c                                       ;   4 / 249
    ld (bc), a                                  ;   7 / 256
    inc c                                       ;   4 / 260

    ; samples 18, 19
    ld l, d                                     ;   4 / 264
    ld a, (hl)                                  ;   7 / 271
    ld l, e                                     ;   4 / 275
    add a, (hl)                                 ;   7 / 282
    rra                                         ;   4 / 286
    ld (bc), a                                  ;   7 / 293
    inc c                                       ;   4 / 297
    ld (bc), a                                  ;   7 / 304
    inc c                                       ;   4 / 308
    ex de, hl                                   ;   4 / 312
    add hl, sp                                  ;  11 / 323

    ; samples 20, 21
    ld e, h                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(7)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 20, 21 cont.
    ld a, (de)                                  ;   7 / 145
    ld e, l                                     ;   4 / 149
    add hl, sp                                  ;  11 / 160
    ex de, hl                                   ;   4 / 164
    add a, (hl)                                 ;   7 / 171
    rra                                         ;   4 / 175
    ld (bc), a                                  ;   7 / 182
    inc c                                       ;   4 / 186
    ld (bc), a                                  ;   7 / 193
    inc c                                       ;   4 / 197

    ; samples 22, 23
    ld l, d                                     ;   4 / 201
    ld a, (hl)                                  ;   7 / 208
    ld l, e                                     ;   4 / 212
    add a, (hl)                                 ;   7 / 219
    rra                                         ;   4 / 223
    ld (bc), a                                  ;   7 / 230
    inc c                                       ;   4 / 234
    ld (bc), a                                  ;   7 / 241
    inc c                                       ;   4 / 245
    ex de, hl                                   ;   4 / 249
    add hl, sp                                  ;  11 / 260

    ; samples 24, 25
    ld e, h                                     ;   4 / 264
    ld a, (de)                                  ;   7 / 271
    ld e, l                                     ;   4 / 275
    add hl, sp                                  ;  11 / 286
    ex de, hl                                   ;   4 / 290
    add a, (hl)                                 ;   7 / 297
    rra                                         ;   4 / 301
    ld (bc), a                                  ;   7 / 308
    inc c                                       ;   4 / 312
    ld (bc), a                                  ;   7 / 319
    inc c                                       ;   4 / 323

    ; samples 26, 27
    ld l, d                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(8)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 26, 27 cont.
    ld a, (hl)                                  ;   7 / 145
    ld l, e                                     ;   4 / 149
    add a, (hl)                                 ;   7 / 156
    rra                                         ;   4 / 160
    ld (bc), a                                  ;   7 / 167
    inc c                                       ;   4 / 171
    ld (bc), a                                  ;   7 / 178
    inc c                                       ;   4 / 182
    ex de, hl                                   ;   4 / 186
    add hl, sp                                  ;  11 / 197

    ; samples 28, 29
    ld e, h                                     ;   4 / 201
    ld a, (de)                                  ;   7 / 208
    ld e, l                                     ;   4 / 212
    add hl, sp                                  ;  11 / 223
    ex de, hl                                   ;   4 / 227
    add a, (hl)                                 ;   7 / 234
    rra                                         ;   4 / 238
    ld (bc), a                                  ;   7 / 245
    inc c                                       ;   4 / 249
    ld (bc), a                                  ;   7 / 256
    inc c                                       ;   4 / 260

    ; samples 30, 31
    ld l, d                                     ;   4 / 264
    ld a, (hl)                                  ;   7 / 271
    ld l, e                                     ;   4 / 275
    add a, (hl)                                 ;   7 / 282
    rra                                         ;   4 / 286
    ld (bc), a                                  ;   7 / 293
    inc c                                       ;   4 / 297
    ld (bc), a                                  ;   7 / 304
    inc c                                       ;   4 / 308
    ex de, hl                                   ;   4 / 312
    add hl, sp                                  ;  11 / 323

    ; samples 32, 33
    ld e, h                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(9)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 32, 33 cont.
    ld a, (de)                                  ;   7 / 145
    ld e, l                                     ;   4 / 149
    add hl, sp                                  ;  11 / 160
    ex de, hl                                   ;   4 / 164
    add a, (hl)                                 ;   7 / 171
    rra                                         ;   4 / 175
    ld (bc), a                                  ;   7 / 182
    inc c                                       ;   4 / 186
    ld (bc), a                                  ;   7 / 193
    inc c                                       ;   4 / 197

    ; samples 34, 35
    ld l, d                                     ;   4 / 201
    ld a, (hl)                                  ;   7 / 208
    ld l, e                                     ;   4 / 212
    add a, (hl)                                 ;   7 / 219
    rra                                         ;   4 / 223
    ld (bc), a                                  ;   7 / 230
    inc c                                       ;   4 / 234
    ld (bc), a                                  ;   7 / 241
    inc c                                       ;   4 / 245
    ex de, hl                                   ;   4 / 249
    add hl, sp                                  ;  11 / 260

    ; samples 36, 37
    ld e, h                                     ;   4 / 264
    ld a, (de)                                  ;   7 / 271
    ld e, l                                     ;   4 / 275
    add hl, sp                                  ;  11 / 286
    ex de, hl                                   ;   4 / 290
    add a, (hl)                                 ;   7 / 297
    rra                                         ;   4 / 301
    ld (bc), a                                  ;   7 / 308
    inc c                                       ;   4 / 312
    ld (bc), a                                  ;   7 / 319
    inc c                                       ;   4 / 323

    ; samples 38, 39
    ld l, d                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(10)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 38, 39 cont.
    ld a, (hl)                                  ;   7 / 145
    ld l, e                                     ;   4 / 149
    add a, (hl)                                 ;   7 / 156
    rra                                         ;   4 / 160
    ld (bc), a                                  ;   7 / 167
    inc c                                       ;   4 / 171
    ld (bc), a                                  ;   7 / 178
    inc c                                       ;   4 / 182
    ex de, hl                                   ;   4 / 186
    add hl, sp                                  ;  11 / 197

    ; samples 40, 41
    ld e, h                                     ;   4 / 201
    ld a, (de)                                  ;   7 / 208
    ld e, l                                     ;   4 / 212
    add hl, sp                                  ;  11 / 223
    ex de, hl                                   ;   4 / 227
    add a, (hl)                                 ;   7 / 234
    rra                                         ;   4 / 238
    ld (bc), a                                  ;   7 / 245
    inc c                                       ;   4 / 249
    ld (bc), a                                  ;   7 / 256
    inc c                                       ;   4 / 260

    ; samples 42, 43
    ld l, d                                     ;   4 / 264
    ld a, (hl)                                  ;   7 / 271
    ld l, e                                     ;   4 / 275
    add a, (hl)                                 ;   7 / 282
    rra                                         ;   4 / 286
    ld (bc), a                                  ;   7 / 293
    inc c                                       ;   4 / 297
    ld (bc), a                                  ;   7 / 304
    inc c                                       ;   4 / 308
    ex de, hl                                   ;   4 / 312
    add hl, sp                                  ;  11 / 323

    ; samples 44, 45
    ld e, h                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(11)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 44, 45 cont.
    ld a, (de)                                  ;   7 / 145
    ld e, l                                     ;   4 / 149
    add hl, sp                                  ;  11 / 160
    ex de, hl                                   ;   4 / 164
    add a, (hl)                                 ;   7 / 171
    rra                                         ;   4 / 175
    ld (bc), a                                  ;   7 / 182
    inc c                                       ;   4 / 186
    ld (bc), a                                  ;   7 / 193
    inc c                                       ;   4 / 197

    ; samples 46, 47
    ld l, d                                     ;   4 / 201
    ld a, (hl)                                  ;   7 / 208
    ld l, e                                     ;   4 / 212
    add a, (hl)                                 ;   7 / 219
    rra                                         ;   4 / 223
    ld (bc), a                                  ;   7 / 230
    inc c                                       ;   4 / 234
    ld (bc), a                                  ;   7 / 241
    inc c                                       ;   4 / 245
    ex de, hl                                   ;   4 / 249
    add hl, sp                                  ;  11 / 260

    ; samples 48, 49
    ld e, h                                     ;   4 / 264
    ld a, (de)                                  ;   7 / 271
    ld e, l                                     ;   4 / 275
    add hl, sp                                  ;  11 / 286
    ex de, hl                                   ;   4 / 290
    add a, (hl)                                 ;   7 / 297
    rra                                         ;   4 / 301
    ld (bc), a                                  ;   7 / 308
    inc c                                       ;   4 / 312
    ld (bc), a                                  ;   7 / 319
    inc c                                       ;   4 / 323

    ; samples 50, 51
    ld l, d                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(12)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 50, 51 cont.
    ld a, (hl)                                  ;   7 / 145
    ld l, e                                     ;   4 / 149
    add a, (hl)                                 ;   7 / 156
    rra                                         ;   4 / 160
    ld (bc), a                                  ;   7 / 167
    inc c                                       ;   4 / 171
    ld (bc), a                                  ;   7 / 178
    inc c                                       ;   4 / 182
    ex de, hl                                   ;   4 / 186
    add hl, sp                                  ;  11 / 197

    ; samples 52, 53
    ld e, h                                     ;   4 / 201
    ld a, (de)                                  ;   7 / 208
    ld e, l                                     ;   4 / 212
    add hl, sp                                  ;  11 / 223
    ex de, hl                                   ;   4 / 227
    add a, (hl)                                 ;   7 / 234
    rra                                         ;   4 / 238
    ld (bc), a                                  ;   7 / 245
    inc c                                       ;   4 / 249
    ld (bc), a                                  ;   7 / 256
    inc c                                       ;   4 / 260

    ; samples 54, 55
    ld l, d                                     ;   4 / 264
    ld a, (hl)                                  ;   7 / 271
    ld l, e                                     ;   4 / 275
    add a, (hl)                                 ;   7 / 282
    rra                                         ;   4 / 286
    ld (bc), a                                  ;   7 / 293
    inc c                                       ;   4 / 297
    ld (bc), a                                  ;   7 / 304
    inc c                                       ;   4 / 308
    ex de, hl                                   ;   4 / 312
    add hl, sp                                  ;  11 / 323

    ; samples 56, 57
    ld e, h                                     ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(13)                               ; 134 / 134
    exx                                         ;   4 / 138

    ; samples 56, 57 cont.
    ld a, (de)                                  ;   7 / 145
    ld e, l                                     ;   4 / 149
    add hl, sp                                  ;  11 / 160
    ex de, hl                                   ;   4 / 164
    add a, (hl)                                 ;   7 / 171
    rra                                         ;   4 / 175
    ld (bc), a                                  ;   7 / 182
    inc c                                       ;   4 / 186
    ld (bc), a                                  ;   7 / 193
    inc c                                       ;   4 / 197

    ; samples 58, 59
    ld l, d                                     ;   4 / 201
    ld a, (hl)                                  ;   7 / 208
    ld l, e                                     ;   4 / 212
    add a, (hl)                                 ;   7 / 219
    rra                                         ;   4 / 223
    ld (bc), a                                  ;   7 / 230
    inc c                                       ;   4 / 234
    ld (bc), a                                  ;   7 / 241

    ex de, hl                                   ;   4 / 245
    add hl, sp                                  ;  11 / 256

    ; jump back

    jp channel_b_branch                         ;  10 / 266

; ============================================

channel_a_unison_song_timer_continue:           ;     / 315

    ; timewasting
    jr $+2                                      ;  12 / 327

    exx                                         ;   4 / 331
    SampleOut(2)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; timewasting
    add hl, hl                                  ;  11 / 149
    add hl, hl                                  ;  11 / 160
    nop                                         ;   4 / 164
    nop                                         ;   4 / 168

    jp channel_a_unison_do_instrument           ;  10 / 178

; ============================================

channel_a_unison_note_timer_continue:           ;     / 165

    ld (ch_a_note_timer), a                     ;  13 / 178

channel_a_unison_do_instrument:                 ;     / 178

    SMC_LD(a, "ch_a_u_ins_timer")               ;   7 / 185
    dec a                                       ;   4 / 189
    jr nz, channel_a_unison_ins_timer_continue  ;   7 / 196 [201 taken]

    ; move to the next row of the instrument

    SMC_LD(hl, "ch_a_u_ins_next_ptr")           ;  10 / 206

    ; get length
    ; (use length of 0 to denote instrument end)
    ld a, (hl)                                  ;   7 / 213

    or a                                        ;   4 / 217
    jp nz, channel_a_unison_ins_continue        ;  10 / 227

    inc hl                                      ;   6 / 233

    ; load loop pointer
    ld sp, hl                                   ;   6 / 239
    pop hl                                      ;  10 / 249

    ; get length
    ld a, (hl)                                  ;   7 / 256

channel_a_unison_ins_return:                    ;     / 256

    ; save the new instrument pointer
    ld (ch_a_u_ins_cur_ptr), hl                 ;  16 / 272

    ; set new timer value
    ld (ch_a_u_ins_timer), a                    ;  13 / 285

    inc hl                                      ;   6 / 291

    ; load waveform
    ld d, (hl)                                  ;   7 / 298
    inc hl                                      ;   6 / 304

    ; save instrument pointer (and update current)
    ld (ch_a_u_ins_next_ptr), hl                ;  16 / 320

    ; timewasting
    cp (hl)                                     ;   7 / 327

    exx                                         ;   4 / 331
    SampleOut(3)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; I forgot to load this earlier
    ld sp, (ch_a_note)                          ;  20 / 158

    ; timewasting
    jr $+2                                      ;  12 / 170
    add hl, hl                                  ;  11 / 181

    jp channel_a_unison_do_samplegen            ;  10 / 191

; ============================================

    ; remain on the same instrument row
channel_a_unison_ins_timer_continue:            ;     / 201

    ; timewasting [CAUTION!]
    ret z                                       ;   5 / 206
    add hl, hl                                  ;  11 / 217

    SMC_LD(hl, "ch_a_u_ins_cur_ptr")            ;  10 / 227

channel_a_unison_ins_continue:                  ;     / 227

    ; timewasting (make sure to preserve A)
    add ix, ix                                  ;  15 / 242
    nop                                         ;   4 / 246

    jp channel_a_unison_ins_return              ;  10 / 256

; ============================================

ch_a_orn_no_loop:                               ;     / 272

    ; save orn note
    ld d, a                                     ;   4 / 276

    ; timewasting
    cp (hl)                                     ;   7 / 283

    jr ch_a_orn_continue                        ;  12 / 295

; ============================================

ch_a_orn:                                       ;     / 212

    ld hl, ch_b_orn                             ;  10 / 222
    ld (orn_target), hl                         ;  16 / 238

    ; get orn note
    SMC_LD(hl, "ch_a_orn_ptr")                  ;  10 / 248
    ld a, (hl)                                  ;   7 / 255

    ; end of ornament?
    cp ORNAMENT_END                             ;   7 / 262

    jp nz, ch_a_orn_no_loop                     ;  10 / 272

    SMC_LD(hl, "ch_a_orn_loop_ptr")             ;  10 / 282
    ld d, (hl)                                  ;   7 / 289

    ; timewasting
    inc bc                                      ;   6 / 295

ch_a_orn_continue:                              ;     / 295

    ; save ornament pointer
    inc hl                                      ;   6 / 301
    ld (ch_a_orn_ptr), hl                       ;  16 / 317

    ; calculate accumulated bend value
    SMC_LD(hl, "ch_a_bend")                     ;  10 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ld bc, (ch_a_bend_accum)                    ;  20 / 158
    add hl, bc                                  ;  11 / 169

    ; save new accumulated value
    ld (ch_a_bend_accum), hl                    ;  16 / 185

    ; add to base note value
    SMC_LD(a, "ch_a_note_value")                ;   7 / 192
    or a                                        ;   4 / 196
    jr z, orn_silence                           ;   7 / 203 [208 taken]

    add a, d                                    ;   4 / 207

    ; look up pitch value
    ld l, a                                     ;   4 / 211
    SMC_LD(h, "ch_a_orn_pitch_table")           ;   7 / 218

    ld sp, hl                                   ;   6 / 224
    pop hl                                      ;  10 / 234

    ; add to bend value
    add hl, bc                                  ;  11 / 245

    ; save note value
    ld (ch_a_note), hl                          ;  16 / 261

    jp event_return_271                         ;  10 / 271

; ============================================

ch_b_orn_no_loop:                               ;     / 272

    ; save orn note
    ld d, a                                     ;   4 / 276

    ; timewasting
    cp (hl)                                     ;   7 / 283

    jr ch_b_orn_continue                        ;  12 / 295

; ============================================

orn_silence:                                    ;     / 208

    jp event_return_218                         ;  10 / 218

; ============================================

ch_b_orn:                                       ;     / 212

    ld hl, ch_c_orn                             ;  10 / 222
    ld (orn_target), hl                         ;  16 / 238

    ; get orn note
    SMC_LD(hl, "ch_b_orn_ptr")                  ;  10 / 248
    ld a, (hl)                                  ;   7 / 255

    ; end of ornament?
    cp ORNAMENT_END                             ;   7 / 262

    jp nz, ch_b_orn_no_loop                     ;  10 / 272

    SMC_LD(hl, "ch_b_orn_loop_ptr")             ;  10 / 282
    ld d, (hl)                                  ;   7 / 289

    ; timewasting
    inc bc                                      ;   6 / 295

ch_b_orn_continue:                              ;     / 295

    ; save ornament pointer
    inc hl                                      ;   6 / 301
    ld (ch_b_orn_ptr), hl                       ;  16 / 317

    ; calculate accumulated bend value
    SMC_LD(hl, "ch_b_bend")                     ;  10 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ld bc, (ch_b_bend_accum)                    ;  20 / 158
    add hl, bc                                  ;  11 / 169

    ; save new accumulated value
    ld (ch_b_bend_accum), hl                    ;  16 / 185

    ; add to base note value
    SMC_LD(a, "ch_b_note_value")                ;   7 / 192
    or a                                        ;   4 / 196
    jr z, orn_silence                           ;   7 / 203 [208 taken]

    add a, d                                    ;   4 / 207

    ; look up pitch value
    ld l, a                                     ;   4 / 211
    ld h, HIGH pitch_table                      ;   7 / 218

    ld sp, hl                                   ;   6 / 224
    pop hl                                      ;  10 / 234

    ; add to bend value
    add hl, bc                                  ;  11 / 245

    ; save note value
    ld (ch_b_note), hl                          ;  16 / 261

    jp event_return_271                         ;  10 / 271

; ============================================

ch_c_orn_no_loop:                               ;     / 272

    ; save orn note
    ld d, a                                     ;   4 / 276

    ; timewasting
    cp (hl)                                     ;   7 / 283

    jr ch_c_orn_continue                        ;  12 / 295

; ============================================

    ; separate from orn_silence because relative
    ; jumps have a limited displacement range
ch_c_orn_silence:                               ;     / 208

    jp event_return_218                         ;  10 / 218

; ============================================

ch_c_orn:                                       ;     / 212

    ld hl, ch_a_orn                             ;  10 / 222
    ld (orn_target), hl                         ;  16 / 238

    ; get orn note
    SMC_LD(hl, "ch_c_orn_ptr")                  ;  10 / 248
    ld a, (hl)                                  ;   7 / 255

    ; end of ornament?
    cp ORNAMENT_END                             ;   7 / 262

    jp nz, ch_c_orn_no_loop                     ;  10 / 272

    SMC_LD(hl, "ch_c_orn_loop_ptr")             ;  10 / 282
    ld d, (hl)                                  ;   7 / 289

    ; timewasting
    inc bc                                      ;   6 / 295

ch_c_orn_continue:                              ;     / 295

    ; save ornament pointer
    inc hl                                      ;   6 / 301
    ld (ch_c_orn_ptr), hl                       ;  16 / 317

    ; calculate accumulated bend value
    SMC_LD(hl, "ch_c_bend")                     ;  10 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ld bc, (ch_c_bend_accum)                    ;  20 / 158
    add hl, bc                                  ;  11 / 169

    ; save new accumulated value
    ld (ch_c_bend_accum), hl                    ;  16 / 185

    ; add to base note value
    SMC_LD(a, "ch_c_note_value")                ;   7 / 192
    or a                                        ;   4 / 196
    jr z, ch_c_orn_silence                      ;   7 / 203 [208 taken]

    add a, d                                    ;   4 / 207

    ; look up pitch value
    ld l, a                                     ;   4 / 211
    ld h, HIGH pitch_table                      ;   7 / 218

    ld sp, hl                                   ;   6 / 224
    pop hl                                      ;  10 / 234

    ; add to bend value
    add hl, bc                                  ;  11 / 245

    ; save note value
    ld (ch_c_note), hl                          ;  16 / 261

    jp event_return_271                         ;  10 / 271

; ============================================

channel_a_unison_reset_pos:                     ;     / 263

    ; we know A = 0
    ld h, a                                     ;   4 / 267
    ld l, a                                     ;   4 / 271

    ld sp, hl                                   ;   6 / 277

    ld (ch_a_pos), hl                           ;  16 / 293
    ld (ch_a_note), hl                          ;  16 / 309

    ; Set up the empty instrument.
    ld d, EMPTY_INS_CARRIER                     ;   7 / 316

    ld a, 1                                     ;   7 / 323

    ; save A register
    ex af, af'                                  ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(3)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; restore A register
    ex af, af'                                  ;   4 / 142

    ld (ch_a_u_ins_timer), a                    ;  13 / 155

    ; NOTE: using the osc. sync instrument here
    ld hl, empty_instrument_osc_sync            ;  10 / 165
    ld (ch_a_u_ins_next_ptr), hl                ;  16 / 181

    jp channel_a_unison_do_samplegen            ;  10 / 191

; ============================================

sample_out_1_321:                               ;     / 321

    ; timewasting
    inc bc                                      ;   6 / 326

sample_out_1:                                   ;     / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    jp (ix)                                     ;   8 / 146

; ============================================

empty_callback:                                 ;     / 226
    ; timewasting
    rld                                         ;  18 / 244
    rrd                                         ;  18 / 262
    rld                                         ;  18 / 280
    rrd                                         ;  18 / 298

    jp samplegen_fm                             ;  10 / 308

; ============================================

callback_ret:                                   ;     / 267
    ; timewasting
    jr $+2                                      ;  12 / 279
    jr $+2                                      ;  12 / 291
    or (hl)                                     ;   7 / 298

    jp samplegen_fm                             ;  10 / 308

; ============================================

BEGIN_PAGE_TABLE("event_jp_table", false)

; Sets channel A samplegen type to unison.
; Takes no parameters.
CHANNEL_A_UNISON        equ LOW $
    dw event_channel_a_unison

; Sets channel A samplegen type to FM.
; Takes no parameters.
CHANNEL_A_FM            equ LOW $
    dw event_channel_a_fm

; Sets channel B samplegen type to oscillator sync.
; Takes no parameters.
CHANNEL_B_OSC_SYNC      equ LOW $
    dw event_channel_b_osc_sync

; Sets channel B samplegen type to FM.
; Takes no parameters.
CHANNEL_B_FM            equ LOW $
    dw event_channel_b_fm

; Sets parameters for oscillator sync on channel B.
; First two bytes specify the initial modulator pitch.
; Second two bytes specify modulator pitch bend value.
OSC_SYNC_PARAMS         equ LOW $
    dw event_osc_sync_params

; Sets the instrument for channel A FM samplegen.
; Takes a pointer to the instrument definition.
CHANNEL_A_INSTRUMENT    equ LOW $
    dw event_channel_a_instrument

; Sets the instrument for channel A unison samplegen.
; Takes a pointer to the instrument definition.
CHANNEL_A_UNISON_INSTRUMENT equ LOW $
    dw event_channel_a_unison_instrument

; Sets the instrument for channel B FM samplegen.
; Takes a pointer to the instrument definition.
CHANNEL_B_INSTRUMENT    equ LOW $
    dw event_channel_b_instrument

; Sets the instrument for channel B oscillator sync samplegen.
; Takes a pointer to the instrument definition.
CHANNEL_B_OSC_INSTRUMENT    equ LOW $
    dw event_channel_b_osc_instrument

; Sets the instrument for channel C FM samplegen.
; Takes a pointer to the instrument definition.
CHANNEL_C_INSTRUMENT    equ LOW $
    dw event_channel_c_instrument

; Sets the pitch bend value for channel A.
; Two bytes specify the bend amount, and
; the third byte is zero if the accumulated
; bend should be reset.
CHANNEL_A_PITCH_BEND    equ LOW $
    dw event_channel_a_pitch_bend

; Sets the pitch bend value for channel B.
; Two bytes specify the bend amount, and
; the third byte is zero if the accumulated
; bend should be reset.
CHANNEL_B_PITCH_BEND    equ LOW $
    dw event_channel_b_pitch_bend

; Sets the pitch bend value for channel C.
; Two bytes specify the bend amount, and
; the third byte is zero if the accumulated
; bend should be reset.
CHANNEL_C_PITCH_BEND    equ LOW $
    dw event_channel_c_pitch_bend

; Sets the ornament for channel A.
; Ornament processing is paused while any event
; processing is taking placed. Round-robin scheduling
; is used for processing the three channels.
; Ornaments are reset when a new note is triggered.
; Takes a single byte representing the ornament ID.
CHANNEL_A_ORNAMENT      equ LOW $
    dw event_channel_a_ornament

; Sets the ornament for channel B.
; Takes a single byte representing the ornament ID.
CHANNEL_B_ORNAMENT      equ LOW $
    dw event_channel_b_ornament

; Sets the ornament for channel C.
; Takes a single byte representing the ornament ID.
CHANNEL_C_ORNAMENT      equ LOW $
    dw event_channel_c_ornament

; Sets the number of ticks for every row update.
; Takes a single byte for the new song speed.
SET_SONG_SPEED          equ LOW $
    dw event_set_song_speed

; Outputs the provided value to the paging register,
; effectively switching banks.
; Takes a single byte for the value to output.
SET_BANK                equ LOW $
    dw event_set_bank

END_PAGE_TABLE("event_jp_table")

; ============================================

event_channel_a_unison:                         ;     / 271

    ld hl, channel_a_unison_setup               ;  10 / 281
    ld (channel_a_samplegen), hl                ;  16 / 297

    ld ix, event_channel_a_unison_return        ;  14 / 311

    jp sample_out_1_321                         ;  10 / 321

; ============================================

event_channel_a_unison_return:                  ;     / 146

    ld (event_pattern_ptr), de                  ;  20 / 166

    xor a                                       ;   4 / 170
    ld (ch_a_pos_prefix), a                     ;  13 / 183

    ld a, HIGH unison_pitch_table               ;   7 / 190
    ld (ch_a_orn_pitch_table), a                ;  13 / 203

    ; timewasting [CAUTION!]
    ret nz                                      ;   5 / 208

    jp event_return_218                         ;  10 / 218

; ============================================

event_channel_a_fm:                             ;     / 271

    ld hl, channel_a_bass_fm                    ;  10 / 281
    ld (channel_a_samplegen), hl                ;  16 / 297

    ld ix, event_channel_a_fm_return            ;  14 / 311

    jp sample_out_1_321                         ;  10 / 321

; ============================================

event_channel_a_fm_return:                      ;     / 146

    ld (event_pattern_ptr), de                  ;  20 / 166

    ld a, $dd                                   ;   7 / 173
    ld (ch_a_pos_prefix), a                     ;  13 / 186

    ld a, HIGH pitch_table                      ;   7 / 193
    ld (ch_a_orn_pitch_table), a                ;  13 / 206

    ; timewasting
    inc hl                                      ;   6 / 212

    jp event_return_222                         ;  10 / 222

; ============================================

event_channel_b_osc_sync:                       ;     / 271

    ld hl, channel_b_osc_sync_setup             ;  10 / 281
    ld (channel_b_samplegen), hl                ;  16 / 297

    ld ix, event_channel_b_osc_sync_return      ;  14 / 311

    jp sample_out_1_321                         ;  10 / 321

; ============================================

event_channel_b_osc_sync_return:                ;     / 146

    ld (event_pattern_ptr), de                  ;  20 / 166

    ld hl, (ch_b_bend_accum)                    ;  16 / 182
    ld (ch_b_bend_accum2), hl                   ;  16 / 198

    jp event_return_208                         ;  10 / 208

; ============================================

event_channel_b_fm:                             ;     / 271

    ld hl, channel_b_fm_setup                   ;  10 / 281
    ld (channel_b_samplegen), hl                ;  16 / 297

    ld ix, event_channel_b_fm_return            ;  14 / 311

    jp sample_out_1_321                         ;  10 / 321

; ============================================

event_channel_b_fm_return:                      ;     / 146

    ld (event_pattern_ptr), de                  ;  20 / 166

    ld hl, (ch_b_bend_accum2)                   ;  16 / 182
    ld (ch_b_bend_accum), hl                    ;  16 / 198

    jp event_return_208                         ;  10 / 208

; ============================================

event_osc_sync_params:                          ;     / 271

    ; timewasting
    cp (hl)                                     ;   7 / 278
    add hl, hl                                  ;  11 / 289

    ; copy pitch and bend parameters (2 bytes each)

    ; put pattern pointer in HL
    ex de, hl                                   ;   4 / 293

    ; load destination pointer
    ld de, ch_b_osc_sync_pitch                  ;  10 / 303

    ld ix, event_osc_sync_params_return         ;  14 / 317

    jp sample_out_1                             ;  10 / 327

; ============================================

event_osc_sync_params_return:                   ;     / 146

    ; timewasting
    cp (hl)                                     ;   7 / 153
    cp (hl)                                     ;   7 / 160

    ; copy pitch value
    ldi                                         ;  16 / 176
    ldi                                         ;  16 / 192

    ; load second destination pointer
    ld de, ch_b_osc_sync_bend                   ;  10 / 202

    ; copy bend value
    ldi                                         ;  16 / 218
    ldi                                         ;  16 / 234

    ; save pattern pointer
    ld (event_pattern_ptr), hl                  ;  16 / 250

    jp event_return_260                         ;  10 / 260

; ============================================

event_channel_a_instrument:                     ;     / 271

    ; move event pointer into HL and SP
    ex de, hl                                   ;   4 / 275
    ld sp, hl                                   ;   6 / 281

    ; get instrument pointer
    pop hl                                      ;  10 / 291

    ; set instrument pointer variable
    ld (ch_a_ins_initial), hl                   ;  16 / 307
    ld (ch_a_ins_cur_ptr), hl                   ;  16 / 323

    ; timewasting
    nop                                         ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; get initial values
    ld a, (hl)                                  ;   7 / 145
    inc hl                                      ;   6 / 151

    ld (ch_a_ins_timer_initial), a              ;  13 / 164
    ld (ch_a_ins_timer), a                      ;  13 / 177

    ld a, (hl)                                  ;   7 / 184
    inc hl                                      ;   6 / 190

    ld (ch_a_carrier_initial), a                ;  13 / 203

    ld a, (hl)                                  ;   7 / 210
    inc hl                                      ;   6 / 216

    ld (ch_a_mod_initial), a                    ;  13 / 229

    ld (ch_a_ins_next_ptr), hl                  ;  16 / 245

    ; save event pattern pointer
    ld (event_pattern_ptr), sp                  ;  20 / 265

    jp event_return                             ;  10 / 275

; ============================================

event_channel_a_unison_instrument:              ;     / 271

    ; move event pointer into HL and SP
    ex de, hl                                   ;   4 / 275
    ld sp, hl                                   ;   6 / 281

    ; get instrument pointer
    pop hl                                      ;  10 / 291

    ; set instrument pointer variable
    ld (ch_a_u_ins_initial), hl                 ;  16 / 307
    ld (ch_a_u_ins_cur_ptr), hl                 ;  16 / 323

    ; timewasting
    nop                                         ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; get initial values
    ld a, (hl)                                  ;   7 / 145
    inc hl                                      ;   6 / 151

    ld (ch_a_u_ins_timer_initial), a            ;  13 / 164
    ld (ch_a_u_ins_timer), a                    ;  13 / 177

    ld a, (hl)                                  ;   7 / 184
    inc hl                                      ;   6 / 190

    ld (ch_a_u_waveform_initial), a             ;  13 / 203

    ld (ch_a_u_ins_next_ptr), hl                ;  16 / 219

    ; save event pattern pointer
    ld (event_pattern_ptr), sp                  ;  20 / 239

    jp event_return_249                         ;  10 / 249

; ============================================

event_channel_b_instrument:                     ;     / 271

    ; move event pointer into HL and SP
    ex de, hl                                   ;   4 / 275
    ld sp, hl                                   ;   6 / 281

    ; get instrument pointer
    pop hl                                      ;  10 / 291

    ; set instrument pointer variable
    ld (ch_b_ins_initial), hl                   ;  16 / 307
    ld (ch_b_ins_cur_ptr), hl                   ;  16 / 323

    ; timewasting
    nop                                         ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; get initial values
    ld a, (hl)                                  ;   7 / 145
    inc hl                                      ;   6 / 151

    ld (ch_b_ins_timer_initial), a              ;  13 / 164
    ld (ch_b_ins_timer), a                      ;  13 / 177

    ld a, (hl)                                  ;   7 / 184
    inc hl                                      ;   6 / 190

    ld (ch_b_carrier_initial), a                ;  13 / 203

    ld a, (hl)                                  ;   7 / 210
    inc hl                                      ;   6 / 216

    ld (ch_b_mod_initial), a                    ;  13 / 229

    ld (ch_b_ins_next_ptr), hl                  ;  16 / 245

    ; save event pattern pointer
    ld (event_pattern_ptr), sp                  ;  20 / 265

    jp event_return                             ;  10 / 275

; ============================================

event_channel_b_osc_instrument:                 ;     / 271

    ; move event pointer into HL and SP
    ex de, hl                                   ;   4 / 275
    ld sp, hl                                   ;   6 / 281

    ; get instrument pointer
    pop hl                                      ;  10 / 291

    ; set instrument pointer variable
    ld (ch_b_osc_ins_initial), hl               ;  16 / 307
    ld (ch_b_osc_ins_cur_ptr), hl               ;  16 / 323

    ; timewasting
    nop                                         ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; get initial values
    ld a, (hl)                                  ;   7 / 145
    inc hl                                      ;   6 / 151

    ld (ch_b_osc_ins_timer_initial), a          ;  13 / 164
    ld (ch_b_osc_ins_timer), a                  ;  13 / 177

    ld a, (hl)                                  ;   7 / 184
    inc hl                                      ;   6 / 190

    ld (ch_b_osc_wave_initial), a               ;  13 / 203

    ld (ch_b_osc_ins_next_ptr), hl              ;  16 / 219

    ; save event pattern pointer
    ld (event_pattern_ptr), sp                  ;  20 / 239

    jp event_return_249                         ;  10 / 249

; ============================================

BEGIN_PAGE_TABLE("buf0", false)

    loop 60
        db $60

    lend

buf1:
    loop 60
        db $60

    lend

END_PAGE_TABLE("buf0")

; ============================================

run_callback:                                   ;     / 299
    ; Note: need to preserve all registers
    ; except for A, C, E

    ld (save_sp), sp
    ld sp, safe_stack_end

    ; save registers
    push bc
    push de
    push hl
    push ix
    push iy

    ; test if a keypress was detected
    jp z, no_keypress

keypress:

    ; test for Q key
    ld a, $fb
    in a, ($fe)
    and $01
    jp z, keypress_q

    ; test for A key
    ld a, $fd
    in a, ($fe)
    and $01
    jp z, keypress_a

    ; check for enter and space
    ld a, $3f
    in a, ($fe)
    and $01
    jr nz, keypress_cont

keypress_enter:
    SMC_LD(a, "select_index")
    cp $72
    jp z, switch_dac_port
    jp nc, switch_output

    cp $32
    jp nz, switch_chip_channels

switch_chip:

    SMC_LD(a, "chip_type")
    inc a
    cp 3
    jr nz, switch_chip_cont

    xor a

switch_chip_cont:

    ld (chip_type), a

    push af

    add a, low chip_select_table
    ld l, a
    ld h, high chip_select_table

    add a, (hl)
    ld c, a
    ld b, h

    ld hl, $4833
    call print_string

    pop af

    cp 2
    jp z, switch_chip_dac

switch_chip_ay:
    SMC_LD(a, "chip_stereo")
    or a
    push af
    jr z, switch_chip_ay_mono

    add a, low chip_stereo_table
    ld l, a
    ld h, high chip_stereo_table

    add a, (hl)

    ld c, a
    ld b, h

    ld hl, $4853
    call print_string

    ld a, (output_stereo)
    or a
    jr z, switch_chip_ay_mono_out

    ld bc, str_stereo
    ld hl, $48b3
    call print_string

switch_chip_ay_stereo:

    pop af

switch_chip_ay_stereo2:

    cp 2
    jr z, switch_chip_ay_acb
    jr nc, switch_chip_ay_bac

switch_chip_ay_abc:

    ld bc, $080a
    ld a, $09

switch_chip_ay_stereo_cont:

    push af

    ld a, b
    ld (chan_l), a
    ld a, c
    ld (chan_r), a

    ld a, OUTPUT_AY_STEREO

    exx
    push hl
    call SampleOut_setup
    pop hl

    pop af
    out (c), a

    exx

    ld a, (chip_type)
    add a, a
    add a, a
    add a, high vol_table_ay_4bit

    exx
    ld d, a
    exx

keypress_cont:
    ; invert condition
    ld a, $ca ; JP Z, nn
    jr run_callback_done

no_keypress:

    ; invert condition
    ld a, $c2 ; JP NZ, nn

run_callback_done:
    ld (callback_jp), a

    ; restore registers
    pop iy
    pop ix
    pop hl
    pop de
    pop bc

    SMC_LD(sp, "save_sp")

    jp samplegen_fm                             ;  10 / 308

; ============================================

switch_chip_ay_mono:

    ld bc, str_mono
    ld hl, $4853
    call print_string

switch_chip_ay_mono_out:

    pop af
    push af

switch_chip_ay_mono_setup:
    ld a, OUTPUT_AY_MONO
    jr z, switch_chip_ay_mono_cont

    ld a, (chip_stereo)
switch_chip_ay_mono_out2:
    add a, $08
    cp $0b
    jr nz, switch_chip_ay_mono_cont2

    ld a, $08

switch_chip_ay_mono_cont2:

    ld (port_4b), a

    ld a, OUTPUT_AY_MONO_4BIT

switch_chip_ay_mono_cont:

    exx
    push hl
    call SampleOut_setup
    pop hl
    exx

    pop af
    or a
    jr z, switch_chip_ay_mono_cont3

    ld a, 3

switch_chip_ay_mono_cont3:
    ld b, a

    ld a, (chip_type)
    add a, a
    add a, a

    add a, b
    add a, HIGH vol_table_ay

    exx
    ld d, a
    exx

    jr keypress_cont

; ============================================

switch_chip_ay_acb:

    ld bc, $0809
    ld a, $0a

    jp switch_chip_ay_stereo_cont

; ============================================

switch_chip_ay_bac:

    ld bc, $090a
    ld a, $08

    jr switch_chip_ay_stereo_cont

; ============================================

switch_chip_dac:

    ld bc, str_mono
    ld hl, $4853
    call print_string

    ld bc, str_mono
    ld hl, $48b3
    call print_string

switch_chip_setup:

    ld a, OUTPUT_SPECDRUM

    exx
    push hl
    call SampleOut_setup
    pop hl
    exx

    jr keypress_cont

; ============================================

switch_dac_port:

    ld a, (dac_port)
    xor $df ^ $fb
    ld (dac_port), a

    push af

    cp $df+1
    sbc a, a
    inc a

    add a, low dac_port_table
    ld l, a
    ld h, high dac_port_table

    add a, (hl)
    ld c, a
    ld b, h

    ld hl, $4873
    call print_string

    pop af

    ld a, (chip_type)
    cp 2
    jr z, switch_chip_setup

    jp keypress_cont

; ============================================

switch_output:

    ld a, (chip_type)
    cp 2
    jp z, keypress_cont

    ld a, (chip_stereo)
    or a
    jp z, keypress_cont

    ; switch mono/stereo

    SMC_LD(a, "output_stereo")
    xor 1
    ld (output_stereo), a

    push af

    add a, low output_table
    ld l, a
    ld h, high output_table

    add a, (hl)
    ld c, a
    ld b, h

    ld hl, $48b3
    call print_string

    pop af

    jp z, switch_output_mono

    ld a, (chip_stereo)
    jp switch_chip_ay_stereo2

; ============================================

switch_output_mono:

    ld a, (chip_stereo)
    push af

    jp switch_chip_ay_mono_out2

; ============================================

switch_chip_channels:

    ld a, (chip_type)
    cp 2
    jp z, keypress_cont

    ld a, (chip_stereo)
    inc a
    cp 4
    jr nz, switch_chan_cont

    xor a

switch_chan_cont:

    ld (chip_stereo), a

    push af

    add a, low chip_stereo_table
    ld l, a
    ld h, high chip_stereo_table

    add a, (hl)
    ld c, a
    ld b, h

    ld hl, $4853
    call print_string

    pop af
    push af

    or a
    jr nz, switch_chan_stereo

    ld bc, str_mono
    ld hl, $48b3
    call print_string

    ; switched to mono chip

    jp switch_chip_ay_mono_setup

; ============================================

switch_chan_stereo:

    ; stereo chip

    ld a, (output_stereo)

    add a, low output_table
    ld l, a
    ld h, high output_table

    add a, (hl)
    ld c, a
    ld b, h

    ld hl, $48b3
    call print_string

    ld a, (output_stereo)
    or a
    jp z, switch_chip_ay_mono_out

    jp switch_chip_ay_stereo

; ============================================

keypress_q:

    ; check if we can move up
    ld a, (select_index)
    cp $32
    jp z, keypress_cont

    push af

    ld l, a
    ld h, $59

    ld a, 6 << 3
    call print_selection

    pop af

    ; move up
    sub $20
    cp $92
    jr nz, keypress_q_cont

    sub $20

keypress_q_cont:
    ld (select_index), a

    ld l, a

    ld a, 6
    call print_selection

    jp keypress_cont

; ============================================

keypress_a:

    ; check if we can move down
    ld a, (select_index)
    cp $b2
    jp z, keypress_cont

    push af

    ld l, a
    ld h, $59

    ld a, 6 << 3
    call print_selection

    pop af

    ; move down
    add a, $20
    cp $92
    jr nz, keypress_a_cont

    add a, $20

keypress_a_cont:
    ld (select_index), a

    ld l, a

    ld a, 6
    call print_selection

    jp keypress_cont

; ============================================

event_channel_c_instrument:                     ;     / 271

    ; move event pointer into HL and SP
    ex de, hl                                   ;   4 / 275
    ld sp, hl                                   ;   6 / 281

    ; get instrument pointer
    pop hl                                      ;  10 / 291

    ; set instrument pointer variable
    ld (ch_c_ins_initial), hl                   ;  16 / 307
    ld (ch_c_ins_cur_ptr), hl                   ;  16 / 323

    ; timewasting
    nop                                         ;   4 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; get initial values
    ld a, (hl)                                  ;   7 / 145
    inc hl                                      ;   6 / 151

    ld (ch_c_ins_timer_initial), a              ;  13 / 164
    ld (ch_c_ins_timer), a                      ;  13 / 177

    ld a, (hl)                                  ;   7 / 184
    inc hl                                      ;   6 / 190

    ld (ch_c_carrier_initial), a                ;  13 / 203

    ld a, (hl)                                  ;   7 / 210
    inc hl                                      ;   6 / 216

    ld (ch_c_mod_initial), a                    ;  13 / 229

    ld (ch_c_ins_next_ptr), hl                  ;  16 / 245

    ; save event pattern pointer
    ld (event_pattern_ptr), sp                  ;  20 / 265

    jp event_return                             ;  10 / 275

; ============================================

event_channel_a_pitch_bend:                     ;     / 271

    ; move event pointer into HL and SP
    ex de, hl                                   ;   4 / 275
    ld sp, hl                                   ;   6 / 281

    ; get pitch bend amount
    pop hl                                      ;  10 / 291

    ; timewasting
    jr $+2                                      ;  12 / 303

    ld ix, event_channel_a_pitch_bend_return    ;  14 / 317

    jp sample_out_1                             ;  10 / 327

; ============================================

event_channel_a_pitch_bend_return:              ;     / 146

    ; load pitch bend variable
    ld (ch_a_bend), hl                          ;  16 / 162

    ; a non-zero third byte means to reset the
    ; accumulated bend
    pop bc                                      ;  10 / 172
    dec sp                                      ;   6 / 178

    ; resave event pattern pointer
    ld (event_pattern_ptr), sp                  ;  20 / 198

    ; C contains the reset flag for the
    ; accumulated bend
    ld a, c                                     ;   4 / 202
    or a                                        ;   4 / 206
    jp nz, channel_a_pitch_bend_no_reset        ;  10 / 216

    ld h, a                                     ;   4 / 220
    ld l, a                                     ;   4 / 224

    ld (ch_a_bend_accum), hl                    ;  16 / 240

    ; timewasting
    inc hl                                      ;   6 / 246
    nop                                         ;   4 / 250

    jp event_return_260                         ;  10 / 260

; ============================================

channel_a_pitch_bend_no_reset:                  ;     / 216

    jp event_return_226                         ;  10 / 226

; ============================================

event_channel_b_pitch_bend:                     ;     / 271

    ; move event pointer into HL and SP
    ex de, hl                                   ;   4 / 275
    ld sp, hl                                   ;   6 / 281

    ; get pitch bend amount
    pop hl                                      ;  10 / 291

    ; timewasting
    jr $+2                                      ;  12 / 303

    ld ix, event_channel_b_pitch_bend_return    ;  14 / 317

    jp sample_out_1                             ;  10 / 327

; ============================================

event_channel_b_pitch_bend_return:              ;     / 146

    ; load pitch bend variable
    ld (ch_b_bend), hl                          ;  16 / 162

    ; a non-zero third byte means to reset the
    ; accumulated bend
    pop bc                                      ;  10 / 172
    dec sp                                      ;   6 / 178

    ; resave event pattern pointer
    ld (event_pattern_ptr), sp                  ;  20 / 198

    ; C contains the reset flag for the
    ; accumulated bend
    ld a, c                                     ;   4 / 202
    or a                                        ;   4 / 206
    jp nz, channel_b_pitch_bend_no_reset        ;  10 / 216

    ld h, a                                     ;   4 / 220
    ld l, a                                     ;   4 / 224

    ld (ch_b_bend_accum), hl                    ;  16 / 240
    ld (ch_b_bend_accum2), hl                   ;  16 / 256

    ; timewasting [CAUTION!]
    ret nz                                      ;   5 / 261

    jp event_return_271                         ;  10 / 271

; ============================================

channel_b_pitch_bend_no_reset:                  ;     / 216

    jp event_return_226                         ;  10 / 226

; ============================================

event_channel_c_pitch_bend:                     ;     / 271

    ; move event pointer into HL and SP
    ex de, hl                                   ;   4 / 275
    ld sp, hl                                   ;   6 / 281

    ; get pitch bend amount
    pop hl                                      ;  10 / 291

    ; timewasting
    jr $+2                                      ;  12 / 303

    ld ix, event_channel_c_pitch_bend_return    ;  14 / 317

    jp sample_out_1                             ;  10 / 327

; ============================================

event_channel_c_pitch_bend_return:              ;     / 146

    ; load pitch bend variable
    ld (ch_c_bend), hl                          ;  16 / 162

    ; a non-zero third byte means to reset the
    ; accumulated bend
    pop bc                                      ;  10 / 172
    dec sp                                      ;   6 / 178

    ; resave event pattern pointer
    ld (event_pattern_ptr), sp                  ;  20 / 198

    ; C contains the reset flag for the
    ; accumulated bend
    ld a, c                                     ;   4 / 202
    or a                                        ;   4 / 206
    jp nz, channel_c_pitch_bend_no_reset        ;  10 / 216

    ld h, a                                     ;   4 / 220
    ld l, a                                     ;   4 / 224

    ld (ch_c_bend_accum), hl                    ;  16 / 240

    ; timewasting
    inc hl                                      ;   6 / 246
    nop                                         ;   4 / 250

    jp event_return_260                         ;  10 / 260

; ============================================

channel_c_pitch_bend_no_reset:                  ;     / 216

    jp event_return_226                         ;  10 / 226

; ============================================

event_channel_a_ornament:                       ;     / 271

    ; get ornament number
    ld a, (de)                                  ;   7 / 278
    inc de                                      ;   6 / 284

    ; resave event pattern pointer
    ld (event_pattern_ptr), de                  ;  20 / 304

    ; look it up in the ornament table
    ld l, a                                     ;   4 / 308
    ld h, HIGH ornament_table                   ;   7 / 315

    ld sp, hl                                   ;   6 / 321

    ; timewasting (modifying DE is safe)
    inc de                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; copy ornament pointers (start pointer and
    ; loop pointer)
    pop hl                                      ;  10 / 148
    ld (ch_a_orn_ptr), hl                       ;  16 / 164
    ld (ch_a_orn_ptr_initial), hl               ;  16 / 180

    ld a, (hl)                                  ;   7 / 187
    ld (ch_a_orn_initial), a                    ;  13 / 200

    pop hl                                      ;  10 / 210
    ld (ch_a_orn_loop_ptr), hl                  ;  16 / 226

    jp event_return_236                         ;  10 / 236

; ============================================

event_channel_b_ornament:                       ;     / 271

    ; get ornament number
    ld a, (de)                                  ;   7 / 278
    inc de                                      ;   6 / 284

    ; resave event pattern pointer
    ld (event_pattern_ptr), de                  ;  20 / 304

    ; look it up in the ornament table
    ld l, a                                     ;   4 / 308
    ld h, HIGH ornament_table                   ;   7 / 315

    ld sp, hl                                   ;   6 / 321

    ; timewasting (modifying DE is safe)
    inc de                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; copy ornament pointers (start pointer and
    ; loop pointer)
    pop hl                                      ;  10 / 148
    ld (ch_b_orn_ptr), hl                       ;  16 / 164
    ld (ch_b_orn_ptr_initial), hl               ;  16 / 180

    ld a, (hl)                                  ;   7 / 187
    ld (ch_b_orn_initial), a                    ;  13 / 200

    pop hl                                      ;  10 / 210
    ld (ch_b_orn_loop_ptr), hl                  ;  16 / 226

    jp event_return_236                         ;  10 / 236

; ============================================

event_channel_c_ornament:                       ;     / 271

    ; get ornament number
    ld a, (de)                                  ;   7 / 278
    inc de                                      ;   6 / 284

    ; resave event pattern pointer
    ld (event_pattern_ptr), de                  ;  20 / 304

    ; look it up in the ornament table
    ld l, a                                     ;   4 / 308
    ld h, HIGH ornament_table                   ;   7 / 315

    ld sp, hl                                   ;   6 / 321

    ; timewasting (modifying DE is safe)
    inc de                                      ;   6 / 327

    exx                                         ;   4 / 331
    SampleOut(1)                                ; 134 / 134
    exx                                         ;   4 / 138

    ; copy ornament pointers (start pointer and
    ; loop pointer)
    pop hl                                      ;  10 / 148
    ld (ch_c_orn_ptr), hl                       ;  16 / 164
    ld (ch_c_orn_ptr_initial), hl               ;  16 / 180

    ld a, (hl)                                  ;   7 / 187
    ld (ch_c_orn_initial), a                    ;  13 / 200

    pop hl                                      ;  10 / 210
    ld (ch_c_orn_loop_ptr), hl                  ;  16 / 226

    jp event_return_236                         ;  10 / 236

; ============================================

event_set_song_speed:                           ;     / 271

    inc de                                      ;   6 / 277

    ; resave event pattern pointer
    ld (event_pattern_ptr), de                  ;  20 / 297

    ; restore old event pattern pointer
    dec de                                      ;   6 / 303

    ld ix, event_set_song_speed_return          ;  14 / 317

    jp sample_out_1                             ;  10 / 327

; ============================================

event_set_song_speed_return:                    ;     / 146

    ; get new song speed
    ld a, (de)                                  ;   7 / 153

    ; update song_speed references
    ld (song_speed0), a                         ;  13 / 166
    ld (song_speed1), a                         ;  13 / 179
    ld (song_speed2), a                         ;  13 / 192
    ld (song_speed3), a                         ;  13 / 205
    ld (song_speed4), a                         ;  13 / 218
    ld (song_speed5), a                         ;  13 / 231

    ; update song timer itself
    ld (song_timer), a                          ;  13 / 244

    ; timewasting
    inc hl                                      ;   6 / 250

    jp event_return_260                         ;  10 / 260

; ============================================

event_set_bank:                                 ;     / 271

    inc de                                      ;   6 / 277

    ; resave event pattern pointer
    ld (event_pattern_ptr), de                  ;  20 / 297

    ; restore old event pattern pointer
    dec de                                      ;   6 / 303

    ld ix, event_set_bank_return                ;  14 / 317

    jp sample_out_1                             ;  10 / 327

; ============================================

event_set_bank_return:                          ;     / 146

    ; get new bank
    ld a, (de)                                  ;   7 / 153

    SMC_LD(bc, "paging_port")                   ;  10 / 163

    ; switch banks
    out (c), a                                  ;  12 / 175

    ; timewasting [CAREFUL!]
    cp (hl)                                     ;   7 / 182

    jp event_return_192                         ;  10 / 192

; ============================================

EMPTY_INS_CARRIER   equ HIGH empty_waveform
EMPTY_INS_MOD       equ HIGH sawtooth_waveform_mod
EMPTY_INS_TIMER     equ 1

empty_instrument:
empty_instrument_loop:
    db 1, EMPTY_INS_CARRIER, EMPTY_INS_MOD
    db 0
    dw empty_instrument_loop

empty_instrument_osc_sync:
empty_instrument_osc_sync_loop:
    db 1, EMPTY_INS_CARRIER
    db 0
    dw empty_instrument_osc_sync_loop

; impossible value (ornaments must be even)
ORNAMENT_END    equ 1

empty_ornament:
empty_ornament_loop:
    db 2*0
    db ORNAMENT_END

major_seventh_chord:
major_seventh_chord_loop:
    db 2*0
    db 2*4
    db 2*7
    db 2*14
    db ORNAMENT_END

; ============================================

BEGIN_PAGE_TABLE("ornament_table", false)

    EMPTY_ORNAMENT  equ LOW $

    dw empty_ornament, empty_ornament_loop

    MAJOR_7TH_ORNAMENT  equ LOW $

    dw major_seventh_chord, major_seventh_chord_loop

END_PAGE_TABLE("ornament_table")

; ============================================

include "song.asm"

; ============================================

; adjust SAMPLE_OUT_COUNT so this assertion passes
zeusassert (sample_out_counter = SAMPLE_OUT_COUNT)

SHOW_BANK_USAGE()

; ============================================

; Final state of variables.

bank_start_0_fin    equ bank_start_0
bank_size_0_fin     equ bank_size_0

bank_start_2_fin    equ bank_start_2
bank_size_2_fin     equ bank_size_2

bank_start_5_fin    equ bank_start_5
bank_size_5_fin     equ bank_size_5

; ============================================
