Page 1 of 1

Memory Mapping Emulation : Switch case VS Pointer

Posted: Tue Oct 07, 2014 7:58 pm
by mickagame
I would like to discuss about another wayt to emulate memory mapping.

Actually most of the emulator emulate mapping adress with a switch case redirecting the memory operation to the correct chip.

For example to access ROM/RAM :

Code: Select all


u32 Genesis::c68kReadByte(u32 adr)
{
    u32 data;
    
    switch((adr >> 21) & 7)
    {

                case 7: /* RAM */
                     adr &= 0xFFFF;
                     READ_BYTE(work_ram, adr, data)
                     return data;

                case 0: /* ROM */
                case 1:
                     adr &= 0xFFFFFF;
                     READ_BYTE(cart->rom, adr, data)
                     return data;

...
I think today about emulating this memory mapping with a table of Chips pointers but i dont know in what way the performance will be affected.

In my emulator all chips are implementing interface depending their bus capability.
ByteReader : able to read byte
WordReader : '' word
ByteWriter : able to write Byte
WordWriter " Word

So it will be easy to create a 16MB function table for each type of access in wich each entry is a direct link to the Chip connected at this adress.

The code for my 68KBus could be (simplified) :

Code: Select all


public Class 68KBus {

private :

ByteReader*  byteReaderMapping[0x1000000];
WordReader* wordReaderMapping[0x1000000];
ByteWriter*   byteWriterMapping[0x1000000];
WordWriter*  wordWriterMapping[0x1000000];

public :
void init();

}

public void 68KBus::init()
{
   u32 i;

   /* Mapping ROM Cartridge */ 
   for(i=0;i<0x400000;i++)
   {
       /* Cartridge implement my ByteReader, WordReader, ByteWriter and WordWriter Interface */
       byteReaderMapping[i]  = cartridge;
       wordReaderMapping[i] = cartridge;  
       byteWriterMapping[i]   = cartridge;  
       wordWriterMapping[i]   = cartridge;    

       ...
   }
}

So When 68K Will access 68K Bus it will be :

Code: Select all

u32 Genesis::c68kReadByte(u32 adr)
{
   u32 data;

   data = byteReaderMapping[adr]->readByte(adr);

   return (data);
}
Does anyone had experimented the two design and how performance are affected by each of these design?

Thanks !

Posted: Tue Oct 07, 2014 8:51 pm
by r57shell
Today, modern compilators generate jump table from "switch-case" statement. It looks like jmp jmptable[case], so it actually same.
But when it needs dynamic mapping, of course every good emulator written in this manner.

For example: Gens, genplus-gx, MAME, MESS...
I don't know why do you think that most of emulators use "switch-case".

Posted: Wed Oct 08, 2014 12:20 pm
by mickagame
OK perhaps i've generalized too much the way emulators are désigned. I will use this design for my own. ;-)

Edit : 08/10/2014 18:28 pm

Posted: Wed Oct 08, 2014 4:26 pm
by r57shell
mickagame wrote:U will use this design for my own. ;-)
Me? I didn't understand.

Posted: Wed Oct 08, 2014 4:37 pm
by tryphon
mistype, he meant 'I' (the letter just next to U)

Posted: Wed Oct 08, 2014 4:46 pm
by mickagame
I've just corrected.
Sorry for my bad english ;-)

Posted: Wed Oct 08, 2014 5:15 pm
by r57shell
Your own emulator? :o

Posted: Wed Oct 08, 2014 6:18 pm
by mickagame
Yes.