-/*
- * 6502 Assembler
- *
- * Init6502 initialization
- * d_6502 handle ".6502" directive
- * m6502cg generate code for a 6502 mnemonic
- * d_org handle 6502 section's ".org" directive
- * m6502obj generate 6502 object file
- *
- */
-#include "rmac.h"
-#include "sect.h"
+//
+// 6502 Assembler
+//
+// Init6502 initialization
+// d_6502 handle ".6502" directive
+// m6502cg generate code for a 6502 mnemonic
+// d_org handle 6502 section's ".org" directive
+// m6502obj generate 6502 object file
+//
+#include "direct.h"
#include "expr.h"
#include "error.h"
+#include "mach.h"
+#include "procln.h"
+#include "riscasm.h"
+#include "rmac.h"
+#include "sect.h"
+#include "token.h"
-#define UPSEG_SIZE 0x10010L /* size of 6502 code buffer, 64K+16bytes */
-
-
-/*
- * Imports
- */
-extern TOKEN *tok; /* -> current token */
-extern int debug; /* >0, in debug mode (-x) */
-extern int m6502; /* 1, in 6502 mode */
-extern TOKEN exprbuf[]; /* "universal" postfix expression buffer */
-extern LONG lsloc; /* `sloc' at start of line */
-extern unsigned orgactive; // RISC/6502 org directive active
-extern unsigned orgaddr; // Org'd address
-extern char * string[];
-
-extern char extra_stuff[]; /* needed-eol error message */
-extern char *range_error; /* value-out-of-range error message */
-
-
-/*
- * Exports
- */
-char in_6502mode[] = "directive illegal in .6502 section";
-static uint16_t orgmap[1024][2]; /* mark all 6502 org changes */
-uint16_t *currentorg = (uint16_t *)orgmap; /* current org range */
-
-/*
- * 6502 addressing modes;
- * do not change these values.
- *
- */
+#define UPSEG_SIZE 0x10010L // size of 6502 code buffer, 64K+16bytes
+
+//
+// Exported vars
+//
+const char in_6502mode[] = "directive illegal in .6502 section";
+static uint16_t orgmap[1024][2]; // Mark all 6502 org changes
+uint16_t * currentorg = &orgmap[0][0]; // Current org range
+
+//
+// 6502 addressing modes;
+// DO NOT CHANGE THESE VALUES.
+//
#define A65_ABS 0
#define A65_ABSX 1
#define A65_ABSY 2
#define A65_IMMEDH 12
#define A65_IMMEDL 13
-#define NMACHOPS 56 /* number of machine ops */
-#define NMODES 14 /* number of addressing modes */
-#define NOP 0xea /* 6502 NOP instruction */
-#define ILLEGAL 0xff /* 'illegal instr' marker */
-#define END65 0xff /* end-of-an-instr-list */
+#define NMACHOPS 56 // Number of machine ops
+#define NMODES 14 // Number of addressing modes
+#define NOP 0xEA // 6502 NOP instruction
+#define ILLEGAL 0xFF // 'Illegal instr' marker
+#define END65 0xFF // End-of-an-instr-list
static char imodes[] =
{
A65_IMPL, 0x98, END65
};
-static char ops[NMACHOPS][NMODES]; /* opcodes */
-static unsigned char inf[NMACHOPS][NMODES]; /* construction info */
+static char ops[NMACHOPS][NMODES]; // Opcodes
+static unsigned char inf[NMACHOPS][NMODES]; // Construction info
+// Absolute-to-zeropage translation table
static int abs2zp[] =
-{ /* absolute-to-zeropage trans table */
- A65_ZP, /* ABS */
- A65_ZPX, /* ABSX */
- A65_ZPY, /* ABSY */
- -1, /* IMPL */
- -1, /* IMMED */
- -1, /* INDX */
- -1, /* INDY */
- -1, /* IND */
- -1, /* REL */
- -1, /* ZP */
- -1, /* ZPX */
- -1 /* ZPY */
+{
+ A65_ZP, // ABS
+ A65_ZPX, // ABSX
+ A65_ZPY, // ABSY
+ -1, // IMPL
+ -1, // IMMED
+ -1, // INDX
+ -1, // INDY
+ -1, // IND
+ -1, // REL
+ -1, // ZP
+ -1, // ZPX
+ -1 // ZPY
};
-/*
- * initialize 6502 assembler
- *
- */
+//
+// Initialize 6502 assembler
+//
void Init6502()
{
register int i;
register int j;
- register char *s;
- s = imodes;
+ register char * s = imodes;
- /* set all instruction slots to illegal */
- for (i = 0; i < NMACHOPS; ++i)
- for (j = 0; j < NMODES; ++j)
+ // Set all instruction slots to illegal
+ for(i=0; i<NMACHOPS; i++)
+ for(j=0; j<NMODES; j++)
inf[i][j] = ILLEGAL;
- /* uncompress legal instructions into their slots */
- for (i = 0; i < NMACHOPS; ++i)
+ // Uncompress legal instructions into their slots
+ for(i=0; i<NMACHOPS; i++)
{
- do {
- j = *s & 0xff;
+ do
+ {
+ j = *s & 0xFF;
inf[i][j] = *s;
ops[i][j] = s[1];
inf[i][A65_ZP] = A65_REL;
ops[i][A65_ZP] = s[1];
}
- } while(*(s += 2) != (char)END65);
- ++s;
+ }
+ while (*(s += 2) != (char)END65);
+
+ s++;
}
- /* set up first org section (set to zero) */
- orgmap[0][0] = 0;
+ // Set up first org section (set to zero)
+ orgmap[0][0] = 0;
}
-/*
- * .6502 --- enter 6502 mode
- *
- */
+//
+// .6502 --- enter 6502 mode
+//
int d_6502()
{
- SaveSection(); /* save curent section */
- SwitchSection(M6502); /* switch to 6502 section */
- if (challoc == 0) {
- /*
- * Allocate and clear 64K of space for the 6502 section
- */
- chcheck(UPSEG_SIZE);
- memset(sect[M6502].scode->chptr, 0, UPSEG_SIZE);
- }
- return 0;
+ SaveSection(); // Save curent section
+ SwitchSection(M6502); // Switch to 6502 section
+
+ if (challoc == 0)
+ {
+ // Allocate and clear 64K of space for the 6502 section
+ chcheck(UPSEG_SIZE);
+ memset(sect[M6502].scode->chptr, 0, UPSEG_SIZE);
+ }
+
+ return 0;
}
-/*
- * Do 6502 code generation
- *
- */
-VOID m6502cg(int op)
+//
+// Do 6502 code generation
+//
+void m6502cg(int op)
{
- register int amode; /* (parsed) addressing mode */
+ register int amode; // (Parsed) addressing mode
register int i;
- VALUE eval; /* expression value */
- WORD eattr; /* expression attributes */
- int zpreq; /* 1, optimize instr to zero-page form */
- register char *p; /* (temp) string usage */
-
-
- ch_size = 0; /* reset chunk size on every instruction */
-
- /*
- * Parse 6502 addressing mode
- *
- */
+ VALUE eval; // Expression value
+ WORD eattr; // Expression attributes
+ int zpreq; // 1, optimize instr to zero-page form
+ register char * p; // (Temp) string usage
+ ch_size = 0; // Reset chunk size on every instruction
+
+ //
+ // Parse 6502 addressing mode
+ //
zpreq = 0;
+
switch ((int)*tok)
{
- case EOL:
- amode = A65_IMPL;
- break;
+ case EOL:
+ amode = A65_IMPL;
+ break;
- case '#':
- ++tok;
- if (*tok == '>')
- {
- ++tok;
- if (expr(exprbuf, &eval, &eattr, NULL) < 0) return;
- amode = A65_IMMEDH;
- break;
- }
- else if (*tok == '<')
- {
- ++tok;
- if (expr(exprbuf, &eval, &eattr, NULL) < 0) return;
- amode = A65_IMMEDL;
- break;
- }
- if (expr(exprbuf, &eval, &eattr, NULL) < 0) return;
- amode = A65_IMMED;
- break;
+ case '#':
+ tok++;
- case '(':
- ++tok;
- if (expr(exprbuf, &eval, &eattr, NULL) < 0) return;
-
- if (*tok == ')')
- { /* (foo) or (foo),y */
- if (*++tok == ',')
- { /* (foo),y */
- ++tok;
- p = string[tok[1]];
- if (*tok != SYMBOL ||
- p[1] != EOS ||
- (*p | 0x20) != 'y') /* sleazo tolower() */
- goto badmode;
- tok += 2;
- amode = A65_INDY;
- }
- else amode = A65_IND;
- }
- else if (*tok == ',')
- { /* (foo,x) */
- ++tok;
- p = string[tok[1]];
- if (*tok != SYMBOL ||
- p[1] != EOS ||
- (*p | 0x20) != 'x') /* sleazo tolower() */
- goto badmode;
- tok += 2;
- if (*tok++ != ')')
- goto badmode;
- amode = A65_INDX;
- }
- else goto badmode;
+ if (*tok == '>')
+ {
+ tok++;
+ if (expr(exprbuf, &eval, &eattr, NULL) < 0)
+ return;
+
+ amode = A65_IMMEDH;
break;
+ }
+ else if (*tok == '<')
+ {
+ tok++;
+ if (expr(exprbuf, &eval, &eattr, NULL) < 0)
+ return;
+
+ amode = A65_IMMEDL;
+ break;
+ }
+
+ if (expr(exprbuf, &eval, &eattr, NULL) < 0)
+ return;
+
+ amode = A65_IMMED;
+ break;
+
+ case '(':
+ tok++;
- case '@':
- ++tok;
- if (expr(exprbuf, &eval, &eattr, NULL) < 0) return;
+ if (expr(exprbuf, &eval, &eattr, NULL) < 0)
+ return;
- if (*tok == '(')
+ if (*tok == ')')
+ {
+ // (foo) or (foo),y
+ if (*++tok == ',')
{
- ++tok;
+ // (foo),y
+ tok++;
p = string[tok[1]];
- if (*tok != SYMBOL ||
- p[1] != EOS ||
- tok[2] != ')' ||
- tok[3] != EOL)
+
+ if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y') // Sleazo tolower()
goto badmode;
- i = (*p | 0x20); /* sleazo tolower */
- if (i == 'x')
- amode = A65_INDX;
- else if (i == 'y')
- amode = A65_INDY;
- else goto badmode;
- tok += 3; /* past SYMBOL <string> ')' EOL */
- zpreq = 1; /* request zeropage optimization */
+ tok += 2;
+ amode = A65_INDY;
}
- else if (*tok == EOL)
+ else
amode = A65_IND;
- else goto badmode;
- break;
+ }
+ else if (*tok == ',')
+ {
+ // (foo,x)
+ tok++;
+ p = string[tok[1]];
- default:
- /*
- * Short-circuit
- * x,foo
- * y,foo
- *
- */
+ if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x') // Sleazo tolower()
+ goto badmode;
+
+ tok += 2;
+
+ if (*tok++ != ')')
+ goto badmode;
+
+ amode = A65_INDX;
+ }
+ else
+ goto badmode;
+
+ break;
+
+ case '@':
+ tok++;
+
+ if (expr(exprbuf, &eval, &eattr, NULL) < 0)
+ return;
+
+ if (*tok == '(')
+ {
+ tok++;
p = string[tok[1]];
- if (*tok == SYMBOL &&
- p[1] == EOS &&
- tok[2] == ',')
- {
- tok += 3; /* past: SYMBOL <string> ',' */
- i = (*p | 0x20);
-
- if (i == 'x')
- amode = A65_ABSX;
- else if (i == 'y')
- amode = A65_ABSY;
- else goto not_coinop;
-
- if (expr(exprbuf, &eval, &eattr, NULL) < 0)
- return;
- if (*tok != EOL)
- goto badmode;
- zpreq = 1;
- break;
- }
+ if (*tok != SYMBOL || p[1] != EOS || tok[2] != ')' || tok[3] != EOL)
+ goto badmode;
-not_coinop:
- if (expr(exprbuf, &eval, &eattr, NULL) < 0) return;
- zpreq = 1;
+ i = (*p | 0x20); // Sleazo tolower()
- if (*tok == EOL)
- amode = A65_ABS;
- else if (*tok == ',')
- {
- ++tok;
- p = string[tok[1]];
- if (*tok != SYMBOL ||
- p[1] != EOS)
- goto badmode;
- tok += 2;
+ if (i == 'x')
+ amode = A65_INDX;
+ else if (i == 'y')
+ amode = A65_INDY;
+ else
+ goto badmode;
+
+ tok += 3; // Past SYMBOL <string> ')' EOL
+ zpreq = 1; // Request zeropage optimization
+ }
+ else if (*tok == EOL)
+ amode = A65_IND;
+ else
+ goto badmode;
+
+ break;
+
+ default:
+ //
+ // Short-circuit
+ // x,foo
+ // y,foo
+ //
+ p = string[tok[1]];
+
+ if (*tok == SYMBOL && p[1] == EOS && tok[2] == ',')
+ {
+ tok += 3; // Past: SYMBOL <string> ','
+ i = (*p | 0x20);
+
+ if (i == 'x')
+ amode = A65_ABSX;
+ else if (i == 'y')
+ amode = A65_ABSY;
+ else
+ goto not_coinop;
- /*
- * Check for X or Y index register;
- * the OR with 0x20 is a sleazo conversion
- * to lower-case that actually works.
- */
- i = *p | 0x20; /* oooh, this is slimey (but fast!) */
- if (i == 'x')
- amode = A65_ABSX;
- else if (i == 'y')
- amode = A65_ABSY;
- else goto badmode;
- }
- else goto badmode;
+ if (expr(exprbuf, &eval, &eattr, NULL) < 0)
+ return;
+
+ if (*tok != EOL)
+ goto badmode;
+
+ zpreq = 1;
break;
+ }
+
+not_coinop:
+ if (expr(exprbuf, &eval, &eattr, NULL) < 0)
+ return;
+
+ zpreq = 1;
+
+ if (*tok == EOL)
+ amode = A65_ABS;
+ else if (*tok == ',')
+ {
+ tok++;
+ p = string[tok[1]];
+
+ if (*tok != SYMBOL || p[1] != EOS)
+ goto badmode;
+
+ tok += 2;
+
+ //
+ // Check for X or Y index register;
+ // the OR with 0x20 is a sleazo conversion
+ // to lower-case that actually works.
+ //
+ i = *p | 0x20; // Oooh, this is slimey (but fast!)
+
+ if (i == 'x')
+ amode = A65_ABSX;
+ else if (i == 'y')
+ amode = A65_ABSY;
+ else
+ goto badmode;
+ }
+ else
+ goto badmode;
+
+ break;
badmode:
- error("bad 6502 addressing mode");
- return;
+ error("bad 6502 addressing mode");
+ return;
}
- /*
- * Optimize ABS modes to zero-page when possible
- * o ZPX or ZPY is illegal, or
- * o expr is zeropage && zeropageRequest && expression is defined
- */
- if (inf[op][amode] == ILLEGAL || /* if current op is illegal, or */
- (eval < 0x100 && /* expr must be zero-page */
- zpreq != 0 && /* amode must request zero-page opt. */
- (eattr & DEFINED))) /* and the expression must be defined */
+ //
+ // Optimize ABS modes to zero-page when possible
+ // o ZPX or ZPY is illegal, or
+ // o expr is zeropage && zeropageRequest && expression is defined
+ //
+ if (inf[op][amode] == ILLEGAL // If current op is illegal,
+ || (eval < 0x100 // or expr must be zero-page
+ && zpreq != 0 // amode must request zero-page opt.
+ && (eattr & DEFINED))) // and the expression must be defined
{
- i = abs2zp[amode]; /* i = zero-page translation of amode */
+ i = abs2zp[amode]; // i = zero-page translation of amode
#ifdef DO_DEBUG
DEBUG printf(" OPT: op=%d amode=%d i=%d inf[op][i]=%d\n",
op, amode, i, inf[op][i]);
#endif
- if (i >= 0 &&
- (inf[op][i] & 0xff) != ILLEGAL) /* use it if it's legal */
+ if (i >= 0 && (inf[op][i] & 0xFF) != ILLEGAL) // Use it if it's legal
amode = i;
}
switch (inf[op][amode])
{
- case A65_IMPL: /* just leave the instruction */
+ case A65_IMPL: // Just leave the instruction
D_byte(ops[op][amode]);
break;
- case A65_IMMEDH:
- D_byte(ops[op][amode]);
- if (!(eattr & DEFINED))
- {
- AddFixup(FU_BYTEH, sloc, exprbuf);
- eval = 0;
- }
- eval = (eval >> 8) & 0xff; /* bring high byte to low */
- D_byte(eval); /* deposit byte following instr */
- break;
-
- case A65_IMMEDL:
- D_byte(ops[op][amode]);
- if (!(eattr & DEFINED))
- {
- AddFixup(FU_BYTEL, sloc, exprbuf);
- eval = 0;
- }
- eval = eval & 0xff; /* mask high byte */
- D_byte(eval); /* deposit byte following instr */
- break;
+ case A65_IMMEDH:
+ D_byte(ops[op][amode]);
+
+ if (!(eattr & DEFINED))
+ {
+ AddFixup(FU_BYTEH, sloc, exprbuf);
+ eval = 0;
+ }
+
+ eval = (eval >> 8) & 0xFF; // Bring high byte to low
+ D_byte(eval); // Deposit byte following instr
+ break;
+
+ case A65_IMMEDL:
+ D_byte(ops[op][amode]);
+
+ if (!(eattr & DEFINED))
+ {
+ AddFixup(FU_BYTEL, sloc, exprbuf);
+ eval = 0;
+ }
+
+ eval = eval & 0xFF; // Mask high byte
+ D_byte(eval); // Deposit byte following instr
+ break;
case A65_IMMED:
case A65_INDX:
case A65_ZPX:
case A65_ZPY:
D_byte(ops[op][amode]);
+
if (!(eattr & DEFINED))
{
AddFixup(FU_BYTE, sloc, exprbuf);
error(range_error);
eval = 0;
}
- D_byte(eval); /* deposit byte following instr */
+
+ D_byte(eval); // Deposit byte following instr
break;
case A65_REL:
D_byte(ops[op][amode]);
+
if (eattr & DEFINED)
{
eval -= (sloc + 1);
+
if (eval + 0x80 >= 0x100)
{
error(range_error);
eval = 0;
}
+
D_byte(eval);
}
else
AddFixup(FU_6BRA, sloc, exprbuf);
D_byte(0);
}
+
break;
case A65_ABS:
case A65_ABSY:
case A65_IND:
D_byte(ops[op][amode]);
+
if (!(eattr & DEFINED))
{
AddFixup(FU_WORD, sloc, exprbuf);
eval = 0;
}
+
D_rword(eval);
break;
- /*
- * Deposit 3 NOPs for illegal things
- */
+ //
+ // Deposit 3 NOPs for illegal things
+ //
default:
case ILLEGAL:
- for (i = 0; i < 3; ++i) {
+ for(i=0; i<3; i++)
D_byte(NOP);
- }
+
error("illegal 6502 addressing mode");
}
- /*
- * Check for overflow of code region
- */
- if (sloc > 0x10000L) fatal("6502 code pointer > 64K");
- if (*tok != EOL) error(extra_stuff);
+ // Check for overflow of code region
+ if (sloc > 0x10000L)
+ fatal("6502 code pointer > 64K");
+
+ if (*tok != EOL)
+ error(extra_stuff);
}
-/*
- * Generate 6502 object output file.
- *
- */
+//
+// Generate 6502 object output file.
+//
// ggn: converted into a com/exe/xex output format
-// Notes: 1. The $ffff is only mandatory for the first segment, but let's dump it everywhere for now
+// Notes: 1. The $FFFF is only mandatory for the first segment, but let's dump it everywhere for now
// 2. It's still dumping pages instead of more fine grained stuff. Should look into this - a8 people don't like waste so much ;)
-VOID m6502obj(ofd)
-int ofd;
+void m6502obj(int ofd)
{
- register CHUNK *ch;
- register char *p;
- uint16_t exeheader[3];
- uint16_t *l;
- int headsize = 6;
- uint16_t *headpoint = (uint16_t *)exeheader;
-
- /*
- * If no 6502 code was generated, forget it
- */
- if ((ch = sect[M6502].scode) == NULL ||
- ch->challoc == 0)
- return;
+ uint16_t exeheader[3];
+ int headsize = 6;
+ uint16_t * headpoint = exeheader;
+
+ CHUNK * ch = sect[M6502].scode;
- exeheader[0] = 0xffff; // mandatory for first segment
- p = ch->chptr;
+ // If no 6502 code was generated, forget it
+ if ((ch == NULL) || (ch->challoc == 0))
+ return;
- for (l = (uint16_t *)orgmap;l < currentorg;l+=2)
- {
- exeheader[1] = l[0];
- exeheader[2] = l[1]-1;
- write(ofd, headpoint, headsize); // Write header
- write(ofd, p + l[0], l[1] - l[0]);
- headpoint = &exeheader[1]; // skip the $ffff after first segment, it's not mandatory
- headsize = 4;
- }
+ exeheader[0] = 0xFFFF; // Mandatory for first segment
+ register uint8_t * p = ch->chptr;
+ for(uint16_t * l=&orgmap[0][0]; l<currentorg; l+=2)
+ {
+ exeheader[1] = l[0];
+ exeheader[2] = l[1] - 1;
+ size_t unused = write(ofd, headpoint, headsize); // Write header
+ unused = write(ofd, p + l[0], l[1] - l[0]);
+ headpoint = &exeheader[1]; // Skip the $FFFF after first segment, it's not mandatory
+ headsize = 4;
+ }
}
+
// mnattr:
#define CGSPECIAL 0x8000 // Special (don't parse addr modes)
-// Prototypes
+// Exported functions
int amode(int);
int reglist(WORD *);
#include "rmac.h"
-// Prototypes
+// Exported functions
int mudump(void);
int mdump(char *, LONG, int, LONG);
int dumptok(TOKEN *);
//
#include "direct.h"
-#include "sect.h"
-#include "riscasm.h"
+#include "6502.h"
#include "error.h"
-#include "token.h"
-#include "procln.h"
#include "expr.h"
-#include "mach.h"
#include "listing.h"
+#include "mach.h"
+#include "macro.h"
#include "mark.h"
+#include "procln.h"
+#include "riscasm.h"
+#include "sect.h"
#include "symbol.h"
+#include "token.h"
#define DEF_KW
#include "kwtab.h"
static long unused; // For supressing 'write' warnings
char buffer[256]; // Scratch buffer for messages
+// Function prototypes
+int d_unimpl(void);
+int d_68000(void);
+int d_bss(void);
+int d_data(void);
+int d_text(void);
+int d_abs(void);
+int d_comm(void);
+int d_dc(WORD);
+int d_ds(WORD);
+int d_dcb(WORD);
+int d_globl(void);
+int d_gpu(void);
+int d_dsp(void);
+int d_assert(void);
+int d_include(void);
+int d_list(void);
+int d_nlist(void);
+int d_error(char *);
+int d_warn(char *);
+int d_org(void);
+int d_init(WORD);
+int d_cargs(void);
+int d_undmac(void);
+int d_regbank0(void);
+int d_regbank1(void);
+int d_incbin(void);
+int d_noclear(void);
+int d_equrundef(void);
+int d_ccundef(void);
+int d_print(void);
+int d_gpumain(void);
+int d_jpad(void);
+int d_nojpad(void);
+int d_fail(void);
+int d_cstruct(void);
+int d_prgflags(void);
+int d_opt(void);
// Directive handler table
int (*dirtab[])() = {
d_org, // 0 org
d_even, // 1 even
- d_6502, // 2 .6502
+ d_6502, // 2 .6502
d_68000, // 3 .68000
d_bss, // 4 bss
d_data, // 5 data
//
int d_org(void)
{
- VALUE address;
-
- if (!rgpu && !rdsp && !m6502)
- return error(".org permitted only in gpu/dsp and 6502 sections");
-
- if (rgpu | rdsp)
- {
- orgaddr = 0;
-
- if (abs_expr(&address) == ERROR)
- {
- error("cannot determine org'd address");
- return ERROR;
- }
-
- orgaddr = address;
- orgactive = 1;
- //printf("ORG: address = $%08X...\n", orgaddr);
-
- return 0;
- }
- else
- {
- // 6502
- // We also kludge `lsloc' so the listing generator doesn't
- // try to spew out megabytes.
- VALUE eval;
-
- //if (m6502 == 0) return error(".org permitted only in .6502 section");
- if (abs_expr(&eval) < 0) return 0;
- if (eval >= 0x10000L) return error(range_error);
-
- if (sloc != currentorg[0])
- {
- currentorg[1] = sloc;
- currentorg += 2;
- }
-
- currentorg[0] = eval;
- ch_size = 0;
- lsloc = sloc = eval;
- chptr = scode->chptr + eval;
- orgactive = 1;
- orgaddr = eval;
- at_eol();
- return 0;
- }
+ VALUE address;
+
+ if (!rgpu && !rdsp && !m6502)
+ return error(".org permitted only in gpu/dsp and 6502 sections");
+
+ if (abs_expr(&address) == ERROR)
+ {
+ error("cannot determine org'd address");
+ return ERROR;
+ }
+
+ if (rgpu | rdsp)
+ {
+ orgaddr = address;
+ orgactive = 1;
+ }
+ else
+ {
+ // 6502. We also kludge `lsloc' so the listing generator doesn't try
+ // to spew out megabytes.
+ if (address > 0xFFFF)
+ return error(range_error);
+
+ if (sloc != currentorg[0])
+ {
+ currentorg[1] = sloc;
+ currentorg += 2;
+ }
+
+ currentorg[0] = address;
+ ch_size = 0;
+ lsloc = sloc = address;
+ chptr = scode->chptr + address;
+ orgaddr = address;
+ orgactive = 1;
+ at_eol();
+ }
+
+ return 0;
}
//
int d_even(void)
{
- if (m6502)
- return error(in_6502mode);
+ if (m6502)
+ return error(in_6502mode);
unsigned skip = (rgpu || rdsp ? orgaddr : sloc) & 0x01;
//
void auto_even(void)
{
- if (cursect != M6502)
- {
- if (scattr & SBSS)
- sloc++; // Bump BSS section
- else
- D_byte(0); // Deposit 0.b in non-BSS
+ if (cursect != M6502)
+ {
+ if (scattr & SBSS)
+ sloc++; // Bump BSS section
+ else
+ D_byte(0); // Deposit 0.b in non-BSS
- if (lab_sym != NULL) // Bump label if we have to
- lab_sym->svalue++;
- }
+ if (lab_sym != NULL) // Bump label if we have to
+ lab_sym->svalue++;
+ }
}
int d_globl(void)
{
- if (m6502)
- return error(in_6502mode);
+ if (m6502)
+ return error(in_6502mode);
symlist(globl1);
return 0;
{
VALUE eval;
- if (m6502)
- return error(in_6502mode);
-
+ if (m6502)
+ return error(in_6502mode);
+
SaveSection();
if (*tok == EOL)
{
if (rgpu || rdsp)
return error("directive forbidden in gpu/dsp mode");
- if (m6502)
- return error(in_6502mode);
+ else if (m6502)
+ return error(in_6502mode);
if (cursect != TEXT)
{
{
if (rgpu || rdsp)
return error("directive forbidden in gpu/dsp mode");
- if (m6502)
- return error(in_6502mode);
+ else if (m6502)
+ return error(in_6502mode);
if (cursect != DATA)
{
{
if (rgpu || rdsp)
return error("directive forbidden in gpu/dsp mode");
- if (m6502)
- return error(in_6502mode);
+ else if (m6502)
+ return error(in_6502mode);
if (cursect != BSS)
{
VALUE eval;
- if (cursect != M6502)
- {
- if ((siz != SIZB) && (sloc & 1)) // Automatic .even
- auto_even();
- }
+ if (cursect != M6502)
+ {
+ if ((siz != SIZB) && (sloc & 1)) // Automatic .even
+ auto_even();
+ }
if (abs_expr(&eval) != OK)
return 0;
listvalue(eval);
eval *= siz;
sloc += eval;
- if (cursect == M6502) chptr += eval;
+
+ if (cursect == M6502)
+ chptr += eval;
+
just_bss = 1; // No data deposited (8-bit CPU mode)
}
else
MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
// Deposit 68000 or 6502 (byte-reversed) word
- if (cursect != M6502)
- {
- D_word(eval);
- }
- else
- {
- D_rword(eval);
- }
-
+ if (cursect != M6502)
+ D_word(eval)
+ else
+ D_rword(eval)
}
break;
case SIZL:
- if (m6502)
- return error(in_6502mode);
+ if (m6502)
+ return error(in_6502mode);
if (!defined)
{
// Deposit 68000 or 6502 (byte-reversed) word
if (cursect != M6502)
- {
- D_word(eval);
- }
+ D_word(eval)
else
- {
- D_rword(eval);
- }
+ D_rword(eval)
}
case SIZL:
if (m6502)
return error(in_6502mode);
-
+
if (!defined)
{
AddFixup(FU_LONG, sloc, exprbuf);
#include "rmac.h"
-// Globals, Externals etc
+// Exported variables
extern TOKEN exprbuf[];
extern SYM * symbolPtr[];
extern int (* dirtab[])();
-extern int as68_flag; /* 1, AS68 kludge mode for Alcyon back-end */
-extern int m6502; /* 1, assembler in 6502 mode */
-extern char in_6502mode[];
-extern uint16_t *currentorg;
-// Prototypes
-int d_even(void);
+// Exported functions
void auto_even(void);
int dep_block(VALUE, WORD, VALUE, WORD, TOKEN *);
-int d_unimpl(void);
-int d_even(void);
-int d_6502(void);
-int d_68000(void);
-int d_bss(void);
-int d_data(void);
-int d_text(void);
-int d_abs(void);
-int d_comm(void);
-int d_dc(WORD);
-int d_ds(WORD);
-int d_dcb(WORD);
-int d_globl(void);
-int d_gpu(void);
-int d_dsp(void);
-int d_assert(void);
-int d_if(void);
-int d_endif(void);
-int d_include(void);
-int ExitMacro(void);
-int d_list(void);
-int d_nlist(void);
-int d_title(void);
-int d_subttl(void);
int eject(void);
-int d_error(char *);
-int d_warn(char *);
-int d_org(void);
-int d_init(WORD);
-int d_cargs(void);
-int d_undmac(void);
-int d_regbank0(void);
-int d_regbank1(void);
+int abs_expr(VALUE *);
+int symlist(int(*)());
+
+int d_even(void);
int d_long(void);
int d_phrase(void);
int d_dphrase(void);
int d_qphrase(void);
-int d_incbin(void);
-int d_noclear(void);
-int d_equrundef(void);
-int d_ccundef(void);
-int d_print(void);
-int d_gpumain(void);
-int d_jpad(void);
-int d_nojpad(void);
-int d_fail(void);
-int symlist(int(*)());
-int abs_expr(VALUE *);
-int d_cstruct(void);
-int d_prgflags(void);
-int d_opt(void);
#endif // __DIRECT_H__
+
// Source utilised with the kind permission of Landon Dyer
//
-#include "rmac.h"
+#include "eagen.h"
#include "amode.h"
#include "sect.h"
#include "mark.h"
#include "rmac.h"
-#define EBUFSIZ 200 // Max size of an error message
+#define EBUFSIZ 200 // Max size of an error message
-// Globals, externals etc
+// Exported variables
extern int errcnt;
extern char * err_fname;
-// Prototypes
+// Exported functions
int error(const char *);
int errors(const char *, char *);
int fatal(const char *);
//
void InitExpression(void)
{
- int i;
- char * p;
-
// Initialize token-class table (all set to END)
- for(i=0; i<256; i++)
+ for(int i=0; i<256; i++)
tokenClass[i] = END;
- for(i=0, p=itokcl; *p!=1; p++)
+ int i = 0;
+
+ for(char * p=itokcl; *p!=1; p++)
{
if (*p == 0)
i++;
#define XOR 11 // Bitwise xor: ^
#define OR 12 // Bitwise or: |
-// Prototypes
+// Exported functions
void InitExpression(void);
int expr1(void);
int expr2(void);
#define TAG_COL 38 // Tag character
#define SRC_COL 40 // Source start
-// Globals, externals etc
+// Exported variables
extern char * list_fname;
extern int listing;
extern int pagelen;
extern int nlines;
extern LONG lsloc;
+extern uint8_t subttl[];
-// Prototypes
-void InitListing(void);
+// Exported functions
int eject(void);
-void ship_ln(const char *);
+VALUE dos_date(void);
+VALUE dos_time(void);
void taglist(char);
void println(const char *);
+void ship_ln(const char *);
+void InitListing(void);
void listeol(void);
-VALUE dos_date(void);
-VALUE dos_time(void);
void lstout(char);
int listvalue(VALUE);
int d_subttl(void);
int d_title(void);
#endif // __LISTING_H__
+
//
#include "mach.h"
+#include "eagen.h"
#include "error.h"
-#include "sect.h"
#include "direct.h"
-#include "token.h"
#include "procln.h"
#include "riscasm.h"
#include "rmac.h"
+#include "sect.h"
+#include "token.h"
#define DEF_KW
#include "kwtab.h"
+// Exported variables
+int movep = 0; // Global flag to indicate we're generating a movep instruction
-// Fucntion prototypes
+// Function prototypes
int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
int m_self(WORD, WORD);
int m_abcd(WORD, WORD);
char undef_error[] = "undefined expression";
char fwd_error[] = "forward or undefined expression";
-extern int ea0gen(WORD);
-extern int ea1gen(WORD);
-
// Include code tables
MNTAB machtab[] = {
// { (WORD)-1, (unsigned long)-1L, (unsigned long)-1L, 0x0000, 0, m_badmode }, // 0
return 0;
}
-int movep = 0; // Global flag to indicate we're generating a movep instruction
//
// movep Dn, disp(An) -- movep disp(An), Dn
//
#ifndef __MACH_H__
#define __MACH_H__
-#include "rmac.h"
#include "amode.h"
// Exported variables
#include "rmac.h"
-// Globals, externals etc
+// Exported variables
extern LONG curuniq;
-//extern TOKEN ** argp;
-//extern int mjump_align;
extern TOKEN * argPtrs[];
-// Prototypes
+// Exported functions
void InitMacro(void);
int ExitMacro(void);
int DefineMacro(void);
CFLAGS = -std=$(STD) -D_DEFAULT_SOURCE -g -D__GCCUNIX__ -I. -O2
-SRCS = amode.c debug.c direct.c eagen.c error.c expr.c listing.c mach.c macro.c mark.c object.c procln.c riscasm.c rmac.c sect.c symbol.c token.c 6502.c
+SRCS = 6502.c amode.c debug.c direct.c eagen.c error.c expr.c listing.c mach.c macro.c mark.c object.c procln.c riscasm.c rmac.c sect.c symbol.c token.c
-OBJS = amode.o debug.o direct.o eagen.o error.o expr.o listing.o mach.o macro.o mark.o object.o procln.o riscasm.o rmac.o sect.o symbol.o token.o 6502.o
+OBJS = 6502.o amode.o debug.o direct.o eagen.o error.o expr.o listing.o mach.o macro.o mark.o object.o procln.o riscasm.o rmac.o sect.o symbol.o token.o
#
# Build everything
./kwgen kw <kwtab >kwtab.h
6502.h : 6502.tbl kwgen
- ./kwgen mp <6502.tbl >6502.h
+ ./kwgen mp <6502.tbl >6502kw.h
risckw.h : kwtab kwgen
./kwgen mr <risctab >risckw.h
# Build RMAC executable
#
-amode.o : amode.c
+amode.o : amode.c amode.h
$(CC) $(CFLAGS) -c amode.c
-debug.o : debug.c
+debug.o : debug.c debug.h
$(CC) $(CFLAGS) -c debug.c
-direct.o : direct.c
+direct.o : direct.c direct.h
$(CC) $(CFLAGS) -c direct.c
-eagen.o : eagen.c
+eagen.o : eagen.c eagen.h eagen0.c
$(CC) $(CFLAGS) -c eagen.c
-error.o : error.c
+error.o : error.c error.h
$(CC) $(CFLAGS) -c error.c
-expr.o : expr.c
+expr.o : expr.c expr.h
$(CC) $(CFLAGS) -c expr.c
-listing.o : listing.c
+listing.o : listing.c listing.h
$(CC) $(CFLAGS) -c listing.c
-mach.o : mach.c
+mach.o : mach.c mach.h
$(CC) $(CFLAGS) -c mach.c
-macro.o : macro.c
+macro.o : macro.c macro.h
$(CC) $(CFLAGS) -c macro.c
-mark.o : mark.c
+mark.o : mark.c mark.h
$(CC) $(CFLAGS) -c mark.c
-object.o : object.c
+object.o : object.c object.h
$(CC) $(CFLAGS) -c object.c
-procln.o : procln.c
+procln.o : procln.c procln.h
$(CC) $(CFLAGS) -c procln.c
-risca.o : risca.c
+risca.o : risca.c risca.h
$(CC) $(CFLAGS) -c risca.c
-rmac.o : rmac.c
+rmac.o : rmac.c rmac.h
$(CC) $(CFLAGS) -c rmac.c
-sect.o : sect.c
+sect.o : sect.c sect.h
$(CC) $(CFLAGS) -c sect.c
-symbol.o : symbol.c
+symbol.o : symbol.c symbol.h
$(CC) $(CFLAGS) -c symbol.c
-6502.o : 6502.c
+6502.o : 6502.c 6502.h
$(CC) $(CFLAGS) -c 6502.c
-token.o : token.c
+token.o : token.c token.h
$(CC) $(CFLAGS) -c token.c
rmac : $(OBJS)
#
clean:
- $(rm) $(OBJS) kwgen.o 68kgen.o rmac kwgen 68kgen kwtab.h 68ktab.h mntab.h risckw.h
+ $(rm) $(OBJS) kwgen.o 68kgen.o rmac kwgen 68kgen kwtab.h 68ktab.h mntab.h risckw.h 6502kw.h
//
-// Add entry to symbol table
+// Add entry to symbol table (in ALCYON mode)
// If 'globflag' is 1, make the symbol global
// If in .PRG mode, adjust symbol values for fake link
//
free(strtable);
}
}
- else if (obj_format == XEX)
- {
- // Just write the object file
- m6502obj(fd);
- }
+ else if (obj_format == XEX)
+ {
+ // Just write the object file
+ m6502obj(fd);
+ }
return 0;
}
//
#include "procln.h"
-#include "listing.h"
+#include "6502.h"
#include "amode.h"
+#include "direct.h"
#include "error.h"
-#include "sect.h"
#include "expr.h"
+#include "listing.h"
#include "mach.h"
-#include "direct.h"
#include "macro.h"
-#include "symbol.h"
#include "riscasm.h"
+#include "sect.h"
+#include "symbol.h"
#define DEF_KW // Declare keyword values
#include "kwtab.h" // Incl generated keyword tables & defs
#define DECL_MR
#include "risckw.h"
-#define DEF_MP /* include 6502 keyword definitions */
-#define DECL_MP /* include 6502 keyword state machine tables */
-#include "6502.h"
-extern int m6502; /* 1, assembler in .6502 mode */
-extern VOID m6502cg(); /* 6502 code generator */
-extern VOID m6502obj(int ofd);
+#define DEF_MP // Include 6502 keyword definitions
+#define DECL_MP // Include 6502 keyword state machine tables
+#include "6502kw.h"
IFENT * ifent; // Current ifent
static IFENT ifent0; // Root ifent
if (state == -3)
goto loop;
- /*
- * If we're in 6502 mode and are still in need
- * of a mnemonic, then search for valid 6502 mnemonic.
- */
- if (m6502 &&
- (state < 0 || state >= 1000))
+ // If we're in 6502 mode and are still in need of a mnemonic, then search
+ // for valid 6502 mnemonic.
+ if (m6502 && (state < 0 || state >= 1000))
{
#ifdef ST
state = kmatch(opname, mpbase, mpcheck, mptab, mpaccept);
#else
- for (state = 0, p = opname; state >= 0;)
+ for(state=0, p=opname; state>= 0; )
{
j = mpbase[state] + tolowertab[*p];
- if (mpcheck[j] != state) /* reject, character doesn't match */
+
+ if (mpcheck[j] != state) // Reject, character doesn't match
{
- state = -1; /* no match */
+ state = -1; // No match
break;
}
if (!*++p)
- { /* must accept or reject at EOS */
- state = mpaccept[j]; /* (-1 on no terminal match) */
+ { // Must accept or reject at EOS
+ state = mpaccept[j]; // (-1 on no terminal match)
break;
}
+
state = mptab[j];
}
#endif
- /*
- * Call 6502 code generator if we found a mnemonic
- */
+ // Call 6502 code generator if we found a mnemonic
if (state >= 2000)
{
m6502cg(state - 2000);
goto loop;
}
}
-
+
// If we are in GPU or DSP mode and still in need of a mnemonic then search
// for one
if ((rgpu || rdsp) && (state < 0 || state >= 1000))
#include "rmac.h"
#include "token.h"
-// Globals, externals etc
+// Exported variables
extern IFENT * ifent;
extern const char comma_error[];
extern const char locgl_error[];
extern VALUE pcloc;
extern SYM * lab_sym;
extern LONG amsktab[];
-extern char in_6502mode[];
-// Prototypes
+// Exported functions
void InitLineProcessor(void);
void Assemble(void);
int d_if(void);
int d_endif(void);
#endif // __PROCLN_H__
+
//
#include "riscasm.h"
+#include "amode.h"
+#include "direct.h"
#include "error.h"
-#include "sect.h"
-#include "token.h"
#include "expr.h"
-#include "direct.h"
#include "mark.h"
-#include "amode.h"
+#include "procln.h"
+#include "sect.h"
+#include "token.h"
#define DEF_MR // Declare keyword values
#include "risckw.h" // Incl. generated risc keywords
#define __RISCA_H__
#include "rmac.h"
-#include "procln.h"
#define MAXINTERNCC 26 // Maximum internal condition codes
//
#include "rmac.h"
+#include "6502.h"
+#include "debug.h"
+#include "direct.h"
#include "error.h"
-#include "listing.h"
-#include "procln.h"
-#include "token.h"
#include "expr.h"
-#include "sect.h"
+#include "listing.h"
#include "mark.h"
#include "macro.h"
+#include "object.h"
+#include "procln.h"
#include "riscasm.h"
-#include "direct.h"
-#include "version.h"
-#include "debug.h"
+#include "sect.h"
#include "symbol.h"
-#include "object.h"
+#include "token.h"
+#include "version.h"
int perm_verb_flag; // Permanently verbose, interactive mode
int list_flag; // "-l" listing flag on command line
" a: ALCYON (use this for ST)\n"
" b: BSD (use this for Jaguar)\n"
" e: ELF\n"
- " x: com/exe/xex (Atari 800)\n"
+ " x: com/exe/xex (Atari 800)\n"
" -i[path] Directory to search for include files\n"
" -l[filename] Create an output listing file\n"
" -n Don't do things behind your back in RISC assembler\n"
" -o file Output file name\n"
" +o[value] Turn a specific optimisation on\n"
- " Available optimisation values and default settings:\n"
- " o0: Absolute long adddresses to word (on)\n"
- " o1: move.l #x,dn/an to moveq (on)\n"
- " o2: Word branches to short (on)\n"
- " o3: Outer displacement 0(an) to (an) (off)\n"
+ " Available optimisation values and default settings:\n"
+ " o0: Absolute long adddresses to word (on)\n"
+ " o1: move.l #x,dn/an to moveq (on)\n"
+ " o2: Word branches to short (on)\n"
+ " o3: Outer displacement 0(an) to (an) (off)\n"
" ~o[value] Turn a specific optimisation off\n"
" +oall Turn all optimisations on\n"
" ~oall Turn all optimisations off\n"
orgactive = 0; // Not in RISC org section
orgwarning = 0; // No ORG warning issued
segpadsize = 2; // Initialise segment padding size
- m6502 = 0; // 6502 mode off by default
+ m6502 = 0; // 6502 mode off by default
// Initialise modules
InitSymbolTable(); // Symbol table
InitMark(); // Mark tape-recorder
InitMacro(); // Macro processor
InitListing(); // Listing generator
- Init6502(); // 6502 assembler
+ Init6502(); // 6502 assembler
// Process command line arguments and assemble source files
- for(argno=0; argno<argc; ++argno)
+ for(argno=0; argno<argc; argno++)
{
if (*argv[argno] == '-')
{
case 'E':
obj_format = ELF;
break;
- case 'x': // -fx = COM/EXE/XEX
- case 'X':
- obj_format = XEX;
- break;
+ case 'x': // -fx = COM/EXE/XEX
+ case 'X':
+ obj_format = XEX;
+ break;
default:
printf("-f: unknown object format specified\n");
errcnt++;
SaveSection();
}
- SwitchSection(M6502);
- if (sloc != currentorg[0])
- {
- currentorg[1] = sloc;
- currentorg += 2;
- }
+ SwitchSection(M6502);
+
+ if (sloc != currentorg[0])
+ {
+ currentorg[1] = sloc;
+ currentorg += 2;
+ }
if (objfname == NULL)
{
(a)[(r + 6)] = (uint8_t)(((v) >> 8) & 0xFF); \
(a)[(r + 7)] = (uint8_t)((v) & 0xFF); }
+// In 6502 mode, turns out we need this:
+#define SETLE16(a, r, v) \
+ { (a)[(r + 0)] = (uint8_t)((v) & 0xFF); \
+ (a)[(r + 1)] = (uint8_t)((v) >> 8); }
+
// Byteswap crap
#define BYTESWAP16(x) ((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
#define BYTESWAP32(x) ((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
#define MWC 1 // Mark Williams object format
#define BSD 2 // BSD object format
#define ELF 3 // ELF object format
-#define XEX 4 // COM/EXE/XEX/whatever a8 object format
+#define XEX 4 // COM/EXE/XEX/whatever a8 object format
// Pointer type that can point to (almost) anything
#define PTR union _ptr
#define TEXT 0x0001 // Relative to text
#define DATA 0x0002 // Relative to data
#define BSS 0x0004 // Relative to BSS
-#define M6502 0x0008 // 6502/microprocessor (absolute)
+#define M6502 0x0008 // 6502/microprocessor (absolute)
#define TDB (TEXT|DATA|BSS) // Mask for text+data+bss
// Sizes
#define EQUATEDCC 0x0020
#define UNDEF_CC 0x0040
-//#define RISCSYM 0x00010000
-
// Optimisation defines
enum
{
OPT_COUNT // Dummy, used to count number of optimisation switches
};
-// Globals, externals, etc.
+// Exported variables
extern int verb_flag;
extern int debug;
extern int rgpu, rdsp;
extern int prg_flag; // 1 = write ".PRG" relocatable executable
extern LONG PRGFLAGS;
extern int optim_flags[OPT_COUNT];
-extern void Init6502();
// Exported functions
char * fext(char *, char *, int);
//
#include "sect.h"
+#include "6502.h"
#include "direct.h"
#include "error.h"
#include "expr.h"
#include "riscasm.h"
#include "symbol.h"
#include "token.h"
-extern int m6502; /* 1, assembler in .6502 mode */
// Function prototypes
*/
if (sno == M6502)
cch->ch_size = cch->challoc;
-
+
do
{
fup.cp = ch->chptr; // fup -> start of chunk
*locp = (uint8_t)eval;
break;
- // Fixup high/low byte off word for 6502
- case FU_BYTEH:
- if (!(eattr & DEFINED))
- {
- error("external byte reference");
- continue;
- }
-
- *locp = (uint8_t)((eval >> 8) & 0xff);
- break;
- case FU_BYTEL:
- if (!(eattr & DEFINED))
- {
- error("external byte reference");
- continue;
- }
-
- *locp = (uint8_t)(eval & 0xff);
- break;
+ // Fixup high/low byte off word for 6502
+ case FU_BYTEH:
+ if (!(eattr & DEFINED))
+ {
+ error("external byte reference");
+ continue;
+ }
+
+ *locp = (uint8_t)((eval >> 8) & 0xFF);
+ break;
+ case FU_BYTEL:
+ if (!(eattr & DEFINED))
+ {
+ error("external byte reference");
+ continue;
+ }
+
+ *locp = (uint8_t)(eval & 0xFF);
+ break;
// Fixup WORD forward references;
// the word could be unaligned in the section buffer, so we have to
// be careful.
}
}
- if (sno != M6502)
- {
- *locp++ = (char)(eval >> 8);
- *locp = (char)eval;
- }
+ // 6502 words are little endian, so handle that here
+ if (sno == M6502)
+ SETLE16(locp, 0, eval)
else
- {
- SETBE16(locp, 0, eval);
- }
+ SETBE16(locp, 0, eval)
+
break;
// Fixup LONG forward references;
// the long could be unaligned in the section buffer, so be careful
// token.L expression list
// (etc)
// ENDEXPR.L (end of expression)
-#define FUMASK 007 // Mask for fixup cases:
-#define FU_QUICK 000 // Fixup 3-bit quick instr field
-#define FU_BYTE 001 // Fixup byte
-#define FU_WORD 002 // Fixup word
-#define FU_WBYTE 003 // Fixup byte (at loc+1)
-#define FU_LONG 004 // Fixup long
-#define FU_BBRA 005 // Fixup byte branch
-#define FU_6BRA 007 // Fixup 6502-format branch offset
-#define FU_BYTEH 050 // Fixup 6502 high byte of immediate word
-#define FU_BYTEL 051 // Fixup 6502 low byte of immediate word
-#define FU_SEXT 010 // Ok to sign extend
-#define FU_PCREL 020 // Subtract PC first
-#define FU_EXPR 040 // Expression (not symbol) follows
+#define FUMASK 0x000F // Mask for fixup cases:(shouldn't this be $7F?)
+#define FU_QUICK 0x0000 // Fixup 3-bit quick instruction field
+#define FU_BYTE 0x0001 // Fixup byte
+#define FU_WORD 0x0002 // Fixup word
+#define FU_WBYTE 0x0003 // Fixup byte (at loc+1)
+#define FU_LONG 0x0004 // Fixup long
+#define FU_BBRA 0x0005 // Fixup byte branch
+#define FU_6BRA 0x0007 // Fixup 6502-format branch offset
+#define FU_BYTEH 0x0008 // Fixup 6502 high byte of immediate word
+#define FU_BYTEL 0x0009 // Fixup 6502 low byte of immediate word
+
+#define FU_SEXT 0x0010 // Ok to sign extend
+#define FU_PCREL 0x0020 // Subtract PC first
+#define FU_EXPR 0x0040 // Expression (not symbol) follows
#define FU_GLOBAL 0x0080 // Mark global symbol
uint32_t uid; // Symbol's unique ID
};
-// Globals, externals, etc.
+// Exported variables
extern int curenv;
-extern uint8_t subttl[];
extern uint32_t firstglobal;// Index of the fist global symbol in an ELF object.
// Exported functions
#include "error.h"
#include "macro.h"
#include "procln.h"
+#include "sect.h"
#include "symbol.h"
#define DECL_KW // Declare keyword arrays
// Information about a macro invocation
IMACRO {
IMACRO * im_link; // Pointer to ancient IMACROs
-// LONG * im_nextln; // Next line to include
struct LineList * im_nextln; // Next line to include
WORD im_nargs; // # of arguments supplied on invocation
WORD im_siz; // Size suffix supplied on invocation
extern char lntag;
extern char tolowertab[];
extern INOBJ * cur_inobj;
-extern unsigned orgactive;
-extern unsigned orgaddr;
-extern LONG sloc;
extern int mjump_align;
extern char * string[];
int TokenizeLine(void);
int fpop(void);
int d_goto(WORD);
-//int d_goto(void);
INOBJ * a_inobj(int);
void DumpTokenBuffer(void);
#endif // __TOKEN_H__
+
// Release Information
#define MAJOR 1 // Major version number
-#define MINOR 5 // Minor version number
-#define PATCH 3 // Patch release number
+#define MINOR 6 // Minor version number
+#define PATCH 0 // Patch release number
#endif // __VERSION_H__