Techniques for skipping unofficial instructions

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Techniques for skipping unofficial instructions
by on (#117766)
It's useful for an emulator to at minimum skip the correct number of bytes when encountering unofficial instructions. Perhaps people could share some approaches. I'll start with the shortest code I could come up with. It assumes you've already read the opcode and advanced pc to the next byte.
Code:
pc += (0xA280414082444141 >> ((opcode & 0x1F) * 2) & 3) + ((opcode & 0x9F) == 0x82);

There's also the table approach
Code:
static int const instr_lens [256] = { // lengths including opcode
   2,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,// 0
   2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,// 1
   3,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,// 2
   2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,// 3
   2,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,// 4
   2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,// 5
   3,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,// 6
   2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,// 7
   2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,// 8
   2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,// 9
   2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,// A
   2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,// B
   2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,// C
   2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,// D
   2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,// E
   2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,// F
};

pc += instr_lens [opcode] - 1;


EDIT: fixed JSR/JMP lens
Re: Techniques for skipping unofficial instructions
by on (#117770)
I've seen GCC generate that lookup-table-in-integer approach for some switches. It's pretty neat.

If an emulator encounters an unofficial instruction it's likely that it's either executing bad code or that the instruction is crucial for the code to work though, so not sure how helpful it would be to just skip over it.

Lookup table would be fastest. Could make the entries uint8_t too to save some cache. Byte lookups should be as fast on x86 at least.
Unofficial opcodes are hard, let's go shopping
by on (#117772)
ulfalizer wrote:
If an emulator encounters an unofficial instruction it's likely that it's either executing bad code or that the instruction is crucial for the code to work though, so not sure how helpful it would be to just skip over it.

I was under the impression that the use case was procrastination. Unofficial opcodes are hard, so one might choose not to implement any until all the official ones are perfect. Yet a lot of existing CPU test ROMs test the useful unofficial opcodes in addition to the official ones.

It might also help with emulating systems using a 65C02, which I'm told does just skip unofficial opcodes according to their length. Platforms using 65C02 include Apple IIc and enhanced IIe as well as Atari Lynx. The HuC6280 in a TG16 is an extended 65C02 if I remember correctly.
Re: Unofficial opcodes are hard, let's go shopping
by on (#117774)
tepples wrote:
ulfalizer wrote:
If an emulator encounters an unofficial instruction it's likely that it's either executing bad code or that the instruction is crucial for the code to work though, so not sure how helpful it would be to just skip over it.

I was under the impression that the use case was procrastination. Unofficial opcodes are hard, so one might choose not to implement any until all the official ones are perfect. Yet a lot of existing CPU test ROMs test the useful unofficial opcodes in addition to the official ones.

It might also help with emulating systems using a 65C02, which I'm told does just skip unofficial opcodes according to their length. Platforms using 65C02 include Apple IIc and enhanced IIe as well as Atari Lynx. The HuC6280 in a TG16 is an extended 65C02 if I remember correctly.


Yeah, sounds reasonable enough. Might've been a bit dismissive. :)

The test ROMs I've come across allow you to test official instructions only, but could still be useful for implementing and testing only a subset of unofficial ones I guess.
Re: Techniques for skipping unofficial instructions
by on (#117775)
Why are the instruction lengths for JSR and JMP Absolute set to 4 in that table by the way?
Re: Techniques for skipping unofficial instructions
by on (#117777)
I copied the table from my instruction timer, which apparently used 4 as a flag that it needed special handling (change-of-flow instruction).
Re: Techniques for skipping unofficial instructions
by on (#117888)
This is definitely cool, thanks for making this.

But what I'd really, really like to see is a truly comprehensive explanation of all unofficial instructions, and C code for how to implement them (at the cycle level), and one name for each of them.

Every document is missing important information, and has different names for them. It would be great if we could all agree on a unified set of names and behavior details.
Re: Techniques for skipping unofficial instructions
by on (#117889)
I think their behavior differs on different implementations, since some have analog elements and are thus hard to pin down. People already use various names in assemblers and code, and each platform has its own distinct culture, so no chance at all of unifying names.
Re: Techniques for skipping unofficial instructions
by on (#117900)
Yeah, agreed-upon names would've been nice. I have a mix of them from different sources in my implementation. :|

TIck-by-tick execution is determined by the addressing mode for the unofficial instructions as well, so nothing complicated there. Some instructions have bus conflicts though: viewtopic.php?f=3&t=3831&start=30 .
Re: Techniques for skipping unofficial instructions
by on (#117923)
For my page about the more useful instructions, I used the names in ca65's 6502X mode.
Re: Techniques for skipping unofficial instructions
by on (#117949)
This thread gave me the kick in the butt I needed to finally sit down and make a lookup table for instruction lengths and cycle numbers :D
Re: Techniques for skipping unofficial instructions
by on (#119203)
To be honest this is a total waste of time blargg (respectfully).

1. Hardly any games use illegal opcodes so coming across them is not only rare but also easy to cater for as they are nothing more than combinations of normal opcodes.
2. All illegal opcodes should already be emulated anyway as they exist on a real NES and some games do rely upon them.
3. They are well documented and as someone has already pointed out, there are many test ROMs in existence to assist with their testing.