1
0
mirror of https://github.com/fachat/xa65.git synced 2025-01-19 08:30:03 +00:00

Updates for .listbytes, and ca65 unnamed labels

This commit is contained in:
fachat 2012-07-28 14:47:04 +02:00
parent 05c7799e9b
commit f04d44d141
9 changed files with 352 additions and 111 deletions

View File

@ -804,15 +804,13 @@ fprintf(stderr, "offset = %i length = %i fstart = %i flen = %i charo = %c\n",
static int pass1(void) static int pass1(void)
{ {
signed char o[2*MAXLINE]; /* doubled for token listing */ signed char o[2*MAXLINE]; /* doubled for token listing */
int l,er,temp_er,al; int l,er,al;
memode=0; memode=0;
xmode=0; xmode=0;
tlen=0; tlen=0;
ner=0; ner=0;
temp_er = 0;
/*FIXIT*/ /*FIXIT*/
while(!(er=getline(s))) while(!(er=getline(s)))
{ {
@ -825,7 +823,7 @@ static int pass1(void)
case SEG_ZERO: zlen += al; break; 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) if(l)
{ {
@ -902,7 +900,7 @@ static void usage(int default816, FILE *fp)
" -R start assembler in relocating mode\n"); " -R start assembler in relocating mode\n");
fprintf(fp, fprintf(fp,
" -Llabel defines `label' as absolute, undefined label even when linking\n" " -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" " -b? addr set segment base address to integer value addr\n"
" `?' stands for t(ext), d(ata), b(ss) and z(ero) segment\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"); " (address can be given more than once, last one is used)\n");
@ -1108,19 +1106,27 @@ static int getline(char *s)
gl=0; gl=0;
if(!ec || ec==E_EOF) if(!ec || ec==E_EOF)
{ {
int startofline = 1;
do { do {
c=s[j]=l[i++]; c=s[j]=l[i++];
if (c=='\"') if (c=='\"') {
hkfl^=1; hkfl^=1;
if (c==';' && !hkfl) }
if (c==';' && !hkfl) {
// start of comment
comcom = 1; comcom = 1;
if (c=='\0') }
if (c=='\0') {
// end of line
break; /* hkfl = comcom = 0 */ break; /* hkfl = comcom = 0 */
}
if (c==':' && !hkfl) { if (c==':' && !hkfl) {
/* if the next char is a "=" - so that we have a ":=" - and we /* if the next char is a "=" - so that we have a ":=" - and we
we have ca65 compatibility, we ignore the colon */ 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 /* but otherwise we check if it is in a comment and we have
MASM or CA65 compatibility, then we ignore the colon as well */ MASM or CA65 compatibility, then we ignore the colon as well */
if(!comcom || !(masm || ca65)) { if(!comcom || !(masm || ca65)) {
@ -1132,6 +1138,9 @@ static int getline(char *s)
} }
} }
} }
if (!isspace(c)) {
startofline = 0;
}
j++; j++;
} while (c!='\0' && j<MAXLINE-1 && i<MAXLINE-1); } while (c!='\0' && j<MAXLINE-1 && i<MAXLINE-1);

View File

@ -119,8 +119,8 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
if(s[pp]==T_LABEL) if(s[pp]==T_LABEL)
{ {
er=l_get(cval(s+pp+1),v, &afl); er=l_get(cval(s+pp+1),v, &afl);
/* printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n", //printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n",
er, segment, afl, nolink, fundef); */ // er, segment, afl, nolink, fundef);
if(er==E_NODEF && segment != SEG_ABS && fundef ) { if(er==E_NODEF && segment != SEG_ABS && fundef ) {
if( nolink || ((afl==SEG_UNDEF) || (afl==SEG_UNDEFZP))) { if( nolink || ((afl==SEG_UNDEF) || (afl==SEG_UNDEFZP))) {
er = E_OK; er = E_OK;

View File

@ -35,7 +35,14 @@
#define MAXLINE 2048 #define MAXLINE 2048
#define MAXPP 40000L #define MAXPP 40000L
#define ANZDEF 2340 /* multiplied by sizeof(List) -> Byte, ANZDEF * 20 < 32768 */ #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 { typedef struct LabOcc {
struct LabOcc *next; struct LabOcc *next;
@ -43,6 +50,9 @@ typedef struct LabOcc {
char *fname; char *fname;
} LabOcc; } LabOcc;
/**
* struct that defines a label, after it has been parsed
*/
typedef struct { typedef struct {
int blk; int blk;
int val; int val;
@ -53,9 +63,14 @@ typedef struct {
*/ */
int afl; /* 0 = no address (no relocation), 1 = address label */ int afl; /* 0 = no address (no relocation), 1 = address label */
int nextindex; 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; char *n;
struct LabOcc *occlist; 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; } Labtab;
typedef struct { typedef struct {

View File

@ -48,14 +48,22 @@ static int b_fget(int*,int);
static int b_ltest(int,int); static int b_ltest(int,int);
static int b_get(int*); static int b_get(int*);
static int b_test(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 int b_new(void);
static void cll_init(); static void cll_init();
static int cll_get(); static int cll_get();
static void cll_clear(); static void cll_clear();
static int cll_getcur(); static int cll_getcur();
/*
static void unn_init();
static int unn_get();
static void unn_clear();
*/
/* local variables */ /* local variables */
/* /*
@ -76,6 +84,7 @@ static Labtab *ltp;
int l_init(void) int l_init(void)
{ {
cll_init(); cll_init();
//unn_init();
return 0; return 0;
#if 0 #if 0
int er; int er;
@ -180,6 +189,41 @@ int cll_getcur() {
return cll_current; 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 lg_set(char *s ) {
int n, er; int n, er;
er = ll_search(s,&n, 0); er = ll_search(s,&n, STD);
if(er==E_OK) { if(er==E_OK) {
fprintf(stderr,"Warning: global label doubly defined!\n"); fprintf(stderr,"Warning: global label doubly defined!\n");
} else { } else {
if(!(er=ll_def(s,&n,0))) { if(!(er=ll_def(s,&n,0, STD))) {
return lg_import(n); 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 l_def(char *s, int *l, int *x, int *f)
{ {
int n,er,b,i=0; 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 *f=0; /* flag (given as param) that the label is to be re-defined and the
"label defined error" is to be skipped */ "label defined error" is to be skipped */
b=0; /* block level on block stack, resp. block number */ b=0; /* block level on block stack, resp. block number */
n=0; /* flag, when set, b is absolute block number and not being translated */ 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]=='-') if(s[0]=='-')
{ {
*f+=1; /* label is being redefined */ *f+=1; /* label is being redefined */
@ -253,7 +304,7 @@ int l_def(char *s, int *l, int *x, int *f)
i++; i++;
n++; /* block number b is absolute */ n++; /* block number b is absolute */
b=cll_get(); /* current (possibly newly allocated) cheap label block */ 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 } else
if(s[0]=='+') if(s[0]=='+')
{ {
@ -273,16 +324,20 @@ int l_def(char *s, int *l, int *x, int *f)
b_fget(&b,b); b_fget(&b,b);
} }
if(!cll_fl) { if(cll_fl == STD) {
/* clear cheap local labels */ /* clear cheap local labels */
cll_clear(); 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; er=E_SYNTAX;
else } else
{ {
er = E_NODEF;
if (cll_fl != UNNAMED) {
er=ll_search(s+i,&n, cll_fl); er=ll_search(s+i,&n, cll_fl);
}
if(er==E_OK) if(er==E_OK)
{ {
@ -308,7 +363,8 @@ int l_def(char *s, int *l, int *x, int *f)
} else } else
if(er==E_NODEF) 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; ltp=afile->la.lt+n;
*l=ltp->len+i; *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 l_search(char *s, int *l, int *x, int *v, int *afl)
{ {
int n,er,b; int n,er,b;
int cll_fl; label_t cll_fl;
*afl=0; *afl=0;
/* check cheap local label */ /* check cheap local label */
cll_fl=0; cll_fl=STD;
if (s[0]=='@') { 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++; 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) if(er==E_OK)
{ {
ltp=afile->la.lt+n; ltp=afile->la.lt+n;
*l=ltp->len + cll_fl; *l=ltp->len + ((cll_fl == STD) ? 0 : 1);
if(ltp->fl == 1) if(ltp->fl == 1)
{ {
l_get(n,v,afl);/* *v=lt[n].val;*/ 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 else
{ {
if(cll_fl) { if(cll_fl == CHEAP) {
b=cll_get(); b=cll_get();
} else
if(cll_fl == UNNAMED_DEF) {
b_get(&b); // b=unn_get();
} else { } else {
b_get(&b); 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=afile->la.lt+(*x);
ltp->is_cll = cll_fl; 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) if(!er)
{ {
@ -414,7 +482,7 @@ void l_addocc(int n, int *v, int *afl) {
} }
/* for the list functionality */ /* 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; ltp=afile->la.lt+n;
*is_cll = ltp->is_cll; *is_cll = ltp->is_cll;
return ltp->n; return ltp->n;
@ -424,7 +492,32 @@ int l_get(int n, int *v, int *afl)
{ {
if(crossref) l_addocc(n,v,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; (*v)=ltp->val;
lz=ltp->n; lz=ltp->n;
*afl = ltp->afl; *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; 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) { if(!afile->la.lt) {
// ... does not exist yet, so malloc it
afile->la.lti = 0; afile->la.lti = 0;
afile->la.ltm = 1000; afile->la.ltm = 1000;
afile->la.lt = malloc(afile->la.ltm * sizeof(Labtab)); afile->la.lt = malloc(afile->la.ltm * sizeof(Labtab));
} }
if(afile->la.lti>=afile->la.ltm) { if(afile->la.lti>=afile->la.ltm) {
// ... or is at its capacity limit, so realloc it
afile->la.ltm *= 1.5; afile->la.ltm *= 1.5;
afile->la.lt = realloc(afile->la.lt, afile->la.ltm * sizeof(Labtab)); afile->la.lt = realloc(afile->la.lt, afile->la.ltm * sizeof(Labtab));
} }
@ -472,21 +569,19 @@ static int ll_def(char *s, int *n, int b) /* definiert naechstes Label
fprintf(stderr, "Oops: no memory!\n"); fprintf(stderr, "Oops: no memory!\n");
exit(1); 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]=='_')) // current pointer in label table
{ ltp = afile->la.lt + afile->la.lti;
s2[j]=s[j];
j++; 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++; while((s[j]!='\0') && (isalnum(s[j]) || (s[j]=='_'))) j++;
}
s2 = malloc(j+1); s2 = malloc(j+1);
if(!s2) { if(!s2) {
fprintf(stderr,"Oops: no memory!\n"); fprintf(stderr,"Oops: no memory!\n");
@ -494,28 +589,31 @@ static int ll_def(char *s, int *n, int b) /* definiert naechstes Label
} }
strncpy(s2,s,j); strncpy(s2,s,j);
s2[j]=0; s2[j]=0;
/* }
if(j<MAXLAB)
{ // init new entry in label table
*/
er=E_OK; er=E_OK;
ltp->len=j; ltp->len=j; // length of label
ltp->n = s2; ltp->n = s2; // name of label (char*)
ltp->blk=b; ltp->blk=b; // block number
ltp->fl=0; ltp->fl=0;
ltp->afl=0; ltp->afl=0;
ltp->is_cll=0; ltp->is_cll=ltype; // STD, CHEAP, or UNNAMED label
ltp->occlist=NULL; ltp->occlist=NULL;
hash=hashcode(s,j); hash=hashcode(s,j); // compute hashcode
ltp->nextindex=afile->la.hashindex[hash]; ltp->nextindex=afile->la.hashindex[hash]; // and link in before last entry with same hashcode
afile->la.hashindex[hash]=afile->la.lti; afile->la.hashindex[hash]=afile->la.lti; // set as start of list for that hashcode
*n=afile->la.lti;
afile->la.lti++; // TODO: does not work across files!
/* lni+=j+1;*/ ltp->blknext = -1; // no next block
/* } ltp->blkprev = b_link( afile->la.lti ); // previous block, linked within block
}
*/ ltp = afile->la.lt + ltp->blkprev;
/*printf("ll_def return: %d\n",er);*/ 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); 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) * set of blocks (in the block stack)
* *
* If cll_fl is set, the label is also searched in the local cheap label scope * 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; 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++); for (k=0;(k<j)&&(ltp->n[k]==s[k]);k++);
if (cll_fl) { if (cll_fl == CHEAP) {
if (ltp->blk == cll_getcur()) { if (ltp->blk == cll_getcur()) {
er=E_OK; er=E_OK;
break; break;
} }
} else
if (cll_fl == UNNAMED) {
// TODO
} else { } else {
/* check if the found label is in any of the blocks in the /* check if the found label is in any of the blocks in the
current block stack */ current block stack */
@ -584,7 +687,7 @@ int ll_pdef(char *t)
{ {
int n; int n;
if(ll_search(t,&n, 0)==E_OK) if(ll_search(t,&n, STD)==E_OK)
{ {
ltp=afile->la.lt+n; ltp=afile->la.lt+n;
if(ltp->fl) if(ltp->fl)
@ -643,6 +746,7 @@ int l_write(FILE *fp)
* a specific block number is contained in the current block stack. * a specific block number is contained in the current block stack.
*/ */
static int bt[MAXBLK]; /* 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 bi; /* length of the block stack (minus 1, i.e. bi[bi] has the innermost block) */
static int blk; /* current block number for allocation */ static int blk; /* current block number for allocation */
@ -651,6 +755,7 @@ int b_init(void)
blk =0; blk =0;
bi =0; bi =0;
bt[bi]=blk; bt[bi]=blk;
labind[bi]=-1;
return(E_OK); return(E_OK);
} }
@ -679,7 +784,9 @@ int b_open(void)
if(bi<MAXBLK-1) if(bi<MAXBLK-1)
{ {
bt[++bi]=b_new(); bi++;
bt[bi]=b_new();
labind[bi] = -1;
er=E_OK; er=E_OK;
} }
@ -700,6 +807,7 @@ int b_close(void)
return E_BLOCK; return E_BLOCK;
} }
cll_clear(); cll_clear();
//unn_clear();
return(E_OK); 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); 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;
}

View File

@ -27,6 +27,7 @@
*/ */
extern char *lz; extern char *lz;
int l_init(void); int l_init(void);
int ga_lab(void); int ga_lab(void);
int gm_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_def(char *s, int* l, int *x, int *f);
int l_search(char *s, int *l, int *x, int *v, int *afl); int l_search(char *s, int *l, int *x, int *v, int *afl);
void l_set(int n, 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_get(int n, int *v, int *afl);
int l_vget(int n, int *v, char **s); 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 ll_pdef(char *t);
int b_open(void); int b_open(void);

View File

@ -53,10 +53,13 @@ FILE *xfopen(const char *fn,const char *mode)
return NULL; return NULL;
} }
// copy to xname by replacing windows backslashes with the proper DIRCHAR
for(i=0;i<l+1;i++) { for(i=0;i<l+1;i++) {
xname[i]=((fn[i]=='\\')?DIRCHAR:fn[i]); xname[i]=((fn[i]=='\\')?DIRCHAR:fn[i]);
} }
//printf("name=%s, xname=%s, mode=%s\n",fn,xname, mode);
if(mode[0]=='r') if(mode[0]=='r')
{ {
if((file=fopen(fn,mode))==NULL if((file=fopen(fn,mode))==NULL
@ -68,7 +71,6 @@ FILE *xfopen(const char *fn,const char *mode)
strcpy(n2,n); strcpy(n2,n);
strcat(n2,xname); strcat(n2,xname);
strcat(n,fn); strcat(n,fn);
/* printf("name=%s,n2=%s,mode=%s\n",n,n2,mode); */
file=fopen(n,mode); file=fopen(n,mode);
if(!file) file=fopen(n2,mode); if(!file) file=fopen(n2,mode);
} }
@ -87,7 +89,6 @@ FILE *xfopen(const char *fn,const char *mode)
strcpy(n2,n); strcpy(n2,n);
strcat(n2,xname); strcat(n2,xname);
strcat(n,fn); strcat(n,fn);
/* printf("name=%s,n2=%s,mode=%s\n",n,n2,mode); */
file=fopen(n,mode); file=fopen(n,mode);
if(!file) file=fopen(n2,mode); if(!file) file=fopen(n2,mode);
} }

View File

@ -131,7 +131,7 @@ int pp_ifldef(char *t)
int pp_iflused(char *t) int pp_iflused(char *t)
{ {
int n; int n;
loopfl=(loopfl<<1)+( ll_search(t,&n,0) ? 1 : 0 ); loopfl=(loopfl<<1)+( ll_search(t,&n,STD) ? 1 : 0 );
return(0); return(0);
} }

View File

@ -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 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); 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 */ /* assembly mnemonics and pseudo-op tokens */
/* ina and dea don't work yet */ /* ina and dea don't work yet */
/* Note AF 20110624: added some ca65 compatibility pseudo opcodes, /* 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", ".zero",".fopt", ".byte", ".end", ".list", ".xlist", ".dupb", ".blkb", ".db", ".dw",
".align",".block", ".bend",".al",".as",".xl",".xs", ".bin", ".aasc", ".code", ".align",".block", ".bend",".al",".as",".xl",".xs", ".bin", ".aasc", ".code",
".include", ".import", ".importzp", ".proc", ".endproc", ".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 Kzeropage Lastbef+36 /* mapped to Kzero */
#define Korg Lastbef+37 /* mapped to Kpcdef - with parameter equivalent to "*=$abcd" */ #define Korg Lastbef+37 /* mapped to Kpcdef - with parameter equivalent to "*=$abcd" */
#define Krelocx Lastbef+38 /* mapped to Kpcdef - without parameter equivalent to "*=" */ #define Krelocx Lastbef+38 /* mapped to Kpcdef - without parameter equivalent to "*=" */
#define Klistbytes (Lastbef+39-256)
/* last valid token+1 */ /* 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) */ #define Kreloc (Anzkey-256) /* *= (relocation mode) */
@ -434,7 +437,7 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
#if 0 #if 0
printf("t_conv (er=%d):",er); printf("t_conv (er=%d):",er);
for(i=0;i<l;i++) for(i=0;i<l;i++)
printf("%02x,",t[i]); printf("%02x,",t[i] & 0xff);
printf("\n"); printf("\n");
#endif #endif
@ -444,7 +447,6 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
afile->base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length(); afile->base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length();
romable=1; romable=1;
} }
if(!er) if(!er)
{ {
@ -453,7 +455,9 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
* pseudo-op dispatch (except .byt, .asc) * pseudo-op dispatch (except .byt, .asc)
* *
*/ */
n=t[0]; // fix sign
n=t[0]; // & 0xff;
/* TODO: make that a big switch statement... */ /* TODO: make that a big switch statement... */
/* maybe later. Cameron */ /* maybe later. Cameron */
@ -486,6 +490,17 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
set_fopt(l,t,nk+1-na1+na2); set_fopt(l,t,nk+1-na1+na2);
*ll = 0; *ll = 0;
} else } 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) if(n==Kpcdef)
{ {
int tmp; int tmp;
@ -636,7 +651,6 @@ printf(" wrote %02x %02x %02x %02x %02x %02x, %02x, %02x\n",
char binfnam[255]; char binfnam[255];
int offset; int offset;
int length; int length;
int fstart;
i = 1; i = 1;
j = 0; j = 0;
@ -672,7 +686,7 @@ printf(" wrote %02x %02x %02x %02x %02x %02x, %02x, %02x\n",
if (!er) { if (!er) {
int k; int k;
fstart = i; //fstart = i;
if(t[i]=='\"') { if(t[i]=='\"') {
i++; i++;
k=t[i]+i+1; 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 rlt[3]; /* relocation table */
static int lab[3]; /* undef. label table */ static int lab[3]; /* undef. label table */
er=E_OK; er=E_OK;
bl=0; bl=0;
if(*ll<0) /* <0 when E_OK, >0 when E_OKDEF */ 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; pc[segment] = npc;
/*printf("Kreloc: newsegment=%d, pc[seg]=%04x\n", segment, pc[segment]);*/ /*printf("Kreloc: newsegment=%d, pc[seg]=%04x\n", segment, pc[segment]);*/
} else } 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) { if(n==Ksegment) {
segment = t[1]; segment = t[1];
*ll=0; *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 p,q,ll,mk,er;
int ud; /* counts undefined labels */ int ud; /* counts undefined labels */
int n; /* label number to be passed between l_def (definition) and l_set (set the value) */ 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 */ int uz; /* unused at the moment */
/*static unsigned char cast;*/ /*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 */ fl=0; /* 1 = pass text thru */
afl=0; /* pointer flag for label */ afl=0; /* pointer flag for label */
while(s[p]==' ') p++; while(isspace(s[p])) p++;
n=T_END; n=T_END;
/*cast='\0';*/ /*cast='\0';*/
@ -1863,6 +1886,27 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
{ {
while(s[p]!='\0' && s[p]!=';') 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? */ /* is keyword? */
if(!(er=t_keyword(s+p,&ll,&n))) if(!(er=t_keyword(s+p,&ll,&n)))
@ -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) if(er && er!=E_NOKEY)
break; 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))) if((er=l_def((char*)s+p,&ll,&n,&f)))
break; break;
p+=ll; p+=ll;
while(s[p]==' ') p++; while(isspace(s[p])) p++;
if(s[p]=='=') if(s[p]=='=')
{ {
@ -2012,9 +2057,27 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
} else } else
/* maybe it's a label /* maybe it's a label
Note that for ca65 cheap local labels, we check for "@" */ 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); er=l_search((char*)s+p,&ll,&n,&v,&afl);
/* /*
if(m==Kglobl || m==Kextzero) { if(m==Kglobl || m==Kextzero) {
@ -2059,6 +2122,7 @@ fprintf(stderr, "could not find %s\n", (char *)s+p);
} }
p+=ll; p+=ll;
} }
}
else else
if(s[p]<='9' && s[p]>='0') 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) if(!er)
{ {
/* /*
@ -2260,20 +2325,28 @@ fprintf(stderr, "could not find %s\n", (char *)s+p);
return(er); 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) 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]!='*' ) if(!isalpha(s[0]) && s[0]!='.' && s[0]!='*' )
return(E_NOKEY); return(E_NOKEY);
// if first char is a character, use it as hash...
if(isalpha(s[0])) if(isalpha(s[0]))
hash=tolower(s[0])-'a'; hash=tolower(s[0])-'a';
else else
hash=26; hash=26;
// check for "*="
if(s[0]=='*') { if(s[0]=='*') {
j=1; j=1;
while(s[j] && isspace(s[j])) j++; while(s[j] && isspace(s[j])) j++;
@ -2282,9 +2355,14 @@ static int t_keyword(signed char *s, int *l, int *n)
j++; j++;
} }
} }
// no keyword yet found?
if(!i) { 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]; i=ktp[hash];
hash=ktp[hash+1]; hash=ktp[hash+1];
// check all entries in opcode table from start to end for that hash code
while(i<hash) while(i<hash)
{ {
j=0; j=0;
@ -2457,6 +2535,8 @@ static int list_lineno = 1; /* current line number */
static int list_last_lineno = 0; /* current line number */ static int list_last_lineno = 0; /* current line number */
static char *list_filenamep = NULL; /* current file name pointer */ 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_string(char *buf, char *string);
static int list_tokens(char *buf, signed char *input, int len); static int list_tokens(char *buf, signed char *input, int len);
static int list_value(char *buf, int val, signed char format); 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_byte_f(char *buf, int outbyte, signed char format);
static int list_nibble_f(char *buf, int outnib, 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 */ /* set line number for the coming listing output */
void list_line(int l) { void list_line(int l) {
list_lineno = 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 "..." */ /* binary output (up to 8 byte. If more than 8 byte, print 7 plus "..." */
n_hexb = bincode_len; n_hexb = bincode_len;
if (n_hexb >= 8) { if (list_numbytes != 0 && n_hexb >= list_numbytes) {
n_hexb = 7; n_hexb = list_numbytes-1;
} }
for (i = 0; i < n_hexb; i++) { for (i = 0; i < n_hexb; i++) {
buf = buf + list_byte(buf, bincode[i]); buf = buf + list_byte(buf, bincode[i]);
@ -2593,7 +2678,7 @@ int list_tokens(char *buf, signed char *input, int len) {
int tmp; int tmp;
char *name; char *name;
signed char c; signed char c;
int is_cll; label_t is_cll;
int tabval; int tabval;
signed char format; 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); tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255);
/*printf("define: len=%d, inp=%d, tmp=%d\n", len, inp, tmp);*/ /*printf("define: len=%d, inp=%d, tmp=%d\n", len, inp, tmp);*/
name=l_get_name(tmp, &is_cll); name=l_get_name(tmp, &is_cll);
if (is_cll) outp += list_char(buf+outp, '@'); 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); tmp = list_string(buf+outp, name);
tabval += tmp + 1 + is_cll; tabval += tmp + 1 + is_cll;
outp += tmp; outp += tmp;
}
outp += list_char(buf+outp, ' '); outp += list_char(buf+outp, ' ');
inp += 3; inp += 3;
tmp = input[inp] & 255; tmp = input[inp] & 255;
@ -2668,8 +2760,15 @@ int list_tokens(char *buf, signed char *input, int len) {
/* 16 bit label number */ /* 16 bit label number */
tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255); tmp = ((input[inp+2]&255)<<8) | (input[inp+1]&255);
name=l_get_name(tmp, &is_cll); name=l_get_name(tmp, &is_cll);
if (is_cll) outp += list_char(buf+outp, '@'); 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); outp += list_string(buf+outp, name);
}
inp += 3; inp += 3;
operator = 1; /* check if arithmetic operator follows */ operator = 1; /* check if arithmetic operator follows */
break; break;

View File

@ -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 binclude/ Binary include code with some weird casing
chppch/ Changing preprocessor characters (-p) chppch/ Changing preprocessor characters (-p)
charset/ Tests of when charsets should be honoured and when not charset/ Tests of when charsets should be honoured and when not
cc65/ Compatibility tests for ca65 compatibility
Cameron Kaiser, André Fachat Cameron Kaiser, André Fachat