You will need informations on the NES (CPU opcodes, memory layout, etc). Someone else might be able to tell you more, I don't really know much about the NES.
As for the langage, I would suggest you to use C# instead of VB.NET. Both langage are about as easy to use but C# is more adapted for low level coding. By example, VB.NET doesn't support unsigned type (ushort, ulong, etc) and CPU often have opcodes that work on unsigned type. You would need to 'emulate' the unsigned value if you use VB.Net, that would be a bit more complicated and also slower. C# also have some advanced features that you might want to use in the future, when you are more confortable with .NET.
Only reason you might 'absolutly' need C++ at some point is if your .NET application need to interact with C/C++ dll. By example, if there is a 'C/C++' graphic plugin you need to use. If this is not the case then you don't need to know C++ at all. Learning C++ is not bad or anything but I can assure you that you can make an emulator in .NET that will be as fast as if it was done in C++ or ASM.
<More advanced stuff following, you should not use this at first but its good to know that its there... 8) >
If, at some point, you want to use 'dynamic recompilation' in your emulator, learning intel ASM would not be the way to go. There is an easier way to do dynamic recompilation in .NET.
In the .NET environnment (JAVA is like this also), there is a few stages to the compilation of an application:
- You compile your VB.Net, C#, or Managed C++ application ==> .NET generate an assembly that contain MSIL (Microsoft Intermediate Langage).
- When someone execute your assembly, .NET take the MSIL and create highly optimized Intel ASM 'on the fly', then execute the intel ASM. Some of the optimization done: registers caching, loop unrolling, method inlining, constant folding, etc.
MSIL is a stack based assembler, which is a lot easier to learn then intel ASM. By example, to execute:
X = (13 + 5) * 2
you would emit something like this:
- Load(13) // STACK: 13
- Load(5) // STACK: 13, 5
- Add // STACK: 18
- Load(2) // STACK: 18, 2
- Mult // STACK: 36
- Store(X) // X=36, STACK: <empty>
All this to say that there is a way to create MSIL dynamically in your code, and then execute the MSIL. You can then take NES "opcodes block", write 'easier to understand' MSIL that emulate the block, then execute it and get execution speed of highly optimized Intel ASM.
FYI, I know this work because I have done a 'proof of concept' N64 emulator in C#, using dynamic recompilation.
Warcon
PS. No, I'm not working for MS or anything but after using C/C++ for years, I'm really impressed by the speed and features of .NET... 8)