hornet: Replace JVS impl with jvs_host device (#10559)

This commit is contained in:
987123879113 2022-11-17 08:11:05 +09:00 committed by GitHub
parent f6bb8eb828
commit 150bfa4650
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 108 additions and 133 deletions

View File

@ -355,6 +355,8 @@ Jumpers set on GFX PCB to scope monitor:
#include "machine/adc1213x.h" #include "machine/adc1213x.h"
#include "machine/ds2401.h" #include "machine/ds2401.h"
#include "machine/eepromser.h" #include "machine/eepromser.h"
#include "machine/jvsdev.h"
#include "machine/jvshost.h"
#include "machine/k033906.h" #include "machine/k033906.h"
#include "konami_gn676_lan.h" #include "konami_gn676_lan.h"
#include "konppc.h" #include "konppc.h"
@ -371,6 +373,64 @@ Jumpers set on GFX PCB to scope monitor:
#include "layout/generic.h" #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 { namespace {
class hornet_state : public driver_device class hornet_state : public driver_device
@ -399,6 +459,7 @@ public:
m_comm_bank(*this, "comm_bank"), m_comm_bank(*this, "comm_bank"),
m_lan_ds2401(*this, "lan_serial_id"), m_lan_ds2401(*this, "lan_serial_id"),
m_watchdog(*this, "watchdog"), m_watchdog(*this, "watchdog"),
m_hornet_jvs_host(*this, "hornet_jvs_host"),
m_cg_view(*this, "cg_view") m_cg_view(*this, "cg_view")
{ } { }
@ -422,6 +483,7 @@ protected:
private: private:
// TODO: Needs verification on real hardware // TODO: Needs verification on real hardware
static const int m_sound_timer_usec = 2800; static const int m_sound_timer_usec = 2800;
static constexpr int JVS_BUFFER_SIZE = 1024;
required_shared_ptr<uint32_t> m_workram; required_shared_ptr<uint32_t> m_workram;
optional_shared_ptr_array<uint32_t, 2> m_sharc_dataram; optional_shared_ptr_array<uint32_t, 2> m_sharc_dataram;
@ -444,11 +506,14 @@ private:
optional_memory_bank m_comm_bank; optional_memory_bank m_comm_bank;
optional_device<ds2401_device> m_lan_ds2401; optional_device<ds2401_device> m_lan_ds2401;
required_device<watchdog_timer_device> m_watchdog; required_device<watchdog_timer_device> m_watchdog;
required_device<hornet_jvs_host> m_hornet_jvs_host;
memory_view m_cg_view; memory_view m_cg_view;
emu_timer *m_sound_irq_timer; emu_timer *m_sound_irq_timer;
std::unique_ptr<uint8_t[]> m_jvs_sdata; std::unique_ptr<uint8_t[]> m_jvs_sdata;
uint32_t m_jvs_sdata_ptr; uint32_t m_jvs_sdata_ptr;
bool m_jvs_is_escape_byte;
uint16_t m_gn680_latch; uint16_t m_gn680_latch;
uint16_t m_gn680_ret0; uint16_t m_gn680_ret0;
uint16_t m_gn680_ret1; uint16_t m_gn680_ret1;
@ -474,9 +539,6 @@ private:
template <uint8_t Which> uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); template <uint8_t Which> uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(sound_irq); 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_map(address_map &map);
void hornet_lan_map(address_map &map); void hornet_lan_map(address_map &map);
void terabrst_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) 0x02 = ADDOR (ADC DOR)
0x01 = ADDO (ADC DO) 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); r |= m_adc12138->do_r() | (m_adc12138->eoc_r() << 2);
break; break;
@ -559,7 +622,7 @@ void hornet_state::sysreg_w(offs_t offset, uint8_t data)
0x80 = EEPWEN (EEPROM write enable) 0x80 = EEPWEN (EEPROM write enable)
0x40 = EEPCS (EEPROM CS) 0x40 = EEPCS (EEPROM CS)
0x20 = EEPSCL (EEPROM SCL?) 0x20 = EEPSCL (EEPROM SCL?)
0x10 = EEPDT (EEPROM data) 0x10 = EEPDT (EEPROM data) / JVSTXEN (for Gradius 4)
0x08 = JVSTXEN / LAMP3 (something about JAMMA interface) 0x08 = JVSTXEN / LAMP3 (something about JAMMA interface)
0x04 = LAMP2 0x04 = LAMP2
0x02 = LAMP1 0x02 = LAMP1
@ -1056,7 +1119,8 @@ void hornet_state::machine_start()
m_pcb_digit.resolve(); m_pcb_digit.resolve();
m_jvs_sdata_ptr = 0; m_jvs_sdata_ptr = 0;
m_jvs_sdata = make_unique_clear<uint8_t[]>(1024); m_jvs_sdata = make_unique_clear<uint8_t[]>(JVS_BUFFER_SIZE);
m_jvs_is_escape_byte = false;
// set conservative DRC options // set conservative DRC options
m_maincpu->ppcdrc_set_options(PPCDRC_COMPATIBLE_OPTIONS); m_maincpu->ppcdrc_set_options(PPCDRC_COMPATIBLE_OPTIONS);
@ -1064,8 +1128,9 @@ void hornet_state::machine_start()
// configure fast RAM regions for DRC // configure fast RAM regions for DRC
m_maincpu->ppcdrc_add_fastram(0x00000000, 0x003fffff, false, m_workram); 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_sdata_ptr));
save_item(NAME(m_jvs_is_escape_byte));
m_sound_irq_timer = timer_alloc(FUNC(hornet_state::sound_irq), this); 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")) if (membank("slave_cgboard_bank"))
membank("slave_cgboard_bank")->set_base(memregion("master_cgboard")->base()); 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) 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); KONPPC(config, m_konppc, 0);
m_konppc->set_num_boards(1); m_konppc->set_num_boards(1);
m_konppc->set_cbboard_type(konppc_device::CGBOARD_TYPE_HORNET); 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) void hornet_state::hornet_lan(machine_config &config)
@ -1280,139 +1353,37 @@ void hornet_state::sscope2_voodoo1(machine_config& config)
void hornet_state::jamma_jvs_w(uint8_t data) void hornet_state::jamma_jvs_w(uint8_t data)
{ {
bool is_escape_byte = m_jvs_is_escape_byte;
m_jvs_is_escape_byte = false;
// 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;
if (m_jvs_sdata_ptr == 0 && data != 0xe0) if (m_jvs_sdata_ptr == 0 && data != 0xe0)
return; 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]) if (m_jvs_sdata_ptr > 0 && data == 0xd0)
jamma_jvs_cmd_exec(); {
m_jvs_is_escape_byte = true;
return;
} }
int hornet_state::jvs_encode_data(uint8_t *in, int length) m_jvs_sdata[m_jvs_sdata_ptr++] = is_escape_byte ? data + 1 : data;
{
int inptr = 0;
int sum = 0;
while (inptr < length) 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)
{ {
uint8_t b = in[inptr++]; m_hornet_jvs_host->write(&m_jvs_sdata[1], m_jvs_sdata_ptr - 2);
if (b == 0xe0) m_hornet_jvs_host->read();
{
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;
}
};
return outptr;
}
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");
printf("jvs data decoded to:\n");
for (i=0; i < length; i++)
{
printf("%02X ", data[i]);
}
printf("\n\n");
#endif
// clear return data
memset(rdata, 0, sizeof(rdata));
rdata_ptr = 0;
// status
rdata[rdata_ptr++] = 0x01; // normal
// handle the command
switch (data[0]) // TODO: thrilldbu trips case 0x01
{
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]);
}
}
// 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; m_jvs_sdata_ptr = 0;
} }
}
/*****************************************************************************/ /*****************************************************************************/

View File

@ -104,8 +104,12 @@ int k573mcal_device::handle_message(const uint8_t* send_buffer, uint32_t send_si
} }
case 0x71: { 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[] = { uint8_t resp[] = {
0x01, // status, must be 1 0x01, // status, must be 1
uint8_t(m_in1->read() & 0x0f), // Area specification uint8_t(m_in1->read() & 0x0f), // Area specification