mirror of
https://github.com/fachat/xa65.git
synced 2024-12-29 07:29:50 +00:00
Updates for .listbytes, and ca65 unnamed labels
This commit is contained in:
parent
05c7799e9b
commit
f04d44d141
31
xa/src/xa.c
31
xa/src/xa.c
@ -804,15 +804,13 @@ fprintf(stderr, "offset = %i length = %i fstart = %i flen = %i charo = %c\n",
|
||||
static int pass1(void)
|
||||
{
|
||||
signed char o[2*MAXLINE]; /* doubled for token listing */
|
||||
int l,er,temp_er,al;
|
||||
int l,er,al;
|
||||
|
||||
memode=0;
|
||||
xmode=0;
|
||||
tlen=0;
|
||||
ner=0;
|
||||
|
||||
temp_er = 0;
|
||||
|
||||
/*FIXIT*/
|
||||
while(!(er=getline(s)))
|
||||
{
|
||||
@ -825,7 +823,7 @@ static int pass1(void)
|
||||
case SEG_ZERO: zlen += al; break;
|
||||
}
|
||||
|
||||
/*printf(": er= %d, l=%d, tmpz=%d\n",er,l,tmpz); */
|
||||
//printf(": er= %d, l=%d\n",er,l);
|
||||
|
||||
if(l)
|
||||
{
|
||||
@ -902,7 +900,7 @@ static void usage(int default816, FILE *fp)
|
||||
" -R start assembler in relocating mode\n");
|
||||
fprintf(fp,
|
||||
" -Llabel defines `label' as absolute, undefined label even when linking\n"
|
||||
" -p<c> replace preprocessor char '#' with custom, e.g. '-p%' replaces it with '%'\n"
|
||||
" -p<c> replace preprocessor char '#' with custom, e.g. '-p!' replaces it with '!'\n"
|
||||
" -b? addr set segment base address to integer value addr\n"
|
||||
" `?' stands for t(ext), d(ata), b(ss) and z(ero) segment\n"
|
||||
" (address can be given more than once, last one is used)\n");
|
||||
@ -1108,19 +1106,27 @@ static int getline(char *s)
|
||||
gl=0;
|
||||
if(!ec || ec==E_EOF)
|
||||
{
|
||||
int startofline = 1;
|
||||
do {
|
||||
c=s[j]=l[i++];
|
||||
|
||||
if (c=='\"')
|
||||
if (c=='\"') {
|
||||
hkfl^=1;
|
||||
if (c==';' && !hkfl)
|
||||
}
|
||||
if (c==';' && !hkfl) {
|
||||
// start of comment
|
||||
comcom = 1;
|
||||
if (c=='\0')
|
||||
break; /* hkfl = comcom = 0 */
|
||||
}
|
||||
if (c=='\0') {
|
||||
// end of line
|
||||
break; /* hkfl = comcom = 0 */
|
||||
}
|
||||
if (c==':' && !hkfl) {
|
||||
/* if the next char is a "=" - so that we have a ":=" - and we
|
||||
we have ca65 compatibility, we ignore the colon */
|
||||
if (l[i]!='=' || !ca65 || comcom) {
|
||||
// also check for ":+" and ":-"
|
||||
|
||||
if (((!startofline) && l[i]!='=' && l[i]!='+' && l[i]!='-') || !ca65 || comcom) {
|
||||
/* but otherwise we check if it is in a comment and we have
|
||||
MASM or CA65 compatibility, then we ignore the colon as well */
|
||||
if(!comcom || !(masm || ca65)) {
|
||||
@ -1131,7 +1137,10 @@ static int getline(char *s)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isspace(c)) {
|
||||
startofline = 0;
|
||||
}
|
||||
j++;
|
||||
} while (c!='\0' && j<MAXLINE-1 && i<MAXLINE-1);
|
||||
|
||||
|
@ -119,8 +119,8 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
|
||||
if(s[pp]==T_LABEL)
|
||||
{
|
||||
er=l_get(cval(s+pp+1),v, &afl);
|
||||
/* printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n",
|
||||
er, segment, afl, nolink, fundef); */
|
||||
//printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n",
|
||||
// er, segment, afl, nolink, fundef);
|
||||
if(er==E_NODEF && segment != SEG_ABS && fundef ) {
|
||||
if( nolink || ((afl==SEG_UNDEF) || (afl==SEG_UNDEFZP))) {
|
||||
er = E_OK;
|
||||
|
19
xa/src/xah.h
19
xa/src/xah.h
@ -35,7 +35,14 @@
|
||||
#define MAXLINE 2048
|
||||
#define MAXPP 40000L
|
||||
#define ANZDEF 2340 /* multiplied by sizeof(List) -> Byte, ANZDEF * 20 < 32768 */
|
||||
#define TMPMEM 200000L /* temporary memory buffer from Pass1 to Pass 2 */
|
||||
#define TMPMEM 2000000L /* temporary memory buffer from Pass1 to Pass 2 (includes all source, thus enlarged) */
|
||||
|
||||
typedef enum {
|
||||
STD = 0,
|
||||
CHEAP = 1,
|
||||
UNNAMED = 2,
|
||||
UNNAMED_DEF = 3
|
||||
} label_t;
|
||||
|
||||
typedef struct LabOcc {
|
||||
struct LabOcc *next;
|
||||
@ -43,6 +50,9 @@ typedef struct LabOcc {
|
||||
char *fname;
|
||||
} LabOcc;
|
||||
|
||||
/**
|
||||
* struct that defines a label, after it has been parsed
|
||||
*/
|
||||
typedef struct {
|
||||
int blk;
|
||||
int val;
|
||||
@ -53,9 +63,14 @@ typedef struct {
|
||||
*/
|
||||
int afl; /* 0 = no address (no relocation), 1 = address label */
|
||||
int nextindex;
|
||||
int is_cll; /* 0 is normal label, 1 is cheap local label (used for listing) */
|
||||
label_t is_cll; /* 0 is normal label, 1 is cheap local label (used for listing) */
|
||||
char *n;
|
||||
struct LabOcc *occlist;
|
||||
// within a block, make a linked list for the unnamed label counting
|
||||
// use indexes, as the label table can be re-alloced (so pointers change)
|
||||
// -1 is the "undef'd" end of list
|
||||
int blknext;
|
||||
int blkprev;
|
||||
} Labtab;
|
||||
|
||||
typedef struct {
|
||||
|
247
xa/src/xal.c
247
xa/src/xal.c
@ -48,14 +48,22 @@ static int b_fget(int*,int);
|
||||
static int b_ltest(int,int);
|
||||
static int b_get(int*);
|
||||
static int b_test(int);
|
||||
static int ll_def(char *s, int *n, int b);
|
||||
static int ll_def(char *s, int *n, int b, label_t ltype);
|
||||
static int b_link(int);
|
||||
|
||||
static int b_new(void);
|
||||
|
||||
static void cll_init();
|
||||
static int cll_get();
|
||||
static void cll_clear();
|
||||
static int cll_getcur();
|
||||
|
||||
/*
|
||||
static void unn_init();
|
||||
static int unn_get();
|
||||
static void unn_clear();
|
||||
*/
|
||||
|
||||
/* local variables */
|
||||
|
||||
/*
|
||||
@ -76,6 +84,7 @@ static Labtab *ltp;
|
||||
int l_init(void)
|
||||
{
|
||||
cll_init();
|
||||
//unn_init();
|
||||
return 0;
|
||||
#if 0
|
||||
int er;
|
||||
@ -180,6 +189,41 @@ int cll_getcur() {
|
||||
return cll_current;
|
||||
}
|
||||
|
||||
/**********************************************************************************
|
||||
* unnamed labels
|
||||
*/
|
||||
#if 0
|
||||
static int unn_current = 0; /* the current cheap local labels block */
|
||||
|
||||
/**
|
||||
* init the cheap local labels
|
||||
*/
|
||||
void unn_init() {
|
||||
unn_current = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the block number for a new cheap local label block
|
||||
*/
|
||||
int unn_get() {
|
||||
if (unn_current == 0) {
|
||||
unn_current = b_new();
|
||||
}
|
||||
return unn_current;
|
||||
}
|
||||
|
||||
/**
|
||||
* clear the local labels
|
||||
*/
|
||||
void unn_clear() {
|
||||
unn_current = 0;
|
||||
}
|
||||
|
||||
int unn_getcur() {
|
||||
return cll_current;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
/**
|
||||
@ -188,12 +232,12 @@ int cll_getcur() {
|
||||
int lg_set(char *s ) {
|
||||
int n, er;
|
||||
|
||||
er = ll_search(s,&n, 0);
|
||||
er = ll_search(s,&n, STD);
|
||||
|
||||
if(er==E_OK) {
|
||||
fprintf(stderr,"Warning: global label doubly defined!\n");
|
||||
} else {
|
||||
if(!(er=ll_def(s,&n,0))) {
|
||||
if(!(er=ll_def(s,&n,0, STD))) {
|
||||
return lg_import(n);
|
||||
}
|
||||
}
|
||||
@ -235,14 +279,21 @@ int lg_importzp(int n) {
|
||||
int l_def(char *s, int *l, int *x, int *f)
|
||||
{
|
||||
int n,er,b,i=0;
|
||||
int cll_fl;
|
||||
label_t cll_fl;
|
||||
|
||||
*f=0; /* flag (given as param) that the label is to be re-defined and the
|
||||
"label defined error" is to be skipped */
|
||||
b=0; /* block level on block stack, resp. block number */
|
||||
n=0; /* flag, when set, b is absolute block number and not being translated */
|
||||
cll_fl=0; /* when set, clear the cheap local label block */
|
||||
cll_fl=STD; /* when 0, clear the cheap local label block */
|
||||
|
||||
if(s[0]==':') {
|
||||
// ca65 unnamed label
|
||||
i++;
|
||||
//n++; /* block number b is absolute */
|
||||
//b=unn_get(); /* current (possibly newly allocated) unnamed label block */
|
||||
cll_fl = UNNAMED; // keep the cheap local label block
|
||||
} else
|
||||
if(s[0]=='-')
|
||||
{
|
||||
*f+=1; /* label is being redefined */
|
||||
@ -253,7 +304,7 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||
i++;
|
||||
n++; /* block number b is absolute */
|
||||
b=cll_get(); /* current (possibly newly allocated) cheap label block */
|
||||
cll_fl=1; /* do not clear the cll block again... */
|
||||
cll_fl=CHEAP; /* do not clear the cll block again... */
|
||||
} else
|
||||
if(s[0]=='+')
|
||||
{
|
||||
@ -273,16 +324,20 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||
b_fget(&b,b);
|
||||
}
|
||||
|
||||
if(!cll_fl) {
|
||||
if(cll_fl == STD) {
|
||||
/* clear cheap local labels */
|
||||
cll_clear();
|
||||
}
|
||||
|
||||
if(!isalpha(s[i]) && s[i]!='_' && !(ca65 && isdigit(s[i]) ) )
|
||||
if((!isalpha(s[i])) && (s[i]!='_') && !(ca65 && ((cll_fl == UNNAMED) || isdigit(s[i])) ) ) {
|
||||
//printf("SYNTAX cll_fl=%d, i=%d, s[i]=%02x (%c)\n", cll_fl, i, s[i], s[i]);
|
||||
er=E_SYNTAX;
|
||||
else
|
||||
} else
|
||||
{
|
||||
er=ll_search(s+i,&n, cll_fl);
|
||||
er = E_NODEF;
|
||||
if (cll_fl != UNNAMED) {
|
||||
er=ll_search(s+i,&n, cll_fl);
|
||||
}
|
||||
|
||||
if(er==E_OK)
|
||||
{
|
||||
@ -308,7 +363,8 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||
} else
|
||||
if(er==E_NODEF)
|
||||
{
|
||||
if(!(er=ll_def(s+i,&n,b))) /* store the label in the table of labels */
|
||||
|
||||
if(!(er=ll_def(s+i,&n,b, cll_fl) )) /* store the label in the table of labels */
|
||||
{
|
||||
ltp=afile->la.lt+n;
|
||||
*l=ltp->len+i;
|
||||
@ -325,23 +381,31 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||
int l_search(char *s, int *l, int *x, int *v, int *afl)
|
||||
{
|
||||
int n,er,b;
|
||||
int cll_fl;
|
||||
label_t cll_fl;
|
||||
|
||||
*afl=0;
|
||||
|
||||
/* check cheap local label */
|
||||
cll_fl=0;
|
||||
cll_fl=STD;
|
||||
if (s[0]=='@') {
|
||||
cll_fl=1; /* also used as offset to the label length, so must be 1 */
|
||||
cll_fl=CHEAP;
|
||||
s++;
|
||||
} else
|
||||
if (s[0]==':') {
|
||||
cll_fl = UNNAMED_DEF;
|
||||
s++;
|
||||
}
|
||||
|
||||
er = E_NODEF;
|
||||
if (cll_fl != UNNAMED_DEF) {
|
||||
er=ll_search(s,&n, cll_fl);
|
||||
}
|
||||
|
||||
er=ll_search(s,&n, cll_fl);
|
||||
/*printf("l_search: lab=%s(l=%d, afl=%d, er=%d, n=%d, cll_fl=%d, cll_cur=%d)\n",s,*l, *afl,er,n, cll_fl, cll_getcur());*/
|
||||
//printf("l_search: lab=%s(afl=%d, er=%d, cll_fl=%d, cll_cur=%d)\n",s,*afl,er, cll_fl, cll_getcur());
|
||||
if(er==E_OK)
|
||||
{
|
||||
ltp=afile->la.lt+n;
|
||||
*l=ltp->len + cll_fl;
|
||||
*l=ltp->len + ((cll_fl == STD) ? 0 : 1);
|
||||
if(ltp->fl == 1)
|
||||
{
|
||||
l_get(n,v,afl);/* *v=lt[n].val;*/
|
||||
@ -355,18 +419,22 @@ int l_search(char *s, int *l, int *x, int *v, int *afl)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cll_fl) {
|
||||
if(cll_fl == CHEAP) {
|
||||
b=cll_get();
|
||||
} else
|
||||
if(cll_fl == UNNAMED_DEF) {
|
||||
b_get(&b); // b=unn_get();
|
||||
} else {
|
||||
b_get(&b);
|
||||
}
|
||||
|
||||
er=ll_def(s,x,b); /* ll_def(...,*v); */
|
||||
er=ll_def(s,x,b, cll_fl); /* ll_def(...,*v); */
|
||||
|
||||
ltp=afile->la.lt+(*x);
|
||||
ltp->is_cll = cll_fl;
|
||||
|
||||
*l=ltp->len + cll_fl;
|
||||
*l=ltp->len + ((cll_fl == STD) ? 0 : 1);
|
||||
//*l=ltp->len + cll_fl;
|
||||
|
||||
if(!er)
|
||||
{
|
||||
@ -414,7 +482,7 @@ void l_addocc(int n, int *v, int *afl) {
|
||||
}
|
||||
|
||||
/* for the list functionality */
|
||||
char *l_get_name(int n, int *is_cll) {
|
||||
char *l_get_name(int n, label_t *is_cll) {
|
||||
ltp=afile->la.lt+n;
|
||||
*is_cll = ltp->is_cll;
|
||||
return ltp->n;
|
||||
@ -424,7 +492,32 @@ int l_get(int n, int *v, int *afl)
|
||||
{
|
||||
if(crossref) l_addocc(n,v,afl);
|
||||
|
||||
ltp=afile->la.lt+n;
|
||||
ltp = afile->la.lt+n;
|
||||
|
||||
if (ltp->is_cll == UNNAMED_DEF) {
|
||||
// need to count up/down in the linkd label list for the block
|
||||
char *namep = ltp->n;
|
||||
//printf("::: unnamed_def: %s, n=%d\n", namep, n);
|
||||
while ((*namep == '+') || (*namep == '-')) {
|
||||
char c = *namep;
|
||||
int nextp = -1;
|
||||
if (c == '+') {
|
||||
nextp = ltp->blknext;
|
||||
} else
|
||||
if (c == '-') {
|
||||
nextp = ltp->blkprev;
|
||||
}
|
||||
//printf("::: nextp=%d\n", nextp);
|
||||
if (nextp == -1) {
|
||||
return E_NODEF;
|
||||
}
|
||||
ltp = afile->la.lt+nextp;
|
||||
//printf("::: leads to: %s, nextp=%d\n", ltp->n, nextp);
|
||||
if (ltp->is_cll == UNNAMED) {
|
||||
namep++;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*v)=ltp->val;
|
||||
lz=ltp->n;
|
||||
*afl = ltp->afl;
|
||||
@ -452,19 +545,23 @@ static void ll_exblk(int a, int b)
|
||||
}
|
||||
}
|
||||
|
||||
static int ll_def(char *s, int *n, int b) /* definiert naechstes Label nr->n */
|
||||
/* defines next label, returns new label number in out param n */
|
||||
static int ll_def(char *s, int *n, int b, label_t ltype)
|
||||
{
|
||||
int j=0,er=E_NOMEM,hash;
|
||||
char *s2;
|
||||
char *s2 = NULL;
|
||||
|
||||
/*printf("ll_def: s=%s\n",s); */
|
||||
//printf("ll_def: s=%s, ltype=%d, no_name=%d\n",s, ltype, no_name);
|
||||
|
||||
// label table for the file ...
|
||||
if(!afile->la.lt) {
|
||||
// ... does not exist yet, so malloc it
|
||||
afile->la.lti = 0;
|
||||
afile->la.ltm = 1000;
|
||||
afile->la.lt = malloc(afile->la.ltm * sizeof(Labtab));
|
||||
}
|
||||
if(afile->la.lti>=afile->la.ltm) {
|
||||
// ... or is at its capacity limit, so realloc it
|
||||
afile->la.ltm *= 1.5;
|
||||
afile->la.lt = realloc(afile->la.lt, afile->la.ltm * sizeof(Labtab));
|
||||
}
|
||||
@ -472,50 +569,51 @@ static int ll_def(char *s, int *n, int b) /* definiert naechstes Label
|
||||
fprintf(stderr, "Oops: no memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
#if 0
|
||||
if((lti<ANZLAB) /*&&(lni<(long)(LABMEM-MAXLAB))*/)
|
||||
{
|
||||
#endif
|
||||
ltp=afile->la.lt+afile->la.lti;
|
||||
/*
|
||||
s2=ltp->n=ln+lni;
|
||||
|
||||
while((j<MAXLAB-1) && (s[j]!='\0') && (isalnum(s[j]) || s[j]=='_'))
|
||||
{
|
||||
s2[j]=s[j];
|
||||
j++;
|
||||
}
|
||||
*/
|
||||
while((s[j]!='\0') && (isalnum(s[j]) || (s[j]=='_'))) j++;
|
||||
s2 = malloc(j+1);
|
||||
if(!s2) {
|
||||
// current pointer in label table
|
||||
ltp = afile->la.lt + afile->la.lti;
|
||||
|
||||
if (ltype != UNNAMED) {
|
||||
// alloc space and copy over name
|
||||
if (ltype == UNNAMED_DEF) {
|
||||
// unnamed lables are like ":--" or ":+" with variable length
|
||||
while((s[j]!='\0') && (s[j]=='+' || s[j]=='-')) j++;
|
||||
} else {
|
||||
// standard (and cheap) labels are normal text
|
||||
while((s[j]!='\0') && (isalnum(s[j]) || (s[j]=='_'))) j++;
|
||||
}
|
||||
s2 = malloc(j+1);
|
||||
if(!s2) {
|
||||
fprintf(stderr,"Oops: no memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
strncpy(s2,s,j);
|
||||
s2[j]=0;
|
||||
}
|
||||
strncpy(s2,s,j);
|
||||
s2[j]=0;
|
||||
/*
|
||||
if(j<MAXLAB)
|
||||
{
|
||||
*/
|
||||
|
||||
// init new entry in label table
|
||||
er=E_OK;
|
||||
ltp->len=j;
|
||||
ltp->n = s2;
|
||||
ltp->blk=b;
|
||||
ltp->len=j; // length of label
|
||||
ltp->n = s2; // name of label (char*)
|
||||
ltp->blk=b; // block number
|
||||
ltp->fl=0;
|
||||
ltp->afl=0;
|
||||
ltp->is_cll=0;
|
||||
ltp->occlist=NULL;
|
||||
hash=hashcode(s,j);
|
||||
ltp->nextindex=afile->la.hashindex[hash];
|
||||
afile->la.hashindex[hash]=afile->la.lti;
|
||||
*n=afile->la.lti;
|
||||
afile->la.lti++;
|
||||
/* lni+=j+1;*/
|
||||
/* }
|
||||
}
|
||||
*/
|
||||
/*printf("ll_def return: %d\n",er);*/
|
||||
ltp->is_cll=ltype; // STD, CHEAP, or UNNAMED label
|
||||
ltp->occlist=NULL;
|
||||
hash=hashcode(s,j); // compute hashcode
|
||||
ltp->nextindex=afile->la.hashindex[hash]; // and link in before last entry with same hashcode
|
||||
afile->la.hashindex[hash]=afile->la.lti; // set as start of list for that hashcode
|
||||
|
||||
// TODO: does not work across files!
|
||||
ltp->blknext = -1; // no next block
|
||||
ltp->blkprev = b_link( afile->la.lti ); // previous block, linked within block
|
||||
|
||||
ltp = afile->la.lt + ltp->blkprev;
|
||||
ltp->blknext = afile->la.lti;
|
||||
|
||||
*n=afile->la.lti; // return the list index for that file in the out parameter n
|
||||
afile->la.lti++; // increase last index in lable table
|
||||
|
||||
return(er);
|
||||
}
|
||||
|
||||
@ -525,8 +623,10 @@ static int ll_def(char *s, int *n, int b) /* definiert naechstes Label
|
||||
* set of blocks (in the block stack)
|
||||
*
|
||||
* If cll_fl is set, the label is also searched in the local cheap label scope
|
||||
*
|
||||
* Do not define the label (as is done in l_search()!)
|
||||
*/
|
||||
int ll_search(char *s, int *n, int cll_fl) /* search Label in Tabelle ,nr->n */
|
||||
int ll_search(char *s, int *n, label_t cll_fl) /* search Label in Tabelle ,nr->n */
|
||||
{
|
||||
int i,j=0,k,er=E_NODEF,hash;
|
||||
|
||||
@ -545,11 +645,14 @@ int ll_search(char *s, int *n, int cll_fl) /* search Label in Tabelle ,
|
||||
{
|
||||
for (k=0;(k<j)&&(ltp->n[k]==s[k]);k++);
|
||||
|
||||
if (cll_fl) {
|
||||
if (cll_fl == CHEAP) {
|
||||
if (ltp->blk == cll_getcur()) {
|
||||
er=E_OK;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
if (cll_fl == UNNAMED) {
|
||||
// TODO
|
||||
} else {
|
||||
/* check if the found label is in any of the blocks in the
|
||||
current block stack */
|
||||
@ -584,7 +687,7 @@ int ll_pdef(char *t)
|
||||
{
|
||||
int n;
|
||||
|
||||
if(ll_search(t,&n, 0)==E_OK)
|
||||
if(ll_search(t,&n, STD)==E_OK)
|
||||
{
|
||||
ltp=afile->la.lt+n;
|
||||
if(ltp->fl)
|
||||
@ -643,6 +746,7 @@ int l_write(FILE *fp)
|
||||
* a specific block number is contained in the current block stack.
|
||||
*/
|
||||
static int bt[MAXBLK]; /* block stack */
|
||||
static int labind[MAXBLK]; /* last allocated label (as index) for the current block, -1 none yet alloc'd */
|
||||
static int bi; /* length of the block stack (minus 1, i.e. bi[bi] has the innermost block) */
|
||||
static int blk; /* current block number for allocation */
|
||||
|
||||
@ -651,6 +755,7 @@ int b_init(void)
|
||||
blk =0;
|
||||
bi =0;
|
||||
bt[bi]=blk;
|
||||
labind[bi]=-1;
|
||||
|
||||
return(E_OK);
|
||||
}
|
||||
@ -679,7 +784,9 @@ int b_open(void)
|
||||
|
||||
if(bi<MAXBLK-1)
|
||||
{
|
||||
bt[++bi]=b_new();
|
||||
bi++;
|
||||
bt[bi]=b_new();
|
||||
labind[bi] = -1;
|
||||
|
||||
er=E_OK;
|
||||
}
|
||||
@ -700,6 +807,7 @@ int b_close(void)
|
||||
return E_BLOCK;
|
||||
}
|
||||
cll_clear();
|
||||
//unn_clear();
|
||||
return(E_OK);
|
||||
}
|
||||
|
||||
@ -763,3 +871,10 @@ static int b_ltest(int a, int b) /* testet ob bt^-1(b) in intervall [0,bt^-1(
|
||||
return(er);
|
||||
}
|
||||
|
||||
int b_link(int newlab) {
|
||||
int tmp = labind[bi];
|
||||
//printf("b_link: old was %d, set to %d\n", tmp, newlab);
|
||||
labind[bi] = newlab;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
*/
|
||||
extern char *lz;
|
||||
|
||||
|
||||
int l_init(void);
|
||||
int ga_lab(void);
|
||||
int gm_lab(void);
|
||||
@ -46,10 +47,10 @@ int ga_blk(void);
|
||||
int l_def(char *s, int* l, int *x, int *f);
|
||||
int l_search(char *s, int *l, int *x, int *v, int *afl);
|
||||
void l_set(int n, int v, int afl);
|
||||
char* l_get_name(int n, int *is_cll);
|
||||
char* l_get_name(int n, label_t *is_cll);
|
||||
int l_get(int n, int *v, int *afl);
|
||||
int l_vget(int n, int *v, char **s);
|
||||
int ll_search(char *s, int *n, int cll_fl);
|
||||
int ll_search(char *s, int *n, label_t labeltype);
|
||||
int ll_pdef(char *t);
|
||||
|
||||
int b_open(void);
|
||||
|
@ -53,10 +53,13 @@ FILE *xfopen(const char *fn,const char *mode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// copy to xname by replacing windows backslashes with the proper DIRCHAR
|
||||
for(i=0;i<l+1;i++) {
|
||||
xname[i]=((fn[i]=='\\')?DIRCHAR:fn[i]);
|
||||
}
|
||||
|
||||
//printf("name=%s, xname=%s, mode=%s\n",fn,xname, mode);
|
||||
|
||||
if(mode[0]=='r')
|
||||
{
|
||||
if((file=fopen(fn,mode))==NULL
|
||||
@ -68,7 +71,6 @@ FILE *xfopen(const char *fn,const char *mode)
|
||||
strcpy(n2,n);
|
||||
strcat(n2,xname);
|
||||
strcat(n,fn);
|
||||
/* printf("name=%s,n2=%s,mode=%s\n",n,n2,mode); */
|
||||
file=fopen(n,mode);
|
||||
if(!file) file=fopen(n2,mode);
|
||||
}
|
||||
@ -87,7 +89,6 @@ FILE *xfopen(const char *fn,const char *mode)
|
||||
strcpy(n2,n);
|
||||
strcat(n2,xname);
|
||||
strcat(n,fn);
|
||||
/* printf("name=%s,n2=%s,mode=%s\n",n,n2,mode); */
|
||||
file=fopen(n,mode);
|
||||
if(!file) file=fopen(n2,mode);
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ int pp_ifldef(char *t)
|
||||
int pp_iflused(char *t)
|
||||
{
|
||||
int n;
|
||||
loopfl=(loopfl<<1)+( ll_search(t,&n,0) ? 1 : 0 );
|
||||
loopfl=(loopfl<<1)+( ll_search(t,&n,STD) ? 1 : 0 );
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
149
xa/src/xat.c
149
xa/src/xat.c
@ -53,6 +53,8 @@ static void tg_bin(signed char*,int*,int*);
|
||||
static int t_p2(signed char *t, int *ll, int fl, int *al);
|
||||
static void do_listing(signed char *listing, int listing_len, signed char *bincode, int bincode_len);
|
||||
|
||||
void list_setbytes(int number_of_bytes_per_line);
|
||||
|
||||
/* assembly mnemonics and pseudo-op tokens */
|
||||
/* ina and dea don't work yet */
|
||||
/* Note AF 20110624: added some ca65 compatibility pseudo opcodes,
|
||||
@ -91,7 +93,7 @@ static char *kt[] ={
|
||||
".zero",".fopt", ".byte", ".end", ".list", ".xlist", ".dupb", ".blkb", ".db", ".dw",
|
||||
".align",".block", ".bend",".al",".as",".xl",".xs", ".bin", ".aasc", ".code",
|
||||
".include", ".import", ".importzp", ".proc", ".endproc",
|
||||
".zeropage", ".org", ".reloc"
|
||||
".zeropage", ".org", ".reloc", ".listbytes"
|
||||
|
||||
};
|
||||
|
||||
@ -158,9 +160,10 @@ static int lp[]= { 0,1,1,1,1,2,2,1,1,1,2,2,2,1,1,1,2,2 };
|
||||
#define Kzeropage Lastbef+36 /* mapped to Kzero */
|
||||
#define Korg Lastbef+37 /* mapped to Kpcdef - with parameter equivalent to "*=$abcd" */
|
||||
#define Krelocx Lastbef+38 /* mapped to Kpcdef - without parameter equivalent to "*=" */
|
||||
#define Klistbytes (Lastbef+39-256)
|
||||
|
||||
/* last valid token+1 */
|
||||
#define Anzkey Lastbef+39 /* define last valid token number; last define above plus one */
|
||||
#define Anzkey Lastbef+40 /* define last valid token number; last define above plus one */
|
||||
|
||||
|
||||
#define Kreloc (Anzkey-256) /* *= (relocation mode) */
|
||||
@ -434,7 +437,7 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
|
||||
#if 0
|
||||
printf("t_conv (er=%d):",er);
|
||||
for(i=0;i<l;i++)
|
||||
printf("%02x,",t[i]);
|
||||
printf("%02x,",t[i] & 0xff);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
@ -444,7 +447,6 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
|
||||
afile->base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length();
|
||||
romable=1;
|
||||
}
|
||||
|
||||
if(!er)
|
||||
{
|
||||
|
||||
@ -453,7 +455,9 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
|
||||
* pseudo-op dispatch (except .byt, .asc)
|
||||
*
|
||||
*/
|
||||
n=t[0];
|
||||
// fix sign
|
||||
n=t[0]; // & 0xff;
|
||||
|
||||
/* TODO: make that a big switch statement... */
|
||||
/* maybe later. Cameron */
|
||||
|
||||
@ -486,6 +490,17 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
|
||||
set_fopt(l,t,nk+1-na1+na2);
|
||||
*ll = 0;
|
||||
} else
|
||||
if(n==Klistbytes) {
|
||||
int p = 0;
|
||||
if(!(er=a_term(t+1,&p,&l,pc[segment],&afl,&label,0))) {
|
||||
er=E_OKDEF;
|
||||
}
|
||||
*ll = 3;
|
||||
t[0] = Klistbytes;
|
||||
t[1] = p & 0xff;
|
||||
t[2] = (p >> 8) & 0xff;
|
||||
//printf("Klistbytes p1: er=%d, l=%d\n", er, l);
|
||||
} else
|
||||
if(n==Kpcdef)
|
||||
{
|
||||
int tmp;
|
||||
@ -636,7 +651,6 @@ printf(" wrote %02x %02x %02x %02x %02x %02x, %02x, %02x\n",
|
||||
char binfnam[255];
|
||||
int offset;
|
||||
int length;
|
||||
int fstart;
|
||||
|
||||
i = 1;
|
||||
j = 0;
|
||||
@ -672,7 +686,7 @@ printf(" wrote %02x %02x %02x %02x %02x %02x, %02x, %02x\n",
|
||||
if (!er) {
|
||||
int k;
|
||||
|
||||
fstart = i;
|
||||
//fstart = i;
|
||||
if(t[i]=='\"') {
|
||||
i++;
|
||||
k=t[i]+i+1;
|
||||
@ -1065,6 +1079,7 @@ int t_p2(signed char *t, int *ll, int fl, int *al)
|
||||
static int rlt[3]; /* relocation table */
|
||||
static int lab[3]; /* undef. label table */
|
||||
|
||||
|
||||
er=E_OK;
|
||||
bl=0;
|
||||
if(*ll<0) /* <0 when E_OK, >0 when E_OKDEF */
|
||||
@ -1360,6 +1375,14 @@ int t_p2(signed char *t, int *ll, int fl, int *al)
|
||||
pc[segment] = npc;
|
||||
/*printf("Kreloc: newsegment=%d, pc[seg]=%04x\n", segment, pc[segment]);*/
|
||||
} else
|
||||
if(n==Klistbytes) {
|
||||
int nbytes = (t[1] & 0xff) + (t[2] << 8);
|
||||
//printf("Klistbytes --> er=%d, nbytes=%d\n", er, nbytes);
|
||||
list_setbytes(nbytes);
|
||||
l = 2;
|
||||
*ll=0;
|
||||
bl =0;
|
||||
} else
|
||||
if(n==Ksegment) {
|
||||
segment = t[1];
|
||||
*ll=0;
|
||||
@ -1832,7 +1855,7 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
|
||||
int p,q,ll,mk,er;
|
||||
int ud; /* counts undefined labels */
|
||||
int n; /* label number to be passed between l_def (definition) and l_set (set the value) */
|
||||
int m, byte;
|
||||
int byte;
|
||||
int uz; /* unused at the moment */
|
||||
/*static unsigned char cast;*/
|
||||
|
||||
@ -1854,7 +1877,7 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
|
||||
fl=0; /* 1 = pass text thru */
|
||||
afl=0; /* pointer flag for label */
|
||||
|
||||
while(s[p]==' ') p++;
|
||||
while(isspace(s[p])) p++;
|
||||
|
||||
n=T_END;
|
||||
/*cast='\0';*/
|
||||
@ -1863,7 +1886,28 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
|
||||
{
|
||||
while(s[p]!='\0' && s[p]!=';')
|
||||
{
|
||||
//printf("CONV: %s\n", s);
|
||||
|
||||
if (s[p] == ':') {
|
||||
// this is a ca65 unnamed label
|
||||
if ((er = l_def((char*)s+p, &ll, &n, &f)))
|
||||
break;
|
||||
l_set(n,pc,segment); /* set as address value */
|
||||
t[q++]=T_DEFINE;
|
||||
t[q++]=n&255;
|
||||
t[q++]=(n>>8)&255;
|
||||
n=0;
|
||||
|
||||
p+=ll;
|
||||
|
||||
while(isspace(s[p])) p++;
|
||||
|
||||
// end of line
|
||||
if (s[p] == 0 || s[p] == ';') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* is keyword? */
|
||||
if(!(er=t_keyword(s+p,&ll,&n)))
|
||||
break;
|
||||
@ -1872,13 +1916,14 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
|
||||
if(er && er!=E_NOKEY)
|
||||
break;
|
||||
|
||||
/* if so, try to understand as label */
|
||||
// if so, try to understand as label
|
||||
// it returns the label number in n
|
||||
if((er=l_def((char*)s+p,&ll,&n,&f)))
|
||||
break;
|
||||
|
||||
p+=ll;
|
||||
|
||||
while(s[p]==' ') p++;
|
||||
while(isspace(s[p])) p++;
|
||||
|
||||
if(s[p]=='=')
|
||||
{
|
||||
@ -2010,11 +2055,29 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
|
||||
{
|
||||
t[q++]=s[p++];
|
||||
} else
|
||||
/* maybe it's a label
|
||||
/* maybe it's a label
|
||||
Note that for ca65 cheap local labels, we check for "@" */
|
||||
if(isalpha(s[p]) || s[p]=='_' || (s[p]=='@' && ca65))
|
||||
if(isalpha(s[p]) || s[p]=='_' || ((s[p]==':' || s[p]=='@') && ca65))
|
||||
{
|
||||
m=n;
|
||||
|
||||
int p2 = 0;
|
||||
if (n == (Klistbytes & 0xff)) {
|
||||
// check for "unlimited"
|
||||
// Note: this could be done by a more general "constants" handling,
|
||||
// where in appropriate places (like the one here), constants are
|
||||
// replaced by a pointer to a predefined constants info, e.g. using
|
||||
// a T_CONSTANT. Which would also fix the listing of this constant
|
||||
// (which is currently listed as "0")
|
||||
static char *unlimited = "unlimited";
|
||||
while (s[p+p2] != 0 && unlimited[p2] != 0 && s[p+p2] == unlimited[p2]) p2++;
|
||||
}
|
||||
if (p2 == 9) { // length of "unlimited"
|
||||
er = E_OK;
|
||||
// found constant
|
||||
wval(q, 0, 'd');
|
||||
p += p2;
|
||||
} else {
|
||||
//m=n;
|
||||
er=l_search((char*)s+p,&ll,&n,&v,&afl);
|
||||
/*
|
||||
if(m==Kglobl || m==Kextzero) {
|
||||
@ -2058,6 +2121,7 @@ fprintf(stderr, "could not find %s\n", (char *)s+p);
|
||||
er=E_OK;
|
||||
}
|
||||
p+=ll;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(s[p]<='9' && s[p]>='0')
|
||||
@ -2213,6 +2277,7 @@ fprintf(stderr, "could not find %s\n", (char *)s+p);
|
||||
}
|
||||
}
|
||||
}
|
||||
//printf("er=%d, ud=%d\n", er, ud);
|
||||
if(!er)
|
||||
{
|
||||
/*
|
||||
@ -2260,20 +2325,28 @@ fprintf(stderr, "could not find %s\n", (char *)s+p);
|
||||
return(er);
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
/*********************************************************************************************
|
||||
* identifies a keyword in s, if it is found, starting with s[0]
|
||||
* A keyword is either a mnemonic, or a pseudo-opcode
|
||||
*/
|
||||
static int t_keyword(signed char *s, int *l, int *n)
|
||||
{
|
||||
int i = 0, j = 0, hash;
|
||||
int i = 0; // index into keywords
|
||||
int j = 0;
|
||||
int hash;
|
||||
|
||||
// keywords either start with a character, a "." or "*"
|
||||
if(!isalpha(s[0]) && s[0]!='.' && s[0]!='*' )
|
||||
return(E_NOKEY);
|
||||
|
||||
// if first char is a character, use it as hash...
|
||||
if(isalpha(s[0]))
|
||||
hash=tolower(s[0])-'a';
|
||||
else
|
||||
hash=26;
|
||||
|
||||
|
||||
// check for "*="
|
||||
if(s[0]=='*') {
|
||||
j=1;
|
||||
while(s[j] && isspace(s[j])) j++;
|
||||
@ -2282,9 +2355,14 @@ static int t_keyword(signed char *s, int *l, int *n)
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
// no keyword yet found?
|
||||
if(!i) {
|
||||
// get sub-table from hash code, and compare with table content
|
||||
// (temporarily) redefine i as start index in opcode table, and hash as end index
|
||||
i=ktp[hash];
|
||||
hash=ktp[hash+1];
|
||||
// check all entries in opcode table from start to end for that hash code
|
||||
while(i<hash)
|
||||
{
|
||||
j=0;
|
||||
@ -2457,6 +2535,8 @@ static int list_lineno = 1; /* current line number */
|
||||
static int list_last_lineno = 0; /* current line number */
|
||||
static char *list_filenamep = NULL; /* current file name pointer */
|
||||
|
||||
static int list_numbytes = 8;
|
||||
|
||||
static int list_string(char *buf, char *string);
|
||||
static int list_tokens(char *buf, signed char *input, int len);
|
||||
static int list_value(char *buf, int val, signed char format);
|
||||
@ -2469,6 +2549,11 @@ static int list_byte(char *buf, int outbyte);
|
||||
static int list_byte_f(char *buf, int outbyte, signed char format);
|
||||
static int list_nibble_f(char *buf, int outnib, signed char format);
|
||||
|
||||
// set number of bytes per line displayed as hex
|
||||
void list_setbytes(int number_of_bytes_per_line) {
|
||||
list_numbytes = number_of_bytes_per_line;
|
||||
}
|
||||
|
||||
/* set line number for the coming listing output */
|
||||
void list_line(int l) {
|
||||
list_lineno = l;
|
||||
@ -2552,8 +2637,8 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
|
||||
|
||||
/* binary output (up to 8 byte. If more than 8 byte, print 7 plus "..." */
|
||||
n_hexb = bincode_len;
|
||||
if (n_hexb >= 8) {
|
||||
n_hexb = 7;
|
||||
if (list_numbytes != 0 && n_hexb >= list_numbytes) {
|
||||
n_hexb = list_numbytes-1;
|
||||
}
|
||||
for (i = 0; i < n_hexb; i++) {
|
||||
buf = buf + list_byte(buf, bincode[i]);
|
||||
@ -2593,7 +2678,7 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||
int tmp;
|
||||
char *name;
|
||||
signed char c;
|
||||
int is_cll;
|
||||
label_t is_cll;
|
||||
int tabval;
|
||||
signed char format;
|
||||
|
||||
@ -2607,10 +2692,17 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||
tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255);
|
||||
/*printf("define: len=%d, inp=%d, tmp=%d\n", len, inp, tmp);*/
|
||||
name=l_get_name(tmp, &is_cll);
|
||||
if (is_cll) outp += list_char(buf+outp, '@');
|
||||
tmp = list_string(buf+outp, name);
|
||||
tabval += tmp + 1 + is_cll;
|
||||
outp += tmp;
|
||||
if (is_cll == CHEAP) {
|
||||
outp += list_char(buf+outp, '@');
|
||||
} else
|
||||
if (is_cll == UNNAMED_DEF || is_cll == UNNAMED) {
|
||||
outp += list_char(buf+outp, ':');
|
||||
}
|
||||
if (is_cll != UNNAMED) {
|
||||
tmp = list_string(buf+outp, name);
|
||||
tabval += tmp + 1 + is_cll;
|
||||
outp += tmp;
|
||||
}
|
||||
outp += list_char(buf+outp, ' ');
|
||||
inp += 3;
|
||||
tmp = input[inp] & 255;
|
||||
@ -2668,8 +2760,15 @@ int list_tokens(char *buf, signed char *input, int len) {
|
||||
/* 16 bit label number */
|
||||
tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255);
|
||||
name=l_get_name(tmp, &is_cll);
|
||||
if (is_cll) outp += list_char(buf+outp, '@');
|
||||
outp += list_string(buf+outp, name);
|
||||
if (is_cll == CHEAP) {
|
||||
outp += list_char(buf+outp, '@');
|
||||
} else
|
||||
if (is_cll == UNNAMED || is_cll == UNNAMED_DEF) {
|
||||
outp += list_char(buf+outp, ':');
|
||||
}
|
||||
if (is_cll != UNNAMED) {
|
||||
outp += list_string(buf+outp, name);
|
||||
}
|
||||
inp += 3;
|
||||
operator = 1; /* check if arithmetic operator follows */
|
||||
break;
|
||||
|
@ -19,6 +19,7 @@ incerr/ 1) .xl/.al should error without -w 2) error should be in
|
||||
binclude/ Binary include code with some weird casing
|
||||
chppch/ Changing preprocessor characters (-p)
|
||||
charset/ Tests of when charsets should be honoured and when not
|
||||
cc65/ Compatibility tests for ca65 compatibility
|
||||
|
||||
Cameron Kaiser, André Fachat
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user