I have read documentation that says that what value the CPU is writing 'generally wins' but does anybody have a statistic for this? (70%? 99%)
Also are bus conflicts even across mappers/boards that have them or are some more prone to others?
I know that it isn't really necessary for NES emulation but it is more of an accuracy thing that I am interested in implementing into my emulator.
I don't know about "generally wins" but if you want to emulate or simulate bus conflicts you might want to figure that if a bus conflict happens, return both sources ORed together. While it isn't necessarily what would happen on a real board in theory you want to return not the CPU value since if the CPU really generally wins then we wouldn't have to worry about bus conflicts.
But there is another problem. Mapper 7 sometimes has another chip to disable PRG-ROM during writes. But there is no iNES flag to determine this. And similarly any discrete logic could also have this chip to do that.
MottZilla wrote:
I don't know about "generally wins" but if you want to emulate or simulate bus conflicts you might want to figure that if a bus conflict happens, return both sources ORed together. While it isn't necessarily what would happen on a real board in theory you want to return not the CPU value since if the CPU really generally wins then we wouldn't have to worry about bus conflicts.
I thought I read somewhere else it is AND, but maybe not?
Quote:
But there is another problem. Mapper 7 sometimes has another chip to disable PRG-ROM during writes. But there is no iNES flag to determine this. And similarly any discrete logic could also have this chip to do that.
Does the NES 2.0 submapper numbers have any flag to specify?
NMOS usually has "and" behavior: a transistor pulling down to 0 beats a resistor pulling up to 1.
There's a
submapper draft covering bus conflicts on discrete mappers.
Since there is no PMOS transistor in the CPU, whenever the CPU wants to write a 1, only a weak NMOS transistor mounted drives the bus line to +VCC. If an EPROM (or another thing) is trying to pull the line low, it will succeed without any doubt, and a '0' will be output.
If the CPU wants to write a '0', it's more ambiguous. A strong NMOS transistor in the CPU will drive the line to GND, but an external EPROM will probably be made of CMOS technology, and so a strong PMOS transistor in the EPROM will also drive the line to +VCC. The situation is ambiguous.
NMOS transistors are usually stronger than PMOS so again the '0' from the CPU will probably win, but the EPROM could as well be made of more modern transistors that will win against the CPU. In this case, the EPROM could as well win with it's '1'. Also, the mapper is physically closer to the EPROM (I'm not sure if this actually plays a role).
For this reason, both the AND behaviour, and the "EPROM wins" behaviour could be encountered, and be considered correct. Only thing I'd say is that the CPU will never win by writing a conflicting '1'.
EDIT : It's possible that mask ROMs in NES games were not CMOS, but NMOS too, like the CPU, especially for early (<1988) made games which had 128kb or more of PRG ROM (you know, those games which became hot when you play them for a long period of time). In this case, the AND behaviour is without a doubt what will be encountered.
If it's on the powerpak that's outputing a '1' the CPU should win either way. If the powerpak outputs a '0' the powerpak will probably win either way.
If it's really an unknown, but you're most likely to get an AND or an OR function depending on things specific to the cartridge and such why now just implement both. Randomly select whether it's AND/OR or possibly powerpak logic above. A game shouldn't rely on bus conflicts. You're really only looking to break a game that has bus conflicts for homebrew development correct? If that's the case something like the ability to turn on warning messages might be nice where you display transparent text informing the developer that they're causing bus conflicts and could get strange behavior. But if you were to bankswitch via bus conflict your game will probably jam anyways giving you enough info to know something's going wrong. You just need to make sure something goes wrong, so there aren't surprises when running on the NES.
More importantly make sure you're only implementing bus conflicts when the mapper is subject to them, as Tepples linked to. Basically all discrete mappers are subject to bus conflicts except ANROM. Since the other members of that mapper family have bus conflicts, you won't be able to implement bus conflicts unless you use submappers. You certainly wouldn't want to implement bus conflicts on any of the ASIC mappers, You'd have to check each one, but I'd guess none of them do.
infiniteneslives wrote:
A game shouldn't rely on bus conflicts.
Some do, though, by accident:
viewtopic.php?f=3&t=7273
thefox wrote:
infiniteneslives wrote:
A game shouldn't rely on bus conflicts.
Some do, though, by accident:
viewtopic.php?f=3&t=7273Then perhaps the best option is to have the user select whether to emulate them allowing games like that to work (are there known others?), or randomly resolve bus conflicts to break the game.
I agree that an emulator should have an accurate hardware mode, and a development mode that can warn of things that won't behave consistently on hardware or do things that will break games which rely on them. One thing the warnings do is expose bugs in the emulator where it's doing something wrong that causes warnings where there shouldn't be.
Can't find a game that does it, but just an LDA $4016 AND $43 CMP #$41 to rread the controller will surely be broken without bus conflicts.
IMO bus conflicts shouldn't even be an option. Put them in!
Quote:
Can't find a game that does it, but just an LDA $4016 AND $43 CMP #$41 to rread the controller will surely be broken without bus conflicts.
You're confusing bus conflics and open bus, my friend.
Quote:
If it's really an unknown, but you're most likely to get an AND or an OR function depending on things specific to the cartridge and such why now just implement both.
It can't be an OR function, as the CPU will never win when writing a "1" (see my post above). It could be either a AND function or a "ROM always wins" function.
Quote:
I agree that an emulator should have an accurate hardware mode, and a development mode that can warn of things that won't behave consistently on hardware or do things that will break games which rely on them. One thing the warnings do is expose bugs in the emulator where it's doing something wrong that causes warnings where there shouldn't be.
I agree. Such a development mode should trap not only bus conflicts, but undocumented opcodes, use of uninitialised memory, and attempts to write to VRAM outside of VBlank.
Bregalad wrote:
Such a development mode should trap not only bus conflicts, but undocumented opcodes, use of uninitialised memory, and attempts to write to VRAM outside of VBlank.
Agreed with one proviso: allow the developer to specify a fine-grained whitelist for
intentional use of stable unofficial opcodes.
Thanks guys but none of this really answers my original answer.
In the event of a bus conflict what happens, and how often does 'it' happen.
Every time a output isn't the same on both chips asserting on the bus.
3gengames wrote:
Every time a output isn't the same on both chips asserting on the bus.
I find this setence a little crytic
.
Basically, a chip can only out put directly to a chip, right? So if a chip is getting two different values from both chips, any different values being asserted is unknown. It can be wrong on any bit, it can be right on any bit. We don't now. It's based on which chip is outputting more and can over ride the other. In NES's case, you WRITE to the mapper. But if the chip doesn't get the output disabled on WRITES, the CPU tries to put the data on the bus WITH the ROM, so both the chip on the board and the microprocessor are trying to "write" data, so this affects the 3rd chip, which is reading the output, which is messed up because two devices are trying to output on the same bus.
Code:
1010
0110
----
UU10
U means unknown, it can be either 0 or 1 to the device reading the bus.
Let me rephrase: What value should an accurate emulator load into each bit of a 74LS161 or 74HC161 binary counter whose input is being driven with this 'U' signal?
As a random sample (no idea as to how representative), the AT28C64 provides the following Vout-vs-Iout graph:
Attachment:
AT28C64-pg8-crop.png [ 7.11 KiB | Viewed 5184 times ]
while the R6502 datasheet only mentions the somewhat lacking "Iload = 1.6mA, Voutmax = 0.4V; Iload = -100µA, Voutmin = 2.4V"
From this, we can conclude that if the ROM pulls low, it'll definitely win. The only question is whether the CPU or ROM wins when the ROM is pulling high and the CPU pulling low.
Code:
ROMout
0 1
CPUout 0 0 ?
1 0 1
Most sources I've seen assume AND, not =ROM. Mapper 144 implies that the ROM was not assumed to win in ordinary Color Dreams boards.
WedNESday wrote:
I find this setence a little crytic
.
A "bus" is made of several lines where bits travel. The address bus has 16 lines and the data bus has 8 lines. These are the paths that addresses and data use to move around. Some carts don't make use of the R/W line (it indicates whether the CPU is reading or writing), meaning they don't know the difference between reading and writing, so they output the contents of the address being accessed regardless of the operation. If it's a write operation, both the CPU and the ROM chip will try to
output data into the same bus at the same time! If the values they output are different, then you have a bus conflict.
Once someone writes some test ROMs for this, we'll have the definitive answer and test of accurate emulation.
Want me to write a UNROM test that uses WRAM and just writes conflicted values (A=0,writes to a location which contains FF, and then an FF to a location which contains 00) and upload 8192 test results for the bank switched to for the 2 writes by taking the bank number as the first byte in each ROM? We can even make it after the test, it goes back to the PRG-ROM and lets you go through the results, sort of like a hex editor, so we can see it on a console-by-console/chip-by-chip/setup-by-setup basis.
That's the first step, to research what actually happens. Then when we have determined what reliably happens (i.e. what a crappy game might depend on), we can write a pass/fail test ROM.
For the research phase, it'd be best to test on actual unmodified game boards, so we're using the original ROM chips, not EPROMS, flash, or whatever.
That can be done by scouring the ROM are above C000 for a $00 and $FF value, save them, and then run the code in RAM. There'd need to be controller reading portion in RAM but that's no big deal either. Sound like a plan? I can maybe get on it now, although I'd rather not really. I have so much other NES stuff going on, I need to stop taking on projects like this so often...
The problem is that mask ROMs in game paks are very different and elvolved trough the years. EPROMs are just as different. A difference in the 74xx161 chip might come into account too.
There could be a definite answer for a given mask ROM and 161 chip, but this result could change if you change the chips.
Also I don't think it's a probability thing like WednesDay seems to understand it in his original post, I assume that for a given cart, the "winner" of the bus conflict will always be the same, but for another cart, the "winner" could be a different chip. You will most likely not see a cartridge where the "winner" randomly alternates between the CPU and the ROM.
In all cases, I think a "AND" behaviour is probably the cleanest - if the programmer assumes that the value he writes to $8000-$ffff is what will get bankswitched he'll be wrong, and if he assumes the value in rom is what will be bankswitched he's wrong too. It's probably the most accurate electronically (see my previous answer).
Bregalad wrote:
In all cases, I think a "AND" behaviour is probably the cleanest - if the programmer assumes that the value he writes to $8000-$ffff is what will get bankswitched he'll be wrong, and if he assumes the value in rom is what will be bankswitched he's wrong too. It's probably the most accurate electronically (see my previous answer).
I'd agree with you because the end result should be that the actual behavior ends up different than what the mistaken programmer intended. There is too much dependent on electrical behavior between components that differ to have one accurate solution. So whatever happens on a mapper that is known to have bus conflicts, it should result in wrong behavior all the time, or wrong behavior none of the time. The reason I think it should just go with what the CPU writes is it will result in people writing programs that have bus conflicts but this is a minor issue for a new game and can easily be corrected either with one extra chip or implementing the table for register writes. Or just have an option, Bus conflicts -> CPU WINS, AND LOGIC, and whatever other options you'd want.
Accuracy mode does as best what NES does. Development mode warns programmer of conflict and possibly allows selection of behavior.
I just tested on unmodified GNROM, AOROM, and UNROM (Dragon Power, Battletoads, and Rygar). I had code running out of NES internal RAM writing bank selection values, then determining the bank that was set and printing it. GNROM and UNROM were AND (value in ROM AND value written by CPU), and AOROM had no conflict. This gives confidence that AND is accurate for these. See photos for details on the boards.
Quote:
I just tested on unmodified GNROM, AOROM, and UNROM (Dragon Power, Battletoads, and Rygar). I had code running out of NES internal RAM writing bank selection values, then determining the bank that was set and printing it.
Man, you are a genius !! I'd never thought of that !
I added the test result to the
wiki page about bus conflicts.
You can use simple rule : "Ground wins"
For example, when two devices A and B are connected to bus D, you can resolve bus conflict in following way :
if (Device A connected) D = A;
if (Device B connected) D = B;
if (Device A connected AND Device B connected) D = A & B;
If the cartridge is readable for the entire 64K, will the addresses that interfere with the CPU/APU/PPU also have their values ANDed in this way (so if set to 255, you can read/write them normally)?
If this works, then you could not only increase the ROM size without bankswitching, but also have hardwired AND masks for some variables in RAM (four each, because it is mirrored) and many for the PPU registers, possibly making some algorithms more efficient.
Will it damage anything to do this?
zzo38 wrote:
If the cartridge is readable for the entire 64K, will the addresses that interfere with the CPU/APU/PPU also have their values ANDed in this way (so if set to 255, you can read/write them normally)?
I'd bet large sums that'll never work... Good luck ever getting all the registers to work, let alone SRAM... Your NES isn't designed for the high currents during bus conflicts. Do it every once in awhile and there shouldn't be any damage. But to do it constantly will stress your CPU's line drivers and most likely shorten their life. Just don't do it...
infiniteneslives wrote:
zzo38 wrote:
If the cartridge is readable for the entire 64K, will the addresses that interfere with the CPU/APU/PPU also have their values ANDed in this way (so if set to 255, you can read/write them normally)?
I'd bet large sums that'll never work... Good luck ever getting all the registers to work, let alone SRAM... Your NES isn't designed for the high currents during bus conflicts. Do it every once in awhile and there shouldn't be any damage. But to do it constantly will stress your CPU's line drivers and most likely shorten their life. Just don't do it...
Ah, OK, thanks, I won't do it.
infiniteneslives wrote:
But to do it constantly will stress your CPU's line drivers and most likely shorten their life. Just don't do it...
Sounds like a caption for an ICHC cat photo. im in ur cpu, stressin' ur line driverz...
So really accurate bus conflict emulation would keep count of the number of conflicting accesses and over time degrade emulation, eventually failing to run any games? I like this.
Perhaps after long enough it shows a smouldering NES console and then a fire truck comes and sprays water on it?
blargg wrote:
So really accurate bus conflict emulation would keep count of the number of conflicting accesses and over time degrade emulation, eventually failing to run any games? I like this.
I think simply displaying the number of bus conflicts somewhere would be good enough, but, yes, keeping count might help.
blargg wrote:
So really accurate bus conflict emulation would keep count of the number of conflicting accesses and over time degrade emulation, eventually failing to run any games? I like this.
Yes, but be sure to keep track of the rate/frequency of the conflicts. Then use this to properly determine the thermals on die so you can assess the rate of degradation and statistical probability of permanent or intermittent failure associated with age of the CPU and number if run time hours logged. Oh, and don't forget to consider ambient temperature and process variation based on CPU revision.
MottZilla wrote:
Perhaps after long enough it shows a smouldering NES console and then a fire truck comes and sprays water on it?
So basically, emulation accuracy is getting so far we emulate things that were not observed in real life because it would ruin precious materials ?
Also it's not related, but if I remember well some early XBox360 models had set on fire. Should this be emulated when XBox360 emus will come out ?
Bregalad wrote:
Also it's not related, but if I remember well some early XBox360 models had set on fire. Should this be emulated when XBox360 emus will come out ?
Seeing as this is a major part of the 360 experience, how can you not include this in an emulator? In the menus, right below "Power" should be "Towel trick", "Repair heat sink", "Fire extinguisher", etc.
Bregalad wrote:
MottZilla wrote:
Perhaps after long enough it shows a smouldering NES console and then a fire truck comes and sprays water on it?
So basically, emulation accuracy is getting so far we emulate things that were not observed in real life because it would ruin precious materials ?
Also it's not related, but if I remember well some early XBox360 models had set on fire. Should this be emulated when XBox360 emus will come out ?
Well I was just joking, I don't think there is any need to emulate bus conflicts except in the way that would help prevent bad software from being made because it worked on an emulator or flash cart that disabled conflicts.
MottZilla wrote:
Well I was just joking, I don't think there is any need to emulate bus conflicts except in the way that would help prevent bad software from being made because it worked on an emulator or flash cart that disabled conflicts.
I agree with you; however, it may be useful to have a counter of number of bus conflicts and max frequent use of bus conflicts in some menu in the emulator, in case you are making a cartridge that has bus conflicts and if you want to view these counters to make sure the bus conflicts aren't being above some threshold. The emulator doesn't need to have fire in it and so on.
Quote:
in case you are making a cartridge that has bus conflicts
You should never have bus conflicts in your code. Some mappers are
capable of conflicts, but proper programming can avoid them. That is, never write a value to ROM unless it matches what's in ROM at that byte. One way to ensure this is to first read from that byte, then write it back. That way a bug will result in the wrong bank rather than a hidden conflict.
If a true bus conflict occurs you should be notified ideally by the emulator. All the commercial games, barring some bug, were programmed to be aware of bus conflicts and avoid them properly. The concern would be you could write homebrew for one of these mappers such as UNROM or CNROM and constantly cause conflicts that could damage to hardware.
blargg wrote:
One way to ensure this is to first read from that byte, then write it back. That way a bug will result in the wrong bank rather than a hidden conflict.
Yes, this is what I have done. Still, it should be useful for the emulator to have some bus conflict counter so that you can see if you have a bug in your program (or if you want to examine if any commercial games are doing this).
Go ask nocash. His NO$GBA had a counter of how often games perform certain "illegal" (undefined or unspecified) behaviors. When I was in the GBA scene, I was pleasantly surprised when my own homebrew games scored way lower on "errors per second" and higher on "low power" than WarioWare and the other games that I dumped from my Game Paks.
tepples wrote:
Go ask nocash. His NO$GBA had a counter of how often games perform certain "illegal" (undefined or unspecified) behaviors. When I was in the GBA scene, I was pleasantly surprised when my own homebrew games scored way lower on "errors per second" and higher on "low power" than WarioWare and the other games that I dumped from my Game Paks.
From memory, the emulator didn't give you any hint as to what illegal actions were being performed or what the severity of ignoring them was, so all it was was a useless factoid.
The shareware version of NO$GBA tells you everything.