It is currently Fri Nov 24, 2017 12:39 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon Sep 11, 2006 5:33 am 
Offline

Joined: Tue Jul 11, 2006 10:12 am
Posts: 60
Hi

I get Error #4 (Pattern B--B- (one even, one odd) should skip 1 clock)
I can only about two things that it may depend on

1. What iam doing is in wrong order...
This is what my emulate-sequence look like:

1. Call NMI (if enabled)
2. Run 6820 PPU cycles (I don't have a CPU cycle counter, only PPU)
3. Clear Status flags (vbl, spritehit, overflow)
4. Add one cycle to the PPU clock if its an odd frame and BG enabled
5. Set up sprites for the frame
6. Run up to 89342 cycles

2. if the cycle counter overflow I call the instruction anyway, is it important to first find out how many cycles the instruction will take, then call it if its enough time left?

What happens if a 6 CPU cycle instruction appears at 89340, is it executed after NMI? In order to pass the timing tests is this important?

thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 10:26 am 
Offline

Joined: Fri Jul 29, 2005 3:40 pm
Posts: 345
Location: near chicago
looks like you got the idea. you might have to explain more on how your ppu work, and how the cpu is run.

matt


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 11:12 am 
Offline

Joined: Tue Jul 11, 2006 10:12 am
Posts: 60
Well.. What I need to know is:

1. is NMI called in the beginning of a frame or at the end.
2. is all instructions performed at its very last cycle, and like my earlier example, if half an instruction is executed before NMI is its "action" made directly after NMI in this case? is this true for all opcodes, CLI is different huh? but what about the others...

Since I always let the instruction to be executed even if it should be right after NMI, may this cause errors in timing?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 11:23 am 
Offline

Joined: Fri Jul 29, 2005 3:40 pm
Posts: 345
Location: near chicago
n6 wrote:
1. is NMI called in the beginning of a frame or at the end.
the term frame is kinda misleading. what do you mean by frame? i assume its the 20 scanlines of vblank, 1 pre line, 240 drawing lines, and 1 post line. nmi would happen inbetween the last cycle of the post line and the first cycle of vblank. so the answer is yes to your OR question. it happens at the begining and at the end because they are the same.
n6 wrote:
2. is all instructions performed at its very last cycle, and like my earlier example, if half an instruction is executed before NMI is its "action" made directly after NMI in this case? is this true for all opcodes, CLI is different huh? but what about the others...
i dont understand what you are asking. well, maybe... blargg just posted something about this, when the cpu checks the nmi or irq, might look at recent post

matt


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 12:04 pm 
Offline

Joined: Tue Jul 11, 2006 10:12 am
Posts: 60
Quote:
the term frame is kinda misleading. what do you mean by frame? i assume its the 20 scanlines of vblank, 1 pre line, 240 drawing lines, and 1 post line. nmi would happen inbetween the last cycle of the post line and the first cycle of vblank. so the answer is yes to your OR question. it happens at the begining and at the end because they are the same.


yeah thats what I wondered, thanks!

Quote:
i dont understand what you are asking. well, maybe... blargg just posted something about this, when the cpu checks the nmi or irq, might look at recent post


some psuedo code might help.

My way:

do
{
RunNextOp();
PPUClock += OpCycles();
} while (PPUClock < 89xxx)

probably the right way:

while (1)
{
PPUClock += OpCycles();
if (PPUClock < 89xxx)
RunNextOp();
else
{
// Find out how many cycles that are left of the current instruction and
// run it after NMI
break;
}
}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 12:14 pm 
Offline

Joined: Fri Jul 29, 2005 3:40 pm
Posts: 345
Location: near chicago
you might have a problem with the ppu cycle in the cpu instruction. since the ppu is (ntsc) 3 times faster then the cpu, and the average cpu instruction is about 4 cycles long, that leaves 3 * 4 = 12 possible values to be read from if the cpu was reading a ppu register. so are you rounding your reads and writes to the intruction boundary? or updating on the exact ppu cycle ?

i have a cpu clock and a ppu clock. i run the cpu till predicted nmi or irq. and catch up the ppu where needed. this works, i might change it alittle, but i think it will always be a catch-up. and i dont lock mine to render frames because i might use the sound call back some day for timing. and the sound call back might never line up with the render frame.

also, i posted a while ago about save states. i took that into consideration too. so i can pause my emulation on a save frame.

sucks that search is STILL broke, but there is alot of info in the old posts.

matt


Last edited by mattmatteh on Mon Sep 11, 2006 12:38 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 12:34 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Since the first two sub tests of 3.even_odd_frames.nes passed, it suggests something more subtle is going on. Test 2 keeps BG disabled the whole time, and passes. Test 3 enables BG for two consecutive frames, then disables it, and expects that only one PPU clock was skipped. Test 4, which fails, enabled BG for one frame, disables it for two, then enables it for one more frame, also expecting only one PPU clock to be skipped.

Oh, wait, maybe I'm assuming too much again. Have you verified that 1.frame_basics.nes and 2.vbl_timing.nes both pass? Ugh.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 1:27 pm 
Offline

Joined: Tue Jul 11, 2006 10:12 am
Posts: 60
Yeah. both pass! But isnt it possible for example that you read the status register at PPU clock 89341 and I get error cause this read is finished before NMI or something like that.

btw, do all instructions do their thing at its last cycle? if NMI is triggered inside an instruction, where is the programcounter? pointing to the instruction, the parameter, the next instruction or does it depend on how far the instruction have come (in cycles)?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 1:34 pm 
Offline

Joined: Fri Jul 29, 2005 3:40 pm
Posts: 345
Location: near chicago
n6 wrote:
do all instructions do their thing at its last cycle?
what do you mean by your thing ? i think you mean when does the read or write occur? if so then that is what i was trying to explain in my last post. you need to determine the exact ppu cycle a ppu register is read on. you can not round that to the end of the instruction.

matt


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 1:39 pm 
Offline

Joined: Tue Jul 11, 2006 10:12 am
Posts: 60
Yeah but what I mean is... LDA $2002 for example, when do the read occur? it takes 12 CPU Cycles to run but at which cycle is the value catched? isnt this the same even if its WRAM or mapper or whatever?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 1:52 pm 
Offline

Joined: Fri Jul 29, 2005 3:40 pm
Posts: 345
Location: near chicago
a link from the wiki: http://users.telenet.be/kim1-6502/6502/proman.html


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 4:17 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
LDA $2002:

1: Read opcode
2: Read low byte of address
3: Read high byte of address
4: Read from $2002

There's also a fifth cycle, but this is overlapped with the opcode fetch for the next instruction so it's usually ignored. The NMI and IRQ lines are checked during cycle 3 in the above example. If either is set, then the interrupt will occur after the instruction finishes, and the program counter saved on the stack will be for the next instruction.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 5:19 pm 
Offline

Joined: Tue Jul 11, 2006 10:12 am
Posts: 60
I see interesting.. so if it's less then 3, the opcode is executed after NMI? and the program counter points to?

since the opcode is finished in the 3 or above case, do this mean that the opcode restarts if its less then 3?

Is there a complete table of where NMI/IRQ checks are made for each op code?

thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 6:50 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
All interrupts occur between completely executed instructions; an instruction is never interrupted before completion. The saved program counter on the stack is where execution should continue once the interrupt has been handled. My tests indicate that it's always the second from last cycle of an instruction that the IRQ/NMI inputs are examined, or the next-to-last cycle if you're ignoring the final cycle that's overlapped with the opcode fetch of the next instruction. This checking is effectively two cycles before it takes effect, so if IRQ/NMI is asserted in the third cycle of LDA in the example above, then an interrupt will occur after LDA completes.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 12, 2006 4:58 am 
Offline

Joined: Tue Jul 11, 2006 10:12 am
Posts: 60
Okey.. last question...

if it just one cycle left until NMI when an LDA $2002 appears, is it ignored? and just executed after NMI?

opcodes that take different time like branches.. are NMI/IRQ checked at different places depending on if it takes 2 or 4 cycles?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

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