]> git.sesse.net Git - pistorm/blob - m68kmmu.h
Add Meson build files.
[pistorm] / m68kmmu.h
1 /*
2     m68kmmu.h - PMMU implementation for 68851/68030/68040
3
4     By R. Belmont
5
6     Copyright Nicola Salmoria and the MAME Team.
7     Visit http://mamedev.org for licensing and usage restrictions.
8 */
9
10 // MMU status register bit definitions
11
12
13
14 struct m68ki_cpu_core;
15 #if 0
16 #define MMULOG(A) printf A
17 #else
18 #define MMULOG(...)
19 #endif
20 #if 1
21 #define logerror printf
22 #else
23 #define logerror(...)
24 #endif
25
26 // MMU SR register fields
27 #define M68K_MMU_SR_BUS_ERROR        0x8000
28 #define M68K_MMU_SR_SUPERVISOR_ONLY  0x2000
29 #define M68K_MMU_SR_WRITE_PROTECT    0x0800
30 #define M68K_MMU_SR_INVALID          0x0400
31 #define M68K_MMU_SR_MODIFIED         0x0200
32 #define M68K_MMU_SR_TRANSPARENT      0x0040
33
34 // MMU translation table descriptor field definitions
35 #define M68K_MMU_DF_DT               0x00000003
36 #define M68K_MMU_DF_DT_INVALID       0x00000000
37 #define M68K_MMU_DF_DT_PAGE          0x00000001
38 #define M68K_MMU_DF_DT_TABLE_4BYTE   0x00000002
39 #define M68K_MMU_DF_DT_TABLE_8BYTE   0x00000003
40 #define M68K_MMU_DF_WP               0x00000004
41 #define M68K_MMU_DF_USED             0x00000008
42 #define M68K_MMU_DF_MODIFIED         0x00000010
43 #define M68K_MMU_DF_CI               0x00000040
44 #define M68K_MMU_DF_SUPERVISOR       0x00000100
45 #define M68K_MMU_DF_ADDR_MASK        0xfffffff0
46 #define M68K_MMU_DF_IND_ADDR_MASK    0xfffffffc
47
48 // MMU ATC Fields
49 #define M68K_MMU_ATC_BUSERROR        0x08000000
50 #define M68K_MMU_ATC_CACHE_IN        0x04000000
51 #define M68K_MMU_ATC_WRITE_PR        0x02000000
52 #define M68K_MMU_ATC_MODIFIED        0x01000000
53 #define M68K_MMU_ATC_MASK            0x00ffffff
54 #define M68K_MMU_ATC_SHIFT           8
55 #define M68K_MMU_ATC_VALID           0x08000000
56
57 // MMU Translation Control register
58 #define M68K_MMU_TC_SRE              0x02000000
59 #define M68K_MMU_TC_FCL              0x01000000
60
61 // TT register
62 #define M68K_MMU_TT_ENABLE           0x8000
63
64 #define m_side_effects_disabled 0
65
66 /* decodes the effective address */
67 uint32 DECODE_EA_32(m68ki_cpu_core *state, int ea)
68 {
69         int mode = (ea >> 3) & 0x7;
70         int reg = (ea & 0x7);
71
72         switch (mode)
73         {
74                 case 2:     // (An)
75                 {
76                         return REG_A[reg];
77                 }
78                 case 3:     // (An)+
79                 {
80                         uint32 ea = EA_AY_PI_32();
81                         return ea;
82                 }
83                 case 5:     // (d16, An)
84                 {
85                         uint32 ea = EA_AY_DI_32();
86                         return ea;
87                 }
88                 case 6:     // (An) + (Xn) + d8
89                 {
90                         uint32 ea = EA_AY_IX_32();
91                         return ea;
92                 }
93                 case 7:
94                 {
95                         switch (reg)
96                         {
97                                 case 0:     // (xxx).W
98                                 {
99                                         uint32 ea = OPER_I_16(state);
100                                         return ea;
101                                 }
102                                 case 1:     // (xxx).L
103                                 {
104                                         uint32 d1 = OPER_I_16(state);
105                                         uint32 d2 = OPER_I_16(state);
106                                         uint32 ea = (d1 << 16) | d2;
107                                         return ea;
108                                 }
109                                 case 2:     // (d16, PC)
110                                 {
111                                         uint32 ea = EA_PCDI_32();
112                                         return ea;
113                                 }
114                                 default:    fatalerror("m68k: DECODE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
115                         }
116                         break;
117                 }
118                 default:    fatalerror("m68k: DECODE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
119         }
120         return 0;
121 }
122
123 void pmmu_set_buserror(m68ki_cpu_core *state, uint32 addr_in)
124 {
125         if (!m_side_effects_disabled && ++state->mmu_tmp_buserror_occurred == 1)
126         {
127                 state->mmu_tmp_buserror_address = addr_in;
128                 state->mmu_tmp_buserror_rw = state->mmu_tmp_rw;
129                 state->mmu_tmp_buserror_fc = state->mmu_tmp_fc;
130                 state->mmu_tmp_buserror_sz = state->mmu_tmp_sz;
131         }
132 }
133
134
135 // pmmu_atc_add: adds this address to the ATC
136 void pmmu_atc_add(m68ki_cpu_core *state, uint32 logical, uint32 physical, int fc, int rw)
137 {
138         // get page size (i.e. # of bits to ignore); is 10 for Apollo
139         int ps = (state->mmu_tc >> 20) & 0xf;
140         uint32 atc_tag = M68K_MMU_ATC_VALID | ((fc & 7) << 24) | ((logical >> ps) << (ps - 8));
141         uint32 atc_data = (physical >> ps) << (ps - 8);
142
143         if (state->mmu_tmp_sr & (M68K_MMU_SR_BUS_ERROR|M68K_MMU_SR_INVALID|M68K_MMU_SR_SUPERVISOR_ONLY))
144         {
145                 atc_data |= M68K_MMU_ATC_BUSERROR;
146         }
147
148         if (state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT)
149         {
150                 atc_data |= M68K_MMU_ATC_WRITE_PR;
151         }
152
153         if (!rw && !(state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT))
154         {
155                 atc_data |= M68K_MMU_ATC_MODIFIED;
156         }
157
158         // first see if this is already in the cache
159         for (int i = 0; i < MMU_ATC_ENTRIES; i++)
160         {
161                 // if tag bits and function code match, don't add
162                 if (state->mmu_atc_tag[i] == atc_tag)
163                 {
164                         MMULOG(("%s: hit, old %08x new %08x\n", __func__, state->mmu_atc_data[i], atc_data));
165                         state->mmu_atc_data[i] = atc_data;
166                         return;
167                 }
168         }
169
170         // find an open entry
171         int found = -1;
172         for (int i = 0; i < MMU_ATC_ENTRIES; i++)
173         {
174                 if (!(state->mmu_atc_tag[i] & M68K_MMU_ATC_VALID))
175                 {
176                         found = i;
177                         break;
178                 }
179         }
180
181         // did we find an entry?  steal one by round-robin then
182         if (found == -1)
183         {
184                 found = state->mmu_atc_rr++;
185
186                 if (state->mmu_atc_rr >= MMU_ATC_ENTRIES)
187                 {
188                         state->mmu_atc_rr = 0;
189                 }
190         }
191
192         // add the entry
193         MMULOG(("ATC[%2d] add: log %08x -> phys %08x (fc=%d) data=%08x\n",
194                         found, (logical >> ps) << ps, (physical >> ps) << ps, fc, atc_data));
195         state->mmu_atc_tag[found] = atc_tag;
196         state->mmu_atc_data[found] = atc_data;
197 }
198
199 // pmmu_atc_flush: flush entire ATC
200 // 7fff0003 001ffd10 80f05750 is what should load
201 void pmmu_atc_flush(m68ki_cpu_core *state)
202 {
203         MMULOG(("ATC flush: pc=%08x\n", state->ppc));
204 //      std::fill(std::begin(state->mmu_atc_tag), std::end(state->mmu_atc_tag), 0);
205         for(int i=0;i<MMU_ATC_ENTRIES;i++)
206                 state->mmu_atc_tag[i]=0;
207         state->mmu_atc_rr = 0;
208 }
209
210 int fc_from_modes(m68ki_cpu_core *state, uint16 modes);
211
212 void pmmu_atc_flush_fc_ea(m68ki_cpu_core *state, uint16 modes)
213 {
214         unsigned int fcmask = (modes >> 5) & 7;
215         unsigned int fc = fc_from_modes(state, modes) & fcmask;
216         unsigned int ps = (state->mmu_tc >> 20) & 0xf;
217         unsigned int mode = (modes >> 10) & 7;
218         uint32 ea;
219
220         switch (mode)
221         {
222         case 1: // PFLUSHA
223                 MMULOG(("PFLUSHA: mode %d\n", mode));
224                         pmmu_atc_flush(state);
225                 break;
226
227         case 4: // flush by fc
228                 MMULOG(("flush by fc: %d, mask %d\n", fc, fcmask));
229                 for(int i=0,e;i<MMU_ATC_ENTRIES;i++)
230                 {
231                         e=state->mmu_atc_tag[i];
232                         if ((e & M68K_MMU_ATC_VALID) && ((e >> 24) & fcmask) == fc)
233                         {
234                                 MMULOG(("flushing entry %08x\n", e));
235                                 state->mmu_atc_tag[i] = 0;
236                         }
237                 }
238                 break;
239
240         case 6: // flush by fc + ea
241
242                 ea = DECODE_EA_32(state, state->ir);
243                 MMULOG(("flush by fc/ea: fc %d, mask %d, ea %08x\n", fc, fcmask, ea));
244                 for(unsigned int i=0,e;i<MMU_ATC_ENTRIES;i++)
245                 {
246                         e=state->mmu_atc_tag[i];
247                         if ((e & M68K_MMU_ATC_VALID) &&
248                                 (((e >> 24) & fcmask) == fc) &&
249 //              (((e >> ps) << (ps - 8)) == ((ea >> ps) << (ps - 8))))
250                                 ( (e << ps) == (ea >> 8 << ps) ))
251                         {
252                                 MMULOG(("flushing entry %08x\n", e));
253                                 state->mmu_atc_tag[i] = 0;
254                         }
255                 }
256                 break;
257
258         default:
259                 logerror("PFLUSH mode %d not supported\n", mode);
260                 break;
261         }
262 }
263
264 //template<bool ptest>
265 uint16 pmmu_atc_lookup(m68ki_cpu_core *state, uint32 addr_in, int fc, uint16 rw, uint32 *addr_out, int ptest)
266 {
267         MMULOG(("%s: LOOKUP addr_in=%08x, fc=%d, ptest=%d, rw=%d\n", __func__, addr_in, fc, ptest,rw));
268         unsigned int ps = (state->mmu_tc >> 20) & 0xf;
269         uint32 atc_tag = M68K_MMU_ATC_VALID | ((fc & 7) << 24) | ((addr_in >> ps) << (ps - 8));
270
271         for (int i = 0; i < MMU_ATC_ENTRIES; i++)
272         {
273
274                 if (state->mmu_atc_tag[i] != atc_tag)
275                 {
276                         continue;
277                 }
278                 
279                 uint32 atc_data = state->mmu_atc_data[i];
280
281                 if (!ptest && !rw)
282                 {
283                         // According to MC86030UM:
284                         // "If the M bit is clear and a write access to this logical
285                         // address is attempted, the MC68030 aborts the access and initiates a table
286                         // search, setting the M bit in the page descriptor, invalidating the old ATC
287                         // entry, and creating a new entry with the M bit set.
288                         if (!(atc_data & M68K_MMU_ATC_MODIFIED))
289                         {
290                                 state->mmu_atc_tag[i] = 0;
291                                 continue;
292                         }
293                 }
294
295                 state->mmu_tmp_sr = 0;
296                 if (atc_data & M68K_MMU_ATC_MODIFIED)
297                 {
298                         state->mmu_tmp_sr |= M68K_MMU_SR_MODIFIED;
299                 }
300
301                 if (atc_data & M68K_MMU_ATC_WRITE_PR)
302                 {
303                         state->mmu_tmp_sr |= M68K_MMU_SR_WRITE_PROTECT;
304                 }
305
306                 if (atc_data & M68K_MMU_ATC_BUSERROR)
307                 {
308                         state->mmu_tmp_sr |= M68K_MMU_SR_BUS_ERROR|M68K_MMU_SR_INVALID;
309                 }
310                 *addr_out = (atc_data << 8) | (addr_in & ~(((uint32)~0) << ps));
311                 MMULOG(("%s: addr_in=%08x, addr_out=%08x, MMU SR %04x\n",
312                                 __func__, addr_in, *addr_out, state->mmu_tmp_sr));
313                 return 1;
314         }
315         MMULOG(("%s: lookup failed\n", __func__));
316         if (ptest)
317         {
318                 state->mmu_tmp_sr = M68K_MMU_SR_INVALID;
319         }
320         return 0;
321 }
322
323 uint16 pmmu_match_tt(m68ki_cpu_core *state, uint32 addr_in, int fc, uint32 tt, uint16 rw)
324 {
325         if (!(tt & M68K_MMU_TT_ENABLE))
326         {
327                 return 0;
328         }
329
330         // transparent translation enabled
331         uint32 address_base = tt & 0xff000000;
332         uint32 address_mask = ((tt << 8) & 0xff000000) ^ 0xff000000;
333         uint32 fcmask = (~tt) & 7;
334         uint32 fcbits = (tt >> 4) & 7;
335         uint16 rwmask = !!(~tt & 0x100);
336         uint16 rwbit = !!(tt & 0x200);
337
338         if ((addr_in & address_mask) != (address_base & address_mask))
339         {
340                 return 0;
341         }
342
343         if ((fc & fcmask) != (fcbits & fcmask))
344         {
345                 return 0;
346         }
347
348         if ((rw & rwmask) != (rwbit & rwmask))
349         {
350                 return 0;
351         }
352
353         state->mmu_tmp_sr |= M68K_MMU_SR_TRANSPARENT;
354         return 1;
355 }
356
357 void update_descriptor(m68ki_cpu_core *state, uint32 tptr, int type, uint32 entry, int16 rw)
358 {
359         // FIXME: Silence unused variable warning
360         if (state) {}
361
362         if (type == M68K_MMU_DF_DT_PAGE && !rw &&
363                         !(entry & M68K_MMU_DF_MODIFIED) &&
364                         !(entry & M68K_MMU_DF_WP))
365         {
366                 MMULOG(("%s: set M+U at %08x\n", __func__, tptr));
367                 m68k_write_memory_32(tptr, entry | M68K_MMU_DF_USED | M68K_MMU_DF_MODIFIED);
368         }
369         else if (type != M68K_MMU_DF_DT_INVALID && !(entry & M68K_MMU_DF_USED))
370         {
371                 MMULOG(("%s: set U at %08x\n", __func__, tptr));
372                 m68k_write_memory_32(tptr, entry | M68K_MMU_DF_USED);
373         }
374 }
375
376
377 //template<bool _long>
378 void update_sr(m68ki_cpu_core *state, int type, uint32 tbl_entry, int fc, uint16 _long)
379 {
380         if (m_side_effects_disabled)
381         {
382                 return;
383         }
384
385         switch(type)
386         {
387         case M68K_MMU_DF_DT_INVALID:
388                 // Invalid has no flags
389                 break;
390
391         case M68K_MMU_DF_DT_PAGE:
392                 if (tbl_entry & M68K_MMU_DF_MODIFIED)
393                 {
394                         state->mmu_tmp_sr |= M68K_MMU_SR_MODIFIED;
395                 }
396                 /* FALLTHROUGH */
397
398         case M68K_MMU_DF_DT_TABLE_4BYTE:
399                 /* FALLTHROUGH */
400
401         case M68K_MMU_DF_DT_TABLE_8BYTE:
402
403                 if (tbl_entry & M68K_MMU_DF_WP)
404                 {
405                         state->mmu_tmp_sr |= M68K_MMU_SR_WRITE_PROTECT;
406                 }
407
408                 if (_long && !(fc & 4) && (tbl_entry & M68K_MMU_DF_SUPERVISOR))
409                 {
410                         state->mmu_tmp_sr |= M68K_MMU_SR_SUPERVISOR_ONLY;
411                 }
412                 break;
413         default:
414                 break;
415         }
416 }
417
418 //template<bool ptest>
419 uint16 pmmu_walk_tables(m68ki_cpu_core *state, uint32 addr_in, int type, uint32 table, uint8 fc, int limit, uint16 rw,
420                                                 uint32 *addr_out, int ptest)
421 {
422         int level = 0;
423         uint32 bits = state->mmu_tc & 0xffff;
424         int pagesize = (state->mmu_tc >> 20) & 0xf;
425         int is = (state->mmu_tc >> 16) & 0xf;
426         int bitpos = 12;
427         int resolved = 0;
428         int pageshift = is;
429
430         addr_in <<= is;
431
432         state->mmu_tablewalk = 1;
433
434         if (state->mmu_tc & M68K_MMU_TC_FCL)
435         {
436                 bitpos = 16;
437         }
438
439         do
440         {
441                 int indexbits = (bits >> bitpos) & 0xf;
442                 int table_index  = (bitpos == 16) ? fc : (addr_in >> (32 - indexbits));
443                 bitpos -= 4;
444                 uint16 indirect = (!bitpos || !(bits >> bitpos)) && indexbits;
445                 uint32 tbl_entry, tbl_entry2;
446
447                 MMULOG(("%s: type %d, table %08x, addr_in %08x, indexbits %d, pageshift %d, indirect %d table_index %08x, rw=%d fc=%d\n",
448                                 __func__, type, table, addr_in, indexbits, pageshift, indirect, table_index, rw, fc));
449
450                 switch(type)
451                 {
452                         case M68K_MMU_DF_DT_INVALID:   // invalid, will cause MMU exception
453                                 state->mmu_tmp_sr = M68K_MMU_SR_INVALID;
454                                 MMULOG(("PMMU: DT0 PC=%x (addr_in %08x -> %08x)\n", state->ppc, addr_in, *addr_out));
455                                 resolved = 1;
456                                 break;
457
458                         case M68K_MMU_DF_DT_PAGE:   // page descriptor, will cause direct mapping
459                                 if (!ptest)
460                                 {
461                                         table &= ((uint32)~0) << pagesize;
462                                         *addr_out = table + (addr_in >> pageshift);
463                                 }
464                                 resolved = 1;
465                                 break;
466
467                         case M68K_MMU_DF_DT_TABLE_4BYTE:   // valid 4 byte descriptors
468                                 level++;
469                                 *addr_out = table + (table_index << 2);
470                                 tbl_entry = m68k_read_memory_32(*addr_out);
471                                 type = tbl_entry & M68K_MMU_DF_DT;
472
473                                 if (indirect && (type == 2 || type == 3))
474                                 {
475                                         level++;
476                                         MMULOG(("SHORT INDIRECT DESC: %08x\n", tbl_entry));
477                                         *addr_out = tbl_entry & M68K_MMU_DF_IND_ADDR_MASK;
478                                         tbl_entry = m68k_read_memory_32(*addr_out);
479                                         type = tbl_entry & M68K_MMU_DF_DT;
480                                 }
481
482                                 MMULOG(("SHORT DESC: %08x\n", tbl_entry));
483                                 table = tbl_entry & M68K_MMU_DF_ADDR_MASK;
484                                 if (!m_side_effects_disabled)
485                                 {
486                                         update_sr(state, type, tbl_entry, fc, 0);
487                                         if (!ptest)
488                                         {
489                                                 update_descriptor(state, *addr_out, type, tbl_entry, rw);
490                                         }
491                                 }
492                                 break;
493
494                         case M68K_MMU_DF_DT_TABLE_8BYTE:   // valid 8 byte descriptors
495                                 level++;
496                                 *addr_out = table + (table_index << 3);
497                                 tbl_entry = m68k_read_memory_32(*addr_out);
498                                 tbl_entry2 = m68k_read_memory_32((*addr_out) + 4);
499                                 type = tbl_entry & M68K_MMU_DF_DT;
500
501                                 if (indirect && (type == 2 || type == 3))
502                                 {
503                                         level++;
504                                         MMULOG(("LONG INDIRECT DESC: %08x%08x\n", tbl_entry, tbl_entry2));
505                                         *addr_out = tbl_entry2 & M68K_MMU_DF_IND_ADDR_MASK;
506                                         tbl_entry = m68k_read_memory_32(*addr_out);
507                                         tbl_entry2 = m68k_read_memory_32(*addr_out);
508                                         type = tbl_entry & M68K_MMU_DF_DT;
509                                 }
510
511                                 MMULOG(("LONG DESC: %08x %08x\n", tbl_entry, tbl_entry2));
512                                 table = tbl_entry2 & M68K_MMU_DF_ADDR_MASK;
513                                 if (!m_side_effects_disabled)
514                                 {
515                                         update_sr(state, type, tbl_entry, fc, 1);
516                                         if (!ptest)
517                                         {
518                                                 update_descriptor(state, *addr_out, type, tbl_entry, rw);
519                                         }
520                                 }
521                                 break;
522                 }
523
524                 if (state->mmu_tmp_sr & M68K_MMU_SR_BUS_ERROR)
525                 {
526                         // Bus error during page table walking is always fatal
527                         resolved = 1;
528                         break;
529                 }
530
531                 if (!ptest && !m_side_effects_disabled)
532                 {
533                         if (!rw && (state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT))
534                         {
535                                 resolved = 1;
536                                 break;
537                         }
538
539                         if (!(fc & 4) && (state->mmu_tmp_sr & M68K_MMU_SR_SUPERVISOR_ONLY))
540                         {
541                                 resolved = 1;
542                                 break;
543                         }
544
545                 }
546                 addr_in <<= indexbits;
547                 pageshift += indexbits;
548         } while(level < limit && !resolved);
549
550
551         state->mmu_tmp_sr &= 0xfff0;
552         state->mmu_tmp_sr |= level;
553         MMULOG(("MMU SR after walk: %04X\n", state->mmu_tmp_sr));
554         state->mmu_tablewalk = 0;
555         return resolved;
556 }
557
558 // pmmu_translate_addr_with_fc: perform 68851/68030-style PMMU address translation
559 //template<bool ptest, bool pload>
560 uint32 pmmu_translate_addr_with_fc(m68ki_cpu_core *state, uint32 addr_in, uint8 fc, uint16 rw, int limit, int ptest,
561                                                                    int pload)
562 {
563         uint32 addr_out = 0;
564
565
566         MMULOG(("%s: addr_in=%08x, fc=%d, ptest=%d, rw=%d, limit=%d, pload=%d\n",
567                         __func__, addr_in, fc, ptest, rw, limit, pload));
568         state->mmu_tmp_sr = 0;
569
570         state->mmu_last_logical_addr = addr_in;
571
572         if (pmmu_match_tt(state, addr_in, fc, state->mmu_tt0, rw) ||
573                 pmmu_match_tt(state, addr_in, fc, state->mmu_tt1, rw) ||
574                 fc == 7)
575         {
576                 return addr_in;
577         }
578
579         if (ptest && limit == 0)
580         {
581                 pmmu_atc_lookup(state, addr_in, fc, rw, &addr_out, 1);
582                 return addr_out;
583         }
584
585         if (!ptest && !pload && pmmu_atc_lookup(state, addr_in, fc, rw, &addr_out, 0))
586         {
587                 if ((state->mmu_tmp_sr & M68K_MMU_SR_BUS_ERROR) || (!rw && (state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT)))
588                 {
589                         MMULOG(("set atc hit buserror: addr_in=%08x, addr_out=%x, rw=%x, fc=%d, sz=%d\n",
590                                         addr_in, addr_out, state->mmu_tmp_rw, state->mmu_tmp_fc, state->mmu_tmp_sz));
591                         pmmu_set_buserror(state, addr_in);
592                 }
593                 return addr_out;
594         }
595
596         int type;
597         uint32 tbl_addr;
598         // if SRP is enabled and we're in supervisor mode, use it
599         if ((state->mmu_tc & M68K_MMU_TC_SRE) && (fc & 4))
600         {
601                 tbl_addr = state->mmu_srp_aptr & M68K_MMU_DF_ADDR_MASK;
602                 type = state->mmu_srp_limit & M68K_MMU_DF_DT;
603         }
604         else    // else use the CRP
605         {
606                 tbl_addr = state->mmu_crp_aptr & M68K_MMU_DF_ADDR_MASK;
607                 type = state->mmu_crp_limit & M68K_MMU_DF_DT;
608         }
609
610         if (!pmmu_walk_tables(state, addr_in, type, tbl_addr, fc, limit, rw, &addr_out, ptest))
611         {
612                 MMULOG(("%s: addr_in=%08x, type=%x, tbl_addr=%x, fc=%d, limit=%x, rw=%x, addr_out=%x, ptest=%d\n",
613                                 __func__, addr_in, type, tbl_addr, fc, limit, rw, addr_out, ptest));
614                 fatalerror("Table walk did not resolve\n");
615         }
616
617         if (ptest)
618         {
619                 return addr_out;
620         }
621
622         if ((state->mmu_tmp_sr & (M68K_MMU_SR_INVALID|M68K_MMU_SR_SUPERVISOR_ONLY)) ||
623                         ((state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT) && !rw))
624         {
625
626                 if (!pload)
627                 {
628                         MMULOG(("%s: set buserror (SR %04X)\n", __func__, state->mmu_tmp_sr));
629                         pmmu_set_buserror(state, addr_in);
630                 }
631         }
632
633         // it seems like at least the 68030 sets the M bit in the MMU SR
634         // if the root descriptor is of PAGE type, so do a logical and
635         // between RW and the root type
636         if (!m_side_effects_disabled)
637         {
638                 pmmu_atc_add(state, addr_in, addr_out, fc, rw && type != 1);
639         }
640         MMULOG(("PMMU: [%08x] => [%08x] (SR %04x)\n", addr_in, addr_out, state->mmu_tmp_sr));
641         return addr_out;
642 }
643
644 // FC bits: 2 = supervisor, 1 = program, 0 = data
645 // the 68040 is a subset of the 68851 and 68030 PMMUs - the page table sizes are fixed, there is no early termination, etc, etc.
646 uint32 pmmu_translate_addr_with_fc_040(m68ki_cpu_core *state, uint32 addr_in, uint8 fc, uint8 ptest)
647 {
648         uint32 addr_out, tt0, tt1;
649
650         addr_out = addr_in;
651         state->mmu_tmp_sr = 0;
652
653         // transparent translation registers are always in force even if the PMMU itself is disabled
654         // they don't do much in emulation because we never write out of order, but the write-protect and cache control features
655         // are emulatable, and apparently transparent translation regions skip the page table lookup.
656         if (fc & 1) // data, use DTT0/DTT1
657         {
658                 tt0 = state->mmu_dtt0;
659                 tt1 = state->mmu_dtt1;
660         }
661         else if (fc & 2)    // program, use ITT0/ITT1
662         {
663                 tt0 = state->mmu_itt0;
664                 tt1 = state->mmu_itt1;
665         }
666         else
667         {
668                 fatalerror("68040: function code %d is neither data nor program!\n", fc & 7);
669         }
670
671         if (tt0 & M68K_MMU_TT_ENABLE)
672         {
673                 int fcmask[4] = { 4, 4, 0, 0 };
674                 int fcmatch[4] = { 0, 4, 0, 0 };
675                 uint32 mask = (tt0 >> 16) & 0xff;
676                 mask ^= 0xff;
677                 mask <<= 24;
678
679                 if ((addr_in & mask) == (tt0 & mask) && (fc & fcmask[(tt0 >> 13) & 3]) == fcmatch[(tt0 >> 13) & 3])
680                 {
681                         MMULOG(("TT0 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt0, mask));
682                         if ((tt0 & 4) && !state->mmu_tmp_rw && !ptest)   // write protect?
683                         {
684                                 pmmu_set_buserror(state, addr_in);
685                         }
686
687                         return addr_in;
688                 }
689         }
690
691         if (tt1 & M68K_MMU_TT_ENABLE)
692         {
693                 static int fcmask[4] = { 4, 4, 0, 0 };
694                 static int fcmatch[4] = { 0, 4, 0, 0 };
695                 uint32 mask = (tt1 >> 16) & 0xff;
696                 mask ^= 0xff;
697                 mask <<= 24;
698
699                 if ((addr_in & mask) == (tt1 & mask) && (fc & fcmask[(tt1 >> 13) & 3]) == fcmatch[(tt1 >> 13) & 3])
700                 {
701                         MMULOG(("TT1 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt1, mask));
702                         if ((tt1 & 4) && !state->mmu_tmp_rw && !ptest)   // write protect?
703                         {
704                                 pmmu_set_buserror(state, addr_in);
705                         }
706
707                         return addr_in;
708                 }
709         }
710
711         if (state->pmmu_enabled)
712         {
713                 uint32 root_idx = (addr_in >> 25) & 0x7f;
714                 uint32 ptr_idx = (addr_in >> 18) & 0x7f;
715                 uint32 page_idx, page;
716                 uint32 root_ptr, pointer_ptr, page_ptr;
717                 uint32 root_entry, pointer_entry, page_entry;
718
719                 // select supervisor or user root pointer
720                 if (fc & 4)
721                 {
722                         root_ptr = state->mmu_srp_aptr + (root_idx<<2);
723                 }
724                 else
725                 {
726                         root_ptr = state->mmu_urp_aptr + (root_idx<<2);
727                 }
728
729                 // get the root entry
730                 root_entry = m68k_read_memory_32(root_ptr);
731
732                 // is UDT marked valid?
733                 if (root_entry & 2)
734                 {
735                         // we're accessing through this root entry, so set the U bit
736                         if ((!(root_entry & 0x8)) && (!ptest) && !m_side_effects_disabled)
737                         {
738                                 root_entry |= 0x8;
739                                 m68k_write_memory_32(root_ptr, root_entry);
740                         }
741
742                         // PTEST: any write protect bits set in the search tree will set W in SR
743                         if ((ptest) && (root_entry & 4))
744                         {
745                                 state->mmu_tmp_sr |= 4;
746                         }
747
748                         pointer_ptr = (root_entry & ~0x1ff) + (ptr_idx<<2);
749                         pointer_entry = m68k_read_memory_32(pointer_ptr);
750
751                         // PTEST: any write protect bits set in the search tree will set W in SR
752                         if ((ptest) && (pointer_entry & 4))
753                         {
754                                 state->mmu_tmp_sr |= 4;
755                         }
756
757                         // update U bit on this pointer entry too
758                         if ((!(pointer_entry & 0x8)) && (!ptest) && !m_side_effects_disabled)
759                         {
760                                 pointer_entry |= 0x8;
761                                 m68k_write_memory_32(pointer_ptr, pointer_entry);
762                         }
763
764                         MMULOG(("pointer entry = %08x\n", pointer_entry));
765
766                         // write protected by the root or pointer entries?
767                         if ((((root_entry & 4) && !state->mmu_tmp_rw) || ((pointer_entry & 4) && !state->mmu_tmp_rw)) && !ptest)
768                         {
769                                 pmmu_set_buserror(state, addr_in);
770                                 return addr_in;
771                         }
772
773                         // is UDT valid on the pointer entry?
774                         if (!(pointer_entry & 2) && !ptest)
775                         {
776                                 logerror("Invalid pointer entry!  PC=%x, addr=%x\n", state->ppc, addr_in);
777                                 pmmu_set_buserror(state, addr_in);
778                                 return addr_in;
779                         }
780
781                         // (fall out of these ifs into the page lookup below)
782                 }
783                 else // throw an error
784                 {
785                         logerror("Invalid root entry!  PC=%x, addr=%x\n", state->ppc, addr_in);
786
787                         if (!ptest)
788                         {
789                                 pmmu_set_buserror(state, addr_in);
790                         }
791
792                         return addr_in;
793                 }
794
795                 // now do the page lookup
796                 if (state->mmu_tc & 0x4000)  // 8k pages?
797                 {
798                         page_idx = (addr_in >> 13) & 0x1f;
799                         page = addr_in & 0x1fff;
800                         pointer_entry &= ~0x7f;
801                         MMULOG(("8k pages: index %x page %x\n", page_idx, page));
802                 }
803                 else    // 4k pages
804                 {
805                         page_idx = (addr_in >> 12) & 0x3f;
806                         page = addr_in & 0xfff;
807                         pointer_entry &= ~0xff;
808                         MMULOG(("4k pages: index %x page %x\n", page_idx, page));
809                 }
810
811                 page_ptr = pointer_entry + (page_idx<<2);
812                 page_entry = m68k_read_memory_32(page_ptr);
813                 state->mmu_last_page_entry_addr = page_ptr;
814
815                 MMULOG(("page_entry = %08x\n", page_entry));
816
817                 // resolve indirect page pointers
818                 while ((page_entry & 3) == 2)
819                 {
820                         page_entry = m68k_read_memory_32(page_entry & ~0x3);
821                         state->mmu_last_page_entry_addr = (page_entry & ~0x3);
822                 }
823                 state->mmu_last_page_entry = page_entry;
824
825                 // is the page write protected or supervisor protected?
826                 if ((((page_entry & 4) && !state->mmu_tmp_rw) || ((page_entry & 0x80) && !(fc & 4))) && !ptest)
827                 {
828                         pmmu_set_buserror(state, addr_in);
829                         return addr_in;
830                 }
831
832                 switch (page_entry & 3)
833                 {
834                         case 0: // invalid
835                                 MMULOG(("Invalid page entry!  PC=%x, addr=%x\n", state->ppc, addr_in));
836                                 if (!ptest)
837                                 {
838                                         pmmu_set_buserror(state, addr_in);
839                                 }
840
841                                 return addr_in;
842
843                         case 1:
844                         case 3: // normal
845                                 if (state->mmu_tc & 0x4000)  // 8k pages?
846                                 {
847                                         addr_out = (page_entry & ~0x1fff) | page;
848                                 }
849                                 else
850                                 {
851                                         addr_out = (page_entry & ~0xfff) | page;
852                                 }
853
854                                 if (!(ptest))
855                                 {
856                                         page_entry |= 0x8;  // always set the U bit
857
858                                         // if we're writing, the M bit comes into play
859                                         if (!state->mmu_tmp_rw)
860                                         {
861                                                 page_entry |= 0x10; // set Modified
862                                         }
863
864                                         // if these updates resulted in a change, write the entry back where we found it
865                                         if (page_entry != state->mmu_last_page_entry && !m_side_effects_disabled)
866                                         {
867                                                 state->mmu_last_page_entry = page_entry;
868                                                 m68k_write_memory_32(state->mmu_last_page_entry_addr, state->mmu_last_page_entry);
869                                         }
870                                 }
871                                 else
872                                 {
873                                         // page entry: UR G U1 U0 S CM CM M U W PDT
874                                         // SR:         B  G U1 U0 S CM CM M 0 W T R
875                                         state->mmu_tmp_sr |= ((addr_out & ~0xfff) || (page_entry & 0x7f4));
876                                 }
877                                 break;
878
879                         case 2: // shouldn't happen
880                                 fatalerror("68040: got indirect final page pointer, shouldn't be possible\n");
881                                 break;
882                 }
883                 //      if (addr_in != addr_out) MMULOG(("040MMU: [%08x] => [%08x]\n", addr_in, addr_out));
884         }
885
886         return addr_out;
887 }
888
889 // pmmu_translate_addr: perform 68851/68030-style PMMU address translation
890 uint32 pmmu_translate_addr(m68ki_cpu_core *state, uint32 addr_in, uint16 rw)
891 {
892         uint32 addr_out;
893
894         if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
895         {
896                 addr_out = pmmu_translate_addr_with_fc_040(state, addr_in, state->mmu_tmp_fc, 0);
897         }
898         else
899         {
900                 addr_out = pmmu_translate_addr_with_fc(state, addr_in, state->mmu_tmp_fc, rw, 7, 0, 0);
901                 MMULOG(("ADDRIN %08X, ADDROUT %08X\n", addr_in, addr_out));
902         }
903         return addr_out;
904 }
905
906 int fc_from_modes(m68ki_cpu_core *state, uint16 modes)
907 {
908         if ((modes & 0x1f) == 0)
909         {
910                 return state->sfc;
911         }
912
913         if ((modes & 0x1f) == 1)
914         {
915                 return state->dfc;
916         }
917
918         if (state->cpu_type & CPU_TYPE_030)
919         {
920                 // 68030 has 3 bits fc, but 68851 4 bits
921                 if (((modes >> 3) & 3) == 1)
922                 {
923                         return REG_D[modes & 7] & 0x7;
924                 }
925
926                 if (((modes >> 3) & 3) == 2)
927                 {
928                         return modes & 7;
929                 }
930         }
931         else
932         {
933                 if (((modes >> 3) & 3) == 1)
934                 {
935                         return REG_D[modes & 7] & 0xf;
936                 }
937
938                 if (modes & 0x10)
939                 {
940                         return modes & 0xf;
941                 }
942         }
943
944
945         fatalerror("%s: unknown fc mode: 0x%02xn", __func__, modes & 0x1f);
946         return 0;
947 }
948
949 void m68851_pload(m68ki_cpu_core *state, uint32 ea, uint16 modes)
950 {
951         uint32 ltmp = DECODE_EA_32(state, ea);
952         int fc = fc_from_modes(state, modes);
953         uint16 rw = !!(modes & 0x200);
954
955         MMULOG(("%s: PLOAD%c addr=%08x, fc=%d\n", __func__, rw ? 'R' : 'W', ltmp, fc));
956
957         // MC68851 traps if MMU is not enabled, 030 not
958         if (state->pmmu_enabled || (state->cpu_type & CPU_TYPE_030))
959         {
960                 if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
961                 {
962                         pmmu_translate_addr_with_fc_040(state, ltmp, fc, 0);
963                 }
964                 else
965                 {
966                         pmmu_translate_addr_with_fc(state, ltmp, fc, rw, 7, 0, 1);
967                 }
968         }
969         else
970         {
971                 MMULOG(("PLOAD with MMU disabled on MC68851\n"));
972                 m68ki_exception_trap(state, 57);
973                 return;
974         }
975 }
976
977 void m68851_ptest(m68ki_cpu_core *state, uint32 ea, uint16 modes)
978 {
979         uint32 v_addr = DECODE_EA_32(state, ea);
980         uint32 p_addr;
981
982         int level = (modes >> 10) & 7;
983         uint16 rw = !!(modes & 0x200);
984         int fc = fc_from_modes(state, modes);
985
986         MMULOG(("PMMU: PTEST%c (%04X) pc=%08x sp=%08x va=%08x fc=%x level=%x a=%d, areg=%d\n",
987                         rw ? 'R' : 'W', modes, state->ppc, REG_A[7], v_addr, fc, level,
988                                         (modes & 0x100) ? 1 : 0, (modes >> 5) & 7));
989
990         if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
991         {
992                 p_addr = pmmu_translate_addr_with_fc_040(state, v_addr, fc, 1);
993         }
994         else
995         {
996                 p_addr = pmmu_translate_addr_with_fc(state, v_addr, fc, rw, level, 1, 0);
997         }
998
999         state->mmu_sr = state->mmu_tmp_sr;
1000
1001         MMULOG(("PMMU: PTEST result: %04x pa=%08x\n", state->mmu_sr, p_addr));
1002         if (modes & 0x100)
1003         {
1004                 int areg = (modes >> 5) & 7;
1005                 WRITE_EA_32(state, 0x08 | areg, p_addr);
1006         }
1007 }
1008
1009 void m68851_pmove_get(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1010 {
1011         switch ((modes>>10) & 0x3f)
1012         {
1013         case 0x02: // transparent translation register 0
1014                 WRITE_EA_32(state, ea, state->mmu_tt0);
1015                 MMULOG(("PMMU: pc=%x PMOVE from mmu_tt0=%08x\n", state->ppc, state->mmu_tt0));
1016                 break;
1017         case 0x03: // transparent translation register 1
1018                 WRITE_EA_32(state, ea, state->mmu_tt1);
1019                 MMULOG(("PMMU: pc=%x PMOVE from mmu_tt1=%08x\n", state->ppc, state->mmu_tt1));
1020                 break;
1021         case 0x10:  // translation control register
1022                 WRITE_EA_32(state, ea, state->mmu_tc);
1023                 MMULOG(("PMMU: pc=%x PMOVE from mmu_tc=%08x\n", state->ppc, state->mmu_tc));
1024                 break;
1025
1026         case 0x12: // supervisor root pointer
1027                 WRITE_EA_64(state, ea, (uint64)state->mmu_srp_limit<<32 | (uint64)state->mmu_srp_aptr);
1028                 MMULOG(("PMMU: pc=%x PMOVE from SRP limit = %08x, aptr = %08x\n", state->ppc, state->mmu_srp_limit, state->mmu_srp_aptr));
1029                 break;
1030
1031         case 0x13: // CPU root pointer
1032                 WRITE_EA_64(state, ea, (uint64)state->mmu_crp_limit<<32 | (uint64)state->mmu_crp_aptr);
1033                 MMULOG(("PMMU: pc=%x PMOVE from CRP limit = %08x, aptr = %08x\n", state->ppc, state->mmu_crp_limit, state->mmu_crp_aptr));
1034                 break;
1035
1036         default:
1037                 logerror("680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, state->pc);
1038                 return;
1039         }
1040
1041         if (!(modes & 0x100))   // flush ATC on moves to TC, SRP, CRP, TT with FD bit clear
1042         {
1043                 pmmu_atc_flush(state);
1044         }
1045
1046 }
1047
1048 void m68851_pmove_put(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1049 {
1050         uint64 temp64;
1051         switch ((modes>>13) & 7)
1052         {
1053         case 0:
1054         {
1055                 uint32 temp = READ_EA_32(state, ea);
1056
1057                 if (((modes >> 10) & 7) == 2)
1058                 {
1059                         MMULOG(("WRITE TT0 = 0x%08x\n", state->mmu_tt0));
1060                         state->mmu_tt0 = temp;
1061                 }
1062                 else if (((modes >> 10) & 7) == 3)
1063                 {
1064                         MMULOG(("WRITE TT1 = 0x%08x\n", state->mmu_tt1));
1065                         state->mmu_tt1 = temp;
1066                 }
1067                 break;
1068
1069                 // FIXME: unreachable
1070                 if (!(modes & 0x100))
1071                 {
1072                         pmmu_atc_flush(state);
1073                 }
1074         }
1075         /* fall through */
1076         /* no break */
1077
1078         case 1:
1079                 logerror("680x0: unknown PMOVE case 1, PC %x\n", state->pc);
1080                 break;
1081
1082         case 2:
1083                 switch ((modes >> 10) & 7)
1084                 {
1085                 case 0: // translation control register
1086                         state->mmu_tc = READ_EA_32(state, ea);
1087                         MMULOG(("PMMU: TC = %08x\n", state->mmu_tc));
1088
1089                         if (state->mmu_tc & 0x80000000)
1090                         {
1091                                 int bits = 0;
1092                                 for (int shift = 20; shift >= 0; shift -= 4)
1093                                 {
1094                                         bits += (state->mmu_tc >> shift) & 0x0f;
1095                                 }
1096
1097                                 if (bits != 32 || !((state->mmu_tc >> 23) & 1))
1098                                 {
1099                                         logerror("MMU: TC invalid!\n");
1100                                         state->mmu_tc &= ~0x80000000;
1101                                         m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1102                                 } else {
1103                                         state->pmmu_enabled = 1;
1104                                 }
1105                                 MMULOG(("PMMU enabled\n"));
1106                         }
1107                         else
1108                         {
1109                                 state->pmmu_enabled = 0;
1110                                 MMULOG(("PMMU disabled\n"));
1111                         }
1112
1113                         if (!(modes & 0x100))   // flush ATC on moves to TC, SRP, CRP with FD bit clear
1114                         {
1115                                 pmmu_atc_flush(state);
1116                         }
1117                         break;
1118
1119                 case 2: // supervisor root pointer
1120                         temp64 = READ_EA_64(state, ea);
1121                         state->mmu_srp_limit = (temp64 >> 32) & 0xffffffff;
1122                         state->mmu_srp_aptr = temp64 & 0xffffffff;
1123                         MMULOG(("PMMU: SRP limit = %08x aptr = %08x\n", state->mmu_srp_limit, state->mmu_srp_aptr));
1124                         // SRP type 0 is not allowed
1125                         if ((state->mmu_srp_limit & 3) == 0)
1126                         {
1127                                 m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1128                                 return;
1129                         }
1130
1131                         if (!(modes & 0x100))
1132                         {
1133                                 pmmu_atc_flush(state);
1134                         }
1135                         break;
1136
1137                 case 3: // CPU root pointer
1138                         temp64 = READ_EA_64(state, ea);
1139                         state->mmu_crp_limit = (temp64 >> 32) & 0xffffffff;
1140                         state->mmu_crp_aptr = temp64 & 0xffffffff;
1141                         MMULOG(("PMMU: CRP limit = %08x aptr = %08x\n", state->mmu_crp_limit, state->mmu_crp_aptr));
1142                         // CRP type 0 is not allowed
1143                         if ((state->mmu_crp_limit & 3) == 0)
1144                         {
1145                                 m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1146                                 return;
1147                         }
1148
1149                         if (!(modes & 0x100))
1150                         {
1151                                 pmmu_atc_flush(state);
1152                         }
1153                         break;
1154
1155                 case 7: // MC68851 Access Control Register
1156                         if (state->cpu_type == CPU_TYPE_020)
1157                         {
1158                                 // DomainOS on Apollo DN3000 will only reset this to 0
1159                                 uint16 mmu_ac = READ_EA_16(state, ea);
1160                                 if (mmu_ac != 0)
1161                                 {
1162                                         MMULOG(("680x0 PMMU: pc=%x PMOVE to mmu_ac=%08x\n",
1163                                                         state->ppc, mmu_ac));
1164                                 }
1165                                 break;
1166                         }
1167                         // fall through; unknown PMOVE mode unless MC68020 with MC68851
1168                         /* fall through */
1169                         /* no break */
1170                 default:
1171                         logerror("680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, state->pc);
1172                         break;
1173                 }
1174                 break;
1175         case 3: // MMU status
1176         {
1177                 uint32 temp = READ_EA_32(state, ea);
1178                 logerror("680x0: unsupported PMOVE %x to MMU status, PC %x\n", temp, state->pc);
1179         }
1180         break;
1181         }
1182 }
1183
1184
1185 void m68851_pmove(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1186 {
1187         switch ((modes>>13) & 0x7)
1188         {
1189         case 0: // MC68030/040 form with FD bit
1190         case 2: // MC68851 form, FD never set
1191                 if (modes & 0x200)
1192                 {
1193                         m68851_pmove_get(state, ea, modes);
1194                         break;
1195                 }
1196                 else    // top 3 bits of modes: 010 for this, 011 for status, 000 for transparent translation regs
1197                 {
1198                         m68851_pmove_put(state, ea, modes);
1199                         break;
1200                 }
1201         case 3: // MC68030 to/from status reg
1202                 if (modes & 0x200)
1203                 {
1204                         MMULOG(("%s: read SR = %04x\n", __func__, state->mmu_sr));
1205                         WRITE_EA_16(state, ea, state->mmu_sr);
1206                 }
1207                 else
1208                 {
1209                         state->mmu_sr = READ_EA_16(state, ea);
1210                         MMULOG(("%s: write SR = %04X\n", __func__, state->mmu_sr));
1211                 }
1212                 break;
1213
1214         default:
1215                 logerror("680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes >> 13) & 0x7, modes, state->pc);
1216                 break;
1217
1218         }
1219
1220 }
1221
1222 void m68851_mmu_ops(m68ki_cpu_core *state)
1223 {
1224         uint16 modes;
1225         uint32 ea = state->ir & 0x3f;
1226
1227         // catch the 2 "weird" encodings up front (PBcc)
1228         if ((state->ir & 0xffc0) == 0xf0c0)
1229         {
1230                 logerror("680x0: unhandled PBcc\n");
1231                 return;
1232         }
1233         else if ((state->ir & 0xffc0) == 0xf080)
1234         {
1235                 logerror("680x0: unhandled PBcc\n");
1236                 return;
1237         }
1238         else if ((state->ir & 0xffe0) == 0xf500)
1239         {
1240                 MMULOG(("68040 pflush: pc=%08x ir=%04x opmode=%d register=%d\n", REG_PC-4, state->ir, (state->ir >> 3) & 3, state->ir & 7));
1241                 pmmu_atc_flush(state);
1242         }
1243         else    // the rest are 1111000xxxXXXXXX where xxx is the instruction family
1244         {
1245                 switch ((state->ir>>9) & 0x7)
1246                 {
1247                         case 0:
1248                                 modes = OPER_I_16(state);
1249
1250                                 if ((modes & 0xfde0) == 0x2000) // PLOAD
1251                                 {
1252                                         m68851_pload(state, ea, modes);
1253                                         return;
1254                                 }
1255                                 else if ((modes & 0xe200) == 0x2000)    // PFLUSH
1256                                 {
1257                                         pmmu_atc_flush_fc_ea(state, modes);
1258                                         return;
1259                                 }
1260                                 else if (modes == 0xa000)       // PFLUSHR
1261                                 {
1262                                         pmmu_atc_flush(state);
1263                                         return;
1264                                 }
1265                                 else if (modes == 0x2800)       // PVALID (FORMAT 1)
1266                                 {
1267                                         logerror("680x0: unhandled PVALID1\n");
1268                                         return;
1269                                 }
1270                                 else if ((modes & 0xfff8) == 0x2c00)    // PVALID (FORMAT 2)
1271                                 {
1272                                         logerror("680x0: unhandled PVALID2\n");
1273                                         return;
1274                                 }
1275                                 else if ((modes & 0xe000) == 0x8000)    // PTEST
1276                                 {
1277                                         m68851_ptest(state, ea, modes);
1278                                         return;
1279                                 }
1280                                 else
1281                                 {
1282                                         m68851_pmove(state, ea, modes);
1283                                 }
1284                                 break;
1285
1286                         default:
1287                                 logerror("680x0: unknown PMMU instruction group %d\n", (state->ir>>9) & 0x7);
1288                                 break;
1289                 }
1290         }
1291 }
1292
1293
1294 /* Apple HMMU translation is much simpler */
1295 /*
1296 inline uint32 hmmu_translate_addr(uint32 addr_in)
1297 {
1298         uint32 addr_out;
1299
1300         addr_out = addr_in;
1301
1302         // check if LC 24-bit mode is enabled - this simply blanks out A31, the V8 ignores A30-24 always
1303         if (state->hmmu_enabled == M68K_HMMU_ENABLE_LC)
1304         {
1305                 addr_out = addr_in & 0xffffff;
1306         }
1307         else if (state->hmmu_enabled == M68K_HMMU_ENABLE_II) // the original II does a more complex translation
1308         {
1309                 addr_out = addr_in & 0xffffff;
1310
1311                 if ((addr_out >= 0x800000) && (addr_out <= 0x8fffff))
1312                 {
1313                         addr_out |= 0x40000000; // ROM
1314                 }
1315                 else if ((addr_out >= 0x900000) && (addr_out <= 0xefffff))
1316                 {
1317                         addr_out = 0xf0000000;  // NuBus
1318                         addr_out |= ((addr_in & 0xf00000)<<4);
1319                         addr_out |= (addr_in & 0xfffff);
1320                 }
1321                 else if (addr_out >= 0xf00000)
1322                 {
1323                         addr_out |= 0x50000000; // I/O
1324                 }
1325
1326                 // (RAM is at 0 and doesn't need special massaging)
1327         }
1328
1329         return addr_out;
1330 }
1331
1332 int m68851_buserror(u32& addr)
1333 {
1334         if (!state->pmmu_enabled)
1335         {
1336                 return false;
1337         }
1338
1339         if (state->mmu_tablewalk)
1340         {
1341                 MMULOG(("buserror during table walk\n"));
1342                 state->mmu_tmp_sr |= M68K_MMU_SR_BUS_ERROR|M68K_MMU_SR_INVALID;
1343                 return true;
1344         }
1345
1346         addr = state->mmu_last_logical_addr;
1347         return false;
1348 }
1349 */