summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2020-08-12 14:41:42 +0200
committer hap <happppp@users.noreply.github.com>2020-08-12 14:41:56 +0200
commit138a281c6ccdf35c750f951878b2e3258a1a1f8c (patch)
treefdffa25ace41b9e713055dafc8cc74e5abde3d37
parentbcb1d091c2961472a12f2d5eee594592b9818795 (diff)
odyssey2: add preliminary Videopac+ C7420 Home Computer Module emulation
-rw-r--r--hash/g7400.xml11
-rw-r--r--hash/odyssey2.xml4
-rw-r--r--scripts/src/bus.lua2
-rw-r--r--src/devices/bus/odyssey2/chess.cpp15
-rw-r--r--src/devices/bus/odyssey2/chess.h5
-rw-r--r--src/devices/bus/odyssey2/homecomp.cpp144
-rw-r--r--src/devices/bus/odyssey2/homecomp.h64
-rw-r--r--src/devices/bus/odyssey2/rally.cpp6
-rw-r--r--src/devices/bus/odyssey2/rally.h2
-rw-r--r--src/devices/bus/odyssey2/slot.cpp15
-rw-r--r--src/devices/bus/odyssey2/slot.h1
-rw-r--r--src/emu/xtal.cpp1
12 files changed, 243 insertions, 27 deletions
diff --git a/hash/g7400.xml b/hash/g7400.xml
index 0f8a120341f..95ba4c04047 100644
--- a/hash/g7400.xml
+++ b/hash/g7400.xml
@@ -32,8 +32,7 @@ Robot City (USA)
Interpol (USA)
NOTE:
-The C7420 Home Computer Module, which contains a Z80 microprocessor running at 3.5468 MHz,
-adds 16K RAM and 16K ROM, that plugs into the G7000.
+The C7420 Home Computer Module contains a Z80, 16K RAM and 16K ROM.
-->
<softwarelist name="g7400" description="Philips Videopac Plus G7400 cartridges">
@@ -202,16 +201,16 @@ adds 16K RAM and 16K ROM, that plugs into the G7000.
</part>
</software>
- <software name="homecomp" supported="no"><!-- needs home computer module emulation, wrong romtype right now -->
+ <software name="homecomp" supported="no">
<description>Home Computer Module (Euro)</description><!-- aka Basic -->
<year>1983</year>
<publisher>Philips</publisher>
<info name="serial" value="C7420"/>
<part name="cart" interface="odyssey_cart">
- <feature name="slot" value="o2_rom" />
+ <feature name="slot" value="o2_homecomp" />
<dataarea name="rom" size="0x4800">
- <rom name="z80_c7420.bin" size="0x4000" crc="939f0e4c" sha1="24c334ba4321f3dd30ac659d35e43f74283ad93b" offset="0" />
- <rom name="vp_c7420.bin" size="0x800" crc="8e824b98" sha1="60dfc1eea93c25f30d25e549f32f837e22735224" offset="0x4000" />
+ <rom name="z80_c7420.bin" offset="0x0000" size="0x4000" crc="939f0e4c" sha1="24c334ba4321f3dd30ac659d35e43f74283ad93b" />
+ <rom name="vp_c7420.bin" offset="0x4000" size="0x0800" crc="8e824b98" sha1="60dfc1eea93c25f30d25e549f32f837e22735224" />
</dataarea>
</part>
</software>
diff --git a/hash/odyssey2.xml b/hash/odyssey2.xml
index a865b226d2d..2f8c14c20d3 100644
--- a/hash/odyssey2.xml
+++ b/hash/odyssey2.xml
@@ -551,8 +551,8 @@ The C7010 Chess Module had a NSC800 CMOS microprocessor, with 2K RAM and 8K ROM.
<part name="cart" interface="odyssey_cart">
<feature name="slot" value="o2_chess" />
<dataarea name="rom" size="0x2800">
- <rom name="z80_c7010.bin" size="0x2000" crc="45080245" sha1="fff3e6449a0e82e8e4ff45e5830c98fc38a8848e" offset="0" />
- <rom name="vp_c7010.bin" size="0x800" crc="77066338" sha1="7162359313f66fe759bdd8a34755a5f62f3cadfb" offset="0x2000" />
+ <rom name="z80_c7010.bin" offset="0x0000" size="0x2000" crc="45080245" sha1="fff3e6449a0e82e8e4ff45e5830c98fc38a8848e" />
+ <rom name="vp_c7010.bin" offset="0x2000" size="0x0800" crc="77066338" sha1="7162359313f66fe759bdd8a34755a5f62f3cadfb" />
</dataarea>
</part>
</software>
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 2704e17faf7..fff70f4852b 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -1696,6 +1696,8 @@ if (BUSES["O2"]~=null) then
MAME_DIR .. "src/devices/bus/odyssey2/4in1.h",
MAME_DIR .. "src/devices/bus/odyssey2/chess.cpp",
MAME_DIR .. "src/devices/bus/odyssey2/chess.h",
+ MAME_DIR .. "src/devices/bus/odyssey2/homecomp.cpp",
+ MAME_DIR .. "src/devices/bus/odyssey2/homecomp.h",
MAME_DIR .. "src/devices/bus/odyssey2/ktaa.cpp",
MAME_DIR .. "src/devices/bus/odyssey2/ktaa.h",
MAME_DIR .. "src/devices/bus/odyssey2/rally.cpp",
diff --git a/src/devices/bus/odyssey2/chess.cpp b/src/devices/bus/odyssey2/chess.cpp
index 67dbfe0bd4d..121c0cacf59 100644
--- a/src/devices/bus/odyssey2/chess.cpp
+++ b/src/devices/bus/odyssey2/chess.cpp
@@ -9,8 +9,6 @@ Hardware notes:
- NSC800 (Z80-compatible) @ 4.43MHz
- 8KB ROM, 2KB RAM
-Service manual with schematics is available.
-
******************************************************************************/
#include "emu.h"
@@ -26,7 +24,7 @@ DEFINE_DEVICE_TYPE(O2_ROM_CHESS, o2_chess_device, "o2_chess", "Odyssey 2 Videopa
o2_chess_device::o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, O2_ROM_CHESS, tag, owner, clock),
device_o2_cart_interface(mconfig, *this),
- m_cpu(*this, "subcpu"),
+ m_maincpu(*this, "maincpu"),
m_latch(*this, "latch%u", 0)
{ }
@@ -65,9 +63,10 @@ void o2_chess_device::chess_io(address_map &map)
void o2_chess_device::device_add_mconfig(machine_config &config)
{
- NSC800(config, m_cpu, 4.433619_MHz_XTAL);
- m_cpu->set_addrmap(AS_PROGRAM, &o2_chess_device::chess_mem);
- m_cpu->set_addrmap(AS_IO, &o2_chess_device::chess_io);
+ // basic machine hardware
+ NSC800(config, m_maincpu, 4.433619_MHz_XTAL);
+ m_maincpu->set_addrmap(AS_PROGRAM, &o2_chess_device::chess_mem);
+ m_maincpu->set_addrmap(AS_IO, &o2_chess_device::chess_io);
GENERIC_LATCH_8(config, m_latch[0]);
GENERIC_LATCH_8(config, m_latch[1]);
@@ -80,10 +79,10 @@ void o2_chess_device::device_add_mconfig(machine_config &config)
void o2_chess_device::write_p1(u8 data)
{
- // P10,P14: must be low to access latches
// P11: reset
- m_cpu->set_input_line(INPUT_LINE_RESET, (data & 2) ? CLEAR_LINE : ASSERT_LINE);
+ m_maincpu->set_input_line(INPUT_LINE_RESET, (data & 2) ? CLEAR_LINE : ASSERT_LINE);
+ // P10,P14: must be low to access latches
m_control = data;
}
diff --git a/src/devices/bus/odyssey2/chess.h b/src/devices/bus/odyssey2/chess.h
index 4ebc81886af..0e89c20fc04 100644
--- a/src/devices/bus/odyssey2/chess.h
+++ b/src/devices/bus/odyssey2/chess.h
@@ -12,6 +12,7 @@
#pragma once
#include "slot.h"
+
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
@@ -33,14 +34,14 @@ protected:
virtual void cart_init() override;
virtual u8 read_rom04(offs_t offset) override { return m_rom[offset + 0x2000]; }
- virtual u8 read_rom0c(offs_t offset) override { return m_rom[offset + 0x2000]; }
+ virtual u8 read_rom0c(offs_t offset) override { return read_rom04(offset); }
virtual void write_p1(u8 data) override;
virtual void io_write(offs_t offset, u8 data) override;
virtual u8 io_read(offs_t offset) override;
private:
- required_device<nsc800_device> m_cpu;
+ required_device<cpu_device> m_maincpu;
required_device_array<generic_latch_8_device, 2> m_latch;
u8 internal_rom_r(offs_t offset) { return m_rom[offset]; }
diff --git a/src/devices/bus/odyssey2/homecomp.cpp b/src/devices/bus/odyssey2/homecomp.cpp
new file mode 100644
index 00000000000..829ecb35c86
--- /dev/null
+++ b/src/devices/bus/odyssey2/homecomp.cpp
@@ -0,0 +1,144 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/******************************************************************************
+
+Videopac+ C7420 Home Computer Module emulation
+
+This module only works on the Videopac+ G7400, although the cartridge can still
+be inserted into the Odyssey 2/G7000.
+
+Hardware notes:
+- Z80 @ 3.547MHz
+- 2*8KB ROM, 16KB RAM(2*TMS4416, 2 unpopulated sockets)
+- optional data recorder
+
+TODO:
+- lots of unacknowledged writes to latch 1, probably harmless
+- add cassette i/o
+
+******************************************************************************/
+
+#include "emu.h"
+#include "homecomp.h"
+#include "speaker.h"
+
+DEFINE_DEVICE_TYPE(O2_ROM_HOMECOMP, o2_homecomp_device, "o2_homecomp", "Odyssey 2 Videopac+ C7420")
+
+
+//-------------------------------------------------
+// o2_homecomp_device - constructor
+//-------------------------------------------------
+
+o2_homecomp_device::o2_homecomp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, O2_ROM_HOMECOMP, tag, owner, clock),
+ device_o2_cart_interface(mconfig, *this),
+ m_maincpu(*this, "maincpu"),
+ m_latch(*this, "latch%u", 0),
+ m_cass(*this, "cassette")
+{ }
+
+void o2_homecomp_device::device_start()
+{
+ save_item(NAME(m_control));
+}
+
+void o2_homecomp_device::cart_init()
+{
+ if (m_rom_size != 0x4800)
+ fatalerror("o2_homecomp_device: Wrong ROM region size\n");
+}
+
+
+//-------------------------------------------------
+// internal i/o
+//-------------------------------------------------
+
+u8 o2_homecomp_device::internal_io_r(offs_t offset)
+{
+ u8 data = 0;
+
+ // A7: input latch
+ if (~offset & 0x80)
+ data |= m_latch[1]->read();
+
+ // A6: other i/o
+ if (~offset & 0x40)
+ {
+ // d0: latch 0 status
+ data |= m_latch[0]->pending_r() ^ 1;
+ }
+
+ return data;
+}
+
+void o2_homecomp_device::internal_io_w(offs_t offset, u8 data)
+{
+ // A7: output latch
+ if (~offset & 0x80)
+ m_latch[0]->write(data);
+}
+
+void o2_homecomp_device::homecomp_mem(address_map &map)
+{
+ map(0x0000, 0x3fff).r(FUNC(o2_homecomp_device::internal_rom_r));
+ map(0x8000, 0xbfff).ram();
+}
+
+void o2_homecomp_device::homecomp_io(address_map &map)
+{
+ map.global_mask(0xff);
+ map(0x00, 0xff).rw(FUNC(o2_homecomp_device::internal_io_r), FUNC(o2_homecomp_device::internal_io_w));
+}
+
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void o2_homecomp_device::device_add_mconfig(machine_config &config)
+{
+ // basic machine hardware
+ Z80(config, m_maincpu, 3.547_MHz_XTAL);
+ m_maincpu->set_addrmap(AS_PROGRAM, &o2_homecomp_device::homecomp_mem);
+ m_maincpu->set_addrmap(AS_IO, &o2_homecomp_device::homecomp_io);
+
+ GENERIC_LATCH_8(config, m_latch[0]);
+ GENERIC_LATCH_8(config, m_latch[1]);
+
+ // cassette
+ CASSETTE(config, m_cass);
+ m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED);
+ SPEAKER(config, "cass_output").front_center(); // on data recorder
+ m_cass->add_route(ALL_OUTPUTS, "cass_output", 0.05);
+}
+
+
+//-------------------------------------------------
+// mapper specific handlers
+//-------------------------------------------------
+
+void o2_homecomp_device::write_p1(u8 data)
+{
+ // P10: Z80 INT pin
+ // P10+P11: Z80 RESET pin
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, (data & 1) ? CLEAR_LINE : ASSERT_LINE);
+ m_maincpu->set_input_line(INPUT_LINE_RESET, (data & 3) ? CLEAR_LINE : ASSERT_LINE);
+
+ // P11: must be low to access latch 0
+ // P14: must be low to access latch 1
+ m_control = data;
+}
+
+u8 o2_homecomp_device::io_read(offs_t offset)
+{
+ if ((offset & 0xa0) == 0xa0 && ~m_control & 2)
+ return m_latch[0]->read();
+ else
+ return 0xff;
+}
+
+void o2_homecomp_device::io_write(offs_t offset, u8 data)
+{
+ if (offset & 0x80 && ~m_control & 0x10)
+ m_latch[1]->write(data);
+}
diff --git a/src/devices/bus/odyssey2/homecomp.h b/src/devices/bus/odyssey2/homecomp.h
new file mode 100644
index 00000000000..5a1d8a84801
--- /dev/null
+++ b/src/devices/bus/odyssey2/homecomp.h
@@ -0,0 +1,64 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/**********************************************************************
+
+ Videopac+ C7420 Home Computer Module emulation
+
+**********************************************************************/
+
+#ifndef MAME_BUS_ODYSSEY2_HOMECOMP_H
+#define MAME_BUS_ODYSSEY2_HOMECOMP_H
+
+#pragma once
+
+#include "slot.h"
+
+#include "cpu/z80/z80.h"
+#include "imagedev/cassette.h"
+#include "machine/gen_latch.h"
+
+
+// ======================> o2_homecomp_device
+
+class o2_homecomp_device : public device_t,
+ public device_o2_cart_interface
+{
+public:
+ // construction/destruction
+ o2_homecomp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ virtual void cart_init() override;
+
+ virtual u8 read_rom04(offs_t offset) override { return m_rom[offset + 0x4000]; }
+ virtual u8 read_rom0c(offs_t offset) override { return read_rom04(offset); }
+
+ virtual void write_p1(u8 data) override;
+ virtual void io_write(offs_t offset, u8 data) override;
+ virtual u8 io_read(offs_t offset) override;
+ virtual DECLARE_READ_LINE_MEMBER(t0_read) override { return m_latch[0]->pending_r(); }
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device_array<generic_latch_8_device, 2> m_latch;
+ required_device<cassette_image_device> m_cass;
+
+ void internal_io_w(offs_t offset, u8 data);
+ u8 internal_io_r(offs_t offset);
+ u8 internal_rom_r(offs_t offset) { return m_rom[offset]; }
+
+ void homecomp_io(address_map &map);
+ void homecomp_mem(address_map &map);
+
+ u8 m_control = 0;
+ u8 m_ioctrl = 0;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(O2_ROM_HOMECOMP, o2_homecomp_device)
+
+#endif // MAME_BUS_ODYSSEY2_HOMECOMP_H
diff --git a/src/devices/bus/odyssey2/rally.cpp b/src/devices/bus/odyssey2/rally.cpp
index e2ab2fe31e2..33881e3abcb 100644
--- a/src/devices/bus/odyssey2/rally.cpp
+++ b/src/devices/bus/odyssey2/rally.cpp
@@ -2,7 +2,7 @@
// copyright-holders:hap
/******************************************************************************
-Videopac 55/58/59/60 cartridge emulation
+Videopac+ 55/58/59/60 cartridge emulation
Bankswitched ROM via latch, either 16KB/2*8KB, or 4KB+8KB.
@@ -12,12 +12,14 @@ Used in:
- #59: Helicopter Rescue
- #60: Trans American Rally
+#55 and #58 also work on the G7000.
+
******************************************************************************/
#include "emu.h"
#include "rally.h"
-DEFINE_DEVICE_TYPE(O2_ROM_RALLY, o2_rally_device, "o2_rally", "Odyssey 2 Videopac 60")
+DEFINE_DEVICE_TYPE(O2_ROM_RALLY, o2_rally_device, "o2_rally", "Odyssey 2 Videopac+ 60")
//-------------------------------------------------
diff --git a/src/devices/bus/odyssey2/rally.h b/src/devices/bus/odyssey2/rally.h
index 13021a3a317..81de2673ae6 100644
--- a/src/devices/bus/odyssey2/rally.h
+++ b/src/devices/bus/odyssey2/rally.h
@@ -2,7 +2,7 @@
// copyright-holders:hap
/**********************************************************************
- Videopac 55/58/59/60 cartridge emulation
+ Videopac+ 55/58/59/60 cartridge emulation
**********************************************************************/
diff --git a/src/devices/bus/odyssey2/slot.cpp b/src/devices/bus/odyssey2/slot.cpp
index ab97e4d7679..417fb3230c1 100644
--- a/src/devices/bus/odyssey2/slot.cpp
+++ b/src/devices/bus/odyssey2/slot.cpp
@@ -118,6 +118,7 @@ static const o2_slot slot_list[] =
{ O2_RALLY, "o2_rally" },
{ O2_KTAA, "o2_ktaa" },
{ O2_CHESS, "o2_chess" },
+ { O2_HOMECOMP, "o2_homecomp" },
{ O2_VOICE, "o2_voice" }
};
@@ -243,14 +244,16 @@ uint8_t o2_cart_slot_device::io_read(offs_t offset)
#include "bus/odyssey2/rally.h"
#include "bus/odyssey2/ktaa.h"
#include "bus/odyssey2/chess.h"
+#include "bus/odyssey2/homecomp.h"
#include "bus/odyssey2/voice.h"
void o2_cart(device_slot_interface &device)
{
- device.option_add_internal("o2_rom", O2_ROM_STD);
- device.option_add_internal("o2_4in1", O2_ROM_4IN1);
- device.option_add_internal("o2_rally", O2_ROM_RALLY);
- device.option_add_internal("o2_ktaa", O2_ROM_KTAA);
- device.option_add_internal("o2_chess", O2_ROM_CHESS);
- device.option_add_internal("o2_voice", O2_ROM_VOICE);
+ device.option_add_internal("o2_rom", O2_ROM_STD);
+ device.option_add_internal("o2_4in1", O2_ROM_4IN1);
+ device.option_add_internal("o2_rally", O2_ROM_RALLY);
+ device.option_add_internal("o2_ktaa", O2_ROM_KTAA);
+ device.option_add_internal("o2_chess", O2_ROM_CHESS);
+ device.option_add_internal("o2_homecomp", O2_ROM_HOMECOMP);
+ device.option_add_internal("o2_voice", O2_ROM_VOICE);
}
diff --git a/src/devices/bus/odyssey2/slot.h b/src/devices/bus/odyssey2/slot.h
index 2e0d847e642..419e187ac7a 100644
--- a/src/devices/bus/odyssey2/slot.h
+++ b/src/devices/bus/odyssey2/slot.h
@@ -21,6 +21,7 @@ enum
O2_RALLY,
O2_KTAA,
O2_CHESS,
+ O2_HOMECOMP,
O2_VOICE
};
diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp
index 98ce751ea58..bc960f8c8ee 100644
--- a/src/emu/xtal.cpp
+++ b/src/emu/xtal.cpp
@@ -91,6 +91,7 @@ const double XTAL::known_xtals[] = {
3'276'800, /* 3.2768_MHz_XTAL SP0256 clock in Speech Synthesis for Dragon 32 */
3'521'280, /* 3.52128_MHz_XTAL RCA COSMAC VIP */
3'546'800, /* 3.5468_MHz_XTAL Atari 400 PAL, Philips G7200 */
+ 3'547'000, /* 3.547_MHz_XTAL Philips C7240 */
3'570'000, /* 3.57_MHz_XTAL Telmac TMC-600 */
3'578'640, /* 3.57864_MHz_XTAL Atari Portfolio PCD3311T */
3'579'000, /* 3.579_MHz_XTAL BeebOPL */