1
0
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:
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)
{
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);

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)
{
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;

View File

@ -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 {

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

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 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;

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
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