diff options
-rw-r--r-- | hash/g7400.xml | 11 | ||||
-rw-r--r-- | hash/odyssey2.xml | 4 | ||||
-rw-r--r-- | scripts/src/bus.lua | 2 | ||||
-rw-r--r-- | src/devices/bus/odyssey2/chess.cpp | 15 | ||||
-rw-r--r-- | src/devices/bus/odyssey2/chess.h | 5 | ||||
-rw-r--r-- | src/devices/bus/odyssey2/homecomp.cpp | 144 | ||||
-rw-r--r-- | src/devices/bus/odyssey2/homecomp.h | 64 | ||||
-rw-r--r-- | src/devices/bus/odyssey2/rally.cpp | 6 | ||||
-rw-r--r-- | src/devices/bus/odyssey2/rally.h | 2 | ||||
-rw-r--r-- | src/devices/bus/odyssey2/slot.cpp | 15 | ||||
-rw-r--r-- | src/devices/bus/odyssey2/slot.h | 1 | ||||
-rw-r--r-- | src/emu/xtal.cpp | 1 |
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 */ |