summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2021-06-21 13:53:49 -0700
committer Aaron Giles <aaron@aarongiles.com>2021-06-21 13:53:49 -0700
commit32dbba7d2d4513774b2d877b4c88f2d0760bcf54 (patch)
treef9e6426cf8dc28413c456bdbcd450c85cb302422 /src/devices
parent5522729235b3ce81c839f3932c1aadc14de59e2b (diff)
parent2709c0143a8c7009715242c135b28403eeffce8b (diff)
Merge branch 'master' into deprecateddeprecated
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/bus/a2bus/a2bus.h1
-rw-r--r--src/devices/bus/a2bus/a2mockingboard.cpp107
-rw-r--r--src/devices/bus/a2bus/a2mockingboard.h51
-rw-r--r--src/devices/bus/a2bus/titan3plus2.cpp334
-rw-r--r--src/devices/bus/a2bus/titan3plus2.h64
-rw-r--r--src/devices/bus/adam/exp.h8
-rw-r--r--src/devices/bus/bw2/exp.h7
-rw-r--r--src/devices/bus/cbm2/exp.cpp9
-rw-r--r--src/devices/bus/cbm2/exp.h7
-rw-r--r--src/devices/bus/coco/coco_multi.cpp123
-rw-r--r--src/devices/bus/coco/coco_multi.h1
-rw-r--r--src/devices/bus/coco/coco_wpk.cpp201
-rw-r--r--src/devices/bus/coco/coco_wpk.h94
-rw-r--r--src/devices/bus/coco/coco_wpk2p.cpp56
-rw-r--r--src/devices/bus/coco/coco_wpk2p.h41
-rw-r--r--src/devices/bus/coco/cococart.cpp65
-rw-r--r--src/devices/bus/coco/cococart.h3
-rw-r--r--src/devices/bus/coco/dragon_claw.cpp212
-rw-r--r--src/devices/bus/coco/dragon_claw.h59
-rw-r--r--src/devices/bus/coco/dragon_msx2.cpp191
-rw-r--r--src/devices/bus/coco/dragon_msx2.h53
-rw-r--r--src/devices/bus/coco/dragon_serial.cpp154
-rw-r--r--src/devices/bus/coco/dragon_serial.h52
-rw-r--r--src/devices/bus/generic/slot.h2
-rw-r--r--src/devices/bus/isa/isa_cards.cpp2
-rw-r--r--src/devices/bus/isa/lrk330.cpp130
-rw-r--r--src/devices/bus/isa/lrk330.h38
-rw-r--r--src/devices/bus/mc10/mc10_cart.cpp230
-rw-r--r--src/devices/bus/mc10/mc10_cart.h118
-rw-r--r--src/devices/bus/mc10/mcx128.cpp371
-rw-r--r--src/devices/bus/mc10/mcx128.h15
-rw-r--r--src/devices/bus/mc10/pak.cpp69
-rw-r--r--src/devices/bus/mc10/pak.h37
-rw-r--r--src/devices/bus/mc10/ram.cpp78
-rw-r--r--src/devices/bus/mc10/ram.h14
-rw-r--r--src/devices/bus/nes/act53.cpp66
-rw-r--r--src/devices/bus/nes/act53.h11
-rw-r--r--src/devices/bus/nes/nes_slot.h4
-rw-r--r--src/devices/bus/newbrain/eim.cpp2
-rw-r--r--src/devices/bus/newbrain/exp.h7
-rw-r--r--src/devices/bus/newbrain/fdc.cpp14
-rw-r--r--src/devices/bus/newbrain/fdc.h5
-rw-r--r--src/devices/bus/odyssey2/rom.cpp2
-rw-r--r--src/devices/bus/pet/exp.h7
-rw-r--r--src/devices/bus/plus4/c1551.cpp4
-rw-r--r--src/devices/bus/plus4/exp.cpp9
-rw-r--r--src/devices/bus/plus4/exp.h7
-rw-r--r--src/devices/bus/pofo/exp.h7
-rw-r--r--src/devices/bus/pofo/hpc104.cpp4
-rw-r--r--src/devices/bus/saitek_osa/expansion.cpp16
-rw-r--r--src/devices/bus/saitek_osa/expansion.h6
-rw-r--r--src/devices/bus/saitek_osa/modules.cpp22
-rw-r--r--src/devices/bus/saitek_osa/modules.h16
-rw-r--r--src/devices/bus/vic10/exp.cpp9
-rw-r--r--src/devices/bus/vic10/exp.h8
-rw-r--r--src/devices/bus/vic20/exp.h8
-rw-r--r--src/devices/bus/vip/exp.h7
-rw-r--r--src/devices/bus/vme/vme.cpp54
-rw-r--r--src/devices/bus/vme/vme.h30
-rw-r--r--src/devices/bus/vme/vme_fccpu20.cpp2
-rw-r--r--src/devices/bus/vme/vme_fcisio.cpp1
-rw-r--r--src/devices/bus/vme/vme_fcscsi.cpp1
-rw-r--r--src/devices/bus/vme/vme_hcpu30.cpp2
-rw-r--r--src/devices/bus/vme/vme_mvme350.cpp1
-rw-r--r--src/devices/bus/vme/vme_mzr8300.cpp1
-rw-r--r--src/devices/cpu/am29000/am29ops.h2
-rw-r--r--src/devices/cpu/arm7/arm7ops.cpp2
-rw-r--r--src/devices/cpu/drcbec.cpp14
-rw-r--r--src/devices/cpu/dspp/dspp.cpp2
-rw-r--r--src/devices/cpu/h8500/h8500.cpp3
-rw-r--r--src/devices/cpu/h8500/h8500.h10
-rw-r--r--src/devices/cpu/h8500/h8510.cpp2
-rw-r--r--src/devices/cpu/h8500/h8520.cpp11
-rw-r--r--src/devices/cpu/h8500/h8520.h8
-rw-r--r--src/devices/cpu/h8500/h8532.cpp11
-rw-r--r--src/devices/cpu/h8500/h8532.h8
-rw-r--r--src/devices/cpu/h8500/h8534.cpp23
-rw-r--r--src/devices/cpu/h8500/h8534.h19
-rw-r--r--src/devices/cpu/m68000/m68kfpu.cpp131
-rw-r--r--src/devices/cpu/m88000/m88000.cpp4
-rw-r--r--src/devices/cpu/mips/r4000.cpp4
-rw-r--r--src/devices/cpu/pdp8/hd6120.cpp43
-rw-r--r--src/devices/cpu/psx/gte.cpp4
-rw-r--r--src/devices/cpu/romp/romp.cpp2
-rw-r--r--src/devices/cpu/sharc/sharc.cpp53
-rw-r--r--src/devices/cpu/sharc/sharc.h5
-rw-r--r--src/devices/cpu/sharc/sharcdma.hxx140
-rw-r--r--src/devices/cpu/tms32031/32031ops.hxx16
-rw-r--r--src/devices/cpu/tms34010/34010ops.hxx6
-rw-r--r--src/devices/cpu/uml.cpp9
-rw-r--r--src/devices/cpu/unsp/unsp_fxxx.cpp4
-rw-r--r--src/devices/cpu/z80/kp69.cpp6
-rw-r--r--src/devices/machine/atmel_arm_aic.cpp4
-rw-r--r--src/devices/machine/netlist.cpp3
-rw-r--r--src/devices/machine/ns32202.cpp8
-rw-r--r--src/devices/machine/sensorboard.cpp2
-rw-r--r--src/devices/machine/smartmed.cpp93
-rw-r--r--src/devices/machine/z80pio.cpp5
-rw-r--r--src/devices/sound/c140.cpp11
-rw-r--r--src/devices/video/dl1416.cpp36
-rw-r--r--src/devices/video/dl1416.h20
-rw-r--r--src/devices/video/hd61830.cpp6
-rw-r--r--src/devices/video/pc_vga.cpp6
-rw-r--r--src/devices/video/vooddefs.ipp20
-rw-r--r--src/devices/video/voodoo.cpp4
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 &centronics(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);