microvsn: add default tms1100 microinstructions (nw)

This commit is contained in:
hap 2020-04-08 00:48:40 +02:00
parent 963a1a5385
commit 4f08f64bd7
7 changed files with 89 additions and 67 deletions

View File

@ -101,8 +101,8 @@ The "rc" feature is used to indicate the source of the clock signal
<publisher>Milton Bradley</publisher>
<info name="serial" value="MP3481" />
<part name="cart" interface="microvision_cart">
<feature name="pla" value="1" /> <!-- correct? -->
<feature name="pcb" value="4952-79 REV-B" /> <!-- correct? -->
<feature name="pla" value="1" />
<feature name="pcb" value="4952-79 REV-B" /> <!-- correct? -->
<feature name="paddle" value="yes" />
<dataarea name="rom" size="2048">
<rom name="connect4t.bin" size="2048" crc="6a4cf60b" sha1="e93d848784205ab49234ad26718e04d267b776ed"/>

View File

@ -139,7 +139,7 @@ void tms0980_cpu_device::device_reset()
m_fixed_decode[op] = (op & 0x80) ? F_CALL: F_BR;
// 6 output bits select a microinstruction index
m_micro_decode[op] = decode_micro(m_ipla->read(op) & 0x3f);
m_micro_decode[op] = m_decode_micro.isnull() ? decode_micro(m_ipla->read(op) & 0x3f) : m_decode_micro(op);
// the other ipla terms each select a fixed instruction
m_fixed_decode[op] |= decode_fixed(op);
@ -151,7 +151,7 @@ void tms0980_cpu_device::device_reset()
memset(&m_micro_decode[0], 0, 0x40*sizeof(u32));
for (int op = 0; op < 0x40; op++)
m_micro_direct[op] = decode_micro(op);
m_micro_direct[op] = m_decode_micro.isnull() ? decode_micro(op) : m_decode_micro(op + 0x200);
}

View File

@ -151,7 +151,7 @@ void tms1000_cpu_device::device_reset()
// decode microinstructions
for (int op = 0; op < 0x100; op++)
m_micro_decode[op] = decode_micro(op);
m_micro_decode[op] = m_decode_micro.isnull() ? decode_micro(op) : m_decode_micro(op);
// the fixed instruction set is not programmable
m_fixed_decode[0x00] = F_COMX;

View File

@ -94,6 +94,7 @@ tms1k_base_device::tms1k_base_device(const machine_config &mconfig, device_type
, m_read_ctl(*this)
, m_write_ctl(*this)
, m_write_pdc(*this)
, m_decode_micro(*this)
{
}
@ -138,6 +139,7 @@ void tms1k_base_device::device_start()
m_read_ctl.resolve_safe(0);
m_write_ctl.resolve_safe();
m_write_pdc.resolve_safe();
m_decode_micro.resolve();
if (m_opla_b != nullptr && m_output_pla_table == nullptr)
set_output_pla(&m_opla_b->as_u16());

View File

@ -83,9 +83,12 @@ public:
auto write_pdc() { return m_write_pdc.bind(); }
// Use this if the output PLA is unknown:
// If the microinstructions (or other) PLA is unknown, try using one from another romset.
void set_output_pla(const u16 *output_pla) { m_output_pla_table = output_pla; }
// If the microinstructions PLA is unknown, try using one from another romset.
// If that's not possible, use this callback:
auto set_decode_micro() { return m_decode_micro.bind(); }
u8 debug_peek_o_index() { return m_o_index; } // get output PLA index, for debugging (don't use in emulation)
protected:
@ -266,6 +269,7 @@ protected:
devcb_read8 m_read_ctl;
devcb_write8 m_write_ctl;
devcb_write_line m_write_pdc;
devcb_read32 m_decode_micro;
u32 m_o_mask;
u32 m_r_mask;

View File

@ -72,6 +72,7 @@ private:
DECLARE_READ8_MEMBER(tms1100_read_k);
DECLARE_WRITE16_MEMBER(tms1100_write_o);
DECLARE_WRITE16_MEMBER(tms1100_write_r);
u32 tms1100_decode_micro(offs_t offset);
// enums
enum cpu_type
@ -101,7 +102,6 @@ private:
pcb_type m_pcb_type;
rc_type m_rc_type;
required_device<dac_byte_interface> m_dac;
required_device<i8021_device> m_i8021;
required_device<tms1100_cpu_device> m_tms1100;
@ -185,35 +185,6 @@ void microvision_state::machine_reset()
m_t1 = 0;
m_paddle_timer->adjust(attotime::never);
switch (m_cpu_type)
{
case CPU_TYPE_I8021:
m_i8021->resume(SUSPEND_REASON_DISABLE);
m_tms1100->suspend(SUSPEND_REASON_DISABLE, 0);
break;
case CPU_TYPE_TMS1100:
m_i8021->suspend(SUSPEND_REASON_DISABLE, 0);
m_tms1100->resume(SUSPEND_REASON_DISABLE);
switch (m_rc_type)
{
case RC_TYPE_100PF_21_0K:
m_tms1100->set_clock(550000);
break;
case RC_TYPE_100PF_23_2K:
case RC_TYPE_UNKNOWN: // Default to most occurring setting
m_tms1100->set_clock(500000);
break;
case RC_TYPE_100PF_39_4K:
m_tms1100->set_clock(300000);
break;
}
break;
}
}
@ -484,33 +455,62 @@ WRITE16_MEMBER( microvision_state::tms1100_write_r )
}
static const u16 microvision_output_pla_0[0x20] =
static const u16 microvision_output_pla[2][0x20] =
{
/* O output PLA configuration currently unknown */
0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E,
0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// default TMS1100 O output PLA
// verified for: blckbstr, pinball
{
0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f,
0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
},
// reversed bit order
// verified for: bowling, vegasslt
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
}
};
static const u16 microvision_output_pla_1[0x20] =
u32 microvision_state::tms1100_decode_micro(offs_t offset)
{
/* O output PLA configuration currently unknown */
/* Reversed bit order */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// default TMS1100 microinstructions PLA - this should work for all games
// verified for: blckbstr, bowling, pinball, vegasslt
static const u16 micro[0x80] =
{
0x1402, 0x0c30, 0xd002, 0x2404, 0x8019, 0x8038, 0x0416, 0x0415,
0x0104, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1100, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x000a, 0x0404, 0x0408, 0x8004, 0xa019, 0xa038, 0x2004, 0x2000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x1580, 0x1580, 0x1580, 0x1580, 0x0c34, 0x0834, 0x0434, 0x1400,
0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108,
0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108,
0x9080, 0x9080, 0x9080, 0x9080, 0x9080, 0x9080, 0x9080, 0x9080,
0x9080, 0x9080, 0x9080, 0x9080, 0x9080, 0x9080, 0x9080, 0x9080,
0x8068, 0x8068, 0x8068, 0x8068, 0x8068, 0x8068, 0x8068, 0x8068,
0x8068, 0x8068, 0x8068, 0x8068, 0x8068, 0x8068, 0x8068, 0x8068,
0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0136,
0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0134
};
if (offset >= 0x80 || micro[offset] == 0)
return 0x8fa3;
else
return micro[offset];
}
DEVICE_IMAGE_LOAD_MEMBER(microvision_state::cart_load)
{
uint8_t *rom1 = memregion("maincpu1")->base();
uint8_t *rom2 = memregion("maincpu2")->base();
uint32_t file_size = m_cart->common_get_size("rom");
m_pla = 0;
if ( file_size != 1024 && file_size != 2048 )
{
@ -518,7 +518,12 @@ DEVICE_IMAGE_LOAD_MEMBER(microvision_state::cart_load)
return image_init_result::FAIL;
}
/* Read cartridge */
// Set default settings
m_pcb_type = microvision_state::PCB_TYPE_UNKNOWN;
m_rc_type = microvision_state::RC_TYPE_UNKNOWN;
m_pla = 0;
// Read cartridge
if (!image.loaded_through_softlist())
{
if (image.fread(rom1, file_size) != file_size)
@ -538,11 +543,7 @@ DEVICE_IMAGE_LOAD_MEMBER(microvision_state::cart_load)
if (pla)
m_pla = 1;
m_tms1100->set_output_pla(m_pla ? microvision_output_pla_1 : microvision_output_pla_0);
// Set default setting for PCB type and RC type
m_pcb_type = microvision_state::PCB_TYPE_UNKNOWN;
m_rc_type = microvision_state::RC_TYPE_UNKNOWN;
m_tms1100->set_output_pla(microvision_output_pla[m_pla]);
// Detect settings for PCB type
const char *pcb = image.get_feature("pcb");
@ -594,17 +595,34 @@ DEVICE_IMAGE_LOAD_MEMBER(microvision_state::cart_load)
// Based on file size select cpu:
// - 1024 -> I8021
// - 2048 -> TI TMS1100
switch (file_size)
{
case 1024:
m_cpu_type = microvision_state::CPU_TYPE_I8021;
m_i8021->set_clock(2000000);
break;
case 2048:
m_cpu_type = microvision_state::CPU_TYPE_TMS1100;
switch (m_rc_type)
{
case RC_TYPE_100PF_21_0K:
m_tms1100->set_clock(550000);
break;
case RC_TYPE_100PF_23_2K:
case RC_TYPE_UNKNOWN: // Default to most occurring setting
m_tms1100->set_clock(500000);
break;
case RC_TYPE_100PF_39_4K:
m_tms1100->set_clock(300000);
break;
}
break;
}
return image_init_result::PASS;
}
@ -635,21 +653,20 @@ INPUT_PORTS_END
void microvision_state::microvision(machine_config &config)
{
I8021(config, m_i8021, 2000000); // approximately
I8021(config, m_i8021, 0);
m_i8021->bus_out_cb().set(FUNC(microvision_state::i8021_p0_write));
m_i8021->p1_out_cb().set(FUNC(microvision_state::i8021_p1_write));
m_i8021->p2_out_cb().set(FUNC(microvision_state::i8021_p2_write));
m_i8021->t1_in_cb().set(FUNC(microvision_state::i8021_t1_read));
m_i8021->bus_in_cb().set(FUNC(microvision_state::i8021_bus_read));
TMS1100(config, m_tms1100, 500000); // most games seem to be running at approximately this speed
m_tms1100->set_output_pla(microvision_output_pla_0);
TMS1100(config, m_tms1100, 0);
m_tms1100->set_output_pla(microvision_output_pla[0]);
m_tms1100->set_decode_micro().set(FUNC(microvision_state::tms1100_decode_micro));
m_tms1100->k().set(FUNC(microvision_state::tms1100_read_k));
m_tms1100->o().set(FUNC(microvision_state::tms1100_write_o));
m_tms1100->r().set(FUNC(microvision_state::tms1100_write_r));
config.set_maximum_quantum(attotime::from_hz(60));
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
screen.set_refresh_hz(60);
screen.set_vblank_time(0);
@ -680,9 +697,7 @@ void microvision_state::microvision(machine_config &config)
ROM_START( microvsn )
ROM_REGION( 0x800, "maincpu1", ROMREGION_ERASE00 )
ROM_REGION( 0x800, "maincpu2", ROMREGION_ERASE00 )
ROM_REGION( 867, "maincpu2:mpla", 0 )
ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) // verified for: pinball, blockbuster, bowling
ROM_REGION( 867, "maincpu2:mpla", ROMREGION_ERASE00 )
ROM_REGION( 365, "maincpu2:opla", ROMREGION_ERASE00 )
ROM_END

View File

@ -22,6 +22,7 @@
1997: R-Zone DataZone: PDA with a built-in SuperScreen.
TODO:
- softwarelist? it's impossible right now due to SVG initialization
- support for SuperScreen. SVG colors will need to be inverted, or maybe
with artwork or HLSL?
- add DataZone, will get its own driver