Hello World

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

User avatar
FinalZero
Posts: 152
Joined: Thu Dec 03, 2009 7:27 am
Contact:

Post by FinalZero »

This .proc might confuse you. But it's just a way to hide the labels defined inside the .proc from view outside the .proc, so that multiple subroutines can share the same names for internal labels. For example, the symbol inside wait4vbl ends up called wait4vbl::loop, and other subroutines won't be defining symbols that start with "wait4vbl::".
Doesn't ca65 have nameless labels though? Isn't the syntax something like "beq +" or something?
Edit: it's "beq :+". Also, there's local labels, which start with '@'.
In what other language or for what other platform have you made a video game? Perhaps I could help explain things with analogies to that platform.
I didn't mean video games, I meant programming/data structures in general. I've made plenty of programs, though I suppose that the only "game" I've made is a room-to-room text adventure sort of thing.
Last edited by FinalZero on Sun Dec 04, 2011 11:02 pm, edited 1 time in total.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

FinalZero wrote:I'm not sure that a description of the structure would confuse me. I'm quite a bit more experienced than some kiddie programmer.
I didn't mean it in the sense that you wouldn't understand the explanations, it's just that everyone does things differently, so you could be overwhelmed by all the possibilities. Also, solving these kinds of problems is part of the learning experience, and through trial and error you'll find what works best for you.

I'm pretty sure that passing parameters through the stack is not very common on the 6502, because having to work around the return address is not very efficient. But if you feel comfortable using the stack that way, there's no reason for you not to.
What tile editor do you recommend?
I don't recommend any. All tile editors I know of are just trying to reinvent the wheel and poorly implementing drawing features that already exist in much better drawing programs. Like tepples, I like to draw sprites in an actual drawing program (I use both MS Paint and GIMP) and just convert them to the NES format when done.
User avatar
FinalZero
Posts: 152
Joined: Thu Dec 03, 2009 7:27 am
Contact:

Post by FinalZero »

I'm pretty sure that passing parameters through the stack is not very common on the 6502, because having to work around the return address is not very efficient. But if you feel comfortable using the stack that way, there's no reason for you not to.
I'm not using *the* stack (the one at $100 to $1FF), I'm using a stack structure on the zero page, with the x register as the index of the current empty spot. One can then use the zeropage, x addressing mode (always as 0, x) to retrieve and do things with the values.
I just use GIMP to make my tile sheets and then run a Python program to convert .png to .chr.
I don't recommend any. All tile editors I know of are just trying to reinvent the wheel and poorly implementing drawing features that already exist in much better drawing programs. Like tepples, I like to draw sprites in an actual drawing program (I use both MS Paint and GIMP) and just convert them to the NES format when done.
To be honest, I've never used GIMP extensively. I use mspaint or Paint.Net most of the time. Is there a common program that can convert an image to .chr format?

* * *

Edit: So, I've implemented adding the "nmis" code to my code, but it doesn't seem to fix anything. My code still gets stuck going between places and not adding/subtracting stuff. It seems to be stuck in this:

Code: Select all

loop: 
  cmp nmis 
  beq loop 
Ideas?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

FinalZero wrote:Is there a common program that can convert an image to .chr format?
There are several. My build environment uses a lot of Python programs, so I wrote my own. It's in the Concentration Room source code archive.

Code: Select all

loop: 
  cmp nmis 
  beq loop 
Ideas?
What have you written to PPUCTRL ($2000)? You could try putting a breakpoint on the NMI handler to make sure it gets called.
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

FinalZero wrote:To be honest, I've never used GIMP extensively. I use mspaint or Paint.Net most of the time. Is there a common program that can convert an image to .chr format?
YY-CHR lets you paste images from the clipboard (up to 128x128), and it is converted to CHR data immediately on paste. It works best if the image is in indexed color format, so make sure your paint program lets you specify it. Photoimpact is really good for this task, since it lets you do color reduction and re-ordering the palette the way you want to, I'm not as experienced with other paint programs. Truecolor images often get mangled when pasting into YY-CHR, because it can't match the colors to an index correctly.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
FinalZero
Posts: 152
Joined: Thu Dec 03, 2009 7:27 am
Contact:

Post by FinalZero »

There are several. My build environment uses a lot of Python programs, so I wrote my own. It's in the Concentration Room source code archive.
Okay, thanks.
What have you written to PPUCTRL ($2000)? You could try putting a breakpoint on the NMI handler to make sure it gets called.
I'm not writing anything there. =/
YY-CHR lets you paste images from the clipboard (up to 128x128), and it is converted to CHR data immediately on paste. It works best if the image is in indexed color format, so make sure your paint program lets you specify it. Photoimpact is really good for this task, since it lets you do color reduction and re-ordering the palette the way you want to, I'm not as experienced with other paint programs. Truecolor images often get mangled when pasting into YY-CHR, because it can't match the colors to an index correctly.
Okay, thank you.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

FinalZero wrote:
What have you written to PPUCTRL ($2000)? You could try putting a breakpoint on the NMI handler to make sure it gets called.
I'm not writing anything there. =/
Your NMI couting code is useless if you are not initializing $2000. Initializing the PPU by writing to $2000 and $2001 at least once is a mandatory thing for NES programs.
User avatar
FinalZero
Posts: 152
Joined: Thu Dec 03, 2009 7:27 am
Contact:

Post by FinalZero »

tokumaru wrote:
FinalZero wrote:
What have you written to PPUCTRL ($2000)? You could try putting a breakpoint on the NMI handler to make sure it gets called.
I'm not writing anything there. =/
Your NMI couting code is useless if you are not initializing $2000. Initializing the PPU by writing to $2000 and $2001 at least once is a mandatory thing for NES programs.
I'm doing something wrong. The wiki pages aren't very helpful either.
http://wiki.nesdev.com/w/index.php/PPU_power_up_state
http://wiki.nesdev.com/w/index.php/Init_code

My code:

Code: Select all

.proc reset
	; Clears the flags.
	clc
	cli ; sei
	clv
	
	; Sets the stack pointer.
	ldx #$FF
	txs
	stx PPU_CONTROL
	stx PPU_MASK
	
	jmp main

Code: Select all

.proc main
	jsr read_input
	jsr vert_blank
	jsr write_video
	jsr write_audio
	
	jmp main
.endproc
.endproc
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

You're supposed to use SEI on start up, not CLI. CLI allows interrupts to happen, and you don't want that during initialization. After initializing everything, you should only enable interrupts (CLI) if you actually use them.

You're supposed to write $00 to the PPU registers, not $FF. Also, you have to give the PPU some time to warm up (2 frames is enough). Usually we poll the VBlank flag in $2002 for this (actually this is the only time when using $2002 to wait for VBlank is acceptable). After the warm up you can configure the PPU as you wish (this is when you enable NMIs). If you don't let the PPU warm up, it behaves erratically.
User avatar
FinalZero
Posts: 152
Joined: Thu Dec 03, 2009 7:27 am
Contact:

Post by FinalZero »

You're supposed to use SEI on start up, not CLI. CLI allows interrupts to happen, and you don't want that during initialization. After initializing everything, you should only enable interrupts (CLI) if you actually use them.
What do you mean "if you actually use them"? I thought I just read that they're used to draw to the screen.
You're supposed to write $00 to the PPU registers, not $FF. Also, you have to give the PPU some time to warm up (2 frames is enough).
How long is a "frame"?
Usually we poll the VBlank flag in $2002 for this (actually this is the only time when using $2002 to wait for VBlank is acceptable). After the warm up you can configure the PPU as you wish (this is when you enable NMIs). If you don't let the PPU warm up, it behaves erratically.
What does "poll" mean?
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 521
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Post by Jarhmander »

FinalZero wrote:
You're supposed to use SEI on start up, not CLI. CLI allows interrupts to happen, and you don't want that during initialization. After initializing everything, you should only enable interrupts (CLI) if you actually use them.
What do you mean "if you actually use them"? I thought I just read that they're used to draw to the screen.
I think you're confusing things, but it's normal.
NMIs are very simmilar to IRQs, but on the NES it is specifically wired to the PPU and, when activated, fires when VBLank begins, basically. Code at the NMI vector is then executed, and then you can update the tiles, sprites and other stuff (or just set a flag, sometimes).
IRQs are often mapper-specific (we exclude here DMC and frame IRQs which come from the APU part of the 2A03). In a 4-way scrolling game (ex:Super Mario Bros. 3), IRQs (from the MMC3 mapper) are used to set the scroll somewhere within a frame, so to perform a 4-way scrolling effect, to give an example.
So as you can see, NMIs and IRQs look similar but they're differents things. And I can expect that other members will emphatize the difference between IRQs and NMIs :)
FinalZero wrote:
You're supposed to write $00 to the PPU registers, not $FF. Also, you have to give the PPU some time to warm up (2 frames is enough).
How long is a "frame"?
Approximatively 1/60 seconds (NTSC) or 1/50 (PAL), which is the time a frame appears on your TV. Assume your TV displays 60 frames per sec. on a NTSC system.
FinalZero wrote:
Usually we poll the VBlank flag in $2002 for this (actually this is the only time when using $2002 to wait for VBlank is acceptable). After the warm up you can configure the PPU as you wish (this is when you enable NMIs). If you don't let the PPU warm up, it behaves erratically.
What does "poll" mean?
It means basically to simply look at a [software/hardware] flag/condition, normally periodically. You can see "by polling" the alternative of "by interrupts". Normally, "by interrupts" is better, but because, at power on, the PPU isn't reliable, it's better to "poll" the state of the VBlank flag.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

I know ~J-@D!~ answered already, but I too want to give it a go.
FinalZero wrote:What do you mean "if you actually use them"? I thought I just read that they're used to draw to the screen.
NMIs are different from IRQs. NMIs are the ones that fire when VBlank starts and allows you to sync the rogram to the refresh rate, IRQs are used for things like raster effects (IRQs generated by mappers) and detecting when DPCM samples have finished playing. Many games (specially the ones with mappers older than the MMC3) don't use IRQs at all.
How long is a "frame"?
In this context, it doesn't matter.
What does "poll" mean?
It means you constantly read a register until the returned value changes. In the case of $2002, the most significant bit tells you when VBlank starts, so you can read it in a loop and wait for the N flag (which is a copy of bit 7) to be set, like this:

Code: Select all

Wait:
	lda $2002
	bpl Wait
While the flag is clear, you keep waiting. Do that twice and you'll have waited 2 frames. This is why I said that the length of the frame doesn't matter in this case.
User avatar
FinalZero
Posts: 152
Joined: Thu Dec 03, 2009 7:27 am
Contact:

Post by FinalZero »

I think you're confusing things, but it's normal.
NMIs are very simmilar to IRQs, but on the NES it is specifically wired to the PPU and, when activated, fires when VBLank begins, basically. Code at the NMI vector is then executed, and then you can update the tiles, sprites and other stuff (or just set a flag, sometimes).
IRQs are often mapper-specific (we exclude here DMC and frame IRQs which come from the APU part of the 2A03). In a 4-way scrolling game (ex:Super Mario Bros. 3), IRQs (from the MMC3 mapper) are used to set the scroll somewhere within a frame, so to perform a 4-way scrolling effect, to give an example.
So as you can see, NMIs and IRQs look similar but they're differents things. And I can expect that other members will emphatize the difference between IRQs and NMIs
NMIs are different from IRQs. NMIs are the ones that fire when VBlank starts and allows you to sync the rogram to the refresh rate, IRQs are used for things like raster effects (IRQs generated by mappers) and detecting when DPCM samples have finished playing. Many games (specially the ones with mappers older than the MMC3) don't use IRQs at all.
I was confusing them. Thank you for the explanations.

Code: Select all

Wait:
	lda $2002
	bpl Wait
While the flag is clear, you keep waiting. Do that twice and you'll have waited 2 frames. This is why I said that the length of the frame doesn't matter in this case.
And this happens at the very beginning of one's program?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Yes. The spinning happens twice, usually about a dozen instructions into a program.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

FinalZero wrote:And this happens at the very beginning of one's program?
It should be right after SEI, CLD, stack initialization, mapper initialization (if applicable) and PPU and APU resetting.
Post Reply