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/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<uint32_t> m_workram;
optional_shared_ptr_array<uint32_t, 2> m_sharc_dataram;
@ -444,11 +506,14 @@ private:
optional_memory_bank m_comm_bank;
optional_device<ds2401_device> m_lan_ds2401;
required_device<watchdog_timer_device> m_watchdog;
required_device<hornet_jvs_host> m_hornet_jvs_host;
memory_view m_cg_view;
emu_timer *m_sound_irq_timer;
std::unique_ptr<uint8_t[]> 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 <uint8_t Which> 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<uint8_t[]>(1024);
m_jvs_sdata = make_unique_clear<uint8_t[]>(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,139 +1353,37 @@ void hornet_state::sscope2_voodoo1(machine_config& config)
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)
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();
if (m_jvs_sdata_ptr > 0 && data == 0xd0)
{
m_jvs_is_escape_byte = true;
return;
}
int hornet_state::jvs_encode_data(uint8_t *in, int length)
{
int inptr = 0;
int sum = 0;
m_jvs_sdata[m_jvs_sdata_ptr++] = is_escape_byte ? data + 1 : data;
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++];
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;
}
};
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_hornet_jvs_host->write(&m_jvs_sdata[1], m_jvs_sdata_ptr - 2);
m_hornet_jvs_host->read();
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: {
// 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