| 1 | // |
| 2 | // Inline functions used by cpuemu.c |
| 3 | // |
| 4 | // by Bernd Schmidt, Thomas Huth, and James Hammons |
| 5 | // |
| 6 | // Since inline functions have to be in a header, we have them all defined |
| 7 | // here, in one place to make finding them easy. |
| 8 | // |
| 9 | |
| 10 | #ifndef __INLINES_H__ |
| 11 | #define __INLINES_H__ |
| 12 | |
| 13 | #include "cpudefs.h" |
| 14 | |
| 15 | STATIC_INLINE int cctrue(const int cc) |
| 16 | { |
| 17 | switch (cc) |
| 18 | { |
| 19 | case 0: return 1; /* T */ |
| 20 | case 1: return 0; /* F */ |
| 21 | case 2: return !CFLG && !ZFLG; /* HI */ |
| 22 | case 3: return CFLG || ZFLG; /* LS */ |
| 23 | case 4: return !CFLG; /* CC */ |
| 24 | case 5: return CFLG; /* CS */ |
| 25 | case 6: return !ZFLG; /* NE */ |
| 26 | case 7: return ZFLG; /* EQ */ |
| 27 | case 8: return !VFLG; /* VC */ |
| 28 | case 9: return VFLG; /* VS */ |
| 29 | case 10: return !NFLG; /* PL */ |
| 30 | case 11: return NFLG; /* MI */ |
| 31 | case 12: return NFLG == VFLG; /* GE */ |
| 32 | case 13: return NFLG != VFLG; /* LT */ |
| 33 | case 14: return !ZFLG && (NFLG == VFLG); /* GT */ |
| 34 | case 15: return ZFLG || (NFLG != VFLG); /* LE */ |
| 35 | } |
| 36 | |
| 37 | abort(); |
| 38 | return 0; |
| 39 | } |
| 40 | |
| 41 | //no #define m68k_incpc(o) (regs.pc_p += (o)) |
| 42 | #define m68k_incpc(o) (regs.pc += (o)) |
| 43 | |
| 44 | STATIC_INLINE void m68k_setpc(uint32_t newpc) |
| 45 | { |
| 46 | //This is only done here... (get_real_address()) |
| 47 | // regs.pc_p = regs.pc_oldp = get_real_address(newpc); |
| 48 | regs.pc = newpc; |
| 49 | } |
| 50 | |
| 51 | #define m68k_setpc_rte m68k_setpc |
| 52 | |
| 53 | STATIC_INLINE uint32_t m68k_getpc(void) |
| 54 | { |
| 55 | // return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); |
| 56 | return regs.pc; |
| 57 | } |
| 58 | |
| 59 | #if 0 |
| 60 | STATIC_INLINE uint32_t m68k_getpc_p(uint8_t * p) |
| 61 | { |
| 62 | return regs.pc + ((char *)p - (char *)regs.pc_oldp); |
| 63 | } |
| 64 | #endif |
| 65 | |
| 66 | STATIC_INLINE void m68k_setstopped(int stop) |
| 67 | { |
| 68 | regs.stopped = stop; |
| 69 | regs.remainingCycles = 0; |
| 70 | |
| 71 | //But trace instructions are only on >68000 cpus, so this is bogus. |
| 72 | #if 0 |
| 73 | /* A traced STOP instruction drops through immediately without |
| 74 | actually stopping. */ |
| 75 | if (stop && (regs.spcflags & SPCFLAG_DOTRACE) == 0) |
| 76 | regs.spcflags |= SPCFLAG_STOP; |
| 77 | #endif |
| 78 | } |
| 79 | |
| 80 | STATIC_INLINE void m68k_do_rts(void) |
| 81 | { |
| 82 | m68k_setpc(m68k_read_memory_32(m68k_areg(regs, 7))); |
| 83 | m68k_areg(regs, 7) += 4; |
| 84 | } |
| 85 | |
| 86 | STATIC_INLINE void m68k_do_bsr(uint32_t oldpc, int32_t offset) |
| 87 | { |
| 88 | m68k_areg(regs, 7) -= 4; |
| 89 | m68k_write_memory_32(m68k_areg(regs, 7), oldpc); |
| 90 | m68k_incpc(offset); |
| 91 | } |
| 92 | |
| 93 | STATIC_INLINE void m68k_do_jsr(uint32_t oldpc, uint32_t dest) |
| 94 | { |
| 95 | m68k_areg(regs, 7) -= 4; |
| 96 | m68k_write_memory_32(m68k_areg(regs, 7), oldpc); |
| 97 | m68k_setpc(dest); |
| 98 | } |
| 99 | |
| 100 | #if 0 |
| 101 | //These do_get_mem_* functions are only used in newcpu... |
| 102 | //What it does is use a pointer to make instruction fetching quicker, |
| 103 | //though it probably leads to more problems than it solves. Something to |
| 104 | //decide using a profiler... |
| 105 | #define get_ibyte(o) do_get_mem_byte(regs.pc_p + (o) + 1) |
| 106 | #define get_iword(o) do_get_mem_word(regs.pc_p + (o)) |
| 107 | #define get_ilong(o) do_get_mem_long(regs.pc_p + (o)) |
| 108 | #else |
| 109 | // For now, we'll punt this crap... |
| 110 | // (Also, notice that the byte read is at address + 1...) |
| 111 | #define get_ibyte(o) m68k_read_memory_8(regs.pc + (o) + 1) |
| 112 | #define get_iword(o) m68k_read_memory_16(regs.pc + (o)) |
| 113 | #define get_ilong(o) m68k_read_memory_32(regs.pc + (o)) |
| 114 | #endif |
| 115 | |
| 116 | // We don't use this crap, so let's comment out for now... |
| 117 | STATIC_INLINE void refill_prefetch(uint32_t currpc, uint32_t offs) |
| 118 | { |
| 119 | #if 0 |
| 120 | uint32_t t = (currpc + offs) & ~1; |
| 121 | int32_t pc_p_offs = t - currpc; |
| 122 | uint8_t * ptr = regs.pc_p + pc_p_offs; |
| 123 | uint32_t r; |
| 124 | |
| 125 | #ifdef UNALIGNED_PROFITABLE |
| 126 | r = *(uint32_t *)ptr; |
| 127 | regs.prefetch = r; |
| 128 | #else |
| 129 | r = do_get_mem_long(ptr); |
| 130 | do_put_mem_long(®s.prefetch, r); |
| 131 | #endif |
| 132 | /* printf ("PC %lx T %lx PCPOFFS %d R %lx\n", currpc, t, pc_p_offs, r); */ |
| 133 | regs.prefetch_pc = t; |
| 134 | #endif |
| 135 | } |
| 136 | |
| 137 | STATIC_INLINE uint32_t get_ibyte_prefetch(int32_t o) |
| 138 | { |
| 139 | #if 0 |
| 140 | uint32_t currpc = m68k_getpc(); |
| 141 | uint32_t addr = currpc + o + 1; |
| 142 | uint32_t offs = addr - regs.prefetch_pc; |
| 143 | |
| 144 | if (offs > 3) |
| 145 | { |
| 146 | refill_prefetch(currpc, o + 1); |
| 147 | offs = addr - regs.prefetch_pc; |
| 148 | } |
| 149 | |
| 150 | uint32_t v = do_get_mem_byte(((uint8_t *)®s.prefetch) + offs); |
| 151 | |
| 152 | if (offs >= 2) |
| 153 | refill_prefetch(currpc, 2); |
| 154 | |
| 155 | /* printf ("get_ibyte PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ |
| 156 | return v; |
| 157 | #else |
| 158 | return get_ibyte(o); |
| 159 | #endif |
| 160 | } |
| 161 | |
| 162 | STATIC_INLINE uint32_t get_iword_prefetch(int32_t o) |
| 163 | { |
| 164 | #if 0 |
| 165 | uint32_t currpc = m68k_getpc(); |
| 166 | uint32_t addr = currpc + o; |
| 167 | uint32_t offs = addr - regs.prefetch_pc; |
| 168 | |
| 169 | if (offs > 3) |
| 170 | { |
| 171 | refill_prefetch(currpc, o); |
| 172 | offs = addr - regs.prefetch_pc; |
| 173 | } |
| 174 | |
| 175 | uint32_t v = do_get_mem_word(((uint8_t *)®s.prefetch) + offs); |
| 176 | |
| 177 | if (offs >= 2) |
| 178 | refill_prefetch(currpc, 2); |
| 179 | |
| 180 | /* printf ("get_iword PC %lx ADDR %lx OFFS %lx V %lx\n", currpc, addr, offs, v); */ |
| 181 | return v; |
| 182 | #else |
| 183 | return get_iword(o); |
| 184 | #endif |
| 185 | } |
| 186 | |
| 187 | STATIC_INLINE uint32_t get_ilong_prefetch(int32_t o) |
| 188 | { |
| 189 | #if 0 |
| 190 | uint32_t v = get_iword_prefetch(o); |
| 191 | v <<= 16; |
| 192 | v |= get_iword_prefetch(o + 2); |
| 193 | return v; |
| 194 | #else |
| 195 | return get_ilong(o); |
| 196 | #endif |
| 197 | } |
| 198 | |
| 199 | STATIC_INLINE void fill_prefetch_0(void) |
| 200 | { |
| 201 | } |
| 202 | |
| 203 | #define fill_prefetch_2 fill_prefetch_0 |
| 204 | |
| 205 | #endif // __INLINES_H__ |