So, after some talk on IRC, I started disassembling the game to see exactly is the cause of the randomness in the character selection. feos prompted me to put my findings here.
First off, this game seems to have been written in C++ and compiled to the 68k; and let me say, I did not know
how much compilers have improved in these ~20 years...
Anyway: each level has its own separate function that initializes the level data; the function responsible for setting up Siberia is at offset 0xFD6A8. Among other functions, this function calls the function at offset 0xFD614; this function is responsible for selecting which player you get.
If player 1 has not yet been initialized (specifically, it tests if the long at 0xffeaa8 is zero or not), then the following code gets run:
jsr j_DisableInterrupts-MainVTable(a5)
loc_FD62C:
moveq #0,d7
move.b (VDP_HV_counter).l,d7
moveq #0,d0
move.b (VDP_HV_counter).l,d0
cmp.w d7,d0
bne.s loc_FD62C
jsr j_EnableInterrupts-MainVTable(a5)
ext.l d7
move.w FrameCount_mod4-MainVTable(a5),d0
ext.l d0
add.l d7,d0
move.l d0,-(sp)
jsr j_InitRNG-MainVTable(a5)
jsr j_GetRandomP1-MainVTable(a5)
Ah, yes, the compiler has made pretty much all calls use a master VTable stored at register a5, and most of these calls point to trampoline functions (that is, a function that is nothing more than a jump to the real function). FrameCount_mod4 is a RAM location: 0xffc670, to be accurate; for Siberia, it is never updated from its initial value of zero, so it is utterly irrelevant.
Now for some info: VDP_HV_counter is a symbolic constant for 0xC00008; it is a memory-mapped port from the Genesis graphics chip, the VDP. You can read it as a byte or as a word; if reading as a word, the low byte is the same as you would get from reading port 0xC00009. Port 0xC00008 is the Horizontal/Vertical counter, or H/V counter. The byte read in the code above is the vertical counter -- it is the line in which the electron beam is in the TV (or would be, in the case of modern TVs and emulators). The other byte would be the horizontal counter, and shows which column the electron beam is in -- it is counted in pairs of pixels because it is a single byte (not that it matters, as the VDP is a lot faster than the 68k anyway...). The game reads it twice, compares and loops just to make sure that the beam is not too close to changing a line.
With these considerations out of the way, we can write the above as the following pseudo-c code:
word scanline = VDP_Get_Active_Line();
InitRNG(scanline + *(word *)FrameCount_mod4);
GetRandomP1();
So: the current scanline is being used to seed the random number generator, which is then used to select P1.
And there is the pickle: Gens-rr is deterministic, so the H/V counter is set to a known value; in real hardware, and in some other emulators, it would be an essentially random value. Changing controller settings works for changing the initial character because the code to read from a 6-button controller is
slightly slower than the code for reading from a 3-button controller; this is enough to change one scanline, but only because the game was apparently close to it already. As far as I can tell, there is no way to gain the 488 clock cycles needed to gain another scanline.
So until there is a setting to change the initial value of the H/V counter, the best that can be done is using Wolverine in that level.