diff options
23 files changed, 955 insertions, 399 deletions
diff --git a/hash/jakks_gamekey_wp.xml b/hash/jakks_gamekey_wp.xml new file mode 100644 index 00000000000..9d0f937c6dd --- /dev/null +++ b/hash/jakks_gamekey_wp.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd"> +<!-- +license:CC0-1.0 +--> +<softwarelist name="jakks_gamekey_wp" description="JAKKS Pacific 'WP' Game Keys"> + + <!-- This list is for the 'WP' coded Game Keys, for Winnie the Pooh --> + + <!-- from a GameKey with Italian packaging, but plays in English --> + <software name="pooh"> + <description>Winnie the Pooh - Piglet's Special Day (3 Bonus Games)</description> + <year>2005</year> + <publisher>JAKKS Pacific / Backbone Entertainment</publisher> + <part name="cart" interface="jakks_gamekey"> + <dataarea name="rom" size="0x800000"> + <rom name="wpgamekey.bin" size="0x200000" crc="7700ed88" sha1="b6b1570b2634fb652b6be7fe758afc5a19d738de" offset="0" /> + </dataarea> + </part> + </software> + +</softwarelist> diff --git a/hash/telestory_cart.xml b/hash/telestory_cart.xml index 743699479bd..7b165b8c4c8 100644 --- a/hash/telestory_cart.xml +++ b/hash/telestory_cart.xml @@ -113,6 +113,17 @@ Undumped carts: </part> </software> + <software name="poohit" cloneof="pooh" supported="no"> + <description>Winnie the Pooh - Salta, Tigro, Salta! / Winnie the Pooh - l'orsetto goloso (Italy)</description> + <year>2006</year> + <publisher>JAKKS Pacific / Toymax / Handheld Games</publisher> + <part name="cart" interface="telestory_cart"> + <dataarea name="rom" size="0x800000"> + <rom name="telestorypoohit.bin" size="0x800000" crc="ca1cbad1" sha1="70541709d31897619760b577a1cfc29d936968b1"/> + </dataarea> + </part> + </software> + <software name="cinder" supported="no"> <description>Cinderella - Cinderella / Beauties in Bloom (USA)</description> <year>2006</year> @@ -135,6 +146,17 @@ Undumped carts: </part> </software> + <software name="lionkingit" cloneof="lionking" supported="no"> + <description>Il Re Leone / Il Re Leone II - Il Regno Di Simba (Italy)</description> + <year>2006</year> + <publisher>JAKKS Pacific / Toymax / Handheld Games</publisher> + <part name="cart" interface="telestory_cart"> + <dataarea name="rom" size="0x800000"> + <rom name="telestorylionkingit.bin" size="0x800000" crc="e9661239" sha1="e3337c9a4ba3a9baa9b175ba3503d867a5141a9e"/> + </dataarea> + </part> + </software> + <software name="dora" supported="no"> <description>Dora the Explorer - At the Carnival / Dora Goes to School (USA)</description> <year>2006</year> diff --git a/src/devices/bus/mononcol/rom.h b/src/devices/bus/mononcol/rom.h index 7a0230e334c..6eb58e7d5f7 100644 --- a/src/devices/bus/mononcol/rom.h +++ b/src/devices/bus/mononcol/rom.h @@ -19,7 +19,6 @@ public: mononcol_rom_plain_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); uint8_t read() override { return m_spi->read(); } - void dir_w(int state) override { m_spi->dir_w(state); } void write(uint8_t data) override { m_spi->write(data); } void set_ready() override { m_spi->set_ready(); } diff --git a/src/devices/bus/mononcol/slot.h b/src/devices/bus/mononcol/slot.h index 5032044a8ca..1a13ec6b750 100644 --- a/src/devices/bus/mononcol/slot.h +++ b/src/devices/bus/mononcol/slot.h @@ -22,7 +22,6 @@ public: // reading and writing virtual uint8_t read() = 0; - virtual void dir_w(int state) = 0; virtual void write(uint8_t data) = 0; virtual void set_ready() = 0; @@ -65,11 +64,6 @@ public: return m_cart->read(); } - void dir_w(int state) - { - m_cart->dir_w(state); - } - void set_ready() { m_cart->set_ready(); diff --git a/src/devices/cpu/axc51/axc51.cpp b/src/devices/cpu/axc51/axc51.cpp index 0f1ee436f51..e6499e8f667 100644 --- a/src/devices/cpu/axc51/axc51.cpp +++ b/src/devices/cpu/axc51/axc51.cpp @@ -88,7 +88,6 @@ axc51base_cpu_device::axc51base_cpu_device(const machine_config &mconfig, device , m_dac_out_cb(*this) , m_spi_in_cb(*this, 0xff) , m_spi_out_cb(*this) - , m_spi_out_dir_cb(*this) , m_rtemp(0) { for (int i = 0; i < 0x80; i++) @@ -1402,7 +1401,6 @@ void axc51base_cpu_device::spicon_w(uint8_t data) { // LOGMASKED(LOG_UNSORTED,"%s: sfr_write SFR_SPICON %02x\n", machine().describe_context(), data); m_sfr_regs[SFR_SPICON] = data; - m_spi_out_dir_cb((data & 0x20) ? true : false); } diff --git a/src/devices/cpu/axc51/axc51.h b/src/devices/cpu/axc51/axc51.h index 8dccb9ce981..e507d600c2a 100644 --- a/src/devices/cpu/axc51/axc51.h +++ b/src/devices/cpu/axc51/axc51.h @@ -28,7 +28,6 @@ public: auto spi_in_cb() { return m_spi_in_cb.bind(); } auto spi_out_cb() { return m_spi_out_cb.bind(); } - auto spi_out_dir_cb() { return m_spi_out_dir_cb.bind(); } void program_internal(address_map &map) ATTR_COLD; void data_internal(address_map &map) ATTR_COLD; @@ -109,8 +108,6 @@ protected: devcb_read8 m_spi_in_cb; devcb_write8 m_spi_out_cb; - devcb_write_line m_spi_out_dir_cb; - // for the debugger uint8_t m_rtemp; diff --git a/src/devices/cpu/unsp/unsp_exxx.cpp b/src/devices/cpu/unsp/unsp_exxx.cpp index ac8a09d59ee..ec2e0db5183 100644 --- a/src/devices/cpu/unsp/unsp_exxx.cpp +++ b/src/devices/cpu/unsp/unsp_exxx.cpp @@ -10,7 +10,7 @@ #define LOG_UNSP_MULS (1U << 1) #define LOG_UNSP_SHIFTS (1U << 2) -#define VERBOSE (LOG_UNSP_SHIFTS) +#define VERBOSE (0) #include "logmacro.h" diff --git a/src/devices/machine/generalplus_gpce4_soc.cpp b/src/devices/machine/generalplus_gpce4_soc.cpp index 7218fff0981..efd81f9b7dc 100644 --- a/src/devices/machine/generalplus_gpce4_soc.cpp +++ b/src/devices/machine/generalplus_gpce4_soc.cpp @@ -32,8 +32,10 @@ generalplus_gpce4_soc_device::generalplus_gpce4_soc_device(const machine_config , m_portb_out(*this) , m_portc_out(*this) , m_spi2_out(*this) + , m_spi_out(*this) + , m_spi_reset(*this) , m_dac(*this, "dac") - , m_bank(*this, "spibank") + , m_spi_tx_timer(*this, "timer_spi_tx") { } @@ -59,11 +61,42 @@ void generalplus_gpce4_soc_device::device_start() save_item(NAME(m_fiq_sel)); save_item(NAME(m_fiq2_sel)); save_item(NAME(m_spi2_ctrl)); + save_item(NAME(m_spi_ctrl)); + + save_item(NAME(m_spi_rx_fifo)); + save_item(NAME(m_spi_tx_fifo)); + save_item(NAME(m_rx_fifo_entries)); + save_item(NAME(m_tx_fifo_entries)); + + save_item(NAME(m_pwm0_ctrl)); + save_item(NAME(m_pwm1_ctrl)); + save_item(NAME(m_pwm2_ctrl)); + save_item(NAME(m_pwm3_ctrl)); set_vectorbase(0x4010); - m_bank->configure_entries(0, memregion("spi")->bytes() / 0x400000, memregion("spi")->base(), 0x400000); - m_bank->set_entry(0); + m_spiregion = 0; + m_spisize = 0; +} + +u8 *generalplus_gpce4_soc_device::get_spi_romregion() +{ + return m_spiregion; +} + + + +void generalplus_gpce4_soc_device::reset_spi_fifos() +{ + for (int i = 0; i < 8; i++) + { + m_spi_rx_fifo[i] = 0; + m_spi_tx_fifo[i] = 0; + } + m_rx_fifo_entries = 0; + m_tx_fifo_entries = 0; + m_spi_tx_timer->adjust(attotime::never); + m_spi_reset(1); } void generalplus_gpce4_soc_device::device_reset() @@ -88,6 +121,15 @@ void generalplus_gpce4_soc_device::device_reset() m_fiq_sel = 0; m_fiq2_sel = 0; m_spi2_ctrl = 0; + + m_spi_ctrl = 0; + + m_pwm0_ctrl = 0; + m_pwm1_ctrl = 0; + m_pwm2_ctrl = 0; + m_pwm3_ctrl = 0; + + reset_spi_fifos(); } void generalplus_gpce4_soc_device::device_add_mconfig(machine_config &config) @@ -96,6 +138,9 @@ void generalplus_gpce4_soc_device::device_add_mconfig(machine_config &config) TIMER(config, "timer_a").configure_periodic(FUNC(generalplus_gpce4_soc_device::timer_a_cb), attotime::from_hz(20000)); // audio TIMER(config, "timer_2hz").configure_periodic(FUNC(generalplus_gpce4_soc_device::timer_2hz_cb), attotime::from_hz(2)); TIMER(config, "timer_64hz").configure_periodic(FUNC(generalplus_gpce4_soc_device::timer_64hz_cb), attotime::from_hz(64)); + TIMER(config, "timer_2khz").configure_periodic(FUNC(generalplus_gpce4_soc_device::timer_2khz_cb), attotime::from_hz(2000)); + + TIMER(config, "timer_spi_tx").configure_generic(FUNC(generalplus_gpce4_soc_device::timer_spi_tx)); SPEAKER(config, "speaker").front_center(); DAC_16BIT_R2R_TWOS_COMPLEMENT(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // unknown DAC @@ -134,10 +179,10 @@ void generalplus_gpce4_soc_device::internal_map(address_map &map) map(0x003015, 0x003015).w(FUNC(generalplus_gpce4_soc_device::timerc_counter_w)); // TimerC_CNTR map(0x003016, 0x003016).rw(FUNC(generalplus_gpce4_soc_device::timer_ctrl_r), FUNC(generalplus_gpce4_soc_device::timer_ctrl_w)); // Timer_Ctrl - map(0x003020, 0x003020).w(FUNC(generalplus_gpce4_soc_device::pwm0_ctrl_w)); // PWM0_Ctrl - map(0x003021, 0x003021).w(FUNC(generalplus_gpce4_soc_device::pwm1_ctrl_w)); // PWM1_Ctrl - map(0x003022, 0x003022).w(FUNC(generalplus_gpce4_soc_device::pwm2_ctrl_w)); // PWM2_Ctrl - map(0x003023, 0x003023).w(FUNC(generalplus_gpce4_soc_device::pwm3_ctrl_w)); // PWM3_Ctrl + map(0x003020, 0x003020).rw(FUNC(generalplus_gpce4_soc_device::pwm0_ctrl_r), FUNC(generalplus_gpce4_soc_device::pwm0_ctrl_w)); // PWM0_Ctrl + map(0x003021, 0x003021).rw(FUNC(generalplus_gpce4_soc_device::pwm1_ctrl_r), FUNC(generalplus_gpce4_soc_device::pwm1_ctrl_w)); // PWM1_Ctrl + map(0x003022, 0x003022).rw(FUNC(generalplus_gpce4_soc_device::pwm2_ctrl_r), FUNC(generalplus_gpce4_soc_device::pwm2_ctrl_w)); // PWM2_Ctrl + map(0x003023, 0x003023).rw(FUNC(generalplus_gpce4_soc_device::pwm3_ctrl_r), FUNC(generalplus_gpce4_soc_device::pwm3_ctrl_w)); // PWM3_Ctrl map(0x003030, 0x003030).w(FUNC(generalplus_gpce4_soc_device::system_clock_w)); // System_Clock // 3031 - System_Reset @@ -173,7 +218,7 @@ void generalplus_gpce4_soc_device::internal_map(address_map &map) map(0x003091, 0x003091).rw(FUNC(generalplus_gpce4_soc_device::spi2_txstatus_r), FUNC(generalplus_gpce4_soc_device::spi2_txstatus_w)); // SPI2_TXStatus map(0x003092, 0x003092).w(FUNC(generalplus_gpce4_soc_device::spi2_txdata_w)); // SPI2_TXData map(0x003093, 0x003093).rw(FUNC(generalplus_gpce4_soc_device::spi2_rxstatus_r), FUNC(generalplus_gpce4_soc_device::spi2_rxstatus_w)); // SPI2_RXStatus - map(0x003094, 0x003094).r(FUNC(generalplus_gpce4_soc_device::spi2_rxdata_r)); // SPI2_RXData + map(0x003094, 0x003094).r(FUNC(generalplus_gpce4_soc_device::spi2_rxdata_r)); // SPI2_RXData map(0x003095, 0x003095).rw(FUNC(generalplus_gpce4_soc_device::spi2_misc_r), FUNC(generalplus_gpce4_soc_device::spi2_misc_w)); // SPI2_Misc // 309a - SPI2_DMA_Start @@ -200,10 +245,10 @@ void generalplus_gpce4_soc_device::internal_map(address_map &map) map(0x0030e0, 0x0030e0).rw(FUNC(generalplus_gpce4_soc_device::spi_ctrl_r), FUNC(generalplus_gpce4_soc_device::spi_ctrl_w)); // SPI_Ctrl map(0x0030e1, 0x0030e1).w(FUNC(generalplus_gpce4_soc_device::spi_txstatus_w)); // SPI_TXStatus map(0x0030e2, 0x0030e2).w(FUNC(generalplus_gpce4_soc_device::spi_txdata_w)); // SPI_TXData - map(0x0030e3, 0x0030e3).w(FUNC(generalplus_gpce4_soc_device::spi_rxstatus_w)); // SPI_RXStatus + map(0x0030e3, 0x0030e3).rw(FUNC(generalplus_gpce4_soc_device::spi_rxstatus_r), FUNC(generalplus_gpce4_soc_device::spi_rxstatus_w)); // SPI_RXStatus map(0x0030e4, 0x0030e4).r(FUNC(generalplus_gpce4_soc_device::spi_rxdata_r)); // SPI_RXData map(0x0030e5, 0x0030e5).rw(FUNC(generalplus_gpce4_soc_device::spi_misc_r), FUNC(generalplus_gpce4_soc_device::spi_misc_w)); // SPI_Misc - // 30e6 - SPI_Man_Ctrl + map(0x0030e6, 0x0030e6).rw(FUNC(generalplus_gpce4_soc_device::spi_man_ctrl_r), FUNC(generalplus_gpce4_soc_device::spi_man_ctrl_w)); // 30e6 - SPI_Man_Ctrl map(0x0030e7, 0x0030e7).rw(FUNC(generalplus_gpce4_soc_device::spi_auto_ctrl_r), FUNC(generalplus_gpce4_soc_device::spi_auto_ctrl_w)); // SPI_Auto_Ctrl // 30e8 - SPI_PRGM_BC map(0x0030e9, 0x0030e9).rw(FUNC(generalplus_gpce4_soc_device::spi_bank_r), FUNC(generalplus_gpce4_soc_device::spi_bank_w)); // SPI_BANK @@ -217,7 +262,7 @@ void generalplus_gpce4_soc_device::internal_map(address_map &map) map(0x004000, 0x00bfff).rom().region("internal", 0x0000); // 0x4000-0x400f are 'test' vectors, 0x4010 - 0x401f are user vectors, 0x4020 - 0x47ff is 'standard test program' 0x4800+ is custom internal ROM map(0x00c000, 0x00ffff).rom().region("internal", 0x0000); - map(0x200000, 0x3fffff).bankr("spibank"); // has direct access to SPI ROM + map(0x200000, 0x3fffff).r(FUNC(generalplus_gpce4_soc_device::spi_direct_r)); // has direct access to SPI ROM } TIMER_DEVICE_CALLBACK_MEMBER( generalplus_gpce4_soc_device::timer_c_cb ) @@ -240,11 +285,16 @@ TIMER_DEVICE_CALLBACK_MEMBER( generalplus_gpce4_soc_device::timer_64hz_cb ) request_interrupt(2); } +TIMER_DEVICE_CALLBACK_MEMBER( generalplus_gpce4_soc_device::timer_2khz_cb ) +{ + request_interrupt(9); +} + // IOA u16 generalplus_gpce4_soc_device::ioa_data_r() { - LOGMASKED(LOG_IO, "%s: m_porta_in\n", machine().describe_context()); + LOGMASKED(LOG_IO, "%s: ioa_data_r\n", machine().describe_context()); return m_porta_in(); } @@ -451,6 +501,30 @@ void generalplus_gpce4_soc_device::timerc_counter_w(u16 data) // PWM +u16 generalplus_gpce4_soc_device::pwm0_ctrl_r() +{ + LOGMASKED(LOG_TIMERS, "%s: pwm0_ctrl_r\n", machine().describe_context()); + return m_pwm0_ctrl; +} + +u16 generalplus_gpce4_soc_device::pwm1_ctrl_r() +{ + LOGMASKED(LOG_TIMERS, "%s: pwm1_ctrl_r\n", machine().describe_context()); + return m_pwm1_ctrl; +} + +u16 generalplus_gpce4_soc_device::pwm2_ctrl_r() +{ + LOGMASKED(LOG_TIMERS, "%s: pwm2_ctrl_r\n", machine().describe_context()); + return m_pwm2_ctrl; +} + +u16 generalplus_gpce4_soc_device::pwm3_ctrl_r() +{ + LOGMASKED(LOG_TIMERS, "%s: pwm3_ctrl_r\n", machine().describe_context()); + return m_pwm3_ctrl; +} + void generalplus_gpce4_soc_device::pwm0_ctrl_w(u16 data) { LOGMASKED(LOG_PWM, "%s: pwm0_ctrl_w %04x\n", machine().describe_context(), data); @@ -510,7 +584,7 @@ void generalplus_gpce4_soc_device::wait_ctrl_w(u16 data) // 6 --- // 5 --- // 4 --- -// +// // 3 --- // 2 --- // 1 Cache_Clr @@ -591,11 +665,11 @@ void generalplus_gpce4_soc_device::interrupt2_status_w(u16 data) { LOGMASKED(LOG_IRQ, "%s: interrupt2_status_w %04x\n", machine().describe_context(), data); - if (data & 0x0004) - clear_interrupt(2); - - if (data & 0x0001) - clear_interrupt(0); + for (int i = 0; i < 16; i++) + { + if (data & (1 << i)) + clear_interrupt(i); + } } u16 generalplus_gpce4_soc_device::interrupt2_ctrl_r() @@ -631,12 +705,17 @@ void generalplus_gpce4_soc_device::interrupt2_ctrl_w(u16 data) u16 generalplus_gpce4_soc_device::spi_ctrl_r() { LOGMASKED(LOG_SPI1, "%s: spi_ctrl_r\n", machine().describe_context()); - return machine().rand(); + return m_spi_ctrl &~ 0x0800; } void generalplus_gpce4_soc_device::spi_ctrl_w(u16 data) { LOGMASKED(LOG_SPI1, "%s: spi_ctrl_w %04x\n", machine().describe_context(), data); + m_spi_ctrl = data; + + if (data & 0x0800) + reset_spi_fifos(); + } void generalplus_gpce4_soc_device::spi_misc_w(u16 data) @@ -649,9 +728,76 @@ void generalplus_gpce4_soc_device::spi_txstatus_w(u16 data) LOGMASKED(LOG_SPI1, "%s: spi_txstatus_w %04x\n", machine().describe_context(), data); } + +TIMER_DEVICE_CALLBACK_MEMBER(generalplus_gpce4_soc_device::timer_spi_tx) +{ + // will only be called if something is in the tx FIFO + + u8 ret = m_spi_tx_fifo[0]; + + for (int i = 1; i < 8; i++) + { + m_spi_tx_fifo[i - 1] = m_spi_tx_fifo[i]; + } + m_spi_tx_fifo[7] = 0; + + // only 8-bits are written to FIFO + // the SoC turns this into actual SPI signals + m_spi_out(ret); + + m_tx_fifo_entries--; + + if (m_tx_fifo_entries == 0) + { + m_spi_tx_timer->enable(false); + m_spi_tx_timer->adjust(attotime::never); + } +} + +void generalplus_gpce4_soc_device::recieve_spi_fifo_data(u8 data) +{ + if (m_rx_fifo_entries < 8) + { + m_spi_rx_fifo[m_rx_fifo_entries] = data; + m_rx_fifo_entries++; + } + else + { + fatalerror("RX FIFO OVERFLOW\n"); + } +} + +void generalplus_gpce4_soc_device::write_to_tx_fifo(u8 data) +{ + if (m_tx_fifo_entries == 0) + { + m_spi_tx_timer->enable(true); + m_spi_tx_timer->adjust(attotime::zero, 0, attotime::from_hz(48'000'000)); + } + + if (m_tx_fifo_entries < 8) + { + m_spi_tx_fifo[m_tx_fifo_entries] = data; + m_tx_fifo_entries++; + } + else + { + fatalerror("TX FIFO OVERFLOW\n"); + } +} + + + void generalplus_gpce4_soc_device::spi_txdata_w(u16 data) { LOGMASKED(LOG_SPI1, "%s: spi_txdata_w %04x\n", machine().describe_context(), data); + write_to_tx_fifo(data); +} + +u16 generalplus_gpce4_soc_device::spi_rxstatus_r() +{ + LOGMASKED(LOG_SPI2, "%s: spi_rxstatus_r\n", machine().describe_context()); + return 0x8000; } void generalplus_gpce4_soc_device::spi_rxstatus_w(u16 data) @@ -662,15 +808,61 @@ void generalplus_gpce4_soc_device::spi_rxstatus_w(u16 data) u16 generalplus_gpce4_soc_device::spi_rxdata_r() { LOGMASKED(LOG_SPI1, "%s: spi_rxdata_r\n", machine().describe_context()); - return machine().rand() & 0x01; + + if (m_rx_fifo_entries == 0) + { + printf("rx underflow!\n"); + return 0; + } + + u8 ret = m_spi_rx_fifo[0]; + + for (int i = 1; i < 8; i++) + { + m_spi_rx_fifo[i - 1] = m_spi_rx_fifo[i]; + } + m_spi_rx_fifo[7] = 0; + m_rx_fifo_entries--; + + return ret; } -u16 generalplus_gpce4_soc_device::spi_misc_r() +u16 generalplus_gpce4_soc_device::spi_man_ctrl_r() { - LOGMASKED(LOG_SPI1, "%s: spi_misc_r\n", machine().describe_context()); + LOGMASKED(LOG_SPI1, "%s: spi_man_ctrl_r\n", machine().describe_context()); return 0x0000; } +void generalplus_gpce4_soc_device::spi_man_ctrl_w(u16 data) +{ + LOGMASKED(LOG_SPI1, "%s: spi_man_ctrl_r %04x\n", machine().describe_context(), data); +} + + +u16 generalplus_gpce4_soc_device::spi_misc_r() +{ + LOGMASKED(LOG_SPI1, "%s: spi_misc_r\n", machine().describe_context()); + return 0x0004; +} + +// SPI_Auto_CTRL +// 15 ADDR_LEN +// 14 ADDR_1BIT +// 13 AUTO_PRGM +// 12 AUTO_ENHM +// 11 AUTO_DUMMY_CYCLE[3] +// 10 AUTO_DUMMY_CYCLE[2] +// 9 AUTO_DUMMY_CYCLE[1] +// 8 AUTO_DUMMY_CYCLE[0] +// 7 AUTO_CMD[7] +// 6 AUTO_CMD[6] +// 5 AUTO_CMD[5] +// 4 AUTO_CMD[4] +// 3 AUTO_CMD[3] +// 2 AUTO_CMD[2] +// 1 AUTO_CMD[1] +// 0 AUTO_CMD[0] + u16 generalplus_gpce4_soc_device::spi_auto_ctrl_r() { LOGMASKED(LOG_SPI1, "%s: spi_auto_ctrl_r\n", machine().describe_context()); @@ -683,6 +875,22 @@ void generalplus_gpce4_soc_device::spi_auto_ctrl_w(u16 data) m_spi_auto_ctrl = data; } +u16 generalplus_gpce4_soc_device::spi_direct_r(offs_t offset) +{ + // The GPCE4 chips can see a bank of SPI memory as a flat space + // as log as SPI_Auto_CTRL has been set to 'READ4' mode prior to + // accessing it (signals are converted to random access SPI on the + // fly) + // + // Emulating it this way is impractical for emulation (DASM wouldn't + // work) so we just present it as a flat space directly. + if (!m_spiregion) + return 0x0000; + + u16 ret = (m_spiregion[((offset * 2) + 0) + (m_spi_bank * 0x400000)]) | (m_spiregion[((offset * 2) + 1) + (m_spi_bank * 0x400000)] << 8); + return ret; +} + u16 generalplus_gpce4_soc_device::spi_bank_r() { LOGMASKED(LOG_SPI1, "%s: spi_bank_r\n", machine().describe_context()); @@ -693,7 +901,6 @@ void generalplus_gpce4_soc_device::spi_bank_w(u16 data) { LOGMASKED(LOG_SPI1, "%s: spi_bank_w %04x\n", machine().describe_context(), data); m_spi_bank = data; - m_bank->set_entry(data & 0xf); } void generalplus_gpce4_soc_device::update_interrupts() @@ -725,6 +932,15 @@ void generalplus_gpce4_soc_device::update_interrupts() set_input_line(UNSP_IRQ3_LINE, CLEAR_LINE); } + if ((m_interrupt_status & 0x0000'0200) && (m_interrupt2_ctrl & 0x0200)) + { + set_input_line(UNSP_IRQ6_LINE, ASSERT_LINE); + } + else + { + set_input_line(UNSP_IRQ6_LINE, CLEAR_LINE); + } + if ((m_interrupt_status & 0x0000'0001) && (m_interrupt2_ctrl & 0x0001)) { set_input_line(UNSP_IRQ7_LINE, ASSERT_LINE); @@ -766,14 +982,12 @@ u16 generalplus_gpce4_soc_device::interrupt_status_r() void generalplus_gpce4_soc_device::interrupt_status_w(u16 data) { - if (data & 0x8000) - clear_interrupt(31); - - if (data & 0x2000) - clear_interrupt(29); - - if (data & 0x0100) - clear_interrupt(24); + LOGMASKED(LOG_IRQ, "%s: interrupt_status_w %04x\n", machine().describe_context(), data); + for (int i = 0; i < 16; i++) + { + if (data & (1 << i)) + clear_interrupt(i + 16); + } } u16 generalplus_gpce4_soc_device::fiq_sel_r() @@ -811,12 +1025,12 @@ void generalplus_gpce4_soc_device::fiq2_sel_w(u16 data) // 10 --- // 9 --- // 8 MOD -// +// // 7 --- // 6 --- // 5 SCKPHA // 4 SCKPOL -// +// // 3 --- // 2 SCKSEL[2] // 1 SCKSEL[1] @@ -856,12 +1070,12 @@ void generalplus_gpce4_soc_device::spi2_rxstatus_w(u16 data) // 10 -- // 9 -- // 8 -- -// +// // 7 TXFLEV[3] // 6 TXFLEV[2] // 5 TXFLEV[1] // 4 TXFLEX[0] -// +// // 3 TXFFLAG[3] // 2 TXFFLAG[2] // 1 TXFFLAG[1] @@ -892,22 +1106,22 @@ u16 generalplus_gpce4_soc_device::spi2_rxdata_r() } // P_SPI2_MISC -// +// // 15 --- // 14 --- // 13 --- // 12 --- -// +// // 11 --- // 10 --- // 9 OVER // 8 SMART -// +// // 7 --- // 6 --- // 5 --- // 4 BSY -// +// // 3 RFF // 2 RNE // 1 TNF @@ -955,7 +1169,7 @@ void generalplus_gpce4_soc_device::adc_ctrl_w(u16 data) u16 generalplus_gpce4_soc_device::adc_data_r() { LOGMASKED(LOG_ADC, "%s: adc_data_r\n", machine().describe_context()); - return 0x0000; + return 0xffff;// 0000; } void generalplus_gpce4_soc_device::adc_data_w(u16 data) diff --git a/src/devices/machine/generalplus_gpce4_soc.h b/src/devices/machine/generalplus_gpce4_soc.h index 992a445629e..1060956e3ba 100644 --- a/src/devices/machine/generalplus_gpce4_soc.h +++ b/src/devices/machine/generalplus_gpce4_soc.h @@ -25,10 +25,16 @@ public: auto portc_out() { return m_portc_out.bind(); } auto spi2_out() { return m_spi2_out.bind(); } + auto spi_out() { return m_spi_out.bind(); } + auto spi_reset() { return m_spi_reset.bind(); } void request_interrupt(int which); void clear_interrupt(int which); + void recieve_spi_fifo_data(u8 data); + u8 *get_spi_romregion(); + void set_spi_romregion(u8 *region, u32 size) { m_spiregion = region; m_spisize = size; } + protected: // device-level overrides virtual void device_start() override ATTR_COLD; @@ -78,11 +84,16 @@ private: void timerc_data_w(u16 data); void timerc_counter_w(u16 data); + u16 pwm0_ctrl_r(); + u16 pwm1_ctrl_r(); + u16 pwm2_ctrl_r(); + u16 pwm3_ctrl_r(); + void pwm0_ctrl_w(u16 data); void pwm1_ctrl_w(u16 data); void pwm2_ctrl_w(u16 data); void pwm3_ctrl_w(u16 data); - + void system_clock_w(u16 data); void timebase_clear_w(u16 data); @@ -120,10 +131,13 @@ private: u16 spi2_misc_r(); void spi2_misc_w(u16 data); + u16 spi_man_ctrl_r(); + void spi_man_ctrl_w(u16 data); u16 spi_ctrl_r(); void spi_ctrl_w(u16 data); void spi_txstatus_w(u16 data); void spi_txdata_w(u16 data); + u16 spi_rxstatus_r(); void spi_rxstatus_w(u16 data); u16 spi_rxdata_r(); u16 spi_misc_r(); @@ -140,12 +154,22 @@ private: u16 adc_linein_bitctrl_r(); void adc_linein_bitctrl_w(u16 data); + u16 spi_direct_r(offs_t offset); + void update_interrupts(); + void write_to_tx_fifo(u8 data); + void reset_spi_fifos(); + TIMER_DEVICE_CALLBACK_MEMBER(timer_c_cb); TIMER_DEVICE_CALLBACK_MEMBER(timer_a_cb); TIMER_DEVICE_CALLBACK_MEMBER(timer_2hz_cb); TIMER_DEVICE_CALLBACK_MEMBER(timer_64hz_cb); + TIMER_DEVICE_CALLBACK_MEMBER(timer_2khz_cb); + TIMER_DEVICE_CALLBACK_MEMBER(timer_spi_tx); + + u8 *m_spiregion; + u32 m_spisize; u16 m_ioa_buffer; u16 m_iob_buffer; @@ -165,9 +189,20 @@ private: u16 m_fiq_sel; u16 m_fiq2_sel; u16 m_spi2_ctrl; + u16 m_spi_ctrl; + + u16 m_pwm0_ctrl; + u16 m_pwm1_ctrl; + u16 m_pwm2_ctrl; + u16 m_pwm3_ctrl; u32 m_interrupt_status; + u8 m_spi_rx_fifo[8]; + u8 m_spi_tx_fifo[8]; + u8 m_rx_fifo_entries; + u8 m_tx_fifo_entries; + devcb_read16 m_porta_in; devcb_read16 m_portb_in; devcb_read16 m_portc_in; @@ -177,9 +212,11 @@ private: devcb_write16 m_portc_out; devcb_write8 m_spi2_out; + devcb_write8 m_spi_out; + devcb_write8 m_spi_reset; required_device<dac_word_device_base> m_dac; - required_memory_bank m_bank; + required_device<timer_device> m_spi_tx_timer; }; DECLARE_DEVICE_TYPE(GPCE4, generalplus_gpce4_soc_device) diff --git a/src/devices/machine/generic_spi_flash.cpp b/src/devices/machine/generic_spi_flash.cpp index 7421004bf2e..6f24a33ef9e 100644 --- a/src/devices/machine/generic_spi_flash.cpp +++ b/src/devices/machine/generic_spi_flash.cpp @@ -1,5 +1,8 @@ // license:BSD-3-Clause // copyright-holders:David Haywood + +// HLE-like implementation for SPI Flash ROMs using byte interface rather than SPI signals + #include "emu.h" #include "generic_spi_flash.h" @@ -9,12 +12,17 @@ #include "logmacro.h" -DEFINE_DEVICE_TYPE(GENERIC_SPI_FLASH, generic_spi_flash_device, "generic_spi_flash", "Generic SPI Flash handling") +DEFINE_DEVICE_TYPE(GENERIC_SPI_FLASH, generic_spi_flash_device, "generic_spi_flash", "Generic Byte HLE SPI Flash handling") -generic_spi_flash_device::generic_spi_flash_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +generic_spi_flash_device::generic_spi_flash_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, GENERIC_SPI_FLASH, tag, owner, clock) , device_nvram_interface(mconfig, *this) + , m_multibyte_status_read(1) + , m_multibyte_status_write(1) { + m_idbytes[0] = 0xfe; + m_idbytes[1] = 0xfe; + m_idbytes[2] = 0x00; } void generic_spi_flash_device::device_start() @@ -22,7 +30,6 @@ void generic_spi_flash_device::device_start() save_item(NAME(m_spiaddr)); save_item(NAME(m_spi_state)); save_item(NAME(m_spilatch)); - save_item(NAME(m_spidir)); } void generic_spi_flash_device::device_reset() @@ -30,152 +37,327 @@ void generic_spi_flash_device::device_reset() m_spiaddr = 0; m_spi_state = 0; m_spilatch = 0; - m_spidir = false; -} - -void generic_spi_flash_device::write(uint8_t data) -{ - if (!m_spidir) // Send to SPI - { - switch (m_spi_state) - { - case READY_FOR_COMMAND: - if (data == 0x03) - { - m_spi_state = READY_FOR_ADDRESS2; - } - else if (data == 0x05) - { - m_spi_state = READY_FOR_STATUS_READ; - } - else if (data == 0x0b) - { - m_spi_state = READY_FOR_HSADDRESS2; - } - else if (data == 0x06) - { - // write enable - m_spi_state = READY_FOR_COMMAND; - } - else if (data == 0x04) - { - // write disable - m_spi_state = READY_FOR_COMMAND; - } - else if (data == 0x02) - { - // page program - m_spi_state = READY_FOR_WRITEADDRESS2; - } - else if (data == 0x20) - { - // erase 4k sector - m_spi_state = READY_FOR_COMMAND; - } - else - { - fatalerror("SPI set to unknown mode %02x\n", data); - } - break; - - case READY_FOR_WRITEADDRESS2: - m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); - m_spi_state = READY_FOR_WRITEADDRESS1; - break; - - case READY_FOR_WRITEADDRESS1: - m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); - m_spi_state = READY_FOR_WRITEADDRESS0; - break; - - case READY_FOR_WRITEADDRESS0: - m_spiaddr = (m_spiaddr & 0xffff00) | (data); - m_spi_state = READY_FOR_WRITE; - LOGMASKED(LOG_SPI, "SPI set to page WRITE mode with address %08x\n", m_spiaddr); - break; - - case READY_FOR_WRITE: - LOGMASKED(LOG_SPI, "Write SPI data %02x\n", data); - - m_spiptr[(m_spiaddr++) & (m_length-1)] = data; - - break; - - - case READY_FOR_ADDRESS2: - m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); - m_spi_state = READY_FOR_ADDRESS1; - break; - - case READY_FOR_ADDRESS1: - m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); - m_spi_state = READY_FOR_ADDRESS0; - break; - - case READY_FOR_ADDRESS0: - m_spiaddr = (m_spiaddr & 0xffff00) | (data); - m_spi_state = READY_FOR_READ; - m_spidir = 1; - LOGMASKED(LOG_SPI, "SPI set to READ mode with address %08x\n", m_spiaddr); - break; - - case READY_FOR_HSADDRESS2: - m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); - m_spi_state = READY_FOR_HSADDRESS1; - break; - - case READY_FOR_HSADDRESS1: - m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); - m_spi_state = READY_FOR_HSADDRESS0; - break; - - case READY_FOR_HSADDRESS0: - m_spiaddr = (m_spiaddr & 0xffff00) | (data); - m_spi_state = READY_FOR_HSDUMMY; - break; - - case READY_FOR_HSDUMMY: - m_spi_state = READY_FOR_READ; - m_spidir = 1; - LOGMASKED(LOG_SPI, "SPI set to High Speed READ mode with address %08x\n", m_spiaddr); - break; - - case READY_FOR_SECTORERASEADDRESS2: - m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); - m_spi_state = READY_FOR_SECTORERASEADDRESS1; - break; - - case READY_FOR_SECTORERASEADDRESS1: - m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); - m_spi_state = READY_FOR_SECTORERASEADDRESS0; - break; - - case READY_FOR_SECTORERASEADDRESS0: - m_spiaddr = (m_spiaddr & 0xffff00) | (data); - LOGMASKED(LOG_SPI, "SPI set to Erase Sector with address %08x\n", m_spiaddr); - break; - - } +} + +void generic_spi_flash_device::get_command(u8 data) +{ + if (data == COMMAND_01_WRSR) + { + LOGMASKED(LOG_SPI, "Set SPI to WRSR, 1 or 2 params required\n"); + m_spi_state = COMMAND_01_WRSR; + } + else if (data == COMMAND_9F_RDID) + { + LOGMASKED(LOG_SPI, "Set SPI to RDID (Read Identification)\n"); + m_spi_state = COMMAND_9F_RDID; + } + else if (data == COMMAND_03_READ) + { + LOGMASKED(LOG_SPI, "Set SPI to READ (normal - 3 params needed)\n"); + m_spi_state = COMMAND_03_READ; + } + else if (data == COMMAND_05_RDSR) + { + LOGMASKED(LOG_SPI, "Set SPI to RDSR (Read Status Register)\n"); + m_spi_state = COMMAND_05_RDSR; + } + else if (data == COMMAND_0B_FAST_READ) + { + LOGMASKED(LOG_SPI, "Set SPI to FAST READ (fast - 4 params needed)\n"); + m_spi_state = COMMAND_0B_FAST_READ; + } + else if (data == COMMAND_06_WREN) + { + LOGMASKED(LOG_SPI, "Set SPI to WREN (Write Enable)\n"); + m_spi_state = READY_FOR_COMMAND; + } + else if (data == COMMAND_04_WRDI) + { + LOGMASKED(LOG_SPI, "Set SPI to WRDI (Write Disable)\n"); + m_spi_state = READY_FOR_COMMAND; + } + else if (data == COMMAND_02_PP) + { + LOGMASKED(LOG_SPI, "Set SPI to PP (Page Program)\n"); + m_spi_state = COMMAND_02_PP; + } + else if (data == COMMAND_20_SE) + { + LOGMASKED(LOG_SPI, "Set SPI to SE (Sector Erase)\n"); + m_spi_state = COMMAND_20_SE; + } + else if (data == COMMAND_90_REMS) + { + LOGMASKED(LOG_SPI, "Set SPI to REMS (Read Electronic Manufacturer & Device ID)\n"); + m_spi_state = COMMAND_90_REMS; + } + else if (data == COMMAND_AB_RDP) + { + LOGMASKED(LOG_SPI, "Set SPI to RDP (Release from deep power down)\n"); + m_spi_state = READY_FOR_COMMAND; + } + else if (data == COMMAND_B9_DP) + { + LOGMASKED(LOG_SPI, "Set SPI to DP (deep power down)\n"); + m_spi_state = READY_FOR_COMMAND; + } + else if (data == COMMAND_EB_4READ) + { + LOGMASKED(LOG_SPI, "Set SPI to 4READ (Quad I/O read with configurable dummy bytes)\n"); + m_spi_state = COMMAND_EB_4READ; } else { - if (m_spi_state == READY_FOR_READ) - { - m_spilatch = m_spiptr[(m_spiaddr++) & (m_length-1)]; - } - else if (m_spi_state == READY_FOR_STATUS_READ) - { - m_spilatch = 0x00; - } + fatalerror("SPI set to unknown/unhandled command %02x\n", data); + } + + m_spi_state_step = 0; +} + +void generic_spi_flash_device::process_read_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); m_spi_state_step++; + break; + case 0x01: + m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); m_spi_state_step++; + break; + case 0x02: + m_spiaddr = (m_spiaddr & 0xffff00) | (data); m_spi_state_step++; + break; + default: + m_spilatch = m_spiptr[(m_spiaddr++) & (m_length - 1)]; + break; + } +} + +void generic_spi_flash_device::process_hsread_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); m_spi_state_step++; + break; + case 0x01: + m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); m_spi_state_step++; + break; + case 0x02: + m_spiaddr = (m_spiaddr & 0xffff00) | (data); m_spi_state_step++; + break; + case 0x03: + /* dummy */ m_spi_state_step++; + break; + default: + m_spilatch = m_spiptr[(m_spiaddr++) & (m_length - 1)]; + break; + } +} + +// has configurable dummy bytes? +void generic_spi_flash_device::process_read4_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); m_spi_state_step++; + break; + case 0x01: + m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); m_spi_state_step++; + break; + case 0x02: + m_spiaddr = (m_spiaddr & 0xffff00) | (data); m_spi_state_step++; + break; + case 0x03: case 0x04: case 0x05: + /* dummy */ m_spi_state_step++; + break; + default: + m_spilatch = m_spiptr[(m_spiaddr++) & (m_length - 1)]; + break; + } +} + +void generic_spi_flash_device::process_write_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); m_spi_state_step++; + break; + case 0x01: + m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); m_spi_state_step++; + break; + case 0x02: + m_spiaddr = (m_spiaddr & 0xffff00) | (data); m_spi_state_step++; + break; + default: + LOGMASKED(LOG_SPI, "Write SPI data %02x\n", data); + m_spiptr[(m_spiaddr++) & (m_length - 1)] = data; + break; + } +} + +void generic_spi_flash_device::process_sector_erase_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + m_spiaddr = (m_spiaddr & 0x00ffff) | (data << 16); m_spi_state_step++; + break; + case 0x01: + m_spiaddr = (m_spiaddr & 0xff00ff) | (data << 8); m_spi_state_step++; + break; + case 0x02: + m_spiaddr = (m_spiaddr & 0xffff00) | (data); m_spi_state_step++; + LOGMASKED(LOG_SPI, "SPI set to Erase Sector with address %08x\n", m_spiaddr); + break; + default: + LOGMASKED(LOG_SPI, "%s unexpected byte %02x when writing sector erase address\n", data); + break; + } +} + +void generic_spi_flash_device::process_status_write_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + LOGMASKED(LOG_SPI, "status write step 1\n"); + if (m_multibyte_status_write != 0) + m_spi_state_step++; else - { - m_spilatch = 0x00; - } + m_spi_state = READY_FOR_COMMAND; + break; + + case 0x01: + LOGMASKED(LOG_SPI, "status write step 2\n"); + m_spi_state = READY_FOR_COMMAND; + break; } } +void generic_spi_flash_device::process_status_read_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + LOGMASKED(LOG_SPI, "status read step 1\n"); + m_spilatch = 0x00; + if (m_multibyte_status_read != 0) + m_spi_state_step++; + else + m_spi_state = READY_FOR_COMMAND; + break; + + case 0x01: + LOGMASKED(LOG_SPI, "status read step 2\n"); + m_spilatch = 0x00; + m_spi_state = READY_FOR_COMMAND; + break; + } +} +void generic_spi_flash_device::process_status_rems_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + LOGMASKED(LOG_SPI, "REMS step 1\n"); + m_spi_state_step++; + break; + + case 0x01: + LOGMASKED(LOG_SPI, "REMS step 2\n"); + m_spi_state_step++; + break; + + case 0x02: + LOGMASKED(LOG_SPI, "REMS step 3\n"); + m_spi_state_step++; + break; + + case 0x03: + LOGMASKED(LOG_SPI, "REMS step 4\n"); + m_spi_state_step++; + break; + + case 0x04: + LOGMASKED(LOG_SPI, "REMS step 5\n"); + m_spi_state = READY_FOR_COMMAND; + break; + } +} + +void generic_spi_flash_device::process_status_rdid_command(u8 data) +{ + switch (m_spi_state_step) + { + case 0x00: + m_spilatch = m_idbytes[0]; + m_spi_state_step++; + break; + + case 0x01: + m_spilatch = m_idbytes[1]; + m_spi_state_step++; + break; + + case 0x02: + m_spilatch = m_idbytes[2]; + m_spi_state = READY_FOR_COMMAND; + break; + } +} + +void generic_spi_flash_device::write(u8 data) +{ + // not all commands have extra params/reads + switch (m_spi_state) + { + case READY_FOR_COMMAND: + get_command(data); + break; + + case COMMAND_01_WRSR: + process_status_write_command(data); + break; + + case COMMAND_02_PP: + process_write_command(data); + break; + + case COMMAND_03_READ: + process_read_command(data); + break; + + case COMMAND_05_RDSR: + process_status_read_command(data); + break; + + case COMMAND_0B_FAST_READ: + process_hsread_command(data); + break; + + case COMMAND_20_SE: + process_sector_erase_command(data); + break; + + case COMMAND_90_REMS: + process_status_rems_command(data); + break; + + case COMMAND_9F_RDID: + process_status_rdid_command(data); + break; + + case COMMAND_EB_4READ: + process_read4_command(data); + break; + } +} + void generic_spi_flash_device::nvram_default() { } diff --git a/src/devices/machine/generic_spi_flash.h b/src/devices/machine/generic_spi_flash.h index d67e04309d5..fb3ecada260 100644 --- a/src/devices/machine/generic_spi_flash.h +++ b/src/devices/machine/generic_spi_flash.h @@ -9,12 +9,12 @@ class generic_spi_flash_device : public device_t, public device_nvram_interface { public: - generic_spi_flash_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock); + generic_spi_flash_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - void set_rom_ptr(uint8_t* rom) { m_spiptr = rom; } + void set_rom_ptr(u8 *rom) { m_spiptr = rom; } void set_rom_size(size_t size) { m_length = size; } - uint8_t read() + u8 read() { return m_spilatch; } @@ -24,12 +24,10 @@ public: m_spi_state = READY_FOR_COMMAND; } - void dir_w(int state) - { - m_spidir = state; - } + void write(u8 data); - void write(uint8_t data); + void set_single_byte_status_read() { m_multibyte_status_read = 0; }; + void set_single_byte_status_writes() { m_multibyte_status_write = 0; }; protected: // device-level overrides @@ -46,36 +44,49 @@ private: { READY_FOR_COMMAND = 0x00, - READY_FOR_ADDRESS2 = 0x01, - READY_FOR_ADDRESS1 = 0x02, - READY_FOR_ADDRESS0 = 0x03, + COMMAND_01_WRSR = 0x01, + COMMAND_02_PP = 0x02, + COMMAND_03_READ = 0x03, + COMMAND_04_WRDI = 0x04, + COMMAND_05_RDSR = 0x05, + COMMAND_06_WREN = 0x06, - READY_FOR_HSADDRESS2 = 0x04, - READY_FOR_HSADDRESS1 = 0x05, - READY_FOR_HSADDRESS0 = 0x06, - READY_FOR_HSDUMMY = 0x07, + COMMAND_0B_FAST_READ = 0x0b, - READY_FOR_WRITEADDRESS2 = 0x08, - READY_FOR_WRITEADDRESS1 = 0x09, - READY_FOR_WRITEADDRESS0 = 0x0a, + COMMAND_20_SE = 0x20, - READY_FOR_SECTORERASEADDRESS2 = 0x0b, - READY_FOR_SECTORERASEADDRESS1 = 0x0c, - READY_FOR_SECTORERASEADDRESS0 = 0x0d, + COMMAND_90_REMS = 0x90, + COMMAND_9F_RDID = 0x9f, - READY_FOR_WRITE = 0x0e, + COMMAND_AB_RDP = 0xab, - READY_FOR_READ = 0x0f, - READY_FOR_STATUS_READ = 0x10, - }; + COMMAND_B9_DP = 0xb9, - uint32_t m_spiaddr; - uint8_t m_spi_state; - uint8_t m_spilatch; - bool m_spidir; + COMMAND_EB_4READ = 0xeb, + }; - uint8_t* m_spiptr; + void get_command(u8 data); + void process_hsread_command(u8 data); + void process_read_command(u8 data); + void process_read4_command(u8 data); + void process_write_command(u8 data); + void process_sector_erase_command(u8 data); + void process_status_write_command(u8 data); + void process_status_rems_command(u8 data); + void process_status_read_command(u8 data); + void process_status_rdid_command(u8 data); + + u32 m_spiaddr; + u8 m_spi_state; + u8 m_spilatch; + u8 m_spi_state_step; + + // config + u8 *m_spiptr; size_t m_length; + u8 m_multibyte_status_read; + u8 m_multibyte_status_write; + u8 m_idbytes[3]; }; DECLARE_DEVICE_TYPE(GENERIC_SPI_FLASH, generic_spi_flash_device) diff --git a/src/devices/video/st7735_lcdc.cpp b/src/devices/video/st7735_lcdc.cpp index ace39beac95..75a68e924f6 100644 --- a/src/devices/video/st7735_lcdc.cpp +++ b/src/devices/video/st7735_lcdc.cpp @@ -20,21 +20,29 @@ st7735_lcdc_device::st7735_lcdc_device(const machine_config &mconfig, const char u32 st7735_lcdc_device::render_to_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - for (int y = cliprect.min_x; y <= cliprect.max_y; y++) + bitmap.fill(0, cliprect); + + if (m_displayon) { - u32* dst = &bitmap.pix(y); + if (m_sleep) + return 0; - for (int x = cliprect.min_x; x <= cliprect.max_x; x++) + for (int y = cliprect.min_x; y <= cliprect.max_y; y++) { - int count = (y * 0x200) + x; + u32* dst = &bitmap.pix(y); + + for (int x = cliprect.min_x; x <= cliprect.max_x; x++) + { + int count = (y * 0x200) + x; - u16 dat = m_displaybuffer[(count * 2) + 1] | (m_displaybuffer[(count * 2) + 0] << 8); + u16 dat = m_displaybuffer[(count * 2) + 1] | (m_displaybuffer[(count * 2) + 0] << 8); - int b = ((dat >> 0) & 0x1f) << 3; - int g = ((dat >> 5) & 0x3f) << 2; - int r = ((dat >> 11) & 0x1f) << 3; + int b = ((dat >> 0) & 0x1f) << 3; + int g = ((dat >> 5) & 0x3f) << 2; + int r = ((dat >> 11) & 0x1f) << 3; - dst[x] = (r << 16) | (g << 8) | (b << 0); + dst[x] = (r << 16) | (g << 8) | (b << 0); + } } } @@ -47,13 +55,20 @@ void st7735_lcdc_device::lcdc_command_w(u8 data) m_command = data; m_commandstep = 0; - if (m_command == 0x11) + if (m_command == 0x10) + { + logerror("command is %02x (SLEEP IN - no params expected)\n", m_command); + m_sleep = 1; + } + else if (m_command == 0x11) { logerror("command is %02x (SLEEP OUT - no params expected)\n", m_command); + m_sleep = 0; } else if (m_command == 0x29) { logerror("command is %02x (DISPLAY ON - no params expected)\n", m_command); + m_displayon = 1; } else if (m_command == 0x2a) { @@ -125,7 +140,7 @@ void st7735_lcdc_device::lcdc_command_w(u8 data) } else { - logerror("unknown command is %02x\n", m_command); + logerror("lcdc unknown command is %02x\n", m_command); } } @@ -288,7 +303,7 @@ void st7735_lcdc_device::lcdc_data_w(u8 data) default: logerror("unexpected parameter for command %02x\n", m_command); break; } } - else if (m_command == 0xe0) // GMCTRP (Gamma +polarity Correction Characteristics) + else if (m_command == 0xe0) // GMCTRP (Gamma +polarity Correction Characteristics) { if (m_commandstep < 16) { @@ -299,7 +314,7 @@ void st7735_lcdc_device::lcdc_data_w(u8 data) logerror("unexpected parameter for command %02x\n", m_command); } } - else if (m_command == 0xe1) // GMCTRN (Gamma -polarity Correction Characteristics) + else if (m_command == 0xe1) // GMCTRN (Gamma -polarity Correction Characteristics) { if (m_commandstep < 16) { @@ -326,6 +341,8 @@ void st7735_lcdc_device::device_start() m_posmaxy = 0; m_command = 0; m_commandstep = 0; + m_displayon = 0; + m_sleep = 1; save_item(NAME(m_displaybuffer)); save_item(NAME(m_posx)); @@ -336,6 +353,8 @@ void st7735_lcdc_device::device_start() save_item(NAME(m_posmaxy)); save_item(NAME(m_command)); save_item(NAME(m_commandstep)); + save_item(NAME(m_displayon)); + save_item(NAME(m_sleep)); } void st7735_lcdc_device::device_reset() diff --git a/src/devices/video/st7735_lcdc.h b/src/devices/video/st7735_lcdc.h index f16a66376c0..1799513e3bc 100644 --- a/src/devices/video/st7735_lcdc.h +++ b/src/devices/video/st7735_lcdc.h @@ -25,13 +25,14 @@ protected: virtual void device_reset() override ATTR_COLD; private: - u8 m_displaybuffer[256 * 256 * 2]{}; - u16 m_posx = 0, m_posy = 0; - u16 m_posminx = 0, m_posmaxx = 0; - u16 m_posminy = 0, m_posmaxy = 0; - u8 m_command = 0; - u8 m_commandstep = 0; - + u8 m_displaybuffer[256 * 256 * 2]; + u16 m_posx, m_posy; + u16 m_posminx, m_posmaxx; + u16 m_posminy, m_posmaxy; + u8 m_command; + u8 m_commandstep; + u8 m_displayon; + u8 m_sleep; }; #endif // MAME_VIDEO_ST7735_LCDC_H diff --git a/src/mame/handheld/generalplus_gpce4.cpp b/src/mame/handheld/generalplus_gpce4.cpp index a52a352b5e6..33a2b882b30 100644 --- a/src/mame/handheld/generalplus_gpce4.cpp +++ b/src/mame/handheld/generalplus_gpce4.cpp @@ -29,6 +29,7 @@ #include "emu.h" #include "machine/generalplus_gpce4_soc.h" +#include "machine/generic_spi_flash.h" #include "machine/timer.h" #include "video/st7735_lcdc.h" @@ -46,7 +47,8 @@ public: driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_screen(*this, "screen"), - m_lcdc(*this, "lcdc") + m_lcdc(*this, "lcdc"), + m_genspi(*this, "spi") { } void generalplus_gpce4(machine_config &config) ATTR_COLD; @@ -59,6 +61,8 @@ protected: u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); virtual void spi_from_soc(u8 data) = 0; + void spi_rom_access_from_soc(u8 data); + void spi_reset(u8 data); void portb_from_soc(u16 data); void process_lcdc_command_params(u8 data); @@ -70,7 +74,7 @@ protected: required_device<generalplus_gpce4_soc_device> m_maincpu; required_device<screen_device> m_screen; required_device<st7735_lcdc_device> m_lcdc; - + required_device<generic_spi_flash_device> m_genspi; }; class generalplus_gpce4_mapacman_state : public generalplus_gpce4_state @@ -78,7 +82,8 @@ class generalplus_gpce4_mapacman_state : public generalplus_gpce4_state public: generalplus_gpce4_mapacman_state(const machine_config &mconfig, device_type type, const char *tag) : generalplus_gpce4_state(mconfig, type, tag) - { } + { + } virtual void spi_from_soc(u8 data) override; }; @@ -88,14 +93,15 @@ class generalplus_gpce4_digicolr_state : public generalplus_gpce4_state public: generalplus_gpce4_digicolr_state(const machine_config &mconfig, device_type type, const char *tag) : generalplus_gpce4_state(mconfig, type, tag) - { } + { + } void digicolr(machine_config &config) ATTR_COLD; virtual void spi_from_soc(u8 data) override; - ioport_value unk_r(); - private: + virtual void machine_start() override ATTR_COLD; + }; u32 generalplus_gpce4_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -275,27 +281,42 @@ static INPUT_PORTS_START( mapacman ) PORT_BIT(0xffff, IP_ACTIVE_HIGH, IPT_UNUSED ) INPUT_PORTS_END -ioport_value generalplus_gpce4_digicolr_state::unk_r() -{ - return machine().rand(); -} - static INPUT_PORTS_START( digicolr ) PORT_INCLUDE( generalplus_gpce4 ) PORT_MODIFY("PORTA") - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(FUNC(generalplus_gpce4_digicolr_state::unk_r)) // unknown, might be a button, but keeps things moving - PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) // this will also keep things moving + PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) + + PORT_MODIFY("PORTB") + PORT_DIPNAME( 0x0004, 0x0004, "Battery Charging" ) + PORT_DIPSETTING( 0x0004, "Not Charging" ) + PORT_DIPSETTING( 0x0000, "Charging") + PORT_DIPNAME( 0x0010, 0x0000, "Charger Connected" ) // if ADC is returning 0 and this is off you'll get the no battery state + PORT_DIPSETTING( 0x0010, "Yes") + PORT_DIPSETTING( 0x0000, "No" ) INPUT_PORTS_END void generalplus_gpce4_state::machine_start() { save_item(NAME(m_iob)); + + m_genspi->set_rom_ptr(memregion("spi")->base()); + m_genspi->set_rom_size(memregion("spi")->bytes()); + + m_genspi->set_single_byte_status_read(); } void generalplus_gpce4_state::machine_reset() { - m_iob = 0; + m_maincpu->set_spi_romregion(memregion("spi")->base(), memregion("spi")->bytes()); +} + +void generalplus_gpce4_digicolr_state::machine_start() +{ + generalplus_gpce4_state::machine_start(); + m_genspi->set_single_byte_status_writes(); } TIMER_DEVICE_CALLBACK_MEMBER( generalplus_gpce4_state::timer ) @@ -332,6 +353,18 @@ void generalplus_gpce4_digicolr_state::spi_from_soc(u8 data) } } +void generalplus_gpce4_state::spi_reset(u8 data) +{ + m_genspi->reset(); +} + +void generalplus_gpce4_state::spi_rom_access_from_soc(u8 data) +{ + logerror("get SPI byte from SoC %02x\n", data); + m_genspi->write(data); + m_maincpu->recieve_spi_fifo_data(m_genspi->read()); +} + void generalplus_gpce4_state::generalplus_gpce4(machine_config &config) { GPCE4(config, m_maincpu, 96000000); // internal ROM uses unsp2.0 opcodes, should be 48MHz (but unSP2.0 opcode take fewer cycles?) @@ -340,6 +373,8 @@ void generalplus_gpce4_state::generalplus_gpce4(machine_config &config) m_maincpu->portc_in().set_ioport("PORTC"); m_maincpu->portb_out().set(FUNC(generalplus_gpce4_state::portb_from_soc)); m_maincpu->spi2_out().set(FUNC(generalplus_gpce4_state::spi_from_soc)); + m_maincpu->spi_out().set(FUNC(generalplus_gpce4_state::spi_rom_access_from_soc)); + m_maincpu->spi_reset().set(FUNC(generalplus_gpce4_state::spi_reset)); SCREEN(config, m_screen, SCREEN_TYPE_LCD); m_screen->set_refresh_hz(60); @@ -351,6 +386,8 @@ void generalplus_gpce4_state::generalplus_gpce4(machine_config &config) // this triggers the SPI2 interrupt, causing pixels to be pushed to the display TIMER(config, "timer").configure_periodic(FUNC(generalplus_gpce4_state::timer), attotime::from_hz(300000)); + GENERIC_SPI_FLASH(config, m_genspi, 0); + ST7735(config, m_lcdc, 0); } @@ -362,7 +399,7 @@ void generalplus_gpce4_digicolr_state::digicolr(machine_config &config) void generalplus_gpce4_state::init_siddr() { - u8* spirom8 = (u8*)memregion("maincpu:spi")->base(); + u8* spirom8 = (u8*)memregion("spi")->base(); for (int i = 0x3000; i < 0x400000; i++) { spirom8[i] = bitswap<8>(spirom8[i] ^ 0x68, @@ -375,7 +412,7 @@ ROM_START( mapacman ) // this is the single game (no games hidden behind solder ROM_REGION16_BE( 0x18000, "maincpu:internal", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "mapacman_internal.rom", 0x000000, 0x10000, CRC(9ea69d2a) SHA1(17f5001794f4454bf5856cfa170834509d68bed0) ) - ROM_REGION16_BE( 0x800000, "maincpu:spi", ROMREGION_ERASEFF ) + ROM_REGION16_BE( 0x800000, "spi", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "fm25q16a.bin", 0x000000, 0x200000, CRC(aeb472ac) SHA1(500c24b725f6d3308ef8cbdf4259f5be556c7c92) ) ROM_END @@ -383,7 +420,7 @@ ROM_START( taspinv ) ROM_REGION16_BE( 0x18000, "maincpu:internal", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "internal.rom", 0x000000, 0x18000, NO_DUMP ) - ROM_REGION16_BE( 0x800000, "maincpu:spi", ROMREGION_ERASEFF ) + ROM_REGION16_BE( 0x800000, "spi", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "tinyarcade_spaceinvaders.bin", 0x000000, 0x200000, CRC(11ac4c77) SHA1(398d5eff83a4e94487ed810819085a0e44582908) ) ROM_END @@ -391,7 +428,7 @@ ROM_START( tagalaga ) ROM_REGION16_BE( 0x18000, "maincpu:internal", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "internal.rom", 0x000000, 0x18000, NO_DUMP ) - ROM_REGION16_BE( 0x800000, "maincpu:spi", ROMREGION_ERASEFF ) + ROM_REGION16_BE( 0x800000, "spi", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "tinyarcadegalaga_fm25q16a_a14015.bin", 0x000000, 0x200000, CRC(2a91460c) SHA1(ce297642d2d51ce568e93c0c57432446633b2077) ) ROM_END @@ -399,7 +436,7 @@ ROM_START( parcade ) ROM_REGION16_BE( 0x18000, "maincpu:internal", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "internal.rom", 0x000000, 0x18000, NO_DUMP ) - ROM_REGION16_BE( 0x800000, "maincpu:spi", ROMREGION_ERASEFF ) + ROM_REGION16_BE( 0x800000, "spi", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "palacearcade_gpr25l3203_c22016.bin", 0x000000, 0x400000, CRC(98fbd2a1) SHA1(ffc19aadd53ead1f9f3472475606941055ca09f9) ) ROM_END @@ -407,7 +444,7 @@ ROM_START( taturtf ) ROM_REGION16_BE( 0x18000, "maincpu:internal", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "internal.rom", 0x000000, 0x18000, NO_DUMP ) - ROM_REGION16_BE( 0x800000, "maincpu:spi", ROMREGION_ERASEFF ) + ROM_REGION16_BE( 0x800000, "spi", ROMREGION_ERASEFF ) ROM_LOAD16_WORD_SWAP( "tinyarcadeturtlefighter_25q32bst16_684016.bin", 0x000000, 0x400000, CRC(8e046f2d) SHA1(e48492cf953f22a47fa2b88a8f96a1e459b8c487) ) ROM_END @@ -424,18 +461,17 @@ Sound unit is a piezo disc. ROM_START( digicolr ) ROM_REGION16_BE( 0x18000, "maincpu:internal", ROMREGION_ERASEFF ) - ROM_LOAD16_WORD_SWAP( "digicolr_unsp.bin", 0x000000, 0x10000, CRC(24815b43) SHA1(d245d1e868d0357f9410cd325a3786b45a8365d2) ) + ROM_LOAD16_WORD_SWAP( "internal_rom_221017a.bin", 0x000000, 0x10000, CRC(10591b51) SHA1(78c11913e8ebd89a64b575d85bfe9b37aafb3bc0) ) - ROM_REGION16_BE( 0x800000, "maincpu:spi", ROMREGION_ERASEFF ) - ROM_LOAD16_WORD_SWAP( "mx25l6433f.u2", 0x000000, 0x800000, CRC(c515cab8) SHA1(a8b04280acae0c4db1a82ea9b46ade398e41f72b) ) - //ROM_LOAD16_WORD_SWAP( "mx25l6433f.u2", 0x000000, 0x800000, CRC(9999e2a0) SHA1(4af880e5e2bb1c820b0ec19acf1b5f858bfa1ab0) ) + ROM_REGION16_BE( 0x800000, "spi", ROMREGION_ERASEFF ) + ROM_LOAD16_WORD_SWAP( "dmc_v1_base.bin", 0x000000, 0x800000, CRC(23227806) SHA1(ebae139f708d36151efcaf2db7c329c6614d7e68) ) ROM_END ROM_START( siddr ) ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "internal.rom", 0x00000, 0x40000, NO_DUMP ) - ROM_REGION16_BE(0x800000, "maincpu:spi", ROMREGION_ERASE00) + ROM_REGION16_BE(0x800000, "spi", ROMREGION_ERASE00) ROM_LOAD16_WORD_SWAP( "ddr-toy.bin", 0x0000, 0x400000, CRC(873cbcc8) SHA1(bdd3d12adb1284991a3f8aaa8e451e3a55931267) ) ROM_END @@ -455,7 +491,8 @@ CONS( 2017, parcade, 0, 0, generalplus_gpce4, generalplus_gpc CONS( 2019, taturtf, 0, 0, generalplus_gpce4, generalplus_gpce4, generalplus_gpce4_mapacman_state, empty_init, "Super Impulse", "Teenage Mutant Ninja Turtles - Turtle Fighter (Tiny Arcade)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) -CONS( 2021, digicolr, 0, 0, digicolr, digicolr, generalplus_gpce4_digicolr_state, empty_init, "Bandai", "Digimon Color", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) +CONS( 2022, digicolr, 0, 0, digicolr, digicolr, generalplus_gpce4_digicolr_state, empty_init, "Bandai", "Digimon Color", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) // Probably not identical hardware, but still not direct mapped SPI. External ROM after 0x3000 is encrypted (maybe decrypted in software) seems to have jumps to internal ROM CONS( 2021, siddr, 0, 0, generalplus_gpce4, generalplus_gpce4, generalplus_gpce4_mapacman_state, init_siddr, "Super Impulse", "Dance Dance Revolution - Broadwalk Arcade", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) + diff --git a/src/mame/handheld/st2302u_bbl_spi.cpp b/src/mame/handheld/st2302u_bbl_spi.cpp index b826ca5e638..000569d3d89 100644 --- a/src/mame/handheld/st2302u_bbl_spi.cpp +++ b/src/mame/handheld/st2302u_bbl_spi.cpp @@ -25,12 +25,11 @@ supreme 0x243e */ -// TODO: convert to use generic_spi_flash.cpp (but there seems to be some buffering of writes / reads?) - #include "emu.h" #include "cpu/m6502/st2205u.h" #include "machine/bl_handhelds_menucontrol.h" +#include "machine/generic_spi_flash.h" #include "video/st7735_lcdc.h" #include "screen.h" @@ -51,18 +50,20 @@ public: m_io_p1(*this, "IN0"), m_io_p2(*this, "IN1"), m_menucontrol(*this, "menucontrol"), - m_lcdc(*this, "lcdc") + m_lcdc(*this, "lcdc"), + m_genspi(*this, "spi") { } - void bbl380(machine_config &config); - void bbl380_menuprot(machine_config &config); - void bbl380_24mhz(machine_config &config); + void bbl380(machine_config &config) ATTR_COLD; + void bbl380_menuprot(machine_config &config) ATTR_COLD; + void bbl380_24mhz(machine_config &config) ATTR_COLD; -private: +protected: virtual void machine_start() override ATTR_COLD; virtual void machine_reset() override ATTR_COLD; - void bbl380_do_maincpu_config(); +private: + void bbl380_do_maincpu_config() ATTR_COLD; u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); @@ -76,37 +77,34 @@ private: u8 m_output2val; - enum spistate : u8 - { - SPI_STATE_READY = 0, - SPI_STATE_WAITING_HIGH_ADDR = 1, - SPI_STATE_WAITING_MID_ADDR = 2, - SPI_STATE_WAITING_LOW_ADDR = 3, - SPI_STATE_WAITING_DUMMY1_ADDR = 4, - SPI_STATE_WAITING_DUMMY2_ADDR = 5, - SPI_STATE_READING = 6, - }; - - u8 m_spistate; - u32 m_spiaddress; - u8 m_delay; - - void spi_w(u8 data); - u8 spi_r(); + void spi10_w(u8 data); + void spi11_w(u8 data); + u8 spi10_r(); + u8 spi11_r(); + + u8 m_spi10; + u8 m_spi11; + + u8 m_spi10out; + u8 m_spi11out; + + u8 m_spi10out_has_data; required_region_ptr<u8> m_spirom; required_ioport m_io_p1; required_ioport m_io_p2; required_device<bl_handhelds_menucontrol_device> m_menucontrol; required_device<st7735_lcdc_device> m_lcdc; + required_device<generic_spi_flash_device> m_genspi; - u8 ff_r() { return 0xff; } + u8 ff_r() { logerror("%s reading from 0x14\n", machine().describe_context()); return 0xff; } }; void bbl380_state::output_w(u8 data) { - m_spistate = SPI_STATE_READY; + // probably unrelated as toumapet does it mid-read and then sends invalid commands + m_genspi->reset(); } void bbl380_state::output2_w(u8 data) @@ -133,10 +131,16 @@ void bbl380_state::machine_start() // port related save_item(NAME(m_output2val)); - // SPI related - save_item(NAME(m_spistate)); - save_item(NAME(m_spiaddress)); - save_item(NAME(m_delay)); + save_item(NAME(m_spi10)); + save_item(NAME(m_spi11)); + + save_item(NAME(m_spi10out)); + save_item(NAME(m_spi11out)); + + save_item(NAME(m_spi10out_has_data)); + + m_genspi->set_rom_ptr(memregion("spi")->base()); + m_genspi->set_rom_size(memregion("spi")->bytes()); } @@ -144,102 +148,56 @@ void bbl380_state::machine_reset() { m_output2val = 0; + m_spi10 = 0; + m_spi11 = 0; + + m_spi10out = 0; + m_spi11out = 0; + + m_spi10out_has_data = 0; + // TODO: handle these things in the core via callbacks etc. once correct behavior is agreed upon - m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0010, 0x0011, read8smo_delegate(*this, FUNC(bbl380_state::spi_r)), write8smo_delegate(*this, FUNC(bbl380_state::spi_w))); // SPI related + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0010, 0x0010, read8smo_delegate(*this, FUNC(bbl380_state::spi10_r)), write8smo_delegate(*this, FUNC(bbl380_state::spi10_w))); // SPI related + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0011, 0x0011, read8smo_delegate(*this, FUNC(bbl380_state::spi11_r)), write8smo_delegate(*this, FUNC(bbl380_state::spi11_w))); // SPI related m_maincpu->space(AS_PROGRAM).install_read_handler(0x0014, 0x0014, read8smo_delegate(*this, FUNC(bbl380_state::ff_r))); // SPI related m_maincpu->space(AS_PROGRAM).install_write_handler(0x0000, 0x0000, write8smo_delegate(*this, FUNC(bbl380_state::output_w))); // Port A output hack, SPI state needs resetting on every port write here or some gfx won't copy fully eg red squares on right of parachute, Soc implementation filters writes } - -void bbl380_state::spi_w(u8 data) +void bbl380_state::spi10_w(u8 data) { - switch (m_spistate) - { - case SPI_STATE_READY: - { - if (data == 0x03) - { - m_spistate = SPI_STATE_WAITING_HIGH_ADDR; - } - else - { - logerror("%s: invalid state request %02x\n", machine().describe_context(), data); - } - break; - } - - case SPI_STATE_WAITING_HIGH_ADDR: - { - m_spiaddress = (m_spiaddress & 0xff00ffff) | data << 16; - m_spistate = SPI_STATE_WAITING_MID_ADDR; - break; - } - - case SPI_STATE_WAITING_MID_ADDR: - { - m_spiaddress = (m_spiaddress & 0xffff00ff) | data << 8; - m_spistate = SPI_STATE_WAITING_LOW_ADDR; - break; - } + m_spi10out = data; + m_spi10out_has_data = 1; + logerror("%s: spi10_w %02x\n", machine().describe_context(), data); +} - case SPI_STATE_WAITING_LOW_ADDR: - { - m_spiaddress = (m_spiaddress & 0xffffff00) | data; - m_spistate = SPI_STATE_READING; - m_delay = 2; - break; - } +void bbl380_state::spi11_w(u8 data) +{ + m_spi11out = data; + logerror("%s: spi11_w %02x\n", machine().describe_context(), data); +} - case SPI_STATE_READING: - { - // writes when in read mode clock in data? - m_delay = 1; - break; - } +u8 bbl380_state::spi10_r() +{ + u8 ret = m_spi10; - case SPI_STATE_WAITING_DUMMY1_ADDR: + if (m_spi10out_has_data) { - m_spistate = SPI_STATE_WAITING_DUMMY2_ADDR; - break; - } + m_genspi->write(m_spi11out); + m_spi11 = m_genspi->read(); - case SPI_STATE_WAITING_DUMMY2_ADDR: - { - // m_spistate = SPI_STATE_READY; - break; + m_genspi->write(m_spi10out); + m_spi10out_has_data = 0; + m_spi10 = m_genspi->read(); } - } + logerror("%s: spi10_r returning %02x\n", machine().describe_context(), ret); + return ret; } -u8 bbl380_state::spi_r() +u8 bbl380_state::spi11_r() { - switch (m_spistate) - { - case SPI_STATE_READING: - { - if (m_delay > 0) - { - m_delay--; - return 0x00; - } - else - { - u8 dat = m_spirom[m_spiaddress & 0x3fffff]; - //logerror("%s: reading SPI %02x from SPI Address %08x\n", machine().describe_context(), dat, m_spiaddress); - m_spiaddress++; - return dat; - } - } - - default: - { - //logerror("%s: reading FIFO in unknown state\n", machine().describe_context() ); - return 0x00; - } - } - - return 0x00; + logerror("%s: spi11_r returning %02x\n", machine().describe_context(), m_spi11); + return m_spi11; } @@ -309,6 +267,8 @@ void bbl380_state::bbl380(machine_config &config) BL_HANDHELDS_MENUCONTROL(config, m_menucontrol, 0); ST7735(config, m_lcdc, 0); + GENERIC_SPI_FLASH(config, m_genspi, 0); + // LCD controller seems to be either Sitronix ST7735R or (if RDDID bytes match) Ilitek ILI9163C // (SoC's built-in LCDC is unused or nonexistent?) // Several other LCDC models are identified by ragc153 and dphh8630 @@ -513,18 +473,22 @@ CONS( 201?, supreme, 0, 0, bbl380_menuprot, bbl380_prot, bbl3 CONS( 201?, throwbck, 0, 0, bbl380_menuprot, bbl380_prot, bbl380_state, empty_init, "Westminster", "Throwback Pocket Video Game Console 150+ 8-Bit Games", MACHINE_IMPERFECT_SOUND ) -// releases with different internal ROM, these currently have rendering issues for unknown reasons +// releases with different internal ROM // for the UK market, runs at a slightly slower clock CONS( 201?, retro150, 0, 0, bbl380_24mhz, bbl380, bbl380_state, empty_init, "Red5", "Retro Arcade Game Controller (150-in-1) (set 1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) CONS( 201?, retro150a, retro150,0, bbl380_24mhz, bbl380, bbl380_state, empty_init, "Red5", "Retro Arcade Game Controller (150-in-1) (set 2)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) + // these are for the Japanese market, the ROM is the same between the Pocket Game and Game Computer but the form factor is different. +// pg118 and table108 have a screen offset issue CONS( 2019, pg118, 0, 0, bbl380_menuprot, bbl380_prot, bbl380_state, empty_init, "Pocket Game / Game Computer", "Pocket Game 118-in-1 / Game Computer 118-in-1", MACHINE_NOT_WORKING ) -CONS( 201?, ppg118, 0, 0, bbl380_menuprot, bbl380_prot, bbl380_state, empty_init, "<unknown>", "PPG Play Portable Game 118 Games (HH-0046)", MACHINE_NOT_WORKING ) CONS( 201?, table108, 0, 0, bbl380_menuprot, bbl380_prot, bbl380_state, empty_init, "<unknown>", "Table Game Classic 108-in-1 (KTFC-001B)", MACHINE_NOT_WORKING ) + +CONS( 201?, ppg118, 0, 0, bbl380_24mhz, bbl380_prot, bbl380_state, empty_init, "<unknown>", "PPG Play Portable Game 118 Games (HH-0046)", MACHINE_NOT_WORKING ) + // it is unclear if dphh8633 refers to the case style, rather than the software, as the dphh8630 set was also noted as previously being found in an 8633 unit CONS( 201?, dphh8633, 0, 0, bbl380_menuprot, bbl380_prot, bbl380_state, empty_init, "<unknown>", "Digital Pocket Hand Held System 268-in-1 - Model 8633", MACHINE_NOT_WORKING ) -CONS( 2016, dphh8661, 0, 0, bbl380_menuprot, bbl380_prot, bbl380_state, empty_init, "<unknown>", "Digital Pocket Hand Held System 268-in-1 - Model 8661", MACHINE_NOT_WORKING ) // from PCP? (logo on back of console) 2016 date on PCB +CONS( 2016, dphh8661, 0, 0, bbl380_24mhz, bbl380_prot, bbl380_state, empty_init, "<unknown>", "Digital Pocket Hand Held System 268-in-1 - Model 8661", MACHINE_NOT_WORKING ) // from PCP? (logo on back of console) 2016 date on PCB // also has the 0xE4 XOR, also doesn't currently boot, could be yet another internal ROM CONS( 2021, toumapet, 0, 0, bbl380, bbl380, bbl380_state, empty_init, "Shenzhen Shiji New Technology", "Tou ma Pet (OK-550)", MACHINE_NOT_WORKING ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 004c99b8fc9..49d37591cb2 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -36070,6 +36070,7 @@ protpp sen101 senwld silv35 +silvlt50 solargm sporzbx sporzbxa @@ -47882,6 +47883,7 @@ dreamlss drumsups epo_tetr fordrace +genitvp gssytts guitarfv guitarss @@ -48136,6 +48138,7 @@ megadri4a abl4play lexitvsprt my1stddr +my1stddrj senspid shtscore teleshi @@ -48194,6 +48197,7 @@ isinger jarajal jpopira ltv_tam +multiplt namcons1 namcons2 popira diff --git a/src/mame/misc/monon_color.cpp b/src/mame/misc/monon_color.cpp index 3ab93a882de..21d5535676d 100644 --- a/src/mame/misc/monon_color.cpp +++ b/src/mame/misc/monon_color.cpp @@ -156,11 +156,6 @@ private: return m_cart->read(); } - void spidir_w(int state) - { - m_cart->dir_w(state); - } - void spibuf_w(uint8_t data) { m_cart->write(data); @@ -944,7 +939,6 @@ void monon_color_state::monon_color(machine_config &config) m_maincpu->port_out_cb<4>().set(FUNC(monon_color_state::out4_w)); m_maincpu->spi_in_cb().set(FUNC(monon_color_state::spibuf_r)); m_maincpu->spi_out_cb().set(FUNC(monon_color_state::spibuf_w)); - m_maincpu->spi_out_dir_cb().set(FUNC(monon_color_state::spidir_w)); m_maincpu->dac_out_cb<0>().set(FUNC(monon_color_state::dacout0_w)); m_maincpu->dac_out_cb<1>().set(FUNC(monon_color_state::dacout1_w)); diff --git a/src/mame/nintendo/nes_vt02_vt03.cpp b/src/mame/nintendo/nes_vt02_vt03.cpp index 3ec59db6a80..30aa2d40d20 100644 --- a/src/mame/nintendo/nes_vt02_vt03.cpp +++ b/src/mame/nintendo/nes_vt02_vt03.cpp @@ -1292,6 +1292,11 @@ ROM_START( joysti30 ) ROM_LOAD( "joystick30.bin", 0x00000, 0x400000, CRC(b3f089af) SHA1(478d53d38eeffdbc4a1271d0e060aeb29e919502) ) ROM_END +ROM_START( silvlt50 ) + ROM_REGION( 0x800000, "mainrom", 0 ) + ROM_LOAD( "silverlit50.u2", 0x00000, 0x400000, CRC(941a3611) SHA1(a9489f0c1dcda55ef106ab213f7bfcf34fe42a41) ) +ROM_END + ROM_START( lxnoddy ) ROM_REGION( 0x200000, "mainrom", 0 ) // PCB had a ROM twice this capacity, but lower half didn't give consistent reads, and upper address line was tied to VCC, making lower half inaccessible anyway @@ -1571,6 +1576,7 @@ CONS( 2004, polmega, 0, 0, nes_vt_vh2009_4mb, nes_vt, nes_vt_swap_op_ CONS( 200?, dgun851, 0, 0, nes_vt_vh2009_4mb, nes_vt, nes_vt_swap_op_d5_d6_state, empty_init, "dreamGEAR / JungleTac", "Plug 'N' Play 30-in-1 (DGUN-851)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) CONS( 200?, dgun853, 0, 0, nes_vt_vh2009_8mb, nes_vt, nes_vt_swap_op_d5_d6_state, empty_init, "dreamGEAR / JungleTac", "Plug 'N' Play 50-in-1 (DGUN-853)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) CONS( 200?, silv35, 0, 0, nes_vt_vh2009_4mb, nes_vt, nes_vt_swap_op_d5_d6_state, empty_init, "SilverLit / JungleTac", "35 in 1 Super Twins", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +CONS( 200?, silvlt50, 0, 0, nes_vt_vh2009_4mb, nes_vt, nes_vt_swap_op_d5_d6_state, empty_init, "SilverLit / JungleTac", "50 in 1 Arcade Joystick", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) CONS( 2004, vsmaxxvd, 0, 0, nes_vt_vh2009_8mb, nes_vt, nes_vt_swap_op_d5_d6_state, empty_init, "Senario / JungleTac", "Vs Maxx Video Extreme 50-in-1 (with Speed Racer and Snood)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) CONS( 200?, vsmaxx77, 0, 0, nes_vt_vh2009_8mb, nes_vt, nes_vt_swap_op_d5_d6_state, empty_init, "Senario / JungleTac", "Vs Maxx Wireless 77-in-1", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) CONS( 200?, joysti30, 0, 0, nes_vt_vh2009_4mb, nes_vt, nes_vt_swap_op_d5_d6_state, empty_init, "WinFun / JungleTac", "Joystick 30", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) // doesn't show WinFun onscreen, but packaging does diff --git a/src/mame/tvgames/spg2xx.cpp b/src/mame/tvgames/spg2xx.cpp index 5e2ca5b4723..90b34d6f29d 100644 --- a/src/mame/tvgames/spg2xx.cpp +++ b/src/mame/tvgames/spg2xx.cpp @@ -2894,6 +2894,11 @@ ROM_START( vtechtvssp ) ROM_LOAD16_WORD_SWAP( "vtechtvstation_sp.bin", 0x000000, 0x800000, CRC(4a2e91eb) SHA1(1ff9cc0360b670cc0ad7efa9de0edd2c68d4d8e3) ) ROM_END +ROM_START( genitvp ) + ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) + ROM_LOAD16_WORD_SWAP( "vtechtvstation_fr.bin", 0x000000, 0x800000, CRC(71c2c5f4) SHA1(cc81f67ec1888b40a735383dae09408f9c877314) ) +ROM_END + ROM_START( vtechtvsgr ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) ROM_LOAD16_WORD_SWAP( "vtechtvstation_gr.bin", 0x000000, 0x800000, CRC(879f1b12) SHA1(c14d52bead2c190130ce88cbdd4f5e93145f13f9) ) @@ -3254,8 +3259,9 @@ CONS( 2007, drumsups, 0, 0, spg28x, drumsups, spg2xx_game_state, CONS( 2009, senwfit, 0, 0, gssytts, senwfit, spg2xx_game_senwfit_state, init_senwfit, "Senario", "Wireless Fitness / Dance Fit (Senario)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // VTech "TV Station" / "TV Learning Station" / "Nitro Vision" -CONS( 2006, vtechtvssp, 0, 0, spg2xx, spg2xx, spg2xx_game_state, empty_init, "VTech", "TV Station (VTech, Spain)", MACHINE_NOT_WORKING ) -CONS( 2006, vtechtvsgr, 0, 0, spg2xx, spg2xx, spg2xx_game_state, empty_init, "VTech", "TV Learning Station (VTech, Germany)", MACHINE_NOT_WORKING ) +CONS( 2006, genitvp, 0, 0, spg2xx, spg2xx, spg2xx_game_state, empty_init, "VTech", "Genius TV Progress (VTech, France)", MACHINE_NOT_WORKING ) +CONS( 2006, vtechtvssp, genitvp, 0, spg2xx, spg2xx, spg2xx_game_state, empty_init, "VTech", "TV Station (VTech, Spain)", MACHINE_NOT_WORKING ) +CONS( 2006, vtechtvsgr, genitvp, 0, spg2xx, spg2xx, spg2xx_game_state, empty_init, "VTech", "TV Learning Station (VTech, Germany)", MACHINE_NOT_WORKING ) CONS( 2007, itvphone, 0, 0, spg2xx_pal, itvphone, spg2xx_game_state, init_itvphone, "Taikee / Oregon Scientific / V-Tac Technology Co Ltd.", u8"Teléfono interactivo de TV (Spain)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS ) diff --git a/src/mame/tvgames/spg2xx_jakks_gkr.cpp b/src/mame/tvgames/spg2xx_jakks_gkr.cpp index 0ff7bbbb8b2..9bb0be5da1b 100644 --- a/src/mame/tvgames/spg2xx_jakks_gkr.cpp +++ b/src/mame/tvgames/spg2xx_jakks_gkr.cpp @@ -537,7 +537,7 @@ void jakks_gkr_state::jakks_gkr_wp(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &jakks_gkr_state::mem_map_1m); m_maincpu->adc_in<0>().set_ioport("JOYX"); m_maincpu->adc_in<2>().set_ioport("JOYY"); - //SOFTWARE_LIST(config, "jakks_gamekey_wp").set_original("jakks_gamekey_wp"); // NO KEYS RELEASED + SOFTWARE_LIST(config, "jakks_gamekey_wp").set_original("jakks_gamekey_wp"); m_maincpu->set_force_no_drc(true); // the Light Tag game seems to hang maybe once every 7 times with the DRC, appears more stable without (could just be chance tho) } diff --git a/src/mame/tvgames/trkfldch.cpp b/src/mame/tvgames/trkfldch.cpp index 1d9cb2485ef..df485328193 100644 --- a/src/mame/tvgames/trkfldch.cpp +++ b/src/mame/tvgames/trkfldch.cpp @@ -1633,6 +1633,11 @@ ROM_START( my1stddr ) ROM_LOAD( "myfirstddr.bin", 0x000000, 0x400000, CRC(2ef57bfc) SHA1(9feea5adb9de8fe17e915f3a037e8ddd70e58ae7) ) ROM_END +ROM_START( my1stddrj ) + ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 ) + ROM_LOAD( "myfirstddrjp.u2", 0x000000, 0x400000, CRC(da62d32f) SHA1(de67f3b1d4bfbf9c51c606f53d7b2958859203bc) ) +ROM_END + ROM_START( abl4play ) ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 ) ROM_LOAD( "abl4play.bin", 0x000000, 0x800000, CRC(5d57fb70) SHA1(34cdf80dc8cb08e5cd98c724268e4c5f483780d7) ) @@ -1747,6 +1752,7 @@ CONS( 2007, trkfldch, 0, 0, trkfldch, trkfldch,trkfldch_state, e CONS( 2007, trkfldchj, trkfldch, 0, trkfldch, trkfldch,trkfldch_state, empty_init, "Konami", "Hashire! Tobe! Nagero! Hyper Sports Challenge (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) CONS( 2006, my1stddr, 0, 0, trkfldch, my1stddr,trkfldch_state, empty_init, "Konami", "My First Dance Dance Revolution (US)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // Japan version has different songs +CONS( 2006, my1stddrj, my1stddr, 0, trkfldch, my1stddr,trkfldch_state, empty_init, "Konami", "My First Dance Dance Revolution (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // Japan version has different songs CONS( 200?, abl4play, 0, 0, trkfldch, abl4play,trkfldch_state, empty_init, "Advance Bright Ltd", "4 Player System - 10 in 1", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/tvgames/xavix.cpp b/src/mame/tvgames/xavix.cpp index c5524063be7..99ecb307f32 100644 --- a/src/mame/tvgames/xavix.cpp +++ b/src/mame/tvgames/xavix.cpp @@ -1468,6 +1468,25 @@ static INPUT_PORTS_START( jarajal ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) INPUT_PORTS_END +static INPUT_PORTS_START( multiplt ) + PORT_INCLUDE(xavix) + + PORT_MODIFY("IN0") + // TODO: steering inputs appear to use multiple bits + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) // DOWN + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) // UP + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Horn") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON5 ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON6 ) // holding this keeps wheel in center + + PORT_MODIFY("IN1") + PORT_DIPNAME( 0x02, 0x02, "Output Mode" ) + PORT_DIPSETTING( 0x00, "Audio Only") + PORT_DIPSETTING( 0x02, "TV Output") +INPUT_PORTS_END + + static INPUT_PORTS_START( tcarnavi ) PORT_INCLUDE(xavix) @@ -2662,6 +2681,11 @@ ROM_START( hippofr ) ROM_LOAD( "54-6447-010.u3", 0x000000, 0x200000, CRC(1fb15364) SHA1(ff2bb54f7d6ccd3c83e722599c6f2b213bf35df8) ) ROM_END +ROM_START( multiplt ) + ROM_REGION( 0x200000, "bios", ROMREGION_ERASE00 ) + ROM_LOAD( "2en1multipilotefr.u2", 0x000000, 0x200000, CRC(77f2ebf6) SHA1(0181bc7d3b6ea5a4a247ffe02fee2cb4942c1623) ) +ROM_END + /* XaviX hardware titles (1st Generation) These use @@ -2679,7 +2703,9 @@ ROM_END // Also exists as // 80-32703 Hippo's Alphabet Adventure (UK) // 80-32700 ABC Jungle Fun (US?) -CONS( 1999, hippofr, 0, 0, xavix_2mb, xavix,xavix_state, init_xavix, "VTech", "Hippo: et la formidable aventure des lettres (France)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // needs keyboard emulating +CONS( 1999, hippofr, 0, 0, xavix_2mb, xavix,xavix_state, init_xavix, "VTech", "2 en 1 Hippo: et la formidable aventure des lettres (France)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // needs keyboard emulating + +CONS( 1999?, multiplt, 0, 0, xavix_2mb, multiplt,xavix_state, init_xavix, "VTech", "2 en 1 Multi'Pilote (France)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // Let's!TVプレイCLASSIC タイトーノスタルジア1 CONS( 2006, taitons1, 0, 0, xavix_i2c_24lc04_2mb, nostalgia,xavix_i2c_state, init_xavix, "Bandai / SSD Company LTD / Taito", "Let's! TV Play Classic - Taito Nostalgia 1 (Japan)", MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/tvgames/xavix_v.cpp b/src/mame/tvgames/xavix_v.cpp index cdcafb5014e..fd52b597eee 100644 --- a/src/mame/tvgames/xavix_v.cpp +++ b/src/mame/tvgames/xavix_v.cpp @@ -975,12 +975,29 @@ void xavix_state::draw_tilemap_line(screen_device &screen, bitmap_rgb32 &bitmap, // Addressing Mode 2 (plus Inline Header) //if (debug_packets) LOG("for tile %04x (at %d %d): ", tile, (((x * 16) + scrollx) & 0xff), (((y * 16) + scrolly) & 0xff)); + if (tileregs[0x7] == 0x94) + { + // multiplt uses this for the '3d' driving sections + const offs_t realaddress = (tileregs[0x2] << 8) + count; + uint8_t extraattr; + + if (m_disable_memory_bypass) + extraattr = m_maincpu->space(AS_PROGRAM).read_byte(realaddress); + else + extraattr = read_full_data_sp_bypass(realaddress); - basereg = (tile & 0xf000) >> 12; - tile &= 0x0fff; - gfxbase = (m_segment_regs[(basereg * 2) + 1] << 16) | (m_segment_regs[(basereg * 2)] << 8); + tile += extraattr << 16; + } + else // tileregs[0x7] == 0x93 + { + // rad_mtrk uses this + basereg = (tile & 0xf000) >> 12; + tile &= 0x0fff; + gfxbase = (m_segment_regs[(basereg * 2) + 1] << 16) | (m_segment_regs[(basereg * 2)] << 8); + + tile += gfxbase; + } - tile += gfxbase; set_data_address(tile, 0); decode_inline_header(flipx, flipy, test, pal, debug_packets); |
