|
|
1.1.1.2 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"
1.1.1.3 ! root 30: #include "mmu_common.h"
1.1.1.2 root 31:
32: #ifndef FULLMMU
33: #define FULLMMU
34: #endif
35:
36: #define DUNUSED(x)
37: #define D
38: #if DEBUG
39: #define bug write_log
40: #else
41: #define bug
42: #endif
43:
44: static __inline void flush_internals (void) { }
45:
46: //typedef uae_u8 flagtype;
47:
48: //static m68k_exception except;
49:
50: struct xttrx {
51: uae_u32 log_addr_base : 8;
52: uae_u32 log_addr_mask : 8;
53: uae_u32 enable : 1;
54: uae_u32 s_field : 2;
55: uae_u32 : 3;
56: uae_u32 usr1 : 1;
57: uae_u32 usr0 : 1;
58: uae_u32 : 1;
59: uae_u32 cmode : 2;
60: uae_u32 : 2;
61: uae_u32 write : 1;
62: uae_u32 : 2;
63: };
64:
65: struct mmusr_t {
66: uae_u32 phys_addr : 20;
67: uae_u32 bus_err : 1;
68: uae_u32 global : 1;
69: uae_u32 usr1 : 1;
70: uae_u32 usr0 : 1;
71: uae_u32 super : 1;
72: uae_u32 cmode : 2;
73: uae_u32 modif : 1;
74: uae_u32 : 1;
75: uae_u32 write : 1;
76: uae_u32 ttrhit : 1;
77: uae_u32 resident : 1;
78: };
79:
80: struct log_addr4 {
81: uae_u32 rif : 7;
82: uae_u32 pif : 7;
83: uae_u32 paif : 6;
84: uae_u32 poff : 12;
85: };
86:
87: struct log_addr8 {
88: uae_u32 rif : 7;
89: uae_u32 pif : 7;
90: uae_u32 paif : 5;
91: uae_u32 poff : 13;
92: };
93:
94: #define MMU_TEST_PTEST 1
95: #define MMU_TEST_VERBOSE 2
96: #define MMU_TEST_FORCE_TABLE_SEARCH 4
97: #define MMU_TEST_NO_BUSERR 8
98:
99: extern void mmu_dump_tables(void);
100:
101: #define MMU_TTR_LOGICAL_BASE 0xff000000
102: #define MMU_TTR_LOGICAL_MASK 0x00ff0000
103: #define MMU_TTR_BIT_ENABLED (1 << 15)
104: #define MMU_TTR_BIT_SFIELD_ENABLED (1 << 14)
105: #define MMU_TTR_BIT_SFIELD_SUPER (1 << 13)
106: #define MMU_TTR_SFIELD_SHIFT 13
107: #define MMU_TTR_UX_MASK ((1 << 9) | (1 << 8))
108: #define MMU_TTR_UX_SHIFT 8
109: #define MMU_TTR_CACHE_MASK ((1 << 6) | (1 << 5))
110: #define MMU_TTR_CACHE_SHIFT 5
111: #define MMU_TTR_BIT_WRITE_PROTECT (1 << 2)
112:
113: #define MMU_UDT_MASK 3
114: #define MMU_PDT_MASK 3
115:
116: #define MMU_DES_WP 4
117: #define MMU_DES_USED 8
118:
119: /* page descriptors only */
120: #define MMU_DES_MODIFIED 16
121: #define MMU_DES_SUPER (1 << 7)
122: #define MMU_DES_GLOBAL (1 << 10)
123:
124: #define MMU_ROOT_PTR_ADDR_MASK 0xfffffe00
125: #define MMU_PTR_PAGE_ADDR_MASK_8 0xffffff80
126: #define MMU_PTR_PAGE_ADDR_MASK_4 0xffffff00
127:
128: #define MMU_PAGE_INDIRECT_MASK 0xfffffffc
129: #define MMU_PAGE_ADDR_MASK_8 0xffffe000
130: #define MMU_PAGE_ADDR_MASK_4 0xfffff000
131: #define MMU_PAGE_UR_MASK_8 ((1 << 12) | (1 << 11))
132: #define MMU_PAGE_UR_MASK_4 (1 << 11)
133: #define MMU_PAGE_UR_SHIFT 11
134:
135: #define MMU_MMUSR_ADDR_MASK 0xfffff000
136: #define MMU_MMUSR_B (1 << 11)
137: #define MMU_MMUSR_G (1 << 10)
138: #define MMU_MMUSR_U1 (1 << 9)
139: #define MMU_MMUSR_U0 (1 << 8)
140: #define MMU_MMUSR_Ux (MMU_MMUSR_U1 | MMU_MMUSR_U0)
141: #define MMU_MMUSR_S (1 << 7)
142: #define MMU_MMUSR_CM ((1 << 6) | ( 1 << 5))
143: #define MMU_MMUSR_M (1 << 4)
144: #define MMU_MMUSR_W (1 << 2)
145: #define MMU_MMUSR_T (1 << 1)
146: #define MMU_MMUSR_R (1 << 0)
147:
148: #define TTR_I0 4
149: #define TTR_I1 5
150: #define TTR_D0 6
151: #define TTR_D1 7
152:
153: #define TTR_NO_MATCH 0
154: #define TTR_NO_WRITE 1
155: #define TTR_OK_MATCH 2
156:
157: struct mmu_atc_line {
158: uaecptr tag; // tag is 16 or 17 bits S+logical
159: unsigned valid : 1;
160: unsigned global : 1;
161: unsigned modified : 1;
162: unsigned write_protect : 1;
163: uaecptr phys; // phys base address
164: };
165:
166: /*
167: * 68040 ATC is a 4 way 16 slot associative address translation cache
168: * the 68040 has a DATA and an INSTRUCTION ATC.
169: * an ATC lookup may result in : a hit, a miss and a modified state.
170: * the 68060 can disable ATC allocation
171: * we must take care of 8k and 4k page size, index position is relative to page size
172: */
173:
174: #define ATC_WAYS 4
175: #define ATC_SLOTS 16
176: #define ATC_TYPE 2
177:
178: extern bool mmu_is_super;
179: extern struct mmu_atc_line mmu_atc_array[ATC_TYPE][ATC_WAYS][ATC_SLOTS];
180:
181: /*
182: * mmu access is a 4 step process:
183: * if mmu is not enabled just read physical
184: * check transparent region, if transparent, read physical
185: * check ATC (address translation cache), read immediatly if HIT
186: * read from mmu with the long path (and allocate ATC entry if needed)
187: */
188: static ALWAYS_INLINE bool mmu_lookup(uaecptr addr, bool data, bool write,
189: struct mmu_atc_line **cl)
190: {
191: int way,index;
192: static int way_miss=0;
193:
194: addr = ((mmu_is_super?0x80000000:0x00000000)|(addr >> 1)) & (regs.mmu_pagesize_8k?0xFFFE0000:0xFFFF0000);
195: if (regs.mmu_pagesize_8k)
196: index=(addr & 0x0001E000)>>13;
197: else
198: index=(addr & 0x0000F000)>>12;
199: for (way=0;way<ATC_WAYS;way++) {
200: // if we have this
201: if ((addr == mmu_atc_array[data][way][index].tag) && (mmu_atc_array[data][way][index].valid)) {
202: *cl=&mmu_atc_array[data][way][index];
203: // if first write to this take slow path (but modify this slot)
204: if ((!mmu_atc_array[data][way][index].modified & write) || (mmu_atc_array[data][way][index].write_protect & write))
205: return false;
206: return true;
207: }
208: }
209: // we select a random way to void
210: *cl=&mmu_atc_array[data][way_miss%ATC_WAYS][index];
211: way_miss++;
212: return false;
213: }
214:
215: /*
216: */
217: static ALWAYS_INLINE bool mmu_user_lookup(uaecptr addr, bool super, bool data,
218: bool write, struct mmu_atc_line **cl)
219: {
220: int way,index;
221: static int way_miss=0;
222:
223: addr = ((super?0x80000000:0x00000000)|(addr >> 1)) & (regs.mmu_pagesize_8k?0xFFFE0000:0xFFFF0000);
224: if (regs.mmu_pagesize_8k)
225: index=(addr & 0x0001E000)>>13;
226: else
227: index=(addr & 0x0000F000)>>12;
228: for (way=0;way<ATC_WAYS;way++) {
229: // if we have this
230: if ((addr == mmu_atc_array[data][way][index].tag) && (mmu_atc_array[data][way][index].valid)) {
231: *cl=&mmu_atc_array[data][way][index];
232: // if first write to this take slow path (but modify this slot)
233: if ((!mmu_atc_array[data][way][index].modified & write) || (mmu_atc_array[data][way][index].write_protect & write))
234: return false;
235: return true;
236: }
237: }
238: // we select a random way to void
239: *cl=&mmu_atc_array[data][way_miss%ATC_WAYS][index];
240: way_miss++;
241: return false;
242: }
243:
244: /* check if an address matches a ttr */
245: static inline int mmu_do_match_ttr(uae_u32 ttr, uaecptr addr, bool super)
246: {
247: if (ttr & MMU_TTR_BIT_ENABLED) { /* TTR enabled */
248: uae_u8 msb, mask;
249:
250: msb = ((addr ^ ttr) & MMU_TTR_LOGICAL_BASE) >> 24;
251: mask = (ttr & MMU_TTR_LOGICAL_MASK) >> 16;
252:
253: if (!(msb & ~mask)) {
254:
255: if ((ttr & MMU_TTR_BIT_SFIELD_ENABLED) == 0) {
256: if (((ttr & MMU_TTR_BIT_SFIELD_SUPER) == 0) != (super == 0)) {
257: return TTR_NO_MATCH;
258: }
259: }
260:
261: return (ttr & MMU_TTR_BIT_WRITE_PROTECT) ? TTR_NO_WRITE : TTR_OK_MATCH;
262: }
263: }
264: return TTR_NO_MATCH;
265: }
266:
267: static inline int mmu_match_ttr(uaecptr addr, bool super, bool data)
268: {
269: int res;
270:
271: if (data) {
272: res = mmu_do_match_ttr(regs.dtt0, addr, super);
273: if (res == TTR_NO_MATCH)
274: res = mmu_do_match_ttr(regs.dtt1, addr, super);
275: } else {
276: res = mmu_do_match_ttr(regs.itt0, addr, super);
277: if (res == TTR_NO_MATCH)
278: res = mmu_do_match_ttr(regs.itt1, addr, super);
279: }
280: return res;
281: }
282:
283: extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr, bool data) REGPARAM;
284: extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr, bool data) REGPARAM;
285:
286: extern uae_u8 REGPARAM3 mmu_get_byte_slow(uaecptr addr, bool super, bool data,
287: int size, struct mmu_atc_line *cl) REGPARAM;
288: extern uae_u16 REGPARAM3 mmu_get_word_slow(uaecptr addr, bool super, bool data,
289: int size, struct mmu_atc_line *cl) REGPARAM;
290: extern uae_u32 REGPARAM3 mmu_get_long_slow(uaecptr addr, bool super, bool data,
291: int size, struct mmu_atc_line *cl) REGPARAM;
292:
293: extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) REGPARAM;
294: extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) REGPARAM;
295:
296: extern void REGPARAM3 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data,
297: int size, struct mmu_atc_line *cl) REGPARAM;
298: extern void REGPARAM3 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data,
299: int size, struct mmu_atc_line *cl) REGPARAM;
300: extern void REGPARAM3 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data,
301: int size, struct mmu_atc_line *cl) REGPARAM;
302:
303: extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode);
304:
305: #define FC_DATA (regs.s ? 5 : 1)
306: #define FC_INST (regs.s ? 6 : 2)
307:
308: extern uaecptr REGPARAM3 mmu_translate(uaecptr addr, bool super, bool data, bool write) REGPARAM;
309:
310: extern uae_u32 REGPARAM3 sfc_get_long(uaecptr addr) REGPARAM;
311: extern uae_u16 REGPARAM3 sfc_get_word(uaecptr addr) REGPARAM;
312: extern uae_u8 REGPARAM3 sfc_get_byte(uaecptr addr) REGPARAM;
313: extern void REGPARAM3 dfc_put_long(uaecptr addr, uae_u32 val) REGPARAM;
314: extern void REGPARAM3 dfc_put_word(uaecptr addr, uae_u16 val) REGPARAM;
315: extern void REGPARAM3 dfc_put_byte(uaecptr addr, uae_u8 val) REGPARAM;
316:
317:
318: extern void REGPARAM3 mmu_flush_atc(uaecptr addr, bool super, bool global) REGPARAM;
319: extern void REGPARAM3 mmu_flush_atc_all(bool global) REGPARAM;
320: extern void REGPARAM3 mmu_op_real(uae_u32 opcode, uae_u16 extra) REGPARAM;
321:
322: extern void REGPARAM3 mmu_reset(void) REGPARAM;
323: extern void REGPARAM3 mmu_set_tc(uae_u16 tc) REGPARAM;
324: extern void REGPARAM3 mmu_set_super(bool super) REGPARAM;
325:
326: static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_line *cl)
327: {
328: return cl->phys | (addr & (regs.mmu_pagesize_8k?0x00001fff:0x00000fff));
329: }
330:
331: static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size)
332: {
333: struct mmu_atc_line *cl;
334:
335: // addr,super,data
336: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH))
337: return phys_get_long(addr);
338: if (likely(mmu_lookup(addr, data, false, &cl)))
339: return phys_get_long(mmu_get_real_address(addr, cl));
340: return mmu_get_long_slow(addr, regs.s != 0, data, size, cl);
341: }
342:
343: static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, bool data, int size)
344: {
345: struct mmu_atc_line *cl;
346:
347: // addr,super,data
348: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH))
349: return phys_get_word(addr);
350: if (likely(mmu_lookup(addr, data, false, &cl)))
351: return phys_get_word(mmu_get_real_address(addr, cl));
352: return mmu_get_word_slow(addr, regs.s != 0, data, size, cl);
353: }
354:
355: static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, bool data, int size)
356: {
357: struct mmu_atc_line *cl;
358:
359: // addr,super,data
360: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH))
361: return phys_get_byte(addr);
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: // addr,super,data
373: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)==TTR_OK_MATCH)) {
374: phys_put_long(addr,val);
375: return;
376: }
377: if (likely(mmu_lookup(addr, data, true, &cl)))
378: phys_put_long(mmu_get_real_address(addr, cl), val);
379: else
380: mmu_put_long_slow(addr, val, regs.s != 0, data, size, cl);
381: }
382:
383: static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size)
384: {
385: struct mmu_atc_line *cl;
386:
387: // addr,super,data
388: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)==TTR_OK_MATCH)) {
389: phys_put_word(addr,val);
390: return;
391: }
392: if (likely(mmu_lookup(addr, data, true, &cl)))
393: phys_put_word(mmu_get_real_address(addr, cl), val);
394: else
395: mmu_put_word_slow(addr, val, regs.s != 0, data, size, cl);
396: }
397:
398: static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, bool data, int size)
399: {
400: struct mmu_atc_line *cl;
401:
402: // addr,super,data
403: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)==TTR_OK_MATCH)) {
404: phys_put_byte(addr,val);
405: return;
406: }
407: if (likely(mmu_lookup(addr, data, true, &cl)))
408: phys_put_byte(mmu_get_real_address(addr, cl), val);
409: else
410: mmu_put_byte_slow(addr, val, regs.s != 0, data, size, cl);
411: }
412:
413: static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool data, int size)
414: {
415: struct mmu_atc_line *cl;
416:
417: // addr,super,data
418: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH))
419: return phys_get_long(addr);
420: if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
421: return phys_get_long(mmu_get_real_address(addr, cl));
422: return mmu_get_long_slow(addr, super, data, size, cl);
423: }
424:
425: static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool data, int size)
426: {
427: struct mmu_atc_line *cl;
428:
429: // addr,super,data
430: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH))
431: return phys_get_word(addr);
432: if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
433: return phys_get_word(mmu_get_real_address(addr, cl));
434: return mmu_get_word_slow(addr, super, data, size, cl);
435: }
436:
437: static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool data, int size)
438: {
439: struct mmu_atc_line *cl;
440:
441: // addr,super,data
442: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH))
443: return phys_get_byte(addr);
444: if (likely(mmu_user_lookup(addr, super, data, false, &cl)))
445: return phys_get_byte(mmu_get_real_address(addr, cl));
446: return mmu_get_byte_slow(addr, super, data, size, cl);
447: }
448:
449: static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool super, bool data, int size)
450: {
451: struct mmu_atc_line *cl;
452:
453: // addr,super,data
454: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) {
455: phys_put_long(addr,val);
456: return;
457: }
458: if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
459: phys_put_long(mmu_get_real_address(addr, cl), val);
460: else
461: mmu_put_long_slow(addr, val, super, data, size, cl);
462: }
463:
464: static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool super, bool data, int size)
465: {
466: struct mmu_atc_line *cl;
467:
468: // addr,super,data
469: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) {
470: phys_put_word(addr,val);
471: return;
472: }
473: if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
474: phys_put_word(mmu_get_real_address(addr, cl), val);
475: else
476: mmu_put_word_slow(addr, val, super, data, size, cl);
477: }
478:
479: static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super, bool data, int size)
480: {
481: struct mmu_atc_line *cl;
482:
483: // addr,super,data
484: if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) {
485: phys_put_byte(addr,val);
486: return;
487: }
488: if (likely(mmu_user_lookup(addr, super, data, true, &cl)))
489: phys_put_byte(mmu_get_real_address(addr, cl), val);
490: else
491: mmu_put_byte_slow(addr, val, super, data, size, cl);
492: }
493:
494:
495: static ALWAYS_INLINE void HWput_l(uaecptr addr, uae_u32 l)
496: {
497: put_long (addr, l);
498: }
499: static ALWAYS_INLINE void HWput_w(uaecptr addr, uae_u32 w)
500: {
501: put_word (addr, w);
502: }
503: static ALWAYS_INLINE void HWput_b(uaecptr addr, uae_u32 b)
504: {
505: put_byte (addr, b);
506: }
507: static ALWAYS_INLINE uae_u32 HWget_l(uaecptr addr)
508: {
509: return get_long (addr);
510: }
511: static ALWAYS_INLINE uae_u32 HWget_w(uaecptr addr)
512: {
513: return get_word (addr);
514: }
515: static ALWAYS_INLINE uae_u32 HWget_b(uaecptr addr)
516: {
517: return get_byte (addr);
518: }
519:
520: static ALWAYS_INLINE uae_u32 uae_mmu_get_ilong(uaecptr addr)
521: {
522: if (unlikely(is_unaligned(addr, 4)))
523: return mmu_get_long_unaligned(addr, false);
524: return mmu_get_long(addr, false, sz_long);
525: }
526: static ALWAYS_INLINE uae_u16 uae_mmu_get_iword(uaecptr addr)
527: {
528: if (unlikely(is_unaligned(addr, 2)))
529: return mmu_get_word_unaligned(addr, false);
530: return mmu_get_word(addr, false, sz_word);
531: }
532: static ALWAYS_INLINE uae_u16 uae_mmu_get_ibyte(uaecptr addr)
533: {
534: return mmu_get_byte(addr, false, sz_byte);
535: }
536: static ALWAYS_INLINE uae_u32 uae_mmu_get_long(uaecptr addr)
537: {
538: if (unlikely(is_unaligned(addr, 4)))
539: return mmu_get_long_unaligned(addr, true);
540: return mmu_get_long(addr, true, sz_long);
541: }
542: static ALWAYS_INLINE uae_u16 uae_mmu_get_word(uaecptr addr)
543: {
544: if (unlikely(is_unaligned(addr, 2)))
545: return mmu_get_word_unaligned(addr, true);
546: return mmu_get_word(addr, true, sz_word);
547: }
548: static ALWAYS_INLINE uae_u8 uae_mmu_get_byte(uaecptr addr)
549: {
550: return mmu_get_byte(addr, true, sz_byte);
551: }
552: static ALWAYS_INLINE void uae_mmu_put_long(uaecptr addr, uae_u32 val)
553: {
554: if (unlikely(is_unaligned(addr, 4)))
555: mmu_put_long_unaligned(addr, val, true);
556: else
557: mmu_put_long(addr, val, true, sz_long);
558: }
559: static ALWAYS_INLINE void uae_mmu_put_word(uaecptr addr, uae_u16 val)
560: {
561: if (unlikely(is_unaligned(addr, 2)))
562: mmu_put_word_unaligned(addr, val, true);
563: else
564: mmu_put_word(addr, val, true, sz_word);
565: }
566: static ALWAYS_INLINE void uae_mmu_put_byte(uaecptr addr, uae_u8 val)
567: {
568: mmu_put_byte(addr, val, true, sz_byte);
569: }
570:
571: STATIC_INLINE void put_byte_mmu (uaecptr addr, uae_u32 v)
572: {
573: uae_mmu_put_byte (addr, v);
574: }
575: STATIC_INLINE void put_word_mmu (uaecptr addr, uae_u32 v)
576: {
577: uae_mmu_put_word (addr, v);
578: }
579: STATIC_INLINE void put_long_mmu (uaecptr addr, uae_u32 v)
580: {
581: uae_mmu_put_long (addr, v);
582: }
583: STATIC_INLINE uae_u32 get_byte_mmu (uaecptr addr)
584: {
585: return uae_mmu_get_byte (addr);
586: }
587: STATIC_INLINE uae_u32 get_word_mmu (uaecptr addr)
588: {
589: return uae_mmu_get_word (addr);
590: }
591: STATIC_INLINE uae_u32 get_long_mmu (uaecptr addr)
592: {
593: return uae_mmu_get_long (addr);
594: }
595: STATIC_INLINE uae_u32 get_ibyte_mmu (int o)
596: {
597: uae_u32 pc = m68k_getpc () + o;
598: return uae_mmu_get_iword (pc);
599: }
600: STATIC_INLINE uae_u32 get_iword_mmu (int o)
601: {
602: uae_u32 pc = m68k_getpc () + o;
603: return uae_mmu_get_iword (pc);
604: }
605: STATIC_INLINE uae_u32 get_ilong_mmu (int o)
606: {
607: uae_u32 pc = m68k_getpc () + o;
608: return uae_mmu_get_ilong (pc);
609: }
610: STATIC_INLINE uae_u32 next_iword_mmu (void)
611: {
612: uae_u32 pc = m68k_getpc ();
613: m68k_incpci (2);
614: return uae_mmu_get_iword (pc);
615: }
616: STATIC_INLINE uae_u32 next_ilong_mmu (void)
617: {
618: uae_u32 pc = m68k_getpc ();
619: m68k_incpci (4);
620: return uae_mmu_get_ilong (pc);
621: }
622:
623: extern void m68k_do_rts_mmu (void);
624: extern void m68k_do_rte_mmu (uaecptr a7);
625: extern void m68k_do_bsr_mmu (uaecptr oldpc, uae_s32 offset);
626:
627: #endif /* CPUMMU_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.