/* ================================================================================== */
/* Copyright (c) 1998-1999 3Com Corporation or its subsidiaries. All rights reserved. */
/* ================================================================================== */

#ifndef _RAM_ROM_H_
#define _RAM_ROM_H_

#include "ErrorHandling.h"		// Errors::EAccessType

class FileReference;


// Types.

// This struct is used to control access to memory.  The first set of fields
// are booleans which, when set to true, turn on address validation for the
// various ranges of memory.  The second second set of fields are booleans
// which, when set to true, prevent access by user applications to the various
// ranges of memory.

struct MemAccessFlags
{
	Bool				fValidate_DummyGet;
	Bool				fValidate_DummySet;
	Bool				fValidate_RegisterGet;
	Bool				fValidate_RegisterSet;
	Bool				fValidate_DRAMGet;
	Bool				fValidate_DRAMSet;
	Bool				fValidate_SRAMGet;
	Bool				fValidate_SRAMSet;
	Bool				fValidate_ROMGet;
	Bool				fValidate_ROMSet;

//	Bool				fProtect_LowMemGet;
//	Bool				fProtect_LowMemSet;
//	Bool				fProtect_GlobalGet;
//	Bool				fProtect_GlobalSet;
//	Bool				fProtect_ScreenGet;
//	Bool				fProtect_ScreenSet;
	Bool				fProtect_SRAMGet;
	Bool				fProtect_SRAMSet;
	Bool				fProtect_ROMGet;
	Bool				fProtect_ROMSet;
	Bool				fProtect_RegisterGet;
	Bool				fProtect_RegisterSet;

//	Bool				fCheck_UserChunkGet;
//	Bool				fCheck_UserChunkSet;
//	Bool				fCheck_SysChunkGet;
//	Bool				fCheck_SysChunkSet;

//	Bool				fProtect_SysLowMemGet;
//	Bool				fProtect_SysLowMemSet;
//	Bool				fProtect_SysGlobalGet;
//	Bool				fProtect_SysGlobalSet;
//	Bool				fProtect_SysScreenGet;
//	Bool				fProtect_SysScreenSet;
//	Bool				fProtect_SysSRAMGet;
//	Bool				fProtect_SysSRAMSet;
	Bool				fProtect_SysROMGet;
	Bool				fProtect_SysROMSet;
//	Bool				fProtect_SysRegisterGet;
//	Bool				fProtect_SysRegisterSet;
};


// Globals.

extern MemAccessFlags	gMemAccessFlags;

#if PROFILE_MEMORY
enum
{
	kDRAMLongRead,	kDRAMLongRead2,		kDRAMWordRead,	kDRAMByteRead,
	kDRAMLongWrite,	kDRAMLongWrite2,	kDRAMWordWrite,	kDRAMByteWrite,
	kSRAMLongRead,	kSRAMLongRead2,		kSRAMWordRead,	kSRAMByteRead,
	kSRAMLongWrite,	kSRAMLongWrite2,	kSRAMWordWrite,	kSRAMByteWrite,
	kROMLongRead,	kROMLongRead2,		kROMWordRead,	kROMByteRead,
	kROMLongWrite,	kROMLongWrite2,		kROMWordWrite,	kROMByteWrite,
	kREGLongRead,	kREGLongRead2,		kREGWordRead,	kREGByteRead,
	kREGLongWrite,	kREGLongWrite2,		kREGWordWrite,	kREGByteWrite,

	
	kLastEnum
};
extern long				gMemoryAccess[];
#endif

// Function prototypes.

class Memory
{
	public:
		static void				Initialize			(const FileReference& iROMFile,
													 uae_s32 iRAMSize);
		static void				Reset				(void);
		static void				Save				(SessionFile&);
		static void				Load				(SessionFile&);
		static void				Dispose				(void);

		static void				InitializeBanks		(AddressBank& iBankInitializer,
													 uae_s32 iStartingBankIndex,
													 uae_s32 iNumberOfBanks);

		static void				MapPhysicalMemory	(const void*, uae_u32);
		static void				UnmapPhysicalMemory	(const void*);
		static void				GetMappingInfo		(const void*, void**, uae_u32*);

		static void				PreventedAccess		(uaecptr iAddress,
													 long size,
													 Bool forRead,
													 Errors::EAccessType kind);
};


// There are places within the emulator where we'd like to access low-memory
// and/or Dragonball registers.  If the PC happens to be in RAM, then
// the checks implied by the above booleans and switches will flag our
// access as an error.  Before making such accesses, create an instance
// of CEnableFullAccess to suspend and restore the checks.
//
// Since such accesses are typically "meta" accesses where the emulator is
// accessing memory outside the normal execution of an opcode, we also
// turn off the profiling variable that controls whether or not cycles
// spent accessing memory are counted.

class CEnableFullAccess
{
	public:
								CEnableFullAccess (void);
								~CEnableFullAccess (void);

		static Bool				AccessOK (void);

	private:
		MemAccessFlags			fOldMemAccessFlags;

#if HAS_PROFILING
		Bool					fOldProfilingCounted;
#endif

		static long				fgAccessCount;
};

#endif /* _RAM_ROM_H_ */

