summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/avr8/avr8.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/avr8/avr8.cpp')
-rw-r--r--src/devices/cpu/avr8/avr8.cpp57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/devices/cpu/avr8/avr8.cpp b/src/devices/cpu/avr8/avr8.cpp
index cbd56d599e8..de75492ee7d 100644
--- a/src/devices/cpu/avr8/avr8.cpp
+++ b/src/devices/cpu/avr8/avr8.cpp
@@ -593,6 +593,7 @@ static const char avr8_reg_name[4] = { 'A', 'B', 'C', 'D' };
//**************************************************************************
DEFINE_DEVICE_TYPE(ATMEGA88, atmega88_device, "atmega88", "Atmel ATmega88")
+DEFINE_DEVICE_TYPE(ATMEGA168, atmega168_device, "atmega168", "Atmel ATmega168")
DEFINE_DEVICE_TYPE(ATMEGA328, atmega328_device, "atmega328", "Atmel ATmega328")
DEFINE_DEVICE_TYPE(ATMEGA644, atmega644_device, "atmega644", "Atmel ATmega644")
DEFINE_DEVICE_TYPE(ATMEGA1280, atmega1280_device, "atmega1280", "Atmel ATmega1280")
@@ -608,6 +609,11 @@ void atmega88_device::atmega88_internal_map(address_map &map)
map(0x0000, 0x00ff).rw(FUNC(atmega88_device::regs_r), FUNC(atmega88_device::regs_w));
}
+void atmega168_device::atmega168_internal_map(address_map &map)
+{
+ map(0x0000, 0x00ff).rw(FUNC(atmega168_device::regs_r), FUNC(atmega168_device::regs_w));
+}
+
void atmega328_device::atmega328_internal_map(address_map &map)
{
map(0x0000, 0x00ff).rw(FUNC(atmega328_device::regs_r), FUNC(atmega328_device::regs_w));
@@ -643,6 +649,15 @@ atmega88_device::atmega88_device(const machine_config &mconfig, const char *tag,
}
//-------------------------------------------------
+// atmega168_device - constructor
+//-------------------------------------------------
+
+atmega168_device::atmega168_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : avr8_device(mconfig, tag, owner, clock, ATMEGA168, 0x1fff, address_map_constructor(FUNC(atmega168_device::atmega168_internal_map), this), 3)
+{
+}
+
+//-------------------------------------------------
// atmega328_device - constructor
//-------------------------------------------------
@@ -1098,6 +1113,23 @@ void avr8_device::update_interrupt(int source)
}
}
+//TODO: review this!
+void atmega168_device::update_interrupt(int source)
+{
+ const interrupt_condition &condition = s_int_conditions[source];
+
+ int intstate = 0;
+ if (m_r[condition.m_intreg] & condition.m_intmask)
+ intstate = (m_r[condition.m_regindex] & condition.m_regmask) ? 1 : 0;
+
+ set_irq_line(condition.m_intindex << 1, intstate);
+
+ if (intstate)
+ {
+ m_r[condition.m_regindex] &= ~condition.m_regmask;
+ }
+}
+
void atmega328_device::update_interrupt(int source)
{
const interrupt_condition &condition = s_int_conditions[source];
@@ -1401,6 +1433,31 @@ inline void avr8_device::timer1_tick()
m_timer1_count = 0;
increment = 0;
}
+
+ switch (m_timer1_compare_mode[reg] & 3)
+ {
+ case 0: /* Normal Operation; OC1A/B disconnected */
+ break;
+
+ case 1: /* Toggle OC1A on compare match */
+ if (reg == 0)
+ {
+ LOGMASKED(LOG_TIMER1, "%s: timer1: Toggle OC1%c on match\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTB, m_io->read_byte(AVR8_IO_PORTB) ^ (2 << reg));
+ }
+ break;
+
+ case 2: /* Clear OC1A/B on compare match */
+ LOGMASKED(LOG_TIMER1, "%s: timer1: Clear OC1%c on match\n", machine().describe_context(), reg ? 'B' : 'A');
+ m_io->write_byte(AVR8_IO_PORTB, m_io->read_byte(AVR8_IO_PORTB) & ~(2 << reg));
+ break;
+
+ case 3: /* Set OC1A/B on compare match */
+ LOGMASKED(LOG_TIMER1, "%s: timer1: Set OC1%c on match\n", machine().describe_context(), reg ? 'B' : 'A');
+ m_io->write_byte(AVR8_IO_PORTB, m_io->read_byte(AVR8_IO_PORTB) | (2 << reg));
+ break;
+ }
+
m_r[AVR8_REGIDX_TIFR1] |= s_ocf1[reg];
update_interrupt(s_int1[reg]);
}