don't understand Nametables.
Moderator: Moderators
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: don't understand Nametables.
I get it now, thanks!
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: don't understand Nametables.
For some reason, the camera is able to avoid showing the nametable at all costs.
Re: don't understand Nametables.
You need to set the scroll after messing with $2006/$2007, otherwise the NES won't know what part of the background you want to show.
After doing everything PPU-related in the NMI handler, while still in vblank, select a name table using register $2000 and set the scroll by writing to $2005 twice (writing zeroes will show the name table from its top left corner).
After doing everything PPU-related in the NMI handler, while still in vblank, select a name table using register $2000 and set the scroll by writing to $2005 twice (writing zeroes will show the name table from its top left corner).
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: don't understand Nametables.
Do I write to $2000 via $2007?
Re: don't understand Nametables.
No, I specifically said "register $2000". If you used $2006/7 you'd be writing to "VRAM address $2000".
Re: don't understand Nametables.
It's usually...
;NMI on, BG = 1st tiles, Sprite = 2nd tiles, nametable 0
LDA #$88
STA $2000
LDA #0
STA $2005
STA $2005
or
;NMI on, BG = 2nd tiles, Sprite = 1st tiles, nametable 0
LDA #$90
STA $2000
LDA #0
STA $2005
STA $2005
;NMI on, BG = 1st tiles, Sprite = 2nd tiles, nametable 0
LDA #$88
STA $2000
LDA #0
STA $2005
STA $2005
or
;NMI on, BG = 2nd tiles, Sprite = 1st tiles, nametable 0
LDA #$90
STA $2000
LDA #0
STA $2005
STA $2005
nesdoug.com -- blog/tutorial on programming for the NES
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: don't understand Nametables.
It sets the scroll when I do 1, but it still doesn't display. As a matter if fact, it never displays.
Re: don't understand Nametables.
You can post the .nes file. I'll debug it for you.
nesdoug.com -- blog/tutorial on programming for the NES
Re: don't understand Nametables.
Your descriptions of what you're doing and how the result differs from what you expect are terribly vague.
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: don't understand Nametables.
Here is my code:
Code: Select all
;----------------------------------------------------------------
; constants
;----------------------------------------------------------------
PRG_COUNT = 1 ;1 = 16KB, 2 = 32KB
MIRRORING = %0001 ;%0000 = horizontal, %0001 = vertical, %1000 = four-screen
;----------------------------------------------------------------
; variables
;----------------------------------------------------------------
.enum $0000
;NOTE: declare variables using the DSB and DSW directives, like this:
;MyVariable0 .dsb 1
;MyVariable1 .dsb 3
PlayerX=$0000
PlayerY=$0001
PalletteController=$2006
.ende
;NOTE: you can also split the variable declarations into individual pages, like this:
;.enum $0100
;.ende
;.enum $0200
;.ende
;----------------------------------------------------------------
; iNES header
;----------------------------------------------------------------
.db "NES", $1a ;identification of the iNES header
.db $01 ;number of 16KB PRG-ROM pages
.db $01 ;number of 8KB CHR-ROM pages
.db $00|$01 ;mapper 0 and mirroring
.dsb 9, $00 ;clear the remaining bytes
;----------------------------------------------------------------
; program bank(s)
;----------------------------------------------------------------
.base $10000-(PRG_COUNT*$4000)
Reset:
LDA #$3F
STA $2006
LDA #$00
STA $2006
LDA #$2C
STA $2007
LDA #$3F
STA $2007
LDA #$29
STA $2007
LDA #$18
STA $2007
LDA #$3F
STA $2006
LDA #$04
STA $2006
LDX #$2C
STX $2007
LDX #$3F
STX $2007
LDX #$28
STX $2007
LDX #$16
STX $2007
LDY #%11001001
STY $2000
LDX #%00011110
STX $2001
LDX #128
STX $0000
STX $0001
Wait:
JMP Wait
UP:
LDX $0001
INX
STX $0001
JMP Wait
DOWN:
LDX $0001
DEX
STX $0001
JMP Wait
LEFT:
LDX $0000
DEX
STX $0000
JMP Wait
RIGHT:
LDY $0000
INY
STY $0000
JMP Wait
NMI:
LDX #$20
STX $2006
LDX #$00
STX $2006
LDA #$12
STA $2007
LDY #0
STY $2000
LDY #0
STY $2005
STY $2005
RTI
IRQ:
;NOTE: IRQ code goes here
RTI
;----------------------------------------------------------------
; interrupt vectors
;----------------------------------------------------------------
.org $fffa
.dw NMI
.dw Reset
.dw IRQ
;----------------------------------------------------------------
; CHR-ROM bank
;----------------------------------------------------------------
.incbin "Graphics.chr"
Re: don't understand Nametables.
Your program would probably push 1 tile to the top left corner of the screen.
Note. Some emulators don't show the upper 8 and bottom 8 pixels of the screen by default. FCEUX, for example. You have to find the display settings, NTSC, and manually adjust the visible scanlines to see them all. (It's trying to accurately emulate 'overscan' of old TVs, which used to cut off the edges of the screen).
This may not be your problem. You are doing STA of #0 to $2000, which means that both BG and Sprites are using the same tile set (the 1st set). And you never set the sprite positions... and they tend to default to the top left of the screen...exactly where your BG tile is...and posibly covering it up.
Also. There could be something wrong with your CHR file. I meant for you to post the actual .nes file. And not the source code.
Note. Some emulators don't show the upper 8 and bottom 8 pixels of the screen by default. FCEUX, for example. You have to find the display settings, NTSC, and manually adjust the visible scanlines to see them all. (It's trying to accurately emulate 'overscan' of old TVs, which used to cut off the edges of the screen).
This may not be your problem. You are doing STA of #0 to $2000, which means that both BG and Sprites are using the same tile set (the 1st set). And you never set the sprite positions... and they tend to default to the top left of the screen...exactly where your BG tile is...and posibly covering it up.
Also. There could be something wrong with your CHR file. I meant for you to post the actual .nes file. And not the source code.
nesdoug.com -- blog/tutorial on programming for the NES
Re: don't understand Nametables.
I haven't run your program, but I can see a few problems with your code:
1)
I can't see your init code. I'd use the one in the wiki if I where you. I gave you earlier a minimal init code that doesn't have the two required vblank waits, just the required register writes ($4017, $4010 etc), but that was only because that program didn't use the PPU (it was just a minimal noise test program that didn't output any graphics). The PPU requires you to wait twice for a vblank before you send any data to it, or it will probably not work as you expect. You don't need to understand the init routine fully at the moment, just remember that it's necessary for all programs.
2)
Your variable declarations are weird. You use the .dsb directive inside the .enum and .ende like I explained earlier. In your code it would be:
Then you can use the variables in your code like:
Also, the "PalletteController=$2006" is a constant definition and not a variable at all, so place it among the other constants. And BTW, $2006 is not really a palette controller, but is used to select what VRAM address you want to read or write to (using $2007). The palette is a part of the VRAM though, as are the nametables and pattern tables but not the OAM (sprite attribute memory).
VRAM Map
3)
Bit 0 and 1 of $2000 are set to %01, this will select nametable 1 (VRAM $2400) as base nametable address. Is that what you wanted? In your NMI you write to nametable 0 so it sounds like this should be set to %00.
Setting bit 6 of $2000 is very bad as it could potentially damage the chip. It should always be zero.
4)
This code is outside the flow and will never happen.
1)
I can't see your init code. I'd use the one in the wiki if I where you. I gave you earlier a minimal init code that doesn't have the two required vblank waits, just the required register writes ($4017, $4010 etc), but that was only because that program didn't use the PPU (it was just a minimal noise test program that didn't output any graphics). The PPU requires you to wait twice for a vblank before you send any data to it, or it will probably not work as you expect. You don't need to understand the init routine fully at the moment, just remember that it's necessary for all programs.
2)
Your variable declarations are weird. You use the .dsb directive inside the .enum and .ende like I explained earlier. In your code it would be:
Code: Select all
.enum $0000
PlayerX .dsb 1
PlayerY .dsb 1
.ende
Code: Select all
LDX #128
STX PlayerX
STX PlayerY
VRAM Map
3)
Code: Select all
LDY #%11001001
STY $2000
Setting bit 6 of $2000 is very bad as it could potentially damage the chip. It should always be zero.
4)
Code: Select all
UP:
LDX $0001
INX
STX $0001
JMP Wait
DOWN:
LDX $0001
DEX
STX $0001
JMP Wait
LEFT:
LDX $0000
DEX
STX $0000
JMP Wait
RIGHT:
LDY $0000
INY
STY $0000
JMP Wait
Re: don't understand Nametables.
And you're still not waiting for the PPU to warm up. In fact, you have no initialization code at all! You absolutely need to initialize some critical things before you can reliably use the console and start displaying anything. Have a look at what the wiki has to say about initialization code.
Re: don't understand Nametables.
Yes that's what I meant with problem number 1).
Re: don't understand Nametables.
Oh crap, didn't see you had already mentioned it!