+// clear the instruction cache
+inline void m68ki_ic_clear()
+{
+ int i;
+ for (i=0; i< M68K_IC_SIZE; i++) {
+ m68ki_cpu.ic_address[i] = ~0;
+ }
+}
+
+extern uint32 pmmu_translate_addr(uint32 addr_in, const uint16 rw);
+
+// read immediate word using the instruction cache
+
+static inline uint32 m68ki_ic_readimm16(uint32 address)
+{
+ if (m68ki_cpu.cacr & M68K_CACR_EI)
+ {
+ // 68020 series I-cache (MC68020 User's Manual, Section 4 - On-Chip Cache Memory)
+ if (CPU_TYPE & (CPU_TYPE_EC020 | CPU_TYPE_020))
+ {
+ uint32 tag = (address >> 8) | (m68ki_cpu.s_flag ? 0x1000000 : 0);
+ int idx = (address >> 2) & 0x3f; // 1-of-64 select
+
+ // do a cache fill if the line is invalid or the tags don't match
+ if ((!m68ki_cpu.ic_valid[idx]) || (m68ki_cpu.ic_address[idx] != tag))
+ {
+ // if the cache is frozen, don't update it
+ if (m68ki_cpu.cacr & M68K_CACR_FI)
+ {
+ return m68k_read_immediate_16(address);
+ }
+
+ uint32 data = m68ki_read_32(address & ~3);
+
+ //printf("m68k: doing cache fill at %08x (tag %08x idx %d)\n", address, tag, idx);
+
+ // if no buserror occurred, validate the tag
+ if (!m68ki_cpu.mmu_tmp_buserror_occurred)
+ {
+ m68ki_cpu.ic_address[idx] = tag;
+ m68ki_cpu.ic_data[idx] = data;
+ m68ki_cpu.ic_valid[idx] = 1;
+ }
+ else
+ {
+ return m68k_read_immediate_16(address);
+ }
+ }
+
+ // at this point, the cache is guaranteed to be valid, either as
+ // a hit or because we just filled it.
+ if (address & 2)
+ {
+ return m68ki_cpu.ic_data[idx] & 0xffff;
+ }
+ else
+ {
+ return m68ki_cpu.ic_data[idx] >> 16;
+ }
+ }
+ }
+ return m68k_read_immediate_16(address);
+}