Fixed G-Stream G2020's sound banking. Compared with a real PCB and everything sounds as it should. [trap15]

This commit is contained in:
Scott Stone 2012-08-28 13:26:16 +00:00
parent 503802a026
commit 01346c2a07

View File

@ -160,8 +160,8 @@ public:
UINT32 m_tmap3_scrolly;
/* misc */
int m_oki_bank_0;
int m_oki_bank_1;
int m_oki_bank_2;
DECLARE_WRITE32_MEMBER(gstream_palette_w);
DECLARE_WRITE32_MEMBER(gstream_vram_w);
@ -293,68 +293,64 @@ ADDRESS_MAP_END
WRITE32_MEMBER(gstream_state::gstream_oki_banking_w)
{
/* OKI BANKING (still far from perfect, based on game behaviour)
/*
****OKI BANKING****
Possibly perfect? works perfectly in-game, may not cover all possibilities.
Needs code testing on PCB.
The two OKIs can independently play music or samples and are switched on the fly during game
This is a preliminary table of the banks:
The two OKIs can independently play music or samples, and have half of the
sound ROMs to themselves. Sometimes the first OKI will play music, and some
times it will play samples. The second OKI is the same way. The banks for
both OKIs are laid out like so:
BANK MUSIC SAMPLES
0 X
1 X
2 X
3 X
4 X
5 X
6 X
7 X
BANK MUSIC SAMPLES
0 X
1 X
2 X
3 X
Two nibbles are used in this handler: (data & 0xf) and ((data >> 4) & 0xf)
The values for the first nibble are the followings and should map the 8 oki banks:
- 0x6, 0x7, 0x9, 0xa, 0xb, 0xd, 0xe, 0xf
The values for the second nibble are the followings and should probably be used too:
- 0x6, 0x9, 0xa
Bank 0 is the same in both ROMs.
Same values are redudant, for example:
level 2: data = 0x99
level 6: data = 0x99
(this means same background music for the two levels - it could be correct, though)
The banking seems to be concerned with half-nibbles in the data byte. For
OKI1, the half-nibbles are bits 76 and 32. For OKI2, 54 and 10.
The bank's '2' bit is the first half-nibble's bottom bit bitwise AND with
the inverse of its top bit. The bank's '1' bit is the second half-nibble's
bottom bit bitwise AND with the top bit.
Also with current implementation, using only (data & 0xf), we have to force some values
manually, because the correspondent places in the table are already used
This may or may not be correct, but further PCB tests are required, and it
certainly sounds perfect in-game, without using any "hacks". */
Musics order is completely guessed but close to what the original PCB game should be */
/*
7654 3210
1010 1010 needs oki2 to be bank 0
1010 1011 needs oki2 to be bank 1
1010 1011 needs oki1 to be bank 0
static const int bank_table_0[16] = { -1, -1, -1, -1, -1, -1, 0, 0, -1, 6, 0, 5, -1, 0, 0, 0 };
static const int bank_table_1[16] = { -1, -1, -1, -1, -1, -1, 2, 2, -1, 0, 0, 4, -1, 1, 1, 1 };
7654 3210
1010 1111 needs oki1 to be bank 1
1010 1110 needs oki1 to be bank 1
1010 1110 needs oki2 to be bank 0
//popmessage("oki_0 banking value = %X\noki_1 banking value = %X\n",data & 0xf,(data >> 4) & 0xf);
7654 3210
0110 0110 needs oki1 to be bank 2
0110 0110 needs oki2 to be bank 0
m_oki_bank_0 = bank_table_0[data & 0xf];
m_oki_bank_1 = bank_table_1[data & 0xf]; // (data >> 4) & 0xf ??
6and!7 & 2and3
/* some values are already used in the table, so we force them manually */
if ((data == 0x6f) || (data == 0x6e))
{
m_oki_bank_0 = 0; // level 3b-5a samples
m_oki_bank_1 = 6; // level 3b-5a music
}
4and!5 & 0and1
if (data == 0x9b)
{
m_oki_bank_0 = 7; // level 7 music
m_oki_bank_1 = 0; // level 7 samples
}
*/
if (data == 0x9f)
{
m_oki_bank_0 = 0; // end sequence samples
m_oki_bank_1 = 3; // end sequence music
}
m_oki_bank_1 = ((BIT(data, 6) & !BIT(data, 7)) << 1) | (BIT(data, 2) & BIT(data, 3));
m_oki_bank_2 = ((BIT(data, 4) & !BIT(data, 5)) << 1) | (BIT(data, 0) & BIT(data, 1));
m_oki_1->set_bank_base(m_oki_bank_0 * 0x40000);
m_oki_2->set_bank_base(m_oki_bank_1 * 0x40000);
//popmessage("oki bank = %X\noki_1 = %X\noki_2 = %X\n",data, m_oki_bank_1, m_oki_bank_2);
m_oki_1->set_bank_base(m_oki_bank_1 * 0x40000);
m_oki_2->set_bank_base(m_oki_bank_2 * 0x40000);
}
// Some clocking?
WRITE32_MEMBER(gstream_state::gstream_oki_4040_w)
{
// data == 0 or data == 0x81
@ -365,9 +361,9 @@ static ADDRESS_MAP_START( gstream_io, AS_IO, 32, gstream_state )
AM_RANGE(0x4010, 0x4013) AM_READ_PORT("IN1")
AM_RANGE(0x4020, 0x4023) AM_READ_PORT("IN2") // extra coin switches etc
AM_RANGE(0x4030, 0x4033) AM_WRITE(gstream_oki_banking_w) // oki banking
AM_RANGE(0x4040, 0x4043) AM_WRITE(gstream_oki_4040_w) // ??
AM_RANGE(0x4050, 0x4053) AM_DEVREADWRITE8("oki2", okim6295_device, read, write, 0x000000ff) // music and samples
AM_RANGE(0x4060, 0x4063) AM_DEVREADWRITE8("oki1", okim6295_device, read, write, 0x000000ff) // music and samples
AM_RANGE(0x4040, 0x4043) AM_WRITE(gstream_oki_4040_w) // some clocking?
AM_RANGE(0x4050, 0x4053) AM_DEVREADWRITE8("oki1", okim6295_device, read, write, 0x000000ff) // music and samples
AM_RANGE(0x4060, 0x4063) AM_DEVREADWRITE8("oki2", okim6295_device, read, write, 0x000000ff) // music and samples
ADDRESS_MAP_END
static INPUT_PORTS_START( gstream )
@ -545,8 +541,8 @@ static MACHINE_START( gstream )
state->save_item(NAME(state->m_tmap1_scrolly));
state->save_item(NAME(state->m_tmap2_scrolly));
state->save_item(NAME(state->m_tmap3_scrolly));
state->save_item(NAME(state->m_oki_bank_0));
state->save_item(NAME(state->m_oki_bank_1));
state->save_item(NAME(state->m_oki_bank_2));
}
static MACHINE_RESET( gstream )
@ -559,8 +555,8 @@ static MACHINE_RESET( gstream )
state->m_tmap1_scrolly = 0;
state->m_tmap2_scrolly = 0;
state->m_tmap3_scrolly = 0;
state->m_oki_bank_0 = 0;
state->m_oki_bank_1 = 0;
state->m_oki_bank_2 = 0;
}
static MACHINE_CONFIG_START( gstream, gstream_state )
@ -623,14 +619,13 @@ ROM_START( gstream )
ROM_LOAD( "gs_gr_05.u174", 0x800000, 0x200000, CRC(ef283a73) SHA1(8b598facb344eac33138611abc141a2acb375983) )
ROM_LOAD( "gs_gr_06.u175", 0xa00000, 0x200000, CRC(d4e3a2b2) SHA1(4577c007172c718bf7ca55a8ccee5455c281026c) )
ROM_REGION( 0x200000, "oki1", 0 )
ROM_REGION( 0x100000, "oki1", 0 )
ROM_LOAD( "gs_snd_01.u192", 0x000000, 0x080000, CRC(79b64d3f) SHA1(b2166210d3a3b85b9ace90749a444c881f69d551) )
ROM_LOAD( "gs_snd_02.u194", 0x080000, 0x080000, CRC(e49ed92c) SHA1(a3d7b3fe93a786a246acf2657d9056398c793078) )
ROM_LOAD( "gs_snd_03.u191", 0x100000, 0x080000, CRC(2bfff4ac) SHA1(cce1bb3c78b86722c926854c737f9589806012ba) )
ROM_LOAD( "gs_snd_04.u193", 0x180000, 0x080000, CRC(b259de3b) SHA1(1a64f41d4344fefad5832332f1a7655e23f6b017) )
ROM_REGION( 0x200000, "oki2", 0 )
ROM_COPY( "oki1", 0, 0, 0x200000 )
ROM_REGION( 0x100000, "oki2", 0 )
ROM_LOAD( "gs_snd_03.u191", 0x000000, 0x080000, CRC(2bfff4ac) SHA1(cce1bb3c78b86722c926854c737f9589806012ba) )
ROM_LOAD( "gs_snd_04.u193", 0x080000, 0x080000, CRC(b259de3b) SHA1(1a64f41d4344fefad5832332f1a7655e23f6b017) )
ROM_REGION( 0x2000, "nvram", 0 )
ROM_LOAD( "gstream.nv", 0x000000, 0x2000, CRC(895d724b) SHA1(97941102f94923220d9beb270939f0ad9a40fe0e) )
@ -652,4 +647,5 @@ DRIVER_INIT_MEMBER(gstream_state,gstream)
}
GAME( 2002, gstream, 0, gstream, gstream, gstream_state, gstream, ROT270, "Oriental Soft", "G-Stream G2020", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
GAME( 2002, gstream, 0, gstream, gstream, gstream_state, gstream, ROT270, "Oriental Soft", "G-Stream G2020", GAME_SUPPORTS_SAVE )