]> git.sesse.net Git - pistorm/blob - m68kmmu.h
removed most traces of direct access to the m68ki_cpu global variable
[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         if (type == M68K_MMU_DF_DT_PAGE && !rw &&
360                         !(entry & M68K_MMU_DF_MODIFIED) &&
361                         !(entry & M68K_MMU_DF_WP))
362         {
363                 MMULOG(("%s: set M+U at %08x\n", __func__, tptr));
364                 m68k_write_memory_32(tptr, entry | M68K_MMU_DF_USED | M68K_MMU_DF_MODIFIED);
365         }
366         else if (type != M68K_MMU_DF_DT_INVALID && !(entry & M68K_MMU_DF_USED))
367         {
368                 MMULOG(("%s: set U at %08x\n", __func__, tptr));
369                 m68k_write_memory_32(tptr, entry | M68K_MMU_DF_USED);
370         }
371 }
372
373
374 //template<bool _long>
375 void update_sr(m68ki_cpu_core *state, int type, uint32 tbl_entry, int fc, uint16 _long)
376 {
377         if (m_side_effects_disabled)
378         {
379                 return;
380         }
381
382         switch(type)
383         {
384         case M68K_MMU_DF_DT_INVALID:
385                 // Invalid has no flags
386                 break;
387
388         case M68K_MMU_DF_DT_PAGE:
389                 if (tbl_entry & M68K_MMU_DF_MODIFIED)
390                 {
391                         state->mmu_tmp_sr |= M68K_MMU_SR_MODIFIED;
392                 }
393                 /* FALLTHROUGH */
394
395         case M68K_MMU_DF_DT_TABLE_4BYTE:
396                 /* FALLTHROUGH */
397
398         case M68K_MMU_DF_DT_TABLE_8BYTE:
399
400                 if (tbl_entry & M68K_MMU_DF_WP)
401                 {
402                         state->mmu_tmp_sr |= M68K_MMU_SR_WRITE_PROTECT;
403                 }
404
405                 if (_long && !(fc & 4) && (tbl_entry & M68K_MMU_DF_SUPERVISOR))
406                 {
407                         state->mmu_tmp_sr |= M68K_MMU_SR_SUPERVISOR_ONLY;
408                 }
409                 break;
410         default:
411                 break;
412         }
413 }
414
415 //template<bool ptest>
416 uint16 pmmu_walk_tables(m68ki_cpu_core *state, uint32 addr_in, int type, uint32 table, uint8 fc, int limit, uint16 rw,
417                                                 uint32 *addr_out, int ptest)
418 {
419         int level = 0;
420         uint32 bits = state->mmu_tc & 0xffff;
421         int pagesize = (state->mmu_tc >> 20) & 0xf;
422         int is = (state->mmu_tc >> 16) & 0xf;
423         int bitpos = 12;
424         int resolved = 0;
425         int pageshift = is;
426
427         addr_in <<= is;
428
429         state->mmu_tablewalk = 1;
430
431         if (state->mmu_tc & M68K_MMU_TC_FCL)
432         {
433                 bitpos = 16;
434         }
435
436         do
437         {
438                 int indexbits = (bits >> bitpos) & 0xf;
439                 int table_index  = (bitpos == 16) ? fc : (addr_in >> (32 - indexbits));
440                 bitpos -= 4;
441                 uint16 indirect = (!bitpos || !(bits >> bitpos)) && indexbits;
442                 uint32 tbl_entry, tbl_entry2;
443
444                 MMULOG(("%s: type %d, table %08x, addr_in %08x, indexbits %d, pageshift %d, indirect %d table_index %08x, rw=%d fc=%d\n",
445                                 __func__, type, table, addr_in, indexbits, pageshift, indirect, table_index, rw, fc));
446
447                 switch(type)
448                 {
449                         case M68K_MMU_DF_DT_INVALID:   // invalid, will cause MMU exception
450                                 state->mmu_tmp_sr = M68K_MMU_SR_INVALID;
451                                 MMULOG(("PMMU: DT0 PC=%x (addr_in %08x -> %08x)\n", state->ppc, addr_in, *addr_out));
452                                 resolved = 1;
453                                 break;
454
455                         case M68K_MMU_DF_DT_PAGE:   // page descriptor, will cause direct mapping
456                                 if (!ptest)
457                                 {
458                                         table &= ((uint32)~0) << pagesize;
459                                         *addr_out = table + (addr_in >> pageshift);
460                                 }
461                                 resolved = 1;
462                                 break;
463
464                         case M68K_MMU_DF_DT_TABLE_4BYTE:   // valid 4 byte descriptors
465                                 level++;
466                                 *addr_out = table + (table_index << 2);
467                                 tbl_entry = m68k_read_memory_32(*addr_out);
468                                 type = tbl_entry & M68K_MMU_DF_DT;
469
470                                 if (indirect && (type == 2 || type == 3))
471                                 {
472                                         level++;
473                                         MMULOG(("SHORT INDIRECT DESC: %08x\n", tbl_entry));
474                                         *addr_out = tbl_entry & M68K_MMU_DF_IND_ADDR_MASK;
475                                         tbl_entry = m68k_read_memory_32(*addr_out);
476                                         type = tbl_entry & M68K_MMU_DF_DT;
477                                 }
478
479                                 MMULOG(("SHORT DESC: %08x\n", tbl_entry));
480                                 table = tbl_entry & M68K_MMU_DF_ADDR_MASK;
481                                 if (!m_side_effects_disabled)
482                                 {
483                                         update_sr(state, type, tbl_entry, fc, 0);
484                                         if (!ptest)
485                                         {
486                                                 update_descriptor(state, *addr_out, type, tbl_entry, rw);
487                                         }
488                                 }
489                                 break;
490
491                         case M68K_MMU_DF_DT_TABLE_8BYTE:   // valid 8 byte descriptors
492                                 level++;
493                                 *addr_out = table + (table_index << 3);
494                                 tbl_entry = m68k_read_memory_32(*addr_out);
495                                 tbl_entry2 = m68k_read_memory_32((*addr_out) + 4);
496                                 type = tbl_entry & M68K_MMU_DF_DT;
497
498                                 if (indirect && (type == 2 || type == 3))
499                                 {
500                                         level++;
501                                         MMULOG(("LONG INDIRECT DESC: %08x%08x\n", tbl_entry, tbl_entry2));
502                                         *addr_out = tbl_entry2 & M68K_MMU_DF_IND_ADDR_MASK;
503                                         tbl_entry = m68k_read_memory_32(*addr_out);
504                                         tbl_entry2 = m68k_read_memory_32(*addr_out);
505                                         type = tbl_entry & M68K_MMU_DF_DT;
506                                 }
507
508                                 MMULOG(("LONG DESC: %08x %08x\n", tbl_entry, tbl_entry2));
509                                 table = tbl_entry2 & M68K_MMU_DF_ADDR_MASK;
510                                 if (!m_side_effects_disabled)
511                                 {
512                                         update_sr(state, type, tbl_entry, fc, 1);
513                                         if (!ptest)
514                                         {
515                                                 update_descriptor(state, *addr_out, type, tbl_entry, rw);
516                                         }
517                                 }
518                                 break;
519                 }
520
521                 if (state->mmu_tmp_sr & M68K_MMU_SR_BUS_ERROR)
522                 {
523                         // Bus error during page table walking is always fatal
524                         resolved = 1;
525                         break;
526                 }
527
528                 if (!ptest && !m_side_effects_disabled)
529                 {
530                         if (!rw && (state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT))
531                         {
532                                 resolved = 1;
533                                 break;
534                         }
535
536                         if (!(fc & 4) && (state->mmu_tmp_sr & M68K_MMU_SR_SUPERVISOR_ONLY))
537                         {
538                                 resolved = 1;
539                                 break;
540                         }
541
542                 }
543                 addr_in <<= indexbits;
544                 pageshift += indexbits;
545         } while(level < limit && !resolved);
546
547
548         state->mmu_tmp_sr &= 0xfff0;
549         state->mmu_tmp_sr |= level;
550         MMULOG(("MMU SR after walk: %04X\n", state->mmu_tmp_sr));
551         state->mmu_tablewalk = 0;
552         return resolved;
553 }
554
555 // pmmu_translate_addr_with_fc: perform 68851/68030-style PMMU address translation
556 //template<bool ptest, bool pload>
557 uint32 pmmu_translate_addr_with_fc(m68ki_cpu_core *state, uint32 addr_in, uint8 fc, uint16 rw, int limit, int ptest,
558                                                                    int pload)
559 {
560         uint32 addr_out = 0;
561
562
563         MMULOG(("%s: addr_in=%08x, fc=%d, ptest=%d, rw=%d, limit=%d, pload=%d\n",
564                         __func__, addr_in, fc, ptest, rw, limit, pload));
565         state->mmu_tmp_sr = 0;
566
567         state->mmu_last_logical_addr = addr_in;
568
569         if (pmmu_match_tt(state, addr_in, fc, state->mmu_tt0, rw) ||
570                 pmmu_match_tt(state, addr_in, fc, state->mmu_tt1, rw) ||
571                 fc == 7)
572         {
573                 return addr_in;
574         }
575
576         if (ptest && limit == 0)
577         {
578                 pmmu_atc_lookup(state, addr_in, fc, rw, &addr_out, 1);
579                 return addr_out;
580         }
581
582         if (!ptest && !pload && pmmu_atc_lookup(state, addr_in, fc, rw, &addr_out, 0))
583         {
584                 if ((state->mmu_tmp_sr & M68K_MMU_SR_BUS_ERROR) || (!rw && (state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT)))
585                 {
586                         MMULOG(("set atc hit buserror: addr_in=%08x, addr_out=%x, rw=%x, fc=%d, sz=%d\n",
587                                         addr_in, addr_out, state->mmu_tmp_rw, state->mmu_tmp_fc, state->mmu_tmp_sz));
588                         pmmu_set_buserror(state, addr_in);
589                 }
590                 return addr_out;
591         }
592
593         int type;
594         uint32 tbl_addr;
595         // if SRP is enabled and we're in supervisor mode, use it
596         if ((state->mmu_tc & M68K_MMU_TC_SRE) && (fc & 4))
597         {
598                 tbl_addr = state->mmu_srp_aptr & M68K_MMU_DF_ADDR_MASK;
599                 type = state->mmu_srp_limit & M68K_MMU_DF_DT;
600         }
601         else    // else use the CRP
602         {
603                 tbl_addr = state->mmu_crp_aptr & M68K_MMU_DF_ADDR_MASK;
604                 type = state->mmu_crp_limit & M68K_MMU_DF_DT;
605         }
606
607         if (!pmmu_walk_tables(state, addr_in, type, tbl_addr, fc, limit, rw, &addr_out, ptest))
608         {
609                 MMULOG(("%s: addr_in=%08x, type=%x, tbl_addr=%x, fc=%d, limit=%x, rw=%x, addr_out=%x, ptest=%d\n",
610                                 __func__, addr_in, type, tbl_addr, fc, limit, rw, addr_out, ptest));
611                 fatalerror("Table walk did not resolve\n");
612         }
613
614         if (ptest)
615         {
616                 return addr_out;
617         }
618
619         if ((state->mmu_tmp_sr & (M68K_MMU_SR_INVALID|M68K_MMU_SR_SUPERVISOR_ONLY)) ||
620                         ((state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT) && !rw))
621         {
622
623                 if (!pload)
624                 {
625                         MMULOG(("%s: set buserror (SR %04X)\n", __func__, state->mmu_tmp_sr));
626                         pmmu_set_buserror(state, addr_in);
627                 }
628         }
629
630         // it seems like at least the 68030 sets the M bit in the MMU SR
631         // if the root descriptor is of PAGE type, so do a logical and
632         // between RW and the root type
633         if (!m_side_effects_disabled)
634         {
635                 pmmu_atc_add(state, addr_in, addr_out, fc, rw && type != 1);
636         }
637         MMULOG(("PMMU: [%08x] => [%08x] (SR %04x)\n", addr_in, addr_out, state->mmu_tmp_sr));
638         return addr_out;
639 }
640
641 // FC bits: 2 = supervisor, 1 = program, 0 = data
642 // the 68040 is a subset of the 68851 and 68030 PMMUs - the page table sizes are fixed, there is no early termination, etc, etc.
643 uint32 pmmu_translate_addr_with_fc_040(m68ki_cpu_core *state, uint32 addr_in, uint8 fc, uint8 ptest)
644 {
645         uint32 addr_out, tt0, tt1;
646
647         addr_out = addr_in;
648         state->mmu_tmp_sr = 0;
649
650         // transparent translation registers are always in force even if the PMMU itself is disabled
651         // they don't do much in emulation because we never write out of order, but the write-protect and cache control features
652         // are emulatable, and apparently transparent translation regions skip the page table lookup.
653         if (fc & 1) // data, use DTT0/DTT1
654         {
655                 tt0 = state->mmu_dtt0;
656                 tt1 = state->mmu_dtt1;
657         }
658         else if (fc & 2)    // program, use ITT0/ITT1
659         {
660                 tt0 = state->mmu_itt0;
661                 tt1 = state->mmu_itt1;
662         }
663         else
664         {
665                 fatalerror("68040: function code %d is neither data nor program!\n", fc & 7);
666         }
667
668         if (tt0 & M68K_MMU_TT_ENABLE)
669         {
670                 int fcmask[4] = { 4, 4, 0, 0 };
671                 int fcmatch[4] = { 0, 4, 0, 0 };
672                 uint32 mask = (tt0 >> 16) & 0xff;
673                 mask ^= 0xff;
674                 mask <<= 24;
675
676                 if ((addr_in & mask) == (tt0 & mask) && (fc & fcmask[(tt0 >> 13) & 3]) == fcmatch[(tt0 >> 13) & 3])
677                 {
678                         MMULOG(("TT0 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt0, mask));
679                         if ((tt0 & 4) && !state->mmu_tmp_rw && !ptest)   // write protect?
680                         {
681                                 pmmu_set_buserror(state, addr_in);
682                         }
683
684                         return addr_in;
685                 }
686         }
687
688         if (tt1 & M68K_MMU_TT_ENABLE)
689         {
690                 static int fcmask[4] = { 4, 4, 0, 0 };
691                 static int fcmatch[4] = { 0, 4, 0, 0 };
692                 uint32 mask = (tt1 >> 16) & 0xff;
693                 mask ^= 0xff;
694                 mask <<= 24;
695
696                 if ((addr_in & mask) == (tt1 & mask) && (fc & fcmask[(tt1 >> 13) & 3]) == fcmatch[(tt1 >> 13) & 3])
697                 {
698                         MMULOG(("TT1 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt1, mask));
699                         if ((tt1 & 4) && !state->mmu_tmp_rw && !ptest)   // write protect?
700                         {
701                                 pmmu_set_buserror(state, addr_in);
702                         }
703
704                         return addr_in;
705                 }
706         }
707
708         if (state->pmmu_enabled)
709         {
710                 uint32 root_idx = (addr_in >> 25) & 0x7f;
711                 uint32 ptr_idx = (addr_in >> 18) & 0x7f;
712                 uint32 page_idx, page;
713                 uint32 root_ptr, pointer_ptr, page_ptr;
714                 uint32 root_entry, pointer_entry, page_entry;
715
716                 // select supervisor or user root pointer
717                 if (fc & 4)
718                 {
719                         root_ptr = state->mmu_srp_aptr + (root_idx<<2);
720                 }
721                 else
722                 {
723                         root_ptr = state->mmu_urp_aptr + (root_idx<<2);
724                 }
725
726                 // get the root entry
727                 root_entry = m68k_read_memory_32(root_ptr);
728
729                 // is UDT marked valid?
730                 if (root_entry & 2)
731                 {
732                         // we're accessing through this root entry, so set the U bit
733                         if ((!(root_entry & 0x8)) && (!ptest) && !m_side_effects_disabled)
734                         {
735                                 root_entry |= 0x8;
736                                 m68k_write_memory_32(root_ptr, root_entry);
737                         }
738
739                         // PTEST: any write protect bits set in the search tree will set W in SR
740                         if ((ptest) && (root_entry & 4))
741                         {
742                                 state->mmu_tmp_sr |= 4;
743                         }
744
745                         pointer_ptr = (root_entry & ~0x1ff) + (ptr_idx<<2);
746                         pointer_entry = m68k_read_memory_32(pointer_ptr);
747
748                         // PTEST: any write protect bits set in the search tree will set W in SR
749                         if ((ptest) && (pointer_entry & 4))
750                         {
751                                 state->mmu_tmp_sr |= 4;
752                         }
753
754                         // update U bit on this pointer entry too
755                         if ((!(pointer_entry & 0x8)) && (!ptest) && !m_side_effects_disabled)
756                         {
757                                 pointer_entry |= 0x8;
758                                 m68k_write_memory_32(pointer_ptr, pointer_entry);
759                         }
760
761                         MMULOG(("pointer entry = %08x\n", pointer_entry));
762
763                         // write protected by the root or pointer entries?
764                         if ((((root_entry & 4) && !state->mmu_tmp_rw) || ((pointer_entry & 4) && !state->mmu_tmp_rw)) && !ptest)
765                         {
766                                 pmmu_set_buserror(state, addr_in);
767                                 return addr_in;
768                         }
769
770                         // is UDT valid on the pointer entry?
771                         if (!(pointer_entry & 2) && !ptest)
772                         {
773                                 logerror("Invalid pointer entry!  PC=%x, addr=%x\n", state->ppc, addr_in);
774                                 pmmu_set_buserror(state, addr_in);
775                                 return addr_in;
776                         }
777
778                         // (fall out of these ifs into the page lookup below)
779                 }
780                 else // throw an error
781                 {
782                         logerror("Invalid root entry!  PC=%x, addr=%x\n", state->ppc, addr_in);
783
784                         if (!ptest)
785                         {
786                                 pmmu_set_buserror(state, addr_in);
787                         }
788
789                         return addr_in;
790                 }
791
792                 // now do the page lookup
793                 if (state->mmu_tc & 0x4000)  // 8k pages?
794                 {
795                         page_idx = (addr_in >> 13) & 0x1f;
796                         page = addr_in & 0x1fff;
797                         pointer_entry &= ~0x7f;
798                         MMULOG(("8k pages: index %x page %x\n", page_idx, page));
799                 }
800                 else    // 4k pages
801                 {
802                         page_idx = (addr_in >> 12) & 0x3f;
803                         page = addr_in & 0xfff;
804                         pointer_entry &= ~0xff;
805                         MMULOG(("4k pages: index %x page %x\n", page_idx, page));
806                 }
807
808                 page_ptr = pointer_entry + (page_idx<<2);
809                 page_entry = m68k_read_memory_32(page_ptr);
810                 state->mmu_last_page_entry_addr = page_ptr;
811
812                 MMULOG(("page_entry = %08x\n", page_entry));
813
814                 // resolve indirect page pointers
815                 while ((page_entry & 3) == 2)
816                 {
817                         page_entry = m68k_read_memory_32(page_entry & ~0x3);
818                         state->mmu_last_page_entry_addr = (page_entry & ~0x3);
819                 }
820                 state->mmu_last_page_entry = page_entry;
821
822                 // is the page write protected or supervisor protected?
823                 if ((((page_entry & 4) && !state->mmu_tmp_rw) || ((page_entry & 0x80) && !(fc & 4))) && !ptest)
824                 {
825                         pmmu_set_buserror(state, addr_in);
826                         return addr_in;
827                 }
828
829                 switch (page_entry & 3)
830                 {
831                         case 0: // invalid
832                                 MMULOG(("Invalid page entry!  PC=%x, addr=%x\n", state->ppc, addr_in));
833                                 if (!ptest)
834                                 {
835                                         pmmu_set_buserror(state, addr_in);
836                                 }
837
838                                 return addr_in;
839
840                         case 1:
841                         case 3: // normal
842                                 if (state->mmu_tc & 0x4000)  // 8k pages?
843                                 {
844                                         addr_out = (page_entry & ~0x1fff) | page;
845                                 }
846                                 else
847                                 {
848                                         addr_out = (page_entry & ~0xfff) | page;
849                                 }
850
851                                 if (!(ptest))
852                                 {
853                                         page_entry |= 0x8;  // always set the U bit
854
855                                         // if we're writing, the M bit comes into play
856                                         if (!state->mmu_tmp_rw)
857                                         {
858                                                 page_entry |= 0x10; // set Modified
859                                         }
860
861                                         // if these updates resulted in a change, write the entry back where we found it
862                                         if (page_entry != state->mmu_last_page_entry && !m_side_effects_disabled)
863                                         {
864                                                 state->mmu_last_page_entry = page_entry;
865                                                 m68k_write_memory_32(state->mmu_last_page_entry_addr, state->mmu_last_page_entry);
866                                         }
867                                 }
868                                 else
869                                 {
870                                         // page entry: UR G U1 U0 S CM CM M U W PDT
871                                         // SR:         B  G U1 U0 S CM CM M 0 W T R
872                                         state->mmu_tmp_sr |= ((addr_out & ~0xfff) || (page_entry & 0x7f4));
873                                 }
874                                 break;
875
876                         case 2: // shouldn't happen
877                                 fatalerror("68040: got indirect final page pointer, shouldn't be possible\n");
878                                 break;
879                 }
880                 //      if (addr_in != addr_out) MMULOG(("040MMU: [%08x] => [%08x]\n", addr_in, addr_out));
881         }
882
883         return addr_out;
884 }
885
886 // pmmu_translate_addr: perform 68851/68030-style PMMU address translation
887 uint32 pmmu_translate_addr(m68ki_cpu_core *state, uint32 addr_in, uint16 rw)
888 {
889         uint32 addr_out;
890
891         if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
892         {
893                 addr_out = pmmu_translate_addr_with_fc_040(state, addr_in, state->mmu_tmp_fc, 0);
894         }
895         else
896         {
897                 addr_out = pmmu_translate_addr_with_fc(state, addr_in, state->mmu_tmp_fc, rw, 7, 0, 0);
898                 MMULOG(("ADDRIN %08X, ADDROUT %08X\n", addr_in, addr_out));
899         }
900         return addr_out;
901 }
902
903 int fc_from_modes(m68ki_cpu_core *state, uint16 modes)
904 {
905         if ((modes & 0x1f) == 0)
906         {
907                 return state->sfc;
908         }
909
910         if ((modes & 0x1f) == 1)
911         {
912                 return state->dfc;
913         }
914
915         if (state->cpu_type & CPU_TYPE_030)
916         {
917                 // 68030 has 3 bits fc, but 68851 4 bits
918                 if (((modes >> 3) & 3) == 1)
919                 {
920                         return REG_D[modes & 7] & 0x7;
921                 }
922
923                 if (((modes >> 3) & 3) == 2)
924                 {
925                         return modes & 7;
926                 }
927         }
928         else
929         {
930                 if (((modes >> 3) & 3) == 1)
931                 {
932                         return REG_D[modes & 7] & 0xf;
933                 }
934
935                 if (modes & 0x10)
936                 {
937                         return modes & 0xf;
938                 }
939         }
940
941
942         fatalerror("%s: unknown fc mode: 0x%02xn", __func__, modes & 0x1f);
943         return 0;
944 }
945
946 void m68851_pload(m68ki_cpu_core *state, uint32 ea, uint16 modes)
947 {
948         uint32 ltmp = DECODE_EA_32(state, ea);
949         int fc = fc_from_modes(state, modes);
950         uint16 rw = !!(modes & 0x200);
951
952         MMULOG(("%s: PLOAD%c addr=%08x, fc=%d\n", __func__, rw ? 'R' : 'W', ltmp, fc));
953
954         // MC68851 traps if MMU is not enabled, 030 not
955         if (state->pmmu_enabled || (state->cpu_type & CPU_TYPE_030))
956         {
957                 if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
958                 {
959                         pmmu_translate_addr_with_fc_040(state, ltmp, fc, 0);
960                 }
961                 else
962                 {
963                         pmmu_translate_addr_with_fc(state, ltmp, fc, rw, 7, 0, 1);
964                 }
965         }
966         else
967         {
968                 MMULOG(("PLOAD with MMU disabled on MC68851\n"));
969                 m68ki_exception_trap(state, 57);
970                 return;
971         }
972 }
973
974 void m68851_ptest(m68ki_cpu_core *state, uint32 ea, uint16 modes)
975 {
976         uint32 v_addr = DECODE_EA_32(state, ea);
977         uint32 p_addr;
978
979         int level = (modes >> 10) & 7;
980         uint16 rw = !!(modes & 0x200);
981         int fc = fc_from_modes(state, modes);
982
983         MMULOG(("PMMU: PTEST%c (%04X) pc=%08x sp=%08x va=%08x fc=%x level=%x a=%d, areg=%d\n",
984                         rw ? 'R' : 'W', modes, state->ppc, REG_A[7], v_addr, fc, level,
985                                         (modes & 0x100) ? 1 : 0, (modes >> 5) & 7));
986
987         if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
988         {
989                 p_addr = pmmu_translate_addr_with_fc_040(state, v_addr, fc, 1);
990         }
991         else
992         {
993                 p_addr = pmmu_translate_addr_with_fc(state, v_addr, fc, rw, level, 1, 0);
994         }
995
996         state->mmu_sr = state->mmu_tmp_sr;
997
998         MMULOG(("PMMU: PTEST result: %04x pa=%08x\n", state->mmu_sr, p_addr));
999         if (modes & 0x100)
1000         {
1001                 int areg = (modes >> 5) & 7;
1002                 WRITE_EA_32(state, 0x08 | areg, p_addr);
1003         }
1004 }
1005
1006 void m68851_pmove_get(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1007 {
1008         switch ((modes>>10) & 0x3f)
1009         {
1010         case 0x02: // transparent translation register 0
1011                 WRITE_EA_32(state, ea, state->mmu_tt0);
1012                 MMULOG(("PMMU: pc=%x PMOVE from mmu_tt0=%08x\n", state->ppc, state->mmu_tt0));
1013                 break;
1014         case 0x03: // transparent translation register 1
1015                 WRITE_EA_32(state, ea, state->mmu_tt1);
1016                 MMULOG(("PMMU: pc=%x PMOVE from mmu_tt1=%08x\n", state->ppc, state->mmu_tt1));
1017                 break;
1018         case 0x10:  // translation control register
1019                 WRITE_EA_32(state, ea, state->mmu_tc);
1020                 MMULOG(("PMMU: pc=%x PMOVE from mmu_tc=%08x\n", state->ppc, state->mmu_tc));
1021                 break;
1022
1023         case 0x12: // supervisor root pointer
1024                 WRITE_EA_64(state, ea, (uint64)state->mmu_srp_limit<<32 | (uint64)state->mmu_srp_aptr);
1025                 MMULOG(("PMMU: pc=%x PMOVE from SRP limit = %08x, aptr = %08x\n", state->ppc, state->mmu_srp_limit, state->mmu_srp_aptr));
1026                 break;
1027
1028         case 0x13: // CPU root pointer
1029                 WRITE_EA_64(state, ea, (uint64)state->mmu_crp_limit<<32 | (uint64)state->mmu_crp_aptr);
1030                 MMULOG(("PMMU: pc=%x PMOVE from CRP limit = %08x, aptr = %08x\n", state->ppc, state->mmu_crp_limit, state->mmu_crp_aptr));
1031                 break;
1032
1033         default:
1034                 logerror("680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, state->pc);
1035                 return;
1036         }
1037
1038         if (!(modes & 0x100))   // flush ATC on moves to TC, SRP, CRP, TT with FD bit clear
1039         {
1040                 pmmu_atc_flush(state);
1041         }
1042
1043 }
1044
1045 void m68851_pmove_put(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1046 {
1047         uint64 temp64;
1048         switch ((modes>>13) & 7)
1049         {
1050         case 0:
1051         {
1052                 uint32 temp = READ_EA_32(state, ea);
1053
1054                 if (((modes >> 10) & 7) == 2)
1055                 {
1056                         MMULOG(("WRITE TT0 = 0x%08x\n", state->mmu_tt0));
1057                         state->mmu_tt0 = temp;
1058                 }
1059                 else if (((modes >> 10) & 7) == 3)
1060                 {
1061                         MMULOG(("WRITE TT1 = 0x%08x\n", state->mmu_tt1));
1062                         state->mmu_tt1 = temp;
1063                 }
1064                 break;
1065
1066                 // FIXME: unreachable
1067                 if (!(modes & 0x100))
1068                 {
1069                         pmmu_atc_flush(state);
1070                 }
1071         }
1072         /* fall through */
1073         /* no break */
1074
1075         case 1:
1076                 logerror("680x0: unknown PMOVE case 1, PC %x\n", state->pc);
1077                 break;
1078
1079         case 2:
1080                 switch ((modes >> 10) & 7)
1081                 {
1082                 case 0: // translation control register
1083                         state->mmu_tc = READ_EA_32(state, ea);
1084                         MMULOG(("PMMU: TC = %08x\n", state->mmu_tc));
1085
1086                         if (state->mmu_tc & 0x80000000)
1087                         {
1088                                 int bits = 0;
1089                                 for (int shift = 20; shift >= 0; shift -= 4)
1090                                 {
1091                                         bits += (state->mmu_tc >> shift) & 0x0f;
1092                                 }
1093
1094                                 if (bits != 32 || !((state->mmu_tc >> 23) & 1))
1095                                 {
1096                                         logerror("MMU: TC invalid!\n");
1097                                         state->mmu_tc &= ~0x80000000;
1098                                         m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1099                                 } else {
1100                                         state->pmmu_enabled = 1;
1101                                 }
1102                                 MMULOG(("PMMU enabled\n"));
1103                         }
1104                         else
1105                         {
1106                                 state->pmmu_enabled = 0;
1107                                 MMULOG(("PMMU disabled\n"));
1108                         }
1109
1110                         if (!(modes & 0x100))   // flush ATC on moves to TC, SRP, CRP with FD bit clear
1111                         {
1112                                 pmmu_atc_flush(state);
1113                         }
1114                         break;
1115
1116                 case 2: // supervisor root pointer
1117                         temp64 = READ_EA_64(state, ea);
1118                         state->mmu_srp_limit = (temp64 >> 32) & 0xffffffff;
1119                         state->mmu_srp_aptr = temp64 & 0xffffffff;
1120                         MMULOG(("PMMU: SRP limit = %08x aptr = %08x\n", state->mmu_srp_limit, state->mmu_srp_aptr));
1121                         // SRP type 0 is not allowed
1122                         if ((state->mmu_srp_limit & 3) == 0)
1123                         {
1124                                 m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1125                                 return;
1126                         }
1127
1128                         if (!(modes & 0x100))
1129                         {
1130                                 pmmu_atc_flush(state);
1131                         }
1132                         break;
1133
1134                 case 3: // CPU root pointer
1135                         temp64 = READ_EA_64(state, ea);
1136                         state->mmu_crp_limit = (temp64 >> 32) & 0xffffffff;
1137                         state->mmu_crp_aptr = temp64 & 0xffffffff;
1138                         MMULOG(("PMMU: CRP limit = %08x aptr = %08x\n", state->mmu_crp_limit, state->mmu_crp_aptr));
1139                         // CRP type 0 is not allowed
1140                         if ((state->mmu_crp_limit & 3) == 0)
1141                         {
1142                                 m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1143                                 return;
1144                         }
1145
1146                         if (!(modes & 0x100))
1147                         {
1148                                 pmmu_atc_flush(state);
1149                         }
1150                         break;
1151
1152                 case 7: // MC68851 Access Control Register
1153                         if (state->cpu_type == CPU_TYPE_020)
1154                         {
1155                                 // DomainOS on Apollo DN3000 will only reset this to 0
1156                                 uint16 mmu_ac = READ_EA_16(state, ea);
1157                                 if (mmu_ac != 0)
1158                                 {
1159                                         MMULOG(("680x0 PMMU: pc=%x PMOVE to mmu_ac=%08x\n",
1160                                                         state->ppc, mmu_ac));
1161                                 }
1162                                 break;
1163                         }
1164                         // fall through; unknown PMOVE mode unless MC68020 with MC68851
1165                         /* fall through */
1166                         /* no break */
1167                 default:
1168                         logerror("680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, state->pc);
1169                         break;
1170                 }
1171                 break;
1172         case 3: // MMU status
1173         {
1174                 uint32 temp = READ_EA_32(state, ea);
1175                 logerror("680x0: unsupported PMOVE %x to MMU status, PC %x\n", temp, state->pc);
1176         }
1177         break;
1178         }
1179 }
1180
1181
1182 void m68851_pmove(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1183 {
1184         switch ((modes>>13) & 0x7)
1185         {
1186         case 0: // MC68030/040 form with FD bit
1187         case 2: // MC68851 form, FD never set
1188                 if (modes & 0x200)
1189                 {
1190                         m68851_pmove_get(state, ea, modes);
1191                         break;
1192                 }
1193                 else    // top 3 bits of modes: 010 for this, 011 for status, 000 for transparent translation regs
1194                 {
1195                         m68851_pmove_put(state, ea, modes);
1196                         break;
1197                 }
1198         case 3: // MC68030 to/from status reg
1199                 if (modes & 0x200)
1200                 {
1201                         MMULOG(("%s: read SR = %04x\n", __func__, state->mmu_sr));
1202                         WRITE_EA_16(state, ea, state->mmu_sr);
1203                 }
1204                 else
1205                 {
1206                         state->mmu_sr = READ_EA_16(state, ea);
1207                         MMULOG(("%s: write SR = %04X\n", __func__, state->mmu_sr));
1208                 }
1209                 break;
1210
1211         default:
1212                 logerror("680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes >> 13) & 0x7, modes, state->pc);
1213                 break;
1214
1215         }
1216
1217 }
1218
1219 void m68851_mmu_ops(m68ki_cpu_core *state)
1220 {
1221         uint16 modes;
1222         uint32 ea = state->ir & 0x3f;
1223
1224         // catch the 2 "weird" encodings up front (PBcc)
1225         if ((state->ir & 0xffc0) == 0xf0c0)
1226         {
1227                 logerror("680x0: unhandled PBcc\n");
1228                 return;
1229         }
1230         else if ((state->ir & 0xffc0) == 0xf080)
1231         {
1232                 logerror("680x0: unhandled PBcc\n");
1233                 return;
1234         }
1235         else if ((state->ir & 0xffe0) == 0xf500)
1236         {
1237                 MMULOG(("68040 pflush: pc=%08x ir=%04x opmode=%d register=%d\n", REG_PC-4, state->ir, (state->ir >> 3) & 3, state->ir & 7));
1238                 pmmu_atc_flush(state);
1239         }
1240         else    // the rest are 1111000xxxXXXXXX where xxx is the instruction family
1241         {
1242                 switch ((state->ir>>9) & 0x7)
1243                 {
1244                         case 0:
1245                                 modes = OPER_I_16(state);
1246
1247                                 if ((modes & 0xfde0) == 0x2000) // PLOAD
1248                                 {
1249                                         m68851_pload(state, ea, modes);
1250                                         return;
1251                                 }
1252                                 else if ((modes & 0xe200) == 0x2000)    // PFLUSH
1253                                 {
1254                                         pmmu_atc_flush_fc_ea(state, modes);
1255                                         return;
1256                                 }
1257                                 else if (modes == 0xa000)       // PFLUSHR
1258                                 {
1259                                         pmmu_atc_flush(state);
1260                                         return;
1261                                 }
1262                                 else if (modes == 0x2800)       // PVALID (FORMAT 1)
1263                                 {
1264                                         logerror("680x0: unhandled PVALID1\n");
1265                                         return;
1266                                 }
1267                                 else if ((modes & 0xfff8) == 0x2c00)    // PVALID (FORMAT 2)
1268                                 {
1269                                         logerror("680x0: unhandled PVALID2\n");
1270                                         return;
1271                                 }
1272                                 else if ((modes & 0xe000) == 0x8000)    // PTEST
1273                                 {
1274                                         m68851_ptest(state, ea, modes);
1275                                         return;
1276                                 }
1277                                 else
1278                                 {
1279                                         m68851_pmove(state, ea, modes);
1280                                 }
1281                                 break;
1282
1283                         default:
1284                                 logerror("680x0: unknown PMMU instruction group %d\n", (state->ir>>9) & 0x7);
1285                                 break;
1286                 }
1287         }
1288 }
1289
1290
1291 /* Apple HMMU translation is much simpler */
1292 /*
1293 inline uint32 hmmu_translate_addr(uint32 addr_in)
1294 {
1295         uint32 addr_out;
1296
1297         addr_out = addr_in;
1298
1299         // check if LC 24-bit mode is enabled - this simply blanks out A31, the V8 ignores A30-24 always
1300         if (state->hmmu_enabled == M68K_HMMU_ENABLE_LC)
1301         {
1302                 addr_out = addr_in & 0xffffff;
1303         }
1304         else if (state->hmmu_enabled == M68K_HMMU_ENABLE_II) // the original II does a more complex translation
1305         {
1306                 addr_out = addr_in & 0xffffff;
1307
1308                 if ((addr_out >= 0x800000) && (addr_out <= 0x8fffff))
1309                 {
1310                         addr_out |= 0x40000000; // ROM
1311                 }
1312                 else if ((addr_out >= 0x900000) && (addr_out <= 0xefffff))
1313                 {
1314                         addr_out = 0xf0000000;  // NuBus
1315                         addr_out |= ((addr_in & 0xf00000)<<4);
1316                         addr_out |= (addr_in & 0xfffff);
1317                 }
1318                 else if (addr_out >= 0xf00000)
1319                 {
1320                         addr_out |= 0x50000000; // I/O
1321                 }
1322
1323                 // (RAM is at 0 and doesn't need special massaging)
1324         }
1325
1326         return addr_out;
1327 }
1328
1329 int m68851_buserror(u32& addr)
1330 {
1331         if (!state->pmmu_enabled)
1332         {
1333                 return false;
1334         }
1335
1336         if (state->mmu_tablewalk)
1337         {
1338                 MMULOG(("buserror during table walk\n"));
1339                 state->mmu_tmp_sr |= M68K_MMU_SR_BUS_ERROR|M68K_MMU_SR_INVALID;
1340                 return true;
1341         }
1342
1343         addr = state->mmu_last_logical_addr;
1344         return false;
1345 }
1346 */