diff --git a/contrib/toacme/docs/README b/contrib/toacme/docs/README index 1d9dca3..83aabb4 100644 --- a/contrib/toacme/docs/README +++ b/contrib/toacme/docs/README @@ -9,7 +9,7 @@ Copyright --------- ToACME - a source code converter for the ACME crossassembler -Copyright (C) 1998-2015 Marco Baye +Copyright (C) 1998-2016 Marco Baye This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -71,7 +71,7 @@ giga C64: Giga-Assembler ok vis C64: VisAss untested ab3 C64: AssBlaster 3.0 to 3.2 good f8ab C64: Flash8-AssBlaster ok - +prof C64: Professional Assembler poor (work in progress) Contacting the author @@ -90,3 +90,4 @@ Credits Thanks to Stefan Hübner for fixing the AssBlaster macro conversion code. Thanks to Andreas Paul for helping with the Giga-Assembler mode. Thanks to Arndt Dettke for helping with the Hypra-Assembler mode. +Thanks to Hoogo for helping with the Professional Assembler mode. diff --git a/contrib/toacme/src/Makefile b/contrib/toacme/src/Makefile index ec773a3..254dde8 100644 --- a/contrib/toacme/src/Makefile +++ b/contrib/toacme/src/Makefile @@ -37,12 +37,14 @@ pet2iso.o: config.h pet2iso.h pet2iso.c platform.o: config.h platform.h platform.c +prof.o: config.h prof.c + scr2iso.o: config.h scr2iso.h scr2iso.c version.o: config.h version.c -toacme: vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o scr2iso.o version.o - $(CC) $(LIBS) $(CFLAGS) -o toacme vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o scr2iso.o version.o +toacme: vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o prof.o scr2iso.o version.o + $(CC) $(LIBS) $(CFLAGS) -o toacme vis.o ab.o ab3.o acme.o f8ab.o giga.o gighyp.o hypra.o io.o main.o mnemo.o obj.o pet2iso.o platform.o prof.o scr2iso.o version.o strip toacme clean: diff --git a/contrib/toacme/src/prof.c b/contrib/toacme/src/prof.c new file mode 100644 index 0000000..258ebc5 --- /dev/null +++ b/contrib/toacme/src/prof.c @@ -0,0 +1,91 @@ +// ToACME - converts other source codes to ACME format. +// Copyright (C) 1999-2016 Marco Baye +// Have a look at "main.c" for further info +// +// "Professional Ass by Oliver Stiller" stuff (NOT "Profi-Ass" by Data Becker!) +// Kickoff: +// http://www.forum64.de/wbb4/index.php?thread/60047-toacme-demn%C3%A4chst-als-win32-release/ + +#include +//#include "config.h" +//#include "acme.h" +//#include "mnemo.h" +#include "io.h" +#include "scr2iso.h" + +// format of input files: +// load address, lo +// load address, hi +// for each line: +// total line length, including this byte +// amount of indentation +// actual line as screen code (this part might be missing in case of empty line) +// total line length, including this byte (yes, the same value again, for upscrolling) +// that's it! + +// special directives: +// '.' is for pseudo opcodes? +// .setpc is *= +// .fill (length, data) ? +// .b is !by, .w is !wo, .macro reads a macro argument? +// .goto is used to skip macro definitions?! +// what do .begin and .end do? local label scope? +// .print str$(*-$1060) wow... O_o +// '-' prefix means local label definition? +// '+' prefix means global label definition? +// '_' starts a macro definition? ".endmacro" ends definition? +// '*' prefix is a macro call? + +#define TABSIZE 8 // anything else is heresy +#define REV_START ";-=#" +#define REV_END "#=-" + +// main +void prof_main(void) +{ + int length1, + indent, + ii, + byte, + hibit, + length2; + + IO_set_input_padding(0); + IO_process_load_address(); + for (;;) { + length1 = IO_get_byte(); + if (length1 == EOF) + break; + if (length1 < 3) { + fprintf(stderr, "Error: Short line (%d bytes)\n", length1); + } + // read amount of indentation and output tabs/spaces + indent = IO_get_byte(); + if (indent < 0) { + fprintf(stderr, "Error: Negative indentation (%d)\n", indent); + } else { + for (ii = 0; ii + TABSIZE <= indent; ii += TABSIZE) + IO_put_byte('\t'); + for (; ii < indent; ii++) + IO_put_byte(' '); + } + // now convert line + hibit = 0; + for (ii = 0; ii < length1 - 3; ii++) { + byte = IO_get_byte(); + if ((byte & 128) != hibit) { + hibit = byte & 128; + IO_put_string(hibit ? REV_START : REV_END); + } + IO_put_byte(SCR2ISO(byte & 127)); + } + if (hibit) + IO_put_string(REV_END); + // and add newline + IO_put_byte('\n'); + // now check second length byte + length2 = IO_get_byte(); + if (length1 != length2) + fprintf(stderr, "Error: Length bytes differ (%d != %d)\n", length1, length2); + } +} diff --git a/contrib/toacme/src/version.c b/contrib/toacme/src/version.c index 48ee5bb..99c38f0 100644 --- a/contrib/toacme/src/version.c +++ b/contrib/toacme/src/version.c @@ -4,12 +4,12 @@ // // Version -#define RELEASE_NUMBER "0.12" // change before release (FIXME) -#define CHANGE_DATE "4 Feb" // change before release -#define CHANGE_YEAR "2015" // change before release +#define RELEASE_NUMBER "0.13" // change before release (FIXME) +#define CHANGE_DATE "16 Feb" // change before release +#define CHANGE_YEAR "2016" // change before release #define HOME_PAGE "http://sourceforge.net/projects/acme-crossass/" // "http://home.pages.de/~mac_bacon/smorbrod/acme/" -#define FILE_TAG ";ACME 0.95.4" // check before release +#define FILE_TAG ";ACME 0.95.6" // check before release #include #include @@ -33,6 +33,7 @@ PLATFORM_VERSION "\n" "Thanks to Stefan Hübner for fixing the AssBlaster macro conversion code.\n" "Thanks to Andreas Paul for helping with the Giga-Assembler mode.\n" "Thanks to Arndt Dettke for helping with the Hypra-Assembler mode.\n" +"Thanks to Hoogo for helping with the Professional Assembler mode.\n" "\n" "The newest version can be found at the ACME homepage:\n" HOME_PAGE "\n" @@ -51,6 +52,7 @@ HOME_PAGE "\n" "vis C64: VisAss untested\n" "ab3 C64: AssBlaster 3.0 to 3.2 good\n" "f8ab C64: Flash8-AssBlaster ok\n" +"prof C64: Professional Assembler poor (work in progress)\n" "\n" , program_name); } @@ -62,6 +64,7 @@ extern void f8ab_main(void); extern void giga_main(void); extern void hypra_main(void); extern void obj_main(void); +extern void prof_main(void); // check id string. returns whether illegal. @@ -79,6 +82,8 @@ int version_parse_id(const char id[]) client_main = hypra_main; else if (strcmp(id, "object") == 0) client_main = obj_main; + else if (strcmp(id, "prof") == 0) + client_main = prof_main; return client_main ? 0 : 1; } diff --git a/docs/AllPOs.txt b/docs/AllPOs.txt index 4d53310..de4c33c 100644 --- a/docs/AllPOs.txt +++ b/docs/AllPOs.txt @@ -27,29 +27,85 @@ Examples: !08 127, symbol, -128 ; output some values Call: !16 EXPRESSION [, EXPRESSION]* -Purpose: Insert 16-bit values. +Purpose: Insert 16-bit values in chosen CPU's byte order. Parameters: EXPRESSION: Any formula the value parser accepts. -Aliases: "!wo", "!word" +Aliases: "!wo", "!word" (and because all currently supported CPUs are + little-endian, "!le16" is in fact another alias) Examples: !16 65535, symbol, -32768 ; output some values !wo 14, $4f35, %100101010010110, &36304, *, "c" !word 3000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 +Call: !le16 EXPRESSION [, EXPRESSION]* +Purpose: Insert 16-bit values in little-endian byte order. +Parameters: EXPRESSION: Any formula the value parser accepts. +Aliases: None (but because all currently supported CPUs are + little-endian, "!16/!wo/!word" are in fact aliases) +Examples: !le16 65535, symbol, -32768 ; output some values + !le16 14, $4f35, %100101010010110, &36304, *, "c" + !le16 3000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 + +Call: !be16 EXPRESSION [, EXPRESSION]* +Purpose: Insert 16-bit values in big-endian byte order. +Parameters: EXPRESSION: Any formula the value parser accepts. +Aliases: None +Examples: !be16 65535, symbol, -32768 ; output some values + !be16 14, $4f35, %100101010010110, &36304, *, "c" + !be16 3000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 + Call: !24 EXPRESSION [, EXPRESSION]* -Purpose: Insert 24-bit values. +Purpose: Insert 24-bit values in chosen CPU's byte order. Parameters: EXPRESSION: Any formula the value parser accepts. +Aliases: None (but because all currently supported CPUs are + little-endian, "!le24" is in fact an alias) Examples: !24 16777215, symbol, -8388608, 14, $6a4f35 !24 %10010110100101010010110, &47336304, *, "c" !24 300000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 +Call: !le24 EXPRESSION [, EXPRESSION]* +Purpose: Insert 24-bit values in little-endian byte order. +Parameters: EXPRESSION: Any formula the value parser accepts. +Aliases: None (but because all currently supported CPUs are + little-endian, "!24" is in fact an alias) +Examples: !le24 16777215, symbol, -8388608, 14, $6a4f35 + !le24 %10010110100101010010110, &47336304, *, "c" + !le24 300000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 + +Call: !be24 EXPRESSION [, EXPRESSION]* +Purpose: Insert 24-bit values in big-endian byte order. +Parameters: EXPRESSION: Any formula the value parser accepts. +Aliases: None +Examples: !be24 16777215, symbol, -8388608, 14, $6a4f35 + !be24 %10010110100101010010110, &47336304, *, "c" + !be24 300000 - 4, a1 AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 + Call: !32 EXPRESSION [, EXPRESSION]* -Purpose: Insert 32-bit values. +Purpose: Insert 32-bit values in chosen CPU's byte order. Parameters: EXPRESSION: Any formula the value parser accepts. +Aliases: None (but because all currently supported CPUs are + little-endian, "!le32" is in fact an alias) Examples: !32 $7fffffff, symbol, -$80000000, 14, $46a4f35 !32 %1001011010010101001011010010, &4733630435, *, "c" !32 300000 - 4, a AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 +Call: !le32 EXPRESSION [, EXPRESSION]* +Purpose: Insert 32-bit values in little-endian byte order. +Parameters: EXPRESSION: Any formula the value parser accepts. +Aliases: None (but because all currently supported CPUs are + little-endian, "!32" is in fact an alias) +Examples: !le32 $7fffffff, symbol, -$80000000, 14, $46a4f35 + !le32 %1001011010010101001011010010, &4733630435, *, "c" + !le32 300000 - 4, a AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 + +Call: !be32 EXPRESSION [, EXPRESSION]* +Purpose: Insert 32-bit values in big-endian byte order. +Parameters: EXPRESSION: Any formula the value parser accepts. +Aliases: None +Examples: !be32 $7fffffff, symbol, -$80000000, 14, $46a4f35 + !be32 %1001011010010101001011010010, &4733630435, *, "c" + !be32 300000 - 4, a AND a2, 2 ^ tz, (3+4)*70, l1 & .j2 + Call: !fill AMOUNT [, VALUE] Purpose: Fill amount of memory with value. diff --git a/docs/Changes.txt b/docs/Changes.txt index 826cabf..5bb22e2 100644 --- a/docs/Changes.txt +++ b/docs/Changes.txt @@ -12,6 +12,18 @@ platform used. There should be another help file in this archive outlining the platform specific changes. +---------------------------------------------------------------------- +Section: New in release 0.95.7 +---------------------------------------------------------------------- + +New pseudo opcodes: + "!be16", "!be24" and "!be32" for big-endian byte order output. + "!le16", "!le24" and "!le32" for little-endian byte order output. + The old pseudo opcodes ("!16", "!24", "!32") will now use the correct + byte order for the chosen CPU (which is always little-endian, because + there is no support for any big-endian CPU yet. ;)) + + ---------------------------------------------------------------------- Section: New in release 0.95.6 ---------------------------------------------------------------------- diff --git a/src/acme.c b/src/acme.c index 4238d3d..f6fa04d 100644 --- a/src/acme.c +++ b/src/acme.c @@ -1,5 +1,5 @@ // ACME - a crossassembler for producing 6502/65c02/65816 code. -// Copyright (C) 1998-2015 Marco Baye +// Copyright (C) 1998-2016 Marco Baye // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -15,10 +15,10 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#define RELEASE "0.95.6" // update before release (FIXME) +#define RELEASE "0.95.7" // update before release (FIXME) #define CODENAME "Fenchurch" // update before release -#define CHANGE_DATE "16 Aug" // update before release -#define CHANGE_YEAR "2015" // update before release +#define CHANGE_DATE "16 Feb" // update before release +#define CHANGE_YEAR "2016" // update before release //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME diff --git a/src/cpu.h b/src/cpu.h index f5595c0..e91035e 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -21,6 +21,7 @@ struct cpu_type { #define CPUFLAG_INDIRECTJMPBUGGY (1u << 0) // warn if "jmp ($xxff)" is assembled #define CPUFLAG_SUPPORTSLONGREGS (1u << 1) // allow "!al" and "!rl" pseudo opcodes #define CPUFLAG_8B_AND_AB_NEED_0_ARG (1u << 2) // warn if "ane/lxa #$xx" uses non-zero arg +#define CPUFLAG_ISBIGENDIAN (1u << 3) // for 16/24/32-bit values, output msb first // if cpu type and value match, set register length variable to value. diff --git a/src/output.c b/src/output.c index cf78b7d..a445469 100644 --- a/src/output.c +++ b/src/output.c @@ -7,6 +7,7 @@ // 25 Sep 2011 Fixed bug in !to (colons in filename could be interpreted as EOS) // 5 Mar 2014 Fixed bug where setting *>0xffff resulted in hangups. // 19 Nov 2014 Merged Johann Klasek's report listing generator patch +// 22 Sep 2015 Added big-endian output functions #include "output.h" #include #include // for memset() @@ -192,7 +193,19 @@ void output_8(intval_t value) } -// output 16-bit value with range check +// output 16-bit value with range check big-endian +void output_be16(intval_t value) +{ + if ((value <= 0xffff) && (value >= -0x8000)) { + Output_byte(value >> 8); + Output_byte(value); + } else { + Throw_error(exception_number_out_of_range); + } +} + + +// output 16-bit value with range check little-endian void output_le16(intval_t value) { if ((value <= 0xffff) && (value >= -0x8000)) { @@ -204,7 +217,20 @@ void output_le16(intval_t value) } -// output 24-bit value with range check +// output 24-bit value with range check big-endian +void output_be24(intval_t value) +{ + if ((value <= 0xffffff) && (value >= -0x800000)) { + Output_byte(value >> 16); + Output_byte(value >> 8); + Output_byte(value); + } else { + Throw_error(exception_number_out_of_range); + } +} + + +// output 24-bit value with range check little-endian void output_le24(intval_t value) { if ((value <= 0xffffff) && (value >= -0x800000)) { @@ -217,7 +243,21 @@ void output_le24(intval_t value) } -// output 32-bit value (without range check) +// output 32-bit value (without range check) big-endian +void output_be32(intval_t value) +{ +// if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) { + Output_byte(value >> 24); + Output_byte(value >> 16); + Output_byte(value >> 8); + Output_byte(value); +// } else { +// Throw_error(exception_number_out_of_range); +// } +} + + +// output 32-bit value (without range check) little-endian void output_le32(intval_t value) { // if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) { diff --git a/src/output.h b/src/output.h index 0607190..cf1fd41 100644 --- a/src/output.h +++ b/src/output.h @@ -46,11 +46,17 @@ extern void Output_fake(int size); extern void (*Output_byte)(intval_t); // Output 8-bit value with range check extern void output_8(intval_t); -// Output 16-bit value with range check +// Output 16-bit value with range check big-endian +extern void output_be16(intval_t); +// Output 16-bit value with range check little-endian extern void output_le16(intval_t); -// Output 24-bit value with range check +// Output 24-bit value with range check big-endian +extern void output_be24(intval_t); +// Output 24-bit value with range check little-endian extern void output_le24(intval_t); -// Output 32-bit value (without range check) +// Output 32-bit value (without range check) big-endian +extern void output_be32(intval_t); +// Output 32-bit value (without range check) little-endian extern void output_le32(intval_t); // define default value for empty memory ("!initmem" pseudo opcode) // returns zero if ok, nonzero if already set diff --git a/src/pseudoopcodes.c b/src/pseudoopcodes.c index 9e64a46..0f940dc 100644 --- a/src/pseudoopcodes.c +++ b/src/pseudoopcodes.c @@ -152,7 +152,17 @@ static enum eos po_byte(void) // Insert 16-bit values ("!16" / "!wo" / "!word" pseudo opcode) -static enum eos po_word(void) +static enum eos po_16(void) +{ + return iterate((CPU_state.type->flags & CPUFLAG_ISBIGENDIAN) ? output_be16 : output_le16); +} +// Insert 16-bit values big-endian ("!be16" pseudo opcode) +static enum eos po_be16(void) +{ + return iterate(output_be16); +} +// Insert 16-bit values little-endian ("!le16" pseudo opcode) +static enum eos po_le16(void) { return iterate(output_le16); } @@ -160,6 +170,16 @@ static enum eos po_word(void) // Insert 24-bit values ("!24" pseudo opcode) static enum eos po_24(void) +{ + return iterate((CPU_state.type->flags & CPUFLAG_ISBIGENDIAN) ? output_be24 : output_le24); +} +// Insert 24-bit values big-endian ("!be24" pseudo opcode) +static enum eos po_be24(void) +{ + return iterate(output_be24); +} +// Insert 24-bit values little-endian ("!le24" pseudo opcode) +static enum eos po_le24(void) { return iterate(output_le24); } @@ -167,6 +187,16 @@ static enum eos po_24(void) // Insert 32-bit values ("!32" pseudo opcode) static enum eos po_32(void) +{ + return iterate((CPU_state.type->flags & CPUFLAG_ISBIGENDIAN) ? output_be32 : output_le32); +} +// Insert 32-bit values big-endian ("!be32" pseudo opcode) +static enum eos po_be32(void) +{ + return iterate(output_be32); +} +// Insert 32-bit values little-endian ("!le32" pseudo opcode) +static enum eos po_le32(void) { return iterate(output_le32); } @@ -948,11 +978,17 @@ static struct ronode pseudo_opcode_list[] = { PREDEFNODE(s_08, po_byte), PREDEFNODE("by", po_byte), PREDEFNODE("byte", po_byte), - PREDEFNODE(s_16, po_word), - PREDEFNODE("wo", po_word), - PREDEFNODE("word", po_word), + PREDEFNODE("wo", po_16), + PREDEFNODE("word", po_16), + PREDEFNODE(s_16, po_16), + PREDEFNODE("be16", po_be16), + PREDEFNODE("le16", po_le16), PREDEFNODE("24", po_24), + PREDEFNODE("be24", po_be24), + PREDEFNODE("le24", po_le24), PREDEFNODE("32", po_32), + PREDEFNODE("be32", po_be32), + PREDEFNODE("le32", po_le32), PREDEFNODE(s_cbm, obsolete_po_cbm), PREDEFNODE("ct", po_convtab), PREDEFNODE("convtab", po_convtab),