1 // $Id: memory.h,v 1.7 2004/01/25 21:04:19 iain Exp $
2 // Functions and macros for accessing game memory.
9 // --------------------------------------------------------------
10 // Macros for reading and writing big-endian data.
12 #ifdef USE_BIG_ENDIAN_UNALIGNED
13 // We're on a big-endian platform which can handle unaligned
14 // accesses, such as the PowerPC. This means we can read and
15 // write multi-byte values in glulx memory directly, without
16 // having to pack and unpack each byte.
18 #define read32(ptr) (*((git_uint32*)(ptr)))
19 #define read16(ptr) (*((git_uint16*)(ptr)))
20 #define write32(ptr,v) (read32(ptr)=(git_uint32)(v))
21 #define write16(ptr,v) (read16(ptr)=(git_uint16)(v))
24 // We're on a little-endian platform, such as the x86, or a
25 // big-endian platform that doesn't like unaligned accesses,
26 // such as the 68K. This means we have to read and write the
27 // slow and tedious way.
30 ( (git_uint32)(((git_uint8 *)(ptr))[0] << 24) \
31 | (git_uint32)(((git_uint8 *)(ptr))[1] << 16) \
32 | (git_uint32)(((git_uint8 *)(ptr))[2] << 8) \
33 | (git_uint32)(((git_uint8 *)(ptr))[3]))
35 ( (git_uint16)(((git_uint8 *)(ptr))[0] << 8) \
36 | (git_uint16)(((git_uint8 *)(ptr))[1]))
38 #define write32(ptr, v) \
39 (((ptr)[0] = (git_uint8)(((git_uint32)(v)) >> 24)), \
40 ((ptr)[1] = (git_uint8)(((git_uint32)(v)) >> 16)), \
41 ((ptr)[2] = (git_uint8)(((git_uint32)(v)) >> 8)), \
42 ((ptr)[3] = (git_uint8)(((git_uint32)(v)))))
43 #define write16(ptr, v) \
44 (((ptr)[0] = (git_uint8)(((git_uint32)(v)) >> 8)), \
45 ((ptr)[1] = (git_uint8)(((git_uint32)(v)))))
47 #endif // USE_BIG_ENDIAN_UNALIGNED
49 // Accessing single bytes is easy on any platform.
51 #define read8(ptr) (*((git_uint8*)(ptr)))
52 #define write8(ptr, v) (read8(ptr)=(git_uint8)(v))
54 // --------------------------------------------------------------
57 extern git_uint32 gRamStart; // The start of RAM.
58 extern git_uint32 gExtStart; // The start of extended memory (initialised to zero).
59 extern git_uint32 gEndMem; // The current end of memory.
60 extern git_uint32 gOriginalEndMem; // The value of EndMem when the game was first loaded.
62 // This is the entire gamefile, as read-only memory. It contains
63 // both the ROM, which is constant for the entire run of the program,
64 // and the original RAM, which is useful for checking what's changed
65 // when saving to disk or remembering a position for UNDO.
66 extern const git_uint8 * gRom;
68 // This is the current contents of RAM. This pointer actually points
69 // to the start of ROM, so that you don't have to keep adding and
70 // subtracting gRamStart, but don't try to access ROM via this pointer.
71 extern git_uint8 * gRam;
73 // --------------------------------------------------------------
76 // Initialise game memory. This sets up all the global variables
77 // declared above. Note that it does *not* copy the given memory
78 // image: it must be valid for the lifetime of the program.
80 extern void initMemory (const git_uint8 * game, git_uint32 gameSize);
82 // Verifies the gamefile based on its checksum. 0 on success, 1 on failure.
84 extern int verifyMemory ();
86 // Resizes the game's memory. Returns 0 on success, 1 on failure.
88 extern int resizeMemory (git_uint32 newSize, int isInternal);
90 // Resets memory to its initial state. Call this when the game restarts.
92 extern void resetMemory (git_uint32 protectPos, git_uint32 protectSize);
94 // Disposes of all the data structures allocated in initMemory().
96 extern void shutdownMemory ();
98 // Utility functions -- these just pass an appropriate
99 // string to fatalError().
101 extern git_uint32 memReadError (git_uint32 address);
102 extern void memWriteError (git_uint32 address);
104 // Functions for reading and writing game memory.
106 GIT_INLINE git_uint32 memRead32 (git_uint32 address)
108 if (address <= gRamStart - 4)
109 return read32 (gRom + address);
110 else if (address <= gEndMem - 4)
111 return read32 (gRam + address);
113 return memReadError (address);
116 GIT_INLINE git_uint32 memRead16 (git_uint32 address)
118 if (address <= gRamStart - 4)
119 return read16 (gRom + address);
120 else if (address <= gEndMem - 2)
121 return read16 (gRam + address);
123 return memReadError (address);
126 GIT_INLINE git_uint32 memRead8 (git_uint32 address)
128 if (address <= gRamStart - 4)
129 return read8 (gRom + address);
130 else if (address < gEndMem)
131 return read8 (gRam + address);
133 return memReadError (address);
136 GIT_INLINE void memWrite32 (git_uint32 address, git_uint32 val)
138 if (address >= gRamStart && address <= (gEndMem - 4))
139 write32 (gRam + address, val);
141 memWriteError (address);
144 GIT_INLINE void memWrite16 (git_uint32 address, git_uint32 val)
146 if (address >= gRamStart && address <= (gEndMem - 2))
147 write16 (gRam + address, val);
149 memWriteError (address);
152 GIT_INLINE void memWrite8 (git_uint32 address, git_uint32 val)
154 if (address >= gRamStart && address < gEndMem)
155 write8 (gRam + address, val);
157 memWriteError (address);
160 #endif // GIT_MEMORY_H