# Getting Information About Memory

The following sections explain how to find out how much memory is available, how to find out the type of memory you have, how to get the size of a memory page, and how to find out which VRAM bank (if any) contains a memory location.

## Finding Out How Much Memory Is Available

You can find out how much memory is available by calling `AvailMem()`:

  `void AvailMem( MemInfo *minfo, uint32 memflags )`

The `memflags` argument specifies the type of memory you want to find out about. If you want to find out how much of all types of memory is available, use `MEMTYPE_ANY` as the value of the flags argument. To find out how much DRAM is available, use `MEMTYPE_DRAM`; for VRAM, use `MEMTYPE_VRAM`. You can also use the flag `MEMTYPE_BANKSELECT` together with either `MEMTYPE_BANK1` or `MEMTYPE_BANK2` to get information about a specific VRAM bank. Other flags you can include are `MEMTYPE_DMA`, `MEMTYPE_CEL`, `MEMTYPE_AUDIO`, and `MEMTYPE_DSP`. For complete descriptions of these flags, see Allocating Memory.

Note: When you call `AvailMem(),` you can only request information about one memory type. Attempting to find out about more than one memory type can produce unexpected results.

The information about available memory is returned in a MemInfo structure pointed to by the `minfo` argument:

``

    typedef struct MemInfo
    {
        uint32 minfo_SysFree;
        uint32 minfo_SysLargest;
        uint32 minfo_TaskFree;
        uint32 minfo_TaskLargest;
    } MemInfo;

This structure contains the following information:

- minfo_SysFree, The amount of memory, in bytes, of the specified memory type in the system-wide free memory pool. The pool contains only full pages of memory.

- minfo_SysLargest, The size, in bytes, of the largest series of contiguous pages of the specified memory type in the system-wide free memory pool.

- minfo_TaskFree, The amount of memory, in bytes, of the specified type in the task's free memory pool.

- minfo_TaskLargest, The size, in bytes, of the largest contiguous block of the specified memory type that can be allocated from the task's free memory pool.

  Warning: Do not depend on these numbers, as they may change if other tasks on the system allocate memory at the same time you are calling AvailMem.

## Getting the Memory Type of a Memory Location

You can find out the memory type of a particular memory location by calling `GetMemType()`:

  `uint32 GetMemType( void *p )`

The `p` argument is a pointer to the memory location to identify. The function returns memory allocation flags (such as `MEMTYPE_VRAM`) which describe the type of memory. For descriptions of these flags, see Allocating a Memory Block.

## Getting the Size of a Memory Page

You can get the size of a memory page by calling the `GetPageSize()` function:

  `int32 GetPageSize( uint32 memflags )`

The `memflags` argument contains memory allocation flags for the page size of the memory type you specify. There are currently only three page sizes: one for DRAM and two for VRAM. You can, however, include any of the following flags: `MEMTYPE_ANY`, `MEMTYPE_VRAM`, `MEMTYPE_DRAM`, `MEMTYPE_BANKSELECT`, `MEMTYPE_BANK1`, `MEMTYPE_BANK2`, `MEMTYPE_DMA`,`MEMTYPE_CEL`, `MEMTYPE_AUDIO`, and `MEMTYPE_DSP`. (For complete descriptions of these flags, see Allocating a Memory Block.) Normally, you should include just one flag which specifies the one type of memory in which you're interested. Including more than one flag can produce an unexpected result.

The return value contains the size of the page for the specified memory type, in bytes.

## Finding Out Which VRAM Bank Contains a VRAM Location

In the current 3DO hardware, 2 MB of video random access memory (VRAM) is divided into two banks, each containing 1 MB of VRAM. Fast VRAM memory transfers using the SPORT bus can take place only between memory locations in the same bank. You can find out which bank of VRAM-if any-contains a particular memory location by calling the `GetBankBits()` macro:

  `uint32 GetBankBits( void *a )`

The `a` argument is a pointer to a memory location. The macro returns a set of memory flags in which the following flags can be set:

- MEMTYPE_BANKSELECT, Set if the memory is contained in VRAM.
- MEMTYPE_BANK1, Set if the memory is in VRAM bank 1.
- MEMTYPE_BANK2, Set if the memory is in VRAM bank 2.

If the memory is not in VRAM, the macro returns 0.

When a task allocates VRAM, the memory block contains memory from one VRAM bank or the other; it never contains memory from both banks. Thus, if any memory location in a block is in one VRAM bank, the entire block is in the same bank.

## Validating Memory Pointers

When working with memory, sometimes it is necessary to verify the validity of memory pointers. This can be extremely useful when debugging, for example, in `ASSERT()` macros. Portfolio validates memory pointers that are passed to it, and rejects any corrupt ones.

The `IsMemReadable()` and `IsMemWritable()` functions let your code verify the validity of pointers.

  `bool IsMemReadable(void *mem, int32 size);
  bool IsMemWritable(void *mem, int32 size);`

To both functions, you supply a pointer to a memory region and the size of that region. The functions return TRUE if the current task or thread can access the complete memory region.