Are stacks uses to save to memory? ie. Zelda ,all your potions and money will save when you move from mapper to mapper(level to level). Up to how many stacks can you have? What other Registers can do this?
How many mappers can you use?
Thanks in Advance,
EL
Okay. First, there is only one stack, from $100-$1FF. RAM ranges from $0-$7FF. $100 bytes are used for the stack, which holds the adresses when you do a JSR. The stack is usually something you want to stay away from, if you're just saving bytes. Zero Page can be used for many things, like jumping to an address depending on the values in Zero Page. Zero Page is the RAM ranging from $0-$100, if you don't know. And $100 bytes somewhere else are almost always used for sprites.
And you say something about different "mappers"? You mean like game maps, or like mappers, like MMC1 and stuff? Because there can only be 1 mapper per game. And You just save stuff like how many potions you have and stuff in RAM/SRAM. Zelda has SRAM which is RAM ranging from $6000-$7FFF that is backed up by a battery, so when you shut the game off, it will be saved. Does that help at all?
Can you use all 6502 assembly parameters for the NES? Ive been reading the Rod Zackys 6502 book and it mentions using more than one stacks for memory addressing. Like Push, pull, and pop.
Also how can i move from screen to screen, meaning nametables to nametables? I want to be able to use the save function to access the saved parameters on another screen.
I had always though of mappers as a section of your code that does one thing like playing level one and then when yhour done with that level it maps to level two with a whole differnet set of parameters, nametables, palettes, etc....
ie, Super mario Brothers 3 when your done defeating one level another level is opened up, but eventually when you beat all the levels in the world you can move up and down to access what ever level you want in the world.
Do mappers do this? What can do this?
nineTENdo wrote:
Can you use all 6502 assembly parameters for the NES? Ive been reading the Rod Zackys 6502 book and it mentions using more than one stacks for memory addressing. Like Push, pull, and pop.
The stack is used to hold return addresses (handled by the processor itself) and to store smal temp data, such as parameters to functions. I really don't know what Rod Zacky is talking about. Maybe you missunderstood him somehow? No offense, but you don't seem to know what these terms (stack, mapper and register) mean.
Quote:
Also how can i move from screen to screen, meaning nametables to nametables? I want to be able to use the save function to access the saved parameters on another screen.
Memory contents are by no means attached to a screen. The program you make controls the memory, as well as the screen. It can change one, the other, both or none of them, depending on what you code.
When you say "move from screen to screen", do you mean scrolling? If yes, don't worry about that yet. If you just mean "change the screen contents with no animation", then you could just draw the new contents to the other name table (the one not beeing displayed) during VBlank and when you are over, set it as the displayed one. Or you could turn rendering off, draw over the same screen and turn rendering on again.
nineTENdo wrote:
Can you use all 6502 assembly parameters for the NES?
Everything of the 6502 except decimal mode works on the NES.
Quote:
Also how can i move from screen to screen, meaning nametables to nametables?
To write to nametables, load an address in $2006 and then load data in $2007. To scroll to the top-left corner at (x, y), write the coordinates mod (256, 240) to $2005 and the coordinates divided by (256, 240) to $2000. See
"NES PPU" on nesdevWiki for more info.
Quote:
I want to be able to use the save function to access the saved parameters on another screen.
Potions, money, and the like are stored in variables. Your assembler should put variables in either internal RAM ($0000-$07FF) or external RAM ($6000-$7FFF) (if your cart has it).
Quote:
I had always though of mappers as a section of your code that does one thing like playing level one and then when yhour done with that level it maps to level two with a whole differnet set of parameters, nametables, palettes, etc....
All a mapper does is manipulate the upper lines of the address, which has the effect of separating PRG and CHR ROM into "banks" that the CPU can load into addressable memory. See
"Bank switching" on Wikipedia.
Quote:
ie, Super mario Brothers 3 when your done defeating one level another level is opened up, but eventually when you beat all the levels in the world you can move up and down to access what ever level you want in the world.
The only thing a mapper would have to do with this is that some games may store one level's map or a few levels' maps in each PRG bank, and whenever the program wants to read the data for a given level, it will switch to the PRG bank containing the data for that level. Or if a game uses CHR ROM, each level's unique tiles will be stored in a separate CHR bank.
Don't bite off more than you can chew. Before you worry about mappers and scrolling, I suggest you make some stationary demos. You still have a lot of the basics to learn before you'll be able to really take advantage of mappers and have a scrolling screen.
It is possible to change the stack pointer (using TXS, TSX) to split up your stack into two of more smaller stacks, but that's sort of a pain.
You can also simulate a stack on your own without using the actual 6502 stack:
Code:
somecode:
lda #$20
jsr push_a ; push a to simulated stack
lda #$10 ; change a
jsr pull_a ; pull a back from stack
; A is now $20 again
rts
push_a:
ldx stack_pointer ; keep the stack pointer in RAM somewhere
sta stack,x
dec stack_pointer
rts
pull_a:
inc stack_pointer
ldx stack_pointer
lda stack,x
rts
But I doubt you'd have much use for this in your program.
Mappers are nothing like what you describe. Games change their nametables and pattern tables by updating the PPU with new info (writing to $2007). It has nothing to do with the mapper used.
tokumaru wrote:
When you say "move from screen to screen", do you mean scrolling?
Nope, scrolling would be done in the level im in.
Quote:
ie, Super mario Brothers 3 when your done defeating one level another level is opened up, but eventually when you beat all the levels in the world you can move up and down to access what ever level you want in the world.
im guessing if its not mappers that do this than it is done with a jmp routine wiht a whole differnt set of nametables and paltetes..etc?
Super Mario Bros. 3 keeps a list of which level numbers have been beaten so that the player can move past them.
On the NES at least, there is only 1 stack. You are asking little questions that take a lot of time to explain. Like Scrolling from one name table to another is up to you about how you want to scroll, all I can tell you is that you store the scroll by writing to $2005 twice. So If I wrote this:
lda #2
sta $2005
lda #6
sta $2005
The picture on screen would be two pixels down, and 6 over from the corner pixel on the nametable. And There are 4 nametables, 2x2 screens. So you'll have to update them as you go, which can be a pain. These are things that can't just be explained simply. I don't know how to explain all this without taking up a whole page.
I'm sorry, but you should understand the 6502 completely before you are asking these questions. If you go to the main page, you can find "Assembly in one step", which is really good. I made the mistake of trying to program the NES without knowing the 6502, and it was not a good plan. I was asking all sorts of questions like this, making a thread be like 4 or 5 pages. If I would have understood the 6502, I probably would have had those threads be like 1 or 2 pages, and have like half the threads even present. I know you probably hate to hear it, but you should really do that. Read 6502 documents till you completely understand everything.
I mean, make tech demos for the NES and practice using the 6502, but do not by any means try and make a game without knowing the language. When I wanted to program the NES last year, I didn't even know what a byte, or bit was. And I didn't know that you could make NES games. So, learning the 6502 can't be that hard, if you are starting out on a higher level than that. And when I first saw the JMP command, I thought it was like Jump, and in mario jumps. Like, the make mario jump command. I laugh looking back thinking how far I've come. I'm rambling, I'll stop.
Well basically i want to display graphics (1 nametable). and use a sprite as a NEXT button to switch to whole differnt set of graphics ( another nametable). Kinda like on Zelda when he enters a cave. Is that a sprite (the black entrance of the cave) that switches to inside a cave.
I know i dont know much about the 6502 yet im just hoping there are easy answers to these questions or just a hint to what opcode to study to do what needs to be done. But even that theres no harm in asking.
nineTENdo wrote:
Well basically i want to display graphics (1 nametable). and use a sprite as a NEXT button to switch to whole differnt set of graphics ( another nametable). Kinda like on Zelda when [Link] enters a cave. Is that a sprite (the black entrance of the cave) that switches to inside a cave.
It's a floor tile, and stepping on that tile causes the game to load a different map.
without more understanding of 6502 assembly the explanations that would be given would be very deteailed (in order to fill in what you dont know). these examples would only teach you how to do that one thing.
with more understanding we could teach you an idea with some code involved and a shorter explanation. this idea could be taken and modified to do what you need it to.
nineTENdo wrote:
a hint to what opcode to study to do what needs to be done.
It's no specific opcode -- each instruction/opcode only does a very small, generic task. Actually doing something involves working with the right combination of several opcodes -- each doing a small part of a larger job.
Quote:
im just hoping there are easy answers to these questions
I think you'll find that once you have more of a grasp on programming fundamentals and understand 6502 a little more, you'll be able to answer these questions yourself. It's not that the answers to these questions are difficult -- it's just that they require some existing understanding of NES operations.
tepples wrote:
It's a floor tile, and stepping on that tile causes the game to load a different map.
So i cant use sprites as buttons. I want to able to make back and forward buttons. the code i can figure out . i just need to know if it can be done. Another example is like when Mario hits on a ? box and a mushroom pops out or when he stomps on a goomba( i know there are two different sprites used for this).
nineTENdo wrote:
i just need to know if it can be done.
Sprites and background are just graphical aspects of a program. The NES does not know what a button is, wich means you'll have to program one. Since you're in charge, you can build a button out of whatever you want. As long as you respect the hardware's limits, of course (no more than 8 sprites on a scanline, for example).
Just drop the idea that these things (sprites, mapper, name tables) are actually attached to any object concepts. A game is just an illusion, created by clever handling of the system's graphical features. Logic manipulates the graphics to simulate something. A sprite, from the programmers point of view, is not a character, an item or an object, it's a 8x8 pixels square (or 8x16 pixels rectangle) that overlaps the background. These can be used for many things, including representing characters, items and objects, but only because the programmer made that happen.
The SNES can vary stack pages with its 16-bit stack pointer. I'm unsure why it would be very usefull, but it can.
I think most newbies get totally lost on the fact that the "technical" side of a game (game engine) and the "design" side of a game (items, characters, gameplay) are absolutely unrelated.
The game engine is a bunch of code that allow the console to take data from its ROM, and from the joypads, and the programm will happen to output the thing you want on the screen and audio speakers. How it is done is the game engine, the technical side of the game, and what appears on the screen in the player point of view are the design side of the game. Both are unrelated.
tepples wrote:
Everything of the 6502 except decimal mode works on the NES.
What do you mean decimal mode?
nineTENdo wrote:
What do you mean decimal mode?
The 6502 has a mode where arithmetic operations (addition and subtraction) are performed in decimal, rather than binary/hex.
In hex, adding 05 to 05 will result in 0A. In decimal mode, it will result in 10, using 4 bits to represent each digit. This is called BCD (Binary Coded Decimal).
It's a shame the NES doesn't have that, it would be very usefull to handle values that must be displayed to the player.
tokumaru wrote:
It's a shame the NES doesn't have that, it would be very usefull to handle values that must be displayed to the player.
I like it actually !! It add challenge when writing RPGs, forcing you to write routines to convert from hex to decimal, also it would be tough to make sure to not have any errors when doing calculation with decimal variables, including multi-byte addition and sustration, and for RPGs possibly multiplications, etc...
Bregalad wrote:
I think most newbies get totally lost on the fact that the "technical" side of a game (game engine) and the "design" side of a game (items, characters, gameplay) are absolutely unrelated.
To Bregalad's comment, I would add that if you want to learn how to be a programmer, writing NES games may not be the easiest place to start. You need to develop quite a range of skills--you need low-level skills, such as a good understanding of 6502 assembly and you need NES-specific skills and knowledge (such as understanding how the PPU works) and you need some skill at high-level design and coding (in other words--you might want to learn some other languages first such as C, C++ or Java, and learn how the high-level concepts from those languages relate to the low-level workings of a processor such as a 6502).
Like many other complicated subjects,
mastering programming takes about ten years. As a professional programmer with over 10 years experience, I can attest to the truth of this.
Of course its never too soon to start learning, and the best way to learn is by doing. We only grow by challenging ourselves.
Bregalad wrote:
It add challenge when writing RPGs, forcing you to write routines to convert from hex to decimal
Which is not that hard. Drop
this subroutine into your code to convert a 16-bit unsigned integer to a decimal string.
mozz wrote:
You need to develop quite a range of skills--you need low-level skills, such as a good understanding of 6502 assembly and you need NES-specific skills and knowledge (such as understanding how the PPU works) and you need some skill at high-level design and coding (in other words--you might want to learn some other languages first such as C, C++ or Java, and learn how the high-level concepts from those languages relate to the low-level workings of a processor such as a 6502).
The only language I knew before I started 6502 assembly was Visual Basic and Basic on my C64 (wich is somewhat similar).
Quote:
Like many other complicated subjects, mastering programming takes about ten years. As a professional programmer with over 10 years experience, I can attest to the truth of this. Cool
As an ammateur programmer with about 4 years of experience, I think I can be quite close as "mastering" programming (while I'm still not totally "mastering" it, depending of the definition you give to that word).
I think from one to two years is enough to be able to make good programs easily from scratch.
tepples wrote:
Drop
this subroutine into your code to convert a 16-bit unsigned integer to a decimal string.
I'm usually quite against "dropping a subroutine", specially if you don't understand how it works. Unfortunatelly I still did not understand this one... O.o
I guess I'll remain using the one I made for now, even though it is a bit slower.
Bregalad wrote:
I think from one to two years is enough to be able to make good programs easily from scratch.
Not impossible, but that can vary a lot from person to person. It took me more than that to learn how to make a decent game. Of course, I learned to program in QBasic, when I was a stupid kid and before there was the internet, it was just harder then.
Bregalad wrote:
As an ammateur programmer with about 4 years of experience, I think I can be quite close as "mastering" programming (while I'm still not totally "mastering" it, depending of the definition you give to that word).
I think from one to two years is enough to be able to make good programs easily from scratch.
Absolutely. You don't need to be an expert at all aspects of programming in order to write good programs, and programmers of all skill levels are going to have some areas they are very familiar with and other areas they are less experienced with. I don't mean to discourage anyone, either--anyone with the determination to stick with it will be able to learn the necessary skills and be successful. (What was that famous Thomas Edison quote? Something about 1% inspiration and 99% perspiration.
)
Bregalad, I'm almost sure you know more about the specific workings of the NES than I do. I'm trying to write code generators to generate simulation cores for the 6502 (and other processors) but I myself have never written assembly language programs for the 6502. Which is a skill I would definitely have to develop if I wanted to write NES games rather than emulators.
Everyone should dream big and chase their dream. That way lies greatness. At the same time, most skills worth learning take a lot of time to learn, and most things worth building take a lot of skill and experience to build. But you've got to start somewhere. Its good to start with things that are really interesting, so you will have the motivation to keep working on them.
tokumaru wrote:
tepples wrote:
Drop
this subroutine into your code to convert a 16-bit unsigned integer to a decimal string.
I'm usually quite against "dropping a subroutine", specially if you don't understand how it works. Unfortunatelly I still did not understand this one... O.o
Yeah, I don't understand it either. I use Wla-Dx, and I really like to use hardcore 6502, and not really stuff that looks like C/C++, like the first or second line of that routine. I was trying to think of a relationship between binary and decimal numbers, but I couldn't come up with one. And I was thinking about Tokumaru's idea, and it's pretty interesting. I don't know how you came up with it though. Tokumaru, if you were to do a 24 bit BDC with your routine, would it require alot of changing?
EDIT: Well, I just turned your routine into a 24 bit conversion! Looky here:
www.freewebs.com/the_bott/toksroutine.asm .
Celius wrote:
Yeah, I don't understand it either. I use Wla-Dx, and I really like to use hardcore 6502, and not really stuff that looks like C/C++, like the first or second line of that routine.
I don't know how to use those either. They seem usefull, though.
Quote:
I was trying to think of a relationship between binary and decimal numbers, but I couldn't come up with one. And I was thinking about Tokumaru's idea, and it's pretty interesting. I don't know how you came up with it though.
I didn't come up with it, I read the theory somewhere. It took me like a week to figure out what they meant, then I implemented it.
Quote:
Tokumaru, if you were to do a 24 bit BDC with your routine, would it require alot of changing?
EDIT: Well, I just turned your routine into a 24 bit conversion! Looky here:
www.freewebs.com/the_bott/toksroutine.asm .
Did you time it? It would seem to me that every digit you add would slow it down quite a deal...
I don't know, it'd probably be like 8/5ths faster than the original, because there are 5 digits in the original, and 8 in the 24 bit one. I'm just roughly estimating. It's around there, I bet. What do you think? I mean, let's just face the facts, there is really no lightning fast way to do this. There is much to be done to a binary number to make it output it's decimal equivelant, so I think it's all pretty fast for what it has to do. And for games like Final Fantasy, they wait more than a few frames to load their screens with numbers on them that have been converted from binary, and do you really notice the wait? This is pretty good speed, I think.
EDIT: Sorry, I meant it takes 5/8ths as long as the original, not it's 5/8th's faster! Sorry!
tokumaru wrote:
tepples wrote:
Drop
this subroutine into your code to convert a 16-bit unsigned integer to a decimal string.
I'm usually quite against "dropping a subroutine", specially if you don't understand how it works. Unfortunatelly I still did not understand this one... O.o
Do you understand how long division works in binary? If you try to explain that, I can word how my subroutine works in terms of your explanation of division.
You align the divisor and the dividend (to the left). Then you subtract the divisor from the divdend, if the subtraction was successfull, put a 1 in the quotient, if not, put a 0. Shift the divisor right and subtract again until the end.
This was pretty quick from the top of my head, is it possible to build an explanation around that?
Have to go now, bye.
tokumaru wrote:
You align the divisor and the dividend (to the left). Then you subtract the divisor from the divdend, if the subtraction was successfull, put a 1 in the quotient, if not, put a 0. Shift the divisor right and subtract again until the end.
So normally, to divide a number less than 15744 by 123, you'd set the divisor to 7872, 3936, 1968, 984, 492, 246, 123.
My BCD subroutine's algorithm works like division, except it uses a constant set of divisors: 40000, 20000, 10000, 8000, 4000, 2000, 1000, 800, 400, 200, 100, 80, 40, 20, 10, 8, 4, 2, 1. Work it out on paper a few times.
Hmm, what do you think is the hardest routine to come up with? The hardest I've encountered is this one, definitely. Another one that took me a while, even though it's not hard at all compared to this, was a routine that would take a sequence of tiles and make it into a 16 byte array. It's on
this graphics editor that I made. One routine takes the 16 byte array that makes the tile and turns it into a sequence of tiles. That wasn't as hard as taking the tiles, and turning them into a 16 byte array. Do you know what I'm saying? If not, use the graphics editor, and you'll get an idea of what I'm talking about.
I coded a routine to convert a 256-byte array into 4 16-byte tiles and output them to the pattern tables. Are you talking about something like that?
I needed this because my decompression routine did a 16x16-pixel square at a time using 8 bits per pixel, for easy indexing. When the square was ready, it had to be converted and exported as 4 individual tiles, with separated planes and all the shit a NES expects.
Celius, I think your program is interesting. I'll leave some comments on it's thread.
Yes, that is what I'm talking about. I had the tile numbers arranged in RAM, and I had to put them into a 16 byte array, and put it in the pattern tables.