Does anyone actually have a copy of this ROM? Everywhere I go the file just downloads like a HTML file and when I try to convert it to a NES ROM it still doesn't work. Does anyone know of a good copy or can someone email me one?
ROM image,
documentation
The problem is that tripoint.org (kevtris's web host) sends "unrecognized" files (i.e. .NES files) as text/plain (which causes browsers to view them as text and causes IE to not save them to disk properly); my web host sends them as application/octet-stream (i.e. "generic binary file"), so it should download fine.
FCE Ultra 0.98.12 gives OK except for illegal ops DCP (error A9) and ISB (BE).
[... reading docs ...]
Well i've always hated FCEU anyway. Does anyone know why nestest.nes doesn't test for all of the illegal opcodes? There are so many individual ones that it does not test for, or the other NOP ones.
Out of curiosity, what does a real NES do on an illegal op?
NES behavior for undocumented 6502 opcodes is the same as any MOS Technology 6502.
dxprog wrote:
Out of curiosity, what does a real NES do on an illegal op?
It executes the opcode. The $x2 ops (HLT) lock up the CPU. Some ops are unstable, most have predictable behaviour, most easily describable as mixtures of different ops.
Thanks for explaining what I already knew (sarcastically). Never mind. Ditto to my previous question, why aren't they all tested.
WedNESday wrote:
Thanks for explaining what I already knew (sarcastically). Never mind. Ditto to my previous question, why aren't they all tested.
First, i wasn't answering your question (i was replying to dxprog). Second. there wasn't any sarcasm involved in any of the prior posts. Third, shame on us for not knowing what you already do or do not know.
As for why some ops may not be tested, i think you'll have to ask the author of the tests for that.
baisoku wrote:
First, i wasn't answering your question (i was replying to dxprog). Second. there wasn't any sarcasm involved in any of the prior posts. Third, shame on us for not knowing what you already do or do not know.
As for why some ops may not be tested, i think you'll have to ask the author of the tests for that.
Not you! I meant the other two. My apologies.
WedNESday wrote:
Thanks for explaining what I already knew (sarcastically). Never mind. Ditto to my previous question, why aren't they all tested.
I wrote the program in question.
As for why they all aren't tested, I test every useful "invalid" opcode, along with many others. About the only ones I don't test are the very odd and utterly useles codes, along with the unpredictable ones, and of course the "halt" codes.
Here is the list of what is tested:
Code:
;
;key:
;XX - opcode has been fully tested by this program
;uu - opcode has been fully tested, but is an "undefined" opcode
;-- - opcode isn't useful or predictable. not tested
;== - opcode crashes CPU so it is not tested
;?? - opcode hasn't been tested yet, but will be later
; - opcode is not tested or otherwise dealt with yet
;tested opcode matrix
; 00 20 40 60 80 A0 C0 E0
;--------------------------
;00 XX XX XX uu XX XX XX
;01 XX XX XX XX XX XX XX XX
;02 == == == == == XX == ==
;03 uu uu uu uu uu uu uu uu
;04 uu XX uu uu XX XX XX XX
;05 XX XX XX XX XX XX XX XX
;06 XX XX XX XX XX XX XX XX
;07 uu uu uu uu uu uu uu uu
;
;08 XX XX XX XX XX XX XX XX
;09 XX XX XX XX XX XX XX XX
;0A XX XX XX XX XX XX XX XX
;0B -- -- -- -- -- -- -- uu
;0C uu XX XX XX XX XX XX XX
;0D XX XX XX XX XX XX XX XX
;0E XX XX XX XX XX XX XX XX
;0F uu uu uu uu uu uu uu uu
;
;10 XX XX XX XX XX XX XX XX
;11 XX XX XX XX XX XX XX XX
;12 == == == == == == == ==
;13 uu uu uu uu -- uu uu uu
;14 uu uu uu uu XX XX uu uu
;15 XX XX XX XX XX XX XX XX
;16 XX XX XX XX XX XX XX XX
;17 uu uu uu uu uu uu uu uu
;
;18 XX XX XX XX XX XX XX XX
;19 XX XX XX XX XX XX XX XX
;1A uu uu uu uu XX XX uu uu
;1B uu uu uu uu -- -- uu uu
;1C uu uu uu uu -- XX uu uu
;1D XX XX XX XX XX XX XX XX
;1E XX XX XX XX -- XX XX XX
;1F uu uu uu uu -- uu uu uu
;
Looks like I test everything except BRK and 13 "invalid" opcodes. I just never got around to BRK since it's just another interrupt and I had tested those previously.
This program was mainly written for my own use to test out the CPU in my FPGA NES, but I did run it on alot of other emulators for shits and giggles. It was originally developed on CopyNES, so I know it works on the real thing properly.
kevtris wrote:
As for why they all aren't tested, I test every useful "invalid" opcode, along with many others. About the only ones I don't test are the very odd and utterly useles codes, along with the unpredictable ones, and of course the "halt" codes.
Purely a matter of opinion. For the purposes of accurate NES emulation, we really need those other ones tested (including the BRK opcode (IT IS STILL AN OPCODE!).
I agree that tests for BRK behavior should be added, but how would one test an opcode whose behavior cannot be reliably predicted given what we already know about its behavior? And how would one test all HLT opcodes sequentially if the mapper cannot assert RESET?
Oh no, I agree that HLT cannot be tested, but the other opcodes, no matter their stability, should be tested ten times or something to see what results are returned. I ask this question because I am trying to add support for the other 13 odd opcodes and different 6502 technical documents are telling me different things.
First, I don't see any reason to support all the 256 opcodes while emulating the NES. If you run a piece of code within "invalid" opcodes, you still watch their behaviour and can describe them. For general emulation, or even homebrew development, it might be useless. Next, if you really want a test ROM for opcodes, it might not exist as you wish. Your task is to understand the instruction/opcode itself, rather than its amount of cycles. What's the secret of "read a byte (+1 cycle), setting flags" and such? If something seems incomplete or inaccurate, so go ahead and update the wiki with something useful to us. ^_^;;
Erm, I don't have any means of testing a real NES. Can anyone else do it for us? (*Cough...* blargg *Cough...*)
WedNESday wrote:
Erm, I don't have any means of testing a real NES. Can anyone else do it for us? (*Cough...* blargg *Cough...*)
You know, it'd be much easier if he had something concrete to test rather than having to come up with a test by himself.
Some opcodes may have different behavior depending on the second-source manufacturer. For instance, a 6502 manufactured by MOS Technology may differ from a 6502 manufactured by Ricoh. (Ricoh made the NES chipset.) Anything involving the $EE may be affected because the $EE seems to come from the decimal-mode circuitry, which is omitted from the 2A03. In addition, a few of the "unstable" opcodes such as $9E have been found to differ based on the high bits of the program counter, which in turn differs whether you try it on a C=64, an Apple II, an Atari 800, or an NES, because they all load code into different parts of address space.
For now, just halt on the "highly unstable" or "disputed" opcodes so that a developer who is smoketesting a build on your emulator can tell when the program has jumped off into nowheresville.
I don't care much for unofficial opcodes. In my NES emulator I only handle the documented ones (and a few of the other NOP and 2-byte NOP codes) and have encountered very few common-mapper cartridges that execute them, and it could be that even these are due to bugs in my emulator rather than intentional use of them. I imagine Nintendo would not have accepted games which used them since it might limit their options in future NES hardware revisions and emulators.
Some time ago I traced the code for the SMB/Tetris/Nintendo World Cup multicart to verify its unique mapper behavior, and in so doing I noticed a couple of two-byte NOPs (most likely a patch in an effort to produce the multicart). Thus, Nintendo used an undocumented opcode at least once.
It's my understanding that the more bizarre opcodes behave differently depending on whether the instruction was interrupted by DMA. Testing such behavior would be tricky (as you would need to use the DPCM to do it), but that is one thing I've always wondered about.
Another thing to consider is that some Game Genie codes may work by creating an undocumented opcode.
Man, you can't create opcodes. You bear what the NES CPU supports.
Yes, and the original 2A03 CPU does indeed support various undocumented opcodes. Nothing is being "created". My point is that some Game Genie codes may change game behavior by altering a documented opcode byte into an undocumented opcode byte.
Translation: the Game Genie effectively modifies the PRG data, so even though most games themselves don't use unofficial opcodes (beyond a few multibyte NOPs), the application of Game Genie codes might result in use of them. Personally I doubt many Game Genie codes use unofficial opcodes; I'd guess that the most common codes change the branch condition, replace an instruction with NOP (perhaps one of the multibyte versions), or change the operand of an immediate instruction.
On the topic of the multi-byte NOPs, they can be very useful for implementing multiple entry points to a routine, so I can understand why they'd be allowed by Nintendo. Perhaps their behavior is very well-defined as compared to the other unofficial opcodes.
So, it sounds like multi-byte NOPs should probably be implemented even if you aren't going to do the full undocumented opcode set. They are far more likely to be used, and are included in at least one licensed game if the above info is correct. Besides, they're very easy to add.
It depends of what you wish to do...? We have hundreds of great titles and... none of them use unofficial opcodes, except the NOP. Plus, by merely replacing a certain byte of PRG data does not mean you'll be happy. You would need to disassemble the game, to study its source code and so... to think about changing something. Just don't dream thinking "it's hot!" because it isn't. ^_^;;..
I know for a fact that Puzznic uses one of the multi-byte NOPs, and will have periodic screen scrambles if you don't support it.
Yeah, and a few japanese titles too... ^_^;;..
Disch wrote:
I know for a fact that Puzznic uses one of the multi-byte NOPs, and will have periodic screen scrambles if you don't support it.
I remember Q talking about this in #nesdev awhile back. seems there was a single bit error in the ROM data which turned a load or store instruction into an invalid opcode. So, I don't think it was on purpose.
The more interesting question would be how the single bit error occured between development and final ROM.
With the existence of the BIT instruction, is there really a need for 2- and 3-byte NOPs?
If I don't want to implement the large number of undocumented instructions, is there any good way to still use the nestest rom (or some other rom)? I do automated checks against nestest.log, but once I stumble on something like LAX, I can't just skip it, because the updates to A and P bork all the following checks.
Kind of disappointing, because I've implemented all the documented opcodes, but the test fails around 5K instructions in from the undocumented ones.
foobaz wrote:
If I don't want to implement the large number of undocumented instructions, is there any good way to still use the nestest rom (or some other rom)? I do automated checks against nestest.log, but once I stumble on something like LAX, I can't just skip it, because the updates to A and P bork all the following checks.
Kind of disappointing, because I've implemented all the documented opcodes, but the test fails around 5K instructions in from the undocumented ones.
i don't believe there is, but the ones it uses are dead simple to implement. in my emulator i have a define called "UNDOCUMENTED" so i can compile with or without support for them.
but yeah it's really simple to add the ones you'll need. this is literally all i needed to handle the predictable ones:
Code:
#ifdef UNDOCUMENTED
static void lax() {
lda();
ldx();
}
static void sax() {
sta();
stx();
putvalue(a & x);
}
static void dcp() {
dec();
cmp();
}
static void isb() {
inc();
sbc();
}
static void slo() {
asl();
ora();
}
static void rla() {
rol();
and();
}
static void sre() {
lsr();
eor();
}
static void rra() {
ror();
adc();
}
#else
#define lax nop
#define sax nop
#define dcp nop
#define isb nop
#define slo nop
#define rla nop
#define sre nop
#define rra nop
#endif
For what it's worth, I went ahead and pulled down blargg's instruction tests and they are nicely grouped into official and not. I had to do some tweaking to actually set the PC from the reset vector as well as map two pages of program rom correctly (only had code for mapping one page at both addresses) - these are all good things, though.
Wrote some code to display the output at 0x6004 and...
"01-implied
Passed"
Yay. More tests to go run.