From ff2052bcaa1428a33a202822a81a6f9b8e567ef4 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Thu, 20 Apr 2017 14:29:31 -0500 Subject: [PATCH] Code cleanup, version bump for last commit. :-) --- 6502.c | 657 ++++++++++++++++++++++++++++-------------------------- amode.h | 2 +- debug.h | 2 +- direct.c | 224 +++++++++++-------- direct.h | 60 +---- eagen.c | 2 +- error.h | 6 +- expr.c | 9 +- expr.h | 2 +- listing.h | 14 +- mach.c | 13 +- mach.h | 1 - macro.h | 6 +- makefile | 44 ++-- object.c | 12 +- procln.c | 45 ++-- procln.h | 6 +- riscasm.c | 9 +- riscasm.h | 1 - rmac.c | 56 ++--- rmac.h | 14 +- sect.c | 55 +++-- sect.h | 27 +-- symbol.h | 3 +- token.c | 1 + token.h | 6 +- version.h | 4 +- 27 files changed, 636 insertions(+), 645 deletions(-) diff --git a/6502.c b/6502.c index 823263a..0e203f0 100644 --- a/6502.c +++ b/6502.c @@ -1,49 +1,35 @@ -/* - * 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 @@ -59,11 +45,11 @@ uint16_t *currentorg = (uint16_t *)orgmap; /* current org range */ #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[] = { @@ -139,48 +125,48 @@ 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; ichptr, 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 ')' 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 ',' */ - 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 ')' 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 ',' + 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; } @@ -422,31 +436,35 @@ badmode: 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: @@ -455,6 +473,7 @@ badmode: case A65_ZPX: case A65_ZPY: D_byte(ops[op][amode]); + if (!(eattr & DEFINED)) { AddFixup(FU_BYTE, sloc, exprbuf); @@ -465,19 +484,23 @@ badmode: 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 @@ -485,6 +508,7 @@ badmode: AddFixup(FU_6BRA, sloc, exprbuf); D_byte(0); } + break; case A65_ABS: @@ -492,68 +516,65 @@ badmode: 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= 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; } @@ -495,8 +527,8 @@ static inline void SkipBytes(unsigned bytesToSkip) // int d_even(void) { - if (m6502) - return error(in_6502mode); + if (m6502) + return error(in_6502mode); unsigned skip = (rgpu || rdsp ? orgaddr : sloc) & 0x01; @@ -593,16 +625,16 @@ int d_qphrase(void) // 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++; + } } @@ -771,8 +803,8 @@ int globl1(char * p) int d_globl(void) { - if (m6502) - return error(in_6502mode); + if (m6502) + return error(in_6502mode); symlist(globl1); return 0; @@ -807,9 +839,9 @@ int d_abs(void) { VALUE eval; - if (m6502) - return error(in_6502mode); - + if (m6502) + return error(in_6502mode); + SaveSection(); if (*tok == EOL) @@ -830,8 +862,8 @@ int d_text(void) { 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) { @@ -847,8 +879,8 @@ int d_data(void) { 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) { @@ -864,8 +896,8 @@ int d_bss(void) { 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) { @@ -886,11 +918,11 @@ int d_ds(WORD siz) 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; @@ -908,7 +940,10 @@ int d_ds(WORD siz) 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 @@ -1021,21 +1056,16 @@ int d_dc(WORD siz) 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) { @@ -1222,13 +1252,9 @@ int dep_block(VALUE count, WORD siz, VALUE eval, WORD eattr, TOKEN * exprbuf) // Deposit 68000 or 6502 (byte-reversed) word if (cursect != M6502) - { - D_word(eval); - } + D_word(eval) else - { - D_rword(eval); - } + D_rword(eval) } @@ -1236,7 +1262,7 @@ int dep_block(VALUE count, WORD siz, VALUE eval, WORD eattr, TOKEN * exprbuf) case SIZL: if (m6502) return error(in_6502mode); - + if (!defined) { AddFixup(FU_LONG, sloc, exprbuf); diff --git a/direct.h b/direct.h index 57cdd63..27219e5 100644 --- a/direct.h +++ b/direct.h @@ -11,69 +11,23 @@ #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__ + diff --git a/eagen.c b/eagen.c index e94c21b..ca87fcc 100644 --- a/eagen.c +++ b/eagen.c @@ -6,7 +6,7 @@ // Source utilised with the kind permission of Landon Dyer // -#include "rmac.h" +#include "eagen.h" #include "amode.h" #include "sect.h" #include "mark.h" diff --git a/error.h b/error.h index 693fe51..aa431a5 100644 --- a/error.h +++ b/error.h @@ -11,13 +11,13 @@ #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 *); diff --git a/expr.c b/expr.c index b7bf4b1..debcd88 100644 --- a/expr.c +++ b/expr.c @@ -77,14 +77,13 @@ static VALUE str_value(char * p) // 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++; diff --git a/expr.h b/expr.h index ebba659..e8436f4 100644 --- a/expr.h +++ b/expr.h @@ -30,7 +30,7 @@ #define XOR 11 // Bitwise xor: ^ #define OR 12 // Bitwise or: | -// Prototypes +// Exported functions void InitExpression(void); int expr1(void); int expr2(void); diff --git a/listing.h b/listing.h index e447f35..dbc49c5 100644 --- a/listing.h +++ b/listing.h @@ -22,25 +22,27 @@ #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__ + diff --git a/mach.c b/mach.c index ca7e17c..71fd3cb 100644 --- a/mach.c +++ b/mach.c @@ -7,19 +7,22 @@ // #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); @@ -54,9 +57,6 @@ char siz_error[] = "bad size specified"; 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 @@ -499,7 +499,6 @@ int m_moveq(WORD inst, WORD siz) return 0; } -int movep = 0; // Global flag to indicate we're generating a movep instruction // // movep Dn, disp(An) -- movep disp(An), Dn // diff --git a/mach.h b/mach.h index 834f3bd..b95636e 100644 --- a/mach.h +++ b/mach.h @@ -9,7 +9,6 @@ #ifndef __MACH_H__ #define __MACH_H__ -#include "rmac.h" #include "amode.h" // Exported variables diff --git a/macro.h b/macro.h index 3884ac7..06274ec 100644 --- a/macro.h +++ b/macro.h @@ -11,13 +11,11 @@ #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); diff --git a/makefile b/makefile index 99325d6..49e00db 100644 --- a/makefile +++ b/makefile @@ -26,9 +26,9 @@ HOSTCC = gcc 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 @@ -54,7 +54,7 @@ kwtab.h : kwtab kwgen ./kwgen kw 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 risckw.h @@ -79,58 +79,58 @@ kwgen : kwgen.o # 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) @@ -141,5 +141,5 @@ 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 diff --git a/object.c b/object.c index 3cae547..af019f0 100644 --- a/object.c +++ b/object.c @@ -57,7 +57,7 @@ See left. 4 & 5 If these bits are set to 0 (PF_PRIVATE), the processes' // -// 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 // @@ -752,11 +752,11 @@ for(int j=0; j= 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)) diff --git a/procln.h b/procln.h index 4acf856..ccb958f 100644 --- a/procln.h +++ b/procln.h @@ -12,7 +12,7 @@ #include "rmac.h" #include "token.h" -// Globals, externals etc +// Exported variables extern IFENT * ifent; extern const char comma_error[]; extern const char locgl_error[]; @@ -22,9 +22,8 @@ extern int just_bss; 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); @@ -32,3 +31,4 @@ int d_else(void); int d_endif(void); #endif // __PROCLN_H__ + diff --git a/riscasm.c b/riscasm.c index fb29b5a..74de784 100644 --- a/riscasm.c +++ b/riscasm.c @@ -7,13 +7,14 @@ // #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 diff --git a/riscasm.h b/riscasm.h index 96623e6..83bd824 100644 --- a/riscasm.h +++ b/riscasm.h @@ -10,7 +10,6 @@ #define __RISCA_H__ #include "rmac.h" -#include "procln.h" #define MAXINTERNCC 26 // Maximum internal condition codes diff --git a/rmac.c b/rmac.c index 6bf5a50..77c37e7 100644 --- a/rmac.c +++ b/rmac.c @@ -7,20 +7,21 @@ // #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 @@ -130,17 +131,17 @@ void DisplayHelp(void) " 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" @@ -252,7 +253,7 @@ int Process(int argc, char ** argv) 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 @@ -263,10 +264,10 @@ int Process(int argc, char ** argv) 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> 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)) @@ -189,7 +194,7 @@ #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 @@ -222,7 +227,7 @@ 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 @@ -240,8 +245,6 @@ PTR #define EQUATEDCC 0x0020 #define UNDEF_CC 0x0040 -//#define RISCSYM 0x00010000 - // Optimisation defines enum { @@ -252,7 +255,7 @@ 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; @@ -272,7 +275,6 @@ extern int legacy_flag; 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); diff --git a/sect.c b/sect.c index 965fcf0..7a88a56 100644 --- a/sect.c +++ b/sect.c @@ -7,6 +7,7 @@ // #include "sect.h" +#include "6502.h" #include "direct.h" #include "error.h" #include "expr.h" @@ -16,7 +17,6 @@ #include "riscasm.h" #include "symbol.h" #include "token.h" -extern int m6502; /* 1, assembler in .6502 mode */ // Function prototypes @@ -417,7 +417,7 @@ int ResolveFixups(int sno) */ if (sno == M6502) cch->ch_size = cch->challoc; - + do { fup.cp = ch->chptr; // fup -> start of chunk @@ -592,25 +592,25 @@ int ResolveFixups(int sno) *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. @@ -741,15 +741,12 @@ int ResolveFixups(int sno) } } - 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 diff --git a/sect.h b/sect.h index d34dec2..65264ae 100644 --- a/sect.h +++ b/sect.h @@ -59,19 +59,20 @@ // 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 diff --git a/symbol.h b/symbol.h index 9c5c26a..c726bde 100644 --- a/symbol.h +++ b/symbol.h @@ -36,9 +36,8 @@ SYM 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 diff --git a/token.c b/token.c index 8726eb4..9083c99 100644 --- a/token.c +++ b/token.c @@ -10,6 +10,7 @@ #include "error.h" #include "macro.h" #include "procln.h" +#include "sect.h" #include "symbol.h" #define DECL_KW // Declare keyword arrays diff --git a/token.h b/token.h index 1deec2c..91230e5 100644 --- a/token.h +++ b/token.h @@ -119,7 +119,6 @@ TOKENSTREAM { // 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 @@ -147,9 +146,6 @@ extern char lnbuf[]; 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[]; @@ -160,8 +156,8 @@ void SetFilenameForErrorReporting(void); int TokenizeLine(void); int fpop(void); int d_goto(WORD); -//int d_goto(void); INOBJ * a_inobj(int); void DumpTokenBuffer(void); #endif // __TOKEN_H__ + diff --git a/version.h b/version.h index 16ddabb..03ad2d0 100644 --- a/version.h +++ b/version.h @@ -14,8 +14,8 @@ // 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__ -- 2.37.2