From 2ad798bef21fb39d920a83a357eea9a3121e2260 Mon Sep 17 00:00:00 2001
From: marcobaye <marcobaye@4df02467-bbd4-4a76-a152-e7ce94205b78>
Date: Tue, 14 Apr 2020 00:28:31 +0000
Subject: [PATCH] ACME release 0.96.5: Added "//" comments, added
 "--ignore-zeroes" and "--strict-segments" CLI switches.

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@121 4df02467-bbd4-4a76-a152-e7ce94205b78
---
 docs/AddrModes.txt    |  3 +++
 docs/Changes.txt      | 16 ++++++++++++++++
 docs/QuickRef.txt     | 14 +++++++++++++-
 docs/cputypes/all.txt | 23 +++++++++++++++++++++++
 src/acme.c            | 40 +++++++++++++++++++++++-----------------
 src/alu.c             |  8 +++-----
 src/global.c          | 20 ++++++++++++--------
 src/global.h          | 12 +++++++-----
 src/input.c           | 24 ++++++++++++++++++------
 src/mnemo.c           |  4 ++--
 src/output.c          |  7 +++----
 src/version.h         |  8 ++++----
 12 files changed, 127 insertions(+), 52 deletions(-)

diff --git a/docs/AddrModes.txt b/docs/AddrModes.txt
index fbd4789..e94042d 100644
--- a/docs/AddrModes.txt
+++ b/docs/AddrModes.txt
@@ -85,6 +85,9 @@ will be assembled to
   ad fd 00	; lda $00fd
   8f ff 00 00	; sta $0000ff
 
+This feature can be disabled using the "--ignore-zeroes" CLI switch.
+
+
 The other possibility is to use the postfix method (described in the
 next paragraph).
 
diff --git a/docs/Changes.txt b/docs/Changes.txt
index ec6fafd..16c7590 100644
--- a/docs/Changes.txt
+++ b/docs/Changes.txt
@@ -12,6 +12,22 @@ platform used. There should be another help file in this archive
 outlining the platform specific changes.
 
 
+----------------------------------------------------------------------
+Section:   New in release 0.96.5
+----------------------------------------------------------------------
+
+Allowed C++-style comments via "//". Thanks to awsm for the
+    suggestion (and please accept my apologies for taking so long to
+    release this)
+Added "--ignore-zeroes" CLI switch. This disables the "leading zeroes
+    determine number size" algorithm. Thanks to groepaz for the
+    suggestion.
+Added "--strict-segments" CLI switch. This changes warnings about
+    overlapping memory segments into errors. Thanks to groepaz for the
+    suggestion.
+Added 6502 family tree to docs/cpu_types/all.txt
+
+
 ----------------------------------------------------------------------
 Section:   New in release 0.96.4
 ----------------------------------------------------------------------
diff --git a/docs/QuickRef.txt b/docs/QuickRef.txt
index e43455e..ea8bb7c 100644
--- a/docs/QuickRef.txt
+++ b/docs/QuickRef.txt
@@ -227,6 +227,18 @@ Available options are:
     --maxdepth NUMBER      set recursion depth for macro calls and !src
         The default value for this is 64.
 
+    --ignore-zeroes        do not determine number size by leading zeroes
+        Normally, using leading zeroes forces ACME to generate
+        oversized addressing modes, like 3-byte absolute instructions
+        instead of 2-byte zero page instructions.
+        Using this CLI switch disables this behavior.
+
+    --strict-segments      turn segment overlap warnings into errors
+        When changing the program counter, segment overlap warnings may
+        be generated. Using this CLI switch turns those warnings into
+        errors (which is recommended).
+        This strict behavior may become the default in future releases!
+
     -vDIGIT                set verbosity level
         Sets how much additional informational output is generated.
         Higher values mean more output:
@@ -408,7 +420,7 @@ or CRLF characters.
 Every line consists of a non-negative number of "statements" and an
 optional comment. Statements have to be separated from each other
 using colon (":") characters, the comment has to be prefixed with a
-semicolon (";") character.
+semicolon (";") character or two slashes ("//").
 
 Every statement consists of an optional "label" and an optional
 "command". These are separated from each other using any number of
diff --git a/docs/cputypes/all.txt b/docs/cputypes/all.txt
index 1aeb426..61a3da0 100644
--- a/docs/cputypes/all.txt
+++ b/docs/cputypes/all.txt
@@ -140,3 +140,26 @@ This is the cpu in version 2 of the C64DTV. It uses a superset of the
 	SAC #$12		set accumulator mapping
 	SIR #$12		set index register mapping
 - support for some of the undocumented opcodes.
+
+
+
+
+Here's a family tree:
+
+    6502                    (standard)
+     |
+     |\_6510                (+ undocumented opcodes of nmos6502)
+     |
+     |\_c64dtv2             (+ bra/sac/sir and some illegals)
+     |
+      \_65c02               (+ bra/phx/phy/plx/ply/stz/trb/tsb, ...)
+         |
+         |\_65816           (16 bit regs, 24 bit address space, ...)
+         |
+          \_r65c02          (+ bit manipulation instructions)
+             |
+             |\_w65c02      (+ stp/wai)
+             |
+              \_65ce02      (+ Z reg, long branches, ...)
+                 |
+                  \_4502    (+ map/eom)
diff --git a/src/acme.c b/src/acme.c
index bd874dd..1aed384 100644
--- a/src/acme.c
+++ b/src/acme.c
@@ -1,5 +1,5 @@
 // ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
-// Copyright (C) 1998-2017 Marco Baye
+// Copyright (C) 1998-2020 Marco Baye
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -63,6 +63,8 @@ static const char	arg_vicelabels[]	= "VICE labels filename";
 #define OPTION_MSVC		"msvc"
 #define OPTION_COLOR		"color"
 #define OPTION_FULLSTOP		"fullstop"
+#define OPTION_IGNORE_ZEROES	"ignore-zeroes"
+#define OPTION_STRICT_SEGMENTS	"strict-segments"
 // options for "-W"
 #define OPTIONWNO_LABEL_INDENT	"no-label-indent"
 #define OPTIONWNO_OLD_FOR	"no-old-for"
@@ -129,15 +131,16 @@ static void show_help_and_exit(void)
 "      --" OPTION_INITMEM " NUMBER   define 'empty' memory\n"
 "      --" OPTION_MAXERRORS " NUMBER set number of errors before exiting\n"
 "      --" OPTION_MAXDEPTH " NUMBER  set recursion depth for macro calls and !src\n"
+"      --" OPTION_IGNORE_ZEROES "    do not determine number size by leading zeroes\n"
+"      --" OPTION_STRICT_SEGMENTS "  turn segment overlap warnings into errors\n"
 "  -vDIGIT                set verbosity level\n"
 "  -DSYMBOL=VALUE         define global symbol\n"
 "  -I PATH/TO/DIR         add search path for input files\n"
-// as long as there is only one -W option:
-#define OPTIONWNO_LABEL_INDENT	"no-label-indent"
+// TODO: replace these:
 "  -W" OPTIONWNO_LABEL_INDENT "      suppress warnings about indented labels\n"
 "  -W" OPTIONWNO_OLD_FOR "           suppress warnings about old \"!for\" syntax\n"
 "  -W" OPTIONWTYPE_MISMATCH "        enable type checking (warn about type mismatch)\n"
-// when there are more, use next line and add a separate function:
+// with this line and add a separate function:
 //"  -W                     show warning level options\n"
 "      --" OPTION_USE_STDOUT "       fix for 'Relaunch64' IDE (see docs)\n"
 "      --" OPTION_MSVC "             output errors in MS VS format\n"
@@ -342,11 +345,11 @@ static void set_output_format(void)
 
 
 // check CPU type (the cpu type tree must be set up at this point!)
-static void set_starting_cpu(void)
+static void set_starting_cpu(const char expression[])
 {
 	const struct cpu_type	*new_cpu_type;
 
-	keyword_to_dynabuf(cliargs_safe_get_next("CPU type"));
+	keyword_to_dynabuf(expression);
 	new_cpu_type = cputype_find();
 	if (new_cpu_type) {
 		default_cpu = new_cpu_type;
@@ -366,8 +369,8 @@ static void could_not_parse(const char strange[])
 
 // return signed long representation of string.
 // copes with hexadecimal if prefixed with "$", "0x" or "0X".
-// copes with octal if prefixed with "&".
-// copes with binary if prefixed with "%".
+// copes with octal if prefixed with "&".	FIXME - add "0o" prefix?
+// copes with binary if prefixed with "%".	FIXME - add "0b" prefix!
 // assumes decimal otherwise.
 static signed long string_to_number(const char *string)
 {
@@ -396,9 +399,9 @@ static signed long string_to_number(const char *string)
 
 
 // set program counter
-static void set_starting_pc(void)
+static void set_starting_pc(const char expression[])
 {
-	start_address = string_to_number(cliargs_safe_get_next("program counter"));
+	start_address = string_to_number(expression);
 	if ((start_address > -1) && (start_address < 65536))
 		return;
 	fprintf(stderr, "%sProgram counter out of range (0-0xffff).\n", cliargs_error);
@@ -407,9 +410,9 @@ static void set_starting_pc(void)
 
 
 // set initial memory contents
-static void set_mem_contents(void)
+static void set_mem_contents(const char expression[])
 {
-	fill_value = string_to_number(cliargs_safe_get_next("initmem value"));
+	fill_value = string_to_number(expression);
 	if ((fill_value >= -128) && (fill_value <= 255))
 		return;
 	fprintf(stderr, "%sInitmem value out of range (0-0xff).\n", cliargs_error);
@@ -453,11 +456,11 @@ static const char *long_option(const char *string)
 	else if (strcmp(string, OPTION_REPORT) == 0)
 		report_filename = cliargs_safe_get_next(arg_reportfile);
 	else if (strcmp(string, OPTION_SETPC) == 0)
-		set_starting_pc();
+		set_starting_pc(cliargs_safe_get_next("program counter"));
 	else if (strcmp(string, OPTION_CPU) == 0)
-		set_starting_cpu();
+		set_starting_cpu(cliargs_safe_get_next("CPU type"));
 	else if (strcmp(string, OPTION_INITMEM) == 0)
-		set_mem_contents();
+		set_mem_contents(cliargs_safe_get_next("initmem value"));
 	else if (strcmp(string, OPTION_MAXERRORS) == 0)
 		config.max_errors = string_to_number(cliargs_safe_get_next("maximum error count"));
 	else if (strcmp(string, OPTION_MAXDEPTH) == 0)
@@ -465,11 +468,15 @@ static const char *long_option(const char *string)
 //	else if (strcmp(string, "strictsyntax") == 0)
 //		strict_syntax = TRUE;
 	else if (strcmp(string, OPTION_USE_STDOUT) == 0)
-		msg_stream = stdout;
+		config.msg_stream = stdout;
 	else if (strcmp(string, OPTION_MSVC) == 0)
 		config.format_msvc = TRUE;
 	else if (strcmp(string, OPTION_FULLSTOP) == 0)
 		config.pseudoop_prefix = '.';
+	else if (strcmp(string, OPTION_IGNORE_ZEROES) == 0)
+		config.honor_leading_zeroes = FALSE;
+	else if (strcmp(string, OPTION_STRICT_SEGMENTS) == 0)
+		config.segment_warning_is_error = TRUE;
 	PLATFORM_LONGOPTION_CODE
 	else if (strcmp(string, OPTION_COLOR) == 0)
 		config.format_color = TRUE;
@@ -552,7 +559,6 @@ int main(int argc, const char *argv[])
 	// if called without any arguments, show usage info (not full help)
 	if (argc == 1)
 		show_help_and_exit();
-	msg_stream = stderr;
 	cliargs_init(argc, argv);
 	DynaBuf_init();	// inits *global* dynamic buffer - important, so first
 	// Init platform-specific stuff.
diff --git a/src/alu.c b/src/alu.c
index e2f2cc6..4768b04 100644
--- a/src/alu.c
+++ b/src/alu.c
@@ -26,8 +26,6 @@
 #include "symbol.h"
 #include "tree.h"
 
-#define honor_leading_zeroes	1	// FIXME - make a CLI argument for this
-
 
 // constants
 
@@ -424,7 +422,7 @@ static void parse_binary_value(void)	// Now GotByte = "%" or "b"
 		}
 	} while (go_on);
 	// set force bits
-	if (honor_leading_zeroes) {
+	if (config.honor_leading_zeroes) {
 		if (digits > 8) {
 			if (digits > 16) {
 				if (value < 65536)
@@ -470,7 +468,7 @@ static void parse_hexadecimal_value(void)	// Now GotByte = "$" or "x"
 		}
 	} while (go_on);
 	// set force bits
-	if (honor_leading_zeroes) {
+	if (config.honor_leading_zeroes) {
 		if (digits > 2) {
 			if (digits > 4) {
 				if (value < 65536)
@@ -565,7 +563,7 @@ static void parse_octal_value(void)	// Now GotByte = "&"
 		GetByte();
 	}
 	// set force bits
-	if (honor_leading_zeroes) {
+	if (config.honor_leading_zeroes) {
 		if (digits > 3) {
 			if (digits > 6) {
 				if (value < 65536)
diff --git a/src/global.c b/src/global.c
index 424f3ce..fb67614 100644
--- a/src/global.c
+++ b/src/global.c
@@ -1,5 +1,5 @@
 // ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
-// Copyright (C) 1998-2017 Marco Baye
+// Copyright (C) 1998-2020 Marco Baye
 // Have a look at "acme.c" for further info
 //
 // Global stuff - things that are needed by several modules
@@ -8,6 +8,8 @@
 //  2 Jun 2014	Added warn_on_old_for and warn_on_type_mismatch
 // 19 Nov 2014	Merged Johann Klasek's report listing generator patch
 // 23 Nov 2014	Merged Martin Piper's "--msvc" error output patch
+//  9 Jan 2018	Made '/' a syntax char to allow for "//" comments
+// 14 Apr 2020	Added config vars for "ignore zeroes" and "segment warnings to errors"
 #include "global.h"
 #include <stdio.h>
 #include "platform.h"
@@ -66,7 +68,7 @@ const char	exception_syntax[]		= "Syntax error.";
 // 7.......	Byte allowed to start keyword
 // .6......	Byte allowed in keyword
 // ..5.....	Byte is upper case, can be lowercased by OR-ing this bit(!)
-// ...4....	special character for input syntax: 0x00 TAB LF CR SPC : ; }
+// ...4....	special character for input syntax: 0x00 TAB LF CR SPC / : ; }
 // ....3...	preceding sequence of '-' characters is anonymous backward
 //		label. Currently only set for ')', ',' and CHAR_EOS.
 // .....210	currently unused
@@ -76,7 +78,7 @@ const char	Byte_flags[256]	= {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 /*$20*/	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// " !"#$%&'"
-	0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,// "()*+,-./"
+	0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10,// "()*+,-./"
 	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,// "01234567"
 	0x40, 0x40, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,// "89:;<=>?"
 /*$40*/	0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,// "@ABCDEFG"
@@ -112,7 +114,6 @@ char		GotByte;			// Last byte read (processed)
 // global counters
 int		pass_undefined_count;	// "NeedValue" type errors
 int		pass_real_errors;	// Errors yet
-FILE		*msg_stream		= NULL;	// set to stdout by --use-stdout
 struct report 	*report			= NULL;
 
 // configuration
@@ -127,8 +128,11 @@ void config_default(struct config *conf)
 	conf->warn_on_old_for		= TRUE;	// warn if "!for" with old syntax is found
 	conf->warn_on_type_mismatch	= FALSE;	// use type-checking system
 	conf->max_errors		= MAXERRORS;	// errors before giving up
-	conf->format_msvc		= FALSE;	// actually bool, enabled by --msvc
-	conf->format_color		= FALSE;	// actually bool, enabled by --color
+	conf->format_msvc		= FALSE;	// enabled by --msvc
+	conf->format_color		= FALSE;	// enabled by --color
+	conf->msg_stream		= stderr;	// set to stdout by --use-stdout
+	conf->honor_leading_zeroes	= TRUE;		// disabled by --ignore-zeroes
+	conf->segment_warning_is_error	= FALSE;	// enabled by --strict-segments		TODO - toggle default?
 }
 
 // memory allocation stuff
@@ -341,11 +345,11 @@ static void throw_message(const char *message, const char *type)
 {
 	++throw_counter;
 	if (config.format_msvc)
-		fprintf(msg_stream, "%s(%d) : %s (%s %s): %s\n",
+		fprintf(config.msg_stream, "%s(%d) : %s (%s %s): %s\n",
 			Input_now->original_filename, Input_now->line_number,
 			type, section_now->type, section_now->title, message);
 	else
-		fprintf(msg_stream, "%s - File %s, line %d (%s %s): %s\n",
+		fprintf(config.msg_stream, "%s - File %s, line %d (%s %s): %s\n",
 			type, Input_now->original_filename, Input_now->line_number,
 			section_now->type, section_now->title, message);
 }
diff --git a/src/global.h b/src/global.h
index c0a5a63..2d1e520 100644
--- a/src/global.h
+++ b/src/global.h
@@ -1,5 +1,5 @@
 // ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
-// Copyright (C) 1998-2017 Marco Baye
+// Copyright (C) 1998-2020 Marco Baye
 // Have a look at "acme.c" for further info
 //
 // Global stuff - things that are needed by several modules
@@ -65,17 +65,19 @@ extern int	pass_count;
 extern char	GotByte;	// Last byte read (processed)
 extern int	pass_undefined_count;	// "NeedValue" type errors in current pass
 extern int	pass_real_errors;	// Errors yet
-extern FILE	*msg_stream;		// set to stdout by --errors_to_stdout
 // configuration
 struct config {
 	char		pseudoop_prefix;	// '!' or '.'
 	int		process_verbosity;	// level of additional output
-	int		warn_on_indented_labels;	// warn if indented label is encountered
-	int		warn_on_old_for;	// warn if "!for" with old syntax is found
-	int		warn_on_type_mismatch;	// use type-checking system
+	int		warn_on_indented_labels;	// actually bool: warn if indented label is encountered
+	int		warn_on_old_for;	// actually bool: warn if "!for" with old syntax is found
+	int		warn_on_type_mismatch;	// actually bool: use type-checking system
 	signed long	max_errors;	// errors before giving up
 	int		format_msvc;		// actually bool, enabled by --msvc
 	int		format_color;		// actually bool, enabled by --color
+	FILE		*msg_stream;		// defaults to stderr, changed to stdout by --use-stdout
+	int		honor_leading_zeroes;	// actually bool, TRUE, disabled by --ignore-zeroes
+	int		segment_warning_is_error;	// actually bool, FALSE, enabled by --strict-segments
 };
 extern struct config	config;
 
diff --git a/src/input.c b/src/input.c
index 2538f61..8725943 100644
--- a/src/input.c
+++ b/src/input.c
@@ -4,6 +4,7 @@
 //
 // Input stuff
 // 19 Nov 2014	Merged Johann Klasek's report listing generator patch
+//  9 Jan 2018	Allowed "//" comments
 #include "input.h"
 #include "config.h"
 #include "alu.h"
@@ -115,7 +116,7 @@ static void report_srcchar(char new_char)
 // Deliver source code from current file (!) in shortened high-level format
 static char get_processed_from_file(void)
 {
-	int	from_file = 0;
+	static int	from_file	= 0;
 
 	for (;;) {
 		switch (Input_now->state) {
@@ -146,7 +147,7 @@ static char get_processed_from_file(void)
 			if ((BYTEFLAGS(from_file) & BYTEIS_SYNTAX) == 0)
 				return (char) from_file;
 
-			// check special characters ("0x00 TAB LF CR SPC :;}")
+			// check special characters ("0x00 TAB LF CR SPC / : ; }")
 			switch (from_file) {
 			case CHAR_TAB:	// TAB character
 			case ' ':
@@ -169,15 +170,26 @@ static char get_processed_from_file(void)
 				Input_now->state = INPUTSTATE_EOB;
 				return CHAR_EOS;	// end of statement
 
-			case CHAR_STATEMENT_DELIMITER:
-				// just deliver an EOS instead
-				return CHAR_EOS;	// end of statement
-
+			case '/':
+				// to check for "//", get another byte:
+				from_file = getc(Input_now->src.fd);
+				IF_WANTED_REPORT_SRCCHAR(from_file);
+				if (from_file != '/') {
+					// not "//", so:
+					Input_now->state = INPUTSTATE_AGAIN;	// second byte must be parsed normally later on
+					return '/';	// first byte is returned normally right now
+				}
+				// it's really "//", so act as if ';'
+				/*FALLTHROUGH*/
 			case CHAR_COMMENT_SEPARATOR:
 				// remember to skip remainder of line
 				Input_now->state = INPUTSTATE_COMMENT;
 				return CHAR_EOS;	// end of statement
 
+			case CHAR_STATEMENT_DELIMITER:
+				// just deliver an EOS instead
+				return CHAR_EOS;	// end of statement
+
 			default:
 				// complain if byte is 0
 				Throw_error("Source file contains illegal character.");
diff --git a/src/mnemo.c b/src/mnemo.c
index f04eebb..64c29b8 100644
--- a/src/mnemo.c
+++ b/src/mnemo.c
@@ -1,5 +1,5 @@
 // ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
-// Copyright (C) 1998-2017 Marco Baye
+// Copyright (C) 1998-2020 Marco Baye
 // Have a look at "acme.c" for further info
 //
 // Mnemonics stuff
@@ -427,7 +427,7 @@ static struct ronode	mnemos_65ce02[]	= {
 	PREDEFNODE("dew", MERGE(GROUP_MISC,	IDXeDEW)),
 	PREDEFNODE("inw", MERGE(GROUP_MISC,	IDXeINW)),
 	PREDEFNODE("ldz", MERGE(GROUP_MISC,	IDXeLDZ)),
-	PREDEFNODE("phw", MERGE(GROUP_MISC,	IDXePHW | IM_FORCE16)),
+	PREDEFNODE("phw", MERGE(GROUP_MISC,	IDXePHW | IM_FORCE16)),	// when using immediate addressing, arg is 16 bit
 	PREDEFNODE("row", MERGE(GROUP_MISC,	IDXeROW)),
 	PREDEFNODE("rtn", MERGE(GROUP_MISC,	IDXeRTN)),
 	PREDEFNODE("cle", MERGE(GROUP_IMPLIEDONLY, 0x02)),
diff --git a/src/output.c b/src/output.c
index 03e9245..1d79bc5 100644
--- a/src/output.c
+++ b/src/output.c
@@ -22,8 +22,6 @@
 #include "platform.h"
 #include "tree.h"
 
-#define segment_warnings_to_errors	0	// FIXME - make a CLI argument for this
-
 
 // constants
 #define OUTBUFFERSIZE		65536
@@ -121,7 +119,8 @@ static void border_crossed(int current_offset)
 	if (current_offset >= OUTBUFFERSIZE)
 		Throw_serious_error("Produced too much code.");
 	if (pass_count == 0) {
-		if (segment_warnings_to_errors)
+		// TODO: make warn/err an arg for a general "Throw" function
+		if (config.segment_warning_is_error)
 			Throw_error("Segment reached another one, overwriting it.");
 		else
 			Throw_warning("Segment reached another one, overwriting it.");
@@ -453,7 +452,7 @@ static void check_segment(intval_t new_pc)
 	// search ring for matching entry
 	while (test_segment->start <= new_pc) {
 		if ((test_segment->start + test_segment->length) > new_pc) {
-			if (segment_warnings_to_errors)
+			if (config.segment_warning_is_error)
 				Throw_error("Segment starts inside another one, overwriting it.");
 			else
 				Throw_warning("Segment starts inside another one, overwriting it.");
diff --git a/src/version.h b/src/version.h
index 238da06..07f8606 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,5 +1,5 @@
 // ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
-// Copyright (C) 1998-2019 Marco Baye
+// Copyright (C) 1998-2020 Marco Baye
 // Have a look at "acme.c" for further info
 //
 // version info
@@ -7,10 +7,10 @@
 #define version_H
 
 
-#define RELEASE		"0.96.4"	// update before release	FIXME
+#define RELEASE		"0.96.5"	// update before release	FIXME
 #define CODENAME	"Fenchurch"	// update before release
-#define CHANGE_DATE	"20 Apr"	// update before release	FIXME
-#define CHANGE_YEAR	"2019"		// update before release
+#define CHANGE_DATE	"14 Apr"	// update before release	FIXME
+#define CHANGE_YEAR	"2020"		// update before release
 //#define HOME_PAGE	"http://home.pages.de/~mac_bacon/smorbrod/acme/"
 #define HOME_PAGE	"http://sourceforge.net/p/acme-crossass/"	// FIXME