It is currently Tue Nov 21, 2017 2:58 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Jun 05, 2016 3:29 am 
Offline

Joined: Sun Jun 05, 2016 3:02 am
Posts: 9
If my instructions don't take the exact cycles/time as documented (but close..), how disastrous would the emulation be ?


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 4:18 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
Depends on your goals. You will be able to run a lot of games even with an inaccurately timed CPU.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 5:13 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3075
Location: Brazil
As far as I can tell you, the CPU emulation doesn't require a cycle counter. Just do all the required steps for each instruction, like reads/writes, setting flags etc. The accuracy is there. On other side, the PPU communicates directly with the CPU - it sets flags like VBlank, NMI and so on. All of these things are necessary for the CPU running "to be possible".
In short words, the PPU emulation is linked with the CPU, cannot work alone.


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 6:02 am 
Offline

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 299
A while back, I had a bug in the "instruction takes an extra cycle if a page is crossed" logic, for indirect X & Y addressing.

This caused a small portion of instructions to sometimes take an extra cycle - this broke at least 2 games that I was aware of (and in reality it probably broke a lot more than this).
In elevator action, the extra cycles caused the NMI handler to take too many cycles, and it couldn't finish before the next frame started drawing, causing pretty obvious scrolling bugs on the screen. It also caused Battletoads to do its typical freeze at the start of level 1, because of a missed sprite 0 hit.

So it seems like even a minor error in the amount of cycles an instruction takes can cause bugs in a good amount of games.


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 6:12 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3950
If you want to run Battletoads without a shaky screen/crashes, you need to have the instructions take the proper number of cycles, including page crossing penalties.

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


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 6:24 am 
Offline

Joined: Sun Jun 05, 2016 3:02 am
Posts: 9
Thank you for all the responses!
I am going to first get a basic CPU running and care later about the cycle accuracy.

Quote:
A while back, I had a bug in the "instruction takes an extra cycle if a page is crossed" logic, for indirect X & Y addressing.

This caused a small portion of instructions to sometimes take an extra cycle - this broke at least 2 games that I was aware of (and in reality it probably broke a lot more than this).


I had this doubt as well! So now I know it *does* matter.
BTW, can anyone verify this "check" if two addresses (a and b) are in different pages ?
Code:
(a % 0x100) != (b % 0x100)

I cannot find much information about "pages", so my logic went like this: Zero Page is 0x100 i.e. 256 bytes long thus that must be the size of a page, and the above is what I came up thinking if the pages are aligned.


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 7:29 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
No, it's not. It should be (a / 0x100) != (b / 0x100), or (a >> 8) != (b >> 8), or (a & 0xFF00) != (b & 0xFF00). Essentially you should be extracting the high 8 bits (= the page) from the addresses and comparing them.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 7:42 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3950
As for the question about how important cycle accuracy is...
Some people use the term "cycle accuracy" to mean emulating the stages of an instruction one by one, including the fetch, memory read, memory write, etc, and also emulating everything the PPU does during those stages. I think it's overkill, catching up significant events is good enough. As long as you get the timing correct for the read/write stage when external hardware is involved, it should be good enough. I actually cheat there and assume that it's always 12 dots from the start of the instruction to the read/write stage.
I think you just mean the correct number of cycles for instructions.

If you are running games which do not do any raster effects at all, such as Megaman and Megaman II, cycle accuracy doesn't matter much at all. Those are some of the simplest games to emulate, even more simple than Super Mario Bros.
But games will use sprite 0 hits, timed code, interrupts at specific PPU timings, and timed scroll writes in the middle of the screen, so getting the timing right for those events matters to avoid shaky screens and stuff.

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


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 8:42 am 
Offline

Joined: Sun Jun 05, 2016 3:02 am
Posts: 9
Quote:
Code:
(a / 0x100) != (b / 0x100)

Ah, yes, that's what I was meaning to code, I mistakenly put mod.
Also appreciate those binary shortcuts/alternatives.

Quote:
I think you just mean the correct number of cycles for instructions.

Yup, that's what I meant!
I'm just completing the entire instruction at one cycle, then skip/stall the remaining cycles. I hope that's good enough.

Also, this is just an education "for-fun" project, I am not aiming for perfect accuracy and 100% game coverage.


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 8:50 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3950
Even if you simulate the whole instruction at once, it might be better to advance the time by 12 dots before the PPU sees a write, because scrolling has such tight timing. The scrolling increment happens at dot 256 of a scanline, so you can treat it as if it happens 12 dots sooner and still avoid most scrolling glitches.

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


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 9:16 am 
Offline

Joined: Sun Jun 05, 2016 3:02 am
Posts: 9
What do you mean by a dot ?
A "pixel" in NES ?

P.S. I've only started with the CPU, haven't touched the PPU or any other part yet.


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 9:49 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3950
On the NTSC NES, for every 1 CPU cycle executed, the PPU draws 3 pixels. Sometimes they are called PPU cycles, sometimes they are called dots.
NTSC NES has 240 visible scanlines, 1 pre-vblank line, 20 vblank lines, and 1 pre-render line. Each scanline is 341 dots wide, the visible area is 256 pixels.
This makes for a total of 341*262 (89342) PPU cycles, or 341*262/3 (29780.66...) CPU cycles per frame.

(On every other frame, one dot is skipped from the pre-render line if rendering is enabled.)

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


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 3:42 pm 
Offline
User avatar

Joined: Mon Feb 07, 2011 12:46 pm
Posts: 932
My own opinion is that the emulator is not really correct (even though it may be good enough for many things) if it doesn't have cycle accuracy. Each read/write must be done during the proper cycle, in order to properly interact with the mapper and PPU and APU and so on. Cycle accuracy is not as important for CPU register writes though, since as long as the new value of the registers is ready for the next instruction, it does not matter during exactly what cycle they are set. So for example, it is OK to read and do the correct calculation for the address and data as soon as possible, even though the next cycle does not necessarily use correct address/data; what matters is that the externally visible behaviour of all stable instructions matches what is seen on NMOS 6502 without decimal arithmetic. Due to the possibility that the PPU registers, APU registers, and mapper registers, might be touched in the middle of execution of an instruction, it must access them during the correct cycle, and the PPU and so on must know what cycle it is written during in order to time the rendering properly in case it touches them during rendering. But, what mechanisms exactly are used to implement this correct behaviour is up to you; there can be more than one possibility to do it.

_________________
.


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 7:27 pm 
Offline

Joined: Sun Jun 05, 2016 3:02 am
Posts: 9
@Dweddit

Thanks! I'll keep your "cheat" in mind.

zzo38 wrote:
My own opinion is that the emulator is not really correct (even though it may be good enough for many things) if it doesn't have cycle accuracy. Each read/write must be done during the proper cycle, in order to properly interact with the mapper and PPU and APU and so on. Cycle accuracy is not as important for CPU register writes though, since as long as the new value of the registers is ready for the next instruction, it does not matter during exactly what cycle they are set. So for example, it is OK to read and do the correct calculation for the address and data as soon as possible, even though the next cycle does not necessarily use correct address/data; what matters is that the externally visible behaviour of all stable instructions matches what is seen on NMOS 6502 without decimal arithmetic. Due to the possibility that the PPU registers, APU registers, and mapper registers, might be touched in the middle of execution of an instruction, it must access them during the correct cycle, and the PPU and so on must know what cycle it is written during in order to time the rendering properly in case it touches them during rendering. But, what mechanisms exactly are used to implement this correct behaviour is up to you; there can be more than one possibility to do it.


If I understand you correctly, only the PPU, APU and mapper registers need to touched in the proper cycle, the CPU registers. the ROM and the SRAM read-writes are malleable ?
I should say that I'm not really aiming for perfect emulation and 100% game coverage.


Top
 Profile  
 
PostPosted: Sun Jun 05, 2016 8:42 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19237
Location: NE Indiana, USA (NTSC)
amhndu wrote:
If I understand you correctly, only the PPU, APU and mapper registers need to touched in the proper cycle, the CPU registers. the ROM and the SRAM read-writes are malleable ?

Correct, with the proviso that some mappers "snoop" RAM writes by placing mapper registers at the same address as certain parts of RAM. This includes a few MMC1/MMC3 multicart mappers' outer bank registers as well as the bank registers in the NINA half of mapper 34. But so far, all such "snooping" that I'm aware of is not cycle sensitive.

amhndu wrote:
I should say that I'm not really aiming for perfect emulation and 100% game coverage.

So in other words, are you saying your project is type "a" (early stage) in this taxonomy?


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

All times are UTC - 7 hours


Who is online

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