What's new

Nes

BGNG

New member
Oh, what the hey? There's a Chip8 and Game Boy topic, why not NES?

Let's see... A few good resources (I've attatched them to this post) for NES emulator programming would be YOSHi's NES TECH document and Firebug's Mappers document (for the expansion modules). Also in that ZIP is documentation on the NMOS 6502 Assembly.

The NES runs on, as just mentioned, a custom NMOS 6502 microprocessor modified for use on the NES by integrating sound generation and assorted I/O registers, which was manufactured by Ricoh and is called RP2A03G. It's approx. 1.773MHz for PAL and 1.790MHz for NTSC.

The NES has a couple of memory modules inaccessible directly by the processor. These would include the PPU memory and Sprite memory, which must be indirectly written to and read from by using registers $2003 & $2004, and $2006 & $2007, which is described in the tech document.

The video system itself is a 256×240-pixel display and is composed of two major parts: the background and the sprites. Both of these use image data from the same place in PPU memory called the Pattern Table. The Pattern Table consists of 8×8-pixel tile data, two bits per pixel. The background has a confusing structure. The lower two bits of the background color is its pattern map, called the Name Table. The upper two bits of the background come from the Attribute Table, which describes the colors for a 4×4-tile square on the screen in a method I will not describe in this post.

By default, mirroring is applied to the Name Tables to allow for wrapping when memory is read from them, but expansion modules can be used to give the NES up to 4 Name/Attribute tables.

The Sprites have a few functions to them which allow them to be flipped horizonally and vertically, and the upper two color bits of the sprites are stored in sprite memory themselves.

The NES has two color palets of 16 colors each; one for Background and one for Sprites. There are 52 different colors these can be, the exact values of which are predefined in the NES (and varry for NTSC and PAL slightly)
__________

Meh. I'll stop there for now. If there's any interest, I'll say more.
 

refraction

PCSX2 Coder
i would say yes as NES is one of my favourite consoles from the past, but, i havent even made a GB emu yet, so ill keep it on hold till i do :p
 
OP
BGNG

BGNG

New member
Is that "yes" as in "Yes, I am interested in this topic"?
__________

Also, the NES processor does not allow for Binary-Coded Decimal like the standard form of the 6502 does. You can set or clear that flag in the Status register all you want, but all arithmetic (ADC and SBC) is done with normal byte arithmetic.
 

refraction

PCSX2 Coder
yes its an interesting topic, im sure it would be very handy for people to have pleanty of info on the NES system, as you said, GB and Chip8 are up there, why not put the next step up too :)
 
OP
BGNG

BGNG

New member
"Next step"? Well... With the exception of some old-fashioned inefficiencies and that mess of mappers, this thing is actually a little easier to emulate than the Game Boy; it's simply a lot weirder, which makes people skip over it. The whole issue with "mappers" is about as proprietary as you can get, and is up on the variation scale along with a lot of the SNES capability chips produced by third-party developers.

But for the most part, if you can get a good grasp on all those ROM/RAM/VRAM/VROM banks in the NES carts and how different games access them, then the emulation will be fairly easy to implement.
__________

I'd have an example to show right now, except I keep changing how I want to make it, and things in real life keep popping up to distract me. I've finally decided to make a DLL that handles all aspects of emulation and needs only HDC for video output, an optional audio device (usually wave mapper), and input map. Any strange findings I make I'll post in this thread.
 
OP
BGNG

BGNG

New member
What do you mean? I'm not boggled, so I may be missing something.

There are four kinds of interrupts on the NES: Abort, Software (IRQ/BRK), Non-Maskable and Reset. Abort needs not be emulated, as it's part of the hardware configuration and has no effect on the programming. The other three have vectors, or addresses to jump to, at the end of the ROM and each is called when approperiate.

The Software interrupt is not much more than a, as far as analogy is concerned, really-low-level callback invoked by the BRK instruction.

The Non-Maskable Interrupt, or NMI, is typically used by the programs to respond to PPU events such as VBlank or sprite hits (non-transparent pixels drawn to the screen).

The Reset vector in NES is nothing more than the code entry point. It will execute code starting at the reset vector. (In the event there is a trainer, however, it will begin execution at the trainer itself)
 

aprentice

Moderator
the vblank interrupt and when it should be executed, at least thats the problem i had when i've given up on my nes emu and went back to my gameboy emu :p
 
OP
BGNG

BGNG

New member
The VBlank triggers a non-maskable interrupt after the last scanline is drawn to the screen... but only if the program enables it to do so when it sets up the PPU. Otherwise, the program can wait and constantly poll the VBlank bit to see if VBlank has occured.
 

Cyberman

Moderator
Moderator
BGNG said:
The VBlank triggers a non-maskable interrupt after the last scanline is drawn to the screen... but only if the program enables it to do so when it sets up the PPU. Otherwise, the program can wait and constantly poll the VBlank bit to see if VBlank has occured.
Which of course means you have to be sure to find a good way to set this VBlank bit to be inspected by software synchronisely with the NES display. That can be a bit of a challenge. You should also 'trip' the interrupt if the intterupt is enabled when you set the bit.

Cyb
 
OP
BGNG

BGNG

New member
The bit is stored in the PPU status register, so you just set it after the last scanline is drawn in the video rendering. No biggie. The memory handler of any emulator should just read memory address $2002 as that byte anyways, which the programs do. It will thusly be such a "Wait for VBlank" in that event. (Although reading the register will reset the BGScroll values. I'll have to look up a better way to poll for VBlank.)

Triggering the interrupt is almost identical to that of the code used for the BRK instruction, with the exception that the vector is at $FFFA instead of $FFFE.
 

hap

New member
Chip8 was fun, proving to myself emulator programming is an enjoyable waste of time. I moved on to something a bit more challenging; yeah, the NES. Currently the only thing that's done is the CPU, it's complete, and completely untested ;p .. all I get on screen right now is BRK BRK BRK BRK BRK, etc, which looks alright, since the memory is filled with zeroes, and BRK is opcode 0.

I mainly used the official datasheet, 1st one in this list: http://www.6502.org/documents/datasheets/rockwell/
 
OP
BGNG

BGNG

New member
Ah. I was about to correct you, but I was thinking NOP was 0, which it isn't. Indeed, BRK is 0.

I myself have been forced to leave my project alone for a time, so I'm still in the process of porting things to DLL format. I may not be able to assist you in your work if you have questions.
 

Eshin

New member
BGNG said:
What do you mean? I'm not boggled, so I may be missing something.

There are four kinds of interrupts on the NES: Abort, Software (IRQ/BRK), Non-Maskable and Reset. Abort needs not be emulated, as it's part of the hardware configuration and has no effect on the programming. The other three have vectors, or addresses to jump to, at the end of the ROM and each is called when approperiate.

The Software interrupt is not much more than a, as far as analogy is concerned, really-low-level callback invoked by the BRK instruction.

The Non-Maskable Interrupt, or NMI, is typically used by the programs to respond to PPU events such as VBlank or sprite hits (non-transparent pixels drawn to the screen).

The Reset vector in NES is nothing more than the code entry point. It will execute code starting at the reset vector. (In the event there is a trainer, however, it will begin execution at the trainer itself)


I dont recall the nes having a abort interrupt. The nes has only 3 interrupt types and function as follows:

RESET:
Is only used during power up after the rom has been loaded into memory, then the cpu jumps to the interrupt vector.

IRQ/BRK:
This can either be triggered by software or hardware. But as far as i know no nes rom is known to use the BRK instruction so this mainly leaves hardware left. There are several mappers that generate IRQ, usaly after a given number of scanlines or each scanline. The sound generator can also trigger IRQ, but very few games are dependent of this.
(and this interrupt is maskable, through the I flag on the cpu)

NMI:
This interrupt is only executed when 0x2000.7 is set. Then the PPU will give the CPU a NMI at the start of Vblank.
(this interrupt is ofcourse non-maskable)

The problem with the nes is that games often uses some nasty trick to get things done in time with the limited prossesor power it got. This means clk timing the nes is VERY important (and causes a big problem with interrupts), some games even crash if your emu is of by only a few clk.
 

Eshin

New member
ah, i saw now where you got the abort interrupt from, since its mention in the docs you posted.

Just as a note.
I skimmed through the doc telling about the nes and it is missing some vital info along with some of it not beeing correct.
i.e the ppu does not genereate NMI on sprite #0 hit, this bit isnt even used on the nes

oh and btw that cpu 6502 doc is not very accurate too, it has some incorrect timings and flag settings errors.
(but its tells the basics though, and should be sufficient to get a working emu)
 

hap

New member
Neat, first time it's showing something ungarbaged. Pacman even goes to the demo, making dots vanish with ghost-pacman :p no sprites yet.
 

hap

New member
this is MMC2, punch out. I'm surprised it's getting this far.
I should really enhance the PPU emulation, all it's doing now is draw 4-colour tiles on the screen.

Is anyone else actively working on a new NES emu ?

*edit* hmm, the background looks better, but mike's not waiting for my challenge anymore :(:p
 
Last edited:
OP
BGNG

BGNG

New member
I've got one in the works, but not actively. Life threw a curveball and it'll take a while to get back to the project. Even when I DO get back to it, it'll take a while to get to testing it in the real world because I'm doing just about everything seperately before connecting them all together. I'm engineering the code to be easily updatable and work as fast as possible by eliminating extrenuous function calls. Not an easy task, but it's fun.

It's also being constructed in a Windows DLL so it can be used from ANY programming language given nothing but an hDC and input map.
 

hap

New member
aprentice: will you ever continue with your NES emu ?

these are the basics for when to hit vblank.

dummy scanline (341 ppu cycles)
240 visible scanlines (341*240 ppu cycles)
dummy scanline (256 ppu cycles, so no hblank here), then hit vblank, and let the cpu run out of cycles before starting a new frame

1 cpu cycle=3 ppu cycles
cpu cycles start at ~1789773/60, so vblank hits at cycle (1789773/60)-((256+341+(240*341))/3)=~2350
 

Top