From 18f2dd9ac1cda2fcae6203a24ee1568189b68a64 Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 1 Aug 2020 19:02:26 +0200 Subject: Software list items promoted to working --------------------------------------- odyssey2: Chess Module (Euro) [hap] --- hash/odyssey2.xml | 11 +++--- src/devices/bus/odyssey2/chess.cpp | 65 ++++++++++++++++++++++++++++++------ src/devices/bus/odyssey2/chess.h | 26 +++++++++++++-- src/devices/bus/odyssey2/slot.cpp | 12 +++++-- src/devices/bus/odyssey2/slot.h | 6 +++- src/devices/bus/odyssey2/voice.cpp | 11 +++--- src/mame/drivers/odyssey2.cpp | 68 ++++++++++++++++++++------------------ 7 files changed, 141 insertions(+), 58 deletions(-) diff --git a/hash/odyssey2.xml b/hash/odyssey2.xml index 6ad3ec9995f..c5d3b1203d8 100644 --- a/hash/odyssey2.xml +++ b/hash/odyssey2.xml @@ -83,7 +83,7 @@ adds 16K RAM and 16K ROM, that plugs into the G7000. - + Home Computer Module (Euro) 1983 Philips @@ -92,7 +92,7 @@ adds 16K RAM and 16K ROM, that plugs into the G7000. - + @@ -545,15 +545,16 @@ adds 16K RAM and 16K ROM, that plugs into the G7000. - + Chess Module (Euro) 1982 Philips - - + + + diff --git a/src/devices/bus/odyssey2/chess.cpp b/src/devices/bus/odyssey2/chess.cpp index e8226a4d3be..f1a871f1000 100644 --- a/src/devices/bus/odyssey2/chess.cpp +++ b/src/devices/bus/odyssey2/chess.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Fabio Priuli +// copyright-holders:hap /****************************************************************************** Videopac C7010 Chess Module emulation @@ -11,10 +11,6 @@ Hardware notes: Service manual with schematics is available. -TODO: -- this code is just a stub... hence, almost everything is still to do! - most importantly, missing 8KB ROM dump - ******************************************************************************/ #include "emu.h" @@ -28,22 +24,38 @@ TODO: DEFINE_DEVICE_TYPE(O2_ROM_CHESS, o2_chess_device, "o2_chess", "Odyssey 2 Videopac Chess Module") -o2_chess_device::o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : o2_rom_device(mconfig, O2_ROM_CHESS, tag, owner, clock) - , m_cpu(*this, "subcpu") +o2_chess_device::o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + o2_rom_device(mconfig, O2_ROM_CHESS, tag, owner, clock), + m_cpu(*this, "subcpu"), + m_latch(*this, "latch%u", 0) +{ } + +void o2_chess_device::device_start() +{ + save_item(NAME(m_control)); +} + +void o2_chess_device::cart_init() { + if (m_rom_size != 0x2800) + fatalerror("o2_chess_device: Wrong ROM region size\n"); } +//------------------------------------------------- +// address maps +//------------------------------------------------- + void o2_chess_device::chess_mem(address_map &map) { - map(0x0000, 0x07ff).r(FUNC(o2_chess_device::read_rom04)); + map(0x0000, 0x1fff).r(FUNC(o2_chess_device::internal_rom_r)); + map(0xe000, 0xe7ff).mirror(0x1800).ram(); } void o2_chess_device::chess_io(address_map &map) { - map.unmap_value_high(); - map.global_mask(0xff); + map.global_mask(0x01); + map(0x00, 0x01).r(m_latch[1], FUNC(generic_latch_8_device::read)).w(m_latch[0], FUNC(generic_latch_8_device::write)); } @@ -56,4 +68,35 @@ 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); + + GENERIC_LATCH_8(config, m_latch[0]); + GENERIC_LATCH_8(config, m_latch[1]); +} + + +//------------------------------------------------- +// mapper specific handlers +//------------------------------------------------- + +void o2_chess_device::write_bank(int bank) +{ + // P10: must be low to access latches + // P11: reset + m_cpu->set_input_line(INPUT_LINE_RESET, (bank & 2) ? CLEAR_LINE : ASSERT_LINE); + + m_control = bank; +} + +u8 o2_chess_device::io_read(offs_t offset) +{ + if (offset & 0x80 && offset & 0x20 && ~m_control & 1) + return m_latch[0]->read(); + else + return 0xff; +} + +void o2_chess_device::io_write(offs_t offset, u8 data) +{ + if (offset & 0x80 && ~m_control & 1) + m_latch[1]->write(data); } diff --git a/src/devices/bus/odyssey2/chess.h b/src/devices/bus/odyssey2/chess.h index da8bee54b9d..d1f6ecbfc9f 100644 --- a/src/devices/bus/odyssey2/chess.h +++ b/src/devices/bus/odyssey2/chess.h @@ -1,5 +1,11 @@ // license:BSD-3-Clause -// copyright-holders:Fabio Priuli +// copyright-holders:hap +/********************************************************************** + + Videopac C7010 Chess Module emulation + +**********************************************************************/ + #ifndef MAME_BUS_ODYSSEY2_CHESS_H #define MAME_BUS_ODYSSEY2_CHESS_H @@ -8,6 +14,7 @@ #include "slot.h" #include "rom.h" #include "cpu/z80/z80.h" +#include "machine/gen_latch.h" // ======================> o2_chess_device @@ -19,14 +26,29 @@ public: o2_chess_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 const rom_entry *device_rom_region() const; + + 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 void write_bank(int bank) override; + virtual void io_write(offs_t offset, u8 data) override; + virtual u8 io_read(offs_t offset) override; private: required_device m_cpu; + required_device_array m_latch; + + u8 internal_rom_r(offs_t offset) { return m_rom[offset]; } void chess_io(address_map &map); void chess_mem(address_map &map); + + u8 m_control = 0; }; // device type definition diff --git a/src/devices/bus/odyssey2/slot.cpp b/src/devices/bus/odyssey2/slot.cpp index 3b743b6964b..b5a2f71be67 100644 --- a/src/devices/bus/odyssey2/slot.cpp +++ b/src/devices/bus/odyssey2/slot.cpp @@ -174,7 +174,7 @@ image_init_result o2_cart_slot_device::call_load() m_type = o2_get_pcb_id(pcb_name); } - //printf("Type: %s\n", o2_get_slot(m_type)); + m_cart->cart_init(); return image_init_result::PASS; } @@ -231,7 +231,7 @@ uint8_t o2_cart_slot_device::read_rom0c(offs_t offset) } /*------------------------------------------------- - io_write + io -------------------------------------------------*/ void o2_cart_slot_device::io_write(offs_t offset, uint8_t data) @@ -240,6 +240,14 @@ void o2_cart_slot_device::io_write(offs_t offset, uint8_t data) m_cart->io_write(offset, data); } +uint8_t o2_cart_slot_device::io_read(offs_t offset) +{ + if (m_cart) + return m_cart->io_read(offset); + else + return 0xff; +} + #include "bus/odyssey2/rom.h" #include "bus/odyssey2/chess.h" diff --git a/src/devices/bus/odyssey2/slot.h b/src/devices/bus/odyssey2/slot.h index 69e107edc11..cec7e2b8eb5 100644 --- a/src/devices/bus/odyssey2/slot.h +++ b/src/devices/bus/odyssey2/slot.h @@ -38,8 +38,11 @@ public: virtual void write_bank(int bank) { } virtual void io_write(offs_t offset, uint8_t data) { } + virtual uint8_t io_read(offs_t offset) { return 0xff; } virtual DECLARE_READ_LINE_MEMBER(t0_read) { return 0; } + virtual void cart_init() { } // called after loading ROM + void rom_alloc(uint32_t size, const char *tag); void ram_alloc(uint32_t size); uint8_t* get_rom_base() { return m_rom; } @@ -100,9 +103,10 @@ public: uint8_t read_rom04(offs_t offset); uint8_t read_rom0c(offs_t offset); void io_write(offs_t offset, uint8_t data); + uint8_t io_read(offs_t offset); DECLARE_READ_LINE_MEMBER(t0_read) { if (m_cart) return m_cart->t0_read(); else return 0; } - void write_bank(int bank) { if (m_cart) m_cart->write_bank(bank); } + void write_bank(int bank) { if (m_cart) m_cart->write_bank(bank); } protected: // device-level overrides diff --git a/src/devices/bus/odyssey2/voice.cpp b/src/devices/bus/odyssey2/voice.cpp index 490b9b286ad..b0c93670b78 100644 --- a/src/devices/bus/odyssey2/voice.cpp +++ b/src/devices/bus/odyssey2/voice.cpp @@ -88,8 +88,11 @@ WRITE_LINE_MEMBER(o2_voice_device::lrq_callback) void o2_voice_device::io_write(offs_t offset, uint8_t data) { - if (data & 0x20) - m_speech->ald_w(offset & 0x7f); - else - m_speech->reset(); + if (offset & 0x80) + { + if (data & 0x20) + m_speech->ald_w(offset & 0x7f); + else + m_speech->reset(); + } } diff --git a/src/mame/drivers/odyssey2.cpp b/src/mame/drivers/odyssey2.cpp index ad083128ee2..78cd6ee67f0 100644 --- a/src/mame/drivers/odyssey2.cpp +++ b/src/mame/drivers/odyssey2.cpp @@ -2,12 +2,14 @@ // copyright-holders:Wilbert Pol /*************************************************************************** - /drivers/odyssey2.c +Driver file to handle emulation of the Odyssey2. - Driver file to handle emulation of the Odyssey2. - - Minor update to "the voice" rom names, and add comment about - the older revision of "the voice" - LN, 10/03/08 +TODO: +- chess has graphics issues near the screen borders: missing A-H at bottom, + rightmost column is not erased properly, wrongly places chars at top +- homecomp does not work, needs new slot device +- a lot more issues, probably, this TODO list was written by someone with + no knowledge on odyssey2 ***************************************************************************/ @@ -52,7 +54,7 @@ protected: required_device m_i8244; required_device m_cart; - uint8_t m_ram[256]; + uint8_t m_ram[0x80]; uint8_t m_p1; uint8_t m_p2; uint8_t m_lum; @@ -290,19 +292,17 @@ void g7400_state::g7400_palette(palette_device &palette) const void odyssey2_state::init_odyssey2() { - uint8_t *gfx = memregion("gfx1")->base(); + memset(m_ram, 0, 0x80); + uint8_t *gfx = memregion("gfx1")->base(); for (int i = 0; i < 256; i++) - { - gfx[i] = i; /* TODO: Why i and not 0? */ - m_ram[i] = 0; - } + gfx[i] = i; /* TODO: Why i and not 0? */ } void odyssey2_state::machine_start() { - save_pointer(NAME(m_ram),256); + save_item(NAME(m_ram)); save_item(NAME(m_p1)); save_item(NAME(m_p2)); save_item(NAME(m_lum)); @@ -344,16 +344,20 @@ void g7400_state::machine_reset() uint8_t odyssey2_state::io_read(offs_t offset) { + u8 data = 0; + if ((m_p1 & (P1_VDC_COPY_MODE_ENABLE | P1_VDC_ENABLE)) == 0) { - return m_i8244->read(offset); + data = m_i8244->read(offset); } - if (!(m_p1 & P1_EXT_RAM_ENABLE)) + else if (!(m_p1 & P1_EXT_RAM_ENABLE)) { - return m_ram[offset]; + data = m_cart->io_read(offset); + if (~offset & 0x80) + data &= m_ram[offset]; } - return 0; + return data; } @@ -361,12 +365,9 @@ void odyssey2_state::io_write(offs_t offset, uint8_t data) { if ((m_p1 & (P1_EXT_RAM_ENABLE | P1_VDC_COPY_MODE_ENABLE)) == 0x00) { - m_ram[offset] = data; - if (offset & 0x80) - { - logerror("voice write %02X, data = %02X (p1 = %02X)\n", offset, data, m_p1); - m_cart->io_write(offset, data); - } + if (~offset & 0x80) + m_ram[offset] = data; + m_cart->io_write(offset, data); } else if (!(m_p1 & P1_VDC_ENABLE)) { @@ -377,20 +378,24 @@ void odyssey2_state::io_write(offs_t offset, uint8_t data) uint8_t g7400_state::io_read(offs_t offset) { + u8 data = 0; + if ((m_p1 & (P1_VDC_COPY_MODE_ENABLE | P1_VDC_ENABLE)) == 0) { - return m_i8244->read(offset); + data = m_i8244->read(offset); } else if (!(m_p1 & P1_EXT_RAM_ENABLE)) { - return m_ram[offset]; + data = m_cart->io_read(offset); + if (~offset & 0x80) + data &= m_ram[offset]; } else if (!(m_p1 & P1_VPP_ENABLE)) { - return m_ef9340_1->ef9341_read( offset & 0x02, offset & 0x01 ); + data = m_ef9340_1->ef9341_read( offset & 0x02, offset & 0x01 ); } - return 0; + return data; } @@ -398,12 +403,9 @@ void g7400_state::io_write(offs_t offset, uint8_t data) { if ((m_p1 & (P1_EXT_RAM_ENABLE | P1_VDC_COPY_MODE_ENABLE)) == 0x00) { - m_ram[offset] = data; - if (offset & 0x80) - { - logerror("voice write %02X, data = %02X (p1 = %02X)\n", offset, data, m_p1); - m_cart->io_write(offset, data); - } + if (~offset & 0x80) + m_ram[offset] = data; + m_cart->io_write(offset, data); } else if (!(m_p1 & P1_VDC_ENABLE)) { @@ -892,4 +894,4 @@ COMP( 1978, odyssey2, 0, 0, odyssey2, odyssey2, odyssey2_state, init COMP( 1979, videopac, odyssey2, 0, videopac, odyssey2, odyssey2_state, init_odyssey2, "Philips", "Videopac G7000/C52", 0 ) COMP( 1983, g7400, odyssey2, 0, g7400, odyssey2, g7400_state, init_odyssey2, "Philips", "Videopac Plus G7400", MACHINE_IMPERFECT_GRAPHICS ) COMP( 1983, jopac, odyssey2, 0, g7400, odyssey2, g7400_state, init_odyssey2, "Brandt", "Jopac JO7400", MACHINE_IMPERFECT_GRAPHICS ) -COMP( 1983, odyssey3, odyssey2, 0, odyssey3, odyssey2, g7400_state, init_odyssey2, "Magnavox", "Odyssey 3 Command Center (prototype)", MACHINE_IMPERFECT_GRAPHICS ) +COMP( 1983, odyssey3, odyssey2, 0, odyssey3, odyssey2, g7400_state, init_odyssey2, "Magnavox", "Odyssey 3 Command Center (prototype)", MACHINE_IMPERFECT_GRAPHICS ) // USA version of G7400 -- cgit v1.2.3