summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author David Haywood <28625134+DavidHaywood@users.noreply.github.com>2020-09-21 18:17:25 +0100
committer GitHub <noreply@github.com>2020-09-21 13:17:25 -0400
commit04672777eb9cb388d37150d2be4db25ae71b6ca3 (patch)
tree853aa0565e7869e2ee1788f7004980eb02cac610
parent85cbd20517a127845fea795ec0b3330aae33ea0a (diff)
pcp8718 / pcp8728 / bkid218 - make menu controller a shared device (#7270)
-rw-r--r--scripts/src/machine.lua11
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/machine/bl_handhelds_menucontrol.cpp214
-rw-r--r--src/devices/machine/bl_handhelds_menucontrol.h64
-rw-r--r--src/mame/drivers/generalplus_gpl_unknown.cpp190
5 files changed, 304 insertions, 176 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index 600c22f2746..ac3cf2b31a1 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -4546,3 +4546,14 @@ if (MACHINES["ALPHA_8921"]~=null) then
MAME_DIR .. "src/devices/machine/alpha_8921.h",
}
end
+
+---------------------------------------------------
+--
+--@src/devices/machine/bl_handhelds_menucontrol.h,MACHINES["BL_HANDHELDS_MENUCONTROL"] = true
+---------------------------------------------------
+if (MACHINES["BL_HANDHELDS_MENUCONTROL"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/bl_handhelds_menucontrol.cpp",
+ MAME_DIR .. "src/devices/machine/bl_handhelds_menucontrol.h",
+ }
+end
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index d4c33c727dd..a2040f202aa 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -779,6 +779,7 @@ MACHINES["XC1700E"] = true
MACHINES["EDLC"] = true
MACHINES["WTL3132"] = true
MACHINES["CXD1185"] = true
+MACHINES["BL_HANDHELDS_MENUCONTROL"] = true
--------------------------------------------------
-- specify available bus cores
diff --git a/src/devices/machine/bl_handhelds_menucontrol.cpp b/src/devices/machine/bl_handhelds_menucontrol.cpp
new file mode 100644
index 00000000000..305f90ecfce
--- /dev/null
+++ b/src/devices/machine/bl_handhelds_menucontrol.cpp
@@ -0,0 +1,214 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+// Menu controller, stores / increments menu position etc. used on handhelds that typically have BL on the boot screen (BaoBaoLong?)
+
+#include "emu.h"
+#include "machine/bl_handhelds_menucontrol.h"
+
+DEFINE_DEVICE_TYPE(BL_HANDHELDS_MENUCONTROL, bl_handhelds_menucontrol_device, "blhandheldmenu", "BaoBaoLong Handhelds Menu Controller")
+
+bl_handhelds_menucontrol_device::bl_handhelds_menucontrol_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, BL_HANDHELDS_MENUCONTROL, tag, owner, clock),
+ m_is_unsp_type_hack(false)
+{
+}
+
+READ_LINE_MEMBER(bl_handhelds_menucontrol_device::status_r)
+{
+ return m_clockstate;
+}
+
+READ_LINE_MEMBER(bl_handhelds_menucontrol_device::data_r)
+{
+ return m_responsebit;
+}
+
+// is there some 'carry' related behavior on the add / remove, because sometimes calculations are off by 1 eg command 0x05 (subtract) subcommand 0xf0
+// edge cases to test - moving up and left off entry 0, moving next / previous page when on any entry on the first/last pages, moving down/right off last entry, crossing 255/256 game boundary
+void bl_handhelds_menucontrol_device::handle_command()
+{
+ uint8_t command = m_command;
+
+ // additions and subtractions here are likely also meant to be done as high byte and low byte
+ if (m_menustate == MENU_READY_FOR_COMMAND)
+ {
+ if (command == 0x00)
+ {
+ m_menustate = MENU_COMMAND_00_IN;
+ m_response = m_menupos & 0xff;
+ }
+ else if (command == 0x01)
+ {
+ m_menustate = MENU_COMMAND_01_IN;
+ m_response = (m_menupos >> 8) & 0xff;
+ }
+ else if (command == 0x02)
+ {
+ m_menustate = MENU_COMMAND_02_IN;
+ }
+ else if (command == 0x03)
+ {
+ m_menustate = MENU_COMMAND_03_IN;
+ }
+ else if (command == 0x04)
+ {
+ m_menustate = MENU_COMMAND_04_IN;
+ }
+ else if (command == 0x05)
+ {
+ m_menustate = MENU_COMMAND_05_IN;
+ }
+ else if (command == 0x09)
+ {
+ // ...
+ }
+ else if ((command) == 0x10)
+ {
+ // this is followed by 0x1b, written if you try to move right off last entry
+ m_menupos = 0x00;
+ }
+ else if (command == 0x30)
+ {
+ m_menupos++;
+ }
+ else if (command == 0x37)
+ {
+ m_menupos--;
+ }
+ else if (command == 0x39)
+ {
+ m_menupos -= 4;
+ }
+ else if (command == 0x2c)
+ {
+ m_menupos = 0x01;
+ }
+ else
+ {
+ logerror("handle_command %02x (unknown)\n", command);
+ }
+ }
+ else if (m_menustate == MENU_COMMAND_00_IN)
+ {
+ m_menustate = MENU_READY_FOR_COMMAND;
+ }
+ else if (m_menustate == MENU_COMMAND_01_IN)
+ {
+ m_menustate = MENU_READY_FOR_COMMAND;
+ }
+ else if (m_menustate == MENU_COMMAND_02_IN)
+ {
+ m_menupos = (m_menupos & 0xff00) | ((command - 0x8) & 0xff);
+ m_menustate = MENU_READY_FOR_COMMAND;
+ }
+ else if (m_menustate == MENU_COMMAND_03_IN)
+ {
+ m_menupos = (m_menupos & 0x00ff) | (((command - 0x9) & 0xff) << 8);
+ m_menustate = MENU_READY_FOR_COMMAND;
+ }
+ else if (m_menustate == MENU_COMMAND_04_IN)
+ {
+ // used if you try to scroll up or left past 0 and the value becomes too large (a negative number)
+ if (m_is_unsp_type_hack)
+ {
+ if (command == 0x0d)
+ m_menupos += 4;
+ else if (command == 0x0a)
+ m_menupos += 0;
+ // used if you try to scroll up or left past 0 and the value becomes too large (a negative number)
+ // actually writes 0x314 split into 2 commands, so the 2nd write to 0x04 with param then instead 0b/16 sequence of writes instead of 26/0c adds to the high byte?
+ else if (command == 0x1e)
+ m_menupos += 0x310;
+ }
+ else
+ {
+ m_menupos += (command - 0x09);
+ m_menustate = MENU_READY_FOR_COMMAND;
+ }
+
+ m_menustate = MENU_READY_FOR_COMMAND;
+ }
+ else if (m_menustate == MENU_COMMAND_05_IN)
+ {
+ // used if you try to scroll down past the and the value becomes too large
+ if (m_is_unsp_type_hack)
+ {
+ // actually writes 0x313 split into 2 commands, so the 2nd write to 0x05 with param then instead 0b/16 sequence of writes instead of 26/0c subtracts from the high byte?
+ if (command == 0x0b)
+ {
+ m_menupos -= 0xdc;
+ }
+ else if (command == 0x0e)
+ {
+ m_menupos -= 0x314;
+ }
+ }
+ else
+ {
+ if (command != 0xf0)
+ m_menupos -= (command - 0x0b);
+ else
+ m_menupos -= (command - 0x0a); // dphh8630 when pressing 'right' on final menu page
+ }
+
+ m_menustate = MENU_READY_FOR_COMMAND;
+ }
+}
+
+WRITE_LINE_MEMBER(bl_handhelds_menucontrol_device::clock_w)
+{
+ if (state)
+ {
+ m_clockstate = 1;
+ }
+ else
+ {
+ m_clockstate = 0;
+ m_command <<= 1;
+ m_command |= ((m_commandbit));
+ m_responsebit = (m_response >> (7 - m_datashifterpos)) & 1;
+ m_datashifterpos++;
+
+ if (m_datashifterpos == 8)
+ {
+ m_datashifterpos = 0;
+ handle_command();
+ }
+ }
+}
+
+WRITE_LINE_MEMBER(bl_handhelds_menucontrol_device::data_w)
+{
+ m_commandbit = state;
+}
+
+WRITE_LINE_MEMBER(bl_handhelds_menucontrol_device::reset_w)
+{
+ m_datashifterpos = 0;
+}
+
+void bl_handhelds_menucontrol_device::device_start()
+{
+ m_responsebit = 0;
+ m_clockstate = 0;
+ m_command = 0;
+ m_datashifterpos = 0;
+ m_menupos = 0;
+ m_response = 0;
+ m_commandbit = 0;
+ m_menustate = MENU_READY_FOR_COMMAND;
+
+ save_item(NAME(m_menupos));
+ save_item(NAME(m_clockstate));
+ save_item(NAME(m_datashifterpos));
+ save_item(NAME(m_responsebit));
+ save_item(NAME(m_response));
+ save_item(NAME(m_commandbit));
+ save_item(NAME(m_command));
+ //save_item(NAME(m_menustate));
+}
+
+void bl_handhelds_menucontrol_device::device_reset()
+{
+}
diff --git a/src/devices/machine/bl_handhelds_menucontrol.h b/src/devices/machine/bl_handhelds_menucontrol.h
new file mode 100644
index 00000000000..bb3d68677c9
--- /dev/null
+++ b/src/devices/machine/bl_handhelds_menucontrol.h
@@ -0,0 +1,64 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#ifndef MAME_MACHINE_BL_HANDHELDS_MENUCONTROL_H
+#define MAME_MACHINE_BL_HANDHELDS_MENUCONTROL_H
+
+#pragma once
+
+DECLARE_DEVICE_TYPE(BL_HANDHELDS_MENUCONTROL, bl_handhelds_menucontrol_device)
+
+class bl_handhelds_menucontrol_device : public device_t
+{
+public:
+ // construction/destruction
+ bl_handhelds_menucontrol_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // the chip is the same between systems, but there's some logic not fully understood that is causing off-by-1 errors on some calcs
+ void set_is_unsp_type_hack() { m_is_unsp_type_hack = true; }
+
+ DECLARE_READ_LINE_MEMBER(status_r);
+ DECLARE_READ_LINE_MEMBER(data_r);
+ DECLARE_WRITE_LINE_MEMBER(clock_w);
+ DECLARE_WRITE_LINE_MEMBER(data_w);
+ DECLARE_WRITE_LINE_MEMBER(reset_w);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ // config
+ bool m_is_unsp_type_hack;
+
+ // internal state
+ int m_menupos;
+
+ // command handling
+ int m_clockstate;
+ int m_datashifterpos;
+
+ int m_responsebit;
+ uint8_t m_response;
+
+ int m_commandbit;
+ uint8_t m_command;
+
+ void handle_command();
+
+ enum menustate : const int
+ {
+ MENU_READY_FOR_COMMAND = 0,
+
+ MENU_COMMAND_00_IN,
+ MENU_COMMAND_01_IN,
+ MENU_COMMAND_02_IN,
+ MENU_COMMAND_03_IN,
+ MENU_COMMAND_04_IN,
+ MENU_COMMAND_05_IN,
+ };
+
+ menustate m_menustate;
+};
+
+#endif // MAME_MACHINE_BL_HANDHELDS_MENUCONTROL_H
diff --git a/src/mame/drivers/generalplus_gpl_unknown.cpp b/src/mame/drivers/generalplus_gpl_unknown.cpp
index a64260644e2..fffce35facb 100644
--- a/src/mame/drivers/generalplus_gpl_unknown.cpp
+++ b/src/mame/drivers/generalplus_gpl_unknown.cpp
@@ -22,12 +22,12 @@
#include "emu.h"
#include "cpu/unsp/unsp.h"
+#include "machine/bl_handhelds_menucontrol.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
-
#define LOG_GPL162XX_LCDTYPE (1U << 1)
#define LOG_GPL162XX_LCDTYPE_SELECT_SIM (1U << 2)
#define LOG_GPL162XX_LCDTYPE_IO_PORT (1U << 3)
@@ -50,14 +50,12 @@ public:
m_screen(*this, "screen"),
m_spirom(*this, "spi"),
m_io_in0(*this, "IN0"),
- m_io_in1(*this, "IN1")
+ m_io_in1(*this, "IN1"),
+ m_menucontrol(*this, "menucontrol")
{ }
void gpl162xx_lcdtype(machine_config &config);
- DECLARE_READ_LINE_MEMBER(bit08state_r);
- DECLARE_READ_LINE_MEMBER(latchinbit_r);
-
private:
virtual void machine_start() override;
virtual void machine_reset() override;
@@ -170,33 +168,9 @@ private:
uint16_t io_7870_r();
required_ioport m_io_in0;
required_ioport m_io_in1;
+ required_device<bl_handhelds_menucontrol_device> m_menucontrol;
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
-
-
- int m_latchinbit;
- void tx_menu_cmd(uint8_t command);
-
- int m_bit08state;
- int m_latchdata;
-
- int m_latchpos;
- int m_menupos;
- uint8_t m_datain;
-
- enum menustate : const int
- {
- MENU_READY_FOR_COMMAND = 0,
-
- MENU_COMMAND_00_IN,
- MENU_COMMAND_01_IN,
- MENU_COMMAND_02_IN,
- MENU_COMMAND_03_IN,
- MENU_COMMAND_04_IN,
- MENU_COMMAND_05_IN,
- };
-
- menustate m_menustate;
};
uint32_t gpl162xx_lcdtype_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@@ -208,7 +182,7 @@ uint32_t gpl162xx_lcdtype_state::screen_update(screen_device &screen, bitmap_rgb
for (int x = 0; x < 320; x++)
{
- // 8-bit values get pumped through a 256 word table in intenral ROM and converted to words, so it's probably raw 16-bit RGB data?
+ // 8-bit values get pumped through a 256 word table in internal ROM and converted to words
uint16_t dat = m_displaybuffer[(count * 2) + 1] | (m_displaybuffer[(count * 2) + 0] << 8);
int b = ((dat >> 0) & 0x1f) << 3;
@@ -224,18 +198,6 @@ uint32_t gpl162xx_lcdtype_state::screen_update(screen_device &screen, bitmap_rgb
}
-
-READ_LINE_MEMBER( gpl162xx_lcdtype_state::bit08state_r )
-{
- return m_bit08state;
-}
-
-READ_LINE_MEMBER( gpl162xx_lcdtype_state::latchinbit_r )
-{
- return m_latchinbit;
-}
-
-
static INPUT_PORTS_START( gpl162xx_lcdtype )
PORT_START("IN0")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED ) // causes lag if state is inverted, investigate
@@ -245,8 +207,8 @@ static INPUT_PORTS_START( gpl162xx_lcdtype )
PORT_DIPNAME( 0x0004, 0x0000, "Show Vs in Test Mode" )
PORT_DIPSETTING( 0x0000, "0000" )
PORT_DIPSETTING( 0x0004, "0004" )
- PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(gpl162xx_lcdtype_state, bit08state_r)
- PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(gpl162xx_lcdtype_state, latchinbit_r)
+ PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("menucontrol", bl_handhelds_menucontrol_device, status_r)
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("menucontrol", bl_handhelds_menucontrol_device, data_r)
PORT_DIPNAME( 0x0020, 0x0020, "P0:0020" )
PORT_DIPSETTING( 0x0000, "0000" )
PORT_DIPSETTING( 0x0020, "0020" )
@@ -326,136 +288,10 @@ uint16_t gpl162xx_lcdtype_state::io_7860_r()
return ret;
}
-// TODO: make this a device, the unk6502_st2xxx.cpp units use the same thing
-void gpl162xx_lcdtype_state::tx_menu_cmd(uint8_t command)
-{
- // additions and subtractions here are likely also meant to be done as high byte and low byte
- if (m_menustate == MENU_READY_FOR_COMMAND)
- {
- if (command == 0x00)
- {
- m_menustate = MENU_COMMAND_00_IN;
- m_datain = m_menupos & 0xff;
- }
- else if (command == 0x01)
- {
- m_menustate = MENU_COMMAND_01_IN;
- m_datain = (m_menupos >> 8) & 0xff;
- }
- else if (command == 0x02)
- {
- m_menustate = MENU_COMMAND_02_IN;
- }
- else if (command == 0x03)
- {
- m_menustate = MENU_COMMAND_03_IN;
- }
- else if (command == 0x04)
- {
- m_menustate = MENU_COMMAND_04_IN;
- }
- else if (command == 0x05)
- {
- m_menustate = MENU_COMMAND_05_IN;
- }
- else if (command == 0x09)
- {
- // ...
- }
- else if ((command) == 0x10)
- {
- // this is followed by 0x1b, written if you try to move right off last entry
- m_menupos = 0x00;
- }
- else if (command == 0x30)
- {
- m_menupos++;
- }
- else if (command == 0x37)
- {
- m_menupos--;
- }
- else if (command == 0x39)
- {
- m_menupos -= 4;
- }
- else if (command == 0x2c)
- {
- m_menupos = 0x01;
- }
- else
- {
- LOGMASKED(LOG_GPL162XX_LCDTYPE_SELECT_SIM, "tx_menu_cmd %02x (unknown)\n", command);
- }
- }
- else if (m_menustate == MENU_COMMAND_00_IN)
- {
- m_menustate = MENU_READY_FOR_COMMAND;
- }
- else if (m_menustate == MENU_COMMAND_01_IN)
- {
- m_menustate = MENU_READY_FOR_COMMAND;
- }
- else if (m_menustate == MENU_COMMAND_02_IN)
- {
- m_menupos = (m_menupos & 0xff00) | ((command - 0x8) & 0xff);
- m_menustate = MENU_READY_FOR_COMMAND;
- }
- else if (m_menustate == MENU_COMMAND_03_IN)
- {
- m_menupos = (m_menupos & 0x00ff) | (((command - 0x9) & 0xff) << 8);
- m_menustate = MENU_READY_FOR_COMMAND;
- }
- else if (m_menustate == MENU_COMMAND_04_IN)
- {
- if (command == 0x0d)
- m_menupos += 4;
- else if (command == 0x0a)
- m_menupos += 0;
- // used if you try to scroll up or left past 0 and the value becomes too large (a negative number)
- // actually writes 0x314 split into 2 commands, so the 2nd write to 0x04 with param then instead 0b/16 sequence of writes instead of 26/0c adds to the high byte?
- else if (command == 0x1e)
- m_menupos += 0x310;
-
- m_menustate = MENU_READY_FOR_COMMAND;
- }
- else if (m_menustate == MENU_COMMAND_05_IN)
- {
- // used if you try to scroll down past the and the value becomes too large
- // actually writes 0x313 split into 2 commands, so the 2nd write to 0x05 with param then instead 0b/16 sequence of writes instead of 26/0c subtracts from the high byte?
- if (command == 0x0b)
- {
- m_menupos -= 0xdc;
- }
- else if (command == 0x0e)
- {
- m_menupos -= 0x314;
- }
-
- m_menustate = MENU_READY_FOR_COMMAND;
- }
-}
-
void gpl162xx_lcdtype_state::io_7860_w(uint16_t data)
{
- if (data & 0x20)
- {
- m_bit08state = 1;
- }
- else
- {
- m_bit08state = 0;
- m_latchdata <<= 1;
- m_latchdata |= ((data & 0x10) >> 4);
- m_latchinbit = (m_datain >> (7 - m_latchpos)) & 1;
- m_latchpos++;
-
- if (m_latchpos == 8)
- {
- m_latchpos = 0;
- tx_menu_cmd(m_latchdata);
- }
- }
+ m_menucontrol->data_w((data & 0x10)>>4);
+ m_menucontrol->clock_w((data & 0x20)>>5);
m_7860 = data;
}
@@ -469,7 +305,7 @@ void gpl162xx_lcdtype_state::unk_7863_w(uint16_t data)
// probably port direction (or 7862 is?)
if (data == 0x3cf7)
{
- m_latchpos = 0;
+ m_menucontrol->reset_w(1);
}
}
@@ -979,8 +815,6 @@ void gpl162xx_lcdtype_state::machine_reset()
// first menu index is stored here
// m_spirom[0x16000] = gamenum & 0xff;
// m_spirom[0x16001] = (gamenum>>8) & 0xff;
-
- m_menupos = 0;
}
WRITE_LINE_MEMBER(gpl162xx_lcdtype_state::screen_vblank)
@@ -1012,6 +846,10 @@ void gpl162xx_lcdtype_state::gpl162xx_lcdtype(machine_config &config)
m_screen->screen_vblank().set(FUNC(gpl162xx_lcdtype_state::screen_vblank));
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x8000);
+
+ BL_HANDHELDS_MENUCONTROL(config, m_menucontrol, 0);
+ m_menucontrol->set_is_unsp_type_hack();
+
}
// pcp8718 and pcp8728 both contain user data (player name?) and will need to be factory defaulted once they work