diff options
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 |
commit | 6141cf5b7a354debd7851a3b072aed23157d5b3d (patch) | |
tree | 49b8e88fd3ddb84464f811d08c9822f492e67582 | |
parent | a2e7f4f5f6d968e96db52b31cf2f0e3c4a0b8994 (diff) |
v25: Add address space for internal data area and SFRs
-rw-r--r-- | src/devices/cpu/nec/v25.cpp | 24 | ||||
-rw-r--r-- | src/devices/cpu/nec/v25.h | 71 | ||||
-rw-r--r-- | src/devices/cpu/nec/v25instr.hxx | 8 | ||||
-rw-r--r-- | src/devices/cpu/nec/v25priv.h | 6 | ||||
-rw-r--r-- | src/devices/cpu/nec/v25sfr.cpp | 726 |
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); } |