mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
cvs: add 0x1885 sound trigger,
route16: small cleanup
This commit is contained in:
parent
98c80be468
commit
6bcdff58a8
@ -196,7 +196,7 @@ private:
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device_array<dac_byte_interface, 2> m_dac;
|
||||
required_device_array<beep_device, 4> m_beep;
|
||||
required_device_array<beep_device, 3> m_beep;
|
||||
required_device<tms5100_device> m_tms5100;
|
||||
required_ioport_array<4> m_in;
|
||||
required_ioport_array<3> m_dsw;
|
||||
@ -652,7 +652,7 @@ void cvs_state::_8_bit_dac_data_w(u8 data)
|
||||
m_dac[0]->write(data);
|
||||
|
||||
// data also goes to 8038 oscillator
|
||||
m_beep[0]->set_clock(data * 4);
|
||||
m_beep[2]->set_clock(data * 4);
|
||||
}
|
||||
|
||||
void cvs_state::_4_bit_dac_data_w(offs_t offset, u8 data)
|
||||
@ -677,12 +677,10 @@ void cvs_state::_4_bit_dac_data_w(offs_t offset, u8 data)
|
||||
|
||||
void cvs_state::sh_trigger_w(offs_t offset, u8 data)
|
||||
{
|
||||
/* offset 0 is used in darkwar, spacefrt, logger, raiders
|
||||
* offset 2 is used in darkwar, spacefrt, 8ball, superbik, raiders
|
||||
* offset 3 is used in cosmos, darkwar, superbik, raiders
|
||||
*
|
||||
* offset 1 is only used inadvertedly(?) by logger
|
||||
*/
|
||||
// offset 0 is used in darkwar, spacefrt, logger, dazzler, wallst, raiders
|
||||
// offset 1 is used in logger, wallst
|
||||
// offset 2 is used in darkwar, spacefrt, 8ball, dazzler, superbik, raiders
|
||||
// offset 3 is used in cosmos, darkwar, superbik, raiders
|
||||
|
||||
data &= 1;
|
||||
|
||||
@ -692,7 +690,10 @@ void cvs_state::sh_trigger_w(offs_t offset, u8 data)
|
||||
m_sh_trigger[offset] = data;
|
||||
}
|
||||
|
||||
m_beep[offset]->set_state(data);
|
||||
if (offset != 1)
|
||||
m_beep[(offset == 0) ? 2 : (offset & 1)]->set_state(data);
|
||||
else
|
||||
m_beep[2]->set_output_gain(0, data ? 0.5 : 1.0);
|
||||
}
|
||||
|
||||
|
||||
@ -1373,10 +1374,9 @@ void cvs_state::cvs(machine_config &config)
|
||||
DAC_8BIT_R2R(config, m_dac[0], 0).add_route(ALL_OUTPUTS, "speaker", 0.15); // unknown DAC
|
||||
DAC_4BIT_R2R(config, m_dac[1], 0).add_route(ALL_OUTPUTS, "speaker", 0.20); // unknown DAC
|
||||
|
||||
BEEP(config, m_beep[0], 0).add_route(ALL_OUTPUTS, "speaker", 0.10); // placeholder
|
||||
BEEP(config, m_beep[1], 0).add_route(ALL_OUTPUTS, "speaker", 0.10); // "
|
||||
BEEP(config, m_beep[2], 600).add_route(ALL_OUTPUTS, "speaker", 0.15); // "
|
||||
BEEP(config, m_beep[3], 150).add_route(ALL_OUTPUTS, "speaker", 0.15); // "
|
||||
BEEP(config, m_beep[0], 600).add_route(ALL_OUTPUTS, "speaker", 0.15); // placeholder
|
||||
BEEP(config, m_beep[1], 150).add_route(ALL_OUTPUTS, "speaker", 0.15); // "
|
||||
BEEP(config, m_beep[2], 0).add_route(ALL_OUTPUTS, "speaker", 0.075); // "
|
||||
|
||||
TMS5100(config, m_tms5100, 640_kHz_XTAL);
|
||||
m_tms5100->data().set(FUNC(cvs_state::speech_rom_read_bit));
|
||||
|
@ -109,7 +109,8 @@ template<int N>
|
||||
void mini_state::seg_w(u8 data)
|
||||
{
|
||||
// R2x,R3x: LCD segment data
|
||||
m_lcd_data = (m_lcd_data & ~(0xf << (N*4))) | (data << (N*4));
|
||||
const u8 shift = N * 4;
|
||||
m_lcd_data = (m_lcd_data & ~(0xf << shift)) | (data << shift);
|
||||
update_lcd();
|
||||
}
|
||||
|
||||
@ -196,6 +197,7 @@ void mini_state::smchess(machine_config &config)
|
||||
PWM_DISPLAY(config, m_display).set_size(4, 8);
|
||||
m_display->set_segmask(0xf, 0x7f);
|
||||
m_display->set_refresh(attotime::from_hz(30));
|
||||
|
||||
config.set_default_layout(layout_saitek_minichess);
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
|
||||
|
@ -8,46 +8,48 @@ Notes
|
||||
-----
|
||||
|
||||
Route 16:
|
||||
- Route 16 doesn't have the SN76477 chip. There is space on the PCB
|
||||
but it is not populated.
|
||||
- Route 16 doesn't have the SN76477 chip. There is space on the PCB
|
||||
but it is not populated.
|
||||
|
||||
- Has the added ability to turn off each bitplane individually.
|
||||
This looks like an afterthought, as one of the same bits that control
|
||||
the palette selection is doubly utilized as the bitmap enable bit.
|
||||
- Has the added ability to turn off each bitplane individually.
|
||||
This looks like an afterthought, as one of the same bits that control
|
||||
the palette selection is doubly utilized as the bitmap enable bit.
|
||||
|
||||
- New code to better emulate the protection in Route 16 was added in 0.194,
|
||||
but it turned out to harbour a bug (see MT 07310). Therefore the previous
|
||||
patches have been restored, and the protection routine has been nullified
|
||||
but is still there in case someone wants to revisit it.
|
||||
- New code to better emulate the protection in Route 16 was added in 0.194,
|
||||
but it turned out to harbour a bug (see MT 07310). Therefore the previous
|
||||
patches have been restored, and the protection routine has been nullified
|
||||
but is still there in case someone wants to revisit it.
|
||||
|
||||
Stratovox:
|
||||
- Has almost *electrically* identical hardware to Route 16 with the exception
|
||||
that it is physically different (2 PCB-set connected with flat cables) and
|
||||
Stratovox has the SN76477 chip and uses a DAC for voice. There are 3 volume
|
||||
pots on the PCB. One for music, one for speech and a master volume.
|
||||
- Has almost *electrically* identical hardware to Route 16 with the exception
|
||||
that it is physically different (2 PCB-set connected with flat cables) and
|
||||
Stratovox has the SN76477 chip and uses a DAC for voice. There are 3 volume
|
||||
pots on the PCB. One for music, one for speech and a master volume.
|
||||
|
||||
Space Echo:
|
||||
- When all astronauts are taken the game over tune ends with 5 bad notes,
|
||||
this appears to be a bug in the ROM from a changed instruction at 2EB3.
|
||||
- When all astronauts are taken the game over tune ends with 5 bad notes,
|
||||
this appears to be a bug in the ROM from a changed instruction at 2EB3.
|
||||
|
||||
- Service mode shows a garbled screen as most of the code for it has been
|
||||
replaced by other routines, however the sound tests still work. it's
|
||||
possible that the service switch isn't connected on the real hardware.
|
||||
- Service mode shows a garbled screen as most of the code for it has been
|
||||
replaced by other routines, however the sound tests still work. it's
|
||||
possible that the service switch isn't connected on the real hardware.
|
||||
|
||||
- The game hangs if it doesn't pass the startup test, a best guess is implemented
|
||||
rather than patching out the test. code for the same test is in stratvox but
|
||||
isn't called, speakres has a very similar test but doesn't care about the result.
|
||||
- The game hangs if it doesn't pass the startup test, a best guess is implemented
|
||||
rather than patching out the test. code for the same test is in stratvox but
|
||||
isn't called, speakres has a very similar test but doesn't care about the result.
|
||||
|
||||
- Interrupts per frame for cpu1 is a best guess based on how stratvox uses the DAC,
|
||||
writing up to 195 times per frame with each byte from the ROM written 4 times.
|
||||
spacecho writes one byte per interrupt so 195/4 or 48 is used. a lower number
|
||||
increases the chance of a sound interrupting itself, which for most sounds
|
||||
is buggy and causes the game to freeze until the first sound completes.
|
||||
- Interrupts per frame for cpu1 is a best guess based on how stratvox uses the DAC,
|
||||
writing up to 195 times per frame with each byte from the ROM written 4 times.
|
||||
spacecho writes one byte per interrupt so 195/4 or 48 is used. a lower number
|
||||
increases the chance of a sound interrupting itself, which for most sounds
|
||||
is buggy and causes the game to freeze until the first sound completes.
|
||||
|
||||
vscompmj:
|
||||
- Stuck notes (constant tone) in-game after the mahjong tiles are laid down.
|
||||
- Stuck notes (constant tone) in-game after the mahjong tiles are laid down.
|
||||
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Route 16/Stratovox memory map (preliminary)
|
||||
|
||||
CPU1
|
||||
@ -171,7 +173,7 @@ public:
|
||||
: route16_state(mconfig, type, tag)
|
||||
, m_sn(*this, "snsnd")
|
||||
, m_dac(*this, "dac")
|
||||
{}
|
||||
{ }
|
||||
|
||||
void speakres(machine_config &config);
|
||||
void stratvox(machine_config &config);
|
||||
@ -191,7 +193,7 @@ private:
|
||||
required_device<sn76477_device> m_sn;
|
||||
required_device<dac_byte_interface> m_dac;
|
||||
|
||||
int m_speakres_vrx = 0;
|
||||
attotime m_speakres_vrx;
|
||||
};
|
||||
|
||||
|
||||
@ -213,6 +215,8 @@ MACHINE_START_MEMBER(route16_state, jongpute)
|
||||
|
||||
void route16_state::init_route16a()
|
||||
{
|
||||
init_route16c();
|
||||
|
||||
// hack out the protection
|
||||
u8 *rom = memregion("cpu1")->base();
|
||||
rom[0x105] = 0; // remove jp nz,4109
|
||||
@ -222,12 +226,12 @@ void route16_state::init_route16a()
|
||||
rom[0x72a] = 0; // remove jp nz,4238
|
||||
rom[0x72b] = 0;
|
||||
rom[0x72c] = 0;
|
||||
init_route16c();
|
||||
}
|
||||
|
||||
void route16_state::init_route16()
|
||||
{
|
||||
save_item(NAME(m_protection_data));
|
||||
|
||||
// hack out the protection
|
||||
u8 *rom = memregion("cpu1")->base();
|
||||
rom[0x105] = 0; // remove jp nz,4109
|
||||
@ -248,6 +252,7 @@ void route16_state::init_route16()
|
||||
void route16_state::init_route16c()
|
||||
{
|
||||
save_item(NAME(m_protection_data));
|
||||
|
||||
// hack out the protection
|
||||
u8 *rom = memregion("cpu1")->base();
|
||||
rom[0x0e9] = 0x3a; // remove call 2CD8
|
||||
@ -260,6 +265,7 @@ void route16_state::init_route16c()
|
||||
void route16_state::init_route16d()
|
||||
{
|
||||
save_item(NAME(m_protection_data));
|
||||
|
||||
// hack out the protection
|
||||
u8 *rom = memregion("cpu1")->base();
|
||||
|
||||
@ -313,7 +319,7 @@ void route16_state::init_vscompmj() // only opcodes encrypted
|
||||
{
|
||||
uint8_t x = rom[i];
|
||||
|
||||
uint8_t row = (BIT(x, 4) + (BIT(x, 6) << 1) + (BIT(x, 7) << 2));
|
||||
uint8_t row = (BIT(x, 4) + (BIT(x, 6) << 1) + (BIT(x, 7) << 2));
|
||||
|
||||
uint8_t xor_v = x & 0x07;
|
||||
|
||||
@ -327,24 +333,6 @@ void route16_state::init_vscompmj() // only opcodes encrypted
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Shared RAM handling
|
||||
*
|
||||
*************************************/
|
||||
|
||||
template<bool cpu1> void route16_state::route16_sharedram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_sharedram[offset] = data;
|
||||
|
||||
// 4313-4319 are used in Route 16 as triggers to wake the other CPU
|
||||
if (offset >= 0x0313 && offset <= 0x0319 && data == 0xff)
|
||||
{
|
||||
// Let the other CPU run
|
||||
(cpu1 ? m_cpu1 : m_cpu2)->yield();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -353,7 +341,7 @@ template<bool cpu1> void route16_state::route16_sharedram_w(offs_t offset, uint8
|
||||
*
|
||||
*************************************/
|
||||
|
||||
uint8_t route16_state::routex_prot_read()
|
||||
uint8_t route16_state::routex_prot_r()
|
||||
{
|
||||
if (m_cpu1->pc() == 0x2f) return 0xfb;
|
||||
|
||||
@ -362,9 +350,10 @@ uint8_t route16_state::routex_prot_read()
|
||||
}
|
||||
|
||||
// never called, see notes.
|
||||
uint8_t route16_state::route16_prot_read()
|
||||
uint8_t route16_state::route16_prot_r()
|
||||
{
|
||||
m_protection_data++;
|
||||
if (!machine().side_effects_disabled())
|
||||
m_protection_data++;
|
||||
return (1 << ((m_protection_data >> 1) & 7));
|
||||
}
|
||||
|
||||
@ -378,17 +367,16 @@ uint8_t route16_state::route16_prot_read()
|
||||
|
||||
void speakres_state::stratvox_sn76477_w(uint8_t data)
|
||||
{
|
||||
/***************************************************************
|
||||
* AY8910 output bits are connected to...
|
||||
* 7 - direct: 5V * 30k/(100+30k) = 1.15V - via DAC??
|
||||
* 6 - SN76477 mixer C
|
||||
* 5 - SN76477 mixer B
|
||||
* 4 - SN76477 mixer A
|
||||
* 3 - SN76477 envelope 2
|
||||
* 2 - SN76477 envelope 1
|
||||
* 1 - SN76477 vco
|
||||
* 0 - SN76477 enable
|
||||
***************************************************************/
|
||||
// AY8910 output bits are connected to...
|
||||
// 7 - direct: 5V * 30k/(100+30k) = 1.15V - via DAC??
|
||||
// 6 - SN76477 mixer C
|
||||
// 5 - SN76477 mixer B
|
||||
// 4 - SN76477 mixer A
|
||||
// 3 - SN76477 envelope 2
|
||||
// 2 - SN76477 envelope 1
|
||||
// 1 - SN76477 vco
|
||||
// 0 - SN76477 enable
|
||||
|
||||
m_sn->enable_w((data >> 0) & 1);
|
||||
m_sn->vco_w((data >> 1) & 1);
|
||||
m_sn->envelope_1_w((data >> 2) & 1);
|
||||
@ -413,72 +401,58 @@ void speakres_state::stratvox_dac_w(uint8_t data)
|
||||
*
|
||||
***************************************************/
|
||||
|
||||
void route16_state::jongpute_input_port_matrix_w(uint8_t data)
|
||||
void route16_state::jongpute_input_w(uint8_t data)
|
||||
{
|
||||
m_jongpute_port_select = data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t route16_state::jongpute_p1_matrix_r()
|
||||
template <int N>
|
||||
uint8_t route16_state::jongpute_input_r()
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint8_t data = 0;
|
||||
|
||||
switch (m_jongpute_port_select)
|
||||
{
|
||||
case 1: ret = m_key[0]->read(); break;
|
||||
case 2: ret = m_key[1]->read(); break;
|
||||
case 4: ret = m_key[2]->read(); break;
|
||||
case 8: ret = m_key[3]->read(); break;
|
||||
default: break;
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (BIT(m_jongpute_port_select, i))
|
||||
data |= m_key[N * 4 + i]->read();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t route16_state::jongpute_p2_matrix_r()
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
switch (m_jongpute_port_select)
|
||||
{
|
||||
case 1: ret = m_key[4]->read(); break;
|
||||
case 2: ret = m_key[5]->read(); break;
|
||||
case 4: ret = m_key[6]->read(); break;
|
||||
case 8: ret = m_key[7]->read(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
guessing that the unconnected IN3 and OUT2 on the stratvox schematic
|
||||
are hooked up for speakres and spacecho to somehow read the variable
|
||||
resistors (eg a voltage ramp), using a write to OUT2 as a trigger
|
||||
and then bits 0-2 of IN3 going low when each pot "matches". the VRx
|
||||
values can be seen when IN0=0x55 and p1b1 is held during power on.
|
||||
|
||||
/***************************************************
|
||||
*
|
||||
* Speak & Rescue VR timer
|
||||
*
|
||||
***************************************************/
|
||||
|
||||
/*
|
||||
Guessing that the unconnected IN3 and OUT2 on the stratvox schematic are hooked up
|
||||
for speakres and spacecho to somehow read the variable resistors (eg a voltage ramp),
|
||||
using a write to OUT2 as a trigger and then bits 0-2 of IN3 going low when each pot
|
||||
"matches". the VRx values can be seen when IN0=0x55 and p1b1 is held during power on.
|
||||
this would then be checking that the sounds are mixed correctly.
|
||||
***************************************************************************/
|
||||
|
||||
Unlikely that this is some form of protection, since the bootlegs use this too?
|
||||
*/
|
||||
|
||||
uint8_t speakres_state::speakres_in3_r()
|
||||
{
|
||||
int bit2=4, bit1=2, bit0=1;
|
||||
uint8_t data = 0;
|
||||
|
||||
/* just using a counter, the constants are the number of reads
|
||||
before going low, each read is 40 cycles apart. the constants
|
||||
were chosen based on the startup tests and for vr0=vr2 */
|
||||
m_speakres_vrx++;
|
||||
if(m_speakres_vrx>0x300) bit0=0; /* VR0 100k ohm - speech */
|
||||
if(m_speakres_vrx>0x200) bit1=0; /* VR1 50k ohm - main volume */
|
||||
if(m_speakres_vrx>0x300) bit2=0; /* VR2 100k ohm - explosion */
|
||||
// each read is 40 cycles apart, the constants were chosen based on the startup tests and for vr0=vr2
|
||||
attotime delta = machine().time() - m_speakres_vrx;
|
||||
|
||||
return 0xf8|bit2|bit1|bit0;
|
||||
if (delta > attotime::from_usec(0x3000)) data |= 1; // VR0 100k ohm - speech
|
||||
if (delta > attotime::from_usec(0x2000)) data |= 2; // VR1 50k ohm - main volume
|
||||
if (delta > attotime::from_usec(0x3000)) data |= 4; // VR2 100k ohm - explosion
|
||||
|
||||
return ~data;
|
||||
}
|
||||
|
||||
void speakres_state::speakres_out2_w(uint8_t data)
|
||||
{
|
||||
m_speakres_vrx=0;
|
||||
m_speakres_vrx = machine().time();
|
||||
}
|
||||
|
||||
|
||||
@ -492,8 +466,8 @@ void speakres_state::speakres_out2_w(uint8_t data)
|
||||
void route16_state::route16_cpu1_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x2fff).rom();
|
||||
map(0x3000, 0x3001).r(FUNC(route16_state::route16_prot_read));
|
||||
map(0x4000, 0x43ff).ram().w(FUNC(route16_state::route16_sharedram_w<true>)).share("sharedram");
|
||||
map(0x3000, 0x3001).r(FUNC(route16_state::route16_prot_r));
|
||||
map(0x4000, 0x43ff).ram().share("sharedram");
|
||||
map(0x4800, 0x4800).portr("DSW").w(FUNC(route16_state::out0_w));
|
||||
map(0x5000, 0x5000).portr("P1").w(FUNC(route16_state::out1_w));
|
||||
map(0x5800, 0x5800).portr("P2");
|
||||
@ -504,11 +478,11 @@ void route16_state::route16_cpu1_map(address_map &map)
|
||||
void route16_state::routex_cpu1_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x3fff).rom();
|
||||
map(0x4000, 0x43ff).ram().w(FUNC(route16_state::route16_sharedram_w<true>)).share("sharedram");
|
||||
map(0x4000, 0x43ff).ram().share("sharedram");
|
||||
map(0x4800, 0x4800).portr("DSW").w(FUNC(route16_state::out0_w));
|
||||
map(0x5000, 0x5000).portr("P1").w(FUNC(route16_state::out1_w));
|
||||
map(0x5800, 0x5800).portr("P2");
|
||||
map(0x6400, 0x6400).r(FUNC(route16_state::routex_prot_read));
|
||||
map(0x6400, 0x6400).r(FUNC(route16_state::routex_prot_r));
|
||||
map(0x8000, 0xbfff).ram().share("videoram1");
|
||||
}
|
||||
|
||||
@ -541,8 +515,8 @@ void route16_state::jongpute_cpu1_map(address_map &map)
|
||||
map(0x0000, 0x3fff).rom();
|
||||
map(0x4000, 0x43ff).ram().share("sharedram");
|
||||
map(0x4800, 0x4800).portr("DSW").w(FUNC(route16_state::out0_w));
|
||||
map(0x5000, 0x5000).r(FUNC(route16_state::jongpute_p2_matrix_r)).w(FUNC(route16_state::out1_w));
|
||||
map(0x5800, 0x5800).rw(FUNC(route16_state::jongpute_p1_matrix_r), FUNC(route16_state::jongpute_input_port_matrix_w));
|
||||
map(0x5000, 0x5000).r(FUNC(route16_state::jongpute_input_r<1>)).w(FUNC(route16_state::out1_w));
|
||||
map(0x5800, 0x5800).rw(FUNC(route16_state::jongpute_input_r<0>), FUNC(route16_state::jongpute_input_w));
|
||||
map(0x6800, 0x6800).w("ay8910", FUNC(ay8910_device::data_w));
|
||||
map(0x6900, 0x6900).w("ay8910", FUNC(ay8910_device::address_w));
|
||||
map(0x8000, 0xbfff).ram().share("videoram1");
|
||||
@ -565,7 +539,7 @@ void route16_state::vscompmj_decrypted_opcodes(address_map &map)
|
||||
void route16_state::route16_cpu2_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x1fff).rom();
|
||||
map(0x4000, 0x43ff).ram().w(FUNC(route16_state::route16_sharedram_w<false>)).share("sharedram");
|
||||
map(0x4000, 0x43ff).ram().share("sharedram");
|
||||
map(0x8000, 0xbfff).ram().share("videoram2");
|
||||
}
|
||||
|
||||
@ -913,6 +887,8 @@ void route16_state::route16(machine_config &config)
|
||||
Z80(config, m_cpu2, 10_MHz_XTAL / 4); // verified on PCB
|
||||
m_cpu2->set_addrmap(AS_PROGRAM, &route16_state::route16_cpu2_map);
|
||||
|
||||
config.set_maximum_quantum(attotime::from_hz(m_cpu1->clock() / 4));
|
||||
|
||||
/* video hardware */
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_size(256, 256);
|
||||
@ -925,7 +901,7 @@ void route16_state::route16(machine_config &config)
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
AY8910(config, "ay8910", 10_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "speaker", 0.5); // verified on PCB
|
||||
AY8910(config, "ay8910", 10_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "speaker", 0.5); // verified on PCB
|
||||
}
|
||||
|
||||
|
||||
@ -950,7 +926,7 @@ void speakres_state::stratvox(machine_config &config)
|
||||
m_screen->set_screen_update(FUNC(speakres_state::screen_update_jongpute));
|
||||
|
||||
/* sound hardware */
|
||||
subdevice<ay8910_device>("ay8910")->port_a_write_callback().set(FUNC(speakres_state::stratvox_sn76477_w)); // SN76477 commands (SN76477 not populated on Route 16 PCB)
|
||||
subdevice<ay8910_device>("ay8910")->port_a_write_callback().set(FUNC(speakres_state::stratvox_sn76477_w)); // SN76477 commands (SN76477 not populated on Route 16 PCB)
|
||||
|
||||
SN76477(config, m_sn);
|
||||
m_sn->set_noise_params(RES_K(47), RES_K(150), CAP_U(0.001));
|
||||
@ -1011,6 +987,7 @@ void route16_state::vscompmj(machine_config &config)
|
||||
m_cpu1->set_addrmap(AS_OPCODES, &route16_state::vscompmj_decrypted_opcodes);
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* ROM definitions
|
||||
@ -1032,8 +1009,8 @@ ROM_START( route16 )
|
||||
ROM_LOAD( "stvg62.b2", 0x1000, 0x0800, CRC(defc5797) SHA1(aec8179e647de70016e0e63b720f932752adacc1) )
|
||||
ROM_LOAD( "stvg63.b3", 0x1800, 0x0800, CRC(88d94a66) SHA1(163e952ada7c05110d1f1c681bd57d3b9ea8866e) )
|
||||
|
||||
ROM_REGION( 0x800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841", 0x000, 0x800, NO_DUMP )
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841_322m.a6", 0x0000, 0x0800, NO_DUMP )
|
||||
|
||||
ROM_REGION( 0x0200, "proms", 0 )
|
||||
// The upper 128 bytes are 0's, used by the hardware to blank the display
|
||||
@ -1041,10 +1018,10 @@ ROM_START( route16 )
|
||||
ROM_LOAD( "mb7052.61", 0x0100, 0x0100, CRC(08793ef7) SHA1(bfc27aaf25d642cd57c0fbe73ab575853bd5f3ca) ) // bottom bitmap
|
||||
ROM_END
|
||||
|
||||
// 2 sets found, one on TVX1 and one on TVX2 PCB. TVX1 has lots of wire hacks. Both PCBs have an identical TVX-S1 sub board with Fujitsu MB8841 + logic.
|
||||
// There were two different bytes between the two versions, both in ROM a2:
|
||||
// 0x1dd is 0x46 in the TVX1 dump and 0x47 in the TVX2 one. 0x764 is 0x04 in the TVX1 dump and 0x06 in the TVX2 one.
|
||||
// Those cause the game to malfunction and it doesn't seem to be additional protection. The a2 ROM below is the one dumped from the TVX2 PCB.
|
||||
// 2 sets found, one on TVX1 and one on TVX2 PCB. TVX1 has lots of wire hacks. Both PCBs have an identical TVX-S1 sub board with Fujitsu MB8841 + logic.
|
||||
// There were two different bytes between the two versions, both in ROM a2:
|
||||
// 0x1dd is 0x46 in the TVX1 dump and 0x47 in the TVX2 one. 0x764 is 0x04 in the TVX1 dump and 0x06 in the TVX2 one.
|
||||
// Those cause the game to malfunction and it doesn't seem to be additional protection. The a2 ROM below is the one dumped from the TVX2 PCB.
|
||||
ROM_START( route16d )
|
||||
ROM_REGION( 0x10000, "cpu1", 0 )
|
||||
ROM_LOAD( "a0.7.bin", 0x0000, 0x0800, CRC(025a4f63) SHA1(f1ced12c7667467c25f7fc595ae2e1b3aef4a29f) )
|
||||
@ -1060,8 +1037,8 @@ ROM_START( route16d )
|
||||
ROM_LOAD( "b2.bin", 0x1000, 0x0800, CRC(defc5797) SHA1(aec8179e647de70016e0e63b720f932752adacc1) )
|
||||
ROM_LOAD( "b3.bin", 0x1800, 0x0800, CRC(88d94a66) SHA1(163e952ada7c05110d1f1c681bd57d3b9ea8866e) )
|
||||
|
||||
ROM_REGION( 0x800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841", 0x000, 0x800, NO_DUMP )
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841_322m.a6", 0x0000, 0x0800, NO_DUMP )
|
||||
|
||||
ROM_REGION( 0x0200, "proms", 0 )
|
||||
// The upper 128 bytes are 0's, used by the hardware to blank the display
|
||||
@ -1084,8 +1061,8 @@ ROM_START( route16a )
|
||||
ROM_LOAD( "tvg62.b2", 0x1000, 0x0800, CRC(529cad13) SHA1(b533d20df1f2580e237c3d60bfe3483486ad9a48) )
|
||||
ROM_LOAD( "tvg63.b3", 0x1800, 0x0800, CRC(3bd8b899) SHA1(bc0c7909dbf5ea85eba5a1bb815fdd98c3aa794e) )
|
||||
|
||||
ROM_REGION( 0x800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841", 0x000, 0x800, NO_DUMP )
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841_322m.a6", 0x0000, 0x0800, NO_DUMP )
|
||||
|
||||
ROM_REGION( 0x0200, "proms", 0 )
|
||||
/* The upper 128 bytes are 0's, used by the hardware to blank the display */
|
||||
@ -1108,8 +1085,8 @@ ROM_START( route16c )
|
||||
ROM_LOAD( "route16.b2", 0x1000, 0x0800, CRC(529cad13) SHA1(b533d20df1f2580e237c3d60bfe3483486ad9a48) )
|
||||
ROM_LOAD( "route16.b3", 0x1800, 0x0800, CRC(3bd8b899) SHA1(bc0c7909dbf5ea85eba5a1bb815fdd98c3aa794e) )
|
||||
|
||||
ROM_REGION( 0x800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841", 0x000, 0x800, NO_DUMP )
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841_322m.a6", 0x0000, 0x0800, NO_DUMP )
|
||||
|
||||
ROM_REGION( 0x0200, "proms", 0 ) /* Intersil IM5623CPE proms compatible with 82s129 */
|
||||
/* The upper 128 bytes are 0's, used by the hardware to blank the display */
|
||||
@ -1132,8 +1109,8 @@ ROM_START( route16b )
|
||||
ROM_LOAD( "route16.b2", 0x1000, 0x0800, CRC(529cad13) SHA1(b533d20df1f2580e237c3d60bfe3483486ad9a48) )
|
||||
ROM_LOAD( "route16.b3", 0x1800, 0x0800, CRC(3bd8b899) SHA1(bc0c7909dbf5ea85eba5a1bb815fdd98c3aa794e) )
|
||||
|
||||
ROM_REGION( 0x800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841", 0x000, 0x800, NO_DUMP )
|
||||
ROM_REGION( 0x0800, "mcu", 0 ) // on a small daughterboard inserted at a6
|
||||
ROM_LOAD( "mb8841_322m.a6", 0x0000, 0x0800, NO_DUMP )
|
||||
|
||||
ROM_REGION( 0x0200, "proms", 0 ) /* Intersil IM5623CPE proms compatible with 82s129 */
|
||||
/* The upper 128 bytes are 0's, used by the hardware to blank the display */
|
||||
@ -1346,7 +1323,7 @@ So... spacecho2 is avoiding to enter the sub at $2929.
|
||||
*/
|
||||
ROM_START( spacecho2 )
|
||||
ROM_REGION( 0x10000, "cpu1", 0 )
|
||||
ROM_LOAD( "c11.5.6t", 0x0000, 0x0800, CRC(90637f25) SHA1(820d2f326a5d8d0a04a0fca46b035624dfd7222c) ) // 3 bytes different at 0x8e
|
||||
ROM_LOAD( "c11.5.6t", 0x0000, 0x0800, CRC(90637f25) SHA1(820d2f326a5d8d0a04a0fca46b035624dfd7222c) ) // 3 bytes different at 0x8e
|
||||
ROM_LOAD( "c2.5t", 0x0800, 0x0800, CRC(a5f0a34f) SHA1(359e7a9954dedb464f7456cd071db77b2219ab2c) )
|
||||
ROM_LOAD( "c3.4.5t", 0x1000, 0x0800, CRC(cbbb3acb) SHA1(3dc71683f31da39a544382b463ece39cca8124b3) )
|
||||
ROM_LOAD( "c4.4t", 0x1800, 0x0800, CRC(311050ca) SHA1(ed4a5cb7ec0306654178dae8f30b39b9c8db0ce3) )
|
||||
@ -1465,24 +1442,24 @@ ROM_END
|
||||
*
|
||||
*************************************/
|
||||
|
||||
GAME( 1981, route16, 0, route16, route16, route16_state, init_route16, ROT270, "Sun Electronics", "Route 16 (Sun Electronics, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16d, route16, route16, route16a, route16_state, init_route16d, ROT270, "Sun Electronics", "Route 16 (Sun Electronics, set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16a, route16, route16, route16a, route16_state, init_route16a, ROT270, "Tehkan / Sun Electronics (Centuri license)", "Route 16 (Centuri license, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16b, route16, route16, route16, route16_state, init_route16, ROT270, "Tehkan / Sun Electronics (Centuri license)", "Route 16 (Centuri license, set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16c, route16, route16, route16, route16_state, init_route16c, ROT270, "Tehkan / Sun Electronics (Centuri license)", "Route 16 (Centuri license, set 3, bootleg?)", MACHINE_SUPPORTS_SAVE ) // similar to set 1 but with some protection removed?
|
||||
GAME( 1981, route16bl,route16, route16, route16, route16_state, empty_init, ROT270, "bootleg (Leisure and Allied)", "Route 16 (bootleg)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, routex, route16, routex, route16, route16_state, empty_init, ROT270, "bootleg", "Route X (bootleg, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, routexa, route16, routex, route16, route16_state, empty_init, ROT270, "bootleg", "Route X (bootleg, set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16, 0, route16, route16, route16_state, init_route16, ROT270, "Sun Electronics", "Route 16 (Sun Electronics, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16d, route16, route16, route16a, route16_state, init_route16d, ROT270, "Sun Electronics", "Route 16 (Sun Electronics, set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16a, route16, route16, route16a, route16_state, init_route16a, ROT270, "Sun Electronics / Tehkan (Centuri license)", "Route 16 (Centuri license, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16b, route16, route16, route16, route16_state, init_route16, ROT270, "Sun Electronics / Tehkan (Centuri license)", "Route 16 (Centuri license, set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, route16c, route16, route16, route16, route16_state, init_route16c, ROT270, "Sun Electronics / Tehkan (Centuri license)", "Route 16 (Centuri license, set 3, bootleg?)", MACHINE_SUPPORTS_SAVE ) // similar to set 1 but with some protection removed?
|
||||
GAME( 1981, route16bl, route16, route16, route16, route16_state, empty_init, ROT270, "bootleg (Leisure and Allied)", "Route 16 (bootleg)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, routex, route16, routex, route16, route16_state, empty_init, ROT270, "bootleg", "Route X (bootleg, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, routexa, route16, routex, route16, route16_state, empty_init, ROT270, "bootleg", "Route X (bootleg, set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
|
||||
GAME( 1980, speakres, 0, speakres, speakres, speakres_state, empty_init, ROT270, "Sun Electronics", "Speak & Rescue", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, speakresb,speakres, speakres, speakres, speakres_state, empty_init, ROT270, "bootleg", "Speak & Rescue (bootleg)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, stratvox, speakres, stratvox, stratvox, speakres_state, empty_init, ROT270, "Sun Electronics (Taito license)", "Stratovox (set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, stratvoxa,speakres, stratvox, stratvox, speakres_state, empty_init, ROT270, "Sun Electronics (Taito license)", "Stratovox (set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, stratvoxb,speakres, stratvox, stratvox, speakres_state, empty_init, ROT270, "bootleg", "Stratovox (bootleg)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, spacecho, speakres, spacecho, spacecho, speakres_state, empty_init, ROT270, "bootleg (Gayton Games)", "Space Echo (set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, spacecho2,speakres, spacecho, spacecho, speakres_state, empty_init, ROT270, "bootleg (Gayton Games)", "Space Echo (set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, speakhlp, speakres, spacecho, spacecho, speakres_state, empty_init, ROT270, "bootleg", "Speak & Help", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND )
|
||||
GAME( 1980, speakres, 0, speakres, speakres, speakres_state, empty_init, ROT270, "Sun Electronics", "Speak & Rescue", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, speakresb, speakres, speakres, speakres, speakres_state, empty_init, ROT270, "bootleg", "Speak & Rescue (bootleg)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, stratvox, speakres, stratvox, stratvox, speakres_state, empty_init, ROT270, "Sun Electronics (Taito license)", "Stratovox (set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, stratvoxa, speakres, stratvox, stratvox, speakres_state, empty_init, ROT270, "Sun Electronics (Taito license)", "Stratovox (set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, stratvoxb, speakres, stratvox, stratvox, speakres_state, empty_init, ROT270, "bootleg", "Stratovox (bootleg)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, spacecho, speakres, spacecho, spacecho, speakres_state, empty_init, ROT270, "bootleg (Gayton Games)", "Space Echo (set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, spacecho2, speakres, spacecho, spacecho, speakres_state, empty_init, ROT270, "bootleg (Gayton Games)", "Space Echo (set 2)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1980, speakhlp, speakres, spacecho, spacecho, speakres_state, empty_init, ROT270, "bootleg", "Speak & Help", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND )
|
||||
|
||||
GAME( 1981, jongpute, 0, jongpute, jongpute, route16_state, empty_init, ROT0, "Alpha Denshi Co.", "Jongputer", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_NOT_WORKING ) // sampling voice is not emulated, bug with colors makes tile recognition difficult
|
||||
GAME( 1981, ttmahjng, jongpute, jongpute, jongpute, route16_state, empty_init, ROT0, "Alpha Denshi Co. (Taito license)", "T.T Mahjong", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, vscompmj, jongpute, vscompmj, jongpute, route16_state, init_vscompmj, ROT0, "Nichibutsu", "VS Computer Mahjong", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_NOT_WORKING ) // decryption might be incomplete (attract resets), inputs seem read differently
|
||||
GAME( 1981, jongpute, 0, jongpute, jongpute, route16_state, empty_init, ROT0, "Alpha Denshi Co.", "Jongputer", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_NOT_WORKING ) // sampling voice is not emulated, bug with colors makes tile recognition difficult
|
||||
GAME( 1981, ttmahjng, jongpute, jongpute, jongpute, route16_state, empty_init, ROT0, "Alpha Denshi Co. (Taito license)", "T.T Mahjong", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1981, vscompmj, jongpute, vscompmj, jongpute, route16_state, init_vscompmj, ROT0, "Nichibutsu", "VS Computer Mahjong", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_NOT_WORKING ) // decryption might be incomplete (attract resets), inputs seem read differently
|
||||
|
@ -15,15 +15,13 @@ public:
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_cpu1(*this, "cpu1")
|
||||
, m_cpu2(*this, "cpu2")
|
||||
, m_sharedram(*this, "sharedram")
|
||||
, m_videoram1(*this, "videoram1")
|
||||
, m_videoram2(*this, "videoram2")
|
||||
, m_decrypted_opcodes(*this, "decrypted_opcodes")
|
||||
, m_palette(*this, "palette")
|
||||
, m_screen(*this, "screen")
|
||||
, m_key(*this, "KEY%u", 0U)
|
||||
, m_protection_data(0)
|
||||
{}
|
||||
{ }
|
||||
|
||||
void routex(machine_config &config);
|
||||
void jongpute(machine_config &config);
|
||||
@ -43,12 +41,10 @@ protected:
|
||||
void out1_w(uint8_t data);
|
||||
|
||||
private:
|
||||
template<bool cpu1> void route16_sharedram_w(offs_t offset, uint8_t data);
|
||||
uint8_t route16_prot_read();
|
||||
uint8_t routex_prot_read();
|
||||
void jongpute_input_port_matrix_w(uint8_t data);
|
||||
uint8_t jongpute_p1_matrix_r();
|
||||
uint8_t jongpute_p2_matrix_r();
|
||||
uint8_t route16_prot_r();
|
||||
uint8_t routex_prot_r();
|
||||
void jongpute_input_w(uint8_t data);
|
||||
template <int N> uint8_t jongpute_input_r();
|
||||
DECLARE_MACHINE_START(jongpute);
|
||||
|
||||
uint32_t screen_update_route16(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
@ -69,14 +65,13 @@ protected:
|
||||
required_device<cpu_device> m_cpu1;
|
||||
required_device<cpu_device> m_cpu2;
|
||||
|
||||
required_shared_ptr<uint8_t> m_sharedram;
|
||||
required_shared_ptr<uint8_t> m_videoram1;
|
||||
required_shared_ptr<uint8_t> m_videoram2;
|
||||
optional_shared_ptr<uint8_t> m_decrypted_opcodes;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<screen_device> m_screen;
|
||||
optional_ioport_array<8> m_key;
|
||||
uint8_t m_protection_data;
|
||||
uint8_t m_protection_data = 0;
|
||||
|
||||
uint8_t m_jongpute_port_select = 0;
|
||||
uint8_t m_flipscreen = 0;
|
||||
|
@ -73,15 +73,15 @@ uint32_t route16_state::screen_update_route16(screen_device &screen, bitmap_rgb3
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
uint8_t color1 = color_prom1[((m_palette_1 << 6) & 0x80) |
|
||||
(m_palette_1 << 2) |
|
||||
((data1 >> 3) & 0x02) |
|
||||
((data1 >> 0) & 0x01)];
|
||||
(m_palette_1 << 2) |
|
||||
((data1 >> 3) & 0x02) |
|
||||
((data1 >> 0) & 0x01)];
|
||||
|
||||
/* bit 7 of the 2nd color is the OR of the 1st color bits 0 and 1 - this is a guess */
|
||||
uint8_t color2 = color_prom2[((m_palette_2 << 6) & 0x80) | (((color1 << 6) & 0x80) | ((color1 << 7) & 0x80)) |
|
||||
(m_palette_2 << 2) |
|
||||
((data2 >> 3) & 0x02) |
|
||||
((data2 >> 0) & 0x01)];
|
||||
(m_palette_2 << 2) |
|
||||
((data2 >> 3) & 0x02) |
|
||||
((data2 >> 0) & 0x01)];
|
||||
|
||||
/* the final color is the OR of the two colors (verified) */
|
||||
uint8_t final_color = (color1 | color2) & 0x07;
|
||||
@ -121,14 +121,14 @@ uint32_t route16_state::screen_update_jongpute(screen_device &screen, bitmap_rgb
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
uint8_t color1 = color_prom1[(m_palette_1 << 2) |
|
||||
((data1 >> 3) & 0x02) |
|
||||
((data1 >> 0) & 0x01)];
|
||||
((data1 >> 3) & 0x02) |
|
||||
((data1 >> 0) & 0x01)];
|
||||
|
||||
/* bit 7 of the 2nd color is the OR of the 1st color bits 0 and 1 (verified) */
|
||||
uint8_t color2 = color_prom2[(((data1 << 3) & 0x80) | ((data1 << 7) & 0x80)) |
|
||||
(m_palette_2 << 2) |
|
||||
((data2 >> 3) & 0x02) |
|
||||
((data2 >> 0) & 0x01)];
|
||||
(m_palette_2 << 2) |
|
||||
((data2 >> 3) & 0x02) |
|
||||
((data2 >> 0) & 0x01)];
|
||||
|
||||
/* the final color is the OR of the two colors */
|
||||
uint8_t final_color = (color1 | color2) & 0x07;
|
||||
|
Loading…
Reference in New Issue
Block a user