Merge pull request #1 from schuay/master
[simavr] / simavr / sim / sim_core.c
index b400ca1..5ceb7f3 100644 (file)
 // SREG bit names
 const char * _sreg_bit_name = "cznvshti";
 
+#ifdef NO_COLOR
+       #define FONT_RED                
+       #define FONT_DEFAULT    
+#else
+       #define FONT_RED                "\e[31m"
+       #define FONT_DEFAULT    "\e[0m"
+#endif
+
 /*
  * Handle "touching" registers, marking them changed.
  * This is used only for debugging purposes to be able to
@@ -40,12 +48,12 @@ const char * _sreg_bit_name = "cznvshti";
 
 #define T(w) w
 
-#define REG_TOUCH(a, r) (a)->touched[(r) >> 5] |= (1 << ((r) & 0x1f))
-#define REG_ISTOUCHED(a, r) ((a)->touched[(r) >> 5] & (1 << ((r) & 0x1f)))
+#define REG_TOUCH(a, r) (a)->trace_data->touched[(r) >> 5] |= (1 << ((r) & 0x1f))
+#define REG_ISTOUCHED(a, r) ((a)->trace_data->touched[(r) >> 5] & (1 << ((r) & 0x1f)))
 
 /*
- * This allows a "special case" to skip indtruction tracing when in these
- * symbols. since printf() is useful to have, but generates a lot of cycles
+ * This allows a "special case" to skip instruction tracing when in these
+ * symbols since printf() is useful to have, but generates a lot of cycles.
  */
 int dont_trace(const char * name)
 {
@@ -63,8 +71,8 @@ int donttrace = 0;
 
 #define STATE(_f, args...) { \
        if (avr->trace) {\
-               if (avr->codeline && avr->codeline[avr->pc>>1]) {\
-                       const char * symn = avr->codeline[avr->pc>>1]->symbol; \
+               if (avr->trace_data->codeline && avr->trace_data->codeline[avr->pc>>1]) {\
+                       const char * symn = avr->trace_data->codeline[avr->pc>>1]->symbol; \
                        int dont = 0 && dont_trace(symn);\
                        if (dont!=donttrace) { \
                                donttrace = dont;\
@@ -93,12 +101,12 @@ void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)
 {
        if (addr > avr->ramend) {
                printf("*** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x out of ram\n",
-                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, v);
+                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, v);
                CRASH();
        }
        if (addr < 32) {
                printf("*** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x low registers\n",
-                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, v);
+                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, v);
                CRASH();
        }
 #if AVR_STACK_WATCH
@@ -107,8 +115,8 @@ void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)
         * higher on the stack than it should be. It's a sign of code that has overrun it's stack
         * frame and is munching on it's own return address.
         */
-       if (avr->stack_frame_index > 1 && addr > avr->stack_frame[avr->stack_frame_index-2].sp) {
-               printf("\e[31m%04x : munching stack SP %04x, A=%04x <= %02x\e[0m\n", avr->pc, _avr_sp_get(avr), addr, v);
+       if (avr->trace_data->stack_frame_index > 1 && addr > avr->trace_data->stack_frame[avr->trace_data->stack_frame_index-2].sp) {
+               printf( FONT_RED "%04x : munching stack SP %04x, A=%04x <= %02x\n" FONT_DEFAULT, avr->pc, _avr_sp_get(avr), addr, v);
        }
 #endif
        avr->data[addr] = v;
@@ -117,8 +125,8 @@ void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)
 uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr)
 {
        if (addr > avr->ramend) {
-               printf("*** Invalid read address PC=%04x SP=%04x O=%04x Address %04x out of ram (%04x)\n",
-                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc]<<8), addr, avr->ramend);
+               printf( FONT_RED "*** Invalid read address PC=%04x SP=%04x O=%04x Address %04x out of ram (%04x)\n" FONT_DEFAULT,
+                               avr->pc, _avr_sp_get(avr), avr->flash[avr->pc + 1] | (avr->flash[avr->pc]<<8), addr, avr->ramend);
                CRASH();
        }
        return avr->data[addr];
@@ -126,7 +134,7 @@ uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr)
 
 /*
  * Set a register (r < 256)
- * if it's an IO regisrer (> 31) also (try to) call any callback that was
+ * if it's an IO register (> 31) also (try to) call any callback that was
  * registered to track changes to that register.
  */
 static inline void _avr_set_r(avr_t * avr, uint8_t r, uint8_t v)
@@ -276,10 +284,10 @@ const char * avr_regname(uint8_t reg)
 static void _avr_invalid_opcode(avr_t * avr)
 {
 #if CONFIG_SIMAVR_TRACE
-       printf("\e[31m*** %04x: %-25s Invalid Opcode SP=%04x O=%04x \e[0m\n",
-                       avr->pc, avr->codeline[avr->pc>>1]->symbol, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8));
+       printf( FONT_RED "*** %04x: %-25s Invalid Opcode SP=%04x O=%04x \n" FONT_DEFAULT,
+                       avr->pc, avr->trace_data->codeline[avr->pc>>1]->symbol, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8));
 #else
-       printf("\e[31m*** %04x: Invalid Opcode SP=%04x O=%04x \e[0m\n",
+       printf( FONT_RED "*** %04x: Invalid Opcode SP=%04x O=%04x \n" FONT_DEFAULT,
                        avr->pc, _avr_sp_get(avr), avr->flash[avr->pc] | (avr->flash[avr->pc+1]<<8));
 #endif
 }
@@ -296,7 +304,7 @@ void avr_dump_state(avr_t * avr)
        int doit = 0;
 
        for (int r = 0; r < 3 && !doit; r++)
-               if (avr->touched[r])
+               if (avr->trace_data->touched[r])
                        doit = 1;
        if (!doit)
                return;
@@ -320,6 +328,10 @@ void avr_dump_state(avr_t * avr)
                const uint8_t r = ((o >> 5) & 0x10) | (o & 0xf); \
                const uint8_t d = (o >> 4) & 0x1f;\
                const uint8_t vd = avr->data[d], vr = avr->data[r];
+#define get_r_dd_10(o) \
+               const uint8_t r = ((o >> 5) & 0x10) | (o & 0xf); \
+               const uint8_t d = (o >> 4) & 0x1f;\
+               const uint8_t vr = avr->data[r];
 #define get_k_r16(o) \
                const uint8_t r = 16 + ((o >> 4) & 0xf); \
                const uint8_t k = ((o & 0x0f00) >> 4) | (o & 0xf);
@@ -329,18 +341,18 @@ void avr_dump_state(avr_t * avr)
  */
 #if CONFIG_SIMAVR_TRACE
 #define TRACE_JUMP()\
-       avr->old[avr->old_pci].pc = avr->pc;\
-       avr->old[avr->old_pci].sp = _avr_sp_get(avr);\
-       avr->old_pci = (avr->old_pci + 1) & (OLD_PC_SIZE-1);\
+       avr->trace_data->old[avr->trace_data->old_pci].pc = avr->pc;\
+       avr->trace_data->old[avr->trace_data->old_pci].sp = _avr_sp_get(avr);\
+       avr->trace_data->old_pci = (avr->trace_data->old_pci + 1) & (OLD_PC_SIZE-1);\
 
 #if AVR_STACK_WATCH
 #define STACK_FRAME_PUSH()\
-       avr->stack_frame[avr->stack_frame_index].pc = avr->pc;\
-       avr->stack_frame[avr->stack_frame_index].sp = _avr_sp_get(avr);\
-       avr->stack_frame_index++; 
+       avr->trace_data->stack_frame[avr->trace_data->stack_frame_index].pc = avr->pc;\
+       avr->trace_data->stack_frame[avr->trace_data->stack_frame_index].sp = _avr_sp_get(avr);\
+       avr->trace_data->stack_frame_index++; 
 #define STACK_FRAME_POP()\
-       if (avr->stack_frame_index > 0) \
-               avr->stack_frame_index--;
+       if (avr->trace_data->stack_frame_index > 0) \
+               avr->trace_data->stack_frame_index--;
 #else
 #define STACK_FRAME_PUSH()
 #define STACK_FRAME_POP()
@@ -414,7 +426,7 @@ get_compare_overflow (uint8_t res, uint8_t rd, uint8_t rr)
     return (rd & ~rr & ~res) | (~rd & rr & res);
 }
 
-static inline int _avr_is_instruction_32_bits(avr_t * avr, uint32_t pc)
+static inline int _avr_is_instruction_32_bits(avr_t * avr, avr_flashaddr_t pc)
 {
        uint16_t o = (avr->flash[pc] | (avr->flash[pc+1] << 8)) & 0xfc0f;
        return  o == 0x9200 || // STS ! Store Direct to Data Space
@@ -439,10 +451,10 @@ static inline int _avr_is_instruction_32_bits(avr_t * avr, uint32_t pc)
  * + It also doesn't check whether the core it's
  *   emulating is supposed to have the fancy instructions, like multiply and such.
  * 
- * The nunber of cycles taken by instruction has been added, but might not be
+ * The number of cycles taken by instruction has been added, but might not be
  * entirely accurate.
  */
-uint16_t avr_run_one(avr_t * avr)
+avr_flashaddr_t avr_run_one(avr_t * avr)
 {
 #if CONFIG_SIMAVR_TRACE
        /*
@@ -453,12 +465,12 @@ uint16_t avr_run_one(avr_t * avr)
                STATE("RESET\n");
                CRASH();
        }
-       avr->touched[0] = avr->touched[1] = avr->touched[2] = 0;
+       avr->trace_data->touched[0] = avr->trace_data->touched[1] = avr->trace_data->touched[2] = 0;
 #endif
 
-       uint32_t        opcode = (avr->flash[avr->pc + 1] << 8) | avr->flash[avr->pc];
-       uint32_t        new_pc = avr->pc + 2;   // future "default" pc
-       int             cycle = 1;
+       uint32_t                opcode = (avr->flash[avr->pc + 1] << 8) | avr->flash[avr->pc];
+       avr_flashaddr_t new_pc = avr->pc + 2;   // future "default" pc
+       int                     cycle = 1;
 
        switch (opcode & 0xf000) {
                case 0x0000: {
@@ -498,7 +510,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
                                                        SREG();
                                                }       break;
-                                               case 0x0800: {  // SBC substract with carry 0000 10rd dddd rrrr
+                                               case 0x0800: {  // SBC subtract with carry 0000 10rd dddd rrrr
                                                        get_r_d_10(opcode);
                                                        uint8_t res = vd - vr - avr->sreg[S_C];
                                                        STATE("sbc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res);
@@ -682,9 +694,9 @@ uint16_t avr_run_one(avr_t * avr)
                                        SREG();
                                }       break;
                                case 0x2c00: {  // MOV  0010 11rd dddd rrrr
-                                       get_r_d_10(opcode);
+                                       get_r_dd_10(opcode);
                                        uint8_t res = vr;
-                                       STATE("mov %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res);
+                                       STATE("mov %s, %s[%02x] = %02x\n", avr_regname(d), avr_regname(r), vr, res);
                                        _avr_set_r(avr, d, res);
                                }       break;
                                default: _avr_invalid_opcode(avr);
@@ -773,7 +785,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                STATE("ld %s, (Z+%d[%04x])=[%02x]\n", avr_regname(r), q, v+q, avr->data[v+q]);
                                                _avr_set_r(avr, r, _avr_get_ram(avr, v+q));
                                        }
-                                       cycle += 2;
+                                       cycle += 1; // 2 cycles, 3 for tinyavr
                                }       break;
                                case 0xa008:
                                case 0x8008: {  // LD (LDD) – Load Indirect using Y 10q0 qq0r rrrr 1qqq
@@ -788,7 +800,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                STATE("ld %s, (Y+%d[%04x])=[%02x]\n", avr_regname(r), q, v+q, avr->data[v+q]);
                                                _avr_set_r(avr, r, _avr_get_ram(avr, v+q));
                                        }
-                                       cycle += 2;
+                                       cycle += 1; // 2 cycles, 3 for tinyavr
                                }       break;
                                default: _avr_invalid_opcode(avr);
                        }
@@ -858,6 +870,7 @@ uint16_t avr_run_one(avr_t * avr)
                                case 0x95c8: {  // LPM Load Program Memory R0 <- (Z)
                                        uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8);
                                        STATE("lpm %s, (Z[%04x])\n", avr_regname(0), z);
+                                       cycle += 2; // 3 cycles
                                        _avr_set_r(avr, 0, avr->flash[z]);
                                }       break;
                                case 0x9408:case 0x9418:case 0x9428:case 0x9438:case 0x9448:case 0x9458:case 0x9468:
@@ -884,7 +897,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        new_pc += 2;
                                                        STATE("lds %s[%02x], 0x%04x\n", avr_regname(r), avr->data[r], x);
                                                        _avr_set_r(avr, r, _avr_get_ram(avr, x));
-                                                       cycle++;
+                                                       cycle++; // 2 cycles
                                                }       break;
                                                case 0x9005:
                                                case 0x9004: {  // LPM Load Program Memory 1001 000d dddd 01oo
@@ -898,7 +911,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                                _avr_set_r(avr, R_ZH, z >> 8);
                                                                _avr_set_r(avr, R_ZL, z);
                                                        }
-                                                       cycle += 2;
+                                                       cycle += 2; // 3 cycles
                                                }       break;
                                                case 0x9006:
                                                case 0x9007: {  // ELPM Extended Load Program Memory 1001 000d dddd 01oo
@@ -915,7 +928,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                                _avr_set_r(avr, R_ZH, z >> 8);
                                                                _avr_set_r(avr, R_ZL, z);
                                                        }
-                                                       cycle += 2;
+                                                       cycle += 2; // 3 cycles
                                                }       break;
                                                /*
                                                 * Load store instructions
@@ -932,7 +945,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        uint8_t r = (opcode >> 4) & 0x1f;
                                                        uint16_t x = (avr->data[R_XH] << 8) | avr->data[R_XL];
                                                        STATE("ld %s, %sX[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", x, op == 1 ? "++" : "");
-
+                                                       cycle++; // 2 cycles (1 for tinyavr, except with inc/dec 2)
                                                        if (op == 2) x--;
                                                        _avr_set_r(avr, r, _avr_get_ram(avr, x));
                                                        if (op == 1) x++;
@@ -946,7 +959,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        uint8_t r = (opcode >> 4) & 0x1f;
                                                        uint16_t x = (avr->data[R_XH] << 8) | avr->data[R_XL];
                                                        STATE("st %sX[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", x, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
-                                                       cycle++;
+                                                       cycle++; // 2 cycles, except tinyavr
                                                        if (op == 2) x--;
                                                        _avr_set_ram(avr, x, avr->data[r]);
                                                        if (op == 1) x++;
@@ -959,7 +972,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        uint8_t r = (opcode >> 4) & 0x1f;
                                                        uint16_t y = (avr->data[R_YH] << 8) | avr->data[R_YL];
                                                        STATE("ld %s, %sY[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", y, op == 1 ? "++" : "");
-                                                       cycle++;
+                                                       cycle++; // 2 cycles, except tinyavr
                                                        if (op == 2) y--;
                                                        _avr_set_r(avr, r, _avr_get_ram(avr, y));
                                                        if (op == 1) y++;
@@ -971,7 +984,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        int op = opcode & 3;
                                                        uint8_t r = (opcode >> 4) & 0x1f;
                                                        uint16_t y = (avr->data[R_YH] << 8) | avr->data[R_YL];
-                                                       STATE("st %sY[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", y, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
+                                                       STATE("st %sY[%04x]%s, %s[%02x]\n", op == 2 ? "--" : "", y, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
                                                        cycle++;
                                                        if (op == 2) y--;
                                                        _avr_set_ram(avr, y, avr->data[r]);
@@ -984,6 +997,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
                                                        new_pc += 2;
                                                        STATE("sts 0x%04x, %s[%02x]\n", x, avr_regname(r), avr->data[r]);
+                                                       cycle++;
                                                        _avr_set_ram(avr, x, avr->data[r]);
                                                }       break;
                                                case 0x9001:
@@ -992,6 +1006,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        uint8_t r = (opcode >> 4) & 0x1f;
                                                        uint16_t z = (avr->data[R_ZH] << 8) | avr->data[R_ZL];
                                                        STATE("ld %s, %sZ[%04x]%s\n", avr_regname(r), op == 2 ? "--" : "", z, op == 1 ? "++" : "");
+                                                       cycle++;; // 2 cycles, except tinyavr
                                                        if (op == 2) z--;
                                                        _avr_set_r(avr, r, _avr_get_ram(avr, z));
                                                        if (op == 1) z++;
@@ -1004,6 +1019,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        uint8_t r = (opcode >> 4) & 0x1f;
                                                        uint16_t z = (avr->data[R_ZH] << 8) | avr->data[R_ZL];
                                                        STATE("st %sZ[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", z, op == 1 ? "++" : "", avr_regname(r), avr->data[r]);
+                                                       cycle++; // 2 cycles, except tinyavr
                                                        if (op == 2) z--;
                                                        _avr_set_ram(avr, z, avr->data[r]);
                                                        if (op == 1) z++;
@@ -1036,7 +1052,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                        avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V];
                                                        SREG();
                                                }       break;
-                                               case 0x9401: {  // NEG – One’s Complement
+                                               case 0x9401: {  // NEG – Two’s Complement
                                                        uint8_t r = (opcode >> 4) & 0x1f;
                                                        uint8_t rd = avr->data[r];
                                                        uint8_t res = 0x00 - rd;
@@ -1119,7 +1135,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                }       break;
                                                case 0x940c:
                                                case 0x940d: {  // JMP Long Call to sub, 32 bits
-                                                       uint32_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);
+                                                       avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);
                                                        uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
                                                        a = (a << 16) | x;
                                                        STATE("jmp 0x%06x\n", a);
@@ -1129,14 +1145,14 @@ uint16_t avr_run_one(avr_t * avr)
                                                }       break;
                                                case 0x940e:
                                                case 0x940f: {  // CALL Long Call to sub, 32 bits
-                                                       uint32_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);
+                                                       avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1);
                                                        uint16_t x = (avr->flash[new_pc+1] << 8) | avr->flash[new_pc];
                                                        a = (a << 16) | x;
                                                        STATE("call 0x%06x\n", a);
                                                        new_pc += 2;
                                                        _avr_push16(avr, new_pc >> 1);
                                                        new_pc = a << 1;
-                                                       cycle += 3;     // 4 cycles
+                                                       cycle += 3;     // 4 cycles; FIXME 5 on devices with 22 bit PC
                                                        TRACE_JUMP();
                                                        STACK_FRAME_PUSH();
                                                }       break;
@@ -1225,6 +1241,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                                                        get_r_d_10(opcode);
                                                                                        uint16_t res = vd * vr;
                                                                                        STATE("mul %s[%02x], %s[%02x] = %04x\n", avr_regname(d), vd, avr_regname(r), vr, res);
+                                                                                       cycle++;
                                                                                        _avr_set_r(avr, 0, res);
                                                                                        _avr_set_r(avr, 1, res >> 8);
                                                                                        avr->sreg[S_Z] = res == 0;
@@ -1260,7 +1277,8 @@ uint16_t avr_run_one(avr_t * avr)
 
                case 0xc000: {
                        // RJMP 1100 kkkk kkkk kkkk
-                       short o = ((short)(opcode << 4)) >> 4;
+//                     int16_t o = ((int16_t)(opcode << 4)) >> 4; // CLANG BUG!
+                       int16_t o = ((int16_t)((opcode << 4)&0xffff)) >> 4;
                        STATE("rjmp .%d [%04x]\n", o, new_pc + (o << 1));
                        new_pc = new_pc + (o << 1);
                        cycle++;
@@ -1269,7 +1287,8 @@ uint16_t avr_run_one(avr_t * avr)
 
                case 0xd000: {
                        // RCALL 1100 kkkk kkkk kkkk
-                       short o = ((short)(opcode << 4)) >> 4;
+//                     int16_t o = ((int16_t)(opcode << 4)) >> 4; // CLANG BUG!
+                       int16_t o = ((int16_t)((opcode << 4)&0xffff)) >> 4;
                        STATE("rcall .%d [%04x]\n", o, new_pc + (o << 1));
                        _avr_push16(avr, new_pc >> 1);
                        new_pc = new_pc + (o << 1);
@@ -1294,7 +1313,7 @@ uint16_t avr_run_one(avr_t * avr)
                                case 0xf200:
                                case 0xf400:
                                case 0xf600: {  // All the SREG branches
-                                       short o = ((short)(opcode << 6)) >> 9; // offset
+                                       int16_t o = ((int16_t)(opcode << 6)) >> 9; // offset
                                        uint8_t s = opcode & 7;
                                        int set = (opcode & 0x0400) == 0;               // this bit means BRXC otherwise BRXS
                                        int branch = (avr->sreg[s] && set) || (!avr->sreg[s] && !set);
@@ -1308,7 +1327,7 @@ uint16_t avr_run_one(avr_t * avr)
                                                STATE("%s%c .%d [%04x]\t; Will%s branch\n", set ? "brbs" : "brbc", _sreg_bit_name[s], o, new_pc + (o << 1), branch ? "":" not");
                                        }
                                        if (branch) {
-                                               cycle++;
+                                               cycle++; // 2 cycles if taken, 1 otherwise
                                                new_pc = new_pc + (o << 1);
                                        }
                                }       break;