mirror of
https://github.com/fachat/xa65.git
synced 2025-01-01 10:29:19 +00:00
added ca65 compatibiltiy patch
This commit is contained in:
parent
ac0f09ba77
commit
f28af4a917
19
xa/man/xa.1
19
xa/man/xa.1
@ -19,6 +19,9 @@ further in this manual page.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-E
|
||||
Do not stop after 20 errors, but show all errors.
|
||||
.TP
|
||||
.B \-v
|
||||
Verbose output.
|
||||
.TP
|
||||
@ -67,9 +70,18 @@ to reconstruct source.
|
||||
Add cross-reference list to labellist (requires
|
||||
.BR \-l ).
|
||||
.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
|
||||
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
|
||||
.B \-R
|
||||
Start assembler in relocating mode.
|
||||
@ -339,7 +351,7 @@ for those opcodes that support it (i.e., keep as 16 bit word)
|
||||
.B @
|
||||
render as 24-bit quantity for 65816 (must specify
|
||||
.B \-w
|
||||
command-line option).
|
||||
command-line option, must not specify the CA65 compatibility).
|
||||
.B This is required to specify any
|
||||
.B 24-bit quantity!
|
||||
.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
|
||||
are valid in relative and absolute modes.
|
||||
.TP
|
||||
.B .code
|
||||
For CA65 compatibility this is currently mapped to ".text".
|
||||
.TP
|
||||
.B .align value
|
||||
Aligns the current segment to a byte boundary (2, 4 or 256) as specified by
|
||||
.B
|
||||
|
@ -1,4 +1,4 @@
|
||||
OBJ = xa.o xaa.o xal.o xap.o xat.o xar.o xar2.o xao.o xau.o xam.o xacharset.o
|
||||
OBJ = xa.o xaa.o xal.o xap.o xat.o xar.o xar2.o xao.o xau.o xam.o xacharset.o
|
||||
|
||||
#CFLAGS=-W -Wall -pedantic -ansi #-g
|
||||
#CFLAGS=-W -Wall -ansi -O2
|
||||
|
91
xa/src/xa.c
91
xa/src/xa.c
@ -61,7 +61,10 @@
|
||||
|
||||
/* exported globals */
|
||||
int ncmos, cmosfl, w65816, n65816;
|
||||
int masm = 0;
|
||||
/* compatibility flags */
|
||||
int masm = 0; /* MASM */
|
||||
int ca65 = 0; /* CA65 */
|
||||
|
||||
int nolink = 0;
|
||||
int romable = 0;
|
||||
int romaddr = 0;
|
||||
@ -71,10 +74,12 @@ int crossref = 0;
|
||||
char altppchar;
|
||||
|
||||
/* local variables */
|
||||
|
||||
static char out[MAXLINE];
|
||||
static time_t tim1, tim2;
|
||||
static FILE *fpout, *fperr, *fplab;
|
||||
static int ner = 0;
|
||||
static int ner_max = 20;
|
||||
|
||||
static int align = 1;
|
||||
|
||||
@ -91,6 +96,7 @@ static int getline(char *);
|
||||
static void lineout(void);
|
||||
static long ga_p1(void);
|
||||
static long gm_p1(void);
|
||||
static int set_compat(char *compat_name);
|
||||
|
||||
/* text */
|
||||
int memode,xmode;
|
||||
@ -191,6 +197,9 @@ int main(int argc,char *argv[])
|
||||
while(i<argc) {
|
||||
if(argv[i][0]=='-') {
|
||||
switch(argv[i][1]) {
|
||||
case 'E':
|
||||
ner_max = 0;
|
||||
break;
|
||||
case 'p':
|
||||
/* intentionally not allowing an argument to follow with a
|
||||
space to avoid - being seen as the alternate
|
||||
@ -210,6 +219,19 @@ int main(int argc,char *argv[])
|
||||
case 'M':
|
||||
masm = 1; /* MASM compatibility mode */
|
||||
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 */
|
||||
{
|
||||
char *name = NULL;
|
||||
@ -500,7 +522,12 @@ int main(int argc,char *argv[])
|
||||
|
||||
if(ner || er)
|
||||
{
|
||||
if (ner_max > 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();*/
|
||||
if(ofile) {
|
||||
unlink(ofile);
|
||||
@ -615,7 +642,7 @@ static int pass2(void)
|
||||
filep=&datei;
|
||||
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++];
|
||||
ll=l;
|
||||
@ -827,6 +854,7 @@ static void usage(int default816, FILE *fp)
|
||||
programname);
|
||||
fprintf(fp,
|
||||
" -v verbose output\n"
|
||||
" -E do not break after 20 errors, but show all\n"
|
||||
" -x old filename behaviour (overrides `-o', `-e', `-l')\n"
|
||||
" This is deprecated and may disappear in future versions!\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"
|
||||
" -r adds crossreference list to labellist (if `-l' given)\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");
|
||||
fprintf(fp,
|
||||
" -Llabel defines `label' as absolute, undefined label even when linking\n"
|
||||
@ -900,7 +930,7 @@ static char *ertxt[] = {
|
||||
"NewFile",
|
||||
"CMOS-Befehl",
|
||||
"pp:Wrong parameter count",
|
||||
"Illegal pointer arithmetic",
|
||||
"Illegal pointer arithmetic (-26)",
|
||||
"Illegal segment",
|
||||
"File header option too long",
|
||||
"File option not at file start (when ROM-able)",
|
||||
@ -939,11 +969,10 @@ static char *ertxt[] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
/* warnings */
|
||||
"Cutting word relocation in byte value",
|
||||
"Byte relocation in word value",
|
||||
"Illegal pointer arithmetic",
|
||||
"Illegal pointer arithmetic (-66)",
|
||||
"Address access to low or high byte pointer",
|
||||
"High byte access to low byte pointer",
|
||||
"Low byte access to high byte pointer",
|
||||
@ -1062,9 +1091,20 @@ static int getline(char *s)
|
||||
comcom = 1;
|
||||
if (c=='\0')
|
||||
break; /* hkfl = comcom = 0 */
|
||||
if (c==':' && !hkfl && (!comcom || !masm)) {
|
||||
gl=1;
|
||||
break;
|
||||
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) {
|
||||
/* 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++;
|
||||
} while (c!='\0' && j<MAXLINE-1 && i<MAXLINE-1);
|
||||
@ -1072,7 +1112,9 @@ static int getline(char *s)
|
||||
s[j]='\0';
|
||||
} else
|
||||
s[0]='\0';
|
||||
|
||||
#if 0
|
||||
printf("got line: %s\n", s);
|
||||
#endif
|
||||
return(ec);
|
||||
}
|
||||
|
||||
@ -1092,8 +1134,8 @@ static void lineout(void)
|
||||
|
||||
void errout(int er)
|
||||
{
|
||||
if (er<-ANZERR || er>-1) {
|
||||
if(er>=-(ANZERR+ANZWARN) && er < -ANZERR) {
|
||||
if (er<=-ANZERR || er>-1) {
|
||||
if(er>=-(ANZERR+ANZWARN) && er <= -ANZERR) {
|
||||
sprintf(out,"%s:line %d: %04x: Warning - %s\n",
|
||||
filep->fname, filep->fline, pc[segment], ertxt[(-er)-1]);
|
||||
} else {
|
||||
@ -1129,3 +1171,30 @@ void logout(char *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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "xah.h" /* For SEG_MAX */
|
||||
|
||||
extern int ncmos, cmosfl, w65816, n65816;
|
||||
extern int masm, nolink;
|
||||
extern int masm, ca65, nolink;
|
||||
extern int noglob;
|
||||
extern int showblk;
|
||||
extern int relmode;
|
||||
|
@ -180,6 +180,8 @@ static int ag_term(signed char *s, int p, int *v, int *nafl, int *label)
|
||||
} else {
|
||||
if(segment!=SEG_ABS) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
13
xa/src/xah.h
13
xa/src/xah.h
@ -20,15 +20,22 @@
|
||||
#ifndef __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 MAXLAB 32
|
||||
#define MAXBLK 16
|
||||
#define MAXFILE 7
|
||||
#define MAXLINE 2048
|
||||
#define MAXPP 40000L
|
||||
#define ANZDEF 2340 /* mal 14 -> Byte, ANZDEF * 14 < 32768 */
|
||||
#define TMPMEM 200000L /* Zwischenspeicher von Pass1 nach Pass 2 */
|
||||
#define ANZDEF 2340 /* multiplied by sizeof(List) -> Byte, ANZDEF * 20 < 32768 */
|
||||
#define TMPMEM 200000L /* temporary memory buffer from Pass1 to Pass 2 */
|
||||
|
||||
typedef struct LabOcc {
|
||||
struct LabOcc *next;
|
||||
|
194
xa/src/xal.c
194
xa/src/xal.c
@ -50,6 +50,12 @@ static int b_get(int*);
|
||||
static int b_test(int);
|
||||
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 */
|
||||
|
||||
/*
|
||||
@ -69,6 +75,7 @@ static Labtab *ltp;
|
||||
|
||||
int l_init(void)
|
||||
{
|
||||
cll_init();
|
||||
return 0;
|
||||
#if 0
|
||||
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 n, er;
|
||||
|
||||
er = ll_search(s,&n);
|
||||
er = ll_search(s,&n, 0);
|
||||
|
||||
if(er==E_OK) {
|
||||
fprintf(stderr,"Warning: global label doubly defined!\n");
|
||||
@ -156,52 +202,73 @@ int lg_set(char *s ) {
|
||||
return er;
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
int l_def(char *s, int *l, int *x, int *f)
|
||||
{
|
||||
int n,er,b,i=0;
|
||||
int cll_fl;
|
||||
|
||||
*f=0;
|
||||
b=0;
|
||||
n=0;
|
||||
*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 */
|
||||
|
||||
if(s[0]=='-')
|
||||
{
|
||||
*f+=1;
|
||||
*f+=1; /* label is being redefined */
|
||||
i++;
|
||||
} 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]=='+')
|
||||
{
|
||||
i++;
|
||||
n++;
|
||||
b=0;
|
||||
n++; /* block number b is absolute */
|
||||
b=0; /* global block number */
|
||||
}
|
||||
while(s[i]=='&')
|
||||
{
|
||||
n=0;
|
||||
if (n) b=0; /* reset block number */
|
||||
n=0; /* block number is relative */
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
else
|
||||
{
|
||||
er=ll_search(s+i,&n);
|
||||
er=ll_search(s+i,&n, cll_fl);
|
||||
|
||||
if(er==E_OK)
|
||||
{
|
||||
/* we actually found an existing label in the same scope */
|
||||
ltp=afile->la.lt+n;
|
||||
|
||||
if(*f)
|
||||
{
|
||||
/* redefinition of label */
|
||||
*l=ltp->len+i;
|
||||
} else
|
||||
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;
|
||||
if(b_ltest(ltp->blk,b))
|
||||
er=E_LABDEF;
|
||||
@ -213,7 +280,7 @@ int l_def(char *s, int *l, int *x, int *f)
|
||||
} else
|
||||
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;
|
||||
*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 n,er,b;
|
||||
int cll_fl;
|
||||
|
||||
*afl=0;
|
||||
|
||||
er=ll_search(s,&n);
|
||||
/*printf("l_search: lab=%s(l=%d), afl=%d, er=%d, n=%d\n",s,*l, *afl,er,n);*/
|
||||
/* check cheap local label */
|
||||
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)
|
||||
{
|
||||
ltp=afile->la.lt+n;
|
||||
*l=ltp->len;
|
||||
*l=ltp->len + cll_fl;
|
||||
if(ltp->fl == 1)
|
||||
{
|
||||
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
|
||||
{
|
||||
b_get(&b);
|
||||
if(cll_fl) {
|
||||
b=cll_get();
|
||||
} else {
|
||||
b_get(&b);
|
||||
}
|
||||
|
||||
er=ll_def(s,x,b); /* ll_def(...,*v); */
|
||||
|
||||
ltp=afile->la.lt+(*x);
|
||||
|
||||
*l=ltp->len;
|
||||
*l=ltp->len + cll_fl;
|
||||
|
||||
if(!er)
|
||||
{
|
||||
@ -401,8 +481,14 @@ static int ll_def(char *s, int *n, int b) /* definiert naechstes Label
|
||||
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;
|
||||
|
||||
@ -411,7 +497,6 @@ int ll_search(char *s, int *n) /* search Label in Tabelle ,nr->n */
|
||||
hash=hashcode(s,j);
|
||||
i=afile->la.hashindex[hash];
|
||||
|
||||
/*printf("search?\n");*/
|
||||
if(i>=afile->la.ltm) return E_NODEF;
|
||||
|
||||
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++);
|
||||
|
||||
if((j==k)&&(!b_test(ltp->blk)))
|
||||
{
|
||||
er=E_OK;
|
||||
break;
|
||||
}
|
||||
if (cll_fl) {
|
||||
if (ltp->blk == cll_getcur()) {
|
||||
er=E_OK;
|
||||
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)
|
||||
@ -451,7 +546,7 @@ int ll_pdef(char *t)
|
||||
{
|
||||
int n;
|
||||
|
||||
if(ll_search(t,&n)==E_OK)
|
||||
if(ll_search(t,&n, 0)==E_OK)
|
||||
{
|
||||
ltp=afile->la.lt+n;
|
||||
if(ltp->fl)
|
||||
@ -496,9 +591,22 @@ int l_write(FILE *fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bt[MAXBLK];
|
||||
static int blk;
|
||||
static int bi;
|
||||
/*******************************************************************************************
|
||||
* block management code. Here the ".(" and ".)" blocks are maintained.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
@ -509,6 +617,11 @@ int b_init(void)
|
||||
return(E_OK);
|
||||
}
|
||||
|
||||
int b_new(void)
|
||||
{
|
||||
return ++blk;
|
||||
}
|
||||
|
||||
int b_depth(void)
|
||||
{
|
||||
return bi;
|
||||
@ -519,19 +632,25 @@ int ga_blk(void)
|
||||
return(blk);
|
||||
}
|
||||
|
||||
/**
|
||||
* open a new block scope
|
||||
*/
|
||||
int b_open(void)
|
||||
{
|
||||
int er=E_BLKOVR;
|
||||
|
||||
if(bi<MAXBLK-1)
|
||||
{
|
||||
bt[++bi]=++blk;
|
||||
bt[++bi]=b_new();
|
||||
|
||||
er=E_OK;
|
||||
}
|
||||
return(er);
|
||||
}
|
||||
|
||||
/**
|
||||
* close a block scope
|
||||
*/
|
||||
int b_close(void)
|
||||
{
|
||||
|
||||
@ -546,6 +665,9 @@ int b_close(void)
|
||||
return(E_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the block number of the current innermost block
|
||||
*/
|
||||
static int b_get(int *n)
|
||||
{
|
||||
*n=bt[bi];
|
||||
@ -553,6 +675,9 @@ static int b_get(int *n)
|
||||
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)
|
||||
{
|
||||
if((bi-i)>=0)
|
||||
@ -562,6 +687,10 @@ static int b_fget(int *n, int i)
|
||||
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)
|
||||
{
|
||||
int i=bi;
|
||||
@ -572,6 +701,9 @@ static int b_test(int n)
|
||||
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)] */
|
||||
{
|
||||
int i=0,er=E_OK;
|
||||
|
@ -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);
|
||||
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 ll_search(char *s, int *n, int cll_fl);
|
||||
int ll_pdef(char *t);
|
||||
|
||||
int b_open(void);
|
||||
|
@ -130,7 +130,7 @@ int pp_ifldef(char *t)
|
||||
int pp_iflused(char *t)
|
||||
{
|
||||
int n;
|
||||
loopfl=(loopfl<<1)+( ll_search(t,&n) ? 1 : 0 );
|
||||
loopfl=(loopfl<<1)+( ll_search(t,&n,0) ? 1 : 0 );
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
35
xa/src/xat.c
35
xa/src/xat.c
@ -75,7 +75,7 @@ static char *kt[] ={
|
||||
|
||||
".byt",".word",".asc",".dsb", ".(", ".)", "*=", ".text",".data",".bss",
|
||||
".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 */
|
||||
#define Lastbef 93
|
||||
/* last valid token+1 */
|
||||
#define Anzkey 123
|
||||
#define Anzkey 124
|
||||
|
||||
#define Kbyt Lastbef+1
|
||||
#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 Kaasc Lastbef+29
|
||||
|
||||
#define Kcode Lastbef+30 /* gets remapped to Ktext */
|
||||
|
||||
#define Kreloc Anzkey /* *= (relocation mode) */
|
||||
#define Ksegment Anzkey+1
|
||||
|
||||
@ -349,6 +351,7 @@ fprintf(stderr, "- p1 %d starting -\n", pc[segment]);
|
||||
printf("\n");
|
||||
*/
|
||||
/* 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)) {
|
||||
afile->base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length();
|
||||
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 operand,o;
|
||||
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;
|
||||
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]=='=')
|
||||
{
|
||||
/*printf("Found = @%s\n",s+p);*/
|
||||
t[q++]=T_OP;
|
||||
t[q++]=n&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;
|
||||
break;
|
||||
} 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]=='=')
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* are we forcing the operand into a particular
|
||||
addressing mode? !, @, ` operators */
|
||||
if(s[p]=='!' || s[p]=='@' || s[p]=='`')
|
||||
addressing mode? !, @, ` operators
|
||||
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];
|
||||
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++];
|
||||
} else
|
||||
/* maybe it's a label */
|
||||
if(isalpha(s[p]) || s[p]=='_')
|
||||
/* maybe it's a label
|
||||
Note that for ca65 cheap local labels, we check for "@" */
|
||||
if(isalpha(s[p]) || s[p]=='_' || (s[p]=='@' && ca65))
|
||||
{
|
||||
m=n;
|
||||
er=l_search((char*)s+p,&ll,&n,&v,&afl);
|
||||
|
||||
/*
|
||||
if(m==Kglobl || m==Kextzero) {
|
||||
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==Kblock) i=Kopen;
|
||||
if(i==Kbend) i=Kclose;
|
||||
if(i==Kcode) i=Ktext;
|
||||
|
||||
|
||||
*l=j;
|
||||
|
Loading…
Reference in New Issue
Block a user