Writing to PPU - stupid coding problem

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

dr00id88
Posts: 28
Joined: Tue Aug 05, 2008 3:19 am

Writing to PPU - stupid coding problem

Post by dr00id88 »

Hi,

I have just registered to this bbs, but I've been tracing topics here for a very long time. I decided to register, because of a little problem with writing data to PPU. I need to write them during VBlank and all would seem ok, if there isn't stupid behaviour of PPU or rather my "unknowledge".

Code: Select all

;-- CODE START --;
	.inesmir 0 ;- don't care about mirroring
	.inesmap 0 ;- Mapper 2!!!
	.inesprg 1 ;- This might be 2 (I think NESASM.EXE goes by 8kb PRGs, so therefore the 4)
	.ineschr 1

	.bank 1  ; should be the last bank
	.org $FFFA
	.dw NMI
	.dw $8000
	.dw 0

	.bank 0    ; first bank loaded at $8000
	.org $8000 

  SEI          ; disable IRQs
  CLD          ; disable decimal mode
  LDX #$40
  STX $4017    ; disable APU frame IRQ
  LDX #$FF
  TXS          ; Set up stack
  INX          ; now X = 0
  STX $2000    ; disable NMI
  STX $2001    ; disable rendering
  STX $4010    ; disable DMC IRQs

vblankwait1:       ; First wait for vblank to make sure PPU is ready
  BIT $2002
  BPL vblankwait1

clrmem:
  LDA #$00
  STA $0000, x
  STA $0100, x
  STA $0200, x
  STA $0400, x
  STA $0500, x
  STA $0600, x
  STA $0700, x
  LDA #$FE
  STA $0300, x
  INX
  BNE clrmem

  ldx #00

vblankwait2:      ; Second wait for vblank, PPU is ready after this
  BIT $2002
  BPL vblankwait2


	lda #%10001000
	sta $2000
	lda #%00011000
	sta $2001


	lda #$3F
	sta $11
	lda #$00
	sta $12
	lda #$41
	sta $13
	lda #1
	sta $14
	
czekajtu:
	lda $14
	cmp #00
	bne czekajtu

	jsr lwait
	jsr lwait
	jsr lwait
	jsr lwait
	jsr lwait
	jsr lwait
	jsr lwait

;pauza: jmp pauza


	lda #$3F       
	sta $11
	lda #0
	sta $12
	lda #$0D
	sta $13
	lda #1
	sta $14
	
czekajtu2:
	lda $14
	cmp #00
	bne czekajtu2

	

	LDX #$00  
	STX $0003

LoadBackground:


	lda #$20       
	sta $11
	ldx $03	
	stx $12
	lda #$1
	sta $13
	lda #1
	sta $14

czekajtu3:
	lda $14
	cmp #00
	bne czekajtu3


	ldx $03
	inx 
	stx $03
	cpx #$FF

	bne LoadBackground





label:
	jmp label

NMI:

	pha
	txa
	pha
	tya
	pha

	lda $2002	

	lda #0
	sta $2000

	lda #%10000000
	sta $2000


	lda $14
	cmp #00
	beq brakgfx

	lda $11
	sta $2006
	lda $12
	sta $2006
	lda $13
	sta $2007
	lda #0
	sta $14

brakgfx:



	pla
	tay
	pla
	tax
	pla


	rti


longwait:

	ldy #$FF
lwait:
	jsr pleasewait
        dey
	cpy #00
	bne lwait

	rts

pleasewait:

	ldx #$FF
wait:
	dex
	cpx #00
	bne wait
	rts

	.bank 2
	.org $0000
	.incbin "our.spr"


;-- CODE END --;
I want to put chars on the screen (background), but I cannot switch off the screen and put all together. They need to be shown one by one. And I don't know why they're putting there from the right side?! For me it's impossible. Can someone repair this code? I'd like to see, how it should be coded to not to do the same mistake next time.

Thank you
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

At first glance, it seems like you're turning off the PPU on every NMI. Oh wait, you're even doing something weird back-to-back:

Code: Select all


   lda #0
   sta $2000

   lda #%10000000
   sta $2000

The first thing I would do is take that out and see what happens. That's just from a quick skim over the code though, there might be other stuff going wrong.
dr00id88
Posts: 28
Joined: Tue Aug 05, 2008 3:19 am

Post by dr00id88 »

I changed it, but there is also something wrong. Background is being build from the right side and only one line. I thnik it should go to the next one. Could you change that code?
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

After looking at that more, I'd say you really need to read up on how the PPU works:

http://nesdevwiki.org/index.php/NES_PPU

Before that, you probably need to check out more on 6502 assembly itself:

http://www.obelisk.demon.co.uk/6502/index.html


@all of the community: heh, now that I know a bit more about NES Dev, I see how it's frustrating for people to try and help. It's like, you want to help, but don't really know where to begin.
dr00id88
Posts: 28
Joined: Tue Aug 05, 2008 3:19 am

Post by dr00id88 »

geez, of course I will read that stuff. I browsed the first few times, but I am not asking about some docs, but about repair my source code. Then it would easier for me to understand my mistake.
User avatar
hap
Posts: 355
Joined: Thu Mar 24, 2005 3:17 pm
Contact:

Post by hap »

It's easier (and more gratifying) for you to understand your mistakes if you find them yourself :)
If you really want someone else to repair it, request the topic to be moved to "Newbie Help Center".
Last edited by hap on Tue Aug 05, 2008 9:43 am, edited 1 time in total.
dr00id88
Posts: 28
Joined: Tue Aug 05, 2008 3:19 am

Post by dr00id88 »

Yes man, but this time I have no idea. Please compile that piece sh*t and tell me what I have to change.
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

Well, it's just that it is hard to "repair" the code. I'm just trying my best to figure out how to go about it. It's not that I'm frustrated with you, it's that I'm frustrated with myself trying to figure out how to help. I hope you didn't take that last statement I made and think I was talking about you. I'll try and help and leave some room for thought, as hap pointed out.

Okay, for writes to $2006, you want to specify where the nametable is going to start at. It looks like you have it set to be at $2000, so you would need to write to $2006 something like this:

Code: Select all

lda $#20
sta $2006
lda #$00
sta $2006
After that is when you can start writing tiles to the screen via $2007. In case you don't know, when you open up your chr file in a text editor, from left to right each tile is a number:

#$00 for the first tile, #$01 for the next tile, etc.

You'll need a way to get lots of tiles on the screen, so you will need to look into using loops, for sure. Also, I wouldn't be doing all this in my NMI routine though, just make sure to wait for vblank before doing it.

So basically, wait for vblank, turn off the PPU, write what nametable you want to use in $2006, put tiles in through $2007, turn the PPU back on.

Quick question too. Is there any certain reason that you're loading $300 and on with 254?
dr00id88
Posts: 28
Joined: Tue Aug 05, 2008 3:19 am

Post by dr00id88 »

Roth wrote:Quick question too. Is there any certain reason that you're loading $300 and on with 254?
I forgot to change it to #00, I found it in one tutorial. It doesn't matter.
But listen to me, Roth. You'd like me to change the code to disable the screen then put the nametable, and turn the screen on. I don't want to draw all the background. I'd like to see the effect similar to these:
http://nesdev.com/bbs/viewtopic.php?t=4227

The text is being written. It is NOT all on the screen, but it's being revealed. Understand me? I know that I can insert the data to $2007 during VBlank and I am trying to do that. I don't want to put all together when the screen is off!
Roth
Posts: 400
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth »

Ah, I see. I've never done any kind of typing like effect, so that'd be something that I wouldn't be able to help you with. At any rate, I figured that you needed to get the basics down first, seeing as how you were doing things like triggering an NMI during NMI. You will probably need to get someone else to help you with that then. Good luck with your project : )
dr00id88
Posts: 28
Joined: Tue Aug 05, 2008 3:19 am

Post by dr00id88 »

Roth wrote:Ah, I see. I've never done any kind of typing like effect, so that'd be something that I wouldn't be able to help you with. At any rate, I figured that you needed to get the basics down first, seeing as how you were doing things like triggering an NMI during NMI. You will probably need to get someone else to help you with that then. Good luck with your project : )
That interrupt during interrupt was because I could't mention the problem. I made a piece of shit then:P Anyway thanks for help, Roth.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

I'm not sure I understand exactly what you want to do. But to draw some stuff on the BG during the NMI you could do something like this:

Code: Select all

 .inesprg    1	
 .ineschr    1	
 .inesmir    1	
 .inesmap    0	

 .bank 0
 .org  $8000
 
 reset:
 	cld
 	sei
 	ldx #$00
 	stx $2000	; No NMI
 	stx $2001	; Disable screen
 	inx
 waitvb:	
 	lda $2002
 	bpl waitvb	; Wait a few frames
 	dex
 	bpl waitvb
	txs		; Set up stack pointer


	; Copy palette data
	lda #$3F       
       	sta $2006      
        lda #$00        
        sta $2006 
	ldx #$00
	ldy #$20
	set_palette:
		lda palette,x        
	        sta $2007
		inx
		dey
		bne set_palette

	; Clear NT 0
	lda #$20
	sta $2006
	lda #$00
	sta $2006
	lda #0
	ldx #0
	ldy #4
	clearNT:
		sta $2007
		dex
		bne clearNT
		dey
		bne clearNT
		
	; Enable BG & sprites, don't clip BG
	lda #$1A
	sta $2001  

	; Enable NMI
	lda #$80
	sta $2000

forever:
	jmp forever



nmi:
	lda #$20
	sta $2006
	lda #$00
	sta $2006

	; Fill the first row of NT 0 with character 1
	lda #1
	ldx #32
	fill1:
		sta $2007
		dex
		bne fill1

	lda #0
	sta $2005
	sta $2005
irq:
	rti




palette:
	.dw 12,6


; Setup interrupt vectors
 .bank 1
 .org  $fffa
	.dw   nmi
	.dw   reset
	.dw   irq


; CHR-ROM
 .bank 2
 .dw 0,0,0,0,0,0,0,0
 .dw $2810,$8244,$82fe,$0082,0,0,0,0
dr00id88
Posts: 28
Joined: Tue Aug 05, 2008 3:19 am

Post by dr00id88 »

No!! You're telling me to do exactly the same thing like Roth. I want to see "in slow motion" char-by-char how the background is being constructed, but you're switching off the screen. And after turn on, all of the chars are done.
Just look at the demo, I hyperlinked a few post above.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

Have fun:

Code: Select all

 .inesprg    1	
 .ineschr    1	
 .inesmir    1	
 .inesmap    0	

VRAMADR_LO 	= $10
DELAY		= $11

 .bank 0
 .org  $8000
 
 reset:
 	cld
 	sei
 	ldx #$00
 	stx $2000	; No NMI
 	stx $2001	; Disable screen
 	inx
 waitvb:	
 	lda $2002
 	bpl waitvb	; Wait a few frames
 	dex
 	bpl waitvb
	txs		; Set up stack pointer


	; Copy palette data
	lda #$3F       
	sta $2006      
	lda #$00        
	sta $2006 
	ldx #$00
	ldy #$20
	set_palette:
		lda palette,x        
		sta $2007
		inx
		dey
		bne set_palette

	; Clear NT 0
	lda #$20
	sta $2006
	lda #$00
	sta $2006
	lda #0
	ldx #0
	ldy #4
	clearNT:
		sta $2007
		dex
		bne clearNT
		dey
		bne clearNT

	lda #$00
	sta <VRAMADR_LO
	
	lda #60
	sta <DELAY
	
	; Enable BG & sprites, don't clip BG
	lda #$1A
	sta $2001  

	; Enable NMI
	lda #$80
	sta $2000

forever:
	jmp forever



nmi:
	ldx <DELAY
	dex
	stx <DELAY
	bne nmi_done

	lda #60
	sta <DELAY
	
	lda #$20
	sta $2006
	lda <VRAMADR_LO
	sta $2006
	tax
	inx
	stx <VRAMADR_LO
	
	lda #1
	sta $2007
	
nmi_done:
	lda #0
	sta $2005
	sta $2005
irq:
	rti




palette:
	.dw 12,6


; Setup interrupt vectors
 .bank 1
 .org  $fffa
	.dw   nmi
	.dw   reset
	.dw   irq


; CHR-ROM
 .bank 2
 .dw 0,0,0,0,0,0,0,0
 .dw $2810,$8244,$82fe,$0082,0,0,0,0

      
dr00id88
Posts: 28
Joined: Tue Aug 05, 2008 3:19 am

Post by dr00id88 »

That's what I need. I will try it and analise the code. Thank you mic_. If I had any questions I will post them here.

EDIT:

I was similar to my code, but I wasn't waiting for delays and because of that the PPU crashed. I supposed that. Thank you for help, once again.

Code: Select all

nmi_done: 
   lda #0 
   sta $2005 
   sta $2005 
that scrolling is necessary?
Last edited by dr00id88 on Tue Aug 05, 2008 11:10 am, edited 1 time in total.
Post Reply