[Q]Is an Arduino powerful enough to fully emulate an MBC?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
[Q]Is an Arduino powerful enough to fully emulate an MBC?
by on (#127846)
I recently coded a gameboy cartridge dumper for my arduino in order to get in touch with gameboy hardware, it works pretty well
(after i lost my pokemon blau save in an attempt to dump the sram -_- but now i found the bug and it dumps everything properly).
I have another project ongoing, but as long as i cannot work on that, i wanted to do some further developement on the gameboy,
so I wanted to know if there is any information on whether the arduino (or rather the atmega chip on it) would be able to emulate
an MBC, at best the MBC5 which would then, as far as i know, be compatible with the other MBC types (excluding the ones with RTC).
I searched around the inet for information or someone who has already tried, but there was only information on CPLDs
capable of doing the work of an MBC. I fear that it is not fast enough to do so as it is not rally fast with its 16MHz, but I could be wrong.
To me it seems like the MBC is rather easy to reproduce in software as it does not much (just rom and ram banking and switching between the chips).
If the arduino would be capable to do so, I would have an awesome idea, which i would then try to make real :D
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#127847)
Like the MMCs of the NES, an MBC is a mapper. Internally, a mapper is a tiny RAM with some logic post-processing its output, and its effects are expected to be visible on the next CPU cycle. This is what CPLDs were made for, but I understand that getting started with a CPLD might be cost prohibitive for you.

On 8080-family host systems, such as the ColecoVision/SG-1000, Master System/Game Gear, and Game Boy, you have a little leeway because the CPU has a bunch of "internal operation" cycles between memory accesses. But I'm still not entirely sure that a microcontroller is better for this job than a CPLD. Someone else more familiar with Atmel ATmega MCUs might be able to help.

Image
Cart edge signals


Every /RD or /WR will need to cause an interrupt that decodes CPU A15-A13 and sets a bunch of outputs connected to ROM A24-A14 and SRAM A14-A13. Every /WR will also have to decode A15-A13 to find which port on the mapper the program wrote to so that it can recompute the next set of output states.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#127850)
An Arduino is definitely not fast enough. The overhead of running its moderately inefficient runtime/language basically ruins any chance of doing it in time.

Hand-written assembly on almost any microcontroller (a plain Atmega, a PIC, a MSP430, some 8051s) might be able to keep up with it.

Positing "fully emulate" requires that the microcontroller handle changing the bank every time the GB reads from the bottom 16 KiB vs. 2nd 16KiB of data. If you add a 74HC08 (quad AND gate) or two (for games bigger than 256KiB), then assembly will definitely work, and the Arduino moves to "well, maybe, but I'd be surprised".

For most of the MBCs I'd probably build it out of discrete logic: it would be tremendously lower power than a CPLD anyway, even if together they are physically bigger. Something close to an MBC5 should be six to eight ICs.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#127852)
The Arduino IDE is capable of doing something called PortManipulation, which is changing the state if the IO Pins in a really fast manner, but i am not sure if this is even fast enough.
I found a blogpost in which someone was able to pass the data of the Nintendo Logo stored in the EEPROM of the Arduino to the Gameboy and it was able to read the data. He also used PortManipulation for the arduino in order to make it fast enough to pass the data through for the gameboy.

To the idea of using discrete logic: it should not be very hard to get discrete logic do the work of an MBC, but as you already pointed out, it would be much bigger than using a CPLD or the actual mapper chip (i wanted it to be not bigger than an actual cartridge for portability and nkt something bulky) and it would only be able to do what the MBC would have done, but what i had in mind was to add more features than just rom and ram banking to a mapper chip, and from capabilities, the Arduino (or more specific the ATmega chip) seemed like it was pretty much fitting my needs (very small chip, cheap to get and easy to work with, at least for me :D), but i was not sure if it was fast enough.
If it is totally not possible to get this to work only with an ATmega Controller, then i will leave it.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#127853)
Thing is, the fastest Atmegas run at 20MIPS, and the GB runs at approximately 1MIPS. You'll need to do everything necessary within 20 instructions to react fast enough. I don't know if the PortManipulation is fast enough to do that.

If you're willing to write a rather simple ATmega assembly program, and are willing to add two (or three, if you want 8megabyte cartridge support) 74HC08s, you should be fine.

You'll basically be doing what tepples said. Connect the microcontroller to GB /WR, A15, A14, A13, D0 through D7, and (for the MBC5) A12.
Set up an interrupt on falling edges on the /WR pin.
In the interrupt, first latch the twelve other input pins, then use a jump table to decide what to do based on A15..A12.
The sixteen functions will correspond to writes to $0xxx, $1xxx, &c, and so the first two will control the RAM enable, the next one is the lower 8 bits of the bank, &c.
Then the functions that actually do things will output the fixed signals +RAM ENABLE, ROM A14..A24, RAM A13..A16.
All-in-all this will require a microcontroller with at least 26 I/O lines, so you'll need one of the 40-pin microcontrollers. (The atmega(4/8/16/32)8 series doesn't quite have enough pins. You could shave off maximum size of RAM or ROM to make it fit, though)
The 74'08s will convert the ROM A14..A24 from the microcontroller to the banking style expected by the MBC5.

SNgamer wrote:
(i wanted it to be not bigger than an actual cartridge for portability and not something bulky)
I think it should fit. We can get TSSOP or BGA versions of all of the necessary chips, and I'm pretty certain that could fit in the 1 in² area we seem to have.

For any 4MB-or-smaller (and therefore doesn't need the register at 0x3XXX) MBC5-compatible games that don't have RAM (and therefore doesn't need the registers at 0x0XXX and 0x4XXX), this becomes trivial because the logic both becomes simpler and we gain the a whole extra square inch inside the cartridge. (A cartridge like this should be 4 ICs: a 74'138, a 74'573, and two 74'08s )
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#127864)
I've given this some thought, an although an AVR is running at far greater clock speeds than the GB bus, (don't even consider Arduino) You will need logic doing your switching as the gameboy expects the data to be on the bus almost the same time as the /RD is asserted. If you were given 1 GB clock cycle to have it prepared then an AVR will get the job done, but that is not what the gameboy is asking. AVR + Logic Yes, AVR alone, no.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#127866)
BennVenn wrote:
I've given this some thought, an although an AVR is running at far greater clock speeds than the GB bus, (don't even consider Arduino) You will need logic doing your switching as the gameboy expects the data to be on the bus almost the same time as the /RD is asserted. If you were given 1 GB clock cycle to have it prepared then an AVR will get the job done, but that is not what the gameboy is asking. AVR + Logic Yes, AVR alone, no.


This being said and the information by lidnariq, I can now try to figure out a solution for this.
Thanks for the information
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128026)
Really, this is a job for a CPLD, not a microcontroller. However, assuming you currently have an Arduino, you could use it as a JTAG programmer for a CPLD such as the XC9500XL series, which would cut down on the entry cost of CPLD development.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128038)
qwertymodo wrote:
Really, this is a job for a CPLD, not a microcontroller. However, assuming you currently have an Arduino, you could use it as a JTAG programmer for a CPLD such as the XC9500XL series, which would cut down on the entry cost of CPLD development.


I sure know that a CPLD is capable of this job and it should not be hard to program it in order to support suh task (there are also proof of concepts for such a thing). But I wanted to know if an Arduino is also suited for such a task (what seems to be not the case, unfortunately).
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128039)
If you had to use an arduino... then maybe you could do some on chip hardware magic like using its comparator, in conjunction with its hardware timers, Input Capture hardware, Output compare hardware, that sort of stuff to trigger hardware level events, to give you CPLD speed, and using the AVR core to enable/disable certain combinations to perform the function of a MBC? That would be thinking outside the box...
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128060)
Capture lets you know exactly when something happened, regardless of how much later you get to it.

Compare lets you change a few pins (five? if you cleverly abuse all three of the atmega's counters) in response to a pin changing. So, you might be able to use that to emulate an AND gate, but I bet there's still situations where you'll need to have your interrupt routine finish in 1µs (such as fetching data from 0x4xxx while executing code from 0x0xxx)

Fundamentally, the MBC1 and MBC5 are just a few latches and some decoding logic. The MBC2 and MBC3 are a little more complicated (with internal RAM or an RTC).
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128062)
I have already got a solution in mind for getting either MBC1 or MBC5 emulated (because of their simplicity), when I have some freetime (unfortunately, I wont get any for some time :( ) I will try to get it done.
If i have got something useful, I will for sure let you know ;)

And MBC2 should be very easy to implement, as the Arduino has enough internal EEPROM space which should be able to act as internal SRAM for MBC2 games ;)
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128064)
Implementing the MBC2's RAM will be nigh-impossible. The address bus is only stable 2cy (500ns for a 4MHz game) before you need to have the value presented to the GBZ80, so that only gives you 10 instructions in a 20MIPS atmega... and I think you lose at least 5 of those just in interrupt latency. Other sources imply closer to 8-11... you're too late before your code even starts executing!

A PIC might almost be able to do it... They max out at 16MIPS, and I can think of a way to implement a 256 byte RAM (yes, too small) in 6cy (375ns).

Someone asked about hooking up an atmega to the ISA bus, which doesn't run tremendously faster than the GB... I really think the notion of implementing RAM inside the micro is a non-starter.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128065)
Maybe if you were to use one of the arduino Mega's? It has an Xbus interface. Not too familiar with it, but perhaps it could monitor your data and address bus along with control signals? All just ideas. How about burning an EEPROM with a bit mask which sits on the address bus and generates outputs on its data bus when reads/writes to particular addresses are made. Use these outputs to latch registers. You could have a very complicated, narrow set of addresses that trigger certain functions.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128070)
The Atari 2600's Harmony cart can emulate a 32KiB ROM accessed by a 6502 clocked at 1.2MHz using a 70MHz ARM. (It also does a number of really other fun things, like automagic loop unrolling). The timing constraints here are about twice as tight, but I think we need to do less.

The big killer for emulating RAM (or ROM) is interrupt or task latency. Simply running things faster doesn't necessarily help, because faster CPUs often have more state they need to save when one thread interrupts another.

The Arduino Mega appears to be an atmega1280, which ... is this "xbus" thing what the datasheet refers to as the External Memory Interface? Unfortunately, that's for connecting the microcontroller to external memory-mapped peripherals (i.e. as atmega is still acting as the cpu), not to emulate a peripheral. Some PICs do have a "parallel slave port" that can respond to a host CPU with no latency, in the manner required here, but it's only one byte. It'd be really hard to make it work like RAM.

Burning an EEPROM as a decoder would be hard to justify as meaningfully different than a 74'138... This isn't doing anything particularly fancy here.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128071)
An EEPROM/EPROM/PROM/Flash would be far superior to a 74xx138. The amount of discrete logic requried to decode up to 256 different addresses for ANY address on the bus (16bit), would be enormous. And as we're not considering CPLD's or FPGA's, an EPROM as an address decoder would save much board space, at a speed that would surpass any MCU. An EPROM could also do the job of an MBC quite easily, with additional address lines used to select modes of operation. Very Fancy.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128075)
I did not want to use either CPLD, FPGA or discrete logic, I wanted to use only an AVR for this job. I actually wanted to use an arduino Mega(Atmega 2560), because I happen to own one and it has enough IOs to do all the decoding on its own.
Now, i did not know about these latencies, seems like these would make it near impossible to do the emulation due to speed issues...
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128079)
BennVenn wrote:
The amount of discrete logic requried to decode up to 256 different addresses for ANY address on the bus (16bit), would be enormous.
But we don't need to fully decode anything... and a ROM can only get us 8 (or 16, I guess) generated signals as a function of N inputs. So it would let us decode 8 independent and arbitrary groups of addresses ... but since the historical MBCs don't have any regions finer than 4 KiB (other than the Datel one), I don't see how that benefits us? It doesn't help us create a 512-address nybble-wide RAM.
SNgamer wrote:
I wanted to use only an AVR for this job
Sorry for hijacking your thread. I still think you can do it with an arbitrary AVR and two 74'08s. (Or one, if you only want to emulate games ≤ 256KiB)
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128087)
SNgamer wrote:
I did not want to use either CPLD, FPGA or discrete logic, I wanted to use only an AVR for this job. I actually wanted to use an arduino Mega(Atmega 2560), because I happen to own one and it has enough IOs to do all the decoding on its own.

Any particular reason for this, other than the fact that you already have it? I mean, maybe it might be possible, but you're trying to shoehorn together a solution out of hardware that just isn't designed for the job. You might as well be trying to accomplish it on a Raspberry Pi, heck it'd be half the price, and just as unsuited for the job, though the extra power might get the job done, especially since you could buffer the entire ROM/SRAM into RAM to speed up the access times. An Arduino Mega is complete overkill in all the wrong places.

If this is just for fun to see if you can do it, don't let me dissuade you from that, but if you're actually wanting to build a reasonable replacement for the MBC chips, the first step is choosing the right tool for the job, and the right tool for replacing an ASIC comprised of logic and registers is a chip containing logic and registers, i.e. a PLD. Emulating simple logic using a microprocessor is like wall-mounting a laptop to use it as a light switch.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128088)
On a Raspberry Pi, I'd just emulate the whole damn Game Boy.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128089)
qwertymodo wrote:
Any particular reason for this, other than the fact that you already have it? I mean, maybe it might be possible, but you're trying to shoehorn together a solution out of hardware that just isn't designed for the job. You might as well be trying to accomplish it on a Raspberry Pi, heck it'd be half the price, and just as unsuited for the job, though the extra power might get the job done, especially since you could buffer the entire ROM/SRAM into RAM to speed up the access times. An Arduino Mega is complete overkill in all the wrong places.

If this is just for fun to see if you can do it, don't let me dissuade you from that, but if you're actually wanting to build a reasonable replacement for the MBC chips, the first step is choosing the right tool for the job, and the right tool for replacing an ASIC comprised of logic and registers is a chip containing logic and registers, i.e. a PLD.


It was just a thought that ran through my mind while programming the Cartridge dumper for Arduino, it's not like that I want to do such thing because I own one or I need one, but more out of interest, in order to see what else can be done with an arduino, as no one has even attempted to ask if such thing like MBC emulation would be possible with an arduino (at least i have not found anything searching the web). And even if it was a waste of the hardware's capabilities, I mean, other than the time I would use to find out if it was capable of doing the emulation, nothing is lost by this :D
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#128090)
tepples wrote:
On a Raspberry Pi, I'd just emulate the whole damn Game Boy.

Exactly what I mean by overkill in all the wrong places. A RPi could easily emulate the entire GB, but I'm not sure if the GPIO latency could support emulating the MBC chips, for the same reason as with the Arduino, except with the added abstraction and overhead of an entire OS.

SNgamer wrote:
And even if it was a waste of the hardware's capabilities, I mean, other than the time I would use to find out if it was capable of doing the emulation, nothing is lost by this :D

Fair enough.
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#148022)
qwertymodo wrote:
Exactly what I mean by overkill in all the wrong places. A RPi could easily emulate the entire GB, but I'm not sure if the GPIO latency could support emulating the MBC chips, for the same reason as with the Arduino, except with the added abstraction and overhead of an entire OS.


I was thinking about trying exactly this on the RPi. Has anyone else tried it yet? Can anyone provide some reference material to help me get started?
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#148027)
... Emulating an MBC on the RPi? Well, you're not going to be running linux on it, that's for sure.

Nevermind that the power budget is daft: the DMC/CGB/GBA consumes about one half to one fifth the power the RPi does. Also the RPi isn't 5V tolerant, and the DMG/CGB are only 5V.

Assuming that you don't want to add the several AND gates, you'll need to have a loop that can always determine what the CPU is doing, and react within 1 microsecond. This should¹ be doable—after all, the Atari 2600 Harmony Cart emulates a ROM using a 70MHz ARM—but using RPi for it is rather like using a smartphone as a hammer... sure, it might work, but you're as likely to hurt yourself or break something as drive the nail.


¹: "should" because the RPi will have some amount of instruction/data caching latency that could screw up your budget. Who knows!
Re: [Q]Is an Arduino powerful enough to fully emulate an MBC
by on (#148229)
You can use an Atmega or another MCU, but it is the wrong tool for the job and the gains from doing it that way are not clear. This would be a great VHDL or Verilog learning project, though this can even be done with a graphical schematic capture.