12.4.2 User-Managed Access

User-managed access means that the programmer must write explicit code to save, set, and restore the PSV or EDS window page register. In certain situations, this could result in faster execution speed.

In the following example, the constant status_string is located in the compiler-managed PSV section, while the constant gamma_factor is located in a separate PSV section.

Note: To modify this example to run on a device which supports the EDS window, replace references to PSVPAG with DSRPAG.

The compiler will initialize the page register only for the compiler-managed PSV section on startup. To properly access gamma_factor, you must manually manage the page register. Namely, save the current page value, set the page register to access gamma_factor, and restore the original page value after. To determine the correct page value for a constant stored in program memory, use the __builtin_psvpage() helper function.

When the page register has been modified to access gamma_factor, be careful not to access constants stored in the compiler-managed PSV section, such as string constants used with printf(). Any attempts to access constants stored in the compiler-managed PSV section with an incorrect page value will fail.

Note: On devices with less than 16K instruction words, there is only one page and manual management of the page register is not required.
#include "stdio.h"
#include "xc.h"

const char __attribute__ ((space(auto_psv))) status_string[2][10] = {"System OK", "Key Made"};
const int __attribute__ ((space(psv))) gamma_factor[3] = {13, 23, 7};

int main(void)
{
  unsigned psv_shadow;
  unsigned key, seed = 17231;

  /* print the first status string */
  printf ("%s\n", status_string[0]);

  /* save the PSVPAG */
  psv_shadow = PSVPAG;

  /* set the PSVPAG for accessing gamma_factor[] */
  PSVPAG = __builtin_psvpage (gamma_factor);

  /* build the key from gamma_factor */
  key = (seed + gamma_factor[0] + gamma_factor[1]) / gamma_factor[2];

  /* restore the PSVPAG for the compiler-managed PSVPAG */
  PSVPAG = psv_shadow;

  /* print the second status message */
  printf ("%s \n", status_string[1]);
}