diff --git a/ACME_Lib/6502/split.a b/ACME_Lib/6502/split.a new file mode 100644 index 0000000..9c4cb4f --- /dev/null +++ b/ACME_Lib/6502/split.a @@ -0,0 +1,45 @@ +;ACME 0.96.5 +!set split_cache = [] ; start every pass with an empty cache +!ifdef lib_6502_split_a !eof +lib_6502_split_a = 1 + +!macro split_lo @args { + +split_putbytes 0, @args + !set split_cache = split_cache + @args +} +!macro split_hi @args { + +split_putbytes 8, @args + !set split_cache = split_cache + @args +} +!macro split_lo { + +split_putbytes 0, split_cache + !set split_cache = [] +} +!macro split_hi { + +split_putbytes 8, split_cache + !set split_cache = [] +} +!macro split_putbytes @shift, @bytes { + !if len(@bytes) { + !for @idx, 0, len(@bytes) - 1 { + !by (@bytes[@idx] >> @shift) & $ff + } + } +} +!eof +; these macros can be used to split address tables in two separate +; parts for high- and low-bytes. example: + +table_hi + +split_hi [$0123, $4567, $89ab, $cdef] ; writes $01, $45, $89, $cd + +split_hi [$1122, $3344, $5566, $7788] ; writes $11, $33, $55, $77 +table_lo + +split_lo ; writes $23, $67, $ab, $ef, $22, $44, $66, $88 from cache + +; of course you can also put the low bytes first: + +table_lo + +split_lo [$0123, $4567, $89ab, $cdef] ; writes $23, $67, $ab, $ef + +split_lo [$1122, $3344, $5566, $7788] ; writes $22, $44, $66, $88 +table_hi + +split_hi ; writes $01, $45, $89, $cd, $11, $33, $55, $77 from cache diff --git a/docs/65816.txt b/docs/65816.txt index 0d23bb5..e08a9a0 100644 --- a/docs/65816.txt +++ b/docs/65816.txt @@ -30,12 +30,13 @@ According to WDC's official syntax for 65816 assembly language, the argument order of the MVN and MVP instructions differs between assembly language and machine code. To copy bytes from bank $ab to bank $cd, use the following statement: - mvn $ab, $cd ; source bank $ab, destination bank $cd + mvn $ab, $cd ; source bank $ab, destination bank $cd +or + mvn #$ab, #$cd ; source bank $ab, destination bank $cd ACME will then produce the following machine code: - $54 $cd $ab ; opcode mvn, destination bank $cd, source bank $ab + $54 $cd $ab ; opcode mvn, destination bank $cd, source bank $ab -ACME 0.05 and earlier did it the wrong way. Several other assemblers -still do. Make sure your sources are correct. +ACME 0.05 and earlier did it the wrong way. ---------------------------------------------------------------------- diff --git a/docs/Changes.txt b/docs/Changes.txt index 4638712..5c9c7da 100644 --- a/docs/Changes.txt +++ b/docs/Changes.txt @@ -12,6 +12,70 @@ platform used. There should be another help file in this archive outlining the platform specific changes. +---------------------------------------------------------------------- +Section: New in release 0.97 +---------------------------------------------------------------------- + +FINALLY strings can be assigned to symbols! + "anything in double quotes" is a string, while characters in + single quotes are, just as before, immediately converted to their + character code. Go and read "docs/Upgrade.txt" to learn about + compatibility issues. +Added backslash escaping in all string literals: + \0 is a null byte, \t is a TAB, \n is a line feed, \r is a + carriage return, \" is a double quote, \' is a single quote and + \\ is a backslash. Go and read "docs/Upgrade.txt" to learn about + compatibility issues. +Added "--dialect" CLI switch: + Because string symbols and backslash escaping introduce a few + incompatibilities to older versions, ACME can now be told to mimic + the behavior of older versions. So it's still possible to assemble + older sources. +Added lists: + Lists can be used to pass an arbitrary number of arguments to + macros, or to store any number of items (including other lists) in + a single symbol. Example: my_list = [1, 2, label, "string", 9] +Added "len()" operator: + This returns the number of elements in a string or list. +Added "[]" operator (for indexing): + This returns a single element from a string or list. Negative + indices are supported as well, they access the string/list from + the other end. Examples: a = my_list[2] b = my_string[-1] +Added "&" operator: + This operator converts labels or the program counter from its + value inside a "!pseudopc" block to the value outside of that + block. Thanks to markusC64 for the suggestion! +Added "!while {}" pseudo opcode. +Added "else if", "else ifdef" and "else ifndef" possibilities. +Added "M65" cpu: + This instruction set includes the MEGA65 extensions, namely 32-bit + pointers and 32-bit data operations using prefix bytes. +Added "NMOS6502" as an alias for "6510" cpu. +Improved NMOS6502/6510 mode: + DOP and TOP can now also be written as NOP. +Improved 65816 mode: + MVN and MVP can now also be written with '#' before arguments. +Added "--test" CLI switch: + This is for people who want to help test experimental features. +Improved error messages: + "Garbage data at end of statement" now includes the unexpected + character. + "Symbol not defined" is only output once per symbol. +Added warning: + ACME complains about binary literals with an "unusual" number of + digits. Thanks to groepaz for the suggestion! + The warning can be disabled using the "-Wno-bin-len" CLI switch. +Added warning: + All mnemonics without indirect addressing now complain about + unneeded parentheses. +Fix: Characters are now unsigned (had been architecture-dependent). +Improved error handling of "--cpu" and "--format" switches. +Added opcode table for NMOS6502 cpu to docs. +Added some test sources. +Fixed some minor bugs no-one ever seems to have encountered. +Rewritten "docs/Upgrade.txt". + + ---------------------------------------------------------------------- Section: New in release 0.96.5 ---------------------------------------------------------------------- diff --git a/docs/QuickRef.txt b/docs/QuickRef.txt index 8aef78f..455f9eb 100644 --- a/docs/QuickRef.txt +++ b/docs/QuickRef.txt @@ -106,7 +106,7 @@ Then there are local symbols (their names starting with a '.' character). These can only be accessed from inside the macro or zone they were defined in (for more about macros and zones, see the file "AllPOs.txt"). -There are also "cheap locals": their names start with a '@' character. +There are also "cheap locals": their names start with an '@'. The area where these can be accessed is limited automatically by the previous and the following global label (cheap locals are "cheap" because you don't have to put in any extra work to limit their range). @@ -323,56 +323,116 @@ given on the command line. ---------------------------------------------------------------------- -Section: The maths parser +Section: The expression parser ---------------------------------------------------------------------- ACME has a relatively powerful maths parser. This parser is used -whenever ACME expects to read a numerical value. Supported operations -include addition, subtraction, multiplication, divisions, comparisons, -shifts, negation, boolean operations and some assembler-specific stuff -like extracting the "low byte", the "high byte" or the "bank byte" -of a value. -Calculations are done using either signed 32-bit integer arithmetic or -floating point arithmetic using the C "double" data type. Symbol -values are stored the same way. +whenever ACME expects to read a value. Supported operations include +addition, subtraction, multiplication, divisions, comparisons, shifts, +negation, boolean operations and some assembler-specific stuff like +extracting the "low byte", the "high byte" or the "bank byte" of a +value. +Calculations are done using either signed (at least 32-bit) integer +arithmetic or floating point arithmetic using the C "double" data +type. Symbol values are stored the same way. + + +This is a list of the value formats currently known by ACME: + +Examples Notes +--------------------------------------------------------------------- +128 a decimal value, integer +128.5 a decimal value, floating point +$d011 hexadecimal values are indicated by either a +0xffd2 leading "$" or a leading "0x". +&1701 an octal value, indicated by "&" +%1010 binary values are indicated by either a leading "%" +%....#... or a leading "0b". In binary values, you can +0b01100110 substitute the characters "0" and "1" by "." and + "#" respectively. This way the values are much + more readable, especially when building bitmapped + objects (like C64 sprites or fonts) in your source + code. +'p' single characters in single quotes are converted to + their character code. The actual numeric value + depends on the current conversion table chosen + using the "!ct" pseudo opcode. +"player 2" double quotes indicate text strings. See below for + more information on single vs. double quotes. +[2, 3, 5, 7] brackets indicate lists. These are useful to group +[0, [x, y], 9] data, for example when passing an arbitrary number + of arguments to a macro. +poll_joy2 a global symbol +.fail a local symbol, indicated by leading "." +@loop a "cheap local", indicated by leading "@" +* the current program counter. During offset assembly, + "*" gives the value of the "Pseudo PC". Just to + make sure: The value of the program counter is + always the value that was valid at the start of + the current statement, so + !word *, *, *, * + will give the same value four times. I think most + assemblers do it this way. + +In older versions of ACME , 'x' and "x" were the same thing, namely +the character code of the letter x using the currently selected +encoding table. +Since release 0.97, anything in single quotes gives the character code +(as before), while anything in double quotes is treated as a string +object. To be compatible to those older versions, ACME keeps accepting +one-char strings in a lot of places where actually single characters +are expected. + This is a list of the operators currently known by ACME: - Priority Example Meaning Alias ------------------------------------------------------------- - 14 sin(v) Trigonometric sine function - 14 cos(v) Trigonometric cosine function - 14 tan(v) Trigonometric tangent function - 14 arcsin(v) Inverse of sin() - 14 arccos(v) Inverse of cos() - 14 arctan(v) Inverse of tan() - 14 address(v) Mark as address addr(v) - 14 int(v) Convert to integer - 14 float(v) Convert to float - 13 ! v Complement of NOT - 12 v ^ w To the power of - 11 - v Negate - 10 v * w Multiply - 10 v / w Divide - 10 v DIV w Integer-Divide - 10 v % w Remainder of DIV MOD - 9 v + w Add - 9 v - w Subtract - 8 v << w Shift left ASL, LSL - 8 v >> w Arithmetic shift right ASR - 8 v >>> w Logical shift right LSR - 7 < v Lowbyte of - 7 > v Highbyte of - 7 ^ v Bankbyte of - 6 v <= w Lower or equal - 6 v < w Lower than - 6 v >= w Higher or equal - 6 v > w Higher than - 5 v != w Not equal <>, >< - 4 v = w Equal - 3 v & w Bit-wise AND AND - 2 Bit-wise exclusive OR XOR - 1 v | w Bit-wise OR OR +Priority Example Meaning Alias Note +---------------------------------------------------------------------- + 16 is_number(v) these three functions return 1 *3 + 16 is_list(v) if v is the correct symbol *3 + 16 is_string(v) type and 0 otherwise *3 + 16 len(v) length of list or string *2 + 16 sin(v) trigonometric sine function + 16 cos(v) trigonometric cosine function + 16 tan(v) trigonometric tangent function + 16 arcsin(v) inverse of sin() + 16 arccos(v) inverse of cos() + 16 arctan(v) inverse of tan() + 16 address(v) mark as address addr(v) + 16 int(v) convert to integer + 16 float(v) convert to float + 15 &symbol "unpseudopc" symbol (see docs on "!pseudopc") + 14 v[w] access v with index w *2 + 13 ! v bit-wise complement NOT + 12 v ^ w to the power of + 11 - v negate + 10 v * w multiply + 10 v / w divide + 10 v DIV w integer divide + 10 v % w remainder of DIV MOD + 9 v + w add *3 + 9 v - w subtract + 8 v << w shift left ASL, LSL + 8 v >> w arithmetic shift right ASR + 8 v >>> w logical shift right LSR + 7 < v low byte of + 7 > v high byte of + 7 ^ v bank byte of + 6 v <= w lower or equal + 6 v < w lower than + 6 v >= w higher or equal + 6 v > w higher than + 5 v != w not equal <>, >< *3 + 4 v = w equal *3 + 3 v & w bit-wise AND AND + 2 bit-wise exclusive OR XOR + 1 v | w bit-wise OR OR + +Notes: +"*2" means this operator only works on lists and strings. +"*3" means this operator works on all three data types (numbers, lists +and strings). +All other operators only work on numbers. Operations with higher priority are done first. Of course you can change this using parentheses. @@ -392,42 +452,8 @@ Calculating 0^0 (zero to the power of zero) will give 1. If you don't know why I'm telling you this, ask a mathematician. :) -This is a list of the value formats currently known by ACME: - -Examples Notes ---------------------------------------------------------------------- -128 a decimal value, integer -128.5 a decimal value, floating point -$d011 hexadecimal values are indicated by either a -0xffd2 leading "$" or a leading "0x". -&1701 an octal value, indicated by "&" -%1010 binary values are indicated by either a leading "%" -%....#... or a leading "0b". In binary values, you can -0b01100110 substitute the characters "0" and "1" by "." and - "#" respectively. This way the values are much - more readable, especially when building bitmapped - objects (like C64 sprites or fonts) in your source - code. -'p' character values are indicated by single or double -"q" quotes. The actual numeric value depends on the - current conversion table (none/petscii/screen), - chosen using the "!ct" pseudo opcode. -poll_joy2 a global symbol -.fail a local symbol, indicated by leading "." -@loop a "cheap local", indicated by leading "@" -* the current program counter. During offset assembly, - "*" gives the value of the "Pseudo PC". Just to - make sure: The value of the program counter is - always the value that was valid at the start of - the current statement, so - !word *, *, *, * - will give the same value four times. I think most - assemblers do it this way. - - - ---------------------------------------------------------------------- -Section: Almost, but not quite, entirely useless syntax +Section: Almost, but not quite, complete syntax ---------------------------------------------------------------------- Every ACME source code file consists of a non-negative number of @@ -457,9 +483,9 @@ Two other possibilities for label names are "all-characters-are-minus" (then it is an anonymous forward label). Every command is one of the following: - An assembler opcode + An assembler mnemonic with an optional argument A pseudo opcode, beginning with a "!" character - A symbol definition (symbol=value) + An explicit symbol definition (SYMBOL = VALUE) A pc definition, beginning with a "*" character A macro call, beginning with a "+" character ...and the syntax of those things varies. :) diff --git a/docs/Upgrade.txt b/docs/Upgrade.txt index 1293ef2..6d5f667 100644 --- a/docs/Upgrade.txt +++ b/docs/Upgrade.txt @@ -11,6 +11,68 @@ If you haven't used ACME before, you don't need to read this text. +---------------------------------------------------------------------- +Upgrading from earlier releases to ACME release 0.97 +---------------------------------------------------------------------- + +a) Single quotes vs. double quotes: +Since "anything in double quotes" is now considered to be a string, +problems can arise when trying to do a calculation with a character +code. Here are some examples: + lda #' ' ; loads 32 like before (ASCII code of space) + lda #' ' + 1 ; loads 33 like before (32 plus one) + lda #" " ; loads 32 like before (ASCII code of space) + lda #" " + 1 ; used to load 33, now fails with error! +The third example still works, because 1-char-strings are treated +just like single characters when returned by the expression parser as +an argument for a mnemonic. +However, the fourth example now fails because the expression parser +tries to add a string to an integer, which is an undefined operation. +Some examples for a related problem: + a = ' ' ; a is 32 (ASCII code of space) + b = ' ' + 1 ; b is 33 (32 plus one) + c = "!" ; c used to be 33, now it's a 1-char string + d = "!" + "!" ; d used to be 66, now it's a 2-char string +If you do not get any errors when compiling your old sources, you do +not need to worry about this problem. +If you _do_ get errors, just use single quotes instead of double +quotes. If you had to use double quotes because the quoted character +itself is a single quote, write '\'' instead (backslash escaping, see +below). + +b) Backslash escaping: +Backslashes in single or double quotes are now used as escape +characters. You need to replace any backslash in older sources with a +sequence of two backslashes, so "some\string" becomes "some\\string", +and a single character '\' becomes '\\'. +If you have used backslashes as directory separators in path names (in +Windows/DOS environments), these also need changing - but instead of +using a double backslash, just use a single forward slash ('/') +instead. This has the added benefit of making the sources platform- +independent (*and* it's compatible to older ACME releases as well). + +c) Character values are now unsigned: +When parsing a character in single quotes, ACME returns its character +code, according to the chosen encoding (raw/petscii/screencode). If +this resulted in a byte with its most significant bit set, the actual +number was architecture-dependent. Here's an example: + !ct pet ; choose PetSCII encoding + x = 'A' ; PetSCII 'A' is 0xc1, so MSB is set +Now x was either -63 or +193, depending on the host cpu architecture. +Since release 0.97, this example will give 193 on all architectures. +In most cases, this is not a problem, because the actual bit pattern +of the lower eight bits is the same. But if you have written any code +where the numerical value of a PetSCII character is used for +computations _in_the_source_code_, please check those computations. + +Use the "--dialect 0.94.12" CLI switch to get the old behavior +concerning a) double quotes and b) backslashes. There is no way to get +the old behavior concerning c) character values, because, as explained +above, the old behavior was architecture-dependent, which is a bad +idea(tm). + + + ---------------------------------------------------------------------- Upgrading from earlier releases to ACME release 0.95.2 ---------------------------------------------------------------------- @@ -18,7 +80,7 @@ Upgrading from earlier releases to ACME release 0.95.2 In 6510 mode, ACME now outputs 0x0b instead of 0x2b when assembling the undocumented ("illegal") ANC #imm8 instruction. Both opcodes do the same thing, this was only changed because all other mnemonics use -the smallest possible opcode as well. +the lowest-numbered possible opcode as well. Forcing the old behavior via the "--dialect" switch is not supported. diff --git a/src/acme.c b/src/acme.c index aea7677..73ddc9b 100644 --- a/src/acme.c +++ b/src/acme.c @@ -141,7 +141,7 @@ static void show_help_and_exit(void) " -I PATH/TO/DIR add search path for input files\n" // TODO: replace these: " -W" OPTIONWNO_LABEL_INDENT " suppress warnings about indented labels\n" -" -W" OPTIONWNO_OLD_FOR " suppress warnings about old \"!for\" syntax\n" +" -W" OPTIONWNO_OLD_FOR " (old, use \"--dialect 0.94.8\" instead)\n" " -W" OPTIONWNO_BIN_LEN " suppress warnings about lengths of binary literals\n" " -W" OPTIONWTYPE_MISMATCH " enable type checking (warn about type mismatch)\n" // with this line and add a separate function: @@ -470,8 +470,8 @@ struct dialect dialects[] = { {VER_DISABLED_OBSOLETE_STUFF, "0.94.8", "\"*=\" works inside \"!pseudopc\", disabled \"!cbm/!realpc/!subzone\""}, {VER_NEWFORSYNTAX, "0.94.12", "new \"!for\" syntax"}, // {VER_, "0.95.2", "changed ANC#8 from 0x2b to 0x0b"}, + {VER_BACKSLASHESCAPING, "0.97", "backslash escaping and strings"}, // {VER_CURRENT, "default", "default"}, -// {VER_BACKSLASHESCAPING, "0.97", "backslash escaping and strings"}, {VER_FUTURE, "future", "enable all experimental features"}, {0, NULL, NULL} // NULLs terminate }; diff --git a/src/alu.c b/src/alu.c index 3855188..bcc0af3 100644 --- a/src/alu.c +++ b/src/alu.c @@ -453,7 +453,7 @@ static void parse_quoted(char closing_quote) if (GlobalDynaBuf->size != 1) Throw_error("There's more than one character."); // parse character - value = (intval_t) (unsigned char) encoding_encode_char(GLOBALDYNABUF_CURRENT[0]); + value = encoding_encode_char(GLOBALDYNABUF_CURRENT[0]); PUSH_INT_ARG(value, 0, 0); // no flags, no addr refs } // Now GotByte = char following closing quote (or CHAR_EOS on error) @@ -490,7 +490,7 @@ static void parse_binary_literal(void) // Now GotByte = "%" or "b" } if (!digits) Throw_warning("Binary literal without any digits."); // FIXME - make into error! - if ((digits & config.warn_bin_mask) && (config.wanted_version >= VER_BACKSLASHESCAPING)) + if (digits & config.warn_bin_mask) Throw_first_pass_warning("Binary literal with strange number of digits."); // set force bits if (config.honor_leading_zeroes) { @@ -1293,7 +1293,7 @@ static void string_to_byte(struct object *self, int index) { intval_t byte; - byte = (intval_t) (unsigned char) encoding_encode_char(self->u.string->payload[index]); + byte = encoding_encode_char(self->u.string->payload[index]); self->u.string->refs--; // FIXME - call a function for this... int_create_byte(self, byte); } diff --git a/src/encoding.c b/src/encoding.c index 5581982..7891fc5 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -17,41 +17,41 @@ // struct definition struct encoder { - char (*fn)(char); + unsigned char (*fn)(unsigned char); // maybe add table pointer? }; // variables -static char outermost_table[256]; // space for encoding table... +static unsigned char outermost_table[256]; // space for encoding table... const struct encoder *encoder_current; // gets set before each pass -char *encoding_loaded_table = outermost_table; // ...loaded from file +unsigned char *encoding_loaded_table = outermost_table; // ...loaded from file // encoder functions: // convert raw to raw (do not convert at all) -static char encoderfn_raw(char byte) +static unsigned char encoderfn_raw(unsigned char byte) { return byte; } // convert raw to petscii -static char encoderfn_pet(char byte) +static unsigned char encoderfn_pet(unsigned char byte) { - if ((byte >= 'A') && (byte <= 'Z')) - return (char) (byte | 0x80); // FIXME - check why SAS-C - if ((byte >= 'a') && (byte <= 'z')) // wants these casts. - return (char) (byte - 32); // There are more below. + if ((byte >= (unsigned char) 'A') && (byte <= (unsigned char) 'Z')) + return byte | 0x80; + if ((byte >= (unsigned char) 'a') && (byte <= (unsigned char) 'z')) + return byte - 32; return byte; } // convert raw to C64 screencode -static char encoderfn_scr(char byte) +static unsigned char encoderfn_scr(unsigned char byte) { - if ((byte >= 'a') && (byte <= 'z')) - return (char) (byte - 96); // shift uppercase down - if ((byte >= '[') && (byte <= '_')) - return (char) (byte - 64); // shift [\]^_ down + if ((byte >= (unsigned char) 'a') && (byte <= (unsigned char) 'z')) + return byte - 96; // shift uppercase down + if ((byte >= (unsigned char) '[') && (byte <= (unsigned char) '_')) + return byte - 64; // shift [\]^_ down if (byte == '`') return 64; // shift ` down if (byte == '@') @@ -59,9 +59,9 @@ static char encoderfn_scr(char byte) return byte; } // convert raw to whatever is defined in table -static char encoderfn_file(char byte) +static unsigned char encoderfn_file(unsigned char byte) { - return encoding_loaded_table[(unsigned char) byte]; + return encoding_loaded_table[byte]; } @@ -97,7 +97,7 @@ static struct ronode encoder_list[] = { // convert character using current encoding (exported for use by alu.c and pseudoopcodes.c) -char encoding_encode_char(char byte) +unsigned char encoding_encode_char(unsigned char byte) { return encoder_current->fn(byte); } @@ -109,7 +109,7 @@ void encoding_passinit(void) } // try to load encoding table from given file -void encoding_load_from_file(char target[256], FILE *stream) +void encoding_load_from_file(unsigned char target[256], FILE *stream) { if (fread(target, sizeof(char), 256, stream) != 256) Throw_error("Conversion table incomplete."); diff --git a/src/encoding.h b/src/encoding.h index ada5d71..72efd80 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -1,5 +1,5 @@ // ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code. -// Copyright (C) 1998-2016 Marco Baye +// Copyright (C) 1998-2020 Marco Baye // Have a look at "acme.c" for further info // // Character encoding stuff @@ -16,17 +16,17 @@ extern const struct encoder encoder_raw; extern const struct encoder encoder_pet; extern const struct encoder encoder_scr; extern const struct encoder encoder_file; -extern char *encoding_loaded_table; // ...loaded from file +extern unsigned char *encoding_loaded_table; // ...loaded from file // prototypes // convert character using current encoding -extern char encoding_encode_char(char byte); +extern unsigned char encoding_encode_char(unsigned char byte); // set "raw" as default encoding extern void encoding_passinit(void); // try to load encoding table from given file -extern void encoding_load_from_file(char target[256], FILE *stream); +extern void encoding_load_from_file(unsigned char target[256], FILE *stream); // lookup encoder held in DynaBuf and return its struct pointer (or NULL on failure) extern const struct encoder *encoding_find(void); diff --git a/src/global.h b/src/global.h index b22eb2d..310c3f0 100644 --- a/src/global.h +++ b/src/global.h @@ -67,8 +67,8 @@ enum version { VER_DISABLED_OBSOLETE_STUFF, // v0.94.8 made *= work inside !pseudopc, disabled !cbm/!realpc/!subzone VER_NEWFORSYNTAX, // v0.94.12 introduced the new "!for" syntax // v0.95.2 changed ANC#8 from 0x2b to 0x0b + VER_BACKSLASHESCAPING, // v0.97 introduced backslash escaping (and therefore strings) VER_CURRENT, // "RELEASE" - VER_BACKSLASHESCAPING, // v0.97 added backslash escaping (and therefore strings) // possible changes in future versions: // paths should be relative to file, not start dir // ignore leading zeroes? @@ -170,9 +170,9 @@ extern void Throw_serious_error(const char *msg); extern void Bug_found(const char *msg, int code); // insert object (in case of list, will iterate/recurse until done) struct iter_context { - void (*fn)(intval_t); // output function - boolean accept_long_strings; // if FALSE, only 1-char-strings work - char stringxor; // for !scrxor, 0 otherwise + void (*fn)(intval_t); // output function + boolean accept_long_strings; // if FALSE, only 1-char-strings work + unsigned char stringxor; // for !scrxor, 0 otherwise }; extern void output_object(struct object *object, struct iter_context *iter); // output 8-bit value with range check diff --git a/src/pseudoopcodes.c b/src/pseudoopcodes.c index 43eebc9..5f87eab 100644 --- a/src/pseudoopcodes.c +++ b/src/pseudoopcodes.c @@ -319,7 +319,7 @@ static enum eos po_cbm(void) // read encoding table from file static enum eos user_defined_encoding(FILE *stream) { - char local_table[256], + unsigned char local_table[256], *buffered_table = encoding_loaded_table; const struct encoder *buffered_encoder = encoder_current; @@ -345,7 +345,7 @@ static enum eos user_defined_encoding(FILE *stream) // use one of the pre-defined encodings (raw, pet, scr) static enum eos predefined_encoding(void) { - char local_table[256], + unsigned char local_table[256], *buffered_table = encoding_loaded_table; const struct encoder *buffered_encoder = encoder_current; @@ -382,7 +382,7 @@ static enum eos po_convtab(void) } } // insert string(s) -static enum eos encode_string(const struct encoder *inner_encoder, char xor) +static enum eos encode_string(const struct encoder *inner_encoder, unsigned char xor) { const struct encoder *outer_encoder = encoder_current; // buffer encoder struct iter_context iter; diff --git a/src/version.h b/src/version.h index 00a0191..cd0f4c8 100644 --- a/src/version.h +++ b/src/version.h @@ -7,9 +7,9 @@ #define version_H -#define RELEASE "0.96.5" // update before release FIXME -#define CODENAME "Fenchurch" // update before release -#define CHANGE_DATE "26 June" // update before release FIXME +#define RELEASE "0.97" // update before release FIXME +#define CODENAME "Zem" // update before release +#define CHANGE_DATE "28 June" // update before release FIXME #define CHANGE_YEAR "2020" // update before release //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME