It is currently Wed Dec 12, 2018 9:55 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 32 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Wed Feb 10, 2016 8:18 am 
Offline

Joined: Tue Jul 09, 2013 7:13 am
Posts: 61
ccovell wrote:
My old demos, Motion / Flame do this nametable double-buffering and flipping, if you want to check out the code for them (though ignore any bad coding practices that you find. ;-D)


I actually found that yesterday! It is super handy. Thanks for the heads up though. I am still really pretty new to coding so this is pretty tough for me. I am going to try and learn how each part of the code works to build up an understanding of what is actually happening. So I am approaching it in more or less the following steps

1 - Load a nametable and display it
2 - load content into different name tables
3 - load content into different name tables and switch between them every X frames
4 - load content into different name tables at 1024 bytes per frame and switch every X frames

I am going to save a little folder with code for each step so hopefully it can be useful for someone else learning down the road.

The ultimate goal is to make a little animation looping demo where different buttons will play the animation forward, backwards, ping pong, forward loop etc.


Top
 Profile  
 
PostPosted: Wed Feb 10, 2016 9:09 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4108
1024 bytes per frame is impossible, that's why we mentioned doing 128 bytes per frame instead.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Wed Feb 10, 2016 5:21 pm 
Offline

Joined: Tue Jul 09, 2013 7:13 am
Posts: 61
Dwedit wrote:
1024 bytes per frame is impossible, that's why we mentioned doing 128 bytes per frame instead.


Sorry! that was a total brainfart. I know it needs to be less. I even mentioned 128 earlier in the thread...


Top
 Profile  
 
PostPosted: Wed Feb 10, 2016 6:01 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7014
Location: Canada
You might be able to push 1024 bytes in a frame if it was mostly forced blank. Maybe if your image area was limited to 16 scanlines or so? ;)


Top
 Profile  
 
PostPosted: Thu Feb 11, 2016 5:42 am 
Offline

Joined: Tue Jul 09, 2013 7:13 am
Posts: 61
OK, so I have spent a bit of time working on this and I have managed to load a different simple picture into each name table. Up and down will select which name table is being displayed which is great. I know it isn't anything major but I am pretty pleased with myself up to this point.

Start should make the frame tables switch automatically every X frames but it will only switch once. It never switches back. I think this is probably the problematic bit of code. Would anyone be kind enough to take a look at it? I have been stumped for a couple of hours

Code:
animation:
   DEC framecounter
   BNE noanimation

        LDA nametableflag
   CMP #$0
   BNE flip
   LDA #%10001010 ;switch to first name table
        STA $2000   
   LDA #$1
   STA nametableflag


flip:
   LDA #%10001000 ;switch to second name table
        STA $2000   

   LDA framenumber
   STA framecounter

noanimation:
        jmp animationover



I have included a pastebin of the full code just in case.

http://pastebin.com/nf1sCN4X


Top
 Profile  
 
PostPosted: Fri Feb 19, 2016 8:23 pm 
Offline

Joined: Tue Jul 09, 2013 7:13 am
Posts: 61
Just in case it is useful for someone in the future, I fixed the problem. I used this code

Code:
animation:
   DEC framecounter
   lda framecounter
   CMP #$00
   BNE noanimation

        LDA nametableflag
   CMP #$0
   BEQ flip
   LDA #%10001010 ;switch to first name table
        STA $2000   

   JMP postflip

flip:
   LDA #%10001000 ;switch to second name table
        STA $2000   

postflip:

   LDA framenumber
   STA framecounter

   LDA nametableflag
   EOR #$01
   STA nametableflag

noanimation:
        jmp animationover


But the main problem is I forgot to declare the framenumber variable!


Top
 Profile  
 
PostPosted: Sat Feb 20, 2016 10:46 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3723
Location: Mountain View, CA
You don't need either of the cmp #$00 / cmp #$0 statements. The preceding lda statements will set the zero flag if the value loaded is zero or not.


Top
 Profile  
 
PostPosted: Sat Feb 27, 2016 5:37 am 
Offline

Joined: Tue Jul 09, 2013 7:13 am
Posts: 61
I am sorry to bug everyone again, I have done a fair amount of work on the code and I THINK I am loading information into alternating name tables and loading alternate name table each frame, but I still have a flash between frames.

This is the code I am using to write to the alternating name tables. Could this be the cause?

Also a couple of people mentioned I should try loading the code 128 bytes per frame but I haven't figured that out just yet. Would that be the cause of the problem?

Code:
DrawScreen:

   LDA nametabletoggle
;   cmp #0
   BNE nametable2000

nametable2c00:

      LDA #$2c                ; set to beginning of first nametable
       STA $2006
       LDA #$00
       STA $2006
   jmp startdrawing

nametable2000:

      LDA #$28                ; set to beginning of second nametable
       STA $2006
       LDA #$00
       STA $2006
   jmp startdrawing

startdrawing:

        LDY #$00
        LDX #$04

NameLoop:                       ; loop to draw entire nametable
        LDA ($10),y
        STA $2007
        INY
        BNE NameLoop
        INC $11
        DEX
        BNE NameLoop

   LDA nametabletoggle
   EOR #$01
   STA nametabletoggle

        RTS


Here is the full code http://pastebin.com/TDH3hb32

The rom animates through 10 "frames" when you press start. I know it isn't super impressive but I happy I have got it this far!

Also the animation timing code wasn't written by me, it was a gentleman called nickmaynard who posted it on another forum quite a while back.



koitsu wrote:
You don't need either of the cmp #$00 / cmp #$0 statements. The preceding lda statements will set the zero flag if the value loaded is zero or not.


Thanks very much, I have removed them!

edit : attached the wrong file...


Attachments:
nesanimation.nes [40.02 KiB]
Downloaded 78 times
Top
 Profile  
 
PostPosted: Sat Feb 27, 2016 6:24 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2354
Location: DIGDUG
Well, you're transferring 1024 bytes at once. Which might look flickery in an emulator, but if done while rendering is on will corrupt the entire screen on real hardware. (As you will be attempting to write to PPU at the same time it's trying to fetch data)

Plus...maybe it looks like an efficient loop...but you really have very very small time during V-blank...you can only transfer 130-180 bytes per V-blank (difference depending on whether or not you do Sprite DMA) with this loop.

With more efficient code, you could squeeze 256 bytes per frame, but for now, maybe stick to 128 bytes per frame.

With your current system... maybe...

Code:
startdrawing:

        LDY #$00

NameLoop:
        LDA ($10),y
        STA $2007
        INY
        BPL NameLoop


Would transfer 128 bytes.

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


Last edited by dougeff on Sat Feb 27, 2016 6:50 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sat Feb 27, 2016 6:45 am 
Offline

Joined: Tue Jul 09, 2013 7:13 am
Posts: 61
dougeff wrote:
Plus...maybe it looks like an efficient loop...but you really have very very small time during V-blank...you can only transfer 130-180 bytes per V-blank (difference depending on whether or not you do Sprite DMA) with this loop..


Thanks I will work on that and report back!

Would the best way to do that be spend 8 frames transferring 128 bytes per frame, set a after the 8th frame , check for the flag during vblank and then transfer?


Top
 Profile  
 
PostPosted: Sat Feb 27, 2016 7:13 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2354
Location: DIGDUG
Rainwarrior said:
Quote:
You might be able to push 1024 bytes in a frame if it was mostly forced blank.


I can't think of a reliable way to time this, unless you ran the exact same code from the start of V-blank every frame (and had rendering off during the transfer)...you can't do a sprite zero hit with rendering off... But, even a conditional branch might be enough to throw you off a scanline, and you'd get screen jitter.

Maybe you could turn redering off about 1/4 from the bottom of the screen, timed with a sprite zero hit.

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


Top
 Profile  
 
PostPosted: Sat Feb 27, 2016 9:40 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7014
Location: Canada
It was not a serious suggestion, dougeff, but yes if you want predictable timing you can either write code with no branches, or account for all branches. It's not that hard to deal with, a branch taken is 1 more cycle than a branch not taken, so if you want both paths to be the same you just add that extra cycle to the branch-not-taken path. It's entirely doable to write long stretches of precisely timed code (e.g. Rad Racer, Big Bird's Hide and Speak, SuperNSF, etc.). It's a lot more tedious than it is difficult (you can use a debugger to count cycles for you).


Top
 Profile  
 
PostPosted: Fri Mar 11, 2016 7:06 pm 
Offline

Joined: Tue Jul 09, 2013 7:13 am
Posts: 61
So I have been looking at Ccovell's motion demo which seems to do exactly what I am trying to do. Seriously thanks for making the source available it is super helpful.

http://nesdev.com/anims.zip

I have converted it to ASM6 which compiles (yay!) and it is displaying content on the screen in the right colors and it seems to be loading 96 bytes per frame and switching name tables which is great. However there are a couple of problems.

1 - According to the PPU viewer in FCEUX It seems that data being written to the PPU looks corrupt

2 - The data written by the screen also looks corrupt.

So rather than nice smooth animation I am just getting kind of trippy glitches which is kind of cool but obviously not what I was hoping for.

Would anyone be kind enough to take a look for me?


Attachments:
nesanimation.zip [63.21 KiB]
Downloaded 68 times
Top
 Profile  
 
PostPosted: Fri Mar 11, 2016 10:18 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2354
Location: DIGDUG
Here's what's wrong...

clear memory routine is broken.

X = $ff
A = $80 ...only does one pass and puts $80 in xff addresses.

-add...
Code:
inx
lda #0

...before clear memory

why 'clear PPU' loop starts at $2400 and not $2000
-change to $20 for first sta 2006

use of the 'forbidden' $0d black, probably fine...I prefer $0f

locating cmcmap after the vectors, the assembler has them listed at address $0000, which is the RAM, nothing is there.
-relocate cmcmap somewhere in the ROM between the code and the vectors...

motion.nam is not a binary file, you should use .include not .incbin


Actually, it was really easy to make these changes to the source code...it looks pretty good to me...


Attachments:
N2.zip [22.27 KiB]
Downloaded 65 times

_________________
nesdoug.com -- blog/tutorial on programming for the NES
Top
 Profile  
 
PostPosted: Fri Mar 11, 2016 10:20 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2354
Location: DIGDUG
Here's a screenshot.


Attachments:
N2.png
N2.png [ 2.08 KiB | Viewed 2105 times ]

_________________
nesdoug.com -- blog/tutorial on programming for the NES
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 32 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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