Merge branch 'master' into Opt-ldptr1
This commit is contained in:
3
.github/checks/sorted.sh
vendored
3
.github/checks/sorted.sh
vendored
@@ -33,7 +33,8 @@ function checkarray_quoted_name
|
||||
}
|
||||
|
||||
|
||||
find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do
|
||||
FILES=$(find "$CHECK_DIR" -name \*.\[ch\] -print)
|
||||
for N in $FILES; do
|
||||
grep -q "BEGIN SORTED.SH" "$N" && checkarray_quoted_name "$N"
|
||||
done
|
||||
exit 0
|
||||
|
||||
3
.github/checks/sorted_codeopt.sh
vendored
3
.github/checks/sorted_codeopt.sh
vendored
@@ -63,7 +63,8 @@ function checkarray
|
||||
}
|
||||
|
||||
|
||||
find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do
|
||||
FILES=$(find "$CHECK_DIR" -name \*.\[ch\] -print)
|
||||
for N in $FILES; do
|
||||
grep -q "BEGIN DECL SORTED_CODEOPT.SH" "$N" && checkarray "$N"
|
||||
done
|
||||
exit 0
|
||||
|
||||
3
.github/checks/sorted_opcodes.sh
vendored
3
.github/checks/sorted_opcodes.sh
vendored
@@ -34,7 +34,8 @@ function checkarray_quoted_name
|
||||
rm -rf .a.tmp
|
||||
}
|
||||
|
||||
find "$CHECK_DIR" -name \*.\[ch\] -print | while read N; do
|
||||
FILES=$(find "$CHECK_DIR" -name \*.\[ch\] -print)
|
||||
for N in $FILES; do
|
||||
grep -q "BEGIN SORTED_OPCODES.SH" "$N" && checkarray_quoted_name "$N"
|
||||
done
|
||||
exit 0
|
||||
|
||||
@@ -39,7 +39,7 @@ MEMORY {
|
||||
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
EXTZP: load = ZP, type = zp;
|
||||
EXTZP: load = ZP, type = zp, optional = yes;
|
||||
EXEHDR: load = HEADER, type = ro, optional = yes;
|
||||
STARTUP: load = ROMS, type = ro, define = yes;
|
||||
ONCE: load = ROMS, type = ro, define = yes;
|
||||
|
||||
@@ -23,7 +23,7 @@ FEATURES {
|
||||
CONDES: type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__,
|
||||
segment = INIT;
|
||||
segment = ONCE;
|
||||
CONDES: type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__,
|
||||
|
||||
@@ -208,6 +208,16 @@ Here is a description of all the command line options:
|
||||
mortals:-)
|
||||
|
||||
|
||||
<label id="option-D">
|
||||
<tag><tt>-D</tt></tag>
|
||||
|
||||
This option allows you to define symbols on the command line. Without a
|
||||
value, the symbol is defined with the value zero. When giving a value,
|
||||
you may use the '$' prefix for hexadecimal symbols. Please note
|
||||
that for some operating systems, '$' has a special meaning, so
|
||||
you may have to quote the expression.
|
||||
|
||||
|
||||
<label id="option--feature">
|
||||
<tag><tt>--feature name</tt></tag>
|
||||
|
||||
@@ -237,6 +247,16 @@ Here is a description of all the command line options:
|
||||
Print the short option summary shown above.
|
||||
|
||||
|
||||
<label id="option-I">
|
||||
<tag><tt>-I dir, --include-dir dir</tt></tag>
|
||||
|
||||
Name a directory which is searched for include files. The option may be
|
||||
used more than once to specify more than one directory to search. The
|
||||
current directory is always searched first before considering any
|
||||
additional directories. See also the section about <ref id="search-paths"
|
||||
name="search paths">.
|
||||
|
||||
|
||||
<label id="option-i">
|
||||
<tag><tt>-i, --ignore-case</tt></tag>
|
||||
|
||||
@@ -316,6 +336,12 @@ Here is a description of all the command line options:
|
||||
</itemize>
|
||||
|
||||
|
||||
<label id="option-S">
|
||||
<tag><tt>-S, --segment-list</tt></tag>
|
||||
|
||||
Add the segment ID in front of each address in the listing file.
|
||||
|
||||
|
||||
<label id="option-s">
|
||||
<tag><tt>-s, --smart-mode</tt></tag>
|
||||
|
||||
@@ -345,34 +371,6 @@ Here is a description of all the command line options:
|
||||
overridden by using the <tt/<ref id="option--cpu" name="--cpu">/ option.
|
||||
|
||||
|
||||
<label id="option-v">
|
||||
<tag><tt>-v, --verbose</tt></tag>
|
||||
|
||||
Increase the assembler verbosity. Usually only needed for debugging
|
||||
purposes. You may use this option more than one time for even more
|
||||
verbose output.
|
||||
|
||||
|
||||
<label id="option-D">
|
||||
<tag><tt>-D</tt></tag>
|
||||
|
||||
This option allows you to define symbols on the command line. Without a
|
||||
value, the symbol is defined with the value zero. When giving a value,
|
||||
you may use the '$' prefix for hexadecimal symbols. Please note
|
||||
that for some operating systems, '$' has a special meaning, so
|
||||
you may have to quote the expression.
|
||||
|
||||
|
||||
<label id="option-I">
|
||||
<tag><tt>-I dir, --include-dir dir</tt></tag>
|
||||
|
||||
Name a directory which is searched for include files. The option may be
|
||||
used more than once to specify more than one directory to search. The
|
||||
current directory is always searched first before considering any
|
||||
additional directories. See also the section about <ref id="search-paths"
|
||||
name="search paths">.
|
||||
|
||||
|
||||
<label id="option-U">
|
||||
<tag><tt>-U, --auto-import</tt></tag>
|
||||
|
||||
@@ -385,6 +383,14 @@ Here is a description of all the command line options:
|
||||
which is not always true for assembler programmers.
|
||||
|
||||
|
||||
<label id="option-v">
|
||||
<tag><tt>-v, --verbose</tt></tag>
|
||||
|
||||
Increase the assembler verbosity. Usually only needed for debugging
|
||||
purposes. You may use this option more than one time for even more
|
||||
verbose output.
|
||||
|
||||
|
||||
<label id="option-V">
|
||||
<tag><tt>-V, --version</tt></tag>
|
||||
|
||||
@@ -407,6 +413,12 @@ Here is a description of all the command line options:
|
||||
An error will be generated if any warnings were produced.
|
||||
|
||||
|
||||
<label id="option-x">
|
||||
<tag><tt>-x, --expand-macros</tt></tag>
|
||||
|
||||
In the listing file, show exactly how macros were expanded. Use twice for
|
||||
more verbose output.
|
||||
|
||||
</descrip>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ Long options:
|
||||
--target sys Set the target system
|
||||
--verbose Increase verbosity
|
||||
--version Print the compiler version number
|
||||
--warnings-as-errors Treat warnings as errors
|
||||
--writable-strings Make string literals writable
|
||||
---------------------------------------------------------------------------
|
||||
</verb></tscreen>
|
||||
@@ -514,6 +515,28 @@ Here is a description of all the command line options:
|
||||
name="#pragma local-strings"></tt> for fine grained control.
|
||||
|
||||
|
||||
<tag><tt>-mm model, --memory-model model</tt></tag>
|
||||
|
||||
This option sets the code and data models for the compiler to use. Please
|
||||
note that memory models are an unfinished feature and using this option
|
||||
with any other memory model than <tt/near/ will cause compile errors.
|
||||
Possible arguments are:
|
||||
|
||||
<descrip>
|
||||
<tag/near/
|
||||
This memory model uses 16 bit addresses for code and data. It is
|
||||
currently the only supported memory model and suited for the 6502.
|
||||
|
||||
<tag/far/
|
||||
This memory model uses 24 bit addresses for code and 16 bit addresses
|
||||
for data. It is suited for the 65816 but currently unsupported.
|
||||
|
||||
<tag/huge/
|
||||
This memory model uses 24 bit addresses for code and data. It is
|
||||
suited for the 65816 but currently unsupported.
|
||||
</descrip>
|
||||
|
||||
|
||||
<tag><tt>-o name</tt></tag>
|
||||
|
||||
Specify the name of the output file. If you don't specify a name, the
|
||||
@@ -656,6 +679,15 @@ Here is a description of all the command line options:
|
||||
or warnings are encountered.
|
||||
|
||||
|
||||
<label id="option--warnings-as-errors">
|
||||
<tag><tt>--warnings-as-errors</tt></tag>
|
||||
|
||||
Treat all warnings as error. This makes the compiler exit with an appropriate
|
||||
error code in case of warnings. The effect of this switch is identical to
|
||||
the command line option <tt/<ref id="option-W" name="-W error">/. It is
|
||||
available for compatibility with the other tools.
|
||||
|
||||
|
||||
<label id="option-writable-strings">
|
||||
<tag><tt>--writable-strings</tt></tag>
|
||||
|
||||
@@ -766,7 +798,9 @@ Here is a description of all the command line options:
|
||||
<tag><tt/const-comparison/</tag>
|
||||
Warn if the result of a comparison is constant.
|
||||
<tag><tt/error/</tag>
|
||||
Treat all warnings as errors.
|
||||
Treat all warnings as errors. This has the same effect as using the
|
||||
<tt/<ref id="option--warnings-as-errors" name="--warnings-as-errors">/
|
||||
option.
|
||||
<tag><tt/no-effect/</tag>
|
||||
Warn about statements that don't have an effect.
|
||||
<tag><tt/pointer-sign/</tag>
|
||||
|
||||
@@ -34,7 +34,7 @@ and other things.
|
||||
---------------------------------------------------------------------------
|
||||
Usage: cl65 [options] file [...]
|
||||
Short options:
|
||||
-c Compile and assemble but don't link
|
||||
-c Compile and assemble, but don't link
|
||||
-d Debug mode
|
||||
-g Add debug info
|
||||
-h Help (this text)
|
||||
@@ -55,10 +55,10 @@ Short options:
|
||||
-L path Specify a library search path
|
||||
-Ln name Create a VICE label file
|
||||
-O Optimize code
|
||||
-Oi Optimize code, inline more code
|
||||
-Oi Optimize code, inline runtime functions
|
||||
-Or Optimize code, honour the register keyword
|
||||
-Os Optimize code, inline standard functions
|
||||
-S Compile but don't assemble and link
|
||||
-Os Optimize code, inline known C functions
|
||||
-S Compile, but don't assemble and link
|
||||
-T Include source as comment
|
||||
-V Print the version number
|
||||
-W name[,...] Suppress compiler warnings
|
||||
@@ -81,8 +81,9 @@ Long options:
|
||||
--code-label name Define and export a CODE segment label
|
||||
--code-name seg Set the name of the CODE segment
|
||||
--codesize x Accept larger code by factor x
|
||||
--color [on|auto|off] Color diagnostics (default: auto)
|
||||
--config name Use linker config file
|
||||
--cpu type Set cpu type
|
||||
--cpu type Set CPU type
|
||||
--create-dep name Create a make dependency file
|
||||
--create-full-dep name Create a full make dependency file
|
||||
--data-label name Define and export a DATA segment label
|
||||
@@ -101,8 +102,9 @@ Long options:
|
||||
--mapfile name Create a map file
|
||||
--memory-model model Set the memory model
|
||||
--module Link as a module
|
||||
--module-id id Specify a module id for the linker
|
||||
--module-id id Specify a module ID for the linker
|
||||
--no-target-lib Don't link the target library
|
||||
--no-utf8 Disable use of UTF-8 in diagnostics
|
||||
--o65-model model Override the o65 model
|
||||
--obj file Link this object file
|
||||
--obj-path path Specify an object file search path
|
||||
|
||||
@@ -369,9 +369,14 @@ function.
|
||||
|
||||
<sect1><tt/dbg.h/<label id="dbg.h"><p>
|
||||
|
||||
<!-- <itemize> -->
|
||||
<!-- <item><ref id="DbgInit" name="DbgInit"> -->
|
||||
<!-- </itemize> -->
|
||||
<itemize>
|
||||
<item><ref id="DbgInit" name="DbgInit">
|
||||
<!-- <item><ref id="BREAK" name="BREAK"> -->
|
||||
<!-- <item><ref id="DbgDisAsm" name="DbgDisAsm"> -->
|
||||
<!-- <item><ref id="DbgDisAsmLen" name="DbgDisAsmLen"> -->
|
||||
<!-- <item><ref id="DbgIsRAM" name="DbgIsRAM"> -->
|
||||
<!-- <item><ref id="DbgMemDump" name="DbgMemDump"> -->
|
||||
</itemize>
|
||||
|
||||
(incomplete)
|
||||
|
||||
@@ -3472,6 +3477,24 @@ used in presence of a prototype.
|
||||
</quote>
|
||||
|
||||
|
||||
<sect1>DbgInit<label id="DbgInit"><p>
|
||||
|
||||
<quote>
|
||||
<descrip>
|
||||
<tag/Function/Initialize the debugger.
|
||||
<tag/Header/<tt/<ref id="dbg.h" name="dbg.h">/
|
||||
<tag/Declaration/<tt/void __fastcall__ DbgInit (unsigned unused);/
|
||||
<tag/Description/<tt/DbgInit/ initializes the debugger.
|
||||
<tag/Notes/<itemize>
|
||||
<item>Use 0 as parameter.
|
||||
<item>The debugger will popup on next brk encountered.
|
||||
</itemize>
|
||||
<tag/Availability/cc65
|
||||
<tag/Example/None.
|
||||
</descrip>
|
||||
</quote>
|
||||
|
||||
|
||||
<sect1>decompress_lz4<label id="decompress_lz4"><p>
|
||||
|
||||
<quote>
|
||||
|
||||
@@ -73,6 +73,7 @@ Short options:
|
||||
Long options:
|
||||
--allow-multiple-definition Allow multiple definitions
|
||||
--cfg-path path Specify a config file search path
|
||||
--color [on|auto|off] Color diagnostics (default: auto)
|
||||
--config name Use linker config file
|
||||
--dbgfile name Generate debug information
|
||||
--define sym=val Define a symbol
|
||||
@@ -84,13 +85,13 @@ Long options:
|
||||
--lib-path path Specify a library search path
|
||||
--mapfile name Create a map file
|
||||
--module-id id Specify a module id
|
||||
--no-utf8 Disable use of UTF-8 in diagnostics
|
||||
--obj file Link this object file
|
||||
--obj-path path Specify an object file search path
|
||||
--start-addr addr Set the default start address
|
||||
--start-group Start a library group
|
||||
--target sys Set the target system
|
||||
--version Print the linker version
|
||||
--warnings-as-errors Treat warnings as errors
|
||||
---------------------------------------------------------------------------
|
||||
</verb></tscreen>
|
||||
|
||||
@@ -292,6 +293,14 @@ Here is a description of all of the command-line options:
|
||||
and in a built-in default directory.
|
||||
|
||||
|
||||
<label id="option--color">
|
||||
<tag><tt>--color</tt></tag>
|
||||
|
||||
This option controls if the linker will use colors when printing
|
||||
diagnostics. The default is "auto" which will enable colors if the output
|
||||
goes to a terminal (not to a file).
|
||||
|
||||
|
||||
<label id="option--dbgfile">
|
||||
<tag><tt>--dbgfile name</tt></tag>
|
||||
|
||||
@@ -315,6 +324,14 @@ Here is a description of all of the command-line options:
|
||||
type because of an unusual extension.
|
||||
|
||||
|
||||
<label id="option--no-utf8">
|
||||
<tag><tt>--no-utf8</tt></tag>
|
||||
|
||||
Disable the use of UTF-8 characters in diagnostics. This might be necessary
|
||||
if auto detection fails or if the output is captured for processing with a
|
||||
tool that is not UTF-8 capable.
|
||||
|
||||
|
||||
<tag><tt>--obj file</tt></tag>
|
||||
|
||||
Links an object file to the output. Use this command-line option instead
|
||||
|
||||
@@ -332,7 +332,7 @@ BreakPoint DbgBreaks [MAX_USERBREAKS+2];
|
||||
BreakPoint* DbgGetBreakSlot (void);
|
||||
/* Search for a free breakpoint slot. Return a pointer to the slot or 0 */
|
||||
|
||||
BreakPoint* DbgIsBreak (unsigned Addr);
|
||||
BreakPoint* __cdecl__ DbgIsBreak (unsigned Addr);
|
||||
/* Check if there is a user breakpoint at the given address, if so, return
|
||||
** a pointer to the slot, else return 0.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
;
|
||||
; Startup code for cc65 (Oric version)
|
||||
;
|
||||
; By Debrune J<EFBFBD>r<EFBFBD>me <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org>
|
||||
; By Debrune Jérôme <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org>
|
||||
;
|
||||
|
||||
.export _exit
|
||||
@@ -36,12 +36,12 @@
|
||||
|
||||
; Call the module destructors. This is also the exit() entry.
|
||||
|
||||
_exit: jsr donelib
|
||||
_exit:
|
||||
|
||||
; Restore the system stuff.
|
||||
; Save return code on stack
|
||||
|
||||
ldx spsave
|
||||
txs
|
||||
pha
|
||||
jsr donelib
|
||||
|
||||
; Copy back the zero-page stuff.
|
||||
|
||||
@@ -51,6 +51,16 @@ L2: lda zpsave,x
|
||||
dex
|
||||
bpl L2
|
||||
|
||||
; Restore the return code.
|
||||
; The return code is on the stack, so we can just pop it.
|
||||
; This is the return code from main().
|
||||
pla
|
||||
|
||||
; Restore the system stuff.
|
||||
|
||||
ldx spsave
|
||||
txs
|
||||
|
||||
; Back to BASIC.
|
||||
|
||||
rts
|
||||
|
||||
@@ -40,11 +40,13 @@ ifdef CC65_HOME
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
GRC = $(CC65_HOME)/bin/grc65
|
||||
else
|
||||
AS := $(if $(wildcard ../bin/ca65*),../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../bin/cc65*),../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../bin/cl65*),../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../bin/ld65*),../bin/ld65,ld65)
|
||||
GRC := $(if $(wildcard ../bin/grc65*),../bin/grc65,grc65)
|
||||
endif
|
||||
|
||||
ifeq ($(SILENT),s)
|
||||
@@ -176,6 +178,7 @@ else
|
||||
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib
|
||||
endif
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Lists of subdirectories
|
||||
|
||||
@@ -193,6 +196,7 @@ EXELIST_agat = \
|
||||
EXELIST_apple2 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
diodemo \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
@@ -212,6 +216,7 @@ EXELIST_apple2enh = $(EXELIST_apple2)
|
||||
EXELIST_atari = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
@@ -250,6 +255,7 @@ EXELIST_bbc = \
|
||||
EXELIST_c64 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
@@ -275,6 +281,7 @@ EXELIST_c65 = \
|
||||
EXELIST_c128 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
@@ -289,6 +296,7 @@ EXELIST_c128 = \
|
||||
EXELIST_c16 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
tinyshell \
|
||||
hello \
|
||||
@@ -297,6 +305,7 @@ EXELIST_c16 = \
|
||||
EXELIST_cbm510 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
@@ -309,6 +318,7 @@ EXELIST_cbm510 = \
|
||||
EXELIST_cbm610 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
@@ -323,6 +333,7 @@ EXELIST_creativision = \
|
||||
EXELIST_cx16 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
@@ -337,10 +348,10 @@ EXELIST_gamate = \
|
||||
hello
|
||||
|
||||
EXELIST_geos-cbm = \
|
||||
ascii
|
||||
ascii.cvt
|
||||
|
||||
EXELIST_geos-apple = \
|
||||
ascii
|
||||
ascii.cvt
|
||||
|
||||
EXELIST_lunix = \
|
||||
notavailable
|
||||
@@ -371,6 +382,7 @@ EXELIST_pce = \
|
||||
EXELIST_pet = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
hello \
|
||||
joydemo \
|
||||
@@ -380,6 +392,7 @@ EXELIST_pet = \
|
||||
EXELIST_plus4 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
@@ -421,6 +434,7 @@ EXELIST_telestrat = \
|
||||
EXELIST_vic20 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
debug \
|
||||
enumdevdir \
|
||||
hello \
|
||||
joydemo \
|
||||
@@ -554,6 +568,25 @@ tgidemo: tgidemo.o
|
||||
$(LD) -D __HIMEM__=0x6000 $(LDFLAGS) -o $@ -C vic20-tgi.cfg -m $@.map $^ $(SYS).lib
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# GEOS programs need a resource file linked to them
|
||||
ifeq ($(SYS),geos-cbm)
|
||||
asciires.o: asciires.grc
|
||||
$(CL) -c -t $(SYS) $<
|
||||
ascii.cvt: ascii.o asciires.o
|
||||
$(if $(QUIET),echo $(SYS):$@)
|
||||
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib
|
||||
endif
|
||||
|
||||
ifeq ($(SYS),geos-apple)
|
||||
asciires.o: asciires.grc
|
||||
$(GRC) -t $(SYS) $<
|
||||
$(AS) $(<:.grc=.s)
|
||||
ascii.cvt: ascii.o asciires.o
|
||||
$(if $(QUIET),echo $(SYS):$@)
|
||||
$(LD) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# some programs link against getsp.o
|
||||
|
||||
|
||||
7
samples/asciires.grc
Normal file
7
samples/asciires.grc
Normal file
@@ -0,0 +1,7 @@
|
||||
; this is the resource file for ascii.c, a GEOS application example
|
||||
|
||||
HEADER APPLICATION "ascii" "ascii" "V0.1" {
|
||||
dostype USR
|
||||
author "cc65 team"
|
||||
info "This is a cc65 sample."
|
||||
}
|
||||
12
samples/debug.c
Normal file
12
samples/debug.c
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <dbg.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* DbgInit has to be called once, to install the BRK handler */
|
||||
DbgInit(0);
|
||||
|
||||
/* now to break into the debugger, use the BREAK macro */
|
||||
BREAK();
|
||||
return 0;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ unsigned WarningCount = 0;
|
||||
typedef enum { DC_NOTE, DC_WARN, DC_ERR, DC_FATAL, DC_COUNT } DiagCat;
|
||||
|
||||
/* Descriptions for diagnostic categories */
|
||||
const char* DiagCatDesc[DC_COUNT] = {
|
||||
static const char* DiagCatDesc[DC_COUNT] = {
|
||||
"Note", "Warning", "Error", "Fatal error"
|
||||
};
|
||||
|
||||
|
||||
@@ -504,14 +504,11 @@ static void OptBinIncludeDir (const char* Opt attribute ((unused)), const char*
|
||||
static void OptColor(const char* Opt, const char* Arg)
|
||||
/* Handle the --color option */
|
||||
{
|
||||
if (strcmp (Arg, "off") == 0 || strcmp (Arg, "false") == 0) {
|
||||
CP_SetColorMode (CM_OFF);
|
||||
} else if (strcmp (Arg, "auto") == 0) {
|
||||
CP_SetColorMode (CM_AUTO);
|
||||
} else if (strcmp (Arg, "on") == 0 || strcmp (Arg, "true") == 0) {
|
||||
CP_SetColorMode (CM_ON);
|
||||
} else {
|
||||
ColorMode Mode = CP_Parse (Arg);
|
||||
if (Mode == CM_INVALID) {
|
||||
AbEnd ("Invalid argument to %s: %s", Opt, Arg);
|
||||
} else {
|
||||
CP_SetColorMode (Mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,6 +742,8 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptSeglist (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Enable segment listing */
|
||||
@@ -752,6 +751,8 @@ static void OptSeglist (const char* Opt attribute ((unused)),
|
||||
SegList = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Generate an error if any warnings occur */
|
||||
@@ -759,6 +760,8 @@ static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||
WarningsAsErrors = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptExpandMacros (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Expand macros in listing
|
||||
@@ -770,6 +773,8 @@ static void OptExpandMacros (const char* Opt attribute ((unused)),
|
||||
ExpandMacros++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoPCAssign (void)
|
||||
/* Start absolute code */
|
||||
{
|
||||
|
||||
@@ -642,7 +642,7 @@ static void DoCharMap (void)
|
||||
|
||||
/* Read the index as numerical value */
|
||||
Index = ConstExpression ();
|
||||
if (IsByteRange (Index)) {
|
||||
if (!IsByteRange (Index)) {
|
||||
/* Value out of range */
|
||||
ErrorSkip ("Index must be in byte range");
|
||||
return;
|
||||
|
||||
@@ -107,14 +107,14 @@ struct OptFunc {
|
||||
static OptFunc DOpt65C02BitOps = { Opt65C02BitOps, "Opt65C02BitOps", 66, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOpt65C02Ind = { Opt65C02Ind, "Opt65C02Ind", 100, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOpt65C02Stores = { Opt65C02Stores, "Opt65C02Stores", 100, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAXLoad = { OptAXLoad, "OptAXLoad", 50, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAXOps = { OptAXOps, "OptAXOps", 50, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd1 = { OptAdd1, "OptAdd1", 125, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd2 = { OptAdd2, "OptAdd2", 200, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd3 = { OptAdd3, "OptAdd3", 65, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd4 = { OptAdd4, "OptAdd4", 90, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd5 = { OptAdd5, "OptAdd5", 100, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAdd6 = { OptAdd6, "OptAdd6", 40, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAXLoad = { OptAXLoad, "OptAXLoad", 50, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptAXOps = { OptAXOps, "OptAXOps", 50, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptBNegA1 = { OptBNegA1, "OptBNegA1", 100, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptBNegA2 = { OptBNegA2, "OptBNegA2", 100, 0, 0, 0, 0, 0 };
|
||||
static OptFunc DOptBNegAX1 = { OptBNegAX1, "OptBNegAX1", 100, 0, 0, 0, 0, 0 };
|
||||
@@ -233,13 +233,14 @@ static OptFunc* OptFuncs[] = {
|
||||
&DOpt65C02BitOps,
|
||||
&DOpt65C02Ind,
|
||||
&DOpt65C02Stores,
|
||||
&DOptAXLoad,
|
||||
&DOptAXOps,
|
||||
&DOptAdd1,
|
||||
&DOptAdd2,
|
||||
&DOptAdd3,
|
||||
&DOptAdd4,
|
||||
&DOptAdd5,
|
||||
&DOptAdd6,
|
||||
&DOptAXOps,
|
||||
&DOptBNegA1,
|
||||
&DOptBNegA2,
|
||||
&DOptBNegAX1,
|
||||
|
||||
@@ -140,6 +140,7 @@ static void Usage (void)
|
||||
" --target sys\t\t\tSet the target system\n"
|
||||
" --verbose\t\t\tIncrease verbosity\n"
|
||||
" --version\t\t\tPrint the compiler version number\n"
|
||||
" --warnings-as-errors\t\tTreat warnings as errors\n"
|
||||
" --writable-strings\t\tMake string literals writable\n",
|
||||
ProgName);
|
||||
}
|
||||
@@ -968,6 +969,15 @@ static void OptWarning (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
|
||||
static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Generate an error if any warnings occur */
|
||||
{
|
||||
IS_Set (&WarningsAreErrors, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptWritableStrings (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Make string literals writable */
|
||||
@@ -1016,6 +1026,7 @@ int main (int argc, char* argv[])
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--verbose", 0, OptVerbose },
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--warnings-as-errors", 0, OptWarningsAsErrors },
|
||||
{ "--writable-strings", 0, OptWritableStrings },
|
||||
};
|
||||
|
||||
@@ -1089,6 +1100,14 @@ int main (int argc, char* argv[])
|
||||
OptSignedChars (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (Arg[2] == 'm') {
|
||||
OptMemoryModel (Arg, GetArg (&I, 3));
|
||||
} else {
|
||||
UnknownOption (Arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
SetOutputName (GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
147
src/cl65/main.c
147
src/cl65/main.c
@@ -70,6 +70,7 @@
|
||||
/* common */
|
||||
#include "attrib.h"
|
||||
#include "cmdline.h"
|
||||
#include "consprop.h"
|
||||
#include "filetype.h"
|
||||
#include "fname.h"
|
||||
#include "mmodel.h"
|
||||
@@ -858,6 +859,7 @@ static void Usage (void)
|
||||
" --code-label name\t\tDefine and export a CODE segment label\n"
|
||||
" --code-name seg\t\tSet the name of the CODE segment\n"
|
||||
" --codesize x\t\t\tAccept larger code by factor x\n"
|
||||
" --color [on|auto|off]\t\tColor diagnostics (default: auto)\n"
|
||||
" --config name\t\t\tUse linker config file\n"
|
||||
" --cpu type\t\t\tSet CPU type\n"
|
||||
" --create-dep name\t\tCreate a make dependency file\n"
|
||||
@@ -880,6 +882,7 @@ static void Usage (void)
|
||||
" --module\t\t\tLink as a module\n"
|
||||
" --module-id id\t\tSpecify a module ID for the linker\n"
|
||||
" --no-target-lib\t\tDon't link the target library\n"
|
||||
" --no-utf8\t\t\tDisable use of UTF-8 in diagnostics\n"
|
||||
" --o65-model model\t\tOverride the o65 model\n"
|
||||
" --obj file\t\t\tLink this object file\n"
|
||||
" --obj-path path\t\tSpecify an object file search path\n"
|
||||
@@ -895,7 +898,8 @@ static void Usage (void)
|
||||
" --version\t\t\tPrint the version number\n"
|
||||
" --verbose\t\t\tVerbose mode\n"
|
||||
" --zeropage-label name\t\tDefine and export a ZEROPAGE segment label\n"
|
||||
" --zeropage-name seg\t\tSet the name of the ZEROPAGE segment\n",
|
||||
" --zeropage-name seg\t\tSet the name of the ZEROPAGE segment\n"
|
||||
" --warnings-as-errors\t\tTreat warnings as errors\n",
|
||||
ProgName);
|
||||
}
|
||||
|
||||
@@ -1028,6 +1032,19 @@ static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
|
||||
static void OptColor(const char* Opt, const char* Arg)
|
||||
/* Handle the --color option */
|
||||
{
|
||||
if (CP_Parse (Arg) == CM_INVALID) {
|
||||
Error ("Invalid argument to %s: %s", Opt, Arg);
|
||||
} else {
|
||||
CmdAddArg2 (&CA65, "--color", Arg);
|
||||
CmdAddArg2 (&LD65, "--color", Arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Handle the --cpu option */
|
||||
{
|
||||
@@ -1236,6 +1253,16 @@ static void OptNoTargetLib (const char* Opt attribute ((unused)),
|
||||
|
||||
|
||||
|
||||
static void OptNoUtf8 (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Handle the --no-utf8 option */
|
||||
{
|
||||
CmdAddArg (&CA65, "--no-utf8");
|
||||
CmdAddArg (&LD65, "--no-utf8");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptO65Model (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Handle the --o65-model option */
|
||||
{
|
||||
@@ -1409,63 +1436,77 @@ static void OptZeropageName (const char* Opt attribute ((unused)), const char* A
|
||||
|
||||
|
||||
|
||||
static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Handle the --warnings-as-errors option */
|
||||
{
|
||||
CmdAddArg (&CA65, "--warnings-as-errors");
|
||||
CmdAddArg (&CC65, "--warnings-as-errors");
|
||||
CmdAddArg (&LD65, "--warnings-as-errors");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main (int argc, char* argv [])
|
||||
/* Utility main program */
|
||||
{
|
||||
/* Program long options */
|
||||
static const LongOpt OptTab[] = {
|
||||
{ "--add-source", 0, OptAddSource },
|
||||
{ "--all-cdecl", 0, OptAllCDecl },
|
||||
{ "--asm-args", 1, OptAsmArgs },
|
||||
{ "--asm-define", 1, OptAsmDefine },
|
||||
{ "--asm-include-dir", 1, OptAsmIncludeDir },
|
||||
{ "--bin-include-dir", 1, OptBinIncludeDir },
|
||||
{ "--bss-label", 1, OptBssLabel },
|
||||
{ "--bss-name", 1, OptBssName },
|
||||
{ "--cc-args", 1, OptCCArgs },
|
||||
{ "--cfg-path", 1, OptCfgPath },
|
||||
{ "--check-stack", 0, OptCheckStack },
|
||||
{ "--code-label", 1, OptCodeLabel },
|
||||
{ "--code-name", 1, OptCodeName },
|
||||
{ "--codesize", 1, OptCodeSize },
|
||||
{ "--config", 1, OptConfig },
|
||||
{ "--cpu", 1, OptCPU },
|
||||
{ "--create-dep", 1, OptCreateDep },
|
||||
{ "--create-full-dep", 1, OptCreateFullDep },
|
||||
{ "--data-label", 1, OptDataLabel },
|
||||
{ "--data-name", 1, OptDataName },
|
||||
{ "--debug", 0, OptDebug },
|
||||
{ "--debug-info", 0, OptDebugInfo },
|
||||
{ "--feature", 1, OptFeature },
|
||||
{ "--force-import", 1, OptForceImport },
|
||||
{ "--help", 0, OptHelp },
|
||||
{ "--include-dir", 1, OptIncludeDir },
|
||||
{ "--ld-args", 1, OptLdArgs },
|
||||
{ "--lib-path", 1, OptLibPath },
|
||||
{ "--list-targets", 0, OptListTargets },
|
||||
{ "--listing", 1, OptListing },
|
||||
{ "--list-bytes", 1, OptListBytes },
|
||||
{ "--mapfile", 1, OptMapFile },
|
||||
{ "--memory-model", 1, OptMemoryModel },
|
||||
{ "--module", 0, OptModule },
|
||||
{ "--module-id", 1, OptModuleId },
|
||||
{ "--no-target-lib", 0, OptNoTargetLib },
|
||||
{ "--o65-model", 1, OptO65Model },
|
||||
{ "--obj", 1, OptObj },
|
||||
{ "--obj-path", 1, OptObjPath },
|
||||
{ "--print-target-path", 0, OptPrintTargetPath},
|
||||
{ "--register-space", 1, OptRegisterSpace },
|
||||
{ "--register-vars", 0, OptRegisterVars },
|
||||
{ "--rodata-name", 1, OptRodataName },
|
||||
{ "--signed-chars", 0, OptSignedChars },
|
||||
{ "--standard", 1, OptStandard },
|
||||
{ "--start-addr", 1, OptStartAddr },
|
||||
{ "--static-locals", 0, OptStaticLocals },
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--verbose", 0, OptVerbose },
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--zeropage-label", 1, OptZeropageLabel },
|
||||
{ "--zeropage-name", 1, OptZeropageName },
|
||||
{ "--add-source", 0, OptAddSource },
|
||||
{ "--all-cdecl", 0, OptAllCDecl },
|
||||
{ "--asm-args", 1, OptAsmArgs },
|
||||
{ "--asm-define", 1, OptAsmDefine },
|
||||
{ "--asm-include-dir", 1, OptAsmIncludeDir },
|
||||
{ "--bin-include-dir", 1, OptBinIncludeDir },
|
||||
{ "--bss-label", 1, OptBssLabel },
|
||||
{ "--bss-name", 1, OptBssName },
|
||||
{ "--cc-args", 1, OptCCArgs },
|
||||
{ "--cfg-path", 1, OptCfgPath },
|
||||
{ "--check-stack", 0, OptCheckStack },
|
||||
{ "--code-label", 1, OptCodeLabel },
|
||||
{ "--code-name", 1, OptCodeName },
|
||||
{ "--codesize", 1, OptCodeSize },
|
||||
{ "--color", 1, OptColor },
|
||||
{ "--config", 1, OptConfig },
|
||||
{ "--cpu", 1, OptCPU },
|
||||
{ "--create-dep", 1, OptCreateDep },
|
||||
{ "--create-full-dep", 1, OptCreateFullDep },
|
||||
{ "--data-label", 1, OptDataLabel },
|
||||
{ "--data-name", 1, OptDataName },
|
||||
{ "--debug", 0, OptDebug },
|
||||
{ "--debug-info", 0, OptDebugInfo },
|
||||
{ "--feature", 1, OptFeature },
|
||||
{ "--force-import", 1, OptForceImport },
|
||||
{ "--help", 0, OptHelp },
|
||||
{ "--include-dir", 1, OptIncludeDir },
|
||||
{ "--ld-args", 1, OptLdArgs },
|
||||
{ "--lib-path", 1, OptLibPath },
|
||||
{ "--list-targets", 0, OptListTargets },
|
||||
{ "--listing", 1, OptListing },
|
||||
{ "--list-bytes", 1, OptListBytes },
|
||||
{ "--mapfile", 1, OptMapFile },
|
||||
{ "--memory-model", 1, OptMemoryModel },
|
||||
{ "--module", 0, OptModule },
|
||||
{ "--module-id", 1, OptModuleId },
|
||||
{ "--no-target-lib", 0, OptNoTargetLib },
|
||||
{ "--no-utf8", 0, OptNoUtf8 },
|
||||
{ "--o65-model", 1, OptO65Model },
|
||||
{ "--obj", 1, OptObj },
|
||||
{ "--obj-path", 1, OptObjPath },
|
||||
{ "--print-target-path", 0, OptPrintTargetPath },
|
||||
{ "--register-space", 1, OptRegisterSpace },
|
||||
{ "--register-vars", 0, OptRegisterVars },
|
||||
{ "--rodata-name", 1, OptRodataName },
|
||||
{ "--signed-chars", 0, OptSignedChars },
|
||||
{ "--standard", 1, OptStandard },
|
||||
{ "--start-addr", 1, OptStartAddr },
|
||||
{ "--static-locals", 0, OptStaticLocals },
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--verbose", 0, OptVerbose },
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--zeropage-label", 1, OptZeropageLabel },
|
||||
{ "--zeropage-name", 1, OptZeropageName },
|
||||
{ "--warnings-as-errors", 0, OptWarningsAsErrors },
|
||||
};
|
||||
|
||||
char* CmdPath;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if !defined(_WIN32)
|
||||
# include <unistd.h>
|
||||
#else
|
||||
@@ -153,6 +154,23 @@ void CP_Init (void)
|
||||
|
||||
|
||||
|
||||
ColorMode CP_Parse (const char* Mode)
|
||||
/* Parse the given string which is assumed to be one of the color modes.
|
||||
* Return the matching enum or CM_INVALID if there was no match.
|
||||
*/
|
||||
{
|
||||
if (strcmp (Mode, "off") == 0 || strcmp (Mode, "false") == 0) {
|
||||
return CM_OFF;
|
||||
} else if (strcmp (Mode, "auto") == 0) {
|
||||
return CM_AUTO;
|
||||
} else if (strcmp (Mode, "on") == 0 || strcmp (Mode, "true") == 0) {
|
||||
return CM_ON;
|
||||
} else {
|
||||
return CM_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CP_IsTTY (void)
|
||||
/* Return true if console output goes to a tty */
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/* Color mode for the program */
|
||||
enum ColorMode { CM_OFF, CM_AUTO, CM_ON };
|
||||
enum ColorMode { CM_INVALID = -1, CM_OFF, CM_AUTO, CM_ON };
|
||||
typedef enum ColorMode ColorMode;
|
||||
|
||||
/* Colors */
|
||||
@@ -96,6 +96,11 @@ void CP_Init (void);
|
||||
** data from this module.
|
||||
**/
|
||||
|
||||
ColorMode CP_Parse (const char* Mode);
|
||||
/* Parse the given string which is assumed to be one of the color modes.
|
||||
** Return the matching enum or CM_INVALID if there was no match.
|
||||
*/
|
||||
|
||||
int CP_IsTTY (void);
|
||||
/* Return true if console output goes to a tty */
|
||||
|
||||
|
||||
@@ -154,13 +154,17 @@ const unsigned CPUIsets[CPU_COUNT] = {
|
||||
CAP_BIT (CAP_CPU_HAS_INA) | \
|
||||
CAP_BIT (CAP_CPU_HAS_PUSHXY))
|
||||
#define CAP_W65C02 \
|
||||
(CAP_BIT (CAP_CPU_HAS_BRA8) | \
|
||||
(CAP_BIT (CAP_CPU_HAS_BITIMM) | \
|
||||
CAP_BIT (CAP_CPU_HAS_BRA8) | \
|
||||
CAP_BIT (CAP_CPU_HAS_INA) | \
|
||||
CAP_BIT (CAP_CPU_HAS_PUSHXY))
|
||||
CAP_BIT (CAP_CPU_HAS_PUSHXY) | \
|
||||
CAP_BIT (CAP_CPU_HAS_ZPIND) | \
|
||||
CAP_BIT (CAP_CPU_HAS_STZ))
|
||||
#define CAP_65CE02 \
|
||||
(CAP_BIT (CAP_CPU_HAS_BRA8) | \
|
||||
CAP_BIT (CAP_CPU_HAS_INA) | \
|
||||
CAP_BIT (CAP_CPU_HAS_PUSHXY))
|
||||
CAP_BIT (CAP_CPU_HAS_PUSHXY) | \
|
||||
CAP_BIT (CAP_CPU_HAS_STZ))
|
||||
|
||||
/* Table containing one capability entry per CPU */
|
||||
static const uint32_t CPUCaps[CPU_COUNT] = {
|
||||
|
||||
@@ -109,8 +109,8 @@ void CheckAssertions (void)
|
||||
for (I = 0; I < CollCount (&Assertions); ++I) {
|
||||
|
||||
const LineInfo* LI;
|
||||
const char* Module;
|
||||
unsigned Line;
|
||||
const FilePos* Pos;
|
||||
const char* Message;
|
||||
|
||||
/* Get the assertion */
|
||||
Assertion* A = CollAtUnchecked (&Assertions, I);
|
||||
@@ -120,38 +120,33 @@ void CheckAssertions (void)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Retrieve the relevant line info for this assertion */
|
||||
LI = CollConstAt (&A->LineInfos, 0);
|
||||
|
||||
/* Get file name and line number from the source */
|
||||
Module = GetSourceName (LI);
|
||||
Line = GetSourceLine (LI);
|
||||
/* Get some assertion data */
|
||||
Message = GetString (A->Msg);
|
||||
LI = CollConstAt (&A->LineInfos, 0);
|
||||
Pos = GetSourcePos (LI);
|
||||
|
||||
/* If the expression is not constant, we're not able to handle it */
|
||||
if (!IsConstExpr (A->Expr)) {
|
||||
Warning ("Cannot evaluate assertion in module '%s', line %u",
|
||||
Module, Line);
|
||||
AddPNote (Pos, "The assert message is: \"%s\"", Message);
|
||||
PWarning (Pos, "Cannot evaluate this source code assertion");
|
||||
} else if (GetExprVal (A->Expr) == 0) {
|
||||
|
||||
/* Assertion failed */
|
||||
const char* Message = GetString (A->Msg);
|
||||
|
||||
switch (A->Action) {
|
||||
|
||||
case ASSERT_ACT_WARN:
|
||||
case ASSERT_ACT_LDWARN:
|
||||
Warning ("%s:%u: %s", Module, Line, Message);
|
||||
PWarning (Pos, "Assertion failed: %s", Message);
|
||||
break;
|
||||
|
||||
case ASSERT_ACT_ERROR:
|
||||
case ASSERT_ACT_LDERROR:
|
||||
Error ("%s:%u: %s", Module, Line, Message);
|
||||
PError (Pos, "Assertion failed: %s", Message);
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid assertion action (%u) in module '%s', "
|
||||
"line %u (file corrupt?)",
|
||||
A->Action, Module, Line);
|
||||
AddPNote (Pos, "The file might be corrupt or wrong version");
|
||||
PError (Pos, "Invalid assertion action %u", A->Action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,11 +301,11 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
/* Open the file */
|
||||
D->F = fopen (D->Filename, "wb");
|
||||
if (D->F == 0) {
|
||||
Error ("Cannot open '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Keep the user happy */
|
||||
Print (stdout, 1, "Opened '%s'...\n", D->Filename);
|
||||
Print (stdout, 1, "Opened `%s'...\n", D->Filename);
|
||||
|
||||
/* Dump all memory areas */
|
||||
for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
|
||||
@@ -317,7 +317,7 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (D->F) != 0) {
|
||||
Error ("Cannot write to '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Reset the file and filename */
|
||||
|
||||
@@ -105,11 +105,11 @@ static ExprNode* Factor (void)
|
||||
/* Left parenthesis */
|
||||
CfgNextTok ();
|
||||
N = CfgExpr ();
|
||||
CfgConsume (CFGTOK_RPAR, "')' expected");
|
||||
CfgConsume (CFGTOK_RPAR, "`)' expected");
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid expression: %d", CfgTok);
|
||||
PError (&CfgErrorPos, "Invalid expression: %d", CfgTok);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ long CfgConstExpr (void)
|
||||
|
||||
/* Check that it's const */
|
||||
if (!IsConstExpr (Expr)) {
|
||||
CfgError (&CfgErrorPos, "Constant expression expected");
|
||||
PError (&CfgErrorPos, "Constant expression expected");
|
||||
}
|
||||
|
||||
/* Get the value */
|
||||
@@ -238,7 +238,7 @@ long CfgCheckedConstExpr (long Min, long Max)
|
||||
|
||||
/* Check the range */
|
||||
if (Val < Min || Val > Max) {
|
||||
CfgError (&CfgErrorPos, "Range error");
|
||||
PError (&CfgErrorPos, "Range error");
|
||||
}
|
||||
|
||||
/* Return the value */
|
||||
|
||||
@@ -228,7 +228,7 @@ static MemoryArea* CfgGetMemory (unsigned Name)
|
||||
{
|
||||
MemoryArea* M = CfgFindMemory (Name);
|
||||
if (M == 0) {
|
||||
CfgError (&CfgErrorPos, "Invalid memory area '%s'", GetString (Name));
|
||||
PError (&CfgErrorPos, "Invalid memory area `%s'", GetString (Name));
|
||||
}
|
||||
return M;
|
||||
}
|
||||
@@ -321,9 +321,8 @@ static MemoryArea* CreateMemoryArea (const FilePos* Pos, unsigned Name)
|
||||
/* Check for duplicate names */
|
||||
MemoryArea* M = CfgFindMemory (Name);
|
||||
if (M) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"Memory area '%s' defined twice",
|
||||
GetString (Name));
|
||||
PError (&CfgErrorPos, "Memory area `%s' defined twice",
|
||||
GetString (Name));
|
||||
}
|
||||
|
||||
/* Create a new memory area */
|
||||
@@ -345,7 +344,7 @@ static SegDesc* NewSegDesc (unsigned Name)
|
||||
/* Check for duplicate names */
|
||||
SegDesc* S = CfgFindSegDesc (Name);
|
||||
if (S) {
|
||||
CfgError (&CfgErrorPos, "Segment '%s' defined twice", GetString (Name));
|
||||
PError (&CfgErrorPos, "Segment `%s' defined twice", GetString (Name));
|
||||
}
|
||||
|
||||
/* Allocate memory */
|
||||
@@ -391,7 +390,7 @@ static void FlagAttr (unsigned* Flags, unsigned Mask, const char* Name)
|
||||
*/
|
||||
{
|
||||
if (*Flags & Mask) {
|
||||
CfgError (&CfgErrorPos, "%s is already defined", Name);
|
||||
PError (&CfgErrorPos, "Attribute `%s' is already defined", Name);
|
||||
}
|
||||
*Flags |= Mask;
|
||||
}
|
||||
@@ -402,7 +401,7 @@ static void AttrCheck (unsigned Attr, unsigned Mask, const char* Name)
|
||||
/* Check that a mandatory attribute was given */
|
||||
{
|
||||
if ((Attr & Mask) == 0) {
|
||||
CfgError (&CfgErrorPos, "%s attribute is missing", Name);
|
||||
PError (&CfgErrorPos, "Mandatory attribute `%s' is missing", Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +439,8 @@ static void ParseMemory (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"Memory attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -500,7 +500,7 @@ static void ParseMemory (void)
|
||||
|
||||
case CFGTOK_TYPE:
|
||||
FlagAttr (&M->Attr, MA_TYPE, "TYPE");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "TYPE");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Memory type");
|
||||
if (CfgTok == CFGTOK_RO) {
|
||||
M->Flags |= MF_RO;
|
||||
}
|
||||
@@ -554,7 +554,7 @@ static void ParseFiles (void)
|
||||
|
||||
/* The MEMORY section must preceed the FILES section */
|
||||
if ((SectionsEncountered & SE_MEMORY) == 0) {
|
||||
CfgError (&CfgErrorPos, "MEMORY must precede FILES");
|
||||
PError (&CfgErrorPos, "`MEMORY' must precede `FILES'");
|
||||
}
|
||||
|
||||
/* Parse all files */
|
||||
@@ -568,9 +568,8 @@ static void ParseFiles (void)
|
||||
/* Search for the file, it must exist */
|
||||
F = FindFile (GetStrBufId (&CfgSVal));
|
||||
if (F == 0) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"File '%s' not found in MEMORY section",
|
||||
SB_GetConstBuf (&CfgSVal));
|
||||
PError (&CfgErrorPos, "File `%s' not found in `MEMORY' section",
|
||||
SB_GetConstBuf (&CfgSVal));
|
||||
}
|
||||
|
||||
/* Skip the token and the following colon */
|
||||
@@ -582,7 +581,8 @@ static void ParseFiles (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"File attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -595,11 +595,10 @@ static void ParseFiles (void)
|
||||
case CFGTOK_FORMAT:
|
||||
if (F->Format != BINFMT_DEFAULT) {
|
||||
/* We've set the format already! */
|
||||
CfgError (&CfgErrorPos,
|
||||
"Cannot set a file format twice");
|
||||
PError (&CfgErrorPos, "Cannot set a file format twice");
|
||||
}
|
||||
/* Read the format token */
|
||||
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
|
||||
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "File format");
|
||||
switch (CfgTok) {
|
||||
|
||||
case CFGTOK_BIN:
|
||||
@@ -667,7 +666,7 @@ static void ParseSegments (void)
|
||||
|
||||
/* The MEMORY section must preceed the SEGMENTS section */
|
||||
if ((SectionsEncountered & SE_MEMORY) == 0) {
|
||||
CfgError (&CfgErrorPos, "MEMORY must precede SEGMENTS");
|
||||
PError (&CfgErrorPos, "`MEMORY' must precede `SEGMENTS'");
|
||||
}
|
||||
|
||||
while (CfgTok == CFGTOK_IDENT) {
|
||||
@@ -686,7 +685,7 @@ static void ParseSegments (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Segment attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -759,7 +758,7 @@ static void ParseSegments (void)
|
||||
|
||||
case CFGTOK_TYPE:
|
||||
FlagAttr (&S->Attr, SA_TYPE, "TYPE");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Segment type");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_RO: S->Flags |= SF_RO; break;
|
||||
case CFGTOK_RW: /* Default */ break;
|
||||
@@ -793,9 +792,9 @@ static void ParseSegments (void)
|
||||
** separate run and load memory areas.
|
||||
*/
|
||||
if ((S->Flags & SF_ALIGN_LOAD) != 0 && (S->Load == S->Run)) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"ALIGN_LOAD attribute specified, but no separate "
|
||||
"LOAD and RUN memory areas assigned");
|
||||
PWarning (&CfgErrorPos,
|
||||
"`ALIGN_LOAD' attribute specified, but no separate "
|
||||
"`LOAD' and `RUN' memory areas assigned");
|
||||
/* Remove the flag */
|
||||
S->Flags &= ~SF_ALIGN_LOAD;
|
||||
}
|
||||
@@ -804,17 +803,17 @@ static void ParseSegments (void)
|
||||
** load and run memory areas, because it's is never written to disk.
|
||||
*/
|
||||
if ((S->Flags & SF_BSS) != 0 && (S->Load != S->Run)) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Segment with type 'bss' has both LOAD and RUN "
|
||||
"memory areas assigned");
|
||||
PWarning (&CfgErrorPos,
|
||||
"Segment with type `bss' has both `LOAD' and `RUN' "
|
||||
"memory areas assigned");
|
||||
}
|
||||
|
||||
/* Don't allow read/write data to be put into a readonly area */
|
||||
if ((S->Flags & SF_RO) == 0) {
|
||||
if (S->Run->Flags & MF_RO) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"Cannot put r/w segment '%s' in r/o memory area '%s'",
|
||||
GetString (S->Name), GetString (S->Run->Name));
|
||||
PError (&CfgErrorPos,
|
||||
"Cannot place r/w segment `%s' in r/o memory area `%s'",
|
||||
GetString (S->Name), GetString (S->Run->Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,8 +822,8 @@ static void ParseSegments (void)
|
||||
((S->Flags & SF_OFFSET) != 0) +
|
||||
((S->Flags & SF_START) != 0);
|
||||
if (Count > 1) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"Only one of ALIGN, START, OFFSET may be used");
|
||||
PError (&CfgErrorPos,
|
||||
"Only one of `ALIGN', `START' or `OFFSET' may be used");
|
||||
}
|
||||
|
||||
/* Skip the semicolon */
|
||||
@@ -881,7 +880,7 @@ static void ParseO65 (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "O65 attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -924,7 +923,7 @@ static void ParseO65 (void)
|
||||
/* Cannot have this attribute twice */
|
||||
FlagAttr (&AttrFlags, atType, "TYPE");
|
||||
/* Get the type of the executable */
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "O65 type");
|
||||
switch (CfgTok) {
|
||||
|
||||
case CFGTOK_SMALL:
|
||||
@@ -936,7 +935,7 @@ static void ParseO65 (void)
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Unexpected type token");
|
||||
PError (&CfgErrorPos, "Unexpected type token");
|
||||
}
|
||||
/* Eat the attribute token */
|
||||
CfgNextTok ();
|
||||
@@ -952,13 +951,15 @@ static void ParseO65 (void)
|
||||
CfgRangeCheck (O65OS_MIN, O65OS_MAX);
|
||||
OS = (unsigned) CfgIVal;
|
||||
} else {
|
||||
CfgSpecialToken (OperatingSystems, ENTRY_COUNT (OperatingSystems), "OS type");
|
||||
CfgSpecialToken (OperatingSystems,
|
||||
ENTRY_COUNT (OperatingSystems),
|
||||
"O65 OS specification");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_LUNIX: OS = O65OS_LUNIX; break;
|
||||
case CFGTOK_OSA65: OS = O65OS_OSA65; break;
|
||||
case CFGTOK_CC65: OS = O65OS_CC65; break;
|
||||
case CFGTOK_OPENCBM: OS = O65OS_OPENCBM; break;
|
||||
default: CfgError (&CfgErrorPos, "Unexpected OS token");
|
||||
default: PError (&CfgErrorPos, "Unexpected OS token");
|
||||
}
|
||||
}
|
||||
CfgNextTok ();
|
||||
@@ -993,13 +994,13 @@ static void ParseO65 (void)
|
||||
/* Check for attributes that may not be combined */
|
||||
if (OS == O65OS_CC65) {
|
||||
if ((AttrFlags & (atImport | atExport)) != 0 && ModuleId < 0x8000) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"OS type CC65 may not have imports or exports for ids < $8000");
|
||||
PError (&CfgErrorPos,
|
||||
"OS type CC65 may not have imports or exports for ids < $8000");
|
||||
}
|
||||
} else {
|
||||
if (AttrFlags & atID) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"Operating system does not support the ID attribute");
|
||||
PError (&CfgErrorPos,
|
||||
"Operating system does not support the ID attribute");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1033,7 +1034,7 @@ static void ParseXex (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Xex attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -1071,7 +1072,7 @@ static void ParseXex (void)
|
||||
CfgNextTok ();
|
||||
/* Add to XEX */
|
||||
if (XexAddInitAd (XexFmtDesc, InitMem, InitAd))
|
||||
CfgError (&CfgErrorPos, "INITAD already given for memory area");
|
||||
PError (&CfgErrorPos, "`INITAD' already given for memory area");
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1104,7 +1105,7 @@ static void ParseFormats (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t FormatTok;
|
||||
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
|
||||
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format attribute");
|
||||
FormatTok = CfgTok;
|
||||
|
||||
/* Skip the name and the following colon */
|
||||
@@ -1190,7 +1191,8 @@ static void ParseConDes (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"CONDES attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -1232,7 +1234,7 @@ static void ParseConDes (void)
|
||||
case CFGTOK_ORDER:
|
||||
/* Don't allow this twice */
|
||||
FlagAttr (&AttrFlags, atOrder, "ORDER");
|
||||
CfgSpecialToken (Orders, ENTRY_COUNT (Orders), "Order");
|
||||
CfgSpecialToken (Orders, ENTRY_COUNT (Orders), "CONDES order");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_DECREASING: Order = cdDecreasing; break;
|
||||
case CFGTOK_INCREASING: Order = cdIncreasing; break;
|
||||
@@ -1257,7 +1259,7 @@ static void ParseConDes (void)
|
||||
CfgRangeCheck (CD_TYPE_MIN, CD_TYPE_MAX);
|
||||
Type = (int) CfgIVal;
|
||||
} else {
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "CONDES type");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_CONSTRUCTOR: Type = CD_TYPE_CON; break;
|
||||
case CFGTOK_DESTRUCTOR: Type = CD_TYPE_DES; break;
|
||||
@@ -1289,10 +1291,10 @@ static void ParseConDes (void)
|
||||
AttrCheck (AttrFlags, atType, "TYPE");
|
||||
|
||||
/* Check if the condes has already attributes defined */
|
||||
if (ConDesHasSegName(Type) || ConDesHasLabel(Type)) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"CONDES attributes for type %d are already defined",
|
||||
Type);
|
||||
if (ConDesHasSegName (Type) || ConDesHasLabel (Type)) {
|
||||
PError (&CfgErrorPos,
|
||||
"`CONDES' attributes for type %d are already defined",
|
||||
Type);
|
||||
}
|
||||
|
||||
/* Define the attributes */
|
||||
@@ -1334,7 +1336,8 @@ static void ParseStartAddress (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"Start address attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -1389,7 +1392,7 @@ static void ParseFeatures (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t FeatureTok;
|
||||
CfgSpecialToken (Features, ENTRY_COUNT (Features), "Feature");
|
||||
CfgSpecialToken (Features, ENTRY_COUNT (Features), "Feature attribute");
|
||||
FeatureTok = CfgTok;
|
||||
|
||||
/* Skip the name and the following colon */
|
||||
@@ -1479,7 +1482,8 @@ static void ParseSymbols (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"Symbol attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* Skip the attribute name */
|
||||
@@ -1495,7 +1499,8 @@ static void ParseSymbols (void)
|
||||
/* Don't allow this twice */
|
||||
FlagAttr (&AttrFlags, atAddrSize, "ADDRSIZE");
|
||||
/* Map the type to a token */
|
||||
CfgSpecialToken (AddrSizes, ENTRY_COUNT (AddrSizes), "AddrSize");
|
||||
CfgSpecialToken (AddrSizes, ENTRY_COUNT (AddrSizes),
|
||||
"Address size specification");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_ABS: AddrSize = ADDR_SIZE_ABS; break;
|
||||
case CFGTOK_FAR: AddrSize = ADDR_SIZE_FAR; break;
|
||||
@@ -1511,7 +1516,8 @@ static void ParseSymbols (void)
|
||||
/* Don't allow this twice */
|
||||
FlagAttr (&AttrFlags, atType, "TYPE");
|
||||
/* Map the type to a token */
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types),
|
||||
"Address size type");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_EXPORT: Type = CfgSymExport; break;
|
||||
case CFGTOK_IMPORT: Type = CfgSymImport; break;
|
||||
@@ -1559,7 +1565,7 @@ static void ParseSymbols (void)
|
||||
case CfgSymImport:
|
||||
/* An import must not have a value */
|
||||
if (AttrFlags & atValue) {
|
||||
CfgError (&CfgErrorPos, "Imports must not have a value");
|
||||
PError (&CfgErrorPos, "Imports must not have a value");
|
||||
}
|
||||
/* Generate the import */
|
||||
Imp = InsertImport (GenImport (Name, AddrSize));
|
||||
@@ -1606,12 +1612,13 @@ static void ParseConfig (void)
|
||||
do {
|
||||
|
||||
/* Read the block ident */
|
||||
CfgSpecialToken (BlockNames, ENTRY_COUNT (BlockNames), "Block identifier");
|
||||
CfgSpecialToken (BlockNames, ENTRY_COUNT (BlockNames),
|
||||
"Configuration block identifier");
|
||||
BlockTok = CfgTok;
|
||||
CfgNextTok ();
|
||||
|
||||
/* Expected a curly brace */
|
||||
CfgConsume (CFGTOK_LCURLY, "'{' expected");
|
||||
CfgConsume (CFGTOK_LCURLY, "`{' expected");
|
||||
|
||||
/* Read the block */
|
||||
switch (BlockTok) {
|
||||
@@ -1646,7 +1653,7 @@ static void ParseConfig (void)
|
||||
}
|
||||
|
||||
/* Skip closing brace */
|
||||
CfgConsume (CFGTOK_RCURLY, "'}' expected");
|
||||
CfgConsume (CFGTOK_RCURLY, "`}' expected");
|
||||
|
||||
} while (CfgTok != CFGTOK_EOF);
|
||||
}
|
||||
@@ -1702,10 +1709,20 @@ static void ProcessSegments (void)
|
||||
** in any of the object file, check that there's no initialized data
|
||||
** in the segment.
|
||||
*/
|
||||
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' with type 'bss' contains initialized data",
|
||||
GetString (S->Name));
|
||||
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0) {
|
||||
Section* Sec = GetNonBSSSection (S->Seg);
|
||||
if (Sec) {
|
||||
const FilePos* Pos = GetSourcePos (S->LI);
|
||||
if (Sec->Obj) {
|
||||
AddPNote (Pos, "Initialized data comes at least partially "
|
||||
"from `%s'", GetString (Sec->Obj->Name));
|
||||
} else {
|
||||
AddPNote (Pos, "Initialized data is at least partially "
|
||||
"linker generated");
|
||||
}
|
||||
PWarning (Pos, "Segment `%s' with type `bss' contains "
|
||||
"initialized data", GetString (S->Name));
|
||||
}
|
||||
}
|
||||
|
||||
/* If this segment does exist in any of the object files, insert the
|
||||
@@ -1732,9 +1749,8 @@ static void ProcessSegments (void)
|
||||
|
||||
/* Print a warning if the segment is not optional */
|
||||
if ((S->Flags & SF_OPTIONAL) == 0) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Segment '%s' does not exist",
|
||||
GetString (S->Name));
|
||||
PWarning (&CfgErrorPos, "Segment `%s' does not exist",
|
||||
GetString (S->Name));
|
||||
}
|
||||
|
||||
/* Discard the descriptor and remove it from the collection */
|
||||
@@ -1764,9 +1780,9 @@ static void ProcessSymbols (void)
|
||||
case CfgSymO65Export:
|
||||
/* Check if the export symbol is also defined as an import. */
|
||||
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
PError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Exported o65 symbol '%s' cannot also be an o65 import",
|
||||
"Exported o65 symbol `%s' cannot also be an o65 import",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1776,9 +1792,9 @@ static void ProcessSymbols (void)
|
||||
** error message when checking it here.
|
||||
*/
|
||||
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
PError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Duplicate exported o65 symbol: '%s'",
|
||||
"Duplicate exported o65 symbol: `%s'",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1790,9 +1806,9 @@ static void ProcessSymbols (void)
|
||||
case CfgSymO65Import:
|
||||
/* Check if the import symbol is also defined as an export. */
|
||||
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
PError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Imported o65 symbol '%s' cannot also be an o65 export",
|
||||
"Imported o65 symbol `%s' cannot also be an o65 export",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1802,9 +1818,9 @@ static void ProcessSymbols (void)
|
||||
** error message when checking it here.
|
||||
*/
|
||||
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
PError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Duplicate imported o65 symbol: '%s'",
|
||||
"Duplicate imported o65 symbol: `%s'",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1913,9 +1929,9 @@ unsigned CfgProcess (void)
|
||||
** and mark the memory area as placed.
|
||||
*/
|
||||
if (!IsConstExpr (M->StartExpr)) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Start address of memory area '%s' is not constant",
|
||||
GetString (M->Name));
|
||||
PError (GetSourcePos (M->LI),
|
||||
"Start address of memory area `%s' is not constant",
|
||||
GetString (M->Name));
|
||||
}
|
||||
Addr = M->Start = GetExprVal (M->StartExpr);
|
||||
M->Flags |= MF_PLACED;
|
||||
@@ -1938,15 +1954,15 @@ unsigned CfgProcess (void)
|
||||
|
||||
/* Resolve the size expression */
|
||||
if (!IsConstExpr (M->SizeExpr)) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Size of memory area '%s' is not constant",
|
||||
GetString (M->Name));
|
||||
PError (GetSourcePos (M->LI),
|
||||
"Size of memory area `%s' is not constant",
|
||||
GetString (M->Name));
|
||||
}
|
||||
M->Size = GetExprVal (M->SizeExpr);
|
||||
if (M->Size >= 0x80000000) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Size of memory area '%s' is negative: %ld",
|
||||
GetString (M->Name), (long)M->Size);
|
||||
PError (GetSourcePos (M->LI),
|
||||
"Size of memory area `%s' is negative: %ld",
|
||||
GetString (M->Name), (long)M->Size);
|
||||
}
|
||||
|
||||
/* Walk through the segments in this memory area */
|
||||
@@ -1968,17 +1984,17 @@ unsigned CfgProcess (void)
|
||||
if (S->Flags & (SF_OFFSET | SF_START)) {
|
||||
++Overwrites;
|
||||
} else {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Segment '%s' of type 'overwrite' requires either"
|
||||
" 'Start' or 'Offset' attribute to be specified",
|
||||
GetString (S->Name));
|
||||
PError (GetSourcePos (M->LI),
|
||||
"Segment `%s' of type `overwrite' requires either"
|
||||
" `START' or `OFFSET' attribute to be specified",
|
||||
GetString (S->Name));
|
||||
}
|
||||
} else {
|
||||
if (Overwrites > 0) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Segment '%s' is preceded by at least one segment"
|
||||
" of type 'overwrite'",
|
||||
GetString (S->Name));
|
||||
PError (GetSourcePos (M->LI),
|
||||
"Segment `%s' is preceded by at least one segment"
|
||||
" of type `overwrite'",
|
||||
GetString (S->Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2002,10 +2018,10 @@ unsigned CfgProcess (void)
|
||||
/* Segment requires another alignment than configured
|
||||
** in the linker.
|
||||
*/
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' isn't aligned properly; the"
|
||||
" resulting executable might not be functional.",
|
||||
GetString (S->Name));
|
||||
PWarning (GetSourcePos (S->LI),
|
||||
"Segment `%s' isn't aligned properly; the"
|
||||
" resulting executable might not be functional.",
|
||||
GetString (S->Name));
|
||||
}
|
||||
|
||||
if (S->Flags & SF_ALIGN) {
|
||||
@@ -2017,10 +2033,10 @@ unsigned CfgProcess (void)
|
||||
** that is somewhat suspicious.
|
||||
*/
|
||||
if (M->FillLevel == 0 && NewAddr > Addr) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"The first segment in memory area '%s' "
|
||||
"needs fill bytes for alignment.",
|
||||
GetString (M->Name));
|
||||
PWarning (GetSourcePos (S->LI),
|
||||
"The first segment in memory area `%s' "
|
||||
"needs fill bytes for alignment.",
|
||||
GetString (M->Name));
|
||||
}
|
||||
|
||||
/* Use the aligned address */
|
||||
@@ -2038,9 +2054,9 @@ unsigned CfgProcess (void)
|
||||
|
||||
if (S->Flags & SF_OVERWRITE) {
|
||||
if (NewAddr < M->Start) {
|
||||
CfgError (GetSourcePos (S->LI),
|
||||
"Segment '%s' begins before memory area '%s'",
|
||||
GetString (S->Name), GetString (M->Name));
|
||||
PError (GetSourcePos (S->LI),
|
||||
"Segment `%s' begins before memory area `%s'",
|
||||
GetString (S->Name), GetString (M->Name));
|
||||
} else {
|
||||
Addr = NewAddr;
|
||||
}
|
||||
@@ -2049,15 +2065,23 @@ unsigned CfgProcess (void)
|
||||
/* Offset already too large */
|
||||
++Overflows;
|
||||
if (S->Flags & SF_OFFSET) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' offset is too small in '%s' by %lu byte%s",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
Addr - NewAddr, (Addr - NewAddr == 1) ? "" : "s");
|
||||
PWarning (
|
||||
GetSourcePos (S->LI),
|
||||
"Segment `%s' offset is too small in `%s' by %lu byte%s",
|
||||
GetString (S->Name),
|
||||
GetString (M->Name),
|
||||
Addr - NewAddr,
|
||||
(Addr - NewAddr == 1) ? "" : "s"
|
||||
);
|
||||
} else {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' start address is too low in '%s' by %lu byte%s",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
Addr - NewAddr, (Addr - NewAddr == 1) ? "" : "s");
|
||||
PWarning (
|
||||
GetSourcePos (S->LI),
|
||||
"Segment `%s' start address is too low in `%s' by %lu byte%s",
|
||||
GetString (S->Name),
|
||||
GetString (M->Name),
|
||||
Addr - NewAddr,
|
||||
(Addr - NewAddr == 1) ? "" : "s"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
Addr = NewAddr;
|
||||
@@ -2101,10 +2125,14 @@ unsigned CfgProcess (void)
|
||||
if (FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) {
|
||||
++Overflows;
|
||||
M->Flags |= MF_OVERFLOW;
|
||||
CfgWarning (GetSourcePos (M->LI),
|
||||
"Segment '%s' overflows memory area '%s' by %lu byte%s",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
FillLevel - M->Size, (FillLevel - M->Size == 1) ? "" : "s");
|
||||
PWarning (
|
||||
GetSourcePos (M->LI),
|
||||
"Segment `%s' overflows memory area `%s' by %lu byte%s",
|
||||
GetString (S->Name),
|
||||
GetString (M->Name),
|
||||
FillLevel - M->Size,
|
||||
(FillLevel - M->Size == 1) ? "" : "s"
|
||||
);
|
||||
}
|
||||
if (FillLevel > M->FillLevel) {
|
||||
/* Regular segments increase FillLevel. Overwrite segments may
|
||||
|
||||
@@ -107,7 +107,7 @@ void CreateDbgFile (void)
|
||||
/* Open the debug info file */
|
||||
FILE* F = fopen (DbgFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create debug file '%s': %s", DbgFileName, strerror (errno));
|
||||
Error ("Cannot create debug file `%s': %s", DbgFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Output version information */
|
||||
@@ -166,6 +166,6 @@ void CreateDbgFile (void)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing debug file '%s': %s", DbgFileName, strerror (errno));
|
||||
Error ("Error closing debug file `%s': %s", DbgFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
304
src/ld65/error.c
304
src/ld65/error.c
@@ -39,10 +39,13 @@
|
||||
|
||||
/* common */
|
||||
#include "cmdline.h"
|
||||
#include "coll.h"
|
||||
#include "consprop.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
/* ld65 */
|
||||
#include "error.h"
|
||||
#include "spool.h"
|
||||
|
||||
|
||||
|
||||
@@ -55,6 +58,22 @@
|
||||
/* Statistics */
|
||||
unsigned WarningCount = 0;
|
||||
|
||||
/* Diagnostic category. */
|
||||
typedef enum { DC_NOTE, DC_WARN, DC_ERR, DC_INT, DC_COUNT } DiagCat;
|
||||
|
||||
/* Descriptions for diagnostic categories */
|
||||
const char* DiagCatDesc[DC_COUNT] = {
|
||||
"Note", "Warning", "Error", "Internal error"
|
||||
};
|
||||
|
||||
/* An empty file position used when diagnostics aren't related to a file */
|
||||
static FilePos NoFile = STATIC_FILEPOS_INITIALIZER;
|
||||
|
||||
/* Notifications. They are remembered here and output with the next call to
|
||||
** Error() or Warning().
|
||||
*/
|
||||
static Collection Notes = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -63,20 +82,213 @@ unsigned WarningCount = 0;
|
||||
|
||||
|
||||
|
||||
static void ReplaceQuotes (StrBuf* Msg)
|
||||
/* Replace opening and closing single quotes in Msg by their typographically
|
||||
** correct UTF-8 counterparts for better readbility. A closing quote will
|
||||
** only get replaced if an opening quote has been seen before.
|
||||
** To handle some special cases, the function will also treat \xF0 as
|
||||
** opening and \xF1 as closing quote. These are replaced without the need for
|
||||
** correct ordering (open/close).
|
||||
** The function will change the quotes in place, so after the call Msg will
|
||||
** contain the changed string. If UTF-8 is not available, the function will
|
||||
** replace '`' by '\'' since that was the default behavior before. It will
|
||||
** also replace \xF0 and \xF1 by '\''.
|
||||
*/
|
||||
{
|
||||
/* UTF-8 characters for single quotes */
|
||||
static const char QuoteStart[] = "\xE2\x80\x98";
|
||||
static const char QuoteEnd[] = "\xE2\x80\x99";
|
||||
|
||||
/* ANSI color sequences */
|
||||
const char* ColorStart = CP_BrightGreen ();
|
||||
const char* ColorEnd = CP_White ();
|
||||
|
||||
/* Remember a few things */
|
||||
int IsUTF8 = CP_IsUTF8 ();
|
||||
|
||||
/* We create a new string in T and will later copy it back to Msg */
|
||||
StrBuf T = AUTO_STRBUF_INITIALIZER;
|
||||
|
||||
/* Parse the string and create a modified copy */
|
||||
SB_Reset (Msg);
|
||||
int InQuote = 0;
|
||||
while (1) {
|
||||
char C = SB_Get (Msg);
|
||||
switch (C) {
|
||||
case '`':
|
||||
if (!InQuote) {
|
||||
InQuote = 1;
|
||||
if (IsUTF8) {
|
||||
SB_AppendStr (&T, QuoteStart);
|
||||
} else {
|
||||
/* ca65 uses \' for opening and closing quotes */
|
||||
SB_AppendChar (&T, '\'');
|
||||
}
|
||||
SB_AppendStr (&T, ColorStart);
|
||||
} else {
|
||||
/* Found two ` without closing quote - don't replace */
|
||||
SB_AppendChar (&T, '`');
|
||||
}
|
||||
break;
|
||||
case '\'':
|
||||
if (InQuote) {
|
||||
InQuote = 0;
|
||||
SB_AppendStr (&T, ColorEnd);
|
||||
if (IsUTF8) {
|
||||
SB_AppendStr (&T, QuoteEnd);
|
||||
} else {
|
||||
SB_AppendChar (&T, C);
|
||||
}
|
||||
} else {
|
||||
SB_AppendChar (&T, C);
|
||||
}
|
||||
break;
|
||||
case '\xF0':
|
||||
if (IsUTF8) {
|
||||
SB_AppendStr (&T, QuoteStart);
|
||||
} else {
|
||||
SB_AppendChar (&T, '\'');
|
||||
}
|
||||
break;
|
||||
case '\xF1':
|
||||
if (IsUTF8) {
|
||||
SB_AppendStr (&T, QuoteEnd);
|
||||
} else {
|
||||
SB_AppendChar (&T, '\'');
|
||||
}
|
||||
break;
|
||||
case '\0':
|
||||
goto Done;
|
||||
default:
|
||||
SB_AppendChar (&T, C);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Done:
|
||||
/* Copy the string back, then terminate it */
|
||||
SB_Move (Msg, &T);
|
||||
SB_Terminate (Msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void VPrepMsg (StrBuf* S, const FilePos* Pos, DiagCat Cat,
|
||||
const char* Format, va_list ap)
|
||||
/* Prepare an error/warning/notification message in S. */
|
||||
{
|
||||
StrBuf Msg = AUTO_STRBUF_INITIALIZER;
|
||||
StrBuf Loc = AUTO_STRBUF_INITIALIZER;
|
||||
|
||||
/* Determine the description for the category and its color */
|
||||
const char* Desc = DiagCatDesc[Cat];
|
||||
const char* Color;
|
||||
switch (Cat) {
|
||||
case DC_NOTE: Color = CP_Cyan (); break;
|
||||
case DC_WARN: Color = CP_Yellow (); break;
|
||||
case DC_ERR: Color = CP_BrightRed (); break;
|
||||
case DC_INT: Color = CP_BrightRed (); break;
|
||||
default: FAIL ("Unexpected Cat value"); break;
|
||||
}
|
||||
|
||||
/* Format the actual message, then replace quotes */
|
||||
SB_VPrintf (&Msg, Format, ap);
|
||||
ReplaceQuotes (&Msg);
|
||||
|
||||
/* Format the location. If the file position is valid, we use the file
|
||||
** position, otherwise the program name. This allows to print fatal
|
||||
** errors in the startup phase.
|
||||
*/
|
||||
if (Pos->Name == INVALID_STRING_ID) {
|
||||
SB_CopyStr (&Loc, ProgName);
|
||||
} else {
|
||||
SB_Printf (&Loc, "%s:%u", GetString (Pos->Name), Pos->Line);
|
||||
}
|
||||
SB_Terminate (&Loc);
|
||||
|
||||
/* Format the full message */
|
||||
SB_Printf (S, "%s%s: %s%s:%s %s%s",
|
||||
CP_White (),
|
||||
SB_GetConstBuf (&Loc),
|
||||
Color,
|
||||
Desc,
|
||||
CP_White (),
|
||||
SB_GetConstBuf (&Msg),
|
||||
CP_Reset ());
|
||||
|
||||
/* Delete the formatted message and the location string */
|
||||
SB_Done (&Loc);
|
||||
SB_Done (&Msg);
|
||||
|
||||
/* Add a new line and terminate the generated full message */
|
||||
SB_AppendChar (S, '\n');
|
||||
SB_Terminate (S);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void VPrintMsg (const FilePos* Pos, DiagCat Cat, const char* Format,
|
||||
va_list ap)
|
||||
/* Format and output an error/warning message. */
|
||||
{
|
||||
/* Format the message */
|
||||
StrBuf S = AUTO_STRBUF_INITIALIZER;
|
||||
VPrepMsg (&S, Pos, Cat, Format, ap);
|
||||
|
||||
/* Output the full message */
|
||||
fputs (SB_GetConstBuf (&S), stderr);
|
||||
|
||||
/* Delete the buffer for the full message */
|
||||
SB_Done (&S);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OutputNotes (void)
|
||||
/* Output all stored notification messages, then delete them */
|
||||
{
|
||||
unsigned I;
|
||||
for (I = 0; I < CollCount (&Notes); ++I) {
|
||||
StrBuf* S = CollAtUnchecked (&Notes, I);
|
||||
fputs (SB_GetConstBuf (S), stderr);
|
||||
FreeStrBuf (S);
|
||||
}
|
||||
CollDeleteAll (&Notes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddNote (const char* Format, ...)
|
||||
/* Add a notification message that will be output after the next error or
|
||||
** warning. There cannot be a Notification() function since Error() will
|
||||
** always terminate.
|
||||
*/
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
/* Create a new string buffer and add it to the notes */
|
||||
StrBuf* S = NewStrBuf ();
|
||||
CollAppend (&Notes, S);
|
||||
|
||||
/* Create the message in the string buffer */
|
||||
va_start (ap, Format);
|
||||
VPrepMsg (S, &NoFile, DC_NOTE, Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Warning (const char* Format, ...)
|
||||
/* Print a warning message */
|
||||
{
|
||||
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&S, Format, ap);
|
||||
VPrintMsg (&NoFile, DC_WARN, Format, ap);
|
||||
va_end (ap);
|
||||
SB_Terminate (&S);
|
||||
|
||||
fprintf (stderr, "%s: Warning: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||
|
||||
SB_Done (&S);
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Count warnings */
|
||||
++WarningCount;
|
||||
@@ -87,18 +299,16 @@ void Warning (const char* Format, ...)
|
||||
void Error (const char* Format, ...)
|
||||
/* Print an error message and die */
|
||||
{
|
||||
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&S, Format, ap);
|
||||
VPrintMsg (&NoFile, DC_ERR, Format, ap);
|
||||
va_end (ap);
|
||||
SB_Terminate (&S);
|
||||
|
||||
fprintf (stderr, "%s: Error: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||
|
||||
SB_Done (&S);
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Terminate after errors */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -107,17 +317,67 @@ void Error (const char* Format, ...)
|
||||
void Internal (const char* Format, ...)
|
||||
/* Print an internal error message and die */
|
||||
{
|
||||
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&S, Format, ap);
|
||||
VPrintMsg (&NoFile, DC_INT, Format, ap);
|
||||
va_end (ap);
|
||||
SB_Terminate (&S);
|
||||
|
||||
fprintf (stderr, "%s: Internal Error: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||
|
||||
SB_Done (&S);
|
||||
|
||||
/* Terminate after errors */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddPNote (const FilePos* Pos, const char* Format, ...)
|
||||
/* Add a notifcation message using file name and line number of the config file.
|
||||
** See comment for AddNote() above.
|
||||
*/
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
/* Create a new string buffer and add it to the notes */
|
||||
StrBuf* S = NewStrBuf ();
|
||||
CollAppend (&Notes, S);
|
||||
|
||||
/* Create the message in the string buffer */
|
||||
va_start (ap, Format);
|
||||
VPrepMsg (S, Pos, DC_NOTE, Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PWarning (const FilePos* Pos, const char* Format, ...)
|
||||
/* Print a warning message adding file name and line number of a given file */
|
||||
{
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
VPrintMsg (Pos, DC_WARN, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Count warnings */
|
||||
++WarningCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PError (const FilePos* Pos, const char* Format, ...)
|
||||
/* Print an error message adding file name and line number of a given file */
|
||||
{
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
VPrintMsg (Pos, DC_ERR, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Terminate after errors */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
/* common */
|
||||
#include "attrib.h"
|
||||
#include "filepos.h"
|
||||
|
||||
|
||||
|
||||
@@ -60,6 +61,12 @@ extern unsigned WarningCount;
|
||||
|
||||
|
||||
|
||||
void AddNote (const char* Format, ...) attribute((format(printf,1,2)));
|
||||
/* Add a notification message that will be output after the next error or
|
||||
** warning. There cannot be a Notification() function since Error() will
|
||||
** always terminate.
|
||||
*/
|
||||
|
||||
void Warning (const char* Format, ...) attribute((format(printf,1,2)));
|
||||
/* Print a warning message */
|
||||
|
||||
@@ -69,6 +76,17 @@ void Error (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
|
||||
void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
|
||||
/* Print an internal error message and die */
|
||||
|
||||
void AddPNote (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Add a notifcation message using file name and line number of the config file.
|
||||
** See comment for AddNote() above.
|
||||
*/
|
||||
|
||||
void PWarning (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Print a warning message adding file name and line number of the config file */
|
||||
|
||||
void PError (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Print an error message adding file name and line number of a given file */
|
||||
|
||||
|
||||
|
||||
/* End of error.h */
|
||||
|
||||
@@ -167,13 +167,13 @@ Import* ReadImport (FILE* F, ObjData* Obj)
|
||||
*/
|
||||
if (ObjHasFiles (I->Obj)) {
|
||||
const LineInfo* LI = GetImportPos (I);
|
||||
Error ("Invalid import size in for '%s', imported from %s:%u: 0x%02X",
|
||||
Error ("Invalid import size in for `%s', imported from %s:%u: 0x%02X",
|
||||
GetString (I->Name),
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI),
|
||||
I->AddrSize);
|
||||
} else {
|
||||
Error ("Invalid import size in for '%s', imported from %s: 0x%02X",
|
||||
Error ("Invalid import size in for `%s', imported from %s: 0x%02X",
|
||||
GetString (I->Name),
|
||||
GetObjFileName (I->Obj),
|
||||
I->AddrSize);
|
||||
@@ -200,7 +200,7 @@ Import* GenImport (unsigned Name, unsigned char AddrSize)
|
||||
/* We have no object file information and no line info for a new
|
||||
** import
|
||||
*/
|
||||
Error ("Invalid import size 0x%02X for symbol '%s'",
|
||||
Error ("Invalid import size 0x%02X for symbol `%s'",
|
||||
I->AddrSize,
|
||||
GetString (I->Name));
|
||||
}
|
||||
@@ -484,7 +484,7 @@ void InsertExport (Export* E)
|
||||
}
|
||||
} else if (AllowMultDef == 0) {
|
||||
/* Duplicate entry, this is fatal unless allowed by the user */
|
||||
Error ("Duplicate external identifier: '%s'",
|
||||
Error ("Duplicate external identifier: `%s'",
|
||||
GetString (L->Name));
|
||||
}
|
||||
return;
|
||||
@@ -663,7 +663,7 @@ long GetExportVal (const Export* E)
|
||||
{
|
||||
if (E->Expr == 0) {
|
||||
/* OOPS */
|
||||
Internal ("'%s' is an undefined external", GetString (E->Name));
|
||||
Internal ("`%s' is an undefined external", GetString (E->Name));
|
||||
}
|
||||
return GetExprVal (E->Expr);
|
||||
}
|
||||
@@ -726,9 +726,9 @@ static void CheckSymType (const Export* E)
|
||||
}
|
||||
|
||||
/* Output the diagnostic */
|
||||
Warning ("Address size mismatch for '%s': "
|
||||
"Exported from %s as '%s', "
|
||||
"import in %s as '%s'",
|
||||
Warning ("Address size mismatch for `%s': "
|
||||
"Exported from %s as `%s', "
|
||||
"import in %s as `%s'",
|
||||
GetString (E->Name),
|
||||
SB_GetConstBuf (&ExportLoc),
|
||||
ExpAddrSize,
|
||||
@@ -775,21 +775,20 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
||||
if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) {
|
||||
/* Unresolved external */
|
||||
Import* Imp = E->ImpList;
|
||||
const char* name = GetString (E->Name);
|
||||
const char* Name = GetString (E->Name);
|
||||
while (Imp) {
|
||||
unsigned J, count = CollCount (&Imp->RefLines);
|
||||
/* The count is 0 when the import was not added by an input file,
|
||||
but by the compiler itself. */
|
||||
if (count == 0) {
|
||||
fprintf (stderr, "Error: Unresolved external '%s'\n", name);
|
||||
unsigned J, Count = CollCount (&Imp->RefLines);
|
||||
/* The count is 0 when the import was not added by an input
|
||||
** file, but by the compiler itself.
|
||||
*/
|
||||
if (Count == 0) {
|
||||
Warning ("Unresolved external `%s'", Name);
|
||||
} else {
|
||||
for (J = 0; J < count; ++J) {
|
||||
for (J = 0; J < Count; ++J) {
|
||||
const LineInfo* LI = CollConstAt (&Imp->RefLines, J);
|
||||
fprintf (stderr,
|
||||
"%s:%u: Error: Unresolved external '%s'\n",
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI),
|
||||
name);
|
||||
PWarning (GetSourcePos (LI),
|
||||
"Unresolved external `%s'",
|
||||
Name);
|
||||
}
|
||||
}
|
||||
Imp = Imp->Next;
|
||||
@@ -1080,7 +1079,7 @@ void CircularRefError (const Export* E)
|
||||
/* Print an error about a circular reference using to define the given export */
|
||||
{
|
||||
const LineInfo* LI = GetExportPos (E);
|
||||
Error ("Circular reference for symbol '%s', %s:%u",
|
||||
Error ("Circular reference for symbol `%s', %s:%u",
|
||||
GetString (E->Name),
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI));
|
||||
|
||||
@@ -408,12 +408,12 @@ long GetExprVal (ExprNode* Expr)
|
||||
Error ("Argument of .BANK() isn't a label attached to a segment");
|
||||
}
|
||||
if (D.Seg->MemArea == 0) {
|
||||
Error ("Segment '%s' is referenced by .BANK(),"
|
||||
Error ("Segment `%s' is referenced by .BANK(),"
|
||||
" but not assigned to a memory area",
|
||||
GetString (D.Seg->Name));
|
||||
}
|
||||
if (D.Seg->MemArea->BankExpr == 0) {
|
||||
Error ("Memory area '%s' is referenced by .BANK(),"
|
||||
Error ("Memory area `%s' is referenced by .BANK(),"
|
||||
" but has no BANK attribute",
|
||||
GetString (D.Seg->MemArea->Name));
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name)
|
||||
ExtSym* E = GetExtSym (Tab, Name);
|
||||
if (E != 0) {
|
||||
/* We do already have a symbol with this name */
|
||||
Error ("Duplicate external symbol '%s'", GetString (Name));
|
||||
Error ("Duplicate external symbol `%s'", GetString (Name));
|
||||
}
|
||||
|
||||
/* Allocate memory for the structure */
|
||||
|
||||
@@ -112,7 +112,7 @@ static void CloseLibrary (Library* L)
|
||||
{
|
||||
/* Close the library file */
|
||||
if (fclose (L->F) != 0) {
|
||||
Error ("Error closing '%s': %s", GetString (L->Name), strerror (errno));
|
||||
Error ("Error closing `%s': %s", GetString (L->Name), strerror (errno));
|
||||
}
|
||||
L->F = 0;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ static void LibSeek (Library* L, unsigned long Offs)
|
||||
/* Do a seek in the library checking for errors */
|
||||
{
|
||||
if (fseek (L->F, Offs, SEEK_SET) != 0) {
|
||||
Error ("Seek error in '%s' (%lu): %s",
|
||||
Error ("Seek error in `%s' (%lu): %s",
|
||||
GetString (L->Name), Offs, strerror (errno));
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ static void LibReadHeader (Library* L)
|
||||
L->Header.Magic = LIB_MAGIC;
|
||||
L->Header.Version = Read16 (L->F);
|
||||
if (L->Header.Version != LIB_VERSION) {
|
||||
Error ("Wrong data version in '%s'", GetString (L->Name));
|
||||
Error ("Wrong data version in `%s'", GetString (L->Name));
|
||||
}
|
||||
L->Header.Flags = Read16 (L->F);
|
||||
L->Header.IndexOffs = Read32 (L->F);
|
||||
@@ -171,12 +171,12 @@ static void LibReadObjHeader (Library* L, ObjData* O)
|
||||
{
|
||||
O->Header.Magic = Read32 (L->F);
|
||||
if (O->Header.Magic != OBJ_MAGIC) {
|
||||
Error ("Object file '%s' in library '%s' is invalid",
|
||||
Error ("Object file `%s' in library `%s' is invalid",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
}
|
||||
O->Header.Version = Read16 (L->F);
|
||||
if (O->Header.Version != OBJ_VERSION) {
|
||||
Error ("Object file '%s' in library '%s' has wrong version",
|
||||
Error ("Object file `%s' in library `%s' has wrong version",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
}
|
||||
O->Header.Flags = Read16 (L->F);
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "asserts.h"
|
||||
#include "binfmt.h"
|
||||
#include "condes.h"
|
||||
#include "consprop.h"
|
||||
#include "config.h"
|
||||
#include "dbgfile.h"
|
||||
#include "error.h"
|
||||
@@ -130,6 +131,7 @@ static void Usage (void)
|
||||
"Long options:\n"
|
||||
" --allow-multiple-definition\tAllow multiple definitions\n"
|
||||
" --cfg-path path\t\tSpecify a config file search path\n"
|
||||
" --color [on|auto|off]\t\tColor diagnostics (default: auto)\n"
|
||||
" --config name\t\t\tUse linker config file\n"
|
||||
" --dbgfile name\t\tGenerate debug information\n"
|
||||
" --define sym=val\t\tDefine a symbol\n"
|
||||
@@ -141,6 +143,7 @@ static void Usage (void)
|
||||
" --lib-path path\t\tSpecify a library search path\n"
|
||||
" --mapfile name\t\tCreate a map file\n"
|
||||
" --module-id id\t\tSpecify a module id\n"
|
||||
" --no-utf8\t\t\tDisable use of UTF-8 in diagnostics\n"
|
||||
" --obj file\t\t\tLink this object file\n"
|
||||
" --obj-path path\t\tSpecify an object file search path\n"
|
||||
" --start-addr addr\t\tSet the default start address\n"
|
||||
@@ -216,13 +219,13 @@ static void LinkFile (const char* Name, FILETYPE Type)
|
||||
|
||||
/* We must have a valid name now */
|
||||
if (PathName == 0) {
|
||||
Error ("Input file '%s' not found", Name);
|
||||
Error ("Input file `%s' not found", Name);
|
||||
}
|
||||
|
||||
/* Try to open the file */
|
||||
F = fopen (PathName, "rb");
|
||||
if (F == 0) {
|
||||
Error ("Cannot open '%s': %s", PathName, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", PathName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Read the magic word */
|
||||
@@ -248,7 +251,7 @@ static void LinkFile (const char* Name, FILETYPE Type)
|
||||
|
||||
default:
|
||||
fclose (F);
|
||||
Error ("File '%s' has unknown type", PathName);
|
||||
Error ("File `%s' has unknown type", PathName);
|
||||
|
||||
}
|
||||
|
||||
@@ -310,6 +313,19 @@ static void OptCfgPath (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
|
||||
static void OptColor (const char* Opt, const char* Arg)
|
||||
/* Handle the --color option */
|
||||
{
|
||||
ColorMode Mode = CP_Parse (Arg);
|
||||
if (Mode == CM_INVALID) {
|
||||
Error ("Invalid argument to %s: %s", Opt, Arg);
|
||||
} else {
|
||||
CP_SetColorMode (Mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Define the config file */
|
||||
{
|
||||
@@ -324,7 +340,7 @@ static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
|
||||
PathName = SearchFile (CfgDefaultPath, Arg);
|
||||
}
|
||||
if (PathName == 0) {
|
||||
Error ("Cannot find config file '%s'", Arg);
|
||||
Error ("Cannot find config file `%s'", Arg);
|
||||
}
|
||||
|
||||
/* Read the config */
|
||||
@@ -378,7 +394,7 @@ static void OptForceImport (const char* Opt attribute ((unused)), const char* Ar
|
||||
/* Get the address size and check it */
|
||||
unsigned char AddrSize = AddrSizeFromStr (ColPos+1);
|
||||
if (AddrSize == ADDR_SIZE_INVALID) {
|
||||
Error ("Invalid address size '%s'", ColPos+1);
|
||||
Error ("Invalid address size `%s'", ColPos+1);
|
||||
}
|
||||
|
||||
/* Create a copy of the argument */
|
||||
@@ -457,6 +473,15 @@ static void OptModuleId (const char* Opt, const char* Arg)
|
||||
|
||||
|
||||
|
||||
static void OptNoUtf8 (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Handle the --no-utf8 option */
|
||||
{
|
||||
CP_DisableUTF8 ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptObj (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Link an object file */
|
||||
{
|
||||
@@ -519,7 +544,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Map the target name to a target id */
|
||||
Target = FindTarget (Arg);
|
||||
if (Target == TGT_UNKNOWN) {
|
||||
Error ("Invalid target name: '%s'", Arg);
|
||||
Error ("Invalid target name: `%s'", Arg);
|
||||
}
|
||||
|
||||
/* Set the target binary format */
|
||||
@@ -536,7 +561,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||
PathName = SearchFile (CfgDefaultPath, SB_GetBuf (&FileName));
|
||||
}
|
||||
if (PathName == 0) {
|
||||
Error ("Cannot find config file '%s'", SB_GetBuf (&FileName));
|
||||
Error ("Cannot find config file `%s'", SB_GetBuf (&FileName));
|
||||
}
|
||||
|
||||
/* Free file name memory */
|
||||
@@ -623,12 +648,13 @@ static void CmdlOptTarget (const char* Opt attribute ((unused)), const char* Arg
|
||||
|
||||
|
||||
|
||||
static void ParseCommandLine(void)
|
||||
static void ParseCommandLine (void)
|
||||
{
|
||||
/* Program long options */
|
||||
static const LongOpt OptTab[] = {
|
||||
{ "--allow-multiple-definition", 0, OptMultDef },
|
||||
{ "--cfg-path", 1, OptCfgPath },
|
||||
{ "--color", 1, OptColor },
|
||||
{ "--config", 1, CmdlOptConfig },
|
||||
{ "--dbgfile", 1, OptDbgFile },
|
||||
{ "--define", 1, OptDefine },
|
||||
@@ -640,6 +666,7 @@ static void ParseCommandLine(void)
|
||||
{ "--lib-path", 1, OptLibPath },
|
||||
{ "--mapfile", 1, OptMapFile },
|
||||
{ "--module-id", 1, OptModuleId },
|
||||
{ "--no-utf8", 0, OptNoUtf8 },
|
||||
{ "--obj", 1, OptObj },
|
||||
{ "--obj-path", 1, OptObjPath },
|
||||
{ "--start-addr", 1, OptStartAddr },
|
||||
@@ -800,6 +827,9 @@ int main (int argc, char* argv [])
|
||||
{
|
||||
unsigned MemoryAreaOverflows;
|
||||
|
||||
/* Initialize console output */
|
||||
CP_Init ();
|
||||
|
||||
/* Initialize the cmdline module */
|
||||
InitCmdLine (&argc, &argv, "ld65");
|
||||
|
||||
@@ -856,7 +886,7 @@ int main (int argc, char* argv [])
|
||||
}
|
||||
|
||||
if (WarningCount > 0 && WarningsAsErrors) {
|
||||
Error("Warnings as errors");
|
||||
Error ("Warnings as errors");
|
||||
}
|
||||
|
||||
/* Create the output file */
|
||||
|
||||
@@ -67,7 +67,7 @@ void CreateMapFile (int ShortMap)
|
||||
/* Open the map file */
|
||||
FILE* F = fopen (MapFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create map file '%s': %s", MapFileName, strerror (errno));
|
||||
Error ("Cannot create map file `%s': %s", MapFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Write a modules list */
|
||||
@@ -132,7 +132,7 @@ void CreateMapFile (int ShortMap)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing map file '%s': %s", MapFileName, strerror (errno));
|
||||
Error ("Error closing map file `%s': %s", MapFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ void CreateLabelFile (void)
|
||||
/* Open the label file */
|
||||
FILE* F = fopen (LabelFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create label file '%s': %s", LabelFileName, strerror (errno));
|
||||
Error ("Cannot create label file `%s': %s", LabelFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Print the labels for the export symbols */
|
||||
@@ -155,6 +155,6 @@ void CreateLabelFile (void)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing label file '%s': %s", LabelFileName, strerror (errno));
|
||||
Error ("Error closing label file `%s': %s", LabelFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,7 +807,7 @@ static void O65WriteSeg (O65Desc* D, SegDesc** Seg, unsigned Count, int DoWrite)
|
||||
|
||||
/* Check the size of the segment for overflow */
|
||||
if ((D->Header.Mode & MF_SIZE_MASK) == MF_SIZE_16BIT && D->SegSize > 0xFFFF) {
|
||||
Error ("Segment overflow in file '%s'", D->Filename);
|
||||
Error ("Segment overflow in file `%s'", D->Filename);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -960,7 +960,7 @@ static void O65WriteExports (O65Desc* D)
|
||||
|
||||
/* Bail out if we cannot handle the expression */
|
||||
if (ED.TooComplex) {
|
||||
Error ("Expression for symbol '%s' is too complex", Name);
|
||||
Error ("Expression for symbol `%s' is too complex", Name);
|
||||
}
|
||||
|
||||
/* Determine the segment id for the expression */
|
||||
@@ -979,7 +979,7 @@ static void O65WriteExports (O65Desc* D)
|
||||
/* For some reason, we didn't find this segment in the list of
|
||||
** segments written to the o65 file.
|
||||
*/
|
||||
Error ("Segment for symbol '%s' is undefined", Name);
|
||||
Error ("Segment for symbol `%s' is undefined", Name);
|
||||
}
|
||||
SegmentID = O65SegType (Seg);
|
||||
|
||||
@@ -1209,7 +1209,7 @@ void O65SetExport (O65Desc* D, unsigned Ident)
|
||||
*/
|
||||
Export* E = FindExport (Ident);
|
||||
if (E == 0 || IsUnresolvedExport (E)) {
|
||||
Error ("Unresolved export: '%s'", GetString (Ident));
|
||||
Error ("Unresolved export: `%s'", GetString (Ident));
|
||||
}
|
||||
|
||||
/* Insert the entry into the table */
|
||||
@@ -1372,7 +1372,7 @@ void O65WriteTarget (O65Desc* D, File* F)
|
||||
/* Open the file */
|
||||
D->F = fopen (D->Filename, "wb");
|
||||
if (D->F == 0) {
|
||||
Error ("Cannot open '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Keep the user happy */
|
||||
@@ -1430,7 +1430,7 @@ void O65WriteTarget (O65Desc* D, File* F)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (D->F) != 0) {
|
||||
Error ("Cannot write to '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Reset the file and filename */
|
||||
|
||||
@@ -184,7 +184,7 @@ unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
|
||||
/* Convert a local string id into a global one and return it. */
|
||||
{
|
||||
if (Index >= O->StringCount) {
|
||||
Error ("Invalid string index (%u) in module '%s'",
|
||||
Error ("Invalid string index (%u) in module `%s'",
|
||||
Index, GetObjFileName (O));
|
||||
}
|
||||
return O->Strings[Index];
|
||||
@@ -214,7 +214,7 @@ struct Section* GetObjSection (const ObjData* O, unsigned Id)
|
||||
/* Get a section from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Sections)) {
|
||||
Error ("Invalid section index (%u) in module '%s'",
|
||||
Error ("Invalid section index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Sections, Id);
|
||||
@@ -226,7 +226,7 @@ struct Import* GetObjImport (const ObjData* O, unsigned Id)
|
||||
/* Get an import from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Imports)) {
|
||||
Error ("Invalid import index (%u) in module '%s'",
|
||||
Error ("Invalid import index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Imports, Id);
|
||||
@@ -238,7 +238,7 @@ struct Export* GetObjExport (const ObjData* O, unsigned Id)
|
||||
/* Get an export from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Exports)) {
|
||||
Error ("Invalid export index (%u) in module '%s'",
|
||||
Error ("Invalid export index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Exports, Id);
|
||||
@@ -250,7 +250,7 @@ struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id)
|
||||
/* Get a debug symbol from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->DbgSyms)) {
|
||||
Error ("Invalid debug symbol index (%u) in module '%s'",
|
||||
Error ("Invalid debug symbol index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->DbgSyms, Id);
|
||||
@@ -262,7 +262,7 @@ struct Scope* GetObjScope (const ObjData* O, unsigned Id)
|
||||
/* Get a scope from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Scopes)) {
|
||||
Error ("Invalid scope index (%u) in module '%s'",
|
||||
Error ("Invalid scope index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Scopes, Id);
|
||||
|
||||
@@ -67,7 +67,7 @@ static unsigned GetModule (const char* Name)
|
||||
/* Make a module name from the file name */
|
||||
const char* Module = FindName (Name);
|
||||
if (*Module == 0) {
|
||||
Error ("Cannot make module name from '%s'", Name);
|
||||
Error ("Cannot make module name from `%s'", Name);
|
||||
}
|
||||
return GetStringId (Module);
|
||||
}
|
||||
@@ -79,7 +79,7 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
||||
{
|
||||
H->Version = Read16 (Obj);
|
||||
if (H->Version != OBJ_VERSION) {
|
||||
Error ("Object file '%s' has wrong version, expected %08X, got %08X",
|
||||
Error ("Object file `%s' has wrong version, expected %08X, got %08X",
|
||||
Name, OBJ_VERSION, H->Version);
|
||||
}
|
||||
H->Flags = Read16 (Obj);
|
||||
|
||||
@@ -76,49 +76,6 @@ static FILE* InputFile = 0;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Error handling */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void CfgWarning (const FilePos* Pos, const char* Format, ...)
|
||||
/* Print a warning message adding file name and line number of a given file */
|
||||
{
|
||||
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&Buf, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
Warning ("%s:%u: %s",
|
||||
GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
|
||||
SB_Done (&Buf);
|
||||
|
||||
/* Count warnings */
|
||||
++WarningCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CfgError (const FilePos* Pos, const char* Format, ...)
|
||||
/* Print an error message adding file name and line number of a given file */
|
||||
{
|
||||
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&Buf, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
Error ("%s:%u: %s",
|
||||
GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
|
||||
SB_Done (&Buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
@@ -170,7 +127,7 @@ static void StrVal (void)
|
||||
|
||||
case EOF:
|
||||
case '\n':
|
||||
CfgError (&CfgErrorPos, "Unterminated string");
|
||||
PError (&CfgErrorPos, "Unterminated string");
|
||||
break;
|
||||
|
||||
case '%':
|
||||
@@ -180,7 +137,7 @@ static void StrVal (void)
|
||||
case EOF:
|
||||
case '\n':
|
||||
case '\"':
|
||||
CfgError (&CfgErrorPos, "Unterminated '%%' escape sequence");
|
||||
PError (&CfgErrorPos, "Unterminated `%%' escape sequence");
|
||||
break;
|
||||
|
||||
case '%':
|
||||
@@ -198,8 +155,8 @@ static void StrVal (void)
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Unknown escape sequence '%%%c'", C);
|
||||
PWarning (&CfgErrorPos,
|
||||
"Unknown escape sequence `%%%c'", C);
|
||||
SB_AppendChar (&CfgSVal, '%');
|
||||
SB_AppendChar (&CfgSVal, C);
|
||||
NextChar ();
|
||||
@@ -255,7 +212,7 @@ Again:
|
||||
if (C == '$') {
|
||||
NextChar ();
|
||||
if (!isxdigit (C)) {
|
||||
CfgError (&CfgErrorPos, "Hex digit expected");
|
||||
PError (&CfgErrorPos, "Hex digit expected");
|
||||
}
|
||||
CfgIVal = 0;
|
||||
while (isxdigit (C)) {
|
||||
@@ -383,7 +340,7 @@ Again:
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid format specification");
|
||||
PError (&CfgErrorPos, "Invalid format specification");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -392,7 +349,7 @@ Again:
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid character '%c'", C);
|
||||
PError (&CfgErrorPos, "Invalid character `%c'", C);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -403,7 +360,7 @@ void CfgConsume (cfgtok_t T, const char* Msg)
|
||||
/* Skip a token, print an error message if not found */
|
||||
{
|
||||
if (CfgTok != T) {
|
||||
CfgError (&CfgErrorPos, "%s", Msg);
|
||||
PError (&CfgErrorPos, "%s", Msg);
|
||||
}
|
||||
CfgNextTok ();
|
||||
}
|
||||
@@ -413,7 +370,7 @@ void CfgConsume (cfgtok_t T, const char* Msg)
|
||||
void CfgConsumeSemi (void)
|
||||
/* Consume a semicolon */
|
||||
{
|
||||
CfgConsume (CFGTOK_SEMI, "';' expected");
|
||||
CfgConsume (CFGTOK_SEMI, "`;' expected");
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +378,7 @@ void CfgConsumeSemi (void)
|
||||
void CfgConsumeColon (void)
|
||||
/* Consume a colon */
|
||||
{
|
||||
CfgConsume (CFGTOK_COLON, "':' expected");
|
||||
CfgConsume (CFGTOK_COLON, "`:' expected");
|
||||
}
|
||||
|
||||
|
||||
@@ -450,7 +407,7 @@ void CfgAssureInt (void)
|
||||
/* Make sure the next token is an integer */
|
||||
{
|
||||
if (CfgTok != CFGTOK_INTCON) {
|
||||
CfgError (&CfgErrorPos, "Integer constant expected");
|
||||
PError (&CfgErrorPos, "Integer constant expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +417,7 @@ void CfgAssureStr (void)
|
||||
/* Make sure the next token is a string constant */
|
||||
{
|
||||
if (CfgTok != CFGTOK_STRCON) {
|
||||
CfgError (&CfgErrorPos, "String constant expected");
|
||||
PError (&CfgErrorPos, "String constant expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +427,7 @@ void CfgAssureIdent (void)
|
||||
/* Make sure the next token is an identifier */
|
||||
{
|
||||
if (CfgTok != CFGTOK_IDENT) {
|
||||
CfgError (&CfgErrorPos, "Identifier expected");
|
||||
PError (&CfgErrorPos, "Identifier expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,12 +437,34 @@ void CfgRangeCheck (unsigned long Lo, unsigned long Hi)
|
||||
/* Check the range of CfgIVal */
|
||||
{
|
||||
if (CfgIVal < Lo || CfgIVal > Hi) {
|
||||
CfgError (&CfgErrorPos, "Range error");
|
||||
PError (&CfgErrorPos, "Range error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void SpecialTokenHelp (const IdentTok* Table, unsigned Size, StrBuf* Msg)
|
||||
/* Create a help message for errors in CfgSpecialToken. StrBuf must be
|
||||
** initialized and is overwritten.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
SB_AppendStr (Msg, "You may use one of `");
|
||||
for (I = 0; I < Size; ++I) {
|
||||
if (I == Size - 1) {
|
||||
SB_AppendStr (Msg, " or `");
|
||||
} else if (I > 0) {
|
||||
SB_AppendStr (Msg, ", `");
|
||||
}
|
||||
SB_AppendStr (Msg, Table[I].Ident);
|
||||
SB_AppendChar (Msg, '\'');
|
||||
}
|
||||
SB_Terminate (Msg); /* So we may use %s */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
|
||||
/* Map an identifier to one of the special tokens in the table */
|
||||
{
|
||||
@@ -504,13 +483,22 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found */
|
||||
CfgError (&CfgErrorPos, "%s expected, got '%s'", Name, SB_GetConstBuf(&CfgSVal));
|
||||
/* Not found. Add a helpful note about the possible names only if
|
||||
** there is a not too large number of them.
|
||||
*/
|
||||
if (Size > 0 && Size <= 5) {
|
||||
StrBuf Note = AUTO_STRBUF_INITIALIZER;
|
||||
SpecialTokenHelp (Table, Size, &Note);
|
||||
AddPNote (&CfgErrorPos, "%s", SB_GetConstBuf (&Note));
|
||||
SB_Done (&Note);
|
||||
}
|
||||
PError (&CfgErrorPos, "%s expected but got `%s'", Name,
|
||||
SB_GetConstBuf (&CfgSVal));
|
||||
return;
|
||||
}
|
||||
|
||||
/* No identifier */
|
||||
CfgError (&CfgErrorPos, "%s expected", Name);
|
||||
PError (&CfgErrorPos, "%s expected", Name);
|
||||
}
|
||||
|
||||
|
||||
@@ -531,7 +519,7 @@ void CfgBoolToken (void)
|
||||
} else {
|
||||
/* We expected an integer here */
|
||||
if (CfgTok != CFGTOK_INTCON) {
|
||||
CfgError (&CfgErrorPos, "Boolean value expected");
|
||||
PError (&CfgErrorPos, "Boolean value expected");
|
||||
}
|
||||
CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE;
|
||||
}
|
||||
@@ -561,7 +549,7 @@ void CfgOpenInput (void)
|
||||
/* Open the file */
|
||||
InputFile = fopen (CfgName, "r");
|
||||
if (InputFile == 0) {
|
||||
Error ("Cannot open '%s': %s", CfgName, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", CfgName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Initialize variables */
|
||||
|
||||
@@ -186,12 +186,6 @@ extern FilePos CfgErrorPos;
|
||||
|
||||
|
||||
|
||||
void CfgWarning (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Print a warning message adding file name and line number of the config file */
|
||||
|
||||
void CfgError (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Print an error message adding file name and line number of a given file */
|
||||
|
||||
void CfgNextTok (void);
|
||||
/* Read the next token from the input stream */
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ void PrintDbgScopes (FILE* F)
|
||||
case SCOPE_ENUM: fputs (",type=enum", F); break;
|
||||
|
||||
default:
|
||||
Error ("Module '%s': Unknown scope type %u",
|
||||
Error ("Module `%s': Unknown scope type %u",
|
||||
GetObjFileName (O), S->Type);
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName)
|
||||
if (ObjName == 0) {
|
||||
ObjName = "[linker generated]";
|
||||
}
|
||||
Error ("Module '%s': Type mismatch for segment '%s'", ObjName,
|
||||
Error ("Module `%s': Type mismatch for segment `%s'", ObjName,
|
||||
GetString (Name));
|
||||
}
|
||||
}
|
||||
@@ -226,13 +226,13 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||
if (Sec->Alignment > 1) {
|
||||
Alignment = LeastCommonMultiple (S->Alignment, Sec->Alignment);
|
||||
if (Alignment > MAX_ALIGNMENT) {
|
||||
Error ("Combined alignment for segment '%s' is %lu which exceeds "
|
||||
"%lu. Last module requiring alignment was '%s'.",
|
||||
Error ("Combined alignment for segment `%s' is %lu which exceeds "
|
||||
"%lu. Last module requiring alignment was `%s'.",
|
||||
GetString (Name), Alignment, MAX_ALIGNMENT,
|
||||
GetObjFileName (O));
|
||||
} else if (Alignment >= LARGE_ALIGNMENT && Alignment > S->Alignment && Alignment > Sec->Alignment && !LargeAlignment) {
|
||||
Warning ("Combined alignment for segment '%s' is suspiciously "
|
||||
"large (%lu). Last module requiring alignment was '%s'.",
|
||||
Warning ("Combined alignment for segment `%s' is suspiciously "
|
||||
"large (%lu). Last module requiring alignment was `%s'.",
|
||||
GetString (Name), Alignment, GetObjFileName (O));
|
||||
}
|
||||
S->Alignment = Alignment;
|
||||
@@ -270,7 +270,7 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||
break;
|
||||
|
||||
default:
|
||||
Error ("Unknown fragment type in module '%s', segment '%s': %02X",
|
||||
Error ("Unknown fragment type in module `%s', segment `%s': %02X",
|
||||
GetObjFileName (O), GetString (S->Name), Type);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
@@ -306,9 +306,11 @@ Segment* SegFind (unsigned Name)
|
||||
|
||||
|
||||
|
||||
int IsBSSType (Segment* S)
|
||||
/* Check if the given segment is a BSS style segment, that is, it does not
|
||||
** contain non-zero data.
|
||||
Section* GetNonBSSSection (Segment* S)
|
||||
/* Used when checking a BSS style segment for initialized data. Will walk over
|
||||
** all sections in S and check if any of them contains initialized data. If so,
|
||||
** the first section containing initialized data is returned. Otherwise the
|
||||
** function returns NULL.
|
||||
*/
|
||||
{
|
||||
/* Loop over all sections */
|
||||
@@ -326,18 +328,20 @@ int IsBSSType (Segment* S)
|
||||
unsigned long Count = F->Size;
|
||||
while (Count--) {
|
||||
if (*Data++ != 0) {
|
||||
return 0;
|
||||
return Sec;
|
||||
}
|
||||
}
|
||||
} else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
|
||||
if (GetExprVal (F->Expr) != 0) {
|
||||
return 0;
|
||||
return Sec;
|
||||
}
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
/* No uninitialized data found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -502,19 +506,19 @@ void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void*
|
||||
break;
|
||||
|
||||
case SEG_EXPR_RANGE_ERROR:
|
||||
Error ("Range error in module '%s', line %u",
|
||||
Error ("Range error in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
|
||||
case SEG_EXPR_TOO_COMPLEX:
|
||||
Error ("Expression too complex in module '%s', line %u",
|
||||
Error ("Expression too complex in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
|
||||
case SEG_EXPR_INVALID:
|
||||
Error ("Invalid expression in module '%s', line %u",
|
||||
Error ("Invalid expression in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
@@ -638,11 +642,9 @@ void PrintDbgSegments (FILE* F)
|
||||
fprintf (F, ",oname=\"%s\",ooffs=%lu",
|
||||
S->OutputName, S->OutputOffs);
|
||||
}
|
||||
if (S->MemArea) {
|
||||
if (S->MemArea->BankExpr) {
|
||||
if (IsConstExpr (S->MemArea->BankExpr)) {
|
||||
fprintf (F, ",bank=%lu", GetExprVal(S->MemArea->BankExpr));
|
||||
}
|
||||
if (S->MemArea && S->MemArea->BankExpr) {
|
||||
if (IsConstExpr (S->MemArea->BankExpr)) {
|
||||
fprintf (F, ",bank=%lu", GetExprVal (S->MemArea->BankExpr));
|
||||
}
|
||||
}
|
||||
fputc ('\n', F);
|
||||
@@ -664,7 +666,7 @@ void CheckSegments (void)
|
||||
|
||||
/* Check it */
|
||||
if (S->Size > 0 && S->Dumped == 0) {
|
||||
Error ("Missing memory area assignment for segment '%s'",
|
||||
Error ("Missing memory area assignment for segment `%s'",
|
||||
GetString (S->Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,9 +131,11 @@ Section* ReadSection (FILE* F, struct ObjData* O);
|
||||
Segment* SegFind (unsigned Name);
|
||||
/* Return the given segment or NULL if not found. */
|
||||
|
||||
int IsBSSType (Segment* S);
|
||||
/* Check if the given segment is a BSS style segment, that is, it does not
|
||||
** contain non-zero data.
|
||||
Section* GetNonBSSSection (Segment* S);
|
||||
/* Used when checking a BSS style segment for initialized data. Will walk over
|
||||
** all sections in S and check if any of them contains initialized data. If so,
|
||||
** the first section containing initialized data is returned. Otherwise the
|
||||
** function returns NULL.
|
||||
*/
|
||||
|
||||
void SegDump (void);
|
||||
|
||||
@@ -120,7 +120,9 @@ void XexSetRunAd (XexDesc* D, Import *RunAd)
|
||||
D->RunAd = RunAd;
|
||||
}
|
||||
|
||||
XexInitAd* XexSearchInitMem(XexDesc* D, MemoryArea *InitMem)
|
||||
|
||||
|
||||
XexInitAd* XexSearchInitMem (XexDesc* D, MemoryArea *InitMem)
|
||||
{
|
||||
XexInitAd* I;
|
||||
for (I=D->InitAds; I != 0; I=I->next)
|
||||
@@ -132,6 +134,7 @@ XexInitAd* XexSearchInitMem(XexDesc* D, MemoryArea *InitMem)
|
||||
}
|
||||
|
||||
|
||||
|
||||
int XexAddInitAd (XexDesc* D, MemoryArea *InitMem, Import *InitAd)
|
||||
/* Sets and INITAD for the given memory area */
|
||||
{
|
||||
@@ -149,6 +152,8 @@ int XexAddInitAd (XexDesc* D, MemoryArea *InitMem, Import *InitAd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
unsigned long Offs attribute ((unused)),
|
||||
void* Data)
|
||||
@@ -287,7 +292,7 @@ static unsigned long XexWriteMem (XexDesc* D, MemoryArea* M)
|
||||
if (DoWrite || (M->Flags & MF_FILL) != 0) {
|
||||
/* "overwrite" segments are not supported */
|
||||
if (S->Flags & SF_OVERWRITE) {
|
||||
Error ("ATARI file format does not support overwrite for segment '%s'.",
|
||||
Error ("ATARI file format does not support overwrite for segment `%s'.",
|
||||
GetString (S->Name));
|
||||
} else {
|
||||
XexStartSegment (D, Addr, NewAddr - Addr);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -61,8 +61,8 @@ define CPUDETECT_template
|
||||
|
||||
$(WORKDIR)/$1-cpudetect.bin: cpudetect.s $1-cpudetect.ref $(ISEQUAL)
|
||||
$(if $(QUIET),echo asm/$1-cpudetect.bin)
|
||||
$(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< $(CATERR)
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib $(CATERR)
|
||||
$(CA65) --no-utf8 -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< $(CATERR)
|
||||
$(LD65) --no-utf8 -t none -o $$@ $$(@:.bin=.o) none.lib $(CATERR)
|
||||
$(ISEQUAL) $1-cpudetect.ref $$@
|
||||
|
||||
endef # CPUDETECT_template
|
||||
@@ -70,7 +70,7 @@ endef # CPUDETECT_template
|
||||
$(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu))))
|
||||
|
||||
$(WORKDIR)/%.o: %.s | $(WORKDIR)
|
||||
$(CA65) -l $(@:.o=.lst) -o $@ $< $(NULLOUT) $(CATERR)
|
||||
$(CA65) --no-utf8 -l $(@:.o=.lst) -o $@ $< $(NULLOUT) $(CATERR)
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
|
||||
; just emit to bss for now, this way the output wont get checked, which is
|
||||
; fine - we only want to see if the assembler accepts all the opcodes it
|
||||
; should accept for the current CPU mode
|
||||
.bss
|
||||
.code
|
||||
|
||||
.if (.cpu .bitand CPU_ISET_6502)
|
||||
.scope
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
11
test/asm/listing/170-ld-errormsg.cfg
Normal file
11
test/asm/listing/170-ld-errormsg.cfg
Normal file
@@ -0,0 +1,11 @@
|
||||
MEMORY {
|
||||
ZP: file = "", start = $80, size = $001F;
|
||||
MAIN: file = %O, start = %S, size = $1000;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = rw;
|
||||
DATA: load = MAIN, type = rw;
|
||||
BSS: load = MAIN, type = bss;
|
||||
}
|
||||
6
test/asm/listing/170-ld-errormsg.s
Normal file
6
test/asm/listing/170-ld-errormsg.s
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
.code
|
||||
.byte 5
|
||||
.bss
|
||||
.byte 3
|
||||
|
||||
11
test/asm/listing/171-ld-errormsg.cfg
Normal file
11
test/asm/listing/171-ld-errormsg.cfg
Normal file
@@ -0,0 +1,11 @@
|
||||
MEMORY {
|
||||
ZP: file = "", start = $80, size = $001F;
|
||||
MAIN: file = %O, start = %S, size = $100;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = rw;
|
||||
DATA: load = MAIN, type = rw;
|
||||
BSS: load = MAIN, type = bss;
|
||||
}
|
||||
4
test/asm/listing/171-ld-errormsg.s
Normal file
4
test/asm/listing/171-ld-errormsg.s
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
.code
|
||||
.res 256, 3
|
||||
.byte $FF
|
||||
6
test/asm/listing/172-ld-errormsg.cfg
Normal file
6
test/asm/listing/172-ld-errormsg.cfg
Normal file
@@ -0,0 +1,6 @@
|
||||
MEMORY {
|
||||
MAIN: file = %O, start = %S, size = $1000;
|
||||
}
|
||||
SEGMENTS {
|
||||
CODE: load = MAIN, type = rwx;
|
||||
}
|
||||
4
test/asm/listing/172-ld-errormsg.s
Normal file
4
test/asm/listing/172-ld-errormsg.s
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
.bss
|
||||
.byte 3
|
||||
|
||||
28
test/asm/listing/666-bug2208.s
Normal file
28
test/asm/listing/666-bug2208.s
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
; #2208 - Current ca65 generates different code for msbasic
|
||||
|
||||
.setcpu "6502"
|
||||
|
||||
ZP_START2 = $04
|
||||
|
||||
INPUTBUFFERX = INPUTBUFFER & $FF00
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
;.feature org_per_seg
|
||||
.zeropage
|
||||
|
||||
; if not present, both 2.18 and head produce a absolute,x instruction
|
||||
; if present, 2.18 produces a zp,x instruction - but head uses abs,x!
|
||||
.org ZP_START2
|
||||
|
||||
INPUTBUFFER:
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.segment "CODE"
|
||||
|
||||
.byte $f0, $f1, $f2, $f3 ; just some data to search for
|
||||
; BUG: this will wrongly assembly into a 3-byte instruction
|
||||
; under certain conditions
|
||||
lda INPUTBUFFERX,x
|
||||
@@ -73,21 +73,21 @@ $(WORKDIR)/$1.bin: $1.s $(ISEQUAL)
|
||||
|
||||
# compile without generating listing
|
||||
ifeq ($(wildcard control/$1.err),)
|
||||
$(CA65) -t none --no-utf8 -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2)
|
||||
$(CA65) --no-utf8 -t none --no-utf8 -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
ifeq ($(wildcard $1.cfg),)
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
$(LD65) --no-utf8 -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
else
|
||||
$(LD65) -C $$(<:.s=.cfg) -o $$@ $$(@:.bin=.o) > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
$(LD65) --no-utf8 -C $$(<:.s=.cfg) -o $$@ $$(@:.bin=.o) > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
endif
|
||||
endif
|
||||
else
|
||||
$(CA65) -t none --no-utf8 -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2) || $(TRUE)
|
||||
$(CA65) --no-utf8 -t none --no-utf8 -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2) || $(TRUE)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
ifeq ($(wildcard $1.cfg),)
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
$(LD65) --no-utf8 -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
else
|
||||
$(LD65) -C $$(<:.s=.cfg) -o $$@ $$(@:.bin=.o) > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
$(LD65) --no-utf8 -C $$(<:.s=.cfg) -o $$@ $$(@:.bin=.o) > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -144,21 +144,21 @@ endif
|
||||
|
||||
# compile with listing file
|
||||
ifeq ($(wildcard control/$1.err),)
|
||||
$(CA65) -t none --no-utf8 -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2)
|
||||
$(CA65) --no-utf8 -t none --no-utf8 -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
ifeq ($(wildcard $1.cfg),)
|
||||
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
$(LD65) --no-utf8 -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
else
|
||||
$(LD65) -C $$(<:.s=.cfg) -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
$(LD65) --no-utf8 -C $$(<:.s=.cfg) -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
endif
|
||||
endif
|
||||
else
|
||||
$(CA65) -t none --no-utf8 -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2) || $(TRUE)
|
||||
$(CA65) --no-utf8 -t none --no-utf8 -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2) || $(TRUE)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
ifeq ($(wildcard $1.cfg),)
|
||||
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
$(LD65) --no-utf8 -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
else
|
||||
$(LD65) -C $$(<:.s=.cfg) -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
$(LD65) --no-utf8 -C $$(<:.s=.cfg) -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -212,7 +212,7 @@ $(foreach listing,$(LISTING_TESTS),$(eval $(call LISTING_template,$(listing))))
|
||||
|
||||
|
||||
$(WORKDIR)/%.o: %.s | $(WORKDIR)
|
||||
$(CA65) -l $(@:.o=.lst) -o $@ $<
|
||||
$(CA65) --no-utf8 -l $(@:.o=.lst) -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
||||
0
test/asm/listing/control/171-ld-errormsg.err
Normal file
0
test/asm/listing/control/171-ld-errormsg.err
Normal file
0
test/asm/listing/control/172-ld-errormsg.err
Normal file
0
test/asm/listing/control/172-ld-errormsg.err
Normal file
@@ -1,40 +1,40 @@
|
||||
ld65: Warning: 030-assert-success.s:3: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:4: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:6: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:7: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:12: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:13: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:15: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:16: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:18: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:19: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:23: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:24: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:26: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:27: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:29: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:30: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:35: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:36: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:38: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:39: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:45: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:46: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:48: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:49: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:51: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:52: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:54: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:55: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:60: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:61: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:65: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:66: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:68: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:69: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:71: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:72: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:74: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:75: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:77: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:78: Code not at $8000
|
||||
030-assert-success.s:3: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:4: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:6: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:7: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:12: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:13: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:15: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:16: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:18: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:19: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:23: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:24: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:26: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:27: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:29: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:30: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:35: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:36: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:38: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:39: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:45: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:46: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:48: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:49: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:51: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:52: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:54: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:55: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:60: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:61: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:65: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:66: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:68: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:69: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:71: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:72: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:74: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:75: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:77: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:78: Warning: Assertion failed: Code not at $8000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error2.s:3: Code not at $0000
|
||||
032-assert-error2.s:3: Error: Assertion failed: Code not at $0000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error3.s:3: Code not at $0000
|
||||
032-assert-error3.s:3: Error: Assertion failed: Code not at $0000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error4.s:3: Code not at $0001
|
||||
032-assert-error4.s:3: Error: Assertion failed: Code not at $0001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error6.s:3: Code not at $1001
|
||||
032-assert-error6.s:3: Error: Assertion failed: Code not at $1001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error7.s:3: Code not at $8000
|
||||
032-assert-error7.s:3: Error: Assertion failed: Code not at $8000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error8.s:3: Code not at $8001
|
||||
032-assert-error8.s:3: Error: Assertion failed: Code not at $8001
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:3: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:4: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:6: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:7: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:12: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:13: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:15: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:16: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:18: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:19: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:23: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:24: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:26: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:27: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:29: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:30: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:35: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:36: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:38: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:39: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:45: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:46: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:48: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:49: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:51: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:52: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:54: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:55: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:60: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:61: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:65: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:66: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:68: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:69: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:71: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:72: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:74: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:75: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:77: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:78: Code not at $8000
|
||||
033-assert-ldwarning-success.s:3: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:4: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:6: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:7: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:12: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:13: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:15: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:16: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:18: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:19: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:23: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:24: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:26: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:27: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:29: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:30: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:35: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:36: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:38: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:39: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:45: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:46: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:48: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:49: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:51: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:52: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:54: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:55: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:60: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:61: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:65: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:66: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:68: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:69: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:71: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:72: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:74: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:75: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:77: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:78: Warning: Assertion failed: Code not at $8000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror2.s:3: Code not at $0000
|
||||
034-assert-lderror2.s:3: Error: Assertion failed: Code not at $0000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror3.s:3: Code not at $0000
|
||||
034-assert-lderror3.s:3: Error: Assertion failed: Code not at $0000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror4.s:3: Code not at $0001
|
||||
034-assert-lderror4.s:3: Error: Assertion failed: Code not at $0001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror6.s:3: Code not at $1001
|
||||
034-assert-lderror6.s:3: Error: Assertion failed: Code not at $1001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror7.s:3: Code not at $8000
|
||||
034-assert-lderror7.s:3: Error: Assertion failed: Code not at $8000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror8.s:3: Code not at $8001
|
||||
034-assert-lderror8.s:3: Error: Assertion failed: Code not at $8001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Warning: <<<#PATH#>>>:<<<#INTEGER#>>>: Segment 'CODE' isn't aligned properly; the resulting executable might not be functional.
|
||||
<<<#PATH#>>>:<<<#INTEGER#>>>: Warning: Segment 'CODE' isn't aligned properly; the resulting executable might not be functional.
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Warning: runtime/sp-compat.s:16: Symbol 'sp' is deprecated - please use 'c_sp' instead
|
||||
runtime/sp-compat.s:16: Warning: Assertion failed: Symbol 'sp' is deprecated - please use 'c_sp' instead
|
||||
|
||||
1
test/asm/listing/ref/170-ld-errormsg.bin-ref
Normal file
1
test/asm/listing/ref/170-ld-errormsg.bin-ref
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
2
test/asm/listing/ref/170-ld-errormsg.ld65err2-ref
Normal file
2
test/asm/listing/ref/170-ld-errormsg.ld65err2-ref
Normal file
@@ -0,0 +1,2 @@
|
||||
170-ld-errormsg.cfg:10: Warning: Segment 'BSS' with type 'bss' contains initialized data
|
||||
170-ld-errormsg.cfg:10: Note: Initialized data comes at least partially from '<<<#PATH#>>>'
|
||||
2
test/asm/listing/ref/171-ld-errormsg.ld65err2-ref
Normal file
2
test/asm/listing/ref/171-ld-errormsg.ld65err2-ref
Normal file
@@ -0,0 +1,2 @@
|
||||
171-ld-errormsg.cfg:3: Warning: Segment 'CODE' overflows memory area 'MAIN' by 1 byte
|
||||
ld65: Error: Cannot generate most of the files due to memory area overflow
|
||||
2
test/asm/listing/ref/172-ld-errormsg.ld65err2-ref
Normal file
2
test/asm/listing/ref/172-ld-errormsg.ld65err2-ref
Normal file
@@ -0,0 +1,2 @@
|
||||
172-ld-errormsg.cfg:5: Error: Segment type expected but got 'RWX'
|
||||
172-ld-errormsg.cfg:5: Note: You may use one of 'RO', 'RW', 'BSS', 'ZP' or 'OVERWRITE'
|
||||
@@ -1,3 +1,3 @@
|
||||
ld65: Warning: 201-overwrite-overflow.cfg:3: Segment 'AO' overflows memory area 'A' by 1 byte
|
||||
ld65: Warning: 201-overwrite-overflow.cfg:4: Segment 'BO' overflows memory area 'B' by 1 byte
|
||||
201-overwrite-overflow.cfg:3: Warning: Segment 'AO' overflows memory area 'A' by 1 byte
|
||||
201-overwrite-overflow.cfg:4: Warning: Segment 'BO' overflows memory area 'B' by 1 byte
|
||||
ld65: Error: Cannot generate most of the files due to memory area overflows
|
||||
|
||||
BIN
test/asm/listing/ref/666-bug2208.bin-ref
Normal file
BIN
test/asm/listing/ref/666-bug2208.bin-ref
Normal file
Binary file not shown.
@@ -63,15 +63,15 @@ define PRG_template
|
||||
# sim65 ensure 64-bit wait time does not timeout
|
||||
$(WORKDIR)/sim65-timein.$1.prg: sim65-timein.s | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/sim65-timein.$1.prg)
|
||||
$(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
|
||||
$(LD65) -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
|
||||
$(CA65) --no-utf8 -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
|
||||
$(LD65) --no-utf8 -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
|
||||
$(SIM65) -x 4400000000 -c $$@ $(NULLOUT) $(NULLERR)
|
||||
|
||||
# sim65 ensure 64-bit wait time does timeout
|
||||
$(WORKDIR)/sim65-timeout.$1.prg: sim65-timeout.s | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/sim65-timeout.$1.prg)
|
||||
$(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
|
||||
$(LD65) -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
|
||||
$(CA65) --no-utf8 -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
|
||||
$(LD65) --no-utf8 -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
|
||||
$(NOT) $(SIM65) -x 4400000000 -c $$@ $(NULLOUT) $(NULLERR)
|
||||
|
||||
endef # PRG_template
|
||||
|
||||
@@ -61,8 +61,8 @@ define OPCODE_template
|
||||
|
||||
$(WORKDIR)/$1-opcodes.bin: $1-opcodes.s $(ISEQUAL)
|
||||
$(if $(QUIET),echo asm/$1-opcodes.bin)
|
||||
$(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$<
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib
|
||||
$(CA65) --no-utf8 -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$<
|
||||
$(LD65) --no-utf8 -t none -o $$@ $$(@:.bin=.o) none.lib
|
||||
$(ISEQUAL) $1-opcodes.ref $$@
|
||||
|
||||
endef # OPCODE_template
|
||||
@@ -70,7 +70,7 @@ endef # OPCODE_template
|
||||
$(foreach cpu,$(OPCODE_CPUS),$(eval $(call OPCODE_template,$(cpu))))
|
||||
|
||||
$(WORKDIR)/%.o: %.s | $(WORKDIR)
|
||||
$(CA65) -l $(@:.o=.lst) -o $@ $<
|
||||
$(CA65) --no-utf8 -l $(@:.o=.lst) -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
||||
@@ -55,8 +55,8 @@ define PRG_template
|
||||
|
||||
$(WORKDIR)/%.$1.prg: %.s | $(WORKDIR)
|
||||
$(if $(QUIET),echo asm/val/$$*.$1.prg)
|
||||
$(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLOUT) $(NULLERR)
|
||||
$(LD65) -C sim6502-asmtest.cfg -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLOUT) $(NULLERR)
|
||||
$(CA65) --no-utf8 -t sim$1 -o $$(@:.prg=.o) $$< $(NULLOUT) $(NULLERR)
|
||||
$(LD65) --no-utf8 -C sim6502-asmtest.cfg -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLOUT) $(NULLERR)
|
||||
$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT)
|
||||
|
||||
endef # PRG_template
|
||||
|
||||
43
test/asm/val/charmap.s
Normal file
43
test/asm/val/charmap.s
Normal file
@@ -0,0 +1,43 @@
|
||||
.setcpu "6502"
|
||||
|
||||
.import _exit
|
||||
.export _main
|
||||
|
||||
.charmap $41, 0
|
||||
.charmap $42, 1
|
||||
.charmap $43, 2
|
||||
mapped:
|
||||
.byte "ABC"
|
||||
|
||||
.include "ascii_charmap.inc"
|
||||
ascii:
|
||||
.byte "ABC"
|
||||
|
||||
_main:
|
||||
ldx #$01
|
||||
|
||||
lda mapped+0
|
||||
cmp #0
|
||||
bne error
|
||||
lda mapped+1
|
||||
cmp #1
|
||||
bne error
|
||||
lda mapped+2
|
||||
cmp #2
|
||||
bne error
|
||||
|
||||
lda ascii+0
|
||||
cmp #$41
|
||||
bne error
|
||||
lda ascii+1
|
||||
cmp #$42
|
||||
bne error
|
||||
lda ascii+2
|
||||
cmp #$43
|
||||
bne error
|
||||
|
||||
ldx #$00
|
||||
|
||||
error:
|
||||
txa
|
||||
jmp _exit
|
||||
Reference in New Issue
Block a user