Color 0D is the low part of the square waves it uses to draw any of the dark colors. The waves are between 00 (gray) and 0D (blacker than black). Regular dark colors which happen to use 0D as the low part of the wave don't cause problems.The other colors are waves between 10 and 1D, 20 and 2D, or 30 and 3D. Column D of the palette isn't supposed to be used though.

Here's a quick breakdown of the meaning of the CPU flags in a math context:

Carry (C): Indicates overflows and underflows of unsigned numbers. For example, add 1 to 255 and it wraps back to 0, because 256 doesn't fit in a byte. The carry is set to indicate this. Similarly, when you subtract 1 from 0, it wraps back to 255, and the carry is cleared to indicate this underflow.

Negative (N): Indicates the sign of signed numbers. It's merely a copy of bit 7, which is clear for values 0 to 127 ($00 to $7f) and set for values -128 to -1 ($80 to $ff).

Overflow (V): Indicates overflows and underflows of signed numbers. For example, add 1 to 127 and you get 128 ($80), which actually corresponds to -128 if you're working with signed numbers, so the overflow flag Indicates this. The same happens when subtractions give results smaller than -128.

Negative (N): Indicates the sign of signed numbers. It's merely a copy of bit 7, which is clear for values 0 to 127 ($00 to $7f) and set for values -128 to -1 ($80 to $ff).

Overflow (V): Indicates overflows and underflows of signed numbers. For example, add 1 to 127 and you get 128 ($80), which actually corresponds to -128 if you're working with signed numbers, so the overflow flag Indicates this. The same happens when subtractions give results smaller than -128.

So you can't just do:

Code:

lda myvariableclc ;(is this necessary for signed math?)adc #$02bpl + ;skip if didnt roll over ;run code if did roll over+:

lda myvariableclc ;(is this necessary for signed math?)adc #$02bpl + ;skip if didnt roll over ;run code if did roll over+:

This doesn't catch all the errors. For example, if you take -45 ($d3) and add -120 ($88), you get $5b, which is positive and is the wrong result. The correct result needs more bits to be represented ($ff5b = -165), and the V flag indicates this. And yes, the CLC is necessary.

4. Are there any situations when programming the NES where (indirect,x) addressing would come in handy?

(ZP,X) gets used a lot in virtual stacks, where the virtual stack (a data stack, separate from the return stack) is in ZP, and X is the index into it, and stack cells often have addresses. This is discussed a lot in my 6502 stacks treatise (notice, "stacks," plural, not just the page-1 hardware stack) starting in chapter 4, on virtual stacks and various ways to implement them, at http://wilsonminesco.com/stacks/virtualstacks.html . Here's a little bit quoted from near the top of the page there:

So far, we've only been talking about the 6502's hardware stack which:

resides in page 1 of the memory map,

has a dedicated processor register (S) as its stack pointer, and

built-in microprocessor instructions automatically take care of the indexing into the stack area and the incrementing and decrementing of the stack pointer.

You can implement virtual stacks too though. This just means you will synthesize the stack in software, typically using an index register as a pointer, and you'll have to use separate instructions to increment and decrement the index register and to store individual bytes of a multi-byte cell.

Ok, so why would you want to, if the 6502's built-in hardware stack operations already do this for you automatically? Well, it turns out that using an additional stack to handle data separately from return addresses has major attractions:

It makes parameter-passing between routines implicit and more efficient since routines won't have to keep stepping over return addresses. This becomes especially important when parameters are passed to a subroutine which may in turn pass one or more parameters to another one which won't know how many return addresses are sprinkled in unless each routine does more stack juggling!

It makes stack handling much easier than trying to put the data on the return (hardware) stack, partly for the reason above.

There are more addressing modes in ZP (zero page), so more operations can be done in place rather than having to do an intermediate move to ZP. There are plenty of things you can't do directly with the hardware stack anyway, like pull a value off to add to the contents of the accumulator.

The resulting easier stack operations reduce the number of variables needed along with the risk of overwriting data that another pending routine expects to find still intact. (This is true of the hardware stack too, but having the separate data stack carries it further.)

It improves nestability and re-entrancy of routines. (This is true of the hardware stack too, but having the separate data stack carries it further.)

It reduces bugs and crashes, improving development time.

The data stack becomes a workspace for arithmetic and logic operations.

Who is online

Users browsing this forum: No registered users and 5 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum