/*
* picasm -- config.c
*
* Copyright 1995-2004 Timo Rossi, <trossi@iki.fi>
* See the file LICENSE for license terms.
*
* The code in this file handles configuration fuse
* setting with the CONFIG-directive
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "picasm.h"
#include "token.h"
#include "symtab.h"
/*
* parse the CONFIG directive
*
* This basically repeatedly expands the __do_config macro with
* the appropriate parameters.
*
*/
void
parse_config(void)
{
static char keyword[260];
struct symbol *config_macro_sym;
char *args[2];
int npairs;
#define MAX_PAIRS 30
char *keywords[MAX_PAIRS];
char *values[MAX_PAIRS];
int i;
if(pic_instr_set == PIC_NONE)
fatal_error("PIC device type not set");
config_macro_sym = lookup_symbol("__do_config", SYMTAB_GLOBAL);
if(config_macro_sym == NULL || config_macro_sym->type != SYM_MACRO)
{
error(1, "__do_config not defined, cannot set configuration bits");
return;
}
npairs = 0;
for(;;)
{
if(token_type != TOK_IDENTIFIER)
{
cfg_error:
error(1, "CONFIG syntax error");
return;
}
strcpy(keyword, token_string);
get_token();
/* hmm... this is a little kludge, but as
the tokenizer now makes 'local id's from
the valid config strings, this must be used... */
if(token_type != TOK_LOCAL_ID)
{
if(token_type != TOK_EQUAL)
{
error(1, "'=' expected");
return;
}
get_token();
if(token_type != TOK_IDENTIFIER)
goto cfg_error;
}
if(npairs >= MAX_PAIRS)
{
error(0, "Too many config keyword=value pairs");
break;
}
keywords[npairs] = mem_alloc(strlen(keyword) + 1);
strcpy(keywords[npairs], keyword);
values[npairs] = mem_alloc(strlen(token_string) + 1);
strcpy(values[npairs], token_string);
npairs++;
get_token();
if(token_type != TOK_COMMA)
break;
get_token();
}
skip_eol();
write_listing_line(0);
listing_on = 0;
for(i = 0; i < npairs; i++)
{
args[0] = keywords[i];
args[1] = values[i];
expand_macro_with_args(config_macro_sym, args, 2, 1);
mem_free(keywords[i]);
mem_free(values[i]);
}
}
void
config_done(void)
{
struct symbol *config_sym;
config_sym = lookup_symbol("__config", SYMTAB_GLOBAL);
if(config_sym == NULL || config_sym->type != SYM_SET)
{
error(0, "Internal CONFIG error: __config not defined (or wrong type)");
return;
}
config_fuses = config_sym->v.value;
/*
* This causes the config fuses to be output on the "exitm" listing line.
* Not very clean, but at least we get the config fuses in the listing.
*/
list_flags = LIST_VAL;
list_val = config_fuses;
listing_on = 1;
}
syntax highlighted by Code2HTML, v. 0.9.1