diff --git a/hash/microvision.xml b/hash/microvision.xml index 0807ab271cb..d894b8b1e66 100644 --- a/hash/microvision.xml +++ b/hash/microvision.xml @@ -101,8 +101,8 @@ The "rc" feature is used to indicate the source of the clock signal Milton Bradley - - + + diff --git a/src/devices/cpu/tms1000/tms0980.cpp b/src/devices/cpu/tms1000/tms0980.cpp index 8521505d585..76d295717e7 100644 --- a/src/devices/cpu/tms1000/tms0980.cpp +++ b/src/devices/cpu/tms1000/tms0980.cpp @@ -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); } diff --git a/src/devices/cpu/tms1000/tms1000.cpp b/src/devices/cpu/tms1000/tms1000.cpp index f99aacc637f..4ffefd7ef91 100644 --- a/src/devices/cpu/tms1000/tms1000.cpp +++ b/src/devices/cpu/tms1000/tms1000.cpp @@ -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; diff --git a/src/devices/cpu/tms1000/tms1k_base.cpp b/src/devices/cpu/tms1000/tms1k_base.cpp index f669a349662..6dbbaed3b60 100644 --- a/src/devices/cpu/tms1000/tms1k_base.cpp +++ b/src/devices/cpu/tms1000/tms1k_base.cpp @@ -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()); diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h index b4c8df9ed43..e535e9322c9 100644 --- a/src/devices/cpu/tms1000/tms1k_base.h +++ b/src/devices/cpu/tms1000/tms1k_base.h @@ -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; diff --git a/src/mame/drivers/microvsn.cpp b/src/mame/drivers/microvsn.cpp index eb72798d1ab..e5af589975c 100644 --- a/src/mame/drivers/microvsn.cpp +++ b/src/mame/drivers/microvsn.cpp @@ -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 m_dac; required_device m_i8021; required_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 diff --git a/src/mame/drivers/rzone.cpp b/src/mame/drivers/rzone.cpp index c191db0a6ad..f4e24b5cbbd 100644 --- a/src/mame/drivers/rzone.cpp +++ b/src/mame/drivers/rzone.cpp @@ -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