The problem
I built myself adapters to use
SMS games on a Megadrive as well as
MarkIII/SMS-J on a Megadrive
. The adapters work well, but there is one complication:
When an SMS game is run on a Megadrive console, there is no bios to run before the game. The CPU executes the game right from the start. This can be a problem for games which rely on intialization normally performed by the bios, in particular setting up the stack pointer.
A quick workaround to this is to first run an SMS game that does not have this problem, turn off the power, insert the non-starting game and reapply power. Now the game should start. This is because even following the power cycle, the stack pointer register bits haven not faded away yet and are still at the last value used!
While the above trick seems to work well, it is not ideal. One needs
to repeat those steps every time, and one has to own at least one game
that starts without problems.
Sega's solution for the Power base converter
Sega used to sold a product equivalent to my adapter under the names
Power base converter,
Mega Adaptor(メガアダプタ),
Master System Converter or
Adaptador Para os Jogos Master System
according to the region of the world.
[1].
Sega's adapter did not have the game startup problem described in the previous paragraphs.
An
interesting discussion on smspower reveals that a simple programmable
logic chip was used to have the CPU run a few instructions to setup the
stack pointer prior to game execution:
21 01 E1 : LD HL, $E101
25 -- -- : DEC H
F9 -- -- : LD SP,HL
C7 -- -- : RST $00
The same thread also provides the chip's logic equations which shows
how the address bits on the BUS are used to present the instruction bytes
in consecutive order, and how a conflict between this chip and the
cartridge is avoided by letting the chip enable signal run through
this same chip. For complete technical details, please refer
to the discussion.
Interesting fact: Since the logic chip did not have enough outputs
to drive the BUS eight data bits, bit 0 is pulled high through
a resistor. So the instructions shown above all have the less
significant bit set to 1!
[1] Source:
http://segaretro.org/Power_Base_Converter.
My hack using an AVR micro-controller
My goal was to fix my problem quickly using what I had on hand without redesigning
the adapter PCB from scratch. I therefore decided to use my
small
multiuse PCB
featuring an Atmel AVR micro-controller (MCU).
The MCU monitors the read signal (RD) and after each pulse, drives the next
instruction value on the data bus, until all 6 bytes have been presented, after
which all MCU pins are switched to input mode to let the game run without
impediments.
The MCU does not monitor the CE signal since it is too slow to use it properly. The
data lines are therefore continuously driven, where normally they would be driven
only when CE and RD are low. This is not very clean, but since we are controlling
the instructions the CPU is executing and know that none of them result in writes (until
we let go of the bus), I don't think this is a problem.
To temporarily disable the CE signal going to the game cartridge, I installed a
1.5k resistor between the megadrive and the cartridge. The micro-controller is
wired to the cartridge side. To cartridge CE pin can be forced high by the micro-controller
during initialisation, preventing a conflict. Even though on the console
side this signal goes low, there is no danger thanks to the resistor which limits
the current. Once initialisation is complete, the corresponding micro-controller
pin is switched to input mode which lets the signal from the megadrive reach the
cartridge through the resistor. The resistor value is low enough not to slow down
transitions too much.
I simply reproduced what Sega did for the D0 bit, even though I still had a free output
on my MCU board (PORTB3). I don't remember why I did that (because I waited 3 months
to write this article) but it might have been to simplify programming during
development (one of the signals uses PORTB3). In any case, whatever the reason,
a pull-up resistor must currently be installed on D0, but it would be easy
to update the firmware to do away with this requirement.
Here are a few pictures of the circuit installed on my cartridge adapter. If you
built an adapter like mine or own a non-Sega adapter without the stack
initialisation circuit, you could use this small circuit to fix the problem.
Contact me if you are interested and I will add preprogrammed circuits to the store.
Source code is available here:
stackchip.tar.gz
Here is an abridged version showing the essential parts:
#define WAIT_RD() do { } while (PIND & 0x04)
#define WAIT_RD_HIGH() do { } while (!(PIND & 0x04))
#define OUTVAL(a,b) do { PORTC = a; PORTB = b | 0x10; } while(0)
#define RD_SYNC() do { WAIT_RD(); WAIT_RD_HIGH(); } while(0)
...
/* LD HL, $E101 */
OUTVAL(0x10, 0x00);
RD_SYNC();
OUTVAL(0x00, 0x00);
RD_SYNC();
OUTVAL(0x70, 0x20);
RD_SYNC();
/* DEC H */
OUTVAL(0x12, 0x00);
RD_SYNC();
/* LD SP,HL */
OUTVAL(0x7C, 0x20);
RD_SYNC();
/* RST $00 */
OUTVAL(0x63, 0x20);
RD_SYNC();
// hands-off the bus
while (1) {
DDRC = 0;
DDRB = 0;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
}
Disclaimer
I cannot be held responsible for any damages that could occur to you
or your equipment while following the procedures present on this page.
Also, I GIVE ABSOLUTELY NO WARRANTY on the correctness and usability
of the informations on this page. Please note, however, that the procedures
above have worked in my case without any damages or problems.
Now you cannot say that I did not warn you :)