From 2e7fc37ad25448a3652d18a3d38c5151fd8e0db7 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Mon, 4 Mar 2013 17:44:41 +0000
Subject: [PATCH] Fix incorrect HEX extended address parsing in the Printer
 class bootloader.

---
 Bootloaders/Printer/BootloaderPrinter.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/Bootloaders/Printer/BootloaderPrinter.c b/Bootloaders/Printer/BootloaderPrinter.c
index 3a14fdce5..fba323c2b 100644
--- a/Bootloaders/Printer/BootloaderPrinter.c
+++ b/Bootloaders/Printer/BootloaderPrinter.c
@@ -59,6 +59,8 @@ struct
 	uint8_t  Checksum;
 	/** Starting address of the last addressed FLASH page. */
 	uint32_t PageStartAddress;
+	/** Current 32-bit byte extended base address in FLASH being targeted. */
+	uint32_t CurrBaseAddress;
 	/** Current 32-bit byte address in FLASH being targeted. */
 	uint32_t CurrAddress;
 } HEXParser =
@@ -117,7 +119,7 @@ static void ParseIntelHEXByte(const char ReadCharacter)
 	if ((HEXParser.ParserState == HEX_PARSE_STATE_WAIT_LINE) || (ReadCharacter == ':'))
 	{
 		HEXParser.Checksum     = 0;
-		HEXParser.CurrAddress &= ~0xFFFF;
+		HEXParser.CurrAddress  = HEXParser.CurrBaseAddress;
 		HEXParser.ParserState  = HEX_PARSE_STATE_WAIT_LINE;
 		HEXParser.ReadMSB      = false;
 
@@ -154,12 +156,12 @@ static void ParseIntelHEXByte(const char ReadCharacter)
 			break;
 
 		case HEX_PARSE_STATE_ADDRESS_HIGH:
-			HEXParser.CurrAddress |= ((uint16_t)HEXParser.Data << 8);
+			HEXParser.CurrAddress += ((uint16_t)HEXParser.Data << 8);
 			HEXParser.ParserState  = HEX_PARSE_STATE_ADDRESS_LOW;
 			break;
 
 		case HEX_PARSE_STATE_ADDRESS_LOW:
-			HEXParser.CurrAddress |= HEXParser.Data;
+			HEXParser.CurrAddress += HEXParser.Data;
 			HEXParser.ParserState  = HEX_PARSE_STATE_RECORD_TYPE;
 			break;
 
@@ -172,6 +174,14 @@ static void ParseIntelHEXByte(const char ReadCharacter)
 			/* Track the number of read data bytes in the record */
 			HEXParser.DataRem--;
 
+			/* Protect the bootloader against being written to */
+			if (HEXParser.CurrAddress >= BOOT_START_ADDR)
+			{
+				HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE;
+				PageDirty = false;
+				return;
+			}
+
 			/* Wait for a machine word (two bytes) of data to be read */
 			if (HEXParser.DataRem & 0x01)
 			{
@@ -210,9 +220,14 @@ static void ParseIntelHEXByte(const char ReadCharacter)
 					}
 					break;
 
+				case HEX_RECORD_TYPE_ExtendedSegmentAddress:
+					/* Extended address data - store the upper 12-bits of the new address */
+					HEXParser.CurrBaseAddress = (((uint32_t)HEXParser.PrevData << 8) | HEXParser.Data) << 4;
+					break;
+
 				case HEX_RECORD_TYPE_ExtendedLinearAddress:
 					/* Extended address data - store the upper 16-bits of the new address */
-					HEXParser.CurrAddress |= (uint32_t)HEXParser.Data << (HEXParser.DataRem ? 24 : 16);
+					HEXParser.CurrBaseAddress = (((uint32_t)HEXParser.PrevData << 8) | HEXParser.Data) << 16;
 					break;
 			}
 
-- 
GitLab