Release 0.97: Now with string symbols, lists, backslash escaping,

"unpseudopc" operator, MEGA65 support, !while, else if, and a CLI switch to
mimic older versions.
Make sure to read "docs/Changes.txt" and "docs/Upgrade.txt"!


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@266 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-06-28 18:56:55 +00:00
parent ca6b6d8771
commit d2683cc64d
12 changed files with 322 additions and 124 deletions

45
ACME_Lib/6502/split.a Normal file
View File

@ -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

View File

@ -31,11 +31,12 @@ argument order of the MVN and MVP instructions differs between
assembly language and machine code. assembly language and machine code.
To copy bytes from bank $ab to bank $cd, use the following statement: 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: 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 ACME 0.05 and earlier did it the wrong way.
still do. Make sure your sources are correct.
---------------------------------------------------------------------- ----------------------------------------------------------------------

View File

@ -12,6 +12,70 @@ platform used. There should be another help file in this archive
outlining the platform specific changes. 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 Section: New in release 0.96.5
---------------------------------------------------------------------- ----------------------------------------------------------------------

View File

@ -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 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 they were defined in (for more about macros and zones, see the file
"AllPOs.txt"). "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 The area where these can be accessed is limited automatically by the
previous and the following global label (cheap locals are "cheap" 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). 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 ACME has a relatively powerful maths parser. This parser is used
whenever ACME expects to read a numerical value. Supported operations whenever ACME expects to read a value. Supported operations include
include addition, subtraction, multiplication, divisions, comparisons, addition, subtraction, multiplication, divisions, comparisons, shifts,
shifts, negation, boolean operations and some assembler-specific stuff negation, boolean operations and some assembler-specific stuff like
like extracting the "low byte", the "high byte" or the "bank byte" extracting the "low byte", the "high byte" or the "bank byte" of a
of a value. value.
Calculations are done using either signed 32-bit integer arithmetic or Calculations are done using either signed (at least 32-bit) integer
floating point arithmetic using the C "double" data type. Symbol arithmetic or floating point arithmetic using the C "double" data
values are stored the same way. 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: This is a list of the operators currently known by ACME:
Priority Example Meaning Alias Priority Example Meaning Alias Note
------------------------------------------------------------ ----------------------------------------------------------------------
14 sin(v) Trigonometric sine function 16 is_number(v) these three functions return 1 *3
14 cos(v) Trigonometric cosine function 16 is_list(v) if v is the correct symbol *3
14 tan(v) Trigonometric tangent function 16 is_string(v) type and 0 otherwise *3
14 arcsin(v) Inverse of sin() 16 len(v) length of list or string *2
14 arccos(v) Inverse of cos() 16 sin(v) trigonometric sine function
14 arctan(v) Inverse of tan() 16 cos(v) trigonometric cosine function
14 address(v) Mark as address addr(v) 16 tan(v) trigonometric tangent function
14 int(v) Convert to integer 16 arcsin(v) inverse of sin()
14 float(v) Convert to float 16 arccos(v) inverse of cos()
13 ! v Complement of NOT 16 arctan(v) inverse of tan()
12 v ^ w To the power of 16 address(v) mark as address addr(v)
11 - v Negate 16 int(v) convert to integer
10 v * w Multiply 16 float(v) convert to float
10 v / w Divide 15 &symbol "unpseudopc" symbol (see docs on "!pseudopc")
10 v DIV w Integer-Divide 14 v[w] access v with index w *2
10 v % w Remainder of DIV MOD 13 ! v bit-wise complement NOT
9 v + w Add 12 v ^ w to the power of
9 v - w Subtract 11 - v negate
8 v << w Shift left ASL, LSL 10 v * w multiply
8 v >> w Arithmetic shift right ASR 10 v / w divide
8 v >>> w Logical shift right LSR 10 v DIV w integer divide
7 < v Lowbyte of 10 v % w remainder of DIV MOD
7 > v Highbyte of 9 v + w add *3
7 ^ v Bankbyte of 9 v - w subtract
6 v <= w Lower or equal 8 v << w shift left ASL, LSL
6 v < w Lower than 8 v >> w arithmetic shift right ASR
6 v >= w Higher or equal 8 v >>> w logical shift right LSR
6 v > w Higher than 7 < v low byte of
5 v != w Not equal <>, >< 7 > v high byte of
4 v = w Equal 7 ^ v bank byte of
3 v & w Bit-wise AND AND 6 v <= w lower or equal
2 Bit-wise exclusive OR XOR 6 v < w lower than
1 v | w Bit-wise OR OR 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 Operations with higher priority are done first. Of course you can
change this using parentheses. 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. :) 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 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). (then it is an anonymous forward label).
Every command is one of the following: 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 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 pc definition, beginning with a "*" character
A macro call, beginning with a "+" character A macro call, beginning with a "+" character
...and the syntax of those things varies. :) ...and the syntax of those things varies. :)

View File

@ -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 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 In 6510 mode, ACME now outputs 0x0b instead of 0x2b when assembling
the undocumented ("illegal") ANC #imm8 instruction. Both opcodes do the undocumented ("illegal") ANC #imm8 instruction. Both opcodes do
the same thing, this was only changed because all other mnemonics use 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. Forcing the old behavior via the "--dialect" switch is not supported.

View File

@ -141,7 +141,7 @@ static void show_help_and_exit(void)
" -I PATH/TO/DIR add search path for input files\n" " -I PATH/TO/DIR add search path for input files\n"
// TODO: replace these: // TODO: replace these:
" -W" OPTIONWNO_LABEL_INDENT " suppress warnings about indented labels\n" " -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" OPTIONWNO_BIN_LEN " suppress warnings about lengths of binary literals\n"
" -W" OPTIONWTYPE_MISMATCH " enable type checking (warn about type mismatch)\n" " -W" OPTIONWTYPE_MISMATCH " enable type checking (warn about type mismatch)\n"
// with this line and add a separate function: // 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_DISABLED_OBSOLETE_STUFF, "0.94.8", "\"*=\" works inside \"!pseudopc\", disabled \"!cbm/!realpc/!subzone\""},
{VER_NEWFORSYNTAX, "0.94.12", "new \"!for\" syntax"}, {VER_NEWFORSYNTAX, "0.94.12", "new \"!for\" syntax"},
// {VER_, "0.95.2", "changed ANC#8 from 0x2b to 0x0b"}, // {VER_, "0.95.2", "changed ANC#8 from 0x2b to 0x0b"},
{VER_BACKSLASHESCAPING, "0.97", "backslash escaping and strings"},
// {VER_CURRENT, "default", "default"}, // {VER_CURRENT, "default", "default"},
// {VER_BACKSLASHESCAPING, "0.97", "backslash escaping and strings"},
{VER_FUTURE, "future", "enable all experimental features"}, {VER_FUTURE, "future", "enable all experimental features"},
{0, NULL, NULL} // NULLs terminate {0, NULL, NULL} // NULLs terminate
}; };

View File

@ -453,7 +453,7 @@ static void parse_quoted(char closing_quote)
if (GlobalDynaBuf->size != 1) if (GlobalDynaBuf->size != 1)
Throw_error("There's more than one character."); Throw_error("There's more than one character.");
// parse 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 PUSH_INT_ARG(value, 0, 0); // no flags, no addr refs
} }
// Now GotByte = char following closing quote (or CHAR_EOS on error) // 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) if (!digits)
Throw_warning("Binary literal without any digits."); // FIXME - make into error! 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."); Throw_first_pass_warning("Binary literal with strange number of digits.");
// set force bits // set force bits
if (config.honor_leading_zeroes) { if (config.honor_leading_zeroes) {
@ -1293,7 +1293,7 @@ static void string_to_byte(struct object *self, int index)
{ {
intval_t byte; 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... self->u.string->refs--; // FIXME - call a function for this...
int_create_byte(self, byte); int_create_byte(self, byte);
} }

View File

@ -17,41 +17,41 @@
// struct definition // struct definition
struct encoder { struct encoder {
char (*fn)(char); unsigned char (*fn)(unsigned char);
// maybe add table pointer? // maybe add table pointer?
}; };
// variables // 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 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: // encoder functions:
// convert raw to raw (do not convert at all) // 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; return byte;
} }
// convert raw to petscii // convert raw to petscii
static char encoderfn_pet(char byte) static unsigned char encoderfn_pet(unsigned char byte)
{ {
if ((byte >= 'A') && (byte <= 'Z')) if ((byte >= (unsigned char) 'A') && (byte <= (unsigned char) 'Z'))
return (char) (byte | 0x80); // FIXME - check why SAS-C return byte | 0x80;
if ((byte >= 'a') && (byte <= 'z')) // wants these casts. if ((byte >= (unsigned char) 'a') && (byte <= (unsigned char) 'z'))
return (char) (byte - 32); // There are more below. return byte - 32;
return byte; return byte;
} }
// convert raw to C64 screencode // convert raw to C64 screencode
static char encoderfn_scr(char byte) static unsigned char encoderfn_scr(unsigned char byte)
{ {
if ((byte >= 'a') && (byte <= 'z')) if ((byte >= (unsigned char) 'a') && (byte <= (unsigned char) 'z'))
return (char) (byte - 96); // shift uppercase down return byte - 96; // shift uppercase down
if ((byte >= '[') && (byte <= '_')) if ((byte >= (unsigned char) '[') && (byte <= (unsigned char) '_'))
return (char) (byte - 64); // shift [\]^_ down return byte - 64; // shift [\]^_ down
if (byte == '`') if (byte == '`')
return 64; // shift ` down return 64; // shift ` down
if (byte == '@') if (byte == '@')
@ -59,9 +59,9 @@ static char encoderfn_scr(char byte)
return byte; return byte;
} }
// convert raw to whatever is defined in table // 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) // 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); return encoder_current->fn(byte);
} }
@ -109,7 +109,7 @@ void encoding_passinit(void)
} }
// try to load encoding table from given file // 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) if (fread(target, sizeof(char), 256, stream) != 256)
Throw_error("Conversion table incomplete."); Throw_error("Conversion table incomplete.");

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code. // 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 // Have a look at "acme.c" for further info
// //
// Character encoding stuff // Character encoding stuff
@ -16,17 +16,17 @@ extern const struct encoder encoder_raw;
extern const struct encoder encoder_pet; extern const struct encoder encoder_pet;
extern const struct encoder encoder_scr; extern const struct encoder encoder_scr;
extern const struct encoder encoder_file; extern const struct encoder encoder_file;
extern char *encoding_loaded_table; // ...loaded from file extern unsigned char *encoding_loaded_table; // ...loaded from file
// prototypes // prototypes
// convert character using current encoding // 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 // set "raw" as default encoding
extern void encoding_passinit(void); extern void encoding_passinit(void);
// try to load encoding table from given file // 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) // lookup encoder held in DynaBuf and return its struct pointer (or NULL on failure)
extern const struct encoder *encoding_find(void); extern const struct encoder *encoding_find(void);

View File

@ -67,8 +67,8 @@ enum version {
VER_DISABLED_OBSOLETE_STUFF, // v0.94.8 made *= work inside !pseudopc, disabled !cbm/!realpc/!subzone 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 VER_NEWFORSYNTAX, // v0.94.12 introduced the new "!for" syntax
// v0.95.2 changed ANC#8 from 0x2b to 0x0b // v0.95.2 changed ANC#8 from 0x2b to 0x0b
VER_BACKSLASHESCAPING, // v0.97 introduced backslash escaping (and therefore strings)
VER_CURRENT, // "RELEASE" VER_CURRENT, // "RELEASE"
VER_BACKSLASHESCAPING, // v0.97 added backslash escaping (and therefore strings)
// possible changes in future versions: // possible changes in future versions:
// paths should be relative to file, not start dir // paths should be relative to file, not start dir
// ignore leading zeroes? // ignore leading zeroes?
@ -172,7 +172,7 @@ extern void Bug_found(const char *msg, int code);
struct iter_context { struct iter_context {
void (*fn)(intval_t); // output function void (*fn)(intval_t); // output function
boolean accept_long_strings; // if FALSE, only 1-char-strings work boolean accept_long_strings; // if FALSE, only 1-char-strings work
char stringxor; // for !scrxor, 0 otherwise unsigned char stringxor; // for !scrxor, 0 otherwise
}; };
extern void output_object(struct object *object, struct iter_context *iter); extern void output_object(struct object *object, struct iter_context *iter);
// output 8-bit value with range check // output 8-bit value with range check

View File

@ -319,7 +319,7 @@ static enum eos po_cbm(void)
// read encoding table from file // read encoding table from file
static enum eos user_defined_encoding(FILE *stream) static enum eos user_defined_encoding(FILE *stream)
{ {
char local_table[256], unsigned char local_table[256],
*buffered_table = encoding_loaded_table; *buffered_table = encoding_loaded_table;
const struct encoder *buffered_encoder = encoder_current; 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) // use one of the pre-defined encodings (raw, pet, scr)
static enum eos predefined_encoding(void) static enum eos predefined_encoding(void)
{ {
char local_table[256], unsigned char local_table[256],
*buffered_table = encoding_loaded_table; *buffered_table = encoding_loaded_table;
const struct encoder *buffered_encoder = encoder_current; const struct encoder *buffered_encoder = encoder_current;
@ -382,7 +382,7 @@ static enum eos po_convtab(void)
} }
} }
// insert string(s) // 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 const struct encoder *outer_encoder = encoder_current; // buffer encoder
struct iter_context iter; struct iter_context iter;

View File

@ -7,9 +7,9 @@
#define version_H #define version_H
#define RELEASE "0.96.5" // update before release FIXME #define RELEASE "0.97" // update before release FIXME
#define CODENAME "Fenchurch" // update before release #define CODENAME "Zem" // update before release
#define CHANGE_DATE "26 June" // update before release FIXME #define CHANGE_DATE "28 June" // update before release FIXME
#define CHANGE_YEAR "2020" // update before release #define CHANGE_YEAR "2020" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME