Ok so, I'm trying to make a multi song NES cart and I came across vegaplay and thought my prayers were answered. All up until I got about 3 songs into my writing (compiling some tests every step of the way as usual) I noticed that hitting the button for next song it will only go to track 2. Furthermore, if I hit up to go backwards one song, it will glitch out and play garbage. I've attached some test .nsf, .nes, and .asm files to show you what I mean. The nsf labeled 'orig' has the nsf header intact. Something important to note here is that I'm using MML to code my songs and I'm using the TextMate Multi-Song MML Bundle to compile the nsf.
I would really appreciate any help you can give me. I'm really running out of options when attempting to fit a album on a cart, cause I attempted famitracker but I can't figure out how to optimize file size as much as I can with MML. It comes nowhere close to as small as my mml versions. Being able to loop individual channels with |: \ :| can give me so much more memory.
Thank you for your time.
Your problem is that your music engine is trying to use the same RAM that Vegaplay is using to store sprites and track numbers and so they're messing with each other's memory. You need to either change the memory locations your music engine uses, or edit vegaplay.asm to use $200 instead of $700 for the start of the sprite buffer.
Where in the asm do you see $700? I had messed with lines 210 and 217 once before and I changed them to $200 because the help doc said to change it from the default $500 in case I was getting glitchy sprites, which I am, but I'm not concerned with the sprites. All I want is the music to play properly. And it had no effect anyway. I even tryed removing everything related to sprites, which got rid of the glitchy graphics but the music was still broken in the same way.
I'm kind of a beginner so I don't know how to change where the song numbers live or how to change the memory location of my music engine. Which is easier? Could you tell me the basics of how to do both the option you offered?
The relevant problem you're having is that the NSF is clearing all of memory for you, so it's a miracle the code works at all. Try replacing the bytes in your NSF from 0x0093 through 0x00A9 with the byte 0xEA.
As far as I can tell, your NSF is using random chunks all over the entirety of the NES's 2k of RAM. There's no large contiguous chunk of memory large enough to hold sprites, let alone predict where's safe for vegaplay to store its private variables. So "it's not you, it's them", not that helps you.
It tentatively looks like the bottom 16 bytes of memory ($00 through $0F) might be unused by your NSF, to use this you'll need to replace all the places in vegaplay.asm where anything else is used. This is both your $c1/$c2/$c3/$c4/$c5 but also vegaplay's use of $10 and $11 in DrawScreen, and you'll have to trash the sprites code (as you probably already knew)
By the way, the NES only has 2k of RAM, there's no point in the sta $0800,x or sta $0900,x instructions; they're entirely redundant to the earlier sta $00,x and sta $0100,x instructions.
Damn, Lidnariq beat me to it!
I wonder if it's even worth it to try to use the stack $0100-$01FF (which isn't cleared) for the program's RAM. (Obviously no sprites, though!)
Let's say you want to change songs. The program depends on the previous song being in RAM. Except... the second you press the button to change the song, that RAM is cleared. That's why you could only get to track 2. Add one to current song. Play second track. But at the start of the second track, current song is made the first track again. Press down. Add one to current song... etc.
Edit: HAH! That totally works (The stack thing). Attached is a file that will work for you. As a bonus, I made it easier to change the number of songs. How complicated do you want your cart to be? Many of us could write a thing that could work in just the unused stack bytes (heh), as long as you're not going for epic presentation.
An even more stealth way to use the stack is to push bytes on the bottom of the stack to reserve space at reset (or simply TXS a value lower than $FF). The lets you use some space, say $1F0-1FF, and the chances of it interfering are extremely improbable. The Powerpak NSF player does this, since some rare NSFs still use the low area of $100 for things, but none depend on the reset state of the stack (this would be forbidden by the NSF spec anyway).
Wow, thanks that worked well. Kasumi, your asm made the song selection work alot better cause looping back to song one is now functioning. and lidnariq, your idea made the curser show up in the right places as well as allowed the third track to join the party. Though I might have fibbed when I said I didn't care about the sprites. The background is a must, but having the curser sprite would still be very nice. I'm working on a background image that I want to be displayed. But as far as what I'm trying to accomplish is I want to use up as much as the 30k as possible with song data. I want to fit a decent amount of music on the cart. Will the method of fixing the code be different depending on how full my music data gets? if so I guess I'll have to wait till I finish writing the album to come ask you wizards for help. If not I would greatly appreciate a modified asm I could work from.
Right now your NSF uses short arrays in RAM spaced all over it every 64 or 128 bytes, all the way from $0200 up to $07FF. It's hard to be sure what exactly that MML replay engine is doing, and whether they'll actually use all that space (in which case, no sprites for you) or are just pretending to be a gas (and expanding to fill all available space; in this case you could move things around to make space).
You should probably talk to the developer and ask what's going on, and if they might be willing to make a version that leaves 256 contiguous bytes for you somewhere.
The PPMCK MML NSF engine clears RAM itself during init, which is annoying because the NSF player is required to do this ahead of time.
So, modifying the asm for you means modifying the PPMCK MML assembly for your NSF, not VegaPlay.
If PPMCK MML works by assembling the NSF with an assembler, then you should be able to make the changes to its source conveniently to prevent the problem in the future. There should be some code near the beginning of the assembly file that looks like this:
sta $200, x
sta $300, x
sta $400, x
sta $500, x
sta $600, x
sta $700, x
inx
Just comment it out, or whatever you need to do to get rid of it.
(I haven't looked directly at PPMCK MML source, I just have dealt with it in disassembly before.)
To do what rainwarrior suggests, look for sounddrv.h in the MML package. (provided whatever I downloaded is actually what you mentioned)
Code:
.memclear
sta $0000,x
sta $0200,x
sta $0300,x
sta $0400,x
sta $0500,x
sta $0600,x
sta $0700,x
inx
bne .memclear
to
Code:
; .memclear
; sta $0000,x
; sta $0200,x
; sta $0300,x
; sta $0400,x
; sta $0500,x
; sta $0600,x
; sta $0700,x
; inx
; bne .memclear
Also, the screen won't cause any problems, just take out the semicolon before JSR DrawScreen on line 131. Instead of sprites, the background could be updated for a cursor, but that requires a bit more work. Also, if you want more than 10 songs (or as many will fit on the screen if you change it), that also becomes more work.
Nice. I found the sounddrv.h inside the MML Bundle, and changed it as you mentioned. It has the same result as when I padded the bytes 0x0093 through 0x00A9 in my nsf with 0xEA. I'm guessing that might be two way to skin the same cat? either way this is good progress. So now I'm unclear on whether you gentleman think that a curser will be doable or not. Well I guess technically I have a curser right now but it comes with glitchy tiles across the screen. Is there a reasonable coarse of action to get it working as intended? And also if that redrawing the screen idea is possible, will that eat more of my precious memory just for a curser?
Quote:
Nice. I found the sounddrv.h inside the MML Bundle, and changed it as you mentioned. It has the same result as when I padded the bytes 0x0093 through 0x00A9 in my nsf with 0xEA. I'm guessing that might be two way to skin the same cat?
Right. 0xEA makes the CPU do nothing for that instruction. So by replacing those bytes with 0xEA, the CPU is doing nothing instead of zeroing the RAM.
Removing the instructions from sounddrv.h just keeps them from being put in the NSF in the first place.
Quote:
So now I'm unclear on whether you gentleman think that a curser will be doable or not.
It's absolutely doable. A cursor on the background wouldn't use much memory. (Like... a byte or two because we need to keep track of where it is/was to draw/erase it.) Edit: Or... wait, if you mean ROM, it'll use some, but not a lot. Maybe less than 100 bytes?
The issue with sprites is the best way to draw them to the screen needs 256 contiguous bytes of RAM.
That said, someone still has to write you a thing. Which I guess I can do, but it obviously depends on the layout of your background being final which you said you were working on changing. Get that sorted, keep the distance between the songs the same and we'll probably be good.
Edit: Ah, two more things that may go without saying: 1. Leave actual ROOM for where you want the cursor. 2: Design the screen such that the same tile can be used to hide the cursor in all places you'd want it drawn. Maybe 2 isn't required, but it makes things easy.
... Actually, do you want to use only one single sprite? Because I have got a goofy solution for you, then.
1- Leave 256 bytes of all FFs somewhere in your ROM, aligned to some multiple of 256 bytes.
2- In your UpdateSprites routine, write the upper byte of that address to $4014 (where it right now says LDA #$05, STA $4014 replace the #$05 appropriately)
3- Afterwards, write the following values in order to $2004: Y, tile number, attributes (e.g. color), X
Unrelatedly, there's some place in the PPMCK where it uses addresses $10 and $11, as does vegaplay. You should probably change one or the other.
If you are referring the the graphic track names when you say keep the same distance between songs then I'm ok with how that is working. I found that
Code:
Line:
.db $37,$47,$57,$67,$77,$87,$97,$A7,$B7,$C7
are the locations of the curser on screen.
and that
Code:
sprites:
;vert tile attr horiz
.db $37, $2D, $00, $17 ; sprite
is the initial place that sprite is drawn. $37 is the screen location, $2D is the Tile used from bank 2 of the .chr and $17 is a horizontal shift.
What I'm concerned with fixing in terms of 'getting the curser working' is removing all the glitchyness from the screen. It seems to move in time with the music and scroll through every tile in bank 2 of the .chr. Attached is the current state of the .nes
lidnariq wrote:
... Actually, do you want to use only one single sprite? Because I have got a goofy solution for you, then.
1- Leave 256 bytes of all FFs somewhere in your ROM, aligned to some multiple of 256 bytes.
2- In your UpdateSprites routine, write the upper byte of that address to $4014 (where it right now says LDA #$05, STA $4014 replace the #$05 appropriately)
3- Afterwards, write the following values in order to $2004: Y, tile number, attributes (e.g. color), X
Unrelatedly, there's some place in the PPMCK where it uses addresses $10 and $11, as does vegaplay. You should probably change one or the other.
I indeed only need one sprite for the curser. I'm up for anything that works. and what line in the vegaplay.asm are refering for those addresses? and how do you know that PPMCK uses them too? are they in one of the .h or asm files inside the MML Bundle?
Code:
DrawScreen:
LDA #<pic ; load low byte of first picture
STA $10
LDA #>pic ; load high byte of first picture
STA $11
I think he's talking about that.
But that probably shouldn't be a problem, it's run only once before the music's own init routine. To be extra safe, one could zero them out after DrawScreen is run, though.
Code:
JSR DrawScreen ; draw initial nametable
lda #$00;Add this
sta $10;And this
sta $11;And this
Hacky, but eh. That's what this'll always be.
Quote:
and how do you know that PPMCK uses them too? are they in one of the .h or asm files inside the MML Bundle?
A really quick, (but not really failsafe) way to see what RAM is being used by your NSF is to run it in FCEUX. Debug, hex editor. Scan through 0x0000-0x07FF. Anything that's non zero is definitely being used, but things that are zero aren't necessarily free.
Ok so I'm sorta getting it now. Since I'm going to be filling my rom up with as much music as possible should I choose a location like $7900? I assume you are talking about locations in the .nes rom right? I looked at my .nes in hexedit and noticed the code for vegaplay looks like it starts way down at $7A10. So $7900 through $7A00 look free to me.
So if I understand you correctly I need to alter the asm to read
Code:
ClearSprites:
STA $500, x
INX
BNE ClearSprites
LDA #$00
STA $2003 ; set the low byte (00) of the RAM address
LDA #$79
STA $4014 ; set the high byte (05) of the RAM address
LoadSprites:
LDX #$00
LoadSpritesLoop:
LDA sprites, x ; load data from address
STA $7900, x ; store into RAM address
INX
CPX #4
BNE LoadSpritesLoop
RTS
instead of the way it was before with $500 in the LoadSprites SDA spot and in the ClearSprites LDA spot.
Where do I add the code for the $2004 register like you described? There is already a spot with those variables in the code that looks like
Code:
sprites:
;vert tile attr horiz
.db $37, $2D, $00, $18 ; sprite
Just simply changing what I have above doesn't do the trick I know there is more to what you told me, but I'm too new at this to know how to proceed.
Septr wrote:
What I'm concerned with fixing in terms of 'getting the cursor working' is removing all the glitchyness from the screen. It seems to move in time with the music and scroll through every tile in bank 2 of the .chr.
You're absolutely right; this is because your NSF is overwriting the bytes at $0500-$05FF , where vegaplay is storing its sprite memory.
Septr wrote:
What line in the vegaplay.asm are referring for those addresses? and how do you know that PPMCK uses them too? are they in one of the .h or asm files inside the MML Bundle?
What Kasumi said. I know PPMCK is using them too because I used
bisqwit's nescom's clever-disasm to automatically disassemble your .NES file, where I found two different places $10 was being used. I assume it's somewhere inside the MML bundle, but changing either is sufficient.
As far as what I was suggesting: I made the modifications and have attached them. To explain exactly what I did:
- I added a NES-2.0 compliant header (because why not)
- I removed the redundant clearing of memory at $0800 and $0900
- I increased the startup time to wait 2-3 vblanks instead of 1-2
- It no longer clears the picture on screen when it boots, because it uploads the actual picture immediately afterwards
- I made the sound initialization comply with what the NSF page says on nesdevwiki
- I moved the pointer that used $10 and $11 to something explicitly allocated at the top of the asm file
- I threw away the old sprites code and replaced it with my minimized one that takes advantage of the NES's design and avoids its bugs. (In short: The NES guarantees that the sprites pointer is 0 at the end of normal rendering. Actively changing the sprites pointer causes corruption, so I avoid it by using the above. We don't actually need to clear the entirety of sprite memory every vertical refresh as I suggested doing in my previous post, so now I do it only once)
- I shaved off 144 more bytes for your NSF.
I hope I haven't ruined your fun by doing it for you ...
I made the thing. (And lidnariq beat me to it AGAIN!!!!)
I guess alternates are always good...
Here is Vegaplay completely free of sprites and (hopefully) most other stuff that would cause incompatibility. Barely tested, though. Should support up to 10 songs without customization. Cursor tile is customizable.
If you want to change where it appears, edit cursornametablehi and cursornametablelo.
"How do I know what to put there?" Open your rom in FCEUX. Debug, nametable viewer. Move your mouse where you want to put the cursor. At the bottom right, you'll see PPU address. The first two characters go in cursornametablehi, the second two go in cursornametablelo.
I could make this slightly better (animated cursor wouldn't be too hard to do at least), but who knows if I ever will. Enjoy.
Quote:
Since I'm going to be filling my rom up with as much music as possible should I choose a location like $7900?
That's not a valid place to start a ROM. Don't aim to use more than you have. $8000 through $FFF9 minus the bytes vegaplay uses.
Edit: Also, if you want more than say... 23 songs, this probably has to be modified to scroll. (I say 23, not 30 to make some room for title graphics/safe area).
Edit2: Silly me, uploaded a broken file. Tried to move something to make it easier to edit, not realizing of course it wouldn't assemble.
Edit3: Fixed wrong cursor offsets for later songs. Whoops. I wasn't kidding when I said barely tested.
lidnariq wrote:
I hope I haven't ruined your fun by doing it for you ...
No fun ruined here. You've only allowed my fun to actually continue. I enjoy making music and modding hardware. I start cracking my head open when I have to start programming or debugging in a difficult and foreign language such as NES assembly. I can't thank you guys enough. You guys are all diamonds.
Do either of you foresee any conflicts that might arise from using most of the memory when I'm nearing completion of the album? I know I can only go so far with it, but will it stop me with the same issue somewhere like half way though my work or can I get pretty much most out of this configuration? And also if I do run into some issues down the line could I message either of you guys for more help?
No, I don't
foresee any issues, but I really make no guarantees. (Like the broken files I uploaded the first two times.
Fixed now!) If it's any consolation, I just tried mine with a 16 KB NSF, which was the largest I have around that's not also too large for NROM (greater than 32KB). Worked fine.
Sure, you can message me or just post here where lidnariq will beat me in the race!
Kasumi wrote:
Sure, you can message me or just post here where lidnariq will beat me in the race!
I'm not going to lie. I had quite the chuckle witnessing how close both of you were to replying on two occasions. XD
And yeah, I'm only using an NROM-256 along with a 27C256 EPROM so I'm assuming things with go smoothly in regards to the hardware side of things.
Yeah, I think both Kasumi's and my implementation should work.
If you ever do want the cursor to be animated, rather than snapping from tile to tile, you'll need to start with my version. Other than that, both should work fine.
Cool. maybe you can point me in the right direction so some material to read so I can try and figure it out. Now are we taking about only animating the screen location, or can I cycle through a tile or two for proper animation?
I had actually already been trying to modified your version to put the cursing is more custom locations.
Code:
UpdateSprites:
;; in NMI, assuming rendering is just finished
;; naturally-- can write 7 bytes to $2004
LDX SongNumber
LDA Virtical,x ; Y
STA $2004
lda #$2B ; tile #
sta $2004
lda #0 ; attrib (e.g. palette)
sta $2004
lda Horizontal,x ; X
sta $2004
RTS
;;; ----------------------------------------------------
Virtical:
.db $77,$87,$97
Horizontal:
.db $2F,17,2F
Though when I tried setting a jump location like that for the tile spot I got errors. I'm gessing is doesn't work the same. if it's possible for animations I would be cheating myself if I didn't try to get that implemented as well
Quote:
Now are we taking about only animating the screen location, or can I cycle through a tile or two for proper animation?
Animating screen location (by say... smoothly sliding the cursor between two songs when one ends, rather than have it warp down) is only possible with sprites.
Having the cursor animate by changing tiles is easy for either method, but really you kinda have to learn a lot about the NES and 6502 programming to do it. If you eventually want to make homebrew games, try reading some of this:
http://nintendoage.com/pub/faq/NA/nerdy_nights_out.html If all you want is just this done, one of us may as well do it for you since it'll take like two seconds as opposed to like... the minimum couple weeks you'll have to spend learning to accomplish the one task.
I could make mine customizably animated later tonight, but I'm about to go out to dinner.
You can use tile-cycling animations using either his or mine.
Moving around not on multiples of 8 pixels, you'll have to use mine.
Color changes are a fuzzy case; if you're only using a single color and just want it to change you can probably instead change the color in the palette and use his or mine. If you want the cursor to have more colors than the current one color, you'll probably need to use mine (the NES requires that every 16x16 pixel block in the background use the same set of three colors)
You failed to put $s before your hexadecimal numbers, there; otherwise it seems to work.
(Also, you'll want those tables to be as long as the number of songs you have, and for the two lines later in the file: CMP #10 ; equal to total # of songs +1, starting from 0 and LDA #9 ; equal to total # of songs, starting from 0 to match that number also)
Kasumi wrote:
If all you want is just this done, one of us may as well do it for you since it'll take like two seconds as opposed to like... the minimum couple weeks you'll have to spend learning to accomplish the one task.
I could make mine customizably animated later tonight, but I'm about to go out to dinner.
That would be wonderful. I just didn't know how far I could politely go in terms of asking for it to be done for me. Cause as I said before I'm a complete novice. If either of you could add animated sprites that allow me to designate which and how many tiles are used that would be awesome. And a smoother transition like what you are describing lidnariq would be very useful as well. lol Both would be freakin' ace! I don't need color changing. But I do need to have multi color curser. I'm using these that I mocked up for my current tests. And I'm also only currently using 4 colors total for the entirety of the graphics.
lidnariq wrote:
You failed to put $s before your hexadecimal numbers, there; otherwise it seems to work.
Oopsie. I had it correct during testing, but just quickly typed it back in when trying to show you guys.
Septr wrote:
If either of you could add animated sprites that allow me to designate which and how many tiles are used that would be awesome.
Just a simple flipbook that goes continuously? Or do you want it to be part of the transition animation? Or something else?
Here's one that allows you to customize the cursor animation. To change the animation, set the length with NumberOfFrames, then add/subtract bytes from cursoranimation as needed. All frames will show up for the same amount of time (CursorDelay). If you want variable delays, find the least common multiple of the delays you want and double up tiles as needed.
That's about as far as I go, unless I broke it again somehow. The more things you want, the harder it is to make customizable anyhow.
lidnariq wrote:
Septr wrote:
If either of you could add animated sprites that allow me to designate which and how many tiles are used that would be awesome.
Just a simple flipbook that goes continuously? Or do you want it to be part of the transition animation? Or something else?
Yeah just like a single loop. I will probably be building some frames to make the curser look like its rotating or bouncing (all within the 8x8 tile of course.) So I could make like three or four tiles of curser animation and it will loop continuously. and if it's is possible maybe like a smooth transition to the next location whenever changing songs (like tweening)
I'm downloading your new version now, Kasumi.
Edit: I tried out you code Kasumi and I noticed that you changed the chr page that the curser used to the same one the background uses. Was that on purpose? I used to put all my curser graphics in page 2 but now it's scrolling though tiles from my background. My preference would be to have the cursers on there own chr page, cause I want as many tiles as I can manage for my back ground graphics. I know it'll only be like 3-4 tiles lost but I could very easily be needing those tiles later on with the plans I have.
Quote:
Edit: I tried out you code Kasumi and I noticed that you changed the chr page that the curser used to the same one the background uses. Was that on purpose?
Um, yeah. Like I said, it's Vegaplay completely free of sprites. I thought it was implied that the background tiles were now being used.
Quote:
My preference would be to have the cursers on there own chr page, cause I want as many tiles as I can manage for my back ground graphics.
Then use lidnariq's. I could maybe mess with his, but honestly I'm pretty sure you could condense four or however many tiles you need for the cursor if you end up with exactly 256 for your background. In fact, I bet the time it'd take you to do so would be less than the time it'd take me to change this. And it is your project!
ok. I'll do some squeezing in graphically. I know it's not your project and I'm gratefull for all you've already done. You just seemed to be ok with continuing with what I was asking. I'm not trying to be impolite. I'll take what's here and run with it if you are content with stopping here. Again thank you. You are a gentleman and scholar.
I spent too much time worrying about how to to it the right way such that I completely dropped it. Bleh.
Anyway, I just cribbed Kasumi's animation code and stuck it in mine, so you can have an animated cursor but no transition animations. I added the ability to move the sprite at the same time as the tile changes.
If you want to use an 8x16 sprite, you can enable that too-- I added a comment about it, just search for "8x16". (Be careful: if you do, the tile numbers get a little weird. Even numbers are from first half of the tiles, odd from the last half.)
I'm trying to compile but I get an error cause of line 376. What does this line do anyway?
Code:
.incbin "vegaplay.nes.chr"
I'm assuming it is loading the .chr file? Because I changed it to "geo.chr" and things seem to work, but I wanted to ask anyway just incase it's something else.
I really like the addition AnimationH and V. I could use them to make the curser bounce or orbit slightly. Real cool!
Your assumption is exactly correct.
I didn't see in the original version how you added the chr to the end, so I added that line (and forgot to mention it) rather than having to manually append it.
Have fun!
lidnariq wrote:
Have fun!
Thank you!