From: Shamus Hammons Date: Sat, 10 Feb 2018 05:08:47 +0000 (-0600) Subject: Partial fix for bug #108 (Fixup cleanups). X-Git-Tag: v2.1.0~84 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=9153334781cd2e23750f4dc002e847606c07a1f0 Partial fix for bug #108 (Fixup cleanups). RMAC has needed a struct for fixups for some time, and now it has one. All of the credit for pushing (and patching!) in that direction goes to ggn; blame for the way it's implemented goes to me. There's still room for improvement; but for now, this should leave us in much better shape. Now at v1.12.0. --- diff --git a/6502.c b/6502.c index 8c16d8d..5978240 100644 --- a/6502.c +++ b/6502.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // 6502.C - 6502 Assembler -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/6502.h b/6502.h index c4f5fba..ccb2a57 100644 --- a/6502.h +++ b/6502.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // 6502.H - 6502 assembler -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/68kgen.c b/68kgen.c index ec3541d..ce15613 100644 --- a/68kgen.c +++ b/68kgen.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // 68KGEN.C - Tool to Generate 68000 Opcode Table -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/amode.c b/amode.c index f56fe9c..ccd86dd 100644 --- a/amode.c +++ b/amode.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // AMODE.C - Addressing Modes -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/amode.h b/amode.h index 2272b9c..e46be37 100644 --- a/amode.h +++ b/amode.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // AMODE.H - Addressing Modes -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/debug.c b/debug.c index 28784bf..9ef0bcb 100644 --- a/debug.c +++ b/debug.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // DEBUG.C - Debugging Messages -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -9,6 +9,7 @@ #include "debug.h" #include "amode.h" #include "direct.h" +#include "expr.h" #include "mark.h" #include "sect.h" #include "token.h" @@ -86,46 +87,32 @@ int chdump(CHUNK * ch, int format) // // Dump fixup records in printable format // -int fudump(CHUNK * ch) +int fudump(FIXUP * fup) { - PTR p; - - for(; ch!=NULL;) + for(; fup!=NULL;) { - p.cp = ch->chptr; - uint8_t * ep = ch->chptr + ch->ch_size; - - while (p.cp < ep) - { - uint16_t attr = *p.wp++; - uint32_t loc = *p.lp++; - uint16_t file = *p.wp++; - uint16_t line = *p.wp++; + uint32_t attr = fup->attr; + uint32_t loc = fup->loc; + uint16_t file = fup->fileno; + uint16_t line = fup->lineno; - printf("$%04X $%08X %d.%d: ", (int)attr, loc, (int)file, (int)line); + printf("$%08X $%08X %d.%d: ", attr, loc, (int)file, (int)line); - if (attr & FU_EXPR) - { - uint16_t esiz = *p.wp++; - printf("(%d long) ", (int)esiz); - p.tk = printexpr(p.tk); - } - else - { - printf("`%s' ;", (*p.sy)->sname); - p.sy++; - } + if (attr & FU_EXPR) + { + uint16_t esiz = ExpressionLength(fup->expr); + printf("(%d long) ", (int)esiz); + printexpr(fup->expr); + } + else + printf("`%s' ;", fup->symbol->sname); - if ((attr & 0x0F00) == FU_JR) - { - printf(" *=$%X", *p.lp); - p.lp++; - } + if ((attr & FUMASKRISC) == FU_JR) + printf(" *=$%X", fup->orgaddr); - printf("\n"); - } + printf("\n"); - ch = ch->chnext; + fup = fup->next; } return 0; diff --git a/debug.h b/debug.h index ad1ccac..71a6c78 100644 --- a/debug.h +++ b/debug.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // DEBUG.H - Debugging Messages -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/direct.c b/direct.c index e507bc5..9e39719 100644 --- a/direct.c +++ b/direct.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // DIRECT.C - Directive Handling -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -1429,7 +1429,7 @@ int d_comm(void) p = string[tok[1]]; tok += 2; - if (*p == '.') // Cannot .comm a local symbol + if (*p == '.') // Cannot .comm a local symbol return error(locgl_error); if ((sym = lookup(p, LABEL, 0)) == NULL) @@ -1445,10 +1445,10 @@ int d_comm(void) if (*tok++ != ',') return error(comma_error); - if (abs_expr(&eval) != OK) // Parse size of common region + if (abs_expr(&eval) != OK) // Parse size of common region return 0; - sym->svalue = (uint32_t)eval; // Install common symbol's size + sym->svalue = eval; // Install common symbol's size at_eol(); return 0; } @@ -1688,7 +1688,7 @@ int d_cargs(void) AddToSymbolDeclarationList(symbol); symbol->sattr |= (ABS | DEFINED | EQUATED); - symbol->svalue = (uint32_t)eval; + symbol->svalue = eval; tok += 2; // What this does is eat any dot suffixes attached to a symbol. If @@ -1815,7 +1815,7 @@ int d_cstruct(void) } symbol->sattr |= (ABS | DEFINED | EQUATED); - symbol->svalue = (uint32_t)eval; + symbol->svalue = eval; // Check for dot suffixes and adjust space accordingly (longs and // words on an odd boundary get bumped to the next word aligned diff --git a/direct.h b/direct.h index c89156d..dee418e 100644 --- a/direct.h +++ b/direct.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // DIRECT.H - Directive Handling -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/eagen.c b/eagen.c index ae349b8..5c83aad 100644 --- a/eagen.c +++ b/eagen.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // EAGEN.C - Effective Address Code Generation -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/eagen.h b/eagen.h index 7767739..dcca6a6 100644 --- a/eagen.h +++ b/eagen.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // EAGEN.H - Effective address generation for 68K -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/eagen0.c b/eagen0.c index b4b5886..1bc5fd6 100644 --- a/eagen0.c +++ b/eagen0.c @@ -2,7 +2,7 @@ // RMAC - Reboot's Macro Assembler for all Atari computers // EAGEN0.C - Effective Address Code Generation // Generated Code for eaN (Included twice by "eagen.c") -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -167,7 +167,7 @@ int eaNgen(WORD siz) if (v + 0x100 >= 0x200) return error(range_error); - D_word(v); + D_word(v & 0xFF); } else { diff --git a/error.c b/error.c index 13b3199..9b5460b 100644 --- a/error.c +++ b/error.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // ERROR.C - Error Handling -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/error.h b/error.h index a81ede7..f433728 100644 --- a/error.h +++ b/error.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // ERROR.H - Error Handling -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/expr.c b/expr.c index 82bb5c6..1d6ce38 100644 --- a/expr.c +++ b/expr.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // EXPR.C - Expression Analyzer -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -1066,3 +1066,27 @@ An open question here is do we promote ints to floats as signed or unsigned? It return OK; } + +// +// Count the # of tokens in the passed in expression +// N.B.: 64-bit constants count as two tokens each +// +uint16_t ExpressionLength(TOKEN * tk) +{ + uint16_t length; + + for(length=0; tk[length]!=ENDEXPR; length++) + { + // Add one to length for 2X tokens, two for 3X tokens + if (tk[length] == SYMBOL) + length++; + else if ((tk[length] == CONST) || (tk[length] == FCONST)) + length += 2; + } + + // Add 1 for ENDEXPR + length++; + + return length; +} + diff --git a/expr.h b/expr.h index f03ca1e..517c4a0 100644 --- a/expr.h +++ b/expr.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // EXPR.H - Expression Analyzer -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -36,5 +36,7 @@ int expr1(void); int expr2(void); int expr(TOKEN *, uint64_t *, WORD *, SYM **); int evexpr(TOKEN *, uint64_t *, WORD *, SYM **); +uint16_t ExpressionLength(TOKEN *); #endif // __EXPR_H__ + diff --git a/fltpoint.c b/fltpoint.c index 1de5d0a..fa1eb41 100644 --- a/fltpoint.c +++ b/fltpoint.c @@ -72,7 +72,7 @@ uint32_t FloatToIEEE754(float f) // [+0.5, +1)) and base-2 exponent // d = mantissa * (2 ^ exponent) *exactly* for FLT_RADIX=2 // Also, since we want the mantissa to be non-inverted (2's complemented), - // we make sure to pass in a positive number (floats/doubles are not 2's + // we make sure to pass in a positive number (floats/doubles are *not* 2's // complemented) as we already captured the sign bit above. int32_t exponent; float mantissa = frexpf((f < 0 ? -f : f), &exponent); @@ -111,7 +111,7 @@ uint64_t DoubleToIEEE754(double d) // and base-2 exponent // d = mantissa * (2 ^ exponent) *exactly* for FLT_RADIX=2 // Also, since we want the mantissa to be non-inverted (2's complemented), - // we make sure to pass in a positive number (floats/doubles are not 2's + // we make sure to pass in a positive number (floats/doubles are *not* 2's // complemented) as we already captured the sign bit above. double mantissa = frexp((d < 0 ? -d : d), &exponent); diff --git a/fltpoint.h b/fltpoint.h index 20caa72..c3d4038 100644 --- a/fltpoint.h +++ b/fltpoint.h @@ -1,6 +1,9 @@ // // Cross-platform floating point handling // +// by James Hammons +// (C) 2018 Underground Software +// #include diff --git a/kwgen.c b/kwgen.c index 1717edf..ae8e125 100644 --- a/kwgen.c +++ b/kwgen.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // KWGEN.C - Keyword & Mnemonic Definition and State Machine Creation Tool -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/listing.c b/listing.c index 77226c7..f6e7eb0 100644 --- a/listing.c +++ b/listing.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // LISTING.C - Listing Output -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/listing.h b/listing.h index 54cafb5..d60793b 100644 --- a/listing.h +++ b/listing.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // LISTING.H - Listing Output -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/mach.c b/mach.c index 7c1ab8e..08a9bab 100644 --- a/mach.c +++ b/mach.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // MACH.C - Code Generation -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/mach.h b/mach.h index 55e089d..e9b7c82 100644 --- a/mach.h +++ b/mach.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // MACH.H - Code Generation -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/macro.c b/macro.c index c92b2db..4ca149d 100644 --- a/macro.c +++ b/macro.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // MACRO.C - Macro Definition and Invocation -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/macro.h b/macro.h index 0062314..49e387d 100644 --- a/macro.h +++ b/macro.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // MACRO.H - Macro Definition and Invocation -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/mark.c b/mark.c index 2a089c3..53eaf87 100644 --- a/mark.c +++ b/mark.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // MARK.C - A record of things that are defined relative to any of the sections -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/mark.h b/mark.h index 4222bbf..5e97d8a 100644 --- a/mark.h +++ b/mark.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // MARK.H - A record of things that are defined relative to any of the sections -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/object.c b/object.c index a184796..9f9de01 100644 --- a/object.c +++ b/object.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // OBJECT.C - Writing Object Files -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/object.h b/object.h index a26ac66..4cac13b 100644 --- a/object.h +++ b/object.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // OBJECT.H - Writing Object Files -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/parmode.h b/parmode.h index e0de037..690b616 100644 --- a/parmode.h +++ b/parmode.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // PARMODE.C - Addressing Modes Parser Include -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/procln.c b/procln.c index 8dd19c6..addff04 100644 --- a/procln.c +++ b/procln.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // PROCLN.C - Line Processing -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -398,13 +398,11 @@ normal: { if ((equtyp == EQUREG) && (sy->sattre & UNDEF_EQUR)) { -//REALLY? sy->sattre |= ~UNDEF_EQUR; sy->sattre &= ~UNDEF_EQUR; sy->svalue = 0; } else if ((equtyp == CCDEF) && (sy->sattre & UNDEF_CC)) { -//REALLY? sy->sattre |= ~UNDEF_CC; sy->sattre &= ~UNDEF_CC; sy->svalue = 0; } @@ -485,8 +483,6 @@ When checking to see if it's already been equated, issue a warning. sy->sattre |= regbank; // Store register bank #endif eattr = ABS | DEFINED | GLOBAL; -// & what does this $80000080 constant mean??? -// eval = 0x80000080 + (riscreg) + (registerbank << 8); eval = riscreg; tok++; } @@ -548,7 +544,7 @@ When checking to see if it's already been equated, issue a warning. else if (expr(exprbuf, &eval, &eattr, &esym) != OK) goto loop; } - //equ a equr + // equ an equr else if (*tok == SYMBOL) { sy2 = lookup(string[tok[1]], LABEL, j); @@ -558,7 +554,6 @@ When checking to see if it's already been equated, issue a warning. sy->stype = sy2->stype; sy->sattr = sy2->sattr; sy->sattre = sy2->sattre; -//ICK sy->svalue = (sy2->svalue & 0xFFFFF0FF); sy->svalue = sy2->svalue; goto loop; } @@ -754,7 +749,6 @@ int HandleLabel(char * label, int labelType) { symbol = NewSymbol(label, LABEL, environment); symbol->sattr = 0; -// symbol->sattre = RISCSYM; symbol->sattre = 0; } else if (symbol->sattr & DEFINED) diff --git a/procln.h b/procln.h index 559081f..a8a1d95 100644 --- a/procln.h +++ b/procln.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // PROCLN.H - Line Processing -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/riscasm.c b/riscasm.c index f9aa055..26dd8cb 100644 --- a/riscasm.c +++ b/riscasm.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // RISCA.C - GPU/DSP Assembler -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/riscasm.h b/riscasm.h index 834cf85..d73d29a 100644 --- a/riscasm.h +++ b/riscasm.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // RISCA.H - GPU/DSP Assembler -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/rmac.c b/rmac.c index 57c3b37..21e1fb8 100644 --- a/rmac.c +++ b/rmac.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // RMAC.C - Main Application Code -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -323,7 +323,7 @@ int Process(int argc, char ** argv) } sy->sattr = DEFINED | EQUATED | ABS; - sy->svalue = (*s ? (uint32_t)atoi(s) : 0); + sy->svalue = (*s ? (uint64_t)atoi(s) : 0); break; case 'e': // Redirect error message output case 'E': diff --git a/rmac.h b/rmac.h index 7b1d972..07d6ed1 100644 --- a/rmac.h +++ b/rmac.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // RMAC.H - Main Application Code -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/sect.c b/sect.c index 16a8025..f4ce788 100644 --- a/sect.c +++ b/sect.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // SECT.C - Code Generation, Fixups and Section Management -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -19,9 +19,6 @@ #include "token.h" -// Minimum size of a fixup record -#define MIN_FIXUP_MEM (3 * sizeof(uint16_t) + 1 * sizeof(uint32_t)) - // Function prototypes void MakeSection(int, uint16_t); void SwitchSection(int); @@ -32,7 +29,7 @@ int cursect; // Current section number // These are copied from the section descriptor, the current code chunk // descriptor and the current fixup chunk descriptor when a switch is made into -// a section. They are copied back to the descriptors when the section is left. +// a section. They are copied back to the descriptors when the section is left. uint16_t scattr; // Section attributes uint32_t sloc; // Current loc in section @@ -42,11 +39,6 @@ uint32_t ch_size; // # bytes used in code chunk uint8_t * chptr; // Deposit point in code chunk buffer uint8_t * chptr_opcode; // Backup of chptr, updated before entering code generators -CHUNK * sfix; // Current (last) fixup chunk -uint32_t fchalloc; // # bytes alloc'd to fixup chunk -uint32_t fchsize; // # bytes used in fixup chunk -PTR fchptr; // Deposit point in fixup chunk buffer - // Return a size (SIZB, SIZW, SIZL) or 0, depending on what kind of fixup is // associated with a location. static uint8_t fusiztab[] = { @@ -78,16 +70,16 @@ static uint8_t fusizoffs[] = { // void InitSection(void) { - // Cleanup all sections + // Initialize all sections for(int i=0; iscattr = attr; p->sloc = 0; + p->orgaddr = 0; p->scode = p->sfcode = NULL; p->sfix = p->sffix = NULL; } @@ -123,7 +116,7 @@ void SwitchSection(int sno) scattr = p->scattr; sloc = p->sloc; scode = p->scode; - sfix = p->sfix; + orgaddr = p->orgaddr; // Copy code chunk vars if ((cp = scode) != NULL) @@ -138,16 +131,6 @@ void SwitchSection(int sno) } else challoc = ch_size = 0; - - // Copy fixup chunk vars - if ((cp = sfix) != NULL) - { - fchalloc = cp->challoc; - fchsize = cp->ch_size; - fchptr.cp = cp->chptr + fchsize; - } - else - fchalloc = fchsize = 0; } @@ -158,53 +141,34 @@ void SaveSection(void) { SECT * p = §[cursect]; - p->scattr = scattr; // Bailout section vars + p->scattr = scattr; // Bailout section vars p->sloc = sloc; + p->orgaddr = orgaddr; - if (scode != NULL) // Bailout code chunk + if (scode != NULL) // Bailout code chunk scode->ch_size = ch_size; - - if (sfix != NULL) // Bailout fixup chunk - sfix->ch_size = fchsize; } // -// Test to see if a location has a fixup sic'd on it. This is used by the +// Test to see if a location has a fixup set on it. This is used by the // listing generator to print 'xx's instead of '00's for forward references // int fixtest(int sno, uint32_t loc) { - PTR fup; - // Force update to sect[] variables StopMark(); - // Hairy, ugly linear search for a mark on our location; the speed doesn't + // Ugly linear search for a mark on our location. The speed doesn't // matter, since this is only done when generating a listing, which is - // SLOW. - for(CHUNK * ch=sect[sno].sffix; ch!=NULL; ch=ch->chnext) + // SLOW anyway. + for(FIXUP * fp=sect[sno].sffix; fp!=NULL; fp=fp->next) { - fup.cp = (uint8_t *)ch->chptr; - uint8_t * fuend = fup.cp + ch->ch_size; + uint32_t w = fp->attr; + uint32_t xloc = fp->loc + (int)fusizoffs[w & FUMASK]; - while (fup.cp < fuend) - { - uint16_t w = *fup.wp++; - uint32_t xloc = *fup.lp++ + (int)fusizoffs[w & FUMASK]; - fup.wp += 2; - - if (xloc == loc) - return (int)fusiztab[w & FUMASK]; - - if (w & FU_EXPR) - { - w = *fup.wp++; - fup.lp += w; - } - else - fup.lp++; - } + if (xloc == loc) + return (int)fusiztab[w & FUMASK]; } return 0; @@ -221,6 +185,7 @@ int fixtest(int sno, uint32_t loc) int chcheck(uint32_t amt) { DEBUG { printf("chcheck(%u)\n", amt); } + // If in BSS section, no allocation required if (scattr & SBSS) return 0; @@ -229,6 +194,7 @@ int chcheck(uint32_t amt) amt = CH_THRESHOLD; DEBUG { printf(" challoc=%i, ch_size=%i, diff=%i\n", challoc, ch_size, challoc-ch_size); } + if ((int)(challoc - ch_size) >= (int)amt) return 0; @@ -265,121 +231,68 @@ int chcheck(uint32_t amt) } -// -// A fixup record is at least 4 pieces of data long, with some optional data at -// the end. Is of the form: -// -// SYMBOL EXPRESSION -// ------ ---------- -// FU_EXPR.W FU_EXPR.W fixup type -// loc.L loc.L location in section -// fileno.W fileno.W file number fixup occurred in -// lineno.W lineno.W line number fixup occurred in -// symbol.* size.W &symbol (32 or 64 bits) / size of expression -// token.L size (zero or more) TOKENS (32-bits each) -// ENDEXPR.L End of expression (with size > zero) -// JR.L Possible ORG address of RISC JR instruction // // Arrange for a fixup on a location // -int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr) +int AddFixup(uint32_t attr, uint32_t loc, TOKEN * fexpr) { - uint32_t i = MIN_FIXUP_MEM; - uint16_t len = 0; + uint16_t exprlen = 0; + SYM * symbol = NULL; + uint32_t _orgaddr = 0; - DEBUG printf("FIXUP@$%X: $%X\n", loc, attr); - - // Compute length of expression (could be faster); determine if it's the - // single-symbol case; no expression if it's just a mark. (? is this true?) - if ((*fexpr == SYMBOL) && (fexpr[2] == ENDEXPR)) + // First, check to see if the expression is a bare label, otherwise, force + // the FU_EXPR flag into the attributes and count the tokens. + if ((fexpr[0] == SYMBOL) && (fexpr[2] == ENDEXPR)) { - // Just a single symbol, possibly followed by a DWORD - i += sizeof(SYM *); + symbol = symbolPtr[fexpr[1]]; - // SCPCD: Correct bit mask for attr (else other FU_xxx will match) - // NYAN ! + // Save the org address for JR RISC instruction if ((attr & FUMASKRISC) == FU_JR) - i += sizeof(uint32_t); + _orgaddr = orgaddr; } else { attr |= FU_EXPR; - - // Count the # of tokens in the expression - for(len=0; fexpr[len]!=ENDEXPR; len++) - { - // Add one to len for 2X tokens, two for 3X tokens - if (fexpr[len] == SYMBOL) - len++; - else if (fexpr[len] == CONST) - len += 2; - } - - // Add 1 for ENDEXPR - len++; - i += sizeof(uint16_t) + (len * sizeof(TOKEN)); + exprlen = ExpressionLength(fexpr); } - // Alloc another fixup chunk for this one to fit in if necessary - if ((fchalloc - fchsize) < i) + // Allocate space for the fixup + any expression + FIXUP * fixup = malloc(sizeof(FIXUP) + (sizeof(TOKEN) * exprlen)); + + // Store the relevant fixup information in the FIXUP + fixup->next = NULL; + fixup->attr = attr; + fixup->loc = loc; + fixup->fileno = cfileno; + fixup->lineno = curlineno; + fixup->expr = NULL; + fixup->symbol = symbol; + fixup->orgaddr = _orgaddr; + + // Copy the passed in expression to the FIXUP, if any + if (exprlen > 0) { - SECT * p = §[cursect]; - CHUNK * cp = (CHUNK *)malloc(sizeof(CHUNK) + CH_FIXUP_SIZE); - - // First fixup chunk in section - if (sfix == NULL) - { - cp->chprev = NULL; - p->sffix = cp; - } - // Add to other chunks - else - { - cp->chprev = sfix; - sfix->chnext = cp; - sfix->ch_size = fchsize; - } - - // Setup fixup chunk and its global vars - cp->chnext = NULL; - fchalloc = cp->challoc = CH_FIXUP_SIZE; - fchsize = cp->ch_size = 0; - fchptr.cp = cp->chptr = ((uint8_t *)cp) + sizeof(CHUNK); - sfix = p->sfix = cp; + fixup->expr = (TOKEN *)((uint8_t *)fixup + sizeof(FIXUP)); + memcpy(fixup->expr, fexpr, sizeof(TOKEN) * exprlen); } - // Record fixup type, fixup location, and the file number and line number - // the fixup is located at. - *fchptr.wp++ = attr; - *fchptr.lp++ = loc; - *fchptr.wp++ = cfileno; - *fchptr.wp++ = curlineno; - - // Store postfix expression or pointer to a single symbol, or nothing for a - // mark (a zero word is stored in this case--[? is it?]). - if (attr & FU_EXPR) + // Finally, put the FIXUP in the current section's linked list + if (sect[cursect].sffix == NULL) { - *fchptr.wp++ = len; - - while (len--) - *fchptr.lp++ = *fexpr++; + sect[cursect].sffix = fixup; + sect[cursect].sfix = fixup; } else { - *fchptr.sy++ = symbolPtr[fexpr[1]]; + sect[cursect].sfix->next = fixup; + sect[cursect].sfix = fixup; + } - // SCPCD: Correct bit mask for attr (else other FU_xxx will match) - // NYAN ! - if ((attr & FUMASKRISC) == FU_JR) - { - if (orgactive) - *fchptr.lp++ = orgaddr; - else - *fchptr.lp++ = 0x00000000; - } + DEBUG { printf("AddFixup: sno=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", cursect, fixup->lineno, fixup->attr, fixup->loc, (void *)fixup->expr, (void *)fixup->symbol, fixup->orgaddr); + if (symbol != NULL) + printf(" name: %s, value: $lX\n", symbol->sname, symbol->svalue); } - fchsize += i; return 0; } @@ -389,18 +302,11 @@ int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr) // int ResolveFixups(int sno) { - PTR fup; // Current fixup uint64_t eval; // Expression value - SYM * sy; // (Temp) pointer to a symbol - uint16_t i; // (Temp) word int reg2; uint16_t flags; SECT * sc = §[sno]; - CHUNK * ch = sc->sffix; - - if (ch == NULL) - return 0; // "Cache" first chunk CHUNK * cch = sc->sfcode; @@ -413,411 +319,431 @@ int ResolveFixups(int sno) if (sno == M6502) cch->ch_size = cch->challoc; - do - { - fup.cp = ch->chptr; // fup -> start of chunk - uint16_t * fuend = (uint16_t *)(fup.cp + ch->ch_size); // fuend -> end of chunk + // Get first fixup for the passed in section + FIXUP * fixup = sect[sno].sffix; - while (fup.wp < fuend) + while (fixup != NULL) + { + // We do it this way because we have continues everywhere... :-P + FIXUP * fup = fixup; + fixup = fixup->next; + + uint32_t w = fup->attr; // Fixup long (type+modes+flags) + uint32_t loc = fup->loc; // Location to fixup + cfileno = fup->fileno; + curlineno = fup->lineno; + DEBUG { printf("ResolveFixups: sect#=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", sno, fup->lineno, fup->attr, fup->loc, (void *)fup->expr, (void *)fup->symbol, fup->orgaddr); } + + // This is based on global vars cfileno, curfname :-P + // This approach is kinda meh as well. I think we can do better + // than this. + SetFilenameForErrorReporting(); + + // Search for chunk containing location to fix up; compute a + // pointer to the location (in the chunk). Often we will find the + // Fixup is in the "cached" chunk, so the linear-search is seldom + // executed. + if (loc < cch->chloc || loc >= (cch->chloc + cch->ch_size)) { - uint16_t w = *fup.wp++; // Fixup word (type+modes+flags) - uint32_t loc = *fup.lp++; // Location to fixup - cfileno = *fup.wp++; - curlineno = *fup.wp++; - DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); } - - // This is based on global vars cfileno, curfname :-P - // This approach is kinda meh as well. I think we can do better - // than this. - SetFilenameForErrorReporting(); - - SYM * esym = NULL; // External symbol involved in expr - - // Search for chunk containing location to fix up; compute a - // pointer to the location (in the chunk). Often we will find the - // Fixup is in the "cached" chunk, so the linear-search is seldom - // executed. - if (loc < cch->chloc || loc >= (cch->chloc + cch->ch_size)) + for(cch=sc->sfcode; cch!=NULL; cch=cch->chnext) { - for(cch=sc->sfcode; cch!=NULL; cch=cch->chnext) - { - if (loc >= cch->chloc && loc < (cch->chloc + cch->ch_size)) - break; - } - - if (cch == NULL) - { - // Fixup (loc) out of range - interror(7); - // NOTREACHED - } + if (loc >= cch->chloc && loc < (cch->chloc + cch->ch_size)) + break; } - // Location to fix (in cached chunk) - uint8_t * locp = cch->chptr + (loc - cch->chloc); - uint16_t eattr = 0; // Expression attrib + if (cch == NULL) + { + // Fixup (loc) is out of range--this should never happen! + // Once we call this function, it winds down immediately; it + // doesn't return. + interror(7); + } + } - // Compute expression/symbol value and attribs + // Location to fix (in current chunk) + // We use the address of the chunk that loc is actually in, then + // subtract the chunk's starting location from loc to get the offset + // into the current chunk. + uint8_t * locp = cch->chptr + (loc - cch->chloc); + uint16_t eattr = 0; // Expression attrib + SYM * esym = NULL; // External symbol involved in expr - // Complex expression - if (w & FU_EXPR) - { - i = *fup.wp++; + // Compute expression/symbol value and attributes - if (evexpr(fup.tk, &eval, &eattr, &esym) != OK) - { - fup.lp += i; - continue; - } + // Complex expression + if (w & FU_EXPR) + { + if (evexpr(fup->expr, &eval, &eattr, &esym) != OK) + continue; + } + // Simple symbol + else + { + SYM * sy = fup->symbol; + eattr = sy->sattr; - fup.lp += i; - } - // Simple symbol + if (eattr & DEFINED) + eval = sy->svalue; else - { - sy = *fup.sy++; - eattr = sy->sattr; - - if (eattr & DEFINED) - eval = sy->svalue; - else - eval = 0; + eval = 0; - // If the symbol is not defined, but global, set esym to sy - if ((eattr & (GLOBAL | DEFINED)) == GLOBAL) - esym = sy; - } + // If the symbol is not defined, but global, set esym to sy + if ((eattr & (GLOBAL | DEFINED)) == GLOBAL) + esym = sy; + } - uint16_t tdb = eattr & TDB; + uint16_t tdb = eattr & TDB; - // If the expression is undefined and no external symbol is - // involved, then that's an error. - if (!(eattr & DEFINED) && (esym == NULL)) - { - error(undef_error); - continue; - } + // If the expression/symbol is undefined and no external symbol is + // involved, then that's an error. + if (!(eattr & DEFINED) && (esym == NULL)) + { + error(undef_error); + continue; + } - // Do the fixup - // - // If a PC-relative fixup is undefined, its value is *not* - // subtracted from the location (that will happen in the linker - // when the external reference is resolved). - // - // MWC expects PC-relative things to have the LOC subtracted from - // the value, if the value is external (that is, undefined at this - // point). - // - // PC-relative fixups must be DEFINED and either in the same - // section (whereupon the subtraction takes place) or ABS (with no - // subtract). - if (w & FU_PCREL) + // Do the fixup + // + // If a PC-relative fixup is undefined, its value is *not* + // subtracted from the location (that will happen in the linker + // when the external reference is resolved). + // + // MWC expects PC-relative things to have the LOC subtracted from + // the value, if the value is external (that is, undefined at this + // point). + // + // PC-relative fixups must be DEFINED and either in the same + // section (whereupon the subtraction takes place) or ABS (with no + // subtract). + if (w & FU_PCREL) + { + if (eattr & DEFINED) { - if (eattr & DEFINED) + if (tdb == sno) + eval -= loc; + else if (tdb) { - if (tdb == sno) - eval -= (uint32_t)loc; - else if (tdb) + // Allow cross-section PCREL fixups in Alcyon mode + if (prg_flag) + { + switch (tdb) + { + case TEXT: +// Shouldn't there be a break here, since otherwise, it will point to the DATA section? +// break; + case DATA: + eval += sect[TEXT].sloc; + break; + case BSS: + eval += sect[TEXT].sloc + sect[DATA].sloc; + break; + default: + error("invalid section"); + break; + } + + eval -= loc; + } + else { error("PC-relative expr across sections"); continue; } - - if (sbra_flag && (w & FU_LBRA) && (eval + 0x80 < 0x100)) - warn("unoptimized short branch"); } - else if (obj_format == MWC) - eval -= (uint32_t)loc; - tdb = 0; - eattr &= ~TDB; + if (sbra_flag && (w & FU_LBRA) && (eval + 0x80 < 0x100)) + warn("unoptimized short branch"); } + else if (obj_format == MWC) + eval -= loc; - // Do fixup classes - switch (w & FUMASK) + tdb = 0; + eattr &= ~TDB; + } + + // Handle fixup classes + switch (w & FUMASK) + { + // FU_BBRA fixes up a one-byte branch offset. + case FU_BBRA: + if (!(eattr & DEFINED)) { - // FU_BBRA fixes up a one-byte branch offset. - case FU_BBRA: - if (!(eattr & DEFINED)) - { - error("external short branch"); - continue; - } + error("external short branch"); + continue; + } - eval -= 2; + eval -= 2; - if (eval + 0x80 >= 0x100) - goto rangeErr; + if (eval + 0x80 >= 0x100) + goto rangeErr; - if (eval == 0) - { - if (CHECK_OPTS(OPT_NULL_BRA)) - { - // just output a nop - *locp++ = 0x4E; - *locp = 0x71; - continue; - } - else - { - error("illegal bra.s with zero offset"); - continue; - } - } - *++locp = (uint8_t)eval; - break; - // Fixup one-byte value at locp + 1. - case FU_WBYTE: - locp++; - // FALLTHROUGH - // Fixup one-byte forward references - case FU_BYTE: - if (!(eattr & DEFINED)) + if (eval == 0) + { + if (CHECK_OPTS(OPT_NULL_BRA)) { - error("external byte reference"); + // Just output a NOP + *locp++ = 0x4E; + *locp = 0x71; continue; } - - if (tdb) + else { - error("non-absolute byte reference"); + error("illegal bra.s with zero offset"); continue; } + } - if ((w & FU_PCREL) && eval + 0x80 >= 0x100) - goto rangeErr; + *++locp = (uint8_t)eval; + break; - if (w & FU_SEXT) - { - if (eval + 0x100 >= 0x200) - goto rangeErr; - } - else if (eval >= 0x100) + // Fixup one-byte value at locp + 1. + case FU_WBYTE: + locp++; + // FALLTHROUGH + + // Fixup one-byte forward references + case FU_BYTE: + if (!(eattr & DEFINED)) + { + error("external byte reference"); + continue; + } + + if (tdb) + { + error("non-absolute byte reference"); + continue; + } + + if ((w & FU_PCREL) && ((eval + 0x80) >= 0x100)) + goto rangeErr; + + if (w & FU_SEXT) + { + if ((eval + 0x100) >= 0x200) goto rangeErr; + } + else if (eval >= 0x100) + goto rangeErr; - *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; + break; - *locp = (uint8_t)((eval >> 8) & 0xFF); - break; - case FU_BYTEL: - if (!(eattr & DEFINED)) - { - error("external byte reference"); - continue; - } + // Fixup high/low byte off word for 6502 + case FU_BYTEH: + 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. - case FU_WORD: - if ((w & FUMASKRISC) == FU_JR) - { - uint32_t orgaddr = *fup.lp++; + *locp = (uint8_t)((eval >> 8) & 0xFF); + break; - if (orgaddr) - reg2 = (signed)((eval - (orgaddr + 2)) / 2); - else - reg2 = (signed)((eval - (loc + 2)) / 2); + case FU_BYTEL: + if (!(eattr & DEFINED)) + { + error("external byte reference"); + continue; + } - if ((reg2 < -16) || (reg2 > 15)) - { - error("relative jump out of range"); - break; - } + *locp = (uint8_t)(eval & 0xFF); + break; - *locp = (uint8_t)(*locp | ((reg2 >> 3) & 0x03)); - locp++; - *locp = (uint8_t)(*locp | ((reg2 & 0x07) << 5)); + // Fixup WORD forward references; the word could be unaligned in + // the section buffer, so we have to be careful. + case FU_WORD: + if ((w & FUMASKRISC) == FU_JR) + { + if (fup->orgaddr) + reg2 = (signed)((eval - (fup->orgaddr + 2)) / 2); + else + reg2 = (signed)((eval - (loc + 2)) / 2); + + if ((reg2 < -16) || (reg2 > 15)) + { + error("relative jump out of range"); break; } - if ((w & FUMASKRISC) == FU_NUM15) + *locp = (uint8_t)(*locp | ((reg2 >> 3) & 0x03)); + locp++; + *locp = (uint8_t)(*locp | ((reg2 & 0x07) << 5)); + break; + } + else if ((w & FUMASKRISC) == FU_NUM15) + { + if (eval < -16 || eval > 15) { - if (eval < -16 || eval > 15) - { - error("constant out of range"); - break; - } - - *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); - locp++; - *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + error("constant out of range"); break; } - if ((w & FUMASKRISC) == FU_NUM31) + *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); + locp++; + *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + break; + } + else if ((w & FUMASKRISC) == FU_NUM31) + { + if (eval > 31) { - if (eval < 0 || eval > 31) - { - error("constant out of range"); - break; - } - - *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); - locp++; - *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + error("constant out of range"); break; } - if ((w & FUMASKRISC) == FU_NUM32) + *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); + locp++; + *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + break; + } + else if ((w & FUMASKRISC) == FU_NUM32) + { + if (eval < 1 || eval > 32) { - if (eval < 1 || eval > 32) - { - error("constant out of range"); - break; - } - - if (w & FU_SUB32) - eval = (32 - eval); - - eval = (eval == 32) ? 0 : eval; - *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); - locp++; - *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + error("constant out of range"); break; } - if ((w & FUMASKRISC) == FU_REGONE) - { - if (eval < 0 || eval > 31) - { - error("register value out of range"); - break; - } + if (w & FU_SUB32) + eval = (32 - eval); - *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); - locp++; - *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + eval = (eval == 32) ? 0 : eval; + *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); + locp++; + *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + break; + } + else if ((w & FUMASKRISC) == FU_REGONE) + { + if (eval > 31) + { + error("register value out of range"); break; } - if ((w & FUMASKRISC) == FU_REGTWO) + *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03)); + locp++; + *locp = (uint8_t)(*locp | ((eval & 0x07) << 5)); + break; + } + else if ((w & FUMASKRISC) == FU_REGTWO) + { + if (eval > 31) { - if (eval < 0 || eval > 31) - { - error("register value out of range"); - break; - } - - locp++; - *locp = (uint8_t)(*locp | (eval & 0x1F)); + error("register value out of range"); break; } - if (!(eattr & DEFINED)) - { - flags = MWORD; + locp++; + *locp = (uint8_t)(*locp | (eval & 0x1F)); + break; + } - if (w & FU_PCREL) - flags |= MPCREL; + if (!(eattr & DEFINED)) + { + flags = MWORD; + + if (w & FU_PCREL) + flags |= MPCREL; + + MarkRelocatable(sno, loc, 0, flags, esym); + } + else + { + if (tdb) + MarkRelocatable(sno, loc, tdb, MWORD, NULL); - MarkRelocatable(sno, loc, 0, flags, esym); + if (w & FU_SEXT) + { + if (eval + 0x10000 >= 0x20000) + goto rangeErr; } else { - if (tdb) - MarkRelocatable(sno, loc, tdb, MWORD, NULL); - - if (w & FU_SEXT) - { - if (eval + 0x10000 >= 0x20000) - goto rangeErr; - } - else + // Range-check BRA and DBRA + if (w & FU_ISBRA) { - // Range-check BRA and DBRA - if (w & FU_ISBRA) - { - if (eval + 0x8000 >= 0x10000) - goto rangeErr; - } - else if (eval >= 0x10000) + if (eval + 0x8000 >= 0x10000) goto rangeErr; } + else if (eval >= 0x10000) + goto rangeErr; } + } - // 6502 words are little endian, so handle that here - if (sno == M6502) - SETLE16(locp, 0, eval) - else - SETBE16(locp, 0, eval) + // 6502 words are little endian, so handle that here + if (sno == M6502) + SETLE16(locp, 0, eval) + else + SETBE16(locp, 0, eval) - break; - // Fixup LONG forward references; - // the long could be unaligned in the section buffer, so be careful - // (again). - case FU_LONG: - flags = MLONG; + break; - if ((w & FUMASKRISC) == FU_MOVEI) - { - // Long constant in MOVEI # is word-swapped, so fix it here - eval = WORDSWAP32(eval); - flags |= MMOVEI; - } + // Fixup LONG forward references; + // the long could be unaligned in the section buffer, so be careful + // (again). + case FU_LONG: + flags = MLONG; - // If the symbol is undefined, make sure to pass the symbol in - // to the MarkRelocatable() function. - if (!(eattr & DEFINED)) - MarkRelocatable(sno, loc, 0, flags, esym); - else if (tdb) - MarkRelocatable(sno, loc, tdb, flags, NULL); + if ((w & FUMASKRISC) == FU_MOVEI) + { + // Long constant in MOVEI # is word-swapped, so fix it here + eval = WORDSWAP32(eval); + flags |= MMOVEI; + } - SETBE32(locp, 0, eval); - break; + // If the symbol is undefined, make sure to pass the symbol in + // to the MarkRelocatable() function. + if (!(eattr & DEFINED)) + MarkRelocatable(sno, loc, 0, flags, esym); + else if (tdb) + MarkRelocatable(sno, loc, tdb, flags, NULL); - // Fixup a 3-bit "QUICK" reference in bits 9..1 - // (range of 1..8) in a word. Really bits 1..3 in a byte. - case FU_QUICK: - if (!(eattr & DEFINED)) - { - error("External quick reference"); - continue; - } + SETBE32(locp, 0, eval); + break; - if (eval < 1 || eval > 8) - goto rangeErr; + // Fixup a 3-bit "QUICK" reference in bits 9..1 + // (range of 1..8) in a word. [Really bits 1..3 in a byte.] + case FU_QUICK: + if (!(eattr & DEFINED)) + { + error("External quick reference"); + continue; + } - *locp |= (eval & 7) << 1; - break; + if ((eval < 1) || (eval > 8)) + goto rangeErr; - // Fix up 6502 funny branch - case FU_6BRA: - eval -= (loc + 1); + *locp |= (eval & 7) << 1; + break; - if (eval + 0x80 >= 0x100) - goto rangeErr; + // Fix up 6502 funny branch + case FU_6BRA: + eval -= (loc + 1); - *locp = (uint8_t)eval; - break; + if (eval + 0x80 >= 0x100) + goto rangeErr; - default: - // Bad fixup type--this should *never* happen! - interror(4); - // NOTREACHED - } - continue; -rangeErr: - error("expression out of range"); + *locp = (uint8_t)eval; + break; + + default: + // Bad fixup type--this should *never* happen! + // Once we call this function, it winds down immediately; it + // doesn't return. + interror(4); } - ch = ch->chnext; + continue; +rangeErr: + error("expression out of range"); } - while (ch != NULL); return 0; } + // // Resolve all fixups // @@ -832,7 +758,7 @@ int ResolveAllFixups(void) DEBUG printf("Resolving DATA sections...\n"); ResolveFixups(DATA); DEBUG printf("Resolving 6502 sections...\n"); - ResolveFixups(M6502); /* fixup 6502 section (if any) */ + ResolveFixups(M6502); // Fixup 6502 section (if any) return 0; } diff --git a/sect.h b/sect.h index 3f6f28e..b3f6e0f 100644 --- a/sect.h +++ b/sect.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // SECT.H - Code Generation, Fixups and Section Management -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilized with the kind permission of Landon Dyer // @@ -34,6 +34,14 @@ sloc += 8; ch_size += 8; if(orgactive) orgaddr += 8;} #define D_rword(w) {*chptr++=(uint8_t)(w); *chptr++=(uint8_t)((w)>>8); \ sloc+=2; ch_size+=2;if(orgactive) orgaddr += 2;} + +// Macro for the 56001. Word size on this device is 24 bits wide. I hope that +// orgaddr += 1 means that the addresses in the device reflect this. +#define D_dsp(w) {chcheck(3);*chptr++=(uint8_t)(w>>16); \ + *chptr++=(uint8_t)(w>>8); *chptr++=(uint8_t)w; \ + sloc+=1; ch_size += 3; if(orgactive) orgaddr += 1; \ + dsp_written_data_in_current_org=1;} + // This macro expects to get an array of uint8_ts with the hi bits in a[0] and // the low bits in a[11] (Big Endian). #define D_extend(a) {memcpy(chptr, a, 12); chptr+=12; sloc+=12, ch_size+=12;\ @@ -56,6 +64,7 @@ #define SABS 0x2000 // Section is absolute #define SPIC 0x1000 // Section is position-independent code +// N.B.: THIS IS NO LONGER TRUE // Fixup record a WORD of these bits, followed by a loc and then a pointer // to a symbol or an ENDEXPR-terminated postfix expression. // @@ -109,24 +118,38 @@ // Chunks are used to hold generated code and fixup records #define CHUNK struct _chunk CHUNK { - CHUNK * chnext; // Next, previous chunks in section - CHUNK * chprev; - uint32_t chloc; // Base addr of this chunk - uint32_t challoc; // # bytes allocated for chunk - uint32_t ch_size; // # bytes chunk actually uses - uint8_t * chptr; // Data for this chunk + CHUNK * chnext; // Next, previous chunks in section + CHUNK * chprev; + uint32_t chloc; // Base addr of this chunk + uint32_t challoc; // # bytes allocated for chunk + uint32_t ch_size; // # bytes chunk actually uses + uint8_t * chptr; // Data for this chunk +}; + +// Fixup records can also hold an expression (if any) +#define FIXUP struct _fixup +FIXUP { + FIXUP * next; // Pointer to next FIXUP + uint32_t attr; // Fixup type + uint32_t loc; // Location in section + uint16_t fileno; // ID of current file + uint32_t lineno; // Current line + TOKEN * expr; // Pointer to stored expression (if any) + SYM * symbol; // Pointer to symbol (if any) + uint32_t orgaddr; // Fixup origin address (used for FU_JR) }; // Section descriptor #define SECT struct _sect SECT { - uint16_t scattr; // Section attributes - uint32_t sloc; // Current loc-in / size-of section - uint32_t relocs; // # of relocations for this section - CHUNK * sfcode; // First chunk in section - CHUNK * scode; // Last chunk in section - CHUNK * sffix; // First fixup chunk - CHUNK * sfix; // Last fixup chunk + uint16_t scattr; // Section attributes + uint32_t sloc; // Current loc-in / size-of section + uint32_t relocs; // # of relocations for this section + uint32_t orgaddr; // Current org'd address ***NEW*** + CHUNK * sfcode; // First chunk in section + CHUNK * scode; // Last chunk in section + FIXUP * sffix; // First fixup + FIXUP * sfix; // Last fixup ***NEW*** }; // 680x0 defines @@ -171,7 +194,7 @@ void SwitchSection(int); void SaveSection(void); int fixtest(int, uint32_t); int chcheck(uint32_t); -int AddFixup(uint16_t, uint32_t, TOKEN *); +int AddFixup(uint32_t, uint32_t, TOKEN *); int ResolveAllFixups(void); #endif // __SECT_H__ diff --git a/symbol.c b/symbol.c index c24720f..87f90c0 100644 --- a/symbol.c +++ b/symbol.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // SYMBOL.C - Symbol Handling -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/symbol.h b/symbol.h index dfe6bdc..f985b1b 100644 --- a/symbol.h +++ b/symbol.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // SYMBOL.H - Symbol Handling -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // diff --git a/token.c b/token.c index f1f88ca..9d6decf 100644 --- a/token.c +++ b/token.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // TOKEN.C - Token Handling -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -531,22 +531,12 @@ arg_num: switch ((int)*tk++) { case SYMBOL: -#if 0 -// d = (char *)*tk++; - d = string[*tk++]; -#else - // This fix should be done for strings too d = symbolString[*tk++]; DEBUG { printf("ExM: SYMBOL=\"%s\"", d); } -#endif break; case STRING: -#if 0 -// d = (char *)*tk++; - d = string[*tk++]; -#else d = symbolString[*tk++]; -#endif + if (dst >= edst) goto overflow; @@ -967,7 +957,7 @@ int TokenizeLine(void) retry: - if (cur_inobj == NULL) // Return EOF if input stack is empty + if (cur_inobj == NULL) // Return EOF if input stack is empty return TKEOF; // Get another line of input from the current input source: a file, a @@ -983,8 +973,8 @@ retry: if ((ln = GetNextLine()) == NULL) { DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } - if (fpop() == 0) // Pop input level - goto retry; // Try for more lines + if (fpop() == 0) // Pop input level + goto retry; // Try for more lines else { ifent->if_prev = (IFENT *)-1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs @@ -992,7 +982,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } } } - curlineno++; // Bump line number + curlineno++; // Bump line number lntag = SPACE; if (as68_flag) @@ -1054,7 +1044,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } strcpy(lnbuf, ln); // General housekeeping - tok = tokeol; // Set "tok" to EOL in case of error + tok = tokeol; // Set "tok" to EOL in case of error tk.u32 = etok; // Reset token ptr stuffnull = 0; // Don't stuff nulls totlines++; // Bump total #lines assembled @@ -1202,16 +1192,9 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } if ((j < 0) || (state < 0)) { *tk.u32++ = SYMBOL; -//#warning -//problem here: nullspot is a char * but TOKEN is a uint32_t. On a 64-bit -//system, this will cause all kinds of mischief. -#if 0 - *tk++ = (TOKEN)nullspot; -#else string[stringNum] = nullspot; *tk.u32++ = stringNum; stringNum++; -#endif } else { @@ -1219,10 +1202,10 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); } stuffnull = 0; } - if (v) // Record attribute token (if any) + if (v) // Record attribute token (if any) *tk.u32++ = (TOKEN)v; - if (stuffnull) // Arrange for string termination on next pass + if (stuffnull) // Arrange for string termination on next pass nullspot = ln; continue; @@ -1637,9 +1620,9 @@ dostring: // Terminate line of tokens and return "success." goteol: - tok = etok; // Set tok to beginning of line + tok = etok; // Set tok to beginning of line - if (stuffnull) // Terminate last SYMBOL + if (stuffnull) // Terminate last SYMBOL *nullspot = EOS; *tk.u32++ = EOL; diff --git a/token.h b/token.h index 4a9b110..e20402b 100644 --- a/token.h +++ b/token.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // TOKEN.H - Token Handling -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -161,7 +161,7 @@ extern char tolowertab[]; extern INOBJ * cur_inobj; extern int mjump_align; extern char * string[]; -int optimizeOff; +extern int optimizeOff; // Exported functions int include(int, char *); diff --git a/version.h b/version.h index 62dbfcb..d95ff7e 100644 --- a/version.h +++ b/version.h @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // VERSION.H - Version Information -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -14,8 +14,8 @@ // Release Information #define MAJOR 1 // Major version number -#define MINOR 11 // Minor version number -#define PATCH 9 // Patch release number +#define MINOR 12 // Minor version number +#define PATCH 0 // Patch release number #endif // __VERSION_H__