--- hatari/src/cpu/cpu_prefetch.h 2019/04/09 08:51:57 1.1.1.2 +++ hatari/src/cpu/cpu_prefetch.h 2019/04/09 08:56:44 1.1.1.4 @@ -1,203 +1,93 @@ +#ifndef UAE_CPU_PREFETCH_H +#define UAE_CPU_PREFETCH_H -STATIC_INLINE uae_u32 get_word_prefetch (int o) -{ - uae_u32 v = regs.irc; - regs.irc = get_wordi (m68k_getpc () + o); - return v; -} -STATIC_INLINE uae_u32 get_long_prefetch (int o) -{ - uae_u32 v = get_word_prefetch (o) << 16; - v |= get_word_prefetch (o + 2); - return v; -} +#include "uae/types.h" #ifdef CPUEMU_20 -STATIC_INLINE void checkcycles_ce020 (void) -{ - if (regs.ce020memcycles > 0) - do_cycles_ce (regs.ce020memcycles); - regs.ce020memcycles = 0; -} +extern uae_u32 get_word_020_prefetch (int); +extern void continue_020_prefetch(void); -STATIC_INLINE uae_u32 mem_access_delay_long_read_ce020 (uaecptr addr) +STATIC_INLINE uae_u32 next_iword_020_prefetch (void) { - checkcycles_ce020 (); - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - if ((addr & 3) != 0) { - uae_u32 v; - v = wait_cpu_cycle_read_ce020 (addr + 0, 1) << 16; - v |= wait_cpu_cycle_read_ce020 (addr + 2, 1) << 0; - return v; - } else { - return wait_cpu_cycle_read_ce020 (addr, -1); - } - case CE_MEMBANK_FAST: - if ((addr & 3) != 0) - do_cycles_ce020_mem (2 * CPU020_MEM_CYCLE); - else - do_cycles_ce020_mem (1 * CPU020_MEM_CYCLE); - break; - case CE_MEMBANK_FAST16BIT: - do_cycles_ce020_mem (2 * CPU020_MEM_CYCLE); - break; - } - return get_long (addr); + uae_u32 r = get_word_020_prefetch (0); + m68k_incpci (2); + return r; } - -STATIC_INLINE uae_u32 mem_access_delay_longi_read_ce020 (uaecptr addr) +STATIC_INLINE uae_u32 next_ilong_020_prefetch (void) { - checkcycles_ce020 (); - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - if ((addr & 3) != 0) { - uae_u32 v; - v = wait_cpu_cycle_read_ce020 (addr + 0, 1) << 16; - v |= wait_cpu_cycle_read_ce020 (addr + 2, 1) << 0; - return v; - } else { - return wait_cpu_cycle_read_ce020 (addr, -1); - } - case CE_MEMBANK_FAST: - if ((addr & 3) != 0) - do_cycles_ce020_mem (2 * CPU020_MEM_CYCLE); - else - do_cycles_ce020_mem (1 * CPU020_MEM_CYCLE); - break; - case CE_MEMBANK_FAST16BIT: - do_cycles_ce020_mem (2 * CPU020_MEM_CYCLE); - break; - } - return get_longi (addr); + uae_u32 r = next_iword_020_prefetch () << 16; + r |= next_iword_020_prefetch (); + return r; } -STATIC_INLINE uae_u32 mem_access_delay_word_read_ce020 (uaecptr addr) +STATIC_INLINE uae_u32 get_long_020_prefetch (int o) { - checkcycles_ce020 (); - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - if ((addr & 3) == 3) { - uae_u16 v; - v = wait_cpu_cycle_read_ce020 (addr + 0, 0) << 8; - v |= wait_cpu_cycle_read_ce020 (addr + 1, 0) << 0; - return v; - } else { - return wait_cpu_cycle_read_ce020 (addr, 1); - } - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - if ((addr & 3) == 3) - do_cycles_ce020_mem (2 * CPU020_MEM_CYCLE); - else - do_cycles_ce020_mem (1 * CPU020_MEM_CYCLE); - break; - } - return get_word (addr); + uae_u32 r = get_word_020_prefetch (o) << 16; + r |= get_word_020_prefetch (o + 2); + return r; } -STATIC_INLINE uae_u32 mem_access_delay_wordi_read_ce020 (uaecptr addr) -{ - checkcycles_ce020 (); - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - return wait_cpu_cycle_read_ce020 (addr, 1); - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - do_cycles_ce020_mem (1 * CPU020_MEM_CYCLE); - break; - } - return get_wordi (addr); -} +#endif -STATIC_INLINE uae_u32 mem_access_delay_byte_read_ce020 (uaecptr addr) -{ - checkcycles_ce020 (); - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - return wait_cpu_cycle_read_ce020 (addr, 0); - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - do_cycles_ce020_mem (1 * CPU020_MEM_CYCLE); - break; +#ifdef CPUEMU_21 - } - return get_byte (addr); -} +#define CE020_INITCYCLES() \ + int head = 0, tail = 0, cycles = 0; \ + unsigned int cu = get_cycles (); +#define CE020_SAVECYCLES(h,t,c) \ + head = h; tail = t; cycles = c; +#define CE020_COUNTCYCLES() -STATIC_INLINE void mem_access_delay_byte_write_ce020 (uaecptr addr, uae_u32 v) +// only for CPU internal cycles +STATIC_INLINE void do_cycles_ce020_internal(int clocks) { - checkcycles_ce020 (); - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - wait_cpu_cycle_write_ce020 (addr, 0, v); + if (currprefs.m68k_speed < 0) { + regs.ce020extracycles += clocks; return; - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - do_cycles_ce020_mem (1 * CPU020_MEM_CYCLE); - break; } - put_byte (addr, v); + int cycs = clocks * cpucycleunit; +//fprintf ( stderr , "do_cycles_ce020_internal %d %d" , cycs , regs.ce020memcycles ); + if (regs.ce020memcycles > 0) { + if (regs.ce020memcycles >= cycs) { + regs.ce020memcycles -= cycs; + return; + } + cycs = cycs - regs.ce020memcycles; + } +//fprintf ( stderr , " -> %d\n" , cycs ); + regs.ce020memcycles = 0; + x_do_cycles (cycs); } -STATIC_INLINE void mem_access_delay_word_write_ce020 (uaecptr addr, uae_u32 v) +STATIC_INLINE void do_cycles_ce020_mem (int clocks, uae_u32 val) { - checkcycles_ce020 (); - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - if ((addr & 3) == 3) { - wait_cpu_cycle_write_ce020 (addr + 0, 0, (v >> 8) & 0xff); - wait_cpu_cycle_write_ce020 (addr + 1, 0, (v >> 0) & 0xff); - } else { - wait_cpu_cycle_write_ce020 (addr + 0, 1, v); - } - return; - break; - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - if ((addr & 3) == 3) - do_cycles_ce020_mem (2 * CPU020_MEM_CYCLE); - else - do_cycles_ce020_mem (1 * CPU020_MEM_CYCLE); - break; - } - put_word (addr, v); + x_do_cycles_post (clocks * cpucycleunit, val); } -STATIC_INLINE void mem_access_delay_long_write_ce020 (uaecptr addr, uae_u32 v) +#if 0 +STATIC_INLINE void do_head_cycles_ce020 (int h) { - checkcycles_ce020 (); - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - if ((addr & 3) == 3) { - wait_cpu_cycle_write_ce020 (addr + 0, 1, (v >> 16) & 0xffff); - wait_cpu_cycle_write_ce020 (addr + 2, 1, (v >> 0) & 0xffff); - } else { - wait_cpu_cycle_write_ce020 (addr + 0, -1, v); - } - return; - break; - case CE_MEMBANK_FAST: - if ((addr & 3) != 0) - do_cycles_ce020_mem (2 * CPU020_MEM_CYCLE); - else - do_cycles_ce020_mem (1 * CPU020_MEM_CYCLE); - break; - case CE_MEMBANK_FAST16BIT: - do_cycles_ce020_mem (2 * CPU020_MEM_CYCLE); - break; + if (regs.ce020_tail) { + int cycs = regs.ce020_tail_cycles - get_cycles (); + if (cycs < 0) + cycs = 0; + cycs -= h * cpucycleunit; + if (cycs) + x_do_cycles (cycs < 0 ? -cycs : cycs); + } else if (h > 0) { + do_cycles_ce020 (h); } - put_long (addr, v); } +#endif + +void mem_access_delay_long_write_ce020 (uaecptr addr, uae_u32 v); +void mem_access_delay_word_write_ce020 (uaecptr addr, uae_u32 v); +void mem_access_delay_byte_write_ce020 (uaecptr addr, uae_u32 v); +uae_u32 mem_access_delay_byte_read_ce020 (uaecptr addr); +uae_u32 mem_access_delay_word_read_ce020 (uaecptr addr); +uae_u32 mem_access_delay_longi_read_ce020 (uaecptr addr); +uae_u32 mem_access_delay_long_read_ce020 (uaecptr addr); STATIC_INLINE uae_u32 get_long_ce020 (uaecptr addr) { @@ -225,62 +115,127 @@ STATIC_INLINE void put_byte_ce020 (uaecp mem_access_delay_byte_write_ce020 (addr, v); } -extern uae_u32 get_word_ce020_prefetch (int); +extern void continue_ce020_prefetch(void); +extern uae_u32 get_word_ce020_prefetch(int); STATIC_INLINE uae_u32 get_long_ce020_prefetch (int o) { uae_u32 v; + uae_u16 tmp; v = get_word_ce020_prefetch (o) << 16; + tmp = regs.db; v |= get_word_ce020_prefetch (o + 2); + regs.db = tmp; return v; } STATIC_INLINE uae_u32 next_iword_020ce (void) { uae_u32 r = get_word_ce020_prefetch (0); - m68k_incpc (2); + m68k_incpci (2); return r; } STATIC_INLINE uae_u32 next_ilong_020ce (void) { uae_u32 r = get_long_ce020_prefetch (0); - m68k_incpc (4); + m68k_incpci (4); return r; } STATIC_INLINE void m68k_do_bsr_ce020 (uaecptr oldpc, uae_s32 offset) { m68k_areg (regs, 7) -= 4; - put_long_ce020 (m68k_areg (regs, 7), oldpc); - m68k_incpc (offset); + x_put_long (m68k_areg (regs, 7), oldpc); + m68k_incpci (offset); } STATIC_INLINE void m68k_do_rts_ce020 (void) { - m68k_setpc (get_long_ce020 (m68k_areg (regs, 7))); + m68k_setpci (x_get_long (m68k_areg (regs, 7))); m68k_areg (regs, 7) += 4; } + + #endif -#ifdef CPUEMU_21 +#ifdef CPUEMU_22 + +extern uae_u32 get_word_030_prefetch(int); + +STATIC_INLINE void put_long_030(uaecptr addr, uae_u32 v) +{ + write_dcache030(addr, v, 2); +} +STATIC_INLINE void put_word_030(uaecptr addr, uae_u32 v) +{ + write_dcache030(addr, v, 1); +} +STATIC_INLINE void put_byte_030(uaecptr addr, uae_u32 v) +{ + write_dcache030(addr, v, 0); +} +STATIC_INLINE uae_u32 get_long_030(uaecptr addr) +{ + return read_dcache030(addr, 2); +} +STATIC_INLINE uae_u32 get_word_030(uaecptr addr) +{ + return read_dcache030(addr, 1); +} +STATIC_INLINE uae_u32 get_byte_030(uaecptr addr) +{ + return read_dcache030(addr, 0); +} + +STATIC_INLINE uae_u32 get_long_030_prefetch(int o) +{ + uae_u32 v; + v = get_word_030_prefetch(o) << 16; + v |= get_word_030_prefetch(o + 2); + return v; +} -extern uae_u32 get_word_ce030_prefetch (int); -extern void write_dcache030 (uaecptr, uae_u32, int); -extern uae_u32 read_dcache030 (uaecptr, int); +STATIC_INLINE uae_u32 next_iword_030_prefetch(void) +{ + uae_u32 r = get_word_030_prefetch(0); + m68k_incpci(2); + return r; +} +STATIC_INLINE uae_u32 next_ilong_030_prefetch(void) +{ + uae_u32 r = get_long_030_prefetch(0); + m68k_incpci(4); + return r; +} + +STATIC_INLINE void m68k_do_bsr_030(uaecptr oldpc, uae_s32 offset) +{ + m68k_areg(regs, 7) -= 4; + put_long_030(m68k_areg(regs, 7), oldpc); + m68k_incpci(offset); +} +STATIC_INLINE void m68k_do_rts_030(void) +{ + m68k_setpc(get_long_030(m68k_areg(regs, 7))); + m68k_areg(regs, 7) += 4; +} + +#endif + +#ifdef CPUEMU_23 + +extern uae_u32 get_word_ce030_prefetch(int); STATIC_INLINE void put_long_ce030 (uaecptr addr, uae_u32 v) { write_dcache030 (addr, v, 2); - mem_access_delay_long_write_ce020 (addr, v); } STATIC_INLINE void put_word_ce030 (uaecptr addr, uae_u32 v) { write_dcache030 (addr, v, 1); - mem_access_delay_word_write_ce020 (addr, v); } STATIC_INLINE void put_byte_ce030 (uaecptr addr, uae_u32 v) { write_dcache030 (addr, v, 0); - mem_access_delay_byte_write_ce020 (addr, v); } STATIC_INLINE uae_u32 get_long_ce030 (uaecptr addr) { @@ -306,13 +261,13 @@ STATIC_INLINE uae_u32 get_long_ce030_pre STATIC_INLINE uae_u32 next_iword_030ce (void) { uae_u32 r = get_word_ce030_prefetch (0); - m68k_incpc (2); + m68k_incpci (2); return r; } STATIC_INLINE uae_u32 next_ilong_030ce (void) { uae_u32 r = get_long_ce030_prefetch (0); - m68k_incpc (4); + m68k_incpci (4); return r; } @@ -320,128 +275,107 @@ STATIC_INLINE void m68k_do_bsr_ce030 (ua { m68k_areg (regs, 7) -= 4; put_long_ce030 (m68k_areg (regs, 7), oldpc); - m68k_incpc (offset); + m68k_incpci (offset); } STATIC_INLINE void m68k_do_rts_ce030 (void) { m68k_setpc (get_long_ce030 (m68k_areg (regs, 7))); m68k_areg (regs, 7) += 4; } + #endif -#ifdef CPUEMU_12 +#ifdef CPUEMU_11 -STATIC_INLINE void ipl_fetch (void) +STATIC_INLINE uae_u32 get_word_000_prefetch(int o) { - regs.ipl = regs.ipl_pin; + uae_u32 v = regs.irc; + regs.irc = regs.db = get_wordi (m68k_getpci () + o); + return v; } - -STATIC_INLINE uae_u32 mem_access_delay_word_read (uaecptr addr) +STATIC_INLINE uae_u32 get_byte_000(uaecptr addr) { - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - return wait_cpu_cycle_read (addr, 1); - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - do_cycles_ce000 (4); - break; - } - return get_word (addr); + uae_u32 v = get_byte (addr); + regs.db = (v << 8) | v; + return v; } -STATIC_INLINE uae_u32 mem_access_delay_wordi_read (uaecptr addr) +STATIC_INLINE uae_u32 get_word_000(uaecptr addr) { - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - return wait_cpu_cycle_read (addr, 1); - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - do_cycles_ce000 (4); - break; - } - return get_wordi (addr); + uae_u32 v = get_word (addr); + regs.db = v; + return v; } - -STATIC_INLINE uae_u32 mem_access_delay_byte_read (uaecptr addr) +STATIC_INLINE void put_byte_000(uaecptr addr, uae_u32 v) { - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - return wait_cpu_cycle_read (addr, 0); - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - do_cycles_ce000 (4); - break; - - } - return get_byte (addr); + regs.db = (v << 8) | v; + put_byte (addr, v); } -STATIC_INLINE void mem_access_delay_byte_write (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_word_000(uaecptr addr, uae_u32 v) { - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - wait_cpu_cycle_write (addr, 0, v); - return; - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - do_cycles_ce000 (4); - break; - } - put_byte (addr, v); + regs.db = v; + put_word (addr, v); } -STATIC_INLINE void mem_access_delay_word_write (uaecptr addr, uae_u32 v) +#endif + +#ifdef CPUEMU_13 + +STATIC_INLINE void do_cycles_ce000_internal(int clocks) { - switch (ce_banktype[addr >> 16]) - { - case CE_MEMBANK_CHIP: - wait_cpu_cycle_write (addr, 1, v); + if (currprefs.m68k_speed < 0) return; - break; - case CE_MEMBANK_FAST: - case CE_MEMBANK_FAST16BIT: - do_cycles_ce000 (4); - break; - } - put_word (addr, v); + x_do_cycles (clocks * cpucycleunit); +} +STATIC_INLINE void do_cycles_ce000 (int clocks) +{ + x_do_cycles (clocks * cpucycleunit); +} + +STATIC_INLINE void ipl_fetch (void) +{ + regs.ipl = regs.ipl_pin; } -STATIC_INLINE uae_u32 get_long_ce (uaecptr addr) +uae_u32 mem_access_delay_word_read (uaecptr addr); +uae_u32 mem_access_delay_wordi_read (uaecptr addr); +uae_u32 mem_access_delay_byte_read (uaecptr addr); +void mem_access_delay_byte_write (uaecptr addr, uae_u32 v); +void mem_access_delay_word_write (uaecptr addr, uae_u32 v); + +STATIC_INLINE uae_u32 get_long_ce000 (uaecptr addr) { uae_u32 v = mem_access_delay_word_read (addr) << 16; v |= mem_access_delay_word_read (addr + 2); return v; } -STATIC_INLINE uae_u32 get_word_ce (uaecptr addr) +STATIC_INLINE uae_u32 get_word_ce000 (uaecptr addr) { return mem_access_delay_word_read (addr); } -STATIC_INLINE uae_u32 get_wordi_ce (uaecptr addr) +STATIC_INLINE uae_u32 get_wordi_ce000 (int offset) { - return mem_access_delay_wordi_read (addr); + return mem_access_delay_wordi_read (m68k_getpci () + offset); } -STATIC_INLINE uae_u32 get_byte_ce (uaecptr addr) +STATIC_INLINE uae_u32 get_byte_ce000 (uaecptr addr) { return mem_access_delay_byte_read (addr); } -STATIC_INLINE uae_u32 get_word_ce_prefetch (int o) +STATIC_INLINE uae_u32 get_word_ce000_prefetch (int o) { uae_u32 v = regs.irc; - regs.irc = get_wordi_ce (m68k_getpc () + o); + regs.irc = regs.db = x_get_iword (o); return v; } -STATIC_INLINE void put_long_ce (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_long_ce000 (uaecptr addr, uae_u32 v) { mem_access_delay_word_write (addr, v >> 16); mem_access_delay_word_write (addr + 2, v); } -STATIC_INLINE void put_word_ce (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_word_ce000 (uaecptr addr, uae_u32 v) { mem_access_delay_word_write (addr, v); } -STATIC_INLINE void put_byte_ce (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_byte_ce000 (uaecptr addr, uae_u32 v) { mem_access_delay_byte_write (addr, v); } @@ -449,28 +383,37 @@ STATIC_INLINE void put_byte_ce (uaecptr STATIC_INLINE void m68k_do_rts_ce (void) { uaecptr pc; - pc = get_word_ce (m68k_areg (regs, 7)) << 16; - pc |= get_word_ce (m68k_areg (regs, 7) + 2); + pc = x_get_word (m68k_areg (regs, 7)) << 16; + pc |= x_get_word (m68k_areg (regs, 7) + 2); m68k_areg (regs, 7) += 4; - if (pc & 1) - exception3 (0x4e75, m68k_getpc (), pc); - else - m68k_setpc (pc); + m68k_setpci (pc); } STATIC_INLINE void m68k_do_bsr_ce (uaecptr oldpc, uae_s32 offset) { m68k_areg (regs, 7) -= 4; - put_word_ce (m68k_areg (regs, 7), oldpc >> 16); - put_word_ce (m68k_areg (regs, 7) + 2, oldpc); - m68k_incpc (offset); + x_put_word (m68k_areg (regs, 7), oldpc >> 16); + x_put_word (m68k_areg (regs, 7) + 2, oldpc); + m68k_incpci (offset); } STATIC_INLINE void m68k_do_jsr_ce (uaecptr oldpc, uaecptr dest) { m68k_areg (regs, 7) -= 4; - put_word_ce (m68k_areg (regs, 7), oldpc >> 16); - put_word_ce (m68k_areg (regs, 7) + 2, oldpc); - m68k_setpc (dest); + x_put_word (m68k_areg (regs, 7), oldpc >> 16); + x_put_word (m68k_areg (regs, 7) + 2, oldpc); + m68k_setpci (dest); } + #endif + +STATIC_INLINE uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp) +{ + int reg = (dp >> 12) & 15; + uae_s32 regd = regs.regs[reg]; + if ((dp & 0x800) == 0) + regd = (uae_s32)(uae_s16)regd; + return base + (uae_s8)dp + regd; +} + +#endif /* UAE_CPU_PREFETCH_H */