A Couple of Questions

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
WJYkK
Posts: 60
Joined: Thu Dec 24, 2009 12:23 am
Location: Igloo and Bear Land (Canada)
Contact:

A Couple of Questions

Post by WJYkK » Thu Jan 27, 2011 10:16 pm

OK, so I've been working on a small demo and putting code in the NMI, and I've noticed that anytime when I want to access a variable at an even location (e.g. $00, $02, etc.), it throws me a CPU Jam in Nestopia and Nintendulator, yet if my addresses are odd, it works OK. Is there any reason why it does that? Could it be because the CPU interprets $02 as a HLT instruction (according to Nintedulator's debugger)?

Secondly, I've been looking for this over the forum and the wiki, but I can't seem to find any information for making a split-screen/HUD. I believe I saw once a link that provided very useful examples and code, but I can't find it anymore.

User avatar
Gilbert
Posts: 364
Joined: Sun Dec 12, 2010 10:27 pm
Location: Hong Kong
Contact:

Re: A Couple of Questions

Post by Gilbert » Thu Jan 27, 2011 10:57 pm

How did you access the variables? With things like LDA $02 or STA $02, right?

If the CPU really interprets $02 as an instruction there must be some severe logic flaw that it's running the codes from incorrect addresses. For example, if you have something like:
C100: A5 02 ;LDA $02
the programme counter should be running the code from address $C100, it would only attempt to interpret the byte "02" as an instruction if at some instances it's running the code at address $C101.

For the split screen thing, some starting pages could be this and this.

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

Re: A Couple of Questions

Post by tokumaru » Thu Jan 27, 2011 11:22 pm

I suggest you check all your stack operations. since you mentioned NMIs, make sure you are returning from them with RTI and not RTS (it's a common beginner mistake) and that you are PUSHing and PULLing registers correctly. If you still can't find what's wrong, you will probably have to post some of the code for us to look at (like the NMI routine and the main loop, for starters).
WJYkK wrote:Secondly, I've been looking for this over the forum and the wiki, but I can't seem to find any information for making a split-screen/HUD. I believe I saw once a link that provided very useful examples and code, but I can't find it anymore.
The implementation of a HUD/status bar depends on the type of scrolling that you are using, and whether you want the HUD at the top or bottom of the screen. If you are only scrolling sideways, the split point for the HUD is usually detected with a sprite 0 hit. Make sure that a solid (i.e. not color 0) background pixel collides with a solid sprite pixel in the first sprite (sprite 0) near the split point and that will cause bit 6 of $2002 to go high, so you know it's time to modify the scroll.

The horizontal scroll can be modified freely during rendering, you just have to write to $2000 and $2005 like you normally would. The vertical scroll can't be modified so easily, so instead of making the second $2005 write it's best that you read $2002 instead, which will clear the latch that selects between first and second writes.

If you want a status bar at the top, when all your PPU updates are done (including setting the scroll for the status bar), wait for the sprite hit flag to go low (this will happen at the end of VBlank, or immediately if there was no hit during the previous frame, but that doesn't matter), and then wait for it to go high again. If you placed the pixels correctly, the flag will change and you will change the horizontal scroll for the gameplay window. After that you can resume the game logic (i.e. exit from the NMI, if that's where you are doing the PPU updates).

If the status bar is at the bottom, after the PPu updates you resume the game logic normally. Once the game logic is done, wait for the hit flag to go high, and change the scroll for the status bar. This sounds simpler than a status bar at the top, but there's a big problem: if your game logic takes too long, and you miss the sprite hit, you'll get annoying visual glitches (the screen will jump, the status bar will flicker, etc). So only use this method if you are ABSOLUTELY sure your game logic will always finish before the hit.

If you are using a mapper with IRQs (it will be harder to manufacture carts in large quantities, since these mappers haven't been cloned by the community yet), replace the sprite hits with IRQs, and you can have your status bar anywhere.

WJYkK
Posts: 60
Joined: Thu Dec 24, 2009 12:23 am
Location: Igloo and Bear Land (Canada)
Contact:

Post by WJYkK » Sun Jan 30, 2011 2:11 pm

In regards to the crashing, this is what I had before in the beginning of my code:

Code: Select all

.enum $0001
Frames .dsb 1
SecondsOnes .dsb 1
SecondsTens .dsb 1
MinutesOnes .dsb 1
MinutesTens .dsb 1
NUMBERS_BASE .dsb 1
.ende
For some reason, on the first second (where SecondsOnes is set to 1) it goes fine, but once SecondsOnes is set to 2, it displays the correct time but crashes one frame later. After changing all .dsb 1 to .dsb 2, it works fine.

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

Post by tokumaru » Sun Jan 30, 2011 4:03 pm

That information by itself doesn't tell us much. Maybe you have other variables occupying the same memory locations, and reserving different amounts of bytes makes them clash in a way that the program doesn't crash... I would try setting a breakpoint to the memory range where those variables are and check if it's really being used correctly. I often reuse RAM when I know that certain variables are not gonna be used at the same time, but I have already used some at the same time by accident and the consequences were pretty bad. Make sure that's not your case.

Post Reply