summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine')
-rw-r--r--src/devices/machine/6525tpi.cpp22
-rw-r--r--src/devices/machine/6525tpi.h16
-rw-r--r--src/devices/machine/68153bim.cpp13
-rw-r--r--src/devices/machine/6821pia.cpp4
-rw-r--r--src/devices/machine/6821pia.h11
-rw-r--r--src/devices/machine/68307.cpp25
-rw-r--r--src/devices/machine/68307.h2
-rw-r--r--src/devices/machine/68340.cpp9
-rw-r--r--src/devices/machine/68340.h2
-rw-r--r--src/devices/machine/68340dma.cpp5
-rw-r--r--src/devices/machine/68340dma.h1
-rw-r--r--src/devices/machine/68340ser.cpp5
-rw-r--r--src/devices/machine/68340ser.h7
-rw-r--r--src/devices/machine/68340sim.cpp6
-rw-r--r--src/devices/machine/68340sim.h1
-rw-r--r--src/devices/machine/68340tmu.cpp10
-rw-r--r--src/devices/machine/68340tmu.h11
-rw-r--r--src/devices/machine/6840ptm.cpp4
-rw-r--r--src/devices/machine/6840ptm.h4
-rw-r--r--src/devices/machine/6850acia.cpp64
-rw-r--r--src/devices/machine/6850acia.h12
-rw-r--r--src/devices/machine/74157.cpp20
-rw-r--r--src/devices/machine/74157.h17
-rw-r--r--src/devices/machine/74165.cpp7
-rw-r--r--src/devices/machine/74166.cpp7
-rw-r--r--src/devices/machine/7474.h15
-rw-r--r--src/devices/machine/8042kbdc.cpp22
-rw-r--r--src/devices/machine/8042kbdc.h5
-rw-r--r--src/devices/machine/8364_paula.h14
-rw-r--r--src/devices/machine/adc0808.cpp14
-rw-r--r--src/devices/machine/adc0808.h8
-rw-r--r--src/devices/machine/adc0844.cpp6
-rw-r--r--src/devices/machine/adc0844.h6
-rw-r--r--src/devices/machine/aic6250.cpp17
-rw-r--r--src/devices/machine/aic6250.h13
-rw-r--r--src/devices/machine/aicartc.h7
-rw-r--r--src/devices/machine/akiko.cpp5
-rw-r--r--src/devices/machine/am9513.cpp8
-rw-r--r--src/devices/machine/am9513.h8
-rw-r--r--src/devices/machine/am9517a.cpp65
-rw-r--r--src/devices/machine/am9517a.h51
-rw-r--r--src/devices/machine/am9519.cpp8
-rw-r--r--src/devices/machine/am9519.h8
-rw-r--r--src/devices/machine/appldriv.h29
-rw-r--r--src/devices/machine/applefdc.h32
-rw-r--r--src/devices/machine/at29x.cpp4
-rw-r--r--src/devices/machine/at29x.h4
-rw-r--r--src/devices/machine/at_keybc.cpp24
-rw-r--r--src/devices/machine/at_keybc.h16
-rw-r--r--src/devices/machine/atapicdr.cpp10
-rw-r--r--src/devices/machine/ay31015.cpp70
-rw-r--r--src/devices/machine/ay31015.h20
-rw-r--r--src/devices/machine/bankdev.cpp18
-rw-r--r--src/devices/machine/bankdev.h42
-rw-r--r--src/devices/machine/clock.h8
-rw-r--r--src/devices/machine/com8116.cpp29
-rw-r--r--src/devices/machine/com8116.h22
-rw-r--r--src/devices/machine/cr511b.cpp14
-rw-r--r--src/devices/machine/cs4031.cpp80
-rw-r--r--src/devices/machine/cs4031.h72
-rw-r--r--src/devices/machine/diablo_hd.cpp15
-rw-r--r--src/devices/machine/diablo_hd.h3
-rw-r--r--src/devices/machine/dp8390.h33
-rw-r--r--src/devices/machine/dp83932c.cpp153
-rw-r--r--src/devices/machine/dp83932c.h111
-rw-r--r--src/devices/machine/ds1204.h3
-rw-r--r--src/devices/machine/ds1205.h3
-rw-r--r--src/devices/machine/ds128x.cpp58
-rw-r--r--src/devices/machine/ds128x.h25
-rw-r--r--src/devices/machine/ds1315.cpp16
-rw-r--r--src/devices/machine/ds1315.h10
-rw-r--r--src/devices/machine/ds75160a.h12
-rw-r--r--src/devices/machine/f3853.cpp353
-rw-r--r--src/devices/machine/f3853.h168
-rw-r--r--src/devices/machine/fdc37c665gt.cpp9
-rw-r--r--src/devices/machine/fdc37c93x.cpp4
-rw-r--r--src/devices/machine/gen_fifo.h11
-rw-r--r--src/devices/machine/genpc.cpp60
-rw-r--r--src/devices/machine/genpc.h29
-rw-r--r--src/devices/machine/hdc92x4.cpp4
-rw-r--r--src/devices/machine/hdc92x4.h4
-rw-r--r--src/devices/machine/i2cmem.cpp121
-rw-r--r--src/devices/machine/i2cmem.h89
-rw-r--r--src/devices/machine/i7220.cpp65
-rw-r--r--src/devices/machine/i8087.cpp14
-rw-r--r--src/devices/machine/i8087.h13
-rw-r--r--src/devices/machine/i8155.cpp26
-rw-r--r--src/devices/machine/i8155.h14
-rw-r--r--src/devices/machine/i82357.cpp307
-rw-r--r--src/devices/machine/i82357.h91
-rw-r--r--src/devices/machine/i82371sb.cpp25
-rw-r--r--src/devices/machine/i82371sb.h1
-rw-r--r--src/devices/machine/i8251.cpp8
-rw-r--r--src/devices/machine/i8251.h8
-rw-r--r--src/devices/machine/i8271.cpp37
-rw-r--r--src/devices/machine/i8271.h18
-rw-r--r--src/devices/machine/idectrl.cpp13
-rw-r--r--src/devices/machine/idectrl.h6
-rw-r--r--src/devices/machine/idehd.cpp7
-rw-r--r--src/devices/machine/ie15.cpp32
-rw-r--r--src/devices/machine/ie15_kbd.cpp5
-rw-r--r--src/devices/machine/input_merger.h22
-rw-r--r--src/devices/machine/ins8154.cpp71
-rw-r--r--src/devices/machine/ins8154.h13
-rw-r--r--src/devices/machine/ins8250.cpp2
-rw-r--r--src/devices/machine/intelfsh.h8
-rw-r--r--src/devices/machine/k054321.cpp2
-rw-r--r--src/devices/machine/keyboard.cpp6
-rw-r--r--src/devices/machine/ldp1000.h7
-rw-r--r--src/devices/machine/ldp1450.h7
-rw-r--r--src/devices/machine/ldpr8210.h2
-rw-r--r--src/devices/machine/ldstub.cpp8
-rw-r--r--src/devices/machine/ldstub.h21
-rw-r--r--src/devices/machine/ldv1000.cpp5
-rw-r--r--src/devices/machine/ldv1000.h6
-rw-r--r--src/devices/machine/ldvp931.cpp80
-rw-r--r--src/devices/machine/ldvp931.h18
-rw-r--r--src/devices/machine/legscsi.h2
-rw-r--r--src/devices/machine/mb8421.cpp16
-rw-r--r--src/devices/machine/mb8421.h16
-rw-r--r--src/devices/machine/mc146818.cpp12
-rw-r--r--src/devices/machine/mc146818.h8
-rw-r--r--src/devices/machine/mc6843.h2
-rw-r--r--src/devices/machine/mc6852.cpp7
-rw-r--r--src/devices/machine/mc6852.h32
-rw-r--r--src/devices/machine/mc6854.cpp4
-rw-r--r--src/devices/machine/mc6854.h4
-rw-r--r--src/devices/machine/mc68681.cpp35
-rw-r--r--src/devices/machine/mc68681.h37
-rw-r--r--src/devices/machine/mccs1850.h22
-rw-r--r--src/devices/machine/mcf5206e.cpp2
-rw-r--r--src/devices/machine/mcf5206e.h9
-rw-r--r--src/devices/machine/meters.h5
-rw-r--r--src/devices/machine/microtch.h12
-rw-r--r--src/devices/machine/mm5740.h38
-rw-r--r--src/devices/machine/mm58167.cpp4
-rw-r--r--src/devices/machine/mm58167.h13
-rw-r--r--src/devices/machine/mm58274c.cpp4
-rw-r--r--src/devices/machine/mm58274c.h17
-rw-r--r--src/devices/machine/mm74c922.h44
-rw-r--r--src/devices/machine/mos6526.cpp12
-rw-r--r--src/devices/machine/mos6526.h61
-rw-r--r--src/devices/machine/mos6530.h21
-rw-r--r--src/devices/machine/mos6530n.h128
-rw-r--r--src/devices/machine/mos6551.cpp36
-rw-r--r--src/devices/machine/mos6551.h6
-rw-r--r--src/devices/machine/mos6702.cpp4
-rw-r--r--src/devices/machine/mos6702.h14
-rw-r--r--src/devices/machine/mos8706.h11
-rw-r--r--src/devices/machine/mos8722.cpp2
-rw-r--r--src/devices/machine/mos8722.h2
-rw-r--r--src/devices/machine/mos8726.cpp4
-rw-r--r--src/devices/machine/mos8726.h15
-rw-r--r--src/devices/machine/mpu401.cpp10
-rw-r--r--src/devices/machine/msm58321.h31
-rw-r--r--src/devices/machine/msm6242.h5
-rw-r--r--src/devices/machine/myb3k_kbd.h21
-rw-r--r--src/devices/machine/ncr5380.h3
-rw-r--r--src/devices/machine/ncr5380n.cpp116
-rw-r--r--src/devices/machine/ncr5380n.h45
-rw-r--r--src/devices/machine/ncr5385.cpp4
-rw-r--r--src/devices/machine/ncr5385.h13
-rw-r--r--src/devices/machine/ncr5390.cpp337
-rw-r--r--src/devices/machine/ncr5390.h135
-rw-r--r--src/devices/machine/ncr539x.cpp4
-rw-r--r--src/devices/machine/ncr539x.h11
-rw-r--r--src/devices/machine/netlist.cpp375
-rw-r--r--src/devices/machine/netlist.h74
-rw-r--r--src/devices/machine/nmc9306.h11
-rw-r--r--src/devices/machine/nsc810.cpp4
-rw-r--r--src/devices/machine/nsc810.h63
-rw-r--r--src/devices/machine/nscsi_bus.cpp67
-rw-r--r--src/devices/machine/nscsi_bus.h28
-rw-r--r--src/devices/machine/nscsi_cb.h46
-rw-r--r--src/devices/machine/nscsi_cd.cpp296
-rw-r--r--src/devices/machine/nscsi_cd.h12
-rw-r--r--src/devices/machine/nscsi_hd.cpp147
-rw-r--r--src/devices/machine/nscsi_hd.h3
-rw-r--r--src/devices/machine/output_latch.h25
-rw-r--r--src/devices/machine/pc_fdc.cpp2
-rw-r--r--src/devices/machine/pc_lpt.cpp8
-rw-r--r--src/devices/machine/pckeybrd.h25
-rw-r--r--src/devices/machine/pdc.cpp3
-rw-r--r--src/devices/machine/pic8259.h4
-rw-r--r--src/devices/machine/pit8253.cpp11
-rw-r--r--src/devices/machine/pit8253.h6
-rw-r--r--src/devices/machine/pla.h21
-rw-r--r--src/devices/machine/pxa255.cpp26
-rw-r--r--src/devices/machine/rtc65271.cpp8
-rw-r--r--src/devices/machine/rtc65271.h8
-rw-r--r--src/devices/machine/scc2698b.cpp5
-rw-r--r--src/devices/machine/scnxx562.cpp9
-rw-r--r--src/devices/machine/sis85c496.cpp27
-rw-r--r--src/devices/machine/smc91c9x.cpp1141
-rw-r--r--src/devices/machine/smc91c9x.h252
-rw-r--r--src/devices/machine/smpc.cpp2
-rw-r--r--src/devices/machine/sonydriv.h18
-rw-r--r--src/devices/machine/spg110.cpp669
-rw-r--r--src/devices/machine/spg110.h220
-rw-r--r--src/devices/machine/spg2xx.cpp2451
-rw-r--r--src/devices/machine/spg2xx.h434
-rw-r--r--src/devices/machine/spg2xx_audio.cpp1258
-rw-r--r--src/devices/machine/spg2xx_audio.h372
-rw-r--r--src/devices/machine/spg2xx_io.cpp1313
-rw-r--r--src/devices/machine/spg2xx_io.h183
-rw-r--r--src/devices/machine/strata.cpp20
-rw-r--r--src/devices/machine/strata.h12
-rw-r--r--src/devices/machine/stvcd.cpp18
-rw-r--r--src/devices/machine/tc009xlvc.cpp2
-rw-r--r--src/devices/machine/terminal.cpp21
-rw-r--r--src/devices/machine/terminal.h2
-rw-r--r--src/devices/machine/ticket.h16
-rw-r--r--src/devices/machine/timekpr.cpp264
-rw-r--r--src/devices/machine/timekpr.h68
-rw-r--r--src/devices/machine/timer.h58
-rw-r--r--src/devices/machine/tmp68301.cpp62
-rw-r--r--src/devices/machine/tmp68301.h24
-rw-r--r--src/devices/machine/tms5501.cpp3
-rw-r--r--src/devices/machine/tms9901.cpp111
-rw-r--r--src/devices/machine/tms9901.h15
-rw-r--r--src/devices/machine/tms9902.cpp127
-rw-r--r--src/devices/machine/tms9902.h4
-rw-r--r--src/devices/machine/tms9914.cpp4
-rw-r--r--src/devices/machine/tms9914.h5
-rw-r--r--src/devices/machine/tube.cpp8
-rw-r--r--src/devices/machine/tube.h8
-rw-r--r--src/devices/machine/upd7002.cpp6
-rw-r--r--src/devices/machine/upd7002.h6
-rw-r--r--src/devices/machine/upd765.cpp139
-rw-r--r--src/devices/machine/upd765.h43
-rw-r--r--src/devices/machine/wd1010.cpp583
-rw-r--r--src/devices/machine/wd1010.h143
-rw-r--r--src/devices/machine/wd11c00_17.cpp9
-rw-r--r--src/devices/machine/wd11c00_17.h1
-rw-r--r--src/devices/machine/wd2010.cpp10
-rw-r--r--src/devices/machine/wd2010.h4
-rw-r--r--src/devices/machine/wd33c93.cpp984
-rw-r--r--src/devices/machine/wd33c93.h112
-rw-r--r--src/devices/machine/wd33c9x.cpp1064
-rw-r--r--src/devices/machine/wd33c9x.h32
-rw-r--r--src/devices/machine/wd7600.cpp128
-rw-r--r--src/devices/machine/wd7600.h88
-rw-r--r--src/devices/machine/x2201.cpp11
-rw-r--r--src/devices/machine/x2201.h1
-rw-r--r--src/devices/machine/xc1700e.cpp91
-rw-r--r--src/devices/machine/xc1700e.h118
-rw-r--r--src/devices/machine/ym2148.cpp4
-rw-r--r--src/devices/machine/ym2148.h4
-rw-r--r--src/devices/machine/z80scc.cpp14
-rw-r--r--src/devices/machine/z80scc.h1
-rw-r--r--src/devices/machine/z80sio.cpp20
251 files changed, 7902 insertions, 10910 deletions
diff --git a/src/devices/machine/6525tpi.cpp b/src/devices/machine/6525tpi.cpp
index 83d28fc0355..a82b09d104c 100644
--- a/src/devices/machine/6525tpi.cpp
+++ b/src/devices/machine/6525tpi.cpp
@@ -294,12 +294,12 @@ WRITE_LINE_MEMBER( tpi6525_device::i4_w )
}
}
-uint8_t tpi6525_device::pa_r()
+READ8_MEMBER( tpi6525_device::pa_r )
{
uint8_t data = m_in_a;
if (!m_in_pa_cb.isnull())
- data = m_in_pa_cb();
+ data = m_in_pa_cb(offset);
data = (data & ~m_ddr_a) | (m_ddr_a & m_port_a);
@@ -307,18 +307,18 @@ uint8_t tpi6525_device::pa_r()
}
-void tpi6525_device::pa_w(uint8_t data)
+WRITE8_MEMBER( tpi6525_device::pa_w )
{
m_in_a = data;
}
-uint8_t tpi6525_device::pb_r()
+READ8_MEMBER( tpi6525_device::pb_r )
{
uint8_t data = m_in_b;
if (!m_in_pb_cb.isnull())
- data = m_in_pb_cb();
+ data = m_in_pb_cb(offset);
data = (data & ~m_ddr_b) | (m_ddr_b & m_port_b);
@@ -326,18 +326,18 @@ uint8_t tpi6525_device::pb_r()
}
-void tpi6525_device::pb_w(uint8_t data)
+WRITE8_MEMBER( tpi6525_device::pb_w )
{
m_in_b = data;
}
-uint8_t tpi6525_device::pc_r()
+READ8_MEMBER( tpi6525_device::pc_r )
{
uint8_t data = m_in_c;
if (!m_in_pc_cb.isnull())
- data &= m_in_pc_cb();
+ data &= m_in_pc_cb(offset);
data = (data & ~m_ddr_c) | (m_ddr_c & m_port_c);
@@ -345,13 +345,13 @@ uint8_t tpi6525_device::pc_r()
}
-void tpi6525_device::pc_w(uint8_t data)
+WRITE8_MEMBER( tpi6525_device::pc_w )
{
m_in_c = data;
}
-uint8_t tpi6525_device::read(offs_t offset)
+READ8_MEMBER( tpi6525_device::read )
{
uint8_t data = 0xff;
@@ -466,7 +466,7 @@ uint8_t tpi6525_device::read(offs_t offset)
}
-void tpi6525_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( tpi6525_device::write )
{
DBG_LOG(machine(), 2, "tpi6525", ("%s write %.2x %.2x\n", tag(), offset, data));
diff --git a/src/devices/machine/6525tpi.h b/src/devices/machine/6525tpi.h
index 4052662d50a..5e1ec394fe4 100644
--- a/src/devices/machine/6525tpi.h
+++ b/src/devices/machine/6525tpi.h
@@ -53,8 +53,8 @@ public:
auto out_ca_cb() { return m_out_ca_cb.bind(); }
auto out_cb_cb() { return m_out_cb_cb.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
DECLARE_WRITE_LINE_MEMBER( i0_w );
DECLARE_WRITE_LINE_MEMBER( i1_w );
@@ -62,12 +62,12 @@ public:
DECLARE_WRITE_LINE_MEMBER( i3_w );
DECLARE_WRITE_LINE_MEMBER( i4_w );
- uint8_t pa_r();
- uint8_t pb_r();
- uint8_t pc_r();
- void pa_w(uint8_t data);
- void pb_w(uint8_t data);
- void pc_w(uint8_t data);
+ DECLARE_READ8_MEMBER( pa_r );
+ DECLARE_READ8_MEMBER( pb_r );
+ DECLARE_READ8_MEMBER( pc_r );
+ DECLARE_WRITE8_MEMBER( pa_w );
+ DECLARE_WRITE8_MEMBER( pb_w );
+ DECLARE_WRITE8_MEMBER( pc_w );
WRITE_LINE_MEMBER( pb0_w ) { port_line_w(m_in_b, 0, state); }
WRITE_LINE_MEMBER( pb1_w ) { port_line_w(m_in_b, 1, state); }
diff --git a/src/devices/machine/68153bim.cpp b/src/devices/machine/68153bim.cpp
index 8df821a813e..30be9ea5e81 100644
--- a/src/devices/machine/68153bim.cpp
+++ b/src/devices/machine/68153bim.cpp
@@ -67,13 +67,12 @@ DEFINE_DEVICE_TYPE(EI68C153, ei68c153_device, "ei68c153", "EPIC
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void bim68153_device::device_add_mconfig(machine_config &config)
-{
- MC68153_CHANNEL(config, m_chn[0], 0);
- MC68153_CHANNEL(config, m_chn[1], 0);
- MC68153_CHANNEL(config, m_chn[2], 0);
- MC68153_CHANNEL(config, m_chn[3], 0);
-}
+MACHINE_CONFIG_START(bim68153_device::device_add_mconfig)
+ MCFG_DEVICE_ADD(CHN0_TAG, MC68153_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHN1_TAG, MC68153_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHN2_TAG, MC68153_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHN3_TAG, MC68153_CHANNEL, 0)
+MACHINE_CONFIG_END
//**************************************************************************
// LIVE DEVICE
diff --git a/src/devices/machine/6821pia.cpp b/src/devices/machine/6821pia.cpp
index 60efe473f19..3bf21c9483b 100644
--- a/src/devices/machine/6821pia.cpp
+++ b/src/devices/machine/6821pia.cpp
@@ -576,7 +576,7 @@ uint8_t pia6821_device::control_b_r()
// read
//-------------------------------------------------
-uint8_t pia6821_device::read(offs_t offset)
+uint8_t pia6821_device::reg_r(uint8_t offset)
{
uint8_t ret;
@@ -846,7 +846,7 @@ void pia6821_device::control_b_w(uint8_t data)
// write
//-------------------------------------------------
-void pia6821_device::write(offs_t offset, uint8_t data)
+void pia6821_device::reg_w(uint8_t offset, uint8_t data)
{
switch (offset & 0x03)
{
diff --git a/src/devices/machine/6821pia.h b/src/devices/machine/6821pia.h
index 8457399cf1a..b31bf03183c 100644
--- a/src/devices/machine/6821pia.h
+++ b/src/devices/machine/6821pia.h
@@ -55,10 +55,13 @@ public:
auto irqa_handler() { return m_irqa_handler.bind(); }
auto irqb_handler() { return m_irqb_handler.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
- uint8_t read_alt(offs_t offset) { return read(((offset << 1) & 0x02) | ((offset >> 1) & 0x01)); }
- void write_alt(offs_t offset, uint8_t data) { write(((offset << 1) & 0x02) | ((offset >> 1) & 0x01), data); }
+ uint8_t reg_r(uint8_t offset);
+ void reg_w(uint8_t offset, uint8_t data);
+
+ DECLARE_READ8_MEMBER( read ) { return reg_r(offset); }
+ DECLARE_WRITE8_MEMBER( write ) { reg_w(offset, data); }
+ DECLARE_READ8_MEMBER( read_alt ) { return reg_r(((offset << 1) & 0x02) | ((offset >> 1) & 0x01)); }
+ DECLARE_WRITE8_MEMBER( write_alt ) { reg_w(((offset << 1) & 0x02) | ((offset >> 1) & 0x01), data); }
uint8_t port_b_z_mask() const { return ~m_ddr_b; } // see first note in .c
void set_port_a_z_mask(uint8_t data) { m_port_a_z_mask = data; }// see second note in .c
diff --git a/src/devices/machine/68307.cpp b/src/devices/machine/68307.cpp
index ae13e090488..421d5f06da2 100644
--- a/src/devices/machine/68307.cpp
+++ b/src/devices/machine/68307.cpp
@@ -40,15 +40,14 @@ void m68307_cpu_device::m68307_internal_map(address_map &map)
}
-void m68307_cpu_device::device_add_mconfig(machine_config &config)
-{
- MC68681(config, m_duart, 16000000/4); // ?? Mhz - should be specified in inline config
- m_duart->irq_cb().set(FUNC(m68307_cpu_device::m68307_duart_irq_handler));
- m_duart->a_tx_cb().set(FUNC(m68307_cpu_device::m68307_duart_txa));
- m_duart->b_tx_cb().set(FUNC(m68307_cpu_device::m68307_duart_txb));
- m_duart->inport_cb().set(FUNC(m68307_cpu_device::m68307_duart_input_r));
- m_duart->outport_cb().set(FUNC(m68307_cpu_device::m68307_duart_output_w));
-}
+MACHINE_CONFIG_START(m68307_cpu_device::device_add_mconfig)
+ MCFG_DEVICE_ADD("internal68681", MC68681, 16000000/4) // ?? Mhz - should be specified in inline config
+ MCFG_MC68681_IRQ_CALLBACK(WRITELINE(*this, m68307_cpu_device, m68307_duart_irq_handler))
+ MCFG_MC68681_A_TX_CALLBACK(WRITELINE(*this, m68307_cpu_device, m68307_duart_txa))
+ MCFG_MC68681_B_TX_CALLBACK(WRITELINE(*this, m68307_cpu_device, m68307_duart_txb))
+ MCFG_MC68681_INPORT_CALLBACK(READ8(*this, m68307_cpu_device, m68307_duart_input_r))
+ MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(*this, m68307_cpu_device, m68307_duart_output_w))
+MACHINE_CONFIG_END
m68307_cpu_device::m68307_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -90,14 +89,6 @@ void m68307_cpu_device::device_reset()
set_ipl(0);
}
-void m68307_cpu_device::m68k_reset_peripherals()
-{
- m_duart->reset();
-
- if (m_m68307MBUS) m_m68307MBUS->reset();
- if (m_m68307TIMER) m_m68307TIMER->reset();
-}
-
/* todo: is it possible to calculate the address map based on CS when they change
and install handlers? Going through this logic for every memory access is
diff --git a/src/devices/machine/68307.h b/src/devices/machine/68307.h
index 6d5ef10b61c..591d0c9cced 100644
--- a/src/devices/machine/68307.h
+++ b/src/devices/machine/68307.h
@@ -44,8 +44,6 @@ protected:
virtual uint32_t execute_min_cycles() const override { return 4; }
virtual uint32_t execute_max_cycles() const override { return 158; }
- virtual void m68k_reset_peripherals() override;
-
private:
void set_ipl(int level);
DECLARE_WRITE_LINE_MEMBER(timer0_interrupt);
diff --git a/src/devices/machine/68340.cpp b/src/devices/machine/68340.cpp
index bae8be35b62..e9f8ba7ba8e 100644
--- a/src/devices/machine/68340.cpp
+++ b/src/devices/machine/68340.cpp
@@ -262,12 +262,3 @@ void m68340_cpu_device::device_start()
m_int_ack_callback = device_irq_acknowledge_delegate(FUNC(m68340_cpu_device::int_ack), this);
}
-
-void m68340_cpu_device::m68k_reset_peripherals()
-{
- m_m68340SIM->module_reset();
- m_m68340DMA->module_reset();
- m_serial->module_reset();
- m_timer[0]->module_reset();
- m_timer[1]->module_reset();
-}
diff --git a/src/devices/machine/68340.h b/src/devices/machine/68340.h
index 23f3ed6b147..12af250c5b2 100644
--- a/src/devices/machine/68340.h
+++ b/src/devices/machine/68340.h
@@ -49,8 +49,6 @@ protected:
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
- virtual void m68k_reset_peripherals() override;
-
private:
required_device<mc68340_serial_module_device> m_serial;
required_device_array<mc68340_timer_module_device, 2> m_timer;
diff --git a/src/devices/machine/68340dma.cpp b/src/devices/machine/68340dma.cpp
index 4a79a4504fc..6649aeb2a94 100644
--- a/src/devices/machine/68340dma.cpp
+++ b/src/devices/machine/68340dma.cpp
@@ -26,9 +26,4 @@ WRITE32_MEMBER( m68340_cpu_device::m68340_internal_dma_w )
void m68340_dma::reset()
{
- module_reset();
-}
-
-void m68340_dma::module_reset()
-{
}
diff --git a/src/devices/machine/68340dma.h b/src/devices/machine/68340dma.h
index 8bec4fb88a7..3a92b4e9a49 100644
--- a/src/devices/machine/68340dma.h
+++ b/src/devices/machine/68340dma.h
@@ -10,7 +10,6 @@ class m68340_dma
{
public:
void reset();
- void module_reset();
};
#endif // MAME_MACHINE_68340DMA_H
diff --git a/src/devices/machine/68340ser.cpp b/src/devices/machine/68340ser.cpp
index e0fc3b29fde..fcf6708305e 100644
--- a/src/devices/machine/68340ser.cpp
+++ b/src/devices/machine/68340ser.cpp
@@ -157,9 +157,4 @@ mc68340_serial_module_device::mc68340_serial_module_device(const machine_config
{
}
-void mc68340_serial_module_device::module_reset()
-{
- mc68340_duart_device::device_reset();
-}
-
DEFINE_DEVICE_TYPE(MC68340_SERIAL_MODULE, mc68340_serial_module_device, "mc68340sermod", "MC68340 Serial Module")
diff --git a/src/devices/machine/68340ser.h b/src/devices/machine/68340ser.h
index b9775f2ad86..e658d719c05 100644
--- a/src/devices/machine/68340ser.h
+++ b/src/devices/machine/68340ser.h
@@ -7,6 +7,11 @@
#include "machine/mc68681.h"
+// MCFG macros to hide the implementation
+#define MCFG_MC68340SER_IRQ_CALLBACK(_cb) MCFG_MC68681_IRQ_CALLBACK(_cb)
+#define MCFG_MC68340SER_A_TX_CALLBACK(_cb) MCFG_MC68681_A_TX_CALLBACK(_cb)
+#define MCFG_MC68340SER_B_TX_CALLBACK(_cb) MCFG_MC68681_B_TX_CALLBACK(_cb)
+
class m68340_cpu_device;
class mc68340_serial_module_device : public mc68340_duart_device
@@ -27,8 +32,6 @@ public:
uint8_t irq_vector() const { return m_ivr; }
uint8_t arbitrate(uint8_t level) const { return (irq_level() == level) ? (m_mcrl & REG_MCRL_ARBLV) : 0; }
- void module_reset();
-
protected:
m68340_cpu_device *m_cpu;
diff --git a/src/devices/machine/68340sim.cpp b/src/devices/machine/68340sim.cpp
index 3dbbfcb0733..cf299ba2b22 100644
--- a/src/devices/machine/68340sim.cpp
+++ b/src/devices/machine/68340sim.cpp
@@ -493,12 +493,6 @@ void m68340_sim::reset()
m_pit_irq = false;
}
-void m68340_sim::module_reset()
-{
- // SYS set in RSR, nothing else happens
- m_avr_rsr = (m_avr_rsr & 0xff00) | 0x02;
-}
-
/* do_tick_pit works on whole clock cycles, no flank support */
void m68340_cpu_device::do_tick_pit()
{
diff --git a/src/devices/machine/68340sim.h b/src/devices/machine/68340sim.h
index 34358e02eff..3c839984db2 100644
--- a/src/devices/machine/68340sim.h
+++ b/src/devices/machine/68340sim.h
@@ -35,7 +35,6 @@ public:
bool m_pit_irq;
void reset();
- void module_reset();
enum {
REG_MCR = 0x00,
diff --git a/src/devices/machine/68340tmu.cpp b/src/devices/machine/68340tmu.cpp
index 801a9802557..1ceaf65f600 100644
--- a/src/devices/machine/68340tmu.cpp
+++ b/src/devices/machine/68340tmu.cpp
@@ -308,16 +308,6 @@ void mc68340_timer_module_device::device_start()
m_tin_in_cb.resolve_safe();
}
-void mc68340_timer_module_device::device_reset()
-{
- module_reset();
-}
-
-void mc68340_timer_module_device::module_reset()
-{
- // TODO
-}
-
void mc68340_timer_module_device::do_timer_irq()
{
assert((m_sr & (REG_SR_TO | REG_SR_TG | REG_SR_TC)) != 0);
diff --git a/src/devices/machine/68340tmu.h b/src/devices/machine/68340tmu.h
index 8952632792b..0582debd475 100644
--- a/src/devices/machine/68340tmu.h
+++ b/src/devices/machine/68340tmu.h
@@ -14,6 +14,9 @@ class mc68340_timer_module_device : public device_t
public:
mc68340_timer_module_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ // device-level overrides
+ virtual void device_start() override;
+
READ16_MEMBER( read );
WRITE16_MEMBER( write );
DECLARE_WRITE_LINE_MEMBER( tin_w );
@@ -23,13 +26,7 @@ public:
uint8_t irq_vector() const { return m_ir & REG_IR_INTVEC; }
uint8_t arbitrate(uint8_t level) const { return (irq_level() == level) ? (m_mcr & REG_MCR_ARBLV) : 0; }
- void module_reset();
-
-protected:
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
+ protected:
m68340_cpu_device *m_cpu;
uint16_t m_mcr;
diff --git a/src/devices/machine/6840ptm.cpp b/src/devices/machine/6840ptm.cpp
index 36b2cd5002b..bf1e6f4adb1 100644
--- a/src/devices/machine/6840ptm.cpp
+++ b/src/devices/machine/6840ptm.cpp
@@ -423,7 +423,7 @@ void ptm6840_device::reload_count(int idx)
// read - Read Timer
//-------------------------------------------------
-uint8_t ptm6840_device::read(offs_t offset)
+READ8_MEMBER( ptm6840_device::read )
{
int val;
@@ -487,7 +487,7 @@ uint8_t ptm6840_device::read(offs_t offset)
// write - Write Timer
//-------------------------------------------------
-void ptm6840_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( ptm6840_device::write )
{
switch ( offset )
{
diff --git a/src/devices/machine/6840ptm.h b/src/devices/machine/6840ptm.h
index 2c913a97b4c..ad5859b771b 100644
--- a/src/devices/machine/6840ptm.h
+++ b/src/devices/machine/6840ptm.h
@@ -39,8 +39,8 @@ public:
void set_ext_clock(int counter, double clock); // set clock frequency
int ext_clock(int counter) const { return m_external_clock[counter]; } // get clock frequency
- void write(offs_t offset, uint8_t data);
- uint8_t read(offs_t offset);
+ DECLARE_WRITE8_MEMBER( write );
+ DECLARE_READ8_MEMBER( read );
void set_gate(int idx, int state);
DECLARE_WRITE_LINE_MEMBER( set_g1 );
diff --git a/src/devices/machine/6850acia.cpp b/src/devices/machine/6850acia.cpp
index 08e8459fd36..6527608bf0f 100644
--- a/src/devices/machine/6850acia.cpp
+++ b/src/devices/machine/6850acia.cpp
@@ -150,27 +150,24 @@ void acia6850_device::device_reset()
output_irq(1);
}
-uint8_t acia6850_device::status_r()
+READ8_MEMBER( acia6850_device::status_r )
{
uint8_t status = m_status;
- if (!machine().side_effects_disabled())
+ if (status & SR_CTS)
{
- if (status & SR_CTS)
- {
- status &= ~SR_TDRE;
- }
+ status &= ~SR_TDRE;
+ }
- if (m_dcd_irq_pending == DCD_IRQ_READ_STATUS)
- {
- m_dcd_irq_pending = DCD_IRQ_READ_DATA;
- }
+ if (m_dcd_irq_pending == DCD_IRQ_READ_STATUS)
+ {
+ m_dcd_irq_pending = DCD_IRQ_READ_DATA;
}
return status;
}
-void acia6850_device::control_w(uint8_t data)
+WRITE8_MEMBER( acia6850_device::control_w )
{
LOG("MC6850 '%s' Control: %02x\n", tag(), data);
@@ -240,7 +237,7 @@ void acia6850_device::update_irq()
output_irq(calculate_txirq() && calculate_rxirq());
}
-void acia6850_device::data_w(uint8_t data)
+WRITE8_MEMBER( acia6850_device::data_w )
{
LOG("MC6850 '%s' Data: %02x\n", tag(), data);
@@ -257,43 +254,40 @@ void acia6850_device::data_w(uint8_t data)
update_irq();
}
-uint8_t acia6850_device::data_r()
+READ8_MEMBER( acia6850_device::data_r )
{
- if (!machine().side_effects_disabled())
+ if (m_overrun_pending)
{
- if (m_overrun_pending)
- {
- m_status |= SR_OVRN;
- m_overrun_pending = false;
- }
- else
- {
- m_status &= ~SR_OVRN;
- m_status &= ~SR_RDRF;
- }
-
- if (m_dcd_irq_pending == DCD_IRQ_READ_DATA)
- {
- m_dcd_irq_pending = DCD_IRQ_NONE;
- }
+ m_status |= SR_OVRN;
+ m_overrun_pending = false;
+ }
+ else
+ {
+ m_status &= ~SR_OVRN;
+ m_status &= ~SR_RDRF;
+ }
- update_irq();
+ if (m_dcd_irq_pending == DCD_IRQ_READ_DATA)
+ {
+ m_dcd_irq_pending = DCD_IRQ_NONE;
}
+ update_irq();
+
return m_rdr;
}
-void acia6850_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( acia6850_device::write )
{
if (BIT(offset, 0))
- data_w(data);
+ data_w(space, 0, data);
else
- control_w(data);
+ control_w(space, 0, data);
}
-uint8_t acia6850_device::read(offs_t offset)
+READ8_MEMBER( acia6850_device::read )
{
- return BIT(offset, 0) ? data_r() : status_r();
+ return BIT(offset, 0) ? data_r(space, 0) : status_r(space, 0);
}
DECLARE_WRITE_LINE_MEMBER( acia6850_device::write_cts )
diff --git a/src/devices/machine/6850acia.h b/src/devices/machine/6850acia.h
index 4d99209d519..4c40e2dc69f 100644
--- a/src/devices/machine/6850acia.h
+++ b/src/devices/machine/6850acia.h
@@ -24,12 +24,12 @@ public:
auto rts_handler() { return m_rts_handler.bind(); }
auto irq_handler() { return m_irq_handler.bind(); }
- void control_w(uint8_t data);
- uint8_t status_r();
- void data_w(uint8_t data);
- uint8_t data_r();
- void write(offs_t offset, uint8_t data);
- uint8_t read(offs_t offset);
+ DECLARE_WRITE8_MEMBER( control_w );
+ DECLARE_READ8_MEMBER( status_r );
+ DECLARE_WRITE8_MEMBER( data_w );
+ DECLARE_READ8_MEMBER( data_r );
+ DECLARE_WRITE8_MEMBER( write );
+ DECLARE_READ8_MEMBER( read );
DECLARE_WRITE_LINE_MEMBER( write_cts );
DECLARE_WRITE_LINE_MEMBER( write_dcd );
diff --git a/src/devices/machine/74157.cpp b/src/devices/machine/74157.cpp
index 1dc7eb1289b..f5a68cc4465 100644
--- a/src/devices/machine/74157.cpp
+++ b/src/devices/machine/74157.cpp
@@ -35,7 +35,7 @@ DEFINE_DEVICE_TYPE(LS157_X2, ls157_x2_device, "ls157_x2", "74LS157 Quad 2-to-1 M
// ls157_device - constructor
//-------------------------------------------------
-ls157_device::ls157_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ls157_device::ls157_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ls157_device(mconfig, LS157, tag, owner, clock, 0x0f)
{
}
@@ -58,7 +58,7 @@ ls157_device::ls157_device(const machine_config &mconfig, device_type type, cons
// ls157_x2_device - constructor
//-------------------------------------------------
-ls157_x2_device::ls157_x2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ls157_x2_device::ls157_x2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ls157_device(mconfig, LS157_X2, tag, owner, clock, 0xff)
{
}
@@ -92,7 +92,7 @@ void ls157_device::device_start()
// a_w -- write nibble to A1-A4
//-------------------------------------------------
-void ls157_device::a_w(u8 data)
+void ls157_device::write_a(u8 data)
{
m_a = data & m_data_mask;
update_output();
@@ -103,7 +103,7 @@ void ls157_device::a_w(u8 data)
// b_w -- write nibble to B1-B4
//-------------------------------------------------
-void ls157_device::b_w(u8 data)
+void ls157_device::write_b(u8 data)
{
m_b = data & m_data_mask;
update_output();
@@ -115,7 +115,7 @@ void ls157_device::b_w(u8 data)
// low nibble to B1-B4
//-------------------------------------------------
-void ls157_device::ab_w(u8 data)
+void ls157_device::write_ab(u8 data)
{
assert(m_data_mask == 0x0f);
m_a = data >> 4;
@@ -129,7 +129,7 @@ void ls157_device::ab_w(u8 data)
// low nibble to A1-A4
//-------------------------------------------------
-void ls157_device::ba_w(u8 data)
+void ls157_device::write_ba(u8 data)
{
assert(m_data_mask == 0x0f);
m_b = data >> 4;
@@ -143,7 +143,7 @@ void ls157_device::ba_w(u8 data)
// A1-A4 and write odd-numbered bits to B1-B4
//-------------------------------------------------
-void ls157_device::interleave_w(u8 data)
+void ls157_device::write_interleave(u8 data)
{
assert(m_data_mask == 0x0f);
m_b = bitswap<4>(data, 7, 5, 3, 1);
@@ -260,7 +260,7 @@ void ls157_device::update_output()
// DATA OUTPUTS
//**************************************************************************
-u8 ls157_device::output_r()
+READ8_MEMBER(ls157_device::output_r)
{
if (m_strobe)
return 0;
@@ -277,7 +277,7 @@ u8 ls157_device::output_r()
DEFINE_DEVICE_TYPE(HC157, hc157_device, "hc157", "74HC157 Quad 2-to-1 Multiplexer")
-hc157_device::hc157_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+hc157_device::hc157_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ls157_device(mconfig, HC157, tag, owner, clock, 0x0f)
{
}
@@ -289,7 +289,7 @@ hc157_device::hc157_device(const machine_config &mconfig, const char *tag, devic
DEFINE_DEVICE_TYPE(HCT157, hct157_device, "hct157", "74HCT157 Quad 2-to-1 Multiplexer")
-hct157_device::hct157_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+hct157_device::hct157_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ls157_device(mconfig, HCT157, tag, owner, clock, 0x0f)
{
}
diff --git a/src/devices/machine/74157.h b/src/devices/machine/74157.h
index 52875cc0a76..4bd4685546c 100644
--- a/src/devices/machine/74157.h
+++ b/src/devices/machine/74157.h
@@ -42,11 +42,16 @@ public:
auto out_callback() { return m_out_cb.bind(); }
// data writes
- void a_w(u8 data);
- void b_w(u8 data);
- void ab_w(u8 data);
- void ba_w(u8 data);
- void interleave_w(u8 data);
+ DECLARE_WRITE8_MEMBER(a_w) { write_a(data); }
+ void write_a(u8 data);
+ DECLARE_WRITE8_MEMBER(b_w) { write_b(data); }
+ void write_b(u8 data);
+ DECLARE_WRITE8_MEMBER(ab_w) { write_ab(data); }
+ void write_ab(u8 data);
+ DECLARE_WRITE8_MEMBER(ba_w) { write_ba(data); }
+ void write_ba(u8 data);
+ DECLARE_WRITE8_MEMBER(interleave_w) { write_interleave(data); }
+ void write_interleave(u8 data);
// data line writes
DECLARE_WRITE_LINE_MEMBER(a0_w);
@@ -63,7 +68,7 @@ public:
DECLARE_WRITE_LINE_MEMBER(strobe_w);
// output read
- u8 output_r();
+ DECLARE_READ8_MEMBER(output_r);
protected:
ls157_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 mask);
diff --git a/src/devices/machine/74165.cpp b/src/devices/machine/74165.cpp
index 9ba4415d56c..d33033d5ab7 100644
--- a/src/devices/machine/74165.cpp
+++ b/src/devices/machine/74165.cpp
@@ -22,10 +22,9 @@ DEFINE_DEVICE_TYPE(TTL165, ttl165_device, "ttl165", "SN54/74165")
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void ttl165_device::device_add_mconfig(machine_config &config)
-{
- TIMER(config, m_timer).configure_generic(FUNC(ttl165_device::qh_output));
-}
+MACHINE_CONFIG_START(ttl165_device::device_add_mconfig)
+ MCFG_TIMER_DRIVER_ADD("timer", ttl165_device, qh_output)
+MACHINE_CONFIG_END
//**************************************************************************
diff --git a/src/devices/machine/74166.cpp b/src/devices/machine/74166.cpp
index 1611b526762..07a9de653a5 100644
--- a/src/devices/machine/74166.cpp
+++ b/src/devices/machine/74166.cpp
@@ -22,10 +22,9 @@ DEFINE_DEVICE_TYPE(TTL166, ttl166_device, "ttl166", "SN54/74166")
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void ttl166_device::device_add_mconfig(machine_config &config)
-{
- TIMER(config, m_timer).configure_generic(FUNC(ttl166_device::qh_output));
-}
+MACHINE_CONFIG_START(ttl166_device::device_add_mconfig)
+ MCFG_TIMER_DRIVER_ADD("timer", ttl166_device, qh_output)
+MACHINE_CONFIG_END
//**************************************************************************
diff --git a/src/devices/machine/7474.h b/src/devices/machine/7474.h
index 0f9d87fa5bf..0a6a678ddfb 100644
--- a/src/devices/machine/7474.h
+++ b/src/devices/machine/7474.h
@@ -45,6 +45,19 @@
#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_7474_OUTPUT_CB(_devcb) \
+ downcast<ttl7474_device &>(*device).set_output_cb(DEVCB_##_devcb);
+
+#define MCFG_7474_COMP_OUTPUT_CB(_devcb) \
+ downcast<ttl7474_device &>(*device).set_comp_output_cb(DEVCB_##_devcb);
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -58,6 +71,8 @@ public:
ttl7474_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// static configuration helpers
+ template <class Object> devcb_base &set_output_cb(Object &&cb) { return m_output_func.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_comp_output_cb(Object &&cb) { return m_comp_output_func.set_callback(std::forward<Object>(cb)); }
auto output_cb() { return m_output_func.bind(); }
auto comp_output_cb() { return m_comp_output_func.bind(); }
diff --git a/src/devices/machine/8042kbdc.cpp b/src/devices/machine/8042kbdc.cpp
index 541e7575b63..602435369ab 100644
--- a/src/devices/machine/8042kbdc.cpp
+++ b/src/devices/machine/8042kbdc.cpp
@@ -45,11 +45,9 @@ kbdc8042_device::kbdc8042_device(const machine_config &mconfig, const char *tag,
{
}
-void kbdc8042_device::device_add_mconfig(machine_config &config)
-{
- AT_KEYB(config, m_keyboard_dev, pc_keyboard_device::KEYBOARD_TYPE::AT, 1);
- m_keyboard_dev->keypress().set(FUNC(kbdc8042_device::keyboard_w));
-}
+MACHINE_CONFIG_START(kbdc8042_device::device_add_mconfig)
+ MCFG_AT_KEYB_ADD("at_keyboard", 1, WRITELINE(*this, kbdc8042_device, keyboard_w))
+MACHINE_CONFIG_END
/*-------------------------------------------------
@@ -71,9 +69,6 @@ void kbdc8042_device::device_start()
m_sending = 0;
m_last_write_to_control = 0;
m_status_read_mode = 0;
-
- m_update_timer = timer_alloc(TIMER_UPDATE);
- m_update_timer->adjust(attotime::never);
}
/*-------------------------------------------------
@@ -91,8 +86,6 @@ void kbdc8042_device::device_reset()
m_mouse_x = 0;
m_mouse_y = 0;
m_mouse_btn = 0;
-
- m_update_timer->adjust(attotime::from_hz(100), 0, attotime::from_hz(100));
}
void kbdc8042_device::at_8042_set_outport(uint8_t data, int initial)
@@ -202,14 +195,7 @@ void kbdc8042_device::at_8042_clear_keyboard_received()
m_mouse.received = 0;
}
-void kbdc8042_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- if (id == TIMER_UPDATE)
- {
- at_8042_check_keyboard();
- at_8042_check_mouse();
- }
-}
+
/* **************************************************************************
* Port 0x60 Input and Output Buffer (keyboard and mouse data)
diff --git a/src/devices/machine/8042kbdc.h b/src/devices/machine/8042kbdc.h
index 38bdbe3814a..f2e7fdfbf04 100644
--- a/src/devices/machine/8042kbdc.h
+++ b/src/devices/machine/8042kbdc.h
@@ -58,11 +58,8 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
virtual ioport_constructor device_input_ports() const override;
- static const device_timer_id TIMER_UPDATE = 0;
-
private:
uint8_t m_inport;
uint8_t m_outport;
@@ -115,8 +112,6 @@ private:
uint16_t m_mouse_y;
uint8_t m_mouse_btn;
- emu_timer * m_update_timer;
-
DECLARE_WRITE_LINE_MEMBER( keyboard_w );
};
diff --git a/src/devices/machine/8364_paula.h b/src/devices/machine/8364_paula.h
index 412fe7679e6..c889a831b67 100644
--- a/src/devices/machine/8364_paula.h
+++ b/src/devices/machine/8364_paula.h
@@ -43,6 +43,18 @@
#pragma once
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_PAULA_MEM_READ_CB(_devcb) \
+ downcast<paula_8364_device &>(*device).set_mem_r_callback(DEVCB_##_devcb);
+
+#define MCFG_PAULA_INT_CB(_devcb) \
+ downcast<paula_8364_device &>(*device).set_int_w_callback(DEVCB_##_devcb);
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -55,6 +67,8 @@ public:
paula_8364_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration
+ template <class Object> devcb_base &set_mem_r_callback(Object &&cb) { return m_mem_r.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_int_w_callback(Object &&cb) { return m_int_w.set_callback(std::forward<Object>(cb)); }
auto mem_read_cb() { return m_mem_r.bind(); }
auto int_cb() { return m_int_w.bind(); }
diff --git a/src/devices/machine/adc0808.cpp b/src/devices/machine/adc0808.cpp
index 11aafe276fb..5f8aeb8f93c 100644
--- a/src/devices/machine/adc0808.cpp
+++ b/src/devices/machine/adc0808.cpp
@@ -156,7 +156,7 @@ void adc0808_device::device_timer(emu_timer &timer, device_timer_id id, int para
// INTERFACE
//**************************************************************************
-u8 adc0808_device::data_r()
+READ8_MEMBER( adc0808_device::data_r )
{
if (!machine().side_effects_disabled())
{
@@ -170,7 +170,7 @@ u8 adc0808_device::data_r()
return m_sar;
}
-void adc0808_device::address_w(u8 data)
+WRITE8_MEMBER( adc0808_device::address_w )
{
m_address = data & 7;
}
@@ -198,22 +198,22 @@ READ_LINE_MEMBER( adc0808_device::eoc_r )
return m_eoc;
}
-void adc0808_device::address_offset_start_w(offs_t offset, u8 data)
+WRITE8_MEMBER( adc0808_device::address_offset_start_w )
{
if (VERBOSE)
logerror("address_offset_start_w %02x %02x\n", offset, data);
start_w(1);
- address_w(offset);
+ address_w(space, 0, offset);
start_w(0);
}
-void adc0808_device::address_data_start_w(u8 data)
+WRITE8_MEMBER( adc0808_device::address_data_start_w )
{
if (VERBOSE)
- logerror("address_data_start_w %02x\n", data);
+ logerror("address_data_start_w %02x %02x\n", offset, data);
start_w(1);
- address_w(data);
+ address_w(space, 0, data);
start_w(0);
}
diff --git a/src/devices/machine/adc0808.h b/src/devices/machine/adc0808.h
index 1fa97aff47e..46943998dca 100644
--- a/src/devices/machine/adc0808.h
+++ b/src/devices/machine/adc0808.h
@@ -51,14 +51,14 @@ public:
auto eoc_ff_callback() { return m_eoc_ff_cb.bind(); }
template <std::size_t Bit> auto in_callback() { return m_in_cb[Bit].bind(); }
- u8 data_r();
- void address_w(u8 data);
+ DECLARE_READ8_MEMBER(data_r);
+ DECLARE_WRITE8_MEMBER(address_w);
DECLARE_WRITE_LINE_MEMBER(start_w);
DECLARE_READ_LINE_MEMBER(eoc_r);
// common hookups
- void address_offset_start_w(offs_t offset, u8 data); // start and ale connected, address to the address bus
- void address_data_start_w(u8 data); // start and ale connected, address to the data bus
+ DECLARE_WRITE8_MEMBER(address_offset_start_w); // start and ale connected, address to the address bus
+ DECLARE_WRITE8_MEMBER(address_data_start_w); // start and ale connected, address to the data bus
protected:
adc0808_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
diff --git a/src/devices/machine/adc0844.cpp b/src/devices/machine/adc0844.cpp
index c3616035927..103702a8d14 100644
--- a/src/devices/machine/adc0844.cpp
+++ b/src/devices/machine/adc0844.cpp
@@ -182,14 +182,14 @@ void adc0848_device::device_timer(emu_timer &timer, device_timer_id id, int para
// INTERFACE
//**************************************************************************
-u8 adc0844_device::read()
+READ8_MEMBER( adc0844_device::read )
{
m_intr_cb(CLEAR_LINE);
return m_result;
}
-void adc0844_device::write(u8 data)
+WRITE8_MEMBER( adc0844_device::write )
{
m_intr_cb(CLEAR_LINE);
@@ -198,7 +198,7 @@ void adc0844_device::write(u8 data)
m_conversion_timer->adjust(attotime::from_usec(40));
}
-void adc0848_device::write(u8 data)
+WRITE8_MEMBER( adc0848_device::write )
{
m_intr_cb(CLEAR_LINE);
diff --git a/src/devices/machine/adc0844.h b/src/devices/machine/adc0844.h
index 51dff681f16..d20d9697a09 100644
--- a/src/devices/machine/adc0844.h
+++ b/src/devices/machine/adc0844.h
@@ -43,8 +43,8 @@ public:
auto ch3_callback() { return m_ch3_cb.bind(); }
auto ch4_callback() { return m_ch4_cb.bind(); }
- u8 read();
- virtual void write(u8 data);
+ DECLARE_READ8_MEMBER(read);
+ virtual DECLARE_WRITE8_MEMBER(write);
protected:
adc0844_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -78,7 +78,7 @@ public:
auto ch7_callback() { return m_ch7_cb.bind(); }
auto ch8_callback() { return m_ch8_cb.bind(); }
- virtual void write(u8 data) override;
+ virtual DECLARE_WRITE8_MEMBER(write) override;
protected:
// device-level overrides
diff --git a/src/devices/machine/aic6250.cpp b/src/devices/machine/aic6250.cpp
index adf90fe99b5..769968569c8 100644
--- a/src/devices/machine/aic6250.cpp
+++ b/src/devices/machine/aic6250.cpp
@@ -41,14 +41,13 @@
#include "logmacro.h"
-DEFINE_DEVICE_TYPE(AIC6250, aic6250_device, "aic6250", "Adaptec AIC-6250 High-Performance SCSI Protocol Chip")
-DEFINE_DEVICE_TYPE(AIC6251A, aic6251a_device, "aic6251a", "Adaptec AIC-6251A Fast SCSI Protocol Chip")
+DEFINE_DEVICE_TYPE(AIC6250, aic6250_device, "aic6250", "Adaptec 6250 High-Performance SCSI Protocol Chip")
static char const *const nscsi_phase[] = { "DATA OUT", "DATA IN", "COMMAND", "STATUS", "*", "*", "MESSAGE OUT", "MESSAGE IN" };
static char const *const aic6250_phase[] = { "DATA OUT", "*", "DATA IN", "*", "COMMAND", "MESSAGE OUT", "STATUS", "MESSAGE IN" };
-aic6250_device::aic6250_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : nscsi_device(mconfig, type, tag, owner, clock)
+aic6250_device::aic6250_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : nscsi_device(mconfig, AIC6250, tag, owner, clock)
, m_int_cb(*this)
, m_breq_cb(*this)
, m_port_a_r_cb(*this)
@@ -58,16 +57,6 @@ aic6250_device::aic6250_device(const machine_config &mconfig, device_type type,
{
}
-aic6250_device::aic6250_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : aic6250_device(mconfig, AIC6250, tag, owner, clock)
-{
-}
-
-aic6251a_device::aic6251a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : aic6250_device(mconfig, AIC6251A, tag, owner, clock)
-{
-}
-
void aic6250_device::map(address_map &map)
{
map(0x0, 0x0).rw(FUNC(aic6250_device::dma_count_l_r), FUNC(aic6250_device::dma_count_l_w));
diff --git a/src/devices/machine/aic6250.h b/src/devices/machine/aic6250.h
index 2a4ba02d118..029c7f72dca 100644
--- a/src/devices/machine/aic6250.h
+++ b/src/devices/machine/aic6250.h
@@ -34,8 +34,6 @@ public:
void dma16_w(u16 data);
protected:
- aic6250_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
// standard device_interface overrides
virtual void device_start() override;
virtual void device_reset() override;
@@ -54,11 +52,11 @@ protected:
u8 status_reg_1_r();
u8 scsi_signal_reg_r();
u8 scsi_id_data_r();
- u8 source_dest_id_r() { return m_source_dest_id; }
+ u8 source_dest_id_r() { logerror("source_dest_id_r\n"); return m_source_dest_id; }
u8 memory_data_r();
u8 port_a_r();
u8 port_b_r();
- u8 scsi_latch_data_r() { return m_scsi_latch_data; }
+ u8 scsi_latch_data_r() { logerror("scsi_latch_data_r 0x%02x\n", m_scsi_latch_data); return m_scsi_latch_data; }
void dma_count_l_w(u8 data) { m_dma_count &= ~0x0000ff; m_dma_count |= (data << 0); }
void dma_count_m_w(u8 data) { m_dma_count &= ~0x00ff00; m_dma_count |= (data << 8); }
@@ -279,13 +277,6 @@ private:
util::fifo <u8, 8> m_fifo;
};
-class aic6251a_device : public aic6250_device
-{
-public:
- aic6251a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-};
-
DECLARE_DEVICE_TYPE(AIC6250, aic6250_device)
-DECLARE_DEVICE_TYPE(AIC6251A, aic6251a_device)
#endif // MAME_MACHINE_AIC6250_H
diff --git a/src/devices/machine/aicartc.h b/src/devices/machine/aicartc.h
index 71c8cdd55ad..757c0a58c1d 100644
--- a/src/devices/machine/aicartc.h
+++ b/src/devices/machine/aicartc.h
@@ -9,6 +9,13 @@
//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_AICARTC_ADD(_tag,_freq) \
+ MCFG_DEVICE_ADD(_tag, AICARTC, _freq)
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
diff --git a/src/devices/machine/akiko.cpp b/src/devices/machine/akiko.cpp
index eb5fa929059..0394750fe30 100644
--- a/src/devices/machine/akiko.cpp
+++ b/src/devices/machine/akiko.cpp
@@ -38,9 +38,8 @@ DEFINE_DEVICE_TYPE(AKIKO, akiko_device, "akiko", "CBM AKIKO")
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void akiko_device::device_add_mconfig(machine_config &config)
-{
-}
+MACHINE_CONFIG_START(akiko_device::device_add_mconfig)
+MACHINE_CONFIG_END
//**************************************************************************
diff --git a/src/devices/machine/am9513.cpp b/src/devices/machine/am9513.cpp
index 6506510369f..c17ae1f09fe 100644
--- a/src/devices/machine/am9513.cpp
+++ b/src/devices/machine/am9513.cpp
@@ -1382,7 +1382,7 @@ void am9513_device::data_write(u16 data)
// read8 - 8-bit read access
//-------------------------------------------------
-u8 am9513_device::read8(offs_t offset)
+READ8_MEMBER(am9513_device::read8)
{
if (BIT(offset, 0))
return status_read();
@@ -1395,7 +1395,7 @@ u8 am9513_device::read8(offs_t offset)
// write8 - 8-bit write access
//-------------------------------------------------
-void am9513_device::write8(offs_t offset, u8 data)
+WRITE8_MEMBER(am9513_device::write8)
{
if (BIT(offset, 0))
{
@@ -1412,7 +1412,7 @@ void am9513_device::write8(offs_t offset, u8 data)
// read16 - 16-bit read access
//-------------------------------------------------
-u16 am9513_device::read16(offs_t offset)
+READ16_MEMBER(am9513_device::read16)
{
if (BIT(offset, 0))
return status_read() | 0xff00;
@@ -1429,7 +1429,7 @@ u16 am9513_device::read16(offs_t offset)
// write16 - 16-bit write access
//-------------------------------------------------
-void am9513_device::write16(offs_t offset, u16 data)
+WRITE16_MEMBER(am9513_device::write16)
{
if ((!bus_is_16_bit() || BIT(offset, 0)) && (data & 0xff00) != 0xff00)
logerror("Errant write of %02X to upper byte of %s register in %d-bit bus mode\n",
diff --git a/src/devices/machine/am9513.h b/src/devices/machine/am9513.h
index ea3fcfe6443..b591294d9b7 100644
--- a/src/devices/machine/am9513.h
+++ b/src/devices/machine/am9513.h
@@ -55,12 +55,12 @@ public:
auto fout_cb() { return m_fout_cb.bind(); }
// 8-bit data bus interface
- u8 read8(offs_t offset);
- void write8(offs_t offset, u8 data);
+ DECLARE_READ8_MEMBER(read8);
+ DECLARE_WRITE8_MEMBER(write8);
// 16-bit data bus interface
- u16 read16(offs_t offset);
- void write16(offs_t offset, u16 data);
+ DECLARE_READ16_MEMBER(read16);
+ DECLARE_WRITE16_MEMBER(write16);
// Source N inputs
DECLARE_WRITE_LINE_MEMBER(source1_w) { write_source(0, state); }
diff --git a/src/devices/machine/am9517a.cpp b/src/devices/machine/am9517a.cpp
index 5fda6ed486c..463f1c447ef 100644
--- a/src/devices/machine/am9517a.cpp
+++ b/src/devices/machine/am9517a.cpp
@@ -39,18 +39,6 @@
*/
-/*
- * The EISA_DMA device represents the 82C37A-compatible DMA devices present in
- * EISA bus systems, in particular those embedded within the i82357 Integrated
- * System Peripheral. The device supports 32 bit addressing, 32 bit data sizes,
- * and 24 bit transfer counts, allowing DMA across 64k boundaries. It also adds
- * stop registers, supporting ring-buffer memory arrangements.
- *
- * TODO
- * - stop registers
- * - 16/32-bit transfer sizes
- */
-
#include "emu.h"
#include "am9517a.h"
@@ -66,7 +54,6 @@
DEFINE_DEVICE_TYPE(AM9517A, am9517a_device, "am9517a", "AM9517A")
DEFINE_DEVICE_TYPE(V5X_DMAU, v5x_dmau_device, "v5x_dmau", "V5X DMAU")
DEFINE_DEVICE_TYPE(PCXPORT_DMAC, pcxport_dmac_device, "pcx_dmac", "PC Transporter DMAC")
-DEFINE_DEVICE_TYPE(EISA_DMA, eisa_dma_device, "eisa_dma", "EISA DMA")
//**************************************************************************
@@ -303,6 +290,8 @@ inline void am9517a_device::dma_advance()
{
bool msb_changed = false;
+ m_channel[m_current_channel].m_count--;
+
if (m_current_channel || !COMMAND_MEM_TO_MEM || !COMMAND_CH0_ADDRESS_HOLD)
{
if (MODE_ADDRESS_DECREMENT)
@@ -327,7 +316,7 @@ inline void am9517a_device::dma_advance()
}
}
- if (m_channel[m_current_channel].m_count-- == 0)
+ if (m_channel[m_current_channel].m_count == 0xffff)
{
end_of_process();
}
@@ -723,7 +712,7 @@ void am9517a_device::execute_run()
// read -
//-------------------------------------------------
-uint8_t am9517a_device::read(offs_t offset)
+READ8_MEMBER( am9517a_device::read )
{
uint8_t data = 0;
@@ -787,7 +776,7 @@ uint8_t am9517a_device::read(offs_t offset)
// write -
//-------------------------------------------------
-void am9517a_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( am9517a_device::write )
{
if (!BIT(offset, 3))
{
@@ -1024,7 +1013,7 @@ void v5x_dmau_device::device_reset()
}
-uint8_t v5x_dmau_device::read(offs_t offset)
+READ8_MEMBER(v5x_dmau_device::read)
{
uint8_t ret = 0;
int channel = m_selected_channel;
@@ -1108,7 +1097,7 @@ uint8_t v5x_dmau_device::read(offs_t offset)
return ret;
}
-void v5x_dmau_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(v5x_dmau_device::write)
{
int channel = m_selected_channel;
@@ -1119,12 +1108,12 @@ void v5x_dmau_device::write(offs_t offset, uint8_t data)
//m_buswidth = data & 0x02;
//if (data & 0x01)
// soft_reset();
- LOG("DMA: Initialise [%02x]\n", data);
+ logerror("DMA: Initialise [%02x]\n", data);
break;
case 0x01: // Channel
m_selected_channel = data & 0x03;
m_base = data & 0x04;
- LOG("DMA: Channel selected [%02x]\n", data);
+ logerror("DMA: Channel selected [%02x]\n", data);
break;
case 0x02: // Count (low)
m_channel[channel].m_base_count =
@@ -1132,7 +1121,7 @@ void v5x_dmau_device::write(offs_t offset, uint8_t data)
if (m_base == 0)
m_channel[channel].m_count =
(m_channel[channel].m_count & 0xff00) | data;
- LOG("DMA: Channel %i Counter set [%04x]\n", m_selected_channel, m_channel[channel].m_base_count);
+ logerror("DMA: Channel %i Counter set [%04x]\n", m_selected_channel, m_channel[channel].m_base_count);
break;
case 0x03: // Count (high)
m_channel[channel].m_base_count =
@@ -1140,7 +1129,7 @@ void v5x_dmau_device::write(offs_t offset, uint8_t data)
if (m_base == 0)
m_channel[channel].m_count =
(m_channel[channel].m_count & 0x00ff) | (data << 8);
- LOG("DMA: Channel %i Counter set [%04x]\n", m_selected_channel, m_channel[channel].m_base_count);
+ logerror("DMA: Channel %i Counter set [%04x]\n", m_selected_channel, m_channel[channel].m_base_count);
break;
case 0x04: // Address (low)
m_channel[channel].m_base_address =
@@ -1148,7 +1137,7 @@ void v5x_dmau_device::write(offs_t offset, uint8_t data)
if (m_base == 0)
m_channel[channel].m_address =
(m_channel[channel].m_address & 0xffffff00) | data;
- LOG("DMA: Channel %i Address set [%08x]\n", m_selected_channel, m_channel[channel].m_base_address);
+ logerror("DMA: Channel %i Address set [%08x]\n", m_selected_channel, m_channel[channel].m_base_address);
break;
case 0x05: // Address (mid)
m_channel[channel].m_base_address =
@@ -1156,7 +1145,7 @@ void v5x_dmau_device::write(offs_t offset, uint8_t data)
if (m_base == 0)
m_channel[channel].m_address =
(m_channel[channel].m_address & 0xffff00ff) | (data << 8);
- LOG("DMA: Channel %i Address set [%08x]\n", m_selected_channel, m_channel[channel].m_base_address);
+ logerror("DMA: Channel %i Address set [%08x]\n", m_selected_channel, m_channel[channel].m_base_address);
break;
case 0x06: // Address (high)
m_channel[channel].m_base_address =
@@ -1164,7 +1153,7 @@ void v5x_dmau_device::write(offs_t offset, uint8_t data)
if (m_base == 0)
m_channel[channel].m_address =
(m_channel[channel].m_address & 0xff00ffff) | (data << 16);
- LOG("DMA: Channel %i Address set [%08x]\n", m_selected_channel, m_channel[channel].m_base_address);
+ logerror("DMA: Channel %i Address set [%08x]\n", m_selected_channel, m_channel[channel].m_base_address);
break;
case 0x07: // Address (highest)
m_channel[channel].m_base_address =
@@ -1172,31 +1161,31 @@ void v5x_dmau_device::write(offs_t offset, uint8_t data)
if (m_base == 0)
m_channel[channel].m_address =
(m_channel[channel].m_address & 0x00ffffff) | (data << 24);
- LOG("DMA: Channel %i Address set [%08x]\n", m_selected_channel, m_channel[channel].m_base_address);
+ logerror("DMA: Channel %i Address set [%08x]\n", m_selected_channel, m_channel[channel].m_base_address);
break;
case 0x0a: // Mode control
m_channel[channel].m_mode = data;
// clear terminal count
m_status &= ~(1 << channel);
- LOG("DMA: Channel %i Mode control set [%02x]\n",m_selected_channel,m_channel[channel].m_mode);
+ logerror("DMA: Channel %i Mode control set [%02x]\n",m_selected_channel,m_channel[channel].m_mode);
break;
case 0x08: // Device control (low)
m_command = data;
- LOG("DMA: Device control low set [%02x]\n",data);
+ logerror("DMA: Device control low set [%02x]\n",data);
break;
case 0x09: // Device control (high)
m_command_high = data;
- LOG("DMA: Device control high set [%02x]\n",data);
+ logerror("DMA: Device control high set [%02x]\n",data);
break;
case 0x0e: // Request
//m_reg.request = data;
- LOG("(invalid) DMA: Request set [%02x]\n",data); // no software requests on the v53 integrated version
+ logerror("(invalid) DMA: Request set [%02x]\n",data); // no software requests on the v53 integrated version
break;
case 0x0f: // Mask
m_mask = data & 0x0f;
- LOG("DMA: Mask set [%02x]\n",data);
+ logerror("DMA: Mask set [%02x]\n",data);
break;
@@ -1309,17 +1298,3 @@ void pcxport_dmac_device::end_of_process()
m_state = STATE_SI;
}
-
-eisa_dma_device::eisa_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : am9517a_device(mconfig, EISA_DMA, tag, owner, clock)
-{
-}
-
-void eisa_dma_device::device_start()
-{
- am9517a_device::device_start();
-
- m_address_mask = 0xffffffffU;
-
- save_item(NAME(m_stop));
-}
diff --git a/src/devices/machine/am9517a.h b/src/devices/machine/am9517a.h
index a1e9215d125..37390a930d3 100644
--- a/src/devices/machine/am9517a.h
+++ b/src/devices/machine/am9517a.h
@@ -61,8 +61,8 @@ public:
template <unsigned C> auto out_iow_callback() { return m_out_iow_cb[C].bind(); }
template <unsigned C> auto out_dack_callback() { return m_out_dack_cb[C].bind(); }
- virtual uint8_t read(offs_t offset);
- virtual void write(offs_t offset, uint8_t data);
+ virtual DECLARE_READ8_MEMBER( read );
+ virtual DECLARE_WRITE8_MEMBER( write );
DECLARE_WRITE_LINE_MEMBER( hack_w );
DECLARE_WRITE_LINE_MEMBER( ready_w );
@@ -95,9 +95,9 @@ protected:
struct
{
uint32_t m_address;
- uint32_t m_count;
+ uint16_t m_count;
uint32_t m_base_address;
- uint32_t m_base_count;
+ uint16_t m_base_count;
uint8_t m_mode;
} m_channel[4];
@@ -149,8 +149,8 @@ public:
template <unsigned C> auto in_io16r_callback() { return m_in_io16r_cb[C].bind(); }
template <unsigned C> auto out_io16w_callback() { return m_out_io16w_cb[C].bind(); }
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+ virtual DECLARE_READ8_MEMBER( read ) override;
+ virtual DECLARE_WRITE8_MEMBER( write ) override;
protected:
// device-level overrides
@@ -186,50 +186,11 @@ protected:
virtual void end_of_process() override;
};
-class eisa_dma_device : public am9517a_device
-{
-public:
- eisa_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- template <unsigned Channel> u8 get_address_page() { return m_channel[Channel].m_address >> 16; }
- template <unsigned Channel> void set_address_page(u8 data)
- {
- m_channel[Channel].m_base_address = (m_channel[Channel].m_base_address & 0x0000ffffU) | (u32(data) << 16);
- m_channel[Channel].m_address = (m_channel[Channel].m_address & 0x0000ffffU) | (u32(data) << 16);
- }
-
- template <unsigned Channel> u8 get_address_page_high() { return m_channel[Channel].m_address >> 24; }
- template <unsigned Channel> void set_address_page_high(u8 data)
- {
- m_channel[Channel].m_base_address = (m_channel[Channel].m_base_address & 0x00ffffffU) | (u32(data) << 24);
- m_channel[Channel].m_address = (m_channel[Channel].m_address & 0x00ffffffU) | (u32(data) << 24);
- }
-
- template <unsigned Channel> u8 get_count_high() { return m_channel[Channel].m_count >> 16; }
- template <unsigned Channel> void set_count_high(u8 data)
- {
- m_channel[Channel].m_base_count = (m_channel[Channel].m_base_count & 0x0000ffffU) | (u32(data) << 16);
- m_channel[Channel].m_count = (m_channel[Channel].m_count & 0x0000ffffU) | (u32(data) << 16);
- }
- template <unsigned Channel> u32 get_stop() { return m_stop[Channel]; }
- template <unsigned Channel> void set_stop(offs_t offset, u32 data, u32 mem_mask)
- {
- mem_mask &= 0x00fffffcU;
- COMBINE_DATA(&m_stop[Channel]);
- }
-
-protected:
- virtual void device_start() override;
-
-private:
- u32 m_stop[4];
-};
// device type definition
DECLARE_DEVICE_TYPE(AM9517A, am9517a_device)
DECLARE_DEVICE_TYPE(V5X_DMAU, v5x_dmau_device)
DECLARE_DEVICE_TYPE(PCXPORT_DMAC, pcxport_dmac_device)
-DECLARE_DEVICE_TYPE(EISA_DMA, eisa_dma_device)
#endif // MAME_MACHINE_AM9517_H
diff --git a/src/devices/machine/am9519.cpp b/src/devices/machine/am9519.cpp
index be0b8c3da10..b1700b38492 100644
--- a/src/devices/machine/am9519.cpp
+++ b/src/devices/machine/am9519.cpp
@@ -103,7 +103,7 @@ IRQ_CALLBACK_MEMBER(am9519_device::iack_cb)
}
-u8 am9519_device::stat_r()
+READ8_MEMBER( am9519_device::stat_r )
{
u8 stat = 0;
for(int n = 0, irq = m_prio; n < 8; n++, irq = (irq + 1) & 7)
@@ -121,7 +121,7 @@ u8 am9519_device::stat_r()
return stat;
}
-u8 am9519_device::data_r()
+READ8_MEMBER( am9519_device::data_r )
{
switch((m_mode & 0x60) >> 5)
{
@@ -137,7 +137,7 @@ u8 am9519_device::data_r()
return 0;
}
-void am9519_device::cmd_w(u8 data)
+WRITE8_MEMBER( am9519_device::cmd_w )
{
m_cmd = data;
switch(data >> 3)
@@ -222,7 +222,7 @@ void am9519_device::cmd_w(u8 data)
set_timer();
}
-void am9519_device::data_w(u8 data)
+WRITE8_MEMBER( am9519_device::data_w )
{
if((m_cmd & 0xf0) >= 0xb0)
{
diff --git a/src/devices/machine/am9519.h b/src/devices/machine/am9519.h
index 315e0bd890d..ddd4925696b 100644
--- a/src/devices/machine/am9519.h
+++ b/src/devices/machine/am9519.h
@@ -36,10 +36,10 @@ public:
auto out_int_callback() { return m_out_int_func.bind(); }
- u8 stat_r();
- u8 data_r();
- void cmd_w(u8 data);
- void data_w(u8 data);
+ DECLARE_READ8_MEMBER( stat_r );
+ DECLARE_READ8_MEMBER( data_r );
+ DECLARE_WRITE8_MEMBER( cmd_w );
+ DECLARE_WRITE8_MEMBER( data_w );
u32 acknowledge();
DECLARE_WRITE_LINE_MEMBER( ireq0_w ) { set_irq_line(0, state); }
diff --git a/src/devices/machine/appldriv.h b/src/devices/machine/appldriv.h
index 6d23284f46a..1a396990167 100644
--- a/src/devices/machine/appldriv.h
+++ b/src/devices/machine/appldriv.h
@@ -63,4 +63,33 @@ private:
// device type definition
DECLARE_DEVICE_TYPE(FLOPPY_APPLE, apple525_floppy_image_device)
+#define MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ downcast<apple525_floppy_image_device *>(device)->set_params(_dividend,_divisor);
+
+#define MCFG_LEGACY_FLOPPY_APPLE_2_DRIVES_ADD(_config,_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY_APPLE, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY_APPLE, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor)
+
+#define MCFG_LEGACY_FLOPPY_APPLE_4_DRIVES_ADD(_config,_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY_APPLE, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY_APPLE, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_2, FLOPPY_APPLE, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_3, FLOPPY_APPLE, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor)
+
+#define MCFG_LEGACY_FLOPPY_APPLE_2_DRIVES_REMOVE() \
+ MCFG_DEVICE_REMOVE(FLOPPY_0) \
+ MCFG_DEVICE_REMOVE(FLOPPY_1)
+
#endif // MAME_MACHINE_APPLDRIV_H
diff --git a/src/devices/machine/applefdc.h b/src/devices/machine/applefdc.h
index 87cc89f36dc..eede57199f7 100644
--- a/src/devices/machine/applefdc.h
+++ b/src/devices/machine/applefdc.h
@@ -124,12 +124,6 @@ private:
class applefdc_device : public applefdc_base_device
{
public:
- applefdc_device(const machine_config &mconfig, const char *tag, device_t *owner, const applefdc_interface *intrf)
- : applefdc_device(mconfig, tag, owner, (uint32_t)0)
- {
- set_config(intrf);
- }
-
applefdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
@@ -151,4 +145,30 @@ public:
iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
+
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+***************************************************************************/
+
+#define MCFG_APPLEFDC_CONFIG(_intrf) \
+ downcast<applefdc_base_device &>(*device).set_config(&(_intrf));
+
+#define MCFG_APPLEFDC_ADD(_tag, _intrf) \
+ MCFG_DEVICE_ADD(_tag, APPLEFDC, 0) \
+ MCFG_APPLEFDC_CONFIG(_intrf)
+
+#define MCFG_APPLEFDC_MODIFY(_tag, _intrf) \
+ MCFG_DEVICE_MODIFY(_tag) \
+ MCFG_APPLEFDC_CONFIG(_intrf)
+
+#define MCFG_IWM_ADD(_tag, _intrf) \
+ MCFG_DEVICE_ADD(_tag, IWM, 0) \
+ MCFG_APPLEFDC_CONFIG(_intrf)
+
+#define MCFG_IWM_MODIFY(_tag, _intrf) \
+ MCFG_DEVICE_MODIFY(_tag) \
+ MCFG_APPLEFDC_CONFIG(_intrf)
+
+
#endif // MAME_MACHINE_APPLEFDC_H
diff --git a/src/devices/machine/at29x.cpp b/src/devices/machine/at29x.cpp
index 3f31e44c0a8..482faf24221 100644
--- a/src/devices/machine/at29x.cpp
+++ b/src/devices/machine/at29x.cpp
@@ -195,7 +195,7 @@ void at29x_device::sync_flags()
/*
read a byte from FEEPROM
*/
-uint8_t at29x_device::read(offs_t offset)
+READ8_MEMBER( at29x_device::read )
{
int reply;
@@ -271,7 +271,7 @@ uint8_t at29x_device::read(offs_t offset)
/*
Write a byte to FEEPROM
*/
-void at29x_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( at29x_device::write )
{
offset &= m_address_mask;
LOGMASKED(LOG_WRITE, "%05x <- %02x\n", offset, data);
diff --git a/src/devices/machine/at29x.h b/src/devices/machine/at29x.h
index 265ef1587c2..435bcaafabc 100644
--- a/src/devices/machine/at29x.h
+++ b/src/devices/machine/at29x.h
@@ -20,8 +20,8 @@ DECLARE_DEVICE_TYPE(AT29C040A, at29c040a_device)
class at29x_device : public device_t, public device_nvram_interface
{
public:
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
protected:
at29x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int memory_size, int device_id, int sector_size);
diff --git a/src/devices/machine/at_keybc.cpp b/src/devices/machine/at_keybc.cpp
index 5e6ac779569..aec9154a38f 100644
--- a/src/devices/machine/at_keybc.cpp
+++ b/src/devices/machine/at_keybc.cpp
@@ -74,8 +74,6 @@ ROM_START(at_kbc)
ROMX_LOAD("1503033.bin", 0x0000, 0x0800, CRC(5a81c0d2) SHA1(0100f8789fb4de74706ae7f9473a12ec2b9bd729), ROM_BIOS(0))
ROM_SYSTEM_BIOS(1, "ptl", "PTL 1986") // unknown controller BIOS, (c) 1985, 1986 PTL
ROMX_LOAD("yan25d05.bin", 0x0000, 0x0800, CRC(70c798f1) SHA1(ae9a79c7184a17331b70a50035ff63c757df094c), ROM_BIOS(1))
- ROM_SYSTEM_BIOS(2, "award15", "Award 1985 V1.5") // MIPS Rx2030 i8742 keyboard controller
- ROMX_LOAD("keyboard_1.5.bin", 0x0000, 0x0800, CRC(f86ba0f7) SHA1(1ad475451db35a76d929824c035d582279fbe3a3), ROM_BIOS(2))
ROM_END
ROM_START(ps2_kbc)
@@ -110,22 +108,22 @@ DEFINE_DEVICE_TYPE(PS2_KEYBOARD_CONTROLLER, ps2_keyboard_controller_device, "ps2
// KEYBOARD CONTROLLER DEVICE BASE
//**************************************************************************
-uint8_t at_kbc_device_base::data_r()
+READ8_MEMBER(at_kbc_device_base::data_r)
{
- return m_mcu->upi41_master_r(machine().dummy_space(), 0U);
+ return m_mcu->upi41_master_r(space, 0U);
}
-uint8_t at_kbc_device_base::status_r()
+READ8_MEMBER(at_kbc_device_base::status_r)
{
- return m_mcu->upi41_master_r(machine().dummy_space(), 1U);
+ return m_mcu->upi41_master_r(space, 1U);
}
-void at_kbc_device_base::data_w(uint8_t data)
+WRITE8_MEMBER(at_kbc_device_base::data_w)
{
machine().scheduler().synchronize(timer_expired_delegate(FUNC(at_kbc_device_base::write_data), this), unsigned(data));
}
-void at_kbc_device_base::command_w(uint8_t data)
+WRITE8_MEMBER(at_kbc_device_base::command_w)
{
machine().scheduler().synchronize(timer_expired_delegate(FUNC(at_kbc_device_base::write_command), this), unsigned(data));
}
@@ -265,7 +263,7 @@ ioport_constructor at_keyboard_controller_device::device_input_ports() const
return INPUT_PORTS_NAME(at_kbc);
}
-void at_keyboard_controller_device::p2_w(uint8_t data)
+WRITE8_MEMBER(at_keyboard_controller_device::p2_w)
{
set_hot_res(BIT(~data, 0));
set_gate_a20(BIT(data, 1));
@@ -279,11 +277,11 @@ void at_keyboard_controller_device::p2_w(uint8_t data)
// PS/2 KEYBOARD/MOUSE CONTROLLER DEVICE
//**************************************************************************
-uint8_t ps2_keyboard_controller_device::data_r()
+READ8_MEMBER(ps2_keyboard_controller_device::data_r)
{
set_kbd_irq(0U);
set_mouse_irq(0U);
- return m_mcu->upi41_master_r(machine().dummy_space(), 0U);
+ return m_mcu->upi41_master_r(space, 0U);
}
WRITE_LINE_MEMBER(ps2_keyboard_controller_device::mouse_clk_w)
@@ -385,12 +383,12 @@ TIMER_CALLBACK_MEMBER(ps2_keyboard_controller_device::set_mouse_data_in)
m_mouse_data_in = param ? 1U : 0U;
}
-uint8_t ps2_keyboard_controller_device::p1_r()
+READ8_MEMBER(ps2_keyboard_controller_device::p1_r)
{
return kbd_data_r() | (mouse_data_r() << 1) | 0xfcU;
}
-void ps2_keyboard_controller_device::p2_w(uint8_t data)
+WRITE8_MEMBER(ps2_keyboard_controller_device::p2_w)
{
set_hot_res(BIT(~data, 0));
set_gate_a20(BIT(data, 1));
diff --git a/src/devices/machine/at_keybc.h b/src/devices/machine/at_keybc.h
index 5ff11aa6ba1..77bf039a7a1 100644
--- a/src/devices/machine/at_keybc.h
+++ b/src/devices/machine/at_keybc.h
@@ -30,10 +30,10 @@ public:
auto kbd_data() { return m_kbd_data_cb.bind(); } // open collector with 10kΩ pull-up
// host interface
- virtual uint8_t data_r();
- virtual uint8_t status_r();
- void data_w(uint8_t data);
- void command_w(uint8_t data);
+ virtual DECLARE_READ8_MEMBER(data_r);
+ virtual DECLARE_READ8_MEMBER(status_r);
+ DECLARE_WRITE8_MEMBER(data_w);
+ DECLARE_WRITE8_MEMBER(command_w);
// inputs from keyboard
DECLARE_WRITE_LINE_MEMBER(kbd_clk_w);
@@ -93,7 +93,7 @@ protected:
private:
// MCU I/O handlers
- void p2_w(uint8_t data);
+ DECLARE_WRITE8_MEMBER(p2_w);
};
@@ -112,7 +112,7 @@ public:
auto mouse_data() { return m_mouse_data_cb.bind(); } // open collector with 10kΩ pull-up
// host interface
- virtual uint8_t data_r() override;
+ virtual DECLARE_READ8_MEMBER(data_r) override;
// inputs from mouse
DECLARE_WRITE_LINE_MEMBER(mouse_clk_w);
@@ -143,8 +143,8 @@ private:
TIMER_CALLBACK_MEMBER(set_mouse_data_in);
// MCU I/O handlers
- uint8_t p1_r();
- void p2_w(uint8_t data);
+ DECLARE_READ8_MEMBER(p1_r);
+ DECLARE_WRITE8_MEMBER(p2_w);
devcb_write_line m_mouse_irq_cb;
devcb_write_line m_mouse_clk_cb, m_mouse_data_cb;
diff --git a/src/devices/machine/atapicdr.cpp b/src/devices/machine/atapicdr.cpp
index 33cb0cb154e..c13b6ff001e 100644
--- a/src/devices/machine/atapicdr.cpp
+++ b/src/devices/machine/atapicdr.cpp
@@ -30,11 +30,11 @@ atapi_fixed_cdrom_device::atapi_fixed_cdrom_device(const machine_config &mconfig
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void atapi_cdrom_device::device_add_mconfig(machine_config &config)
-{
- CDROM(config, "image").set_interface("cdrom");
- CDDA(config, "cdda");
-}
+MACHINE_CONFIG_START(atapi_cdrom_device::device_add_mconfig)
+ MCFG_CDROM_ADD("image")
+ MCFG_CDROM_INTERFACE("cdrom")
+ MCFG_DEVICE_ADD("cdda", CDDA)
+MACHINE_CONFIG_END
void atapi_cdrom_device::device_start()
{
diff --git a/src/devices/machine/ay31015.cpp b/src/devices/machine/ay31015.cpp
index 6ab1103b28a..b9cc6c74a9b 100644
--- a/src/devices/machine/ay31015.cpp
+++ b/src/devices/machine/ay31015.cpp
@@ -116,10 +116,14 @@ ay31015_device::ay31015_device(const machine_config &mconfig, device_type type,
m_rx_bit_count(0),
m_rx_parity(0),
m_rx_pulses(0),
+ m_rx_clock(0),
+ m_rx_timer(nullptr),
m_tx_data(0),
m_tx_buffer(0),
m_tx_parity(0),
m_tx_pulses(0),
+ m_tx_clock(0),
+ m_tx_timer(nullptr),
m_read_si_cb(*this),
m_write_so_cb(*this),
m_write_pe_cb(*this),
@@ -169,6 +173,14 @@ void ay31015_device::device_resolve_objects()
void ay31015_device::device_start()
{
+ m_rx_timer = timer_alloc(TIMER_RX);
+ m_rx_timer->adjust(attotime::never);
+ update_rx_timer();
+
+ m_tx_timer = timer_alloc(TIMER_TX);
+ m_tx_timer->adjust(attotime::never);
+ update_tx_timer();
+
save_item(NAME(m_pins));
save_item(NAME(m_control_reg));
save_item(NAME(m_status_reg));
@@ -182,12 +194,14 @@ void ay31015_device::device_start()
save_item(NAME(m_rx_bit_count));
save_item(NAME(m_rx_parity));
save_item(NAME(m_rx_pulses));
+ save_item(NAME(m_rx_clock));
save_item(NAME(m_tx_state));
save_item(NAME(m_tx_data));
save_item(NAME(m_tx_buffer));
save_item(NAME(m_tx_parity));
save_item(NAME(m_tx_pulses));
+ save_item(NAME(m_tx_clock));
}
//-------------------------------------------------
@@ -256,6 +270,14 @@ void ay31015_device::update_status_pins()
update_status_pin(STATUS_EOC, EOC, m_write_eoc_cb);
}
+void ay31015_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ if (id == TIMER_RX)
+ rx_process();
+ else if(id == TIMER_TX)
+ tx_process();
+}
+
/*************************************************** RECEIVE CONTROLS *************************************************/
@@ -710,6 +732,54 @@ int ay31015_device::get_output_pin( ay31015_device::output_pin pin )
}
+inline void ay31015_device::update_rx_timer()
+{
+ if (m_rx_clock > 0.0)
+ {
+ m_rx_timer->adjust(attotime::from_hz(m_rx_clock), 0, attotime::from_hz(m_rx_clock));
+ }
+ else
+ {
+ m_rx_timer->enable(0);
+ }
+}
+
+
+inline void ay31015_device::update_tx_timer()
+{
+ if (m_tx_clock > 0.0)
+ {
+ m_tx_timer->adjust(attotime::from_hz(m_tx_clock), 0, attotime::from_hz(m_tx_clock));
+ }
+ else
+ {
+ m_tx_timer->enable(0);
+ }
+}
+
+
+/*-------------------------------------------------
+ ay31015_set_receiver_clock - set receive clock
+-------------------------------------------------*/
+
+void ay31015_device::set_receiver_clock( double new_clock )
+{
+ m_rx_clock = new_clock;
+ update_rx_timer();
+}
+
+
+/*-------------------------------------------------
+ ay31015_set_transmitter_clock - set transmit clock
+-------------------------------------------------*/
+
+void ay31015_device::set_transmitter_clock( double new_clock )
+{
+ m_tx_clock = new_clock;
+ update_tx_timer();
+}
+
+
/*-------------------------------------------------
ay31015_get_received_data - return a byte to the computer
-------------------------------------------------*/
diff --git a/src/devices/machine/ay31015.h b/src/devices/machine/ay31015.h
index 42518cb9a85..497c6b6a9f9 100644
--- a/src/devices/machine/ay31015.h
+++ b/src/devices/machine/ay31015.h
@@ -20,6 +20,10 @@ class ay31015_device : public device_t
public:
ay31015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ void set_tx_clock(double tx_clock) { m_tx_clock = tx_clock; }
+ void set_tx_clock(const XTAL &xtal) { set_tx_clock(xtal.dvalue()); }
+ void set_rx_clock(double rx_clock) { m_rx_clock = rx_clock; }
+ void set_rx_clock(const XTAL &xtal) { set_rx_clock(xtal.dvalue()); }
void set_auto_rdav(bool auto_rdav) { m_auto_rdav = auto_rdav; }
auto read_si_callback() { return m_read_si_cb.bind(); }
@@ -54,6 +58,12 @@ public:
DECLARE_READ_LINE_MEMBER(eoc_r) { return get_output_pin(EOC); }
DECLARE_READ_LINE_MEMBER(so_r) { return get_output_pin(SO); }
+ /* Set a new transmitter clock (new_clock is in Hz) */
+ void set_transmitter_clock( double new_clock );
+
+ /* Set a new receiver clock (new_clock is in Hz) */
+ void set_receiver_clock( double new_clock );
+
/* Reead the received data */
/* The received data is available on RD8-RD1 (pins 5-12) */
uint8_t get_received_data();
@@ -104,12 +114,16 @@ protected:
PREP_TIME
};
+ static constexpr device_timer_id TIMER_RX = 0;
+ static constexpr device_timer_id TIMER_TX = 1;
+
ay31015_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
void rx_process();
void tx_process();
@@ -123,6 +137,8 @@ protected:
void transfer_control_pins();
void set_input_pin(input_pin pin, int data);
int get_output_pin(output_pin pin);
+ inline void update_rx_timer();
+ inline void update_tx_timer();
int m_pins[41];
@@ -138,12 +154,16 @@ protected:
uint8_t m_rx_bit_count;
uint8_t m_rx_parity;
uint16_t m_rx_pulses; // total pulses left
+ double m_rx_clock; /* RCP - pin 17 */
+ emu_timer *m_rx_timer;
state_t m_tx_state;
uint8_t m_tx_data; // byte being sent
uint8_t m_tx_buffer; // next byte to send
uint8_t m_tx_parity;
uint16_t m_tx_pulses; // total pulses left
+ double m_tx_clock; /* TCP - pin 40 */
+ emu_timer *m_tx_timer;
devcb_read_line m_read_si_cb; // SI - pin 20 - This will be called whenever the SI pin is sampled. Optional
devcb_write_line m_write_so_cb; // SO - pin 25 - This will be called whenever data is put on the SO pin. Optional
diff --git a/src/devices/machine/bankdev.cpp b/src/devices/machine/bankdev.cpp
index e8e141ff7e6..8c10286ccfa 100644
--- a/src/devices/machine/bankdev.cpp
+++ b/src/devices/machine/bankdev.cpp
@@ -6,7 +6,7 @@
// device type definition
DEFINE_DEVICE_TYPE(ADDRESS_MAP_BANK, address_map_bank_device, "address_map_bank", "Address Map Bank")
-address_map_bank_device::address_map_bank_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+address_map_bank_device::address_map_bank_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock )
: device_t(mconfig, ADDRESS_MAP_BANK, tag, owner, clock),
device_memory_interface(mconfig, *this),
m_endianness(ENDIANNESS_NATIVE),
@@ -46,42 +46,42 @@ void address_map_bank_device::amap64(address_map &map)
map(0x00000000, 0xffffffff).rw(FUNC(address_map_bank_device::read64), FUNC(address_map_bank_device::write64));
}
-void address_map_bank_device::write8(offs_t offset, u8 data)
+WRITE8_MEMBER(address_map_bank_device::write8)
{
m_program->write_byte(m_offset + offset, data);
}
-void address_map_bank_device::write16(offs_t offset, u16 data, u16 mem_mask)
+WRITE16_MEMBER(address_map_bank_device::write16)
{
m_program->write_word(m_offset + (offset << (m_shift+1)), data, mem_mask);
}
-void address_map_bank_device::write32(offs_t offset, u32 data, u32 mem_mask)
+WRITE32_MEMBER(address_map_bank_device::write32)
{
m_program->write_dword(m_offset + (offset << (m_shift+2)), data, mem_mask);
}
-void address_map_bank_device::write64(offs_t offset, u64 data, u64 mem_mask)
+WRITE64_MEMBER(address_map_bank_device::write64)
{
m_program->write_qword(m_offset + (offset << (m_shift+3)), data, mem_mask);
}
-u8 address_map_bank_device::read8(offs_t offset)
+READ8_MEMBER(address_map_bank_device::read8)
{
return m_program->read_byte(m_offset + offset);
}
-u16 address_map_bank_device::read16(offs_t offset, u16 mem_mask)
+READ16_MEMBER(address_map_bank_device::read16)
{
return m_program->read_word(m_offset + (offset << (m_shift+1)), mem_mask);
}
-u32 address_map_bank_device::read32(offs_t offset, u32 mem_mask)
+READ32_MEMBER(address_map_bank_device::read32)
{
return m_program->read_dword(m_offset + (offset << (m_shift+2)), mem_mask);
}
-u64 address_map_bank_device::read64(offs_t offset, u64 mem_mask)
+READ64_MEMBER(address_map_bank_device::read64)
{
return m_program->read_qword(m_offset + (offset << (m_shift+3)), mem_mask);
}
diff --git a/src/devices/machine/bankdev.h b/src/devices/machine/bankdev.h
index 05a3c2eb411..39bcfdcf08a 100644
--- a/src/devices/machine/bankdev.h
+++ b/src/devices/machine/bankdev.h
@@ -12,16 +12,16 @@ class address_map_bank_device :
{
public:
// construction/destruction
- address_map_bank_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ address_map_bank_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
// configuration helpers
template <typename... T> address_map_bank_device& set_map(T &&... args) { set_addrmap(0, std::forward<T>(args)...); return *this; }
address_map_bank_device& set_endianness(endianness_t endianness) { m_endianness = endianness; return *this; }
- address_map_bank_device& set_data_width(u8 data_width) { m_data_width = data_width; return *this; }
- address_map_bank_device& set_addr_width(u8 addr_width) { m_addr_width = addr_width; return *this; }
- address_map_bank_device& set_stride(u32 stride) { m_stride = stride; return *this; }
- address_map_bank_device& set_shift(u32 shift) { m_shift = shift; return *this; }
- address_map_bank_device& set_options(endianness_t endianness, u8 data_width, u8 addr_width, u32 stride = 1)
+ address_map_bank_device& set_data_width(uint8_t data_width) { m_data_width = data_width; return *this; }
+ address_map_bank_device& set_addr_width(uint8_t addr_width) { m_addr_width = addr_width; return *this; }
+ address_map_bank_device& set_stride(uint32_t stride) { m_stride = stride; return *this; }
+ address_map_bank_device& set_shift(uint32_t shift) { m_shift = shift; return *this; }
+ address_map_bank_device& set_options(endianness_t endianness, uint8_t data_width, uint8_t addr_width, uint32_t stride = 1)
{
set_endianness(endianness);
set_data_width(data_width);
@@ -32,25 +32,25 @@ public:
template <typename... T> address_map_bank_device& map(T &&... args) { set_addrmap(0, std::forward<T>(args)...); return *this; }
address_map_bank_device& endianness(endianness_t endianness) { m_endianness = endianness; return *this; }
- address_map_bank_device& data_width(u8 data_width) { m_data_width = data_width; return *this; }
- address_map_bank_device& addr_width(u8 addr_width) { m_addr_width = addr_width; return *this; }
- address_map_bank_device& stride(u32 stride) { m_stride = stride; return *this; }
- address_map_bank_device& shift(u32 shift) { m_shift = shift; return *this; }
+ address_map_bank_device& data_width(uint8_t data_width) { m_data_width = data_width; return *this; }
+ address_map_bank_device& addr_width(uint8_t addr_width) { m_addr_width = addr_width; return *this; }
+ address_map_bank_device& stride(uint32_t stride) { m_stride = stride; return *this; }
+ address_map_bank_device& shift(uint32_t shift) { m_shift = shift; return *this; }
void amap8(address_map &map);
void amap16(address_map &map);
void amap32(address_map &map);
void amap64(address_map &map);
- void write8(offs_t offset, u8 data);
- void write16(offs_t offset, u16 data, u16 mem_mask = 0xffff);
- void write32(offs_t offset, u32 data, u32 mem_mask = 0xffffffff);
- void write64(offs_t offset, u64 data, u64 mem_mask = ~u64(0));
+ DECLARE_WRITE8_MEMBER(write8);
+ DECLARE_WRITE16_MEMBER(write16);
+ DECLARE_WRITE32_MEMBER(write32);
+ DECLARE_WRITE64_MEMBER(write64);
- u8 read8(offs_t offset);
- u16 read16(offs_t offset, u16 mem_mask = 0xffff);
- u32 read32(offs_t offset, u32 mem_mask = 0xffffffff);
- u64 read64(offs_t offset, u64 mem_mask = ~u64(0));
+ DECLARE_READ8_MEMBER(read8);
+ DECLARE_READ16_MEMBER(read16);
+ DECLARE_READ32_MEMBER(read32);
+ DECLARE_READ64_MEMBER(read64);
void set_bank(offs_t offset);
@@ -64,9 +64,9 @@ protected:
private:
// internal state
endianness_t m_endianness;
- u8 m_data_width;
- u8 m_addr_width;
- u32 m_stride;
+ uint8_t m_data_width;
+ uint8_t m_addr_width;
+ uint32_t m_stride;
address_space_config m_program_config;
address_space *m_program;
offs_t m_offset;
diff --git a/src/devices/machine/clock.h b/src/devices/machine/clock.h
index 4bf0bed47a0..32989a15149 100644
--- a/src/devices/machine/clock.h
+++ b/src/devices/machine/clock.h
@@ -6,11 +6,17 @@
#pragma once
+#define MCFG_CLOCK_ADD(_tag, _clock) \
+ MCFG_DEVICE_ADD(_tag, CLOCK, _clock)
+
+#define MCFG_CLOCK_SIGNAL_HANDLER(_devcb) \
+ downcast<clock_device &>(*device).set_signal_handler(DEVCB_##_devcb);
+
class clock_device : public device_t
{
public:
+ template <class Object> devcb_base &set_signal_handler(Object &&cb) { return m_signal_handler.set_callback(std::forward<Object>(cb)); }
auto signal_handler() { return m_signal_handler.bind(); }
- DECLARE_READ_LINE_MEMBER(signal_r) { return m_signal; }
clock_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
diff --git a/src/devices/machine/com8116.cpp b/src/devices/machine/com8116.cpp
index 06ebfb2f5b0..0a3da24042e 100644
--- a/src/devices/machine/com8116.cpp
+++ b/src/devices/machine/com8116.cpp
@@ -25,7 +25,6 @@ DEFINE_DEVICE_TYPE(COM8116, com8116_device, "com8116", "COM8116 Dual BRG")
DEFINE_DEVICE_TYPE(COM8116_003, com8116_003_device, "com8116_003", "COM8116-003 Dual BRG")
DEFINE_DEVICE_TYPE(COM5016_5, com5016_5_device, "com5016_5", "COM5016-5 Dual BRG")
DEFINE_DEVICE_TYPE(COM5016_013, com5016_013_device, "com5016_013", "COM5016-013 Dual BRG")
-DEFINE_DEVICE_TYPE(COM8116_020, com8116_020_device, "com8116_020", "COM8116-020 Dual BRG")
// Parts with T after the number do not have an internal oscillator and require an external clock source
// The SMC/COM 5xxx parts are all dual 5v/12v parts, while the 8xxx parts are 5v only
@@ -41,6 +40,7 @@ const int com8116_device::divisors_16X_5_0688MHz[16] =
// SMC/COM8116-003 and WD WD-1943-03
// from http://www.vintagecomputer.net/fjkraan/comp/divcomp/doc/SMC_BaudGen.pdf page 283 (pdf page 20)
// baud rates are 50, 75, 110, 134.5, 150, 200, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800, 9600, 19200
+// SMC/COM8116T-020 should have similar output rates, but clock is unknown and probably different
const int com8116_device::divisors_16X_6_01835MHz[16] =
{ 7523, 5015, 3420, 2797, 2508, 1881, 1254, 627, 313, 209, 188, 157, 104, 78, 39, 20 };
@@ -63,12 +63,6 @@ const int com8116_device::divisors_32X_5_0688MHz[16] =
const int com8116_device::divisors_16X_2_7648MHz[16] =
{ 3456, 2304, 1571, 1285, 1152, 864, 576, 288, 144, 96, 86, 72, 48, 36, 18, 9 };
-// SMC/COM8116T-020 (corrected from http://bitsavers.org/pdf/visualTechnology/Visual_100/MM-100-001-0A_Visual_100_and_Visual_400_Video_Display_Terminal_Maintenance_Manual_Sep1980.pdf (pdf page 99))
-// (75, 134.5 and 2000 baud divisors given as 1,807, 856 and 57, which do not match stated actual frequencies)
-// baud rates are 50, 75, 110, 134.5, 150, 200, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800, 9600, 19200
-const int com8116_device::divisors_16X_1_8432MHz[16] =
- { 2304, 1536, 1047, 857, 768, 576, 384, 192, 96, 64, 58, 48, 32, 24, 12, 6 };
-
// SMC/COM5026(T)-030 (non-standard serial rates, from http://bitsavers.informatik.uni-stuttgart.de/pdf/standardMicrosystems/_dataBooks/1979_StandardMicrosystems.pdf page 135)
const int com8116_device::divisors_16X_5_0688MHz_030[16] =
{ 731, 733, 735, 737, 741, 743, 745, 751, 6970, 5569, 5433, 4752, 4269, 1920, 1584, 301 };
@@ -126,11 +120,6 @@ com5016_013_device::com5016_013_device(const machine_config &mconfig, const char
{
}
-com8116_020_device::com8116_020_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- com8116_device(mconfig, COM8116_020, tag, owner, clock, divisors_16X_1_8432MHz)
-{
-}
-
//-------------------------------------------------
// device_start - device-specific startup
@@ -204,7 +193,7 @@ void com8116_device::device_timer(emu_timer &timer, device_timer_id id, int para
// str_w -
//-------------------------------------------------
-void com8116_device::str_w(uint8_t data)
+void com8116_device::write_str(uint8_t data)
{
int fr_divider = data & 0x0f;
int fr_clock = clock() / m_divisors[fr_divider];
@@ -219,7 +208,7 @@ void com8116_device::str_w(uint8_t data)
// stt_w -
//-------------------------------------------------
-void com8116_device::stt_w(uint8_t data)
+void com8116_device::write_stt(uint8_t data)
{
int ft_divider = data & 0x0f;
int ft_clock = clock() / m_divisors[ft_divider];
@@ -234,10 +223,10 @@ void com8116_device::stt_w(uint8_t data)
// str_stt_w -
//-------------------------------------------------
-void com8116_device::str_stt_w(uint8_t data)
+WRITE8_MEMBER(com8116_device::str_stt_w)
{
- str_w(data >> 4);
- stt_w(data & 0x0f);
+ write_str(data >> 4);
+ write_stt(data & 0x0f);
}
@@ -245,8 +234,8 @@ void com8116_device::str_stt_w(uint8_t data)
// stt_str_w -
//-------------------------------------------------
-void com8116_device::stt_str_w(uint8_t data)
+WRITE8_MEMBER(com8116_device::stt_str_w)
{
- stt_w(data >> 4);
- str_w(data & 0x0f);
+ write_stt(data >> 4);
+ write_str(data & 0x0f);
}
diff --git a/src/devices/machine/com8116.h b/src/devices/machine/com8116.h
index d073ceac91f..50c8849e2ee 100644
--- a/src/devices/machine/com8116.h
+++ b/src/devices/machine/com8116.h
@@ -43,10 +43,12 @@ public:
auto fr_handler() { return m_fr_handler.bind(); }
auto ft_handler() { return m_ft_handler.bind(); }
- void str_w(uint8_t data);
- void stt_w(uint8_t data);
- void str_stt_w(uint8_t data);
- void stt_str_w(uint8_t data);
+ void write_str(uint8_t data);
+ void write_stt(uint8_t data);
+ DECLARE_WRITE8_MEMBER(str_w) { write_str(data); }
+ DECLARE_WRITE8_MEMBER(stt_w) { write_stt(data); }
+ DECLARE_WRITE8_MEMBER(str_stt_w);
+ DECLARE_WRITE8_MEMBER(stt_str_w);
protected:
com8116_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const int *divisors);
@@ -56,7 +58,6 @@ protected:
static const int divisors_16X_4_9152MHz[16];
static const int divisors_32X_5_0688MHz[16];
static const int divisors_16X_2_7648MHz[16];
- static const int divisors_16X_1_8432MHz[16];
static const int divisors_16X_5_0688MHz_030[16];
static const int divisors_16X_4_6080MHz[16];
static const int divisors_16X_4_9152MHz_SY2661_1[16];
@@ -122,21 +123,10 @@ public:
};
-// ======================> com8116_020_device
-
-class com8116_020_device : public com8116_device
-{
-public:
- // construction/destruction
- com8116_020_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-};
-
-
// device type definition
DECLARE_DEVICE_TYPE(COM8116, com8116_device)
DECLARE_DEVICE_TYPE(COM8116_003, com8116_003_device)
DECLARE_DEVICE_TYPE(COM5016_5, com5016_5_device)
DECLARE_DEVICE_TYPE(COM5016_013, com5016_013_device)
-DECLARE_DEVICE_TYPE(COM8116_020, com8116_020_device)
#endif // MAME_MACHINE_COM8116_H
diff --git a/src/devices/machine/cr511b.cpp b/src/devices/machine/cr511b.cpp
index 6a4309f12c9..066f08575ac 100644
--- a/src/devices/machine/cr511b.cpp
+++ b/src/devices/machine/cr511b.cpp
@@ -23,13 +23,13 @@ DEFINE_DEVICE_TYPE(CR511B, cr511b_device, "cr511b", "CR-511-B CD-ROM drive")
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void cr511b_device::device_add_mconfig(machine_config &config)
-{
- CDROM(config, m_cdrom).set_interface("cdrom");
- CDDA(config, m_cdda);
- m_cdda->add_route(0, ":lspeaker", 1.0);
- m_cdda->add_route(1, ":rspeaker", 1.0);
-}
+MACHINE_CONFIG_START(cr511b_device::device_add_mconfig)
+ MCFG_CDROM_ADD("cdrom")
+ MCFG_CDROM_INTERFACE("cdrom")
+ MCFG_DEVICE_ADD("cdda", CDDA)
+ MCFG_SOUND_ROUTE(0, ":lspeaker", 1.0)
+ MCFG_SOUND_ROUTE(1, ":rspeaker", 1.0)
+MACHINE_CONFIG_END
//**************************************************************************
diff --git a/src/devices/machine/cs4031.cpp b/src/devices/machine/cs4031.cpp
index 13ec9b90a6d..fb1ac37b698 100644
--- a/src/devices/machine/cs4031.cpp
+++ b/src/devices/machine/cs4031.cpp
@@ -263,19 +263,19 @@ void cs4031_device::device_start()
m_space->install_rom(0xffff0000, 0xffffffff, m_bios + 0xf0000);
// install i/o accesses
- m_space_io->install_readwrite_handler(0x0000, 0x000f, read8sm_delegate(FUNC(am9517a_device::read), &(*m_dma1)), write8sm_delegate(FUNC(am9517a_device::write), &(*m_dma1)), 0xffffffff);
+ m_space_io->install_readwrite_handler(0x0000, 0x000f, read8_delegate(FUNC(am9517a_device::read), &(*m_dma1)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma1)), 0xffffffff);
m_space_io->install_readwrite_handler(0x0020, 0x0023, read8sm_delegate(FUNC(pic8259_device::read), &(*m_intc1)), write8sm_delegate(FUNC(pic8259_device::write), &(*m_intc1)), 0x0000ffff);
- m_space_io->install_write_handler(0x0020, 0x0023, write8smo_delegate(FUNC(cs4031_device::config_address_w), this), 0x00ff0000);
- m_space_io->install_readwrite_handler(0x0020, 0x0023, read8smo_delegate(FUNC(cs4031_device::config_data_r), this), write8smo_delegate(FUNC(cs4031_device::config_data_w), this), 0xff000000);
+ m_space_io->install_write_handler(0x0020, 0x0023, write8_delegate(FUNC(cs4031_device::config_address_w), this), 0x00ff0000);
+ m_space_io->install_readwrite_handler(0x0020, 0x0023, read8_delegate(FUNC(cs4031_device::config_data_r), this), write8_delegate(FUNC(cs4031_device::config_data_w), this), 0xff000000);
m_space_io->install_readwrite_handler(0x0040, 0x0043, read8sm_delegate(FUNC(pit8254_device::read), &(*m_ctc)), write8sm_delegate(FUNC(pit8254_device::write), &(*m_ctc)), 0xffffffff);
- m_space_io->install_readwrite_handler(0x0060, 0x0063, read8smo_delegate(FUNC(cs4031_device::keyb_data_r), this), write8smo_delegate(FUNC(cs4031_device::keyb_data_w), this), 0x000000ff);
- m_space_io->install_readwrite_handler(0x0060, 0x0063, read8smo_delegate(FUNC(cs4031_device::portb_r), this), write8smo_delegate(FUNC(cs4031_device::portb_w), this), 0x0000ff00);
- m_space_io->install_readwrite_handler(0x0064, 0x0067, read8smo_delegate(FUNC(cs4031_device::keyb_status_r), this), write8smo_delegate(FUNC(cs4031_device::keyb_command_w), this), 0x000000ff);
- m_space_io->install_readwrite_handler(0x0070, 0x0073, read8sm_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8sm_delegate(FUNC(cs4031_device::rtc_w), this), 0x0000ffff);
- m_space_io->install_readwrite_handler(0x0080, 0x008f, read8sm_delegate(FUNC(cs4031_device::dma_page_r), this), write8sm_delegate(FUNC(cs4031_device::dma_page_w), this), 0xffffffff);
- m_space_io->install_readwrite_handler(0x0090, 0x0093, read8smo_delegate(FUNC(cs4031_device::sysctrl_r), this), write8smo_delegate(FUNC(cs4031_device::sysctrl_w), this), 0x00ff0000);
+ m_space_io->install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(cs4031_device::keyb_data_r), this), write8_delegate(FUNC(cs4031_device::keyb_data_w), this), 0x000000ff);
+ m_space_io->install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(cs4031_device::portb_r), this), write8_delegate(FUNC(cs4031_device::portb_w), this), 0x0000ff00);
+ m_space_io->install_readwrite_handler(0x0064, 0x0067, read8_delegate(FUNC(cs4031_device::keyb_status_r), this), write8_delegate(FUNC(cs4031_device::keyb_command_w), this), 0x000000ff);
+ m_space_io->install_readwrite_handler(0x0070, 0x0073, read8_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8_delegate(FUNC(cs4031_device::rtc_w), this), 0x0000ffff);
+ m_space_io->install_readwrite_handler(0x0080, 0x008f, read8_delegate(FUNC(cs4031_device::dma_page_r), this), write8_delegate(FUNC(cs4031_device::dma_page_w), this), 0xffffffff);
+ m_space_io->install_readwrite_handler(0x0090, 0x0093, read8_delegate(FUNC(cs4031_device::sysctrl_r), this), write8_delegate(FUNC(cs4031_device::sysctrl_w), this), 0x00ff0000);
m_space_io->install_readwrite_handler(0x00a0, 0x00a3, read8sm_delegate(FUNC(pic8259_device::read), &(*m_intc2)), write8sm_delegate(FUNC(pic8259_device::write), &(*m_intc2)), 0x0000ffff);
- m_space_io->install_readwrite_handler(0x00c0, 0x00df, read8sm_delegate(FUNC(cs4031_device::dma2_r),this), write8sm_delegate(FUNC(cs4031_device::dma2_w),this), 0xffffffff);
+ m_space_io->install_readwrite_handler(0x00c0, 0x00df, read8_delegate(FUNC(cs4031_device::dma2_r),this), write8_delegate(FUNC(cs4031_device::dma2_w),this), 0xffffffff);
}
//-------------------------------------------------
@@ -328,7 +328,7 @@ offs_t cs4031_device::page_offset()
return 0xff0000;
}
-uint8_t cs4031_device::dma_read_byte(offs_t offset)
+READ8_MEMBER( cs4031_device::dma_read_byte )
{
if (m_dma_channel == -1)
return 0xff;
@@ -336,7 +336,7 @@ uint8_t cs4031_device::dma_read_byte(offs_t offset)
return m_space->read_byte(page_offset() + offset);
}
-void cs4031_device::dma_write_byte(offs_t offset, uint8_t data)
+WRITE8_MEMBER( cs4031_device::dma_write_byte )
{
if (m_dma_channel == -1)
return;
@@ -344,7 +344,7 @@ void cs4031_device::dma_write_byte(offs_t offset, uint8_t data)
m_space->write_byte(page_offset() + offset, data);
}
-uint8_t cs4031_device::dma_read_word(offs_t offset)
+READ8_MEMBER( cs4031_device::dma_read_word )
{
if (m_dma_channel == -1)
return 0xff;
@@ -355,7 +355,7 @@ uint8_t cs4031_device::dma_read_word(offs_t offset)
return result;
}
-void cs4031_device::dma_write_word(offs_t offset, uint8_t data)
+WRITE8_MEMBER( cs4031_device::dma_write_word )
{
if (m_dma_channel == -1)
return;
@@ -377,8 +377,6 @@ WRITE_LINE_MEMBER( cs4031_device::dma1_eop_w )
void cs4031_device::set_dma_channel(int channel, bool state)
{
- //m_write_dack(channel, state);
-
if (!state)
{
m_dma_channel = channel;
@@ -431,7 +429,7 @@ void cs4031_device::trigger_nmi()
}
}
-uint8_t cs4031_device::intc1_slave_ack_r(offs_t offset)
+READ8_MEMBER( cs4031_device::intc1_slave_ack_r )
{
if (offset == 2) // IRQ 2
return m_intc2->acknowledge();
@@ -478,13 +476,13 @@ WRITE_LINE_MEMBER( cs4031_device::ctc_out2_w )
// CHIPSET CONFIGURATION
//**************************************************************************
-void cs4031_device::config_address_w(uint8_t data)
+WRITE8_MEMBER( cs4031_device::config_address_w )
{
m_address = data;
m_address_valid = (m_address < 0x20) ? true : false;
}
-uint8_t cs4031_device::config_data_r()
+READ8_MEMBER( cs4031_device::config_data_r )
{
uint8_t result = 0xff;
@@ -501,7 +499,7 @@ uint8_t cs4031_device::config_data_r()
return result;
}
-void cs4031_device::config_data_w(uint8_t data)
+WRITE8_MEMBER( cs4031_device::config_data_w )
{
if (m_address_valid)
{
@@ -694,21 +692,21 @@ void cs4031_device::keyboard_gatea20(int state)
update_a20m();
}
-uint8_t cs4031_device::keyb_status_r()
+READ8_MEMBER( cs4031_device::keyb_status_r )
{
LOGKEYBOARD("cs4031_device::keyb_status_r\n");
- return m_keybc->status_r();
+ return m_keybc->status_r(space, 0);
}
-void cs4031_device::keyb_command_blocked_w(uint8_t data)
+WRITE8_MEMBER( cs4031_device::keyb_command_blocked_w )
{
// command is optionally blocked
if (!BIT(m_registers[SOFT_RESET_AND_GATEA20], 7))
- m_keybc->command_w(data);
+ m_keybc->command_w(space, 0, data);
}
-void cs4031_device::keyb_command_w(uint8_t data)
+WRITE8_MEMBER( cs4031_device::keyb_command_w )
{
LOGKEYBOARD("cs4031_device::keyb_command_w: %02x\n", data);
@@ -722,12 +720,12 @@ void cs4031_device::keyb_command_w(uint8_t data)
emulated_gatea20(1);
// self-test is never blocked
- m_keybc->command_w(data);
+ m_keybc->command_w(space, 0, data);
break;
case 0xd1:
m_keybc_d1_written = true;
- keyb_command_blocked_w(data);
+ keyb_command_blocked_w(space, 0, data);
break;
case 0xf0:
@@ -756,7 +754,7 @@ void cs4031_device::keyb_command_w(uint8_t data)
emulated_gatea20(1);
}
- keyb_command_blocked_w(data);
+ keyb_command_blocked_w(space, 0, data);
break;
@@ -765,28 +763,28 @@ void cs4031_device::keyb_command_w(uint8_t data)
if (m_keybc_data_blocked)
{
m_keybc_data_blocked = false;
- keyb_command_blocked_w(data);
+ keyb_command_blocked_w(space, 0, data);
}
else
- m_keybc->command_w(data);
+ m_keybc->command_w(space, 0, data);
break;
// everything else goes directly to the keyboard controller
default:
- m_keybc->command_w(data);
+ m_keybc->command_w(space, 0, data);
break;
}
}
-uint8_t cs4031_device::keyb_data_r()
+READ8_MEMBER( cs4031_device::keyb_data_r )
{
LOGKEYBOARD("cs4031_device::keyb_data_r\n");
- return m_keybc->data_r();
+ return m_keybc->data_r(space, 0);
}
-void cs4031_device::keyb_data_w(uint8_t data)
+WRITE8_MEMBER( cs4031_device::keyb_data_w )
{
LOGKEYBOARD("cs4031_device::keyb_data_w: %02x\n", data);
@@ -800,7 +798,7 @@ void cs4031_device::keyb_data_w(uint8_t data)
else
{
m_keybc_data_blocked = false;
- m_keybc->data_w(data);
+ m_keybc->data_w(space, 0, data);
}
}
@@ -839,7 +837,7 @@ WRITE_LINE_MEMBER( cs4031_device::kbrst_w )
1 - Fast Gate A20
*/
-void cs4031_device::sysctrl_w(uint8_t data)
+WRITE8_MEMBER( cs4031_device::sysctrl_w )
{
LOGIO("cs4031_device::sysctrl_w: %u\n", data);
@@ -855,7 +853,7 @@ void cs4031_device::sysctrl_w(uint8_t data)
m_cpureset = BIT(data, 0);
}
-uint8_t cs4031_device::sysctrl_r()
+READ8_MEMBER( cs4031_device::sysctrl_r )
{
uint8_t result = 0; // reserved bits read as 0?
@@ -885,7 +883,7 @@ uint8_t cs4031_device::sysctrl_r()
7 - Parity check latch (r) [not emulated]
*/
-uint8_t cs4031_device::portb_r()
+READ8_MEMBER( cs4031_device::portb_r )
{
if (0)
logerror("cs4031_device::portb_r: %02x\n", m_portb);
@@ -893,7 +891,7 @@ uint8_t cs4031_device::portb_r()
return m_portb;
}
-void cs4031_device::portb_w(uint8_t data)
+WRITE8_MEMBER( cs4031_device::portb_w )
{
if (0)
logerror("cs4031_device::portb_w: %02x\n", data);
@@ -919,7 +917,7 @@ void cs4031_device::portb_w(uint8_t data)
7 - NMI mask
6:0 - RTC address
*/
-void cs4031_device::rtc_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER( cs4031_device::rtc_w )
{
if (0)
logerror("cs4031_device::rtc_w: %02x\n", data);
@@ -930,5 +928,5 @@ void cs4031_device::rtc_w(offs_t offset, uint8_t data)
data &= 0x7f;
}
- m_rtc->write(offset, data);
+ m_rtc->write(space, offset, data);
}
diff --git a/src/devices/machine/cs4031.h b/src/devices/machine/cs4031.h
index 3e554e91904..e8b6e314f93 100644
--- a/src/devices/machine/cs4031.h
+++ b/src/devices/machine/cs4031.h
@@ -59,23 +59,23 @@ public:
auto spkr() { return m_write_spkr.bind(); }
// internal io
- void config_address_w(uint8_t data);
- uint8_t config_data_r();
- void config_data_w(uint8_t data);
- uint8_t portb_r();
- void portb_w(uint8_t data);
- void rtc_w(offs_t offset, uint8_t data);
- void sysctrl_w(uint8_t data);
- uint8_t sysctrl_r();
- uint8_t dma_page_r(offs_t offset) { return m_dma_page[offset]; }
- void dma_page_w(offs_t offset, uint8_t data) { m_dma_page[offset] = data; }
- uint8_t dma2_r(offs_t offset) { return m_dma2->read(offset / 2); }
- void dma2_w(offs_t offset, uint8_t data) { m_dma2->write(offset / 2, data); }
- uint8_t keyb_data_r();
- void keyb_data_w(uint8_t data);
- uint8_t keyb_status_r();
- void keyb_command_w(uint8_t data);
- void keyb_command_blocked_w(uint8_t data);
+ DECLARE_WRITE8_MEMBER( config_address_w );
+ DECLARE_READ8_MEMBER( config_data_r );
+ DECLARE_WRITE8_MEMBER( config_data_w );
+ DECLARE_READ8_MEMBER( portb_r );
+ DECLARE_WRITE8_MEMBER( portb_w );
+ DECLARE_WRITE8_MEMBER( rtc_w );
+ DECLARE_WRITE8_MEMBER( sysctrl_w );
+ DECLARE_READ8_MEMBER( sysctrl_r );
+ DECLARE_READ8_MEMBER( dma_page_r ) { return m_dma_page[offset]; }
+ DECLARE_WRITE8_MEMBER( dma_page_w ) { m_dma_page[offset] = data; }
+ DECLARE_READ8_MEMBER( dma2_r ) { return m_dma2->read(space, offset / 2); }
+ DECLARE_WRITE8_MEMBER( dma2_w ) { m_dma2->write(space, offset / 2, data); }
+ DECLARE_READ8_MEMBER( keyb_data_r );
+ DECLARE_WRITE8_MEMBER( keyb_data_w );
+ DECLARE_READ8_MEMBER( keyb_status_r );
+ DECLARE_WRITE8_MEMBER( keyb_command_w );
+ DECLARE_WRITE8_MEMBER( keyb_command_blocked_w );
// input lines
DECLARE_WRITE_LINE_MEMBER( irq01_w ) { m_intc1->ir1_w(state); }
@@ -205,25 +205,25 @@ private:
uint8_t m_registers[0x20];
- uint8_t dma_read_byte(offs_t offset);
- void dma_write_byte(offs_t offset, uint8_t data);
- uint8_t dma_read_word(offs_t offset);
- void dma_write_word(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( dma_read_byte );
+ DECLARE_WRITE8_MEMBER( dma_write_byte );
+ DECLARE_READ8_MEMBER( dma_read_word );
+ DECLARE_WRITE8_MEMBER( dma_write_word );
DECLARE_WRITE_LINE_MEMBER( dma1_eop_w );
- uint8_t dma1_ior0_r() { return m_read_ior(0); }
- uint8_t dma1_ior1_r() { return m_read_ior(1); }
- uint8_t dma1_ior2_r() { return m_read_ior(2); }
- uint8_t dma1_ior3_r() { return m_read_ior(3); }
- uint8_t dma2_ior1_r() { uint16_t const result = m_read_ior(5); m_dma_high_byte = result >> 8; return result; }
- uint8_t dma2_ior2_r() { uint16_t const result = m_read_ior(6); m_dma_high_byte = result >> 8; return result; }
- uint8_t dma2_ior3_r() { uint16_t const result = m_read_ior(7); m_dma_high_byte = result >> 8; return result; }
- void dma1_iow0_w(uint8_t data) { m_write_iow(0, data, 0xffff); }
- void dma1_iow1_w(uint8_t data) { m_write_iow(1, data, 0xffff); }
- void dma1_iow2_w(uint8_t data) { m_write_iow(2, data, 0xffff); }
- void dma1_iow3_w(uint8_t data) { m_write_iow(3, data, 0xffff); }
- void dma2_iow1_w(uint8_t data) { m_write_iow(5, (m_dma_high_byte << 8) | data, 0xffff); }
- void dma2_iow2_w(uint8_t data) { m_write_iow(6, (m_dma_high_byte << 8) | data, 0xffff); }
- void dma2_iow3_w(uint8_t data) { m_write_iow(7, (m_dma_high_byte << 8) | data, 0xffff); }
+ DECLARE_READ8_MEMBER( dma1_ior0_r ) { return m_read_ior(0); }
+ DECLARE_READ8_MEMBER( dma1_ior1_r ) { return m_read_ior(1); }
+ DECLARE_READ8_MEMBER( dma1_ior2_r ) { return m_read_ior(2); }
+ DECLARE_READ8_MEMBER( dma1_ior3_r ) { return m_read_ior(3); }
+ DECLARE_READ8_MEMBER( dma2_ior1_r ) { uint16_t const result = m_read_ior(5); m_dma_high_byte = result >> 8; return result; }
+ DECLARE_READ8_MEMBER( dma2_ior2_r ) { uint16_t const result = m_read_ior(6); m_dma_high_byte = result >> 8; return result; }
+ DECLARE_READ8_MEMBER( dma2_ior3_r ) { uint16_t const result = m_read_ior(7); m_dma_high_byte = result >> 8; return result; }
+ DECLARE_WRITE8_MEMBER( dma1_iow0_w ) { m_write_iow(0, data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma1_iow1_w ) { m_write_iow(1, data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma1_iow2_w ) { m_write_iow(2, data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma1_iow3_w ) { m_write_iow(3, data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma2_iow1_w ) { m_write_iow(5, (m_dma_high_byte << 8) | data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma2_iow2_w ) { m_write_iow(6, (m_dma_high_byte << 8) | data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma2_iow3_w ) { m_write_iow(7, (m_dma_high_byte << 8) | data, 0xffff); }
DECLARE_WRITE_LINE_MEMBER( dma1_dack0_w ) { set_dma_channel(0, state); }
DECLARE_WRITE_LINE_MEMBER( dma1_dack1_w ) { set_dma_channel(1, state); }
DECLARE_WRITE_LINE_MEMBER( dma1_dack2_w ) { set_dma_channel(2, state); }
@@ -234,7 +234,7 @@ private:
DECLARE_WRITE_LINE_MEMBER( dma2_dack3_w ) { set_dma_channel(7, state); }
DECLARE_WRITE_LINE_MEMBER( dma2_hreq_w ) { m_write_hold(state); }
DECLARE_WRITE_LINE_MEMBER( intc1_int_w ) { m_write_intr(state); }
- uint8_t intc1_slave_ack_r(offs_t offset);
+ DECLARE_READ8_MEMBER( intc1_slave_ack_r );
DECLARE_WRITE_LINE_MEMBER( ctc_out1_w );
DECLARE_WRITE_LINE_MEMBER( ctc_out2_w );
};
diff --git a/src/devices/machine/diablo_hd.cpp b/src/devices/machine/diablo_hd.cpp
index 36c57cbd0d7..669285ccb08 100644
--- a/src/devices/machine/diablo_hd.cpp
+++ b/src/devices/machine/diablo_hd.cpp
@@ -1324,9 +1324,11 @@ void diablo_hd_device::device_start()
void diablo_hd_device::device_reset()
{
// free previous page cache
- for (int page = 0; page < m_pages; page++)
- if (m_cache[page])
- m_cache[page] = nullptr;
+ if (m_cache) {
+ for (int page = 0; page < m_pages; page++)
+ if (m_cache[page])
+ m_cache[page] = nullptr;
+ }
// free previous bits cache
if (m_bits) {
for (int page = 0; page < m_pages; page++)
@@ -1440,10 +1442,9 @@ void diablo_hd_device::device_timer(emu_timer &timer, device_timer_id id, int pa
}
}
-void diablo_hd_device::device_add_mconfig(machine_config &config)
-{
- DIABLO(config, "drive", 0);
-}
+MACHINE_CONFIG_START(diablo_hd_device::device_add_mconfig)
+ MCFG_DIABLO_ADD("drive")
+MACHINE_CONFIG_END
DEFINE_DEVICE_TYPE(DIABLO_HD, diablo_hd_device, "diablo_hd", "Diablo Disk")
diff --git a/src/devices/machine/diablo_hd.h b/src/devices/machine/diablo_hd.h
index 93915e628e3..41f206cc531 100644
--- a/src/devices/machine/diablo_hd.h
+++ b/src/devices/machine/diablo_hd.h
@@ -162,4 +162,7 @@ private:
void sector_mark_0();
};
+#define MCFG_DIABLO_DRIVES_ADD() \
+ MCFG_DEVICE_ADD(DIABLO_HD_0, DIABLO_HD, 3333333) \
+ MCFG_DEVICE_ADD(DIABLO_HD_1, DIABLO_HD, 3333333)
#endif // !defined(_DIABLO_HD_DEVICE_)
diff --git a/src/devices/machine/dp8390.h b/src/devices/machine/dp8390.h
index c13fe53e1d3..74b57f027d1 100644
--- a/src/devices/machine/dp8390.h
+++ b/src/devices/machine/dp8390.h
@@ -8,13 +8,38 @@
// device stuff
+#define MCFG_DP8390D_IRQ_CB(_devcb) \
+ downcast<dp8390_device &>(*device).set_irq_callback(DEVCB_##_devcb);
+
+#define MCFG_DP8390D_BREQ_CB(_devcb) \
+ downcast<dp8390_device &>(*device).set_breq_callback(DEVCB_##_devcb);
+
+#define MCFG_DP8390D_MEM_READ_CB(_devcb) \
+ downcast<dp8390_device &>(*device).set_mem_read_callback(DEVCB_##_devcb);
+
+#define MCFG_DP8390D_MEM_WRITE_CB(_devcb) \
+ downcast<dp8390_device &>(*device).set_mem_write_callback(DEVCB_##_devcb);
+
+#define MCFG_RTL8019A_IRQ_CB(_devcb) \
+ downcast<rtl8019a_device &>(*device).set_irq_callback(DEVCB_##_devcb);
+
+#define MCFG_RTL8019A_BREQ_CB(_devcb) \
+ downcast<rtl8019a_device &>(*device).set_breq_callback(DEVCB_##_devcb);
+
+#define MCFG_RTL8019A_MEM_READ_CB(_devcb) \
+ downcast<rtl8019a_device &>(*device).set_mem_read_callback(DEVCB_##_devcb);
+
+#define MCFG_RTL8019A_MEM_WRITE_CB(_devcb) \
+ downcast<rtl8019a_device &>(*device).set_mem_write_callback(DEVCB_##_devcb);
+
+
class dp8390_device : public device_t, public device_network_interface
{
public:
- auto irq_callback() { return m_irq_cb.bind(); }
- auto breq_callback() { return m_breq_cb.bind(); }
- auto mem_read_callback() { return m_mem_read_cb.bind(); }
- auto mem_write_callback() { return m_mem_write_cb.bind(); }
+ template <class Object> devcb_base &set_irq_callback(Object &&cb) { return m_irq_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_breq_callback(Object &&cb) { return m_breq_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_mem_read_callback(Object &&cb) { return m_mem_read_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_mem_write_callback(Object &&cb) { return m_mem_write_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_WRITE16_MEMBER( dp8390_w );
DECLARE_READ16_MEMBER( dp8390_r );
diff --git a/src/devices/machine/dp83932c.cpp b/src/devices/machine/dp83932c.cpp
index 82d70f02797..c8c7fcfcd9e 100644
--- a/src/devices/machine/dp83932c.cpp
+++ b/src/devices/machine/dp83932c.cpp
@@ -20,99 +20,112 @@
#define VERBOSE 0
#include "logmacro.h"
-DEFINE_DEVICE_TYPE(DP83932C, dp83932c_device, "dp83932c", "National Semiconductor DP83932C SONIC")
+DEFINE_DEVICE_TYPE(DP83932C_BE, dp83932c_be_device, "dp83932c_be", "National Semiconductor DP83932C SONIC (big)")
+DEFINE_DEVICE_TYPE(DP83932C_LE, dp83932c_le_device, "dp83932c_le", "National Semiconductor DP83932C SONIC (little)")
-dp83932c_device::dp83932c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, DP83932C, tag, owner, clock)
+dp83932c_device::dp83932c_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endian)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_memory_interface(mconfig, *this)
, device_network_interface(mconfig, *this, 10.0f)
- , m_ram(*this, finder_base::DUMMY_TAG)
+ , m_space_config("shared", endian, 32, 32)
, m_out_int(*this)
{
}
+dp83932c_be_device::dp83932c_be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : dp83932c_device(mconfig, DP83932C_BE, tag, owner, clock, ENDIANNESS_BIG)
+{
+}
+
+dp83932c_le_device::dp83932c_le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : dp83932c_device(mconfig, DP83932C_LE, tag, owner, clock, ENDIANNESS_LITTLE)
+{
+}
+
void dp83932c_device::map(address_map &map)
{
- // datasheet uses unshifted register addresses
- int const shift = 1;
-
- // command and status registers
- map(0x00 << shift, (0x00 << shift) | 0x01).rw(FUNC(dp83932c_device::cr_r), FUNC(dp83932c_device::cr_w));
- //map(0x01 << shift, (0x01 << shift) | 0x01).rw(FUNC(dp83932c_device::dcr_r), FUNC(dp83932c_device::dcr_w));
- //map(0x02 << shift, (0x02 << shift) | 0x01).rw(FUNC(dp83932c_device::rcr_r), FUNC(dp83932c_device::rcr_w));
- map(0x03 << shift, (0x03 << shift) | 0x01).rw(FUNC(dp83932c_device::tcr_r), FUNC(dp83932c_device::tcr_w));
- //map(0x04 << shift, (0x04 << shift) | 0x01).rw(FUNC(dp83932c_device::imr_r), FUNC(dp83932c_device::imr_w));
- map(0x05 << shift, (0x05 << shift) | 0x01).rw(FUNC(dp83932c_device::isr_r), FUNC(dp83932c_device::isr_w));
-
- // transmit registers
- map(0x06 << shift, (0x06 << shift) | 0x01).rw(FUNC(dp83932c_device::utda_r), FUNC(dp83932c_device::utda_w));
- //map(0x07 << shift, (0x07 << shift) | 0x01).rw(FUNC(dp83932c_device::ctda_r), FUNC(dp83932c_device::ctda_w));
-
- // tps
- // tfc
- // tsa0
- // tsa1
- // tfs
-
- // receive registers
- //map(0x0d << shift, (0x0d << shift) | 0x01).rw(FUNC(dp83932c_device::urda_r), FUNC(dp83932c_device::urda_w));
- map(0x0e << shift, (0x0e << shift) | 0x01).rw(FUNC(dp83932c_device::crda_r), FUNC(dp83932c_device::crda_w));
-
- // crba0
- // crba1
- // rbwc0
- // rbwc1
- // eobc
- // urra
- // rsa
- // rea
- map(0x17 << shift, (0x17 << shift) | 0x01).rw(FUNC(dp83932c_device::rrp_r), FUNC(dp83932c_device::rrp_w));
- map(0x18 << shift, (0x18 << shift) | 0x01).rw(FUNC(dp83932c_device::rwp_r), FUNC(dp83932c_device::rwp_w));
- // trba0
- // trba1
- // tbwc0
- // tbwc1
- // addr0
- // addr1
- // llfa
- // ttda
- // cep
- // cap2
- // cap1
- // cap0
- map(0x25 << shift, (0x25 << shift) | 0x01).rw(FUNC(dp83932c_device::ce_r), FUNC(dp83932c_device::ce_w));
- // cdp
- // cdc
- // sr
- map(0x29 << shift, (0x29 << shift) | 0x01).rw(FUNC(dp83932c_device::wt0_r), FUNC(dp83932c_device::wt0_w));
- map(0x2a << shift, (0x2a << shift) | 0x01).rw(FUNC(dp83932c_device::wt1_r), FUNC(dp83932c_device::wt1_w));
- map(0x2b << shift, (0x2b << shift) | 0x01).rw(FUNC(dp83932c_device::rsc_r), FUNC(dp83932c_device::rsc_w));
- // crct
- map(0x2d << shift, (0x2d << shift) | 0x01).rw(FUNC(dp83932c_device::faet_r), FUNC(dp83932c_device::faet_w));
- // mpt
- // mdt
-
- // 30-3e internal use registers
- // dcr2
+/*
+ // command and status registers
+ map(0x00, 0x03).rw(FUNC(dp83932c_device::cr_r), FUNC(dp83932c_device::cr_w));
+ map(0x04, 0x07).rw(FUNC(dp83932c_device::dcr_r), FUNC(dp83932c_device::dcr_w));
+ map(0x08, 0x0b).rw(FUNC(dp83932c_device::rcr_r), FUNC(dp83932c_device::rcr_w));
+ map(0x0c, 0x0f).rw(FUNC(dp83932c_device::tcr_r), FUNC(dp83932c_device::tcr_w));
+ map(0x10, 0x13).rw(FUNC(dp83932c_device::imr_r), FUNC(dp83932c_device::imr_w));
+ map(0x14, 0x17).rw(FUNC(dp83932c_device::isr_r), FUNC(dp83932c_device::isr_w));
+
+ // transmit registers
+ map(0x18, 0x1b).rw(FUNC(dp83932c_device::utda_r), FUNC(dp83932c_device::utda_w));
+ map(0x1c, 0x1f).rw(FUNC(dp83932c_device::ctda_r), FUNC(dp83932c_device::ctda_w));
+
+ // tps
+ // tfc
+ // tsa0
+ // tsa1
+ // tfs
+
+ // receive registers
+ map(0x34, 0x37).rw(FUNC(dp83932c_device::urda_r), FUNC(dp83932c_device::urda_w));
+ map(0x38, 0x3b).rw(FUNC(dp83932c_device::crda_r), FUNC(dp83932c_device::crda_w));
+
+ // crba0
+ // crba1
+ // rbwc0
+ // rbwc1
+ // eobc
+ // urra
+ // rsa
+ // rea
+ // rrp
+ // rwp
+ // trba0
+ // trba1
+ // tbwc0
+ // tbwc1
+ // addr0
+ // addr1
+ // llfa
+ // ttda
+ // cep
+ // cap2
+ // cap1
+ // cap0
+ // ce
+ // cdp
+ // cdc
+ // sr
+ // wt0
+ // wt1
+ // rsc
+ // crct
+ // faet
+ // mpt
+ // mdt
+
+ // 30-3e internal use registers
+*/
}
void dp83932c_device::device_start()
{
+ m_space = &space(0);
m_out_int.resolve();
}
void dp83932c_device::device_reset()
{
- m_cr = RST | STP | RXDIS;
- m_tcr = NCRS | PTX;
- m_isr = 0;
- m_ce = 0;
- m_rsc = 0;
}
void dp83932c_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
}
+device_memory_interface::space_config_vector dp83932c_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
void dp83932c_device::send_complete_cb(int result)
{
}
diff --git a/src/devices/machine/dp83932c.h b/src/devices/machine/dp83932c.h
index e608f7508a6..27f5ae60d85 100644
--- a/src/devices/machine/dp83932c.h
+++ b/src/devices/machine/dp83932c.h
@@ -6,113 +6,54 @@
#pragma once
-#include "machine/ram.h"
-
-class dp83932c_device
- : public device_t
- , public device_network_interface
+class dp83932c_device :
+ public device_t,
+ public device_memory_interface,
+ public device_network_interface
{
public:
- dp83932c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- static constexpr feature_type imperfect_features() { return feature::LAN; }
-
- // configuration
- template <typename T> void set_ram(T &&tag) { m_ram.set_tag(std::forward<T>(tag)); }
+ // callback configuration
auto out_int_cb() { return m_out_int.bind(); }
void map(address_map &map);
protected:
+ dp83932c_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endian);
+
// device_t overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ // device_memory_interface overrides
+ virtual space_config_vector memory_space_config() const override;
+
// device_network_interface overrides
virtual void send_complete_cb(int result) override;
virtual int recv_start_cb(u8 *buf, int length) override;
virtual void recv_complete_cb(int result) override;
- enum cr_mask : u16
- {
- HTX = 0x0001, // halt transmission
- TXP = 0x0002, // transmit packets
- RXDIS = 0x0004, // receiver disable
- RXEN = 0x0008, // receiver enable
- STP = 0x0010, // stop timer
- ST = 0x0020, // start timer
- RST = 0x0080, // software reset
- RRRA = 0x0100, // read rra
- LCAM = 0x0200, // load cam
-
- CR_WMASK = 0x03bf
- };
-
- enum tcr_mask : u16
- {
- PTX = 0x0001, // packet transmitted ok
- BCM = 0x0002, // byte count mismatch
- FU = 0x0004, // fifo underrun
- PMB = 0x0008, // packet monitored bad
- OWC = 0x0020, // out of window collision
- EXC = 0x0040, // excessive collisions
- CRSL = 0x0080, // crs lost
- NCRS = 0x0100, // no crs
- DEF = 0x0200, // deferred transmission
- EXD = 0x0400, // excessive deferral
- EXDIS = 0x1000, // disable excessive deferral timer
- CRCI = 0x2000, // crc inhibit
- POWC = 0x4000, // programmed out of window collision timer
- PINT = 0x8000, // programmable interrupt
-
- TCR_WMASK = 0xf000
- };
-
- u16 cr_r() { return m_cr; }
- u16 tcr_r() { return m_tcr; }
- u16 utda_r() { return m_utda; }
- u16 crda_r() { return m_crda; }
- u16 rrp_r() { return m_rrp; }
- u16 rwp_r() { return m_rwp; }
- u16 isr_r() { return m_isr; }
- u16 ce_r() { return m_ce; }
- u16 wt0_r() { return m_wt0; }
- u16 wt1_r() { return m_wt1; }
- u16 rsc_r() { return m_rsc; }
- u16 faet_r() { return m_faet; }
-
- void cr_w(u16 data) { m_cr = (data & CR_WMASK) | (m_cr & ~CR_WMASK); }
- void tcr_w(u16 data) { m_tcr = (data & TCR_WMASK) | (m_tcr & ~TCR_WMASK); }
- void utda_w(u16 data) { m_utda = data; }
- void crda_w(u16 data) { m_crda = data; }
- void rrp_w(u16 data) { m_rrp = data; }
- void rwp_w(u16 data) { m_rwp = data; }
- void isr_w(u16 data) { m_isr = data; }
- void ce_w(u16 data) { m_ce = data; }
- void wt0_w(u16 data) { m_wt0 = data; }
- void wt1_w(u16 data) { m_wt1 = data; }
- void rsc_w(u16 data) { m_rsc = data; }
- void faet_w(u16 data) { m_faet = ~data; }
-
private:
- required_device<ram_device> m_ram;
+ // device_memory_interface members
+ const address_space_config m_space_config;
+ address_space *m_space;
devcb_write_line m_out_int;
+};
+
+class dp83932c_be_device : public dp83932c_device
+{
+public:
+ dp83932c_be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
- u16 m_cr;
- u16 m_tcr;
- u16 m_utda;
- u16 m_crda;
- u16 m_rrp;
- u16 m_rwp;
- u16 m_isr;
- u16 m_ce;
- u16 m_wt0;
- u16 m_wt1;
- u16 m_rsc;
- u16 m_faet;
+class dp83932c_le_device : public dp83932c_device
+{
+public:
+ dp83932c_le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
-DECLARE_DEVICE_TYPE(DP83932C, dp83932c_device)
+DECLARE_DEVICE_TYPE(DP83932C_BE, dp83932c_be_device)
+DECLARE_DEVICE_TYPE(DP83932C_LE, dp83932c_le_device)
#endif // MAME_MACHINE_DP83932C_H
diff --git a/src/devices/machine/ds1204.h b/src/devices/machine/ds1204.h
index 59dc5718989..12bc61657e4 100644
--- a/src/devices/machine/ds1204.h
+++ b/src/devices/machine/ds1204.h
@@ -13,6 +13,9 @@
#pragma once
+#define MCFG_DS1204_ADD( _tag ) \
+ MCFG_DEVICE_ADD( _tag, DS1204, 0 )
+
class ds1204_device : public device_t, public device_nvram_interface
{
public:
diff --git a/src/devices/machine/ds1205.h b/src/devices/machine/ds1205.h
index ad7432e1ac7..7f854d901fc 100644
--- a/src/devices/machine/ds1205.h
+++ b/src/devices/machine/ds1205.h
@@ -13,6 +13,9 @@
#pragma once
+#define MCFG_DS1205_ADD( _tag ) \
+ MCFG_DEVICE_ADD( _tag, DS1205, 0 )
+
class ds1205_device : public device_t, public device_nvram_interface
{
public:
diff --git a/src/devices/machine/ds128x.cpp b/src/devices/machine/ds128x.cpp
index 91e022e07e7..7a397aab303 100644
--- a/src/devices/machine/ds128x.cpp
+++ b/src/devices/machine/ds128x.cpp
@@ -10,12 +10,7 @@ DEFINE_DEVICE_TYPE(DS12885, ds12885_device, "ds12885", "DS12885 RTC/NVRAM")
//-------------------------------------------------
ds12885_device::ds12885_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : ds12885_device(mconfig, DS12885, tag, owner, clock)
-{
-}
-
-ds12885_device::ds12885_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : mc146818_device(mconfig, type, tag, owner, clock)
+ : mc146818_device(mconfig, DS12885, tag, owner, clock)
{
}
@@ -28,54 +23,3 @@ int ds12885_device::get_timer_bypass()
return 22; // No tick
}
-
-DEFINE_DEVICE_TYPE(DS12885EXT, ds12885ext_device, "ds12885ext", "DS12885 RTC/NVRAM size 256 bytes")
-
-//-------------------------------------------------
-// ds12885ext_device - constructor
-//-------------------------------------------------
-
-ds12885ext_device::ds12885ext_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : ds12885_device(mconfig, DS12885EXT, tag, owner, clock)
-{
-}
-
-//-------------------------------------------------
-// ds12885ext_device - handlers that allow acces to extended memory size
-//-------------------------------------------------
-
-uint8_t ds12885ext_device::read_extended(offs_t offset)
-{
- switch (offset)
- {
- case 0:
- case 1:
- return read(offset);
- break;
- case 2:
- case 3:
- return read(offset - 2);
- break;
- default:
- return 0xff;
- }
-}
-
-void ds12885ext_device::write_extended(offs_t offset, uint8_t data)
-{
- switch (offset)
- {
- case 0:
- write(offset, data & 127);
- break;
- case 1:
- write(offset, data);
- break;
- case 2:
- write(offset - 2, data);
- break;
- case 3:
- write(offset - 2, data);
- break;
- }
-}
diff --git a/src/devices/machine/ds128x.h b/src/devices/machine/ds128x.h
index 7ade1bfa431..671d3ee0a6f 100644
--- a/src/devices/machine/ds128x.h
+++ b/src/devices/machine/ds128x.h
@@ -5,8 +5,10 @@
#include "mc146818.h"
+#define MCFG_DS12885_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, DS12885, XTAL(32'768))
-// ======================> ds12885_device
+// ======================> mc146818_device
class ds12885_device : public mc146818_device
{
@@ -15,8 +17,6 @@ public:
ds12885_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 32'768);
protected:
- ds12885_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
virtual int data_size() override { return 128; }
virtual int get_timer_bypass() override;
};
@@ -24,23 +24,4 @@ protected:
// device type definition
DECLARE_DEVICE_TYPE(DS12885, ds12885_device)
-// ======================> ds12885ext_device
-
-class ds12885ext_device : public ds12885_device
-{
-public:
- // construction/destruction
- ds12885ext_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 32'768);
-
- // read/write access to extended ram
- uint8_t read_extended(offs_t offset);
- void write_extended(offs_t offset, uint8_t data);
-
-protected:
- virtual int data_size() override { return 256; }
-};
-
-// device type definition
-DECLARE_DEVICE_TYPE(DS12885EXT, ds12885ext_device)
-
#endif // MAME_MACHINE_DS128X_H
diff --git a/src/devices/machine/ds1315.cpp b/src/devices/machine/ds1315.cpp
index 2a574dca399..6b37957f9eb 100644
--- a/src/devices/machine/ds1315.cpp
+++ b/src/devices/machine/ds1315.cpp
@@ -87,17 +87,17 @@ static const uint8_t ds1315_pattern[] =
***************************************************************************/
// automated read, does all the work the real Dallas chip does
-uint8_t ds1315_device::read(offs_t offset)
+READ8_MEMBER( ds1315_device::read )
{
if (m_mode == DS_SEEK_MATCHING)
{
if (offset & 1)
{
- read_1();
+ read_1(space, 0);
}
else
{
- read_0();
+ read_0(space, 0);
}
if (offset & 4)
@@ -110,7 +110,7 @@ uint8_t ds1315_device::read(offs_t offset)
}
else if (m_mode == DS_CALENDAR_IO)
{
- return read_data();
+ return read_data(space, offset);
}
return 0xff; // shouldn't happen, but compilers don't know that
@@ -121,7 +121,7 @@ uint8_t ds1315_device::read(offs_t offset)
read_0 (actual data)
-------------------------------------------------*/
-uint8_t ds1315_device::read_0()
+READ8_MEMBER( ds1315_device::read_0 )
{
if (ds1315_pattern[m_count++] == 0)
{
@@ -145,7 +145,7 @@ uint8_t ds1315_device::read_0()
read_1 (actual data)
-------------------------------------------------*/
-uint8_t ds1315_device::read_1()
+READ8_MEMBER( ds1315_device::read_1 )
{
if (ds1315_pattern[m_count++] == 1)
{
@@ -163,7 +163,7 @@ uint8_t ds1315_device::read_1()
read_data
-------------------------------------------------*/
-uint8_t ds1315_device::read_data()
+READ8_MEMBER( ds1315_device::read_data )
{
uint8_t result;
@@ -228,7 +228,7 @@ void ds1315_device::fill_raw_data()
write_data
-------------------------------------------------*/
-uint8_t ds1315_device::write_data(offs_t offset)
+READ8_MEMBER(ds1315_device::write_data)
{
static int write_count;
if (write_count >= 64)
diff --git a/src/devices/machine/ds1315.h b/src/devices/machine/ds1315.h
index 720c4a08202..a5b70c38c76 100644
--- a/src/devices/machine/ds1315.h
+++ b/src/devices/machine/ds1315.h
@@ -24,12 +24,12 @@ public:
auto read_backing() { return m_backing_read.bind(); }
// this handler automates the bits 0/2 stuff
- uint8_t read(offs_t offset);
+ DECLARE_READ8_MEMBER(read);
- uint8_t read_0();
- uint8_t read_1();
- uint8_t read_data();
- uint8_t write_data(offs_t offset);
+ DECLARE_READ8_MEMBER(read_0);
+ DECLARE_READ8_MEMBER(read_1);
+ DECLARE_READ8_MEMBER(read_data);
+ DECLARE_READ8_MEMBER(write_data);
bool chip_enable();
void chip_reset();
diff --git a/src/devices/machine/ds75160a.h b/src/devices/machine/ds75160a.h
index bdc03e9dc99..2f2a2147a5e 100644
--- a/src/devices/machine/ds75160a.h
+++ b/src/devices/machine/ds75160a.h
@@ -25,6 +25,18 @@
#pragma once
+
+
+///*************************************************************************
+// INTERFACE CONFIGURATION MACROS
+///*************************************************************************
+
+#define MCFG_DS75160A_ADD(_tag, _read, _write) \
+ MCFG_DEVICE_ADD(_tag, DS75160A, 0) \
+ downcast<ds75160a_device *>(device)->set_callbacks(DEVCB_##_read, DEVCB_##_write);
+
+
+
///*************************************************************************
// TYPE DEFINITIONS
///*************************************************************************
diff --git a/src/devices/machine/f3853.cpp b/src/devices/machine/f3853.cpp
index 45511f334ab..f4713f3fa3a 100644
--- a/src/devices/machine/f3853.cpp
+++ b/src/devices/machine/f3853.cpp
@@ -1,29 +1,19 @@
// license:BSD-3-Clause
-// copyright-holders:Wilbert Pol, hap
+// copyright-holders:Wilbert Pol
/**********************************************************************
-Fairchild F3853 SMI, F3851 PSU, F3856 PSU, F38T56 PSU
+ Fairchild F3853 SRAM interface with integrated interrupt
+ controller and timer (SMI)
-This device only emulates the I/O, interrupt, timer functions. Not the
-low-level ROMC signals.
+ This chip is a timer shift register, basically the same as in the
+ F3851.
-F3853: Static memory interface with integrated interrupt controller and timer.
+ Based on a datasheet obtained from www.freetradezone.com
-The timer is an 8-bit linear feedback shift register:
-Feedback in0 = !((out3 ^ out4) ^ (out5 ^ out7))
-Interrupts are at 0xfe
-0xff stops the register (0xfe is never reached)
-
-F3851: Program Storage Unit, same timer and interrupt controller as F3853,
-but has 2 I/O ports instead of a programmable interrupt vector.
-
-F3856/F38T56 Program Storage Unit: similar interrupt controller, timer
-is more versatile, a simple downcounter instead of shift register.
-
-TODO:
-- emulate at lower level and place this stuff into devices/cpu/f8 folder
-- interrupt priority pin
-- 3856/38T56 timer pulse counter mode, event counter mode
+ 8-bit shift register:
+ Feedback in0 = !((out3 ^ out4) ^ (out5 ^ out7))
+ Interrupts are at 0xfe
+ 0xff stops the register (0xfe is never reached)
**********************************************************************/
@@ -31,60 +21,31 @@ TODO:
#include "f3853.h"
-// device type definition
-
-DEFINE_DEVICE_TYPE(F3853, f3853_device, "f3853_smi", "Fairchild F3853 SMI")
-DEFINE_DEVICE_TYPE(F3851, f3851_device, "f3851_psu", "Fairchild F3851 PSU")
-DEFINE_DEVICE_TYPE(F3856, f3856_device, "f3856_psu", "Fairchild F3856 PSU")
-DEFINE_DEVICE_TYPE(F38T56, f38t56_device, "f38t56_psu", "Fairchild F38T56 PSU")
-
-
-//-------------------------------------------------
-// constructor
-//-------------------------------------------------
-
-f3853_device::f3853_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
- device_t(mconfig, type, tag, owner, clock),
- m_int_req_callback(*this),
- m_pri_out_callback(*this),
- m_int_vector(0),
- m_prescaler(31),
- m_priority_line(false),
- m_external_interrupt_line(true)
-{ }
-
-f3853_device::f3853_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- f3853_device(mconfig, F3853, tag, owner, clock)
-{ }
-
-f3851_device::f3851_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
- f3853_device(mconfig, type, tag, owner, clock),
- m_read_port{{*this}, {*this}},
- m_write_port{{*this}, {*this}}
-{ }
-
-f3851_device::f3851_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- f3851_device(mconfig, F3851, tag, owner, clock)
-{ }
-
-f3856_device::f3856_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
- f3851_device(mconfig, type, tag, owner, clock)
-{ }
-
-f3856_device::f3856_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- f3856_device(mconfig, F3856, tag, owner, clock)
-{ }
-f38t56_device::f38t56_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- f3856_device(mconfig, F38T56, tag, owner, clock)
-{ }
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+// device type definition
+DEFINE_DEVICE_TYPE(F3853, f3853_device, "f3853_device", "F3853 SMI")
//-------------------------------------------------
-// initialisation
+// f3853_device - constructor
//-------------------------------------------------
+f3853_device::f3853_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, F3853, tag, owner, clock)
+ , m_int_req_callback(*this)
+ , m_pri_out_callback(*this)
+ , m_priority_line(false)
+ , m_external_interrupt_line(true)
+{
+}
+
void f3853_device::device_resolve_objects()
{
m_int_req_callback.resolve_safe();
@@ -92,20 +53,12 @@ void f3853_device::device_resolve_objects()
m_int_daisy_chain_callback.bind_relative_to(*owner());
}
-void f3851_device::device_resolve_objects()
-{
- f3853_device::device_resolve_objects();
-
- // 2 I/O ports
- for (devcb_read8 &cb : m_read_port)
- cb.resolve_safe(0);
- for (devcb_write8 &cb : m_write_port)
- cb.resolve_safe();
-}
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
void f3853_device::device_start()
{
- // lookup table for 3851/3853 lfsr timer
uint8_t reg = 0xfe; // Known to get 0xfe after 255 cycles
for(int i = reg; i >= 0; i--)
{
@@ -115,62 +68,47 @@ void f3853_device::device_start()
m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(f3853_device::timer_callback),this));
- // zerofill (what's not in constructor)
- m_external_int_enable = false;
- m_timer_int_enable = false;
- m_request_flipflop = false;
-
- // register for savestates
save_item(NAME(m_int_vector));
- save_item(NAME(m_prescaler));
- save_item(NAME(m_external_int_enable));
- save_item(NAME(m_timer_int_enable));
+ save_item(NAME(m_external_enable));
+ save_item(NAME(m_timer_enable));
save_item(NAME(m_request_flipflop));
save_item(NAME(m_priority_line));
save_item(NAME(m_external_interrupt_line));
}
-void f3856_device::device_start()
-{
- f3853_device::device_start();
- m_timer_count = 0;
- m_timer_modulo = 0;
- m_timer_start = false;
-
- save_item(NAME(m_timer_count));
- save_item(NAME(m_timer_modulo));
- save_item(NAME(m_timer_start));
-}
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
void f3853_device::device_reset()
{
- // note that standalone peripherals don't have a reset pin, but 3870 does
+ m_int_vector = 0;
+ m_external_enable = false;
+ m_timer_enable = false;
+ m_request_flipflop = false;
+ m_external_interrupt_line = true;
+ set_interrupt_request_line();
- // clear ports at power-on
- for (int i = 0; i < 4; i++)
- write(machine().dummy_space(), i, 0);
+ m_timer->enable(false);
}
-//-------------------------------------------------
-// implementation
-//-------------------------------------------------
-
void f3853_device::set_interrupt_request_line()
{
m_int_req_callback(m_request_flipflop && !m_priority_line ? ASSERT_LINE : CLEAR_LINE);
}
+
IRQ_CALLBACK_MEMBER(f3853_device::int_acknowledge)
{
- if (m_external_int_enable && !m_priority_line && m_request_flipflop)
+ if (m_external_enable && !m_priority_line && m_request_flipflop)
{
m_request_flipflop = false;
set_interrupt_request_line();
return external_interrupt_vector();
}
- else if (m_timer_int_enable && !m_priority_line && m_request_flipflop)
+ else if (m_timer_enable && !m_priority_line && m_request_flipflop)
{
m_request_flipflop = false;
set_interrupt_request_line();
@@ -189,14 +127,14 @@ IRQ_CALLBACK_MEMBER(f3853_device::int_acknowledge)
void f3853_device::timer_start(uint8_t value)
{
- attotime period = (value != 0xff) ? attotime::from_hz(clock()) * (m_value_to_cycle[value] * m_prescaler) : attotime::never;
+ attotime period = (value != 0xff) ? attotime::from_hz(clock()) * (m_value_to_cycle[value]*31) : attotime::never;
m_timer->adjust(period);
}
TIMER_CALLBACK_MEMBER(f3853_device::timer_callback)
{
- if(m_timer_int_enable)
+ if(m_timer_enable)
{
m_request_flipflop = true;
set_interrupt_request_line();
@@ -204,10 +142,9 @@ TIMER_CALLBACK_MEMBER(f3853_device::timer_callback)
timer_start(0xfe);
}
-
WRITE_LINE_MEMBER(f3853_device::ext_int_w)
{
- if(m_external_interrupt_line && !state && m_external_int_enable)
+ if(m_external_interrupt_line && !state && m_external_enable)
{
m_request_flipflop = true;
}
@@ -224,201 +161,49 @@ WRITE_LINE_MEMBER(f3853_device::pri_in_w)
READ8_MEMBER(f3853_device::read)
{
- switch (offset & 3)
+ uint8_t data = 0;
+
+ switch (offset)
{
- // interrupt vector
case 0:
- return m_int_vector >> 8;
+ data = m_int_vector >> 8;
+ break;
+
case 1:
- return m_int_vector & 0xff;
+ data = m_int_vector & 0xff;
+ break;
- // interrupt control, timer: write-only
- default:
- return 0;
+ case 2: // Interrupt control; not readable
+ case 3: // Timer; not readable
+ break;
}
+
+ return data;
}
+
WRITE8_MEMBER(f3853_device::write)
{
- switch (offset & 3)
+ switch(offset)
{
- // interrupt vector
case 0:
m_int_vector = (data << 8) | (m_int_vector & 0x00ff);
break;
+
case 1:
m_int_vector = data | (m_int_vector & 0xff00);
break;
- // interrupt control
- case 2:
- m_external_int_enable = (data & 3) == 1;
- m_timer_int_enable = (data & 3) == 3;
+ case 2: //interrupt control
+ m_external_enable = ((data & 3) == 1);
+ m_timer_enable = ((data & 3) == 3);
set_interrupt_request_line();
break;
- // set timer
- case 3:
+ case 3: //timer
m_request_flipflop = false;
set_interrupt_request_line();
timer_start(data);
break;
}
}
-
-
-//-------------------------------------------------
-// f3851_device-specific handlers
-//-------------------------------------------------
-
-READ8_MEMBER(f3851_device::read)
-{
- switch (offset & 3)
- {
- // I/O ports
- case 0: case 1:
- return (m_read_port[offset & 1])(offs_t(offset & 1));
-
- // interrupt control, timer: write-only
- default:
- return 0;
- }
-}
-
-WRITE8_MEMBER(f3851_device::write)
-{
- switch (offset & 3)
- {
- // I/O ports
- case 0: case 1:
- (m_write_port[offset & 1])(offs_t(offset & 1), data);
- break;
-
- // interrupt control, timer: same as 3853
- case 2: case 3:
- f3853_device::write(space, offset, data);
- break;
- }
-}
-
-
-//-------------------------------------------------
-// f3856_device-specific handlers
-//-------------------------------------------------
-
-void f3856_device::timer_start(uint8_t value)
-{
- m_timer_count = value;
- attotime period = (m_timer_start) ? (attotime::from_hz(clock()) * m_prescaler) : attotime::never;
-
- m_timer->adjust(period);
-}
-
-TIMER_CALLBACK_MEMBER(f3856_device::timer_callback)
-{
- if (--m_timer_count == 0)
- {
- m_timer_count = m_timer_modulo;
- if (m_timer_int_enable)
- {
- m_request_flipflop = true;
- set_interrupt_request_line();
- }
- }
-
- timer_start(m_timer_count);
-}
-
-READ8_MEMBER(f3856_device::read)
-{
- switch (offset & 3)
- {
- // timer: active counter
- case 3:
- return m_timer_count;
-
- // other: same as 3851
- default:
- return f3851_device::read(space, offset);
- }
-}
-
-WRITE8_MEMBER(f3856_device::write)
-{
- switch (offset & 3)
- {
- // I/O ports: same as 3851
- case 0: case 1:
- f3851_device::write(space, offset, data);
- break;
-
- // interrupt/timer control
- case 2:
- {
- // timer prescaler
- static const u8 prescaler[8] = { 32, 128, 8, 2 };
- m_prescaler = prescaler[data >> 5 & 7];
-
- // start/stop timer
- bool prev = m_timer_start;
- m_timer_start = bool(~data & 0x10);
- if (m_timer_start != prev)
- timer_start(m_timer_count);
-
- // enable interrupts
- m_external_int_enable = (data & 3) == 1 || (data & 3) == 2;
- m_timer_int_enable = bool(data & 2);
- set_interrupt_request_line();
- break;
- }
-
- // set timer
- case 3:
- f3853_device::write(space, offset, data);
- break;
- }
-}
-
-
-//-------------------------------------------------
-// f38t56_device-specific handlers
-//-------------------------------------------------
-
-WRITE8_MEMBER(f38t56_device::write)
-{
- switch (offset & 3)
- {
- // I/O ports: same as 3851
- case 0: case 1:
- f3851_device::write(space, offset, data);
- break;
-
- // interrupt/timer control
- case 2:
- {
- // timer prescaler
- m_prescaler = 200;
- if (~data & 0x80) m_prescaler /= 20;
- if (~data & 0x40) m_prescaler /= 5;
- if (~data & 0x20) m_prescaler /= 2;
-
- // start/stop timer
- bool prev = m_timer_start;
- m_timer_start = bool(data & 8);
- if (m_timer_start != prev)
- timer_start(m_timer_count);
-
- // enable interrupts
- m_external_int_enable = bool(data & 1);
- m_timer_int_enable = bool(data & 2);
- set_interrupt_request_line();
- break;
- }
-
- // set timer
- case 3:
- m_timer_modulo = data;
- f3853_device::write(space, offset, data);
- break;
- }
-}
diff --git a/src/devices/machine/f3853.h b/src/devices/machine/f3853.h
index 762f46950fb..14c922871b1 100644
--- a/src/devices/machine/f3853.h
+++ b/src/devices/machine/f3853.h
@@ -1,67 +1,49 @@
// license:BSD-3-Clause
-// copyright-holders:Wilbert Pol, hap
-/*
-
- Fairchild F3853 SMI, F3851 PSU, F3856 PSU, F38T56 PSU
-
-*/
+// copyright-holders:Wilbert Pol
+/***************************************************************************
+
+ Fairchild F3853 SRAM interface with integrated interrupt
+ controller and timer
+
+ This chip is a timer shift register, basically the same as in the
+ F3851.
+
+****************************************************************************
+ _____ _____
+ Vgg 1 |* \_/ | 40 Vdd
+ PHI 2 | | 39 ROMC4
+ WRITE 3 | | 38 ROMC3
+ _INT REQ 4 | | 37 ROMC2
+ _PRI IN 5 | | 36 ROMC1
+ _RAM WRITE 6 | | 35 ROMC0
+ _EXT INT 7 | | 34 CPU READ
+ ADDR7 8 | | 33 REG DR
+ ADDR6 9 | | 32 ADDR15
+ ADDR5 10 | F3853 | 31 ADDR14
+ ADDR4 11 | | 30 ADDR13
+ ADDR3 12 | | 29 ADDR12
+ ADDR2 13 | | 28 ADDR11
+ ADDR1 14 | | 27 ADDR10
+ ADDR0 15 | | 26 ADDR9
+ DB0 16 | | 25 ADDR8
+ DB1 17 | | 24 DB7
+ DB2 18 | | 23 DB6
+ DB3 19 | | 22 DB5
+ Vss 20 |_____________| 21 DB4
+
+***************************************************************************/
#ifndef MAME_MACHINE_F3853_H
#define MAME_MACHINE_F3853_H
#pragma once
-// pinout reference
-
-/*
- _____ _____
- Vgg 1 |* \_/ | 40 Vdd
- PHI 2 | | 39 ROMC4
- WRITE 3 | | 38 ROMC3
- _INT REQ 4 | | 37 ROMC2
- _PRI IN 5 | | 36 ROMC1
- _RAM WRITE 6 | | 35 ROMC0
- _EXT INT 7 | | 34 CPU READ
- ADDR7 8 | | 33 REG DR
- ADDR6 9 | | 32 ADDR15
- ADDR5 10 | F3853 | 31 ADDR14
- ADDR4 11 | | 30 ADDR13
- ADDR3 12 | | 29 ADDR12
- ADDR2 13 | | 28 ADDR11
- ADDR1 14 | | 27 ADDR10
- ADDR0 15 | | 26 ADDR9
- DB0 16 | | 25 ADDR8
- DB1 17 | | 24 DB7
- DB2 18 | | 23 DB6
- DB3 19 | | 22 DB5
- Vss 20 |_____________| 21 DB4
-
- _____ _____
- _I/O B7 1 |* \_/ | 40 DB7
- _I/O A7 2 | | 39 DB6
- Vgg 3 | | 38 _I/O B6
- Vdd 4 | | 37 _I/O A6
- _EXT INT 5 | | 36 _I/O A5
- _PRI OUT 6 | | 35 _I/O B5
- WRITE 7 | | 34 DB5
- PHI 8 | | 33 DB4
- _INT REQ 9 | F3851 | 32 _I/O B4
- _PRI IN 10 | F3856 | 31 _I/O A4
- _DBDR 11 | F38T56 | 30 _I/O A3
- STROBE 12 | | 29 _I/O B3
- ROMC4 13 | | 28 DB3
- ROMC3 14 | | 27 DB2
- ROMC2 15 | | 26 _I/O B2
- ROMC1 16 | | 25 _I/O A2
- ROMC0 17 | | 24 _I/O A1
- Vss 18 | | 23 _I/O B1
- _I/O A0 19 | | 22 DB1
- _I/O B0 20 |_____________| 21 DB0
-
- F38T56 is internal in F3870
- note: STROBE is N/C on F3851
-*/
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+// ======================> f3853_device
class f3853_device : public device_t
{
@@ -73,38 +55,36 @@ public:
auto pri_out_callback() { return m_pri_out_callback.bind(); }
template<typename Object> void set_int_daisy_chain_callback(Object &&cb) { m_int_daisy_chain_callback = std::forward<Object>(cb); }
- virtual DECLARE_READ8_MEMBER(read);
- virtual DECLARE_WRITE8_MEMBER(write);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
DECLARE_WRITE_LINE_MEMBER(ext_int_w);
DECLARE_WRITE_LINE_MEMBER(pri_in_w);
- virtual TIMER_CALLBACK_MEMBER(timer_callback);
+ TIMER_CALLBACK_MEMBER(timer_callback);
IRQ_CALLBACK_MEMBER(int_acknowledge);
protected:
- f3853_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_reset() override;
+private:
uint16_t timer_interrupt_vector() const { return m_int_vector & ~uint16_t(0x0080); }
uint16_t external_interrupt_vector() const { return m_int_vector | uint16_t(0x0080); }
void set_interrupt_request_line();
- virtual void timer_start(uint8_t value);
+ void timer_start(uint8_t value);
devcb_write_line m_int_req_callback;
devcb_write_line m_pri_out_callback;
device_irq_acknowledge_delegate m_int_daisy_chain_callback;
uint16_t m_int_vector; // Bit 7 is set to 0 for timer interrupts, 1 for external interrupts
- u8 m_prescaler;
- bool m_external_int_enable;
- bool m_timer_int_enable;
+ bool m_external_enable;
+ bool m_timer_enable;
bool m_request_flipflop;
@@ -116,66 +96,8 @@ protected:
uint8_t m_value_to_cycle[0x100];
};
-class f3851_device : public f3853_device
-{
-public:
- f3851_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- // interrupt vector is a mask option on 3851 and 3856
- void set_int_vector(u16 vector) { m_int_vector = vector; }
-
- // bidirectional I/O ports A and B
- auto read_a() { return m_read_port[0].bind(); }
- auto read_b() { return m_read_port[1].bind(); }
- auto write_a() { return m_write_port[0].bind(); }
- auto write_b() { return m_write_port[1].bind(); }
-
- virtual DECLARE_READ8_MEMBER(read) override;
- virtual DECLARE_WRITE8_MEMBER(write) override;
-
-protected:
- f3851_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void device_resolve_objects() override;
-
- devcb_read8 m_read_port[2];
- devcb_write8 m_write_port[2];
-};
-
-class f3856_device : public f3851_device
-{
-public:
- f3856_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- virtual DECLARE_READ8_MEMBER(read) override;
- virtual DECLARE_WRITE8_MEMBER(write) override;
-
- virtual TIMER_CALLBACK_MEMBER(timer_callback) override;
-
-protected:
- f3856_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void device_start() override;
-
- virtual void timer_start(uint8_t value) override;
-
- u8 m_timer_count;
- u8 m_timer_modulo;
- bool m_timer_start;
-};
-
-class f38t56_device : public f3856_device
-{
-public:
- f38t56_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- virtual DECLARE_WRITE8_MEMBER(write) override;
-};
// device type definition
DECLARE_DEVICE_TYPE(F3853, f3853_device)
-DECLARE_DEVICE_TYPE(F3851, f3851_device)
-DECLARE_DEVICE_TYPE(F3856, f3856_device)
-DECLARE_DEVICE_TYPE(F38T56, f38t56_device)
#endif // MAME_MACHINE_F3853_H
diff --git a/src/devices/machine/fdc37c665gt.cpp b/src/devices/machine/fdc37c665gt.cpp
index f2df880d2e8..4c6f23651db 100644
--- a/src/devices/machine/fdc37c665gt.cpp
+++ b/src/devices/machine/fdc37c665gt.cpp
@@ -49,10 +49,9 @@ void fdc37c665gt_device::device_start()
{
}
-void fdc37c665gt_device::device_add_mconfig(machine_config &config)
-{
- NS16550(config, m_uart1, XTAL(24'000'000)/13);
- NS16550(config, m_uart2, XTAL(24'000'000)/13);
-}
+MACHINE_CONFIG_START(fdc37c665gt_device::device_add_mconfig)
+ MCFG_DEVICE_ADD("uart1", NS16550, XTAL(24'000'000)/13)
+ MCFG_DEVICE_ADD("uart2", NS16550, XTAL(24'000'000)/13)
+MACHINE_CONFIG_END
DEFINE_DEVICE_TYPE(FDC37C665GT, fdc37c665gt_device, "fdc37c665gt", "FDC37C665GT")
diff --git a/src/devices/machine/fdc37c93x.cpp b/src/devices/machine/fdc37c93x.cpp
index 8ff5afc76d4..05c87fd38ef 100644
--- a/src/devices/machine/fdc37c93x.cpp
+++ b/src/devices/machine/fdc37c93x.cpp
@@ -639,12 +639,12 @@ void fdc37c93x_device::map_rtc(address_map &map)
READ8_MEMBER(fdc37c93x_device::rtc_read)
{
- return ds12885_rtcdev->read(offset);
+ return ds12885_rtcdev->read(space, offset, mem_mask);
}
WRITE8_MEMBER(fdc37c93x_device::rtc_write)
{
- ds12885_rtcdev->write(offset, data);
+ ds12885_rtcdev->write(space, offset, data, mem_mask);
}
void fdc37c93x_device::map_rtc_addresses()
diff --git a/src/devices/machine/gen_fifo.h b/src/devices/machine/gen_fifo.h
index 0ef98fb20c3..4db8a75d8c1 100644
--- a/src/devices/machine/gen_fifo.h
+++ b/src/devices/machine/gen_fifo.h
@@ -72,6 +72,13 @@
*/
+#define MCFG_GENERIC_FIFO_EMPTY_CALLBACK(_devcb) \
+ downcast<screen_device &>(*device).set_empty_cb(DEVCB_##_devcb);
+
+#define MCFG_GENERIC_FIFO_FULL_CALLBACK(_devcb) \
+ downcast<screen_device &>(*device).set_full_cb(DEVCB_##_devcb);
+
+
template<typename T> class generic_fifo_device_base : public device_t {
public:
/* The general setup. Call be called multiple times, clears the fifo. */
@@ -111,8 +118,8 @@ public:
void clear();
/* Callbacks signalling empty (true)/nonempty (false) and full (true)/nonfull (false) */
- auto empty_cb() { return m_empty_cb.bind(); }
- auto full_cb() { return m_full_cb.bind(); }
+ template<class Object> devcb_base &set_empty_cb(Object &&object) { return m_empty_cb.set_callback(std::forward<Object>(object)); }
+ template<class Object> devcb_base &set_full_cb(Object &&object) { return m_full_cb.set_callback(std::forward<Object>(object)); }
/* Get the fifo current size - Note that real hardware usually
can't do that. May be bigger that the fifo size if some extra
diff --git a/src/devices/machine/genpc.cpp b/src/devices/machine/genpc.cpp
index e626bf96b30..269c1915bb0 100644
--- a/src/devices/machine/genpc.cpp
+++ b/src/devices/machine/genpc.cpp
@@ -135,8 +135,6 @@ WRITE_LINE_MEMBER( ibm5160_mb_device::pc_dma8237_out_eop )
void ibm5160_mb_device::pc_select_dma_channel(int channel, bool state)
{
- m_isabus->dack_line_w(channel, state);
-
if(!state) {
m_dma_channel = channel;
if(m_cur_eop)
@@ -395,16 +393,8 @@ WRITE8_MEMBER( ibm5160_mb_device::pc_ppi_portb_w )
WRITE8_MEMBER( ibm5160_mb_device::nmi_enable_w )
{
m_nmi_enabled = BIT(data,7);
- if (!m_nmi_enabled)
- m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
-}
-
-WRITE_LINE_MEMBER( ibm5160_mb_device::iochck_w )
-{
- if (m_nmi_enabled && !state)
- m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
+ m_isabus->set_nmi_state(m_nmi_enabled);
}
-
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@@ -420,9 +410,8 @@ DEFINE_DEVICE_TYPE(IBM5160_MOTHERBOARD, ibm5160_mb_device, "ibm5160_mb", "IBM 51
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void ibm5160_mb_device::device_add_mconfig(machine_config &config)
-{
- PIT8253(config, m_pit8253);
+MACHINE_CONFIG_START(ibm5160_mb_device::device_add_mconfig)
+ PIT8253(config, m_pit8253, 0);
m_pit8253->set_clk<0>(XTAL(14'318'181)/12.0); // heartbeat IRQ
m_pit8253->out_handler<0>().set(m_pic8259, FUNC(pic8259_device::ir0_w));
m_pit8253->set_clk<1>(XTAL(14'318'181)/12.0); // DRAM refresh
@@ -447,7 +436,7 @@ void ibm5160_mb_device::device_add_mconfig(machine_config &config)
m_dma8237->out_dack_callback<2>().set(FUNC(ibm5160_mb_device::pc_dack2_w));
m_dma8237->out_dack_callback<3>().set(FUNC(ibm5160_mb_device::pc_dack3_w));
- PIC8259(config, m_pic8259);
+ PIC8259(config, m_pic8259, 0);
m_pic8259->out_int_callback().set(FUNC(ibm5160_mb_device::pic_int_w));
I8255A(config, m_ppi8255, 0);
@@ -456,8 +445,7 @@ void ibm5160_mb_device::device_add_mconfig(machine_config &config)
m_ppi8255->in_pc_callback().set(FUNC(ibm5160_mb_device::pc_ppi_portc_r));
ISA8(config, m_isabus, 0);
- m_isabus->set_memspace(":maincpu", AS_PROGRAM);
- m_isabus->set_iospace(":maincpu", AS_IO);
+ m_isabus->set_cputag(":maincpu");
m_isabus->irq2_callback().set(m_pic8259, FUNC(pic8259_device::ir2_w));
m_isabus->irq3_callback().set(m_pic8259, FUNC(pic8259_device::ir3_w));
m_isabus->irq4_callback().set(m_pic8259, FUNC(pic8259_device::ir4_w));
@@ -467,16 +455,15 @@ void ibm5160_mb_device::device_add_mconfig(machine_config &config)
m_isabus->drq1_callback().set(m_dma8237, FUNC(am9517a_device::dreq1_w));
m_isabus->drq2_callback().set(m_dma8237, FUNC(am9517a_device::dreq2_w));
m_isabus->drq3_callback().set(m_dma8237, FUNC(am9517a_device::dreq3_w));
- m_isabus->iochck_callback().set(FUNC(ibm5160_mb_device::iochck_w));
- PC_KBDC(config, m_pc_kbdc, 0);
- m_pc_kbdc->out_clock_cb().set(FUNC(ibm5160_mb_device::keyboard_clock_w));
- m_pc_kbdc->out_data_cb().set(FUNC(ibm5160_mb_device::keyboard_data_w));
+ MCFG_DEVICE_ADD("pc_kbdc", PC_KBDC, 0)
+ MCFG_PC_KBDC_OUT_CLOCK_CB(WRITELINE(*this, ibm5160_mb_device, keyboard_clock_w))
+ MCFG_PC_KBDC_OUT_DATA_CB(WRITELINE(*this, ibm5160_mb_device, keyboard_data_w))
/* sound hardware */
SPEAKER(config, "mono").front_center();
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 1.00);
-}
+MACHINE_CONFIG_END
static INPUT_PORTS_START( ibm5160_mb )
@@ -608,18 +595,18 @@ DEFINE_DEVICE_TYPE(IBM5150_MOTHERBOARD, ibm5150_mb_device, "ibm5150_mb", "IBM 51
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void ibm5150_mb_device::device_add_mconfig(machine_config &config)
-{
+MACHINE_CONFIG_START(ibm5150_mb_device::device_add_mconfig)
ibm5160_mb_device::device_add_mconfig(config);
- subdevice<pc_kbdc_device>("pc_kbdc")->out_clock_cb().set(FUNC(ibm5150_mb_device::keyboard_clock_w));
+ MCFG_DEVICE_MODIFY("pc_kbdc")
+ MCFG_PC_KBDC_OUT_CLOCK_CB(WRITELINE(*this, ibm5150_mb_device, keyboard_clock_w))
m_ppi8255->out_pb_callback().set(FUNC(ibm5150_mb_device::pc_ppi_portb_w));
m_ppi8255->in_pc_callback().set(FUNC(ibm5150_mb_device::pc_ppi_portc_r));
- CASSETTE(config, m_cassette);
- m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
-}
+ MCFG_CASSETTE_ADD( "cassette" )
+ MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED)
+MACHINE_CONFIG_END
//**************************************************************************
// LIVE DEVICE
@@ -785,15 +772,15 @@ DEFINE_DEVICE_TYPE(EC1841_MOTHERBOARD, ec1841_mb_device, "ec1841_mb", "EC-1840 m
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void ec1841_mb_device::device_add_mconfig(machine_config &config)
-{
+MACHINE_CONFIG_START(ec1841_mb_device::device_add_mconfig)
ibm5160_mb_device::device_add_mconfig(config);
m_ppi8255->out_pb_callback().set(FUNC(ec1841_mb_device::pc_ppi_portb_w));
m_ppi8255->in_pc_callback().set(FUNC(ec1841_mb_device::pc_ppi_portc_r));
- subdevice<pc_kbdc_device>("pc_kbdc")->out_clock_cb().set(FUNC(ec1841_mb_device::keyboard_clock_w));
-}
+ MCFG_DEVICE_MODIFY("pc_kbdc")
+ MCFG_PC_KBDC_OUT_CLOCK_CB(WRITELINE(*this, ec1841_mb_device, keyboard_clock_w))
+MACHINE_CONFIG_END
static INPUT_PORTS_START( ec1841_mb )
PORT_START("DSW0") /* SA1 */
@@ -911,13 +898,12 @@ pc_noppi_mb_device::pc_noppi_mb_device(const machine_config &mconfig, device_typ
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void pc_noppi_mb_device::device_add_mconfig(machine_config &config)
-{
+MACHINE_CONFIG_START(pc_noppi_mb_device::device_add_mconfig)
ibm5160_mb_device::device_add_mconfig(config);
- config.device_remove("pc_kbdc");
- config.device_remove("ppi8255");
-}
+ MCFG_DEVICE_REMOVE("pc_kbdc")
+ MCFG_DEVICE_REMOVE("ppi8255")
+MACHINE_CONFIG_END
static INPUT_PORTS_START( pc_noppi_mb )
INPUT_PORTS_END
diff --git a/src/devices/machine/genpc.h b/src/devices/machine/genpc.h
index e222b975873..4c412a9a720 100644
--- a/src/devices/machine/genpc.h
+++ b/src/devices/machine/genpc.h
@@ -23,6 +23,11 @@
#include "bus/pc_kbd/pc_kbdc.h"
+#define MCFG_IBM5160_MOTHERBOARD_ADD(_tag, _cputag) \
+ MCFG_DEVICE_ADD(_tag, IBM5160_MOTHERBOARD, 0) \
+ downcast<ibm5160_mb_device &>(*device).set_cputag(_cputag); \
+ (*device->subdevice<isa8_device>("isa")).set_cputag(_cputag);
+
// ======================> ibm5160_mb_device
class ibm5160_mb_device : public device_t
{
@@ -31,12 +36,7 @@ public:
ibm5160_mb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// inline configuration
- template <typename T> void set_cputag(T &&tag)
- {
- m_maincpu.set_tag(std::forward<T>(tag));
- subdevice<isa8_device>("isa")->set_memspace(std::forward<T>(tag), AS_PROGRAM);
- subdevice<isa8_device>("isa")->set_iospace(std::forward<T>(tag), AS_IO);
- }
+ void set_cputag(const char *tag) { m_maincpu.set_tag(tag); }
void map(address_map &map);
@@ -119,7 +119,6 @@ protected:
DECLARE_WRITE_LINE_MEMBER( pc_dack1_w );
DECLARE_WRITE_LINE_MEMBER( pc_dack2_w );
DECLARE_WRITE_LINE_MEMBER( pc_dack3_w );
- DECLARE_WRITE_LINE_MEMBER( iochck_w );
void pc_select_dma_channel(int channel, bool state);
};
@@ -129,6 +128,11 @@ protected:
DECLARE_DEVICE_TYPE(IBM5160_MOTHERBOARD, ibm5160_mb_device)
+#define MCFG_IBM5150_MOTHERBOARD_ADD(_tag, _cputag) \
+ MCFG_DEVICE_ADD(_tag, IBM5150_MOTHERBOARD, 0) \
+ downcast<ibm5150_mb_device &>(*device).set_cputag(_cputag); \
+ (*device->subdevice<isa8_device>("isa")).set_cputag(_cputag);
+
// ======================> ibm5150_mb_device
class ibm5150_mb_device : public ibm5160_mb_device
{
@@ -158,6 +162,12 @@ private:
// device type definition
DECLARE_DEVICE_TYPE(IBM5150_MOTHERBOARD, ibm5150_mb_device)
+
+#define MCFG_EC1841_MOTHERBOARD_ADD(_tag, _cputag) \
+ MCFG_DEVICE_ADD(_tag, EC1841_MOTHERBOARD, 0) \
+ downcast<ec1841_mb_device &>(*device).set_cputag(_cputag); \
+ (*device->subdevice<isa8_device>("isa")).set_cputag(_cputag);
+
class ec1841_mb_device : public ibm5160_mb_device
{
public:
@@ -179,13 +189,16 @@ private:
DECLARE_DEVICE_TYPE(EC1841_MOTHERBOARD, ec1841_mb_device)
+#define MCFG_PCNOPPI_MOTHERBOARD_ADD(_tag, _cputag) \
+ MCFG_DEVICE_ADD(_tag, PCNOPPI_MOTHERBOARD, 0) \
+ downcast<pc_noppi_mb_device &>(*device).set_cputag(_cputag); \
+ (*device->subdevice<isa8_device>("isa")).set_cputag(_cputag);
class pc_noppi_mb_device : public ibm5160_mb_device
{
public:
// construction/destruction
pc_noppi_mb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
uint8_t pit_out2() { return m_pit_out2; } // helper for near-clones with multifunction ics instead of 8255s
void map(address_map &map);
diff --git a/src/devices/machine/hdc92x4.cpp b/src/devices/machine/hdc92x4.cpp
index 4354711738f..e7c42d31452 100644
--- a/src/devices/machine/hdc92x4.cpp
+++ b/src/devices/machine/hdc92x4.cpp
@@ -4265,7 +4265,7 @@ uint16_t hdc92x4_device::encode_a1_hd()
Read a byte of data from the controller
The address (offset) encodes the C/D* line (command and /data)
*/
-uint8_t hdc92x4_device::read(offs_t offset)
+READ8_MEMBER( hdc92x4_device::read )
{
uint8_t reply;
if ((offset & 1) == 0)
@@ -4300,7 +4300,7 @@ uint8_t hdc92x4_device::read(offs_t offset)
The operation terminates immediately, and the controller picks up the
values stored in this phase at a later time.
*/
-void hdc92x4_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( hdc92x4_device::write )
{
if ((offset & 1) == 0)
{
diff --git a/src/devices/machine/hdc92x4.h b/src/devices/machine/hdc92x4.h
index c4850ffa103..e0c25d1a524 100644
--- a/src/devices/machine/hdc92x4.h
+++ b/src/devices/machine/hdc92x4.h
@@ -45,8 +45,8 @@ public:
};
// Accessors from the CPU side
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
DECLARE_WRITE_LINE_MEMBER( reset );
DECLARE_WRITE_LINE_MEMBER( dmaack );
diff --git a/src/devices/machine/i2cmem.cpp b/src/devices/machine/i2cmem.cpp
index 34e75569a49..94670ff5326 100644
--- a/src/devices/machine/i2cmem.cpp
+++ b/src/devices/machine/i2cmem.cpp
@@ -58,14 +58,8 @@ static inline void ATTR_PRINTF( 3, 4 ) verboselog( device_t *device, int n_level
//**************************************************************************
// device type definition
-DEFINE_DEVICE_TYPE(I2CMEM, i2cmem_device, "i2cmem", "I2C Memory")
-DEFINE_DEVICE_TYPE(I2C_X2404P, i2c_x2404p_device, "x2404p", "X2404P I2C Memory")
-DEFINE_DEVICE_TYPE(I2C_24C01, i2c_24c01_device, "24c01", "24C01 I2C Memory")
-DEFINE_DEVICE_TYPE(I2C_24C02, i2c_24c02_device, "24c02", "24C02 I2C Memory")
-DEFINE_DEVICE_TYPE(I2C_24C08, i2c_24c08_device, "24c08", "24C08 I2C Memory")
-DEFINE_DEVICE_TYPE(I2C_24C16, i2c_24c16_device, "24c16", "24C16 I2C Memory")
-DEFINE_DEVICE_TYPE(I2C_24C16A, i2c_24c16a_device, "24c16a", "24C16A I2C Memory")
-DEFINE_DEVICE_TYPE(I2C_24C64, i2c_24c64_device, "24c64", "24C64 I2C Memory")
+DEFINE_DEVICE_TYPE(I2CMEM, i2cmem_device, "i2cmem", "I2C Memory")
+DEFINE_DEVICE_TYPE(X2404P, x2404p_device, "x2404p", "X2404P I2C Memory")
//**************************************************************************
// LIVE DEVICE
@@ -75,76 +69,36 @@ DEFINE_DEVICE_TYPE(I2C_24C64, i2c_24c64_device, "24c64", "24C64 I2C Memory")
// i2cmem_device - constructor
//-------------------------------------------------
-i2cmem_device::i2cmem_device(
- const machine_config &mconfig,
- device_type type,
- const char *tag,
- device_t *owner,
- uint32_t clock,
- int page_size,
- int data_size) :
- device_t(mconfig, type, tag, owner, clock),
+i2cmem_device::i2cmem_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_nvram_interface(mconfig, *this),
m_region(*this, DEVICE_SELF),
- m_slave_address(I2CMEM_SLAVE_ADDRESS),
- m_page_size(page_size),
- m_data_size(data_size),
- m_scl(0),
- m_sdaw(0),
- m_e0(0),
- m_e1(0),
- m_e2(0),
- m_wc(0),
- m_sdar(1),
- m_state(STATE_IDLE),
- m_shift(0),
- m_byteaddr(0),
- m_page_offset(0),
- m_page_written_size(0),
- m_in_write(false)
+ m_slave_address( I2CMEM_SLAVE_ADDRESS ),
+ m_page_size( 0 ),
+ m_data_size( 0 ),
+ m_scl( 0 ),
+ m_sdaw( 0 ),
+ m_e0( 0 ),
+ m_e1( 0 ),
+ m_e2( 0 ),
+ m_wc( 0 ),
+ m_sdar( 1 ),
+ m_state( STATE_IDLE ),
+ m_shift( 0 ),
+ m_byteaddr( 0 )
{
- // these memories work off the I2C clock only
- assert(!clock);
}
-i2cmem_device::i2cmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- i2cmem_device(mconfig, I2CMEM, tag, owner, clock, 0, 0)
+i2cmem_device::i2cmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : i2cmem_device(mconfig, I2CMEM, tag, owner, clock)
{
}
-i2c_x2404p_device::i2c_x2404p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- i2cmem_device(mconfig, I2C_X2404P, tag, owner, clock, 8, 0x200)
-{
-}
-
-i2c_24c01_device::i2c_24c01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- i2cmem_device(mconfig, I2C_24C01, tag, owner, clock, 4, 0x80)
-{
-}
-
-i2c_24c02_device::i2c_24c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- i2cmem_device(mconfig, I2C_24C02, tag, owner, clock, 4, 0x100)
-{
-}
-
-i2c_24c08_device::i2c_24c08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- i2cmem_device(mconfig, I2C_24C08, tag, owner, clock, 0, 0x400)
-{
-}
-
-i2c_24c16_device::i2c_24c16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- i2cmem_device(mconfig, I2C_24C16, tag, owner, clock, 8, 0x800)
-{
-}
-
-i2c_24c16a_device::i2c_24c16a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- i2cmem_device(mconfig, I2C_24C16A, tag, owner, clock, 0, 0x800)
-{
-}
-
-i2c_24c64_device::i2c_24c64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- i2cmem_device(mconfig, I2C_24C64, tag, owner, clock, 8, 0x2000)
+x2404p_device::x2404p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : i2cmem_device(mconfig, X2404P, tag, owner, clock)
{
+ set_page_size(8);
+ set_data_size(0x200);
}
//-------------------------------------------------
@@ -168,9 +122,6 @@ void i2cmem_device::device_start()
save_item( NAME(m_shift) );
save_item( NAME(m_devsel) );
save_item( NAME(m_byteaddr) );
- save_item( NAME(m_in_write) );
- save_item( NAME(m_page_offset) );
- save_item( NAME(m_page_written_size) );
save_pointer( &m_data[0], "m_data", m_data_size );
if ( m_page_size > 0 )
{
@@ -185,7 +136,6 @@ void i2cmem_device::device_start()
void i2cmem_device::device_reset()
{
- m_in_write = false;
}
@@ -287,15 +237,6 @@ WRITE_LINE_MEMBER( i2cmem_device::write_sda )
{
if( m_sdaw )
{
- if( m_in_write )
- {
- int base = data_offset();
- int root = base & ~( m_page_size - 1);
- for( int i=0; i < m_page_written_size; i++)
- m_data[root | ((base + i) & (m_page_size - 1))] = m_page[i];
- m_in_write = false;
- verboselog( this, 1, "data[ %04x to %04x ] = %x bytes\n", base, root | ((base + m_page_written_size - 1) & (m_page_size - 1)), m_page_written_size );
- }
verboselog( this, 1, "stop\n" );
m_state = STATE_IDLE;
}
@@ -360,7 +301,6 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl )
case STATE_BYTEADDR:
m_byteaddr = m_shift;
m_page_offset = 0;
- m_page_written_size = 0;
verboselog( this, 1, "byteaddr %02x\n", m_byteaddr );
@@ -375,16 +315,23 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl )
}
else if( m_page_size > 0 )
{
- m_in_write = true;
m_page[ m_page_offset ] = m_shift;
verboselog( this, 1, "page[ %04x ] <- %02x\n", m_page_offset, m_page[ m_page_offset ] );
m_page_offset++;
if( m_page_offset == m_page_size )
+ {
+ int offset = data_offset() & ~( m_page_size - 1 );
+
+ verboselog( this, 1, "data[ %04x to %04x ] = page\n", offset, offset + m_page_size - 1 );
+
+ for( int i = 0; i < m_page_size; i++ )
+ {
+ m_data[offset + i] = m_page[ i ];
+ }
+
m_page_offset = 0;
- m_page_written_size++;
- if( m_page_written_size > m_page_size)
- m_page_written_size = m_page_size;
+ }
}
else
{
diff --git a/src/devices/machine/i2cmem.h b/src/devices/machine/i2cmem.h
index c912709871d..d67fa463c2e 100644
--- a/src/devices/machine/i2cmem.h
+++ b/src/devices/machine/i2cmem.h
@@ -23,6 +23,61 @@
//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_I2CMEM_ADD( _tag ) \
+ MCFG_DEVICE_ADD( _tag, I2CMEM, 0 )
+
+#define MCFG_I2CMEM_ADDRESS( address ) \
+ downcast<i2cmem_device &>(*device).set_address(address);
+#define MCFG_I2CMEM_PAGE_SIZE( page_size ) \
+ downcast<i2cmem_device &>(*device).set_page_size(page_size);
+#define MCFG_I2CMEM_DATA_SIZE(data_size) \
+ downcast<i2cmem_device &>(*device).set_data_size(data_size);
+#define MCFG_I2CMEM_E0(e0) \
+ downcast<i2cmem_device &>(*device).set_e0(e0);
+#define MCFG_I2CMEM_E1(e1) \
+ downcast<i2cmem_device &>(*device).set_e1(e1);
+#define MCFG_I2CMEM_E2(e2) \
+ downcast<i2cmem_device &>(*device).set_e2(e2);
+#define MCFG_I2CMEM_WC(wc) \
+ downcast<i2cmem_device &>(*device).set_wc(wc);
+
+#define MCFG_X2404P_ADD( _tag ) \
+ MCFG_I2CMEM_ADD( _tag ) \
+ MCFG_I2CMEM_PAGE_SIZE(8) \
+ MCFG_I2CMEM_DATA_SIZE(0x200)
+
+#define MCFG_24C01_ADD( _tag ) \
+ MCFG_I2CMEM_ADD( _tag ) \
+ MCFG_I2CMEM_PAGE_SIZE(4) \
+ MCFG_I2CMEM_DATA_SIZE(0x80)
+
+#define MCFG_24C02_ADD( _tag ) \
+ MCFG_I2CMEM_ADD( _tag ) \
+ MCFG_I2CMEM_PAGE_SIZE(4) \
+ MCFG_I2CMEM_DATA_SIZE(0x100)
+
+#define MCFG_24C08_ADD( _tag ) \
+ MCFG_I2CMEM_ADD( _tag ) \
+ MCFG_I2CMEM_DATA_SIZE(0x400)
+
+#define MCFG_24C16_ADD( _tag ) \
+ MCFG_I2CMEM_ADD( _tag ) \
+ MCFG_I2CMEM_PAGE_SIZE(8) \
+ MCFG_I2CMEM_DATA_SIZE(0x800)
+
+#define MCFG_24C16A_ADD( _tag ) \
+ MCFG_I2CMEM_ADD( _tag ) \
+ MCFG_I2CMEM_DATA_SIZE(0x800)
+
+#define MCFG_24C64_ADD( _tag ) \
+ MCFG_I2CMEM_ADD( _tag ) \
+ MCFG_I2CMEM_PAGE_SIZE(8) \
+ MCFG_I2CMEM_DATA_SIZE(0x2000)
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -55,7 +110,7 @@ public:
protected:
// construction/destruction
- i2cmem_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int page_size, int data_size);
+ i2cmem_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0);
// device-level overrides
virtual void device_start() override;
@@ -92,33 +147,17 @@ protected:
int m_byteaddr;
std::vector<uint8_t> m_page;
int m_page_offset;
- int m_page_written_size;
- bool m_in_write;
};
-#define DECLARE_I2C_DEVICE(name) \
- class i2c_##name##_device : public i2cmem_device \
- { \
- public: \
- i2c_##name##_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); \
- };
-
-DECLARE_I2C_DEVICE(x2404p)
-DECLARE_I2C_DEVICE(24c01)
-DECLARE_I2C_DEVICE(24c02)
-DECLARE_I2C_DEVICE(24c08)
-DECLARE_I2C_DEVICE(24c16);
-DECLARE_I2C_DEVICE(24c16a);
-DECLARE_I2C_DEVICE(24c64);
+class x2404p_device : public i2cmem_device
+{
+public:
+ // construction/destruction
+ x2404p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+};
// device type definition
-DECLARE_DEVICE_TYPE(I2CMEM, i2cmem_device)
-DECLARE_DEVICE_TYPE(I2C_X2404P, i2c_x2404p_device)
-DECLARE_DEVICE_TYPE(I2C_24C01, i2c_24c01_device)
-DECLARE_DEVICE_TYPE(I2C_24C02, i2c_24c02_device)
-DECLARE_DEVICE_TYPE(I2C_24C08, i2c_24c08_device)
-DECLARE_DEVICE_TYPE(I2C_24C16, i2c_24c16_device)
-DECLARE_DEVICE_TYPE(I2C_24C16A, i2c_24c16a_device)
-DECLARE_DEVICE_TYPE(I2C_24C64, i2c_24c64_device)
+DECLARE_DEVICE_TYPE(I2CMEM, i2cmem_device)
+DECLARE_DEVICE_TYPE(X2404P, x2404p_device)
#endif // MAME_MACHINE_I2CMEM_H
diff --git a/src/devices/machine/i7220.cpp b/src/devices/machine/i7220.cpp
index 0e86dc081bb..8543d9f61f2 100644
--- a/src/devices/machine/i7220.cpp
+++ b/src/devices/machine/i7220.cpp
@@ -29,16 +29,17 @@
#include "i7220.h"
-//#define LOG_GENERAL (1U << 0) //defined in logmacro.h already
-#define LOG_REGISTER (1U << 1)
-#define LOG_DEBUG (1U << 2)
+#define VERBOSE_DBG 2 /* general debug messages */
-//#define VERBOSE (LOG_DEBUG)
-//#define LOG_OUTPUT_FUNC printf
-#include "logmacro.h"
-
-#define LOGREG(...) LOGMASKED(LOG_REGISTER, __VA_ARGS__)
-#define LOGDBG(...) LOGMASKED(LOG_DEBUG, __VA_ARGS__)
+#define DBG_LOG(N,M,A) \
+ do { \
+ if(VERBOSE_DBG>=N) \
+ { \
+ if( M ) \
+ logerror("%11.6f at %s: %-10s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
+ logerror A; \
+ } \
+ } while (0)
// device type definition
@@ -223,8 +224,8 @@ void i7220_device::start_command(int cmd)
// NFC bits in BLR MSB must be set to 0001 before issuing this command.
// MBM GROUP SELECT bits in the AR must select the last MBM in the system.
case C_INIT:
- LOG("BMC INIT: BLR %04x (NFC %d pages %d) AR %04x (MBM %d addr %03x) ER %02d\n",
- m_blr, blr_nfc, blr_count, m_ar, ar_mbm, ar_addr, m_regs[R_ER]);
+ DBG_LOG(1, "BMC", ("INIT: BLR %04x (NFC %d pages %d) AR %04x (MBM %d addr %03x) ER %02d\n",
+ m_blr, blr_nfc, blr_count, m_ar, ar_mbm, ar_addr, m_regs[R_ER]));
if (blr_nfc != 2)
{
command_fail_start(bi);
@@ -241,8 +242,8 @@ void i7220_device::start_command(int cmd)
// all parametric registers must be properly set up before issuing Read Bubble Data command
case C_READ:
- LOG("BMC RBD: BLR %04x (NFC %d pages %d) AR %04x (MBM %d addr %03x) ER %02d\n",
- m_blr, blr_nfc, blr_count, m_ar, ar_mbm, ar_addr, m_regs[R_ER]);
+ DBG_LOG(1, "BMC", ("RBD: BLR %04x (NFC %d pages %d) AR %04x (MBM %d addr %03x) ER %02d\n",
+ m_blr, blr_nfc, blr_count, m_ar, ar_mbm, ar_addr, m_regs[R_ER]));
if (ar_mbm >= m_data_size || blr_nfc != 2)
{
command_fail_start(bi);
@@ -254,8 +255,8 @@ void i7220_device::start_command(int cmd)
break;
case C_WRITE:
- LOG("BMC WBD: BLR %04x (NFC %d pages %d) AR %04x (MBM %d addr %03x) ER %02d\n",
- m_blr, blr_nfc, blr_count, m_ar, ar_mbm, ar_addr, m_regs[R_ER]);
+ DBG_LOG(1, "BMC", ("WBD: BLR %04x (NFC %d pages %d) AR %04x (MBM %d addr %03x) ER %02d\n",
+ m_blr, blr_nfc, blr_count, m_ar, ar_mbm, ar_addr, m_regs[R_ER]));
if (ar_mbm >= m_data_size || blr_nfc != 2)
{
command_fail_start(bi);
@@ -338,7 +339,7 @@ void i7220_device::general_continue(bubble_info &bi)
break;
default:
- LOG("BMC general_continue on unknown main-state %d\n", bi.main_state);
+ DBG_LOG(1,"BMC",("general_continue on unknown main-state %d\n", bi.main_state));
break;
}
}
@@ -388,7 +389,7 @@ void i7220_device::command_fail_continue(bubble_info &bi)
return;
default:
- LOG("BMC fail unknown sub-state %d\n", bi.sub_state);
+ DBG_LOG(1,"BMC",("fail unknown sub-state %d\n", bi.sub_state));
return;
}
}
@@ -422,7 +423,7 @@ void i7220_device::init_continue(bubble_info &bi)
return;
default:
- LOG("BMC init unknown sub-state %d\n", bi.sub_state);
+ DBG_LOG(1,"BMC",("init unknown sub-state %d\n", bi.sub_state));
return;
}
}
@@ -462,7 +463,7 @@ void i7220_device::read_fsa_continue(bubble_info &bi)
return;
default:
- LOG("BMC read fsa unknown sub-state %d\n", bi.sub_state);
+ DBG_LOG(1,"BMC",("read fsa unknown sub-state %d\n", bi.sub_state));
return;
}
}
@@ -496,7 +497,7 @@ void i7220_device::read_data_continue(bubble_info &bi)
break;
case WAIT_FSA_REPLY:
- LOGDBG("BMC read data: ct %02d limit %02d\n", bi.counter, bi.limit);
+ DBG_LOG(3,"BMC",("read data: ct %02d limit %02d\n", bi.counter, bi.limit));
if (bi.counter < bi.limit)
{
for (int a = 0; a < 32; a++)
@@ -514,7 +515,7 @@ void i7220_device::read_data_continue(bubble_info &bi)
return;
default:
- LOG("BMC read data unknown sub-state %d\n", bi.sub_state);
+ DBG_LOG(1,"BMC",("read data unknown sub-state %d\n", bi.sub_state));
return;
}
}
@@ -542,7 +543,7 @@ void i7220_device::write_data_continue(bubble_info &bi)
return;
case WAIT_FIFO:
- LOGDBG("BMC write data: fifo %02d ct %02d limit %02d\n", m_fifo_size, bi.counter, bi.limit);
+ DBG_LOG(3,"BMC",("write data: fifo %02d ct %02d limit %02d\n", m_fifo_size, bi.counter, bi.limit));
if (m_fifo_size >= 32)
{
for (int a = 0; a < 32; a++)
@@ -564,7 +565,7 @@ void i7220_device::write_data_continue(bubble_info &bi)
return;
default:
- LOG("BMC write data unknown sub-state %d\n", bi.sub_state);
+ DBG_LOG(1,"BMC",("write data unknown sub-state %d\n", bi.sub_state));
return;
}
}
@@ -585,14 +586,14 @@ READ8_MEMBER(i7220_device::read)
if (m_rac)
{
data = m_regs[m_rac];
- LOGREG("BMC R reg @ %02x == %02x\n", m_rac, data);
+ DBG_LOG(2, "BMC", ("R reg @ %02x == %02x\n", m_rac, data));
m_rac++;
m_rac &= 15;
}
else
{
data = fifo_pop();
- LOGREG("BMC R fifo == %02x\n", data);
+ DBG_LOG(2, "BMC", ("R fifo == %02x\n", data));
}
break;
@@ -625,8 +626,8 @@ READ8_MEMBER(i7220_device::read)
data |= SR_FIFO;
}
}
- LOGREG("BMC R status == %02x (phase %d state %d:%d fifo %d drq %d)\n",
- data, main_phase, bi.main_state, bi.sub_state, m_fifo_size, drq);
+ DBG_LOG(2, "BMC", ("R status == %02x (phase %d state %d:%d fifo %d drq %d)\n",
+ data, main_phase, bi.main_state, bi.sub_state, m_fifo_size, drq));
if (main_phase == PHASE_RESULT)
{
main_phase = PHASE_IDLE;
@@ -634,7 +635,7 @@ READ8_MEMBER(i7220_device::read)
break;
}
- LOGDBG("BMC R @ %d == %02x\n", offset, data);
+ DBG_LOG(3, "BMC", ("R @ %d == %02x\n", offset, data));
return data;
}
@@ -664,14 +665,14 @@ WRITE8_MEMBER( i7220_device::write )
"Software Reset"
};
- LOGDBG("BMC W @ %d <- %02x\n", offset, data);
+ DBG_LOG(3, "BMC", ("W @ %d <- %02x\n", offset, data));
switch (offset & 1)
{
case 0:
if (m_rac)
{
- LOGREG("BMC W reg @ %02x <- %02x\n", m_rac, data);
+ DBG_LOG(2, "BMC", ("W reg @ %02x <- %02x\n", m_rac, data));
m_regs[m_rac] = data;
update_regs();
m_rac++;
@@ -679,7 +680,7 @@ WRITE8_MEMBER( i7220_device::write )
}
else
{
- LOGREG("BMC W fifo <- %02x\n", data);
+ DBG_LOG(2, "BMC", ("W fifo <- %02x\n", data));
fifo_push(data);
}
break;
@@ -694,7 +695,7 @@ WRITE8_MEMBER( i7220_device::write )
m_cmdr = data & 15;
if (main_phase == PHASE_IDLE)
{
- LOG("BMC command %02x '%s'\n", data, commands[m_cmdr]);
+ DBG_LOG(1, "BMC", ("command %02x '%s'\n", data, commands[m_cmdr]));
main_phase = PHASE_CMD;
start_command(m_cmdr);
}
diff --git a/src/devices/machine/i8087.cpp b/src/devices/machine/i8087.cpp
index e137ae105e4..15d5e51bea2 100644
--- a/src/devices/machine/i8087.cpp
+++ b/src/devices/machine/i8087.cpp
@@ -169,7 +169,7 @@ DEFINE_DEVICE_TYPE(I8087, i8087_device, "i8087", "Intel 8087")
i8087_device::i8087_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, type, tag, owner, clock),
- m_space(*this, finder_base::DUMMY_TAG, -1),
+ device_memory_interface(mconfig, *this),
m_int_handler(*this),
m_busy_handler(*this)
{
@@ -180,6 +180,13 @@ i8087_device::i8087_device(const machine_config &mconfig, const char *tag, devic
{
}
+device_memory_interface::space_config_vector i8087_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(AS_PROGRAM, &m_space_config),
+ };
+}
+
void i8087_device::device_start()
{
save_item(NAME(m_reg[0].high));
@@ -215,6 +222,11 @@ void i8087_device::device_start()
build_opcode_table();
}
+void i8087_device::device_config_complete()
+{
+ m_space_config = address_space_config("program", ENDIANNESS_LITTLE, m_data_width, 20);
+}
+
void i8087_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
m_busy_handler(1);
diff --git a/src/devices/machine/i8087.h b/src/devices/machine/i8087.h
index 9344ca2e68e..290b9a95b16 100644
--- a/src/devices/machine/i8087.h
+++ b/src/devices/machine/i8087.h
@@ -10,12 +10,12 @@
DECLARE_DEVICE_TYPE(I8087, i8087_device)
-class i8087_device : public device_t
+class i8087_device : public device_t,
+ public device_memory_interface
{
public:
i8087_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- template <class Object> void set_space_88(Object &&tag, int spacenum) { m_space.set_tag(std::forward<Object>(tag), spacenum); m_space.set_data_width(8); }
- template <class Object> void set_space_86(Object &&tag, int spacenum) { m_space.set_tag(std::forward<Object>(tag), spacenum); m_space.set_data_width(16); }
+ void set_data_width(u8 data_width) { m_data_width = data_width; }
auto irq() { return m_int_handler.bind(); }
auto busy() { return m_busy_handler.bind(); }
@@ -26,13 +26,13 @@ protected:
i8087_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
virtual void device_start() override;
virtual void device_reset() override;
+ virtual void device_config_complete() override;
+ virtual space_config_vector memory_space_config() const override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
- address_space &space() { return *m_space; }
-
typedef void (i8087_device::*x87_func)(u8 modrm);
- required_address_space m_space;
+ address_space_config m_space_config;
devcb_write_line m_int_handler;
devcb_write_line m_busy_handler;
emu_timer *m_timer;
@@ -45,6 +45,7 @@ private:
u16 m_cw;
u16 m_sw;
u16 m_tw;
+ int m_data_width;
int m_icount;
x87_func m_opcode_table_d8[256];
diff --git a/src/devices/machine/i8155.cpp b/src/devices/machine/i8155.cpp
index b5027368633..779874a244d 100644
--- a/src/devices/machine/i8155.cpp
+++ b/src/devices/machine/i8155.cpp
@@ -406,7 +406,7 @@ void i8155_device::device_timer(emu_timer &timer, device_timer_id id, int param,
// io_r - register read
//-------------------------------------------------
-uint8_t i8155_device::io_r(offs_t offset)
+READ8_MEMBER( i8155_device::io_r )
{
uint8_t data = 0;
@@ -539,7 +539,7 @@ void i8155_device::register_w(int offset, uint8_t data)
// io_w - register write
//-------------------------------------------------
-void i8155_device::io_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER( i8155_device::io_w )
{
register_w(offset, data);
}
@@ -549,7 +549,7 @@ void i8155_device::io_w(offs_t offset, uint8_t data)
// memory_r - internal RAM read
//-------------------------------------------------
-uint8_t i8155_device::memory_r(offs_t offset)
+READ8_MEMBER( i8155_device::memory_r )
{
return m_ram[offset & 0xff];
}
@@ -559,7 +559,7 @@ uint8_t i8155_device::memory_r(offs_t offset)
// memory_w - internal RAM write
//-------------------------------------------------
-void i8155_device::memory_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER( i8155_device::memory_w )
{
m_ram[offset & 0xff] = data;
}
@@ -569,7 +569,7 @@ void i8155_device::memory_w(offs_t offset, uint8_t data)
// ale_w - address latch write
//-------------------------------------------------
-void i8155_device::ale_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER( i8155_device::ale_w )
{
// I/O / memory select
m_io_m = BIT(offset, 0);
@@ -580,21 +580,21 @@ void i8155_device::ale_w(offs_t offset, uint8_t data)
//-------------------------------------------------
-// data_r - memory or I/O read
+// read - memory or I/O read
//-------------------------------------------------
-uint8_t i8155_device::data_r()
+READ8_MEMBER( i8155_device::read )
{
uint8_t data = 0;
switch (m_io_m)
{
case MEMORY:
- data = memory_r(m_ad);
+ data = memory_r(space, m_ad);
break;
case IO:
- data = io_r(m_ad);
+ data = io_r(space, m_ad);
break;
}
@@ -603,19 +603,19 @@ uint8_t i8155_device::data_r()
//-------------------------------------------------
-// data_w - memory or I/O write
+// write - memory or I/O write
//-------------------------------------------------
-void i8155_device::data_w(uint8_t data)
+WRITE8_MEMBER( i8155_device::write )
{
switch (m_io_m)
{
case MEMORY:
- memory_w(m_ad, data);
+ memory_w(space, m_ad, data);
break;
case IO:
- io_w(m_ad, data);
+ io_w(space, m_ad, data);
break;
}
}
diff --git a/src/devices/machine/i8155.h b/src/devices/machine/i8155.h
index 2d6e49b2063..a17692211e6 100644
--- a/src/devices/machine/i8155.h
+++ b/src/devices/machine/i8155.h
@@ -55,15 +55,15 @@ public:
auto out_pc_callback() { return m_out_pc_cb.bind(); }
auto out_to_callback() { return m_out_to_cb.bind(); }
- uint8_t io_r(offs_t offset);
- void io_w(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( io_r );
+ DECLARE_WRITE8_MEMBER( io_w );
- uint8_t memory_r(offs_t offset);
- void memory_w(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( memory_r );
+ DECLARE_WRITE8_MEMBER( memory_w );
- void ale_w(offs_t offset, uint8_t data);
- uint8_t data_r();
- void data_w(uint8_t data);
+ DECLARE_WRITE8_MEMBER( ale_w );
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
protected:
i8155_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
diff --git a/src/devices/machine/i82357.cpp b/src/devices/machine/i82357.cpp
deleted file mode 100644
index 9b3be9c0905..00000000000
--- a/src/devices/machine/i82357.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Patrick Mackinlay
-
-/*
- * An implementation of the Intel 82357 Integrated System Peripheral.
- *
- * This device was one part of the 3-chip Intel 82350 EISA bus chipset.
- *
- * Sources:
- *
- * http://bitsavers.org/components/intel/_dataBooks/1996_Intel_Peripheral_Components.pdf
- *
- * TODO
- * - expose everything to an actual EISA bus
- * - 32-bit dma functionality
- *
- */
-
-#include "emu.h"
-#include "i82357.h"
-
-#define LOG_GENERAL (1U << 0)
-
-//#define VERBOSE (LOG_GENERAL)
-
-#include "logmacro.h"
-
-DEFINE_DEVICE_TYPE(I82357, i82357_device, "i82357", "Intel 82357 Integrated System Peripheral")
-
-i82357_device::i82357_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, I82357, tag, owner, clock)
- , m_pic(*this, "pic%u", 0)
- , m_pit(*this, "pit%u", 0)
- , m_dma(*this, "dma%u", 0)
- , m_out_rtc(*this)
- , m_out_nmi(*this)
- , m_out_spkr(*this)
-{
-}
-
-void i82357_device::device_add_mconfig(machine_config &config)
-{
- PIC8259(config, m_pic[0], 0);
- m_pic[0]->in_sp_callback().set_constant(1);
- m_pic[0]->read_slave_ack_callback().set(
- [this](offs_t offset)
- {
- if (offset == 2)
- return m_pic[1]->acknowledge();
-
- return u32(0);
- });
-
- PIC8259(config, m_pic[1], 0);
- m_pic[1]->out_int_callback().set(m_pic[0], FUNC(pic8259_device::ir2_w));
- m_pic[1]->in_sp_callback().set_constant(0);
-
- PIT8254(config, m_pit[0], 0);
- PIT8254(config, m_pit[1], 0);
-
- // timer 1 counter 0: system timer
- m_pit[0]->set_clk<0>(clock() / 12);
- m_pit[0]->out_handler<0>().set(m_pic[0], FUNC(pic8259_device::ir0_w));
-
- // timer 1 counter 1: refresh request
- m_pit[0]->set_clk<1>(clock() / 12);
- m_pit[0]->out_handler<1>().set(
- [this](int state)
- {
- // FIXME: not accurate, but good enough to pass diagnostic
- if (state)
- m_nmi_reg ^= NMI_REFRESH;
-
- m_pit[1]->write_gate2(state);
- });
-
- // timer 1 counter 2: speaker
- m_pit[0]->set_clk<2>(clock() / 12);
- m_pit[0]->out_handler<2>().set(
- [this](int state)
- {
- if (state)
- m_nmi_reg |= NMI_T1C2_STATE;
- else
- m_nmi_reg &= ~NMI_T1C2_STATE;
-
- m_out_spkr((m_nmi_reg & NMI_T1C2_STATE) && (m_nmi_reg & NMI_SPEAKER_DATA));
- });
-
- // timer 2 counter 0: fail-safe timer
- m_pit[1]->set_clk<0>(clock() / 48);
- m_pit[1]->out_handler<0>().set(
- [this](int state)
- {
- if (state && (m_nmi_ext & NMI_EXT_EN_FAILSAFE))
- {
- m_nmi_ext |= NMI_EXT_FAILSAFE;
-
- m_nmi_check->adjust(attotime::zero);
- }
- });
-
- // timer 2 counter 1: does not exist
-
- // timer 2 counter 2: cpu speed control
- m_pit[1]->set_clk<2>(8_MHz_XTAL);
- //m_pit[1]->out_handler<2>().set();
-
- EISA_DMA(config, m_dma[0], clock() / 3);
- EISA_DMA(config, m_dma[1], clock() / 3);
- m_dma[1]->out_dack_callback<0>().set(m_dma[0], FUNC(eisa_dma_device::hack_w)).invert();
-}
-
-void i82357_device::map(address_map &map)
-{
- map(0x000, 0x00f).rw(m_dma[0], FUNC(eisa_dma_device::read), FUNC(eisa_dma_device::write));
- map(0x020, 0x021).rw(m_pic[0], FUNC(pic8259_device::read), FUNC(pic8259_device::write));
- map(0x040, 0x043).rw(m_pit[0], FUNC(pit8254_device::read), FUNC(pit8254_device::write));
- map(0x048, 0x04b).rw(m_pit[1], FUNC(pit8254_device::read), FUNC(pit8254_device::write));
-
- // FIXME: also 0x065 - "NMI Status"
- map(0x061, 0x061).rw(FUNC(i82357_device::nmi_reg_r), FUNC(i82357_device::nmi_reg_w));
-
- // NMI Enable Register (0x70, 72, 74, 76)
- map(0x070, 0x077).lw8("nmi_rtc",
- [this](address_space &space, offs_t offset, u8 data)
- {
- m_nmi_enabled = !BIT(data, 7);
-
- m_out_rtc(space, 0, data & 0x7f);
-
- m_nmi_check->adjust(attotime::zero);
- }).umask64(0xff);
-
- map(0x081, 0x081).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page<2>), FUNC(eisa_dma_device::set_address_page<2>));
- map(0x082, 0x082).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page<3>), FUNC(eisa_dma_device::set_address_page<3>));
- map(0x083, 0x083).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page<1>), FUNC(eisa_dma_device::set_address_page<1>));
- map(0x087, 0x087).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page<0>), FUNC(eisa_dma_device::set_address_page<0>));
- map(0x089, 0x089).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page<2>), FUNC(eisa_dma_device::set_address_page<2>));
- map(0x08a, 0x08a).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page<3>), FUNC(eisa_dma_device::set_address_page<3>));
- map(0x08b, 0x08b).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page<1>), FUNC(eisa_dma_device::set_address_page<1>));
- map(0x08f, 0x08f).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page<0>), FUNC(eisa_dma_device::set_address_page<0>));
-
- // TODO: also 0xa4, a8, ac, b0, b4, b8, bc
- map(0x0a0, 0x0a1).rw(m_pic[1], FUNC(pic8259_device::read), FUNC(pic8259_device::write));
- map(0x0c0, 0x0df).rw(m_dma[1], FUNC(eisa_dma_device::read), FUNC(eisa_dma_device::write)).umask16(0x00ff);
-
- map(0x401, 0x401).rw(m_dma[0], FUNC(eisa_dma_device::get_count_high<0>), FUNC(eisa_dma_device::set_count_high<0>));
- map(0x403, 0x403).rw(m_dma[0], FUNC(eisa_dma_device::get_count_high<1>), FUNC(eisa_dma_device::set_count_high<1>));
- map(0x405, 0x405).rw(m_dma[0], FUNC(eisa_dma_device::get_count_high<2>), FUNC(eisa_dma_device::set_count_high<2>));
- map(0x407, 0x407).rw(m_dma[0], FUNC(eisa_dma_device::get_count_high<3>), FUNC(eisa_dma_device::set_count_high<3>));
-
- //map(0x40a, 0x40a); // DMA1 Set Chaining Mode (w)/Interrupt Status (r)
- //map(0x40b, 0x40b); // DMA1 Ext Write Mode (w)
- //map(0x40c, 0x40c); // Chain Buffer Control
- //map(0x40d, 0x40d); // Stepping Level Register (ro)
- //map(0x40e, 0x40e); // ISP Test Register
- //map(0x40f, 0x40f); // ISP Test Register
-
- map(0x461, 0x461).rw(FUNC(i82357_device::nmi_ext_r), FUNC(i82357_device::nmi_ext_w));
- map(0x462, 0x462).lw8("nmi_ioport",
- [this](u8 data)
- {
- if (m_nmi_ext & NMI_EXT_EN_IOPORT)
- {
- m_nmi_ext |= NMI_EXT_IOPORT;
-
- m_nmi_check->adjust(attotime::zero);
- }
- });
- //map(0x464, 0x464); // Last 32-bit bus master granted (L)
-
- map(0x481, 0x481).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page_high<2>), FUNC(eisa_dma_device::set_address_page_high<2>));
- map(0x482, 0x482).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page_high<3>), FUNC(eisa_dma_device::set_address_page_high<3>));
- map(0x483, 0x483).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page_high<1>), FUNC(eisa_dma_device::set_address_page_high<1>));
- map(0x487, 0x487).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page_high<0>), FUNC(eisa_dma_device::set_address_page_high<0>));
- map(0x489, 0x489).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page_high<2>), FUNC(eisa_dma_device::set_address_page_high<2>));
- map(0x48a, 0x48a).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page_high<3>), FUNC(eisa_dma_device::set_address_page_high<3>));
- map(0x48b, 0x48b).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page_high<1>), FUNC(eisa_dma_device::set_address_page_high<1>));
- map(0x48f, 0x48f).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page_high<0>), FUNC(eisa_dma_device::set_address_page_high<0>));
-
- map(0x4c2, 0x4c2).rw(m_dma[1], FUNC(eisa_dma_device::get_count_high<0>), FUNC(eisa_dma_device::set_count_high<0>));
- map(0x4c6, 0x4c6).rw(m_dma[1], FUNC(eisa_dma_device::get_count_high<1>), FUNC(eisa_dma_device::set_count_high<1>));
- map(0x4ca, 0x4ca).rw(m_dma[1], FUNC(eisa_dma_device::get_count_high<2>), FUNC(eisa_dma_device::set_count_high<2>));
- map(0x4ce, 0x4ce).rw(m_dma[1], FUNC(eisa_dma_device::get_count_high<3>), FUNC(eisa_dma_device::set_count_high<3>));
- map(0x4d0, 0x4d1).lrw8("elcr",
- [this](offs_t offset) { return m_elcr[offset]; },
- [this](offs_t offset, u8 data) { m_elcr[offset] = data; });
-
- //map(0x4d4, 0x4d4); // DMA2 Set Chaining Mode
- //map(0x4d6, 0x4d6); // DMA2 Ext Write Mode Register
-
- map(0x4e0, 0x4e3).rw(m_dma[0], FUNC(eisa_dma_device::get_stop<0>), FUNC(eisa_dma_device::set_stop<0>));
- map(0x4e4, 0x4e7).rw(m_dma[0], FUNC(eisa_dma_device::get_stop<1>), FUNC(eisa_dma_device::set_stop<1>));
- map(0x4e8, 0x4eb).rw(m_dma[0], FUNC(eisa_dma_device::get_stop<2>), FUNC(eisa_dma_device::set_stop<2>));
- map(0x4ec, 0x4ef).rw(m_dma[0], FUNC(eisa_dma_device::get_stop<3>), FUNC(eisa_dma_device::set_stop<3>));
-
- map(0x4f0, 0x4f3).rw(m_dma[1], FUNC(eisa_dma_device::get_stop<0>), FUNC(eisa_dma_device::set_stop<0>)); // reserved
- map(0x4f4, 0x4f7).rw(m_dma[1], FUNC(eisa_dma_device::get_stop<1>), FUNC(eisa_dma_device::set_stop<1>));
- map(0x4f8, 0x4fb).rw(m_dma[1], FUNC(eisa_dma_device::get_stop<2>), FUNC(eisa_dma_device::set_stop<2>));
- map(0x4fc, 0x4ff).rw(m_dma[1], FUNC(eisa_dma_device::get_stop<3>), FUNC(eisa_dma_device::set_stop<3>));
-}
-
-void i82357_device::device_start()
-{
- m_out_rtc.resolve_safe();
- m_out_nmi.resolve_safe();
- m_out_spkr.resolve_safe();
-
- m_nmi_check = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(i82357_device::nmi_check), this));
-}
-
-void i82357_device::device_reset()
-{
- m_elcr[0] = 0;
- m_elcr[1] = 0;
-
- m_nmi_enabled = true;
- m_nmi_reg = 0;
- m_nmi_ext = 0;
-
- m_nmi_check->adjust(attotime::zero);
-}
-
-void i82357_device::nmi_reg_w(u8 data)
-{
- m_pit[0]->write_gate2(!!(data & NMI_T1C2_GATE));
-
- // clear parity nmi
- if (data & NMI_PARITY_DISABLE)
- m_nmi_reg &= ~NMI_PARITY;
-
- // clear iochk nmi
- if (data & NMI_IOCHK_DISABLE)
- m_nmi_reg &= ~NMI_IOCHK;
-
- m_nmi_reg = (m_nmi_reg & ~NMI_WMASK) | (data & NMI_WMASK);
-
- // update speaker state
- m_out_spkr((m_nmi_reg & NMI_T1C2_STATE) && (m_nmi_reg & NMI_SPEAKER_DATA));
-
- m_nmi_check->adjust(attotime::zero);
-}
-
-void i82357_device::nmi_ext_w(u8 data)
-{
- if (!(data & NMI_EXT_EN_IOPORT))
- m_nmi_ext &= ~NMI_EXT_IOPORT;
-
- if (!(data & NMI_EXT_EN_TIMEOUT))
- m_nmi_ext &= ~NMI_EXT_TIMEOUT;
-
- if (!(data & NMI_EXT_EN_FAILSAFE))
- m_nmi_ext &= ~NMI_EXT_FAILSAFE;
-
- m_nmi_ext = (m_nmi_ext & ~NMI_EXT_WMASK) | (data & NMI_EXT_WMASK);
-
- m_nmi_check->adjust(attotime::zero);
-}
-
-WRITE_LINE_MEMBER(i82357_device::in_iochk)
-{
- if (!state && !(m_nmi_reg & NMI_PARITY_DISABLE))
- {
- m_nmi_reg |= NMI_IOCHK;
-
- m_nmi_check->adjust(attotime::zero);
- }
- else
- m_nmi_reg &= ~NMI_IOCHK;
-}
-
-WRITE_LINE_MEMBER(i82357_device::in_parity)
-{
- if (!state && !(m_nmi_reg & NMI_IOCHK_DISABLE))
- {
- m_nmi_reg |= NMI_PARITY;
-
- m_nmi_check->adjust(attotime::zero);
- }
- else
- m_nmi_reg &= ~NMI_PARITY;
-}
-
-TIMER_CALLBACK_MEMBER(i82357_device::nmi_check)
-{
- if (m_nmi_enabled)
- {
- if ((m_nmi_reg & NMI_NMI) || (m_nmi_ext & NMI_EXT_NMI))
- {
- if (!m_out_nmi_asserted)
- {
- m_out_nmi_asserted = true;
- m_out_nmi(1);
- }
-
- return;
- }
- }
-
- // disabled or no source
- if (m_out_nmi_asserted)
- {
- m_out_nmi_asserted = false;
- m_out_nmi(0);
- }
-}
diff --git a/src/devices/machine/i82357.h b/src/devices/machine/i82357.h
deleted file mode 100644
index 3c5a7756061..00000000000
--- a/src/devices/machine/i82357.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Patrick Mackinlay
-
-#ifndef MAME_MACHINE_I82357_H
-#define MAME_MACHINE_I82357_H
-
-#pragma once
-
-#include "machine/pic8259.h"
-#include "machine/pit8253.h"
-#include "machine/am9517a.h"
-
-class i82357_device : public device_t
-{
-public:
- i82357_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-
- auto out_rtc_cb() { return m_out_rtc.bind(); }
- auto out_int_cb() { return subdevice<pic8259_device>("pic0")->out_int_callback(); }
- auto out_nmi_cb() { return m_out_nmi.bind(); }
- auto out_spkr_cb() { return m_out_spkr.bind(); }
-
- u32 eisa_irq_ack() { return m_pic[0]->acknowledge(); }
-
- DECLARE_WRITE_LINE_MEMBER(in_iochk);
- DECLARE_WRITE_LINE_MEMBER(in_parity);
-
- void map(address_map &map);
-
-protected:
- // standard device_t overrides
- virtual void device_add_mconfig(machine_config &config) override;
- virtual void device_start() override;
- virtual void device_reset() override;
-
- void nmi_reg_w(u8 data);
- void nmi_ext_w(u8 data);
- u8 nmi_reg_r() { return m_nmi_reg; }
- u8 nmi_ext_r() { return m_nmi_ext; }
-
- TIMER_CALLBACK_MEMBER(nmi_check);
-
-private:
- required_device_array<pic8259_device, 2> m_pic;
- required_device_array<pit8254_device, 2> m_pit;
- required_device_array<eisa_dma_device, 2> m_dma;
-
- devcb_write8 m_out_rtc;
- devcb_write_line m_out_nmi;
- devcb_write_line m_out_spkr;
-
- enum nmi_reg_mask : u8
- {
- NMI_T1C2_GATE = 0x01,
- NMI_SPEAKER_DATA = 0x02,
- NMI_PARITY_DISABLE = 0x04,
- NMI_IOCHK_DISABLE = 0x08,
- NMI_REFRESH = 0x10,
- NMI_T1C2_STATE = 0x20,
- NMI_IOCHK = 0x40,
- NMI_PARITY = 0x80,
-
- NMI_WMASK = 0x0f,
- NMI_NMI = 0xc0,
- };
- enum nmi_ext_mask : u8
- {
- NMI_EXT_BUS_RESET = 0x01, // bus reset (read/write)
- NMI_EXT_EN_IOPORT = 0x02,
- NMI_EXT_EN_FAILSAFE = 0x04,
- NMI_EXT_EN_TIMEOUT = 0x08,
- NMI_EXT_8US_TIMEOUT = 0x10, // 8us EISA bus master timeout occurred
- NMI_EXT_IOPORT = 0x20, // NMI I/O port interrupt pending
- NMI_EXT_TIMEOUT = 0x40, // EISA bus master timeout occurred, NMI requested
- NMI_EXT_FAILSAFE = 0x80, // Fail-safe timer is active, NMI requested
-
- NMI_EXT_WMASK = 0x0f,
- NMI_EXT_NMI = 0xe0,
- };
- u8 m_elcr[2];
-
- emu_timer *m_nmi_check;
- bool m_out_nmi_asserted;
- bool m_nmi_enabled;
- u8 m_nmi_reg;
- u8 m_nmi_ext;
-};
-
-DECLARE_DEVICE_TYPE(I82357, i82357_device)
-
-#endif // MAME_MACHINE_I82357_H
diff --git a/src/devices/machine/i82371sb.cpp b/src/devices/machine/i82371sb.cpp
index b149d98a48f..579d678906a 100644
--- a/src/devices/machine/i82371sb.cpp
+++ b/src/devices/machine/i82371sb.cpp
@@ -49,7 +49,7 @@ void i82371sb_isa_device::internal_io_map(address_map &map)
void i82371sb_isa_device::device_add_mconfig(machine_config &config)
{
- PIT8254(config, m_pit8254);
+ PIT8254(config, m_pit8254, 0);
m_pit8254->set_clk<0>(4772720/4); // heartbeat IRQ
m_pit8254->out_handler<0>().set(FUNC(i82371sb_isa_device::at_pit8254_out0_changed));
m_pit8254->set_clk<1>(4772720/4); // DRAM refresh
@@ -90,12 +90,12 @@ void i82371sb_isa_device::device_add_mconfig(machine_config &config)
m_dma8237_2->out_dack_callback<2>().set(FUNC(i82371sb_isa_device::pc_dack6_w));
m_dma8237_2->out_dack_callback<3>().set(FUNC(i82371sb_isa_device::pc_dack7_w));
- PIC8259(config, m_pic8259_master);
+ PIC8259(config, m_pic8259_master, 0);
m_pic8259_master->out_int_callback().set_inputline(m_maincpu, 0);
m_pic8259_master->in_sp_callback().set_constant(1);
m_pic8259_master->read_slave_ack_callback().set(FUNC(i82371sb_isa_device::get_slave_ack));
- PIC8259(config, m_pic8259_slave);
+ PIC8259(config, m_pic8259_slave, 0);
m_pic8259_slave->out_int_callback().set(m_pic8259_master, FUNC(pic8259_device::ir2_w));
m_pic8259_slave->in_sp_callback().set_constant(0);
@@ -104,8 +104,7 @@ void i82371sb_isa_device::device_add_mconfig(machine_config &config)
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);
ISA16(config, m_isabus, 0);
- m_isabus->set_memspace(":maincpu", AS_PROGRAM);
- m_isabus->set_iospace(":maincpu", AS_IO);
+ m_isabus->set_cputag(":maincpu");
m_isabus->irq3_callback().set(FUNC(i82371sb_isa_device::pc_irq3_w));
m_isabus->irq4_callback().set(FUNC(i82371sb_isa_device::pc_irq4_w));
m_isabus->irq5_callback().set(FUNC(i82371sb_isa_device::pc_irq5_w));
@@ -124,7 +123,6 @@ void i82371sb_isa_device::device_add_mconfig(machine_config &config)
m_isabus->drq5_callback().set(m_dma8237_2, FUNC(am9517a_device::dreq1_w));
m_isabus->drq6_callback().set(m_dma8237_2, FUNC(am9517a_device::dreq2_w));
m_isabus->drq7_callback().set(m_dma8237_2, FUNC(am9517a_device::dreq3_w));
- m_isabus->iochck_callback().set(FUNC(i82371sb_isa_device::iochck_w));
}
i82371sb_isa_device::i82371sb_isa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
@@ -658,8 +656,6 @@ WRITE_LINE_MEMBER( i82371sb_isa_device::at_dma8237_out_eop )
void i82371sb_isa_device::pc_select_dma_channel(int channel, bool state)
{
- m_isabus->dack_line_w(channel, state);
-
if(!state) {
m_dma_channel = channel;
if(m_cur_eop)
@@ -822,24 +818,17 @@ WRITE8_MEMBER( i82371sb_isa_device::at_portb_w )
m_pit8254->write_gate2(BIT(data, 0));
at_speaker_set_spkrdata( BIT(data, 1));
m_channel_check = BIT(data, 3);
- if (m_channel_check)
- m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
-}
-
-WRITE_LINE_MEMBER( i82371sb_isa_device::iochck_w )
-{
- if (!state && !m_channel_check && m_nmi_enabled)
- m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
+ m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0));
}
READ8_MEMBER( i82371sb_isa_device::at_dma8237_2_r )
{
- return m_dma8237_2->read(offset / 2);
+ return m_dma8237_2->read( space, offset / 2);
}
WRITE8_MEMBER( i82371sb_isa_device::at_dma8237_2_w )
{
- m_dma8237_2->write(offset / 2, data);
+ m_dma8237_2->write( space, offset / 2, data);
}
READ8_MEMBER(i82371sb_isa_device::eisa_irq_read)
diff --git a/src/devices/machine/i82371sb.h b/src/devices/machine/i82371sb.h
index 5d79eec29ef..ea7976ad845 100644
--- a/src/devices/machine/i82371sb.h
+++ b/src/devices/machine/i82371sb.h
@@ -146,7 +146,6 @@ private:
DECLARE_WRITE8_MEMBER(at_page8_w);
DECLARE_READ8_MEMBER(at_portb_r);
DECLARE_WRITE8_MEMBER(at_portb_w);
- DECLARE_WRITE_LINE_MEMBER(iochck_w);
DECLARE_READ8_MEMBER(ide_read_cs1_r);
DECLARE_WRITE8_MEMBER(ide_write_cs1_w);
DECLARE_READ8_MEMBER(ide2_read_cs1_r);
diff --git a/src/devices/machine/i8251.cpp b/src/devices/machine/i8251.cpp
index 1c3189d8f8f..773262b617e 100644
--- a/src/devices/machine/i8251.cpp
+++ b/src/devices/machine/i8251.cpp
@@ -674,11 +674,9 @@ uint8_t i8251_device::data_r()
{
LOG("read data: %02x, STATUS=%02x\n",m_rx_data,m_status);
/* reading clears */
- if (!machine().side_effects_disabled())
- {
- m_status &= ~I8251_STATUS_RX_READY;
- update_rx_ready();
- }
+ m_status &= ~I8251_STATUS_RX_READY;
+
+ update_rx_ready();
return m_rx_data;
}
diff --git a/src/devices/machine/i8251.h b/src/devices/machine/i8251.h
index f8b92725b05..4e2773c3e40 100644
--- a/src/devices/machine/i8251.h
+++ b/src/devices/machine/i8251.h
@@ -54,7 +54,10 @@ public:
DECLARE_READ_LINE_MEMBER(txrdy_r);
-protected:
+ /// TODO: REMOVE THIS
+ void receive_character(uint8_t ch);
+
+ /// TODO: this shouldn't be public
enum
{
I8251_STATUS_FRAMING_ERROR = 0x20,
@@ -65,6 +68,7 @@ protected:
I8251_STATUS_TX_READY = 0x01
};
+protected:
i8251_device(
const machine_config &mconfig,
device_type type,
@@ -79,8 +83,6 @@ protected:
void command_w(uint8_t data);
void mode_w(uint8_t data);
- void receive_character(uint8_t ch);
-
void update_rx_ready();
void update_tx_ready();
void update_tx_empty();
diff --git a/src/devices/machine/i8271.cpp b/src/devices/machine/i8271.cpp
index 1bac233f955..3a309c4ea16 100644
--- a/src/devices/machine/i8271.cpp
+++ b/src/devices/machine/i8271.cpp
@@ -132,7 +132,7 @@ void i8271_device::set_floppy(floppy_image_device *flop)
flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&i8271_device::index_callback, this));
}
-uint8_t i8271_device::sr_r()
+READ8_MEMBER(i8271_device::sr_r)
{
uint32_t ret = (irq ? SR_IRQ : 0);
switch(main_phase) {
@@ -151,13 +151,11 @@ uint8_t i8271_device::sr_r()
return ret;
}
-uint8_t i8271_device::rr_r()
+READ8_MEMBER(i8271_device::rr_r)
{
- if (!machine().side_effects_disabled()) {
- if (main_phase == PHASE_RESULT)
- main_phase = PHASE_IDLE;
- set_irq(false);
- }
+ if(main_phase == PHASE_RESULT)
+ main_phase = PHASE_IDLE;
+ set_irq(false);
return rr;
}
@@ -166,32 +164,31 @@ void i8271_device::set_rate(int rate)
cur_rate = rate;
}
-uint8_t i8271_device::read(offs_t offset)
+READ8_MEMBER(i8271_device::read)
{
switch(offset & 0x03) {
- case 0x00: return sr_r();
- case 0x01: return rr_r();
+ case 0x00: return sr_r(space, 0);
+ case 0x01: return rr_r(space, 0);
}
return 0xff;
}
-void i8271_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(i8271_device::write)
{
switch(offset & 0x03) {
- case 0x00: cmd_w(data); break;
- case 0x01: param_w(data); break;
- case 0x02: reset_w(data); break;
+ case 0x00: cmd_w(space, 0, data); break;
+ case 0x01: param_w(space, 0, data); break;
+ case 0x02: reset_w(space, 0, data); break;
}
}
-uint8_t i8271_device::data_r()
+READ8_MEMBER(i8271_device::data_r)
{
- if (!machine().side_effects_disabled())
- set_drq(false);
+ set_drq(false);
return dma_data;
}
-void i8271_device::data_w(uint8_t data)
+WRITE8_MEMBER(i8271_device::data_w)
{
if(drq) {
set_drq(false);
@@ -199,7 +196,7 @@ void i8271_device::data_w(uint8_t data)
}
}
-void i8271_device::cmd_w(uint8_t data)
+WRITE8_MEMBER(i8271_device::cmd_w)
{
if(main_phase == PHASE_IDLE) {
command[0] = data;
@@ -214,7 +211,7 @@ void i8271_device::cmd_w(uint8_t data)
}
}
-void i8271_device::param_w(uint8_t data)
+WRITE8_MEMBER(i8271_device::param_w)
{
if(main_phase == PHASE_CMD) {
command[command_pos++] = data;
diff --git a/src/devices/machine/i8271.h b/src/devices/machine/i8271.h
index 88e9a6146e6..701085f58d4 100644
--- a/src/devices/machine/i8271.h
+++ b/src/devices/machine/i8271.h
@@ -24,10 +24,10 @@ public:
auto hdl_wr_callback() { return hdl_cb.bind(); }
auto opt_wr_callback() { return opt_cb.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
- uint8_t data_r();
- void data_w(uint8_t data);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
+ DECLARE_READ8_MEMBER (data_r);
+ DECLARE_WRITE8_MEMBER(data_w);
void ready_w(bool val);
@@ -228,11 +228,11 @@ private:
C_INCOMPLETE
};
- uint8_t sr_r();
- uint8_t rr_r();
- void reset_w(uint8_t data) { if(data == 1) soft_reset(); }
- void cmd_w(uint8_t data);
- void param_w(uint8_t data);
+ DECLARE_READ8_MEMBER (sr_r);
+ DECLARE_READ8_MEMBER (rr_r);
+ DECLARE_WRITE8_MEMBER(reset_w) { if(data == 1) soft_reset(); }
+ DECLARE_WRITE8_MEMBER(cmd_w);
+ DECLARE_WRITE8_MEMBER(param_w);
void delay_cycles(emu_timer *tm, int cycles);
void set_drq(bool state);
diff --git a/src/devices/machine/idectrl.cpp b/src/devices/machine/idectrl.cpp
index 45f6ab6f703..b8ab541fc8d 100644
--- a/src/devices/machine/idectrl.cpp
+++ b/src/devices/machine/idectrl.cpp
@@ -222,7 +222,6 @@ DEFINE_DEVICE_TYPE(BUS_MASTER_IDE_CONTROLLER, bus_master_ide_controller_device,
bus_master_ide_controller_device::bus_master_ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
ide_controller_32_device(mconfig, BUS_MASTER_IDE_CONTROLLER, tag, owner, clock),
- m_dma_space(*this, finder_base::DUMMY_TAG, -1, 32),
m_dma_address(0),
m_dma_bytes_left(0),
m_dma_descriptor(0),
@@ -240,7 +239,17 @@ void bus_master_ide_controller_device::device_start()
ide_controller_32_device::device_start();
/* find the bus master space */
- m_dma_address_xor = (m_dma_space->endianness() == ENDIANNESS_LITTLE) ? 0 : 3;
+ if (m_bmcpu != nullptr)
+ {
+ device_t *bmtarget = machine().device(m_bmcpu);
+ if (bmtarget == nullptr)
+ throw emu_fatalerror("IDE controller '%s' bus master target '%s' doesn't exist!", tag(), m_bmcpu);
+ device_memory_interface *memory;
+ if (!bmtarget->interface(memory))
+ throw emu_fatalerror("IDE controller '%s' bus master target '%s' has no memory!", tag(), m_bmcpu);
+ m_dma_space = &memory->space(m_bmspace);
+ m_dma_address_xor = (m_dma_space->endianness() == ENDIANNESS_LITTLE) ? 0 : 3;
+ }
save_item(NAME(m_dma_address));
save_item(NAME(m_dma_bytes_left));
diff --git a/src/devices/machine/idectrl.h b/src/devices/machine/idectrl.h
index c0e84e3c562..3a0886a5185 100644
--- a/src/devices/machine/idectrl.h
+++ b/src/devices/machine/idectrl.h
@@ -105,7 +105,7 @@ class bus_master_ide_controller_device : public ide_controller_32_device
{
public:
bus_master_ide_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
- template <typename T> void set_bus_master_space(T &&bmtag, int bmspace) { m_dma_space.set_tag(std::forward<T>(bmtag), bmspace); }
+ void set_bus_master_space(const char *bmcpu, uint32_t bmspace) { m_bmcpu = bmcpu; m_bmspace = bmspace; }
template <typename T> bus_master_ide_controller_device &master(T &&opts, const char *dflt = nullptr, bool fixed = false)
{
@@ -140,7 +140,9 @@ protected:
private:
void execute_dma();
- required_address_space m_dma_space;
+ const char *m_bmcpu;
+ uint32_t m_bmspace;
+ address_space *m_dma_space;
uint8_t m_dma_address_xor;
offs_t m_dma_address;
diff --git a/src/devices/machine/idehd.cpp b/src/devices/machine/idehd.cpp
index 1f4be38d491..b9f6ddbbe70 100644
--- a/src/devices/machine/idehd.cpp
+++ b/src/devices/machine/idehd.cpp
@@ -869,7 +869,6 @@ uint8_t ide_hdd_device::calculate_status()
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void ide_hdd_device::device_add_mconfig(machine_config &config)
-{
- HARDDISK(config, "image");
-}
+MACHINE_CONFIG_START(ide_hdd_device::device_add_mconfig)
+ MCFG_HARDDISK_ADD( "image" )
+MACHINE_CONFIG_END
diff --git a/src/devices/machine/ie15.cpp b/src/devices/machine/ie15.cpp
index 65a71ae23c3..4f1a8a25bfc 100644
--- a/src/devices/machine/ie15.cpp
+++ b/src/devices/machine/ie15.cpp
@@ -568,25 +568,25 @@ static GFXDECODE_START( gfx_ie15 )
GFXDECODE_ENTRY("chargen", 0x0000, ie15_charlayout, 0, 1)
GFXDECODE_END
-void ie15_device::ie15core(machine_config &config)
-{
+MACHINE_CONFIG_START(ie15_device::ie15core)
/* Basic machine hardware */
- IE15_CPU(config, m_maincpu, XTAL(30'800'000)/10);
- m_maincpu->set_addrmap(AS_PROGRAM, &ie15_device::ie15_mem);
- m_maincpu->set_addrmap(AS_IO, &ie15_device::ie15_io);
+ MCFG_DEVICE_ADD("maincpu", IE15_CPU, XTAL(30'800'000)/10)
+ MCFG_DEVICE_PROGRAM_MAP(ie15_mem)
+ MCFG_DEVICE_IO_MAP(ie15_io)
config.set_default_layout(layout_ie15);
/* Devices */
- IE15_KEYBOARD(config, m_keyboard, 0).keyboard_cb().set(FUNC(ie15_device::kbd_put));
+ IE15_KEYBOARD(config, m_keyboard, 0)
+ .keyboard_cb().set(FUNC(ie15_device::kbd_put));
RS232_PORT(config, m_rs232, default_rs232_devices, "null_modem");
m_rs232->rxd_handler().set(FUNC(ie15_device::serial_rx_callback));
SPEAKER(config, "mono").front_center();
- BEEP(config, m_beeper, 2400);
- m_beeper->add_route(ALL_OUTPUTS, "mono", 0.15);
-}
+ MCFG_DEVICE_ADD("beeper", BEEP, 2400)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
+MACHINE_CONFIG_END
/* ROM definition */
ROM_START( ie15 )
@@ -603,20 +603,18 @@ ROM_START( ie15 )
ROM_LOAD("chargen-15ie.bin", 0x0000, 0x0800, CRC(ed16bf6b) SHA1(6af9fb75f5375943d5c0ce9ed408e0fb4621b17e))
ROM_END
-void ie15_device::device_add_mconfig(machine_config &config)
-{
- SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
- m_screen->set_color(rgb_t::green());
- m_screen->set_screen_update(FUNC(ie15_device::screen_update));
- m_screen->set_raw(XTAL(30'800'000)/2,
+MACHINE_CONFIG_START(ie15_device::device_add_mconfig)
+ MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green())
+ MCFG_SCREEN_UPDATE_DRIVER(ie15_device, screen_update)
+ MCFG_SCREEN_RAW_PARAMS(XTAL(30'800'000)/2,
IE15_TOTAL_HORZ, IE15_HORZ_START, IE15_HORZ_START+IE15_DISP_HORZ,
IE15_TOTAL_VERT, IE15_VERT_START, IE15_VERT_START+IE15_DISP_VERT);
ie15core(config);
- GFXDECODE(config, "gfxdecode", "palette", gfx_ie15);
+ MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_ie15)
PALETTE(config, "palette", palette_device::MONOCHROME);
-}
+MACHINE_CONFIG_END
ioport_constructor ie15_device::device_input_ports() const
{
diff --git a/src/devices/machine/ie15_kbd.cpp b/src/devices/machine/ie15_kbd.cpp
index 79a4bb86aad..13ee3ea5744 100644
--- a/src/devices/machine/ie15_kbd.cpp
+++ b/src/devices/machine/ie15_kbd.cpp
@@ -122,9 +122,8 @@ const tiny_rom_entry *ie15_keyboard_device::device_rom_region() const
return ROM_NAME( ie15_keyboard );
}
-void ie15_keyboard_device::device_add_mconfig(machine_config &config)
-{
-}
+MACHINE_CONFIG_START(ie15_keyboard_device::device_add_mconfig)
+MACHINE_CONFIG_END
void ie15_keyboard_device::device_start()
diff --git a/src/devices/machine/input_merger.h b/src/devices/machine/input_merger.h
index aa5e66cc1f1..53af1a38cfd 100644
--- a/src/devices/machine/input_merger.h
+++ b/src/devices/machine/input_merger.h
@@ -15,6 +15,27 @@
#pragma once
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_INPUT_MERGER_ANY_HIGH(_tag) \
+ MCFG_DEVICE_ADD(_tag, INPUT_MERGER_ANY_HIGH, 0)
+
+#define MCFG_INPUT_MERGER_ALL_HIGH(_tag) \
+ MCFG_DEVICE_ADD(_tag, INPUT_MERGER_ALL_HIGH, 0)
+
+#define MCFG_INPUT_MERGER_ANY_LOW(_tag) \
+ MCFG_DEVICE_ADD(_tag, INPUT_MERGER_ANY_LOW, 0)
+
+#define MCFG_INPUT_MERGER_ALL_LOW(_tag) \
+ MCFG_DEVICE_ADD(_tag, INPUT_MERGER_ALL_LOW, 0)
+
+#define MCFG_INPUT_MERGER_OUTPUT_HANDLER(_devcb) \
+ downcast<input_merger_device &>(*device).set_output_handler(DEVCB_##_devcb);
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -23,6 +44,7 @@ class input_merger_device : public device_t
{
public:
// callback
+ template <class Object> devcb_base &set_output_handler(Object &&cb) { return m_output_handler.set_callback(std::forward<Object>(cb)); }
auto output_handler() { return m_output_handler.bind(); }
// input lines
diff --git a/src/devices/machine/ins8154.cpp b/src/devices/machine/ins8154.cpp
index 11943cdee2c..8a134000f3f 100644
--- a/src/devices/machine/ins8154.cpp
+++ b/src/devices/machine/ins8154.cpp
@@ -1,24 +1,21 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
-/******************************************************************************
+/***************************************************************************
National Semiconductor INS8154
N-Channel 128-by-8 Bit RAM Input/Output (RAM I/O)
TODO: Strobed modes
- TODO: Check the ODRx register for where to get pin values, _cb() vs m_out_x
-*******************************************************************************/
+***************************************************************************/
#include "emu.h"
#include "ins8154.h"
-#define LOG_BITS (1U << 1)
-//#define VERBOSE (LOG_BITS) // (LOG_GENERAL|LOG_BITS)
+#define VERBOSE 1
#include "logmacro.h"
-#define LOGBITS(...) LOGMASKED(LOG_BITS, __VA_ARGS__)
/***************************************************************************
CONSTANTS
@@ -78,7 +75,6 @@ void ins8154_device::device_start()
save_item(NAME(m_mdr));
save_item(NAME(m_odra));
save_item(NAME(m_odrb));
- save_item(NAME(m_ram));
}
@@ -98,7 +94,7 @@ void ins8154_device::device_reset()
}
-uint8_t ins8154_device::read_io(offs_t offset)
+READ8_MEMBER(ins8154_device::ins8154_r)
{
uint8_t val = 0xff;
@@ -123,23 +119,17 @@ uint8_t ins8154_device::read_io(offs_t offset)
break;
default:
- val = 0;
- if (offset < 0x08) // Read a bit in Port A
+ if (offset < 0x08)
{
if (!m_in_a_cb.isnull())
- {
- //val = (m_in_a_cb(0) << (8 - offset)) & 0x80;
- val = (m_in_a_cb(0) & ~m_odra & (1 << (offset & 0x07))) ? 0x80 : 0x00;
- }
- LOGBITS("%s: INS8154 Port A read bit %02x: %02x\n", machine().describe_context(), offset & 0x07, val);
+ val = (m_in_a_cb(0) << (8 - offset)) & 0x80;
+ m_in_a = val;
}
- else // Read a bit in Port B
+ else
{
if (!m_in_b_cb.isnull())
- {
- val = (m_in_b_cb(0) & ~m_odrb & (1 << (offset & 0x07))) ? 0x80 : 0x00;
- }
- LOGBITS("%s: INS8154 Port B read bit %02x: %02x\n", machine().describe_context(), offset & 0x07, val);
+ val = (m_in_b_cb(0) << (8 - (offset >> 4))) & 0x80;
+ m_in_b = val;
}
break;
}
@@ -147,12 +137,7 @@ uint8_t ins8154_device::read_io(offs_t offset)
return val;
}
-uint8_t ins8154_device::read_ram(offs_t offset)
-{
- return m_ram[offset & 0x7f];
-}
-
-void ins8154_device::porta_w(uint8_t data)
+WRITE8_MEMBER(ins8154_device::ins8154_porta_w)
{
m_out_a = data;
@@ -161,9 +146,8 @@ void ins8154_device::porta_w(uint8_t data)
m_out_a_cb(offs_t(0), (data & m_odra) | (m_odra ^ 0xff));
}
-void ins8154_device::portb_w(uint8_t data)
+WRITE8_MEMBER(ins8154_device::ins8154_portb_w)
{
- LOG("%s: INS8154 Write PortB %02x with odrb: %02x\n", machine().describe_context(), data, m_odrb);
m_out_b = data;
/* Test if any pins are set as outputs */
@@ -171,7 +155,7 @@ void ins8154_device::portb_w(uint8_t data)
m_out_b_cb(offs_t(0), (data & m_odrb) | (m_odrb ^ 0xff));
}
-void ins8154_device::write_io(offs_t offset, uint8_t data)
+WRITE8_MEMBER(ins8154_device::ins8154_w)
{
if (offset > 0x24)
{
@@ -182,11 +166,11 @@ void ins8154_device::write_io(offs_t offset, uint8_t data)
switch (offset)
{
case 0x20:
- porta_w(data);
+ ins8154_porta_w(space, 0, data);
break;
case 0x21:
- portb_w(data);
+ ins8154_portb_w(space, 0, data);
break;
case 0x22:
@@ -209,35 +193,18 @@ void ins8154_device::write_io(offs_t offset, uint8_t data)
{
/* Set bit */
if (offset < 0x08)
- {
- LOGBITS("%s: INS8154 Port A set bit %02x\n", machine().describe_context(), offset & 0x07);
- porta_w(m_out_a |= (1 << (offset & 0x07)));
- }
+ ins8154_porta_w(space, 0, m_out_a |= offset & 0x07);
else
- {
- LOGBITS("%s: INS8154 Port B set bit %02x\n", machine().describe_context(), offset & 0x07);
- portb_w(m_out_b |= (1 << (offset & 0x07)));
- }
+ ins8154_portb_w(space, 0, m_out_b |= (offset >> 4) & 0x07);
}
else
{
/* Clear bit */
if (offset < 0x08)
- {
- LOGBITS("%s: INS8154 Port A clear bit %02x\n", machine().describe_context(), offset & 0x07);
- porta_w(m_out_a & ~(1 << (offset & 0x07)));
- }
+ ins8154_porta_w(space, 0, m_out_a & ~(offset & 0x07));
else
- {
- LOGBITS("%s: INS8154 Port B clear bit %02x\n", machine().describe_context(), offset & 0x07);
- portb_w(m_out_b & ~(1 << (offset & 0x07)));
- }
+ ins8154_portb_w(space, 0, m_out_b & ~((offset >> 4) & 0x07));
}
break;
}
}
-
-void ins8154_device::write_ram(offs_t offset, uint8_t data)
-{
- m_ram[offset & 0x7f] = data;
-}
diff --git a/src/devices/machine/ins8154.h b/src/devices/machine/ins8154.h
index 2ce40ec9e70..5ba94ab9cda 100644
--- a/src/devices/machine/ins8154.h
+++ b/src/devices/machine/ins8154.h
@@ -47,13 +47,11 @@ public:
auto out_b() { return m_out_b_cb.bind(); }
auto out_irq() { return m_out_irq_cb.bind(); }
- uint8_t read_io(offs_t offset);
- void write_io(offs_t offset, uint8_t data);
- uint8_t read_ram(offs_t offset);
- void write_ram(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( ins8154_r );
+ DECLARE_WRITE8_MEMBER( ins8154_w );
- void porta_w(uint8_t data);
- void portb_w(uint8_t data);
+ DECLARE_WRITE8_MEMBER( ins8154_porta_w );
+ DECLARE_WRITE8_MEMBER( ins8154_portb_w );
protected:
// device-level overrides
@@ -79,9 +77,6 @@ private:
uint8_t m_mdr; /* Mode Definition Register */
uint8_t m_odra; /* Output Definition Register Port A */
uint8_t m_odrb; /* Output Definition Register Port B */
-
- /* on-board RAM */
- uint8_t m_ram[0x80];
};
diff --git a/src/devices/machine/ins8250.cpp b/src/devices/machine/ins8250.cpp
index d127ce0e40d..88262cdbac2 100644
--- a/src/devices/machine/ins8250.cpp
+++ b/src/devices/machine/ins8250.cpp
@@ -390,8 +390,6 @@ WRITE8_MEMBER( ins8250_uart_device::ins8250_w )
if ( m_regs.msr & 0x0f )
trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
- else
- clear_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
break;
case 7:
m_regs.scr = data;
diff --git a/src/devices/machine/intelfsh.h b/src/devices/machine/intelfsh.h
index edaa23d69f6..7dcf9f7e173 100644
--- a/src/devices/machine/intelfsh.h
+++ b/src/devices/machine/intelfsh.h
@@ -102,8 +102,8 @@ class intelfsh8_device : public intelfsh_device
{
public:
// public interface
- uint8_t read(offs_t offset) { return read_full(offset); }
- void write(offs_t offset, uint8_t data) { write_full(offset, data); }
+ DECLARE_READ8_MEMBER(read) { return read_full(offset); }
+ DECLARE_WRITE8_MEMBER(write) { write_full(offset, data); }
uint8_t read_raw(offs_t offset) { return m_data[offset]; }
void write_raw(offs_t offset, uint8_t data) { m_data[offset] = data; }
@@ -120,8 +120,8 @@ class intelfsh16_device : public intelfsh_device
{
public:
// public interface
- uint16_t read(offs_t offset) { return read_full(offset); }
- void write(offs_t offset, uint16_t data) { write_full(offset, data); }
+ DECLARE_READ16_MEMBER(read) { return read_full(offset); }
+ DECLARE_WRITE16_MEMBER(write) { write_full(offset, data); }
uint16_t read_raw(offs_t offset) { return m_data[offset*2] | (m_data[offset*2+1] << 8); }
void write_raw(offs_t offset, uint16_t data) { m_data[offset*2] = data; m_data[offset*2+1] = data >> 8; }
diff --git a/src/devices/machine/k054321.cpp b/src/devices/machine/k054321.cpp
index 592bc74582a..21e02e9042f 100644
--- a/src/devices/machine/k054321.cpp
+++ b/src/devices/machine/k054321.cpp
@@ -11,7 +11,7 @@
/*
The 054321 is a sound communication latch/volume manager chip, that
- is integrated into the 054544 and 054986A hybrid chips. The hybrid
+ is integrated into the 054544 and 05489A hybrid chips. The hybrid
chips also include the DACs, capacitors, etc needed for the audio
output.
diff --git a/src/devices/machine/keyboard.cpp b/src/devices/machine/keyboard.cpp
index 52502597227..03e73f3ac05 100644
--- a/src/devices/machine/keyboard.cpp
+++ b/src/devices/machine/keyboard.cpp
@@ -9,10 +9,10 @@ or for the case of a computer with an inbuilt (not serial) ascii keyboard.
Example of usage in a driver.
-In the machine config function:
+In MACHINE_CONFIG
- generic_keyboard_device &kbd(GENERIC_KEYBOARD(config, KEYBOARD_TAG, 0));
- kbd.set_keyboard_callback(FUNC(xxx_state::kbd_put));
+ MCFG_DEVICE_ADD(KEYBOARD_TAG, GENERIC_KEYBOARD, 0)
+ MCFG_GENERIC_KEYBOARD_CB(WRITE8(*this, xxx_state, kbd_put))
In the code:
diff --git a/src/devices/machine/ldp1000.h b/src/devices/machine/ldp1000.h
index b3f420afb6e..1f3140f14e8 100644
--- a/src/devices/machine/ldp1000.h
+++ b/src/devices/machine/ldp1000.h
@@ -15,6 +15,13 @@
//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_LASERDISC_LDP1000_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, SONY_LDP1000, 0)
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
diff --git a/src/devices/machine/ldp1450.h b/src/devices/machine/ldp1450.h
index 67a429845e1..3ef9fab0939 100644
--- a/src/devices/machine/ldp1450.h
+++ b/src/devices/machine/ldp1450.h
@@ -15,6 +15,13 @@
//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_LASERDISC_LDP1450_ADD(_tag, clock) \
+ MCFG_DEVICE_ADD(_tag, SONY_LDP1450, clock)
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
diff --git a/src/devices/machine/ldpr8210.h b/src/devices/machine/ldpr8210.h
index fc0a28d6d26..f142229314c 100644
--- a/src/devices/machine/ldpr8210.h
+++ b/src/devices/machine/ldpr8210.h
@@ -23,6 +23,8 @@
#define MCFG_LASERDISC_PR8210_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, PIONEER_PR8210, 0)
+#define MCFG_LASERDISC_SIMUTREK_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, SIMUTREK_SPECIAL, 0)
//**************************************************************************
diff --git a/src/devices/machine/ldstub.cpp b/src/devices/machine/ldstub.cpp
index c0c9a7ac05a..9d3dab58ce3 100644
--- a/src/devices/machine/ldstub.cpp
+++ b/src/devices/machine/ldstub.cpp
@@ -17,8 +17,8 @@
//**************************************************************************
// device type definition
-DEFINE_DEVICE_TYPE(PIONEER_PR7820, pioneer_pr7820_device, "pr7820", "Pioneer PR-7820")
-DEFINE_DEVICE_TYPE(PHILIPS_22VP932, philips_22vp932_device, "22vp932", "Philips 22VP932")
+DEFINE_DEVICE_TYPE(PIONEER_PR7820, pioneer_pr7820_device, "pr7820", "Pioneer PR-7820")
+DEFINE_DEVICE_TYPE(PHILLIPS_22VP932, phillips_22vp932_device, "22vp932", "Phillips 22VP932")
pioneer_pr7820_device::pioneer_pr7820_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -27,7 +27,7 @@ pioneer_pr7820_device::pioneer_pr7820_device(const machine_config &mconfig, cons
}
-philips_22vp932_device::philips_22vp932_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : laserdisc_device(mconfig, PHILIPS_22VP932, tag, owner, clock)
+phillips_22vp932_device::phillips_22vp932_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : laserdisc_device(mconfig, PHILLIPS_22VP932, tag, owner, clock)
{
}
diff --git a/src/devices/machine/ldstub.h b/src/devices/machine/ldstub.h
index 9fbc756b240..4bf463b897d 100644
--- a/src/devices/machine/ldstub.h
+++ b/src/devices/machine/ldstub.h
@@ -17,12 +17,23 @@
//**************************************************************************
+// DEVICE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_LASERDISC_PR7820_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, PIONEER_PR7820, 0)
+#define MCFG_LASERDISC_22VP932_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, PHILLIPS_22VP932, 0)
+
+
+//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
-DECLARE_DEVICE_TYPE(PIONEER_PR7820, pioneer_pr7820_device)
-DECLARE_DEVICE_TYPE(PHILIPS_22VP932, philips_22vp932_device)
+DECLARE_DEVICE_TYPE(PIONEER_PR7820, pioneer_pr7820_device)
+DECLARE_DEVICE_TYPE(PHILLIPS_22VP932, phillips_22vp932_device)
+
//**************************************************************************
@@ -52,13 +63,13 @@ protected:
};
-// ======================> philips_22vp932_device
+// ======================> phillips_22vp932_device
-class philips_22vp932_device : public laserdisc_device
+class phillips_22vp932_device : public laserdisc_device
{
public:
// construction/destruction
- philips_22vp932_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ phillips_22vp932_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// input/output
uint8_t data_r() { return 0; }
diff --git a/src/devices/machine/ldv1000.cpp b/src/devices/machine/ldv1000.cpp
index 4f7a0196e40..4a9b1295b75 100644
--- a/src/devices/machine/ldv1000.cpp
+++ b/src/devices/machine/ldv1000.cpp
@@ -272,8 +272,7 @@ const tiny_rom_entry *pioneer_ldv1000_device::device_rom_region() const
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void pioneer_ldv1000_device::device_add_mconfig(machine_config &config)
-{
+MACHINE_CONFIG_START(pioneer_ldv1000_device::device_add_mconfig)
Z80(config, m_z80_cpu, XTAL(5'000'000)/2);
m_z80_cpu->set_daisy_config(daisy_chain);
m_z80_cpu->set_addrmap(AS_PROGRAM, &pioneer_ldv1000_device::ldv1000_map);
@@ -292,7 +291,7 @@ void pioneer_ldv1000_device::device_add_mconfig(machine_config &config)
ldvppi1.in_pa_callback().set(FUNC(pioneer_ldv1000_device::ppi1_porta_r));
ldvppi1.out_pb_callback().set(FUNC(pioneer_ldv1000_device::ppi1_portb_w));
ldvppi1.out_pc_callback().set(FUNC(pioneer_ldv1000_device::ppi1_portc_w));
-}
+MACHINE_CONFIG_END
//-------------------------------------------------
diff --git a/src/devices/machine/ldv1000.h b/src/devices/machine/ldv1000.h
index 55516da36fe..661d0a44f0b 100644
--- a/src/devices/machine/ldv1000.h
+++ b/src/devices/machine/ldv1000.h
@@ -26,6 +26,10 @@
#define MCFG_LASERDISC_LDV1000_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, PIONEER_LDV1000, 0)
+#define MCFG_LASERDISC_LDV1000_COMMAND_STROBE_CB(_cb) \
+ downcast<pioneer_ldv1000_device *>(device)->set_command_strobe_callback(DEVCB_##_cb);
+
+
//**************************************************************************
// GLOBAL VARIABLES
@@ -49,7 +53,7 @@ public:
// construction/destruction
pioneer_ldv1000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- auto command_strobe_callback() { return m_command_strobe_cb.bind(); }
+ template <class cmd_strobe_cb> devcb_base &set_command_strobe_callback(cmd_strobe_cb &&latch) { return m_command_strobe_cb.set_callback(std::forward<cmd_strobe_cb>(latch)); }
// input and output
void data_w(uint8_t data);
diff --git a/src/devices/machine/ldvp931.cpp b/src/devices/machine/ldvp931.cpp
index 4bcb74e1b6a..7a688736a93 100644
--- a/src/devices/machine/ldvp931.cpp
+++ b/src/devices/machine/ldvp931.cpp
@@ -45,7 +45,7 @@
//**************************************************************************
// devices
-DEFINE_DEVICE_TYPE(PHILIPS_22VP931, philips_22vp931_device, "22vp931", "Philips 22VP931")
+DEFINE_DEVICE_TYPE(PHILLIPS_22VP931, phillips_22vp931_device, "22vp931", "Phillips 22VP931")
@@ -53,12 +53,12 @@ DEFINE_DEVICE_TYPE(PHILIPS_22VP931, philips_22vp931_device, "22vp931", "Philips
// 22VP931 ROM AND MACHINE INTERFACES
//**************************************************************************
-void philips_22vp931_device::vp931_portmap(address_map &map)
+void phillips_22vp931_device::vp931_portmap(address_map &map)
{
- map(0x00, 0x00).mirror(0xcf).rw(FUNC(philips_22vp931_device::i8049_keypad_r), FUNC(philips_22vp931_device::i8049_output0_w));
- map(0x10, 0x10).mirror(0xcf).rw(FUNC(philips_22vp931_device::i8049_unknown_r), FUNC(philips_22vp931_device::i8049_output1_w));
- map(0x20, 0x20).mirror(0xcf).rw(FUNC(philips_22vp931_device::i8049_datic_r), FUNC(philips_22vp931_device::i8049_lcd_w));
- map(0x30, 0x30).mirror(0xcf).rw(FUNC(philips_22vp931_device::i8049_from_controller_r), FUNC(philips_22vp931_device::i8049_to_controller_w));
+ map(0x00, 0x00).mirror(0xcf).rw(FUNC(phillips_22vp931_device::i8049_keypad_r), FUNC(phillips_22vp931_device::i8049_output0_w));
+ map(0x10, 0x10).mirror(0xcf).rw(FUNC(phillips_22vp931_device::i8049_unknown_r), FUNC(phillips_22vp931_device::i8049_output1_w));
+ map(0x20, 0x20).mirror(0xcf).rw(FUNC(phillips_22vp931_device::i8049_datic_r), FUNC(phillips_22vp931_device::i8049_lcd_w));
+ map(0x30, 0x30).mirror(0xcf).rw(FUNC(phillips_22vp931_device::i8049_from_controller_r), FUNC(phillips_22vp931_device::i8049_to_controller_w));
}
@@ -70,15 +70,15 @@ ROM_END
//**************************************************************************
-// PHILIPS 22VP931 IMPLEMENTATION
+// PHILLIPS 22VP931 IMPLEMENTATION
//**************************************************************************
//-------------------------------------------------
-// philips_22vp931_device - constructor
+// phillips_22vp931_device - constructor
//-------------------------------------------------
-philips_22vp931_device::philips_22vp931_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : laserdisc_device(mconfig, PHILIPS_22VP931, tag, owner, clock),
+phillips_22vp931_device::phillips_22vp931_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : laserdisc_device(mconfig, PHILLIPS_22VP931, tag, owner, clock),
m_i8049_cpu(*this, "vp931"),
m_tracktimer(nullptr),
m_i8049_out0(0),
@@ -103,7 +103,7 @@ philips_22vp931_device::philips_22vp931_device(const machine_config &mconfig, co
// reset_w - write to the reset line
//-------------------------------------------------
-void philips_22vp931_device::reset_w(uint8_t data)
+void phillips_22vp931_device::reset_w(uint8_t data)
{
// control the CPU state
m_i8049_cpu->set_input_line(INPUT_LINE_RESET, data);
@@ -119,7 +119,7 @@ void philips_22vp931_device::reset_w(uint8_t data)
// 22VP931
//-------------------------------------------------
-uint8_t philips_22vp931_device::data_r()
+uint8_t phillips_22vp931_device::data_r()
{
// if data is pending, clear the pending flag and notify any callbacks
if (m_tocontroller_pending)
@@ -139,7 +139,7 @@ uint8_t philips_22vp931_device::data_r()
// device_start - device initialization
//-------------------------------------------------
-void philips_22vp931_device::device_start()
+void phillips_22vp931_device::device_start()
{
// pass through to the parent
laserdisc_device::device_start();
@@ -153,7 +153,7 @@ void philips_22vp931_device::device_start()
// device_reset - device reset
//-------------------------------------------------
-void philips_22vp931_device::device_reset()
+void phillips_22vp931_device::device_reset()
{
// pass through to the parent
laserdisc_device::device_reset();
@@ -185,7 +185,7 @@ void philips_22vp931_device::device_reset()
// device
//-------------------------------------------------
-void philips_22vp931_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+void phillips_22vp931_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
@@ -276,7 +276,7 @@ void philips_22vp931_device::device_timer(emu_timer &timer, device_timer_id id,
// ROM region definitions
//-------------------------------------------------
-const tiny_rom_entry *philips_22vp931_device::device_rom_region() const
+const tiny_rom_entry *phillips_22vp931_device::device_rom_region() const
{
return ROM_NAME(vp931);
}
@@ -286,16 +286,16 @@ const tiny_rom_entry *philips_22vp931_device::device_rom_region() const
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void philips_22vp931_device::device_add_mconfig(machine_config &config)
+void phillips_22vp931_device::device_add_mconfig(machine_config &config)
{
I8049(config, m_i8049_cpu, XTAL(11'000'000));
- m_i8049_cpu->set_addrmap(AS_IO, &philips_22vp931_device::vp931_portmap);
- m_i8049_cpu->p1_in_cb().set(FUNC(philips_22vp931_device::i8049_port1_r));
- m_i8049_cpu->p1_out_cb().set(FUNC(philips_22vp931_device::i8049_port1_w));
- m_i8049_cpu->p2_in_cb().set(FUNC(philips_22vp931_device::i8049_port2_r));
- m_i8049_cpu->p2_out_cb().set(FUNC(philips_22vp931_device::i8049_port2_w));
- m_i8049_cpu->t0_in_cb().set(FUNC(philips_22vp931_device::i8049_t0_r));
- m_i8049_cpu->t1_in_cb().set(FUNC(philips_22vp931_device::i8049_t1_r));
+ m_i8049_cpu->set_addrmap(AS_IO, &phillips_22vp931_device::vp931_portmap);
+ m_i8049_cpu->p1_in_cb().set(FUNC(phillips_22vp931_device::i8049_port1_r));
+ m_i8049_cpu->p1_out_cb().set(FUNC(phillips_22vp931_device::i8049_port1_w));
+ m_i8049_cpu->p2_in_cb().set(FUNC(phillips_22vp931_device::i8049_port2_r));
+ m_i8049_cpu->p2_out_cb().set(FUNC(phillips_22vp931_device::i8049_port2_w));
+ m_i8049_cpu->t0_in_cb().set(FUNC(phillips_22vp931_device::i8049_t0_r));
+ m_i8049_cpu->t1_in_cb().set(FUNC(phillips_22vp931_device::i8049_t1_r));
}
@@ -304,7 +304,7 @@ void philips_22vp931_device::device_add_mconfig(machine_config &config)
// start of the blanking period
//-------------------------------------------------
-void philips_22vp931_device::player_vsync(const vbi_metadata &vbi, int fieldnum, const attotime &curtime)
+void phillips_22vp931_device::player_vsync(const vbi_metadata &vbi, int fieldnum, const attotime &curtime)
{
// reset our command counter (debugging only)
m_cmdcount = 0;
@@ -320,7 +320,7 @@ void philips_22vp931_device::player_vsync(const vbi_metadata &vbi, int fieldnum,
// the first visible line of the frame
//-------------------------------------------------
-int32_t philips_22vp931_device::player_update(const vbi_metadata &vbi, int fieldnum, const attotime &curtime)
+int32_t phillips_22vp931_device::player_update(const vbi_metadata &vbi, int fieldnum, const attotime &curtime)
{
// set the first VBI timer to go at the start of line 16
timer_set(screen().time_until_pos(16*2), TID_VBI_DATA_FETCH, LASERDISC_CODE_LINE16 << 2);
@@ -335,7 +335,7 @@ int32_t philips_22vp931_device::player_update(const vbi_metadata &vbi, int field
// and other bits
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_output0_w )
+WRITE8_MEMBER( phillips_22vp931_device::i8049_output0_w )
{
/*
$80 = n/c
@@ -374,7 +374,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_output0_w )
// i8049_output1_w - controls scanning behaviors
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_output1_w )
+WRITE8_MEMBER( phillips_22vp931_device::i8049_output1_w )
{
/*
$80 = n/c
@@ -418,7 +418,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_output1_w )
// i8049_lcd_w - vestigial LCD frame display
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_lcd_w )
+WRITE8_MEMBER( phillips_22vp931_device::i8049_lcd_w )
{
/*
Frame number is written as 5 digits here; however, it is not actually
@@ -431,7 +431,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_lcd_w )
// i8049_unknown_r - unknown input port
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_unknown_r )
+READ8_MEMBER( phillips_22vp931_device::i8049_unknown_r )
{
// only bit $80 is checked and its effects are minor
return 0x00;
@@ -443,7 +443,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_unknown_r )
// controls
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_keypad_r )
+READ8_MEMBER( phillips_22vp931_device::i8049_keypad_r )
{
/*
From the code, this is apparently a vestigial keypad with basic controls:
@@ -465,7 +465,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_keypad_r )
// DATIC circuit
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_datic_r )
+READ8_MEMBER( phillips_22vp931_device::i8049_datic_r )
{
return m_daticval;
}
@@ -476,7 +476,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_datic_r )
// external controller wrote
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_from_controller_r )
+READ8_MEMBER( phillips_22vp931_device::i8049_from_controller_r )
{
// clear the pending flag and return the data
m_fromcontroller_pending = false;
@@ -489,7 +489,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_from_controller_r )
// the external controller
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_to_controller_w )
+WRITE8_MEMBER( phillips_22vp931_device::i8049_to_controller_w )
{
// set the pending flag and stash the data
m_tocontroller_pending = true;
@@ -508,7 +508,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_to_controller_w )
// i8049_port1_r - read the 8048 I/O port 1
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_port1_r )
+READ8_MEMBER( phillips_22vp931_device::i8049_port1_r )
{
/*
$80 = P17 = (in) unsure
@@ -527,7 +527,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_port1_r )
// i8049_port1_w - write the 8048 I/O port 1
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_port1_w )
+WRITE8_MEMBER( phillips_22vp931_device::i8049_port1_w )
{
/*
$10 = P14 = (out) D104 -> /SPEED
@@ -598,7 +598,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_port1_w )
// i8049_port2_r - read from the 8048 I/O port 2
//-------------------------------------------------
-READ8_MEMBER( philips_22vp931_device::i8049_port2_r )
+READ8_MEMBER( phillips_22vp931_device::i8049_port2_r )
{
/*
$80 = P27 = (in) set/reset latch; set by FOC LS, reset by IGR
@@ -619,7 +619,7 @@ READ8_MEMBER( philips_22vp931_device::i8049_port2_r )
// i8049_port2_w - write the 8048 I/O port 2
//-------------------------------------------------
-WRITE8_MEMBER( philips_22vp931_device::i8049_port2_w )
+WRITE8_MEMBER( phillips_22vp931_device::i8049_port2_w )
{
/*
$40 = P26 = (out) cleared while data is sent back & forth; set afterwards
@@ -633,7 +633,7 @@ WRITE8_MEMBER( philips_22vp931_device::i8049_port2_w )
// connected to the DATIC's data strobe line
//-------------------------------------------------
-READ_LINE_MEMBER( philips_22vp931_device::i8049_t0_r )
+READ_LINE_MEMBER( phillips_22vp931_device::i8049_t0_r )
{
return m_datastrobe;
}
@@ -645,7 +645,7 @@ READ_LINE_MEMBER( philips_22vp931_device::i8049_t0_r )
// to count the number of tracks advanced
//-------------------------------------------------
-READ_LINE_MEMBER( philips_22vp931_device::i8049_t1_r )
+READ_LINE_MEMBER( phillips_22vp931_device::i8049_t1_r )
{
return m_trackstate;
}
diff --git a/src/devices/machine/ldvp931.h b/src/devices/machine/ldvp931.h
index fd69f52429e..0bf2e263558 100644
--- a/src/devices/machine/ldvp931.h
+++ b/src/devices/machine/ldvp931.h
@@ -18,11 +18,19 @@
//**************************************************************************
+// DEVICE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_LASERDISC_22VP931_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, PHILLIPS_22VP931, 0)
+
+
+//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
-DECLARE_DEVICE_TYPE(PHILIPS_22VP931, philips_22vp931_device)
+DECLARE_DEVICE_TYPE(PHILLIPS_22VP931, phillips_22vp931_device)
@@ -30,17 +38,17 @@ DECLARE_DEVICE_TYPE(PHILIPS_22VP931, philips_22vp931_device)
// TYPE DEFINITIONS
//**************************************************************************
-// ======================> philips_22vp931_device
+// ======================> phillips_22vp931_device
// base _22vp931 class
-class philips_22vp931_device : public laserdisc_device
+class phillips_22vp931_device : public laserdisc_device
{
public:
// types
- typedef delegate<void (philips_22vp931_device &, int)> data_ready_delegate;
+ typedef delegate<void (phillips_22vp931_device &, int)> data_ready_delegate;
// construction/destruction
- philips_22vp931_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ phillips_22vp931_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// input and output
void data_w(uint8_t data) { synchronize(TID_DEFERRED_DATA, data); }
diff --git a/src/devices/machine/legscsi.h b/src/devices/machine/legscsi.h
index 229580bc0bf..fee1b333061 100644
--- a/src/devices/machine/legscsi.h
+++ b/src/devices/machine/legscsi.h
@@ -7,6 +7,8 @@
#include "bus/scsi/scsihle.h"
+#define MCFG_LEGACY_SCSI_PORT(_tag) \
+ downcast<legacy_scsi_host_adapter &>(*device).set_scsi_port(_tag);
class legacy_scsi_host_adapter : public device_t
{
diff --git a/src/devices/machine/mb8421.cpp b/src/devices/machine/mb8421.cpp
index e6344843f92..a5b08f5ea90 100644
--- a/src/devices/machine/mb8421.cpp
+++ b/src/devices/machine/mb8421.cpp
@@ -129,14 +129,14 @@ void mb8421_master_device::update_intr(offs_t offset)
// (write to 7FF asserts INTR)
//-------------------------------------------------
-void mb8421_device::left_w(offs_t offset, u8 data)
+WRITE8_MEMBER(mb8421_device::left_w)
{
offset &= 0x7ff;
m_ram[offset] = data;
update_intr<read_or_write::WRITE, false>(offset);
}
-void mb8421_mb8431_16_device::left_w(offs_t offset, u16 data, u16 mem_mask)
+WRITE16_MEMBER(mb8421_mb8431_16_device::left_w)
{
offset &= 0x7ff;
COMBINE_DATA(&m_ram[offset]);
@@ -148,14 +148,14 @@ void mb8421_mb8431_16_device::left_w(offs_t offset, u16 data, u16 mem_mask)
// (read from 7FE acknowledges INTL)
//-------------------------------------------------
-u8 mb8421_device::left_r(offs_t offset)
+READ8_MEMBER(mb8421_device::left_r)
{
offset &= 0x7ff;
update_intr<read_or_write::READ, false>(offset);
return m_ram[offset];
}
-u16 mb8421_mb8431_16_device::left_r(offs_t offset, u16 mem_mask)
+READ16_MEMBER(mb8421_mb8431_16_device::left_r)
{
offset &= 0x7ff;
update_intr<read_or_write::READ, false>(offset);
@@ -167,14 +167,14 @@ u16 mb8421_mb8431_16_device::left_r(offs_t offset, u16 mem_mask)
// (write to 7FE asserts INTL)
//-------------------------------------------------
-void mb8421_device::right_w(offs_t offset, u8 data)
+WRITE8_MEMBER(mb8421_device::right_w)
{
offset &= 0x7ff;
m_ram[offset] = data;
update_intr<read_or_write::WRITE, true>(offset);
}
-void mb8421_mb8431_16_device::right_w(offs_t offset, u16 data, u16 mem_mask)
+WRITE16_MEMBER(mb8421_mb8431_16_device::right_w)
{
offset &= 0x7ff;
COMBINE_DATA(&m_ram[offset]);
@@ -186,14 +186,14 @@ void mb8421_mb8431_16_device::right_w(offs_t offset, u16 data, u16 mem_mask)
// (read from 7FF acknowledges INTR)
//-------------------------------------------------
-u8 mb8421_device::right_r(offs_t offset)
+READ8_MEMBER(mb8421_device::right_r)
{
offset &= 0x7ff;
update_intr<read_or_write::READ, true>(offset);
return m_ram[offset];
}
-u16 mb8421_mb8431_16_device::right_r(offs_t offset, u16 mem_mask)
+READ16_MEMBER(mb8421_mb8431_16_device::right_r)
{
offset &= 0x7ff;
update_intr<read_or_write::READ, true>(offset);
diff --git a/src/devices/machine/mb8421.h b/src/devices/machine/mb8421.h
index 00e8f8d207f..4ef0a010c9b 100644
--- a/src/devices/machine/mb8421.h
+++ b/src/devices/machine/mb8421.h
@@ -108,10 +108,10 @@ public:
u8 peek(offs_t offset) const { return m_ram[offset & 0x7ff]; }
- void left_w(offs_t offset, u8 data);
- u8 left_r(offs_t offset);
- void right_w(offs_t offset, u8 data);
- u8 right_r(offs_t offset);
+ DECLARE_WRITE8_MEMBER(left_w);
+ DECLARE_READ8_MEMBER(left_r);
+ DECLARE_WRITE8_MEMBER(right_w);
+ DECLARE_READ8_MEMBER(right_r);
protected:
mb8421_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
@@ -140,10 +140,10 @@ public:
u16 peek(offs_t offset) const { return m_ram[offset & 0x7ff]; }
- void left_w(offs_t offset, u16 data, u16 mem_mask = 0xffff);
- u16 left_r(offs_t offset, u16 mem_mask = 0xffff);
- void right_w(offs_t offset, u16 data, u16 mem_mask = 0xffff);
- u16 right_r(offs_t offset, u16 mem_mask = 0xffff);
+ DECLARE_WRITE16_MEMBER(left_w);
+ DECLARE_READ16_MEMBER(left_r);
+ DECLARE_WRITE16_MEMBER(right_w);
+ DECLARE_READ16_MEMBER(right_r);
protected:
// device-level overrides
diff --git a/src/devices/machine/mc146818.cpp b/src/devices/machine/mc146818.cpp
index 1259e1502ca..990d6f3ec35 100644
--- a/src/devices/machine/mc146818.cpp
+++ b/src/devices/machine/mc146818.cpp
@@ -510,7 +510,7 @@ void mc146818_device::update_irq()
// read - I/O handler for reading
//-------------------------------------------------
-uint8_t mc146818_device::read(offs_t offset)
+READ8_MEMBER( mc146818_device::read )
{
uint8_t data = 0;
switch (offset)
@@ -520,14 +520,14 @@ uint8_t mc146818_device::read(offs_t offset)
break;
case 1:
- data = read_direct(m_index);
+ data = read_direct(space, m_index);
break;
}
return data;
}
-uint8_t mc146818_device::read_direct(offs_t offset)
+READ8_MEMBER( mc146818_device::read_direct )
{
uint8_t data = 0;
@@ -569,7 +569,7 @@ uint8_t mc146818_device::read_direct(offs_t offset)
// write - I/O handler for writing
//-------------------------------------------------
-void mc146818_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mc146818_device::write )
{
switch (offset)
{
@@ -578,12 +578,12 @@ void mc146818_device::write(offs_t offset, uint8_t data)
break;
case 1:
- write_direct(m_index, data);
+ write_direct(space, m_index, data);
break;
}
}
-void mc146818_device::write_direct(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mc146818_device::write_direct )
{
LOG("mc146818_port_w(): offset=0x%02x data=0x%02x\n", offset, data);
diff --git a/src/devices/machine/mc146818.h b/src/devices/machine/mc146818.h
index b1431964dde..499698a84cd 100644
--- a/src/devices/machine/mc146818.h
+++ b/src/devices/machine/mc146818.h
@@ -39,12 +39,12 @@ public:
void set_binary_year(int bin) { m_binyear = bin; }
// read/write access
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
// direct-mapped read/write access
- uint8_t read_direct(offs_t offset);
- void write_direct(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read_direct );
+ DECLARE_WRITE8_MEMBER( write_direct );
protected:
mc146818_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
diff --git a/src/devices/machine/mc6843.h b/src/devices/machine/mc6843.h
index 63052970edb..29f3b862bda 100644
--- a/src/devices/machine/mc6843.h
+++ b/src/devices/machine/mc6843.h
@@ -15,6 +15,8 @@
#include "imagedev/flopdrv.h"
+#define MCFG_MC6843_IRQ_CALLBACK(_write) \
+ downcast<mc6843_device &>(*device).set_irq_wr_callback(DEVCB_##_write);
class mc6843_device : public device_t
{
diff --git a/src/devices/machine/mc6852.cpp b/src/devices/machine/mc6852.cpp
index 6d5a9876153..d2021a450a2 100644
--- a/src/devices/machine/mc6852.cpp
+++ b/src/devices/machine/mc6852.cpp
@@ -147,7 +147,7 @@ void mc6852_device::rcv_complete()
// read -
//-------------------------------------------------
-uint8_t mc6852_device::read(offs_t offset)
+READ8_MEMBER( mc6852_device::read )
{
uint8_t data = 0;
@@ -156,8 +156,7 @@ uint8_t mc6852_device::read(offs_t offset)
if (m_rx_fifo.size() > 0)
{
data = m_rx_fifo.front();
- if (!machine().side_effects_disabled())
- m_rx_fifo.pop();
+ m_rx_fifo.pop();
}
}
else
@@ -173,7 +172,7 @@ uint8_t mc6852_device::read(offs_t offset)
// write -
//-------------------------------------------------
-void mc6852_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mc6852_device::write )
{
if (BIT(offset, 0))
{
diff --git a/src/devices/machine/mc6852.h b/src/devices/machine/mc6852.h
index 3f05182ed6f..798529db3ef 100644
--- a/src/devices/machine/mc6852.h
+++ b/src/devices/machine/mc6852.h
@@ -32,6 +32,30 @@
//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MC6852_RX_CLOCK(_clock) \
+ downcast<mc6852_device &>(*device).set_rx_clock(_clock);
+
+#define MCFG_MC6852_TX_CLOCK(_clock) \
+ downcast<mc6852_device &>(*device).set_tx_clock(_clock);
+
+#define MCFG_MC6852_TX_DATA_CALLBACK(_write) \
+ downcast<mc6852_device &>(*device).set_tx_data_wr_callback(DEVCB_##_write);
+
+#define MCFG_MC6852_IRQ_CALLBACK(_write) \
+ downcast<mc6852_device &>(*device).set_irq_wr_callback(DEVCB_##_write);
+
+#define MCFG_MC6852_SM_DTR_CALLBACK(_write) \
+ downcast<mc6852_device &>(*device).set_sm_dtr_wr_callback(DEVCB_##_write);
+
+#define MCFG_MC6852_TUF_CALLBACK(_write) \
+ downcast<mc6852_device &>(*device).set_tuf_wr_callback(DEVCB_##_write);
+
+
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -46,14 +70,18 @@ public:
void set_rx_clock(int clock) { m_rx_clock = clock; }
void set_tx_clock(int clock) { m_tx_clock = clock; }
+ template <class Object> devcb_base &set_tx_data_wr_callback(Object &&cb) { return m_write_tx_data.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_irq_wr_callback(Object &&cb) { return m_write_irq.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_sm_dtr_wr_callback(Object &&cb) { return m_write_sm_dtr.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_tuf_wr_callback(Object &&cb) { return m_write_tuf.set_callback(std::forward<Object>(cb)); }
auto tx_data_callback() { return m_write_tx_data.bind(); }
auto irq_callback() { return m_write_irq.bind(); }
auto sm_dtr_callback() { return m_write_sm_dtr.bind(); }
auto tuf_callback() { return m_write_tuf.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
DECLARE_WRITE_LINE_MEMBER( rx_data_w ) { device_serial_interface::rx_w(state); }
DECLARE_WRITE_LINE_MEMBER( rx_clk_w ) { rx_clock_w(state); }
diff --git a/src/devices/machine/mc6854.cpp b/src/devices/machine/mc6854.cpp
index acaa74b0cf9..43e09eba5d2 100644
--- a/src/devices/machine/mc6854.cpp
+++ b/src/devices/machine/mc6854.cpp
@@ -809,7 +809,7 @@ void mc6854_device::update_sr1( )
-uint8_t mc6854_device::read(offs_t offset)
+READ8_MEMBER( mc6854_device::read )
{
switch ( offset )
{
@@ -850,7 +850,7 @@ uint8_t mc6854_device::read(offs_t offset)
-void mc6854_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mc6854_device::write )
{
switch ( offset )
{
diff --git a/src/devices/machine/mc6854.h b/src/devices/machine/mc6854.h
index 0f90544336b..99f09f5d3a7 100644
--- a/src/devices/machine/mc6854.h
+++ b/src/devices/machine/mc6854.h
@@ -40,8 +40,8 @@ public:
}
/* interface to CPU via address/data bus*/
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
/* low-level, bit-based interface */
DECLARE_WRITE_LINE_MEMBER( set_rx );
diff --git a/src/devices/machine/mc68681.cpp b/src/devices/machine/mc68681.cpp
index a3a3b480979..b60567aa3f7 100644
--- a/src/devices/machine/mc68681.cpp
+++ b/src/devices/machine/mc68681.cpp
@@ -268,25 +268,22 @@ void xr68c681_device::device_reset()
m_XTXA = m_XRXA = m_XTXB = m_XRXB = false;
}
-void duart_base_device::device_add_mconfig(machine_config &config)
-{
- DUART_CHANNEL(config, CHANA_TAG, 0);
- DUART_CHANNEL(config, CHANB_TAG, 0);
-}
-
-void sc28c94_device::device_add_mconfig(machine_config &config)
-{
- DUART_CHANNEL(config, CHANA_TAG, 0);
- DUART_CHANNEL(config, CHANB_TAG, 0);
- DUART_CHANNEL(config, CHANC_TAG, 0);
- DUART_CHANNEL(config, CHAND_TAG, 0);
-}
-
-void mc68340_duart_device::device_add_mconfig(machine_config &config)
-{
- DUART_CHANNEL(config, CHANA_TAG, 0);
- DUART_CHANNEL(config, CHANB_TAG, 0);
-}
+MACHINE_CONFIG_START(duart_base_device::device_add_mconfig)
+ MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0)
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_START(sc28c94_device::device_add_mconfig)
+ MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANC_TAG, DUART_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHAND_TAG, DUART_CHANNEL, 0)
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_START(mc68340_duart_device::device_add_mconfig)
+ MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0)
+MACHINE_CONFIG_END
void duart_base_device::update_interrupts()
{
diff --git a/src/devices/machine/mc68681.h b/src/devices/machine/mc68681.h
index 50e5cdd1489..ea4fd63e3af 100644
--- a/src/devices/machine/mc68681.h
+++ b/src/devices/machine/mc68681.h
@@ -7,6 +7,32 @@
#include "diserial.h"
+#define MCFG_MC68681_IRQ_CALLBACK(_cb) \
+ downcast<duart_base_device &>(*device).set_irq_cb(DEVCB_##_cb);
+
+#define MCFG_MC68681_A_TX_CALLBACK(_cb) \
+ downcast<duart_base_device &>(*device).set_a_tx_cb(DEVCB_##_cb);
+
+#define MCFG_MC68681_B_TX_CALLBACK(_cb) \
+ downcast<duart_base_device &>(*device).set_b_tx_cb(DEVCB_##_cb);
+
+// deprecated: use ipX_w() instead
+#define MCFG_MC68681_INPORT_CALLBACK(_cb) \
+ downcast<duart_base_device &>(*device).set_inport_cb(DEVCB_##_cb);
+
+#define MCFG_MC68681_OUTPORT_CALLBACK(_cb) \
+ downcast<duart_base_device &>(*device).set_outport_cb(DEVCB_##_cb);
+
+#define MCFG_MC68681_SET_EXTERNAL_CLOCKS(_a, _b, _c, _d) \
+ downcast<duart_base_device &>(*device).set_clocks(_a, _b, _c, _d);
+
+// SC28C94 specific callbacks
+#define MCFG_SC28C94_C_TX_CALLBACK(_cb) \
+ downcast<sc28c94_device &>(*device).set_c_tx_cb(DEVCB_##_cb);
+
+#define MCFG_SC28C94_D_TX_CALLBACK(_cb) \
+ downcast<sc28c94_device &>(*device).set_d_tx_cb(DEVCB_##_cb);
+
#define MC68681_RX_FIFO_SIZE 3
// forward declaration
@@ -101,10 +127,15 @@ public:
DECLARE_WRITE_LINE_MEMBER(rx_a_w) { m_chanA->device_serial_interface::rx_w((uint8_t)state); }
DECLARE_WRITE_LINE_MEMBER(rx_b_w) { m_chanB->device_serial_interface::rx_w((uint8_t)state); }
+ template <class Object> devcb_base &set_irq_cb(Object &&cb) { return write_irq.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_a_tx_cb(Object &&cb) { return write_a_tx.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_b_tx_cb(Object &&cb) { return write_b_tx.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_inport_cb(Object &&cb) { return read_inport.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_outport_cb(Object &&cb) { return write_outport.set_callback(std::forward<Object>(cb)); }
auto irq_cb() { return write_irq.bind(); }
auto a_tx_cb() { return write_a_tx.bind(); }
auto b_tx_cb() { return write_b_tx.bind(); }
- auto inport_cb() { return read_inport.bind(); } // deprecated: use ipX_w() instead
+ auto inport_cb() { return read_inport.bind(); }
auto outport_cb() { return write_outport.bind(); }
// new-style push handlers for input port bits
@@ -216,8 +247,8 @@ class sc28c94_device : public duart_base_device
public:
sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- auto c_tx_cb() { return write_c_tx.bind(); }
- auto d_tx_cb() { return write_d_tx.bind(); }
+ template <class Object> devcb_base &set_c_tx_cb(Object &&cb) { return write_c_tx.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_d_tx_cb(Object &&cb) { return write_d_tx.set_callback(std::forward<Object>(cb)); }
DECLARE_WRITE_LINE_MEMBER(rx_c_w) { m_chanC->device_serial_interface::rx_w((uint8_t)state); }
DECLARE_WRITE_LINE_MEMBER(rx_d_w) { m_chanD->device_serial_interface::rx_w((uint8_t)state); }
diff --git a/src/devices/machine/mccs1850.h b/src/devices/machine/mccs1850.h
index 62b7f5d5afc..bd7771bc6a0 100644
--- a/src/devices/machine/mccs1850.h
+++ b/src/devices/machine/mccs1850.h
@@ -25,6 +25,22 @@
#include "dirtc.h"
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MCCS1850_INT_CALLBACK(_write) \
+ downcast<mccs1850_device &>(*device).set_int_wr_callback(DEVCB_##_write);
+
+#define MCFG_MCCS1850_PSE_CALLBACK(_write) \
+ downcast<mccs1850_device &>(*device).set_pse_wr_callback(DEVCB_##_write);
+
+#define MCFG_MCCS1850_NUC_CALLBACK(_write) \
+ downcast<mccs1850_device &>(*device).set_nuc_wr_callback(DEVCB_##_write);
+
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -39,9 +55,9 @@ public:
// construction/destruction
mccs1850_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- auto int_wr_callback() { return int_cb.bind(); }
- auto pse_wr_callback() { return pse_cb.bind(); }
- auto nuc_wr_callback() { return nuc_cb.bind(); }
+ template <class Object> devcb_base &set_int_wr_callback(Object &&cb) { return int_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pse_wr_callback(Object &&cb) { return pse_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_nuc_wr_callback(Object &&cb) { return nuc_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_WRITE_LINE_MEMBER( ce_w );
DECLARE_WRITE_LINE_MEMBER( sck_w );
diff --git a/src/devices/machine/mcf5206e.cpp b/src/devices/machine/mcf5206e.cpp
index cea38ca7f0f..085afac92ec 100644
--- a/src/devices/machine/mcf5206e.cpp
+++ b/src/devices/machine/mcf5206e.cpp
@@ -826,7 +826,7 @@ DEFINE_DEVICE_TYPE(MCF5206E_PERIPHERAL, mcf5206e_peripheral_device, "mcf5206e_pe
mcf5206e_peripheral_device::mcf5206e_peripheral_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, MCF5206E_PERIPHERAL, tag, owner, clock),
device_memory_interface(mconfig, *this),
- m_space_config("coldfire_regs", ENDIANNESS_BIG, 32,10, 0, address_map_constructor(FUNC(mcf5206e_peripheral_device::coldfire_regs_map), this))
+ m_space_config("coldfire_regs", ENDIANNESS_BIG, 32,10, 0, address_map_constructor(), address_map_constructor(FUNC(mcf5206e_peripheral_device::coldfire_regs_map), this))
{
}
diff --git a/src/devices/machine/mcf5206e.h b/src/devices/machine/mcf5206e.h
index a910849a25d..3bf54bbefd5 100644
--- a/src/devices/machine/mcf5206e.h
+++ b/src/devices/machine/mcf5206e.h
@@ -12,6 +12,15 @@
#pragma once
+
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+***************************************************************************/
+
+#define MCFG_MCF5206E_PERIPHERAL_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, MCF5206E_PERIPHERAL, 0)
+
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
diff --git a/src/devices/machine/meters.h b/src/devices/machine/meters.h
index c9a11790931..1a349f82485 100644
--- a/src/devices/machine/meters.h
+++ b/src/devices/machine/meters.h
@@ -15,6 +15,9 @@
#pragma once
+#define MCFG_METERS_NUMBER(_number) \
+ downcast<meters_device &>(*device).set_number_meters(_number);
+
class meters_device : public device_t
{
public:
@@ -24,7 +27,7 @@ public:
meters_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- void set_number(int number) { m_number_mtr = number; }
+ void set_number_meters(int number) { m_number_mtr = number; }
int update(int id, int state);
int GetActivity(int id);
diff --git a/src/devices/machine/microtch.h b/src/devices/machine/microtch.h
index 0cb486aa3f1..592b0a669da 100644
--- a/src/devices/machine/microtch.h
+++ b/src/devices/machine/microtch.h
@@ -13,14 +13,15 @@ class microtouch_device :
{
public:
microtouch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ template <class Object> devcb_base &set_stx_callback(Object &&cb) { return m_out_stx_func.set_callback(std::forward<Object>(cb)); }
auto stx() { return m_out_stx_func.bind(); }
virtual ioport_constructor device_input_ports() const override;
DECLARE_WRITE_LINE_MEMBER(rx) { device_serial_interface::rx_w(state); }
DECLARE_INPUT_CHANGED_MEMBER(touch);
- typedef device_delegate<int (int *, int *)> touch_cb;
- template <typename... T> void set_touch_callback(T &&... args) { m_out_touch_cb = touch_cb(std::forward<T>(args)...); }
+ typedef delegate<int (int *, int *)> touch_cb;
+ template <typename Object> void set_touch_callback(Object &&cb) { m_out_touch_cb = std::forward<Object>(cb); }
protected:
virtual void device_start() override;
@@ -72,4 +73,11 @@ private:
DECLARE_DEVICE_TYPE(MICROTOUCH, microtouch_device)
+#define MCFG_MICROTOUCH_ADD(_tag, _clock, _devcb) \
+ MCFG_DEVICE_ADD(_tag, MICROTOUCH, _clock) \
+ downcast<microtouch_device &>(*device).set_stx_callback(DEVCB_##_devcb);
+
+#define MCFG_MICROTOUCH_TOUCH_CB(_class, _touch_cb) \
+ downcast<microtouch_device &>(*device).set_touch_callback(microtouch_device::touch_cb(&_class::_touch_cb, this));
+
#endif // MAME_MACHINE_MICROTCH_H
diff --git a/src/devices/machine/mm5740.h b/src/devices/machine/mm5740.h
index 1896f568e4c..e28fbdc0956 100644
--- a/src/devices/machine/mm5740.h
+++ b/src/devices/machine/mm5740.h
@@ -80,6 +80,23 @@ Vgg 18 -12V
//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MM5740_MATRIX_X1(_cb) downcast<mm5740_device &>(*device).set_x_cb<0>(DEVCB_##_cb);
+#define MCFG_MM5740_MATRIX_X2(_cb) downcast<mm5740_device &>(*device).set_x_cb<1>(DEVCB_##_cb);
+#define MCFG_MM5740_MATRIX_X3(_cb) downcast<mm5740_device &>(*device).set_x_cb<2>(DEVCB_##_cb);
+#define MCFG_MM5740_MATRIX_X4(_cb) downcast<mm5740_device &>(*device).set_x_cb<3>(DEVCB_##_cb);
+#define MCFG_MM5740_MATRIX_X5(_cb) downcast<mm5740_device &>(*device).set_x_cb<4>(DEVCB_##_cb);
+#define MCFG_MM5740_MATRIX_X6(_cb) downcast<mm5740_device &>(*device).set_x_cb<5>(DEVCB_##_cb);
+#define MCFG_MM5740_MATRIX_X7(_cb) downcast<mm5740_device &>(*device).set_x_cb<6>(DEVCB_##_cb);
+#define MCFG_MM5740_MATRIX_X8(_cb) downcast<mm5740_device &>(*device).set_x_cb<7>(DEVCB_##_cb);
+#define MCFG_MM5740_MATRIX_X9(_cb) downcast<mm5740_device &>(*device).set_x_cb<8>(DEVCB_##_cb);
+#define MCFG_MM5740_SHIFT_CB(_cb) downcast<mm5740_device &>(*device).set_shift_cb(DEVCB_##_cb);
+#define MCFG_MM5740_CONTROL_CB(_cb) downcast<mm5740_device &>(*device).set_control_cb(DEVCB_##_cb);
+#define MCFG_MM5740_DATA_READY_CB(_cb) downcast<mm5740_device &>(*device).set_data_ready_cb(DEVCB_##_cb);
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -94,11 +111,22 @@ public:
// public interface
uint16_t b_r();
- template <unsigned N> auto x_cb() { return m_read_x[N].bind(); }
- auto shift_cb() { return m_read_shift.bind(); }
- auto control_cb() { return m_read_control.bind(); }
- auto data_ready_cb() { return m_write_data_ready.bind(); }
-
+ template <unsigned N, typename Object> devcb_base &set_x_cb(Object &&cb)
+ {
+ return m_read_x[N].set_callback(std::forward<Object>(cb));
+ }
+ template <typename Object> devcb_base &set_shift_cb(Object &&cb)
+ {
+ return m_read_shift.set_callback(std::forward<Object>(cb));
+ }
+ template <typename Object> devcb_base &set_control_cb(Object &&cb)
+ {
+ return m_read_control.set_callback(std::forward<Object>(cb));
+ }
+ template <typename Object> devcb_base &set_data_ready_cb(Object &&cb)
+ {
+ return m_write_data_ready.set_callback(std::forward<Object>(cb));
+ }
static uint32_t calc_effective_clock_key_debounce(uint32_t capacitance);
protected:
diff --git a/src/devices/machine/mm58167.cpp b/src/devices/machine/mm58167.cpp
index f226590e9d2..22b49f4a7dd 100644
--- a/src/devices/machine/mm58167.cpp
+++ b/src/devices/machine/mm58167.cpp
@@ -180,7 +180,7 @@ void mm58167_device::update_rtc()
m_milliseconds = (bcd_to_integer(m_regs[R_CNT_HUNDTENTHS]) * 10) + (bcd_to_integer(m_regs[R_CNT_MILLISECONDS] >> 4) % 10);
}
-uint8_t mm58167_device::read(offs_t offset)
+READ8_MEMBER(mm58167_device::read)
{
// printf("read reg %x = %02x\n", offset, m_regs[offset]);
@@ -196,7 +196,7 @@ uint8_t mm58167_device::read(offs_t offset)
return m_regs[offset];
}
-void mm58167_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(mm58167_device::write)
{
// printf("%02x to reg %x\n", data, offset);
diff --git a/src/devices/machine/mm58167.h b/src/devices/machine/mm58167.h
index c12b151b676..2c6bb5add34 100644
--- a/src/devices/machine/mm58167.h
+++ b/src/devices/machine/mm58167.h
@@ -15,6 +15,14 @@
//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MM58167_IRQ_CALLBACK(_cb) \
+ downcast<mm58167_device &>(*device).set_irq_cb(DEVCB_##_cb);
+
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -27,9 +35,10 @@ public:
// construction/destruction
mm58167_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
+ template <class Object> devcb_base &set_irq_cb(Object &&wr) { return m_irq_w.set_callback(std::forward<Object>(wr)); }
auto irq() { return m_irq_w.bind(); }
devcb_write_line m_irq_w;
diff --git a/src/devices/machine/mm58274c.cpp b/src/devices/machine/mm58274c.cpp
index c7e7f49a78e..61904923326 100644
--- a/src/devices/machine/mm58274c.cpp
+++ b/src/devices/machine/mm58274c.cpp
@@ -152,7 +152,7 @@ attotime mm58274c_device::interrupt_period_table(int val)
}
}
-uint8_t mm58274c_device::read(offs_t offset)
+READ8_MEMBER( mm58274c_device::read )
{
int reply;
@@ -242,7 +242,7 @@ uint8_t mm58274c_device::read(offs_t offset)
}
-void mm58274c_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mm58274c_device::write )
{
offset &= 0xf;
data &= 0xf;
diff --git a/src/devices/machine/mm58274c.h b/src/devices/machine/mm58274c.h
index c6fcbee3c46..cee2df48db9 100644
--- a/src/devices/machine/mm58274c.h
+++ b/src/devices/machine/mm58274c.h
@@ -16,8 +16,8 @@ public:
void set_day1(int day) { m_day1 = day; }
void set_mode_and_day(int mode, int day) { m_mode24 = mode; m_day1 = day; }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
TIMER_CALLBACK_MEMBER(rtc_increment_cb);
TIMER_CALLBACK_MEMBER(rtc_interrupt_cb);
@@ -30,7 +30,7 @@ protected:
private:
// internal state
- // Initialization of the clock chip:
+ // Initializion the clock chip:
// m_day1 must be set to a value from 0 (sunday), 1 (monday)...
// to 6 (saturday) and is needed to correctly retrieve the
// day-of-week from the host system clock.
@@ -66,4 +66,15 @@ private:
DECLARE_DEVICE_TYPE(MM58274C, mm58274c_device)
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+***************************************************************************/
+
+#define MCFG_MM58274C_MODE24(_mode) \
+ downcast<mm58274c_device &>(*device).set_mode24(_mode);
+
+#define MCFG_MM58274C_DAY1(_day) \
+ downcast<mm58274c_device &>(*device).set_day1(_day);
+
#endif // MAME_MACHINE_MM58274C_H
diff --git a/src/devices/machine/mm74c922.h b/src/devices/machine/mm74c922.h
index dce81dd40dc..bd448c2eb22 100644
--- a/src/devices/machine/mm74c922.h
+++ b/src/devices/machine/mm74c922.h
@@ -36,6 +36,38 @@
#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MM74C922_OSC(_value) \
+ downcast<mm74c922_device &>(*device).set_cap_osc(_value);
+
+#define MCFG_MM74C922_DEBOUNCE(_value) \
+ downcast<mm74c922_device &>(*device).set_cap_debounce(_value);
+
+#define MCFG_MM74C922_DA_CALLBACK(_write) \
+ downcast<mm74c922_device &>(*device).set_da_wr_callback(DEVCB_##_write);
+
+#define MCFG_MM74C922_X1_CALLBACK(_read) \
+ downcast<mm74c922_device &>(*device).set_x1_rd_callback(DEVCB_##_read);
+
+#define MCFG_MM74C922_X2_CALLBACK(_read) \
+ downcast<mm74c922_device &>(*device).set_x2_rd_callback(DEVCB_##_read);
+
+#define MCFG_MM74C922_X3_CALLBACK(_read) \
+ downcast<mm74c922_device &>(*device).set_x3_rd_callback(DEVCB_##_read);
+
+#define MCFG_MM74C922_X4_CALLBACK(_read) \
+ downcast<mm74c922_device &>(*device).set_x4_rd_callback(DEVCB_##_read);
+
+#define MCFG_MM74C922_X5_CALLBACK(_read) \
+ downcast<mm74c922_device &>(*device).set_x5_rd_callback(DEVCB_##_read);
+
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -51,12 +83,12 @@ public:
void set_cap_osc(double value) { m_cap_osc = value; }
void set_cap_debounce(double value) { m_cap_debounce = value; }
- auto da_wr_callback() { return m_write_da.bind(); }
- auto x1_rd_callback() { return m_read_x1.bind(); }
- auto x2_rd_callback() { return m_read_x2.bind(); }
- auto x3_rd_callback() { return m_read_x3.bind(); }
- auto x4_rd_callback() { return m_read_x4.bind(); }
- auto x5_rd_callback() { return m_read_x5.bind(); }
+ template <class Object> devcb_base &set_da_wr_callback(Object &&cb) { return m_write_da.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_x1_rd_callback(Object &&cb) { return m_read_x1.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_x2_rd_callback(Object &&cb) { return m_read_x2.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_x3_rd_callback(Object &&cb) { return m_read_x3.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_x4_rd_callback(Object &&cb) { return m_read_x4.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_x5_rd_callback(Object &&cb) { return m_read_x5.set_callback(std::forward<Object>(cb)); }
uint8_t read();
diff --git a/src/devices/machine/mos6526.cpp b/src/devices/machine/mos6526.cpp
index e1f40b109c1..9df653c4c5f 100644
--- a/src/devices/machine/mos6526.cpp
+++ b/src/devices/machine/mos6526.cpp
@@ -788,7 +788,7 @@ void mos6526_device::execute_run()
// read -
//-------------------------------------------------
-uint8_t mos6526_device::read(offs_t offset)
+READ8_MEMBER( mos6526_device::read )
{
uint8_t data = 0;
@@ -926,7 +926,7 @@ uint8_t mos6526_device::read(offs_t offset)
return data;
}
-uint8_t mos8520_device::read(offs_t offset)
+READ8_MEMBER( mos8520_device::read )
{
uint8_t data;
@@ -947,7 +947,7 @@ uint8_t mos8520_device::read(offs_t offset)
break;
default:
- data = mos6526_device::read(offset);
+ data = mos6526_device::read(space, offset);
}
return data;
@@ -957,7 +957,7 @@ uint8_t mos8520_device::read(offs_t offset)
// write -
//-------------------------------------------------
-void mos6526_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mos6526_device::write )
{
switch (offset & 0x0f)
{
@@ -1099,12 +1099,12 @@ void mos6526_device::write(offs_t offset, uint8_t data)
}
}
-void mos8520_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mos8520_device::write )
{
switch (offset & 0x0f)
{
default:
- mos6526_device::write(offset, data);
+ mos6526_device::write(space, offset, data);
break;
case TOD_MIN:
diff --git a/src/devices/machine/mos6526.h b/src/devices/machine/mos6526.h
index 33ccc6dd26d..07001edf4d6 100644
--- a/src/devices/machine/mos6526.h
+++ b/src/devices/machine/mos6526.h
@@ -61,6 +61,41 @@
#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS6526_TOD(_clock) \
+ downcast<mos6526_device &>(*device).set_tod_clock(_clock);
+
+#define MCFG_MOS6526_IRQ_CALLBACK(_write) \
+ downcast<mos6526_device &>(*device).set_irq_wr_callback(DEVCB_##_write);
+
+#define MCFG_MOS6526_CNT_CALLBACK(_write) \
+ downcast<mos6526_device &>(*device).set_cnt_wr_callback(DEVCB_##_write);
+
+#define MCFG_MOS6526_SP_CALLBACK(_write) \
+ downcast<mos6526_device &>(*device).set_sp_wr_callback(DEVCB_##_write);
+
+#define MCFG_MOS6526_PA_INPUT_CALLBACK(_read) \
+ downcast<mos6526_device &>(*device).set_pa_rd_callback(DEVCB_##_read);
+
+#define MCFG_MOS6526_PA_OUTPUT_CALLBACK(_write) \
+ downcast<mos6526_device &>(*device).set_pa_wr_callback(DEVCB_##_write);
+
+#define MCFG_MOS6526_PB_INPUT_CALLBACK(_read) \
+ downcast<mos6526_device &>(*device).set_pb_rd_callback(DEVCB_##_read);
+
+#define MCFG_MOS6526_PB_OUTPUT_CALLBACK(_write) \
+ downcast<mos6526_device &>(*device).set_pb_wr_callback(DEVCB_##_write);
+
+#define MCFG_MOS6526_PC_CALLBACK(_write) \
+ downcast<mos6526_device &>(*device).set_pc_wr_callback(DEVCB_##_write);
+
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -76,6 +111,14 @@ public:
void set_tod_clock(int clock) { m_tod_clock = clock; }
+ template <class Object> devcb_base &set_irq_wr_callback(Object &&cb) { return m_write_irq.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_cnt_wr_callback(Object &&cb) { return m_write_cnt.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_sp_wr_callback(Object &&cb) { return m_write_sp.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pa_rd_callback(Object &&cb) { return m_read_pa.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pa_wr_callback(Object &&cb) { return m_write_pa.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pb_rd_callback(Object &&cb) { return m_read_pb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pb_wr_callback(Object &&cb) { return m_write_pb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pc_wr_callback(Object &&cb) { return m_write_pc.set_callback(std::forward<Object>(cb)); }
auto irq_wr_callback() { return m_write_irq.bind(); }
auto cnt_wr_callback() { return m_write_cnt.bind(); }
auto sp_wr_callback() { return m_write_sp.bind(); }
@@ -85,11 +128,13 @@ public:
auto pb_wr_callback() { return m_write_pb.bind(); }
auto pc_wr_callback() { return m_write_pc.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
- uint8_t pa_r() { return m_pa; }
- uint8_t pb_r() { return m_pb; }
+ uint8_t read_pa() { return m_pa; }
+ DECLARE_READ8_MEMBER( pa_r ) { return m_pa; }
+ uint8_t read_pb() { return m_pb; }
+ DECLARE_READ8_MEMBER( pb_r ) { return m_pb; }
DECLARE_READ_LINE_MEMBER( sp_r ) { return m_sp; }
DECLARE_WRITE_LINE_MEMBER( sp_w );
@@ -228,8 +273,8 @@ class mos8520_device : public mos6526_device
public:
mos8520_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
protected:
virtual inline void clock_tod() override;
@@ -243,8 +288,8 @@ class mos5710_device : public mos6526_device
public:
mos5710_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- //uint8_t read(offs_t offset);
- //void write(offs_t offset, uint8_t data);
+ //DECLARE_READ8_MEMBER( read );
+ //DECLARE_WRITE8_MEMBER( write );
};
diff --git a/src/devices/machine/mos6530.h b/src/devices/machine/mos6530.h
index 6bbeb8db9de..cc930fa8613 100644
--- a/src/devices/machine/mos6530.h
+++ b/src/devices/machine/mos6530.h
@@ -48,10 +48,10 @@ class mos6530_device : public device_t
public:
mos6530_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- auto in_pa_callback() { return m_in_pa_cb.bind(); }
- auto out_pa_callback() { return m_out_pa_cb.bind(); }
- auto in_pb_callback() { return m_in_pb_cb.bind(); }
- auto out_pb_callback() { return m_out_pb_cb.bind(); }
+ template <class Object> devcb_base &set_in_pa_callback(Object &&cb) { return m_in_pa_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_out_pa_callback(Object &&cb) { return m_out_pa_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_in_pb_callback(Object &&cb) { return m_in_pb_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_out_pb_callback(Object &&cb) { return m_out_pb_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
@@ -108,4 +108,17 @@ private:
DECLARE_DEVICE_TYPE(MOS6530, mos6530_device)
+
+#define MCFG_MOS6530_IN_PA_CB(_devcb) \
+ downcast<mos6530_device &>(*device).set_in_pa_callback(DEVCB_##_devcb);
+
+#define MCFG_MOS6530_OUT_PA_CB(_devcb) \
+ downcast<mos6530_device &>(*device).set_out_pa_callback(DEVCB_##_devcb);
+
+#define MCFG_MOS6530_IN_PB_CB(_devcb) \
+ downcast<mos6530_device &>(*device).set_in_pb_callback(DEVCB_##_devcb);
+
+#define MCFG_MOS6530_OUT_PB_CB(_devcb) \
+ downcast<mos6530_device &>(*device).set_out_pb_callback(DEVCB_##_devcb);
+
#endif // MAME_MACHINE_MOS6530_H
diff --git a/src/devices/machine/mos6530n.h b/src/devices/machine/mos6530n.h
index 0042a73e429..a5dfd3ee6fe 100644
--- a/src/devices/machine/mos6530n.h
+++ b/src/devices/machine/mos6530n.h
@@ -57,6 +57,125 @@
#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS6530n_IRQ_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_irq_wr_callback(DEVCB_##_write);
+
+#define MCFG_MOS6530n_IN_PA_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback(DEVCB_##_read);
+
+#define MCFG_MOS6530n_OUT_PA_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback(DEVCB_##_write);
+
+#define MCFG_MOS6530n_IN_PB_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback(DEVCB_##_read);
+
+#define MCFG_MOS6530n_OUT_PB_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback(DEVCB_##_write);
+
+#define MCFG_MOS6530n_IN_PA0_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback<0>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PA1_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback<1>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PA2_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback<2>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PA3_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback<3>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PA4_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback<4>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PA5_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback<5>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PA6_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback<6>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PA7_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pa_rd_callback<7>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_OUT_PA0_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback<0>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PA1_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback<1>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PA2_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback<2>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PA3_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback<3>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PA4_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback<4>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PA5_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback<5>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PA6_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback<6>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PA7_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pa_wr_callback<7>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_IN_PB0_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback<0>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PB1_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback<1>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PB2_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback<2>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PB3_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback<3>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PB4_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback<4>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PB5_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback<5>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PB6_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback<6>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_IN_PB7_CB(_read) \
+ downcast<mos6530_device_base &>(*device).set_pb_rd_callback<7>(DEVCB_##_read);
+
+#define MCFG_MOS6530n_OUT_PB0_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback<0>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PB1_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback<1>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PB2_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback<2>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PB3_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback<3>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PB4_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback<4>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PB5_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback<5>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PB6_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback<6>(DEVCB_##_write);
+
+#define MCFG_MOS6530n_OUT_PB7_CB(_write) \
+ downcast<mos6530_device_base &>(*device).set_pb_wr_callback<7>(DEVCB_##_write);
+
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -66,6 +185,15 @@
class mos6530_device_base : public device_t
{
public:
+ template <class Object> devcb_base &set_irq_wr_callback(Object &&cb) { return m_irq_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pa_rd_callback(Object &&cb) { return m_in8_pa_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pa_wr_callback(Object &&cb) { return m_out8_pa_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pb_rd_callback(Object &&cb) { return m_in8_pb_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_pb_wr_callback(Object &&cb) { return m_out8_pb_cb.set_callback(std::forward<Object>(cb)); }
+ template <unsigned N, class Object> devcb_base &set_pa_rd_callback(Object &&cb) { return m_in_pa_cb[N].set_callback(std::forward<Object>(cb)); }
+ template <unsigned N, class Object> devcb_base &set_pa_wr_callback(Object &&cb) { return m_out_pa_cb[N].set_callback(std::forward<Object>(cb)); }
+ template <unsigned N, class Object> devcb_base &set_pb_rd_callback(Object &&cb) { return m_in_pb_cb[N].set_callback(std::forward<Object>(cb)); }
+ template <unsigned N, class Object> devcb_base &set_pb_wr_callback(Object &&cb) { return m_out_pb_cb[N].set_callback(std::forward<Object>(cb)); }
auto irq_wr_callback() { return m_irq_cb.bind(); }
auto pa_rd_callback() { return m_in8_pa_cb.bind(); }
auto pa_wr_callback() { return m_out8_pa_cb.bind(); }
diff --git a/src/devices/machine/mos6551.cpp b/src/devices/machine/mos6551.cpp
index f9edbd39cee..37bb874aaf4 100644
--- a/src/devices/machine/mos6551.cpp
+++ b/src/devices/machine/mos6551.cpp
@@ -63,11 +63,10 @@ const int mos6551_device::transmitter_controls[4][3] =
{0, 1, 1}
};
-void mos6551_device::device_add_mconfig(machine_config &config)
-{
- CLOCK(config, m_internal_clock, 0);
- m_internal_clock->signal_handler().set(FUNC(mos6551_device::internal_clock));
-}
+MACHINE_CONFIG_START(mos6551_device::device_add_mconfig)
+ MCFG_DEVICE_ADD("clock", CLOCK, 0)
+ MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(*this, mos6551_device, internal_clock))
+MACHINE_CONFIG_END
void mos6551_device::device_start()
@@ -271,8 +270,7 @@ void mos6551_device::update_divider()
uint8_t mos6551_device::read_rdr()
{
- if (!machine().side_effects_disabled())
- m_status &= ~(SR_PARITY_ERROR | SR_FRAMING_ERROR | SR_OVERRUN | SR_RDRF);
+ m_status &= ~(SR_PARITY_ERROR | SR_FRAMING_ERROR | SR_OVERRUN | SR_RDRF);
return m_rdr;
}
@@ -280,18 +278,15 @@ uint8_t mos6551_device::read_status()
{
uint8_t status = m_status;
- if (!machine().side_effects_disabled())
+ if (m_cts)
{
- if (m_cts)
- {
- status &= ~SR_TDRE;
- }
+ status &= ~SR_TDRE;
+ }
- if (m_irq_state != 0)
- {
- m_irq_state = 0;
- update_irq();
- }
+ if (m_irq_state != 0)
+ {
+ m_irq_state = 0;
+ update_irq();
}
return status;
@@ -379,8 +374,11 @@ void mos6551_device::write_command(uint8_t data)
update_divider();
}
-uint8_t mos6551_device::read(offs_t offset)
+READ8_MEMBER( mos6551_device::read )
{
+ if (machine().side_effects_disabled())
+ return 0xff;
+
switch (offset & 0x03)
{
case 0:
@@ -398,7 +396,7 @@ uint8_t mos6551_device::read(offs_t offset)
}
}
-void mos6551_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mos6551_device::write )
{
switch (offset & 0x03)
{
diff --git a/src/devices/machine/mos6551.h b/src/devices/machine/mos6551.h
index b7afabfa603..626c17fd0b2 100644
--- a/src/devices/machine/mos6551.h
+++ b/src/devices/machine/mos6551.h
@@ -33,7 +33,7 @@
class mos6551_device : public device_t
{
public:
- mos6551_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ mos6551_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
auto irq_handler() { return m_irq_handler.bind(); }
auto txd_handler() { return m_txd_handler.bind(); }
@@ -41,8 +41,8 @@ public:
auto rts_handler() { return m_rts_handler.bind(); }
auto dtr_handler() { return m_dtr_handler.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
DECLARE_WRITE_LINE_MEMBER(write_xtal1); // txc
DECLARE_WRITE_LINE_MEMBER(write_rxd);
diff --git a/src/devices/machine/mos6702.cpp b/src/devices/machine/mos6702.cpp
index 1b552054cb4..a5fa3d4c088 100644
--- a/src/devices/machine/mos6702.cpp
+++ b/src/devices/machine/mos6702.cpp
@@ -49,7 +49,7 @@ void mos6702_device::device_start()
// read -
//-------------------------------------------------
-uint8_t mos6702_device::read(offs_t offset)
+READ8_MEMBER( mos6702_device::read )
{
return 0;
}
@@ -59,6 +59,6 @@ uint8_t mos6702_device::read(offs_t offset)
// write -
//-------------------------------------------------
-void mos6702_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mos6702_device::write )
{
}
diff --git a/src/devices/machine/mos6702.h b/src/devices/machine/mos6702.h
index ab1ea945e6e..4e7ef027b6e 100644
--- a/src/devices/machine/mos6702.h
+++ b/src/devices/machine/mos6702.h
@@ -25,6 +25,16 @@
#pragma once
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS6702_ADD(tag, clock) \
+ MCFG_DEVICE_ADD(tag, MOS6702, clock)
+
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -37,8 +47,8 @@ public:
// construction/destruction
mos6702_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
protected:
// device-level overrides
diff --git a/src/devices/machine/mos8706.h b/src/devices/machine/mos8706.h
index a3a6247bf5a..36cb6d55d5d 100644
--- a/src/devices/machine/mos8706.h
+++ b/src/devices/machine/mos8706.h
@@ -29,6 +29,17 @@
#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS8706_ADD(tag, clock) \
+ MCFG_DEVICE_ADD((tag), MOS8706, (clock))
+
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
diff --git a/src/devices/machine/mos8722.cpp b/src/devices/machine/mos8722.cpp
index 0364460b63e..b55d8393a9f 100644
--- a/src/devices/machine/mos8722.cpp
+++ b/src/devices/machine/mos8722.cpp
@@ -171,7 +171,7 @@ uint8_t mos8722_device::read(offs_t offset, uint8_t data)
// write - register write
//-------------------------------------------------
-void mos8722_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mos8722_device::write )
{
if (MCR_C64) return;
diff --git a/src/devices/machine/mos8722.h b/src/devices/machine/mos8722.h
index 2b80aa846c2..e5d32d4e4ea 100644
--- a/src/devices/machine/mos8722.h
+++ b/src/devices/machine/mos8722.h
@@ -57,7 +57,7 @@ public:
auto sense40() { return m_read_sense40.bind(); }
uint8_t read(offs_t offset, uint8_t data);
- void write(offs_t offset, uint8_t data);
+ DECLARE_WRITE8_MEMBER( write );
DECLARE_READ_LINE_MEMBER( fsdir_r );
diff --git a/src/devices/machine/mos8726.cpp b/src/devices/machine/mos8726.cpp
index e1f167d70d3..0c2286788a7 100644
--- a/src/devices/machine/mos8726.cpp
+++ b/src/devices/machine/mos8726.cpp
@@ -90,7 +90,7 @@ void mos8726_device::execute_run()
// read -
//-------------------------------------------------
-uint8_t mos8726_device::read(offs_t offset)
+READ8_MEMBER( mos8726_device::read )
{
uint8_t data = 0;
@@ -102,7 +102,7 @@ uint8_t mos8726_device::read(offs_t offset)
// write -
//-------------------------------------------------
-void mos8726_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( mos8726_device::write )
{
}
diff --git a/src/devices/machine/mos8726.h b/src/devices/machine/mos8726.h
index 90b78ec8412..8435bf0f544 100644
--- a/src/devices/machine/mos8726.h
+++ b/src/devices/machine/mos8726.h
@@ -47,6 +47,17 @@
#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS8726_ADD(tag) \
+ MCFG_DEVICE_ADD((tag), MOS8726, 1000000) // dummy clock
+
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -60,8 +71,8 @@ public:
// construction/destruction
mos8726_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
DECLARE_WRITE_LINE_MEMBER( bs_w );
diff --git a/src/devices/machine/mpu401.cpp b/src/devices/machine/mpu401.cpp
index 48cc04b455d..578ad206721 100644
--- a/src/devices/machine/mpu401.cpp
+++ b/src/devices/machine/mpu401.cpp
@@ -81,8 +81,7 @@ DEFINE_DEVICE_TYPE(MPU401, mpu401_device, "mpu401", "Roland MPU-401 I/O box")
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void mpu401_device::device_add_mconfig(machine_config &config)
-{
+MACHINE_CONFIG_START(mpu401_device::device_add_mconfig)
M6801(config, m_ourcpu, 4000000); /* 4 MHz as per schematics */
m_ourcpu->set_addrmap(AS_PROGRAM, &mpu401_device::mpu401_map);
m_ourcpu->in_p1_cb().set(FUNC(mpu401_device::port1_r));
@@ -91,10 +90,11 @@ void mpu401_device::device_add_mconfig(machine_config &config)
m_ourcpu->out_p2_cb().set(FUNC(mpu401_device::port2_w));
m_ourcpu->out_ser_tx_cb().set(MIDIOUT_TAG, FUNC(midi_port_device::write_txd));
- MIDI_PORT(config, MIDIIN_TAG, midiin_slot, "midiin").rxd_handler().set(DEVICE_SELF, FUNC(mpu401_device::midi_rx_w));
+ MCFG_MIDI_PORT_ADD(MIDIIN_TAG, midiin_slot, "midiin")
+ MCFG_MIDI_RX_HANDLER(WRITELINE(DEVICE_SELF, mpu401_device, midi_rx_w))
- MIDI_PORT(config, MIDIOUT_TAG, midiout_slot, "midiout");
-}
+ MCFG_MIDI_PORT_ADD(MIDIOUT_TAG, midiout_slot, "midiout")
+MACHINE_CONFIG_END
//-------------------------------------------------
// rom_region - device-specific ROM region
diff --git a/src/devices/machine/msm58321.h b/src/devices/machine/msm58321.h
index d5b7a5d78c3..1842b4f2036 100644
--- a/src/devices/machine/msm58321.h
+++ b/src/devices/machine/msm58321.h
@@ -39,6 +39,32 @@
#include "dirtc.h"
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MSM58321_D0_HANDLER(_devcb) \
+ downcast<msm58321_device &>(*device).set_d0_handler(DEVCB_##_devcb);
+
+#define MCFG_MSM58321_D1_HANDLER(_devcb) \
+ downcast<msm58321_device &>(*device).set_d1_handler(DEVCB_##_devcb);
+
+#define MCFG_MSM58321_D2_HANDLER(_devcb) \
+ downcast<msm58321_device &>(*device).set_d2_handler(DEVCB_##_devcb);
+
+#define MCFG_MSM58321_D3_HANDLER(_devcb) \
+ downcast<msm58321_device &>(*device).set_d3_handler(DEVCB_##_devcb);
+
+#define MCFG_MSM58321_BUSY_HANDLER(_devcb) \
+ downcast<msm58321_device &>(*device).set_busy_handler(DEVCB_##_devcb);
+
+#define MCFG_MSM58321_YEAR0(_year0) \
+ downcast<msm58321_device &>(*device).set_year0(_year0);
+
+#define MCFG_MSM58321_DEFAULT_24H(_default_24h) \
+ downcast<msm58321_device &>(*device).set_default_24h(_default_24h);
+
// ======================> msm58321_device
class msm58321_device : public device_t,
@@ -50,6 +76,11 @@ public:
msm58321_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
+ template <class Object> devcb_base &set_d0_handler(Object &&cb) { return m_d0_handler.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_d1_handler(Object &&cb) { return m_d1_handler.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_d2_handler(Object &&cb) { return m_d2_handler.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_d3_handler(Object &&cb) { return m_d3_handler.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_busy_handler(Object &&cb) { return m_busy_handler.set_callback(std::forward<Object>(cb)); }
auto d0_handler() { return m_d0_handler.bind(); }
auto d1_handler() { return m_d1_handler.bind(); }
auto d2_handler() { return m_d2_handler.bind(); }
diff --git a/src/devices/machine/msm6242.h b/src/devices/machine/msm6242.h
index 430bbbc10f0..bd6bd89403e 100644
--- a/src/devices/machine/msm6242.h
+++ b/src/devices/machine/msm6242.h
@@ -40,6 +40,10 @@
#include "dirtc.h"
+#define MCFG_MSM6242_OUT_INT_HANDLER(_devcb) \
+ downcast<msm6242_device &>(*device).set_out_int_handler(DEVCB_##_devcb);
+
+
// ======================> msm6242_device
class msm6242_device : public device_t, public device_rtc_interface
@@ -48,6 +52,7 @@ public:
// construction/destruction
msm6242_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ template <class Object> devcb_base &set_out_int_handler(Object &&cb) { return m_out_int_handler.set_callback(std::forward<Object>(cb)); }
auto out_int_handler() { return m_out_int_handler.bind(); }
// I/O operations
diff --git a/src/devices/machine/myb3k_kbd.h b/src/devices/machine/myb3k_kbd.h
index 34c2c5cc414..747289a53f1 100644
--- a/src/devices/machine/myb3k_kbd.h
+++ b/src/devices/machine/myb3k_kbd.h
@@ -14,6 +14,9 @@
is responsible for storing the byte into the serial/parallell converter
(that can be read through IN from port 0x04) and then trigger an interrupt.
+ MCFG_DEVICE_ADD("myb3k_keyboard", MYB3K_KEYBOARD, 0)
+ MCFG_MYB3K_KEYBOARD_CB(PUT(myb3k_state, kbd_set_data_and_interrupt))
+
**********************************************************************/
#ifndef MAME_MACHINE_MYB3K_KBD_H
@@ -21,6 +24,11 @@
#pragma once
+#define MYB3K_KBD_CB_PUT(cls, fnc) myb3k_keyboard_device::output_delegate((&cls::fnc), (#cls "::" #fnc), DEVICE_SELF, ((cls *)nullptr))
+#define MYB3K_KBD_CB_DEVPUT(tag, cls, fnc) myb3k_keyboard_device::output_delegate((&cls::fnc), (#cls "::" #fnc), (tag), ((cls *)nullptr))
+
+#define MCFG_MYB3K_KEYBOARD_CB(cb) downcast<myb3k_keyboard_device &>(*device).set_keyboard_callback((MYB3K_KBD_CB_##cb));
+
DECLARE_DEVICE_TYPE(MYB3K_KEYBOARD, myb3k_keyboard_device)
DECLARE_DEVICE_TYPE(JB3000_KEYBOARD, jb3000_keyboard_device)
DECLARE_DEVICE_TYPE(STEPONE_KEYBOARD, stepone_keyboard_device)
@@ -43,18 +51,7 @@ public:
TIMER_ID_SECOND_BYTE
};
- template <class FunctionClass>
- void set_keyboard_callback(void (FunctionClass::*callback)(u8 character), const char *name)
- {
- set_keyboard_callback(output_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
- }
- // FIXME: this should be aware of current device for resolving the tag
- template <class FunctionClass>
- void set_keyboard_callback(const char *devname, void (FunctionClass::*callback)(u8 character), const char *name)
- {
- set_keyboard_callback(output_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)));
- }
- void set_keyboard_callback(output_delegate callback) { m_keyboard_cb = callback; }
+ template <class Object> void set_keyboard_callback(Object &&cb) { m_keyboard_cb = std::forward<Object>(cb); }
protected:
myb3k_keyboard_device(
diff --git a/src/devices/machine/ncr5380.h b/src/devices/machine/ncr5380.h
index 9d9d7b96617..b2f7e4f2509 100644
--- a/src/devices/machine/ncr5380.h
+++ b/src/devices/machine/ncr5380.h
@@ -36,6 +36,8 @@ enum
// device stuff
+#define MCFG_NCR5380_IRQ_CB(_devcb) \
+ downcast<ncr5380_device &>(*device).set_irq_callback(DEVCB_##_devcb);
class ncr5380_device : public legacy_scsi_host_adapter
{
@@ -43,6 +45,7 @@ public:
// construction/destruction
ncr5380_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ template <class Object> devcb_base &set_irq_callback(Object &&cb) { return m_irq_cb.set_callback(std::forward<Object>(cb)); }
auto irq_callback() { return m_irq_cb.bind(); }
// our API
diff --git a/src/devices/machine/ncr5380n.cpp b/src/devices/machine/ncr5380n.cpp
index e5132603609..4d09a910e46 100644
--- a/src/devices/machine/ncr5380n.cpp
+++ b/src/devices/machine/ncr5380n.cpp
@@ -288,12 +288,12 @@ void ncr5380n_device::delay_cycles(int cycles)
tm->adjust(clocks_to_attotime(cycles));
}
-uint8_t ncr5380n_device::scsidata_r()
+READ8_MEMBER(ncr5380n_device::scsidata_r)
{
return scsi_bus->data_r();
}
-void ncr5380n_device::outdata_w(uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::outdata_w)
{
m_outdata = data;
@@ -304,12 +304,12 @@ void ncr5380n_device::outdata_w(uint8_t data)
}
}
-uint8_t ncr5380n_device::icmd_r()
+READ8_MEMBER(ncr5380n_device::icmd_r)
{
return m_icommand;
}
-void ncr5380n_device::icmd_w(uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::icmd_w)
{
// asserting to drive the data bus?
if ((data & IC_DBUS) && !(m_icommand & IC_DBUS))
@@ -340,12 +340,12 @@ void ncr5380n_device::icmd_w(uint8_t data)
delay(2);
}
-uint8_t ncr5380n_device::mode_r()
+READ8_MEMBER(ncr5380n_device::mode_r)
{
return m_mode;
}
-void ncr5380n_device::mode_w(uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::mode_w)
{
// logerror("%s: mode_w %02x (%s)\n", tag(), data, machine().describe_context());
// arbitration bit being set?
@@ -373,13 +373,13 @@ void ncr5380n_device::mode_w(uint8_t data)
m_mode = data;
}
-uint8_t ncr5380n_device::command_r()
+READ8_MEMBER(ncr5380n_device::command_r)
{
// logerror("%s: command_r %02x (%s)\n", tag(), m_tcommand, machine().describe_context());
return m_tcommand;
}
-void ncr5380n_device::command_w(uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::command_w)
{
// logerror("%s: command_w %02x (%s)\n", tag(), data, machine().describe_context());
m_tcommand = data;
@@ -413,7 +413,7 @@ void ncr5380n_device::check_irq()
#endif
}
-uint8_t ncr5380n_device::status_r()
+READ8_MEMBER(ncr5380n_device::status_r)
{
uint32_t ctrl = scsi_bus->ctrl_r();
uint8_t res = status |
@@ -429,11 +429,11 @@ uint8_t ncr5380n_device::status_r()
return res;
}
-void ncr5380n_device::selenable_w(uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::selenable_w)
{
}
-uint8_t ncr5380n_device::busandstatus_r()
+READ8_MEMBER(ncr5380n_device::busandstatus_r)
{
uint32_t ctrl = scsi_bus->ctrl_r();
uint8_t res = m_busstatus |
@@ -445,28 +445,28 @@ uint8_t ncr5380n_device::busandstatus_r()
return res;
}
-void ncr5380n_device::startdmasend_w(uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::startdmasend_w)
{
logerror("%02x to start dma send\n", data);
drq_set();
}
-uint8_t ncr5380n_device::indata_r()
+READ8_MEMBER(ncr5380n_device::indata_r)
{
return dma_r();
}
-void ncr5380n_device::startdmatargetrx_w(uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::startdmatargetrx_w)
{
logerror("%02x to start dma target Rx\n", data);
}
-uint8_t ncr5380n_device::resetparityirq_r()
+READ8_MEMBER(ncr5380n_device::resetparityirq_r)
{
return 0;
}
-void ncr5380n_device::startdmainitrx_w(uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::startdmainitrx_w)
{
// logerror("%02x to start dma initiator Rx\n", data);
recv_byte();
@@ -518,73 +518,73 @@ void ncr5380n_device::drq_clear()
}
}
-uint8_t ncr5380n_device::read(offs_t offset)
+READ8_MEMBER(ncr5380n_device::read)
{
switch (offset & 7)
{
- case 0:
- return scsidata_r();
+ case 0:
+ return scsidata_r(space, offset);
- case 1:
- return icmd_r();
+ case 1:
+ return icmd_r(space, offset);
- case 2:
- return mode_r();
+ case 2:
+ return mode_r(space, offset);
- case 3:
- return command_r();
+ case 3:
+ return command_r(space, offset);
- case 4:
- return status_r();
+ case 4:
+ return status_r(space, offset);
- case 5:
- return busandstatus_r();
+ case 5:
+ return busandstatus_r(space, offset);
- case 6:
- return indata_r();
+ case 6:
+ return indata_r(space, offset);
- case 7:
- return resetparityirq_r();
+ case 7:
+ return resetparityirq_r(space, offset);
}
return 0xff;
}
-void ncr5380n_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(ncr5380n_device::write)
{
// logerror("%x to 5380 @ %x\n", data, offset);
switch (offset & 7)
{
- case 0:
- outdata_w(data);
- break;
+ case 0:
+ outdata_w(space, offset, data);
+ break;
- case 1:
- icmd_w(data);
- break;
+ case 1:
+ icmd_w(space, offset, data);
+ break;
- case 2:
- mode_w(data);
- break;
+ case 2:
+ mode_w(space, offset, data);
+ break;
- case 3:
- command_w(data);
- break;
+ case 3:
+ command_w(space, offset, data);
+ break;
- case 4:
- selenable_w(data);
- break;
+ case 4:
+ selenable_w(space, offset, data);
+ break;
- case 5:
- startdmasend_w(data);
- break;
+ case 5:
+ startdmasend_w(space, offset, data);
+ break;
- case 6:
- startdmatargetrx_w(data);
- break;
+ case 6:
+ startdmatargetrx_w(space, offset, data);
+ break;
- case 7:
- startdmainitrx_w(data);
- break;
+ case 7:
+ startdmainitrx_w(space, offset, data);
+ break;
}
}
diff --git a/src/devices/machine/ncr5380n.h b/src/devices/machine/ncr5380n.h
index 365df032419..973616c65a3 100644
--- a/src/devices/machine/ncr5380n.h
+++ b/src/devices/machine/ncr5380n.h
@@ -15,6 +15,11 @@
#include "machine/nscsi_bus.h"
+#define MCFG_NCR5380N_IRQ_HANDLER(_devcb) \
+ downcast<ncr5380n_device &>(*device).set_irq_handler(DEVCB_##_devcb);
+
+#define MCFG_NCR5380N_DRQ_HANDLER(_devcb) \
+ downcast<ncr5380n_device &>(*device).set_drq_handler(DEVCB_##_devcb);
class ncr5380n_device : public nscsi_device
{
@@ -22,11 +27,11 @@ public:
ncr5380n_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
- auto irq_handler() { return m_irq_handler.bind(); }
- auto drq_handler() { return m_drq_handler.bind(); }
+ template <class Object> devcb_base &set_irq_handler(Object &&cb) { return m_irq_handler.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_drq_handler(Object &&cb) { return m_drq_handler.set_callback(std::forward<Object>(cb)); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
uint8_t dma_r();
void dma_w(uint8_t val);
@@ -198,22 +203,22 @@ private:
void map(address_map &map);
- uint8_t scsidata_r();
- void outdata_w(uint8_t data);
- uint8_t icmd_r();
- void icmd_w(uint8_t data);
- uint8_t mode_r();
- void mode_w(uint8_t data);
- uint8_t command_r();
- void command_w(uint8_t data);
- uint8_t status_r();
- void selenable_w(uint8_t data);
- uint8_t busandstatus_r();
- void startdmasend_w(uint8_t data);
- uint8_t indata_r();
- void startdmatargetrx_w(uint8_t data);
- uint8_t resetparityirq_r();
- void startdmainitrx_w(uint8_t data);
+ DECLARE_READ8_MEMBER(scsidata_r);
+ DECLARE_WRITE8_MEMBER(outdata_w);
+ DECLARE_READ8_MEMBER(icmd_r);
+ DECLARE_WRITE8_MEMBER(icmd_w);
+ DECLARE_READ8_MEMBER(mode_r);
+ DECLARE_WRITE8_MEMBER(mode_w);
+ DECLARE_READ8_MEMBER(command_r);
+ DECLARE_WRITE8_MEMBER(command_w);
+ DECLARE_READ8_MEMBER(status_r);
+ DECLARE_WRITE8_MEMBER(selenable_w);
+ DECLARE_READ8_MEMBER(busandstatus_r);
+ DECLARE_WRITE8_MEMBER(startdmasend_w);
+ DECLARE_READ8_MEMBER(indata_r);
+ DECLARE_WRITE8_MEMBER(startdmatargetrx_w);
+ DECLARE_READ8_MEMBER(resetparityirq_r);
+ DECLARE_WRITE8_MEMBER(startdmainitrx_w);
devcb_write_line m_irq_handler;
devcb_write_line m_drq_handler;
diff --git a/src/devices/machine/ncr5385.cpp b/src/devices/machine/ncr5385.cpp
index 6c1f4a3bb4e..d5cd98a4a5f 100644
--- a/src/devices/machine/ncr5385.cpp
+++ b/src/devices/machine/ncr5385.cpp
@@ -34,7 +34,7 @@ void ncr5385_device::device_reset()
m_diag_status_reg = DIAG_COMPLETE;
}
-void ncr5385_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(ncr5385_device::write)
{
switch (offset)
{
@@ -96,7 +96,7 @@ void ncr5385_device::write(offs_t offset, uint8_t data)
}
}
-uint8_t ncr5385_device::read(offs_t offset)
+READ8_MEMBER(ncr5385_device::read)
{
switch (offset)
{
diff --git a/src/devices/machine/ncr5385.h b/src/devices/machine/ncr5385.h
index a1dec052045..3a60ca0a6c8 100644
--- a/src/devices/machine/ncr5385.h
+++ b/src/devices/machine/ncr5385.h
@@ -44,6 +44,14 @@
#pragma once
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_NCR5385_INT_CB(_int) \
+ downcast<ncr5385_device &>(*device).set_int_callback(DEVCB_##_int);
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -56,10 +64,11 @@ public:
// construction/destruction
ncr5385_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ template <class Object> devcb_base &set_int_callback(Object &&cb) { return m_int.set_callback(std::forward<Object>(cb)); }
auto irq() { return m_int.bind(); }
- void write(offs_t offset, uint8_t data);
- uint8_t read(offs_t offset);
+ DECLARE_WRITE8_MEMBER(write);
+ DECLARE_READ8_MEMBER(read);
protected:
// device-level overrides
diff --git a/src/devices/machine/ncr5390.cpp b/src/devices/machine/ncr5390.cpp
index 10b7510d707..62c62a038b6 100644
--- a/src/devices/machine/ncr5390.cpp
+++ b/src/devices/machine/ncr5390.cpp
@@ -1,12 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
-/*
- * TODO
- * - 16 bit dma order, alignment and last byte handling
- * - clean up variable naming and protection
- */
-
#include "emu.h"
#include "ncr5390.h"
@@ -20,10 +14,9 @@
#define DELAY_HACK
-DEFINE_DEVICE_TYPE(NCR5390, ncr5390_device, "ncr5390", "NCR 5390 SCSI Controller")
-DEFINE_DEVICE_TYPE(NCR53C90A, ncr53c90a_device, "ncr53c90a", "NCR 53C90A Advanced SCSI Controller")
-DEFINE_DEVICE_TYPE(NCR53C94, ncr53c94_device, "ncr53c94", "NCR 53C94 Advanced SCSI Controller")
-DEFINE_DEVICE_TYPE(NCR53CF94, ncr53cf94_device, "ncr53cf94", "NCR 53CF94-2 Fast SCSI Controller") // TODO: differences not emulated
+DEFINE_DEVICE_TYPE(NCR5390, ncr5390_device, "ncr5390", "NCR 5390 SCSI")
+DEFINE_DEVICE_TYPE(NCR53C90A, ncr53c90a_device, "ncr53c90a", "NCR 53C90A SCSI")
+DEFINE_DEVICE_TYPE(NCR53C94, ncr53c94_device, "ncr53c94", "NCR 53C94 SCSI")
void ncr5390_device::map(address_map &map)
{
@@ -40,38 +33,38 @@ void ncr5390_device::map(address_map &map)
map(0x9, 0x9).w(FUNC(ncr5390_device::clock_w));
}
-uint8_t ncr5390_device::read(offs_t offset)
+READ8_MEMBER(ncr5390_device::read)
{
switch (offset)
{
- case 0: return tcounter_lo_r();
- case 1: return tcounter_hi_r();
- case 2: return fifo_r();
- case 3: return command_r();
- case 4: return status_r();
- case 5: return istatus_r();
- case 6: return seq_step_r();
- case 7: return fifo_flags_r();
- case 8: return conf_r();
- default: return 0xff;
+ case 0: return tcounter_lo_r(space, 0);
+ case 1: return tcounter_hi_r(space, 0);
+ case 2: return fifo_r(space, 0);
+ case 3: return command_r(space, 0);
+ case 4: return status_r(space, 0);
+ case 5: return istatus_r(space, 0);
+ case 6: return seq_step_r(space, 0);
+ case 7: return fifo_flags_r(space, 0);
+ case 8: return conf_r(space, 0);
+ default: return 0;
}
}
-void ncr5390_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(ncr5390_device::write)
{
switch (offset)
{
- case 0: tcount_lo_w(data); break;
- case 1: tcount_hi_w(data); break;
- case 2: fifo_w(data); break;
- case 3: command_w(data); break;
- case 4: bus_id_w(data); break;
- case 5: timeout_w(data); break;
- case 6: sync_period_w(data); break;
- case 7: sync_offset_w(data); break;
- case 8: conf_w(data); break;
- case 9: clock_w(data); break;
- case 10: test_w(data); break;
+ case 0: tcount_lo_w(space, 0, data); break;
+ case 1: tcount_hi_w(space, 0, data); break;
+ case 2: fifo_w(space, 0, data); break;
+ case 3: command_w(space, 0, data); break;
+ case 4: bus_id_w(space, 0, data); break;
+ case 5: timeout_w(space, 0, data); break;
+ case 6: sync_period_w(space, 0, data); break;
+ case 7: sync_offset_w(space, 0, data); break;
+ case 8: conf_w(space, 0, data); break;
+ case 9: clock_w(space, 0, data); break;
+ case 10: test_w(space, 0, data); break;
default: break;
}
}
@@ -83,18 +76,18 @@ void ncr53c90a_device::map(address_map &map)
map(0xb, 0xb).rw(FUNC(ncr53c90a_device::conf2_r), FUNC(ncr53c90a_device::conf2_w));
}
-uint8_t ncr53c90a_device::read(offs_t offset)
+READ8_MEMBER(ncr53c90a_device::read)
{
if (offset == 11)
- return conf2_r();
- return ncr5390_device::read(offset);
+ return conf2_r(space, 0);
+ return ncr5390_device::read(space, offset);
}
-void ncr53c90a_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(ncr53c90a_device::write)
{
if (offset == 11)
- return conf2_w(data);
- ncr5390_device::write(offset, data);
+ return conf2_w(space, 0, data);
+ ncr5390_device::write(space, offset, data);
}
void ncr53c94_device::map(address_map &map)
@@ -105,21 +98,21 @@ void ncr53c94_device::map(address_map &map)
map(0xf, 0xf).w(FUNC(ncr53c94_device::fifo_align_w));
}
-uint8_t ncr53c94_device::read(offs_t offset)
+READ8_MEMBER(ncr53c94_device::read)
{
if (offset == 12)
- return conf3_r();
- return ncr53c90a_device::read(offset);
+ return conf3_r(space, 0);
+ return ncr53c90a_device::read(space, offset);
}
-void ncr53c94_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(ncr53c94_device::write)
{
if (offset == 11)
- conf3_w(data);
+ conf3_w(space, 0, data);
else if (offset == 15)
- fifo_align_w(data);
+ fifo_align_w(space, 0, data);
else
- ncr53c90a_device::write(offset, data);
+ ncr53c90a_device::write(space, offset, data);
}
ncr5390_device::ncr5390_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
@@ -148,19 +141,8 @@ ncr53c90a_device::ncr53c90a_device(const machine_config &mconfig, const char *ta
}
ncr53c94_device::ncr53c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : ncr53c94_device(mconfig, NCR53C94, tag, owner, clock)
-{
-}
-
-ncr53c94_device::ncr53c94_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : ncr53c90a_device(mconfig, type, tag, owner, clock)
+ : ncr53c90a_device(mconfig, NCR53C94, tag, owner, clock)
, config3(0)
- , m_busmd(BUSMD_0)
-{
-}
-
-ncr53cf94_device::ncr53cf94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : ncr53c94_device(mconfig, NCR53CF94, tag, owner, clock)
{
}
@@ -195,7 +177,10 @@ void ncr5390_device::device_start()
m_irq_handler.resolve_safe();
m_drq_handler.resolve_safe();
+ tcount = 0;
+ tcounter = 0;
config = 0;
+ status = 0;
bus_id = 0;
select_timeout = 0;
tm = timer_alloc(0);
@@ -211,28 +196,26 @@ void ncr5390_device::device_reset()
sync_offset = 0;
seq = 0;
config &= 7;
- status = 0;
+ status &= 0x90;
istatus = 0;
irq = false;
m_irq_handler(irq);
+ reset_soft();
+}
+void ncr5390_device::reset_soft()
+{
state = IDLE;
scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL);
+ status &= 0xef;
drq = false;
test_mode = false;
m_drq_handler(drq);
-
- scsi_bus->ctrl_w(scsi_refid, 0, S_RST);
- tcount = 0;
- tcounter = 0;
-
reset_disconnect();
}
void ncr5390_device::reset_disconnect()
{
- scsi_bus->ctrl_w(scsi_refid, 0, ~S_RST);
-
command_pos = 0;
command_length = 0;
memset(command, 0, sizeof(command));
@@ -275,17 +258,6 @@ void ncr5390_device::step(bool timeout)
case IDLE:
break;
- case BUSRESET_WAIT_INT:
- state = IDLE;
- scsi_bus->ctrl_w(scsi_refid, 0, S_RST);
- reset_disconnect();
-
- if (!(config & 0x40)) {
- istatus |= I_SCSI_RESET;
- check_irq();
- }
- break;
-
case ARB_COMPLETE << SUB_SHIFT: {
if(!timeout)
break;
@@ -295,7 +267,7 @@ void ncr5390_device::step(bool timeout)
if(win != scsi_id) {
scsi_bus->data_w(scsi_refid, 0);
scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
- fatalerror("ncr5390_device::step need to wait for bus free\n");
+ fatalerror("need to wait for bus free\n");
}
state = (state & STATE_MASK) | (ARB_ASSERT_SEL << SUB_SHIFT);
scsi_bus->ctrl_w(scsi_refid, S_SEL, S_SEL);
@@ -435,13 +407,15 @@ void ncr5390_device::step(bool timeout)
case DISC_SEL_ARBITRATION_INIT:
// wait until a command is in the fifo
- if (!fifo_pos) {
+ if (!fifo_pos && dma_command && !(status & S_TC0)) {
// dma starts after bus arbitration/selection is complete
- check_drq();
+ dma_set(DMA_OUT);
+ step(false);
break;
}
- command_length = fifo_pos + tcounter;
+ // "with atn" variants have a message byte before the command descriptor
+ command_length = (c == CD_SELECT) ? derive_msg_size(fifo[0]) : 1;
state = DISC_SEL_ARBITRATION;
step(false);
break;
@@ -475,6 +449,7 @@ void ncr5390_device::step(bool timeout)
seq = 1;
function_bus_complete();
} else {
+ command_length = derive_msg_size(fifo[0]);
state = DISC_SEL_WAIT_REQ;
}
break;
@@ -485,8 +460,6 @@ void ncr5390_device::step(bool timeout)
if((ctrl & S_PHASE_MASK) != S_PHASE_COMMAND) {
if(!command_length)
seq = 4;
- else
- seq = 2;
scsi_bus->ctrl_wait(scsi_refid, 0, S_REQ);
function_bus_complete();
break;
@@ -707,7 +680,7 @@ void ncr5390_device::function_bus_complete()
state = IDLE;
istatus |= I_FUNCTION|I_BUS;
dma_set(DMA_NONE);
- check_drq();
+ drq_clear();
check_irq();
}
@@ -717,7 +690,7 @@ void ncr5390_device::function_complete()
state = IDLE;
istatus |= I_FUNCTION;
dma_set(DMA_NONE);
- check_drq();
+ drq_clear();
check_irq();
}
@@ -727,7 +700,7 @@ void ncr5390_device::bus_complete()
state = IDLE;
istatus |= I_BUS;
dma_set(DMA_NONE);
- check_drq();
+ drq_clear();
check_irq();
}
@@ -744,25 +717,25 @@ void ncr5390_device::delay_cycles(int cycles)
tm->adjust(clocks_to_attotime(cycles));
}
-uint8_t ncr5390_device::tcounter_lo_r()
+READ8_MEMBER(ncr5390_device::tcounter_lo_r)
{
LOG("tcounter_lo_r %02x (%s)\n", tcounter & 0xff, machine().describe_context());
return tcounter;
}
-void ncr5390_device::tcount_lo_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::tcount_lo_w)
{
tcount = (tcount & 0xff00) | data;
LOG("tcount_lo_w %02x (%s)\n", data, machine().describe_context());
}
-uint8_t ncr5390_device::tcounter_hi_r()
+READ8_MEMBER(ncr5390_device::tcounter_hi_r)
{
LOG("tcounter_hi_r %02x (%s)\n", tcounter >> 8, machine().describe_context());
return tcounter >> 8;
}
-void ncr5390_device::tcount_hi_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::tcount_hi_w)
{
tcount = (tcount & 0x00ff) | (data << 8);
LOG("tcount_hi_w %02x (%s)\n", data, machine().describe_context());
@@ -773,17 +746,19 @@ uint8_t ncr5390_device::fifo_pop()
uint8_t r = fifo[0];
fifo_pos--;
memmove(fifo, fifo+1, fifo_pos);
- check_drq();
+ if((!fifo_pos) && dma_dir == DMA_OUT && !(status & S_TC0))
+ drq_set();
return r;
}
void ncr5390_device::fifo_push(uint8_t val)
{
fifo[fifo_pos++] = val;
- check_drq();
+ if(!drq && dma_dir == DMA_IN && !(status & S_TC0))
+ drq_set();
}
-uint8_t ncr5390_device::fifo_r()
+READ8_MEMBER(ncr5390_device::fifo_r)
{
uint8_t r;
if(fifo_pos) {
@@ -796,20 +771,20 @@ uint8_t ncr5390_device::fifo_r()
return r;
}
-void ncr5390_device::fifo_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::fifo_w)
{
LOGMASKED(LOG_FIFO, "fifo_w 0x%02x fifo_pos %d (%s)\n", data, fifo_pos, machine().describe_context());
if(fifo_pos != 16)
fifo[fifo_pos++] = data;
}
-uint8_t ncr5390_device::command_r()
+READ8_MEMBER(ncr5390_device::command_r)
{
LOG("command_r (%s)\n", machine().describe_context());
return command[0];
}
-void ncr5390_device::command_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::command_w)
{
LOG("command_w %02x command_pos %d (%s)\n", data, command_pos, machine().describe_context());
if(command_pos == 2) {
@@ -859,8 +834,6 @@ void ncr5390_device::start_command()
// clear transfer count zero flag when counter is reloaded
status &= ~S_TC0;
}
- else
- tcounter = 0;
switch(c) {
case CM_NOP:
@@ -881,9 +854,13 @@ void ncr5390_device::start_command()
case CM_RESET_BUS:
LOGMASKED(LOG_COMMAND, "Reset SCSI bus\n");
- state = BUSRESET_WAIT_INT;
- scsi_bus->ctrl_w(scsi_refid, S_RST, S_RST);
- delay(130);
+ reset_soft();
+ // FIXME: this interrupt should be generated when the reset is reflected
+ // back into the device, and not when the device starts the scsi reset
+ if (!(config & 0x40)) {
+ istatus = I_SCSI_RESET;
+ check_irq();
+ }
break;
case CD_RESELECT:
@@ -901,7 +878,6 @@ void ncr5390_device::start_command()
"Select with ATN and stop sequence\n");
seq = 0;
state = DISC_SEL_ARBITRATION_INIT;
- dma_set(dma_command ? DMA_OUT : DMA_NONE);
arbitrate();
break;
@@ -920,7 +896,6 @@ void ncr5390_device::start_command()
state = INIT_XFR;
xfr_phase = scsi_bus->ctrl_r() & S_PHASE_MASK;
dma_set(dma_command ? ((xfr_phase & S_INP) ? DMA_IN : DMA_OUT) : DMA_NONE);
- check_drq();
step(false);
break;
@@ -961,14 +936,8 @@ void ncr5390_device::start_command()
command_pop_and_chain();
break;
- case CI_RESET_ATN:
- LOGMASKED(LOG_COMMAND, "Reset ATN\n");
- scsi_bus->ctrl_w(scsi_refid, 0, S_ATN);
- command_pop_and_chain();
- break;
-
default:
- fatalerror("ncr5390_device::start_command unimplemented command %02x\n", c);
+ fatalerror("start unimplemented command %02x\n", c);
}
}
@@ -984,6 +953,12 @@ bool ncr5390_device::check_valid_command(uint8_t cmd)
return false;
}
+int ncr5390_device::derive_msg_size(uint8_t msg_id)
+{
+ const static int sizes[8] = { 6, 10, 6, 6, 6, 12, 6, 10 };
+ return sizes[msg_id >> 5];
+}
+
void ncr5390_device::arbitrate()
{
state = (state & STATE_MASK) | (ARB_COMPLETE << SUB_SHIFT);
@@ -1001,7 +976,7 @@ void ncr5390_device::check_irq()
}
-uint8_t ncr5390_device::status_r()
+READ8_MEMBER(ncr5390_device::status_r)
{
uint32_t ctrl = scsi_bus->ctrl_r();
uint8_t res = status | (ctrl & S_MSG ? 4 : 0) | (ctrl & S_CTL ? 2 : 0) | (ctrl & S_INP ? 1 : 0);
@@ -1010,13 +985,13 @@ uint8_t ncr5390_device::status_r()
return res;
}
-void ncr5390_device::bus_id_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::bus_id_w)
{
bus_id = data & 7;
LOG("bus_id=%d\n", bus_id);
}
-uint8_t ncr5390_device::istatus_r()
+READ8_MEMBER(ncr5390_device::istatus_r)
{
uint8_t res = istatus;
@@ -1034,39 +1009,39 @@ uint8_t ncr5390_device::istatus_r()
return res;
}
-void ncr5390_device::timeout_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::timeout_w)
{
LOG("timeout_w 0x%02x\n", data);
select_timeout = data;
}
-uint8_t ncr5390_device::seq_step_r()
+READ8_MEMBER(ncr5390_device::seq_step_r)
{
LOG("seq_step_r %d (%s)\n", seq, machine().describe_context());
return seq;
}
-void ncr5390_device::sync_period_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::sync_period_w)
{
sync_period = data & 0x1f;
}
-uint8_t ncr5390_device::fifo_flags_r()
+READ8_MEMBER(ncr5390_device::fifo_flags_r)
{
return fifo_pos;
}
-void ncr5390_device::sync_offset_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::sync_offset_w)
{
sync_offset = data & 0x0f;
}
-uint8_t ncr5390_device::conf_r()
+READ8_MEMBER(ncr5390_device::conf_r)
{
return config;
}
-void ncr5390_device::conf_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::conf_w)
{
config = data;
scsi_id = data & 7;
@@ -1076,13 +1051,13 @@ void ncr5390_device::conf_w(uint8_t data)
test_mode = true;
}
-void ncr5390_device::test_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::test_w)
{
if (test_mode)
logerror("test_w %d (%s) - test mode not implemented\n", data, machine().describe_context());
}
-void ncr5390_device::clock_w(uint8_t data)
+WRITE8_MEMBER(ncr5390_device::clock_w)
{
clock_conv = data & 0x07;
}
@@ -1090,17 +1065,16 @@ void ncr5390_device::clock_w(uint8_t data)
void ncr5390_device::dma_set(int dir)
{
dma_dir = dir;
-
- // account for data already in the fifo
- if (dir == DMA_OUT && fifo_pos)
- decrement_tcounter(fifo_pos);
+ if(dma_dir == DMA_OUT && fifo_pos != 16 && ((tcounter > fifo_pos) || !tcounter))
+ drq_set();
}
void ncr5390_device::dma_w(uint8_t val)
{
fifo_push(val);
decrement_tcounter();
- check_drq();
+ if(fifo_pos == 16 || (status & S_TC0))
+ drq_clear();
step(false);
}
@@ -1108,41 +1082,34 @@ uint8_t ncr5390_device::dma_r()
{
uint8_t r = fifo_pop();
decrement_tcounter();
- check_drq();
+ if(!fifo_pos || (status & S_TC0))
+ drq_clear();
step(false);
return r;
}
-void ncr5390_device::check_drq()
+void ncr5390_device::drq_set()
{
- bool drq_state = drq;
-
- switch (dma_dir) {
- case DMA_NONE:
- drq_state = false;
- break;
-
- case DMA_IN: // device to memory
- drq_state = !(status & S_TC0) && fifo_pos;
- break;
-
- case DMA_OUT: // memory to device
- drq_state = !(status & S_TC0) && fifo_pos < 16;
- break;
+ if(!drq) {
+ drq = true;
+ m_drq_handler(drq);
}
+}
- if (drq_state != drq) {
- drq = drq_state;
+void ncr5390_device::drq_clear()
+{
+ if(drq) {
+ drq = false;
m_drq_handler(drq);
}
}
-void ncr5390_device::decrement_tcounter(int count)
+void ncr5390_device::decrement_tcounter()
{
if (!dma_command)
return;
- tcounter -= count;
+ tcounter--;
if (tcounter == 0)
status |= S_TC0;
}
@@ -1175,14 +1142,14 @@ void ncr53c90a_device::device_start()
ncr5390_device::device_start();
}
-void ncr53c90a_device::device_reset()
+void ncr53c90a_device::reset_soft()
{
config2 = 0;
- ncr5390_device::device_reset();
+ ncr5390_device::reset_soft();
}
-uint8_t ncr53c90a_device::status_r()
+READ8_MEMBER(ncr53c90a_device::status_r)
{
uint32_t ctrl = scsi_bus->ctrl_r();
uint8_t res = (irq ? S_INTERRUPT : 0) | status | (ctrl & S_MSG ? 4 : 0) | (ctrl & S_CTL ? 2 : 0) | (ctrl & S_INP ? 1 : 0);
@@ -1213,75 +1180,9 @@ void ncr53c94_device::device_start()
ncr53c90a_device::device_start();
}
-void ncr53c94_device::device_reset()
+void ncr53c94_device::reset_soft()
{
config3 = 0;
- ncr53c90a_device::device_reset();
-}
-
-u16 ncr53c94_device::dma16_r()
-{
- // check fifo underflow
- if (fifo_pos < 2)
- fatalerror("ncr53c94_device::dma16_r fifo_pos %d\n", fifo_pos);
-
- // pop two bytes from fifo
- u16 const data = (fifo[0] << 8) | fifo[1];
- fifo_pos -= 2;
- memmove(fifo, fifo + 2, fifo_pos);
-
- // update drq
- decrement_tcounter(2);
- check_drq();
-
- step(false);
-
- return data;
-}
-
-void ncr53c94_device::dma16_w(u16 data)
-{
- // check fifo overflow
- if (fifo_pos > 14)
- fatalerror("ncr53c94_device::dma16_w fifo_pos %d\n", fifo_pos);
-
- // push two bytes into fifo
- fifo[fifo_pos++] = data >> 8;
- fifo[fifo_pos++] = data;
-
- // update drq
- decrement_tcounter(2);
- check_drq();
-
- step(false);
-}
-
-void ncr53c94_device::check_drq()
-{
- if (m_busmd != BUSMD_0)
- {
- bool drq_state = drq;
-
- switch (dma_dir) {
- case DMA_NONE:
- drq_state = false;
- break;
-
- case DMA_IN: // device to memory
- drq_state = !(status & S_TC0) && fifo_pos > 1;
- break;
-
- case DMA_OUT: // memory to device
- drq_state = !(status & S_TC0) && fifo_pos < 15;
- break;
- }
-
- if (drq_state != drq) {
- drq = drq_state;
- m_drq_handler(drq);
- }
- }
- else
- ncr5390_device::check_drq();
+ ncr53c90a_device::reset_soft();
}
diff --git a/src/devices/machine/ncr5390.h b/src/devices/machine/ncr5390.h
index 7cc2469bde5..bf301bed266 100644
--- a/src/devices/machine/ncr5390.h
+++ b/src/devices/machine/ncr5390.h
@@ -7,46 +7,59 @@
#include "machine/nscsi_bus.h"
+#define MCFG_NCR5390_IRQ_HANDLER(_devcb) \
+ downcast<ncr5390_device &>(*device).set_irq_handler(DEVCB_##_devcb);
+
+#define MCFG_NCR5390_DRQ_HANDLER(_devcb) \
+ downcast<ncr5390_device &>(*device).set_drq_handler(DEVCB_##_devcb);
+
class ncr5390_device : public nscsi_device
{
public:
ncr5390_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
+ template <class Object> devcb_base &set_irq_handler(Object &&cb) { return m_irq_handler.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_drq_handler(Object &&cb) { return m_drq_handler.set_callback(std::forward<Object>(cb)); }
+
auto irq_handler_cb() { return m_irq_handler.bind(); }
auto drq_handler_cb() { return m_drq_handler.bind(); }
virtual void map(address_map &map);
- uint8_t tcounter_lo_r();
- void tcount_lo_w(uint8_t data);
- uint8_t tcounter_hi_r();
- void tcount_hi_w(uint8_t data);
- uint8_t fifo_r();
- void fifo_w(uint8_t data);
- uint8_t command_r();
- void command_w(uint8_t data);
- virtual uint8_t status_r();
- void bus_id_w(uint8_t data);
- uint8_t istatus_r();
- void timeout_w(uint8_t data);
- uint8_t seq_step_r();
- void sync_period_w(uint8_t data);
- uint8_t fifo_flags_r();
- void sync_offset_w(uint8_t data);
- uint8_t conf_r();
- void conf_w(uint8_t data);
- void test_w(uint8_t data);
- void clock_w(uint8_t data);
-
- virtual uint8_t read(offs_t offset);
- virtual void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(tcounter_lo_r);
+ DECLARE_WRITE8_MEMBER(tcount_lo_w);
+ DECLARE_READ8_MEMBER(tcounter_hi_r);
+ DECLARE_WRITE8_MEMBER(tcount_hi_w);
+ DECLARE_READ8_MEMBER(fifo_r);
+ DECLARE_WRITE8_MEMBER(fifo_w);
+ DECLARE_READ8_MEMBER(command_r);
+ DECLARE_WRITE8_MEMBER(command_w);
+ virtual DECLARE_READ8_MEMBER(status_r);
+ DECLARE_WRITE8_MEMBER(bus_id_w);
+ DECLARE_READ8_MEMBER(istatus_r);
+ DECLARE_WRITE8_MEMBER(timeout_w);
+ DECLARE_READ8_MEMBER(seq_step_r);
+ DECLARE_WRITE8_MEMBER(sync_period_w);
+ DECLARE_READ8_MEMBER(fifo_flags_r);
+ DECLARE_WRITE8_MEMBER(sync_offset_w);
+ DECLARE_READ8_MEMBER(conf_r);
+ DECLARE_WRITE8_MEMBER(conf_w);
+ DECLARE_WRITE8_MEMBER(test_w);
+ DECLARE_WRITE8_MEMBER(clock_w);
+
+ virtual DECLARE_READ8_MEMBER(read);
+ virtual DECLARE_WRITE8_MEMBER(write);
virtual void scsi_ctrl_changed() override;
uint8_t dma_r();
void dma_w(uint8_t val);
+ // memory mapped wrappers for dma read/write
+ DECLARE_READ8_MEMBER(mdma_r) { return dma_r(); }
+ DECLARE_WRITE8_MEMBER(mdma_w) { dma_w(data); }
+
protected:
ncr5390_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -207,11 +220,13 @@ protected:
bool test_mode;
void dma_set(int dir);
- virtual void check_drq();
+ void drq_set();
+ void drq_clear();
void start_command();
void step(bool timeout);
virtual bool check_valid_command(uint8_t cmd);
+ int derive_msg_size(uint8_t msg_id);
void function_complete();
void function_bus_complete();
void bus_complete();
@@ -220,6 +235,10 @@ protected:
void command_pop_and_chain();
void check_irq();
+protected:
+ virtual void reset_soft();
+
+private:
void reset_disconnect();
uint8_t fifo_pop();
@@ -230,7 +249,7 @@ protected:
void delay(int cycles);
void delay_cycles(int cycles);
- void decrement_tcounter(int count = 1);
+ void decrement_tcounter();
devcb_write_line m_irq_handler;
devcb_write_line m_drq_handler;
@@ -243,19 +262,19 @@ public:
virtual void map(address_map &map) override;
- virtual uint8_t status_r() override;
+ virtual DECLARE_READ8_MEMBER(status_r) override;
- uint8_t conf2_r() { return config2; };
- void conf2_w(uint8_t data) { config2 = data; };
+ DECLARE_READ8_MEMBER(conf2_r) { return config2; };
+ DECLARE_WRITE8_MEMBER(conf2_w) { config2 = data; };
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+ virtual DECLARE_READ8_MEMBER(read) override;
+ virtual DECLARE_WRITE8_MEMBER(write) override;
protected:
ncr53c90a_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 reset_soft() override;
virtual bool check_valid_command(uint8_t cmd) override;
@@ -264,18 +283,6 @@ protected:
S_INTERRUPT = 0x80,
};
- enum conf2_mask : u8
- {
- PGDP = 0x01, // pass through/generate data parity
- PGRP = 0x02, // pass through/generate register parity
- ACDPE = 0x04, // abort on command/data parity error
- S2FE = 0x08, // scsi-2 features enable
- TSDR = 0x10, // tri-state dma request
- SBO = 0x20, // select byte order
- LSP = 0x40, // latch scsi phase
- DAE = 0x80, // data alignment enable
- };
-
private:
u8 config2;
};
@@ -285,56 +292,26 @@ class ncr53c94_device : public ncr53c90a_device
public:
ncr53c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- enum busmd_t : u8
- {
- BUSMD_0 = 0, // single bus: 8-bit host, 8 bit dma
- BUSMD_1 = 1, // single bus: 8 bit host, 16 bit dma
- BUSMD_2 = 2, // two buses: 8 bit multiplexed host, 16 bit dma
- BUSMD_3 = 3, // two buses: 8 bit host, 16 bit dma
- };
- void set_busmd(busmd_t const busmd) { m_busmd = busmd; }
-
virtual void map(address_map &map) override;
- uint8_t conf3_r() { return config3; };
- void conf3_w(uint8_t data) { config3 = data; };
- void fifo_align_w(uint8_t data) { fifo_align = data; };
-
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+ DECLARE_READ8_MEMBER(conf3_r) { return config3; };
+ DECLARE_WRITE8_MEMBER(conf3_w) { config3 = data; };
+ DECLARE_WRITE8_MEMBER(fifo_align_w) { fifo_align = data; };
- u16 dma16_r();
- void dma16_w(u16 data);
+ virtual DECLARE_READ8_MEMBER(read) override;
+ virtual DECLARE_WRITE8_MEMBER(write) override;
protected:
- ncr53c94_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- enum conf3_mask : u8
- {
- BS8 = 0x01, // burst size 8
- MDM = 0x02, // modify dma mode
- LBTM = 0x04, // last byte transfer mode
- };
-
virtual void device_start() override;
- virtual void device_reset() override;
- virtual void check_drq() override;
+ virtual void reset_soft() override;
private:
u8 config3;
u8 fifo_align;
- busmd_t m_busmd;
-};
-
-class ncr53cf94_device : public ncr53c94_device
-{
-public:
- ncr53cf94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
DECLARE_DEVICE_TYPE(NCR5390, ncr5390_device)
DECLARE_DEVICE_TYPE(NCR53C90A, ncr53c90a_device)
DECLARE_DEVICE_TYPE(NCR53C94, ncr53c94_device)
-DECLARE_DEVICE_TYPE(NCR53CF94, ncr53cf94_device)
#endif // MAME_MACHINE_NCR5390_H
diff --git a/src/devices/machine/ncr539x.cpp b/src/devices/machine/ncr539x.cpp
index 09e0bee9f21..58c69a16ad1 100644
--- a/src/devices/machine/ncr539x.cpp
+++ b/src/devices/machine/ncr539x.cpp
@@ -280,7 +280,7 @@ void ncr539x_device::device_timer(emu_timer &timer, device_timer_id tid, int par
}
}
-uint8_t ncr539x_device::read(offs_t offset)
+READ8_MEMBER( ncr539x_device::read )
{
uint8_t rv = 0;
@@ -412,7 +412,7 @@ uint8_t ncr539x_device::read(offs_t offset)
return rv;
}
-void ncr539x_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( ncr539x_device::write )
{
//if (offset != 2)
LOG("539x: Write %02x @ %s (%02x) (%s)\n", data, wrregs[offset], offset, machine().describe_context());
diff --git a/src/devices/machine/ncr539x.h b/src/devices/machine/ncr539x.h
index 8172f4ea5f2..8caa26c25a1 100644
--- a/src/devices/machine/ncr539x.h
+++ b/src/devices/machine/ncr539x.h
@@ -14,6 +14,11 @@
// device stuff
+#define MCFG_NCR539X_OUT_IRQ_CB(_devcb) \
+ downcast<ncr539x_device &>(*device).set_out_irq_callback(DEVCB_##_devcb);
+
+#define MCFG_NCR539X_OUT_DRQ_CB(_devcb) \
+ downcast<ncr539x_device &>(*device).set_out_drq_callback(DEVCB_##_devcb);
class ncr539x_device : public legacy_scsi_host_adapter
{
@@ -21,12 +26,14 @@ public:
// construction/destruction
ncr539x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ template <class Object> devcb_base &set_out_irq_callback(Object &&cb) { return m_out_irq_cb.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_out_drq_callback(Object &&cb) { return m_out_drq_cb.set_callback(std::forward<Object>(cb)); }
auto irq_callback() { return m_out_irq_cb.bind(); }
auto drq_callback() { return m_out_drq_cb.bind(); }
// our API
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
void dma_read_data(int bytes, uint8_t *pData);
void dma_write_data(int bytes, uint8_t *pData);
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index 3e7580be5b9..648d435ace8 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -49,16 +49,21 @@ DEFINE_DEVICE_TYPE(NETLIST_STREAM_OUTPUT, netlist_mame_stream_output_device, "nl
// Special netlist extension devices ....
// ----------------------------------------------------------------------------------------
-class netlist_mame_device::netlist_mame_callbacks_t : public netlist::callbacks_t
+class netlist_mame_device::netlist_mame_t : public netlist::netlist_t
{
public:
- netlist_mame_callbacks_t(netlist_mame_device &parent)
- : netlist::callbacks_t()
+ netlist_mame_t(netlist_mame_device &parent, const pstring &aname)
+ : netlist::netlist_t(aname)
, m_parent(parent)
{
}
+ running_machine &machine() { return m_parent.machine(); }
+
+
+ netlist_mame_device &parent() { return m_parent; }
+
protected:
void vlog(const plib::plog_level &l, const pstring &ls) const override
{
@@ -90,24 +95,6 @@ private:
};
-class netlist_mame_device::netlist_mame_t : public netlist::netlist_t
-{
-public:
-
- netlist_mame_t(netlist_mame_device &parent, const pstring &aname)
- : netlist::netlist_t(aname, plib::make_unique<netlist_mame_device::netlist_mame_callbacks_t>(parent))
- , m_parent(parent)
- {
- }
-
- running_machine &machine() { return m_parent.machine(); }
- netlist_mame_device &parent() { return m_parent; }
-
-private:
- netlist_mame_device &m_parent;
-};
-
-
namespace {
// ----------------------------------------------------------------------------------------
@@ -117,13 +104,13 @@ namespace {
class NETLIB_NAME(analog_callback) : public netlist::device_t
{
public:
- NETLIB_NAME(analog_callback)(netlist::netlist_state_t &anetlist, const pstring &name)
+ NETLIB_NAME(analog_callback)(netlist::netlist_t &anetlist, const pstring &name)
: device_t(anetlist, name)
, m_in(*this, "IN")
, m_cpu_device(nullptr)
, m_last(*this, "m_last", 0)
{
- m_cpu_device = downcast<netlist_mame_cpu_device *>(&static_cast<netlist_mame_device::netlist_mame_t &>(exec()).parent());
+ m_cpu_device = downcast<netlist_mame_cpu_device *>(&downcast<netlist_mame_device::netlist_mame_t &>(netlist()).parent());
}
ATTR_COLD void reset() override
@@ -144,7 +131,7 @@ public:
// avoid calls due to noise
if (std::fabs(cur - m_last) > 1e-6)
{
- m_cpu_device->update_icount(exec().time());
+ m_cpu_device->update_time_x();
m_callback(cur, m_cpu_device->local_time());
m_cpu_device->check_mame_abort_slice();
m_last = cur;
@@ -165,13 +152,13 @@ private:
class NETLIB_NAME(logic_callback) : public netlist::device_t
{
public:
- NETLIB_NAME(logic_callback)(netlist::netlist_state_t &anetlist, const pstring &name)
+ NETLIB_NAME(logic_callback)(netlist::netlist_t &anetlist, const pstring &name)
: device_t(anetlist, name)
, m_in(*this, "IN")
, m_cpu_device(nullptr)
, m_last(*this, "m_last", 0)
{
- m_cpu_device = downcast<netlist_mame_cpu_device *>(&static_cast<netlist_mame_device::netlist_mame_t &>(exec()).parent());
+ m_cpu_device = downcast<netlist_mame_cpu_device *>(&downcast<netlist_mame_device::netlist_mame_t &>(netlist()).parent());
}
ATTR_COLD void reset() override
@@ -186,13 +173,13 @@ public:
NETLIB_UPDATEI()
{
- netlist::netlist_sig_t cur = m_in();
+ netlist_sig_t cur = m_in();
// FIXME: make this a parameter
// avoid calls due to noise
if (cur != m_last)
{
- m_cpu_device->update_icount(exec().time());
+ m_cpu_device->update_time_x();
m_callback(cur, m_cpu_device->local_time());
m_cpu_device->check_mame_abort_slice();
m_last = cur;
@@ -203,10 +190,9 @@ private:
netlist::logic_input_t m_in;
netlist_mame_logic_output_device::output_delegate m_callback;
netlist_mame_cpu_device *m_cpu_device;
- netlist::state_var<netlist::netlist_sig_t> m_last;
+ netlist::state_var<netlist_sig_t> m_last;
};
-
// ----------------------------------------------------------------------------------------
// Extensions to interface netlist with MAME code ....
// ----------------------------------------------------------------------------------------
@@ -214,26 +200,22 @@ private:
class netlist_source_memregion_t : public netlist::source_t
{
public:
- netlist_source_memregion_t(device_t &dev, pstring name)
- : netlist::source_t(), m_dev(dev), m_name(name)
+ netlist_source_memregion_t(netlist::setup_t &setup, pstring name)
+ : netlist::source_t(setup), m_name(name)
{
}
- virtual plib::unique_ptr<plib::pistream> stream(const pstring &name) override;
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
- device_t &m_dev;
pstring m_name;
};
class netlist_data_memregions_t : public netlist::source_t
{
public:
- netlist_data_memregions_t(device_t &dev);
+ netlist_data_memregions_t(netlist::setup_t &setup);
- virtual plib::unique_ptr<plib::pistream> stream(const pstring &name) override;
-
-private:
- device_t &m_dev;
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
};
@@ -241,31 +223,30 @@ private:
// memregion source support
// ----------------------------------------------------------------------------------------
-plib::unique_ptr<plib::pistream> netlist_source_memregion_t::stream(const pstring &name)
+std::unique_ptr<plib::pistream> netlist_source_memregion_t::stream(const pstring &name)
{
- //memory_region *mem = static_cast<netlist_mame_device::netlist_mame_t &>(setup().setup().exec()).machine().root_device().memregion(m_name.c_str());
- memory_region *mem = m_dev.machine().root_device().memregion(m_name.c_str());
- return plib::make_unique<plib::pimemstream>(mem->base(), mem->bytes());
+ memory_region *mem = downcast<netlist_mame_device::netlist_mame_t &>(setup().netlist()).machine().root_device().memregion(m_name.c_str());
+ return plib::make_unique_base<plib::pistream, plib::pimemstream>(mem->base(), mem->bytes());
}
-netlist_data_memregions_t::netlist_data_memregions_t(device_t &dev)
- : netlist::source_t(netlist::source_t::DATA), m_dev(dev)
+netlist_data_memregions_t::netlist_data_memregions_t(netlist::setup_t &setup)
+ : netlist::source_t(setup, netlist::source_t::DATA)
{
}
-plib::unique_ptr<plib::pistream> netlist_data_memregions_t::stream(const pstring &name)
+std::unique_ptr<plib::pistream> netlist_data_memregions_t::stream(const pstring &name)
{
- //memory_region *mem = static_cast<netlist_mame_device::netlist_mame_t &>(setup().setup().exec()).parent().memregion(name.c_str());
- memory_region *mem = m_dev.memregion(name.c_str());
+ memory_region *mem = downcast<netlist_mame_device::netlist_mame_t &>(setup().netlist()).parent().memregion(name.c_str());
+ //memory_region *mem = downcast<netlist_mame_t &>(setup().netlist()).machine().root_device().memregion(name.c_str());
if (mem != nullptr)
{
- return plib::make_unique<plib::pimemstream>(mem->base(), mem->bytes());
+ return plib::make_unique_base<plib::pistream, plib::pimemstream>(mem->base(), mem->bytes());
}
else
{
// This should be the last data provider being called - last resort
fatalerror("data named %s not found in device rom regions\n", name.c_str());
- return plib::unique_ptr<plib::pistream>(nullptr);
+ return std::unique_ptr<plib::pistream>(nullptr);
}
}
@@ -280,55 +261,44 @@ plib::unique_ptr<plib::pistream> netlist_data_memregions_t::stream(const pstring
class NETLIB_NAME(sound_out) : public netlist::device_t
{
public:
- NETLIB_NAME(sound_out)(netlist::netlist_state_t &anetlist, const pstring &name)
+ NETLIB_NAME(sound_out)(netlist::netlist_t &anetlist, const pstring &name)
: netlist::device_t(anetlist, name)
, m_channel(*this, "CHAN", 0)
, m_mult(*this, "MULT", 1000.0)
, m_offset(*this, "OFFSET", 0.0)
, m_buffer(nullptr)
- , m_bufsize(0)
- , m_sample_time(netlist::netlist_time::from_hz(1)) //sufficiently big enough
+ , m_sample(netlist::netlist_time::from_hz(1)) //sufficiently big enough
, m_in(*this, "IN")
, m_cur(0.0)
, m_last_pos(0)
- , m_last_buffer_time(*this, "m_last_buffer", netlist::netlist_time::zero())
+ , m_last_buffer(*this, "m_last_buffer", netlist::netlist_time::zero())
{
}
- //static const int BUFSIZE = 2048;
+ static const int BUFSIZE = 2048;
ATTR_COLD void reset() override
{
m_cur = 0.0;
m_last_pos = 0;
- m_last_buffer_time = netlist::netlist_time::zero();
+ m_last_buffer = netlist::netlist_time::zero();
}
ATTR_HOT void sound_update(const netlist::netlist_time &upto)
{
- int pos = (upto - m_last_buffer_time) / m_sample_time;
- if (pos > m_bufsize)
- throw emu_fatalerror("sound %s: pos %d exceeded bufsize %d\n", name().c_str(), pos, m_bufsize);
+ int pos = (upto - m_last_buffer) / m_sample;
+ if (pos >= BUFSIZE)
+ netlist().log().fatal("sound {1}: exceeded BUFSIZE\n", name().c_str());
while (m_last_pos < pos )
{
m_buffer[m_last_pos++] = (stream_sample_t) m_cur;
}
}
- ATTR_HOT void sound_update_fill(int samples)
- {
- if (samples > m_bufsize)
- throw emu_fatalerror("sound %s: pos %d exceeded bufsize %d\n", name().c_str(), samples, m_bufsize);
- while (m_last_pos < samples )
- {
- m_buffer[m_last_pos++] = (stream_sample_t) m_cur;
- }
- }
-
NETLIB_UPDATEI()
{
nl_double val = m_in() * m_mult() + m_offset();
- sound_update(exec().time());
+ sound_update(netlist().time());
/* ignore spikes */
if (std::abs(val) < 32767.0)
m_cur = val;
@@ -343,22 +313,21 @@ public:
ATTR_HOT void buffer_reset(const netlist::netlist_time &upto)
{
m_last_pos = 0;
- m_last_buffer_time = upto;
+ m_last_buffer = upto;
+ m_cur = 0.0;
}
netlist::param_int_t m_channel;
netlist::param_double_t m_mult;
netlist::param_double_t m_offset;
stream_sample_t *m_buffer;
- int m_bufsize;
-
- netlist::netlist_time m_sample_time;
+ netlist::netlist_time m_sample;
private:
netlist::analog_input_t m_in;
double m_cur;
int m_last_pos;
- netlist::state_var<netlist::netlist_time> m_last_buffer_time;
+ netlist::state_var<netlist::netlist_time> m_last_buffer;
};
// ----------------------------------------------------------------------------------------
@@ -368,57 +337,58 @@ private:
class NETLIB_NAME(sound_in) : public netlist::device_t
{
public:
-
- static const int MAX_INPUT_CHANNELS = 16;
-
- NETLIB_NAME(sound_in)(netlist::netlist_state_t &anetlist, const pstring &name)
+ NETLIB_NAME(sound_in)(netlist::netlist_t &anetlist, const pstring &name)
: netlist::device_t(anetlist, name)
- , m_inc(netlist::netlist_time::from_nsec(1))
, m_feedback(*this, "FB") // clock part
, m_Q(*this, "Q")
, m_pos(0)
- , m_num_channels(0)
+ , m_num_channel(0)
{
connect(m_feedback, m_Q);
+ m_inc = netlist::netlist_time::from_nsec(1);
+
for (int i = 0; i < MAX_INPUT_CHANNELS; i++)
{
- m_channels[i].m_param_name = netlist::pool().make_poolptr<netlist::param_str_t>(*this, plib::pfmt("CHAN{1}")(i), "");
- m_channels[i].m_param_mult = netlist::pool().make_poolptr<netlist::param_double_t>(*this, plib::pfmt("MULT{1}")(i), 1.0);
- m_channels[i].m_param_offset = netlist::pool().make_poolptr<netlist::param_double_t>(*this, plib::pfmt("OFFSET{1}")(i), 0.0);
+ m_param_name[i] = std::make_unique<netlist::param_str_t>(*this, plib::pfmt("CHAN{1}")(i), "");
+ m_param_mult[i] = std::make_unique<netlist::param_double_t>(*this, plib::pfmt("MULT{1}")(i), 1.0);
+ m_param_offset[i] = std::make_unique<netlist::param_double_t>(*this, plib::pfmt("OFFSET{1}")(i), 0.0);
}
}
+ static const int MAX_INPUT_CHANNELS = 10;
+
ATTR_COLD void reset() override
{
m_pos = 0;
- for (auto & elem : m_channels)
- elem.m_buffer = nullptr;
+ for (auto & elem : m_buffer)
+ elem = nullptr;
}
- ATTR_COLD void resolve()
+ ATTR_COLD int resolve()
{
m_pos = 0;
for (int i = 0; i < MAX_INPUT_CHANNELS; i++)
{
- if ((*m_channels[i].m_param_name)() != pstring(""))
+ if ((*m_param_name[i])() != pstring(""))
{
- if (i != m_num_channels)
- state().log().fatal("sound input numbering has to be sequential!");
- m_num_channels++;
- m_channels[i].m_param = dynamic_cast<netlist::param_double_t *>(setup().find_param((*m_channels[i].m_param_name)(), true));
+ if (i != m_num_channel)
+ netlist().log().fatal("sound input numbering has to be sequential!");
+ m_num_channel++;
+ m_param[i] = dynamic_cast<netlist::param_double_t *>(setup().find_param((*m_param_name[i])(), true));
}
}
+ return m_num_channel;
}
NETLIB_UPDATEI()
{
- for (int i=0; i<m_num_channels; i++)
+ for (int i=0; i<m_num_channel; i++)
{
- if (m_channels[i].m_buffer == nullptr)
+ if (m_buffer[i] == nullptr)
break; // stop, called outside of stream_update
- const nl_double v = m_channels[i].m_buffer[m_pos];
- m_channels[i].m_param->setTo(v * (*m_channels[i].m_param_mult)() + (*m_channels[i].m_param_offset)());
+ const nl_double v = m_buffer[i][m_pos];
+ m_param[i]->setTo(v * (*m_param_mult[i])() + (*m_param_offset[i])());
}
m_pos++;
m_Q.net().toggle_and_push_to_queue(m_inc);
@@ -430,25 +400,19 @@ public:
m_pos = 0;
}
- struct channel
- {
- netlist::pool_owned_ptr<netlist::param_str_t> m_param_name;
- netlist::param_double_t *m_param;
- stream_sample_t *m_buffer;
- netlist::pool_owned_ptr<netlist::param_double_t> m_param_mult;
- netlist::pool_owned_ptr<netlist::param_double_t> m_param_offset;
- };
- channel m_channels[MAX_INPUT_CHANNELS];
+ std::unique_ptr<netlist::param_str_t> m_param_name[MAX_INPUT_CHANNELS];
+ netlist::param_double_t *m_param[MAX_INPUT_CHANNELS];
+ stream_sample_t *m_buffer[MAX_INPUT_CHANNELS];
+ std::unique_ptr<netlist::param_double_t> m_param_mult[MAX_INPUT_CHANNELS];
+ std::unique_ptr<netlist::param_double_t> m_param_offset[MAX_INPUT_CHANNELS];
netlist::netlist_time m_inc;
- int num_channels() { return m_num_channels; }
-
private:
netlist::logic_input_t m_feedback;
netlist::logic_output_t m_Q;
int m_pos;
- int m_num_channels;
+ int m_num_channel;
};
@@ -467,25 +431,26 @@ private:
netlist::setup_t &netlist_mame_device::setup()
{
- return m_netlist->nlstate().setup();
+ return m_netlist->setup();
}
-void netlist_mame_device::register_memregion_source(netlist::nlparse_t &setup, device_t &dev, const char *name)
+void netlist_mame_device::register_memregion_source(netlist::setup_t &setup, const char *name)
{
- setup.register_source(plib::make_unique<netlist_source_memregion_t>(dev, pstring(name)));
+ setup.register_source(plib::make_unique_base<netlist::source_t, netlist_source_memregion_t>(setup, pstring(name, pstring::UTF8)));
}
void netlist_mame_analog_input_device::write(const double val)
{
- m_value_for_device_timer = val * m_mult + m_offset;
- if (m_value_for_device_timer != (*m_param)())
- synchronize(0, 0, &m_value_for_device_timer);
-}
-
-void netlist_mame_analog_input_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- update_to_current_time();
- m_param->setTo(*((double *) ptr));
+ if (is_sound_device())
+ {
+ update_to_current_time();
+ m_param->setTo(val * m_mult + m_offset);
+ }
+ else
+ {
+ // FIXME: use device timer ....
+ m_param->setTo(val * m_mult + m_offset);
+ }
}
void netlist_mame_int_input_device::write(const uint32_t val)
@@ -504,13 +469,15 @@ void netlist_mame_logic_input_device::write(const uint32_t val)
void netlist_mame_int_input_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- update_to_current_time();
+ if (is_sound_device())
+ update_to_current_time();
m_param->setTo(param);
}
void netlist_mame_logic_input_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- update_to_current_time();
+ if (is_sound_device())
+ update_to_current_time();
m_param->setTo(param);
}
@@ -533,7 +500,7 @@ void netlist_mame_cpu_device::state_string_export(const device_state_entry &entr
if (entry.index() & 1)
str = string_format("%10.6f", *((double *)entry.dataptr()));
else
- str = string_format("%d", *((netlist::netlist_sig_t *)entry.dataptr()));
+ str = string_format("%d", *((netlist_sig_t *)entry.dataptr()));
}
}
@@ -561,7 +528,7 @@ netlist_mame_analog_input_device::netlist_mame_analog_input_device(const machine
void netlist_mame_analog_input_device::device_start()
{
LOGDEVCALLS("start\n");
- netlist::param_t *p = this->nl_owner().setup().find_param(pstring(m_param_name));
+ netlist::param_t *p = this->nl_owner().setup().find_param(pstring(m_param_name, pstring::UTF8));
m_param = dynamic_cast<netlist::param_double_t *>(p);
if (m_param == nullptr)
{
@@ -593,17 +560,16 @@ void netlist_mame_analog_output_device::set_params(const char *in_name, output_d
m_delegate = std::move(adelegate);
}
-void netlist_mame_analog_output_device::custom_netlist_additions(netlist::netlist_state_t &nlstate)
+void netlist_mame_analog_output_device::custom_netlist_additions(netlist::setup_t &setup)
{
- const pstring pin(m_in);
+ const pstring pin(m_in, pstring::UTF8);
pstring dname = pstring("OUT_") + pin;
- pstring dfqn = nlstate.setup().build_fqn(dname);
m_delegate.bind_relative_to(owner()->machine().root_device());
- auto dev = netlist::pool().make_poolptr<NETLIB_NAME(analog_callback)>(nlstate, dfqn);
+ plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(analog_callback)>(setup.netlist(), setup.build_fqn(dname));
static_cast<NETLIB_NAME(analog_callback) *>(dev.get())->register_callback(std::move(m_delegate));
- nlstate.add_dev(dfqn, std::move(dev));
- nlstate.setup().register_link(dname + ".IN", pin);
+ setup.netlist().register_dev(std::move(dev));
+ setup.register_link(dname + ".IN", pin);
}
void netlist_mame_analog_output_device::device_start()
@@ -629,18 +595,16 @@ void netlist_mame_logic_output_device::set_params(const char *in_name, output_de
m_delegate = std::move(adelegate);
}
-void netlist_mame_logic_output_device::custom_netlist_additions(netlist::netlist_state_t &nlstate)
+void netlist_mame_logic_output_device::custom_netlist_additions(netlist::setup_t &setup)
{
- pstring pin(m_in);
+ pstring pin(m_in, pstring::UTF8);
pstring dname = "OUT_" + pin;
- pstring dfqn = nlstate.setup().build_fqn(dname);
-
m_delegate.bind_relative_to(owner()->machine().root_device());
- auto dev = netlist::pool().make_poolptr<NETLIB_NAME(logic_callback)>(nlstate, dfqn);
+ plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(logic_callback)>(setup.netlist(), setup.build_fqn(dname));
static_cast<NETLIB_NAME(logic_callback) *>(dev.get())->register_callback(std::move(m_delegate));
- nlstate.add_dev(dfqn, std::move(dev));
- nlstate.setup().register_link(dname + ".IN", pin);
+ setup.netlist().register_dev(std::move(dev));
+ setup.register_link(dname + ".IN", pin);
}
void netlist_mame_logic_output_device::device_start()
@@ -674,7 +638,7 @@ void netlist_mame_int_input_device::set_params(const char *param_name, const uin
void netlist_mame_int_input_device::device_start()
{
LOGDEVCALLS("start\n");
- netlist::param_t *p = downcast<netlist_mame_device *>(this->owner())->setup().find_param(pstring(m_param_name));
+ netlist::param_t *p = downcast<netlist_mame_device *>(this->owner())->setup().find_param(pstring(m_param_name, pstring::UTF8));
m_param = dynamic_cast<netlist::param_int_t *>(p);
if (m_param == nullptr)
{
@@ -705,7 +669,7 @@ void netlist_mame_logic_input_device::set_params(const char *param_name, const u
void netlist_mame_logic_input_device::device_start()
{
LOGDEVCALLS("start\n");
- netlist::param_t *p = downcast<netlist_mame_device *>(this->owner())->setup().find_param(pstring(m_param_name));
+ netlist::param_t *p = downcast<netlist_mame_device *>(this->owner())->setup().find_param(pstring(m_param_name, pstring::UTF8));
m_param = dynamic_cast<netlist::param_logic_t *>(p);
if (m_param == nullptr)
{
@@ -736,7 +700,7 @@ void netlist_mame_ram_pointer_device::set_params(const char *param_name)
void netlist_mame_ram_pointer_device::device_start()
{
LOGDEVCALLS("start\n");
- netlist::param_t *p = downcast<netlist_mame_device *>(this->owner())->setup().find_param(pstring(m_param_name));
+ netlist::param_t *p = downcast<netlist_mame_device *>(this->owner())->setup().find_param(pstring(m_param_name, pstring::UTF8));
m_param = dynamic_cast<netlist::param_ptr_t *>(p);
if (m_param == nullptr)
{
@@ -769,17 +733,17 @@ void netlist_mame_stream_input_device::device_start()
LOGDEVCALLS("start\n");
}
-void netlist_mame_stream_input_device::custom_netlist_additions(netlist::netlist_state_t &nlstate)
+void netlist_mame_stream_input_device::custom_netlist_additions(netlist::setup_t &setup)
{
- if (!nlstate.setup().device_exists("STREAM_INPUT"))
- nlstate.setup().register_dev("NETDEV_SOUND_IN", "STREAM_INPUT");
+ if (!setup.device_exists("STREAM_INPUT"))
+ setup.register_dev("NETDEV_SOUND_IN", "STREAM_INPUT");
pstring sparam = plib::pfmt("STREAM_INPUT.CHAN{1}")(m_channel);
- nlstate.setup().register_param(sparam, pstring(m_param_name));
+ setup.register_param(sparam, pstring(m_param_name, pstring::UTF8));
sparam = plib::pfmt("STREAM_INPUT.MULT{1}")(m_channel);
- nlstate.setup().register_param(sparam, m_mult);
+ setup.register_param(sparam, m_mult);
sparam = plib::pfmt("STREAM_INPUT.OFFSET{1}")(m_channel);
- nlstate.setup().register_param(sparam, m_offset);
+ setup.register_param(sparam, m_offset);
}
// ----------------------------------------------------------------------------------------
@@ -805,18 +769,18 @@ void netlist_mame_stream_output_device::device_start()
LOGDEVCALLS("start\n");
}
-void netlist_mame_stream_output_device::custom_netlist_additions(netlist::netlist_state_t &nlstate)
+void netlist_mame_stream_output_device::custom_netlist_additions(netlist::setup_t &setup)
{
//NETLIB_NAME(sound_out) *snd_out;
pstring sname = plib::pfmt("STREAM_OUT_{1}")(m_channel);
//snd_out = dynamic_cast<NETLIB_NAME(sound_out) *>(setup.register_dev("nld_sound_out", sname));
- nlstate.setup().register_dev("NETDEV_SOUND_OUT", sname);
+ setup.register_dev("NETDEV_SOUND_OUT", sname);
- nlstate.setup().register_param(sname + ".CHAN" , m_channel);
- nlstate.setup().register_param(sname + ".MULT", m_mult);
- nlstate.setup().register_param(sname + ".OFFSET", m_offset);
- nlstate.setup().register_link(sname + ".IN", pstring(m_out_name));
+ setup.register_param(sname + ".CHAN" , m_channel);
+ setup.register_param(sname + ".MULT", m_mult);
+ setup.register_param(sname + ".OFFSET", m_offset);
+ setup.register_link(sname + ".IN", pstring(m_out_name, pstring::UTF8));
}
@@ -833,6 +797,7 @@ netlist_mame_device::netlist_mame_device(const machine_config &mconfig, device_t
: device_t(mconfig, type, tag, owner, clock)
, m_icount(0)
, m_old(netlist::netlist_time::zero())
+ , m_netlist(nullptr)
, m_setup_func(nullptr)
{
}
@@ -842,6 +807,12 @@ netlist_mame_device::~netlist_mame_device()
LOGDEVCALLS("~netlist_mame_device\n");
}
+void netlist_mame_device::set_constructor(void (*setup_func)(netlist::setup_t &))
+{
+ if (LOG_DEV_CALLS) logerror("set_constructor\n");
+ m_setup_func = setup_func;
+}
+
void netlist_mame_device::device_config_complete()
{
LOGDEVCALLS("device_config_complete %s\n", this->mconfig().gamedrv().name);
@@ -859,7 +830,7 @@ void netlist_mame_device::device_start()
//printf("clock is %d\n", clock());
- m_netlist = netlist::pool().make_poolptr<netlist_mame_t>(*this, "netlist");
+ m_netlist = global_alloc(netlist_mame_t(*this, "netlist"));
// register additional devices
@@ -872,12 +843,12 @@ void netlist_mame_device::device_start()
if( sdev != nullptr )
{
LOGDEVCALLS("Preparse subdevice %s/%s\n", d.name(), d.shortname());
- sdev->pre_parse_action(m_netlist->nlstate());
+ sdev->pre_parse_action(setup());
}
}
/* add default data provider for roms */
- setup().register_source(plib::make_unique<netlist_data_memregions_t>(*this));
+ setup().register_source(plib::make_unique_base<netlist::source_t, netlist_data_memregions_t>(setup()));
m_setup_func(setup());
@@ -888,15 +859,15 @@ void netlist_mame_device::device_start()
if( sdev != nullptr )
{
LOGDEVCALLS("Found subdevice %s/%s\n", d.name(), d.shortname());
- sdev->custom_netlist_additions(m_netlist->nlstate());
+ sdev->custom_netlist_additions(setup());
}
}
- setup().prepare_to_run();
+ netlist().start();
- netlist().nlstate().save(*this, m_rem, this->name(), "m_rem");
- netlist().nlstate().save(*this, m_div, this->name(), "m_div");
- netlist().nlstate().save(*this, m_old, this->name(), "m_old");
+ netlist().save(*this, m_rem, "m_rem");
+ netlist().save(*this, m_div, "m_div");
+ netlist().save(*this, m_old, "m_old");
save_state();
@@ -925,26 +896,29 @@ void netlist_mame_device::device_stop()
{
LOGDEVCALLS("device_stop\n");
netlist().stop();
+
+ global_free(m_netlist);
+ m_netlist = nullptr;
}
ATTR_COLD void netlist_mame_device::device_post_load()
{
LOGDEVCALLS("device_post_load\n");
- netlist().run_state_manager().post_load();
- netlist().nlstate().rebuild_lists();
+ netlist().state().post_load();
+ netlist().rebuild_lists();
}
ATTR_COLD void netlist_mame_device::device_pre_save()
{
LOGDEVCALLS("device_pre_save\n");
- netlist().run_state_manager().pre_save();
+ netlist().state().pre_save();
}
-void netlist_mame_device::update_icount(netlist::netlist_time time)
+void netlist_mame_device::update_time_x()
{
- const netlist::netlist_time newt(time);
+ const netlist::netlist_time newt(netlist().time());
const netlist::netlist_time delta(newt - m_old + m_rem);
const uint64_t d = delta / m_div;
m_old = newt;
@@ -960,7 +934,7 @@ void netlist_mame_device::check_mame_abort_slice()
ATTR_COLD void netlist_mame_device::save_state()
{
- for (auto const & s : netlist().run_state_manager().save_list())
+ for (auto const & s : netlist().state().save_list())
{
netlist().log().debug("saving state for {1}\n", s->m_name.c_str());
if (s->m_dt.is_float)
@@ -1023,18 +997,17 @@ void netlist_mame_cpu_device::device_start()
state_add(STATE_GENPC, "GENPC", m_genPC).noshow();
state_add(STATE_GENPCBASE, "CURPC", m_genPC).noshow();
- int index = 0;
- for (auto &n : netlist().nlstate().nets())
+ for (int i=0; i < netlist().m_nets.size(); i++)
{
+ netlist::detail::net_t *n = netlist().m_nets[i].get();
if (n->is_logic())
{
- state_add(index, n->name().c_str(), *(downcast<netlist::logic_net_t &>(*n).Q_state_ptr()));
+ state_add(i*2, n->name().c_str(), *downcast<netlist::logic_net_t *>(n)->Q_state_ptr());
}
else
{
- state_add(index, n->name().c_str(), *(downcast<netlist::analog_net_t &>(*n).Q_Analog_state_ptr()));
+ state_add(i*2+1, n->name().c_str(), *downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr());
}
- index++;
}
// set our instruction counter
@@ -1059,8 +1032,10 @@ ATTR_COLD uint64_t netlist_mame_cpu_device::execute_cycles_to_clocks(uint64_t cy
ATTR_HOT void netlist_mame_cpu_device::execute_run()
{
+ bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0);
+ // debugging
//m_ppc = m_pc; // copy PC to previous PC
- if (debugger_enabled())
+ if (check_debugger)
{
while (m_icount > 0)
{
@@ -1068,13 +1043,13 @@ ATTR_HOT void netlist_mame_cpu_device::execute_run()
m_genPC &= 255;
debugger_instruction_hook(m_genPC);
netlist().process_queue(m_div);
- update_icount(netlist().time());
+ update_time_x();
}
}
else
{
netlist().process_queue(m_div * m_icount);
- update_icount(netlist().time());
+ update_time_x();
}
}
@@ -1114,8 +1089,11 @@ offs_t netlist_disassembler::disassemble(std::ostream &stream, offs_t pc, const
netlist_mame_sound_device::netlist_mame_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: netlist_mame_device(mconfig, NETLIST_SOUND, tag, owner, clock)
, device_sound_interface(mconfig, *this)
+ , m_out{nullptr}
, m_in(nullptr)
, m_stream(nullptr)
+ , m_num_inputs(0)
+ , m_num_outputs(0)
{
}
@@ -1127,45 +1105,44 @@ void netlist_mame_sound_device::device_start()
// Configure outputs
- std::vector<nld_sound_out *> outdevs = netlist().nlstate().get_device_list<nld_sound_out>();
+ std::vector<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
if (outdevs.size() == 0)
fatalerror("No output devices");
- //m_num_outputs = outdevs.size();
+ m_num_outputs = outdevs.size();
/* resort channels */
- for (auto &outdev : outdevs)
+ for (int i=0; i < MAX_OUT; i++) m_out[i] = nullptr;
+ for (int i=0; i < m_num_outputs; i++)
{
- int chan = outdev->m_channel();
+ int chan = outdevs[i]->m_channel();
- netlist().log().verbose("Output %s on channel %d", outdev->name(), chan);
+ netlist().log().verbose("Output %d on channel %d", i, chan);
- if (chan < 0 || chan >= outdevs.size())
+ if (chan < 0 || chan >= MAX_OUT || chan >= outdevs.size())
fatalerror("illegal channel number");
- m_out[chan] = outdev;
- m_out[chan]->m_sample_time = netlist::netlist_time::from_hz(clock());
+ m_out[chan] = outdevs[i];
+ m_out[chan]->m_sample = netlist::netlist_time::from_hz(clock());
m_out[chan]->m_buffer = nullptr;
- m_out[chan]->m_bufsize = 0;
}
// Configure inputs
- // FIXME: The limitation to one input device seems artificial.
- // We should allow multiple devices with one channel each.
+ m_num_inputs = 0;
m_in = nullptr;
- std::vector<nld_sound_in *> indevs = netlist().nlstate().get_device_list<nld_sound_in>();
+ std::vector<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
if (indevs.size() > 1)
fatalerror("A maximum of one input device is allowed!");
if (indevs.size() == 1)
{
m_in = indevs[0];
- m_in->resolve();
+ m_num_inputs = m_in->resolve();
m_in->m_inc = netlist::netlist_time::from_hz(clock());
}
/* initialize the stream(s) */
- m_stream = machine().sound().stream_alloc(*this, m_in ? m_in->num_channels() : 0, m_out.size(), clock());
+ m_stream = machine().sound().stream_alloc(*this, m_num_inputs, m_num_outputs, clock());
}
@@ -1178,21 +1155,17 @@ void netlist_mame_sound_device::nl_register_devices()
void netlist_mame_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
-
- for (auto &e : m_out)
+ for (int i=0; i < m_num_outputs; i++)
{
- e.second->m_buffer = outputs[e.first];
- e.second->m_bufsize = samples;
+ m_out[i]->m_buffer = outputs[i];
}
+ if (m_num_inputs)
+ m_in->buffer_reset();
- if (m_in)
+ for (int i=0; i < m_num_inputs; i++)
{
- m_in->buffer_reset();
- for (int i=0; i < m_in->num_channels(); i++)
- {
- m_in->m_channels[i].m_buffer = inputs[i];
- }
+ m_in->m_buffer[i] = inputs[i];
}
netlist::netlist_time cur(netlist().time());
@@ -1201,9 +1174,9 @@ void netlist_mame_sound_device::sound_stream_update(sound_stream &stream, stream
cur += (m_div * samples);
- for (auto &e : m_out)
+ for (int i=0; i < m_num_outputs; i++)
{
- e.second->sound_update_fill(samples);
- e.second->buffer_reset(cur);
+ m_out[i]->sound_update(cur);
+ m_out[i]->buffer_reset(cur);
}
}
diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h
index 639223d2842..36bdcb0c415 100644
--- a/src/devices/machine/netlist.h
+++ b/src/devices/machine/netlist.h
@@ -11,19 +11,16 @@
#ifndef MAME_MACHINE_NETLIST_H
#define MAME_MACHINE_NETLIST_H
-#include <functional>
-
-#include "../../lib/netlist/nltypes.h"
+#include "netlist/nl_time.h"
class nld_sound_out;
class nld_sound_in;
namespace netlist {
class setup_t;
- class netlist_state_t;
- class nlparse_t;
- template <typename T>
- class param_num_t;
+ class param_double_t;
+ class param_int_t;
+ class param_logic_t;
class param_ptr_t;
}
@@ -34,9 +31,6 @@ namespace netlist {
#define MCFG_NETLIST_SETUP(_setup) \
downcast<netlist_mame_device &>(*device).set_constructor(NETLIST_NAME(_setup));
-#define MCFG_NETLIST_SETUP_MEMBER(_obj, _setup) \
- downcast<netlist_mame_device &>(*device).set_constructor(_obj, _setup);
-
#define MCFG_NETLIST_ANALOG_INPUT(_basetag, _tag, _name) \
MCFG_DEVICE_ADD(_basetag ":" _tag, NETLIST_ANALOG_INPUT, 0) \
downcast<netlist_mame_analog_input_device &>(*device).set_name(_name);
@@ -85,10 +79,9 @@ namespace netlist {
#define NETLIST_ANALOG_PORT_CHANGED(_base, _tag) \
PORT_CHANGED_MEMBER(_base ":" _tag, netlist_mame_analog_input_device, input_changed, 0)
-/* This macro can only be called from device member */
#define MEMREGION_SOURCE(_name) \
- netlist_mame_device::register_memregion_source(setup, *this, _name);
+ netlist_mame_device::register_memregion_source(setup, _name);
#define NETDEV_ANALOG_CALLBACK_MEMBER(_name) \
void _name(const double data, const attotime &time)
@@ -106,32 +99,21 @@ class netlist_mame_device : public device_t
{
public:
class netlist_mame_t;
- class netlist_mame_callbacks_t;
-
- using func_type = std::function<void(netlist::nlparse_t &)>;
// construction/destruction
netlist_mame_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~netlist_mame_device();
- void set_constructor(void (*setup_func)(netlist::nlparse_t &))
- {
- m_setup_func = func_type(setup_func);
- }
-
- template <typename T, typename F>
- void set_constructor(T *obj, F && f)
- {
- m_setup_func = std::move(std::bind(std::forward<F>(f), obj, std::placeholders::_1));
- }
+ void set_constructor(void (*setup_func)(netlist::setup_t &));
ATTR_HOT inline netlist::setup_t &setup();
ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; }
- ATTR_HOT void update_icount(netlist::netlist_time time);
+ ATTR_HOT inline const netlist::netlist_time last_time_update() { return m_old; }
+ ATTR_HOT void update_time_x();
ATTR_HOT void check_mame_abort_slice();
- static void register_memregion_source(netlist::nlparse_t &setup, device_t &dev, const char *name);
+ static void register_memregion_source(netlist::setup_t &setup, const char *name);
int m_icount;
@@ -160,9 +142,9 @@ private:
netlist::netlist_time m_rem;
netlist::netlist_time m_old;
- netlist::pool_owned_ptr<netlist_mame_t> m_netlist;
+ netlist_mame_t * m_netlist;
- func_type m_setup_func;
+ void (*m_setup_func)(netlist::setup_t &);
};
// ----------------------------------------------------------------------------------------
@@ -249,9 +231,13 @@ protected:
virtual void device_start() override;
private:
- std::map<int, nld_sound_out *> m_out;
+ static constexpr int MAX_OUT = 10;
+ nld_sound_out *m_out[MAX_OUT];
nld_sound_in *m_in;
sound_stream *m_stream;
+ int m_num_inputs;
+ int m_num_outputs;
+
};
// ----------------------------------------------------------------------------------------
@@ -269,16 +255,14 @@ public:
{
}
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) { }
- virtual void pre_parse_action(netlist::netlist_state_t &nlstate) { }
+ virtual void custom_netlist_additions(netlist::setup_t &setup) { }
+ virtual void pre_parse_action(netlist::setup_t &setup) { }
inline netlist_mame_device &nl_owner() const { return *m_owner; }
- inline void update_to_current_time()
- {
- if (m_sound != nullptr)
- m_sound->get_stream()->update();
- }
+ inline bool is_sound_device() const { return bool(m_sound); }
+
+ inline void update_to_current_time() { m_sound->get_stream()->update(); }
void set_mult_offset(const double mult, const double offset);
@@ -322,13 +306,11 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
- netlist::param_num_t<double> *m_param;
+ netlist::param_double_t *m_param;
bool m_auto_port;
const char *m_param_name;
- double m_value_for_device_timer;
};
// ----------------------------------------------------------------------------------------
@@ -348,7 +330,7 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) override;
+ virtual void custom_netlist_additions(netlist::setup_t &setup) override;
private:
const char *m_in;
@@ -380,7 +362,7 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) override;
+ virtual void custom_netlist_additions(netlist::setup_t &setup) override;
private:
const char *m_in;
@@ -420,7 +402,7 @@ protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
- netlist::param_num_t<int> *m_param;
+ netlist::param_int_t *m_param;
uint32_t m_mask;
uint32_t m_shift;
const char *m_param_name;
@@ -459,7 +441,7 @@ protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
- netlist::param_num_t<bool> *m_param;
+ netlist::param_logic_t *m_param;
uint32_t m_shift;
const char *m_param_name;
};
@@ -509,7 +491,7 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) override;
+ virtual void custom_netlist_additions(netlist::setup_t &setup) override;
private:
uint32_t m_channel;
const char *m_param_name;
@@ -535,7 +517,7 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void custom_netlist_additions(netlist::netlist_state_t &nlstate) override;
+ virtual void custom_netlist_additions(netlist::setup_t &setup) override;
private:
uint32_t m_channel;
diff --git a/src/devices/machine/nmc9306.h b/src/devices/machine/nmc9306.h
index 07aa6b36db0..097742685aa 100644
--- a/src/devices/machine/nmc9306.h
+++ b/src/devices/machine/nmc9306.h
@@ -19,6 +19,17 @@
#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_NMC9306_ADD(tag) \
+ MCFG_DEVICE_ADD((tag), NMC9306, 0)
+
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
diff --git a/src/devices/machine/nsc810.cpp b/src/devices/machine/nsc810.cpp
index 96a13e7b696..bf06c34d9dc 100644
--- a/src/devices/machine/nsc810.cpp
+++ b/src/devices/machine/nsc810.cpp
@@ -118,7 +118,7 @@ void nsc810_device::device_timer(emu_timer &timer, device_timer_id id, int param
}
}
-uint8_t nsc810_device::read(offs_t offset)
+READ8_MEMBER(nsc810_device::read)
{
uint8_t res = 0xff;
@@ -191,7 +191,7 @@ uint8_t nsc810_device::read(offs_t offset)
return res;
}
-void nsc810_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(nsc810_device::write)
{
uint32_t rate;
diff --git a/src/devices/machine/nsc810.h b/src/devices/machine/nsc810.h
index 520591208f7..bebeb8f82a6 100644
--- a/src/devices/machine/nsc810.h
+++ b/src/devices/machine/nsc810.h
@@ -16,38 +16,24 @@ class nsc810_device : public device_t
{
public:
// construction/destruction
- nsc810_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t clk0, uint32_t clk1)
- : nsc810_device(mconfig, tag, owner, clock)
- {
- set_timer0_clock(clk0);
- set_timer1_clock(clk1);
- }
-
- nsc810_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const XTAL &clk0, const XTAL &clk1)
- : nsc810_device(mconfig, tag, owner, clock)
- {
- set_timer0_clock(clk0.value());
- set_timer1_clock(clk1.value());
- }
-
nsc810_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- auto portA_read_callback() { return m_portA_r.bind(); }
- auto portB_read_callback() { return m_portB_r.bind(); }
- auto portC_read_callback() { return m_portC_r.bind(); }
- auto portA_write_callback() { return m_portA_w.bind(); }
- auto portB_write_callback() { return m_portB_w.bind(); }
- auto portC_write_callback() { return m_portC_w.bind(); }
- auto timer0_callback() { return m_timer0_out.bind(); }
- auto timer1_callback() { return m_timer1_out.bind(); }
+ template <class Object> devcb_base &set_portA_read_callback(Object &&cb) { return m_portA_r.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_portB_read_callback(Object &&cb) { return m_portB_r.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_portC_read_callback(Object &&cb) { return m_portC_r.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_portA_write_callback(Object &&cb) { return m_portA_w.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_portB_write_callback(Object &&cb) { return m_portB_w.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_portC_write_callback(Object &&cb) { return m_portC_w.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_timer0_callback(Object &&cb) { return m_timer0_out.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_timer1_callback(Object &&cb) { return m_timer1_out.set_callback(std::forward<Object>(cb)); }
void set_timer0_clock(uint32_t clk) { m_timer0_clock = clk; }
void set_timer0_clock(const XTAL &clk) { set_timer0_clock(clk.value()); }
void set_timer1_clock(uint32_t clk) { m_timer1_clock = clk; }
void set_timer1_clock(const XTAL &clk) { set_timer1_clock(clk.value()); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
protected:
virtual void device_start() override;
@@ -116,6 +102,35 @@ private:
};
};
+#define MCFG_NSC810_ADD(_tag, _t0clk, _t1clk) \
+ MCFG_DEVICE_ADD(_tag, NSC810, 0) \
+ downcast<nsc810_device *>(device)->set_timer0_clock(_t0clk); \
+ downcast<nsc810_device *>(device)->set_timer1_clock(_t1clk);
+
+#define MCFG_NSC810_PORTA_READ(_read) \
+ downcast<nsc810_device &>(*device).set_portA_read_callback(DEVCB_##_read);
+
+#define MCFG_NSC810_PORTB_READ(_read) \
+ downcast<nsc810_device &>(*device).set_portB_read_callback(DEVCB_##_read);
+
+#define MCFG_NSC810_PORTC_READ(_read) \
+ downcast<nsc810_device &>(*device).set_portC_read_callback(DEVCB_##_read);
+
+#define MCFG_NSC810_PORTA_WRITE(_write) \
+ downcast<nsc810_device &>(*device).set_portA_write_callback(DEVCB_##_write);
+
+#define MCFG_NSC810_PORTB_WRITE(_write) \
+ downcast<nsc810_device &>(*device).set_portB_write_callback(DEVCB_##_write);
+
+#define MCFG_NSC810_PORTC_WRITE(_write) \
+ downcast<nsc810_device &>(*device).set_portC_write_callback(DEVCB_##_write);
+
+#define MCFG_NSC810_TIMER0_OUT(_write) \
+ downcast<nsc810_device &>(*device).set_timer0_callback(DEVCB_##_write);
+
+#define MCFG_NSC810_TIMER1_OUT(_write) \
+ downcast<nsc810_device &>(*device).set_timer1_callback(DEVCB_##_write);
+
// device type definition
DECLARE_DEVICE_TYPE(NSC810, nsc810_device)
diff --git a/src/devices/machine/nscsi_bus.cpp b/src/devices/machine/nscsi_bus.cpp
index ef3c0dd9f9a..328dd7239bd 100644
--- a/src/devices/machine/nscsi_bus.cpp
+++ b/src/devices/machine/nscsi_bus.cpp
@@ -3,15 +3,13 @@
#include "emu.h"
#include "nscsi_bus.h"
-#define LOG_GENERAL (1U << 0)
-#define LOG_UNSUPPORTED (1U << 1)
-#define LOG_STATE (1U << 2)
-#define LOG_CONTROL (1U << 3)
-#define LOG_DATA (1U << 4)
-#define LOG_DATA_SENT (1U << 5)
+#define LOG_GENERAL (1U << 0)
+#define LOG_STATE (1U << 1)
+#define LOG_CONTROL (1U << 2)
+#define LOG_DATA (1U << 3)
//#define VERBOSE (LOG_GENERAL | LOG_STATE | LOG_CONTROL | LOG_DATA)
-#define VERBOSE (LOG_UNSUPPORTED | LOG_DATA_SENT)
+#define VERBOSE 0
#include "logmacro.h"
@@ -442,7 +440,7 @@ void nscsi_full_device::step(bool timeout)
break;
}
- if(scsi_command_done(scsi_cmdbuf[0], data_buffer_pos)) {
+ if(command_done()) {
scsi_cmdsize = data_buffer_pos;
scsi_bus->ctrl_wait(scsi_refid, 0, S_ACK);
scsi_command();
@@ -509,17 +507,18 @@ void nscsi_full_device::target_send_buffer_byte()
target_send_byte(scsi_get_data(data_buffer_id, data_buffer_pos++));
}
-bool nscsi_full_device::scsi_command_done(uint8_t command, uint8_t length)
+bool nscsi_full_device::command_done()
{
- if(!length)
+ if(!data_buffer_pos)
return false;
- switch(command >> 5) {
- case 0: return length == 6;
- case 1: return length == 10;
- case 2: return length == 10;
+ uint8_t h = scsi_cmdbuf[0];
+ switch(h >> 5) {
+ case 0: return data_buffer_pos == 6;
+ case 1: return data_buffer_pos == 10;
+ case 2: return data_buffer_pos == 10;
case 3: return true;
case 4: return true;
- case 5: return length == 12;
+ case 5: return data_buffer_pos == 12;
case 6: return true;
case 7: return true;
}
@@ -563,17 +562,6 @@ void nscsi_full_device::scsi_status_complete(uint8_t st)
void nscsi_full_device::scsi_data_in(int buf, int size)
{
- if((VERBOSE & LOG_DATA_SENT) && buf == 0) {
- std::string dt = "";
- int sz = size;
- if(sz > 50)
- sz = 50;
- for(int i=0; i<sz; i++)
- dt += util::string_format(" %02x", scsi_cmdbuf[i]);
- if(size > sz)
- dt += " ...";
- LOGMASKED(LOG_DATA_SENT, "Sending data (%d)%s\n", size, dt);
- }
control *c;
c = buf_control_push();
c->action = BC_DATA_IN;
@@ -595,28 +583,31 @@ void nscsi_full_device::sense(bool deferred, uint8_t key, uint8_t asc, uint8_t a
memset(scsi_sense_buffer, 0, sizeof(scsi_sense_buffer));
scsi_sense_buffer[0] = deferred ? 0x71 : 0x70;
scsi_sense_buffer[2] = key;
- scsi_sense_buffer[7] = sizeof(scsi_sense_buffer) - 8;
scsi_sense_buffer[12] = asc;
scsi_sense_buffer[13] = ascq;
}
void nscsi_full_device::scsi_unknown_command()
{
- std::string txt = util::string_format("Unhandled command %s (%d):", command_names[scsi_cmdbuf[0]], scsi_cmdsize);
+ LOG("Unhandled command %s", command_names[scsi_cmdbuf[0]]);
for(int i=0; i != scsi_cmdsize; i++)
- txt += util::string_format(" %02x", scsi_cmdbuf[i]);
- LOGMASKED(LOG_UNSUPPORTED, "%s\n", txt);
+ logerror(" %02x", scsi_cmdbuf[i]);
+ logerror("\n");
scsi_status_complete(SS_CHECK_CONDITION);
- sense(false, SK_ILLEGAL_REQUEST);
+ sense(false, 5);
}
void nscsi_full_device::scsi_command()
{
switch(scsi_cmdbuf[0]) {
case SC_REQUEST_SENSE:
- LOG("command REQUEST SENSE alloc=%d\n", scsi_cmdbuf[4]);
- scsi_data_in(SBUF_SENSE, scsi_cmdbuf[4] ? std::min(scsi_cmdbuf[4], u8(sizeof(scsi_sense_buffer))) : 4);
+ LOG("command REQUEST SENSE\n");
+ /*
+ * Targets shall be capable of returning eighteen bytes of data in
+ * response to a REQUEST SENSE command.
+ */
+ scsi_data_in(SBUF_SENSE, 18);
scsi_status_complete(SS_GOOD);
break;
default:
@@ -632,10 +623,10 @@ void nscsi_full_device::scsi_message()
return;
}
- std::string txt = "Unknown message";
+ LOG("Unknown message");
for(int i=0; i != scsi_cmdsize; i++)
- txt += util::string_format(" %02x", scsi_cmdbuf[i]);
- LOGMASKED(LOG_UNSUPPORTED, "%s\n", txt);
+ logerror(" %02x", scsi_cmdbuf[i]);
+ logerror("\n");
}
int nscsi_full_device::get_lun(int def)
@@ -649,7 +640,9 @@ int nscsi_full_device::get_lun(int def)
void nscsi_full_device::bad_lun()
{
scsi_status_complete(SS_CHECK_CONDITION);
- sense(false, SK_ILLEGAL_REQUEST, SK_ASC_LOGICAL_UNIT_NOT_SUPPORTED);
+
+ // key:illegal request, asc:logical unit not supported
+ sense(false, 5, 0x25);
}
// Arbitration delay (2.4us)
diff --git a/src/devices/machine/nscsi_bus.h b/src/devices/machine/nscsi_bus.h
index 244eda94fe8..5e7d7dcecab 100644
--- a/src/devices/machine/nscsi_bus.h
+++ b/src/devices/machine/nscsi_bus.h
@@ -6,12 +6,19 @@
#pragma once
+#define MCFG_NSCSI_BUS_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, NSCSI_BUS, 0)
+
+#define MCFG_NSCSI_ADD(_tag, _slot_intf, _def_slot, _fixed) \
+ MCFG_DEVICE_ADD(_tag, NSCSI_CONNECTOR, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed)
+
class nscsi_device;
class nscsi_bus_device : public device_t
{
public:
- nscsi_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ nscsi_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void ctrl_w(int refid, uint32_t lines, uint32_t mask);
void data_w(int refid, uint32_t lines);
@@ -42,19 +49,10 @@ private:
};
class nscsi_connector: public device_t,
- public device_slot_interface
+ public device_slot_interface
{
public:
- template <typename T>
- nscsi_connector(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt, bool fixed = false)
- : nscsi_connector(mconfig, tag, owner, 0)
- {
- option_reset();
- opts(*this);
- set_default_option(dflt);
- set_fixed(fixed);
- }
- nscsi_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ nscsi_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~nscsi_connector();
nscsi_device *get_device();
@@ -169,9 +167,7 @@ protected:
// SCSI addtional sense code qualifiers
enum {
- SK_ASC_INVALID_FIELD_IN_CDB = 0x24,
- SK_ASC_LOGICAL_UNIT_NOT_SUPPORTED = 0x25,
- SK_ASC_MEDIUM_NOT_PRESENT = 0x3a
+ SK_ASC_MEDIUM_NOT_PRESENT = 0x3a
};
// SCSI commands
@@ -308,7 +304,6 @@ protected:
virtual void scsi_message();
virtual void scsi_command();
- virtual bool scsi_command_done(uint8_t command, uint8_t length);
void scsi_unknown_command();
void scsi_status_complete(uint8_t st);
@@ -449,6 +444,7 @@ private:
void target_recv_byte();
void target_send_byte(uint8_t val);
void target_send_buffer_byte();
+ bool command_done();
};
diff --git a/src/devices/machine/nscsi_cb.h b/src/devices/machine/nscsi_cb.h
index 575e8f19298..b5156935a98 100644
--- a/src/devices/machine/nscsi_cb.h
+++ b/src/devices/machine/nscsi_cb.h
@@ -8,20 +8,48 @@
#include "machine/nscsi_bus.h"
+#define MCFG_NSCSICB_RST_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_rst_callback(DEVCB_##_line);
+
+#define MCFG_NSCSICB_ATN_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_atn_callback(DEVCB_##_line);
+
+#define MCFG_NSCSICB_ACK_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_ack_callback(DEVCB_##_line);
+
+#define MCFG_NSCSICB_REQ_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_req_callback(DEVCB_##_line);
+
+#define MCFG_NSCSICB_MSG_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_msg_callback(DEVCB_##_line);
+
+#define MCFG_NSCSICB_IO_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_io_callback(DEVCB_##_line);
+
+#define MCFG_NSCSICB_CD_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_cd_callback(DEVCB_##_line);
+
+#define MCFG_NSCSICB_SEL_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_sel_callback(DEVCB_##_line);
+
+#define MCFG_NSCSICB_BSY_HANDLER(_line) \
+ downcast<nscsi_callback_device *>(device)->set_bsy_callback(DEVCB_##_line);
+
+
class nscsi_callback_device : public nscsi_device
{
public:
nscsi_callback_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- auto rst_callback() { return m_write_rst.bind(); }
- auto atn_callback() { return m_write_atn.bind(); }
- auto ack_callback() { return m_write_ack.bind(); }
- auto req_callback() { return m_write_req.bind(); }
- auto msg_callback() { return m_write_msg.bind(); }
- auto io_callback() { return m_write_io.bind(); }
- auto cd_callback() { return m_write_cd.bind(); }
- auto sel_callback() { return m_write_sel.bind(); }
- auto bsy_callback() { return m_write_bsy.bind(); }
+ template <class Line> devcb_base &set_rst_callback(Line &&cb) { return m_write_rst.set_callback(std::forward<Line>(cb)); }
+ template <class Line> devcb_base &set_atn_callback(Line &&cb) { return m_write_atn.set_callback(std::forward<Line>(cb)); }
+ template <class Line> devcb_base &set_ack_callback(Line &&cb) { return m_write_ack.set_callback(std::forward<Line>(cb)); }
+ template <class Line> devcb_base &set_req_callback(Line &&cb) { return m_write_req.set_callback(std::forward<Line>(cb)); }
+ template <class Line> devcb_base &set_msg_callback(Line &&cb) { return m_write_msg.set_callback(std::forward<Line>(cb)); }
+ template <class Line> devcb_base &set_io_callback(Line &&cb) { return m_write_io.set_callback(std::forward<Line>(cb)); }
+ template <class Line> devcb_base &set_cd_callback(Line &&cb) { return m_write_cd.set_callback(std::forward<Line>(cb)); }
+ template <class Line> devcb_base &set_sel_callback(Line &&cb) { return m_write_sel.set_callback(std::forward<Line>(cb)); }
+ template <class Line> devcb_base &set_bsy_callback(Line &&cb) { return m_write_bsy.set_callback(std::forward<Line>(cb)); }
virtual void scsi_ctrl_changed() override;
diff --git a/src/devices/machine/nscsi_cd.cpp b/src/devices/machine/nscsi_cd.cpp
index 0446c600e9f..fc1898eecd5 100644
--- a/src/devices/machine/nscsi_cd.cpp
+++ b/src/devices/machine/nscsi_cd.cpp
@@ -7,7 +7,6 @@
#include "logmacro.h"
DEFINE_DEVICE_TYPE(NSCSI_CDROM, nscsi_cdrom_device, "scsi_cdrom", "SCSI CD-ROM")
-DEFINE_DEVICE_TYPE(NSCSI_CDROM_SGI, nscsi_cdrom_sgi_device, "scsi_cdrom_sgi", "SCSI CD-ROM SGI")
DEFINE_DEVICE_TYPE(NSCSI_RRD45, nscsi_dec_rrd45_device, "nrrd45", "RRD45 CD-ROM (New)")
DEFINE_DEVICE_TYPE(NSCSI_XM3301, nscsi_toshiba_xm3301_device, "nxm3301", "XM-3301TA CD-ROM (New)")
DEFINE_DEVICE_TYPE(NSCSI_XM5301SUN, nscsi_toshiba_xm5301_sun_device, "nxm5301sun", "XM-5301B Sun 4x CD-ROM (New)")
@@ -20,11 +19,6 @@ nscsi_cdrom_device::nscsi_cdrom_device(const machine_config &mconfig, const char
{
}
-nscsi_cdrom_sgi_device::nscsi_cdrom_sgi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- nscsi_cdrom_device(mconfig, NSCSI_CDROM_SGI, tag, owner, "Sony", "CDU-76S", "1.0", 0x00, 0x05)
-{
-}
-
nscsi_dec_rrd45_device::nscsi_dec_rrd45_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
nscsi_cdrom_device(mconfig, NSCSI_RRD45, tag, owner, "DEC ", "RRD45 (C) DEC ", "0436", 0x98, 0x02)
{
@@ -82,19 +76,10 @@ void nscsi_cdrom_device::device_reset()
cur_sector = -1;
}
-void nscsi_cdrom_device::device_add_mconfig(machine_config &config)
-{
- CDROM(config, image).set_interface("cdrom");
-}
-
-int nscsi_cdrom_device::to_msf(int frame)
-{
- int m = frame / (75 * 60);
- int s = (frame / 75) % 60;
- int f = frame % 75;
-
- return (m << 16) | (s << 8) | f;
-}
+MACHINE_CONFIG_START(nscsi_cdrom_device::device_add_mconfig)
+ MCFG_CDROM_ADD("image")
+ MCFG_CDROM_INTERFACE("cdrom")
+MACHINE_CONFIG_END
void nscsi_cdrom_device::set_block_size(u32 block_size)
{
@@ -208,16 +193,21 @@ void nscsi_cdrom_device::scsi_command()
* is returned with sense data ILLEGAL REQUEST and LOGICAL UNIT NOT
* SUPPORTED.
*/
+ if(lun) {
+ bad_lun();
+ return;
+ }
+
int page = scsi_cmdbuf[2];
int size = scsi_cmdbuf[4];
switch(page) {
case 0:
std::fill_n(scsi_cmdbuf, 36, 0);
- if (lun != 0)
- scsi_cmdbuf[0] = 0x7f;
- else
- scsi_cmdbuf[0] = 0x05; // device is present, device is CD/DVD (MMC-3)
+ // vendor and product information must be padded with spaces
+ std::fill_n(&scsi_cmdbuf[8], 28, 0x20);
+
+ scsi_cmdbuf[0] = 0x05; // device is present, device is CD/DVD (MMC-3)
scsi_cmdbuf[1] = 0x80; // media is removable
scsi_cmdbuf[2] = compliance; // device complies with SPC-3 standard
scsi_cmdbuf[3] = 0x02; // response data format = SPC-3 standard
@@ -226,12 +216,6 @@ void nscsi_cdrom_device::scsi_command()
strncpy((char *)&scsi_cmdbuf[8], manufacturer, 8);
strncpy((char *)&scsi_cmdbuf[16], product, 16);
strncpy((char *)&scsi_cmdbuf[32], revision, 4);
-
- // vendor and product information must be padded with spaces
- for(int i = 8; i < 36; i++)
- if(scsi_cmdbuf[i] == 0)
- scsi_cmdbuf[i] = 0x20;
-
if(size > 36)
size = 36;
scsi_data_in(SBUF_MAIN, size);
@@ -257,48 +241,6 @@ void nscsi_cdrom_device::scsi_command()
scsi_status_complete(SS_GOOD);
break;
- case SC_RECIEVE_DIAG_RES: {
- LOG("command RECIEVE DIAGNOSTICS RESULTS");
- int size = (scsi_cmdbuf[3] << 8) | scsi_cmdbuf[4];
- int pos = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 6;
- scsi_cmdbuf[pos++] = 0; // ROM is OK
- scsi_cmdbuf[pos++] = 0; // RAM is OK
- scsi_cmdbuf[pos++] = 0; // Data buffer is OK
- scsi_cmdbuf[pos++] = 0; // Interface is OK
- scsi_cmdbuf[pos++] = 0;
- if(size > pos)
- size = pos;
- scsi_data_in(0, size);
- scsi_status_complete(SS_GOOD);
- break;
- }
-
- case SC_SEND_DIAGNOSTICS: {
- LOG("command SEND DIAGNOSTICS");
- int size = (scsi_cmdbuf[3] << 8) | scsi_cmdbuf[4];
- if(scsi_cmdbuf[1] & 4) {
- // Self-test
- scsi_status_complete(SS_GOOD);
- break;
- }
- int pos = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 6;
- scsi_cmdbuf[pos++] = 0; // ROM is OK
- scsi_cmdbuf[pos++] = 0; // RAM is OK
- scsi_cmdbuf[pos++] = 0; // Data buffer is OK
- scsi_cmdbuf[pos++] = 0; // Interface is OK
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- if(size > pos)
- size = pos;
- scsi_data_in(0, size);
- scsi_status_complete(SS_GOOD);
- break;
- }
-
case SC_READ_CAPACITY: {
if(!cdrom) {
return_no_cd();
@@ -308,7 +250,7 @@ void nscsi_cdrom_device::scsi_command()
LOG("command READ CAPACITY\n");
// get the last used block on the disc
- const u32 temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1;
+ const uint32_t temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1;
scsi_cmdbuf[0] = (temp>>24) & 0xff;
scsi_cmdbuf[1] = (temp>>16) & 0xff;
@@ -325,15 +267,16 @@ void nscsi_cdrom_device::scsi_command()
}
case SC_READ_10:
- lba = (scsi_cmdbuf[2]<<24) | (scsi_cmdbuf[3]<<16) | (scsi_cmdbuf[4]<<8) | scsi_cmdbuf[5];
- blocks = (scsi_cmdbuf[7] << 8) | scsi_cmdbuf[8];
-
- LOG("command READ EXTENDED start=%08x blocks=%04x\n", lba, blocks);
if(!cdrom) {
return_no_cd();
break;
}
+ lba = (scsi_cmdbuf[2]<<24) | (scsi_cmdbuf[3]<<16) | (scsi_cmdbuf[4]<<8) | scsi_cmdbuf[5];
+ blocks = (scsi_cmdbuf[7] << 8) | scsi_cmdbuf[8];
+
+ LOG("command READ EXTENDED start=%08x blocks=%04x\n", lba, blocks);
+
scsi_data_in(2, blocks*bytes_per_block);
scsi_status_complete(SS_GOOD);
break;
@@ -354,7 +297,7 @@ void nscsi_cdrom_device::scsi_command()
scsi_cmdbuf[pos++] = 0x80; // WP, cache
// get the last used block on the disc
- const u32 temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1;
+ const uint32_t temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1;
scsi_cmdbuf[pos++] = 0x08; // Block descriptor length
scsi_cmdbuf[pos++] = 0x00; // density code
@@ -366,11 +309,10 @@ void nscsi_cdrom_device::scsi_command()
scsi_cmdbuf[pos++] = (bytes_per_block>>8)&0xff;
scsi_cmdbuf[pos++] = (bytes_per_block & 0xff);
- bool fail = false;
int pmax = page == 0x3f ? 0x3e : page;
int pmin = page == 0x3f ? 0x00 : page;
- for(int p=pmax; p >= pmin; p--) {
- switch(p) {
+ for(int page=pmax; page >= pmin; page--) {
+ switch(page) {
case 0x00: // Vendor specific (does not require page format)
scsi_cmdbuf[pos++] = 0x80; // PS, page id
scsi_cmdbuf[pos++] = 0x02; // Page length
@@ -398,10 +340,7 @@ void nscsi_cdrom_device::scsi_command()
break;
default:
- if (page != 0x3f) {
- LOG("mode sense page %02x unhandled\n", p);
- fail = true;
- }
+ LOG("mode sense page %02x unhandled\n", page);
break;
}
}
@@ -409,13 +348,8 @@ void nscsi_cdrom_device::scsi_command()
if(pos > size)
pos = size;
- if (!fail) {
- scsi_data_in(0, pos);
- scsi_status_complete(SS_GOOD);
- } else {
- scsi_status_complete(SS_CHECK_CONDITION);
- sense(false, SK_ILLEGAL_REQUEST, SK_ASC_INVALID_FIELD_IN_CDB);
- }
+ scsi_data_in(0, pos);
+ scsi_status_complete(SS_GOOD);
break;
}
@@ -425,186 +359,10 @@ void nscsi_cdrom_device::scsi_command()
scsi_status_complete(SS_GOOD);
break;
- case SC_READ_TOC_PMA_ATIP: {
- /*
- Track numbers are problematic here: 0 = lead-in, 0xaa = lead-out.
- That makes sense in terms of how real-world CDs are referred to, but
- our internal routines for tracks use "0" as track 1. That probably
- should be fixed...
- */
- static const char *const format_names[16] = {
- "TOC",
- "Session info",
- "Full TOC",
- "PMA",
- "ATIP"
- "Reserved 5",
- "Reserved 6",
- "Reserved 7",
- "Reserved 8",
- "Reserved 9",
- "Reserved 10",
- "Reserved 11",
- "Reserved 12",
- "Reserved 13",
- "Reserved 14",
- "Reserved 15"
- };
-
- bool msf = (scsi_cmdbuf[1] & 0x2) != 0;
- u16 size = (scsi_cmdbuf[7] << 7) | scsi_cmdbuf[8];
- u8 format = scsi_cmdbuf[2] & 15;
-
- /// SFF8020 legacy format field (see T10/1836-D Revision 2g page 643)
- if(!format)
- format = (scsi_cmdbuf[9] >> 6) & 3;
-
- LOG("command READ TOC PMA ATIP, format %s msf=%d size=%d\n", format_names[format], msf, size);
-
- int pos = 0;
- switch (format) {
- case 0: {
- int start_track = scsi_cmdbuf[6];
- int end_track = cdrom_get_last_track(cdrom);
-
- int tracks;
- if(start_track == 0)
- tracks = end_track + 1;
- else if(start_track <= end_track)
- tracks = (end_track - start_track) + 2;
- else if(start_track <= 0xaa)
- tracks = 1;
- else
- tracks = 0;
-
- int len = 2 + (tracks * 8);
-
- // the returned TOC DATA LENGTH must be the full amount,
- // regardless of how much we're able to pass back due to size
- scsi_cmdbuf[pos++] = (len>>8) & 0xff;
- scsi_cmdbuf[pos++] = (len & 0xff);
- scsi_cmdbuf[pos++] = 1;
- scsi_cmdbuf[pos++] = cdrom_get_last_track(cdrom);
-
- if (start_track == 0)
- start_track = 1;
-
- for(int i = 0; i < tracks; i++) {
- int track = start_track + i;
- int cdrom_track = track - 1;
- if(i == tracks-1) {
- track = 0xaa;
- cdrom_track = 0xaa;
- }
-
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = cdrom_get_adr_control(cdrom, cdrom_track);
- scsi_cmdbuf[pos++] = track;
- scsi_cmdbuf[pos++] = 0;
-
- u32 tstart = cdrom_get_track_start(cdrom, cdrom_track);
-
- if(msf)
- tstart = to_msf(tstart+150);
-
- scsi_cmdbuf[pos++] = (tstart>>24) & 0xff;
- scsi_cmdbuf[pos++] = (tstart>>16) & 0xff;
- scsi_cmdbuf[pos++] = (tstart>>8) & 0xff;
- scsi_cmdbuf[pos++] = (tstart & 0xff);
- }
- break;
- }
-
- case 1: {
- int len = 2 + (8 * 1);
-
- scsi_cmdbuf[pos++] = (len>>8) & 0xff;
- scsi_cmdbuf[pos++] = (len & 0xff);
- scsi_cmdbuf[pos++] = 1;
- scsi_cmdbuf[pos++] = 1;
-
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = cdrom_get_adr_control(cdrom, 0);
- scsi_cmdbuf[pos++] = 1;
- scsi_cmdbuf[pos++] = 0;
-
- u32 tstart = cdrom_get_track_start(cdrom, 0);
-
- if (msf)
- tstart = to_msf(tstart+150);
-
- scsi_cmdbuf[pos++] = (tstart>>24) & 0xff;
- scsi_cmdbuf[pos++] = (tstart>>16) & 0xff;
- scsi_cmdbuf[pos++] = (tstart>>8) & 0xff;
- scsi_cmdbuf[pos++] = (tstart & 0xff);
- break;
- }
-
- default:
- LOG("Unhandled format %d\n", format_names[format]);
- break;
- }
-
- if(pos) {
- if(pos > size)
- pos = size;
-
- scsi_data_in(0, pos);
- scsi_status_complete(SS_GOOD);
- } else {
- // report unit attention condition
- scsi_status_complete(SS_CHECK_CONDITION);
- sense(false, SK_ILLEGAL_REQUEST);
- break;
- }
- break;
- }
-
default:
- nscsi_full_device::scsi_command();
- break;
- }
-}
-
-enum sgi_scsi_command_e : uint8_t {
- /*
- * The SGI supplied CD-ROM drives (and possibly those from some other vendors)
- * identify themselves as hard disk drives at poweron, and after SCSI bus resets,
- * until issued a vendor specific command (0xc9). This is done because older
- * systems would otherwise be unable to boot and load miniroots from CD, due to
- * their design (they attempted to protect the user from booting from
- * "ridiculous" devices, long before CD-ROM drives existed). The SGI drives are
- * sent a command to "revert" to CD-ROM inquiry information during boot if on
- * a SCSI bus handled by the PROM, but not all possible buses are handled by all
- * PROMs; additionally, a SCSI bus reset causes the CD-ROM drives to revert to
- * the poweron default, and this could happen before the hardware inventory code
- * in the kernel runs, if there are SCSI problems.
- */
- SGI_HD2CDROM = 0xc9,
-};
-
-void nscsi_cdrom_sgi_device::scsi_command()
-{
- switch (scsi_cmdbuf[0]) {
- case SGI_HD2CDROM:
- LOG("command SGI_HD2CDROM");
- // No need to do anything (yet). Just acknowledge the command.
- scsi_status_complete(SS_GOOD);
- break;
+ logerror("unhandled command %02x\n", scsi_cmdbuf[0]);
- default:
- nscsi_cdrom_device::scsi_command();
+ nscsi_full_device::scsi_command();
break;
}
}
-
-bool nscsi_cdrom_sgi_device::scsi_command_done(uint8_t command, uint8_t length)
-{
- switch (command) {
- case SGI_HD2CDROM:
- return length == 10;
-
- default:
- return nscsi_full_device::scsi_command_done(command, length);
- }
-}
diff --git a/src/devices/machine/nscsi_cd.h b/src/devices/machine/nscsi_cd.h
index 48097cea42f..f3ce871c70a 100644
--- a/src/devices/machine/nscsi_cd.h
+++ b/src/devices/machine/nscsi_cd.h
@@ -54,17 +54,6 @@ private:
uint8_t compliance;
void return_no_cd();
- static int to_msf(int frame);
-};
-
-class nscsi_cdrom_sgi_device : public nscsi_cdrom_device
-{
-public:
- nscsi_cdrom_sgi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
-
-protected:
- virtual void scsi_command() override;
- virtual bool scsi_command_done(uint8_t command, uint8_t length) override;
};
class nscsi_dec_rrd45_device : public nscsi_cdrom_device
@@ -104,7 +93,6 @@ public:
};
DECLARE_DEVICE_TYPE(NSCSI_CDROM, nscsi_cdrom_device)
-DECLARE_DEVICE_TYPE(NSCSI_CDROM_SGI, nscsi_cdrom_sgi_device)
DECLARE_DEVICE_TYPE(NSCSI_RRD45, nscsi_dec_rrd45_device)
DECLARE_DEVICE_TYPE(NSCSI_XM3301, nscsi_toshiba_xm3301_device)
DECLARE_DEVICE_TYPE(NSCSI_XM5301SUN, nscsi_toshiba_xm5301_sun_device)
diff --git a/src/devices/machine/nscsi_hd.cpp b/src/devices/machine/nscsi_hd.cpp
index 6684942c9d6..c83a2c17ef9 100644
--- a/src/devices/machine/nscsi_hd.cpp
+++ b/src/devices/machine/nscsi_hd.cpp
@@ -20,7 +20,7 @@ nscsi_harddisk_device::nscsi_harddisk_device(const machine_config &mconfig, cons
}
nscsi_harddisk_device::nscsi_harddisk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
- nscsi_full_device(mconfig, type, tag, owner, clock), image(*this, "image"), harddisk(nullptr), lba(0), cur_lba(0), blocks(0), bytes_per_sector(0)
+ nscsi_full_device(mconfig, type, tag, owner, clock), harddisk(nullptr), lba(0), cur_lba(0), blocks(0), bytes_per_sector(0)
{
}
@@ -37,7 +37,8 @@ void nscsi_harddisk_device::device_start()
void nscsi_harddisk_device::device_reset()
{
nscsi_full_device::device_reset();
- harddisk = image->get_hard_disk_file();
+ harddisk_image_device *hd = subdevice<harddisk_image_device>("image");
+ harddisk = hd->get_hard_disk_file();
if(!harddisk) {
scsi_id = -1;
bytes_per_sector = 0;
@@ -45,17 +46,18 @@ void nscsi_harddisk_device::device_reset()
const hard_disk_info *hdinfo = hard_disk_get_info(harddisk);
bytes_per_sector = hdinfo->sectorbytes;
- chd_file *chd = image->get_chd_file();
+ chd_file *chd = hd->get_chd_file();
if(chd != nullptr)
chd->read_metadata(HARD_DISK_IDENT_METADATA_TAG, 0, m_inquiry_data);
}
cur_lba = -1;
}
-void nscsi_harddisk_device::device_add_mconfig(machine_config &config)
-{
- HARDDISK(config, image).set_interface("scsi_hdd");
-}
+MACHINE_CONFIG_START(nscsi_harddisk_device::device_add_mconfig)
+ MCFG_HARDDISK_ADD("image")
+ MCFG_HARDDISK_INTERFACE("scsi_hdd")
+MACHINE_CONFIG_END
+
uint8_t nscsi_harddisk_device::scsi_get_data(int id, int pos)
{
@@ -90,9 +92,9 @@ void nscsi_harddisk_device::scsi_put_data(int id, int pos, uint8_t data)
int offset = pos % bytes_per_sector;
block[offset] = data;
- cur_lba = lba + pos / bytes_per_sector;
+ int clba = lba + pos / bytes_per_sector;
if(offset == bytes_per_sector-1) {
- if(!hard_disk_write(harddisk, cur_lba, block))
+ if(!hard_disk_write(harddisk, clba, block))
LOG("HD WRITE ERROR !\n");
}
}
@@ -166,8 +168,8 @@ void nscsi_harddisk_device::scsi_command()
// Apple HD SC setup utility needs to see this
strcpy((char *)&scsi_cmdbuf[8], " SEAGATE");
- strcpy((char *)&scsi_cmdbuf[16], " ST225N");
- strcpy((char *)&scsi_cmdbuf[32], "1.00");
+ strcpy((char *)&scsi_cmdbuf[15], " ST225N");
+ strcpy((char *)&scsi_cmdbuf[31], "1.00");
scsi_cmdbuf[36] = 0x00; // # of extents high
scsi_cmdbuf[37] = 0x08; // # of extents low
scsi_cmdbuf[38] = 0x00; // group 0 commands 0-1f
@@ -228,10 +230,8 @@ void nscsi_harddisk_device::scsi_command()
int pmax = page == 0x3f ? 0x3e : page;
int pmin = page == 0x3f ? 0x00 : page;
-
- bool fail = false;
- for(int p=pmax; p >= pmin; p--) {
- switch(p) {
+ for(int page=pmax; page >= pmin; page--) {
+ switch(page) {
case 0x00: // Unit attention parameters page (weird)
scsi_cmdbuf[pos++] = 0x80; // PS, page id
scsi_cmdbuf[pos++] = 0x02; // Page length
@@ -239,40 +239,6 @@ void nscsi_harddisk_device::scsi_command()
scsi_cmdbuf[pos++] = 0x00; // Double meh
break;
- case 0x01: // read-write error recovery page
- scsi_cmdbuf[pos++] = 0x01; // !PS, page id
- scsi_cmdbuf[pos++] = 0x0a; // page length
- scsi_cmdbuf[pos++] = 0; // various bits
- scsi_cmdbuf[pos++] = 0; // read retry count
- scsi_cmdbuf[pos++] = 0; // correction span
- scsi_cmdbuf[pos++] = 0; // head offset count
- scsi_cmdbuf[pos++] = 0; // data strobe offset count
- scsi_cmdbuf[pos++] = 0; // reserved
- scsi_cmdbuf[pos++] = 0; // write retry count
- scsi_cmdbuf[pos++] = 0; // reserved
- scsi_cmdbuf[pos++] = 0; // recovery time limit (msb)
- scsi_cmdbuf[pos++] = 0; // recovery time limit (lsb)
- break;
-
- case 0x02: // disconnect-reconnect page
- scsi_cmdbuf[pos++] = 0x02; // !PS, page id
- scsi_cmdbuf[pos++] = 0x0e; // page length
- scsi_cmdbuf[pos++] = 0; // buffer full ratio
- scsi_cmdbuf[pos++] = 0; // buffer empty ratio
- scsi_cmdbuf[pos++] = 0; // bus inactivity limit (msb)
- scsi_cmdbuf[pos++] = 0; // bus inactivity limit (lsb)
- scsi_cmdbuf[pos++] = 0; // disconnect time limit (msb)
- scsi_cmdbuf[pos++] = 0; // disconnect time limit (lsb)
- scsi_cmdbuf[pos++] = 0; // connect time limit (msb)
- scsi_cmdbuf[pos++] = 0; // connect time limit (lsb)
- scsi_cmdbuf[pos++] = 0; // maximum burst size (msb)
- scsi_cmdbuf[pos++] = 0; // maximum burst size (lsb)
- scsi_cmdbuf[pos++] = 0; // reserved
- scsi_cmdbuf[pos++] = 0; // reserved
- scsi_cmdbuf[pos++] = 0; // reserved
- scsi_cmdbuf[pos++] = 0; // reserved
- break;
-
case 0x03: { // Format parameters page
scsi_cmdbuf[pos++] = 0x83; // PS, page id
scsi_cmdbuf[pos++] = 0x16; // Page length
@@ -329,21 +295,6 @@ void nscsi_harddisk_device::scsi_command()
break;
}
- case 0x08: // caching page
- scsi_cmdbuf[pos++] = 0x08; // !PS, page id
- scsi_cmdbuf[pos++] = 0x0a; // page length
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- break;
-
case 0x30: { // Apple firmware ID page
scsi_cmdbuf[pos++] = 0xb0; // cPS, page id
scsi_cmdbuf[pos++] = 0x16; // Page length
@@ -373,25 +324,16 @@ void nscsi_harddisk_device::scsi_command()
}
default:
- if (page != 0x3f) {
- LOG("mode sense page %02x unhandled\n", page);
- fail = true;
- }
+ LOG("mode sense page %02x unhandled\n", page);
break;
}
}
+ scsi_cmdbuf[0] = pos;
+ if(pos > size)
+ pos = size;
- if (!fail) {
- scsi_cmdbuf[0] = pos;
- if (pos > size)
- pos = size;
-
- scsi_data_in(0, pos);
- scsi_status_complete(SS_GOOD);
- } else {
- scsi_status_complete(SS_CHECK_CONDITION);
- sense(false, SK_ILLEGAL_REQUEST, SK_ASC_INVALID_FIELD_IN_CDB);
- }
+ scsi_data_in(0, pos);
+ scsi_status_complete(SS_GOOD);
break;
}
@@ -400,48 +342,6 @@ void nscsi_harddisk_device::scsi_command()
scsi_status_complete(SS_GOOD);
break;
- case SC_RECIEVE_DIAG_RES: {
- LOG("command RECIEVE DIAGNOSTICS RESULTS");
- int size = (scsi_cmdbuf[3] << 8) | scsi_cmdbuf[4];
- int pos = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 6;
- scsi_cmdbuf[pos++] = 0; // ROM is OK
- scsi_cmdbuf[pos++] = 0; // RAM is OK
- scsi_cmdbuf[pos++] = 0; // Data buffer is OK
- scsi_cmdbuf[pos++] = 0; // Interface is OK
- scsi_cmdbuf[pos++] = 0;
- if(size > pos)
- size = pos;
- scsi_data_in(0, size);
- scsi_status_complete(SS_GOOD);
- break;
- }
-
- case SC_SEND_DIAGNOSTICS: {
- LOG("command SEND DIAGNOSTICS");
- int size = (scsi_cmdbuf[3] << 8) | scsi_cmdbuf[4];
- if(scsi_cmdbuf[1] & 4) {
- // Self-test
- scsi_status_complete(SS_GOOD);
- break;
- }
- int pos = 0;
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 6;
- scsi_cmdbuf[pos++] = 0; // ROM is OK
- scsi_cmdbuf[pos++] = 0; // RAM is OK
- scsi_cmdbuf[pos++] = 0; // Data buffer is OK
- scsi_cmdbuf[pos++] = 0; // Interface is OK
- scsi_cmdbuf[pos++] = 0;
- scsi_cmdbuf[pos++] = 0;
- if(size > pos)
- size = pos;
- scsi_data_in(0, size);
- scsi_status_complete(SS_GOOD);
- break;
- }
-
case SC_READ_CAPACITY: {
LOG("command READ CAPACITY\n");
@@ -503,11 +403,6 @@ void nscsi_harddisk_device::scsi_command()
scsi_status_complete(SS_GOOD);
break;
- case SC_MODE_SELECT_6:
- LOG("command MODE SELECT\n");
- scsi_status_complete(SS_GOOD);
- break;
-
default:
LOG("command %02x ***UNKNOWN***\n", scsi_cmdbuf[0]);
nscsi_full_device::scsi_command();
diff --git a/src/devices/machine/nscsi_hd.h b/src/devices/machine/nscsi_hd.h
index 5ddbf3e8519..19dfe55c0e5 100644
--- a/src/devices/machine/nscsi_hd.h
+++ b/src/devices/machine/nscsi_hd.h
@@ -6,7 +6,7 @@
#pragma once
#include "machine/nscsi_bus.h"
-#include "imagedev/harddriv.h"
+#include "harddisk.h"
class nscsi_harddisk_device : public nscsi_full_device
{
@@ -24,7 +24,6 @@ protected:
virtual uint8_t scsi_get_data(int id, int pos) override;
virtual void scsi_put_data(int buf, int offset, uint8_t data) override;
- required_device<harddisk_image_device> image;
uint8_t block[512];
hard_disk_file *harddisk;
int lba, cur_lba, blocks;
diff --git a/src/devices/machine/output_latch.h b/src/devices/machine/output_latch.h
index 2498be7f63f..c915b4c7207 100644
--- a/src/devices/machine/output_latch.h
+++ b/src/devices/machine/output_latch.h
@@ -6,11 +6,36 @@
#pragma once
+#define MCFG_OUTPUT_LATCH_BIT0_HANDLER(_devcb) \
+ downcast<output_latch_device &>(*device).set_bit_handler<0>(DEVCB_##_devcb);
+
+#define MCFG_OUTPUT_LATCH_BIT1_HANDLER(_devcb) \
+ downcast<output_latch_device &>(*device).set_bit_handler<1>(DEVCB_##_devcb);
+
+#define MCFG_OUTPUT_LATCH_BIT2_HANDLER(_devcb) \
+ downcast<output_latch_device &>(*device).set_bit_handler<2>(DEVCB_##_devcb);
+
+#define MCFG_OUTPUT_LATCH_BIT3_HANDLER(_devcb) \
+ downcast<output_latch_device &>(*device).set_bit_handler<3>(DEVCB_##_devcb);
+
+#define MCFG_OUTPUT_LATCH_BIT4_HANDLER(_devcb) \
+ downcast<output_latch_device &>(*device).set_bit_handler<4>(DEVCB_##_devcb);
+
+#define MCFG_OUTPUT_LATCH_BIT5_HANDLER(_devcb) \
+ downcast<output_latch_device &>(*device).set_bit_handler<5>(DEVCB_##_devcb);
+
+#define MCFG_OUTPUT_LATCH_BIT6_HANDLER(_devcb) \
+ downcast<output_latch_device &>(*device).set_bit_handler<6>(DEVCB_##_devcb);
+
+#define MCFG_OUTPUT_LATCH_BIT7_HANDLER(_devcb) \
+ downcast<output_latch_device &>(*device).set_bit_handler<7>(DEVCB_##_devcb);
+
class output_latch_device : public device_t
{
public:
output_latch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ template <unsigned Bit, class Object> devcb_base &set_bit_handler(Object &&cb) { return m_bit_handlers[Bit].set_callback(std::forward<Object>(cb)); }
template <unsigned Bit> auto bit_handler() { return m_bit_handlers[Bit].bind(); }
void write(uint8_t data);
diff --git a/src/devices/machine/pc_fdc.cpp b/src/devices/machine/pc_fdc.cpp
index 8f48da0f505..601c4c813c5 100644
--- a/src/devices/machine/pc_fdc.cpp
+++ b/src/devices/machine/pc_fdc.cpp
@@ -157,7 +157,7 @@ uint8_t pc_fdc_family_device::do_dir_r()
WRITE8_MEMBER( pc_fdc_xt_device::dor_fifo_w)
{
- fdc->fifo_w(data);
+ fdc->fifo_w(space, 0, data, mem_mask);
dor_w(space, 0, data, mem_mask);
}
diff --git a/src/devices/machine/pc_lpt.cpp b/src/devices/machine/pc_lpt.cpp
index 0d43fbc6eeb..b0f97871e87 100644
--- a/src/devices/machine/pc_lpt.cpp
+++ b/src/devices/machine/pc_lpt.cpp
@@ -46,8 +46,7 @@ void pc_lpt_device::device_reset()
m_cent_ctrl_out->write(m_control);
}
-void pc_lpt_device::device_add_mconfig(machine_config &config)
-{
+MACHINE_CONFIG_START(pc_lpt_device::device_add_mconfig)
centronics_device &centronics(CENTRONICS(config, "centronics", centronics_devices, "printer"));
centronics.set_data_input_buffer(m_cent_data_in);
centronics.fault_handler().set(m_cent_status_in, FUNC(input_buffer_device::write_bit3));
@@ -65,8 +64,7 @@ void pc_lpt_device::device_add_mconfig(machine_config &config)
INPUT_BUFFER(config, m_cent_ctrl_in);
INPUT_BUFFER(config, m_cent_status_in);
- OUTPUT_LATCH(config, m_cent_data_out);
- centronics.set_output_latch(*m_cent_data_out);
+ MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics")
OUTPUT_LATCH(config, m_cent_ctrl_out);
m_cent_ctrl_out->bit_handler<0>().set("centronics", FUNC(centronics_device::write_strobe));
@@ -74,7 +72,7 @@ void pc_lpt_device::device_add_mconfig(machine_config &config)
m_cent_ctrl_out->bit_handler<2>().set("centronics", FUNC(centronics_device::write_init));
m_cent_ctrl_out->bit_handler<3>().set("centronics", FUNC(centronics_device::write_select_in));
m_cent_ctrl_out->bit_handler<4>().set(FUNC(pc_lpt_device::write_irq_enabled));
-}
+MACHINE_CONFIG_END
READ8_MEMBER( pc_lpt_device::data_r )
diff --git a/src/devices/machine/pckeybrd.h b/src/devices/machine/pckeybrd.h
index 42a443226f5..7ee6c5c2c14 100644
--- a/src/devices/machine/pckeybrd.h
+++ b/src/devices/machine/pckeybrd.h
@@ -20,11 +20,12 @@
class pc_keyboard_device : public device_t
{
public:
- pc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ pc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE_LINE_MEMBER(enable);
+ template <class Object> devcb_base &set_keypress_callback(Object &&cb) { return m_out_keypress_func.set_callback(std::forward<Object>(cb)); }
auto keypress() { return m_out_keypress_func.bind(); }
enum class KEYBOARD_TYPE
@@ -76,13 +77,7 @@ private:
class at_keyboard_device : public pc_keyboard_device
{
public:
- at_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, KEYBOARD_TYPE type, int default_set)
- : at_keyboard_device(mconfig, tag, owner, 0)
- {
- set_type(type, default_set);
- }
-
- at_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ at_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_WRITE8_MEMBER( write );
@@ -119,4 +114,18 @@ INPUT_PORTS_EXTERN( at_keyboard );
DECLARE_DEVICE_TYPE(PC_KEYB, pc_keyboard_device)
DECLARE_DEVICE_TYPE(AT_KEYB, at_keyboard_device)
+#define MCFG_PC_KEYB_ADD(_tag, _cb) \
+ MCFG_DEVICE_ADD(_tag, PC_KEYB, 0) \
+ downcast<pc_keyboard_device &>(*device).set_keypress_callback(DEVCB_##_cb);
+
+#define MCFG_AT_KEYB_ADD(_tag, _def_set, _cb) \
+ MCFG_DEVICE_ADD(_tag, AT_KEYB, 0) \
+ downcast<at_keyboard_device &>(*device).set_type(pc_keyboard_device::KEYBOARD_TYPE::AT, _def_set); \
+ downcast<pc_keyboard_device &>(*device).set_keypress_callback(DEVCB_##_cb);
+
+#define MCFG_AT_MF2_KEYB_ADD(_tag, _def_set, _cb) \
+ MCFG_DEVICE_ADD(_tag, AT_KEYB, 0) \
+ downcast<at_keyboard_device &>(*device).set_type(pc_keyboard_device::KEYBOARD_TYPE_MF2, _def_set); \
+ downcast<pc_keyboard_device &>(*device).set_keypress_callback(DEVCB_##_cb);
+
#endif // MAME_MACHINE_PCKEYBRD_H
diff --git a/src/devices/machine/pdc.cpp b/src/devices/machine/pdc.cpp
index 20b0c627dc5..99964762548 100644
--- a/src/devices/machine/pdc.cpp
+++ b/src/devices/machine/pdc.cpp
@@ -261,7 +261,7 @@ void pdc_device::device_add_mconfig(machine_config &config)
Z80(config, m_pdccpu, XTAL(10'000'000) / 2);
m_pdccpu->set_addrmap(AS_PROGRAM, &pdc_device::pdc_mem);
m_pdccpu->set_addrmap(AS_IO, &pdc_device::pdc_io);
- //config.m_perfect_cpu_quantum = subtag(M6502_TAG);
+ //MCFG_QUANTUM_PERFECT_CPU(M6502_TAG)
/* Floppy Disk Controller - uPD765a - NEC D765AC-2 */
UPD765A(config, m_fdc, 4'000'000, true, true);
@@ -279,7 +279,6 @@ void pdc_device::device_add_mconfig(machine_config &config)
m_dma8237->out_eop_callback().set(FUNC(pdc_device::i8237_eop_w));
m_dma8237->in_memr_callback().set(FUNC(pdc_device::i8237_dma_mem_r));
m_dma8237->out_memw_callback().set(FUNC(pdc_device::i8237_dma_mem_w));
- //m_dma8237->out_dack_callback<0>().set(m_fdc, FUNC(upd765a_device::dack_w));
m_dma8237->in_ior_callback<0>().set(FUNC(pdc_device::i8237_fdc_dma_r));
m_dma8237->out_iow_callback<0>().set(FUNC(pdc_device::i8237_fdc_dma_w));
m_dma8237->in_ior_callback<1>().set(FUNC(pdc_device::m68k_dma_r));
diff --git a/src/devices/machine/pic8259.h b/src/devices/machine/pic8259.h
index 298ef1debea..0b85efd9ac1 100644
--- a/src/devices/machine/pic8259.h
+++ b/src/devices/machine/pic8259.h
@@ -31,7 +31,7 @@
class pic8259_device : public device_t
{
public:
- pic8259_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ pic8259_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
auto out_int_callback() { return m_out_int_func.bind(); } // Interrupt request output to CPU or master 8259 (active high)
auto in_sp_callback() { return m_in_sp_func.bind(); } // Slave program select (VCC = master; GND = slave; pin becomes EN output in buffered mode)
@@ -118,7 +118,7 @@ private:
class v5x_icu_device : public pic8259_device
{
public:
- v5x_icu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ v5x_icu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual bool is_x86() const override { return true; }
diff --git a/src/devices/machine/pit8253.cpp b/src/devices/machine/pit8253.cpp
index 7d52572ba89..6e6f86e5b0e 100644
--- a/src/devices/machine/pit8253.cpp
+++ b/src/devices/machine/pit8253.cpp
@@ -74,12 +74,11 @@ fe2010_pit_device::fe2010_pit_device(const machine_config &mconfig, const char *
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void pit8253_device::device_add_mconfig(machine_config &config)
-{
- PIT_COUNTER(config, "counter0", 0);
- PIT_COUNTER(config, "counter1", 0);
- PIT_COUNTER(config, "counter2", 0);
-}
+MACHINE_CONFIG_START(pit8253_device::device_add_mconfig)
+ MCFG_DEVICE_ADD("counter0", PIT_COUNTER, 0)
+ MCFG_DEVICE_ADD("counter1", PIT_COUNTER, 0)
+ MCFG_DEVICE_ADD("counter2", PIT_COUNTER, 0)
+MACHINE_CONFIG_END
//-------------------------------------------------
diff --git a/src/devices/machine/pit8253.h b/src/devices/machine/pit8253.h
index 77f0bf552f9..eebee4edbb3 100644
--- a/src/devices/machine/pit8253.h
+++ b/src/devices/machine/pit8253.h
@@ -104,7 +104,7 @@ class pit8253_device : public device_t
public:
// construction/destruction
- pit8253_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ pit8253_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
template <unsigned N> void set_clk(double clk) { m_clk[N] = clk; }
@@ -157,7 +157,7 @@ DECLARE_DEVICE_TYPE(PIT8253, pit8253_device)
class pit8254_device : public pit8253_device
{
public:
- pit8254_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ pit8254_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void readback_command(uint8_t data) override;
@@ -168,7 +168,7 @@ DECLARE_DEVICE_TYPE(PIT8254, pit8254_device)
class fe2010_pit_device : public pit8253_device
{
public:
- fe2010_pit_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ fe2010_pit_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
DECLARE_DEVICE_TYPE(FE2010_PIT, fe2010_pit_device)
diff --git a/src/devices/machine/pla.h b/src/devices/machine/pla.h
index b614a968b36..7e4672b7860 100644
--- a/src/devices/machine/pla.h
+++ b/src/devices/machine/pla.h
@@ -11,6 +11,24 @@
#pragma once
+///*************************************************************************
+// INTERFACE CONFIGURATION MACROS
+///*************************************************************************
+
+#define MCFG_PLA_ADD(tag, inputs, outputs, terms) \
+ MCFG_DEVICE_ADD((tag), PLA, 0) \
+ downcast<pla_device &>(*device).set_num_inputs((inputs)); \
+ downcast<pla_device &>(*device).set_num_outputs((outputs)); \
+ downcast<pla_device &>(*device).set_num_terms((terms));
+
+#define MCFG_PLA_INPUTMASK(mask) \
+ downcast<pla_device &>(*device).set_inputmask((mask));
+
+#define MCFG_PLA_FILEFORMAT(format) \
+ downcast<pla_device &>(*device).set_format((pla_device::FMT::format));
+
+
+// macros for known (and used) devices
// 82S100, 82S101, PLS100, PLS101
// 16x48x8 PLA, 28-pin:
@@ -30,7 +48,8 @@
F4 13 | | 16 F2
GND 14 |_____________| 15 F3
*/
-
+#define MCFG_PLS100_ADD(tag) \
+ MCFG_DEVICE_ADD((tag), PLS100)
///*************************************************************************
// TYPE DEFINITIONS
diff --git a/src/devices/machine/pxa255.cpp b/src/devices/machine/pxa255.cpp
index 5a65f1542ae..0e96fec2b27 100644
--- a/src/devices/machine/pxa255.cpp
+++ b/src/devices/machine/pxa255.cpp
@@ -1222,20 +1222,20 @@ uint32_t pxa255_periphs_device::screen_update(screen_device &screen, bitmap_rgb3
return 0;
}
-void pxa255_periphs_device::device_add_mconfig(machine_config &config)
-{
- screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
- screen.set_size(1024, 1024);
- screen.set_visarea(0, 295, 0, 479);
- screen.set_screen_update(FUNC(pxa255_periphs_device::screen_update));
-
- PALETTE(config, m_palette).set_entries(256);
+MACHINE_CONFIG_START(pxa255_periphs_device::device_add_mconfig)
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
+ MCFG_SCREEN_SIZE(1024, 1024)
+ MCFG_SCREEN_VISIBLE_AREA(0, 295, 0, 479)
+ MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, pxa255_periphs_device, screen_update)
+ MCFG_PALETTE_ADD(m_palette, 256)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
- DMADAC(config, m_dmadac[0]).add_route(ALL_OUTPUTS, "lspeaker", 1.0);
- DMADAC(config, m_dmadac[1]).add_route(ALL_OUTPUTS, "rspeaker", 1.0);
-}
+ MCFG_DEVICE_ADD(m_dmadac[0], DMADAC)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
+ MCFG_DEVICE_ADD(m_dmadac[1], DMADAC)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
+MACHINE_CONFIG_END
diff --git a/src/devices/machine/rtc65271.cpp b/src/devices/machine/rtc65271.cpp
index 9ccc83997bf..f44cc8255fc 100644
--- a/src/devices/machine/rtc65271.cpp
+++ b/src/devices/machine/rtc65271.cpp
@@ -346,12 +346,12 @@ uint8_t rtc65271_device::read(int xramsel, offs_t offset)
return reply;
}
-uint8_t rtc65271_device::rtc_r(offs_t offset)
+READ8_MEMBER( rtc65271_device::rtc_r )
{
return read(0, offset );
}
-uint8_t rtc65271_device::xram_r(offs_t offset)
+READ8_MEMBER( rtc65271_device::xram_r )
{
return read(1, offset );
}
@@ -436,12 +436,12 @@ void rtc65271_device::write(int xramsel, offs_t offset, uint8_t data)
}
}
-void rtc65271_device::rtc_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER( rtc65271_device::rtc_w )
{
write(0, offset, data );
}
-void rtc65271_device::xram_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER( rtc65271_device::xram_w )
{
write(1, offset, data );
}
diff --git a/src/devices/machine/rtc65271.h b/src/devices/machine/rtc65271.h
index 1a69b518839..65ee8233675 100644
--- a/src/devices/machine/rtc65271.h
+++ b/src/devices/machine/rtc65271.h
@@ -21,10 +21,10 @@ public:
auto interrupt_cb() { return m_interrupt_cb.bind(); }
- uint8_t rtc_r(offs_t offset);
- uint8_t xram_r(offs_t offset);
- void rtc_w(offs_t offset, uint8_t data);
- void xram_w(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( rtc_r );
+ DECLARE_READ8_MEMBER( xram_r );
+ DECLARE_WRITE8_MEMBER( rtc_w );
+ DECLARE_WRITE8_MEMBER( xram_w );
protected:
// device-level overrides
diff --git a/src/devices/machine/scc2698b.cpp b/src/devices/machine/scc2698b.cpp
index 8a362e26d45..1f6c537f52d 100644
--- a/src/devices/machine/scc2698b.cpp
+++ b/src/devices/machine/scc2698b.cpp
@@ -768,8 +768,7 @@ attotime scc2698b_device::generate_baudrate(int block, int tx, int table_index)
-void scc2698b_device::device_add_mconfig(machine_config &config)
-{
+MACHINE_CONFIG_START(scc2698b_device::device_add_mconfig)
for (required_device<scc2698b_channel> &channel : m_channel)
SCC2698B_CHANNEL(config, channel, 0);
-}
+MACHINE_CONFIG_END
diff --git a/src/devices/machine/scnxx562.cpp b/src/devices/machine/scnxx562.cpp
index c3bfbfacc5d..9ccf996782c 100644
--- a/src/devices/machine/scnxx562.cpp
+++ b/src/devices/machine/scnxx562.cpp
@@ -126,11 +126,10 @@ DEFINE_DEVICE_TYPE(DUSCC68C562, duscc68c562_device, "duscc68c562", "Philips
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void duscc_device::device_add_mconfig(machine_config &config)
-{
- DUSCC_CHANNEL(config, CHANA_TAG, 0);
- DUSCC_CHANNEL(config, CHANB_TAG, 0);
-}
+MACHINE_CONFIG_START(duscc_device::device_add_mconfig)
+ MCFG_DEVICE_ADD(CHANA_TAG, DUSCC_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANB_TAG, DUSCC_CHANNEL, 0)
+MACHINE_CONFIG_END
//**************************************************************************
// LIVE DEVICE
diff --git a/src/devices/machine/sis85c496.cpp b/src/devices/machine/sis85c496.cpp
index 87b01edf2e6..186c4894b8d 100644
--- a/src/devices/machine/sis85c496.cpp
+++ b/src/devices/machine/sis85c496.cpp
@@ -45,8 +45,7 @@ void sis85c496_host_device::internal_io_map(address_map &map)
map(0x00e0, 0x00ef).noprw();
}
-void sis85c496_host_device::device_add_mconfig(machine_config &config)
-{
+MACHINE_CONFIG_START(sis85c496_host_device::device_add_mconfig)
PIT8254(config, m_pit8254, 0);
m_pit8254->set_clk<0>(4772720/4); // heartbeat IRQ
m_pit8254->out_handler<0>().set(FUNC(sis85c496_host_device::at_pit8254_out0_changed));
@@ -104,10 +103,10 @@ void sis85c496_host_device::device_add_mconfig(machine_config &config)
m_keybc->kbd_clk().set("pc_kbdc", FUNC(pc_kbdc_device::clock_write_from_mb));
m_keybc->kbd_data().set("pc_kbdc", FUNC(pc_kbdc_device::data_write_from_mb));
- PC_KBDC(config, m_pc_kbdc, 0);
- m_pc_kbdc->out_clock_cb().set("keybc", FUNC(at_keyboard_controller_device::kbd_clk_w));
- m_pc_kbdc->out_data_cb().set("keybc", FUNC(at_keyboard_controller_device::kbd_data_w));
- PC_KBDC_SLOT(config, "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL).set_pc_kbdc_slot(subdevice("pc_kbdc"));
+ MCFG_DEVICE_ADD("pc_kbdc", PC_KBDC, 0)
+ MCFG_PC_KBDC_OUT_CLOCK_CB(WRITELINE("keybc", at_keyboard_controller_device, kbd_clk_w))
+ MCFG_PC_KBDC_OUT_DATA_CB(WRITELINE("keybc", at_keyboard_controller_device, kbd_data_w))
+ MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL)
DS12885(config, m_ds12885);
m_ds12885->irq().set(m_pic8259_slave, FUNC(pic8259_device::ir0_w));
@@ -116,7 +115,7 @@ void sis85c496_host_device::device_add_mconfig(machine_config &config)
/* sound hardware */
SPEAKER(config, "mono").front_center();
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);
-}
+MACHINE_CONFIG_END
sis85c496_host_device::sis85c496_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -493,8 +492,6 @@ WRITE_LINE_MEMBER( sis85c496_host_device::at_dma8237_out_eop )
void sis85c496_host_device::pc_select_dma_channel(int channel, bool state)
{
- //m_isabus->dack_line_w(channel, state);
-
if(!state) {
m_dma_channel = channel;
//if(m_cur_eop)
@@ -544,19 +541,19 @@ WRITE8_MEMBER( sis85c496_host_device::at_portb_w )
READ8_MEMBER( sis85c496_host_device::at_dma8237_2_r )
{
- return m_dma8237_2->read( offset / 2);
+ return m_dma8237_2->read( space, offset / 2);
}
WRITE8_MEMBER( sis85c496_host_device::at_dma8237_2_w )
{
- m_dma8237_2->write( offset / 2, data);
+ m_dma8237_2->write( space, offset / 2, data);
}
READ8_MEMBER( sis85c496_host_device::at_keybc_r )
{
switch (offset)
{
- case 0: return m_keybc->data_r();
+ case 0: return m_keybc->data_r(space, 0);
case 1: return at_portb_r(space, 0);
}
@@ -567,7 +564,7 @@ WRITE8_MEMBER( sis85c496_host_device::at_keybc_w )
{
switch (offset)
{
- case 0: m_keybc->data_w(data); break;
+ case 0: m_keybc->data_w(space, 0, data); break;
case 1: at_portb_w(space, 0, data); break;
}
}
@@ -578,10 +575,10 @@ WRITE8_MEMBER( sis85c496_host_device::write_rtc )
if (offset==0) {
m_nmi_enabled = BIT(data,7);
//m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0));
- m_ds12885->write(0,data);
+ m_ds12885->write(space,0,data);
}
else {
- m_ds12885->write(offset,data);
+ m_ds12885->write(space,offset,data);
}
}
diff --git a/src/devices/machine/smc91c9x.cpp b/src/devices/machine/smc91c9x.cpp
index 359a69eefdb..e081c2c6a17 100644
--- a/src/devices/machine/smc91c9x.cpp
+++ b/src/devices/machine/smc91c9x.cpp
@@ -4,29 +4,92 @@
SMC91C9X ethernet controller implementation
- by Aaron Giles, Ted Green
+ by Aaron Giles, Jean-François DEL NERO
-***************************************************************************/
+***************************************************************************
+
+ Notes:
+ * Connected mode working
+
+**************************************************************************/
#include "emu.h"
#include "smc91c9x.h"
-#include <sstream>
-#include <iomanip>
+// Needed for netdev_count???
+#include "osdnet.h"
+
/***************************************************************************
DEBUGGING
***************************************************************************/
-#define LOG_GENERAL (1U << 0)
-#define LOG_PACKETS (1U << 1)
-#define LOG_TX (1U << 2)
-#define LOG_RX (1U << 3)
-#define LOG_FILTER (1U << 4)
-//#define VERBOSE (LOG_GENERAL | LOG_PACKETS | LOG_TX | LOG_RX | LOG_FILTER)
+//#define VERBOSE 1
#include "logmacro.h"
#define DISPLAY_STATS (0)
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+/* Ethernet registers - bank 0 */
+#define EREG_TCR (0*8 + 0)
+#define EREG_EPH_STATUS (0*8 + 1)
+#define EREG_RCR (0*8 + 2)
+#define EREG_COUNTER (0*8 + 3)
+#define EREG_MIR (0*8 + 4)
+#define EREG_MCR (0*8 + 5)
+#define EREG_BANK (0*8 + 7)
+
+/* Ethernet registers - bank 1 */
+#define EREG_CONFIG (1*8 + 0)
+#define EREG_BASE (1*8 + 1)
+#define EREG_IA0_1 (1*8 + 2)
+#define EREG_IA2_3 (1*8 + 3)
+#define EREG_IA4_5 (1*8 + 4)
+#define EREG_GENERAL_PURP (1*8 + 5)
+#define EREG_CONTROL (1*8 + 6)
+
+/* Ethernet registers - bank 2 */
+#define EREG_MMU_COMMAND (2*8 + 0)
+#define EREG_PNR_ARR (2*8 + 1)
+#define EREG_FIFO_PORTS (2*8 + 2)
+#define EREG_POINTER (2*8 + 3)
+#define EREG_DATA_0 (2*8 + 4)
+#define EREG_DATA_1 (2*8 + 5)
+#define EREG_INTERRUPT (2*8 + 6)
+
+/* Ethernet registers - bank 3 */
+#define EREG_MT0_1 (3*8 + 0)
+#define EREG_MT2_3 (3*8 + 1)
+#define EREG_MT4_5 (3*8 + 2)
+#define EREG_MT6_7 (3*8 + 3)
+#define EREG_MGMT (3*8 + 4)
+#define EREG_REVISION (3*8 + 5)
+#define EREG_ERCV (3*8 + 6)
+
+/* Ethernet MMU commands */
+#define ECMD_NOP 0
+#define ECMD_ALLOCATE 2
+#define ECMD_RESET_MMU 4
+#define ECMD_REMOVE_TOPFRAME_RX 6
+#define ECMD_REMOVE_TOPFRAME_TX 7
+#define ECMD_REMOVE_RELEASE_TOPFRAME_RX 8
+#define ECMD_RELEASE_PACKET 10
+#define ECMD_ENQUEUE_PACKET 12
+#define ECMD_RESET_FIFOS 14
+
+/* Ethernet interrupt bits */
+#define EINT_RCV 0x01
+#define EINT_TX 0x02
+#define EINT_TX_EMPTY 0x04
+#define EINT_ALLOC 0x08
+#define EINT_RX_OVRN 0x10
+#define EINT_EPH 0x20
+#define EINT_ERCV 0x40
+
/* Ethernet register names */
static const char *const ethernet_regname[64] =
{
@@ -44,93 +107,73 @@ static const char *const ethernet_regname[64] =
DEVICE INTERFACE
***************************************************************************/
-DEFINE_DEVICE_TYPE(SMC91C94, smc91c94_device, "smc91c94", "SMC91C94 Ethernet Controller")
-
-smc91c94_device::smc91c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : smc91c9x_device(mconfig, SMC91C94, tag, owner, clock, dev_type::SMC91C94)
-{
- m_num_ebuf = 18;
-}
-
-DEFINE_DEVICE_TYPE(SMC91C96, smc91c96_device, "smc91c96", "SMC91C96 Ethernet Controller")
-
-smc91c96_device::smc91c96_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : smc91c9x_device(mconfig, SMC91C96, tag, owner, clock, dev_type::SMC91C96)
-{
- m_num_ebuf = 24;
-}
-
-smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, dev_type device_type)
+smc91c9x_device::smc91c9x_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_network_interface(mconfig, *this, 10.0f)
- , m_device_type(device_type)
- , m_num_ebuf(16)
, m_irq_handler(*this)
, m_link_unconnected(false)
{
}
-const u8 smc91c9x_device::ETH_BROADCAST[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-const u8 smc91c9x_device::WMS_OUI[] = { 0x00, 0xA0, 0xAF };
-
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void smc91c9x_device::device_start()
{
- // Allocate main buffer
- m_buffer = std::make_unique<u8[]>(ETHER_BUFFER_SIZE * m_num_ebuf);
-
// TX timer
- m_tx_poll = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(smc91c9x_device::tx_poll), this));
+ m_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(smc91c9x_device::send_frame), this));
m_irq_handler.resolve_safe();
- // These registers don't get cleared on reset
- m_reg[B1_CONFIG] = 0x0030; m_regmask[B1_CONFIG] = 0x17c6;
- m_reg[B1_BASE] = 0x1866; m_regmask[B1_BASE] = 0xfffe;
-
- m_reg[B1_IA0_1] = 0x0000; m_regmask[B1_IA0_1] = 0xffff;
- m_reg[B1_IA2_3] = 0x0000; m_regmask[B1_IA2_3] = 0xffff;
- m_reg[B1_IA4_5] = 0x0000; m_regmask[B1_IA4_5] = 0xffff;
-
- // Revision is set based on chip type
- m_regmask[B3_REVISION] = 0x0000;
- if (m_device_type == dev_type::SMC91C94)
- m_reg[B3_REVISION] = 0x3345;
- else if (m_device_type == dev_type::SMC91C96)
- m_reg[B3_REVISION] = 0x3346;
- else
- fatalerror("device_start: Unknown device type\n");
-
/* register ide states */
save_item(NAME(m_reg));
save_item(NAME(m_regmask));
save_item(NAME(m_irq_state));
- save_pointer(NAME(m_buffer), ETHER_BUFFER_SIZE * m_num_ebuf);
+ save_item(NAME(m_buffer));
save_item(NAME(m_sent));
save_item(NAME(m_recd));
save_item(NAME(m_alloc_rx));
save_item(NAME(m_alloc_tx));
- save_item(NAME(m_tx_active));
- save_item(NAME(m_rx_active));
- save_item(NAME(m_tx_retry_count));
- save_item(NAME(m_rx_hash));
- save_item(NAME(m_loopback_result));
-
- // Circular FIFOs
- save_item(NAME(m_queued_tx));
- save_item(NAME(m_queued_tx_h));
- save_item(NAME(m_queued_tx_t));
- save_item(NAME(m_completed_tx));
- save_item(NAME(m_completed_tx_h));
- save_item(NAME(m_completed_tx_t));
- save_item(NAME(m_completed_rx));
- save_item(NAME(m_completed_rx_h));
- save_item(NAME(m_completed_rx_t));
+ // Save vector data for proper save state restoration
+ save_item(NAME(m_comp_rx_data));
+ save_item(NAME(m_comp_tx_data));
+ save_item(NAME(m_trans_tx_data));
+ // Save vector sizes for proper save state restoration
+ save_item(NAME(m_comp_tx_size));
+ save_item(NAME(m_comp_rx_size));
+ save_item(NAME(m_trans_tx_size));
+}
+
+// Save state presave to save vector sizes
+void smc91c9x_device::device_pre_save()
+{
+ m_comp_tx_size = m_comp_tx.size();
+ m_comp_rx_size = m_comp_rx.size();
+ m_trans_tx_size = m_trans_tx.size();
+ memcpy(m_comp_rx_data, m_comp_rx.data(), m_comp_rx_size * sizeof(u32));
+ memcpy(m_comp_tx_data, m_comp_tx.data(), m_comp_tx_size * sizeof(u32));
+ memcpy(m_trans_tx_data, m_trans_tx.data(), m_trans_tx_size * sizeof(u32));
+
+ //osd_printf_info("Save: comp_tx: %d comp_rx: %d trans_tx: %d\n", m_comp_tx_size, m_comp_rx_size, m_trans_tx_size);
+ //if (m_comp_tx_size)
+ // osd_printf_info("comp_tx packet: %d\n", m_comp_tx.front());
}
+// Save state preload to restore vector sizes
+void smc91c9x_device::device_post_load()
+{
+ m_comp_tx.resize(m_comp_tx_size);
+ m_comp_rx.resize(m_comp_rx_size);
+ m_trans_tx.resize(m_trans_tx_size);
+ memcpy(m_comp_rx.data(), m_comp_rx_data, m_comp_rx_size * sizeof(u32));
+ memcpy(m_comp_tx.data(), m_comp_tx_data, m_comp_tx_size * sizeof(u32));
+ memcpy(m_trans_tx.data(), m_trans_tx_data, m_trans_tx_size * sizeof(u32));
+
+ //osd_printf_info("Restore: comp_tx: %d comp_rx: %d trans_tx: %d\n", m_comp_tx_size, m_comp_rx_size, m_trans_tx_size);
+ //if (m_comp_tx_size)
+ // osd_printf_info("comp_tx size: %lu comp_tx packet: %d array_data: %d\n", m_comp_tx.size(), m_comp_tx.front(), m_comp_tx_data[0]);
+}
//-------------------------------------------------
// device_reset - device-specific reset
@@ -138,43 +181,75 @@ void smc91c9x_device::device_start()
void smc91c9x_device::device_reset()
{
+ std::fill(std::begin(m_reg), std::end(m_reg), 0);
+
+ std::fill(std::begin(m_regmask), std::end(m_regmask), 0);
+
m_irq_state = 0;
m_sent = 0;
m_recd = 0;
- m_tx_active = 0;
- m_rx_active = 0;
- m_tx_retry_count = 0;
-
- m_reg[B0_TCR] = 0x0000; m_regmask[B0_TCR] = 0x3d87;
- m_reg[B0_EPH_STATUS] = 0x0000; m_regmask[B0_EPH_STATUS] = 0x0000;
- m_reg[B0_RCR] = 0x0000; m_regmask[B0_RCR] = 0xc307;
- m_reg[B0_COUNTER] = 0x0000; m_regmask[B0_COUNTER] = 0x0000;
- m_reg[B0_MIR] = 0x1212; m_regmask[B0_MIR] = 0x0000;
- m_reg[B0_MCR] = 0x3300; m_regmask[B0_MCR] = 0x00ff;
- m_reg[B0_BANK] = 0x3300; m_regmask[B0_BANK] = 0x0007;
-
- m_reg[B1_GENERAL_PURP] = 0x0000; m_regmask[B1_GENERAL_PURP] = 0xffff;
- m_reg[B1_CONTROL] = 0x0100; m_regmask[B1_CONTROL] = 0x68e7;
-
- m_reg[B2_MMU_COMMAND] = 0x0000; m_regmask[B2_MMU_COMMAND] = 0x00e7;
- m_reg[B2_PNR_ARR] = 0x8000; m_regmask[B2_PNR_ARR] = 0x00ff;
- m_reg[B2_FIFO_PORTS] = 0x8080; m_regmask[B2_FIFO_PORTS] = 0x0000;
- m_reg[B2_POINTER] = 0x0000; m_regmask[B2_POINTER] = 0xf7ff;
- m_reg[B2_DATA_0] = 0x0000; m_regmask[B2_DATA_0] = 0xffff;
- m_reg[B2_DATA_1] = 0x0000; m_regmask[B2_DATA_1] = 0xffff;
- m_reg[B2_INTERRUPT] = 0x0004; m_regmask[B2_INTERRUPT] = 0x7f00;
-
- m_reg[B3_MT0_1] = 0x0000; m_regmask[B3_MT0_1] = 0xffff;
- m_reg[B3_MT2_3] = 0x0000; m_regmask[B3_MT2_3] = 0xffff;
- m_reg[B3_MT4_5] = 0x0000; m_regmask[B3_MT4_5] = 0xffff;
- m_reg[B3_MT6_7] = 0x0000; m_regmask[B3_MT6_7] = 0xffff;
- m_reg[B3_MGMT] = 0x3030; m_regmask[B3_MGMT] = 0x0f0f;
-
- m_reg[B3_ERCV] = 0x331f; m_regmask[B3_ERCV] = 0x009f;
+ m_reg[EREG_TCR] = 0x0000; m_regmask[EREG_TCR] = 0x3d87;
+ m_reg[EREG_EPH_STATUS] = 0x0000; m_regmask[EREG_EPH_STATUS] = 0x0000;
+ m_reg[EREG_RCR] = 0x0000; m_regmask[EREG_RCR] = 0xc307;
+ m_reg[EREG_COUNTER] = 0x0000; m_regmask[EREG_COUNTER] = 0x0000;
+ m_reg[EREG_MIR] = 0x1212; m_regmask[EREG_MIR] = 0x0000;
+ m_reg[EREG_MCR] = 0x3300; m_regmask[EREG_MCR] = 0x00ff;
+ m_reg[EREG_BANK] = 0x3300; m_regmask[EREG_BANK] = 0x0007;
+
+ m_reg[EREG_CONFIG] = 0x0030; m_regmask[EREG_CONFIG] = 0x17c6;
+ m_reg[EREG_BASE] = 0x1866; m_regmask[EREG_BASE] = 0xfffe;
+
+ // Default MAC
+ m_reg[EREG_IA0_1] = 0x1300; m_regmask[EREG_IA0_1] = 0xffff;
+ m_reg[EREG_IA2_3] = 0x12F7; m_regmask[EREG_IA2_3] = 0xffff;
+ m_reg[EREG_IA4_5] = 0x5634; m_regmask[EREG_IA4_5] = 0xffff;
+
+ m_reg[EREG_GENERAL_PURP] = 0x0000; m_regmask[EREG_GENERAL_PURP] = 0xffff;
+ m_reg[EREG_CONTROL] = 0x0100; m_regmask[EREG_CONTROL] = 0x68e7;
+
+ m_reg[EREG_MMU_COMMAND] = 0x0000; m_regmask[EREG_MMU_COMMAND] = 0x00e7;
+ m_reg[EREG_PNR_ARR] = 0x8000; m_regmask[EREG_PNR_ARR] = 0x00ff;
+ m_reg[EREG_FIFO_PORTS] = 0x8080; m_regmask[EREG_FIFO_PORTS] = 0x0000;
+ m_reg[EREG_POINTER] = 0x0000; m_regmask[EREG_POINTER] = 0xf7ff;
+ m_reg[EREG_DATA_0] = 0x0000; m_regmask[EREG_DATA_0] = 0xffff;
+ m_reg[EREG_DATA_1] = 0x0000; m_regmask[EREG_DATA_1] = 0xffff;
+ m_reg[EREG_INTERRUPT] = 0x0004; m_regmask[EREG_INTERRUPT] = 0x7f00;
+
+ m_reg[EREG_MT0_1] = 0x0000; m_regmask[EREG_MT0_1] = 0xffff;
+ m_reg[EREG_MT2_3] = 0x0000; m_regmask[EREG_MT2_3] = 0xffff;
+ m_reg[EREG_MT4_5] = 0x0000; m_regmask[EREG_MT4_5] = 0xffff;
+ m_reg[EREG_MT6_7] = 0x0000; m_regmask[EREG_MT6_7] = 0xffff;
+ m_reg[EREG_MGMT] = 0x3030; m_regmask[EREG_MGMT] = 0x0f0f;
+ // TODO: Revision should be set based on chip type
+ m_reg[EREG_REVISION] = 0x3345; m_regmask[EREG_REVISION] = 0x0000;
+ m_reg[EREG_ERCV] = 0x331f; m_regmask[EREG_ERCV] = 0x009f;
update_ethernet_irq();
+ m_tx_timer->reset();
+
+ // Setup real network if enabled
+ m_network_available = false;
+ if (netdev_count()) {
+ m_network_available = true;
+ osd_list_network_adapters();
+ unsigned char const *const mac = (const unsigned char *)get_mac();
+ if (VERBOSE & LOG_GENERAL)
+ {
+ logerror("MAC : ");
+ for (int i = 0; i < ETHERNET_ADDR_SIZE; i++)
+ logerror("%.2X", mac[i]);
+
+ logerror("\n");
+ }
+
+ set_promisc(true);
+ // Interface MAC
+ m_reg[EREG_IA0_1] = mac[0] | (mac[1] << 8);
+ m_reg[EREG_IA2_3] = mac[2] | (mac[3] << 8);
+ m_reg[EREG_IA4_5] = mac[4] | (mac[5] << 8);
+ }
// Reset MMU
mmu_reset();
@@ -186,36 +261,39 @@ void smc91c9x_device::mmu_reset()
m_alloc_rx = 0;
m_alloc_tx = 0;
- // Reset fifos.
- reset_tx_fifos();
- reset_completed_rx();
+ // Flush fifos.
+ clear_tx_fifo();
+ clear_rx_fifo();
update_ethernet_irq();
}
-void smc91c9x_device::reset_tx_fifos()
+DEFINE_DEVICE_TYPE(SMC91C94, smc91c94_device, "smc91c94", "SMC91C94 Ethernet Controller")
+
+smc91c94_device::smc91c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : smc91c9x_device(mconfig, SMC91C94, tag, owner, clock)
+{
+}
+
+DEFINE_DEVICE_TYPE(SMC91C96, smc91c96_device, "smc91c96", "SMC91C96 Ethernet Controller")
+
+smc91c96_device::smc91c96_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : smc91c9x_device(mconfig, SMC91C96, tag, owner, clock)
{
- // Disable transmit timer
- m_tx_poll->enable(false);
- // Reset transmit queue
- reset_queued_tx();
- // Reset completion FIFOs
- reset_completed_tx();
}
bool smc91c9x_device::alloc_req(const int tx, int &packet_num)
{
u32 curr_alloc = m_alloc_rx | m_alloc_tx;
- for (int index = 0; index < m_num_ebuf; index++)
- {
- if (!(curr_alloc & (1 << index)))
- {
+ for (int index = 0; index < ETHER_BUFFERS; index++) {
+ if (!(curr_alloc & (1 << index))) {
packet_num = index;
- if (tx)
+ if (tx) {
m_alloc_tx |= 1 << index;
- else
+ } else {
m_alloc_rx |= 1 << index;
+ }
return true;
}
}
@@ -226,8 +304,7 @@ bool smc91c9x_device::alloc_req(const int tx, int &packet_num)
void smc91c9x_device::alloc_release(const int packet_num)
{
int clear_mask = ~(1 << packet_num);
- if (!((m_alloc_tx | m_alloc_rx) & (1 << packet_num)))
- {
+ if (!((m_alloc_tx | m_alloc_rx) & (1 << packet_num))) {
logerror("alloc_release: Trying to release a non-allocated packet. packet_num: %02x alloc_tx: %04x alloc_rx: %04x\n",
packet_num, m_alloc_tx, m_alloc_rx);
}
@@ -235,448 +312,338 @@ void smc91c9x_device::alloc_release(const int packet_num)
m_alloc_rx &= clear_mask;
}
-/***************************************************************************
- INTERNAL HELPERS
-***************************************************************************/
-
-/*-------------------------------------------------
- update_ethernet_irq - update the IRQ state
--------------------------------------------------*/
-
-void smc91c9x_device::update_ethernet_irq()
+void smc91c9x_device::clear_tx_fifo()
{
- // Check tx completion fifo empty
- if (empty_completed_tx())
- m_reg[B2_INTERRUPT] &= ~EINT_TX;
- else
- m_reg[B2_INTERRUPT] |= EINT_TX;
+ // Clear transmit timer
+ m_tx_timer->reset();
+ // Reset transmit queue
+ m_trans_tx.clear();
+ // Reset completion FIFOs
+ m_comp_tx.clear();
+}
- // Check rx completion fifo empty
- if (empty_completed_rx())
- m_reg[B2_INTERRUPT] &= ~EINT_RCV;
- else
- m_reg[B2_INTERRUPT] |= EINT_RCV;
+void smc91c9x_device::clear_rx_fifo()
+{
+ // Clear recieve FIFO
+ m_comp_rx.clear();
+}
- uint8_t const mask = m_reg[B2_INTERRUPT] >> 8;
- uint8_t const state = m_reg[B2_INTERRUPT] & 0xff;
+int smc91c9x_device::is_broadcast(const uint8_t *mac_address)
+{
+ int i;
+ i = 0;
- /* update the IRQ state */
- uint8_t new_state = mask & state;
- if (m_irq_state ^ new_state)
+ while(mac_address[i] == 0xFF)
{
- LOG("update_ethernet_irq: old: %02x new: %02x\n", m_irq_state, new_state);
- m_irq_state = new_state;
- m_irq_handler(m_irq_state ? ASSERT_LINE : CLEAR_LINE);
+ i++;
}
-}
+ if ( i == 6 )
+ return 1;
-/*-------------------------------------------------
- update_stats - draw statistics
--------------------------------------------------*/
-
-void smc91c9x_device::update_stats()
-{
- if ( DISPLAY_STATS )
- popmessage("Sent:%d Rec'd:%d", m_sent, m_recd);
+ return 0;
}
-/*-------------------------------------------------
-dump_bytes - Print packet bytes
--------------------------------------------------*/
-void smc91c9x_device::dump_bytes(u8 *buf, int length)
+int smc91c9x_device::ethernet_packet_is_for_me(const uint8_t *mac_address)
{
- if (VERBOSE & LOG_PACKETS)
- {
- std::stringstream ss_bytes;
- ss_bytes << std::hex << std::setfill('0');
- for (int i = 0; i < length; i++)
- {
- ss_bytes << std::setw(2) << (int) buf[i];
- // Send newline every 16 bytes and at the end
- if ((i & 0xf) == 0xf || i == length - 1)
- {
- LOGMASKED(LOG_PACKETS, "%s\n", ss_bytes.str());
- ss_bytes.str("");
- }
- else
- ss_bytes << " ";
- }
- }
-}
+ // tcpdump -i eth0 -q ether host 08:00:1e:01:ae:a5 or ether broadcast or ether dst 09:00:1e:00:00:00 or ether dst 09:00:1e:00:00:01
+ // wireshark filter: eth.addr eq 08:00:1e:01:ae:a5 or eth.dst eq ff:ff:ff:ff:ff:ff or eth.dst eq 09:00:1e:00:00:00 or eth.dst eq 09:00:1e:00:00:01
-/*-------------------------------------------------
-address_filter - Filter the received packet
--------------------------------------------------*/
+ int i;
-int smc91c9x_device::address_filter(u8 *buf)
-{
- if (m_reg[B0_RCR] & PRMS)
- {
- // TODO: 91C94 doesn't receive it's own transmisson when not in full duplex
- LOGMASKED(LOG_FILTER, "address_filter accepted (promiscuous mode)\n");
- return ADDR_UNICAST;
- }
- else if (buf[0] & 1)
+ LOG("\n");
+
+ if (VERBOSE & LOG_GENERAL)
{
- // broadcast
- if (!memcmp(ETH_BROADCAST, buf, 6))
+ for ( i = 0 ; i < ETHERNET_ADDR_SIZE ; i++ )
{
- LOGMASKED(LOG_FILTER, "address_filter accepted (broadcast) %02x-%02x-%02x-%02x-%02x-%02x\n",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
-
- return ADDR_BROADCAST;
+ logerror("%.2X", ((u8 *)&m_reg[EREG_IA0_1])[i]);
}
-
- // multicast
- /*
- * Multicast address matching is performed by computing the fcs crc of
- * the destination address, and then using the upper 6 bits as an index
- * into the 64-bit logical address filter.
- */
- // Check for all multicast bit
- if (m_reg[B0_RCR] & ALMUL)
- return ADDR_MULTICAST;
-
- u32 const crc = util::crc32_creator::simple(buf, 6);
- // The hash is based on the top 6 MSBs of the CRC
- // The CRC needs to be inverted and reflected
- m_rx_hash = 0x0;
- for (int i = 0; i < 6; i++)
- m_rx_hash |= (((~crc) >> i) & 1) << (5 - i);
- u64 multicast_addr = *(u64*)&m_reg[B3_MT0_1];
- if (BIT(multicast_addr, m_rx_hash))
+ logerror("=");
+ for ( i = 0 ; i < ETHERNET_ADDR_SIZE ; i++ )
{
- LOGMASKED(LOG_FILTER, "address_filter accepted (multicast address match) %02x-%02x-%02x-%02x-%02x-%02x\n",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
-
- return ADDR_MULTICAST;
+ logerror("%.2X",mac_address[i]);
}
- LOGMASKED(LOG_FILTER, "address_filter rejected multicast %02x-%02x-%02x-%02x-%02x-%02x crc: %08x hash: %02x multi: %16ullx\n",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], crc, m_rx_hash, *(u64*)&m_reg[B3_MT0_1]);
+ logerror("?");
}
- else
- {
- // unicast
- if (!memcmp(&m_reg[B1_IA0_1], buf, 6))
- {
- LOGMASKED(LOG_FILTER, "address_filter accepted (physical address match)\n");
- return ADDR_UNICAST;
- }
+ // skip Ethernet broadcast packets if RECV_BROAD is not set
+ if (is_broadcast(mac_address))
+ {
+ LOG(" -- Broadcast rx\n");
+ return 2;
}
- return ADDR_NOMATCH;
-}
-/*-------------------------------------------------
-recv_start_cb - Start receiving packet
- A return value of 0 will stop rx processing in dinetwork device
- Any other value will be sent to the recv_complete_cb
--------------------------------------------------*/
-
-int smc91c9x_device::recv_start_cb(u8 *buf, int length)
-{
- // check internal loopback
- if (m_reg[B0_TCR] & (EPH_LOOP | LOOP))
+ if (memcmp(mac_address, &m_reg[EREG_IA0_1], ETHERNET_ADDR_SIZE) == 0)
{
- LOGMASKED(LOG_RX, "receive internal loopback mode, external packet discarded\n");
-
- return 0;
+ LOG(" -- Address Match\n");
+ return 1;
}
- // discard bad length packets
- if (length < 64 || length > 256*6 - 6)
- {
- LOGMASKED(LOG_RX, "received bad length packet length %d discarded\n", length);
+ LOG(" -- Not Matching\n");
- return 0;
- }
+ return 0;
+}
- // discard packets not from WMS
- if (memcmp(WMS_OUI, &buf[6], 3))
- {
- LOGMASKED(LOG_RX, "received non-WMS packet OUI: %02x:%02x:%02x length %d discarded\n", buf[6], buf[7], buf[8], length);
+/***************************************************************************
+ recv_cb - receive callback - receive and process an ethernet packet
+ ***************************************************************************/
- return 0;
- }
+void smc91c9x_device::recv_cb(uint8_t *data, int length)
+{
+ LOG("recv_cb : %d/0x%x\n",length,length);
- // Check for active transmission
- if (m_tx_active)
- {
- // TODO: Update collision counters
- LOGMASKED(LOG_RX, "transmit active COLLISION, rx packet length %d discarded\n", length);
+ int const isforme = ethernet_packet_is_for_me( data );
- return 0;
+ if (isforme==1 && (length >= ETHERNET_ADDR_SIZE) && (VERBOSE & LOG_GENERAL))
+ {
+ logerror("RX: ");
+ for (int i = 0; i < ETHERNET_ADDR_SIZE; i++)
+ logerror("%.2X", data[i]);
- }
+ logerror(" ");
- return receive(buf, length);
-}
+ for (int i = 0; i < length-ETHERNET_ADDR_SIZE; i++)
+ logerror("%.2X", data[ETHERNET_ADDR_SIZE + i]);
-/*-------------------------------------------------
-receive - Receive data into buffer
- Returns the buffer packet number + 1 if successful
--------------------------------------------------*/
+ logerror(" - IsForMe %d - %d/0x%x bytes\n", isforme, length, length);
+ }
-int smc91c9x_device::receive(u8 *buf, int length)
-{
- // check receiver enabled
- if (!(m_reg[B0_RCR] & RXEN))
+ if ( (length < ETHERNET_ADDR_SIZE || !isforme) && !(m_reg[EREG_RCR] & 0x0102) )
{
- LOGMASKED(LOG_RX, "receive disabled, external packet discarded\n");
+ LOG("\n");
- return -1;
+ // skip packet
+ return;
}
- // address filter
- int filter = address_filter(buf);
- if (filter == ADDR_NOMATCH)
- return -1;
-
- LOGMASKED(LOG_RX, "receive packet length %d\n", length);
- dump_bytes(buf, length);
+ /* signal a receive */
// Try to request a packet number
int packet_num;
- if (!alloc_req(0, packet_num))
- {
- logerror("recv_cb: Couldn't allocate memory for receive packet\n");
- return -2;
+ if (!alloc_req(0, packet_num)) {
+ logerror("recv_cb: Couldn't allocate a receive packet\n");
+ return;
}
- m_rx_active = 1;
+ /* compute the packet length */
- // build up the packet
- uint8_t *const packet = &m_buffer[packet_num * ETHER_BUFFER_SIZE];
+ if ( ( length < ( ETHER_BUFFER_SIZE - ( 2+2+2 ) ) ) )
+ {
+ uint8_t *const packet = &m_buffer[ packet_num * ETHER_BUFFER_SIZE];
- // Strip CRC
- if (m_reg[B0_RCR] & STRIP_CRC)
- length -= 4;
+ int dst = 0;
- // Copy received payload
- memcpy(&packet[4], buf, length);
+ // build up the packet
- // Status word
- u16 *rx_status = (u16*)&packet[0];
- *rx_status = 0x0000;
+ // Status word
+ packet[dst++] = 0x00;
- // set the broadcast flag
- if (filter == ADDR_BROADCAST)
- *rx_status |= BRODCAST;
+ // set the broadcast flag
+ if ( isforme == 2 )
+ packet[dst++] |= 0x40;
+ else
+ packet[dst++] = 0x00;
- // set the multicast flag and hash
- if (filter == ADDR_MULTICAST)
- {
- *rx_status |= (m_rx_hash << 1) | MULTCAST;
- }
+ //bytes count
+ packet[dst++] = 0x00;
+ packet[dst++] = 0x00;
- // Calculate buffer length and set control byte
- u16 buf_length;
+ memcpy(&packet[dst], data, length );
+ dst += length;
- if (length & 1)
- {
- // ODD Frame
- *rx_status |= ODDFRM;
- packet[length + 4] = EBUF_RX_ALWAYS | EBUF_ODD; // Control
- buf_length = length + 5;
- }
- else
- {
- packet[length + 4] = 0x00; // Pad
- packet[length + 5] = EBUF_RX_ALWAYS; // Control
- buf_length = length + 6;
- }
+ if ( dst & 1 )
+ {
+ // ODD Frame
+ packet[dst++] = 0x40 | 0x20; // Control
+ }
+ else
+ {
+ packet[dst++] = 0x00; // Pad
+ packet[dst++] = 0x40 | 0x00; // Control
+ }
- // Set buffer length word
- *(u16*)&packet[2] = buf_length;
+ //dst += 2;
- return packet_num + 1;
-}
+ dst &= 0x7FF;
-/*-------------------------------------------------
-recv_complete_cb - End of receive
--------------------------------------------------*/
+ packet[2] = (dst&0xFF);
+ packet[3] = (dst) >> 8;
-void smc91c9x_device::recv_complete_cb(int result)
-{
- if (result > 0)
- {
// Push packet number to rx completion fifo
- push_completed_rx(result - 1);
+ m_comp_rx.push_back(packet_num);
}
- // Couldn't allocate memory
- else if (result == -2)
+ else
{
- m_reg[B2_INTERRUPT] |= EINT_ALLOC;
+ LOG("Rejected ! Fifo Full ?");
}
update_ethernet_irq();
- m_rx_active = 0;
+ LOG("\n");
}
+/***************************************************************************
+ INTERNAL HELPERS
+***************************************************************************/
+
/*-------------------------------------------------
- tx_poll - Starts transmit
+ update_ethernet_irq - update the IRQ state
-------------------------------------------------*/
-TIMER_CALLBACK_MEMBER(smc91c9x_device::tx_poll)
+void smc91c9x_device::update_ethernet_irq()
{
- // Check for active RX and delay if necessary
- if (m_rx_active)
- {
- // TODO: Implement correct CSMA/CD algorithm
- m_tx_poll->adjust(attotime::from_usec(40));
- m_tx_retry_count++;
- LOGMASKED(LOG_TX, "tx_poll: Delaying TX due to active RX retry_count = %d\n", m_tx_retry_count);
- }
- // Check if TX is enabled and packet is queued
- else if ((m_reg[B0_TCR] & TXENA) && !empty_queued_tx())
- {
- // Reset retry count
- m_tx_retry_count = 0;
+ // Check tx completion fifo empty
+ if (m_comp_tx.empty())
+ m_reg[EREG_INTERRUPT] &= ~EINT_TX;
+ else
+ m_reg[EREG_INTERRUPT] |= EINT_TX;
- // Get the packet number from the transmit fifo
- const int packet_num = curr_queued_tx();
- uint8_t *const tx_buffer = &m_buffer[packet_num * ETHER_BUFFER_SIZE];
+ // Check rx completion fifo empty
+ if (m_comp_rx.empty())
+ m_reg[EREG_INTERRUPT] &= ~EINT_RCV;
+ else
+ m_reg[EREG_INTERRUPT] |= EINT_RCV;
- // Get the length and control fields from buffer
- u16 length = (*(u16*)&tx_buffer[2]) & 0x7ff;
- const u8 control = tx_buffer[length - 1];
+ uint8_t const mask = m_reg[EREG_INTERRUPT] >> 8;
+ uint8_t const state = m_reg[EREG_INTERRUPT] & 0xff;
- // Remove [pad], control
- if (control & EBUF_ODD)
- length -= 1;
- else
- length -= 2;
- // Add padding up to CRC area
- // take into account status & length removal (-4) and crc addtion (+4)
- while (length < 64 + 4 - 4 && (m_reg[B0_TCR] & PAD_EN))
- tx_buffer[length++] = 0x00;
+ /* update the IRQ state */
+ uint8_t new_state = mask & state;
+ if (m_irq_state ^ new_state)
+ {
+ LOG("update_ethernet_irq: old: %02x new: %02x\n", m_irq_state, new_state);
+ m_irq_state = new_state;
+ m_irq_handler(m_irq_state ? ASSERT_LINE : CLEAR_LINE);
+ }
+}
- // Add CRC
- // TODO: Calculate CRC
- if (1 && ((control & EBUF_CRC) || !(m_reg[B0_TCR] & NOCRC)))
- {
- tx_buffer[length++] = 0x11;
- tx_buffer[length++] = 0x22;
- tx_buffer[length++] = 0x33;
- tx_buffer[length++] = 0x44;
- }
- // Remove status, length
- length -= 4;
+/*-------------------------------------------------
+ update_stats - draw statistics
+-------------------------------------------------*/
- // Reset the EPH register */
- m_reg[B0_EPH_STATUS] &= LINK_OK;
+void smc91c9x_device::update_stats()
+{
+ if ( DISPLAY_STATS )
+ popmessage("Sent:%d Rec'd:%d", m_sent, m_recd);
+}
- // Send the frame
- m_tx_active = 1;
- m_tx_poll->enable(false);
- LOGMASKED(LOG_TX, "Start sending packet %d length = %d time: %s\n", packet_num, length, machine().scheduler().time().as_string());
- dump_bytes(&tx_buffer[4], length);
+/*-------------------------------------------------
+ send_frame - push a frame to the interface
+-------------------------------------------------*/
- // Write loopback data and save result
- if (m_reg[B0_TCR] & (EPH_LOOP | LOOP | FDUPLX))
- m_loopback_result = receive(&tx_buffer[4], length);
- else
- m_loopback_result = 0;
+TIMER_CALLBACK_MEMBER(smc91c9x_device::send_frame)
+{
+ // Get the packet number from the transmit fifo
+ const int packet_num = m_trans_tx.front();
+ uint8_t *const tx_buffer = &m_buffer[packet_num * ETHER_BUFFER_SIZE];
- // Local loopback isn't sent to cable
- //if ((m_reg[B0_TCR] & (EPH_LOOP | LOOP) || (get_interface() < 0 && (m_reg[B0_TCR] & FDUPLX))))
- if (m_reg[B0_TCR] & (EPH_LOOP | LOOP))
- send_complete_cb(length);
- else
- send(&tx_buffer[4], length);
+ // Pop the transmit fifo
+ m_trans_tx.erase(m_trans_tx.begin());
- }
-}
+ /* update the EPH register */
+ m_reg[EREG_EPH_STATUS] = 0x0001;
-/*-------------------------------------------------
-send_complete_cb - Called after transmit complete
--------------------------------------------------*/
+ if (is_broadcast(&tx_buffer[4]))
+ m_reg[EREG_EPH_STATUS] |= 0x0040;
+
+ // Check tx completion fifo empty
+ if (m_trans_tx.empty())
+ m_reg[EREG_INTERRUPT] |= EINT_TX_EMPTY;
-void smc91c9x_device::send_complete_cb(int result)
-{
m_sent++;
+
update_stats();
- // Pop the packet number from the transmit fifo
- const int packet_num = pop_queued_tx();
- uint8_t *const tx_buffer = &m_buffer[packet_num * ETHER_BUFFER_SIZE];
+ int buffer_len = ((tx_buffer[3] << 8) | tx_buffer[2]) & 0x7ff;
+ // Remove status, length, [pad], control
+ if (tx_buffer[buffer_len - 1] & 0x20)
+ buffer_len -= 5;
+ else
+ buffer_len -= 6;
+ // Add padding
+ if (buffer_len < 64 && (m_reg[EREG_TCR] & 0x0080)) {
+ while (buffer_len < 64)
+ tx_buffer[4 + buffer_len++] = 0x00;
+ }
+ if (VERBOSE & LOG_GENERAL)
+ {
+ logerror("TX: ");
+ for (int i = 0; i < ETHERNET_ADDR_SIZE; i++)
+ logerror("%.2X", tx_buffer[4 + i]);
- LOGMASKED(LOG_TX, "End sending packet %d result = %d time: %s\n", packet_num, result, machine().scheduler().time().as_string());
+ logerror(" ");
- /* update the EPH register */
- m_reg[B0_EPH_STATUS] |= TX_SUC;
+ for (int i = ETHERNET_ADDR_SIZE; i < buffer_len; i++)
+ logerror("%.2X", tx_buffer[4 + i]);
- // Set LINK_OK in status
- if (0 && !(m_reg[B0_EPH_STATUS] & LINK_OK))
- {
- m_reg[B0_EPH_STATUS] |= LINK_OK;
- // Set a ethernet phy status interrupt
- m_reg[B2_INTERRUPT] |= EINT_EPH;
+ logerror("--- %d/0x%x bytes\n", buffer_len, buffer_len);
}
- // Set Tx broadcast flag
- if (!memcmp(ETH_BROADCAST, &tx_buffer[4], 6))
- m_reg[B0_EPH_STATUS] |= LTX_BRD;
+ if (buffer_len > 4)
+ {
+ if (m_link_unconnected)
+ {
+ // Set lost carrier
+ if (m_reg[EREG_TCR] & 0x0400)
+ {
+ m_reg[EREG_EPH_STATUS] |= 0x400;
+ // Clear Tx Enable on error
+ m_reg[EREG_TCR] &= ~0x1;
+ }
- // Check tx queued fifo empty
- if (empty_queued_tx())
- m_reg[B2_INTERRUPT] |= EINT_TX_EMPTY;
+ // Set signal quality error
+ if (m_reg[EREG_TCR] & 0x1000)
+ {
+ m_reg[EREG_EPH_STATUS] |= 0x20;
+ // Clear Tx Enable on error
+ m_reg[EREG_TCR] &= ~0x1;
+ }
- // Set no-transmission flags
- if (m_link_unconnected)
- {
- //m_reg[B0_EPH_STATUS] &= ~LINK_OK;
- //m_reg[B0_EPH_STATUS] &= ~TX_SUC;
+ // Set a ethernet phy status interrupt
+ m_reg[EREG_INTERRUPT] |= EINT_EPH;
- // Set lost carrier
- if (m_reg[B0_TCR] & MON_CSN)
- {
- m_reg[B0_EPH_STATUS] |= LOST_CARR;
- // Clear Tx Enable on error
- m_reg[B0_TCR] &= ~TXENA;
+ // TODO: Is it necessary to clear FIFOs on error?
+ // Flush fifos.
+ //clear_tx_fifo();
+ //clear_rx_fifo();
}
-
- // Set signal quality error
- if (m_reg[B0_TCR] & STP_SQET)
+ else
{
- m_reg[B0_EPH_STATUS] |= SQET;
- // Clear Tx Enable on error
- m_reg[B0_TCR] &= ~TXENA;
- }
+ // Send the frame
+ if (!send(&tx_buffer[4], buffer_len))
+ {
+ // FIXME: failed to send the Ethernet packet
+ //logerror("failed to send Ethernet packet\n");
+ //LOG(this,("read_command_port(): !!! failed to send Ethernet packet"));
+ }
- // Set a ethernet phy status interrupt
- m_reg[B2_INTERRUPT] |= EINT_EPH;
+ // Loopback if loopback is set or fduplx is set
+ // TODO: Figure out correct size
+ // TODO: Check for addtional filter options for FDUPLX mode
+ if ((m_reg[EREG_TCR] & 0x2002) || (m_network_available && (m_reg[EREG_TCR] & 0x0800)))
+ recv_cb(&tx_buffer[4], buffer_len);
+ }
}
-
// Update status in the transmit word
- *(u16*)&tx_buffer[0] = m_reg[B0_EPH_STATUS];
+ tx_buffer[0] = m_reg[EREG_EPH_STATUS];
+ tx_buffer[1] = m_reg[EREG_EPH_STATUS] >> 8;
// Push the packet number onto the tx completion fifo
- push_completed_tx(packet_num);
+ m_comp_tx.push_back(packet_num);
update_ethernet_irq();
- // Loopback if loopback is set or fduplx is set
- if (m_loopback_result)
- {
- //int rx_result = receive(&tx_buffer[4], result);
- recv_complete_cb(m_loopback_result);
+ // If there is more packets to transmit then set the tx timer
+ if ((m_reg[EREG_TCR] & 0x1) && !m_trans_tx.empty()) {
+ // Shortest packet (64 bytes @ 10Mbps = 50us)
+ m_tx_timer->adjust(attotime::from_usec(50));
}
-
- // If there is more packets to transmit then start the tx polling
- if ((m_reg[B0_TCR] & TXENA) && !empty_queued_tx())
- {
- m_tx_poll->adjust(attotime::from_usec(10));
- }
-
- m_tx_active = 0;
}
/*-------------------------------------------------
@@ -695,48 +662,53 @@ void smc91c9x_device::process_command(uint16_t data)
LOG(" ALLOCATE MEMORY FOR TX (%d)", (data & 7));
{
int packet_num;
- if (alloc_req(1, packet_num))
- {
+ if (alloc_req(1, packet_num)) {
LOG(" packet_num = %02x\n", (packet_num));
// Set ARR register
- m_reg[B2_PNR_ARR] &= ~0xff00;
- m_reg[B2_PNR_ARR] |= packet_num << 8;
- m_reg[B2_INTERRUPT] |= EINT_ALLOC;
+ m_reg[EREG_PNR_ARR] &= ~0xff00;
+ m_reg[EREG_PNR_ARR] |= packet_num << 8;
+ m_reg[EREG_INTERRUPT] |= EINT_ALLOC;
update_ethernet_irq();
}
- else
- {
+ else {
logerror("ECMD_ALLOCATE: Couldn't allocate TX memory\n");
}
}
break;
case ECMD_RESET_MMU:
+ /*
+ 0100
+ - RESET MMU TO INITIAL STATE -
+ Frees all memory allocations, clears relevant
+ interrupts, resets packet FIFO pointers.
+ */
+
LOG(" RESET MMU\n");
mmu_reset();
break;
case ECMD_REMOVE_TOPFRAME_TX:
LOG(" REMOVE FRAME FROM TX FIFO\n");
- if (empty_completed_tx())
+ if (m_comp_tx.empty())
logerror("process_command: Trying to remove entry from empty tx completion fifo\n");
else
- pop_completed_tx();
+ m_comp_tx.erase(m_comp_tx.begin());
break;
case ECMD_REMOVE_RELEASE_TOPFRAME_RX:
- LOG(" REMOVE AND RELEASE FRAME FROM RX FIFO (PACK_NUM=%d)\n", curr_completed_rx());
+ LOG(" REMOVE AND RELEASE FRAME FROM RX FIFO (PACK_NUM=%d)\n", m_comp_rx.front());
// Release memory allocation
- alloc_release(curr_completed_rx());
+ alloc_release(m_comp_rx.front());
// Fall through
case ECMD_REMOVE_TOPFRAME_RX:
LOG(" REMOVE FRAME FROM RX FIFO\n");
// remove entry from rx completion queue
- if (empty_completed_rx())
+ if (m_comp_rx.empty())
logerror("process_command: Trying to remove entry from empty rx completion fifo\n");
else
- pop_completed_rx();
+ m_comp_rx.erase(m_comp_rx.begin());
update_ethernet_irq();
m_recd++;
@@ -745,7 +717,7 @@ void smc91c9x_device::process_command(uint16_t data)
case ECMD_RELEASE_PACKET:
{
- const int packet_number = m_reg[B2_PNR_ARR] & 0xff;
+ const int packet_number = m_reg[EREG_PNR_ARR] & 0xff;
alloc_release(packet_number);
LOG(" RELEASE SPECIFIC PACKET %d\n", packet_number);
}
@@ -754,31 +726,33 @@ void smc91c9x_device::process_command(uint16_t data)
case ECMD_ENQUEUE_PACKET:
LOG(" ENQUEUE TX PACKET ");
- if (m_reg[B0_TCR] & TXENA)
+ if (m_reg[EREG_TCR] & 0x0001) // TX EN ?
{
- const int packet_number = m_reg[B2_PNR_ARR] & 0xff;
+ const int packet_number = m_reg[EREG_PNR_ARR] & 0xff;
LOG("(PACKET_NUM=%d)\n", packet_number);
// Push packet number to tx transmit fifo
- push_queued_tx(packet_number);
- // Start timer to send frame if not already transmitting
- if (!m_tx_active && !m_tx_poll->enabled())
- {
- m_tx_poll->adjust(attotime::from_usec(10));
- LOG("Start polling time: %s\n", machine().scheduler().time().as_string());
- }
+ m_trans_tx.push_back(packet_number);
+ // Calculate transmit time
+ //uint8_t *const tx_buffer = &m_buffer[packet_number * ETHER_BUFFER_SIZE];
+ //int buffer_len = ((tx_buffer[3] << 8) | tx_buffer[2]) & 0x7ff;
+ //buffer_len -= 6;
+ //int usec = ((buffer_len * 8) / 10) + 1;
+ // Shortest packet (64 bytes @ 10Mbps = 50us)
+ m_tx_timer->adjust(attotime::from_usec(50));
}
break;
case ECMD_RESET_FIFOS:
LOG(" RESET TX FIFOS\n");
// Flush fifos.
- reset_tx_fifos();
+ clear_tx_fifo();
break;
}
// Set Busy (clear on next read)
- m_reg[B2_MMU_COMMAND] |= 0x0001;
-
+ m_reg[EREG_MMU_COMMAND] |= 0x0001;
+ //LOG("process_command: TxQ: %d TxComp: %d RxComp: %d TxAlloc: %04x RxAlloc: %04x\n",
+ // m_trans_tx.size(), m_comp_tx.size(), m_comp_rx.size(), m_alloc_tx, m_alloc_rx);
}
@@ -797,60 +771,60 @@ READ16_MEMBER( smc91c9x_device::read )
/* determine the effective register */
offset %= 8;
- if ( offset != B0_BANK )
- offset += 8 * (m_reg[B0_BANK] & 7);
+ if ( offset != EREG_BANK )
+ offset += 8 * (m_reg[EREG_BANK] & 7);
result = m_reg[offset];
switch (offset)
{
- case B2_MMU_COMMAND:
+ case EREG_MMU_COMMAND:
// Clear busy
- m_reg[B2_MMU_COMMAND] &= ~0x0001;
+ m_reg[EREG_MMU_COMMAND] &= ~0x0001;
break;
- case B2_PNR_ARR:
+ case EREG_PNR_ARR:
if ( ACCESSING_BITS_8_15 )
{
- m_reg[B2_INTERRUPT] &= ~EINT_ALLOC;
+ m_reg[EREG_INTERRUPT] &= ~EINT_ALLOC;
update_ethernet_irq();
}
break;
- case B2_FIFO_PORTS:
+ case EREG_FIFO_PORTS:
result = 0;
- if (!empty_completed_tx())
- result |= curr_completed_tx();
+ if (!m_comp_tx.empty())
+ result |= m_comp_tx.front();
else
result |= 0x80;
- if (!empty_completed_rx())
- result |= curr_completed_rx() << 8;
+ if (!m_comp_rx.empty())
+ result |= m_comp_rx.front() << 8;
else
result |= 0x80 << 8;
break;
- case B2_DATA_0: /* data register */
- case B2_DATA_1: /* data register */
+ case EREG_DATA_0: /* data register */
+ case EREG_DATA_1: /* data register */
{
uint8_t *buffer;
- int addr = m_reg[B2_POINTER] & 0x7ff;
+ int addr = m_reg[EREG_POINTER] & 0x7ff;
- if ( m_reg[B2_POINTER] & 0x8000 )
- buffer = &m_buffer[curr_completed_rx() * ETHER_BUFFER_SIZE];
+ if ( m_reg[EREG_POINTER] & 0x8000 )
+ buffer = &m_buffer[m_comp_rx.front() * ETHER_BUFFER_SIZE];
else
- buffer = &m_buffer[(m_reg[B2_PNR_ARR] & 0x1f) * ETHER_BUFFER_SIZE];;
+ buffer = &m_buffer[(m_reg[EREG_PNR_ARR] & 0x1f) * ETHER_BUFFER_SIZE];;
result = buffer[addr++];
if ( ACCESSING_BITS_8_15 )
result |= buffer[addr++] << 8;
- if ( m_reg[B2_POINTER] & 0x4000 )
- m_reg[B2_POINTER] = (m_reg[B2_POINTER] & ~0x7ff) | (addr & 0x7ff);
+ if ( m_reg[EREG_POINTER] & 0x4000 )
+ m_reg[EREG_POINTER] = (m_reg[EREG_POINTER] & ~0x7ff) | (addr & 0x7ff);
break;
}
}
- if (offset != B0_BANK)
+ if (offset != EREG_BANK)
LOG("%s:smc91c9x_r(%s) = %04X & %04X\n", machine().describe_context(), ethernet_regname[offset], result, mem_mask);
return result;
}
@@ -864,12 +838,12 @@ WRITE16_MEMBER( smc91c9x_device::write )
{
/* determine the effective register */
offset %= 8;
- if (offset != B0_BANK)
- offset += 8 * (m_reg[B0_BANK] & 7);
+ if (offset != EREG_BANK)
+ offset += 8 * (m_reg[EREG_BANK] & 7);
/* update the data generically */
- if (offset != B0_BANK && offset < sizeof(m_reg))
+ if (offset != EREG_BANK && offset < sizeof(m_reg))
LOG("%s:smc91c9x_w(%s) = [%04X]<-%04X & (%04X & %04X)\n", machine().describe_context(), ethernet_regname[offset], offset, data, mem_mask , m_regmask[offset]);
mem_mask &= m_regmask[offset];
@@ -878,62 +852,49 @@ WRITE16_MEMBER( smc91c9x_device::write )
/* handle it */
switch (offset)
{
- case B0_TCR: /* transmit control register */
+ case EREG_TCR: /* transmit control register */
// Setting Tx Enable clears some status and interrupts
- if ( data & TXENA )
- {
- if (m_reg[B0_EPH_STATUS] & (LOST_CARR | SQET | LATCOL | E16COL))
- {
- m_reg[B0_EPH_STATUS] &= ~(LOST_CARR | SQET | LATCOL | E16COL);
- m_reg[B2_INTERRUPT] &= ~EINT_EPH;
- update_ethernet_irq();
- }
- }
- if (VERBOSE & LOG_GENERAL)
- {
- if (data & FDSE) LOG(" FDSE\n");
- if (data & EPH_LOOP) LOG(" EPH LOOP\n");
- if (data & STP_SQET) LOG(" STP SQET\n");
- if (data & FDUPLX) LOG(" FDUPLX\n");
- if (data & MON_CSN) LOG(" MON_CSN\n");
- if (data & NOCRC) LOG(" NOCRC\n");
- if (data & PAD_EN) LOG(" PAD_EN\n");
- if (data & FORCOL) LOG(" FORCOL\n");
- if (data & LOOP) LOG(" LOOP\n");
- if (data & TXENA) LOG(" TXENA\n");
+ if ( data & 0x1 ) {
+ m_reg[EREG_EPH_STATUS] &= ~0x420;
+ m_reg[EREG_INTERRUPT] &= ~EINT_EPH;
+ update_ethernet_irq();
}
+
+ if (data & 0x2000) LOG(" EPH LOOP\n");
+ if (data & 0x1000) LOG(" STP SQET\n");
+ if (data & 0x0800) LOG(" FDUPLX\n");
+ if (data & 0x0400) LOG(" MON_CSN\n");
+ if (data & 0x0100) LOG(" NOCRC\n");
+ if (data & 0x0080) LOG(" PAD_EN\n");
+ if (data & 0x0004) LOG(" FORCOL\n");
+ if (data & 0x0002) LOG(" LOOP\n");
+ if (data & 0x0001) LOG(" TXENA\n");
break;
- case B0_RCR: /* receive control register */
+ case EREG_RCR: /* receive control register */
- if ( data & SOFT_RST)
+ if ( data & 0x8000 )
{
- reset();
+ clear_rx_fifo();
+ clear_tx_fifo();
}
- if ( !(data & RXEN) )
- {
- reset_completed_rx();
- }
- if (data & RXEN)
+ if ( !(data & 0x0100) )
{
- // Set LINK_OK in status
- m_reg[B0_EPH_STATUS] |= LINK_OK;
+ clear_rx_fifo();
}
- if (VERBOSE & LOG_GENERAL)
- {
- if (data & SOFT_RST) LOG(" SOFT RST\n");
- if (data & FILT_CAR) LOG(" FILT_CAR\n");
- if (data & STRIP_CRC) LOG(" STRIP CRC\n");
- if (data & RXEN) LOG(" RXEN\n");
- if (data & ALMUL) LOG(" ALMUL\n");
- if (data & PRMS) LOG(" PRMS\n");
- if (data & RX_ABORT) LOG(" RX_ABORT\n");
- }
+ if (data & 0x8000) reset();
+ if (data & 0x8000) LOG(" SOFT RST\n");
+ if (data & 0x4000) LOG(" FILT_CAR\n");
+ if (data & 0x0200) LOG(" STRIP CRC\n");
+ if (data & 0x0100) LOG(" RXEN\n");
+ if (data & 0x0004) LOG(" ALMUL\n");
+ if (data & 0x0002) LOG(" PRMS\n");
+ if (data & 0x0001) LOG(" RX_ABORT\n");
break;
- case B1_CONFIG: /* configuration register */
+ case EREG_CONFIG: /* configuration register */
if (data & 0x1000) LOG(" NO WAIT\n");
if (data & 0x0400) LOG(" FULL STEP\n");
if (data & 0x0200) LOG(" SET SQLCH\n");
@@ -944,86 +905,64 @@ WRITE16_MEMBER( smc91c9x_device::write )
if (data & 0x0002) LOG(" INT SEL0\n");
break;
- case B1_BASE: /* base address register */
+ case EREG_BASE: /* base address register */
LOG(" base = $%04X\n", (data & 0xe000) | ((data & 0x1f00) >> 3));
LOG(" romsize = %d\n", ((data & 0xc0) >> 6));
LOG(" romaddr = $%05X\n", ((data & 0x3e) << 13));
break;
- case B1_IA4_5:
- set_promisc(m_reg[B0_RCR] & PRMS);
- set_mac((char *)&m_reg[B1_IA0_1]);
-
- break;
-
- case B1_CONTROL: /* control register */
- // Clearing LE_EN clears interrupt from LINK_OK status change
- if (!(data & LE_ENABLE))
- {
- m_reg[B2_INTERRUPT] &= ~EINT_EPH;
- update_ethernet_irq();
- }
- if (0 && (data & LE_ENABLE))
- {
- if (m_reg[B0_EPH_STATUS] & LINK_OK)
- {
- m_reg[B0_EPH_STATUS] &= ~(LINK_OK);
- m_reg[B2_INTERRUPT] &= ~EINT_EPH;
- update_ethernet_irq();
- }
- }
- if (VERBOSE & LOG_GENERAL)
- {
- if (data & RCV_BAD) LOG(" RCV_BAD\n");
- if (data & PWRDN) LOG(" PWRDN\n");
- if (data & WAKEUP_EN) LOG(" WAKEUP ENABLE\n");
- if (data & AUTO_RELEASE) LOG(" AUTO RELEASE\n");
- if (data & LE_ENABLE) LOG(" LE ENABLE\n");
- if (data & CR_ENABLE) LOG(" CR ENABLE\n");
- if (data & TE_ENABLE) LOG(" TE ENABLE\n");
- if (data & EEPROM_SEL) LOG(" EEPROM SELECT\n");
- if (data & RELOAD) LOG(" RELOAD\n");
- if (data & STORE) LOG(" STORE\n");
- }
+ case EREG_CONTROL: /* control register */
+ if (data & 0x4000) LOG(" RCV_BAD\n");
+ if (data & 0x2000) LOG(" PWRDN\n");
+ if (data & 0x0800) LOG(" AUTO RELEASE\n");
+ if (data & 0x0080) LOG(" LE ENABLE\n");
+ if (data & 0x0040) LOG(" CR ENABLE\n");
+ if (data & 0x0020) LOG(" TE ENABLE\n");
+ if (data & 0x0004) LOG(" EEPROM SELECT\n");
+ if (data & 0x0002) LOG(" RELOAD\n");
+ if (data & 0x0001) LOG(" STORE\n");
break;
- case B2_MMU_COMMAND: /* command register */
+ case EREG_MMU_COMMAND: /* command register */
process_command(data);
break;
- case B2_DATA_0: /* data register */
- case B2_DATA_1: /* data register */
+ case EREG_DATA_0: /* data register */
+ case EREG_DATA_1: /* data register */
{
uint8_t *buffer;
- int addr = m_reg[B2_POINTER] & PTR;
+ int addr = m_reg[EREG_POINTER] & 0x7ff;
- if (m_reg[B2_POINTER] & RCV)
- buffer = &m_buffer[curr_completed_rx() * ETHER_BUFFER_SIZE];
+ if (m_reg[EREG_POINTER] & 0x8000)
+ buffer = &m_buffer[m_comp_rx.front() * ETHER_BUFFER_SIZE];
else
- buffer = &m_buffer[(m_reg[B2_PNR_ARR] & 0x1f) * ETHER_BUFFER_SIZE];;
+ buffer = &m_buffer[(m_reg[EREG_PNR_ARR] & 0x1f) * ETHER_BUFFER_SIZE];;
+ // TODO: Should be checking if incr is set
buffer[addr++] = data;
if ( ACCESSING_BITS_8_15 )
buffer[addr++] = data >> 8;
- if ( m_reg[B2_POINTER] & AUTO_INCR)
- m_reg[B2_POINTER] = (m_reg[B2_POINTER] & ~PTR) | (addr & PTR);
+ if ( m_reg[EREG_POINTER] & 0x4000 )
+ m_reg[EREG_POINTER] = (m_reg[EREG_POINTER] & ~0x7ff) | (addr & 0x7ff);
break;
}
- case B2_INTERRUPT:
+ case EREG_INTERRUPT:
// Pop tx fifo packet from completion fifo if clear tx int is set
- if (m_reg[B2_INTERRUPT] & data & EINT_TX)
- {
- if (empty_completed_tx())
+ if (m_reg[EREG_INTERRUPT] & data & EINT_TX) {
+ if (m_comp_tx.empty()) {
logerror("write: Trying to remove an entry from empty tx completion fifo\n");
- else
- {
- LOG("Removing tx completion packet_num = %d\n", curr_completed_tx());
- pop_completed_tx();
}
+ else {
+ LOG("Removing tx completion packet_num = %d\n", m_comp_tx.front());
+ m_comp_tx.erase(m_comp_tx.begin());
+ }
+ }
+ // Clear TX_EMPTY interrupt if clear tx empty bit is set
+ if (m_reg[EREG_INTERRUPT] & data & EINT_TX_EMPTY) {
+ m_reg[EREG_INTERRUPT] &= ~EINT_TX_EMPTY;
}
- // Clear interrupts
- m_reg[B2_INTERRUPT] &= ~(data & (EINT_ERCV | EINT_RX_OVRN | EINT_TX_EMPTY | EINT_TX));
+ m_reg[EREG_INTERRUPT] &= ~(data & 0x56);
update_ethernet_irq();
break;
}
diff --git a/src/devices/machine/smc91c9x.h b/src/devices/machine/smc91c9x.h
index b84f6070ef7..79fb52fcd0d 100644
--- a/src/devices/machine/smc91c9x.h
+++ b/src/devices/machine/smc91c9x.h
@@ -4,15 +4,13 @@
SMC91C9X ethernet controller implementation
- by Aaron Giles, Ted Green
+ by Aaron Giles, Jean-François DEL NERO
**************************************************************************/
#ifndef MAME_MACHINE_SMC91C9X_H
#define MAME_MACHINE_SMC91C9X_H
-#pragma once
-
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@@ -24,206 +22,39 @@ public:
DECLARE_READ16_MEMBER( read );
DECLARE_WRITE16_MEMBER( write );
+ TIMER_CALLBACK_MEMBER(send_frame);
+ virtual void recv_cb(uint8_t *data, int length) override;
void set_link_connected(bool connected) { m_link_unconnected = !connected; };
protected:
- enum class dev_type {
- SMC91C94,
- SMC91C96
- };
-
- smc91c9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, dev_type device_type);
+ smc91c9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
- // device_network_interface overrides
- virtual void send_complete_cb(int result) override;
- virtual int recv_start_cb(u8 *buf, int length) override;
- virtual void recv_complete_cb(int result) override;
-
- void dump_bytes(u8 *buf, int length);
- int address_filter(u8 *buf);
- int receive(u8 *buf, int length);
-
- TIMER_CALLBACK_MEMBER(tx_poll);
-
- const dev_type m_device_type;
- unsigned m_num_ebuf;
+ virtual void device_pre_save(void) override;
+ virtual void device_post_load(void) override;
private:
- // Ethernet registers - bank 0
- enum bank0_addr : u8 {
- B0_TCR = (0 * 8 + 0),
- B0_EPH_STATUS = (0 * 8 + 1),
- B0_RCR = (0 * 8 + 2),
- B0_COUNTER = (0 * 8 + 3),
- B0_MIR = (0 * 8 + 4),
- B0_MCR = (0 * 8 + 5),
- B0_BANK = (0 * 8 + 7)
- };
-
- // Ethernet registers - bank 1
- enum bank1_addr : u8 {
- B1_CONFIG = (1 * 8 + 0),
- B1_BASE = (1 * 8 + 1),
- B1_IA0_1 = (1 * 8 + 2),
- B1_IA2_3 = (1 * 8 + 3),
- B1_IA4_5 = (1 * 8 + 4),
- B1_GENERAL_PURP = (1 * 8 + 5),
- B1_CONTROL = (1 * 8 + 6)
- };
-
- // Ethernet registers - bank 2
- enum bank2_addr : u8 {
- B2_MMU_COMMAND = (2 * 8 + 0),
- B2_PNR_ARR = (2 * 8 + 1),
- B2_FIFO_PORTS = (2 * 8 + 2),
- B2_POINTER = (2 * 8 + 3),
- B2_DATA_0 = (2 * 8 + 4),
- B2_DATA_1 = (2 * 8 + 5),
- B2_INTERRUPT = (2 * 8 + 6)
- };
-
- // Ethernet registers - bank 3
- enum bank3_addr : u8 {
- B3_MT0_1 = (3 * 8 + 0),
- B3_MT2_3 = (3 * 8 + 1),
- B3_MT4_5 = (3 * 8 + 2),
- B3_MT6_7 = (3 * 8 + 3),
- B3_MGMT = (3 * 8 + 4),
- B3_REVISION = (3 * 8 + 5),
- B3_ERCV = (3 * 8 + 6)
- };
-
- // Ethernet MMU commands
- enum mmu_cmd : u8 {
- ECMD_NOP = 0,
- ECMD_ALLOCATE = 2,
- ECMD_RESET_MMU = 4,
- ECMD_REMOVE_TOPFRAME_RX = 6,
- ECMD_REMOVE_TOPFRAME_TX = 7,
- ECMD_REMOVE_RELEASE_TOPFRAME_RX = 8,
- ECMD_RELEASE_PACKET = 10,
- ECMD_ENQUEUE_PACKET = 12,
- ECMD_RESET_FIFOS = 14
- };
-
- // Ethernet interrupt bits
- enum eint_def : u8 {
- EINT_RCV = 0x01,
- EINT_TX = 0x02,
- EINT_TX_EMPTY = 0x04,
- EINT_ALLOC = 0x08,
- EINT_RX_OVRN = 0x10,
- EINT_EPH = 0x20,
- EINT_ERCV = 0x40, // 91c92 only
- EINT_TX_IDLE = 0x80 // 91c94 only
- };
-
- // Address filter return codes
- enum addr_filter_def : int {
- ADDR_NOMATCH = 0,
- ADDR_UNICAST = 1,
- ADDR_BROADCAST = 2,
- ADDR_MULTICAST = 3
- };
-
- // Rx/Tx control bits
- enum control_mask : u8 {
- EBUF_RX_ALWAYS = 0x40, // Always set on receive buffer control byte
- EBUF_ODD = 0x20, // Odd number of data payload bytes
- EBUF_CRC = 0x10 // Tx add CRC
- };
-
- // Receive buffer status
- enum rx_status_mask : u16 {
- ALGNERR = 0x8000,
- BRODCAST = 0x4000,
- BADCRC = 0x2000,
- ODDFRM = 0x1000,
- TOOLNG = 0x0800, // Received fram is longer than 1518 bytes on cable
- TOOSHORT = 0x0400, // Received fram is shorter than 64 bytes on cable
- HASHVALUE = 0x007e,
- MULTCAST = 0x0001
- };
-
- // EPH Status bits
- enum eph_mask : u16 {
- LINK_OK = 0x4000, // State of link integrity test
- CTR_ROL = 0x1000, // Counter roll Over
- EXC_DEF = 0x0800, // Excessive deferral
- LOST_CARR = 0x0400, // Lost carrier sense
- LATCOL = 0x0200, // Late collisions detected
- WAKEUP = 0x0100, // Magic packet received
- TX_DEFER = 0x0080, // Transmit deferred
- LTX_BRD = 0x0040, // Last transmit frame was a broadcast
- SQET = 0x0020, // Signal Quality Error Test
- E16COL = 0x0010, // 16 collisions reached
- LTX_MULT = 0x0008, // Last transmit frame was a multicast
- MULCOL = 0x0004, // Multiple collisions detected
- SNGLCOL = 0x0002, // Single collision detected
- TX_SUC = 0x0001 // Last transmit frame was successful
- };
-
- // CTR register bits
- enum ctr_mask : u16 {
- RCV_BAD = 0x4000, // Receive bad CRC packets
- PWRDN = 0x2000, // Power down ethernet
- WAKEUP_EN = 0x1000, // Enable magic packet wakeup
- AUTO_RELEASE = 0x0800, // Release transmit packets on good transmission
- LE_ENABLE = 0x0080, // Link Error enable
- CR_ENABLE = 0x0040, // Counter Roll over enable
- TE_ENABLE = 0x0020, // Transmit Error enable
- EEPROM_SEL = 0x0004, // EEPROM address
- RELOAD = 0x0002, // Reload config from EEPROM
- STORE = 0x0001 // Store config to EEPROM
- };
-
- // Transmit Control Register bits
- enum tcr_mask : u16 {
- FDSE = 0x8000,
- EPH_LOOP = 0x2000,
- STP_SQET = 0x1000,
- FDUPLX = 0x0800,
- MON_CSN = 0x0400,
- NOCRC = 0x0100,
- PAD_EN = 0x0080,
- FORCOL = 0x0004,
- LOOP = 0x0002,
- TXENA = 0x0001
- };
-
- // Receive Control Register bits
- enum rcr_mask : u16 {
- SOFT_RST = 0x8000,
- FILT_CAR = 0x4000,
- STRIP_CRC = 0x0200,
- RXEN = 0x0100,
- ALMUL = 0x0004,
- PRMS = 0x0002,
- RX_ABORT = 0x0001
- };
-
- // Pointer Register bits
- enum pointer_mask : u16 {
- RCV = 0x8000,
- AUTO_INCR = 0x4000,
- READ = 0x2000,
- PTR = 0x07ff
- };
-
- static constexpr unsigned ETHER_BUFFER_SIZE = 256 * 6;
- static const u8 ETH_BROADCAST[];
- static const u8 WMS_OUI[];
+ static constexpr unsigned ETHER_BUFFER_SIZE = 2048;
+ // TODO: 96 device is larger
+ static constexpr unsigned ETHER_BUFFERS = 16;
+ static constexpr unsigned ETHERNET_ADDR_SIZE = 6;
- // mmu
+ // external network is present
+ bool m_network_available;
+ // mmu
// The bits in these vectors indicate a packet has been allocated
u32 m_alloc_rx, m_alloc_tx;
-
+ std::vector<u32> m_comp_tx, m_comp_rx;
+ // Fifo for allocated (queued) transmit packets
+ std::vector<u32> m_trans_tx;
+ // Save vector data and sizes for proper save state restoration
+ u32 m_comp_tx_data[ETHER_BUFFERS], m_comp_rx_data[ETHER_BUFFERS], m_trans_tx_data[ETHER_BUFFERS];
+ u32 m_comp_tx_size, m_comp_rx_size, m_trans_tx_size;
// Requests a packet allocation and returns true
// and sets the packet number if successful
bool alloc_req(const int tx, int &packet_num);
@@ -246,56 +77,23 @@ private:
uint8_t m_irq_state;
// Main memory
- std::unique_ptr<u8[]> m_buffer;
+ uint8_t m_buffer[ETHER_BUFFER_SIZE * ETHER_BUFFERS];
/* counters */
uint32_t m_sent;
uint32_t m_recd;
- emu_timer* m_tx_poll;
+ emu_timer* m_tx_timer;
- int m_tx_active;
- int m_rx_active;
- int m_tx_retry_count;
- u8 m_rx_hash;
- u8 m_loopback_result;
+ int ethernet_packet_is_for_me(const uint8_t *mac_address);
+ int is_broadcast(const uint8_t *mac_address);
void update_ethernet_irq();
void update_stats();
void process_command(uint16_t data);
- void reset_tx_fifos();
-
- // TODO: Make circular fifo a separate device
- // Simple circular FIFO, power of 2 size, no over/under run checking
- static constexpr unsigned FIFO_SIZE = 1 << 5;
-
- // FIFO for allocated (queued) transmit packets
- u8 m_queued_tx[FIFO_SIZE];
- int m_queued_tx_h, m_queued_tx_t;
- void reset_queued_tx() { m_queued_tx_t = m_queued_tx_h = 0; };
- void push_queued_tx(const u8 &data) { m_queued_tx[m_queued_tx_h++] = data; m_queued_tx_h &= FIFO_SIZE - 1; };
- u8 pop_queued_tx() { u8 val = m_queued_tx[m_queued_tx_t++]; m_queued_tx_t &= FIFO_SIZE - 1; return val; };
- bool empty_queued_tx() const { return m_queued_tx_h == m_queued_tx_t; };
- u8 curr_queued_tx() const { return m_queued_tx[m_queued_tx_t]; };
-
- // FIFO for completed transmit packets
- u8 m_completed_tx[FIFO_SIZE];
- int m_completed_tx_h, m_completed_tx_t;
- void reset_completed_tx() { m_completed_tx_t = m_completed_tx_h = 0; };
- void push_completed_tx(const u8 &data) { m_completed_tx[m_completed_tx_h++] = data; m_completed_tx_h &= FIFO_SIZE - 1; };
- u8 pop_completed_tx() { u8 val = m_completed_tx[m_completed_tx_t++]; m_completed_tx_t &= FIFO_SIZE - 1; return val; };
- bool empty_completed_tx() const { return m_completed_tx_h == m_completed_tx_t; };
- u8 curr_completed_tx() const { return m_completed_tx[m_completed_tx_t]; };
-
- // FIFO for completed receive packets
- u8 m_completed_rx[FIFO_SIZE];
- int m_completed_rx_h, m_completed_rx_t;
- void reset_completed_rx() { m_completed_rx_t = m_completed_rx_h = 0; };
- void push_completed_rx(const u8 &data) { m_completed_rx[m_completed_rx_h++] = data; m_completed_rx_h &= FIFO_SIZE - 1; };
- u8 pop_completed_rx() { u8 val = m_completed_rx[m_completed_rx_t++]; m_completed_rx_t &= FIFO_SIZE - 1; return val; };
- bool empty_completed_rx() const { return m_completed_rx_h == m_completed_rx_t; };
- u8 curr_completed_rx() const { return m_completed_rx[m_completed_rx_t]; };
+ void clear_tx_fifo();
+ void clear_rx_fifo();
};
diff --git a/src/devices/machine/smpc.cpp b/src/devices/machine/smpc.cpp
index c62e65e1703..042fc06d590 100644
--- a/src/devices/machine/smpc.cpp
+++ b/src/devices/machine/smpc.cpp
@@ -205,7 +205,7 @@ void smpc_hle_device::smpc_regs(address_map &map)
smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, SMPC_HLE, tag, owner, clock),
device_memory_interface(mconfig, *this),
- m_space_config("regs", ENDIANNESS_LITTLE, 8, 7, 0, address_map_constructor(FUNC(smpc_hle_device::smpc_regs), this)),
+ m_space_config("regs", ENDIANNESS_LITTLE, 8, 7, 0, address_map_constructor(), address_map_constructor(FUNC(smpc_hle_device::smpc_regs), this)),
m_mini_nvram(*this, "smem"),
m_mshres(*this),
m_mshnmi(*this),
diff --git a/src/devices/machine/sonydriv.h b/src/devices/machine/sonydriv.h
index 322db3f3342..b6e4358eadb 100644
--- a/src/devices/machine/sonydriv.h
+++ b/src/devices/machine/sonydriv.h
@@ -58,4 +58,22 @@ protected:
// device type definition
DECLARE_DEVICE_TYPE(FLOPPY_SONY, sonydriv_floppy_image_device)
+#define MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(_config) \
+ MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY_SONY, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY_SONY, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config)
+
+#define MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADDITIONAL_ADD(_config) \
+ MCFG_DEVICE_ADD(FLOPPY_2, FLOPPY_SONY, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_DEVICE_ADD(FLOPPY_3, FLOPPY_SONY, 0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config)
+
+#define MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_MODIFY(_config) \
+ MCFG_DEVICE_MODIFY(FLOPPY_0) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config) \
+ MCFG_DEVICE_MODIFY(FLOPPY_1) \
+ MCFG_LEGACY_FLOPPY_CONFIG(_config)
+
#endif // MAME_MACHINE_SONYDRIV_H
diff --git a/src/devices/machine/spg110.cpp b/src/devices/machine/spg110.cpp
deleted file mode 100644
index 9f9256f4b27..00000000000
--- a/src/devices/machine/spg110.cpp
+++ /dev/null
@@ -1,669 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Haywood
-/*****************************************************************************
-
- SunPlus SPG110-series SoC peripheral emulation
-
- 0032xx looks like it could be the same as 003dxx on spg2xx
- but the video seems to have differences, and data
- is fetched from private buffers filled by DMA instead of
- main space? tile attributes different? palette format different
-
-**********************************************************************/
-
-#include "emu.h"
-#include "spg110.h"
-
-DEFINE_DEVICE_TYPE(SPG110, spg110_device, "spg110", "SPG110 System-on-a-Chip")
-
-spg110_device::spg110_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_memory_interface(mconfig, *this)
- , m_space_config("spg110", ENDIANNESS_BIG, 16, 32, 0, address_map_constructor(FUNC(spg110_device::map_video), this))
- , m_cpu(*this, finder_base::DUMMY_TAG)
- , m_screen(*this, finder_base::DUMMY_TAG)
- , m_palette(*this, "palette")
- , m_gfxdecode(*this, "gfxdecode")
- , m_palram(*this, "palram")
- , m_spg_io(*this, "spg_io")
- , m_porta_out(*this)
- , m_portb_out(*this)
- , m_portc_out(*this)
- , m_porta_in(*this)
- , m_portb_in(*this)
- , m_portc_in(*this)
- , m_adc_in{{*this}, {*this}}
- , m_chip_sel(*this)
-{
-}
-
-template<spg110_device::flipx_t FlipX>
-void spg110_device::blit(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t attr, uint32_t ctrl, uint32_t bitmap_addr, uint16_t tile)
-{
- address_space &space = m_cpu->space(AS_PROGRAM);
-
- int32_t h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
- int32_t w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
-
- uint32_t yflipmask = attr & TILE_Y_FLIP ? h - 1 : 0;
-
- uint32_t nc = ((attr & 0x0003) + 1) << 1;
-
- uint32_t palette_offset = (attr & 0x0f00) >> 4;
-
- palette_offset >>= nc;
- palette_offset <<= nc;
-
- uint32_t bits_per_row = nc * w / 16;
- uint32_t words_per_tile = bits_per_row * h;
- uint32_t m = bitmap_addr + words_per_tile * tile + bits_per_row * (line ^ yflipmask);
- uint32_t bits = 0;
- uint32_t nbits = 0;
- uint32_t y = line;
-
- int yy = (yoff + y) & 0x1ff;
- if (yy >= 0x01c0)
- yy -= 0x0200;
-
- if (yy > 240 || yy < 0)
- return;
-
- int y_index = yy * 320;
-
- for (int32_t x = FlipX ? (w - 1) : 0; FlipX ? x >= 0 : x < w; FlipX ? x-- : x++)
- {
- int xx = xoff + x;
-
- bits <<= nc;
-
- if (nbits < nc)
- {
- uint16_t b = space.read_word(m++ & 0x3fffff);
- //b = (b << 8) | (b >> 8);
- bits |= b << (nc - nbits);
- nbits += 16;
- }
- nbits -= nc;
-
- uint32_t pal = palette_offset + (bits >> 16);
- bits &= 0xffff;
-
- xx &= 0x01ff;
- if (xx >= 0x01c0)
- xx -= 0x0200;
-
- if (xx >= 0 && xx < 320)
- {
- // TODO, this is completely wrong for this palette system
- int pix_index = xx + y_index;
- uint16_t rawpal = m_palram[pal];
- const pen_t *pens = m_palette->pens();
- uint32_t paldata = pens[pal];
-
- if (!(rawpal & 0x8000))
- {
- m_screenbuf[pix_index] = paldata;
- }
- }
- }
-}
-
-void spg110_device::blit_page(const rectangle &cliprect, uint32_t scanline, int depth, uint32_t bitmap_addr, uint16_t *regs)
-{
- uint32_t xscroll = regs[0];
- uint32_t yscroll = regs[1];
- uint32_t attr = regs[2];
- uint32_t ctrl = regs[3];
- uint32_t tilemap = regs[4];
- uint32_t palette_map = regs[5];
- address_space &space2 = this->space(0);
-
- if (!(ctrl & PAGE_ENABLE_MASK))
- {
- return;
- }
-
- if (((attr & PAGE_DEPTH_FLAG_MASK) >> PAGE_DEPTH_FLAG_SHIFT) != depth)
- {
- return;
- }
-
- uint32_t tile_h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
- uint32_t tile_w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
-
- uint32_t tile_count_x = 512 / tile_w;
-
- uint32_t bitmap_y = (scanline + yscroll) & 0xff;
- uint32_t y0 = bitmap_y / tile_h;
- uint32_t tile_scanline = bitmap_y % tile_h;
- uint32_t tile_address = tile_count_x * y0;
-
- for (uint32_t x0 = 0; x0 < tile_count_x; x0++, tile_address++)
- {
- uint32_t yy = ((tile_h * y0 - yscroll + 0x10) & 0xff) - 0x10;
- uint32_t xx = (tile_w * x0 - xscroll) & 0x1ff;
- uint16_t tile = (ctrl & PAGE_WALLPAPER_MASK) ? space2.read_word(tilemap*2) : space2.read_word((tilemap + tile_address)*2);
- uint16_t palette = 0;
-
- if (!tile)
- continue;
-
- palette = space2.read_word(palette_map + tile_address / 2);
- if (x0 & 1)
- palette = (palette & 0xff00) >> 8;
- else
- palette = (palette & 0x00ff);
-
-
- bool flip_x = 0;//(tileattr & TILE_X_FLIP);
-
- if (flip_x)
- blit<FlipXOn>(cliprect, tile_scanline, xx, yy, attr, ctrl, bitmap_addr, tile);
- else
- blit<FlipXOff>(cliprect, tile_scanline, xx, yy, attr, ctrl, bitmap_addr, tile);
-
- }
-}
-
-
-/* correct, 4bpp gfxs */
-static const gfx_layout charlayout =
-{
- 8,8,
- RGN_FRAC(1,1),
- 4,
- { STEP4(0,1) },
- { 0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4 },
- { STEP8(0,4*8) },
- 8*8*4
-};
-
-static const gfx_layout charlayout6 =
-{
- 8,8,
- RGN_FRAC(1,1),
- 6,
- { 0,1,2,3,4,5 },
- { STEP8(0,6) },
- { STEP8(0,6*8) },
- 8*8*6
-};
-
-static const gfx_layout char16layout =
-{
- 16,16,
- RGN_FRAC(1,1),
- 4,
- { STEP4(0,1) },
- { 0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4, 8*4,9*4,10*4,11*4,12*4,13*4,14*4,15*4 },
- { STEP16(0,4*16) },
- 16*16*4
-};
-
-static const gfx_layout char32layout =
-{
- 32,32,
- RGN_FRAC(1,1),
- 4,
- { STEP4(0,1) },
- { STEP32(0,4) },
- { STEP32(0,4*32) },
- 32*32*4
-};
-
-
-
-static GFXDECODE_START( gfx )
- GFXDECODE_ENTRY( ":maincpu", 0, charlayout, 0, 16 )
- GFXDECODE_ENTRY( ":maincpu", 0, char16layout, 0, 16 )
- GFXDECODE_ENTRY( ":maincpu", 0, char32layout, 0, 16 )
- GFXDECODE_ENTRY( ":maincpu", 0, charlayout6, 0, 16 ) // correct for lots of the tiles inc. startup text
-GFXDECODE_END
-
-void spg110_device::configure_spg_io(spg2xx_io_device* io)
-{
- io->porta_in().set(FUNC(spg110_device::porta_r));
- io->portb_in().set(FUNC(spg110_device::portb_r));
- io->portc_in().set(FUNC(spg110_device::portc_r));
- io->porta_out().set(FUNC(spg110_device::porta_w));
- io->portb_out().set(FUNC(spg110_device::portb_w));
- io->portc_out().set(FUNC(spg110_device::portc_w));
- io->adc_in<0>().set(FUNC(spg110_device::adc_r<0>));
- io->adc_in<1>().set(FUNC(spg110_device::adc_r<1>));
- io->chip_select().set(FUNC(spg110_device::cs_w));
-// io->pal_read_callback().set(FUNC(spg110_device::get_pal_r));
-// io->write_timer_irq_callback().set(FUNC(spg110_device::timerirq_w));
-// io->write_uart_adc_irq_callback().set(FUNC(spg110_device::uartirq_w));
-// io->write_external_irq_callback().set(FUNC(spg110_device::extirq_w));
-// io->write_ffrq_tmr1_irq_callback().set(FUNC(spg110_device::ffreq1_w));
-// io->write_ffrq_tmr2_irq_callback().set(FUNC(spg110_device::ffreq2_w));
-}
-
-void spg110_device::device_add_mconfig(machine_config &config)
-{
-// PALETTE(config, m_palette).set_format(palette_device::xRGB_555, 0x100);
-// PALETTE(config, m_palette).set_format(palette_device::RGB_565, 0x100);
-// PALETTE(config, m_palette).set_format(palette_device::IRGB_4444, 0x100);
-// PALETTE(config, m_palette).set_format(palette_device::RGBI_4444, 0x100);
-// PALETTE(config, m_palette).set_format(palette_device::xRGB_555, 0x100);
- PALETTE(config, m_palette, palette_device::BLACK, 256);
-
- GFXDECODE(config, m_gfxdecode, m_palette, gfx);
-
- SPG24X_IO(config, m_spg_io, DERIVED_CLOCK(1, 1), m_cpu, m_screen);
- configure_spg_io(m_spg_io);
-
-}
-
-
-device_memory_interface::space_config_vector spg110_device::memory_space_config() const
-{
- return space_config_vector {
- std::make_pair(0, &m_space_config)
- };
-}
-
-spg110_device::spg110_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : spg110_device(mconfig, SPG110, tag, owner, clock)
-{
-}
-
-// irq source or similar?
-READ16_MEMBER(spg110_device::spg110_2063_r)
-{
- // checks for bits 0x20 and 0x08 in the IRQ function (all IRQs point to the same place)
- return 0x0008;
-}
-
-WRITE16_MEMBER(spg110_device::spg110_2063_w)
-{
- // writes 0x28, probably clears the IRQ / IRQ sources? 0x63 is the same offset for this in spg2xx but bits used seem to be different
- m_cpu->set_state_unsynced(UNSP_IRQ0_LINE, CLEAR_LINE);
-}
-
-
-WRITE16_MEMBER(spg110_device::spg110_201c_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2020_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2042_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2031_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2032_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2033_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2034_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2035_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2036_w) { COMBINE_DATA(&m_2036_scroll); }
-WRITE16_MEMBER(spg110_device::spg110_2039_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2037_w) { }
-WRITE16_MEMBER(spg110_device::spg110_203c_w) { }
-WRITE16_MEMBER(spg110_device::spg110_203d_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2045_w) { }
-
-
-WRITE16_MEMBER(spg110_device::spg110_2028_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2029_w) { }
-
-READ16_MEMBER(spg110_device::spg110_2028_r) { return 0x0000; }
-READ16_MEMBER(spg110_device::spg110_2029_r) { return 0x0000; }
-
-
-WRITE16_MEMBER(spg110_device::spg110_2050_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2051_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2052_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2053_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2054_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2055_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2056_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2057_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2058_w) { }
-WRITE16_MEMBER(spg110_device::spg110_2059_w) { }
-WRITE16_MEMBER(spg110_device::spg110_205a_w) { }
-WRITE16_MEMBER(spg110_device::spg110_205b_w) { }
-WRITE16_MEMBER(spg110_device::spg110_205c_w) { }
-WRITE16_MEMBER(spg110_device::spg110_205d_w) { }
-WRITE16_MEMBER(spg110_device::spg110_205e_w) { }
-WRITE16_MEMBER(spg110_device::spg110_205f_w) { }
-
-WRITE16_MEMBER(spg110_device::dma_unk_2061_w) { COMBINE_DATA(&m_dma_unk_2061); }
-WRITE16_MEMBER(spg110_device::dma_dst_step_w) { COMBINE_DATA(&m_dma_dst_step); }
-WRITE16_MEMBER(spg110_device::dma_unk_2067_w) { COMBINE_DATA(&m_dma_unk_2067); }
-WRITE16_MEMBER(spg110_device::dma_src_step_w) { COMBINE_DATA(&m_dma_src_step); }
-
-WRITE16_MEMBER(spg110_device::dma_dst_w) { COMBINE_DATA(&m_dma_dst); }
-WRITE16_MEMBER(spg110_device::dma_src_w) { COMBINE_DATA(&m_dma_src); }
-
-WRITE16_MEMBER(spg110_device::dma_len_trigger_w)
-{
- int length = data & 0x1fff;
-
- // this is presumably a counter that underflows to 0x1fff, because that's what the wait loop waits for?
- logerror("%s: (trigger len) %04x with values (unk) %04x (dststep) %04x (unk) %04x (src step) %04x | (dst) %04x (src) %04x\n", machine().describe_context(), data, m_dma_unk_2061, m_dma_dst_step, m_dma_unk_2067, m_dma_src_step, m_dma_dst, m_dma_src);
-
- if ((m_dma_unk_2061!=0x0000) || (m_dma_unk_2067 != 0x0000))
- fatalerror("unknown DMA params are not zero!\n");
-
- int source = m_dma_src;
- int dest = m_dma_dst;
-
- for (int i = 0; i < length; i++)
- {
- address_space &mem = m_cpu->space(AS_PROGRAM);
- uint16_t val = mem.read_word(source);
-
- this->space(0).write_word(dest * 2, val, 0xffff);
-
- source+=m_dma_src_step;
- dest+=m_dma_dst_step;
- }
-}
-
-READ16_MEMBER(spg110_device::dma_len_status_r)
-{
- return 0x1fff; // DMA related?
-}
-
-READ16_MEMBER(spg110_device::spg110_2037_r) { return 0x0000; }
-READ16_MEMBER(spg110_device::spg110_2042_r) { return 0x0000; }
-
-
-WRITE16_MEMBER(spg110_device::spg110_3100_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3101_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3102_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3104_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3105_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3106_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3107_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3108_w) { }
-WRITE16_MEMBER(spg110_device::spg110_3109_w) { }
-WRITE16_MEMBER(spg110_device::spg110_310b_w) { }
-WRITE16_MEMBER(spg110_device::spg110_310c_w) { }
-WRITE16_MEMBER(spg110_device::spg110_310d_w) { }
-
-READ16_MEMBER(spg110_device::spg110_310f_r) { return 0x0000; }
-
-READ16_MEMBER(spg110_device::tmap0_regs_r) { return tmap0_regs[offset]; }
-READ16_MEMBER(spg110_device::tmap1_regs_r) { return tmap1_regs[offset]; }
-
-void spg110_device::tilemap_write_regs(int which, uint16_t* regs, int regno, uint16_t data)
-{
- switch (regno)
- {
- case 0x0: // Page X scroll
- logerror("video_w: Page %d X Scroll = %04x\n", which, data & 0x01ff);
- regs[regno] = data & 0x01ff;
- break;
-
- case 0x1: // Page Y scroll
- logerror("video_w: Page %d Y Scroll = %04x\n", which, data & 0x00ff);
- regs[regno] = data & 0x00ff;
- break;
-
- case 0x2: // Page Attributes
- // 'depth' (aka z value) can't be depth here as it is on spg2xx, or the scores in attract will be behind the table, it really seems to be per attribute bit instead
-
- logerror("video_w: Page %d Attributes = %04x (Depth:%d, Palette:%d, VSize:%d, HSize:%d, FlipY:%d, FlipX:%d, BPP:%d)\n", which, data
- , (data >> 12) & 3, (data >> 8) & 15, 8 << ((data >> 6) & 3), 8 << ((data >> 4) & 3), BIT(data, 3), BIT(data, 2), 2 * ((data & 3) + 1));
- regs[regno] = data;
- break;
-
- case 0x3: // Page Control
- logerror("video_w: Page %d Control = %04x (Blend:%d, HiColor:%d, RowScroll:%d, Enable:%d, Wallpaper:%d, RegSet:%d, Bitmap:%d)\n", which, data
- , BIT(data, 8), BIT(data, 7), BIT(data, 4), BIT(data, 3), BIT(data, 2), BIT(data, 1), BIT(data, 0));
- regs[regno] = data;
- break;
-
- case 0x4: // Page Tile Address
- logerror("video_w: Page %d Tile Address = %04x\n", which, data);
- regs[regno] = data;
- break;
-
- case 0x5: // Page Attribute Address
- logerror("video_w: Page %d Attribute Address = %04x\n", which, data);
- regs[regno] = data;
- break;
- }
-}
-
-
-WRITE16_MEMBER(spg110_device::tmap0_regs_w)
-{
- tilemap_write_regs(0, tmap0_regs,offset,data);
-}
-
-
-WRITE16_MEMBER(spg110_device::tmap1_regs_w)
-{
- tilemap_write_regs(1, tmap1_regs,offset,data);
-}
-
-void spg110_device::map(address_map &map)
-{
- map(0x000000, 0x000fff).ram();
-
-
- // vregs are at 2000?
- map(0x002010, 0x002015).rw(FUNC(spg110_device::tmap0_regs_r), FUNC(spg110_device::tmap0_regs_w));
- map(0x002016, 0x00201b).rw(FUNC(spg110_device::tmap1_regs_r), FUNC(spg110_device::tmap1_regs_w));
-
- map(0x00201c, 0x00201c).w(FUNC(spg110_device::spg110_201c_w));
-
- map(0x002020, 0x002020).w(FUNC(spg110_device::spg110_2020_w));
-
- map(0x002028, 0x002028).rw(FUNC(spg110_device::spg110_2028_r), FUNC(spg110_device::spg110_2028_w));
- map(0x002029, 0x002029).rw(FUNC(spg110_device::spg110_2029_r), FUNC(spg110_device::spg110_2029_w));
-
- map(0x002031, 0x002031).w(FUNC(spg110_device::spg110_2031_w)); // sometimes 14a?
- map(0x002032, 0x002032).w(FUNC(spg110_device::spg110_2032_w)); // always 14a?
- map(0x002033, 0x002033).w(FUNC(spg110_device::spg110_2033_w));
- map(0x002034, 0x002034).w(FUNC(spg110_device::spg110_2034_w));
- map(0x002035, 0x002035).w(FUNC(spg110_device::spg110_2035_w));
- map(0x002036, 0x002036).w(FUNC(spg110_device::spg110_2036_w)); // possible scroll register?
- map(0x002037, 0x002037).rw(FUNC(spg110_device::spg110_2037_r), FUNC(spg110_device::spg110_2037_w));
-
- map(0x002039, 0x002039).w(FUNC(spg110_device::spg110_2039_w));
-
- map(0x00203c, 0x00203c).w(FUNC(spg110_device::spg110_203c_w));
-
- map(0x00203d, 0x00203d).w(FUNC(spg110_device::spg110_203d_w)); // possible scroll register?
-
- map(0x002042, 0x002042).rw(FUNC(spg110_device::spg110_2042_r),FUNC(spg110_device::spg110_2042_w));
-
- map(0x002045, 0x002045).w(FUNC(spg110_device::spg110_2045_w));
-
- // seems to be 16 entries for.. something?
- map(0x002050, 0x002050).w(FUNC(spg110_device::spg110_2050_w));
- map(0x002051, 0x002051).w(FUNC(spg110_device::spg110_2051_w));
- map(0x002052, 0x002052).w(FUNC(spg110_device::spg110_2052_w));
- map(0x002053, 0x002053).w(FUNC(spg110_device::spg110_2053_w));
- map(0x002054, 0x002054).w(FUNC(spg110_device::spg110_2054_w));
- map(0x002055, 0x002055).w(FUNC(spg110_device::spg110_2055_w));
- map(0x002056, 0x002056).w(FUNC(spg110_device::spg110_2056_w));
- map(0x002057, 0x002057).w(FUNC(spg110_device::spg110_2057_w));
- map(0x002058, 0x002058).w(FUNC(spg110_device::spg110_2058_w));
- map(0x002059, 0x002059).w(FUNC(spg110_device::spg110_2059_w));
- map(0x00205a, 0x00205a).w(FUNC(spg110_device::spg110_205a_w));
- map(0x00205b, 0x00205b).w(FUNC(spg110_device::spg110_205b_w));
- map(0x00205c, 0x00205c).w(FUNC(spg110_device::spg110_205c_w));
- map(0x00205d, 0x00205d).w(FUNC(spg110_device::spg110_205d_w));
- map(0x00205e, 0x00205e).w(FUNC(spg110_device::spg110_205e_w));
- map(0x00205f, 0x00205f).w(FUNC(spg110_device::spg110_205f_w));
-
- //map(0x002010, 0x00205f).ram();
-
- // everything (dma? and interrupt flag?!)
- map(0x002060, 0x002060).w(FUNC(spg110_device::dma_dst_w));
- map(0x002061, 0x002061).w(FUNC(spg110_device::dma_unk_2061_w));
- map(0x002062, 0x002062).rw(FUNC(spg110_device::dma_len_status_r),FUNC(spg110_device::dma_len_trigger_w));
- map(0x002063, 0x002063).rw(FUNC(spg110_device::spg110_2063_r),FUNC(spg110_device::spg110_2063_w)); // this looks like interrupt stuff and is checked in the irq like an irq source, but why in the middle of what otherwise look like some kind of DMA?
- map(0x002064, 0x002064).w(FUNC(spg110_device::dma_dst_step_w));
- map(0x002066, 0x002066).w(FUNC(spg110_device::dma_src_w));
- map(0x002067, 0x002067).w(FUNC(spg110_device::dma_unk_2067_w));
- map(0x002068, 0x002068).w(FUNC(spg110_device::dma_src_step_w));
-
- map(0x002200, 0x0022ff).ram(); // looks like per-pen brightness or similar? strange because palette isn't memory mapped here
-
- map(0x003000, 0x00307f).ram(); // sound registers? seems to be 8 long entries, only uses up to 0x7f?
- map(0x003080, 0x0030ff).ram();
-
- map(0x003100, 0x003100).w(FUNC(spg110_device::spg110_3100_w));
- map(0x003101, 0x003101).w(FUNC(spg110_device::spg110_3101_w));
- map(0x003102, 0x003102).w(FUNC(spg110_device::spg110_3102_w));
-
- map(0x003104, 0x003104).w(FUNC(spg110_device::spg110_3104_w));
- map(0x003105, 0x003105).w(FUNC(spg110_device::spg110_3105_w));
- map(0x003106, 0x003106).w(FUNC(spg110_device::spg110_3106_w));
- map(0x003107, 0x003107).w(FUNC(spg110_device::spg110_3107_w));
- map(0x003108, 0x003108).w(FUNC(spg110_device::spg110_3108_w));
- map(0x003109, 0x003109).w(FUNC(spg110_device::spg110_3109_w));
-
- map(0x00310b, 0x00310b).w(FUNC(spg110_device::spg110_310b_w));
- map(0x00310c, 0x00310c).w(FUNC(spg110_device::spg110_310c_w));
- map(0x00310d, 0x00310d).w(FUNC(spg110_device::spg110_310d_w));
-
- map(0x00310f, 0x00310f).r(FUNC(spg110_device::spg110_310f_r));
-
- // 0032xx looks like it could be the same as 003d00 on spg2xx
- map(0x003200, 0x00322f).rw(m_spg_io, FUNC(spg2xx_io_device::io_r), FUNC(spg2xx_io_device::io_w));
-}
-
-// this seems to be a different, non-cpu mapped space only accessible via the DMA?
-void spg110_device::map_video(address_map &map)
-{
- // are these addresses hardcoded, or can they move (in which case tilemap system isn't really suitable)
- map(0x00000, 0x03fff).ram(); // 2fff?
-
- map(0x04000, 0x04fff).ram(); // seems to be 3 blocks, almost certainly spritelist
-
-// map(0x08000, 0x081ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // probably? format unknown tho
- map(0x08000, 0x081ff).ram().share("palram");
-}
-
-
-/*
-TIMER_CALLBACK_MEMBER(spg110_device::test_timer)
-{
- //
-}
-*/
-
-
-
-void spg110_device::device_start()
-{
-// m_test_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg110_device::test_timer), this));
- save_item(NAME(m_dma_src_step));
- save_item(NAME(m_dma_dst_step));
- save_item(NAME(m_dma_unk_2061));
- save_item(NAME(m_dma_unk_2067));
- save_item(NAME(m_dma_dst));
- save_item(NAME(m_dma_src));
- save_item(NAME(m_bg_scrollx));
- save_item(NAME(m_bg_scrolly));
- save_item(NAME(m_2036_scroll));
-
- m_porta_out.resolve_safe();
- m_portb_out.resolve_safe();
- m_portc_out.resolve_safe();
- m_porta_in.resolve_safe(0);
- m_portb_in.resolve_safe(0);
- m_portc_in.resolve_safe(0);
- m_adc_in[0].resolve_safe(0x0fff);
- m_adc_in[1].resolve_safe(0x0fff);
- m_chip_sel.resolve_safe();
-
-}
-
-void spg110_device::device_reset()
-{
- m_dma_src_step = 0;
- m_dma_dst_step = 0;
- m_dma_unk_2061 = 0;
- m_dma_unk_2067 = 0;
- m_dma_dst = 0;
- m_dma_src = 0;
- m_bg_scrollx = 0;
- m_bg_scrolly = 0;
- m_2036_scroll = 0;
-}
-
-double spg110_device::hue2rgb(double p, double q, double t)
-{
- if (t < 0) t += 1;
- if (t > 1) t -= 1;
- if (t < 1 / 6.0f) return p + (q - p) * 6 * t;
- if (t < 1 / 2.0f) return q;
- if (t < 2 / 3.0f) return p + (q - p) * (2 / 3.0f - t) * 6;
- return p;
-}
-
-uint32_t spg110_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
-{
- // Palette, this is still wrong!
- int offs = 0;
- for (int index = 0;index < 256; index++)
- {
- uint16_t dat = m_palram[offs++];
-
- // llll lsss sshh hhhh
- int l_raw = (dat & 0xf800) >> 11;
- int sl_raw = (dat & 0x07c0) >> 6;
- int h_raw = (dat & 0x003f) >> 0;
-
- double l = (double)l_raw / 31.0f;
- double s = (double)sl_raw / 31.0f;
- double h = (double)h_raw / 47.0f;
-
- double r, g, b;
-
- if (s == 0) {
- r = g = b = l; // greyscale
- } else {
- double q = l < 0.5f ? l * (1 + s) : l + s - l * s;
- double p = 2 * l - q;
- r = hue2rgb(p, q, h + 1/3.0f);
- g = hue2rgb(p, q, h);
- b = hue2rgb(p, q, h - 1/3.0f);
- }
-
- int r_real = r * 255.0f;
- int g_real = g * 255.0f;
- int b_real = b * 255.0f;
-
- m_palette->set_pen_color(index, r_real, g_real, b_real);
- }
-
- memset(&m_screenbuf[320 * cliprect.min_y], 0, 4 * 320 * ((cliprect.max_y - cliprect.min_y) + 1));
-
- const uint32_t page1_addr = 0;//0x40 * m_video_regs[0x20];
- const uint32_t page2_addr = 0;//0x40 * m_video_regs[0x21];
- uint16_t *page1_regs = tmap0_regs;
- uint16_t *page2_regs = tmap1_regs;
-
- for (uint32_t scanline = (uint32_t)cliprect.min_y; scanline <= (uint32_t)cliprect.max_y; scanline++)
- {
- for (int i = 0; i < 4; i++)
- {
- blit_page(cliprect, scanline, i, page2_addr, page2_regs);
- blit_page(cliprect, scanline, i, page1_addr, page1_regs);
- //blit_sprites(cliprect, scanline, i);
- }
- }
-
- for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
- {
- uint32_t *dest = &bitmap.pix32(y, cliprect.min_x);
- uint32_t *src = &m_screenbuf[cliprect.min_x + 320 * y];
- memcpy(dest, src, sizeof(uint32_t) * ((cliprect.max_x - cliprect.min_x) + 1));
- }
-
- return 0;
-}
-
-WRITE_LINE_MEMBER(spg110_device::vblank)
-{
- if (!state)
- {
- m_cpu->set_state_unsynced(UNSP_IRQ0_LINE, ASSERT_LINE);
- // m_test_timer->adjust(attotime::from_usec(100), 0);
- }
-
- return;
-}
diff --git a/src/devices/machine/spg110.h b/src/devices/machine/spg110.h
deleted file mode 100644
index 64464e1ba9d..00000000000
--- a/src/devices/machine/spg110.h
+++ /dev/null
@@ -1,220 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Haywood
-
-#ifndef MAME_MACHINE_SPG110_H
-#define MAME_MACHINE_SPG110_H
-
-#pragma once
-
-//#include "spg2xx.h"
-#include "cpu/unsp/unsp.h"
-#include "emupal.h"
-#include "spg2xx_io.h"
-
-
-class spg110_device : public device_t, public device_memory_interface
-
-{
-public:
- spg110_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
- spg110_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- template <typename T, typename U>
- spg110_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag, U &&screen_tag)
- : spg110_device(mconfig, tag, owner, clock)
- {
- m_cpu.set_tag(std::forward<T>(cpu_tag));
- m_screen.set_tag(std::forward<U>(screen_tag));
- }
-
- void map(address_map &map);
- void map_video(address_map &map);
-
- double hue2rgb(double p, double q, double t);
- uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- DECLARE_WRITE_LINE_MEMBER(vblank);
-
- auto porta_out() { return m_porta_out.bind(); }
- auto portb_out() { return m_portb_out.bind(); }
- auto portc_out() { return m_portc_out.bind(); }
- auto porta_in() { return m_porta_in.bind(); }
- auto portb_in() { return m_portb_in.bind(); }
- auto portc_in() { return m_portc_in.bind(); }
-
- template <size_t Line> auto adc_in() { return m_adc_in[Line].bind(); }
-
- auto chip_select() { return m_chip_sel.bind(); }
-
-protected:
- virtual void device_start() override;
- virtual void device_reset() override;
-
- virtual void device_add_mconfig(machine_config &config) override;
-
- virtual space_config_vector memory_space_config() const override;
-
- address_space_config m_space_config;
-
-private:
- enum
- {
- PAGE_ENABLE_MASK = 0x0008,
- PAGE_WALLPAPER_MASK = 0x0004,
-
- PAGE_DEPTH_FLAG_MASK = 0x3000,
- PAGE_DEPTH_FLAG_SHIFT = 12,
- PAGE_TILE_HEIGHT_MASK = 0x00c0,
- PAGE_TILE_HEIGHT_SHIFT = 6,
- PAGE_TILE_WIDTH_MASK = 0x0030,
- PAGE_TILE_WIDTH_SHIFT = 4,
-
- TILE_X_FLIP = 0x0004,
- TILE_Y_FLIP = 0x0008
- };
-
- enum flipx_t : bool
- {
- FlipXOff = false,
- FlipXOn = true
- };
-
- required_device<unsp_device> m_cpu;
- required_device<screen_device> m_screen;
- required_device<palette_device> m_palette;
- required_device<gfxdecode_device> m_gfxdecode;
- required_shared_ptr<uint16_t> m_palram;
- required_device<spg2xx_io_device> m_spg_io;
-
- //TIMER_CALLBACK_MEMBER(test_timer);
- //emu_timer *m_test_timer;
-
-
- DECLARE_WRITE16_MEMBER(spg110_201c_w);
- DECLARE_WRITE16_MEMBER(spg110_2020_w);
-
- DECLARE_WRITE16_MEMBER(spg110_2028_w);
- DECLARE_WRITE16_MEMBER(spg110_2029_w);
-
- DECLARE_READ16_MEMBER(spg110_2028_r);
- DECLARE_READ16_MEMBER(spg110_2029_r);
-
- DECLARE_WRITE16_MEMBER(spg110_2031_w);
- DECLARE_WRITE16_MEMBER(spg110_2032_w);
- DECLARE_WRITE16_MEMBER(spg110_2033_w);
- DECLARE_WRITE16_MEMBER(spg110_2034_w);
- DECLARE_WRITE16_MEMBER(spg110_2035_w);
- DECLARE_WRITE16_MEMBER(spg110_2036_w);
- DECLARE_WRITE16_MEMBER(spg110_2037_w);
- DECLARE_WRITE16_MEMBER(spg110_2039_w);
-
- DECLARE_WRITE16_MEMBER(spg110_203c_w);
- DECLARE_WRITE16_MEMBER(spg110_203d_w);
-
- DECLARE_WRITE16_MEMBER(spg110_2042_w);
-
- DECLARE_WRITE16_MEMBER(spg110_2045_w);
-
- DECLARE_WRITE16_MEMBER(spg110_2050_w);
- DECLARE_WRITE16_MEMBER(spg110_2051_w);
- DECLARE_WRITE16_MEMBER(spg110_2052_w);
- DECLARE_WRITE16_MEMBER(spg110_2053_w);
- DECLARE_WRITE16_MEMBER(spg110_2054_w);
- DECLARE_WRITE16_MEMBER(spg110_2055_w);
- DECLARE_WRITE16_MEMBER(spg110_2056_w);
- DECLARE_WRITE16_MEMBER(spg110_2057_w);
- DECLARE_WRITE16_MEMBER(spg110_2058_w);
- DECLARE_WRITE16_MEMBER(spg110_2059_w);
- DECLARE_WRITE16_MEMBER(spg110_205a_w);
- DECLARE_WRITE16_MEMBER(spg110_205b_w);
- DECLARE_WRITE16_MEMBER(spg110_205c_w);
- DECLARE_WRITE16_MEMBER(spg110_205d_w);
- DECLARE_WRITE16_MEMBER(spg110_205e_w);
- DECLARE_WRITE16_MEMBER(spg110_205f_w);
-
-
- DECLARE_READ16_MEMBER(spg110_2037_r);
- DECLARE_READ16_MEMBER(spg110_2042_r);
-
- DECLARE_WRITE16_MEMBER(dma_dst_w);
- DECLARE_WRITE16_MEMBER(dma_unk_2061_w);
- DECLARE_WRITE16_MEMBER(dma_len_trigger_w);
- DECLARE_WRITE16_MEMBER(spg110_2063_w);
- DECLARE_WRITE16_MEMBER(dma_dst_step_w);
- DECLARE_WRITE16_MEMBER(dma_src_w);
- DECLARE_WRITE16_MEMBER(dma_unk_2067_w);
- DECLARE_WRITE16_MEMBER(dma_src_step_w);
-
- DECLARE_READ16_MEMBER(dma_len_status_r);
- DECLARE_READ16_MEMBER(spg110_2063_r);
-
- DECLARE_WRITE16_MEMBER(spg110_3100_w);
-
- DECLARE_WRITE16_MEMBER(spg110_3101_w);
- DECLARE_WRITE16_MEMBER(spg110_3102_w);
- DECLARE_WRITE16_MEMBER(spg110_3104_w);
- DECLARE_WRITE16_MEMBER(spg110_3105_w);
- DECLARE_WRITE16_MEMBER(spg110_3106_w);
- DECLARE_WRITE16_MEMBER(spg110_3107_w);
- DECLARE_WRITE16_MEMBER(spg110_3108_w);
- DECLARE_WRITE16_MEMBER(spg110_3109_w);
-
- DECLARE_WRITE16_MEMBER(spg110_310b_w);
- DECLARE_WRITE16_MEMBER(spg110_310c_w);
- DECLARE_WRITE16_MEMBER(spg110_310d_w);
-
- DECLARE_READ16_MEMBER(spg110_310f_r);
-
- DECLARE_READ16_MEMBER(tmap0_regs_r);
- DECLARE_READ16_MEMBER(tmap1_regs_r);
- DECLARE_WRITE16_MEMBER(tmap0_regs_w);
- DECLARE_WRITE16_MEMBER(tmap1_regs_w);
-
- uint16_t tmap0_regs[0x6];
- uint16_t tmap1_regs[0x6];
-
- uint16_t m_dma_src_step;
- uint16_t m_dma_dst_step;
- uint16_t m_dma_unk_2061;
- uint16_t m_dma_unk_2067;
-
- uint16_t m_dma_dst;
- uint16_t m_dma_src;
-
- uint16_t m_bg_scrollx;
- uint16_t m_bg_scrolly;
- uint16_t m_2036_scroll;
-
- void tilemap_write_regs(int which, uint16_t* regs, int regno, uint16_t data);
-
- template<flipx_t FlipX>
- void blit(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t attr, uint32_t ctrl, uint32_t bitmap_addr, uint16_t tile);
- void blit_page(const rectangle &cliprect, uint32_t scanline, int depth, uint32_t bitmap_addr, uint16_t *regs);
- uint32_t m_screenbuf[320 * 240];
-
- devcb_write16 m_porta_out;
- devcb_write16 m_portb_out;
- devcb_write16 m_portc_out;
- devcb_read16 m_porta_in;
- devcb_read16 m_portb_in;
- devcb_read16 m_portc_in;
-
- devcb_read16 m_adc_in[2];
-
- devcb_write8 m_chip_sel;
-
- DECLARE_READ16_MEMBER(porta_r) { return m_porta_in(); };
- DECLARE_READ16_MEMBER(portb_r) { return m_portb_in(); };
- DECLARE_READ16_MEMBER(portc_r) { return m_portc_in(); };
- DECLARE_WRITE16_MEMBER(porta_w) { m_porta_out(offset, data, mem_mask); };
- DECLARE_WRITE16_MEMBER(portb_w) { m_portb_out(offset, data, mem_mask); };
- DECLARE_WRITE16_MEMBER(portc_w) { m_portc_out(offset, data, mem_mask); };
- template <size_t Line> DECLARE_READ16_MEMBER(adc_r) { return m_adc_in[Line](); };
- DECLARE_WRITE8_MEMBER(cs_w) { m_chip_sel(offset, data, mem_mask); };
- DECLARE_READ16_MEMBER(get_pal_r) { return 0; /*m_pal_flag;*/ };
- void configure_spg_io(spg2xx_io_device* io);
-
-};
-
-DECLARE_DEVICE_TYPE(SPG110, spg110_device)
-
-#endif // MAME_MACHINE_SPG110_H
diff --git a/src/devices/machine/spg2xx.cpp b/src/devices/machine/spg2xx.cpp
index 3a3a22abac3..a325346558d 100644
--- a/src/devices/machine/spg2xx.cpp
+++ b/src/devices/machine/spg2xx.cpp
@@ -17,38 +17,57 @@
DEFINE_DEVICE_TYPE(SPG24X, spg24x_device, "spg24x", "SPG240-series System-on-a-Chip")
DEFINE_DEVICE_TYPE(SPG28X, spg28x_device, "spg28x", "SPG280-series System-on-a-Chip")
+#define LOG_IO_READS (1U << 1)
+#define LOG_IO_WRITES (1U << 2)
#define LOG_UNKNOWN_IO (1U << 3)
#define LOG_IRQS (1U << 4)
#define LOG_VLINES (1U << 5)
+#define LOG_GPIO (1U << 6)
+#define LOG_UART (1U << 7)
+#define LOG_I2C (1U << 8)
#define LOG_DMA (1U << 9)
+#define LOG_SEGMENT (1U << 10)
+#define LOG_WATCHDOG (1U << 11)
+#define LOG_TIMERS (1U << 12)
+#define LOG_SPU_READS (1U << 13)
+#define LOG_SPU_WRITES (1U << 14)
+#define LOG_UNKNOWN_SPU (1U << 15)
+#define LOG_CHANNEL_READS (1U << 16)
+#define LOG_CHANNEL_WRITES (1U << 17)
+#define LOG_ENVELOPES (1U << 18)
+#define LOG_SAMPLES (1U << 19)
+#define LOG_RAMPDOWN (1U << 20)
+#define LOG_BEAT (1U << 21)
#define LOG_PPU_READS (1U << 22)
#define LOG_PPU_WRITES (1U << 23)
#define LOG_UNKNOWN_PPU (1U << 24)
-#define LOG_IO (LOG_IRQS | LOG_DMA | LOG_UNKNOWN_IO)
+#define LOG_IO (LOG_IO_READS | LOG_IO_WRITES | LOG_IRQS | LOG_GPIO | LOG_UART | LOG_I2C | LOG_DMA | LOG_TIMERS | LOG_UNKNOWN_IO)
+#define LOG_CHANNELS (LOG_CHANNEL_READS | LOG_CHANNEL_WRITES)
+#define LOG_SPU (LOG_SPU_READS | LOG_SPU_WRITES | LOG_UNKNOWN_SPU | LOG_CHANNEL_READS | LOG_CHANNEL_WRITES \
+ | LOG_ENVELOPES | LOG_SAMPLES | LOG_RAMPDOWN | LOG_BEAT)
#define LOG_PPU (LOG_PPU_READS | LOG_PPU_WRITES | LOG_UNKNOWN_PPU)
-#define LOG_ALL (LOG_IO | LOG_PPU | LOG_VLINES )
+#define LOG_ALL (LOG_IO | LOG_SPU | LOG_PPU | LOG_VLINES | LOG_SEGMENT)
-#define VERBOSE (0)
+#define VERBOSE (LOG_UART | LOG_UNKNOWN_IO)
#include "logmacro.h"
#define SPG_DEBUG_VIDEO (0)
+#define SPG_DEBUG_AUDIO (0)
+#define IO_IRQ_ENABLE m_io_regs[0x21]
+#define IO_IRQ_STATUS m_io_regs[0x22]
#define VIDEO_IRQ_ENABLE m_video_regs[0x62]
#define VIDEO_IRQ_STATUS m_video_regs[0x63]
spg2xx_device::spg2xx_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_mixer_interface(mconfig, *this, 2)
- , m_spg_audio(*this, "spgaudio")
- , m_spg_io(*this, "spgio")
- , m_rowscrolloffset(15)
+ , device_sound_interface(mconfig, *this)
, m_porta_out(*this)
, m_portb_out(*this)
, m_portc_out(*this)
, m_porta_in(*this)
, m_portb_in(*this)
, m_portc_in(*this)
- , m_adc_in{{*this}, {*this}}
, m_eeprom_w(*this)
, m_eeprom_r(*this)
, m_uart_tx(*this)
@@ -78,234 +97,212 @@ void spg2xx_device::map(address_map &map)
map(0x002900, 0x002aff).ram().share("scrollram");
map(0x002b00, 0x002bff).ram().share("paletteram");
map(0x002c00, 0x002fff).ram().share("spriteram");
- map(0x003000, 0x0031ff).rw(m_spg_audio, FUNC(spg2xx_audio_device::audio_r), FUNC(spg2xx_audio_device::audio_w));
- map(0x003200, 0x0033ff).rw(m_spg_audio, FUNC(spg2xx_audio_device::audio_phase_r), FUNC(spg2xx_audio_device::audio_phase_w));
- map(0x003400, 0x0037ff).rw(m_spg_audio, FUNC(spg2xx_audio_device::audio_ctrl_r), FUNC(spg2xx_audio_device::audio_ctrl_w));
- map(0x003d00, 0x003d2f).rw(m_spg_io, FUNC(spg2xx_io_device::io_r), FUNC(spg2xx_io_device::io_w));
- map(0x003d30, 0x003dff).rw(m_spg_io, FUNC(spg2xx_io_device::io_extended_r), FUNC(spg2xx_io_device::io_extended_w));
- map(0x003e00, 0x003e03).rw(FUNC(spg2xx_device::dma_r), FUNC(spg2xx_device::dma_w));
+ map(0x003000, 0x0037ff).rw(FUNC(spg2xx_device::audio_r), FUNC(spg2xx_device::audio_w));
+ map(0x003d00, 0x003eff).rw(FUNC(spg2xx_device::io_r), FUNC(spg2xx_device::io_w));
}
void spg2xx_device::device_start()
{
- for (uint8_t i = 0; i < 32; i++)
- {
- m_rgb5_to_rgb8[i] = (i << 3) | (i >> 2);
- }
- for (uint16_t i = 0; i < 0x8000; i++)
- {
- m_rgb555_to_rgb888[i] = (m_rgb5_to_rgb8[(i >> 10) & 0x1f] << 16) |
- (m_rgb5_to_rgb8[(i >> 5) & 0x1f] << 8) |
- (m_rgb5_to_rgb8[(i >> 0) & 0x1f] << 0);
- }
m_porta_out.resolve_safe();
m_portb_out.resolve_safe();
m_portc_out.resolve_safe();
m_porta_in.resolve_safe(0);
m_portb_in.resolve_safe(0);
m_portc_in.resolve_safe(0);
- m_adc_in[0].resolve_safe(0x0fff);
- m_adc_in[1].resolve_safe(0x0fff);
m_eeprom_w.resolve_safe();
m_eeprom_r.resolve_safe(0);
m_uart_tx.resolve_safe();
m_chip_sel.resolve_safe();
+ m_tmb1 = timer_alloc(TIMER_TMB1);
+ m_tmb2 = timer_alloc(TIMER_TMB2);
+ m_tmb1->adjust(attotime::never);
+ m_tmb2->adjust(attotime::never);
+
m_screenpos_timer = timer_alloc(TIMER_SCREENPOS);
m_screenpos_timer->adjust(attotime::never);
- save_item(NAME(m_hide_page0));
- save_item(NAME(m_hide_page1));
- save_item(NAME(m_hide_sprites));
- save_item(NAME(m_debug_sprites));
- save_item(NAME(m_debug_blit));
- save_item(NAME(m_debug_palette));
- save_item(NAME(m_sprite_index_to_debug));
+ m_audio_beat = timer_alloc(TIMER_BEAT);
+ m_audio_beat->adjust(attotime::never);
- save_item(NAME(m_dma_regs));
+ m_stream = stream_alloc(0, 2, 44100);
- save_item(NAME(m_video_regs));
- save_item(NAME(m_sprite_limit));
- save_item(NAME(m_pal_flag));
+ m_channel_debug = -1;
}
void spg2xx_device::device_reset()
{
+ memset(m_audio_regs, 0, 0x800 * sizeof(uint16_t));
+ memset(m_sample_shift, 0, 16);
+ memset(m_sample_count, 0, sizeof(uint32_t) * 16);
+ memset(m_sample_addr, 0, sizeof(uint32_t) * 16);
+ memset(m_channel_rate, 0, sizeof(double) * 16);
+ memset(m_channel_rate_accum, 0, sizeof(double) * 16);
+ memset(m_rampdown_frame, 0, sizeof(uint32_t) * 16);
+ memset(m_envclk_frame, 4, sizeof(uint32_t) * 16);
+ memset(m_envelope_addr, 0, sizeof(uint32_t) * 16);
+
memset(m_video_regs, 0, 0x100 * sizeof(uint16_t));
- memset(m_dma_regs, 0, 0x4 * sizeof(uint16_t));
+ memset(m_io_regs, 0, 0x200 * sizeof(uint16_t));
+
+ m_io_regs[0x23] = 0x0028;
+ m_uart_rx_available = false;
+ memset(m_uart_rx_fifo, 0, ARRAY_LENGTH(m_uart_rx_fifo));
+ m_uart_rx_fifo_start = 0;
+ m_uart_rx_fifo_end = 0;
+ m_uart_rx_fifo_count = 0;
m_video_regs[0x36] = 0xffff;
m_video_regs[0x37] = 0xffff;
m_video_regs[0x3c] = 0x0020;
- m_video_regs[0x42] = 0x0001;
m_hide_page0 = false;
m_hide_page1 = false;
m_hide_sprites = false;
m_debug_sprites = false;
m_debug_blit = false;
- m_debug_palette = false;
m_sprite_index_to_debug = 0;
-}
+ m_debug_samples = false;
+ m_debug_rates = false;
+ m_audio_curr_beat_base_count = 0;
-WRITE_LINE_MEMBER(spg2xx_device::audioirq_w)
-{
- m_cpu->set_state_unsynced(UNSP_IRQ4_LINE, state);
-}
+ m_audio_regs[AUDIO_CHANNEL_REPEAT] = 0x3f;
+ m_audio_regs[AUDIO_CHANNEL_ENV_MODE] = 0x3f;
-WRITE_LINE_MEMBER(spg2xx_device::timerirq_w)
-{
- m_cpu->set_state_unsynced(UNSP_IRQ2_LINE, state);
+ m_audio_beat->adjust(attotime::from_ticks(4, 281250), 0, attotime::from_ticks(4, 281250));
}
-WRITE_LINE_MEMBER(spg2xx_device::uartirq_w)
-{
- m_cpu->set_state_unsynced(UNSP_IRQ3_LINE, state);
-}
-WRITE_LINE_MEMBER(spg2xx_device::extirq_w)
-{
- m_cpu->set_state_unsynced(UNSP_IRQ5_LINE, state);
-}
+/*************************
+* Video Hardware *
+*************************/
-WRITE_LINE_MEMBER(spg2xx_device::ffreq1_w)
+inline uint8_t spg2xx_device::expand_rgb5_to_rgb8(uint8_t val)
{
- m_cpu->set_state_unsynced(UNSP_IRQ6_LINE, state);
+ uint8_t temp = val & 0x1f;
+ return (temp << 3) | (temp >> 2);
}
-WRITE_LINE_MEMBER(spg2xx_device::ffreq2_w)
+// Perform a lerp between a and b
+inline uint8_t spg2xx_device::mix_channel(uint8_t bottom, uint8_t top)
{
- m_cpu->set_state_unsynced(UNSP_IRQ7_LINE, state);
+ uint8_t alpha = (m_video_regs[0x2a] & 3) << 6;
+ return ((256 - alpha) * bottom + alpha * top) >> 8;
}
-
-
-READ16_MEMBER(spg2xx_device::space_r)
+void spg2xx_device::mix_pixel(uint32_t offset, uint16_t rgb)
{
- address_space &cpuspace = m_cpu->space(AS_PROGRAM);
- return cpuspace.read_word(offset);
+ m_screenbuf[offset].r = mix_channel(m_screenbuf[offset].r, expand_rgb5_to_rgb8(rgb >> 10));
+ m_screenbuf[offset].g = mix_channel(m_screenbuf[offset].g, expand_rgb5_to_rgb8(rgb >> 5));
+ m_screenbuf[offset].b = mix_channel(m_screenbuf[offset].b, expand_rgb5_to_rgb8(rgb));
}
-/*************************
-* Video Hardware *
-*************************/
-
-// Perform a lerp between a and b
-inline uint8_t spg2xx_device::mix_channel(uint8_t bottom, uint8_t top)
+void spg2xx_device::set_pixel(uint32_t offset, uint16_t rgb)
{
- uint8_t alpha = (m_video_regs[0x2a] & 3) << 6;
- return ((256 - alpha) * bottom + alpha * top) >> 8;
+ m_screenbuf[offset].r = expand_rgb5_to_rgb8(rgb >> 10);
+ m_screenbuf[offset].g = expand_rgb5_to_rgb8(rgb >> 5);
+ m_screenbuf[offset].b = expand_rgb5_to_rgb8(rgb);
}
-template<spg2xx_device::blend_enable_t Blend, spg2xx_device::rowscroll_enable_t RowScroll, spg2xx_device::flipx_t FlipX>
-void spg2xx_device::blit(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t attr, uint32_t ctrl, uint32_t bitmap_addr, uint16_t tile)
+void spg2xx_device::blit(const rectangle &cliprect, uint32_t xoff, uint32_t yoff, uint32_t attr, uint32_t ctrl, uint32_t bitmap_addr, uint16_t tile)
{
address_space &space = m_cpu->space(AS_PROGRAM);
- int32_t h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
- int32_t w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
+ uint32_t h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
+ uint32_t w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
uint32_t yflipmask = attr & TILE_Y_FLIP ? h - 1 : 0;
+ uint32_t xflipmask = attr & TILE_X_FLIP ? w - 1 : 0;
uint32_t nc = ((attr & 0x0003) + 1) << 1;
uint32_t palette_offset = (attr & 0x0f00) >> 4;
- if (SPG_DEBUG_VIDEO && m_debug_blit)
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
{
- printf("s:%d line:%d xy:%08x,%08x attr:%08x ctrl:%08x bitmap_addr:%08x tile:%04x\n", cliprect.min_x, line, xoff, yoff, attr, ctrl, bitmap_addr, tile);
- printf("hw:%d,%d f:%d,%d yfm:%d ncols:%d pobs:%02x ", w, h, (attr & TILE_X_FLIP) ? 1 : 0, (attr & TILE_Y_FLIP) ? 1 : 0, yflipmask, nc, palette_offset);
+ printf("xy:%08x,%08x attr:%08x ctrl:%08x bitmap_addr:%08x tile:%04x\n", xoff, yoff, attr, ctrl, bitmap_addr, tile);
+ printf("hw:%d,%d f:%d,%d fm:%d,%d ncols:%d pobs:%02x ", w, h, (attr & TILE_X_FLIP) ? 1 : 0, (attr & TILE_Y_FLIP) ? 1 : 0, xflipmask, yflipmask, nc, palette_offset);
}
palette_offset >>= nc;
palette_offset <<= nc;
- if (SPG_DEBUG_VIDEO && m_debug_blit)
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
{
printf("poas:%02x\n", palette_offset);
}
- uint32_t bits_per_row = nc * w / 16;
- uint32_t words_per_tile = bits_per_row * h;
- uint32_t m = bitmap_addr + words_per_tile * tile + bits_per_row * (line ^ yflipmask);
+ uint32_t m = bitmap_addr + nc * w*h / 16 * tile;
uint32_t bits = 0;
uint32_t nbits = 0;
- uint32_t y = line;
-
- int yy = (yoff + y) & 0x1ff;
- if (yy >= 0x01c0)
- yy -= 0x0200;
- if (yy > 240 || yy < 0)
- return;
-
- if (SPG_DEBUG_VIDEO && m_debug_blit)
- printf("%3d:\n", yy);
-
- int y_index = yy * 320;
-
- for (int32_t x = FlipX ? (w - 1) : 0; FlipX ? x >= 0 : x < w; FlipX ? x-- : x++)
+ for (uint32_t y = 0; y < h; y++)
{
- int xx = xoff + x;
+ int yy = (yoff + (y ^ yflipmask)) & 0x1ff;
+ if (yy >= 0x01c0)
+ yy -= 0x0200;
- bits <<= nc;
- if (SPG_DEBUG_VIDEO && m_debug_blit)
- printf(" %08x:%d ", bits, nbits);
- if (nbits < nc)
- {
- uint16_t b = space.read_word(m++ & 0x3fffff);
- b = (b << 8) | (b >> 8);
- bits |= b << (nc - nbits);
- nbits += 16;
- if (SPG_DEBUG_VIDEO && m_debug_blit)
- printf("(%04x:%08x:%d) ", b, bits, nbits);
- }
- nbits -= nc;
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
+ printf("%3d:\n", yy);
- uint32_t pal = palette_offset + (bits >> 16);
- if (SPG_DEBUG_VIDEO && m_debug_blit)
- printf("%02x:%02x:%04x ", bits >> 16, pal, bits & 0xffff);
- bits &= 0xffff;
+ for (uint32_t x = 0; x < w; x++)
+ {
+ int xx = xoff + (x ^ xflipmask);
- if (RowScroll)
- xx -= (int16_t)m_scrollram[(yy + m_rowscrolloffset) & 0x1ff];
+ bits <<= nc;
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
+ printf(" %08x:%d ", bits, nbits);
+ if (nbits < nc)
+ {
+ uint16_t b = space.read_word(m++ & 0x3fffff);
+ b = (b << 8) | (b >> 8);
+ bits |= b << (nc - nbits);
+ nbits += 16;
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
+ printf("(%04x:%08x:%d) ", b, bits, nbits);
+ }
+ nbits -= nc;
- xx &= 0x01ff;
- if (xx >= 0x01c0)
- xx -= 0x0200;
+ uint32_t pal = palette_offset + (bits >> 16);
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
+ printf("%02x:%02x:%04x ", bits >> 16, pal, bits & 0xffff);
+ bits &= 0xffff;
- if (xx >= 0 && xx < 320)
- {
- int pix_index = xx + y_index;
+ if ((ctrl & 0x0010) && yy < 240)
+ xx -= (int16_t)m_scrollram[yy + 15];
- uint16_t rgb = m_paletteram[pal];
- if (SPG_DEBUG_VIDEO && m_debug_blit)
- printf("rgb:%04x ", rgb);
+ xx &= 0x01ff;
+ if (xx >= 0x01c0)
+ xx -= 0x0200;
- if (!(rgb & 0x8000))
+ if (xx >= 0 && xx < 320 && yy >= 0 && yy < 240)
{
- if (Blend)
+ uint16_t rgb = m_paletteram[pal];
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
+ printf("rgb:%04x ", rgb);
+ if (!(rgb & 0x8000))
{
- if (SPG_DEBUG_VIDEO && m_debug_blit)
- printf("M\n");
- m_screenbuf[pix_index] = (mix_channel((uint8_t)(m_screenbuf[pix_index] >> 16), m_rgb5_to_rgb8[(rgb >> 10) & 0x1f]) << 16) |
- (mix_channel((uint8_t)(m_screenbuf[pix_index] >> 8), m_rgb5_to_rgb8[(rgb >> 5) & 0x1f]) << 8) |
- (mix_channel((uint8_t)(m_screenbuf[pix_index] >> 0), m_rgb5_to_rgb8[rgb & 0x1f]));
+ if (attr & 0x4000 || ctrl & 0x0100)
+ {
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
+ printf("M\n");
+ mix_pixel(xx + 320 * yy, rgb);
+ }
+ else
+ {
+ if (m_debug_blit && SPG_DEBUG_VIDEO)
+ printf("S\n");
+ set_pixel(xx + 320 * yy, rgb);
+ }
}
- else
+ else if (m_debug_blit && SPG_DEBUG_VIDEO)
{
- if (SPG_DEBUG_VIDEO && m_debug_blit)
- printf("S\n");
- m_screenbuf[pix_index] = m_rgb555_to_rgb888[rgb];
+ printf("X\n");
}
}
- else if (SPG_DEBUG_VIDEO && m_debug_blit)
- {
- printf("X\n");
- }
}
}
}
-void spg2xx_device::blit_page(const rectangle &cliprect, uint32_t scanline, int depth, uint32_t bitmap_addr, uint16_t *regs)
+void spg2xx_device::blit_page(const rectangle &cliprect, int depth, uint32_t bitmap_addr, uint16_t *regs)
{
uint32_t xscroll = regs[0];
uint32_t yscroll = regs[1];
@@ -325,98 +322,62 @@ void spg2xx_device::blit_page(const rectangle &cliprect, uint32_t scanline, int
return;
}
- uint32_t tile_h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
- uint32_t tile_w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
-
- uint32_t tile_count_x = 512 / tile_w;
+ uint32_t h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
+ uint32_t w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
- uint32_t bitmap_y = (scanline + yscroll) & 0xff;
- uint32_t y0 = bitmap_y / tile_h;
- uint32_t tile_scanline = bitmap_y % tile_h;
- uint32_t tile_address = tile_count_x * y0;
- if (SPG_DEBUG_VIDEO && machine().input().code_pressed(KEYCODE_H))
- printf("s:%3d | baddr:%08x | yscr:%3d | bity:%3d | y0:%2d | ts:%2d\n", scanline, bitmap_addr, yscroll, bitmap_y, y0, tile_scanline);
+ uint32_t hn = 256 / h;
+ uint32_t wn = 512 / w;
- if (SPG_DEBUG_VIDEO && machine().input().code_pressed(KEYCODE_EQUALS))
- m_debug_blit = true;
- for (uint32_t x0 = 0; x0 < tile_count_x; x0++, tile_address++)
+ for (uint32_t y0 = 0; y0 < hn; y0++)
{
- uint32_t yy = ((tile_h * y0 - yscroll + 0x10) & 0xff) - 0x10;
- uint32_t xx = (tile_w * x0 - xscroll) & 0x1ff;
- uint16_t tile = (ctrl & PAGE_WALLPAPER_MASK) ? space.read_word(tilemap) : space.read_word(tilemap + tile_address);
- uint16_t palette = 0;
+ for (uint32_t x0 = 0; x0 < wn; x0++)
+ {
+ uint16_t tile = (ctrl & PAGE_WALLPAPER_MASK) ? space.read_word(tilemap) : space.read_word(tilemap + x0 + wn * y0);
+ uint16_t palette = 0;
+ uint32_t xx, yy;
- if (!tile)
- continue;
+ if (!tile)
+ {
+ continue;
+ }
- palette = (ctrl & PAGE_WALLPAPER_MASK) ? space.read_word(palette_map) : space.read_word(palette_map + tile_address / 2);
- if (x0 & 1)
- palette >>= 8;
+ palette = space.read_word(palette_map + (x0 + wn * y0) / 2);
+ if (x0 & 1)
+ {
+ palette >>= 8;
+ }
- uint32_t tileattr = attr;
- uint32_t tilectrl = ctrl;
- if ((ctrl & 2) == 0)
- { // -(1) bld(1) flip(2) pal(4)
- tileattr &= ~0x000c;
- tileattr |= (palette >> 2) & 0x000c; // flip
+ uint32_t tileattr = attr;
+ uint32_t tilectrl = ctrl;
+ if ((ctrl & 2) == 0)
+ { // -(1) bld(1) flip(2) pal(4)
+ tileattr &= ~0x000c;
+ tileattr |= (palette >> 2) & 0x000c; // flip
- tileattr &= ~0x0f00;
- tileattr |= (palette << 8) & 0x0f00; // palette
+ tileattr &= ~0x0f00;
+ tileattr |= (palette << 8) & 0x0f00; // palette
- tilectrl &= ~0x0100;
- tilectrl |= (palette << 2) & 0x0100; // blend
- }
+ tilectrl &= ~0x0100;
+ tilectrl |= (palette << 2) & 0x0100; // blend
+ }
- bool blend = (tileattr & 0x4000 || tilectrl & 0x0100);
- bool row_scroll = (tilectrl & 0x0010);
- bool flip_x = (tileattr & TILE_X_FLIP);
+ yy = ((h*y0 - yscroll + 0x10) & 0xff) - 0x10;
+ xx = (w*x0 - xscroll) & 0x1ff;
- if (blend)
- {
- if (row_scroll)
- {
- if (flip_x)
- blit<BlendOn, RowScrollOn, FlipXOn>(cliprect, tile_scanline, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
- else
- blit<BlendOn, RowScrollOn, FlipXOff>(cliprect, tile_scanline, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
- }
- else
- {
- if (flip_x)
- blit<BlendOn, RowScrollOff, FlipXOn>(cliprect, tile_scanline, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
- else
- blit<BlendOn, RowScrollOff, FlipXOff>(cliprect, tile_scanline, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
- }
- }
- else
- {
- if (row_scroll)
- {
- if (flip_x)
- blit<BlendOff, RowScrollOn, FlipXOn>(cliprect, tile_scanline, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
- else
- blit<BlendOff, RowScrollOn, FlipXOff>(cliprect, tile_scanline, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
- }
- else
- {
- if (flip_x)
- blit<BlendOff, RowScrollOff, FlipXOn>(cliprect, tile_scanline, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
- else
- blit<BlendOff, RowScrollOff, FlipXOff>(cliprect, tile_scanline, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
- }
+ blit(cliprect, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
}
}
- if (SPG_DEBUG_VIDEO && machine().input().code_pressed(KEYCODE_EQUALS))
- m_debug_blit = false;
}
-void spg2xx_device::blit_sprite(const rectangle &cliprect, uint32_t scanline, int depth, uint32_t base_addr)
+void spg2xx_device::blit_sprite(const rectangle &cliprect, int depth, uint32_t base_addr)
{
+ address_space &space = m_cpu->space(AS_PROGRAM);
uint32_t bitmap_addr = 0x40 * m_video_regs[0x22];
- uint16_t tile = m_spriteram[base_addr + 0];
- int16_t x = m_spriteram[base_addr + 1];
- int16_t y = m_spriteram[base_addr + 2];
- uint16_t attr = m_spriteram[base_addr + 3];
+
+ uint16_t tile = space.read_word(base_addr + 0);
+ int16_t x = space.read_word(base_addr + 1);
+ int16_t y = space.read_word(base_addr + 2);
+ uint16_t attr = space.read_word(base_addr + 3);
if (!tile)
{
@@ -428,68 +389,32 @@ void spg2xx_device::blit_sprite(const rectangle &cliprect, uint32_t scanline, in
return;
}
- const uint32_t h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
- const uint32_t w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
-
if (!(m_video_regs[0x42] & SPRITE_COORD_TL_MASK))
{
- x = (160 + x) - w / 2;
- y = (120 - y) - (h / 2) + 8;
- }
+ x = 160 + x;
+ y = 120 - y;
- x &= 0x01ff;
- y &= 0x01ff;
+ uint32_t h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
+ uint32_t w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);
- uint32_t tile_line = ((scanline - y) + 0x200) % h;
- int16_t test_y = (y + tile_line) & 0x1ff;
- if (test_y >= 0x01c0)
- test_y -= 0x0200;
-
- if (test_y != scanline)
- {
- return;
+ x -= (w / 2);
+ y -= (h / 2) - 8;
}
- bool blend = (attr & 0x4000);
- bool flip_x = (attr & TILE_X_FLIP);
+ x &= 0x01ff;
+ y &= 0x01ff;
#if SPG_DEBUG_VIDEO
if (m_debug_sprites && machine().input().code_pressed(KEYCODE_MINUS))
m_debug_blit = true;
- if (blend)
- {
- if (flip_x)
- blit<BlendOn, RowScrollOff, FlipXOn>(cliprect, tile_line, x, y, attr, 0, bitmap_addr, tile);
- else
- blit<BlendOn, RowScrollOff, FlipXOff>(cliprect, tile_line, x, y, attr, 0, bitmap_addr, tile);
- }
- else
- {
- if (flip_x)
- blit<BlendOff, RowScrollOff, FlipXOn>(cliprect, tile_line, x, y, attr, 0, bitmap_addr, tile);
- else
- blit<BlendOff, RowScrollOff, FlipXOff>(cliprect, tile_line, x, y, attr, 0, bitmap_addr, tile);
- }
+ blit(cliprect, x, y, attr, 0, bitmap_addr, tile);
m_debug_blit = false;
#else
- if (blend)
- {
- if (flip_x)
- blit<BlendOn, RowScrollOff, FlipXOn>(cliprect, tile_line, x, y, attr, 0, bitmap_addr, tile);
- else
- blit<BlendOn, RowScrollOff, FlipXOff>(cliprect, tile_line, x, y, attr, 0, bitmap_addr, tile);
- }
- else
- {
- if (flip_x)
- blit<BlendOff, RowScrollOff, FlipXOn>(cliprect, tile_line, x, y, attr, 0, bitmap_addr, tile);
- else
- blit<BlendOff, RowScrollOff, FlipXOff>(cliprect, tile_line, x, y, attr, 0, bitmap_addr, tile);
- }
+ blit(cliprect, x, y, attr, 0, bitmap_addr, tile);
#endif
}
-void spg2xx_device::blit_sprites(const rectangle &cliprect, uint32_t scanline, int depth)
+void spg2xx_device::blit_sprites(const rectangle &cliprect, int depth)
{
if (!(m_video_regs[0x42] & SPRITE_ENABLE_MASK))
{
@@ -502,13 +427,13 @@ void spg2xx_device::blit_sprites(const rectangle &cliprect, uint32_t scanline, i
#endif
for (uint32_t n = 0; n < m_sprite_limit; n++)
{
- blit_sprite(cliprect, scanline, depth, 4 * n);
+ blit_sprite(cliprect, depth, 0x2c00 + 4 * n);
}
#if SPG_DEBUG_VIDEO
}
else
{
- blit_sprite(cliprect, scanline, depth, 4 * m_sprite_index_to_debug);
+ blit_sprite(cliprect, depth, 0x2c00 + 4 * m_sprite_index_to_debug);
}
#endif
}
@@ -522,13 +447,12 @@ void spg2xx_device::apply_saturation(const rectangle &cliprect)
const float sat_adjust = (0xff - (m_video_regs[0x3c] & 0x00ff)) / (float)(0xff - 0x20);
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
- uint32_t *src = &m_screenbuf[cliprect.min_x + 320 * y];
+ rgbtriad_t *src = &m_screenbuf[cliprect.min_x + 320 * y];
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
- const uint32_t src_rgb = *src;
- const float src_r = (uint8_t)(src_rgb >> 16) * s_u8_to_float;
- const float src_g = (uint8_t)(src_rgb >> 8) * s_u8_to_float;
- const float src_b = (uint8_t)(src_rgb >> 0) * s_u8_to_float;
+ const float src_r = src->r * s_u8_to_float;
+ const float src_g = src->g * s_u8_to_float;
+ const float src_b = src->b * s_u8_to_float;
const float luma = src_r * s_gray_r + src_g * s_gray_g + src_b * s_gray_b;
const float adjusted_r = luma + (src_r - luma) * sat_adjust;
const float adjusted_g = luma + (src_g - luma) * sat_adjust;
@@ -536,55 +460,50 @@ void spg2xx_device::apply_saturation(const rectangle &cliprect)
const int integer_r = (int)floor(adjusted_r * 255.0f);
const int integer_g = (int)floor(adjusted_g * 255.0f);
const int integer_b = (int)floor(adjusted_b * 255.0f);
- *src++ = (integer_r > 255 ? 0xff0000 : (integer_r < 0 ? 0 : ((uint8_t)integer_r << 16))) |
- (integer_g > 255 ? 0x00ff00 : (integer_g < 0 ? 0 : ((uint8_t)integer_g << 8))) |
- (integer_b > 255 ? 0x0000ff : (integer_b < 0 ? 0 : (uint8_t)integer_b));
+ src->r = integer_r > 255 ? 255 : (integer_r < 0 ? 0 : (uint8_t)integer_r);
+ src->g = integer_g > 255 ? 255 : (integer_g < 0 ? 0 : (uint8_t)integer_g);
+ src->b = integer_b > 255 ? 255 : (integer_b < 0 ? 0 : (uint8_t)integer_b);
+ src++;
}
}
}
void spg2xx_device::apply_fade(const rectangle &cliprect)
{
- const uint16_t fade_offset = m_video_regs[0x30];
+ const uint16_t fade_offset = m_video_regs[0x30] << 1;
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
- uint32_t *src = &m_screenbuf[cliprect.min_x + 320 * y];
+ rgbtriad_t *src = &m_screenbuf[cliprect.min_x + 320 * y];
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
- const uint32_t src_rgb = *src;
- const uint8_t src_r = (src_rgb >> 16) & 0xff;
- const uint8_t src_g = (src_rgb >> 8) & 0xff;
- const uint8_t src_b = (src_rgb >> 0) & 0xff;
- const uint8_t r = src_r - fade_offset;
- const uint8_t g = src_g - fade_offset;
- const uint8_t b = src_b - fade_offset;
- *src++ = (r > src_r ? 0 : (r << 16)) |
- (g > src_g ? 0 : (g << 8)) |
- (b > src_b ? 0 : (b << 0));
+ const uint16_t r = (uint16_t)src->r - fade_offset;
+ const uint16_t g = (uint16_t)src->g - fade_offset;
+ const uint16_t b = (uint16_t)src->b - fade_offset;
+ src->r = (r > src->r ? 0 : r);
+ src->g = (g > src->g ? 0 : g);
+ src->b = (b > src->b ? 0 : b);
+ src++;
}
}
}
uint32_t spg2xx_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- memset(&m_screenbuf[320 * cliprect.min_y], 0, 4 * 320 * ((cliprect.max_y - cliprect.min_y) + 1));
+ memset(&m_screenbuf[320 * cliprect.min_y], 0, 3 * 320 * ((cliprect.max_y - cliprect.min_y) + 1));
const uint32_t page1_addr = 0x40 * m_video_regs[0x20];
const uint32_t page2_addr = 0x40 * m_video_regs[0x21];
uint16_t *page1_regs = m_video_regs + 0x10;
uint16_t *page2_regs = m_video_regs + 0x16;
- for (uint32_t scanline = (uint32_t)cliprect.min_y; scanline <= (uint32_t)cliprect.max_y; scanline++)
+ for (int i = 0; i < 4; i++)
{
- for (int i = 0; i < 4; i++)
- {
- if (!SPG_DEBUG_VIDEO || !m_hide_page0)
- blit_page(cliprect, scanline, i, page1_addr, page1_regs);
- if (!SPG_DEBUG_VIDEO || !m_hide_page1)
- blit_page(cliprect, scanline, i, page2_addr, page2_regs);
- if (!SPG_DEBUG_VIDEO || !m_hide_sprites)
- blit_sprites(cliprect, scanline, i);
- }
+ if (!m_hide_page0)
+ blit_page(cliprect, i, page1_addr, page1_regs);
+ if (!m_hide_page1)
+ blit_page(cliprect, i, page2_addr, page2_regs);
+ if (!m_hide_sprites)
+ blit_sprites(cliprect, i);
}
if ((m_video_regs[0x3c] & 0x00ff) != 0x0020)
@@ -597,30 +516,15 @@ uint32_t spg2xx_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma
apply_fade(cliprect);
}
+ bitmap.fill(0, cliprect);
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
uint32_t *dest = &bitmap.pix32(y, cliprect.min_x);
- uint32_t *src = &m_screenbuf[cliprect.min_x + 320 * y];
- memcpy(dest, src, sizeof(uint32_t) * ((cliprect.max_x - cliprect.min_x) + 1));
- }
-
- if (SPG_DEBUG_VIDEO && m_debug_palette)
- {
- for (int y = cliprect.min_y; y <= cliprect.max_y && y < 128; y++)
+ rgbtriad_t *src = &m_screenbuf[cliprect.min_x + 320 * y];
+ for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
- const uint16_t high_nybble = (y / 8) << 4;
- uint32_t *dest = &bitmap.pix32(y, cliprect.min_x);
- for (int x = cliprect.min_x; x <= cliprect.max_x && x < 256; x++)
- {
- const uint16_t low_nybble = x / 16;
- const uint16_t palette_entry = high_nybble | low_nybble;
- const uint16_t color = m_paletteram[palette_entry];
- if (!(color & 0x8000))
- {
- *dest = m_rgb555_to_rgb888[color & 0x7fff];
- }
- dest++;
- }
+ *dest++ = (src->r << 16) | (src->g << 8) | src->b;
+ src++;
}
}
@@ -632,22 +536,15 @@ void spg2xx_device::do_sprite_dma(uint32_t len)
address_space &mem = m_cpu->space(AS_PROGRAM);
uint32_t src = m_video_regs[0x70] & 0x3fff;
- uint32_t dst = m_video_regs[0x71];
+ uint32_t dst = (m_video_regs[0x71] & 0x3ff) + 0x2c00;
for (uint32_t j = 0; j < len; j++)
{
- m_spriteram[(dst + j) & 0x3ff] = mem.read_word(src + j);
+ mem.write_word(dst + j, mem.read_word(src + j));
}
m_video_regs[0x72] = 0;
- if (VIDEO_IRQ_ENABLE & 4)
- {
- const uint16_t old = VIDEO_IRQ_STATUS;
- VIDEO_IRQ_STATUS |= 4;
- const uint16_t changed = old ^ (VIDEO_IRQ_ENABLE & VIDEO_IRQ_STATUS);
- if (changed)
- check_video_irq();
- }
+ VIDEO_IRQ_STATUS |= 4;
}
READ16_MEMBER(spg2xx_device::video_r)
@@ -841,12 +738,9 @@ WRITE16_MEMBER(spg2xx_device::video_w)
break;
case 0x72: // Sprite DMA Length
- {
LOGMASKED(LOG_DMA, "video_w: Sprite DMA Length = %04x\n", data & 0x03ff);
- uint16_t length = data & 0x3ff;
- do_sprite_dma(length ? length : 0x400);
+ do_sprite_dma(data & 0x3ff);
break;
- }
default:
LOGMASKED(LOG_UNKNOWN_PPU, "video_w: Unknown register %04x = %04x\n", 0x2800 + offset, data);
@@ -858,12 +752,7 @@ WRITE16_MEMBER(spg2xx_device::video_w)
WRITE_LINE_MEMBER(spg2xx_device::vblank)
{
if (!state)
- {
- VIDEO_IRQ_STATUS &= ~1;
- LOGMASKED(LOG_IRQS, "Setting video IRQ status to %04x\n", VIDEO_IRQ_STATUS);
- check_video_irq();
return;
- }
#if SPG_DEBUG_VIDEO
if (machine().input().code_pressed_once(KEYCODE_5))
@@ -878,22 +767,38 @@ WRITE_LINE_MEMBER(spg2xx_device::vblank)
m_sprite_index_to_debug--;
if (machine().input().code_pressed_once(KEYCODE_0))
m_sprite_index_to_debug++;
- if (machine().input().code_pressed_once(KEYCODE_L))
- m_debug_palette = !m_debug_palette;
#endif
- if (VIDEO_IRQ_ENABLE & 1)
+#if SPG_DEBUG_AUDIO
+ if (machine().input().code_pressed_once(KEYCODE_3))
+ m_debug_samples = !m_debug_samples;
+ if (machine().input().code_pressed_once(KEYCODE_4))
+ m_debug_rates = !m_debug_rates;
+ if (machine().input().code_pressed_once(KEYCODE_1))
{
- VIDEO_IRQ_STATUS |= 1;
- LOGMASKED(LOG_IRQS, "Setting video IRQ status to %04x\n", VIDEO_IRQ_STATUS);
- check_video_irq();
+ m_channel_debug--;
+ if (m_channel_debug < -1)
+ m_channel_debug = 15;
}
+ if (machine().input().code_pressed_once(KEYCODE_2))
+ {
+ m_channel_debug++;
+ if (m_channel_debug == 16)
+ m_channel_debug = -1;
+ }
+#endif
+
+ const uint16_t old = VIDEO_IRQ_ENABLE & VIDEO_IRQ_STATUS;
+ VIDEO_IRQ_STATUS |= 1;
+ LOGMASKED(LOG_IRQS, "Setting video IRQ status to %04x\n", VIDEO_IRQ_STATUS);
+ const uint16_t changed = old ^ (VIDEO_IRQ_ENABLE & VIDEO_IRQ_STATUS);
+ if (changed)
+ check_video_irq();
}
void spg2xx_device::check_video_irq()
{
- LOGMASKED(LOG_IRQS, "%ssserting IRQ0 (%04x, %04x)\n", (VIDEO_IRQ_STATUS & VIDEO_IRQ_ENABLE) ? "A" : "Dea", VIDEO_IRQ_STATUS, VIDEO_IRQ_ENABLE);
- m_cpu->set_state_unsynced(UNSP_IRQ0_LINE, (VIDEO_IRQ_STATUS & VIDEO_IRQ_ENABLE) ? ASSERT_LINE : CLEAR_LINE);
+ m_cpu->set_input_line(UNSP_IRQ0_LINE, (VIDEO_IRQ_STATUS & VIDEO_IRQ_ENABLE) ? ASSERT_LINE : CLEAR_LINE);
}
@@ -901,66 +806,588 @@ void spg2xx_device::check_video_irq()
* Machine Hardware *
*************************/
-READ16_MEMBER(spg2xx_device::dma_r)
+void spg2xx_device::uart_rx(uint8_t data)
{
- uint16_t val = m_dma_regs[offset];
+ if (!m_uart_rx_available)
+ {
+ if (BIT(m_io_regs[0x30], 6))
+ {
+ m_io_regs[0x36] = data;
+ if (BIT(m_io_regs[0x30], 0))
+ {
+ IO_IRQ_STATUS |= 0x0100;
+ check_irqs(0x0100);
+ }
+ m_uart_rx_available = true;
+ }
+ }
+ else if (m_uart_rx_fifo_count == ARRAY_LENGTH(m_uart_rx_fifo))
+ {
+ m_io_regs[0x37] |= 0x4000;
+ }
+ else
+ {
+ m_uart_rx_fifo[m_uart_rx_fifo_end] = data;
+ m_uart_rx_fifo_end = (m_uart_rx_fifo_end + 1) % ARRAY_LENGTH(m_uart_rx_fifo);
+ m_uart_rx_fifo_count++;
+ }
+}
+
+READ16_MEMBER(spg2xx_device::io_r)
+{
+ static const char *const gpioregs[] = { "GPIO Data Port", "GPIO Buffer Port", "GPIO Direction Port", "GPIO Attribute Port", "GPIO IRQ/Latch Port" };
+ static const char gpioports[] = { 'A', 'B', 'C' };
+
+ uint16_t val = m_io_regs[offset];
+
switch (offset)
{
+ case 0x01: case 0x06: case 0x0b: // GPIO Data Port A/B/C
+ do_gpio(offset);
+ LOGMASKED(LOG_GPIO, "io_r: %s %c = %04x\n", gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], m_io_regs[offset]);
+ val = m_io_regs[offset];
+ break;
+
+ case 0x02: case 0x03: case 0x04: case 0x05:
+ case 0x07: case 0x08: case 0x09: case 0x0a:
+ case 0x0c: case 0x0d: case 0x0e: case 0x0f: // Other GPIO regs
+ LOGMASKED(LOG_GPIO, "io_r: %s %c = %04x\n", gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], m_io_regs[offset]);
+ break;
+
+ case 0x10: // Timebase Control
+ LOGMASKED(LOG_IO_READS, "io_r: Timebase Control = %04x\n", val);
+ break;
- case 0x000: // DMA Source (L)
- LOGMASKED(LOG_DMA, "dma_r: DMA Source (lo) = %04x\n", val);
+ case 0x1c: // Video line counter
+ val = m_screen->vpos();
+ LOGMASKED(LOG_VLINES, "io_r: Video Line = %04x\n", val);
break;
- case 0x001: // DMA Source (H)
- LOGMASKED(LOG_DMA, "dma_r: DMA Source (hi) = %04x\n", val);
+ case 0x20: // System Control
+ LOGMASKED(LOG_IO_READS, "io_r: System Control = %04x\n", val);
break;
- case 0x002: // DMA Length
- LOGMASKED(LOG_DMA, "dma_r: DMA Length = %04x\n", 0);
+ case 0x21: // IRQ Control
+ LOGMASKED(LOG_IRQS, "io_r: I/O IRQ Control = %04x\n", val);
+ break;
+
+ case 0x22: // IRQ Status
+ LOGMASKED(LOG_IRQS, "io_r: I/O IRQ Status = %04x\n", val);
+ break;
+
+ case 0x23: // External Memory Control
+ LOGMASKED(LOG_IO_READS, "io_r: Ext. Memory Control = %04x\n", val);
+ break;
+
+ case 0x25: // ADC Control
+ LOGMASKED(LOG_IO_READS, "io_r: ADC Control = %04x\n", val);
+ break;
+
+ case 0x27: // ADC Data
+ m_io_regs[0x27] = 0;
+ LOGMASKED(LOG_IO_READS, "io_r: ADC Data = %04x\n", val);
+ break;
+
+ case 0x29: // Wakeup Source
+ LOGMASKED(LOG_IO_READS, "io_r: Wakeup Source = %04x\n", val);
+ break;
+
+ case 0x2b:
+ LOGMASKED(LOG_IO_READS, "io_r: NTSC/PAL = %04x\n", m_pal_flag);
+ return m_pal_flag;
+
+ case 0x2c: case 0x2d: // PRNG 0/1
+ val = machine().rand() & 0x0000ffff;
+ LOGMASKED(LOG_IO_READS, "io_r: PRNG %d = %04x\n", offset - 0x2c, val);
+ break;
+
+ case 0x2e: // FIQ Source Select
+ LOGMASKED(LOG_IRQS, "io_r: FIQ Source Select = %04x\n", val);
+ break;
+
+ case 0x2f: // Data Segment
+ val = m_cpu->state_int(UNSP_SR) >> 10;
+ LOGMASKED(LOG_SEGMENT, "io_r: Data Segment = %04x\n", val);
+ break;
+
+ case 0x31: // UART Status
+ val |= (m_uart_rx_available ? 0x81 : 0);
+ LOGMASKED(LOG_UART, "io_r: UART Status = %04x\n", val);
+ break;
+
+ case 0x36: // UART RX Data
+ if (m_uart_rx_available)
+ {
+ if (m_uart_rx_fifo_count)
+ {
+ m_io_regs[0x36] = m_uart_rx_fifo[m_uart_rx_fifo_start];
+ m_uart_rx_fifo_start = (m_uart_rx_fifo_start + 1) % ARRAY_LENGTH(m_uart_rx_fifo);
+ m_uart_rx_fifo_count--;
+ }
+ else
+ {
+ m_uart_rx_available = false;
+ }
+ }
+ else
+ {
+ m_io_regs[0x37] |= 0x2000;
+ }
+ LOGMASKED(LOG_UART, "%s: io_r: UART Rx Data = %04x\n", machine().describe_context(), val);
+ break;
+
+ case 0x37: // UART Rx FIFO Control
+ val &= ~0x0070;
+ val |= (m_uart_rx_available ? 7 : 0) << 4;
+ LOGMASKED(LOG_UART, "io_r: UART Rx FIFO Control = %04x\n", val);
+ break;
+
+ case 0x59: // I2C Status
+ LOGMASKED(LOG_I2C, "io_r: I2C Status = %04x\n", val);
+ break;
+
+ case 0x5e: // I2C Data In
+ LOGMASKED(LOG_I2C, "io_r: I2C Data In = %04x\n", val);
+ break;
+
+ case 0x100: // DMA Source (L)
+ LOGMASKED(LOG_DMA, "io_r: DMA Source (lo) = %04x\n", val);
+ break;
+
+ case 0x101: // DMA Source (H)
+ LOGMASKED(LOG_DMA, "io_r: DMA Source (hi) = %04x\n", val);
+ break;
+
+ case 0x102: // DMA Length
+ LOGMASKED(LOG_DMA, "io_r: DMA Length = %04x\n", 0);
val = 0;
break;
- case 0x003: // DMA Destination
- LOGMASKED(LOG_DMA, "dma_r: DMA Dest = %04x\n", val);
+ case 0x103: // DMA Destination
+ LOGMASKED(LOG_DMA, "io_r: DMA Dest = %04x\n", val);
break;
default:
- LOGMASKED(LOG_UNKNOWN_IO, "dma_r: Unknown register %04x\n", 0x3d00 + offset);
+ LOGMASKED(LOG_UNKNOWN_IO, "io_r: Unknown register %04x\n", 0x3d00 + offset);
break;
}
return val;
}
+void spg2xx_device::update_porta_special_modes()
+{
+ static const char* const s_pa_special[4][16] =
+ {
+ // Input, Special 0
+ // Input, Special 1
+ // Output, Special 0
+ // Output, Special 1
+
+ { "LP", "ExtClk2", "ExtClk1", "-", "SDA", "SlvRDY", "-", "-", "SPICLK", "-", "RxD", "SPISSB", "-", "-", "-", "-" },
+ { "-", "-", "-", "SCK", "-", "SWS", "-", "-", "-", "-", "-", "-", "IRQ2B", "-", "-", "IRQ1B" },
+ { "-", "-", "-", "SCK", "SDA", "SWS", "-", "-", "SPICLK", "TxD", "-", "SPISSB", "TAPWM", "TM1", "TBPWM", "TM2" },
+ { "CSB3", "CSB2", "CSB1", "SCK", "SDA", "VSYNC", "HSYNC", "SYSCLK3", "SPICLK", "TxD", "SWS", "SPISSB", "-", "VSYNC", "HSYNC", "CSYNC" },
+ };
+ for (int bit = 15; bit >= 0; bit--)
+ {
+ if (!BIT(m_io_regs[0x05], bit))
+ continue;
+ uint8_t type = (BIT(m_io_regs[0x03], bit) << 1) | BIT(m_io_regs[0x00], 0);
+ LOGMASKED(LOG_GPIO, " Bit %2d: %s\n", bit, s_pa_special[type][bit]);
+ }
+}
+
+void spg2xx_device::update_portb_special_modes()
+{
+ static const char* const s_pb_special[4][8] =
+ {
+ // Input, Special 0
+ // Input, Special 1
+ // Output, Special 0
+ // Output, Special 1
+
+ { "-", "-", "-", "-", "-", "-", "SDA", "SlvRDY" },
+ { "-", "-", "-", "-", "-", "-", "SDA", "SlvRDY" },
+ { "VSYNC", "HSYNC", "CSYNC", "-", "-", "SCK", "SDA", "SWS" },
+ { "CSB3", "CSB2", "CSB1", "TBPWM", "TM2", "-", "-", "SYSCLK2" },
+ };
+ for (int bit = 7; bit >= 0; bit--)
+ {
+ if (!BIT(m_io_regs[0x0a], bit))
+ continue;
+ uint8_t type = (BIT(m_io_regs[0x08], bit) << 1) | BIT(m_io_regs[0x00], 1);
+ LOGMASKED(LOG_GPIO, " Bit %2d: %s\n", bit, s_pb_special[type][bit]);
+ }
+}
-WRITE16_MEMBER(spg2xx_device::dma_w)
+WRITE16_MEMBER(spg2xx_device::io_w)
{
+ static const char *const gpioregs[] = { "GPIO Data Port", "GPIO Buffer Port", "GPIO Direction Port", "GPIO Attribute Port", "GPIO IRQ/Latch Port" };
+ static const char gpioports[3] = { 'A', 'B', 'C' };
+
switch (offset)
{
- case 0x000: // DMA Source (lo)
- LOGMASKED(LOG_DMA, "dma_w: DMA Source (lo) = %04x\n", data);
- m_dma_regs[offset] = data;
+ case 0x00: // GPIO special function select
+ {
+ LOGMASKED(LOG_GPIO, "io_w: GPIO Configuration = %04x (IOBWake:%d, IOAWake:%d, IOBSpecSel:%d, IOASpecSel:%d)\n", data
+ , BIT(data, 4), BIT(data, 3), BIT(data, 1), BIT(data, 0));
+ const uint16_t old = m_io_regs[offset];
+ m_io_regs[offset] = data;
+ const uint16_t changed = old ^ data;
+ if (BIT(changed, 0))
+ update_porta_special_modes();
+ if (BIT(changed, 1))
+ update_portb_special_modes();
break;
+ }
- case 0x001: // DMA Source (hi)
- LOGMASKED(LOG_DMA, "dma_w: DMA Source (hi) = %04x\n", data);
- m_dma_regs[offset] = data;
+ case 0x01: case 0x06: case 0x0b: // GPIO data, port A/B/C
+ offset++;
+ // Intentional fallthrough - we redirect data register writes to the buffer register.
+
+ case 0x02: case 0x04: // Port A
+ case 0x07: case 0x09: // Port B
+ case 0x0c: case 0x0d: case 0x0e: case 0x0f: // Port C
+ LOGMASKED(LOG_GPIO, "io_w: %s %c = %04x\n", gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], data);
+ m_io_regs[offset] = data;
+ do_gpio(offset);
+ break;
+
+ case 0x03: // Port A Direction
+ LOGMASKED(LOG_GPIO, "io_w: GPIO Direction Port A = %04x\n", data);
+ m_io_regs[offset] = data;
+ update_porta_special_modes();
+ do_gpio(offset);
break;
- case 0x002: // DMA Length
- LOGMASKED(LOG_DMA, "dma_w: DMA Length = %04x\n", data);
- if (!(data & 0xc000)) // jak_dora writes 0xffff here which ends up trashing registers etc. why? such writes can't be valid
- do_cpu_dma(data);
+ case 0x08: // Port B Direction
+ LOGMASKED(LOG_GPIO, "io_w: GPIO Direction Port B = %04x\n", data);
+ m_io_regs[offset] = data;
+ update_portb_special_modes();
+ do_gpio(offset);
break;
- case 0x003: // DMA Destination
- LOGMASKED(LOG_DMA, "dma_w: DMA Dest = %04x\n", data);
- m_dma_regs[offset] = data;
+ case 0x05: // Port A Special
+ LOGMASKED(LOG_GPIO, "io_w: Port A Special Function Select: %04x\n", data);
+ m_io_regs[offset] = data;
+ update_porta_special_modes();
+ break;
+
+ case 0x0a: // Port B Special
+ LOGMASKED(LOG_GPIO, "io_w: Port B Special Function Select: %04x\n", data);
+ m_io_regs[offset] = data;
+ update_portb_special_modes();
+ break;
+
+ case 0x10: // Timebase Control
+ {
+ static const char* const s_tmb1_sel[2][4] =
+ {
+ { "8Hz", "16Hz", "32Hz", "64Hz" },
+ { "12kHz", "24kHz", "40kHz", "40kHz" }
+ };
+ static const char* const s_tmb2_sel[2][4] =
+ {
+ { "128Hz", "256Hz", "512Hz", "1024Hz" },
+ { "105kHz", "210kHz", "420kHz", "840kHz" }
+ };
+ static const uint32_t s_tmb1_freq[2][4] =
+ {
+ { 8, 16, 32, 64 },
+ { 12000, 24000, 40000, 40000 }
+ };
+ static const uint32_t s_tmb2_freq[2][4] =
+ {
+ { 128, 256, 512, 1024 },
+ { 105000, 210000, 420000, 840000 }
+ };
+ LOGMASKED(LOG_IO_WRITES, "io_w: Timebase Control = %04x (Source:%s, TMB2:%s, TMB1:%s)\n", data,
+ BIT(data, 4) ? "27MHz" : "32768Hz", s_tmb2_sel[BIT(data, 4)][(data >> 2) & 3], s_tmb1_sel[BIT(data, 4)][data & 3]);
+ const uint16_t old = m_io_regs[offset];
+ m_io_regs[offset] = data;
+ const uint16_t changed = old ^ m_io_regs[offset];
+ if (changed & 0x001f)
+ {
+ const uint8_t hifreq = BIT(data, 4);
+ if (changed & 0x0013)
+ {
+ const uint32_t freq = s_tmb1_freq[hifreq][data & 3];
+ m_tmb1->adjust(attotime::from_hz(freq), 0, attotime::from_hz(freq));
+ }
+ if (changed & 0x001c)
+ {
+ const uint32_t freq = s_tmb2_freq[hifreq][(data >> 2) & 3];
+ m_tmb2->adjust(attotime::from_hz(freq), 0, attotime::from_hz(freq));
+ }
+ }
+ break;
+ }
+
+ case 0x11: // Timebase Clear
+ LOGMASKED(LOG_IO_WRITES, "io_w: Timebase Clear = %04x\n", data);
+ break;
+
+ case 0x20: // System Control
+ {
+ static const char* const s_sysclk[4] = { "13.5MHz", "27MHz", "27MHz NoICE", "54MHz" };
+ static const char* const s_lvd_voltage[4] = { "2.7V", "2.9V", "3.1V", "3.3V" };
+ static const char* const s_weak_strong[2] = { "Weak", "Strong" };
+ LOGMASKED(LOG_IO_WRITES, "io_w: System Control = %04x (Watchdog:%d, Sleep:%d, SysClk:%s, SysClkInv:%d, LVROutEn:%d, LVREn:%d\n"
+ , data, BIT(data, 15), BIT(data, 14), s_sysclk[(data >> 12) & 3], BIT(data, 11), BIT(data, 9), BIT(data, 8));
+ LOGMASKED(LOG_IO_WRITES, " LVDEn:%d, LVDVoltSel:%s, 32kHzDisable:%d, StrWkMode:%s, VDACDisable:%d, ADACDisable:%d, ADACOutDisable:%d)\n"
+ , BIT(data, 7), s_lvd_voltage[(data >> 5) & 3], BIT(data, 4), s_weak_strong[BIT(data, 3)], BIT(data, 2), BIT(data, 1), BIT(data, 0));
+ m_io_regs[offset] = data;
+ break;
+ }
+
+ case 0x21: // IRQ Enable
+ {
+ LOGMASKED(LOG_IRQS, "io_w: IRQ Enable = %04x\n", data);
+ const uint16_t old = IO_IRQ_ENABLE & IO_IRQ_STATUS;
+ m_io_regs[offset] = data;
+ const uint16_t changed = old ^ (IO_IRQ_ENABLE & IO_IRQ_STATUS);
+ if (changed)
+ check_irqs(changed);
+ break;
+ }
+
+ case 0x22: // IRQ Acknowledge
+ {
+ LOGMASKED(LOG_IRQS, "io_w: IRQ Acknowledge = %04x\n", data);
+ const uint16_t old = IO_IRQ_STATUS;
+ IO_IRQ_STATUS &= ~data;
+ const uint16_t changed = old ^ (IO_IRQ_ENABLE & IO_IRQ_STATUS);
+ if (changed)
+ check_irqs(changed);
+ break;
+ }
+
+ case 0x23: // External Memory Control
+ {
+ static const char* const s_bus_arb[8] =
+ {
+ "Forbidden", "Forbidden", "Forbidden", "Forbidden", "Forbidden", "1:SPU/2:PPU/3:CPU", "Forbidden", "1:PPU/2:SPU/3:CPU"
+ };
+ static const char* const s_addr_decode[4] =
+ {
+ "ROMCSB: 4000-3fffff, CSB1: ---, CSB2: ---, CSB3: ---",
+ "ROMCSB: 4000-1fffff, CSB1: 200000-3fffff, CSB2: ---, CSB3: ---",
+ "ROMCSB: 4000-0fffff, CSB1: 100000-1fffff, CSB2: 200000-2fffff, CSB3: 300000-3fffff",
+ "ROMCSB: 4000-0fffff, CSB1: 100000-1fffff, CSB2: 200000-2fffff, CSB3: 300000-3fffff"
+ };
+ static const char* const s_ram_decode[16] =
+ {
+ "None", "None", "None", "None", "None", "None", "None", "None",
+ "4KW, 3ff000-3fffff\n",
+ "8KW, 3fe000-3fffff\n",
+ "16KW, 3fc000-3fffff\n",
+ "32KW, 3f8000-3fffff\n",
+ "64KW, 3f0000-3fffff\n",
+ "128KW, 3e0000-3fffff\n",
+ "256KW, 3c0000-3fffff\n",
+ "512KW, 380000-3fffff\n"
+ };
+ LOGMASKED(LOG_IO_WRITES, "io_w: Ext. Memory Control (not yet implemented) = %04x:\n", data);
+ LOGMASKED(LOG_IO_WRITES, " WaitStates:%d, BusArbPrio:%s\n", (data >> 1) & 3, s_bus_arb[(data >> 3) & 7]);
+ LOGMASKED(LOG_IO_WRITES, " ROMAddrDecode:%s\n", s_addr_decode[(data >> 6) & 3]);
+ LOGMASKED(LOG_IO_WRITES, " RAMAddrDecode:%s\n", s_ram_decode[(data >> 8) & 15]);
+ m_chip_sel((data >> 6) & 3);
+ m_io_regs[offset] = data;
+ break;
+ }
+
+ case 0x24: // Watchdog
+ LOGMASKED(LOG_WATCHDOG, "io_w: Watchdog Pet = %04x\n", data);
+ break;
+
+ case 0x25: // ADC Control
+ {
+ LOGMASKED(LOG_IO_WRITES, "io_w: ADC Control = %04x\n", data);
+ //const uint16_t changed = m_io_regs[offset] ^ data;
+ m_io_regs[offset] = data;
+ //if (BIT(changed, 12) && BIT(data, 12) && !BIT(m_io_regs[offset], 1))
+ {
+ //m_io_regs[0x27] = 0x80ff;
+ //const uint16_t old = IO_IRQ_STATUS;
+ //IO_IRQ_STATUS |= 0x2000;
+ //const uint16_t changed = IO_IRQ_STATUS ^ old;
+ //if (changed)
+ //check_irqs(changed);
+ }
+ break;
+ }
+
+ case 0x28: // Sleep Mode
+ LOGMASKED(LOG_IO_WRITES, "io_w: Sleep Mode (%s enter value) = %04x\n", data == 0xaa55 ? "valid" : "invalid", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x29: // Wakeup Source
+ {
+ m_io_regs[offset] = data;
+ static const char* const s_sources[8] =
+ {
+ "TMB1", "TMB2", "2Hz", "4Hz", "1024Hz", "2048Hz", "4096Hz", "Key"
+ };
+
+ LOGMASKED(LOG_IO_WRITES, "io_w: Wakeup Source = %04x:\n", data);
+ bool comma = false;
+ char buf[1024];
+ int char_idx = 0;
+ for (int i = 7; i >= 0; i--)
+ {
+ if (BIT(data, i))
+ {
+ char_idx += sprintf(&buf[char_idx], "%s%s", comma ? ", " : "", s_sources[i]);
+ comma = true;
+ }
+ }
+ buf[char_idx] = 0;
+ LOGMASKED(LOG_IO_WRITES, " %s\n", buf);
+ break;
+ }
+
+ case 0x2e: // FIQ Source Select
+ {
+ static const char* const s_fiq_select[8] =
+ {
+ "PPU", "SPU Channel", "Timer A", "Timer B", "UART/SPI", "External", "Reserved", "None"
+ };
+ LOGMASKED(LOG_IRQS, "io_w: FIQ Source Select (not yet implemented) = %04x, %s\n", data, s_fiq_select[data & 7]);
+ m_io_regs[offset] = data;
+ break;
+ }
+
+ case 0x2f: // Data Segment
+ {
+ uint16_t ds = m_cpu->state_int(UNSP_SR);
+ m_cpu->set_state_int(UNSP_SR, (ds & 0x03ff) | ((data & 0x3f) << 10));
+ LOGMASKED(LOG_SEGMENT, "io_w: Data Segment = %04x\n", data);
+ break;
+ }
+
+ case 0x30: // UART Control
+ {
+ static const char* const s_9th_bit[4] = { "0", "1", "Odd", "Even" };
+ LOGMASKED(LOG_UART, "io_w: UART Control = %04x (TxEn:%d, RxEn:%d, Bits:%d, MultiProc:%d, 9thBit:%s, TxIntEn:%d, RxIntEn:%d\n", data
+ , BIT(data, 7), BIT(data, 6), BIT(data, 5) ? 9 : 8, BIT(data, 4), s_9th_bit[(data >> 2) & 3], BIT(data, 1), BIT(data, 0));
+ const uint16_t changed = m_io_regs[offset] ^ data;
+ m_io_regs[offset] = data;
+ if (!BIT(data, 6))
+ {
+ m_uart_rx_available = false;
+ m_io_regs[0x36] = 0;
+ }
+ if (BIT(changed, 7) && BIT(data, 7))
+ {
+ m_io_regs[0x31] |= 0x0002;
+ }
+ break;
+ }
+
+ case 0x31: // UART Status
+ LOGMASKED(LOG_UART, "io_w: UART Status = %04x\n", data);
+ m_io_regs[offset] &= ~data;
+ break;
+
+ case 0x33: // UART Baud Rate (low byte)
+ case 0x34: // UART Baud Rate (high byte)
+ {
+ m_io_regs[offset] = data;
+ const uint32_t divisor = 16 * (0x10000 - ((m_io_regs[0x34] << 8) | m_io_regs[0x33]));
+ LOGMASKED(LOG_UART, "io_w: UART Baud Rate (%s byte): Baud rate = %d\n", offset == 0x33 ? "low" : "high", 27000000 / divisor);
+ break;
+ }
+
+ case 0x35: // UART TX Data
+ LOGMASKED(LOG_UART, "io_w: UART Tx Data = %02x\n", data & 0x00ff);
+ m_io_regs[offset] = data;
+ m_uart_tx((uint8_t)data);
+ m_io_regs[0x31] |= 2;
+ break;
+
+ case 0x36: // UART RX Data
+ LOGMASKED(LOG_UART, "io_w: UART Rx Data (read-only) = %04x\n", data);
+ break;
+
+ case 0x37: // UART Rx FIFO Control
+ LOGMASKED(LOG_UART, "io_w: UART Rx FIFO Control = %04x (Reset:%d, Overrun:%d, Underrun:%d, Count:%d, Threshold:%d)\n", data
+ , BIT(data, 15), BIT(data, 14), BIT(data, 13), (data >> 4) & 7, data & 7);
+ if (data & 0x8000)
+ {
+ m_uart_rx_available = false;
+ m_io_regs[0x36] = 0;
+ }
+ m_io_regs[offset] &= ~data & 0x6000;
+ m_io_regs[offset] &= ~0x0007;
+ m_io_regs[offset] |= data & 0x0007;
+ break;
+
+ case 0x58: // I2C Command
+ LOGMASKED(LOG_I2C, "io_w: I2C Command = %04x\n", data);
+ m_io_regs[offset] = data;
+ do_i2c();
+ break;
+
+ case 0x59: // I2C Status / Acknowledge
+ LOGMASKED(LOG_I2C, "io_w: I2C Acknowledge = %04x\n", data);
+ m_io_regs[offset] &= ~data;
+ break;
+
+ case 0x5a: // I2C Access Mode
+ LOGMASKED(LOG_I2C, "io_w: I2C Access Mode = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x5b: // I2C Device Address
+ LOGMASKED(LOG_I2C, "io_w: I2C Device Address = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x5c: // I2C Sub-Address
+ LOGMASKED(LOG_I2C, "io_w: I2C Sub-Address = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x5d: // I2C Data Out
+ LOGMASKED(LOG_I2C, "io_w: I2C Data Out = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x5e: // I2C Data In
+ LOGMASKED(LOG_I2C, "io_w: I2C Data In = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x5f: // I2C Controller Mode
+ LOGMASKED(LOG_I2C, "io_w: I2C Controller Mode = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x100: // DMA Source (lo)
+ LOGMASKED(LOG_DMA, "io_w: DMA Source (lo) = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x101: // DMA Source (hi)
+ LOGMASKED(LOG_DMA, "io_w: DMA Source (hi) = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x103: // DMA Destination
+ LOGMASKED(LOG_DMA, "io_w: DMA Dest = %04x\n", data);
+ m_io_regs[offset] = data;
+ break;
+
+ case 0x102: // DMA Length
+ LOGMASKED(LOG_DMA, "io_w: DMA Length = %04x\n", data);
+ do_cpu_dma(data);
break;
default:
- LOGMASKED(LOG_UNKNOWN_IO, "dma_w: Unknown register %04x = %04x\n", 0x3d00 + offset, data);
- m_dma_regs[offset] = data;
+ LOGMASKED(LOG_UNKNOWN_IO, "io_w: Unknown register %04x = %04x\n", 0x3d00 + offset, data);
+ m_io_regs[offset] = data;
break;
}
}
@@ -969,29 +1396,145 @@ void spg2xx_device::device_timer(emu_timer &timer, device_timer_id id, int param
{
switch (id)
{
+ case TIMER_TMB1:
+ {
+ LOGMASKED(LOG_TIMERS, "TMB1 elapsed, setting IRQ Status bit 0 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 1, IO_IRQ_ENABLE);
+ IO_IRQ_STATUS |= 1;
+ check_irqs(0x0001);
+ break;
+ }
+
+ case TIMER_TMB2:
+ {
+ LOGMASKED(LOG_TIMERS, "TMB2 elapsed, setting IRQ Status bit 1 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 2, IO_IRQ_ENABLE);
+ IO_IRQ_STATUS |= 2;
+ check_irqs(0x0002);
+ break;
+ }
+
case TIMER_SCREENPOS:
{
- if (VIDEO_IRQ_ENABLE & 2)
+ const uint16_t old = VIDEO_IRQ_ENABLE & VIDEO_IRQ_STATUS;
+ VIDEO_IRQ_STATUS |= 2;
+ const uint16_t changed = old ^ (VIDEO_IRQ_ENABLE & VIDEO_IRQ_STATUS);
+ if (changed)
{
- VIDEO_IRQ_STATUS |= 2;
check_video_irq();
}
m_screen->update_partial(m_screen->vpos());
+ break;
+ }
- // fire again, jak_dbz pinball needs this
- m_screenpos_timer->adjust(m_screen->time_until_pos(m_video_regs[0x36], m_video_regs[0x37] << 1));
+ case TIMER_BEAT:
+ {
+ audio_frame_tick();
break;
}
}
}
+void spg2xx_device::check_irqs(const uint16_t changed)
+{
+ // {
+ // m_cpu->set_input_line(UNSP_IRQ1_LINE, ASSERT_LINE);
+ // }
+
+ if (changed & 0x0c00) // Timer A, Timer B IRQ
+ {
+ LOGMASKED(LOG_IRQS, "%ssserting IRQ2 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b));
+ m_cpu->set_input_line(UNSP_IRQ2_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE);
+ }
+
+ if (changed & 0x2100) // UART, ADC IRQ
+ {
+ LOGMASKED(LOG_IRQS, "%ssserting IRQ3 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b));
+ m_cpu->set_input_line(UNSP_IRQ3_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? ASSERT_LINE : CLEAR_LINE);
+ }
+
+ if (changed & (AUDIO_BIS_MASK | AUDIO_BIE_MASK)) // Beat IRQ
+ {
+ if ((m_audio_regs[AUDIO_BEAT_COUNT] & (AUDIO_BIS_MASK | AUDIO_BIE_MASK)) == (AUDIO_BIS_MASK | AUDIO_BIE_MASK))
+ {
+ LOGMASKED(LOG_BEAT, "Asserting beat IRQ\n");
+ m_cpu->set_input_line(UNSP_IRQ4_LINE, ASSERT_LINE);
+ }
+ else
+ {
+ LOGMASKED(LOG_BEAT, "Clearing beat IRQ\n");
+ m_cpu->set_input_line(UNSP_IRQ4_LINE, CLEAR_LINE);
+ }
+ }
+
+ if (changed & 0x1200) // External IRQ
+ {
+ LOGMASKED(LOG_IRQS, "%ssserting IRQ5 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b));
+ m_cpu->set_input_line(UNSP_IRQ5_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? ASSERT_LINE : CLEAR_LINE);
+ }
+
+ if (changed & 0x0070) // 1024Hz, 2048Hz, 4096Hz IRQ
+ {
+ LOGMASKED(LOG_IRQS, "%ssserting IRQ6 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b));
+ m_cpu->set_input_line(UNSP_IRQ6_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE);
+ }
+
+ if (changed & 0x008b) // TMB1, TMB2, 4Hz, key change IRQ
+ {
+ LOGMASKED(LOG_IRQS, "%ssserting IRQ7 (%04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b));
+ m_cpu->set_input_line(UNSP_IRQ7_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? ASSERT_LINE : CLEAR_LINE);
+ }
+}
+
+void spg2xx_device::do_gpio(uint32_t offset)
+{
+ uint32_t index = (offset - 1) / 5;
+ uint16_t buffer = m_io_regs[5 * index + 2];
+ uint16_t dir = m_io_regs[5 * index + 3];
+ uint16_t attr = m_io_regs[5 * index + 4];
+ uint16_t special = m_io_regs[5 * index + 5];
+
+ uint16_t push = dir;
+ uint16_t pull = (~dir) & (~attr);
+ uint16_t what = (buffer & (push | pull));
+ what ^= (dir & ~attr);
+ what &= ~special;
+
+ switch (index)
+ {
+ case 0:
+ m_porta_out(0, what, push &~ special);
+ what = (what & ~pull) | (m_porta_in(0, pull &~ special) & pull);
+ break;
+ case 1:
+ m_portb_out(0, what, push &~ special);
+ what = (what & ~pull) | (m_portb_in(0, pull &~ special) & pull);
+ break;
+ case 2:
+ m_portc_out(0, what, push &~ special);
+ what = (what & ~pull) | (m_portc_in(0, pull &~ special) & pull);
+ break;
+ }
+
+ m_io_regs[5 * index + 1] = what;
+}
+
+void spg2xx_device::do_i2c()
+{
+ const uint16_t addr = ((m_io_regs[0x5b] & 0x06) << 7) | (uint8_t)m_io_regs[0x5c];
+
+ if (m_io_regs[0x58] & 0x40) // Serial EEPROM read
+ m_io_regs[0x5e] = m_eeprom_r(addr);
+ else
+ m_eeprom_w(addr, m_io_regs[0x5d]);
+
+ m_io_regs[0x59] |= 1;
+}
void spg2xx_device::do_cpu_dma(uint32_t len)
{
address_space &mem = m_cpu->space(AS_PROGRAM);
- uint32_t src = ((m_dma_regs[0x001] & 0x3f) << 16) | m_dma_regs[0x000];
- uint32_t dst = m_dma_regs[0x003] & 0x3fff;
+ uint32_t src = ((m_io_regs[0x101] & 0x3f) << 16) | m_io_regs[0x100];
+ uint32_t dst = m_io_regs[0x103] & 0x3fff;
for (uint32_t j = 0; j < len; j++)
{
@@ -999,56 +1542,1128 @@ void spg2xx_device::do_cpu_dma(uint32_t len)
}
src += len;
- m_dma_regs[0x000] = (uint16_t)src;
- m_dma_regs[0x001] = (src >> 16) & 0x3f;
- m_dma_regs[0x002] = 0;
- m_dma_regs[0x003] = (dst + len) & 0x3fff;
+ m_io_regs[0x100] = (uint16_t)src;
+ m_io_regs[0x101] = (src >> 16) & 0x3f;
+ m_io_regs[0x102] = 0;
+ m_io_regs[0x103] = (dst + len) & 0x3fff;
+}
+
+/***********************
+* Audio Hardware *
+***********************/
+
+READ16_MEMBER(spg2xx_device::audio_r)
+{
+ const uint16_t channel = (offset & 0x00f0) >> 4;
+ uint16_t data = m_audio_regs[offset];
+
+ if (offset >= 0x400)
+ {
+ switch (offset)
+ {
+ case AUDIO_CHANNEL_ENABLE:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Channel Enable: %04x\n", data);
+ break;
+
+ case AUDIO_MAIN_VOLUME:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Main Volume: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_FIQ_ENABLE:
+ LOGMASKED(LOG_SPU_READS | LOG_IRQS, "audio_r: Channel FIQ Enable: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_FIQ_STATUS:
+ LOGMASKED(LOG_SPU_READS | LOG_IRQS, "audio_r: Channel FIQ Acknowledge: %04x\n", data);
+ break;
+
+ case AUDIO_BEAT_BASE_COUNT:
+ LOGMASKED(LOG_SPU_READS | LOG_BEAT, "audio_r: Beat Base Count: %04x\n", data);
+ break;
+
+ case AUDIO_BEAT_COUNT:
+ LOGMASKED(LOG_SPU_READS | LOG_BEAT, "audio_r: Beat Count: %04x\n", data);
+ break;
+
+ case AUDIO_ENVCLK0:
+ case AUDIO_ENVCLK1:
+ LOGMASKED(LOG_SPU_READS | LOG_ENVELOPES, "audio_r: Envelope Interval %d (lo): %04x\n", offset == AUDIO_ENVCLK0 ? 0 : 1, data);
+ break;
+
+ case AUDIO_ENVCLK0_HIGH:
+ case AUDIO_ENVCLK1_HIGH:
+ LOGMASKED(LOG_SPU_READS | LOG_ENVELOPES, "audio_r: Envelope Interval %d (hi): %04x\n", offset == AUDIO_ENVCLK0_HIGH ? 0 : 1, data);
+ break;
+
+ case AUDIO_ENV_RAMP_DOWN:
+ LOGMASKED(LOG_SPU_READS | LOG_RAMPDOWN, "audio_r: Envelope Fast Ramp Down: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_STOP:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Channel Stop Status: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_ZERO_CROSS:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Channel Zero-Cross Enable: %04x\n", data);
+ break;
+
+ case AUDIO_CONTROL:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Control: %04x\n", data);
+ break;
+
+ case AUDIO_COMPRESS_CTRL:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Compressor Control: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_STATUS:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Channel Status: %04x\n", data);
+ break;
+
+ case AUDIO_WAVE_IN_L:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Wave In (L) / FIFO Write Data: %04x\n", data);
+ break;
+
+ case AUDIO_WAVE_IN_R:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Wave In (R) / Software Channel FIFO IRQ Control: %04x\n", data);
+ break;
+
+ case AUDIO_WAVE_OUT_L:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Wave Out (L): %04x\n", data);
+ break;
+
+ case AUDIO_WAVE_OUT_R:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Wave Out (R): %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_REPEAT:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Channel Repeat Enable: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_ENV_MODE:
+ LOGMASKED(LOG_SPU_READS | LOG_ENVELOPES, "audio_r: Channel Envelope Enable: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_TONE_RELEASE:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Channel Tone Release Enable: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_ENV_IRQ:
+ LOGMASKED(LOG_SPU_READS | LOG_IRQS, "audio_r: Channel Envelope IRQ Status: %04x\n", data);
+ break;
+
+ case AUDIO_CHANNEL_PITCH_BEND:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Channel Pitch Bend Enable: %04x\n", data);
+ break;
+
+ case AUDIO_SOFT_PHASE:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Software Channel Phase: %04x\n", data);
+ break;
+
+ case AUDIO_ATTACK_RELEASE:
+ LOGMASKED(LOG_SPU_READS, "audio_r: Attack/Release Time Control: %04x\n", data);
+ break;
+
+ case AUDIO_EQ_CUTOFF10:
+ LOGMASKED(LOG_SPU_READS, "audio_r: EQ Cutoff Frequency 0/1: %04x\n", data);
+ break;
+
+ case AUDIO_EQ_CUTOFF32:
+ LOGMASKED(LOG_SPU_READS, "audio_r: EQ Cutoff Frequency 2/3: %04x\n", data);
+ break;
+
+ case AUDIO_EQ_GAIN10:
+ LOGMASKED(LOG_SPU_READS, "audio_r: EQ Cutoff Gain 0/1: %04x\n", data);
+ break;
+
+ case AUDIO_EQ_GAIN32:
+ LOGMASKED(LOG_SPU_READS, "audio_r: EQ Cutoff Gain 2/3: %04x\n", data);
+ break;
+
+ default:
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_r: Unknown register %04x = %04x\n", 0x3000 + offset, data);
+ break;
+ }
+ }
+ else if (channel < 16)
+ {
+ switch (offset & AUDIO_CHAN_OFFSET_MASK)
+ {
+ case AUDIO_WAVE_ADDR:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Wave Addr (lo): %04x\n", channel, data);
+ break;
+
+ case AUDIO_MODE:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Mode: %04x (ADPCM:%d, 16M:%d, TONE:%d, LADDR_HI:%04x, WADDR_HI:%04x)\n", channel, data,
+ get_adpcm_bit(channel), get_16bit_bit(channel), get_tone_mode(channel), get_loop_addr_high(channel), get_wave_addr_high(channel));
+ break;
+
+ case AUDIO_LOOP_ADDR:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Loop Addr: %04x\n", channel, data);
+ break;
+
+ case AUDIO_PAN_VOL:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Pan/Vol: %04x (PAN:%02x, VOL:%02x)\n", channel, data,
+ get_pan(channel), get_volume(channel));
+ break;
+
+ case AUDIO_ENVELOPE0:
+ LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope0: %04x (RPTPER:%d, TARGET:%02x, SIGN:%d, INC:%02x)\n", channel, data,
+ get_repeat_period_bit(channel), get_envelope_target(channel), get_envelope_sign_bit(channel), get_envelope_inc(channel));
+ break;
+
+ case AUDIO_ENVELOPE_DATA:
+ LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope Data: %04x (CNT:%d, EDD:%02x)\n", channel, data,
+ get_envelope_count(channel), get_edd(channel));
+ break;
+
+ case AUDIO_ENVELOPE1:
+ LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope1 Data: %04x (RPTCNT:%02x, RPT:%d, LOAD:%02x)\n", channel, data,
+ get_envelope_repeat_count(channel), get_envelope_repeat_bit(channel), get_envelope_load(channel));
+ break;
+
+ case AUDIO_ENVELOPE_ADDR_HIGH:
+ LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope Addr (hi): %04x (IRQADDR:%03x, IRQEN:%d, EADDR_HI:%02x)\n", channel, data,
+ get_audio_irq_addr(channel), get_audio_irq_enable_bit(channel), get_envelope_addr_high(channel));
+ break;
+
+ case AUDIO_ENVELOPE_ADDR:
+ LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope Addr (lo): %04x \n", channel, data);
+ break;
+
+ case AUDIO_WAVE_DATA_PREV:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Wave Data Prev: %04x \n", channel, data);
+ break;
+
+ case AUDIO_ENVELOPE_LOOP_CTRL:
+ LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope Loop Ctrl: %04x (RDOFFS:%02x, EAOFFS:%03x)\n", channel, data,
+ get_rampdown_offset(channel), get_envelope_eaoffset(channel));
+ break;
+
+ case AUDIO_WAVE_DATA:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Wave Data: %04x\n", channel, data);
+ break;
+
+ case AUDIO_ADPCM_SEL:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: ADPCM Sel: %04x (ADPCM36:%d, POINTNUM:%02x\n", channel, data,
+ get_adpcm36_bit(channel), get_point_number(channel));
+ break;
+
+ case AUDIO_PHASE_HIGH:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Phase High: %04x\n", channel, data);
+ break;
+
+ case AUDIO_PHASE_ACCUM_HIGH:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Phase Accum High: %04x\n", channel, data);
+ break;
+
+ case AUDIO_TARGET_PHASE_HIGH:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Target Phase High: %04x\n", channel, data);
+ break;
+
+ case AUDIO_RAMP_DOWN_CLOCK:
+ LOGMASKED(LOG_CHANNEL_READS | LOG_RAMPDOWN, "audio_r: Channel %d: Rampdown Clock: %04x\n", channel, data);
+ break;
+
+ case AUDIO_PHASE:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Phase: %04x\n", channel, data);
+ break;
+
+ case AUDIO_PHASE_ACCUM:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Phase Accum: %04x\n", channel, data);
+ break;
+
+ case AUDIO_TARGET_PHASE:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Target Phase: %04x\n", channel, data);
+ break;
+
+ case AUDIO_PHASE_CTRL:
+ LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Phase Ctrl: %04x (TIMESTEP:%d, SIGN:%d, OFFSET:%03x\n", channel, data,
+ get_phase_time_step(channel), get_phase_sign_bit(channel), get_phase_offset(channel));
+ break;
+
+ default:
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_r: Unknown register %04x\n", 0x3000 + offset);
+ break;
+ }
+ }
+ else if (channel >= 16)
+ {
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_r: Trying to read from channel %d\n", channel);
+ }
+ return data;
}
-void spg2xx_device::configure_spg_io(spg2xx_io_device* io)
+WRITE16_MEMBER(spg2xx_device::audio_w)
{
- io->porta_in().set(FUNC(spg2xx_device::porta_r));
- io->portb_in().set(FUNC(spg2xx_device::portb_r));
- io->portc_in().set(FUNC(spg2xx_device::portc_r));
- io->porta_out().set(FUNC(spg2xx_device::porta_w));
- io->portb_out().set(FUNC(spg2xx_device::portb_w));
- io->portc_out().set(FUNC(spg2xx_device::portc_w));
- io->adc_in<0>().set(FUNC(spg2xx_device::adc_r<0>));
- io->adc_in<1>().set(FUNC(spg2xx_device::adc_r<1>));
- io->eeprom_w().set(FUNC(spg2xx_device::eepromx_w));
- io->eeprom_r().set(FUNC(spg2xx_device::eepromx_r));
- io->uart_tx().set(FUNC(spg2xx_device::tx_w));
- io->chip_select().set(FUNC(spg2xx_device::cs_w));
- io->pal_read_callback().set(FUNC(spg2xx_device::get_pal_r));
- io->write_timer_irq_callback().set(FUNC(spg2xx_device::timerirq_w));
- io->write_uart_adc_irq_callback().set(FUNC(spg2xx_device::uartirq_w));
- io->write_external_irq_callback().set(FUNC(spg2xx_device::extirq_w));
- io->write_ffrq_tmr1_irq_callback().set(FUNC(spg2xx_device::ffreq1_w));
- io->write_ffrq_tmr2_irq_callback().set(FUNC(spg2xx_device::ffreq2_w));
+ const uint16_t channel = (offset & 0x00f0) >> 4;
+
+ if (offset >= 0x400)
+ {
+ switch (offset)
+ {
+ case AUDIO_CHANNEL_ENABLE:
+ {
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Channel Enable: %04x\n", data);
+ const uint16_t changed = m_audio_regs[AUDIO_CHANNEL_ENABLE] ^ data;
+ for (uint32_t channel_bit = 0; channel_bit < 16; channel_bit++)
+ {
+ const uint16_t mask = 1 << channel_bit;
+ if (!(changed & mask))
+ continue;
+
+ if (data & mask)
+ {
+ if (!(m_audio_regs[AUDIO_CHANNEL_STATUS] & mask))
+ {
+ LOGMASKED(LOG_SPU_WRITES, "Enabling channel %d\n", channel_bit);
+ m_audio_regs[offset] |= mask;
+ if (!(m_audio_regs[AUDIO_CHANNEL_STOP] & mask))
+ {
+ LOGMASKED(LOG_SPU_WRITES, "Stop not set, starting playback on channel %d, mask %04x\n", channel_bit, mask);
+ m_audio_regs[AUDIO_CHANNEL_STATUS] |= mask;
+ m_sample_addr[channel_bit] = get_wave_addr(channel_bit);
+ m_envelope_addr[channel_bit] = get_envelope_addr(channel_bit);
+ set_envelope_count(channel, get_envelope_load(channel));
+ }
+ m_adpcm[channel_bit].reset();
+ m_sample_shift[channel_bit] = 0;
+ m_sample_count[channel_bit] = 0;
+ }
+ }
+ else
+ {
+ m_audio_regs[offset] &= ~mask;
+ m_audio_regs[AUDIO_CHANNEL_STATUS] &= ~mask;
+ m_audio_regs[AUDIO_CHANNEL_STOP] |= mask;
+ m_audio_regs[AUDIO_CHANNEL_TONE_RELEASE] &= ~mask;
+ }
+ }
+ break;
+ }
+
+ case AUDIO_MAIN_VOLUME:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Main Volume: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_MAIN_VOLUME_MASK;
+ break;
+
+ case AUDIO_CHANNEL_FIQ_ENABLE:
+ LOGMASKED(LOG_SPU_WRITES | LOG_IRQS, "audio_w: Channel FIQ Enable: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_CHANNEL_FIQ_ENABLE_MASK;
+ break;
+
+ case AUDIO_CHANNEL_FIQ_STATUS:
+ LOGMASKED(LOG_SPU_WRITES | LOG_IRQS, "audio_w: Channel FIQ Acknowledge: %04x\n", data);
+ m_audio_regs[offset] &= ~(data & AUDIO_CHANNEL_FIQ_STATUS_MASK);
+ break;
+
+ case AUDIO_BEAT_BASE_COUNT:
+ LOGMASKED(LOG_SPU_WRITES | LOG_BEAT, "audio_w: Beat Base Count: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_BEAT_BASE_COUNT_MASK;
+ m_audio_curr_beat_base_count = m_audio_regs[offset];
+ break;
+
+ case AUDIO_BEAT_COUNT:
+ {
+ LOGMASKED(LOG_SPU_WRITES | LOG_BEAT, "audio_w: Beat Count: %04x\n", data);
+ const uint16_t old = m_audio_regs[offset];
+ m_audio_regs[offset] &= ~(data & AUDIO_BIS_MASK);
+ m_audio_regs[offset] &= AUDIO_BIS_MASK;
+ m_audio_regs[offset] |= data & ~AUDIO_BIS_MASK;
+ const uint16_t changed = old ^ m_audio_regs[offset];
+ if (data == 0xc000 && m_audio_regs[offset])
+ {
+ }
+ if (changed & (AUDIO_BIS_MASK | AUDIO_BIE_MASK))
+ {
+ LOGMASKED(LOG_BEAT, "BIS mask changed, updating IRQ\n");
+ check_irqs(changed & (AUDIO_BIS_MASK | AUDIO_BIE_MASK));
+ }
+ break;
+ }
+
+ case AUDIO_ENVCLK0:
+ case AUDIO_ENVCLK1:
+ {
+ LOGMASKED(LOG_SPU_WRITES | LOG_ENVELOPES, "audio_w: Envelope Interval %d (lo): %04x\n", offset == AUDIO_ENVCLK0 ? 0 : 1, data);
+ const uint16_t old = m_audio_regs[offset];
+ m_audio_regs[offset] = data;
+ const uint16_t changed = old ^ m_audio_regs[offset];
+
+ if (!changed)
+ break;
+
+ const uint8_t channel_offset = offset == AUDIO_ENVCLK0 ? 0 : 8;
+ for (uint8_t channel_bit = 0; channel_bit < 4; channel_bit++)
+ {
+ const uint8_t shift = channel_bit << 2;
+ const uint16_t mask = 0x0f << shift;
+ if (changed & mask)
+ {
+ m_envclk_frame[channel_bit + channel_offset] = get_envclk_frame_count(channel_bit + channel_offset);
+ }
+ }
+ break;
+ }
+
+ case AUDIO_ENVCLK0_HIGH:
+ case AUDIO_ENVCLK1_HIGH:
+ {
+ LOGMASKED(LOG_SPU_WRITES | LOG_ENVELOPES, "audio_w: Envelope Interval %d (hi): %04x\n", offset == AUDIO_ENVCLK0_HIGH ? 0 : 1, data);
+ const uint16_t old = m_audio_regs[offset];
+ m_audio_regs[offset] = data;
+ const uint16_t changed = old ^ m_audio_regs[offset];
+ if (!changed)
+ break;
+
+ const uint8_t channel_offset = offset == AUDIO_ENVCLK0_HIGH ? 0 : 8;
+ for (uint8_t channel_bit = 0; channel_bit < 4; channel_bit++)
+ {
+ const uint8_t shift = channel_bit << 2;
+ const uint16_t mask = 0x0f << shift;
+ if (changed & mask)
+ {
+ m_envclk_frame[channel_bit + channel_offset + 4] = get_envclk_frame_count(channel_bit + channel_offset);
+ }
+ }
+ break;
+ }
+
+ case AUDIO_ENV_RAMP_DOWN:
+ {
+ LOGMASKED(LOG_SPU_WRITES | LOG_RAMPDOWN, "audio_w: Envelope Fast Ramp Down: %04x\n", data);
+ const uint16_t old = m_audio_regs[offset];
+ m_audio_regs[offset] = data & AUDIO_ENV_RAMP_DOWN_MASK;
+ const uint16_t changed = old ^ m_audio_regs[offset];
+ if (!changed)
+ break;
+
+ for (uint32_t channel_bit = 0; channel_bit < 16; channel_bit++)
+ {
+ const uint16_t mask = 1 << channel_bit;
+ if ((changed & mask) && (data & mask))
+ {
+ m_rampdown_frame[channel_bit] = get_rampdown_frame_count(channel_bit);
+ LOGMASKED(LOG_RAMPDOWN, "Preparing to ramp down channel %d in %d ticks\n", channel_bit, m_rampdown_frame[channel_bit] / 13);
+ }
+ }
+ break;
+ }
+
+ case AUDIO_CHANNEL_STOP:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Channel Stop Status: %04x\n", data);
+ m_audio_regs[offset] &= ~data;
+ m_audio_regs[AUDIO_CHANNEL_ENABLE] &= ~data;
+ break;
+
+ case AUDIO_CHANNEL_ZERO_CROSS:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Channel Zero-Cross Enable: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_CHANNEL_ZERO_CROSS_MASK;
+ break;
+
+ case AUDIO_CONTROL:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Control: %04x (SOFTCH:%d, COMPEN:%d, NOHIGH:%d, NOINT:%d, EQEN:%d\n", data
+ , (data & AUDIO_CONTROL_SOFTCH_MASK) ? 1 : 0
+ , (data & AUDIO_CONTROL_COMPEN_MASK) ? 1 : 0
+ , (data & AUDIO_CONTROL_NOHIGH_MASK) ? 1 : 0
+ , (data & AUDIO_CONTROL_NOINT_MASK) ? 1 : 0
+ , (data & AUDIO_CONTROL_EQEN_MASK) ? 1 : 0);
+ m_audio_regs[offset] = data & AUDIO_CONTROL_MASK;
+ break;
+
+ case AUDIO_COMPRESS_CTRL:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Compressor Control: %04x\n", data);
+ m_audio_regs[offset] = data;
+ break;
+
+ case AUDIO_CHANNEL_STATUS:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Channel Status (read-only): %04x\n", data);
+ break;
+
+ case AUDIO_WAVE_IN_L:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Wave In (L) / FIFO Write Data: %04x\n", data);
+ m_audio_regs[offset] = data;
+ break;
+
+ case AUDIO_WAVE_IN_R:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Wave In (R) / Software Channel FIFO IRQ Control: %04x\n", data);
+ m_audio_regs[offset] = data;
+ break;
+
+ case AUDIO_WAVE_OUT_L:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Wave Out (L): %04x\n", data);
+ m_audio_regs[offset] = data;
+ break;
+
+ case AUDIO_WAVE_OUT_R:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Wave Out (R): %04x\n", data);
+ m_audio_regs[offset] = data;
+ break;
+
+ case AUDIO_CHANNEL_REPEAT:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Channel Repeat Enable: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_CHANNEL_REPEAT_MASK;
+ break;
+
+ case AUDIO_CHANNEL_ENV_MODE:
+ LOGMASKED(LOG_SPU_WRITES | LOG_ENVELOPES, "audio_w: Channel Envelope Enable: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_CHANNEL_ENV_MODE_MASK;
+ break;
+
+ case AUDIO_CHANNEL_TONE_RELEASE:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Channel Tone Release Enable: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_CHANNEL_TONE_RELEASE_MASK;
+ break;
+
+ case AUDIO_CHANNEL_ENV_IRQ:
+ LOGMASKED(LOG_SPU_WRITES | LOG_ENVELOPES | LOG_IRQS, "audio_w: Channel Envelope IRQ Acknowledge: %04x\n", data);
+ m_audio_regs[offset] &= ~data & AUDIO_CHANNEL_ENV_IRQ_MASK;
+ break;
+
+ case AUDIO_CHANNEL_PITCH_BEND:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Channel Pitch Bend Enable: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_CHANNEL_PITCH_BEND_MASK;
+ break;
+
+ case AUDIO_SOFT_PHASE:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Software Channel Phase: %04x\n", data);
+ m_audio_regs[offset] = data;
+ break;
+
+ case AUDIO_ATTACK_RELEASE:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: Attack/Release Time Control: %04x\n", data);
+ m_audio_regs[offset] = data;
+ break;
+
+ case AUDIO_EQ_CUTOFF10:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: EQ Cutoff Frequency 0/1: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_EQ_CUTOFF10_MASK;
+ break;
+
+ case AUDIO_EQ_CUTOFF32:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: EQ Cutoff Frequency 2/3: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_EQ_CUTOFF32_MASK;
+ break;
+
+ case AUDIO_EQ_GAIN10:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: EQ Cutoff Gain 0/1: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_EQ_GAIN10_MASK;
+ break;
+
+ case AUDIO_EQ_GAIN32:
+ LOGMASKED(LOG_SPU_WRITES, "audio_w: EQ Cutoff Gain 2/3: %04x\n", data);
+ m_audio_regs[offset] = data & AUDIO_EQ_GAIN32_MASK;
+ break;
+
+ default:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
+ break;
+ }
+ }
+ else if (channel < 16)
+ {
+ switch (offset & AUDIO_CHAN_OFFSET_MASK)
+ {
+ case AUDIO_WAVE_ADDR:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Wave Addr (lo): %04x\n", channel, data);
+ break;
+
+ case AUDIO_MODE:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Mode: %04x (ADPCM:%d, 16M:%d, TONE:%d, LADDR_HI:%04x, WADDR_HI:%04x)\n", channel, data,
+ get_adpcm_bit(channel), get_16bit_bit(channel), get_tone_mode(channel), get_loop_addr_high(channel), get_wave_addr_high(channel));
+ break;
+
+ case AUDIO_LOOP_ADDR:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Loop Addr: %04x\n", channel, data);
+ break;
+
+ case AUDIO_PAN_VOL:
+ m_audio_regs[offset] = data & AUDIO_PAN_VOL_MASK;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Pan/Vol: %04x (PAN:%02x, VOL:%02x)\n", channel, data,
+ get_pan(channel), get_volume(channel));
+ break;
+
+ case AUDIO_ENVELOPE0:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope0: %04x (RPTPER:%d, TARGET:%02x, SIGN:%d, INC:%02x)\n", channel, data,
+ get_repeat_period_bit(channel), get_envelope_target(channel), get_envelope_sign_bit(channel), get_envelope_inc(channel));
+ break;
+
+ case AUDIO_ENVELOPE_DATA:
+ m_audio_regs[offset] = data & AUDIO_ENVELOPE_DATA_MASK;
+ LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope Data: %04x (CNT:%d, EDD:%02x)\n", channel, data,
+ get_envelope_count(channel), get_edd(channel));
+ break;
+
+ case AUDIO_ENVELOPE1:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope1 Data: %04x (RPTCNT:%02x, RPT:%d, LOAD:%02x)\n", channel, data,
+ get_envelope_repeat_count(channel), get_envelope_repeat_bit(channel), get_envelope_load(channel));
+ break;
+
+ case AUDIO_ENVELOPE_ADDR_HIGH:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope Addr (hi): %04x (IRQADDR:%03x, IRQEN:%d, EADDR_HI:%02x)\n", channel, data,
+ get_audio_irq_addr(channel), get_audio_irq_enable_bit(channel), get_envelope_addr_high(channel));
+ break;
+
+ case AUDIO_ENVELOPE_ADDR:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope Addr (lo): %04x\n", channel, data);
+ break;
+
+ case AUDIO_WAVE_DATA_PREV:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Wave Data Prev: %04x \n", channel, data);
+ break;
+
+ case AUDIO_ENVELOPE_LOOP_CTRL:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope Loop Ctrl: %04x (RDOFFS:%02x, EAOFFS:%03x)\n", channel, data,
+ get_rampdown_offset(channel), get_envelope_eaoffset(channel));
+ break;
+
+ case AUDIO_WAVE_DATA:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Wave Data: %04x\n", channel, data);
+ break;
+
+ case AUDIO_ADPCM_SEL:
+ m_audio_regs[offset] = data & AUDIO_ADPCM_SEL_MASK;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: ADPCM Sel: %04x (ADPCM36:%d, POINTNUM:%02x\n", channel, data,
+ get_adpcm36_bit(channel), get_point_number(channel));
+ break;
+
+ case AUDIO_PHASE_HIGH:
+ m_audio_regs[offset] = data & AUDIO_PHASE_HIGH_MASK;
+ m_channel_rate[channel] = ((double)get_phase(channel) * 140625.0 * 2.0) / (double)(1 << 19);
+ m_channel_rate_accum[channel] = 0.0;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Phase High: %04x (rate: %f)\n", channel, data, m_channel_rate[channel]);
+ break;
+
+ case AUDIO_PHASE_ACCUM_HIGH:
+ m_audio_regs[offset] = data & AUDIO_PHASE_ACCUM_HIGH_MASK;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Phase Accum High: %04x\n", channel, data);
+ break;
+
+ case AUDIO_TARGET_PHASE_HIGH:
+ m_audio_regs[offset] = data & AUDIO_TARGET_PHASE_HIGH_MASK;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Target Phase High: %04x\n", channel, data);
+ break;
+
+ case AUDIO_RAMP_DOWN_CLOCK:
+ m_audio_regs[offset] = data & AUDIO_RAMP_DOWN_CLOCK_MASK;
+ LOGMASKED(LOG_CHANNEL_WRITES | LOG_RAMPDOWN, "audio_w: Channel %d: Rampdown Clock: %04x\n", channel, data);
+ break;
+
+ case AUDIO_PHASE:
+ m_audio_regs[offset] = data;
+ m_channel_rate[channel] = ((double)get_phase(channel) * 140625.0 * 2.0) / (double)(1 << 19);
+ m_channel_rate_accum[channel] = 0.0;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Phase: %04x (rate: %f)\n", channel, data, m_channel_rate[channel]);
+ break;
+
+ case AUDIO_PHASE_ACCUM:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Phase Accum: %04x\n", channel, data);
+ break;
+
+ case AUDIO_TARGET_PHASE:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Target Phase: %04x\n", channel, data);
+ break;
+
+ case AUDIO_PHASE_CTRL:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Phase Ctrl: %04x (TIMESTEP:%d, SIGN:%d, OFFSET:%03x\n", channel, data,
+ get_phase_time_step(channel), get_phase_sign_bit(channel), get_phase_offset(channel));
+ break;
+
+ default:
+ m_audio_regs[offset] = data;
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
+ break;
+ }
+ }
+ else if (channel >= 16)
+ {
+ LOGMASKED(LOG_UNKNOWN_SPU, "audio_w: Trying to write to channel %d: %04x = %04x\n", channel, 0x3000 + offset, data);
+ }
+ else
+ {
+ m_audio_regs[offset] = data;
+ }
+}
+
+void spg2xx_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+{
+ stream_sample_t *out_l = outputs[0];
+ stream_sample_t *out_r = outputs[1];
+ address_space &space = m_cpu->space(AS_PROGRAM);
+
+ for (int i = 0; i < samples; i++)
+ {
+ int32_t left_total = 0;
+ int32_t right_total = 0;
+ int32_t active_count = 0;
+
+ for (uint32_t ch_index = 0; ch_index < 16; ch_index++)
+ {
+ if (!get_channel_status(ch_index))
+ {
+ continue;
+ }
+
+ if (SPG_DEBUG_AUDIO && m_debug_rates)
+ printf("%f:%f ", m_channel_rate[ch_index], m_channel_rate_accum[ch_index]);
+ bool playing = advance_channel(space, ch_index);
+ if (playing)
+ {
+ int32_t sample = (int16_t)(m_audio_regs[(ch_index << 4) | AUDIO_WAVE_DATA] ^ 0x8000);
+ if (!(m_audio_regs[AUDIO_CONTROL] & AUDIO_CONTROL_NOINT_MASK))
+ {
+ int32_t prev_sample = (int16_t)(m_audio_regs[(ch_index << 4) | AUDIO_WAVE_DATA_PREV] ^ 0x8000);
+ int16_t lerp_factor = (int16_t)((m_channel_rate_accum[ch_index] / 44100.0) * 256.0);
+ prev_sample = (prev_sample * (0x100 - lerp_factor)) >> 8;
+ sample = (sample * lerp_factor) >> 8;
+ sample += prev_sample;
+ }
+
+ sample = (sample * (int16_t)get_edd(ch_index)) >> 7;
+
+ active_count++;
+
+ int32_t vol = get_volume(ch_index);
+ int32_t pan = get_pan(ch_index);
+
+ int32_t pan_left, pan_right;
+ if (pan < 0x40)
+ {
+ pan_left = 0x7f * vol;
+ pan_right = pan * 2 * vol;
+ }
+ else
+ {
+ pan_left = (0x7f - pan) * 2 * vol;
+ pan_right = 0x7f * vol;
+ }
+
+ left_total += ((int16_t)sample * (int16_t)pan_left) >> 14;
+ right_total += ((int16_t)sample * (int16_t)pan_right) >> 14;
+ }
+ }
+
+ if (active_count)
+ {
+ left_total /= active_count;
+ right_total /= active_count;
+ *out_l++ = (left_total * (int16_t)m_audio_regs[AUDIO_MAIN_VOLUME]) >> 7;
+ *out_r++ = (right_total * (int16_t)m_audio_regs[AUDIO_MAIN_VOLUME]) >> 7;
+ }
+ else
+ {
+ *out_l++ = 0;
+ *out_r++ = 0;
+ }
+ }
+}
+
+inline void spg2xx_device::stop_channel(const uint32_t channel)
+{
+ // TODO: IRQs
+ m_audio_regs[AUDIO_CHANNEL_ENABLE] &= ~(1 << channel);
+ m_audio_regs[AUDIO_CHANNEL_STATUS] &= ~(1 << channel);
+ m_audio_regs[AUDIO_CHANNEL_STOP] |= (1 << channel);
+ m_audio_regs[(channel << 4) | AUDIO_MODE] &= ~AUDIO_ADPCM_MASK;
+ m_audio_regs[AUDIO_CHANNEL_TONE_RELEASE] &= ~(1 << channel);
+}
+
+bool spg2xx_device::advance_channel(address_space &space, const uint32_t channel)
+{
+ m_channel_rate_accum[channel] += m_channel_rate[channel];
+ uint32_t samples_to_advance = 0;
+ while (m_channel_rate_accum[channel] >= 44100.0)
+ {
+ m_channel_rate_accum[channel] -= 44100.0;
+ samples_to_advance++;
+ }
+
+ if (!samples_to_advance)
+ return true;
+
+ bool playing = true;
+
+ if (get_adpcm_bit(channel))
+ {
+ // ADPCM mode
+ for (uint32_t sample = 0; sample < samples_to_advance && playing; sample++)
+ {
+ playing = fetch_sample(space, channel);
+ if (playing)
+ {
+ m_sample_shift[channel] += 4;
+ if (m_sample_shift[channel] == 16)
+ {
+ m_sample_shift[channel] = 0;
+ m_sample_addr[channel]++;
+ }
+ }
+ }
+ }
+ else if (get_16bit_bit(channel))
+ {
+ // 16-bit mode
+ for (uint32_t sample = 0; sample < samples_to_advance && playing; sample++)
+ {
+ playing = fetch_sample(space, channel);
+ if (playing)
+ m_sample_addr[channel]++;
+ }
+ }
+ else
+ {
+ // 8-bit mode
+ for (uint32_t sample = 0; sample < samples_to_advance && playing; sample++)
+ {
+ playing = fetch_sample(space, channel);
+ if (playing)
+ {
+ m_sample_shift[channel] += 8;
+ if (m_sample_shift[channel] == 16)
+ {
+ m_sample_shift[channel] = 0;
+ m_sample_addr[channel]++;
+ }
+ }
+ }
+ }
+
+ return playing;
+}
+
+bool spg2xx_device::fetch_sample(address_space &space, const uint32_t channel)
+{
+ const uint32_t channel_mask = channel << 4;
+ m_audio_regs[channel_mask | AUDIO_WAVE_DATA_PREV] = m_audio_regs[channel_mask | AUDIO_WAVE_DATA];
+
+ const uint32_t wave_data_reg = channel_mask | AUDIO_WAVE_DATA;
+ const uint16_t tone_mode = get_tone_mode(channel);
+ const uint16_t raw_sample = tone_mode ? space.read_word(m_sample_addr[channel]) : m_audio_regs[wave_data_reg];
+
+ m_audio_regs[wave_data_reg] = raw_sample;
+
+ if (get_adpcm_bit(channel))
+ {
+ // ADPCM mode
+ m_audio_regs[wave_data_reg] >>= m_sample_shift[channel];
+ m_audio_regs[wave_data_reg] = (uint16_t)(m_adpcm[channel].clock((uint8_t)(m_audio_regs[wave_data_reg] & 0x000f)) * 7) ^ 0x8000;
+ if (tone_mode != 0 && raw_sample == 0xffff)
+ {
+ if (tone_mode == AUDIO_TONE_MODE_HW_ONESHOT)
+ {
+ LOGMASKED(LOG_SAMPLES, "ADPCM stopped after %d samples\n", m_sample_count[channel]);
+ m_sample_count[channel] = 0;
+ stop_channel(channel);
+ return false;
+ }
+ else
+ {
+ LOGMASKED(LOG_SAMPLES, "ADPCM looping after %d samples\n", m_sample_count[channel]);
+ m_sample_count[channel] = 0;
+ loop_channel(channel);
+ }
+ }
+ m_sample_count[channel]++;
+ }
+ else if (get_16bit_bit(channel))
+ {
+ // 16-bit mode
+ if (tone_mode != 0 && raw_sample == 0xffff)
+ {
+ if (tone_mode == AUDIO_TONE_MODE_HW_ONESHOT)
+ {
+ LOGMASKED(LOG_SAMPLES, "16-bit PCM stopped after %d samples\n", m_sample_count[channel]);
+ m_sample_count[channel] = 0;
+ stop_channel(channel);
+ return false;
+ }
+ else
+ {
+ LOGMASKED(LOG_SAMPLES, "16-bit PCM looping after %d samples\n", m_sample_count[channel]);
+ m_sample_count[channel] = 0;
+ loop_channel(channel);
+ }
+ }
+ m_sample_count[channel]++;
+ }
+ else
+ {
+ // 8-bit mode
+ if (tone_mode != 0)
+ {
+ if (m_sample_shift[channel])
+ m_audio_regs[wave_data_reg] <<= 8;
+ else
+ m_audio_regs[wave_data_reg] &= 0xff00;
+
+ if (m_audio_regs[wave_data_reg] == 0xff00)
+ {
+ if (tone_mode == AUDIO_TONE_MODE_HW_ONESHOT)
+ {
+ LOGMASKED(LOG_SAMPLES, "8-bit PCM stopped after %d samples\n", m_sample_count[channel]);
+ m_sample_count[channel] = 0;
+ stop_channel(channel);
+ return false;
+ }
+ else
+ {
+ LOGMASKED(LOG_SAMPLES, "8-bit PCM looping after %d samples\n", m_sample_count[channel]);
+ m_sample_count[channel] = 0;
+ loop_channel(channel);
+ }
+ }
+ }
+ m_sample_count[channel]++;
+ }
+
+ return true;
}
-void spg24x_device::device_add_mconfig(machine_config &config)
+inline void spg2xx_device::loop_channel(const uint32_t channel)
{
- SPG2XX_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1));
- m_spg_audio->write_irq_callback().set(FUNC(spg24x_device::audioirq_w));
- m_spg_audio->space_read_callback().set(FUNC(spg24x_device::space_r));
+ m_sample_addr[channel] = get_loop_addr(channel);
+ m_sample_shift[channel] = 0;
+}
- m_spg_audio->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
- m_spg_audio->add_route(1, *this, 1.0, AUTO_ALLOC_INPUT, 1);
+void spg2xx_device::audio_frame_tick()
+{
+ audio_beat_tick();
- SPG24X_IO(config, m_spg_io, DERIVED_CLOCK(1, 1), m_cpu, m_screen);
- configure_spg_io(m_spg_io);
+ address_space &space = m_cpu->space(AS_PROGRAM);
+ bool any_changed = false;
+ for (uint32_t channel = 0; channel < 16; channel++)
+ {
+ const uint16_t mask = (1 << channel);
+ if (!(m_audio_regs[AUDIO_CHANNEL_STATUS] & mask))
+ {
+ continue;
+ }
+
+ if (m_audio_regs[AUDIO_ENV_RAMP_DOWN] & mask)
+ {
+ m_rampdown_frame[channel]--;
+ if (m_rampdown_frame[channel] == 0)
+ {
+ LOGMASKED(LOG_RAMPDOWN, "Ticking rampdown for channel %d\n", channel);
+ audio_rampdown_tick(channel);
+ any_changed = true;
+ }
+ continue;
+ }
+
+ if (!(m_audio_regs[AUDIO_CHANNEL_ENV_MODE] & mask))
+ {
+ m_envclk_frame[channel]--;
+ if (m_envclk_frame[channel] == 0)
+ {
+ LOGMASKED(LOG_ENVELOPES, "Ticking envelope for channel %d\n", channel);
+ any_changed = audio_envelope_tick(space, channel) || any_changed;
+ m_envclk_frame[channel] = get_envclk_frame_count(channel);
+ }
+ }
+ }
+
+ if (any_changed)
+ {
+ m_stream->update();
+ }
}
-void spg28x_device::device_add_mconfig(machine_config &config)
+void spg2xx_device::audio_beat_tick()
{
- SPG2XX_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1));
- m_spg_audio->write_irq_callback().set(FUNC(spg28x_device::audioirq_w));
- m_spg_audio->space_read_callback().set(FUNC(spg28x_device::space_r));
+ if (m_audio_curr_beat_base_count == 0)
+ {
+ LOGMASKED(LOG_BEAT, "Beat base count elapsed, reloading with %d\n", m_audio_regs[AUDIO_BEAT_BASE_COUNT]);
+ m_audio_curr_beat_base_count = m_audio_regs[AUDIO_BEAT_BASE_COUNT];
+
+ uint16_t beat_count = m_audio_regs[AUDIO_BEAT_COUNT] & AUDIO_BEAT_COUNT_MASK;
+ if (beat_count == 0)
+ {
+ if (m_audio_regs[AUDIO_BEAT_COUNT] & AUDIO_BIE_MASK)
+ {
+ LOGMASKED(LOG_BEAT, "Beat count elapsed, setting Status bit and checking IRQs\n");
+ m_audio_regs[AUDIO_BEAT_COUNT] |= AUDIO_BIS_MASK;
+ check_irqs(AUDIO_BIS_MASK);
+ }
+ else
+ {
+ LOGMASKED(LOG_BEAT, "Beat count elapsed but IRQ not enabled\n");
+ }
+ }
+ else
+ {
+ beat_count--;
+ m_audio_regs[AUDIO_BEAT_COUNT] = (m_audio_regs[AUDIO_BEAT_COUNT] & ~AUDIO_BEAT_COUNT_MASK) | beat_count;
+ }
+ }
+ else
+ {
+ m_audio_curr_beat_base_count--;
+ }
+}
- m_spg_audio->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
- m_spg_audio->add_route(1, *this, 1.0, AUTO_ALLOC_INPUT, 1);
+void spg2xx_device::audio_rampdown_tick(const uint32_t channel)
+{
+ const uint8_t old_edd = get_edd(channel);
+ uint8_t new_edd = old_edd - get_rampdown_offset(channel);
+ if (new_edd > old_edd)
+ new_edd = 0;
- SPG28X_IO(config, m_spg_io, DERIVED_CLOCK(1, 1), m_cpu, m_screen);
- configure_spg_io(m_spg_io);
+ if (new_edd)
+ {
+ LOGMASKED(LOG_RAMPDOWN, "Channel %d preparing for next rampdown step (%02x)\n", channel, new_edd);
+ const uint16_t channel_mask = channel << 4;
+ m_audio_regs[channel_mask | AUDIO_ENVELOPE_DATA] &= ~AUDIO_EDD_MASK;
+ m_audio_regs[channel_mask | AUDIO_ENVELOPE_DATA] |= new_edd & AUDIO_EDD_MASK;
+ m_rampdown_frame[channel] = get_rampdown_frame_count(channel);
+ }
+ else
+ {
+ LOGMASKED(LOG_RAMPDOWN, "Stopping channel %d due to rampdown\n", channel);
+ const uint16_t channel_mask = 1 << channel;
+ m_audio_regs[AUDIO_CHANNEL_ENABLE] &= ~channel_mask;
+ m_audio_regs[AUDIO_CHANNEL_STATUS] &= ~channel_mask;
+ m_audio_regs[AUDIO_CHANNEL_STOP] |= channel_mask;
+ m_audio_regs[AUDIO_ENV_RAMP_DOWN] &= ~channel_mask;
+ m_audio_regs[AUDIO_CHANNEL_TONE_RELEASE] &= ~channel_mask;
+ }
+}
+
+const uint32_t spg2xx_device::s_rampdown_frame_counts[8] =
+{
+ 13*4, 13*16, 13*64, 13*256, 13*1024, 13*4096, 13*8192, 13*8192
+};
+
+uint32_t spg2xx_device::get_rampdown_frame_count(const uint32_t channel)
+{
+ return s_rampdown_frame_counts[get_rampdown_clock(channel)];
+}
+
+const uint32_t spg2xx_device::s_envclk_frame_counts[16] =
+{
+ 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 8192, 8192, 8192, 8192
+};
+
+uint32_t spg2xx_device::get_envclk_frame_count(const uint32_t channel)
+{
+ return s_envclk_frame_counts[get_envelope_clock(channel)];
+}
+
+uint32_t spg2xx_device::get_envelope_clock(const offs_t channel) const
+{
+ if (channel < 4)
+ return (m_audio_regs[AUDIO_ENVCLK0] >> (channel << 2)) & 0x000f;
+ else if (channel < 8)
+ return (m_audio_regs[AUDIO_ENVCLK0_HIGH] >> ((channel - 4) << 2)) & 0x000f;
+ else if (channel < 12)
+ return (m_audio_regs[AUDIO_ENVCLK1] >> ((channel - 8) << 2)) & 0x000f;
+ else
+ return (m_audio_regs[AUDIO_ENVCLK1_HIGH] >> ((channel - 12) << 2)) & 0x000f;
+}
+
+bool spg2xx_device::audio_envelope_tick(address_space &space, const uint32_t channel)
+{
+ const uint16_t channel_mask = channel << 4;
+ uint16_t new_count = get_envelope_count(channel);
+ const uint16_t curr_edd = get_edd(channel);
+ LOGMASKED(LOG_ENVELOPES, "envelope %d tick, count is %04x, curr edd is %04x\n", channel, new_count, curr_edd);
+ bool edd_changed = false;
+ if (new_count == 0)
+ {
+ const uint16_t target = get_envelope_target(channel);
+ uint16_t new_edd = curr_edd;
+ const uint16_t inc = get_envelope_inc(channel);
+
+ if (new_edd != target)
+ {
+ if (get_envelope_sign_bit(channel))
+ {
+ new_edd -= inc;
+ LOGMASKED(LOG_ENVELOPES, "Envelope %d new EDD-: %04x (%04x), dec %04x\n", channel, new_edd, target, inc);
+ if (new_edd > curr_edd)
+ new_edd = 0;
+ else if (new_edd < target)
+ new_edd = target;
+
+ if (new_edd == 0)
+ {
+ LOGMASKED(LOG_ENVELOPES, "Envelope %d at 0, stopping channel\n", channel);
+ stop_channel(channel);
+ return true;
+ }
+ }
+ else
+ {
+ new_edd += inc;
+ LOGMASKED(LOG_ENVELOPES, "Envelope %d new EDD+: %04x\n", channel, new_edd);
+ if (new_edd >= target)
+ new_edd = target;
+ }
+ }
+
+ if (new_edd == target)
+ {
+ LOGMASKED(LOG_ENVELOPES, "Envelope %d at target %04x\n", channel, target);
+ new_edd = target;
+
+ if (get_envelope_repeat_bit(channel))
+ {
+ const uint16_t repeat_count = get_envelope_repeat_count(channel) - 1;
+ LOGMASKED(LOG_ENVELOPES, "Repeating envelope, new repeat count %d\n", repeat_count);
+ if (repeat_count == 0)
+ {
+ m_audio_regs[channel_mask | AUDIO_ENVELOPE0] = space.read_word(m_envelope_addr[channel]);
+ m_audio_regs[channel_mask | AUDIO_ENVELOPE1] = space.read_word(m_envelope_addr[channel] + 1);
+ m_audio_regs[channel_mask | AUDIO_ENVELOPE_LOOP_CTRL] = space.read_word(m_envelope_addr[channel] + 2);
+ m_envelope_addr[channel] = get_envelope_addr(channel) + get_envelope_eaoffset(channel);
+ LOGMASKED(LOG_ENVELOPES, "Envelope data after repeat: %04x %04x %04x (%08x)\n", m_audio_regs[channel_mask | AUDIO_ENVELOPE0], m_audio_regs[channel_mask | AUDIO_ENVELOPE1], m_audio_regs[channel_mask | AUDIO_ENVELOPE_LOOP_CTRL], m_envelope_addr[channel]);
+ }
+ else
+ {
+ set_envelope_repeat_count(channel, repeat_count);
+ }
+ }
+ else
+ {
+ LOGMASKED(LOG_ENVELOPES, "Fetching envelope for channel %d from %08x\n", channel, m_envelope_addr[channel]);
+ m_audio_regs[channel_mask | AUDIO_ENVELOPE0] = space.read_word(m_envelope_addr[channel]);
+ m_audio_regs[channel_mask | AUDIO_ENVELOPE1] = space.read_word(m_envelope_addr[channel] + 1);
+ LOGMASKED(LOG_ENVELOPES, "Fetched envelopes %04x %04x\n", m_audio_regs[channel_mask | AUDIO_ENVELOPE0], m_audio_regs[channel_mask | AUDIO_ENVELOPE1]);
+ m_envelope_addr[channel] += 2;
+ }
+ new_count = get_envelope_load(channel);
+ set_envelope_count(channel, new_count);
+ }
+ else
+ {
+ LOGMASKED(LOG_ENVELOPES, "Envelope %d not yet at target %04x (%04x)\n", channel, target, new_edd);
+ new_count = get_envelope_load(channel);
+ set_envelope_count(channel, new_count);
+ }
+ LOGMASKED(LOG_ENVELOPES, "Envelope %d new count %04x\n", channel, new_count);
+
+ set_edd(channel, new_edd);
+ edd_changed = true;
+ LOGMASKED(LOG_ENVELOPES, "Setting channel %d edd to %04x, register is %04x\n", channel, new_edd, m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA]);
+ }
+ else
+ {
+ new_count--;
+ set_envelope_count(channel, new_count);
+ }
+ LOGMASKED(LOG_ENVELOPES, "envelope %d post-tick, count is now %04x, register is %04x\n", channel, new_count, m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA]);
+ return edd_changed;
}
diff --git a/src/devices/machine/spg2xx.h b/src/devices/machine/spg2xx.h
index 859620d9f66..0573daef7ac 100644
--- a/src/devices/machine/spg2xx.h
+++ b/src/devices/machine/spg2xx.h
@@ -27,6 +27,12 @@
ND - unknown - Wireless Air 60
ND - Likely many more
+ Also on this hardware:
+
+ name PCB ID ROM width TSOP pads ROM size SEEPROM die markings
+ Radica Play TV Football 2 L7278 x16 48 not dumped no Sunplus
+ Dream Life ? x16 48 not dumped no Sunplus
+
**********************************************************************/
#ifndef MAME_MACHINE_SPG2XX_H
@@ -35,17 +41,15 @@
#pragma once
#include "cpu/unsp/unsp.h"
-#include "spg2xx_audio.h"
-#include "spg2xx_io.h"
+#include "sound/okiadpcm.h"
#include "screen.h"
-class spg2xx_device : public device_t, public device_mixer_interface
+class spg2xx_device : public device_t, public device_sound_interface
{
public:
spg2xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
void set_pal(bool pal) { m_pal_flag = pal ? 1 : 0; }
- void set_rowscroll_offset(int offset) { m_rowscrolloffset = offset; }
void map(address_map &map);
@@ -56,8 +60,6 @@ public:
auto portb_in() { return m_portb_in.bind(); }
auto portc_in() { return m_portc_in.bind(); }
- template <size_t Line> auto adc_in() { return m_adc_in[Line].bind(); }
-
auto eeprom_w() { return m_eeprom_w.bind(); }
auto eeprom_r() { return m_eeprom_r.bind(); }
@@ -65,22 +67,21 @@ public:
auto chip_select() { return m_chip_sel.bind(); }
+ void uart_rx(uint8_t data);
+
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(vblank);
- required_device<spg2xx_audio_device> m_spg_audio;
- required_device<spg2xx_io_device> m_spg_io;
-
- void extint_w(int channel, bool state) { m_spg_io->extint_w(channel, state); };
- void uart_rx(uint8_t data) { m_spg_io->uart_rx(data); };
-
protected:
- spg2xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const uint32_t sprite_limit)
+ spg2xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const size_t sprite_limit)
: spg2xx_device(mconfig, type, tag, owner, clock)
{
m_sprite_limit = sprite_limit;
}
+ // sound stream update overrides
+ virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
+
enum
{
PAGE_ENABLE_MASK = 0x0008,
@@ -99,82 +100,370 @@ protected:
TILE_Y_FLIP = 0x0008
};
- DECLARE_READ16_MEMBER(video_r);
- DECLARE_WRITE16_MEMBER(video_w);
+ void audio_frame_tick();
+ void audio_beat_tick();
+ void audio_rampdown_tick(const uint32_t channel);
+ bool audio_envelope_tick(address_space &space, const uint32_t channel);
+ inline uint32_t get_rampdown_frame_count(const uint32_t channel);
+ inline uint32_t get_envclk_frame_count(const uint32_t channel);
+
+ // Audio getters
+ bool get_channel_enable(const offs_t channel) const { return m_audio_regs[AUDIO_CHANNEL_ENABLE] & (1 << channel); }
+ bool get_channel_status(const offs_t channel) const { return m_audio_regs[AUDIO_CHANNEL_STATUS] & (1 << channel); }
+ bool get_manual_envelope_enable(const offs_t channel) const { return m_audio_regs[AUDIO_CHANNEL_ENV_MODE] & (1 << channel); }
+ bool get_auto_envelope_enable(const offs_t channel) const { return !get_manual_envelope_enable(channel); }
+ uint32_t get_envelope_clock(const offs_t channel) const;
+
+ // Audio Mode getters
+ uint16_t get_wave_addr_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_WADDR_HIGH_MASK; }
+ uint16_t get_loop_addr_high(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_LADDR_HIGH_MASK) >> AUDIO_LADDR_HIGH_SHIFT; }
+ uint16_t get_tone_mode(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_TONE_MODE_MASK) >> AUDIO_TONE_MODE_SHIFT; }
+ uint16_t get_16bit_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_16M_MASK) ? 1 : 0; }
+ uint16_t get_adpcm_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_ADPCM_MASK) ? 1 : 0; }
+
+ // Audio Pan getters
+ uint16_t get_volume(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_PAN_VOL] & AUDIO_VOLUME_MASK; }
+ uint16_t get_pan(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_PAN_VOL] & AUDIO_PAN_MASK) >> AUDIO_PAN_SHIFT; }
+
+ // Audio Envelope0 Data getters
+ uint16_t get_envelope_inc(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_INC_MASK; }
+ uint16_t get_envelope_sign_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_SIGN_MASK) ? 1 : 0; }
+ uint16_t get_envelope_target(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_TARGET_MASK) >> AUDIO_ENVELOPE_TARGET_SHIFT; }
+ uint16_t get_repeat_period_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_REPEAT_PERIOD_MASK) ? 1 : 0; }
+
+ // Audio Envelope Data getters
+ uint16_t get_edd(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & AUDIO_EDD_MASK; }
+ uint16_t get_envelope_count(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & AUDIO_ENVELOPE_COUNT_MASK) >> AUDIO_ENVELOPE_COUNT_SHIFT; }
+ void set_edd(const offs_t channel, uint8_t edd) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & ~AUDIO_EDD_MASK) | edd; }
+ void set_envelope_count(const offs_t channel, uint16_t count) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] = get_edd(channel) | (count << AUDIO_ENVELOPE_COUNT_SHIFT); }
+
+ // Audio Envelope1 Data getters
+ uint16_t get_envelope_load(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_LOAD_MASK; }
+ uint16_t get_envelope_repeat_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_RPT_MASK) ? 1 : 0; }
+ uint16_t get_envelope_repeat_count(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_RPCNT_MASK) >> AUDIO_ENVELOPE_RPCNT_SHIFT; }
+ inline void set_envelope_repeat_count(const offs_t channel, const uint16_t count) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & ~AUDIO_ENVELOPE_RPCNT_MASK) | ((count << AUDIO_ENVELOPE_RPCNT_SHIFT) & AUDIO_ENVELOPE_RPCNT_MASK); }
+
+ // Audio Envelope Address getters
+ uint16_t get_envelope_addr_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_EADDR_HIGH_MASK; }
+ uint16_t get_audio_irq_enable_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_IRQ_EN_MASK) ? 1 : 0; }
+ uint16_t get_audio_irq_addr(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_IRQ_ADDR_MASK) >> AUDIO_IRQ_ADDR_SHIFT; }
+
+ // Audio Envelope Loop getters
+ uint16_t get_envelope_eaoffset(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & AUDIO_EAOFFSET_MASK; }
+ uint16_t get_rampdown_offset(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & AUDIO_RAMPDOWN_OFFSET_MASK) >> AUDIO_RAMPDOWN_OFFSET_SHIFT; }
+ void set_envelope_eaoffset(const offs_t channel, uint16_t eaoffset) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & ~AUDIO_RAMPDOWN_OFFSET_MASK) | (eaoffset & AUDIO_EAOFFSET_MASK); }
+
+ // Audio ADPCM getters
+ uint16_t get_point_number(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ADPCM_SEL] & AUDIO_POINT_NUMBER_MASK) >> AUDIO_POINT_NUMBER_SHIFT; }
+ uint16_t get_adpcm36_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ADPCM_SEL] & AUDIO_ADPCM36_MASK) ? 1 : 0; }
+
+ // Audio high-word getters
+ uint16_t get_phase_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_PHASE_HIGH] & AUDIO_PHASE_HIGH_MASK; }
+ uint16_t get_phase_accum_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_PHASE_ACCUM_HIGH] & AUDIO_PHASE_ACCUM_HIGH_MASK; }
+ uint16_t get_target_phase_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_TARGET_PHASE_HIGH] & AUDIO_TARGET_PHASE_HIGH_MASK; }
+ uint16_t get_rampdown_clock(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_RAMP_DOWN_CLOCK] & AUDIO_RAMP_DOWN_CLOCK_MASK; }
+
+ // Audio ADPCM getters
+ uint16_t get_phase_offset(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_OFFSET_MASK; }
+ uint16_t get_phase_sign_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_SIGN_MASK) >> AUDIO_PHASE_SIGN_SHIFT; }
+ uint16_t get_phase_time_step(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_TIME_STEP_MASK) >> AUDIO_PHASE_TIME_STEP_SHIFT; }
+
+ // Audio combined getters
+ uint32_t get_phase(const offs_t channel) const { return ((uint32_t)get_phase_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_PHASE]; }
+ uint32_t get_phase_accum(const offs_t channel) const { return ((uint32_t)get_phase_accum_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_PHASE_ACCUM]; }
+ uint32_t get_target_phase(const offs_t channel) const { return ((uint32_t)get_target_phase_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_TARGET_PHASE]; }
+ uint32_t get_wave_addr(const offs_t channel) const { return ((uint32_t)get_wave_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_WAVE_ADDR]; }
+ uint32_t get_loop_addr(const offs_t channel) const { return ((uint32_t)get_loop_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_LOOP_ADDR]; }
+ uint32_t get_envelope_addr(const offs_t channel) const { return ((uint32_t)get_envelope_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR]; }
+
+ enum
+ {
+ AUDIO_WAVE_ADDR = 0x000,
+
+ AUDIO_MODE = 0x001,
+ AUDIO_WADDR_HIGH_MASK = 0x003f,
+ AUDIO_LADDR_HIGH_MASK = 0x0fc0,
+ AUDIO_LADDR_HIGH_SHIFT = 6,
+ AUDIO_TONE_MODE_MASK = 0x3000,
+ AUDIO_TONE_MODE_SHIFT = 12,
+ AUDIO_TONE_MODE_SW = 0,
+ AUDIO_TONE_MODE_HW_ONESHOT = 1,
+ AUDIO_TONE_MODE_HW_LOOP = 2,
+ AUDIO_16M_MASK = 0x4000,
+ AUDIO_ADPCM_MASK = 0x8000,
+
+ AUDIO_LOOP_ADDR = 0x002,
+
+ AUDIO_PAN_VOL = 0x003,
+ AUDIO_PAN_VOL_MASK = 0x7f7f,
+ AUDIO_VOLUME_MASK = 0x007f,
+ AUDIO_PAN_MASK = 0x7f00,
+ AUDIO_PAN_SHIFT = 8,
+
+ AUDIO_ENVELOPE0 = 0x004,
+ AUDIO_ENVELOPE_INC_MASK = 0x007f,
+ AUDIO_ENVELOPE_SIGN_MASK = 0x0080,
+ AUDIO_ENVELOPE_TARGET_MASK = 0x7f00,
+ AUDIO_ENVELOPE_TARGET_SHIFT = 8,
+ AUDIO_ENVELOPE_REPEAT_PERIOD_MASK = 0x8000,
+
+ AUDIO_ENVELOPE_DATA = 0x005,
+ AUDIO_ENVELOPE_DATA_MASK = 0xff7f,
+ AUDIO_EDD_MASK = 0x007f,
+ AUDIO_ENVELOPE_COUNT_MASK = 0xff00,
+ AUDIO_ENVELOPE_COUNT_SHIFT = 8,
+
+ AUDIO_ENVELOPE1 = 0x006,
+ AUDIO_ENVELOPE_LOAD_MASK = 0x00ff,
+ AUDIO_ENVELOPE_RPT_MASK = 0x0100,
+ AUDIO_ENVELOPE_RPCNT_MASK = 0xfe00,
+ AUDIO_ENVELOPE_RPCNT_SHIFT = 9,
+
+ AUDIO_ENVELOPE_ADDR_HIGH = 0x007,
+ AUDIO_EADDR_HIGH_MASK = 0x003f,
+ AUDIO_IRQ_EN_MASK = 0x0040,
+ AUDIO_IRQ_ADDR_MASK = 0xff80,
+ AUDIO_IRQ_ADDR_SHIFT = 7,
+
+ AUDIO_ENVELOPE_ADDR = 0x008,
+ AUDIO_WAVE_DATA_PREV = 0x009,
+
+ AUDIO_ENVELOPE_LOOP_CTRL = 0x00a,
+ AUDIO_EAOFFSET_MASK = 0x01ff,
+ AUDIO_RAMPDOWN_OFFSET_MASK = 0xfe00,
+ AUDIO_RAMPDOWN_OFFSET_SHIFT = 9,
+
+ AUDIO_WAVE_DATA = 0x00b,
+
+ AUDIO_ADPCM_SEL = 0x00d,
+ AUDIO_ADPCM_SEL_MASK = 0xfe00,
+ AUDIO_POINT_NUMBER_MASK = 0x7e00,
+ AUDIO_POINT_NUMBER_SHIFT = 9,
+ AUDIO_ADPCM36_MASK = 0x8000,
+
+ AUDIO_PHASE_HIGH = 0x200,
+ AUDIO_PHASE_HIGH_MASK = 0x0007,
+
+ AUDIO_PHASE_ACCUM_HIGH = 0x201,
+ AUDIO_PHASE_ACCUM_HIGH_MASK = 0x0007,
+
+ AUDIO_TARGET_PHASE_HIGH = 0x202,
+ AUDIO_TARGET_PHASE_HIGH_MASK= 0x0007,
+
+ AUDIO_RAMP_DOWN_CLOCK = 0x203,
+ AUDIO_RAMP_DOWN_CLOCK_MASK = 0x0007,
+
+ AUDIO_PHASE = 0x204,
+ AUDIO_PHASE_ACCUM = 0x205,
+ AUDIO_TARGET_PHASE = 0x206,
+
+ AUDIO_PHASE_CTRL = 0x207,
+ AUDIO_PHASE_OFFSET_MASK = 0x0fff,
+ AUDIO_PHASE_SIGN_MASK = 0x1000,
+ AUDIO_PHASE_SIGN_SHIFT = 12,
+ AUDIO_PHASE_TIME_STEP_MASK = 0xe000,
+ AUDIO_PHASE_TIME_STEP_SHIFT = 13,
+
+ AUDIO_CHAN_OFFSET_MASK = 0xf0f,
+
+ AUDIO_CHANNEL_ENABLE = 0x400,
+ AUDIO_CHANNEL_ENABLE_MASK = 0xffff,
+
+ AUDIO_MAIN_VOLUME = 0x401,
+ AUDIO_MAIN_VOLUME_MASK = 0x007f,
+
+ AUDIO_CHANNEL_FIQ_ENABLE = 0x402,
+ AUDIO_CHANNEL_FIQ_ENABLE_MASK = 0xffff,
+
+ AUDIO_CHANNEL_FIQ_STATUS = 0x403,
+ AUDIO_CHANNEL_FIQ_STATUS_MASK = 0xffff,
+
+ AUDIO_BEAT_BASE_COUNT = 0x404,
+ AUDIO_BEAT_BASE_COUNT_MASK = 0x07ff,
+
+ AUDIO_BEAT_COUNT = 0x405,
+ AUDIO_BEAT_COUNT_MASK = 0x3fff,
+ AUDIO_BIS_MASK = 0x4000,
+ AUDIO_BIE_MASK = 0x8000,
+
+ AUDIO_ENVCLK0 = 0x406,
+
+ AUDIO_ENVCLK0_HIGH = 0x407,
+ AUDIO_ENVCLK0_HIGH_MASK = 0xffff,
+
+ AUDIO_ENVCLK1 = 0x408,
+
+ AUDIO_ENVCLK1_HIGH = 0x409,
+ AUDIO_ENVCLK1_HIGH_MASK = 0xffff,
+
+ AUDIO_ENV_RAMP_DOWN = 0x40a,
+ AUDIO_ENV_RAMP_DOWN_MASK = 0xffff,
+
+ AUDIO_CHANNEL_STOP = 0x40b,
+ AUDIO_CHANNEL_STOP_MASK = 0xffff,
+
+ AUDIO_CHANNEL_ZERO_CROSS = 0x40c,
+ AUDIO_CHANNEL_ZERO_CROSS_MASK = 0xffff,
+
+ AUDIO_CONTROL = 0x40d,
+ AUDIO_CONTROL_MASK = 0x9fe8,
+ AUDIO_CONTROL_SATURATE_MASK = 0x8000,
+ AUDIO_CONTROL_SOFTCH_MASK = 0x1000,
+ AUDIO_CONTROL_COMPEN_MASK = 0x0800,
+ AUDIO_CONTROL_NOHIGH_MASK = 0x0400,
+ AUDIO_CONTROL_NOINT_MASK = 0x0200,
+ AUDIO_CONTROL_EQEN_MASK = 0x0100,
+ AUDIO_CONTROL_VOLSEL_MASK = 0x00c0,
+ AUDIO_CONTROL_VOLSEL_SHIFT = 6,
+ AUDIO_CONTROL_FOF_MASK = 0x0020,
+ AUDIO_CONTROL_INIT_MASK = 0x0008,
+
+ AUDIO_COMPRESS_CTRL = 0x40e,
+ AUDIO_COMPRESS_CTRL_PEAK_MASK = 0x8000,
+ AUDIO_COMPRESS_CTRL_THRESHOLD_MASK = 0x7f00,
+ AUDIO_COMPRESS_CTRL_THRESHOLD_SHIFT = 8,
+ AUDIO_COMPRESS_CTRL_ATTSCALE_MASK = 0x00c0,
+ AUDIO_COMPRESS_CTRL_ATTSCALE_SHIFT = 6,
+ AUDIO_COMPRESS_CTRL_RELSCALE_MASK = 0x0030,
+ AUDIO_COMPRESS_CTRL_RELSCALE_SHIFT = 4,
+ AUDIO_COMPRESS_CTRL_DISZC_MASK = 0x0008,
+ AUDIO_COMPRESS_CTRL_RATIO_MASK = 0x0007,
+
+ AUDIO_CHANNEL_STATUS = 0x40f,
+ AUDIO_CHANNEL_STATUS_MASK = 0xffff,
+
+ AUDIO_WAVE_IN_L = 0x410,
+
+ AUDIO_WAVE_IN_R = 0x411,
+ AUDIO_SOFTIRQ_MASK = 0x8000,
+ AUDIO_SOFTIRQ_EN_MASK = 0x4000,
+ AUDIO_SOFT_PHASE_HIGH_MASK = 0x0070,
+ AUDIO_SOFT_PHASE_HIGH_SHIFT = 4,
+ AUDIO_FIFO_IRQ_THRESHOLD_MASK = 0x000f,
+
+ AUDIO_WAVE_OUT_L = 0x412,
+ AUDIO_WAVE_OUT_R = 0x413,
+
+ AUDIO_CHANNEL_REPEAT = 0x414,
+ AUDIO_CHANNEL_REPEAT_MASK = 0xffff,
+
+ AUDIO_CHANNEL_ENV_MODE = 0x415,
+ AUDIO_CHANNEL_ENV_MODE_MASK = 0xffff,
+
+ AUDIO_CHANNEL_TONE_RELEASE = 0x416,
+ AUDIO_CHANNEL_TONE_RELEASE_MASK = 0xffff,
+
+ AUDIO_CHANNEL_ENV_IRQ = 0x417,
+ AUDIO_CHANNEL_ENV_IRQ_MASK = 0xffff,
+
+ AUDIO_CHANNEL_PITCH_BEND = 0x418,
+ AUDIO_CHANNEL_PITCH_BEND_MASK = 0xffff,
+
+ AUDIO_SOFT_PHASE = 0x419,
- DECLARE_READ16_MEMBER(dma_r);
- DECLARE_WRITE16_MEMBER(dma_w);
+ AUDIO_ATTACK_RELEASE = 0x41a,
+ AUDIO_RELEASE_TIME_MASK = 0x00ff,
+ AUDIO_ATTACK_TIME_MASK = 0xff00,
+ AUDIO_ATTACK_TIME_SHIFT = 8,
- DECLARE_WRITE_LINE_MEMBER(audioirq_w);
- DECLARE_WRITE_LINE_MEMBER(timerirq_w);
- DECLARE_WRITE_LINE_MEMBER(uartirq_w);
- DECLARE_WRITE_LINE_MEMBER(extirq_w);
- DECLARE_WRITE_LINE_MEMBER(ffreq1_w);
- DECLARE_WRITE_LINE_MEMBER(ffreq2_w);
+ AUDIO_EQ_CUTOFF10 = 0x41b,
+ AUDIO_EQ_CUTOFF10_MASK = 0x7f7f,
- DECLARE_READ16_MEMBER(space_r);
+ AUDIO_EQ_CUTOFF32 = 0x41c,
+ AUDIO_EQ_CUTOFF32_MASK = 0x7f7f,
+ AUDIO_EQ_GAIN10 = 0x41d,
+ AUDIO_EQ_GAIN10_MASK = 0x7f7f,
+
+ AUDIO_EQ_GAIN32 = 0x41e,
+ AUDIO_EQ_GAIN32_MASK = 0x7f7f
+ };
+
+ DECLARE_READ16_MEMBER(video_r);
+ DECLARE_WRITE16_MEMBER(video_w);
+ DECLARE_READ16_MEMBER(audio_r);
+ DECLARE_WRITE16_MEMBER(audio_w);
+ DECLARE_READ16_MEMBER(io_r);
+ DECLARE_WRITE16_MEMBER(io_w);
+
+ void check_irqs(const uint16_t changed);
inline void check_video_irq();
void spg2xx_map(address_map &map);
+ static const device_timer_id TIMER_TMB1 = 0;
+ static const device_timer_id TIMER_TMB2 = 1;
static const device_timer_id TIMER_SCREENPOS = 2;
-
+ static const device_timer_id TIMER_BEAT = 3;
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ void update_porta_special_modes();
+ void update_portb_special_modes();
+ void do_gpio(uint32_t offset);
+
+ void do_i2c();
void do_cpu_dma(uint32_t len);
void do_sprite_dma(uint32_t len);
- enum blend_enable_t : bool
- {
- BlendOff = false,
- BlendOn = true
- };
-
- enum rowscroll_enable_t : bool
- {
- RowScrollOff = false,
- RowScrollOn = true
- };
-
- enum flipx_t : bool
- {
- FlipXOff = false,
- FlipXOn = true
- };
-
void apply_saturation(const rectangle &cliprect);
void apply_fade(const rectangle &cliprect);
+ void blit(const rectangle &cliprect, uint32_t xoff, uint32_t yoff, uint32_t attr, uint32_t ctrl, uint32_t bitmap_addr, uint16_t tile);
+ void blit_page(const rectangle &cliprect, int depth, uint32_t bitmap_addr, uint16_t *regs);
+ void blit_sprite(const rectangle &cliprect, int depth, uint32_t base_addr);
+ void blit_sprites(const rectangle &cliprect, int depth);
- template<blend_enable_t Blend, rowscroll_enable_t RowScroll, flipx_t FlipX>
- void blit(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t attr, uint32_t ctrl, uint32_t bitmap_addr, uint16_t tile);
- void blit_page(const rectangle &cliprect, uint32_t scanline, int depth, uint32_t bitmap_addr, uint16_t *regs);
- void blit_sprite(const rectangle &cliprect, uint32_t scanline, int depth, uint32_t base_addr);
- void blit_sprites(const rectangle &cliprect, uint32_t scanline, int depth);
-
+ uint8_t expand_rgb5_to_rgb8(uint8_t val);
uint8_t mix_channel(uint8_t a, uint8_t b);
+ void mix_pixel(uint32_t offset, uint16_t rgb);
+ void set_pixel(uint32_t offset, uint16_t rgb);
+
+ void stop_channel(const uint32_t channel);
+ bool advance_channel(address_space &space, const uint32_t channel);
+ bool fetch_sample(address_space &space, const uint32_t channel);
+ void loop_channel(const uint32_t channel);
+
+ struct rgbtriad_t
+ {
+ uint8_t r, g, b;
+ };
- uint32_t m_screenbuf[320 * 240];
- uint8_t m_rgb5_to_rgb8[32];
- uint32_t m_rgb555_to_rgb888[0x8000];
+ rgbtriad_t m_screenbuf[320 * 240];
bool m_hide_page0;
bool m_hide_page1;
bool m_hide_sprites;
bool m_debug_sprites;
bool m_debug_blit;
- bool m_debug_palette;
uint8_t m_sprite_index_to_debug;
- uint16_t m_dma_regs[0x4];
+ bool m_debug_samples;
+ bool m_debug_rates;
+
+ uint16_t m_audio_regs[0x800];
+ uint8_t m_sample_shift[16];
+ uint32_t m_sample_count[16];
+ uint32_t m_sample_addr[16];
+ double m_channel_rate[16];
+ double m_channel_rate_accum[16];
+ uint32_t m_rampdown_frame[16];
+ uint32_t m_envclk_frame[16];
+ uint32_t m_envelope_addr[16];
+ int m_channel_debug;
+ uint16_t m_audio_curr_beat_base_count;
+
+ uint16_t m_io_regs[0x200];
+ uint8_t m_uart_rx_fifo[8];
+ uint8_t m_uart_rx_fifo_start;
+ uint8_t m_uart_rx_fifo_end;
+ uint8_t m_uart_rx_fifo_count;
+ bool m_uart_rx_available;
uint16_t m_video_regs[0x100];
- uint32_t m_sprite_limit;
- int m_rowscrolloffset; // auto racing in 'zone60' minigames needs this to be 15, the JAKKS games (Star Wars Revenge of the sith - Gunship Battle, Wheel of Fortune, Namco Ms. Pac-Man 5-in-1 Pole Position) need it to be 0, where does it come from?
+ size_t m_sprite_limit;
uint16_t m_pal_flag;
devcb_write16 m_porta_out;
@@ -184,8 +473,6 @@ protected:
devcb_read16 m_portb_in;
devcb_read16 m_portc_in;
- devcb_read16 m_adc_in[2];
-
devcb_write8 m_eeprom_w;
devcb_read8 m_eeprom_r;
@@ -193,7 +480,13 @@ protected:
devcb_write8 m_chip_sel;
+ emu_timer *m_tmb1;
+ emu_timer *m_tmb2;
emu_timer *m_screenpos_timer;
+ emu_timer *m_audio_beat;
+
+ sound_stream *m_stream;
+ oki_adpcm_state m_adpcm[16];
required_device<unsp_device> m_cpu;
required_device<screen_device> m_screen;
@@ -201,23 +494,8 @@ protected:
required_shared_ptr<uint16_t> m_paletteram;
required_shared_ptr<uint16_t> m_spriteram;
- void configure_spg_io(spg2xx_io_device* io);
-
- DECLARE_READ16_MEMBER(porta_r) { return m_porta_in(); };
- DECLARE_READ16_MEMBER(portb_r) { return m_portb_in(); };
- DECLARE_READ16_MEMBER(portc_r) { return m_portc_in(); };
- DECLARE_WRITE16_MEMBER(porta_w) { m_porta_out(offset, data, mem_mask); };
- DECLARE_WRITE16_MEMBER(portb_w) { m_portb_out(offset, data, mem_mask); };
- DECLARE_WRITE16_MEMBER(portc_w) { m_portc_out(offset, data, mem_mask); };
- template <size_t Line> DECLARE_READ16_MEMBER(adc_r) { return m_adc_in[Line](); };
-
- DECLARE_WRITE8_MEMBER(eepromx_w) { m_eeprom_w(offset, data, mem_mask); };
- DECLARE_READ8_MEMBER(eepromx_r) { return m_eeprom_r(); };
-
- DECLARE_WRITE8_MEMBER(tx_w) { m_uart_tx(offset, data, mem_mask); };
- DECLARE_WRITE8_MEMBER(cs_w) { m_chip_sel(offset, data, mem_mask); };
- DECLARE_READ16_MEMBER(get_pal_r) { return m_pal_flag; };
-
+ static const uint32_t s_rampdown_frame_counts[8];
+ static const uint32_t s_envclk_frame_counts[16];
};
class spg24x_device : public spg2xx_device
@@ -232,9 +510,6 @@ public:
}
spg24x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void device_add_mconfig(machine_config &config) override;
-
};
class spg28x_device : public spg2xx_device
@@ -249,9 +524,6 @@ public:
}
spg28x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void device_add_mconfig(machine_config &config) override;
-
};
DECLARE_DEVICE_TYPE(SPG24X, spg24x_device)
diff --git a/src/devices/machine/spg2xx_audio.cpp b/src/devices/machine/spg2xx_audio.cpp
deleted file mode 100644
index a09eb907694..00000000000
--- a/src/devices/machine/spg2xx_audio.cpp
+++ /dev/null
@@ -1,1258 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Ryan Holtz
-/*****************************************************************************
-
- SunPlus SPG2xx-series SoC peripheral emulation (Audio)
-
-**********************************************************************/
-
-#include "emu.h"
-#include "spg2xx_audio.h"
-
-DEFINE_DEVICE_TYPE(SPG2XX_AUDIO, spg2xx_audio_device, "spg2xx", "SPG2xx-series System-on-a-Chip Audio")
-
-#define LOG_SPU_READS (1U << 0)
-#define LOG_SPU_WRITES (1U << 1)
-#define LOG_UNKNOWN_SPU (1U << 2)
-#define LOG_CHANNEL_READS (1U << 3)
-#define LOG_CHANNEL_WRITES (1U << 4)
-#define LOG_ENVELOPES (1U << 5)
-#define LOG_SAMPLES (1U << 6)
-#define LOG_RAMPDOWN (1U << 7)
-#define LOG_BEAT (1U << 8)
-
-#define LOG_ALL (LOG_SPU_READS | LOG_SPU_WRITES | LOG_UNKNOWN_SPU | LOG_CHANNEL_READS | LOG_CHANNEL_WRITES \
- | LOG_ENVELOPES | LOG_SAMPLES | LOG_RAMPDOWN | LOG_BEAT)
-
-#define VERBOSE (0)
-#include "logmacro.h"
-
-#define SPG_DEBUG_AUDIO (0)
-
-
-spg2xx_audio_device::spg2xx_audio_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_sound_interface(mconfig, *this)
- , m_space_read_cb(*this)
- , m_irq_cb(*this)
-{
-}
-
-spg2xx_audio_device::spg2xx_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : spg2xx_audio_device(mconfig, SPG2XX_AUDIO, tag, owner, clock)
-{
-}
-
-
-void spg2xx_audio_device::device_start()
-{
- m_audio_beat = timer_alloc(TIMER_BEAT);
- m_audio_beat->adjust(attotime::never);
-
- m_stream = stream_alloc(0, 2, 281250/4);
-
- m_channel_debug = -1;
-
- save_item(NAME(m_debug_samples));
- save_item(NAME(m_debug_rates));
-
- save_item(NAME(m_audio_regs));
- save_item(NAME(m_audio_phase_regs));
- save_item(NAME(m_audio_ctrl_regs));
-
- save_item(NAME(m_sample_shift));
- save_item(NAME(m_sample_count));
- save_item(NAME(m_sample_addr));
- save_item(NAME(m_channel_rate));
- save_item(NAME(m_channel_rate_accum));
- save_item(NAME(m_rampdown_frame));
- save_item(NAME(m_envclk_frame));
- save_item(NAME(m_envelope_addr));
- save_item(NAME(m_channel_debug));
- save_item(NAME(m_audio_curr_beat_base_count));
-
-
- for (int i = 0; i < 16; i++)
- {
- save_item(NAME(m_adpcm[i].m_signal), i);
- save_item(NAME(m_adpcm[i].m_step), i);
- }
-
- m_space_read_cb.resolve_safe(0);
- m_irq_cb.resolve();
-}
-
-void spg2xx_audio_device::device_reset()
-{
- memset(m_audio_regs, 0, 0x200 * sizeof(uint16_t));
- memset(m_audio_phase_regs, 0, 0x200 * sizeof(uint16_t));
- memset(m_audio_ctrl_regs, 0, 0x400 * sizeof(uint16_t));
-
- memset(m_sample_shift, 0, 16);
- memset(m_sample_count, 0, sizeof(uint32_t) * 16);
- memset(m_sample_addr, 0, sizeof(uint32_t) * 16);
- memset(m_channel_rate, 0, sizeof(double) * 16);
- memset(m_channel_rate_accum, 0, sizeof(double) * 16);
- memset(m_rampdown_frame, 0, sizeof(uint32_t) * 16);
- memset(m_envclk_frame, 4, sizeof(uint32_t) * 16);
- memset(m_envelope_addr, 0, sizeof(uint32_t) * 16);
-
- m_debug_samples = false;
- m_debug_rates = false;
- m_audio_curr_beat_base_count = 0;
-
- m_audio_ctrl_regs[AUDIO_CHANNEL_REPEAT] = 0x3f;
- m_audio_ctrl_regs[AUDIO_CHANNEL_ENV_MODE] = 0x3f;
-
- m_audio_beat->adjust(attotime::from_ticks(4, 281250), 0, attotime::from_ticks(4, 281250));
-}
-
-
-void spg2xx_audio_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id)
- {
- case TIMER_BEAT:
- audio_beat_tick();
- break;
- }
-}
-
-/***********************
-* Audio Hardware *
-***********************/
-void spg2xx_audio_device::check_irqs(const uint16_t changed)
-{
- if (changed & (AUDIO_BIS_MASK | AUDIO_BIE_MASK)) // Beat IRQ
- {
- if ((m_audio_ctrl_regs[AUDIO_BEAT_COUNT] & (AUDIO_BIS_MASK | AUDIO_BIE_MASK)) == (AUDIO_BIS_MASK | AUDIO_BIE_MASK))
- {
- LOGMASKED(LOG_BEAT, "Asserting beat IRQ\n");
- m_irq_cb(true);
- }
- else
- {
- LOGMASKED(LOG_BEAT, "Clearing beat IRQ\n");
- m_irq_cb(false);
- }
- }
-}
-
-READ16_MEMBER(spg2xx_audio_device::audio_ctrl_r)
-{
- uint16_t data = m_audio_ctrl_regs[offset];
-
- switch (offset)
- {
- case AUDIO_CHANNEL_ENABLE:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel Enable: %04x\n", data);
- break;
-
- case AUDIO_MAIN_VOLUME:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Main Volume: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_FIQ_ENABLE:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel FIQ Enable: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_FIQ_STATUS:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel FIQ Acknowledge: %04x\n", data);
- break;
-
- case AUDIO_BEAT_BASE_COUNT:
- LOGMASKED(LOG_SPU_READS | LOG_BEAT, "audio_ctrl_r: Beat Base Count: %04x\n", data);
- break;
-
- case AUDIO_BEAT_COUNT:
- LOGMASKED(LOG_SPU_READS | LOG_BEAT, "audio_ctrl_r: Beat Count: %04x\n", data);
- break;
-
- case AUDIO_ENVCLK0:
- case AUDIO_ENVCLK1:
- LOGMASKED(LOG_SPU_READS | LOG_ENVELOPES, "audio_ctrl_r: Envelope Interval %d (lo): %04x\n", offset == AUDIO_ENVCLK0 ? 0 : 1, data);
- break;
-
- case AUDIO_ENVCLK0_HIGH:
- case AUDIO_ENVCLK1_HIGH:
- LOGMASKED(LOG_SPU_READS | LOG_ENVELOPES, "audio_ctrl_r: Envelope Interval %d (hi): %04x\n", offset == AUDIO_ENVCLK0_HIGH ? 0 : 1, data);
- break;
-
- case AUDIO_ENV_RAMP_DOWN:
- LOGMASKED(LOG_SPU_READS | LOG_RAMPDOWN, "audio_ctrl_r: Envelope Fast Ramp Down: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_STOP:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel Stop Status: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_ZERO_CROSS:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel Zero-Cross Enable: %04x\n", data);
- break;
-
- case AUDIO_CONTROL:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Control: %04x\n", data);
- break;
-
- case AUDIO_COMPRESS_CTRL:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Compressor Control: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_STATUS:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel Status: %04x\n", data);
- break;
-
- case AUDIO_WAVE_IN_L:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Wave In (L) / FIFO Write Data: %04x\n", data);
- break;
-
- case AUDIO_WAVE_IN_R:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Wave In (R) / Software Channel FIFO IRQ Control: %04x\n", data);
- break;
-
- case AUDIO_WAVE_OUT_L:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Wave Out (L): %04x\n", data);
- break;
-
- case AUDIO_WAVE_OUT_R:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Wave Out (R): %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_REPEAT:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel Repeat Enable: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_ENV_MODE:
- LOGMASKED(LOG_SPU_READS | LOG_ENVELOPES, "audio_ctrl_r: Channel Envelope Enable: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_TONE_RELEASE:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel Tone Release Enable: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_ENV_IRQ:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel Envelope IRQ Status: %04x\n", data);
- break;
-
- case AUDIO_CHANNEL_PITCH_BEND:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Channel Pitch Bend Enable: %04x\n", data);
- break;
-
- case AUDIO_SOFT_PHASE:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Software Channel Phase: %04x\n", data);
- break;
-
- case AUDIO_ATTACK_RELEASE:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: Attack/Release Time Control: %04x\n", data);
- break;
-
- case AUDIO_EQ_CUTOFF10:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: EQ Cutoff Frequency 0/1: %04x\n", data);
- break;
-
- case AUDIO_EQ_CUTOFF32:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: EQ Cutoff Frequency 2/3: %04x\n", data);
- break;
-
- case AUDIO_EQ_GAIN10:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: EQ Cutoff Gain 0/1: %04x\n", data);
- break;
-
- case AUDIO_EQ_GAIN32:
- LOGMASKED(LOG_SPU_READS, "audio_ctrl_r: EQ Cutoff Gain 2/3: %04x\n", data);
- break;
-
- default:
- LOGMASKED(LOG_UNKNOWN_SPU, "audio_ctrl_r: Unknown register %04x = %04x\n", 0x3000 + offset, data);
- break;
- }
-
- return data;
-}
-
-READ16_MEMBER(spg2xx_audio_device::audio_r)
-{
- const uint16_t channel = (offset & 0x00f0) >> 4;
- uint16_t data = m_audio_regs[offset];
-
-
- switch (offset & AUDIO_CHAN_OFFSET_MASK)
- {
- case AUDIO_WAVE_ADDR:
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Wave Addr (lo): %04x\n", channel, data);
- break;
-
- case AUDIO_MODE:
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Mode: %04x (ADPCM:%d, 16M:%d, TONE:%d, LADDR_HI:%04x, WADDR_HI:%04x)\n", channel, data,
- get_adpcm_bit(channel), get_16bit_bit(channel), get_tone_mode(channel), get_loop_addr_high(channel), get_wave_addr_high(channel));
- break;
-
- case AUDIO_LOOP_ADDR:
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Loop Addr: %04x\n", channel, data);
- break;
-
- case AUDIO_PAN_VOL:
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Pan/Vol: %04x (PAN:%02x, VOL:%02x)\n", channel, data,
- get_pan(channel), get_volume(channel));
- break;
-
- case AUDIO_ENVELOPE0:
- LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope0: %04x (RPTPER:%d, TARGET:%02x, SIGN:%d, INC:%02x)\n", channel, data,
- get_repeat_period_bit(channel), get_envelope_target(channel), get_envelope_sign_bit(channel), get_envelope_inc(channel));
- break;
-
- case AUDIO_ENVELOPE_DATA:
- LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope Data: %04x (CNT:%d, EDD:%02x)\n", channel, data,
- get_envelope_count(channel), get_edd(channel));
- break;
-
- case AUDIO_ENVELOPE1:
- LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope1 Data: %04x (RPTCNT:%02x, RPT:%d, LOAD:%02x)\n", channel, data,
- get_envelope_repeat_count(channel), get_envelope_repeat_bit(channel), get_envelope_load(channel));
- break;
-
- case AUDIO_ENVELOPE_ADDR_HIGH:
- LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope Addr (hi): %04x (IRQADDR:%03x, IRQEN:%d, EADDR_HI:%02x)\n", channel, data,
- get_audio_irq_addr(channel), get_audio_irq_enable_bit(channel), get_envelope_addr_high(channel));
- break;
-
- case AUDIO_ENVELOPE_ADDR:
- LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope Addr (lo): %04x \n", channel, data);
- break;
-
- case AUDIO_WAVE_DATA_PREV:
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Wave Data Prev: %04x \n", channel, data);
- break;
-
- case AUDIO_ENVELOPE_LOOP_CTRL:
- LOGMASKED(LOG_CHANNEL_READS | LOG_ENVELOPES, "audio_r: Channel %d: Envelope Loop Ctrl: %04x (RDOFFS:%02x, EAOFFS:%03x)\n", channel, data,
- get_rampdown_offset(channel), get_envelope_eaoffset(channel));
- break;
-
- case AUDIO_WAVE_DATA:
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: Wave Data: %04x\n", channel, data);
- break;
-
- case AUDIO_ADPCM_SEL:
- LOGMASKED(LOG_CHANNEL_READS, "audio_r: Channel %d: ADPCM Sel: %04x (ADPCM36:%d, POINTNUM:%02x\n", channel, data,
- get_adpcm36_bit(channel), get_point_number(channel));
- break;
-
- default:
- LOGMASKED(LOG_UNKNOWN_SPU, "audio_r: Unknown register %04x\n", 0x3000 + offset);
- break;
-
- }
-
- return data;
-}
-
-
-READ16_MEMBER(spg2xx_audio_device::audio_phase_r)
-{
- const uint16_t channel = (offset & 0x00f0) >> 4;
- uint16_t data = m_audio_phase_regs[offset];
-
- switch (offset & AUDIO_CHAN_OFFSET_MASK)
- {
- case AUDIO_PHASE_HIGH:
- LOGMASKED(LOG_CHANNEL_READS, "audio_phase_r: Channel %d: Phase High: %04x\n", channel, data);
- break;
-
- case AUDIO_PHASE_ACCUM_HIGH:
- LOGMASKED(LOG_CHANNEL_READS, "audio_phase_r: Channel %d: Phase Accum High: %04x\n", channel, data);
- break;
-
- case AUDIO_TARGET_PHASE_HIGH:
- LOGMASKED(LOG_CHANNEL_READS, "audio_phase_r: Channel %d: Target Phase High: %04x\n", channel, data);
- break;
-
- case AUDIO_RAMP_DOWN_CLOCK:
- LOGMASKED(LOG_CHANNEL_READS | LOG_RAMPDOWN, "audio_phase_r: Channel %d: Rampdown Clock: %04x\n", channel, data);
- break;
-
- case AUDIO_PHASE:
- LOGMASKED(LOG_CHANNEL_READS, "audio_phase_r: Channel %d: Phase: %04x\n", channel, data);
- break;
-
- case AUDIO_PHASE_ACCUM:
- LOGMASKED(LOG_CHANNEL_READS, "audio_phase_r: Channel %d: Phase Accum: %04x\n", channel, data);
- break;
-
- case AUDIO_TARGET_PHASE:
- LOGMASKED(LOG_CHANNEL_READS, "audio_phase_r: Channel %d: Target Phase: %04x\n", channel, data);
- break;
-
- case AUDIO_PHASE_CTRL:
- LOGMASKED(LOG_CHANNEL_READS, "audio_phase_r: Channel %d: Phase Ctrl: %04x (TIMESTEP:%d, SIGN:%d, OFFSET:%03x\n", channel, data,
- get_phase_time_step(channel), get_phase_sign_bit(channel), get_phase_offset(channel));
- break;
-
- default:
- LOGMASKED(LOG_UNKNOWN_SPU, "audio_phase_r: Unknown register %04x\n", 0x3000 + offset);
- break;
- }
-
- return data;
-}
-
-WRITE16_MEMBER(spg2xx_audio_device::audio_ctrl_w)
-{
- switch (offset)
- {
- case AUDIO_CHANNEL_ENABLE:
- {
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel Enable: %04x\n", data);
- const uint16_t changed = m_audio_ctrl_regs[AUDIO_CHANNEL_ENABLE] ^ data;
- for (uint32_t channel_bit = 0; channel_bit < 16; channel_bit++)
- {
- const uint16_t mask = 1 << channel_bit;
- if (!(changed & mask))
- continue;
-
- if (data & mask)
- {
- if (!(m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] & mask))
- {
- LOGMASKED(LOG_SPU_WRITES, "Enabling channel %d\n", channel_bit);
- m_audio_ctrl_regs[offset] |= mask;
- if (!(m_audio_ctrl_regs[AUDIO_CHANNEL_STOP] & mask))
- {
- LOGMASKED(LOG_SPU_WRITES, "Stop not set, starting playback on channel %d, mask %04x\n", channel_bit, mask);
- m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] |= mask;
- m_sample_addr[channel_bit] = get_wave_addr(channel_bit);
- m_envelope_addr[channel_bit] = get_envelope_addr(channel_bit);
- set_envelope_count(channel_bit, get_envelope_load(channel_bit));
- }
- m_adpcm[channel_bit].reset();
- m_sample_shift[channel_bit] = 0;
- m_sample_count[channel_bit] = 0;
- }
- }
- else
- {
- stop_channel(channel_bit);
- //m_audio_ctrl_regs[offset] &= ~mask;
- //m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] &= ~mask;
- //m_audio_ctrl_regs[AUDIO_CHANNEL_STOP] |= mask;
- //m_audio_ctrl_regs[AUDIO_CHANNEL_TONE_RELEASE] &= ~mask;
- }
- }
- break;
- }
-
- case AUDIO_MAIN_VOLUME:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Main Volume: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_MAIN_VOLUME_MASK;
- break;
-
- case AUDIO_CHANNEL_FIQ_ENABLE:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel FIQ Enable: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_CHANNEL_FIQ_ENABLE_MASK;
- break;
-
- case AUDIO_CHANNEL_FIQ_STATUS:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel FIQ Acknowledge: %04x\n", data);
- m_audio_ctrl_regs[offset] &= ~(data & AUDIO_CHANNEL_FIQ_STATUS_MASK);
- break;
-
- case AUDIO_BEAT_BASE_COUNT:
- LOGMASKED(LOG_SPU_WRITES | LOG_BEAT, "audio_ctrl_w: Beat Base Count: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_BEAT_BASE_COUNT_MASK;
- m_audio_curr_beat_base_count = m_audio_ctrl_regs[offset];
- break;
-
- case AUDIO_BEAT_COUNT:
- {
- LOGMASKED(LOG_SPU_WRITES | LOG_BEAT, "audio_ctrl_w: Beat Count: %04x\n", data);
- const uint16_t old = m_audio_ctrl_regs[offset];
- m_audio_ctrl_regs[offset] &= ~(data & AUDIO_BIS_MASK);
- m_audio_ctrl_regs[offset] &= AUDIO_BIS_MASK;
- m_audio_ctrl_regs[offset] |= data & ~AUDIO_BIS_MASK;
- const uint16_t changed = old ^ m_audio_ctrl_regs[offset];
- if (changed & (AUDIO_BIS_MASK | AUDIO_BIE_MASK))
- {
- LOGMASKED(LOG_BEAT, "BIS mask changed, updating IRQ\n");
- check_irqs(changed & (AUDIO_BIS_MASK | AUDIO_BIE_MASK));
- }
- break;
- }
-
- case AUDIO_ENVCLK0:
- case AUDIO_ENVCLK1:
- {
- LOGMASKED(LOG_SPU_WRITES | LOG_ENVELOPES, "audio_ctrl_w: Envelope Interval %d (lo): %04x\n", offset == AUDIO_ENVCLK0 ? 0 : 1, data);
- const uint16_t old = m_audio_ctrl_regs[offset];
- m_audio_ctrl_regs[offset] = data;
- const uint16_t changed = old ^ m_audio_ctrl_regs[offset];
-
- if (!changed)
- break;
-
- const uint8_t channel_offset = offset == AUDIO_ENVCLK0 ? 0 : 8;
- for (uint8_t channel_bit = 0; channel_bit < 4; channel_bit++)
- {
- const uint8_t shift = channel_bit << 2;
- const uint16_t mask = 0x0f << shift;
- if (changed & mask)
- {
- m_envclk_frame[channel_bit + channel_offset] = get_envclk_frame_count(channel_bit + channel_offset);
- }
- }
- break;
- }
-
- case AUDIO_ENVCLK0_HIGH:
- case AUDIO_ENVCLK1_HIGH:
- {
- LOGMASKED(LOG_SPU_WRITES | LOG_ENVELOPES, "audio_ctrl_w: Envelope Interval %d (hi): %04x\n", offset == AUDIO_ENVCLK0_HIGH ? 0 : 1, data);
- const uint16_t old = m_audio_ctrl_regs[offset];
- m_audio_ctrl_regs[offset] = data;
- const uint16_t changed = old ^ m_audio_ctrl_regs[offset];
- if (!changed)
- break;
-
- const uint8_t channel_offset = offset == AUDIO_ENVCLK0_HIGH ? 0 : 8;
- for (uint8_t channel_bit = 0; channel_bit < 4; channel_bit++)
- {
- const uint8_t shift = channel_bit << 2;
- const uint16_t mask = 0x0f << shift;
- if (changed & mask)
- {
- m_envclk_frame[channel_bit + channel_offset + 4] = get_envclk_frame_count(channel_bit + channel_offset);
- }
- }
- break;
- }
-
- case AUDIO_ENV_RAMP_DOWN:
- {
- LOGMASKED(LOG_SPU_WRITES | LOG_RAMPDOWN, "audio_ctrl_w: Envelope Fast Ramp Down: %04x\n", data);
- const uint16_t old = m_audio_ctrl_regs[offset];
- m_audio_ctrl_regs[offset] = (data & AUDIO_ENV_RAMP_DOWN_MASK) & m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS];
- const uint16_t changed = old ^ m_audio_ctrl_regs[offset];
- if (!changed)
- break;
-
- for (uint32_t channel_bit = 0; channel_bit < 16; channel_bit++)
- {
- const uint16_t mask = 1 << channel_bit;
- if ((changed & mask) && (data & mask))
- {
- m_rampdown_frame[channel_bit] = get_rampdown_frame_count(channel_bit);
- LOGMASKED(LOG_RAMPDOWN, "Preparing to ramp down channel %d in %d ticks\n", channel_bit, m_rampdown_frame[channel_bit] / 13);
- }
- }
- break;
- }
-
- case AUDIO_CHANNEL_STOP:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel Stop Status: %04x\n", data);
- m_audio_ctrl_regs[offset] &= ~data;
- break;
-
- case AUDIO_CHANNEL_ZERO_CROSS:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel Zero-Cross Enable: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_CHANNEL_ZERO_CROSS_MASK;
- break;
-
- case AUDIO_CONTROL:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Control: %04x (SOFTCH:%d, COMPEN:%d, NOHIGH:%d, NOINT:%d, EQEN:%d, VOLSEL:%d)\n", data
- , (data & AUDIO_CONTROL_SOFTCH_MASK) ? 1 : 0
- , (data & AUDIO_CONTROL_COMPEN_MASK) ? 1 : 0
- , (data & AUDIO_CONTROL_NOHIGH_MASK) ? 1 : 0
- , (data & AUDIO_CONTROL_NOINT_MASK) ? 1 : 0
- , (data & AUDIO_CONTROL_EQEN_MASK) ? 1 : 0
- , (data & AUDIO_CONTROL_VOLSEL_MASK) >> AUDIO_CONTROL_VOLSEL_SHIFT);
- m_audio_ctrl_regs[offset] = data & AUDIO_CONTROL_MASK;
- break;
-
- case AUDIO_COMPRESS_CTRL:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Compressor Control: %04x\n", data);
- m_audio_ctrl_regs[offset] = data;
- break;
-
- case AUDIO_CHANNEL_STATUS:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel Status (read-only): %04x\n", data);
- break;
-
- case AUDIO_WAVE_IN_L:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Wave In (L) / FIFO Write Data: %04x\n", data);
- m_audio_ctrl_regs[offset] = data;
- break;
-
- case AUDIO_WAVE_IN_R:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Wave In (R) / Software Channel FIFO IRQ Control: %04x\n", data);
- m_audio_ctrl_regs[offset] = data;
- break;
-
- case AUDIO_WAVE_OUT_L:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Wave Out (L): %04x\n", data);
- m_audio_ctrl_regs[offset] = data;
- break;
-
- case AUDIO_WAVE_OUT_R:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Wave Out (R): %04x\n", data);
- m_audio_ctrl_regs[offset] = data;
- break;
-
- case AUDIO_CHANNEL_REPEAT:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel Repeat Enable: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_CHANNEL_REPEAT_MASK;
- break;
-
- case AUDIO_CHANNEL_ENV_MODE:
- LOGMASKED(LOG_SPU_WRITES | LOG_ENVELOPES, "audio_ctrl_w: Channel Envelope Enable: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_CHANNEL_ENV_MODE_MASK;
- break;
-
- case AUDIO_CHANNEL_TONE_RELEASE:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel Tone Release Enable: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_CHANNEL_TONE_RELEASE_MASK;
- break;
-
- case AUDIO_CHANNEL_ENV_IRQ:
- LOGMASKED(LOG_SPU_WRITES | LOG_ENVELOPES, "audio_ctrl_w: Channel Envelope IRQ Acknowledge: %04x\n", data);
- m_audio_ctrl_regs[offset] &= ~data & AUDIO_CHANNEL_ENV_IRQ_MASK;
- break;
-
- case AUDIO_CHANNEL_PITCH_BEND:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Channel Pitch Bend Enable: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_CHANNEL_PITCH_BEND_MASK;
- break;
-
- case AUDIO_SOFT_PHASE:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Software Channel Phase: %04x\n", data);
- m_audio_ctrl_regs[offset] = data;
- break;
-
- case AUDIO_ATTACK_RELEASE:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: Attack/Release Time Control: %04x\n", data);
- m_audio_ctrl_regs[offset] = data;
- break;
-
- case AUDIO_EQ_CUTOFF10:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: EQ Cutoff Frequency 0/1: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_EQ_CUTOFF10_MASK;
- break;
-
- case AUDIO_EQ_CUTOFF32:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: EQ Cutoff Frequency 2/3: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_EQ_CUTOFF32_MASK;
- break;
-
- case AUDIO_EQ_GAIN10:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: EQ Cutoff Gain 0/1: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_EQ_GAIN10_MASK;
- break;
-
- case AUDIO_EQ_GAIN32:
- LOGMASKED(LOG_SPU_WRITES, "audio_ctrl_w: EQ Cutoff Gain 2/3: %04x\n", data);
- m_audio_ctrl_regs[offset] = data & AUDIO_EQ_GAIN32_MASK;
- break;
-
- default:
- m_audio_ctrl_regs[offset] = data;
- LOGMASKED(LOG_UNKNOWN_SPU, "audio_ctrl_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
- break;
- }
-}
-
-WRITE16_MEMBER(spg2xx_audio_device::audio_phase_w)
-{
- const uint16_t channel = (offset & 0x00f0) >> 4;
-
- switch (offset & AUDIO_CHAN_OFFSET_MASK)
- {
- case AUDIO_PHASE_HIGH:
- m_audio_phase_regs[offset] = data & AUDIO_PHASE_HIGH_MASK;
- m_channel_rate[channel] = ((double)get_phase(channel) * 140625.0 * 2.0) / (double)(1 << 19);
- m_channel_rate_accum[channel] = 0.0;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_phase_w: Channel %d: Phase High: %04x (rate: %f)\n", channel, data, m_channel_rate[channel]);
- break;
-
- case AUDIO_PHASE_ACCUM_HIGH:
- m_audio_phase_regs[offset] = data & AUDIO_PHASE_ACCUM_HIGH_MASK;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_phase_w: Channel %d: Phase Accum High: %04x\n", channel, data);
- break;
-
- case AUDIO_TARGET_PHASE_HIGH:
- m_audio_phase_regs[offset] = data & AUDIO_TARGET_PHASE_HIGH_MASK;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_phase_w: Channel %d: Target Phase High: %04x\n", channel, data);
- break;
-
- case AUDIO_RAMP_DOWN_CLOCK:
- m_audio_phase_regs[offset] = data & AUDIO_RAMP_DOWN_CLOCK_MASK;
- LOGMASKED(LOG_CHANNEL_WRITES | LOG_RAMPDOWN, "audio_phase_w: Channel %d: Rampdown Clock: %04x\n", channel, data);
- break;
-
- case AUDIO_PHASE:
- m_audio_phase_regs[offset] = data;
- m_channel_rate[channel] = ((double)get_phase(channel) * 140625.0 * 2.0) / (double)(1 << 19);
- m_channel_rate_accum[channel] = 0.0;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_phase_w: Channel %d: Phase: %04x (rate: %f)\n", channel, data, m_channel_rate[channel]);
- break;
-
- case AUDIO_PHASE_ACCUM:
- m_audio_phase_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_phase_w: Channel %d: Phase Accum: %04x\n", channel, data);
- break;
-
- case AUDIO_TARGET_PHASE:
- m_audio_phase_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_phase_w: Channel %d: Target Phase: %04x\n", channel, data);
- break;
-
- case AUDIO_PHASE_CTRL:
- m_audio_phase_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_phase_w: Channel %d: Phase Ctrl: %04x (TIMESTEP:%d, SIGN:%d, OFFSET:%03x\n", channel, data,
- get_phase_time_step(channel), get_phase_sign_bit(channel), get_phase_offset(channel));
- break;
-
- default:
- m_audio_phase_regs[offset] = data;
- LOGMASKED(LOG_UNKNOWN_SPU, "audio_phase_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
- break;
- }
-}
-
-
-WRITE16_MEMBER(spg2xx_audio_device::audio_w)
-{
- const uint16_t channel = (offset & 0x00f0) >> 4;
-
- switch (offset & AUDIO_CHAN_OFFSET_MASK)
- {
- case AUDIO_WAVE_ADDR:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Wave Addr (lo): %04x\n", channel, data);
- break;
-
- case AUDIO_MODE:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Mode: %04x (ADPCM:%d, 16M:%d, TONE:%d, LADDR_HI:%04x, WADDR_HI:%04x)\n", channel, data,
- get_adpcm_bit(channel), get_16bit_bit(channel), get_tone_mode(channel), get_loop_addr_high(channel), get_wave_addr_high(channel));
- break;
-
- case AUDIO_LOOP_ADDR:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Loop Addr: %04x\n", channel, data);
- break;
-
- case AUDIO_PAN_VOL:
- m_audio_regs[offset] = data & AUDIO_PAN_VOL_MASK;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Pan/Vol: %04x (PAN:%02x, VOL:%02x)\n", channel, data,
- get_pan(channel), get_volume(channel));
- break;
-
- case AUDIO_ENVELOPE0:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope0: %04x (RPTPER:%d, TARGET:%02x, SIGN:%d, INC:%02x)\n", channel, data,
- get_repeat_period_bit(channel), get_envelope_target(channel), get_envelope_sign_bit(channel), get_envelope_inc(channel));
- break;
-
- case AUDIO_ENVELOPE_DATA:
- m_audio_regs[offset] = data & AUDIO_ENVELOPE_DATA_MASK;
- LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope Data: %04x (CNT:%d, EDD:%02x)\n", channel, data,
- get_envelope_count(channel), get_edd(channel));
- break;
-
- case AUDIO_ENVELOPE1:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope1 Data: %04x (RPTCNT:%02x, RPT:%d, LOAD:%02x)\n", channel, data,
- get_envelope_repeat_count(channel), get_envelope_repeat_bit(channel), get_envelope_load(channel));
- break;
-
- case AUDIO_ENVELOPE_ADDR_HIGH:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope Addr (hi): %04x (IRQADDR:%03x, IRQEN:%d, EADDR_HI:%02x)\n", channel, data,
- get_audio_irq_addr(channel), get_audio_irq_enable_bit(channel), get_envelope_addr_high(channel));
- break;
-
- case AUDIO_ENVELOPE_ADDR:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope Addr (lo): %04x\n", channel, data);
- break;
-
- case AUDIO_WAVE_DATA_PREV:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Wave Data Prev: %04x \n", channel, data);
- break;
-
- case AUDIO_ENVELOPE_LOOP_CTRL:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES | LOG_ENVELOPES, "audio_w: Channel %d: Envelope Loop Ctrl: %04x (RDOFFS:%02x, EAOFFS:%03x)\n", channel, data,
- get_rampdown_offset(channel), get_envelope_eaoffset(channel));
- break;
-
- case AUDIO_WAVE_DATA:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: Wave Data: %04x\n", channel, data);
- break;
-
- case AUDIO_ADPCM_SEL:
- m_audio_regs[offset] = data & AUDIO_ADPCM_SEL_MASK;
- LOGMASKED(LOG_CHANNEL_WRITES, "audio_w: Channel %d: ADPCM Sel: %04x (ADPCM36:%d, POINTNUM:%02x\n", channel, data,
- get_adpcm36_bit(channel), get_point_number(channel));
- break;
-
- default:
- m_audio_regs[offset] = data;
- LOGMASKED(LOG_UNKNOWN_SPU, "audio_w: Unknown register %04x = %04x\n", 0x3000 + offset, data);
- break;
-
- }
-}
-
-void spg2xx_audio_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
-{
- stream_sample_t *out_l = outputs[0];
- stream_sample_t *out_r = outputs[1];
-
- for (int i = 0; i < samples; i++)
- {
- int32_t left_total = 0;
- int32_t right_total = 0;
-
- for (uint32_t channel = 0; channel < 16; channel++)
- {
- if (!get_channel_status(channel))
- {
- continue;
- }
-
- if (SPG_DEBUG_AUDIO && m_debug_rates)
- printf("%f:%f ", m_channel_rate[channel], m_channel_rate_accum[channel]);
- bool playing = advance_channel(channel);
- if (playing)
- {
- int32_t sample = (int16_t)(m_audio_regs[(channel << 4) | AUDIO_WAVE_DATA] ^ 0x8000);
- if (!(m_audio_ctrl_regs[AUDIO_CONTROL] & AUDIO_CONTROL_NOINT_MASK))
- {
- int32_t prev_sample = (int16_t)(m_audio_regs[(channel << 4) | AUDIO_WAVE_DATA_PREV] ^ 0x8000);
- int16_t lerp_factor = (int16_t)((m_channel_rate_accum[channel] / 70312.5) * 256.0);
- prev_sample = (prev_sample * (0x100 - lerp_factor)) >> 8;
- sample = (sample * lerp_factor) >> 8;
- sample += prev_sample;
- }
-
- sample = (sample * (int32_t)get_edd(channel)) >> 7;
-
- int32_t vol = get_volume(channel);
- int32_t pan = get_pan(channel);
-
- int32_t pan_left, pan_right;
- if (pan < 0x40)
- {
- pan_left = 0x7f * vol;
- pan_right = pan * 2 * vol;
- }
- else
- {
- pan_left = (0x7f - pan) * 2 * vol;
- pan_right = 0x7f * vol;
- }
-
- left_total += ((int16_t)sample * (int16_t)pan_left) >> 14;
- right_total += ((int16_t)sample * (int16_t)pan_right) >> 14;
-
- const uint16_t mask = (1 << channel);
- if (m_audio_ctrl_regs[AUDIO_ENV_RAMP_DOWN] & mask)
- {
- if (m_rampdown_frame[channel] == 0)
- {
- LOGMASKED(LOG_RAMPDOWN, "Ticking rampdown for channel %d\n", channel);
- audio_rampdown_tick(channel);
- }
- m_rampdown_frame[channel]--;
- }
- else if (!(m_audio_ctrl_regs[AUDIO_CHANNEL_ENV_MODE] & mask))
- {
- if (m_envclk_frame[channel] == 0)
- {
- LOGMASKED(LOG_ENVELOPES, "Ticking envelope for channel %d\n", channel);
- audio_envelope_tick(channel);
- m_envclk_frame[channel] = get_envclk_frame_count(channel);
- }
- m_envclk_frame[channel]--;
- }
- }
- }
-
- switch (get_vol_sel())
- {
- case 0: // 1/16
- left_total >>= 4;
- right_total >>= 4;
- break;
- case 1: // 1/4
- case 2: // 1
- case 3: // 2 // Both x1 and x2 clip like mad even with only 6 voices. Hack it for now.
- left_total >>= 2;
- right_total >>= 2;
- break;
- }
- *out_l++ = (left_total * (int16_t)m_audio_ctrl_regs[AUDIO_MAIN_VOLUME]) >> 7;
- *out_r++ = (right_total * (int16_t)m_audio_ctrl_regs[AUDIO_MAIN_VOLUME]) >> 7;
- }
-}
-
-inline void spg2xx_audio_device::stop_channel(const uint32_t channel)
-{
- // TODO: IRQs
- m_audio_ctrl_regs[AUDIO_CHANNEL_ENABLE] &= ~(1 << channel);
- m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] &= ~(1 << channel);
- m_audio_regs[(channel << 4) | AUDIO_MODE] &= ~AUDIO_ADPCM_MASK;
- m_audio_ctrl_regs[AUDIO_CHANNEL_TONE_RELEASE] &= ~(1 << channel);
- m_audio_ctrl_regs[AUDIO_ENV_RAMP_DOWN] &= ~(1 << channel);
-}
-
-bool spg2xx_audio_device::advance_channel(const uint32_t channel)
-{
- m_channel_rate_accum[channel] += m_channel_rate[channel];
- uint32_t samples_to_advance = 0;
- while (m_channel_rate_accum[channel] >= 70312.5)
- {
- m_channel_rate_accum[channel] -= 70312.5;
- samples_to_advance++;
- }
-
- if (!samples_to_advance)
- return true;
-
- bool playing = true;
-
- for (uint32_t sample = 0; sample < samples_to_advance; sample++)
- {
- playing = fetch_sample(channel);
- if (!playing)
- break;
-
- if (get_adpcm_bit(channel))
- {
- // ADPCM mode
- m_sample_shift[channel] += 4;
- if (m_sample_shift[channel] >= 16)
- {
- m_sample_shift[channel] = 0;
- m_sample_addr[channel]++;
- }
- }
- else if (get_16bit_bit(channel))
- {
- // 16-bit mode
- m_sample_addr[channel]++;
- }
- else
- {
- // 8-bit mode
- m_sample_shift[channel] += 8;
- if (m_sample_shift[channel] >= 16)
- {
- m_sample_shift[channel] = 0;
- m_sample_addr[channel]++;
- }
- }
- }
-
- return playing;
-}
-
-uint16_t spg2xx_audio_device::read_space(offs_t offset)
-{
- return m_space_read_cb(offset);
-}
-
-bool spg2xx_audio_device::fetch_sample(const uint32_t channel)
-{
- const uint32_t channel_mask = channel << 4;
- m_audio_regs[channel_mask | AUDIO_WAVE_DATA_PREV] = m_audio_regs[channel_mask | AUDIO_WAVE_DATA];
-
- const uint32_t wave_data_reg = channel_mask | AUDIO_WAVE_DATA;
- const uint16_t tone_mode = get_tone_mode(channel);
- uint16_t raw_sample = tone_mode ? read_space(m_sample_addr[channel]) : m_audio_regs[wave_data_reg];
-
- LOGMASKED(LOG_SAMPLES, "Channel %d: Raw sample %04x\n", channel, raw_sample);
-
- if (get_adpcm_bit(channel))
- {
- // ADPCM mode
- if (tone_mode != 0 && raw_sample == 0xffff)
- {
- if (tone_mode == AUDIO_TONE_MODE_HW_ONESHOT)
- {
- LOGMASKED(LOG_SAMPLES, "ADPCM stopped after %d samples\n", m_sample_count[channel]);
- m_sample_count[channel] = 0;
- stop_channel(channel);
- return false;
- }
- else
- {
- LOGMASKED(LOG_SAMPLES, "ADPCM looping after %d samples\n", m_sample_count[channel]);
- m_sample_count[channel] = 0;
- loop_channel(channel);
- m_audio_regs[(channel << 4) | AUDIO_MODE] &= ~AUDIO_ADPCM_MASK;
- }
- }
- else
- {
- m_audio_regs[wave_data_reg] = raw_sample;
- m_audio_regs[wave_data_reg] >>= m_sample_shift[channel];
- const uint8_t adpcm_sample = (uint8_t)(m_audio_regs[wave_data_reg] & 0x000f);
- m_audio_regs[wave_data_reg] = (uint16_t)(m_adpcm[channel].clock(adpcm_sample) << 4) ^ 0x8000;
- }
- m_sample_count[channel]++;
- }
- else if (get_16bit_bit(channel))
- {
- // 16-bit mode
- if (tone_mode != 0 && raw_sample == 0xffff)
- {
- if (tone_mode == AUDIO_TONE_MODE_HW_ONESHOT)
- {
- LOGMASKED(LOG_SAMPLES, "16-bit PCM stopped after %d samples\n", m_sample_count[channel]);
- m_sample_count[channel] = 0;
- stop_channel(channel);
- return false;
- }
- else
- {
- LOGMASKED(LOG_SAMPLES, "16-bit PCM looping after %d samples\n", m_sample_count[channel]);
- m_sample_count[channel] = 0;
- loop_channel(channel);
- }
- }
- else
- {
- m_audio_regs[wave_data_reg] = raw_sample;
- }
- m_sample_count[channel]++;
- }
- else
- {
- // 8-bit mode
- LOGMASKED(LOG_SAMPLES, "Channel %d: Processing as 8-bit sample, tone_mode is %d, sample_shift is %d\n", channel, tone_mode, m_sample_shift[channel]);
- if (tone_mode != 0)
- {
- if (m_sample_shift[channel])
- raw_sample &= 0xff00;
- else
- raw_sample <<= 8;
- raw_sample |= raw_sample >> 8;
-
- if (raw_sample == 0xffff)
- {
- if (tone_mode == AUDIO_TONE_MODE_HW_ONESHOT)
- {
- LOGMASKED(LOG_SAMPLES, "Channel %d: 8-bit PCM stopped after %d samples\n", channel, m_sample_count[channel]);
- m_sample_count[channel] = 0;
- stop_channel(channel);
- return false;
- }
- else
- {
- LOGMASKED(LOG_SAMPLES, "Channel %d: 8-bit PCM looping after %d samples\n", channel, m_sample_count[channel]);
- m_sample_count[channel] = 0;
- loop_channel(channel);
- }
- }
- else
- {
- m_audio_regs[wave_data_reg] = raw_sample;
- }
- }
- m_sample_count[channel]++;
- }
-
- return true;
-}
-
-inline void spg2xx_audio_device::loop_channel(const uint32_t channel)
-{
- m_sample_addr[channel] = get_loop_addr(channel);
- m_sample_shift[channel] = 0;
- LOGMASKED(LOG_SAMPLES, "Channel %d: Looping to address %08x\n", channel, m_sample_addr[channel]);
-}
-
-void spg2xx_audio_device::audio_beat_tick()
-{
- if (m_audio_curr_beat_base_count == 0)
- {
- LOGMASKED(LOG_BEAT, "Beat base count elapsed, reloading with %d\n", m_audio_ctrl_regs[AUDIO_BEAT_BASE_COUNT]);
- m_audio_curr_beat_base_count = m_audio_ctrl_regs[AUDIO_BEAT_BASE_COUNT];
-
- uint16_t beat_count = m_audio_ctrl_regs[AUDIO_BEAT_COUNT] & AUDIO_BEAT_COUNT_MASK;
- if (beat_count == 0)
- {
- if (m_audio_ctrl_regs[AUDIO_BEAT_COUNT] & AUDIO_BIE_MASK)
- {
- LOGMASKED(LOG_BEAT, "Beat count elapsed, setting Status bit and checking IRQs\n");
- m_audio_ctrl_regs[AUDIO_BEAT_COUNT] |= AUDIO_BIS_MASK;
- check_irqs(AUDIO_BIS_MASK);
- }
- else
- {
- LOGMASKED(LOG_BEAT, "Beat count elapsed but IRQ not enabled\n");
- }
- }
- else
- {
- beat_count--;
- m_audio_ctrl_regs[AUDIO_BEAT_COUNT] = (m_audio_ctrl_regs[AUDIO_BEAT_COUNT] & ~AUDIO_BEAT_COUNT_MASK) | beat_count;
- }
- }
- m_audio_curr_beat_base_count--;
-}
-
-void spg2xx_audio_device::audio_rampdown_tick(const uint32_t channel)
-{
- const uint8_t old_edd = get_edd(channel);
- uint8_t new_edd = old_edd - get_rampdown_offset(channel);
- if (new_edd > old_edd)
- new_edd = 0;
-
- if (new_edd)
- {
- LOGMASKED(LOG_RAMPDOWN, "Channel %d preparing for next rampdown step (%02x)\n", channel, new_edd);
- const uint16_t channel_mask = channel << 4;
- m_audio_regs[channel_mask | AUDIO_ENVELOPE_DATA] &= ~AUDIO_EDD_MASK;
- m_audio_regs[channel_mask | AUDIO_ENVELOPE_DATA] |= new_edd & AUDIO_EDD_MASK;
- m_rampdown_frame[channel] = get_rampdown_frame_count(channel);
- }
- else
- {
- LOGMASKED(LOG_RAMPDOWN, "Stopping channel %d due to rampdown\n", channel);
- const uint16_t channel_mask = 1 << channel;
- m_audio_ctrl_regs[AUDIO_CHANNEL_ENABLE] &= ~channel_mask;
- m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] &= ~channel_mask;
- m_audio_ctrl_regs[AUDIO_CHANNEL_STOP] |= channel_mask;
- m_audio_ctrl_regs[AUDIO_ENV_RAMP_DOWN] &= ~channel_mask;
- m_audio_ctrl_regs[AUDIO_CHANNEL_TONE_RELEASE] &= ~channel_mask;
- }
-}
-
-const uint32_t spg2xx_audio_device::s_rampdown_frame_counts[8] =
-{
- 13*4, 13*16, 13*64, 13*256, 13*1024, 13*4096, 13*8192, 13*8192
-};
-
-uint32_t spg2xx_audio_device::get_rampdown_frame_count(const uint32_t channel)
-{
- return s_rampdown_frame_counts[get_rampdown_clock(channel)];
-}
-
-const uint32_t spg2xx_audio_device::s_envclk_frame_counts[16] =
-{
- 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 8192, 8192, 8192, 8192
-};
-
-uint32_t spg2xx_audio_device::get_envclk_frame_count(const uint32_t channel)
-{
- return s_envclk_frame_counts[get_envelope_clock(channel)];
-}
-
-uint32_t spg2xx_audio_device::get_envelope_clock(const offs_t channel) const
-{
- if (channel < 4)
- return (m_audio_ctrl_regs[AUDIO_ENVCLK0] >> (channel << 2)) & 0x000f;
- else if (channel < 8)
- return (m_audio_ctrl_regs[AUDIO_ENVCLK0_HIGH] >> ((channel - 4) << 2)) & 0x000f;
- else if (channel < 12)
- return (m_audio_ctrl_regs[AUDIO_ENVCLK1] >> ((channel - 8) << 2)) & 0x000f;
- else
- return (m_audio_ctrl_regs[AUDIO_ENVCLK1_HIGH] >> ((channel - 12) << 2)) & 0x000f;
-}
-
-bool spg2xx_audio_device::audio_envelope_tick(const uint32_t channel)
-{
- const uint16_t channel_mask = channel << 4;
- uint16_t new_count = get_envelope_count(channel);
- const uint16_t curr_edd = get_edd(channel);
- LOGMASKED(LOG_ENVELOPES, "envelope %d tick, count is %04x, curr edd is %04x\n", channel, new_count, curr_edd);
- bool edd_changed = false;
- if (new_count == 0)
- {
- const uint16_t target = get_envelope_target(channel);
- uint16_t new_edd = curr_edd;
- const uint16_t inc = get_envelope_inc(channel);
-
- if (new_edd != target)
- {
- if (get_envelope_sign_bit(channel))
- {
- new_edd -= inc;
- LOGMASKED(LOG_ENVELOPES, "Envelope %d new EDD-: %04x (%04x), dec %04x\n", channel, new_edd, target, inc);
- if (new_edd > curr_edd)
- new_edd = 0;
- else if (new_edd < target)
- new_edd = target;
-
- if (new_edd == 0)
- {
- LOGMASKED(LOG_ENVELOPES, "Envelope %d at 0, stopping channel\n", channel);
- stop_channel(channel);
- return true;
- }
- }
- else
- {
- new_edd += inc;
- LOGMASKED(LOG_ENVELOPES, "Envelope %d new EDD+: %04x (%04x), inc %04x\n", channel, new_edd, target, inc);
- if (new_edd >= target)
- new_edd = target;
- }
- }
-
- if (new_edd == target)
- {
- LOGMASKED(LOG_ENVELOPES, "Envelope %d at target %04x\n", channel, target);
- new_edd = target;
-
- if (get_envelope_repeat_bit(channel))
- {
- const uint16_t repeat_count = get_envelope_repeat_count(channel) - 1;
- LOGMASKED(LOG_ENVELOPES, "Repeating envelope, new repeat count %d\n", repeat_count);
- if (repeat_count == 0)
- {
- m_audio_regs[channel_mask | AUDIO_ENVELOPE0] = read_space(m_envelope_addr[channel]);
- m_audio_regs[channel_mask | AUDIO_ENVELOPE1] = read_space(m_envelope_addr[channel] + 1);
- m_audio_regs[channel_mask | AUDIO_ENVELOPE_LOOP_CTRL] = read_space(m_envelope_addr[channel] + 2);
- m_envelope_addr[channel] = get_envelope_addr(channel) + get_envelope_eaoffset(channel);
- LOGMASKED(LOG_ENVELOPES, "Envelope data after repeat: %04x %04x %04x (%08x)\n", m_audio_regs[channel_mask | AUDIO_ENVELOPE0], m_audio_regs[channel_mask | AUDIO_ENVELOPE1], m_audio_regs[channel_mask | AUDIO_ENVELOPE_LOOP_CTRL], m_envelope_addr[channel]);
- }
- else
- {
- set_envelope_repeat_count(channel, repeat_count);
- }
- }
- else
- {
- LOGMASKED(LOG_ENVELOPES, "Fetching envelope for channel %d from %08x\n", channel, m_envelope_addr[channel]);
- m_audio_regs[channel_mask | AUDIO_ENVELOPE0] = read_space(m_envelope_addr[channel]);
- m_audio_regs[channel_mask | AUDIO_ENVELOPE1] = read_space(m_envelope_addr[channel] + 1);
- LOGMASKED(LOG_ENVELOPES, "Fetched envelopes %04x %04x\n", m_audio_regs[channel_mask | AUDIO_ENVELOPE0], m_audio_regs[channel_mask | AUDIO_ENVELOPE1]);
- m_envelope_addr[channel] += 2;
- }
- new_count = get_envelope_load(channel);
- set_envelope_count(channel, new_count);
- }
- else
- {
- LOGMASKED(LOG_ENVELOPES, "Envelope %d not yet at target %04x (%04x)\n", channel, target, new_edd);
- new_count = get_envelope_load(channel);
- set_envelope_count(channel, new_count);
- }
- LOGMASKED(LOG_ENVELOPES, "Envelope %d new count %04x\n", channel, new_count);
-
- set_edd(channel, new_edd);
- edd_changed = true;
- LOGMASKED(LOG_ENVELOPES, "Setting channel %d edd to %04x, register is %04x\n", channel, new_edd, m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA]);
- }
- else
- {
- new_count--;
- set_envelope_count(channel, new_count);
- }
- LOGMASKED(LOG_ENVELOPES, "envelope %d post-tick, count is now %04x, register is %04x\n", channel, new_count, m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA]);
- return edd_changed;
-}
diff --git a/src/devices/machine/spg2xx_audio.h b/src/devices/machine/spg2xx_audio.h
deleted file mode 100644
index 22f5108e405..00000000000
--- a/src/devices/machine/spg2xx_audio.h
+++ /dev/null
@@ -1,372 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Ryan Holtz
-/*****************************************************************************
-
- SunPlus SPG2xx-series SoC peripheral emulation (Audio)
-
-**********************************************************************/
-
-#ifndef MAME_MACHINE_SPG2XX_AUDIO_H
-#define MAME_MACHINE_SPG2XX_AUDIO_H
-
-#pragma once
-
-#include "sound/okiadpcm.h"
-#include "cpu/unsp/unsp.h"
-
-class spg2xx_audio_device : public device_t, public device_sound_interface
-{
-public:
- spg2xx_audio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
- spg2xx_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- auto space_read_callback() { return m_space_read_cb.bind(); }
- auto write_irq_callback() { return m_irq_cb.bind(); }
-
- DECLARE_READ16_MEMBER(audio_r);
- DECLARE_WRITE16_MEMBER(audio_w);
- DECLARE_READ16_MEMBER(audio_ctrl_r);
- DECLARE_WRITE16_MEMBER(audio_ctrl_w);
- DECLARE_READ16_MEMBER(audio_phase_r);
- DECLARE_WRITE16_MEMBER(audio_phase_w);
-
-protected:
- // sound stream update overrides
- virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
-
- void audio_beat_tick();
- void audio_rampdown_tick(const uint32_t channel);
- bool audio_envelope_tick(const uint32_t channel);
- inline uint32_t get_rampdown_frame_count(const uint32_t channel);
- inline uint32_t get_envclk_frame_count(const uint32_t channel);
-
- // Audio getters
- bool get_channel_enable(const offs_t channel) const { return m_audio_ctrl_regs[AUDIO_CHANNEL_ENABLE] & (1 << channel); }
- bool get_channel_status(const offs_t channel) const { return m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] & (1 << channel); }
- bool get_manual_envelope_enable(const offs_t channel) const { return m_audio_ctrl_regs[AUDIO_CHANNEL_ENV_MODE] & (1 << channel); }
- bool get_auto_envelope_enable(const offs_t channel) const { return !get_manual_envelope_enable(channel); }
- uint32_t get_envelope_clock(const offs_t channel) const;
- uint16_t get_vol_sel() const { return (m_audio_ctrl_regs[AUDIO_CONTROL] & AUDIO_CONTROL_VOLSEL_MASK) >> AUDIO_CONTROL_VOLSEL_SHIFT; }
-
- // Audio Mode getters
- uint16_t get_wave_addr_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_WADDR_HIGH_MASK; }
- uint16_t get_loop_addr_high(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_LADDR_HIGH_MASK) >> AUDIO_LADDR_HIGH_SHIFT; }
- uint16_t get_tone_mode(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_TONE_MODE_MASK) >> AUDIO_TONE_MODE_SHIFT; }
- uint16_t get_16bit_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_16M_MASK) ? 1 : 0; }
- uint16_t get_adpcm_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_ADPCM_MASK) ? 1 : 0; }
-
- // Audio Pan getters
- uint16_t get_volume(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_PAN_VOL] & AUDIO_VOLUME_MASK; }
- uint16_t get_pan(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_PAN_VOL] & AUDIO_PAN_MASK) >> AUDIO_PAN_SHIFT; }
-
- // Audio Envelope0 Data getters
- uint16_t get_envelope_inc(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_INC_MASK; }
- uint16_t get_envelope_sign_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_SIGN_MASK) ? 1 : 0; }
- uint16_t get_envelope_target(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_TARGET_MASK) >> AUDIO_ENVELOPE_TARGET_SHIFT; }
- uint16_t get_repeat_period_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_REPEAT_PERIOD_MASK) ? 1 : 0; }
-
- // Audio Envelope Data getters
- uint16_t get_edd(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & AUDIO_EDD_MASK; }
- uint16_t get_envelope_count(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & AUDIO_ENVELOPE_COUNT_MASK) >> AUDIO_ENVELOPE_COUNT_SHIFT; }
- void set_edd(const offs_t channel, uint8_t edd) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & ~AUDIO_EDD_MASK) | edd; }
- void set_envelope_count(const offs_t channel, uint16_t count) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] = get_edd(channel) | (count << AUDIO_ENVELOPE_COUNT_SHIFT); }
-
- // Audio Envelope1 Data getters
- uint16_t get_envelope_load(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_LOAD_MASK; }
- uint16_t get_envelope_repeat_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_RPT_MASK) ? 1 : 0; }
- uint16_t get_envelope_repeat_count(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_RPCNT_MASK) >> AUDIO_ENVELOPE_RPCNT_SHIFT; }
- inline void set_envelope_repeat_count(const offs_t channel, const uint16_t count) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & ~AUDIO_ENVELOPE_RPCNT_MASK) | ((count << AUDIO_ENVELOPE_RPCNT_SHIFT) & AUDIO_ENVELOPE_RPCNT_MASK); }
-
- // Audio Envelope Address getters
- uint16_t get_envelope_addr_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_EADDR_HIGH_MASK; }
- uint16_t get_audio_irq_enable_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_IRQ_EN_MASK) ? 1 : 0; }
- uint16_t get_audio_irq_addr(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_IRQ_ADDR_MASK) >> AUDIO_IRQ_ADDR_SHIFT; }
-
- // Audio Envelope Loop getters
- uint16_t get_envelope_eaoffset(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & AUDIO_EAOFFSET_MASK; }
- uint16_t get_rampdown_offset(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & AUDIO_RAMPDOWN_OFFSET_MASK) >> AUDIO_RAMPDOWN_OFFSET_SHIFT; }
- void set_envelope_eaoffset(const offs_t channel, uint16_t eaoffset) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & ~AUDIO_RAMPDOWN_OFFSET_MASK) | (eaoffset & AUDIO_EAOFFSET_MASK); }
-
- // Audio ADPCM getters
- uint16_t get_point_number(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ADPCM_SEL] & AUDIO_POINT_NUMBER_MASK) >> AUDIO_POINT_NUMBER_SHIFT; }
- uint16_t get_adpcm36_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ADPCM_SEL] & AUDIO_ADPCM36_MASK) ? 1 : 0; }
-
- // Audio high-word getters
- uint16_t get_phase_high(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_HIGH] & AUDIO_PHASE_HIGH_MASK; }
- uint16_t get_phase_accum_high(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_ACCUM_HIGH] & AUDIO_PHASE_ACCUM_HIGH_MASK; }
- uint16_t get_target_phase_high(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_TARGET_PHASE_HIGH] & AUDIO_TARGET_PHASE_HIGH_MASK; }
- uint16_t get_rampdown_clock(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_RAMP_DOWN_CLOCK] & AUDIO_RAMP_DOWN_CLOCK_MASK; }
-
- // Audio ADPCM getters
- uint16_t get_phase_offset(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_OFFSET_MASK; }
- uint16_t get_phase_sign_bit(const offs_t channel) const { return (m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_SIGN_MASK) >> AUDIO_PHASE_SIGN_SHIFT; }
- uint16_t get_phase_time_step(const offs_t channel) const { return (m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_TIME_STEP_MASK) >> AUDIO_PHASE_TIME_STEP_SHIFT; }
-
- // Audio combined getters
- uint32_t get_phase(const offs_t channel) const { return ((uint32_t)get_phase_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_PHASE]; }
- uint32_t get_phase_accum(const offs_t channel) const { return ((uint32_t)get_phase_accum_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_ACCUM]; }
- uint32_t get_target_phase(const offs_t channel) const { return ((uint32_t)get_target_phase_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_TARGET_PHASE]; }
-
- uint32_t get_wave_addr(const offs_t channel) const { return ((uint32_t)get_wave_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_WAVE_ADDR]; }
- uint32_t get_loop_addr(const offs_t channel) const { return ((uint32_t)get_loop_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_LOOP_ADDR]; }
- uint32_t get_envelope_addr(const offs_t channel) const { return ((uint32_t)get_envelope_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR]; }
-
- enum // at audio write offset 0x000 in spg2xx
- {
- AUDIO_WAVE_ADDR = 0x000,
-
- AUDIO_MODE = 0x001,
- AUDIO_WADDR_HIGH_MASK = 0x003f,
- AUDIO_LADDR_HIGH_MASK = 0x0fc0,
- AUDIO_LADDR_HIGH_SHIFT = 6,
- AUDIO_TONE_MODE_MASK = 0x3000,
- AUDIO_TONE_MODE_SHIFT = 12,
- AUDIO_TONE_MODE_SW = 0,
- AUDIO_TONE_MODE_HW_ONESHOT = 1,
- AUDIO_TONE_MODE_HW_LOOP = 2,
- AUDIO_16M_MASK = 0x4000,
- AUDIO_ADPCM_MASK = 0x8000,
-
- AUDIO_LOOP_ADDR = 0x002,
-
- AUDIO_PAN_VOL = 0x003,
- AUDIO_PAN_VOL_MASK = 0x7f7f,
- AUDIO_VOLUME_MASK = 0x007f,
- AUDIO_PAN_MASK = 0x7f00,
- AUDIO_PAN_SHIFT = 8,
-
- AUDIO_ENVELOPE0 = 0x004,
- AUDIO_ENVELOPE_INC_MASK = 0x007f,
- AUDIO_ENVELOPE_SIGN_MASK = 0x0080,
- AUDIO_ENVELOPE_TARGET_MASK = 0x7f00,
- AUDIO_ENVELOPE_TARGET_SHIFT = 8,
- AUDIO_ENVELOPE_REPEAT_PERIOD_MASK = 0x8000,
-
- AUDIO_ENVELOPE_DATA = 0x005,
- AUDIO_ENVELOPE_DATA_MASK = 0xff7f,
- AUDIO_EDD_MASK = 0x007f,
- AUDIO_ENVELOPE_COUNT_MASK = 0xff00,
- AUDIO_ENVELOPE_COUNT_SHIFT = 8,
-
- AUDIO_ENVELOPE1 = 0x006,
- AUDIO_ENVELOPE_LOAD_MASK = 0x00ff,
- AUDIO_ENVELOPE_RPT_MASK = 0x0100,
- AUDIO_ENVELOPE_RPCNT_MASK = 0xfe00,
- AUDIO_ENVELOPE_RPCNT_SHIFT = 9,
-
- AUDIO_ENVELOPE_ADDR_HIGH = 0x007,
- AUDIO_EADDR_HIGH_MASK = 0x003f,
- AUDIO_IRQ_EN_MASK = 0x0040,
- AUDIO_IRQ_ADDR_MASK = 0xff80,
- AUDIO_IRQ_ADDR_SHIFT = 7,
-
- AUDIO_ENVELOPE_ADDR = 0x008,
- AUDIO_WAVE_DATA_PREV = 0x009,
-
- AUDIO_ENVELOPE_LOOP_CTRL = 0x00a,
- AUDIO_EAOFFSET_MASK = 0x01ff,
- AUDIO_RAMPDOWN_OFFSET_MASK = 0xfe00,
- AUDIO_RAMPDOWN_OFFSET_SHIFT = 9,
-
- AUDIO_WAVE_DATA = 0x00b,
-
- AUDIO_ADPCM_SEL = 0x00d,
- AUDIO_ADPCM_SEL_MASK = 0xfe00,
- AUDIO_POINT_NUMBER_MASK = 0x7e00,
- AUDIO_POINT_NUMBER_SHIFT = 9,
- AUDIO_ADPCM36_MASK = 0x8000,
- };
-
- enum // at audio write offset 0x200 in spg2xx
- {
- AUDIO_PHASE_HIGH = 0x000,
- AUDIO_PHASE_HIGH_MASK = 0x0007,
-
- AUDIO_PHASE_ACCUM_HIGH = 0x001,
- AUDIO_PHASE_ACCUM_HIGH_MASK = 0x0007,
-
- AUDIO_TARGET_PHASE_HIGH = 0x002,
- AUDIO_TARGET_PHASE_HIGH_MASK= 0x0007,
-
- AUDIO_RAMP_DOWN_CLOCK = 0x003,
- AUDIO_RAMP_DOWN_CLOCK_MASK = 0x0007,
-
- AUDIO_PHASE = 0x004,
- AUDIO_PHASE_ACCUM = 0x005,
- AUDIO_TARGET_PHASE = 0x006,
-
- AUDIO_PHASE_CTRL = 0x007,
- AUDIO_PHASE_OFFSET_MASK = 0x0fff,
- AUDIO_PHASE_SIGN_MASK = 0x1000,
- AUDIO_PHASE_SIGN_SHIFT = 12,
- AUDIO_PHASE_TIME_STEP_MASK = 0xe000,
- AUDIO_PHASE_TIME_STEP_SHIFT = 13,
-
- AUDIO_CHAN_OFFSET_MASK = 0xf0f,
- };
-
- enum // at audio write offset 0x400 in spg2xx
- {
-
- AUDIO_CHANNEL_ENABLE = 0x000,
- AUDIO_CHANNEL_ENABLE_MASK = 0xffff,
-
- AUDIO_MAIN_VOLUME = 0x001,
- AUDIO_MAIN_VOLUME_MASK = 0x007f,
-
- AUDIO_CHANNEL_FIQ_ENABLE = 0x002,
- AUDIO_CHANNEL_FIQ_ENABLE_MASK = 0xffff,
-
- AUDIO_CHANNEL_FIQ_STATUS = 0x003,
- AUDIO_CHANNEL_FIQ_STATUS_MASK = 0xffff,
-
- AUDIO_BEAT_BASE_COUNT = 0x004,
- AUDIO_BEAT_BASE_COUNT_MASK = 0x07ff,
-
- AUDIO_BEAT_COUNT = 0x005,
- AUDIO_BEAT_COUNT_MASK = 0x3fff,
- AUDIO_BIS_MASK = 0x4000,
- AUDIO_BIE_MASK = 0x8000,
-
- AUDIO_ENVCLK0 = 0x006,
-
- AUDIO_ENVCLK0_HIGH = 0x007,
- AUDIO_ENVCLK0_HIGH_MASK = 0xffff,
-
- AUDIO_ENVCLK1 = 0x008,
-
- AUDIO_ENVCLK1_HIGH = 0x009,
- AUDIO_ENVCLK1_HIGH_MASK = 0xffff,
-
- AUDIO_ENV_RAMP_DOWN = 0x00a,
- AUDIO_ENV_RAMP_DOWN_MASK = 0xffff,
-
- AUDIO_CHANNEL_STOP = 0x00b,
- AUDIO_CHANNEL_STOP_MASK = 0xffff,
-
- AUDIO_CHANNEL_ZERO_CROSS = 0x00c,
- AUDIO_CHANNEL_ZERO_CROSS_MASK = 0xffff,
-
- AUDIO_CONTROL = 0x00d,
- AUDIO_CONTROL_MASK = 0x9fe8,
- AUDIO_CONTROL_SATURATE_MASK = 0x8000,
- AUDIO_CONTROL_SOFTCH_MASK = 0x1000,
- AUDIO_CONTROL_COMPEN_MASK = 0x0800,
- AUDIO_CONTROL_NOHIGH_MASK = 0x0400,
- AUDIO_CONTROL_NOINT_MASK = 0x0200,
- AUDIO_CONTROL_EQEN_MASK = 0x0100,
- AUDIO_CONTROL_VOLSEL_MASK = 0x00c0,
- AUDIO_CONTROL_VOLSEL_SHIFT = 6,
- AUDIO_CONTROL_FOF_MASK = 0x0020,
- AUDIO_CONTROL_INIT_MASK = 0x0008,
-
- AUDIO_COMPRESS_CTRL = 0x00e,
- AUDIO_COMPRESS_CTRL_PEAK_MASK = 0x8000,
- AUDIO_COMPRESS_CTRL_THRESHOLD_MASK = 0x7f00,
- AUDIO_COMPRESS_CTRL_THRESHOLD_SHIFT = 8,
- AUDIO_COMPRESS_CTRL_ATTSCALE_MASK = 0x00c0,
- AUDIO_COMPRESS_CTRL_ATTSCALE_SHIFT = 6,
- AUDIO_COMPRESS_CTRL_RELSCALE_MASK = 0x0030,
- AUDIO_COMPRESS_CTRL_RELSCALE_SHIFT = 4,
- AUDIO_COMPRESS_CTRL_DISZC_MASK = 0x0008,
- AUDIO_COMPRESS_CTRL_RATIO_MASK = 0x0007,
-
- AUDIO_CHANNEL_STATUS = 0x00f,
- AUDIO_CHANNEL_STATUS_MASK = 0xffff,
-
- AUDIO_WAVE_IN_L = 0x010,
-
- AUDIO_WAVE_IN_R = 0x011,
- AUDIO_SOFTIRQ_MASK = 0x8000,
- AUDIO_SOFTIRQ_EN_MASK = 0x4000,
- AUDIO_SOFT_PHASE_HIGH_MASK = 0x0070,
- AUDIO_SOFT_PHASE_HIGH_SHIFT = 4,
- AUDIO_FIFO_IRQ_THRESHOLD_MASK = 0x000f,
-
- AUDIO_WAVE_OUT_L = 0x012,
- AUDIO_WAVE_OUT_R = 0x013,
-
- AUDIO_CHANNEL_REPEAT = 0x014,
- AUDIO_CHANNEL_REPEAT_MASK = 0xffff,
-
- AUDIO_CHANNEL_ENV_MODE = 0x015,
- AUDIO_CHANNEL_ENV_MODE_MASK = 0xffff,
-
- AUDIO_CHANNEL_TONE_RELEASE = 0x016,
- AUDIO_CHANNEL_TONE_RELEASE_MASK = 0xffff,
-
- AUDIO_CHANNEL_ENV_IRQ = 0x017,
- AUDIO_CHANNEL_ENV_IRQ_MASK = 0xffff,
-
- AUDIO_CHANNEL_PITCH_BEND = 0x018,
- AUDIO_CHANNEL_PITCH_BEND_MASK = 0xffff,
-
- AUDIO_SOFT_PHASE = 0x019,
-
- AUDIO_ATTACK_RELEASE = 0x01a,
- AUDIO_RELEASE_TIME_MASK = 0x00ff,
- AUDIO_ATTACK_TIME_MASK = 0xff00,
- AUDIO_ATTACK_TIME_SHIFT = 8,
-
- AUDIO_EQ_CUTOFF10 = 0x01b,
- AUDIO_EQ_CUTOFF10_MASK = 0x7f7f,
-
- AUDIO_EQ_CUTOFF32 = 0x01c,
- AUDIO_EQ_CUTOFF32_MASK = 0x7f7f,
-
- AUDIO_EQ_GAIN10 = 0x01d,
- AUDIO_EQ_GAIN10_MASK = 0x7f7f,
-
- AUDIO_EQ_GAIN32 = 0x01e,
- AUDIO_EQ_GAIN32_MASK = 0x7f7f
- };
-
- static const device_timer_id TIMER_BEAT = 3;
- void check_irqs(const uint16_t changed);
-
- virtual void device_start() override;
- virtual void device_reset() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
-
- uint16_t read_space(offs_t offset);
-
- void stop_channel(const uint32_t channel);
- bool advance_channel(const uint32_t channel);
- bool fetch_sample(const uint32_t channel);
- void loop_channel(const uint32_t channel);
-
-
- bool m_debug_samples;
- bool m_debug_rates;
-
- uint16_t m_audio_regs[0x200];
- uint16_t m_audio_phase_regs[0x200];
- uint16_t m_audio_ctrl_regs[0x400];
- uint8_t m_sample_shift[16];
- uint32_t m_sample_count[16];
- uint32_t m_sample_addr[16];
- double m_channel_rate[16];
- double m_channel_rate_accum[16];
- uint32_t m_rampdown_frame[16];
- uint32_t m_envclk_frame[16];
- uint32_t m_envelope_addr[16];
- int m_channel_debug;
- uint16_t m_audio_curr_beat_base_count;
-
- emu_timer *m_audio_beat;
-
- sound_stream *m_stream;
- oki_adpcm_state m_adpcm[16];
-
- static const uint32_t s_rampdown_frame_counts[8];
- static const uint32_t s_envclk_frame_counts[16];
-
-private:
- devcb_read16 m_space_read_cb;
- devcb_write_line m_irq_cb;
-
-};
-
-DECLARE_DEVICE_TYPE(SPG2XX_AUDIO, spg2xx_audio_device)
-
-#endif // MAME_MACHINE_SPG2XX_AUDIO_H
diff --git a/src/devices/machine/spg2xx_io.cpp b/src/devices/machine/spg2xx_io.cpp
deleted file mode 100644
index 404087f6a7f..00000000000
--- a/src/devices/machine/spg2xx_io.cpp
+++ /dev/null
@@ -1,1313 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Ryan Holtz
-
-/* this is used by the SPG110, SPG24x and SPG28x
- basic I/O behavior is definitely the same on the SPG110 but
- the rest needs verifying */
-
-#include "emu.h"
-#include "spg2xx_io.h"
-
-DEFINE_DEVICE_TYPE(SPG24X_IO, spg24x_io_device, "spg24x_io", "SPG240-series System-on-a-Chip I/O")
-DEFINE_DEVICE_TYPE(SPG28X_IO, spg28x_io_device, "spg28x_io", "SPG280-series System-on-a-Chip I/O")
-
-#define LOG_IO_READS (1U << 1)
-#define LOG_IO_WRITES (1U << 2)
-#define LOG_UNKNOWN_IO (1U << 3)
-#define LOG_IRQS (1U << 4)
-#define LOG_VLINES (1U << 5)
-#define LOG_GPIO (1U << 6)
-#define LOG_UART (1U << 7)
-#define LOG_I2C (1U << 8)
-#define LOG_SEGMENT (1U << 10)
-#define LOG_WATCHDOG (1U << 11)
-#define LOG_TIMERS (1U << 12)
-#define LOG_FIQ (1U << 25)
-#define LOG_SIO (1U << 26)
-#define LOG_EXT_MEM (1U << 27)
-#define LOG_EXTINT (1U << 28)
-#define LOG_IO (LOG_IO_READS | LOG_IO_WRITES | LOG_IRQS | LOG_GPIO | LOG_UART | LOG_I2C | LOG_TIMERS | LOG_EXTINT | LOG_UNKNOWN_IO)
-#define LOG_ALL (LOG_IO | LOG_VLINES | LOG_SEGMENT | LOG_FIQ)
-
-#define VERBOSE (0)
-#include "logmacro.h"
-
-
-#define IO_IRQ_ENABLE m_io_regs[0x21]
-#define IO_IRQ_STATUS m_io_regs[0x22]
-
-spg2xx_io_device::spg2xx_io_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, type, tag, owner, clock)
- , m_porta_out(*this)
- , m_portb_out(*this)
- , m_portc_out(*this)
- , m_porta_in(*this)
- , m_portb_in(*this)
- , m_portc_in(*this)
- , m_adc_in{{*this}, {*this}}
- , m_eeprom_w(*this)
- , m_eeprom_r(*this)
- , m_uart_tx(*this)
- , m_chip_sel(*this)
- , m_cpu(*this, finder_base::DUMMY_TAG)
- , m_screen(*this, finder_base::DUMMY_TAG)
- , m_pal_read_cb(*this)
- , m_timer_irq_cb(*this)
- , m_uart_adc_irq_cb(*this)
- , m_external_irq_cb(*this)
- , m_ffreq_tmr1_irq_cb(*this)
- , m_ffreq_tmr2_irq_cb(*this)
-{
-}
-
-spg24x_io_device::spg24x_io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : spg2xx_io_device(mconfig, SPG24X_IO, tag, owner, clock, 256)
-{
-}
-
-spg28x_io_device::spg28x_io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : spg2xx_io_device(mconfig, SPG28X_IO, tag, owner, clock, 64)
-{
-}
-
-
-void spg2xx_io_device::device_start()
-{
- m_porta_out.resolve_safe();
- m_portb_out.resolve_safe();
- m_portc_out.resolve_safe();
- m_porta_in.resolve_safe(0);
- m_portb_in.resolve_safe(0);
- m_portc_in.resolve_safe(0);
- m_adc_in[0].resolve_safe(0x0fff);
- m_adc_in[1].resolve_safe(0x0fff);
- m_eeprom_w.resolve_safe();
- m_eeprom_r.resolve_safe(0);
- m_uart_tx.resolve_safe();
- m_chip_sel.resolve_safe();
- m_pal_read_cb.resolve_safe(0);
-
- m_timer_irq_cb.resolve();
- m_uart_adc_irq_cb.resolve();
- m_external_irq_cb.resolve();
- m_ffreq_tmr1_irq_cb.resolve();
- m_ffreq_tmr2_irq_cb.resolve();
-
- m_tmb1 = timer_alloc(TIMER_TMB1);
- m_tmb2 = timer_alloc(TIMER_TMB2);
- m_tmb1->adjust(attotime::never);
- m_tmb2->adjust(attotime::never);
-
- m_uart_tx_timer = timer_alloc(TIMER_UART_TX);
- m_uart_tx_timer->adjust(attotime::never);
-
- m_uart_rx_timer = timer_alloc(TIMER_UART_RX);
- m_uart_rx_timer->adjust(attotime::never);
-
- m_4khz_timer = timer_alloc(TIMER_4KHZ);
- m_4khz_timer->adjust(attotime::never);
-
- m_timer_src_ab = timer_alloc(TIMER_SRC_AB);
- m_timer_src_ab->adjust(attotime::never);
-
- m_timer_src_c = timer_alloc(TIMER_SRC_C);
- m_timer_src_c->adjust(attotime::never);
-
- save_item(NAME(m_timer_a_preload));
- save_item(NAME(m_timer_b_preload));
- save_item(NAME(m_timer_b_divisor));
- save_item(NAME(m_timer_b_tick_rate));
-
- save_item(NAME(m_io_regs));
-
- save_item(NAME(m_extint));
-
- save_item(NAME(m_2khz_divider));
- save_item(NAME(m_1khz_divider));
- save_item(NAME(m_4hz_divider));
-
- save_item(NAME(m_uart_baud_rate));
-
-}
-
-void spg2xx_io_device::device_reset()
-{
- memset(m_io_regs, 0, 0x100 * sizeof(uint16_t));
-
- m_timer_a_preload = 0;
- m_timer_b_preload = 0;
- m_timer_b_divisor = 0;
- m_timer_b_tick_rate = 0;
-
- m_io_regs[0x23] = 0x0028;
- m_io_regs[0x2c] = 0x1418;
- m_io_regs[0x2d] = 0x1658;
-
- m_uart_rx_available = false;
- memset(m_uart_rx_fifo, 0, ARRAY_LENGTH(m_uart_rx_fifo));
- m_uart_rx_fifo_start = 0;
- m_uart_rx_fifo_end = 0;
- m_uart_rx_fifo_count = 0;
- m_uart_tx_irq = false;
- m_uart_rx_irq = false;
-
- memset(m_extint, 0, sizeof(bool) * 2);
-
- m_4khz_timer->adjust(attotime::from_hz(4096), 0, attotime::from_hz(4096));
-
- m_2khz_divider = 0;
- m_1khz_divider = 0;
- m_4hz_divider = 0;
-}
-
-/*************************
-* Machine Hardware *
-*************************/
-
-void spg2xx_io_device::uart_rx(uint8_t data)
-{
- LOGMASKED(LOG_UART, "uart_rx: Pulling %02x into receive FIFO\n", data);
- if (BIT(m_io_regs[0x30], 6))
- {
- m_uart_rx_fifo[m_uart_rx_fifo_end] = data;
- m_uart_rx_fifo_end = (m_uart_rx_fifo_end + 1) % ARRAY_LENGTH(m_uart_rx_fifo);
- m_uart_rx_fifo_count++;
- if (m_uart_rx_timer->remaining() == attotime::never)
- m_uart_rx_timer->adjust(attotime::from_ticks(BIT(m_io_regs[0x30], 5) ? 11 : 10, m_uart_baud_rate));
- }
-}
-
-READ16_MEMBER(spg2xx_io_device::io_r)
-{
- static const char *const gpioregs[] = { "GPIO Data Port", "GPIO Buffer Port", "GPIO Direction Port", "GPIO Attribute Port", "GPIO IRQ/Latch Port" };
- static const char gpioports[] = { 'A', 'B', 'C' };
-
- uint16_t val = m_io_regs[offset];
-
- switch (offset)
- {
- case 0x01: case 0x06: case 0x0b: // GPIO Data Port A/B/C
- do_gpio(offset, false);
- LOGMASKED(LOG_GPIO, "%s: io_r: %s %c = %04x\n", machine().describe_context(), gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], m_io_regs[offset]);
- val = m_io_regs[offset];
- break;
-
- case 0x02: case 0x03: case 0x04: case 0x05:
- case 0x07: case 0x08: case 0x09: case 0x0a:
- case 0x0c: case 0x0d: case 0x0e: case 0x0f: // Other GPIO regs
- LOGMASKED(LOG_GPIO, "%s: io_r: %s %c = %04x\n", machine().describe_context(), gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], m_io_regs[offset]);
- break;
-
- case 0x10: // Timebase Control
- LOGMASKED(LOG_IO_READS, "io_r: Timebase Control = %04x\n", val);
- break;
-
- case 0x12: // Timer A Data
- LOGMASKED(LOG_IO_WRITES, "io_r: Timer A Data = %04x\n", val);
- break;
-
- case 0x1c: // Video line counter
- val = m_screen->vpos();
- LOGMASKED(LOG_VLINES, "io_r: Video Line = %04x\n", val);
- break;
-
- case 0x20: // System Control
- LOGMASKED(LOG_IO_READS, "io_r: System Control = %04x\n", val);
- break;
-
- case 0x21: // IRQ Control
- LOGMASKED(LOG_IRQS, "%s: io_r: I/O IRQ Control = %04x\n", machine().describe_context(), val);
- break;
-
- case 0x22: // IRQ Status
- LOGMASKED(LOG_IRQS, "%s: io_r: I/O IRQ Status = %04x\n", machine().describe_context(), val);
- break;
-
- case 0x23: // External Memory Control
- LOGMASKED(LOG_IO_READS, "%s: io_r: Ext. Memory Control = %04x\n", machine().describe_context(), val);
- break;
-
- case 0x25: // ADC Control
- LOGMASKED(LOG_IO_READS, "io_r: ADC Control = %04x\n", val);
- break;
-
- case 0x27: // ADC Data
- {
- m_io_regs[0x27] = 0;
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS &= ~0x2000;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(changed);
- LOGMASKED(LOG_IO_READS, "%s: io_r: ADC Data = %04x\n", machine().describe_context(), val);
- break;
- }
-
- case 0x29: // Wakeup Source
- LOGMASKED(LOG_IO_READS, "io_r: Wakeup Source = %04x\n", val);
- break;
-
- case 0x2b:
- {
- uint16_t pal = m_pal_read_cb();
- LOGMASKED(LOG_IO_READS, "io_r: NTSC/PAL = %04x\n", pal);
- return pal;
- }
-
- case 0x2c: // PRNG 0
- {
- const uint16_t value = m_io_regs[0x2c];
- m_io_regs[0x2c] = ((value << 1) | (BIT(value, 14) ^ BIT(value, 13))) & 0x7fff;
- return value;
- }
-
- case 0x2d: // PRNG 1
- {
- const uint16_t value = m_io_regs[0x2d];
- m_io_regs[0x2d] = ((value << 1) | (BIT(value, 14) ^ BIT(value, 13))) & 0x7fff;
- return value;
- }
-
- case 0x2e: // FIQ Source Select
- LOGMASKED(LOG_FIQ, "io_r: FIQ Source Select = %04x\n", val);
- break;
-
- case 0x2f: // Data Segment
- val = m_cpu->get_ds();
- LOGMASKED(LOG_SEGMENT, "io_r: Data Segment = %04x\n", val);
- break;
-
- default:
- LOGMASKED(LOG_UNKNOWN_IO, "io_r: Unknown register %04x\n", 0x3d00 + offset);
- break;
- }
-
- return val;
-}
-
-READ16_MEMBER(spg2xx_io_device::io_extended_r)
-{
- // this set of registers might only be on the 24x not the 11x
-
- offset += 0x30;
-
- uint16_t val = m_io_regs[offset];
-
- switch (offset)
- {
- case 0x30: // UART Control
- LOGMASKED(LOG_UART, "%s: io_r: UART Control = %04x\n", machine().describe_context(), val);
- break;
-
- case 0x31: // UART Status
- //LOGMASKED(LOG_UART, "%s: io_r: UART Status = %04x\n", machine().describe_context(), val);
- break;
-
- case 0x36: // UART RX Data
- if (m_uart_rx_available)
- {
- m_io_regs[0x31] &= ~0x0081;
- LOGMASKED(LOG_UART, "UART Rx data is available, clearing bits\n");
- if (m_uart_rx_fifo_count)
- {
- LOGMASKED(LOG_UART, "Remaining count %d, value %02x\n", m_uart_rx_fifo_count, m_uart_rx_fifo[m_uart_rx_fifo_start]);
- m_io_regs[0x36] = m_uart_rx_fifo[m_uart_rx_fifo_start];
- val = m_io_regs[0x36];
- m_uart_rx_fifo_start = (m_uart_rx_fifo_start + 1) % ARRAY_LENGTH(m_uart_rx_fifo);
- m_uart_rx_fifo_count--;
-
- if (m_uart_rx_fifo_count == 0)
- {
- m_uart_rx_available = false;
- }
- else
- {
- LOGMASKED(LOG_UART, "Remaining count %d, setting up timer\n", m_uart_rx_fifo_count);
- //uart_receive_tick();
- if (m_uart_rx_timer->remaining() == attotime::never)
- m_uart_rx_timer->adjust(attotime::from_ticks(BIT(m_io_regs[0x30], 5) ? 11 : 10, m_uart_baud_rate));
- }
- }
- else
- {
- m_uart_rx_available = false;
- }
- }
- else
- {
- m_io_regs[0x37] |= 0x2000;
- }
- LOGMASKED(LOG_UART, "%s: io_r: UART Rx Data = %04x\n", machine().describe_context(), val);
- break;
-
- case 0x37: // UART Rx FIFO Control
- val &= ~0x0070;
- val |= (m_uart_rx_available ? 7 : 0) << 4;
- LOGMASKED(LOG_UART, "io_r: UART Rx FIFO Control = %04x\n", machine().describe_context(), val);
- break;
-
- case 0x51: // unknown, polled by ClickStart cartridges ( clikstrt )
- return 0x8000;
-
- case 0x59: // I2C Status
- LOGMASKED(LOG_I2C, "io_r: I2C Status = %04x\n", val);
- break;
-
- case 0x5e: // I2C Data In
- LOGMASKED(LOG_I2C, "io_r: I2C Data In = %04x\n", val);
- break;
-
- default:
- LOGMASKED(LOG_UNKNOWN_IO, "io_r: Unknown register %04x\n", 0x3d00 + offset);
- break;
- }
-
- return val;
-}
-
-void spg2xx_io_device::update_porta_special_modes()
-{
- static const char* const s_pa_special[4][16] =
- {
- // Input, Special 0
- // Input, Special 1
- // Output, Special 0
- // Output, Special 1
-
- { "LP", "ExtClk2", "ExtClk1", "-", "SDA", "SlvRDY", "-", "-", "SPICLK", "-", "RxD", "SPISSB", "-", "-", "-", "-" },
- { "-", "-", "-", "SCK", "-", "SWS", "-", "-", "-", "-", "-", "-", "IRQ2B", "-", "-", "IRQ1B" },
- { "-", "-", "-", "SCK", "SDA", "SWS", "-", "-", "SPICLK", "TxD", "-", "SPISSB", "TAPWM", "TM1", "TBPWM", "TM2" },
- { "CSB3", "CSB2", "CSB1", "SCK", "SDA", "VSYNC", "HSYNC", "SYSCLK3", "SPICLK", "TxD", "SWS", "SPISSB", "-", "VSYNC", "HSYNC", "CSYNC" },
- };
- for (int bit = 15; bit >= 0; bit--)
- {
- if (!BIT(m_io_regs[0x05], bit))
- continue;
- uint8_t type = (BIT(m_io_regs[0x03], bit) << 1) | BIT(m_io_regs[0x00], 0);
- LOGMASKED(LOG_GPIO, " Bit %2d: %s\n", bit, s_pa_special[type][bit]);
- }
-}
-
-void spg2xx_io_device::update_portb_special_modes()
-{
- static const char* const s_pb_special[4][8] =
- {
- // Input, Special 0
- // Input, Special 1
- // Output, Special 0
- // Output, Special 1
-
- { "-", "-", "-", "-", "-", "-", "SDA", "SlvRDY" },
- { "-", "-", "-", "-", "-", "-", "SDA", "SlvRDY" },
- { "VSYNC", "HSYNC", "CSYNC", "-", "-", "SCK", "SDA", "SWS" },
- { "CSB3", "CSB2", "CSB1", "TBPWM", "TM2", "-", "-", "SYSCLK2" },
- };
- for (int bit = 7; bit >= 0; bit--)
- {
- if (!BIT(m_io_regs[0x0a], bit))
- continue;
- uint8_t type = (BIT(m_io_regs[0x08], bit) << 1) | BIT(m_io_regs[0x00], 1);
- LOGMASKED(LOG_GPIO, " Bit %2d: %s\n", bit, s_pb_special[type][bit]);
- }
-}
-
-void spg2xx_io_device::update_timer_b_rate()
-{
- switch (m_io_regs[0x17] & 7)
- {
- case 0:
- case 1:
- case 5:
- case 6:
- case 7:
- m_timer_src_c->adjust(attotime::never);
- break;
- case 2:
- m_timer_src_c->adjust(attotime::from_hz(32768), 0, attotime::from_hz(32768));
- break;
- case 3:
- m_timer_src_c->adjust(attotime::from_hz(8192), 0, attotime::from_hz(8192));
- break;
- case 4:
- m_timer_src_c->adjust(attotime::from_hz(4096), 0, attotime::from_hz(4096));
- break;
- }
-}
-
-void spg2xx_io_device::update_timer_ab_src()
-{
- if (m_timer_b_tick_rate == 0)
- return;
-
- m_timer_b_divisor++;
- if (m_timer_b_divisor >= m_timer_b_tick_rate)
- {
- m_timer_b_divisor = 0;
- increment_timer_a();
- }
-}
-
-void spg2xx_io_device::increment_timer_a()
-{
- m_io_regs[0x12]++;
- if (m_io_regs[0x12] == 0)
- {
- m_io_regs[0x12] = m_timer_a_preload;
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 0x0800;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- {
- //printf("Timer A overflow\n");
- check_irqs(0x0800);
- }
- }
-}
-
-void spg2xx_io_device::update_timer_c_src()
-{
- m_io_regs[0x16]++;
- if (m_io_regs[0x16] == 0)
- {
- m_io_regs[0x16] = m_timer_b_preload;
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 0x0400;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- {
- printf("Timer B overflow\n");
- check_irqs(0x0400);
- }
- }
-}
-
-
-WRITE16_MEMBER(spg28x_io_device::io_extended_w)
-{
- offset += 0x30;
-
- if (offset == 0x33)
- {
- m_io_regs[offset] = data;
- m_uart_baud_rate = 27000000 / (0x10000 - m_io_regs[0x33]);
- LOGMASKED(LOG_UART, "%s: io_w: UART Baud Rate scaler = %04x (%d baud)\n", machine().describe_context(), data, m_uart_baud_rate);
- }
- else
- {
- spg2xx_io_device::io_extended_w(space, offset-0x30, data, mem_mask);
- }
-}
-
-WRITE16_MEMBER(spg2xx_io_device::io_w)
-{
- static const char *const gpioregs[] = { "GPIO Data Port", "GPIO Buffer Port", "GPIO Direction Port", "GPIO Attribute Port", "GPIO IRQ/Latch Port" };
- static const char gpioports[3] = { 'A', 'B', 'C' };
-
- switch (offset)
- {
- case 0x00: // GPIO special function select
- {
- LOGMASKED(LOG_GPIO, "%s: io_w: GPIO Configuration = %04x (IOBWake:%d, IOAWake:%d, IOBSpecSel:%d, IOASpecSel:%d)\n", machine().describe_context(), data
- , BIT(data, 4), BIT(data, 3), BIT(data, 1), BIT(data, 0));
- const uint16_t old = m_io_regs[offset];
- m_io_regs[offset] = data;
- const uint16_t changed = old ^ data;
- if (BIT(changed, 0))
- update_porta_special_modes();
- if (BIT(changed, 1))
- update_portb_special_modes();
- break;
- }
-
- case 0x01: case 0x06: case 0x0b: // GPIO data, port A/B/C
- offset++;
- // Intentional fallthrough - we redirect data register writes to the buffer register.
-
- case 0x02: case 0x04: // Port A
- case 0x07: case 0x09: // Port B
- case 0x0c: case 0x0d: case 0x0e: case 0x0f: // Port C
- LOGMASKED(LOG_GPIO, "%s: io_w: %s %c = %04x\n", machine().describe_context(), gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], data);
- m_io_regs[offset] = data;
- do_gpio(offset, true);
- break;
-
- case 0x03: // Port A Direction
- LOGMASKED(LOG_GPIO, "%s: io_w: GPIO Direction Port A = %04x\n", machine().describe_context(), data);
- m_io_regs[offset] = data;
- update_porta_special_modes();
- do_gpio(offset, true);
- break;
-
- case 0x08: // Port B Direction
- LOGMASKED(LOG_GPIO, "%s: io_w: GPIO Direction Port B = %04x\n", machine().describe_context(), data);
- m_io_regs[offset] = data;
- update_portb_special_modes();
- do_gpio(offset, true);
- break;
-
- case 0x05: // Port A Special
- LOGMASKED(LOG_GPIO, "%s: io_w: Port A Special Function Select: %04x\n", machine().describe_context(), data);
- m_io_regs[offset] = data;
- update_porta_special_modes();
- break;
-
- case 0x0a: // Port B Special
- LOGMASKED(LOG_GPIO, "%s: io_w: Port B Special Function Select: %04x\n", machine().describe_context(), data);
- m_io_regs[offset] = data;
- update_portb_special_modes();
- break;
-
- case 0x10: // Timebase Control
- {
- static const char* const s_tmb1_sel[2][4] =
- {
- { "8Hz", "16Hz", "32Hz", "64Hz" },
- { "12kHz", "24kHz", "40kHz", "40kHz" }
- };
- static const char* const s_tmb2_sel[2][4] =
- {
- { "128Hz", "256Hz", "512Hz", "1024Hz" },
- { "105kHz", "210kHz", "420kHz", "840kHz" }
- };
- static const uint32_t s_tmb1_freq[2][4] =
- {
- { 8, 16, 32, 64 },
- { 12000, 24000, 40000, 40000 }
- };
- static const uint32_t s_tmb2_freq[2][4] =
- {
- { 128, 256, 512, 1024 },
- { 105000, 210000, 420000, 840000 }
- };
- LOGMASKED(LOG_TIMERS, "io_w: Timebase Control = %04x (Source:%s, TMB2:%s, TMB1:%s)\n", data,
- BIT(data, 4) ? "27MHz" : "32768Hz", s_tmb2_sel[BIT(data, 4)][(data >> 2) & 3], s_tmb1_sel[BIT(data, 4)][data & 3]);
- m_io_regs[offset] = data;
- const uint8_t hifreq = BIT(data, 4);
- const uint32_t tmb1freq = s_tmb1_freq[hifreq][data & 3];
- m_tmb1->adjust(attotime::from_hz(tmb1freq), 0, attotime::from_hz(tmb1freq));
- const uint32_t tmb2freq = s_tmb2_freq[hifreq][(data >> 2) & 3];
- m_tmb2->adjust(attotime::from_hz(tmb2freq), 0, attotime::from_hz(tmb2freq));
- break;
- }
-
- case 0x11: // Timebase Clear
- LOGMASKED(LOG_TIMERS, "io_w: Timebase Clear = %04x\n", data);
- break;
-
- case 0x12: // Timer A Data
- LOGMASKED(LOG_TIMERS, "io_w: Timer A Data = %04x\n", data);
- m_io_regs[offset] = data;
- m_timer_a_preload = data;
- break;
-
- case 0x13: // Timer A Control
- {
- static const char* const s_source_a[8] = { "0", "0", "32768Hz", "8192Hz", "4096Hz", "1", "0", "ExtClk1" };
- static const char* const s_source_b[8] = { "2048Hz", "1024Hz", "256Hz", "TMB1", "4Hz", "2Hz", "1", "ExtClk2" };
- LOGMASKED(LOG_TIMERS, "io_w: Timer A Control = %04x (Source A:%s, Source B:%s)\n", data,
- s_source_a[data & 7], s_source_b[(data >> 3) & 7]);
- m_io_regs[offset] = data;
- int timer_a_rate = 0;
- switch (data & 7)
- {
- case 0:
- case 1:
- case 5:
- case 6:
- case 7:
- m_timer_src_ab->adjust(attotime::never);
- break;
- case 2:
- m_timer_src_ab->adjust(attotime::from_hz(32768), 0, attotime::from_hz(32768));
- timer_a_rate = 32768;
- break;
- case 3:
- m_timer_src_ab->adjust(attotime::from_hz(8192), 0, attotime::from_hz(8192));
- timer_a_rate = 8192;
- break;
- case 4:
- m_timer_src_ab->adjust(attotime::from_hz(4096), 0, attotime::from_hz(4096));
- timer_a_rate = 4096;
- break;
- }
- switch ((data >> 3) & 7)
- {
- case 0:
- m_timer_b_tick_rate = timer_a_rate / 2048;
- break;
- case 1:
- m_timer_b_tick_rate = timer_a_rate / 1024;
- break;
- case 2:
- m_timer_b_tick_rate = timer_a_rate / 256;
- break;
- case 3:
- m_timer_b_tick_rate = 0;
- break;
- case 4:
- m_timer_b_tick_rate = timer_a_rate / 4;
- break;
- case 5:
- m_timer_b_tick_rate = timer_a_rate / 2;
- break;
- case 6:
- m_timer_b_tick_rate = 1;
- break;
- case 7:
- m_timer_b_tick_rate = 0;
- break;
- }
- break;
- }
-
- case 0x15: // Timer A IRQ Clear
- {
- LOGMASKED(LOG_TIMERS, "io_w: Timer A IRQ Clear\n");
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS &= ~0x0800;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(0x0800);
- break;
- }
-
- case 0x16: // Timer B Data
- LOGMASKED(LOG_TIMERS, "io_w: Timer B Data = %04x\n", data);
- m_io_regs[offset] = data;
- m_timer_b_preload = data;
- break;
-
- case 0x17: // Timer B Control
- {
- static const char* const s_source_c[8] = { "0", "0", "32768Hz", "8192Hz", "4096Hz", "1", "0", "ExtClk1" };
- LOGMASKED(LOG_TIMERS, "io_w: Timer B Control = %04x (Source C:%s)\n", data, s_source_c[data & 7]);
- m_io_regs[offset] = data;
- if (m_io_regs[0x18] == 1)
- {
- update_timer_b_rate();
- }
- break;
- }
-
- case 0x18: // Timer B Enable
- {
- LOGMASKED(LOG_TIMERS, "io_w: Timer B Enable = %04x\n", data);
- m_io_regs[offset] = data & 1;
- if (data & 1)
- {
- update_timer_b_rate();
- }
- else
- {
- m_timer_src_c->adjust(attotime::never);
- }
- break;
- }
-
- case 0x19: // Timer B IRQ Clear
- {
- LOGMASKED(LOG_TIMERS, "io_w: Timer B IRQ Clear\n");
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS &= ~0x0400;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(0x0400);
- break;
- }
-
- case 0x20: // System Control
- {
- static const char* const s_sysclk[4] = { "13.5MHz", "27MHz", "27MHz NoICE", "54MHz" };
- static const char* const s_lvd_voltage[4] = { "2.7V", "2.9V", "3.1V", "3.3V" };
- static const char* const s_weak_strong[2] = { "Weak", "Strong" };
- LOGMASKED(LOG_IO_WRITES, "io_w: System Control = %04x (Watchdog:%d, Sleep:%d, SysClk:%s, SysClkInv:%d, LVROutEn:%d, LVREn:%d\n"
- , data, BIT(data, 15), BIT(data, 14), s_sysclk[(data >> 12) & 3], BIT(data, 11), BIT(data, 9), BIT(data, 8));
- LOGMASKED(LOG_IO_WRITES, " LVDEn:%d, LVDVoltSel:%s, 32kHzDisable:%d, StrWkMode:%s, VDACDisable:%d, ADACDisable:%d, ADACOutDisable:%d)\n"
- , BIT(data, 7), s_lvd_voltage[(data >> 5) & 3], BIT(data, 4), s_weak_strong[BIT(data, 3)], BIT(data, 2), BIT(data, 1), BIT(data, 0));
- m_io_regs[offset] = data;
- break;
- }
-
- case 0x21: // IRQ Enable
- {
- LOGMASKED(LOG_IRQS, "io_w: IRQ Enable = %04x\n", data);
- const uint16_t old = IO_IRQ_ENABLE;
- m_io_regs[offset] = data;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(changed);
- break;
- }
-
- case 0x22: // IRQ Acknowledge
- {
- LOGMASKED(LOG_IRQS, "io_w: IRQ Acknowledge = %04x\n", data);
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS &= ~data;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (m_uart_rx_irq || m_uart_tx_irq)
- {
- LOGMASKED(LOG_IRQS | LOG_UART, "Re-setting UART IRQ due to still-unacknowledged Rx or Tx.\n");
- IO_IRQ_STATUS |= 0x0100;
- }
- if (changed)
- check_irqs(changed);
- break;
- }
-
- case 0x23: // External Memory Control
- {
- static const char* const s_bus_arb[8] =
- {
- "Forbidden", "Forbidden", "Forbidden", "Forbidden", "Forbidden", "1:SPU/2:PPU/3:CPU", "Forbidden", "1:PPU/2:SPU/3:CPU"
- };
- static const char* const s_addr_decode[4] =
- {
- "ROMCSB: 4000-3fffff, CSB1: ---, CSB2: ---, CSB3: ---",
- "ROMCSB: 4000-1fffff, CSB1: 200000-3fffff, CSB2: ---, CSB3: ---",
- "ROMCSB: 4000-0fffff, CSB1: 100000-1fffff, CSB2: 200000-2fffff, CSB3: 300000-3fffff",
- "ROMCSB: 4000-0fffff, CSB1: 100000-1fffff, CSB2: 200000-2fffff, CSB3: 300000-3fffff"
- };
- static const char* const s_ram_decode[16] =
- {
- "None", "None", "None", "None", "None", "None", "None", "None",
- "4KW, 3ff000-3fffff\n",
- "8KW, 3fe000-3fffff\n",
- "16KW, 3fc000-3fffff\n",
- "32KW, 3f8000-3fffff\n",
- "64KW, 3f0000-3fffff\n",
- "128KW, 3e0000-3fffff\n",
- "256KW, 3c0000-3fffff\n",
- "512KW, 380000-3fffff\n"
- };
- LOGMASKED(LOG_EXT_MEM, "io_w: Ext. Memory Control (not yet implemented) = %04x:\n", data);
- LOGMASKED(LOG_EXT_MEM, " WaitStates:%d, BusArbPrio:%s\n", (data >> 1) & 3, s_bus_arb[(data >> 3) & 7]);
- LOGMASKED(LOG_EXT_MEM, " ROMAddrDecode:%s\n", s_addr_decode[(data >> 6) & 3]);
- LOGMASKED(LOG_EXT_MEM, " RAMAddrDecode:%s\n", s_ram_decode[(data >> 8) & 15]);
- m_chip_sel((data >> 6) & 3);
- m_io_regs[offset] = data;
- break;
- }
-
- case 0x24: // Watchdog
- LOGMASKED(LOG_WATCHDOG, "io_w: Watchdog Pet = %04x\n", data);
- break;
-
- case 0x25: // ADC Control
- {
- LOGMASKED(LOG_IO_WRITES, "%s: io_w: ADC Control = %04x\n", machine().describe_context(), data);
- m_io_regs[offset] = data & ~0x1000;
- if (BIT(data, 0))
- {
- m_io_regs[0x27] = 0x8000 | (m_adc_in[BIT(data, 5)]() & 0x7fff);
- m_io_regs[0x25] |= 0x2000;
- }
- if (BIT(data, 12) && !BIT(m_io_regs[offset], 1))
- {
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 0x2000;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- {
- check_irqs(changed);
- }
- }
- break;
- }
-
- case 0x28: // Sleep Mode
- LOGMASKED(LOG_IO_WRITES, "io_w: Sleep Mode (%s enter value) = %04x\n", data == 0xaa55 ? "valid" : "invalid", data);
- m_io_regs[offset] = data;
- break;
-
- case 0x29: // Wakeup Source
- {
- m_io_regs[offset] = data;
- static const char* const s_sources[8] =
- {
- "TMB1", "TMB2", "2Hz", "4Hz", "1024Hz", "2048Hz", "4096Hz", "Key"
- };
-
- LOGMASKED(LOG_IO_WRITES, "io_w: Wakeup Source = %04x:\n", data);
- bool comma = false;
- char buf[1024];
- int char_idx = 0;
- for (int i = 7; i >= 0; i--)
- {
- if (BIT(data, i))
- {
- char_idx += sprintf(&buf[char_idx], "%s%s", comma ? ", " : "", s_sources[i]);
- comma = true;
- }
- }
- buf[char_idx] = 0;
- LOGMASKED(LOG_IO_WRITES, " %s\n", buf);
- break;
- }
-
- case 0x2c: // PRNG 0 seed
- LOGMASKED(LOG_IO_WRITES, "io_w: PRNG 0 seed = %04x\n", data & 0x7fff);
- m_io_regs[offset] = data & 0x7fff;
- break;
-
- case 0x2d: // PRNG 1 seed
- LOGMASKED(LOG_IO_WRITES, "io_w: PRNG 1 seed = %04x\n", data & 0x7fff);
- m_io_regs[offset] = data & 0x7fff;
- break;
-
- case 0x2e: // FIQ Source Select
- {
- static const char* const s_fiq_select[8] =
- {
- "PPU", "SPU Channel", "Timer A", "Timer B", "UART/SPI", "External", "Reserved", "None"
- };
- LOGMASKED(LOG_FIQ, "io_w: FIQ Source Select (not yet implemented) = %04x, %s\n", data, s_fiq_select[data & 7]);
- m_io_regs[offset] = data;
- break;
- }
-
- case 0x2f: // Data Segment
- m_cpu->set_ds(data & 0x3f);
- LOGMASKED(LOG_SEGMENT, "io_w: Data Segment = %04x\n", data);
- break;
-
- default:
- LOGMASKED(LOG_UNKNOWN_IO, "io_w: Unknown register %04x = %04x\n", 0x3d00 + offset, data);
- m_io_regs[offset] = data;
- break;
- }
-}
-
-
-
-
-WRITE16_MEMBER(spg2xx_io_device::io_extended_w)
-{
- // this set of registers might only be on the 24x not the 11x
-
- offset += 0x30;
-
- switch (offset)
- {
-
- case 0x30: // UART Control
- {
- static const char* const s_9th_bit[4] = { "0", "1", "Odd", "Even" };
- LOGMASKED(LOG_UART, "%s: io_w: UART Control = %04x (TxEn:%d, RxEn:%d, Bits:%d, MultiProc:%d, 9thBit:%s, TxIntEn:%d, RxIntEn:%d\n",
- machine().describe_context(), data, BIT(data, 7), BIT(data, 6), BIT(data, 5) ? 9 : 8, BIT(data, 4), s_9th_bit[(data >> 2) & 3],
- BIT(data, 1), BIT(data, 0));
- const uint16_t changed = m_io_regs[offset] ^ data;
- m_io_regs[offset] = data;
- if (!BIT(data, 6))
- {
- m_uart_rx_available = false;
- m_io_regs[0x36] = 0;
- }
- if (BIT(changed, 7))
- {
- if (BIT(data, 7))
- {
- m_io_regs[0x31] |= 0x0002;
- }
- else
- {
- m_io_regs[0x31] &= ~0x0042;
- m_uart_tx_timer->adjust(attotime::never);
- }
- }
- break;
- }
-
- case 0x31: // UART Status
- LOGMASKED(LOG_UART, "%s: io_w: UART Status = %04x\n", machine().describe_context(), data);
- if (BIT(data, 0))
- {
- m_io_regs[0x31] &= ~1;
- m_uart_rx_irq = false;
- }
- if (BIT(data, 1))
- {
- m_io_regs[0x31] &= ~2;
- m_uart_tx_irq = false;
- }
- if (!m_uart_rx_irq && !m_uart_tx_irq)
- {
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS &= ~0x0100;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(0x0100);
- }
- break;
-
- case 0x33: // UART Baud Rate (low byte)
- case 0x34: // UART Baud Rate (high byte)
- {
- m_io_regs[offset] = data;
- const uint32_t divisor = 16 * (0x10000 - ((m_io_regs[0x34] << 8) | m_io_regs[0x33]));
- LOGMASKED(LOG_UART, "%s: io_w: UART Baud Rate (%s byte): Baud rate = %d\n", offset == 0x33 ? "low" : "high", machine().describe_context(), 27000000 / divisor);
- m_uart_baud_rate = 27000000 / divisor;
- break;
- }
-
- case 0x35: // UART TX Data
- LOGMASKED(LOG_UART, "%s: io_w: UART Tx Data = %02x\n", machine().describe_context(), data & 0x00ff);
- m_io_regs[offset] = data;
- if (BIT(m_io_regs[0x30], 7))
- {
- LOGMASKED(LOG_UART, "io_w: UART Tx: Clearing ready bit, setting busy bit, setting up timer\n");
- m_uart_tx_timer->adjust(attotime::from_ticks(BIT(m_io_regs[0x30], 5) ? 11 : 10, m_uart_baud_rate));
- m_io_regs[0x31] &= ~0x0002;
- m_io_regs[0x31] |= 0x0040;
- }
- break;
-
- case 0x36: // UART RX Data
- LOGMASKED(LOG_UART, "%s: io_w: UART Rx Data (read-only) = %04x\n", machine().describe_context(), data);
- break;
-
- case 0x37: // UART Rx FIFO Control
- LOGMASKED(LOG_UART, "%s: io_w: UART Rx FIFO Control = %04x (Reset:%d, Overrun:%d, Underrun:%d, Count:%d, Threshold:%d)\n",
- machine().describe_context(), data, BIT(data, 15), BIT(data, 14), BIT(data, 13), (data >> 4) & 7, data & 7);
- if (data & 0x8000)
- {
- m_uart_rx_available = false;
- m_io_regs[0x36] = 0;
- }
- m_io_regs[offset] &= ~data & 0x6000;
- m_io_regs[offset] &= ~0x0007;
- m_io_regs[offset] |= data & 0x0007;
- break;
-
- case 0x50: // SIO Setup
- {
- static const char* const s_addr_mode[4] = { "16-bit", "None", "8-bit", "24-bit" };
- static const char* const s_baud_rate[4] = { "/16", "/4", "/8", "/32" };
- LOGMASKED(LOG_SIO, "io_w: SIO Setup (not implemented) = %04x (DS301Ready:%d, Start:%d, Auto:%d, IRQEn:%d, Width:%d, Related:%d\n", data
- , BIT(data, 11), BIT(data, 10), BIT(data, 9), BIT(data, 8), BIT(data, 7) ? 16 : 8, BIT(data, 6));
- LOGMASKED(LOG_SIO, " (Mode:%s, RWProtocol:%d, Rate:sysclk%s, AddrMode:%s)\n"
- , BIT(data, 5), BIT(data, 4), s_baud_rate[(data >> 2) & 3], s_addr_mode[data & 3]);
- break;
- }
-
- case 0x52: // SIO Start Address (low)
- LOGMASKED(LOG_SIO, "io_w: SIO Stat Address (low) (not implemented) = %04x\n", data);
- break;
-
- case 0x53: // SIO Start Address (hi)
- LOGMASKED(LOG_SIO, "io_w: SIO Stat Address (hi) (not implemented) = %04x\n", data);
- break;
-
- case 0x54: // SIO Data
- LOGMASKED(LOG_SIO, "io_w: SIO Data (not implemented) = %04x\n", data);
- break;
-
- case 0x55: // SIO Automatic Transmit Count
- LOGMASKED(LOG_SIO, "io_w: SIO Auto Transmit Count (not implemented) = %04x\n", data);
- break;
-
- case 0x58: // I2C Command
- LOGMASKED(LOG_I2C, "io_w: I2C Command = %04x\n", data);
- m_io_regs[offset] = data;
- do_i2c();
- break;
-
- case 0x59: // I2C Status / Acknowledge
- LOGMASKED(LOG_I2C, "io_w: I2C Acknowledge = %04x\n", data);
- m_io_regs[offset] &= ~data;
- break;
-
- case 0x5a: // I2C Access Mode
- LOGMASKED(LOG_I2C, "io_w: I2C Access Mode = %04x\n", data);
- m_io_regs[offset] = data;
- break;
-
- case 0x5b: // I2C Device Address
- LOGMASKED(LOG_I2C, "io_w: I2C Device Address = %04x\n", data);
- m_io_regs[offset] = data;
- break;
-
- case 0x5c: // I2C Sub-Address
- LOGMASKED(LOG_I2C, "io_w: I2C Sub-Address = %04x\n", data);
- m_io_regs[offset] = data;
- break;
-
- case 0x5d: // I2C Data Out
- LOGMASKED(LOG_I2C, "io_w: I2C Data Out = %04x\n", data);
- m_io_regs[offset] = data;
- break;
-
- case 0x5e: // I2C Data In
- LOGMASKED(LOG_I2C, "io_w: I2C Data In = %04x\n", data);
- m_io_regs[offset] = data;
- break;
-
- case 0x5f: // I2C Controller Mode
- LOGMASKED(LOG_I2C, "io_w: I2C Controller Mode = %04x\n", data);
- m_io_regs[offset] = data;
- break;
-
- default:
- LOGMASKED(LOG_UNKNOWN_IO, "io_w: Unknown register %04x = %04x\n", 0x3d00 + offset, data);
- m_io_regs[offset] = data;
- break;
- }
-}
-
-void spg2xx_io_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id)
- {
- case TIMER_TMB1:
- {
- LOGMASKED(LOG_TIMERS, "TMB1 elapsed, setting IRQ Status bit 0 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 1, IO_IRQ_ENABLE);
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 1;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(0x0001);
- break;
- }
-
- case TIMER_TMB2:
- {
- LOGMASKED(LOG_TIMERS, "TMB2 elapsed, setting IRQ Status bit 1 (old:%04x, new:%04x, enable:%04x)\n", IO_IRQ_STATUS, IO_IRQ_STATUS | 2, IO_IRQ_ENABLE);
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 2;
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(0x0002);
- break;
- }
-
- case TIMER_UART_TX:
- uart_transmit_tick();
- break;
-
- case TIMER_UART_RX:
- uart_receive_tick();
- break;
-
- case TIMER_4KHZ:
- system_timer_tick();
- break;
-
- case TIMER_SRC_AB:
- update_timer_ab_src();
- break;
-
- case TIMER_SRC_C:
- update_timer_c_src();
- break;
- }
-}
-
-void spg2xx_io_device::system_timer_tick()
-{
- const uint16_t old = IO_IRQ_STATUS;
- uint16_t check_mask = 0x0040;
- IO_IRQ_STATUS |= 0x0040;
-
- m_2khz_divider++;
- if (m_2khz_divider == 2)
- {
- m_2khz_divider = 0;
- IO_IRQ_STATUS |= 0x0020;
- check_mask |= 0x0020;
-
- m_1khz_divider++;
- if (m_1khz_divider == 2)
- {
- m_1khz_divider = 0;
- IO_IRQ_STATUS |= 0x0010;
- check_mask |= 0x0010;
-
- m_4hz_divider++;
- if (m_4hz_divider == 256)
- {
- m_4hz_divider = 0;
- IO_IRQ_STATUS |= 0x0008;
- check_mask |= 0x0008;
- }
- }
- }
-
- const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE);
- if (changed)
- check_irqs(check_mask);
-}
-
-void spg2xx_io_device::uart_transmit_tick()
-{
- LOGMASKED(LOG_UART, "uart_transmit_tick: Transmitting %02x, setting TxReady, clearing TxBusy\n", (uint8_t)m_io_regs[0x35]);
- m_uart_tx((uint8_t)m_io_regs[0x35]);
- m_io_regs[0x31] |= 0x0002;
- m_io_regs[0x31] &= ~0x0040;
- if (BIT(m_io_regs[0x30], 1))
- {
- const uint16_t old = IO_IRQ_STATUS;
- IO_IRQ_STATUS |= 0x0100;
- m_uart_tx_irq = true;
- LOGMASKED(LOG_UART, "uart_transmit_tick: Setting UART IRQ bit\n");
- if (IO_IRQ_STATUS != old)
- {
- LOGMASKED(LOG_UART, "uart_transmit_tick: Bit newly set, checking IRQs\n");
- check_irqs(0x0100);
- }
- }
-}
-
-void spg2xx_io_device::uart_receive_tick()
-{
- LOGMASKED(LOG_UART, "uart_receive_tick: Setting RBF and RxRDY\n");
- m_io_regs[0x31] |= 0x81;
- m_uart_rx_available = true;
- if (BIT(m_io_regs[0x30], 0))
- {
- LOGMASKED(LOG_UART, "uart_receive_tick: RxIntEn is set, setting rx_irq to true and setting UART IRQ\n");
- m_uart_rx_irq = true;
- IO_IRQ_STATUS |= 0x0100;
- check_irqs(0x0100);
- }
-}
-
-void spg2xx_io_device::extint_w(int channel, bool state)
-{
- LOGMASKED(LOG_EXTINT, "Setting extint channel %d to %s\n", channel, state ? "true" : "false");
- bool old = m_extint[channel];
- m_extint[channel] = state;
- if (old != state)
- {
- check_extint_irq(channel);
- }
-}
-
-void spg2xx_io_device::check_extint_irq(int channel)
-{
- LOGMASKED(LOG_EXTINT, "%sing extint %d interrupt\n", m_extint[channel] ? "rais" : "lower", channel + 1);
- const uint16_t mask = (channel == 0) ? 0x0200 : 0x1000;
- const uint16_t old_irq = IO_IRQ_STATUS;
- if (m_extint[channel])
- IO_IRQ_STATUS |= mask;
- else
- IO_IRQ_STATUS &= ~mask;
-
- if (old_irq != IO_IRQ_STATUS)
- {
- LOGMASKED(LOG_EXTINT, "extint IRQ changed, so checking interrupts\n");
- check_irqs(mask);
- }
-}
-
-void spg2xx_io_device::check_irqs(const uint16_t changed)
-{
- if (changed & 0x0c00) // Timer A, Timer B IRQ
- {
- LOGMASKED(LOG_TIMERS, "%ssserting IRQ2 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00), changed);
- m_timer_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0c00) ? ASSERT_LINE : CLEAR_LINE);
- }
-
- if (changed & 0x2100) // UART, ADC IRQ
- {
- LOGMASKED(LOG_UART, "%ssserting IRQ3 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100), changed);
- m_uart_adc_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x2100) ? ASSERT_LINE : CLEAR_LINE);
- }
-
- if (changed & 0x1200) // External IRQ
- {
- LOGMASKED(LOG_UART, "%ssserting IRQ5 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200), changed);
- m_external_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x1200) ? ASSERT_LINE : CLEAR_LINE);
- }
-
- if (changed & 0x0070) // 1024Hz, 2048Hz, 4096Hz IRQ
- {
- LOGMASKED(LOG_TIMERS, "%ssserting IRQ6 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070), changed); //m_cpu->set_state_unsynced(UNSP_IRQ6_LINE, (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE);
- m_ffreq_tmr1_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x0070) ? ASSERT_LINE : CLEAR_LINE);
- }
-
- if (changed & 0x008b) // TMB1, TMB2, 4Hz, key change IRQ
- {
- LOGMASKED(LOG_IRQS, "%ssserting IRQ7 (%04x, %04x)\n", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? "A" : "Dea", (IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b), changed);
- m_ffreq_tmr2_irq_cb((IO_IRQ_ENABLE & IO_IRQ_STATUS & 0x008b) ? ASSERT_LINE : CLEAR_LINE);
- }
-}
-
-uint16_t spg2xx_io_device::do_special_gpio(uint32_t index, uint16_t mask)
-{
- uint16_t data = 0;
- switch (index)
- {
- case 0: // Port A
- if (mask & 0xe000)
- {
- const uint8_t csel = m_cpu->get_csb() & 0x0e;
- data = (csel << 12) & mask;
- }
- break;
- case 1: // Port B
- // To do
- break;
- case 2: // Port C
- // To do
- break;
- default:
- // Can't happen
- break;
- }
- return data;
-}
-
-void spg2xx_io_device::do_gpio(uint32_t offset, bool write)
-{
- uint32_t index = (offset - 1) / 5;
- uint16_t buffer = m_io_regs[5 * index + 2];
- uint16_t dir = m_io_regs[5 * index + 3];
- uint16_t attr = m_io_regs[5 * index + 4];
- uint16_t special = m_io_regs[5 * index + 5];
-
- uint16_t push = dir;
- uint16_t pull = ~dir;
- uint16_t what = (buffer & (push | pull));
- what ^= (dir & ~attr);
- what &= ~special;
-
- switch (index)
- {
- case 0:
- if (write)
- m_porta_out(0, what, push &~ special);
- what = (what & ~pull);
- if (!write)
- what |= m_porta_in(0, pull &~ special) & pull;
- break;
- case 1:
- if (write)
- m_portb_out(0, what, push &~ special);
- what = (what & ~pull);
- if (!write)
- what |= m_portb_in(0, pull &~ special) & pull;
- break;
- case 2:
- if (write)
- m_portc_out(0, what, push &~ special);
- what = (what & ~pull);
- if (!write)
- what |= m_portc_in(0, pull &~ special) & pull;
- break;
- }
-
- what |= do_special_gpio(index, special);
- m_io_regs[5 * index + 1] = what;
-}
-
-void spg2xx_io_device::do_i2c()
-{
- const uint16_t addr = ((m_io_regs[0x5b] & 0x06) << 7) | (uint8_t)m_io_regs[0x5c];
-
- if (m_io_regs[0x58] & 0x40) // Serial EEPROM read
- m_io_regs[0x5e] = m_eeprom_r(addr);
- else
- m_eeprom_w(addr, m_io_regs[0x5d]);
-
- m_io_regs[0x59] |= 1;
-}
diff --git a/src/devices/machine/spg2xx_io.h b/src/devices/machine/spg2xx_io.h
deleted file mode 100644
index d829915cbec..00000000000
--- a/src/devices/machine/spg2xx_io.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Ryan Holtz
-
-#ifndef MAME_MACHINE_SPG2XX_IO_H
-#define MAME_MACHINE_SPG2XX_IO_H
-
-#pragma once
-
-#include "cpu/unsp/unsp.h"
-#include "screen.h"
-
-class spg2xx_io_device : public device_t
-{
-public:
- spg2xx_io_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- auto porta_out() { return m_porta_out.bind(); }
- auto portb_out() { return m_portb_out.bind(); }
- auto portc_out() { return m_portc_out.bind(); }
- auto porta_in() { return m_porta_in.bind(); }
- auto portb_in() { return m_portb_in.bind(); }
- auto portc_in() { return m_portc_in.bind(); }
-
- template <size_t Line> auto adc_in() { return m_adc_in[Line].bind(); }
-
- auto eeprom_w() { return m_eeprom_w.bind(); }
- auto eeprom_r() { return m_eeprom_r.bind(); }
-
- auto uart_tx() { return m_uart_tx.bind(); }
-
- auto chip_select() { return m_chip_sel.bind(); }
-
- void uart_rx(uint8_t data);
-
- void extint_w(int channel, bool state);
-
- DECLARE_READ16_MEMBER(io_r);
- DECLARE_WRITE16_MEMBER(io_w);
-
- virtual DECLARE_READ16_MEMBER(io_extended_r);
- virtual DECLARE_WRITE16_MEMBER(io_extended_w);
-
-
- auto pal_read_callback() { return m_pal_read_cb.bind(); };
-
- auto write_timer_irq_callback() { return m_timer_irq_cb.bind(); };
- auto write_uart_adc_irq_callback() { return m_uart_adc_irq_cb.bind(); };
- auto write_external_irq_callback() { return m_external_irq_cb.bind(); };
- auto write_ffrq_tmr1_irq_callback() { return m_ffreq_tmr1_irq_cb.bind(); };
- auto write_ffrq_tmr2_irq_callback() { return m_ffreq_tmr2_irq_cb.bind(); };
-
-protected:
- spg2xx_io_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const uint32_t sprite_limit)
- : spg2xx_io_device(mconfig, type, tag, owner, clock)
- {
- }
-
- void check_extint_irq(int channel);
- void check_irqs(const uint16_t changed);
-
- static const device_timer_id TIMER_TMB1 = 0;
- static const device_timer_id TIMER_TMB2 = 1;
-
- static const device_timer_id TIMER_UART_TX = 4;
- static const device_timer_id TIMER_UART_RX = 5;
- static const device_timer_id TIMER_4KHZ = 6;
- static const device_timer_id TIMER_SRC_AB = 7;
- static const device_timer_id TIMER_SRC_C = 8;
-
- virtual void device_start() override;
- virtual void device_reset() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
-
- void update_porta_special_modes();
- void update_portb_special_modes();
- void do_gpio(uint32_t offset, bool write);
- uint16_t do_special_gpio(uint32_t index, uint16_t mask);
-
- void update_timer_b_rate();
- void update_timer_ab_src();
- void update_timer_c_src();
- void increment_timer_a();
-
- void uart_transmit_tick();
- void uart_receive_tick();
-
- void system_timer_tick();
-
- void do_i2c();
-
- uint16_t m_io_regs[0x100];
-
- uint8_t m_uart_rx_fifo[8];
- uint8_t m_uart_rx_fifo_start;
- uint8_t m_uart_rx_fifo_end;
- uint8_t m_uart_rx_fifo_count;
- bool m_uart_rx_available;
- bool m_uart_rx_irq;
- bool m_uart_tx_irq;
-
- bool m_extint[2];
-
- devcb_write16 m_porta_out;
- devcb_write16 m_portb_out;
- devcb_write16 m_portc_out;
- devcb_read16 m_porta_in;
- devcb_read16 m_portb_in;
- devcb_read16 m_portc_in;
-
- devcb_read16 m_adc_in[2];
-
- devcb_write8 m_eeprom_w;
- devcb_read8 m_eeprom_r;
-
- devcb_write8 m_uart_tx;
-
- devcb_write8 m_chip_sel;
-
- uint16_t m_timer_a_preload;
- uint16_t m_timer_b_preload;
- uint16_t m_timer_b_divisor;
- uint16_t m_timer_b_tick_rate;
-
- emu_timer *m_tmb1;
- emu_timer *m_tmb2;
- emu_timer *m_timer_src_ab;
- emu_timer *m_timer_src_c;
-
- emu_timer *m_4khz_timer;
- uint32_t m_2khz_divider;
- uint32_t m_1khz_divider;
- uint32_t m_4hz_divider;
-
- uint32_t m_uart_baud_rate;
- emu_timer *m_uart_tx_timer;
- emu_timer *m_uart_rx_timer;
-
- required_device<unsp_device> m_cpu;
- required_device<screen_device> m_screen;
-
- devcb_read16 m_pal_read_cb;
-
- devcb_write_line m_timer_irq_cb;
- devcb_write_line m_uart_adc_irq_cb;
- devcb_write_line m_external_irq_cb;
- devcb_write_line m_ffreq_tmr1_irq_cb;
- devcb_write_line m_ffreq_tmr2_irq_cb;
-};
-
-class spg24x_io_device : public spg2xx_io_device
-{
-public:
- template <typename T, typename U>
- spg24x_io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag, U &&screen_tag)
- : spg24x_io_device(mconfig, tag, owner, clock)
- {
- m_cpu.set_tag(std::forward<T>(cpu_tag));
- m_screen.set_tag(std::forward<U>(screen_tag));
- }
-
- spg24x_io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-};
-
-class spg28x_io_device : public spg2xx_io_device
-{
-public:
- template <typename T, typename U>
- spg28x_io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag, U &&screen_tag)
- : spg28x_io_device(mconfig, tag, owner, clock)
- {
- m_cpu.set_tag(std::forward<T>(cpu_tag));
- m_screen.set_tag(std::forward<U>(screen_tag));
- }
-
- spg28x_io_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- virtual DECLARE_WRITE16_MEMBER(io_extended_w) override;
-};
-
-DECLARE_DEVICE_TYPE(SPG24X_IO, spg24x_io_device)
-DECLARE_DEVICE_TYPE(SPG28X_IO, spg28x_io_device)
-
-#endif // MAME_MACHINE_SPG2XX_IO_H
diff --git a/src/devices/machine/strata.cpp b/src/devices/machine/strata.cpp
index df434adbd24..3f32b62739f 100644
--- a/src/devices/machine/strata.cpp
+++ b/src/devices/machine/strata.cpp
@@ -203,7 +203,7 @@ void strataflash_device::device_start()
/*
read a 8/16-bit word from FEEPROM
*/
-uint16_t strataflash_device::read8_16(offs_t offset, bus_width_t bus_width)
+uint16_t strataflash_device::read8_16(address_space& space, offs_t offset, bus_width_t bus_width)
{
switch (bus_width)
{
@@ -393,7 +393,7 @@ uint16_t strataflash_device::read8_16(offs_t offset, bus_width_t bus_width)
/*
write a 8/16-bit word to FEEPROM
*/
-void strataflash_device::write8_16(offs_t offset, uint16_t data, bus_width_t bus_width)
+void strataflash_device::write8_16(address_space& space, offs_t offset, uint16_t data, bus_width_t bus_width)
{
switch (bus_width)
{
@@ -634,31 +634,31 @@ void strataflash_device::write8_16(offs_t offset, uint16_t data, bus_width_t bus
/*
read a byte from FEEPROM
*/
-uint8_t strataflash_device::read8(offs_t offset)
+READ8_MEMBER( strataflash_device::read8 )
{
- return read8_16(offset, bw_8);
+ return read8_16(space, offset, bw_8);
}
/*
Write a byte to FEEPROM
*/
-void strataflash_device::write8(offs_t offset, uint8_t data)
+WRITE8_MEMBER( strataflash_device::write8 )
{
- write8_16(offset, data, bw_8);
+ write8_16(space, offset, data, bw_8);
}
/*
read a 16-bit word from FEEPROM
*/
-uint16_t strataflash_device::read16(offs_t offset)
+READ16_MEMBER( strataflash_device::read16 )
{
- return read8_16(offset, bw_16);
+ return read8_16(space, offset, bw_16);
}
/*
Write a byte to FEEPROM
*/
-void strataflash_device::write16(offs_t offset, uint16_t data)
+WRITE16_MEMBER( strataflash_device::write16 )
{
- write8_16(offset, data, bw_16);
+ write8_16(space, offset, data, bw_16);
}
diff --git a/src/devices/machine/strata.h b/src/devices/machine/strata.h
index 1a3acbbd9dd..26d8675f436 100644
--- a/src/devices/machine/strata.h
+++ b/src/devices/machine/strata.h
@@ -12,12 +12,12 @@ public:
strataflash_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// 8-bit access
- uint8_t read8(offs_t offset);
- void write8(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read8 );
+ DECLARE_WRITE8_MEMBER( write8 );
// 16-bit access
- uint16_t read16(offs_t offset);
- void write16(offs_t offset, uint16_t data);
+ DECLARE_READ16_MEMBER( read16 );
+ DECLARE_WRITE16_MEMBER( write16 );
protected:
// device-level overrides
@@ -36,8 +36,8 @@ private:
bw_16
};
- uint16_t read8_16(offs_t offset, bus_width_t bus_width);
- void write8_16(offs_t offset, uint16_t data, bus_width_t bus_width);
+ uint16_t read8_16(address_space& space, offs_t offset, bus_width_t bus_width);
+ void write8_16(address_space& space, offs_t offset, uint16_t data, bus_width_t bus_width);
enum fm_mode_t
{
diff --git a/src/devices/machine/stvcd.cpp b/src/devices/machine/stvcd.cpp
index c4b7ada9b9f..09323a7deea 100644
--- a/src/devices/machine/stvcd.cpp
+++ b/src/devices/machine/stvcd.cpp
@@ -78,17 +78,17 @@ stvcd_device::stvcd_device(const machine_config &mconfig, const char *tag, devic
{
}
-void stvcd_device::device_add_mconfig(machine_config &config)
-{
- CDROM(config, "cdrom").set_interface("sat_cdrom");
+MACHINE_CONFIG_START(stvcd_device::device_add_mconfig)
+ MCFG_CDROM_ADD("cdrom")
+ MCFG_CDROM_INTERFACE("sat_cdrom")
- TIMER(config, m_sector_timer).configure_generic(FUNC(stvcd_device::stv_sector_cb));
- TIMER(config, m_sh1_timer).configure_generic(FUNC(stvcd_device::stv_sh1_sim));
+ MCFG_TIMER_DRIVER_ADD("sector_timer", stvcd_device, stv_sector_cb)
+ MCFG_TIMER_DRIVER_ADD("sh1_cmd", stvcd_device, stv_sh1_sim)
- CDDA(config, m_cdda);
- m_cdda->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
- m_cdda->add_route(1, *this, 1.0, AUTO_ALLOC_INPUT, 1);
-}
+ MCFG_DEVICE_ADD("cdda", CDDA)
+ MCFG_MIXER_ROUTE(0, *this, 1.0, 0)
+ MCFG_MIXER_ROUTE(1, *this, 1.0, 1)
+MACHINE_CONFIG_END
void stvcd_device::device_start()
{
diff --git a/src/devices/machine/tc009xlvc.cpp b/src/devices/machine/tc009xlvc.cpp
index a870dee98a6..4624e3fc79d 100644
--- a/src/devices/machine/tc009xlvc.cpp
+++ b/src/devices/machine/tc009xlvc.cpp
@@ -171,7 +171,7 @@ void tc0091lvc_device::tc0091lvc_map8(address_map &map)
tc0091lvc_device::tc0091lvc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, TC0091LVC, tag, owner, clock)
, device_memory_interface(mconfig, *this)
- , m_space_config("tc0091lvc", ENDIANNESS_LITTLE, 8,20, 0, address_map_constructor(FUNC(tc0091lvc_device::tc0091lvc_map8), this))
+ , m_space_config("tc0091lvc", ENDIANNESS_LITTLE, 8,20, 0, address_map_constructor(), address_map_constructor(FUNC(tc0091lvc_device::tc0091lvc_map8), this))
, m_gfxdecode(*this, finder_base::DUMMY_TAG)
{
}
diff --git a/src/devices/machine/terminal.cpp b/src/devices/machine/terminal.cpp
index c2e5c5be205..be9b501c687 100644
--- a/src/devices/machine/terminal.cpp
+++ b/src/devices/machine/terminal.cpp
@@ -326,22 +326,21 @@ void generic_terminal_device::kbd_put(u8 data)
VIDEO HARDWARE
***************************************************************************/
-void generic_terminal_device::device_add_mconfig(machine_config &config)
-{
- screen_device &screen(SCREEN(config, TERMINAL_SCREEN_TAG, SCREEN_TYPE_RASTER));
- screen.set_refresh_hz(50);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
- screen.set_size(generic_terminal_device::TERMINAL_WIDTH*8, generic_terminal_device::TERMINAL_HEIGHT*10);
- screen.set_visarea(0, generic_terminal_device::TERMINAL_WIDTH*8-1, 0, generic_terminal_device::TERMINAL_HEIGHT*10-1);
- screen.set_screen_update(FUNC(generic_terminal_device::update));
+MACHINE_CONFIG_START(generic_terminal_device::device_add_mconfig)
+ MCFG_SCREEN_ADD(TERMINAL_SCREEN_TAG, RASTER)
+ MCFG_SCREEN_REFRESH_RATE(50)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
+ MCFG_SCREEN_SIZE(generic_terminal_device::TERMINAL_WIDTH*8, generic_terminal_device::TERMINAL_HEIGHT*10)
+ MCFG_SCREEN_VISIBLE_AREA(0, generic_terminal_device::TERMINAL_WIDTH*8-1, 0, generic_terminal_device::TERMINAL_HEIGHT*10-1)
+ MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, generic_terminal_device, update)
generic_keyboard_device &keyboard(GENERIC_KEYBOARD(config, KEYBOARD_TAG, 0));
keyboard.set_keyboard_callback(FUNC(generic_terminal_device::kbd_put));
SPEAKER(config, "bell").front_center();
- BEEP(config, m_beeper, 2'000);
- m_beeper->add_route(ALL_OUTPUTS, "bell", 0.25);
-}
+ MCFG_DEVICE_ADD("beeper", BEEP, 2'000)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "bell", 0.25)
+MACHINE_CONFIG_END
void generic_terminal_device::device_start()
{
diff --git a/src/devices/machine/terminal.h b/src/devices/machine/terminal.h
index dab8bd40578..bf2f81c07f7 100644
--- a/src/devices/machine/terminal.h
+++ b/src/devices/machine/terminal.h
@@ -36,7 +36,7 @@ public:
}
void set_keyboard_callback(generic_keyboard_device::output_delegate callback) { m_keyboard_cb = callback; }
- void write(u8 data) { term_write(data); }
+ DECLARE_WRITE8_MEMBER(write) { term_write(data); }
void kbd_put(u8 data);
diff --git a/src/devices/machine/ticket.h b/src/devices/machine/ticket.h
index 7330ad3cb74..813e27b95c1 100644
--- a/src/devices/machine/ticket.h
+++ b/src/devices/machine/ticket.h
@@ -21,6 +21,22 @@
DECLARE_DEVICE_TYPE(TICKET_DISPENSER, ticket_dispenser_device)
DECLARE_DEVICE_TYPE(HOPPER, hopper_device)
+
+//**************************************************************************
+// DEVICE CONFIGURATION MACROS
+//**************************************************************************
+
+// add/remove dispensers
+#define MCFG_TICKET_DISPENSER_ADD(_tag, _period_in_msec, _motor_sense, _status_sense) \
+ MCFG_DEVICE_ADD(_tag, TICKET_DISPENSER, 0) \
+ downcast<ticket_dispenser_device &>(*device).set_period(_period_in_msec); \
+ downcast<ticket_dispenser_device &>(*device).set_senses(_motor_sense, _status_sense, false);
+
+#define MCFG_HOPPER_ADD(_tag, _period_in_msec, _motor_sense, _status_sense) \
+ MCFG_DEVICE_ADD(_tag, TICKET_DISPENSER, 0) \
+ downcast<ticket_dispenser_device &>(*device).set_period(_period_in_msec); \
+ downcast<ticket_dispenser_device &>(*device).set_senses(_motor_sense, _status_sense, true);
+
//**************************************************************************
// CONSTANTS
//**************************************************************************
diff --git a/src/devices/machine/timekpr.cpp b/src/devices/machine/timekpr.cpp
index f7cfed5451c..7dddede2c05 100644
--- a/src/devices/machine/timekpr.cpp
+++ b/src/devices/machine/timekpr.cpp
@@ -37,47 +37,53 @@ DEFINE_DEVICE_TYPE(MK48T12, mk48t12_device, "mk48t12", "MK48T12 Timekeeper")
MACROS
***************************************************************************/
-#define MASK_SECONDS (0x7f)
-#define MASK_MINUTES (0x7f)
-#define MASK_HOURS (0x3f)
-#define MASK_DAY (0x07)
-#define MASK_DATE (0x3f)
-#define MASK_MONTH (0x1f)
-#define MASK_YEAR (0xff)
-#define MASK_CENTURY (0xff)
+#define MASK_SECONDS ( 0x7f )
+#define MASK_MINUTES ( 0x7f )
+#define MASK_HOURS ( 0x3f )
+#define MASK_DAY ( 0x07 )
+#define MASK_DATE ( 0x3f )
+#define MASK_MONTH ( 0x1f )
+#define MASK_YEAR ( 0xff )
+#define MASK_CENTURY ( 0xff )
-#define CONTROL_W (0x80)
-#define CONTROL_R (0x40)
-#define CONTROL_S (0x20) /* not emulated */
-#define CONTROL_CALIBRATION (0x1f) /* not emulated */
+#define CONTROL_W ( 0x80 )
+#define CONTROL_R ( 0x40 )
+#define CONTROL_S ( 0x20 ) /* not emulated */
+#define CONTROL_CALIBRATION ( 0x1f ) /* not emulated */
-#define SECONDS_ST (0x80)
+#define SECONDS_ST ( 0x80 )
-#define DAY_FT (0x40) /* M48T37 - not emulated */
-#define DAY_CEB (0x20) /* M48T35/M48T58 */
-#define DAY_CB (0x10) /* M48T35/M48T58 */
+#define DAY_FT ( 0x40 ) /* M48T37 - not emulated */
+#define DAY_CEB ( 0x20 ) /* M48T35/M48T58 */
+#define DAY_CB ( 0x10 ) /* M48T35/M48T58 */
-#define DATE_BLE (0x80) /* M48T58: not emulated */
-#define DATE_BL (0x40) /* M48T58: not emulated */
+#define DATE_BLE ( 0x80 ) /* M48T58: not emulated */
+#define DATE_BL ( 0x40 ) /* M48T58: not emulated */
-#define FLAGS_BL (0x10) /* MK48T08/M48T37: not emulated */
-#define FLAGS_AF (0x40) /* M48T37: not emulated */
-#define FLAGS_WDF (0x80) /* M48T37 */
+#define FLAGS_BL ( 0x10 ) /* MK48T08/M48T37: not emulated */
+#define FLAGS_AF ( 0x40 ) /* M48T37: not emulated */
+#define FLAGS_WDF ( 0x80 ) /* M48T37 */
/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
-inline void counter_to_ram(u8 *data, s32 offset, u8 counter)
+static void counter_to_ram( uint8_t *data, int offset, int counter )
{
- if (offset >= 0)
- data[offset] = counter;
+ if( offset >= 0 )
+ {
+ data[ offset ] = counter;
+ }
}
-inline int counter_from_ram(u8 const *data, s32 offset, u8 unmap = 0)
+static int counter_from_ram( uint8_t *data, int offset )
{
- return (offset >= 0) ? data[offset] : unmap;
+ if( offset >= 0 )
+ {
+ return data[ offset ];
+ }
+ return 0;
}
//**************************************************************************
@@ -88,7 +94,7 @@ inline int counter_from_ram(u8 const *data, s32 offset, u8 unmap = 0)
// timekeeper_device_config - constructor
//-------------------------------------------------
-timekeeper_device::timekeeper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 size)
+timekeeper_device::timekeeper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int size)
: device_t(mconfig, type, tag, owner, clock)
, device_nvram_interface(mconfig, *this)
, m_reset_cb(*this)
@@ -98,7 +104,7 @@ timekeeper_device::timekeeper_device(const machine_config &mconfig, device_type
{
}
-m48t02_device::m48t02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+m48t02_device::m48t02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: timekeeper_device(mconfig, M48T02, tag, owner, clock, 0x800)
{
m_offset_watchdog = -1;
@@ -114,7 +120,7 @@ m48t02_device::m48t02_device(const machine_config &mconfig, const char *tag, dev
m_offset_flags = -1;
}
-m48t35_device::m48t35_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+m48t35_device::m48t35_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: timekeeper_device(mconfig, M48T35, tag, owner, clock, 0x8000)
{
m_offset_watchdog = -1;
@@ -130,7 +136,7 @@ m48t35_device::m48t35_device(const machine_config &mconfig, const char *tag, dev
m_offset_flags = -1;
}
-m48t37_device::m48t37_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+m48t37_device::m48t37_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: timekeeper_device(mconfig, M48T37, tag, owner, clock, 0x8000)
{
m_offset_watchdog = 0x7ff7;
@@ -146,7 +152,7 @@ m48t37_device::m48t37_device(const machine_config &mconfig, const char *tag, dev
m_offset_flags = 0x7ff0;
}
-m48t58_device::m48t58_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+m48t58_device::m48t58_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: timekeeper_device(mconfig, M48T58, tag, owner, clock, 0x2000)
{
m_offset_watchdog = -1;
@@ -162,7 +168,7 @@ m48t58_device::m48t58_device(const machine_config &mconfig, const char *tag, dev
m_offset_flags = -1;
}
-mk48t08_device::mk48t08_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+mk48t08_device::mk48t08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: timekeeper_device(mconfig, MK48T08, tag, owner, clock, 0x2000)
{
m_offset_watchdog = -1;
@@ -178,7 +184,7 @@ mk48t08_device::mk48t08_device(const machine_config &mconfig, const char *tag, d
m_offset_flags = 0x1ff0;
}
-mk48t12_device::mk48t12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+mk48t12_device::mk48t12_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: timekeeper_device(mconfig, MK48T12, tag, owner, clock, 0x800)
{
m_offset_watchdog = -1;
@@ -208,27 +214,27 @@ void timekeeper_device::device_start()
machine().base_datetime(systime);
m_control = 0;
- m_seconds = time_helper::make_bcd(systime.local_time.second);
- m_minutes = time_helper::make_bcd(systime.local_time.minute);
- m_hours = time_helper::make_bcd(systime.local_time.hour);
- m_day = time_helper::make_bcd(systime.local_time.weekday + 1);
- m_date = time_helper::make_bcd(systime.local_time.mday);
- m_month = time_helper::make_bcd(systime.local_time.month + 1);
- m_year = time_helper::make_bcd(systime.local_time.year % 100);
- m_century = time_helper::make_bcd(systime.local_time.year / 100);
- m_data.resize(m_size);
-
- save_item(NAME(m_control));
- save_item(NAME(m_seconds));
- save_item(NAME(m_minutes));
- save_item(NAME(m_hours));
- save_item(NAME(m_day));
- save_item(NAME(m_date));
- save_item(NAME(m_month));
- save_item(NAME(m_year));
- save_item(NAME(m_century));
- save_item(NAME(m_data));
- save_item(NAME(m_watchdog_delay));
+ m_seconds = time_helper::make_bcd( systime.local_time.second );
+ m_minutes = time_helper::make_bcd( systime.local_time.minute );
+ m_hours = time_helper::make_bcd( systime.local_time.hour );
+ m_day = time_helper::make_bcd( systime.local_time.weekday + 1 );
+ m_date = time_helper::make_bcd( systime.local_time.mday );
+ m_month = time_helper::make_bcd( systime.local_time.month + 1 );
+ m_year = time_helper::make_bcd( systime.local_time.year % 100 );
+ m_century = time_helper::make_bcd( systime.local_time.year / 100 );
+ m_data.resize( m_size );
+
+ save_item( NAME(m_control) );
+ save_item( NAME(m_seconds) );
+ save_item( NAME(m_minutes) );
+ save_item( NAME(m_hours) );
+ save_item( NAME(m_day) );
+ save_item( NAME(m_date) );
+ save_item( NAME(m_month) );
+ save_item( NAME(m_year) );
+ save_item( NAME(m_century) );
+ save_item( NAME(m_data) );
+ save_item( NAME(m_watchdog_delay));
emu_timer *timer = timer_alloc();
timer->adjust(attotime::from_seconds(1), 0, attotime::from_seconds(1));
@@ -248,98 +254,98 @@ void timekeeper_device::device_reset() { }
void timekeeper_device::counters_to_ram()
{
- counter_to_ram(&m_data[0], m_offset_control, m_control);
- counter_to_ram(&m_data[0], m_offset_seconds, m_seconds);
- counter_to_ram(&m_data[0], m_offset_minutes, m_minutes);
- counter_to_ram(&m_data[0], m_offset_hours, m_hours);
- counter_to_ram(&m_data[0], m_offset_day, m_day);
- counter_to_ram(&m_data[0], m_offset_date, m_date);
- counter_to_ram(&m_data[0], m_offset_month, m_month);
- counter_to_ram(&m_data[0], m_offset_year, m_year);
- counter_to_ram(&m_data[0], m_offset_century, m_century);
+ counter_to_ram( &m_data[0], m_offset_control, m_control );
+ counter_to_ram( &m_data[0], m_offset_seconds, m_seconds );
+ counter_to_ram( &m_data[0], m_offset_minutes, m_minutes );
+ counter_to_ram( &m_data[0], m_offset_hours, m_hours );
+ counter_to_ram( &m_data[0], m_offset_day, m_day );
+ counter_to_ram( &m_data[0], m_offset_date, m_date );
+ counter_to_ram( &m_data[0], m_offset_month, m_month );
+ counter_to_ram( &m_data[0], m_offset_year, m_year );
+ counter_to_ram( &m_data[0], m_offset_century, m_century );
}
void timekeeper_device::counters_from_ram()
{
- m_control = counter_from_ram(&m_data[0], m_offset_control);
- m_seconds = counter_from_ram(&m_data[0], m_offset_seconds);
- m_minutes = counter_from_ram(&m_data[0], m_offset_minutes);
- m_hours = counter_from_ram(&m_data[0], m_offset_hours);
- m_day = counter_from_ram(&m_data[0], m_offset_day);
- m_date = counter_from_ram(&m_data[0], m_offset_date);
- m_month = counter_from_ram(&m_data[0], m_offset_month);
- m_year = counter_from_ram(&m_data[0], m_offset_year);
- m_century = counter_from_ram(&m_data[0], m_offset_century);
+ m_control = counter_from_ram( &m_data[0], m_offset_control );
+ m_seconds = counter_from_ram( &m_data[0], m_offset_seconds );
+ m_minutes = counter_from_ram( &m_data[0], m_offset_minutes );
+ m_hours = counter_from_ram( &m_data[0], m_offset_hours );
+ m_day = counter_from_ram( &m_data[0], m_offset_day );
+ m_date = counter_from_ram( &m_data[0], m_offset_date );
+ m_month = counter_from_ram( &m_data[0], m_offset_month );
+ m_year = counter_from_ram( &m_data[0], m_offset_year );
+ m_century = counter_from_ram( &m_data[0], m_offset_century );
}
void timekeeper_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
LOGMASKED(LOG_TICKS, "Tick\n");
- if ((m_seconds & SECONDS_ST) != 0 ||
- (m_control & CONTROL_W) != 0)
+ if( ( m_seconds & SECONDS_ST ) != 0 ||
+ ( m_control & CONTROL_W ) != 0 )
{
logerror("No Tick\n");
return;
}
- int carry = time_helper::inc_bcd(&m_seconds, MASK_SECONDS, 0x00, 0x59);
- if (carry)
+ int carry = time_helper::inc_bcd( &m_seconds, MASK_SECONDS, 0x00, 0x59 );
+ if( carry )
{
- carry = time_helper::inc_bcd(&m_minutes, MASK_MINUTES, 0x00, 0x59);
+ carry = time_helper::inc_bcd( &m_minutes, MASK_MINUTES, 0x00, 0x59 );
}
- if (carry)
+ if( carry )
{
- carry = time_helper::inc_bcd(&m_hours, MASK_HOURS, 0x00, 0x23);
+ carry = time_helper::inc_bcd( &m_hours, MASK_HOURS, 0x00, 0x23 );
}
- if (carry)
+ if( carry )
{
- u8 maxdays;
- static const u8 daysinmonth[] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 };
+ uint8_t maxdays;
+ static const uint8_t daysinmonth[] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 };
- time_helper::inc_bcd(&m_day, MASK_DAY, 0x01, 0x07);
+ time_helper::inc_bcd( &m_day, MASK_DAY, 0x01, 0x07 );
- u8 month = time_helper::from_bcd(m_month);
- u8 year = time_helper::from_bcd(m_year);
+ uint8_t month = time_helper::from_bcd( m_month );
+ uint8_t year = time_helper::from_bcd( m_year );
- if (month == 2 && (year % 4) == 0)
+ if( month == 2 && ( year % 4 ) == 0 )
{
maxdays = 0x29;
}
- else if (month >= 1 && month <= 12)
+ else if( month >= 1 && month <= 12 )
{
- maxdays = daysinmonth[month - 1];
+ maxdays = daysinmonth[ month - 1 ];
}
else
{
maxdays = 0x31;
}
- carry = time_helper::inc_bcd(&m_date, MASK_DATE, 0x01, maxdays);
+ carry = time_helper::inc_bcd( &m_date, MASK_DATE, 0x01, maxdays );
}
- if (carry)
+ if( carry )
{
- carry = time_helper::inc_bcd(&m_month, MASK_MONTH, 0x01, 0x12);
+ carry = time_helper::inc_bcd( &m_month, MASK_MONTH, 0x01, 0x12 );
}
- if (carry)
+ if( carry )
{
- carry = time_helper::inc_bcd(&m_year, MASK_YEAR, 0x00, 0x99);
+ carry = time_helper::inc_bcd( &m_year, MASK_YEAR, 0x00, 0x99 );
}
- if (carry)
+ if( carry )
{
- carry = time_helper::inc_bcd(&m_century, MASK_CENTURY, 0x00, 0x99);
+ carry = time_helper::inc_bcd( &m_century, MASK_CENTURY, 0x00, 0x99 );
- if (type() == M48T35 ||
- type() == M48T58)
+ if( type() == M48T35 ||
+ type() == M48T58 )
{
- if ((m_day & DAY_CEB) != 0)
+ if( ( m_day & DAY_CEB ) != 0 )
{
m_day ^= DAY_CB;
}
}
}
- if ((m_control & CONTROL_R) == 0)
+ if( ( m_control & CONTROL_R ) == 0 )
{
counters_to_ram();
}
@@ -350,59 +356,57 @@ TIMER_CALLBACK_MEMBER(timekeeper_device::watchdog_callback)
// Set Flag
m_data[m_offset_flags] |= FLAGS_WDF;
// WDS (bit 7) selects callback
- if (m_data[m_offset_watchdog] & 0x80)
- {
+ if (m_data[m_offset_watchdog] & 0x80) {
// Clear watchdog register
m_data[m_offset_watchdog] = 0;
m_reset_cb(ASSERT_LINE);
}
- else
+ else {
m_irq_cb(ASSERT_LINE);
-
+ }
logerror("watchdog_callback: WD Control: %02x WD Flags: %02x\n", m_data[m_offset_watchdog], m_data[m_offset_flags]);
}
-void timekeeper_device::watchdog_write(u8 data)
+WRITE8_MEMBER(timekeeper_device::watchdog_write)
{
- if ((m_data[m_offset_watchdog] & 0x7f) != 0)
+ if ((m_data[m_offset_watchdog] & 0x7f) != 0) {
m_watchdog_timer->adjust(m_watchdog_delay);
+ }
}
-void timekeeper_device::write(offs_t offset, u8 data)
+WRITE8_MEMBER( timekeeper_device::write )
{
LOGMASKED(LOG_GENERAL, "timekeeper_device::write: %04x = %02x\n", offset, data);
- if (offset == m_offset_control)
+ if( offset == m_offset_control )
{
- if ((m_control & CONTROL_W) != 0 &&
- (data & CONTROL_W) == 0)
+ if( ( m_control & CONTROL_W ) != 0 &&
+ ( data & CONTROL_W ) == 0 )
{
counters_from_ram();
}
- if ((m_control & CONTROL_R) != 0 &&
- (data & CONTROL_W) == 0)
+ if( ( m_control & CONTROL_R ) != 0 &&
+ ( data & CONTROL_W ) == 0 )
{
counters_to_ram();
}
m_control = data;
}
- else if (offset == m_offset_day)
+ else if( offset == m_offset_day )
{
- if (type() == M48T35 ||
- type() == M48T58)
+ if( type() == M48T35 ||
+ type() == M48T58 )
{
- m_day = (m_day & ~DAY_CEB) | (data & DAY_CEB);
+ m_day = ( m_day & ~DAY_CEB ) | ( data & DAY_CEB );
}
}
else if (offset == m_offset_watchdog && type() == M48T37)
{
- if ((data & 0x7f) == 0)
- {
+ if ((data & 0x7f) == 0) {
m_watchdog_timer->adjust(attotime::never);
}
- else
- {
+ else {
// Calculate the time unit
m_watchdog_delay = attotime::from_usec(62500 << (2 * (data & 0x3)));
// Adjust by multiplier
@@ -412,17 +416,17 @@ void timekeeper_device::write(offs_t offset, u8 data)
}
}
- m_data[offset] = data;
+ m_data[ offset ] = data;
}
-u8 timekeeper_device::read(offs_t offset)
+READ8_MEMBER( timekeeper_device::read )
{
- u8 result = m_data[offset];
- if (offset == m_offset_date && type() == M48T58)
+ uint8_t result = m_data[ offset ];
+ if( offset == m_offset_date && type() == M48T58 )
{
result &= ~DATE_BL;
}
- else if (offset == m_offset_flags && type() == M48T37)
+ else if( offset == m_offset_flags && type() == M48T37 )
{
// Clear the watchdog flag
m_data[m_offset_flags] &= ~FLAGS_WDF;
@@ -443,15 +447,15 @@ void timekeeper_device::nvram_default()
{
if (m_default_data.found())
{
- memcpy(&m_data[0], m_default_data, m_size);
+ memcpy( &m_data[0], m_default_data, m_size );
}
else
{
- memset(&m_data[0], 0xff, m_data.size());
+ memset( &m_data[0], 0xff, m_data.size());
}
- if (m_offset_flags >= 0)
- m_data[m_offset_flags] = 0;
+ if ( m_offset_flags >= 0 )
+ m_data[ m_offset_flags ] = 0;
counters_to_ram();
}
@@ -463,7 +467,7 @@ void timekeeper_device::nvram_default()
void timekeeper_device::nvram_read(emu_file &file)
{
- file.read(&m_data[0], m_size);
+ file.read( &m_data[0], m_size );
counters_to_ram();
}
@@ -476,5 +480,5 @@ void timekeeper_device::nvram_read(emu_file &file)
void timekeeper_device::nvram_write(emu_file &file)
{
- file.write(&m_data[0], m_size);
+ file.write( &m_data[0], m_size );
}
diff --git a/src/devices/machine/timekpr.h b/src/devices/machine/timekpr.h
index def60c02059..4742a1b1ae8 100644
--- a/src/devices/machine/timekpr.h
+++ b/src/devices/machine/timekpr.h
@@ -32,16 +32,16 @@
class timekeeper_device : public device_t, public device_nvram_interface
{
public:
- void write(offs_t offset, u8 data);
- u8 read(offs_t offset);
- void watchdog_write(u8 data = 0);
+ DECLARE_WRITE8_MEMBER( write );
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER(watchdog_write);
auto reset_cb() { return m_reset_cb.bind(); }
auto irq_cb() { return m_irq_cb.bind(); }
protected:
// construction/destruction
- timekeeper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 size);
+ timekeeper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int size);
// device-level overrides
virtual void device_start() override;
@@ -62,70 +62,70 @@ private:
void counters_from_ram();
// internal state
- u8 m_control;
- u8 m_seconds;
- u8 m_minutes;
- u8 m_hours;
- u8 m_day;
- u8 m_date;
- u8 m_month;
- u8 m_year;
- u8 m_century;
-
- std::vector<u8> m_data;
- optional_region_ptr<u8> m_default_data;
+ uint8_t m_control;
+ uint8_t m_seconds;
+ uint8_t m_minutes;
+ uint8_t m_hours;
+ uint8_t m_day;
+ uint8_t m_date;
+ uint8_t m_month;
+ uint8_t m_year;
+ uint8_t m_century;
+
+ std::vector<uint8_t> m_data;
+ optional_region_ptr<uint8_t> m_default_data;
emu_timer* m_watchdog_timer;
attotime m_watchdog_delay;
protected:
- u32 const m_size;
- s32 m_offset_watchdog;
- s32 m_offset_control;
- s32 m_offset_seconds;
- s32 m_offset_minutes;
- s32 m_offset_hours;
- s32 m_offset_day;
- s32 m_offset_date;
- s32 m_offset_month;
- s32 m_offset_year;
- s32 m_offset_century;
- s32 m_offset_flags;
+ int const m_size;
+ int m_offset_watchdog;
+ int m_offset_control;
+ int m_offset_seconds;
+ int m_offset_minutes;
+ int m_offset_hours;
+ int m_offset_day;
+ int m_offset_date;
+ int m_offset_month;
+ int m_offset_year;
+ int m_offset_century;
+ int m_offset_flags;
};
class m48t02_device : public timekeeper_device
{
public:
- m48t02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ m48t02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
};
class m48t35_device : public timekeeper_device
{
public:
- m48t35_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ m48t35_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
};
class m48t37_device : public timekeeper_device
{
public:
- m48t37_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ m48t37_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
};
class m48t58_device : public timekeeper_device
{
public:
- m48t58_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ m48t58_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
};
class mk48t08_device : public timekeeper_device
{
public:
- mk48t08_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ mk48t08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
};
class mk48t12_device : public timekeeper_device
{
public:
- mk48t12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ mk48t12_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
};
// device type definition
diff --git a/src/devices/machine/timer.h b/src/devices/machine/timer.h
index 944db93c1e5..e27c8a8cc53 100644
--- a/src/devices/machine/timer.h
+++ b/src/devices/machine/timer.h
@@ -23,6 +23,44 @@
#define TIMER_DEVICE_CALLBACK_MEMBER(name) void name(timer_device &timer, void *ptr, s32 param)
//**************************************************************************
+// TIMER DEVICE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_TIMER_ADD_NONE(_tag) \
+ MCFG_DEVICE_ADD(_tag, TIMER, 0) \
+ downcast<timer_device &>(*device).configure_generic(timer_device::expired_delegate());
+#define MCFG_TIMER_DRIVER_ADD(_tag, _class, _callback) \
+ MCFG_DEVICE_ADD(_tag, TIMER, 0) \
+ downcast<timer_device &>(*device).configure_generic(timer_device::expired_delegate(&_class::_callback, #_class "::" #_callback, nullptr, (_class *)nullptr));
+#define MCFG_TIMER_DEVICE_ADD(_tag, _devtag, _class, _callback) \
+ MCFG_DEVICE_ADD(_tag, TIMER, 0) \
+ downcast<timer_device &>(*device).configure_generic(timer_device::expired_delegate(&_class::_callback, #_class "::" #_callback, _devtag, (_class *)nullptr));
+#define MCFG_TIMER_DRIVER_ADD_PERIODIC(_tag, _class, _callback, _period) \
+ MCFG_DEVICE_ADD(_tag, TIMER, 0) \
+ downcast<timer_device &>(*device).configure_periodic(timer_device::expired_delegate(&_class::_callback, #_class "::" #_callback, nullptr, (_class *)nullptr), _period);
+#define MCFG_TIMER_DEVICE_ADD_PERIODIC(_tag, _devtag, _class, _callback, _period) \
+ MCFG_DEVICE_ADD(_tag, TIMER, 0) \
+ downcast<timer_device &>(*device).configure_periodic(timer_device::expired_delegate(&_class::_callback, #_class "::" #_callback, _devtag, (_class *)nullptr), _period);
+#define MCFG_TIMER_DRIVER_ADD_SCANLINE(_tag, _class, _callback, _screen, _first_vpos, _increment) \
+ MCFG_DEVICE_ADD(_tag, TIMER, 0) \
+ downcast<timer_device &>(*device).configure_scanline(timer_device::expired_delegate(&_class::_callback, #_class "::" #_callback, nullptr, (_class *)nullptr), _screen, _first_vpos, _increment);
+#define MCFG_TIMER_DEVICE_ADD_SCANLINE(_tag, _devtag, _class, _callback, _screen, _first_vpos, _increment) \
+ MCFG_DEVICE_ADD(_tag, TIMER, 0) \
+ downcast<timer_device &>(*device).configure_scanline(timer_device::expired_delegate(&_class::_callback, #_class "::" #_callback, _devtag, (_class *)nullptr), _screen, _first_vpos, _increment);
+#define MCFG_TIMER_MODIFY(_tag) \
+ MCFG_DEVICE_MODIFY(_tag)
+
+#define MCFG_TIMER_DRIVER_CALLBACK(_class, _callback) \
+ downcast<timer_device &>(*device).set_callback(timer_device::expired_delegate(&_class::_callback, #_class "::" #_callback, nullptr, (_class *)nullptr));
+#define MCFG_TIMER_START_DELAY(_start_delay) \
+ downcast<timer_device &>(*device).set_start_delay(_start_delay);
+#define MCFG_TIMER_PARAM(_param) \
+ downcast<timer_device &>(*device).config_param(_param);
+#define MCFG_TIMER_PTR(_ptr) \
+ downcast<timer_device &>(*device).set_ptr((void *)(_ptr));
+
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -48,11 +86,6 @@ public:
configure_generic(expired_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
}
- template <class FunctionClass> void configure_generic(const char *devname, void (FunctionClass::*callback)(timer_device &, void *, s32), const char *name)
- {
- configure_generic(expired_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)));
- }
-
template <typename Object> void configure_periodic(Object &&cb, const attotime &period)
{
m_type = TIMER_TYPE_PERIODIC;
@@ -65,12 +98,6 @@ public:
configure_periodic(expired_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)), period);
}
- template <class FunctionClass> void configure_periodic(const char *devname, void (FunctionClass::*callback)(timer_device &, void *, s32),
- const char *name, const attotime &period)
- {
- configure_periodic(expired_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)), period);
- }
-
template <typename Object> void configure_scanline(Object &&cb, const char *screen, int first_vpos, int increment)
{
m_type = TIMER_TYPE_SCANLINE;
@@ -111,18 +138,13 @@ public:
// adjustments
void reset() { adjust(attotime::never, 0, attotime::never); }
- void adjust(const attotime &duration, s32 param = 0, const attotime &period = attotime::never) const
- {
- assert(m_type == TIMER_TYPE_GENERIC);
- m_timer->adjust(duration, param, period);
- }
+ void adjust(const attotime &duration, s32 param = 0, const attotime &period = attotime::never) const { assert(m_type == TIMER_TYPE_GENERIC); m_timer->adjust(duration, param, period); }
// timing information
attotime time_elapsed() const { return m_timer->elapsed(); }
attotime time_left() const { return m_timer->remaining(); }
attotime start_time() const { return m_timer->start(); }
attotime fire_time() const { return m_timer->expire(); }
- attotime period() const { return m_timer ? m_timer->period() : m_period; }
private:
// device-level overrides
@@ -141,7 +163,7 @@ private:
// configuration data
timer_type m_type; // type of timer
- expired_delegate m_callback; // the timer's callback function
+ expired_delegate m_callback; // the timer's callback function
void * m_ptr; // the pointer parameter passed to the timer callback
// periodic timers only
diff --git a/src/devices/machine/tmp68301.cpp b/src/devices/machine/tmp68301.cpp
index 1eea072c64a..2add964e4e5 100644
--- a/src/devices/machine/tmp68301.cpp
+++ b/src/devices/machine/tmp68301.cpp
@@ -23,8 +23,7 @@ DEFINE_DEVICE_TYPE(TMP68301, tmp68301_device, "tmp68301", "Toshiba TMP68301")
void tmp68301_device::tmp68301_regs(address_map &map)
{
- map(0x000, 0x3ff).rw(FUNC(tmp68301_device::regs_r), FUNC(tmp68301_device::regs_w));
-
+// AM_RANGE(0x000,0x3ff) AM_RAM
map(0x080, 0x093).rw(FUNC(tmp68301_device::icr_r), FUNC(tmp68301_device::icr_w)).umask16(0x00ff);
map(0x094, 0x095).rw(FUNC(tmp68301_device::imr_r), FUNC(tmp68301_device::imr_w));
@@ -135,7 +134,9 @@ WRITE8_MEMBER(tmp68301_device::icr_w)
}
tmp68301_device::tmp68301_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : m68000_device(mconfig, TMP68301, tag, owner, clock),
+ : device_t(mconfig, TMP68301, tag, owner, clock),
+ device_memory_interface(mconfig, *this),
+ m_cpu(*this, finder_base::DUMMY_TAG),
m_in_parallel_cb(*this),
m_out_parallel_cb(*this),
m_ipl(0),
@@ -144,7 +145,8 @@ tmp68301_device::tmp68301_device(const machine_config &mconfig, const char *tag,
m_iisr(0),
m_scr(0),
m_pdir(0),
- m_pdr(0)
+ m_pdr(0),
+ m_space_config("regs", ENDIANNESS_LITTLE, 16, 10, 0, address_map_constructor(), address_map_constructor(FUNC(tmp68301_device::tmp68301_regs), this))
{
memset(m_regs, 0, sizeof(m_regs));
memset(m_icr, 0, sizeof(m_icr));
@@ -157,17 +159,13 @@ tmp68301_device::tmp68301_device(const machine_config &mconfig, const char *tag,
void tmp68301_device::device_start()
{
- m68000_device::device_start();
-
- for (int i = 0; i < 3; i++)
+ int i;
+ for (i = 0; i < 3; i++)
m_tmp68301_timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tmp68301_device::timer_callback), this));
m_in_parallel_cb.resolve_safe(0);
m_out_parallel_cb.resolve_safe();
- m_program->install_device(0xfffc00, 0xffffff, *this, &tmp68301_device::tmp68301_regs);
- m_int_ack_callback = device_irq_acknowledge_delegate(FUNC(tmp68301_device::irq_callback), this);
-
save_item(NAME(m_regs));
save_item(NAME(m_icr));
save_item(NAME(m_ipl));
@@ -185,8 +183,6 @@ void tmp68301_device::device_start()
void tmp68301_device::device_reset()
{
- m68000_device::device_reset();
-
m_ipr = 0;
m_iisr = 0;
m_imr = 0x7f7; // mask all irqs
@@ -194,10 +190,40 @@ void tmp68301_device::device_reset()
update_ipl();
}
+//-------------------------------------------------
+// memory_space_config - return a description of
+// any address spaces owned by this device
+//-------------------------------------------------
+
+device_memory_interface::space_config_vector tmp68301_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
//**************************************************************************
// INLINE HELPERS
//**************************************************************************
+//-------------------------------------------------
+// read_byte - read a byte at the given address
+//-------------------------------------------------
+
+inline uint16_t tmp68301_device::read_word(offs_t address)
+{
+ return space(0).read_word(address << 1);
+}
+
+//-------------------------------------------------
+// write_byte - write a byte at the given address
+//-------------------------------------------------
+
+inline void tmp68301_device::write_word(offs_t address, uint16_t data)
+{
+ space(0).write_word(address << 1, data);
+}
+
IRQ_CALLBACK_MEMBER(tmp68301_device::irq_callback)
{
uint8_t IVNR = m_regs[0x9a/2] & 0xe0; // Interrupt Vector Number Register (IVNR)
@@ -286,7 +312,7 @@ void tmp68301_device::update_timer(int i)
{
int scale = (TCR & 0x3c00)>>10; // P4..1
if (scale > 8) scale = 8;
- duration = attotime::from_hz(unscaled_clock()) * ((1 << scale) * max);
+ duration = attotime::from_hz(m_cpu->unscaled_clock()) * ((1 << scale) * max);
}
break;
}
@@ -317,9 +343,9 @@ void tmp68301_device::update_ipl()
if (new_ipl != m_ipl)
{
if (m_ipl != 0)
- set_input_line(m_ipl, CLEAR_LINE);
+ m_cpu->set_input_line(m_ipl, CLEAR_LINE);
if (new_ipl != 0)
- set_input_line(new_ipl, ASSERT_LINE);
+ m_cpu->set_input_line(new_ipl, ASSERT_LINE);
m_ipl = new_ipl;
}
@@ -340,16 +366,18 @@ uint8_t tmp68301_device::serial_interrupt_cause(int channel)
READ16_MEMBER( tmp68301_device::regs_r )
{
- return m_regs[offset];
+ return read_word(offset);
}
WRITE16_MEMBER( tmp68301_device::regs_w )
{
COMBINE_DATA(&m_regs[offset]);
+ write_word(offset,m_regs[offset]);
+
if (!ACCESSING_BITS_0_7) return;
-// logerror("CPU #0 PC %06X: TMP68301 Reg %04X<-%04X & %04X\n", >pc(),offset*2,data,mem_mask^0xffff);
+// logerror("CPU #0 PC %06X: TMP68301 Reg %04X<-%04X & %04X\n", m_cpu->pc(),offset*2,data,mem_mask^0xffff);
switch( offset * 2 )
{
diff --git a/src/devices/machine/tmp68301.h b/src/devices/machine/tmp68301.h
index c350b9b0be6..e019387802b 100644
--- a/src/devices/machine/tmp68301.h
+++ b/src/devices/machine/tmp68301.h
@@ -16,19 +16,27 @@
-class tmp68301_device : public m68000_device
+class tmp68301_device : public device_t,
+ public device_memory_interface
{
public:
tmp68301_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ template <typename T> void set_cputag(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); } // FIXME: M68000 ought to be a parent class, not an external object
auto in_parallel_callback() { return m_in_parallel_cb.bind(); }
auto out_parallel_callback() { return m_out_parallel_cb.bind(); }
+ // Hardware Registers
+ DECLARE_READ16_MEMBER( regs_r );
+ DECLARE_WRITE16_MEMBER( regs_w );
+
// Interrupts
void external_interrupt_0();
void external_interrupt_1();
void external_interrupt_2();
+ IRQ_CALLBACK_MEMBER(irq_callback);
+
private:
DECLARE_READ16_MEMBER(imr_r);
DECLARE_WRITE16_MEMBER(imr_w);
@@ -45,18 +53,13 @@ private:
DECLARE_READ8_MEMBER(icr_r);
DECLARE_WRITE8_MEMBER(icr_w);
- // Hardware Registers
- DECLARE_READ16_MEMBER( regs_r );
- DECLARE_WRITE16_MEMBER( regs_w );
-
void tmp68301_regs(address_map &map);
- IRQ_CALLBACK_MEMBER(irq_callback);
-
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
+ virtual space_config_vector memory_space_config() const override;
private:
TIMER_CALLBACK_MEMBER(timer_callback);
@@ -75,6 +78,11 @@ private:
static constexpr uint16_t TIMER1_IRQ = 1 << 9;
static constexpr uint16_t TIMER2_IRQ = 1 << 10;
+ inline uint16_t read_word(offs_t address);
+ inline void write_word(offs_t address, uint16_t data);
+
+ required_device<m68000_base_device> m_cpu;
+
devcb_read16 m_in_parallel_cb;
devcb_write16 m_out_parallel_cb;
@@ -92,6 +100,8 @@ private:
uint16_t m_pdir;
uint16_t m_pdr;
uint8_t m_icr[10];
+
+ const address_space_config m_space_config;
};
DECLARE_DEVICE_TYPE(TMP68301, tmp68301_device)
diff --git a/src/devices/machine/tms5501.cpp b/src/devices/machine/tms5501.cpp
index d067497567a..f7581a30a72 100644
--- a/src/devices/machine/tms5501.cpp
+++ b/src/devices/machine/tms5501.cpp
@@ -263,9 +263,6 @@ READ8_MEMBER( tms5501_device::rst_r )
READ8_MEMBER( tms5501_device::sta_r )
{
- if(is_transmit_register_empty())
- m_sta |= STA_XBE;
-
uint8_t data = m_sta;
m_sta &= ~STA_OE;
diff --git a/src/devices/machine/tms9901.cpp b/src/devices/machine/tms9901.cpp
index 4e7341feb61..5282dd6f9f5 100644
--- a/src/devices/machine/tms9901.cpp
+++ b/src/devices/machine/tms9901.cpp
@@ -53,16 +53,6 @@ Pins:
(This is mostly obvious, but it implies that you cannot trigger an
interrupt by setting the output state of a pin, which is not SO obvious.)
-Clock mode:
- The "clock mode" is entered by setting bit 0 to 1. This means that the
- clock register becomes accessible to changes and inspection. The clock
- itself runs in the interrupt mode. Accordingly, the typical setup
- involves first setting bit 0 to 1, then loading some or all of the
- clock register bits, and then switching to interrupt mode again. From then
- on, INT3 is asserted whenever the clock reaches 0, and is cleared by
- writing 0 or 1 to bit 3. The clock can only be stopped by setting the
- register to 0 or by a reset.
-
Interrupt handling:
After each clock cycle, TMS9901 latches the state of INT1*-INT15* (except
pins which are set as output pins). If the clock is enabled, it replaces
@@ -115,9 +105,6 @@ MZ: According to the description in
MZ: Turned to class (January 2012)
-MZ: Added a synchronous clock input (Phi line) as an alternative to the
- emu_timer.
-
TODO: Tests on a real machine
- Set an interrupt input (e.g. keyboard for Geneve), trigger RST2*, check whether
interrupt mask has been reset
@@ -137,23 +124,24 @@ TODO: Tests on a real machine
#include <math.h>
-#define LOG_GENERAL (1U << 0)
-#define LOG_PINS (1U << 1)
-#define LOG_CONFIG (1U << 2)
-#define LOG_MODE (1U << 3)
-#define LOG_INT (1U << 4)
-#define LOG_DECVALUE (1U << 5)
+#define LOG_GENERAL (1U << 0)
+#define LOG_PINS (1U << 1)
+#define LOG_CLOCK (1U << 2)
+#define LOG_MODE (1U << 3)
-#define VERBOSE ( 0 )
+//#define VERBOSE (LOG_PINS | LOG_CLOCK | LOG_MODE)
#include "logmacro.h"
+#define LOGPINS(...) LOGMASKED(LOG_PINS, __VA_ARGS__)
+#define LOGCLOCK(...) LOGMASKED(LOG_CLOCK, __VA_ARGS__)
+#define LOGMODE(...) LOGMASKED(LOG_MODE, __VA_ARGS__)
+
+
/*
Constructor
*/
tms9901_device::tms9901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, TMS9901, tag, owner, clock),
- m_clock_active(false),
- m_clockdiv(0),
m_read_block(*this),
m_write_p{{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this},{*this}},
m_interrupt(*this)
@@ -174,12 +162,12 @@ void tms9901_device::field_interrupts()
// if timer is enabled, INT3 pin is overridden by timer
if (m_timer_int_pending)
{
- LOGMASKED(LOG_INT, "INT3 (timer) asserted\n");
+ LOGCLOCK("timer fires\n");
current_ints |= INT3;
}
else
{
- LOGMASKED(LOG_INT, "INT3 (timer) cleared\n");
+ LOGCLOCK("timer clear\n");
current_ints &= ~INT3;
}
}
@@ -209,7 +197,6 @@ void tms9901_device::field_interrupts()
current_ints >>= 1; /* try next bit */
level++;
}
- LOGMASKED(LOG_INT, "Triggering interrupt, level %d\n", level);
m_int_pending = true;
if (!m_interrupt.isnull())
m_interrupt(level, 1, 0xff); // the offset carries the IC0-3 level
@@ -250,11 +237,11 @@ void tms9901_device::timer_reload()
if (m_clock_register != 0)
{ /* reset clock interval */
m_decrementer_value = m_clock_register;
- m_clock_active = true;
+ m_decrementer->enable(true);
}
else
{ /* clock interval == 0 -> no timer */
- m_clock_active = false;
+ m_decrementer->enable(false);
}
}
@@ -275,13 +262,13 @@ void tms9901_device::timer_reload()
bit 16-31: current status of the P0-P15 pins (quits timer mode, too...)
*/
-uint8_t tms9901_device::read(offs_t offset)
+READ8_MEMBER( tms9901_device::read )
{
int answer = 0;
- offset &= 0x01f;
+ offset &= 0x003;
- switch (offset >> 3)
+ switch (offset)
{
case 0:
if (m_clock_mode)
@@ -304,7 +291,7 @@ uint8_t tms9901_device::read(offs_t offset)
// Set those bits here
answer |= (m_pio_output_mirror & m_pio_direction_mirror) & 0xFF;
}
- LOGMASKED(LOG_PINS, "Input on lines INT7..CB = %02x\n", answer);
+ LOGPINS("input on lines INT7..CB = %02x\n", answer);
break;
case 1:
if (m_clock_mode)
@@ -324,7 +311,7 @@ uint8_t tms9901_device::read(offs_t offset)
answer &= ~(m_pio_direction_mirror >> 8);
answer |= (m_pio_output_mirror & m_pio_direction_mirror) >> 8;
}
- LOGMASKED(LOG_PINS, "Input on lines INT15..INT8 = %02x\n", answer);
+ LOGPINS("input on lines INT15..INT8 = %02x\n", answer);
break;
case 2:
/* exit timer mode */
@@ -338,7 +325,7 @@ uint8_t tms9901_device::read(offs_t offset)
answer &= ~m_pio_direction;
answer |= (m_pio_output & m_pio_direction) & 0xFF;
- LOGMASKED(LOG_PINS, "Input on lines P7..P0 = %02x\n", answer);
+ LOGPINS("input on lines P7..P0 = %02x\n", answer);
break;
case 3:
@@ -351,12 +338,12 @@ uint8_t tms9901_device::read(offs_t offset)
answer &= ~(m_pio_direction >> 8);
answer |= (m_pio_output & m_pio_direction) >> 8;
- LOGMASKED(LOG_PINS, "Input on lines P15..P8 = %02x\n", answer);
+ LOGPINS("input on lines P15..P8 = %02x\n", answer);
break;
}
- return BIT(answer, offset & 7);
+ return answer;
}
/*
@@ -372,7 +359,7 @@ uint8_t tms9901_device::read(offs_t offset)
bit 16-31: set output state of P0-P15 (and set them as output pin) (quit timer mode, too...)
*/
-void tms9901_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER ( tms9901_device::write )
{
data &= 1; /* clear extra bits */
offset &= 0x01F;
@@ -380,7 +367,7 @@ void tms9901_device::write(offs_t offset, uint8_t data)
if (offset >= 0x10)
{
int pin = offset & 0x0F;
- LOGMASKED(LOG_PINS, "Output on P%d = %d\n", pin, data);
+ LOGPINS("output on P%d = %d\n", pin, data);
int bit = (1 << pin);
@@ -421,20 +408,18 @@ void tms9901_device::write(offs_t offset, uint8_t data)
{
// Switch to interrupt mode; quit clock mode
m_clock_mode = false;
- LOGMASKED(LOG_MODE, "Enter interrupt mode\n");
+ LOGMODE("int mode\n");
}
else
{
m_clock_mode = true;
- LOGMASKED(LOG_MODE, "Enter clock mode\n");
+ LOGMODE("clock mode\n");
// we are switching to clock mode: latch the current value of
// the decrementer register
if (m_clock_register != 0)
m_clock_read_register = m_decrementer_value;
else
m_clock_read_register = 0; /* timer inactive... */
-
- LOGMASKED(LOG_CONFIG, "Clock setting = %d\n", m_clock_read_register);
}
}
else if (offset == 0x0f)
@@ -452,7 +437,7 @@ void tms9901_device::write(offs_t offset, uint8_t data)
// Spec is not clear on whether the mask bits are also reset by RST2*
// TODO: Check on a real machine. (I'd guess from the text they are not touched)
m_enabled_ints = 0;
- LOGMASKED(LOG_MODE, "Soft reset (RST2*)\n");
+ LOGMODE("Soft reset (RST2*)\n");
}
}
else
@@ -462,7 +447,7 @@ void tms9901_device::write(offs_t offset, uint8_t data)
else
m_enabled_ints &= ~0x4000; /* unset bit */
- LOGMASKED(LOG_CONFIG, "Enabled interrupts = %04x\n", m_enabled_ints);
+ LOGMODE("interrupts = %04x\n", m_enabled_ints);
field_interrupts(); /* changed interrupt state */
}
}
@@ -484,7 +469,7 @@ void tms9901_device::write(offs_t offset, uint8_t data)
m_clock_register &= ~bit; /* clear bit */
/* reset clock timer (page 8) */
- LOGMASKED(LOG_CONFIG, "Clock register = %04x\n", m_clock_register);
+ LOGCLOCK("clock register = %04x\n", m_clock_register);
timer_reload();
}
else
@@ -499,7 +484,7 @@ void tms9901_device::write(offs_t offset, uint8_t data)
if (offset == 3)
m_timer_int_pending = false; /* SBO 3 clears pending timer interrupt (??) */
- LOGMASKED(LOG_CONFIG, "Enabled interrupts = %04x\n", m_enabled_ints);
+ LOGMODE("enabled interrupts = %04x\n");
field_interrupts(); /* changed interrupt state */
}
}
@@ -515,20 +500,10 @@ void tms9901_device::device_timer(emu_timer &timer, device_timer_id id, int para
{
if (id==DECREMENTER) // we have only that one
{
- clock_in(ASSERT_LINE);
- clock_in(CLEAR_LINE);
- }
-}
-
-void tms9901_device::clock_in(line_state clk)
-{
- if (m_clock_active && clk == ASSERT_LINE)
- {
m_decrementer_value--;
- LOGMASKED(LOG_DECVALUE, "Decrementer = %d\n", m_decrementer_value);
+ LOGCLOCK("decrementer = %d\n", m_decrementer_value);
if (m_decrementer_value<=0)
{
- LOGMASKED(LOG_INT, "Timer expired\n");
m_timer_int_pending = true; // decrementer interrupt requested
field_interrupts();
m_decrementer_value = m_clock_register;
@@ -536,21 +511,6 @@ void tms9901_device::clock_in(line_state clk)
}
}
-/*
- Synchronous clock input. This may be used for systems which have
- a CLK line controlled by the CPU, like the TMS99xx systems.
- In that case, clock is set to 0.
-*/
-WRITE_LINE_MEMBER( tms9901_device::phi_line )
-{
- // Divider by 64
- if (state==ASSERT_LINE)
- m_clockdiv = (m_clockdiv+1) % 0x40;
-
- if (m_clockdiv==0)
- clock_in((line_state)state);
-}
-
/*-------------------------------------------------
device_stop - device-specific stop
-------------------------------------------------*/
@@ -605,12 +565,9 @@ void tms9901_device::do_reset()
void tms9901_device::device_start()
{
- // Allow for using asynchronous and synchronous clocks
- if (clock() != 0)
- {
- m_decrementer = timer_alloc(DECREMENTER);
- m_decrementer->adjust(attotime::from_hz(clock() / 64.), 0, attotime::from_hz(clock() / 64.));
- }
+ m_decrementer = timer_alloc(DECREMENTER);
+ m_decrementer->adjust(attotime::from_hz(clock() / 64.), 0, attotime::from_hz(clock() / 64.));
+ m_decrementer->enable(false);
m_read_block.resolve();
for (auto &cb : m_write_p)
diff --git a/src/devices/machine/tms9901.h b/src/devices/machine/tms9901.h
index eda01f253ad..86a2c6852e3 100644
--- a/src/devices/machine/tms9901.h
+++ b/src/devices/machine/tms9901.h
@@ -60,11 +60,8 @@ public:
DECLARE_WRITE_LINE_MEMBER( rst1_line );
- // Synchronous clock input
- DECLARE_WRITE_LINE_MEMBER( phi_line );
-
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
auto p_out_cb(int n) { return m_write_p[n].bind(); }
auto read_cb() { return m_read_block.bind(); }
@@ -86,9 +83,6 @@ private:
// Common method for device_reset and rst1_line
void do_reset();
- // Common clock handling
- void clock_in(line_state clk);
-
// State of the INT1-INT15 lines (must be inverted when queried)
// Note that the levels must also be delivered when reading the pins, which
// may require to latch the int levels.
@@ -99,9 +93,6 @@ private:
bool m_int_pending; // status of the int* pin (connected to TMS9900)
bool m_timer_int_pending; // timer int pending (overrides int3 pin if timer enabled)
- bool m_clock_active;
- int m_clockdiv; // Clock divider counter (for synchronous clock)
-
// PIO registers
int m_pio_direction; // direction register for PIO
@@ -119,7 +110,7 @@ private:
// true = clock mode (read/write clock interval)
bool m_clock_mode;
- // Timer, used to emulate the decrementer register
+ // MESS timer, used to emulate the decrementer register
emu_timer *m_decrementer;
// clock interval, loaded in decrementer when it reaches 0.
diff --git a/src/devices/machine/tms9902.cpp b/src/devices/machine/tms9902.cpp
index 813372f6f22..93e48cf03a2 100644
--- a/src/devices/machine/tms9902.cpp
+++ b/src/devices/machine/tms9902.cpp
@@ -478,109 +478,48 @@ void tms9902_device::initiate_transmit()
bit 13-15: not emulated, normally used for diagnostics
bit 16: RBINT (RBRL&RIENB)
*/
-uint8_t tms9902_device::cruread(offs_t offset)
+READ8_MEMBER( tms9902_device::cruread )
{
uint8_t answer = 0;
- switch (offset & 31)
- {
- case 31:
- answer = m_INT;
- break;
-
- case 30:
- answer = (m_LDCTRL || m_LDIR || m_LRDR || m_LXDR || m_BRKON);
- break;
-
- case 29:
- answer = m_DSCH;
- break;
-
- case 28:
- answer = m_CTSin;
- break;
-
- case 27:
- answer = m_DSRin;
- break;
-
- case 26:
- answer = m_RTSout;
- break;
-
- case 25:
- answer = m_TIMELP;
- break;
-
- case 24:
- answer = m_TIMERR;
- break;
-
- case 23:
- answer = m_XSRE;
- break;
-
- case 22:
- answer = m_XBRE;
- break;
+ offset &= 0x0003;
- case 21:
- answer = m_RBRL;
- break;
-
- case 20:
- answer = (m_DSCH && m_DSCENB);
- break;
-
- case 19:
- answer = (m_TIMELP && m_TIMENB);
- break;
-
- case 17:
- answer = (m_XBRE && m_XBIENB);
- break;
-
- case 16:
- answer = (m_RBRL && m_RIENB);
- break;
-
- case 15:
- answer = m_RIN;
- break;
-
- case 14:
- answer = m_RSBD;
- break;
-
- case 13:
- answer = m_RFBD;
- break;
-
- case 12:
- answer = m_RFER;
- break;
-
- case 11:
- answer = m_ROVER;
+ switch (offset)
+ {
+ case 3: // Bits 31-24
+ if (m_INT) answer |= 0x80;
+ if (m_LDCTRL || m_LDIR || m_LRDR || m_LXDR || m_BRKON) answer |= 0x40;
+ if (m_DSCH) answer |= 0x20;
+ if (m_CTSin) answer |= 0x10;
+ if (m_DSRin) answer |= 0x08;
+ if (m_RTSout) answer |= 0x04;
+ if (m_TIMELP) answer |= 0x02;
+ if (m_TIMERR) answer |= 0x01;
break;
- case 10:
- answer = m_RPER;
+ case 2: // Bits 23-16
+ if (m_XSRE) answer |= 0x80;
+ if (m_XBRE) answer |= 0x40;
+ if (m_RBRL) answer |= 0x20;
+ if (m_DSCH && m_DSCENB) answer |= 0x10;
+ if (m_TIMELP && m_TIMENB) answer |= 0x08;
+ if (m_XBRE && m_XBIENB) answer |= 0x02;
+ if (m_RBRL && m_RIENB) answer |= 0x01;
break;
- case 9:
- answer = (m_RPER || m_RFER || m_ROVER);
+ case 1: // Bits 15-8
+ if (m_RIN) answer |= 0x80;
+ if (m_RSBD) answer |= 0x40;
+ if (m_RFBD) answer |= 0x20;
+ if (m_RFER) answer |= 0x10;
+ if (m_ROVER) answer |= 0x08;
+ if (m_RPER) answer |= 0x04;
+ if (m_RPER || m_RFER || m_ROVER) answer |= 0x02;
break;
- case 7:
- case 6:
- case 5:
- case 4:
- case 3:
- case 2:
- case 1:
- case 0:
- answer = BIT(m_RBR, offset & 31);
+ case 0: // Bits 7-0
+ LOGCRU("Reading received byte = %02x\n", m_RBR);
+ answer = m_RBR;
break;
}
if (VERBOSE & LOG_DETAIL) LOGCRU("Reading flag bits %d - %d = %02x\n", ((offset+1)*8-1), offset*8, answer);
@@ -658,7 +597,7 @@ void tms9902_device::reset_uart()
/*
TMS9902 CRU write
*/
-void tms9902_device::cruwrite(offs_t offset, uint8_t data)
+WRITE8_MEMBER( tms9902_device::cruwrite )
{
data &= 1; /* clear extra bits */
diff --git a/src/devices/machine/tms9902.h b/src/devices/machine/tms9902.h
index 3d203c59709..1f96e2ffc17 100644
--- a/src/devices/machine/tms9902.h
+++ b/src/devices/machine/tms9902.h
@@ -69,8 +69,8 @@ public:
int get_config_value();
- uint8_t cruread(offs_t offset);
- void cruwrite(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( cruread );
+ DECLARE_WRITE8_MEMBER( cruwrite );
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
diff --git a/src/devices/machine/tms9914.cpp b/src/devices/machine/tms9914.cpp
index eef06895493..00fedd5db0c 100644
--- a/src/devices/machine/tms9914.cpp
+++ b/src/devices/machine/tms9914.cpp
@@ -241,7 +241,7 @@ WRITE_LINE_MEMBER(tms9914_device::ren_w)
}
// Register I/O
-void tms9914_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(tms9914_device::reg8_w)
{
LOG_REG("W %u=%02x\n" , offset , data);
@@ -323,7 +323,7 @@ void tms9914_device::write(offs_t offset, uint8_t data)
}
}
-uint8_t tms9914_device::read(offs_t offset)
+READ8_MEMBER(tms9914_device::reg8_r)
{
uint8_t res;
diff --git a/src/devices/machine/tms9914.h b/src/devices/machine/tms9914.h
index 9fda5aa2ebb..14df9d80647 100644
--- a/src/devices/machine/tms9914.h
+++ b/src/devices/machine/tms9914.h
@@ -83,9 +83,8 @@ public:
DECLARE_WRITE_LINE_MEMBER(atn_w);
DECLARE_WRITE_LINE_MEMBER(ren_w);
- // Register access
- void write(offs_t offset, uint8_t data);
- uint8_t read(offs_t offset);
+ DECLARE_WRITE8_MEMBER(reg8_w);
+ DECLARE_READ8_MEMBER(reg8_r);
// CONT output: true when 9914 is current controller-in-charge
DECLARE_READ_LINE_MEMBER(cont_r);
diff --git a/src/devices/machine/tube.cpp b/src/devices/machine/tube.cpp
index a53c05ac38c..aac084a3158 100644
--- a/src/devices/machine/tube.cpp
+++ b/src/devices/machine/tube.cpp
@@ -79,7 +79,7 @@ void tube_device::update_interrupts()
m_drq_handler(!BIT(m_r1stat, 4) && ((m_hp3pos > BIT(m_r1stat, 4)) || (m_ph3pos == 0)) ? ASSERT_LINE : CLEAR_LINE);
}
-uint8_t tube_device::host_r(offs_t offset)
+READ8_MEMBER(tube_device::host_r)
{
uint8_t data = 0xfe;
@@ -143,7 +143,7 @@ uint8_t tube_device::host_r(offs_t offset)
return data;
}
-void tube_device::host_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER(tube_device::host_w)
{
switch (offset & 0x07)
{
@@ -197,7 +197,7 @@ void tube_device::host_w(offs_t offset, uint8_t data)
update_interrupts();
}
-uint8_t tube_device::parasite_r(offs_t offset)
+READ8_MEMBER(tube_device::parasite_r)
{
uint8_t data = 0x00;
@@ -265,7 +265,7 @@ uint8_t tube_device::parasite_r(offs_t offset)
return data;
}
-void tube_device::parasite_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER(tube_device::parasite_w)
{
switch (offset & 0x07)
{
diff --git a/src/devices/machine/tube.h b/src/devices/machine/tube.h
index 384cf29b8d9..c8d94b1c7a7 100644
--- a/src/devices/machine/tube.h
+++ b/src/devices/machine/tube.h
@@ -32,10 +32,10 @@ public:
auto pirq_handler() { return m_pirq_handler.bind(); }
auto drq_handler() { return m_drq_handler.bind(); }
- uint8_t host_r(offs_t offset);
- void host_w(offs_t offset, uint8_t data);
- uint8_t parasite_r(offs_t offset);
- void parasite_w(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(host_r);
+ DECLARE_WRITE8_MEMBER(host_w);
+ DECLARE_READ8_MEMBER(parasite_r);
+ DECLARE_WRITE8_MEMBER(parasite_w);
protected:
// device-level overrides
diff --git a/src/devices/machine/upd7002.cpp b/src/devices/machine/upd7002.cpp
index b00d44066e5..69b9bb262ee 100644
--- a/src/devices/machine/upd7002.cpp
+++ b/src/devices/machine/upd7002.cpp
@@ -59,7 +59,7 @@ void upd7002_device::device_reset()
*****************************************************************************/
-READ_LINE_MEMBER( upd7002_device::eoc_r )
+READ8_MEMBER( upd7002_device::eoc_r )
{
return (m_status>>7)&0x01;
}
@@ -94,7 +94,7 @@ void upd7002_device::device_timer(emu_timer &timer, device_timer_id id, int para
}
-uint8_t upd7002_device::read(offs_t offset)
+READ8_MEMBER( upd7002_device::read )
{
switch(offset&0x03)
{
@@ -112,7 +112,7 @@ uint8_t upd7002_device::read(offs_t offset)
-void upd7002_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER( upd7002_device::write )
{
/* logerror("write to uPD7002 $%02X = $%02X\n",offset,data); */
diff --git a/src/devices/machine/upd7002.h b/src/devices/machine/upd7002.h
index 2a68774d435..5b62d13dc34 100644
--- a/src/devices/machine/upd7002.h
+++ b/src/devices/machine/upd7002.h
@@ -30,9 +30,9 @@ public:
template <typename... T> void set_get_analogue_callback(T &&... args) { m_get_analogue_cb = get_analogue_delegate(std::forward<T>(args)...); }
template <typename... T> void set_eoc_callback(T &&... args) { m_eoc_cb = eoc_delegate(std::forward<T>(args)...); }
- DECLARE_READ_LINE_MEMBER(eoc_r);
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(eoc_r);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
protected:
// device-level overrides
diff --git a/src/devices/machine/upd765.cpp b/src/devices/machine/upd765.cpp
index 64b844dd222..bfbf277449b 100644
--- a/src/devices/machine/upd765.cpp
+++ b/src/devices/machine/upd765.cpp
@@ -18,7 +18,6 @@
#define LOG_MATCH (1U << 10) // Sector matching
#define LOG_STATE (1U << 11) // State machine
#define LOG_LIVE (1U << 12) // Live states
-#define LOG_DONE (1U << 13) // Command done
#define VERBOSE (LOG_GENERAL | LOG_WARN )
@@ -39,7 +38,6 @@
#define LOGMATCH(...) LOGMASKED(LOG_MATCH, __VA_ARGS__)
#define LOGSTATE(...) LOGMASKED(LOG_STATE, __VA_ARGS__)
#define LOGLIVE(...) LOGMASKED(LOG_LIVE, __VA_ARGS__)
-#define LOGDONE(...) LOGMASKED(LOG_DONE, __VA_ARGS__)
DEFINE_DEVICE_TYPE(UPD765A, upd765a_device, "upd765a", "NEC uPD765A FDC")
DEFINE_DEVICE_TYPE(UPD765B, upd765b_device, "upd765b", "NEC uPD765B FDC")
@@ -168,9 +166,7 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device
pc_fdc_interface(mconfig, type, tag, owner, clock),
intrq_cb(*this),
drq_cb(*this),
- hdl_cb(*this),
- idx_cb(*this),
- us_cb(*this)
+ hdl_cb(*this)
{
ready_polled = true;
ready_connected = true;
@@ -195,20 +191,15 @@ void upd765_family_device::set_mode(int _mode)
mode = _mode;
}
-void upd765_family_device::device_resolve_objects()
-{
- intrq_cb.resolve_safe();
- drq_cb.resolve_safe();
- hdl_cb.resolve_safe();
- idx_cb.resolve_safe();
- us_cb.resolve_safe();
-}
-
void upd765_family_device::device_start()
{
save_item(NAME(motorcfg));
save_item(NAME(selected_drive));
+ intrq_cb.resolve_safe();
+ drq_cb.resolve_safe();
+ hdl_cb.resolve_safe();
+
for(int i=0; i != 4; i++) {
char name[2];
flopi[i].tm = timer_alloc(i);
@@ -336,7 +327,6 @@ void upd765_family_device::set_ds(int fid)
for(floppy_info &fi : flopi)
if(fi.dev)
fi.dev->ds_w(fid);
- us_cb(fid);
// record selected drive
selected_drive = fid;
@@ -351,11 +341,9 @@ void upd765_family_device::set_floppy(floppy_image_device *flop)
}
if(flop)
flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&upd765_family_device::index_callback, this));
- else
- idx_cb(0);
}
-uint8_t upd765_family_device::sra_r()
+READ8_MEMBER(upd765_family_device::sra_r)
{
uint8_t sra = 0;
int fid = dor & 3;
@@ -378,17 +366,17 @@ uint8_t upd765_family_device::sra_r()
return sra;
}
-uint8_t upd765_family_device::srb_r()
+READ8_MEMBER(upd765_family_device::srb_r)
{
return 0;
}
-uint8_t upd765_family_device::dor_r()
+READ8_MEMBER(upd765_family_device::dor_r)
{
return dor;
}
-void upd765_family_device::dor_w(uint8_t data)
+WRITE8_MEMBER(upd765_family_device::dor_w)
{
LOGREGS("dor = %02x\n", data);
uint8_t diff = dor ^ data;
@@ -404,16 +392,21 @@ void upd765_family_device::dor_w(uint8_t data)
check_irq();
}
-uint8_t upd765_family_device::tdr_r()
+READ8_MEMBER(upd765_family_device::tdr_r)
{
return 0;
}
-void upd765_family_device::tdr_w(uint8_t data)
+WRITE8_MEMBER(upd765_family_device::tdr_w)
+{
+}
+
+READ8_MEMBER(upd765_family_device::msr_r)
{
+ return read_msr();
}
-uint8_t upd765_family_device::msr_r()
+uint8_t upd765_family_device::read_msr()
{
uint32_t msr = 0;
switch(main_phase) {
@@ -444,7 +437,7 @@ uint8_t upd765_family_device::msr_r()
}
msr |= get_drive_busy();
- if(data_irq && !machine().side_effects_disabled()) {
+ if(data_irq) {
data_irq = false;
check_irq();
}
@@ -452,7 +445,7 @@ uint8_t upd765_family_device::msr_r()
return msr;
}
-void upd765_family_device::dsr_w(uint8_t data)
+WRITE8_MEMBER(upd765_family_device::dsr_w)
{
LOGREGS("dsr_w %02x (%s)\n", data, machine().describe_context());
if(data & 0x80)
@@ -466,43 +459,39 @@ void upd765_family_device::set_rate(int rate)
cur_rate = rate;
}
-uint8_t upd765_family_device::fifo_r()
+uint8_t upd765_family_device::read_fifo()
{
uint8_t r = 0xff;
switch(main_phase) {
case PHASE_EXEC:
- if(machine().side_effects_disabled())
- return fifo[0];
if(internal_drq)
return fifo_pop(false);
- LOGFIFO("fifo_r in phase %d\n", main_phase);
+ LOGFIFO("read_fifo in phase %d\n", main_phase);
break;
case PHASE_RESULT:
r = result[0];
- if(!machine().side_effects_disabled()) {
- result_pos--;
- memmove(result, result+1, result_pos);
- if(!result_pos)
- main_phase = PHASE_CMD;
- else if(result_pos == 1) {
- // clear drive busy bit after the first sense interrupt status result byte is read
- for(floppy_info &fi : flopi)
- if((fi.main_state == RECALIBRATE || fi.main_state == SEEK) && fi.sub_state == IDLE && fi.st0_filled == false)
- fi.main_state = IDLE;
- clr_drive_busy();
- }
+ result_pos--;
+ memmove(result, result+1, result_pos);
+ if(!result_pos)
+ main_phase = PHASE_CMD;
+ else if(result_pos == 1) {
+ // clear drive busy bit after the first sense interrupt status result byte is read
+ for(floppy_info &fi : flopi)
+ if((fi.main_state == RECALIBRATE || fi.main_state == SEEK) && fi.sub_state == IDLE && fi.st0_filled == false)
+ fi.main_state = IDLE;
+ clr_drive_busy();
}
break;
default:
- LOGFIFO("fifo_r in phase %d\n", main_phase);
+ LOGFIFO("read_fifo in phase %d\n", main_phase);
break;
}
return r;
}
-void upd765_family_device::fifo_w(uint8_t data)
+void upd765_family_device::write_fifo(uint8_t data)
{
switch(main_phase) {
case PHASE_CMD: {
@@ -528,11 +517,11 @@ void upd765_family_device::fifo_w(uint8_t data)
fifo_push(data, false);
return;
}
- LOGFIFO("fifo_w in phase %d\n", main_phase);
+ LOGFIFO("write_fifo in phase %d\n", main_phase);
break;
default:
- LOGFIFO("fifo_w in phase %d\n", main_phase);
+ LOGFIFO("write_fifo in phase %d\n", main_phase);
break;
}
}
@@ -545,7 +534,12 @@ uint8_t upd765_family_device::do_dir_r()
return 0x00;
}
-void upd765_family_device::ccr_w(uint8_t data)
+READ8_MEMBER(upd765_family_device::dir_r)
+{
+ return do_dir_r();
+}
+
+WRITE8_MEMBER(upd765_family_device::ccr_w)
{
dsr = (dsr & 0xfc) | (data & 3);
cur_rate = rates[data & 3];
@@ -647,10 +641,18 @@ void upd765_family_device::fifo_expect(int size, bool write)
enable_transfer();
}
+READ8_MEMBER(upd765_family_device::mdma_r)
+{
+ return dma_r();
+}
+
+WRITE8_MEMBER(upd765_family_device::mdma_w)
+{
+ dma_w(data);
+}
+
uint8_t upd765_family_device::dma_r()
{
- if(machine().side_effects_disabled())
- return fifo[0];
return fifo_pop(false);
}
@@ -1472,7 +1474,7 @@ void upd765_family_device::execute_command(int cmd)
void upd765_family_device::command_end(floppy_info &fi, bool data_completion)
{
- LOGDONE("command done (%s) - %s\n", data_completion ? "data" : "seek", results());
+ LOGCOMMAND("command done (%s) - %s\n", data_completion ? "data" : "seek", results());
fi.main_state = fi.sub_state = IDLE;
if(data_completion)
data_irq = true;
@@ -1744,16 +1746,7 @@ void upd765_family_device::read_data_continue(floppy_info &fi)
fi.sub_state = COMMAND_DONE;
break;
}
- // MZ: This st1 handling ensures that both HX5102 floppy and the
- // Speedlock protection scheme are properly working.
- // a) HX5102 requires that the ND flag not be set when no address
- // marks could be found on the track at all (particularly due to
- // wrong density)
- // b) Speedlock requires the ND flag be set when there are valid
- // sectors on the track, but the desired sector is missing, also
- // when it has no valid address marks
st1 &= ~ST1_MA;
- st1 |= ST1_ND;
if(!sector_matches()) {
if(cur_live.idbuf[0] != command[2]) {
if(cur_live.idbuf[0] == 0xff)
@@ -1765,7 +1758,6 @@ void upd765_family_device::read_data_continue(floppy_info &fi)
live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
return;
}
- st1 &= ~ST1_ND;
LOGRW("reading sector %02x %02x %02x %02x\n",
cur_live.idbuf[0],
cur_live.idbuf[1],
@@ -1784,6 +1776,11 @@ void upd765_family_device::read_data_continue(floppy_info &fi)
case SCAN_ID_FAILED:
LOGSTATE("SCAN_ID_FAILED\n");
fi.st0 |= ST0_FAIL;
+ // MZ: The HX5102 does not correctly detect a FM/MFM mismatch
+ // when the ND bit is set, because in the firmware the ND bit wins
+ // against MA, and thus concludes that the format is correct
+ // but the sector is missing.
+ // st1 |= ST1_ND;
fi.sub_state = COMMAND_DONE;
break;
@@ -1855,7 +1852,7 @@ void upd765_family_device::write_data_start(floppy_info &fi)
fi.main_state = WRITE_DATA;
fi.sub_state = HEAD_LOAD;
mfm = command[0] & 0x40;
- LOGCOMMAND("command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
+ LOGRW("command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
command[0] & 0x08 ? " deleted" : "",
command[0] & 0x80 ? " mt" : "",
command[0] & 0x40 ? " mfm" : "",
@@ -1923,11 +1920,6 @@ void upd765_family_device::write_data_continue(floppy_info &fi)
break;
}
st1 &= ~ST1_MA;
- LOGRW("writing sector %02x %02x %02x %02x\n",
- cur_live.idbuf[0],
- cur_live.idbuf[1],
- cur_live.idbuf[2],
- cur_live.idbuf[3]);
sector_size = calc_sector_size(cur_live.idbuf[3]);
fifo_expect(sector_size, true);
fi.sub_state = SECTOR_WRITTEN;
@@ -2000,7 +1992,7 @@ void upd765_family_device::read_track_start(floppy_info &fi)
mfm = command[0] & 0x40;
sectors_read = 0;
- LOGCOMMAND("command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
+ LOGRW("command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n",
command[0] & 0x40 ? " mfm" : "",
command[0],
command[1],
@@ -2292,9 +2284,6 @@ void upd765_family_device::read_id_start(floppy_info &fi)
return;
}
- for(int i=0; i<4; i++)
- cur_live.idbuf[i] = command[i+2];
-
read_id_continue(fi);
}
@@ -2327,7 +2316,8 @@ void upd765_family_device::read_id_continue(floppy_info &fi)
case SCAN_ID_FAILED:
LOGSTATE("SCAN_ID_FAILED\n");
fi.st0 |= ST0_FAIL;
- st1 |= ST1_ND|ST1_MA;
+ // st1 |= ST1_ND|ST1_MA;
+ st1 = ST1_MA;
fi.sub_state = COMMAND_DONE;
break;
@@ -2453,7 +2443,6 @@ void upd765_family_device::index_callback(floppy_image_device *floppy, int state
if(fi.live)
live_sync();
fi.index = state;
- idx_cb(state);
if(!state) {
general_continue(fi);
@@ -2966,7 +2955,7 @@ void mcs3201_device::device_start()
m_input_handler.resolve_safe(0);
}
-uint8_t mcs3201_device::input_r()
+READ8_MEMBER( mcs3201_device::input_r )
{
return m_input_handler();
}
@@ -2986,7 +2975,7 @@ void tc8566af_device::device_start()
save_item(NAME(m_cr1));
}
-void tc8566af_device::cr1_w(uint8_t data)
+WRITE8_MEMBER(tc8566af_device::cr1_w)
{
m_cr1 = data;
@@ -2996,7 +2985,7 @@ void tc8566af_device::cr1_w(uint8_t data)
}
}
-void upd72065_device::auxcmd_w(uint8_t data)
+WRITE8_MEMBER(upd72065_device::auxcmd_w)
{
switch(data) {
case 0x36: // reset
diff --git a/src/devices/machine/upd765.h b/src/devices/machine/upd765.h
index 0a40e4f4b53..dd2e30ce78a 100644
--- a/src/devices/machine/upd765.h
+++ b/src/devices/machine/upd765.h
@@ -45,29 +45,34 @@ public:
auto intrq_wr_callback() { return intrq_cb.bind(); }
auto drq_wr_callback() { return drq_cb.bind(); }
auto hdl_wr_callback() { return hdl_cb.bind(); }
- auto us_wr_callback() { return us_cb.bind(); }
- auto idx_wr_callback() { return idx_cb.bind(); }
virtual void map(address_map &map) override = 0;
- uint8_t sra_r();
- uint8_t srb_r();
- uint8_t dor_r();
- void dor_w(uint8_t data);
- uint8_t tdr_r();
- void tdr_w(uint8_t data);
- uint8_t msr_r();
- void dsr_w(uint8_t data);
- uint8_t fifo_r();
- void fifo_w(uint8_t data);
- uint8_t dir_r() { return do_dir_r(); }
- void ccr_w(uint8_t data);
+ DECLARE_READ8_MEMBER (sra_r);
+ DECLARE_READ8_MEMBER (srb_r);
+ DECLARE_READ8_MEMBER (dor_r);
+ DECLARE_WRITE8_MEMBER(dor_w);
+ DECLARE_READ8_MEMBER (tdr_r);
+ DECLARE_WRITE8_MEMBER(tdr_w);
+ uint8_t read_msr();
+ DECLARE_READ8_MEMBER (msr_r);
+ DECLARE_WRITE8_MEMBER(dsr_w);
+ uint8_t read_fifo();
+ void write_fifo(uint8_t data);
+ DECLARE_READ8_MEMBER (fifo_r) { return read_fifo(); }
+ DECLARE_WRITE8_MEMBER(fifo_w) { write_fifo(data); }
+ DECLARE_READ8_MEMBER (dir_r);
+ DECLARE_WRITE8_MEMBER(ccr_w);
virtual uint8_t do_dir_r() override;
uint8_t dma_r() override;
void dma_w(uint8_t data) override;
+ // Same as the previous ones, but as memory-mappable members
+ DECLARE_READ8_MEMBER(mdma_r);
+ DECLARE_WRITE8_MEMBER(mdma_w);
+
bool get_irq() const;
bool get_drq() const;
void tc_w(bool val) override;
@@ -86,7 +91,6 @@ public:
protected:
upd765_family_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
- virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
@@ -265,8 +269,7 @@ protected:
int main_phase;
live_info cur_live, checkpoint_live;
- devcb_write_line intrq_cb, drq_cb, hdl_cb, idx_cb;
- devcb_write8 us_cb;
+ devcb_write_line intrq_cb, drq_cb, hdl_cb;
bool cur_irq, other_irq, data_irq, drq, internal_drq, tc, tc_done, locked, mfm, scan_done;
floppy_info flopi[4];
@@ -470,7 +473,7 @@ public:
upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void map(address_map &map) override;
- void auxcmd_w(uint8_t data);
+ DECLARE_WRITE8_MEMBER(auxcmd_w);
};
class n82077aa_device : public upd765_family_device {
@@ -521,7 +524,7 @@ public:
auto input_handler() { return m_input_handler.bind(); }
virtual void map(address_map &map) override;
- uint8_t input_r();
+ DECLARE_READ8_MEMBER( input_r );
protected:
virtual void device_start() override;
@@ -536,7 +539,7 @@ public:
virtual void map(address_map &map) override;
- void cr1_w(uint8_t data);
+ DECLARE_WRITE8_MEMBER(cr1_w);
protected:
virtual void device_start() override;
diff --git a/src/devices/machine/wd1010.cpp b/src/devices/machine/wd1010.cpp
deleted file mode 100644
index 16442934352..00000000000
--- a/src/devices/machine/wd1010.cpp
+++ /dev/null
@@ -1,583 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Dirk Best
-/***************************************************************************
-
- Western Digital WD1010-05 Winchester Disk Controller
-
-***************************************************************************/
-
-#include "emu.h"
-#include "wd1010.h"
-
-//#define LOG_GENERAL (1U << 0)
-#define LOG_CMD (1U << 1)
-#define LOG_INT (1U << 2)
-#define LOG_SEEK (1U << 3)
-#define LOG_REGS (1U << 4)
-#define LOG_DATA (1U << 5)
-
-//#define VERBOSE (LOG_CMD | LOG_INT | LOG_SEEK | LOG_REGS | LOG_DATA)
-//#define LOG_OUTPUT_STREAM std::cout
-
-#include "logmacro.h"
-
-#define LOGCMD(...) LOGMASKED(LOG_CMD, __VA_ARGS__)
-#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__)
-#define LOGSEEK(...) LOGMASKED(LOG_SEEK, __VA_ARGS__)
-#define LOGREGS(...) LOGMASKED(LOG_REGS, __VA_ARGS__)
-#define LOGDATA(...) LOGMASKED(LOG_DATA, __VA_ARGS__)
-
-
-//**************************************************************************
-// DEVICE DEFINITIONS
-//**************************************************************************
-
-DEFINE_DEVICE_TYPE(WD1010, wd1010_device, "wd1010", "Western Digital WD1010-05")
-
-
-//**************************************************************************
-// LIVE DEVICE
-//**************************************************************************
-
-//-------------------------------------------------
-// wd1010_device - constructor
-//-------------------------------------------------
-
-wd1010_device::wd1010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, WD1010, tag, owner, clock),
- m_out_intrq_cb(*this),
- m_out_bcr_cb(*this),
- m_in_data_cb(*this),
- m_out_data_cb(*this),
- m_intrq(0),
- m_brdy(0),
- m_stepping_rate(0x00),
- m_command(0x00),
- m_error(0x00),
- m_precomp(0x00),
- m_sector_count(0x00),
- m_sector_number(0x00),
- m_cylinder(0x0000),
- m_sdh(0x00),
- m_status(0x00)
-{
-}
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void wd1010_device::device_start()
-{
- // get connected drives
- for (int i = 0; i < 4; i++)
- {
- char name[2];
- name[0] = '0' + i;
- name[1] = 0;
- m_drives[i].drive = subdevice<harddisk_image_device>(name);
- m_drives[i].head = 0;
- m_drives[i].cylinder = 0;
- m_drives[i].sector = 0;
- }
-
- // resolve callbacks
- m_out_intrq_cb.resolve_safe();
- m_out_bcr_cb.resolve_safe();
- m_in_data_cb.resolve_safe(0);
- m_out_data_cb.resolve_safe();
-
- // allocate timer
- m_seek_timer = timer_alloc(TIMER_SEEK);
- m_data_timer = timer_alloc(TIMER_DATA);
-
- // register for save states
- save_item(NAME(m_intrq));
- save_item(NAME(m_brdy));
- save_item(NAME(m_stepping_rate));
- save_item(NAME(m_command));
- save_item(NAME(m_error));
- save_item(NAME(m_precomp));
- save_item(NAME(m_sector_count));
- save_item(NAME(m_sector_number));
- save_item(NAME(m_cylinder));
- save_item(NAME(m_sdh));
- save_item(NAME(m_status));
-}
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void wd1010_device::device_reset()
-{
-}
-
-//-------------------------------------------------
-// device_timer - device-specific timer
-//-------------------------------------------------
-
-void wd1010_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
-{
- switch (tid)
- {
- case TIMER_SEEK:
-
- if ((m_command >> 4) != CMD_SCAN_ID)
- {
- LOGSEEK("Seek complete\n");
- m_drives[drive()].cylinder = param;
- m_status |= STATUS_SC;
- }
-
- switch (m_command >> 4)
- {
- case CMD_RESTORE:
- cmd_restore();
- break;
-
- case CMD_SEEK:
- cmd_seek();
- break;
-
- case CMD_READ_SECTOR:
- cmd_read_sector();
- break;
-
- case CMD_WRITE_SECTOR:
- case CMD_WRITE_FORMAT:
- cmd_write_sector();
- break;
-
- case CMD_SCAN_ID:
- cmd_scan_id();
- break;
- }
-
- break;
-
- case TIMER_DATA:
-
- // check if data is ready or continue waiting
- if (m_brdy)
- cmd_write_sector();
- else
- m_data_timer->adjust(attotime::from_usec(35));
-
- break;
- }
-}
-
-//-------------------------------------------------
-// set_error - set error and adjust status
-//-------------------------------------------------
-
-void wd1010_device::set_error(int error)
-{
- if (error)
- {
- m_error |= error;
- m_status |= STATUS_ERR;
- }
- else
- {
- m_error = 0;
- m_status &= ~STATUS_ERR;
- }
-}
-
-//-------------------------------------------------
-// set_intrq - set interrupt status
-//-------------------------------------------------
-
-void wd1010_device::set_intrq(int state)
-{
- if (m_intrq == 0 && state == 1)
- {
- LOGINT("INT 1\n");
- m_intrq = 1;
- m_out_intrq_cb(1);
- }
- else if (m_intrq == 1 && state == 0)
- {
- LOGINT("INT 0\n");
- m_intrq = 0;
- m_out_intrq_cb(0);
- }
-}
-
-//-------------------------------------------------
-// get_stepping_rate - calculate stepping rate
-//-------------------------------------------------
-
-attotime wd1010_device::get_stepping_rate()
-{
- if (m_stepping_rate)
- return attotime::from_usec(500 * m_stepping_rate);
- else
- return attotime::from_usec(35);
-}
-
-//-------------------------------------------------
-// start_command - executed at the start of every command
-//-------------------------------------------------
-
-void wd1010_device::start_command()
-{
- // now busy and command in progress, clear error
- m_status |= STATUS_BSY;
- m_status |= STATUS_CIP;
- set_error(0);
-
- switch (m_command >> 4)
- {
- case CMD_RESTORE:
- m_stepping_rate = m_command & 0x0f;
- LOGCMD("RESTORE\n");
- break;
- case CMD_READ_SECTOR:
- LOGCMD("READ SECTOR\n");
- break;
- case CMD_WRITE_SECTOR:
- LOGCMD("WRITE SECTOR\n");
- break;
- case CMD_SCAN_ID:
- LOGCMD("SCAN ID\n");
- break;
- case CMD_WRITE_FORMAT:
- LOGCMD("WRITE FORMAT ID\n");
- break;
- case CMD_SEEK:
- m_stepping_rate = m_command & 0x0f;
- LOGCMD("SEEK\n");
- break;
- }
-}
-
-//-------------------------------------------------
-// end_command - executed at end of every command
-//-------------------------------------------------
-
-void wd1010_device::end_command()
-{
- m_out_bcr_cb(1);
- m_out_bcr_cb(0);
-
- m_status &= ~(STATUS_BSY | STATUS_CIP);
-
- set_intrq(1);
-}
-
-//-------------------------------------------------
-// get_lbasector - translate to lba
-//-------------------------------------------------
-
-int wd1010_device::get_lbasector()
-{
- hard_disk_file *file = m_drives[drive()].drive->get_hard_disk_file();
- hard_disk_info *info = hard_disk_get_info(file);
- int lbasector;
-
- lbasector = m_cylinder;
- lbasector *= info->heads;
- lbasector += head();
- lbasector *= info->sectors;
- lbasector += m_sector_number;
-
- return lbasector;
-}
-
-
-//**************************************************************************
-// INTERFACE
-//**************************************************************************
-
-WRITE_LINE_MEMBER( wd1010_device::drdy_w )
-{
- if (state)
- m_status |= STATUS_RDY;
- else
- m_status &= ~STATUS_RDY;
-}
-
-WRITE_LINE_MEMBER( wd1010_device::brdy_w )
-{
- m_brdy = state;
-}
-
-READ8_MEMBER( wd1010_device::read )
-{
- // if the controller is busy all reads return the status register
- if (m_status & STATUS_BSY)
- {
- LOG("Read while busy, return STATUS: %02x\n", m_status);
- return m_status;
- }
-
- switch (offset & 0x07)
- {
- case 0:
- LOGREGS("RD INVALID\n");
- return 0;
-
- case 1:
- LOGREGS("RD ERROR: %02x\n", m_error);
- return m_error;
-
- case 2:
- LOGREGS("RD SECTOR COUNT: %02x\n", m_sector_count);
- return m_sector_count;
-
- case 3:
- LOGREGS("RD SECTOR NUMBER: %02x\n", m_sector_number);
- return m_sector_number;
-
- case 4:
- LOGREGS("RD CYLINDER L: %02x\n", m_cylinder & 0xff);
- return m_cylinder & 0xff;
-
- case 5:
- LOGREGS("RD CYLINDER H: %02x\n", m_cylinder >> 8);
- return m_cylinder >> 8;
-
- case 6:
- LOGREGS("RD SDH: %02x\n", m_sdh);
- return m_sdh;
-
- case 7:
- LOGREGS("RD STATUS: %02x\n", m_status);
-
- // reading the status register clears the interrupt
- set_intrq(0);
-
- return m_status;
- }
-
- // should never get here
- return 0xff;
-}
-
-WRITE8_MEMBER( wd1010_device::write )
-{
- switch (offset & 0x07)
- {
- case 0:
- LOGREGS("WR INVALID: %02x\n", data);
- break;
-
- case 1:
- LOGREGS("WR PRECOMP: %02x\n", data);
- m_precomp = data;
- break;
-
- case 2:
- LOGREGS("WR SECTOR COUNT: %02x\n", data);
- m_sector_count = data;
- break;
-
- case 3:
- LOGREGS("WR SECTOR NUMBER: %02x\n", data);
- m_sector_number = data;
- break;
-
- case 4:
- LOGREGS("WR CYLINDER L: %02x\n", data);
- m_cylinder = (m_cylinder & 0xff00) | (data << 0);
- break;
-
- case 5:
- LOGREGS("WR CYLINDER H: %02x\n", data);
- m_cylinder = (m_cylinder & 0x00ff) | (data << 8);
- break;
-
- case 6:
- LOGREGS("WR SDH: %02x\n", data);
- m_sdh = data;
- break;
-
- case 7:
- // writes to the command register are ignored when a command is in progress
- if (m_status & STATUS_CIP)
- return;
-
- // writing the command register clears the interrupt
- set_intrq(0);
-
- // check drive status
- if (!(m_status & STATUS_RDY))
- {
- // selected drive not ready
- LOG("--> Drive not ready, aborting\n");
-
- set_error(ERR_AC);
- end_command();
- }
- else
- {
- m_command = data;
-
- start_command();
-
- // all other command imply a seek
- if ((m_command >> 4) != CMD_SCAN_ID)
- m_status &= ~STATUS_SC;
-
- int amount = 0;
- int target = 0;
-
- switch (m_command >> 4)
- {
- case CMD_RESTORE:
- amount = m_drives[drive()].cylinder;
- target = 0;
- break;
-
- case CMD_SEEK:
- case CMD_READ_SECTOR:
- case CMD_WRITE_SECTOR:
- case CMD_WRITE_FORMAT:
- amount = abs(m_drives[drive()].cylinder - m_cylinder);
- target = m_cylinder;
- break;
- }
-
- if ((m_command >> 4) != CMD_SCAN_ID)
- LOGSEEK("Seeking %d cylinders to %d\n", amount, target);
-
- m_seek_timer->adjust(get_stepping_rate() * amount, target);
- }
-
- break;
- }
-}
-
-
-//**************************************************************************
-// IMPLEMENTATION
-//**************************************************************************
-
-void wd1010_device::cmd_restore()
-{
- LOGCMD("--> RESTORE done\n");
- end_command();
-}
-
-void wd1010_device::cmd_read_sector()
-{
- hard_disk_file *file = m_drives[drive()].drive->get_hard_disk_file();
- hard_disk_info *info = hard_disk_get_info(file);
-
- m_out_bcr_cb(1);
- m_out_bcr_cb(0);
-
- // verify that we can read
- if (head() > info->heads)
- {
- // out of range
- LOG("--> Head out of range, aborting\n");
-
- set_error(ERR_AC);
- end_command();
- }
- else
- {
- uint8_t buffer[512];
-
- while (m_sector_count > 0)
- {
- LOGDATA("--> Transferring sector to buffer (lba = %08x)\n", get_lbasector());
-
- hard_disk_read(file, get_lbasector(), buffer);
-
- for (int i = 0; i < 512; i++)
- m_out_data_cb(buffer[i]);
-
- m_out_bcr_cb(1);
- m_out_bcr_cb(0);
-
- // save last read head and sector number
- m_drives[drive()].head = head();
- m_drives[drive()].sector = m_sector_number;
-
- if (BIT(m_command, 2))
- {
- m_sector_number++;
- m_sector_count--;
- }
- else
- break;
- }
-
- end_command();
- }
-}
-
-void wd1010_device::cmd_write_sector()
-{
- if (!(m_status & STATUS_DRQ))
- {
- LOGDATA("Setting DATA REQUEST\n");
- m_status |= STATUS_DRQ;
- m_data_timer->adjust(attotime::from_usec(35));
- return;
- }
-
- if (m_brdy == 0)
- {
- m_data_timer->adjust(attotime::from_usec(35));
- return;
- }
-
- LOGDATA("Clearing DATA REQUEST\n");
- m_status &= ~STATUS_DRQ;
-
- hard_disk_file *file = m_drives[drive()].drive->get_hard_disk_file();
- uint8_t buffer[512];
-
- while (m_sector_count > 0)
- {
- if ((m_command >> 4) == CMD_WRITE_FORMAT)
- {
- // we ignore the format specification and fill everything with 0xe5
- std::fill(std::begin(buffer), std::end(buffer), 0xe5);
- }
- else
- {
- // get data for sector from buffer chip
- for (int i = 0; i < 512; i++)
- buffer[i] = m_in_data_cb();
- }
-
- hard_disk_write(file, get_lbasector(), buffer);
-
- // save last read head and sector number
- m_drives[drive()].head = head();
- m_drives[drive()].sector = m_sector_number;
-
- if (BIT(m_command, 2))
- {
- m_sector_number++;
- m_sector_count--;
- }
- else
- break;
- }
-
- end_command();
-}
-
-void wd1010_device::cmd_scan_id()
-{
- // update head, sector size, sector number and cylinder
- m_sdh = (m_sdh & 0xf8) | (m_drives[drive()].head & 0x07);
- m_sector_number = m_drives[drive()].sector;
- m_cylinder = m_drives[drive()].cylinder;
-
- end_command();
-}
-
-void wd1010_device::cmd_seek()
-{
- LOGCMD("--> SEEK done\n");
- end_command();
-}
diff --git a/src/devices/machine/wd1010.h b/src/devices/machine/wd1010.h
deleted file mode 100644
index b5db9975693..00000000000
--- a/src/devices/machine/wd1010.h
+++ /dev/null
@@ -1,143 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Dirk Best
-/***************************************************************************
-
- Western Digital WD1010-05 Winchester Disk Controller
-
-***************************************************************************/
-
-#ifndef MAME_MACHINE_WD1010_H
-#define MAME_MACHINE_WD1010_H
-
-#pragma once
-
-#include "imagedev/harddriv.h"
-
-
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-// ======================> wd1010_device
-
-class wd1010_device : public device_t
-{
-public:
- // construction/destruction
- wd1010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- auto out_intrq_callback() { return m_out_intrq_cb.bind(); }
- auto out_bcr_callback() { return m_out_bcr_cb.bind(); }
- auto in_data_callback() { return m_in_data_cb.bind(); }
- auto out_data_callback() { return m_out_data_cb.bind(); }
-
- DECLARE_READ8_MEMBER(read);
- DECLARE_WRITE8_MEMBER(write);
-
- DECLARE_WRITE_LINE_MEMBER(drdy_w);
- DECLARE_WRITE_LINE_MEMBER(brdy_w);
-
-protected:
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
-
-private:
- enum
- {
- STATUS_ERR = 0x01, // error
- STATUS_CIP = 0x02, // command in progress
- STATUS_RSV = 0x04, // reserved
- STATUS_DRQ = 0x08, // data request
- STATUS_SC = 0x10, // seek complete
- STATUS_WF = 0x20, // write fault
- STATUS_RDY = 0x40, // drive ready
- STATUS_BSY = 0x80 // controller busy
- };
-
- enum
- {
- ERR_DM = 0x01, // data address mark not found
- ERR_TK = 0x02, // track zero error
- ERR_AC = 0x04, // aborted command
- ERR_RSV1 = 0x08, // reserved, forced to 0
- ERR_ID = 0x10, // id not found
- ERR_RSV2 = 0x20, // reserved, forced to 0
- ERR_CRC = 0x40, // crc error
- ERR_BB = 0x80 // bad block
- };
-
- enum
- {
- CMD_RESTORE = 1,
- CMD_READ_SECTOR = 2,
- CMD_WRITE_SECTOR = 3,
- CMD_SCAN_ID = 4,
- CMD_WRITE_FORMAT = 5,
- CMD_SEEK = 7
- };
-
- enum
- {
- TIMER_SEEK,
- TIMER_DATA
- };
-
- void set_error(int error);
- void set_intrq(int state);
- attotime get_stepping_rate();
- void start_command();
- void end_command();
- int get_lbasector();
-
- // extract values from sdh
- int head() { return (m_sdh >> 0) & 0x07; }
- int drive() { return (m_sdh >> 3) & 0x03; }
- int sector_size()
- {
- const int S[4] = { 256, 512, 1024, 128 };
- return S[(m_sdh >> 5) & 0x03];
- }
-
- void cmd_restore();
- void cmd_read_sector();
- void cmd_write_sector();
- void cmd_scan_id();
- void cmd_seek();
-
- devcb_write_line m_out_intrq_cb;
- devcb_write_line m_out_bcr_cb;
- devcb_read8 m_in_data_cb;
- devcb_write8 m_out_data_cb;
-
- struct
- {
- harddisk_image_device *drive;
- uint8_t head;
- uint16_t cylinder;
- uint8_t sector;
- } m_drives[4];
-
- emu_timer *m_seek_timer;
- emu_timer *m_data_timer;
-
- int m_intrq;
- int m_brdy;
- uint8_t m_stepping_rate;
- uint8_t m_command;
-
- // task file registers
- uint8_t m_error;
- uint8_t m_precomp;
- uint8_t m_sector_count;
- uint8_t m_sector_number;
- uint16_t m_cylinder;
- uint8_t m_sdh;
- uint8_t m_status;
-};
-
-// device type definition
-DECLARE_DEVICE_TYPE(WD1010, wd1010_device)
-
-#endif // MAME_MACHINE_WD1010_H
diff --git a/src/devices/machine/wd11c00_17.cpp b/src/devices/machine/wd11c00_17.cpp
index b0d58034f6d..499601c943f 100644
--- a/src/devices/machine/wd11c00_17.cpp
+++ b/src/devices/machine/wd11c00_17.cpp
@@ -301,15 +301,6 @@ WRITE8_MEMBER( wd11c00_17_device::io_w )
//-------------------------------------------------
-// dack3_w -
-//-------------------------------------------------
-
-WRITE_LINE_MEMBER(wd11c00_17_device::dack3_w)
-{
-}
-
-
-//-------------------------------------------------
// dack_r -
//-------------------------------------------------
diff --git a/src/devices/machine/wd11c00_17.h b/src/devices/machine/wd11c00_17.h
index 0b375f61e67..e109c548202 100644
--- a/src/devices/machine/wd11c00_17.h
+++ b/src/devices/machine/wd11c00_17.h
@@ -39,7 +39,6 @@ public:
DECLARE_READ8_MEMBER( io_r );
DECLARE_WRITE8_MEMBER( io_w );
- DECLARE_WRITE_LINE_MEMBER( dack3_w );
uint8_t dack_r();
void dack_w(uint8_t data);
diff --git a/src/devices/machine/wd2010.cpp b/src/devices/machine/wd2010.cpp
index 95bb4803107..c25aa538df3 100644
--- a/src/devices/machine/wd2010.cpp
+++ b/src/devices/machine/wd2010.cpp
@@ -28,11 +28,11 @@ UNIMPLEMENTED FEATURES :
the intended instruction flow. Some loops were omitted!
USAGE: tie WF (write fault) to ground if not needed:
- in_wf_callback().set_constant(0)
+ MCFG_WD2010_IN_WF_CB(GND)
Other signals should be set to VCC if not serviced:
- in_drdy_callback().set_constant(1) // DRIVE READY = VCC
- in_sc_callback().set_constant(1) // SEEK COMPLETE = VCC
+ MCFG_WD2010_IN_DRDY_CB(VCC) // DRIVE READY = VCC
+ MCFG_WD2010_IN_SC_CB(VCC) // SEEK COMPLETE = VCC
**********************************************************************/
#include "emu.h"
@@ -233,7 +233,7 @@ void wd2010_device::device_reset()
// read -
//-------------------------------------------------
-uint8_t wd2010_device::read(offs_t offset)
+READ8_MEMBER(wd2010_device::read)
{
uint8_t data;
@@ -273,7 +273,7 @@ uint8_t wd2010_device::read(offs_t offset)
// write -
//-------------------------------------------------
-void wd2010_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(wd2010_device::write)
{
m_task_file[offset] = data;
diff --git a/src/devices/machine/wd2010.h b/src/devices/machine/wd2010.h
index 1617f886ed6..fdfc2c4462c 100644
--- a/src/devices/machine/wd2010.h
+++ b/src/devices/machine/wd2010.h
@@ -40,8 +40,8 @@ public:
auto in_tk000_callback() { return m_in_tk000_cb.bind(); }
auto in_sc_callback() { return m_in_sc_cb.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
void buffer_ready(bool state);
diff --git a/src/devices/machine/wd33c93.cpp b/src/devices/machine/wd33c93.cpp
new file mode 100644
index 00000000000..fcbb45957af
--- /dev/null
+++ b/src/devices/machine/wd33c93.cpp
@@ -0,0 +1,984 @@
+// license:BSD-3-Clause
+// copyright-holders:ElSemi, R. Belmont, Ryan Holtz
+/*
+ * wd33c93.c
+ *
+ * WD/AMD 33c93 SCSI controller, as seen in
+ * early PCs, some MSX add-ons, NEC PC-88, and SGI
+ * Indigo, Indigo2, and Indy systems.
+ *
+ * References:
+ * WD 33c93 manual
+ * NetBSD 33c93 driver
+ *
+ */
+
+#include "emu.h"
+#include "wd33c93.h"
+
+#define LOG_READS (1 << 0)
+#define LOG_WRITES (1 << 1)
+#define LOG_COMMANDS (1 << 2)
+#define LOG_ERRORS (1 << 3)
+#define LOG_MISC (1 << 4)
+#define LOG_REGS (LOG_READS | LOG_WRITES)
+#define LOG_ALL (LOG_REGS | LOG_COMMANDS | LOG_ERRORS | LOG_MISC)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
+
+/* WD commands */
+#define WD_CMD_RESET 0x00
+#define WD_CMD_ABORT 0x01
+#define WD_CMD_ASSERT_ATN 0x02
+#define WD_CMD_NEGATE_ACK 0x03
+#define WD_CMD_DISCONNECT 0x04
+#define WD_CMD_RESELECT 0x05
+#define WD_CMD_SEL_ATN 0x06
+#define WD_CMD_SEL 0x07
+#define WD_CMD_SEL_ATN_XFER 0x08
+#define WD_CMD_SEL_XFER 0x09
+#define WD_CMD_RESEL_RECEIVE 0x0a
+#define WD_CMD_RESEL_SEND 0x0b
+#define WD_CMD_WAIT_SEL_RECEIVE 0x0c
+#define WD_CMD_SSCC 0x0d
+#define WD_CMD_SND_DISC 0x0e
+#define WD_CMD_SET_IDI 0x0f
+#define WD_CMD_RCV_CMD 0x10
+#define WD_CMD_RCV_DATA 0x11
+#define WD_CMD_RCV_MSG_OUT 0x12
+#define WD_CMD_RCV 0x13
+#define WD_CMD_SND_STATUS 0x14
+#define WD_CMD_SND_DATA 0x15
+#define WD_CMD_SND_MSG_IN 0x16
+#define WD_CMD_SND 0x17
+#define WD_CMD_TRANS_ADDR 0x18
+#define WD_CMD_XFER_PAD 0x19
+#define WD_CMD_TRANS_INFO 0x20
+#define WD_CMD_TRANSFER_PAD 0x21
+#define WD_CMD_SBT_MODE 0x80
+
+/* ASR register */
+#define ASR_INT 0x80
+#define ASR_LCI 0x40
+#define ASR_BSY 0x20
+#define ASR_CIP 0x10
+#define ASR_PE 0x02
+#define ASR_DBR 0x01
+
+/* SCSI Bus Phases */
+#define PHS_DATA_OUT 0x00
+#define PHS_DATA_IN 0x01
+#define PHS_COMMAND 0x02
+#define PHS_STATUS 0x03
+#define PHS_MESS_OUT 0x06
+#define PHS_MESS_IN 0x07
+
+/* Command Status Register definitions */
+
+ /* reset state interrupts */
+#define CSR_RESET 0x00
+#define CSR_RESET_AF 0x01
+
+ /* successful completion interrupts */
+#define CSR_RESELECT 0x10
+#define CSR_SELECT 0x11
+#define CSR_SEL_XFER_DONE 0x16
+#define CSR_XFER_DONE 0x18
+
+ /* paused or aborted interrupts */
+#define CSR_MSGIN 0x20
+#define CSR_SDP 0x21
+#define CSR_SEL_ABORT 0x22
+#define CSR_RESEL_ABORT 0x25
+#define CSR_RESEL_ABORT_AM 0x27
+#define CSR_ABORT 0x28
+
+ /* terminated interrupts */
+#define CSR_INVALID 0x40
+#define CSR_UNEXP_DISC 0x41
+#define CSR_TIMEOUT 0x42
+#define CSR_PARITY 0x43
+#define CSR_PARITY_ATN 0x44
+#define CSR_BAD_STATUS 0x45
+#define CSR_UNEXP 0x48
+
+ /* service required interrupts */
+#define CSR_RESEL 0x80
+#define CSR_RESEL_AM 0x81
+#define CSR_DISC 0x85
+#define CSR_SRV_REQ 0x88
+
+ /* Own ID/CDB Size register */
+#define OWNID_EAF 0x08
+#define OWNID_EHP 0x10
+#define OWNID_RAF 0x20
+#define OWNID_FS_8 0x00
+#define OWNID_FS_12 0x40
+#define OWNID_FS_16 0x80
+
+ /* Control register */
+#define CTRL_HSP 0x01
+#define CTRL_HA 0x02
+#define CTRL_IDI 0x04
+#define CTRL_EDI 0x08
+#define CTRL_HHP 0x10
+#define CTRL_POLLED 0x00
+#define CTRL_BURST 0x20
+#define CTRL_BUS 0x40
+#define CTRL_DMA 0x80
+
+ /* Synchronous Transfer Register */
+#define STR_FSS 0x80
+
+ /* Destination ID register */
+#define DSTID_DPD 0x40
+#define DATA_OUT_DIR 0
+#define DATA_IN_DIR 1
+#define DSTID_SCC 0x80
+
+ /* Source ID register */
+#define SRCID_MASK 0x07
+#define SRCID_SIV 0x08
+#define SRCID_DSP 0x20
+#define SRCID_ES 0x40
+#define SRCID_ER 0x80
+
+/* convernience functions */
+uint8_t wd33c93_device::getunit()
+{
+ /* return the destination unit id */
+ return m_regs[WD_DESTINATION_ID] & SRCID_MASK;
+}
+
+void wd33c93_device::set_xfer_count( int count )
+{
+ /* set the count */
+ m_regs[WD_TRANSFER_COUNT_LSB] = count & 0xff;
+ m_regs[WD_TRANSFER_COUNT] = (count >> 8) & 0xff;
+ m_regs[WD_TRANSFER_COUNT_MSB] = (count >> 16) & 0xff;
+}
+
+int wd33c93_device::get_xfer_count()
+{
+ /* get the count */
+ int count = m_regs[WD_TRANSFER_COUNT_MSB];
+
+ count <<= 8;
+ count |= m_regs[WD_TRANSFER_COUNT];
+ count <<= 8;
+ count |= m_regs[WD_TRANSFER_COUNT_LSB];
+
+ return count;
+}
+
+void wd33c93_device::complete_immediate(int status)
+{
+ /* reset our timer */
+ m_cmd_timer->reset();
+
+ /* set the new status */
+ m_regs[WD_SCSI_STATUS] = status & 0xff;
+
+ /* set interrupt pending */
+ m_regs[WD_AUXILIARY_STATUS] |= ASR_INT;
+
+ /* check for error conditions */
+ if (get_xfer_count() > 0)
+ {
+ /* set data buffer ready */
+ m_regs[WD_AUXILIARY_STATUS] |= ASR_DBR;
+ }
+ else
+ {
+ /* clear data buffer ready */
+ m_regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
+ }
+
+ /* clear command in progress and bus busy */
+ m_regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
+
+ /* if we have a callback, call it */
+ if (!m_irq_cb.isnull())
+ {
+ m_irq_cb(1);
+ }
+}
+
+void wd33c93_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
+{
+ switch (tid)
+ {
+ case 0:
+ complete_immediate(param);
+ break;
+
+ case 1:
+ complete_immediate(CSR_SRV_REQ | m_busphase);
+ break;
+
+ case 2:
+ m_regs[WD_AUXILIARY_STATUS] &= ~ASR_CIP;
+ break;
+ }
+}
+
+void wd33c93_device::complete_cmd(uint8_t status)
+{
+ /* fire off a timer to complete the command */
+ m_cmd_timer->adjust(attotime::from_usec(1), status);
+}
+
+/* command handlers */
+void wd33c93_device::unimplemented_cmd()
+{
+ LOGMASKED(LOG_COMMANDS | LOG_ERRORS, "%s: Unimplemented SCSI controller command: %02x\n", machine().describe_context(), m_regs[WD_COMMAND]);
+
+ /* complete the command */
+ complete_cmd(CSR_INVALID);
+}
+
+void wd33c93_device::invalid_cmd()
+{
+ LOGMASKED(LOG_COMMANDS | LOG_ERRORS, "%s: Invalid SCSI controller command: %02x\n", machine().describe_context(), m_regs[WD_COMMAND]);
+
+ /* complete the command */
+ complete_cmd(CSR_INVALID);
+}
+
+void wd33c93_device::reset_cmd()
+{
+ int advanced = 0;
+
+ /* see if it wants us to reset with advanced features */
+ if (m_regs[WD_OWN_ID] & OWNID_EAF)
+ {
+ advanced = 1;
+ }
+
+ /* clear out all registers */
+ memset(m_regs, 0, sizeof(m_regs));
+
+ /* complete the command */
+ complete_cmd(advanced ? CSR_RESET_AF : CSR_RESET);
+}
+
+void wd33c93_device::abort_cmd()
+{
+ /* complete the command */
+ complete_cmd(CSR_ABORT);
+}
+
+void wd33c93_device::disconnect_cmd()
+{
+ /* complete the command */
+ m_regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
+}
+
+void wd33c93_device::select_cmd()
+{
+ uint8_t unit = getunit();
+ uint8_t newstatus;
+
+ /* see if we can select that device */
+ if (select(unit))
+ {
+ /* device is available - signal selection done */
+ newstatus = CSR_SELECT;
+
+ /* determine the next bus phase depending on the command */
+ if ((m_regs[WD_COMMAND] & 0x7f) == WD_CMD_SEL_ATN)
+ {
+ /* /ATN asserted during select: Move to Message Out Phase to read identify */
+ m_busphase = PHS_MESS_OUT;
+ }
+ else
+ {
+ /* No /ATN asserted: Move to Command Phase */
+ m_busphase = PHS_COMMAND;
+ }
+
+ /* queue up a service request out in the future */
+ m_service_req_timer->adjust( attotime::from_usec(50) );
+ }
+ else
+ {
+ /* device is not available */
+ newstatus = CSR_TIMEOUT;
+ }
+
+ /* complete the command */
+ complete_cmd(newstatus);
+}
+
+void wd33c93_device::selectxfer_cmd()
+{
+ uint8_t unit = getunit();
+ uint8_t newstatus;
+
+ /* see if we can select that device */
+ if (select(unit))
+ {
+ if (m_regs[WD_COMMAND_PHASE] < 0x45)
+ {
+ /* device is available */
+
+ /* do the request */
+ send_command(&m_regs[WD_CDB_1], 12);
+ int phase = get_phase();
+
+ /* set transfer count */
+ if (get_xfer_count() > TEMP_INPUT_LEN)
+ {
+ LOGMASKED(LOG_ERRORS, "WD33C93: Transfer count too big. Please increase TEMP_INPUT_LEN (size=%d)\n", get_xfer_count());
+ set_xfer_count(TEMP_INPUT_LEN);
+ }
+
+ switch (phase)
+ {
+ case SCSI_PHASE_DATAIN:
+ m_read_pending = true;
+ break;
+ }
+ }
+
+ if (m_read_pending)
+ {
+ int len = TEMP_INPUT_LEN;
+
+ if (get_xfer_count() < len)
+ len = get_xfer_count();
+
+ memset(&m_temp_input[0], 0, TEMP_INPUT_LEN);
+ read_data(&m_temp_input[0], len);
+ m_temp_input_pos = 0;
+ m_read_pending = false;
+ }
+
+ m_regs[WD_TARGET_LUN] = 0;
+ m_regs[WD_CONTROL] |= CTRL_EDI;
+ m_regs[WD_COMMAND_PHASE] = 0x60;
+
+ /* signal transfer ready */
+ newstatus = CSR_SEL_XFER_DONE;
+
+ /* if allowed disconnect, queue a service request */
+ if (m_identify & 0x40)
+ {
+ /* queue disconnect message in */
+ m_busphase = PHS_MESS_IN;
+
+ /* queue up a service request out in the future */
+ m_service_req_timer->adjust(attotime::from_usec(50));
+ }
+ }
+ else
+ {
+ /* device is not available */
+ newstatus = CSR_TIMEOUT;
+
+ set_xfer_count(0);
+ }
+
+ /* complete the command */
+ complete_cmd(newstatus);
+}
+
+void wd33c93_device::negate_ack()
+{
+ LOGMASKED(LOG_MISC, "WD33C93: ACK Negated\n");
+
+ /* complete the command */
+ m_regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
+}
+
+void wd33c93_device::xferinfo_cmd()
+{
+ /* make the buffer available right away */
+ m_regs[WD_AUXILIARY_STATUS] |= ASR_DBR;
+ m_regs[WD_AUXILIARY_STATUS] |= ASR_CIP;
+
+ /* the command will be completed once the data is transferred */
+ m_deassert_cip_timer->adjust(attotime::from_msec(1));
+}
+
+/* Handle pending commands */
+void wd33c93_device::dispatch_command()
+{
+ /* get the command */
+ uint8_t cmd = m_regs[WD_COMMAND] & 0x7f;
+
+ switch (cmd)
+ {
+ case WD_CMD_RESET:
+ LOGMASKED(LOG_COMMANDS, "WD33C93: %s - Reset Command\n", machine().describe_context());
+ reset_cmd();
+ break;
+
+ case WD_CMD_ABORT:
+ LOGMASKED(LOG_COMMANDS, "WD33C93: %s - Abort Command\n", machine().describe_context());
+ abort_cmd();
+ break;
+
+ case WD_CMD_NEGATE_ACK:
+ LOGMASKED(LOG_COMMANDS, "WD33C93: %s - Negate ACK Command\n", machine().describe_context());
+ negate_ack();
+ break;
+
+ case WD_CMD_DISCONNECT:
+ LOGMASKED(LOG_COMMANDS, "WD33C93: %s - Disconnect Command\n", machine().describe_context());
+ disconnect_cmd();
+ break;
+
+ case WD_CMD_SEL_ATN:
+ case WD_CMD_SEL:
+ LOGMASKED(LOG_COMMANDS, "WD33C93: %s - Select %sCommand\n", machine().describe_context(), cmd == WD_CMD_SEL_ATN ? "w/ ATN " : "");
+ select_cmd();
+ break;
+
+ case WD_CMD_SEL_ATN_XFER:
+ case WD_CMD_SEL_XFER:
+ LOGMASKED(LOG_COMMANDS, "WD33C93: %s - Select %sand Xfer Command\n", machine().describe_context(), cmd == WD_CMD_SEL_ATN ? "w/ ATN " : "");
+ selectxfer_cmd();
+ break;
+
+ case WD_CMD_TRANS_INFO:
+ LOGMASKED(LOG_COMMANDS, "WD33C93: %s - Transfer Info Command\n", machine().describe_context());
+ xferinfo_cmd();
+ break;
+
+ case WD_CMD_ASSERT_ATN:
+ case WD_CMD_RESELECT:
+ case WD_CMD_RESEL_RECEIVE:
+ case WD_CMD_RESEL_SEND:
+ case WD_CMD_WAIT_SEL_RECEIVE:
+ case WD_CMD_SSCC:
+ case WD_CMD_SND_DISC:
+ case WD_CMD_SET_IDI:
+ case WD_CMD_RCV_CMD:
+ case WD_CMD_RCV_DATA:
+ case WD_CMD_RCV_MSG_OUT:
+ case WD_CMD_RCV:
+ case WD_CMD_SND_STATUS:
+ case WD_CMD_SND_DATA:
+ case WD_CMD_SND_MSG_IN:
+ case WD_CMD_SND:
+ case WD_CMD_TRANS_ADDR:
+ case WD_CMD_XFER_PAD:
+ case WD_CMD_TRANSFER_PAD:
+ unimplemented_cmd();
+ break;
+
+ default:
+ invalid_cmd();
+ break;
+ }
+}
+
+WRITE8_MEMBER(wd33c93_device::write)
+{
+ switch (offset)
+ {
+ case 0:
+ {
+ /* update register select */
+ m_sasr = data & 0x1f;
+ }
+ break;
+
+ case 1:
+ {
+ /* update the register */
+ if (m_sasr != WD_SCSI_STATUS && m_sasr <= WD_QUEUE_TAG)
+ {
+ m_regs[m_sasr] = data;
+ }
+
+ switch (m_sasr)
+ {
+ case WD_OWN_ID:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Own ID Register (CDB Size) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CONTROL:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Control Register = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_TIMEOUT_PERIOD:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Timeout Period Register = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_1:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Total Sectors Register (CDB1) = %02x\n", machine().describe_context(), m_sasr, data);
+ m_regs[WD_COMMAND_PHASE] = 0;
+ break;
+ case WD_CDB_2:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Total Heads Register (CDB2) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_3:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Total Cylinders Register MSB (CDB3) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_4:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Total Cylinders Register LSB (CDB4) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_5:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Logical Address Register MSB (CDB5) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_6:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Logical Address Register 2nd (CDB6) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_7:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Logical Address Register 3rd (CDB7) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_8:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Logical Address Register LSB (CDB8) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_9:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Sector Number Register (CDB9) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_10:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Head Number Register (CDB10) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_11:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Cylinder Number Register MSB (CDB11) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_CDB_12:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Cylinder Number Register LSB (CDB12) = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_TARGET_LUN:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Target LUN Register = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_COMMAND_PHASE:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Command Phase Register = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_SYNCHRONOUS_TRANSFER:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Synchronous Transfer Register = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_TRANSFER_COUNT_MSB:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Transfer Count Register MSB = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_TRANSFER_COUNT:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Transfer Count Register 2nd = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_TRANSFER_COUNT_LSB:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Transfer Count Register LSB = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_DESTINATION_ID:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Destination ID Register = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_SOURCE_ID:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Source ID Register = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_SCSI_STATUS:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, SCSI Status Register (read-only!) = %02x (ignored)\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_COMMAND:
+ /* if we receive a command, schedule to process it */
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Command Register = %02x - unit %d\n", machine().describe_context(), m_sasr, data, getunit());
+
+ /* signal we're processing it */
+ m_regs[WD_AUXILIARY_STATUS] |= ASR_CIP;
+
+ /* process the command */
+ dispatch_command();
+ break;
+ case WD_DATA:
+ {
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Data Register = %02x\n", machine().describe_context(), m_sasr, data);
+
+ /* if data was written, and we have a count, send to device */
+ int count = get_xfer_count();
+
+ if (m_regs[WD_COMMAND] & 0x80)
+ count = 1;
+
+ if (count-- > 0)
+ {
+ /* write to FIFO */
+ if (m_fifo_pos < FIFO_SIZE)
+ {
+ m_fifo[m_fifo_pos++] = data;
+ }
+
+ /* update count */
+ set_xfer_count(count);
+
+ /* if we're done with the write, see where we're at */
+ if (count == 0)
+ {
+ m_regs[WD_AUXILIARY_STATUS] |= ASR_INT;
+ m_regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
+
+ switch (m_busphase)
+ {
+ case PHS_MESS_OUT:
+ {
+ /* reset fifo */
+ m_fifo_pos = 0;
+
+ /* Message out phase. Data is probably SCSI Identify. Move to command phase. */
+ m_busphase = PHS_COMMAND;
+
+ m_identify = m_fifo[0];
+ }
+ break;
+
+ case PHS_COMMAND:
+ {
+ /* Execute the command. Depending on the command, we'll move to data in or out */
+ send_command(&m_fifo[0], 12);
+ int xfercount = get_length();
+ int phase = get_phase();
+
+ /* reset fifo */
+ m_fifo_pos = 0;
+
+ /* set the new count */
+ set_xfer_count(xfercount);
+
+ switch (phase)
+ {
+ case SCSI_PHASE_STATUS:
+ m_busphase = PHS_STATUS;
+ break;
+
+ case SCSI_PHASE_DATAIN:
+ m_busphase = PHS_DATA_IN;
+ m_read_pending = true;
+ break;
+
+ case SCSI_PHASE_DATAOUT:
+ m_busphase = PHS_DATA_OUT;
+ break;
+ }
+ }
+ break;
+
+ case PHS_DATA_OUT:
+ {
+ /* write data out to device */
+ write_data(m_fifo, m_fifo_pos);
+
+ /* reset fifo */
+ m_fifo_pos = 0;
+
+ /* move to status phase */
+ m_busphase = PHS_STATUS;
+ }
+ break;
+ }
+
+ /* complete the command */
+ complete_immediate(CSR_XFER_DONE | m_busphase);
+ }
+ }
+ else
+ {
+ LOGMASKED(LOG_MISC | LOG_ERRORS, "WD33C93: Sending data to device with transfer count = 0!. Ignoring...\n");
+ }
+ break;
+ }
+ case WD_QUEUE_TAG:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Queue Tag Register = %02x\n", machine().describe_context(), m_sasr, data);
+ break;
+ case WD_AUXILIARY_STATUS:
+ LOGMASKED(LOG_WRITES, "WD33C93: %s - Write Register %02x, Auxiliary Status Register (read-only!) = %02x (ignored)\n", machine().describe_context(), m_sasr, data);
+ break;
+ default:
+ LOGMASKED(LOG_WRITES | LOG_ERRORS, "WD33C93: %s - Write Register %02x, Unknown = %02x (ignored)\n", machine().describe_context(), m_sasr, data);
+ break;
+ }
+
+ /* auto-increment register select if not on special registers */
+ if (m_sasr != WD_COMMAND && m_sasr != WD_DATA && m_sasr != WD_AUXILIARY_STATUS)
+ {
+ m_sasr = (m_sasr + 1) & 0x1f;
+ }
+ }
+ break;
+
+ default:
+ {
+ LOGMASKED(LOG_ERRORS, "WD33C93: Write to invalid offset %d (data=%02x)\n", offset, data);
+ }
+ break;
+ }
+}
+
+READ8_MEMBER(wd33c93_device::read)
+{
+ switch (offset)
+ {
+ case 0:
+ /* read aux status */
+ return m_regs[WD_AUXILIARY_STATUS];
+
+ case 1:
+ {
+ switch (m_sasr)
+ {
+ case WD_OWN_ID:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Own ID Register (CDB Size) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CONTROL:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Control Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_TIMEOUT_PERIOD:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Timeout Period Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_1:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Total Sectors Register (CDB1) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ m_regs[WD_COMMAND_PHASE] = 0;
+ break;
+ case WD_CDB_2:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Total Heads Register (CDB2) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_3:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Total Cylinders Register MSB (CDB3) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_4:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Total Cylinders Register LSB (CDB4) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_5:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Logical Address Register MSB (CDB5) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_6:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Logical Address Register 2nd (CDB6) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_7:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Logical Address Register 3rd (CDB7) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_8:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Logical Address Register LSB (CDB8) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_9:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Sector Number Register (CDB9) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_10:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Head Number Register (CDB10) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_11:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Cylinder Number Register MSB (CDB11) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_CDB_12:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Cylinder Number Register LSB (CDB12) (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_TARGET_LUN:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Target LUN Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_COMMAND_PHASE:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Command Phase Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_SYNCHRONOUS_TRANSFER:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Synchronous Transfer Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_TRANSFER_COUNT_MSB:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Transfer Count Register MSB (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_TRANSFER_COUNT:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Transfer Count Register 2nd (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_TRANSFER_COUNT_LSB:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Transfer Count Register LSB (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_DESTINATION_ID:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Destination ID Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_SOURCE_ID:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Source ID Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_SCSI_STATUS:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, SCSI Status Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ m_regs[WD_AUXILIARY_STATUS] &= ~ASR_INT;
+
+ /* if reading status, clear irq flag */
+ if (!m_irq_cb.isnull())
+ {
+ m_irq_cb(0);
+ }
+ break;
+ case WD_COMMAND:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Command Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_DATA:
+ {
+ /* we're going to be doing synchronous reads */
+
+ /* get the transfer count */
+ int count = get_xfer_count();
+
+ /* initialize the return value */
+ m_regs[WD_DATA] = 0;
+
+ if (count <= 0 && m_busphase == PHS_MESS_IN)
+ {
+ /* move to disconnect */
+ complete_cmd(CSR_DISC);
+ }
+ else if (count == 1 && m_busphase == PHS_STATUS)
+ {
+ /* update the count */
+ set_xfer_count(0);
+
+ /* move to message in phase */
+ m_busphase = PHS_MESS_IN;
+
+ /* complete the command */
+ complete_cmd(CSR_XFER_DONE | m_busphase);
+ }
+ else if (count-- > 0) /* make sure we still have data to send */
+ {
+ if (m_read_pending)
+ {
+ int len = TEMP_INPUT_LEN;
+
+ if ((count + 1) < len )
+ len = count + 1;
+ read_data(&m_temp_input[0], len);
+ m_temp_input_pos = 0;
+ m_read_pending = false;
+ }
+
+ m_regs[WD_AUXILIARY_STATUS] &= ~ASR_INT;
+
+ /* read in one byte */
+ if (m_temp_input_pos < TEMP_INPUT_LEN)
+ m_regs[WD_DATA] = m_temp_input[m_temp_input_pos++];
+
+ /* update the count */
+ set_xfer_count(count);
+
+ /* transfer finished, see where we're at */
+ if (count == 0)
+ {
+ if (m_regs[WD_COMMAND_PHASE] != 0x60)
+ {
+ /* move to status phase */
+ m_busphase = PHS_STATUS;
+
+ /* complete the command */
+ complete_cmd(CSR_XFER_DONE | m_busphase);
+ }
+ else
+ {
+ m_regs[WD_AUXILIARY_STATUS] |= ASR_INT;
+ m_regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
+ }
+ }
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Data Register (%02x)\n", machine().describe_context(), WD_DATA, m_regs[WD_DATA]);
+ }
+ break;
+ }
+ case WD_QUEUE_TAG:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Queue Tag Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ case WD_AUXILIARY_STATUS:
+ LOGMASKED(LOG_READS, "WD33C93: %s - Read Register %02x, Auxiliary Status Register (%02x)\n", machine().describe_context(), m_sasr, m_regs[m_sasr]);
+ break;
+ default:
+ LOGMASKED(LOG_READS | LOG_ERRORS, "WD33C93: %s - Read Register %02x, Unknown\n", machine().describe_context(), m_sasr);
+ break;
+ }
+
+ /* get the register value */
+ uint8_t ret = 0xff;
+ if (m_sasr == WD_AUXILIARY_STATUS || m_sasr <= WD_QUEUE_TAG)
+ ret = m_regs[m_sasr];
+
+ /* auto-increment register select if not on special registers */
+ if (m_sasr != WD_COMMAND && m_sasr != WD_DATA && m_sasr != WD_AUXILIARY_STATUS)
+ {
+ m_sasr = (m_sasr + 1) & 0x1f;
+ }
+
+ return ret;
+ }
+
+ default:
+ LOGMASKED(LOG_READS | LOG_ERRORS, "WD33C93: Read from invalid offset %d\n", offset);
+ break;
+ }
+
+ return 0;
+}
+
+wd33c93_device::wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ legacy_scsi_host_adapter(mconfig, WD33C93, tag, owner, clock),
+ m_irq_cb(*this)
+{
+}
+
+void wd33c93_device::device_start()
+{
+ legacy_scsi_host_adapter::device_start();
+
+ memset(m_regs, 0, sizeof(m_regs));
+ memset(m_fifo, 0, sizeof(m_fifo));
+ memset(m_temp_input, 0, sizeof(m_temp_input));
+
+ m_sasr = 0;
+ m_fifo_pos = 0;
+ m_temp_input_pos = 0;
+ m_busphase = 0;
+ m_identify = 0;
+ m_read_pending = 0;
+
+ m_irq_cb.resolve();
+
+ /* allocate a timer for commands */
+ m_cmd_timer = timer_alloc(0);
+ m_service_req_timer = timer_alloc(1);
+ m_deassert_cip_timer = timer_alloc(2);
+
+ save_item(NAME(m_sasr));
+ save_item(NAME(m_regs));
+ save_item(NAME(m_fifo));
+ save_item(NAME(m_fifo_pos));
+ save_item(NAME(m_temp_input));
+ save_item(NAME(m_temp_input_pos));
+ save_item(NAME(m_busphase));
+ save_item(NAME(m_identify));
+ save_item(NAME(m_read_pending));
+}
+
+int wd33c93_device::dma_read_data(int bytes, uint8_t *data)
+{
+ int len = bytes;
+
+ if (len >= get_xfer_count())
+ len = get_xfer_count();
+
+ if (len == 0)
+ return 0;
+
+ if ((m_temp_input_pos + len) >= TEMP_INPUT_LEN)
+ {
+ LOGMASKED(LOG_ERRORS, "Reading past end of buffer, increase TEMP_INPUT_LEN size\n");
+ len = TEMP_INPUT_LEN - len;
+ }
+
+ assert(len);
+
+ memcpy(data, &m_temp_input[m_temp_input_pos], len);
+
+ m_temp_input_pos += len;
+ set_xfer_count(get_xfer_count() - len);
+ return len;
+}
+
+void wd33c93_device::dma_write_data(int bytes, uint8_t *data)
+{
+ write_data(data, bytes);
+}
+
+void wd33c93_device::clear_dma()
+{
+ /* indicate DMA completed by clearing the transfer count */
+ set_xfer_count(0);
+ m_regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
+}
+
+int wd33c93_device::get_dma_count()
+{
+ return get_xfer_count();
+}
+
+DEFINE_DEVICE_TYPE(WD33C93, wd33c93_device, "wd33c93", "Western Digital WD33C93 SCSI")
diff --git a/src/devices/machine/wd33c93.h b/src/devices/machine/wd33c93.h
new file mode 100644
index 00000000000..b4a883afca4
--- /dev/null
+++ b/src/devices/machine/wd33c93.h
@@ -0,0 +1,112 @@
+// license:BSD-3-Clause
+// copyright-holders:ElSemi, R. Belmont, Ryan Holtz
+/*
+ * wd33c93.h
+ *
+ */
+
+#ifndef MAME_MACHINE_WD33C93_H
+#define MAME_MACHINE_WD33C93_H
+
+#pragma once
+
+#include "legscsi.h"
+
+class wd33c93_device : public legacy_scsi_host_adapter
+{
+public:
+ // construction/destruction
+ wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner)
+ : wd33c93_device(mconfig, tag, owner, (uint32_t)0)
+ {
+ }
+
+ wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ auto irq_cb() { return m_irq_cb.bind(); }
+
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
+
+ int dma_read_data(int bytes, uint8_t *data);
+ void dma_write_data(int bytes, uint8_t *data);
+ void clear_dma();
+ int get_dma_count();
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+private:
+ // wd register names
+ enum
+ {
+ WD_OWN_ID = 0x00,
+ WD_CONTROL = 0x01,
+ WD_TIMEOUT_PERIOD = 0x02,
+ WD_CDB_1 = 0x03,
+ WD_CDB_2 = 0x04,
+ WD_CDB_3 = 0x05,
+ WD_CDB_4 = 0x06,
+ WD_CDB_5 = 0x07,
+ WD_CDB_6 = 0x08,
+ WD_CDB_7 = 0x09,
+ WD_CDB_8 = 0x0a,
+ WD_CDB_9 = 0x0b,
+ WD_CDB_10 = 0x0c,
+ WD_CDB_11 = 0x0d,
+ WD_CDB_12 = 0x0e,
+ WD_TARGET_LUN = 0x0f,
+ WD_COMMAND_PHASE = 0x10,
+ WD_SYNCHRONOUS_TRANSFER = 0x11,
+ WD_TRANSFER_COUNT_MSB = 0x12,
+ WD_TRANSFER_COUNT = 0x13,
+ WD_TRANSFER_COUNT_LSB = 0x14,
+ WD_DESTINATION_ID = 0x15,
+ WD_SOURCE_ID = 0x16,
+ WD_SCSI_STATUS = 0x17,
+ WD_COMMAND = 0x18,
+ WD_DATA = 0x19,
+ WD_QUEUE_TAG = 0x1a,
+ WD_AUXILIARY_STATUS = 0x1f
+ };
+
+ static constexpr int TEMP_INPUT_LEN = 262144;
+ static constexpr int FIFO_SIZE = 12;
+
+ uint8_t getunit();
+ void set_xfer_count(int count);
+ int get_xfer_count();
+ void complete_immediate(int status);
+ void complete_cmd(uint8_t status);
+ void unimplemented_cmd();
+ void invalid_cmd();
+ void reset_cmd();
+ void abort_cmd();
+ void disconnect_cmd();
+ void select_cmd();
+ void selectxfer_cmd();
+ void negate_ack();
+ void xferinfo_cmd();
+ void dispatch_command();
+
+ uint8_t m_sasr;
+ uint8_t m_regs[WD_AUXILIARY_STATUS+1];
+ uint8_t m_fifo[FIFO_SIZE];
+ int m_fifo_pos;
+ uint8_t m_temp_input[TEMP_INPUT_LEN];
+ int m_temp_input_pos;
+ uint8_t m_busphase;
+ uint8_t m_identify;
+ bool m_read_pending;
+ emu_timer *m_cmd_timer;
+ emu_timer *m_service_req_timer;
+ emu_timer *m_deassert_cip_timer;
+ devcb_write_line m_irq_cb; /* irq callback */
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(WD33C93, wd33c93_device)
+
+#endif // MAME_MACHINE_WD33C93_H
diff --git a/src/devices/machine/wd33c9x.cpp b/src/devices/machine/wd33c9x.cpp
index d425a9249b9..2ef063ad449 100644
--- a/src/devices/machine/wd33c9x.cpp
+++ b/src/devices/machine/wd33c9x.cpp
@@ -29,7 +29,8 @@
#define LOG_REGS (LOG_READS | LOG_WRITES)
#define LOG_ALL (LOG_REGS | LOG_COMMANDS | LOG_ERRORS | LOG_MISC | LOG_LINES | LOG_STATE | LOG_STEP)
-#define VERBOSE (0)
+#define VERBOSE (LOG_COMMANDS | LOG_ERRORS | LOG_STATE)
+#define LOG_OUTPUT_FUNC printf
#include "logmacro.h"
enum register_addresses_e : uint8_t {
@@ -278,27 +279,6 @@ enum : uint16_t {
INIT_CPT_RECV_BYTE_NACK
};
-const char *const wd33c9x_base_device::state_names[] = {
- "-",
- "IDLE",
- "FINISHED",
- "DISC_SEL_ARBITRATION",
- "INIT_MSG_WAIT_REQ",
- "INIT_XFR",
- "INIT_XFR_SEND_PAD_WAIT_REQ",
- "INIT_XFR_SEND_PAD",
- "INIT_XFR_RECV_PAD_WAIT_REQ",
- "INIT_XFR_RECV_PAD",
- "INIT_XFR_RECV_BYTE_ACK",
- "INIT_XFR_RECV_BYTE_NACK",
- "INIT_XFR_FUNCTION_COMPLETE",
- "INIT_XFR_BUS_COMPLETE",
- "INIT_XFR_WAIT_REQ",
- "INIT_CPT_RECV_BYTE_ACK",
- "INIT_CPT_RECV_WAIT_REQ",
- "INIT_CPT_RECV_BYTE_NACK",
-};
-
enum : uint16_t {
// Arbitration
ARB_WAIT_BUS_FREE = 1,
@@ -319,24 +299,6 @@ enum : uint16_t {
RECV_WAIT_REQ_0
};
-const char *const wd33c9x_base_device::substate_names[] = {
- "-",
- "ARB_WAIT_BUS_FREE",
- "ARB_CHECK_FREE",
- "ARB_EXAMINE_BUS",
- "ARB_ASSERT_SEL",
- "ARB_SET_DEST",
- "ARB_RELEASE_BUSY",
- "ARB_TIMEOUT_BUSY",
- "ARB_TIMEOUT_ABORT",
- "ARB_DESKEW_WAIT",
- "SEND_WAIT_SETTLE",
- "SEND_WAIT_REQ_0",
- "RECV_WAIT_REQ_1",
- "RECV_WAIT_SETTLE",
- "RECV_WAIT_REQ_0",
-};
-
enum : uint16_t {
STATE_MASK = 0x00ff,
SUB_SHIFT = 8,
@@ -348,8 +310,8 @@ enum : uint16_t {
// LIVE DEVICE
//**************************************************************************
-DEFINE_DEVICE_TYPE(WD33C92, wd33c92_device, "wd33c92", "Western Digital WD33C92 SCSI Controller")
-DEFINE_DEVICE_TYPE(WD33C93, wd33c93_device, "wd33c93", "Western Digital WD33C93 SCSI Controller")
+DEFINE_DEVICE_TYPE(WD33C92, wd33c92_device, "wd33c92", "Western Digital WD33C92 SCSI Controller")
+DEFINE_DEVICE_TYPE(WD33C93N, wd33c93n_device, "wd33c93", "Western Digital WD33C93 SCSI Controller")
DEFINE_DEVICE_TYPE(WD33C93A, wd33c93a_device, "wd33c93a", "Western Digital WD33C93A SCSI Controller")
DEFINE_DEVICE_TYPE(WD33C93B, wd33c93b_device, "wd33c93b", "Western Digital WD33C93B SCSI Controller")
@@ -362,10 +324,10 @@ wd33c9x_base_device::wd33c9x_base_device(const machine_config &mconfig, device_t
, m_addr{ 0 }
, m_regs{ 0 }
, m_command_length{ 0 }
- , m_last_message{ 0 }
, m_scsi_state{ IDLE }
, m_mode{ MODE_D }
, m_xfr_phase{ 0 }
+ , m_step_count{ 0 }
, m_transfer_count{ 0 }
, m_data_fifo{ 0 }
, m_data_fifo_pos{ 0 }
@@ -393,10 +355,10 @@ void wd33c9x_base_device::device_start()
save_item(NAME(m_addr));
save_item(NAME(m_regs));
save_item(NAME(m_command_length));
- save_item(NAME(m_last_message));
save_item(NAME(m_mode));
save_item(NAME(m_scsi_state));
save_item(NAME(m_xfr_phase));
+ save_item(NAME(m_step_count));
save_item(NAME(m_transfer_count));
save_item(NAME(m_data_fifo));
save_item(NAME(m_data_fifo_pos));
@@ -422,10 +384,10 @@ void wd33c9x_base_device::device_reset()
m_regs[reg] = (QUEUE_TAG <= reg && reg <= INVALID_1E) ? 0xff : 0;
}
m_command_length = 0;
- m_last_message = 0;
set_scsi_state(IDLE);
m_mode = MODE_D;
m_xfr_phase = 0;
+ m_step_count = 0;
m_transfer_count = 0;
data_fifo_reset();
irq_fifo_reset();
@@ -470,10 +432,10 @@ void wd33c9x_base_device::scsi_ctrl_changed()
// dir_r
//-------------------------------------------------
-uint8_t wd33c9x_base_device::dir_r(offs_t offset)
+READ8_MEMBER(wd33c9x_base_device::dir_r)
{
m_addr = offset & REGS_MASK;
- return indir_reg_r();
+ return indir_reg_r(space, 0, mem_mask);
}
@@ -481,10 +443,10 @@ uint8_t wd33c9x_base_device::dir_r(offs_t offset)
// dir_w
//-------------------------------------------------
-void wd33c9x_base_device::dir_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER(wd33c9x_base_device::dir_w)
{
m_addr = offset & REGS_MASK;
- indir_reg_w(data);
+ indir_reg_w(space, 0, data, mem_mask);
}
@@ -492,15 +454,15 @@ void wd33c9x_base_device::dir_w(offs_t offset, uint8_t data)
// indir_r
//-------------------------------------------------
-uint8_t wd33c9x_base_device::indir_r(offs_t offset)
+READ8_MEMBER(wd33c9x_base_device::indir_r)
{
switch (offset) {
case 0:
- return indir_addr_r();
+ return indir_addr_r(space, 0, mem_mask);
case 1:
- return indir_reg_r();
+ return indir_reg_r(space, 0, mem_mask);
default:
- LOGMASKED(LOG_READS | LOG_ERRORS, "Read from invalid offset %d\n", offset);
+ LOGMASKED(LOG_READS | LOG_ERRORS, "%s: Read from invalid offset %d\n", shortname(), offset);
break;
}
return 0;
@@ -511,17 +473,17 @@ uint8_t wd33c9x_base_device::indir_r(offs_t offset)
// indir_w
//-------------------------------------------------
-void wd33c9x_base_device::indir_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER(wd33c9x_base_device::indir_w)
{
switch (offset) {
case 0:
- indir_addr_w(data);
+ indir_addr_w(space, 0, data, mem_mask);
break;
case 1:
- indir_reg_w(data);
+ indir_reg_w(space, 0, data, mem_mask);
break;
default:
- LOGMASKED(LOG_WRITES | LOG_ERRORS, "Write to invalid offset %d (data=%02x)\n", offset, data);
+ LOGMASKED(LOG_WRITES | LOG_ERRORS, "%s: Write to invalid offset %d (data=%02x)\n", shortname(), offset, data);
break;
}
}
@@ -531,10 +493,13 @@ void wd33c9x_base_device::indir_w(offs_t offset, uint8_t data)
// indir_addr_r
//-------------------------------------------------
-uint8_t wd33c9x_base_device::indir_addr_r()
+READ8_MEMBER(wd33c9x_base_device::indir_addr_r)
{
- // Trick to push the interrupt flag after the fifo is empty to help cps3
- return m_regs[AUXILIARY_STATUS] & 0x01 ? m_regs[AUXILIARY_STATUS] & 0x7f : m_regs[AUXILIARY_STATUS];
+ if (offset != 0) {
+ fatalerror("%s: Read from invalid address offset %d\n", shortname(), offset);
+ }
+ step(false);
+ return m_regs[AUXILIARY_STATUS];
}
@@ -542,8 +507,11 @@ uint8_t wd33c9x_base_device::indir_addr_r()
// indir_addr_w
//-------------------------------------------------
-void wd33c9x_base_device::indir_addr_w(uint8_t data)
+WRITE8_MEMBER(wd33c9x_base_device::indir_addr_w)
{
+ if (offset != 0) {
+ fatalerror("%s: Write to invalid address offset %d (data=%02x)\n", shortname(), offset, data);
+ }
m_addr = data & REGS_MASK;
}
@@ -552,11 +520,15 @@ void wd33c9x_base_device::indir_addr_w(uint8_t data)
// indir_reg_r
//-------------------------------------------------
-uint8_t wd33c9x_base_device::indir_reg_r()
+READ8_MEMBER(wd33c9x_base_device::indir_reg_r)
{
+ if (offset != 0) {
+ fatalerror("%s: Read from invalid indirect register offset %d\n", shortname(), offset);
+ }
+
uint8_t ret;
switch (m_addr) {
- case DATA: {
+ case DATA:
if (!(m_regs[AUXILIARY_STATUS] & AUXILIARY_STATUS_DBR)) {
// The processor, except in one case, should only
// access the Data Register when the DBR bit in the
@@ -567,14 +539,9 @@ uint8_t wd33c9x_base_device::indir_reg_r()
// Data Register.
fatalerror("%s: The host should never access the data register without DBR set.\n", shortname());
}
- bool was_full = data_fifo_full();
ret = data_fifo_pop();
- if (data_fifo_empty())
- m_regs[AUXILIARY_STATUS] &= ~AUXILIARY_STATUS_DBR;
- if (was_full)
- step(false);
+ m_regs[AUXILIARY_STATUS] &= ~AUXILIARY_STATUS_DBR;
break;
- }
default:
if (m_addr == OWN_ID) {
@@ -604,8 +571,12 @@ uint8_t wd33c9x_base_device::indir_reg_r()
// indir_reg_w
//-------------------------------------------------
-void wd33c9x_base_device::indir_reg_w(uint8_t data)
+WRITE8_MEMBER(wd33c9x_base_device::indir_reg_w)
{
+ if (offset != 0) {
+ fatalerror("%s: Write to invalid indirect register offset %d (data=%02x)\n", shortname(), offset, data);
+ }
+
switch (m_addr) {
case SCSI_STATUS:
case QUEUE_TAG: // Only for 92/93 and 93A
@@ -614,7 +585,7 @@ void wd33c9x_base_device::indir_reg_w(uint8_t data)
case INVALID_1D:
case INVALID_1E:
case AUXILIARY_STATUS:
- LOGMASKED(LOG_WRITES | LOG_ERRORS, "Write to read-only register address %d (data=%02x)\n", m_addr, data);
+ LOGMASKED(LOG_WRITES | LOG_ERRORS, "%s: Write to read-only register address %d (data=%02x)\n", shortname(), m_addr, data);
break;
case COMMAND: {
@@ -666,7 +637,7 @@ void wd33c9x_base_device::indir_reg_w(uint8_t data)
WRITE_LINE_MEMBER(wd33c9x_base_device::reset_w)
{
if (state) {
- LOGMASKED(LOG_LINES, "Reset via MR line\n");
+ LOGMASKED(LOG_LINES, "%s: Reset via MR line\n", shortname());
device_reset();
}
}
@@ -724,7 +695,7 @@ void wd33c9x_base_device::start_command()
switch (cc) {
case COMMAND_CC_RESET:
- LOGMASKED(LOG_COMMANDS, "Reset Command\n");
+ LOGMASKED(LOG_COMMANDS, "%s: Reset Command\n", shortname());
scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL);
m_regs[OWN_ID] = m_command_length;
@@ -738,18 +709,17 @@ void wd33c9x_base_device::start_command()
set_scsi_state(FINISHED);
irq_fifo_push((m_regs[OWN_ID] & OWN_ID_EAF) ? SCSI_STATUS_RESET_EAF : SCSI_STATUS_RESET);
scsi_id = (m_regs[OWN_ID] & OWN_ID_SCSI_ID);
- step(false);
break;
case COMMAND_CC_ABORT:
- LOGMASKED(LOG_COMMANDS, "Abort Command\n");
+ LOGMASKED(LOG_COMMANDS, "%s: Abort Command\n", shortname());
set_scsi_state(FINISHED);
// FIXME
irq_fifo_push((m_regs[OWN_ID] & OWN_ID_EAF) ? SCSI_STATUS_RESET_EAF : SCSI_STATUS_RESET);
break;
case COMMAND_CC_ASSERT_ATN:
- LOGMASKED(LOG_COMMANDS, "Assert ATN Command\n");
+ LOGMASKED(LOG_COMMANDS, "%s: Assert ATN Command\n", shortname());
if (m_mode != MODE_I) {
fatalerror("%s: ASSERT_ATN command only valid in the Initiator state.", shortname());
}
@@ -757,7 +727,7 @@ void wd33c9x_base_device::start_command()
return;
case COMMAND_CC_NEGATE_ACK:
- LOGMASKED(LOG_COMMANDS, "Negate ACK Command\n");
+ LOGMASKED(LOG_COMMANDS, "%s: Negate ACK Command\n", shortname());
// FIXME - This is causing problems, so ignore for now.
//if (m_mode != MODE_I) {
// fatalerror("NEGATE_ACK command only valid in the Initiator state.");
@@ -766,27 +736,26 @@ void wd33c9x_base_device::start_command()
return;
case COMMAND_CC_DISCONNECT:
- LOGMASKED(LOG_COMMANDS, "Disconnect Command\n");
+ LOGMASKED(LOG_COMMANDS, "%s: Disconnect Command\n", shortname());
scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL);
m_mode = MODE_D;
- set_scsi_state(IDLE);
- m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY);
+ set_scsi_state(FINISHED);
+ irq_fifo_push(SCSI_STATUS_DISCONNECT);
break;
case COMMAND_CC_SELECT:
case COMMAND_CC_SELECT_ATN:
- LOGMASKED(LOG_COMMANDS, "%s Command\n", select_strings[cc - COMMAND_CC_SELECT_ATN]);
+ LOGMASKED(LOG_COMMANDS, "%s: %s Command\n", shortname(), select_strings[cc - COMMAND_CC_SELECT_ATN]);
if (m_mode != MODE_D) {
fatalerror("Select commands only valid in the Disconnected state.");
}
set_scsi_state((ARB_WAIT_BUS_FREE << SUB_SHIFT) | DISC_SEL_ARBITRATION);
- step(false);
break;
case COMMAND_CC_SELECT_TRANSFER:
case COMMAND_CC_SELECT_ATN_TRANSFER:
- LOGMASKED(LOG_COMMANDS, "%s Command\n", select_strings[cc - COMMAND_CC_SELECT_ATN]);
+ LOGMASKED(LOG_COMMANDS, "%s: %s Command\n", shortname(), select_strings[cc - COMMAND_CC_SELECT_ATN]);
if (m_mode == MODE_D) {
set_scsi_state((ARB_WAIT_BUS_FREE << SUB_SHIFT) | DISC_SEL_ARBITRATION);
m_regs[COMMAND_PHASE] = COMMAND_PHASE_ZERO;
@@ -799,11 +768,10 @@ void wd33c9x_base_device::start_command()
}
set_command_length(cc);
load_transfer_count();
- step(false);
break;
case COMMAND_CC_TRANSFER_INFO:
- LOGMASKED(LOG_COMMANDS, "Transfer Info Command\n");
+ LOGMASKED(LOG_COMMANDS, "%s: Transfer Info Command\n", shortname());
if (m_mode != MODE_I) {
fatalerror("%s: TRANSFER_INFO command only valid in the Initiator state.", shortname());
}
@@ -819,6 +787,8 @@ void wd33c9x_base_device::start_command()
fatalerror("%s: Unimplemented command: 0x%02x", shortname(), cc);
break;
}
+
+ delay(1);
}
@@ -840,533 +810,563 @@ static const char * phase_strings[8] = {
void wd33c9x_base_device::step(bool timeout)
{
+ if (++m_step_count > 1) {
+ return;
+ }
+
const uint8_t cc = (m_regs[COMMAND] & COMMAND_CC);
const bool sat = (cc == COMMAND_CC_SELECT_TRANSFER || cc == COMMAND_CC_SELECT_ATN_TRANSFER);
- const uint32_t ctrl = scsi_bus->ctrl_r();
- const uint32_t data = scsi_bus->data_r();
-
- LOGMASKED(LOG_STEP,
- "%s: step - PHASE:%s BSY:%x SEL:%x REQ:%x ACK:%x ATN:%x RST:%x DATA:%02x (%s.%s) %s\n",
- shortname(),
- phase_strings[ctrl & S_PHASE_MASK],
- (ctrl & S_BSY) ? 1 : 0,
- (ctrl & S_SEL) ? 1 : 0,
- (ctrl & S_REQ) ? 1 : 0,
- (ctrl & S_ACK) ? 1 : 0,
- (ctrl & S_ATN) ? 1 : 0,
- (ctrl & S_RST) ? 1 : 0,
- data,
- state_names[m_scsi_state & STATE_MASK], substate_names[m_scsi_state >> SUB_SHIFT],
- (timeout) ? "timeout" : "change"
- );
-
- if (m_mode == MODE_I) {
- if (ctrl & S_BSY) {
- if (ctrl & S_REQ) {
- uint8_t xfr_phase = (ctrl & S_PHASE_MASK);
- switch (m_scsi_state) {
- case DISC_SEL_ARBITRATION:
- m_xfr_phase = xfr_phase;
- break;
+ uint32_t cycles = 0;
+ do {
+ const uint32_t ctrl = scsi_bus->ctrl_r();
+ const uint32_t data = scsi_bus->data_r();
+
+ m_step_count = 1;
+
+ LOGMASKED(LOG_STEP,
+ "%s: step - PHASE:%s BSY:%x SEL:%x REQ:%x ACK:%x ATN:%x RST:%x DATA:%x (%d.%d) %s\n",
+ shortname(),
+ phase_strings[ctrl & S_PHASE_MASK],
+ (ctrl & S_BSY) ? 1 : 0,
+ (ctrl & S_SEL) ? 1 : 0,
+ (ctrl & S_REQ) ? 1 : 0,
+ (ctrl & S_ACK) ? 1 : 0,
+ (ctrl & S_ATN) ? 1 : 0,
+ (ctrl & S_RST) ? 1 : 0,
+ data,
+ m_scsi_state & STATE_MASK, m_scsi_state >> SUB_SHIFT,
+ (timeout) ? "timeout" : "change"
+ );
- case INIT_XFR_WAIT_REQ:
- break;
+ if (m_mode == MODE_I) {
+ if (ctrl & S_BSY) {
+ if (ctrl & S_REQ) {
+ uint8_t xfr_phase = (ctrl & S_PHASE_MASK);
+ switch (m_scsi_state) {
+ case DISC_SEL_ARBITRATION:
+ m_xfr_phase = xfr_phase;
+ break;
- default:
- if (m_xfr_phase != xfr_phase) {
- fatalerror("%s: Unexpected phase change during state.\n", shortname());
+ case INIT_XFR_WAIT_REQ:
+ break;
+
+ default:
+ if (m_xfr_phase != xfr_phase) {
+ fatalerror("%s: Unexpected phase change during state.\n", shortname());
+ }
+ break;
}
- break;
}
}
- } else {
- LOGMASKED(LOG_STATE, "Target disconnected\n");
- if (sat) {
- switch (m_regs[COMMAND_PHASE]) {
- case COMMAND_PHASE_DISCONNECT_MESSAGE:
- set_scsi_state(FINISHED);
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_DISCONNECTED;
- break;
-
- case COMMAND_PHASE_COMMAND_COMPLETE:
- if (m_regs[CONTROL] & CONTROL_EDI) {
+ else {
+ LOGMASKED(LOG_STATE, "%s: Target disconnected\n", shortname());
+ if (sat) {
+ switch (m_regs[COMMAND_PHASE]) {
+ case COMMAND_PHASE_DISCONNECT_MESSAGE:
set_scsi_state(FINISHED);
- irq_fifo_push(SCSI_STATUS_SELECT_TRANSFER_SUCCESS);
- } else {
- // Makes very little sense, but the previous code did it and warzard seems to need it - XXX
- m_regs[CONTROL] |= CONTROL_EDI;
- }
- break;
+ m_regs[COMMAND_PHASE] = COMMAND_PHASE_DISCONNECTED;
+ break;
- default:
- fatalerror("%s: Unhandled command phase during Select-and-Transfer disconnect.\n", shortname());
- break;
+ case COMMAND_PHASE_COMMAND_COMPLETE:
+ if (m_regs[CONTROL] & CONTROL_EDI) {
+ set_scsi_state(FINISHED);
+ irq_fifo_push(SCSI_STATUS_SELECT_TRANSFER_SUCCESS);
+ }
+ break;
+
+ default:
+ fatalerror("%s: Unhandled command phase during Select-and-Transfer disconnect.\n", shortname());
+ break;
+ }
}
- } else {
- set_scsi_state(FINISHED);
- irq_fifo_push(SCSI_STATUS_DISCONNECT);
+ else {
+ set_scsi_state(FINISHED);
+ irq_fifo_push(SCSI_STATUS_DISCONNECT);
+ }
+ m_mode = MODE_D;
+ scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
+ scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL);
+ continue;
}
- m_mode = MODE_D;
- scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
- scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL);
}
- }
- switch (m_scsi_state & SUB_MASK ? m_scsi_state & SUB_MASK : m_scsi_state & STATE_MASK) {
- case IDLE:
- break;
+ switch (m_scsi_state & SUB_MASK ? m_scsi_state & SUB_MASK : m_scsi_state & STATE_MASK) {
+ case IDLE:
+ break;
- case FINISHED:
- set_scsi_state(IDLE);
- m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY);
- update_irq();
- break;
+ case FINISHED:
+ set_scsi_state(IDLE);
+ m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY);
+ update_irq();
+ break;
- case ARB_WAIT_BUS_FREE << SUB_SHIFT:
- if (!(ctrl & (S_BSY | S_SEL))) {
- set_scsi_state_sub(ARB_CHECK_FREE);
- delay(1);
- }
- break;
+ case ARB_WAIT_BUS_FREE << SUB_SHIFT:
+ if (timeout) {
+ if (!(ctrl & (S_BSY | S_SEL))) {
+ set_scsi_state_sub(ARB_CHECK_FREE);
+ }
+ cycles = 1;
+ }
+ break;
- case ARB_CHECK_FREE << SUB_SHIFT:
- if (ctrl & (S_BSY | S_SEL)) {
- set_scsi_state_sub(ARB_CHECK_FREE);
+ case ARB_CHECK_FREE << SUB_SHIFT:
+ if (timeout) {
+ uint8_t next_state;
+ if (ctrl & (S_BSY | S_SEL)) {
+ next_state = ARB_WAIT_BUS_FREE;
+ cycles = 1;
+ }
+ else {
+ scsi_bus->data_w(scsi_refid, 1 << scsi_id);
+ scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
+ next_state = ARB_EXAMINE_BUS;
+ cycles = 1;
+ }
+ set_scsi_state_sub(next_state);
+ }
break;
- }
- if (timeout) {
- scsi_bus->data_w(scsi_refid, 1 << scsi_id);
- scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
- set_scsi_state_sub(ARB_EXAMINE_BUS);
- delay(1);
- }
- break;
- case ARB_EXAMINE_BUS << SUB_SHIFT:
- if (timeout) {
- if (ctrl & S_SEL) {
- scsi_bus->ctrl_w(scsi_refid, 0, S_BSY);
- scsi_bus->data_w(scsi_refid, 0);
- set_scsi_state_sub(ARB_WAIT_BUS_FREE);
- } else {
- int win;
- for (win = 7; win >=0 && !(data & (1 << win)); win--);
- if (win == scsi_id) {
- scsi_bus->ctrl_w(scsi_refid, S_SEL, S_SEL);
- set_scsi_state_sub(ARB_ASSERT_SEL);
- delay(1);
- } else {
+ case ARB_EXAMINE_BUS << SUB_SHIFT:
+ if (timeout) {
+ if (ctrl & S_SEL) {
+ scsi_bus->ctrl_w(scsi_refid, 0, S_BSY);
scsi_bus->data_w(scsi_refid, 0);
- scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
- set_scsi_state_sub(ARB_CHECK_FREE);
+ set_scsi_state_sub(ARB_WAIT_BUS_FREE);
}
+ else {
+ int win;
+ for (win = 7; win >=0 && !(data & (1 << win)); win--) {};
+ if (win == scsi_id) {
+ scsi_bus->ctrl_w(scsi_refid, S_SEL, S_SEL);
+ set_scsi_state_sub(ARB_ASSERT_SEL);
+ }
+ else {
+ scsi_bus->data_w(scsi_refid, 0);
+ scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
+ }
+ }
+ cycles = 1;
}
- }
- break;
+ break;
- case ARB_ASSERT_SEL << SUB_SHIFT:
- if (timeout) {
- scsi_bus->data_w(scsi_refid, (1 << scsi_id) | (1 << (m_regs[DESTINATION_ID] & DESTINATION_ID_DI)));
- set_scsi_state_sub(ARB_SET_DEST);
- delay(1);
- }
- break;
+ case ARB_ASSERT_SEL << SUB_SHIFT:
+ if (timeout) {
+ scsi_bus->data_w(scsi_refid, (1 << scsi_id) | (1 << (m_regs[DESTINATION_ID] & DESTINATION_ID_DI)));
+ set_scsi_state_sub(ARB_SET_DEST);
+ cycles = 1;
+ }
+ break;
- case ARB_SET_DEST << SUB_SHIFT:
- if (timeout) {
- scsi_bus->ctrl_w(scsi_refid, (cc == COMMAND_CC_SELECT_ATN || cc == COMMAND_CC_SELECT_ATN_TRANSFER) ? S_ATN : 0, S_ATN | S_BSY);
- set_scsi_state_sub(ARB_RELEASE_BUSY);
- delay(1);
- }
- break;
+ case ARB_SET_DEST << SUB_SHIFT:
+ if (timeout) {
+ scsi_bus->ctrl_w(scsi_refid, (cc == COMMAND_CC_SELECT_ATN || cc == COMMAND_CC_SELECT_ATN_TRANSFER) ? S_ATN : 0, S_ATN | S_BSY);
+ set_scsi_state_sub(ARB_RELEASE_BUSY);
+ cycles = 1;
+ }
+ break;
- case ARB_RELEASE_BUSY << SUB_SHIFT:
- if (timeout) {
- if (ctrl & S_BSY) {
- set_scsi_state_sub(ARB_DESKEW_WAIT);
- if (cc == COMMAND_CC_RESELECT) {
- scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
+ case ARB_RELEASE_BUSY << SUB_SHIFT:
+ if (timeout) {
+ if (ctrl & S_BSY) {
+ set_scsi_state_sub(ARB_DESKEW_WAIT);
+ if (cc == COMMAND_CC_RESELECT) {
+ scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
+ }
+ cycles = 1;
+ }
+ else {
+ set_scsi_state_sub(ARB_TIMEOUT_BUSY);
+ cycles = 1;
}
- delay(1);
- } else {
- set_scsi_state_sub(ARB_TIMEOUT_BUSY);
- delay(1); // Should be the select timeout...
}
- }
- break;
-
- case ARB_DESKEW_WAIT << SUB_SHIFT:
- if (timeout) {
- scsi_bus->data_w(scsi_refid, 0);
- scsi_bus->ctrl_w(scsi_refid, 0, S_SEL);
- m_mode = (cc == COMMAND_CC_RESELECT) ? MODE_T : MODE_I;
- set_scsi_state_sub(0);
- step(true);
- }
- break;
+ break;
- case ARB_TIMEOUT_BUSY << SUB_SHIFT:
- if (timeout) {
- scsi_bus->data_w(scsi_refid, 0);
- set_scsi_state_sub(ARB_TIMEOUT_ABORT);
- delay(1000);
- } else if (ctrl & S_BSY) {
- set_scsi_state_sub(ARB_DESKEW_WAIT);
- if (cc == COMMAND_CC_RESELECT) {
- scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
+ case ARB_DESKEW_WAIT << SUB_SHIFT:
+ if (timeout) {
+ scsi_bus->data_w(scsi_refid, 0);
+ scsi_bus->ctrl_w(scsi_refid, 0, S_SEL);
+ m_mode = (cc == COMMAND_CC_RESELECT) ? MODE_T : MODE_I;
+ set_scsi_state_sub(0);
+ ++m_step_count;
}
- delay(1);
- }
- break;
+ break;
- case ARB_TIMEOUT_ABORT << SUB_SHIFT:
- if (timeout) {
- if (ctrl & S_BSY) {
+ case ARB_TIMEOUT_BUSY << SUB_SHIFT:
+ if (timeout) {
+ scsi_bus->data_w(scsi_refid, 0);
+ set_scsi_state_sub(ARB_TIMEOUT_ABORT);
+ cycles = 1000;
+ }
+ else if (ctrl & S_BSY) {
set_scsi_state_sub(ARB_DESKEW_WAIT);
if (cc == COMMAND_CC_RESELECT) {
scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
}
- delay(1);
- } else {
- scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
- scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL);
- m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY);
- m_mode = MODE_D;
- set_scsi_state(IDLE);
- irq_fifo_push(SCSI_STATUS_SELECTION_TIMEOUT);
- update_irq();
+ cycles = 1;
}
- }
- break;
+ break;
- case SEND_WAIT_SETTLE << SUB_SHIFT:
- if (timeout) {
- set_scsi_state_sub(SEND_WAIT_REQ_0);
- step(false);
- }
- break;
+ case ARB_TIMEOUT_ABORT << SUB_SHIFT:
+ if (timeout) {
+ if (ctrl & S_BSY) {
+ set_scsi_state_sub(ARB_DESKEW_WAIT);
+ if (cc == COMMAND_CC_RESELECT) {
+ scsi_bus->ctrl_w(scsi_refid, S_BSY, S_BSY);
+ }
+ cycles = 1;
+ }
+ else {
+ scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
+ scsi_bus->ctrl_wait(scsi_refid, S_SEL|S_BSY|S_RST, S_ALL);
+ m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY);
+ m_mode = MODE_D;
+ set_scsi_state(IDLE);
+ irq_fifo_push(SCSI_STATUS_SELECTION_TIMEOUT);
+ update_irq();
+ }
+ }
+ break;
- case SEND_WAIT_REQ_0 << SUB_SHIFT:
- if (!(ctrl & S_REQ)) {
- set_scsi_state_sub(0);
- scsi_bus->data_w(scsi_refid, 0);
- scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
- if (sat) {
- switch (m_xfr_phase) {
- case S_PHASE_COMMAND:
- ++m_regs[COMMAND_PHASE];
- break;
+ case SEND_WAIT_SETTLE << SUB_SHIFT:
+ if (timeout) {
+ set_scsi_state_sub(SEND_WAIT_REQ_0);
+ ++m_step_count;
+ }
+ break;
+
+ case SEND_WAIT_REQ_0 << SUB_SHIFT:
+ if (!(ctrl & S_REQ)) {
+ set_scsi_state_sub(0);
+ scsi_bus->data_w(scsi_refid, 0);
+ scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
+ if (sat) {
+ switch (m_xfr_phase) {
+ case S_PHASE_COMMAND:
+ ++m_regs[COMMAND_PHASE];
+ break;
+ }
}
+ ++m_step_count;
}
- step(false);
- }
- break;
+ break;
- case RECV_WAIT_REQ_1 << SUB_SHIFT:
- if (ctrl & S_REQ) {
- set_scsi_state_sub(RECV_WAIT_SETTLE);
- delay(1);
- }
- break;
+ case RECV_WAIT_REQ_1 << SUB_SHIFT:
+ if (ctrl & S_REQ) {
+ set_scsi_state_sub(RECV_WAIT_SETTLE);
+ cycles = 1;
+ }
+ break;
- case RECV_WAIT_SETTLE << SUB_SHIFT:
- if (timeout) {
- if (sat) {
- switch (m_xfr_phase) {
- case S_PHASE_DATA_IN:
+ case RECV_WAIT_SETTLE << SUB_SHIFT:
+ if (timeout) {
+ if (sat) {
+ switch (m_xfr_phase) {
+ case S_PHASE_DATA_IN:
+ data_fifo_push(data);
+ if ((m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) {
+ set_drq();
+ }
+ else {
+ decrement_transfer_count();
+ m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
+ }
+ break;
+
+ case S_PHASE_STATUS:
+ m_regs[TARGET_LUN] = data;
+ m_regs[COMMAND_PHASE] = COMMAND_PHASE_STATUS_RECEIVED;
+ break;
+
+ case S_PHASE_MSG_IN:
+ data_fifo_push(data);
+ break;
+
+ default:
+ fatalerror("%s: Unexpected phase in RECV_WAIT_SETTLE.\n", shortname());
+ break;
+ }
+ }
+ else {
data_fifo_push(data);
- if ((m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) {
+ if (m_xfr_phase == S_PHASE_DATA_IN && (m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) {
set_drq();
- } else {
+ }
+ else {
decrement_transfer_count();
m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
}
- break;
-
- case S_PHASE_STATUS:
- m_regs[TARGET_LUN] = data;
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_STATUS_RECEIVED;
- break;
-
- case S_PHASE_MSG_IN:
- m_last_message = data;
- break;
-
- default:
- fatalerror("%s: Unexpected phase in RECV_WAIT_SETTLE.\n", shortname());
- break;
- }
- } else {
- data_fifo_push(data);
- if (m_xfr_phase == S_PHASE_DATA_IN && (m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) {
- set_drq();
- } else {
- decrement_transfer_count();
- m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
}
+ set_scsi_state_sub(RECV_WAIT_REQ_0);
+ scsi_bus->ctrl_w(scsi_refid, S_ACK, S_ACK);
+ ++m_step_count;
}
- set_scsi_state_sub(RECV_WAIT_REQ_0);
- scsi_bus->ctrl_w(scsi_refid, S_ACK, S_ACK);
- step(false);
- }
- break;
-
- case RECV_WAIT_REQ_0 << SUB_SHIFT:
- if (!(ctrl & S_REQ)) {
- set_scsi_state_sub(0);
- step(false);
- }
- break;
+ break;
- case DISC_SEL_ARBITRATION:
- scsi_bus->ctrl_wait(scsi_refid, S_REQ, S_REQ);
- if (cc == COMMAND_CC_SELECT || cc == COMMAND_CC_SELECT_ATN) {
- set_scsi_state(FINISHED);
- irq_fifo_push(SCSI_STATUS_SELECT_SUCCESS);
- if (ctrl & S_REQ) {
- irq_fifo_push(SCSI_STATUS_REQ | m_xfr_phase);
+ case RECV_WAIT_REQ_0 << SUB_SHIFT:
+ if (!(ctrl & S_REQ)) {
+ set_scsi_state_sub(0);
+ ++m_step_count;
}
- } else {
- if(cc == COMMAND_CC_SELECT_TRANSFER) {
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_CP_BYTES_0;
- std::string cmd;
- for (uint8_t i = 0; i < m_command_length; ++i) {
- const uint8_t command_byte = m_regs[CDB_1 + i];
- cmd += util::string_format(" %02x", command_byte);
- data_fifo_push(command_byte);
+ break;
+
+ case DISC_SEL_ARBITRATION:
+ scsi_bus->ctrl_wait(scsi_refid, S_REQ, S_REQ);
+ if (cc == COMMAND_CC_SELECT || cc == COMMAND_CC_SELECT_ATN) {
+ set_scsi_state(FINISHED);
+ irq_fifo_push(SCSI_STATUS_SELECT_SUCCESS);
+ if (ctrl & S_REQ) {
+ irq_fifo_push(SCSI_STATUS_REQ | m_xfr_phase);
}
- LOGMASKED(LOG_COMMANDS, "Sending command:%s (%d)\n", cmd, m_transfer_count);
- } else
+ }
+ else {
+ set_scsi_state(INIT_XFR);
m_regs[COMMAND_PHASE] = COMMAND_PHASE_SELECTED;
- set_scsi_state(INIT_XFR);
- }
- step(false);
- break;
+ }
+ ++m_step_count;
+ break;
- case INIT_XFR:
- if (ctrl & S_REQ) {
- switch (m_xfr_phase) {
- case S_PHASE_DATA_OUT:
- if ((m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) {
- if(!data_fifo_full() && m_transfer_count > 0)
- set_drq();
- }
- if (!data_fifo_empty()) {
- set_scsi_state(INIT_XFR_WAIT_REQ);
- delay(send_byte());
- } else if ((m_regs[CONTROL] & CONTROL_DM) == CONTROL_DM_POLLED) {
- m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
- }
- break;
+ case INIT_XFR:
+ if (ctrl & S_REQ) {
+ switch (m_xfr_phase) {
+ case S_PHASE_DATA_OUT:
+ if ((m_regs[CONTROL] & CONTROL_DM) != CONTROL_DM_POLLED) {
+ while (!data_fifo_full() && m_transfer_count > 0) {
+ set_drq();
+ }
+ }
+ if (!data_fifo_empty()) {
+ set_scsi_state(INIT_XFR_WAIT_REQ);
+ cycles = send_byte();
+ }
+ else if ((m_regs[CONTROL] & CONTROL_DM) == CONTROL_DM_POLLED) {
+ m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
+ }
+ break;
- case S_PHASE_COMMAND:
- if (!data_fifo_empty()) {
- uint32_t mask;
- if (sat) {
- mask = 0;
- } else {
+ case S_PHASE_COMMAND:
+ if (!data_fifo_empty()) {
+ uint32_t mask;
+ if (sat) {
+ mask = 0;
+ }
+ else {
+ m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
+ mask = (m_transfer_count == 0 && m_data_fifo_size == 1) ? S_ATN : 0;
+ }
+ set_scsi_state(INIT_XFR_WAIT_REQ);
+ cycles = send_byte(0, mask);
+ }
+ else if (!sat) {
m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
- mask = (m_transfer_count == 0 && m_data_fifo_size == 1) ? S_ATN : 0;
}
- set_scsi_state(INIT_XFR_WAIT_REQ);
- delay(send_byte(0, mask));
- } else if (!sat) {
- m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
- }
- break;
+ break;
- case S_PHASE_MSG_OUT:
- if (sat) {
- data_fifo_push(get_msg_out());
- }
- if (!data_fifo_empty()) {
- uint32_t mask;
+ case S_PHASE_MSG_OUT:
if (sat) {
- mask = S_ATN;
- } else {
+ data_fifo_push(get_msg_out());
+ }
+ if (!data_fifo_empty()) {
+ uint32_t mask;
+ if (sat) {
+ mask = S_ATN;
+ }
+ else {
+ m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
+ mask = (m_transfer_count == 0 && m_data_fifo_size == 1) ? S_ATN : 0;
+ }
+ set_scsi_state(INIT_XFR_WAIT_REQ);
+ cycles = send_byte(0, mask);
+ }
+ else if (!sat) {
m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
- mask = (m_transfer_count == 0 && m_data_fifo_size == 1) ? S_ATN : 0;
}
- set_scsi_state(INIT_XFR_WAIT_REQ);
- delay(send_byte(0, mask));
- } else if (!sat) {
- m_regs[AUXILIARY_STATUS] |= AUXILIARY_STATUS_DBR;
- }
- break;
+ break;
- case S_PHASE_DATA_IN:
- case S_PHASE_STATUS:
- case S_PHASE_MSG_IN:
- if (!data_fifo_full()) {
- // if it's the last message byte, ACK remains asserted, terminate with function_complete()
- //state = (m_xfr_phase == S_PHASE_MSG_IN && (!dma_command || tcounter == 1)) ? INIT_XFR_RECV_BYTE_NACK : INIT_XFR_RECV_BYTE_ACK;
- scsi_bus->ctrl_wait(scsi_refid, S_REQ, S_REQ);
- set_scsi_state((RECV_WAIT_REQ_1 << SUB_SHIFT) | INIT_XFR_RECV_BYTE_ACK);
- step(false);
- }
- break;
+ case S_PHASE_DATA_IN:
+ case S_PHASE_STATUS:
+ case S_PHASE_MSG_IN:
+ if (!data_fifo_full()) {
+ // if it's the last message byte, ACK remains asserted, terminate with function_complete()
+ //state = (m_xfr_phase == S_PHASE_MSG_IN && (!dma_command || tcounter == 1)) ? INIT_XFR_RECV_BYTE_NACK : INIT_XFR_RECV_BYTE_ACK;
+ scsi_bus->ctrl_wait(scsi_refid, S_REQ, S_REQ);
+ set_scsi_state((RECV_WAIT_REQ_1 << SUB_SHIFT) | INIT_XFR_RECV_BYTE_ACK);
+ if (ctrl & S_REQ) {
+ ++m_step_count;
+ }
+ }
+ break;
- default:
- fatalerror("%s: Invalid phase during INIT_XFR.\n", shortname());
- break;
+ default:
+ fatalerror("%s: Invalid phase during INIT_XFR.\n", shortname());
+ break;
+ }
}
- }
- break;
+ break;
- case INIT_XFR_WAIT_REQ:
- if (ctrl & S_REQ) {
- uint16_t next_state = m_scsi_state;
+ case INIT_XFR_WAIT_REQ:
+ if (ctrl & S_REQ) {
+ uint16_t next_state = m_scsi_state;
- const uint8_t xfr_phase = (ctrl & S_PHASE_MASK);
+ const uint8_t xfr_phase = (ctrl & S_PHASE_MASK);
- switch ((m_xfr_phase << 3) | xfr_phase) {
- case ((S_PHASE_MSG_OUT << 3) | S_PHASE_MSG_OUT):
- case ((S_PHASE_COMMAND << 3) | S_PHASE_COMMAND):
- case ((S_PHASE_MSG_IN << 3) | S_PHASE_MSG_IN):
- next_state = INIT_XFR;
- break;
+ switch ((m_xfr_phase << 3) | xfr_phase) {
+ case ((S_PHASE_MSG_OUT << 3) | S_PHASE_MSG_OUT):
+ case ((S_PHASE_COMMAND << 3) | S_PHASE_COMMAND):
+ case ((S_PHASE_MSG_IN << 3) | S_PHASE_MSG_IN):
+ next_state = INIT_XFR;
+ break;
- case ((S_PHASE_DATA_IN << 3) | S_PHASE_DATA_IN):
- case ((S_PHASE_DATA_OUT << 3) | S_PHASE_DATA_OUT):
- if (sat || cc == COMMAND_CC_TRANSFER_INFO) {
- if (m_transfer_count > 0 || (m_xfr_phase == S_PHASE_DATA_OUT && !data_fifo_empty())) {
- next_state = INIT_XFR;
+ case ((S_PHASE_DATA_IN << 3) | S_PHASE_DATA_IN):
+ case ((S_PHASE_DATA_OUT << 3) | S_PHASE_DATA_OUT):
+ if (sat || cc == COMMAND_CC_TRANSFER_INFO) {
+ if (m_transfer_count > 0 || (m_xfr_phase == S_PHASE_DATA_OUT && !data_fifo_empty())) {
+ next_state = INIT_XFR;
+ }
+ else {
+ next_state = FINISHED;
+ uint8_t scsi_status;
+ if (sat) {
+ m_regs[COMMAND_PHASE] = COMMAND_PHASE_TRANSFER_COUNT;
+ scsi_status = SCSI_STATUS_UNEXPECTED_PHASE;
+ }
+ else {
+ scsi_status = SCSI_STATUS_TRANSFER_SUCCESS;
+ }
+ irq_fifo_push(scsi_status | m_xfr_phase);
+ }
}
else {
+ fatalerror("%s: Unhandled command in data phase.\n", shortname());
next_state = FINISHED;
- uint8_t scsi_status;
- if (sat) {
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_TRANSFER_COUNT;
- scsi_status = SCSI_STATUS_UNEXPECTED_PHASE;
- }
- else {
- scsi_status = SCSI_STATUS_TRANSFER_SUCCESS;
+ }
+ break;
+
+ case ((S_PHASE_MSG_OUT << 3) | S_PHASE_COMMAND):
+ case ((S_PHASE_COMMAND << 3) | S_PHASE_DATA_OUT):
+ case ((S_PHASE_COMMAND << 3) | S_PHASE_DATA_IN):
+ case ((S_PHASE_COMMAND << 3) | S_PHASE_STATUS):
+ case ((S_PHASE_COMMAND << 3) | S_PHASE_MSG_IN):
+ case ((S_PHASE_DATA_OUT << 3) | S_PHASE_STATUS):
+ case ((S_PHASE_DATA_IN << 3) | S_PHASE_STATUS):
+ case ((S_PHASE_STATUS << 3) | S_PHASE_MSG_IN):
+ if (!(m_xfr_phase & 1) && !data_fifo_empty()) {
+ fatalerror("%s: Data FIFO is not empty on phase transition.\n", shortname());
+ }
+
+ if (sat) {
+ switch (xfr_phase) {
+ case S_PHASE_MSG_OUT:
+ next_state = INIT_XFR;
+ break;
+
+ case S_PHASE_COMMAND:
+ next_state = INIT_XFR;
+ m_regs[COMMAND_PHASE] = COMMAND_PHASE_CP_BYTES_0;
+ LOGMASKED(LOG_COMMANDS, "%s: Sending Command:", shortname());
+ for (uint8_t i = 0; i < m_command_length; ++i) {
+ const uint8_t command_byte = m_regs[CDB_1 + i];
+ LOGMASKED(LOG_COMMANDS, " %02x", command_byte);
+ data_fifo_push(command_byte);
+ }
+ LOGMASKED(LOG_COMMANDS, " (%d)\n", m_transfer_count);
+ break;
+
+ case S_PHASE_DATA_OUT:
+ case S_PHASE_DATA_IN:
+ next_state = INIT_XFR;
+ break;
+
+ case S_PHASE_STATUS:
+ next_state = INIT_XFR;
+ m_regs[COMMAND_PHASE] = COMMAND_PHASE_RECEIVE_STATUS;
+ break;
+
+ case S_PHASE_MSG_IN:
+ next_state = INIT_XFR;
+ break;
+
+ default:
+ fatalerror("%s: Unhandled phase in Select-w/Atn-and-Transfer.\n", shortname());
+ next_state = FINISHED;
+ break;
}
- irq_fifo_push(scsi_status | m_xfr_phase);
}
- }
- else {
- fatalerror("%s: Unhandled command in data phase.\n", shortname());
+ else if (cc == COMMAND_CC_TRANSFER_INFO) {
+ next_state = FINISHED;
+ irq_fifo_push(SCSI_STATUS_TRANSFER_SUCCESS | xfr_phase);
+ }
+ else {
+ fatalerror("%s: Unhandled command in data phase.\n", shortname());
+ next_state = FINISHED;
+ }
+ break;
+
+ default:
+ fatalerror("%s: Unhandled phase transition in INIT_XFR_WAIT_REQ.\n", shortname());
next_state = FINISHED;
+ break;
}
- break;
- case ((S_PHASE_MSG_OUT << 3) | S_PHASE_COMMAND):
- case ((S_PHASE_COMMAND << 3) | S_PHASE_DATA_OUT):
- case ((S_PHASE_COMMAND << 3) | S_PHASE_DATA_IN):
- case ((S_PHASE_COMMAND << 3) | S_PHASE_STATUS):
- case ((S_PHASE_COMMAND << 3) | S_PHASE_MSG_IN):
- case ((S_PHASE_DATA_OUT << 3) | S_PHASE_STATUS):
- case ((S_PHASE_DATA_IN << 3) | S_PHASE_STATUS):
- case ((S_PHASE_STATUS << 3) | S_PHASE_MSG_IN):
- if (!(m_xfr_phase & 1) && !data_fifo_empty()) {
- fatalerror("%s: Data FIFO is not empty on phase transition.\n", shortname());
+ if (next_state != m_scsi_state) {
+ set_scsi_state(next_state);
+ ++m_step_count;
+ m_xfr_phase = xfr_phase;
}
+ }
+ break;
- if (sat) {
- switch (xfr_phase) {
- case S_PHASE_MSG_OUT:
- next_state = INIT_XFR;
- break;
-
- case S_PHASE_COMMAND: {
- next_state = INIT_XFR;
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_CP_BYTES_0;
- std::string cmd;
- for (uint8_t i = 0; i < m_command_length; ++i) {
- const uint8_t command_byte = m_regs[CDB_1 + i];
- cmd += util::string_format(" %02x", command_byte);
- data_fifo_push(command_byte);
- }
- LOGMASKED(LOG_COMMANDS, "Sending command:%s (%d)\n", cmd, m_transfer_count);
+ case INIT_XFR_RECV_BYTE_ACK:
+ if (sat && m_xfr_phase == S_PHASE_MSG_IN) {
+ const uint8_t msg = data_fifo_pop();
+ if (m_regs[COMMAND_PHASE] <= COMMAND_PHASE_CP_BYTES_C) {
+ switch (msg) {
+ case SM_SAVE_DATA_PTR:
+ set_scsi_state(FINISHED);
+ irq_fifo_push(SCSI_STATUS_SAVE_DATA_POINTERS);
+ m_regs[COMMAND_PHASE] = COMMAND_PHASE_SAVE_DATA_POINTER;
break;
- }
- case S_PHASE_DATA_OUT:
- case S_PHASE_DATA_IN:
- next_state = INIT_XFR;
+ case SM_DISCONNECT:
+ m_regs[COMMAND_PHASE] = COMMAND_PHASE_DISCONNECT_MESSAGE;
break;
- case S_PHASE_STATUS:
- next_state = INIT_XFR;
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_RECEIVE_STATUS;
+ default:
+ fatalerror("%s: Unhandled MSG_IN.\n", shortname());
break;
-
- case S_PHASE_MSG_IN:
- next_state = INIT_XFR;
+ }
+ }
+ else if (m_regs[COMMAND_PHASE] < COMMAND_PHASE_COMMAND_COMPLETE) {
+ switch (msg) {
+ case SM_COMMAND_COMPLETE:
+ set_scsi_state(FINISHED);
+ irq_fifo_push(SCSI_STATUS_SELECT_TRANSFER_SUCCESS);
+ m_regs[COMMAND_PHASE] = COMMAND_PHASE_COMMAND_COMPLETE;
break;
-
default:
- fatalerror("%s: Unhandled phase in Select-w/Atn-and-Transfer.\n", shortname());
- next_state = FINISHED;
+ fatalerror("%s: Unhandled MSG_IN.\n", shortname());
break;
}
}
- else if (cc == COMMAND_CC_TRANSFER_INFO) {
- next_state = FINISHED;
- irq_fifo_push(SCSI_STATUS_TRANSFER_SUCCESS | xfr_phase);
- }
- else {
- fatalerror("%s: Unhandled command in data phase.\n", shortname());
- next_state = FINISHED;
- }
- break;
-
- default:
- fatalerror("%s: Unhandled phase transition in INIT_XFR_WAIT_REQ.\n", shortname());
- next_state = FINISHED;
- break;
}
-
- if (next_state != m_scsi_state) {
- set_scsi_state(next_state);
- m_xfr_phase = xfr_phase;
- step(false);
+ else {
+ set_scsi_state(INIT_XFR_WAIT_REQ);
}
- }
- break;
+ scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
+ ++m_step_count;
+ break;
- case INIT_XFR_RECV_BYTE_ACK:
- if (sat && m_xfr_phase == S_PHASE_MSG_IN) {
- if (m_regs[COMMAND_PHASE] <= COMMAND_PHASE_CP_BYTES_C) {
- switch (m_last_message) {
- case SM_SAVE_DATA_PTR:
- set_scsi_state(FINISHED);
- irq_fifo_push(SCSI_STATUS_SAVE_DATA_POINTERS);
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_SAVE_DATA_POINTER;
- break;
+ default:
+ fatalerror("%s: Unhandled state in step.\n", shortname());
+ break;
+ }
- case SM_DISCONNECT:
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_DISCONNECT_MESSAGE;
- break;
+ timeout = false;
- default:
- fatalerror("%s: Unhandled MSG_IN %02x.\n", shortname(), m_last_message);
- break;
- }
- } else if (m_regs[COMMAND_PHASE] < COMMAND_PHASE_COMMAND_COMPLETE) {
- switch (m_last_message) {
- case SM_COMMAND_COMPLETE:
- set_scsi_state(FINISHED);
- irq_fifo_push(SCSI_STATUS_SELECT_TRANSFER_SUCCESS);
- m_regs[COMMAND_PHASE] = COMMAND_PHASE_COMMAND_COMPLETE;
- break;
- default:
- fatalerror("%s: Unhandled MSG_IN %02x.\n", shortname(), m_last_message);
- break;
- }
- }
- } else {
- set_scsi_state(INIT_XFR_WAIT_REQ);
- }
- scsi_bus->ctrl_w(scsi_refid, 0, S_ACK);
- step(false);
- break;
+ } while (--m_step_count);
- default:
- fatalerror("%s: Unhandled state in step.\n", shortname());
- break;
+ if (cycles) {
+ delay(cycles);
}
}
@@ -1390,7 +1390,7 @@ void wd33c9x_base_device::load_transfer_count()
m_transfer_count = 1;
}
}
- LOGMASKED(LOG_COMMANDS, "Transfer Count %d bytes\n", m_transfer_count);
+ LOGMASKED(LOG_COMMANDS, "%s: Transfer Count %d bytes\n", shortname(), m_transfer_count);
}
@@ -1499,9 +1499,7 @@ uint32_t wd33c9x_base_device::send_byte(const uint32_t value, const uint32_t mas
void wd33c9x_base_device::set_scsi_state(uint16_t state)
{
- LOGMASKED(LOG_STEP, "SCSI state change: %s.%s to %s.%s\n",
- state_names[m_scsi_state & STATE_MASK], substate_names[m_scsi_state >> SUB_SHIFT],
- state_names[state & STATE_MASK], substate_names[state >> SUB_SHIFT]);
+ LOGMASKED(LOG_STEP, "%s: SCSI state change: %x to %x\n", shortname(), m_scsi_state, state);
m_scsi_state = state;
}
@@ -1590,7 +1588,7 @@ void wd33c9x_base_device::update_irq()
{
if (m_regs[AUXILIARY_STATUS] & AUXILIARY_STATUS_INT) {
m_regs[AUXILIARY_STATUS] &= ~AUXILIARY_STATUS_INT;
- LOGMASKED(LOG_LINES, "Clearing IRQ\n");
+ LOGMASKED(LOG_LINES, "%s: Clearing IRQ\n", shortname());
m_irq_cb(CLEAR_LINE);
}
if (!irq_fifo_empty()) {
@@ -1614,7 +1612,7 @@ void wd33c9x_base_device::update_irq()
}
}
- LOGMASKED(LOG_LINES, "Asserting IRQ - SCSI Status (%02x)\n", m_regs[SCSI_STATUS]);
+ LOGMASKED(LOG_LINES, "%s: Asserting IRQ - SCSI Status (%02x)\n", shortname(), m_regs[SCSI_STATUS]);
m_irq_cb(ASSERT_LINE);
}
}
@@ -1627,7 +1625,7 @@ void wd33c9x_base_device::update_irq()
void wd33c9x_base_device::set_drq()
{
if (!m_drq_state) {
- LOGMASKED(LOG_LINES, "Asserting DRQ\n");
+ LOGMASKED(LOG_LINES, "%s: Asserting DRQ\n", shortname());
m_drq_state = true;
m_drq_cb(ASSERT_LINE);
}
@@ -1641,7 +1639,7 @@ void wd33c9x_base_device::set_drq()
void wd33c9x_base_device::clear_drq()
{
if (m_drq_state) {
- LOGMASKED(LOG_LINES, "Clearing DRQ\n");
+ LOGMASKED(LOG_LINES, "%s: Clearing DRQ\n", shortname());
m_drq_state = false;
m_drq_cb(CLEAR_LINE);
}
@@ -1680,13 +1678,15 @@ bool wd33c9x_base_device::set_command_length(const uint8_t cc)
if (eaf && (cc == COMMAND_CC_SELECT_TRANSFER || cc == COMMAND_CC_SELECT_ATN_TRANSFER)) {
m_command_length &= OWN_ID_CDB_SIZE;
ret = true;
- } else if (eaf && cc == COMMAND_CC_WAIT_SELECT_RECEIVE_DATA) {
+ }
+ else if (eaf && cc == COMMAND_CC_WAIT_SELECT_RECEIVE_DATA) {
m_command_length = 6;
m_regs[COMMAND_PHASE] = COMMAND_PHASE_CP_BYTES_1;
irq_fifo_push(SCSI_STATUS_NEED_COMMAND_SIZE);
update_irq();
ret = false;
- } else {
+ }
+ else {
switch (m_regs[CDB_1] >> 5) {
default:
case 0: m_command_length = 6; break;
@@ -1695,7 +1695,7 @@ bool wd33c9x_base_device::set_command_length(const uint8_t cc)
}
ret = true;
}
- LOGMASKED(LOG_COMMANDS, "SCSI Command Length %d bytes\n", m_command_length);
+ LOGMASKED(LOG_COMMANDS, "%s: SCSI Command Length %d bytes\n", shortname(), m_command_length);
return ret;
}
@@ -1715,8 +1715,8 @@ wd33c92_device::wd33c92_device(const machine_config &mconfig, const char *tag, d
{
}
-wd33c93_device::wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : wd33c9x_base_device(mconfig, WD33C93, tag, owner, clock)
+wd33c93n_device::wd33c93n_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : wd33c9x_base_device(mconfig, WD33C93N, tag, owner, clock)
{
}
diff --git a/src/devices/machine/wd33c9x.h b/src/devices/machine/wd33c9x.h
index 65e97852e00..d5f3b5a5da4 100644
--- a/src/devices/machine/wd33c9x.h
+++ b/src/devices/machine/wd33c9x.h
@@ -18,18 +18,18 @@ public:
auto drq_cb() { return m_drq_cb.bind(); }
// Direct Addressing Interface
- uint8_t dir_r(offs_t offset);
- void dir_w(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(dir_r);
+ DECLARE_WRITE8_MEMBER(dir_w);
// Indirect Addressing Interface
- uint8_t indir_r(offs_t offset);
- void indir_w(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(indir_r);
+ DECLARE_WRITE8_MEMBER(indir_w);
// Alternative Indirect Addressing Interface
- uint8_t indir_addr_r();
- void indir_addr_w(uint8_t data);
- uint8_t indir_reg_r();
- void indir_reg_w(uint8_t data);
+ DECLARE_READ8_MEMBER(indir_addr_r);
+ DECLARE_WRITE8_MEMBER(indir_addr_w);
+ DECLARE_READ8_MEMBER(indir_reg_r);
+ DECLARE_WRITE8_MEMBER(indir_reg_w);
// Master Reset (MR) Interface
DECLARE_WRITE_LINE_MEMBER(reset_w);
@@ -48,14 +48,11 @@ protected:
virtual void scsi_ctrl_changed() override;
private:
- static const char *const state_names[];
- static const char *const substate_names[];
static constexpr uint8_t NUM_REGS = 0x20;
static constexpr uint8_t REGS_MASK = NUM_REGS - 1;
uint8_t m_addr;
uint8_t m_regs[NUM_REGS];
uint8_t m_command_length;
- uint8_t m_last_message;
void start_command();
@@ -65,6 +62,7 @@ private:
uint16_t m_scsi_state;
uint8_t m_mode;
uint8_t m_xfr_phase;
+ uint8_t m_step_count;
void load_transfer_count();
bool decrement_transfer_count();
@@ -119,15 +117,15 @@ public:
wd33c92_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
-class wd33c93_device : public wd33c9x_base_device
+class wd33c93n_device : public wd33c9x_base_device
{
public:
- wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner)
- : wd33c93_device(mconfig, tag, owner, 0)
+ wd33c93n_device(const machine_config &mconfig, const char *tag, device_t *owner)
+ : wd33c93n_device(mconfig, tag, owner, 0)
{
}
- wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ wd33c93n_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
class wd33c93a_device : public wd33c9x_base_device
@@ -153,8 +151,8 @@ public:
};
-DECLARE_DEVICE_TYPE(WD33C92, wd33c92_device)
-DECLARE_DEVICE_TYPE(WD33C93, wd33c93_device)
+DECLARE_DEVICE_TYPE(WD33C92, wd33c92_device)
+DECLARE_DEVICE_TYPE(WD33C93N, wd33c93n_device)
DECLARE_DEVICE_TYPE(WD33C93A, wd33c93a_device)
DECLARE_DEVICE_TYPE(WD33C93B, wd33c93b_device)
diff --git a/src/devices/machine/wd7600.cpp b/src/devices/machine/wd7600.cpp
index 373c371cb5f..9c018fede8e 100644
--- a/src/devices/machine/wd7600.cpp
+++ b/src/devices/machine/wd7600.cpp
@@ -159,46 +159,46 @@ void wd7600_device::device_start()
if (m_space_io->data_width() == 16)
{
// FIXME: are all these address ranges correct?
- m_space_io->install_readwrite_handler(0x0000, 0x000f, read8sm_delegate(FUNC(am9517a_device::read), &(*m_dma1)), write8sm_delegate(FUNC(am9517a_device::write), &(*m_dma1)), 0xffff);
+ m_space_io->install_readwrite_handler(0x0000, 0x000f, read8_delegate(FUNC(am9517a_device::read), &(*m_dma1)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma1)), 0xffff);
m_space_io->install_readwrite_handler(0x0020, 0x003f, read8sm_delegate(FUNC(pic8259_device::read), &(*m_pic1)), write8sm_delegate(FUNC(pic8259_device::write), &(*m_pic1)), 0xffff);
m_space_io->install_readwrite_handler(0x0040, 0x0043, read8sm_delegate(FUNC(pit8254_device::read), &(*m_ctc)), write8sm_delegate(FUNC(pit8254_device::write), &(*m_ctc)), 0xffff);
- m_space_io->install_readwrite_handler(0x0060, 0x0061, read8smo_delegate(FUNC(wd7600_device::keyb_data_r), this), write8smo_delegate(FUNC(wd7600_device::keyb_data_w), this), 0x00ff);
- m_space_io->install_readwrite_handler(0x0060, 0x0061, read8smo_delegate(FUNC(wd7600_device::portb_r), this), write8smo_delegate(FUNC(wd7600_device::portb_w), this), 0xff00);
- m_space_io->install_readwrite_handler(0x0064, 0x0065, read8smo_delegate(FUNC(wd7600_device::keyb_status_r), this), write8smo_delegate(FUNC(wd7600_device::keyb_cmd_w), this), 0x00ff);
- m_space_io->install_readwrite_handler(0x0070, 0x007f, read8sm_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8sm_delegate(FUNC(wd7600_device::rtc_w), this), 0xffff);
- m_space_io->install_readwrite_handler(0x0080, 0x008f, read8sm_delegate(FUNC(wd7600_device::dma_page_r), this), write8sm_delegate(FUNC(wd7600_device::dma_page_w), this), 0xffff);
- m_space_io->install_readwrite_handler(0x0092, 0x0093, read8smo_delegate(FUNC(wd7600_device::a20_reset_r), this), write8smo_delegate(FUNC(wd7600_device::a20_reset_w), this), 0x00ff);
+ m_space_io->install_readwrite_handler(0x0060, 0x0061, read8_delegate(FUNC(wd7600_device::keyb_data_r), this), write8_delegate(FUNC(wd7600_device::keyb_data_w), this), 0x00ff);
+ m_space_io->install_readwrite_handler(0x0060, 0x0061, read8_delegate(FUNC(wd7600_device::portb_r), this), write8_delegate(FUNC(wd7600_device::portb_w), this), 0xff00);
+ m_space_io->install_readwrite_handler(0x0064, 0x0065, read8_delegate(FUNC(wd7600_device::keyb_status_r), this), write8_delegate(FUNC(wd7600_device::keyb_cmd_w), this), 0x00ff);
+ m_space_io->install_readwrite_handler(0x0070, 0x007f, read8_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8_delegate(FUNC(wd7600_device::rtc_w), this), 0xffff);
+ m_space_io->install_readwrite_handler(0x0080, 0x008f, read8_delegate(FUNC(wd7600_device::dma_page_r), this), write8_delegate(FUNC(wd7600_device::dma_page_w), this), 0xffff);
+ m_space_io->install_readwrite_handler(0x0092, 0x0093, read8_delegate(FUNC(wd7600_device::a20_reset_r), this), write8_delegate(FUNC(wd7600_device::a20_reset_w), this), 0x00ff);
m_space_io->install_readwrite_handler(0x00a0, 0x00a3, read8sm_delegate(FUNC(pic8259_device::read), &(*m_pic2)), write8sm_delegate(FUNC(pic8259_device::write), &(*m_pic2)), 0xffff);
- m_space_io->install_readwrite_handler(0x00c0, 0x00df, read8sm_delegate(FUNC(am9517a_device::read), &(*m_dma2)), write8sm_delegate(FUNC(am9517a_device::write), &(*m_dma2)), 0x00ff);
- m_space_io->install_readwrite_handler(0x2072, 0x2073, read16smo_delegate(FUNC(wd7600_device::refresh_r), this), write16smo_delegate(FUNC(wd7600_device::refresh_w), this));
- m_space_io->install_readwrite_handler(0x2872, 0x2873, read16smo_delegate(FUNC(wd7600_device::chipsel_r), this), write16smo_delegate(FUNC(wd7600_device::chipsel_w), this));
- m_space_io->install_readwrite_handler(0x3872, 0x3873, read16smo_delegate(FUNC(wd7600_device::mem_ctrl_r), this), write16smo_delegate(FUNC(wd7600_device::mem_ctrl_w), this));
- m_space_io->install_readwrite_handler(0x4872, 0x4873, read16s_delegate(FUNC(wd7600_device::bank_01_start_r), this), write16s_delegate(FUNC(wd7600_device::bank_01_start_w), this));
- m_space_io->install_readwrite_handler(0x5072, 0x5073, read16s_delegate(FUNC(wd7600_device::bank_23_start_r), this), write16s_delegate(FUNC(wd7600_device::bank_23_start_w), this));
- m_space_io->install_readwrite_handler(0x5872, 0x5873, read16smo_delegate(FUNC(wd7600_device::split_addr_r), this), write16smo_delegate(FUNC(wd7600_device::split_addr_w), this));
- m_space_io->install_readwrite_handler(0x9872, 0x9873, read16smo_delegate(FUNC(wd7600_device::diag_r), this), write16smo_delegate(FUNC(wd7600_device::diag_w), this));
+ m_space_io->install_readwrite_handler(0x00c0, 0x00df, read8_delegate(FUNC(am9517a_device::read), &(*m_dma2)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma2)), 0x00ff);
+ m_space_io->install_readwrite_handler(0x2072, 0x2073, read16_delegate(FUNC(wd7600_device::refresh_r), this), write16_delegate(FUNC(wd7600_device::refresh_w), this));
+ m_space_io->install_readwrite_handler(0x2872, 0x2873, read16_delegate(FUNC(wd7600_device::chipsel_r), this), write16_delegate(FUNC(wd7600_device::chipsel_w), this));
+ m_space_io->install_readwrite_handler(0x3872, 0x3873, read16_delegate(FUNC(wd7600_device::mem_ctrl_r), this), write16_delegate(FUNC(wd7600_device::mem_ctrl_w), this));
+ m_space_io->install_readwrite_handler(0x4872, 0x4873, read16_delegate(FUNC(wd7600_device::bank_01_start_r), this), write16_delegate(FUNC(wd7600_device::bank_01_start_w), this));
+ m_space_io->install_readwrite_handler(0x5072, 0x5073, read16_delegate(FUNC(wd7600_device::bank_23_start_r), this), write16_delegate(FUNC(wd7600_device::bank_23_start_w), this));
+ m_space_io->install_readwrite_handler(0x5872, 0x5873, read16_delegate(FUNC(wd7600_device::split_addr_r), this), write16_delegate(FUNC(wd7600_device::split_addr_w), this));
+ m_space_io->install_readwrite_handler(0x9872, 0x9873, read16_delegate(FUNC(wd7600_device::diag_r), this), write16_delegate(FUNC(wd7600_device::diag_w), this));
}
else
{
assert(m_space_io->data_width() == 32);
- m_space_io->install_readwrite_handler(0x0000, 0x000f, read8sm_delegate(FUNC(am9517a_device::read), &(*m_dma1)), write8sm_delegate(FUNC(am9517a_device::write), &(*m_dma1)), 0xffffffff);
+ m_space_io->install_readwrite_handler(0x0000, 0x000f, read8_delegate(FUNC(am9517a_device::read), &(*m_dma1)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma1)), 0xffffffff);
m_space_io->install_readwrite_handler(0x0020, 0x003f, read8sm_delegate(FUNC(pic8259_device::read), &(*m_pic1)), write8sm_delegate(FUNC(pic8259_device::write), &(*m_pic1)), 0x0000ffff);
m_space_io->install_readwrite_handler(0x0040, 0x0043, read8sm_delegate(FUNC(pit8254_device::read), &(*m_ctc)), write8sm_delegate(FUNC(pit8254_device::write), &(*m_ctc)), 0xffffffff);
- m_space_io->install_readwrite_handler(0x0060, 0x0063, read8smo_delegate(FUNC(wd7600_device::keyb_data_r), this), write8smo_delegate(FUNC(wd7600_device::keyb_data_w), this), 0x000000ff);
- m_space_io->install_readwrite_handler(0x0060, 0x0063, read8smo_delegate(FUNC(wd7600_device::portb_r), this), write8smo_delegate(FUNC(wd7600_device::portb_w), this), 0x0000ff00);
- m_space_io->install_readwrite_handler(0x0064, 0x0067, read8smo_delegate(FUNC(wd7600_device::keyb_status_r), this), write8smo_delegate(FUNC(wd7600_device::keyb_cmd_w), this), 0x000000ff);
- m_space_io->install_readwrite_handler(0x0070, 0x007f, read8sm_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8sm_delegate(FUNC(wd7600_device::rtc_w), this), 0x0000ffff);
- m_space_io->install_readwrite_handler(0x0080, 0x008f, read8sm_delegate(FUNC(wd7600_device::dma_page_r), this), write8sm_delegate(FUNC(wd7600_device::dma_page_w), this), 0xffffffff);
- m_space_io->install_readwrite_handler(0x0090, 0x0093, read8smo_delegate(FUNC(wd7600_device::a20_reset_r), this), write8smo_delegate(FUNC(wd7600_device::a20_reset_w), this), 0x00ff0000);
+ m_space_io->install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(wd7600_device::keyb_data_r), this), write8_delegate(FUNC(wd7600_device::keyb_data_w), this), 0x000000ff);
+ m_space_io->install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(wd7600_device::portb_r), this), write8_delegate(FUNC(wd7600_device::portb_w), this), 0x0000ff00);
+ m_space_io->install_readwrite_handler(0x0064, 0x0067, read8_delegate(FUNC(wd7600_device::keyb_status_r), this), write8_delegate(FUNC(wd7600_device::keyb_cmd_w), this), 0x000000ff);
+ m_space_io->install_readwrite_handler(0x0070, 0x007f, read8_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8_delegate(FUNC(wd7600_device::rtc_w), this), 0x0000ffff);
+ m_space_io->install_readwrite_handler(0x0080, 0x008f, read8_delegate(FUNC(wd7600_device::dma_page_r), this), write8_delegate(FUNC(wd7600_device::dma_page_w), this), 0xffffffff);
+ m_space_io->install_readwrite_handler(0x0090, 0x0093, read8_delegate(FUNC(wd7600_device::a20_reset_r), this), write8_delegate(FUNC(wd7600_device::a20_reset_w), this), 0x00ff0000);
m_space_io->install_readwrite_handler(0x00a0, 0x00a3, read8sm_delegate(FUNC(pic8259_device::read), &(*m_pic2)), write8sm_delegate(FUNC(pic8259_device::write), &(*m_pic2)), 0x0000ffff);
- m_space_io->install_readwrite_handler(0x00c0, 0x00df, read8sm_delegate(FUNC(am9517a_device::read), &(*m_dma2)), write8sm_delegate(FUNC(am9517a_device::write), &(*m_dma2)), 0x00ff00ff);
- m_space_io->install_readwrite_handler(0x2070, 0x2073, read16smo_delegate(FUNC(wd7600_device::refresh_r), this), write16smo_delegate(FUNC(wd7600_device::refresh_w), this), 0xffff0000);
- m_space_io->install_readwrite_handler(0x2870, 0x2873, read16smo_delegate(FUNC(wd7600_device::chipsel_r), this), write16smo_delegate(FUNC(wd7600_device::chipsel_w), this), 0xffff0000);
- m_space_io->install_readwrite_handler(0x3870, 0x3873, read16smo_delegate(FUNC(wd7600_device::mem_ctrl_r), this), write16smo_delegate(FUNC(wd7600_device::mem_ctrl_w), this), 0xffff0000);
- m_space_io->install_readwrite_handler(0x4870, 0x4873, read16s_delegate(FUNC(wd7600_device::bank_01_start_r), this), write16s_delegate(FUNC(wd7600_device::bank_01_start_w), this), 0xffff0000);
- m_space_io->install_readwrite_handler(0x5070, 0x5073, read16s_delegate(FUNC(wd7600_device::bank_23_start_r), this), write16s_delegate(FUNC(wd7600_device::bank_23_start_w), this), 0xffff0000);
- m_space_io->install_readwrite_handler(0x5870, 0x5873, read16smo_delegate(FUNC(wd7600_device::split_addr_r), this), write16smo_delegate(FUNC(wd7600_device::split_addr_w), this), 0xffff0000);
- m_space_io->install_readwrite_handler(0x9870, 0x9873, read16smo_delegate(FUNC(wd7600_device::diag_r), this), write16smo_delegate(FUNC(wd7600_device::diag_w), this), 0xffff0000);
+ m_space_io->install_readwrite_handler(0x00c0, 0x00df, read8_delegate(FUNC(am9517a_device::read), &(*m_dma2)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma2)), 0x00ff00ff);
+ m_space_io->install_readwrite_handler(0x2070, 0x2073, read16_delegate(FUNC(wd7600_device::refresh_r), this), write16_delegate(FUNC(wd7600_device::refresh_w), this), 0xffff0000);
+ m_space_io->install_readwrite_handler(0x2870, 0x2873, read16_delegate(FUNC(wd7600_device::chipsel_r), this), write16_delegate(FUNC(wd7600_device::chipsel_w), this), 0xffff0000);
+ m_space_io->install_readwrite_handler(0x3870, 0x3873, read16_delegate(FUNC(wd7600_device::mem_ctrl_r), this), write16_delegate(FUNC(wd7600_device::mem_ctrl_w), this), 0xffff0000);
+ m_space_io->install_readwrite_handler(0x4870, 0x4873, read16_delegate(FUNC(wd7600_device::bank_01_start_r), this), write16_delegate(FUNC(wd7600_device::bank_01_start_w), this), 0xffff0000);
+ m_space_io->install_readwrite_handler(0x5070, 0x5073, read16_delegate(FUNC(wd7600_device::bank_23_start_r), this), write16_delegate(FUNC(wd7600_device::bank_23_start_w), this), 0xffff0000);
+ m_space_io->install_readwrite_handler(0x5870, 0x5873, read16_delegate(FUNC(wd7600_device::split_addr_r), this), write16_delegate(FUNC(wd7600_device::split_addr_w), this), 0xffff0000);
+ m_space_io->install_readwrite_handler(0x9870, 0x9873, read16_delegate(FUNC(wd7600_device::diag_r), this), write16_delegate(FUNC(wd7600_device::diag_w), this), 0xffff0000);
}
}
@@ -255,7 +255,7 @@ void wd7600_device::keyboard_gatea20(int state)
a20m();
}
-void wd7600_device::rtc_w(offs_t offset, uint8_t data)
+WRITE8_MEMBER( wd7600_device::rtc_w )
{
if (offset == 0)
{
@@ -263,10 +263,10 @@ void wd7600_device::rtc_w(offs_t offset, uint8_t data)
data &= 0x7f;
}
- m_rtc->write(offset, data);
+ m_rtc->write(space, offset, data);
}
-uint8_t wd7600_device::pic1_slave_ack_r(offs_t offset)
+READ8_MEMBER( wd7600_device::pic1_slave_ack_r )
{
if (offset == 2) // IRQ 2
return m_pic2->acknowledge();
@@ -288,36 +288,36 @@ WRITE_LINE_MEMBER( wd7600_device::ctc_out2_w )
}
// Keyboard
-void wd7600_device::keyb_data_w(uint8_t data)
+WRITE8_MEMBER( wd7600_device::keyb_data_w )
{
// LOG("WD7600: keyboard data write %02x\n", data);
- m_keybc->data_w(data);
+ m_keybc->data_w(space,0,data);
}
-uint8_t wd7600_device::keyb_data_r()
+READ8_MEMBER( wd7600_device::keyb_data_r )
{
- uint8_t ret = m_keybc->data_r();
+ uint8_t ret = m_keybc->data_r(space,0);
// LOG("WD7600: keyboard data read %02x\n", ret);
return ret;
}
-void wd7600_device::keyb_cmd_w(uint8_t data)
+WRITE8_MEMBER( wd7600_device::keyb_cmd_w )
{
// LOG("WD7600: keyboard command %02x\n", data);
- m_keybc->command_w(data);
+ m_keybc->command_w(space,0,data);
}
-uint8_t wd7600_device::keyb_status_r()
+READ8_MEMBER( wd7600_device::keyb_status_r )
{
- return m_keybc->status_r();
+ return m_keybc->status_r(space,0);
}
-uint8_t wd7600_device::portb_r()
+READ8_MEMBER( wd7600_device::portb_r )
{
return m_portb;
}
-void wd7600_device::portb_w(uint8_t data)
+WRITE8_MEMBER( wd7600_device::portb_w )
{
m_portb = (m_portb & 0xf0) | (data & 0x0f);
@@ -352,7 +352,7 @@ offs_t wd7600_device::page_offset()
return 0xff0000;
}
-uint8_t wd7600_device::dma_read_byte(offs_t offset)
+READ8_MEMBER( wd7600_device::dma_read_byte )
{
if (m_dma_channel == -1)
return 0xff;
@@ -360,7 +360,7 @@ uint8_t wd7600_device::dma_read_byte(offs_t offset)
return m_space->read_byte(page_offset() + offset);
}
-void wd7600_device::dma_write_byte(offs_t offset, uint8_t data)
+WRITE8_MEMBER( wd7600_device::dma_write_byte )
{
if (m_dma_channel == -1)
return;
@@ -368,7 +368,7 @@ void wd7600_device::dma_write_byte(offs_t offset, uint8_t data)
m_space->write_byte(page_offset() + offset, data);
}
-uint8_t wd7600_device::dma_read_word(offs_t offset)
+READ8_MEMBER( wd7600_device::dma_read_word )
{
if (m_dma_channel == -1)
return 0xff;
@@ -379,7 +379,7 @@ uint8_t wd7600_device::dma_read_word(offs_t offset)
return result;
}
-void wd7600_device::dma_write_word(offs_t offset, uint8_t data)
+WRITE8_MEMBER( wd7600_device::dma_write_word )
{
if (m_dma_channel == -1)
return;
@@ -401,8 +401,6 @@ WRITE_LINE_MEMBER( wd7600_device::dma1_eop_w )
void wd7600_device::set_dma_channel(int channel, bool state)
{
- //m_write_dack(channel, state);
-
if (!state)
{
m_dma_channel = channel;
@@ -440,7 +438,7 @@ WRITE_LINE_MEMBER( wd7600_device::kbrst_w )
m_kbrst = state;
}
-void wd7600_device::a20_reset_w(uint8_t data)
+WRITE8_MEMBER( wd7600_device::a20_reset_w )
{
m_alt_a20 = BIT(data,1);
a20m();
@@ -453,7 +451,7 @@ void wd7600_device::a20_reset_w(uint8_t data)
}
}
-uint8_t wd7600_device::a20_reset_r()
+READ8_MEMBER( wd7600_device::a20_reset_r )
{
uint8_t ret = 0;
if(m_alt_a20)
@@ -462,12 +460,12 @@ uint8_t wd7600_device::a20_reset_r()
}
// port 0x2072 - Refresh Control, and serial/parallel port address select
-uint16_t wd7600_device::refresh_r()
+READ16_MEMBER(wd7600_device::refresh_r)
{
return m_refresh_ctrl;
}
-void wd7600_device::refresh_w(uint16_t data)
+WRITE16_MEMBER(wd7600_device::refresh_w)
{
// TODO: select serial/parallel I/O port location
m_refresh_ctrl = data;
@@ -475,36 +473,36 @@ void wd7600_device::refresh_w(uint16_t data)
}
// port 0x2872 - chip select
-uint16_t wd7600_device::chipsel_r()
+READ16_MEMBER(wd7600_device::chipsel_r)
{
return m_chip_sel;
}
-void wd7600_device::chipsel_w(uint16_t data)
+WRITE16_MEMBER(wd7600_device::chipsel_w)
{
m_chip_sel = data;
LOG("WD7600: Chip Select write %04x\n", data);
}
// port 0x3872 - Memory Control
-uint16_t wd7600_device::mem_ctrl_r()
+READ16_MEMBER(wd7600_device::mem_ctrl_r)
{
return m_memory_ctrl;
}
-void wd7600_device::mem_ctrl_w(uint16_t data)
+WRITE16_MEMBER(wd7600_device::mem_ctrl_w)
{
m_memory_ctrl = data;
LOG("WD7600: Memory Control write %04x\n", data);
}
// port 0x4872 - Bank 0 and 1 start address
-uint16_t wd7600_device::bank_01_start_r(offs_t offset, uint16_t mem_mask)
+READ16_MEMBER(wd7600_device::bank_01_start_r)
{
return (m_bank_start[1] << 8) | m_bank_start[0];
}
-void wd7600_device::bank_01_start_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+WRITE16_MEMBER(wd7600_device::bank_01_start_w)
{
if(ACCESSING_BITS_0_7)
{
@@ -519,12 +517,12 @@ void wd7600_device::bank_01_start_w(offs_t offset, uint16_t data, uint16_t mem_m
}
// port 0x5072 - Bank 2 and 3 start address
-uint16_t wd7600_device::bank_23_start_r(offs_t offset, uint16_t mem_mask)
+READ16_MEMBER(wd7600_device::bank_23_start_r)
{
return (m_bank_start[3] << 8) | m_bank_start[2];
}
-void wd7600_device::bank_23_start_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+WRITE16_MEMBER(wd7600_device::bank_23_start_w)
{
if(ACCESSING_BITS_0_7)
{
@@ -539,24 +537,24 @@ void wd7600_device::bank_23_start_w(offs_t offset, uint16_t data, uint16_t mem_m
}
// port 0x5872 - split starting address (used for BIOS shadowing)
-uint16_t wd7600_device::split_addr_r()
+READ16_MEMBER(wd7600_device::split_addr_r)
{
return m_split_start;
}
-void wd7600_device::split_addr_w(uint16_t data)
+WRITE16_MEMBER(wd7600_device::split_addr_w)
{
m_split_start = data;
LOG("WD7600: Split start address write %04x\n", data);
}
// port 0x9872 - Diagnostic
-uint16_t wd7600_device::diag_r()
+READ16_MEMBER(wd7600_device::diag_r)
{
return m_diagnostic | 0xe080;
}
-void wd7600_device::diag_w(uint16_t data)
+WRITE16_MEMBER(wd7600_device::diag_w)
{
m_diagnostic = data;
LOG("WD7600: Diagnostic write %04x\n", data);
diff --git a/src/devices/machine/wd7600.h b/src/devices/machine/wd7600.h
index 43ddb00b038..8f40ed3116f 100644
--- a/src/devices/machine/wd7600.h
+++ b/src/devices/machine/wd7600.h
@@ -75,20 +75,20 @@ public:
DECLARE_WRITE_LINE_MEMBER( gatea20_w );
DECLARE_WRITE_LINE_MEMBER( kbrst_w );
- uint16_t refresh_r();
- void refresh_w(uint16_t data);
- uint16_t chipsel_r();
- void chipsel_w(uint16_t data);
- uint16_t mem_ctrl_r();
- void mem_ctrl_w(uint16_t data);
- uint16_t bank_01_start_r(offs_t offset, uint16_t mem_mask);
- void bank_01_start_w(offs_t offset, uint16_t data, uint16_t mem_mask);
- uint16_t bank_23_start_r(offs_t offset, uint16_t mem_mask);
- void bank_23_start_w(offs_t offset, uint16_t data, uint16_t mem_mask);
- uint16_t split_addr_r();
- void split_addr_w(uint16_t data);
- uint16_t diag_r();
- void diag_w(uint16_t data);
+ DECLARE_READ16_MEMBER(refresh_r);
+ DECLARE_WRITE16_MEMBER(refresh_w);
+ DECLARE_READ16_MEMBER(chipsel_r);
+ DECLARE_WRITE16_MEMBER(chipsel_w);
+ DECLARE_READ16_MEMBER(mem_ctrl_r);
+ DECLARE_WRITE16_MEMBER(mem_ctrl_w);
+ DECLARE_READ16_MEMBER(bank_01_start_r);
+ DECLARE_WRITE16_MEMBER(bank_01_start_w);
+ DECLARE_READ16_MEMBER(bank_23_start_r);
+ DECLARE_WRITE16_MEMBER(bank_23_start_w);
+ DECLARE_READ16_MEMBER(split_addr_r);
+ DECLARE_WRITE16_MEMBER(split_addr_w);
+ DECLARE_READ16_MEMBER(diag_r);
+ DECLARE_WRITE16_MEMBER(diag_w);
IRQ_CALLBACK_MEMBER(intack_cb) { return m_pic1->acknowledge(); }
@@ -101,39 +101,39 @@ protected:
private:
DECLARE_WRITE_LINE_MEMBER( pic1_int_w ) { m_write_intr(state); }
- uint8_t pic1_slave_ack_r(offs_t offset);
+ DECLARE_READ8_MEMBER( pic1_slave_ack_r );
DECLARE_WRITE_LINE_MEMBER( ctc_out1_w );
DECLARE_WRITE_LINE_MEMBER( ctc_out2_w );
- void rtc_w(offs_t offset, uint8_t data);
- void keyb_cmd_w(uint8_t data);
- void keyb_data_w(uint8_t data);
- uint8_t keyb_data_r();
- uint8_t keyb_status_r();
- void a20_reset_w(uint8_t data);
- uint8_t a20_reset_r();
- uint8_t portb_r();
- void portb_w(uint8_t data);
- void dma_page_w(offs_t offset, uint8_t data) { m_dma_page[offset & 0x0f] = data; }
- uint8_t dma_page_r(offs_t offset) { return m_dma_page[offset & 0x0f]; }
- uint8_t dma_read_byte(offs_t offset);
- void dma_write_byte(offs_t offset, uint8_t data);
- uint8_t dma_read_word(offs_t offset);
- void dma_write_word(offs_t offset, uint8_t data);
+ DECLARE_WRITE8_MEMBER( rtc_w );
+ DECLARE_WRITE8_MEMBER( keyb_cmd_w );
+ DECLARE_WRITE8_MEMBER( keyb_data_w );
+ DECLARE_READ8_MEMBER( keyb_data_r );
+ DECLARE_READ8_MEMBER( keyb_status_r );
+ DECLARE_WRITE8_MEMBER( a20_reset_w );
+ DECLARE_READ8_MEMBER( a20_reset_r );
+ DECLARE_READ8_MEMBER( portb_r );
+ DECLARE_WRITE8_MEMBER( portb_w );
+ DECLARE_WRITE8_MEMBER( dma_page_w ) { m_dma_page[offset & 0x0f] = data; }
+ DECLARE_READ8_MEMBER( dma_page_r ) { return m_dma_page[offset & 0x0f]; }
+ DECLARE_READ8_MEMBER( dma_read_byte );
+ DECLARE_WRITE8_MEMBER( dma_write_byte );
+ DECLARE_READ8_MEMBER( dma_read_word );
+ DECLARE_WRITE8_MEMBER( dma_write_word );
DECLARE_WRITE_LINE_MEMBER( dma1_eop_w );
- uint8_t dma1_ior0_r() { return m_read_ior(0); }
- uint8_t dma1_ior1_r() { return m_read_ior(1); }
- uint8_t dma1_ior2_r() { return m_read_ior(2); }
- uint8_t dma1_ior3_r() { return m_read_ior(3); }
- uint8_t dma2_ior1_r() { uint16_t result = m_read_ior(5); m_dma_high_byte = result >> 8; return result; }
- uint8_t dma2_ior2_r() { uint16_t result = m_read_ior(6); m_dma_high_byte = result >> 8; return result; }
- uint8_t dma2_ior3_r() { uint16_t result = m_read_ior(7); m_dma_high_byte = result >> 8; return result; }
- void dma1_iow0_w(uint8_t data) { m_write_iow(0, data, 0xffff); }
- void dma1_iow1_w(uint8_t data) { m_write_iow(1, data, 0xffff); }
- void dma1_iow2_w(uint8_t data) { m_write_iow(2, data, 0xffff); }
- void dma1_iow3_w(uint8_t data) { m_write_iow(3, data, 0xffff); }
- void dma2_iow1_w(uint8_t data) { m_write_iow(5, (m_dma_high_byte << 8) | data, 0xffff); }
- void dma2_iow2_w(uint8_t data) { m_write_iow(6, (m_dma_high_byte << 8) | data, 0xffff); }
- void dma2_iow3_w(uint8_t data) { m_write_iow(7, (m_dma_high_byte << 8) | data, 0xffff); }
+ DECLARE_READ8_MEMBER( dma1_ior0_r ) { return m_read_ior(0); }
+ DECLARE_READ8_MEMBER( dma1_ior1_r ) { return m_read_ior(1); }
+ DECLARE_READ8_MEMBER( dma1_ior2_r ) { return m_read_ior(2); }
+ DECLARE_READ8_MEMBER( dma1_ior3_r ) { return m_read_ior(3); }
+ DECLARE_READ8_MEMBER( dma2_ior1_r ) { uint16_t result = m_read_ior(5); m_dma_high_byte = result >> 8; return result; }
+ DECLARE_READ8_MEMBER( dma2_ior2_r ) { uint16_t result = m_read_ior(6); m_dma_high_byte = result >> 8; return result; }
+ DECLARE_READ8_MEMBER( dma2_ior3_r ) { uint16_t result = m_read_ior(7); m_dma_high_byte = result >> 8; return result; }
+ DECLARE_WRITE8_MEMBER( dma1_iow0_w ) { m_write_iow(0, data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma1_iow1_w ) { m_write_iow(1, data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma1_iow2_w ) { m_write_iow(2, data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma1_iow3_w ) { m_write_iow(3, data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma2_iow1_w ) { m_write_iow(5, (m_dma_high_byte << 8) | data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma2_iow2_w ) { m_write_iow(6, (m_dma_high_byte << 8) | data, 0xffff); }
+ DECLARE_WRITE8_MEMBER( dma2_iow3_w ) { m_write_iow(7, (m_dma_high_byte << 8) | data, 0xffff); }
DECLARE_WRITE_LINE_MEMBER( dma1_dack0_w ) { set_dma_channel(0, state); }
DECLARE_WRITE_LINE_MEMBER( dma1_dack1_w ) { set_dma_channel(1, state); }
DECLARE_WRITE_LINE_MEMBER( dma1_dack2_w ) { set_dma_channel(2, state); }
diff --git a/src/devices/machine/x2201.cpp b/src/devices/machine/x2201.cpp
index 90d731b7e3e..ec252d1b8dd 100644
--- a/src/devices/machine/x2201.cpp
+++ b/src/devices/machine/x2201.cpp
@@ -128,6 +128,17 @@ u8 x2201_device::read(offs_t offset)
//-------------------------------------------------
+// read_byte - read 8 bits of data from RAM
+// (FIXME: remove once CRU reads are 1-bit)
+//-------------------------------------------------
+
+u8 x2201_device::read_byte(offs_t offset)
+{
+ return m_ram[offset & 127];
+}
+
+
+//-------------------------------------------------
// write - write one bit of data to RAM
//-------------------------------------------------
diff --git a/src/devices/machine/x2201.h b/src/devices/machine/x2201.h
index 1d873850df1..670c69b349c 100644
--- a/src/devices/machine/x2201.h
+++ b/src/devices/machine/x2201.h
@@ -38,6 +38,7 @@ public:
// read/write handlers
u8 read(offs_t offset);
+ u8 read_byte(offs_t offset); // hack
void write(offs_t offset, u8 data);
// control lines
diff --git a/src/devices/machine/xc1700e.cpp b/src/devices/machine/xc1700e.cpp
deleted file mode 100644
index fe056664b07..00000000000
--- a/src/devices/machine/xc1700e.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Patrick Mackinlay
-
-/*
- * An implementation of the Xilinx XC1700E family of serial configuration PROM
- * devices, including:
- *
- * Part Capacity Variants
- * -------- --------- ----------------
- * XC1736E 36,288
- * XC1765E 65,536 XC1765EL
- * XC17128E 131,072 XC17128EL
- * XC17256E 262,144 XC17256EL
- * XC17512L 524,288
- * XC1701 1,048,576 XC1701L, XQ1701L
- * XC1702L 2,097,152
- * XC1704L 4,194,304
- *
- * The input C̅E̅ and CLK lines have not been explicitly implemented; these are
- * assumed to be asserted as expected before/during data read. The effect of
- * C̅E̅O̅ can be obtained by connecting the cascade_r callback to the data_r of
- * the cascaded device and resetting all devices when needed.
- *
- * This implementation assumes the input data is stored least-significant bit
- * first; i.e. the first bit read out of the device is held in the LSB of the
- * first byte of the memory region. This convention matches at least one
- * dumping device tested.
- *
- * Sources:
- *
- * http://www.xilinx.com/support/documentation/data_sheets/ds027.pdf
- *
- */
-
-#include "emu.h"
-#include "xc1700e.h"
-
-#define VERBOSE 0
-#include "logmacro.h"
-
-DEFINE_DEVICE_TYPE(XC1736E, xc1736e_device, "xc1736e", "Xilinx 36,288 bit Serial PROM")
-DEFINE_DEVICE_TYPE(XC1765E, xc1765e_device, "xc1765e", "Xilinx 65,536 bit Serial PROM")
-DEFINE_DEVICE_TYPE(XC17128E, xc17128e_device, "xc17128e", "Xilinx 131,072 bit Serial PROM")
-DEFINE_DEVICE_TYPE(XC17256E, xc17256e_device, "xc17256e", "Xilinx 262,144 bit Serial PROM")
-DEFINE_DEVICE_TYPE(XC17512L, xc17512l_device, "xc17512l", "Xilinx 524,288 bit Serial PROM")
-DEFINE_DEVICE_TYPE(XC1701, xc1701_device, "xc1701", "Xilinx 1,048,576 bit Serial PROM")
-DEFINE_DEVICE_TYPE(XC1702L, xc1702l_device, "xc1702l", "Xilinx 2,097,152 bit Serial PROM")
-DEFINE_DEVICE_TYPE(XC1704L, xc1704l_device, "xc1704l", "Xilinx 4,194,304 bit Serial PROM")
-
-base_xc1700e_device::base_xc1700e_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 capacity)
- : device_t(mconfig, type, tag, owner, clock)
- , m_capacity(capacity)
- , m_region(*this, DEVICE_SELF)
- , m_cascade_cb(*this)
- , m_reset(true)
- , m_address(0)
-{
-}
-
-void base_xc1700e_device::device_start()
-{
- m_cascade_cb.resolve_safe(1);
-
- save_item(NAME(m_reset));
- save_item(NAME(m_address));
-}
-
-void base_xc1700e_device::reset_w(int state)
-{
- if (state)
- m_address = 0;
-
- m_reset = bool(state);
-}
-
-int base_xc1700e_device::data_r()
-{
- if (m_reset)
- return 1;
-
- if (m_address < m_capacity)
- {
- int const data = BIT(m_region->as_u8(m_address >> 3), m_address & 7);
-
- m_address++;
-
- return data;
- }
- else
- return m_cascade_cb();
-}
diff --git a/src/devices/machine/xc1700e.h b/src/devices/machine/xc1700e.h
deleted file mode 100644
index 42a191c73ce..00000000000
--- a/src/devices/machine/xc1700e.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Patrick Mackinlay
-
-#ifndef MAME_MACHINE_XC1700E_H
-#define MAME_MACHINE_XC1700E_H
-
-#pragma once
-
-class base_xc1700e_device : public device_t
-{
-public:
- // configuration
- auto cascade_r() { return m_cascade_cb.bind(); }
-
- // input/output lines
- void reset_w(int state);
- int data_r();
-
-protected:
- base_xc1700e_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 capacity);
-
- // device_t overrides
- virtual void device_start() override;
-
-private:
- // device configuration
- const u32 m_capacity;
- required_memory_region m_region;
-
- devcb_read_line m_cascade_cb;
-
- // device state
- bool m_reset;
- unsigned m_address;
-};
-
-DECLARE_DEVICE_TYPE(XC1736E, xc1736e_device)
-DECLARE_DEVICE_TYPE(XC1765E, xc1765e_device)
-DECLARE_DEVICE_TYPE(XC17128E, xc17128e_device)
-DECLARE_DEVICE_TYPE(XC17256E, xc17256e_device)
-DECLARE_DEVICE_TYPE(XC17512L, xc17512l_device)
-DECLARE_DEVICE_TYPE(XC1701, xc1701_device)
-DECLARE_DEVICE_TYPE(XC1702L, xc1702l_device)
-DECLARE_DEVICE_TYPE(XC1704L, xc1704l_device)
-
-class xc1736e_device : public base_xc1700e_device
-{
-public:
- xc1736e_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
- : base_xc1700e_device(mconfig, XC1736E, tag, owner, clock, 36'288UL)
- {
- }
-};
-
-class xc1765e_device : public base_xc1700e_device
-{
-public:
- xc1765e_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
- : base_xc1700e_device(mconfig, XC1765E, tag, owner, clock, 65'536UL)
- {
- }
-};
-
-class xc17128e_device : public base_xc1700e_device
-{
-public:
- xc17128e_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
- : base_xc1700e_device(mconfig, XC17128E, tag, owner, clock, 131'072UL)
- {
- }
-};
-
-class xc17256e_device : public base_xc1700e_device
-{
-public:
- xc17256e_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
- : base_xc1700e_device(mconfig, XC17256E, tag, owner, clock, 262'144UL)
- {
- }
-};
-
-class xc17512l_device : public base_xc1700e_device
-{
-public:
- xc17512l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
- : base_xc1700e_device(mconfig, XC17512L, tag, owner, clock, 524'288UL)
- {
- }
-};
-
-class xc1701_device : public base_xc1700e_device
-{
-public:
- xc1701_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
- : base_xc1700e_device(mconfig, XC1701, tag, owner, clock, 1'048'576UL)
- {
- }
-};
-
-class xc1702l_device : public base_xc1700e_device
-{
-public:
- xc1702l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
- : base_xc1700e_device(mconfig, XC1702L, tag, owner, clock, 2'097'152UL)
- {
- }
-};
-
-class xc1704l_device : public base_xc1700e_device
-{
-public:
- xc1704l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
- : base_xc1700e_device(mconfig, XC1704L, tag, owner, clock, 4'194'304UL)
- {
- }
-};
-
-#endif // MAME_MACHINE_XC1700E_H
diff --git a/src/devices/machine/ym2148.cpp b/src/devices/machine/ym2148.cpp
index 04a3e53e97e..10eb9c9e6c9 100644
--- a/src/devices/machine/ym2148.cpp
+++ b/src/devices/machine/ym2148.cpp
@@ -143,7 +143,7 @@ void ym2148_device::device_timer(emu_timer &timer, device_timer_id id, int param
}
-uint8_t ym2148_device::read(offs_t offset)
+READ8_MEMBER(ym2148_device::read)
{
switch (offset & 7)
{
@@ -165,7 +165,7 @@ uint8_t ym2148_device::read(offs_t offset)
}
-void ym2148_device::write(offs_t offset, uint8_t data)
+WRITE8_MEMBER(ym2148_device::write)
{
switch (offset & 7)
{
diff --git a/src/devices/machine/ym2148.h b/src/devices/machine/ym2148.h
index 3cb13bf2058..7f5f45d7066 100644
--- a/src/devices/machine/ym2148.h
+++ b/src/devices/machine/ym2148.h
@@ -31,8 +31,8 @@ public:
auto port_read_handler() { return m_port_read_handler.bind(); }
auto irq_handler() { return m_irq_handler.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
DECLARE_WRITE_LINE_MEMBER(write_rxd);
uint8_t get_irq_vector();
diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp
index b44be5c5873..711d58b8b49 100644
--- a/src/devices/machine/z80scc.cpp
+++ b/src/devices/machine/z80scc.cpp
@@ -84,9 +84,9 @@ baud rate:
-- in the unlikely case of T == 0, pretend T = 1.
- If the required wr11 bits are set:
-- let's say M = wr4 D7,D6 if 1,1 M = 64; if 1,0 M = 32; if 0,1 M = 16 else M = 1
--- so, the required device clock = 2*T*B*M.
+-- so, the required clock on the MCFG_DEVICE_ADD line = 2*T*B*M.
- If the required wr11 bits are not set:
--- call: configure_channels(X, 0, Y, 0), where X = channel-A-baud * T,
+-- add a line: MCFG_Z80SCC_OFFSETS(X, 0, Y, 0), where X = channel-A-baud * T,
and Y = channel-B-baud * T.
***************************************************************************/
@@ -436,7 +436,6 @@ z80scc_device::z80scc_device(const machine_config &mconfig, device_type type, co
m_out_rxdrq_cb{ { *this }, { *this } },
m_out_txdrq_cb{ { *this }, { *this } },
m_out_int_cb(*this),
- m_out_int_state(CLEAR_LINE),
m_variant(variant),
m_wr0_ptrbits(0),
m_cputag(nullptr)
@@ -518,7 +517,6 @@ void z80scc_device::device_start()
LOG("%s", FUNCNAME);
// state saving
- save_item(NAME(m_out_int_state));
save_item(NAME(m_int_state));
save_item(NAME(m_int_source));
save_item(NAME(m_wr9));
@@ -683,12 +681,8 @@ void z80scc_device::z80daisy_irq_reti()
void z80scc_device::check_interrupts()
{
int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE;
- if (m_out_int_state != state)
- {
- m_out_int_state = state;
- LOGINT("%s\n", FUNCNAME);
- m_out_int_cb(state);
- }
+ LOGINT("%s %s \n",tag(), FUNCNAME);
+ m_out_int_cb(state);
}
diff --git a/src/devices/machine/z80scc.h b/src/devices/machine/z80scc.h
index 3e8812707dc..e2cad9e660b 100644
--- a/src/devices/machine/z80scc.h
+++ b/src/devices/machine/z80scc.h
@@ -467,7 +467,6 @@ protected:
devcb_write_line m_out_int_cb;
- int m_out_int_state;
int m_int_state[6]; // interrupt state
int m_int_source[6]; // interrupt source
diff --git a/src/devices/machine/z80sio.cpp b/src/devices/machine/z80sio.cpp
index 8337aeafdf6..82997875f46 100644
--- a/src/devices/machine/z80sio.cpp
+++ b/src/devices/machine/z80sio.cpp
@@ -242,17 +242,15 @@ DEFINE_DEVICE_TYPE(UPD7201_NEW, upd7201_new_device, "upd7201_new", "NEC uP
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
-void z80sio_device::device_add_mconfig(machine_config &config)
-{
- Z80SIO_CHANNEL(config, CHANA_TAG, 0);
- Z80SIO_CHANNEL(config, CHANB_TAG, 0);
-}
-
-void i8274_new_device::device_add_mconfig(machine_config &config)
-{
- I8274_CHANNEL(config, CHANA_TAG, 0);
- I8274_CHANNEL(config, CHANB_TAG, 0);
-}
+MACHINE_CONFIG_START(z80sio_device::device_add_mconfig)
+ MCFG_DEVICE_ADD(CHANA_TAG, Z80SIO_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANB_TAG, Z80SIO_CHANNEL, 0)
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_START(i8274_new_device::device_add_mconfig)
+ MCFG_DEVICE_ADD(CHANA_TAG, I8274_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANB_TAG, I8274_CHANNEL, 0)
+MACHINE_CONFIG_END
//**************************************************************************