|
|
1.1 root 1: /*
2: * cpummu.h - MMU emulation
3: *
4: * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS)
5: *
6: * Inspired by UAE MMU patch
7: *
8: * This file is part of the ARAnyM project which builds a new and powerful
9: * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
10: *
11: * ARAnyM is free software; you can redistribute it and/or modify
12: * it under the terms of the GNU General Public License as published by
13: * the Free Software Foundation; either version 2 of the License, or
14: * (at your option) any later version.
15: *
16: * ARAnyM is distributed in the hope that it will be useful,
17: * but WITHOUT ANY WARRANTY; without even the implied warranty of
18: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19: * GNU General Public License for more details.
20: *
21: * You should have received a copy of the GNU General Public License
22: * along with ARAnyM; if not, write to the Free Software
23: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24: */
25:
26: #ifndef CPUMMU_H
27: #define CPUMMU_H
28:
29: #include "compat.h"
30:
31: #ifndef FULLMMU
32: #define FULLMMU
33: #endif
34:
35: #define DUNUSED(x)
36: #define D
37: #if DEBUG
38: #define bug write_log
39: #else
40: #define bug
41: #endif
42:
43: /*struct m68k_exception {
44: int prb;
45: m68k_exception (int exc) : prb (exc) {}
46: operator int() { return prb; }
47: };*/
48: typedef int m68k_exception;
49:
50: #define SAVE_EXCEPTION
51: #define RESTORE_EXCEPTION
52: //#define TRY(var) try
53: //#define CATCH(var) catch(m68k_exception var)
54: #define CATCH(var) if (except != 0)
55: //#define THROW(n) except=n
56: //#define THROW_AGAIN(var) except=var
57: #define VOLATILE
58: #define ALWAYS_INLINE __inline
59:
60: static __inline void flush_internals (void) { }
61:
62: //typedef uae_u8 flagtype;
63:
64: static m68k_exception except;
65:
66: struct xttrx {
67: uae_u32 log_addr_base : 8;
68: uae_u32 log_addr_mask : 8;
69: uae_u32 enable : 1;
70: uae_u32 s_field : 2;
71: uae_u32 : 3;
72: uae_u32 usr1 : 1;
73: uae_u32 usr0 : 1;
74: uae_u32 : 1;
75: uae_u32 cmode : 2;
76: uae_u32 : 2;
77: uae_u32 write : 1;
78: uae_u32 : 2;
79: };
80:
81: struct mmusr_t {
82: uae_u32 phys_addr : 20;
83: uae_u32 bus_err : 1;
84: uae_u32 global : 1;
85: uae_u32 usr1 : 1;
86: uae_u32 usr0 : 1;
87: uae_u32 super : 1;
88: uae_u32 cmode : 2;
89: uae_u32 modif : 1;
90: uae_u32 : 1;
91: uae_u32 write : 1;
92: uae_u32 ttrhit : 1;
93: uae_u32 resident : 1;
94: };
95:
96: struct log_addr4 {
97: uae_u32 rif : 7;
98: uae_u32 pif : 7;
99: uae_u32 paif : 6;
100: uae_u32 poff : 12;
101: };
102:
103: struct log_addr8 {
104: uae_u32 rif : 7;
105: uae_u32 pif : 7;
106: uae_u32 paif : 5;
107: uae_u32 poff : 13;
108: };
109:
110: #define MMU_TEST_PTEST 1
111: #define MMU_TEST_VERBOSE 2
112: #define MMU_TEST_FORCE_TABLE_SEARCH 4
113: #define MMU_TEST_NO_BUSERR 8
114:
115: extern void mmu_dump_tables(void);
116:
117: #define MMU_TTR_LOGICAL_BASE 0xff000000
118: #define MMU_TTR_LOGICAL_MASK 0x00ff0000
119: #define MMU_TTR_BIT_ENABLED (1 << 15)
120: #define MMU_TTR_BIT_SFIELD_ENABLED (1 << 14)
121: #define MMU_TTR_BIT_SFIELD_SUPER (1 << 13)
122: #define MMU_TTR_SFIELD_SHIFT 13
123: #define MMU_TTR_UX_MASK ((1 << 9) | (1 << 8))
124: #define MMU_TTR_UX_SHIFT 8
125: #define MMU_TTR_CACHE_MASK ((1 << 6) | (1 << 5))
126: #define MMU_TTR_CACHE_SHIFT 5
127: #define MMU_TTR_BIT_WRITE_PROTECT (1 << 2)
128:
129: #define MMU_UDT_MASK 3
130: #define MMU_PDT_MASK 3
131:
132: #define MMU_DES_WP 4
133: #define MMU_DES_USED 8
134:
135: /* page descriptors only */
136: #define MMU_DES_MODIFIED 16
137: #define MMU_DES_SUPER (1 << 7)
138: #define MMU_DES_GLOBAL (1 << 10)
139:
140: #define MMU_ROOT_PTR_ADDR_MASK 0xfffffe00
141: #define MMU_PTR_PAGE_ADDR_MASK_8 0xffffff80
142: #define MMU_PTR_PAGE_ADDR_MASK_4 0xffffff00
143:
144: #define MMU_PAGE_INDIRECT_MASK 0xfffffffc
145: #define MMU_PAGE_ADDR_MASK_8 0xffffe000
146: #define MMU_PAGE_ADDR_MASK_4 0xfffff000
147: #define MMU_PAGE_UR_MASK_8 ((1 << 12) | (1 << 11))
148: #define MMU_PAGE_UR_MASK_4 (1 << 11)
149: #define MMU_PAGE_UR_SHIFT 11
150:
151: #define MMU_MMUSR_ADDR_MASK 0xfffff000
152: #define MMU_MMUSR_B (1 << 11)
153: #define MMU_MMUSR_G (1 << 10)
154: #define MMU_MMUSR_U1 (1 << 9)
155: #define MMU_MMUSR_U0 (1 << 8)
156: #define MMU_MMUSR_Ux (MMU_MMUSR_U1 | MMU_MMUSR_U0)
157: #define MMU_MMUSR_S (1 << 7)
158: #define MMU_MMUSR_CM ((1 << 6) | ( 1 << 5))
159: #define MMU_MMUSR_M (1 << 4)
160: #define MMU_MMUSR_W (1 << 2)
161: #define MMU_MMUSR_T (1 << 1)
162: #define MMU_MMUSR_R (1 << 0)
163:
164: /* special status word (access error stack frame) */
165: #define MMU_SSW_TM 0x0007
166: #define MMU_SSW_TT 0x0018
167: #define MMU_SSW_SIZE 0x0060
168: #define MMU_SSW_SIZE_B 0x0020
169: #define MMU_SSW_SIZE_W 0x0040
170: #define MMU_SSW_SIZE_L 0x0000
171: #define MMU_SSW_RW 0x0100
172: #define MMU_SSW_LK 0x0200
173: #define MMU_SSW_ATC 0x0400
174: #define MMU_SSW_MA 0x0800
175: #define MMU_SSW_CM 0x1000
176: #define MMU_SSW_CT 0x2000
177: #define MMU_SSW_CU 0x4000
178: #define MMU_SSW_CP 0x8000
179:
180: #define TTR_I0 4
181: #define TTR_I1 5
182: #define TTR_D0 6
183: #define TTR_D1 7
184:
185: #define TTR_NO_MATCH 0
186: #define TTR_NO_WRITE 1
187: #define TTR_OK_MATCH 2
188:
189: struct mmu_atc_line {
190: uae_u16 tag;
191: unsigned tt : 1;
192: unsigned valid_data : 1;
193: unsigned valid_inst : 1;
194: unsigned global : 1;
195: unsigned modified : 1;
196: unsigned write_protect : 1;
197: unsigned hw : 1;
198: unsigned bus_fault : 1;
199: uaecptr phys;
200: };
201:
202: /*
203: * We don't need to store the whole logical address in the atc cache, as part of
204: * it is encoded as index into the cache. 14 bits of the address are stored in
205: * the tag, this means at least 6 bits must go into the index. The upper two
206: * bits of the tag define the type of data in the atc line:
207: * - 00: a normal memory address
208: * - 11: invalid memory address or hardware access
209: * (generated via ~ATC_TAG(addr) in the slow path)
210: * - 10: empty atc line
211: */
212:
213: #define ATC_TAG_SHIFT 18
214: #define ATC_TAG(addr) ((uae_u32)(addr) >> ATC_TAG_SHIFT)
215:
216:
217: #define ATC_L1_SIZE_LOG 8
218: #define ATC_L1_SIZE (1 << ATC_L1_SIZE_LOG)
219:
220: #define ATC_L1_INDEX(addr) (((addr) >> 12) % ATC_L1_SIZE)
221:
222: /*
223: * first level atc cache
224: * indexed by [super][data][rw][idx]
225: */
226:
227: typedef struct mmu_atc_line mmu_atc_l1_array[2][2][ATC_L1_SIZE];
228: extern mmu_atc_l1_array atc_l1[2];
229: extern mmu_atc_l1_array *current_atc;
230:
231: #define ATC_L2_SIZE_LOG 12
232: #define ATC_L2_SIZE (1 << ATC_L2_SIZE_LOG)
233:
234: #define ATC_L2_INDEX(addr) ((((addr) >> 12) ^ ((addr) >> (32 - ATC_L2_SIZE_LOG))) % ATC_L2_SIZE)
235:
236: extern struct mmu_atc_line atc_l2[2][ATC_L2_SIZE];
237:
238: /*
239: * lookup address in the level 1 atc cache,
240: * the data and write arguments are constant in the common,
241: * thus allows gcc to generate a constant offset.
242: */
243: static ALWAYS_INLINE bool mmu_lookup(uaecptr addr, bool data, bool write,
244: struct mmu_atc_line **cl)
245: {
246: addr >>= 12;
247: *cl = &(*current_atc)[data ? 1 : 0][write ? 1 : 0][addr % ATC_L1_SIZE];
248: return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12);
249: }
250:
251: /*
252: * similiar to mmu_user_lookup, but for the use of the moves instruction
253: */
254: static ALWAYS_INLINE bool mmu_user_lookup(uaecptr addr, bool super, bool data,
255: bool write, struct mmu_atc_line **cl)
256: {
257: addr >>= 12;
258: *cl = &atc_l1[super ? 1 : 0][data ? 1 : 0][write ? 1 : 0][addr % ATC_L1_SIZE];
259: return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12);
260: }
261:
262: extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr, bool data) REGPARAM;
263: extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr, bool data) REGPARAM;
264:
265: extern uae_u8 REGPARAM3 mmu_get_byte_slow(uaecptr addr, bool super, bool data,
266: int size, struct mmu_atc_line *cl) REGPARAM;
267: extern uae_u16 REGPARAM3 mmu_get_word_slow(uaecptr addr, bool super, bool data,
268: int size, struct mmu_atc_line *cl) REGPARAM;
269: extern uae_u32 REGPARAM3 mmu_get_long_slow(uaecptr addr, bool super, bool data,
270: int size, struct mmu_atc_line *cl) REGPARAM;
271:
272: extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) REGPARAM;
273: extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) REGPARAM;
274:
275: extern void REGPARAM3 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data,
276: int size, struct mmu_atc_line *cl) REGPARAM;
277: extern void REGPARAM3 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data,
278: int size, struct mmu_atc_line *cl) REGPARAM;
279: extern void REGPARAM3 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data,
280: int size, struct mmu_atc_line *cl) REGPARAM;
281:
282: extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode);
283:
284: #define FC_DATA (regs.s ? 5 : 1)
285: #define FC_INST (regs.s ? 6 : 2)
286:
287: extern uaecptr REGPARAM3 mmu_translate(uaecptr addr, bool super, bool data, bool write) REGPARAM;
288:
289: extern uae_u32 REGPARAM3 sfc_get_long(uaecptr addr) REGPARAM;
290: extern uae_u16 REGPARAM3 sfc_get_word(uaecptr addr) REGPARAM;
291: extern uae_u8 REGPARAM3 sfc_get_byte(uaecptr addr) REGPARAM;
292: extern void REGPARAM3 dfc_put_long(uaecptr addr, uae_u32 val) REGPARAM;
293: extern void REGPARAM3 dfc_put_word(uaecptr addr, uae_u16 val) REGPARAM;
294: extern void REGPARAM3 dfc_put_byte(uaecptr addr, uae_u8 val) REGPARAM;
295:
296:
297: extern void REGPARAM3 mmu_flush_atc(uaecptr addr, bool super, bool global) REGPARAM;
298: extern void REGPARAM3 mmu_flush_atc_all(bool global) REGPARAM;
299: extern void REGPARAM3 mmu_op_real(uae_u32 opcode, uae_u16 extra) REGPARAM;
300:
301: extern void REGPARAM3 mmu_reset(void) REGPARAM;
302: extern void REGPARAM3 mmu_set_tc(uae_u16 tc) REGPARAM;
303: extern void REGPARAM3 mmu_set_super(bool super) REGPARAM;
304:
305: static ALWAYS_INLINE bool is_unaligned(uaecptr addr, int size)
306: {
307: return unlikely((addr & (size - 1)) && (addr ^ (addr + size - 1)) & 0x1000);
308: }
309:
310: static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_line *cl)
311: {
312: return cl->phys + addr;
313: }
314:
315: static ALWAYS_INLINE void phys_put_long(uaecptr addr, uae_u32 l)
316: {
317: longput(addr, l);
318: }
319: static ALWAYS_INLINE void phys_put_word(uaecptr addr, uae_u32 w)
320: {
321: wordput(addr, w);
322: }
323: static ALWAYS_INLINE void phys_put_byte(uaecptr addr, uae_u32 b)
324: {
325: byteput(addr, b);
326: }
327: static ALWAYS_INLINE uae_u32 phys_get_long(uaecptr addr)
328: {
329: return longget (addr);
330: }
331: static ALWAYS_INLINE uae_u32 phys_get_word(uaecptr addr)
332: {
333: return wordget (addr);
334: }
335: static ALWAYS_INLINE uae_u32 phys_get_byte(uaecptr addr)
336: {
337: return byteget (addr);
338: }
339:
340: static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size)
341: {
342: struct mmu_atc_line *cl;
343:
344: if (likely(mmu_lookup(addr, data, false, &cl)))
345: return phys_get_long(mmu_get_real_address(addr, cl));
346: return mmu_get_long_slow(addr, regs.s != 0, data, size, cl);
347: }
348:
349: static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, bool data, int size)
350: {
351: struct mmu_atc_line *cl;
352:
353: if (likely(mmu_lookup(addr, data, false, &cl)))
354: return phys_get_word(mmu_get_real_address(addr, cl));
355: return mmu_get_word_slow(addr, regs.s != 0, data, size, cl);
356: }
357:
358: static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, bool data, int size)
359: {
360: struct mmu_atc_line *cl;
361:
362: if (likely(mmu_lookup(addr, data, false, &cl)))
363: return phys_get_byte(mmu_get_real_address(addr, cl));
364: return mmu_get_byte_slow(addr, regs.s != 0, data, size, cl);
365: }
366:
367:
368: static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, bool data, int size)
369: {
370: struct mmu_atc_line *cl;
371:
372: if (likely(mmu_lookup(addr, data, true, &cl)))
373: phys_put_long(mmu_get_real_address(addr, cl), val);
374: else
375: mmu_put_long_slow(addr, val, regs.s != 0, data, size, cl);
376: }
377:
378: static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size)
379: {
380: struct mmu_atc_line *cl;
381:
382: if (likely(mmu_lookup(addr, data, true, &cl)))
383: phys_put_word(mmu_get_real_address(addr, cl), val);
384: else
385: mmu_put_word_slow(addr, val, regs.s != 0, data, size, cl);
386: }
387:
388: static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, bool data, int size)
389: {
390: struct mmu_atc_line *cl;
391:
392: if (likely(mmu_lookup(addr, data, true, &cl)))
393: phys_put_byte(mmu_get_real_address(addr, cl), val);
394: else
395: mmu_put_byte_slow(addr, val, regs.s != 0, data, size, cl);
396: }
397:
398: static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool data, int size)
399: {
400: struct mmu_atc_line *cl;
401:
402: if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
403: return phys_get_long(mmu_get_real_address(addr, cl));
404: return mmu_get_long_slow(addr, super, data, size, cl);
405: }
406:
407: static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool data, int size)
408: {
409: struct mmu_atc_line *cl;
410:
411: if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
412: return phys_get_word(mmu_get_real_address(addr, cl));
413: return mmu_get_word_slow(addr, super, data, size, cl);
414: }
415:
416: static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool data, int size)
417: {
418: struct mmu_atc_line *cl;
419:
420: if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
421: return phys_get_byte(mmu_get_real_address(addr, cl));
422: return mmu_get_byte_slow(addr, super, data, size, cl);
423: }
424:
425: static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool super, bool data, int size)
426: {
427: struct mmu_atc_line *cl;
428:
429: if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
430: phys_put_long(mmu_get_real_address(addr, cl), val);
431: else
432: mmu_put_long_slow(addr, val, super, data, size, cl);
433: }
434:
435: static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool super, bool data, int size)
436: {
437: struct mmu_atc_line *cl;
438:
439: if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
440: phys_put_word(mmu_get_real_address(addr, cl), val);
441: else
442: mmu_put_word_slow(addr, val, super, data, size, cl);
443: }
444:
445: static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super, bool data, int size)
446: {
447: struct mmu_atc_line *cl;
448:
449: if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
450: phys_put_byte(mmu_get_real_address(addr, cl), val);
451: else
452: mmu_put_byte_slow(addr, val, super, data, size, cl);
453: }
454:
455:
456: static ALWAYS_INLINE void HWput_l(uaecptr addr, uae_u32 l)
457: {
458: put_long (addr, l);
459: }
460: static ALWAYS_INLINE void HWput_w(uaecptr addr, uae_u32 w)
461: {
462: put_word (addr, w);
463: }
464: static ALWAYS_INLINE void HWput_b(uaecptr addr, uae_u32 b)
465: {
466: put_byte (addr, b);
467: }
468: static ALWAYS_INLINE uae_u32 HWget_l(uaecptr addr)
469: {
470: return get_long (addr);
471: }
472: static ALWAYS_INLINE uae_u32 HWget_w(uaecptr addr)
473: {
474: return get_word (addr);
475: }
476: static ALWAYS_INLINE uae_u32 HWget_b(uaecptr addr)
477: {
478: return get_byte (addr);
479: }
480:
481: static ALWAYS_INLINE uae_u32 uae_mmu_get_ilong(uaecptr addr)
482: {
483: if (unlikely(is_unaligned(addr, 4)))
484: return mmu_get_long_unaligned(addr, false);
485: return mmu_get_long(addr, false, sz_long);
486: }
487: static ALWAYS_INLINE uae_u16 uae_mmu_get_iword(uaecptr addr)
488: {
489: if (unlikely(is_unaligned(addr, 2)))
490: return mmu_get_word_unaligned(addr, false);
491: return mmu_get_word(addr, false, sz_word);
492: }
493: static ALWAYS_INLINE uae_u16 uae_mmu_get_ibyte(uaecptr addr)
494: {
495: return mmu_get_byte(addr, false, sz_byte);
496: }
497: static ALWAYS_INLINE uae_u32 uae_mmu_get_long(uaecptr addr)
498: {
499: if (unlikely(is_unaligned(addr, 4)))
500: return mmu_get_long_unaligned(addr, true);
501: return mmu_get_long(addr, true, sz_long);
502: }
503: static ALWAYS_INLINE uae_u16 uae_mmu_get_word(uaecptr addr)
504: {
505: if (unlikely(is_unaligned(addr, 2)))
506: return mmu_get_word_unaligned(addr, true);
507: return mmu_get_word(addr, true, sz_word);
508: }
509: static ALWAYS_INLINE uae_u8 uae_mmu_get_byte(uaecptr addr)
510: {
511: return mmu_get_byte(addr, true, sz_byte);
512: }
513: static ALWAYS_INLINE void uae_mmu_put_long(uaecptr addr, uae_u32 val)
514: {
515: if (unlikely(is_unaligned(addr, 4)))
516: mmu_put_long_unaligned(addr, val, true);
517: else
518: mmu_put_long(addr, val, true, sz_long);
519: }
520: static ALWAYS_INLINE void uae_mmu_put_word(uaecptr addr, uae_u16 val)
521: {
522: if (unlikely(is_unaligned(addr, 2)))
523: mmu_put_word_unaligned(addr, val, true);
524: else
525: mmu_put_word(addr, val, true, sz_word);
526: }
527: static ALWAYS_INLINE void uae_mmu_put_byte(uaecptr addr, uae_u8 val)
528: {
529: mmu_put_byte(addr, val, true, sz_byte);
530: }
531:
532: STATIC_INLINE void put_byte_mmu (uaecptr addr, uae_u32 v)
533: {
534: uae_mmu_put_byte (addr, v);
535: }
536: STATIC_INLINE void put_word_mmu (uaecptr addr, uae_u32 v)
537: {
538: uae_mmu_put_word (addr, v);
539: }
540: STATIC_INLINE void put_long_mmu (uaecptr addr, uae_u32 v)
541: {
542: uae_mmu_put_long (addr, v);
543: }
544: STATIC_INLINE uae_u32 get_byte_mmu (uaecptr addr)
545: {
546: return uae_mmu_get_byte (addr);
547: }
548: STATIC_INLINE uae_u32 get_word_mmu (uaecptr addr)
549: {
550: return uae_mmu_get_word (addr);
551: }
552: STATIC_INLINE uae_u32 get_long_mmu (uaecptr addr)
553: {
554: return uae_mmu_get_long (addr);
555: }
556: STATIC_INLINE uae_u32 get_ibyte_mmu (int o)
557: {
558: uae_u32 pc = m68k_getpc () + o;
559: return uae_mmu_get_iword (pc);
560: }
561: STATIC_INLINE uae_u32 get_iword_mmu (int o)
562: {
563: uae_u32 pc = m68k_getpc () + o;
564: return uae_mmu_get_iword (pc);
565: }
566: STATIC_INLINE uae_u32 get_ilong_mmu (int o)
567: {
568: uae_u32 pc = m68k_getpc () + o;
569: return uae_mmu_get_ilong (pc);
570: }
571: STATIC_INLINE uae_u32 next_iword_mmu (void)
572: {
573: uae_u32 pc = m68k_getpc ();
574: m68k_incpci (2);
575: return uae_mmu_get_iword (pc);
576: }
577: STATIC_INLINE uae_u32 next_ilong_mmu (void)
578: {
579: uae_u32 pc = m68k_getpc ();
580: m68k_incpci (4);
581: return uae_mmu_get_ilong (pc);
582: }
583:
584: extern void m68k_do_rts_mmu (void);
585: extern void m68k_do_rte_mmu (uaecptr a7);
586: extern void m68k_do_bsr_mmu (uaecptr oldpc, uae_s32 offset);
587:
588: struct mmufixup
589: {
590: int reg;
591: uae_u32 value;
592: };
593: extern struct mmufixup mmufixup[2];
594:
595: #endif /* CPUMMU_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.