From 0eebfe12ff7cc1cfccc8272b7d7abe7501217740 Mon Sep 17 00:00:00 2001 From: Risugami <@> Date: Tue, 23 Aug 2016 17:19:07 -0500 Subject: [PATCH 1/3] Finished implementing the Galil command communication. Still don't know what should be getting sent however. --- src/mame/drivers/midvunit.cpp | 37 +++++++++++++++++++++++++++-------- src/mame/includes/midvunit.h | 7 ++++++- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/mame/drivers/midvunit.cpp b/src/mame/drivers/midvunit.cpp index bfeb35578bc..66ba5a9b04f 100644 --- a/src/mame/drivers/midvunit.cpp +++ b/src/mame/drivers/midvunit.cpp @@ -56,6 +56,7 @@ void midvunit_state::machine_start() save_item(NAME(m_shifter_state)); save_item(NAME(m_timer_rate)); save_item(NAME(m_output_mode)); + save_item(NAME(m_output)); } @@ -375,9 +376,21 @@ WRITE32_MEMBER(midvunit_state::offroadc_serial_data_w) READ32_MEMBER(midvunit_state::midvunit_output_r) { //need 0x8000 to allow reading of the following: - //0x4700, 0x5100, 0x5300, 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00 (ascii maybe?) + //0x4700, 0x5100, 0x5300, 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00 + + //G + //V$## -> Expects value of 6, if not checks FCAC for 2 and sets it? + //X$## -> Stored at FD12 + //Y$## -> Stored at FD13 + //Z$## -> Stored at FD14 + + //Floating point operation. No further inputs given. Goes to same place as G when done. + //W -> BE36 + //S -> BE37 + //Q -> BE38 + //will softlock the game if it remains 0x8000 as that is not one of the expected branches - return 0; + return m_output; } WRITE32_MEMBER(midvunit_state::midvunit_output_w) @@ -389,19 +402,27 @@ WRITE32_MEMBER(midvunit_state::midvunit_output_w) case 0xF7: m_output_mode = arg; break; case 0xFB: switch (m_output_mode) { - case 0x00: break; //device init? 3C 1C are the only 2 writes at boot. + case 0x00: + m_galil_input[0] = 'G'; + m_galil_input_index = 0; + m_galil_input_length = 1; + m_galil_output_index = 0; + memset(m_galil_output, 0, 256); + break; //device init? 3C 1C are the only 2 writes at boot. case 0x04: output().set_value("wheel", (arg&0x80)?(0x7F-(arg&0x7F)):(arg|0x80)); break; //wheel motor delta. left < 128 < right. 128 is no change. case 0x05: for (bit = 0; bit < 8; bit++) output().set_lamp_value(bit, (arg >> bit) & 0x1); break; - case 0x08: break; //called when motion controller reads a 0x8000 from midvunit_output_r and wants a response. + case 0x08: m_output = m_galil_input[m_galil_input_index++] << 8; break; //get next character from input string. case 0x09: if (arg != 0xD) - m_galil_cmd += (char)arg; + m_galil_output[(m_galil_output_index < 255) ? m_galil_output_index++ : m_galil_output_index] = (char)arg; else { - osd_printf_error("Galil: %s\n", m_galil_cmd.c_str()); - m_galil_cmd.clear(); + osd_printf_error("Galil: %s\n", m_galil_output); + m_galil_input_index = 0; + m_galil_output_index = 0; + memset(m_galil_output, 0, 256); } break; //Galil command input. ascii inputs terminated with carriage return. - case 0x0A: break; //write 0 to request response. wants to read 0x8000 after? + case 0x0A: m_output = (m_galil_input_index < m_galil_input_length) ? 0x8000 : 0x0; break; //set output to 0x8000 if there is data available, otherwise 0. case 0x0B: break; //0 written at boot. case 0x0C: break; //0 written at boot. } diff --git a/src/mame/includes/midvunit.h b/src/mame/includes/midvunit.h index d0d15427468..c84c6c5eaca 100644 --- a/src/mame/includes/midvunit.h +++ b/src/mame/includes/midvunit.h @@ -96,8 +96,13 @@ public: UINT8 m_video_changed; emu_timer *m_scanline_timer; std::unique_ptr m_poly; + UINT8 m_galil_input_index; + UINT8 m_galil_input_length; + char m_galil_input[256]; + UINT8 m_galil_output_index; + char m_galil_output[256]; + UINT32 m_output; UINT8 m_output_mode; - std::string m_galil_cmd; DECLARE_WRITE32_MEMBER(midvunit_dma_queue_w); DECLARE_READ32_MEMBER(midvunit_dma_queue_entries_r); DECLARE_READ32_MEMBER(midvunit_dma_trigger_r); From 1219cb3fb27055198e77a8dff13ea4442d433db7 Mon Sep 17 00:00:00 2001 From: Risugami <@> Date: Wed, 24 Aug 2016 02:48:13 -0500 Subject: [PATCH 2/3] Know everything the Galil console interface will send and receive. Faking one of the commands for now. Still not enough to make it work so there is yet another port at use somewhere. --- src/mame/drivers/midvunit.cpp | 31 +++++++++++++++++-------------- src/mame/includes/midvunit.h | 2 +- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/mame/drivers/midvunit.cpp b/src/mame/drivers/midvunit.cpp index 66ba5a9b04f..d3621399f34 100644 --- a/src/mame/drivers/midvunit.cpp +++ b/src/mame/drivers/midvunit.cpp @@ -375,21 +375,17 @@ WRITE32_MEMBER(midvunit_state::offroadc_serial_data_w) READ32_MEMBER(midvunit_state::midvunit_output_r) { - //need 0x8000 to allow reading of the following: - //0x4700, 0x5100, 0x5300, 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00 - - //G - //V$## -> Expects value of 6, if not checks FCAC for 2 and sets it? - //X$## -> Stored at FD12 - //Y$## -> Stored at FD13 - //Z$## -> Stored at FD14 + //G -> MG "G" + //V$## -> #IBO;IBO=_SCX|_SCY|_SCZ;MG "V" IBO {$2.0} + //X$## -> MG "X", _TSX {$2.0} + //Y$## -> MG "Y", _TSY {$2.0} + //Z$## -> MG "Z", _TSZ {$2.0} //Floating point operation. No further inputs given. Goes to same place as G when done. - //W -> BE36 - //S -> BE37 - //Q -> BE38 + //W -> MG "W" + //S -> MG "S" + //Q -> MG "Q" - //will softlock the game if it remains 0x8000 as that is not one of the expected branches return m_output; } @@ -403,7 +399,7 @@ WRITE32_MEMBER(midvunit_state::midvunit_output_w) case 0xFB: switch (m_output_mode) { case 0x00: - m_galil_input[0] = 'G'; + m_galil_input = ":"; m_galil_input_index = 0; m_galil_input_length = 1; m_galil_output_index = 0; @@ -416,9 +412,16 @@ WRITE32_MEMBER(midvunit_state::midvunit_output_w) if (arg != 0xD) m_galil_output[(m_galil_output_index < 255) ? m_galil_output_index++ : m_galil_output_index] = (char)arg; else { - osd_printf_error("Galil: %s\n", m_galil_output); m_galil_input_index = 0; m_galil_output_index = 0; + if (strstr(m_galil_output,"MG \"V\" IBO {$2.0}")) { + m_galil_input = "V$00"; + m_galil_input_length = 4; + } else { + m_galil_input = ":"; + m_galil_input_length = 1; + } + osd_printf_error("Galil << %s\nGalil >> %s\n", m_galil_output, m_galil_input); memset(m_galil_output, 0, 256); } break; //Galil command input. ascii inputs terminated with carriage return. diff --git a/src/mame/includes/midvunit.h b/src/mame/includes/midvunit.h index c84c6c5eaca..39e970c2fa8 100644 --- a/src/mame/includes/midvunit.h +++ b/src/mame/includes/midvunit.h @@ -98,7 +98,7 @@ public: std::unique_ptr m_poly; UINT8 m_galil_input_index; UINT8 m_galil_input_length; - char m_galil_input[256]; + const char *m_galil_input; UINT8 m_galil_output_index; char m_galil_output[256]; UINT32 m_output; From f5b4df5a7b56ed125aef0ca566abeb5503236a07 Mon Sep 17 00:00:00 2001 From: Risugami <@> Date: Wed, 24 Aug 2016 10:36:43 -0500 Subject: [PATCH 3/3] Finished implementing motion controller. Motion test will succeed and everything sent to motion controller goes to stdout. Could rewrite the whole system to be a real one, but that's for another time. --- src/mame/drivers/midvunit.cpp | 80 ++++++++++++++++++++++------------- src/mame/includes/midvunit.h | 3 +- 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/mame/drivers/midvunit.cpp b/src/mame/drivers/midvunit.cpp index d3621399f34..190145f4fde 100644 --- a/src/mame/drivers/midvunit.cpp +++ b/src/mame/drivers/midvunit.cpp @@ -35,6 +35,7 @@ Known to exist but not dumped: #include "machine/nvram.h" #include "includes/midvunit.h" #include "crusnusa.lh" +#include #define CPU_CLOCK 50000000 @@ -375,20 +376,15 @@ WRITE32_MEMBER(midvunit_state::offroadc_serial_data_w) READ32_MEMBER(midvunit_state::midvunit_output_r) { - //G -> MG "G" - //V$## -> #IBO;IBO=_SCX|_SCY|_SCZ;MG "V" IBO {$2.0} - //X$## -> MG "X", _TSX {$2.0} - //Y$## -> MG "Y", _TSY {$2.0} - //Z$## -> MG "Z", _TSZ {$2.0} - - //Floating point operation. No further inputs given. Goes to same place as G when done. - //W -> MG "W" - //S -> MG "S" - //Q -> MG "Q" - return m_output; } +void midvunit_state::set_input(const char *s) { + m_galil_input = s; + m_galil_input_index = 0; + m_galil_input_length = strlen(s); +} + WRITE32_MEMBER(midvunit_state::midvunit_output_w) { int bit; @@ -399,35 +395,54 @@ WRITE32_MEMBER(midvunit_state::midvunit_output_w) case 0xFB: switch (m_output_mode) { case 0x00: - m_galil_input = ":"; - m_galil_input_index = 0; - m_galil_input_length = 1; + set_input(":"); m_galil_output_index = 0; - memset(m_galil_output, 0, 256); + memset(m_galil_output, 0, 450); break; //device init? 3C 1C are the only 2 writes at boot. case 0x04: output().set_value("wheel", (arg&0x80)?(0x7F-(arg&0x7F)):(arg|0x80)); break; //wheel motor delta. left < 128 < right. 128 is no change. case 0x05: for (bit = 0; bit < 8; bit++) output().set_lamp_value(bit, (arg >> bit) & 0x1); break; case 0x08: m_output = m_galil_input[m_galil_input_index++] << 8; break; //get next character from input string. case 0x09: - if (arg != 0xD) - m_galil_output[(m_galil_output_index < 255) ? m_galil_output_index++ : m_galil_output_index] = (char)arg; + if (arg != 0xD) { + m_galil_output[m_galil_output_index] = (char)arg; + if (m_galil_output_index < 450) + m_galil_output_index++; + } else { - m_galil_input_index = 0; + // G, W, S, and Q are commented out because they are error commands. + // When the motion tests succeeds it will send the program over to + // the motion controller and as this is not a real system it will + // assume it wants to execute them which turns off the motion system. + // If anyone wishes to implement a real Galil motion controller feel + // free to do so. This will only dump everything to stdout. + if (strstr(m_galil_output,"MG \"V\" IBO {$2.0}")) + set_input("V$00"); + else if (strstr(m_galil_output,"MG \"X\", _TSX {$2.0}")) + set_input("X$00"); + else if (strstr(m_galil_output,"MG \"Y\", _TSY {$2.0}")) + set_input("Y$00"); + else if (strstr(m_galil_output,"MG \"Z\", _TSZ {$2.0}")) + set_input("Z$00"); + /*else if (strstr(m_galil_output,"MG \"G\"")) + set_input("G"); + else if (strstr(m_galil_output,"MG \"W\"")) + set_input("W"); + else if (strstr(m_galil_output,"MG \"S\"")) + set_input("S"); + else if (strstr(m_galil_output,"MG \"Q\"")) + set_input("Q");*/ + else + set_input(":"); + std::cout << m_galil_output << std::endl; + //osd_printf_error("Galil << %s\n", m_galil_output); + memset(m_galil_output, 0, m_galil_output_index); m_galil_output_index = 0; - if (strstr(m_galil_output,"MG \"V\" IBO {$2.0}")) { - m_galil_input = "V$00"; - m_galil_input_length = 4; - } else { - m_galil_input = ":"; - m_galil_input_length = 1; - } - osd_printf_error("Galil << %s\nGalil >> %s\n", m_galil_output, m_galil_input); - memset(m_galil_output, 0, 256); } break; //Galil command input. ascii inputs terminated with carriage return. case 0x0A: m_output = (m_galil_input_index < m_galil_input_length) ? 0x8000 : 0x0; break; //set output to 0x8000 if there is data available, otherwise 0. case 0x0B: break; //0 written at boot. case 0x0C: break; //0 written at boot. + case 0x0E: break; //0 written after test. } break; //receives same data as midvunit_sound_w. unsure what its purpose is, but it is redundant. @@ -617,8 +632,15 @@ static INPUT_PORTS_START( crusnusa ) PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("View 1") /* view 1 */ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON9 ) PORT_NAME("View 2") /* view 2 */ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON10 ) PORT_NAME("View 3") /* view 3 */ - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON11 ) PORT_NAME("View 4") /* view 4 */ - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Motion Stop") + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Right Mat") + PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Rear Mat") + PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Left Mat") + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Front Mat") + PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Mat Plugin") + PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Mat Step") + PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Opto Detector") + PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_NAME("Failsafe Switch") PORT_START("DSW") /* DSW2 at U97 */ diff --git a/src/mame/includes/midvunit.h b/src/mame/includes/midvunit.h index 39e970c2fa8..fa06a050f63 100644 --- a/src/mame/includes/midvunit.h +++ b/src/mame/includes/midvunit.h @@ -100,7 +100,7 @@ public: UINT8 m_galil_input_length; const char *m_galil_input; UINT8 m_galil_output_index; - char m_galil_output[256]; + char m_galil_output[450]; UINT32 m_output; UINT8 m_output_mode; DECLARE_WRITE32_MEMBER(midvunit_dma_queue_w); @@ -146,6 +146,7 @@ public: DECLARE_DRIVER_INIT(wargods); DECLARE_DRIVER_INIT(offroadc); DECLARE_DRIVER_INIT(crusnusa); + void set_input(const char *s); void init_crusnwld_common(offs_t speedup); void init_crusnusa_common(offs_t speedup); virtual void machine_start() override;