this repo has no description
1/*
2 ENDIANAC.h
3
4 Copyright (C) 2006 Bernd Schmidt, Paul C. Pratt
5
6 You can redistribute this file and/or modify it under the terms
7 of version 2 of the GNU General Public License as published by
8 the Free Software Foundation. You should have received a copy
9 of the license along with this file; see the file COPYING.
10
11 This file is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 license for more details.
15*/
16
17/*
18 ENDIAN ACcess
19
20 Deals with endian issues in memory access.
21
22 This code is adapted from code in the Un*x Amiga Emulator by
23 Bernd Schmidt, as found in vMac by Philip Cummins.
24*/
25
26#ifdef ENDIANAC_H
27#error "header already included"
28#else
29#define ENDIANAC_H
30#endif
31
32
33#define do_get_mem_byte(a) ((ui3r)*((ui3b *)(a)))
34
35#if BigEndianUnaligned
36#define do_get_mem_word(a) ((ui4r)*((ui4b *)(a)))
37#else
38LOCALINLINEFUNC ui4r do_get_mem_word(ui3p a)
39{
40#if LittleEndianUnaligned
41 ui4b b = (*((ui4b *)(a)));
42
43 return ((b & 0x00FF) << 8) | ((b >> 8) & 0x00FF);
44#else
45 return (((ui4r)*a) << 8) | ((ui4r)*(a + 1));
46#endif
47}
48#endif
49
50#if BigEndianUnaligned
51#define do_get_mem_long(a) ((ui5r)*((ui5b *)(a)))
52#elif HaveMySwapUi5r && LittleEndianUnaligned
53#define do_get_mem_long(a) (MySwapUi5r((ui5r)*((ui5b *)(a))))
54#else
55LOCALINLINEFUNC ui5r do_get_mem_long(ui3p a)
56{
57#if LittleEndianUnaligned
58#if 0
59 ui5b b = (*((ui5b *)(a)));
60 return ((b & 0x000000FF) << 24)
61 | ((b & 0x0000FF00) << 8)
62 | ((b & 0x00FF0000) >> 8)
63 | ((b & 0xFF000000) >> 24);
64#endif
65#if 0
66 ui5b b = (*((ui5b *)(a)));
67 return ((b << 24) & 0xFF000000)
68 | ((b << 8) & 0x00FF0000)
69 | ((b >> 8) & 0x0000FF00)
70 | ((b >> 24) & 0x000000FF);
71 /*
72 no, this doesn't do well with apple tools,
73 instead try combining two 16 bit swaps.
74 */
75#endif
76 ui5b b = (*((ui5b *)(a)));
77 ui4b b1 = b;
78 ui4b b2 = b >> 16;
79 ui4b c1 = ((b1 & 0x00FF) << 8) | ((b1 >> 8) & 0x00FF);
80 ui4b c2 = ((b2 & 0x00FF) << 8) | ((b2 >> 8) & 0x00FF);
81
82 return (((ui5r)c1) << 16) | ((ui5r)c2);
83 /*
84 better, though still doesn't use BSWAP
85 instruction with apple tools for intel.
86 */
87#else
88 return (((ui5r)*a) << 24) | (((ui5r)*(a + 1)) << 16)
89 | (((ui5r)*(a + 2)) << 8) | ((ui5r)*(a + 3));
90#endif
91}
92#endif
93
94#define do_put_mem_byte(a, v) ((*((ui3b *)(a))) = (v))
95
96#if BigEndianUnaligned
97#define do_put_mem_word(a, v) ((*((ui4b *)(a))) = (v))
98#else
99LOCALINLINEFUNC void do_put_mem_word(ui3p a, ui4r v)
100{
101#if LittleEndianUnaligned
102 ui4b b = ((v & 0x00FF) << 8) | ((v >> 8) & 0x00FF);
103
104 *(ui4b *)a = b;
105#else
106 *a = v >> 8;
107 *(a + 1) = v;
108#endif
109}
110#endif
111
112#if BigEndianUnaligned
113#define do_put_mem_long(a, v) ((*((ui5b *)(a))) = (v))
114#elif HaveMySwapUi5r && LittleEndianUnaligned
115#define do_put_mem_long(a, v) ((*((ui5b *)(a))) = MySwapUi5r(v))
116#else
117LOCALINLINEFUNC void do_put_mem_long(ui3p a, ui5r v)
118{
119#if LittleEndianUnaligned
120 ui4b b1 = v;
121 ui4b b2 = v >> 16;
122 ui4b c1 = ((b1 & 0x00FF) << 8) | ((b1 >> 8) & 0x00FF);
123 ui4b c2 = ((b2 & 0x00FF) << 8) | ((b2 >> 8) & 0x00FF);
124
125 *(ui5b *)a = (c1 << 16) | c2;
126#else
127 *a = v >> 24;
128 *(a + 1) = v >> 16;
129 *(a + 2) = v >> 8;
130 *(a + 3) = v;
131#endif
132}
133#endif