summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/avr8/avr8.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/avr8/avr8.c')
-rw-r--r--src/emu/cpu/avr8/avr8.c2806
1 files changed, 1403 insertions, 1403 deletions
diff --git a/src/emu/cpu/avr8/avr8.c b/src/emu/cpu/avr8/avr8.c
index 10aefec61aa..9a271fcab55 100644
--- a/src/emu/cpu/avr8/avr8.c
+++ b/src/emu/cpu/avr8/avr8.c
@@ -39,7 +39,7 @@
#include "debugger.h"
#include "avr8.h"
-#define VERBOSE_LEVEL (0)
+#define VERBOSE_LEVEL (0)
#define ENABLE_VERBOSE_LOG (0)
@@ -66,14 +66,14 @@ INLINE void verboselog(UINT16 pc, int n_level, const char *s_fmt, ...)
enum
{
- AVR8_SREG_C = 0,
- AVR8_SREG_Z,
- AVR8_SREG_N,
- AVR8_SREG_V,
- AVR8_SREG_S,
- AVR8_SREG_H,
- AVR8_SREG_T,
- AVR8_SREG_I,
+ AVR8_SREG_C = 0,
+ AVR8_SREG_Z,
+ AVR8_SREG_N,
+ AVR8_SREG_V,
+ AVR8_SREG_S,
+ AVR8_SREG_H,
+ AVR8_SREG_T,
+ AVR8_SREG_I,
};
// I/O Enums
@@ -131,181 +131,181 @@ static const char avr8_reg_name[4] = { 'A', 'B', 'C', 'D' };
#define QCONST6(op) ((((op) >> 8) & 0x0020) | (((op) >> 7) & 0x0018) | ((op) & 0x0007))
#define ACONST5(op) (((op) >> 3) & 0x001f)
#define ACONST6(op) ((((op) >> 5) & 0x0030) | ((op) & 0x000f))
-#define MULCONST2(op) ((((op) >> 6) & 0x0002) | (((op) >> 3) & 0x0001))
+#define MULCONST2(op) ((((op) >> 6) & 0x0002) | (((op) >> 3) & 0x0001))
// Register Defines
#define XREG ((m_r[27] << 8) | m_r[26])
#define YREG ((m_r[29] << 8) | m_r[28])
#define ZREG ((m_r[31] << 8) | m_r[30])
-#define SPREG ((m_r[AVR8_REGIDX_SPH] << 8) | m_r[AVR8_REGIDX_SPL])
+#define SPREG ((m_r[AVR8_REGIDX_SPH] << 8) | m_r[AVR8_REGIDX_SPL])
// I/O Defines
-#define AVR8_OCR1BH (m_r[AVR8_REGIDX_OCR1BH])
-#define AVR8_OCR1BL (m_r[AVR8_REGIDX_OCR1BL])
-#define AVR8_OCR1AH (m_r[AVR8_REGIDX_OCR1AH])
-#define AVR8_OCR1AL (m_r[AVR8_REGIDX_OCR1AL])
-#define AVR8_ICR1H (m_r[AVR8_REGIDX_ICR1H])
-#define AVR8_ICR1L (m_r[AVR8_REGIDX_ICR1L])
-#define AVR8_TCNT1H (m_r[AVR8_REGIDX_TCNT1H])
-#define AVR8_TCNT1L (m_r[AVR8_REGIDX_TCNT1L])
-
-#define AVR8_TCCR0B (m_r[AVR8_REGIDX_TCCR0B])
-#define AVR8_TCCR0B_FOC0A_MASK 0x80
-#define AVR8_TCCR0B_FOC0A_SHIFT 7
-#define AVR8_TCCR0B_FOC0B_MASK 0x40
-#define AVR8_TCCR0B_FOC0B_SHIFT 6
-#define AVR8_TCCR0B_WGM0_2_MASK 0x08
-#define AVR8_TCCR0B_WGM0_2_SHIFT 3
-#define AVR8_TCCR0B_CS_MASK 0x07
-#define AVR8_TCCR0B_CS_SHIFT 0
-#define AVR8_TIMER0_CLOCK_SELECT (AVR8_TCCR0B & AVR8_TCCR0B_CS_MASK)
-
-#define AVR8_TCCR0A (m_r[AVR8_REGIDX_TCCR0A])
-#define AVR8_TCCR0A_COM0A_MASK 0xc0
-#define AVR8_TCCR0A_COM0A_SHIFT 6
-#define AVR8_TCCR0A_COM0B_MASK 0x30
-#define AVR8_TCCR0A_COM0B_SHIFT 4
-#define AVR8_TCCR0A_WGM0_10_MASK 0x03
-#define AVR8_TCCR0A_WGM0_10_SHIFT 0
-#define AVR8_TCCR0A_COM0A ((AVR8_TCCR0A & AVR8_TCCR0A_COM0A_MASK) >> AVR8_TCCR0A_COM0A_SHIFT)
-#define AVR8_TCCR0A_COM0B ((AVR8_TCCR0A & AVR8_TCCR0A_COM0B_MASK) >> AVR8_TCCR0A_COM0B_SHIFT)
-#define AVR8_TCCR0A_WGM0_10 (AVR8_TCCR0A & AVR8_TCCR0A_WGM0_10_MASK)
-
-#define AVR8_TIMSK0 (m_r[AVR8_REGIDX_TIMSK0])
-#define AVR8_TIMSK0_OCIE0B_MASK 0x04
-#define AVR8_TIMSK0_OCIE0A_MASK 0x02
-#define AVR8_TIMSK0_TOIE0_MASK 0x01
-#define AVR8_TIMSK0_OCIE0B ((AVR8_TIMSK0 & AVR8_TIMSK0_OCIE0B_MASK) >> 2)
-#define AVR8_TIMSK0_OCIE0A ((AVR8_TIMSK0 & AVR8_TIMSK0_OCIE0A_MASK) >> 1)
-#define AVR8_TIMSK0_TOIE0 (AVR8_TIMSK0 & AVR8_TIMSK0_TOIE0_MASK)
-
-#define AVR8_TIFR0 (m_r[AVR8_REGIDX_TIFR0])
-#define AVR8_TIFR0_OCF0B_MASK 0x04
-#define AVR8_TIFR0_OCF0B_SHIFT 2
-#define AVR8_TIFR0_OCF0A_MASK 0x02
-#define AVR8_TIFR0_OCF0A_SHIFT 1
-#define AVR8_TIFR0_TOV0_MASK 0x01
-#define AVR8_TIFR0_TOV0_SHIFT 0
-#define AVR8_TIFR0_MASK (AVR8_TIFR0_TOV0_MASK | AVR8_TIFR0_OCF0B_MASK | AVR8_TIFR0_OCF0A_MASK)
-
-#define AVR8_TCCR1B (m_r[AVR8_REGIDX_TCCR1B])
-#define AVR8_TCCR1B_ICNC1_MASK 0x80
-#define AVR8_TCCR1B_ICNC1_SHIFT 7
-#define AVR8_TCCR1B_ICES1_MASK 0x40
-#define AVR8_TCCR1B_ICES1_SHIFT 6
-#define AVR8_TCCR1B_WGM1_32_MASK 0x18
-#define AVR8_TCCR1B_WGM1_32_SHIFT 3
-#define AVR8_TCCR1B_CS_MASK 0x07
-#define AVR8_TCCR1B_CS_SHIFT 0
-#define AVR8_TIMER1_CLOCK_SELECT (AVR8_TCCR1B & AVR8_TCCR1B_CS_MASK)
-
-#define AVR8_TCCR1A (m_r[AVR8_REGIDX_TCCR1A])
-#define AVR8_TCCR1A_COM1A_MASK 0xc0
-#define AVR8_TCCR1A_COM1A_SHIFT 6
-#define AVR8_TCCR1A_COM1B_MASK 0x30
-#define AVR8_TCCR1A_COM1B_SHIFT 4
-#define AVR8_TCCR1A_WGM1_10_MASK 0x03
-#define AVR8_TCCR1A_WGM1_10_SHIFT 0
-#define AVR8_TCCR1A_COM1A ((AVR8_TCCR1A & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT)
-#define AVR8_TCCR1A_COM1B ((AVR8_TCCR1A & AVR8_TCCR1A_COM1B_MASK) >> AVR8_TCCR1A_COM1B_SHIFT)
-#define AVR8_TCCR1A_WGM1_10 (AVR8_TCCR1A & AVR8_TCCR1A_WGM1_10_MASK)
-
-#define AVR8_TIMSK1 (m_r[AVR8_REGIDX_TIMSK1])
-#define AVR8_TIMSK1_ICIE1_MASK 0x20
-#define AVR8_TIMSK1_OCIE1B_MASK 0x04
-#define AVR8_TIMSK1_OCIE1A_MASK 0x02
-#define AVR8_TIMSK1_TOIE1_MASK 0x01
-#define AVR8_TIMSK1_ICIE1 ((AVR8_TIMSK1 & AVR8_TIMSK1_ICIE1_MASK) >> 5)
-#define AVR8_TIMSK1_OCIE1B ((AVR8_TIMSK1 & AVR8_TIMSK1_OCIE1B_MASK) >> 2)
-#define AVR8_TIMSK1_OCIE1A ((AVR8_TIMSK1 & AVR8_TIMSK1_OCIE1A_MASK) >> 1)
-#define AVR8_TIMSK1_TOIE1 (AVR8_TIMSK1 & AVR8_TIMSK1_TOIE1_MASK)
-
-#define AVR8_TIFR1 (m_r[AVR8_REGIDX_TIFR1])
-#define AVR8_TIFR1_ICF1_MASK 0x20
-#define AVR8_TIFR1_ICF1_SHIFT 5
-#define AVR8_TIFR1_OCF1B_MASK 0x04
-#define AVR8_TIFR1_OCF1B_SHIFT 2
-#define AVR8_TIFR1_OCF1A_MASK 0x02
-#define AVR8_TIFR1_OCF1A_SHIFT 1
-#define AVR8_TIFR1_TOV1_MASK 0x01
-#define AVR8_TIFR1_TOV1_SHIFT 0
-#define AVR8_TIFR1_MASK (AVR8_TIFR1_ICF1_MASK | AVR8_TIFR1_TOV1_MASK | \
- AVR8_TIFR1_OCF1B_MASK | AVR8_TIFR1_OCF1A_MASK)
-
-#define AVR8_TCCR2B (m_r[AVR8_REGIDX_TCCR2B])
-#define AVR8_TCCR2B_FOC2A_MASK 0x80
-#define AVR8_TCCR2B_FOC2A_SHIFT 7
-#define AVR8_TCCR2B_FOC2B_MASK 0x40
-#define AVR8_TCCR2B_FOC2B_SHIFT 6
-#define AVR8_TCCR2B_WGM2_2_MASK 0x08
-#define AVR8_TCCR2B_WGM2_2_SHIFT 3
-#define AVR8_TCCR2B_CS_MASK 0x07
-#define AVR8_TCCR2B_CS_SHIFT 0
-#define AVR8_TIMER2_CLOCK_SELECT (AVR8_TCCR2B & AVR8_TCCR2B_CS_MASK)
-
-#define AVR8_TCCR2A (m_r[AVR8_REGIDX_TCCR2A])
-#define AVR8_TCCR2A_COM2A_MASK 0xc0
-#define AVR8_TCCR2A_COM2A_SHIFT 6
-#define AVR8_TCCR2A_COM2B_MASK 0x30
-#define AVR8_TCCR2A_COM2B_SHIFT 4
-#define AVR8_TCCR2A_WGM2_10_MASK 0x03
-#define AVR8_TCCR2A_WGM2_10_SHIFT 0
-#define AVR8_TCCR2A_COM2A ((AVR8_TCCR2A & AVR8_TCCR2A_COM2A_MASK) >> AVR8_TCCR2A_COM2A_SHIFT)
-#define AVR8_TCCR2A_COM2B ((AVR8_TCCR2A & AVR8_TCCR2A_COM2B_MASK) >> AVR8_TCCR2A_COM2B_SHIFT)
-#define AVR8_TCCR2A_WGM2_10 (AVR8_TCCR2A & AVR8_TCCR2A_WGM2_10_MASK)
-
-#define AVR8_TIMSK2 (m_r[AVR8_REGIDX_TIMSK2])
-#define AVR8_TIMSK2_OCIE2B_MASK 0x04
-#define AVR8_TIMSK2_OCIE2A_MASK 0x02
-#define AVR8_TIMSK2_TOIE2_MASK 0x01
-#define AVR8_TIMSK2_OCIE2B ((AVR8_TIMSK2 & AVR8_TIMSK2_OCIE2B_MASK) >> 2)
-#define AVR8_TIMSK2_OCIE2A ((AVR8_TIMSK2 & AVR8_TIMSK2_OCIE2A_MASK) >> 1)
-#define AVR8_TIMSK2_TOIE2 (AVR8_TIMSK2 & AVR8_TIMSK2_TOIE2_MASK)
-
-#define AVR8_TIFR2 (m_r[AVR8_REGIDX_TIFR2])
-#define AVR8_TIFR2_OCF2B_MASK 0x04
-#define AVR8_TIFR2_OCF2B_SHIFT 2
-#define AVR8_TIFR2_OCF2A_MASK 0x02
-#define AVR8_TIFR2_OCF2A_SHIFT 1
-#define AVR8_TIFR2_TOV2_MASK 0x01
-#define AVR8_TIFR2_TOV2_SHIFT 0
-#define AVR8_TIFR2_MASK (AVR8_TIFR2_TOV2_MASK | AVR8_TIFR2_OCF2B_MASK | AVR8_TIFR2_OCF2A_MASK)
-
-#define AVR8_OCR0A m_r[AVR8_REGIDX_OCR0A]
-#define AVR8_OCR0B m_r[AVR8_REGIDX_OCR0B]
-#define AVR8_TCNT0 m_r[AVR8_REGIDX_TCNT0]
-#define AVR8_WGM0 (((AVR8_TCCR0B & 0x08) >> 1) | (AVR8_TCCR0A & 0x03))
-
-#define AVR8_OCR1A ((AVR8_OCR1AH << 8) | AVR8_OCR1AL)
-#define AVR8_OCR1B ((AVR8_OCR1BH << 8) | AVR8_OCR1BL)
-#define AVR8_ICR1 ((AVR8_ICR1H << 8) | AVR8_ICR1L)
-#define AVR8_TCNT1 ((AVR8_TCNT1H << 8) | AVR8_TCNT1L)
-#define AVR8_WGM1 (((AVR8_TCCR1B & 0x18) >> 1) | (AVR8_TCCR1A & 0x03))
-#define AVR8_TCNT1_DIR (state->m_tcnt1_direction)
-
-#define AVR8_OCR2A m_r[AVR8_REGIDX_OCR2A]
-#define AVR8_OCR2B m_r[AVR8_REGIDX_OCR2B]
-#define AVR8_TCNT2 m_r[AVR8_REGIDX_TCNT2]
-#define AVR8_WGM2 (((AVR8_TCCR2B & 0x08) >> 1) | (AVR8_TCCR2A & 0x03))
-
-#define AVR8_GTCCR_PSRASY_MASK 0x02
-#define AVR8_GTCCR_PSRASY_SHIFT 1
-
-#define AVR8_SPSR (m_r[AVR8_REGIDX_SPSR])
-#define AVR8_SPSR_SPR2X (AVR8_SPSR & AVR8_SPSR_SPR2X_MASK)
-
-#define AVR8_SPCR (m_r[AVR8_REGIDX_SPCR])
-#define AVR8_SPCR_SPIE ((AVR8_SPCR & AVR8_SPCR_SPIE_MASK) >> 7)
-#define AVR8_SPCR_SPE ((AVR8_SPCR & AVR8_SPCR_SPE_MASK) >> 6)
-#define AVR8_SPCR_DORD ((AVR8_SPCR & AVR8_SPCR_DORD_MASK) >> 5)
-#define AVR8_SPCR_MSTR ((AVR8_SPCR & AVR8_SPCR_MSTR_MASK) >> 4)
-#define AVR8_SPCR_CPOL ((AVR8_SPCR & AVR8_SPCR_CPOL_MASK) >> 3)
-#define AVR8_SPCR_CPHA ((AVR8_SPCR & AVR8_SPCR_CPHA_MASK) >> 2)
-#define AVR8_SPCR_SPR (AVR8_SPCR & AVR8_SPCR_SPR_MASK)
-
-#define AVR8_SPI_RATE ((AVR8_SPSR_SPR2X << 2) | AVR8_SPCR_SPR)
-
-#define AVR8_PORTB_MOSI 0x08
+#define AVR8_OCR1BH (m_r[AVR8_REGIDX_OCR1BH])
+#define AVR8_OCR1BL (m_r[AVR8_REGIDX_OCR1BL])
+#define AVR8_OCR1AH (m_r[AVR8_REGIDX_OCR1AH])
+#define AVR8_OCR1AL (m_r[AVR8_REGIDX_OCR1AL])
+#define AVR8_ICR1H (m_r[AVR8_REGIDX_ICR1H])
+#define AVR8_ICR1L (m_r[AVR8_REGIDX_ICR1L])
+#define AVR8_TCNT1H (m_r[AVR8_REGIDX_TCNT1H])
+#define AVR8_TCNT1L (m_r[AVR8_REGIDX_TCNT1L])
+
+#define AVR8_TCCR0B (m_r[AVR8_REGIDX_TCCR0B])
+#define AVR8_TCCR0B_FOC0A_MASK 0x80
+#define AVR8_TCCR0B_FOC0A_SHIFT 7
+#define AVR8_TCCR0B_FOC0B_MASK 0x40
+#define AVR8_TCCR0B_FOC0B_SHIFT 6
+#define AVR8_TCCR0B_WGM0_2_MASK 0x08
+#define AVR8_TCCR0B_WGM0_2_SHIFT 3
+#define AVR8_TCCR0B_CS_MASK 0x07
+#define AVR8_TCCR0B_CS_SHIFT 0
+#define AVR8_TIMER0_CLOCK_SELECT (AVR8_TCCR0B & AVR8_TCCR0B_CS_MASK)
+
+#define AVR8_TCCR0A (m_r[AVR8_REGIDX_TCCR0A])
+#define AVR8_TCCR0A_COM0A_MASK 0xc0
+#define AVR8_TCCR0A_COM0A_SHIFT 6
+#define AVR8_TCCR0A_COM0B_MASK 0x30
+#define AVR8_TCCR0A_COM0B_SHIFT 4
+#define AVR8_TCCR0A_WGM0_10_MASK 0x03
+#define AVR8_TCCR0A_WGM0_10_SHIFT 0
+#define AVR8_TCCR0A_COM0A ((AVR8_TCCR0A & AVR8_TCCR0A_COM0A_MASK) >> AVR8_TCCR0A_COM0A_SHIFT)
+#define AVR8_TCCR0A_COM0B ((AVR8_TCCR0A & AVR8_TCCR0A_COM0B_MASK) >> AVR8_TCCR0A_COM0B_SHIFT)
+#define AVR8_TCCR0A_WGM0_10 (AVR8_TCCR0A & AVR8_TCCR0A_WGM0_10_MASK)
+
+#define AVR8_TIMSK0 (m_r[AVR8_REGIDX_TIMSK0])
+#define AVR8_TIMSK0_OCIE0B_MASK 0x04
+#define AVR8_TIMSK0_OCIE0A_MASK 0x02
+#define AVR8_TIMSK0_TOIE0_MASK 0x01
+#define AVR8_TIMSK0_OCIE0B ((AVR8_TIMSK0 & AVR8_TIMSK0_OCIE0B_MASK) >> 2)
+#define AVR8_TIMSK0_OCIE0A ((AVR8_TIMSK0 & AVR8_TIMSK0_OCIE0A_MASK) >> 1)
+#define AVR8_TIMSK0_TOIE0 (AVR8_TIMSK0 & AVR8_TIMSK0_TOIE0_MASK)
+
+#define AVR8_TIFR0 (m_r[AVR8_REGIDX_TIFR0])
+#define AVR8_TIFR0_OCF0B_MASK 0x04
+#define AVR8_TIFR0_OCF0B_SHIFT 2
+#define AVR8_TIFR0_OCF0A_MASK 0x02
+#define AVR8_TIFR0_OCF0A_SHIFT 1
+#define AVR8_TIFR0_TOV0_MASK 0x01
+#define AVR8_TIFR0_TOV0_SHIFT 0
+#define AVR8_TIFR0_MASK (AVR8_TIFR0_TOV0_MASK | AVR8_TIFR0_OCF0B_MASK | AVR8_TIFR0_OCF0A_MASK)
+
+#define AVR8_TCCR1B (m_r[AVR8_REGIDX_TCCR1B])
+#define AVR8_TCCR1B_ICNC1_MASK 0x80
+#define AVR8_TCCR1B_ICNC1_SHIFT 7
+#define AVR8_TCCR1B_ICES1_MASK 0x40
+#define AVR8_TCCR1B_ICES1_SHIFT 6
+#define AVR8_TCCR1B_WGM1_32_MASK 0x18
+#define AVR8_TCCR1B_WGM1_32_SHIFT 3
+#define AVR8_TCCR1B_CS_MASK 0x07
+#define AVR8_TCCR1B_CS_SHIFT 0
+#define AVR8_TIMER1_CLOCK_SELECT (AVR8_TCCR1B & AVR8_TCCR1B_CS_MASK)
+
+#define AVR8_TCCR1A (m_r[AVR8_REGIDX_TCCR1A])
+#define AVR8_TCCR1A_COM1A_MASK 0xc0
+#define AVR8_TCCR1A_COM1A_SHIFT 6
+#define AVR8_TCCR1A_COM1B_MASK 0x30
+#define AVR8_TCCR1A_COM1B_SHIFT 4
+#define AVR8_TCCR1A_WGM1_10_MASK 0x03
+#define AVR8_TCCR1A_WGM1_10_SHIFT 0
+#define AVR8_TCCR1A_COM1A ((AVR8_TCCR1A & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT)
+#define AVR8_TCCR1A_COM1B ((AVR8_TCCR1A & AVR8_TCCR1A_COM1B_MASK) >> AVR8_TCCR1A_COM1B_SHIFT)
+#define AVR8_TCCR1A_WGM1_10 (AVR8_TCCR1A & AVR8_TCCR1A_WGM1_10_MASK)
+
+#define AVR8_TIMSK1 (m_r[AVR8_REGIDX_TIMSK1])
+#define AVR8_TIMSK1_ICIE1_MASK 0x20
+#define AVR8_TIMSK1_OCIE1B_MASK 0x04
+#define AVR8_TIMSK1_OCIE1A_MASK 0x02
+#define AVR8_TIMSK1_TOIE1_MASK 0x01
+#define AVR8_TIMSK1_ICIE1 ((AVR8_TIMSK1 & AVR8_TIMSK1_ICIE1_MASK) >> 5)
+#define AVR8_TIMSK1_OCIE1B ((AVR8_TIMSK1 & AVR8_TIMSK1_OCIE1B_MASK) >> 2)
+#define AVR8_TIMSK1_OCIE1A ((AVR8_TIMSK1 & AVR8_TIMSK1_OCIE1A_MASK) >> 1)
+#define AVR8_TIMSK1_TOIE1 (AVR8_TIMSK1 & AVR8_TIMSK1_TOIE1_MASK)
+
+#define AVR8_TIFR1 (m_r[AVR8_REGIDX_TIFR1])
+#define AVR8_TIFR1_ICF1_MASK 0x20
+#define AVR8_TIFR1_ICF1_SHIFT 5
+#define AVR8_TIFR1_OCF1B_MASK 0x04
+#define AVR8_TIFR1_OCF1B_SHIFT 2
+#define AVR8_TIFR1_OCF1A_MASK 0x02
+#define AVR8_TIFR1_OCF1A_SHIFT 1
+#define AVR8_TIFR1_TOV1_MASK 0x01
+#define AVR8_TIFR1_TOV1_SHIFT 0
+#define AVR8_TIFR1_MASK (AVR8_TIFR1_ICF1_MASK | AVR8_TIFR1_TOV1_MASK | \
+ AVR8_TIFR1_OCF1B_MASK | AVR8_TIFR1_OCF1A_MASK)
+
+#define AVR8_TCCR2B (m_r[AVR8_REGIDX_TCCR2B])
+#define AVR8_TCCR2B_FOC2A_MASK 0x80
+#define AVR8_TCCR2B_FOC2A_SHIFT 7
+#define AVR8_TCCR2B_FOC2B_MASK 0x40
+#define AVR8_TCCR2B_FOC2B_SHIFT 6
+#define AVR8_TCCR2B_WGM2_2_MASK 0x08
+#define AVR8_TCCR2B_WGM2_2_SHIFT 3
+#define AVR8_TCCR2B_CS_MASK 0x07
+#define AVR8_TCCR2B_CS_SHIFT 0
+#define AVR8_TIMER2_CLOCK_SELECT (AVR8_TCCR2B & AVR8_TCCR2B_CS_MASK)
+
+#define AVR8_TCCR2A (m_r[AVR8_REGIDX_TCCR2A])
+#define AVR8_TCCR2A_COM2A_MASK 0xc0
+#define AVR8_TCCR2A_COM2A_SHIFT 6
+#define AVR8_TCCR2A_COM2B_MASK 0x30
+#define AVR8_TCCR2A_COM2B_SHIFT 4
+#define AVR8_TCCR2A_WGM2_10_MASK 0x03
+#define AVR8_TCCR2A_WGM2_10_SHIFT 0
+#define AVR8_TCCR2A_COM2A ((AVR8_TCCR2A & AVR8_TCCR2A_COM2A_MASK) >> AVR8_TCCR2A_COM2A_SHIFT)
+#define AVR8_TCCR2A_COM2B ((AVR8_TCCR2A & AVR8_TCCR2A_COM2B_MASK) >> AVR8_TCCR2A_COM2B_SHIFT)
+#define AVR8_TCCR2A_WGM2_10 (AVR8_TCCR2A & AVR8_TCCR2A_WGM2_10_MASK)
+
+#define AVR8_TIMSK2 (m_r[AVR8_REGIDX_TIMSK2])
+#define AVR8_TIMSK2_OCIE2B_MASK 0x04
+#define AVR8_TIMSK2_OCIE2A_MASK 0x02
+#define AVR8_TIMSK2_TOIE2_MASK 0x01
+#define AVR8_TIMSK2_OCIE2B ((AVR8_TIMSK2 & AVR8_TIMSK2_OCIE2B_MASK) >> 2)
+#define AVR8_TIMSK2_OCIE2A ((AVR8_TIMSK2 & AVR8_TIMSK2_OCIE2A_MASK) >> 1)
+#define AVR8_TIMSK2_TOIE2 (AVR8_TIMSK2 & AVR8_TIMSK2_TOIE2_MASK)
+
+#define AVR8_TIFR2 (m_r[AVR8_REGIDX_TIFR2])
+#define AVR8_TIFR2_OCF2B_MASK 0x04
+#define AVR8_TIFR2_OCF2B_SHIFT 2
+#define AVR8_TIFR2_OCF2A_MASK 0x02
+#define AVR8_TIFR2_OCF2A_SHIFT 1
+#define AVR8_TIFR2_TOV2_MASK 0x01
+#define AVR8_TIFR2_TOV2_SHIFT 0
+#define AVR8_TIFR2_MASK (AVR8_TIFR2_TOV2_MASK | AVR8_TIFR2_OCF2B_MASK | AVR8_TIFR2_OCF2A_MASK)
+
+#define AVR8_OCR0A m_r[AVR8_REGIDX_OCR0A]
+#define AVR8_OCR0B m_r[AVR8_REGIDX_OCR0B]
+#define AVR8_TCNT0 m_r[AVR8_REGIDX_TCNT0]
+#define AVR8_WGM0 (((AVR8_TCCR0B & 0x08) >> 1) | (AVR8_TCCR0A & 0x03))
+
+#define AVR8_OCR1A ((AVR8_OCR1AH << 8) | AVR8_OCR1AL)
+#define AVR8_OCR1B ((AVR8_OCR1BH << 8) | AVR8_OCR1BL)
+#define AVR8_ICR1 ((AVR8_ICR1H << 8) | AVR8_ICR1L)
+#define AVR8_TCNT1 ((AVR8_TCNT1H << 8) | AVR8_TCNT1L)
+#define AVR8_WGM1 (((AVR8_TCCR1B & 0x18) >> 1) | (AVR8_TCCR1A & 0x03))
+#define AVR8_TCNT1_DIR (state->m_tcnt1_direction)
+
+#define AVR8_OCR2A m_r[AVR8_REGIDX_OCR2A]
+#define AVR8_OCR2B m_r[AVR8_REGIDX_OCR2B]
+#define AVR8_TCNT2 m_r[AVR8_REGIDX_TCNT2]
+#define AVR8_WGM2 (((AVR8_TCCR2B & 0x08) >> 1) | (AVR8_TCCR2A & 0x03))
+
+#define AVR8_GTCCR_PSRASY_MASK 0x02
+#define AVR8_GTCCR_PSRASY_SHIFT 1
+
+#define AVR8_SPSR (m_r[AVR8_REGIDX_SPSR])
+#define AVR8_SPSR_SPR2X (AVR8_SPSR & AVR8_SPSR_SPR2X_MASK)
+
+#define AVR8_SPCR (m_r[AVR8_REGIDX_SPCR])
+#define AVR8_SPCR_SPIE ((AVR8_SPCR & AVR8_SPCR_SPIE_MASK) >> 7)
+#define AVR8_SPCR_SPE ((AVR8_SPCR & AVR8_SPCR_SPE_MASK) >> 6)
+#define AVR8_SPCR_DORD ((AVR8_SPCR & AVR8_SPCR_DORD_MASK) >> 5)
+#define AVR8_SPCR_MSTR ((AVR8_SPCR & AVR8_SPCR_MSTR_MASK) >> 4)
+#define AVR8_SPCR_CPOL ((AVR8_SPCR & AVR8_SPCR_CPOL_MASK) >> 3)
+#define AVR8_SPCR_CPHA ((AVR8_SPCR & AVR8_SPCR_CPHA_MASK) >> 2)
+#define AVR8_SPCR_SPR (AVR8_SPCR & AVR8_SPCR_SPR_MASK)
+
+#define AVR8_SPI_RATE ((AVR8_SPSR_SPR2X << 2) | AVR8_SPCR_SPR)
+
+#define AVR8_PORTB_MOSI 0x08
//**************************************************************************
// DEVICE INTERFACE
@@ -346,33 +346,33 @@ atmega644_device::atmega644_device(const machine_config &mconfig, const char *ta
avr8_device::avr8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, const device_type type, UINT32 addr_mask, address_map_constructor internal_map)
: cpu_device(mconfig, type, "AVR8", tag, owner, clock),
- 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, 2),
- m_eeprom(NULL),
- m_pc(0),
- m_shifted_pc(0),
- m_timer0_top(0),
- m_timer0_increment(1),
- m_timer0_prescale(0),
- m_timer0_prescale_count(0),
- m_timer1_top(0),
- m_timer1_increment(1),
- m_timer1_prescale(0),
- m_timer1_prescale_count(0),
- m_timer2_top(0),
- m_timer2_increment(1),
- m_timer2_prescale(0),
- m_timer2_prescale_count(0),
- m_spi_active(false),
- m_spi_prescale(0),
- m_spi_prescale_count(0),
- m_addr_mask(addr_mask),
- m_interrupt_pending(false),
- m_icount(0),
- m_elapsed_cycles(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, 2),
+ m_eeprom(NULL),
+ m_pc(0),
+ m_shifted_pc(0),
+ m_timer0_top(0),
+ m_timer0_increment(1),
+ m_timer0_prescale(0),
+ m_timer0_prescale_count(0),
+ m_timer1_top(0),
+ m_timer1_increment(1),
+ m_timer1_prescale(0),
+ m_timer1_prescale_count(0),
+ m_timer2_top(0),
+ m_timer2_increment(1),
+ m_timer2_prescale(0),
+ m_timer2_prescale_count(0),
+ m_spi_active(false),
+ m_spi_prescale(0),
+ m_spi_prescale_count(0),
+ m_addr_mask(addr_mask),
+ m_interrupt_pending(false),
+ m_icount(0),
+ m_elapsed_cycles(0)
{
- // Allocate & setup
+ // Allocate & setup
}
@@ -395,7 +395,7 @@ void avr8_device::static_set_config(device_t &device, const avr8_config &config)
void avr8_device::unimplemented_opcode(UINT32 op)
{
- fatalerror("AVR8: unknown opcode (%08x) at %08x\n", op, m_pc);
+ fatalerror("AVR8: unknown opcode (%08x) at %08x\n", op, m_pc);
}
@@ -432,11 +432,11 @@ inline bool avr8_device::is_long_opcode(UINT16 op)
void avr8_device::device_start()
{
- m_pc = 0;
+ m_pc = 0;
- m_program = &space(AS_PROGRAM);
- m_data = &space(AS_DATA);
- m_io = &space(AS_IO);
+ m_program = &space(AS_PROGRAM);
+ m_data = &space(AS_DATA);
+ m_io = &space(AS_IO);
// register our state for the debugger
astring tempstr;
@@ -521,31 +521,31 @@ void avr8_device::device_reset()
m_spi_prescale = 0;
m_spi_prescale_count = 0;
- m_timer0_top = 0;
+ m_timer0_top = 0;
m_timer0_increment = 1;
m_timer0_prescale = 0;
m_timer0_prescale_count = 0;
- m_timer1_top = 0;
+ m_timer1_top = 0;
m_timer1_increment = 1;
m_timer1_prescale = 0;
m_timer1_prescale_count = 0;
- m_timer2_top = 0;
+ m_timer2_top = 0;
m_timer2_increment = 1;
m_timer2_prescale = 0;
m_timer2_prescale_count = 0;
- AVR8_TIMSK1 = 0;
- AVR8_OCR1AH = 0;
- AVR8_OCR1AL = 0;
- AVR8_OCR1BH = 0;
- AVR8_OCR1BL = 0;
- AVR8_ICR1H = 0;
- AVR8_ICR1L = 0;
- AVR8_TCNT1H = 0;
- AVR8_TCNT1L = 0;
- AVR8_TCNT2 = 0;
+ AVR8_TIMSK1 = 0;
+ AVR8_OCR1AH = 0;
+ AVR8_OCR1AL = 0;
+ AVR8_OCR1BH = 0;
+ AVR8_OCR1BL = 0;
+ AVR8_ICR1H = 0;
+ AVR8_ICR1L = 0;
+ AVR8_TCNT1H = 0;
+ AVR8_TCNT1L = 0;
+ AVR8_TCNT2 = 0;
m_interrupt_pending = false;
@@ -587,14 +587,14 @@ void avr8_device::state_string_export(const device_state_entry &entry, astring &
{
case STATE_GENFLAGS:
string.printf("%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' : '-');
+ (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;
}
}
@@ -641,19 +641,19 @@ offs_t avr8_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *opr
inline void avr8_device::push(UINT8 val)
{
UINT16 sp = SPREG;
- m_data->write_byte(sp, val);
- sp--;
- m_r[AVR8_REGIDX_SPL] = sp & 0x00ff;
- m_r[AVR8_REGIDX_SPH] = (sp >> 8) & 0x00ff;
+ m_data->write_byte(sp, val);
+ sp--;
+ m_r[AVR8_REGIDX_SPL] = sp & 0x00ff;
+ m_r[AVR8_REGIDX_SPH] = (sp >> 8) & 0x00ff;
}
inline UINT8 avr8_device::pop()
{
UINT16 sp = SPREG;
- sp++;
+ sp++;
m_r[AVR8_REGIDX_SPL] = sp & 0x00ff;
m_r[AVR8_REGIDX_SPH] = (sp >> 8) & 0x00ff;
- return m_data->read_byte(sp);
+ return m_data->read_byte(sp);
}
//**************************************************************************
@@ -662,9 +662,9 @@ inline UINT8 avr8_device::pop()
void avr8_device::set_irq_line(UINT16 vector, int state)
{
- // Horrible hack, not accurate
- if(state)
- {
+ // Horrible hack, not accurate
+ if(state)
+ {
if(SREG_R(AVR8_SREG_I))
{
SREG_W(AVR8_SREG_I, 0);
@@ -677,7 +677,7 @@ void avr8_device::set_irq_line(UINT16 vector, int state)
{
m_interrupt_pending = true;
}
- }
+ }
}
class CInterruptCondition
@@ -707,10 +707,10 @@ static const CInterruptCondition s_int_conditions[AVR8_INTIDX_COUNT] =
void avr8_device::update_interrupt(int source)
{
- CInterruptCondition condition = s_int_conditions[source];
+ CInterruptCondition condition = s_int_conditions[source];
- int intstate = (m_r[condition.m_regindex] & condition.m_regmask) ? 1 : 0;
- intstate = (m_r[condition.m_intreg] & condition.m_intmask) ? intstate : 0;
+ int intstate = (m_r[condition.m_regindex] & condition.m_regmask) ? 1 : 0;
+ intstate = (m_r[condition.m_intreg] & condition.m_intmask) ? intstate : 0;
set_irq_line(condition.m_intindex, intstate);
@@ -738,10 +738,10 @@ static const CInterruptCondition s_mega644_int_conditions[AVR8_INTIDX_COUNT] =
void atmega644_device::update_interrupt(int source)
{
- CInterruptCondition condition = s_mega644_int_conditions[source];
+ CInterruptCondition condition = s_mega644_int_conditions[source];
- int intstate = (m_r[condition.m_regindex] & condition.m_regmask) ? 1 : 0;
- intstate = (m_r[condition.m_intreg] & condition.m_intmask) ? intstate : 0;
+ int intstate = (m_r[condition.m_regindex] & condition.m_regmask) ? 1 : 0;
+ intstate = (m_r[condition.m_intreg] & condition.m_intmask) ? intstate : 0;
set_irq_line(condition.m_intindex << 1, intstate);
@@ -810,94 +810,94 @@ void avr8_device::timer_tick(int cycles)
void avr8_device::timer0_tick()
{
/*
- UINT16 count = m_r[AVR8_REGIDX_TCNT0];
- INT32 wgm0 = ((m_r[AVR8_REGIDX_TCCR0B] & AVR8_TCCR0B_WGM0_2_MASK) >> 1) |
- (m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_WGM0_10_MASK);
-
- // Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer
- //UINT8 compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_COM0A_MASK) >> AVR8_TCCR0A_COM0A_SHIFT,
- //(m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_COM0B_MASK) >> AVR8_TCCR0A_COM0B_SHIFT };
- UINT8 ocr0[2] = { m_r[AVR8_REGIDX_OCR0A], m_r[AVR8_REGIDX_OCR0B] };
- UINT8 ocf0[2] = { (1 << AVR8_TIFR0_OCF0A_SHIFT), (1 << AVR8_TIFR0_OCF0B_SHIFT) };
- INT32 increment = m_timer0_increment;
-
- for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
- {
- switch(wgm0)
- {
- case WGM02_FAST_PWM:
- if(count == ocr0[reg])
- {
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR0] |= AVR8_TIFR0_TOV0_MASK;
- count = 0;
- increment = 0;
- }
-
- m_r[AVR8_REGIDX_TIFR0] |= ocf0[reg];
- }
- else if(count == 0)
- {
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR0] &= ~AVR8_TIFR0_TOV0_MASK;
- }
- }
- break;
-
- case WGM02_FAST_PWM_CMP:
- if(count == ocr0[reg])
- {
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR0] |= AVR8_TIFR0_TOV0_MASK;
- count = 0;
- increment = 0;
- }
-
- m_r[AVR8_REGIDX_TIFR0] |= ocf0[reg];
- }
- else if(count == 0)
- {
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR0] &= ~AVR8_TIFR0_TOV0_MASK;
- }
- }
- break;
-
- default:
- // TODO
- break;
- }
- switch(compare_mode[reg])
- {
- case 0:
- //verboselog(m_pc, 0, "update_timer0_compare_mode: Normal port operation (OC0 disconnected)\n");
- break;
-
- case 1:
- case 2:
- // TODO
- break;
-
- case 3:
- break;
- }
- }
-
- m_r[AVR8_REGIDX_TCNT0] = count + increment;
-
- update_interrupt(AVR8_INTIDX_OCF0A);
- update_interrupt(AVR8_INTIDX_OCF0B);
- update_interrupt(AVR8_INTIDX_TOV0);
- */
+ UINT16 count = m_r[AVR8_REGIDX_TCNT0];
+ INT32 wgm0 = ((m_r[AVR8_REGIDX_TCCR0B] & AVR8_TCCR0B_WGM0_2_MASK) >> 1) |
+ (m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_WGM0_10_MASK);
+
+ // Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer
+ //UINT8 compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_COM0A_MASK) >> AVR8_TCCR0A_COM0A_SHIFT,
+ //(m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_COM0B_MASK) >> AVR8_TCCR0A_COM0B_SHIFT };
+ UINT8 ocr0[2] = { m_r[AVR8_REGIDX_OCR0A], m_r[AVR8_REGIDX_OCR0B] };
+ UINT8 ocf0[2] = { (1 << AVR8_TIFR0_OCF0A_SHIFT), (1 << AVR8_TIFR0_OCF0B_SHIFT) };
+ INT32 increment = m_timer0_increment;
+
+ for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
+ {
+ switch(wgm0)
+ {
+ case WGM02_FAST_PWM:
+ if(count == ocr0[reg])
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR0] |= AVR8_TIFR0_TOV0_MASK;
+ count = 0;
+ increment = 0;
+ }
+
+ m_r[AVR8_REGIDX_TIFR0] |= ocf0[reg];
+ }
+ else if(count == 0)
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR0] &= ~AVR8_TIFR0_TOV0_MASK;
+ }
+ }
+ break;
+
+ case WGM02_FAST_PWM_CMP:
+ if(count == ocr0[reg])
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR0] |= AVR8_TIFR0_TOV0_MASK;
+ count = 0;
+ increment = 0;
+ }
+
+ m_r[AVR8_REGIDX_TIFR0] |= ocf0[reg];
+ }
+ else if(count == 0)
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR0] &= ~AVR8_TIFR0_TOV0_MASK;
+ }
+ }
+ break;
+
+ default:
+ // TODO
+ break;
+ }
+ switch(compare_mode[reg])
+ {
+ case 0:
+ //verboselog(m_pc, 0, "update_timer0_compare_mode: Normal port operation (OC0 disconnected)\n");
+ break;
+
+ case 1:
+ case 2:
+ // TODO
+ break;
+
+ case 3:
+ break;
+ }
+ }
+
+ m_r[AVR8_REGIDX_TCNT0] = count + increment;
+
+ update_interrupt(AVR8_INTIDX_OCF0A);
+ update_interrupt(AVR8_INTIDX_OCF0B);
+ update_interrupt(AVR8_INTIDX_TOV0);
+ */
}
void avr8_device::update_timer0_waveform_gen_mode()
{
- m_timer0_top = 0;
+ m_timer0_top = 0;
switch(AVR8_WGM0)
{
case WGM02_NORMAL:
@@ -1008,32 +1008,32 @@ void avr8_device::update_timer0_clock_source()
void avr8_device::update_ocr0(UINT8 newval, UINT8 reg)
{
- m_r[(reg == AVR8_REG_A) ? AVR8_REGIDX_OCR0A : AVR8_REGIDX_OCR0B] = newval;
+ m_r[(reg == AVR8_REG_A) ? AVR8_REGIDX_OCR0A : AVR8_REGIDX_OCR0B] = newval;
}
// Timer 1 Handling
void avr8_device::timer1_tick()
{
- /* TODO: Handle comparison, setting OC1x pins, detection of BOTTOM and TOP */
+ /* TODO: Handle comparison, setting OC1x pins, detection of BOTTOM and TOP */
- UINT16 count = (m_r[AVR8_REGIDX_TCNT1H] << 8) | m_r[AVR8_REGIDX_TCNT1L];
- INT32 wgm1 = ((m_r[AVR8_REGIDX_TCCR1B] & AVR8_TCCR1B_WGM1_32_MASK) >> 1) |
- (m_r[AVR8_REGIDX_TCCR1A] & AVR8_TCCR1A_WGM1_10_MASK);
+ UINT16 count = (m_r[AVR8_REGIDX_TCNT1H] << 8) | m_r[AVR8_REGIDX_TCNT1L];
+ INT32 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 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 ocr1[2] = { (m_r[AVR8_REGIDX_OCR1AH] << 8) | m_r[AVR8_REGIDX_OCR1AL],
- (m_r[AVR8_REGIDX_OCR1BH] << 8) | m_r[AVR8_REGIDX_OCR1BL] };
+ // Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer
+ //UINT8 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 ocr1[2] = { (m_r[AVR8_REGIDX_OCR1AH] << 8) | m_r[AVR8_REGIDX_OCR1AL],
+ (m_r[AVR8_REGIDX_OCR1BH] << 8) | m_r[AVR8_REGIDX_OCR1BL] };
UINT8 ocf1[2] = { (1 << AVR8_TIFR1_OCF1A_SHIFT), (1 << AVR8_TIFR1_OCF1B_SHIFT) };
UINT8 int1[2] = { AVR8_INTIDX_OCF1A, AVR8_INTIDX_OCF1B };
- INT32 increment = m_timer1_increment;
+ INT32 increment = m_timer1_increment;
- for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
- {
- switch(wgm1)
- {
+ for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
+ {
+ switch(wgm1)
+ {
case WGM1_CTC_OCR:
if (count == 0xffff)
{
@@ -1043,81 +1043,81 @@ void avr8_device::timer1_tick()
increment = 0;
}
- if (count == ocr1[reg])
- {
- if (reg == 0)
- {
+ if (count == ocr1[reg])
+ {
+ if (reg == 0)
+ {
count = 0;
increment = 0;
- }
- m_r[AVR8_REGIDX_TIFR1] |= ocf1[reg];
+ }
+ 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;
+ }
+ else if (count == 0)
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK;
update_interrupt(AVR8_INTIDX_TOV1);
- }
+ }
- m_r[AVR8_REGIDX_TIFR1] &= ~ocf1[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)
- {
- m_r[AVR8_REGIDX_TIFR1] |= AVR8_TIFR1_TOV1_MASK;
+ }
+ break;
+
+ case WGM1_FAST_PWM_OCR:
+ 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;
- }
+ count = 0;
+ increment = 0;
+ }
- m_r[AVR8_REGIDX_TIFR1] |= ocf1[reg];
+ 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;
+ }
+ else if(count == 0)
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK;
update_interrupt(AVR8_INTIDX_TOV1);
- }
+ }
- m_r[AVR8_REGIDX_TIFR1] &= ~ocf1[reg];
+ m_r[AVR8_REGIDX_TIFR1] &= ~ocf1[reg];
update_interrupt(int1[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 1:
- case 2:
- // TODO
- break;
-
- case 3:
- break;
- }
- */
- }
-
- count += increment;
- m_r[AVR8_REGIDX_TCNT1H] = (count >> 8) & 0xff;
- m_r[AVR8_REGIDX_TCNT1L] = count & 0xff;
+ }
+ 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 1:
+ case 2:
+ // TODO
+ break;
+
+ case 3:
+ break;
+ }
+ */
+ }
+
+ count += increment;
+ m_r[AVR8_REGIDX_TCNT1H] = (count >> 8) & 0xff;
+ m_r[AVR8_REGIDX_TCNT1L] = count & 0xff;
}
void avr8_device::update_timer1_waveform_gen_mode()
@@ -1171,7 +1171,7 @@ void avr8_device::changed_tccr1a(UINT8 data)
UINT8 newtccr = data;
UINT8 changed = newtccr ^ oldtccr;
- m_r[AVR8_REGIDX_TCCR1A] = newtccr;
+ m_r[AVR8_REGIDX_TCCR1A] = newtccr;
if(changed & AVR8_TCCR1A_WGM1_10_MASK)
{
@@ -1232,7 +1232,7 @@ void avr8_device::changed_tccr1b(UINT8 data)
UINT8 newtccr = data;
UINT8 changed = newtccr ^ oldtccr;
- m_r[AVR8_REGIDX_TCCR1B] = newtccr;
+ m_r[AVR8_REGIDX_TCCR1B] = newtccr;
if(changed & AVR8_TCCR1B_ICNC1_MASK)
{
@@ -1264,93 +1264,93 @@ void avr8_device::update_ocr1(UINT16 newval, UINT8 reg)
*p_reg_h = (UINT8)(newval >> 8);
*p_reg_l = (UINT8)newval;
- // Nothing needs to be done? All handled in timer callback
+ // Nothing needs to be done? All handled in timer callback
}
// Timer 2 Handling
void avr8_device::timer2_tick()
{
- UINT16 count = m_r[AVR8_REGIDX_TCNT2];
- INT32 wgm2 = ((m_r[AVR8_REGIDX_TCCR2B] & AVR8_TCCR2B_WGM2_2_MASK) >> 1) |
- (m_r[AVR8_REGIDX_TCCR2A] & AVR8_TCCR2A_WGM2_10_MASK);
-
- // Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer
- //UINT8 compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR2A] & AVR8_TCCR2A_COM2A_MASK) >> AVR8_TCCR2A_COM2A_SHIFT,
- //(m_r[AVR8_REGIDX_TCCR2A] & AVR8_TCCR2A_COM2B_MASK) >> AVR8_TCCR2A_COM2B_SHIFT };
- UINT8 ocr2[2] = { m_r[AVR8_REGIDX_OCR2A], m_r[AVR8_REGIDX_OCR2B] };
+ UINT16 count = m_r[AVR8_REGIDX_TCNT2];
+ INT32 wgm2 = ((m_r[AVR8_REGIDX_TCCR2B] & AVR8_TCCR2B_WGM2_2_MASK) >> 1) |
+ (m_r[AVR8_REGIDX_TCCR2A] & AVR8_TCCR2A_WGM2_10_MASK);
+
+ // Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer
+ //UINT8 compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR2A] & AVR8_TCCR2A_COM2A_MASK) >> AVR8_TCCR2A_COM2A_SHIFT,
+ //(m_r[AVR8_REGIDX_TCCR2A] & AVR8_TCCR2A_COM2B_MASK) >> AVR8_TCCR2A_COM2B_SHIFT };
+ UINT8 ocr2[2] = { m_r[AVR8_REGIDX_OCR2A], m_r[AVR8_REGIDX_OCR2B] };
UINT8 ocf2[2] = { (1 << AVR8_TIFR2_OCF2A_SHIFT), (1 << AVR8_TIFR2_OCF2B_SHIFT) };
- INT32 increment = m_timer2_increment;
-
- for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
- {
- switch(wgm2)
- {
- case WGM02_FAST_PWM:
- if(count == ocr2[reg])
- {
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR2] |= AVR8_TIFR2_TOV2_MASK;
- count = 0;
- increment = 0;
- }
-
- m_r[AVR8_REGIDX_TIFR2] |= ocf2[reg];
- }
- else if(count == 0)
- {
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR2] &= ~AVR8_TIFR2_TOV2_MASK;
- }
- }
- break;
-
- case WGM02_FAST_PWM_CMP:
- if(count == ocr2[reg])
- {
- if (reg == 0)
- {
- m_r[AVR8_REGIDX_TIFR2] |= AVR8_TIFR2_TOV2_MASK;
- count = 0;
- increment = 0;
- }
-
- m_r[AVR8_REGIDX_TIFR2] |= ocf2[reg];
- }
- else if(count == 0)
- {
- if (reg == 0)
- {
- 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;
-
- case 3:
- break;
- }
- */
- }
-
- m_r[AVR8_REGIDX_TCNT2] = count + increment;
+ INT32 increment = m_timer2_increment;
+
+ for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
+ {
+ switch(wgm2)
+ {
+ case WGM02_FAST_PWM:
+ if(count == ocr2[reg])
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR2] |= AVR8_TIFR2_TOV2_MASK;
+ count = 0;
+ increment = 0;
+ }
+
+ m_r[AVR8_REGIDX_TIFR2] |= ocf2[reg];
+ }
+ else if(count == 0)
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR2] &= ~AVR8_TIFR2_TOV2_MASK;
+ }
+ }
+ break;
+
+ case WGM02_FAST_PWM_CMP:
+ if(count == ocr2[reg])
+ {
+ if (reg == 0)
+ {
+ m_r[AVR8_REGIDX_TIFR2] |= AVR8_TIFR2_TOV2_MASK;
+ count = 0;
+ increment = 0;
+ }
+
+ m_r[AVR8_REGIDX_TIFR2] |= ocf2[reg];
+ }
+ else if(count == 0)
+ {
+ if (reg == 0)
+ {
+ 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;
+
+ case 3:
+ break;
+ }
+ */
+ }
+
+ m_r[AVR8_REGIDX_TCNT2] = count + increment;
update_interrupt(AVR8_INTIDX_OCF2A);
update_interrupt(AVR8_INTIDX_OCF2B);
@@ -1359,7 +1359,7 @@ void avr8_device::timer2_tick()
void avr8_device::update_timer2_waveform_gen_mode()
{
- m_timer2_top = 0;
+ m_timer2_top = 0;
switch(AVR8_WGM2)
{
case WGM02_NORMAL:
@@ -1471,9 +1471,9 @@ void avr8_device::changed_tccr2b(UINT8 data)
void avr8_device::update_ocr2(UINT8 newval, UINT8 reg)
{
- m_r[(reg == AVR8_REG_A) ? AVR8_REGIDX_OCR2A : AVR8_REGIDX_OCR2B] = newval;
+ m_r[(reg == AVR8_REG_A) ? AVR8_REGIDX_OCR2A : AVR8_REGIDX_OCR2B] = newval;
- // Nothing needs to be done? All handled in timer callback
+ // Nothing needs to be done? All handled in timer callback
}
/****************/
@@ -1578,8 +1578,8 @@ void avr8_device::change_spsr(UINT8 data)
WRITE8_MEMBER( avr8_device::regs_w )
{
- switch( offset )
- {
+ switch( offset )
+ {
case AVR8_REGIDX_R0:
case AVR8_REGIDX_R1:
case AVR8_REGIDX_R2:
@@ -1651,8 +1651,8 @@ WRITE8_MEMBER( avr8_device::regs_w )
update_interrupt(AVR8_INTIDX_TOV0);
break;
- case AVR8_REGIDX_TCNT0:
- AVR8_TCNT0 = data;
+ case AVR8_REGIDX_TCNT0:
+ AVR8_TCNT0 = data;
break;
case AVR8_REGIDX_TCCR1B:
@@ -1703,12 +1703,12 @@ WRITE8_MEMBER( avr8_device::regs_w )
update_interrupt(AVR8_INTIDX_TOV1);
break;
- case AVR8_REGIDX_TCNT1H:
- AVR8_TCNT1H = data;
+ case AVR8_REGIDX_TCNT1H:
+ AVR8_TCNT1H = data;
break;
- case AVR8_REGIDX_TCNT1L:
- AVR8_TCNT1L = data;
+ case AVR8_REGIDX_TCNT1L:
+ AVR8_TCNT1L = data;
break;
case AVR8_REGIDX_TCCR2B:
@@ -1744,13 +1744,13 @@ WRITE8_MEMBER( avr8_device::regs_w )
update_interrupt(AVR8_INTIDX_TOV2);
break;
- case AVR8_REGIDX_TCNT2:
- AVR8_TCNT2 = data;
+ case AVR8_REGIDX_TCNT2:
+ AVR8_TCNT2 = data;
break;
- case AVR8_REGIDX_GTCCR:
- if (data & AVR8_GTCCR_PSRASY_MASK)
- {
+ case AVR8_REGIDX_GTCCR:
+ if (data & AVR8_GTCCR_PSRASY_MASK)
+ {
data &= ~AVR8_GTCCR_PSRASY_MASK;
m_timer2_prescale_count = 0;
}
@@ -1802,7 +1802,7 @@ WRITE8_MEMBER( avr8_device::regs_w )
m_r[AVR8_REGIDX_PORTC] = data;
break;
- case AVR8_REGIDX_PORTD:
+ case AVR8_REGIDX_PORTD:
m_io->write_byte(0x03, data);
m_r[AVR8_REGIDX_PORTD] = data;
break;
@@ -1824,17 +1824,17 @@ WRITE8_MEMBER( avr8_device::regs_w )
break;
}
- default:
+ default:
verboselog(m_pc, 0, "AVR8: Unknown Register Write: %02x = %02x\n", (UINT8)offset, data);
break;
- }
+ }
}
READ8_MEMBER( avr8_device::regs_r )
{
//printf("offset %04x\n", offset);
- switch( offset )
- {
+ switch( offset )
+ {
case AVR8_REGIDX_R0:
case AVR8_REGIDX_R1:
case AVR8_REGIDX_R2:
@@ -1899,10 +1899,10 @@ READ8_MEMBER( avr8_device::regs_r )
case AVR8_REGIDX_PIND:
return m_io->read_byte(AVR8_REG_D);
- default:
+ default:
verboselog(m_pc, 0, "AVR8: Unknown Register Read: %02x\n", (UINT8)offset);
- return 0;
- }
+ return 0;
+ }
}
@@ -1955,48 +1955,48 @@ void avr8_device::execute_set_input(int inputnum, int state)
void avr8_device::execute_run()
{
- UINT32 op = 0;
- INT32 offs = 0;
- UINT8 rd = 0;
- UINT8 rr = 0;
- UINT8 res = 0;
- UINT16 pd = 0;
- INT16 sd = 0;
- INT32 opcycles = 1;
-
- while (m_icount > 0)
- {
+ UINT32 op = 0;
+ INT32 offs = 0;
+ UINT8 rd = 0;
+ UINT8 rr = 0;
+ UINT8 res = 0;
+ UINT16 pd = 0;
+ INT16 sd = 0;
+ INT32 opcycles = 1;
+
+ while (m_icount > 0)
+ {
opcycles = 1;
- m_pc &= m_addr_mask;
- m_shifted_pc &= (m_addr_mask << 1) | 1;
-
- debugger_instruction_hook(this, m_shifted_pc);
-
- op = (UINT32)m_program->read_word(m_shifted_pc);
-
- 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)m_r[16 + RD4(op)] * (INT8)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))
- {
+ m_pc &= m_addr_mask;
+ m_shifted_pc &= (m_addr_mask << 1) | 1;
+
+ debugger_instruction_hook(this, m_shifted_pc);
+
+ op = (UINT32)m_program->read_word(m_shifted_pc);
+
+ 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)m_r[16 + RD4(op)] * (INT8)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)m_r[16 + RD3(op)] * (UINT8)m_r[16 + RR3(op)];
m_r[1] = (sd >> 8) & 0x00ff;
@@ -2033,869 +2033,869 @@ void avr8_device::execute_run()
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;
- }
- 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)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:
+ 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;
+ }
+ 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)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;
- }
- 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[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;
- }
- 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 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: // 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
- //output += sprintf( output, "ELPM R%d, Z", RD5(op) );
- unimplemented_opcode(op);
- break;
- case 0x0007: // ELPM Rd,Z+
- //output += sprintf( output, "ELPM R%d, Z+", RD5(op) );
- unimplemented_opcode(op);
- 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;
- }
- 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;
- }
- 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
- //output += sprintf( output, "EIJMP" );
- unimplemented_opcode(op);
- 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
+ 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;
+ }
+ 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[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;
+ }
+ 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 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: // 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
+ //output += sprintf( output, "ELPM R%d, Z", RD5(op) );
+ unimplemented_opcode(op);
+ break;
+ case 0x0007: // ELPM Rd,Z+
+ //output += sprintf( output, "ELPM R%d, Z+", RD5(op) );
+ unimplemented_opcode(op);
+ 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;
+ }
+ 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;
+ }
+ 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
+ //output += sprintf( output, "EIJMP" );
+ unimplemented_opcode(op);
+ 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++;
+ 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:
+ 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++;
+ 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;
- }
- 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" );
- 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);
- 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;
- }
- 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;
- 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
- //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;
- break;
- case 0x0900: // SBIC A,b
- if(NOT(BIT(m_data->read_byte(32 + ACONST5(op)), RR3(op))))
- {
- op = (UINT32)m_program->read_word(m_shifted_pc + 2);
+ break;
+ default:
+ unimplemented_opcode(op);
+ //output += sprintf( output, "Undefined (%04x)", op );
+ break;
+ }
+ 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" );
+ 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);
+ 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;
+ }
+ 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;
+ 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
+ //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;
+ break;
+ case 0x0900: // SBIC A,b
+ if(NOT(BIT(m_data->read_byte(32 + ACONST5(op)), RR3(op))))
+ {
+ op = (UINT32)m_program->read_word(m_shifted_pc + 2);
opcycles = is_long_opcode(op) ? 3 : 2;
- m_pc += is_long_opcode(op) ? 2 : 1;
+ m_pc += is_long_opcode(op) ? 2 : 1;
}
- 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)))
- {
- op = (UINT32)m_program->read_word(m_shifted_pc + 2);
+ 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)))
+ {
+ op = (UINT32)m_program->read_word(m_shifted_pc + 2);
opcycles = is_long_opcode(op) ? 3 : 2;
- m_pc += is_long_opcode(op) ? 2 : 1;
+ m_pc += is_long_opcode(op) ? 2 : 1;
+ }
+ break;
+ case 0x0c00:
+ case 0x0d00:
+ case 0x0e00:
+ case 0x0f00: // MUL Rd,Rr
+ sd = (UINT8)m_r[RD5(op)] * (UINT8)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;
+ }
+ 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)((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff));
+ m_pc += offs;
+ opcycles = 2;
+ break;
+ case 0xd000: // RCALL k
+ offs = (INT32)((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)(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)(KCONST7(op));
+ if(offs & 0x40)
+ {
+ offs |= 0xffffff80;
+ }
+ m_pc += offs;
+ opcycles = 2;
}
- break;
- case 0x0c00:
- case 0x0d00:
- case 0x0e00:
- case 0x0f00: // MUL Rd,Rr
- sd = (UINT8)m_r[RD5(op)] * (UINT8)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;
- }
- 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)((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff));
- m_pc += offs;
- opcycles = 2;
- break;
- case 0xd000: // RCALL k
- offs = (INT32)((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)(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)(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)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)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++;
-
- m_shifted_pc = m_pc << 1;
-
- m_icount -= opcycles;
+ 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)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)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++;
+
+ m_shifted_pc = m_pc << 1;
+
+ m_icount -= opcycles;
timer_tick(opcycles);
- }
+ }
}