From 613ee94f445463c76135c5cb9ebffad6b9027cae Mon Sep 17 00:00:00 2001 From: Jeff Tranter Date: Sun, 30 Apr 2023 18:40:09 -0400 Subject: [PATCH 01/32] Source listing in bootstrap.s is incorrect. The OSI C1P alternative boot file format works, but the code in the source listing does not match the ASCII-coded hex translation (which is actually used). This is confusing to anyone trying to maintain the code. Also, the source code does not assemble when ASM is defined. With these changes the source file should correctly match what is used at run time. --- libsrc/osic1p/bootstrap.s | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s index e88e257fd..292f98914 100644 --- a/libsrc/osic1p/bootstrap.s +++ b/libsrc/osic1p/bootstrap.s @@ -34,7 +34,7 @@ ram_top := __MAIN_START__ + __MAIN_SIZE__ .ifdef ASM - .include "osic1p.inc" + .include "screen-c1p-24x24.s" .macpack generic load := $08 ; private variables @@ -45,20 +45,22 @@ 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 stx load+1 - ldx #(load_size) + 1 - stx count+1 ; save size with each byte incremented separately + lda #load_size + eor #$FF + sta count+1 -L1: dec count +L1: inc count bnz L2 - dec count+1 + inc count+1 bze L3 L2: jsr GETCHAR ; (doesn't change .Y) sta (load),y @@ -70,7 +72,7 @@ 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 From 4d97e30b557172d32435c83b1cb41f8eb5106042 Mon Sep 17 00:00:00 2001 From: Jeff Tranter Date: Sun, 30 Apr 2023 18:40:09 -0400 Subject: [PATCH 02/32] Source listing in bootstrap.s is incorrect. The OSI C1P alternative boot file format works, but the code in the source listing does not match the ASCII-coded hex translation (which is actually used). This is confusing to anyone trying to maintain the code. Also, the source code did not assemble when ASM is defined. Also removed use of branch macros and an unnecessary "<" operator. With these changes the source file should correctly match what is used at run time. --- libsrc/osic1p/bootstrap.s | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s index e88e257fd..52ce31f84 100644 --- a/libsrc/osic1p/bootstrap.s +++ b/libsrc/osic1p/bootstrap.s @@ -34,7 +34,7 @@ ram_top := __MAIN_START__ + __MAIN_SIZE__ .ifdef ASM - .include "osic1p.inc" + .include "screen-c1p-24x24.s" .macpack generic load := $08 ; private variables @@ -45,21 +45,23 @@ 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 stx load+1 - ldx #(load_size) + 1 - stx count+1 ; save size with each byte incremented separately + lda #load_size + eor #$FF + sta count+1 -L1: dec count - bnz L2 - dec count+1 - bze L3 +L1: inc count + bne L2 + inc count+1 + beq L3 L2: jsr GETCHAR ; (doesn't change .Y) sta (load),y @@ -70,12 +72,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 From bf5b37a3b2b0a286e3cc14d1435f0ddbaa6cee4d Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Tue, 2 May 2023 21:27:02 -0400 Subject: [PATCH 03/32] Error check for internal overflow of numerical constant See bug #2026 --- src/cc65/scanner.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 36fd1301b..055c02450 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -522,6 +522,7 @@ static void NumericConst (void) char C; unsigned DigitVal; unsigned long IVal; /* Value */ + int Overflow; /* Get the pp-number first, then parse on it */ CopyPPNumber (&Src); @@ -575,6 +576,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 +584,17 @@ static void NumericConst (void) SB_Clear (&Src); break; } - IVal = (IVal * Base) + DigitVal; + if ((((unsigned long)(IVal * Base)) / Base) != IVal) + Overflow = 1; + IVal = IVal * Base; + if (((unsigned long)(IVal + DigitVal)) < IVal) + Overflow = 1; + IVal += DigitVal; SB_Skip (&Src); } + if (Overflow) + Error ("Numerical constant \"%s\" too large for internal 32-bit representation", + SB_GetConstBuf (&Src)); /* Distinguish between integer and floating point constants */ if (!IsFloat) { From 409235aee65ce5fd807a50b32a2a4ba664aaab70 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Tue, 2 May 2023 22:27:28 -0400 Subject: [PATCH 04/32] Optional warning for implicit constant conversion overflow --- doc/cc65.sgml | 2 ++ src/cc65/error.c | 2 ++ src/cc65/error.h | 1 + src/cc65/typeconv.c | 5 +++++ 4 files changed, 10 insertions(+) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 683249bda..5a094571a 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/src/cc65/error.c b/src/cc65/error.c index 3f36d9e97..6ac3e594b 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/typeconv.c b/src/cc65/typeconv.c index f77ec3951..49dfcc597 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -128,6 +128,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** internally already represented by a long. */ if (NewBits <= OldBits) { + unsigned 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)) { + Warning ("Implicit conversion of constant overflows %d-bit destination", NewBits); + } } /* Do the integer constant <-> absolute address conversion if necessary */ From 387d455cb45d7fc7249ffe1e1d927fb0300e897d Mon Sep 17 00:00:00 2001 From: Jeff Tranter Date: Wed, 3 May 2023 11:16:22 -0400 Subject: [PATCH 05/32] Revised patch. Uses code in source listing. Tested on a real OSI C1P machine. --- libsrc/osic1p/bootstrap.s | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s index 52ce31f84..0d8a74eb7 100644 --- a/libsrc/osic1p/bootstrap.s +++ b/libsrc/osic1p/bootstrap.s @@ -35,7 +35,6 @@ ram_top := __MAIN_START__ + __MAIN_SIZE__ .ifdef ASM .include "screen-c1p-24x24.s" - .macpack generic load := $08 ; private variables count := $0A @@ -51,16 +50,14 @@ LINEDIST = $20 ; Offset in video RAM between two lines sta load stx load+1 - lda #load_size - eor #$FF - sta count+1 + ldx #(load_size) + 1 + stx count+1 ; save size with each byte incremented separately -L1: inc count +L1: dec count bne L2 - inc count+1 + dec count+1 beq L3 L2: jsr GETCHAR ; (doesn't change .Y) sta (load),y @@ -114,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 From 9a502c69dc9d3c4c29791b75d9f03796487e3cc7 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Wed, 3 May 2023 16:46:59 -0400 Subject: [PATCH 06/32] fix tab, braces for 1-line if, Expr->Ival is signed --- src/cc65/error.c | 2 +- src/cc65/scanner.c | 9 ++++++--- src/cc65/typeconv.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cc65/error.c b/src/cc65/error.c index 6ac3e594b..39b067825 100644 --- a/src/cc65/error.c +++ b/src/cc65/error.c @@ -103,7 +103,7 @@ static WarnMapEntry WarnMap[] = { { &WarnUnusedLabel, "unused-label" }, { &WarnUnusedParam, "unused-param" }, { &WarnUnusedVar, "unused-var" }, - { &WarnConstOverflow, "const-overflow" }, + { &WarnConstOverflow, "const-overflow" }, }; Collection DiagnosticStrBufs; diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 055c02450..ec49d0e3c 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -584,17 +584,20 @@ static void NumericConst (void) SB_Clear (&Src); break; } - if ((((unsigned long)(IVal * Base)) / Base) != IVal) + if ((((unsigned long)(IVal * Base)) / Base) != IVal) { Overflow = 1; + } IVal = IVal * Base; - if (((unsigned long)(IVal + DigitVal)) < IVal) + if (((unsigned long)(IVal + DigitVal)) < IVal) { Overflow = 1; + } IVal += DigitVal; SB_Skip (&Src); } - if (Overflow) + if (Overflow) { Error ("Numerical constant \"%s\" too large for internal 32-bit representation", SB_GetConstBuf (&Src)); + } /* Distinguish between integer and floating point constants */ if (!IsFloat) { diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 49dfcc597..e1d95ff63 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -128,7 +128,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** internally already represented by a long. */ if (NewBits <= OldBits) { - unsigned long OldVal = Expr->IVal; + long OldVal = Expr->IVal; /* Cut the value to the new size */ Expr->IVal &= (0xFFFFFFFFUL >> (32 - NewBits)); From 49bd5681136fc4afff5f46f796eeb777c0e691d1 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Wed, 3 May 2023 17:55:02 -0400 Subject: [PATCH 07/32] error test for integer constant too large for internal representation --- test/err/huge-integer-constant.c | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 test/err/huge-integer-constant.c 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; +} From e3cb8dfb9be6e4f9244fdecba6610f6a72116763 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Wed, 3 May 2023 19:27:37 -0400 Subject: [PATCH 08/32] Numerical constant scanner requires explicitly 32-bit sized type for cross-platform consistency --- src/cc65/scanner.c | 16 +++++++++++----- test/val/common.h | 1 + test/val/cq241.c | 19 +++++++++++++++++-- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index ec49d0e3c..f747fb458 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -39,6 +39,7 @@ #include #include #include +#include /* common */ #include "chartype.h" @@ -151,6 +152,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 +527,7 @@ 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 */ @@ -584,19 +590,19 @@ static void NumericConst (void) SB_Clear (&Src); break; } - if ((((unsigned long)(IVal * Base)) / Base) != IVal) { + if (((scan_t)(IVal * Base) / Base) != IVal) { Overflow = 1; } IVal = IVal * Base; - if (((unsigned long)(IVal + DigitVal)) < IVal) { + if (((scan_t)(IVal + DigitVal)) < IVal) { Overflow = 1; } IVal += DigitVal; SB_Skip (&Src); } if (Overflow) { - Error ("Numerical constant \"%s\" too large for internal 32-bit representation", - SB_GetConstBuf (&Src)); + Error ("Numerical constant \"%s\" too large for internal %d-bit representation", + SB_GetConstBuf (&Src), (int)(sizeof(IVal)*8)); } /* Distinguish between integer and floating point constants */ 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 Date: Wed, 3 May 2023 19:42:05 -0400 Subject: [PATCH 09/32] Suppress overflow warning when conversion is an explicit cast --- src/cc65/typeconv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index e1d95ff63..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; @@ -141,7 +141,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) } } - if ((OldVal != Expr->IVal) && IS_Get (&WarnConstOverflow)) { + if ((OldVal != Expr->IVal) && IS_Get (&WarnConstOverflow) && !Explicit) { Warning ("Implicit conversion of constant overflows %d-bit destination", NewBits); } } @@ -288,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 @@ -335,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'"); From b5f255f9123dc898e494321406edd434b89a6d49 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Wed, 3 May 2023 19:54:40 -0400 Subject: [PATCH 10/32] Test case for const-overflow warnings --- test/err/integer-const-overflow.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 test/err/integer-const-overflow.c 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; +} From ca8201a314bc0b6539a49518c334cc297e651764 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Thu, 4 May 2023 05:44:20 -0400 Subject: [PATCH 11/32] Overflow test optimization suggested by kugelfuhr User CHAR_BIT instead of 8 --- src/cc65/scanner.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index f747fb458..54ce02158 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -590,19 +590,15 @@ static void NumericConst (void) SB_Clear (&Src); break; } - if (((scan_t)(IVal * Base) / Base) != IVal) { + if (((scan_t)(IVal * Base + DigitVal) / Base) != IVal) { Overflow = 1; } - IVal = IVal * Base; - if (((scan_t)(IVal + DigitVal)) < IVal) { - Overflow = 1; - } - IVal += DigitVal; + 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)*8)); + SB_GetConstBuf (&Src), (int)(sizeof(IVal)*CHAR_BIT)); } /* Distinguish between integer and floating point constants */ From 69f4cd184779925ca399823acc56e50dcff1dc29 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Thu, 4 May 2023 05:48:48 -0400 Subject: [PATCH 12/32] limits.h was apparently already included somewhere on windows but not linux --- src/cc65/scanner.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 54ce02158..ede77cb2c 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -40,6 +40,7 @@ #include #include #include +#include /* common */ #include "chartype.h" @@ -590,6 +591,7 @@ static void NumericConst (void) SB_Clear (&Src); break; } + /* Test result of adding digit for overflow. */ if (((scan_t)(IVal * Base + DigitVal) / Base) != IVal) { Overflow = 1; } From cfc8a41a031c244ebf5162b08ac88817e7dd175e Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Thu, 4 May 2023 17:07:34 -0400 Subject: [PATCH 13/32] guard test to ensure 3-byte struct isn't re-enabled without evaluation by accident --- test/misc/Makefile | 5 ++ test/misc/struct-by-value.c | 156 ++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 test/misc/struct-by-value.c 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; +} From 9f3e47e9c93d1aa5b439a5ecf2f38ec0a5a41b4c Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 11:04:31 -0400 Subject: [PATCH 14/32] test/standard was never added to test makefile --- test/Makefile | 2 ++ 1 file changed, 2 insertions(+) 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 From 5c20fb28123bd938c18618d321766d85b9ecb4fc Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 11:28:42 -0400 Subject: [PATCH 15/32] test/todo makefile uses testwrk/val by mistake --- test/todo/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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) From c662c7a36f6c31c15858e7656c652f864c9d5aaf Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 12:02:50 -0400 Subject: [PATCH 16/32] use diff-index to prevent commit instead of bash if preferred because the if suppresses all git commit errors, instead of the one error we need to suppress (commit with no changes) --- .github/workflows/snapshot-on-push-master.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index 50f5cd296..cba5b89dd 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -115,9 +115,8 @@ jobs: git config push.default simple git add -A # prevent failure when there is nothing to commit - if git commit -m "Updated from https://github.com/cc65/cc65/commit/${GITHUB_SHA}" ; then - git push - fi + git diff-index --quiet HEAD || git commit -m "Updated from https://github.com/cc65/cc65/commit/${GITHUB_SHA}" + git push # enter secrets under "repository secrets" - name: Upload snapshot to sourceforge From 1c58b302d8857928832931dfb2fd23a7c448919a Mon Sep 17 00:00:00 2001 From: mvax Date: Fri, 5 May 2023 12:31:19 -0400 Subject: [PATCH 17/32] Bugfix for the .ISMNEMONIC, .ISMNEM builtin function --- src/ca65/expr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); } From 17706208e80de82dff33a6e5feef53d330de4d9d Mon Sep 17 00:00:00 2001 From: Jeff Tranter Date: Fri, 5 May 2023 18:02:42 -0400 Subject: [PATCH 18/32] Add support for 48x12 video mode on Challenger 1P. Tested on real C1P hardware. --- doc/osi.sgml | 13 +++++++++++++ libsrc/osic1p/extra/screen-c1p-48x12.s | 16 ++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 libsrc/osic1p/extra/screen-c1p-48x12.s 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/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 From 18570d18b811ed325972db70b8a21d3668e1e80a Mon Sep 17 00:00:00 2001 From: mvax Date: Fri, 5 May 2023 18:43:10 -0400 Subject: [PATCH 19/32] add test --- test/asm/err/ismnemonic.s | 808 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 808 insertions(+) create mode 100644 test/asm/err/ismnemonic.s diff --git a/test/asm/err/ismnemonic.s b/test/asm/err/ismnemonic.s new file mode 100644 index 000000000..438afed70 --- /dev/null +++ b/test/asm/err/ismnemonic.s @@ -0,0 +1,808 @@ +; 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" + +.macro test_Ismnemonic instr + .if .ismnemonic(instr) + ; do nothing + .else + .error .sprintf(".ISMNEMONIC failed for instruction: %s", .string(instr)) + .endif +.endmacro + +; 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) + .error ".ISMNEMONIC with CPU set to 'none' should not match any instructions." +.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 From c5cf32ac47836b770e73323c10a5aa6b5e8d1195 Mon Sep 17 00:00:00 2001 From: mvax Date: Fri, 5 May 2023 18:50:44 -0400 Subject: [PATCH 20/32] add test - fix --- test/asm/{err => val}/ismnemonic.s | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/asm/{err => val}/ismnemonic.s (100%) diff --git a/test/asm/err/ismnemonic.s b/test/asm/val/ismnemonic.s similarity index 100% rename from test/asm/err/ismnemonic.s rename to test/asm/val/ismnemonic.s From 7994889213352a82c904efd06f5b82bbfdf193e7 Mon Sep 17 00:00:00 2001 From: mvax Date: Fri, 5 May 2023 19:07:14 -0400 Subject: [PATCH 21/32] add test - fix again --- test/asm/val/ismnemonic.s | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/test/asm/val/ismnemonic.s b/test/asm/val/ismnemonic.s index 438afed70..4ba74c97f 100644 --- a/test/asm/val/ismnemonic.s +++ b/test/asm/val/ismnemonic.s @@ -13,18 +13,22 @@ ; "65816" ; "sweet16" +; count any errors: +ismnemonic_error .set 0 + +; macro to test an instruction .macro test_Ismnemonic instr .if .ismnemonic(instr) ; do nothing .else - .error .sprintf(".ISMNEMONIC failed for instruction: %s", .string(instr)) + ismnemonic_error .set ismnemonic_error + 1 .endif .endmacro ; 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) - .error ".ISMNEMONIC with CPU set to 'none' should not match any instructions." + ismnemonic_error .set ismnemonic_error + 1 .endif .setcpu "6502" @@ -806,3 +810,17 @@ 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 From dd0a2bf1bc78188b75a22003590f20a4fedac941 Mon Sep 17 00:00:00 2001 From: mvax Date: Fri, 5 May 2023 19:10:16 -0400 Subject: [PATCH 22/32] add test - fix stlye --- test/asm/val/ismnemonic.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/asm/val/ismnemonic.s b/test/asm/val/ismnemonic.s index 4ba74c97f..a4534a9c4 100644 --- a/test/asm/val/ismnemonic.s +++ b/test/asm/val/ismnemonic.s @@ -815,7 +815,7 @@ test_Ismnemonic sub .import _exit .export _main - + _main: .if ismnemonic_error ldx #$01 From 8d048699ee6b33c68f06bc6d0a16e521a733a386 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 21:32:34 -0400 Subject: [PATCH 23/32] grc65 fix flawed text parsing Was using fseek(F,-1,SEEK_CUR) which is invalid for text files, behaviour unreliable across platforms. Added check for internal buffer overflow. --- src/grc65/main.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/grc65/main.c b/src/grc65/main.c index 349b5c110..ac654300d 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -850,8 +850,12 @@ 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); + 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 = ' '; if (a == ',' && quote) a = ' '; if (a == '\042') quote =! quote; @@ -873,13 +877,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!"); From f2e7609046b4febb23a5726f2f4dbd1489aac929 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 21:45:57 -0400 Subject: [PATCH 24/32] sim65 cycles 32-bit range fix long is 64-bit on some platforms, making this inconsistent, added range check to catch overflow. reduced tests requesting 5 billion cycles to 2^32-1 so they can fun on 32-bit long sim65. --- src/sim65/main.c | 5 +++++ test/asm/val/Makefile | 3 ++- test/standard/Makefile | 3 ++- test/val/Makefile | 3 ++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/sim65/main.c b/src/sim65/main.c index f2daf9295..9e371fd5d 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -36,6 +36,7 @@ #include #include #include +#include /* common */ #include "abend.h" @@ -140,6 +141,10 @@ static void OptQuitXIns (const char* Opt attribute ((unused)), /* quit after MaxCycles cycles */ { MaxCycles = strtoul(Arg, NULL, 0); + /* Guard against overflow. */ + if (MaxCycles == ULONG_MAX && errno == ERANGE) { + Error("'-x parameter out of range. Max: %lu",ULONG_MAX); + } } static unsigned char ReadProgramFile (void) diff --git a/test/asm/val/Makefile b/test/asm/val/Makefile index 91dae9afd..49b6d5290 100644 --- a/test/asm/val/Makefile +++ b/test/asm/val/Makefile @@ -22,7 +22,8 @@ ifdef QUIET NULLERR = 2>$(NULLDEV) endif -SIM65FLAGS = -x 5000000000 +# sim65 can support 64-bit cycle counts on some platforms, but not all. This must fit in 32-bit. +SIM65FLAGS = -x 4294967295 CA65 := $(if $(wildcard ../../../bin/ca65*),..$S..$S..$Sbin$Sca65,ca65) LD65 := $(if $(wildcard ../../../bin/ld65*),..$S..$S..$Sbin$Sld65,ld65) diff --git a/test/standard/Makefile b/test/standard/Makefile index 054623b79..9993ba699 100644 --- a/test/standard/Makefile +++ b/test/standard/Makefile @@ -22,7 +22,8 @@ ifdef QUIET NULLERR = 2>$(NULLDEV) endif -SIM65FLAGS = -x 5000000000 -c +# sim65 can support 64-bit cycle counts on some platforms, but not all. This must fit in 32-bit. +SIM65FLAGS = -x 4294967295 -c CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65) diff --git a/test/val/Makefile b/test/val/Makefile index a3722f7bf..8820e535a 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -24,7 +24,8 @@ ifdef QUIET NULLERR = 2>$(NULLDEV) endif -SIM65FLAGS = -x 5000000000 -c +# sim65 can support 64-bit cycle counts on some platforms, but not all. This must fit in 32-bit. +SIM65FLAGS = -x 4294967295 -c CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65) From 773716c32ae0f19a78264c511d89758600288dce Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 21:46:11 -0400 Subject: [PATCH 25/32] sim65 close(-1) crash fix test/val/constexpr.c relies on close(-1) to return -1 for some reason (comment says "abuse"), but on MSVC close(-1) is treated as a security issue and terminates the program instead of returning -1 simulating this desire for sim65, though constexpr.c may also warrant a review --- src/sim65/paravirt.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 9e5c28432..0b16f89e9 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -242,7 +242,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); } From c03d00bc805ffdda6afe1866d6263e7eef098a39 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 21:46:42 -0400 Subject: [PATCH 26/32] sim65 suppress uninitialized variable warning the EOF check was protecting uninitialized Val2 but the compiler can't figure that out --- src/sim65/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sim65/main.c b/src/sim65/main.c index 9e371fd5d..27299168e 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -189,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); From df749abbfba01458907fd954beb47e96756d4fe7 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 21:56:52 -0400 Subject: [PATCH 27/32] libtest target alternative to libs saves me about 20 minutes if I only want to run tests --- Makefile | 4 ++-- libsrc/Makefile | 8 +++++++- test/readme.txt | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 909de81ec..29fcbbf96 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ mostlyclean clean: avail unavail bin: @$(MAKE) -C src --no-print-directory $@ -lib: +lib libtest: @$(MAKE) -C libsrc --no-print-directory $@ doc html info: @@ -43,7 +43,7 @@ util: checkstyle: @$(MAKE) -C .github/checks --no-print-directory $@ -# simple "test" target, only run regression tests for c64 target +# runs regression tests, requires libtest target libraries test: @$(MAKE) -C test --no-print-directory $@ diff --git a/libsrc/Makefile b/libsrc/Makefile index 627897d9b..732fa1d0e 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) 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. From a022f7203dca1b7b4a00a2fdfff577b9f08ec90d Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Fri, 5 May 2023 22:05:10 -0400 Subject: [PATCH 28/32] workflow for manually dispatched Windows build and test --- .github/workflows/build-on-pull-request.yml | 4 ++ .github/workflows/snapshot-on-push-master.yml | 4 ++ .github/workflows/windows-test-manual.yml | 43 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 .github/workflows/windows-test-manual.yml diff --git a/.github/workflows/build-on-pull-request.yml b/.github/workflows/build-on-pull-request.yml index 05d6a4a39..57f00751d 100644 --- a/.github/workflows/build-on-pull-request.yml +++ b/.github/workflows/build-on-pull-request.yml @@ -67,3 +67,7 @@ jobs: - name: Build app (release) run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release + + # The regression tests are currently too slow to run for this Windows build, + # but the "Windows Test Manual" workflow (windows-test-manual.yml) can by + # manually dispatched from the Actions menu to test as needed. diff --git a/.github/workflows/snapshot-on-push-master.yml b/.github/workflows/snapshot-on-push-master.yml index 50f5cd296..43fcce0a8 100644 --- a/.github/workflows/snapshot-on-push-master.yml +++ b/.github/workflows/snapshot-on-push-master.yml @@ -29,6 +29,10 @@ jobs: - name: Build app (release) run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release + # The regression tests are currently too slow to run for this Windows build, + # but the "Windows Test Manual" workflow (windows-test-manual.yml) can by + # manually dispatched from the Actions menu to test as needed. + build_linux: name: Build, Test, and Snapshot (Linux) if: github.repository == 'cc65/cc65' diff --git a/.github/workflows/windows-test-manual.yml b/.github/workflows/windows-test-manual.yml new file mode 100644 index 000000000..854327726 --- /dev/null +++ b/.github/workflows/windows-test-manual.yml @@ -0,0 +1,43 @@ +name: Windows Test Manual +# Manually dispatched because it's much slower than the Linux test. + +on: + workflow_dispatch: + +jobs: + build_windows: + name: Build, Test (Windows MSVC) + runs-on: windows-latest + + steps: + - name: Git Setup + shell: bash + run: git config --global core.autocrlf input + + - name: Checkout source + uses: actions/checkout@v3 + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + + - name: Build app (MSVC debug) + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Debug + + - name: Build app (MSVC release) + run: msbuild src\cc65.sln -t:rebuild -property:Configuration=Release + + - name: Build utils (MinGW) + shell: cmd + run: make -j2 util + + - name: Build the platform libraries (make lib) + shell: cmd + run: make -j2 lib QUIET=1 + + - name: Run the regression tests (make test) + shell: cmd + run: make test QUIET=1 + + - name: Test that the samples can be built (make samples) + shell: cmd + run: make -j2 samples From 1df7ab0352a43546c6ece76830594a687681c938 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 6 May 2023 11:55:21 -0400 Subject: [PATCH 29/32] opening brace on same line as while other AbEnd messages don't end in . --- src/grc65/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/grc65/main.c b/src/grc65/main.c index ac654300d..adce3dc47 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -851,10 +851,9 @@ static char *filterInput (FILE *F, char *tbl) int a, prevchar = -1, i = 0, bracket = 0, quote = 1; a = getc(F); - while (1) - { + while (1) { if (i >= BLOODY_BIG_BUFFER) { - AbEnd ("File too large for internal parsing buffer (%d bytes).",BLOODY_BIG_BUFFER); + AbEnd ("File too large for internal parsing buffer (%d bytes)",BLOODY_BIG_BUFFER); } if ((a == '\n') || (a == '\015')) a = ' '; if (a == ',' && quote) a = ' '; From 532681c9613af15b1993e08db12761855c9707c6 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 6 May 2023 12:06:06 -0400 Subject: [PATCH 30/32] braces were requested combining the two a = ' ' cases was requested --- src/grc65/main.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/grc65/main.c b/src/grc65/main.c index adce3dc47..7d31bfc52 100644 --- a/src/grc65/main.c +++ b/src/grc65/main.c @@ -855,12 +855,20 @@ static char *filterInput (FILE *F, char *tbl) if (i >= BLOODY_BIG_BUFFER) { AbEnd ("File too large for internal parsing buffer (%d bytes)",BLOODY_BIG_BUFFER); } - if ((a == '\n') || (a == '\015')) a = ' '; - if (a == ',' && quote) a = ' '; - if (a == '\042') quote =! quote; + 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'; From fe35386b794b5359c726a5867b26f8dc58c26615 Mon Sep 17 00:00:00 2001 From: mvax Date: Sat, 6 May 2023 12:56:34 -0400 Subject: [PATCH 31/32] add test - add overloading instruction test --- test/asm/val/ismnemonic.s | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/test/asm/val/ismnemonic.s b/test/asm/val/ismnemonic.s index a4534a9c4..2d131e7a9 100644 --- a/test/asm/val/ismnemonic.s +++ b/test/asm/val/ismnemonic.s @@ -21,14 +21,34 @@ ismnemonic_error .set 0 .if .ismnemonic(instr) ; do nothing .else - ismnemonic_error .set ismnemonic_error + 1 + 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 ismnemonic_error + 1 + ismnemonic_error .set 1 .endif .setcpu "6502" From 84f0ab322d4b056191fd09d8fbc792ba1e045453 Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Sat, 6 May 2023 13:54:28 -0400 Subject: [PATCH 32/32] sim65: cycles does not increment 1 at a time, so some small overhead is needed in range check --- src/sim65/main.c | 11 ++++++++--- test/asm/val/Makefile | 2 +- test/standard/Makefile | 2 +- test/val/Makefile | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/sim65/main.c b/src/sim65/main.c index 27299168e..d92d52ef6 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -64,6 +64,12 @@ const char* ProgramFile; /* exit simulator after MaxCycles Cycles */ unsigned long MaxCycles; +/* maximum number of cycles that can be tested, +** requires overhead for longest possible instruction, +** which should be 7, using 16 for safety. +*/ +#define MAXCYCLES_LIMIT (ULONG_MAX-16) + /* Header signature 'sim65' */ static const unsigned char HeaderSignature[] = { 0x73, 0x69, 0x6D, 0x36, 0x35 @@ -73,7 +79,6 @@ static const unsigned char HeaderSignature[] = { static const unsigned char HeaderVersion = 2; - /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -142,8 +147,8 @@ static void OptQuitXIns (const char* Opt attribute ((unused)), { MaxCycles = strtoul(Arg, NULL, 0); /* Guard against overflow. */ - if (MaxCycles == ULONG_MAX && errno == ERANGE) { - Error("'-x parameter out of range. Max: %lu",ULONG_MAX); + if (MaxCycles >= MAXCYCLES_LIMIT) { + Error("'-x parameter out of range. Max: %lu",MAXCYCLES_LIMIT); } } diff --git a/test/asm/val/Makefile b/test/asm/val/Makefile index 49b6d5290..09a6b91bc 100644 --- a/test/asm/val/Makefile +++ b/test/asm/val/Makefile @@ -23,7 +23,7 @@ ifdef QUIET endif # sim65 can support 64-bit cycle counts on some platforms, but not all. This must fit in 32-bit. -SIM65FLAGS = -x 4294967295 +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/standard/Makefile b/test/standard/Makefile index 9993ba699..40299c1bf 100644 --- a/test/standard/Makefile +++ b/test/standard/Makefile @@ -23,7 +23,7 @@ ifdef QUIET endif # sim65 can support 64-bit cycle counts on some platforms, but not all. This must fit in 32-bit. -SIM65FLAGS = -x 4294967295 -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/Makefile b/test/val/Makefile index 8820e535a..158967f9e 100644 --- a/test/val/Makefile +++ b/test/val/Makefile @@ -25,7 +25,7 @@ ifdef QUIET endif # sim65 can support 64-bit cycle counts on some platforms, but not all. This must fit in 32-bit. -SIM65FLAGS = -x 4294967295 -c +SIM65FLAGS = -x 4000000000 -c CC65 := $(if $(wildcard ../../bin/cc65*),..$S..$Sbin$Scc65,cc65) CA65 := $(if $(wildcard ../../bin/ca65*),..$S..$Sbin$Sca65,ca65)