summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2018-10-31 15:13:46 -0400
committer AJR <ajrhacker@users.noreply.github.com>2018-10-31 15:14:17 -0400
commit6141cf5b7a354debd7851a3b072aed23157d5b3d (patch)
tree49b8e88fd3ddb84464f811d08c9822f492e67582
parenta2e7f4f5f6d968e96db52b31cf2f0e3c4a0b8994 (diff)
v25: Add address space for internal data area and SFRs
-rw-r--r--src/devices/cpu/nec/v25.cpp24
-rw-r--r--src/devices/cpu/nec/v25.h71
-rw-r--r--src/devices/cpu/nec/v25instr.hxx8
-rw-r--r--src/devices/cpu/nec/v25priv.h6
-rw-r--r--src/devices/cpu/nec/v25sfr.cpp726
5 files changed, 485 insertions, 350 deletions
diff --git a/src/devices/cpu/nec/v25.cpp b/src/devices/cpu/nec/v25.cpp
index 7a076f2c6c3..9800540a04c 100644
--- a/src/devices/cpu/nec/v25.cpp
+++ b/src/devices/cpu/nec/v25.cpp
@@ -50,11 +50,12 @@ DEFINE_DEVICE_TYPE(V25, v25_device, "v25", "NEC V25")
DEFINE_DEVICE_TYPE(V35, v35_device, "v35", "NEC V35")
-v25_common_device::v25_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, offs_t fetch_xor, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type)
+v25_common_device::v25_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, 20, 0)
+ , m_data_config("data", ENDIANNESS_LITTLE, 16, 9, 0, address_map_constructor(FUNC(v25_common_device::ida_sfr_map), this))
, m_io_config("io", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, 16, 0)
- , m_fetch_xor(fetch_xor)
+ , m_internal_ram(*this, "internal_ram")
, m_PCK(8)
, m_pt_in(*this)
, m_p0_in(*this)
@@ -72,13 +73,13 @@ v25_common_device::v25_common_device(const machine_config &mconfig, device_type
v25_device::v25_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : v25_common_device(mconfig, V25, tag, owner, clock, false, 0, 4, 4, V20_TYPE)
+ : v25_common_device(mconfig, V25, tag, owner, clock, false, 4, 4, V20_TYPE)
{
}
v35_device::v35_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : v25_common_device(mconfig, V35, tag, owner, clock, true, BYTE_XOR_LE(0), 6, 2, V30_TYPE)
+ : v25_common_device(mconfig, V35, tag, owner, clock, true, 6, 2, V30_TYPE)
{
}
@@ -86,6 +87,7 @@ device_memory_interface::space_config_vector v25_common_device::memory_space_con
{
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config),
+ std::make_pair(AS_DATA, &m_data_config),
std::make_pair(AS_IO, &m_io_config)
};
}
@@ -177,8 +179,6 @@ uint8_t v25_common_device::fetchop()
void v25_common_device::device_reset()
{
- attotime time;
-
m_ip = 0;
m_IBRK = 1;
m_F0 = 0;
@@ -216,10 +216,12 @@ void v25_common_device::device_reset()
m_RAMEN = 1;
m_TB = 20;
m_PCK = 8;
- m_IDB = 0xFFE00;
+ m_RFM = 0xfc;
+ m_WTC = 0xffff;
+ m_IDB = 0xffe00;
- int tmp = m_PCK << m_TB;
- time = attotime::from_hz(unscaled_clock()) * tmp;
+ unsigned tmp = m_PCK << m_TB;
+ attotime time = clocks_to_attotime(tmp);
m_timers[3]->adjust(time, INTTB, time);
m_timers[0]->adjust(attotime::never);
@@ -462,7 +464,6 @@ void v25_common_device::device_start()
for (i = 0; i < 4; i++)
m_timers[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(v25_common_device::v25_timer_callback),this));
- save_item(NAME(m_ram.w));
save_item(NAME(m_intp_state));
save_item(NAME(m_ip));
@@ -506,6 +507,8 @@ void v25_common_device::device_start()
save_item(NAME(m_RAMEN));
save_item(NAME(m_TB));
save_item(NAME(m_PCK));
+ save_item(NAME(m_RFM));
+ save_item(NAME(m_WTC));
save_item(NAME(m_IDB));
save_item(NAME(m_prefetch_count));
save_item(NAME(m_prefetch_reset));
@@ -518,6 +521,7 @@ void v25_common_device::device_start()
auto cache = m_program->cache<1, 0, ENDIANNESS_LITTLE>();
m_dr8 = [cache](offs_t address) -> u8 { return cache->read_byte(address); };
}
+ m_data = &space(AS_DATA);
m_io = &space(AS_IO);
m_pt_in.resolve_safe(0xff);
diff --git a/src/devices/cpu/nec/v25.h b/src/devices/cpu/nec/v25.h
index af7d5eb4d93..3f651337667 100644
--- a/src/devices/cpu/nec/v25.h
+++ b/src/devices/cpu/nec/v25.h
@@ -74,7 +74,7 @@ public:
protected:
// construction/destruction
- v25_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, offs_t fetch_xor, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type);
+ v25_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type);
// device-level overrides
virtual void device_start() override;
@@ -105,17 +105,11 @@ protected:
private:
address_space_config m_program_config;
+ address_space_config m_data_config;
address_space_config m_io_config;
/* internal RAM and register banks */
- union internalram
- {
- uint16_t w[128];
- uint8_t b[256];
- };
-
- internalram m_ram;
- offs_t m_fetch_xor;
+ required_shared_ptr<uint16_t> m_internal_ram;
uint16_t m_ip;
@@ -146,10 +140,13 @@ private:
/* system control */
uint8_t m_RAMEN, m_TB, m_PCK; /* PRC register */
+ uint8_t m_RFM;
+ uint16_t m_WTC;
uint32_t m_IDB;
address_space *m_program;
std::function<u8 (offs_t address)> m_dr8;
+ address_space *m_data;
address_space *m_io;
int m_icount;
@@ -194,12 +191,60 @@ private:
void nec_bankswitch(unsigned bank_num);
void nec_trap();
void external_int();
+
+ void ida_sfr_map(address_map &map);
uint8_t read_irqcontrol(int /*INTSOURCES*/ source, uint8_t priority);
- uint8_t read_sfr(unsigned o);
- uint16_t read_sfr_word(unsigned o);
void write_irqcontrol(int /*INTSOURCES*/ source, uint8_t d);
- void write_sfr(unsigned o, uint8_t d);
- void write_sfr_word(unsigned o, uint16_t d);
+ uint8_t p0_r();
+ void p0_w(uint8_t d);
+ void pm0_w(uint8_t d);
+ void pmc0_w(uint8_t d);
+ uint8_t p1_r();
+ void p1_w(uint8_t d);
+ void pm1_w(uint8_t d);
+ void pmc1_w(uint8_t d);
+ uint8_t p2_r();
+ void p2_w(uint8_t d);
+ void pm2_w(uint8_t d);
+ void pmc2_w(uint8_t d);
+ uint8_t pt_r();
+ void pmt_w(uint8_t d);
+ uint8_t exic0_r();
+ void exic0_w(uint8_t d);
+ uint8_t exic1_r();
+ void exic1_w(uint8_t d);
+ uint8_t exic2_r();
+ void exic2_w(uint8_t d);
+ uint16_t tm0_r();
+ void tm0_w(uint16_t d);
+ uint16_t md0_r();
+ void md0_w(uint16_t d);
+ uint16_t tm1_r();
+ void tm1_w(uint16_t d);
+ uint16_t md1_r();
+ void md1_w(uint16_t d);
+ void tmc0_w(uint8_t d);
+ void tmc1_w(uint8_t d);
+ uint8_t tmic0_r();
+ void tmic0_w(uint8_t d);
+ uint8_t tmic1_r();
+ void tmic1_w(uint8_t d);
+ uint8_t tmic2_r();
+ void tmic2_w(uint8_t d);
+ uint8_t rfm_r();
+ void rfm_w(uint8_t d);
+ uint16_t wtc_r();
+ void wtc_w(offs_t a, uint16_t d, uint16_t m);
+ uint8_t flag_r();
+ void flag_w(uint8_t d);
+ uint8_t prc_r();
+ void prc_w(uint8_t d);
+ uint8_t tbic_r();
+ void tbic_w(uint8_t d);
+ uint8_t irqs_r();
+ uint8_t ispr_r();
+ uint8_t idb_r();
+ void idb_w(uint8_t d);
uint8_t v25_read_byte(unsigned a);
uint16_t v25_read_word(unsigned a);
void v25_write_byte(unsigned a, uint8_t d);
diff --git a/src/devices/cpu/nec/v25instr.hxx b/src/devices/cpu/nec/v25instr.hxx
index e394e9ab213..9d1fcccfdee 100644
--- a/src/devices/cpu/nec/v25instr.hxx
+++ b/src/devices/cpu/nec/v25instr.hxx
@@ -26,13 +26,13 @@
#define MOVSPA \
tmp = (Wreg(PSW_SAVE) & 0x7000) >> 8; \
- Sreg(SS) = m_ram.w[tmp+SS]; \
- Wreg(SP) = m_ram.w[tmp+SP]
+ Sreg(SS) = m_internal_ram[tmp+SS]; \
+ Wreg(SP) = m_internal_ram[tmp+SP]
#define MOVSPB \
tmp <<= 4; \
- m_ram.w[tmp+SS] = Sreg(SS); \
- m_ram.w[tmp+SP] = Wreg(SP)
+ m_internal_ram[tmp+SS] = Sreg(SS); \
+ m_internal_ram[tmp+SP] = Wreg(SP)
#define FINT \
for(tmp = 1; tmp < 0x100; tmp <<= 1) { \
diff --git a/src/devices/cpu/nec/v25priv.h b/src/devices/cpu/nec/v25priv.h
index a5e1b484808..018bd5c94d9 100644
--- a/src/devices/cpu/nec/v25priv.h
+++ b/src/devices/cpu/nec/v25priv.h
@@ -93,9 +93,9 @@ enum BREGS {
#define SetRB(x) do { m_RBW = (x) << 4; m_RBB = (x) << 5; } while (0)
-#define Sreg(x) m_ram.w[m_RBW + (x)]
-#define Wreg(x) m_ram.w[m_RBW + (x)]
-#define Breg(x) m_ram.b[m_RBB + (x)]
+#define Sreg(x) m_internal_ram[m_RBW + (x)]
+#define Wreg(x) m_internal_ram[m_RBW + (x)]
+#define Breg(x) reinterpret_cast<uint8_t *>(&m_internal_ram[0])[m_RBB + (x)]
#define PC() ((Sreg(PS)<<4)+m_ip)
diff --git a/src/devices/cpu/nec/v25sfr.cpp b/src/devices/cpu/nec/v25sfr.cpp
index 788ab419b29..acab173e363 100644
--- a/src/devices/cpu/nec/v25sfr.cpp
+++ b/src/devices/cpu/nec/v25sfr.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Bryan McPhail, Alex W. Jackson
/****************************************************************************
- NEC V25/V35 special function registers and internal ram access
+ NEC V25/V35 special function registers and internal data area access
****************************************************************************/
@@ -10,6 +10,42 @@
#include "v25.h"
#include "v25priv.h"
+void v25_common_device::ida_sfr_map(address_map &map)
+{
+ map(0x000, 0x0ff).ram().share("internal_ram");
+ map(0x100, 0x100).rw(FUNC(v25_common_device::p0_r), FUNC(v25_common_device::p0_w));
+ map(0x101, 0x101).w(FUNC(v25_common_device::pm0_w));
+ map(0x102, 0x102).w(FUNC(v25_common_device::pmc0_w));
+ map(0x108, 0x108).rw(FUNC(v25_common_device::p1_r), FUNC(v25_common_device::p1_w));
+ map(0x109, 0x109).w(FUNC(v25_common_device::pm1_w));
+ map(0x10a, 0x10a).w(FUNC(v25_common_device::pmc1_w));
+ map(0x110, 0x110).rw(FUNC(v25_common_device::p2_r), FUNC(v25_common_device::p2_w));
+ map(0x111, 0x111).w(FUNC(v25_common_device::pm2_w));
+ map(0x112, 0x112).w(FUNC(v25_common_device::pmc2_w));
+ map(0x138, 0x138).r(FUNC(v25_common_device::pt_r));
+ map(0x13b, 0x13b).w(FUNC(v25_common_device::pmt_w));
+ map(0x14c, 0x14c).rw(FUNC(v25_common_device::exic0_r), FUNC(v25_common_device::exic0_w));
+ map(0x14d, 0x14d).rw(FUNC(v25_common_device::exic1_r), FUNC(v25_common_device::exic1_w));
+ map(0x14e, 0x14e).rw(FUNC(v25_common_device::exic2_r), FUNC(v25_common_device::exic2_w));
+ map(0x180, 0x181).rw(FUNC(v25_common_device::tm0_r), FUNC(v25_common_device::tm0_w));
+ map(0x182, 0x183).rw(FUNC(v25_common_device::md0_r), FUNC(v25_common_device::md0_w));
+ map(0x188, 0x189).rw(FUNC(v25_common_device::tm1_r), FUNC(v25_common_device::tm1_w));
+ map(0x18a, 0x18b).rw(FUNC(v25_common_device::md1_r), FUNC(v25_common_device::md1_w));
+ map(0x190, 0x190).w(FUNC(v25_common_device::tmc0_w));
+ map(0x191, 0x191).w(FUNC(v25_common_device::tmc1_w));
+ map(0x19c, 0x19c).rw(FUNC(v25_common_device::tmic0_r), FUNC(v25_common_device::tmic0_w));
+ map(0x19d, 0x19d).rw(FUNC(v25_common_device::tmic1_r), FUNC(v25_common_device::tmic1_w));
+ map(0x19e, 0x19e).rw(FUNC(v25_common_device::tmic2_r), FUNC(v25_common_device::tmic2_w));
+ map(0x1e1, 0x1e1).rw(FUNC(v25_common_device::rfm_r), FUNC(v25_common_device::rfm_w));
+ map(0x1e8, 0x1e9).rw(FUNC(v25_common_device::wtc_r), FUNC(v25_common_device::wtc_w));
+ map(0x1ea, 0x1ea).rw(FUNC(v25_common_device::flag_r), FUNC(v25_common_device::flag_w));
+ map(0x1eb, 0x1eb).rw(FUNC(v25_common_device::prc_r), FUNC(v25_common_device::prc_w));
+ map(0x1ec, 0x1ec).rw(FUNC(v25_common_device::tbic_r), FUNC(v25_common_device::tbic_w));
+ map(0x1ef, 0x1ef).r(FUNC(v25_common_device::irqs_r));
+ map(0x1fc, 0x1fc).r(FUNC(v25_common_device::ispr_r));
+ map(0x1ff, 0x1ff).rw(FUNC(v25_common_device::idb_r), FUNC(v25_common_device::idb_w));
+}
+
uint8_t v25_common_device::read_irqcontrol(int /*INTSOURCES*/ source, uint8_t priority)
{
return (((m_pending_irq & source) ? 0x80 : 0x00)
@@ -18,386 +54,436 @@ uint8_t v25_common_device::read_irqcontrol(int /*INTSOURCES*/ source, uint8_t pr
| priority);
}
-uint8_t v25_common_device::read_sfr(unsigned o)
-{
- uint8_t ret;
-
- switch(o)
- {
- case 0x00: /* P0 */
- ret = m_p0_in();
- break;
- case 0x08: /* P1 */
- /* P1 is combined with the interrupt lines */
- ret = ((m_p1_in() & 0xF0)
- | (m_nmi_state ? 0x00 : 0x01)
- | (m_intp_state[0] ? 0x00 : 0x02)
- | (m_intp_state[1] ? 0x00 : 0x04)
- | (m_intp_state[2] ? 0x00 : 0x08));
- break;
- case 0x10: /* P2 */
- ret = m_p2_in();
- break;
- case 0x38: /* PT */
- ret = m_pt_in();
- break;
- case 0x4C: /* EXIC0 */
- ret = read_irqcontrol(INTP0, m_priority_intp);
- break;
- case 0x4D: /* EXIC1 */
- ret = read_irqcontrol(INTP1, 7);
- break;
- case 0x4E: /* EXIC2 */
- ret = read_irqcontrol(INTP2, 7);
- break;
- case 0x9C: /* TMIC0 */
- ret = read_irqcontrol(INTTU0, m_priority_inttu);
- break;
- case 0x9D: /* TMIC1 */
- ret = read_irqcontrol(INTTU1, 7);
- break;
- case 0x9E: /* TMIC2 */
- ret = read_irqcontrol(INTTU2, 7);
- break;
- case 0xEA: /* FLAG */
- ret = ((m_F0 << 3) | (m_F1 << 5));
- break;
- case 0xEB: /* PRC */
- ret = (m_RAMEN ? 0x40 : 0);
- switch (m_TB)
- {
- case 10:
- break;
- case 13:
- ret |= 0x04;
- break;
- case 16:
- ret |= 0x08;
- break;
- case 20:
- ret |= 0x0C;
- break;
- }
- switch (m_PCK)
- {
- case 2:
- break;
- case 4:
- ret |= 0x01;
- break;
- case 8:
- ret |= 0x02;
- break;
- }
- break;
- case 0xEC: /* TBIC */
- ret = read_irqcontrol(INTTB, 7);
- break;
- case 0xEF: /* IRQS */
- ret = m_IRQS;
- break;
- case 0xFC: /* ISPR */
- ret = m_ISPR;
- break;
- case 0xFF: /* IDB */
- ret = (m_IDB >> 12);
- break;
- default:
- logerror("%06x: Read from special function register %02x\n",PC(),o);
- ret = 0;
- }
- return ret;
-}
-
-uint16_t v25_common_device::read_sfr_word(unsigned o)
-{
- uint16_t ret;
-
- switch(o)
- {
- case 0x80: /* TM0 */
- logerror("%06x: Warning: read back TM0\n",PC());
- ret = m_TM0;
- break;
- case 0x82: /* MD0 */
- logerror("%06x: Warning: read back MD0\n",PC());
- ret = m_MD0;
- break;
- case 0x88: /* TM1 */
- logerror("%06x: Warning: read back TM1\n",PC());
- ret = m_TM1;
- break;
- case 0x8A: /* MD1 */
- logerror("%06x: Warning: read back MD1\n",PC());
- ret = m_MD1;
- break;
- default:
- ret = (read_sfr(o) | (read_sfr(o+1) << 8));
- }
- return ret;
-}
-
void v25_common_device::write_irqcontrol(int /*INTSOURCES*/ source, uint8_t d)
{
- if(d & 0x80)
+ if (BIT(d, 7))
m_pending_irq |= source;
else
m_pending_irq &= ~source;
- if(d & 0x40)
+ if (BIT(d, 6))
m_unmasked_irq &= ~source;
else
m_unmasked_irq |= source;
- if(d & 0x20)
+ if (BIT(d, 5))
logerror("%06x: Warning: macro service function not implemented\n",PC());
- if(d & 0x10)
+ if (BIT(d, 4))
m_bankswitch_irq |= source;
else
m_bankswitch_irq &= ~source;
}
-void v25_common_device::write_sfr(unsigned o, uint8_t d)
+uint8_t v25_common_device::p0_r()
{
- int tmp;
- attotime time;
+ return m_p0_in();
+}
- static const int timebases[4] = { 10, 13, 16, 20 };
- static const int clocks[4] = { 2, 4, 8, 0 };
+void v25_common_device::p0_w(uint8_t d)
+{
+ m_p0_out(d);
+}
- switch(o)
- {
- case 0x00: /* P0 */
- m_p0_out(d);
- break;
- case 0x08: /* P1 */
- /* only the upper four bits of P1 can be used as output */
- m_p1_out(d & 0xF0);
- break;
- case 0x10: /* P2 */
- m_p2_out(d);
- break;
- case 0x4C: /* EXIC0 */
- write_irqcontrol(INTP0, d);
- m_priority_intp = d & 0x7;
- break;
- case 0x4D: /* EXIC1 */
- write_irqcontrol(INTP1, d);
- break;
- case 0x4E: /* EXIC2 */
- write_irqcontrol(INTP2, d);
- break;
- case 0x90: /* TMC0 */
- m_TMC0 = d;
- if(d & 1) /* oneshot mode */
- {
- if(d & 0x80)
- {
- tmp = m_PCK * m_TM0 * ((d & 0x40) ? 128 : 12 );
- time = attotime::from_hz(unscaled_clock()) * tmp;
- m_timers[0]->adjust(time, INTTU0);
- }
- else
- m_timers[0]->adjust(attotime::never);
-
- if(d & 0x20)
- {
- tmp = m_PCK * m_MD0 * ((d & 0x10) ? 128 : 12 );
- time = attotime::from_hz(unscaled_clock()) * tmp;
- m_timers[1]->adjust(time, INTTU1);
- }
- else
- m_timers[1]->adjust(attotime::never);
- }
- else /* interval mode */
- {
- if(d & 0x80)
- {
- tmp = m_PCK * m_MD0 * ((d & 0x40) ? 128 : 6 );
- time = attotime::from_hz(unscaled_clock()) * tmp;
- m_timers[0]->adjust(time, INTTU0, time);
- m_timers[1]->adjust(attotime::never);
- m_TM0 = m_MD0;
- }
- else
- {
- m_timers[0]->adjust(attotime::never);
- m_timers[1]->adjust(attotime::never);
- }
- }
- break;
- case 0x91: /* TMC1 */
- m_TMC1 = d & 0xC0;
- if(d & 0x80)
- {
- tmp = m_PCK * m_MD1 * ((d & 0x40) ? 128 : 6 );
- time = attotime::from_hz(unscaled_clock()) * tmp;
- m_timers[2]->adjust(time, INTTU2, time);
- m_TM1 = m_MD1;
- }
- else
- m_timers[2]->adjust(attotime::never);
- break;
- case 0x9C: /* TMIC0 */
- write_irqcontrol(INTTU0, d);
- m_priority_inttu = d & 0x7;
- break;
- case 0x9D: /* TMIC1 */
- write_irqcontrol(INTTU1, d);
- break;
- case 0x9E: /* TMIC2 */
- write_irqcontrol(INTTU2, d);
- break;
- case 0xEA: /* FLAG */
- m_F0 = ((d & 0x08) == 0x08);
- m_F1 = ((d & 0x20) == 0x20);
- break;
- case 0xEB: /* PRC */
- logerror("%06x: PRC set to %02x\n", PC(), d);
- m_RAMEN = ((d & 0x40) == 0x40);
- m_TB = timebases[(d & 0x0C) >> 2];
- m_PCK = clocks[d & 0x03];
- if (m_PCK == 0)
- {
- logerror(" Warning: invalid clock divider\n");
- m_PCK = 8;
- }
- tmp = m_PCK << m_TB;
- time = attotime::from_hz(unscaled_clock()) * tmp;
- m_timers[3]->adjust(time, INTTB, time);
- notify_clock_changed(); /* make device_execute_interface pick up the new clocks_to_cycles() */
- logerror(" Internal RAM %sabled\n", (m_RAMEN ? "en" : "dis"));
- logerror(" Time base set to 2^%d\n", m_TB);
- logerror(" Clock divider set to %d\n", m_PCK);
- break;
- case 0xEC: /* TBIC */
- /* time base interrupt doesn't support macro service, bank switching or priority control */
- write_irqcontrol(INTTB, d & 0xC0);
- break;
- case 0xFF: /* IDB */
- m_IDB = (d << 12) | 0xE00;
- logerror("%06x: IDB set to %02x\n",PC(),d);
- break;
- default:
- logerror("%06x: Wrote %02x to special function register %02x\n",PC(),d,o);
- }
+void v25_common_device::pm0_w(uint8_t d)
+{
+ logerror("%06x: PM0 set to %02x\n", PC(), d);
}
-void v25_common_device::write_sfr_word(unsigned o, uint16_t d)
+void v25_common_device::pmc0_w(uint8_t d)
{
- switch(o)
- {
- case 0x80: /* TM0 */
- m_TM0 = d;
- break;
- case 0x82: /* MD0 */
- m_MD0 = d;
- break;
- case 0x88: /* TM1 */
- m_TM1 = d;
- break;
- case 0x8A: /* MD1 */
- m_MD1 = d;
- break;
- default:
- write_sfr(o, d);
- write_sfr(o+1, d >> 8);
- }
+ logerror("%06x: PMC0 set to %02x\n", PC(), d);
}
-uint8_t v25_common_device::v25_read_byte(unsigned a)
+uint8_t v25_common_device::p1_r()
{
- if((a & 0xFFE00) == m_IDB || a == 0xFFFFF)
- {
- unsigned o = a & 0x1FF;
+ // P1 is combined with the interrupt lines
+ return ((m_p1_in() & 0xf0)
+ | (m_nmi_state ? 0x00 : 0x01)
+ | (m_intp_state[0] ? 0x00 : 0x02)
+ | (m_intp_state[1] ? 0x00 : 0x04)
+ | (m_intp_state[2] ? 0x00 : 0x08));
+}
- if(m_RAMEN && o < 0x100)
- return m_ram.b[BYTE_XOR_LE(o)];
+void v25_common_device::p1_w(uint8_t d)
+{
+ // only the upper four bits of P1 can be used as output
+ m_p1_out(d & 0xf0);
+}
- if(o >= 0x100)
- return read_sfr(o-0x100);
- }
+void v25_common_device::pm1_w(uint8_t d)
+{
+ logerror("%06x: PM1 set to %02x\n", PC(), d);
+}
- return m_program->read_byte(a);
+void v25_common_device::pmc1_w(uint8_t d)
+{
+ logerror("%06x: PMC1 set to %02x\n", PC(), d);
}
-uint16_t v25_common_device::v25_read_word(unsigned a)
+uint8_t v25_common_device::p2_r()
{
- if( a & 1 )
- return (v25_read_byte(a) | (v25_read_byte(a + 1) << 8));
+ return m_p2_in();
+}
- if((a & 0xFFE00) == m_IDB)
- {
- unsigned o = a & 0x1FF;
+void v25_common_device::p2_w(uint8_t d)
+{
+ m_p2_out(d);
+}
- if(m_RAMEN && o < 0x100)
- return m_ram.w[o/2];
+void v25_common_device::pm2_w(uint8_t d)
+{
+ logerror("%06x: PM2 set to %02x\n", PC(), d);
+}
- if(o >= 0x100)
- return read_sfr_word(o-0x100);
- }
+void v25_common_device::pmc2_w(uint8_t d)
+{
+ logerror("%06x: PMC2 set to %02x\n", PC(), d);
+}
- if(a == 0xFFFFE) /* not sure about this - manual says FFFFC-FFFFE are "reserved" */
- return (m_program->read_byte(a) | (read_sfr(0xFF) << 8));
+uint8_t v25_common_device::pt_r()
+{
+ return m_pt_in();
+}
- return m_program->read_word(a);
+void v25_common_device::pmt_w(uint8_t d)
+{
+ logerror("%06x: PMT set to %02x\n", PC(), d);
}
-void v25_common_device::v25_write_byte(unsigned a, uint8_t d)
+uint8_t v25_common_device::exic0_r()
{
- if((a & 0xFFE00) == m_IDB || a == 0xFFFFF)
- {
- unsigned o = a & 0x1FF;
+ return read_irqcontrol(INTP0, m_priority_intp);
+}
+
+void v25_common_device::exic0_w(uint8_t d)
+{
+ write_irqcontrol(INTP0, d);
+ m_priority_intp = d & 0x7;
+}
+
+uint8_t v25_common_device::exic1_r()
+{
+ return read_irqcontrol(INTP1, 7);
+}
+
+void v25_common_device::exic1_w(uint8_t d)
+{
+ write_irqcontrol(INTP1, d);
+}
+
+uint8_t v25_common_device::exic2_r()
+{
+ return read_irqcontrol(INTP2, 7);
+}
- if(m_RAMEN && o < 0x100)
+void v25_common_device::exic2_w(uint8_t d)
+{
+ write_irqcontrol(INTP2, d);
+}
+
+uint16_t v25_common_device::tm0_r()
+{
+ if (!machine().side_effects_disabled())
+ logerror("%06x: Warning: read back TM0\n",PC());
+ return m_TM0;
+}
+
+void v25_common_device::tm0_w(uint16_t d)
+{
+ m_TM0 = d;
+}
+
+uint16_t v25_common_device::md0_r()
+{
+ if (!machine().side_effects_disabled())
+ logerror("%06x: Warning: read back MD0\n",PC());
+ return m_MD0;
+}
+
+void v25_common_device::md0_w(uint16_t d)
+{
+ m_MD0 = d;
+}
+
+uint16_t v25_common_device::tm1_r()
+{
+ if (!machine().side_effects_disabled())
+ logerror("%06x: Warning: read back TM1\n",PC());
+ return m_TM1;
+}
+
+void v25_common_device::tm1_w(uint16_t d)
+{
+ m_TM1 = d;
+}
+
+uint16_t v25_common_device::md1_r()
+{
+ if (!machine().side_effects_disabled())
+ logerror("%06x: Warning: read back MD1\n",PC());
+ return m_MD1;
+}
+
+void v25_common_device::md1_w(uint16_t d)
+{
+ m_MD1 = d;
+}
+
+void v25_common_device::tmc0_w(uint8_t d)
+{
+ m_TMC0 = d;
+ if (BIT(d, 0)) // oneshot mode
+ {
+ if (BIT(d, 7))
{
- m_ram.b[BYTE_XOR_LE(o)] = d;
- return;
+ unsigned tmp = m_PCK * m_TM0 * (BIT(d, 6) ? 128 : 12);
+ attotime time = clocks_to_attotime(tmp);
+ m_timers[0]->adjust(time, INTTU0);
}
+ else
+ m_timers[0]->adjust(attotime::never);
- if(o >= 0x100)
+ if (BIT(d, 5))
+ {
+ unsigned tmp = m_PCK * m_MD0 * (BIT(d, 4) ? 128 : 12);
+ attotime time = clocks_to_attotime(tmp);
+ m_timers[1]->adjust(time, INTTU1);
+ }
+ else
+ m_timers[1]->adjust(attotime::never);
+ }
+ else // interval mode
+ {
+ if (BIT(d, 7))
+ {
+ unsigned tmp = m_PCK * m_MD0 * (BIT(d, 6) ? 128 : 6);
+ attotime time = clocks_to_attotime(tmp);
+ m_timers[0]->adjust(time, INTTU0, time);
+ m_timers[1]->adjust(attotime::never);
+ m_TM0 = m_MD0;
+ }
+ else
{
- write_sfr(o-0x100, d);
- return;
+ m_timers[0]->adjust(attotime::never);
+ m_timers[1]->adjust(attotime::never);
}
}
+}
+
+void v25_common_device::tmc1_w(uint8_t d)
+{
+ m_TMC1 = d & 0xC0;
+ if (BIT(d, 7))
+ {
+ unsigned tmp = m_PCK * m_MD1 * (BIT(d, 6) ? 128 : 6);
+ attotime time = clocks_to_attotime(tmp);
+ m_timers[2]->adjust(time, INTTU2, time);
+ m_TM1 = m_MD1;
+ }
+ else
+ m_timers[2]->adjust(attotime::never);
+}
- m_program->write_byte(a, d);
+uint8_t v25_common_device::tmic0_r()
+{
+ return read_irqcontrol(INTTU0, m_priority_inttu);
}
-void v25_common_device::v25_write_word(unsigned a, uint16_t d)
+void v25_common_device::tmic0_w(uint8_t d)
+{
+ write_irqcontrol(INTTU0, d);
+ m_priority_inttu = d & 0x7;
+}
+
+uint8_t v25_common_device::tmic1_r()
+{
+ return read_irqcontrol(INTTU1, 7);
+}
+
+void v25_common_device::tmic1_w(uint8_t d)
+{
+ write_irqcontrol(INTTU1, d);
+}
+
+uint8_t v25_common_device::tmic2_r()
+{
+ return read_irqcontrol(INTTU2, 7);
+}
+
+void v25_common_device::tmic2_w(uint8_t d)
+{
+ write_irqcontrol(INTTU2, d);
+}
+
+uint8_t v25_common_device::rfm_r()
+{
+ return m_RFM;
+}
+
+void v25_common_device::rfm_w(uint8_t d)
+{
+ m_RFM = d;
+}
+
+uint16_t v25_common_device::wtc_r()
+{
+ return m_WTC;
+}
+
+void v25_common_device::wtc_w(offs_t a, uint16_t d, uint16_t m)
+{
+ m_WTC = (m_WTC & ~m) | (d & m);
+}
+
+uint8_t v25_common_device::flag_r()
+{
+ return (m_F0 << 3) | (m_F1 << 5);
+}
+
+void v25_common_device::flag_w(uint8_t d)
+{
+ m_F0 = BIT(d, 3);
+ m_F1 = BIT(d, 5);
+}
+
+uint8_t v25_common_device::prc_r()
{
- if( a & 1 )
+ uint8_t ret = m_RAMEN ? 0x40 : 0;
+
+ switch (m_TB)
{
- v25_write_byte(a, d);
- v25_write_byte(a + 1, d >> 8);
- return;
+ case 10:
+ break;
+ case 13:
+ ret |= 0x04;
+ break;
+ case 16:
+ ret |= 0x08;
+ break;
+ case 20:
+ ret |= 0x0C;
+ break;
}
- if((a & 0xFFE00) == m_IDB)
+ switch (m_PCK)
{
- unsigned o = a & 0x1FF;
+ case 2:
+ break;
+ case 4:
+ ret |= 0x01;
+ break;
+ case 8:
+ ret |= 0x02;
+ break;
+ }
- if(m_RAMEN && o < 0x100)
- {
- m_ram.w[o/2] = d;
- return;
- }
+ return ret;
+}
- if(o >= 0x100)
- {
- write_sfr_word(o-0x100, d);
- return;
- }
- }
+void v25_common_device::prc_w(uint8_t d)
+{
+ static const int timebases[4] = { 10, 13, 16, 20 };
+ static const int clocks[4] = { 2, 4, 8, 0 };
- if(a == 0xFFFFE) /* not sure about this - manual says FFFFC-FFFFE are "reserved" */
+ logerror("%06x: PRC set to %02x\n", PC(), d);
+ m_RAMEN = ((d & 0x40) == 0x40);
+ m_TB = timebases[(d & 0x0C) >> 2];
+ m_PCK = clocks[d & 0x03];
+ if (m_PCK == 0)
{
+ logerror(" Warning: invalid clock divider\n");
+ m_PCK = 8;
+ }
+
+ unsigned tmp = m_PCK << m_TB;
+ attotime time = clocks_to_attotime(tmp);
+ m_timers[3]->adjust(time, INTTB, time);
+ notify_clock_changed(); // make device_execute_interface pick up the new clocks_to_cycles()
+
+ logerror(" Internal RAM %sabled\n", (m_RAMEN ? "en" : "dis"));
+ logerror(" Time base set to 2^%d\n", m_TB);
+ logerror(" Clock divider set to %d\n", m_PCK);
+}
+
+uint8_t v25_common_device::tbic_r()
+{
+ return read_irqcontrol(INTTB, 7);
+}
+
+void v25_common_device::tbic_w(uint8_t d)
+{
+ // time base interrupt doesn't support macro service, bank switching or priority control
+ write_irqcontrol(INTTB, d & 0xC0);
+}
+
+uint8_t v25_common_device::irqs_r()
+{
+ return m_IRQS;
+}
+
+uint8_t v25_common_device::ispr_r()
+{
+ return m_ISPR;
+}
+
+uint8_t v25_common_device::idb_r()
+{
+ return m_IDB >> 12;
+}
+
+void v25_common_device::idb_w(uint8_t d)
+{
+ m_IDB = (d << 12) | 0xe00;
+}
+
+uint8_t v25_common_device::v25_read_byte(unsigned a)
+{
+ if (((a & 0xffe00) == m_IDB && (m_RAMEN || BIT(a, 8))) || a == 0xfffff)
+ return m_data->read_byte(a & 0x1ff);
+ else
+ return m_program->read_byte(a);
+}
+
+uint16_t v25_common_device::v25_read_word(unsigned a)
+{
+ if (BIT(a, 0))
+ return (v25_read_byte(a) | (v25_read_byte(a + 1) << 8));
+
+ // not sure about this - manual says FFFFC-FFFFE are "reserved"
+ if (a == 0xffffe)
+ return (m_program->read_byte(a) | (m_data->read_byte(0x1ff) << 8));
+ else if ((a & 0xffe00) == m_IDB && (m_RAMEN || BIT(a, 8)))
+ return m_data->read_word(a & 0x1ff);
+ else
+ return m_program->read_word(a);
+}
+
+void v25_common_device::v25_write_byte(unsigned a, uint8_t d)
+{
+ if (((a & 0xffe00) == m_IDB && (m_RAMEN || BIT(a, 8))) || a == 0xfffff)
+ m_data->write_byte(a & 0x1ff, d);
+ else
m_program->write_byte(a, d);
- write_sfr(0xFF, d >> 8);
+}
+
+void v25_common_device::v25_write_word(unsigned a, uint16_t d)
+{
+ if (BIT(a, 0))
+ {
+ v25_write_byte(a, d);
+ v25_write_byte(a + 1, d >> 8);
return;
}
- m_program->write_word(a, d);
+ // not sure about this - manual says FFFFC-FFFFE are "reserved"
+ if (a == 0xffffe)
+ {
+ m_program->write_byte(a, d);
+ m_data->write_byte(0x1ff, d >> 8);
+ }
+ else if ((a & 0xffe00) == m_IDB && (m_RAMEN || BIT(a, 8)))
+ m_data->write_word(a & 0x1ff, d);
+ else
+ m_program->write_word(a, d);
}