diff options
author | 2020-07-14 07:26:41 +0200 | |
---|---|---|
committer | 2020-07-14 07:27:28 +0200 | |
commit | e04f490e4b0a7bc5ed9c212663facaf8195c96f4 (patch) | |
tree | 6d21ead0db392df77748f245157a4434dd3d4770 /src/devices/cpu/avr8 | |
parent | 735752cea8c83134f3dc0046af2457d3305442ce (diff) |
-avr8: Fixed assorted Timer 0 and Timer 1 bugs. [Ryan Holtz]
-avr8dasm: Fixed erroneous disassembly of CBI, SBI, SBIS, and SBIC opcodes. [Ryan Holtz]
New working machines
--------------------
Power Ninja Action Challenge [Ryan Holtz]
Diffstat (limited to 'src/devices/cpu/avr8')
-rw-r--r-- | src/devices/cpu/avr8/avr8.cpp | 134 | ||||
-rw-r--r-- | src/devices/cpu/avr8/avr8dasm.cpp | 1027 |
2 files changed, 583 insertions, 578 deletions
diff --git a/src/devices/cpu/avr8/avr8.cpp b/src/devices/cpu/avr8/avr8.cpp index 69096da7059..013ac8db6f6 100644 --- a/src/devices/cpu/avr8/avr8.cpp +++ b/src/devices/cpu/avr8/avr8.cpp @@ -92,7 +92,7 @@ #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) + | LOG_OSC | LOG_PINCHG | LOG_EXTMEM | LOG_ADC | LOG_DIGINPUT | LOG_ASYNC | LOG_TWI | LOG_UART) #define VERBOSE (0) #include "logmacro.h" @@ -870,6 +870,7 @@ void avr8_device::device_start() // Misc. save_item(NAME(m_addr_mask)); save_item(NAME(m_interrupt_pending)); + save_item(NAME(m_opcycles)); // set our instruction counter set_icountptr(m_icount); @@ -1040,7 +1041,6 @@ inline uint8_t avr8_device::pop() void avr8_device::set_irq_line(uint16_t vector, int state) { - // Horrible hack, not accurate if (state) { if (SREG_R(AVR8_SREG_I)) @@ -1058,17 +1058,16 @@ void avr8_device::set_irq_line(uint16_t vector, int state) } } -class CInterruptCondition +struct interrupt_condition { - public: - uint8_t m_intindex; - uint8_t m_intreg; - uint8_t m_intmask; - uint8_t m_regindex; - uint8_t m_regmask; + uint8_t m_intindex; + uint8_t m_intreg; + uint8_t m_intmask; + uint8_t m_regindex; + uint8_t m_regmask; }; -static const CInterruptCondition s_int_conditions[AVR8_INTIDX_COUNT] = +static const interrupt_condition s_int_conditions[AVR8_INTIDX_COUNT] = { { AVR8_INT_SPI_STC, AVR8_REGIDX_SPCR, AVR8_SPCR_SPIE_MASK, AVR8_REGIDX_SPSR, AVR8_SPSR_SPIF_MASK }, { AVR8_INT_T0COMPB, AVR8_REGIDX_TIMSK0, AVR8_TIMSK0_OCIE0B_MASK, AVR8_REGIDX_TIFR0, AVR8_TIFR0_OCF0B_MASK }, @@ -1085,7 +1084,7 @@ static const CInterruptCondition s_int_conditions[AVR8_INTIDX_COUNT] = void avr8_device::update_interrupt(int source) { - const CInterruptCondition &condition = s_int_conditions[source]; + const interrupt_condition &condition = s_int_conditions[source]; int intstate = 0; if (m_r[condition.m_intreg] & condition.m_intmask) @@ -1101,7 +1100,7 @@ void avr8_device::update_interrupt(int source) void atmega328_device::update_interrupt(int source) { - const CInterruptCondition &condition = s_int_conditions[source]; + const interrupt_condition &condition = s_int_conditions[source]; int intstate = 0; if (m_r[condition.m_intreg] & condition.m_intmask) @@ -1115,7 +1114,7 @@ void atmega328_device::update_interrupt(int source) } } -static const CInterruptCondition s_mega644_int_conditions[AVR8_INTIDX_COUNT] = +static const interrupt_condition s_mega644_int_conditions[AVR8_INTIDX_COUNT] = { { ATMEGA644_INT_SPI_STC, AVR8_REGIDX_SPCR, AVR8_SPCR_SPIE_MASK, AVR8_REGIDX_SPSR, AVR8_SPSR_SPIF_MASK }, { ATMEGA644_INT_T0COMPB, AVR8_REGIDX_TIMSK0, AVR8_TIMSK0_OCIE0B_MASK, AVR8_REGIDX_TIFR0, AVR8_TIFR0_OCF0B_MASK }, @@ -1132,7 +1131,7 @@ static const CInterruptCondition s_mega644_int_conditions[AVR8_INTIDX_COUNT] = void atmega644_device::update_interrupt(int source) { - const CInterruptCondition &condition = s_mega644_int_conditions[source]; + const interrupt_condition &condition = s_mega644_int_conditions[source]; int intstate = 0; if (m_r[condition.m_intreg] & condition.m_intmask) @@ -1149,7 +1148,7 @@ void atmega644_device::update_interrupt(int source) //TODO: review this! void atmega1280_device::update_interrupt(int source) { - const CInterruptCondition &condition = s_mega644_int_conditions[source]; + const interrupt_condition &condition = s_mega644_int_conditions[source]; int intstate = 0; if (m_r[condition.m_intreg] & condition.m_intmask) @@ -1166,7 +1165,7 @@ void atmega1280_device::update_interrupt(int source) //TODO: review this! void atmega2560_device::update_interrupt(int source) { - const CInterruptCondition &condition = s_mega644_int_conditions[source]; + const interrupt_condition &condition = s_mega644_int_conditions[source]; int intstate = 0; if (m_r[condition.m_intreg] & condition.m_intmask) @@ -1224,20 +1223,17 @@ void avr8_device::timer_tick() } } -// uint8_t ocr0[2] = { m_r[AVR8_REGIDX_OCR0A], m_r[AVR8_REGIDX_OCR0B] }; -//TODO uint8_t ocf0[2] = { (1 << AVR8_TIFR0_OCF0A_SHIFT), (1 << AVR8_TIFR4_OCF0B_SHIFT) }; -//TODO uint8_t int0[2] = { AVR8_INTIDX_OCF0A, AVR8_INTIDX_OCF0B }; - -#define LOG_TIMER_0 0 -#define LOG_TIMER_5 0 // Timer 0 Handling void avr8_device::timer0_tick() { + static const uint8_t s_ocf0[2] = { (1 << AVR8_TIFR0_OCF0A_SHIFT), (1 << AVR8_TIFR0_OCF0B_SHIFT) }; + static const uint8_t s_int0[2] = { AVR8_INTIDX_OCF0A, AVR8_INTIDX_OCF0B }; + 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]; + count++; switch (AVR8_WGM0) { @@ -1253,10 +1249,16 @@ void avr8_device::timer0_tick() switch (AVR8_TCCR0A_COM0B) { case 0: /* Normal Operation */ - if (count == m_timer_top[0]) + if (count == AVR8_OCR0A) { - LOGMASKED(LOG_TIMER0, "%s: timer0: Set normal OC0B behavior\n", machine().describe_context()); - m_timer_top[0] = 0; + m_r[AVR8_REGIDX_TIFR0] |= s_ocf0[AVR8_REG_A]; + update_interrupt(s_int0[AVR8_REG_A]); + count = 0; + } + else if (count == AVR8_OCR0B) + { + m_r[AVR8_REGIDX_TIFR0] |= s_ocf0[AVR8_REG_B]; + update_interrupt(s_int0[AVR8_REG_B]); } break; @@ -1290,26 +1292,23 @@ void avr8_device::timer0_tick() break; case WGM02_FAST_PWM: - LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: WGM02_FAST_PWM: Unimplemented timer0 waveform generation mode\n", machine().describe_context()); - break; + LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: WGM02_FAST_PWM: Unimplemented timer0 waveform generation mode\n", machine().describe_context()); + 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; + 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: - LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: WGM02_FAST_PWM_CMP: Unimplemented timer0 waveform generation mode\n", machine().describe_context()); - break; + LOGMASKED(LOG_TIMER0 | LOG_UNKNOWN, "%s: WGM02_FAST_PWM_CMP: Unimplemented timer0 waveform generation mode\n", machine().describe_context()); + 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; - - count += increment; - m_r[AVR8_REGIDX_TCNT0] = count & 0xff; + m_r[AVR8_REGIDX_TCNT0] = count; } void avr8_device::changed_tccr0a(uint8_t data) @@ -1379,11 +1378,15 @@ inline void avr8_device::timer1_tick() static const uint8_t s_int1[2] = { AVR8_INTIDX_OCF1A, AVR8_INTIDX_OCF1B }; int32_t increment = m_timer_increment[1]; + LOGMASKED(LOG_TIMER1_TICK, "%s: AVR8_WGM1: %d\n", machine().describe_context(), AVR8_WGM1); + for (int32_t reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++) { switch (m_wgm1) { case WGM1_CTC_OCR: + LOGMASKED(LOG_TIMER1_TICK, "%s: timer1_count: %04x\n", machine().describe_context(), m_timer1_count); + LOGMASKED(LOG_TIMER1_TICK, "%s: OCR1%c: %04x\n", machine().describe_context(), reg ? 'A' : 'B', m_ocr1[reg]); if (m_timer1_count == 0xffff) { m_r[AVR8_REGIDX_TIFR1] |= AVR8_TIFR1_TOV1_MASK; @@ -1409,9 +1412,6 @@ inline void avr8_device::timer1_tick() m_r[AVR8_REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK; update_interrupt(AVR8_INTIDX_TOV1); } - - m_r[AVR8_REGIDX_TIFR1] &= ~s_ocf1[reg]; - update_interrupt(s_int1[reg]); } break; @@ -1882,7 +1882,7 @@ void avr8_device::update_timer_clock_source(uint8_t t, uint8_t clock_select) }; m_timer_prescale[t] = s_prescale_values[(t == 2) ? 1 : 0][clock_select]; - LOGMASKED((LOG_TIMER0 + t), "%s: update_timer_clock_source: t = %d, cs = %d\n", t, machine().describe_context(), clock_select); + LOGMASKED((LOG_TIMER0 + t), "%s: update_timer_clock_source: t = %d, cs = %d\n", machine().describe_context(), t, clock_select); if (m_timer_prescale[t] == 0xffff) { @@ -2250,56 +2250,67 @@ void avr8_device::regs_w(offs_t offset, uint8_t data) break; case AVR8_REGIDX_PORTA: + LOGMASKED(LOG_GPIO, "%s: PORTA Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTA, data); m_r[AVR8_REGIDX_PORTA] = data; break; case AVR8_REGIDX_PORTB: + LOGMASKED(LOG_GPIO, "%s: PORTB Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTB, data); m_r[AVR8_REGIDX_PORTB] = data; break; case AVR8_REGIDX_PORTC: + LOGMASKED(LOG_GPIO, "%s: PORTC Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTC, data); m_r[AVR8_REGIDX_PORTC] = data; break; case AVR8_REGIDX_PORTD: + LOGMASKED(LOG_GPIO, "%s: PORTD Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTD, data); m_r[AVR8_REGIDX_PORTD] = data; break; case AVR8_REGIDX_PORTE: + LOGMASKED(LOG_GPIO, "%s: PORTE Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTE, data); m_r[AVR8_REGIDX_PORTE] = data; break; case AVR8_REGIDX_PORTF: + LOGMASKED(LOG_GPIO, "%s: PORTF Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTF, data); m_r[AVR8_REGIDX_PORTF] = data; break; case AVR8_REGIDX_PORTG: + LOGMASKED(LOG_GPIO, "%s: PORTG Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTG, data); m_r[AVR8_REGIDX_PORTG] = data; break; case AVR8_REGIDX_PORTH: + LOGMASKED(LOG_GPIO, "%s: PORTH Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTH, data); m_r[AVR8_REGIDX_PORTH] = data; break; case AVR8_REGIDX_PORTJ: + LOGMASKED(LOG_GPIO, "%s: PORTJ Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTJ, data); m_r[AVR8_REGIDX_PORTJ] = data; break; case AVR8_REGIDX_PORTK: + LOGMASKED(LOG_GPIO, "%s: PORTK Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTK, data); m_r[AVR8_REGIDX_PORTK] = data; break; case AVR8_REGIDX_PORTL: + LOGMASKED(LOG_GPIO, "%s: PORTL Write: %02x\n", machine().describe_context(), data); m_io->write_byte(AVR8_IO_PORTL, data); m_r[AVR8_REGIDX_PORTL] = data; break; @@ -2327,12 +2338,12 @@ void avr8_device::regs_w(offs_t offset, uint8_t data) case AVR8_REGIDX_OCR0A: LOGMASKED(LOG_TIMER0, "%s: OCR0A = %02x\n", machine().describe_context(), data); - update_ocr0(AVR8_OCR0A, AVR8_REG_A); + update_ocr0(data, AVR8_REG_A); break; case AVR8_REGIDX_OCR0B: LOGMASKED(LOG_TIMER0, "%s: OCR0B = %02x\n", machine().describe_context(), data); - update_ocr0(AVR8_OCR0B, AVR8_REG_B); + update_ocr0(data, AVR8_REG_B); break; case AVR8_REGIDX_TIFR0: @@ -2408,7 +2419,12 @@ void avr8_device::regs_w(offs_t offset, uint8_t data) break; case AVR8_REGIDX_GPIOR1: + LOGMASKED(LOG_GPIO, "%s: GPIOR1 Write: %02x\n", machine().describe_context(), data); + m_r[offset] = data; + break; + case AVR8_REGIDX_GPIOR2: + LOGMASKED(LOG_GPIO, "%s: GPIOR2 Write: %02x\n", machine().describe_context(), data); m_r[offset] = data; break; @@ -2813,6 +2829,8 @@ void avr8_device::regs_w(offs_t offset, uint8_t data) uint8_t avr8_device::regs_r(offs_t offset) { + uint8_t data = m_r[offset]; + switch (offset) { case AVR8_REGIDX_R0: @@ -2847,7 +2865,7 @@ uint8_t avr8_device::regs_r(offs_t offset) case AVR8_REGIDX_R29: case AVR8_REGIDX_R30: case AVR8_REGIDX_R31: - return m_r[offset]; + return data; case AVR8_REGIDX_PINA: // TODO: account for DDRA @@ -2904,7 +2922,7 @@ uint8_t avr8_device::regs_r(offs_t offset) case AVR8_REGIDX_PORTJ: case AVR8_REGIDX_PORTK: case AVR8_REGIDX_PORTL: - return m_r[offset]; + return data; case AVR8_REGIDX_DDRA: case AVR8_REGIDX_DDRB: @@ -2917,19 +2935,25 @@ uint8_t avr8_device::regs_r(offs_t offset) case AVR8_REGIDX_DDRJ: case AVR8_REGIDX_DDRK: case AVR8_REGIDX_DDRL: - return m_r[offset]; + return data; // EEPROM registers case AVR8_REGIDX_EECR: case AVR8_REGIDX_EEDR: - return m_r[offset]; + return data; // Miscellaneous registers // TODO: Implement readback for all applicable registers. case AVR8_REGIDX_GPIOR0: + LOGMASKED(LOG_GPIO, "%s: GPIOR0 Read: %02x\n", machine().describe_context(), data); + return data; case AVR8_REGIDX_GPIOR1: + LOGMASKED(LOG_GPIO, "%s: GPIOR1 Read: %02x\n", machine().describe_context(), data); + return data; case AVR8_REGIDX_GPIOR2: + LOGMASKED(LOG_GPIO, "%s: GPIOR2 Read: %02x\n", machine().describe_context(), data); + return data; // 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 @@ -2939,12 +2963,26 @@ uint8_t avr8_device::regs_r(offs_t offset) case AVR8_REGIDX_SPH: case AVR8_REGIDX_SREG: case AVR8_REGIDX_TIMSK0: + LOGMASKED(LOG_TIMER0, "%s: TIMSK0 Read: %02x\n", machine().describe_context(), data); + return data; case AVR8_REGIDX_TIMSK1: + LOGMASKED(LOG_TIMER1, "%s: TIMSK1 Read: %02x\n", machine().describe_context(), data); + return data; case AVR8_REGIDX_TIMSK2: -// case AVR8_REGIDX_TIMSK3: // TODO: needed for Replicator 1 + LOGMASKED(LOG_TIMER2, "%s: TIMSK2 Read: %02x\n", machine().describe_context(), data); + return data; + case AVR8_REGIDX_TIMSK3: + LOGMASKED(LOG_TIMER3, "%s: TIMSK3 Read: %02x\n", machine().describe_context(), data); + return data; case AVR8_REGIDX_TIMSK4: + LOGMASKED(LOG_TIMER4, "%s: TIMSK4 Read: %02x\n", machine().describe_context(), data); + return data; case AVR8_REGIDX_TIMSK5: - return m_r[offset]; + LOGMASKED(LOG_TIMER5, "%s: TIMSK5 Read: %02x\n", machine().describe_context(), data); + return data; + case AVR8_REGIDX_TIFR1: + //LOGMASKED(LOG_TIMER0, "%s: TIFR1 Read: %02x\n", machine().describe_context(), data); + return data; // Two-wire registers case AVR8_REGIDX_TWCR: diff --git a/src/devices/cpu/avr8/avr8dasm.cpp b/src/devices/cpu/avr8/avr8dasm.cpp index 5f47198c425..3fed61c55fa 100644 --- a/src/devices/cpu/avr8/avr8dasm.cpp +++ b/src/devices/cpu/avr8/avr8dasm.cpp @@ -106,572 +106,539 @@ offs_t avr8_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat switch(op & 0xf000) { + case 0x0000: + switch(op & 0x0f00) + { case 0x0000: - switch(op & 0x0f00) + util::stream_format(stream, "NOP"); + break; + case 0x0100: + util::stream_format(stream, "MOVW R%d:R%d, R%d:R%d", (RD4(op) << 1)+1, RD4(op) << 1, (RR4(op) << 1)+1, RR4(op) << 1); + break; + case 0x0200: + util::stream_format(stream, "MULS R%d, R%d", 16+RD4(op), 16+RR4(op)); + break; + case 0x0300: + switch(MULCONST2(op)) { - case 0x0000: - util::stream_format(stream, "NOP"); - break; - case 0x0100: - util::stream_format(stream, "MOVW R%d:R%d, R%d:R%d", (RD4(op) << 1)+1, RD4(op) << 1, (RR4(op) << 1)+1, RR4(op) << 1); - break; - case 0x0200: - util::stream_format(stream, "MULS R%d, R%d", 16+RD4(op), 16+RR4(op)); - break; - case 0x0300: - switch(MULCONST2(op)) - { - case 0: - util::stream_format(stream, "MULSU R%d, R%d", 16+RD3(op), 16+RR3(op)); - break; - case 1: - util::stream_format(stream, "FMUL R%d, R%d", 16+RD3(op), 16+RR3(op)); - break; - case 2: - util::stream_format(stream, "FMULS R%d, R%d", 16+RD3(op), 16+RR3(op)); - break; - case 3: - util::stream_format(stream, "FMULSU R%d, R%d", 16+RD3(op), 16+RR3(op)); - break; - } - break; - case 0x0400: - case 0x0500: - case 0x0600: - case 0x0700: - util::stream_format(stream, "CPC R%d, R%d", RD5(op), RR5(op)); - break; - case 0x0800: - case 0x0900: - case 0x0a00: - case 0x0b00: - util::stream_format(stream, "SBC R%d, R%d", RD5(op), RR5(op)); - break; - case 0x0c00: - case 0x0d00: - case 0x0e00: - case 0x0f00: - util::stream_format(stream, "ADD R%d, R%d", RD5(op), RR5(op)); - break; + case 0: + util::stream_format(stream, "MULSU R%d, R%d", 16+RD3(op), 16+RR3(op)); + break; + case 1: + util::stream_format(stream, "FMUL R%d, R%d", 16+RD3(op), 16+RR3(op)); + break; + case 2: + util::stream_format(stream, "FMULS R%d, R%d", 16+RD3(op), 16+RR3(op)); + break; + case 3: + util::stream_format(stream, "FMULSU R%d, R%d", 16+RD3(op), 16+RR3(op)); + break; } break; - case 0x1000: - switch(op & 0x0c00) + case 0x0400: + case 0x0500: + case 0x0600: + case 0x0700: + util::stream_format(stream, "CPC R%d, R%d", RD5(op), RR5(op)); + break; + case 0x0800: + case 0x0900: + case 0x0a00: + case 0x0b00: + util::stream_format(stream, "SBC R%d, R%d", RD5(op), RR5(op)); + break; + case 0x0c00: + case 0x0d00: + case 0x0e00: + case 0x0f00: + util::stream_format(stream, "ADD R%d, R%d", RD5(op), RR5(op)); + break; + } + break; + case 0x1000: + switch(op & 0x0c00) + { + case 0x0000: + util::stream_format(stream, "CPSE R%d, R%d", RD5(op), RR5(op)); + break; + case 0x0400: + util::stream_format(stream, "CP R%d, R%d", RD5(op), RR5(op)); + break; + case 0x0800: + util::stream_format(stream, "SUB R%d, R%d", RD5(op), RR5(op)); + break; + case 0x0c00: + util::stream_format(stream, "ADC R%d, R%d", RD5(op), RR5(op)); + break; + } + break; + case 0x2000: + switch(op & 0x0c00) + { + case 0x0000: + util::stream_format(stream, "AND R%d, R%d", RD5(op), RR5(op)); + break; + case 0x0400: + util::stream_format(stream, "EOR R%d, R%d", RD5(op), RR5(op)); + break; + case 0x0800: + util::stream_format(stream, "OR R%d, R%d", RD5(op), RR5(op)); + break; + case 0x0c00: + util::stream_format(stream, "MOV R%d, R%d", RD5(op), RR5(op)); + break; + } + break; + case 0x3000: + util::stream_format(stream, "CPI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); + break; + case 0x4000: + util::stream_format(stream, "SBCI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); + break; + case 0x5000: + util::stream_format(stream, "SUBI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); + break; + case 0x6000: + util::stream_format(stream, "ORI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); + break; + case 0x7000: + util::stream_format(stream, "ANDI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); + break; + case 0x8000: + case 0xa000: + switch(op & 0x0208) + { + case 0x0000: + util::stream_format(stream, "LD(D) R%d, Z+%02x", RD5(op), QCONST6(op)); + break; + case 0x0008: + util::stream_format(stream, "LD(D) R%d, Y+%02x", RD5(op), QCONST6(op)); + break; + case 0x0200: + util::stream_format(stream, "ST(D) Z+%02x, R%d", QCONST6(op), RD5(op)); + break; + case 0x0208: + util::stream_format(stream, "ST(D) Y+%02x, R%d", QCONST6(op), RD5(op)); + break; + } + break; + case 0x9000: + switch(op & 0x0f00) + { + case 0x0000: + case 0x0100: + switch(op & 0x000f) + { + case 0x0000: + op <<= 16; + op |= opcodes.r16(pc); + pc += 2; + util::stream_format(stream, "LDS R%d, (0x%04x)", RD5(op >> 16), op & 0x0000ffff); + break; + case 0x0001: + util::stream_format(stream, "LD R%d, Z+", RD5(op)); + break; + case 0x0002: + util::stream_format(stream, "LD R%d,-Z", RD5(op)); + break; + case 0x0004: + util::stream_format(stream, "LPM R%d, Z", RD5(op)); + break; + case 0x0005: + util::stream_format(stream, "LPM R%d, Z+", RD5(op)); + break; + case 0x0006: + util::stream_format(stream, "ELPM R%d, Z", RD5(op)); + break; + case 0x0007: + util::stream_format(stream, "ELPM R%d, Z+", RD5(op)); + break; + case 0x0009: + util::stream_format(stream, "LD R%d, Y+", RD5(op)); + break; + case 0x000a: + util::stream_format(stream, "LD R%d,-Y", RD5(op)); + break; + case 0x000c: + util::stream_format(stream, "LD R%d, X", RD5(op)); + break; + case 0x000d: + util::stream_format(stream, "LD R%d, X+", RD5(op)); + break; + case 0x000e: + util::stream_format(stream, "LD R%d,-X", RD5(op)); + break; + case 0x000f: + util::stream_format(stream, "POP R%d", RD5(op)); + break; + default: + util::stream_format(stream, "Undefined (%08x)", op); + break; + } + break; + case 0x0200: + case 0x0300: + switch(op & 0x000f) + { + case 0x0000: + op <<= 16; + op |= opcodes.r16(pc); + pc += 2; + util::stream_format(stream, "STS (0x%04x), R%d", op & 0x0000ffff, RD5(op >> 16)); + break; + case 0x0001: + util::stream_format(stream, "ST Z+, R%d", RD5(op)); + break; + case 0x0002: + util::stream_format(stream, "ST -Z , R%d", RD5(op)); + break; + case 0x0009: + util::stream_format(stream, "ST Y+, R%d", RD5(op)); + break; + case 0x000a: + util::stream_format(stream, "ST -Y , R%d", RD5(op)); + break; + case 0x000c: + util::stream_format(stream, "ST X , R%d", RD5(op)); + break; + case 0x000d: + util::stream_format(stream, "ST X+, R%d", RD5(op)); + break; + case 0x000e: + util::stream_format(stream, "ST -X , R%d", RD5(op)); + break; + case 0x000f: + util::stream_format(stream, "PUSH R%d", RD5(op)); + break; + default: + util::stream_format(stream, "Undefined (%08x)", op); + break; + } + break; + case 0x0400: + switch(op & 0x000f) { + case 0x0000: + util::stream_format(stream, "COM R%d", RD5(op)); + break; + case 0x0001: + util::stream_format(stream, "NEG R%d", RD5(op)); + break; + case 0x0002: + util::stream_format(stream, "SWAP R%d", RD5(op)); + break; + case 0x0003: + util::stream_format(stream, "INC R%d", RD5(op)); + break; + case 0x0005: + util::stream_format(stream, "ASR R%d", RD5(op)); + break; + case 0x0006: + util::stream_format(stream, "LSR R%d", RD5(op)); + break; + case 0x0007: + util::stream_format(stream, "ROR R%d", RD5(op)); + break; + case 0x0008: + switch(op & 0x00f0) + { case 0x0000: - util::stream_format(stream, "CPSE R%d, R%d", RD5(op), RR5(op)); + util::stream_format(stream, "SEC"); break; - case 0x0400: - util::stream_format(stream, "CP R%d, R%d", RD5(op), RR5(op)); + case 0x0010: + util::stream_format(stream, "SEZ"); break; - case 0x0800: - util::stream_format(stream, "SUB R%d, R%d", RD5(op), RR5(op)); + case 0x0020: + util::stream_format(stream, "SEN"); break; - case 0x0c00: - util::stream_format(stream, "ADC R%d, R%d", RD5(op), RR5(op)); + case 0x0030: + util::stream_format(stream, "SEV"); break; - } - break; - case 0x2000: - switch(op & 0x0c00) - { - case 0x0000: - util::stream_format(stream, "AND R%d, R%d", RD5(op), RR5(op)); + case 0x0040: + util::stream_format(stream, "SES"); break; - case 0x0400: - util::stream_format(stream, "EOR R%d, R%d", RD5(op), RR5(op)); + case 0x0050: + util::stream_format(stream, "SEH"); break; - case 0x0800: - util::stream_format(stream, "OR R%d, R%d", RD5(op), RR5(op)); + case 0x0060: + util::stream_format(stream, "SET"); break; - case 0x0c00: - util::stream_format(stream, "MOV R%d, R%d", RD5(op), RR5(op)); + case 0x0070: + util::stream_format(stream, "SEI"); break; - } - break; - case 0x3000: - util::stream_format(stream, "CPI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); - break; - case 0x4000: - util::stream_format(stream, "SBCI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); - break; - case 0x5000: - util::stream_format(stream, "SUBI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); - break; - case 0x6000: - util::stream_format(stream, "ORI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); - break; - case 0x7000: - util::stream_format(stream, "ANDI R%d, 0x%02x", 16+RD4(op), KCONST8(op)); - break; - case 0x8000: - case 0xa000: - switch(op & 0x0208) - { - case 0x0000: - util::stream_format(stream, "LD(D) R%d, Z+%02x", RD5(op), QCONST6(op)); + case 0x0080: + util::stream_format(stream, "CLC"); + break; + case 0x0090: + util::stream_format(stream, "CLZ"); break; - case 0x0008: - util::stream_format(stream, "LD(D) R%d, Y+%02x", RD5(op), QCONST6(op)); + case 0x00a0: + util::stream_format(stream, "CLN"); break; - case 0x0200: - util::stream_format(stream, "ST(D) Z+%02x, R%d", QCONST6(op), RD5(op)); + case 0x00b0: + util::stream_format(stream, "CLV"); break; - case 0x0208: - util::stream_format(stream, "ST(D) Y+%02x, R%d", QCONST6(op), RD5(op)); + case 0x00c0: + util::stream_format(stream, "CLS"); break; + case 0x00d0: + util::stream_format(stream, "CLH"); + break; + case 0x00e0: + util::stream_format(stream, "CLT"); + break; + case 0x00f0: + util::stream_format(stream, "CLI"); + break; + default: + util::stream_format(stream, "Undefined (%08x)", op); + break; + } + break; + case 0x0009: + switch(op & 0x00f0) + { + case 0x0000: + util::stream_format(stream, "IJMP"); + break; + case 0x0010: + util::stream_format(stream, "EIJMP"); + break; + default: + util::stream_format(stream, "Undefined (%08x)", op); + break; + } + break; + case 0x000a: + util::stream_format(stream, "DEC R%d", RD5(op)); + break; + case 0x000c: + case 0x000d: + addr = KCONST22(op) << 16; + addr |= opcodes.r16(pc); + pc += 2; + util::stream_format(stream, "JMP 0x%06x", addr << 1); + break; + case 0x000e: + case 0x000f: + addr = KCONST22(op) << 16; + addr |= opcodes.r16(pc); + pc += 2; + util::stream_format(stream, "CALL 0x%06x", addr << 1); + break; + default: + util::stream_format(stream, "Undefined (%08x)", op); + break; } break; - case 0x9000: - switch(op & 0x0f00) + case 0x0500: + switch(op & 0x000f) { + case 0x0000: + util::stream_format(stream, "COM R%d", RD5(op)); + break; + case 0x0001: + util::stream_format(stream, "NEG R%d", RD5(op)); + break; + case 0x0002: + util::stream_format(stream, "SWAP R%d", RD5(op)); + break; + case 0x0003: + util::stream_format(stream, "INC R%d", RD5(op)); + break; + case 0x0005: + util::stream_format(stream, "ASR R%d", RD5(op)); + break; + case 0x0006: + util::stream_format(stream, "LSR R%d", RD5(op)); + break; + case 0x0007: + util::stream_format(stream, "ROR R%d", RD5(op)); + break; + case 0x0008: + switch(op & 0x00f0) + { case 0x0000: - case 0x0100: - switch(op & 0x000f) - { - case 0x0000: - op <<= 16; - op |= opcodes.r16(pc); - pc += 2; - util::stream_format(stream, "LDS R%d, (0x%04x)", RD5(op >> 16), op & 0x0000ffff); - break; - case 0x0001: - util::stream_format(stream, "LD R%d, Z+", RD5(op)); - break; - case 0x0002: - util::stream_format(stream, "LD R%d,-Z", RD5(op)); - break; - case 0x0004: - util::stream_format(stream, "LPM R%d, Z", RD5(op)); - break; - case 0x0005: - util::stream_format(stream, "LPM R%d, Z+", RD5(op)); - break; - case 0x0006: - util::stream_format(stream, "ELPM R%d, Z", RD5(op)); - break; - case 0x0007: - util::stream_format(stream, "ELPM R%d, Z+", RD5(op)); - break; - case 0x0009: - util::stream_format(stream, "LD R%d, Y+", RD5(op)); - break; - case 0x000a: - util::stream_format(stream, "LD R%d,-Y", RD5(op)); - break; - case 0x000c: - util::stream_format(stream, "LD R%d, X", RD5(op)); - break; - case 0x000d: - util::stream_format(stream, "LD R%d, X+", RD5(op)); - break; - case 0x000e: - util::stream_format(stream, "LD R%d,-X", RD5(op)); - break; - case 0x000f: - util::stream_format(stream, "POP R%d", RD5(op)); - break; - default: - util::stream_format(stream, "Undefined (%08x)", op); - break; - } - break; - case 0x0200: - case 0x0300: - switch(op & 0x000f) - { - case 0x0000: - op <<= 16; - op |= opcodes.r16(pc); - pc += 2; - util::stream_format(stream, "STS (0x%04x), R%d", op & 0x0000ffff, RD5(op >> 16)); - break; - case 0x0001: - util::stream_format(stream, "ST Z+, R%d", RD5(op)); - break; - case 0x0002: - util::stream_format(stream, "ST -Z , R%d", RD5(op)); - break; - case 0x0009: - util::stream_format(stream, "ST Y+, R%d", RD5(op)); - break; - case 0x000a: - util::stream_format(stream, "ST -Y , R%d", RD5(op)); - break; - case 0x000c: - util::stream_format(stream, "ST X , R%d", RD5(op)); - break; - case 0x000d: - util::stream_format(stream, "ST X+, R%d", RD5(op)); - break; - case 0x000e: - util::stream_format(stream, "ST -X , R%d", RD5(op)); - break; - case 0x000f: - util::stream_format(stream, "PUSH R%d", RD5(op)); - break; - default: - util::stream_format(stream, "Undefined (%08x)", op); - break; - } - break; - case 0x0400: - switch(op & 0x000f) - { - case 0x0000: - util::stream_format(stream, "COM R%d", RD5(op)); - break; - case 0x0001: - util::stream_format(stream, "NEG R%d", RD5(op)); - break; - case 0x0002: - util::stream_format(stream, "SWAP R%d", RD5(op)); - break; - case 0x0003: - util::stream_format(stream, "INC R%d", RD5(op)); - break; - case 0x0005: - util::stream_format(stream, "ASR R%d", RD5(op)); - break; - case 0x0006: - util::stream_format(stream, "LSR R%d", RD5(op)); - break; - case 0x0007: - util::stream_format(stream, "ROR R%d", RD5(op)); - break; - case 0x0008: - switch(op & 0x00f0) - { - case 0x0000: - util::stream_format(stream, "SEC"); - break; - case 0x0010: - util::stream_format(stream, "SEZ"); - break; - case 0x0020: - util::stream_format(stream, "SEN"); - break; - case 0x0030: - util::stream_format(stream, "SEV"); - break; - case 0x0040: - util::stream_format(stream, "SES"); - break; - case 0x0050: - util::stream_format(stream, "SEH"); - break; - case 0x0060: - util::stream_format(stream, "SET"); - break; - case 0x0070: - util::stream_format(stream, "SEI"); - break; - case 0x0080: - util::stream_format(stream, "CLC"); - break; - case 0x0090: - util::stream_format(stream, "CLZ"); - break; - case 0x00a0: - util::stream_format(stream, "CLN"); - break; - case 0x00b0: - util::stream_format(stream, "CLV"); - break; - case 0x00c0: - util::stream_format(stream, "CLS"); - break; - case 0x00d0: - util::stream_format(stream, "CLH"); - break; - case 0x00e0: - util::stream_format(stream, "CLT"); - break; - case 0x00f0: - util::stream_format(stream, "CLI"); - break; - default: - util::stream_format(stream, "Undefined (%08x)", op); - break; - } - break; - case 0x0009: - switch(op & 0x00f0) - { - case 0x0000: - util::stream_format(stream, "IJMP"); - break; - case 0x0010: - util::stream_format(stream, "EIJMP"); - break; - default: - util::stream_format(stream, "Undefined (%08x)", op); - break; - } - break; - case 0x000a: - util::stream_format(stream, "DEC R%d", RD5(op)); - break; - case 0x000c: - case 0x000d: - addr = KCONST22(op) << 16; - addr |= opcodes.r16(pc); - pc += 2; - util::stream_format(stream, "JMP 0x%06x", addr << 1); - break; - case 0x000e: - case 0x000f: - addr = KCONST22(op) << 16; - addr |= opcodes.r16(pc); - pc += 2; - util::stream_format(stream, "CALL 0x%06x", addr << 1); - break; - default: - util::stream_format(stream, "Undefined (%08x)", op); - break; - } - break; - case 0x0500: - switch(op & 0x000f) - { - case 0x0000: - util::stream_format(stream, "COM R%d", RD5(op)); - break; - case 0x0001: - util::stream_format(stream, "NEG R%d", RD5(op)); - break; - case 0x0002: - util::stream_format(stream, "SWAP R%d", RD5(op)); - break; - case 0x0003: - util::stream_format(stream, "INC R%d", RD5(op)); - break; - case 0x0005: - util::stream_format(stream, "ASR R%d", RD5(op)); - break; - case 0x0006: - util::stream_format(stream, "LSR R%d", RD5(op)); - break; - case 0x0007: - util::stream_format(stream, "ROR R%d", RD5(op)); - break; - case 0x0008: - switch(op & 0x00f0) - { - case 0x0000: - util::stream_format(stream, "RET"); - break; - case 0x0010: - util::stream_format(stream, "RETI"); - break; - case 0x0080: - util::stream_format(stream, "SLEEP"); - break; - case 0x0090: - util::stream_format(stream, "BREAK"); - break; - case 0x00a0: - util::stream_format(stream, "WDR"); - break; - case 0x00c0: - util::stream_format(stream, "LPM"); - break; - case 0x00d0: - util::stream_format(stream, "ELPM"); - break; - case 0x00e0: - util::stream_format(stream, "SPM"); - break; - case 0x00f0: - util::stream_format(stream, "SPM Z+"); - break; - default: - util::stream_format(stream, "Undefined (%08x)", op); - break; - } - break; - case 0x0009: - switch(op & 0x00f0) - { - case 0x0000: - util::stream_format(stream, "ICALL"); - break; - case 0x0010: - util::stream_format(stream, "EICALL"); - break; - default: - util::stream_format(stream, "Undefined (%08x)", op); - break; - } - break; - case 0x000a: - util::stream_format(stream, "DEC R%d", RD5(op)); - break; - case 0x000c: - case 0x000d: - op <<= 16; - op |= opcodes.r16(pc); - pc += 2; - util::stream_format(stream, "JMP 0x%06x", KCONST22(op) << 1); - break; - case 0x000e: - case 0x000f: - op <<= 16; - op |= opcodes.r16(pc); - pc += 2; - util::stream_format(stream, "CALL 0x%06x", KCONST22(op) << 1); - break; - } - break; - case 0x0600: - util::stream_format(stream, "ADIW R%d:R%d, 0x%02x", 24+(RD2(op) << 1)+1, 24+(RD2(op) << 1), KCONST6(op)); - break; - case 0x0700: - util::stream_format(stream, "SBIW R%d:R%d, 0x%02x", 24+(RD2(op) << 1)+1, 24+(RD2(op) << 1), KCONST6(op)); - break; - case 0x0800: - if (ACONST5(op) < 0x20) - util::stream_format(stream, "CBI %s, %s", register_names[ACONST5(op)], register_bit_names[ACONST5(op)][RR3(op)]); - else - util::stream_format(stream, "CBI 0x%02x, %d", ACONST5(op), RR3(op)); + util::stream_format(stream, "RET"); break; - case 0x0900: - if (ACONST5(op) < 0x20) - util::stream_format(stream, "SBIC %s, %s", register_names[ACONST5(op)], register_bit_names[ACONST5(op)][RR3(op)]); - else - util::stream_format(stream, "SBIC 0x%02x, %d", ACONST5(op), RR3(op)); + case 0x0010: + util::stream_format(stream, "RETI"); break; - case 0x0a00: - if (ACONST5(op) < 0x20) - util::stream_format(stream, "SBI %s, %s", register_names[ACONST5(op)], register_bit_names[ACONST5(op)][RR3(op)]); - else - util::stream_format(stream, "SBI 0x%02x, %d", ACONST5(op), RR3(op)); + case 0x0080: + util::stream_format(stream, "SLEEP"); break; - case 0x0b00: - if (ACONST5(op) < 0x20) - util::stream_format(stream, "SBIS %s, %s", register_names[ACONST5(op)], register_bit_names[ACONST5(op)][RR3(op)]); - else - util::stream_format(stream, "SBIS 0x%02x, %d", ACONST5(op), RR3(op)); + case 0x0090: + util::stream_format(stream, "BREAK"); break; - case 0x0c00: - case 0x0d00: - case 0x0e00: - case 0x0f00: - util::stream_format(stream, "MUL R%d, R%d", RD5(op), RR5(op)); + case 0x00a0: + util::stream_format(stream, "WDR"); break; + case 0x00c0: + util::stream_format(stream, "LPM"); + break; + case 0x00d0: + util::stream_format(stream, "ELPM"); + break; + case 0x00e0: + util::stream_format(stream, "SPM"); + break; + case 0x00f0: + util::stream_format(stream, "SPM Z+"); + break; + default: + util::stream_format(stream, "Undefined (%08x)", op); + break; + } + break; + case 0x0009: + switch(op & 0x00f0) + { + case 0x0000: + util::stream_format(stream, "ICALL"); + break; + case 0x0010: + util::stream_format(stream, "EICALL"); + break; + default: + util::stream_format(stream, "Undefined (%08x)", op); + break; + } + break; + case 0x000a: + util::stream_format(stream, "DEC R%d", RD5(op)); + break; + case 0x000c: + case 0x000d: + op <<= 16; + op |= opcodes.r16(pc); + pc += 2; + util::stream_format(stream, "JMP 0x%06x", KCONST22(op) << 1); + break; + case 0x000e: + case 0x000f: + op <<= 16; + op |= opcodes.r16(pc); + pc += 2; + util::stream_format(stream, "CALL 0x%06x", KCONST22(op) << 1); + break; } break; - case 0xb000: - if(op & 0x0800) - { - if (ACONST6(op) < 0x40 ) { - util::stream_format(stream, "OUT %s, R%d", register_names[ACONST6(op)], RD5(op)); - } else { - util::stream_format(stream, "OUT 0x%02x, R%d", ACONST6(op), RD5(op)); - } - } - else - { - if (ACONST6(op) < 0x40 ) { - util::stream_format(stream, "IN R%d, %s", RD5(op), register_names[ACONST6(op)]); - } else { - util::stream_format(stream, "IN R%d, 0x%02x", RD5(op), ACONST6(op)); - } - } + case 0x0600: + util::stream_format(stream, "ADIW R%d:R%d, 0x%02x", 24+(RD2(op) << 1)+1, 24+(RD2(op) << 1), KCONST6(op)); + break; + case 0x0700: + util::stream_format(stream, "SBIW R%d:R%d, 0x%02x", 24+(RD2(op) << 1)+1, 24+(RD2(op) << 1), KCONST6(op)); + break; + case 0x0800: + util::stream_format(stream, "CBI %s, %s", register_names[ACONST5(op)], register_bit_names[ACONST5(op)][RR3(op)]); break; - case 0xc000: - //I'm not sure if this is correct. why pc + ... : pc + 8 + ... ? - util::stream_format(stream, "RJMP %08x", (((op & 0x0800) ? pc + ((op & 0x0fff) | 0xfffff000) : pc + 8 + (op & 0x0fff)) << 0)); + case 0x0900: + util::stream_format(stream, "SBIC %s, %s", register_names[ACONST5(op)], register_bit_names[ACONST5(op)][RR3(op)]); + break; + case 0x0a00: + util::stream_format(stream, "SBI %s, %s", register_names[ACONST5(op)], register_bit_names[ACONST5(op)][RR3(op)]); break; - case 0xd000: - util::stream_format(stream, "RCALL %08x", (((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff)) << 1)); + case 0x0b00: + util::stream_format(stream, "SBIS %s, %s", register_names[ACONST5(op)], register_bit_names[ACONST5(op)][RR3(op)]); + break; + case 0x0c00: + case 0x0d00: + case 0x0e00: + case 0x0f00: + util::stream_format(stream, "MUL R%d, R%d", RD5(op), RR5(op)); break; - case 0xe000: - util::stream_format(stream, "LDI R%d, 0x%02x", 16 + RD4(op), KCONST8(op)); + } + break; + case 0xb000: + if(op & 0x0800) + util::stream_format(stream, "OUT %s, R%d", register_names[ACONST6(op)], RD5(op)); + else + util::stream_format(stream, "IN R%d, %s", RD5(op), register_names[ACONST6(op)]); + break; + case 0xc000: + util::stream_format(stream, "RJMP %08x", (((op & 0x0800) ? pc + ((op & 0x0fff) | 0xfffff000) : pc + 2 + (op & 0x0fff)) << 0)); + break; + case 0xd000: + util::stream_format(stream, "RCALL %08x", (((op & 0x0800) ? ((op & 0x0fff) | 0xfffff000) : (op & 0x0fff)) << 1)); + break; + case 0xe000: + util::stream_format(stream, "LDI R%d, 0x%02x", 16 + RD4(op), KCONST8(op)); + break; + case 0xf000: + switch(op & 0x0c00) + { + case 0x0000: + switch(op & 0x0007) + { + case 0x0000: + util::stream_format(stream, "BRLO %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0001: + util::stream_format(stream, "BREQ %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0002: + util::stream_format(stream, "BRMI %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0003: + util::stream_format(stream, "BRVS %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0004: + util::stream_format(stream, "BRLT %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0005: + util::stream_format(stream, "BRHS %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0006: + util::stream_format(stream, "BRTS %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0007: + util::stream_format(stream, "BRIE %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + } break; - case 0xf000: - switch(op & 0x0c00) + case 0x0400: + switch(op & 0x0007) { - case 0x0000: - switch(op & 0x0007) - { - case 0x0000: - util::stream_format(stream, "BRLO %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0001: - util::stream_format(stream, "BREQ %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0002: - util::stream_format(stream, "BRMI %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0003: - util::stream_format(stream, "BRVS %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0004: - util::stream_format(stream, "BRLT %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0005: - util::stream_format(stream, "BRHS %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0006: - util::stream_format(stream, "BRTS %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0007: - util::stream_format(stream, "BRIE %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - } - break; - case 0x0400: - switch(op & 0x0007) - { - case 0x0000: - util::stream_format(stream, "BRSH %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0001: - util::stream_format(stream, "BRNE %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0002: - util::stream_format(stream, "BRPL %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0003: - util::stream_format(stream, "BRVC %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0004: - util::stream_format(stream, "BRGE %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0005: - util::stream_format(stream, "BRHC %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0006: - util::stream_format(stream, "BRTC %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - case 0x0007: - util::stream_format(stream, "BRID %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); - break; - } - break; - case 0x0800: - if(op & 0x0200) - { - util::stream_format(stream, "BST R%d, %d", RD5(op), RR3(op)); - } - else - { - util::stream_format(stream, "BLD R%d, %d", RD5(op), RR3(op)); - } - break; - case 0x0c00: - if(op & 0x0200) - { - util::stream_format(stream, "SBRS R%d, %d", RD5(op), RR3(op)); - } - else - { - util::stream_format(stream, "SBRC R%d, %d", RD5(op), RR3(op)); - } - break; + case 0x0000: + util::stream_format(stream, "BRSH %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0001: + util::stream_format(stream, "BRNE %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0002: + util::stream_format(stream, "BRPL %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0003: + util::stream_format(stream, "BRVC %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0004: + util::stream_format(stream, "BRGE %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0005: + util::stream_format(stream, "BRHC %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0006: + util::stream_format(stream, "BRTC %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; + case 0x0007: + util::stream_format(stream, "BRID %08x", (((op & 0x0200) ? (KCONST7(op) | 0xff80) : KCONST7(op)) << 1)); + break; } break; + case 0x0800: + if(op & 0x0200) + util::stream_format(stream, "BST R%d, %d", RD5(op), RR3(op)); + else + util::stream_format(stream, "BLD R%d, %d", RD5(op), RR3(op)); + break; + case 0x0c00: + if(op & 0x0200) + util::stream_format(stream, "SBRS R%d, %d", RD5(op), RR3(op)); + else + util::stream_format(stream, "SBRC R%d, %d", RD5(op), RR3(op)); + break; + } + break; } return (pc - base_pc) | SUPPORTED; |