Goal: I would like to set the NES background as a single repeating pattern.

Something like this:

Problem: I can't get my pattern to display. I have the pattern I want loaded into the pattern table, I have written the colors I want to the background palette, all name tables are pointing to tile zero, all my attribute tables are zero; yet nothing is being displayed.

Logical program flow (what I think my program is doing):

disable interrupts / set stack pointer

set PPU control #1 bits to %00001000 so that:

D0-D1: name table address set to $2000

D2: PPU increment is 1

D3: sprite pattern address is $1000

D4: background pattern address is $0000

D5: sprite size is 8x8

D6: ?

D7: disable NMI on Vblank

set PPU control #2 bits to %00011110 so that:

D0: color display

D1: no background clipping

D2: no sprite clipping

D3: background is visible

D4: sprites are visible (no sprites in this example)

D5-D7: color intensity is set to none

clear Vblank flag

first wait for Vblank

second wait for Vblank

enable NMI on Vblank

Branch:

Main loop constantly sets $00 to whatever is in the Xreg

on NMI interrupt

write two bytes to the background palette (first is transparency, second is the color I want the pattern to be)

write one byte of $00 to name table #0 and attribute table #0 (really does nothing)

I have set up my CHR-ROM to point to the second color I loaded into the background palette. Here is my pattern table and palette according to FCEUX:

Here is my name tables according to FCEUX:

Yet my emulator is only displaying:

Secondary/tangent questions:

Why is so much of the NES memory mirrored? From a newb point of view this seems wasteful.

From (http://wiki.nesdev.com/w/index.php/Init_code); disabling IRQs (opcode SEI) is good if one might later desire to manually call the RESET routine. This makes sense to me but I have noticed that the order in which NMI and IRQs are enabled (I'm referencing my "INIT:" label in "test.s" below) determines whether or not PPU memory is written to (i.e. calling "CLI" before setting the 7th bit of PPU control #1 to 1 causes pattern table, name table, and attribute table to be empty; it might actually be causing the whole NES to crash, I'm not sure.)

Here I'm thinking it might be best to not manually disable IRQs (call SEI) and let the system do it naturally on interrupt for the benefit of simplicity.

I can give out about 5 or 6 URLs of threads here on the forum discussing all of this too, and they're just as convoluted. Just search for any posts from me with $2005 or PPUSCROL mentioned, but I guess the most applicable post would be this one from tokumaru:

First, there is something you need to know about the address register at $2006: it is also used by the PPU during rendering. It needs to be initialized during vertical blank after using it to update PPU RAM (tables, palette). There are two other registers that affect the internal address latch: $2000 and $2005. Ideally, you should do the following after updating whatever needs to be updated in PPU:

A. Set the scroll in $2005 to whatever horizontal and vertical scroll values you need, andB. Set $2000 using the name table you need for bits 1 and 0 (making sure to appropriately set the NMI enable and sprite/background bits).

Second, you did not disable the 2a03 APU's frame counter by writing a 1 to bit 6 of $4017. This means that it will continue to send IRQs to the CPU until:

A. the frame interrupt is acknowledged by reading $4015, orB. the frame interrupt is inhibited by writing a 1 to bit 6 of $4017.

The fastest way to deal with this, of course, is to simply do an SEI and be done with it, if you're not using any IRQs at all, which is the approach I would go with in this case.

Quote:

Secondary/tangent questions:

Why is so much of the NES memory mirrored? From a newb point of view this seems wasteful. From (http://wiki.nesdev.com/w/index.php/Init_code); disabling IRQs (opcode SEI) is good if one might later desire to manually call the RESET routine. This makes sense to me but I have noticed that the order in which NMI and IRQs are enabled (I'm referencing my "INIT:" label in "test.s" below) determines whether or not PPU memory is written to (i.e. calling "CLI" before setting the 7th bit of PPU control #1 to 1 causes pattern table, name table, and attribute table to be empty; it might actually be causing the whole NES to crash, I'm not sure.) Here I'm thinking it might be best to not manually disable IRQs (call SEI) and let the system do it naturally on interrupt for the benefit of simplicity.

IRQs need to be acknowledged by the programmer (the method of this depends on what hardware causes the IRQ), or they will execute continuously. This, I think, was meant to allow for multiple IRQs occurring, so that each hardware that requested the interrupt could be serviced in turn. IRQs are not supposed to interfere with NMIs ideally. The only reason why it would happen on the NES is because the IRQs are firing off continuously before the PPU hardware is given a chance to be allowed to fire off NMIs.

Interrupts only disable IRQs until the RTI instruction is executed. The RTI instruction returns the I flag to whatever it was set to before. Therefore, you still need to disable IRQs outside of interrupt code if you don't want them to happen.

I hope this hasn't been too confusing, I will attempt to clarify if need be.

Why is so much of the NES memory mirrored? From a newb point of view this seems wasteful.

Quite the opposite! Mirroring memory requires less logic/hardware than NOT mirroring it. If you have only 2KB of memory to fill a space of 8KB, it's AUTOMATICALLY mirrored to fill the whole space. Since there are no negative side effects from the mirroring in most cases, it's cheaper/simpler to just leave the mirrors alone.

I think he meant wasteful of the address space. Like you say, though, it's a tradeoff: waste logical address space, or use more hardware. Given the lack of need for logical address space, they choose to use less hardware.

I fully understand what it provides in the case of the SNES/65816, where for example portions of bank $00 are mirrored throughout other banks -- the purpose there should be obvious.

Likewise, on the Apple IIGS (again 65816), there were some "shadowed" (mirrored) registers and memory ranges which I was told time and time again by older/senior programmers should be used because, somehow at some particular level (hardware-wise), "they were faster than using the non-shadowed versions". I still don't understand how this can be the case, since it's going to cost the same number of CPU cycles no matter what the address is; I can see the benefit if there's a separate bus that runs at a higher clock speed that the mirrored/shadowed areas ties into, and that, say, a DMA chip could utilise (for memory copying/transfer), but the IIGS had no such thing. The only thing that made sense (in this regard) was the "mirroring" of banks $00 and $01 to banks $E0 and $E1 on the IIGS, where banks $00/01 ran at a slower clock speed (to be compatible with the earlier Apple II models) while banks $E0/E1 ran at a higher clock speed (reference; search for the phrases "shadowing is the term" and "$E0 and $E1 execute at standard clock speed"). I believe what I'm remembering are people telling me to access certain registers via $E0C0xx rather than $00C0xx to benefit from the higher clock speed; but how this matters I still don't understand (for example both sta $e0c034 and sta $00c034 would take 5 cycles (assuming 8-bit accum)).

Anyway, in the case of the NES/6502, I just don't see anything advantageous from the aforementioned mirroring.

2A03 has limited pins. PPU/SRAM/etc. decoding is done externally with a '139. This generates select signals for the cartridge, internal SRAM, and PPU. It would have taken 3 more pins on the 2A03. I'm guessing that this would have pushed it into a package size that cost noticeably more at the time (economics of size aren't just the small amount of extra plastic/pins, but the quantity produced, molds, etc.) 2A03 and 2C02 also both have 40 pins, so they probably get some economy by using the same count.

Well the 2A03 has 16 pins for A0-A15 (hence making up the full 16-bit address bus), and I understand that a 74LS139 is used to handle designation of "what speaks to what" (CPU vs. PPU vs. SRAM vs. external), but I still don't see how that justifies the $0800-1FFF and $2008-3FFF mirroring within CPU addressing space. Why is that needed? Why couldn't it just be left floating/open bus for the CPU? Or is there some kind of "commonality" (not sure what other word to use here) between the addressing spaces (as far as the 74LS139 goes) within the PPU vs. CPU vs. SRAM vs. external that justifies this need?

koitsu: Why would there need to be a software advantage to justify the mirrors on the NES? If it simplifies the hardware to leave it mirrored, isn't that purpose enough?

How does it simplify the hardware design? That hasn't been explained. A reference to a 74LS139 decoder being used does not explain why said CPU addressing ranges needed to be mirrored (respectfully blargg, not arguing or being combative).

The NES feeds the first one A from PHI2 and B from A15, with /EN low so it's always enabled. This generates /Y1 on access to 0-$7FFF, and /Y3 on access to $8000-$FFFF. The latter goes directly to the cartridge. /Y0 and /Y2 aren't useful as they indicate the other half of a cycle.

/Y1 is tied to the second decoder's enable, so it's enabled on access to the low half of the address space. A goes to A13 and B to A14. This divides the low half into four segments, 0-$1FFF, $2000-$3FFF, $4000-$5FFF, and $6000-$7FFF. It uses /Y0 for SRAM and /Y1 for the PPU. To "fully decode" SRAM, it'd need to look at A12 and A11, only enabling then they're low. To fully decode the PPU, it'd need to additionally look at A3-A12 (10 additional address lines), only selecting the PPU when they are all low. This adds hardware and latency due to gate propagation delays.

Incomplete decoding is elegant in the context of doing enough to work and not wasting extra hardware on things that don't matter.

Well, for example, mirroring a particular range 4 times means that there are 2 bits in the address decoding for it that don't have to do anything. The mirroring is simply a side effect of ignoring those bits.

Mirroring is a just a side effect of not using more address lines than are strictly needed. It's not a situation you would normally go out of your way to create, because mirrors aren't normally useful. (The Apple II thing you described is fairly unusual, I think.)

I see no $2005 writes or clearing of $2006, which from what I can see looks to be the root cause

Quote:

A. Set the scroll in $2005 to whatever horizontal and vertical scroll values you need, andB. Set $2000 using the name table you need for bits 1 and 0 (making sure to appropriately set the NMI enable and sprite/background bits).

Thanks! Seems like scrolling can get quite complicated! I will eventually have to master scrolling in both horizontal and vertical directions.

I've added the following ASM, it seems to put my X, Y at (0, 0) and clear $2006 which is what I'm going for.

Code:

LDA #$00 ; x positionSTA $2005LDA #$00 ; y positionSTA $2005

LDA #$00 ; clear $2006STA $2006LDA #$00STA $2006

(no reason why I'm setting the accumulator multiple times. I wouldn't do this in a real project)

It seems that the bigger problem was that PPU control byte #2 was being written to $2000 instead of $2001, that explains why nothing was being displayed. I must have copied and pasted the first PPU control line, changed the bits, but forgot to change the address it was being written to.

Who is online

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