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
|
/******************************************************************************
******************************************************************************
*** From <emulator>/SrcShared/Palm/Platform/Core/System/IncsPrv/MemoryPrv.h
******************************************************************************
******************************************************************************//******************************************************************************
*
* Copyright (c) 1994-1999 Palm Computing, Inc. or its subsidiaries.
* All rights reserved.
*
* File: MemoryPrv.h
*
* Description:
* Private includes for Memory Manager.
*
* History:
* 11/11/96 RM Re-written to allow heaps > 64K in size.
* 10/26/99 kwk Added memRomStoreNum & memRamStoreNum defines.
*
*****************************************************************************/
//#ifdef NON_PORTABLE
#if 0
// SystemPrv.h must be included before this header file. SystemPrv.h will
// then in turn include this header.
#ifndef __SYSTEMPRV_H__
#include "SystemPrv.h"
#endif
#endif
#ifndef __MEMORYPRV_H__
#define __MEMORYPRV_H__
//#include "PalmOptErrorCheckLevel.h"
/************************************************************
* Private Flags accepted as parameter for MemNewChunk.
*************************************************************/
#define memNewChunkFlagAllowLarge 0x1000 // allow >64K allocations
/************************************************************
* Store numbers for MemStoreInfo.
*************************************************************/
#define memRomStoreNum 0
#define memRamStoreNum 1
/********************************************************************
* Structure of a version 2 Master Pointer Table chunk.
* The first master pointer chunk is always immediately following the
* heap header. As more movable chunks are created, new master
* pointer chunks are allocated dynamically and linked together through
* the nextTblOffset field and prevTblOffset field.
********************************************************************/
typedef struct {
UInt16 numEntries; // number of master pointer entries
UInt32 nextTblOffset; // offset from start of heap to next table
//void * mstrP[numEntries]; // array of pointers to movable chunks
} MemMstrPtrTableType;
typedef MemMstrPtrTableType* MemMstrPtrTablePtr;
/********************************************************************
* Structure of a version 1 Master Pointer Table chunk.
* This is included for use by the Palm Debugger so that it can do
* heap dumps of devices that use the version 1 Memory Manager.
********************************************************************/
typedef struct {
UInt16 numEntries; // number of master pointer entries
UInt16 nextTblOffset; // offset from start of heap to next table
//void * mstrP[numEntries]; // array of pointers to movable chunks
} Mem1MstrPtrTableType;
typedef Mem1MstrPtrTableType* Mem1MstrPtrTablePtr;
/********************************************************************
* Structure of a version 2 Memory Manager Chunk Header.
********************************************************************/
#if CPU_ENDIAN == CPU_ENDIAN_BIG
typedef struct {
UInt32 free :1; // set if free chunk
UInt32 moved :1; // used by MemHeapScramble
UInt32 unused2 :1; // unused
UInt32 unused3 :1; // unused
UInt32 sizeAdj :4; // size adjustment
UInt32 size :24; // actual size of chunk
UInt32 lockCount :4; // lock count
UInt32 owner :4; // owner ID
Int32 hOffset :24; // signed MemHandle offset/2
// used in free chunks to point to next free chunk
} MemChunkHeaderType;
#else
// Since this is an internal structure, I rearranged the fields.
// There were two reasons: the size and hOffset fields are accessed
// more efficiently (no shifting needed) and the flags macros still
// return the flags as defined by the API (memChunkFlagsXXXX), without
// requiring a lot of bit manipulation.
// But, the size field needs to be in the first DWord because the
// MemHeapTerminatorType is assumed to be in the same position as size.
typedef struct {
UInt32 size :24; // actual size of chunk
UInt32 sizeAdj :4; // size adjustment
UInt32 unused3 :1; // unused
UInt32 unused2 :1; // unused
UInt32 moved :1; // used by MemHeapScramble
UInt32 free :1; // set if free chunk
Int32 hOffset :24; // signed MemHandle offset/2
// used in free chunks to point to next free chunk
UInt32 owner :4; // owner ID
UInt32 lockCount :4; // lock count
} MemChunkHeaderType;
#endif
typedef MemChunkHeaderType * MemChunkHeaderPtr;
// The MemHeapTerminatorType is stored at the end of every heap and
// is pointed to by the last real chunk in the heap
typedef UInt32 MemHeapTerminatorType;
// This macro is a quicker way of clearing a chunk header than
// MemSet...
#define memClearChunkHeader(p) { *((UInt32 *)p) = 0; *(((UInt32 *)p)+1) = 0;}
// This macro is used to initialize a freeChunk header
#define memInitFreeChunkHeader(p, size, hOffset) \
{ *((UInt32*)p) = (0x80000000 | (size)); *(((UInt32*)p)+1) = (hOffset); }
// This macro returns the data portion of a chunk given a pointer to the header
#define memChunkData(chunkP) (void *)(((MemChunkHeaderPtr)(chunkP)) + 1)
// This macro returns the memChunkHeader given a pointer to the start of the data
#define memChunkHeader(dataP) (((MemChunkHeaderPtr)(dataP)) - 1)
#if CPU_ENDIAN == CPU_ENDIAN_BIG
// This macro is used to grab all the flags at once and place them into
// a byte
#define memChunkFlags(p) (*((UInt8 *)p) & 0xF0)
// This macro is used to clear all the flags at once
#define memChunkFlagsClear(p) ((*((UInt8 *)p)) &= 0x0F)
#else
// This macro is used to grab all the flags at once and place them into
// a byte
#define memChunkFlags(p) (*(((UInt8 *)p)+3) & 0xF0)
// This macro is used to clear all the flags at once
#define memChunkFlagsClear(p) (*(((UInt8 *)p)+3) &= 0x0F)
#endif
// When flags are returned by the API (by MemPtrFlags, etc.)
#define memChunkFlagFree 0x80 // free bit
#define memChunkFlagUnused1 0x40 // unused
#define memChunkFlagUnused2 0x20 // unused
#define memChunkFlagUnused3 0x10 // unused
// A lockcount of memPtrLockCount means a permanently unmovable chunk
#define memPtrLockCount 15
// A ownerID of 15 is used for master pointer chunks
#define memOwnerMasterPtrTbl 15
// This equate returns the name of the ChunkHeaderType. This was created
// so that we can change the name of the CHunkHeaderType (as we did for V2 of
// the Memory Manager) and souce code won't know the difference
#define memChunkHeaderTypeName MemChunkHeaderType
/********************************************************************
* Structure of a version 1 Memory Manager Chunk Header.
* This is included for use by the Palm Debugger so that it can do
* heap dumps of devices that use the version 1 Memory Manager.
********************************************************************/
typedef struct {
UInt16 size; // size of block in bytes, including header
UInt8 lockOwner; // lock count in high nibble, owner in low
UInt8 flags; // flags, size adj in low nibble
Int16 hOffset; // offset/2 to MemHandle for movables
} Mem1ChunkHeaderType;
typedef Mem1ChunkHeaderType* Mem1ChunkHeaderPtr;
#define mem1ChunkFlagSizeAdj 0x0F // mask for size adjustment
// A non-movable chunk has 0xF as the lock count
#define mem1ChunkLockMask 0xF0
#define mem1ChunkOwnerMask 0x0F
/********************************************************************
* Structure of a Heap
*
* A heap starts with a HeapHeader
* Followed by the offset table (numHandles)
* Followed by movable chunks
* Followed by non-movable chunks
********************************************************************/
/********************************************************************
* Structure of a version 3 Memory Heap Header.
********************************************************************/
typedef struct {
UInt16 flags; // heap flags;
UInt32 size; // size of heap
UInt32 firstFreeChunkOffset;// offset/2 to first free chunk
MemMstrPtrTableType mstrPtrTbl; // Master pointer table
} MemHeapHeaderType;
typedef MemHeapHeaderType * MemHeapHeaderPtr;
// Flags Field
#define memHeapFlagReadOnly 0x0001 // heap is read-only (ROM based)
#define memHeapFlagVers2 0x8000 // version 2 heap (> 64K)
#define memHeapFlagVers3 0x4000 // version 3 heap (has free list)
#define memHeapFlagVers4 0x2000 // version 4 heap (has free master pointer table entry list)
#define memMstrPtrTableGrowBy 50 // # of entries to grow master pointer tables by
#define memMstrPtrTableInitSizeD 200 // # of entries to allocate initially for dynamic heap(s)
#define memMstrPtrTableInitSizeS 200 // # of entries to allocate initially for storage heap(s)
/********************************************************************
* Structure of a version 1 Memory Heap Header.
* This is included for use by the Palm Debugger so that it can do
* heap dumps of devices that use the version 1 Memory Manager.
********************************************************************/
typedef struct {
UInt16 flags; // heap flags;
UInt16 size; // size of heap - 0 means 64K;
Mem1MstrPtrTableType mstrPtrTbl; // Master pointer table
} Mem1HeapHeaderType;
typedef Mem1HeapHeaderType * Mem1HeapHeaderPtr;
/********************************************************************
* Structure of a version 2 Memory Heap Header.
* This is included for use by the Palm Debugger so that it can do
* heap dumps of devices that use the version 1 Memory Manager.
********************************************************************/
typedef struct {
UInt16 flags; // heap flags;
UInt32 size; // size of heap
MemMstrPtrTableType mstrPtrTbl; // Master pointer table
} Mem2HeapHeaderType;
typedef Mem2HeapHeaderType * Mem2HeapHeaderPtr;
/********************************************************************
* These macros pave the way for the version 2 Memory Manager that
* supports >64K chunks.
*
* They are a general way to get info out of a Chunk header and Heap header
* whether it be a version 1 or version 2 header. They are used almost
* exclusively by the Palm Debugger and Simulator Heap Dump utility
* since it must be able to do heap dumps of both versions of the Palm
* Memory Manager.
*
* The 'ver' parameter to these macros is either 1 for version 1 or
* 2 for version 2 and the 'p' parameter is the chunk header pointer.
********************************************************************/
// This structure is big enough to read in a version 1 or version 2
// Master Pointer Table into
typedef struct {
union {
MemMstrPtrTableType ver2;
Mem1MstrPtrTableType ver1;
} header;
} MemMstrPtrTableUnionType;
#define memUSizeOfMstrPtrTable(ver) \
(ver>1 ? sizeof(MemMstrPtrTableType) : sizeof(Mem1MstrPtrTableType))
#define memUMstrPtrTableNextTblOffset(p,ver) \
(ver>1 ? ((MemMstrPtrTablePtr)p)->nextTblOffset : ((Mem1MstrPtrTablePtr)p)->nextTblOffset)
#define memUMstrPtrTableNumEntries(p,ver) \
(ver>1 ? ((MemMstrPtrTablePtr)p)->numEntries : ((Mem1MstrPtrTablePtr)p)->numEntries)
// This structure is big enough to read in a version 1, version 2, or version 3
// heap header into
typedef struct {
union {
MemHeapHeaderType ver3;
Mem2HeapHeaderType ver2;
Mem1HeapHeaderType ver1;
} header;
} MemHeapHeaderUnionType;
#define memUHeapVer(p) \
(memUHeapFlags((p)) & memHeapFlagVers4 ? 4 : \
(memUHeapFlags((p)) & memHeapFlagVers3 ? 3 : \
(memUHeapFlags((p)) & memHeapFlagVers2 ? 2 : 1)))
#define memUSizeOfHeapHeader(ver) \
(ver>2 ? sizeof (MemHeapHeaderType) : (ver>1 ? sizeof(Mem2HeapHeaderType) : sizeof(Mem1HeapHeaderType)))
#define memUHeapSize(p,ver) \
(ver>2 ? ((MemHeapHeaderPtr)p)->size : (ver>1 ? ((Mem2HeapHeaderPtr)p)->size : ((Mem1HeapHeaderPtr)p)->size))
#define memUHeapFlags(p) \
(((MemHeapHeaderPtr)p)->flags)
#define memUHeapMstrPtrEntries(p,ver) \
(ver>2 ? ((MemHeapHeaderPtr)p)->mstrPtrTbl.numEntries : (ver>1 ? ((Mem2HeapHeaderPtr)p)->mstrPtrTbl.numEntries : ((Mem1HeapHeaderPtr)p)->mstrPtrTbl.numEntries))
#define memUHeapMstrPtrAddr(p,ver) \
(ver>2 ? (void *)&((MemHeapHeaderPtr)p)->mstrPtrTbl : (ver>1 ? (void *)&((Mem2HeapHeaderPtr)p)->mstrPtrTbl : (void *)&((Mem1HeapHeaderPtr)p)->mstrPtrTbl))
// This structure is big enough to read in a version 1 or version 2
// chunk header into.
typedef struct {
union {
MemChunkHeaderType ver2;
Mem1ChunkHeaderType ver1;
} header;
} MemChunkHeaderUnionType;
#define memUSizeOfHeapTerminator(ver) \
(ver>1 ? sizeof(MemHeapTerminatorType) : sizeof(UInt16))
#define memUSizeOfChunkHeader(ver) \
(ver>1 ? sizeof(MemChunkHeaderType) : sizeof(Mem1ChunkHeaderType))
#define memUChunkSize(p,ver) \
(ver>1 ? ((MemChunkHeaderPtr)p)->size : ((Mem1ChunkHeaderPtr)p)->size)
#define memUChunkFlags(p,ver) \
(ver>1 ? memChunkFlags(p) : ((Mem1ChunkHeaderPtr)p)->flags & 0xF0)
#define memUChunkSizeAdj(p,ver) \
(ver>1 ? ((MemChunkHeaderPtr)p)->sizeAdj : ((Mem1ChunkHeaderPtr)p)->flags & mem1ChunkFlagSizeAdj)
#define memUChunkLockCount(p,ver) \
(ver>1 ? ((MemChunkHeaderPtr)p)->lockCount : ((Mem1ChunkHeaderPtr)p)->lockOwner >> 4)
#define memUChunkOwner(p,ver) \
(ver>1 ? ((MemChunkHeaderPtr)p)->owner : ((Mem1ChunkHeaderPtr)p)->lockOwner & mem1ChunkOwnerMask)
#define memUChunkHOffset(p,ver) \
(ver>1 ? ((MemChunkHeaderPtr)p)->hOffset : ((Mem1ChunkHeaderPtr)p)->hOffset)
/************************************************************
* Structure of a Card Header.
* There is 1 card header for in every card that has ROM. The
* card header is stored at sysCardHeaderOffset into the card.
*
* RAM only cards will not have a card header
*************************************************************/
#define memMaxNameLen 32 // size of name and manuf fields including null
typedef struct CardHeaderType {
UInt32 initStack; // initial stack pointer (v4: offset to code in RomBoot)
UInt32 resetVector; // reset vector
UInt32 signature; // must be sysCardSignature
UInt16 hdrVersion; // header version
UInt16 flags; // card flags;
UInt8 name[memMaxNameLen]; // card name
UInt8 manuf[memMaxNameLen]; // card manufacturer's name
UInt16 version; // card version
UInt32 creationDate; // card creation date
UInt16 numRAMBlocks; // number of RAM blocks on card
UInt32 blockListOffset; // offset to RAM block list
UInt32 readWriteParmsOffset; // v2: offset from CardBase to r/w system data if any (in ROM)
UInt32 readWriteParmsSize; // v2: size of read/write system data if any (in ROM)
UInt32 readOnlyParmsOffset; // v2: offset from CardBase to read-only system data (in ROM)
UInt32 bigROMOffset; // v2: in SmallROM header: where SmallROM expects bigROM to live
// in BigROM header: where BigROM expects itself to live
UInt32 checksumBytes; // v2: size of card image in bytes (for checksum)
UInt16 checksumValue; // v2: checksum of card image (from Crc16CalcBlock)
UInt32 readWriteWorkingOffset; // v3: offset from CardBase to r/w working area if any (in ROM)
UInt32 readWriteWorkingSize; // v3: size of read/write working area if any (in ROM)
UInt32 halCodeOffset; // v4: offset from CardHeader to HAL code
UInt8 reserved[130]; // to bring us to 0x100 alignment
} CardHeaderType;
typedef CardHeaderType* CardHeaderPtr;
#define memCardHeaderFlagRAMOnly 0x0001 // RAM only card
#define memCardHeaderFlag328 0x0010 // ROM Supports 68328 processor
#define memCardHeaderFlagEZ 0x0020 // ROM SUpports 68EZ328 processor
#define memCardHeaderFlag230K 0x1000 // SmallROM supports 230Kbps
/************************************************************
* Structure of a Storage Header.
* There is 1 of these for every "store" on a memory card. A
* "store" can be all the RAM on a card or all the ROM on a card.
*
* The RAM storage header is stored at sysRAMHeader offset into the
* card. and the ROM storage header is stored at sysROMHeader offset
* into the card.
*************************************************************/
typedef struct {
UInt32 signature; // must be sysStoreSignature
UInt16 version; // version of header
UInt16 flags; // flags
UInt8 name[memMaxNameLen]; // name of store
UInt32 creationDate; // creation date
UInt32 backupDate; // last backup date
UInt32 heapListOffset; // offset to heap list for store
UInt32 initCodeOffset1; // init code for store, if any
UInt32 initCodeOffset2; // second init code for store, if any
LocalID databaseDirID; // local ID of database dir.
UInt32 rsvSpace; // where first heap starts.
UInt32 dynHeapSpace; // how big the dynamic heap area is
// (always 0 for ROM stores)
UInt32 firstRAMBlockSize; // Copy of firstRAMBlock size from cardinfo
// Used to determine if we're rebooting
// with a different amount of RAM.
// The following fields are used to store non-volatile information that
// must be accessed by the system but that is not convenient to store
// in a database due to access time or frequency. It is only valid
// in the RAM STORE ON CARD #0! Though some initialization values for
// the card 0 RAM store come from the ROM store's nvParams field.
SysNVParamsType nvParams;
// Filler bytes - reserved for future use. Size adjusted to
// keep total size of storage header at 0x100 bytes.
UInt8 reserved[176-sizeof(SysNVParamsType)];
// CRC value
UInt32 crc; // crc to check validity
} StorageHeaderType;
typedef StorageHeaderType* StorageHeaderPtr;
#define memStoreHeaderFlagRAMOnly 0x0001 // RAM store
// A Heap list for each store on a card (either RAM or ROM) gives a list of
// heaps' starting offsets for that store
typedef struct {
UInt16 numHeaps; // Number of heaps in store
UInt32 heapOffset[1]; // offset to heap
} HeapListType;
/********************************************************************
* CardInfo structure
* The Palm globals has a pointer to an array of CardInfo structures.
*
* This array is initialized by the Boot code before the Memory Manager
* starts up. Among other things, it tells the Memory Manager where
* every card is and the size of each card.
********************************************************************/
typedef struct CardInfoType {
// These fields are filled in by the boot code BEFORE
// MemInit() is called.
UInt8 *baseP; // base address of card
UInt32 size; // address range of card
UInt32 firstRAMBlockSize; // size of RAM block at offset 0
UInt32 targetROMShift; // used only under Emulation mode, must be
// added to emulated ROM pointers when calculating
// a LocalID for use in the device ROM.
UInt32 cardHeaderOffset; // offset to card header (usually in ROM)
// = 0 if RAM only card
UInt32 rsvSpace; // reserve space in RAM before first heap
UInt32 dynHeapSpace; // how much space to reserve for dynamic heap(s)
StorageHeaderPtr ramStoreP; // pointer to RAM store header
// This location depends on how much space
// was reserved on the card for the dynamic
// heap.
// These fields are copies of information in the card and storage headers
// they are cached here for quicker access by the Memory Manager. They
// are filled in by the Memory Manager during MemInit.
UInt16 numRAMHeaps; // Number of RAM heaps - for quick access
UInt32 *ramHeapOffsetsP; // Table of RAM heap offsets - for quick access
UInt16 numROMHeaps; // Number of RAM heaps - for quick access
UInt32 *romHeapOffsetsP; // Table of RAM heap offsets - for quick access
// This field was added for Palm OS v3.5. The HAL fills this in so the OS
// no longer has to use a #define'd value which can differ from device to device.
UInt32 cardOffsetMask; // converts a pointer to a card offset
} CardInfoType;
typedef CardInfoType* CardInfoPtr;
// The constant hwrNumCardSlots, defined in Hardware.h defines the maximum number
// of cards supported by the hardware.
/************************************************************
* Private Memory Manager Constants
*************************************************************/
// Private constant - # of dynamic heaps
#define memDynamicHeaps 1
// Private constant - maximum chunk size allowed (0xFFFFFFFFL = up to available memory)
// We're presently limiting the maximum chunk allocation because the current HotSync cannot
// transfer records/resources larger than (0x0FFFF - 30) bytes. This restriction will
// be removed when HotSync is extended to MemHandle larger transfers.
#define memMaxChunkAllocSize ((UInt32)(0x0FFFFUL - 30UL))
/************************************************************
* Private Memory Manager Macros. These macros are not
* guaranteed to be compatible in the future and should
* only be used in system code, not applications.
*
* To use these, define NON_PORTABLE at the top of your
* source code module.
*
* WARNING: This macro must only be used on Locked chunks!!!
* When running with error checking, it will verify
* that the chunk is locked before it dereferences it.
*************************************************************/
#if MEMORY_FORCE_LOCK == MEMORY_FORCE_LOCK_ON
#define memHandleProtect(h) \
((MemHandle)((UInt32)h | 0x80000000))
#define memHandleUnProtect(h) \
((void **)((UInt32)h & 0x7FFFFFFF))
#else
#define memHandleProtect(h) (h)
#define memHandleUnProtect(h) (h)
#endif
#if MEMORY_TYPE == MEMORY_LOCAL
#if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL
#define MemDeref(h) \
((MemHandleLockCount(h)==0 ? (*((void **)0x80000000)) : (*memHandleUnProtect(h))))
#else
#define MemDeref(h) \
(*(memHandleUnProtect(h)))
#endif
#else
#if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL
#define MemDeref(h) \
((MemHandleLockCount(h)==0 ? (*((void **)0x80000000)) : ((void *)ShlDWord(h))) )
#else
#define MemDeref(h) \
((void *)ShlDWord(memHandleUnProtect(h)))
#endif
#endif
// Typecast access to the MemCardInfo MemPtr
#define memCardInfoP(cardNo) \
( ((CardInfoPtr) ((LowMemHdrType*)PilotGlobalsP)->globals.memCardInfoP) + cardNo)
#endif // __MEMORYPRV_H__
//#endif // NON_PORTABLE
|