It is currently Sat Nov 17, 2018 7:46 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Thu Aug 16, 2018 9:51 pm 
Offline

Joined: Fri Oct 28, 2016 12:37 pm
Posts: 50
Hi all,

so everything was working fine with my project until I decided to use some RAM for a collision map (basically an array to hold a 0 for empty space, 1 for occupied space).

After creating the collision map I lose my picture, however the debugger shows my nametable is all there and looks fine on the PPU.

First question is, is there a common denominator to help debug through when the screen is black but the nametable looks fine?

Second question is, does anything in the code stand out as obvious? By the way, prior to updating the nametable I wait for vblank, turn off rendering, write to the PPU, then try to update my collision map. I wait for vblank again, then turn rendering back on.

Code:
nt_collision_ptr .rs 2 ; pointer to nametable collision map


Code:
Reset_nt_collision_ptr:
   ; set collision pointer to page 2 in RAM
   LDA #$00 ; low byte
   STA nt_collision_ptr
   LDA #$01 ; high byte
   STA nt_collision_ptr + 1
   ;done, $0100
   RTS


Full disclosure on this next bit, originally I added the collision update logic in my nametable loader code but this was also giving me a black screen, so to test I broke it out into its own subroutine but I'm getting the same result. And I know this loop will read an extra 64 bytes from the attribute table but I planned on making this work first (I can save the 64 bytes after this works). What is very weird is, if I remove the STA command under the solid_tile label then my picture comes back..

Code:
Update_collision_map:
   JSR Reset_nt_collision_ptr
   
   LDX #$00
   LDY #$00
update_collision_loop:
   LDA [nametable_ptr], y
   CMP #TILE_CLEAR
   BNE solid_tile
   ; empty space
   LDA #$00
   STA [nt_collision_ptr], y
   JMP resume_collision_load
solid_tile:
   LDA #$01
   STA [nt_collision_ptr], y
resume_collision_load:
   INY
   CPY #$00 ; wrap around = 256 tiles
   BNE update_collision_loop
   ; see if next set needs to be processed
   INC nt_collision_ptr + 1
   LDY #$00
   INX
   CPX #$04
   BNE update_collision_loop
   RTS


Top
 Profile  
 
PostPosted: Thu Aug 16, 2018 10:13 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6955
Location: Canada
If your nametables and palettes are showing up in the debugger, but the screen is black, there are a few possibilities:

1. Rendering is not turned back on, maybe the write to $2001 never happened?

2. The scroll position is pointing at the second nametable, which might be an empty black page? (When you've finished uploading all 1024 bytes of nametable, the scroll pointer will actually be currently pointed at 0,0 on the subsequent nametable.)

For #1, a possible cause is failing to enable the NMI again (via $2000), your NMI handler will never be able to do that write to $2001.


Top
 Profile  
 
PostPosted: Thu Aug 16, 2018 10:30 pm 
Offline
User avatar

Joined: Sat Aug 15, 2015 3:42 pm
Posts: 150
Location: France
Be careful when using page $0100 in RAM, that's where the stack lives. Try to use another area like $0300 for example.

_________________
My first game : Twin Dragons available at Broke Studio.


Top
 Profile  
 
PostPosted: Thu Aug 16, 2018 10:41 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2333
Location: DIGDUG
Unrelated, you could make this loop more efficient.

For example

LDA #$00
STA [nt_collision_ptr], y
JMP resume_collision_load

Lda #0 sets the zero flag
sta changes no flags
so we could do...
beq resume_collision_load
and save a byte.

both options do
STA [nt_collision_ptr], y

so you could throw both after resume_collision_load: and save a few bytes.

INY
CPY #$00 ; wrap around = 256 tiles
BNE update_collision_loop

the CPY #0 is redundant.
INY sets the zero flag if its result is zero, so all you need is...

INY
BNE update_collision_loop

and you don't need the LDY #0 below that. It's already zero.

And lastly, if X isn't doing anything but counting, you could start it at #4 and count down to zero, and remove the CPX.

LDX #4
loop:
...
DEX
BNE loop


So, let's optimize it...



Code:
   LDX #$04
   LDY #$00
update_collision_loop:
   LDA [nametable_ptr], y
   CMP #TILE_CLEAR
   BNE solid_tile
   ; empty space
   LDA #$00
   BEQ resume_collision_load
solid_tile:
   LDA #$01
resume_collision_load:
   STA [nt_collision_ptr], y
   INY
   BNE update_collision_loop
   ; see if next set needs to be processed
   INC nt_collision_ptr + 1
   DEX
   BNE update_collision_loop
   RTS

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Thu Aug 16, 2018 10:48 pm 
Offline

Joined: Fri Oct 28, 2016 12:37 pm
Posts: 50
Quote:
Be careful when using page $0100 in RAM, that's where the stack lives. Try to use another area like $0300 for example.


I'm such a noob :roll: , this resolved the issue glutock.. thank you!


Thanks rainwarrior, I wanted to address your points in case I'm doing these things incorrectly;

Quote:
1. Rendering is not turned back on, maybe the write to $2001 never happened?


Here is the heart of it. By the way I also swap the background palette when I change my nametables, so I'm setting a flag and doing that part in NMI. The code below is outside of my NMI.

Code:
; turn off rendering
   JSR Wait_vblank
   JSR Disable_rendering
   
   ; update palette
   LDA #LOW(select_palette)
   STA palette_ptr
   LDA #HIGH(select_palette)
   STA palette_ptr + 1
   LDA #$01
   STA swap_palette
   JSR Wait_vblank
   
   ; load starting nametable
   LDA #LOW(select_nametable)
   STA nametable_ptr   
   LDA #HIGH(select_nametable)
   STA nametable_ptr + 1
   JSR Load_nametable   ; this now also updates the collision map so I read from the nametable pointer once
   
   ; turn rendering back on
   JSR Wait_vblank
   JSR Enable_rendering   



Code:
; only call this during vblank
Disable_rendering:
   ; turn off ppu
   LDA #%00000000
   STA PPUMASK
   RTS

; only call this during vblank   
Enable_rendering:
   ; turn on ppu on
   LDA #%00011110
   STA PPUMASK
   RTS


Quote:
The scroll position is pointing at the second nametable, which might be an empty black page? (When you've finished uploading all 1024 bytes of nametable, the scroll pointer will actually be currently pointed at 0,0 on the subsequent nametable.)


I have this at the end of my NMI, right before I pop the stack

Code:
   ; scroll pos
   LDA #$00
   STA $2005
   STA $2005



And thanks for those tips doug! I'm new to assembly, it's interesting to see how the zero flag can work to save some opcodes.


Top
 Profile  
 
PostPosted: Thu Aug 16, 2018 10:58 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6955
Location: Canada
casprog wrote:
I have this at the end of my NMI, right before I pop the stack

Code:
   ; scroll pos
   LDA #$00
   STA $2005
   STA $2005

So, going back to one of my earlier suggestions, did you remember to turn the NMI itself back on so that this scroll code can take effect? ($2000 / PPUCTRL)


Top
 Profile  
 
PostPosted: Thu Aug 16, 2018 11:03 pm 
Offline

Joined: Fri Oct 28, 2016 12:37 pm
Posts: 50
Quote:
So, going back to one of my earlier suggestions, did you remember to turn the NMI itself back on so that this scroll code can take effect? ($2000 / PPUCTRL)


Well I leave my NMI running, I never turn it off anymore, I just disable / enable rendering now.

EDIT:: do I need to update $2000 again even if I don't turn it off explicitly?


Top
 Profile  
 
PostPosted: Fri Aug 17, 2018 5:56 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20776
Location: NE Indiana, USA (NTSC)
I would recommend writing $2000 every frame, as it contains the upper bit of the X and Y scroll position.


Top
 Profile  
 
PostPosted: Fri Aug 17, 2018 11:34 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6955
Location: Canada
casprog wrote:
Well I leave my NMI running, I never turn it off anymore, I just disable / enable rendering now.

EDIT:: do I need to update $2000 again even if I don't turn it off explicitly?

Okay, well have you re-enabled rendering then?

As tepples is suggesting, setting the scroll normally takes 3 writes, $2000, $2005, $2005. All need to be done during vblank. (They take effect at the beginning of the visible frame, if rendering is on.)

They definitely shouldn't be happening every NMI though, only when you have your flag to let your NMI handler do PPU interaction. Otherwise, writing $2005 while you're in the middle of doing updates to your nametables will mess up the address you're trying to write to.


Anyway, the main question is whether these things you expect to be happening are actually happening. Whether or not you wrote code to do them is only part of it. Make sure that code is being executed. Put a breakpoint on the code, or put a breakpoint on writes to $2001 etc.

BTW if you post a ROM someone could use a debugger to answer this question immediately. Reading fragments of your code mostly just creates a lot of questions that only you can answer.


Top
 Profile  
 
PostPosted: Fri Aug 17, 2018 3:14 pm 
Offline

Joined: Fri Oct 28, 2016 12:37 pm
Posts: 50
Thanks rainwarrior,

Yes I was enabling rendering again, looks like the issue was my collision map was written to an area of memory which was conflicting with the stack.

Quote:
They definitely shouldn't be happening every NMI though, only when you have your flag to let your NMI handler do PPU interaction. Otherwise, writing $2005 while you're in the middle of doing updates to your nametables will mess up the address you're trying to write to.


I'll be sure to move that logic under my ppu on flag. And to be safe I added a call to turn NMI back on in my NMI as was suggested earlier.

I appreciate all the help and advice.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group