cvs: add 0x1885 sound trigger,

route16: small cleanup
This commit is contained in:
hap 2024-12-18 13:51:25 +01:00
parent 98c80be468
commit 6bcdff58a8
5 changed files with 162 additions and 188 deletions

View File

@ -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));

View File

@ -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));

View File

@ -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

View File

@ -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;

View File

@ -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;