> > Both. If it's in RAM, you have to keep track of whether it's been overwritten,
> > which can introduce significant overhead.
I'm thinking mainly of ARM, MIPS portable machines here by the way - x86 of course for 68000 is done and dusted since Pentium 2s. With an ARM and only about 8Meg of memory (or maybe even less on the GP32?), you have to be more careful - I don't think the structures for each opcode (dynamically or statically 'recompiled') can be too big.
I'm tempted by the idea of filling in the address of the handler for each opcode however adding arguments seems to be throwing away too much ram... I'm not sure it could be afforded on a portable machine.
How about passing in a pointer to a previous opcode 'instance'...
void (*execute)(int currentPc); // Handler for executing the opcode, either the flags version or not
char ra,rb; // Registers to use
And then you allocate a new one for each unique opcode (e.g. move d0,d2 gets a new Opcode structure, but following move d0,d2 opcodes point to the previous one)
Hmmm, not even convinced myself here! Because you need a unique current Program Counter for each one.
What I'd ideally like I guess is
unsigned int pc; // The PC where this opcode is
void (*execute)(); // Pointer to correct handler for executing the opcode, either the flags version or not
// Do you think it is really worth decoding 68000 source and dest register here?
//I mean isn't it just a shift and AND? Maybe worth including the opcode number itself instead
Am I worrying a bit too much here... I mean I guess that's only roughly the same size as the code in the original 68000 Program anyway (as long as you only recompile real opcode starts)? Do you think it would be roughly the same?
By the way... was there a name for this thing? It seems halfway between an interpreting emulator and a recompiler... Generator calls it a Dynarec, but it doesn't quite seem to me that it is because it doesn't emit real code, only IL code.
If it doesn't have a name, shall we give it a name? ;)
Intepretarec or InteRec or something... err no maybe not.....
Opcode Representation, Opcode Preparse, or something
> I think my approach to the problem would be to partition memory space into equal
> sized regions and keep a bitmap. For every memory write I would set the bit
> associated with the region containing the memory address. Then in the dispatch
> loop, the code would clear the cache if the region to be executed has been
> written and the bitmap would also be cleared. Writes to the current execution
> region would also require code to do an early exit back to the dispatch loop.
> For Nuance, I didn't really have to worry about this. None of the games use
> self-modifying code. The main processor is cached so the cache only needs to be
> flushed when the appropriate BIOS call is made. The three other processors are
> not cached but local memory is split into IRAM and DTRAM and the only way to
> access external memory is through DMA. The only check I make is to clear the
> cache for DMA reads from external memory to local IRAM. I assume that any code
> in the DTRAM area will be loaded by the main MPE via BIOS. This handles all
> existing situations so far. The instruction encodings are convoluted enough
> that self-modifying code would probably be more expensive than non-modifying
> code in both terms of speed and space so I'm not really concerned about
> supporting it.
> > > This is how the Nuon Aries3 processor works.
> > Speaking of which, is there a programmer's manual for this processor? I'd love
> > to add it to my little collection of CPU/DSP documentation :)
> The public version of the official documentation set is in the SDK which you can
> get from [url] instruction encoding document which is on http://emuforge.org in the
> files section of the forums.
You learn something old everyday...