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:
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)
|
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')
|
}
|
||||||
break; /* hkfl = comcom = 0 */
|
if (c=='\0') {
|
||||||
|
// end of line
|
||||||
|
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)) {
|
||||||
@ -1131,7 +1137,10 @@ static int getline(char *s)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
19
xa/src/xah.h
19
xa/src/xah.h
@ -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 {
|
||||||
|
245
xa/src/xal.c
245
xa/src/xal.c
@ -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=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)
|
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=ll_search(s,&n, cll_fl);
|
er = E_NODEF;
|
||||||
/*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());*/
|
if (cll_fl != UNNAMED_DEF) {
|
||||||
|
er=ll_search(s,&n, cll_fl);
|
||||||
|
}
|
||||||
|
|
||||||
|
//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,50 +569,51 @@ 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) {
|
||||||
while((s[j]!='\0') && (isalnum(s[j]) || (s[j]=='_'))) j++;
|
// unnamed lables are like ":--" or ":+" with variable length
|
||||||
s2 = malloc(j+1);
|
while((s[j]!='\0') && (s[j]=='+' || s[j]=='-')) j++;
|
||||||
if(!s2) {
|
} 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");
|
fprintf(stderr,"Oops: no memory!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
|
strncpy(s2,s,j);
|
||||||
|
s2[j]=0;
|
||||||
}
|
}
|
||||||
strncpy(s2,s,j);
|
|
||||||
s2[j]=0;
|
// init new entry in label table
|
||||||
/*
|
|
||||||
if(j<MAXLAB)
|
|
||||||
{
|
|
||||||
*/
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 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]=='=')
|
||||||
{
|
{
|
||||||
@ -2010,11 +2055,29 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
|
|||||||
{
|
{
|
||||||
t[q++]=s[p++];
|
t[q++]=s[p++];
|
||||||
} 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) {
|
||||||
@ -2058,6 +2121,7 @@ fprintf(stderr, "could not find %s\n", (char *)s+p);
|
|||||||
er=E_OK;
|
er=E_OK;
|
||||||
}
|
}
|
||||||
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) {
|
||||||
tmp = list_string(buf+outp, name);
|
outp += list_char(buf+outp, '@');
|
||||||
tabval += tmp + 1 + is_cll;
|
} else
|
||||||
outp += tmp;
|
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, ' ');
|
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_string(buf+outp, name);
|
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;
|
inp += 3;
|
||||||
operator = 1; /* check if arithmetic operator follows */
|
operator = 1; /* check if arithmetic operator follows */
|
||||||
break;
|
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
|
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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user