From 150bfa4650a8af22c8c3278cf78c73ef2489b81e Mon Sep 17 00:00:00 2001 From: 987123879113 <63495610+987123879113@users.noreply.github.com> Date: Thu, 17 Nov 2022 08:11:05 +0900 Subject: hornet: Replace JVS impl with jvs_host device (#10559) --- src/mame/konami/hornet.cpp | 231 +++++++++++++++++++------------------------ src/mame/konami/k573mcal.cpp | 6 +- 2 files changed, 106 insertions(+), 131 deletions(-) diff --git a/src/mame/konami/hornet.cpp b/src/mame/konami/hornet.cpp index 9adf5f28570..0ff19724601 100644 --- a/src/mame/konami/hornet.cpp +++ b/src/mame/konami/hornet.cpp @@ -355,6 +355,8 @@ Jumpers set on GFX PCB to scope monitor: #include "machine/adc1213x.h" #include "machine/ds2401.h" #include "machine/eepromser.h" +#include "machine/jvsdev.h" +#include "machine/jvshost.h" #include "machine/k033906.h" #include "konami_gn676_lan.h" #include "konppc.h" @@ -371,6 +373,64 @@ Jumpers set on GFX PCB to scope monitor: #include "layout/generic.h" +DECLARE_DEVICE_TYPE(HORNET_JVS_HOST, hornet_jvs_host) + +class hornet_jvs_host : public jvs_host +{ +public: + // construction/destruction + hornet_jvs_host(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + void read(); + void write(uint8_t *data, int length); + + DECLARE_READ_LINE_MEMBER( sense ); + + auto output_callback() { return output_cb.bind(); } + +protected: + virtual void device_start() override; + +private: + devcb_write8 output_cb; +}; + +DEFINE_DEVICE_TYPE(HORNET_JVS_HOST, hornet_jvs_host, "hornet_jvs_host", "JVS Host (Hornet)") + +hornet_jvs_host::hornet_jvs_host(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : jvs_host(mconfig, HORNET_JVS_HOST, tag, owner, clock), + output_cb(*this) +{ +} + +void hornet_jvs_host::device_start() +{ + jvs_host::device_start(); + output_cb.resolve_safe(); +} + +READ_LINE_MEMBER( hornet_jvs_host::sense ) +{ + return !get_address_set_line(); +} + +void hornet_jvs_host::read() +{ + const uint8_t *data; + uint32_t length; + + get_encoded_reply(data, length); + + for (int i = 0; i < length; i++) + output_cb(data[i]); +} + +void hornet_jvs_host::write(uint8_t *data, int length) +{ + for (int i = 0; i < length; i++) + push(data[i]); + commit_raw(); +} + namespace { class hornet_state : public driver_device @@ -399,6 +459,7 @@ public: m_comm_bank(*this, "comm_bank"), m_lan_ds2401(*this, "lan_serial_id"), m_watchdog(*this, "watchdog"), + m_hornet_jvs_host(*this, "hornet_jvs_host"), m_cg_view(*this, "cg_view") { } @@ -422,6 +483,7 @@ protected: private: // TODO: Needs verification on real hardware static const int m_sound_timer_usec = 2800; + static constexpr int JVS_BUFFER_SIZE = 1024; required_shared_ptr m_workram; optional_shared_ptr_array m_sharc_dataram; @@ -444,11 +506,14 @@ private: optional_memory_bank m_comm_bank; optional_device m_lan_ds2401; required_device m_watchdog; + required_device m_hornet_jvs_host; memory_view m_cg_view; emu_timer *m_sound_irq_timer; std::unique_ptr m_jvs_sdata; uint32_t m_jvs_sdata_ptr; + bool m_jvs_is_escape_byte; + uint16_t m_gn680_latch; uint16_t m_gn680_ret0; uint16_t m_gn680_ret1; @@ -474,9 +539,6 @@ private: template uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); TIMER_CALLBACK_MEMBER(sound_irq); - int jvs_encode_data(uint8_t *in, int length); - int jvs_decode_data(uint8_t *in, uint8_t *out, int length); - void jamma_jvs_cmd_exec(); void hornet_map(address_map &map); void hornet_lan_map(address_map &map); void terabrst_map(address_map &map); @@ -527,7 +589,8 @@ uint8_t hornet_state::sysreg_r(offs_t offset) 0x02 = ADDOR (ADC DOR) 0x01 = ADDO (ADC DO) */ - r = 0xf0; + r = 0x70; + r |= m_hornet_jvs_host->sense() << 7; r |= m_adc12138->do_r() | (m_adc12138->eoc_r() << 2); break; @@ -559,7 +622,7 @@ void hornet_state::sysreg_w(offs_t offset, uint8_t data) 0x80 = EEPWEN (EEPROM write enable) 0x40 = EEPCS (EEPROM CS) 0x20 = EEPSCL (EEPROM SCL?) - 0x10 = EEPDT (EEPROM data) + 0x10 = EEPDT (EEPROM data) / JVSTXEN (for Gradius 4) 0x08 = JVSTXEN / LAMP3 (something about JAMMA interface) 0x04 = LAMP2 0x02 = LAMP1 @@ -1056,7 +1119,8 @@ void hornet_state::machine_start() m_pcb_digit.resolve(); m_jvs_sdata_ptr = 0; - m_jvs_sdata = make_unique_clear(1024); + m_jvs_sdata = make_unique_clear(JVS_BUFFER_SIZE); + m_jvs_is_escape_byte = false; // set conservative DRC options m_maincpu->ppcdrc_set_options(PPCDRC_COMPATIBLE_OPTIONS); @@ -1064,8 +1128,9 @@ void hornet_state::machine_start() // configure fast RAM regions for DRC m_maincpu->ppcdrc_add_fastram(0x00000000, 0x003fffff, false, m_workram); - save_pointer(NAME(m_jvs_sdata), 1024); + save_pointer(NAME(m_jvs_sdata), JVS_BUFFER_SIZE); save_item(NAME(m_jvs_sdata_ptr)); + save_item(NAME(m_jvs_is_escape_byte)); m_sound_irq_timer = timer_alloc(FUNC(hornet_state::sound_irq), this); } @@ -1088,6 +1153,9 @@ void hornet_state::machine_reset() if (membank("slave_cgboard_bank")) membank("slave_cgboard_bank")->set_base(memregion("master_cgboard")->base()); } + + m_jvs_sdata_ptr = 0; + m_jvs_is_escape_byte = false; } double hornet_state::adc12138_input_callback(uint8_t input) @@ -1162,6 +1230,11 @@ void hornet_state::hornet(machine_config &config) KONPPC(config, m_konppc, 0); m_konppc->set_num_boards(1); m_konppc->set_cbboard_type(konppc_device::CGBOARD_TYPE_HORNET); + + HORNET_JVS_HOST(config, m_hornet_jvs_host, 0); + m_hornet_jvs_host->output_callback().set([this](uint8_t c) { + m_maincpu->ppc4xx_spu_receive_byte(c); + }); } void hornet_state::hornet_lan(machine_config &config) @@ -1280,138 +1353,36 @@ void hornet_state::sscope2_voodoo1(machine_config& config) void hornet_state::jamma_jvs_w(uint8_t data) { - if (m_jvs_sdata_ptr == 0 && data != 0xe0) - return; - m_jvs_sdata[m_jvs_sdata_ptr] = data; - m_jvs_sdata_ptr++; - - if (m_jvs_sdata_ptr >= 3 && m_jvs_sdata_ptr >= 3 + m_jvs_sdata[2]) - jamma_jvs_cmd_exec(); -} - -int hornet_state::jvs_encode_data(uint8_t *in, int length) -{ - int inptr = 0; - int sum = 0; - - while (inptr < length) - { - uint8_t b = in[inptr++]; - if (b == 0xe0) - { - sum += 0xd0 + 0xdf; - m_maincpu->ppc4xx_spu_receive_byte(0xd0); - m_maincpu->ppc4xx_spu_receive_byte(0xdf); - } - else if (b == 0xd0) - { - sum += 0xd0 + 0xcf; - m_maincpu->ppc4xx_spu_receive_byte(0xd0); - m_maincpu->ppc4xx_spu_receive_byte(0xcf); - } - else - { - sum += b; - m_maincpu->ppc4xx_spu_receive_byte(b); - } - } - return sum; -} - -int hornet_state::jvs_decode_data(uint8_t *in, uint8_t *out, int length) -{ - int outptr = 0; - int inptr = 0; - - while (inptr < length) - { - uint8_t b = in[inptr++]; - if (b == 0xd0) - { - uint8_t b2 = in[inptr++]; - out[outptr++] = b2 + 1; - } - else - { - out[outptr++] = b; - } - }; + bool is_escape_byte = m_jvs_is_escape_byte; + m_jvs_is_escape_byte = false; - return outptr; -} + // Throw away the buffer and wait for the next sync marker instead of overflowing when + // a invalid packet is filling the entire buffer. + if (m_jvs_sdata_ptr >= JVS_BUFFER_SIZE) + m_jvs_sdata_ptr = 0; -void hornet_state::jamma_jvs_cmd_exec() -{ - uint8_t byte_num; - uint8_t data[1024], rdata[1024]; -#if 0 - int length; -#endif - int rdata_ptr; - int sum; - -// sync = m_jvs_sdata[0]; -// node = m_jvs_sdata[1]; - byte_num = m_jvs_sdata[2]; - -#if 0 - length = -#endif - jvs_decode_data(&m_jvs_sdata[3], data, byte_num-1); -#if 0 - printf("jvs input data:\n"); - for (i=0; i < byte_num; i++) - { - printf("%02X ", m_jvs_sdata[3+i]); - } - printf("\n"); + if (m_jvs_sdata_ptr == 0 && data != 0xe0) + return; - printf("jvs data decoded to:\n"); - for (i=0; i < length; i++) + if (m_jvs_sdata_ptr > 0 && data == 0xd0) { - printf("%02X ", data[i]); + m_jvs_is_escape_byte = true; + return; } - printf("\n\n"); -#endif - - // clear return data - memset(rdata, 0, sizeof(rdata)); - rdata_ptr = 0; - // status - rdata[rdata_ptr++] = 0x01; // normal + m_jvs_sdata[m_jvs_sdata_ptr++] = is_escape_byte ? data + 1 : data; - // handle the command - switch (data[0]) // TODO: thrilldbu trips case 0x01 + const bool is_complete_packet = m_jvs_sdata_ptr >= 5 + && m_jvs_sdata_ptr == m_jvs_sdata[2] + 3 + && m_jvs_sdata[0] == 0xe0 + && m_jvs_sdata[1] != 0x00 + && m_jvs_sdata[m_jvs_sdata_ptr - 1] == (std::accumulate(&m_jvs_sdata[1], &m_jvs_sdata[m_jvs_sdata_ptr - 1], 0) & 0xff); + if (is_complete_packet) { - case 0xf0: // Reset - { - break; - } - case 0xf1: // Address setting - { - rdata[rdata_ptr++] = 0x01; // report data (normal) - break; - } - case 0xfa: - { - break; - } - default: - { - logerror("jamma_jvs_cmd_exec: unknown command %02X\n", data[0]); - } + m_hornet_jvs_host->write(&m_jvs_sdata[1], m_jvs_sdata_ptr - 2); + m_hornet_jvs_host->read(); + m_jvs_sdata_ptr = 0; } - - // write jvs return data - sum = 0x00 + (rdata_ptr+1); - m_maincpu->ppc4xx_spu_receive_byte(0xe0); // sync - m_maincpu->ppc4xx_spu_receive_byte(0x00); // node - m_maincpu->ppc4xx_spu_receive_byte(rdata_ptr + 1); // num of bytes - sum += jvs_encode_data(rdata, rdata_ptr); - m_maincpu->ppc4xx_spu_receive_byte(sum - 1); // checksum - - m_jvs_sdata_ptr = 0; } /*****************************************************************************/ diff --git a/src/mame/konami/k573mcal.cpp b/src/mame/konami/k573mcal.cpp index 097e80e66fe..3947c574cf8 100644 --- a/src/mame/konami/k573mcal.cpp +++ b/src/mame/konami/k573mcal.cpp @@ -104,8 +104,12 @@ int k573mcal_device::handle_message(const uint8_t* send_buffer, uint32_t send_si } case 0x71: { - // msg: 71 ff ff 01 + // msg: 71 00 00 80 -> Offset = 0x0000, requested size = 0x80 bytes + // msg: 71 00 20 10 -> Offset = 0x0020, requested size = 0x10 bytes + // "Master Calendar ROM". Contents are specific to the game being initialized. + // Only encountered and tested on Hornet games. + // msg: 71 ff ff 01 -> Offset = 0xffff, requested size = 0x01 bytes, special request for the area specification flag? Used by Sys573 uint8_t resp[] = { 0x01, // status, must be 1 uint8_t(m_in1->read() & 0x0f), // Area specification -- cgit v1.2.3