8x16 and whatever else unreg wants to know

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Wed Mar 06, 2013 2:01 pm

Kasumi, when I change the code to

Code: Select all

lda #29
it's all really confusing now... my character doesn't fall all the way to the ground... she falls for a small part of a second and then suddenly stops... cant move her around.

User avatar
Kasumi
Posts: 1292
Joined: Wed Apr 02, 2008 2:09 pm

Re: 8x16 sprite is really a 16x32 pixel image?

Post by Kasumi » Wed Mar 06, 2013 2:07 pm

You would also need to change this:

Code: Select all

     dex
     stx t2
      bne -- 
to this

Code: Select all

     dex
     stx t2
      bpl -- 
Otherwise it never actually does 0. Whether or not that will fix the falling issue, I don't know. You've never posted that code, and I'm not magic. Does the movement routine use what's in RAMbuffer2? Because you've just changed how it works, and any other code that uses it also needs to updated to reflect that.

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Wed Mar 06, 2013 2:52 pm

Kasumi wrote:You would also need to change this:

Code: Select all

     dex
     stx t2
      bne -- 
to this

Code: Select all

     dex
     stx t2
      bpl -- 
Otherwise it never actually does 0. Whether or not that will fix the falling issue, I don't know. You've never posted that code, and I'm not magic. Does the movement routine use what's in RAMbuffer2? Because you've just changed how it works, and any other code that uses it also needs to updated to reflect that.
I know you aren't magic. Thank you for noticing bne-to-bpl that fixed part of it! :D I kept thinking of other code needing to be updated and found two things that probably fixed the other part of it before reading your response. My brain is working today! :D

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Fri Mar 08, 2013 5:27 pm

ok... this is kind of weird...

Code: Select all

0C06A 58                        	cli
0C06B                           ;----------------------------END OF RESET----------------------------------
0C06B                           	; Transfer control to the GAME LOGIC routines.
0C06B                           
0C06B                           
0C06B                              ;initialize the flag to "false" 
0C06B A9 00                        lda #$00 
0C06D 85 21                        sta FrameReady 
0C06F                           
0C06F                           MainLoop: 
0C06F                           
0C06F                              ;DO THE GAME LOGIC HERE (i.e. movement, collisions, etc.) 
0C06F 20 2F C1                    jsr react_to_input
0C072 20 91 C3                    jsr collisionU
0C075                             
0C075 A6 0F                     	    		ldx aFrame
0C077 20 05 C4                  		jsr draw_sprite
0C07A                             ;  hope this will be some good cement. :)  tested... works good so far :D
0C07A EA                        nop
0C07B EA                        nop  ;ldx #$02
0C07C EA                        nop  ;ldy #$00
0C07D EA                        nop
0C07E 20 41 C4                    jsr draw_RAMbuffers ;left & right column
0C081                           		
0C081                             ;indicate that the frame calculations are done 
0C081 C6 21                       dec FrameReady 
0C083                           
0C083                           WaitForUpdates: 
0C083                              ;wait for the flag to change 
0C083 24 21                        bit FrameReady 
0C085 30 FC                        bmi WaitForUpdates 
0C087                           
0C087 4C 6F C0                  jmp MainLoop
So I added the ldx #$02 and ldy #$00 right above my jsr draw_RAMbuffers. Then was wondering why the attribute tables changed. Ok so then after a while of testing it appears to me that it doesn't really matter what those instructions are... as long as they equal 4 bytes... my attribute tables are changed!! :( This is a picture of the code with the changed attribute tables because of the 4 nops being 1 byte each. If there are 5 nops the attribute table is ok... if there are 3 nops it's ok. 4 nops before my jsr draw_RAMbuffers is messed up atttribute table. I'm lost... don't have a clue where to fix; dose anyone have a helpful thought they would like to share with me? :?

User avatar
Kasumi
Posts: 1292
Joined: Wed Apr 02, 2008 2:09 pm

Re: 8x16 sprite is really a 16x32 pixel image?

Post by Kasumi » Fri Mar 08, 2013 5:33 pm

So what's in draw_RAMbuffers? And your NMI?

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Fri Mar 08, 2013 11:33 pm

Code: Select all

0C441                             ;*******************************************************
0C441                             ; uses x for load_screen input... send value of screen to load in x
0C441                             ; uses y to pick a column (1 16x16 metatile wide).
0C441                             ;*******************************************************
0C441                             draw_RAMbuffers:
0C441                             ;"Prepare the (new nametable) writes in a RAM buffer during draw time..." tepples pg 59
0C441                                 
0C441 85 FF                     	  sta $ff
0C443 A2 02                     	  ldx #$02
0C445 20 24 C1                  	  jsr load_screen
0C448                           	  
0C448 A9 1D                     	  lda #29
0C44A 85 31                     	  sta t2
0C44C                           	  
0C44C                           	  ;tya
0C44C                           	  ;pha ;------->
0C44C A0 03                     	  ldy #$03
0C44E                           	  ;---
0C44E                           	  ;
0C44E B1 10                      --   lda ($10), y
0C450 AA                        	  tax 
0C451                            ;29  lda MetatileTile2, x
0C451 BD 52 C7                        lda MetatileTile2, x
0C454 48                        	  pha ;--->
0C455                            ;30  lda MetatileTile0, x
0C455 BD 94 C5                        lda MetatileTile0, x
0C458 A6 31                     	  ldx t2
0C45A 95 33                     	  sta RAMbuffer1, x
0C45C CA                        	  dex
0C45D 68                        	  pla ;<---
0C45E 95 33                     	  sta RAMbuffer1, x
0C460                           
0C460 98                        	  tya
0C461 18                        	  clc
0C462 69 10                     	  adc #$10 ;increment y by 16!!!!
0C464 A8                        	  tay
0C465                           	
0C465 CA                        	  dex
0C466 86 31                     	  stx t2
0C468 10 E4                     	  bpl -- 
0C46A                           	  
0C46A                           	  
0C46A A9 1D                     	 lda #29 ;need to reset t2 back up to #29
0C46C 85 31                     	 sta t2
0C46E                           	  
0C46E                           	 ;pla ;<--------
0C46E                           	 ;tay
0C46E A0 03                     	 ldy #$03
0C470                           	  ;---
0C470 B1 10                      --   lda ($10), y
0C472 AA                        	  tax 
0C473                            ;29  lda MetatileTile3, x
0C473 BD 31 C8                        lda MetatileTile3, x
0C476 48                        	  pha ;--->
0C477                            ;30  lda MetatileTile1, x
0C477 BD 73 C6                        lda MetatileTile1, x
0C47A A6 31                     	  ldx t2
0C47C 95 51                     	  sta RAMbuffer2, x
0C47E CA                        	  dex
0C47F 68                        	  pla ;<---
0C480 95 51                     	  sta RAMbuffer2, x
0C482                           	  
0C482 98                        	  tya
0C483 18                        	  clc
0C484 69 10                     	  adc #$10  ;increment y by 16!!!!
0C486 A8                        	  tay
0C487                           	  
0C487 CA                        	  dex
0C488 86 31                     	  stx t2
0C48A 10 E4                           bpl -- 
0C48C                           
0C48C                           	  
0C48C 60                        	  rts ;end of draw_RAMbuffers
And here is my mni: (vblank... this is my vblank procedure and scrolllandiii, at the end, is just some more scrolling-vblank-type prcedures; do you need those too?)

Code: Select all

   
vblank: inc FRAME_CNT

;skip the video updates if the frame calculations aren't over yet 
   bit FrameReady 
   bpl SkipUpdates 

   ;PERFORM VIDEO UPDATES HERE 
  jsr update_sprite
  jsr update_vram  



   ;modify the flag 
   inc FrameReady 
   
  

SkipUpdates: 

   ;PERFORM TASKS THAT MUST BE PERFORMED EVEN 
   ;WHEN THE FRAME IS NOT READY, SUCH AS UPDATING 
   ;THE MUSIC OR DRAWING A STATUS BAR 
    jsr FamiToneUpdate
;"Setting the scroll should ALWAYS be the very last thing in your VBlank handler." -tokumaru pg 43
  jsr scroll_screen 

   ;return from the NMI (vblank) 
   rti

;^ that's the end of my vblank: procedure... what follows are some vblank-type procedures...


update_sprite:
		lda #>sprite
        sta $4014 ;OAM_DMA register ; Jam sprite page ($200-$2FF) into SPR-RAM

                      ;takes 513 cycles.
					  
        rts
		
.enum LocalVariables4vblank

  tE .dsb 2
.ende

update_vram: ;testing... works grandly :)
        lda my_copy_of_last_write_to_PPUCTRL
		ora #00000100b  ;change $2007 increment to +32
		sta PPUCTRL0
		sta my_copy_of_last_write_to_PPUCTRL
		
		lda #$20
		sta PPUADDR6
		lda #$00
		sta tE
		sta PPUADDR6
		
		ldx #29 ;should hold last spot written to RAMbuffer. each column is always full so #29 1XNJJ8WY
	-	lda RAMbuffer1, x
		sta PPUDATA7
        dex
		bpl -
          ;this part should hold the increase +1 (moves over to next column) for tE, I think...
	      inc tE
		  lda #$20
		  sta PPUADDR6
		  lda tE
		  sta PPUADDR6
        ldx #29
	-	lda RAMbuffer2, x
		sta PPUDATA7
        dex
		bpl -

				
        rts ;end of update_vram.

.include "daprg-scrolllandiii.asm"
Hope this helps... :)

edit: Sorry this is a bit late... it's Saturday morning right now... time for sleep.

User avatar
Kasumi
Posts: 1292
Joined: Wed Apr 02, 2008 2:09 pm

Re: 8x16 sprite is really a 16x32 pixel image?

Post by Kasumi » Sat Mar 09, 2013 12:32 am

Beats me. My guess is it's because you're not saving your registers in the NMI routine?

The NMI can interrupt your code at any time. If it changes the value in a register, the "wrong" value (i.e. a value that the code the NMI interrupted doesn't expect) will be there when it returns. To avoid this, just push the values of all the registers to the stack right at the beginning, and then pull them all at the end of the interrupt before the RTI.
Like this:

Code: Select all

vblank: 
pha
tya
pha
txa
pha

inc FRAME_CNT
;skip the video updates if the frame calculations aren't over yet
   bit FrameReady
   bpl SkipUpdates
And at the end...

Code: Select all

   ;return from the NMI (vblank)
   pla
   tax
   pla
   tay
   pla
   rti
If that's not it, I'm not sure I can find anything else.

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Sat Mar 09, 2013 2:57 pm

Kasumi wrote:Beats me. My guess is it's because you're not saving your registers in the NMI routine?

The NMI can interrupt your code at any time. If it changes the value in a register, the "wrong" value (i.e. a value that the code the NMI interrupted doesn't expect) will be there when it returns. To avoid this, just push the values of all the registers to the stack right at the beginning, and then pull them all at the end of the interrupt before the RTI.
Like this:

Code: Select all

vblank: 
pha
tya
pha
txa
pha

inc FRAME_CNT
;skip the video updates if the frame calculations aren't over yet
   bit FrameReady
   bpl SkipUpdates
And at the end...

Code: Select all

   ;return from the NMI (vblank)
   pla
   tax
   pla
   tay
   pla
   rti
If that's not it, I'm not sure I can find anything else.
Woah, ok, yes!!! Thank you 500 percent Kasumi! :D You are very wise and thank you for sharing your wisdom with me.

edit.

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Mon Mar 11, 2013 4:54 pm

When drawing columns while scrolling... is this the correct way to think about construction of my 16-bit level?

I should make sure to draw columns at the beginning of nametable 0 nearing the end of nametable 1 so that it appears to scroll the screen to the right into a new nametable (nametable 0). Is thinking like this bad? My level is some-how wider than the two nametables... but I dont understand how to start the next 3rd screen. I'm lost. :(

tepples
Posts: 22014
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: 8x16 sprite is really a 16x32 pixel image?

Post by tepples » Mon Mar 11, 2013 5:00 pm

unregistered wrote:I should make sure to draw columns at the beginning of nametable 0 nearing the end of nametable 1 so that it appears to scroll the screen to the right into a new nametable (nametable 0). Is thinking like this bad?
Not bad at all. Look at this example from "PPU scrolling" on the wiki:

Image

At the top is the nametables; at the bottom is the visible portion of the background. Columns of tiles are rewritten (symbolized by columns of ? blocks) during vertical blanking just before the visible area (symbolized by the red bracket) moves into them.

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Mon Mar 11, 2013 5:48 pm

So, that makes sense! Thank you tepples! I will try to make it work like that... have to draw four columns at a time... right now I can draw two columns at a time. Then I have to wait for a new frame so the two columns can be replaced. Is it better to draw four columns at a time?

tepples
Posts: 22014
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: 8x16 sprite is really a 16x32 pixel image?

Post by tepples » Mon Mar 11, 2013 6:13 pm

unregistered wrote:I will try to make it work like that... have to draw four columns at a time
You don't need to draw more than one column at a time. I just showed four because it makes the GIF clearer. SMB1 actually draws four columns, one at a time, and then fills the attributes for those columns.

User avatar
tokumaru
Posts: 11749
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 8x16 sprite is really a 16x32 pixel image?

Post by tokumaru » Mon Mar 11, 2013 8:45 pm

tepples wrote:You don't need to draw more than one column at a time.
Actually, the number of columns you need to draw depends on how much you scroll each frame. Most games don't scroll any faster than 8 pixels at a time, so they can get away with updating only 1 column at a time. To scroll up to 16 pixels from one frame to the next, you need to update 2 columns, and so on.

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Tue Mar 12, 2013 3:04 pm

Thank you incredibly much tepples and tokumaru! :D


I'm gonna try scrolling less than 16 pixels per frame. So two 8bit columns they are already drawn correctly... must color them. This code appears to be very complex... to color them correctly. So far I've chosen to keep the incrament increment +32...

Code: Select all

set 2006 to 23C0
Write to 23C0... 
and to 23E0
set 2006 to 23C8
write to 23C8...
and to 23E8
set 2006 to 23D0
write to 23D0...
and to 23F0
set 2006 to 23D8
write to 23D8...
and to 23F8
ok...so I guess if it is susposed to work like tepples' graphic it will be written something like...
umm... ...

Code: Select all

lda $2007
and #11001100b
ora tileA
ora tileC
sta $2007
or

Code: Select all

lda $2007
and #00110011b
ora tileB
ora tileD
sta $2007
edit: ^...depending on wheather whether the $2006 address is odd or even. So after writing the 2 8bit columns will there be any attribute table suprizes when scrolling the screen?

unregistered
Posts: 1071
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: 8x16 sprite is really a 16x32 pixel image?

Post by unregistered » Thu Mar 21, 2013 4:15 pm

Ok, so finally... I'm making rules and choices about drawing a new column to the screen. If it is an even column I'll have to find the new palette values for AA and CC... and I guess get the values already on the screen for BB and DD. How do I get those old values? I can read from $2007... but how do I specify the address? :? (I know the address increments by 1 or 32 after each write to $2007.)

Post Reply