Preview of my modded VegaPlay

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Preview of my modded VegaPlay
by on (#129653)
So here is a project that I've been working on.
It's a SNROM version of VegaPlay. With a 256KB flash you can load 7 non-banking NSFs <32K (you lose the vector table and trampoline bytes from each 32K 'slot'. One 32K 'slot' is used for reset code and CHR data that's banked out after reset.).
The runtime is loaded into WRAM during reset, leaving the PRG space for NSFs. The testing I've done so far: works with FamiTracker NSFs but can have strange behavior with other NSF Players. I use Nestopia so can't speak for other EMUs.
I've tried to simplify the loading and compiling process, you don't need to strip the header from the NSFs and there is a User Configure file to do all the editing in, so the main ASM file can be left alone.
Just drop all your NSFs into the build folder, edit User Configure with the NSF titles and load addresses and run the compile bat. It will spit out a .NES and/or a .PRG ready to flash.
With a compiler switch you can use the normal playback timing based on the NMI or use Sync pulses on controller 2 (this is based on FamiSlayer v6.66 by Heavyw8bit). I'm working on a cheap (16F628 based) Midi Clock to NES Sync24 converter. Testing a proto board, so both the HW and the NES rom could change as things progress.
These preview ROMs are NSFs from the FamiMiniCompo10, the User Configure.asm has the title info. NSF 1, 3 and 4 have strange behavior, plays for a short time then triggers a bankswitch. Still testing :)
The Pad1 controls:
Up/Down - song # (all these are single song NSFs so trying to run a song other than the first will crash it)
Left/Right - cycle thru the 7 NSFs
Start Button - Start/Stop playback

UPDATE 7/20/2014:
Added a preview rom with a fixed Read routines. No more strange behavior, at least from the NES :)

https://www.dropbox.com/sh/g6osy6uozook ... -yjh_7WJUa
Yogi
Re: Preview of my modded VegaPlay
by on (#129827)
This sounds promising. The limitation of songs in Vegaplay has been a problem for me.
Re: Preview of my modded VegaPlay
by on (#129828)
Kreese wrote:
This sounds promising. The limitation of songs in Vegaplay has been a problem for me.

Same here, it was my motivation. I hope it will be useful, if people would like a 512K build it's not too much of an issue. The main thing I wanted was a 'no fuss' tool to put music on real hardware.
I haven't changed the UI very much so there is lots of room there for improvement, but OTH I'm considering turning the PPU off during playback for the best sync timing. I'm finishing up a HW Midi Clock to Sync24 interface and after some testing will know how much NMI calls affect the playback.
Yogi
Re: Preview of my modded VegaPlay
by on (#131115)
Just to let you know, Vegaplay code for pad reading has that problem with DPCM DMA transfers causing false positives to button presses.
For obvious reasons this is actually a SERIOUS problem considering that DPCM will be used extensively within the music playback code.

To fix it I had to change this:
Code:
ControllerTest:

        LDA NewButtons
   STA OldButtons

        LDX #$00
   LDA #$01      ; strobe joypad
   STA $4016
   LDA #$00
   STA $4016
ConLoop:
   LDA $4016      ; check the state of each button
   LSR
   ROR NewButtons
        INX
        CPX #$08
        bne ConLoop

into this:
Code:
ControllerTest:

        LDA NewButtons
   STA OldButtons

   LDA #$01      ; strobe joypad
   STA $4016
   LDA #$00
   STA $4016

   lda #$80
   sta NewButtons
ConLoop:
      LDA $4016
      AND #$03
      CMP #$01
      ROR NewButtons
      BCC ConLoop


to stop the input from glitching on the FAMICOM. Original code work perfectly fine on a NES (as you already know).

My project is play VRC6 songs on real hardware. I still need to tackle banking. Great job at banking here, considering that MMC1 banking is harder to deal with than VRC6!

I'll be using this for "classic" (2A03 only) NSFs! :D

P.S.:Thanks to blargg for the very smart bit of code which does the controller read using "ring buffer" idea with the carry bit.

The issue at hand:
viewtopic.php?t=4116
The solution used here is leeched from this:
viewtopic.php?t=4124
Re: Preview of my modded VegaPlay
by on (#131125)
l_oliveira wrote:
into this:

I don't see how this fixes anything. To avoid problems due to the DPCM glitch, you need to read the controller multiple times. Also the problem is not Famicom specific, it also occurs on CPU revisions used in NTSC NESes.
Re: Preview of my modded VegaPlay
by on (#131126)
thefox wrote:
I don't see how this fixes anything.

Indeed. I fail to see how switching from counting with the X register to waiting for a flag bit will help at all. If the controller gets clocked, the bits read after this will be wrong with either kind of loop.
Re: Preview of my modded VegaPlay
by on (#131128)
Perhaps the multiple reads settle faster if three of them can be done in one DMC fetch period (432 cycles). Not needing to bookkeep with X makes this more likely.
Re: Preview of my modded VegaPlay
by on (#131129)
l_oliveira wrote:
Just to let you know, Vegaplay code for pad reading has that problem with DPCM DMA transfers causing false positives to button presses.
For obvious reasons this is actually a SERIOUS problem considering that DPCM will be used extensively within the music playback code.

To fix it I had to change this:
Code:
ControllerTest:

        LDA NewButtons
   STA OldButtons

        LDX #$00
   LDA #$01      ; strobe joypad
   STA $4016
   LDA #$00
   STA $4016
ConLoop:
   LDA $4016      ; check the state of each button
   LSR
   ROR NewButtons
        INX
        CPX #$08
        bne ConLoop

into this:
Code:
ControllerTest:

        LDA NewButtons
   STA OldButtons

   LDA #$01      ; strobe joypad
   STA $4016
   LDA #$00
   STA $4016

   lda #$80
   sta NewButtons
ConLoop:
      LDA $4016
      AND #$03
      CMP #$01
      ROR NewButtons
      BCC ConLoop


to stop the input from glitching on the FAMICOM. Original code work perfectly fine on a NES (as you already know).


Thanks much for this 'heads up'. Does sound like the glitches I have observed; a random advance to the next NSF ( = to a 'Right' button press on controller 1). The odd thing, in my case, is I have the glitches testing on Nestopia (haven't tested on real HW yet) and the the same NSFs have the glitch when played via the NMI or via the 'SlayerSync' variable timing, which so far amounts to me banging controller 2's trigger button to advance the Frame plays at a very slow rate.
The Frame at which the glitch occurs ( through different for each of the troubled roms) seems to be fixed, regardless of the timing; so leads me to conclude the the trigger is associated with a particular Frame's actions. A false controller read due to a DPCM could account for the behavior but I doubt that Nestopia emulates the hardware this closely.

Quote:
My project is play VRC6 songs on real hardware. I still need to tackle banking. Great job at banking here, considering that MMC1 banking is harder to deal with than VRC6!

I'll be using this for "classic" (2A03 only) NSFs! :D

P.S.:Thanks to blargg for the very smart bit of code which does the controller read using "ring buffer" idea with the carry bit.

The issue at hand:
viewtopic.php?t=4116
The solution used here is leeched from this:
viewtopic.php?t=4124


The first iterations of this project was focused on VRC7 playback and banking, but I changed direction due to the access to La Grange Point vers SNROM based NES carts :) I do have a working rom with VRC7 banking (limited testing on Nestopia only).
yogi
Re: Preview of my modded VegaPlay
by on (#131130)
tokumaru wrote:
thefox wrote:
I don't see how this fixes anything.

Indeed. I fail to see how switching from counting with the X register to waiting for a flag bit will help at all. If the controller gets clocked, the bits read after this will be wrong with either kind of loop.


If you guys had a Famicom you could test it. I wish I had means to explain what is going on.
I simply don't have enough engineering background to even get close to understand this behavior.


Original code randomly jumps down on the track list during music playback.
Jumping stopped completely when I changed the code. And of course as you see there's no multiple reads involved.

Edit:

Videos of it running on a real Famicom: (controller code already changed)
https://www.youtube.com/watch?v=PxXf0KBTvnI
https://www.youtube.com/watch?v=Pgu7l_XpE1A
Re: Preview of my modded VegaPlay
by on (#131132)
yogi wrote:
A false controller read due to a DPCM could account for the behavior but I doubt that Nestopia emulates the hardware this closely.

Nestopia does emulate this glitch behavior.

l_oliveira: The fact that it works with the modified code is probably just luck. If you want a robust approach, read the controller multiple times. People often say to read multiple times until you get matching reads, but it may be theoretically possible that two consecutive reads get corrupted. In the thread you linked there's a routine by blargg that always reads the controller 4 times and should never fail (IIRC it can guarantee this because of the timing of the routine).

EDIT: I realized (thanks to rainwarrior at #nesdev) that it shouldn't be possible for two consecutive reads to get corrupted if the reading routine is sufficiently fast enough. From a quick look at blargg's code it seems like it reads 4 times only because there's a chance that the button state may change inbetween the reads. But I didn't look further into it.
Re: Preview of my modded VegaPlay
by on (#131133)
Another way to avoid this problem with DPCM may be to disallow any functions while music is playing except to push the "A" button to stop it, and then you can push the direction buttons and START button to play the next music. (I believe the "A" button can be read without DPCM interference.)
Re: Preview of my modded VegaPlay
by on (#131134)
Are you guys interested on testing this ? If so I can share the sources and the test roms I am working with.
Re: Preview of my modded VegaPlay
by on (#131135)
thefox wrote:
yogi wrote:
A false controller read due to a DPCM could account for the behavior but I doubt that Nestopia emulates the hardware this closely.

Nestopia does emulate this glitch behavior.

Wow, did not realize. This sheds a new light on things. Will have to investigate this more; had assumed it was due to different trackers frame play code.
yogi
Re: Preview of my modded VegaPlay
by on (#131142)
I tested the ROM which glitches on the Famicom in Nestopia 1.40 and there isn't a single sign of the glitch anywhere.
It's as if it was being run in a NES. Works fine on my NES.

I don't understand what is going on here, at all ... lol
Re: Preview of my modded VegaPlay
by on (#131145)
It might be a timing difference ultimately resulting from a difference in PPU/CPU alignment between the Famicom and NES. Anything that affects PPU/CPU alignment is likely to affect 6502/APU alignment within the CPU because normally, the program running on the 6502 waits for the PPU to warm up before doing anything. I know the PPU reset line isn't connected one way on the front-loading NES and the other way on the Famicom and top-loading NES.
Re: Preview of my modded VegaPlay
by on (#131146)
Did anyone ever make a test ROM for demonstrating the DPCM problem?

I've run stuff before that I thought should have been subject to the problem on both my Famicom and NES, but so far I've never seen a spurious right-press. Is this a thing that doesn't happen on some Famicom or NES revisions?
Re: Preview of my modded VegaPlay
by on (#131147)
rainwarrior wrote:
Did anyone ever make a test ROM for demonstrating the DPCM problem?

I made Eighty, which requires an NES Four Score and demonstrates the preferred DPCM glitch detection method for that device. But it won't run on the original RF Famicom because the NES Four Score works only with NES (front- and top-loading) and AV Famicom. Should I make another test ROM for DPCM glitching without the Four Score?
Re: Preview of my modded VegaPlay
by on (#131148)
tepples wrote:
But it won't run on the original RF Famicom because the NES Four Score works only with NES (front- and top-loading) and AV Famicom. Should I make another test ROM for DPCM glitching without the Four Score?
Yes, not only for that reason, but also in case you have NES without Four Score, or to test it with emulators not emulator Four Score.
Re: Preview of my modded VegaPlay
by on (#131174)
I can confirm that the glitches are due to DPCM samples. I added a folder to the Dropbox on the first post, which has a .NES rom and the User Configure.asm (Disclaimer: none of the songs used are my work, all have been DLed from FT Fourm). To test, I edited a FTM file and exported the song with two versions, one with DPCM (NSF #3 & #6) and the other (NSF #4 & #7) without. As soon as the Samples start playing it triggers a bankswitch (triggers a false 'Right' button).
SO... it's good that I know what the problem is; now just got to work out a better controller read routine.
Thanks for all the input, this helped alot!
Yogi

PS the first two NSF in the ROM are a test of FT's engine speed custom setting. One at 60Hz and the other at 30Hz playback.
Re: Preview of my modded VegaPlay
by on (#131178)
What I do is read the controllers twice, and if they don't match, use the previous frame's data. A tested example is in pads.s in this project template.
Re: Preview of my modded VegaPlay
by on (#131179)
tepples wrote:
What I do is read the controllers twice, and if they don't match, use the previous frame's data. A tested example is in pads.s in this project template.

Thanks tepples! I'll follow your example. Such a weird thing!
Yogi
Re: Preview of my modded VegaPlay
by on (#131285)
Man let's work together so we don't need to do all the work twice ! :D


VRCVI:
http://www.youtube.com/watch?v=PxXf0KBTvnI
http://www.youtube.com/watch?v=Pgu7l_XpE1A
The VRCVI hardware is just a Madara cart with holes and sockets for eproms/eeproms. It was modified to use INES 24 registers layout.

VRCVII:
http://www.youtube.com/watch?v=yZNW1MwnLRQ

Hardware picture:
Image

I need to work with the banking stuff still and this part is where we should join up to define a standard way of doing it.
Re: Preview of my modded VegaPlay
by on (#131287)
l_oliveira wrote:
Man let's work together so we don't need to do all the work twice ! :D


VRCVI:
http://www.youtube.com/watch?v=PxXf0KBTvnI
http://www.youtube.com/watch?v=Pgu7l_XpE1A
The VRCVI hardware is just a Madara cart with holes and sockets for eproms/eeproms. It was modified to use INES 24 registers layout.

VRCVII:
http://www.youtube.com/watch?v=yZNW1MwnLRQ

Hardware picture:
Image

I need to work with the banking stuff still and this part is where we should join up to define a standard way of doing it.


WOW, Cool vids! nice work!! Yes we can work out a early ALPHA release for testing :) would love to see/hear it on HW!!
My rom isn't ready for general release but does work on Nestopia. As built, it assumes 128KB Eprom, but can be expanded without too much work. Let me know your Eprom target size.
The kernel and NMI code resides in the last 8K bank, so max NSF size is 24K, starting at $8000.
The docs are 'lacking' and out of date, but the code is commented (excessively). If you have the time to read through the code, should be able to get the gist.
I'll clean it a bit and do a 'quick start' guide (not too different from VegaPlay) and zip it up. 'Own risk' and all that :)
Yogi
Re: Preview of my modded VegaPlay
by on (#131289)
My current idea is put the driver code *too* at the fixed page (we can have two different source codes as it won't be too much of a hassle) and we use the songs as .asm includes.

Would be something like this:

VRC6:
0x8000-0xBFFF -> Song data banking
0xC000-0xDFFF -> DPCM data banking
0xE000 -> Song driver and VegaPlay

VRC7:
0x8000-0x9FFF -> Song data banking
0xA000-0xBFFF -> Song data banking
0xC000-0xDFFF -> DPCM data banking
0xE000 -> Song driver and VegaPlay

My current target size is 256KB/256KB. VRC6 supports only 256KB for PRG but VRC7 supports 512KB.

VRC6 has CHR mapper capabilities comparable to that of MMC5 (MMC5 has a lot more features though) but the PRG banking is quite lame/meh.
VRC7 has decent PRG mapper capabilities but it gimps CHR (it can't do rom nametables, for example).

In our case, original VRC7 carts use CHR RAM but I am using CHR ROM for sake of saving space on PRG ROM. My cart has WRAM so it can be used for code storage. CHR ROM can be used as "offline" data storage which could in turn be copied to WRAM for execution.
Re: Preview of my modded VegaPlay
by on (#131303)
l_oliveira wrote:
My current idea is put the driver code *too* at the fixed page (we can have two different source codes as it won't be too much of a hassle) and we use the songs as .asm includes.


That is how I handled it. The CHR data, Reset and a part of the NMI code are in two 8K banks (we lose 16K for these). During the NMI the bulk of the controller read and logic code is banked back in. When we are ready to play the next frame, we jump to the NMI code in the fixed bank and the current NSF banks are restored and we JSR to the play address and then exits the NMI.
Banking of NSFs is done with 3 - 8K banks at a time, each of these 24K blocks contain an NSF. So with a 128K rom this allows 4 NSFs, 3 at 24K and the last at 31K max. This is all based on a 128K device, with a 256K you could have 7.
My Fixed bank code is less than 200 bytes at the top of mem, so the last NSF can overlap onto the lower part of this fixed bank.

With the MMC1 that I have been working on, all of the runtime code is in WRAM and during normal play, NSF banking is done with 32K blocks. During a reset, the MMC switches to 16K banking, that makes the Reset code visible in the top 16K bank.

Quote:
Would be something like this:

VRC6:
0x8000-0xBFFF -> Song data banking
0xC000-0xDFFF -> DPCM data banking
0xE000 -> Song driver and VegaPlay

VRC7:
0x8000-0x9FFF -> Song data banking
0xA000-0xBFFF -> Song data banking
0xC000-0xDFFF -> DPCM data banking
0xE000 -> Song driver and VegaPlay


Your approach does give you tight control over the placement of song data and would work well for album production. How difficult is the preparation process for the song data? Hand editing of the raw data? If it can be automated with a script that would help users.
I wanted to maintain the VegaPlay NSF structure; many users of VegaPlay are more interested is making music and less knowledgeable about NES kernels. It has it's downside, wasteful of the space and dependent on the Export routine's default memory usage, but for a musician it's far less complicated.

Quote:
My current target size is 256KB/256KB. VRC6 supports only 256KB for PRG but VRC7 supports 512KB.

VRC6 has CHR mapper capabilities comparable to that of MMC5 (MMC5 has a lot more features though) but the PRG banking is quite lame/meh.
VRC7 has decent PRG mapper capabilities but it gimps CHR (it can't do rom nametables, for example).

In our case, original VRC7 carts use CHR RAM but I am using CHR ROM for sake of saving space on PRG ROM. My cart has WRAM so it can be used for code storage. CHR ROM can be used as "offline" data storage which could in turn be copied to WRAM for execution.


I debated CHR ram vs rom, but giving up the space for the CHR seemed the best trade off. With VegaPlay the background is static so it is a bit of a waste with RAM, but I only have to worry about the PRG when flashing.
Yogi
EDIT: I have added a test VRC7 .PRG and .NES to the dropbox in the first post
Re: Preview of my modded VegaPlay
by on (#131305)
My hardware has a socket for CHR ROM but it has a CHR RAM (32Kb banked) piggy backed on the solder side of the board.

A pair of switches toggle A18 on/off (when off it puts the pin 31 at +5v which is ideal for 256 or 128Kb flash chips) and CHR ROM/CHR RAM mode.
The cart can run Lagrange Point as it if A18 is enabled and CHR is set to RAM mode.

Also the limit here is 512KB.

I'll need some time to study the code you sent me and decide what I'll do with my own code which is just a small patch on the original code. Atm most of the work I spent was spent on the hardware side of the thing.

Edit: Do you have means to assembly hardware stuff at your side ?
It might be possible to make some simple circuit that add a standard YM2413 to the NES and on that case you don't really need a VRC7 to play own compositions. ;)
Re: Preview of my modded VegaPlay
by on (#131308)
l_oliveira wrote:
My hardware has a socket for CHR ROM but it has a CHR RAM (32Kb banked) piggy backed on the solder side of the board.

A pair of switches toggle A18 on/off (when off it puts the pin 31 at +5v which is ideal for 256 or 128Kb flash chips) and CHR ROM/CHR RAM mode.
The cart can run Lagrange Point as it if A18 is enabled and CHR is set to RAM mode.

Also the limit here is 512KB.

Very good, nice dev cart. You are using a VRC 7, how did you come by it? I was thinking of getting a LGP famicom cart but didn't want to layout the cash for it and a Fami-to-NES adaptor ATM.
AS far as the ROM size goes, at the time I was working on the code just picked 128K out of the blue, the way the rom is layed out not much effort to increase the size.

Quote:
I'll need some time to study the code you sent me and decide what I'll do with my own code which is just a small patch on the original code. Atm most of the work I spent was spent on the hardware side of the thing.

Edit: Do you have means to assembly hardware stuff at your side ?
It might be possible to make some simple circuit that add a standard YM2413 to the NES and on that case you don't really need a VRC7 to play own compositions. ;)

Hum, funny you should ask, been working on a modified VRC7 hack with a YM2413. The idea is to implement the two VRC7 sound addresses and just the first banking register address at $8000. All banking would be in 24K blocks. It would be compatible with VRC7 NSFs and the VegaPlay code I have; just no 8K banking. I got it mostly prototyped but not tested yet. Kind of went on the back burner till I get the MMC project done.
Yogi
Re: Preview of my modded VegaPlay
by on (#131310)
yogi wrote:
I was thinking of getting a LGP famicom cart but didn't want to lay out the cash for it and a Fami-to-NES adaptor ATM.
If you're already up for rework, Tiny Toon Adventures 2 is a little bit cheaper on ebay. (Looks like ~$28 instead of ~$35)
Quote:
All banking would be in 24K blocks.
How would 24K blocks work? Specify an offset as a multiple of 8 KiB? Multiply by 3? 32 KiB where the top 8 KiB is concealed?
Re: Preview of my modded VegaPlay
by on (#131312)
I commented about the YM2413, because the small chip in the middle of the board happens to be a YM2413 which is connected to 0x9010/0x9030 and receives the same writes as the VRC7 FM core. It's operating properly and produces music without distortion or wrong sounding notes. (save the rom patches being different)

The 74LS138 is there to provide decoding for the YM2413 enable. It does leech it's clock from the VRC7 crystal oscillator.

The 555 timer IC is there as a "missing pulse detector", which monitors the phy2 signal. That provides a proper power on reset for the YM2413 and when phy2 stops changing states, YM2413 reset is held high, stopping the sound completely.

So the connection of YM2413 to the NES/Famicom is a non issue atm.
Re: Preview of my modded VegaPlay
by on (#131314)
lidnariq wrote:
yogi wrote:
I was thinking of getting a LGP famicom cart but didn't want to lay out the cash for it and a Fami-to-NES adaptor ATM.
If you're already up for rework, Tiny Toon Adventures 2 is a little bit cheaper on ebay. (Looks like ~$28 instead of ~$35)

I knew it used the VRC7 mapper but does it have a functional FM core? I remember seeing some discussion and guesses on if it can do expo sound but didn't think anyone had done it. It does seems likely that they would use the same chip but...
At ~$30 without an adapter, it does sound much better.

Quote:
Quote:
All banking would be in 24K blocks.
How would 24K blocks work? Specify an offset as a multiple of 8 KiB? Multiply by 3? 32 KiB where the top 8 KiB is concealed?


You're right, 32K banks (been awhile since I reviewed the sch) With the bulk of the kernel in WRAM and some bytes in each bank lost to the reset vectors and bankswitch trampoline. One bank loses the space for the CHR data and Reset code. We still end up with 7 30-31K banks and one 18-20K on a 256K device.
Attachment:
VRC Lite V0.1.png
VRC Lite V0.1.png [ 21.09 KiB | Viewed 2939 times ]

IC3 Bank Reg decoder- /W & PHI & 1000xxxxx000xxxx
IC2 YM decoder- /W & PHI & 1001xxxx00x1xxxx
Yogi
Re: Preview of my modded VegaPlay
by on (#131315)
l_oliveira wrote:
I commented about the YM2413, because the small chip in the middle of the board happens to be a YM2413 which is connected to 0x9010/0x9030 and receives the same writes as the VRC7 FM core. It's operating properly and produces music without distortion or wrong sounding notes. (save the rom patches being different)

The 74LS138 is there to provide decoding for the YM2413 enable. It does leech it's clock from the VRC7 crystal oscillator.

The 555 timer IC is there as a "missing pulse detector", which monitors the phy2 signal. That provides a proper power on reset for the YM2413 and when phy2 stops changing states, YM2413 reset is held high, stopping the sound completely.

So the connection of YM2413 to the NES/Famicom is a non issue atm.

OH COOL, I do have a couple YMs I got for this project. I Like the 555 auto reset, I hadn't addressed the reset properly.
Yogi
Re: Preview of my modded VegaPlay
by on (#131316)
It's actually a lot simpler than what you thought:
Image
(this is enough to make the YM2413 work properly without any side effects)

And I have a feeling that the mapper is using internally a logic function which is equivalent to a 74LS138 to decode all the register addresses...

Here's a little table I wrote at the time I was trying to see the big picture of the VRC7 registers decoding:
Code:
_____AAAAAAAAAAAAAAAA
_____1111110000000000
_____5432109876543210
______***______**____  <- * means "do care"
8000 *000000000000000
8010 *000000000010000
9000 *001000000000000
9010 *001000000010000
9030 *001000000110000
A000 *010000000000000
A010 *010000000010000
B000 *011000000000000
B010 *011000000010000
C000 *100000000000000
C010 *100000000010000
D000 *101000000000000
D010 *101000000010000
E000 *110000000000000
E010 *110000000010000
F000 *111000000000000
F010 *111000000010000
Re: Preview of my modded VegaPlay
by on (#131317)
yogi wrote:
I knew it used the VRC7 mapper but does it have a functional FM core?
Sure does, but you'll have to rewire it pretty substantially to get it a clock source and a reasonable audio amplifier.
Quote:
At ~$30 without an adapter, it does sound much better.
Waitamoment... the US release of TTA2 does not use the VRC7. You'll still need an adapter or a total rebuild of a cartridge.


Two 74'521s and a 74'20? Seems more complex than a few 74'138s...
Especially 'cuz we know the VRC7 is only paying attention to A12..A15, A5, and (A4 xor A3): not A6 or A7.

74'138: A14=0, A13=0, A12, A4, /ROMSEL=0, R/W=0. Decoding on A12 and A4 lets you capture all five PRG/audio registers. Still use the 74'20 for WRAM and to prevent bus conflicts. ... Need another inverter from somewhere... ... er, and what l_oliveira said.

edit: remove bad advice
Re: Preview of my modded VegaPlay
by on (#131318)
lidnariq wrote:
Still use the 74'20 for WRAM and to prevent bus conflicts. ... er, what l_oliveira said.


In my case, the real VRC7 is there and it has control of the ROM chip enable strobe. It certainly put the ROM "to sleep" when R/W is low.

If you're going to implement banking, I'd suggest a couple of 74LS670s.

a 74LS138 and a 74LS139 could be used to generate strobes which could then be combined using ports of 74LS32s to select.

But then due to the complexity of this, a PAL/GAL chip would be a better alternative for the combinational logic.

Using common sense we end figuring out that this stuff would be best fit within an modest CPLD chip after all. ;)
Re: Preview of my modded VegaPlay
by on (#131321)
l_oliveira wrote:
It's actually a lot simpler than what you thought:
Image
(this is enough to make the YM2413 work properly without any side effects)

And I have a feeling that the mapper is using internally a logic function which is equivalent to a 74LS138 to decode all the register addresses...

Here's a little table I wrote at the time I was trying to see the big picture of the VRC7 registers decoding:
Code:
_____AAAAAAAAAAAAAAAA
_____1111110000000000
_____5432109876543210
______***______**____  <- * means "do care"
8000 *000000000000000
8010 *000000000010000
9000 *001000000000000
9010 *001000000010000
9030 *001000000110000
A000 *010000000000000
A010 *010000000010000
B000 *011000000000000
B010 *011000000010000
C000 *100000000000000
C010 *100000000010000
D000 *101000000000000
D010 *101000000010000
E000 *110000000000000
E010 *110000000010000
F000 *111000000000000
F010 *111000000010000

Ok, so /Y1= /ROMSEL & A4 & /A12 & /A13 & A14
ADR b100x xxxx xxx1 xxxx, wouldn't this mirror at $8010 as well as $9010. Thinking about this, I guess for my design with a bank reg @ $8000 and the YM regs @ $9010 and $9030, 2- '138s would handle it, but would have to move A4 to /G2A or B for the $8000 address decoder. Isn't M2 relevant here or is it a factor of the /ROMSEL, so it's accounted for?
And Yes A5:A7 are not needed but I had the extra pins on the '521s (not a good reason to add the wires, I know).
Lidnariq wrote:
74'138: A14=0, A13=0, A12, A4, M2=1, R/W=0. Decoding on A12 and A4 lets you capture all five PRG/audio registers.

Shouldn't A14=1 for $8xxx or $9xxx and in both cases A12 should be 0? b100x for both $8 or $9. What am I missing, will have a look at the '138 truth table.
Yogi
EDIT- just figured it out The correct adr bit pattern bx001 xxxx xxx1 xxxx true for $9010 if we include /ROMSEL for Bit 15. And bx000 xxxx xxx0 xxxx & /ROMSEL is true for $8000.
Doh!
Re: Preview of my modded VegaPlay
by on (#131322)
There's absolutely no mirroring in the way you mention.

Because the 74LS138 considers A14,A13 and A12 on it's logic, the YM2413 will be mirrored at the whole 9000-9FFF range.
But then the FM synth inside the VRC7 mirrors in the exact same way.

For 8000 we have A15=1 A14=0 A13=0 A12=0 and for 9000 we have A15=1 A14=0 A13=0 A12=1, hence me connecting the YM2413 to Y1.
A4 is connected to non inverted G enable of the 74LS138 to prevent the YM2413 from appearing at 9000.

M2 is the actual source of CPU chip select signals on this system. /ROMSEL already brings M2 encoded in itself as it's just M2 when A15=1. You already know that since you exploit that to generate a chip select for WRAM.

Edit:
yogi wrote:
What am I missing, will have a look at the '138 truth table.


What you are missing is that the binary number being input on the three inputs correspond exactly to which output will be active:

321 <- inputs
000=Y0
001=Y1
010=Y2
011=Y3
100=Y4
101=Y5
110=Y6
111=Y7

(Y will be 0 only when /G1=0 /G2=0 and G1=1)

What is actually output depends on the status of the three G pins. Two are inverted and both need to be connected to gnd and the non inverted enable must be connected to +5v to make the selected output active.
Re: Preview of my modded VegaPlay
by on (#131323)
l_oliveira wrote:
There's absolutely no mirroring in the way you mention.

Because the 74LS138 considers A14,A13 and A12 on it's logic, the YM2413 will be mirrored at the whole 9000-9FFF range.
But then the FM synth inside the VRC7 mirrors in the exact same way.

For 8000 we have A15=1 A14=0 A13=0 A12=0 and for 9000 we have A15=1 A14=0 A13=0 A12=1, hence me connecting the YM2413 to Y1.
A4 is connected to non inverted G enable of the 74LS138 to prevent the YM2413 from appearing at 9000.

M2 is the actual source of CPU chip select signals on this system. /ROMSEL already brings M2 encoded in itself as it's just M2 when A15=1. You already know that since you exploit that to generate a chip select for WRAM.

Edit:
yogi wrote:
What am I missing, will have a look at the '138 truth table.


What you are missing is that the binary number being input on the three inputs correspond exactly to which output will be active:

321 <- inputs
000=Y0
001=Y1
010=Y2
011=Y3
100=Y4
101=Y5
110=Y6
111=Y7

(Y will be 0 only when /G1=0 /G2=0 and G1=1)

What is actually output depends on the status of the three G pins. Two are inverted and both need to be connected to gnd and the non inverted enable must be connected to +5v to make the selected output active.

I just worked out what I was missing. Looking at the '138s inputs A, B & C with A12, A13 & A14 ADR - $x001, but what I was SEEING was ADR bit15, 14 and 13 - $100x. In truth /ROMSEL active accounts for ADR Bit 15, so Bits 14:12 completes the MSNibble of the address. Hence the state of A12 determines if the nibble is $8 or $9. Got it.
/Y1 = /G2 & A & /B & /C & G1 = /ROMSEL & A12 & /A13 & /A14 & A4
Got to take a brake,
Yogi
Re: Preview of my modded VegaPlay
by on (#131324)
So thinking along these same lines
Attachment:
138 ADR decoder 2.png
138 ADR decoder 2.png [ 4.43 KiB | Viewed 2806 times ]

Came up with this
Yogi
Re: Preview of my modded VegaPlay
by on (#131357)
So wahoo \o/ fixed the Read routines.
Code:
Controller1Test:  ; Check Controller 1 till we get matching reads in a row
               LDA NewButtons      ; Get last pass button state
          STA OldButtons      ; Save to OldButtons

Chk_Loop1:   ; Read Controller till we get two consecutive matching reads
      LDA NewButtons
      STA LastPass            ; save copy of last state
      JSR Check_Joy1        ; Read Pad 1
      LDA NewButtons       ; Button State returned
      CMP LastPass           ; same as last?
           BNE Chk_Loop1        ; loop if reads don't match.

(sorry about the weird formatting above, can't get the forum to cooperate)
The Chk_Loop1 will run a min of 2x but not sure what the max would be during heavy DMAs.
Added a preview ROM into the dropbox on on the first post.
Yogi
Re: Preview of my modded VegaPlay
by on (#131403)
I've been testing blargg's "DPCM resistant" controller read code and it doesn't help at all with this problem.

If your solution works for the controller issue, it still creates a problem, which is holding up the processor during NMI processing....
Fortunately that problem is of easy solution:

Because the controller read routine and related processing doesn't rely on anything that *MUST* be done during NMI we can move it away from the NMI processing and insert it on the main loop (which is just a jump instruction which jumps on itself) and then we don't waste processor cycles during the NMI processing. To mod it to work that way we would just need to move the "ControllerTest" code to the "InfLoop" routine and remove the JSR instruction which originally called it.

Funny enough, when I did that, the bug manifested itself on FCEUX. Probably means that FCEUX is coded in a way that the the bug simulation code won't trigger if the processor core is doing interrupt processing...

Oh well...

Test case file added (includes asm listing) with controller stuff moved to main loop. Uses blargg's code for controller read. Music change instruction was removed so the music driver don't crash while "the cursor is dancing" ...
Re: Preview of my modded VegaPlay
by on (#131409)
l_oliveira wrote:
I've been testing blargg's "DPCM resistant" controller read code and it doesn't help at all with this problem.

You're not using the code properly. The DPCM glitch resistant button state byte is returned in A, it's not in tmp1.

EDIT: I didn't notice the listing file in the package so the variable name is not tmp1 in this case, obviously.
Re: Preview of my modded VegaPlay
by on (#131413)
VegaPlay testcase 2 here. Original controller code was put on main loop.

Again, listing included.

Edit: Test case 3 included
Re: Preview of my modded VegaPlay
by on (#131417)
l_oliveira wrote:
I've been testing blargg's "DPCM resistant" controller read code and it doesn't help at all with this problem.

If your solution works for the controller issue, it still creates a problem, which is holding up the processor during NMI processing....
Fortunately that problem is of easy solution:

Because the controller read routine and related processing doesn't rely on anything that *MUST* be done during NMI we can move it away from the NMI processing and insert it on the main loop (which is just a jump instruction which jumps on itself) and then we don't waste processor cycles during the NMI processing. To mod it to work that way we would just need to move the "ControllerTest" code to the "InfLoop" routine and remove the JSR instruction which originally called it.

Funny enough, when I did that, the bug manifested itself on FCEUX. Probably means that FCEUX is coded in a way that the the bug simulation code won't trigger if the processor core is doing interrupt processing...

Oh well...

Test case file added (includes asm listing) with controller stuff moved to main loop. Uses blargg's code for controller read. Music change instruction was removed so the music driver don't crash while "the cursor is dancing" ...

I watched your 1st test rom, thanks. That sprite behavior doesn't seem like the DMA bug to me; more of a case of the sprit data or pointer getting over written. It doesn't affect the NSF playback so its not changing the 'SongNumber' VAR that is passed to the InitMusic routine. Just saw that you commented out "JSR InitMusic" at the end of EndDrawChk:
Should recheck your ControllerTest:
NewButton3 is the first Read; stack holds the second Read; NewBotton2 is the third Read; 'A' then holds the fourth read but you overwrite it from the stack with the second Read.
A> CMP second Read to first Read, and exit to JoyEnd if Equal.
B> If not Equal, CMP second Read to NewButtons (which seems like it's undefined) and exit to JoyEnd if Equal.
C>If not Equal get the third Read (which may or may not match the first two Reads) and drop into JoyEnd and RTS.
Thinking you wanted a four Read test routine, but it is only testing the first two reads and assuming the third Read will be good if the first two fail. The undefined NewButtons is part(all) of the problem. That may solve your sprite/NewSong problem but you will need to restructure to get the four Read testing working, I think. I would also avoid the stack it may be a problem also if other code is using it in the NMI; or Not.

The configuration I'm using with the MMC1 code, has the bulk of the logic in the main loop. It's based on the VegaPlay fork called FamiSlayer v6.66
http://www.heavyw8bit.com/famislayer.php
The NMI routine I use only does a few tests to either call the NSF Frame Play code or let the Main loop do the Frame Play. The choice is based on a Assembler definition 'Sync'. It will never changed at runtime, so could be rewritten with IFDEFs to eliminate the Sync check.
Code:
NMI:         ;Extern NMI = NSFroutine + $021F
         ; Save regs to stk
   PHA
   TXA
   PHA
   TYA
   PHA
    JSR UpdateSprites   
   LDA StartMode      ; Mode CHK: 1=PLAYING OR  0=STOPPED
    BEQ NMIexit         ; IF STOPPED, We're done
   LDA #Sync         ; Test Sync option
   CMP #$01
   BEQ NMIexit         ; If Sync = 0, NSFplay via NMI
   JSR RamPlay         ; go sub to NSF Play vector
NMIexit:   ; Restore regs from stk
   PLA
   TAY
   PLA
   TAX
   PLA
         ; Fall into IRQ for RTI

IRQ:      ;Extern IRQ = NSFroutine + $023A
    RTI


Though I had tried another Controller Read routine that had a fixed structure- 'read twice; CMP both; and do again if no match' , it had issues but could have been the surrounding code. Also tried not using the 'RIGHT' button at all, this solved the DMA issue but complicated the UI layout. But it did demonstrate to me that the the DMA bug seems to only affect Bit7. Anyone know for sure?
With the controller read loop I posted, in most cases it will execute twice, but I don't know the max pass count with DMA interference.
It plays all the NSF that had failed before, without the 'false trigger' bug, but I did notice a slight tempo slow down that occurred after 2-5 mins of play time on a file (testing on Nestopia). I'm not convinced of the reason; could have been caused by a Windows' background tasks or some other code issue. Needs more testing but not sure there is a tempo fix, in my case, for NSFs that heavily use the DPCM channel aside from just not using the 'RIGHT' button.
Yogi
Re: Preview of my modded VegaPlay
by on (#131419)
After very useful insights from thefox at #NESDEV IRC I got this to work properly.

This time I included the asm file so yogi, give this controller read code a try on your sources for MMC1...
Re: Preview of my modded VegaPlay
by on (#131420)
Thanks man, I'll look it over but my code is working with the new controller Read code I posted.
Yogi
Re: Preview of my modded VegaPlay
by on (#131421)
yogi wrote:
Thanks man, I'll look it over but my code is working with the new controller Read code I posted.
Yogi


Yep, but I meant, put this on place of your code and test if it has any differences on performance...
Re: Preview of my modded VegaPlay
by on (#131422)
From your 4th test rom
Code:
ControllerTest:                 ;EDIT:
   JSR ReadController   ; ReadController: returns in A AND NewButtons
   STA NewButtons3    ; First Read Val
   JSR ReadController
   PHA                        ; Stack has Second Read Val
   JSR ReadController
   STA NewButtons2     ; Third Read Val
   JSR ReadController   ; Fourth Read in NewButtons

   PLA                          ; POP Second Read
   CMP NewButtons3      ; Is Second = First?
   BEQ JoyEnd
   CMP NewButtons       ; Is Second = Fourth?
   BEQ JoyEnd
   LDA NewButtons2      ; No, so use Third Reading must be good (?)
   CMP #0                     ; CMP Third to 0 (?) set/clr Z (?)
JoyEnd:
   STA NewButtons        ; Store current Read 
   RTS                         ; Return

My code works for me, so not sure I should comment on your's if it works for you.
Yogi
EDIT: just noticed that your NES doesn't actually change the song, just moves the sprite. Was this your intent?
EDIT2: Changed the comments to better reflect the VAR usage.
Re: Preview of my modded VegaPlay
by on (#131423)
yogi wrote:
EDIT: just noticed that your NES doesn't actually change the song, just moves the sprite. Was this your intent?


Yes, I was using a 1 song NSF and issuing a music change command would crash the playback driver.

That patch on the code was intended to stop the change music command from crashing the sound playback thread so the behavior of DPCM controller glitch could be fully appreciated.


Edit:
That controller code is from blargg:
viewtopic.php?t=4124

The point is doing multiple reads to reduce the chances of glitch on the controller input. As a bonus it also checks the expansion port for external controllers (this is a Famicom and some people use controllers connected to the 15 pin expansion port it has on the front...).
Re: Preview of my modded VegaPlay
by on (#131424)
Here's the DPCM-safe code I use in my own projects, extracted from my project template. It handles both player 1 and player 2 as well as Famicom expansion controllers. And because it reads only twice, it takes nearly constant time unlike some routines that read repeatedly and wait for it to settle.
Code:
.segment "ZEROPAGE"
cur_keys: .res 2
new_keys: .res 2

.segment "CODE"
.proc read_pads
thisRead = $0000  ; local temporary variables
firstRead = $0002
lastFrameKeys = $0004

  ; store the current keypress state to detect key-down later
  lda cur_keys
  sta lastFrameKeys
  lda cur_keys+1
  sta lastFrameKeys+1

  ; Read the joypads twice in case DMC DMA caused a clock glitch.
  jsr read_pads_once
  lda thisRead
  sta firstRead
  lda thisRead+1
  sta firstRead+1
  jsr read_pads_once

  ; For each player, make sure the reads agree, then find newly
  ; pressed keys.
  ldx #1
@fixupKeys:

  ; If the player's keys read out the same way both times, update.
  ; Otherwise, keep the last frame's keypresses.
  lda thisRead,x
  cmp firstRead,x
  bne @dontUpdateGlitch
  sta cur_keys,x
@dontUpdateGlitch:
 
  lda lastFrameKeys,x   ; A = keys that were down last frame
  eor #$FF              ; A = keys that were up last frame
  and cur_keys,x        ; A = keys down now and up last frame
  sta new_keys,x
  dex
  bpl @fixupKeys
  rts

read_pads_once:

  ; Bits from the controllers are shifted into thisRead and
  ; thisRead+1.  In addition, thisRead+1 serves as the loop counter:
  ; once the $01 gets shifted left eight times, the 1 bit will
  ; end up in carry, terminating the loop.
  lda #$01
  sta thisRead+1
  ; Write 1 then 0 to JOY1 to send a latch signal, telling the
  ; controllers to copy button states into a shift register
  sta JOY1
  lsr a
  sta JOY1
  loop:
    ; On NES and AV Famicom, button presses always show up in D0.
    ; On the original Famicom, presses on the hardwired controllers
    ; show up in D0 and presses on plug-in controllers show up in D1.
    ; D2-D7 consist of data from the Zapper, Power Pad, Vs. System
    ; DIP switches, and bus capacitance; ignore them.
    lda JOY1       ; read player 1's controller
    and #%00000011 ; ignore D2-D7
    cmp #1         ; CLC if A=0, SEC if A>=1
    rol thisRead   ; put one bit in the register
    lda JOY2       ; read player 2's controller the same way
    and #$03
    cmp #1
    rol thisRead+1
    bcc loop       ; once $01 has been shifted 8 times, we're done
  rts
.endproc
Re: Preview of my modded VegaPlay
by on (#131430)
l_oliveira wrote:
yogi wrote:
EDIT: just noticed that your NES doesn't actually change the song, just moves the sprite. Was this your intent?


Yes, I was using a 1 song NSF and issuing a music change command would crash the playback driver.

That patch on the code was intended to stop the change music command from crashing the sound playback thread so the behavior of DPCM controller glitch could be fully appreciated.

OK thought so but just thought I should point it out if you didn't realise. In my routine I can start/stop playback and test song selection, of course if I try to play song 2-10 of a single song NSF it will crash.

Quote:
Edit:
That controller code is from blargg:
viewtopic.php?t=4124

The point is doing multiple reads to reduce the chances of glitch on the controller input. As a bonus it also checks the expansion port for external controllers (this is a Famicom and some people use controllers connected to the 15 pin expansion port it has on the front...).

I understand the need to do multi reads; but the fourth read is not used for anything. Is it just a wait loop?

Quote:
Yep, but I meant, put this on place of your code and test if it has any differences on performance...

Well this code would need some fixes to work in my code infrastructure that aren't trivial. I'll try it at some point, after I get a bit more testing done.
So far with my testing: Went through the NSFs I used in this test rom
Attachment:
vegaplayMMC1test16.nes [256.02 KiB]
Downloaded 98 times

Some of the source NSFs have a 'random dropped frame' issue in Nestopia that also shows up in the NES (GIGO ?).
The worst is (NSF #5):
Attachment:
Entry087.nsf [23.25 KiB]
Downloaded 99 times

It's a good. fast song but really hammers the DPCM channel. This is the only one that causes an occasional bankswitch now (so even doing multi reads can return a false read?). With Nestopia the NSF drops the tempo from time to time (unintentionally, I think) as do a few other NSF also.
The fact that the source NSFs have problems playing in Nestopia leads me to believe there is:
a. a bug/problem with the NSF in question
b. a bug with Nestopia
c. a bug caused by Windows
d. The Moon is in the wrong phase for chiptune playback

Will be burning to a cart to see how real HW handles it.
Yogi
Re: Preview of my modded VegaPlay
by on (#131431)
tepples wrote:
Here's the DPCM-safe code I use in my own projects, extracted from my project template. It handles both player 1 and player 2 as well as Famicom expansion controllers. And because it reads only twice, it takes nearly constant time unlike some routines that read repeatedly and wait for it to settle.
Code:
.segment "ZEROPAGE"
cur_keys: .res 2
new_keys: .res 2

.segment "CODE"
.proc read_pads
thisRead = $0000  ; local temporary variables
firstRead = $0002
lastFrameKeys = $0004

  ; store the current keypress state to detect key-down later
  lda cur_keys
  sta lastFrameKeys
  lda cur_keys+1
  sta lastFrameKeys+1

  ; Read the joypads twice in case DMC DMA caused a clock glitch.
  jsr read_pads_once
  lda thisRead
  sta firstRead
  lda thisRead+1
  sta firstRead+1
  jsr read_pads_once

  ; For each player, make sure the reads agree, then find newly
  ; pressed keys.
  ldx #1
@fixupKeys:

  ; If the player's keys read out the same way both times, update.
  ; Otherwise, keep the last frame's keypresses.
  lda thisRead,x
  cmp firstRead,x
  bne @dontUpdateGlitch
  sta cur_keys,x
@dontUpdateGlitch:
 
  lda lastFrameKeys,x   ; A = keys that were down last frame
  eor #$FF              ; A = keys that were up last frame
  and cur_keys,x        ; A = keys down now and up last frame
  sta new_keys,x
  dex
  bpl @fixupKeys
  rts

read_pads_once:

  ; Bits from the controllers are shifted into thisRead and
  ; thisRead+1.  In addition, thisRead+1 serves as the loop counter:
  ; once the $01 gets shifted left eight times, the 1 bit will
  ; end up in carry, terminating the loop.
  lda #$01
  sta thisRead+1
  ; Write 1 then 0 to JOY1 to send a latch signal, telling the
  ; controllers to copy button states into a shift register
  sta JOY1
  lsr a
  sta JOY1
  loop:
    ; On NES and AV Famicom, button presses always show up in D0.
    ; On the original Famicom, presses on the hardwired controllers
    ; show up in D0 and presses on plug-in controllers show up in D1.
    ; D2-D7 consist of data from the Zapper, Power Pad, Vs. System
    ; DIP switches, and bus capacitance; ignore them.
    lda JOY1       ; read player 1's controller
    and #%00000011 ; ignore D2-D7
    cmp #1         ; CLC if A=0, SEC if A>=1
    rol thisRead   ; put one bit in the register
    lda JOY2       ; read player 2's controller the same way
    and #$03
    cmp #1
    rol thisRead+1
    bcc loop       ; once $01 has been shifted 8 times, we're done
  rts
.endproc

Thanks, at one point I tried converting the core read routine from your template, but ran into issues with my cut down (busted) version and the surrounding code. I will revisit it with a fresh mind :)
yogi
Re: Preview of my modded VegaPlay
by on (#131433)
yogi wrote:
I understand the need to do multi reads; but the fourth read is not used for anything. Is it just a wait loop?

The fourth read places the controller byte into NewButtons (in this case). The value gets compared to later on with CMP NewButtons.
Re: Preview of my modded VegaPlay
by on (#131436)
thefox wrote:
yogi wrote:
I understand the need to do multi reads; but the fourth read is not used for anything. Is it just a wait loop?

The fourth read places the controller byte into NewButtons (in this case). The value gets compared to later on with CMP NewButtons.

Hey Thefox, sorry, I missed that in the ReadController Sub
Yogi
Re: Preview of my modded VegaPlay
by on (#131480)
Hey yogi, more stuff for you to play with ! :)

The N163 was a tad tricky to get to work because hardware NSF players don't rely on the mapper native mechanism so they aren't affected by this issue:

N163 has the sound hardware enable bit on one of the bank change registers so I had to "patch" the driver code to not write there as it was crashing due to unwanted memory bank changes.

And this song is just plain awesome...

Edit: There were some writes missing on the code. I did not init the registers which did CIRAM control so in FCEUX it works fine but on the real thing you get a nice gray screen with music playing.

There's a fixed version, now.

Edit2: The volume is wrong on my cart. N163 plays way too loud. This tune is 1 channel and my N163 dev cart is based on a 8 channel game.
Re: Preview of my modded VegaPlay
by on (#131487)
Now that the basic idea is laid out, the mapper init code can be useful to other people so I'd like to add this one, too.
Re: Preview of my modded VegaPlay
by on (#131494)
l_oliveira wrote:
I did not init the registers which did CIRAM control
Huh, I bet you could use that to make a board that wouldn't need to have its CHR-ROM replaced.
Quote:
This tune is 1 channel and my N163 dev cart is based on a 8 channel game.
Sadly, nothing to be done for that other than adding a potentiometer...
Re: Preview of my modded VegaPlay
by on (#131496)
Could you re-export the tune with more channels enabled but silent? That would lower the volume. (Trivial if you have famitracker source, not so trivial if all you have is the NSF.)
Re: Preview of my modded VegaPlay
by on (#131497)
lidnariq wrote:
Huh, I bet you could use that to make a board that wouldn't need to have its CHR-ROM replaced.

Yep, but the point here was use that "ugly" board I made with the N163 I got from Namco Classic II, so it already has a socket for CHR-ROM...

(this one)http://forums.nesdev.com/viewtopic.php?f=9&t=8570

lidnariq wrote:
Sadly, nothing to be done for that other than adding a potentiometer...

Yeah ... I will look into implementing something like that.

rainwarrior wrote:
Could you re-export the tune with more channels enabled but silent? That would lower the volume. (Trivial if you have famitracker source, not so trivial if all you have is the NSF.)


That's actually a very good idea, but considering the "generic" context this is going to have, adjustable volume could be something more desirable ...
Re: Preview of my modded VegaPlay
by on (#131498)
Hey Guys,
You've been busy l_oliveira. ++ on the Sunsoft 5B :) With INL's flash cart this would be killer!
The N163 sounds so good, may have to go hunting on Ebay for a donor cart. Looked over the code but will need a closer look for an indepth understanding. Lik'en It

Been working on another preview. This time moved the Sprite Ram into WRAM @ $6000, had a few NSF that trashed it @ $0500.

As to the DMA bug, I took the coward's way out; now the code only checks the 'Start' button during playback. You can select Song/NSF only when NO song is playing. This avoids the random false 'Right' trigger, but it's not a great solution. So there is extra button pressing, Start Button to stop the playing song and then select a new song/NSF.
I tried your ControllerTest routine, l_oliveira, but ran into issues that broke the main code so I set it aside for the moment.
As things are I had planned to use Right/Left buttons on Controller 2 for Midi controlled Frame FF and Rewind. Wouldn't be the end of the world if I have to re-assign these functions to other buttons, just have to adjust my PIC code. Hummm

When I included this 'pre check' just after my Controller1Test
Code:
   LDA NewButtons      ; Check for a New Active buttons
   BEQ BreakOut      ; NewButtons=$FF, No buttons pressed
   CMP OldButtons      ; Pressed buttons same as last MainLoop Pass?
   BNE Update         ; No , so test Controller 1 buttons
   
BreakOut:
   JMP MainLoop

This improved playback in the last Preview code, but didn't eliminate the DMA bug.

The odd effect was, the NSF that would trip a bankswitch would never do it at the same Frame, some NSFs did it after 3-6 loops. This leads me to think it's a side effect of my MainLoop's controller read frequency and the DPCM useage lining up at random (or very long cycle) points where I have two false reads in a row that are affected by the DMA. Bears more thought.

Anyway, here is the latest build preview. A new group of songs from the Famicomp Mini 10. NSF #3 is very experimental and 'beepy'; when I first listened to it in my build, I freaked out. The song REALLY does some weird tempo breaks and sounds like the NES is broken at some points :)
NSF #5 is the same song from last preview, Without random banking.
Attachment:
Main_vpMMC16.nes [256.02 KiB]
Downloaded 103 times

Yogi
Re: Preview of my modded VegaPlay
by on (#131502)
If you put the display list at $6000, some playback engine will probably end up trashing it there too. You might need to make it configurable per NSF.
Re: Preview of my modded VegaPlay
by on (#131503)
The issue with $500 is that some NSFs do clear the RAM when you call their init routine.

First time I saw that was on the 5B driver from mmlshare.com, on this Gato/Gonzales music I just posted.

In my humble opinion, the NSF standard is just as bad as the whole INES problem with only 256 mapper slots ... A big mess. XD
Re: Preview of my modded VegaPlay
by on (#131506)
tepples wrote:
If you put the display list at $6000, some playback engine will probably end up trashing it there too. You might need to make it configurable per NSF.

That is a good point, is there any ram that is un-molested by NSF play routines?
As l_oliveira noted there is a vast gray area as to what a NSF can do. Am I wrong in thinking the vast majority of NSF Play routines don't touch WRAM? I know WRAM addresses are part of the NSF definition but in practice how many Trackers/Composition tool's player code use it? Only a very small number of NSF I have tried had a issue with ram at $0500 let alone WRAM (none) but my sample size is very small and I haven't messed at all with game rips (which may be more probable to use WRAM).
But this brings up another point I've been wondering about. As this code switches between NSF, should I be clearing the low ram as I do in the reset routine? (haven't see any problem so far, but...) All my VARs and Sprites are in WRAM now, so clearing the lo ram is only a benefit to the loaded NSF. It's really not clear to me if the NSF handles the initialization of the ram it uses.
Then again the NSF format was never assumed to be running on a console, right?
Yogi
Re: Preview of my modded VegaPlay
by on (#131509)
The code which tampers with the sprites buffer on the Gonzales song is like this:
Code:
 06:8080:20 93 80  JSR $8093
 06:8083:60          RTS
....
 06:8093:A9 00      LDA #$00
 06:8095:A2 00      LDX #$00
 06:8097:9D 00 00  STA $0000,X @ $0000 = #$03
 06:809A:9D 00 02  STA $0200,X @ $0200 = #$8E
 06:809D:9D 00 03  STA $0300,X @ $0300 = #$00
 06:80A0:9D 00 04  STA $0400,X @ $0400 = #$00
 06:80A3:9D 00 05  STA $0500,X @ $0500 = #$37
 06:80A6:9D 00 06  STA $0600,X @ $0600 = #$00
 06:80A9:9D 00 07  STA $0700,X @ $0700 = #$00
 06:80AC:E8          INX
 06:80AD:D0 E8      BNE $8097
 06:80AF:A9 00      LDA #$00


It's quite obviously an ram clear routine which also happens to be similar to the existing one on VegaPlay.
At least it leaves the stack alone ...
(hehehe)

To fix this I just changed the JSR routine at the init address ($8080) to call $80AF instead of $8093.

Still I don't understand why someone would put a ram clear routine on a NSF.

Clearing the RAM supposedly is meant to be done by the NFS player firmware.
Re: Preview of my modded VegaPlay
by on (#131520)
Yogi, while your goal (at the moment) seems to be pack a lot of songs on a cartridge, I wanted mostly to get the "in driver" banking working so I could play the longer, bigger songs.

Yesterday I did a experiment with a banked N163 song which at the moment only work on emulators. I'll do more testing to try to figure out why it only work on emulators but apparently seems to be a issue with the driver itself because when I tried a non banked song which used the same driver it failed with the same exact behavior.

This MCK driver is interesting because it seems to only bank $A000-$BFFF and $C000-$DFFF which matches perfectly the required behavior for operating on the real hardware.

Even then, I had to do some changes on the banking code:

- Modify mapper init on VegaPlay to init mapper for low bank numbers as I started to put the NSF at the start of the ROM file.
- Modify the NSF native init code to not touch memory regions used by VegaPlay.
- Modify the NSF banking code to not touch registers it's not supposed to and modify the actual banking code to use one 8KB bank instead of two 4KB banks:

Code:
Original:
 00:816E:C9 0E      CMP #$0E
 00:8170:B0 0D      BCS $817F
 00:8172:8D FA 5F  STA $5FFA
 00:8175:18          CLC
 00:8176:69 01      ADC #$01
 00:8178:C9 0E      CMP #$0E
 00:817A:B0 03      BCS $817F
 00:817C:8D FB 5F  STA $5FFB
 00:817F:60           RTS

Edited:
 00:816E:C9 0E      CMP #$0E
 00:8170:B0 0D      BCS $817F
 00:8172:EA          NOP
 00:8173:EA          NOP
 00:8174:EA          NOP
 00:8175:EA          NOP
 00:8176:EA          NOP
 00:8177:EA          NOP
 00:8178:EA          NOP
 00:8179:EA          NOP
 00:817A:EA          NOP
 00:817B:6A          ROR           <- Rotate 1 bit right because we're banking with 8KB banks, so we have 1 address line less to deal with.
 00:817C:8D 00 E8  STA $E800 <- This write originally went to $5FFA. We discard $5FFB write completely hence the NOPs.
 00:817F:60           RTS



- Relocate the stuff which used to get mapped at $E000-$FFFF to the end of the ROM image and fix some data the NSF had on the vectors position to stay at $FFE8 instead ...

(this is a work in progress)
Re: Preview of my modded VegaPlay
by on (#131584)
Hi Ya,
l_oliveira wrote:
Yogi, while your goal (at the moment) seems to be pack a lot of songs on a cartridge, I wanted mostly to get the "in driver" banking working so I could play the longer, bigger songs.


Your efforts are greatly appreciated; I have barely scratched the surface of the NSF format and am trying to learn more. This project (the VRC7 and SNROM) is my first with the NES and it was something I thought I could:
A. Learn NES/Famicom development
B. Build something that feeds my personal interest and the Chiptune crowd.
So Please I hope you don't think I'm not interested in your project, just the opposite! :)
Quote:
Yesterday I did a experiment with a banked N163 song which at the moment only work on emulators. I'll do more testing to try to figure out why it only work on emulators but apparently seems to be a issue with the driver itself because when I tried a non banked song which used the same driver it failed with the same exact behavior.

This MCK driver is interesting because it seems to only bank $A000-$BFFF and $C000-$DFFF which matches perfectly the required behavior for operating on the real hardware.

Even then, I had to do some changes on the banking code:

- Modify mapper init on VegaPlay to init mapper for low bank numbers as I started to put the NSF at the start of the ROM file.
- Modify the NSF native init code to not touch memory regions used by VegaPlay.
- Modify the NSF banking code to not touch registers it's not supposed to and modify the actual banking code to use one 8KB bank instead of two 4KB banks:

Code:
Original:
 00:816E:C9 0E      CMP #$0E
 00:8170:B0 0D      BCS $817F
 00:8172:8D FA 5F  STA $5FFA
 00:8175:18          CLC
 00:8176:69 01      ADC #$01
 00:8178:C9 0E      CMP #$0E
 00:817A:B0 03      BCS $817F
 00:817C:8D FB 5F  STA $5FFB
 00:817F:60           RTS

Edited:
 00:816E:C9 0E      CMP #$0E
 00:8170:B0 0D      BCS $817F
 00:8172:EA          NOP
 00:8173:EA          NOP
 00:8174:EA          NOP
 00:8175:EA          NOP
 00:8176:EA          NOP
 00:8177:EA          NOP
 00:8178:EA          NOP
 00:8179:EA          NOP
 00:817A:EA          NOP
 00:817B:6A          ROR           <- Rotate 1 bit right because we're banking with 8KB banks, so we have 1 address line less to deal with.
 00:817C:8D 00 E8  STA $E800 <- This write originally went to $5FFA. We discard $5FFB write completely hence the NOPs.
 00:817F:60           RTS



- Relocate the stuff which used to get mapped at $E000-$FFFF to the end of the ROM image and fix some data the NSF had on the vectors position to stay at $FFE8 instead ...

(this is a work in progress)

Quite interesting; which disassembler do you use? I've tried FCEUltra but it's timing is not setup right or this XP box just doesn't like it; it runs very badly and stutters horribly. Looking for a stand alone disassembler.
I implemented the ControllerTest code you posted with mixed results. It runs fine and I think is faster on average, than the original routine I had; but the troubled NSFs have the same errors as when using the original code. So I'm thinking there is a subtle bug somewhere else. Or it is due to the frequency I read the controllers in the Main Loop and the timing of the DMA activity. In which case I will have to live with it and use the workaround of not reading the 'Right' button, which is not the worst thing (it speeds up the Main Loop). At the very least, the good news is I have a definite cycle count for each pass of the routine.
Also changed the handling of the Sprite ram, to allow easy reassignment of it's ram location. WRAM should be the safest place; if the NSF clears WRAM, it will destroy the runtime code as well, so this software will not support it anyway. But it's flexible enough if I needed to use system ram at some point or in another project.
I just ordered one of INL's Sunsoft 5B carts so next on the agenda is to try out your 5B code! Looking forward to it,
Yogi
Re: Preview of my modded VegaPlay
by on (#131585)
yogi wrote:
Looking for a stand alone disassembler.

I used da65 (from the makers of cc65) to recover my DPCM Split demo after a laptop died and all I had was the .nes binary.
Re: Preview of my modded VegaPlay
by on (#131586)
tepples wrote:
yogi wrote:
Looking for a stand alone disassembler.

I used da65 (from the makers of cc65) to recover my DPCM Split demo after a laptop died and all I had was the .nes binary.

OK will give that a try, Thanks.
Re: Preview of my modded VegaPlay
by on (#131587)
I have been astoundingly pleased with bisqwit's clever-disasm (part of nescom). ... but his site seems to be down at the moment.
Re: Preview of my modded VegaPlay
by on (#131588)
The nescom part of site seems to be work for me... The git server looks like it's down, though.
Re: Preview of my modded VegaPlay
by on (#131648)
l_oliveira wrote:
I'll do more testing to try to figure out why it only work on emulators but apparently seems to be a issue with the driver itself because when I tried a non banked song which used the same driver it failed with the same exact behavior.


I spent the WHOLE WEEKEND tinkering with this and in the end THERE WERE NOTHING WRONG WITH THE CODE.

-_______-;


The problem was fuxxoring crappy unreliable flash memories.

Several types of flash memory seem to be unreliable when used in a configuration where the /OE pin is to be tied to GND.
Even "high quality" Intel chips gave me this headache.
I suppose I'll stick to Atmel flash chips when working with 6502 based stuff ... :P

Once I burnt "Dancing Mad" on a Atmel flash chip the thing booted properly and played the song.

edit: Disassembler ? I'm loading the NSF file on FCEUX and debugging it there (debugger with conditional watchpoints and breakpoints, hexa editor/viewer and instruction logging, not to mention a very decent real time disassembler). The point of doing it this way is that you can watch things happening in real time. Also helps with learning the processor.
Re: Preview of my modded VegaPlay
by on (#132559)
Just letting you know I didn't give up yet on this yet ... Just hella busy with other things ...

This is a very large banked song for you to listen to.

The VRC7 rocks, man !
Re: Preview of my modded VegaPlay
by on (#132561)
Crashes after I change the track number twice ?
Re: Preview of my modded VegaPlay
by on (#132562)
lidnariq wrote:
Crashes after I change the track number twice ?


There's only one song on that .nes file. Famitracker driver still tries to find "song 2" even if there's none, hence the crash...