mirror of
https://github.com/holub/mame
synced 2025-05-29 17:13:05 +03:00
hornet: Replace JVS impl with jvs_host device (#10559)
This commit is contained in:
parent
f6bb8eb828
commit
150bfa4650
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user