Newbie to emulation questions

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
kyuusaku
Posts: 1665
Joined: Mon Sep 27, 2004 2:13 pm

Newbie to emulation questions

Post by kyuusaku »

What's the simplest way of implementing a dynamic memory map? An [0x2][0x10000] array of pointers? (64k for reads/writes)

Is there any good reason to implement a cycle stepping CPU? (Disregarding performance)

Where can I surf to learn about basic electronic music theory which might pertain to games/emulation? I know next to nothing about music.

What's the best way to generate timing for an emulator without too much overhead? How do obsolete emulators do it?

Are there alternatives to DirectInput or is it all the same in the end like DirectSound?

What happens in the case of a PPU bus conflict?

If the PPU reads from unmapped memory, will it return the last byte on the bus like the CPU?

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

Re: Newbie to emulation questions

Post by tepples »

kyuusaku wrote:What's the simplest way of implementing a dynamic memory map? An [0x2][0x10000] array of pointers? (64k for reads/writes)
Try 16 pointers, each referencing a 4 KB bank, for reads, and 16 pointers for writes.
Is there any good reason to implement a cycle stepping CPU? (Disregarding performance)
What do you mean by "cycle stepping"?
Where can I surf to learn about basic electronic music theory which might pertain to games/emulation? I know next to nothing about music.
Google DSP tutorial.
Are there alternatives to DirectInput or is it all the same in the end like DirectSound?
My PC programs use the Allegro library, which abstracts over DirectInput, DirectDraw, and DirectSound, and their equivalents on other platforms.
What happens in the case of a PPU bus conflict?
When would such a conflict happen? And what do you think happens? There aren't any mappers with writable registers in PPU space, if that's what you're asking.
If the PPU reads from unmapped memory, will it return the last byte on the bus like the CPU?
In general, a mapper will map all 16 KB of the PPU address space: the first 8 KB to the cartridge and the rest to CIRAM.
User avatar
kyuusaku
Posts: 1665
Joined: Mon Sep 27, 2004 2:13 pm

Re: Newbie to emulation questions

Post by kyuusaku »

tepples wrote:Try 16 pointers, each referencing a 4 KB bank, for reads, and 16 pointers for writes.
With the large banks, how would you suggest I have byte precision for open bus/memory/io/ignore and bus conflict events? Why even 4KB banks? Apart from the APU registers everything is decoded in 8KB segments including every PRG ROM I've come across.
tepples wrote:What do you mean by "cycle stepping"?
Emulating the system at sluggishly low level similar to how I gather people are emulating the PPU, a state machine executing pseudo microinstructions for each cycle like the actual thing.
Google DSP tutorial.
I'm familiar with filters, sampling and DAC but envelopes, decay and arpeggio I'm pretty clueless about. These seem to be things people with a musical background take for granted. Must I give myself a more traditional musical background to understand say FM synthesis (which appears to be more instrument oriented)?
My PC programs use the Allegro library, which abstracts over DirectInput, DirectDraw, and DirectSound, and their equivalents on other platforms.
Thanks for the tip. I assume you prefer this to SDL; please tell me why. I have never used either.
When would such a conflict happen? And what do you think happens? There aren't any mappers with writable registers in PPU space, if that's what you're asking.
It would happen for example when a homebrew programmer indexes ROM with $2006 and writes to $2007. There aren't any mappers with writable registers in PPU space--yet. I'm just interested in the behavior, I wondered if the PPU would crash and if so, if it could be recovered by turning the PPU off then on again etc.
In general, a mapper will map all 16 KB of the PPU address space: the first 8 KB to the cartridge and the rest to CIRAM.
I know this but what if there was no CHR ROM, CHR RAM or VRAM? My theoretical emulator would emphasize arbitrary software/hardware design; not be bound to traditional commercial game emulation (iNES or even UNIF for a description.)

The fact is I'm a neophyte (nubile? :P) programmer, and I know that inevitably I'm going to write poor code, I’m just thinking about getting my foot in the door. My emulator’s priorities would be: speed < completeness < accuracy < simplicity
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Newbie to emulation questions

Post by tepples »

kyuusaku wrote:
tepples wrote:Try 16 pointers, each referencing a 4 KB bank, for reads, and 16 pointers for writes.
With the large banks, how would you suggest I have byte precision for open bus/memory/io/ignore and bus conflict events?
For the CPU built-in I/O registers, set your $4000 handler to check if the write is in $4000-$4017 and use a separate pair of 24-entry tables for those.
Why even 4KB banks?
NSF, for one. Crazy Japanese Famicom mappers, for another.
Emulating the system at sluggishly low level similar to how I gather people are emulating the PPU, a state machine executing pseudo microinstructions for each cycle like the actual thing.
Some interrupts can be predicted far in advance. When one of those interrupts is about to occur, you might want to use a cycle-by-cycle engine for a few instructions until it does occur. It's just like the PPU, where you use a scanline engine for most scanlines and a cycle-by-cycle engine for "interesting" scanlines.
I'm familiar with filters, sampling and DAC but envelopes, decay and arpeggio I'm pretty clueless about.
"Envelope" is the change in volume as a note is played on an instrument. This envelope generally falls into four segments: attack (rising), decay (falling), sustain (more or less constant), and release (falling to zero).

"Arpeggio" in the context of tracked music is rapid oscillation of one tone generator among two to four pitches to produce a warbly chord.
My PC programs use the Allegro library, which abstracts over DirectInput, DirectDraw, and DirectSound, and their equivalents on other platforms.
Thanks for the tip. I assume you prefer this to SDL; please tell me why. I have never used either.
I learned Allegro back when my PC ran MS-DOS and Windows 3.1. Allegro ran on DOS (and still DOeS); SDL does not. Allegro also implements slightly higher level functions (e.g. line, rectfill, and even basic GUI elements) out of the box.
It would happen for example when a homebrew programmer indexes ROM with $2006 and writes to $2007.
Writes are just ignored, as long as rendering is turned off while this happens.
There aren't any mappers with writable registers in PPU space--yet. I'm just interested in the behavior, I wondered if the PPU would crash and if so, if it could be recovered by turning the PPU off then on again etc.
Writes to $2007 while rendering is turned on appear to cause conflict on both the data and address buses.
I know this but what if there was no CHR ROM, CHR RAM or VRAM? My theoretical emulator would emphasize arbitrary software/hardware design; not be bound to traditional commercial game emulation (iNES or even UNIF for a description.)
Arbitrary hardware? So are you willing to allow for things like Wide Boy, where you have a completely separate computer on an NES cart, with its own PPU that feeds a stream of pixels to the NES PPU, and the 6502 just sits there polling the controllers?
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Newbie to emulation questions

Post by Quietust »

tepples wrote:Allegro ran on DOS (and still DOeS); SDL does not.
Unfortunately, Allegro isn't terribly reliable under Windows - the last Allegro application I ran (pineight tools) crashed and corrupted my mouse pointer after pressing ALT+TAB three times.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

If that happened in 8TED, that's my fault. I didn't handle GUI switch events properly at the time; now I know how to do that. For GUI-style things, it might have been better for me to use wxWidgets instead of Allegro.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust »

tepples wrote:If that happened in 8TED, that's my fault. I didn't handle GUI switch events properly at the time; now I know how to do that. For GUI-style things, it might have been better for me to use wxWidgets instead of Allegro.
I believe that was the program. The other issue I had was that it ran at a nice tiny 320x200 on my 1600x1200 desktop, making it impossible to see what the hell I was doing without using a magnifying glass. :)
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
n6
Posts: 60
Joined: Tue Jul 11, 2006 10:12 am

Post by n6 »

Try 16 pointers, each referencing a 4 KB bank, for reads, and 16 pointers for writes.
Isnt it even better with 2kb blocks? because of the size of WRAM
User avatar
kyuusaku
Posts: 1665
Joined: Mon Sep 27, 2004 2:13 pm

Re: Newbie to emulation questions

Post by kyuusaku »

tepples wrote:For the CPU built-in I/O registers, set your $4000 handler to check if the write is in $4000-$4017 and use a separate pair of 24-entry tables for those.
Wouldn't compare logic and additional tables be far slower than a pointer array which could directly point to separate memory ignore/conflict/success/open bus handlers and PPU/APU functions?
NSF, for one. Crazy Japanese Famicom mappers, for another.
I didn't know, right now NSF isn't in the picture. The dynamic map idea was to allow individual mapper modules (NSF or FDS for example) to change the map on a case by case basis. Which FC mappers are these with 4KB banks? Are you sure they aren't pirate originals?
Some interrupts can be predicted far in advance. When one of those interrupts is about to occur, you might want to use a cycle-by-cycle engine for a few instructions until it does occur. It's just like the PPU, where you use a scanline engine for most scanlines and a cycle-by-cycle engine for "interesting" scanlines.
I know this is probably horrible, but I was thinking about running both the CPU and PPU in real time by interleaving which would allow me to skip the look ahead logic for the PPU, just evaluate the interrupts before each instruction. It's unfortunate that this would be so intense for even current desktops but "interesting" detection algorithms not only seem like a lot of work but are pretty complex, which sorta goes against the simplicity philosophy.
"Envelope" is the change in volume as a note is played on an instrument. This envelope generally falls into four segments: attack (rising), decay (falling), sustain (more or less constant), and release (falling to zero).

"Arpeggio" in the context of tracked music is rapid oscillation of one tone generator among two to four pitches to produce a warbly chord.
Thank you, that was exactly what I wanted.
Arbitrary hardware? So are you willing to allow for things like Wide Boy, where you have a completely separate computer on an NES cart, with its own PPU that feeds a stream of pixels to the NES PPU, and the 6502 just sits there polling the controllers?
Sure, I guess. I wasn't thinking of hardware that complex, I was thinking of large integration ASIC like MMC5 which for me is a big deal. I don't see why a mapper module (which would "patch"s over the default setup) and an additional CPU/PPU core couldn't be added similarly to FDS support. Of course I personally can't add them though nor will my DMG TV Monitor (1st generation Wide Boy?) will be sacrificed for this cause either ;)
n6 wrote:
Try 16 pointers, each referencing a 4 KB bank, for reads, and 16 pointers for writes.
Isnt it even better with 2kb blocks? because of the size of WRAM
Wouldn't 1 byte blocks be best since that's the size of i/o ports? :P
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Newbie to emulation questions

Post by Quietust »

kyuusaku wrote:I know this is probably horrible, but I was thinking about running both the CPU and PPU in real time by interleaving which would allow me to skip the look ahead logic for the PPU, just evaluate the interrupts before each instruction. It's unfortunate that this would be so intense for even current desktops but "interesting" detection algorithms not only seem like a lot of work but are pretty complex, which sorta goes against the simplicity philosophy.
Ever used Nintendulator? That's pretty much exactly how it works, and you can expect your emulator to be just as slow if you use the same method. :)
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Newbie to emulation questions

Post by Memblers »

kyuusaku wrote: Must I give myself a more traditional musical background to understand say FM synthesis (which appears to be more instrument oriented)?
Gonna emulate an FM chip? Jesus man, good luck. :P
I tried designing my own FM software synth and all I get so far is crazy sounds. Which is actually pretty cool, but not very musical.

FM synths are easy to use with some experimentation, but making one or emulating one properly seems to involve tons of mathematic stuff that's incomprehensible to me. Actually emulating one would probably be easier I'd imagine, since there's a lot of lookup tables needed which are already available.
User avatar
kyuusaku
Posts: 1665
Joined: Mon Sep 27, 2004 2:13 pm

Post by kyuusaku »

That's good to hear, I thought every emulator looked ahead now. I would be quite satisfied to achieve Nintendulator's speed. I don't think that will happen though since I wouldn't use any assembly. With a "roll your own" emulator, I guess speed isn't a big issue since there'll be no userbase.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Newbie to emulation questions

Post by Dwedit »

Quietust wrote:
tepples wrote:Allegro ran on DOS (and still DOeS); SDL does not.
Unfortunately, Allegro isn't terribly reliable under Windows - the last Allegro application I ran (pineight tools) crashed and corrupted my mouse pointer after pressing ALT+TAB three times.
Allegro is stable enough. One time I wrote a program using the win32 api, then attached allegro to the main window, and it works fine even doing things that way.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
kyuusaku
Posts: 1665
Joined: Mon Sep 27, 2004 2:13 pm

Re: Newbie to emulation questions

Post by kyuusaku »

Memblers wrote:Gonna emulate an FM chip? Jesus man, good luck. :P
I tried designing my own FM software synth and all I get so far is crazy sounds. Which is actually pretty cool, but not very musical.
Heh not any time soon! Everything right now is a pipe dream. I just got this crazy idea to write an emulator last week; I haven't even used the majority of the built in NES hardware or ever written a Win32 app ;) My first step will be to come up with a cool name.
User avatar
laughy
Posts: 41
Joined: Wed Nov 17, 2004 12:34 pm
Contact:

Re: Newbie to emulation questions

Post by laughy »

I know this is probably horrible, but I was thinking about running both the CPU and PPU in real time by interleaving which would allow me to skip the look ahead logic for the PPU, just evaluate the interrupts before each instruction. It's unfortunate that this would be so intense for even current desktops but "interesting" detection algorithms not only seem like a lot of work but are pretty complex, which sorta goes against the simplicity philosophy.
I don't believe there are any complex detection algorithms that need to be implemented. I was able to produce an accurate catchup emulator using a virtual counter/event model, which isn't too hard to set up, and a pleasure to use. Any changes to the state of the emulator means just updating the virtual counters accordingly. I don't find it necessary to implement "micro-instructions" should an event be close to occuring: interrupts are usually handled by the 6502 after instructions finish anyway. Note that events wouldn't do things like set flags or anything - flag updates would be done only when the game requested the status of said flag...i.e. "catchup" emulation.

Writes to registers that need to cycle accurate (i.e. v = t at frame start) would have to be delayed should an event have occurred part-way in the instruction, but that's only if you want to get some really picky games working. You can emulate most games without having to worry about silly things like that, and it's easy to revisit should you decide you want that level of detail.

Really though, I think in general the most complex thing in any NES emulator is writing the PPU, which you have to do regardless of the type of emulator it is (scanline, cycle, catchup, etc.), and the difficulty in implementation for these types is close to the same. In my emulator the most complex thing would actually be the JIT compiler, but I suggest NOT writing one of those.
Post Reply