Famitone2 channel question

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Famitone2 channel question
by on (#226613)
EDIT: RESOLVED
As noted by glutock (Thank You!), LDX FT_SFX_CH1 should have been LDX #FT_SFX_CH1

If weird crap happens in memory while playing sound effects, check for this : ) and thanks everyone for your help.


------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I completed my second game and have been working on final touches. Up until now I've been playing music and using one sound effect channel. I decided to use two sound effect channels since one sound in particular happens often and I didn't want it to get cut off.

If I use FT_SFX_CH0, everything is fine (been using this one only up until now)

If I use FT_SFX_CH1, everything gets glitched up, including vram? It's odd.

If I use FT_SFX_CH2, everything is fine, I can actually use channel 2 and 0 together without issue. Why would channel 1 sends things out of whack? This might be a loaded question but I'm hoping the symptom is obvious; I re-read the readme that came with the library and didn't see anything special about channel 1.

If it helps, here is the layout of how I'm using memory (NROM, no bankswitching):

Code:
; zero page memory 0000 - 00FF
; stack memory 0100 - 01FF
; memory range 0100 - 010F = enemy slots (tail end of stack memory, don't let stack build up)
; memory range 0200 - 0300 = sprite ram
; memory range 0300 - 06CO = virtual gameboard nametable
; memory range 06C0 - 06FF = ppu buffer
; memory range 0700 - 0800 = famitone2


And here is my famitone2 init macros

Code:
FT_BASE_ADR      = $0700   ; page in the RAM used for FT2 variables, should be $xx00
FT_TEMP         = $F5   ; 3 bytes in zeropage used by the library as a scratchpad
FT_DPCM_OFF      = $c000   ; $c000..$ffc0, 64-byte steps
FT_SFX_STREAMS   = 3      ; number of sound effects played at once, 1..4
;FT_DPCM_ENABLE            ;undefine to exclude all DMC code
FT_SFX_ENABLE            ;undefine to exclude all sound effects code
FT_THREAD               ;undefine if you are calling sound effects from the same thread as the sound update call
;FT_PAL_SUPPORT            ;undefine to exclude PAL support
FT_NTSC_SUPPORT            ;undefine to exclude NTSC support


My famitone2 updates are in NMI and my play effects calls are in main thread.
Re: Famitone2 channel question
by on (#226617)
Try

FT_SFX_ENABLE = 1

how are you calling sfx? are you using neslib.s?
Re: Famitone2 channel question
by on (#226619)
Added, current init block:

Code:
;famitone2 settings
FT_BASE_ADR      = $0700   ; page in the RAM used for FT2 variables, should be $xx00
FT_TEMP         = $F5   ; 3 bytes in zeropage used by the library as a scratchpad
FT_DPCM_OFF      = $c000   ; $c000..$ffc0, 64-byte steps
FT_SFX_STREAMS   = 2      ; number of sound effects played at once, 1..4
;FT_DPCM_ENABLE            ;undefine to exclude all DMC code
;FT_SFX_ENABLE            ;undefine to exclude all sound effects code
FT_SFX_ENABLE = 1
FT_THREAD               ;undefine if you are calling sound effects from the same thread as the sound update call
;FT_PAL_SUPPORT            ;undefine to exclude PAL support
FT_NTSC_SUPPORT            ;undefine to exclude NTSC support


When I play sfx I'm doing:

Code:
LDA #$01
LDX FT_SFX_CH1
JSR FamiToneSfxPlay


This is in my main thread. A = index to clip (created in famitracker, ending with c00).

Seems like FT_SFX_ENABLE = 1 still causes the issue, super weird how CH2 works.

I attached a screenshot. See bottom right corner, I highlighted it in green. Tiles should be all zeros but the nametable gets messed up there after using CH1 one time. Famitone is using last page of ram all to itself ($0700) with tail end of zero page for its scratchpad. I'm using less than half of zero page for the entire game. I wonder if somehow it's touching my ppu buffer... which is a small area of RAM. $06C0 - $06FF
Re: Famitone2 channel question
by on (#226621)
Code:
LDA #$01
LDX FT_SFX_CH1
JSR FamiToneSfxPlay


That looks right.

Quote:
super weird


I agree.

I would try to output a listing of all labels, and see if anything else is in the 700-7ff range besides music variables. My gut says something is getting overwritten by the sfx. Something that doesn't belong there.
Re: Famitone2 channel question
by on (#226623)
I didn't realize at first but if your memory for famitone is at $0700, this is usually where the C stack is, at the end of the memory.

This could explain your issue. Set the address lower like 200~300 and see how it goes.
Re: Famitone2 channel question
by on (#226624)
I guess that could be. What assembler / compiler are you using?
Re: Famitone2 channel question
by on (#226626)
I'm using NESASM v3.1

So I had to gut my code a bit to test. I cleared out using 0300 and pointed Famitone to that. Although it doesn't mess with the nametable, it won't play sound on CH1 which was a previous symptom when using 0700 as well. And before it would only mess with a couple tiles it seems.

If I'm using assembly / nesasm do I still need to worry about using 0700? I could live with using a single sound channel or using ch0 and ch2 for this project but I don't get how vram could have been impacted. I verified nothing else in my code was using anything in the last page of RAM.
Re: Famitone2 channel question
by on (#226627)
NESASM, then yes, you should be able to safely put things at 700-7ff.

C stack is only for cc65 C compiler, which usually people put the C stack there.

.

Here's another thought.

Writing to the PPU outside of V blank.

If you have music updates in the NMI code... is it after PPU updates or before?
Re: Famitone2 channel question
by on (#226628)
@dougeff was faster than me to answer :lol: So I won't mention the C stack again.

It becomes harder to guess without testing with your code since the cause could be anything:

- your code do something that write in the same memory as famitone's memory
- your famitone library is broken for some reason
- there is a bug with famitone with nesasm that was not known up to now (unlikely but possible)
- your sfx data is broken
- some initialization is missing
- something wrongs happens in NMI (like dougeff said)

Like mentioned before, the best thing to do it to isolate and conquer: extract the code that play music/sfx in it's own test sample. Play those sfx in that sample. If sfx fail then you know it's not your game code but either the library has issue, init issue or the music data has issue.

If you have a chance, try to make that sample without your game code and test it.
Re: Famitone2 channel question
by on (#226629)
Thanks, this was indeed a loaded question, so many possible scenarios.

@dougeff, JSR FamiToneUpdate is after ppu updates, but I noticed something interesting. If I comment this out the game still glitches when I write to CH1, so whatever happens is happening right at that moment and not during updates in famitone.

I have gutted a lot of code so far in a test build to try and isolate the issue, it's pretty much unplayable right now in this test build lol but issue still replicates. If interested I've attached two roms, labeled ch0 and ch1. If you press start/pause when the game is running (after credit + title screen), then look at the lower right corner and also the enemy, you will see the strange behavior with the ch1 rom. Also note no sound will play when pressing start using the ch1 rom, so it glitches and gives no sound. I cut out a lot of code so if anything else weird is going on or making no sense it is unrelated lol.

I will keep cutting away and testing until it is bare bones.
Re: Famitone2 channel question
by on (#226655)
I was not able to test your sfx issue (I cannot hear any sfx on button press or don't know when and how they are executed) but one thing I saw while testing is that if I press the start button, there is a lot processing that occurs in the nmi.

Is it possible that you are processing other thing in the nmi that shouldn't be there? that could be one of your issue.
Re: Famitone2 channel question
by on (#226669)
So something really weird is going on, as I was making my source thinner and thinner I could not locate a consistent solution to get CH1 working, so I wrote a quick program to just test the channels and now CH0 does not work but CH1 does lol I wonder if this is a bug in NESASM? I took sound effects from Famitone's examples to rule out an issue with my file. Also note the background music is commented out in my example below but it works just fine if you uncomment it. And if you change FT_SFX_CH0 to FT_SFX_CH1 the sound effect works. The code below just waits for start to be pressed (not held down) and plays a sound.


And @Banshaku, to answer your question, it's possible in cutting stuff in my original source to get the channel working I caused some weirdness, however during NMI I only update the PPU when needed, decrement some timing variables, do my OAM transfer when needed, reset my scroll, and update famitone at the end. When I clock the cycles it stays under 2K under full load in my full game.

Code:
   .inesprg 1   ; 1x 16KB PRG code
   .ineschr 1   ; 1x  8KB CHR data
   .inesmap 0   ; mapper 0 = NROM, no bank swapping
   .inesmir 1   ; background mirroring

; ---------------------------------------   
   .rsset $0000
controller_state .rs 1
controller_last_state .rs 1
;famitone2 settings
FT_BASE_ADR      = $0300   ; page in the RAM used for FT2 variables, should be $xx00
FT_TEMP         = $FC   ; 3 bytes in zeropage used by the library as a scratchpad
FT_DPCM_OFF      = $c000   ; $c000..$ffc0, 64-byte steps
FT_SFX_STREAMS   = 1      ; number of sound effects played at once, 1..4
;FT_DPCM_ENABLE   = 1      ;undefine to exclude all DMC code
FT_SFX_ENABLE   = 1      ;undefine to exclude all sound effects code
FT_THREAD            ;undefine if you are calling sound effects from the same thread as the sound update call
;FT_PAL_SUPPORT         ;undefine to exclude PAL support
FT_NTSC_SUPPORT         ;undefine to exclude NTSC support

; ---------------------------------------   

   .bank 0
   .org $C000

RESET:
   SEI          ; disable IRQs
   CLD          ; disable decimal mode
   LDX #$40
   STX $4017    ; disable APU frame IRQ
   LDX #$FF
   TXS          ; Set up stack
   INX          ; now X = 0
   STX $2000    ; disable NMI
   STX $2001    ; disable rendering
   STX $4010    ; disable DMC IRQs

Vblank_wait_1:       ; First wait for vblank to make sure PPU is ready
   BIT $2002
   BPL Vblank_wait_1
   
Clrmem:
   LDA #$00
   STA $0000, x
   STA $0100, x
   STA $0300, x
   STA $0400, x
   STA $0500, x
   STA $0600, x
   STA $0700, x
   LDA #$FE
   STA $0200, x
   INX
   BNE Clrmem

Vblank_wait_2:      ; Second wait for vblank, PPU is ready after this
   BIT $2002
   BPL Vblank_wait_2      

   LDA #$00
   STA controller_state
   STA controller_last_state
   
   LDX #LOW(bgmusic_data)
   LDY #HIGH(bgmusic_data)
   LDA #$80 ; this sets Famitone to use NTSC mode.
   JSR FamiToneInit

   LDX #LOW(sounds)
   LDY #HIGH(sounds)
   JSR FamiToneSfxInit

   LDA #%10010000   
   STA $2000   

; ---------------------------------------   

Main:
   JSR Read_controller
   LDA controller_last_state   ; prevent buttons from behind held
   AND #%00010000
   BNE skip_sfx_play
   LDA controller_state      ; check for fresh press
   AND #%00010000
   BEQ skip_sfx_play
   ; play sound
   
   ; this will work so I know logic is hitting this
   ;LDA #$00
   ;JSR FamiToneMusicPlay
   
   ; this does not work
   LDA #$00
   LDX FT_SFX_CH0
   JSR FamiToneSfxPlay
skip_sfx_play:   
   JMP Main

; ---------------------------------------   
   
NMI:
   PHA
   TXA
   PHA
   TYA
   PHA
   
   LDA #%10010000
   STA $2000
   JSR FamiToneUpdate
   
   PLA
   TAY
   PLA
   TAX
   PLA
   RTI

; ---------------------------------------   
   
Read_controller:
   ; store previous state
   LDA controller_state
   STA controller_last_state
   
   ; prepare to read controller
   LDA #$01
   STA $4016
   LDA #$00
   STA $4016
   
   ; read controller
   LDX #$00
controller_loop:
   LDA $4016
   AND #%00000001
   LSR A
   ROL controller_state
   INX
   CPX #$08
   BNE controller_loop   
   RTS

; ---------------------------------------   
   
   .bank 1
   .org $E000   

   .include "famitone2.asm"; sound engine
   .include "bgmusic.asm"   ; famitracker bg music
   .include "sfx.asm"   ; famitracker sound effects

; ---------------------------------------   

   .org $FFFA
   .dw NMI
   .dw RESET
   .dw 0   
   
   .bank 2
   .org $0000
   .incbin "sb.chr"   
Re: Famitone2 channel question
by on (#226674)
Code:
ldx #FT_SFX_CH0


instead of

Code:
ldx FT_SFX_CH0


should solve the problem.
Re: Famitone2 channel question
by on (#226677)
@glutock oh... my... sdljfsdlafjdlfjsdf this was the problem all along -_- of course, need the value of that constant... assumed it was so much more complex. this solves the issue in my actual game code as well.

Thanks everyone, this would explain the random memory issues and the inconsistency trying to troubleshoot. I'm going to add this note to the first part of this thread.
Re: Famitone2 channel question
by on (#226686)
Like mentioned, divide and conquer ;)

Without an example of the problematic code it was hard to guess the issue since it could have been anything. When you see your code all day those errors slip since the code looks perfectly fine ^^;;