diff options
| author | 2021-06-21 13:53:49 -0700 | |
|---|---|---|
| committer | 2021-06-21 13:53:49 -0700 | |
| commit | 32dbba7d2d4513774b2d877b4c88f2d0760bcf54 (patch) | |
| tree | f9e6426cf8dc28413c456bdbcd450c85cb302422 /src/devices | |
| parent | 5522729235b3ce81c839f3932c1aadc14de59e2b (diff) | |
| parent | 2709c0143a8c7009715242c135b28403eeffce8b (diff) | |
Merge branch 'master' into deprecateddeprecated
Diffstat (limited to 'src/devices')
105 files changed, 3507 insertions, 583 deletions
diff --git a/src/devices/bus/a2bus/a2bus.h b/src/devices/bus/a2bus/a2bus.h index 1c7d94bbcdc..5a10f06de39 100644 --- a/src/devices/bus/a2bus/a2bus.h +++ b/src/devices/bus/a2bus/a2bus.h @@ -149,6 +149,7 @@ public: virtual void write_inh_rom(uint16_t offset, uint8_t data) { } virtual uint16_t inh_start() { return INH_START_INVALID; } virtual uint16_t inh_end() { return INH_END_INVALID; } + virtual bool inh_check(uint16_t offset, bool bIsWrite) { return false; } virtual int inh_type() { return INH_NONE; } device_a2bus_card_interface *next() const { return m_next; } diff --git a/src/devices/bus/a2bus/a2mockingboard.cpp b/src/devices/bus/a2bus/a2mockingboard.cpp index 6073e843371..380e9988a8b 100644 --- a/src/devices/bus/a2bus/a2mockingboard.cpp +++ b/src/devices/bus/a2bus/a2mockingboard.cpp @@ -41,11 +41,13 @@ DEFINE_DEVICE_TYPE(A2BUS_ECHOPLUS, a2bus_echoplus_device, "a2echop", "S void a2bus_ayboard_device::add_common_devices(machine_config &config) { MOS6522(config, m_via1, 1022727); + m_via1->readpa_handler().set(FUNC(a2bus_ayboard_device::via1_in_a)); m_via1->writepa_handler().set(FUNC(a2bus_ayboard_device::via1_out_a)); m_via1->writepb_handler().set(FUNC(a2bus_ayboard_device::via1_out_b)); m_via1->irq_handler().set(FUNC(a2bus_ayboard_device::via1_irq_w)); MOS6522(config, m_via2, 1022727); + m_via2->readpa_handler().set(FUNC(a2bus_ayboard_device::via2_in_a)); m_via2->writepa_handler().set(FUNC(a2bus_ayboard_device::via2_out_a)); m_via2->writepb_handler().set(FUNC(a2bus_ayboard_device::via2_out_b)); m_via2->irq_handler().set(FUNC(a2bus_ayboard_device::via2_irq_w)); @@ -101,6 +103,9 @@ void a2bus_echoplus_device::device_add_mconfig(machine_config &config) { add_common_devices(config); + config.device_remove(VIA2_TAG); + m_via1->writepb_handler().set(FUNC(a2bus_ayboard_device::via1_out_b)); + AY8913(config, m_ay2, 1022727); m_ay2->add_route(ALL_OUTPUTS, "rspeaker", 0.5); @@ -165,7 +170,7 @@ void a2bus_ayboard_device::device_reset() read_cnxx - called for reads from this card's cnxx space -------------------------------------------------*/ -uint8_t a2bus_ayboard_device::read_cnxx(uint8_t offset) +u8 a2bus_ayboard_device::read_cnxx(u8 offset) { if (offset <= 0x7f) { @@ -179,9 +184,15 @@ uint8_t a2bus_ayboard_device::read_cnxx(uint8_t offset) return 0; } -uint8_t a2bus_phasor_device::read_cnxx(uint8_t offset) +u8 a2bus_echoplus_device::read_cnxx(u8 offset) { - uint8_t ret = 0; + m_last_cnxx_addr = offset; + return m_via1->read(offset & 0xf); +} + +u8 a2bus_phasor_device::read_cnxx(u8 offset) +{ + u8 ret = 0; int via_sel; if (m_native) @@ -212,7 +223,7 @@ uint8_t a2bus_phasor_device::read_cnxx(uint8_t offset) write_cnxx - called for writes to this card's c0nx space -------------------------------------------------*/ -void a2bus_ayboard_device::write_cnxx(uint8_t offset, uint8_t data) +void a2bus_ayboard_device::write_cnxx(u8 offset, u8 data) { // When the SSI-263 is emulated, Cn40 will write to both the VIA and // the first SSI-263, and Cn20 will write to both the VIA and the @@ -227,7 +238,13 @@ void a2bus_ayboard_device::write_cnxx(uint8_t offset, uint8_t data) } } -void a2bus_phasor_device::write_cnxx(uint8_t offset, uint8_t data) +void a2bus_echoplus_device::write_cnxx(u8 offset, u8 data) +{ + m_last_cnxx_addr = offset; + m_via1->write(offset & 0xf, data); +} + +void a2bus_phasor_device::write_cnxx(u8 offset, u8 data) { if ((offset < 0x20) || (offset >= 0x80 && offset < 0xa0)) { @@ -277,12 +294,12 @@ WRITE_LINE_MEMBER( a2bus_ayboard_device::via2_irq_w ) } } -void a2bus_ayboard_device::via1_out_a(uint8_t data) +void a2bus_ayboard_device::via1_out_a(u8 data) { m_porta1 = data; } -void a2bus_ayboard_device::via1_out_b(uint8_t data) +void a2bus_ayboard_device::via1_out_b(u8 data) { if (!BIT(data, 2)) { @@ -310,7 +327,65 @@ void a2bus_ayboard_device::via1_out_b(uint8_t data) } } -void a2bus_phasor_device::via1_out_b(uint8_t data) +void a2bus_echoplus_device::via1_out_b(u8 data) +{ + if (!(m_last_cnxx_addr & 0x80)) + { + if (!BIT(data, 2)) + { + m_ay1->reset_w(); + } + else + { + switch (data & 3) + { + case 0: // BDIR=0, BC1=0 (inactive) + break; + + case 1: // BDIR=0, BC1=1 (read PSG) + m_porta1 = m_ay1->data_r(); + break; + + case 2: // BDIR=1, BC1=0 (write PSG) + m_ay1->data_w(m_porta1); + break; + + case 3: // BDIR=1, BC1=1 (latch) + m_ay1->address_w(m_porta1); + break; + } + } + } + else + { + if (!BIT(data, 2)) + { + m_ay2->reset_w(); + } + else + { + switch (data & 3) + { + case 0: // BDIR=0, BC1=0 (inactive) + break; + + case 1: // BDIR=0, BC1=1 (read PSG) + m_porta1 = m_ay2->data_r(); + break; + + case 2: // BDIR=1, BC1=0 (write PSG) + m_ay2->data_w(m_porta1); + break; + + case 3: // BDIR=1, BC1=1 (latch) + m_ay2->address_w(m_porta1); + break; + } + } + } +} + +void a2bus_phasor_device::via1_out_b(u8 data) { if (!(data & 4)) { @@ -359,12 +434,12 @@ void a2bus_phasor_device::via1_out_b(uint8_t data) } } -void a2bus_ayboard_device::via2_out_a(uint8_t data) +void a2bus_ayboard_device::via2_out_a(u8 data) { m_porta2 = data; } -void a2bus_ayboard_device::via2_out_b(uint8_t data) +void a2bus_ayboard_device::via2_out_b(u8 data) { if (!BIT(data, 2)) { @@ -392,7 +467,7 @@ void a2bus_ayboard_device::via2_out_b(uint8_t data) } } -void a2bus_phasor_device::via2_out_b(uint8_t data) +void a2bus_phasor_device::via2_out_b(u8 data) { if (!BIT(data, 2)) { @@ -463,20 +538,20 @@ void a2bus_phasor_device::set_clocks() } } -uint8_t a2bus_phasor_device::read_c0nx(uint8_t offset) +u8 a2bus_phasor_device::read_c0nx(u8 offset) { m_native = BIT(offset, 0); set_clocks(); return 0xff; } -void a2bus_phasor_device::write_c0nx(uint8_t offset, uint8_t data) +void a2bus_phasor_device::write_c0nx(u8 offset, u8 data) { m_native = BIT(offset, 0); set_clocks(); } -uint8_t a2bus_echoplus_device::read_c0nx(uint8_t offset) +u8 a2bus_echoplus_device::read_c0nx(u8 offset) { switch (offset) { @@ -487,7 +562,7 @@ uint8_t a2bus_echoplus_device::read_c0nx(uint8_t offset) return 0; } -void a2bus_echoplus_device::write_c0nx(uint8_t offset, uint8_t data) +void a2bus_echoplus_device::write_c0nx(u8 offset, u8 data) { switch (offset) { @@ -513,7 +588,7 @@ WRITE_LINE_MEMBER( a2bus_mockingboard_device::write_via1_cb2 ) m_last_cb2_state = state; } -void a2bus_mockingboard_device::via1_out_b(uint8_t data) +void a2bus_mockingboard_device::via1_out_b(u8 data) { m_portb1 = data; diff --git a/src/devices/bus/a2bus/a2mockingboard.h b/src/devices/bus/a2bus/a2mockingboard.h index 44acff10006..539363c1f10 100644 --- a/src/devices/bus/a2bus/a2mockingboard.h +++ b/src/devices/bus/a2bus/a2mockingboard.h @@ -28,10 +28,12 @@ class a2bus_ayboard_device: public: DECLARE_WRITE_LINE_MEMBER( via1_irq_w ); DECLARE_WRITE_LINE_MEMBER( via2_irq_w ); - void via1_out_a(uint8_t data); - virtual void via1_out_b(uint8_t data); - void via2_out_a(uint8_t data); - virtual void via2_out_b(uint8_t data); + u8 via1_in_a() { return m_porta1; } + u8 via2_in_a() { return m_porta2; } + void via1_out_a(u8 data); + virtual void via1_out_b(u8 data); + void via2_out_a(u8 data); + virtual void via2_out_b(u8 data); protected: // construction/destruction @@ -42,20 +44,20 @@ protected: virtual void device_add_mconfig(machine_config &config) override; // overrides of standard a2bus slot functions - virtual uint8_t read_c0nx(uint8_t offset) override { return 0xff; } - virtual void write_c0nx(uint8_t offset, uint8_t data) override { } - virtual uint8_t read_cnxx(uint8_t offset) override; - virtual void write_cnxx(uint8_t offset, uint8_t data) override; + virtual u8 read_c0nx(u8 offset) override { return 0xff; } + virtual void write_c0nx(u8 offset, u8 data) override { } + virtual u8 read_cnxx(u8 offset) override; + virtual void write_cnxx(u8 offset, u8 data) override; void add_common_devices(machine_config &config); required_device<via6522_device> m_via1; - required_device<via6522_device> m_via2; + optional_device<via6522_device> m_via2; required_device<ay8913_device> m_ay1; required_device<ay8913_device> m_ay2; - uint8_t m_porta1; - uint8_t m_porta2; + u8 m_porta1; + u8 m_porta2; }; class a2bus_mockingboard_device : public a2bus_ayboard_device @@ -63,7 +65,7 @@ class a2bus_mockingboard_device : public a2bus_ayboard_device public: a2bus_mockingboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual void via1_out_b(uint8_t data) override; + virtual void via1_out_b(u8 data) override; protected: virtual void device_add_mconfig(machine_config &config) override; virtual void device_reset() override; @@ -73,7 +75,7 @@ protected: private: DECLARE_WRITE_LINE_MEMBER(write_via1_cb2); - uint8_t m_portb1; + u8 m_portb1; int m_last_cb2_state; }; @@ -82,16 +84,16 @@ class a2bus_phasor_device : public a2bus_ayboard_device public: a2bus_phasor_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - void via1_out_b(uint8_t data) override; - void via2_out_b(uint8_t data) override; + void via1_out_b(u8 data) override; + void via2_out_b(u8 data) override; protected: virtual void device_add_mconfig(machine_config &config) override; - virtual uint8_t read_c0nx(uint8_t offset) override; - virtual void write_c0nx(uint8_t offset, uint8_t data) override; - virtual uint8_t read_cnxx(uint8_t offset) override; - virtual void write_cnxx(uint8_t offset, uint8_t data) override; + virtual u8 read_c0nx(u8 offset) override; + virtual void write_c0nx(u8 offset, u8 data) override; + virtual u8 read_cnxx(u8 offset) override; + virtual void write_cnxx(u8 offset, u8 data) override; required_device<ay8913_device> m_ay3; required_device<ay8913_device> m_ay4; @@ -110,10 +112,17 @@ public: protected: virtual void device_add_mconfig(machine_config &config) override; - virtual uint8_t read_c0nx(uint8_t offset) override; - virtual void write_c0nx(uint8_t offset, uint8_t data) override; + virtual void via1_out_b(u8 data) override; + + virtual u8 read_c0nx(u8 offset) override; + virtual void write_c0nx(u8 offset, u8 data) override; + virtual u8 read_cnxx(u8 offset) override; + virtual void write_cnxx(u8 offset, u8 data) override; required_device<tms5220_device> m_tms; + +private: + u8 m_last_cnxx_addr; }; // device type definition diff --git a/src/devices/bus/a2bus/titan3plus2.cpp b/src/devices/bus/a2bus/titan3plus2.cpp new file mode 100644 index 00000000000..e04dc03448a --- /dev/null +++ b/src/devices/bus/a2bus/titan3plus2.cpp @@ -0,0 +1,334 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + titan3plus3.cpp + + Implemention of the Titan "/// Plus //"" card. + By R. Belmont, based on reverse-engineering by Rob Justice. + + This extends the Apple ///'s II emulation to include a 128K + extended language card and Apple II compatible game I/O. + + The card enables itself if the /// is at 1 MHz and accesses the + card's $CNxx ROM space. If the /// goes back to 2 MHz mode at + any time, the card disables itself. + + Address ranges this messes with: + $C05X - passed through to ///, but also used for annunciators on A2 gameio + $C06X - /// doesn't see when card enabled, A2 paddles + $C07X - passed through to ///, but also used for A2 paddle reset + $C08X - unused by /// (language card control) + $D000-$FFFF: usual (for A2) language card space. Not so usual for ///. + +*********************************************************************/ + +#include "emu.h" +#include "titan3plus2.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(A2BUS_TITAN3PLUS2, a2bus_titan3plus2_device, "titan3p2", "Titan /// Plus //") + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +void a2bus_titan3plus2_device::device_add_mconfig(machine_config &config) +{ + APPLE2_GAMEIO(config, m_gameio, apple2_gameio_device::default_options, nullptr); +} + +a2bus_titan3plus2_device::a2bus_titan3plus2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), device_a2bus_card_interface(mconfig, *this), + m_gameio(*this, "gameio"), + m_inh_state(0), m_last_offset(0), m_dxxx_bank(0), m_main_bank(0), m_enabled(false) +{ +} + +a2bus_titan3plus2_device::a2bus_titan3plus2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + a2bus_titan3plus2_device(mconfig, A2BUS_TITAN3PLUS2, tag, owner, clock) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a2bus_titan3plus2_device::device_start() +{ + memset(m_ram, 0, 128*1024); + + save_item(NAME(m_inh_state)); + save_item(NAME(m_ram)); + save_item(NAME(m_dxxx_bank)); + save_item(NAME(m_main_bank)); + save_item(NAME(m_last_offset)); + save_item(NAME(m_enabled)); + + m_x_calibration = m_y_calibration = attotime::from_nsec(10800).as_double(); +} + +void a2bus_titan3plus2_device::device_reset() +{ + m_inh_state = INH_NONE; + m_dxxx_bank = 0; + m_main_bank = 0; + m_last_offset = -1; +} + +void a2bus_titan3plus2_device::do_io(int offset) +{ + int old_inh_state = m_inh_state; + + switch (offset) + { + case 0x1: case 0x3: case 0x9: case 0xb: + if (offset != m_last_offset) + { + m_last_offset = offset; + return; + } + break; + } + m_last_offset = offset; + + if (offset & 4) + { + switch (offset) + { + case 0x4: m_main_bank = 0x00000; break; + case 0x5: m_main_bank = 0x04000; break; + case 0x6: m_main_bank = 0x08000; break; + case 0x7: m_main_bank = 0x0c000; break; + case 0xc: m_main_bank = 0x10000; break; + case 0xd: m_main_bank = 0x14000; break; + case 0xe: m_main_bank = 0x18000; break; + case 0xf: m_main_bank = 0x1c000; break; + } + } + else + { + m_inh_state = INH_NONE; + m_dxxx_bank = 0; + + if (offset & 0x1) + { + m_inh_state |= INH_WRITE; + } + + switch(offset & 0x03) + { + case 0x00: + case 0x03: + m_inh_state |= INH_READ; + break; + } + + if (!(offset & 8)) + { + m_dxxx_bank = 0x1000; + } + } + + if (m_inh_state != old_inh_state) + { + recalc_slot_inh(); + } + + #if 0 + printf("LC: (ofs %x) new state %c%c dxxx=%04x main=%05x\n", + offset, + (m_inh_state & INH_READ) ? 'R' : 'x', + (m_inh_state & INH_WRITE) ? 'W' : 'x', + m_dxxx_bank, m_main_bank); + #endif +} + + +/*------------------------------------------------- + read_c08x - called for reads from the LC switches +-------------------------------------------------*/ + +uint8_t a2bus_titan3plus2_device::read_c08x(uint8_t offset) +{ + if (!machine().side_effects_disabled()) + { + do_io(offset & 0xf); + } + return 0xff; +} + + +/*------------------------------------------------- + write_c0nx - called for writes to the LC switches +-------------------------------------------------*/ + +void a2bus_titan3plus2_device::write_c08x(uint8_t offset, uint8_t data) +{ + do_io(offset & 0xf); +} + +uint8_t a2bus_titan3plus2_device::read_inh_rom(uint16_t offset) +{ + if (offset < 0xd000) + { + if ((offset >= 0xc080) && (offset <= 0xc08f)) + { + return read_c08x(offset & 0xf); + } + + if ((offset >= 0xc060) && (offset <= 0xc06f)) + { + switch (offset & 0x7) + { + case 1: // button 0 + return (m_gameio->sw0_r() ? 0x80 : 0); + + case 2: // button 1 + return (m_gameio->sw1_r() ? 0x80 : 0); + + case 3: // button 2 + return (m_gameio->sw2_r() ? 0x80 : 0); + + case 4: // joy 1 X axis + if (!m_gameio->is_device_connected()) + return 0x80; + return ((machine().time().as_double() < m_joystick_x1_time) ? 0x80 : 0); + + case 5: // joy 1 Y axis + if (!m_gameio->is_device_connected()) + return 0x80; + return ((machine().time().as_double() < m_joystick_y1_time) ? 0x80 : 0); + + case 6: // joy 2 X axis + if (!m_gameio->is_device_connected()) + return 0x80; + return ((machine().time().as_double() < m_joystick_x2_time) ? 0x80 : 0); + + case 7: // joy 2 Y axis + if (!m_gameio->is_device_connected()) + return 0x80; + return ((machine().time().as_double() < m_joystick_y2_time) ? 0x80 : 0); + } + } + } + else + { + if (offset < 0xe000) + { + return m_ram[(offset & 0xfff) + m_dxxx_bank + m_main_bank]; + } + + return m_ram[(offset & 0x1fff) + 0x2000 + m_main_bank]; + } + + return 0xff; +} + +void a2bus_titan3plus2_device::write_inh_rom(uint16_t offset, uint8_t data) +{ + if (offset < 0xd000) + { + if ((offset >= 0xc080) && (offset <= 0xc08f)) + { + write_c08x(offset & 0xf, data); + return; + } + } + else + { + if (offset < 0xe000) + { + m_ram[(offset & 0xfff) + m_dxxx_bank + m_main_bank] = data; + return; + } + + m_ram[(offset & 0x1fff) + 0x2000 + m_main_bank] = data; + } +} + +u8 a2bus_titan3plus2_device::read_cnxx(u8 offset) +{ + m_enabled = true; + return 0xff; +} + +// returns if we want to /INH a read or write to a specific address +bool a2bus_titan3plus2_device::inh_check(u16 offset, bool bIsWrite) +{ + if (!m_enabled) + { + return false; + } + + // handle LC + if (offset >= 0xd000) + { + if ((bIsWrite) && (m_inh_state & INH_WRITE)) + { + return true; + } + + if (!(bIsWrite) && (m_inh_state & INH_READ)) + { + return true; + } + } + + if ((offset >= 0xc080) && (offset <= 0xc08f)) + { + return true; + } + + if ((offset >= 0xc070) && (offset <= 0xc07f)) + { + m_joystick_x1_time = machine().time().as_double() + m_x_calibration * m_gameio->pdl0_r(); + m_joystick_y1_time = machine().time().as_double() + m_y_calibration * m_gameio->pdl1_r(); + m_joystick_x2_time = machine().time().as_double() + m_x_calibration * m_gameio->pdl2_r(); + m_joystick_y2_time = machine().time().as_double() + m_y_calibration * m_gameio->pdl3_r(); + + return false; // Apple /// should still handle this + } + + if ((offset >= 0xc060) && (offset <= 0xc06f)) + { + return true; + } + + if ((offset >= 0xc058) && (offset <= 0xc05f)) + { + switch (offset & 0xf) + { + case 8: + case 9: + m_gameio->an0_w(offset & 1); + break; + case 0xa: + case 0xb: + m_gameio->an1_w(offset & 1); + break; + case 0xc: + case 0xd: + m_gameio->an2_w(offset & 1); + break; + case 0xe: + case 0xf: + m_gameio->an3_w(offset & 1); + break; + } + return false; // Apple /// should still see this + } + + return false; +} diff --git a/src/devices/bus/a2bus/titan3plus2.h b/src/devices/bus/a2bus/titan3plus2.h new file mode 100644 index 00000000000..f162f115d8e --- /dev/null +++ b/src/devices/bus/a2bus/titan3plus2.h @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + titan3plus2.h + + Implemention of the Titan /// Plus II card + +*********************************************************************/ + +#ifndef MAME_BUS_A2BUS_TITAN3PLUS2_H +#define MAME_BUS_A2BUS_TITAN3PLUS2_H + +#pragma once + +#include "a2bus.h" +#include "bus/a2gameio/gameio.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a2bus_titan3plus2_device: + public device_t, + public device_a2bus_card_interface +{ +public: + // construction/destruction + a2bus_titan3plus2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + a2bus_titan3plus2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + + // overrides of standard a2bus slot functions + virtual u8 read_inh_rom(u16 offset) override; + virtual void write_inh_rom(u16 offset, u8 data) override; + virtual bool inh_check(uint16_t offset, bool bIsWrite) override; + +private: + required_device<apple2_gameio_device> m_gameio; + + u8 read_c08x(u8 offset); + void write_c08x(u8 offset, u8 data); + u8 read_cnxx(u8 offset) override; + void do_io(int offset); + + int m_inh_state; + int m_last_offset; + int m_dxxx_bank; + int m_main_bank; + u8 m_ram[128*1024]; + bool m_enabled; + + double m_joystick_x1_time, m_joystick_y1_time, m_joystick_x2_time, m_joystick_y2_time, m_x_calibration, m_y_calibration; +}; + +// device type definition +DECLARE_DEVICE_TYPE(A2BUS_TITAN3PLUS2, a2bus_titan3plus2_device) + +#endif // MAME_BUS_A2BUS_TITAN3PLUS2_H diff --git a/src/devices/bus/adam/exp.h b/src/devices/bus/adam/exp.h index ee74bf0396a..d9e993c3a1f 100644 --- a/src/devices/bus/adam/exp.h +++ b/src/devices/bus/adam/exp.h @@ -15,14 +15,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define ADAM_LEFT_EXPANSION_SLOT_TAG "slot1" -#define ADAM_CENTER_EXPANSION_SLOT_TAG "slot2" -#define ADAM_RIGHT_EXPANSION_SLOT_TAG "slot3" - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/bw2/exp.h b/src/devices/bus/bw2/exp.h index dfb5924351b..6c6acf11f9a 100644 --- a/src/devices/bus/bw2/exp.h +++ b/src/devices/bus/bw2/exp.h @@ -43,13 +43,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define BW2_EXPANSION_SLOT_TAG "exp" - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/cbm2/exp.cpp b/src/devices/bus/cbm2/exp.cpp index a824ecd051e..cc0f3516bc5 100644 --- a/src/devices/bus/cbm2/exp.cpp +++ b/src/devices/bus/cbm2/exp.cpp @@ -76,15 +76,6 @@ cbm2_expansion_slot_device::cbm2_expansion_slot_device(const machine_config &mco void cbm2_expansion_slot_device::device_start() { m_card = get_card_device(); - - // inherit bus clock - // FIXME: this should be unnecessary as slots pass DERIVED_CLOCK(1, 1) through by default - if (clock() == 0) - { - cbm2_expansion_slot_device *root = machine().root_device().subdevice<cbm2_expansion_slot_device>(CBM2_EXPANSION_SLOT_TAG); - assert(root); - set_unscaled_clock(root->clock()); - } } diff --git a/src/devices/bus/cbm2/exp.h b/src/devices/bus/cbm2/exp.h index 9781e4ac05a..b9f967137ca 100644 --- a/src/devices/bus/cbm2/exp.h +++ b/src/devices/bus/cbm2/exp.h @@ -34,13 +34,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define CBM2_EXPANSION_SLOT_TAG "exp" - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/coco/coco_multi.cpp b/src/devices/bus/coco/coco_multi.cpp index 7006281286f..2061c905b3f 100644 --- a/src/devices/bus/coco/coco_multi.cpp +++ b/src/devices/bus/coco/coco_multi.cpp @@ -101,6 +101,8 @@ namespace INPUT_CHANGED_MEMBER( switch_changed ); protected: + coco_multipak_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + // device-level overrides virtual void device_start() override; virtual void device_reset() override; @@ -119,10 +121,12 @@ namespace virtual address_space &cartridge_space() override; virtual ioport_constructor device_input_ports() const override; - private: // device references required_device_array<cococart_slot_device, 4> m_slots; + void update_line(int slot_number, line ln); + + private: // internal state u8 m_select; u8 m_block; @@ -138,24 +142,24 @@ namespace void set_select(u8 new_select); u8 ff7f_read(); void ff7f_write(u8 data); - void update_line(int slot_number, line ln); - - DECLARE_WRITE_LINE_MEMBER(multi_slot1_cart_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot1_nmi_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot1_halt_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot2_cart_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot2_nmi_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot2_halt_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot3_cart_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot3_nmi_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot3_halt_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot4_cart_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot4_nmi_w); - DECLARE_WRITE_LINE_MEMBER(multi_slot4_halt_w); }; }; +// ======================> dragon_multipak_device + +class dragon_multipak_device : public coco_multipak_device +{ +public: + // construction/destruction + dragon_multipak_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; +}; + + /*************************************************************************** IMPLEMENTATION ***************************************************************************/ @@ -175,21 +179,54 @@ static void coco_cart_slot4(device_slot_interface &device) void coco_multipak_device::device_add_mconfig(machine_config &config) { COCOCART_SLOT(config, m_slots[0], DERIVED_CLOCK(1, 1), coco_cart_slot1_3, nullptr); - m_slots[0]->cart_callback().set(FUNC(coco_multipak_device::multi_slot1_cart_w)); - m_slots[0]->nmi_callback().set(FUNC(coco_multipak_device::multi_slot1_nmi_w)); - m_slots[0]->halt_callback().set(FUNC(coco_multipak_device::multi_slot1_halt_w)); + m_slots[0]->cart_callback().set([this](int state) { update_line(1, line::CART); }); + m_slots[0]->nmi_callback().set([this](int state) { update_line(1, line::NMI); }); + m_slots[0]->halt_callback().set([this](int state) { update_line(1, line::HALT); }); COCOCART_SLOT(config, m_slots[1], DERIVED_CLOCK(1, 1), coco_cart_slot1_3, nullptr); - m_slots[1]->cart_callback().set(FUNC(coco_multipak_device::multi_slot2_cart_w)); - m_slots[1]->nmi_callback().set(FUNC(coco_multipak_device::multi_slot2_nmi_w)); - m_slots[1]->halt_callback().set(FUNC(coco_multipak_device::multi_slot2_halt_w)); + m_slots[1]->cart_callback().set([this](int state) { update_line(2, line::CART); }); + m_slots[1]->nmi_callback().set([this](int state) { update_line(2, line::NMI); }); + m_slots[1]->halt_callback().set([this](int state) { update_line(2, line::HALT); }); COCOCART_SLOT(config, m_slots[2], DERIVED_CLOCK(1, 1), coco_cart_slot1_3, nullptr); - m_slots[2]->cart_callback().set(FUNC(coco_multipak_device::multi_slot3_cart_w)); - m_slots[2]->nmi_callback().set(FUNC(coco_multipak_device::multi_slot3_nmi_w)); - m_slots[2]->halt_callback().set(FUNC(coco_multipak_device::multi_slot3_halt_w)); + m_slots[2]->cart_callback().set([this](int state) { update_line(3, line::CART); }); + m_slots[2]->nmi_callback().set([this](int state) { update_line(3, line::NMI); }); + m_slots[2]->halt_callback().set([this](int state) { update_line(3, line::HALT); }); COCOCART_SLOT(config, m_slots[3], DERIVED_CLOCK(1, 1), coco_cart_slot4, "fdcv11"); - m_slots[3]->cart_callback().set(FUNC(coco_multipak_device::multi_slot4_cart_w)); - m_slots[3]->nmi_callback().set(FUNC(coco_multipak_device::multi_slot4_nmi_w)); - m_slots[3]->halt_callback().set(FUNC(coco_multipak_device::multi_slot4_halt_w)); + m_slots[3]->cart_callback().set([this](int state) { update_line(4, line::CART); }); + m_slots[3]->nmi_callback().set([this](int state) { update_line(4, line::NMI); }); + m_slots[3]->halt_callback().set([this](int state) { update_line(4, line::HALT); }); +} + + +static void dragon_cart_slot1_3(device_slot_interface &device) +{ + dragon_cart_add_basic_devices(device); +} + +static void dragon_cart_slot4(device_slot_interface &device) +{ + dragon_cart_add_basic_devices(device); + dragon_cart_add_fdcs(device); +} + + +void dragon_multipak_device::device_add_mconfig(machine_config &config) +{ + COCOCART_SLOT(config, m_slots[0], DERIVED_CLOCK(1, 1), dragon_cart_slot1_3, nullptr); + m_slots[0]->cart_callback().set([this](int state) { update_line(1, line::CART); }); + m_slots[0]->nmi_callback().set([this](int state) { update_line(1, line::NMI); }); + m_slots[0]->halt_callback().set([this](int state) { update_line(1, line::HALT); }); + COCOCART_SLOT(config, m_slots[1], DERIVED_CLOCK(1, 1), dragon_cart_slot1_3, nullptr); + m_slots[1]->cart_callback().set([this](int state) { update_line(2, line::CART); }); + m_slots[1]->nmi_callback().set([this](int state) { update_line(2, line::NMI); }); + m_slots[1]->halt_callback().set([this](int state) { update_line(2, line::HALT); }); + COCOCART_SLOT(config, m_slots[2], DERIVED_CLOCK(1, 1), dragon_cart_slot1_3, nullptr); + m_slots[2]->cart_callback().set([this](int state) { update_line(3, line::CART); }); + m_slots[2]->nmi_callback().set([this](int state) { update_line(3, line::NMI); }); + m_slots[2]->halt_callback().set([this](int state) { update_line(3, line::HALT); }); + COCOCART_SLOT(config, m_slots[3], DERIVED_CLOCK(1, 1), dragon_cart_slot4, "dragon_fdc"); + m_slots[3]->cart_callback().set([this](int state) { update_line(4, line::CART); }); + m_slots[3]->nmi_callback().set([this](int state) { update_line(4, line::NMI); }); + m_slots[3]->halt_callback().set([this](int state) { update_line(4, line::HALT); }); } INPUT_PORTS_START( coco_multipack ) @@ -206,6 +243,7 @@ INPUT_PORTS_END //************************************************************************** DEFINE_DEVICE_TYPE_PRIVATE(COCO_MULTIPAK, device_cococart_interface, coco_multipak_device, "coco_multipack", "CoCo Multi-Pak Interface") +DEFINE_DEVICE_TYPE_PRIVATE(DRAGON_MULTIPAK, device_cococart_interface, dragon_multipak_device, "dragon_multipack", "Dragon Multi-Pak Interface") @@ -226,13 +264,22 @@ ioport_constructor coco_multipak_device::device_input_ports() const // coco_multipak_device - constructor //------------------------------------------------- -coco_multipak_device::coco_multipak_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, COCO_MULTIPAK, tag, owner, clock) +coco_multipak_device::coco_multipak_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) , device_cococart_interface(mconfig, *this) , m_slots(*this, "slot%u", 1), m_select(0), m_block(0) { } +coco_multipak_device::coco_multipak_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_multipak_device(mconfig, COCO_MULTIPAK, tag, owner, clock) +{ +} + +dragon_multipak_device::dragon_multipak_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_multipak_device(mconfig, DRAGON_MULTIPAK, tag, owner, clock) +{ +} //------------------------------------------------- // device_start - device-specific startup @@ -486,24 +533,6 @@ void coco_multipak_device::scs_write(offs_t offset, u8 data) //------------------------------------------------- -// multiX_slotX_[cart|nmi|halt] trampolines -//------------------------------------------------- - -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot1_cart_w) { update_line(1, line::CART); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot1_nmi_w) { update_line(1, line::NMI); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot1_halt_w) { update_line(1, line::HALT); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot2_cart_w) { update_line(2, line::CART); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot2_nmi_w) { update_line(2, line::NMI); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot2_halt_w) { update_line(2, line::HALT); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot3_cart_w) { update_line(3, line::CART); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot3_nmi_w) { update_line(3, line::NMI); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot3_halt_w) { update_line(3, line::HALT); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot4_cart_w) { update_line(4, line::CART); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot4_nmi_w) { update_line(4, line::NMI); } -WRITE_LINE_MEMBER(coco_multipak_device::multi_slot4_halt_w) { update_line(4, line::HALT); } - - -//------------------------------------------------- // cartridge_space //------------------------------------------------- diff --git a/src/devices/bus/coco/coco_multi.h b/src/devices/bus/coco/coco_multi.h index eb66aee9660..94e9c6bbc05 100644 --- a/src/devices/bus/coco/coco_multi.h +++ b/src/devices/bus/coco/coco_multi.h @@ -9,5 +9,6 @@ // device type definition DECLARE_DEVICE_TYPE(COCO_MULTIPAK, device_cococart_interface) +DECLARE_DEVICE_TYPE(DRAGON_MULTIPAK, device_cococart_interface) #endif // MAME_BUS_COCO_COCO_MULTIPAK_H diff --git a/src/devices/bus/coco/coco_wpk.cpp b/src/devices/bus/coco/coco_wpk.cpp new file mode 100644 index 00000000000..8841c2960ea --- /dev/null +++ b/src/devices/bus/coco/coco_wpk.cpp @@ -0,0 +1,201 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + PBJ Word-Pak/Word-Pak II - 80 Column Video Cartridge + + TODO: + - the R6545 Transparent Mode used to update video RAM needs some attention. + - original PBJ WorkPak (not II or RS) had an optional Basic Driver ROM (undumped). + - does WordPak II use different character ROM? + +***************************************************************************/ + +#include "emu.h" +#include "coco_wpk.h" +#include "render.h" +#include "screen.h" + + +//------------------------------------------------- +// ROM( coco_wpk ) +//------------------------------------------------- + +ROM_START(coco_wpk) + ROM_REGION(0x0800, "chargen", 0) + ROM_LOAD("chr_gen_4.0.rom", 0x0000, 0x0800, CRC(6e9a671a) SHA1(0ff5fae512c7f1abe138504d51492404dd86be03)) // from PBJ WordPak RS +ROM_END + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(COCO_WPK, coco_wpk_device, "coco_wpk", "CoCo WordPak") +DEFINE_DEVICE_TYPE(COCO_WPK2, coco_wpk2_device, "coco_wpk2", "CoCo WordPak II") +DEFINE_DEVICE_TYPE(COCO_WPKRS, coco_wpkrs_device, "coco_wpkrs", "CoCo WordPak RS") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// coco_wpk_device - constructor +//------------------------------------------------- + +coco_wpk_device::coco_wpk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_cococart_interface(mconfig, *this ) + , m_crtc(*this, "crtc") + , m_palette(*this, "palette") + , m_chargen(*this, "chargen") + , m_video_addr(0) + , m_video_data(0) +{ +} + +coco_wpk_device::coco_wpk_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_wpk_device(mconfig, COCO_WPK, tag, owner, clock) +{ +} + +coco_wpk2_device::coco_wpk2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_wpk_device(mconfig, COCO_WPK2, tag, owner, clock) +{ +} + +coco_wpkrs_device::coco_wpkrs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : coco_wpk_device(mconfig, COCO_WPKRS, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void coco_wpk_device::device_start() +{ + m_video_ram = std::make_unique<u8[]>(0x800); + + save_pointer(NAME(m_video_ram), 0x800); + save_item(NAME(m_video_addr)); +} + +void coco_wpk2_device::device_start() +{ + coco_wpk_device::device_start(); +} + +void coco_wpkrs_device::device_start() +{ + coco_wpk_device::device_start(); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void coco_wpk_device::device_reset() +{ + install_readwrite_handler(0xff98, 0xff98, read8smo_delegate(*m_crtc, FUNC(r6545_1_device::status_r)), write8smo_delegate(*m_crtc, FUNC(r6545_1_device::address_w))); + install_readwrite_handler(0xff99, 0xff99, read8smo_delegate(*m_crtc, FUNC(r6545_1_device::register_r)), write8smo_delegate(*m_crtc, FUNC(r6545_1_device::register_w))); + install_write_handler(0xff9b, 0xff9b, write8smo_delegate(*this, FUNC(coco_wpkrs_device::crtc_display_w))); +} + +void coco_wpk2_device::device_reset() +{ + coco_wpk_device::device_reset(); + + install_write_handler(0xff9c, 0xff9c, write8smo_delegate(*this, FUNC(coco_wpk2_device::video_select_w))); + + machine().render().first_target()->set_view(0); +} + +void coco_wpkrs_device::device_reset() +{ + install_readwrite_handler(0xff76, 0xff76, read8smo_delegate(*m_crtc, FUNC(r6545_1_device::status_r)), write8smo_delegate(*m_crtc, FUNC(r6545_1_device::address_w))); + install_readwrite_handler(0xff77, 0xff77, read8smo_delegate(*m_crtc, FUNC(r6545_1_device::register_r)), write8smo_delegate(*m_crtc, FUNC(r6545_1_device::register_w))); + install_write_handler(0xff79, 0xff79, write8smo_delegate(*this, FUNC(coco_wpkrs_device::crtc_display_w))); +} + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void coco_wpk_device::device_add_mconfig(machine_config &config) +{ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(14.318181_MHz_XTAL, 896, 0, 640, 290, 0, 240); + screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + + PALETTE(config, m_palette, palette_device::MONOCHROME); + + R6545_1(config, m_crtc, 14.318181_MHz_XTAL / 8); + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_on_update_addr_change_callback(FUNC(coco_wpkrs_device::crtc_addr)); + m_crtc->set_update_row_callback(FUNC(coco_wpkrs_device::crtc_update_row)); +} + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *coco_wpk_device::device_rom_region() const +{ + return ROM_NAME( coco_wpk ); +} + + +void coco_wpk_device::crtc_display_w(u8 data) +{ + //logerror("crtc_display_w: %02x\n", data); + m_video_ram[m_video_addr] = data; + + m_crtc->register_r(); +} + + +MC6845_ON_UPDATE_ADDR_CHANGED(coco_wpk_device::crtc_addr) +{ + //logerror("crtc_addr: %04x %d\n", address, strobe); + m_video_addr = address; +} + + +MC6845_UPDATE_ROW(coco_wpk_device::crtc_update_row) +{ + u32 *p = &bitmap.pix(y); + + for (int column = 0; column < x_count; column++) + { + u8 code = m_video_ram[(ma + column) & 0x7ff]; + u16 addr = (code << 4) | (ra & 0x0f); + u8 data = m_chargen->base()[addr & 0x7ff]; + + if (column == cursor_x) + { + data = 0xff; + } + + for (int bit = 0; bit < 8; bit++) + { + *p++ = m_palette->pen(BIT(data, 0) && de); + + data >>= 1; + } + } +} + + +void coco_wpk2_device::video_select_w(u8 data) +{ + // software video switch (Word-Pak II only) + machine().render().first_target()->set_view(BIT(data, 6)); +} diff --git a/src/devices/bus/coco/coco_wpk.h b/src/devices/bus/coco/coco_wpk.h new file mode 100644 index 00000000000..65534dd3709 --- /dev/null +++ b/src/devices/bus/coco/coco_wpk.h @@ -0,0 +1,94 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +#ifndef MAME_BUS_COCO_COCO_WPK_H +#define MAME_BUS_COCO_COCO_WPK_H + +#pragma once + +#include "cococart.h" +#include "video/mc6845.h" +#include "emupal.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> coco_wpk_device + +class coco_wpk_device : + public device_t, + public device_cococart_interface +{ +public: + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + + // construction/destruction + coco_wpk_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // construction/destruction + coco_wpk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + required_device<r6545_1_device> m_crtc; + required_device<palette_device> m_palette; + required_memory_region m_chargen; + + u16 m_video_addr; + u8 m_video_data; + + std::unique_ptr<u8[]> m_video_ram; + + void crtc_display_w(u8 data); + MC6845_ON_UPDATE_ADDR_CHANGED(crtc_addr); + MC6845_UPDATE_ROW(crtc_update_row); +}; + + +// ======================> coco_wpk2_device + +class coco_wpk2_device : public coco_wpk_device +{ +public: + // construction/destruction + coco_wpk2_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_reset() override; + +private: + void video_select_w(u8 data); +}; + + +// ======================> coco_wpkrs_device + +class coco_wpkrs_device : public coco_wpk_device +{ +public: + // construction/destruction + coco_wpkrs_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_reset() override; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(COCO_WPK, coco_wpk_device) +DECLARE_DEVICE_TYPE(COCO_WPK2, coco_wpk2_device) +DECLARE_DEVICE_TYPE(COCO_WPKRS, coco_wpkrs_device) + +#endif // MAME_BUS_COCO_COCO_WPK_H diff --git a/src/devices/bus/coco/coco_wpk2p.cpp b/src/devices/bus/coco/coco_wpk2p.cpp new file mode 100644 index 00000000000..62fb2504bf7 --- /dev/null +++ b/src/devices/bus/coco/coco_wpk2p.cpp @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + CoCo WordPak 2+ + +***************************************************************************/ + +#include "emu.h" +#include "coco_wpk2p.h" +#include "screen.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(COCO_WPK2P, coco_wpk2p_device, "coco_wpk2p", "CoCo WordPak 2+") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// coco_wpk2p_device - constructor +//------------------------------------------------- + +coco_wpk2p_device::coco_wpk2p_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, COCO_WPK2P, tag, owner, clock) + , device_cococart_interface(mconfig, *this ) + , m_v9958(*this, "v9958") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void coco_wpk2p_device::device_start() +{ + install_readwrite_handler(0xff78, 0xff7b, read8sm_delegate(*m_v9958, FUNC(v9958_device::read)), write8sm_delegate(*m_v9958, FUNC(v9958_device::write))); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void coco_wpk2p_device::device_add_mconfig(machine_config &config) +{ + /* video hardware */ + V9958(config, m_v9958, 21.477272_MHz_XTAL); + m_v9958->set_screen_ntsc("screen"); + m_v9958->set_vram_size(0x20000); + m_v9958->int_cb().set([this](int state) { set_line_value(line::NMI, state); }); + SCREEN(config, "screen", SCREEN_TYPE_RASTER); +} diff --git a/src/devices/bus/coco/coco_wpk2p.h b/src/devices/bus/coco/coco_wpk2p.h new file mode 100644 index 00000000000..f6c3debc766 --- /dev/null +++ b/src/devices/bus/coco/coco_wpk2p.h @@ -0,0 +1,41 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +#ifndef MAME_BUS_COCO_COCO_WPK2P_H +#define MAME_BUS_COCO_COCO_WPK2P_H + +#pragma once + +#include "cococart.h" +#include "video/v9938.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> coco_wpk2p_device + +class coco_wpk2p_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + coco_wpk2p_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + +private: + required_device<v9958_device> m_v9958; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(COCO_WPK2P, coco_wpk2p_device) + +#endif // MAME_BUS_COCO_COCO_WPK2P_H diff --git a/src/devices/bus/coco/cococart.cpp b/src/devices/bus/coco/cococart.cpp index 8f733cd6c6a..28e97457114 100644 --- a/src/devices/bus/coco/cococart.cpp +++ b/src/devices/bus/coco/cococart.cpp @@ -54,6 +54,17 @@ #include "coco_ssc.h" #include "coco_stecomp.h" #include "coco_sym12.h" +#include "coco_wpk.h" +#include "coco_wpk2p.h" + +#include "dragon_amtor.h" +#include "dragon_claw.h" +#include "dragon_fdc.h" +#include "dragon_jcbsnd.h" +#include "dragon_jcbspch.h" +#include "dragon_msx2.h" +#include "dragon_serial.h" +#include "dragon_sprites.h" /*************************************************************************** @@ -702,12 +713,17 @@ void coco_cart_add_basic_devices(device_slot_interface &device) device.option_add("gmc", COCO_PAK_GMC); device.option_add("max", COCO_PAK_MAX); device.option_add("midi", COCO_MIDI); + device.option_add("msx2", DRAGON_MSX2); device.option_add("orch90", COCO_ORCH90); device.option_add("ram", COCO_PAK_RAM); device.option_add("rs232", COCO_RS232); device.option_add("ssc", COCO_SSC); device.option_add("stecomp", COCO_STEREO_COMPOSER); device.option_add("sym12", COCO_SYM12); + device.option_add("wpk", COCO_WPK); + device.option_add("wpk2", COCO_WPK2); + device.option_add("wpkrs", COCO_WPKRS); + device.option_add("wpk2p", COCO_WPK2P); } @@ -737,3 +753,52 @@ void coco_cart_add_multi_pak(device_slot_interface &device) // and the Multi-Pak itself is optional because they cannot be daisy chained device.option_add("multi", COCO_MULTIPAK); } + + +//------------------------------------------------- +// dragon_cart_add_basic_devices +//------------------------------------------------- + +void dragon_cart_add_basic_devices(device_slot_interface &device) +{ + device.option_add_internal("amtor", DRAGON_AMTOR); + device.option_add("ccpsg", COCO_PSG); + device.option_add("claw", DRAGON_CLAW); + device.option_add("gmc", COCO_PAK_GMC); + device.option_add("jcbsnd", DRAGON_JCBSND); + device.option_add("jcbspch", DRAGON_JCBSPCH); + device.option_add("max", COCO_PAK_MAX); + device.option_add("midi", DRAGON_MIDI); + device.option_add("msx2", DRAGON_MSX2); + device.option_add("orch90", COCO_ORCH90); + device.option_add("pak", COCO_PAK); + device.option_add("serial", DRAGON_SERIAL); + device.option_add("ram", COCO_PAK_RAM); + device.option_add("sprites", DRAGON_SPRITES); + device.option_add("ssc", COCO_SSC); + device.option_add("stecomp", COCO_STEREO_COMPOSER); + device.option_add("sym12", COCO_SYM12); + device.option_add("wpk2p", COCO_WPK2P); +} + + +//------------------------------------------------- +// dragon_cart_add_fdcs +//------------------------------------------------- + +void dragon_cart_add_fdcs(device_slot_interface &device) +{ + device.option_add("dragon_fdc", DRAGON_FDC); + device.option_add("premier_fdc", PREMIER_FDC); + device.option_add("sdtandy_fdc", SDTANDY_FDC); +} + + +//------------------------------------------------- +// dragon_cart_add_multi_pak +//------------------------------------------------- + +void dragon_cart_add_multi_pak(device_slot_interface &device) +{ + device.option_add("multi", DRAGON_MULTIPAK); +} diff --git a/src/devices/bus/coco/cococart.h b/src/devices/bus/coco/cococart.h index 78176588969..d2e33085956 100644 --- a/src/devices/bus/coco/cococart.h +++ b/src/devices/bus/coco/cococart.h @@ -231,5 +231,8 @@ private: void coco_cart_add_basic_devices(device_slot_interface &device); void coco_cart_add_fdcs(device_slot_interface &device); void coco_cart_add_multi_pak(device_slot_interface &device); +void dragon_cart_add_basic_devices(device_slot_interface &device); +void dragon_cart_add_fdcs(device_slot_interface &device); +void dragon_cart_add_multi_pak(device_slot_interface &device); #endif // MAME_BUS_COCO_COCOCART_H diff --git a/src/devices/bus/coco/dragon_claw.cpp b/src/devices/bus/coco/dragon_claw.cpp new file mode 100644 index 00000000000..a4c00b0f71a --- /dev/null +++ b/src/devices/bus/coco/dragon_claw.cpp @@ -0,0 +1,212 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + The Dragon's Claw from Lucidata + + http://archive.worldofdragon.org/index.php?title=The_Dragon%27s_Claw + + The Dragon's Claw is an extension cartridge for the Dragon by Lucidata. + It features two parallel I/O ports. One with the BBC User Port pinout, + and the second with a Centronics Printer Port pinout. + +***************************************************************************/ + +#include "emu.h" +#include "dragon_claw.h" +#include "bus/bbc/userport/userport.h" +#include "bus/centronics/ctronics.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE_PRIVATE(DRAGON_CLAW, device_cococart_interface, dragon_claw_device, "dragon_claw", "The Dragon's Claw") + +//------------------------------------------------- +// INPUT_PORTS( claw ) +//------------------------------------------------- + +INPUT_PORTS_START(claw) + PORT_START("LINKS") + PORT_CONFNAME(0x03, 0x00, "L1 Address Selection") + PORT_CONFSETTING(0x00, "$FF80") + PORT_CONFSETTING(0x01, "$FF90") + PORT_CONFSETTING(0x02, "$FFA0") + PORT_CONFSETTING(0x03, "$FFB0") + PORT_CONFNAME(0x04, 0x00, "L2 Interrupt Line") + PORT_CONFSETTING(0x00, "NMI") + PORT_CONFSETTING(0x04, "CART") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor dragon_claw_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(claw); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// dragon_claw_device - constructor +//------------------------------------------------- + +dragon_claw_device::dragon_claw_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, DRAGON_CLAW, tag, owner, clock) + , device_cococart_interface(mconfig, *this ) + , m_via(*this, "via") + , m_slot(*this, "slot") + , m_links(*this, "LINKS") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void dragon_claw_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void dragon_claw_device::device_reset() +{ + uint8_t addr = (m_links->read() & 0x03) << 8; + + install_readwrite_handler(0xff80 | addr, 0xff8f | addr, read8sm_delegate(*m_via, FUNC(via6522_device::read)), write8sm_delegate(*m_via, FUNC(via6522_device::write))); +} + +static void dragon_cart(device_slot_interface &device) +{ + dragon_cart_add_basic_devices(device); + dragon_cart_add_fdcs(device); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void dragon_claw_device::device_add_mconfig(machine_config &config) +{ + MOS6522(config, m_via, DERIVED_CLOCK(1, 1)); + m_via->writepa_handler().set("cent_data_out", FUNC(output_latch_device::write)); + m_via->readpb_handler().set("userport", FUNC(bbc_userport_slot_device::pb_r)); + m_via->writepb_handler().set("userport", FUNC(bbc_userport_slot_device::pb_w)); + m_via->ca2_handler().set("centronics", FUNC(centronics_device::write_strobe)); + m_via->cb1_handler().set("userport", FUNC(bbc_userport_slot_device::write_cb1)); + m_via->cb2_handler().set("userport", FUNC(bbc_userport_slot_device::write_cb2)); + m_via->irq_handler().set(FUNC(dragon_claw_device::irq_w)); // link L2 selects either NMI or CART line + + bbc_userport_slot_device &userport(BBC_USERPORT_SLOT(config, "userport", bbc_userport_devices, nullptr)); + userport.cb1_handler().set(m_via, FUNC(via6522_device::write_cb1)); + userport.cb2_handler().set(m_via, FUNC(via6522_device::write_cb2)); + + centronics_device ¢ronics(CENTRONICS(config, "centronics", centronics_devices, nullptr)); + centronics.ack_handler().set(m_via, FUNC(via6522_device::write_ca1)); + output_latch_device &latch(OUTPUT_LATCH(config, "cent_data_out")); + centronics.set_output_latch(latch); + + COCOCART_SLOT(config, m_slot, DERIVED_CLOCK(1, 1), dragon_cart, nullptr); + m_slot->cart_callback().set([this](int state) { set_line_value(line::CART, state); }); + m_slot->nmi_callback().set([this](int state) { set_line_value(line::NMI, state); }); + m_slot->halt_callback().set([this](int state) { set_line_value(line::HALT, state); }); +} + +WRITE_LINE_MEMBER(dragon_claw_device::irq_w) +{ + if (m_links->read() & 0x04) + set_line_value(line::CART, state); + else + set_line_value(line::NMI, state); +} + + +//------------------------------------------------- +// set_sound_enable +//------------------------------------------------- + +void dragon_claw_device::set_sound_enable(bool sound_enable) +{ + m_slot->set_line_value(line::SOUND_ENABLE, sound_enable ? line_value::ASSERT : line_value::CLEAR); +} + + +//------------------------------------------------- +// get_cart_base +//------------------------------------------------- + +u8 *dragon_claw_device::get_cart_base() +{ + return m_slot->get_cart_base(); +} + + +//------------------------------------------------- +// get_cart_size +//------------------------------------------------- + +u32 dragon_claw_device::get_cart_size() +{ + return m_slot->get_cart_size(); +} + + +//------------------------------------------------- +// cts_read +//------------------------------------------------- + +u8 dragon_claw_device::cts_read(offs_t offset) +{ + return m_slot->cts_read(offset); +} + + +//------------------------------------------------- +// cts_write +//------------------------------------------------- + +void dragon_claw_device::cts_write(offs_t offset, u8 data) +{ + m_slot->cts_write(offset, data); +} + + +//------------------------------------------------- +// scs_read +//------------------------------------------------- + +u8 dragon_claw_device::scs_read(offs_t offset) +{ + return m_slot->scs_read(offset); +} + + +//------------------------------------------------- +// scs_write +//------------------------------------------------- + +void dragon_claw_device::scs_write(offs_t offset, u8 data) +{ + m_slot->scs_write(offset, data); +} + + +//------------------------------------------------- +// cartridge_space +//------------------------------------------------- + +address_space &dragon_claw_device::cartridge_space() +{ + return device_cococart_interface::cartridge_space(); +} diff --git a/src/devices/bus/coco/dragon_claw.h b/src/devices/bus/coco/dragon_claw.h new file mode 100644 index 00000000000..9743b5b0b3c --- /dev/null +++ b/src/devices/bus/coco/dragon_claw.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +#ifndef MAME_BUS_COCO_DRAGON_CLAW_H +#define MAME_BUS_COCO_DRAGON_CLAW_H + +#pragma once + +#include "cococart.h" +#include "machine/6522via.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> dragon_claw_device + +class dragon_claw_device : + public device_t, + public device_cococart_interface, + public device_cococart_host_interface +{ +public: + // construction/destruction + dragon_claw_device(const machine_config& mconfig, const char* tag, device_t* owner, u32 clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config& config) override; + virtual ioport_constructor device_input_ports() const override; + + virtual u8 cts_read(offs_t offset) override; + virtual void cts_write(offs_t offset, u8 data) override; + virtual u8 scs_read(offs_t offset) override; + virtual void scs_write(offs_t offset, u8 data) override; + virtual void set_sound_enable(bool sound_enable) override; + + virtual u8 *get_cart_base() override; + virtual u32 get_cart_size() override; + + virtual address_space &cartridge_space() override; + +private: + DECLARE_WRITE_LINE_MEMBER(irq_w); + + required_device<via6522_device> m_via; + required_device<cococart_slot_device> m_slot; + required_ioport m_links; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(DRAGON_CLAW, device_cococart_interface) + +#endif // MAME_BUS_COCO_DRAGON_CLAW_H diff --git a/src/devices/bus/coco/dragon_msx2.cpp b/src/devices/bus/coco/dragon_msx2.cpp new file mode 100644 index 00000000000..9460b6955f3 --- /dev/null +++ b/src/devices/bus/coco/dragon_msx2.cpp @@ -0,0 +1,191 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +// thanks-to:John Whitworth +/*************************************************************************** + + Dragon MSX 2+ by DragonPlus Electronics + +***************************************************************************/ + +#include "emu.h" +#include "dragon_msx2.h" +#include "render.h" +#include "screen.h" +#include "speaker.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(DRAGON_MSX2, dragon_msx2_device, "dragon_msx2", "Dragon MSX 2+") + + +//------------------------------------------------- +// INPUT_PORTS( dragon_msx2 ) +//------------------------------------------------- + +INPUT_PORTS_START( dragon_msx2 ) + PORT_START("CONFIG") + PORT_CONFNAME(0x01, 0x00, "J1 PWR") + PORT_CONFSETTING(0x00, "Cart Port") + PORT_CONFSETTING(0x01, "External") + PORT_CONFNAME(0x02, 0x00, "J2 CART") + PORT_CONFSETTING(0x00, "N/C") + PORT_CONFSETTING(0x02, "HSYNC") + PORT_CONFNAME(0x04, 0x00, "J3 Port Select") + PORT_CONFSETTING(0x00, "FF7* (Native)") + PORT_CONFSETTING(0x04, "FF5* (MPI)") + PORT_CONFNAME(0x08, 0x08, "J4 Default Video") + PORT_CONFSETTING(0x00, "V9958") + PORT_CONFSETTING(0x08, "MC6847") + PORT_CONFNAME(0x10, 0x10, "J5 Video Lock") + PORT_CONFSETTING(0x00, "Locked") + PORT_CONFSETTING(0x10, "Unlocked") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor dragon_msx2_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( dragon_msx2 ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// dragon_msx2_device - constructor +//------------------------------------------------- + +dragon_msx2_device::dragon_msx2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, DRAGON_MSX2, tag, owner, clock) + , device_cococart_interface(mconfig, *this ) + , m_ym2413(*this, "ym2413") + , m_v9958(*this, "v9958") + , m_ym2149(*this, "ym2149") + , m_config(*this, "CONFIG") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void dragon_msx2_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void dragon_msx2_device::device_reset() +{ + // pin 26 is tied to GND + m_ym2149->set_pin26_low_w(); + + // Native mode + if (!BIT(m_config->read(), 2)) + { + install_readwrite_handler(0xff76, 0xff77, read8sm_delegate(*m_ym2413, FUNC(ym2413_device::read)), write8sm_delegate(*m_ym2413, FUNC(ym2413_device::write))); + install_readwrite_handler(0xff78, 0xff7b, read8sm_delegate(*m_v9958, FUNC(v9958_device::read)), write8sm_delegate(*m_v9958, FUNC(v9958_device::write))); + install_write_handler(0xff7c, 0xff7c, write8smo_delegate(*m_ym2149, FUNC(ym2149_device::address_w))); + install_readwrite_handler(0xff7d, 0xff7d, read8smo_delegate(*m_ym2149, FUNC(ym2149_device::data_r)), write8smo_delegate(*m_ym2149, FUNC(ym2149_device::data_w))); + install_write_handler(0xff7e, 0xff7e, write8smo_delegate(*this, FUNC(dragon_msx2_device::video_select_w))); + } + + // Default Video + machine().render().first_target()->set_view(!BIT(m_config->read(), 3)); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void dragon_msx2_device::device_add_mconfig(machine_config &config) +{ + V9958(config, m_v9958, 21.477272_MHz_XTAL); + m_v9958->set_screen_pal("screen"); + m_v9958->set_vram_size(0x20000); + m_v9958->int_cb().set([this](int state) { set_line_value(line::NMI, state); }); + SCREEN(config, "screen", SCREEN_TYPE_RASTER); + + SPEAKER(config, "speaker").front_center(); + YM2413(config, m_ym2413, 21.477272_MHz_XTAL / 6).add_route(ALL_OUTPUTS, "speaker", 1.0); + YM2149(config, m_ym2149, 21.477272_MHz_XTAL / 6).add_route(ALL_OUTPUTS, "speaker", 1.0); +} + + +//------------------------------------------------- +// scs_read +//------------------------------------------------- + +u8 dragon_msx2_device::scs_read(offs_t offset) +{ + u8 data = 0x00; + + if (BIT(m_config->read(), 2)) // MPI mode + { + switch (offset) + { + case 0x16: case 0x17: + data = m_ym2413->read(offset & 1); + break; + + case 0x18: case 0x19: case 0x1a: case 0x1b: + data = m_v9958->read(offset & 3); + break; + + case 0x1d: + data = m_ym2149->data_r(); + break; + } + } + + return data; +} + +//------------------------------------------------- +// scs_write +//------------------------------------------------- + +void dragon_msx2_device::scs_write(offs_t offset, u8 data) +{ + if (BIT(m_config->read(), 2)) // MPI mode + { + switch (offset) + { + case 0x16: case 0x17: + m_ym2413->write(offset & 1, data); + break; + + case 0x18: case 0x19: case 0x1a: case 0x1b: + m_v9958->write(offset & 3, data); + break; + + case 0x1c: + m_ym2149->address_w(data); + break; + + case 0x1d: + m_ym2149->data_w(data); + break; + + case 0x1e: + video_select_w(data); + break; + } + } +} + +void dragon_msx2_device::video_select_w(u8 data) +{ + if (BIT(m_config->read(), 4)) // Unlocked + machine().render().first_target()->set_view(!BIT(data, 0)); +} diff --git a/src/devices/bus/coco/dragon_msx2.h b/src/devices/bus/coco/dragon_msx2.h new file mode 100644 index 00000000000..3eb1fcaa64b --- /dev/null +++ b/src/devices/bus/coco/dragon_msx2.h @@ -0,0 +1,53 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +#ifndef MAME_BUS_COCO_DRAGON_MSX2_H +#define MAME_BUS_COCO_DRAGON_MSX2_H + +#pragma once + +#include "cococart.h" +#include "sound/ay8910.h" +#include "sound/ymopl.h" +#include "video/v9938.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> dragon_msx2_device + +class dragon_msx2_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + dragon_msx2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + + virtual u8 scs_read(offs_t offset) override; + virtual void scs_write(offs_t offset, u8 data) override; + +private: + required_device<ym2413_device> m_ym2413; + required_device<v9958_device> m_v9958; + required_device<ym2149_device> m_ym2149; + required_ioport m_config; + + void video_select_w(u8 data); +}; + + +// device type definition +DECLARE_DEVICE_TYPE(DRAGON_MSX2, dragon_msx2_device) + +#endif // MAME_BUS_COCO_DRAGON_MSX2_H diff --git a/src/devices/bus/coco/dragon_serial.cpp b/src/devices/bus/coco/dragon_serial.cpp new file mode 100644 index 00000000000..8967bed816c --- /dev/null +++ b/src/devices/bus/coco/dragon_serial.cpp @@ -0,0 +1,154 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Peaksoft Prestel Module + + Also known as the New Era Interface from Peaksoft/Harry Whitehouse, which + includes a through port for DOS cartridges. + + TODO: + - RX/TX rate set by dipswitches (default 100001/001001?), for use with a 1200/75 modem. + - add throughport, not known how CTS/SCS lines are switched between slots. + +***************************************************************************/ + +#include "emu.h" +#include "dragon_serial.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" + + +//------------------------------------------------- +// ROM( dragon_serial ) +//------------------------------------------------- + +ROM_START(dragon_serial) + ROM_REGION(0x2000, "eprom", 0) + ROM_LOAD("comron_peaksoft.rom", 0x0000, 0x2000, CRC(9d18cf46) SHA1(14124dfb4bd78d1907e80d779cd7f3bae30564c9)) +ROM_END + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(DRAGON_SERIAL, dragon_serial_device, "dragon_serial", "Dragon Peaksoft Prestel Module") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// dragon_serial_device - constructor +//------------------------------------------------- + +dragon_serial_device::dragon_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, DRAGON_SERIAL, tag, owner, clock) + , device_cococart_interface(mconfig, *this ) + , m_eprom(*this, "eprom") + , m_acia(*this, "acia") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void dragon_serial_device::device_start() +{ + set_line_value(line::CART, line_value::Q); +} + +//------------------------------------------------- +// dragon_serial_device::get_cart_base +//------------------------------------------------- + +u8 *dragon_serial_device::get_cart_base() +{ + return m_eprom->base(); +} + +//------------------------------------------------- +// dragon_serial_device::get_cart_memregion +//------------------------------------------------- + +memory_region *dragon_serial_device::get_cart_memregion() +{ + return m_eprom; +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void dragon_serial_device::device_add_mconfig(machine_config &config) +{ + ACIA6850(config, m_acia, 0); + m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); + m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); + m_acia->irq_handler().set([this](int state) { set_line_value(line::NMI, state); }); + + clock_device &acia_clock(CLOCK(config, "acia_clock", 2.4576_MHz_XTAL)); + acia_clock.signal_handler().set(FUNC(dragon_serial_device::write_acia_clock)); + + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "null_modem")); + rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd)); + rs232.cts_handler().set(m_acia, FUNC(acia6850_device::write_cts)); + rs232.dcd_handler().set(m_acia, FUNC(acia6850_device::write_dcd)); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *dragon_serial_device::device_rom_region() const +{ + return ROM_NAME( dragon_serial ); +} + +//------------------------------------------------- +// cts_read +//------------------------------------------------- + +u8 dragon_serial_device::cts_read(offs_t offset) +{ + return m_eprom->base()[offset & 0x1fff]; +} + +//------------------------------------------------- +// scs_read +//------------------------------------------------- + +u8 dragon_serial_device::scs_read(offs_t offset) +{ + uint8_t result = 0x00; + + switch (offset) + { + case 0x14: case 0x15: + result = m_acia->read(offset & 1); + break; + } + return result; +} + +//------------------------------------------------- +// scs_write +//------------------------------------------------- + +void dragon_serial_device::scs_write(offs_t offset, u8 data) +{ + switch (offset) + { + case 0x14: case 0x15: + m_acia->write(offset & 1, data); + break; + } +} + +WRITE_LINE_MEMBER(dragon_serial_device::write_acia_clock) +{ + m_acia->write_txc(state); + m_acia->write_rxc(state); +} diff --git a/src/devices/bus/coco/dragon_serial.h b/src/devices/bus/coco/dragon_serial.h new file mode 100644 index 00000000000..7f33a61de67 --- /dev/null +++ b/src/devices/bus/coco/dragon_serial.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +#ifndef MAME_BUS_COCO_DRAGON_SERIAL_H +#define MAME_BUS_COCO_DRAGON_SERIAL_H + +#pragma once + +#include "cococart.h" +#include "machine/6850acia.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> dragon_serial_device + +class dragon_serial_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + dragon_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + static constexpr feature_type imperfect_features() { return feature::COMMS; } + +protected: + // device-level overrides + virtual void device_start() override; + virtual u8 *get_cart_base() override; + virtual memory_region *get_cart_memregion() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual u8 cts_read(offs_t offset) override; + virtual u8 scs_read(offs_t offset) override; + virtual void scs_write(offs_t offset, u8 data) override; + +private: + DECLARE_WRITE_LINE_MEMBER(write_acia_clock); + + required_memory_region m_eprom; + required_device<acia6850_device> m_acia; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(DRAGON_SERIAL, dragon_serial_device) + +#endif // MAME_BUS_COCO_DRAGON_SERIAL_H diff --git a/src/devices/bus/generic/slot.h b/src/devices/bus/generic/slot.h index 883e521c908..ee96382f435 100644 --- a/src/devices/bus/generic/slot.h +++ b/src/devices/bus/generic/slot.h @@ -30,7 +30,7 @@ public: assert(!(decode_limit & base)); for (offs_t remain = length, start = 0U; remain && (decode_limit >= start); ) { - unsigned const msb(31 - count_leading_zeros(u32(remain))); + unsigned const msb(31 - count_leading_zeros_32(u32(remain))); offs_t const chunk(offs_t(1) << msb); offs_t range((chunk - 1) & decode_limit); offs_t mirror(decode_limit & ~decode_mask & ~range); diff --git a/src/devices/bus/isa/isa_cards.cpp b/src/devices/bus/isa/isa_cards.cpp index ce23388ea1d..cc00f2233e0 100644 --- a/src/devices/bus/isa/isa_cards.cpp +++ b/src/devices/bus/isa/isa_cards.cpp @@ -50,6 +50,7 @@ #include "tekram_dc820.h" #include "asc88.h" #include "omti8621.h" +#include "lrk330.h" // sound #include "adlib.h" @@ -230,4 +231,5 @@ void pc_isa16_cards(device_slot_interface &device) device.option_add("dc820", TEKRAM_DC820); // actually an EISA card device.option_add("dc820b", TEKRAM_DC820B); // actually an EISA card device.option_add("omti8621", ISA16_OMTI8621); + device.option_add("lrk331", LRK331); } diff --git a/src/devices/bus/isa/lrk330.cpp b/src/devices/bus/isa/lrk330.cpp new file mode 100644 index 00000000000..18cd1bfe29e --- /dev/null +++ b/src/devices/bus/isa/lrk330.cpp @@ -0,0 +1,130 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Skeleton driver for ESDI controllers by Lark Associates Inc. + + Major ICs excluding EPROMs, in order of decreasing pin count: + * Silicon Logic LD1111 HDC (QFP128, U1) + * Xilinx XC2018-70PC68C Logic Cell Array (PLCC84, U11) + * National DP8473V Floppy Disk Controller PLUS-2 (PLCC52, U4) + * Signetics SCN8032HCCA44 8-Bit Microcontroller (PLCC44, U20) + * Sharp LH52258D-45 32Kx8 CMOS Static RAM (SDIP28, U2 & U3) + * Vitelic V61C16F70L 2Kx8 CMOS Static RAM (SSOP24, U19) + + The purpose of the small SRAM is not clear. Perhaps it can be banked + into the lower part of the 8032 program space after loading patches + for the EPROM microcode, since that uses the upper mirror addresses + almost exclusively. + + A transfer rate of up to 24 megabits per second was advertised. + + LRK-330 is presumably identical to LRK-331, only without the FDC or + 34-pin floppy drive cable connector installed. + +***************************************************************************/ + +#include "emu.h" +#include "lrk330.h" + +#include "imagedev/floppy.h" +#include "machine/upd765.h" + +// device type definition +DEFINE_DEVICE_TYPE(LRK331, lrk331_device, "lrk331", "Lark Associates LRK-331 ESDI Controller") + + +lrk331_device::lrk331_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, LRK331, tag, owner, clock) + , device_isa16_card_interface(mconfig, *this) + , m_mcu(*this, "mcu") + , m_bios(*this, "bios") + , m_config(*this, "CONFIG") +{ +} + +void lrk331_device::device_start() +{ +} + +void lrk331_device::device_reset() +{ +} + +void lrk331_device::ucode_map(address_map &map) +{ + map(0x0000, 0x3fff).mirror(0x4000).rom().region("ucode", 0); +} + +void lrk331_device::ext_map(address_map &map) +{ + map.global_mask(0xff); + map(0x0b, 0x0b).nopw(); +} + +static INPUT_PORTS_START(lrk331) + PORT_START("CONFIG") + PORT_DIPNAME(0x001, 0x001, "Drive Addresses") PORT_DIPLOCATION("W1:1") + PORT_DIPSETTING(0x001, "Primary (1F0h-1F7h, 3F0h-3F7h)") + PORT_DIPSETTING(0x000, "Secondary (170h-177h, 370h-377h)") + PORT_DIPNAME(0x002, 0x002, "Floppy Drive Speed") PORT_DIPLOCATION("W2:2") + PORT_DIPSETTING(0x002, "Single") + PORT_DIPSETTING(0x000, "Dual") + PORT_DIPNAME(0x004, 0x004, "Interrupt Delay") PORT_DIPLOCATION("W3:1") + PORT_DIPSETTING(0x004, "Disabled") + PORT_DIPSETTING(0x000, "Enabled") + PORT_DIPNAME(0x008, 0x008, "Factory Configured - Do Not Alter") PORT_DIPLOCATION("W4:1") + PORT_DIPSETTING(0x008, DEF_STR(Off)) + PORT_DIPSETTING(0x000, DEF_STR(On)) + PORT_DIPNAME(0x0f0, 0x0e0, "BIOS Address") PORT_DIPLOCATION("W5-W8:1,2,3,4") + PORT_DIPSETTING(0x0f0, "Disabled") + PORT_DIPSETTING(0x0e0, "C800h") + PORT_DIPSETTING(0x0d0, "CC00h") + PORT_DIPSETTING(0x0b0, "D000h") + PORT_DIPSETTING(0x070, "D400h") + PORT_DIPNAME(0x300, 0x200, "IRQ Select") PORT_DIPLOCATION("W9-W10:1,2") + PORT_DIPSETTING(0x200, "IRQ 14") + PORT_DIPSETTING(0x100, "IRQ 15") + PORT_DIPNAME(0x400, 0x000, "Floppy Drive Interface") PORT_DIPLOCATION("W11:1") + PORT_DIPSETTING(0x400, "Disabled") + PORT_DIPSETTING(0x000, "Enabled") +INPUT_PORTS_END + +ioport_constructor lrk331_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(lrk331); +} + +static void pc_hd_floppies(device_slot_interface &device) +{ + device.option_add("525hd", FLOPPY_525_HD); + device.option_add("35hd", FLOPPY_35_HD); + device.option_add("525dd", FLOPPY_525_DD); + device.option_add("35dd", FLOPPY_35_DD); +} + +void lrk331_device::device_add_mconfig(machine_config &config) +{ + I8032(config, m_mcu, 24_MHz_XTAL / 2); + m_mcu->set_addrmap(AS_PROGRAM, &lrk331_device::ucode_map); + m_mcu->set_addrmap(AS_IO, &lrk331_device::ext_map); + + //LD1111(config, m_hdc, 24_MHz_XTAL); + + DP8473(config, "fdc", 24_MHz_XTAL); + FLOPPY_CONNECTOR(config, "fdc:0", pc_hd_floppies, "525hd", floppy_image_device::default_pc_floppy_formats); + FLOPPY_CONNECTOR(config, "fdc:1", pc_hd_floppies, nullptr, floppy_image_device::default_pc_floppy_formats); +} + +ROM_START(lrk331) + ROM_REGION(0x2000, "bios", 0) + ROM_LOAD("63308-10.bin", 0x0000, 0x2000, CRC(f16d4f25) SHA1(437664ff9723c8036a40f1e504899b7cacd21ad0)) + + ROM_REGION(0x4000, "ucode", 0) + ROM_LOAD("63307-08.bin", 0x0000, 0x4000, CRC(6d2e8b26) SHA1(1a33462a29b306b01960cf2ac0b209b2adf58dbe)) +ROM_END + +const tiny_rom_entry *lrk331_device::device_rom_region() const +{ + return ROM_NAME(lrk331); +} diff --git a/src/devices/bus/isa/lrk330.h b/src/devices/bus/isa/lrk330.h new file mode 100644 index 00000000000..b75a50fa7a3 --- /dev/null +++ b/src/devices/bus/isa/lrk330.h @@ -0,0 +1,38 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_BUS_ISA_LRK330_H +#define MAME_BUS_ISA_LRK330_H + +#pragma once + +#include "isa.h" +#include "cpu/mcs51/mcs51.h" + +class lrk331_device : public device_t, public device_isa16_card_interface +{ +public: + lrk331_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + static constexpr feature_type unemulated_features() { return feature::DISK; } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual ioport_constructor device_input_ports() const override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + +private: + void ucode_map(address_map &map); + void ext_map(address_map &map); + + required_device<mcs51_cpu_device> m_mcu; + required_region_ptr<u8> m_bios; + required_ioport m_config; +}; + +DECLARE_DEVICE_TYPE(LRK331, lrk331_device) + +#endif // MAME_BUS_ISA_LRK330_H diff --git a/src/devices/bus/mc10/mc10_cart.cpp b/src/devices/bus/mc10/mc10_cart.cpp new file mode 100644 index 00000000000..f7858a087bc --- /dev/null +++ b/src/devices/bus/mc10/mc10_cart.cpp @@ -0,0 +1,230 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/********************************************************************* + + mc10cart.cpp + + MC-10 / Alice expansion slot - typically used for the 16K external + RAM expansion. + + MC-10 and Alice pinout listing + --- ------- --- ------- + 1 GND 18 A6 + 2 GND 19 A7 + 3 D0 20 A8 + 4 D1 21 A9 + 5 D2 22 A10 + 6 D3 23 A11 + 7 D4 24 A12 + 8 D5 25 A13 + 9 D6 26 A14 + 10 D7 27 A15 + 11 R/!W 28 E + 12 A0 29 SEL + 13 A1 30 RESET + 14 A2 31 !NMI + 15 A3 32 +5V + 16 A3 33 GND + 17 A5 34 GND + + SEL is an input to the MC-10 that allows the cartridge to remove + the internal chips from the bus. + +*********************************************************************/ + +#include "emu.h" +#include "mc10_cart.h" + +#include "mcx128.h" +#include "pak.h" +#include "ram.h" + +//#define VERBOSE 1 +#include "logmacro.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(MC10CART_SLOT, mc10cart_slot_device, "mc10cart_slot", "MC-10 Cartridge Slot") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// mc10cart_slot_device - constructor +//------------------------------------------------- +mc10cart_slot_device::mc10cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, MC10CART_SLOT, tag, owner, clock), + device_single_card_slot_interface<device_mc10cart_interface>(mconfig, *this), + device_image_interface(mconfig, *this), + m_nmi_callback(*this), + m_cart(nullptr), + m_memspace(*this, finder_base::DUMMY_TAG, -1) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc10cart_slot_device::device_start() +{ + m_nmi_callback.resolve_safe(); + m_cart = get_card_device(); +} + +//------------------------------------------------- +// set_nmi_line +//------------------------------------------------- + +void mc10cart_slot_device::set_nmi_line(int state) +{ + m_nmi_callback(state); +} + +//------------------------------------------------- +// call_load +//------------------------------------------------- + +image_init_result mc10cart_slot_device::call_load() +{ + if (!m_cart) + return image_init_result::PASS; + + memory_region *romregion(loaded_through_softlist() ? memregion("rom") : nullptr); + if (loaded_through_softlist() && !romregion) + { + seterror(IMAGE_ERROR_INVALIDIMAGE, "Software list item has no 'rom' data area"); + return image_init_result::FAIL; + } + + u32 const len(loaded_through_softlist() ? romregion->bytes() : length()); + if (len > m_cart->max_rom_length()) + { + seterror(IMAGE_ERROR_UNSUPPORTED, "Unsupported cartridge size"); + return image_init_result::FAIL; + } + + if (!loaded_through_softlist()) + { + LOG("Allocating %u byte cartridge ROM region\n", len); + romregion = machine().memory().region_alloc(subtag("rom").c_str(), len, 1, ENDIANNESS_BIG); + u32 const cnt(fread(romregion->base(), len)); + if (cnt != len) + { + seterror(IMAGE_ERROR_UNSPECIFIED, "Error reading cartridge file"); + return image_init_result::FAIL; + } + } + + return m_cart->load(); +} + +//------------------------------------------------- +// get_default_card_software +//------------------------------------------------- + +std::string mc10cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const +{ + return software_get_default_slot("pak"); +} + +//************************************************************************** +// DEVICE MC-10 CART INTERFACE - Implemented by devices that plug into +// MC-10 cartridge slots +//************************************************************************** + +template class device_finder<device_mc10cart_interface, false>; +template class device_finder<device_mc10cart_interface, true>; + +//------------------------------------------------- +// device_mc10cart_interface - constructor +//------------------------------------------------- + +device_mc10cart_interface::device_mc10cart_interface(const machine_config &mconfig, device_t &device) + : device_interface(device, "mc10cart") + , m_owning_slot(nullptr) +{ +} + +//------------------------------------------------- +// ~device_mc10cart_interface - destructor +//------------------------------------------------- + +device_mc10cart_interface::~device_mc10cart_interface() +{ +} + +//------------------------------------------------- +// interface_config_complete +//------------------------------------------------- + +void device_mc10cart_interface::interface_config_complete() +{ + m_owning_slot = dynamic_cast<mc10cart_slot_device *>(device().owner()); +} + +//------------------------------------------------- +// interface_pre_start +//------------------------------------------------- + +void device_mc10cart_interface::interface_pre_start() +{ + if (!m_owning_slot) + throw emu_fatalerror("Expected device().owner() to be of type mc10cart_slot_device"); +} + +/*------------------------------------------------- + max_rom_length +-------------------------------------------------*/ + +int device_mc10cart_interface::max_rom_length() const +{ + return 0; +} + +/*------------------------------------------------- + load +-------------------------------------------------*/ + +image_init_result device_mc10cart_interface::load() +{ + return image_init_result::FAIL; +} + +//------------------------------------------------- +// mc10_cart_add_basic_devices +//------------------------------------------------- + +void mc10_cart_add_basic_devices(device_slot_interface &device) +{ + // basic devices + device.option_add("mcx128", MC10_PAK_MCX128); + device.option_add("pak", MC10_PAK); + device.option_add("ram", MC10_PAK_RAM); +} + +//------------------------------------------------- +// alice_cart_add_basic_devices +//------------------------------------------------- + +void alice_cart_add_basic_devices(device_slot_interface &device) +{ + // basic devices + device.option_add("alice128", ALICE_PAK_MCX128); + device.option_add("pak", MC10_PAK); + device.option_add("ram", MC10_PAK_RAM); +} + +//------------------------------------------------- +// alice32_cart_add_basic_devices +//------------------------------------------------- + +void alice32_cart_add_basic_devices(device_slot_interface &device) +{ + // basic devices + device.option_add("pak", MC10_PAK); + device.option_add("ram", MC10_PAK_RAM); +} diff --git a/src/devices/bus/mc10/mc10_cart.h b/src/devices/bus/mc10/mc10_cart.h new file mode 100644 index 00000000000..eba93284325 --- /dev/null +++ b/src/devices/bus/mc10/mc10_cart.h @@ -0,0 +1,118 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/********************************************************************* + + mc10_cart.h + + MC-10 / Alice cartridge management + +*********************************************************************/ + +#ifndef MAME_BUS_MC10_MC10CART_H +#define MAME_BUS_MC10_MC10CART_H + +#pragma once + +#include "softlist_dev.h" + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + + +// ======================> mc10cart_slot_device +class device_mc10cart_interface; + +class mc10cart_slot_device final : public device_t, + public device_single_card_slot_interface<device_mc10cart_interface>, + public device_image_interface +{ +public: + + // construction/destruction + template <typename T> + mc10cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&opts, const char *dflt) + : mc10cart_slot_device(mconfig, tag, owner, clock) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(false); + } + + mc10cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // inline configuration + template <typename T> void set_memspace(T &&tag, int spacenum) { m_memspace.set_tag(std::forward<T>(tag), spacenum); } + auto nmi_callback() { return m_nmi_callback.bind(); } + + // address map manipulations + address_space &memspace() const { return *m_memspace; }; + + // device-level overrides + virtual void device_start() override; + + // image-level overrides + virtual image_init_result call_load() override; + virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); } + + virtual iodevice_t image_type() const noexcept override { return IO_CARTSLOT; } + + virtual bool is_readable() const noexcept override { return true; } + virtual bool is_writeable() const noexcept override { return false; } + virtual bool is_creatable() const noexcept override { return false; } + virtual bool must_be_loaded() const noexcept override { return false; } + virtual bool is_reset_on_load() const noexcept override { return true; } + virtual const char *image_interface() const noexcept override { return "mc10_cart"; } + virtual const char *file_extensions() const noexcept override { return "mcc,rom"; } + + // manipulation of nmi line + void set_nmi_line(int state); + devcb_write_line m_nmi_callback; + + // slot interface overrides + virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override; + +private: + + // cartridge + device_mc10cart_interface *m_cart; + +protected: + required_address_space m_memspace; +}; + +// device type definition +DECLARE_DEVICE_TYPE(MC10CART_SLOT, mc10cart_slot_device) + +class device_mc10cart_interface : public device_interface +{ +public: + // construction/destruction + virtual ~device_mc10cart_interface(); + + virtual int max_rom_length() const; + virtual image_init_result load(); + +protected: + void raise_cart_nmi() { m_owning_slot->set_nmi_line(ASSERT_LINE); } + void lower_cart_nmi() { m_owning_slot->set_nmi_line(CLEAR_LINE); } + + virtual void interface_config_complete() override; + virtual void interface_pre_start() override; + + device_mc10cart_interface(const machine_config &mconfig, device_t &device); + + // accessors for containers + mc10cart_slot_device &owning_slot() const { assert(m_owning_slot); return *m_owning_slot; } + +private: + mc10cart_slot_device * m_owning_slot; +}; + +// methods for configuring MC-10 slot devices +void mc10_cart_add_basic_devices(device_slot_interface &device); +void alice_cart_add_basic_devices(device_slot_interface &device); +void alice32_cart_add_basic_devices(device_slot_interface &device); + +#endif // MAME_BUS_MC10_MC10CART_H diff --git a/src/devices/bus/mc10/mcx128.cpp b/src/devices/bus/mc10/mcx128.cpp new file mode 100644 index 00000000000..32c9239afb5 --- /dev/null +++ b/src/devices/bus/mc10/mcx128.cpp @@ -0,0 +1,371 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/*************************************************************************** + + mcx128.cpp + + Code for emulating Darren Atkinson's MCX-128 cartridge + + Features: + 128K of RAM expansion + 16K of ROM expansion + + New MC-10 memory map defined by this cartridge: + + 0000 - 0003 6803 Ports + 0004 - 0007 Expansion RAM + 0008 - 000E 6803 Status / Control + 000F Expansion RAM + 0010 - 0013 6803 UART + 0014 6803 RAM Control Reg + 0015 - 001F Unused + 0020 - 007F Expansion RAM + 0080 - 00FF On-chip CPU RAM / Expansion RAM + 0100 - 3FFF Expansion RAM + 4000 - 5FFF Built-In RAM / Expansion RAM + 6000 - BEFF Expansion RAM + BF00 RAM Bank Control Reg + BF01 ROM Map Control Reg + BF80 - BFFF Keyboard / VDG / Sound + C000 - DFFF EPROM or Expansion RAM + E000 - FFFF Built-in ROM, EPROM or Expansion RAM + + Deficiency: + + * Writing to 6803 chip RAM at $80 to $ff should be mirrored + to external RAM. + +***************************************************************************/ + +#include "emu.h" +#include "mcx128.h" + +//#define VERBOSE (LOG_GENERAL) +#include "logmacro.h" + + +ROM_START(mc10_mcx128) + ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) + ROM_LOAD("mcx128bas.rom", 0x0000, 0x4000, CRC(11202e4b) SHA1(36c30d0f198a1bffee88ef29d92f2401447a91f4)) +ROM_END + +ROM_START(alice_mcx128) + ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) + ROM_LOAD("alice128bas.rom", 0x0000, 0x4000, CRC(a737544a) SHA1(c8fd92705fc42deb6a0ffac6274e27fd61ecd4cc)) +ROM_END + +//************************************************************************** +// TYPE DECLARATIONS +//************************************************************************** + +// ======================> mc10_pak_device + +class mc10_pak_mcx128_device : + public device_t, + public device_mc10cart_interface +{ +public: + // construction/destruction + mc10_pak_mcx128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // construction/destruction + mc10_pak_mcx128_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_post_load() override; + + virtual const tiny_rom_entry *device_rom_region() const override + { + return ROM_NAME(mc10_mcx128); + } + + u8 control_register_read(offs_t offset); + void control_register_write(offs_t offset, u8 data); + + void write_ram_mirror(address_space &space, offs_t offset, u8 data); + + void view_map0(address_map &map); + void view_map1(address_map &map); + void view_map2(address_map &map); + void view_map3(address_map &map); + void view_map4(address_map &map); + void view_map5(address_map &map); + void view_map6(address_map &map); + void view_map7(address_map &map); + + +private: + memory_share_creator<u8> m_share; + memory_view m_view; + memory_bank_array_creator<8> m_bank; + uint8_t ram_bank_cr; + uint8_t rom_map_cr; + + void update_banks(); + +}; + +DEFINE_DEVICE_TYPE_PRIVATE(MC10_PAK_MCX128, device_mc10cart_interface, mc10_pak_mcx128_device, "mc10_mcx128", "Darren Atkinson's MCX-128 cartridge") + +//------------------------------------------------- +// mc10_pak_device - constructor +//------------------------------------------------- + +mc10_pak_mcx128_device::mc10_pak_mcx128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + :mc10_pak_mcx128_device(mconfig, MC10_PAK_MCX128, tag, owner, clock) +{ +} + +mc10_pak_mcx128_device::mc10_pak_mcx128_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_mc10cart_interface(mconfig, *this) + , m_share(*this, "ext_ram", 1024*128, ENDIANNESS_BIG) + , m_view(*this, "mcx_view") + , m_bank(*this, "bank%u", 0U) +{ +} + +void mc10_pak_mcx128_device::view_map0(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0x5fff).bankr("bank3").w(FUNC(mc10_pak_mcx128_device::write_ram_mirror)); + map(0x6000, 0xbeff).bankrw("bank4"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xfeff).rom().region("eprom",0x0000).bankw("bank5"); + map(0xff00, 0xffff).rom().region("eprom",0x3f00).bankw("bank7"); +} + +void mc10_pak_mcx128_device::view_map1(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0x5fff).bankr("bank3").w(FUNC(mc10_pak_mcx128_device::write_ram_mirror)); + map(0x6000, 0xbeff).bankrw("bank4"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xdfff).bankrw("bank5"); + map(0xe000, 0xfeff).rom().region("eprom",0x2000).bankw("bank6"); + map(0xff00, 0xffff).rom().region("eprom",0x3f00).bankw("bank7"); +} + +void mc10_pak_mcx128_device::view_map2(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0x5fff).bankr("bank3").w(FUNC(mc10_pak_mcx128_device::write_ram_mirror)); + map(0x6000, 0xbeff).bankrw("bank4"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xdfff).bankrw("bank5"); + map(0xe000, 0xfeff).bankw("bank6"); + map(0xff00, 0xffff).bankw("bank7"); +// 0xe000, 0xffff: read internal ROM +} + +void mc10_pak_mcx128_device::view_map3(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0x5fff).bankr("bank3").w(FUNC(mc10_pak_mcx128_device::write_ram_mirror)); + map(0x6000, 0xbeff).bankrw("bank4"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xfeff).bankrw("bank5"); + map(0xff00, 0xffff).bankrw("bank7"); +} + +void mc10_pak_mcx128_device::view_map4(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0xbeff).bankrw("bank3"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xfeff).rom().region("eprom",0x0000).bankw("bank5"); + map(0xff00, 0xffff).rom().region("eprom",0x3f00).bankw("bank7"); +} + +void mc10_pak_mcx128_device::view_map5(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0xbeff).bankrw("bank3"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xdfff).bankrw("bank5"); + map(0xe000, 0xfeff).rom().region("eprom",0x2000).bankw("bank6"); + map(0xff00, 0xffff).rom().region("eprom",0x3f00).bankw("bank7"); +} + +void mc10_pak_mcx128_device::view_map6(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0xbeff).bankrw("bank3"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xdfff).bankrw("bank5"); + map(0xe000, 0xfeff).bankw("bank6"); + map(0xff00, 0xffff).bankw("bank7"); +// 0xe000, 0xffff: read internal ROM +} + +void mc10_pak_mcx128_device::view_map7(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0xbeff).bankrw("bank3"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xfeff).bankrw("bank5"); + map(0xff00, 0xffff).bankrw("bank7"); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc10_pak_mcx128_device::device_start() +{ + save_item(NAME(ram_bank_cr)); + save_item(NAME(rom_map_cr)); + + // 0x0004 - 0x0007 + m_bank[0]->configure_entry(0, &m_share[0x00004]); + m_bank[0]->configure_entry(1, &m_share[0x10004]); + + // 0x000f - 0x000f + m_bank[1]->configure_entry(0, &m_share[0x0000f]); + m_bank[1]->configure_entry(1, &m_share[0x1000f]); + + // 0x0000 - 0x3fff + m_bank[2]->configure_entry(0, &m_share[0x00020]); + m_bank[2]->configure_entry(1, &m_share[0x10020]); + + // 0x4000 - 0x5fff + m_bank[3]->configure_entry(0, &m_share[0x08000]); + m_bank[3]->configure_entry(1, &m_share[0x18000]); + + // 0x6000 - 0xbeff + m_bank[4]->configure_entry(0, &m_share[0x0a000]); + m_bank[4]->configure_entry(1, &m_share[0x1a000]); + + // 0xc000 - 0xdfff + m_bank[5]->configure_entry(0, &m_share[0x04000]); + m_bank[5]->configure_entry(1, &m_share[0x14000]); + + // 0xe000 - 0xffff + m_bank[6]->configure_entry(0, &m_share[0x06000]); + m_bank[6]->configure_entry(1, &m_share[0x16000]); + + // 0xff00 - 0xffff + m_bank[7]->configure_entry(0, &m_share[0x07f00]); + m_bank[7]->configure_entry(1, &m_share[0x07f00]); + + owning_slot().memspace().install_view(0x0000, 0xffff, m_view); + + m_view[0].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map0); + m_view[1].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map1); + m_view[2].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map2); + m_view[3].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map3); + m_view[4].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map4); + m_view[5].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map5); + m_view[6].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map6); + m_view[7].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map7); +} + +//------------------------------------------------- +// device_reset - device-specific startup +//------------------------------------------------- + +void mc10_pak_mcx128_device::device_reset() +{ + ram_bank_cr = 0; + rom_map_cr = 0; + update_banks(); +} + +void mc10_pak_mcx128_device::device_post_load() +{ + update_banks(); +} + +void mc10_pak_mcx128_device::write_ram_mirror(address_space &space, offs_t offset, u8 data) +{ + std::optional<int> cur_slot = m_view.entry(); + m_share[0x08000+offset] = data; + + if (cur_slot.has_value()) + { + int cur_slot_int = *cur_slot; + m_view.disable(); + space.write_byte(0x4000+offset, data); + m_view.select(cur_slot_int); + } +} + +u8 mc10_pak_mcx128_device::control_register_read(offs_t offset) +{ + if (offset==0) + return ram_bank_cr & 0x03; + + return rom_map_cr & 0x03; +} + +void mc10_pak_mcx128_device::control_register_write(offs_t offset, u8 data) +{ + if (offset==0) + ram_bank_cr = data; + else + rom_map_cr = data; + + update_banks(); +} + +void mc10_pak_mcx128_device::update_banks() +{ + int bank0 = ram_bank_cr & 0x01; + int bank1 = (ram_bank_cr & 0x02) >> 1; + + m_bank[0]->set_entry(bank0); + m_bank[1]->set_entry(bank0); + m_bank[2]->set_entry(bank0); + m_bank[3]->set_entry(bank1); + m_bank[4]->set_entry(bank1); + m_bank[5]->set_entry(bank0); + m_bank[6]->set_entry(bank0); + m_bank[7]->set_entry(bank0); + + m_view.select((bank1 << 2) | (rom_map_cr & 0x03)); + LOG("view select: %d, bank cr: %d\n", (bank1 << 2) | (rom_map_cr & 0x03), ram_bank_cr & 0x03 ); +} + +class alice_pak_mcx128_device : public mc10_pak_mcx128_device +{ +public: + // construction/destruction + alice_pak_mcx128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device-level overrides + virtual const tiny_rom_entry *device_rom_region() const override + { + return ROM_NAME(alice_mcx128); + } +}; + +//------------------------------------------------- +// mc10_pak_device - constructor +//------------------------------------------------- + +alice_pak_mcx128_device::alice_pak_mcx128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : mc10_pak_mcx128_device(mconfig, ALICE_PAK_MCX128, tag, owner, clock) +{ +} + +DEFINE_DEVICE_TYPE_PRIVATE(ALICE_PAK_MCX128, device_mc10cart_interface, alice_pak_mcx128_device, "alice_mcx128", "Darren Atkinson's MCX-128 cartridge (Alice ROM)") diff --git a/src/devices/bus/mc10/mcx128.h b/src/devices/bus/mc10/mcx128.h new file mode 100644 index 00000000000..29ae63b64e2 --- /dev/null +++ b/src/devices/bus/mc10/mcx128.h @@ -0,0 +1,15 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +#ifndef MAME_BUS_MC10_MC10_MCX128_H +#define MAME_BUS_MC10_MC10_MCX128_H + +#pragma once + +#include "mc10_cart.h" + +// device type definition +DECLARE_DEVICE_TYPE(MC10_PAK_MCX128, device_mc10cart_interface) +DECLARE_DEVICE_TYPE(ALICE_PAK_MCX128, device_mc10cart_interface) + +#endif // MAME_BUS_MC10_MC10_MCX128_H + diff --git a/src/devices/bus/mc10/pak.cpp b/src/devices/bus/mc10/pak.cpp new file mode 100644 index 00000000000..8e27d58ab8b --- /dev/null +++ b/src/devices/bus/mc10/pak.cpp @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/*************************************************************************** + + pak.cpp + + Code for emulating standard MC-10 cartridges with only ROM + +***************************************************************************/ + +#include "emu.h" +#include "pak.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(MC10_PAK, mc10_pak_device, "mc10pak", "MC-10 Program PAK") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// mc10_pak_device - constructor +//------------------------------------------------- +mc10_pak_device::mc10_pak_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_mc10cart_interface(mconfig, *this) +{ +} + +mc10_pak_device::mc10_pak_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : mc10_pak_device(mconfig, MC10_PAK, tag, owner, clock) +{ +} + +//------------------------------------------------- +// max_rom_length - device-specific startup +//------------------------------------------------- + +int mc10_pak_device::max_rom_length() const +{ + return 1024 * 16; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc10_pak_device::device_start() +{ +} + +//------------------------------------------------- +// load - install rom region +//------------------------------------------------- + +image_init_result mc10_pak_device::load() +{ + // if the host has supplied a ROM space, install it + memory_region *const romregion(memregion("^rom")); + if (romregion) + owning_slot().memspace().install_rom(0x5000, 0x5000 + romregion->bytes(), romregion->base()); + else + return image_init_result::FAIL; + + return image_init_result::PASS; +} diff --git a/src/devices/bus/mc10/pak.h b/src/devices/bus/mc10/pak.h new file mode 100644 index 00000000000..797cea2f691 --- /dev/null +++ b/src/devices/bus/mc10/pak.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +#ifndef MAME_BUS_MC10_MC10_PAK_H +#define MAME_BUS_MC10_MC10_PAK_H + +#pragma once + +#include "mc10_cart.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> mc10_pak_device + +class mc10_pak_device : + public device_t, + public device_mc10cart_interface +{ +public: + // construction/destruction + mc10_pak_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual int max_rom_length() const override; + virtual image_init_result load() override; + +protected: + mc10_pak_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; +}; + +// device type definitions +DECLARE_DEVICE_TYPE(MC10_PAK, mc10_pak_device) + +#endif // MAME_BUS_MC10_MC10_PAK_H diff --git a/src/devices/bus/mc10/ram.cpp b/src/devices/bus/mc10/ram.cpp new file mode 100644 index 00000000000..f6a6f488955 --- /dev/null +++ b/src/devices/bus/mc10/ram.cpp @@ -0,0 +1,78 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/*************************************************************************** + + ram.cpp + + Code for emulating the Radio Shack 16K RAM Cartridge + +***************************************************************************/ + +#include "emu.h" +#include "ram.h" + +// #include "machine/ram.h" + +// #define VERBOSE (LOG_GENERAL ) +#include "logmacro.h" + + +//************************************************************************** +// TYPE DECLARATIONS +//************************************************************************** + +namespace +{ + // ======================> mc10_pak_device + + class mc10_pak_ram_device : + public device_t, + public device_mc10cart_interface + { + public: + // construction/destruction + mc10_pak_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + protected: + // device-level overrides + virtual void device_start() override; + private: + memory_share_creator<u8> m_share; + }; +}; + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE_PRIVATE(MC10_PAK_RAM, device_mc10cart_interface, mc10_pak_ram_device, "mc10pakram", "Radio Shack 16K RAM Cartridge") + + + +//------------------------------------------------- +// mc10_pak_device - constructor +//------------------------------------------------- + +mc10_pak_ram_device::mc10_pak_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, MC10_PAK_RAM, tag, owner, clock) + , device_mc10cart_interface(mconfig, *this) + , m_share(*this, "ext_ram", 1024*16, ENDIANNESS_BIG) +{ +} + + + +//************************************************************************** +// MACHINE FRAGMENTS AND ADDRESS MAPS +//************************************************************************** + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc10_pak_ram_device::device_start() +{ + owning_slot().memspace().install_ram(0x5000, 0x8fff, &m_share[0]); +} diff --git a/src/devices/bus/mc10/ram.h b/src/devices/bus/mc10/ram.h new file mode 100644 index 00000000000..e32530f81e6 --- /dev/null +++ b/src/devices/bus/mc10/ram.h @@ -0,0 +1,14 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +#ifndef MAME_BUS_MC10_MC10_RAM_H +#define MAME_BUS_MC10_MC10_RAM_H + +#pragma once + +#include "mc10_cart.h" + +// device type definition +DECLARE_DEVICE_TYPE(MC10_PAK_RAM, device_mc10cart_interface) + +#endif // MAME_BUS_MC10_MC10_RAM_H + diff --git a/src/devices/bus/nes/act53.cpp b/src/devices/bus/nes/act53.cpp index 2a441c36153..0576f36a06c 100644 --- a/src/devices/bus/nes/act53.cpp +++ b/src/devices/bus/nes/act53.cpp @@ -32,7 +32,7 @@ DEFINE_DEVICE_TYPE(NES_ACTION53, nes_action53_device, "nes_action53", "NES Cart Action 53 PCB") -nes_action53_device::nes_action53_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nes_action53_device::nes_action53_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : nes_nrom_device(mconfig, NES_ACTION53, tag, owner, clock) , m_sel(0) { @@ -45,17 +45,21 @@ void nes_action53_device::device_start() common_start(); save_item(NAME(m_sel)); save_item(NAME(m_reg)); - m_reg[0] = 0x00; - m_reg[1] = 0x0f; - m_reg[2] = 0x00; - m_reg[3] = 0x3f; +} + +void nes_action53_device::pcb_start(running_machine &machine, u8 *ciram_ptr, bool cart_mounted) +{ + device_nes_cart_interface::pcb_start(machine, ciram_ptr, cart_mounted); + // at power on last 16K of ROM is mapped to $C000-$FFFF + m_reg[0] = m_reg[1] = m_reg[2] = 0; + m_reg[3] = (m_prg_chunks - 1) >> 1; + update_prg(); } void nes_action53_device::pcb_reset() { m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; // register content is not touched by reset - update_prg(); } @@ -79,7 +83,7 @@ void nes_action53_device::pcb_reset() R:$80 is clear R:$01: [...M PPPP] - P = PRG Reg + P = Inner PRG Reg M = Mirroring This bit overwrites bit 0 of R:$80, but only if bit 1 of R:$80 is clear @@ -97,7 +101,7 @@ void nes_action53_device::pcb_reset() %10 = Vert %11 = Horz - R:$81: [..BB BBBB] + R:$81: [BBBB BBBB] Outer PRG Reg @@ -105,34 +109,20 @@ void nes_action53_device::pcb_reset() void nes_action53_device::update_prg() { - uint8_t prg_lo, prg_hi, helper; - uint8_t out = (m_reg[3] & 0x3f) << 1; // Outer PRG reg - uint8_t size = (m_reg[2] & 0x30) >> 4; // Game size - uint8_t mask = (1 << (size + 1)) - 1; // Bits to be taken from PRG reg - - if (!BIT(m_reg[2], 3)) - { - helper = (out & ~mask) | ((m_reg[1] << 1) & mask); - //32K mode - prg_lo = (helper & 0xfe); - prg_hi = (helper | 0x01); - } - else - { - helper = (out & ~mask) | (m_reg[1] & mask); - if (BIT(m_reg[2], 2)) - { - //16K mode with fixed HI - prg_lo = helper; - prg_hi = (out | 0x01); - } - else - { - //16K mode with fixed LO - prg_lo = (out & 0xfe); - prg_hi = helper; - } - } + u16 prg_lo, prg_hi; + u8 size = (m_reg[2] & 0x30) >> 4; // Game size + u16 mask = ~0 << (size + 1); // Bits to be taken from PRG regs + u8 b32k = !BIT(m_reg[2], 3); // 32K mode bit + u16 outer = m_reg[3] << 1; // Outer PRG reg bits + u8 inner = (m_reg[1] << b32k) & ~mask; // Inner PRG reg bits + + prg_hi = prg_lo = (outer & mask) | inner; + if (b32k) // 32K mode + prg_hi++; + else if (BIT(m_reg[2], 2)) // 16K mode with fixed HI + prg_hi = ++outer; + else // 16K mode with fixed LO + prg_lo = outer; // printf("banks : 0x%2X - 0x%2X\n", prg_lo, prg_hi); prg16_89ab(prg_lo); @@ -158,7 +148,7 @@ void nes_action53_device::update_mirr() } } -void nes_action53_device::write_l(offs_t offset, uint8_t data) +void nes_action53_device::write_l(offs_t offset, u8 data) { LOG_MMC(("action 53 write_l, offset: %04x, data: %02x\n", offset, data)); offset += 0x100; @@ -167,7 +157,7 @@ void nes_action53_device::write_l(offs_t offset, uint8_t data) } -void nes_action53_device::write_h(offs_t offset, uint8_t data) +void nes_action53_device::write_h(offs_t offset, u8 data) { LOG_MMC(("action 53 write_h, offset: %04x, data: %02x\n", offset, data)); diff --git a/src/devices/bus/nes/act53.h b/src/devices/bus/nes/act53.h index 8e4b1c3b073..ead18a54ad6 100644 --- a/src/devices/bus/nes/act53.h +++ b/src/devices/bus/nes/act53.h @@ -12,12 +12,13 @@ class nes_action53_device : public nes_nrom_device { public: // construction/destruction - nes_action53_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + nes_action53_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - virtual void write_l(offs_t offset, uint8_t data) override; - virtual void write_h(offs_t offset, uint8_t data) override; + virtual void write_l(offs_t offset, u8 data) override; + virtual void write_h(offs_t offset, u8 data) override; virtual void pcb_reset() override; + virtual void pcb_start(running_machine &machine, u8 *ciram_ptr, bool cart_mounted) override; protected: // device-level overrides @@ -26,8 +27,8 @@ protected: private: void update_prg(); void update_mirr(); - uint8_t m_sel; - uint8_t m_reg[4]; + u8 m_sel; + u8 m_reg[4]; }; // device type definition diff --git a/src/devices/bus/nes/nes_slot.h b/src/devices/bus/nes/nes_slot.h index acdfed33164..a207a26e869 100644 --- a/src/devices/bus/nes/nes_slot.h +++ b/src/devices/bus/nes/nes_slot.h @@ -237,9 +237,9 @@ protected: device_nes_cart_interface(const machine_config &mconfig, device_t &device); DECLARE_WRITE_LINE_MEMBER(set_irq_line); - void hold_irq_line(); + [[deprecated("IRQs should be cleared explicitly")]] void hold_irq_line(); void reset_cpu(); - void poke(offs_t offset, uint8_t data); + [[deprecated("devices should stop poking into memory spaces where they don't belong")]] void poke(offs_t offset, uint8_t data); // internal state uint8_t *m_prg; diff --git a/src/devices/bus/newbrain/eim.cpp b/src/devices/bus/newbrain/eim.cpp index be3cae2e615..7b3685eeea7 100644 --- a/src/devices/bus/newbrain/eim.cpp +++ b/src/devices/bus/newbrain/eim.cpp @@ -113,7 +113,7 @@ newbrain_eim_device::newbrain_eim_device(const machine_config &mconfig, const ch device_newbrain_expansion_slot_interface(mconfig, *this), m_ctc(*this, Z80CTC_TAG), m_acia(*this, MC6850_TAG), - m_exp(*this, NEWBRAIN_EXPANSION_SLOT_TAG), + m_exp(*this, "exp"), m_rom(*this, "eim"), m_ram(*this, RAM_TAG) { diff --git a/src/devices/bus/newbrain/exp.h b/src/devices/bus/newbrain/exp.h index e8293a9c540..922ef17213a 100644 --- a/src/devices/bus/newbrain/exp.h +++ b/src/devices/bus/newbrain/exp.h @@ -43,13 +43,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define NEWBRAIN_EXPANSION_SLOT_TAG "exp" - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/newbrain/fdc.cpp b/src/devices/bus/newbrain/fdc.cpp index a356d034a39..fa046e0d5a9 100644 --- a/src/devices/bus/newbrain/fdc.cpp +++ b/src/devices/bus/newbrain/fdc.cpp @@ -135,11 +135,8 @@ newbrain_fdc_device::newbrain_fdc_device(const machine_config &mconfig, const ch device_newbrain_expansion_slot_interface(mconfig, *this), m_maincpu(*this, Z80_TAG), m_fdc(*this, UPD765_TAG), - m_floppy0(*this, UPD765_TAG ":0"), - m_floppy1(*this, UPD765_TAG ":1"), - m_floppy2(*this, UPD765_TAG ":2"), - m_floppy3(*this, UPD765_TAG ":3"), - m_exp(*this, NEWBRAIN_EXPANSION_SLOT_TAG) + m_floppy(*this, UPD765_TAG ":%u", 0U), + m_exp(*this, "exp") { } @@ -224,10 +221,9 @@ void newbrain_fdc_device::iorq_w(offs_t offset, uint8_t data, bool &prtov) void newbrain_fdc_device::moton(int state) { - if (m_floppy0->get_device()) m_floppy0->get_device()->mon_w(!state); - if (m_floppy1->get_device()) m_floppy1->get_device()->mon_w(!state); - if (m_floppy2->get_device()) m_floppy2->get_device()->mon_w(!state); - if (m_floppy3->get_device()) m_floppy3->get_device()->mon_w(!state); + for (auto &floppy : m_floppy) + if (floppy->get_device()) + floppy->get_device()->mon_w(!state); } diff --git a/src/devices/bus/newbrain/fdc.h b/src/devices/bus/newbrain/fdc.h index e5d6665a078..3ac24faffa6 100644 --- a/src/devices/bus/newbrain/fdc.h +++ b/src/devices/bus/newbrain/fdc.h @@ -57,10 +57,7 @@ private: required_device<z80_device> m_maincpu; required_device<upd765a_device> m_fdc; - required_device<floppy_connector> m_floppy0; - required_device<floppy_connector> m_floppy1; - required_device<floppy_connector> m_floppy2; - required_device<floppy_connector> m_floppy3; + required_device_array<floppy_connector, 4> m_floppy; required_device<newbrain_expansion_slot_device> m_exp; void moton(int state); diff --git a/src/devices/bus/odyssey2/rom.cpp b/src/devices/bus/odyssey2/rom.cpp index 20b04256d00..b964d99b584 100644 --- a/src/devices/bus/odyssey2/rom.cpp +++ b/src/devices/bus/odyssey2/rom.cpp @@ -28,7 +28,7 @@ void o2_rom_device::device_start() void o2_rom_device::cart_init() { - m_cart_mask = (1 << (31 - count_leading_zeros(m_rom_size))) - 1; + m_cart_mask = (1 << (31 - count_leading_zeros_32(m_rom_size))) - 1; } diff --git a/src/devices/bus/pet/exp.h b/src/devices/bus/pet/exp.h index d3adf1e9262..14fe9296a8d 100644 --- a/src/devices/bus/pet/exp.h +++ b/src/devices/bus/pet/exp.h @@ -17,13 +17,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define PET_EXPANSION_SLOT_TAG "exp" - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/plus4/c1551.cpp b/src/devices/bus/plus4/c1551.cpp index 5811f7b42f7..b8ecd0b7642 100644 --- a/src/devices/bus/plus4/c1551.cpp +++ b/src/devices/bus/plus4/c1551.cpp @@ -368,7 +368,7 @@ void c1551_device::device_add_mconfig(machine_config &config) connector.set_fixed(true); connector.set_formats(c1551_device::floppy_formats); - PLUS4_EXPANSION_SLOT(config, m_exp, 0); + PLUS4_EXPANSION_SLOT(config, m_exp, DERIVED_CLOCK(1, 1)); m_exp->irq_wr_callback().set(DEVICE_SELF_OWNER, FUNC(plus4_expansion_slot_device::irq_w)); m_exp->cd_rd_callback().set(DEVICE_SELF_OWNER, FUNC(plus4_expansion_slot_device::dma_cd_r)); m_exp->cd_wr_callback().set(DEVICE_SELF_OWNER, FUNC(plus4_expansion_slot_device::dma_cd_w)); @@ -417,7 +417,7 @@ c1551_device::c1551_device(const machine_config &mconfig, const char *tag, devic , m_ga(*this, C64H156_TAG) , m_pla(*this, PLA_TAG) , m_floppy(*this, C64H156_TAG":0:525ssqd") - , m_exp(*this, PLUS4_EXPANSION_SLOT_TAG) + , m_exp(*this, "exp") , m_jp1(*this, "JP1") , m_leds(*this, "led%u", 0U) , m_tcbm_data(0xff) diff --git a/src/devices/bus/plus4/exp.cpp b/src/devices/bus/plus4/exp.cpp index 4099b38d5bd..fb0387908ef 100644 --- a/src/devices/bus/plus4/exp.cpp +++ b/src/devices/bus/plus4/exp.cpp @@ -90,15 +90,6 @@ void plus4_expansion_slot_device::device_start() m_read_dma_cd.resolve_safe(0xff); m_write_dma_cd.resolve_safe(); m_write_aec.resolve_safe(); - - // inherit bus clock - // FIXME: this should be unnecessary as slots pass DERIVED_CLOCK(1, 1) through by default - if (clock() == 0) - { - plus4_expansion_slot_device *root = machine().root_device().subdevice<plus4_expansion_slot_device>(PLUS4_EXPANSION_SLOT_TAG); - assert(root); - set_unscaled_clock(root->clock()); - } } diff --git a/src/devices/bus/plus4/exp.h b/src/devices/bus/plus4/exp.h index fb03fb7fd4b..785207dd4f1 100644 --- a/src/devices/bus/plus4/exp.h +++ b/src/devices/bus/plus4/exp.h @@ -43,13 +43,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define PLUS4_EXPANSION_SLOT_TAG "exp" - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/pofo/exp.h b/src/devices/bus/pofo/exp.h index f760ce694c3..4078535e2c7 100644 --- a/src/devices/bus/pofo/exp.h +++ b/src/devices/bus/pofo/exp.h @@ -48,13 +48,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define PORTFOLIO_EXPANSION_SLOT_TAG "exp" - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/pofo/hpc104.cpp b/src/devices/bus/pofo/hpc104.cpp index 11744206c7e..0d8953b20c6 100644 --- a/src/devices/bus/pofo/hpc104.cpp +++ b/src/devices/bus/pofo/hpc104.cpp @@ -100,7 +100,7 @@ pofo_hpc104_device::pofo_hpc104_device(const machine_config &mconfig, device_typ device_portfolio_expansion_slot_interface(mconfig, *this), device_nvram_interface(mconfig, *this), m_ccm(*this, PORTFOLIO_MEMORY_CARD_SLOT_B_TAG), - m_exp(*this, PORTFOLIO_EXPANSION_SLOT_TAG), + m_exp(*this, "exp"), m_nvram(*this, "nvram", 0x40000, ENDIANNESS_LITTLE), m_io_sw1(*this, "SW1") { @@ -169,7 +169,7 @@ uint8_t pofo_hpc104_device::nrdi_r(offs_t offset, uint8_t data, bool iom, bool b { if (offset >= 0x1f000 && offset < 0x5f000) { - data = m_nvram[offset - 0x1f000] = data; + data = m_nvram[offset - 0x1f000]; } } } diff --git a/src/devices/bus/saitek_osa/expansion.cpp b/src/devices/bus/saitek_osa/expansion.cpp index bae1dfe0eb5..0c7e6be78bc 100644 --- a/src/devices/bus/saitek_osa/expansion.cpp +++ b/src/devices/bus/saitek_osa/expansion.cpp @@ -11,6 +11,10 @@ Used by Saitek(SciSys) chess computers Leonardo, Galileo, Renaissance. #include "emu.h" #include "expansion.h" +#include "maestro.h" +#include "maestroa.h" +#include "sparc.h" + //************************************************************************** // DEVICE DEFINITIONS @@ -153,3 +157,15 @@ device_saitekosa_expansion_interface::device_saitekosa_expansion_interface(const device_saitekosa_expansion_interface::~device_saitekosa_expansion_interface() { } + +//------------------------------------------------- +// module list +//------------------------------------------------- + +void saitekosa_expansion_modules(device_slot_interface &device) +{ + device.option_add("analyst", OSA_ANALYST); + device.option_add("maestro", OSA_MAESTRO); + device.option_add("maestroa", OSA_MAESTROA); + device.option_add("sparc", OSA_SPARC); +} diff --git a/src/devices/bus/saitek_osa/expansion.h b/src/devices/bus/saitek_osa/expansion.h index 2c245ada301..cb513bf2f4e 100644 --- a/src/devices/bus/saitek_osa/expansion.h +++ b/src/devices/bus/saitek_osa/expansion.h @@ -119,10 +119,10 @@ protected: saitekosa_expansion_device *m_expansion; }; +void saitekosa_expansion_modules(device_slot_interface &device); + + // device type definition DECLARE_DEVICE_TYPE(SAITEKOSA_EXPANSION, saitekosa_expansion_device) -// include here so drivers don't need to -#include "modules.h" - #endif // MAME_BUS_SAITEKOSA_EXPANSION_H diff --git a/src/devices/bus/saitek_osa/modules.cpp b/src/devices/bus/saitek_osa/modules.cpp deleted file mode 100644 index 19b7af1ff13..00000000000 --- a/src/devices/bus/saitek_osa/modules.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:hap -/*************************************************************************** - - Saitek OSA Expansion Slot modules - -***************************************************************************/ - -#include "emu.h" -#include "modules.h" - -#include "maestro.h" -#include "maestroa.h" -#include "sparc.h" - -void saitekosa_expansion_modules(device_slot_interface &device) -{ - device.option_add("analyst", OSA_ANALYST); - device.option_add("maestro", OSA_MAESTRO); - device.option_add("maestroa", OSA_MAESTROA); - device.option_add("sparc", OSA_SPARC); -} diff --git a/src/devices/bus/saitek_osa/modules.h b/src/devices/bus/saitek_osa/modules.h deleted file mode 100644 index 009daf69cec..00000000000 --- a/src/devices/bus/saitek_osa/modules.h +++ /dev/null @@ -1,16 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:hap -/*************************************************************************** - - Saitek OSA Expansion Slot modules - -***************************************************************************/ - -#ifndef MAME_BUS_SAITEKOSA_MODULES_H -#define MAME_BUS_SAITEKOSA_MODULES_H - -#pragma once - -void saitekosa_expansion_modules(device_slot_interface &device); - -#endif // MAME_BUS_SAITEKOSA_MODULES_H diff --git a/src/devices/bus/vic10/exp.cpp b/src/devices/bus/vic10/exp.cpp index a678a2624c3..48f42ad73c1 100644 --- a/src/devices/bus/vic10/exp.cpp +++ b/src/devices/bus/vic10/exp.cpp @@ -79,15 +79,6 @@ void vic10_expansion_slot_device::device_start() m_write_res.resolve_safe(); m_write_cnt.resolve_safe(); m_write_sp.resolve_safe(); - - // inherit bus clock - // FIXME: this should be unnecessary as slots pass DERIVED_CLOCK(1, 1) through by default - if (clock() == 0) - { - vic10_expansion_slot_device *root = machine().root_device().subdevice<vic10_expansion_slot_device>(VIC10_EXPANSION_SLOT_TAG); - assert(root); - set_unscaled_clock(root->clock()); - } } diff --git a/src/devices/bus/vic10/exp.h b/src/devices/bus/vic10/exp.h index 20d21f99e1c..c2b1f52ec70 100644 --- a/src/devices/bus/vic10/exp.h +++ b/src/devices/bus/vic10/exp.h @@ -41,14 +41,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define VIC10_EXPANSION_SLOT_TAG "exp" - - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/vic20/exp.h b/src/devices/bus/vic20/exp.h index 96583a29577..dab459cf7bf 100644 --- a/src/devices/bus/vic20/exp.h +++ b/src/devices/bus/vic20/exp.h @@ -40,14 +40,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define VIC20_EXPANSION_SLOT_TAG "exp" - - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/vip/exp.h b/src/devices/bus/vip/exp.h index bb9cd203690..aa50074e9ca 100644 --- a/src/devices/bus/vip/exp.h +++ b/src/devices/bus/vip/exp.h @@ -40,13 +40,6 @@ //************************************************************************** -// CONSTANTS -//************************************************************************** - -#define VIP_EXPANSION_SLOT_TAG "exp" - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/vme/vme.cpp b/src/devices/bus/vme/vme.cpp index a6edb30b693..57f0c6170d2 100644 --- a/src/devices/bus/vme/vme.cpp +++ b/src/devices/bus/vme/vme.cpp @@ -109,54 +109,34 @@ vme_slot_device::vme_slot_device(const machine_config &mconfig, const char *tag, vme_slot_device::vme_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) , device_slot_interface(mconfig, *this) - , m_vme_tag(nullptr) - , m_vme_slottag(nullptr) + , m_vme(*this, finder_base::DUMMY_TAG) + , m_slot_nbr(0) , m_vme_j1_callback(*this) { LOG("%s %s\n", tag, FUNCNAME); } //------------------------------------------------- -// update_vme_chains -//------------------------------------------------- -void vme_slot_device::update_vme_chains(uint32_t slot_nbr) -{ - LOG("%s %s - %d\n", FUNCNAME, tag(), slot_nbr); -} - -//------------------------------------------------- -// set_vme_slot +// device_start - device-specific startup //------------------------------------------------- -void vme_slot_device::set_vme_slot(const char *tag, const char *slottag) +void vme_slot_device::device_start() { - LOG("%s %s - %s\n", FUNCNAME, tag, slottag); - m_vme_tag = tag; - m_vme_slottag = slottag; + // m_card = dynamic_cast<device_vme_card_interface *>(get_card_device()); } //------------------------------------------------- -// device_start - device-specific startup +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time //------------------------------------------------- -void vme_slot_device::device_start() +void vme_slot_device::device_resolve_objects() { device_vme_card_interface *dev = dynamic_cast<device_vme_card_interface *>(get_card_device()); - LOG("%s %s - %s:%s\n", tag(), FUNCNAME, m_vme_tag, m_vme_slottag); + LOG("%s %s - %s\n", tag(), FUNCNAME, m_vme.finder_tag()); if (dev) { - dev->set_vme_tag(m_vme_tag, m_vme_slottag); + dev->set_vme_bus(*m_vme, m_slot_nbr); } - - // m_card = dynamic_cast<device_vme_card_interface *>(get_card_device()); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- -void vme_slot_device::device_config_complete() -{ - LOG("%s %s\n", tag(), FUNCNAME); } //------------------------------------------------- @@ -457,8 +437,6 @@ void vme_device::install_device(vme_amod_t amod, offs_t start, offs_t end, read3 device_vme_card_interface::device_vme_card_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "vme") , m_vme(nullptr) - , m_vme_tag(nullptr) - , m_vme_slottag(nullptr) , m_slot(0) , m_next(nullptr) { @@ -471,17 +449,9 @@ device_vme_card_interface::~device_vme_card_interface() LOG("%s %s\n", m_device->tag(), FUNCNAME); } -void device_vme_card_interface::set_vme_tag(const char *tag, const char *slottag) -{ - LOG("%s %s\n", tag, FUNCNAME); - m_vme_tag = tag; - m_vme_slottag = slottag; -} - -void device_vme_card_interface::set_vme_device() +void device_vme_card_interface::interface_post_start() { LOG("%s %s\n", m_device->tag(), FUNCNAME); - m_vme = device().machine().root_device().subdevice<vme_device>(m_vme_tag); // printf("*** %s %sfound\n", m_vme_tag, m_vme ? "" : "not "); if (m_vme) m_vme->add_vme_card(this); } diff --git a/src/devices/bus/vme/vme.h b/src/devices/bus/vme/vme.h index 93947e40e91..e49b23cbbbe 100644 --- a/src/devices/bus/vme/vme.h +++ b/src/devices/bus/vme/vme.h @@ -55,12 +55,11 @@ // CONSTANTS //************************************************************************** -#define VME_BUS_TAG "vme" - //void vme_slot1(device_slot_interface &device); // Disabled until we know how to combine a board driver and a slot device. void vme_slots(device_slot_interface &device); class device_vme_card_interface; // This interface is standardized +class vme_device; class vme_slot_device : public device_t, public device_slot_interface @@ -85,16 +84,15 @@ public: }; // construction/destruction - template <typename T> - vme_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt, uint32_t slot_nbr, char const *bus_tag) + template <typename T, typename U> + vme_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt, uint32_t slot_nbr, U &&bus_tag) : vme_slot_device(mconfig, tag, owner, 0) { option_reset(); opts(*this); set_default_option(dflt); set_fixed(false); - set_vme_slot(bus_tag, tag); - update_vme_chains(slot_nbr); + set_vme_slot(std::forward<U>(bus_tag), slot_nbr); } vme_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -102,8 +100,7 @@ public: // Callbacks to the board from the VME bus comes through here auto vme_j1_callback() { return m_vme_j1_callback.bind(); } - void set_vme_slot(const char *tag, const char *slottag); - void update_vme_chains(uint32_t slot_nbr); + template <typename T> void set_vme_slot(T &&tag, uint32_t slot_nbr) { m_vme.set_tag(std::forward<T>(tag)); m_slot_nbr = slot_nbr; } virtual uint8_t read8(offs_t offset); virtual void write8(offs_t offset, uint8_t data); @@ -113,10 +110,11 @@ protected: // device-level overrides virtual void device_start() override; - virtual void device_config_complete() override; + virtual void device_resolve_objects() override; // configuration - const char *m_vme_tag, *m_vme_slottag; + required_device<vme_device> m_vme; + uint32_t m_slot_nbr; // callbacks devcb_write_line m_vme_j1_callback; @@ -139,8 +137,6 @@ public: void set_cputag(const char *tag) { m_cputag = tag; } void use_owner_spaces(); - virtual space_config_vector memory_space_config() const override; - const address_space_config m_a32_config; void add_vme_card(device_vme_card_interface *card); @@ -196,6 +192,8 @@ protected: virtual void device_reset() override; simple_list<device_vme_card_interface> m_device_list; + virtual space_config_vector memory_space_config() const override; + // internal state cpu_device *m_maincpu; @@ -218,22 +216,22 @@ class device_vme_card_interface : public device_interface template <class ElementType> friend class simple_list; public: // inline configuration - void set_vme_tag(const char *tag, const char *slottag); + void set_vme_bus(vme_device &vme, int slot) { m_vme = &vme; m_slot = slot; } // construction/destruction virtual ~device_vme_card_interface(); - void set_vme_device(); virtual uint8_t read8(offs_t offset); virtual void write8(offs_t offset, uint8_t data); +protected: device_vme_card_interface(const machine_config &mconfig, device_t &device); -protected: + virtual void interface_post_start() override; + device_t *m_device; vme_device *m_vme; - const char *m_vme_tag, *m_vme_slottag; int m_slot; private: diff --git a/src/devices/bus/vme/vme_fccpu20.cpp b/src/devices/bus/vme/vme_fccpu20.cpp index 8759c47d143..ee07b86e1be 100644 --- a/src/devices/bus/vme/vme_fccpu20.cpp +++ b/src/devices/bus/vme/vme_fccpu20.cpp @@ -443,8 +443,6 @@ void vme_fccpu20_device::device_start() { LOG("%s\n", FUNCNAME); - set_vme_device(); - save_pointer (NAME (m_sysrom), sizeof(m_sysrom)); save_pointer (NAME (m_sysram), sizeof(m_sysram)); // save_item(NAME(m_board_id)); // TODO: Save this "non base type" item diff --git a/src/devices/bus/vme/vme_fcisio.cpp b/src/devices/bus/vme/vme_fcisio.cpp index d9e35370812..de4c03dfab8 100644 --- a/src/devices/bus/vme/vme_fcisio.cpp +++ b/src/devices/bus/vme/vme_fcisio.cpp @@ -405,7 +405,6 @@ vme_fcisio1_card_device::vme_fcisio1_card_device(const machine_config &mconfig, void vme_fcisio1_card_device::device_start() { LOG("%s\n", FUNCNAME); - set_vme_device(); /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */ m_sysrom = (uint16_t*)(memregion ("maincpu")->base () + 0xf00000); diff --git a/src/devices/bus/vme/vme_fcscsi.cpp b/src/devices/bus/vme/vme_fcscsi.cpp index 508ae910e9c..7324dd907b6 100644 --- a/src/devices/bus/vme/vme_fcscsi.cpp +++ b/src/devices/bus/vme/vme_fcscsi.cpp @@ -329,7 +329,6 @@ vme_fcscsi1_card_device::vme_fcscsi1_card_device(const machine_config &mconfig, void vme_fcscsi1_card_device::device_start() { LOG("%s\n", FUNCNAME); - set_vme_device(); /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */ m_sysrom = (uint16_t*)(memregion ("maincpu")->base () + 0xe00000); diff --git a/src/devices/bus/vme/vme_hcpu30.cpp b/src/devices/bus/vme/vme_hcpu30.cpp index 0c072c20191..2d70c85dd94 100644 --- a/src/devices/bus/vme/vme_hcpu30.cpp +++ b/src/devices/bus/vme/vme_hcpu30.cpp @@ -180,8 +180,6 @@ void vme_hcpu30_card_device::device_start() { LOG("%s %s\n", tag(), FUNCNAME); - set_vme_device(); - save_pointer (NAME (m_sysrom), sizeof(m_sysrom)); save_pointer (NAME (m_sysram), sizeof(m_sysram)); diff --git a/src/devices/bus/vme/vme_mvme350.cpp b/src/devices/bus/vme/vme_mvme350.cpp index 1b8f2f7a564..a0dca46b996 100644 --- a/src/devices/bus/vme/vme_mvme350.cpp +++ b/src/devices/bus/vme/vme_mvme350.cpp @@ -224,7 +224,6 @@ vme_mvme350_card_device::vme_mvme350_card_device(const machine_config &mconfig, void vme_mvme350_card_device::device_start() { LOG("%s %s\n", tag(), FUNCNAME); - set_vme_device(); /* Setup r/w handlers for shared memory area */ #if 0 diff --git a/src/devices/bus/vme/vme_mzr8300.cpp b/src/devices/bus/vme/vme_mzr8300.cpp index cdcd3bd267e..99e2e8c0889 100644 --- a/src/devices/bus/vme/vme_mzr8300.cpp +++ b/src/devices/bus/vme/vme_mzr8300.cpp @@ -168,7 +168,6 @@ vme_mzr8300_card_device::vme_mzr8300_card_device(const machine_config &mconfig, void vme_mzr8300_card_device::device_start() { LOG("%s %s\n", tag(), FUNCNAME); - set_vme_device(); /* Setup r/w handlers for first SIO in A16 */ uint32_t base = 0xFF0000; diff --git a/src/devices/cpu/am29000/am29ops.h b/src/devices/cpu/am29000/am29ops.h index 74f6eef48f9..e111af99cd1 100644 --- a/src/devices/cpu/am29000/am29ops.h +++ b/src/devices/cpu/am29000/am29ops.h @@ -1396,7 +1396,7 @@ void am29000_cpu_device::CLZ() { uint32_t b = INST_M_BIT ? I8: GET_RB_VAL; - m_r[RC] = count_leading_zeros(b); + m_r[RC] = count_leading_zeros_32(b); } void am29000_cpu_device::SETIP() diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp index cb08ff8fed4..f5a8f435762 100644 --- a/src/devices/cpu/arm7/arm7ops.cpp +++ b/src/devices/cpu/arm7/arm7ops.cpp @@ -1697,7 +1697,7 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) uint32_t rm = insn&0xf; uint32_t rd = (insn>>12)&0xf; - SetRegister(rd, count_leading_zeros(GetRegister(rm))); + SetRegister(rd, count_leading_zeros_32(GetRegister(rm))); R15 += 4; } diff --git a/src/devices/cpu/drcbec.cpp b/src/devices/cpu/drcbec.cpp index d8b30535d6e..f54e6416696 100644 --- a/src/devices/cpu/drcbec.cpp +++ b/src/devices/cpu/drcbec.cpp @@ -1062,11 +1062,11 @@ int drcbe_c::execute(code_handle &entry) break; case MAKE_OPCODE_SHORT(OP_LZCNT, 4, 0): // LZCNT dst,src - PARAM0 = count_leading_zeros(PARAM1); + PARAM0 = count_leading_zeros_32(PARAM1); break; case MAKE_OPCODE_SHORT(OP_LZCNT, 4, 1): - temp32 = count_leading_zeros(PARAM1); + temp32 = count_leading_zeros_32(PARAM1); flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; @@ -1675,17 +1675,11 @@ int drcbe_c::execute(code_handle &entry) break; case MAKE_OPCODE_SHORT(OP_LZCNT, 8, 0): // DLZCNT dst,src - if ((uint32_t)(DPARAM1 >> 32) != 0) - DPARAM0 = count_leading_zeros(DPARAM1 >> 32); - else - DPARAM0 = 32 + count_leading_zeros(DPARAM1); + DPARAM0 = count_leading_zeros_64(DPARAM1); break; case MAKE_OPCODE_SHORT(OP_LZCNT, 8, 1): - if ((uint32_t)(DPARAM1 >> 32) != 0) - temp64 = count_leading_zeros(DPARAM1 >> 32); - else - temp64 = 32 + count_leading_zeros(DPARAM1); + temp64 = count_leading_zeros_64(DPARAM1); flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; diff --git a/src/devices/cpu/dspp/dspp.cpp b/src/devices/cpu/dspp/dspp.cpp index ac7ece3cfb5..3479e461af5 100644 --- a/src/devices/cpu/dspp/dspp.cpp +++ b/src/devices/cpu/dspp/dspp.cpp @@ -1588,7 +1588,7 @@ void dspp_device::update_fifo_dma() while (mask != 0) { - uint32_t channel = 31 - count_leading_zeros(mask); + uint32_t channel = 31 - count_leading_zeros_32(mask); const fifo_dma & dma = m_fifo_dma[channel]; diff --git a/src/devices/cpu/h8500/h8500.cpp b/src/devices/cpu/h8500/h8500.cpp index c96fed16f7f..765988ceeaa 100644 --- a/src/devices/cpu/h8500/h8500.cpp +++ b/src/devices/cpu/h8500/h8500.cpp @@ -12,10 +12,11 @@ #include "h8500.h" #include "h8500dasm.h" -h8500_device::h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, address_map_constructor map) +h8500_device::h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, int defmode, address_map_constructor map) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, buswidth, addrbits, 0, map) , m_ram_config("internal RAM", ENDIANNESS_BIG, 16, ramsize, 0, address_map_constructor(FUNC(h8500_device::ram_map), this)) + , m_mode_control(defmode) , m_pc(0) , m_ppc(0) , m_sr(0) diff --git a/src/devices/cpu/h8500/h8500.h b/src/devices/cpu/h8500/h8500.h index ede393687a9..3755ab7a4ab 100644 --- a/src/devices/cpu/h8500/h8500.h +++ b/src/devices/cpu/h8500/h8500.h @@ -18,8 +18,10 @@ public: H8500_R4, H8500_R5, H8500_FP, H8500_SP }; + void set_mode(u8 mode) { assert(!configured()); m_mode_control = mode; } + protected: - h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, address_map_constructor map); + h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, int defmode, address_map_constructor map); // device-level overrides virtual void device_config_complete() override; @@ -40,7 +42,8 @@ protected: // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - virtual bool h8_maximum_mode() const noexcept { return true; } + u8 mode_control() const { return m_mode_control; } + virtual bool h8_maximum_mode() const noexcept { return m_mode_control == 3 || m_mode_control == 4; } // all except H8/570 private: void ram_map(address_map &map); @@ -52,6 +55,9 @@ private: address_space *m_program; memory_access<11, 1, 0, ENDIANNESS_BIG>::cache m_ram_cache; + // misc. configuration + u8 m_mode_control; + // internal registers u16 m_pc; u16 m_ppc; diff --git a/src/devices/cpu/h8500/h8510.cpp b/src/devices/cpu/h8500/h8510.cpp index 413f99cc248..b4ade58d8d5 100644 --- a/src/devices/cpu/h8500/h8510.cpp +++ b/src/devices/cpu/h8500/h8510.cpp @@ -12,7 +12,7 @@ DEFINE_DEVICE_TYPE(HD6415108, hd6415108_device, "hd6415108", "Hitachi HD6415108 (H8/510)") h8510_device::h8510_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : h8500_device(mconfig, type, tag, owner, clock, 24, 16, 0, address_map_constructor(FUNC(h8510_device::internal_map), this)) + : h8500_device(mconfig, type, tag, owner, clock, 24, 16, 0, 4, address_map_constructor(FUNC(h8510_device::internal_map), this)) { } diff --git a/src/devices/cpu/h8500/h8520.cpp b/src/devices/cpu/h8500/h8520.cpp index 9a3a076d5e4..459a979da98 100644 --- a/src/devices/cpu/h8500/h8520.cpp +++ b/src/devices/cpu/h8500/h8520.cpp @@ -10,9 +10,10 @@ #include "h8520.h" DEFINE_DEVICE_TYPE(HD6435208, hd6435208_device, "hd6435208", "Hitachi HD6435208 (H8/520)") +DEFINE_DEVICE_TYPE(HD6475208, hd6475208_device, "hd6475208", "Hitachi HD6475208 (H8/520)") h8520_device::h8520_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 9, address_map_constructor(FUNC(h8520_device::internal_map), this)) + : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 9, 4, address_map_constructor(FUNC(h8520_device::internal_map), this)) { } @@ -21,9 +22,15 @@ hd6435208_device::hd6435208_device(const machine_config &mconfig, const char *ta { } +hd6475208_device::hd6475208_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : h8520_device(mconfig, HD6475208, tag, owner, clock) +{ +} + void h8520_device::internal_map(address_map &map) { - map(0x0000, 0x3fff).rom().region(DEVICE_SELF, 0); // modes 2, 4, 7 + if (mode_control() == 2 || mode_control() == 4 || mode_control() == 7) + map(0x0000, 0x3fff).rom().region(DEVICE_SELF, 0); #if 0 map(0xff80, 0xff80).w(FUNC(h8520_device::p1ddr_w)); map(0xff81, 0xff81).w(FUNC(h8520_device::p2ddr_w)); diff --git a/src/devices/cpu/h8500/h8520.h b/src/devices/cpu/h8500/h8520.h index fc8795e7425..7f66327c796 100644 --- a/src/devices/cpu/h8500/h8520.h +++ b/src/devices/cpu/h8500/h8520.h @@ -24,6 +24,14 @@ public: hd6435208_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; +class hd6475208_device : public h8520_device +{ +public: + // device type constructor + hd6475208_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + DECLARE_DEVICE_TYPE(HD6435208, hd6435208_device) +DECLARE_DEVICE_TYPE(HD6475208, hd6475208_device) #endif // MAME_CPU_H8500_H8520_H diff --git a/src/devices/cpu/h8500/h8532.cpp b/src/devices/cpu/h8500/h8532.cpp index 9d0be448e3f..20c9869c4ee 100644 --- a/src/devices/cpu/h8500/h8532.cpp +++ b/src/devices/cpu/h8500/h8532.cpp @@ -10,9 +10,10 @@ #include "h8532.h" DEFINE_DEVICE_TYPE(HD6435328, hd6435328_device, "hd6435328", "Hitachi HD6435328 (H8/532)") +DEFINE_DEVICE_TYPE(HD6475328, hd6475328_device, "hd6475328", "Hitachi HD6475328 (H8/532)") h8532_device::h8532_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 10, address_map_constructor(FUNC(h8532_device::internal_map), this)) + : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 10, 4, address_map_constructor(FUNC(h8532_device::internal_map), this)) { } @@ -21,9 +22,15 @@ hd6435328_device::hd6435328_device(const machine_config &mconfig, const char *ta { } +hd6475328_device::hd6475328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : h8532_device(mconfig, HD6475328, tag, owner, clock) +{ +} + void h8532_device::internal_map(address_map &map) { - map(0x0000, 0x7fff).rom().region(DEVICE_SELF, 0); // modes 2, 4, 7 + if (mode_control() == 2 || mode_control() == 4 || mode_control() == 7) + map(0x0000, 0x7fff).rom().region(DEVICE_SELF, 0); #if 0 map(0xff80, 0xff80).w(FUNC(h8532_device::p1ddr_w)); map(0xff81, 0xff81).w(FUNC(h8532_device::p2ddr_w)); diff --git a/src/devices/cpu/h8500/h8532.h b/src/devices/cpu/h8500/h8532.h index c9b08ee1d00..71ec652a465 100644 --- a/src/devices/cpu/h8500/h8532.h +++ b/src/devices/cpu/h8500/h8532.h @@ -24,6 +24,14 @@ public: hd6435328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; +class hd6475328_device : public h8532_device +{ +public: + // device type constructor + hd6475328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + DECLARE_DEVICE_TYPE(HD6435328, hd6435328_device) +DECLARE_DEVICE_TYPE(HD6475328, hd6475328_device) #endif // MAME_CPU_H8500_H8532_H diff --git a/src/devices/cpu/h8500/h8534.cpp b/src/devices/cpu/h8500/h8534.cpp index dd33af71128..06c9b0dc24f 100644 --- a/src/devices/cpu/h8500/h8534.cpp +++ b/src/devices/cpu/h8500/h8534.cpp @@ -9,11 +9,13 @@ #include "emu.h" #include "h8534.h" +DEFINE_DEVICE_TYPE(HD6435348, hd6435348_device, "hd6435348", "Hitachi HD6435348 (H8/534)") DEFINE_DEVICE_TYPE(HD6475348, hd6475348_device, "hd6475348", "Hitachi HD6475348 (H8/534)") DEFINE_DEVICE_TYPE(HD6435368, hd6435368_device, "hd6435368", "Hitachi HD6435368 (H8/536)") +DEFINE_DEVICE_TYPE(HD6475368, hd6475368_device, "hd6475368", "Hitachi HD6475368 (H8/536)") h8534_device::h8534_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map) - : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 11, map) + : h8500_device(mconfig, type, tag, owner, clock, 20, 8, 11, 4, map) { } @@ -22,6 +24,11 @@ h8534_device::h8534_device(const machine_config &mconfig, device_type type, cons { } +hd6435348_device::hd6435348_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : h8534_device(mconfig, HD6435348, tag, owner, clock) +{ +} + hd6475348_device::hd6475348_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : h8534_device(mconfig, HD6475348, tag, owner, clock) { @@ -37,16 +44,24 @@ hd6435368_device::hd6435368_device(const machine_config &mconfig, const char *ta { } +hd6475368_device::hd6475368_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : h8536_device(mconfig, HD6475368, tag, owner, clock) +{ +} + void h8534_device::internal_map(address_map &map) { - map(0x0000, 0x7fff).rom().region(DEVICE_SELF, 0); // modes 2, 4, 7 + if (mode_control() == 2 || mode_control() == 4 || mode_control() == 7) + map(0x0000, 0x7fff).rom().region(DEVICE_SELF, 0); register_field_map(map); } void h8536_device::internal_map(address_map &map) { - //map(0x0000, 0xee7f).rom().region(DEVICE_SELF, 0); // mode 2? - //map(0x0000, 0xf67f).rom().region(DEVICE_SELF, 0); // modes 4, 7 + if (mode_control() == 2) + map(0x0000, 0xee7f).rom().region(DEVICE_SELF, 0); + else if (mode_control() == 4 || mode_control() == 7) + map(0x0000, 0xf67f).rom().region(DEVICE_SELF, 0); register_field_map(map); } diff --git a/src/devices/cpu/h8500/h8534.h b/src/devices/cpu/h8500/h8534.h index 8e5c357ff1b..2fad7985a70 100644 --- a/src/devices/cpu/h8500/h8534.h +++ b/src/devices/cpu/h8500/h8534.h @@ -11,9 +11,8 @@ class h8534_device : public h8500_device { protected: - // delegating constructor + // delegating constructors h8534_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); - h8534_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map); void register_field_map(address_map &map); @@ -22,6 +21,13 @@ private: void internal_map(address_map &map); }; +class hd6435348_device : public h8534_device +{ +public: + // device type constructor + hd6435348_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + class hd6475348_device : public h8534_device { public: @@ -45,7 +51,16 @@ public: hd6435368_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; +class hd6475368_device : public h8536_device +{ +public: + // device type constructor + hd6475368_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +DECLARE_DEVICE_TYPE(HD6435348, hd6435348_device) DECLARE_DEVICE_TYPE(HD6475348, hd6475348_device) DECLARE_DEVICE_TYPE(HD6435368, hd6435368_device) +DECLARE_DEVICE_TYPE(HD6475368, hd6475368_device) #endif // MAME_CPU_H8500_H8534_H diff --git a/src/devices/cpu/m68000/m68kfpu.cpp b/src/devices/cpu/m68000/m68kfpu.cpp index ed439f2fe5f..7cd10e84b84 100644 --- a/src/devices/cpu/m68000/m68kfpu.cpp +++ b/src/devices/cpu/m68000/m68kfpu.cpp @@ -241,6 +241,53 @@ inline void m68000_base_device::store_pack_float80(u32 ea, int k, floatx80 fpr) m68ki_write_32(ea+8, dw3); } +inline floatx80 propagateFloatx80NaNOneArg(floatx80 a) +{ + if (floatx80_is_signaling_nan(a)) + float_raise(float_flag_invalid); + + a.low |= 0xC000000000000000U; + + return a; +} + +static void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr) +{ + int shiftCount = countLeadingZeros64(aSig); + *zSigPtr = aSig << shiftCount; + *zExpPtr = 1 - shiftCount; +} + +inline floatx80 getman(floatx80 src) +{ + const flag sign = (src.high >> 15); + int32_t exp = (src.high & 0x7fff); + uint64_t signific = src.low; + + if (exp == 0x7fff) + { + if ((uint64_t)(signific << 1)) + { + return propagateFloatx80NaNOneArg(src); + } + else + { + return packFloatx80(0, 0xffff, 0xffffffffffffffffU); + } + } + + if (exp == 0) + { + if (signific == 0) + { + return packFloatx80(sign, 0, 0); + } + normalizeFloatx80Subnormal(signific, &exp, &signific); + } + + return packFloatx80(sign, 0x3fff, signific); +} + inline void m68000_base_device::SET_CONDITION_CODES(floatx80 reg) { // u64 *regi; @@ -347,6 +394,10 @@ u8 m68000_base_device::READ_EA_8(int ea) { return REG_D()[reg]; } + case 1: // An + { + return REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -423,6 +474,10 @@ u16 m68000_base_device::READ_EA_16(int ea) { return (u16)(REG_D()[reg]); } + case 1: // An + { + return (u16)REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -500,6 +555,10 @@ u32 m68000_base_device::READ_EA_32(int ea) { return REG_D()[reg]; } + case 1: // An + { + return REG_A()[reg]; + } case 2: // (An) { u32 ea = REG_A()[reg]; @@ -1106,6 +1165,13 @@ void m68000_base_device::WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di break; } + case 6: // (An) + (Xn) + d8 + { + u32 ea = EA_AY_IX_32(); + store_extended_float80(ea, fpr); + break; + } + case 7: { switch (reg) @@ -1163,11 +1229,11 @@ void m68000_base_device::WRITE_EA_PACK(int ea, int k, floatx80 fpr) void m68000_base_device::fpgen_rm_reg(u16 w2) { - int ea = m_ir & 0x3f; - int rm = (w2 >> 14) & 0x1; - int src = (w2 >> 10) & 0x7; - int dst = (w2 >> 7) & 0x7; - int opmode = w2 & 0x7f; + const int ea = m_ir & 0x3f; + const int rm = (w2 >> 14) & 0x1; + const int src = (w2 >> 10) & 0x7; + const int dst = (w2 >> 7) & 0x7; + const int opmode = w2 & 0x7f; floatx80 source; // fmovecr #$f, fp0 f200 5c0f @@ -1383,7 +1449,7 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) } case 0x06: // FLOGNP1 { - m_fpr[dst] = floatx80_flognp1 (source); + m_fpr[dst] = floatx80_flognp1(source); SET_CONDITION_CODES(m_fpr[dst]); m_icount -= 594; // for MC68881 break; @@ -1460,6 +1526,13 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) m_icount -= 6; break; } + case 0x1f: // FGETMAN + { + m_fpr[dst] = getman(source); + SET_CONDITION_CODES(m_fpr[dst]); + m_icount -= 31; + break; + } case 0x60: // FSDIVS case 0x20: // FDIV { @@ -1534,6 +1607,24 @@ void m68000_base_device::fpgen_rm_reg(u16 w2) m_icount -= 9; break; } + case 0x30: // FSINCOS + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + { + m_fpr[dst] = source; + floatx80_fsin(m_fpr[dst]); + SET_CONDITION_CODES(m_fpr[dst]); // condition codes are set for the sine result + + m_fpr[(w2 & 0x7)] = source; + floatx80_fcos(m_fpr[(w2 & 0x7)]); + m_icount -= 451; + break; + } case 0x38: // FCMP { floatx80 res; @@ -1743,17 +1834,6 @@ void m68000_base_device::fmovem(u16 w2) int mode = (w2 >> 11) & 0x3; int reglist = w2 & 0xff; - u32 mem_addr = 0; - switch (ea >> 3) - { - case 5: // (d16, An) - mem_addr= EA_AY_DI_32(); - break; - case 6: // (An) + (Xn) + d8 - mem_addr= EA_AY_IX_32(); - break; - } - if (dir) // From FP regs to mem { switch (mode) @@ -1797,8 +1877,7 @@ void m68000_base_device::fmovem(u16 w2) { int imode = (ea >> 3) & 0x7; int reg = (ea & 0x7); - int di_mode = imode == 5; - + int di_mode = (imode == 5); uint32 di_mode_ea = di_mode ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; for (i=0; i < 8; i++) @@ -1832,23 +1911,17 @@ void m68000_base_device::fmovem(u16 w2) { int imode = (ea >> 3) & 0x7; int reg = (ea & 0x7); - int di_mode = imode == 5; + int di_mode = (imode == 5); uint32 di_mode_ea = di_mode ? (REG_A()[reg] + MAKE_INT_16(m68ki_read_imm_16())) : 0; for (i=0; i < 8; i++) { if (reglist & (1 << i)) { - switch (ea >> 3) + m_fpr[7 - i] = READ_EA_FPE(imode, reg, di_mode_ea); + if (di_mode) { - case 5: // (d16, An) - case 6: // (An) + (Xn) + d8 - m_fpr[7-i] = load_extended_float80(mem_addr); - mem_addr += 12; - break; - default: - m_fpr[7 - i] = READ_EA_FPE(imode, reg, di_mode_ea); - break; + di_mode_ea += 12; } m_icount -= 2; } diff --git a/src/devices/cpu/m88000/m88000.cpp b/src/devices/cpu/m88000/m88000.cpp index 130888d8cc3..b45a74b830e 100644 --- a/src/devices/cpu/m88000/m88000.cpp +++ b/src/devices/cpu/m88000/m88000.cpp @@ -996,14 +996,14 @@ void mc88100_device::execute(u32 const inst) break; case 0x740: // ff1: find first bit set { - unsigned const count = count_leading_zeros(m_r[S2]); + unsigned const count = count_leading_zeros_32(m_r[S2]); m_r[D] = (count == 32) ? count : 31 - count; } break; case 0x760: // ff0: find first bit clear { - unsigned const count = count_leading_ones(m_r[S2]); + unsigned const count = count_leading_ones_32(m_r[S2]); m_r[D] = (count == 32) ? count : 31 - count; } diff --git a/src/devices/cpu/mips/r4000.cpp b/src/devices/cpu/mips/r4000.cpp index eb2cff471d2..2b12a2089f5 100644 --- a/src/devices/cpu/mips/r4000.cpp +++ b/src/devices/cpu/mips/r4000.cpp @@ -1175,7 +1175,7 @@ void r4000_base_device::cpu_exception(u32 exception, u16 const vector) u32 const iphw = CAUSE & SR & CAUSE_IPHW; if (iphw) - debug()->interrupt_hook(22 - count_leading_zeros((iphw - 1) & ~iphw)); + debug()->interrupt_hook(22 - count_leading_zeros_32((iphw - 1) & ~iphw)); } } else @@ -1530,7 +1530,7 @@ void r4000_base_device::cp0_tlbwi(u8 const index) entry.pfn[0] = m_cp0[CP0_EntryLo0] & EL_WM; entry.pfn[1] = m_cp0[CP0_EntryLo1] & EL_WM; - entry.low_bit = 32 - count_leading_zeros((entry.mask >> 1) | 0xfff); + entry.low_bit = 32 - count_leading_zeros_32((entry.mask >> 1) | 0xfff); LOGMASKED(LOG_TLB, "tlb write index %02d mask 0x%016x vpn2 0x%016x %c asid 0x%02x pfn0 0x%016x %c%c pfn1 0x%016x %c%c (%s)\n", index, entry.mask, diff --git a/src/devices/cpu/pdp8/hd6120.cpp b/src/devices/cpu/pdp8/hd6120.cpp index ec72498d272..947225ae603 100644 --- a/src/devices/cpu/pdp8/hd6120.cpp +++ b/src/devices/cpu/pdp8/hd6120.cpp @@ -86,20 +86,34 @@ Register”), PC and the two stack pointers, include several which are only implicitly used in execution: a TEMP register that latches ALU outputs, the instruction register IR, and the output latch register OL - that holds all addresses and data to be output on the DX bus. HD-6120 - also internally maintains a group of 3-bit registers whose path - connects to TEMP, each of which contains the current memory extension - fields, their mirrors or various flags. (This emulation extends the - field registers to 4 bits to include the CTRLFF, PDF and PEX flags, - which are neither readable nor output directly at any time.) - Particular flag registers are enabled on the C0, C1 and EMA2 lines - during the final writes of ISZ, DCA and JMS. The most important of - these flag registers includes LINK, the interrupt enable flip-flop and - the GT flag hitherto provided only on arithmetic extensions of some - previous PDP-8 CPUs, though like MQ it conveys no specific purpose - here. Another flag register contains the inverse of the active-low - INTREQ input, the PWRON flag (set if STRTUP = VSS at RESET time, - causing entry into panel mode) and 0 in its LSB. + that holds all addresses and data to be output on the DX bus. + + HD-6120 also maintains a group of 3-bit internal registers whose data + path connects to TEMP. These are used to hold the current memory + extension fields, their mirrors and various flags. (This emulation + extends the field registers to 4 bits to include the CTRLFF, PDF and + PEX flags, which are neither readable nor output directly at any + time.) These 3-bit registers may be enabled on the C0, C1 and EMA2 + lines at particular times, and the GTF, GCF, PRS, RDF, RIF and RIB + internal IOTs read various combinations of them into AC. They include: + + MSB LSB Output conditions + ----------------------------------------- + IF0 IF1 IF2 IFETCH, direct operands (except if FZ) + IB0 IB1 IB2 None (until transferred to IF) + ISF0 ISF1 ISF2 None + DF0 DF1 DF2 Indirect operand addressing, IOTs, etc. + DSF0 DSF1 DSF2 None + LINK GT IEFF DCA AC writes + INTREQ* PWRON 0 ISZ result writes + BTSTRAP PNLTRP HLTFLG JMS PC writes + + The GT flag, like MQ, is not used for any specific purpose on the + HD-6120, unlike the arithmetic extensions of previous PDP-8 CPUs which + originally implemented them. The INTREQ flag is 1 when the input pin + is sampled active low and 0 when it is inactive. The PWRON flag is set + if STRTUP is sampled as VSS at RESET time; it causes the CPU to trap + into panel mode before executing its first instruction. Undefined Group 3 OPRs and internal IOTs have no effect on the HD-6120 except that both interrupts and panel requests are blocked @@ -1001,6 +1015,7 @@ void hd6120_device::execute_run() break; case minor_state::PEX_1: + m_temp = m_ac; m_state = minor_state::PEX_2; break; diff --git a/src/devices/cpu/psx/gte.cpp b/src/devices/cpu/psx/gte.cpp index d48b206e84f..6305b4d7412 100644 --- a/src/devices/cpu/psx/gte.cpp +++ b/src/devices/cpu/psx/gte.cpp @@ -215,7 +215,7 @@ void gte::setcp2dr( uint32_t pc, int reg, uint32_t value ) break; case 30: - LZCR = (value & 0x80000000) == 0 ? count_leading_zeros(value) : count_leading_ones(value); + LZCR = (value & 0x80000000) == 0 ? count_leading_zeros_32(value) : count_leading_ones_32(value); break; case 31: @@ -314,7 +314,7 @@ static inline uint32_t gte_divide( uint16_t numerator, uint16_t denominator ) 0x00 }; - int shift = count_leading_zeros( denominator ) - 16; + int shift = count_leading_zeros_32( denominator ) - 16; int r1 = ( denominator << shift ) & 0x7fff; int r2 = table[ ( ( r1 + 0x40 ) >> 7 ) ] + 0x101; diff --git a/src/devices/cpu/romp/romp.cpp b/src/devices/cpu/romp/romp.cpp index d68988cb876..94e3da8591c 100644 --- a/src/devices/cpu/romp/romp.cpp +++ b/src/devices/cpu/romp/romp.cpp @@ -887,7 +887,7 @@ void romp_device::execute_run() flags_log(m_gpr[R2]); break; case 0xf5: // clz: count leading zeros - m_gpr[R2] = count_leading_zeros(u16(m_gpr[R3])) - 16; + m_gpr[R2] = count_leading_zeros_32(u16(m_gpr[R3])) - 16; break; case 0xf9: // mc03: move character zero from three diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp index ded941af415..134611079a8 100644 --- a/src/devices/cpu/sharc/sharc.cpp +++ b/src/devices/cpu/sharc/sharc.cpp @@ -343,7 +343,10 @@ void adsp21062_device::iop_w(offs_t offset, uint32_t data) case 0x1c: { m_core->dma[6].control = data; - sharc_iop_delayed_w(0x1c, data, 1); + if (data & 0x1) + { + sharc_iop_delayed_w(0x1c, data, 1); + } break; } @@ -360,9 +363,12 @@ void adsp21062_device::iop_w(offs_t offset, uint32_t data) // DMA 7 case 0x1d: - { + { m_core->dma[7].control = data; - sharc_iop_delayed_w(0x1d, data, 30); + if (data & 0x1) + { + sharc_iop_delayed_w(0x1d, data, 30); + } break; } @@ -442,7 +448,7 @@ void adsp21062_device::external_dma_write(uint32_t address, uint64_t data) All addresses in the 17-bit index registers are offset by 0x0002 0000, the first internal RAM location, before they are used by the DMA controller. */ - + switch ((m_core->dma[6].control >> 6) & 0x3) { case 2: // 16/48 packing @@ -972,6 +978,19 @@ void adsp21062_device::set_flag_input(int flag_num, int state) } } +WRITE_LINE_MEMBER(adsp21062_device::write_stall) +{ + m_core->write_stalled = (state == 0) ? false : true; + + if (m_enable_drc) + { + if (m_core->write_stalled) + spin_until_trigger(45757); + else + machine().scheduler().trigger(45757); + } +} + void adsp21062_device::check_interrupts() { int i; @@ -1028,8 +1047,24 @@ void adsp21062_device::execute_run() } else { + if (m_core->write_stalled) + eat_cycles(m_core->icount); + if (m_core->idle && m_core->irq_pending == 0) { + int dma_count = m_core->icount; + + // run active DMAs even while idling + while (dma_count > 0 && m_core->dma_status & ((1 << 6) | (1 << 7))) + { + if (!m_core->write_stalled) + { + dma_run_cycle(6); + dma_run_cycle(7); + } + dma_count--; + } + m_core->icount = 0; debugger_instruction_hook(m_core->daddr); } @@ -1037,9 +1072,9 @@ void adsp21062_device::execute_run() { check_interrupts(); m_core->idle = 0; - } + } - while (m_core->icount > 0 && !m_core->idle) + while (m_core->icount > 0 && !m_core->idle && !m_core->write_stalled) { m_core->pc = m_core->daddr; m_core->daddr = m_core->faddr; @@ -1126,6 +1161,12 @@ void adsp21062_device::execute_run() } } + if (!m_core->write_stalled) + { + dma_run_cycle(6); + dma_run_cycle(7); + } + --m_core->icount; }; } diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h index 6c9292c5193..f7d2d8701cd 100644 --- a/src/devices/cpu/sharc/sharc.h +++ b/src/devices/cpu/sharc/sharc.h @@ -103,6 +103,8 @@ public: TIMER_CALLBACK_MEMBER(sharc_iop_delayed_write_callback); TIMER_CALLBACK_MEMBER(sharc_dma_callback); + WRITE_LINE_MEMBER(write_stall); + void sharc_cfunc_unimplemented(); void sharc_cfunc_read_iop(); void sharc_cfunc_write_iop(); @@ -270,6 +272,7 @@ private: int32_t chained_direction; emu_timer *timer; bool active; + bool chained; }; @@ -379,6 +382,7 @@ private: SHARC_DMA_OP dma_op[12]; uint32_t dma_status; + bool write_stalled; int32_t interrupt_active; @@ -475,6 +479,7 @@ private: void schedule_dma_op(int channel, uint32_t src, uint32_t dst, int src_modifier, int dst_modifier, int src_count, int dst_count, int pmode); void dma_op(int channel); void sharc_dma_exec(int channel); + void dma_run_cycle(int channel); void add_systemreg_write_latency_effect(int sysreg, uint32_t data, uint32_t prev_data); inline void swap_register(uint32_t *a, uint32_t *b); void systemreg_write_latency_effect(); diff --git a/src/devices/cpu/sharc/sharcdma.hxx b/src/devices/cpu/sharc/sharcdma.hxx index fdbf7a0f635..e0df2cb5e54 100644 --- a/src/devices/cpu/sharc/sharcdma.hxx +++ b/src/devices/cpu/sharc/sharcdma.hxx @@ -10,7 +10,7 @@ void adsp21062_device::schedule_chained_dma_op(int channel, uint32_t dma_chain_ptr, int chained_direction) { - uint32_t op_ptr = 0x20000 + dma_chain_ptr; + uint32_t op_ptr = 0x20000 + (dma_chain_ptr & 0x1ffff); uint32_t int_index = dm_read32(op_ptr - 0); uint32_t int_modifier = dm_read32(op_ptr - 1); @@ -49,10 +49,14 @@ void adsp21062_device::schedule_chained_dma_op(int channel, uint32_t dma_chain_p m_core->dma_op[channel].chain_ptr = chain_ptr; m_core->dma_op[channel].chained_direction = chained_direction; + m_core->dma_op[channel].chained = true; m_core->dma_op[channel].active = true; - int cycles = m_core->dma_op[channel].src_count / 4; - m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel); + if (m_enable_drc) + { + int cycles = m_core->dma_op[channel].src_count / 4; + m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel); + } // enable busy flag m_core->dma_status |= (1 << channel); @@ -74,15 +78,107 @@ void adsp21062_device::schedule_dma_op(int channel, uint32_t src, uint32_t dst, m_core->dma_op[channel].pmode = pmode; m_core->dma_op[channel].chain_ptr = 0; + m_core->dma_op[channel].chained = false; m_core->dma_op[channel].active = true; - int cycles = src_count / 4; - m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel); + if (m_enable_drc) + { + int cycles = src_count / 4; + m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel); + } // enable busy flag m_core->dma_status |= (1 << channel); } +void adsp21062_device::dma_run_cycle(int channel) +{ + if (m_core->dma_status & (1 << channel)) + { + uint32_t src = m_core->dma_op[channel].src; + uint32_t dst = m_core->dma_op[channel].dst; + int src_modifier = m_core->dma_op[channel].src_modifier; + int dst_modifier = m_core->dma_op[channel].dst_modifier; + int src_count = m_core->dma_op[channel].src_count; + //int dst_count = m_core->dma_op[channel].dst_count; + int pmode = m_core->dma_op[channel].pmode; + + switch (pmode) + { + case DMA_PMODE_NO_PACKING: + { + uint32_t data = dm_read32(src); + dm_write32(dst, data); + src += src_modifier; + dst += dst_modifier; + src_count--; + break; + } + case DMA_PMODE_16_32: + { + uint32_t data = ((dm_read32(src + 0) & 0xffff) << 16) | (dm_read32(src + 1) & 0xffff); + + dm_write32(dst, data); + src += src_modifier * 2; + dst += dst_modifier; + src_count -= 2; + break; + } + case DMA_PMODE_8_48: + { + uint64_t data = ((uint64_t)(dm_read32(src + 0) & 0xff) << 0) | + ((uint64_t)(dm_read32(src + 1) & 0xff) << 8) | + ((uint64_t)(dm_read32(src + 2) & 0xff) << 16) | + ((uint64_t)(dm_read32(src + 3) & 0xff) << 24) | + ((uint64_t)(dm_read32(src + 4) & 0xff) << 32) | + ((uint64_t)(dm_read32(src + 5) & 0xff) << 40); + + pm_write48(dst, data); + src += src_modifier * 6; + dst += dst_modifier; + src_count -= 6; + break; + } + default: + { + fatalerror("SHARC: dma_op: unimplemented packing mode %d\n", pmode); + } + } + + m_core->dma_op[channel].src_count = src_count; + m_core->dma_op[channel].src = src; + m_core->dma_op[channel].dst = dst; + + if (src_count <= 0) + { + // clear busy flag + m_core->dma_status &= ~(1 << channel); + + m_core->dma_op[channel].active = false; + + // raise interrupt if + // * non-chained DMA + // * chained-DMA with PCI set in the next chain pointer + if (!m_core->dma_op[channel].chained || (m_core->dma_op[channel].chained && (m_core->dma_op[channel].chain_ptr & 0x20000))) + { + m_core->irptl |= (1 << (channel + 10)); + + // DMA interrupt + if (m_core->imask & (1 << (channel + 10))) + { + m_core->irq_pending |= 1 << (channel + 10); + } + } + + // schedule chained op if chaining + if ((m_core->dma_op[channel].chain_ptr & 0x1ffff) != 0) + { + schedule_chained_dma_op(channel, m_core->dma_op[channel].chain_ptr, m_core->dma_op[channel].chained_direction); + } + } + } +} + void adsp21062_device::dma_op(int channel) { int i; @@ -94,7 +190,7 @@ void adsp21062_device::dma_op(int channel) //int dst_count = m_core->dma_op[channel].dst_count; int pmode = m_core->dma_op[channel].pmode; - //printf("dma_op: %08X, %08X, %08X, %08X, %08X, %d\n", src, dst, src_modifier, dst_modifier, src_count, pmode); + //printf("dma_op: ch %d: %08X, %08X, %08X, %08X, %08X, %d at %08X\n", channel, src, dst, src_modifier, dst_modifier, src_count, pmode, m_core->pc); switch (pmode) { @@ -191,36 +287,36 @@ void adsp21062_device::sharc_dma_exec(int channel) { uint32_t dma_chain_ptr = m_core->dma[channel].chain_ptr & 0x1ffff; - schedule_chained_dma_op(channel, dma_chain_ptr, tran); + schedule_chained_dma_op(channel, dma_chain_ptr, tran); } else { if (tran) // Transmit to external { - dst = m_core->dma[channel].ext_index; - dst_modifier = m_core->dma[channel].ext_modifier; - dst_count = m_core->dma[channel].ext_count; - src = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000; - src_modifier = m_core->dma[channel].int_modifier; - src_count = m_core->dma[channel].int_count; + dst = m_core->dma[channel].ext_index; + dst_modifier = m_core->dma[channel].ext_modifier; + dst_count = m_core->dma[channel].ext_count; + src = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000; + src_modifier = m_core->dma[channel].int_modifier; + src_count = m_core->dma[channel].int_count; } else // Receive from external { - src = m_core->dma[channel].ext_index; - src_modifier = m_core->dma[channel].ext_modifier; - src_count = m_core->dma[channel].ext_count; - dst = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000; - dst_modifier = m_core->dma[channel].int_modifier; - dst_count = m_core->dma[channel].int_count; + src = m_core->dma[channel].ext_index; + src_modifier = m_core->dma[channel].ext_modifier; + src_count = m_core->dma[channel].ext_count; + dst = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000; + dst_modifier = m_core->dma[channel].int_modifier; + dst_count = m_core->dma[channel].int_count; } if (dtype) - //if (src_count != dst_count) + //if (src_count != dst_count) { pmode = DMA_PMODE_8_48; } - schedule_dma_op(channel, src, dst, src_modifier, dst_modifier, src_count, dst_count, pmode); + schedule_dma_op(channel, src, dst, src_modifier, dst_modifier, src_count, dst_count, pmode); } } @@ -239,7 +335,7 @@ TIMER_CALLBACK_MEMBER(adsp21062_device::sharc_dma_callback) } dma_op(channel); - if (m_core->dma_op[channel].chain_ptr != 0) + if ((m_core->dma_op[channel].chain_ptr & 0x1ffff) != 0) { schedule_chained_dma_op(channel, m_core->dma_op[channel].chain_ptr, m_core->dma_op[channel].chained_direction); } diff --git a/src/devices/cpu/tms32031/32031ops.hxx b/src/devices/cpu/tms32031/32031ops.hxx index da59340b7d9..06533f09abb 100644 --- a/src/devices/cpu/tms32031/32031ops.hxx +++ b/src/devices/cpu/tms32031/32031ops.hxx @@ -393,7 +393,7 @@ void tms3203x_device::int2float(tmsreg &srcdst) // positive values; count leading zeros and shift else if ((int32_t)man > 0) { - cnt = count_leading_zeros(man); + cnt = count_leading_zeros_32(man); man <<= cnt; exp = 31 - cnt; } @@ -401,7 +401,7 @@ void tms3203x_device::int2float(tmsreg &srcdst) // negative values; count leading ones and shift else { - cnt = count_leading_ones(man); + cnt = count_leading_ones_32(man); man <<= cnt; exp = 31 - cnt; } @@ -585,13 +585,13 @@ void tms3203x_device::addf(tmsreg &dst, tmsreg &src1, tmsreg &src2) { if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } @@ -698,13 +698,13 @@ void tms3203x_device::subf(tmsreg &dst, tmsreg &src1, tmsreg &src2) { if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } @@ -847,13 +847,13 @@ void tms3203x_device::norm(tmsreg &dst, tmsreg &src) int cnt; if (man > 0) { - cnt = count_leading_zeros((uint32_t)man); + cnt = count_leading_zeros_32((uint32_t)man); man <<= cnt; exp -= cnt; } else { - cnt = count_leading_ones((uint32_t)man); + cnt = count_leading_ones_32((uint32_t)man); man <<= cnt; exp -= cnt; } diff --git a/src/devices/cpu/tms34010/34010ops.hxx b/src/devices/cpu/tms34010/34010ops.hxx index 1c71439107e..aa398e3c776 100644 --- a/src/devices/cpu/tms34010/34010ops.hxx +++ b/src/devices/cpu/tms34010/34010ops.hxx @@ -2458,16 +2458,16 @@ void tms340x0_device::setcdp(uint16_t op) // .. only single bit set, pitch is power of two! case 1: { - m_convdp = 32 - count_leading_zeros(dptch); + m_convdp = 32 - count_leading_zeros_32(dptch); COUNT_CYCLES(4); return; } // .. two bits, we can decompose it to sum of two power of two numbers case 2: { - uint8_t first_one = count_leading_zeros(dptch); + uint8_t first_one = count_leading_zeros_32(dptch); uint8_t v1 = 32 - first_one; - uint8_t v2 = 32 - count_leading_zeros(dptch & ~(1 << (first_one - 1))); + uint8_t v2 = 32 - count_leading_zeros_32(dptch & ~(1 << (first_one - 1))); m_convdp = v2 | (v1 << 8); COUNT_CYCLES(6); diff --git a/src/devices/cpu/uml.cpp b/src/devices/cpu/uml.cpp index 8b0c7023f58..6a81d63400e 100644 --- a/src/devices/cpu/uml.cpp +++ b/src/devices/cpu/uml.cpp @@ -631,14 +631,9 @@ void uml::instruction::simplify() if (m_param[1].is_immediate()) { if (m_size == 4) - convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate())); + convert_to_mov_immediate(count_leading_zeros_32(m_param[1].immediate())); else if (m_size == 8) - { - if ((m_param[1].immediate() >> 32) == 0) - convert_to_mov_immediate(32 + count_leading_zeros(m_param[1].immediate())); - else - convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate() >> 32)); - } + convert_to_mov_immediate(count_leading_zeros_64(m_param[1].immediate())); } break; diff --git a/src/devices/cpu/unsp/unsp_fxxx.cpp b/src/devices/cpu/unsp/unsp_fxxx.cpp index 4c1f41245ad..13b7bd27995 100644 --- a/src/devices/cpu/unsp/unsp_fxxx.cpp +++ b/src/devices/cpu/unsp/unsp_fxxx.cpp @@ -396,11 +396,11 @@ void unsp_12_device::execute_fxxx_101_group(uint16_t op) if (r4 & 0x8000) { - m_core->m_r[REG_R2] = count_leading_ones(0xffff0000 | r4) - 17; + m_core->m_r[REG_R2] = count_leading_ones_32(0xffff0000 | r4) - 17; } else { - m_core->m_r[REG_R2] = count_leading_zeros(r4) - 17; // -17 because count_leading_zeros works with 32-bit values + m_core->m_r[REG_R2] = count_leading_zeros_32(r4) - 17; // -17 because count_leading_zeros_32 works with 32-bit values } return; diff --git a/src/devices/cpu/z80/kp69.cpp b/src/devices/cpu/z80/kp69.cpp index 84be060c4c7..0e194138b2c 100644 --- a/src/devices/cpu/z80/kp69.cpp +++ b/src/devices/cpu/z80/kp69.cpp @@ -409,14 +409,14 @@ int kp69_base_device::z80daisy_irq_ack() // Restrict to high-priority interrupts if any of those are pending if ((m_irr & m_pgr) != 0) { - level = 31 - count_leading_zeros(u32(m_irr & m_pgr)); + level = 31 - count_leading_zeros_32(u32(m_irr & m_pgr)); assert(level >= 0 && level < 16); if ((1 << level) < (m_isr & m_pgr)) level = -1; } else if (m_irr != 0 && (m_isr & m_pgr) == 0) { - level = 31 - count_leading_zeros(u32(m_irr)); + level = 31 - count_leading_zeros_32(u32(m_irr)); assert(level >= 0 && level < 16); if ((1 << level) < m_isr) level = -1; @@ -461,7 +461,7 @@ void kp69_base_device::z80daisy_irq_reti() } else if (m_isr != 0) { - int level = 31 - count_leading_zeros(u32((m_isr & m_pgr) != 0 ? (m_isr & m_pgr) : m_isr)); + int level = 31 - count_leading_zeros_32(u32((m_isr & m_pgr) != 0 ? (m_isr & m_pgr) : m_isr)); assert(level >= 0 && level < 16); m_isr &= ~(1 << level); diff --git a/src/devices/machine/atmel_arm_aic.cpp b/src/devices/machine/atmel_arm_aic.cpp index 258bb3ae438..5e80a471477 100644 --- a/src/devices/machine/atmel_arm_aic.cpp +++ b/src/devices/machine/atmel_arm_aic.cpp @@ -53,7 +53,7 @@ uint32_t arm_aic_device::irq_vector_r() int midx = -1; do { - uint8_t idx = 31 - count_leading_zeros(mask); + uint8_t idx = 31 - count_leading_zeros_32(mask); if ((int)(m_aic_smr[idx] & 7) >= pri) { midx = idx; @@ -146,7 +146,7 @@ void arm_aic_device::check_irqs() int pri = get_level(); do { - uint8_t idx = 31 - count_leading_zeros(mask); + uint8_t idx = 31 - count_leading_zeros_32(mask); if ((int)(m_aic_smr[idx] & 7) > pri) { m_core_status |= 2; diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 7c43c35838d..cc1f92c5755 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -828,7 +828,8 @@ void netlist_mame_stream_output_device::sound_update_fill(write_stream_view &tar int sampindex; for (sampindex = 0; sampindex < m_buffer.size(); sampindex++) target.put(sampindex, m_buffer[sampindex]); - target.fill(m_cur, sampindex); + if (sampindex < target.samples()) + target.fill(m_cur, sampindex); } diff --git a/src/devices/machine/ns32202.cpp b/src/devices/machine/ns32202.cpp index 1a84ad180e9..4eb6f67f487 100644 --- a/src/devices/machine/ns32202.cpp +++ b/src/devices/machine/ns32202.cpp @@ -275,7 +275,7 @@ void ns32202_device::interrupt(void *ptr, s32 param) // check equal priority unmasked pending cascade interrupt if ((m_csrc & mask) && (m_ipnd & mask) && !(m_imsk & mask)) { - LOGMASKED(LOG_STATE, "unmasked pending cascade in-service interrupt %d\n", 31 - count_leading_zeros(mask)); + LOGMASKED(LOG_STATE, "unmasked pending cascade in-service interrupt %d\n", 31 - count_leading_zeros_32(mask)); accept = true; } @@ -285,7 +285,7 @@ void ns32202_device::interrupt(void *ptr, s32 param) // check unmasked pending interrupt if ((m_ipnd & mask) && !(m_imsk & mask)) { - LOGMASKED(LOG_STATE, "unmasked pending interrupt %d\n", 31 - count_leading_zeros(mask)); + LOGMASKED(LOG_STATE, "unmasked pending interrupt %d\n", 31 - count_leading_zeros_32(mask)); accept = true; break; } @@ -324,7 +324,7 @@ u8 ns32202_device::interrupt_acknowledge(bool side_effects) mask = (mask << 1) | (mask >> 15); } - unsigned const number = 31 - count_leading_zeros(mask); + unsigned const number = 31 - count_leading_zeros_32(mask); if (side_effects) { LOGMASKED(LOG_STATE, "acknowledge highest priority unmasked interrupt %d\n", number); @@ -400,7 +400,7 @@ u8 ns32202_device::interrupt_return(bool side_effects) // rotate priority mask mask = (mask << 1) | (mask >> 15); } - unsigned const number = 31 - count_leading_zeros(mask); + unsigned const number = 31 - count_leading_zeros_32(mask); if (side_effects) { diff --git a/src/devices/machine/sensorboard.cpp b/src/devices/machine/sensorboard.cpp index 8970726cf50..3d4188396dd 100644 --- a/src/devices/machine/sensorboard.cpp +++ b/src/devices/machine/sensorboard.cpp @@ -497,7 +497,7 @@ INPUT_CHANGED_MEMBER(sensorboard_device::sensor) INPUT_CHANGED_MEMBER(sensorboard_device::ui_spawn) { - u8 pos = (newval) ? (u8)param : 32 - count_leading_zeros(m_inp_spawn->read()); + u8 pos = (newval) ? (u8)param : 32 - count_leading_zeros_32(m_inp_spawn->read()); if (pos == 0 || pos > m_maxspawn) return; diff --git a/src/devices/machine/smartmed.cpp b/src/devices/machine/smartmed.cpp index 0d0643c1965..0a7c8911571 100644 --- a/src/devices/machine/smartmed.cpp +++ b/src/devices/machine/smartmed.cpp @@ -124,9 +124,8 @@ void nand_device::device_start() image_init_result smartmedia_image_device::smartmedia_format_1() { SM_disk_image_header custom_header; - int bytes_read; - bytes_read = fread(&custom_header, sizeof(custom_header)); + const int bytes_read = fread(&custom_header, sizeof(custom_header)); if (bytes_read != sizeof(custom_header)) { return image_init_result::FAIL; @@ -207,6 +206,7 @@ int smartmedia_image_device::detect_geometry( uint8_t id1, uint8_t id2) { switch (id2) { + case 0x73 : m_page_data_size = 0x0200; m_num_pages = 0x08000; m_page_total_size = 0x0210; m_log2_pages_per_block = 5; result = true; break; case 0x75 : m_page_data_size = 0x0200; m_num_pages = 0x10000; m_page_total_size = 0x0210; m_log2_pages_per_block = 5; result = true; break; } } @@ -219,9 +219,8 @@ int smartmedia_image_device::detect_geometry( uint8_t id1, uint8_t id2) image_init_result smartmedia_image_device::smartmedia_format_2() { disk_image_format_2_header custom_header; - int bytes_read, i, j; - bytes_read = fread(&custom_header, sizeof(custom_header)); + const int bytes_read = fread(&custom_header, sizeof(custom_header)); if (bytes_read != sizeof(custom_header)) { return image_init_result::FAIL; @@ -250,18 +249,19 @@ image_init_result smartmedia_image_device::smartmedia_format_2() m_accumulated_status = 0; m_pagereg = std::make_unique<uint8_t[]>(m_page_total_size); m_id_len = 3; - memcpy( m_id, custom_header.data1, m_id_len); + memcpy(m_id, custom_header.data1, m_id_len); m_mp_opcode = 0; m_col_address_cycles = 1; m_row_address_cycles = (m_num_pages > 0x10000) ? 3 : 2; m_sequential_row_read = 1; - for (i=0;i<8;i++) + for (int i = 0; i < 8; i++) { - memcpy( m_data_uid_ptr.get() + i * 32, custom_header.data2, 16); - for (j=0;j<16;j++) m_data_uid_ptr[i*32+16+j] = custom_header.data2[j] ^ 0xFF; + memcpy(m_data_uid_ptr.get() + i * 32, custom_header.data2, 16); + for (int j = 0; j < 16; j++) + m_data_uid_ptr[i * 32 + 16 + j] = custom_header.data2[j] ^ 0xFF; } - memcpy( m_data_uid_ptr.get() + 256, custom_header.data3, 16); + memcpy(m_data_uid_ptr.get() + 256, custom_header.data3, 16); fread(m_feeprom_data, m_page_total_size*m_num_pages); @@ -281,9 +281,9 @@ image_init_result smartmedia_image_device::call_load() result = smartmedia_format_1(); if (result != image_init_result::PASS) { - // try format 2 - fseek( position, SEEK_SET); - result = smartmedia_format_2(); + // try format 2 + fseek(position, SEEK_SET); + result = smartmedia_format_2(); } return result; } @@ -299,10 +299,9 @@ void smartmedia_image_device::call_unload() if (m_image_format == 1) { SM_disk_image_header custom_header; - int bytes_read; - fseek( 0, SEEK_SET); - bytes_read = fread( &custom_header, sizeof( custom_header)); - if (bytes_read == sizeof( custom_header)) + fseek(0, SEEK_SET); + const int bytes_read = fread(&custom_header, sizeof(custom_header)); + if (bytes_read == sizeof(custom_header)) { if (custom_header.version == 0) { @@ -337,7 +336,7 @@ void smartmedia_image_device::call_unload() m_status = 0xC0; m_accumulated_status = 0; m_pagereg = std::make_unique<uint8_t[]>(m_page_total_size); - memset( m_id, 0, sizeof( m_id)); + memset(m_id, 0, sizeof(m_id)); m_id_len = 0; m_mp_opcode = 0; m_mode_3065 = 0; @@ -390,8 +389,8 @@ void nand_device::command_w(uint8_t data) m_mode_3065 = 0; if (!m_write_rnb.isnull()) { - m_write_rnb( 0); - m_write_rnb( 1); + m_write_rnb(0); + m_write_rnb(1); } break; case 0x00: // Read (1st cycle) @@ -422,10 +421,10 @@ void nand_device::command_w(uint8_t data) } else { - m_mode = SM_M_READ; - m_pointer_mode = SM_PM_C; - m_page_addr = 0; - m_addr_load_ptr = 0; + m_mode = SM_M_READ; + m_pointer_mode = SM_PM_C; + m_page_addr = 0; + m_addr_load_ptr = 0; } break; case 0x80: // Page Program (1st cycle) @@ -444,11 +443,10 @@ void nand_device::command_w(uint8_t data) } else { - int i; m_status = (m_status & 0x80) | m_accumulated_status; //logerror( "smartmedia: program, page_addr %08X\n", m_page_addr); - for (i=0; i<m_page_total_size; i++) - m_feeprom_data[m_page_addr*m_page_total_size + i] &= m_pagereg[i]; + for (int i = 0; i < m_page_total_size; i++) + m_feeprom_data[m_page_addr * m_page_total_size + i] &= m_pagereg[i]; m_status |= 0x40; if (data == 0x15) m_accumulated_status = m_status & 0x1f; @@ -457,13 +455,13 @@ void nand_device::command_w(uint8_t data) m_mode = SM_M_INIT; if (!m_write_rnb.isnull()) { - m_write_rnb( 0); - m_write_rnb( 1); + m_write_rnb(0); + m_write_rnb(1); } } break; - /*case 0x11: - break;*/ + //case 0x11: + // break; case 0x60: // Block Erase (1st cycle) m_mode = SM_M_ERASE; m_page_addr = 0; @@ -486,22 +484,22 @@ void nand_device::command_w(uint8_t data) m_pointer_mode = SM_PM_A; if (!m_write_rnb.isnull()) { - m_write_rnb( 0); - m_write_rnb( 1); + m_write_rnb(0); + m_write_rnb(1); } } break; case 0x70: // Read Status m_mode = SM_M_READSTATUS; break; - /*case 0x71: - break;*/ + //case 0x71: + // break; case 0x90: // Read ID m_mode = SM_M_READID; m_addr_load_ptr = 0; break; - /*case 0x91: - break;*/ + //case 0x91: + // break; case 0x30: // Read (2nd cycle) if (m_col_address_cycles == 1) { @@ -523,8 +521,8 @@ void nand_device::command_w(uint8_t data) { if (!m_write_rnb.isnull()) { - m_write_rnb( 0); - m_write_rnb( 1); + m_write_rnb(0); + m_write_rnb(1); } } } @@ -622,12 +620,12 @@ void nand_device::address_w(uint8_t data) if (m_addr_load_ptr < m_col_address_cycles) { m_byte_addr &= ~(0xFF << (m_addr_load_ptr * 8)); - m_byte_addr |= (data << (m_addr_load_ptr * 8)); + m_byte_addr |= (data << (m_addr_load_ptr * 8)); } else if (m_addr_load_ptr < m_col_address_cycles + m_row_address_cycles) { m_page_addr &= ~(0xFF << ((m_addr_load_ptr - m_col_address_cycles) * 8)); - m_page_addr |= (data << ((m_addr_load_ptr - m_col_address_cycles) * 8)); + m_page_addr |= (data << ((m_addr_load_ptr - m_col_address_cycles) * 8)); } } m_addr_load_ptr++; @@ -636,7 +634,7 @@ void nand_device::address_w(uint8_t data) if (m_addr_load_ptr < m_row_address_cycles) { m_page_addr &= ~(0xFF << (m_addr_load_ptr * 8)); - m_page_addr |= (data << (m_addr_load_ptr * 8)); + m_page_addr |= (data << (m_addr_load_ptr * 8)); } m_addr_load_ptr++; break; @@ -645,7 +643,7 @@ void nand_device::address_w(uint8_t data) if (m_addr_load_ptr < m_col_address_cycles) { m_byte_addr &= ~(0xFF << (m_addr_load_ptr * 8)); - m_byte_addr |= (data << (m_addr_load_ptr * 8)); + m_byte_addr |= (data << (m_addr_load_ptr * 8)); } m_addr_load_ptr++; break; @@ -682,7 +680,10 @@ uint8_t nand_device::data_r() { if (m_byte_addr < m_page_total_size) { - reply = m_feeprom_data[m_page_addr*m_page_total_size + m_byte_addr]; + if (m_page_addr < m_num_pages) + reply = m_feeprom_data[m_page_addr * m_page_total_size + m_byte_addr]; + else + reply = 0xff; } else { @@ -691,7 +692,11 @@ uint8_t nand_device::data_r() } else { - reply = m_data_uid_ptr[m_page_addr*m_page_total_size + m_byte_addr]; + // FIXME: this appears to be incorrect, m_data_uid_ptr is a smaller structure of 256*16 + // this code would always result in reading past the buffer + uint32_t addr = m_page_addr * m_page_total_size + m_byte_addr; + if (addr < 256 + 16) + reply = m_data_uid_ptr[addr]; } m_byte_addr++; if ((m_byte_addr == m_page_total_size) && (m_sequential_row_read != 0)) diff --git a/src/devices/machine/z80pio.cpp b/src/devices/machine/z80pio.cpp index d269891e333..e1664055f21 100644 --- a/src/devices/machine/z80pio.cpp +++ b/src/devices/machine/z80pio.cpp @@ -601,11 +601,6 @@ void z80pio_device::pio_port::control_write(uint8_t data) // load interrupt vector m_vector = data; if (LOG) m_device->logerror("Z80PIO Port %c Interrupt Vector: %02x\n", 'A' + m_index, data); - - // set interrupt enable - m_icw |= ICW_ENABLE_INT; - m_ie = true; - check_interrupts(); } else { diff --git a/src/devices/sound/c140.cpp b/src/devices/sound/c140.cpp index c6e5a05271e..b04a35a0f31 100644 --- a/src/devices/sound/c140.cpp +++ b/src/devices/sound/c140.cpp @@ -478,8 +478,10 @@ inline u8 c140_device::keyon_status_read(u16 offset) u8 c140_device::c140_r(offs_t offset) { offset &= 0x1ff; - if ((offset & 0xf) == 0x5) + + if ((offset & 0xf) == 0x5 && offset < 0x180) return keyon_status_read(offset); + return m_REG[offset]; } @@ -552,9 +554,14 @@ void c140_device::c140_w(offs_t offset, u8 data) u8 c219_device::c219_r(offs_t offset) { + offset &= 0x1ff; + // assume same as c140 // TODO: what happens here on reading unmapped voice regs? - return c140_r(offset); + if ((offset & 0xf) == 0x5 && offset < 0x100) + return keyon_status_read(offset); + + return m_REG[offset]; } diff --git a/src/devices/video/dl1416.cpp b/src/devices/video/dl1416.cpp index 2508bb179fb..4321192e981 100644 --- a/src/devices/video/dl1416.cpp +++ b/src/devices/video/dl1416.cpp @@ -185,15 +185,12 @@ dl1414_device::dl1414_device( device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock) - , m_update_cb(*this) - , m_digit_ram{ 0x00, 0x00, 0x00, 0x00 } - , m_cursor_state{ false, false, false, false } , m_wr_in(true) - , m_ce_in(true) - , m_ce_latch(true) , m_addr_in(0x00) - , m_addr_latch(0x00) , m_data_in(0x00) + , m_update_cb(*this) + , m_digit_ram{ 0x00, 0x00, 0x00, 0x00 } + , m_cursor_state{ false, false, false, false } { } @@ -204,7 +201,10 @@ dl1416_device::dl1416_device( device_t *owner, u32 clock) : dl1414_device(mconfig, type, tag, owner, clock) + , m_ce_in(true) + , m_ce_latch(true) , m_cu_in(true) + , m_addr_latch(0x00) { } @@ -220,18 +220,12 @@ void dl1414_device::device_start() save_item(NAME(m_digit_ram)); save_item(NAME(m_cursor_state)); save_item(NAME(m_wr_in)); - save_item(NAME(m_ce_in)); - save_item(NAME(m_ce_latch)); save_item(NAME(m_addr_in)); - save_item(NAME(m_addr_latch)); save_item(NAME(m_data_in)); // set initial state for input lines m_wr_in = true; - m_ce_in = true; - m_ce_latch = true; m_addr_in = 0x00; - m_addr_latch = 0x00; m_data_in = 0x00; // randomise internal RAM @@ -249,10 +243,16 @@ void dl1416_device::device_start() dl1414_device::device_start(); // register for state saving + save_item(NAME(m_ce_in)); + save_item(NAME(m_ce_latch)); save_item(NAME(m_cu_in)); + save_item(NAME(m_addr_latch)); // set initial state for input lines + m_ce_in = true; + m_ce_latch = true; m_cu_in = true; + m_addr_latch = 0x00; } //------------------------------------------------- @@ -277,6 +277,16 @@ WRITE_LINE_MEMBER( dl1414_device::wr_w ) { m_wr_in = bool(state); if (m_wr_in) + bus_w(m_addr_in, m_data_in); + } +} + +WRITE_LINE_MEMBER( dl1416_device::wr_w ) +{ + if (bool(state) != m_wr_in) + { + m_wr_in = bool(state); + if (m_wr_in) { if (!m_ce_latch) bus_w(m_addr_latch, m_data_in); @@ -289,7 +299,7 @@ WRITE_LINE_MEMBER( dl1414_device::wr_w ) } } -WRITE_LINE_MEMBER( dl1414_device::ce_w ) +WRITE_LINE_MEMBER( dl1416_device::ce_w ) { m_ce_in = bool(state); } diff --git a/src/devices/video/dl1416.h b/src/devices/video/dl1416.h index 9c4b6228ee3..ce1d61071f4 100644 --- a/src/devices/video/dl1416.h +++ b/src/devices/video/dl1416.h @@ -7,7 +7,7 @@ * 4-Digit 16-Segment Alphanumeric Intelligent Display * with Memory/Decoder/Driver * - * See video/dl1416.c for more info + * See video/dl1416.cpp for more info * ****************************************************************************/ @@ -36,8 +36,7 @@ public: auto update() { return m_update_cb.bind(); } // signal-level interface - DECLARE_WRITE_LINE_MEMBER(wr_w); // write strobe (rising edge) - DECLARE_WRITE_LINE_MEMBER(ce_w); // chip enable (active low) + virtual DECLARE_WRITE_LINE_MEMBER(wr_w); // write strobe (rising edge) void addr_w(u8 state); void data_w(u8 state); @@ -59,23 +58,24 @@ protected: void set_cursor_state(offs_t offset, bool state); virtual u16 translate(u8 digit, bool cursor) const = 0; + // input line state + bool m_wr_in; + u8 m_addr_in; + u8 m_data_in; + private: devcb_write16 m_update_cb; // internal state u8 m_digit_ram[4]; // holds the digit code for each position bool m_cursor_state[4]; // holds the cursor state for each position - - // input line state - bool m_wr_in; - bool m_ce_in, m_ce_latch; - u8 m_addr_in, m_addr_latch; - u8 m_data_in; }; class dl1416_device : public dl1414_device { public: + virtual DECLARE_WRITE_LINE_MEMBER(wr_w) override; + DECLARE_WRITE_LINE_MEMBER(ce_w); // chip enable (active low) DECLARE_WRITE_LINE_MEMBER(cu_w); // cursor enable (active low) protected: @@ -93,7 +93,9 @@ protected: private: // input line state + bool m_ce_in, m_ce_latch; bool m_cu_in; + u8 m_addr_latch; }; #endif // MAME_VIDEO_DL1416_H diff --git a/src/devices/video/hd61830.cpp b/src/devices/video/hd61830.cpp index 55bf2bbd588..235d250b405 100644 --- a/src/devices/video/hd61830.cpp +++ b/src/devices/video/hd61830.cpp @@ -440,7 +440,7 @@ void hd61830_device::draw_char(bitmap_ind16 &bitmap, const rectangle &cliprect, { // cursor off, character blink if (!cursor) - pixel = m_cursor ? pixel : 0; + pixel = m_cursor ? 1 : pixel; // cursor blink if (cursor && (cl == m_cp)) @@ -483,8 +483,8 @@ void hd61830_device::update_text(bitmap_ind16 &bitmap, const rectangle &cliprect md1 = readbyte(rac2); md2 = readbyte(rac2+1); - draw_char(bitmap, cliprect, ma, x, y + rows, md1); - draw_char(bitmap, cliprect, ma+1, x+1, y + rows, md2); + draw_char(bitmap, cliprect, ma + (rows * m_hn), x, y + rows, md1); + draw_char(bitmap, cliprect, ma+1 + (rows * m_hn), x+1, y + rows, md2); ma+=2; rac1+=2; diff --git a/src/devices/video/pc_vga.cpp b/src/devices/video/pc_vga.cpp index d72899d2de2..2edaaca392a 100644 --- a/src/devices/video/pc_vga.cpp +++ b/src/devices/video/pc_vga.cpp @@ -36,11 +36,11 @@ ROM declarations: (oti 037 chip) - ROM_LOAD("oakvga.bin", 0xc0000, 0x8000, 0x318c5f43) + ROM_LOAD("oakvga.bin", 0xc0000, 0x8000, CRC(318c5f43) SHA1(2aeb6cf737fd87dfd08c9f5b5bc421fcdbab4ce9) ) (tseng labs famous et4000 isa vga card (oem)) - ROM_LOAD("et4000b.bin", 0xc0000, 0x8000, 0xa903540d) + ROM_LOAD("et4000b.bin", 0xc0000, 0x8000, CRC(a903540d) SHA1(unknown) ) (tseng labs famous et4000 isa vga card) - ROM_LOAD("et4000.bin", 0xc0000, 0x8000, 0xf01e4be0) + ROM_LOAD("et4000.bin", 0xc0000, 0x8000, CRC(f01e4be0) SHA1(95d75ff41bcb765e50bd87a8da01835fd0aa01d5) ) ***************************************************************************/ diff --git a/src/devices/video/vooddefs.ipp b/src/devices/video/vooddefs.ipp index 6a169640947..d9726edf960 100644 --- a/src/devices/video/vooddefs.ipp +++ b/src/devices/video/vooddefs.ipp @@ -135,7 +135,7 @@ static inline int32_t fast_reciplog(int64_t value, int32_t *log2) } /* determine how many leading zeros in the value and shift it up high */ - lz = count_leading_zeros(temp); + lz = count_leading_zeros_32(temp); temp <<= lz; exp += lz; @@ -1852,15 +1852,15 @@ do wfloat = 0xffff; \ else \ { \ - int exp = count_leading_zeros(temp); \ + int exp = count_leading_zeros_32(temp); \ wfloat = ((exp << 12) | ((~temp >> (19 - exp)) & 0xfff)) + 1; \ } \ } \ \ /* compute depth value (W or Z) for this pixel */ \ - if (FBZMODE_WBUFFER_SELECT(FBZMODE)) \ + if (FBZMODE_WBUFFER_SELECT(FBZMODE)) \ { \ - if (!FBZMODE_DEPTH_FLOAT_SELECT(FBZMODE)) \ + if (!FBZMODE_DEPTH_FLOAT_SELECT(FBZMODE)) \ depthval = wfloat; \ else \ { \ @@ -1873,7 +1873,7 @@ do depthval = 0xffff; \ else \ { \ - int exp = count_leading_zeros(temp); \ + int exp = count_leading_zeros_32(temp); \ depthval = ((exp << 12) | ((~temp >> (19 - exp)) & 0xfff)) + 1; \ } \ } \ @@ -1884,11 +1884,11 @@ do CLAMPED_Z(ITERZ, FBZCOLORPATH, depthval); \ } \ /* add the bias */ \ - biasdepth = depthval; \ + biasdepth = depthval; \ if (FBZMODE_ENABLE_DEPTH_BIAS(FBZMODE)) \ { \ - biasdepth += (int16_t)vd->reg[zaColor].u; \ - CLAMP(biasdepth, 0, 0xffff); \ + biasdepth += (int16_t)vd->reg[zaColor].u; \ + CLAMP(biasdepth, 0, 0xffff); \ } @@ -1898,12 +1898,12 @@ do /* handle depth buffer testing */ \ if (FBZMODE_ENABLE_DEPTHBUF(FBZMODE)) \ { \ - int32_t depthsource; \ + int32_t depthsource; \ \ /* the source depth is either the iterated W/Z+bias or a */ \ /* constant value */ \ if (FBZMODE_DEPTH_SOURCE_COMPARE(FBZMODE) == 0) \ - depthsource = biasdepth; \ + depthsource = biasdepth; \ else \ depthsource = (uint16_t)vd->reg[zaColor].u; \ \ diff --git a/src/devices/video/voodoo.cpp b/src/devices/video/voodoo.cpp index 180a8d454c3..2b57e67e3de 100644 --- a/src/devices/video/voodoo.cpp +++ b/src/devices/video/voodoo.cpp @@ -3129,7 +3129,7 @@ int32_t voodoo_device::register_w(voodoo_device *vd, offs_t offset, uint32_t dat attoseconds_t refresh = vd->m_screen->frame_period().attoseconds(); attoseconds_t stdperiod, medperiod, vgaperiod; attoseconds_t stddiff, meddiff, vgadiff; - rectangle visarea; + rectangle visarea; if (vd->vd_type == TYPE_VOODOO_2) { @@ -3151,7 +3151,7 @@ int32_t voodoo_device::register_w(voodoo_device *vd, offs_t offset, uint32_t dat } /* create a new visarea */ - visarea.set(hbp, hbp + hvis - 1, vbp, vbp + vvis - 1); + visarea.set(hbp, hbp + std::max(hvis - 1, 0), vbp, vbp + std::max(vvis - 1, 0)); /* keep within bounds */ visarea.max_x = (std::min)(visarea.max_x, htotal - 1); |
