Source file: /~heha/hs/gputils64-210929.zip/gpasm/processor.cpp

/* PIC Processor selection
   Copyright 1998-2005	James Bowman, Craig Franklin
   Copyright 2014-2016	Molnár Károly
*/

#include "stdhdr.h"

#include "libgputils.h"
#include "gpasm.h"
#include "directive.h"
#include "gpmsg.h"

/*------------------------------------------------------------------------------------------------*/

static void _make_bank_constants_and_variables(pic_processor_t Proc, int Num_of_banks) {
  int  bank_size;
  int  bank_addr;
  int  i;
  char name[64];

  i = (Num_of_banks == 1) ? 0 : __BANK_INV;

  set_global(__ACTIVE_BANK_ADDR, i, VAL_VARIABLE, true, false);
  set_global(__ASSUMED_BANK_ADDR, i, VAL_VARIABLE, true, false);

  if (Num_of_banks <= 0) {
    return;
  }

  set_global("__NUM_BANKS", Num_of_banks, VAL_CONSTANT, true, false);

  bank_size = Proc->pclass->bank_size;
  bank_addr = 0;
  i         = 0;
  while (true) {
    if (i == 0) {
      set_global("__BANK_FIRST", bank_addr, VAL_CONSTANT, true, false);
    }

    snprintf(name, sizeof(name), "__BANK_%i", i);
    set_global(name, bank_addr, VAL_CONSTANT, true, false);
    ++i;

    if (i == Num_of_banks) {
      set_global("__BANK_LAST", bank_addr, VAL_CONSTANT, true, false);
      break;
    }

    bank_addr += bank_size;
  }
}

/*------------------------------------------------------------------------------------------------*/

static void
_make_page_constants_and_variables(pic_processor_t Proc, int Num_of_pages)
{
  int  page_size;
  int  page_addr;
  int  i;
  char name[64];

  i = (Num_of_pages == 1) ? 0 : __PAGE_INV;

  set_global(__ACTIVE_PAGE_ADDR, i, VAL_VARIABLE, true, false);

  if (Num_of_pages <= 0) {
    return;
  }

  set_global("__NUM_PAGES", Num_of_pages, VAL_CONSTANT, true, false);

  page_size = Proc->pclass->page_size;
  page_addr = 0;
  i         = 0;
  while (true) {
    if (i == 0) {
      set_global("__PAGE_FIRST", page_addr, VAL_CONSTANT, true, false);
    }

    snprintf(name, sizeof(name), "__PAGE_%i", i);
    set_global(name, page_addr, VAL_CONSTANT, true, false);
    ++i;

    if (i == Num_of_pages) {
      set_global("__PAGE_LAST", page_addr, VAL_CONSTANT, true, false);
      break;
    }

    page_addr += page_size;
  }
}

/*------------------------------------------------------------------------------------------------*/

void
select_processor(const char *Name)
{
  pic_processor_t  found;
  proc_class_t     pclass;
  const int       *pair;
  const vector_t  *vec;
  unsigned     num;
  int              addr;
  int              num_of_banks;
  int              num_of_pages;
  char             buf[BUFSIZ];
  int              badrom_idx;
  long             start;
  long             end;

  if (state.cmd_line.processor) {
    gpmsg(GPW_CMDLINE_PROC, NULL);
  }
  else {
    found = gp_find_processor(Name);

    if (found) {
      if (!state.processor) {
        /* If in extended mode: Check if processor supports extended instruction set. */
        if (state.extended_pic16e && !(found->cpu_flags & CPU_HAVE_EXTINST)) {
          gpmsg(GPE_NO_EXTENDED_MODE, NULL);
        }

        state.processor = found;
        state.maxram    = found->maxram;
        state.maxrom    = found->maxrom;

        if (state.maxrom > 0) {
          /* Initialize badrom from internal processor info. */

          for (badrom_idx = 0; badrom_idx < MAX_BADROM; badrom_idx += 2) {
            start = found->badrom[badrom_idx];
            end   = found->badrom[badrom_idx + 1];

            if ((start >= 0) && (end >= start)) {
              state.badrom.setrange(start, end);
            }
          }
        }

        set_global(found->defined_as, 1, VAL_CONSTANT, false, false);

        if (!state.mpasm_compatible) {
          pclass = found->pclass;

          num_of_banks = gp_processor_num_banks(found);
          num_of_pages = gp_processor_num_pages(found);

          if ((pclass == PROC_CLASS_GENERIC) || (pclass == PROC_CLASS_PIC12) ||
              (pclass == PROC_CLASS_PIC12E)  || (pclass == PROC_CLASS_PIC12I)) {
            if ((pclass == PROC_CLASS_PIC12E) || (pclass == PROC_CLASS_PIC12I)) {
              set_global("__ENHANCED", 1,                 VAL_CONSTANT, true, false);
            }

            set_global("__12_BIT",     1,                 VAL_CONSTANT, true, false);
            set_global("__PAGE_BITS",  PIC12_PAGE_BITS,   VAL_CONSTANT, true, false);
            set_global("__PAGE_MASK",  pclass->page_mask,  VAL_CONSTANT, true, false);
            set_global("__PAGE_SHIFT", PIC12_PAGE_SHIFT,  VAL_CONSTANT, true, false);
            set_global("__PAGE_SIZE",  pclass->page_size,  VAL_CONSTANT, true, false);
            set_global("__PAGE_INV",   __PAGE_INV,        VAL_CONSTANT, true, false);

            _make_bank_constants_and_variables(found, num_of_banks);
            _make_page_constants_and_variables(found, num_of_pages);
          }
          else if (pclass == PROC_CLASS_SX) {
            set_global("__12_BIT",     1,                 VAL_CONSTANT, true, false);
            set_global("__PAGE_BITS",  SX_PAGE_BITS,      VAL_CONSTANT, true, false);
            set_global("__PAGE_MASK",  pclass->page_mask,  VAL_CONSTANT, true, false);
            set_global("__PAGE_SHIFT", PIC12_PAGE_SHIFT,  VAL_CONSTANT, true, false);
            set_global("__PAGE_SIZE",  pclass->page_size,  VAL_CONSTANT, true, false);
            set_global("__PAGE_INV",   __PAGE_INV,        VAL_CONSTANT, true, false);

            _make_bank_constants_and_variables(found, num_of_banks);
            _make_page_constants_and_variables(found, num_of_pages);
          }
          else if (pclass == PROC_CLASS_PIC14) {
            set_global("__14_BIT",     1,                 VAL_CONSTANT, true, false);
            set_global("__PAGE_BITS",  PIC14_PAGE_BITS,   VAL_CONSTANT, true, false);
            set_global("__PAGE_MASK",  pclass->page_mask,  VAL_CONSTANT, true, false);
            set_global("__PAGE_SHIFT", PIC14_PAGE_SHIFT,  VAL_CONSTANT, true, false);
            set_global("__PAGE_SIZE",  pclass->page_size,  VAL_CONSTANT, true, false);
            set_global("__PAGE_INV",   __PAGE_INV,        VAL_CONSTANT, true, false);

            _make_bank_constants_and_variables(found, num_of_banks);
            _make_page_constants_and_variables(found, num_of_pages);
          }
          else if ((pclass == PROC_CLASS_PIC14E) || (pclass == PROC_CLASS_PIC14EX)) {
            set_global("__14_BIT",        1,                    VAL_CONSTANT, true, false);
            set_global("__ENHANCED",      1,                    VAL_CONSTANT, true, false);
            set_global("__PAGE_BITS",     PIC14E_PAGE_BITS,     VAL_CONSTANT, true, false);
            set_global("__PAGE_MASK",     pclass->page_mask,     VAL_CONSTANT, true, false);
            set_global("__PAGE_SHIFT",    PIC14_PAGE_SHIFT,     VAL_CONSTANT, true, false);
            set_global("__PAGE_SIZE",     pclass->page_size,     VAL_CONSTANT, true, false);
            set_global("__PAGE512_SHIFT", PIC14E_PAGE512_SHIFT, VAL_CONSTANT, true, false);
            set_global("__PAGE_INV",      __PAGE_INV,           VAL_CONSTANT, true, false);

            _make_bank_constants_and_variables(found, num_of_banks);
            _make_page_constants_and_variables(found, num_of_pages);
          }
          else if (pclass == PROC_CLASS_PIC16) {
            set_global("__16_BIT",     1,                 VAL_CONSTANT, true, false);
            set_global("__PAGE_BITS",  PIC16_PAGE_BITS,   VAL_CONSTANT, true, false);
            set_global("__PAGE_MASK",  pclass->page_mask,  VAL_CONSTANT, true, false);
            set_global("__PAGE_SHIFT", PIC16_PAGE_SHIFT,  VAL_CONSTANT, true, false);
            set_global("__PAGE_SIZE",  pclass->page_size,  VAL_CONSTANT, true, false);
            set_global("__PAGE_INV",   __PAGE_INV,        VAL_CONSTANT, true, false);

            _make_bank_constants_and_variables(found, num_of_banks);
            _make_page_constants_and_variables(found, num_of_pages);
          }
          else if (pclass == PROC_CLASS_PIC16E) {
            set_global("__16_BIT",   1, VAL_CONSTANT, true, false);
            set_global("__EXTENDED", 1, VAL_CONSTANT, true, false);

            _make_bank_constants_and_variables(found, num_of_banks);
          }

          set_global("__BANK_BITS",  found->bank_bits,       VAL_CONSTANT, true, false);
          set_global("__BANK_MASK",  pclass->bank_mask,       VAL_CONSTANT, true, false);
          set_global("__BANK_SHIFT", pclass->bank_bits_shift, VAL_CONSTANT, true, false);
          set_global("__BANK_SIZE",  pclass->bank_size,       VAL_CONSTANT, true, false);
          set_global("__BANK_INV",   __BANK_INV,             VAL_CONSTANT, true, false);

          if ((pair = gp_processor_common_ram_exist(found))) {
            set_global("__COMMON_RAM_START", pair[0], VAL_CONSTANT, true, false);
            set_global("__COMMON_RAM_END",   pair[1], VAL_CONSTANT, true, false);
          }

          if (found->common_ram_max > 0) {
            set_global("__COMMON_RAM_MAX", found->common_ram_max, VAL_CONSTANT, true, false);
          }

          if ((pair = gp_processor_linear_ram_exist(found))) {
            set_global("__LINEAR_RAM_START", pair[0], VAL_CONSTANT, true, false);
            set_global("__LINEAR_RAM_END",   pair[1], VAL_CONSTANT, true, false);
          }

          if ((pclass->vector_table) || (pclass->vector_number > 0)) {
            vec = pclass->vector_table;
            num = pclass->vector_number;

            for (; num; ++vec, --num) {
              buf[0] = '_';
              buf[1] = '_';
              gp_stptoupper(&buf[2], vec->name, sizeof(buf) - 2);

              if (vec->address < 0) {
                /* This a SX type processor. */
                addr = found->prog_mem_size;

                if (addr > 0) {
                  --addr;
                }
              }
              else {
                addr = vec->address;
              }

              set_global(buf, addr, VAL_CONSTANT, true, false);
            }
          }

          addr = found->prog_mem_size;

          if (addr > 0) {
            set_global("__CODE_START",        0, VAL_CONSTANT, true, false);
            set_global("__CODE_END",   addr - 1, VAL_CONSTANT, true, false);
          }

          if ((pair = gp_processor_idlocs_exist(found))) {
            set_global("__IDLOCS_START", pair[0], VAL_CONSTANT, true, false);
            set_global("__IDLOCS_END",   pair[1], VAL_CONSTANT, true, false);
          }

          if ((pair = gp_processor_config_exist(found))) {
            set_global("__CONFIG_START", pair[0], VAL_CONSTANT, true, false);
            set_global("__CONFIG_END",   pair[1], VAL_CONSTANT, true, false);
          }

          if ((pair = gp_processor_eeprom_exist(found))) {
            set_global("__EEPROM_START", pair[0], VAL_CONSTANT, true, false);
            set_global("__EEPROM_END",   pair[1], VAL_CONSTANT, true, false);
          }

          addr = gp_processor_bsr_boundary(found);

          if (addr > 0) {
            set_global("__ACC_RAM_LOW_START",        0, VAL_CONSTANT, true, false);
            set_global("__ACC_RAM_LOW_END",   addr - 1, VAL_CONSTANT, true, false);
          }
        } /* if (!state.mpasm_compatible) */
      } /* if (state.processor == NULL) */
      else if (state.processor != found) {
        gpmsg(GPW_REDEFINING_PROC, NULL);
        gpmsg(GPE_EXTRA_PROC, NULL);
      }
    }
    else {
      if (state.pass > 0) {
        gpmsg(GPE_UNKNOWN_PROC, NULL, Name);
      }
      else {
        printf("Didn't find any processor named: %s\nHere are the supported processors:\n", Name);
        gp_dump_processor_list(true, PROC_CLASS_UNKNOWN, PROC_CLASS_UNKNOWN, PROC_CLASS_UNKNOWN);
        exit(1);
      }
    }

    /* Load the instruction sets if necessary. */
    if ((!state.processor_chosen) && (state.processor)) {
      opcode_init(1);   /* General directives. */
      /* Separate the directives from the opcodes. */
      state.stBuiltin = gp_sym_push_table(state.stBuiltin, true);
      opcode_init(2);   /* Processor-specific. */

      if (!(IS_PIC16_CORE) && !(IS_PIC16E_CORE)) {
        opcode_init(3);   /* Special pseudo ops for 12 and 14 bit devices. */
      }

      state.processor_chosen = true;
    }
  }
}
Detected encoding: UTF-80