It is currently Mon Oct 23, 2017 1:17 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2
Author Message
 Post subject:
PostPosted: Sun May 22, 2005 9:25 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1390
Muchaserres wrote:
So now, instead of having a "if(address>=0x8000){writetomapper(address,byte);}" I have to "writetomapper(address,byte);" every time a write occurs. My question here is: how are you dealing with this problem? or, is it there a better/faster/smarter way of doing this?


This is pretty much the same way I handle it, except instead of having a 'writetomapper(addr,val)' I have 16 'writeToBank()' function pointers, one for each of $x000-$xFFF (and another set for reads). By default, all of them are set up for system RAM (0000-1FFF), PPU I/O (2000-3FFF), APU I/O (4000-4FFF, though the upper space just attempts to read/write from ROM), and ROM for the rest; when each mapper loads, it simply overrides the default I/O handlers to use its own behavior when reading/writing certain addresses (keeping track of the previous handler for registers at $4xxx so sound/controllers still work).

Muchaserres wrote:
On the other hand, I'm still having problems with Romancia_(J). It shows garbage on title screen.. but I'm almost sure that my MMC1 implementation is oK. Suggestions?


Do you support CHR RAM bankswitching? If not, this would explain why you are having problems - the upper half of the screen swaps in the first 4KB CHR RAM bank at PPU $1000-$1FFF, then switches in the second bank to display the picture at the bottom.

Muchaserres wrote:
Also still having trouble with Bee_52_(U).. may it be missing IRQ handling?

Bee 52's mapper does not use IRQs; rather, the game uses DPCM IRQs as a scanline timer (Fire Hawk also does this) and requires very precise emulation to get it to display just right.

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 22, 2005 12:09 pm 
Offline

Joined: Sat Nov 13, 2004 6:25 am
Posts: 96
Quietust wrote:
This is pretty much the same way I handle it, except instead of having a 'writetomapper(addr,val)' I have 16 'writeToBank()' function pointers, one for each of $x000-$xFFF (and another set for reads). By default, all of them are set up for system RAM (0000-1FFF), PPU I/O (2000-3FFF), APU I/O (4000-4FFF, though the upper space just attempts to read/write from ROM), and ROM for the rest; when each mapper loads, it simply overrides the default I/O handlers to use its own behavior when reading/writing certain addresses (keeping track of the previous handler for registers at $4xxx so sound/controllers still work).


Neat!

Quietust wrote:
Do you support CHR RAM bankswitching? If not, this would explain why you are having problems - the upper half of the screen swaps in the first 4KB CHR RAM bank at PPU $1000-$1FFF, then switches in the second bank to display the picture at the bottom.


I do so with CHR ROM. I guess the problem is that I'm not doing it when there's no CHR banks. I'll check that.

Quietust wrote:
Bee 52's mapper does not use IRQs; rather, the game uses DPCM IRQs as a scanline timer (Fire Hawk also does this) and requires very precise emulation to get it to display just right.


OK, I'm not emulating the APU yet, so this must be the problem.

Thanks for the quick answer!


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 26, 2005 8:31 am 
Offline
User avatar

Joined: Thu Mar 24, 2005 3:17 pm
Posts: 355
The titlescreen in Romancia looks fine here, but it's got problems in-game: the statusbar is garbaged, and scrolls along with the playfield.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jul 31, 2005 3:12 am 
Offline

Joined: Sat Nov 13, 2004 6:25 am
Posts: 96
Hi all,

So, having some free time this days, I've decided to start implementing the APU into my emu. The first part of it which I am dealing with is DMC, as implementing it will increase my emu's compatibility (cause of IRQ/DMA's, you know). But I'm quite far from understanding how this unit works. I've read several APU docs, but I'm quite lost.. So, is it there any "let's learn how it works step by step" doc, or THE doc, which I could use to get an overall idea about how thinks work?

Thx.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jul 31, 2005 8:20 am 
Offline
User avatar

Joined: Thu Mar 24, 2005 3:17 pm
Posts: 355
APU emulation without actual sound output is not hard to get running. I think the wiki ( http://nesdev.com/wiki/?page=nesdevWiki )covers it well, plus blargg's new information a few threads back (thanks blargg).

The problem historic hap above you is blabbing about will be fixed with DMC implementation.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 8:43 am 
Offline

Joined: Sat Nov 13, 2004 6:25 am
Posts: 96
OK, so I'll read those sources carefully.

Just one question: as with the PPU, is it there any list of the APU operation on each of its cycles? I mean, how does the APU know what it has to do on each (let's say) CPU cycle?

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 11:53 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
The closest to this is the frame counter, which times note durations and the volume fading. The APU is basically a collection of many independent units, each generally running all the time, so there isn't a master table of operation. This should be expected since each sound channel must be separate from the others. But even within a sound channel, each sub-unit generally runs at its own rate. Sound is controlled by switching the connections between units on and off, and changing the input parameters. In hardware it's usually easier to simply ignore the output of something than switch it off, so things run all the time.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 3:54 pm 
Offline

Joined: Sat Nov 13, 2004 6:25 am
Posts: 96
So, what should be done to keep everything synchronized? I mean, the simplest NES emulator core would run the CPU for some cycles, then the PPU for the equivalent cycles, and then the APU. Should "RunAPUCycles()" just increment/decrement counters? And, if so, how many units per CPU cycle?

Thx again.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 7:44 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
The APU only needs to be run when its side-effects matter. The simplest implementation is to run the APU up to the current CPU time whenever the CPU reads or writes to an APU register, when your emulator needs more samples, and when the APU takes a special action on its own.

The special actions the APU carries out are the frame IRQ, DMC IRQ, and DMC wait-states when reading a sample byte. These are somewhat complex to implement properly. They can be efficiently handled by calculating the timestamp of the next APU-generated event, and avoiding running the CPU beyond this. This timestamp might change after an APU write or after one of these events occurs.

I've found it simplest to use a common timebase that is periodically re-zeroed (to prevent overflow). This could be done at the beginning of vertical blanking each frame. In my APU the read and write functions take the timestamp. The APU keeps track of the last time it was run to, allowing it to determine how many clocks it needs to run to catch up to present. It's better to keep this calculation in one place in the APU rather than make the calling code keep track of it.

Within the APU, functions take a count of the number of clocks to run for. They generally contain a loop that emulates the various dividers in the APU. When a divider reloads, the event is emulated. This might clock another unit, usually handled with a clock_x() function.

When I first wrote an APU emulator, I implemented only the frequency of the first square channel. No volume, frame counter, nothing else. It was enjoyable to hear the basic tune once it worked.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 07, 2005 9:30 am 
Offline

Joined: Sat Nov 13, 2004 6:25 am
Posts: 96
In order to do things like that, I'm now modifying my emu so it uses a master timer, as Disch (?) proposed some time ago. My question here is: have any of you had any major problems when recoding your emus that way? Or, what should be changed in the way the emu works? I mean, mine is actually cycle-accurate an runs every game (almost) perfectly, but when rewritting its parts to fit the new scheme (using ideas from other posts), all games get glitchy. I may be missing something. I'm actually multiplying PPU cycles by 5 and CPU cycles by 15, I hope I'm right at least with that.


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

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