diff --git a/edid-decode.h b/edid-decode.h
index 9f73e9c..6a40092 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -153,7 +153,8 @@ struct edid_state {
 		// CTA-861 block state
 		cta.has_vic_1 = cta.first_svd_might_be_preferred = cta.has_sldb =
 			cta.has_hdmi = cta.has_vcdb = cta.has_vfpdb = false;
-		cta.last_block_was_hdmi_vsdb = cta.have_hf_vsdb = cta.have_hf_scdb = false;
+		cta.previous_cta_tag = 0xfff;
+		cta.have_hf_vsdb = cta.have_hf_scdb = false;
 		cta.block_number = 0;
 		cta.first_svd = true;
 		cta.supported_hdmi_vic_codes = cta.supported_hdmi_vic_vsb_codes = 0;
@@ -244,8 +245,8 @@ struct edid_state {
 		vec_timings_ext preferred_timings;
 		bool preparsed_has_t8vtdb;
 		// Keep track of the found Tag/Extended Tag pairs.
-		// The unsigned value is equal to: (tag << 8) | ext_tag
-		std::set<unsigned> found_tags;
+		// The unsigned value is equal to: (tag) | (OUI enum << 12) or (extended tag) | (tag << 8) | (OUI enum << 12)
+		std::vector<unsigned> found_tags;
 		timings_ext t8vtdb;
 		vec_timings_ext native_timings;
 		bool has_vic_1;
@@ -259,7 +260,7 @@ struct edid_state {
 		bool preparsed_sld;
 		bool has_sldb;
 		unsigned short preparsed_phys_addr;
-		bool last_block_was_hdmi_vsdb;
+		unsigned previous_cta_tag;
 		bool have_hf_vsdb, have_hf_scdb;
 		unsigned block_number;
 		bool first_svd;
@@ -286,8 +287,8 @@ struct edid_state {
 		unsigned native_width, native_height;
 		unsigned block_number;
 		// Keep track of the found CTA-861 Tag/Extended Tag pairs.
-		// The unsigned value is equal to: (tag << 8) | ext_tag
-		std::set<unsigned> found_tags;
+		// The unsigned value is equal to: (tag) | (OUI enum << 12) or (extended tag) | (tag << 8) | (OUI enum << 12)
+		std::vector<unsigned> found_tags;
 	} dispid;
 
 	// Block Map block state
@@ -350,7 +351,7 @@ struct edid_state {
 	void cta_displayid_type_7(const unsigned char *x, unsigned length);
 	void cta_displayid_type_8(const unsigned char *x, unsigned length);
 	void cta_displayid_type_10(const unsigned char *x, unsigned length);
-	void cta_block(const unsigned char *x, bool duplicate);
+	void cta_block(const unsigned char *x, std::vector<unsigned> &found_tags);
 	void preparse_cta_block(const unsigned char *x);
 	void parse_cta_block(const unsigned char *x);
 	void cta_resolve_svr(vec_timings_ext::iterator iter);
diff --git a/parse-cta-block.cpp b/parse-cta-block.cpp
index 71e0041..9ae7597 100644
--- a/parse-cta-block.cpp
+++ b/parse-cta-block.cpp
@@ -2029,13 +2029,15 @@ static void cta_hdmi_audio_block(const unsigned char *x, unsigned length)
 
 #define data_block_o(n) \
 	do { \
+		unsigned ouinum; \
 		data_block_oui(n, x, length, &ouinum); \
 		x += (length < 3) ? length : 3; \
 		length -= (length < 3) ? length : 3; \
 		dooutputname = false; \
+		tag |= ouinum; \
 	} while(0)
 
-void edid_state::cta_block(const unsigned char *x, bool duplicate)
+void edid_state::cta_block(const unsigned char *x, std::vector<unsigned> &found_tags)
 {
 	unsigned length = x[0] & 0x1f;
 	unsigned tag=(x[0] & 0xe0) >> 5;
@@ -2048,7 +2050,6 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
 		x++;
 	}
 
-	unsigned ouinum = 0;
 	bool dooutputname = true;
 	bool audio_block = false;
 	data_block.clear();
@@ -2118,7 +2119,7 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
 	case 0x713:
 	case 0x778:
 	case 0x779:
-		if (duplicate)
+		if (std::find(found_tags.begin(), found_tags.end(), tag) != found_tags.end())
 			fail("Only one instance of this Data Block is allowed.\n");
 	}
 
@@ -2126,28 +2127,25 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
 	if (audio_block && !(cta.byte3 & 0x40))
 		fail("Audio information is present, but bit 6 of Byte 3 of the CTA-861 Extension header indicates no Basic Audio support.\n");
 
-	tag |= ouinum;
 	switch (tag) {
 	case 0x01: cta_audio_block(x, length); break;
 	case 0x02: cta_svd(x, length, false); break;
 	case 0x03|kOUI_HDMI:
 		cta_hdmi_block(x, length);
-		cta.last_block_was_hdmi_vsdb = 1;
-		cta.block_number++;
 		// The HDMI OUI is present, so this EDID represents an HDMI
 		// interface. And HDMI interfaces must use EDID version 1.3
 		// according to the HDMI Specification, so check for this.
 		if (base.edid_minor != 3)
 			fail("The HDMI Specification requires EDID 1.3 instead of 1.%u.\n",
 				 base.edid_minor);
-		return;
+		break;
 	case 0x03|kOUI_HDMIForum:
-		if (!cta.last_block_was_hdmi_vsdb)
+		if (cta.previous_cta_tag != (0x03|kOUI_HDMI))
 			fail("HDMI Forum VSDB did not immediately follow the HDMI VSDB.\n");
 		if (cta.have_hf_scdb || cta.have_hf_vsdb)
 			fail("Duplicate HDMI Forum VSDB/SCDB.\n");
 		cta_hf_scdb(x, length);
-		cta.have_hf_vsdb = 1;
+		cta.have_hf_vsdb = true;
 		break;
 	case 0x03|kOUI_AMD: cta_amd(x, length); break;
 	case 0x03|kOUI_Microsoft: if (length != 0x12) goto dodefault; cta_microsoft(x, length); break;
@@ -2179,7 +2177,7 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
 			fail("Block starts at a wrong offset.\n");
 		break;
 	case 0x779:
-		if (!cta.last_block_was_hdmi_vsdb)
+		if (cta.previous_cta_tag != (0x03|kOUI_HDMI))
 			fail("HDMI Forum SCDB did not immediately follow the HDMI VSDB.\n");
 		if (cta.have_hf_scdb || cta.have_hf_vsdb)
 			fail("Duplicate HDMI Forum VSDB/SCDB.\n");
@@ -2191,7 +2189,7 @@ void edid_state::cta_block(const unsigned char *x, bool duplicate)
 		if (x[0] || x[1])
 			printf("  Non-zero SCDB reserved fields!\n");
 		cta_hf_scdb(x + 2, length - 2);
-		cta.have_hf_scdb = 1;
+		cta.have_hf_scdb = true;
 		break;
 dodefault:
 	default:
@@ -2199,7 +2197,8 @@ dodefault:
 	}
 
 	cta.block_number++;
-	cta.last_block_was_hdmi_vsdb = 0;
+	cta.previous_cta_tag = tag;
+	found_tags.push_back(tag);
 }
 
 void edid_state::preparse_cta_block(const unsigned char *x)
@@ -2345,15 +2344,7 @@ void edid_state::parse_cta_block(const unsigned char *x)
 			unsigned i;
 
 			for (i = 4; i < offset; i += (x[i] & 0x1f) + 1) {
-				unsigned tag = (x[i] & 0xe0) << 3;
-
-				if (tag == 0x700)
-					tag |= x[i + 1];
-				bool duplicate = cta.found_tags.find(tag) != cta.found_tags.end();
-
-				cta_block(x + i, duplicate);
-				if (!duplicate)
-					cta.found_tags.insert(tag);
+				cta_block(x + i, cta.found_tags);
 			}
 
 			data_block.clear();
diff --git a/parse-displayid-block.cpp b/parse-displayid-block.cpp
index 597005e..a38c90e 100644
--- a/parse-displayid-block.cpp
+++ b/parse-displayid-block.cpp
@@ -1556,15 +1556,7 @@ void edid_state::parse_displayid_cta_data_block(const unsigned char *x)
 	x += 3;
 
 	for (i = 0; i < len; i += (x[i] & 0x1f) + 1) {
-		unsigned tag = (x[i] & 0xe0) << 3;
-
-		if (tag == 0x700)
-			tag |= x[i + 1];
-		bool duplicate = dispid.found_tags.find(tag) != dispid.found_tags.end();
-
-		cta_block(x + i, duplicate);
-		if (!duplicate)
-			dispid.found_tags.insert(tag);
+		cta_block(x + i, dispid.found_tags);
 	}
 
 	if (i != len)
@@ -1653,21 +1645,25 @@ void edid_state::preparse_displayid_block(const unsigned char *x)
 
 #define data_block_o(n, a, b) \
 do { \
+	unsigned ouinum; \
 	data_block_oui(n, x + 3, len, &ouinum, tag == 0, a, b); \
 	dooutputname = false; \
+	if (tag != 0x00 && tag != 0x20) tag |= ouinum; \
+	hasoui = true; \
 } while (0)
 
 unsigned edid_state::displayid_block(const unsigned version, const unsigned char *x, unsigned length)
 {
 	unsigned i;
 	unsigned tag = x[0];
-	unsigned ouinum = 0;
+	unsigned tag_version = (tag < 0x20) ? 1 : (tag < 0x7f) ? 2 : (tag < 0x80) ? 1 : 0;
 	bool dooutputname = true;
 	unsigned len = (length < 3) ? 0 : x[2];
+	bool hasoui = false;
 
 		switch (tag) {
 		// DisplayID 1.3:
-	case 0x00: data_block_o("Product Identification Data Block (" + utohex(tag) + ")", true, false); ouinum = 0; break;
+	case 0x00: data_block_o("Product Identification Data Block (" + utohex(tag) + ")", true, false); break;
 		case 0x01: data_block = "Display Parameters Data Block (" + utohex(tag) + ")"; break;
 		case 0x02: data_block = "Color Characteristics Data Block"; break;
 		case 0x03: data_block = "Video Timing Modes Type 1 - Detailed Timings Data Block"; break;
@@ -1689,7 +1685,7 @@ unsigned edid_state::displayid_block(const unsigned version, const unsigned char
 		case 0x13: data_block = "Video Timing Modes Type 6 - Detailed Timings Data Block"; break;
 		// 0x14 .. 0x7e RESERVED for Additional VESA-defined Data Blocks
 		// DisplayID 2.0
-	case 0x20: data_block_o("Product Identification Data Block (" + utohex(tag) + ")", false, false); ouinum = 0; break;
+	case 0x20: data_block_o("Product Identification Data Block (" + utohex(tag) + ")", false, false); break;
 		case 0x21: data_block = "Display Parameters Data Block (" + utohex(tag) + ")"; break;
 		case 0x22: data_block = "Video Timing Modes Type 7 - Detailed Timings Data Block"; break;
 		case 0x23: data_block = "Video Timing Modes Type 8 - Enumerated Timing Codes Data Block"; break;
@@ -1743,16 +1739,15 @@ unsigned edid_state::displayid_block(const unsigned version, const unsigned char
 	if (dooutputname && data_block.length())
 		printf("  %s:\n", data_block.c_str());
 
-	if (version >= 0x20 && (tag < 0x20 || tag == 0x7f))
+	if (version >= 0x20 && tag_version == 1)
 		fail("Use of DisplayID v1.x tag for DisplayID v%u.%u.\n",
 			 version >> 4, version & 0xf);
-	if (version < 0x20 && tag >= 0x20 && tag <= 0x7e)
+	if (version < 0x20 && tag_version == 2)
 		fail("Use of DisplayID v2.0 tag for DisplayID v%u.%u.\n",
 			 version >> 4, version & 0xf);
 
 	unsigned block_rev = x[1] & 0x07;
 
-	tag |= ouinum;
 		switch (tag) {
 	case 0x00: parse_displayid_product_id(x); break;
 	case 0x01: parse_displayid_parameters(x); break;
@@ -1875,7 +1870,7 @@ unsigned edid_state::displayid_block(const unsigned version, const unsigned char
 		}
 	case 0x7e|kOUI_VESA: parse_displayid_vesa(x); break;
 	case 0x81: parse_displayid_cta_data_block(x); break;
-	default: hex_block("    ", x + 3 + (ouinum ? 3 : 0), len - (ouinum ? 3 : 0)); break;
+	default: hex_block("    ", x + 3 + (hasoui ? 3 : 0), (len > (hasoui ? 3 : 0)) ? len - (hasoui ? 3 : 0) : 0); break;
 		}
 
 		if ((tag == 0x00 || tag == 0x20) &&
