This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Writing to PPU - stupid coding problem

Writing to PPU - stupid coding problem
by on (#35494)
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:
;-- 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

by on (#35498)
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:

   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.

by on (#35499)
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?

by on (#35501)
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.

by on (#35503)
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.

by on (#35507)
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".

by on (#35508)
Yes man, but this time I have no idea. Please compile that piece sh*t and tell me what I have to change.

by on (#35509)
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:
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?

by on (#35510)
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!

by on (#35511)
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 : )

by on (#35512)
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.

by on (#35514)
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:
 .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

by on (#35515)
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.

by on (#35516)
Have fun:

Code:
 .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

     

by on (#35517)
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:
nmi_done:
   lda #0
   sta $2005
   sta $2005


that scrolling is necessary?

by on (#35518)
It was just to make sure that scrolling is "off".

by on (#35525)
It is good practice to set the scroll at the end of the NMI, and it's mandatory if you used registers $2006 and $2007, which can mess up the scroll.

by on (#35534)
tokumaru wrote:
It is good practice to set the scroll at the end of the NMI, and it's mandatory if you used registers $2006 and $2007, which can mess up the scroll.


And because of not switching the scrolling my code messed the PPU. That's it man!!