Putting famitone SFX in another bank

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
vnsbr
Posts: 22
Joined: Sun Feb 17, 2019 5:18 pm

Putting famitone SFX in another bank

Post by vnsbr » Sat Sep 12, 2020 3:18 am

Hello all,
I have been using famitone 2 and UNROM template as na_th_an posted somewhere in this forum.

it already has bank switching for music, but i can't make it work for banked SFX as well.

here are my changes:

putting data on BANK 6

Code: Select all

;not here anymore
;.segment "RODATA"
;	.if(FT_SFX_ENABLE)
;sounds_data:
;	.include "sounds.s"
;	.endif
.segment "ROM6"
.export _sounds_data
_sounds_data:
	.include "sounds.s"
bankswitching on FamitoneUpdate:

Code: Select all

	
	.if(FT_SFX_ENABLE)
	;process all sound effect streams
	lda #6
	jsr bankswitch_no_save
	.if FT_SFX_STREAMS>0
	ldx #FT_SFX_CH0
	jsr _FT2SfxUpdate
	.endif
	.if FT_SFX_STREAMS>1
	ldx #FT_SFX_CH1
	jsr _FT2SfxUpdate
	.endif
	.if FT_SFX_STREAMS>2
	ldx #FT_SFX_CH2
	jsr _FT2SfxUpdate
	.endif
	.if FT_SFX_STREAMS>3
	ldx #FT_SFX_CH3
	jsr _FT2SfxUpdate
	.endif
	lda <MUSIC_BANK
	jsr bankswitch_no_save

	;send data from the output buffer to the APU
	(...)
also analogue to his code i did the init SFX function in ASM:

Code: Select all

;void __fastcall__ famitonesfx_init (unsigned char *song_data);
_famitonesfx_init:
	sta <TEMP
	stx <TEMP+1
	lda #6
	jsr bankswitch_no_save

	ldx <TEMP
	ldy <TEMP+1
	jsr FamiToneSfxInit 

	lda <CURRENT_BANK
	jsr bankswitch_no_save

	rts 
Finaly, initializing sound data in C

Code: Select all

extern const unsigned char sounds_data[]; // A pointer to the sound data @ ROM6.
(...)
// i did this analogue to famitone_init from nathan code
famitonesfx_init(sounds_data);
and here is the relevant code for bankswitching:

Code: Select all

; void __fastcall__ bankswitch(unsigned char bank);
_bankswitch:
	sta CURRENT_BANK
bankswitch_no_save:
	tax
	lda banktable, x
	sta banktable, x
	rts

banktable:				; Write to this table to switch banks.
	.byte $00, $01, $02, $03, $04, $05, $06

	.include "famitone2.s"

but my sfx are mute :( any ideas what might been missing/wrong?
Last edited by vnsbr on Sat Sep 12, 2020 11:03 am, edited 1 time in total.

User avatar
dougeff
Posts: 2735
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Putting famitone SFX in another bank

Post by dougeff » Sat Sep 12, 2020 10:03 am

ldx <TEMP
ldy <TEMP+1
jsr FamiToneSfxInit

This is wrong, it should be...

LDX #<_sounds_data
LDY #>_sounds_data
jsr FamiToneSfxInit

Also, when the code that starts a sfx needs to be called, you need to make sure to switch banks.
nesdoug.com -- blog/tutorial on programming for the NES

vnsbr
Posts: 22
Joined: Sun Feb 17, 2019 5:18 pm

Re: Putting famitone SFX in another bank

Post by vnsbr » Sat Sep 12, 2020 11:08 am

dougeff wrote:
Sat Sep 12, 2020 10:03 am
Also, when the code that starts a sfx needs to be called, you need to make sure to switch banks.
yes sorry, forgot to include that too. this is what i modified from famitonesfxplay

Code: Select all

;------------------------------------------------------------------------------
; play sound effect
; in: A is a number of the sound effect
;     X is offset of sound effect channel, should be FT_SFX_CH0..FT_SFX_CH3
;------------------------------------------------------------------------------
	
FamiToneSfxPlay:
	tay
	lda #6
	jsr bankswitch_no_save
	tya
	asl a					;get offset in the effects list
	tay

	jsr _FT2SfxClearChannel	;stops the effect if it plays

	lda FT_SFX_ADR_L
	sta <FT_TEMP_PTR_L
	lda FT_SFX_ADR_H
	sta <FT_TEMP_PTR_H

	lda (FT_TEMP_PTR),y		;read effect pointer from the table
	sta FT_SFX_PTR_L,x		;store it
	iny
	lda (FT_TEMP_PTR),y
	sta FT_SFX_PTR_H,x		;this enables the effect
	lda <CURRENT_BANK
	jsr bankswitch_no_save

	rts
dougeff wrote:
Sat Sep 12, 2020 10:03 am
ldx <TEMP
ldy <TEMP+1
jsr FamiToneSfxInit

This is wrong, it should be...

LDX #<_sounds_data
LDY #>_sounds_data
jsr FamiToneSfxInit
aren't they pointing to the same thing? i believe TEMP is point to sounds_data that is passed as parameter from C.

does not work though

----

one thing that ocurred me now, is that famitoneupdate is already banked in (bank 1) where music is stored, before i switch to bank 6 where sfx is stored, I wanted to have SFX and music stored separatedly (in fact i dont have any space left on music bank right now =/), but maybe it cant work that way?

User avatar
dougeff
Posts: 2735
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Putting famitone SFX in another bank

Post by dougeff » Sun Sep 13, 2020 7:07 am

The music update can be split into 2 parts, the song and the sfx. The song code only writes to a buffer, then it checks each sfx channel, then it copies the buffer to the APU registers. You can put the song part in one bank and the sfx part on another bank, and call them sequentially.

By the way, if you're not sure where everything is compiling, on the command line instructions that run ca65 (possibly in a batch file or make file), put -g to instruct it to make a list of labels, Then on the linker line add...

-Ln labels.txt

To create a listing of label addresses. And also

-m map.txt

To create a map of all segments.

You can use this information for debugging. It's more difficult, working from C. Most of the labels are auto generated by the compiler. But you can look at the .s file generated by cc65, to find the label names. Sometimes I put in a dummy variable, and only use that variable right before the code I'm trying to test. Then I can quickly search my files for that variable (or set a breakpoint for writes to that variable).

Edit, after looking at both labels.txt and map.txt, neither one tells you which segment each line is in. Hmm.
Last edited by dougeff on Sun Sep 13, 2020 7:24 am, edited 1 time in total.
nesdoug.com -- blog/tutorial on programming for the NES

User avatar
dougeff
Posts: 2735
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Putting famitone SFX in another bank

Post by dougeff » Sun Sep 13, 2020 7:22 am

Looking at famitone2.s

Everything between FamitoneUpdate: and

.if (FT_SFX_ENABLE)

;process all sound effects

can go in the bank with the music code. Slap a RTS there.
You need to include _FTChannelUpdate and _FT2SetInstrument and the note table. And the DPCM functions.. (have the word "sample" in their labels).


Then the .if (FT_SFX_ENABLE) down to the RTS goes in the sfx bank. Include _FT2SfxUpdate.
nesdoug.com -- blog/tutorial on programming for the NES

vnsbr
Posts: 22
Joined: Sun Feb 17, 2019 5:18 pm

Re: Putting famitone SFX in another bank

Post by vnsbr » Wed Sep 16, 2020 3:38 am

dougeff wrote:
Sun Sep 13, 2020 7:22 am
Looking at famitone2.s

Everything between FamitoneUpdate: and

.if (FT_SFX_ENABLE)

;process all sound effects

can go in the bank with the music code. Slap a RTS there.
You need to include _FTChannelUpdate and _FT2SetInstrument and the note table. And the DPCM functions.. (have the word "sample" in their labels).


Then the .if (FT_SFX_ENABLE) down to the RTS goes in the sfx bank. Include _FT2SfxUpdate.
thanks! looking back i worded it wrong! only the music and sfx data are banked, the famitone code is not, i was able to fix the code now it works :D

the problem is that i was banking to music bank after playing sounds, when in fact there is no need if the code is in the main bank :facepalm:

thanks @dougeff

i put the code here to help anyone in the future
warning: famitone 5.1 by dougeff, not regular famitone :D
https://github.com/valdirSalgueiro/famitone2sfxbanking

Post Reply