diff --git a/src/acme.c b/src/acme.c index fbad572..663b0d8 100644 --- a/src/acme.c +++ b/src/acme.c @@ -587,32 +587,3 @@ int main(int argc, const char *argv[]) save_output_file(); return ACME_finalize(EXIT_SUCCESS); // dump labels, if wanted } - -/* -TODO - maybe add a "use version" switch to ease assembling old sources? -relevant changes are: - -v0.05: - ...would be the syntax before any changes - (how was offset assembly ended? '*' in a line on its own?) - BIT without any arg would output $2c, masking the next two bytes -v0.07: - "leading zeroes" info is now stored in symbols as well - changed argument order of mvp/mvn - !cbm outputs warning to use !ct pet instead - !end changed to !eof - *= is now segment change instead of offset assembly - added !pseudopc/!realpc - -config->wanted_version = - 8600 // v0.86 make !pseudopc/!realpc give a warning to use !pseudopc{} instead -VER_0_93 9300 // v0.93 allowed *= inside offset assembly blocks -VER_RIGHTASSOCIATIVEPOWEROF 9406 // v0.94.6 made "power of" operator right-associative - 9408 // v0.94.8 disabled !cbm, !pseudopc/!realpc, !subzone -VER_NEWFORSYNTAX 9412 // v0.94.12 introduced the new "!for" syntax - 9502 // v0.95.2 changed ANC#8 from 0x2b to 0x0b -VER_BACKSLASHESCAPING ? // not yet: backslash escaping (and therefore strings) -VER_FUTURE 32767 - TODO: paths should be relative to file, not start dir - TODO: ignore leading zeroes? -*/ diff --git a/src/global.c b/src/global.c index 24f77bb..4239c74 100644 --- a/src/global.c +++ b/src/global.c @@ -34,14 +34,11 @@ const char s_asl[] = "asl"; const char s_asr[] = "asr"; const char s_bra[] = "bra"; const char s_brl[] = "brl"; -const char s_cbm[] = "cbm"; const char s_eor[] = "eor"; const char s_error[] = "error"; const char s_lsr[] = "lsr"; const char s_scrxor[] = "scrxor"; char s_untitled[] = "<untitled>"; // FIXME - this is actually const -const char s_Zone[] = "Zone"; -const char s_subzone[] = "subzone"; const char s_pet[] = "pet"; const char s_raw[] = "raw"; const char s_scr[] = "scr"; diff --git a/src/global.h b/src/global.h index e656312..caad3e1 100644 --- a/src/global.h +++ b/src/global.h @@ -26,15 +26,11 @@ extern const char s_asl[]; extern const char s_asr[]; extern const char s_bra[]; extern const char s_brl[]; -extern const char s_cbm[]; extern const char s_eor[]; extern const char s_error[]; extern const char s_lsr[]; extern const char s_scrxor[]; extern char s_untitled[]; -extern const char s_Zone[]; -#define s_zone (s_subzone + 3) // Yes, I know I'm sick -extern const char s_subzone[]; extern const char s_pet[]; extern const char s_raw[]; extern const char s_scr[]; @@ -74,14 +70,34 @@ struct config { boolean honor_leading_zeroes; // TRUE, disabled by --ignore-zeroes boolean segment_warning_is_error; // FALSE, enabled by --strict-segments boolean test_new_features; // FALSE, enabled by --test - int wanted_version; -#define VER_0_93 9300 // v0.93 -#define VER_RIGHTASSOCIATIVEPOWEROF 9406 // v0.94.6 made "power of" operator right-associative -#define VER_NEWFORSYNTAX 9412 // v0.94.12 introduced the new "!for" syntax -#define VER_BACKSLASHESCAPING 10000 // not yet: backslash escaping -#define VER_FUTURE 32767 + int wanted_version; // TODO - add switch to set this (in addition to "--test --test") }; extern struct config config; +/* versions that could be supported by "wanted_version": +v0.05: + ...would be the syntax before any changes + (how was offset assembly ended? '*' in a line on its own?) + BIT without any arg would output $2c, masking the next two bytes +v0.07: + "leading zeroes" info is now stored in symbols as well + changed argument order of mvp/mvn + !cbm outputs warning to use !ct pet instead + !end changed to !eof + *= is now segment change instead of offset assembly + added !pseudopc/!realpc +*/ +//#define VER_ 8500 // v0.85 looks like the oldest version it makes sense to actually support +//#define VER_ 8600 // v0.86 made !pseudopc/!realpc give a warning to use !pseudopc{} instead, and !to wants a file format +//#define VER_ 9300 // v0.93 allowed *= inside offset assembly blocks +#define VER_RIGHTASSOCIATIVEPOWEROF 9406 // v0.94.6 made "power of" operator right-associative +#define VER_DISABLED_OBSOLETE_STUFF 9408 // v0.94.8 disabled !cbm, !pseudopc/!realpc, !subzone +#define VER_NEWFORSYNTAX 9412 // v0.94.12 introduced the new "!for" syntax +// 9502 // v0.95.2 changed ANC#8 from 0x2b to 0x0b +#define VER_BACKSLASHESCAPING 10000 // not yet: backslash escaping (and therefore strings) FIXME - value is bogus! +#define VER_FUTURE 32767 +// possible changes in future versions: +// paths should be relative to file, not start dir +// ignore leading zeroes? struct pass { int number; // counts up from zero diff --git a/src/output.c b/src/output.c index df96190..e78e580 100644 --- a/src/output.c +++ b/src/output.c @@ -76,7 +76,7 @@ static struct ronode *file_format_tree = NULL; // tree to hold output formats (F static struct ronode file_format_list[] = { #define KNOWN_FORMATS "'plain', 'cbm', 'apple'" // shown in CLI error message for unknown formats PREDEFNODE("apple", OUTPUT_FORMAT_APPLE), - PREDEFNODE(s_cbm, OUTPUT_FORMAT_CBM), + PREDEFNODE("cbm", OUTPUT_FORMAT_CBM), // PREDEFNODE("o65", OUTPUT_FORMAT_O65), PREDEFLAST("plain", OUTPUT_FORMAT_PLAIN), // ^^^^ this marks the last element @@ -657,11 +657,12 @@ void pseudopc_start(struct number *new_pc) CPU_state.pc.flags |= NUMBER_IS_DEFINED; // FIXME - remove when allowing undefined! //new: CPU_state.pc.flags = new_pc->flags & (NUMBER_IS_DEFINED | NUMBER_EVER_UNDEFINED); } -// end offset assembly -void pseudopc_end(void) +// end offset assembly (use FALSE for old, deprecated, obsolete, non-nesting !realpc) +void pseudopc_end(boolean choke_outside) { if (pseudopc_current_context == NULL) { - Bug_found("ClosingUnopenedPseudopcBlock", 0); + if (choke_outside) + Bug_found("ClosingUnopenedPseudopcBlock", 0); } else { CPU_state.pc.val.intval = (CPU_state.pc.val.intval - pseudopc_current_context->offset) & 0xffff; // pc might have wrapped around CPU_state.pc.flags = pseudopc_current_context->flags; diff --git a/src/output.h b/src/output.h index 0ed83b0..2913cbf 100644 --- a/src/output.h +++ b/src/output.h @@ -102,8 +102,8 @@ extern void vcpu_end_statement(void); struct pseudopc; // start offset assembly extern void pseudopc_start(struct number *new_pc); -// end offset assembly -extern void pseudopc_end(void); +// end offset assembly (use FALSE for old, deprecated, obsolete, non-nesting !realpc) +extern void pseudopc_end(boolean choke_outside); // un-pseudopc a label value by given number of levels // returns nonzero on error (if level too high) extern int pseudopc_unpseudo(struct number *target, struct pseudopc *context, unsigned int levels); diff --git a/src/pseudoopcodes.c b/src/pseudoopcodes.c index 633ff7a..72548b6 100644 --- a/src/pseudoopcodes.c +++ b/src/pseudoopcodes.c @@ -296,9 +296,14 @@ static enum eos po_hex(void) // now GotByte = illegal char // "!cbm" pseudo opcode (now obsolete) -static enum eos obsolete_po_cbm(void) +static enum eos po_cbm(void) { - Throw_error("\"!cbm\" is obsolete; use \"!ct pet\" instead."); + if (config.wanted_version >= VER_DISABLED_OBSOLETE_STUFF) { + Throw_error("\"!cbm\" is obsolete; use \"!ct pet\" instead."); + } else { + encoder_current = &encoder_pet; + Throw_first_pass_warning("\"!cbm\" is deprecated; use \"!ct pet\" instead."); + } return ENSURE_EOS; } @@ -580,8 +585,16 @@ static enum eos po_align(void) return ENSURE_EOS; } -static const char Error_old_offset_assembly[] = - "\"!pseudopc/!realpc\" is obsolete; use \"!pseudopc {}\" instead."; + +// not using a block is no longer allowed +static void old_offset_assembly(void) +{ + if (config.wanted_version >= VER_DISABLED_OBSOLETE_STUFF) + Throw_error("\"!pseudopc/!realpc\" is obsolete; use \"!pseudopc {}\" instead."); + else + Throw_first_pass_warning("\"!pseudopc/!realpc\" is deprecated; use \"!pseudopc {}\" instead."); +} + // start offset assembly // TODO - maybe add a label argument to assign the block size afterwards (for assemble-to-end-address) (or add another pseudo opcode) static enum eos po_pseudopc(void) @@ -612,20 +625,19 @@ static enum eos po_pseudopc(void) pseudopc_start(&new_pc); // if there's a block, parse that and then restore old value! if (Parse_optional_block()) { - // restore old state - pseudopc_end(); + pseudopc_end(TRUE); // restore old state } else { - // not using a block is no longer allowed - Throw_error(Error_old_offset_assembly); + old_offset_assembly(); } return ENSURE_EOS; } // "!realpc" pseudo opcode (now obsolete) -static enum eos obsolete_po_realpc(void) +static enum eos po_realpc(void) { - Throw_error(Error_old_offset_assembly); + old_offset_assembly(); + pseudopc_end(FALSE); // restore old state, if possible return ENSURE_EOS; } @@ -810,15 +822,18 @@ static enum eos po_zone(void) } else { // no block found, so it's a normal zone change section_finalize(&entry_values); // end outer zone - section_now->type = s_Zone; // change type to "Zone" + section_now->type = "Zone"; // fix type } return ENSURE_EOS; } // "!subzone" or "!sz" pseudo opcode (now obsolete) -static enum eos obsolete_po_subzone(void) +static enum eos po_subzone(void) { - Throw_error("\"!subzone {}\" is obsolete; use \"!zone {}\" instead."); + if (config.wanted_version >= VER_DISABLED_OBSOLETE_STUFF) + Throw_error("\"!subzone {}\" is obsolete; use \"!zone {}\" instead."); + else + Throw_first_pass_warning("\"!subzone {}\" is deprecated; use \"!zone {}\" instead."); // call "!zone" instead return po_zone(); } @@ -1262,7 +1277,7 @@ static struct ronode pseudo_opcode_list[] = { PREDEFNODE("le32", po_le32), PREDEFNODE("h", po_hex), PREDEFNODE("hex", po_hex), - PREDEFNODE(s_cbm, obsolete_po_cbm), + PREDEFNODE("cbm", po_cbm), // obsolete PREDEFNODE("ct", po_convtab), PREDEFNODE("convtab", po_convtab), PREDEFNODE("tx", po_text), @@ -1278,7 +1293,7 @@ static struct ronode pseudo_opcode_list[] = { PREDEFNODE("skip", po_skip), PREDEFNODE("align", po_align), PREDEFNODE("pseudopc", po_pseudopc), - PREDEFNODE("realpc", obsolete_po_realpc), + PREDEFNODE("realpc", po_realpc), // obsolete PREDEFNODE("cpu", po_cpu), PREDEFNODE("al", po_al), PREDEFNODE("as", po_as), @@ -1291,9 +1306,9 @@ static struct ronode pseudo_opcode_list[] = { PREDEFNODE(s_sl, po_symbollist), PREDEFNODE("symbollist", po_symbollist), PREDEFNODE("zn", po_zone), - PREDEFNODE(s_zone, po_zone), - PREDEFNODE("sz", obsolete_po_subzone), - PREDEFNODE(s_subzone, obsolete_po_subzone), + PREDEFNODE("zone", po_zone), + PREDEFNODE("sz", po_subzone), // obsolete + PREDEFNODE("subzone", po_subzone), // obsolete PREDEFNODE("src", po_source), PREDEFNODE("source", po_source), PREDEFNODE("if", po_if), diff --git a/src/section.c b/src/section.c index 0541ffe..242c4be 100644 --- a/src/section.c +++ b/src/section.c @@ -73,7 +73,7 @@ void section_passinit(void) { //printf("[old maxima: locals=%d, cheap=%d]\n", local_scope_max, cheap_scope_max); local_scope_max = 0; // will be incremented by 2 by next line - section_new(&outer_section, s_Zone, s_untitled, FALSE); + section_new(&outer_section, "Zone", s_untitled, FALSE); cheap_scope_max = -1; // will be incremented by 2 by next line section_new_cheap_scope(&outer_section); }