X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=interpreters%2Fgit%2Fmemory.h;fp=interpreters%2Fgit%2Fmemory.h;h=3cb39168f79b3bdf5502252087a631ec53fc891e;hb=147a8cbf17f2b3379277bf7d37cda9866510f16c;hp=0000000000000000000000000000000000000000;hpb=7de488aa6a1709a4d5c59b5ff59862105c1748c5;p=rodin%2Fchimara.git diff --git a/interpreters/git/memory.h b/interpreters/git/memory.h new file mode 100644 index 0000000..3cb3916 --- /dev/null +++ b/interpreters/git/memory.h @@ -0,0 +1,160 @@ +// $Id: memory.h,v 1.7 2004/01/25 21:04:19 iain Exp $ +// Functions and macros for accessing game memory. + +#ifndef GIT_MEMORY_H +#define GIT_MEMORY_H + +#include "config.h" + +// -------------------------------------------------------------- +// Macros for reading and writing big-endian data. + +#ifdef USE_BIG_ENDIAN_UNALIGNED +// We're on a big-endian platform which can handle unaligned +// accesses, such as the PowerPC. This means we can read and +// write multi-byte values in glulx memory directly, without +// having to pack and unpack each byte. + +#define read32(ptr) (*((git_uint32*)(ptr))) +#define read16(ptr) (*((git_uint16*)(ptr))) +#define write32(ptr,v) (read32(ptr)=(git_uint32)(v)) +#define write16(ptr,v) (read16(ptr)=(git_uint16)(v)) + +#else +// We're on a little-endian platform, such as the x86, or a +// big-endian platform that doesn't like unaligned accesses, +// such as the 68K. This means we have to read and write the +// slow and tedious way. + +#define read32(ptr) \ + ( (git_uint32)(((git_uint8 *)(ptr))[0] << 24) \ + | (git_uint32)(((git_uint8 *)(ptr))[1] << 16) \ + | (git_uint32)(((git_uint8 *)(ptr))[2] << 8) \ + | (git_uint32)(((git_uint8 *)(ptr))[3])) +#define read16(ptr) \ + ( (git_uint16)(((git_uint8 *)(ptr))[0] << 8) \ + | (git_uint16)(((git_uint8 *)(ptr))[1])) + +#define write32(ptr, v) \ + (((ptr)[0] = (git_uint8)(((git_uint32)(v)) >> 24)), \ + ((ptr)[1] = (git_uint8)(((git_uint32)(v)) >> 16)), \ + ((ptr)[2] = (git_uint8)(((git_uint32)(v)) >> 8)), \ + ((ptr)[3] = (git_uint8)(((git_uint32)(v))))) +#define write16(ptr, v) \ + (((ptr)[0] = (git_uint8)(((git_uint32)(v)) >> 8)), \ + ((ptr)[1] = (git_uint8)(((git_uint32)(v))))) + +#endif // USE_BIG_ENDIAN_UNALIGNED + +// Accessing single bytes is easy on any platform. + +#define read8(ptr) (*((git_uint8*)(ptr))) +#define write8(ptr, v) (read8(ptr)=(git_uint8)(v)) + +// -------------------------------------------------------------- +// Globals + +extern git_uint32 gRamStart; // The start of RAM. +extern git_uint32 gExtStart; // The start of extended memory (initialised to zero). +extern git_uint32 gEndMem; // The current end of memory. +extern git_uint32 gOriginalEndMem; // The value of EndMem when the game was first loaded. + +// This is the entire gamefile, as read-only memory. It contains +// both the ROM, which is constant for the entire run of the program, +// and the original RAM, which is useful for checking what's changed +// when saving to disk or remembering a position for UNDO. +extern const git_uint8 * gRom; + +// This is the current contents of RAM. This pointer actually points +// to the start of ROM, so that you don't have to keep adding and +// subtracting gRamStart, but don't try to access ROM via this pointer. +extern git_uint8 * gRam; + +// -------------------------------------------------------------- +// Functions + +// Initialise game memory. This sets up all the global variables +// declared above. Note that it does *not* copy the given memory +// image: it must be valid for the lifetime of the program. + +extern void initMemory (const git_uint8 * game, git_uint32 gameSize); + +// Verifies the gamefile based on its checksum. 0 on success, 1 on failure. + +extern int verifyMemory (); + +// Resizes the game's memory. Returns 0 on success, 1 on failure. + +extern int resizeMemory (git_uint32 newSize, int isInternal); + +// Resets memory to its initial state. Call this when the game restarts. + +extern void resetMemory (git_uint32 protectPos, git_uint32 protectSize); + +// Disposes of all the data structures allocated in initMemory(). + +extern void shutdownMemory (); + +// Utility functions -- these just pass an appropriate +// string to fatalError(). + +extern git_uint32 memReadError (git_uint32 address); +extern void memWriteError (git_uint32 address); + +// Functions for reading and writing game memory. + +GIT_INLINE git_uint32 memRead32 (git_uint32 address) +{ + if (address <= gRamStart - 4) + return read32 (gRom + address); + else if (address <= gEndMem - 4) + return read32 (gRam + address); + else + return memReadError (address); +} + +GIT_INLINE git_uint32 memRead16 (git_uint32 address) +{ + if (address <= gRamStart - 4) + return read16 (gRom + address); + else if (address <= gEndMem - 2) + return read16 (gRam + address); + else + return memReadError (address); +} + +GIT_INLINE git_uint32 memRead8 (git_uint32 address) +{ + if (address <= gRamStart - 4) + return read8 (gRom + address); + else if (address < gEndMem) + return read8 (gRam + address); + else + return memReadError (address); +} + +GIT_INLINE void memWrite32 (git_uint32 address, git_uint32 val) +{ + if (address >= gRamStart && address <= (gEndMem - 4)) + write32 (gRam + address, val); + else + memWriteError (address); +} + +GIT_INLINE void memWrite16 (git_uint32 address, git_uint32 val) +{ + if (address >= gRamStart && address <= (gEndMem - 2)) + write16 (gRam + address, val); + else + memWriteError (address); +} + +GIT_INLINE void memWrite8 (git_uint32 address, git_uint32 val) +{ + if (address >= gRamStart && address < gEndMem) + write8 (gRam + address, val); + else + memWriteError (address); +} + +#endif // GIT_MEMORY_H