Loading my "hello, world" on real hardware (AVS)

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

Post Reply
ludoVIC
Posts: 31
Joined: Fri Jan 08, 2021 8:36 am

Loading my "hello, world" on real hardware (AVS)

Post by ludoVIC » Thu Jan 28, 2021 6:31 am

Hello people! I just finished studying the first part of the Nerdy Nights tutorials.
I had a lot of questions, but most of them are now solved thanks to your support :mrgreen:
Before proceeding, I wrote my "hello, world" ROM where I implemented most of the ideas that I learnt.

Sadly, when I load it on my real hardware (AVS retroUSB + EZ Everdrive N8 Pro), I just get a blank screen.
Does anybody know, what the cause might be?

In case, my code is attached. Thanks in advance for your help!

Ps: the code shows a "Title Screen". After pressing Start, you move Mario and get a Game Over when hitting Goomba.
Everything very rudimentary, just for the sake of practicing.
Attachments
mario2.chr
(8 KiB) Downloaded 20 times
draft.nes
(24.02 KiB) Downloaded 24 times
draft.asm
(8.93 KiB) Downloaded 21 times

User avatar
tokumaru
Posts: 11991
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Loading my "hello, world" on real hardware (AVS)

Post by tokumaru » Thu Jan 28, 2021 7:03 am

One thing that you seem to be getting wrong in your programs is that you're only waiting for one vblank before using the PPU, while the recommendation is to wait for two. Also, it's good practice to do a preliminary $2002 read before the actual wait loop, to prevent the case where no waiting takes place due to the code being called at a time when the vblank flag is already on:

Code: Select all

WaitForPPU:
  bit $2002 ;makes sure the vblank flag is off
Wait:
  bit $2002
  bpl Wait
  rts
I don't know if this is the problem preventing your program from working correctly (probably not, specially if you're loading this from a flashcart, but you should definitely fix this.

In which emulators have you tested this? If you can find an emulator which gives the same result as on hardware that has at least some debugging features, you can try tracing through the code to see if all the code is executing as expected.

User avatar
tokumaru
Posts: 11991
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Loading my "hello, world" on real hardware (AVS)

Post by tokumaru » Thu Jan 28, 2021 7:15 am

Found another BIG problem with your code: you don't have the holy pair of 6502 instructions at the very beginning of your reset routine - SEI and CLD. You don't have a valid IRQ handler (it's set to address 0, another shortcoming of Nerdy Nights), so if an IRQ fires (and the APU is known to fire IRQs from time to time if not properly initialized), the CPU will jump to address $0000 and most likely crash. Better disable IRQs altogether by putting a SEI instruction as the first thing in the reset handler. As for CLD, even though the decimal flag isn't a thing on the NES, it doesn't hurt to put that instruction in.

ludoVIC
Posts: 31
Joined: Fri Jan 08, 2021 8:36 am

Re: Loading my "hello, world" on real hardware (AVS)

Post by ludoVIC » Thu Jan 28, 2021 7:59 am

Great! I corrected my code and it worked perfectly!
Thank you so much, especially for having clearly explained the reasons beyond any suggestion :wink:

User avatar
tokumaru
Posts: 11991
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Loading my "hello, world" on real hardware (AVS)

Post by tokumaru » Sat Jan 30, 2021 11:45 am

Maybe now is a good time to talk about a couple of gripes I have with the Nerdy Nights tutorials. One is the use of 0 as the IRQ vector... There's always a chance you'll accidentally enable IRQs, or execute a BRK instruction, in which case the CPU will jump to address $0000 and crash. The fix for this is very simple and doesn't consume any extra resources: just point the IRQ vector to the RTI instruction at the end of the NMI handler:

Code: Select all

NMI:
  ;(do all your NMI stuff here)

IRQ: ;<-- point the IRQ vector to this label, instead of 0
  rti ;returns from either the NMI or the IRQ 
If at some point you end up needing an actual IRQ handler (for an audio engine or an scanline counter), just give the NMI handler its own RTI back.

Now for the biggest problem in the Nerdy Nights tutorials: the entire game logic runs during vblank! The NMI signal is there to notify the CPU that vblank has started, so that you can make the most out of that short period and do all your video updates (sprites, name tables, palettes, etc.). But that's not how the tutorials use it, instead they do a bunch of tasks that have no place running during vblank, such as reading the controllers and reading sprite, and only after that will it carry out the necessary video updates.

Since video updates can only be done during vblank, this means that both the game logic and the video updates have to fit in the vblank period, witch is a measly 20 scanlines out of 262. That's right, Nerdy Nights programs can only use less than 8% of the CPU power of the NES before they start to glitch.

I'm not sure if they fix this in later lessons (I hope they do!), but sometimes you see people trying to create basic games such as Pong using Nerdy Nights as a base, and the games suddenly breaks because they added too much logic and the video updates started spilling out o vblank and into rendering time.

The simplest fix here is to invert the order in which you do things in the NMI handler: first do the video updates (using data computed during the previous NMI), then process the game logic for the *next* frame. Just be careful to not do a glitchy round of video updates the first time the NMI handler runs, possibly by having a flag signal whether the NMI handler is supposed to do any video updates. A flag like this is normally needed anyway for cases when you want to disable rendering and do big name table updates, so the NMI handler won't interfere with those.

Pokun
Posts: 1746
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Loading my "hello, world" on real hardware (AVS)

Post by Pokun » Sun Jan 31, 2021 9:41 am

tokumaru wrote:
Sat Jan 30, 2021 11:45 am
I'm not sure if they fix this in later lessons (I hope they do!)
Nope, at least not in Bunnyboys tutorials (though which are great in many ways anyway) IIRC. The Nerdy Nights sound tutorial by Metalslime does teach you this however which is one reason it's also great. It's a sound tutorial but it actually teaches you how to make a buffering system for the graphics, just for the purpose of the simple music player interface it uses to teach sound.

I highly recommend to look at this tutorial after you are quite comfortable with what's taught in the regular tutorials.

ludoVIC
Posts: 31
Joined: Fri Jan 08, 2021 8:36 am

Re: Loading my "hello, world" on real hardware (AVS)

Post by ludoVIC » Wed Feb 17, 2021 11:14 am

Oh, wow, thank you a lot for the added information!
My apologize for being so late (busy with work): I saved your post in order to be ready when I am more comfortable with NES programming :D

Post Reply