Guerilla War NSF

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Guerilla War NSF
by on (#48991)
Seems the two Guerilla War NSFs floating around (Kevin Horton's version and the one on zophar.net) have some issues with Track 4 (stage 3 in the game).

Nestopia, when playing the actual game/ROM, sounds correct. But when playing the NSF, the square channels in Track 4 sound incorrect (durations are too short sometimes). Notso Fatso sounds similar.

Given that I haven't worked with the NSF format before, I'm grasping at straws here, but my guess is that there's some value in RAM which isn't being set correctly in the NSF, which the ripper(s) didn't notice because their ears aren't so great or because they just didn't listen close enough. :-) Here's the audio as played by Nestopia:

Guerilla War (in game): http://www.malkavian.com/~jdc/gw_ingame.wav (1.8MB)
Guerilla War (NSF): http://www.malkavian.com/~jdc/gw_nsf.wav (1.8MB)

I'm looking to fix it, but I'd like some pointers/advice from folks on how to go about doing this.

by on (#48992)
It may have to do with the $4017 register, "Frame Sequencer". That'd be my guess.
http://nesdev.com/apu_ref.txt

Could try changing what is written to $4017 (if anything) in the init routine.

by on (#49005)
Wow, this is proving to be a real bitch. I'm still digging for that routine.

by on (#49168)
koitsu wrote:
Wow, this is proving to be a real bitch. I'm still digging for that routine.


Try surfing the reset routine, often you'll find addresses being initialized for the sound driver.

When I rip NSFs, I run a test on the NSF to detect read without writing. Track those down as well.

by on (#49203)
Gil-Galad wrote:
Try surfing the reset routine, often you'll find addresses being initialized for the sound driver.


What reset? The NSF specification doesn't mention supporting the 6502 reset vector, but the docs are... well... I'm not going to go there.

Maybe you mean the NSF INIT address? If so: yeah, I've disassembled quite a lot (by hand) so far, starting with INIT -- that's what I meant by "this is proving to be a real bitch". I haven't found any NES registers being adjusted at this point, this is all purely RAM setup ($01xx range).

I can put up the 14KB of hand-disassembly I've done so far but it just continues on and on, and I've yet to find a single bit of code that touches a *any* NES register. The decoded portion of the NSF header is below. Sorry for the formatting mess, but the forum doesn't appear to translate literal tabs to 8 spaces.

Code:
Guerilla War.NSF (from Zophar's NSF Archive)

0x0006 = $30      ; Total songs: $30
0x0007 = $01      ; Start with song #1
0x0008 = $0080      ; LOAD address = $8000  (file offset 0x0080)
0x000a = $00c0      ; INIT address = $C000  (file offset 0x4080)
0x000c = $2480      ; PLAY address = $8024  (file offset 0x00a4)
0x0070 = $00      ; no bankswitching used
......         ; no bankswitching used
0x0077 = $00      ; no bankswitching used

0x0080 = Bank 0, located at $8000
0x1080 = Bank 1, located at $9000
0x2080 = Bank 2, located at $A000
0x3080 = Bank 3, located at $B000
0x4080 = Bank 4, located at $C000

; !!! INIT address
; ORG $C000   (file offset 0x4080)
;
; 0x4080 = AA BD 0A C0 8D 00 01 4C 2B 80 0B 0F 19 08 17 03
; 0x4090 = 05 06 1B 13 10 1C 0D 15 04 01 20 21 22 23 24 25
; 0x40A0 = 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35
; 0x40B0 = 36 37 38 39 3A 3B 3C 3D 3E 3F
;
; reg A = song #
; reg X = NTSC(0) or PAL(1)
;
0x4080   AA      tax      ; Song number --> X index
0x4081   BD0AC0      lda $c00a,x   ; ...and load from table at $c00a (file offset 0x408a)
0x4084   8D0001      sta $0100
0x4087   4C2B80      jmp L802B   ; jump to label L802B



Well I moved the original INIT address from $C000 to $BFF0 and changed the code from the above to:

Code:
0x4070   AA      tax      ; Song number --> X index
0x4071   BD0AC0      lda $c00a,x   ; ...and load from table at $c00a (file offset 0x408a)
0x4074   8D0001      sta $0100
0x4077   A980      lda #$80
0x4079   8D1740      sta $4017
0x407c   4C2B80      jmp L802B   ; jump to label L802B


Sadly no difference. It also seems that FXEUX 2.1.0's debugger is "weird" with NSFs; I added a breakpoint for r/w/x on $4017 and reloaded the NSF, but it never got triggered, indicating the emulator doesn't appear to utilise breakpoints for NSFs (INIT, PLAY, or LOAD). I also tried a BP for $4000, same thing. Awesome.

by on (#49215)
That's some nice work there with the disassembly. I also suggest writing 0Fh to $4015 in your initialization code, just in case.

Worst case scenario, I highly suggest to re-rip the NSF from the game. It's easy to isolate the music driver data from the ROM. You can dump in FCEU using the debugger in that version. Specify $8000 - $FFFF in the memory viewer and you're all set (after breaking on $4000 - $4008). Disassemble! You already know the init and play addresses. There is also the possibility that the rip you're working with has been over-optimized.

UGETAB has made a NSF version of FCEUXDSP, where you can debug, use the hex editor and other features for NSFs. I don't really mess with FCEUX for NSF ripping. However, I have requested that they merge UGETAB's version with FCEUX.

by on (#49228)
Thanks for the tip about the more-NSF-friendly version of FCEUXD SP! This has shed some light on a couple of things.

The most interesting of the bunch is that UGETAB's version of FCEUXD SP appears to play track 4 of the Guerilla War NSF correctly. This would indicate the NSF itself is fine, but Notso Fatso and NEStopia have some kind of quirk/bug in their audio engine. Then I saw this on UGETAB's page:

Quote:
NotSoFatso-UF's Version + Wave_Square.h update Simply UF's latest listed NotSoFatso source(09262007), with the Wave_Square.h file updated with some code that functions the way FCEUXDSP's sound code does. Makes 4017 inits work better.


I'll need to bust out Notso Fatso's code and get a diff, because the .rar on UGETAB's site only includes the modified .h, not the original, nor any comments in the code indicating what was changed...

EDIT: It seems Drag's Notso Fatso version (labelled 0.86) also fixes this problem. So yeah, it's a sound engine thing. :-) Seems Nestopia will need similar fixing... http://nesdev.com/bbs/viewtopic.php?t=4653

by on (#49259)
That's great that you figured out the real problem. I have up to date NSF players and emulators to test compatibility when I rip NSFs, even players that don't properly support $4017.

Let us know if you try to fix Nestopia's $4017 problem.

by on (#49261)
Gil-Galad wrote:
I have up to date NSF players and emulators to test compatibility when I rip NSFs, even players that don't properly support $4017.


- Of course. ^_^;;

by on (#49266)
Fx3 wrote:
Gil-Galad wrote:
I have up to date NSF players and emulators to test compatibility when I rip NSFs, even players that don't properly support $4017.


- Of course. ^_^;;


I think that the circle visualization is pretty cool. Also that you can use a savestate with NSFs, that's interesting.

How about adding support for the rest of the sound expansion channels if you can. A register viewer would be great, that doesn' t show FFh. Also more debugging tools.