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

added ca65 compatibiltiy patch

This commit is contained in:
Andre Fachat
2011-12-16 23:22:32 +01:00
parent ac0f09ba77
commit f28af4a917
10 changed files with 303 additions and 59 deletions

View File

@@ -19,6 +19,9 @@ further in this manual page.
.SH OPTIONS .SH OPTIONS
.TP .TP
.B \-E
Do not stop after 20 errors, but show all errors.
.TP
.B \-v .B \-v
Verbose output. Verbose output.
.TP .TP
@@ -67,9 +70,18 @@ to reconstruct source.
Add cross-reference list to labellist (requires Add cross-reference list to labellist (requires
.BR \-l ). .BR \-l ).
.TP .TP
.B \-Xcompatset
Enables compatibility settings to become more (not fully!) compatible with other 6502 assemblers.
Currently supported are compatibility set "MASM" and "CA65".
"MASM" allows colons to appear in comments. This does not affect colon interpretation elsewhere.
"CA65" allows the ":=" label definition (instead of "="), and also the "cheap local labels" using
the "@" character. This, however, disables the "@" 24-bit enforcement.
.TP
.B \-M .B \-M
Allow colons to appear in comments; for MASM compatibility. This does Allow colons to appear in comments; for MASM compatibility. This does
not affect colon interpretation elsewhere. not affect colon interpretation elsewhere. This option is deprecated. Use
.BR -X
instead.
.TP .TP
.B \-R .B \-R
Start assembler in relocating mode. Start assembler in relocating mode.
@@ -339,7 +351,7 @@ for those opcodes that support it (i.e., keep as 16 bit word)
.B @ .B @
render as 24-bit quantity for 65816 (must specify render as 24-bit quantity for 65816 (must specify
.B \-w .B \-w
command-line option). command-line option, must not specify the CA65 compatibility).
.B This is required to specify any .B This is required to specify any
.B 24-bit quantity! .B 24-bit quantity!
.TP .TP
@@ -538,6 +550,9 @@ space for allocation and .zero being uninitialized zero page space for
allocation. In .bss and .zero, only labels are evaluated. These pseudo-ops allocation. In .bss and .zero, only labels are evaluated. These pseudo-ops
are valid in relative and absolute modes. are valid in relative and absolute modes.
.TP .TP
.B .code
For CA65 compatibility this is currently mapped to ".text".
.TP
.B .align value .B .align value
Aligns the current segment to a byte boundary (2, 4 or 256) as specified by Aligns the current segment to a byte boundary (2, 4 or 256) as specified by
.B .B

View File

@@ -61,7 +61,10 @@
/* exported globals */ /* exported globals */
int ncmos, cmosfl, w65816, n65816; int ncmos, cmosfl, w65816, n65816;
int masm = 0; /* compatibility flags */
int masm = 0; /* MASM */
int ca65 = 0; /* CA65 */
int nolink = 0; int nolink = 0;
int romable = 0; int romable = 0;
int romaddr = 0; int romaddr = 0;
@@ -71,10 +74,12 @@ int crossref = 0;
char altppchar; char altppchar;
/* local variables */ /* local variables */
static char out[MAXLINE]; static char out[MAXLINE];
static time_t tim1, tim2; static time_t tim1, tim2;
static FILE *fpout, *fperr, *fplab; static FILE *fpout, *fperr, *fplab;
static int ner = 0; static int ner = 0;
static int ner_max = 20;
static int align = 1; static int align = 1;
@@ -91,6 +96,7 @@ static int getline(char *);
static void lineout(void); static void lineout(void);
static long ga_p1(void); static long ga_p1(void);
static long gm_p1(void); static long gm_p1(void);
static int set_compat(char *compat_name);
/* text */ /* text */
int memode,xmode; int memode,xmode;
@@ -191,6 +197,9 @@ int main(int argc,char *argv[])
while(i<argc) { while(i<argc) {
if(argv[i][0]=='-') { if(argv[i][0]=='-') {
switch(argv[i][1]) { switch(argv[i][1]) {
case 'E':
ner_max = 0;
break;
case 'p': case 'p':
/* intentionally not allowing an argument to follow with a /* intentionally not allowing an argument to follow with a
space to avoid - being seen as the alternate space to avoid - being seen as the alternate
@@ -210,6 +219,19 @@ int main(int argc,char *argv[])
case 'M': case 'M':
masm = 1; /* MASM compatibility mode */ masm = 1; /* MASM compatibility mode */
break; break;
case 'X': /* compatibility across assemblers... */
{
char *name = NULL;
if (argv[i][2] == 0) {
name = argv[++i];
} else {
name = argv[i]+2;
}
if (set_compat(name) < 0) {
fprintf(stderr, "Compatibility set '%s' unknown - ignoring! (check case?)\n", name);
}
}
break;
case 'O': /* output charset */ case 'O': /* output charset */
{ {
char *name = NULL; char *name = NULL;
@@ -500,7 +522,12 @@ int main(int argc,char *argv[])
if(ner || er) if(ner || er)
{ {
if (ner_max > 0) {
fprintf(stderr, "Break after %d error%c\n",ner,ner?'s':0); fprintf(stderr, "Break after %d error%c\n",ner,ner?'s':0);
} else {
/* ner_max==0, i.e. show all errors */
fprintf(stderr, "End after %d error%c\n",ner,ner?'s':0);
}
/*unlink();*/ /*unlink();*/
if(ofile) { if(ofile) {
unlink(ofile); unlink(ofile);
@@ -615,7 +642,7 @@ static int pass2(void)
filep=&datei; filep=&datei;
afile->mn.tmpe=0L; afile->mn.tmpe=0L;
while(ner<20 && afile->mn.tmpe<afile->mn.tmpz) while((ner_max==0 || ner<ner_max) && afile->mn.tmpe<afile->mn.tmpz)
{ {
l=afile->mn.tmp[afile->mn.tmpe++]; l=afile->mn.tmp[afile->mn.tmpe++];
ll=l; ll=l;
@@ -827,6 +854,7 @@ static void usage(int default816, FILE *fp)
programname); programname);
fprintf(fp, fprintf(fp,
" -v verbose output\n" " -v verbose output\n"
" -E do not break after 20 errors, but show all\n"
" -x old filename behaviour (overrides `-o', `-e', `-l')\n" " -x old filename behaviour (overrides `-o', `-e', `-l')\n"
" This is deprecated and may disappear in future versions!\n" " This is deprecated and may disappear in future versions!\n"
" -C no CMOS-opcodes\n" " -C no CMOS-opcodes\n"
@@ -844,6 +872,8 @@ static void usage(int default816, FILE *fp)
" -l filename sets labellist filename, default is none\n" " -l filename sets labellist filename, default is none\n"
" -r adds crossreference list to labellist (if `-l' given)\n" " -r adds crossreference list to labellist (if `-l' given)\n"
" -M allow ``:'' to appear in comments for MASM compatibility\n" " -M allow ``:'' to appear in comments for MASM compatibility\n"
" -Xcompatset set compatibility flags for other assemblers, known values are:\n"
" MASM, CA65\n"
" -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"
@@ -900,7 +930,7 @@ static char *ertxt[] = {
"NewFile", "NewFile",
"CMOS-Befehl", "CMOS-Befehl",
"pp:Wrong parameter count", "pp:Wrong parameter count",
"Illegal pointer arithmetic", "Illegal pointer arithmetic (-26)",
"Illegal segment", "Illegal segment",
"File header option too long", "File header option too long",
"File option not at file start (when ROM-able)", "File option not at file start (when ROM-able)",
@@ -939,11 +969,10 @@ static char *ertxt[] = {
"", "",
"", "",
"", "",
"",
/* warnings */ /* warnings */
"Cutting word relocation in byte value", "Cutting word relocation in byte value",
"Byte relocation in word value", "Byte relocation in word value",
"Illegal pointer arithmetic", "Illegal pointer arithmetic (-66)",
"Address access to low or high byte pointer", "Address access to low or high byte pointer",
"High byte access to low byte pointer", "High byte access to low byte pointer",
"Low byte access to high byte pointer", "Low byte access to high byte pointer",
@@ -1062,9 +1091,20 @@ static int getline(char *s)
comcom = 1; comcom = 1;
if (c=='\0') if (c=='\0')
break; /* hkfl = comcom = 0 */ break; /* hkfl = comcom = 0 */
if (c==':' && !hkfl && (!comcom || !masm)) { if (c==':' && !hkfl) {
gl=1; /* if the next char is a "=" - so that we have a ":=" - and we
break; we have ca65 compatibility, we ignore the colon */
if (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)) {
/* we found a colon, so we keep the current line in memory
but return the part before the colon, and next time the part
after the colon, so we can parse C64 BASIC text assembler... */
gl=1;
break;
}
}
} }
j++; j++;
} while (c!='\0' && j<MAXLINE-1 && i<MAXLINE-1); } while (c!='\0' && j<MAXLINE-1 && i<MAXLINE-1);
@@ -1072,7 +1112,9 @@ static int getline(char *s)
s[j]='\0'; s[j]='\0';
} else } else
s[0]='\0'; s[0]='\0';
#if 0
printf("got line: %s\n", s);
#endif
return(ec); return(ec);
} }
@@ -1092,8 +1134,8 @@ static void lineout(void)
void errout(int er) void errout(int er)
{ {
if (er<-ANZERR || er>-1) { if (er<=-ANZERR || er>-1) {
if(er>=-(ANZERR+ANZWARN) && er < -ANZERR) { if(er>=-(ANZERR+ANZWARN) && er <= -ANZERR) {
sprintf(out,"%s:line %d: %04x: Warning - %s\n", sprintf(out,"%s:line %d: %04x: Warning - %s\n",
filep->fname, filep->fline, pc[segment], ertxt[(-er)-1]); filep->fname, filep->fline, pc[segment], ertxt[(-er)-1]);
} else { } else {
@@ -1129,3 +1171,30 @@ void logout(char *s)
fprintf(fperr,"%s",s); fprintf(fperr,"%s",s);
} }
/*****************************************************************/
typedef struct {
char *name;
int *flag;
} compat_set;
static compat_set compat_sets[] = {
{ "MASM", &masm },
{ "CA65", &ca65 },
{ NULL, NULL }
};
int set_compat(char *compat_name) {
int i = 0;
while (compat_sets[i].name != NULL) {
if (strcmp(compat_sets[i].name, compat_name) == 0) {
/* set appropriate compatibility flag */
(*compat_sets[i].flag) = 1;
return 0;
}
i++;
}
return -1;
}

View File

@@ -22,7 +22,7 @@
#include "xah.h" /* For SEG_MAX */ #include "xah.h" /* For SEG_MAX */
extern int ncmos, cmosfl, w65816, n65816; extern int ncmos, cmosfl, w65816, n65816;
extern int masm, nolink; extern int masm, ca65, nolink;
extern int noglob; extern int noglob;
extern int showblk; extern int showblk;
extern int relmode; extern int relmode;

View File

@@ -180,6 +180,8 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
} else { } else {
if(segment!=SEG_ABS) { if(segment!=SEG_ABS) {
if(!dsb_len) { if(!dsb_len) {
/*printf("ILLPOINTER=dsb_len=%d,segment=%d\n",dsb_len, segment);*/
/* e.g. adding two pointers, adding two undefined values */
er=E_ILLPOINTER; er=E_ILLPOINTER;
} }
} }

View File

@@ -20,15 +20,22 @@
#ifndef __XA65_XAH_H__ #ifndef __XA65_XAH_H__
#define __XA65_XAH_H__ #define __XA65_XAH_H__
#define ANZLAB 5000 /* mal 14 -> Byte */ /*
* Note: the computations to get the number of bytes necessary to allocate are
* a historic remnant of the Atari ST (the original platform) not being able to efficiently allocate small chunks
* of memory so I had to allocate a large chunk myself and manage the tables myself.
* This has changed and some parts of xa65 are modified to just do a malloc() now.
* These fixed numbers should actually go away. AF 20110623
*/
#define ANZLAB 5000 /* multiplied by sizeof(Labtab) -> Byte */
#define LABMEM 40000L #define LABMEM 40000L
#define MAXLAB 32 #define MAXLAB 32
#define MAXBLK 16 #define MAXBLK 16
#define MAXFILE 7 #define MAXFILE 7
#define MAXLINE 2048 #define MAXLINE 2048
#define MAXPP 40000L #define MAXPP 40000L
#define ANZDEF 2340 /* mal 14 -> Byte, ANZDEF * 14 < 32768 */ #define ANZDEF 2340 /* multiplied by sizeof(List) -> Byte, ANZDEF * 20 < 32768 */
#define TMPMEM 200000L /* Zwischenspeicher von Pass1 nach Pass 2 */ #define TMPMEM 200000L /* temporary memory buffer from Pass1 to Pass 2 */
typedef struct LabOcc { typedef struct LabOcc {
struct LabOcc *next; struct LabOcc *next;

View File

@@ -50,6 +50,12 @@ 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);
static int b_new(void);
static void cll_init();
static int cll_get();
static void cll_clear();
static int cll_getcur();
/* local variables */ /* local variables */
/* /*
@@ -69,6 +75,7 @@ static Labtab *ltp;
int l_init(void) int l_init(void)
{ {
cll_init();
return 0; return 0;
#if 0 #if 0
int er; int er;
@@ -139,10 +146,49 @@ FILE *fp;
} }
} }
/**********************************************************************************
* cheap local labels
*/
static int cll_current = 0; /* the current cheap local labels block */
/**
* init the cheap local labels
*/
void cll_init() {
cll_current = 0;
}
/**
* get the block number for a new cheap local label block
*/
int cll_get() {
if (cll_current == 0) {
cll_current = b_new();
}
return cll_current;
}
/**
* clear the local labels
*/
void cll_clear() {
cll_current = 0;
}
int cll_getcur() {
return cll_current;
}
/**********************************************************************************/
/**
* define a global label
*/
int lg_set(char *s ) { int lg_set(char *s ) {
int n, er; int n, er;
er = ll_search(s,&n); er = ll_search(s,&n, 0);
if(er==E_OK) { if(er==E_OK) {
fprintf(stderr,"Warning: global label doubly defined!\n"); fprintf(stderr,"Warning: global label doubly defined!\n");
@@ -156,52 +202,73 @@ int lg_set(char *s ) {
return er; return er;
} }
/**********************************************************************************/
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;
*f=0; *f=0; /* flag (given as param) that the label is to be re-defined and the
b=0; "label defined error" is to be skipped */
n=0; 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 */
if(s[0]=='-') if(s[0]=='-')
{ {
*f+=1; *f+=1; /* label is being redefined */
i++; i++;
} else } else
if(s[0]=='@')
{
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... */
} else
if(s[0]=='+') if(s[0]=='+')
{ {
i++; i++;
n++; n++; /* block number b is absolute */
b=0; b=0; /* global block number */
} }
while(s[i]=='&') while(s[i]=='&')
{ {
n=0; if (n) b=0; /* reset block number */
n=0; /* block number is relative */
i++; i++;
b++; b++; /* one (more) level up the block stack */
} }
if(!n) if(!n) {
/* translate from block stack level to absolute block number */
b_fget(&b,b); b_fget(&b,b);
}
if(!cll_fl) {
/* clear cheap local labels */
cll_clear();
}
if(!isalpha(s[i]) && s[i]!='_') if(!isalpha(s[i]) && s[i]!='_' && !(ca65 && isdigit(s[i]) ) )
er=E_SYNTAX; er=E_SYNTAX;
else else
{ {
er=ll_search(s+i,&n); er=ll_search(s+i,&n, cll_fl);
if(er==E_OK) if(er==E_OK)
{ {
/* we actually found an existing label in the same scope */
ltp=afile->la.lt+n; ltp=afile->la.lt+n;
if(*f) if(*f)
{ {
/* redefinition of label */
*l=ltp->len+i; *l=ltp->len+i;
} else } else
if(ltp->fl==0) if(ltp->fl==0)
{ {
/* label has not been defined yet, (e.g. pass1 forward ref), so we try to set it. */
*l=ltp->len+i; *l=ltp->len+i;
if(b_ltest(ltp->blk,b)) if(b_ltest(ltp->blk,b))
er=E_LABDEF; er=E_LABDEF;
@@ -213,7 +280,7 @@ 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))) /* ll_def(...,*f) */ if(!(er=ll_def(s+i,&n,b))) /* 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;
@@ -229,15 +296,23 @@ 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;
*afl=0; *afl=0;
er=ll_search(s,&n); /* check cheap local label */
/*printf("l_search: lab=%s(l=%d), afl=%d, er=%d, n=%d\n",s,*l, *afl,er,n);*/ cll_fl=0;
if (s[0]=='@') {
cll_fl=1; /* also used as offset to the label length, so must be 1 */
s++;
}
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());*/
if(er==E_OK) if(er==E_OK)
{ {
ltp=afile->la.lt+n; ltp=afile->la.lt+n;
*l=ltp->len; *l=ltp->len + cll_fl;
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;*/
@@ -251,12 +326,17 @@ int l_search(char *s, int *l, int *x, int *v, int *afl)
} }
else else
{ {
b_get(&b); if(cll_fl) {
b=cll_get();
} else {
b_get(&b);
}
er=ll_def(s,x,b); /* ll_def(...,*v); */ er=ll_def(s,x,b); /* ll_def(...,*v); */
ltp=afile->la.lt+(*x); ltp=afile->la.lt+(*x);
*l=ltp->len; *l=ltp->len + cll_fl;
if(!er) if(!er)
{ {
@@ -401,8 +481,14 @@ static int ll_def(char *s, int *n, int b) /* definiert naechstes Label
return(er); return(er);
} }
/**
int ll_search(char *s, int *n) /* search Label in Tabelle ,nr->n */ * search a label name in the label table. Return the label number
* in "n". Finds only labels that are in a block that is in the current
* set of blocks (in the block stack)
*
* If cll_fl is set, the label is also searched in the local cheap label scope
*/
int ll_search(char *s, int *n, int 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;
@@ -411,7 +497,6 @@ int ll_search(char *s, int *n) /* search Label in Tabelle ,nr->n */
hash=hashcode(s,j); hash=hashcode(s,j);
i=afile->la.hashindex[hash]; i=afile->la.hashindex[hash];
/*printf("search?\n");*/
if(i>=afile->la.ltm) return E_NODEF; if(i>=afile->la.ltm) return E_NODEF;
do do
@@ -422,11 +507,21 @@ int ll_search(char *s, int *n) /* search Label in Tabelle ,nr->n */
{ {
for (k=0;(k<j)&&(ltp->n[k]==s[k]);k++); for (k=0;(k<j)&&(ltp->n[k]==s[k]);k++);
if((j==k)&&(!b_test(ltp->blk))) if (cll_fl) {
{ if (ltp->blk == cll_getcur()) {
er=E_OK; er=E_OK;
break; break;
} }
} else {
/* check if the found label is in any of the blocks in the
current block stack */
if((j==k)&&(!b_test(ltp->blk)))
{
/* ok, label found and it is reachable (its block nr is in the current block stack */
er=E_OK;
break;
}
}
} }
if(!i) if(!i)
@@ -451,7 +546,7 @@ int ll_pdef(char *t)
{ {
int n; int n;
if(ll_search(t,&n)==E_OK) if(ll_search(t,&n, 0)==E_OK)
{ {
ltp=afile->la.lt+n; ltp=afile->la.lt+n;
if(ltp->fl) if(ltp->fl)
@@ -496,9 +591,22 @@ int l_write(FILE *fp)
return 0; return 0;
} }
static int bt[MAXBLK]; /*******************************************************************************************
static int blk; * block management code. Here the ".(" and ".)" blocks are maintained.
static int bi; *
* Blocks are numbered uniquely, every time a new block is opened, the "blk" variable
* is increased and its number used as block number.
*
* The currently open blocks are maintained in a stack (bt[]). The lowest entry is the outermost
* block number, adding block numbers as blocks are opened. When a block is closed,
* the block stack is shortened again (bi has the length of the block stack)
*
* Methods exist to open new blocks, close a block, and do some checks, e.g. whether
* a specific block number is contained in the current block stack.
*/
static int bt[MAXBLK]; /* block stack */
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 */
int b_init(void) int b_init(void)
{ {
@@ -509,6 +617,11 @@ int b_init(void)
return(E_OK); return(E_OK);
} }
int b_new(void)
{
return ++blk;
}
int b_depth(void) int b_depth(void)
{ {
return bi; return bi;
@@ -519,19 +632,25 @@ int ga_blk(void)
return(blk); return(blk);
} }
/**
* open a new block scope
*/
int b_open(void) int b_open(void)
{ {
int er=E_BLKOVR; int er=E_BLKOVR;
if(bi<MAXBLK-1) if(bi<MAXBLK-1)
{ {
bt[++bi]=++blk; bt[++bi]=b_new();
er=E_OK; er=E_OK;
} }
return(er); return(er);
} }
/**
* close a block scope
*/
int b_close(void) int b_close(void)
{ {
@@ -546,6 +665,9 @@ int b_close(void)
return(E_OK); return(E_OK);
} }
/**
* get the block number of the current innermost block
*/
static int b_get(int *n) static int b_get(int *n)
{ {
*n=bt[bi]; *n=bt[bi];
@@ -553,6 +675,9 @@ static int b_get(int *n)
return(E_OK); return(E_OK);
} }
/**
* returns the block number of the block "i" levels up in the current block stack
*/
static int b_fget(int *n, int i) static int b_fget(int *n, int i)
{ {
if((bi-i)>=0) if((bi-i)>=0)
@@ -562,6 +687,10 @@ static int b_fget(int *n, int i)
return(E_OK); return(E_OK);
} }
/**
* tests whether the given block number n is in the current stack of
* current block numbers bt[]
*/
static int b_test(int n) static int b_test(int n)
{ {
int i=bi; int i=bi;
@@ -572,6 +701,9 @@ static int b_test(int n)
return( i+1 ? E_OK : E_NOBLK ); return( i+1 ? E_OK : E_NOBLK );
} }
/**
* tests whether the given block number "a" is in the
*/
static int b_ltest(int a, int b) /* testet ob bt^-1(b) in intervall [0,bt^-1(a)] */ static int b_ltest(int a, int b) /* testet ob bt^-1(b) in intervall [0,bt^-1(a)] */
{ {
int i=0,er=E_OK; int i=0,er=E_OK;

View File

@@ -42,7 +42,7 @@ 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);
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 ll_search(char *s, int *n, int cll_fl);
int ll_pdef(char *t); int ll_pdef(char *t);
int b_open(void); int b_open(void);

View File

@@ -130,7 +130,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) ? 1 : 0 ); loopfl=(loopfl<<1)+( ll_search(t,&n,0) ? 1 : 0 );
return(0); return(0);
} }

View File

@@ -75,7 +75,7 @@ static char *kt[] ={
".byt",".word",".asc",".dsb", ".(", ".)", "*=", ".text",".data",".bss", ".byt",".word",".asc",".dsb", ".(", ".)", "*=", ".text",".data",".bss",
".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" ".align",".block", ".bend",".al",".as",".xl",".xs", ".bin", ".aasc", ".code"
}; };
@@ -85,7 +85,7 @@ static int lp[]= { 0,1,1,1,1,2,2,1,1,1,2,2,2,1,1,1,2,2 };
/* last valid mnemonic */ /* last valid mnemonic */
#define Lastbef 93 #define Lastbef 93
/* last valid token+1 */ /* last valid token+1 */
#define Anzkey 123 #define Anzkey 124
#define Kbyt Lastbef+1 #define Kbyt Lastbef+1
#define Kword Lastbef+2 #define Kword Lastbef+2
@@ -119,6 +119,8 @@ static int lp[]= { 0,1,1,1,1,2,2,1,1,1,2,2,2,1,1,1,2,2 };
#define Kbin Lastbef+28 #define Kbin Lastbef+28
#define Kaasc Lastbef+29 #define Kaasc Lastbef+29
#define Kcode Lastbef+30 /* gets remapped to Ktext */
#define Kreloc Anzkey /* *= (relocation mode) */ #define Kreloc Anzkey /* *= (relocation mode) */
#define Ksegment Anzkey+1 #define Ksegment Anzkey+1
@@ -349,6 +351,7 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
printf("\n"); printf("\n");
*/ */
/* if text/data produced, then no more fopt allowed in romable mode */ /* if text/data produced, then no more fopt allowed in romable mode */
/* TODO: need to check, Kbyte is being remapped to Kbyt. What is the effect here? */
if((romable>1) && (t[0]<Kopen || t[0]==Kbyte || t[0]==Kpcdef)) { if((romable>1) && (t[0]<Kopen || t[0]==Kbyte || t[0]==Kpcdef)) {
afile->base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length(); afile->base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length();
romable=1; romable=1;
@@ -1536,7 +1539,8 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
static int v,f; static int v,f;
static int operand,o; static int operand,o;
int fl,afl; int fl,afl;
int p,q,ud,n,ll,mk,er; int p,q,ud,ll,mk,er;
int n; /* label number to be passed between l_def (definition) and l_set (set the value) */
int m, uz, byte; int m, uz, byte;
static unsigned char cast; static unsigned char cast;
@@ -1586,6 +1590,7 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
if(s[p]=='=') if(s[p]=='=')
{ {
/*printf("Found = @%s\n",s+p);*/
t[q++]=T_OP; t[q++]=T_OP;
t[q++]=n&255; t[q++]=n&255;
t[q++]=(n>>8)&255; t[q++]=(n>>8)&255;
@@ -1594,6 +1599,17 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
ll=n=0; ll=n=0;
break; break;
} else } else
if(s[p]==':' && s[p+1]=='=') /* support := label assignments (ca65 compatibility) */
{
/*printf("Found := @%s\n", s+p);*/
t[q++]=T_OP;
t[q++]=n&255;
t[q++]=(n>>8)&255;
t[q++]='=';
p+=2;
ll=n=0;
break;
} else
if(f && s[p]!='\0' && s[p+1]=='=') if(f && s[p]!='\0' && s[p+1]=='=')
{ {
t[q++]=T_OP; t[q++]=T_OP;
@@ -1674,8 +1690,10 @@ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk,
if(operand) if(operand)
{ {
/* are we forcing the operand into a particular /* are we forcing the operand into a particular
addressing mode? !, @, ` operators */ addressing mode? !, @, ` operators
if(s[p]=='!' || s[p]=='@' || s[p]=='`') Note these are not available in ca65, but we only
switch off "@" which are used for cheap local labels*/
if(s[p]=='!' || (s[p]=='@' && !ca65) || s[p]=='`')
{ {
cast=s[p]; cast=s[p];
operand= -operand+1; operand= -operand+1;
@@ -1691,12 +1709,12 @@ 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
if(isalpha(s[p]) || s[p]=='_') Note that for ca65 cheap local labels, we check for "@" */
if(isalpha(s[p]) || s[p]=='_' || (s[p]=='@' && ca65))
{ {
m=n; 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) {
if(er==E_NODEF) { if(er==E_NODEF) {
@@ -1961,6 +1979,7 @@ static int t_keyword(signed char *s, int *l, int *n)
if(i==Kdw) i=Kword; if(i==Kdw) i=Kword;
if(i==Kblock) i=Kopen; if(i==Kblock) i=Kopen;
if(i==Kbend) i=Kclose; if(i==Kbend) i=Kclose;
if(i==Kcode) i=Ktext;
*l=j; *l=j;