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.cpp3653
1 files changed, 1827 insertions, 1826 deletions
diff --git a/src/devices/cpu/avr8/avr8.cpp b/src/devices/cpu/avr8/avr8.cpp
index fbde839982e..6da6bf00f2a 100644
--- a/src/devices/cpu/avr8/avr8.cpp
+++ b/src/devices/cpu/avr8/avr8.cpp
@@ -62,22 +62,40 @@
#include "avr8dasm.h"
#include "debugger.h"
-#define VERBOSE_LEVEL (0)
-
-#define ENABLE_VERBOSE_LOG (0)
-
-static inline void ATTR_PRINTF(3, 4) verboselogout(device_t &dev, uint16_t pc, const char *s_fmt, ...)
-{
- va_list v;
- char buf[ 32768 ];
- va_start( v, s_fmt );
- vsprintf( buf, s_fmt, v );
- va_end( v );
- dev.logerror( "%05x: %s", pc << 1, buf );
-}
-
-#define verboselog(x,y,...) do { if (ENABLE_VERBOSE_LOG && (VERBOSE_LEVEL >= y)) verboselogout(*this, x, __VA_ARGS__); } while (false)
-
+#define LOG_UNKNOWN (1 << 1)
+#define LOG_BOOT (1 << 2)
+#define LOG_TIMER0 (1 << 3)
+#define LOG_TIMER1 (1 << 4)
+#define LOG_TIMER2 (1 << 5)
+#define LOG_TIMER3 (1 << 6)
+#define LOG_TIMER4 (1 << 7)
+#define LOG_TIMER5 (1 << 8)
+#define LOG_TIMER0_TICK (1 << 9)
+#define LOG_TIMER1_TICK (1 << 10)
+#define LOG_TIMER2_TICK (1 << 11)
+#define LOG_TIMER3_TICK (1 << 12)
+#define LOG_TIMER4_TICK (1 << 13)
+#define LOG_TIMER5_TICK (1 << 14)
+#define LOG_EEPROM (1 << 15)
+#define LOG_GPIO (1 << 16)
+#define LOG_WDOG (1 << 17)
+#define LOG_CLOCK (1 << 18)
+#define LOG_POWER (1 << 19)
+#define LOG_OSC (1 << 20)
+#define LOG_PINCHG (1 << 21)
+#define LOG_EXTMEM (1 << 22)
+#define LOG_ADC (1 << 23)
+#define LOG_DIGINPUT (1 << 24)
+#define LOG_ASYNC (1 << 25)
+#define LOG_TWI (1 << 26)
+#define LOG_UART (1 << 27)
+#define LOG_TIMERS (LOG_TIMER0 | LOG_TIMER1 | LOG_TIMER2 | LOG_TIMER3 | LOG_TIMER4 | LOG_TIMER5)
+#define LOG_TIMER_TICKS (LOG_TIMER0_TICK | LOG_TIMER1_TICK | LOG_TIMER2_TICK | LOG_TIMER3_TICK | LOG_TIMER4_TICK | LOG_TIMER5_TICK)
+#define LOG_ALL (LOG_UNKNOWN | LOG_BOOT | LOG_TIMERS | LOG_TIMER_TICKS | LOG_EEPROM | LOG_GPIO | LOG_WDOG | LOG_CLOCK | LOG_POWER \
+ LOG_OSC | LOG_PINCHG | LOG_EXTMEM | LOG_ADC | LOG_DIGINPUT | LOG_ASYNC | LOG_TWI | LOG_UART)
+
+#define VERBOSE (0)
+#include "logmacro.h"
//**************************************************************************
// ENUMS AND MACROS
@@ -568,6 +586,7 @@ DEFINE_DEVICE_TYPE(ATMEGA88, atmega88_device, "atmega88", "Atmel ATmega88"
DEFINE_DEVICE_TYPE(ATMEGA644, atmega644_device, "atmega644", "Atmel ATmega644")
DEFINE_DEVICE_TYPE(ATMEGA1280, atmega1280_device, "atmega1280", "Atmel ATmega1280")
DEFINE_DEVICE_TYPE(ATMEGA2560, atmega2560_device, "atmega2560", "Atmel ATmega2560")
+DEFINE_DEVICE_TYPE(ATTINY15, attiny15_device, "attiny15", "Atmel ATtiny15")
//**************************************************************************
// INTERNAL ADDRESS MAP
@@ -593,12 +612,17 @@ void atmega2560_device::atmega2560_internal_map(address_map &map)
map(0x0000, 0x01ff).rw(FUNC(atmega2560_device::regs_r), FUNC(atmega2560_device::regs_w));
}
+void attiny15_device::attiny15_internal_map(address_map &map)
+{
+ map(0x00, 0x1f).rw(FUNC(attiny15_device::regs_r), FUNC(attiny15_device::regs_w));
+}
+
//-------------------------------------------------
// atmega88_device - constructor
//-------------------------------------------------
atmega88_device::atmega88_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : avr8_device(mconfig, tag, owner, clock, ATMEGA88, 0x0fff, address_map_constructor(FUNC(atmega88_device::atmega88_internal_map), this), CPU_TYPE_ATMEGA88)
+ : avr8_device(mconfig, tag, owner, clock, ATMEGA88, 0x0fff, address_map_constructor(FUNC(atmega88_device::atmega88_internal_map), this))
{
}
@@ -607,7 +631,7 @@ atmega88_device::atmega88_device(const machine_config &mconfig, const char *tag,
//-------------------------------------------------
atmega644_device::atmega644_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : avr8_device(mconfig, tag, owner, clock, ATMEGA644, 0xffff, address_map_constructor(FUNC(atmega644_device::atmega644_internal_map), this), CPU_TYPE_ATMEGA644)
+ : avr8_device(mconfig, tag, owner, clock, ATMEGA644, 0xffff, address_map_constructor(FUNC(atmega644_device::atmega644_internal_map), this))
{
}
@@ -616,7 +640,7 @@ atmega644_device::atmega644_device(const machine_config &mconfig, const char *ta
//-------------------------------------------------
atmega1280_device::atmega1280_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : avr8_device(mconfig, tag, owner, clock, ATMEGA1280, 0x1ffff, address_map_constructor(FUNC(atmega1280_device::atmega1280_internal_map), this), CPU_TYPE_ATMEGA1280)
+ : avr8_device(mconfig, tag, owner, clock, ATMEGA1280, 0x1ffff, address_map_constructor(FUNC(atmega1280_device::atmega1280_internal_map), this))
{
}
@@ -625,7 +649,16 @@ atmega1280_device::atmega1280_device(const machine_config &mconfig, const char *
//-------------------------------------------------
atmega2560_device::atmega2560_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : avr8_device(mconfig, tag, owner, clock, ATMEGA2560, 0x1ffff, address_map_constructor(FUNC(atmega2560_device::atmega2560_internal_map), this), CPU_TYPE_ATMEGA2560)
+ : avr8_device(mconfig, tag, owner, clock, ATMEGA2560, 0x1ffff, address_map_constructor(FUNC(atmega2560_device::atmega2560_internal_map), this))
+{
+}
+
+//-------------------------------------------------
+// attiny15_device - constructor
+//-------------------------------------------------
+
+attiny15_device::attiny15_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : avr8_device(mconfig, tag, owner, clock, ATTINY15, 0x03ff, address_map_constructor(FUNC(attiny15_device::attiny15_internal_map), this))
{
}
@@ -633,18 +666,17 @@ atmega2560_device::atmega2560_device(const machine_config &mconfig, const char *
// avr8_device - constructor
//-------------------------------------------------
-avr8_device::avr8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, uint32_t addr_mask, address_map_constructor internal_map, uint8_t cpu_type)
+avr8_device::avr8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, uint32_t addr_mask, address_map_constructor internal_map)
: cpu_device(mconfig, type, tag, owner, clock)
, m_shifted_pc(0)
, m_program_config("program", ENDIANNESS_LITTLE, 8, 22)
, m_data_config("data", ENDIANNESS_LITTLE, 8, 16, 0, internal_map)
, m_io_config("io", ENDIANNESS_LITTLE, 8, 4)
, m_eeprom(*this, finder_base::DUMMY_TAG)
- , m_cpu_type(cpu_type)
, m_lfuses(0x62)
, m_hfuses(0x99)
- , m_efuses(0xFF)
- , m_lock_bits(0xFF)
+ , m_efuses(0xff)
+ , m_lock_bits(0xff)
, m_pc(0)
, m_spi_active(false)
, m_spi_prescale(0)
@@ -653,14 +685,6 @@ avr8_device::avr8_device(const machine_config &mconfig, const char *tag, device_
, m_interrupt_pending(false)
, m_elapsed_cycles(0)
{
- // Allocate & setup
-
- for (int t=0; t<=5; t++){
- m_timer_top[t] = 0;
- m_timer_increment[t] = 1;
- m_timer_prescale[t] = 0;
- m_timer_prescale_count[t] = 0;
- }
}
@@ -719,18 +743,18 @@ void avr8_device::unimplemented_opcode(uint32_t op)
inline bool avr8_device::is_long_opcode(uint16_t op)
{
- if((op & 0xf000) == 0x9000)
+ if ((op & 0xf000) == 0x9000)
{
- if((op & 0x0f00) < 0x0400)
+ if ((op & 0x0f00) < 0x0400)
{
- if((op & 0x000f) == 0x0000)
+ if ((op & 0x000f) == 0x0000)
{
return true;
}
}
- else if((op & 0x0f00) < 0x0600)
+ else if ((op & 0x0f00) < 0x0600)
{
- if((op & 0x000f) >= 0x000c)
+ if ((op & 0x000f) >= 0x000c)
{
return true;
}
@@ -793,12 +817,28 @@ void avr8_device::device_start()
state_add(AVR8_R31, "R31", m_r[31]).mask(0xff);
// register our state for saving
+ save_item(NAME(m_boot_size));
+ save_item(NAME(m_lfuses));
+ save_item(NAME(m_hfuses));
+ save_item(NAME(m_efuses));
+ save_item(NAME(m_lock_bits));
save_item(NAME(m_pc));
save_item(NAME(m_r));
+
+ // Timers
save_item(NAME(m_timer_top));
save_item(NAME(m_timer_increment));
save_item(NAME(m_timer_prescale));
save_item(NAME(m_timer_prescale_count));
+ save_item(NAME(m_ocr2_not_reached_yet));
+
+ // SPI
+ save_item(NAME(m_spi_active));
+ save_item(NAME(m_spi_prescale));
+ save_item(NAME(m_spi_prescale_count));
+ save_item(NAME(m_spi_prescale_countdown));
+
+ // Misc.
save_item(NAME(m_addr_mask));
save_item(NAME(m_interrupt_pending));
save_item(NAME(m_elapsed_cycles));
@@ -818,7 +858,8 @@ void avr8_device::device_reset()
logerror("AVR extended fuse bits: 0x%02X\n", m_efuses);
logerror("AVR lock bits: 0x%02X\n", m_lock_bits);
- switch ((m_hfuses & (BOOTSZ1|BOOTSZ0)) >> 1){
+ switch ((m_hfuses & (BOOTSZ1 | BOOTSZ0)) >> 1)
+ {
case 0: m_boot_size = 4096; break;
case 1: m_boot_size = 2048; break;
case 2: m_boot_size = 1024; break;
@@ -826,24 +867,26 @@ void avr8_device::device_reset()
default: break;
}
- if (m_hfuses & BOOTRST){
- m_shifted_pc = 0x0000;
- logerror("Booting AVR core from address 0x0000\n");
+ if (m_hfuses & BOOTRST)
+ {
+ m_shifted_pc = 0x0000;
+ LOGMASKED(LOG_BOOT, "Booting AVR core from address 0x0000\n");
} else {
- m_shifted_pc = (m_addr_mask + 1) - 2*m_boot_size;
- logerror("AVR Boot loader section size: %d words\n", m_boot_size);
+ m_shifted_pc = (m_addr_mask + 1) - 2*m_boot_size;
+ LOGMASKED(LOG_BOOT, "AVR Boot loader section size: %d words\n", m_boot_size);
}
- for (auto & elem : m_r)
+ for (int i = 0; i < 0x200; i++)
{
- elem = 0;
+ m_r[i] = 0;
}
m_spi_active = false;
m_spi_prescale = 0;
m_spi_prescale_count = 0;
- for (int t=0; t<=5; t++){
+ for (int t = 0; t <= 5; t++)
+ {
m_timer_top[t] = 0;
m_timer_increment[t] = 1;
m_timer_prescale[t] = 0;
@@ -879,17 +922,17 @@ void avr8_device::state_string_export(const device_state_entry &entry, std::stri
{
switch (entry.index())
{
- case STATE_GENFLAGS:
- str = string_format("%c%c%c%c%c%c%c%c",
- (m_r[AVR8_REGIDX_SREG] & 0x80) ? 'I' : '-',
- (m_r[AVR8_REGIDX_SREG] & 0x40) ? 'T' : '-',
- (m_r[AVR8_REGIDX_SREG] & 0x20) ? 'H' : '-',
- (m_r[AVR8_REGIDX_SREG] & 0x10) ? 'S' : '-',
- (m_r[AVR8_REGIDX_SREG] & 0x08) ? 'V' : '-',
- (m_r[AVR8_REGIDX_SREG] & 0x04) ? 'N' : '-',
- (m_r[AVR8_REGIDX_SREG] & 0x02) ? 'Z' : '-',
- (m_r[AVR8_REGIDX_SREG] & 0x01) ? 'C' : '-');
- break;
+ case STATE_GENFLAGS:
+ str = string_format("%c%c%c%c%c%c%c%c",
+ (m_r[AVR8_REGIDX_SREG] & 0x80) ? 'I' : '-',
+ (m_r[AVR8_REGIDX_SREG] & 0x40) ? 'T' : '-',
+ (m_r[AVR8_REGIDX_SREG] & 0x20) ? 'H' : '-',
+ (m_r[AVR8_REGIDX_SREG] & 0x10) ? 'S' : '-',
+ (m_r[AVR8_REGIDX_SREG] & 0x08) ? 'V' : '-',
+ (m_r[AVR8_REGIDX_SREG] & 0x04) ? 'N' : '-',
+ (m_r[AVR8_REGIDX_SREG] & 0x02) ? 'Z' : '-',
+ (m_r[AVR8_REGIDX_SREG] & 0x01) ? 'C' : '-');
+ break;
}
}
@@ -929,9 +972,9 @@ inline uint8_t avr8_device::pop()
void avr8_device::set_irq_line(uint16_t vector, int state)
{
// Horrible hack, not accurate
- if(state)
+ if (state)
{
- if(SREG_R(AVR8_SREG_I))
+ if (SREG_R(AVR8_SREG_I))
{
SREG_W(AVR8_SREG_I, 0);
push(m_pc & 0x00ff);
@@ -1059,10 +1102,9 @@ void atmega2560_device::update_interrupt(int source)
//**************************************************************************
void avr8_device::timer_tick(int cycles)
{
- for(int count = 0; count < cycles; count++)
+ for (int count = 0; count < cycles; count++)
{
m_elapsed_cycles++;
-
if (m_spi_active && m_spi_prescale > 0 && m_spi_prescale_countdown >= 0)
{
m_spi_prescale_count++;
@@ -1076,25 +1118,26 @@ void avr8_device::timer_tick(int cycles)
}
}
- for (int t=0; t<=5; t++){
+ for (int t = 0; t <= 5; t++)
+ {
if (m_timer_prescale[t] != 0)
{
m_timer_prescale_count[t]++;
if (m_timer_prescale_count[t] >= m_timer_prescale[t])
{
- switch (t){
- case 0: timer0_tick(); break;
- case 1: timer1_tick(); break;
- case 2: timer2_tick(); break;
- case 3: timer3_tick(); break;
- case 4: timer4_tick(); break;
- case 5: timer5_tick(); break;
- }
+ switch (t)
+ {
+ case 0: timer0_tick(); break;
+ case 1: timer1_tick(); break;
+ case 2: timer2_tick(); break;
+ case 3: timer3_tick(); break;
+ case 4: timer4_tick(); break;
+ case 5: timer5_tick(); break;
+ }
m_timer_prescale_count[t] -= m_timer_prescale[t];
}
}
- }
-
+ }
}
}
@@ -1107,77 +1150,77 @@ void avr8_device::timer_tick(int cycles)
// Timer 0 Handling
void avr8_device::timer0_tick()
{
-#if LOG_TIMER_0
- printf("AVR8_WGM0: %d\n", AVR8_WGM0);
- printf("AVR8_TCCR0A_COM0B: %d\n", AVR8_TCCR0A_COM0B);
-#endif
+ LOGMASKED(LOG_TIMER0_TICK, "%s: AVR8_WGM0: %d\n", machine().describe_context(), AVR8_WGM0);
+ LOGMASKED(LOG_TIMER0_TICK, "%s: AVR8_TCCR0A_COM0B: %d\n", machine().describe_context(), AVR8_TCCR0A_COM0B);
uint8_t count = m_r[AVR8_REGIDX_TCNT0];
int32_t increment = m_timer_increment[0];
- switch(AVR8_WGM0)
+ switch (AVR8_WGM0)
{
- case WGM02_NORMAL:
- //printf("WGM02_NORMAL: Unimplemented timer#0 waveform generation mode\n");
+ case WGM02_NORMAL:
+ LOGMASKED(LOG_TIMER0, "%s: WGM02_NORMAL: Unimplemented timer#0 waveform generation mode\n", machine().describe_context());
break;
- case WGM02_PWM_PC:
- //printf("WGM02_PWM_PC: Unimplemented timer#0 waveform generation mode\n");
+ case WGM02_PWM_PC:
+ LOGMASKED(LOG_TIMER0, "%s: WGM02_PWM_PC: Unimplemented timer0 waveform generation mode\n", machine().describe_context());
break;
- case WGM02_CTC_CMP:
- switch(AVR8_TCCR0A_COM0B){
+ case WGM02_CTC_CMP:
+ switch (AVR8_TCCR0A_COM0B)
+ {
case 0: /* Normal Operation */
- if (count == m_timer_top[0]){
- m_timer_top[0] = 0;
+ if (count == m_timer_top[0])
+ {
+ LOGMASKED(LOG_TIMER0, "%s: timer0: Set normal OC0B behavior\n", machine().describe_context());
+ m_timer_top[0] = 0;
}
break;
+
case 1: /* Toggle OC0B on compare match */
- if (count == m_timer_top[0]){
- m_timer_top[0] = 0;
-#if LOG_TIMER_0
- printf("[0] Toggle OC0B\n");
-#endif
- m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) ^ (1 << 5));
+ if (count == m_timer_top[0])
+ {
+ m_timer_top[0] = 0;
+ LOGMASKED(LOG_TIMER0, "%s: timer0: Toggle OC0B on match\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) ^ (1 << 5));
}
break;
+
case 2: /* Clear OC0B on compare match */
- if (count == m_timer_top[0]){
- m_timer_top[0] = 0;
- //Clear OC0B
-#if LOG_TIMER_0
- printf("[0] Clear OC0B\n");
-#endif
- m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) & ~(1 << 5));
+ if (count == m_timer_top[0])
+ {
+ m_timer_top[0] = 0;
+ LOGMASKED(LOG_TIMER0, "[0] timer0: Clear OC0B on match\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) & ~(1 << 5));
}
break;
+
case 3: /* Set OC0B on compare match */
- if (count == m_timer_top[0]){
- m_timer_top[0] = 0;
-#if LOG_TIMER_0
- printf("[0] Set OC0B\n");
-#endif
- m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) | (1 << 5));
+ if (count == m_timer_top[0])
+ {
+ m_timer_top[0] = 0;
+ LOGMASKED(LOG_TIMER0, "%s: timer0: Set OC0B on match\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) | (1 << 5));
}
break;
}
break;
- case WGM02_FAST_PWM:
- printf("WGM02_FAST_PWM: Unimplemented timer#0 waveform generation mode\n");
- break;
+ case WGM02_FAST_PWM:
+ LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: WGM02_FAST_PWM: Unimplemented timer0 waveform generation mode\n", machine().describe_context());
+ break;
- case WGM02_PWM_PC_CMP:
- printf("WGM02_PWM_PC_CMP: Unimplemented timer#0 waveform generation mode\n");
- break;
+ case WGM02_PWM_PC_CMP:
+ LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: WGM02_PWM_PC_CMP: Unimplemented timer0 waveform generation mode\n", machine().describe_context());
+ break;
- case WGM02_FAST_PWM_CMP:
- printf("WGM02_FAST_PWM_CMP: Unimplemented timer#0 waveform generation mode\n");
- break;
+ case WGM02_FAST_PWM_CMP:
+ LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: WGM02_FAST_PWM_CMP: Unimplemented timer0 waveform generation mode\n", machine().describe_context());
+ break;
- default:
- verboselog(m_pc, 0, "update_timer0_compare_mode: Unknown waveform generation mode: %02x\n", AVR8_WGM0);
- break;
+ default:
+ LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: update_timer0_compare_mode: Unknown waveform generation mode: %02x\n", machine().describe_context(), AVR8_WGM0);
+ break;
}
count = count & 0xff;
@@ -1194,7 +1237,7 @@ void avr8_device::changed_tccr0a(uint8_t data)
AVR8_TCCR0A = data;
- if(changed & AVR8_TCCR0A_WGM0_10_MASK)
+ if (changed & AVR8_TCCR0A_WGM0_10_MASK)
{
update_timer_waveform_gen_mode(0, AVR8_WGM0);
}
@@ -1202,13 +1245,12 @@ void avr8_device::changed_tccr0a(uint8_t data)
void avr8_device::timer0_force_output_compare(int reg)
{
- // TODO
- verboselog(m_pc, 0, "timer0_force_output_compare: TODO; should be forcing OC0%c\n", avr8_reg_name[reg]);
+ LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: timer0_force_output_compare: TODO; should be forcing OC0%c\n", machine().describe_context(), avr8_reg_name[reg]);
}
void avr8_device::changed_tccr0b(uint8_t data)
{
- if (VERBOSE_LEVEL) printf("changed_tccr0b: data=0x%02X\n", data);
+ LOGMASKED(LOG_TIMER0, "%s: changed_tccr0b: data = 0x%02X\n", machine().describe_context(), data);
uint8_t oldtccr = AVR8_TCCR0B;
uint8_t newtccr = data;
@@ -1216,24 +1258,24 @@ void avr8_device::changed_tccr0b(uint8_t data)
AVR8_TCCR0B = data;
- if(changed & AVR8_TCCR0B_FOC0A_MASK)
+ if (changed & AVR8_TCCR0B_FOC0A_MASK)
{
// TODO
timer0_force_output_compare(AVR8_REG_A);
}
- if(changed & AVR8_TCCR0B_FOC0B_MASK)
+ if (changed & AVR8_TCCR0B_FOC0B_MASK)
{
// TODO
timer0_force_output_compare(AVR8_REG_B);
}
- if(changed & AVR8_TCCR0B_WGM0_2_MASK)
+ if (changed & AVR8_TCCR0B_WGM0_2_MASK)
{
update_timer_waveform_gen_mode(0, AVR8_WGM0);
}
- if(changed & AVR8_TCCR0B_CS_MASK)
+ if (changed & AVR8_TCCR0B_CS_MASK)
{
update_timer_clock_source(0, AVR8_TIMER0_CLOCK_SELECT);
}
@@ -1248,104 +1290,135 @@ void avr8_device::update_ocr0(uint8_t newval, uint8_t reg)
void avr8_device::timer1_tick()
{
- /* TODO: Handle comparison, setting OC1x pins, detection of BOTTOM and TOP */
+ /* TODO: Handle comparison, setting OC1A pin, detection of BOTTOM and TOP */
uint16_t count = (m_r[AVR8_REGIDX_TCNT1H] << 8) | m_r[AVR8_REGIDX_TCNT1L];
int32_t wgm1 = ((m_r[AVR8_REGIDX_TCCR1B] & AVR8_TCCR1B_WGM1_32_MASK) >> 1) |
(m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_WGM1_10_MASK);
- // Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer
- //uint8_t compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT,
- //(m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_COM1B_MASK) >> AVR8_TCCR1A_COM1B_SHIFT };
+ int32_t compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT,
+ (m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_COM1B_MASK) >> AVR8_TCCR1A_COM1B_SHIFT };
uint16_t ocr1[2] = { static_cast<uint16_t>((m_r[AVR8_REGIDX_OCR1AH] << 8) | m_r[AVR8_REGIDX_OCR1AL]),
static_cast<uint16_t>((m_r[AVR8_REGIDX_OCR1BH] << 8) | m_r[AVR8_REGIDX_OCR1BL]) };
uint8_t ocf1[2] = { (1 << AVR8_TIFR1_OCF1A_SHIFT), (1 << AVR8_TIFR1_OCF1B_SHIFT) };
uint8_t int1[2] = { AVR8_INTIDX_OCF1A, AVR8_INTIDX_OCF1B };
int32_t increment = m_timer_increment[1];
- for(int32_t reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
+ for (int32_t reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
{
- switch(wgm1)
+ switch (wgm1)
{
- case WGM1_CTC_OCR:
- if (count == 0xffff)
+ case WGM1_CTC_OCR:
+ if (count == 0xffff)
+ {
+ m_r[AVR8_REGIDX_TIFR1] |= AVR8_TIFR1_TOV1_MASK;
+ update_interrupt(AVR8_INTIDX_TOV1);
+ count = 0;
+ increment = 0;
+ }
+
+ if (count == ocr1[reg])
+ {
+ if (reg == 0)
{
- m_r[AVR8_REGIDX_TIFR1] |= AVR8_TIFR1_TOV1_MASK;
- update_interrupt(AVR8_INTIDX_TOV1);
count = 0;
increment = 0;
}
+ m_r[AVR8_REGIDX_TIFR1] |= ocf1[reg];
+ update_interrupt(int1[reg]);
+ }
+ else if (count == 0)
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK;
+ update_interrupt(AVR8_INTIDX_TOV1);
+ }
- if (count == ocr1[reg])
+ m_r[AVR8_REGIDX_TIFR1] &= ~ocf1[reg];
+ update_interrupt(int1[reg]);
+ }
+ break;
+
+ case WGM1_FAST_PWM_OCR:
+ if (count == ocr1[reg])
+ {
+ if (reg == 0)
{
- if (reg == 0)
- {
- count = 0;
- increment = 0;
- }
- m_r[AVR8_REGIDX_TIFR1] |= ocf1[reg];
- update_interrupt(int1[reg]);
+ m_r[AVR8_REGIDX_TIFR1] |= AVR8_TIFR1_TOV1_MASK;
+ update_interrupt(AVR8_INTIDX_TOV1);
+ count = 0;
+ increment = 0;
}
- else if (count == 0)
+
+ switch (compare_mode[reg])
{
+ case 0: /* Normal Operation; OC1A/B disconnected */
+ break;
+
+ case 1: /* Toggle OC1A on compare match */
if (reg == 0)
{
- m_r[AVR8_REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK;
- update_interrupt(AVR8_INTIDX_TOV1);
+ 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;
- m_r[AVR8_REGIDX_TIFR1] &= ~ocf1[reg];
- update_interrupt(int1[reg]);
+ 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;
}
- break;
- case WGM1_FAST_PWM_OCR:
- if(count == ocr1[reg])
+ m_r[AVR8_REGIDX_TIFR1] |= ocf1[reg];
+ update_interrupt(int1[reg]);
+ }
+ else if (count == 0)
+ {
+ if (reg == 0)
{
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR1] |= AVR8_TIFR1_TOV1_MASK;
- update_interrupt(AVR8_INTIDX_TOV1);
- count = 0;
- increment = 0;
- }
-
- m_r[AVR8_REGIDX_TIFR1] |= ocf1[reg];
- update_interrupt(int1[reg]);
+ m_r[AVR8_REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK;
+ update_interrupt(AVR8_INTIDX_TOV1);
}
- else if(count == 0)
+
+ switch (compare_mode[reg])
{
+ case 0: /* Normal Operation; OC1A/B disconnected */
+ break;
+
+ case 1: /* Toggle OC1A at BOTTOM*/
if (reg == 0)
{
- m_r[AVR8_REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK;
- update_interrupt(AVR8_INTIDX_TOV1);
+ LOGMASKED(LOG_TIMER1, "%s: timer1: Toggle OC1A at BOTTOM\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTB, m_io->read_byte(AVR8_IO_PORTB) ^ (2 << reg));
}
+ break;
- m_r[AVR8_REGIDX_TIFR1] &= ~ocf1[reg];
- update_interrupt(int1[reg]);
- }
- break;
+ case 2: /* Set OC1A/B at BOTTOM*/
+ LOGMASKED(LOG_TIMER1, "%s: timer1: Set OC1%c at BOTTOM\n", machine().describe_context(), reg ? 'B' : 'A');
+ m_io->write_byte(AVR8_IO_PORTB, m_io->read_byte(AVR8_IO_PORTB) | (2 << reg));
+ break;
- default:
- verboselog(m_pc, 0, "update_timer1_compare_mode: Unknown waveform generation mode: %02x\n", wgm1);
- break;
- }
- /*
- switch(compare_mode[reg])
- {
- case 0:
- //verboselog(m_pc, 0, "update_timer1_compare_mode: Normal port operation (OC1 disconnected)\n");
- break;
+ case 3: /* Clear OC1A/B at BOTTOM */
+ LOGMASKED(LOG_TIMER1, "%s: timer1: Clear OC1%c at BOTTOM\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 1:
- case 2:
- // TODO
- break;
+ m_r[AVR8_REGIDX_TIFR1] &= ~ocf1[reg];
+ update_interrupt(int1[reg]);
+ }
+ break;
- case 3:
- break;
+ default:
+ LOGMASKED(LOG_TIMER1 | LOG_UNKNOWN, "%s: timer1_tick: Unknown waveform generation mode: %02x\n", machine().describe_context(), wgm1);
+ break;
}
- */
}
count += increment;
@@ -1357,7 +1430,8 @@ void avr8_device::update_timer_waveform_gen_mode(uint8_t t, uint8_t mode)
{
int32_t oc_val = -1, ic_val = -1;
- switch (t){
+ switch (t)
+ {
case 0:
oc_val = AVR8_OCR0A;
ic_val = -1;
@@ -1384,29 +1458,37 @@ void avr8_device::update_timer_waveform_gen_mode(uint8_t t, uint8_t mode)
break;
}
- int32_t top_values_02[8] = {0xFF, 0xFF, oc_val, 0xFF, -1, oc_val, -1, oc_val}; //table 20-8
+ static const int32_t s_top_values_02[8] =
+ {
+ 0xff, 0xff, oc_val, 0xff, -1, oc_val, -1, oc_val
+ }; //table 20-8
- int32_t top_values_1345[16] = {0xFFFF, 0x00FF, 0x01FF, 0x03FF,
- oc_val, 0x00FF, 0x01FF, 0x03FF,
- ic_val, oc_val, ic_val, oc_val,
- ic_val, -1, ic_val, oc_val}; //table 17-2
+ static const int32_t s_top_values_1345[16] =
+ {
+ 0xffff, 0x00ff, 0x01ff, 0x03ff,
+ oc_val, 0x00ff, 0x01ff, 0x03ff,
+ ic_val, oc_val, ic_val, oc_val,
+ ic_val, -1, ic_val, oc_val
+ }; //table 17-2
- switch(t){
+ switch (t)
+ {
case 0:
case 2:
- m_timer_top[t] = top_values_02[mode];
+ m_timer_top[t] = s_top_values_02[mode];
break;
case 1:
case 3:
case 4:
case 5:
- m_timer_top[t] = top_values_1345[mode];
+ m_timer_top[t] = s_top_values_1345[mode];
break;
}
- if (m_timer_top[t] == -1){
- m_timer_top[t] = 0;
- printf("update_timer_waveform_gen_mode: Timer #%d - Unsupported waveform generation type: %d\n", t, mode);
+ if (m_timer_top[t] == -1)
+ {
+ m_timer_top[t] = 0;
+ LOGMASKED((LOG_TIMER0 + t), "%s: update_timer_waveform_gen_mode: Timer %d - Unsupported waveform generation type: %d\n", machine().describe_context(), t, mode);
}
}
@@ -1418,7 +1500,7 @@ void avr8_device::changed_tccr1a(uint8_t data)
m_r[AVR8_REGIDX_TCCR1A] = newtccr;
- if(changed & AVR8_TCCR1A_WGM1_10_MASK)
+ if (changed & AVR8_TCCR1A_WGM1_10_MASK)
{
update_timer_waveform_gen_mode(1, AVR8_WGM1);
}
@@ -1426,18 +1508,17 @@ void avr8_device::changed_tccr1a(uint8_t data)
void avr8_device::update_timer1_input_noise_canceler()
{
- // TODO
+ LOGMASKED(LOG_TIMER1 | LOG_UNKNOWN, "%s: update_timer1_input_noise_canceler: TODO\n", machine().describe_context());
}
void avr8_device::update_timer1_input_edge_select()
{
- // TODO
- //verboselog(m_pc, 0, "update_timer1_input_edge_select: TODO; Clocking edge is %s\n", "test");
+ LOGMASKED(LOG_TIMER1 | LOG_UNKNOWN, "%s: update_timer1_input_edge_select: TODO\n", machine().describe_context());
}
void avr8_device::changed_tccr1b(uint8_t data)
{
- if (VERBOSE_LEVEL) printf("changed_tccr1b: data=0x%02X\n", data);
+ LOGMASKED(LOG_TIMER1, "%s: changed_tccr1b: data = 0x%02X\n", machine().describe_context(), data);
uint8_t oldtccr = AVR8_TCCR1B;
uint8_t newtccr = data;
@@ -1445,24 +1526,22 @@ void avr8_device::changed_tccr1b(uint8_t data)
m_r[AVR8_REGIDX_TCCR1B] = newtccr;
- if(changed & AVR8_TCCR1B_ICNC1_MASK)
+ if (changed & AVR8_TCCR1B_ICNC1_MASK)
{
- // TODO
update_timer1_input_noise_canceler();
}
- if(changed & AVR8_TCCR1B_ICES1_MASK)
+ if (changed & AVR8_TCCR1B_ICES1_MASK)
{
- // TODO
update_timer1_input_edge_select();
}
- if(changed & AVR8_TCCR1B_WGM1_32_MASK)
+ if (changed & AVR8_TCCR1B_WGM1_32_MASK)
{
update_timer_waveform_gen_mode(1, AVR8_WGM1);
}
- if(changed & AVR8_TCCR1B_CS_MASK)
+ if (changed & AVR8_TCCR1B_CS_MASK)
{
update_timer_clock_source(1, AVR8_TIMER1_CLOCK_SELECT);
}
@@ -1493,76 +1572,60 @@ void avr8_device::timer2_tick()
uint8_t ocf2[2] = { (1 << AVR8_TIFR2_OCF2A_SHIFT), (1 << AVR8_TIFR2_OCF2B_SHIFT) };
int32_t increment = m_timer_increment[2];
- for(int32_t reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
+ for (int32_t reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
{
- switch(wgm2)
+ switch (wgm2)
{
- case WGM02_FAST_PWM:
- if (reg==0)
+ case WGM02_FAST_PWM:
+ if (reg == 0)
+ {
+ if (count >= m_r[AVR8_REGIDX_OCR2A])
{
- if (count >= m_r[AVR8_REGIDX_OCR2A])
+ if (count >= 0xff)
{
- if (count >= 0xFF)
- {
- //Turn on
- m_io->write_byte(AVR8_IO_PORTD, m_io->read_byte(AVR8_IO_PORTD) | (1 << 7));
- m_r[AVR8_REGIDX_TCNT2] = 0;
- m_ocr2_not_reached_yet = true;
- }
- else
+ // Turn on
+ m_io->write_byte(AVR8_IO_PORTD, m_io->read_byte(AVR8_IO_PORTD) | (1 << 7));
+ m_r[AVR8_REGIDX_TCNT2] = 0;
+ m_ocr2_not_reached_yet = true;
+ }
+ else
+ {
+ if (m_ocr2_not_reached_yet)
{
- if (m_ocr2_not_reached_yet)
- {
- //Turn off
- m_io->write_byte(AVR8_IO_PORTD, m_io->read_byte(AVR8_IO_PORTD) & ~(1 << 7));
- m_ocr2_not_reached_yet = false;
- }
+ // Turn off
+ m_io->write_byte(AVR8_IO_PORTD, m_io->read_byte(AVR8_IO_PORTD) & ~(1 << 7));
+ m_ocr2_not_reached_yet = false;
}
}
}
- break;
+ }
+ break;
- case WGM02_FAST_PWM_CMP:
- if(count == ocr2[reg])
+ case WGM02_FAST_PWM_CMP:
+ if (count == ocr2[reg])
+ {
+ if (reg == 0)
{
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR2] |= AVR8_TIFR2_TOV2_MASK;
- count = 0;
- increment = 0;
- }
-
- m_r[AVR8_REGIDX_TIFR2] |= ocf2[reg];
+ m_r[AVR8_REGIDX_TIFR2] |= AVR8_TIFR2_TOV2_MASK;
+ count = 0;
+ increment = 0;
}
- else if (count == 0)
+
+ m_r[AVR8_REGIDX_TIFR2] |= ocf2[reg];
+ }
+ else if (count == 0)
+ {
+ if (reg == 0)
{
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR2] &= ~AVR8_TIFR2_TOV2_MASK;
- }
+ m_r[AVR8_REGIDX_TIFR2] &= ~AVR8_TIFR2_TOV2_MASK;
}
- break;
-
- default:
- // TODO
- break;
- }
- /*
- switch(compare_mode[reg])
- {
- case 0:
- //verboselog(m_pc, 0, "update_timer2_compare_mode: Normal port operation (OC2 disconnected)\n");
- break;
-
- case 1:
- case 2:
- // TODO
- break;
+ }
+ break;
- case 3:
- break;
+ default:
+ LOGMASKED(LOG_TIMER2 | LOG_UNKNOWN, "%s: timer2_tick: Unknown waveform generation mode: %02x\n", machine().describe_context(), wgm2);
+ break;
}
- */
}
m_r[AVR8_REGIDX_TCNT2] += increment;
@@ -1580,22 +1643,20 @@ void avr8_device::changed_tccr2a(uint8_t data)
AVR8_TCCR2A = data;
- if(changed & AVR8_TCCR2A_WGM2_10_MASK)
+ if (changed & AVR8_TCCR2A_WGM2_10_MASK)
{
- // TODO
update_timer_waveform_gen_mode(2, AVR8_WGM2);
}
}
void avr8_device::timer2_force_output_compare(int reg)
{
- // TODO
- verboselog(m_pc, 0, "force_output_compare: TODO; should be forcing OC2%c\n", avr8_reg_name[reg]);
+ LOGMASKED(LOG_TIMER2 | LOG_UNKNOWN, "%s: force_output_compare: TODO; should be forcing OC2%c\n", machine().describe_context(), avr8_reg_name[reg]);
}
void avr8_device::changed_tccr2b(uint8_t data)
{
- if (VERBOSE_LEVEL) printf("changed_tccr2b: data=0x%02X\n", data);
+ LOGMASKED(LOG_TIMER2, "%s: changed_tccr2b: data = 0x%02X\n", machine().describe_context(), data);
uint8_t oldtccr = AVR8_TCCR2B;
uint8_t newtccr = data;
@@ -1603,24 +1664,22 @@ void avr8_device::changed_tccr2b(uint8_t data)
AVR8_TCCR2B = data;
- if(changed & AVR8_TCCR2B_FOC2A_MASK)
+ if (changed & AVR8_TCCR2B_FOC2A_MASK)
{
- // TODO
timer2_force_output_compare(AVR8_REG_A);
}
- if(changed & AVR8_TCCR2B_FOC2B_MASK)
+ if (changed & AVR8_TCCR2B_FOC2B_MASK)
{
- // TODO
timer2_force_output_compare(AVR8_REG_B);
}
- if(changed & AVR8_TCCR2B_WGM2_2_MASK)
+ if (changed & AVR8_TCCR2B_WGM2_2_MASK)
{
update_timer_waveform_gen_mode(2, AVR8_WGM2);
}
- if(changed & AVR8_TCCR2B_CS_MASK)
+ if (changed & AVR8_TCCR2B_CS_MASK)
{
update_timer_clock_source(2, AVR8_TIMER2_CLOCK_SELECT);
}
@@ -1645,81 +1704,82 @@ void avr8_device::timer3_tick()
void avr8_device::timer4_tick()
{
/* TODO: Handle comparison, setting OC1x pins, detection of BOTTOM and TOP */
-// printf("AVR8_WGM4: %d\n", AVR8_WGM4);
-// printf("AVR8_TCCR4A_COM4B: %d\n", AVR8_TCCR4A_COM4B);
+ LOGMASKED(LOG_TIMER4_TICK, "%s: AVR8_WGM4: %d\n", machine().describe_context(), AVR8_WGM4);
+ LOGMASKED(LOG_TIMER4_TICK, "%s: AVR8_TCCR4A_COM4B: %d\n", machine().describe_context(), AVR8_TCCR4A_COM4B);
uint16_t count = (m_r[AVR8_REGIDX_TCNT4H] << 8) | m_r[AVR8_REGIDX_TCNT4L];
// Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer
- //uint8_t compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT,
- //(m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_COM1B_MASK) >> AVR8_TCCR1A_COM1B_SHIFT };
- uint16_t ocr4[2] = { static_cast<uint16_t>((m_r[AVR8_REGIDX_OCR4AH] << 8) | m_r[AVR8_REGIDX_OCR4AL]),
- static_cast<uint16_t>((m_r[AVR8_REGIDX_OCR4BH] << 8) | m_r[AVR8_REGIDX_OCR4BL]) };
-//TODO uint8_t ocf4[2] = { (1 << AVR8_TIFR4_OCF4A_SHIFT), (1 << AVR8_TIFR4_OCF4B_SHIFT) };
-//TODO uint8_t int4[2] = { AVR8_INTIDX_OCF4A, AVR8_INTIDX_OCF4B };
+ // uint8_t compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT,
+ // (m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_COM1B_MASK) >> AVR8_TCCR1A_COM1B_SHIFT };
+ // uint16_t ocr4[2] = { static_cast<uint16_t>((m_r[AVR8_REGIDX_OCR4AH] << 8) | m_r[AVR8_REGIDX_OCR4AL]),
+ // static_cast<uint16_t>((m_r[AVR8_REGIDX_OCR4BH] << 8) | m_r[AVR8_REGIDX_OCR4BL]) };
+ // TODO uint8_t ocf4[2] = { (1 << AVR8_TIFR4_OCF4A_SHIFT), (1 << AVR8_TIFR4_OCF4B_SHIFT) };
+ // TODO uint8_t int4[2] = { AVR8_INTIDX_OCF4A, AVR8_INTIDX_OCF4B };
int32_t increment = m_timer_increment[4];
- switch(AVR8_WGM4)
+ switch (AVR8_WGM4)
{
- case WGM4_FAST_PWM_8:
- case WGM4_FAST_PWM_9:
- case WGM4_FAST_PWM_10:
- switch(AVR8_TCCR4A_COM4B){
+ case WGM4_FAST_PWM_8:
+ case WGM4_FAST_PWM_9:
+ case WGM4_FAST_PWM_10:
+ switch (AVR8_TCCR4A_COM4B)
+ {
case 0: /* Normal Operation */
break;
case 1: /* TODO */
break;
case 2: /* Non-inverting mode */
- if (count == m_timer_top[4]){
- //Clear OC0B
- printf("[2] Clear OC0B\n");
- m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) & ~(1 << 5));
- } else if (count == 0){
- //Set OC0B
- printf("[2] Set OC0B\n");
- m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) | (1 << 5));
+ if (count == m_timer_top[4])
+ {
+ // Clear OC0B
+ LOGMASKED(LOG_TIMER4, "%s: timer4: non-inverting mode, Clear OC0B\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) & ~(1 << 5));
+ }
+ else if (count == 0)
+ {
+ // Set OC0B
+ LOGMASKED(LOG_TIMER4, "%s: timer4: non-inverting mode, Set OC0B\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) | (1 << 5));
}
break;
case 3: /* Inverting mode */
- if (count == m_timer_top[4]){
- //Set OC0B
- printf("[3] Set OC0B\n");
- m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) | (1 << 5));
- } else if (count == 0){
- //Clear OC0B
- printf("[3] Clear OC0B\n");
- m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) & ~(1 << 5));
+ if (count == m_timer_top[4])
+ {
+ // Set OC0B
+ LOGMASKED(LOG_TIMER4, "%s: timer4: inverting mode, Clear OC0B\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) | (1 << 5));
+ }
+ else if (count == 0)
+ {
+ // Clear OC0B
+ LOGMASKED(LOG_TIMER4, "%s: timer4: inverting mode, Set OC0B\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTG, m_io->read_byte(AVR8_IO_PORTG) & ~(1 << 5));
}
break;
}
break;
- case WGM4_CTC_OCR:
- //printf("[T4] tick WGM4_CTC_OCR: %d\n", count);
- if (count == 0xffff)
- {
- m_r[AVR8_REGIDX_TIFR4] |= AVR8_TIFR4_TOV4_MASK;
- update_interrupt(AVR8_INTIDX_TOV4);
- count = 0;
- increment = 0;
- }
+ case WGM4_CTC_OCR:
+ LOGMASKED(LOG_TIMER4, "%s: timer4: tick WGM4_CTC_OCR: %d\n", machine().describe_context(), count);
+ if (count == 0xffff)
+ {
+ m_r[AVR8_REGIDX_TIFR4] |= AVR8_TIFR4_TOV4_MASK;
+ update_interrupt(AVR8_INTIDX_TOV4);
+ count = 0;
+ increment = 0;
+ }
- if (count == ocr4[0]) /*TODO: test for all 3 register*/
- {}
- else if (count == 0)
- {}
- break;
+ /* TODO: test for match against all 3 registers */
+ break;
- case WGM1_FAST_PWM_OCR:
- if(count == ocr4[0]) /*TODO: test for all 3 register*/
- {}
- else if(count == 0)
- {}
- break;
+ case WGM1_FAST_PWM_OCR:
+ /* TODO: test for match against all 3 registers */
+ break;
- default:
- verboselog(m_pc, 0, "update_timer4_compare_mode: Unknown waveform generation mode: %02x\n", AVR8_WGM4);
- break;
+ default:
+ LOGMASKED(LOG_TIMER4 | LOG_UNKNOWN, "%s: timer4_tick: Unknown waveform generation mode: %02x\n", machine().describe_context(), AVR8_WGM4);
+ break;
}
count += increment;
@@ -1729,41 +1789,45 @@ void avr8_device::timer4_tick()
void avr8_device::update_timer_clock_source(uint8_t t, uint8_t clock_select)
{
- int prescale_values[8] = {0, 1, 8, 64, 256, 1024, -1, -1};
- m_timer_prescale[t] = prescale_values[clock_select];
+ static const int s_prescale_values[8] =
+ {
+ 0, 1, 8, 64, 256, 1024, -1, -1
+ };
+ m_timer_prescale[t] = s_prescale_values[clock_select];
- if (VERBOSE_LEVEL) printf("update_timer_clock_source: t=%d cs=%d\n", t, clock_select);
+ LOGMASKED((LOG_TIMER0 + t), "%s: update_timer_clock_source: t = %d, cs = %d\n", t, machine().describe_context(), clock_select);
- if (m_timer_prescale[t] == 0xFFFF){
- printf("[Timer #%d]: update_timer_clock_source: External trigger mode not implemented yet\n", t);
- m_timer_prescale[t] = 0;
+ if (m_timer_prescale[t] == 0xffff)
+ {
+ LOGMASKED((LOG_TIMER0 + t), "%s: timer%d: update_timer_clock_source: External trigger mode not implemented yet\n", machine().describe_context(), t);
+ m_timer_prescale[t] = 0;
}
if (m_timer_prescale_count[t] > m_timer_prescale[t])
+ {
m_timer_prescale_count[t] = m_timer_prescale[t] - 1;
+ }
}
void avr8_device::changed_tccr3a(uint8_t data)
{
- //TODO: Implement-me
-// AVR8_TCCR3A = data;
+ // TODO
+ // AVR8_TCCR3A = data;
}
void avr8_device::changed_tccr3b(uint8_t data)
{
- printf("IMPLEMENT-ME: changed_tccr4b: data=0x%02X\n", data);
+ LOGMASKED(LOG_TIMER3 | LOG_UNKNOWN, "%s: (not yet implemented) changed_tccr3b: data = %02X\n", machine().describe_context(), data);
}
void avr8_device::changed_tccr3c(uint8_t data)
{
-// uint8_t oldtccr = AVR8_TCCR3C;
-// uint8_t newtccr = data;
-// uint8_t changed = newtccr ^ oldtccr;
- printf("IMPLEMENT-ME: changed_tccr3c: data=0x%02X\n", data);
+ // uint8_t oldtccr = AVR8_TCCR3C;
+ // uint8_t newtccr = data;
+ // uint8_t changed = newtccr ^ oldtccr;
+ LOGMASKED(LOG_TIMER3 | LOG_UNKNOWN, "%s: (not yet implemented) changed_tccr3c: data = %02X\n", machine().describe_context(), data);
-// AVR8_TCCR3C = data;
-
- //TODO: Implement-me
+ // AVR8_TCCR3C = data;
}
void avr8_device::changed_tccr4a(uint8_t data)
@@ -1774,7 +1838,7 @@ void avr8_device::changed_tccr4a(uint8_t data)
AVR8_TCCR4A = data;
- if(changed & AVR8_TCCR4A_WGM4_10_MASK)
+ if (changed & AVR8_TCCR4A_WGM4_10_MASK)
{
update_timer_waveform_gen_mode(4, AVR8_WGM4);
}
@@ -1782,7 +1846,7 @@ void avr8_device::changed_tccr4a(uint8_t data)
void avr8_device::changed_tccr4b(uint8_t data)
{
- printf("changed_tccr4b: data=0x%02X\n", data);
+ LOGMASKED(LOG_TIMER4, "%s: changed_tccr4b: data = %02X\n", machine().describe_context(), data);
uint8_t oldtccr = AVR8_TCCR4B;
uint8_t newtccr = data;
@@ -1790,24 +1854,24 @@ void avr8_device::changed_tccr4b(uint8_t data)
AVR8_TCCR4B = data;
- if(changed & AVR8_TCCR4B_FOC4A_MASK)
+ if (changed & AVR8_TCCR4B_FOC4A_MASK)
{
// TODO
-// timer4_force_output_compare(AVR8_REG_A);
+ // timer4_force_output_compare(AVR8_REG_A);
}
- if(changed & AVR8_TCCR4B_FOC4B_MASK)
+ if (changed & AVR8_TCCR4B_FOC4B_MASK)
{
// TODO
-// timer4_force_output_compare(AVR8_REG_B);
+ // timer4_force_output_compare(AVR8_REG_B);
}
- if(changed & AVR8_TCCR4B_WGM4_32_MASK)
+ if (changed & AVR8_TCCR4B_WGM4_32_MASK)
{
update_timer_waveform_gen_mode(4, AVR8_WGM4);
}
- if(changed & AVR8_TCCR4B_CS_MASK)
+ if (changed & AVR8_TCCR4B_CS_MASK)
{
update_timer_clock_source(4, AVR8_TIMER4_CLOCK_SELECT);
}
@@ -1815,13 +1879,11 @@ void avr8_device::changed_tccr4b(uint8_t data)
void avr8_device::changed_tccr4c(uint8_t data)
{
-// uint8_t oldtccr = AVR8_TCCR4C;
-// uint8_t newtccr = data;
-// uint8_t changed = newtccr ^ oldtccr;
+ // uint8_t oldtccr = AVR8_TCCR4C;
+ // uint8_t newtccr = data;
+ // uint8_t changed = newtccr ^ oldtccr;
AVR8_TCCR4C = data;
-
- //TODO: Implement-me
}
/************************************************************************************************/
@@ -1829,21 +1891,19 @@ void avr8_device::changed_tccr4c(uint8_t data)
// Timer 5 Handling
void avr8_device::timer5_tick()
{
-#if LOG_TIMER_5
- printf("AVR8_WGM5: %d\n", AVR8_WGM5);
- printf("AVR8_TCCR5A_COM5B: %d\n", AVR8_TCCR5A_COM5B);
-#endif
+ LOGMASKED(LOG_TIMER5_TICK, "%s: AVR8_WGM5: %d\n", machine().describe_context(), AVR8_WGM5);
+ LOGMASKED(LOG_TIMER5_TICK, "%s: AVR8_TCCR5A_COM5B: %d\n", machine().describe_context(), AVR8_TCCR5A_COM5B);
uint16_t count = (AVR8_TCNT5H << 8) + AVR8_TCNT5L;
int32_t increment = m_timer_increment[5];
- switch(AVR8_WGM5)
+ switch (AVR8_WGM5)
{
- case WGM5_NORMAL:
+ case WGM5_NORMAL:
case WGM5_PWM_8_PC:
case WGM5_PWM_9_PC:
case WGM5_PWM_10_PC:
-// case WGM5_CTC_OCR:
+// case WGM5_CTC_OCR:
case WGM5_FAST_PWM_8:
case WGM5_FAST_PWM_9:
case WGM5_FAST_PWM_10:
@@ -1854,53 +1914,50 @@ void avr8_device::timer5_tick()
case WGM5_CTC_ICR:
case WGM5_FAST_PWM_ICR:
case WGM5_FAST_PWM_OCR:
-#if LOG_TIMER_5
- printf("Unimplemented timer#5 waveform generation mode: AVR8_WGM5 = 0x%02X\n", AVR8_WGM5);
-#endif
- break;
+ LOGMASKED(LOG_TIMER5 | LOG_UNKNOWN, "%s: Unimplemented timer5 waveform generation mode: AVR8_WGM5 = 0x%02X\n", machine().describe_context(), AVR8_WGM5);
+ break;
- case WGM5_CTC_OCR:
- //TODO: verify this! Can be very wrong!!!
- switch(AVR8_TCCR5A_COM5B){
+ case WGM5_CTC_OCR:
+ // TODO: Please verify, might be wrong
+ switch (AVR8_TCCR5A_COM5B)
+ {
case 0: /* Normal Operation */
- if (count == m_timer_top[5]){
- m_timer_top[5] = 0;
+ if (count == m_timer_top[5])
+ {
+ m_timer_top[5] = 0;
}
break;
case 1: /* Toggle OC5B on compare match */
- if (count == m_timer_top[5]){
- m_timer_top[5] = 0;
-#if LOG_TIMER_5
- printf("[5] Toggle OC5B\n");
-#endif
- m_io->write_byte(AVR8_IO_PORTL, m_io->read_byte(AVR8_IO_PORTL) ^ (1 << 4));
+ if (count == m_timer_top[5])
+ {
+ m_timer_top[5] = 0;
+ LOGMASKED(LOG_TIMER5, "%s: timer5: Toggle OC5B on compare match\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTL, m_io->read_byte(AVR8_IO_PORTL) ^ (1 << 4));
}
break;
case 2: /* Clear OC5B on compare match */
- if (count == m_timer_top[5]){
- m_timer_top[5] = 0;
- //Clear OC5B
-#if LOG_TIMER_5
- printf("[5] Clear OC5B\n");
-#endif
- m_io->write_byte(AVR8_IO_PORTL, m_io->read_byte(AVR8_IO_PORTL) & ~(1 << 4));
+ if (count == m_timer_top[5])
+ {
+ m_timer_top[5] = 0;
+ // Clear OC5B
+ LOGMASKED(LOG_TIMER5, "%s: timer5: Clear OC5B on compare match\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTL, m_io->read_byte(AVR8_IO_PORTL) & ~(1 << 4));
}
break;
case 3: /* Set OC5B on compare match */
- if (count == m_timer_top[5]){
- m_timer_top[5] = 0;
-#if LOG_TIMER_5
- printf("[5] Set OC5B\n");
-#endif
- m_io->write_byte(AVR8_IO_PORTL, m_io->read_byte(AVR8_IO_PORTL) | (1 << 4));
+ if (count == m_timer_top[5])
+ {
+ m_timer_top[5] = 0;
+ LOGMASKED(LOG_TIMER5, "%s: timer5: Set OC5B on compare match\n", machine().describe_context());
+ m_io->write_byte(AVR8_IO_PORTL, m_io->read_byte(AVR8_IO_PORTL) | (1 << 4));
}
break;
}
break;
- default:
- printf("Timer #5: Unknown waveform generation mode: %02x\n", AVR8_WGM5);
- break;
+ default:
+ LOGMASKED(LOG_TIMER5 | LOG_UNKNOWN, "%s: timer5: Unknown waveform generation mode: %02x\n", machine().describe_context(), AVR8_WGM5);
+ break;
}
count += increment;
@@ -1916,7 +1973,7 @@ void avr8_device::changed_tccr5a(uint8_t data)
AVR8_TCCR5A = data;
- if(changed & AVR8_TCCR5A_WGM5_10_MASK)
+ if (changed & AVR8_TCCR5A_WGM5_10_MASK)
{
update_timer_waveform_gen_mode(5, AVR8_WGM5);
}
@@ -1924,7 +1981,7 @@ void avr8_device::changed_tccr5a(uint8_t data)
void avr8_device::changed_tccr5b(uint8_t data)
{
- printf("changed_tccr5b: data=0x%02X\n", data);
+ LOGMASKED(LOG_TIMER5, "%s: changed_tccr5b: data = %02X\n", machine().describe_context(), data);
uint8_t oldtccr = AVR8_TCCR5B;
uint8_t newtccr = data;
@@ -1932,30 +1989,30 @@ void avr8_device::changed_tccr5b(uint8_t data)
AVR8_TCCR5B = data;
- if(changed & AVR8_TCCR5C_FOC5A_MASK)
+ if (changed & AVR8_TCCR5C_FOC5A_MASK)
{
// TODO
-// timer5_force_output_compare(AVR8_REG_A);
+ // timer5_force_output_compare(AVR8_REG_A);
}
- if(changed & AVR8_TCCR5C_FOC5B_MASK)
+ if (changed & AVR8_TCCR5C_FOC5B_MASK)
{
// TODO
-// timer5_force_output_compare(AVR8_REG_B);
+ // timer5_force_output_compare(AVR8_REG_B);
}
- if(changed & AVR8_TCCR5C_FOC5C_MASK)
+ if (changed & AVR8_TCCR5C_FOC5C_MASK)
{
// TODO
-// timer5_force_output_compare(AVR8_REG_C);
+ // timer5_force_output_compare(AVR8_REG_C);
}
- if(changed & AVR8_TCCR5B_WGM5_32_MASK)
+ if (changed & AVR8_TCCR5B_WGM5_32_MASK)
{
update_timer_waveform_gen_mode(5, AVR8_WGM5);
}
- if(changed & AVR8_TCCR5B_CS_MASK)
+ if (changed & AVR8_TCCR5B_CS_MASK)
{
update_timer_clock_source(5, AVR8_TIMER5_CLOCK_SELECT);
}
@@ -1993,11 +2050,13 @@ void avr8_device::spi_update_clock_phase()
// TODO
}
-const uint8_t avr8_device::spi_clock_divisor[8] = { 4, 16, 64, 128, 2, 8, 32, 64 };
-
void avr8_device::spi_update_clock_rate()
{
- m_spi_prescale = spi_clock_divisor[AVR8_SPI_RATE];
+ static const uint8_t s_spi_clock_divisor[8] =
+ {
+ 4, 16, 64, 128, 2, 8, 32, 64
+ };
+ m_spi_prescale = s_spi_clock_divisor[AVR8_SPI_RATE];
m_spi_prescale_count &= m_spi_prescale - 1;
}
@@ -2011,37 +2070,37 @@ void avr8_device::change_spcr(uint8_t data)
AVR8_SPCR = data;
- if(changed & AVR8_SPCR_SPIE_MASK)
+ if (changed & AVR8_SPCR_SPIE_MASK)
{
// Check for SPI interrupt condition
update_interrupt(AVR8_INTIDX_SPI);
}
- if(low_to_high & AVR8_SPCR_SPE_MASK)
+ if (low_to_high & AVR8_SPCR_SPE_MASK)
{
enable_spi();
}
- else if(high_to_low & AVR8_SPCR_SPE_MASK)
+ else if (high_to_low & AVR8_SPCR_SPE_MASK)
{
disable_spi();
}
- if(changed & AVR8_SPCR_MSTR_MASK)
+ if (changed & AVR8_SPCR_MSTR_MASK)
{
spi_update_masterslave_select();
}
- if(changed & AVR8_SPCR_CPOL_MASK)
+ if (changed & AVR8_SPCR_CPOL_MASK)
{
spi_update_clock_polarity();
}
- if(changed & AVR8_SPCR_CPHA_MASK)
+ if (changed & AVR8_SPCR_CPHA_MASK)
{
spi_update_clock_phase();
}
- if(changed & AVR8_SPCR_SPR_MASK)
+ if (changed & AVR8_SPCR_SPR_MASK)
{
spi_update_clock_rate();
}
@@ -2056,7 +2115,7 @@ void avr8_device::change_spsr(uint8_t data)
AVR8_SPSR &= ~1;
AVR8_SPSR |= data & 1;
- if(changed & AVR8_SPSR_SPR2X_MASK)
+ if (changed & AVR8_SPSR_SPR2X_MASK)
{
spi_update_clock_rate();
}
@@ -2064,804 +2123,763 @@ void avr8_device::change_spsr(uint8_t data)
/*****************************************************************************/
-WRITE8_MEMBER( avr8_device::regs_w )
-{
- //printf("<<< WRITE offset [%04x]=%02x >>>\n", offset, data);
-
- switch( offset )
- {
- case AVR8_REGIDX_R0:
- case AVR8_REGIDX_R1:
- case AVR8_REGIDX_R2:
- case AVR8_REGIDX_R3:
- case AVR8_REGIDX_R4:
- case AVR8_REGIDX_R5:
- case AVR8_REGIDX_R6:
- case AVR8_REGIDX_R7:
- case AVR8_REGIDX_R8:
- case AVR8_REGIDX_R9:
- case AVR8_REGIDX_R10:
- case AVR8_REGIDX_R11:
- case AVR8_REGIDX_R12:
- case AVR8_REGIDX_R13:
- case AVR8_REGIDX_R14:
- case AVR8_REGIDX_R15:
- case AVR8_REGIDX_R16:
- case AVR8_REGIDX_R17:
- case AVR8_REGIDX_R18:
- case AVR8_REGIDX_R19:
- case AVR8_REGIDX_R20:
- case AVR8_REGIDX_R21:
- case AVR8_REGIDX_R22:
- case AVR8_REGIDX_R23:
- case AVR8_REGIDX_R24:
- case AVR8_REGIDX_R25:
- case AVR8_REGIDX_R26:
- case AVR8_REGIDX_R27:
- case AVR8_REGIDX_R28:
- case AVR8_REGIDX_R29:
- case AVR8_REGIDX_R30:
- case AVR8_REGIDX_R31:
- m_r[offset] = data;
- break;
+WRITE8_MEMBER(avr8_device::regs_w)
+{
+ switch (offset)
+ {
+ case AVR8_REGIDX_R0:
+ case AVR8_REGIDX_R1:
+ case AVR8_REGIDX_R2:
+ case AVR8_REGIDX_R3:
+ case AVR8_REGIDX_R4:
+ case AVR8_REGIDX_R5:
+ case AVR8_REGIDX_R6:
+ case AVR8_REGIDX_R7:
+ case AVR8_REGIDX_R8:
+ case AVR8_REGIDX_R9:
+ case AVR8_REGIDX_R10:
+ case AVR8_REGIDX_R11:
+ case AVR8_REGIDX_R12:
+ case AVR8_REGIDX_R13:
+ case AVR8_REGIDX_R14:
+ case AVR8_REGIDX_R15:
+ case AVR8_REGIDX_R16:
+ case AVR8_REGIDX_R17:
+ case AVR8_REGIDX_R18:
+ case AVR8_REGIDX_R19:
+ case AVR8_REGIDX_R20:
+ case AVR8_REGIDX_R21:
+ case AVR8_REGIDX_R22:
+ case AVR8_REGIDX_R23:
+ case AVR8_REGIDX_R24:
+ case AVR8_REGIDX_R25:
+ case AVR8_REGIDX_R26:
+ case AVR8_REGIDX_R27:
+ case AVR8_REGIDX_R28:
+ case AVR8_REGIDX_R29:
+ case AVR8_REGIDX_R30:
+ case AVR8_REGIDX_R31:
+ m_r[offset] = data;
+ break;
- case AVR8_REGIDX_PORTA:
+ case AVR8_REGIDX_PORTA:
m_io->write_byte(AVR8_IO_PORTA, data);
m_r[AVR8_REGIDX_PORTA] = data;
break;
- case AVR8_REGIDX_PORTB:
+ case AVR8_REGIDX_PORTB:
m_io->write_byte(AVR8_IO_PORTB, data);
m_r[AVR8_REGIDX_PORTB] = data;
break;
- case AVR8_REGIDX_PORTC:
+ case AVR8_REGIDX_PORTC:
m_io->write_byte(AVR8_IO_PORTC, data);
m_r[AVR8_REGIDX_PORTC] = data;
break;
- case AVR8_REGIDX_PORTD:
+ case AVR8_REGIDX_PORTD:
m_io->write_byte(AVR8_IO_PORTD, data);
m_r[AVR8_REGIDX_PORTD] = data;
break;
- case AVR8_REGIDX_PORTE:
+ case AVR8_REGIDX_PORTE:
m_io->write_byte(AVR8_IO_PORTE, data);
m_r[AVR8_REGIDX_PORTE] = data;
break;
- case AVR8_REGIDX_PORTF:
+ case AVR8_REGIDX_PORTF:
m_io->write_byte(AVR8_IO_PORTF, data);
m_r[AVR8_REGIDX_PORTF] = data;
break;
- case AVR8_REGIDX_PORTG:
+ case AVR8_REGIDX_PORTG:
m_io->write_byte(AVR8_IO_PORTG, data);
m_r[AVR8_REGIDX_PORTG] = data;
break;
- case AVR8_REGIDX_PORTH:
+ case AVR8_REGIDX_PORTH:
m_io->write_byte(AVR8_IO_PORTH, data);
m_r[AVR8_REGIDX_PORTH] = data;
break;
- case AVR8_REGIDX_PORTJ:
+ case AVR8_REGIDX_PORTJ:
m_io->write_byte(AVR8_IO_PORTJ, data);
m_r[AVR8_REGIDX_PORTJ] = data;
break;
- case AVR8_REGIDX_PORTK:
+ case AVR8_REGIDX_PORTK:
m_io->write_byte(AVR8_IO_PORTK, data);
m_r[AVR8_REGIDX_PORTK] = data;
break;
- case AVR8_REGIDX_PORTL:
+ case AVR8_REGIDX_PORTL:
m_io->write_byte(AVR8_IO_PORTL, data);
m_r[AVR8_REGIDX_PORTL] = data;
break;
- case AVR8_REGIDX_DDRA:
- case AVR8_REGIDX_DDRB:
- case AVR8_REGIDX_DDRC:
- case AVR8_REGIDX_DDRD:
- case AVR8_REGIDX_SREG:
+ case AVR8_REGIDX_DDRA:
+ case AVR8_REGIDX_DDRB:
+ case AVR8_REGIDX_DDRC:
+ case AVR8_REGIDX_DDRD:
+ case AVR8_REGIDX_SREG:
case AVR8_REGIDX_RAMPZ:
- case AVR8_REGIDX_SPH:
- case AVR8_REGIDX_SPL:
- m_r[offset] = data;
- break;
-
- case AVR8_REGIDX_TCCR0B:
- verboselog(m_pc, 0, "AVR8: TCCR0B = %02x\n", data );
- changed_tccr0b(data);
- break;
+ case AVR8_REGIDX_SPH:
+ case AVR8_REGIDX_SPL:
+ m_r[offset] = data;
+ break;
- case AVR8_REGIDX_TCCR0A:
- verboselog(m_pc, 0, "AVR8: TCCR0A = %02x\n", data );
- changed_tccr0a(data);
- break;
+ case AVR8_REGIDX_TCCR0B:
+ LOGMASKED(LOG_TIMER0, "%s: TCCR0B = %02x\n", machine().describe_context(), data);
+ changed_tccr0b(data);
+ break;
- case AVR8_REGIDX_OCR0A:
- verboselog(m_pc, 0, "AVR8: OCR0A = %02x\n", data);
- update_ocr0(AVR8_OCR0A, AVR8_REG_A);
- break;
+ case AVR8_REGIDX_TCCR0A:
+ LOGMASKED(LOG_TIMER0, "%s: TCCR0A = %02x\n", machine().describe_context(), data);
+ changed_tccr0a(data);
+ break;
- case AVR8_REGIDX_OCR0B:
- verboselog(m_pc, 0, "AVR8: OCR0B = %02x\n", data );
- update_ocr0(AVR8_OCR0B, AVR8_REG_B);
- break;
+ case AVR8_REGIDX_OCR0A:
+ LOGMASKED(LOG_TIMER0, "%s: OCR0A = %02x\n", machine().describe_context(), data);
+ update_ocr0(AVR8_OCR0A, AVR8_REG_A);
+ break;
- case AVR8_REGIDX_TIFR0:
- verboselog(m_pc, 0, "AVR8: TIFR0 = %02x\n", data );
- m_r[AVR8_REGIDX_TIFR0] &= ~(data & AVR8_TIFR0_MASK);
- update_interrupt(AVR8_INTIDX_OCF0A);
- update_interrupt(AVR8_INTIDX_OCF0B);
- update_interrupt(AVR8_INTIDX_TOV0);
- break;
+ case AVR8_REGIDX_OCR0B:
+ LOGMASKED(LOG_TIMER0, "%s: OCR0B = %02x\n", machine().describe_context(), data);
+ update_ocr0(AVR8_OCR0B, AVR8_REG_B);
+ break;
- case AVR8_REGIDX_TCNT0:
- AVR8_TCNT0 = data;
- break;
+ case AVR8_REGIDX_TIFR0:
+ LOGMASKED(LOG_TIMER0, "%s: TIFR0 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIFR0] &= ~(data & AVR8_TIFR0_MASK);
+ update_interrupt(AVR8_INTIDX_OCF0A);
+ update_interrupt(AVR8_INTIDX_OCF0B);
+ update_interrupt(AVR8_INTIDX_TOV0);
+ break;
- case AVR8_REGIDX_TIFR1:
- verboselog(m_pc, 0, "AVR8: TIFR1 = %02x\n", data );
- m_r[AVR8_REGIDX_TIFR1] &= ~(data & AVR8_TIFR1_MASK);
- update_interrupt(AVR8_INTIDX_ICF1);
- update_interrupt(AVR8_INTIDX_OCF1A);
- update_interrupt(AVR8_INTIDX_OCF1B);
- update_interrupt(AVR8_INTIDX_TOV1);
- break;
+ case AVR8_REGIDX_TCNT0:
+ AVR8_TCNT0 = data;
+ break;
- case AVR8_REGIDX_TIFR2:
- verboselog(m_pc, 0, "AVR8: TIFR2 = %02x\n", data );
- m_r[AVR8_REGIDX_TIFR2] &= ~(data & AVR8_TIFR2_MASK);
- update_interrupt(AVR8_INTIDX_OCF2A);
- update_interrupt(AVR8_INTIDX_OCF2B);
- update_interrupt(AVR8_INTIDX_TOV2);
- break;
+ case AVR8_REGIDX_TIFR1:
+ LOGMASKED(LOG_TIMER1, "%s: TIFR1 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIFR1] &= ~(data & AVR8_TIFR1_MASK);
+ update_interrupt(AVR8_INTIDX_ICF1);
+ update_interrupt(AVR8_INTIDX_OCF1A);
+ update_interrupt(AVR8_INTIDX_OCF1B);
+ update_interrupt(AVR8_INTIDX_TOV1);
+ break;
- case AVR8_REGIDX_GTCCR:
- if (data & AVR8_GTCCR_PSRASY_MASK)
- {
- data &= ~AVR8_GTCCR_PSRASY_MASK;
- m_timer_prescale_count[2] = 0;
- }
- break;
+ case AVR8_REGIDX_TIFR2:
+ LOGMASKED(LOG_TIMER2, "%s: TIFR2 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIFR2] &= ~(data & AVR8_TIFR2_MASK);
+ update_interrupt(AVR8_INTIDX_OCF2A);
+ update_interrupt(AVR8_INTIDX_OCF2B);
+ update_interrupt(AVR8_INTIDX_TOV2);
+ break;
-// EEPROM registers:
- case AVR8_REGIDX_EEARL:
- case AVR8_REGIDX_EEARH:
- case AVR8_REGIDX_EEDR:
- m_r[offset] = data;
+ case AVR8_REGIDX_GTCCR:
+ if (data & AVR8_GTCCR_PSRASY_MASK)
+ {
+ data &= ~AVR8_GTCCR_PSRASY_MASK;
+ m_timer_prescale_count[2] = 0;
+ }
break;
- case AVR8_REGIDX_EECR:
- m_r[offset] = data;
+ // EEPROM registers
+ case AVR8_REGIDX_EEARL:
+ case AVR8_REGIDX_EEARH:
+ case AVR8_REGIDX_EEDR:
+ m_r[offset] = data;
+ break;
- if (data & AVR8_EECR_EERE_MASK)
- {
- uint16_t addr = (m_r[AVR8_REGIDX_EEARH] & AVR8_EEARH_MASK) << 8;
- addr |= m_r[AVR8_REGIDX_EEARL];
- m_r[AVR8_REGIDX_EEDR] = m_eeprom[addr];
- if (VERBOSE_LEVEL) printf("EEPROM read @ 0x%04x data = 0x%02x\n", addr, m_eeprom[addr]);
- }
- if ((data & AVR8_EECR_EEPE_MASK) && (data & AVR8_EECR_EEMPE_MASK))
- {
- uint16_t addr = (m_r[AVR8_REGIDX_EEARH] & AVR8_EEARH_MASK) << 8;
- addr |= m_r[AVR8_REGIDX_EEARL];
- m_eeprom[addr] = m_r[AVR8_REGIDX_EEDR];
- if (VERBOSE_LEVEL) printf("EEPROM write @ 0x%04x data = 0x%02x ('%c')\n", addr, m_eeprom[addr], m_eeprom[addr]);
+ case AVR8_REGIDX_EECR:
+ m_r[offset] = data;
- m_r[offset] = data & ~AVR8_EECR_EEPE_MASK; //indicates that we've finished writing a value to the EEPROM.
- //TODO: shouldn't this happen only after a certain dalay?
- }
- break;
+ if (data & AVR8_EECR_EERE_MASK)
+ {
+ uint16_t addr = (m_r[AVR8_REGIDX_EEARH] & AVR8_EEARH_MASK) << 8;
+ addr |= m_r[AVR8_REGIDX_EEARL];
+ m_r[AVR8_REGIDX_EEDR] = m_eeprom[addr];
+ LOGMASKED(LOG_EEPROM, "%s: EEPROM read @ %04x data = %02x\n", machine().describe_context(), addr, m_eeprom[addr]);
+ }
+ if ((data & AVR8_EECR_EEPE_MASK) && (data & AVR8_EECR_EEMPE_MASK))
+ {
+ uint16_t addr = (m_r[AVR8_REGIDX_EEARH] & AVR8_EEARH_MASK) << 8;
+ addr |= m_r[AVR8_REGIDX_EEARL];
+ m_eeprom[addr] = m_r[AVR8_REGIDX_EEDR];
+ LOGMASKED(LOG_EEPROM, "%s: EEPROM write @ %04x data = %02x ('%c')\n", machine().describe_context(), addr, m_eeprom[addr], m_eeprom[addr]);
+
+ // Indicate that we've finished writing a value to the EEPROM.
+ // TODO: this should only happen after a certain dalay.
+ m_r[offset] = data & ~AVR8_EECR_EEPE_MASK;
+ }
+ break;
- case AVR8_REGIDX_GPIOR0:
- verboselog(m_pc, 1, "AVR8: GPIOR0 Write: %02x\n", data);
- m_r[AVR8_REGIDX_GPIOR0] = data;
- break;
+ case AVR8_REGIDX_GPIOR0:
+ LOGMASKED(LOG_GPIO, "%s: GPIOR0 Write: %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_GPIOR0] = data;
+ break;
- case AVR8_REGIDX_GPIOR1:
- case AVR8_REGIDX_GPIOR2:
- m_r[offset] = data;
- break;
+ case AVR8_REGIDX_GPIOR1:
+ case AVR8_REGIDX_GPIOR2:
+ m_r[offset] = data;
+ break;
- case AVR8_REGIDX_SPSR:
- change_spsr(data);
- break;
+ case AVR8_REGIDX_SPSR:
+ change_spsr(data);
+ break;
- case AVR8_REGIDX_SPCR:
- change_spcr(data);
- break;
+ case AVR8_REGIDX_SPCR:
+ change_spcr(data);
+ break;
- case AVR8_REGIDX_SPDR:
- {
- m_r[AVR8_REGIDX_SPDR] = data;
- m_spi_active = true;
- m_spi_prescale_countdown = 7;
- m_spi_prescale_count = 0;
- break;
- }
+ case AVR8_REGIDX_SPDR:
+ {
+ m_r[AVR8_REGIDX_SPDR] = data;
+ m_spi_active = true;
+ m_spi_prescale_countdown = 7;
+ m_spi_prescale_count = 0;
+ break;
+ }
case AVR8_REGIDX_WDTCSR:
- verboselog(m_pc, 0, "AVR8: WDTCSR = %02x\n", data );
- //TODO: changed_wdtcsr(data);
+ LOGMASKED(LOG_WDOG, "%s: (not yet implemented) WDTCSR = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_CLKPR:
- verboselog(m_pc, 0, "AVR8: CLKPR = %02x\n", data );
- //TODO: changed_clkpr(data);
+ LOGMASKED(LOG_CLOCK, "%s: (not yet implemented) CLKPR = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_PRR0:
- verboselog(m_pc, 0, "AVR8: PRR0 = %02x\n", data );
- //TODO: changed_prr0(data);
+ LOGMASKED(LOG_POWER, "%s: (not yet implemented) PRR0 = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_PRR1:
- verboselog(m_pc, 0, "AVR8: PRR1 = %02x\n", data );
- //TODO: changed_prr1(data);
+ LOGMASKED(LOG_POWER, "%s: (not yet implemented) PRR1 = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_OSCCAL:
- verboselog(m_pc, 0, "AVR8: OSCCAL = %02x\n", data );
- //TODO: changed_osccal(data);
+ LOGMASKED(LOG_OSC, "%s: (not yet implemented) OSCCAL = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_PCICR:
- verboselog(m_pc, 0, "AVR8: PCICR = %02x\n", data );
- //TODO: changed_pcicr(data);
+ LOGMASKED(LOG_PINCHG, "%s: (not yet implemented) PCICR = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_EICRA:
- verboselog(m_pc, 0, "AVR8: EICRA = %02x\n", data );
- //TODO: changed_eicra(data);
+ LOGMASKED(LOG_GPIO, "%s: (not yet implemented) EICRA = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_EICRB:
- verboselog(m_pc, 0, "AVR8: EICRB = %02x\n", data );
- //TODO: changed_eicrb(data);
+ LOGMASKED(LOG_GPIO, "%s: (not yet implemented) EICRB = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_PCMSK0:
- verboselog(m_pc, 0, "AVR8: PCMSK0 = %02x\n", data );
- //TODO: changed_pcmsk0(data);
+ LOGMASKED(LOG_PINCHG, "%s: (not yet implemented) PCMSK0 = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_PCMSK1:
- verboselog(m_pc, 0, "AVR8: PCMSK1 = %02x\n", data );
- //TODO: changed_pcmsk1(data);
+ LOGMASKED(LOG_PINCHG, "%s: (not yet implemented) PCMSK1 = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_PCMSK2:
- verboselog(m_pc, 0, "AVR8: PCMSK2 = %02x\n", data );
- //TODO: changed_pcmsk2(data);
+ LOGMASKED(LOG_PINCHG, "%s: (not yet implemented) PCMSK2 = %02x\n", machine().describe_context(), data);
break;
- case AVR8_REGIDX_TIMSK0:
- verboselog(m_pc, 0, "AVR8: TIMSK0 = %02x\n", data );
- m_r[AVR8_REGIDX_TIMSK0] = data;
- update_interrupt(AVR8_INTIDX_OCF0A);
- update_interrupt(AVR8_INTIDX_OCF0B);
- update_interrupt(AVR8_INTIDX_TOV0);
- break;
+ case AVR8_REGIDX_TIMSK0:
+ LOGMASKED(LOG_TIMER0, "%s: TIMSK0 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIMSK0] = data;
+ update_interrupt(AVR8_INTIDX_OCF0A);
+ update_interrupt(AVR8_INTIDX_OCF0B);
+ update_interrupt(AVR8_INTIDX_TOV0);
+ break;
- case AVR8_REGIDX_TIMSK1:
- verboselog(m_pc, 0, "AVR8: TIMSK1 = %02x\n", data );
- m_r[AVR8_REGIDX_TIMSK1] = data;
- update_interrupt(AVR8_INTIDX_ICF1);
- update_interrupt(AVR8_INTIDX_OCF1A);
- update_interrupt(AVR8_INTIDX_OCF1B);
- update_interrupt(AVR8_INTIDX_TOV1);
- break;
+ case AVR8_REGIDX_TIMSK1:
+ LOGMASKED(LOG_TIMER1, "%s: TIMSK1 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIMSK1] = data;
+ update_interrupt(AVR8_INTIDX_ICF1);
+ update_interrupt(AVR8_INTIDX_OCF1A);
+ update_interrupt(AVR8_INTIDX_OCF1B);
+ update_interrupt(AVR8_INTIDX_TOV1);
+ break;
- case AVR8_REGIDX_TIMSK2:
- verboselog(m_pc, 0, "AVR8: TIMSK2 = %02x\n", data );
- m_r[AVR8_REGIDX_TIMSK2] = data;
- update_interrupt(AVR8_INTIDX_OCF2A);
- update_interrupt(AVR8_INTIDX_OCF2B);
- update_interrupt(AVR8_INTIDX_TOV2);
- break;
+ case AVR8_REGIDX_TIMSK2:
+ LOGMASKED(LOG_TIMER2, "%s: TIMSK2 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIMSK2] = data;
+ update_interrupt(AVR8_INTIDX_OCF2A);
+ update_interrupt(AVR8_INTIDX_OCF2B);
+ update_interrupt(AVR8_INTIDX_TOV2);
+ break;
- case AVR8_REGIDX_TIMSK3:
- verboselog(m_pc, 0, "AVR8: TIMSK3 = %02x\n", data );
- m_r[AVR8_REGIDX_TIMSK3] = data;
- update_interrupt(AVR8_INTIDX_OCF3A);
- update_interrupt(AVR8_INTIDX_OCF3B);
- update_interrupt(AVR8_INTIDX_TOV3);
- break;
+ case AVR8_REGIDX_TIMSK3:
+ LOGMASKED(LOG_TIMER3, "%s: TIMSK3 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIMSK3] = data;
+ update_interrupt(AVR8_INTIDX_OCF3A);
+ update_interrupt(AVR8_INTIDX_OCF3B);
+ update_interrupt(AVR8_INTIDX_TOV3);
+ break;
- case AVR8_REGIDX_TIMSK4:
- verboselog(m_pc, 0, "AVR8: TIMSK4 = %02x\n", data );
- m_r[AVR8_REGIDX_TIMSK4] = data;
- update_interrupt(AVR8_INTIDX_OCF4A);
- update_interrupt(AVR8_INTIDX_OCF4B);
- update_interrupt(AVR8_INTIDX_TOV4);
- break;
+ case AVR8_REGIDX_TIMSK4:
+ LOGMASKED(LOG_TIMER4, "%s: TIMSK4 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIMSK4] = data;
+ update_interrupt(AVR8_INTIDX_OCF4A);
+ update_interrupt(AVR8_INTIDX_OCF4B);
+ update_interrupt(AVR8_INTIDX_TOV4);
+ break;
- case AVR8_REGIDX_TIMSK5:
- verboselog(m_pc, 0, "AVR8: TIMSK5 = %02x\n", data );
- m_r[AVR8_REGIDX_TIMSK5] = data;
- update_interrupt(AVR8_INTIDX_OCF5A);
- update_interrupt(AVR8_INTIDX_OCF5B);
- update_interrupt(AVR8_INTIDX_TOV5);
- break;
+ case AVR8_REGIDX_TIMSK5:
+ LOGMASKED(LOG_TIMER5, "%s: TIMSK5 = %02x\n", machine().describe_context(), data);
+ m_r[AVR8_REGIDX_TIMSK5] = data;
+ update_interrupt(AVR8_INTIDX_OCF5A);
+ update_interrupt(AVR8_INTIDX_OCF5B);
+ update_interrupt(AVR8_INTIDX_TOV5);
+ break;
case AVR8_REGIDX_XMCRA:
- verboselog(m_pc, 0, "AVR8: XMCRA = %02x\n", data );
- //TODO: changed_xmcra(data);
+ LOGMASKED(LOG_EXTMEM, "%s: (not yet implemented) XMCRA = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_XMCRB:
- verboselog(m_pc, 0, "AVR8: XMCRB = %02x\n", data );
- //TODO: changed_xmcrb(data);
+ LOGMASKED(LOG_EXTMEM, "%s: (not yet implemented) XMCRB = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_ADCL:
- verboselog(m_pc, 0, "AVR8: ADCL = %02x\n", data );
- //TODO: changed_adcl(data);
+ LOGMASKED(LOG_ADC, "%s: (not yet implemented) ADCL = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_ADCH:
- verboselog(m_pc, 0, "AVR8: ADCH = %02x\n", data );
- //TODO: changed_adch(data);
+ LOGMASKED(LOG_ADC, "%s: (not yet implemented) ADCH = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_ADCSRA:
- verboselog(m_pc, 0, "AVR8: ADCSRA = %02x\n", data );
- //TODO: changed_adcsra(data);
+ LOGMASKED(LOG_ADC, "%s: (not yet implemented) ADCSRA = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_ADCSRB:
- verboselog(m_pc, 0, "AVR8: ADCSRB = %02x\n", data );
- //TODO: changed_adcsrb(data);
+ LOGMASKED(LOG_ADC, "%s: (not yet implemented) ADCSRB = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_ADMUX:
- verboselog(m_pc, 0, "AVR8: ADMUX = %02x\n", data );
- //TODO: changed_admux(data);
+ LOGMASKED(LOG_ADC, "%s: (not yet implemented) ADMUX = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_DIDR0:
- verboselog(m_pc, 0, "AVR8: DIDR0 = %02x\n", data );
- //TODO: changed_didr0(data);
+ LOGMASKED(LOG_DIGINPUT, "%s: (not yet implemented) DIDR0 = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_DIDR1:
- verboselog(m_pc, 0, "AVR8: DIDR1 = %02x\n", data );
- //TODO: changed_didr1(data);
+ LOGMASKED(LOG_DIGINPUT, "%s: (not yet implemented) DIDR1 = %02x\n", machine().describe_context(), data);
break;
case AVR8_REGIDX_DIDR2:
- verboselog(m_pc, 0, "AVR8: DIDR2 = %02x\n", data );
- //TODO: changed_didr2(data);
+ LOGMASKED(LOG_DIGINPUT, "%s: (not yet implemented) DIDR2 = %02x\n", machine().describe_context(), data);
break;
- case AVR8_REGIDX_TCCR1A:
- verboselog(m_pc, 0, "AVR8: TCCR1A = %02x\n", data );
- changed_tccr1a(data);
- break;
+ case AVR8_REGIDX_TCCR1A:
+ LOGMASKED(LOG_TIMER1, "%s: TCCR1A = %02x\n", machine().describe_context(), data);
+ changed_tccr1a(data);
+ break;
- case AVR8_REGIDX_TCCR1B:
- verboselog(m_pc, 0, "AVR8: TCCR1B = %02x\n", data );
- changed_tccr1b(data);
- break;
+ case AVR8_REGIDX_TCCR1B:
+ LOGMASKED(LOG_TIMER1, "%s: TCCR1B = %02x\n", machine().describe_context(), data);
+ changed_tccr1b(data);
+ break;
- case AVR8_REGIDX_TCCR1C:
- verboselog(m_pc, 0, "AVR8: TCCR1C = %02x\n", data );
- //TODO: changed_tccr1c(data);
- break;
+ case AVR8_REGIDX_TCCR1C:
+ LOGMASKED(LOG_TIMER1, "%s: (not yet implemented) TCCR1C = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_TCNT1L:
- AVR8_TCNT1L = data;
- break;
+ case AVR8_REGIDX_TCNT1L:
+ AVR8_TCNT1L = data;
+ break;
- case AVR8_REGIDX_TCNT1H:
- AVR8_TCNT1H = data;
- break;
+ case AVR8_REGIDX_TCNT1H:
+ AVR8_TCNT1H = data;
+ break;
- case AVR8_REGIDX_ICR1L:
- AVR8_ICR1L = data;
- break;
+ case AVR8_REGIDX_ICR1L:
+ AVR8_ICR1L = data;
+ break;
- case AVR8_REGIDX_ICR1H:
- AVR8_ICR1H = data;
- break;
+ case AVR8_REGIDX_ICR1H:
+ AVR8_ICR1H = data;
+ break;
- case AVR8_REGIDX_OCR1AL:
- verboselog(m_pc, 0, "AVR8: OCR1AL = %02x\n", data );
- update_ocr1((AVR8_OCR1A & 0xff00) | data, AVR8_REG_A);
- break;
+ case AVR8_REGIDX_OCR1AL:
+ LOGMASKED(LOG_TIMER1, "%s: OCR1AL = %02x\n", machine().describe_context(), data);
+ update_ocr1((AVR8_OCR1A & 0xff00) | data, AVR8_REG_A);
+ break;
- case AVR8_REGIDX_OCR1AH:
- verboselog(m_pc, 0, "AVR8: OCR1AH = %02x\n", data );
- update_ocr1((AVR8_OCR1A & 0x00ff) | (data << 8), AVR8_REG_A);
- break;
+ case AVR8_REGIDX_OCR1AH:
+ LOGMASKED(LOG_TIMER1, "%s: OCR1AH = %02x\n", machine().describe_context(), data);
+ update_ocr1((AVR8_OCR1A & 0x00ff) | (data << 8), AVR8_REG_A);
+ break;
- case AVR8_REGIDX_OCR1BL:
- verboselog(m_pc, 0, "AVR8: OCR1BL = %02x\n", data );
- update_ocr1((AVR8_OCR1B & 0xff00) | data, AVR8_REG_B);
- break;
+ case AVR8_REGIDX_OCR1BL:
+ LOGMASKED(LOG_TIMER1, "%s: OCR1BL = %02x\n", machine().describe_context(), data);
+ update_ocr1((AVR8_OCR1B & 0xff00) | data, AVR8_REG_B);
+ break;
- case AVR8_REGIDX_OCR1BH:
- verboselog(m_pc, 0, "AVR8: OCR1BH = %02x\n", data );
- update_ocr1((AVR8_OCR1B & 0x00ff) | (data << 8), AVR8_REG_B);
- break;
+ case AVR8_REGIDX_OCR1BH:
+ LOGMASKED(LOG_TIMER1, "%s: OCR1BH = %02x\n", machine().describe_context(), data);
+ update_ocr1((AVR8_OCR1B & 0x00ff) | (data << 8), AVR8_REG_B);
+ break;
- case AVR8_REGIDX_OCR1CL:
- verboselog(m_pc, 0, "AVR8: OCR1CL = %02x\n", data );
- update_ocr1((AVR8_OCR1C & 0xff00) | data, AVR8_REG_C);
- break;
+ case AVR8_REGIDX_OCR1CL:
+ LOGMASKED(LOG_TIMER1, "%s: OCR1CL = %02x\n", machine().describe_context(), data);
+ update_ocr1((AVR8_OCR1C & 0xff00) | data, AVR8_REG_C);
+ break;
- case AVR8_REGIDX_OCR1CH:
- verboselog(m_pc, 0, "AVR8: OCR1CH = %02x\n", data );
- update_ocr1((AVR8_OCR1C & 0x00ff) | (data << 8), AVR8_REG_C);
- break;
+ case AVR8_REGIDX_OCR1CH:
+ LOGMASKED(LOG_TIMER1, "%s: OCR1CH = %02x\n", machine().describe_context(), data);
+ update_ocr1((AVR8_OCR1C & 0x00ff) | (data << 8), AVR8_REG_C);
+ break;
- case AVR8_REGIDX_TCCR2A:
- verboselog(m_pc, 0, "AVR8: TCCR2A = %02x\n", data );
- changed_tccr2a(data);
- break;
+ case AVR8_REGIDX_TCCR2A:
+ LOGMASKED(LOG_TIMER2, "%s: TCCR2A = %02x\n", machine().describe_context(), data);
+ changed_tccr2a(data);
+ break;
- case AVR8_REGIDX_TCCR2B:
- verboselog(m_pc, 0, "AVR8: TCCR2B = %02x\n", data );
- changed_tccr2b(data);
- break;
+ case AVR8_REGIDX_TCCR2B:
+ LOGMASKED(LOG_TIMER2, "%s: TCCR2B = %02x\n", machine().describe_context(), data);
+ changed_tccr2b(data);
+ break;
- case AVR8_REGIDX_TCNT2:
- AVR8_TCNT2 = data;
- break;
+ case AVR8_REGIDX_TCNT2:
+ AVR8_TCNT2 = data;
+ break;
- case AVR8_REGIDX_OCR2A:
- update_ocr2(data, AVR8_REG_A);
- break;
+ case AVR8_REGIDX_OCR2A:
+ update_ocr2(data, AVR8_REG_A);
+ break;
- case AVR8_REGIDX_OCR2B:
- update_ocr2(data, AVR8_REG_B);
- break;
+ case AVR8_REGIDX_OCR2B:
+ update_ocr2(data, AVR8_REG_B);
+ break;
- case AVR8_REGIDX_TCCR3A:
- verboselog(m_pc, 0, "AVR8: TCCR3A = %02x\n", data );
+ case AVR8_REGIDX_TCCR3A:
+ LOGMASKED(LOG_TIMER3, "%s: TCCR3A = %02x\n", machine().describe_context(), data);
changed_tccr3a(data);
- break;
+ break;
- case AVR8_REGIDX_TCCR3B:
- verboselog(m_pc, 0, "AVR8: TCCR3B = %02x\n", data );
+ case AVR8_REGIDX_TCCR3B:
+ LOGMASKED(LOG_TIMER3, "%s: TCCR3B = %02x\n", machine().describe_context(), data);
changed_tccr3b(data);
- break;
+ break;
- case AVR8_REGIDX_TCCR3C:
- verboselog(m_pc, 0, "AVR8: TCCR3C = %02x\n", data );
+ case AVR8_REGIDX_TCCR3C:
+ LOGMASKED(LOG_TIMER3, "%s: TCCR3C = %02x\n", machine().describe_context(), data);
changed_tccr3c(data);
- break;
+ break;
- case AVR8_REGIDX_TCNT3L:
- AVR8_TCNT3L = data;
- break;
+ case AVR8_REGIDX_TCNT3L:
+ AVR8_TCNT3L = data;
+ break;
- case AVR8_REGIDX_TCNT3H:
- AVR8_TCNT3H = data;
- break;
+ case AVR8_REGIDX_TCNT3H:
+ AVR8_TCNT3H = data;
+ break;
- case AVR8_REGIDX_ICR3L:
- AVR8_ICR3L = data;
- break;
+ case AVR8_REGIDX_ICR3L:
+ AVR8_ICR3L = data;
+ break;
- case AVR8_REGIDX_ICR3H:
- AVR8_ICR3H = data;
- break;
+ case AVR8_REGIDX_ICR3H:
+ AVR8_ICR3H = data;
+ break;
- case AVR8_REGIDX_OCR3AL:
- AVR8_OCR3AL = data;
- break;
+ case AVR8_REGIDX_OCR3AL:
+ AVR8_OCR3AL = data;
+ break;
- case AVR8_REGIDX_OCR3AH:
- AVR8_OCR3AH = data;
- break;
+ case AVR8_REGIDX_OCR3AH:
+ AVR8_OCR3AH = data;
+ break;
- case AVR8_REGIDX_OCR3BL:
- AVR8_OCR3BL = data;
- break;
+ case AVR8_REGIDX_OCR3BL:
+ AVR8_OCR3BL = data;
+ break;
- case AVR8_REGIDX_OCR3BH:
- AVR8_OCR3BH = data;
- break;
+ case AVR8_REGIDX_OCR3BH:
+ AVR8_OCR3BH = data;
+ break;
- case AVR8_REGIDX_OCR3CL:
- AVR8_OCR3CL = data;
- break;
+ case AVR8_REGIDX_OCR3CL:
+ AVR8_OCR3CL = data;
+ break;
- case AVR8_REGIDX_OCR3CH:
- AVR8_OCR3CH = data;
- break;
+ case AVR8_REGIDX_OCR3CH:
+ AVR8_OCR3CH = data;
+ break;
- case AVR8_REGIDX_TCCR4A:
- verboselog(m_pc, 0, "AVR8: TCCR4A = %02x\n", data );
+ case AVR8_REGIDX_TCCR4A:
+ LOGMASKED(LOG_TIMER4, "%s: TCCR4A = %02x\n", machine().describe_context(), data);
changed_tccr4a(data);
- break;
+ break;
- case AVR8_REGIDX_TCCR4B:
- verboselog(m_pc, 0, "AVR8: TCCR4B = %02x\n", data );
+ case AVR8_REGIDX_TCCR4B:
+ LOGMASKED(LOG_TIMER4, "%s: TCCR4B = %02x\n", machine().describe_context(), data);
changed_tccr4b(data);
- break;
+ break;
- case AVR8_REGIDX_TCCR4C:
- verboselog(m_pc, 0, "AVR8: TCCR4C = %02x\n", data );
+ case AVR8_REGIDX_TCCR4C:
+ LOGMASKED(LOG_TIMER4, "%s: TCCR4C = %02x\n", machine().describe_context(), data);
changed_tccr4c(data);
- break;
+ break;
- case AVR8_REGIDX_TCNT4L:
- AVR8_TCNT4L = data;
- break;
+ case AVR8_REGIDX_TCNT4L:
+ AVR8_TCNT4L = data;
+ break;
- case AVR8_REGIDX_TCNT4H:
- AVR8_TCNT4H = data;
- break;
+ case AVR8_REGIDX_TCNT4H:
+ AVR8_TCNT4H = data;
+ break;
- case AVR8_REGIDX_ICR4L:
- AVR8_ICR4L = data;
- break;
+ case AVR8_REGIDX_ICR4L:
+ AVR8_ICR4L = data;
+ break;
- case AVR8_REGIDX_ICR4H:
- AVR8_ICR4H = data;
- break;
+ case AVR8_REGIDX_ICR4H:
+ AVR8_ICR4H = data;
+ break;
- case AVR8_REGIDX_OCR4AL:
- AVR8_OCR4AL = data;
- break;
+ case AVR8_REGIDX_OCR4AL:
+ AVR8_OCR4AL = data;
+ break;
- case AVR8_REGIDX_OCR4AH:
- AVR8_OCR4AH = data;
- break;
+ case AVR8_REGIDX_OCR4AH:
+ AVR8_OCR4AH = data;
+ break;
- case AVR8_REGIDX_OCR4BL:
- AVR8_OCR4BL = data;
- break;
+ case AVR8_REGIDX_OCR4BL:
+ AVR8_OCR4BL = data;
+ break;
- case AVR8_REGIDX_OCR4BH:
- AVR8_OCR4BH = data;
- break;
+ case AVR8_REGIDX_OCR4BH:
+ AVR8_OCR4BH = data;
+ break;
- case AVR8_REGIDX_OCR4CL:
- AVR8_OCR4CL = data;
- break;
+ case AVR8_REGIDX_OCR4CL:
+ AVR8_OCR4CL = data;
+ break;
- case AVR8_REGIDX_OCR4CH:
- AVR8_OCR4CH = data;
- break;
+ case AVR8_REGIDX_OCR4CH:
+ AVR8_OCR4CH = data;
+ break;
- case AVR8_REGIDX_TCCR5A:
- verboselog(m_pc, 0, "AVR8: TCCR5A = %02x\n", data );
+ case AVR8_REGIDX_TCCR5A:
+ LOGMASKED(LOG_TIMER5, "%s: TCCR5A = %02x\n", machine().describe_context(), data);
changed_tccr5a(data);
- break;
+ break;
- case AVR8_REGIDX_TCCR5B:
- verboselog(m_pc, 0, "AVR8: TCCR5B = %02x\n", data );
+ case AVR8_REGIDX_TCCR5B:
+ LOGMASKED(LOG_TIMER5, "%s: TCCR5B = %02x\n", machine().describe_context(), data);
changed_tccr5b(data);
- break;
+ break;
- case AVR8_REGIDX_ASSR:
- verboselog(m_pc, 0, "AVR8: ASSR = %02x\n", data );
- //TODO: changed_assr(data);
- break;
+ case AVR8_REGIDX_ASSR:
+ LOGMASKED(LOG_ASYNC, "%s: (not yet implemented) ASSR = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_TWBR:
- verboselog(m_pc, 0, "AVR8: TWBR = %02x\n", data );
- //TODO: changed_twbr(data);
- break;
+ case AVR8_REGIDX_TWBR:
+ LOGMASKED(LOG_TWI, "%s: (not yet implemented) TWBR = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_TWSR:
- verboselog(m_pc, 0, "AVR8: TWSR = %02x\n", data );
- //TODO: changed_twsr(data);
- break;
+ case AVR8_REGIDX_TWSR:
+ LOGMASKED(LOG_TWI, "%s: (not yet implemented) TWSR = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_TWAR:
- verboselog(m_pc, 0, "AVR8: TWAR = %02x\n", data );
- //TODO: changed_twar(data);
- break;
+ case AVR8_REGIDX_TWAR:
+ LOGMASKED(LOG_TWI, "%s: (not yet implemented) TWAR = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_TWDR:
- verboselog(m_pc, 0, "AVR8: TWDR = %02x\n", data );
- //TODO: changed_twdr(data);
- break;
+ case AVR8_REGIDX_TWDR:
+ LOGMASKED(LOG_TWI, "%s: (not yet implemented) TWDR = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_TWCR:
- verboselog(m_pc, 0, "AVR8: TWCR = %02x\n", data );
- //TODO: changed_twcr(data);
+ case AVR8_REGIDX_TWCR:
+ LOGMASKED(LOG_TWI, "%s: (not yet implemented) TWCR = %02x\n", machine().describe_context(), data);
m_r[AVR8_REGIDX_TWCR] = data;
- break;
+ break;
- case AVR8_REGIDX_TWAMR:
- verboselog(m_pc, 0, "AVR8: TWAMR = %02x\n", data );
- //TODO: changed_twamr(data);
- break;
+ case AVR8_REGIDX_TWAMR:
+ LOGMASKED(LOG_TWI, "%s: (not yet implemented) TWAMR = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_UCSR0A:
- verboselog(m_pc, 0, "AVR8: UCSR0A = %02x\n", data );
- //TODO: changed_ucsr0a(data);
- break;
+ case AVR8_REGIDX_UCSR0A:
+ LOGMASKED(LOG_UART, "%s: (not yet implemented) UCSR0A = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_UCSR0B:
- verboselog(m_pc, 0, "AVR8: UCSR0B = %02x\n", data );
- //TODO: changed_ucsr0b(data);
- break;
+ case AVR8_REGIDX_UCSR0B:
+ LOGMASKED(LOG_UART, "%s: (not yet implemented) UCSR0B = %02x\n", machine().describe_context(), data);
+ break;
- case AVR8_REGIDX_UCSR0C:
- verboselog(m_pc, 0, "AVR8: UCSR0C = %02x\n", data );
- //TODO: changed_ucsr0c(data);
- break;
-/*
- case AVR8_REGIDX_:
- verboselog(m_pc, 0, "AVR8: = %02x\n", data );
- //TODO: changed_(data);
- break;
-*/
- default:
- verboselog(m_pc, 0, "AVR8: Unknown Register Write: %03x = %02x\n", offset, data);
- break;
+ case AVR8_REGIDX_UCSR0C:
+ LOGMASKED(LOG_UART, "%s: (not yet implemented) UCSR0C = %02x\n", machine().describe_context(), data);
+ break;
+
+ default:
+ LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Write: %03x = %02x\n", machine().describe_context(), offset, data);
+ break;
}
}
-READ8_MEMBER( avr8_device::regs_r )
-{
-// printf("--- READ offset %04x ---\n", offset);
-
- switch( offset )
- {
- case AVR8_REGIDX_R0:
- case AVR8_REGIDX_R1:
- case AVR8_REGIDX_R2:
- case AVR8_REGIDX_R3:
- case AVR8_REGIDX_R4:
- case AVR8_REGIDX_R5:
- case AVR8_REGIDX_R6:
- case AVR8_REGIDX_R7:
- case AVR8_REGIDX_R8:
- case AVR8_REGIDX_R9:
- case AVR8_REGIDX_R10:
- case AVR8_REGIDX_R11:
- case AVR8_REGIDX_R12:
- case AVR8_REGIDX_R13:
- case AVR8_REGIDX_R14:
- case AVR8_REGIDX_R15:
- case AVR8_REGIDX_R16:
- case AVR8_REGIDX_R17:
- case AVR8_REGIDX_R18:
- case AVR8_REGIDX_R19:
- case AVR8_REGIDX_R20:
- case AVR8_REGIDX_R21:
- case AVR8_REGIDX_R22:
- case AVR8_REGIDX_R23:
- case AVR8_REGIDX_R24:
- case AVR8_REGIDX_R25:
- case AVR8_REGIDX_R26:
- case AVR8_REGIDX_R27:
- case AVR8_REGIDX_R28:
- case AVR8_REGIDX_R29:
- case AVR8_REGIDX_R30:
- case AVR8_REGIDX_R31:
- return m_r[offset];
-
- case AVR8_REGIDX_PINA:
- // TODO: consider the DDRA
+READ8_MEMBER(avr8_device::regs_r)
+{
+ switch (offset)
+ {
+ case AVR8_REGIDX_R0:
+ case AVR8_REGIDX_R1:
+ case AVR8_REGIDX_R2:
+ case AVR8_REGIDX_R3:
+ case AVR8_REGIDX_R4:
+ case AVR8_REGIDX_R5:
+ case AVR8_REGIDX_R6:
+ case AVR8_REGIDX_R7:
+ case AVR8_REGIDX_R8:
+ case AVR8_REGIDX_R9:
+ case AVR8_REGIDX_R10:
+ case AVR8_REGIDX_R11:
+ case AVR8_REGIDX_R12:
+ case AVR8_REGIDX_R13:
+ case AVR8_REGIDX_R14:
+ case AVR8_REGIDX_R15:
+ case AVR8_REGIDX_R16:
+ case AVR8_REGIDX_R17:
+ case AVR8_REGIDX_R18:
+ case AVR8_REGIDX_R19:
+ case AVR8_REGIDX_R20:
+ case AVR8_REGIDX_R21:
+ case AVR8_REGIDX_R22:
+ case AVR8_REGIDX_R23:
+ case AVR8_REGIDX_R24:
+ case AVR8_REGIDX_R25:
+ case AVR8_REGIDX_R26:
+ case AVR8_REGIDX_R27:
+ case AVR8_REGIDX_R28:
+ case AVR8_REGIDX_R29:
+ case AVR8_REGIDX_R30:
+ case AVR8_REGIDX_R31:
+ return m_r[offset];
+
+ case AVR8_REGIDX_PINA:
+ // TODO: account for DDRA
return m_io->read_byte(AVR8_REG_A);
- case AVR8_REGIDX_PINB:
- // TODO: consider the DDRB
+ case AVR8_REGIDX_PINB:
+ // TODO: account for DDRB
return m_io->read_byte(AVR8_REG_B);
- case AVR8_REGIDX_PINC:
- // TODO: consider the DDRC
+ case AVR8_REGIDX_PINC:
+ // TODO: account for DDRC
return m_io->read_byte(AVR8_REG_C);
- case AVR8_REGIDX_PIND:
- // TODO: consider the DDRD
+ case AVR8_REGIDX_PIND:
+ // TODO: account for DDRD
return m_io->read_byte(AVR8_REG_D);
- case AVR8_REGIDX_PINE:
- // TODO: consider the DDRE
+ case AVR8_REGIDX_PINE:
+ // TODO: account for DDRE
return m_io->read_byte(AVR8_REG_E);
- case AVR8_REGIDX_PINF:
- // TODO: consider the DDRF
+ case AVR8_REGIDX_PINF:
+ // TODO: account for DDRF
return m_io->read_byte(AVR8_REG_F);
- case AVR8_REGIDX_PING:
- // TODO: consider the DDRG
+ case AVR8_REGIDX_PING:
+ // TODO: account for DDRG
return m_io->read_byte(AVR8_REG_G);
- case AVR8_REGIDX_PINH:
- // TODO: consider the DDRH
+ case AVR8_REGIDX_PINH:
+ // TODO: account for DDRH
return m_io->read_byte(AVR8_REG_H);
- case AVR8_REGIDX_PINJ:
- // TODO: consider the DDRJ
+ case AVR8_REGIDX_PINJ:
+ // TODO: account for DDRJ
return m_io->read_byte(AVR8_REG_J);
- case AVR8_REGIDX_PINK:
- // TODO: consider the DDRK
+ case AVR8_REGIDX_PINK:
+ // TODO: account for DDRK
return m_io->read_byte(AVR8_REG_K);
- case AVR8_REGIDX_PINL:
- // TODO: consider the DDRL
+ case AVR8_REGIDX_PINL:
+ // TODO: account for DDRL
return m_io->read_byte(AVR8_REG_L);
- case AVR8_REGIDX_PORTA:
- case AVR8_REGIDX_PORTB:
- case AVR8_REGIDX_PORTC:
- case AVR8_REGIDX_PORTD:
- case AVR8_REGIDX_PORTE:
- case AVR8_REGIDX_PORTF:
- case AVR8_REGIDX_PORTG:
- case AVR8_REGIDX_PORTH:
- case AVR8_REGIDX_PORTJ:
- case AVR8_REGIDX_PORTK:
- case AVR8_REGIDX_PORTL:
- return m_r[offset];
-
- case AVR8_REGIDX_DDRA:
- case AVR8_REGIDX_DDRB:
- case AVR8_REGIDX_DDRC:
- case AVR8_REGIDX_DDRD:
- case AVR8_REGIDX_DDRE:
- case AVR8_REGIDX_DDRF:
- case AVR8_REGIDX_DDRG:
- case AVR8_REGIDX_DDRH:
- case AVR8_REGIDX_DDRJ:
- case AVR8_REGIDX_DDRK:
- case AVR8_REGIDX_DDRL:
- return m_r[offset];
-
-// EEPROM registers:
+ case AVR8_REGIDX_PORTA:
+ case AVR8_REGIDX_PORTB:
+ case AVR8_REGIDX_PORTC:
+ case AVR8_REGIDX_PORTD:
+ case AVR8_REGIDX_PORTE:
+ case AVR8_REGIDX_PORTF:
+ case AVR8_REGIDX_PORTG:
+ case AVR8_REGIDX_PORTH:
+ case AVR8_REGIDX_PORTJ:
+ case AVR8_REGIDX_PORTK:
+ case AVR8_REGIDX_PORTL:
+ return m_r[offset];
+
+ case AVR8_REGIDX_DDRA:
+ case AVR8_REGIDX_DDRB:
+ case AVR8_REGIDX_DDRC:
+ case AVR8_REGIDX_DDRD:
+ case AVR8_REGIDX_DDRE:
+ case AVR8_REGIDX_DDRF:
+ case AVR8_REGIDX_DDRG:
+ case AVR8_REGIDX_DDRH:
+ case AVR8_REGIDX_DDRJ:
+ case AVR8_REGIDX_DDRK:
+ case AVR8_REGIDX_DDRL:
+ return m_r[offset];
+
+ // EEPROM registers
case AVR8_REGIDX_EECR:
- case AVR8_REGIDX_EEDR:
- return m_r[offset];
-
-/* Misc. registers.
- TODO: implement all registers reads */
-
- case AVR8_REGIDX_GPIOR0:
- case AVR8_REGIDX_GPIOR1:
- case AVR8_REGIDX_GPIOR2:
-// case AVR8_REGIDX_UCSR0B:/*TODO: needed for Replicator 1 */
- case AVR8_REGIDX_SPDR: /*TODO: needed for Replicator 1 */
- case AVR8_REGIDX_SPSR: /*TODO: needed for Replicator 1 */
-// case AVR8_REGIDX_ADCSRA: /*TODO: needed for Replicator 1 */
-// case AVR8_REGIDX_ADCSRB: /*TODO: needed for Replicator 1 */
- case AVR8_REGIDX_SPL:
- case AVR8_REGIDX_SPH:
- case AVR8_REGIDX_SREG:
+ case AVR8_REGIDX_EEDR:
+ return m_r[offset];
+
+ // Miscellaneous registers
+ // TODO: Implement readback for all applicable registers.
+
+ case AVR8_REGIDX_GPIOR0:
+ case AVR8_REGIDX_GPIOR1:
+ case AVR8_REGIDX_GPIOR2:
+// case AVR8_REGIDX_UCSR0B: // TODO: needed for Replicator 1
+ case AVR8_REGIDX_SPDR: // TODO: needed for Replicator 1
+ case AVR8_REGIDX_SPSR: // TODO: needed for Replicator 1
+// case AVR8_REGIDX_ADCSRA: // TODO: needed for Replicator 1
+// case AVR8_REGIDX_ADCSRB: // TODO: needed for Replicator 1
+ case AVR8_REGIDX_SPL:
+ case AVR8_REGIDX_SPH:
+ case AVR8_REGIDX_SREG:
case AVR8_REGIDX_TIMSK0:
case AVR8_REGIDX_TIMSK1:
case AVR8_REGIDX_TIMSK2:
-// case AVR8_REGIDX_TIMSK3: /*TODO: needed for Replicator 1 */
+// case AVR8_REGIDX_TIMSK3: // TODO: needed for Replicator 1
case AVR8_REGIDX_TIMSK4:
case AVR8_REGIDX_TIMSK5:
- return m_r[offset];
+ return m_r[offset];
-/* Two-wire registers: */
- case AVR8_REGIDX_TWCR:
- /*TODO: needed for Replicator 1
- BLOQUEIA PROGRESSO DA EXECU??O DO FIRMWARE no endere?o 105EC*/
- return m_r[offset];
+ // Two-wire registers
+ case AVR8_REGIDX_TWCR:
+ // TODO: needed for Replicator 1
+ return m_r[offset];
- case AVR8_REGIDX_TWSR:
- //quick hack: by returning a value != 0x08 we induce an error state that makes the object code jump out of the wait loop and continue execution failing the 2-wire write operation.
- //TODO: implement-me!
- return 0x00; /*TODO: needed for Replicator 1 */
+ case AVR8_REGIDX_TWSR:
+ // HACK for Replicator 1:
+ // By returning a value != 0x08, we induce an error state that makes the object code jump out of the wait loop,
+ // and continue execution failing the 2-wire write operation.
+ return 0x00;
- case AVR8_REGIDX_TCNT1L:
- case AVR8_REGIDX_TCNT1H:
- case AVR8_REGIDX_TCNT2:
- case AVR8_REGIDX_UCSR0A:
- return m_r[offset];
+ case AVR8_REGIDX_TCNT1L:
+ case AVR8_REGIDX_TCNT1H:
+ case AVR8_REGIDX_TCNT2:
+ case AVR8_REGIDX_UCSR0A:
+ return m_r[offset];
- default:
- printf("[%08X] AVR8: Unknown Register Read: 0x%03X\n", m_shifted_pc, offset);
-// machine().debug_break();
- return 0;
+ default:
+ LOGMASKED(LOG_UNKNOWN, "%s: Unknown Register Read: %03X\n", machine().describe_context(), offset);
+ return 0;
}
}
@@ -2936,215 +2954,87 @@ void avr8_device::execute_run()
op = (uint32_t)m_program->read_word(m_shifted_pc);
- switch(op & 0xf000)
+ switch (op & 0xf000)
{
- case 0x0000:
- switch(op & 0x0f00)
- {
- case 0x0000: // NOP
- break;
- case 0x0100: // MOVW Rd+1:Rd,Rr+1:Rd
- m_r[(RD4(op) << 1) + 1] = m_r[(RR4(op) << 1) + 1];
- m_r[RD4(op) << 1] = m_r[RR4(op) << 1];
- break;
- case 0x0200: // MULS Rd,Rr
- sd = (int8_t)m_r[16 + RD4(op)] * (int8_t)m_r[16 + RR4(op)];
- m_r[1] = (sd >> 8) & 0x00ff;
- m_r[0] = sd & 0x00ff;
- SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
- SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
- opcycles = 2;
- break;
- case 0x0300: // Multiplicatn
- switch(MULCONST2(op))
- {
- case 0x0000: // MULSU Rd,Rr
- sd = (int8_t)m_r[16 + RD3(op)] * (uint8_t)m_r[16 + RR3(op)];
- m_r[1] = (sd >> 8) & 0x00ff;
- m_r[0] = sd & 0x00ff;
- SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
- SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
- opcycles = 2;
- break;
- case 0x0001: // FMUL Rd,Rr
- sd = (uint8_t)m_r[16 + RD3(op)] * (uint8_t)m_r[16 + RR3(op)];
- sd <<= 1;
- m_r[1] = (sd >> 8) & 0x00ff;
- m_r[0] = sd & 0x00ff;
- SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
- SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
- opcycles = 2;
- break;
- case 0x0002: // FMULS Rd,Rr
- sd = (int8_t)m_r[16 + RD3(op)] * (int8_t)m_r[16 + RR3(op)];
- sd <<= 1;
- m_r[1] = (sd >> 8) & 0x00ff;
- m_r[0] = sd & 0x00ff;
- SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
- SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
- opcycles = 2;
- break;
- case 0x0003: // FMULSU Rd,Rr
- sd = (int8_t)m_r[16 + RD3(op)] * (uint8_t)m_r[16 + RR3(op)];
- sd <<= 1;
- m_r[1] = (sd >> 8) & 0x00ff;
- m_r[0] = sd & 0x00ff;
- SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
- SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
- opcycles = 2;
- break;
- }
- break;
- case 0x0400:
- case 0x0500:
- case 0x0600:
- case 0x0700: // CPC Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- res = rd - (rr + SREG_R(AVR8_SREG_C));
- SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
- SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? SREG_R(AVR8_SREG_Z) : 0);
- SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
- break;
- case 0x0800:
- case 0x0900:
- case 0x0a00:
- case 0x0b00: // SBC Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- res = rd - (rr + SREG_R(AVR8_SREG_C));
- m_r[RD5(op)] = res;
- SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
- SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? SREG_R(AVR8_SREG_Z) : 0);
- SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
- break;
- case 0x0c00:
- case 0x0d00:
- case 0x0e00:
- case 0x0f00: // ADD Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- res = rd + rr;
- m_r[RD5(op)] = res;
- SREG_W(AVR8_SREG_H, (BIT(rd,3) & BIT(rr,3)) | (BIT(rr,3) & NOT(BIT(res,3))) | (NOT(BIT(res,3)) & BIT(rd,3)));
- SREG_W(AVR8_SREG_V, (BIT(rd,7) & BIT(rr,7) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & NOT(BIT(rr,7)) & BIT(res,7)));
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_C, (BIT(rd,7) & BIT(rr,7)) | (BIT(rr,7) & NOT(BIT(res,7))) | (NOT(BIT(res,7)) & BIT(rd,7)));
- break;
- }
+ case 0x0000:
+ switch (op & 0x0f00)
+ {
+ case 0x0000: // NOP
break;
- case 0x1000:
- switch(op & 0x0c00)
- {
- case 0x0000: // CPSE Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- if (rd == rr)
- {
- op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
- opcycles += is_long_opcode(op) ? 2 : 1;
- m_pc += is_long_opcode(op) ? 2 : 1;
- }
- break;
- case 0x0400: // CP Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- res = rd - rr;
- SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
- SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
- break;
- case 0x0800: // SUB Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- res = rd - rr;
- m_r[RD5(op)] = res;
- SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
- SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
- break;
- case 0x0c00: // ADC Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- res = rd + rr + SREG_R(AVR8_SREG_C);
- m_r[RD5(op)] = res;
- SREG_W(AVR8_SREG_H, (BIT(rd,3) & BIT(rr,3)) | (BIT(rr,3) & NOT(BIT(res,3))) | (NOT(BIT(res,3)) & BIT(rd,3)));
- SREG_W(AVR8_SREG_V, (BIT(rd,7) & BIT(rr,7) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & NOT(BIT(rr,7)) & BIT(res,7)));
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_C, (BIT(rd,7) & BIT(rr,7)) | (BIT(rr,7) & NOT(BIT(res,7))) | (NOT(BIT(res,7)) & BIT(rd,7)));
- break;
- }
+ case 0x0100: // MOVW Rd+1:Rd,Rr+1:Rd
+ m_r[(RD4(op) << 1) + 1] = m_r[(RR4(op) << 1) + 1];
+ m_r[RD4(op) << 1] = m_r[RR4(op) << 1];
break;
- case 0x2000:
- switch(op & 0x0c00)
+ case 0x0200: // MULS Rd,Rr
+ sd = (int8_t)m_r[16 + RD4(op)] * (int8_t)m_r[16 + RR4(op)];
+ m_r[1] = (sd >> 8) & 0x00ff;
+ m_r[0] = sd & 0x00ff;
+ SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
+ SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
+ opcycles = 2;
+ break;
+ case 0x0300: // Multiplication
+ switch (MULCONST2(op))
{
- case 0x0000: // AND Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- rd &= rr;
- SREG_W(AVR8_SREG_V, 0);
- SREG_W(AVR8_SREG_N, BIT(rd,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0);
- m_r[RD5(op)] = rd;
- break;
- case 0x0400: // EOR Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- rd ^= rr;
- SREG_W(AVR8_SREG_V, 0);
- SREG_W(AVR8_SREG_N, BIT(rd,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0);
- m_r[RD5(op)] = rd;
- break;
- case 0x0800: // OR Rd,Rr
- rd = m_r[RD5(op)];
- rr = m_r[RR5(op)];
- rd |= rr;
- SREG_W(AVR8_SREG_V, 0);
- SREG_W(AVR8_SREG_N, BIT(rd,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0);
- m_r[RD5(op)] = rd;
- break;
- case 0x0c00: // MOV Rd,Rr
- m_r[RD5(op)] = m_r[RR5(op)];
- break;
+ case 0x0000: // MULSU Rd,Rr
+ sd = (int8_t)m_r[16 + RD3(op)] * (uint8_t)m_r[16 + RR3(op)];
+ m_r[1] = (sd >> 8) & 0x00ff;
+ m_r[0] = sd & 0x00ff;
+ SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
+ SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
+ opcycles = 2;
+ break;
+ case 0x0001: // FMUL Rd,Rr
+ sd = (uint8_t)m_r[16 + RD3(op)] * (uint8_t)m_r[16 + RR3(op)];
+ sd <<= 1;
+ m_r[1] = (sd >> 8) & 0x00ff;
+ m_r[0] = sd & 0x00ff;
+ SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
+ SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
+ opcycles = 2;
+ break;
+ case 0x0002: // FMULS Rd,Rr
+ sd = (int8_t)m_r[16 + RD3(op)] * (int8_t)m_r[16 + RR3(op)];
+ sd <<= 1;
+ m_r[1] = (sd >> 8) & 0x00ff;
+ m_r[0] = sd & 0x00ff;
+ SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
+ SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
+ opcycles = 2;
+ break;
+ case 0x0003: // FMULSU Rd,Rr
+ sd = (int8_t)m_r[16 + RD3(op)] * (uint8_t)m_r[16 + RR3(op)];
+ sd <<= 1;
+ m_r[1] = (sd >> 8) & 0x00ff;
+ m_r[0] = sd & 0x00ff;
+ SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
+ SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
+ opcycles = 2;
+ break;
}
break;
- case 0x3000: // CPI Rd,K
- rd = m_r[16 + RD4(op)];
- rr = KCONST8(op);
- res = rd - rr;
+ case 0x0400:
+ case 0x0500:
+ case 0x0600:
+ case 0x0700: // CPC Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
+ res = rd - (rr + SREG_R(AVR8_SREG_C));
SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
SREG_W(AVR8_SREG_N, BIT(res,7));
SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? SREG_R(AVR8_SREG_Z) : 0);
SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
break;
- case 0x4000: // SBCI Rd,K
- rd = m_r[16 + RD4(op)];
- rr = KCONST8(op);
+ case 0x0800:
+ case 0x0900:
+ case 0x0a00:
+ case 0x0b00: // SBC Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
res = rd - (rr + SREG_R(AVR8_SREG_C));
- m_r[16 + RD4(op)] = res;
+ m_r[RD5(op)] = res;
SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
SREG_W(AVR8_SREG_N, BIT(res,7));
@@ -3152,11 +3042,52 @@ void avr8_device::execute_run()
SREG_W(AVR8_SREG_Z, (res == 0) ? SREG_R(AVR8_SREG_Z) : 0);
SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
break;
- case 0x5000: // SUBI Rd,K
- rd = m_r[16 + RD4(op)];
- rr = KCONST8(op);
+ case 0x0c00:
+ case 0x0d00:
+ case 0x0e00:
+ case 0x0f00: // ADD Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
+ res = rd + rr;
+ m_r[RD5(op)] = res;
+ SREG_W(AVR8_SREG_H, (BIT(rd,3) & BIT(rr,3)) | (BIT(rr,3) & NOT(BIT(res,3))) | (NOT(BIT(res,3)) & BIT(rd,3)));
+ SREG_W(AVR8_SREG_V, (BIT(rd,7) & BIT(rr,7) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & NOT(BIT(rr,7)) & BIT(res,7)));
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, (BIT(rd,7) & BIT(rr,7)) | (BIT(rr,7) & NOT(BIT(res,7))) | (NOT(BIT(res,7)) & BIT(rd,7)));
+ break;
+ }
+ break;
+ case 0x1000:
+ switch (op & 0x0c00)
+ {
+ case 0x0000: // CPSE Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
+ if (rd == rr)
+ {
+ op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
+ opcycles += is_long_opcode(op) ? 2 : 1;
+ m_pc += is_long_opcode(op) ? 2 : 1;
+ }
+ break;
+ case 0x0400: // CP Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
+ res = rd - rr;
+ SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
+ SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
+ break;
+ case 0x0800: // SUB Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
res = rd - rr;
- m_r[16 + RD4(op)] = res;
+ m_r[RD5(op)] = res;
SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
SREG_W(AVR8_SREG_N, BIT(res,7));
@@ -3164,700 +3095,770 @@ void avr8_device::execute_run()
SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
break;
- case 0x6000: // ORI Rd,K
- rd = m_r[16 + RD4(op)];
- rr = KCONST8(op);
- rd |= rr;
+ case 0x0c00: // ADC Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
+ res = rd + rr + SREG_R(AVR8_SREG_C);
+ m_r[RD5(op)] = res;
+ SREG_W(AVR8_SREG_H, (BIT(rd,3) & BIT(rr,3)) | (BIT(rr,3) & NOT(BIT(res,3))) | (NOT(BIT(res,3)) & BIT(rd,3)));
+ SREG_W(AVR8_SREG_V, (BIT(rd,7) & BIT(rr,7) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & NOT(BIT(rr,7)) & BIT(res,7)));
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, (BIT(rd,7) & BIT(rr,7)) | (BIT(rr,7) & NOT(BIT(res,7))) | (NOT(BIT(res,7)) & BIT(rd,7)));
+ break;
+ }
+ break;
+ case 0x2000:
+ switch (op & 0x0c00)
+ {
+ case 0x0000: // AND Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
+ rd &= rr;
SREG_W(AVR8_SREG_V, 0);
SREG_W(AVR8_SREG_N, BIT(rd,7));
SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0);
- m_r[16 + RD4(op)] = rd;
+ m_r[RD5(op)] = rd;
break;
- case 0x7000: // ANDI Rd,K
- rd = m_r[16 + RD4(op)];
- rr = KCONST8(op);
- rd &= rr;
+ case 0x0400: // EOR Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
+ rd ^= rr;
+ SREG_W(AVR8_SREG_V, 0);
+ SREG_W(AVR8_SREG_N, BIT(rd,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0);
+ m_r[RD5(op)] = rd;
+ break;
+ case 0x0800: // OR Rd,Rr
+ rd = m_r[RD5(op)];
+ rr = m_r[RR5(op)];
+ rd |= rr;
SREG_W(AVR8_SREG_V, 0);
SREG_W(AVR8_SREG_N, BIT(rd,7));
SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0);
- m_r[16 + RD4(op)] = rd;
+ m_r[RD5(op)] = rd;
+ break;
+ case 0x0c00: // MOV Rd,Rr
+ m_r[RD5(op)] = m_r[RR5(op)];
+ break;
+ }
+ break;
+ case 0x3000: // CPI Rd,K
+ rd = m_r[16 + RD4(op)];
+ rr = KCONST8(op);
+ res = rd - rr;
+ SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
+ SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
+ break;
+ case 0x4000: // SBCI Rd,K
+ rd = m_r[16 + RD4(op)];
+ rr = KCONST8(op);
+ res = rd - (rr + SREG_R(AVR8_SREG_C));
+ m_r[16 + RD4(op)] = res;
+ SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
+ SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? SREG_R(AVR8_SREG_Z) : 0);
+ SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
+ break;
+ case 0x5000: // SUBI Rd,K
+ rd = m_r[16 + RD4(op)];
+ rr = KCONST8(op);
+ res = rd - rr;
+ m_r[16 + RD4(op)] = res;
+ SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3))));
+ SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7)));
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7))));
+ break;
+ case 0x6000: // ORI Rd,K
+ rd = m_r[16 + RD4(op)];
+ rr = KCONST8(op);
+ rd |= rr;
+ SREG_W(AVR8_SREG_V, 0);
+ SREG_W(AVR8_SREG_N, BIT(rd,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0);
+ m_r[16 + RD4(op)] = rd;
+ break;
+ case 0x7000: // ANDI Rd,K
+ rd = m_r[16 + RD4(op)];
+ rr = KCONST8(op);
+ rd &= rr;
+ SREG_W(AVR8_SREG_V, 0);
+ SREG_W(AVR8_SREG_N, BIT(rd,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0);
+ m_r[16 + RD4(op)] = rd;
+ break;
+ case 0x8000:
+ case 0xa000:
+ switch (op & 0x0208)
+ {
+ case 0x0000: // LDD Rd,Z+q
+ m_r[RD5(op)] = m_data->read_byte(ZREG + QCONST6(op));
+ opcycles = 2;
+ break;
+ case 0x0008: // LDD Rd,Y+q
+ m_r[RD5(op)] = m_data->read_byte(YREG + QCONST6(op));
+ opcycles = 2;
break;
- case 0x8000:
- case 0xa000:
- switch(op & 0x0208)
+ case 0x0200: // STD Z+q,Rr
+ m_data->write_byte(ZREG + QCONST6(op), m_r[RD5(op)]);
+ opcycles = 2;
+ break;
+ case 0x0208: // STD Y+q,Rr
+ m_data->write_byte(YREG + QCONST6(op), m_r[RD5(op)]);
+ opcycles = 2;
+ break;
+ }
+ break;
+ case 0x9000:
+ switch (op & 0x0f00)
+ {
+ case 0x0000:
+ case 0x0100:
+ switch (op & 0x000f)
{
- case 0x0000: // LDD Rd,Z+q
- m_r[RD5(op)] = m_data->read_byte(ZREG + QCONST6(op));
- opcycles = 2;
+ case 0x0000: // LDS Rd,k
+ op <<= 16;
+ m_pc++;
+ m_shifted_pc += 2;
+ op |= m_program->read_word(m_shifted_pc);
+ m_r[RD5(op >> 16)] = m_data->read_byte(op & 0x0000ffff);
+ opcycles = 2;
+ break;
+ case 0x0001: // LD Rd,Z+
+ pd = ZREG;
+ m_r[RD5(op)] = m_data->read_byte(pd);
+ pd++;
+ m_r[31] = (pd >> 8) & 0x00ff;
+ m_r[30] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x0002: // LD Rd,-Z
+ pd = ZREG;
+ pd--;
+ m_r[RD5(op)] = m_data->read_byte(pd);
+ m_r[31] = (pd >> 8) & 0x00ff;
+ m_r[30] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x0004: // LPM Rd,Z
+ m_r[RD5(op)] = m_program->read_byte(ZREG);
+ opcycles = 3;
+ break;
+ case 0x0005: // LPM Rd,Z+
+ pd = ZREG;
+ m_r[RD5(op)] = m_program->read_byte(pd);
+ pd++;
+ m_r[31] = (pd >> 8) & 0x00ff;
+ m_r[30] = pd & 0x00ff;
+ opcycles = 3;
+ break;
+ case 0x0006: // ELPM Rd,Z
+ m_r[RD5(op)] = m_program->read_byte((m_r[AVR8_REGIDX_RAMPZ] << 16) | ZREG);
+ opcycles = 3;
+ break;
+ case 0x0007: // ELPM Rd,Z+
+ pd32 = (m_r[AVR8_REGIDX_RAMPZ] << 16) | ZREG;
+ m_r[RD5(op)] = m_program->read_byte(pd32);
+ pd32++;
+ m_r[AVR8_REGIDX_RAMPZ] = (pd32 >> 16) & 0x00ff;
+ m_r[31] = (pd32 >> 8) & 0x00ff;
+ m_r[30] = pd32 & 0x00ff;
+ opcycles = 3;
+ break;
+ case 0x0009: // LD Rd,Y+
+ pd = YREG;
+ m_r[RD5(op)] = m_data->read_byte(pd);
+ pd++;
+ m_r[29] = (pd >> 8) & 0x00ff;
+ m_r[28] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x000a: // LD Rd,-Y
+ pd = YREG;
+ pd--;
+ m_r[RD5(op)] = m_data->read_byte(pd);
+ m_r[29] = (pd >> 8) & 0x00ff;
+ m_r[28] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x000c: // LD Rd,X
+ m_r[RD5(op)] = m_data->read_byte(XREG);
+ opcycles = 2;
+ break;
+ case 0x000d: // LD Rd,X+
+ pd = XREG;
+ m_r[RD5(op)] = m_data->read_byte(pd);
+ pd++;
+ m_r[27] = (pd >> 8) & 0x00ff;
+ m_r[26] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x000e: // LD Rd,-X
+ pd = XREG;
+ pd--;
+ m_r[RD5(op)] = m_data->read_byte(pd);
+ m_r[27] = (pd >> 8) & 0x00ff;
+ m_r[26] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x000f: // POP Rd
+ m_r[RD5(op)] = pop();
+ opcycles = 2;
+ break;
+ default:
+ unimplemented_opcode(op);
+ break;
+ }
+ break;
+ case 0x0200:
+ case 0x0300:
+ switch (op & 0x000f)
+ {
+ case 0x0000: // STS k,Rr
+ op <<= 16;
+ m_pc++;
+ m_shifted_pc += 2;
+ op |= m_program->read_word(m_shifted_pc);
+ m_data->write_byte(op & 0x0000ffff, m_r[RD5(op >> 16)]);
+ opcycles = 2;
+ break;
+ case 0x0001: // ST Z+,Rd
+ pd = ZREG;
+ m_data->write_byte(pd, m_r[RD5(op)]);
+ pd++;
+ m_r[31] = (pd >> 8) & 0x00ff;
+ m_r[30] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x0002: // ST -Z,Rd
+ pd = ZREG;
+ pd--;
+ m_data->write_byte(pd, m_r[RD5(op)]);
+ m_r[31] = (pd >> 8) & 0x00ff;
+ m_r[30] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x0009: // ST Y+,Rd
+ pd = YREG;
+ m_data->write_byte(pd, m_r[RD5(op)]);
+ pd++;
+ m_r[29] = (pd >> 8) & 0x00ff;
+ m_r[28] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x000a: // ST -Y,Rd
+ pd = YREG;
+ pd--;
+ m_data->write_byte(pd, m_r[RD5(op)]);
+ m_r[29] = (pd >> 8) & 0x00ff;
+ m_r[28] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x000c: // ST X,Rd
+ m_data->write_byte(XREG, m_r[RD5(op)]);
+ break;
+ case 0x000d: // ST X+,Rd
+ pd = XREG;
+ m_data->write_byte(pd, m_r[RD5(op)]);
+ pd++;
+ m_r[27] = (pd >> 8) & 0x00ff;
+ m_r[26] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x000e: // ST -X,Rd
+ pd = XREG;
+ pd--;
+ m_data->write_byte(pd, m_r[RD5(op)]);
+ m_r[27] = (pd >> 8) & 0x00ff;
+ m_r[26] = pd & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x000f: // PUSH Rd
+ push(m_r[RD5(op)]);
+ opcycles = 2;
+ break;
+ default:
+ unimplemented_opcode(op);
+ break;
+ }
+ break;
+ case 0x0400:
+ switch (op & 0x000f)
+ {
+ case 0x0000: // COM Rd
+ rd = m_r[RD5(op)];
+ res = ~rd;
+ SREG_W(AVR8_SREG_C, 1);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, 0);
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0001: // NEG Rd
+ rd = m_r[RD5(op)];
+ res = 0 - rd;
+ SREG_W(AVR8_SREG_C, (res == 0) ? 0 : 1);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, (res == 0x80) ? 1 : 0);
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_H, BIT(res,3) | BIT(rd,3));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0002: // SWAP Rd
+ rd = m_r[RD5(op)];
+ m_r[RD5(op)] = (rd >> 4) | (rd << 4);
+ break;
+ case 0x0003: // INC Rd
+ rd = m_r[RD5(op)];
+ res = rd + 1;
+ SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0005: // ASR Rd
+ rd = m_r[RD5(op)];
+ res = (rd & 0x80) | (rd >> 1);
+ SREG_W(AVR8_SREG_C, BIT(rd,0));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(rd,7));
+ SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0006: // LSR Rd
+ rd = m_r[RD5(op)];
+ res = rd >> 1;
+ SREG_W(AVR8_SREG_C, BIT(rd,0));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
+ SREG_W(AVR8_SREG_N, 0);
+ SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0007: // ROR Rd
+ rd = m_r[RD5(op)];
+ res = rd >> 1;
+ res |= (SREG_R(AVR8_SREG_C) << 7);
+ SREG_W(AVR8_SREG_C, BIT(rd,0));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0008:
+ switch (op & 0x00f0)
+ {
+ case 0x0000: // SEC
+ case 0x0010: // SEZ
+ case 0x0020: // SEN
+ case 0x0030: // SEV
+ case 0x0040: // SES
+ case 0x0050: // SEH
+ case 0x0060: // SET
+ case 0x0070: // SEI
+ SREG_W((op >> 4) & 0x07, 1);
break;
- case 0x0008: // LDD Rd,Y+q
- m_r[RD5(op)] = m_data->read_byte(YREG + QCONST6(op));
- opcycles = 2;
+ case 0x0080: // CLC
+ case 0x0090: // CLZ
+ case 0x00a0: // CLN
+ case 0x00b0: // CLV
+ case 0x00c0: // CLS
+ case 0x00d0: // CLH
+ case 0x00e0: // CLT
+ case 0x00f0: // CLI
+ SREG_W((op >> 4) & 0x07, 0);
break;
- case 0x0200: // STD Z+q,Rr
- m_data->write_byte(ZREG + QCONST6(op), m_r[RD5(op)]);
+ }
+ break;
+ case 0x0009:
+ switch (op & 0x00f0)
+ {
+ case 0x0000: // IJMP
+ m_pc = ZREG - 1;
opcycles = 2;
break;
- case 0x0208: // STD Y+q,Rr
- m_data->write_byte(YREG + QCONST6(op), m_r[RD5(op)]);
+ case 0x0010: // EIJMP
+ m_pc = (m_r[AVR8_REGIDX_EIND] << 16 | ZREG) - 1;
opcycles = 2;
break;
+ default:
+ unimplemented_opcode(op);
+ break;
+ }
+ break;
+ case 0x000a: // DEC Rd
+ rd = m_r[RD5(op)];
+ res = rd - 1;
+ SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ m_r[RD5(op)] = res;
+ break;
+ case 0x000c:
+ case 0x000d: // JMP k
+ offs = KCONST22(op) << 16;
+ m_pc++;
+ m_shifted_pc += 2;
+ offs |= m_program->read_word(m_shifted_pc);
+ m_pc = offs;
+ m_pc--;
+ opcycles = 3;
+ break;
+ case 0x000e: // CALL k
+ case 0x000f:
+ push((m_pc + 2) & 0x00ff);
+ push(((m_pc + 2) >> 8) & 0x00ff);
+ offs = KCONST22(op) << 16;
+ m_pc++;
+ m_shifted_pc += 2;
+ offs |= m_program->read_word(m_shifted_pc);
+ m_pc = offs;
+ m_pc--;
+ opcycles = 4;
+ break;
+ default:
+ unimplemented_opcode(op);
+ break;
}
break;
- case 0x9000:
- switch(op & 0x0f00)
+ case 0x0500:
+ switch (op & 0x000f)
{
- case 0x0000:
- case 0x0100:
- switch(op & 0x000f)
- {
- case 0x0000: // LDS Rd,k
- op <<= 16;
- m_pc++;
- m_shifted_pc += 2;
- op |= m_program->read_word(m_shifted_pc);
- m_r[RD5(op >> 16)] = m_data->read_byte(op & 0x0000ffff);
- opcycles = 2;
- break;
- case 0x0001: // LD Rd,Z+
- pd = ZREG;
- m_r[RD5(op)] = m_data->read_byte(pd);
- pd++;
- m_r[31] = (pd >> 8) & 0x00ff;
- m_r[30] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x0002: // LD Rd,-Z
- pd = ZREG;
- pd--;
- m_r[RD5(op)] = m_data->read_byte(pd);
- m_r[31] = (pd >> 8) & 0x00ff;
- m_r[30] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x0004: // LPM Rd,Z
- m_r[RD5(op)] = m_program->read_byte(ZREG);
- opcycles = 3;
- break;
- case 0x0005: // LPM Rd,Z+
- pd = ZREG;
- m_r[RD5(op)] = m_program->read_byte(pd);
- pd++;
- m_r[31] = (pd >> 8) & 0x00ff;
- m_r[30] = pd & 0x00ff;
- opcycles = 3;
- break;
- case 0x0006: // ELPM Rd,Z
- m_r[RD5(op)] = m_program->read_byte((m_r[AVR8_REGIDX_RAMPZ] << 16) | ZREG);
- opcycles = 3;
- break;
- case 0x0007: // ELPM Rd,Z+
- pd32 = (m_r[AVR8_REGIDX_RAMPZ] << 16) | ZREG;
- m_r[RD5(op)] = m_program->read_byte(pd32);
- pd32++;
- m_r[AVR8_REGIDX_RAMPZ] = (pd32 >> 16) & 0x00ff;
- m_r[31] = (pd32 >> 8) & 0x00ff;
- m_r[30] = pd32 & 0x00ff;
- opcycles = 3;
- break;
- case 0x0009: // LD Rd,Y+
- pd = YREG;
- m_r[RD5(op)] = m_data->read_byte(pd);
- pd++;
- m_r[29] = (pd >> 8) & 0x00ff;
- m_r[28] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x000a: // LD Rd,-Y
- pd = YREG;
- pd--;
- m_r[RD5(op)] = m_data->read_byte(pd);
- m_r[29] = (pd >> 8) & 0x00ff;
- m_r[28] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x000c: // LD Rd,X
- m_r[RD5(op)] = m_data->read_byte(XREG);
- opcycles = 2;
- break;
- case 0x000d: // LD Rd,X+
- pd = XREG;
- m_r[RD5(op)] = m_data->read_byte(pd);
- pd++;
- m_r[27] = (pd >> 8) & 0x00ff;
- m_r[26] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x000e: // LD Rd,-X
- pd = XREG;
- pd--;
- m_r[RD5(op)] = m_data->read_byte(pd);
- m_r[27] = (pd >> 8) & 0x00ff;
- m_r[26] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x000f: // POP Rd
- m_r[RD5(op)] = pop();
- opcycles = 2;
- break;
- default:
- unimplemented_opcode(op);
- //output += sprintf( output, "Undefined (%04x)", op );
- break;
- }
+ case 0x0000: // COM Rd
+ rd = m_r[RD5(op)];
+ res = ~rd;
+ SREG_W(AVR8_SREG_C, 1);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, 0);
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0001: // NEG Rd
+ rd = m_r[RD5(op)];
+ res = 0 - rd;
+ SREG_W(AVR8_SREG_C, (res == 0) ? 0 : 1);
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, (res == 0x80) ? 1 : 0);
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_H, BIT(res,3) | BIT(rd,3));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0002: // SWAP Rd
+ rd = m_r[RD5(op)];
+ m_r[RD5(op)] = (rd >> 4) | (rd << 4);
+ break;
+ case 0x0003: // INC Rd
+ rd = m_r[RD5(op)];
+ res = rd + 1;
+ SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0005: // ASR Rd
+ rd = m_r[RD5(op)];
+ res = (rd & 0x80) | (rd >> 1);
+ SREG_W(AVR8_SREG_C, BIT(rd,0));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(rd,7));
+ SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0006: // LSR Rd
+ rd = m_r[RD5(op)];
+ res = rd >> 1;
+ SREG_W(AVR8_SREG_C, BIT(rd,0));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
+ SREG_W(AVR8_SREG_N, 0);
+ SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0007: // ROR Rd
+ rd = m_r[RD5(op)];
+ res = rd >> 1;
+ res |= (SREG_R(AVR8_SREG_C) << 7);
+ SREG_W(AVR8_SREG_C, BIT(rd,0));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ m_r[RD5(op)] = res;
+ break;
+ case 0x0008:
+ switch (op & 0x00f0)
+ {
+ case 0x0000: // RET
+ m_pc = pop() << 8;
+ m_pc |= pop();
+ m_pc--;
+ opcycles = 4;
break;
- case 0x0200:
- case 0x0300:
- switch(op & 0x000f)
- {
- case 0x0000: // STS k,Rr
- op <<= 16;
- m_pc++;
- m_shifted_pc += 2;
- op |= m_program->read_word(m_shifted_pc);
- m_data->write_byte(op & 0x0000ffff, m_r[RD5(op >> 16)]);
- opcycles = 2;
- break;
- case 0x0001: // ST Z+,Rd
- pd = ZREG;
- m_data->write_byte(pd, m_r[RD5(op)]);
- pd++;
- m_r[31] = (pd >> 8) & 0x00ff;
- m_r[30] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x0002: // ST -Z,Rd
- pd = ZREG;
- pd--;
- m_data->write_byte(pd, m_r[RD5(op)]);
- m_r[31] = (pd >> 8) & 0x00ff;
- m_r[30] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x0009: // ST Y+,Rd
- pd = YREG;
- m_data->write_byte(pd, m_r[RD5(op)]);
- pd++;
- m_r[29] = (pd >> 8) & 0x00ff;
- m_r[28] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x000a: // ST -Y,Rd
- pd = YREG;
- pd--;
- m_data->write_byte(pd, m_r[RD5(op)]);
- m_r[29] = (pd >> 8) & 0x00ff;
- m_r[28] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x000c: // ST X,Rd
- m_data->write_byte(XREG, m_r[RD5(op)]);
- break;
- case 0x000d: // ST X+,Rd
- pd = XREG;
- m_data->write_byte(pd, m_r[RD5(op)]);
- pd++;
- m_r[27] = (pd >> 8) & 0x00ff;
- m_r[26] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x000e: // ST -X,Rd
- pd = XREG;
- pd--;
- m_data->write_byte(pd, m_r[RD5(op)]);
- m_r[27] = (pd >> 8) & 0x00ff;
- m_r[26] = pd & 0x00ff;
- opcycles = 2;
- break;
- case 0x000f: // PUSH Rd
- push(m_r[RD5(op)]);
- opcycles = 2;
- break;
- default:
- unimplemented_opcode(op);
- //output += sprintf( output, "Undefined (%04x)", op );
- break;
- }
+ case 0x0010: // RETI
+ m_pc = pop() << 8;
+ m_pc |= pop();
+ m_pc--;
+ SREG_W(AVR8_SREG_I, 1);
+ opcycles = 4;
break;
- case 0x0400:
- switch(op & 0x000f)
- {
- case 0x0000: // COM Rd
- rd = m_r[RD5(op)];
- res = ~rd;
- SREG_W(AVR8_SREG_C, 1);
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_V, 0);
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- m_r[RD5(op)] = res;
- break;
- case 0x0001: // NEG Rd
- rd = m_r[RD5(op)];
- res = 0 - rd;
- SREG_W(AVR8_SREG_C, (res == 0) ? 0 : 1);
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_V, (res == 0x80) ? 1 : 0);
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_H, BIT(res,3) | BIT(rd,3));
- m_r[RD5(op)] = res;
- break;
- case 0x0002: // SWAP Rd
- rd = m_r[RD5(op)];
- m_r[RD5(op)] = (rd >> 4) | (rd << 4);
- break;
- case 0x0003: // INC Rd
- rd = m_r[RD5(op)];
- res = rd + 1;
- SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- m_r[RD5(op)] = res;
- break;
- case 0x0005: // ASR Rd
- rd = m_r[RD5(op)];
- res = (rd & 0x80) | (rd >> 1);
- SREG_W(AVR8_SREG_C, BIT(rd,0));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(rd,7));
- SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- m_r[RD5(op)] = res;
- break;
- case 0x0006: // LSR Rd
- rd = m_r[RD5(op)];
- res = rd >> 1;
- SREG_W(AVR8_SREG_C, BIT(rd,0));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
- SREG_W(AVR8_SREG_N, 0);
- SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- m_r[RD5(op)] = res;
- break;
- case 0x0007: // ROR Rd
- rd = m_r[RD5(op)];
- res = rd >> 1;
- res |= (SREG_R(AVR8_SREG_C) << 7);
- SREG_W(AVR8_SREG_C, BIT(rd,0));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- m_r[RD5(op)] = res;
- break;
- case 0x0008:
- switch(op & 0x00f0)
- {
- case 0x0000: // SEC
- case 0x0010: // SEZ
- case 0x0020: // SEN
- case 0x0030: // SEV
- case 0x0040: // SES
- case 0x0050: // SEH
- case 0x0060: // SET
- case 0x0070: // SEI
- SREG_W((op >> 4) & 0x07, 1);
- break;
- case 0x0080: // CLC
- case 0x0090: // CLZ
- case 0x00a0: // CLN
- case 0x00b0: // CLV
- case 0x00c0: // CLS
- case 0x00d0: // CLH
- case 0x00e0: // CLT
- case 0x00f0: // CLI
- SREG_W((op >> 4) & 0x07, 0);
- break;
- }
- break;
- case 0x0009:
- switch(op & 0x00f0)
- {
- case 0x0000: // IJMP
- m_pc = ZREG - 1;
- opcycles = 2;
- break;
- case 0x0010: // EIJMP
- m_pc = (m_r[AVR8_REGIDX_EIND] << 16 | ZREG) - 1;
- opcycles = 2;
- break;
- default:
- //output += sprintf( output, "Undefined (%04x)", op );
- unimplemented_opcode(op);
- break;
- }
- break;
- case 0x000a: // DEC Rd
- rd = m_r[RD5(op)];
- res = rd - 1;
- SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- m_r[RD5(op)] = res;
- break;
- case 0x000c:
- case 0x000d: // JMP k
- offs = KCONST22(op) << 16;
- m_pc++;
- m_shifted_pc += 2;
- offs |= m_program->read_word(m_shifted_pc);
- m_pc = offs;
- m_pc--;
- opcycles = 3;
- break;
- case 0x000e: // CALL k
- case 0x000f:
- push((m_pc + 2) & 0x00ff);
- push(((m_pc + 2) >> 8) & 0x00ff);
- offs = KCONST22(op) << 16;
- m_pc++;
- m_shifted_pc += 2;
- offs |= m_program->read_word(m_shifted_pc);
- m_pc = offs;
- m_pc--;
- opcycles = 4;
- break;
- default:
- unimplemented_opcode(op);
- //output += sprintf( output, "Undefined (%04x)", op );
- break;
- }
+ case 0x0080: // SLEEP
+ m_pc--;
+ opcycles = 1;
+ //unimplemented_opcode(op);
break;
- case 0x0500:
- switch(op & 0x000f)
- {
- case 0x0000: // COM Rd
- rd = m_r[RD5(op)];
- res = ~rd;
- SREG_W(AVR8_SREG_C, 1);
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_V, 0);
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- m_r[RD5(op)] = res;
- break;
- case 0x0001: // NEG Rd
- rd = m_r[RD5(op)];
- res = 0 - rd;
- SREG_W(AVR8_SREG_C, (res == 0) ? 0 : 1);
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_V, (res == 0x80) ? 1 : 0);
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_H, BIT(res,3) | BIT(rd,3));
- m_r[RD5(op)] = res;
- break;
- case 0x0002: // SWAP Rd
- rd = m_r[RD5(op)];
- m_r[RD5(op)] = (rd >> 4) | (rd << 4);
- break;
- case 0x0003: // INC Rd
- rd = m_r[RD5(op)];
- res = rd + 1;
- SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- m_r[RD5(op)] = res;
- break;
- case 0x0005: // ASR Rd
- rd = m_r[RD5(op)];
- res = (rd & 0x80) | (rd >> 1);
- SREG_W(AVR8_SREG_C, BIT(rd,0));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(rd,7));
- SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- m_r[RD5(op)] = res;
- break;
- case 0x0006: // LSR Rd
- rd = m_r[RD5(op)];
- res = rd >> 1;
- SREG_W(AVR8_SREG_C, BIT(rd,0));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
- SREG_W(AVR8_SREG_N, 0);
- SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- m_r[RD5(op)] = res;
- break;
- case 0x0007: // ROR Rd
- rd = m_r[RD5(op)];
- res = rd >> 1;
- res |= (SREG_R(AVR8_SREG_C) << 7);
- SREG_W(AVR8_SREG_C, BIT(rd,0));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 :0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- m_r[RD5(op)] = res;
- break;
- case 0x0008:
- switch(op & 0x00f0)
- {
- case 0x0000: // RET
- m_pc = pop() << 8;
- m_pc |= pop();
- m_pc--;
- opcycles = 4;
- break;
- case 0x0010: // RETI
- m_pc = pop() << 8;
- m_pc |= pop();
- m_pc--;
- SREG_W(AVR8_SREG_I, 1);
- opcycles = 4;
- break;
- case 0x0080: // SLEEP
- //output += sprintf( output, "SLEEP" );
- m_pc--;
- opcycles = 1;
- //unimplemented_opcode(op);
- break;
- case 0x0090: // BREAK
- //output += sprintf( output, "BREAK" );
- unimplemented_opcode(op);
- break;
- case 0x00a0: // WDR
- //output += sprintf( output, "WDR" );
- //unimplemented_opcode(op); //TODO: necessary for emulating the Replicator 1
- //printf("Watchdot Reset!\n");
- opcycles = 1;
- break;
- case 0x00c0: // LPM
- m_r[0] = m_program->read_byte(ZREG);
- opcycles = 3;
- break;
- case 0x00d0: // ELPM
- //output += sprintf( output, "ELPM" );
- unimplemented_opcode(op);
- break;
- case 0x00e0: // SPM
- //output += sprintf( output, "SPM" );
- unimplemented_opcode(op);
- break;
- case 0x00f0: // SPM Z+
- //output += sprintf( output, "SPM Z+" );
- unimplemented_opcode(op);
- break;
- default:
- unimplemented_opcode(op);
- //output += sprintf( output, "Undefined (%04x)", op );
- break;
- }
- break;
- case 0x0009:
- switch(op & 0x00f0)
- {
- case 0x0000: // ICALL
- push((m_pc + 1) & 0x00ff);
- push(((m_pc + 1) >> 8) & 0x00ff);
- m_pc = ZREG;
- m_pc--;
- opcycles = 3;
- break;
- case 0x0010: // EICALL
- //output += sprintf( output, "EICALL" );
- unimplemented_opcode(op);
- break;
- default:
- unimplemented_opcode(op);
- //output += sprintf( output, "Undefined (%04x)", op );
- break;
- }
- break;
- case 0x000a: // DEC Rd
- rd = m_r[RD5(op)];
- res = rd - 1;
- SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
- SREG_W(AVR8_SREG_N, BIT(res,7));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
- m_r[RD5(op)] = res;
- break;
- case 0x000c:
- case 0x000d: // JMP k
- //op <<= 8;
- //op |= oprom[pos++];
- //op <<= 8;
- //op |= oprom[pos++];
- //output += sprintf( output, "JMP 0x%06x", KCONST22(op) );
- unimplemented_opcode(op);
- break;
- case 0x000e:
- case 0x000f: // CALL k
- //op <<= 8;
- //op |= oprom[pos++];
- //op <<= 8;
- //op |= oprom[pos++];
- //output += sprintf( output, "CALL 0x%06x", KCONST22(op) );
- unimplemented_opcode(op);
- break;
- }
+ case 0x0090: // BREAK
+ unimplemented_opcode(op);
break;
- case 0x0600: // ADIW Rd+1:Rd,K
- rd = m_r[24 + (DCONST(op) << 1)];
- rr = m_r[25 + (DCONST(op) << 1)];
- pd = rd;
- pd |= rr << 8;
- pd += KCONST6(op);
- SREG_W(AVR8_SREG_V, BIT(pd,15) & NOT(BIT(rr,7)));
- SREG_W(AVR8_SREG_N, BIT(pd,15));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (pd == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_C, NOT(BIT(pd,15)) & BIT(rr,7));
- m_r[24 + (DCONST(op) << 1)] = pd & 0x00ff;
- m_r[25 + (DCONST(op) << 1)] = (pd >> 8) & 0x00ff;
- opcycles = 2;
+ case 0x00a0: // WDR
+ LOGMASKED(LOG_WDOG, "%s: Watchdog reset opcode\n", machine().describe_context());
+ opcycles = 1;
break;
- case 0x0700: // SBIW Rd+1:Rd,K
- rd = m_r[24 + (DCONST(op) << 1)];
- rr = m_r[25 + (DCONST(op) << 1)];
- pd = rd;
- pd |= rr << 8;
- pd -= KCONST6(op);
- SREG_W(AVR8_SREG_V, NOT(BIT(pd,15)) & BIT(rr,7));
- SREG_W(AVR8_SREG_N, BIT(pd,15));
- SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
- SREG_W(AVR8_SREG_Z, (pd == 0) ? 1 : 0);
- SREG_W(AVR8_SREG_C, BIT(pd,15) & NOT(BIT(rr,7)));
- m_r[24 + (DCONST(op) << 1)] = pd & 0x00ff;
- m_r[25 + (DCONST(op) << 1)] = (pd >> 8) & 0x00ff;
- opcycles = 2;
+ case 0x00c0: // LPM
+ m_r[0] = m_program->read_byte(ZREG);
+ opcycles = 3;
break;
- case 0x0800: // CBI A,b
- //output += sprintf( output, "CBI 0x%02x, %d", ACONST5(op), RR3(op) );
- m_data->write_byte(32 + ACONST5(op), m_data->read_byte(32 + ACONST5(op)) &~ (1 << RR3(op)));
- opcycles = 2;
+ case 0x00d0: // ELPM
+ unimplemented_opcode(op);
break;
- case 0x0900: // SBIC A,b
- if(NOT(BIT(m_data->read_byte(32 + ACONST5(op)), RR3(op))))
- {
- op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
- opcycles = is_long_opcode(op) ? 3 : 2;
- m_pc += is_long_opcode(op) ? 2 : 1;
- }
+ case 0x00e0: // SPM
+ unimplemented_opcode(op);
break;
- case 0x0a00: // SBI A,b
- m_data->write_byte(32 + ACONST5(op), m_data->read_byte(32 + ACONST5(op)) | (1 << RR3(op)));
- opcycles = 2;
+ case 0x00f0: // SPM Z+
+ unimplemented_opcode(op);
break;
- case 0x0b00: // SBIS A,b
- if(BIT(m_data->read_byte(32 + ACONST5(op)), RR3(op)))
- {
- op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
- opcycles = is_long_opcode(op) ? 3 : 2;
- m_pc += is_long_opcode(op) ? 2 : 1;
- }
+ default:
+ unimplemented_opcode(op);
break;
- case 0x0c00:
- case 0x0d00:
- case 0x0e00:
- case 0x0f00: // MUL Rd,Rr
- sd = (uint8_t)m_r[RD5(op)] * (uint8_t)m_r[RR5(op)];
- m_r[1] = (sd >> 8) & 0x00ff;
- m_r[0] = sd & 0x00ff;
- SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
- SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
- opcycles = 2;
+ }
+ break;
+ case 0x0009:
+ switch (op & 0x00f0)
+ {
+ case 0x0000: // ICALL
+ push((m_pc + 1) & 0x00ff);
+ push(((m_pc + 1) >> 8) & 0x00ff);
+ m_pc = ZREG;
+ m_pc--;
+ opcycles = 3;
+ break;
+ case 0x0010: // EICALL
+ unimplemented_opcode(op);
break;
+ default:
+ unimplemented_opcode(op);
+ break;
+ }
+ break;
+ case 0x000a: // DEC Rd
+ rd = m_r[RD5(op)];
+ res = rd - 1;
+ SREG_W(AVR8_SREG_V, (rd == 0x7f) ? 1 : 0);
+ SREG_W(AVR8_SREG_N, BIT(res,7));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0);
+ m_r[RD5(op)] = res;
+ break;
+ case 0x000c:
+ case 0x000d: // JMP k
+ //op <<= 8;
+ //op |= oprom[pos++];
+ //op <<= 8;
+ //op |= oprom[pos++];
+ unimplemented_opcode(op);
+ break;
+ case 0x000e:
+ case 0x000f: // CALL k
+ //op <<= 8;
+ //op |= oprom[pos++];
+ //op <<= 8;
+ //op |= oprom[pos++];
+ unimplemented_opcode(op);
+ break;
}
break;
- case 0xb000:
- if(op & 0x0800) // OUT A,Rr
+ case 0x0600: // ADIW Rd+1:Rd,K
+ rd = m_r[24 + (DCONST(op) << 1)];
+ rr = m_r[25 + (DCONST(op) << 1)];
+ pd = rd;
+ pd |= rr << 8;
+ pd += KCONST6(op);
+ SREG_W(AVR8_SREG_V, BIT(pd,15) & NOT(BIT(rr,7)));
+ SREG_W(AVR8_SREG_N, BIT(pd,15));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (pd == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, NOT(BIT(pd,15)) & BIT(rr,7));
+ m_r[24 + (DCONST(op) << 1)] = pd & 0x00ff;
+ m_r[25 + (DCONST(op) << 1)] = (pd >> 8) & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x0700: // SBIW Rd+1:Rd,K
+ rd = m_r[24 + (DCONST(op) << 1)];
+ rr = m_r[25 + (DCONST(op) << 1)];
+ pd = rd;
+ pd |= rr << 8;
+ pd -= KCONST6(op);
+ SREG_W(AVR8_SREG_V, NOT(BIT(pd,15)) & BIT(rr,7));
+ SREG_W(AVR8_SREG_N, BIT(pd,15));
+ SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
+ SREG_W(AVR8_SREG_Z, (pd == 0) ? 1 : 0);
+ SREG_W(AVR8_SREG_C, BIT(pd,15) & NOT(BIT(rr,7)));
+ m_r[24 + (DCONST(op) << 1)] = pd & 0x00ff;
+ m_r[25 + (DCONST(op) << 1)] = (pd >> 8) & 0x00ff;
+ opcycles = 2;
+ break;
+ case 0x0800: // CBI A,b
+ m_data->write_byte(32 + ACONST5(op), m_data->read_byte(32 + ACONST5(op)) &~ (1 << RR3(op)));
+ opcycles = 2;
+ break;
+ case 0x0900: // SBIC A,b
+ if (!BIT(m_data->read_byte(32 + ACONST5(op)), RR3(op)))
{
- m_data->write_byte(32 + ACONST6(op), m_r[RD5(op)]);
+ op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
+ opcycles = is_long_opcode(op) ? 3 : 2;
+ m_pc += is_long_opcode(op) ? 2 : 1;
}
- else // IN Rd,A
+ break;
+ case 0x0a00: // SBI A,b
+ m_data->write_byte(32 + ACONST5(op), m_data->read_byte(32 + ACONST5(op)) | (1 << RR3(op)));
+ opcycles = 2;
+ break;
+ case 0x0b00: // SBIS A,b
+ if (BIT(m_data->read_byte(32 + ACONST5(op)), RR3(op)))
{
- m_r[RD5(op)] = m_data->read_byte(0x20 + ACONST6(op));
+ op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
+ opcycles = is_long_opcode(op) ? 3 : 2;
+ m_pc += is_long_opcode(op) ? 2 : 1;
}
break;
- case 0xc000: // RJMP k
- offs = (int32_t)((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff));
- m_pc += offs;
+ case 0x0c00:
+ case 0x0d00:
+ case 0x0e00:
+ case 0x0f00: // MUL Rd,Rr
+ sd = (uint8_t)m_r[RD5(op)] * (uint8_t)m_r[RR5(op)];
+ m_r[1] = (sd >> 8) & 0x00ff;
+ m_r[0] = sd & 0x00ff;
+ SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
+ SREG_W(AVR8_SREG_Z, (sd == 0) ? 1 : 0);
opcycles = 2;
break;
- case 0xd000: // RCALL k
- offs = (int32_t)((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff));
- push((m_pc + 1) & 0x00ff);
- push(((m_pc + 1) >> 8) & 0x00ff);
- m_pc += offs;
- opcycles = 3;
+ }
+ break;
+ case 0xb000:
+ if (op & 0x0800) // OUT A,Rr
+ {
+ m_data->write_byte(32 + ACONST6(op), m_r[RD5(op)]);
+ }
+ else // IN Rd,A
+ {
+ m_r[RD5(op)] = m_data->read_byte(0x20 + ACONST6(op));
+ }
+ break;
+ case 0xc000: // RJMP k
+ offs = (int32_t)((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff));
+ m_pc += offs;
+ opcycles = 2;
+ break;
+ case 0xd000: // RCALL k
+ offs = (int32_t)((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff));
+ push((m_pc + 1) & 0x00ff);
+ push(((m_pc + 1) >> 8) & 0x00ff);
+ m_pc += offs;
+ opcycles = 3;
+ break;
+ case 0xe000: // LDI Rd,K
+ m_r[16 + RD4(op)] = KCONST8(op);
+ break;
+ case 0xf000:
+ switch (op & 0x0c00)
+ {
+ case 0x0000: // BRLO through BRIE
+ if (SREG_R(op & 0x0007))
+ {
+ offs = (int32_t)(KCONST7(op));
+ if (offs & 0x40)
+ {
+ offs |= 0xffffff80;
+ }
+ m_pc += offs;
+ opcycles = 2;
+ }
+ break;
+ case 0x0400: // BRSH through BRID
+ if (SREG_R(op & 0x0007) == 0)
+ {
+ offs = (int32_t)(KCONST7(op));
+ if (offs & 0x40)
+ {
+ offs |= 0xffffff80;
+ }
+ m_pc += offs;
+ opcycles = 2;
+ }
break;
- case 0xe000: // LDI Rd,K
- m_r[16 + RD4(op)] = KCONST8(op);
+ case 0x0800:
+ if (op & 0x0200) // BST Rd, b
+ {
+ SREG_W(AVR8_SREG_T, (BIT(m_r[RD5(op)], RR3(op))) ? 1 : 0);
+ }
+ else // BLD Rd, b
+ {
+ if (SREG_R(AVR8_SREG_T))
+ {
+ m_r[RD5(op)] |= (1 << RR3(op));
+ }
+ else
+ {
+ m_r[RD5(op)] &= ~(1 << RR3(op));
+ }
+ }
break;
- case 0xf000:
- switch(op & 0x0c00)
+ case 0x0c00:
+ if (op & 0x0200) // SBRS Rd, b
{
- case 0x0000: // BRLO through BRIE
- if(SREG_R(op & 0x0007))
- {
- offs = (int32_t)(KCONST7(op));
- if(offs & 0x40)
- {
- offs |= 0xffffff80;
- }
- m_pc += offs;
- opcycles = 2;
- }
- break;
- case 0x0400: // BRSH through BRID
- if(SREG_R(op & 0x0007) == 0)
- {
- offs = (int32_t)(KCONST7(op));
- if(offs & 0x40)
- {
- offs |= 0xffffff80;
- }
- m_pc += offs;
- opcycles = 2;
- }
- break;
- case 0x0800:
- if(op & 0x0200) // BST Rd, b
- {
- SREG_W(AVR8_SREG_T, (BIT(m_r[RD5(op)], RR3(op))) ? 1 : 0);
- }
- else // BLD Rd, b
- {
- if(SREG_R(AVR8_SREG_T))
- {
- m_r[RD5(op)] |= (1 << RR3(op));
- }
- else
- {
- m_r[RD5(op)] &= ~(1 << RR3(op));
- }
- }
- break;
- case 0x0c00:
- if(op & 0x0200) // SBRS Rd, b
- {
- if(BIT(m_r[RD5(op)], RR3(op)))
- {
- op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
- m_pc += is_long_opcode(op) ? 2 : 1;
- opcycles = is_long_opcode(op) ? 3 : 2;
- }
- }
- else // SBRC Rd, b
- {
- if(NOT(BIT(m_r[RD5(op)], RR3(op))))
- {
- op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
- m_pc += is_long_opcode(op) ? 2 : 1;
- opcycles = is_long_opcode(op) ? 3 : 2;
- }
- }
- break;
+ if (BIT(m_r[RD5(op)], RR3(op)))
+ {
+ op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
+ m_pc += is_long_opcode(op) ? 2 : 1;
+ opcycles = is_long_opcode(op) ? 3 : 2;
+ }
+ }
+ else // SBRC Rd, b
+ {
+ if (!BIT(m_r[RD5(op)], RR3(op)))
+ {
+ op = (uint32_t)m_program->read_word(m_shifted_pc + 2);
+ m_pc += is_long_opcode(op) ? 2 : 1;
+ opcycles = is_long_opcode(op) ? 3 : 2;
+ }
}
break;
+ }
+ break;
}
m_pc++;