1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
|
/* -*- mode: C++; tab-width: 4 -*- */
/* ================================================================================== */
/* Copyright (c) 1998-1999 3Com Corporation or its subsidiaries. All rights reserved. */
/* ================================================================================== */
#ifndef _METAMEMORY_H_
#define _METAMEMORY_H_
#include "PalmHeap.h" // PalmHeap
#include "ErrorHandling.h" // Errors::EAccessType
class MetaMemory
{
public:
static void Initialize (void);
static void Reset (void);
static void Save (SessionFile&);
static void Load (SessionFile&);
static void Dispose (void);
// Called to mark and unmark some areas of memory.
static void MarkTotalAccess (uaecptr begin, uaecptr end);
static void SetAccess (uaecptr begin, uaecptr end, uae_u8 bits);
static void MarkLowMemory (uaecptr begin, uaecptr end);
static void MarkSystemGlobals (uaecptr begin, uaecptr end);
static void MarkHeapHeader (uaecptr begin, uaecptr end);
static void MarkMPT (uaecptr begin, uaecptr end);
static void MarkChunkHeader (uaecptr begin, uaecptr end);
static void MarkChunkTrailer (uaecptr begin, uaecptr end);
static void MarkLowStack (uaecptr begin, uaecptr end);
static void MarkUnlockedChunk (uaecptr begin, uaecptr end);
static void MarkFreeChunk (uaecptr begin, uaecptr end);
static void MarkScreen (uaecptr begin, uaecptr end);
static void UnmarkScreen (uaecptr begin, uaecptr end);
static void MarkCPUBreak (uaecptr opcodeLocation);
static void UnmarkCPUBreak (uaecptr opcodeLocation);
// Called when memory needs to be marked as initialized or not.
#if FOR_LATER
static void MarkUninitialized (uaecptr begin, uaecptr end);
static void MoveUninitialized (uaecptr source, uaecptr dest, uae_u32 size);
static void MarkInitialized (uaecptr begin, uaecptr end);
static void MarkLongInitialized (uaecptr); // Inlined, defined below
static void MarkWordInitialized (uaecptr); // Inlined, defined below
static void MarkByteInitialized (uaecptr); // Inlined, defined below
#endif
// Called on Chunk-based operations.
static void MemChunkNew (VoidPtr, UInt attributes);
static void MemChunkFree (VoidPtr);
// Called on Pointer-based operations.
static void MemPtrNew (VoidPtr);
static void MemPtrResize (VoidPtr, UInt oldSize);
// Called on Handle-based operations.
static void MemHandleNew (VoidHand);
static void MemHandleResize (VoidHand, UInt oldSize);
static void MemHandleFree (VoidHand);
// Called when a chunk is locked or unlocked.
static void MemLocalIDToLockedPtr (VoidPtr);
static void MemHandleLock (VoidHand);
static void MemHandleUnlock (VoidHand);
static void MemHandleResetLock (VoidHand);
static void MemPtrResetLock (VoidPtr);
static void MemPtrUnlock (VoidPtr);
// Called to brute-force sync with the heap state. Called
// after things like MemHeapCompact, MemHeapInit, MemHeapScramble,
// etc. Implicitly called after above functions like MemFooNew.
static void SyncHeap (const PalmHeap::HeapInfo& heapInfo);
static void SyncDynamicHeap (void);
static void SyncAllHeaps (void);
static void AssertSynced (void);
// Can a normal application access this memory location?
// Forbidden locations are low-memory, system globals, screen
// memory, memory manager structures, unlocked handles, and
// uninitialized memory.
static Bool CanAppGetLong (uae_u8*); // Inlined, defined below
static Bool CanAppGetWord (uae_u8*); // Inlined, defined below
static Bool CanAppGetByte (uae_u8*); // Inlined, defined below
static Bool CanAppSetLong (uae_u8*); // Inlined, defined below
static Bool CanAppSetWord (uae_u8*); // Inlined, defined below
static Bool CanAppSetByte (uae_u8*); // Inlined, defined below
// Can the non-Memory Manager parts of the system access this memory location?
// Forbidden locations are low-memory, memory manager structures,
// unlocked handles, and uninitialized memory.
static Bool CanSystemGetLong (uae_u8*); // Inlined, defined below
static Bool CanSystemGetWord (uae_u8*); // Inlined, defined below
static Bool CanSystemGetByte (uae_u8*); // Inlined, defined below
static Bool CanSystemSetLong (uae_u8*); // Inlined, defined below
static Bool CanSystemSetWord (uae_u8*); // Inlined, defined below
static Bool CanSystemSetByte (uae_u8*); // Inlined, defined below
// Can the Memory Managers parts of the system access this memory location?
// Forbidden locations are low-memory and uninitialized memory.
static Bool CanMemMgrGetLong (uae_u8*); // Inlined, defined below
static Bool CanMemMgrGetWord (uae_u8*); // Inlined, defined below
static Bool CanMemMgrGetByte (uae_u8*); // Inlined, defined below
static Bool CanMemMgrSetLong (uae_u8*); // Inlined, defined below
static Bool CanMemMgrSetWord (uae_u8*); // Inlined, defined below
static Bool CanMemMgrSetByte (uae_u8*); // Inlined, defined below
static Errors::EAccessType
GetWhatHappened (uaecptr iAddress, long size, Bool forRead);
static Errors::EAccessType
AllowForBugs (uaecptr iAddress, long size, Bool forRead, Errors::EAccessType);
// Accessors for getting ranges of memory.
static uaecptr GetLowMemoryBegin (void);
static uaecptr GetLowMemoryEnd (void);
static uaecptr GetSysGlobalsBegin (void);
static uaecptr GetSysGlobalsEnd (void);
static uaecptr GetScreenBegin (void);
static uaecptr GetScreenEnd (void);
static uaecptr GetHeapHdrBegin (UInt heapID);
static uaecptr GetHeapHdrEnd (UInt heapID);
// Predicates to help determine what kind of access error
// just occurred.
static Bool IsLowMemory (uaecptr testAddress, uae_u32 size);
static Bool IsSystemGlobal (uaecptr testAddress, uae_u32 size);
static Bool IsScreenBuffer (uaecptr testAddress, uae_u32 size);
static Bool IsMemMgrData (uaecptr testAddress, uae_u32 size);
static Bool IsUnlockedChunk (uaecptr testAddress, uae_u32 size);
static Bool IsFreeChunk (uaecptr testAddress, uae_u32 size);
static Bool IsUninitialized (uaecptr testAddress, uae_u32 size);
static Bool IsStack (uaecptr testAddress, uae_u32 size);
static Bool IsLowStack (uaecptr testAddress, uae_u32 size);
static Bool IsAllocatedChunk (uaecptr testAddress, uae_u32 size);
static Bool IsScreenBuffer8 (uae_u8* metaAddress); // Inlined, defined below
static Bool IsScreenBuffer16 (uae_u8* metaAddress); // Inlined, defined below
static Bool IsScreenBuffer32 (uae_u8* metaAddress); // Inlined, defined below
static Bool IsScreenBuffer (uae_u8* metaAddress, uae_u32 size);
static Bool IsCPUBreak (uaecptr opcodeLocation);
static Bool IsCPUBreak (uae_u8* metaLocation);
private:
struct ChunkCheck
{
uaecptr testAddress;
uae_u32 size;
Bool result;
};
struct WhatHappenedData
{
Errors::EAccessType result;
uaecptr address;
uae_u32 size;
Bool forRead;
};
static void MarkRange (uaecptr start, uaecptr end, uae_u8 v);
static void UnmarkRange (uaecptr start, uaecptr end, uae_u8 v);
static void MarkUnmarkRange (uaecptr start, uaecptr end,
uae_u8 andValue, uae_u8 orValue);
static DWord GetChunkSize (VoidPtr p);
static DWord GetChunkLockCount (VoidPtr p);
static PalmHeap::EWalkerProcResult
SyncOneHeap (const PalmHeap::HeapInfo& heapInfo,
void* userData);
static PalmHeap::EWalkerProcResult
SyncOneChunk (const PalmHeap::HeapInfo& heapInfo,
const PalmHeap::ChunkInfo& chunkInfo,
void* userData);
static PalmHeap::EWalkerProcResult
AssertChunkSynced (const PalmHeap::HeapInfo& heapInfo,
const PalmHeap::ChunkInfo& chunkInfo,
void* userData);
static PalmHeap::EWalkerProcResult
WhatHappenedHeapCallback(const PalmHeap::HeapInfo& heapInfo,
void* userData);
static PalmHeap::EWalkerProcResult
WhatHappenedChunkCallback(const PalmHeap::HeapInfo& heapInfo,
const PalmHeap::ChunkInfo& chunkInfo,
void* userData);
static PalmHeap::EWalkerProcResult
CheckForChunkHeader (const PalmHeap::HeapInfo& heapInfo,
const PalmHeap::ChunkInfo& chunkInfo,
void* userData);
static PalmHeap::EWalkerProcResult
CheckForUnlockedChunk (const PalmHeap::HeapInfo& heapInfo,
const PalmHeap::ChunkInfo& chunkInfo,
void* userData);
static PalmHeap::EWalkerProcResult
CheckForFreeChunk (const PalmHeap::HeapInfo& heapInfo,
const PalmHeap::ChunkInfo& chunkInfo,
void* userData);
static PalmHeap::EWalkerProcResult
CheckForAllocatedChunk (const PalmHeap::HeapInfo& heapInfo,
const PalmHeap::ChunkInfo& chunkInfo,
void* userData);
static Bool ValidChunk (VoidPtr);
static Bool ValidHandle (VoidHand);
static Bool memfilled (const uae_u8* ptr, uae_u8 value, long len);
/*
Memory is laid out as follows:
+-------------------+
| Low Memory | Off Limits to everyone except IRQ handlers, SysSleep, and SysDoze
+-------------------+
| |
| System Globals | Off Limits to applications
| |
+-------------------+
| Dynamic Heap |
|+-----------------+|
|| Heap Header || Off Limits to applications and non-MemMgr system
|+-----------------+|
|| Chunks || Off Limits to apps and non-MemMgr system if unlocked
|+-----------------+|
|| Free chunk || Off Limits to applications and non-MemMgr system
|+-----------------+|
|| Chunks ||
|+-----------------+|
|| Chunks ||
|+-----------------+|
|| Chunks ||
|+-----------------+|
|| Stack Chunk || Off Limits to everyone if below A7
|+-----------------+|
|| Screen Chunk || Off Limits to applications
|+-----------------+|
+-------------------+
Any memory location can be marked as "uninitialized", which means that
it can be written to but not read from. An exception to this would be
the parts of the memory manager that moves around blocks (which may
contain uninitialized sections).
*/
enum
{
kNoAppAccess = 0x01,
kNoSystemAccess = 0x02,
kNoMemMgrAccess = 0x04,
#if FOR_LATER
kUninitialized = 0x10, // Bytes have not been written to.
#endif
kScreenBuffer = 0x20, // Screen buffer; update host screen if these bytes are changed.
kStopCPU = 0x40, // Halt CPU emulation and check to see why (stored on even bytes).
kPatchResource = 0x80, // Bytes belong to a system update resource (stored on even bytes).
kCodeCoverage = 0x80, // Bytes have been executed during code coverage test (stored on odd bytes).
kLowMemoryBits = kNoAppAccess | kNoSystemAccess | kNoMemMgrAccess,
kGlobalsBits = kNoAppAccess,
kMPTBits = kNoAppAccess,
kMemStructBits = kNoAppAccess | kNoSystemAccess,
kLowStackBits = kNoAppAccess | kNoSystemAccess | kNoMemMgrAccess,
kFreeChunkBits = kNoAppAccess | kNoSystemAccess, //kInaccessibleChunk,
kUnlockedChunkBits = kNoAppAccess | kNoSystemAccess, //kInaccessibleChunk,
kScreenBits = kNoAppAccess | kScreenBuffer,
kAccessBitMask = kNoAppAccess | kNoSystemAccess | kNoMemMgrAccess,
kFreeAccessBits = 0
};
};
// Macros to take a byte of bits and produce an
// 8-bit, 16-bit, or 32-bit version of it.
#define META_BITS_32(bits) \
(((uae_u32) (bits)) << 24) | \
(((uae_u32) (bits)) << 16) | \
(((uae_u32) (bits)) << 8) | \
(((uae_u32) (bits)))
#define META_BITS_16(bits) \
(((uae_u16) (bits)) << 8) | \
(((uae_u16) (bits)))
#define META_BITS_8(bits) \
(((uae_u8) (bits)))
// Macros to fetch the appropriate 8-bit, 16-bit, or
// 32-bit value from meta-memory.
//
// Fetch the values with byte operations in order to
// support CPUs that don't allow, say, 16-bit fetches
// on odd boundaries or 32-bit fetches on odd 16-bit
// boundaries.
#define META_VALUE_32(p) \
((((uae_u32)((uae_u8*) p)[0]) << 24) | \
(((uae_u32)((uae_u8*) p)[1]) << 16) | \
(((uae_u32)((uae_u8*) p)[2]) << 8) | \
(((uae_u32)((uae_u8*) p)[3])))
#define META_VALUE_16(p) \
((((uae_u16)((uae_u8*) p)[0]) << 8) | \
(((uae_u16)((uae_u8*) p)[1])))
#define META_VALUE_8(p) \
(*(uae_u8*) p)
// Macros to define CanAppGetLong, CanAppSetLong,
// CanSystemGetLong, CanSystemSetLong, etc.
#define DEFINE_FUNCTIONS(kind, bits) \
\
inline Bool MetaMemory::Can##kind##Long (uae_u8* metaAddress) \
{ \
const uae_u32 kMask = META_BITS_32 (bits); \
\
return (META_VALUE_32 (metaAddress) & kMask) == 0; \
} \
\
inline Bool MetaMemory::Can##kind##Word (uae_u8* metaAddress) \
{ \
const uae_u16 kMask = META_BITS_16 (bits); \
\
return (META_VALUE_16 (metaAddress) & kMask) == 0; \
} \
\
inline Bool MetaMemory::Can##kind##Byte (uae_u8* metaAddress) \
{ \
const uae_u8 kMask = META_BITS_8 (bits); \
\
return (META_VALUE_8 (metaAddress) & kMask) == 0; \
}
#if FOR_LATER
DEFINE_FUNCTIONS(AppGet, kNoAppAccess | kUninitialized)
DEFINE_FUNCTIONS(AppSet, kNoAppAccess)
DEFINE_FUNCTIONS(SystemGet, kNoSystemAccess | kUninitialized)
DEFINE_FUNCTIONS(SystemSet, kNoSystemAccess)
DEFINE_FUNCTIONS(MemMgrGet, kNoMemMgrAccess | kUninitialized)
DEFINE_FUNCTIONS(MemMgrSet, kNoMemMgrAccess)
#else
DEFINE_FUNCTIONS(AppGet, kNoAppAccess)
DEFINE_FUNCTIONS(AppSet, kNoAppAccess)
DEFINE_FUNCTIONS(SystemGet, kNoSystemAccess)
DEFINE_FUNCTIONS(SystemSet, kNoSystemAccess)
DEFINE_FUNCTIONS(MemMgrGet, kNoMemMgrAccess)
DEFINE_FUNCTIONS(MemMgrSet, kNoMemMgrAccess)
#endif
#if FOR_LATER
inline void MetaMemory::MarkLongInitialized (uaecptr p)
{
const uae_u32 kMask = META_BITS_32 (kUninitialized);
META_VALUE_32 (p) &= ~kMask;
}
#endif
#if FOR_LATER
inline void MetaMemory::MarkWordInitialized (uaecptr p)
{
const uae_u16 kMask = META_BITS_16 (kUninitialized);
META_VALUE_16 (p) &= ~kMask;
}
#endif
#if FOR_LATER
inline void MetaMemory::MarkByteInitialized (uaecptr p)
{
const uae_u8 kMask = META_BITS_8 (kUninitialized);
META_VALUE_8 (p) &= ~kMask;
}
#endif
inline Bool MetaMemory::IsScreenBuffer (uae_u8* metaAddress, uae_u32 size)
{
if (size == 1)
{
const uae_u8 kMask = META_BITS_8 (kScreenBuffer);
return (META_VALUE_8 (metaAddress) & kMask) != 0;
}
else if (size == 2)
{
const uae_u16 kMask = META_BITS_16 (kScreenBuffer);
return (META_VALUE_16 (metaAddress) & kMask) != 0;
}
else if (size == 4)
{
const uae_u32 kMask = META_BITS_32 (kScreenBuffer);
return (META_VALUE_32 (metaAddress) & kMask) != 0;
}
const uae_u8 kMask = META_BITS_8 (kScreenBuffer);
for (uae_u32 ii = 0; ii < size; ++ii)
{
if (((*(uae_u8*) (metaAddress + ii)) & kMask) != 0)
{
return true;
}
}
return false;
}
inline Bool MetaMemory::IsScreenBuffer8 (uae_u8* metaAddress)
{
const uae_u8 kMask = META_BITS_8 (kScreenBuffer);
return (META_VALUE_8 (metaAddress) & kMask) != 0;
}
inline Bool MetaMemory::IsScreenBuffer16 (uae_u8* metaAddress)
{
const uae_u16 kMask = META_BITS_16 (kScreenBuffer);
return (META_VALUE_16 (metaAddress) & kMask) != 0;
}
inline Bool MetaMemory::IsScreenBuffer32 (uae_u8* metaAddress)
{
const uae_u32 kMask = META_BITS_32 (kScreenBuffer);
return (META_VALUE_32 (metaAddress) & kMask) != 0;
}
inline Bool MetaMemory::IsCPUBreak (uaecptr opcodeLocation)
{
assert ((opcodeLocation & 1) == 0);
return IsCPUBreak (get_meta_address (opcodeLocation));
}
inline Bool MetaMemory::IsCPUBreak (uae_u8* metaLocation)
{
return ((*metaLocation) & kStopCPU) != 0;
}
#define META_CHECK(metaAddress, address, op, size, forRead) \
if (ROMBank::IsPCInRAM ()) \
{ \
if (!MetaMemory::CanApp##op (metaAddress)) \
{ \
ProbableCause (address, sizeof (size), forRead); \
} \
} \
else if (Patches::IsPCInMemMgr ()) \
{ \
if (!MetaMemory::CanMemMgr##op (metaAddress)) \
{ \
ProbableCause (address, sizeof (size), forRead); \
} \
} \
else \
{ \
if (!MetaMemory::CanSystem##op (metaAddress)) \
{ \
ProbableCause (address, sizeof (size), forRead); \
} \
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkTotalAccess
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkTotalAccess (uaecptr begin, uaecptr end)
{
UnmarkRange (begin, end, kAccessBitMask);
}
// ---------------------------------------------------------------------------
// MetaMemory::SetAccess
// ---------------------------------------------------------------------------
inline void MetaMemory::SetAccess (uaecptr begin, uaecptr end, uae_u8 bits)
{
MarkUnmarkRange (begin, end, ~kAccessBitMask, bits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkLowMemory
// ---------------------------------------------------------------------------
// Mark the "low memory" range of memory (the first 256 bytes of
// memory that hold exception vectors).
inline void MetaMemory::MarkLowMemory (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kLowMemoryBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkSystemGlobals
// ---------------------------------------------------------------------------
// Mark the "system globals" range of memory. This range holds the
// global variables used by the Palm OS, as well as the jump table.
inline void MetaMemory::MarkSystemGlobals (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kGlobalsBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkHeapHeader
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkHeapHeader (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kMemStructBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkMPT
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkMPT (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kMPTBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkChunkHeader
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkChunkHeader (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kMemStructBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkChunkTrailer
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkChunkTrailer (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kMemStructBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkLowStack
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkLowStack (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kLowStackBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkUnlockedChunk
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkUnlockedChunk (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kUnlockedChunkBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkFreeChunk
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkFreeChunk (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kFreeChunkBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkScreen
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkScreen (uaecptr begin, uaecptr end)
{
SetAccess (begin, end, kScreenBits);
}
// ---------------------------------------------------------------------------
// MetaMemory::UnmarkScreen
// ---------------------------------------------------------------------------
inline void MetaMemory::UnmarkScreen (uaecptr begin, uaecptr end)
{
MarkTotalAccess (begin, end);
UnmarkRange (begin, end, kScreenBuffer);
}
// ---------------------------------------------------------------------------
// MetaMemory::MarkCPUBreak
// ---------------------------------------------------------------------------
inline void MetaMemory::MarkCPUBreak (uaecptr opcodeLocation)
{
assert ((opcodeLocation & 1) == 0);
uae_u8* ptr = get_meta_address (opcodeLocation);
*ptr |= kStopCPU;
}
// ---------------------------------------------------------------------------
// MetaMemory::UnmarkCPUBreak
// ---------------------------------------------------------------------------
inline void MetaMemory::UnmarkCPUBreak (uaecptr opcodeLocation)
{
assert ((opcodeLocation & 1) == 0);
uae_u8* ptr = get_meta_address (opcodeLocation);
*ptr &= ~kStopCPU;
}
#endif /* _METAMEMORY_H_ */
|