Quantcast
Channel: Emulators - World of Spectrum
Viewing all articles
Browse latest Browse all 477

New emulation approach idea - convert the Z80 to orthogonal RISC?

$
0
0
Hi,

just interested in hearing some feedback about my new emulation approach idea. My hobby is writing software for retro computers and the problem with retro computers is that software does not only need to be super fast - it also needs to be super small. A typical emulation today is 1700+ lines of code which is way too much for a small system with possible 48 KB of free memory. I want to do it in less than 1/3 of that with minimal performance penalty. Here's the inspiration - a nano 8080 emulator. The following text is a theoretical idea about how to do it.

I love systems with clean instruction sets. They are easy to emulate, they can use table driven assemblers and disassemblers, etc. So what if we could easily turn Z80 into an orthogonal RISC? A typical Z80 emulation has an opcode table. This table is typically 256 (4 byte) pointers to functions that implement instructions (or forward it to next table for multi-byte instruction decoding).

The first step towards RISC would obviously be reducing the number of instructions by grouping them. For example all loads in one group. All jumps (CALL, JR, RET, RST, JP, DJNZ...) in another. We would have max. 16 instruction groups. We can then make these groups instructions and invent opcodes for each that use only 4 bits (a nibble). This gives us a RISC.

The second step is assuming the orthogonal architecture (i.e. each instruction supports all addressing modes). Why? Because we can then use only one function to decode the parameters. Ideally we would parametrize operands into 12 bits (so that opcode plus extended opcode takes 2 bytes).

Finally, we create a half smaller opcode table (512 bytes) with two bytes holding opcode for each instruction and unified (orthogonal) information about operands. First nibble gives us the emulation function index. We then call this function passing it the operands which are decoded in the same way. Since the operands are always passed in the same way it is like having a precompiled decoder for them.

To summarize the idea: we would effectively be using the opcode table to do 2 things:
1) to find an emulation function for the opcode (which is how we do it right now, but we would route opcodes to max 16 instruction groups i.e. RISC instructions) and
2) to convert operands to the expected unified (optimized) form to reduce decoding logic with minimal performance penalty. What about the addressing modes that are not supported by Z80? They are just theoretical and they won't be in the opcode table.

Could this approach work and reduce the size of the Z80 emulator.

Sincerely,
Tom

Viewing all articles
Browse latest Browse all 477

Trending Articles