@@ -2795,12 +2791,6 @@ See: ,[
-
- Enables the .ADDRSIZE pseudo function. This function is experimental and not enabled by default.
-
- See also: ]
-
at_in_identifiers
Accept the at character ('@') as a valid character in identifiers. The
diff --git a/doc/cc65.sgml b/doc/cc65.sgml
index 1476b40a3..4303edb48 100644
--- a/doc/cc65.sgml
+++ b/doc/cc65.sgml
@@ -754,6 +754,8 @@ Here is a description of all the command line options:
Warn about unused function parameters.
Warn about unused variables.
+
+ Warn if numerical constant conversion implies overflow. (Disabled by default.)
The full list of available warning names can be retrieved by using the
diff --git a/doc/doc.css b/doc/doc.css
index e4c316e16..0f6e90d67 100644
--- a/doc/doc.css
+++ b/doc/doc.css
@@ -2,12 +2,14 @@ body {
font-family: arial, helvetica, sans-serif;
font-size: 100%;
text-align: justify;
- margin-left: 110px;
- margin-top: 10px;
- margin-right: 30px;
- margin-bottom: 10px;
+ margin: 0px;
+ padding-left: 110px;
+ padding-top: 10px;
+ padding-right: 30px;
+ padding-bottom: 10px;
background-image: url(doc.png);
background-repeat: repeat-y;
+ background-position:left top;
}
h1, h2, h2 a:link, h2 a:active, h2 a:visited {
@@ -25,7 +27,7 @@ h1 {
}
h2 {
- font-size: 160%;
+ font-size: 150%;
text-shadow: 1px 1px 3px #303030;
letter-spacing: 1px;
margin-top: 2em;
diff --git a/doc/funcref.sgml b/doc/funcref.sgml
index 6418723b5..2a6d77adc 100644
--- a/doc/funcref.sgml
+++ b/doc/funcref.sgml
@@ -976,7 +976,7 @@ previously been allocated by /, / or /.
- Passing a pointer to a block that was is not the result of one of the
-allocation functions, or that has been free'd will give unpredicable results.
+allocation functions, or that has been free'd will give unpredictable results.
- The function is available only as a fastcall function; so, it may be used
only in the presence of a prototype.
diff --git a/doc/osi.sgml b/doc/osi.sgml
index eeaee4a97..62d466406 100644
--- a/doc/osi.sgml
+++ b/doc/osi.sgml
@@ -187,8 +187,21 @@ Currently the following extra screen configuration modules are implemented:
osic1p-screen-s3-32x28.o : 32 columns by 28 lines mode
for Briel Superboard ///
+osic1p-screen-c1p-48x12.s : 48 columns by 12 lines mode
+for Challenger 1P
+On the Briel Superboard /// you enter 32 column mode by holding down
+the BREAK key on powerup.
+
+On the Challenger 1P you can enable 48 column mode by writing a 1 to
+bit 0 of address $D800, and writing a 0 to go back to 24 column mode.
+You can use code like the following to do this:
+
+
+*(char*)0xd800 = 1; /* Switch to 48 column mode */
+
+
Limitations
stdio implementation
diff --git a/doc/sim65.sgml b/doc/sim65.sgml
index 310de4667..b1e5afbdc 100644
--- a/doc/sim65.sgml
+++ b/doc/sim65.sgml
@@ -44,6 +44,13 @@ The simulator is called as follows:
--version Print the simulator version number
+sim65 will exit with the error code of the simulated program,
+which is limited to an 8-bit result 0-255.
+
+An error in sim65, like bad arguments or an internal problem will exit with Command line options in detail
@@ -126,9 +133,17 @@ a set of built-in paravirtualization functions ([Creating a Test in Assembly]
Assembly tests may similarly be assembled and linked with
-
+
+- Return from
The binary file has a 12 byte header:
diff --git a/include/_atari5200os.h b/include/_atari5200os.h
index 5bba43016..196b69e56 100644
--- a/include/_atari5200os.h
+++ b/include/_atari5200os.h
@@ -54,7 +54,21 @@ struct __os {
unsigned char color2; // = $0E PF color 2
unsigned char color3; // = $0F PF color 3
unsigned char color4; // = $10 PF color 4
- unsigned char _free_1[0xEF]; // = $11-$FF User space
+ unsigned char paddl0; // = $11 POT0 Shadow
+ unsigned char paddl1; // = $12 POT1 Shadow
+ unsigned char paddl2; // = $13 POT2 Shadow
+ unsigned char paddl3; // = $14 POT3 Shadow
+ unsigned char paddl4; // = $15 POT4 Shadow
+ unsigned char paddl5; // = $16 POT5 Shadow
+ unsigned char paddl6; // = $17 POT6 Shadow
+ unsigned char paddl7; // = $18 POT7 Shadow
+
+ /*cc65 runtime zero page variables*/
+ unsigned char rowcrs_5200; // = $19 Cursor row (conio)
+ unsigned char colcrs_5200; // = $1A Cursor column (conio)
+ unsigned char* savmsc; // = $1B/$1C Pointer to screen memory (conio)
+
+ unsigned char _filler_1[0xE3]; // = $1D-$FF Filler
/*Stack*/
unsigned char stack[0x100]; // = $100-$1FF Stack
diff --git a/include/_atarios.h b/include/_atarios.h
index ec33b98c9..cbf33bda6 100644
--- a/include/_atarios.h
+++ b/include/_atarios.h
@@ -334,17 +334,17 @@ struct __os {
void (*vserin)(void); // = $020A/$020B POKEY SERIAL INPUT READY IRQ
void (*vseror)(void); // = $020C/$020D POKEY SERIAL OUTPUT READY IRQ
void (*vseroc)(void); // = $020E/$020F POKEY SERIAL OUTPUT COMPLETE IRQ
- void (*vtimr1)(void); // = $0210/$0201 POKEY TIMER 1 IRQ
- void (*vtimr2)(void); // = $0212/$0203 POKEY TIMER 2 IRQ
- void (*vtimr4)(void); // = $0214/$0205 POKEY TIMER 4 IRQ
- void (*vimirq)(void); // = $0216/$0207 IMMEDIATE IRQ VECTOR
- unsigned int cdtmv1; // = $0218/$0210 COUNT DOWN TIMER 1
+ void (*vtimr1)(void); // = $0210/$0211 POKEY TIMER 1 IRQ
+ void (*vtimr2)(void); // = $0212/$0213 POKEY TIMER 2 IRQ
+ void (*vtimr4)(void); // = $0214/$0215 POKEY TIMER 4 IRQ
+ void (*vimirq)(void); // = $0216/$0217 IMMEDIATE IRQ VECTOR
+ unsigned int cdtmv1; // = $0218/$0219 COUNT DOWN TIMER 1
unsigned int cdtmv2; // = $021A/$021B COUNT DOWN TIMER 2
unsigned int cdtmv3; // = $021C/$021D COUNT DOWN TIMER 3
unsigned int cdtmv4; // = $021E/$021F COUNT DOWN TIMER 4
unsigned int cdtmv5; // = $0220/$0221 COUNT DOWN TIMER 5
void (*vvblki)(void); // = $0222/$0223 IMMEDIATE VERTICAL BLANK NMI VECTOR
- void (*vvblkd)(void); // = $0224/$0224 DEFERRED VERTICAL BLANK NMI VECTOR
+ void (*vvblkd)(void); // = $0224/$0225 DEFERRED VERTICAL BLANK NMI VECTOR
void (*cdtma1)(void); // = $0226/$0227 COUNT DOWN TIMER 1 JSR ADDRESS
void (*cdtma2)(void); // = $0228/$0229 COUNT DOWN TIMER 2 JSR ADDRESS
unsigned char cdtmf3; // = $022A COUNT DOWN TIMER 3 FLAG
diff --git a/include/geos/gconst.h b/include/geos/gconst.h
index e70eb9304..3e42feed7 100644
--- a/include/geos/gconst.h
+++ b/include/geos/gconst.h
@@ -4,13 +4,15 @@
reassembled by Maciej 'YTM/Elysium' Witkowiak
*/
-/* Here are constants which didn't fit into any other cathegory... */
+/* Here are constants which didn't fit into any other category... */
#ifndef _GCONST_H
#define _GCONST_H
-#define NULL 0
-#define FALSE NULL
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+#define FALSE 0
#define TRUE 0xff
#define MOUSE_SPRNUM 0
#define DISK_DRV_LGH 0x0d80
diff --git a/include/locale.h b/include/locale.h
index 3f23e01d2..f408e1ef3 100644
--- a/include/locale.h
+++ b/include/locale.h
@@ -39,9 +39,8 @@
/* NULL pointer */
-#ifndef _HAVE_NULL
-#define NULL 0
-#define _HAVE_NULL
+#ifndef NULL
+#define NULL ((void *) 0)
#endif
/* Locale information constants */
@@ -82,6 +81,3 @@ char* __fastcall__ setlocale (int category, const char* locale);
/* End of locale.h */
#endif
-
-
-
diff --git a/include/stddef.h b/include/stddef.h
index ca93edf62..d2bfd6138 100644
--- a/include/stddef.h
+++ b/include/stddef.h
@@ -53,9 +53,8 @@ typedef unsigned size_t;
#endif
/* NULL pointer */
-#ifndef _HAVE_NULL
-#define NULL ((void *) 0)
-#define _HAVE_NULL
+#ifndef NULL
+#define NULL ((void *) 0)
#endif
/* offsetof macro */
@@ -65,6 +64,3 @@ typedef unsigned size_t;
/* End of stddef.h */
#endif
-
-
-
diff --git a/include/stdio.h b/include/stdio.h
index 858dd5059..012b8e2ba 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -38,9 +38,8 @@
/* NULL pointer */
-#ifndef _HAVE_NULL
-#define NULL 0
-#define _HAVE_NULL
+#ifndef NULL
+#define NULL ((void *) 0)
#endif
/* size_t is needed */
diff --git a/include/stdlib.h b/include/stdlib.h
index 4e7ffbd6a..e789f732b 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -44,6 +44,11 @@ typedef unsigned size_t;
#define _HAVE_size_t
#endif
+/* NULL pointer */
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
/* Standard exit codes */
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
@@ -167,6 +172,3 @@ int __fastcall__ putenv (char* s);
/* End of stdlib.h */
#endif
-
-
-
diff --git a/include/string.h b/include/string.h
index 854359dad..abaf80e7d 100644
--- a/include/string.h
+++ b/include/string.h
@@ -37,9 +37,8 @@
#define _STRING_H
/* NULL pointer */
-#ifndef _HAVE_NULL
-#define NULL 0
-#define _HAVE_NULL
+#ifndef NULL
+#define NULL ((void *) 0)
#endif
/* size_t is needed */
diff --git a/include/time.h b/include/time.h
index 642d68c4e..bfc2ac435 100644
--- a/include/time.h
+++ b/include/time.h
@@ -39,9 +39,8 @@
/* NULL pointer */
-#ifndef _HAVE_NULL
-#define NULL 0
-#define _HAVE_NULL
+#ifndef NULL
+#define NULL ((void *) 0)
#endif
/* size_t is needed */
diff --git a/libsrc/Makefile b/libsrc/Makefile
index 627897d9b..0873d019f 100644
--- a/libsrc/Makefile
+++ b/libsrc/Makefile
@@ -39,6 +39,10 @@ TARGETS = apple2 \
sym1 \
telestrat
+TARGETTEST = none \
+ sim6502 \
+ sim65c02
+
DRVTYPES = emd \
joy \
mou \
@@ -53,7 +57,7 @@ OUTPUTDIRS := lib
$(subst ../,,$(wildcard ../target/*/drv/*)) \
$(subst ../,,$(wildcard ../target/*/util))
-.PHONY: all mostlyclean clean install zip lib $(TARGETS)
+.PHONY: all mostlyclean clean install zip lib libtest $(TARGETS)
.SUFFIXES:
@@ -81,6 +85,8 @@ datadir = $(PREFIX)/share/cc65
all lib: $(TARGETS)
+libtest: $(TARGETTEST)
+
mostlyclean:
$(call RMDIR,../libwrk)
@@ -116,9 +122,13 @@ endef # ZIP_recipe
zip:
$(foreach dir,$(OUTPUTDIRS),$(ZIP_recipe))
-$(TARGETS):
+$(TARGETS): | ../lib
@$(MAKE) --no-print-directory $@
+# ../lib must be created globally before doing lib targets in parallel
+../lib:
+ @$(call MKDIR,$@)
+
else # TARGET
CA65FLAGS =
@@ -287,10 +297,12 @@ $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../libwrk/$(TARGET) ../lib
@echo $(TARGET) - $(__cwd
- sta mliparam + MLI::PREFIX::PATHNAME
- stx mliparam + MLI::PREFIX::PATHNAME+1
+ ; Check for ProDOS 8
+ lda __dos_type
+ beq done
- ; Get current working directory
- lda #GET_PREFIX_CALL
- ldx #PREFIX_COUNT
- jsr callmli
+ ; Save random counter
+ lda RNDL
+ pha
+ lda RNDH
+ pha
+
+ ; Call MLI
+ ; We're not using mli.s' callmli because its
+ ; mliparam is in BSS and this will be called
+ ; before LC code is moved to the Language Card.
+
+ jsr $BF00 ; MLI call entry point
+ .byte GET_PREFIX_CALL ; MLI command
+ .addr mli_parameters ; MLI parameter
+
+ ; Restore random counter
+ pla
+ sta RNDH
+ pla
+ sta RNDL
; Check for null prefix
ldx __cwd
@@ -39,3 +54,9 @@ initcwd:
sta __cwd,x
done: rts
+
+ .rodata
+
+mli_parameters:
+ .byte $01 ; Number of parameters
+ .addr __cwd ; Address of parameter
diff --git a/libsrc/apple2/syschdir.s b/libsrc/apple2/syschdir.s
index 8afc3af0b..b3f81e2a5 100644
--- a/libsrc/apple2/syschdir.s
+++ b/libsrc/apple2/syschdir.s
@@ -29,7 +29,8 @@ __syschdir:
bcs cleanup
; Update current working directory
- jsr initcwd ; Returns with A = 0
+ jsr initcwd
+ lda #$00
; Cleanup name
cleanup:jsr popname ; Preserves A
diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s
index e88e257fd..0d8a74eb7 100644
--- a/libsrc/osic1p/bootstrap.s
+++ b/libsrc/osic1p/bootstrap.s
@@ -34,8 +34,7 @@ ram_top := __MAIN_START__ + __MAIN_SIZE__
.ifdef ASM
- .include "osic1p.inc"
- .macpack generic
+ .include "screen-c1p-24x24.s"
load := $08 ; private variables
count := $0A
@@ -45,7 +44,7 @@ GETCHAR := $FFBF ; gets one character from ACIA
FIRSTVISC = $85 ; Offset of first visible character in video RAM
LINEDIST = $20 ; Offset in video RAM between two lines
- ldy #<$0000
+ ldy #$00
lda #load_addr
sta load
@@ -57,9 +56,9 @@ LINEDIST = $20 ; Offset in video RAM between two lines
stx count+1 ; save size with each byte incremented separately
L1: dec count
- bnz L2
+ bne L2
dec count+1
- bze L3
+ beq L3
L2: jsr GETCHAR ; (doesn't change .Y)
sta (load),y
@@ -70,12 +69,12 @@ L2: jsr GETCHAR ; (doesn't change .Y)
lsr a
and #8 - 1
ora #$10 ; eight arrow characters
- sta SCRNBASE + FIRSTVISC + 2 * LINEDIST + 11
+ sta C1P_SCR_BASE + FIRSTVISC + 2 * LINEDIST + 11
iny
- bnz L1
+ bne L1
inc load+1
- bnz L1 ; branch always
+ bne L1 ; branch always
L3: jmp load_addr
@@ -112,18 +111,15 @@ CR = $0D
hex2 >load_addr
.byte CR, "85", CR, "08", CR
.byte "86", CR, "09", CR
- .byte "A9", CR
- hex2 load_size
- .byte CR, "49", CR, "FF", CR
- .byte "85", CR, "0B", CR
-
- .byte "E6", CR, "0A", CR
+ .byte "A2", CR
+ hex2 (load_size) + 1
+ .byte CR, "86", CR, "0B", CR
+ .byte "C6", CR, "0A", CR
.byte "D0", CR, "04", CR
- .byte "E6", CR, "0B", CR
+ .byte "C6", CR, "0B", CR
.byte "F0", CR, "16", CR
.byte "20", CR, "BF", CR, "FF", CR
.byte "91", CR, "08", CR
diff --git a/libsrc/osic1p/extra/screen-c1p-48x12.s b/libsrc/osic1p/extra/screen-c1p-48x12.s
new file mode 100644
index 000000000..91a61338b
--- /dev/null
+++ b/libsrc/osic1p/extra/screen-c1p-48x12.s
@@ -0,0 +1,16 @@
+;
+; Implementation of screen-layout related functions for Challenger 1P in 48x12 mode.
+;
+
+ .include "../osiscreen.inc"
+
+C1P_SCR_BASE := $D000 ; Base of C1P video RAM
+C1P_VRAM_SIZE = $0400 ; Size of C1P video RAM (1 kB)
+C1P_SCR_WIDTH = $30 ; Screen width
+C1P_SCR_HEIGHT = $0C ; Screen height
+C1P_SCR_FIRSTCHAR = $8B ; Offset of cursor position (0, 0) from base
+ ; of video RAM
+C1P_SCROLL_DIST = $40 ; Memory distance for scrolling by one line
+
+osi_screen_funcs C1P_SCR_BASE, C1P_VRAM_SIZE, C1P_SCR_FIRSTCHAR, \
+ C1P_SCR_WIDTH, C1P_SCR_HEIGHT, C1P_SCROLL_DIST
diff --git a/libsrc/telestrat/read.s b/libsrc/telestrat/read.s
index f31909f45..736546363 100644
--- a/libsrc/telestrat/read.s
+++ b/libsrc/telestrat/read.s
@@ -30,13 +30,14 @@
ldy ptr1+1
BRK_TELEMON XFREAD
; compute nb of bytes read
- lda PTR_READ_DEST+1
sec
+ lda PTR_READ_DEST
+ sbc ptr2
+ pha
+ lda PTR_READ_DEST+1
sbc ptr2+1
tax
- lda PTR_READ_DEST
- sec
- sbc ptr2
- ; here A and X contains number of bytes read
+ pla
+
rts
.endproc
diff --git a/libsrc/telestrat/write.s b/libsrc/telestrat/write.s
index 2ce2657ac..37a896696 100644
--- a/libsrc/telestrat/write.s
+++ b/libsrc/telestrat/write.s
@@ -42,16 +42,16 @@ next:
ldy ptr3+1
ldx tmp1 ; send fd in X
BRK_TELEMON XFWRITE
+
; compute nb of bytes written
-
-
- lda PTR_READ_DEST+1
sec
+ lda PTR_READ_DEST
+ sbc ptr1
+ pha
+ lda PTR_READ_DEST+1
sbc ptr1+1
tax
- lda PTR_READ_DEST
- sec
- sbc ptr1
+ pla
rts
diff --git a/src/ca65/expr.c b/src/ca65/expr.c
index 812b6e90c..5dcf5ca71 100644
--- a/src/ca65/expr.c
+++ b/src/ca65/expr.c
@@ -496,7 +496,7 @@ static ExprNode* FuncIsMnemonic (void)
/* Skip the name */
NextTok ();
- return GenLiteralExpr (Instr > 0);
+ return GenLiteralExpr (Instr >= 0);
}
diff --git a/src/ca65/feature.c b/src/ca65/feature.c
index 41177d66b..9f5ca5876 100644
--- a/src/ca65/feature.c
+++ b/src/ca65/feature.c
@@ -118,7 +118,6 @@ void SetFeature (feature_t Feature, unsigned char On)
case FEAT_C_COMMENTS: CComments = On; break;
case FEAT_FORCE_RANGE: ForceRange = On; break;
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= On; break;
- case FEAT_ADDRSIZE: AddrSize = On; break;
case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = On; break;
case FEAT_STRING_ESCAPES: StringEscapes = On; break;
case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = On; break;
diff --git a/src/ca65/global.c b/src/ca65/global.c
index 337677e31..050d19e09 100644
--- a/src/ca65/global.c
+++ b/src/ca65/global.c
@@ -85,5 +85,4 @@ unsigned char OrgPerSeg = 0; /* Make .org local to current seg */
unsigned char CComments = 0; /* Allow C like comments */
unsigned char ForceRange = 0; /* Force values into expected range */
unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */
-unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */
unsigned char BracketAsIndirect = 0; /* Use '[]' not '()' for indirection */
diff --git a/src/ca65/global.h b/src/ca65/global.h
index 46fb6c763..b3de99df5 100644
--- a/src/ca65/global.h
+++ b/src/ca65/global.h
@@ -87,7 +87,6 @@ extern unsigned char OrgPerSeg; /* Make .org local to current seg */
extern unsigned char CComments; /* Allow C like comments */
extern unsigned char ForceRange; /* Force values into expected range */
extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */
-extern unsigned char AddrSize; /* Allow .ADDRSIZE function */
extern unsigned char BracketAsIndirect; /* Use '[]' not '()' for indirection */
diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c
index 1877512d5..2ce1ae087 100644
--- a/src/ca65/pseudo.c
+++ b/src/ca65/pseudo.c
@@ -1043,6 +1043,11 @@ static void DoFeature (void)
ErrorSkip ("Invalid feature: '%m%p'", &CurTok.SVal);
return;
}
+
+ if (Feature == FEAT_ADDRSIZE) {
+ Warning (1, "Deprecated feature: '.feature addrsize'. Pseudo function .addrsize is always available.");
+ }
+
NextTok ();
/* Optional +/- or ON/OFF */
diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c
index add365e84..185100025 100644
--- a/src/ca65/scanner.c
+++ b/src/ca65/scanner.c
@@ -748,24 +748,7 @@ static token_t FindDotKeyword (void)
R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
sizeof (DotKeywords [0]), CmpDotKeyword);
if (R != 0) {
-
- /* By default, disable any somewhat experiemental DotKeyword. */
-
- switch (R->Tok) {
-
- case TOK_ADDRSIZE:
- /* Disallow .ADDRSIZE function by default */
- if (AddrSize == 0) {
- return TOK_NONE;
- }
- break;
-
- default:
- break;
- }
-
return R->Tok;
-
} else {
return TOK_NONE;
}
diff --git a/src/cc65/error.c b/src/cc65/error.c
index 3f36d9e97..39b067825 100644
--- a/src/cc65/error.c
+++ b/src/cc65/error.c
@@ -79,6 +79,7 @@ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */
IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */
IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */
IntStack WarnUnusedFunc = INTSTACK(1); /* - unused functions */
+IntStack WarnConstOverflow = INTSTACK(0); /* - overflow conversion of numerical constants */
/* Map the name of a warning to the intstack that holds its state */
typedef struct WarnMapEntry WarnMapEntry;
@@ -102,6 +103,7 @@ static WarnMapEntry WarnMap[] = {
{ &WarnUnusedLabel, "unused-label" },
{ &WarnUnusedParam, "unused-param" },
{ &WarnUnusedVar, "unused-var" },
+ { &WarnConstOverflow, "const-overflow" },
};
Collection DiagnosticStrBufs;
diff --git a/src/cc65/error.h b/src/cc65/error.h
index 7fcb03467..83be8c782 100644
--- a/src/cc65/error.h
+++ b/src/cc65/error.h
@@ -76,6 +76,7 @@ extern IntStack WarnUnusedLabel; /* - unused labels */
extern IntStack WarnUnusedParam; /* - unused parameters */
extern IntStack WarnUnusedVar; /* - unused variables */
extern IntStack WarnUnusedFunc; /* - unused functions */
+extern IntStack WarnConstOverflow; /* - overflow conversion of numerical constants */
/* Forward */
struct StrBuf;
diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c
index 36fd1301b..ede77cb2c 100644
--- a/src/cc65/scanner.c
+++ b/src/cc65/scanner.c
@@ -39,6 +39,8 @@
#include
#include
#include
+#include
+#include
/* common */
#include "chartype.h"
@@ -151,6 +153,11 @@ static const struct Keyword {
#define IT_ULONG 0x08
+/* Internal type for numeric constant scanning.
+** Size must be explicit for cross-platform uniformity.
+*/
+typedef uint32_t scan_t;
+
/*****************************************************************************/
/* code */
@@ -521,7 +528,8 @@ static void NumericConst (void)
int IsFloat;
char C;
unsigned DigitVal;
- unsigned long IVal; /* Value */
+ scan_t IVal; /* Scanned value. */
+ int Overflow;
/* Get the pp-number first, then parse on it */
CopyPPNumber (&Src);
@@ -575,6 +583,7 @@ static void NumericConst (void)
/* Since we now know the correct base, convert the input into a number */
SB_SetIndex (&Src, Index);
IVal = 0;
+ Overflow = 0;
while ((C = SB_Peek (&Src)) != '\0' && (Base <= 10 ? IsDigit (C) : IsXDigit (C))) {
DigitVal = HexVal (C);
if (DigitVal >= Base) {
@@ -582,9 +591,17 @@ static void NumericConst (void)
SB_Clear (&Src);
break;
}
- IVal = (IVal * Base) + DigitVal;
+ /* Test result of adding digit for overflow. */
+ if (((scan_t)(IVal * Base + DigitVal) / Base) != IVal) {
+ Overflow = 1;
+ }
+ IVal = IVal * Base + DigitVal;
SB_Skip (&Src);
}
+ if (Overflow) {
+ Error ("Numerical constant \"%s\" too large for internal %d-bit representation",
+ SB_GetConstBuf (&Src), (int)(sizeof(IVal)*CHAR_BIT));
+ }
/* Distinguish between integer and floating point constants */
if (!IsFloat) {
diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c
index 72a2ac007..a2bbf13dd 100644
--- a/src/cc65/symtab.c
+++ b/src/cc65/symtab.c
@@ -793,6 +793,8 @@ static int HandleSymRedefinition (SymEntry* Sym, const Type* T, unsigned Flags)
*/
Error ("Redeclaration of enumerator constant '%s'", Sym->Name);
Sym = 0;
+ } else if (Flags & SC_STRUCTFIELD) {
+ Error ("Duplicate member '%s'", Sym->Name);
}
}
}
@@ -1338,15 +1340,14 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
Name);
Entry = 0;
} else if ((Flags & SC_ESUTYPEMASK) != SC_TYPEDEF) {
- /* If a static declaration follows a non-static declaration, then
- ** diagnose the conflict. It will warn and compile an extern
- ** declaration if both declarations are global, otherwise give an
- ** error.
+ /* If a static declaration follows a non-static declaration, then the result is undefined.
+ ** Most compilers choose to either give an error at compile time,
+ ** or remove the extern property for a link time error if used.
*/
if (SymTab == SymTab0 &&
(Flags & SC_EXTERN) == 0 &&
(Entry->Flags & SC_EXTERN) != 0) {
- Warning ("Static declaration of '%s' follows non-static declaration", Name);
+ Error ("Static declaration of '%s' follows non-static declaration", Name);
} else if ((Flags & SC_EXTERN) != 0 &&
(Entry->Owner == SymTab0 || (Entry->Flags & SC_DEF) != 0) &&
(Entry->Flags & SC_EXTERN) == 0) {
@@ -1358,8 +1359,12 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
*/
if (Entry->Owner == SymTab0) {
if ((Flags & SC_STORAGE) == 0) {
- /* Linkage must be unchanged */
+ /* Linkage must be unchanged.
+ ** The C standard specifies that a later extern declaration will be ignored,
+ ** and will use the previous linkage instead. Giving a warning for this case.
+ */
Flags &= ~SC_EXTERN;
+ Warning ("Extern declaration of '%s' follows static declaration, extern ignored", Name);
} else {
Error ("Non-static declaration of '%s' follows static declaration", Name);
}
diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c
index f77ec3951..6bdb45b5f 100644
--- a/src/cc65/typeconv.c
+++ b/src/cc65/typeconv.c
@@ -55,7 +55,7 @@
-static void DoConversion (ExprDesc* Expr, const Type* NewType)
+static void DoConversion (ExprDesc* Expr, const Type* NewType, int Explicit)
/* Emit code to convert the given expression to a new type. */
{
const Type* OldType;
@@ -128,6 +128,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType)
** internally already represented by a long.
*/
if (NewBits <= OldBits) {
+ long OldVal = Expr->IVal;
/* Cut the value to the new size */
Expr->IVal &= (0xFFFFFFFFUL >> (32 - NewBits));
@@ -139,6 +140,10 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType)
Expr->IVal |= shl_l (~0UL, NewBits);
}
}
+
+ if ((OldVal != Expr->IVal) && IS_Get (&WarnConstOverflow) && !Explicit) {
+ Warning ("Implicit conversion of constant overflows %d-bit destination", NewBits);
+ }
}
/* Do the integer constant <-> absolute address conversion if necessary */
@@ -283,7 +288,7 @@ void TypeConversion (ExprDesc* Expr, const Type* NewType)
/* Both types must be complete */
if (!IsIncompleteESUType (NewType) && !IsIncompleteESUType (Expr->Type)) {
/* Do the actual conversion */
- DoConversion (Expr, NewType);
+ DoConversion (Expr, NewType, 0);
} else {
/* We should have already generated error elsewhere so that we
** could just silently fail here to avoid excess errors, but to
@@ -330,7 +335,7 @@ void TypeCast (ExprDesc* Expr)
ReplaceType (Expr, NewType);
} else if (IsCastType (Expr->Type)) {
/* Convert the value. The result has always the new type */
- DoConversion (Expr, NewType);
+ DoConversion (Expr, NewType, 1);
} else {
TypeCompatibilityDiagnostic (NewType, Expr->Type, 1,
"Cast to incompatible type '%s' from '%s'");
diff --git a/src/grc65/main.c b/src/grc65/main.c
index 349b5c110..7d31bfc52 100644
--- a/src/grc65/main.c
+++ b/src/grc65/main.c
@@ -850,14 +850,25 @@ static char *filterInput (FILE *F, char *tbl)
/* loads file into buffer filtering it out */
int a, prevchar = -1, i = 0, bracket = 0, quote = 1;
- for (;;) {
- a = getc(F);
- if ((a == '\n') || (a == '\015')) a = ' ';
- if (a == ',' && quote) a = ' ';
- if (a == '\042') quote =! quote;
+ a = getc(F);
+ while (1) {
+ if (i >= BLOODY_BIG_BUFFER) {
+ AbEnd ("File too large for internal parsing buffer (%d bytes)",BLOODY_BIG_BUFFER);
+ }
+ if (((a == '\n') || (a == '\015')) ||
+ (a == ',' && quote)) {
+ a = ' ';
+ }
+ if (a == '\042') {
+ quote =! quote;
+ }
if (quote) {
- if ((a == '{') || (a == '(')) bracket++;
- if ((a == '}') || (a == ')')) bracket--;
+ if ((a == '{') || (a == '(')) {
+ bracket++;
+ }
+ if ((a == '}') || (a == ')')) {
+ bracket--;
+ }
}
if (a == EOF) {
tbl[i] = '\0';
@@ -873,13 +884,18 @@ static char *filterInput (FILE *F, char *tbl)
if (a == ';' && quote) {
do {
a = getc (F);
- } while (a != '\n');
- fseek (F, -1, SEEK_CUR);
+ } while (a != '\n' && a != EOF);
+ /* Don't discard this newline/EOF, continue to next loop.
+ ** A previous implementation used fseek(F,-1,SEEK_CUR),
+ ** which is invalid for text mode files, and was unreliable across platforms.
+ */
+ continue;
} else {
tbl[i++] = a;
prevchar = a;
}
}
+ a = getc(F);
}
if (bracket != 0) AbEnd ("There are unclosed brackets!");
diff --git a/src/sim65/6502.c b/src/sim65/6502.c
index 6c23b0dfc..9d2c93da8 100644
--- a/src/sim65/6502.c
+++ b/src/sim65/6502.c
@@ -64,18 +64,12 @@ static CPURegs Regs;
/* Cycles for the current insn */
static unsigned Cycles;
-/* Total number of CPU cycles exec'd */
-static unsigned long TotalCycles;
-
/* NMI request active */
static unsigned HaveNMIRequest;
/* IRQ request active */
static unsigned HaveIRQRequest;
-/* flag to print cycles at program termination */
-int PrintCycles;
-
/*****************************************************************************/
/* Helper functions and macros */
@@ -3277,18 +3271,6 @@ unsigned ExecuteInsn (void)
Handlers[CPU][OPC] ();
}
- /* Count cycles */
- TotalCycles += Cycles;
-
/* Return the number of clock cycles needed by this insn */
return Cycles;
}
-
-
-
-unsigned long GetCycles (void)
-/* Return the total number of cycles executed */
-{
- /* Return the total number of cycles */
- return TotalCycles;
-}
diff --git a/src/sim65/6502.h b/src/sim65/6502.h
index f8e894567..39b995793 100644
--- a/src/sim65/6502.h
+++ b/src/sim65/6502.h
@@ -96,12 +96,6 @@ unsigned ExecuteInsn (void);
** executed instruction.
*/
-unsigned long GetCycles (void);
-/* Return the total number of clock cycles executed */
-
-extern int PrintCycles;
-/* flag to print cycles at program termination */
-
/* End of 6502.h */
diff --git a/src/sim65/error.c b/src/sim65/error.c
index 441b07d2a..fc24ca006 100644
--- a/src/sim65/error.c
+++ b/src/sim65/error.c
@@ -41,6 +41,20 @@
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* flag to print cycles at program termination */
+int PrintCycles = 0;
+
+/* cycles are counted by main.c */
+extern unsigned long long TotalCycles;
+
+
+
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@@ -99,3 +113,14 @@ void Internal (const char* Format, ...)
va_end (ap);
exit (SIM65_ERROR);
}
+
+
+
+void SimExit (int Code)
+/* Exit the simulation with an exit code */
+{
+ if (PrintCycles) {
+ fprintf (stdout, "%llu cycles\n", TotalCycles);
+ }
+ exit (Code);
+}
diff --git a/src/sim65/error.h b/src/sim65/error.h
index ea54fa048..6dbee974c 100644
--- a/src/sim65/error.h
+++ b/src/sim65/error.h
@@ -49,12 +49,17 @@
-#define SIM65_ERROR 0x7F
-/* Does not use EXIT_FAILURE because it may overlap with test results. */
+#define SIM65_ERROR -1
+/* An error result for errors that are not part of the simulated test.
+** Note that set simulated test can only return 8-bit errors 0-255.
+*/
-#define SIM65_ERROR_TIMEOUT 0x7E
+#define SIM65_ERROR_TIMEOUT -2
/* An error result for max CPU instructions exceeded. */
+extern int PrintCycles;
+/* flag to print cycles at program termination */
+
/*****************************************************************************/
@@ -75,6 +80,9 @@ void ErrorCode (int Code, const char* Format, ...) attribute((noreturn, format(p
void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
/* Print an internal error message and die */
+void SimExit (int Code);
+/* Exit the simulation with an exit code */
+
/* End of error.h */
diff --git a/src/sim65/main.c b/src/sim65/main.c
index f2daf9295..3c7cdc157 100644
--- a/src/sim65/main.c
+++ b/src/sim65/main.c
@@ -60,8 +60,14 @@
/* Name of program file */
const char* ProgramFile;
-/* exit simulator after MaxCycles Cycles */
-unsigned long MaxCycles;
+/* count of total cycles executed */
+unsigned long long TotalCycles = 0;
+
+/* exit simulator after MaxCycles Cccles */
+unsigned long long MaxCycles = 0;
+
+/* countdown from MaxCycles */
+unsigned long long RemainCycles;
/* Header signature 'sim65' */
static const unsigned char HeaderSignature[] = {
@@ -72,7 +78,6 @@ static const unsigned char HeaderSignature[] = {
static const unsigned char HeaderVersion = 2;
-
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@@ -139,7 +144,7 @@ static void OptQuitXIns (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* quit after MaxCycles cycles */
{
- MaxCycles = strtoul(Arg, NULL, 0);
+ MaxCycles = strtoull(Arg, NULL, 0);
}
static unsigned char ReadProgramFile (void)
@@ -184,6 +189,7 @@ static unsigned char ReadProgramFile (void)
}
/* Get load address */
+ Val2 = 0; /* suppress uninitialized variable warning */
if (((Val = fgetc(F)) == EOF) ||
((Val2 = fgetc(F)) == EOF)) {
Error ("'%s': Header missing load address", ProgramFile);
@@ -236,6 +242,7 @@ int main (int argc, char* argv[])
unsigned I;
unsigned char SPAddr;
+ unsigned int Cycles;
/* Initialize the cmdline module */
InitCmdLine (&argc, &argv, "sim65");
@@ -298,18 +305,24 @@ int main (int argc, char* argv[])
MemInit ();
SPAddr = ReadProgramFile ();
-
ParaVirtInit (I, SPAddr);
Reset ();
+ RemainCycles = MaxCycles;
while (1) {
- ExecuteInsn ();
- if (MaxCycles && (GetCycles () >= MaxCycles)) {
- ErrorCode (SIM65_ERROR_TIMEOUT, "Maximum number of cycles reached.");
+ Cycles = ExecuteInsn ();
+ TotalCycles += Cycles;
+ if (MaxCycles) {
+ if (Cycles > RemainCycles) {
+ ErrorCode (SIM65_ERROR_TIMEOUT, "Maximum number of cycles reached.");
+ }
+ RemainCycles -= Cycles;
}
}
- /* Return an apropriate exit code */
- return EXIT_SUCCESS;
+ /* Unreachable. sim65 program must exit through paravirtual PVExit
+ ** or timeout from MaxCycles producing an error.
+ */
+ return SIM65_ERROR;
}
diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c
index 9e5c28432..2e52d6e7e 100644
--- a/src/sim65/paravirt.c
+++ b/src/sim65/paravirt.c
@@ -124,11 +124,7 @@ static unsigned PopParam (unsigned char Incr)
static void PVExit (CPURegs* Regs)
{
Print (stderr, 1, "PVExit ($%02X)\n", Regs->AC);
- if (PrintCycles) {
- Print (stdout, 0, "%lu cycles\n", GetCycles ());
- }
-
- exit (Regs->AC);
+ SimExit (Regs->AC); /* Error code in range 0-255. */
}
@@ -242,7 +238,15 @@ static void PVClose (CPURegs* Regs)
Print (stderr, 2, "PVClose ($%04X)\n", FD);
- RetVal = close (FD);
+ if (FD != 0xFFFF) {
+ RetVal = close (FD);
+ } else {
+ /* test/val/constexpr.c "abuses" close, expecting close(-1) to return -1.
+ ** This behaviour is not the same on all target platforms.
+ ** MSVC's close treats it as a fatal error instead and terminates.
+ */
+ RetVal = 0xFFFF;
+ }
SetAX (Regs, RetVal);
}
diff --git a/test/Makefile b/test/Makefile
index abc70d58f..22e425c9c 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -22,6 +22,7 @@ continue:
@$(MAKE) -C val all
@$(MAKE) -C ref all
@$(MAKE) -C err all
+ @$(MAKE) -C standard all
@$(MAKE) -C misc all
@$(MAKE) -C todo all
@@ -31,6 +32,7 @@ mostlyclean:
@$(MAKE) -C val clean
@$(MAKE) -C ref clean
@$(MAKE) -C err clean
+ @$(MAKE) -C standard clean
@$(MAKE) -C misc clean
@$(MAKE) -C todo clean
diff --git a/test/asm/Makefile b/test/asm/Makefile
index 3481dae78..dea53f6b2 100644
--- a/test/asm/Makefile
+++ b/test/asm/Makefile
@@ -12,7 +12,7 @@ endif
WORKDIR = ../testwrk/asm
-SUBDIRS = cpudetect opcodes listing val err
+SUBDIRS = cpudetect opcodes listing val err misc
.PHONY: all continue mostlyclean clean
diff --git a/test/asm/misc/Makefile b/test/asm/misc/Makefile
new file mode 100644
index 000000000..5a9d4f3ef
--- /dev/null
+++ b/test/asm/misc/Makefile
@@ -0,0 +1,70 @@
+# Makefile for the remaining asm tests that need special care in one way or another
+
+ifneq ($(shell echo),)
+ CMD_EXE = 1
+endif
+
+ifdef CMD_EXE
+ S = $(subst /,\,/)
+ NOT = - # Hack
+ EXE = .exe
+ NULLDEV = nul:
+ MKDIR = mkdir $(subst /,\,$1)
+ RMDIR = -rmdir /s /q $(subst /,\,$1)
+else
+ S = /
+ NOT = !
+ EXE =
+ NULLDEV = /dev/null
+ MKDIR = mkdir -p $1
+ RMDIR = $(RM) -r $1
+endif
+
+ifdef QUIET
+ .SILENT:
+ NULLOUT = >$(NULLDEV)
+ NULLERR = 2>$(NULLDEV)
+endif
+
+SIM65FLAGS = -x 200000000
+
+CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65)
+LD65 := $(if $(wildcard ../../../bin/ld65*),..$S..$S..$Sbin$Sld65,ld65)
+SIM65 := $(if $(wildcard ../../../bin/sim65*),..$S..$S..$Sbin$Ssim65,sim65)
+
+WORKDIR = ..$S..$S..$Stestwrk$Sasm$Smisc
+
+.PHONY: all clean
+
+SOURCES := $(wildcard *.s)
+TESTS = $(SOURCES:%.s=$(WORKDIR)/%.6502.prg)
+TESTS += $(SOURCES:%.s=$(WORKDIR)/%.65c02.prg)
+
+all: $(TESTS)
+
+$(WORKDIR):
+ $(call MKDIR,$(WORKDIR))
+
+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)
+ $(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)
+ $(NOT) $(SIM65) -x 4400000000 -c $$@ $(NULLOUT) $(NULLERR)
+
+endef # PRG_template
+
+$(eval $(call PRG_template,6502))
+$(eval $(call PRG_template,65c02))
+
+clean:
+ @$(call RMDIR,$(WORKDIR))
diff --git a/test/asm/misc/sim65-time-wait.inc b/test/asm/misc/sim65-time-wait.inc
new file mode 100644
index 000000000..bc761ac16
--- /dev/null
+++ b/test/asm/misc/sim65-time-wait.inc
@@ -0,0 +1,55 @@
+; Shared timer for:
+; sim65-timein.s
+; sim65-timeout.s
+
+; wait A * 100,000,000 cycles, plus small amount of overhead
+wait100m:
+ tay
+ bne :+
+ rts ; return quickly if A=0
+:
+ jsr wait50331648 ; 50331648
+ jsr wait25165824 ; 75497472
+ jsr wait12582912 ; 88080384
+ jsr wait6291456 ; 94371840
+ jsr wait3145728 ; 97517568
+ jsr wait1572864 ; 99090432
+ jsr wait786432 ; 99876864
+ jsr wait98304 ; 99975168
+ jsr wait24576 ; 99999744
+ jsr wait192 ; 99999936
+ jsr wait48 ; 99999984
+ nop ; 99999986
+ nop ; 99999988
+ php ; 99999991
+ plp ; 99999995
+ dey ; 99999997
+ bne :- ; 100000000
+ rts
+; Note that this branch could cross a page if poorly aligned,
+; adding an additional 1 cycle per loop.
+; This precision is not important for the tests used.
+
+wait50331648: jsr wait25165824
+wait25165824: jsr wait12582912
+wait12582912: jsr wait6291456
+wait6291456: jsr wait3145728
+wait3145728: jsr wait1572864
+wait1572864: jsr wait786432
+wait786432: jsr wait393216
+wait393216: jsr wait196608
+wait196608: jsr wait98304
+wait98304: jsr wait49152
+wait49152: jsr wait24576
+wait24576: jsr wait12288
+wait12288: jsr wait6144
+wait6144: jsr wait3072
+wait3072: jsr wait1536
+wait1536: jsr wait768
+wait768: jsr wait384
+wait384: jsr wait192
+wait192: jsr wait96
+wait96: jsr wait48
+wait48: jsr wait24
+wait24: jsr wait12
+wait12: rts
diff --git a/test/asm/misc/sim65-timein.s b/test/asm/misc/sim65-timein.s
new file mode 100644
index 000000000..13365f0a8
--- /dev/null
+++ b/test/asm/misc/sim65-timein.s
@@ -0,0 +1,17 @@
+; Verifies that sim65 can handle 64-bit timeout counter.
+; sim65 sim65-timein.prg -x 4400000000
+
+.export _main
+.import exit
+
+_main:
+ ; wait ~4,300,000,000 cycles
+ lda #43
+ jsr wait100m
+ ; This is a positive test.
+ ; If the timeout did not occur, returning 0 reports success.
+ lda #0
+ rts
+
+; wait100m
+.include "sim65-time-wait.inc"
diff --git a/test/asm/misc/sim65-timeout.s b/test/asm/misc/sim65-timeout.s
new file mode 100644
index 000000000..6f1778dcd
--- /dev/null
+++ b/test/asm/misc/sim65-timeout.s
@@ -0,0 +1,17 @@
+; Verifies that sim65 can handle 64-bit timeout counter.
+; sim65 sim65-timeout.prg -x 4400000000
+
+.export _main
+.import exit
+
+_main:
+ ; wait ~4,500,000,000 cycles
+ lda #45
+ jsr wait100m
+ ; This is a negative test.
+ ; If the timeout did not occur, returning 0 reports failure.
+ lda #0
+ rts
+
+; wait100m
+.include "sim65-time-wait.inc"
diff --git a/test/asm/readme.txt b/test/asm/readme.txt
index 49b530d1c..9b716e60c 100644
--- a/test/asm/readme.txt
+++ b/test/asm/readme.txt
@@ -36,3 +36,9 @@ val:
Runtime assembly tests using sim65 that should end with an exit code of 0 if
they pass. If they fail the exit code should be either -1, or a number
indicating what part of the test failed.
+
+
+misc:
+-----
+
+This is for tests that require special make steps or conditions.
diff --git a/test/asm/val/Makefile b/test/asm/val/Makefile
index 91dae9afd..54b1100ec 100644
--- a/test/asm/val/Makefile
+++ b/test/asm/val/Makefile
@@ -22,7 +22,7 @@ ifdef QUIET
NULLERR = 2>$(NULLDEV)
endif
-SIM65FLAGS = -x 5000000000
+SIM65FLAGS = -x 4000000000
CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65)
LD65 := $(if $(wildcard ../../../bin/ld65*),..$S..$S..$Sbin$Sld65,ld65)
diff --git a/test/asm/val/addrsize.s b/test/asm/val/addrsize.s
new file mode 100644
index 000000000..932090df0
--- /dev/null
+++ b/test/asm/val/addrsize.s
@@ -0,0 +1,32 @@
+; test .addrsize and ensure .feature addrsize is allowed, but inactive
+
+.export _main
+
+.segment "ZEROPAGE"
+zplabel:
+
+.segment "CODE"
+abslabel:
+
+; exit with 0
+
+_main:
+ lda #0
+ tax
+ rts
+
+
+.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
+.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
+
+.feature addrsize
+.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
+.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
+
+.feature addrsize +
+.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
+.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
+
+.feature addrsize -
+.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
+.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
diff --git a/test/asm/val/feature.s b/test/asm/val/feature.s
index 4428cf4c2..0def9d92c 100644
--- a/test/asm/val/feature.s
+++ b/test/asm/val/feature.s
@@ -6,7 +6,6 @@
zplabel:
.segment "CODE"
-abslabel:
; exit with 0
@@ -17,13 +16,6 @@ _main:
tax
rts
-
-.feature addrsize +
-.assert .addrsize(zplabel) = 1, error, ".addrsize 1 expected for ZEROPAGE"
-.assert .addrsize(abslabel) = 2, error, ".addrsize 2 expected for absolute"
-.feature addrsize -
-
-
.feature at_in_identifiers on
ident@with@at:
rts
diff --git a/test/asm/val/ismnemonic.s b/test/asm/val/ismnemonic.s
new file mode 100644
index 000000000..2d131e7a9
--- /dev/null
+++ b/test/asm/val/ismnemonic.s
@@ -0,0 +1,846 @@
+; Tests to ensure .ismnemonic is working correctly
+; The .ismnemonic function calls FindInstruction internally,
+; which is how the assembler detects all instructions
+;
+; Currently supported CPUs:
+; "6502"
+; "6502X"
+; "6502DTV"
+; "65SC02"
+; "65C02"
+; "4510"
+; "huc6280"
+; "65816"
+; "sweet16"
+
+; count any errors:
+ismnemonic_error .set 0
+
+; macro to test an instruction
+.macro test_Ismnemonic instr
+ .if .ismnemonic(instr)
+ ; do nothing
+ .else
+ ismnemonic_error .set 1
+ .endif
+.endmacro
+
+; test .feature ubiquitous_idents
+
+ ; allow overloading mnemonics
+.feature ubiquitous_idents
+
+.setcpu "6502"
+
+; make an adc macro
+.macro adc
+.endmacro
+
+; should not match
+.if .ismnemonic(adc)
+ ismnemonic_error .set 1
+.endif
+
+.delmac adc
+
+; test all instructions:
+
+; there is no instruction table for "none", make sure 'adc' (common to all CPUs) and 'add' (sweet16) doesn't match
+.setcpu "none"
+.if .ismnemonic(adc) || .ismnemonic(add)
+ ismnemonic_error .set 1
+.endif
+
+.setcpu "6502"
+test_Ismnemonic adc
+test_Ismnemonic and
+test_Ismnemonic asl
+test_Ismnemonic bcc
+test_Ismnemonic bcs
+test_Ismnemonic beq
+test_Ismnemonic bit
+test_Ismnemonic bmi
+test_Ismnemonic bne
+test_Ismnemonic bpl
+test_Ismnemonic brk
+test_Ismnemonic bvc
+test_Ismnemonic bvs
+test_Ismnemonic clc
+test_Ismnemonic cld
+test_Ismnemonic cli
+test_Ismnemonic clv
+test_Ismnemonic cmp
+test_Ismnemonic cpx
+test_Ismnemonic cpy
+test_Ismnemonic dec
+test_Ismnemonic dex
+test_Ismnemonic dey
+test_Ismnemonic eor
+test_Ismnemonic inc
+test_Ismnemonic inx
+test_Ismnemonic iny
+test_Ismnemonic jmp
+test_Ismnemonic jsr
+test_Ismnemonic lda
+test_Ismnemonic ldx
+test_Ismnemonic ldy
+test_Ismnemonic lsr
+test_Ismnemonic nop
+test_Ismnemonic ora
+test_Ismnemonic pha
+test_Ismnemonic php
+test_Ismnemonic pla
+test_Ismnemonic plp
+test_Ismnemonic rol
+test_Ismnemonic ror
+test_Ismnemonic rti
+test_Ismnemonic rts
+test_Ismnemonic sbc
+test_Ismnemonic sec
+test_Ismnemonic sed
+test_Ismnemonic sei
+test_Ismnemonic sta
+test_Ismnemonic stx
+test_Ismnemonic sty
+test_Ismnemonic tax
+test_Ismnemonic tay
+test_Ismnemonic tsx
+test_Ismnemonic txa
+test_Ismnemonic txs
+test_Ismnemonic tya
+
+.setcpu "6502X"
+test_Ismnemonic adc
+test_Ismnemonic alr
+test_Ismnemonic anc
+test_Ismnemonic and
+test_Ismnemonic ane
+test_Ismnemonic arr
+test_Ismnemonic asl
+test_Ismnemonic axs
+test_Ismnemonic bcc
+test_Ismnemonic bcs
+test_Ismnemonic beq
+test_Ismnemonic bit
+test_Ismnemonic bmi
+test_Ismnemonic bne
+test_Ismnemonic bpl
+test_Ismnemonic brk
+test_Ismnemonic bvc
+test_Ismnemonic bvs
+test_Ismnemonic clc
+test_Ismnemonic cld
+test_Ismnemonic cli
+test_Ismnemonic clv
+test_Ismnemonic cmp
+test_Ismnemonic cpx
+test_Ismnemonic cpy
+test_Ismnemonic dcp
+test_Ismnemonic dec
+test_Ismnemonic dex
+test_Ismnemonic dey
+test_Ismnemonic eor
+test_Ismnemonic inc
+test_Ismnemonic inx
+test_Ismnemonic iny
+test_Ismnemonic isc
+test_Ismnemonic jam
+test_Ismnemonic jmp
+test_Ismnemonic jsr
+test_Ismnemonic las
+test_Ismnemonic lax
+test_Ismnemonic lda
+test_Ismnemonic ldx
+test_Ismnemonic ldy
+test_Ismnemonic lsr
+test_Ismnemonic nop
+test_Ismnemonic ora
+test_Ismnemonic pha
+test_Ismnemonic php
+test_Ismnemonic pla
+test_Ismnemonic plp
+test_Ismnemonic rla
+test_Ismnemonic rol
+test_Ismnemonic ror
+test_Ismnemonic rra
+test_Ismnemonic rti
+test_Ismnemonic rts
+test_Ismnemonic sax
+test_Ismnemonic sbc
+test_Ismnemonic sec
+test_Ismnemonic sed
+test_Ismnemonic sei
+test_Ismnemonic sha
+test_Ismnemonic shx
+test_Ismnemonic shy
+test_Ismnemonic slo
+test_Ismnemonic sre
+test_Ismnemonic sta
+test_Ismnemonic stx
+test_Ismnemonic sty
+test_Ismnemonic tas
+test_Ismnemonic tax
+test_Ismnemonic tay
+test_Ismnemonic tsx
+test_Ismnemonic txa
+test_Ismnemonic txs
+test_Ismnemonic tya
+
+.setcpu "6502DTV"
+test_Ismnemonic adc
+test_Ismnemonic alr
+test_Ismnemonic anc
+test_Ismnemonic and
+test_Ismnemonic ane
+test_Ismnemonic arr
+test_Ismnemonic asl
+test_Ismnemonic axs
+test_Ismnemonic bcc
+test_Ismnemonic bcs
+test_Ismnemonic beq
+test_Ismnemonic bit
+test_Ismnemonic bmi
+test_Ismnemonic bne
+test_Ismnemonic bpl
+test_Ismnemonic bra
+test_Ismnemonic brk
+test_Ismnemonic bvc
+test_Ismnemonic bvs
+test_Ismnemonic clc
+test_Ismnemonic cld
+test_Ismnemonic cli
+test_Ismnemonic clv
+test_Ismnemonic cmp
+test_Ismnemonic cpx
+test_Ismnemonic cpy
+test_Ismnemonic dec
+test_Ismnemonic dex
+test_Ismnemonic dey
+test_Ismnemonic eor
+test_Ismnemonic inc
+test_Ismnemonic inx
+test_Ismnemonic iny
+test_Ismnemonic jmp
+test_Ismnemonic jsr
+test_Ismnemonic las
+test_Ismnemonic lax
+test_Ismnemonic lda
+test_Ismnemonic ldx
+test_Ismnemonic ldy
+test_Ismnemonic lsr
+test_Ismnemonic nop
+test_Ismnemonic ora
+test_Ismnemonic pha
+test_Ismnemonic php
+test_Ismnemonic pla
+test_Ismnemonic plp
+test_Ismnemonic rla
+test_Ismnemonic rol
+test_Ismnemonic ror
+test_Ismnemonic rra
+test_Ismnemonic rti
+test_Ismnemonic rts
+test_Ismnemonic sac
+test_Ismnemonic sbc
+test_Ismnemonic sec
+test_Ismnemonic sed
+test_Ismnemonic sei
+test_Ismnemonic sha
+test_Ismnemonic shx
+test_Ismnemonic shy
+test_Ismnemonic sir
+test_Ismnemonic sta
+test_Ismnemonic stx
+test_Ismnemonic sty
+test_Ismnemonic tax
+test_Ismnemonic tay
+test_Ismnemonic tsx
+test_Ismnemonic txa
+test_Ismnemonic txs
+test_Ismnemonic tya
+
+.setcpu "65SC02"
+test_Ismnemonic adc
+test_Ismnemonic and
+test_Ismnemonic asl
+test_Ismnemonic bcc
+test_Ismnemonic bcs
+test_Ismnemonic beq
+test_Ismnemonic bit
+test_Ismnemonic bmi
+test_Ismnemonic bne
+test_Ismnemonic bpl
+test_Ismnemonic bra
+test_Ismnemonic brk
+test_Ismnemonic bvc
+test_Ismnemonic bvs
+test_Ismnemonic clc
+test_Ismnemonic cld
+test_Ismnemonic cli
+test_Ismnemonic clv
+test_Ismnemonic cmp
+test_Ismnemonic cpx
+test_Ismnemonic cpy
+test_Ismnemonic dea
+test_Ismnemonic dec
+test_Ismnemonic dex
+test_Ismnemonic dey
+test_Ismnemonic eor
+test_Ismnemonic ina
+test_Ismnemonic inc
+test_Ismnemonic inx
+test_Ismnemonic iny
+test_Ismnemonic jmp
+test_Ismnemonic jsr
+test_Ismnemonic lda
+test_Ismnemonic ldx
+test_Ismnemonic ldy
+test_Ismnemonic lsr
+test_Ismnemonic nop
+test_Ismnemonic ora
+test_Ismnemonic pha
+test_Ismnemonic php
+test_Ismnemonic phx
+test_Ismnemonic phy
+test_Ismnemonic pla
+test_Ismnemonic plp
+test_Ismnemonic plx
+test_Ismnemonic ply
+test_Ismnemonic rol
+test_Ismnemonic ror
+test_Ismnemonic rti
+test_Ismnemonic rts
+test_Ismnemonic sbc
+test_Ismnemonic sec
+test_Ismnemonic sed
+test_Ismnemonic sei
+test_Ismnemonic sta
+test_Ismnemonic stx
+test_Ismnemonic sty
+test_Ismnemonic stz
+test_Ismnemonic tax
+test_Ismnemonic tay
+test_Ismnemonic trb
+test_Ismnemonic tsb
+test_Ismnemonic tsx
+test_Ismnemonic txa
+test_Ismnemonic txs
+test_Ismnemonic tya
+
+.setcpu "65C02"
+test_Ismnemonic adc
+test_Ismnemonic and
+test_Ismnemonic asl
+test_Ismnemonic bbr0
+test_Ismnemonic bbr1
+test_Ismnemonic bbr2
+test_Ismnemonic bbr3
+test_Ismnemonic bbr4
+test_Ismnemonic bbr5
+test_Ismnemonic bbr6
+test_Ismnemonic bbr7
+test_Ismnemonic bbs0
+test_Ismnemonic bbs1
+test_Ismnemonic bbs2
+test_Ismnemonic bbs3
+test_Ismnemonic bbs4
+test_Ismnemonic bbs5
+test_Ismnemonic bbs6
+test_Ismnemonic bbs7
+test_Ismnemonic bcc
+test_Ismnemonic bcs
+test_Ismnemonic beq
+test_Ismnemonic bit
+test_Ismnemonic bmi
+test_Ismnemonic bne
+test_Ismnemonic bpl
+test_Ismnemonic bra
+test_Ismnemonic brk
+test_Ismnemonic bvc
+test_Ismnemonic bvs
+test_Ismnemonic clc
+test_Ismnemonic cld
+test_Ismnemonic cli
+test_Ismnemonic clv
+test_Ismnemonic cmp
+test_Ismnemonic cpx
+test_Ismnemonic cpy
+test_Ismnemonic dea
+test_Ismnemonic dec
+test_Ismnemonic dex
+test_Ismnemonic dey
+test_Ismnemonic eor
+test_Ismnemonic ina
+test_Ismnemonic inc
+test_Ismnemonic inx
+test_Ismnemonic iny
+test_Ismnemonic jmp
+test_Ismnemonic jsr
+test_Ismnemonic lda
+test_Ismnemonic ldx
+test_Ismnemonic ldy
+test_Ismnemonic lsr
+test_Ismnemonic nop
+test_Ismnemonic ora
+test_Ismnemonic pha
+test_Ismnemonic php
+test_Ismnemonic phx
+test_Ismnemonic phy
+test_Ismnemonic pla
+test_Ismnemonic plp
+test_Ismnemonic plx
+test_Ismnemonic ply
+test_Ismnemonic rmb0
+test_Ismnemonic rmb1
+test_Ismnemonic rmb2
+test_Ismnemonic rmb3
+test_Ismnemonic rmb4
+test_Ismnemonic rmb5
+test_Ismnemonic rmb6
+test_Ismnemonic rmb7
+test_Ismnemonic rol
+test_Ismnemonic ror
+test_Ismnemonic rti
+test_Ismnemonic rts
+test_Ismnemonic sbc
+test_Ismnemonic sec
+test_Ismnemonic sed
+test_Ismnemonic sei
+test_Ismnemonic smb0
+test_Ismnemonic smb1
+test_Ismnemonic smb2
+test_Ismnemonic smb3
+test_Ismnemonic smb4
+test_Ismnemonic smb5
+test_Ismnemonic smb6
+test_Ismnemonic smb7
+test_Ismnemonic sta
+test_Ismnemonic stp
+test_Ismnemonic stx
+test_Ismnemonic sty
+test_Ismnemonic stz
+test_Ismnemonic tax
+test_Ismnemonic tay
+test_Ismnemonic trb
+test_Ismnemonic tsb
+test_Ismnemonic tsx
+test_Ismnemonic txa
+test_Ismnemonic txs
+test_Ismnemonic tya
+test_Ismnemonic wai
+
+.setcpu "4510"
+test_Ismnemonic adc
+test_Ismnemonic and
+test_Ismnemonic asl
+test_Ismnemonic asr
+test_Ismnemonic asw
+test_Ismnemonic bbr0
+test_Ismnemonic bbr1
+test_Ismnemonic bbr2
+test_Ismnemonic bbr3
+test_Ismnemonic bbr4
+test_Ismnemonic bbr5
+test_Ismnemonic bbr6
+test_Ismnemonic bbr7
+test_Ismnemonic bbs0
+test_Ismnemonic bbs1
+test_Ismnemonic bbs2
+test_Ismnemonic bbs3
+test_Ismnemonic bbs4
+test_Ismnemonic bbs5
+test_Ismnemonic bbs6
+test_Ismnemonic bbs7
+test_Ismnemonic bcc
+test_Ismnemonic bcs
+test_Ismnemonic beq
+test_Ismnemonic bit
+test_Ismnemonic bmi
+test_Ismnemonic bne
+test_Ismnemonic bpl
+test_Ismnemonic bra
+test_Ismnemonic brk
+test_Ismnemonic bsr
+test_Ismnemonic bvc
+test_Ismnemonic bvs
+test_Ismnemonic clc
+test_Ismnemonic cld
+test_Ismnemonic cle
+test_Ismnemonic cli
+test_Ismnemonic clv
+test_Ismnemonic cmp
+test_Ismnemonic cpx
+test_Ismnemonic cpy
+test_Ismnemonic cpz
+test_Ismnemonic dea
+test_Ismnemonic dec
+test_Ismnemonic dew
+test_Ismnemonic dex
+test_Ismnemonic dey
+test_Ismnemonic dez
+test_Ismnemonic eom
+test_Ismnemonic eor
+test_Ismnemonic ina
+test_Ismnemonic inc
+test_Ismnemonic inw
+test_Ismnemonic inx
+test_Ismnemonic iny
+test_Ismnemonic inz
+test_Ismnemonic jmp
+test_Ismnemonic jsr
+test_Ismnemonic lbcc
+test_Ismnemonic lbcs
+test_Ismnemonic lbeq
+test_Ismnemonic lbmi
+test_Ismnemonic lbne
+test_Ismnemonic lbpl
+test_Ismnemonic lbra
+test_Ismnemonic lbvc
+test_Ismnemonic lbvs
+test_Ismnemonic lda
+test_Ismnemonic ldx
+test_Ismnemonic ldy
+test_Ismnemonic ldz
+test_Ismnemonic lsr
+test_Ismnemonic map
+test_Ismnemonic neg
+test_Ismnemonic nop
+test_Ismnemonic ora
+test_Ismnemonic pha
+test_Ismnemonic phd
+test_Ismnemonic php
+test_Ismnemonic phw
+test_Ismnemonic phx
+test_Ismnemonic phy
+test_Ismnemonic phz
+test_Ismnemonic pla
+test_Ismnemonic plp
+test_Ismnemonic plx
+test_Ismnemonic ply
+test_Ismnemonic plz
+test_Ismnemonic rmb0
+test_Ismnemonic rmb1
+test_Ismnemonic rmb2
+test_Ismnemonic rmb3
+test_Ismnemonic rmb4
+test_Ismnemonic rmb5
+test_Ismnemonic rmb6
+test_Ismnemonic rmb7
+test_Ismnemonic rol
+test_Ismnemonic ror
+test_Ismnemonic row
+test_Ismnemonic rti
+test_Ismnemonic rtn
+test_Ismnemonic rts
+test_Ismnemonic sbc
+test_Ismnemonic sec
+test_Ismnemonic sed
+test_Ismnemonic see
+test_Ismnemonic sei
+test_Ismnemonic smb0
+test_Ismnemonic smb1
+test_Ismnemonic smb2
+test_Ismnemonic smb3
+test_Ismnemonic smb4
+test_Ismnemonic smb5
+test_Ismnemonic smb6
+test_Ismnemonic smb7
+test_Ismnemonic sta
+test_Ismnemonic stx
+test_Ismnemonic sty
+test_Ismnemonic stz
+test_Ismnemonic tab
+test_Ismnemonic tax
+test_Ismnemonic tay
+test_Ismnemonic taz
+test_Ismnemonic tba
+test_Ismnemonic trb
+test_Ismnemonic tsb
+test_Ismnemonic tsx
+test_Ismnemonic tsy
+test_Ismnemonic txa
+test_Ismnemonic txs
+test_Ismnemonic tya
+test_Ismnemonic tys
+test_Ismnemonic tza
+
+.setcpu "HuC6280"
+test_Ismnemonic adc
+test_Ismnemonic and
+test_Ismnemonic asl
+test_Ismnemonic bbr0
+test_Ismnemonic bbr1
+test_Ismnemonic bbr2
+test_Ismnemonic bbr3
+test_Ismnemonic bbr4
+test_Ismnemonic bbr5
+test_Ismnemonic bbr6
+test_Ismnemonic bbr7
+test_Ismnemonic bbs0
+test_Ismnemonic bbs1
+test_Ismnemonic bbs2
+test_Ismnemonic bbs3
+test_Ismnemonic bbs4
+test_Ismnemonic bbs5
+test_Ismnemonic bbs6
+test_Ismnemonic bbs7
+test_Ismnemonic bcc
+test_Ismnemonic bcs
+test_Ismnemonic beq
+test_Ismnemonic bit
+test_Ismnemonic bmi
+test_Ismnemonic bne
+test_Ismnemonic bpl
+test_Ismnemonic bra
+test_Ismnemonic brk
+test_Ismnemonic bsr
+test_Ismnemonic bvc
+test_Ismnemonic bvs
+test_Ismnemonic cla
+test_Ismnemonic clc
+test_Ismnemonic cld
+test_Ismnemonic cli
+test_Ismnemonic clv
+test_Ismnemonic clx
+test_Ismnemonic cly
+test_Ismnemonic cmp
+test_Ismnemonic cpx
+test_Ismnemonic cpy
+test_Ismnemonic csh
+test_Ismnemonic csl
+test_Ismnemonic dea
+test_Ismnemonic dec
+test_Ismnemonic dex
+test_Ismnemonic dey
+test_Ismnemonic eor
+test_Ismnemonic ina
+test_Ismnemonic inc
+test_Ismnemonic inx
+test_Ismnemonic iny
+test_Ismnemonic jmp
+test_Ismnemonic jsr
+test_Ismnemonic lda
+test_Ismnemonic ldx
+test_Ismnemonic ldy
+test_Ismnemonic lsr
+test_Ismnemonic nop
+test_Ismnemonic ora
+test_Ismnemonic pha
+test_Ismnemonic php
+test_Ismnemonic phx
+test_Ismnemonic phy
+test_Ismnemonic pla
+test_Ismnemonic plp
+test_Ismnemonic plx
+test_Ismnemonic ply
+test_Ismnemonic rmb0
+test_Ismnemonic rmb1
+test_Ismnemonic rmb2
+test_Ismnemonic rmb3
+test_Ismnemonic rmb4
+test_Ismnemonic rmb5
+test_Ismnemonic rmb6
+test_Ismnemonic rmb7
+test_Ismnemonic rol
+test_Ismnemonic ror
+test_Ismnemonic rti
+test_Ismnemonic rts
+test_Ismnemonic sax
+test_Ismnemonic say
+test_Ismnemonic sbc
+test_Ismnemonic sec
+test_Ismnemonic sed
+test_Ismnemonic sei
+test_Ismnemonic set
+test_Ismnemonic smb0
+test_Ismnemonic smb1
+test_Ismnemonic smb2
+test_Ismnemonic smb3
+test_Ismnemonic smb4
+test_Ismnemonic smb5
+test_Ismnemonic smb6
+test_Ismnemonic smb7
+test_Ismnemonic st0
+test_Ismnemonic st1
+test_Ismnemonic st2
+test_Ismnemonic sta
+test_Ismnemonic stx
+test_Ismnemonic sty
+test_Ismnemonic stz
+test_Ismnemonic sxy
+test_Ismnemonic tai
+test_Ismnemonic tam
+test_Ismnemonic tam0
+test_Ismnemonic tam1
+test_Ismnemonic tam2
+test_Ismnemonic tam3
+test_Ismnemonic tam4
+test_Ismnemonic tam5
+test_Ismnemonic tam6
+test_Ismnemonic tam7
+test_Ismnemonic tax
+test_Ismnemonic tay
+test_Ismnemonic tdd
+test_Ismnemonic tia
+test_Ismnemonic tii
+test_Ismnemonic tin
+test_Ismnemonic tma
+test_Ismnemonic tma0
+test_Ismnemonic tma1
+test_Ismnemonic tma2
+test_Ismnemonic tma3
+test_Ismnemonic tma4
+test_Ismnemonic tma5
+test_Ismnemonic tma6
+test_Ismnemonic tma7
+test_Ismnemonic trb
+test_Ismnemonic tsb
+test_Ismnemonic tst
+test_Ismnemonic tsx
+test_Ismnemonic txa
+test_Ismnemonic txs
+test_Ismnemonic tya
+
+.setcpu "65816"
+test_Ismnemonic adc
+test_Ismnemonic and
+test_Ismnemonic asl
+test_Ismnemonic bcc
+test_Ismnemonic bcs
+test_Ismnemonic beq
+test_Ismnemonic bit
+test_Ismnemonic bmi
+test_Ismnemonic bne
+test_Ismnemonic bpl
+test_Ismnemonic bra
+test_Ismnemonic brk
+test_Ismnemonic brl
+test_Ismnemonic bvc
+test_Ismnemonic bvs
+test_Ismnemonic clc
+test_Ismnemonic cld
+test_Ismnemonic cli
+test_Ismnemonic clv
+test_Ismnemonic cmp
+test_Ismnemonic cop
+test_Ismnemonic cpa
+test_Ismnemonic cpx
+test_Ismnemonic cpy
+test_Ismnemonic dea
+test_Ismnemonic dec
+test_Ismnemonic dex
+test_Ismnemonic dey
+test_Ismnemonic eor
+test_Ismnemonic ina
+test_Ismnemonic inc
+test_Ismnemonic inx
+test_Ismnemonic iny
+test_Ismnemonic jml
+test_Ismnemonic jmp
+test_Ismnemonic jsl
+test_Ismnemonic jsr
+test_Ismnemonic lda
+test_Ismnemonic ldx
+test_Ismnemonic ldy
+test_Ismnemonic lsr
+test_Ismnemonic mvn
+test_Ismnemonic mvp
+test_Ismnemonic nop
+test_Ismnemonic ora
+test_Ismnemonic pea
+test_Ismnemonic pei
+test_Ismnemonic per
+test_Ismnemonic pha
+test_Ismnemonic phb
+test_Ismnemonic phd
+test_Ismnemonic phk
+test_Ismnemonic php
+test_Ismnemonic phx
+test_Ismnemonic phy
+test_Ismnemonic pla
+test_Ismnemonic plb
+test_Ismnemonic pld
+test_Ismnemonic plp
+test_Ismnemonic plx
+test_Ismnemonic ply
+test_Ismnemonic rep
+test_Ismnemonic rol
+test_Ismnemonic ror
+test_Ismnemonic rti
+test_Ismnemonic rtl
+test_Ismnemonic rts
+test_Ismnemonic sbc
+test_Ismnemonic sec
+test_Ismnemonic sed
+test_Ismnemonic sei
+test_Ismnemonic sep
+test_Ismnemonic sta
+test_Ismnemonic stp
+test_Ismnemonic stx
+test_Ismnemonic sty
+test_Ismnemonic stz
+test_Ismnemonic swa
+test_Ismnemonic tad
+test_Ismnemonic tas
+test_Ismnemonic tax
+test_Ismnemonic tay
+test_Ismnemonic tcd
+test_Ismnemonic tcs
+test_Ismnemonic tda
+test_Ismnemonic tdc
+test_Ismnemonic trb
+test_Ismnemonic tsa
+test_Ismnemonic tsb
+test_Ismnemonic tsc
+test_Ismnemonic tsx
+test_Ismnemonic txa
+test_Ismnemonic txs
+test_Ismnemonic txy
+test_Ismnemonic tya
+test_Ismnemonic tyx
+test_Ismnemonic wai
+test_Ismnemonic wdm
+test_Ismnemonic xba
+test_Ismnemonic xce
+
+.setcpu "sweet16"
+test_Ismnemonic add
+test_Ismnemonic bc
+test_Ismnemonic bk
+test_Ismnemonic bm
+test_Ismnemonic bm1
+test_Ismnemonic bnc
+test_Ismnemonic bnm1
+test_Ismnemonic bnz
+test_Ismnemonic bp
+test_Ismnemonic br
+test_Ismnemonic bs
+test_Ismnemonic bz
+test_Ismnemonic cpr
+test_Ismnemonic dcr
+test_Ismnemonic inr
+test_Ismnemonic ld
+test_Ismnemonic ldd
+test_Ismnemonic pop
+test_Ismnemonic popd
+test_Ismnemonic rs
+test_Ismnemonic rtn
+test_Ismnemonic set
+test_Ismnemonic st
+test_Ismnemonic std
+test_Ismnemonic stp
+test_Ismnemonic sub
+
+ .setcpu "6502"
+
+ .import _exit
+ .export _main
+
+_main:
+ .if ismnemonic_error
+ ldx #$01
+ .else
+ ldx #$00
+ .endif
+ txa
+ jmp _exit
diff --git a/test/err/huge-integer-constant.c b/test/err/huge-integer-constant.c
new file mode 100644
index 000000000..1f423347c
--- /dev/null
+++ b/test/err/huge-integer-constant.c
@@ -0,0 +1,7 @@
+/* too big for internal integer representation */
+unsigned long huge = 4294967296;
+
+int main(void)
+{
+ return 0;
+}
diff --git a/test/err/integer-const-overflow.c b/test/err/integer-const-overflow.c
new file mode 100644
index 000000000..37cc0f01e
--- /dev/null
+++ b/test/err/integer-const-overflow.c
@@ -0,0 +1,20 @@
+/* Integer constant overflow warnings. */
+
+/* Warnings as errors. */
+#pragma warn(error,on)
+
+/* Warn on const overflow */
+#pragma warn(const-overflow,on)
+
+unsigned char a = 256;
+signed char b = 128;
+unsigned char c = -129;
+unsigned short int d = 0x00010000;
+unsigned short int e = 0x80000000;
+signed short int f = 32768L;
+signed short int g = -32769L;
+
+int main(void)
+{
+ return 0;
+}
diff --git a/test/err/struct-duplicate-member.c b/test/err/struct-duplicate-member.c
new file mode 100644
index 000000000..30cd06207
--- /dev/null
+++ b/test/err/struct-duplicate-member.c
@@ -0,0 +1,17 @@
+/* Ensure that a duplicate member in a struct produces an error.
+** https://github.com/cc65/cc65/issues/2015
+*/
+
+struct bads {
+ int a;
+ int a; /* this is an error */
+};
+
+union badu {
+ int a, a; /* also an error */
+};
+
+int main(void)
+{
+ return 0;
+}
diff --git a/test/misc/Makefile b/test/misc/Makefile
index d0b8979b0..c708b160b 100644
--- a/test/misc/Makefile
+++ b/test/misc/Makefile
@@ -163,6 +163,11 @@ $(WORKDIR)/goto.$1.$2.prg: goto.c $(ISEQUAL) | $(WORKDIR)
$(CC65) -t sim$2 -$1 -o $$@ $$< 2>$(WORKDIR)/goto.$1.$2.out
$(ISEQUAL) $(WORKDIR)/goto.$1.$2.out goto.ref
+# should not compile until 3-byte struct by value tests are re-enabled
+$(WORKDIR)/struct-by-value.$1.$2.prg: struct-by-value.c | $(WORKDIR)
+ $(if $(QUIET),echo misc/struct-by-value.$1.$2.prg)
+ $(NOT) $(CC65) -t sim$2 -$1 -o $$@ $$< $(NULLERR)
+
# the rest are tests that fail currently for one reason or another
$(WORKDIR)/sitest.$1.$2.prg: sitest.c | $(WORKDIR)
@echo "FIXME: " $$@ "currently does not compile."
diff --git a/test/misc/struct-by-value.c b/test/misc/struct-by-value.c
new file mode 100644
index 000000000..fc44f8729
--- /dev/null
+++ b/test/misc/struct-by-value.c
@@ -0,0 +1,156 @@
+/* This test ensures that compilation fails if a 3-byte struct by value
+** is attempted, to avoid re-introducting a bug by accident:
+** https://github.com/cc65/cc65/issues/2022
+** When 3-byte structs are re-enabled, this test will compile,
+** which should trigger a "misc" test failure.
+** When this happens:
+** Delete this comment from the top.
+** Replace test/val/struct-by-value.c with this one.
+** See:
+** https://github.com/cc65/cc65/issues/2086
+*/
+
+/* Test of passing and returning structs by value.
+ Structs of 1, 2, 3, 4 bytes are supported.
+ Note that structs of 3 bytes had a past issue:
+ https://github.com/cc65/cc65/issues/2022
+*/
+
+int fail = 0;
+
+struct s1 { char a; };
+struct s2 { char a, b; };
+struct s3 { char a, b, c; };
+struct s4 { char a, b, c, d; };
+
+const struct s1 c1 = { 1 };
+const struct s2 c2 = { 2, 3 };
+const struct s3 c3 = { 4, 5, 6 };
+const struct s4 c4 = { 7, 8, 9, 10 };
+
+struct s1 return1() { return c1; }
+struct s2 return2() { return c2; }
+struct s3 return3() { return c3; }
+struct s4 return4() { return c4; }
+
+int compare1(struct s1 a, struct s1 b)
+{
+ if (a.a != b.a) return 1;
+ return 0;
+}
+
+int compare2(struct s2 a, struct s2 b)
+{
+ if (a.a != b.a) return 1;
+ if (a.b != b.b) return 1;
+ return 0;
+}
+
+int compare3(struct s3 a, struct s3 b)
+{
+ if (a.a != b.a) return 1;
+ if (a.b != b.b) return 1;
+ if (a.c != b.c) return 1;
+ return 0;
+}
+
+int compare4(struct s4 a, struct s4 b)
+{
+ if (a.a != b.a) return 1;
+ if (a.b != b.b) return 1;
+ if (a.c != b.c) return 1;
+ if (a.d != b.d) return 1;
+ return 0;
+}
+
+int pass1(struct s1 p1)
+{
+ struct s1 a1;
+ a1 = p1;
+ if (a1.a != c1.a) return 1;
+ return 0;
+}
+
+int pass2(struct s2 p2)
+{
+ struct s2 a2;
+ a2 = p2;
+ if (a2.a != c2.a) return 1;
+ if (a2.b != c2.b) return 1;
+ return 0;
+}
+
+int pass3(struct s3 p3)
+{
+ struct s3 a3;
+ a3 = p3;
+ if (a3.a != c3.a) return 1;
+ if (a3.b != c3.b) return 1;
+ if (a3.c != c3.c) return 1;
+ return 0;
+}
+
+int pass4(struct s4 p4)
+{
+ struct s4 a4;
+ a4 = p4;
+ if (a4.a != c4.a) return 1;
+ if (a4.b != c4.b) return 1;
+ if (a4.c != c4.c) return 1;
+ if (a4.d != c4.d) return 1;
+ return 0;
+}
+
+void reset(char* gg)
+{
+ char i;
+ for (i=0;i<5;++i) gg[i] = 128+i;
+}
+
+int test(char* gg, char start)
+{
+ char i;
+ for (i=start;i<5;++i)
+ if (gg[i] != 128+i) return 1;
+ return 0;
+}
+
+int main()
+{
+ /* Used to check #2022 bug condition of extra bytes being overwritten. */
+ union
+ {
+ char gg[5];
+ struct s1 g1;
+ struct s2 g2;
+ struct s3 g3;
+ struct s4 g4;
+ } guard;
+
+ reset(guard.gg);
+ guard.g1 = return1();
+ fail += compare1(guard.g1,c1);
+ fail += test(guard.gg,1);
+
+ reset(guard.gg);
+ guard.g2 = return2();
+ fail += compare2(guard.g2,c2);
+ fail += test(guard.gg,2);
+
+ reset(guard.gg);
+ guard.g3 = return3();
+ fail += compare3(guard.g3,c3);
+ fail += test(guard.gg,3);
+
+ reset(guard.gg);
+ guard.g4 = return4();
+ fail += compare4(guard.g4,c4);
+ fail += test(guard.gg,4);
+
+ fail += pass1(c1);
+ fail += pass2(c2);
+ fail += pass3(c3);
+ fail += pass4(c4);
+
+ return fail;
+}
diff --git a/test/readme.txt b/test/readme.txt
index 41d19aee3..d3f17148e 100644
--- a/test/readme.txt
+++ b/test/readme.txt
@@ -68,7 +68,11 @@ compiler is working as expected (when the tests behave as described):
which will require additional changes to the makefile(s).
-To run the tests use "make" in this (top) directory, the makefile should exit
+These tests only require a subset of the platform libraries. In the (top)
+directory above this one, "make libtest" can be used to build only those
+libraries needed for testing, instead of "make lib".
+
+To run the tests use "make" in this (test) directory, the makefile should exit
with no error.
When a test failed you can use "make continue" to run further tests.
diff --git a/test/standard/Makefile b/test/standard/Makefile
index 054623b79..bf513c84e 100644
--- a/test/standard/Makefile
+++ b/test/standard/Makefile
@@ -22,7 +22,7 @@ ifdef QUIET
NULLERR = 2>$(NULLDEV)
endif
-SIM65FLAGS = -x 5000000000 -c
+SIM65FLAGS = -x 4000000000 -c
CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65)
CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65)
diff --git a/test/todo/Makefile b/test/todo/Makefile
index 17561f8f4..062b899ce 100644
--- a/test/todo/Makefile
+++ b/test/todo/Makefile
@@ -31,7 +31,7 @@ CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65)
LD65 := $(if $(wildcard ../../bin/ld65*),..$S..$Sbin$Sld65,ld65)
SIM65 := $(if $(wildcard ../../bin/sim65*),..$S..$Sbin$Ssim65,sim65)
-WORKDIR = ../../testwrk/val
+WORKDIR = ../../testwrk/todo
OPTIONS = g O Os Osi Osir Osr Oi Oir Or
@@ -49,7 +49,7 @@ $(WORKDIR):
define PRG_template
$(WORKDIR)/%.$1.$2.prg: %.c | $(WORKDIR)
- $(if $(QUIET),echo val/$$*.$1.$2.prg)
+ $(if $(QUIET),echo todo/$$*.$1.$2.prg)
$(CC65) -t sim$2 $$(CC65FLAGS) -$1 -o $$(@:.prg=.s) $$< $(NULLERR)
$(CA65) -t sim$2 -o $$(@:.prg=.o) $$(@:.prg=.s) $(NULLERR)
$(LD65) -t sim$2 -o $$@ $$(@:.prg=.o) sim$2.lib $(NULLERR)
diff --git a/test/val/Makefile b/test/val/Makefile
index a3722f7bf..56d8e5ff9 100644
--- a/test/val/Makefile
+++ b/test/val/Makefile
@@ -24,7 +24,7 @@ ifdef QUIET
NULLERR = 2>$(NULLDEV)
endif
-SIM65FLAGS = -x 5000000000 -c
+SIM65FLAGS = -x 4000000000 -c
CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65)
CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65)
diff --git a/test/val/add4.c b/test/val/add4.c
index f02a7fb9c..2371aea69 100644
--- a/test/val/add4.c
+++ b/test/val/add4.c
@@ -22,7 +22,6 @@ long long0 = 0;
long long1 = 0;
unsigned long ulong0 = 0;
unsigned long ulong1 = 0;
-#define NULL 0
char *cP0=NULL;
char *cP1=NULL;
int *iP0=NULL;
diff --git a/test/val/bug2079-struct-assign.c b/test/val/bug2079-struct-assign.c
new file mode 100644
index 000000000..b8a41fe8b
--- /dev/null
+++ b/test/val/bug2079-struct-assign.c
@@ -0,0 +1,66 @@
+
+/* test struct assignment, of structs with a length of 3, which happen to be
+ a special case eg when passing/returning structs
+ related to bugs #2022, #2079 */
+
+#include
+#include
+
+int failures = 0;
+
+struct foo { char a; char b; char c; };
+struct foo foo, bar;
+void f3(void)
+{
+ foo.a = 6;
+ foo.b = 6;
+ foo.c = 6;
+ bar.a = 1;
+ bar.b = 2;
+ bar.c = 3;
+ foo = bar;
+ printf("%d %d %d, %d %d %d (1,2,3 1,2,3)\n",
+ foo.a, foo.b, foo.c,
+ bar.a, bar.b, bar.c);
+ if ((foo.a != 1) || (foo.b != 2) || (foo.c != 3) ||
+ (bar.a != 1) || (bar.b != 2) || (bar.c != 3)) {
+ failures++;
+ }
+ foo.a = 3;
+ foo.b = 2;
+ foo.c = 1;
+ printf("%d %d %d, %d %d %d (3,2,1 1,2,3)\n",
+ foo.a, foo.b, foo.c,
+ bar.a, bar.b, bar.c);
+ if ((foo.a != 3) || (foo.b != 2) || (foo.c != 1) ||
+ (bar.a != 1) || (bar.b != 2) || (bar.c != 3)) {
+ failures++;
+ }
+ bar.a = 5;
+ bar.b = 6;
+ bar.c = 7;
+ printf("%d %d %d, %d %d %d (3,2,1 5,6,7)\n",
+ foo.a, foo.b, foo.c,
+ bar.a, bar.b, bar.c);
+ if ((foo.a != 3) || (foo.b != 2) || (foo.c != 1) ||
+ (bar.a != 5) || (bar.b != 6) || (bar.c != 7)) {
+ failures++;
+ }
+ bar = foo;
+ foo.a = 6;
+ foo.b = 6;
+ foo.c = 6;
+ printf("%d %d %d, %d %d %d (6,6,6 3,2,1)\n",
+ foo.a, foo.b, foo.c,
+ bar.a, bar.b, bar.c);
+ if ((foo.a != 6) || (foo.b != 6) || (foo.c != 6) ||
+ (bar.a != 3) || (bar.b != 2) || (bar.c != 1)) {
+ failures++;
+ }
+}
+
+int main(void)
+{
+ f3();
+ return failures;
+}
diff --git a/test/val/common.h b/test/val/common.h
index dada61a14..61da6c325 100644
--- a/test/val/common.h
+++ b/test/val/common.h
@@ -20,3 +20,4 @@
#define SIZEOF_LONG_32BIT
#define UNSIGNED_CHARS
#define UNSIGNED_BITFIELDS
+#define INTEGER_CONSTANT_MAX_32BIT
diff --git a/test/val/cq241.c b/test/val/cq241.c
index 611b5a376..a6d6c5324 100644
--- a/test/val/cq241.c
+++ b/test/val/cq241.c
@@ -4,6 +4,14 @@
!!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC
*/
+/* INTEGER_CONSTANT_MAX_32BIT
+** This suppresses constants longer than 32-bit, which are now an error:
+** https://github.com/cc65/cc65/pull/2084
+** Because cc65's internal representation is implicitly/explicitly
+** 32-bit in many places, values larger than this aren't representable,
+** but also can't be checked for overflow once accepted.
+*/
+
#include "common.h"
struct defs {
@@ -62,7 +70,12 @@ long pow2(long n) {
return s;
}
- long d[39], o[39], x[39];
+#ifndef INTEGER_CONSTANT_MAX_32BIT
+#define CTCOUNT 39
+#else
+#define CTCOUNT 36
+#endif
+ long d[CTCOUNT], o[CTCOUNT], x[CTCOUNT];
#ifndef NO_OLD_FUNC_DECL
s241(pd0)
@@ -212,13 +225,15 @@ int s241(struct defs *pd0) {
d[33] = 1073741823; o[33] = 07777777777; x[33] = 0x3fffffff;
d[34] = 1073741824; o[34] = 010000000000; x[34] = 0x40000000;
d[35] = 4294967295; o[35] = 037777777777; x[35] = 0xffffffff;
+#if CTCOUNT > 36
d[36] = 4294967296; o[36] = 040000000000; x[36] = 0x100000000;
d[37] = 68719476735; o[37] = 0777777777777; x[37] = 0xfffffffff;
d[38] = 68719476736; o[38] = 01000000000000; x[38] = 0x1000000000;
+#endif
/* WHEW! */
- for (j=0; j<39; j++){
+ for (j=0; j