gb-tarot/gbt_player_bank1.inc

1390 lines
26 KiB
PHP

;###############################################################################
;
; GBT Player v3.1.0
;
; SPDX-License-Identifier: MIT
;
; Copyright (c) 2009-2020 Antonio Niño Díaz <antonio_nd@outlook.com>
;
;###############################################################################
INCLUDE "hardware.inc"
INCLUDE "gbt_player.inc"
;###############################################################################
SECTION "GBT_BANK1",ROMX,BANK[1]
;-------------------------------------------------------------------------------
gbt_wave: ; 8 sounds
DB $A5,$D7,$C9,$E1,$BC,$9A,$76,$31,$0C,$BA,$DE,$60,$1B,$CA,$03,$93 ; random
DB $F0,$E1,$D2,$C3,$B4,$A5,$96,$87,$78,$69,$5A,$4B,$3C,$2D,$1E,$0F
DB $FD,$EC,$DB,$CA,$B9,$A8,$97,$86,$79,$68,$57,$46,$35,$24,$13,$02 ; up-downs
DB $DE,$FE,$DC,$BA,$9A,$A9,$87,$77,$88,$87,$65,$56,$54,$32,$10,$12
DB $AB,$CD,$EF,$ED,$CB,$A0,$12,$3E,$DC,$BA,$BC,$DE,$FE,$DC,$32,$10 ; tri. broken
DB $FF,$EE,$DD,$CC,$BB,$AA,$99,$88,$77,$66,$55,$44,$33,$22,$11,$00 ; triangular
DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$00,$00,$00,$00 ; square
DB $79,$BC,$DE,$EF,$FF,$EE,$DC,$B9,$75,$43,$21,$10,$00,$11,$23,$45 ; sine
gbt_noise: ; 16 sounds
; 7 bit
DB $5F,$5B,$4B,$2F,$3B,$58,$1F,$0F
; 15 bit
DB $90,$80,$70,$50,$00
DB $67,$63,$53
gbt_frequencies:
DW 44, 156, 262, 363, 457, 547, 631, 710, 786, 854, 923, 986
DW 1046, 1102, 1155, 1205, 1253, 1297, 1339, 1379, 1417, 1452, 1486, 1517
DW 1546, 1575, 1602, 1627, 1650, 1673, 1694, 1714, 1732, 1750, 1767, 1783
DW 1798, 1812, 1825, 1837, 1849, 1860, 1871, 1881, 1890, 1899, 1907, 1915
DW 1923, 1930, 1936, 1943, 1949, 1954, 1959, 1964, 1969, 1974, 1978, 1982
DW 1985, 1988, 1992, 1995, 1998, 2001, 2004, 2006, 2009, 2011, 2013, 2015
;-------------------------------------------------------------------------------
_gbt_get_freq_from_index: ; a = index, bc = returned freq
ld hl,gbt_frequencies
ld c,a
ld b,$00
add hl,bc
add hl,bc
ld c,[hl]
inc hl
ld b,[hl]
ret
;-------------------------------------------------------------------------------
; ---------------------------------- Channel 1 ---------------------------------
;-------------------------------------------------------------------------------
gbt_channel_1_handle:: ; de = info
ld a,[gbt_channels_enabled]
and a,$01
jr nz,.channel1_enabled
; Channel is disabled. Increment pointer as needed
ld a,[de]
inc de
bit 7,a
jr nz,.more_bytes
bit 6,a
jr z,.no_more_bytes_this_channel
jr .one_more_byte
.more_bytes:
ld a,[de]
inc de
bit 7,a
jr z,.no_more_bytes_this_channel
.one_more_byte:
inc de
.no_more_bytes_this_channel:
ret
.channel1_enabled:
; Channel 1 is enabled
ld a,[de]
inc de
bit 7,a
jr nz,.has_frequency
; Not frequency
bit 6,a
jr nz,.instr_effects
; Set volume or NOP
bit 5,a
jr nz,.just_set_volume
; NOP
ret
.just_set_volume:
; Set volume
and a,$0F
swap a
ld [gbt_vol+0],a
jr .refresh_channel1_regs
.instr_effects:
; Set instrument and effect
ld b,a ; save byte
and a,$30
add a,a
add a,a
ld [gbt_instr+0],a ; Instrument
ld a,b ; restore byte
and a,$0F ; a = effect
call gbt_channel_1_set_effect
jr .refresh_channel1_regs
.has_frequency:
; Has frequency
and a,$7F
ld [gbt_arpeggio_freq_index+0*3],a
; This destroys hl and a. Returns freq in bc
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+0*2+0],a
ld a,b
ld [gbt_freq+0*2+1],a ; Get frequency
ld a,[de]
inc de
bit 7,a
jr nz,.freq_instr_and_effect
; Freq + Instr + Volume
ld b,a ; save byte
and a,$30
add a,a
add a,a
ld [gbt_instr+0],a ; Instrument
ld a,b ; restore byte
and a,$0F ; a = volume
swap a
ld [gbt_vol+0],a
jr .refresh_channel1_regs
.freq_instr_and_effect:
; Freq + Instr + Effect
ld b,a ; save byte
and a,$30
add a,a
add a,a
ld [gbt_instr+0],a ; Instrument
ld a,b ; restore byte
and a,$0F ; a = effect
call gbt_channel_1_set_effect
;jr .refresh_channel1_regs
.refresh_channel1_regs:
; fall through!!!!!
; -----------------
channel1_refresh_registers:
xor a,a
ld [rNR10],a
ld a,[gbt_instr+0]
ld [rNR11],a
ld a,[gbt_vol+0]
ld [rNR12],a
ld a,[gbt_freq+0*2+0]
ld [rNR13],a
ld a,[gbt_freq+0*2+1]
or a,$80 ; start
ld [rNR14],a
ret
; ------------------
channel1_update_effects: ; returns 1 in a if it needed to update sound registers
; Cut note
; --------
ld a,[gbt_cut_note_tick+0]
ld hl,gbt_ticks_elapsed
cp a,[hl]
jp nz,.dont_cut
dec a ; a = $FF
ld [gbt_cut_note_tick+0],a ; disable cut note
xor a,a ; vol = 0
ld [rNR12],a
ld a,$80 ; start
ld [rNR14],a
.dont_cut:
; Arpeggio
; --------
ld a,[gbt_arpeggio_enabled+0]
and a,a
ret z ; a is 0, return 0
; If enabled arpeggio, handle it
ld a,[gbt_arpeggio_tick+0]
and a,a
jr nz,.not_tick_0
; Tick 0 - Set original frequency
ld a,[gbt_arpeggio_freq_index+0*3+0]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+0*2+0],a
ld a,b
ld [gbt_freq+0*2+1],a ; Set frequency
ld a,1
ld [gbt_arpeggio_tick+0],a
ret ; ret 1
.not_tick_0:
cp a,1
jr nz,.not_tick_1
; Tick 1
ld a,[gbt_arpeggio_freq_index+0*3+1]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+0*2+0],a
ld a,b
ld [gbt_freq+0*2+1],a ; Set frequency
ld a,2
ld [gbt_arpeggio_tick+0],a
dec a
ret ; ret 1
.not_tick_1:
; Tick 2
ld a,[gbt_arpeggio_freq_index+0*3+2]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+0*2+0],a
ld a,b
ld [gbt_freq+0*2+1],a ; Set frequency
xor a,a
ld [gbt_arpeggio_tick+0],a
inc a ; ret 1
ret
; -----------------
; returns a = 1 if needed to update registers, 0 if not
gbt_channel_1_set_effect: ; a = effect, de = pointer to data.
ld hl,.gbt_ch1_jump_table
ld c,a
ld b,0
add hl,bc
add hl,bc
ld a,[hl+]
ld h,[hl]
ld l,a
ld a,[de] ; load args
inc de
jp hl
.gbt_ch1_jump_table:
DW .gbt_ch1_pan
DW .gbt_ch1_arpeggio
DW .gbt_ch1_cut_note
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_jump_pattern
DW gbt_ch1234_jump_position
DW gbt_ch1234_speed
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
.gbt_ch1_pan:
and a,$11
ld [gbt_pan+0],a
xor a,a
ret ; ret 0 do not update registers, only NR51 at end.
.gbt_ch1_arpeggio:
ld b,a ; b = params
ld hl,gbt_arpeggio_freq_index+0*3
ld c,[hl] ; c = base index
inc hl
ld a,b
swap a
and a,$0F
add a,c
ld [hl+],a ; save first increment
ld a,b
and a,$0F
add a,c
ld [hl],a ; save second increment
ld a,1
ld [gbt_arpeggio_enabled+0],a
ld [gbt_arpeggio_tick+0],a
ret ; ret 1
.gbt_ch1_cut_note:
ld [gbt_cut_note_tick+0],a
xor a,a ; ret 0
ret
;-------------------------------------------------------------------------------
; ---------------------------------- Channel 2 ---------------------------------
;-------------------------------------------------------------------------------
gbt_channel_2_handle:: ; de = info
ld a,[gbt_channels_enabled]
and a,$02
jr nz,.channel2_enabled
; Channel is disabled. Increment pointer as needed
ld a,[de]
inc de
bit 7,a
jr nz,.more_bytes
bit 6,a
jr z,.no_more_bytes_this_channel
jr .one_more_byte
.more_bytes:
ld a,[de]
inc de
bit 7,a
jr z,.no_more_bytes_this_channel
.one_more_byte:
inc de
.no_more_bytes_this_channel:
ret
.channel2_enabled:
; Channel 2 is enabled
ld a,[de]
inc de
bit 7,a
jr nz,.has_frequency
; Not frequency
bit 6,a
jr nz,.instr_effects
; Set volume or NOP
bit 5,a
jr nz,.just_set_volume
; NOP
ret
.just_set_volume:
; Set volume
and a,$0F
swap a
ld [gbt_vol+1],a
jr .refresh_channel2_regs
.instr_effects:
; Set instrument and effect
ld b,a ; save byte
and a,$30
add a,a
add a,a
ld [gbt_instr+1],a ; Instrument
ld a,b ; restore byte
and a,$0F ; a = effect
call gbt_channel_2_set_effect
jr .refresh_channel2_regs
.has_frequency:
; Has frequency
and a,$7F
ld [gbt_arpeggio_freq_index+1*3],a
; This destroys hl and a. Returns freq in bc
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+1*2+0],a
ld a,b
ld [gbt_freq+1*2+1],a ; Get frequency
ld a,[de]
inc de
bit 7,a
jr nz,.freq_instr_and_effect
; Freq + Instr + Volume
ld b,a ; save byte
and a,$30
add a,a
add a,a
ld [gbt_instr+1],a ; Instrument
ld a,b ; restore byte
and a,$0F ; a = volume
swap a
ld [gbt_vol+1],a
jr .refresh_channel2_regs
.freq_instr_and_effect:
; Freq + Instr + Effect
ld b,a ; save byte
and a,$30
add a,a
add a,a
ld [gbt_instr+1],a ; Instrument
ld a,b ; restore byte
and a,$0F ; a = effect
call gbt_channel_2_set_effect
;jr .refresh_channel2_regs
.refresh_channel2_regs:
; fall through!!!!!
; -----------------
channel2_refresh_registers:
ld a,[gbt_instr+1]
ld [rNR21],a
ld a,[gbt_vol+1]
ld [rNR22],a
ld a,[gbt_freq+1*2+0]
ld [rNR23],a
ld a,[gbt_freq+1*2+1]
or a,$80 ; start
ld [rNR24],a
ret
; ------------------
channel2_update_effects: ; returns 1 in a if it needed to update sound registers
; Cut note
; --------
ld a,[gbt_cut_note_tick+1]
ld hl,gbt_ticks_elapsed
cp a,[hl]
jp nz,.dont_cut
dec a ; a = $FF
ld [gbt_cut_note_tick+1],a ; disable cut note
xor a,a ; vol = 0
ld [rNR22],a
ld a,$80 ; start
ld [rNR24],a
.dont_cut:
; Arpeggio
; --------
ld a,[gbt_arpeggio_enabled+1]
and a,a
ret z ; a is 0, return 0
; If enabled arpeggio, handle it
ld a,[gbt_arpeggio_tick+1]
and a,a
jr nz,.not_tick_0
; Tick 0 - Set original frequency
ld a,[gbt_arpeggio_freq_index+1*3+0]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+1*2+0],a
ld a,b
ld [gbt_freq+1*2+1],a ; Set frequency
ld a,1
ld [gbt_arpeggio_tick+1],a
ret ; ret 1
.not_tick_0:
cp a,1
jr nz,.not_tick_1
; Tick 1
ld a,[gbt_arpeggio_freq_index+1*3+1]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+1*2+0],a
ld a,b
ld [gbt_freq+1*2+1],a ; Set frequency
ld a,2
ld [gbt_arpeggio_tick+1],a
dec a
ret ; ret 1
.not_tick_1:
; Tick 2
ld a,[gbt_arpeggio_freq_index+1*3+2]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+1*2+0],a
ld a,b
ld [gbt_freq+1*2+1],a ; Set frequency
xor a,a
ld [gbt_arpeggio_tick+1],a
inc a ; ret 1
ret
; -----------------
; returns a = 1 if needed to update registers, 0 if not
gbt_channel_2_set_effect: ; a = effect, de = pointer to data
ld hl,.gbt_ch2_jump_table
ld c,a
ld b,0
add hl,bc
add hl,bc
ld a,[hl+]
ld h,[hl]
ld l,a
ld a,[de] ; load args
inc de
jp hl
.gbt_ch2_jump_table:
DW .gbt_ch2_pan
DW .gbt_ch2_arpeggio
DW .gbt_ch2_cut_note
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_jump_pattern
DW gbt_ch1234_jump_position
DW gbt_ch1234_speed
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
.gbt_ch2_pan:
and a,$22
ld [gbt_pan+1],a
xor a,a
ret ; ret 0 do not update registers, only NR51 at end.
.gbt_ch2_arpeggio:
ld b,a ; b = params
ld hl,gbt_arpeggio_freq_index+1*3
ld c,[hl] ; c = base index
inc hl
ld a,b
swap a
and a,$0F
add a,c
ld [hl+],a ; save first increment
ld a,b
and a,$0F
add a,c
ld [hl],a ; save second increment
ld a,1
ld [gbt_arpeggio_enabled+1],a
ld [gbt_arpeggio_tick+1],a
ret ; ret 1
.gbt_ch2_cut_note:
ld [gbt_cut_note_tick+1],a
xor a,a ; ret 0
ret
;-------------------------------------------------------------------------------
; ---------------------------------- Channel 3 ---------------------------------
;-------------------------------------------------------------------------------
gbt_channel_3_handle:: ; de = info
ld a,[gbt_channels_enabled]
and a,$04
jr nz,.channel3_enabled
; Channel is disabled. Increment pointer as needed
ld a,[de]
inc de
bit 7,a
jr nz,.more_bytes
bit 6,a
jr z,.no_more_bytes_this_channel
jr .one_more_byte
.more_bytes:
ld a,[de]
inc de
bit 7,a
jr z,.no_more_bytes_this_channel
.one_more_byte:
inc de
.no_more_bytes_this_channel:
ret
.channel3_enabled:
; Channel 3 is enabled
ld a,[de]
inc de
bit 7,a
jr nz,.has_frequency
; Not frequency
bit 6,a
jr nz,.effects
; Set volume or NOP
bit 5,a
jr nz,.just_set_volume
; NOP
ret
.just_set_volume:
; Set volume
and a,$0F
swap a
ld [gbt_vol+2],a
jr .refresh_channel3_regs
.effects:
; Set effect
and a,$0F ; a = effect
call gbt_channel_3_set_effect
and a,a
ret z ; if 0, don't refresh registers
jr .refresh_channel3_regs
.has_frequency:
; Has frequency
and a,$7F
ld [gbt_arpeggio_freq_index+2*3],a
; This destroys hl and a. Returns freq in bc
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+2*2+0],a
ld a,b
ld [gbt_freq+2*2+1],a ; Get frequency
ld a,[de]
inc de
bit 7,a
jr nz,.freq_instr_and_effect
; Freq + Instr + Volume
ld b,a ; save byte
and a,$0F
ld [gbt_instr+2],a ; Instrument
ld a,b ; restore byte
and a,$30 ; a = volume
add a,a
ld [gbt_vol+2],a
jr .refresh_channel3_regs
.freq_instr_and_effect:
; Freq + Instr + Effect
ld b,a ; save byte
and a,$0F
ld [gbt_instr+2],a ; Instrument
ld a,b ; restore byte
and a,$70
swap a ; a = effect (only 0-7 allowed here)
call gbt_channel_3_set_effect
;jr .refresh_channel3_regs
.refresh_channel3_regs:
; fall through!!!!!
; -----------------
channel3_refresh_registers:
xor a,a
ld [rNR30],a ; disable
ld a,[gbt_channel3_loaded_instrument]
ld b,a
ld a,[gbt_instr+2]
cp a,b
call nz,gbt_channel3_load_instrument ; a = instrument
ld a,$80
ld [rNR30],a ; enable
xor a,a
ld [rNR31],a
ld a,[gbt_vol+2]
ld [rNR32],a
ld a,[gbt_freq+2*2+0]
ld [rNR33],a
ld a,[gbt_freq+2*2+1]
or a,$80 ; start
ld [rNR34],a
ret
; ------------------
gbt_channel3_load_instrument:
ld [gbt_channel3_loaded_instrument],a
swap a ; a = a * 16
ld c,a
ld b,0
ld hl,gbt_wave
add hl,bc
ld c,$30
ld b,16
.loop:
ld a,[hl+]
ld [$FF00+c],a
inc c
dec b
jr nz,.loop
ret
; ------------------
channel3_update_effects: ; returns 1 in a if it needed to update sound registers
; Cut note
; --------
ld a,[gbt_cut_note_tick+2]
ld hl,gbt_ticks_elapsed
cp a,[hl]
jp nz,.dont_cut
dec a ; a = $FF
ld [gbt_cut_note_tick+2],a ; disable cut note
ld a,$80
ld [rNR30],a ; enable
xor a,a ; vol = 0
ld [rNR32],a
ld a,$80 ; start
ld [rNR34],a
.dont_cut:
; Arpeggio
; --------
ld a,[gbt_arpeggio_enabled+2]
and a,a
ret z ; a is 0, return 0
; If enabled arpeggio, handle it
ld a,[gbt_arpeggio_tick+2]
and a,a
jr nz,.not_tick_0
; Tick 0 - Set original frequency
ld a,[gbt_arpeggio_freq_index+2*3+0]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+2*2+0],a
ld a,b
ld [gbt_freq+2*2+1],a ; Set frequency
ld a,1
ld [gbt_arpeggio_tick+2],a
ret ; ret 1
.not_tick_0:
cp a,1
jr nz,.not_tick_1
; Tick 1
ld a,[gbt_arpeggio_freq_index+2*3+1]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+2*2+0],a
ld a,b
ld [gbt_freq+2*2+1],a ; Set frequency
ld a,2
ld [gbt_arpeggio_tick+2],a
dec a
ret ; ret 1
.not_tick_1:
; Tick 2
ld a,[gbt_arpeggio_freq_index+2*3+2]
call _gbt_get_freq_from_index
ld a,c
ld [gbt_freq+2*2+0],a
ld a,b
ld [gbt_freq+2*2+1],a ; Set frequency
xor a,a
ld [gbt_arpeggio_tick+2],a
inc a
ret ; ret 1
; -----------------
; returns a = 1 if needed to update registers, 0 if not
gbt_channel_3_set_effect: ; a = effect, de = pointer to data
ld hl,.gbt_ch3_jump_table
ld c,a
ld b,0
add hl,bc
add hl,bc
ld a,[hl+]
ld h,[hl]
ld l,a
ld a,[de] ; load args
inc de
jp hl
.gbt_ch3_jump_table:
DW .gbt_ch3_pan
DW .gbt_ch3_arpeggio
DW .gbt_ch3_cut_note
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_jump_pattern
DW gbt_ch1234_jump_position
DW gbt_ch1234_speed
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
.gbt_ch3_pan:
and a,$44
ld [gbt_pan+2],a
xor a,a
ret ; ret 0 do not update registers, only NR51 at end.
.gbt_ch3_arpeggio:
ld b,a ; b = params
ld hl,gbt_arpeggio_freq_index+2*3
ld c,[hl] ; c = base index
inc hl
ld a,b
swap a
and a,$0F
add a,c
ld [hl+],a ; save first increment
ld a,b
and a,$0F
add a,c
ld [hl],a ; save second increment
ld a,1
ld [gbt_arpeggio_enabled+2],a
ld [gbt_arpeggio_tick+2],a
ret ; ret 1
.gbt_ch3_cut_note:
ld [gbt_cut_note_tick+2],a
xor a,a ; ret 0
ret
;-------------------------------------------------------------------------------
; ---------------------------------- Channel 4 ---------------------------------
;-------------------------------------------------------------------------------
gbt_channel_4_handle:: ; de = info
ld a,[gbt_channels_enabled]
and a,$08
jr nz,.channel4_enabled
; Channel is disabled. Increment pointer as needed
ld a,[de]
inc de
bit 7,a
jr nz,.more_bytes
bit 6,a
jr z,.no_more_bytes_this_channel
jr .one_more_byte
.more_bytes:
ld a,[de]
inc de
bit 7,a
jr z,.no_more_bytes_this_channel
.one_more_byte:
inc de
.no_more_bytes_this_channel:
ret
.channel4_enabled:
; Channel 4 is enabled
ld a,[de]
inc de
bit 7,a
jr nz,.has_instrument
; Not instrument
bit 6,a
jr nz,.effects
; Set volume or NOP
bit 5,a
jr nz,.just_set_volume
; NOP
ret
.just_set_volume:
; Set volume
and a,$0F
swap a
ld [gbt_vol+3],a
jr .refresh_channel4_regs
.effects:
; Set effect
and a,$0F ; a = effect
call gbt_channel_4_set_effect
and a,a
ret z ; if 0, don't refresh registers
jr .refresh_channel4_regs
.has_instrument:
; Has instrument
and a,$0F
ld hl,gbt_noise
ld c,a
ld b,0
add hl,bc
ld a,[hl] ; a = instrument data
ld [gbt_instr+3],a
ld a,[de]
inc de
bit 7,a
jr nz,.instr_and_effect
; Instr + Volume
and a,$0F ; a = volume
swap a
ld [gbt_vol+3],a
jr .refresh_channel4_regs
.instr_and_effect:
; Instr + Effect
and a,$0F ; a = effect
call gbt_channel_4_set_effect
;jr .refresh_channel4_regs
.refresh_channel4_regs:
; fall through!!!!!
; -----------------
channel4_refresh_registers:
xor a,a
ld [rNR41],a
ld a,[gbt_vol+3]
ld [rNR42],a
ld a,[gbt_instr+3]
ld [rNR43],a
ld a,$80 ; start
ld [rNR44],a
ret
; ------------------
channel4_update_effects: ; returns 1 in a if it needed to update sound registers
; Cut note
; --------
ld a,[gbt_cut_note_tick+3]
ld hl,gbt_ticks_elapsed
cp a,[hl]
jp nz,.dont_cut
dec a ; a = $FF
ld [gbt_cut_note_tick+3],a ; disable cut note
xor a,a ; vol = 0
ld [rNR42],a
ld a,$80 ; start
ld [rNR44],a
.dont_cut:
xor a,a
ret ; a is 0, return 0
; -----------------
; returns a = 1 if needed to update registers, 0 if not
gbt_channel_4_set_effect: ; a = effect, de = pointer to data
ld hl,.gbt_ch4_jump_table
ld c,a
ld b,0
add hl,bc
add hl,bc
ld a,[hl+]
ld h,[hl]
ld l,a
ld a,[de] ; load args
inc de
jp hl
.gbt_ch4_jump_table:
DW .gbt_ch4_pan
DW gbt_ch1234_nop ; gbt_ch4_arpeggio
DW .gbt_ch4_cut_note
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_jump_pattern
DW gbt_ch1234_jump_position
DW gbt_ch1234_speed
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
DW gbt_ch1234_nop
.gbt_ch4_pan:
and a,$88
ld [gbt_pan+3],a
xor a,a
ret ; ret 0 do not update registers, only NR51 at end.
.gbt_ch4_cut_note:
ld [gbt_cut_note_tick+3],a
xor a,a ; ret 0
ret
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; Common effects go here:
gbt_ch1234_nop:
xor a,a ;ret 0
ret
gbt_ch1234_jump_pattern:
ld [gbt_current_pattern],a
xor a,a
ld [gbt_current_step],a
ld [gbt_have_to_stop_next_step],a ; clear stop flag
ld a,1
ld [gbt_update_pattern_pointers],a
xor a,a ;ret 0
ret
gbt_ch1234_jump_position:
ld [gbt_current_step],a
ld hl,gbt_current_pattern
inc [hl]
; Check to see if jump puts us past end of song
ld a,[hl]
call gbt_get_pattern_ptr_banked
ld a,1
ld [gbt_update_pattern_pointers],a
xor a,a ;ret 0
ret
gbt_ch1234_speed:
ld [gbt_speed],a
xor a,a
ld [gbt_ticks_elapsed],a
ret ;ret 0
;-------------------------------------------------------------------------------
gbt_update_bank1::
ld de,gbt_temp_play_data
; each function will return in de the pointer to next byte
call gbt_channel_1_handle
call gbt_channel_2_handle
call gbt_channel_3_handle
call gbt_channel_4_handle
; end of channel handling
ld hl,gbt_pan
ld a,[hl+]
or a,[hl]
inc hl
or a,[hl]
inc hl
or a,[hl]
ld [rNR51],a ; handle panning...
ret
;-------------------------------------------------------------------------------
gbt_update_effects_bank1::
call channel1_update_effects
and a,a
call nz,channel1_refresh_registers
call channel2_update_effects
and a,a
call nz,channel2_refresh_registers
call channel3_update_effects
and a,a
call nz,channel3_refresh_registers
call channel4_update_effects
and a,a
call nz,channel4_refresh_registers
ret
;###############################################################################