

                                 ACME

         ...the ACME Crossassembler for Multiple Environments

                        --- error messages ---


Here's a sorted list of all error messages ACME can give, possible
reasons and what you can do to sort it out.


----------------------------------------------------------------------
Section:   Errors on startup
----------------------------------------------------------------------

Cannot open toplevel file "FILENAME".
    Maybe you mistyped its name?

Error in CLI arguments: ...
    There are several of these errors, but they should be quite self-
    explanatory.


----------------------------------------------------------------------
Section:   Warnings during assembly
----------------------------------------------------------------------

!warn: ...
    This is given when the pseudo opcode "!warn" is executed. The
    actual message varies according to the pseudo opcode's arguments.

Assembling buggy JMP($xxff) instruction
    The original 6502 processor has a bug: When executing an indirect
    JMP instruction where the low byte of the argument equals $ff, it
    fetches the high byte of the jump target address not from memory
    location ARGUMENT + 1, but from ARGUMENT - 255. Therefore ACME
    issues this warning if you are about to generate such an
    instruction.
    Note that this warning is only given for some CPU types (6502,
    nmos6502/6510, c64dtv2) because later ones like 65c02 and 65816
    have been fixed in this regard.

Assembling unstable ANE #NONZERO instruction
Assembling unstable LXA #NONZERO instruction
    These warnings are only ever given for CPU type nmos6502 (6510).
    ANE and LXA are undocumented ("illegal") opcodes of this CPU, and
    they only work reliably if the argument is zero or the accumulator
    contains 0xff.
    Therefore ACME issues these warnings if it is about to generate
    these instructions with a non-zero argument.

Binary literal with strange number of digits.
    This warning is given if the number of digits in a binary literal
    is not a multiple of four. This is useful when you meant to write
    %#....... but actually wrote %#........ by mistake. See? :P
    You can disable this warning using the CLI switch "-Wno-bin-len".

Bug in ACME, code follows
    A situation has been encountered implying there is a bug in ACME.
    See the last section in this file.

Converted to integer for binary logic operator.
    Applying binary logic to float values does not make much sense,
    therefore floats will be converted to integer in such cases.

"EOR" is deprecated; use "XOR" instead.
    This means the operator, not the mnemonic.

Found old "!for" syntax.
    Please update your sources to use the new "!for" syntax. See
    AllPOs.txt for details.
    You can suppress this warning using the "--dialect" or the
    "-Wno-old-for" CLI switch.
    ("-Wno-old-for" does _exactly_ the same as "--dialect 0.94.8")

Found new "!for" syntax.
    When using the "-Wno-old-for" switch to disable the warning about
    the older syntax, the new syntax will trigger this warning.

Found SED instruction for CPU with known decimal SBC bug.
    This warning is only ever given for CPU types 65ce02 and 4502,
    because they are known to be buggy in decimal mode.
    Pavel Zima and Eric Smith found an example where $41 minus $08
    gave $39 instead of $33.

Label name not in leftmost column.
    A label definition has blanks before the label name.
    Imagine this source code:
		lda #00
		imx
		rts
    Obviously, there's a typo in the middle line (imx instead of inx),
    but ACME does not recognize this: It looks just like a label
    definition! Therefore releases 0.89 and higher warn you when a
    label name does not start in column 1. Releases 0.94 and higher
    support a command line option to switch off this warning
    ("-Wno-label-indent").

Memory already initialised.
    The "!initmem" pseudo opcode was given more than once, or in
    addition to the "--initmem" command line option. Only use it once.

Output file name already chosen.
    The "!to" pseudo opcode was given more than once, or in addition
    to the "--outfile" command line option. Only use it once.

Output file format already chosen.
    The "!to" pseudo opcode specified a file format, but a format had
    already been chosen using the "--format" command line option.

Segment reached another one, overwriting it.
    The program counter has just reached the start of another segment.
    Because some people might want to assemble "onto" a binary file
    that was loaded before, this warning can be inhibited using
    modifier keywords when changing the program counter via "*=".
    For extra safety you can also turn this warning into an error
    using the "--strict-segments" CLI switch. In future versions of
    ACME this might become the default.

Segment starts inside another one, overwriting it.
    The given value in a "*=" assignment is located inside another
    segment. Because some people might want to assemble "onto" a
    binary file that was loaded before, this warning can be inhibited
    using modifier keywords when changing the program counter via
    "*=".
    For extra safety you can also turn this warning into an error
    using the "--strict-segments" CLI switch. In future versions of
    ACME this might become the default.

Symbol list file name already chosen.
    The "!sl" pseudo opcode was given more than once, or in addition
    to the "--symbollist" command line option. Only use it once.

Symbol name starts with a shift-space character.
    The name of a global symbol starts with a shift-space character.
    It is highly likely that this is a typing error, therefore this
    warning is issued.

Used "!to" without file format indicator.
    Please specify the file format as a second argument to the "!to"
    pseudo opcode. If not given, cbm format is used.
    The file format can be overridden by the "--format" cli switch.

Using oversized addressing mode.
    ACME just assembled an instruction using an addressing mode that
    was larger than needed. This only happens if ACME could not work
    out the argument's value in the first pass, therefore assuming a
    16-bit addressing mode. If, in a later pass, ACME finds out that
    the argument is small enough to fit in 8 bits, then this warning
    is shown. If you define all your zeropage symbols *before* they
    are first used, this shouldn't happen. If you know that a specific
    argument fits in 8 bits, you can force ACME to use 8 bits
    addressing by postfixing the mnemonic with "+1". Example:
		lda+1 label
    ACME will then use an 8-bit addressing mode, regardless of whether
    the label is known or not. If the label value happens to be too
    large to fit in 8 bits, ACME will show an error of course (to
    always truncate a value to 8 bits, use the '<' operator).
    More about the postfixing method can be found in "AddrModes.txt".

Wrong type - expected address.
Wrong type - expected integer.
Wrong type for loop's END value - must match type of START value.
    These warnings are only given when type checking has been enabled
    using the "-Wtype-mismatch" switch. Make sure the argument type
    matches the instruction's addressing mode.
    In "!for" loops, START and END must have the same type, which then
    gets used for the loop counter.

Zeropage pointer wraps around from $ff to $00
    A zeropage-indirect addressing mode uses $ff as the argument. The
    6502 will then fetch the second pointer byte from $00 instead of
    $0100, therefore this warning is issued.

...called from here.
    If warnings and/or errors are output during a macro call, messages
    with this text are added to display the call stack (because you
    might need to fix the call instead of the macro itself).


----------------------------------------------------------------------
Section:   Errors during assembly
----------------------------------------------------------------------

"!cbm" is obsolete; use "!ct pet" instead.
    This is given when the now obsolete "!cbm" pseudo opcode is
    encountered.
    If you want to assemble an old source code without first updating
    it, you can use the "--dialect" CLI switch to make ACME mimic an
    older version.

"!pseudopc/!realpc" are obsolete; use "!pseudopc {}" instead.
    This is given when one of the now obsolete !pseudopc/!realpc
    pseudo opcodes is encountered.
    If you want to assemble an old source code without first updating
    it, you can use the "--dialect" CLI switch to make ACME mimic an
    older version.

"!subzone {}" is obsolete; use "!zone {}" instead.
    This is given when the now obsolete "!subzone" pseudo opcode is
    encountered.
    If you want to assemble an old source code without first updating
    it, you can use the "--dialect" CLI switch to make ACME mimic an
    older version.

!error: ...
    This is given when the pseudo opcode "!error" is executed. The
    actual message varies according to the pseudo opcode's arguments.

Argument out of range.
    You called arcsin/arccos with something not in the [-1, 1] range.

Binary literal without any digits.
Hex literal without any digits.
    There were no digits after a number prefix like "0x" or "%".

Cannot open input file.
    ACME had problems opening an input file ("!bin", "!convtab" or
    "!src"). Maybe you mistyped its name.

Conversion table incomplete.
    The conversion table file is too small. It needs to be exactly 256
    bytes in size.

CPU does not support this addressing mode for this mnemonic.
    The given mnemonic cannot be combined with the given addressing
    mode on the CPU you have chosen.

CPU does not support this postfix for this mnemonic.
    The given mnemonic cannot be combined with the addressing mode
    indicated by the given postfix, at least not on the CPU you have
    chosen.

Division by zero.
    Guess what - you attempted to divide by zero.

Expected '{' or IF/IFDEF/IFNDEF keyword after ELSE keyword.
    There is something strange after ELSE: It must be "if", "ifdef",
    "ifndef" or an opening brace.

Expected ',' or IN keyword after loop variable.
    You made a syntax error when using "!for": After the loop variable
    there can either be a comma (for a simple counting loop) or the
    "in" keyword (when iterating over string or list contents).
    Anything else will give this error.

Expected end-of-statement after ELSE block.
    There is something after the closing brace of an ELSE block.

Expected end-of-statement or ELSE keyword after '}'.
    There is something after the closing brace of an IF block that is
    not an ELSE.

Expected end-of-statement, found 'CHAR' instead.
    There are still arguments when there should not be any more. The
    given character is the one where end-of-line was expected.

Expected EOF, found '}' instead.
    ACME encountered a '}' character when it expected the file to end
    instead (because no blocks were open).

Expected WHILE or UNTIL keyword, or an empty loop condition.
    When using "!do", loop conditions are optional before and after
    the block, but if one is given, it has to start with "while" or
    "until".

Expected index register after comma.
    You used an addressing mode with a comma but did not supply a
    valid index register (like 'x') after it.

Expected two hex digits after \x backslash sequence.
    In string literals, the backslash sequence "\x" must be followed
    by two hex digits. If the string ends before two hex digits have
    been found, this error is generated.

Exponent is negative.
    Using negative exponents only give sensible results when using
    floating point maths.

Expression did not return a number.
    An expression returned a string or a list but a number (integer or
    float) was expected.

Expression did not return a string.
    An expression returned a list or a number but a string was
    expected (for example a file name).

Quotes not found.
    In older versions, file names could not be specified via symbols,
    but had to be given as string literals in quotes:
    Either as "path/to/file" for lookups in the current directory or
    as <path/to/file> for lookups in the library.
    So if the first character is neither '<' nor '"' this error was
    generated.

Force bits can only be given to counters, not when iterating over string/list contents.
    You used a force bit with a "!for" loop counter, but then used the
    "iterate over string/list contents" syntax. This does not work,
    because lists could contain other lists, and then a force bit does
    not make any sense.

Force bits can only be given to numbers.
    You tried to give a force bit to a symbol and then assign a string
    or list to it.

Given object is not iterable.
    You used "!for VAR in ITERABLE", but the iterable was neither a
    string nor a list (likely a number).

Hex digits are not given in pairs.
    The two digits of a hex byte are separated by another character,
    or there is an odd number of digits.

Illegal postfix.
    You used a postfix other than "+1", "+2" or "+3".

Index is undefined.
    You attempted an indexing operation with some undefined symbol.

Index out of range.
    The value for an indexing operation wasn't in the allowed range.

Invalid hex digit after \x, expected 0-9/a-f.
    In string literals, the backslash sequence "\x" must be followed
    by two hex digits. If the next two chars are not [0-9a-fA-F], this
    error will be generated.

Library path not set. Use --libpath or create an environment variable.
    This will be shown if the source code references a file from the
    library but ACME does not know where the library is located.
    If the ACME binary was compiled with a default path, you will not
    see this error.
    See the file "Lib.txt" in this directory for info on how to setup
    the library path.

Macro already defined.
    Macros can only be defined once. If you define a macro twice, ACME
    will give an error for the new definition and then output an info
    message pointing to the initial definition.

Macro not defined (or wrong signature).
    You tried to call a macro that either wasn't defined yet (always
    define macros before using them) or was called with an illegal
    argument list. There must be a 1:1 match between the definition's
    formal parameters and the call's actual arguments.

Macro parameter twice.
    The same symbol name is used two (or more) times in the same macro
    parameter list.

Negative size argument.
    The size argument of "!bin" or "!skip" must be zero or positive,
    but cannot be negative.

Negative value - cannot choose addressing mode.
    Because the argument is a negative value, ACME does not know what
    addressing mode (8 bits, 16 bits, on a 65816 even 24 bits) to use.
    You can overcome this problem using the postfix method. Or correct
    your program to use positive addresses instead.

No string given.
    ACME expects a string but doesn't find it, or the string is empty.
    This can also mean keywords or symbol names.

Number does not fit in N bits.
Number out of range.
    A value is too high or too low to be stored in 8/16/24 bits.
    This can also mean the desired addressing mode is not available,
    as in "sty $e000, x".

Operation not supported: Cannot apply "OP" to "TYPE".
Operation not supported: Cannot apply "OP" to "TYPE" and "TYPE".
    You tried to use an operator on the wrong type(s) of argument(s),
    like indexing a float or negating a string.

Program counter cannot be negative.
    You used "--setpc VALUE", "* = VALUE" or "!pseudopc VALUE" with a
    negative number.

Program counter undefined.
    You tried to generate data before setting the program counter. Use
    either "--setpc VALUE" on the command line or "* = VALUE" at the
    start of your source code file.

Quotes still open at end of line.
    You forgot the closing quotes.

Source file contains illegal character.
    Your source code file contained a null byte.

String length is not 1.
    You tried something like LDA#"X" with an illegal string length.

Symbol already defined.
    You defined a symbol that already had a different type or value.
    To change a symbol's type or value, use the "!set" pseudo opcode.

Syntax error.
    Guess what - there's a syntax error.

Target not in bank (0xTARGET).
    You tried to branch to an address not in the 0x0000..0xffff range.
    Relative addressing (branch instructions or PER) cannot leave the
    current code bank of 64 KiB.

Target out of range (N; M too far).
    Branch instructions use relative addressing, which only has a
    limited range. You exceeded it. N is the attempted offset, M is
    the difference to the limit - so if you succeed in optimizing M
    bytes away, the code would assemble.

The chosen CPU uses opcode 0xXY as a prefix code, do not use this mnemonic!
    The mnemonic is valid, but should not be used on this CPU. If you
    know better, you can get around this error like this:
	!cpu ANY_OTHER_CPU { PROBLEMATIC_MNEMONIC }

There's more than one character.
    You used a text string containing more than one character in a
    situation where only a string with length one is allowed.

Too late for postfix.
    You can only postfix symbols at the start, before they are used
    for the first time.

Too many '('.
    A formula ends before all parentheses were closed.

Un-pseudopc operator '&' can only be applied to number symbols.
    You tried to use the operator '&' on a list or a string. This
    operator only works on labels and on '*' (the program counter), it
    cannot be used on other objects.

Un-pseudopc operator '&' only works on addresses.
    You tried to apply the operator '&' to something that is neither
    the program counter nor an implicitly defined label nor something
    derived from those. Example:
	argument = * + 1
label		lda #$ff
	dummy = 500
    You can use '&' on "label" and on "argument", but not on "dummy".

Un-pseudopc operator '&' has no !pseudopc context.
    You tried to apply the operator '&' to an address symbol that was
    defined outside of a !pseudopc block, or, more generally, the
    number of '&' characters used was larger than the number of
    !pseudopc blocks around the definition.

Unknown encoding.
    You used the "!convtab" pseudo opcode with a keyword ACME does not
    know.

Unknown function.
    You used a mathematical function ACME does not know.

Unknown mnemonic.
    You mistyped a mnemonic, or you forgot to select the correct cpu.

Unknown operator.
    You used an arithmetic/logical operator ACME does not know.

Unknown output format.
    You used the "!to" pseudo opcode with a format specifier ACME does
    not know.

Unknown processor.
    You used the "!cpu" pseudo opcode with a cpu specifier ACME does
    not know.

Unknown pseudo opcode.
    You have mistyped the keyword after "!".

Unknown "*=" segment modifier.
    You used a modifier keyword ACME does not know.

Unsupported backslash sequence.
    The character following the backslash was not one of the allowed
    ones. Backslash escaping was added in release 0.97 of ACME.
    If you want to assemble an old source code without first updating
    it, you can use the "--dialect" CLI switch to make ACME mimic an
    older version.

Unterminated index spec.
    An index was started with '[' but did not end with ']'.

Unterminated list.
    A list was started with '[' but did not end with ']'.

Value not defined (SYMBOL NAME).
    A value could not be worked out. Maybe you mistyped a symbol name.
    Whether this is given as a "normal" or as a serious error depends
    on the currently parsed pseudo opcode.


----------------------------------------------------------------------
Section:   Serious errors (stopping assembly)
----------------------------------------------------------------------

!serious: ...
    This is given when the pseudo opcode "!serious" is executed. The
    actual message varies according to the pseudo opcode's arguments.

Expected '{' character.
    ACME didn't find the expected '{' character. Remember that '{'
    characters must be given on the same line as the keyword they
    belong to.

Expected '}', found EOF instead.
    The file ended when ACME expected the block to be closed instead
    (because there was at least one block left open).

Loop count is negative.
    You used the "!for" pseudo opcode with a negative loop count
    (getting this error is only possible when using the now deprecated
    syntax).

Out of memory.
    When ACME runs out of memory, it stops assembly, giving this
    error. Free some memory and try again. It's highly unlikely anyone
    will ever see this error, though. ;)

Reached memory limit.
    This error is reported if the write index for the output buffer
    exceeds 16 megabytes. This is an arbitrary limit - if you have a
    good reason for having it raised further, tell me. :D

Syntax error.
    This is only given as a _serious_ error if it's in a "!do" loop
    condition.

Too deeply nested. Recursive macro calls?
    The only reason for ACME to have a limit on macro call nesting
    at all is to find infinite recursions.
    The default limit is 64, this can be changed using the
    "--maxdepth" CLI switch.

Too deeply nested. Recursive "!source"?
    The only reason for ACME to still have a limit on "!source"
    nesting at all is to find infinite recursions.
    The default limit is 64, this can be changed using the
    "--maxdepth" CLI switch.

Tried to write to negative address.
    This means that a new segment inside a !pseudopc block would be
    placed before the start of the output buffer. Example:
	* = $1000		; ok (we begin at $1000)
	!pseudopc $8000 {	; ok (we pretend to be at $8000)
		* = $5000	; error (we need to go back by $3000,
	}			; which would mean going to -$2000!)

Unexpected char when evaluating loop condition.
    There was a syntax error while evaluating the loop condition.

Value not defined.
    A value could not be worked out. Maybe you mistyped a symbol name.
    Whether this is given as a "normal" or as a serious error depends
    on the currently parsed pseudo opcode.


----------------------------------------------------------------------
Section:   Errors on closedown
----------------------------------------------------------------------

Cannot open symbol list file "FILENAME".
Cannot open output file "FILENAME".
    Make sure the name doesn't contain wildcard characters and you
    have write access to the directory.

No output file specified (use the "-o" option or the "!to" pseudo opcode).
    You didn't specify the output file, so ACME did not create one.


----------------------------------------------------------------------
Section:   Bugs in ACME
----------------------------------------------------------------------

The warning "Bug in ACME, code follows" is always followed by a
serious error message, stopping assembly. The second message actually
gives a hint about the bug's location in the source code.
If you ever get this combination of warning and serious error, please
send me an e-mail and tell me about it. If possible, include a piece
of source code that triggers it.
Please don't get this wrong - there are no known bugs. I just left
some debugging code in place in case there is a bug I failed to notice
during testing. In practice, this warning is not expected to be given
at all. That's the reason why I want to be notified if it *does*
decide to show up.

The hint messages are of no real interest to the end user, but here
they are for completeness' sake:


ArgStackEmpty
    There was no data for a monadic operator to work on.

ArgStackNotEmpty
    The expression parser has finished though there are still
    arguments left to process.

ExtendingListWithItself
    There were multiple references to the same list.

ForceBitZero
    The function to handle force bits was called without a force bit.

IllegalBlockTerminator
    A RAM block (macro or loop) was terminated incorrectly.

IllegalGroupIndex
    The mnemonic tree contains a group that I didn't add.

IllegalIfMode
    A sanity check in the if/ifdef/ifndef/else code failed.

IllegalImmediateMode
    The mnemonic tree contains invalid info about the size of immediate
    arguments.

IllegalInputSource
    Input is taken neither from a file nor from a RAM block.

IllegalLoopAlgo
    The "!for" function was told to use an unknown algorithm.

IllegalNumberTypeX
    A number was neither INT nor FLOAT nor UNDEFINED.

IllegalObjectType
    A symbol is used that is neither number nor list nor string.

IllegalOperatorId
IllegalOperatorGroup
    The expression parser found an operator that does not exist.

IllegalOutformat1
IllegalOutformat2
    The output file format enum has an unexpected value.

IllegalSymbolNameLength
    A sanity check on string lengths failed.

NotEnoughArgs
    There was not enough data for a dyadic operator to work on.

NullTypeObject
ObjectHasNullType
    A symbol is used that does not have a type (number/list/string)
    associated with it.

OperatorIsNotDyadic
OperatorIsNotMonadic
    A function was passed the wrong type of operator.

OperatorStackNotEmpty
    The expression parser has finished though there are still
    operators left to process.

PartialEscapeSequence
    Buffered data ended on a backslash, which shouldn't be possible.

PseudoPCContext
    A pointer became NULL which shouldn't happen.

SecondArgIsNotAnInt
    A sanity check failed: An argument should have been converted to
    integer but wasn't.

StrangeEscapeState1
StrangeEscapeState2
    The state machine for backslash escaping reached a non-existing state.

StrangeInputMode
    The input state machine has reached a state that does not exist.

StrangeOperator
    The expression parser found a non-existing operator.

TriedToIndexNumber
    The "index" operator was applied to a number type.
