Hi!
I wonder if the PC register ever will contain addresses<0x8000 (point to locations outside of the PRG ROM), or if it's possible.
Yes it's possible. It can point to anywhere from $0000 to $FFFF. As long as the CPU can read valid instructions, it'll keep working.
Programs that copy code to RAM and execute it there are common. This is often done because of self-modifying code (code that modifies itself as necessary, something done for speed) or to have a piece of code available regardless of the PRG-ROM banks that are selected.
The program will probably crash if the CPU tries to execute the PPU registers for example (because the returned values are not meaningful logic, and possibly contains illegal instructions and reads, writes and jumps to unknown locations), but it will certainly try if you jump there.
Thank you very much!
Now I came to think of some more questions.
1. What happens if you read from write only memory(I think some registers are), or from memory that doesn't exist, like 6000-7fff if there's no sram. Is any value returned at all, or is the contents of the destination unchanged?
2. how do I know if sram exists? the .nes file doesn't say anything about it.
You read open bus, that is the last byte that was put on the bus. Normally, this is the last byte of the opcode doing the read, which is usually the high byte of the destination adress, but in case of indirect or indexed read, it can be different.
Snaer wrote:
2. how do I know if sram exists? the .nes file doesn't say anything about it.
UNIF and
NES 2.0 formats do say something about it. For
iNES ROMs (the majority of dumps in the wild), assume 8 KiB, unless it's on a mapper that can take more. This applies even on a mapper that ordinarily can't take any, such as the discrete mappers, in which case it'd be decoded with a circuit like
this. A couple games such as Low G Man rely on the presence of open bus at $6000-$7FFF. Such games can't be represented properly in iNES format, and you may need to detect these by comparing the MD5 of the last bank of PRG to values for known problem games.
Just to elaborate on what Bregalad said, in case you do not have much knowledge of electronics:
To access memory you need a bus, which is a what connects the different chips. In order to read a value from memory, the CPU send to the memory chip the address it wants to read through the address bus. Then it waits for the value to show up on the data bus, which will be what the memory chip outputs.
If there is no memory chip at the address in question, the CPU will still put the address on the address bus, but since there is no memory chip to respond, it will just read back what was in the data bus previously, which is usually the last byte of the instruction it's running (since the CPU uses the address and data buses to read the instructions themselves before running them).
Thank you everybody!
Quote:
in case you do not have much knowledge of electronics
Yes that is the case.
Is it necessary to have knowledge of electronics when you write an emulator? If so, are there any good documents to get some basics?
Snaer wrote:
Is it necessary to have knowledge of electronics when you write an emulator?
Not really. It will help you understand some things that at first don't make any sense (like this open bus thing), but it's not an absolute necessity. I don't know much about electronics myself, but I ended up learning a few things from working with the NES (although I like to make NES programs, not emulators, but either way you should learn something).
I don't have any links to recommend, but if you want to read about the subject search, Google for things like "introduction to digital electronics" and "introduction to computer architecture". These should give you a good idea of how things work on the logical side, without being too specific about the electronics stuff.
Thanks again, I think I found some good docs.
New question
:
What do I need to do on startup? Should any memory or registers be set to zero or something like that? Or do the roms handle all that stuff?
Snaer wrote:
What do I need to do on startup? Should any memory or registers be set to zero or something like that? Or do the roms handle all that stuff?
Well programmed games don't assume anything and will safely initialize everything they use, but there are some things known about the startup sate of the NES.
Memory is not explicitly cleared, but it isn't very chaotic either, so it's mostly 0's. No game should count on it though, so do whatever you want with it. I believe most emulators clear it all to 0's.
EDIT: Apparently it's $FF and not $00, my mistake!
I believe that the CPU and PPU registers have a somewhat consistent startup state, maybe someone else can point you to a document with that information, but games shouldn't rely on that either.
My opinion is that the startup state is not very important, as I can't think of a single game that relies on that kind of thing.
In fact the memory is mostly cleaned with FFs, but some bits are randomly cleared here and there. Also I'm not sure but I think some bits will randomly be clear - but it will always be the same for the same RAM chip (for the NES). This also applies to nametable RAM, CHR-RAM, etc...
So the "most accurate" is to init everything with FFs, but developers shouldn't rely on this.
I don't know if you need knownledge in electronics to write an emulator, but if you want to code a very accurate emulator you'll probably needs some knownledge.
Bregalad wrote:
ISo the "most accurate" is to init everything with FFs, but developers shouldn't rely on this.
- A lot of demos don't work because they expect RAM to be 00h instead of FFh. It includes the open-bus for 6000-7FFF, among others.
Zepper wrote:
A lot of demos don't work because they expect RAM to be 00h instead of FFh.
What demos? Do they work on real consoles?
No program should ever rely on uninitialized RAM... Unless the programmer is trying to seed a random number generator or something like that, but uninitialized RAM is not such a good source of random numbers either.
If these demos do rely on uninitialized memory they deserve to not run. A good emulator behaves like the original console, and using hacks to support programs that don't run on a real console goes against that.
tokumaru wrote:
What demos? Do they work on real consoles?
- Nope, they don't... or work with glitches. I removed the "wrong" to avoid a negative impact. ^_^;;
Oh, so they are Nesticle demos, not NES demos! =)
Aah remembers me my first days in Nesdev when I was using Nesticle to test my programms and didn't know what a VBlank is (none of the doccuments I was reading mentionned it, they didn't even said that $2006/7 wrties can't be done at all times and affect the scroll), Bananmos literally scolded me. I now fully understand how right he was.
Sounds like I should avoid nesticle from now on. :p
Anyway, now I set everything to FF (including PPU/APU registers) on startup.
I've also started testing some roms(Super mario bros, ice climber, donkey kong) to see if everything works good so far.
It does not! :p
Only donkey kong gives me the correct graphical output. Ice climber is just blank, and I don't know why.
I wonder if anyone might have an idea of whats wrong.
I've not implemented sound or input support yet if that could have something to do with it?
Well, I think the sound is automatically mute when you reset/turn on the console ($4015 := $00) but I'm not 100% sure. Most programms will do it manually anyway.
About the PPU it has it's "warm up time" where it's entierely disabled and only $2002.7 reads are known to be reliable, but I don't know any details. That's why most programms write $00 to $2000/$2001 to turn the graphic output off, wait 2 or 3 frames by polling $2002.7, and write $00 to $2000/$2001 again to make sure the PPU is effectively disabled, because on power on the first writes might as well not have any effect.
The vast majority of programms should work without the sound being emulated, but a few will rely on DMC IRQs (Guardian Legend, ...) or APU IRQs (Door Door, Dragon Quest, ...) in order to work.
Snaer wrote:
Sounds like I should avoid nesticle from now on. :p
You mean you aren't already?!
Quote:
I wonder if anyone might have an idea of whats wrong.
Hard to say without debugging. Your best bet is to log every executed instruction to a file, then run the game in FCEUXD for example (which can log to file as well) and compare both outputs to see where your emulator went wrong.
Quote:
I've not implemented sound or input support yet if that could have something to do with it?
Programs usually run without those things.
Thanks I'll try that when I get home.
Quote:
You mean you aren't already?!
Well actually I mostly use FCEultra but I use nesticle sometimes
(very rarely though).
Snaer wrote:
Well actually I mostly use FCEultra but I use nesticle sometimes
(very rarely though).
Well, if you like to use it for playing, that's your call, but please never use it for development purposes (like comparing your emulator to it).
FCEU isn't terribly accurate either. It's great because it originated debugging versions that are insanely useful, but it doesn't do a great job out of simulating several obscure details of the console.
The consensus is that Nestopia and Nintendulator are the most accurate emulators, so you should always use those for development purposes. But having an actual console to run tests on is a good idea too. I have programmed stuff that these two emulators were fine with, but they looked wrong on the actual console.
tokumaru wrote:
FCEU isn't terribly accurate either. It's great because it originated debugging versions that are insanely useful, but it doesn't do a great job out of simulating several obscure details of the console.
The consensus is that Nestopia and Nintendulator are the most accurate emulators, so you should always use those for development purposes.
I second that recommendation for people who run Windows on their primary development PC. But in your opinion, is the combination of FCEU and testing a daily build on an NES + PowerPak fine too? Or should all Linux users build
Nestopia from source?
Quote:
But having an actual console to run tests on is a good idea too. I have programmed stuff that these two emulators were fine with, but they looked wrong on the actual console.
I'd submit such "stuff" as a test case if the emulator's author is still contactable.
tepples wrote:
But in your opinion, is the combination of FCEU and testing a daily build on an NES + PowerPak fine too? Or should all Linux users build
Nestopia from source?
I'm not in a position where I can give Linux-related opinions. In fact, one of the reasons I haven't switched to Linux yet is NES emulation.
Quote:
I'd submit such "stuff" as a test case if the emulator's author is still contactable.
In my most recent situation I had mostly the same problem you had with LJ65 because you turned sprites off early. I was disabling and enabling sprite rendering mid-frame and this caused sprites to look corrupted. I don't know if that behavior has been completely understood by now...
From the small experience I've had, the Linux version of FCEU also sucks as opposed to its Windows counterpart. It had no graphics filters available, was lagging even tough my PC is largely powerful enough to accurately emulate the NES, and I didn't even see debugging options. It might have been me tough.
I think there was 2 NES emus I found on Linux so I may be confusing with the other one - I'd have to check that again.
Tokumaru, in case you don't want to Switch to Linux you can do like me : Install Windows, install Linux on the top of it, and modify the boot parameters so that Windows is selected by default. Be careful tough not to mess up with your drives, which is a very easy thing to do.
Yeah, I though of the multiboot approach, but that doesn't solve the problem. I want to get rid of windows entirely, because if I have a partition with it I'll always feel tempted to use it and Linux will go abandoned.
I experienced the same as you. My notebook is powerful enough to run NES emulators with filters and debugging windows without any sort of lag, but when I tried what was available for Linux it was all very slow and unstable.
I've dualbooted my computer with both windows and ubuntu just one week ago
I tried some debugging yesterday and I did find two small bugs
, unfortunately ice climber still didn't work after I fixed them(still just a blank window).
I tried donkeykong jr and donkeykong 3 and they both worked fine too.
I'll continue the debugging after work today. It takes so much time.
Debugged some more, the two logs are the same until the second nmi.
The first one is called at exactly the same place in both.
But the second one is a little bit later in my log.
Is it very important that nmi gets called at the right place and that all instructions are timed right?
Some games do require very precise timing to work correctly, but most are not so bitchy about it. But sure, fixing your timing can never be a bad thing, even though I doubt this is the problem with these old first-gen games.
Made some progress this weekend. Now both iceclimber and smb is playable!
(edit: after running nestest and fixing all cpu bugs I can also play the donkeykong games
)
There are some other bugs left though and I have some more questions :p.
1. Should the top row(the one not visible on ntsc displays) contain garbage(sprites) in donkey kong?
2. Any idea why the hud in SMB is flickering? Could it be a timing related problem or something else?
There is more but I will do some more research before asking.