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 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
|
/* -*- mode: C++; tab-width: 4 -*- */
/* ================================================================================== */
/* Copyright (c) 1998-1999 3Com Corporation or its subsidiaries. All rights reserved. */
/* ================================================================================== */
#include "EmulatorCommon.h"
#include "RAM_ROM.h"
#include "Bank_DRAM.h" // DRAMBank::Initialize
#include "Bank_Dummy.h" // DummyBank::Initialize
#include "Bank_MC68328.h" // MC68328Bank::Initialize
//#include "Bank_MC68681.h" // MC68681Bank::Initialize
#include "Bank_MC68EZ328.h" // MC68EZ328Bank::Initialize
#include "Bank_PLD.h" // PLDBank::Initialize
#include "Bank_ROM.h" // ROMBank::Initialize
#include "Bank_SED1375.h" // SED1375Bank::Initialize
#include "Bank_SRAM.h" // SRAMBank::Initialize
#include "CPU_REG.h" // Emulator::HasFlash, EZMode
#include "MetaMemory.h" // MetaMemory::Initialize
#if !defined(NDEBUG) && !defined(__MACOS__)
#include "CPU_MT.h"
#endif
#if HAS_PROFILING
#include "Profiling.h" // profiling stuff
#endif
/*
Hitchhiker's Guide To Accessing Memory
When emulating CPU instructions, all memory access must be emulated
as well. In addition, the memory location that the emulated instruction
is accessing is not necessarily the same as the memory location in
the emulator's address space. That is, memory location 0x00001234 in
the emulated process's address space is not the same as memory location
0x00001234 in the emulator's address space. Instead, the emulated
0x00001234 is actually 0x00001234 bytes into some buffer that we've
allocate for the purpose of holding the emulated address space's
contents.
There are several ranges of Palm OS memory that we need to emulate:
- Low-memory RAM (for the dynamic heap)
- High-memory RAM (for the storage heap)
- ROM
- Dragonball registers
- Everything else
Each of these ranges (except for the last one) is managed by a set of
functions for reading from and writing to that memory and a chunk of
memory that we allocate as a "backing store" for that memory.
Thus, for each of these ranges, we need to quickly determine what set
of functions need to be called. The UAE-prescribed method for doing this
is to divide the entire 4GB address space into 64K banks, each 64K long.
Each 64K bank is managed by a set of functions. These functions
handle reading from and writing to that 64K bank, handling 1-byte, 2-byte,
and 4-byte accesses. They also manage mapping from the emulated addres
space to the physical space as viewed by the emulator, and validate
memory addresses.
Because there are 64K of these 64K banks, the functions that manage
each bank are stored in an array of 64K elements. When we need to invoke
a function for a particular bank, the upper word of the prospective
memory address is used as a "bank index" into this array. From that,
the right set of functions is found, and the desired function from that
set of functions is called.
This 64K array is very sparse. There are a one or two entries for
managing the dynamic heap (depending on whether the dynamic heap is
64K, 96K or 128K), 2 to 128 entries for the storage heap (depending on
whether the storage heap is 128K to 8Meg), 8 to 32 entries for the ROM
(again, depending on its size), and 1 for the Dragonball registers.
That leaves the remaining 64K - 12 entries to be managed by a set of
functions that do little but signal an address error if the memory they
manage is being accessed.
Pictorally, it looks like this:
Emulated 4G space: Memory function array Address Bank functions
0x00000000 +--------------+ +--------------------------------+
| 64K |<---| Ptr to fns that mng this range |------+
0x00010000 +--------------+ +--------------------------------+ |
| 64K |<---| Ptr to fns that mng this range |------+
0x00020000 +--------------+ +--------------------------------+ |
| 64K | +-----> DRAM::GetLong, DRAM::SetLong
\/\/\/\/\/\/\/\/ DRAM::GetWord, DRAM::SetWord
\/\/\/\/\/\/\/\/ DRAM::GetByte, DRAM::SetByte
| 64K | etc.
0x10000000 +--------------+ +--------------------------------+
| 64K |<---| Ptr to fns that mng this range |------+
0x10010000 +--------------+ +--------------------------------+ |
| 64K |<---| Ptr to fns that mng this range |------+
0x10020000 +--------------+ +--------------------------------+ |
| 64K | +-----> SRAM::GetLong, SRAM::SetLong
\/\/\/\/\/\/\/\/ SRAM::GetWord, SRAM::SetWord
\/\/\/\/\/\/\/\/ SRAM::GetByte, SRAM::SetByte
| 64K | etc.
0x10C00000 +--------------+ +--------------------------------+
| 64K |<---| Ptr to fns that mng this range |------+
0x10C10000 +--------------+ +--------------------------------+ |
| 64K |<---| Ptr to fns that mng this range |------+
0x10C20000 +--------------+ +--------------------------------+ |
| 64K | +-----> ROM::GetLong, ROM::SetLong
\/\/\/\/\/\/\/\/ ROM::GetWord, ROM::SetWord
\/\/\/\/\/\/\/\/ ROM::GetByte, ROM::SetByte
| 64K | etc.
0xFFFE0000 +--------------+ +--------------------------------+
| 64K |<---| Ptr to fns that mng this range |
0xFFFF0000 +--------------+ +--------------------------------+
| 64K |<---| Ptr to fns that mng this range |------+
0xFFFFFFFF +--------------+ +--------------------------------+ |
+-----> Regs::GetLong, Regs::SetLong
Regs::GetWord, Regs::SetWord
Regs::GetByte, Regs::SetByte
etc.
All of the remaining memory function array entries are initialized with
pointers to the Dummy::GetLong, Dummy::SetLong, etc., set of functions.
As an extension to this UAE model, we have added the facility for mapping
memory from the emulator's address space directly into the emulated address
space. Thus, if we have some data at memory location 0x01234567 (for
instance, some data from a .prc file that we're installing), we can make
that data also show up at memory location 0x01234567 within the emulated
address space. This mechanism makes it easy for us to "inject" data
into the emulated address space. It also makes it easier to call emulated
ROM functions as subroutines. Some ROM functions take as parameters
pointers to memory locations that are to receive values (for example,
pointers to local variables). For those functions, we just map the
emulator's stack into the emulated address space. After that's done,
we can pass pointers to stack-based variables with impunity.
Mapping from emulated addresses to "real" addresses (that is, the corresponding
memory locations within the buffers we've allocated to "stand in" for the
emulated memory) is performed via UAE-defined macros, described below.
Executive summary:
- use get_foo if you want the address checked for even/oddness.
- use fooget to get the stuff that jumps through the address banks
- use do_get_mem_foo to actually get the value using a physical address.
get_long, get_word, get_byte, put_long, put_word, put_byte
Inline functions that check for bus error (if necessary) and
then either call one of the following or handle the bus error.
longget_1, wordget_1, byteget_1, longput_1, wordput_1, byteput_1
If MD_HAVE_MEM_1_FUNCS is not defined, these are just macros
to the following functions. Otherwise, the machdep/memory.h
file is assumed to have defined them.
longget, wordget, byteget, longput, wordput, byteput
If NO_INLINE_MEMORY_ACCESS is not defined, these are macros
to "call_mem_get_func(get_mem_bank(addr).lget, addr)", etc.
Otherwise, they are out-of-line functions. machdep_memory.h
undefs this, so we get the inlined functions.
get_mem_bank
Gets the right addrbank object, with the help of the bankindex
macro.
bankindex
Returns a bank index for the given address.
call_mem_get_func
Merely calls the given function through the addrbank fn ptr.
check_addr
Macro called by get_long, etc., to check the address for a
bus error. Always returns true (OK) if NO_EXCEPTION_3 is
defined or CPU_LEVEL indicates 68020 or better. Otherwise
returns false (error) if low-bit of address is set. config.h
defines NO_EXCEPTION_3, so this stubs to "true".
do_get_mem_long, do_get_mem_word, do_get_mem_byte,
do_put_mem_long, do_put_mem_word, do_put_mem_byte
Very low-level memory access. They return the value at the
given physical location, byte-swapping if needed.
m68k_setpc
Given a virtual address, sets regs.pc and updates regs.pc_p
to point to hold the physical address.
m68k_getpc
Returns the current virtual address (which is not always
up-to-date in regs.pc, but _is_ up-to-date in regs.pc_p).
nextilong, nextiword, nextibyte
Get the value pointed to by the pc and then bump the pc.
*/
// Types.
#pragma mark Types
// Globals.
#pragma mark Globals
AddressBank* mem_banks[65536]; // (normally defined in memory.c)
MemAccessFlags gMemAccessFlags =
{
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
MASTER_RUNTIME_VALIDATE_SWITCH,
// User prevention flags.
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
false, // SRAM-get
true, // SRAM-set
false, // ROM-get
true, // ROM-set (HACK: We really want it to be true!)
MASTER_RUNTIME_PREVENT_SWITCH,
MASTER_RUNTIME_PREVENT_SWITCH,
// false, // fCheck_UserChunkGet
// false, // fCheck_UserChunkSet
// false, // fCheck_SysChunkGet
// false, // fCheck_SysChunkSet
// System prevention flags.
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH,
// false, // SRAM-get
// true, // SRAM-set
false, // ROM-get
true, // ROM-set (HACK: We really want it to be true!)
// MASTER_RUNTIME_PREVENT_SWITCH,
// MASTER_RUNTIME_PREVENT_SWITCH
};
MemAccessFlags kZeroMemAccessFlags;
#if PROFILE_MEMORY
/*
After 12 Million instructions executed...
kDRAMLongRead, // 2,797,111
kDRAMLongRead2, //
kDRAMWordRead, // 1,334,295
kDRAMByteRead, // 427,936
kDRAMLongWrite, // 1,960,933
kDRAMLongWrite2, //
kDRAMWordWrite, // 800,780
kDRAMByteWrite, // 213,029
kSRAMLongRead, // 4,167
kSRAMLongRead2, // 4,167
kSRAMWordRead, // 10,768
kSRAMByteRead, // 6,295 (jumped WAY up (5-fold) after playing with Address Book / 20 Million instructions)
kSRAMLongWrite, // 516,246 (stable after boot?)
kSRAMLongWrite2, //
kSRAMWordWrite, // 5,112
kSRAMByteWrite, // 2,183
kROMLongRead, // 10,156
kROMLongRead2, //
kROMWordRead, // 557,062
kROMByteRead, // 15,516
kROMLongWrite, // 0
kROMLongWrite2, //
kROMWordWrite, // 0
kROMByteWrite, // 0
kREGLongRead, // 16,638
kREGLongRead2, //
kREGWordRead, // 30,477
kREGByteRead, // 3,553
kREGLongWrite, // 9,472
kREGLongWrite2, //
kREGWordWrite, // 20,709
kREGByteWrite, // 12,656
After 32,439,154 instructions:
kDRAMLongRead, // 6,466,064
kDRAMWordRead, // 3,342,826
kDRAMByteRead, // 940,345
kDRAMLongWrite, // 4,136,635
kDRAMWordWrite, // 1,462,995
kDRAMByteWrite, // 509,189
kSRAMLongRead, // 24,355
kSRAMWordRead, // 32,190
kSRAMByteRead, // 75,917
kSRAMLongWrite, // 2,074,137 (8-Meg ROM)
kSRAMWordWrite, // 42,050
kSRAMByteWrite, // 11,292
kROMLongRead, // 25,806
kROMWordRead, // 1,302,897
kROMByteRead, // 63,590
kROMLongWrite, // 0
kROMWordWrite, // 0
kROMByteWrite, // 0
kREGLongRead, // 32,037
kREGWordRead, // 74,299
kREGByteRead, // 91,930
kREGLongWrite, // 20,358
kREGWordWrite, // 57,879
kREGByteWrite, // 22,592
*/
long gMemoryAccess[kLastEnum];
#endif
#pragma mark -
// ===========================================================================
// Memory
// ===========================================================================
// ---------------------------------------------------------------------------
// Memory::Initialize
// ---------------------------------------------------------------------------
// Initializes the RAM, ROM, and special memory areas of the emulator. Takes
// a stream handle to the ROM.
void Memory::Initialize ( StreamHandle& hROM,
RAMSizeType iRAMSize)
{
// Clear the memory banks.
memset (mem_banks, 0, sizeof (mem_banks));
// Initialize the valid memory banks.
DummyBank::Initialize ();
// Initialize the Hardware registers memory bank. Do this
// *before* initializing the other RAM banks so that we
// know how memory is laid out from the chip selects.
if (Emulator::EZMode ())
MC68EZ328Bank::Initialize ();
else
MC68328Bank::Initialize ();
// Initialize DRAMBank after initializing the SRAMBank. The order is
// important for DragonballEZ. On Dragonball devices, DRAM is
// at 0x00000000, and SRAM is at 0x10000000. But on EZ devices,
// both start at 0x00000000. By calling DRAMBank::Initialize
// second, we allow it to overwrite the AddressBank handlers
// for the part of memory where they overlap.
SRAMBank::Initialize (iRAMSize);
DRAMBank::Initialize ();
ROMBank::Initialize (hROM);
if (Emulator::HasFlash ())
FlashBank::Initialize ();
if (Emulator::HasPLD ())
PLDBank::Initialize();
// (Taken out because we don't have any ROMs that use the
// 68681 any more. The Debug 2.0 ROM used to, but we've now posted
// a version that doesn't.)
// MC68681Bank::Initialize ();
if (Emulator::HasSED())
SED1375Bank::Initialize();
MetaMemory::Initialize ();
Memory::ResetRAMBankHandlers ();
}
/***********************************************************************
*
* FUNCTION: Memory::Reset
*
* DESCRIPTION: Standard reset function. Sets the sub-system to a
* default state. This occurs not only on a Reset (as
* from the menu item), but also when the sub-system
* is first initialized (Reset is called after Initialize)
* as well as when the system is re-loaded from an
* insufficient session file.
*
* PARAMETERS: None.
*
* RETURNED: Nothing.
*
***********************************************************************/
void Memory::Reset (void)
{
DummyBank::Reset ();
if (Emulator::EZMode ())
MC68EZ328Bank::Reset ();
else
MC68328Bank::Reset ();
SRAMBank::Reset ();
DRAMBank::Reset ();
ROMBank::Reset ();
if (Emulator::HasFlash ())
FlashBank::Reset ();
if (Emulator::HasPLD ())
PLDBank::Reset();
// MC68681Bank::Reset ();
if (Emulator::HasSED())
SED1375Bank::Reset ();
MetaMemory::Reset ();
Memory::ResetRAMBankHandlers ();
}
/***********************************************************************
*
* FUNCTION: Memory::Save
*
* DESCRIPTION: Standard save function. Saves any sub-system state to
* the given session file.
*
* PARAMETERS: None.
*
* RETURNED: Nothing.
*
***********************************************************************/
void Memory::Save (SessionFile& f)
{
DummyBank::Save (f);
if (Emulator::EZMode ())
MC68EZ328Bank::Save (f);
else
MC68328Bank::Save (f);
SRAMBank::Save (f);
DRAMBank::Save (f);
ROMBank::Save (f);
if (Emulator::HasFlash ())
FlashBank::Save (f);
if (Emulator::HasPLD ())
PLDBank::Save(f);
// MC68681Bank::Save ();
if (Emulator::HasSED())
SED1375Bank::Save (f);
MetaMemory::Save (f);
}
/***********************************************************************
*
* FUNCTION: Memory::Load
*
* DESCRIPTION: Standard load function. Loads any sub-system state
* from the given session file.
*
* PARAMETERS: None.
*
* RETURNED: Nothing.
*
***********************************************************************/
void Memory::Load (SessionFile& f)
{
DummyBank::Load (f);
if (Emulator::EZMode ())
MC68EZ328Bank::Load (f);
else
MC68328Bank::Load (f);
SRAMBank::Load (f);
DRAMBank::Load (f);
ROMBank::Load (f);
if (Emulator::HasFlash ())
FlashBank::Load (f);
if (Emulator::HasPLD ())
PLDBank::Load(f);
// MC68681Bank::Save ();
if (Emulator::HasSED())
SED1375Bank::Load (f);
MetaMemory::Load (f);
Memory::ResetRAMBankHandlers ();
}
/***********************************************************************
*
* FUNCTION: Memory::Dispose
*
* DESCRIPTION: Standard dispose function. Completely release any
* resources acquired or allocated in Initialize and/or
* Load.
*
* PARAMETERS: None.
*
* RETURNED: Nothing.
*
***********************************************************************/
void Memory::Dispose (void)
{
DummyBank::Dispose ();
if (Emulator::EZMode ())
MC68EZ328Bank::Dispose ();
else
MC68328Bank::Dispose ();
SRAMBank::Dispose ();
DRAMBank::Dispose ();
ROMBank::Dispose ();
if (Emulator::HasFlash ())
FlashBank::Dispose ();
if (Emulator::HasPLD ())
PLDBank::Dispose();
// MC68681Bank::Dispose ();
if (Emulator::HasSED())
SED1375Bank::Dispose ();
MetaMemory::Dispose ();
}
// ---------------------------------------------------------------------------
// Memory::InitializeBanks
// ---------------------------------------------------------------------------
// Initializes the specified memory banks with the given data.
void Memory::InitializeBanks ( AddressBank& iBankInitializer,
uae_s32 iStartingBankIndex,
uae_s32 iNumberOfBanks)
{
for (uae_s32 aBankIndex = iStartingBankIndex;
aBankIndex < iStartingBankIndex + iNumberOfBanks;
aBankIndex++)
{
mem_banks[aBankIndex] = &iBankInitializer;
}
}
// ---------------------------------------------------------------------------
// Memory::ResetRAMBankHandlers
// ---------------------------------------------------------------------------
// Reset the RAM bank handlers in response to the chip selects changing.
void Memory::ResetRAMBankHandlers (void)
{
SRAMBank::SetBankHandlers ();
DRAMBank::SetBankHandlers ();
ROMBank::SetBankHandlers ();
if (Emulator::HasFlash ())
FlashBank::Initialize ();
if (Emulator::HasPLD ())
PLDBank::Initialize();
}
// ---------------------------------------------------------------------------
// Memory::MapPhysicalMemory
// ---------------------------------------------------------------------------
// Maps a range of physical memory to appear at the same location of the
// emulated Palm OS's virtual memory.
void Memory::MapPhysicalMemory (const void* addr, uae_u32 size)
{
DummyBank::MapPhysicalMemory (addr, size);
}
// ---------------------------------------------------------------------------
// Memory::UnmapPhysicalMemory
// ---------------------------------------------------------------------------
// Unmaps a range of physical memory from appearing at the same location of
// the emulated Palm OS's virtual memory.
void Memory::UnmapPhysicalMemory (const void* addr)
{
DummyBank::UnmapPhysicalMemory (addr);
}
// ---------------------------------------------------------------------------
// Memory::GetMappingInfo
// ---------------------------------------------------------------------------
void Memory::GetMappingInfo (const void* addr, void** start, uae_u32* len)
{
DummyBank::GetMappingInfo (addr, start, len);
}
// ---------------------------------------------------------------------------
// Memory::PreventedAccess
// ---------------------------------------------------------------------------
void Memory::PreventedAccess (uaecptr iAddress, long size, Bool forRead, Errors::EAccessType kind)
{
int button = Errors::ReportPreventedAccess (iAddress, size, forRead, kind);
// (Exception is thrown if button == kDebug or kReset).
Emulator::HandleDlgButton (button, m68k_getpc ());
}
#pragma mark -
// ===========================================================================
// CEnableFullAccess
// ===========================================================================
long CEnableFullAccess::fgAccessCount = 0;
// ---------------------------------------------------------------------------
// CEnableFullAccess::CEnableFullAccess
// ---------------------------------------------------------------------------
CEnableFullAccess::CEnableFullAccess (void) :
fOldMemAccessFlags (gMemAccessFlags)
#if HAS_PROFILING
, fOldProfilingCounted (gProfilingCounted)
#endif
{
gMemAccessFlags = kZeroMemAccessFlags;
#if HAS_PROFILING
gProfilingCounted = false;
#endif
#if !defined(NDEBUG) && !defined(__MACOS__)
// Normally, we only grant ourself access from within the CPU
// thread. If we're NOT in the CPU thread, then make sure it's
// stopped first. CEnableFullAccess is not thread safe, so we
// have to make sure only one thread can create on at a time.
if (omni_thread::self() != (omni_thread*) Platform::GetCPU())
{
assert (CPUStopper::fgInstantiated != 0);
}
#endif
++fgAccessCount;
}
// ---------------------------------------------------------------------------
// CEnableFullAccess::~CEnableFullAccess
// ---------------------------------------------------------------------------
CEnableFullAccess::~CEnableFullAccess (void)
{
gMemAccessFlags = fOldMemAccessFlags;
#if HAS_PROFILING
gProfilingCounted = fOldProfilingCounted;
#endif
--fgAccessCount;
}
// ---------------------------------------------------------------------------
// CEnableFullAccess::AccessOK
// ---------------------------------------------------------------------------
Bool CEnableFullAccess::AccessOK (void)
{
return fgAccessCount > 0;
}
|