Page 1 of 1

How execute a program loaded into the APU?

Posted: Sun Jan 27, 2019 2:35 pm
by StarCaptain524
So I'm writing a program in python to convert NSF files into a more readable format, with the information about each sound channel at each audio frame displayed (similar to FamiTracker, but as a csv) but I ran into some issues with executing the program once it has been loaded into ram.

I've loaded the data from the file into my emulator correctly (as checked by NSFplay), and I setup all the registers according to the nsf documentation, but now I don't know how to execute the program properly. When I try, either nothing changes or it doesn't change correctly (depends on the nsf file).

I'm using py65emu, and I know it works because of this article.

What am I doing wrong? Code and test nsf linked.
nsf_reader.txt
The python script (save as .py)
(6.04 KiB) Downloaded 348 times
test1.nsf
My test nsf. Just plays one note in the first pulse channel endlessly.
(5.77 KiB) Downloaded 344 times

Re: How execute a program loaded into the APU?

Posted: Sun Jan 27, 2019 3:17 pm
by rainwarrior
If it helps as an example, here's an NSF analyzer I wrote using py65emu:
https://github.com/bbbradsmith/zensf/bl ... fspider.py

Alternatively, you might try the old NSF Importer fork of Famitracker that breaks NSFs down into tracker data. You could then use the Famitracker text export to get a text file version of it. (Unfortunately the NSF Import fork was before the text export so there'd be an extra step to save and run the text exporter from a later version.)
http://rainwarrior.ca/projects/nes/nsfimport.html

Re: How execute a program loaded into the APU?

Posted: Mon Jan 28, 2019 8:13 pm
by StarCaptain524
rainwarrior wrote:If it helps as an example, here's an NSF analyzer I wrote using py65emu:
https://github.com/bbbradsmith/zensf/bl ... fspider.py

Alternatively, you might try the old NSF Importer fork of Famitracker that breaks NSFs down into tracker data. You could then use the Famitracker text export to get a text file version of it. (Unfortunately the NSF Import fork was before the text export so there'd be an extra step to save and run the text exporter from a later version.)
http://rainwarrior.ca/projects/nes/nsfimport.html
Thanks! You're code and work has been a huge help!
As for zensf, I had a about the code, why can't you read at addresses $4000 - $4013 in the ram? Aren't those the addresses for the sound channels?

Re: How execute a program loaded into the APU?

Posted: Mon Jan 28, 2019 8:19 pm
by tepples
Most 2A03 APU ports are write-only. Only $4015 (length counter status) is readable.

Re: How execute a program loaded into the APU?

Posted: Tue Jan 29, 2019 1:32 am
by pubby
$0000-$07FF is RAM. The APU registers don't map to RAM.

Re: How execute a program loaded into the APU?

Posted: Tue Jan 29, 2019 9:08 am
by tokumaru
StarCaptain524 wrote:why can't you read at addresses $4000 - $4013 in the ram? Aren't those the addresses for the sound channels?
These addresses are not RAM, they're memory-mapped registers. The way these work is that the CPU intercepts accesses to certain special addresses and redirects them to the appropriate devices, and, in this case, the device is the APU. Read and write operations are treated separately for memory-mapped registers (e.g. the same register could even access completely different devices depending on whether you're writing or reading to/from that register), so even when reads are supported, that doesn't mean you'll get back what you wrote, you'll get whatever the device that's responding sends back.

Re: How execute a program loaded into the APU?

Posted: Sat Feb 09, 2019 5:40 am
by Zepper
StarCaptain524 wrote:why can't you read at addresses $4000 - $4013 in the ram? Aren't those the addresses for the sound channels?
Why do you want a read from $4000-$4013 after all???

Re: How execute a program loaded into the APU?

Posted: Sat Feb 09, 2019 6:32 am
by tepples
If APU registers were readable (which they aren't), then reading $4003 or $4007 would allow a program to not trigger phase reset unnecessarily during vibrato or portamento without having to use a separate variable to keep track of the last written value.