mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-12-24 16:29:23 +00:00
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:
parent
ca6b6d8771
commit
d2683cc64d
45
ACME_Lib/6502/split.a
Normal file
45
ACME_Lib/6502/split.a
Normal 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
|
@ -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.
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
@ -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
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
@ -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. :)
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.");
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user