diff --git a/hash/gameboy.xml b/hash/gameboy.xml
index 006bebbdd38..ac324cbb490 100644
--- a/hash/gameboy.xml
+++ b/hash/gameboy.xml
@@ -25354,7 +25354,7 @@ patch the rom to 0x00 and 0x00....and at 0x0B3D also patch it to
-
+
@@ -25371,7 +25371,7 @@ patch the rom to 0x00 and 0x00....and at 0x0B3D also patch it to
-
+
@@ -25385,7 +25385,7 @@ patch the rom to 0x00 and 0x00....and at 0x0B3D also patch it to
-
+
diff --git a/src/devices/bus/gameboy/mbc.cpp b/src/devices/bus/gameboy/mbc.cpp
index 4e182116deb..286c2d90a1e 100644
--- a/src/devices/bus/gameboy/mbc.cpp
+++ b/src/devices/bus/gameboy/mbc.cpp
@@ -35,6 +35,7 @@ DEFINE_DEVICE_TYPE(GB_ROM_LICHENG, gb_rom_licheng_device, "gb_rom_licheng",
DEFINE_DEVICE_TYPE(GB_ROM_DIGIMON, gb_rom_digimon_device, "gb_rom_digimon", "GB Digimon")
DEFINE_DEVICE_TYPE(GB_ROM_ROCKMAN8, gb_rom_rockman8_device, "gb_rom_rockman8", "GB MBC1 Rockman 8")
DEFINE_DEVICE_TYPE(GB_ROM_SM3SP, gb_rom_sm3sp_device, "gb_sm3sp", "GB MBC1 Super Mario 3 Special")
+DEFINE_DEVICE_TYPE(GB_ROM_CAMERA, gb_rom_camera_device, "gb_rom_camera", "GB Camera")
gb_rom_mbc_device::gb_rom_mbc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
@@ -148,6 +149,11 @@ gb_rom_sm3sp_device::gb_rom_sm3sp_device(const machine_config &mconfig, const ch
{
}
+gb_rom_camera_device::gb_rom_camera_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : gb_rom_mbc_device(mconfig, GB_ROM_CAMERA, tag, owner, clock)
+{
+}
+
//-------------------------------------------------
// shared_start
@@ -324,6 +330,18 @@ void gb_rom_chongwu_device::device_reset()
m_protection_checked = 0;
}
+void gb_rom_camera_device::device_start()
+{
+ shared_start();
+ save_item(NAME(m_camera_regs));
+}
+
+void gb_rom_camera_device::device_reset()
+{
+ shared_reset();
+ memset(m_camera_regs, 0, sizeof(m_camera_regs));
+}
+
/*-------------------------------------------------
mapper specific handlers
@@ -1351,3 +1369,72 @@ WRITE8_MEMBER(gb_rom_sm3sp_device::write_ram)
if (!m_ram.empty())
m_ram[offset] = data;
}
+
+void gb_rom_camera_device::update_camera()
+{
+ m_camera_regs[0] &= ~0x1;
+}
+
+READ8_MEMBER(gb_rom_camera_device::read_rom)
+{
+ if (offset < 0x4000)
+ return m_rom[rom_bank_map[m_latch_bank] * 0x4000 + (offset & 0x3fff)];
+ else
+ return m_rom[rom_bank_map[m_latch_bank2] * 0x4000 + (offset & 0x3fff)];
+}
+
+WRITE8_MEMBER(gb_rom_camera_device::write_bank)
+{
+ if (offset < 0x2000)
+ m_ram_enable = ((data & 0x0f) == 0x0a) ? 1 : 0;
+ else if (offset < 0x4000)
+ {
+ // 7bits
+ data &= 0x7f;
+ /* Selecting bank 0 == selecting bank 1 */
+ if (data == 0)
+ data = 1;
+
+ m_latch_bank2 = data;
+ }
+ else if (offset < 0x6000)
+ {
+ m_ram_bank = data & 0x1f;
+ }
+}
+
+READ8_MEMBER(gb_rom_camera_device::read_ram)
+{
+ if ((m_ram_bank & 0x10) != 0)
+ return (offset == 0) ? (m_camera_regs[0] & 0x7) : 0;
+ if (!m_ram.empty() && (m_camera_regs[0] & 0x1) == 0)
+ {
+ /* Use first saved image as the snapshot. Top and bottom of snapshot are not saved. */
+ if (m_ram_bank == 0 && offset >= 0x100 && offset < 0xf00)
+ return m_ram[0x1f00 + offset];
+ return m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)];
+ }
+ return 0;
+}
+
+WRITE8_MEMBER(gb_rom_camera_device::write_ram)
+{
+ if ((m_ram_bank & 0x10) != 0)
+ {
+ if (offset == 0)
+ {
+ m_camera_regs[0] = data & 0x7;
+ if (data & 0x1) update_camera();
+ }
+ else if (offset < 54)
+ {
+ m_camera_regs[offset] = data;
+ }
+ }
+ else if (m_ram_enable && (m_camera_regs[0] & 0x1) == 0)
+ {
+ // RAM
+ if (!m_ram.empty())
+ m_ram[ram_bank_map[m_ram_bank] * 0x2000 + (offset & 0x1fff)] = data;
+ }
+}
diff --git a/src/devices/bus/gameboy/mbc.h b/src/devices/bus/gameboy/mbc.h
index a99f859639b..4bc169488bf 100644
--- a/src/devices/bus/gameboy/mbc.h
+++ b/src/devices/bus/gameboy/mbc.h
@@ -403,6 +403,28 @@ protected:
uint8_t m_bank_mask, m_bank, m_reg, m_mode;
};
+// ======================> gb_rom_camera_device
+class gb_rom_camera_device : public gb_rom_mbc_device
+{
+public:
+ // construction/destruction
+ gb_rom_camera_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual DECLARE_READ8_MEMBER(read_rom) override;
+ virtual DECLARE_WRITE8_MEMBER(write_bank) override;
+ virtual DECLARE_READ8_MEMBER(read_ram) override;
+ virtual DECLARE_WRITE8_MEMBER(write_ram) override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ void update_camera();
+ uint8_t m_camera_regs[54];
+};
+
// device type definition
@@ -423,5 +445,6 @@ DECLARE_DEVICE_TYPE(GB_ROM_LICHENG, gb_rom_licheng_device)
DECLARE_DEVICE_TYPE(GB_ROM_DIGIMON, gb_rom_digimon_device)
DECLARE_DEVICE_TYPE(GB_ROM_ROCKMAN8, gb_rom_rockman8_device)
DECLARE_DEVICE_TYPE(GB_ROM_SM3SP, gb_rom_sm3sp_device)
+DECLARE_DEVICE_TYPE(GB_ROM_CAMERA, gb_rom_camera_device)
#endif // MAME_BUS_GAMEBOY_MBC_H
diff --git a/src/mame/drivers/gb.cpp b/src/mame/drivers/gb.cpp
index be62bc322ec..c2042546326 100644
--- a/src/mame/drivers/gb.cpp
+++ b/src/mame/drivers/gb.cpp
@@ -519,7 +519,7 @@ static SLOT_INTERFACE_START(gb_cart)
SLOT_INTERFACE_INTERNAL("rom_yong", GB_ROM_YONG)
SLOT_INTERFACE_INTERNAL("rom_lasama", GB_ROM_LASAMA)
SLOT_INTERFACE_INTERNAL("rom_atvrac", GB_ROM_ATVRAC)
- SLOT_INTERFACE_INTERNAL("rom_camera", GB_STD_ROM)
+ SLOT_INTERFACE_INTERNAL("rom_camera", GB_ROM_CAMERA)
SLOT_INTERFACE_INTERNAL("rom_188in1", GB_ROM_188IN1)
SLOT_INTERFACE_INTERNAL("rom_sintax", GB_ROM_SINTAX)
SLOT_INTERFACE_INTERNAL("rom_chong", GB_ROM_CHONGWU)