diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 82245dc559a..24e85d8f3d3 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -4104,6 +4104,8 @@ files { MAME_DIR .. "src/mame/drivers/titan_soc.cpp", MAME_DIR .. "src/mame/drivers/st22xx_bbl338.cpp", MAME_DIR .. "src/mame/drivers/unk6502_st2xxx.cpp", + MAME_DIR .. "src/mame/video/bl_handhelds_lcdc.cpp", + MAME_DIR .. "src/mame/video/bl_handhelds_lcdc.h", MAME_DIR .. "src/mame/drivers/actions_atj2279b.cpp", MAME_DIR .. "src/mame/drivers/pubint_storyreader.cpp", MAME_DIR .. "src/mame/drivers/magiceyes_pollux_vr3520f.cpp", diff --git a/src/mame/drivers/st22xx_bbl338.cpp b/src/mame/drivers/st22xx_bbl338.cpp index 1a0959aa0e9..28680e110f7 100644 --- a/src/mame/drivers/st22xx_bbl338.cpp +++ b/src/mame/drivers/st22xx_bbl338.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "cpu/m6502/st2205u.h" +#include "video/bl_handhelds_lcdc.h" #include "screen.h" class st22xx_bbl338_state : public driver_device @@ -12,6 +13,7 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_screen(*this, "screen") + , m_lcdc(*this, "lcdc") { } @@ -22,36 +24,69 @@ private: required_device m_maincpu; required_device m_screen; + required_device m_lcdc; u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); }; + void st22xx_bbl338_state::st22xx_bbl338_map(address_map &map) { map(0x000000, 0x1fffff).rom().region("maincpu", 0); + + map(0x600000, 0x600000).w(m_lcdc, FUNC(bl_handhelds_lcdc_device::lcdc_command_w)); + map(0x604000, 0x604000).rw(m_lcdc, FUNC(bl_handhelds_lcdc_device::lcdc_data_r), FUNC(bl_handhelds_lcdc_device::lcdc_data_w)); +} + +u32 st22xx_bbl338_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return m_lcdc->render_to_bitmap(screen, bitmap, cliprect); } static INPUT_PORTS_START(st22xx_bbl338) + PORT_START("IN0") // not confirmed, but probably similar to other units + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) // maybe ON/OFF + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("SOUND") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("B") + + PORT_START("IN1") // not confirmed, but probably similar to other units + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("A") + PORT_BIT(0x06, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("IN2") + PORT_CONFNAME( 0x01, 0x01, DEF_STR( Language ) ) + PORT_CONFSETTING( 0x00, "Chinese" ) + PORT_CONFSETTING( 0x01, "English" ) + PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED) // probably unused INPUT_PORTS_END -u32 st22xx_bbl338_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - return 0; -} - - void st22xx_bbl338_state::st22xx_bbl338(machine_config &config) { ST2302U(config, m_maincpu, 12000000); // likely higher clock m_maincpu->set_addrmap(AS_DATA, &st22xx_bbl338_state::st22xx_bbl338_map); + m_maincpu->in_pa_callback().set_ioport("IN0"); + m_maincpu->in_pb_callback().set_ioport("IN1"); + m_maincpu->in_pc_callback().set_ioport("IN2"); + // incorrect for bbl338 SCREEN(config, m_screen, SCREEN_TYPE_LCD); m_screen->set_refresh_hz(60); m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0)); - m_screen->set_size(160, 128); // incorrect + m_screen->set_size(160, 128); m_screen->set_visarea(0, 160 - 1, 0, 128 - 1); m_screen->set_screen_update(FUNC(st22xx_bbl338_state::screen_update)); + + // incorrect for bbl338 (or will need changes to support higher resolutions) + BL_HANDHELDS_LCDC(config, m_lcdc, 0); } ROM_START( bbl338 ) @@ -63,17 +98,13 @@ ROM_START( bbl338 ) ROM_LOAD( "en29lv160ab.u1", 0x000000, 0x200000, CRC(2c73e16c) SHA1(e2c69b3534e32ef384c0c2f5618118a419326e3a) ) ROM_END - ROM_START( dphh8213 ) ROM_REGION( 0x200000, "maincpu", 0 ) ROM_LOAD( "mx29lv160cb.u1", 0x000000, 0x200000, CRC(c8e7e355) SHA1(726f28c2c9ab012a6842f9f30a0a71538741ba14) ) ROM_END - - - // this is uses a higher resolution display than the common units, but not as high as the SunPlus based ones COMP( 201?, bbl338, 0, 0, st22xx_bbl338, st22xx_bbl338, st22xx_bbl338_state, empty_init, "BaoBaoLong", "Portable Game Player BBL-338 (BaoBaoLong, 48-in-1)", MACHINE_IS_SKELETON ) -// Chinese menus only, low resolution -COMP( 201?, dphh8213, 0, 0, st22xx_bbl338, st22xx_bbl338, st22xx_bbl338_state, empty_init, "", "Digital Pocket Hand Held System 20-in-1 - Model 8213 (China)", MACHINE_IS_SKELETON ) +// Language controlled by port bit, set at factory, low resolution +COMP( 201?, dphh8213, 0, 0, st22xx_bbl338, st22xx_bbl338, st22xx_bbl338_state, empty_init, "", "Digital Pocket Hand Held System 20-in-1 - Model 8213", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/unk6502_st2xxx.cpp b/src/mame/drivers/unk6502_st2xxx.cpp index 68314c84c38..fd686b338f2 100644 --- a/src/mame/drivers/unk6502_st2xxx.cpp +++ b/src/mame/drivers/unk6502_st2xxx.cpp @@ -29,6 +29,7 @@ #include "cpu/m6502/st2205u.h" #include "machine/bl_handhelds_menucontrol.h" +#include "video/bl_handhelds_lcdc.h" #include "screen.h" #include "emupal.h" @@ -44,16 +45,13 @@ public: m_spirom(*this, "spi"), m_io_p1(*this, "IN0"), m_io_p2(*this, "IN1"), - m_menucontrol(*this, "menucontrol") + m_menucontrol(*this, "menucontrol"), + m_lcdc(*this, "lcdc") { } void bbl380(machine_config &config); private: - void lcdc_command_w(u8 data); - u8 lcdc_data_r(); - void lcdc_data_w(u8 data); - virtual void machine_start() override; virtual void machine_reset() override; @@ -69,13 +67,6 @@ private: u8 m_output2val; - u8 m_displaybuffer[256 * 256 * 2]; - u16 m_posx, m_posy; - u16 m_posminx, m_posmaxx; - u16 m_posminy, m_posmaxy; - u8 m_command; - u8 m_commandstep; - enum spistate : u8 { SPI_STATE_READY = 0, @@ -98,6 +89,7 @@ private: required_ioport m_io_p1; required_ioport m_io_p2; required_device m_menucontrol; + required_device m_lcdc; u8 ff_r() { return 0xff; } }; @@ -124,25 +116,7 @@ void bbl380_state::output2_w(u8 data) u32 bbl380_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - for (int y = 0; y < 128; y++) - { - u32* dst = &bitmap.pix(y); - - for (int x = 0; x < 160; x++) - { - int count = (y * 0x200) + x; - - u16 dat = m_displaybuffer[(count * 2) + 1] | (m_displaybuffer[(count * 2) + 0] << 8); - - int b = ((dat >> 0) & 0x1f) << 3; - int g = ((dat >> 5) & 0x3f) << 2; - int r = ((dat >> 11) & 0x1f) << 3; - - dst[x] = (r << 16) | (g << 8) | (b << 0); - } - } - - return 0; + return m_lcdc->render_to_bitmap(screen, bitmap, cliprect); } void bbl380_state::machine_start() @@ -150,17 +124,6 @@ void bbl380_state::machine_start() // port related save_item(NAME(m_output2val)); - // LCDC / display related - save_item(NAME(m_displaybuffer)); - save_item(NAME(m_posx)); - save_item(NAME(m_posy)); - save_item(NAME(m_posminx)); - save_item(NAME(m_posmaxx)); - save_item(NAME(m_posminy)); - save_item(NAME(m_posmaxy)); - save_item(NAME(m_command)); - save_item(NAME(m_commandstep)); - // SPI related save_item(NAME(m_spistate)); save_item(NAME(m_spiaddress)); @@ -176,67 +139,8 @@ void bbl380_state::machine_reset() m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0010, 0x0011, read8smo_delegate(*this, FUNC(bbl380_state::spi_r)), write8smo_delegate(*this, FUNC(bbl380_state::spi_w))); // SPI related m_maincpu->space(AS_PROGRAM).install_read_handler(0x0014, 0x0014, read8smo_delegate(*this, FUNC(bbl380_state::ff_r))); // SPI related m_maincpu->space(AS_PROGRAM).install_write_handler(0x0000, 0x0000, write8smo_delegate(*this, FUNC(bbl380_state::output_w))); // Port A output hack, SPI state needs resetting on every port write here or some gfx won't copy fully eg red squares on right of parachute, Soc implementation filters writes - m_maincpu->space(AS_PROGRAM).install_read_handler(0x007b, 0x007b, read8smo_delegate(*this, FUNC(bbl380_state::ff_r))); // unknown internal register } -void bbl380_state::lcdc_command_w(u8 data) -{ - m_command = data; - m_commandstep = 0; - - if (m_command == 0x2c) - { - m_posx = m_posminx << 1; - m_posy = m_posminy; - } -} - -u8 bbl380_state::lcdc_data_r() -{ - return 0; -} - -void bbl380_state::lcdc_data_w(u8 data) -{ - if (m_command == 0x2b) - { - switch (m_commandstep) - { - case 0: m_posminy = data << 8 | (m_posminy & 0xff); break; - case 1: m_posminy = (m_posminy & 0xff00) | data; break; - case 2: m_posmaxy = data << 8 | (m_posmaxy & 0xff); break; - case 3: m_posmaxy = (m_posmaxy & 0xff00) | data; break; - } - m_commandstep++; - } - else if (m_command == 0x2a) - { - switch (m_commandstep) - { - case 0: m_posminx = data << 8 | (m_posminx & 0xff); break; - case 1: m_posminx = (m_posminx & 0xff00) | data; break; - case 2: m_posmaxx = data << 8 | (m_posmaxx & 0xff); break; - case 3: m_posmaxx = (m_posmaxx & 0xff00) | data; break; - } - m_commandstep++; - } - else if (m_command == 0x2c) - { - m_displaybuffer[((m_posx + (m_posy * 0x400))) & 0x1ffff] = data; - - m_posx++; - if (m_posx > ((m_posmaxx << 1) + 1)) - { - m_posx = m_posminx << 1; - m_posy++; - - if (m_posy > m_posmaxy) - { - m_posy = m_posminy; - } - } - } -} void bbl380_state::spi_w(u8 data) { @@ -333,8 +237,8 @@ u8 bbl380_state::spi_r() void bbl380_state::bbl380_map(address_map &map) { map(0x0000000, 0x03fffff).rom().region("maincpu", 0); - map(0x1800000, 0x1800000).w(FUNC(bbl380_state::lcdc_command_w)); - map(0x1804000, 0x1804000).rw(FUNC(bbl380_state::lcdc_data_r), FUNC(bbl380_state::lcdc_data_w)); + map(0x1800000, 0x1800000).w(m_lcdc, FUNC(bl_handhelds_lcdc_device::lcdc_command_w)); + map(0x1804000, 0x1804000).rw(m_lcdc, FUNC(bl_handhelds_lcdc_device::lcdc_data_r), FUNC(bl_handhelds_lcdc_device::lcdc_data_w)); } static INPUT_PORTS_START(bbl380) @@ -362,6 +266,8 @@ void bbl380_state::bbl380(machine_config &config) m_maincpu->set_addrmap(AS_DATA, &bbl380_state::bbl380_map); m_maincpu->in_pa_callback().set_ioport("IN0"); m_maincpu->in_pb_callback().set_ioport("IN1"); + + m_maincpu->out_pa_callback().set(FUNC(bbl380_state::output_w)); m_maincpu->out_pb_callback().set(FUNC(bbl380_state::output2_w)); // TODO, hook these up properly @@ -376,6 +282,7 @@ void bbl380_state::bbl380(machine_config &config) m_screen->set_screen_update(FUNC(bbl380_state::screen_update)); BL_HANDHELDS_MENUCONTROL(config, m_menucontrol, 0); + BL_HANDHELDS_LCDC(config, m_lcdc, 0); // LCD controller seems to be either Sitronix ST7735R or (if RDDID bytes match) Ilitek ILI9163C // (SoC's built-in LCDC is unused or nonexistent?) diff --git a/src/mame/video/bl_handhelds_lcdc.cpp b/src/mame/video/bl_handhelds_lcdc.cpp new file mode 100644 index 00000000000..15038e30bb0 --- /dev/null +++ b/src/mame/video/bl_handhelds_lcdc.cpp @@ -0,0 +1,122 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#include "emu.h" +#include "video/bl_handhelds_lcdc.h" + +DEFINE_DEVICE_TYPE(BL_HANDHELDS_LCDC, bl_handhelds_lcdc_device, "blhandheldlcdc", "BaoBaoLong Handhelds LCD Controller") + +bl_handhelds_lcdc_device::bl_handhelds_lcdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, BL_HANDHELDS_LCDC, tag, owner, clock) +{ +} + +u32 bl_handhelds_lcdc_device::render_to_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + for (int y = 0; y < 128; y++) + { + u32* dst = &bitmap.pix(y); + + for (int x = 0; x < 160; x++) + { + int count = (y * 0x200) + x; + + u16 dat = m_displaybuffer[(count * 2) + 1] | (m_displaybuffer[(count * 2) + 0] << 8); + + int b = ((dat >> 0) & 0x1f) << 3; + int g = ((dat >> 5) & 0x3f) << 2; + int r = ((dat >> 11) & 0x1f) << 3; + + dst[x] = (r << 16) | (g << 8) | (b << 0); + } + } + + return 0; +} + + +void bl_handhelds_lcdc_device::lcdc_command_w(u8 data) +{ + m_command = data; + m_commandstep = 0; + + if (m_command == 0x2c) + { + m_posx = m_posminx << 1; + m_posy = m_posminy; + } +} + +u8 bl_handhelds_lcdc_device::lcdc_data_r() +{ + return 0; +} + +void bl_handhelds_lcdc_device::lcdc_data_w(u8 data) +{ + if (m_command == 0x2b) + { + switch (m_commandstep) + { + case 0: m_posminy = data << 8 | (m_posminy & 0xff); break; + case 1: m_posminy = (m_posminy & 0xff00) | data; break; + case 2: m_posmaxy = data << 8 | (m_posmaxy & 0xff); break; + case 3: m_posmaxy = (m_posmaxy & 0xff00) | data; break; + } + m_commandstep++; + } + else if (m_command == 0x2a) + { + switch (m_commandstep) + { + case 0: m_posminx = data << 8 | (m_posminx & 0xff); break; + case 1: m_posminx = (m_posminx & 0xff00) | data; break; + case 2: m_posmaxx = data << 8 | (m_posmaxx & 0xff); break; + case 3: m_posmaxx = (m_posmaxx & 0xff00) | data; break; + } + m_commandstep++; + } + else if (m_command == 0x2c) + { + m_displaybuffer[((m_posx + (m_posy * 0x400))) & 0x1ffff] = data; + + m_posx++; + if (m_posx > ((m_posmaxx << 1) + 1)) + { + m_posx = m_posminx << 1; + m_posy++; + + if (m_posy > m_posmaxy) + { + m_posy = m_posminy; + } + } + } +} + +void bl_handhelds_lcdc_device::device_start() +{ + std::fill(std::begin(m_displaybuffer), std::end(m_displaybuffer), 0); + m_posx = 0; + m_posy = 0; + m_posminx = 0; + m_posmaxx = 0; + m_posminy = 0; + m_posmaxy = 0; + m_command = 0; + m_commandstep = 0; + + save_item(NAME(m_displaybuffer)); + save_item(NAME(m_posx)); + save_item(NAME(m_posy)); + save_item(NAME(m_posminx)); + save_item(NAME(m_posmaxx)); + save_item(NAME(m_posminy)); + save_item(NAME(m_posmaxy)); + save_item(NAME(m_command)); + save_item(NAME(m_commandstep)); +} + +void bl_handhelds_lcdc_device::device_reset() +{ +} diff --git a/src/mame/video/bl_handhelds_lcdc.h b/src/mame/video/bl_handhelds_lcdc.h new file mode 100644 index 00000000000..4569c341c5a --- /dev/null +++ b/src/mame/video/bl_handhelds_lcdc.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#ifndef MAME_MACHINE_BL_HANDHELDS_LCDC_H +#define MAME_MACHINE_BL_HANDHELDS_LCDC_H + +#pragma once + +DECLARE_DEVICE_TYPE(BL_HANDHELDS_LCDC, bl_handhelds_lcdc_device) + +class bl_handhelds_lcdc_device : public device_t +{ +public: + // construction/destruction + bl_handhelds_lcdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + void lcdc_command_w(u8 data); + u8 lcdc_data_r(); + void lcdc_data_w(u8 data); + + u32 render_to_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + u8 m_displaybuffer[256 * 256 * 2]; + u16 m_posx, m_posy; + u16 m_posminx, m_posmaxx; + u16 m_posminy, m_posmaxy; + u8 m_command; + u8 m_commandstep; + +}; + +#endif // MAME_MACHINE_BL_HANDHELDS_LCDC_H