Finished PET2001 and the rest of the PET character conversions.
2 files changed, 264 insertions(+), 41 deletions(-)

M jasm/strings/string_conversions.cpp
M jasm/strings/string_conversions.h
M jasm/strings/string_conversions.cpp +263 -38
@@ 27,9 27,7 @@ namespace {
 
 const std::string_view StringConversions::_formats[static_cast<size_t>(StringConversions::Format::NumFormats)] = {
 	std::string_view("pet2001"),
-	std::string_view("pet3000"),
-	std::string_view("pet4000"),
-	std::string_view("pet8000"),
+	std::string_view("pet"),
 	std::string_view("vic20"),
 	std::string_view("c16"),
 	std::string_view("plus4"),

          
@@ 62,6 60,10 @@ StringConversions::StringConversions()
 	static_assert(core::array_num_elements(StringConversions::_locales) == static_cast<size_t>(StringConversions::Locale::NumLocales), "Formats mismatch");
 	static_assert(core::array_num_elements(StringConversions::_flags) == static_cast<size_t>(StringConversions::NumFlags), "Formats mismatch");
 
+	// -------
+	// PET2001
+	// -------
+
 	{
 		// fill pet2001 lowercase
 		ConversionMap map;

          
@@ 147,11 149,58 @@ StringConversions::StringConversions()
 		_conversions[format_hash(Format::Pet2001, SubFormat::Uppercase, Locale::English)] = map;
 	}
 
-		{
+	{
 		// fill pet2001 screencode uppercase
 		ConversionMap map;
+		map[L'@'] = 0;
+		for (wchar_t c = 0; c < 26; ++c)
+			map[c + L'A'] = c + 1;
+		map[L'['] = 27;
+		map[L'\\'] = 28;
+		map[L']'] = 29;
+		map[L'\u2191'] = 30;
+		map[L'\u2190'] = 31;
 		for (wchar_t c = 0; c < 32; ++c)
 			map[c + 32] = c + 32;
+
+		map[L'\u2501'] = 0x40; // horizontal line
+		map[L'\u2660'] = 0x41; // spades
+		map[L'\u2572'] = 0x4d; // nw diagonal line
+		map[L'\u2571'] = 0x4e; // ne diagonal line
+		map[L'\u25cf'] = 0x51; // filled circle
+		map[L'\u2665'] = 0x53; // heart
+		map[L'\u2573'] = 0x56; // cross
+		map[L'\u25cb'] = 0x57; // circle
+		map[L'\u2663'] = 0x58; // club
+		map[L'\u2666'] = 0x5a; // diamond
+		map[L'\u254b'] = 0x5b; // junction
+		map[L'\u2503'] = 0x5d; // vertical line
+
+		map[L'\u23c0'] = 0x5e; // pi
+		map[L'\u25e5'] = 0x5f; // upper right triangle
+		map[L'\u2592'] = 0x66; // medium checker
+		map[L'\u25e4'] = 0x69; // upper left triangle
+
+		map[L'\u2523'] = 0x6b; // vertical and right crossing
+		map[L'\u2597'] = 0x6e; // quadrant lower right
+		map[L'\u2517'] = 0x6d; // up and right bend
+		map[L'\u2513'] = 0x6e; // down and left bend
+		map[L'\u250f'] = 0x70; // down and right bend
+		map[L'\u253b'] = 0x71; // up and horizontal crossing
+		map[L'\u2533'] = 0x72; // down and horizontal crossing
+		map[L'\u252b'] = 0x73; // vertical and left crossing
+		map[L'\u2596'] = 0x7b; // quadrant lower left
+		map[L'\u259d'] = 0x7c; // quadrant upper right
+		map[L'\u251b'] = 0x7d; // up and left bend
+		map[L'\u2598'] = 0x7e; // quadrant upper right
+		map[L'\u259a'] = 0x7f; // quadrant upper left lower right
+
+		_conversions[format_hash(Format::Pet2001, SubFormat::UppercaseScreen, Locale::English)] = map;
+	}
+
+	{
+		// fill pet2001 screencode lowercase
+		ConversionMap map;
 		map[L'@'] = 0;
 		for (wchar_t c = 0; c < 26; ++c)
 			map[c + L'A'] = c + 1;

          
@@ 160,46 209,214 @@ StringConversions::StringConversions()
 		map[L']'] = 29;
 		map[L'\u2191'] = 30;
 		map[L'\u2190'] = 31;
+		for (wchar_t c = 0; c < 32; ++c)
+			map[c + 32] = c + 32;
 
-		map[L'\u2501'] = 64; // horizontal line
-		map[L'\u2660'] = 65; // spades
-		map[L'\u2572'] = 77; // nw diagonal line
-		map[L'\u2571'] = 78; // ne diagonal line
-		map[L'\u25cf'] = 81; // filled circle
-		map[L'\u2665'] = 83; // heart
-		map[L'\u2573'] = 86; // cross
-		map[L'\u25cb'] = 87; // circle
-		map[L'\u2663'] = 88; // club
-		map[L'\u2666'] = 90; // diamond
-		map[L'\u254b'] = 91; // junction
-		map[L'\u2503'] = 93; // vertical line
+		map[L'\u2501'] = 0x40; // horizontal line
+		for (wchar_t c = 0; c < 26; ++c)
+			map[c + L'a'] = 0x41 + c;
+		map[L'\u254b'] = 0x5b; // junction
+		map[L'\u2503'] = 0x5d; // vertical line
+
+		map[L'\u2592'] = 0x66; // medium checker
 
-		map[L'\u23c0'] = 94; // pi
-		map[L'\u25e5'] = 95; // upper right triangle
-		map[L'\u2592'] = 102; // medium checker
-		map[L'\u25e4'] = 105; // upper left triangle
+		map[L'\u2523'] = 0x6b; // vertical and right crossing
+		map[L'\u2597'] = 0x6e; // quadrant lower right
+		map[L'\u2517'] = 0x6d; // up and right bend
+		map[L'\u2513'] = 0x6e; // down and left bend
+		map[L'\u250f'] = 0x70; // down and right bend
+		map[L'\u253b'] = 0x71; // up and horizontal crossing
+		map[L'\u2533'] = 0x72; // down and horizontal crossing
+		map[L'\u252b'] = 0x73; // vertical and left crossing
+		map[L'\u2596'] = 0x7b; // quadrant lower left
+		map[L'\u259d'] = 0x7c; // quadrant upper right
+		map[L'\u251b'] = 0x7d; // up and left bend
+		map[L'\u2598'] = 0x7e; // quadrant upper right
+		map[L'\u259a'] = 0x7f; // quadrant upper left lower right
+
+		_conversions[format_hash(Format::Pet2001, SubFormat::UppercaseScreen, Locale::English)] = map;
+	}
+
+	// ---------------------
+	// PET (other than 2001)
+	// ---------------------
 
-		map[L'\u2523'] = 107; // vertical and right crossing
-		map[L'\u2597'] = 108; // quadrant lower right
-		map[L'\u2517'] = 109; // up and right bend
-		map[L'\u2513'] = 110; // down and left bend
-		map[L'\u250f'] = 112; // down and right bend
-		map[L'\u253b'] = 113; // up and horizontal crossing
-		map[L'\u2533'] = 114; // down and horizontal crossing
-		map[L'\u252b'] = 115; // vertical and left crossing
-		map[L'\u2596'] = 123; // quadrant lower left
-		map[L'\u259d'] = 124; // quadrant upper right
-		map[L'\u251b'] = 125; // up and left bend
-		map[L'\u2598'] = 126; // quadrant upper right
-		map[L'\u259a'] = 127; // quadrant upper left lower right
+	{
+		// fill pet lowercase
+		ConversionMap map;
+		for (wchar_t c = 0; c < 32; ++c)
+			map[c + 32] = 32 + c;
+		map[L'@'] = 64;
+		for (wchar_t c = 0; c < 26; ++c)
+			map[c + L'a'] = c + 0x41;
+		map[L'['] = 0x5b;
+		map[L'\\'] = 0x5c;
+		map[L']'] = 0x5d;
+		map[L'\u2191'] = 0x5e; // arrow up
+		map[L'\u2190'] = 0x5f; // arrow left
+		map[L'\u2501'] = 0xc0; // horizontal line
+		for (wchar_t c = 0; c < 26; ++c)
+			map[c + 'A'] = c + 0xc1;
+		map[L'\u254b'] = 0xdb; // junction
+		map[L'\u2503'] = 0xdd; // vertical line
 
-		_conversions[format_hash(Format::Vic20, SubFormat::UppercaseScreen, Locale::English)] = map;
-		_conversions[format_hash(Format::C16, SubFormat::UppercaseScreen, Locale::English)] = map;
-		_conversions[format_hash(Format::Plus4, SubFormat::UppercaseScreen, Locale::English)] = map;
-		_conversions[format_hash(Format::C64, SubFormat::UppercaseScreen, Locale::English)] = map;
-		_conversions[format_hash(Format::C128, SubFormat::UppercaseScreen, Locale::English)] = map;
+		map[L'\u2592'] = 0xa6; // medium checker
+
+		map[L'\u2523'] = 0xab; // vertical and right crossing
+		map[L'\u2597'] = 0xac; // quadrant lower right
+		map[L'\u2517'] = 0xad; // up and right bend
+		map[L'\u2513'] = 0xae; // down and left bend
+		map[L'\u250f'] = 0xb0; // down and right bend
+		map[L'\u253b'] = 0xb1; // up and horizontal crossing
+		map[L'\u2533'] = 0xb2; // down and horizontal crossing
+		map[L'\u252b'] = 0xb3; // vertical and left crossing
+		map[L'\u2596'] = 0xbb; // quadrant lower left
+		map[L'\u259d'] = 0xbc; // quadrant upper right
+		map[L'\u251b'] = 0xbd; // up and left bend
+		map[L'\u2598'] = 0xbe; // quadrant upper left
+		map[L'\u259a'] = 0xbf; // quadrant upper left lower right
+
+		 _conversions[format_hash(Format::Pet, SubFormat::Lowercase, Locale::English)] = map;
 	}
 
+	{
+		// fill pet uppercase
+		ConversionMap map;
+		for (wchar_t c = 0; c < 32; ++c)
+			map[c + 32] = c + 32;
+		map[L'@'] = 64;
+		for (wchar_t c = 0; c < 26; ++c)
+			map[c + L'A'] = 0x41 + c;
+		map[L'['] = 0x5b;
+		map[L'\\'] = 0x5c;
+		map[L']'] = 0x5d;
+		map[L'\u2191'] = 0x5e; // arrow up
+		map[L'\u2190'] = 0x5f; // arrow left
+		map[L'\u2501'] = 0xc0; // horizontal line
+		map[L'\u2660'] = 0xc1; // spades
+		map[L'\u2572'] = 0xcd; // nw diagonal line
+		map[L'\u2571'] = 0xce; // ne diagonal line
+		map[L'\u25cf'] = 0xd1; // filled circle
+		map[L'\u2665'] = 0xd3; // heart
+		map[L'\u2573'] = 0xd6; // cross
+		map[L'\u25cb'] = 0xd7; // circle
+		map[L'\u2663'] = 0xd8; // club
+		map[L'\u2666'] = 0xda; // diamond
+		map[L'\u254b'] = 0xdb; // junction
+		map[L'\u2503'] = 0xdd; // vertical line
+		map[L'\u23c0'] = 0xde; // pi
+		map[L'\u25e5'] = 0xdf; // upper right triangle
+		map[L'\u2592'] = 0xa6; // medium checker
+		map[L'\u25e4'] = 0xe9; // upper left triangle
+
+		map[L'\u2523'] = 0xab; // vertical and right crossing
+		map[L'\u2597'] = 0xac; // quadrant lower right
+		map[L'\u2517'] = 0xad; // up and right bend
+		map[L'\u2513'] = 0xae; // down and left bend
+		map[L'\u250f'] = 0xb0; // down and right bend
+		map[L'\u253b'] = 0xb1; // up and horizontal crossing
+		map[L'\u2533'] = 0xb2; // down and horizontal crossing
+		map[L'\u252b'] = 0xb3; // vertical and left crossing
+		map[L'\u2596'] = 0xbb; // quadrant lower left
+		map[L'\u259d'] = 0xbc; // quadrant upper right
+		map[L'\u251b'] = 0xbd; // up and left bend
+		map[L'\u2598'] = 0xbe; // quadrant upper left
+		map[L'\u259a'] = 0xbf; // quadrant upper left lower right
+
+		_conversions[format_hash(Format::Pet, SubFormat::Uppercase, Locale::English)] = map;
+	}
+
+	{
+		// fill pet screencode uppercase
+		ConversionMap map;
+		map[L'@'] = 0;
+		for (wchar_t c = 0; c < 26; ++c)
+			map[c + L'A'] = c + 1;
+		map[L'['] = 27;
+		map[L'\\'] = 28;
+		map[L']'] = 29;
+		map[L'\u2191'] = 30;
+		map[L'\u2190'] = 31;
+		for (wchar_t c = 0; c < 32; ++c)
+			map[c + 32] = c + 32;
+
+		map[L'\u2501'] = 0x40; // horizontal line
+		map[L'\u2660'] = 0x41; // spades
+		map[L'\u2572'] = 0x4d; // nw diagonal line
+		map[L'\u2571'] = 0x4e; // ne diagonal line
+		map[L'\u25cf'] = 0x51; // filled circle
+		map[L'\u2665'] = 0x53; // heart
+		map[L'\u2573'] = 0x56; // cross
+		map[L'\u25cb'] = 0x57; // circle
+		map[L'\u2663'] = 0x58; // club
+		map[L'\u2666'] = 0x5a; // diamond
+		map[L'\u254b'] = 0x5b; // junction
+		map[L'\u2503'] = 0x5d; // vertical line
+
+		map[L'\u23c0'] = 0x5e; // pi
+		map[L'\u25e5'] = 0x5f; // upper right triangle
+		map[L'\u2592'] = 0x66; // medium checker
+		map[L'\u25e4'] = 0x69; // upper left triangle
+
+		map[L'\u2523'] = 0x6b; // vertical and right crossing
+		map[L'\u2597'] = 0x6e; // quadrant lower right
+		map[L'\u2517'] = 0x6d; // up and right bend
+		map[L'\u2513'] = 0x6e; // down and left bend
+		map[L'\u250f'] = 0x70; // down and right bend
+		map[L'\u253b'] = 0x71; // up and horizontal crossing
+		map[L'\u2533'] = 0x72; // down and horizontal crossing
+		map[L'\u252b'] = 0x73; // vertical and left crossing
+		map[L'\u2596'] = 0x7b; // quadrant lower left
+		map[L'\u259d'] = 0x7c; // quadrant upper right
+		map[L'\u251b'] = 0x7d; // up and left bend
+		map[L'\u2598'] = 0x7e; // quadrant upper right
+		map[L'\u259a'] = 0x7f; // quadrant upper left lower right
+
+		_conversions[format_hash(Format::Pet, SubFormat::UppercaseScreen, Locale::English)] = map;
+	}
+
+	{
+		// fill pet screencode lowercase
+		ConversionMap map;
+		map[L'@'] = 0;
+		for (wchar_t c = 0; c < 26; ++c)
+			map[c + L'a'] = c + 1;
+		map[L'['] = 27;
+		map[L'\\'] = 28;
+		map[L']'] = 29;
+		map[L'\u2191'] = 30;
+		map[L'\u2190'] = 31;
+		for (wchar_t c = 0; c < 32; ++c)
+			map[c + 32] = c + 32;
+
+		map[L'\u2501'] = 0x40; // horizontal line
+		for (wchar_t c = 0; c < 26; ++c)
+			map[c + L'A'] = 0x41 + c;
+		map[L'\u254b'] = 0x5b; // junction
+		map[L'\u2503'] = 0x5d; // vertical line
+
+		map[L'\u2592'] = 0x66; // medium checker
+
+		map[L'\u2523'] = 0x6b; // vertical and right crossing
+		map[L'\u2597'] = 0x6e; // quadrant lower right
+		map[L'\u2517'] = 0x6d; // up and right bend
+		map[L'\u2513'] = 0x6e; // down and left bend
+		map[L'\u250f'] = 0x70; // down and right bend
+		map[L'\u253b'] = 0x71; // up and horizontal crossing
+		map[L'\u2533'] = 0x72; // down and horizontal crossing
+		map[L'\u252b'] = 0x73; // vertical and left crossing
+		map[L'\u2596'] = 0x7b; // quadrant lower left
+		map[L'\u259d'] = 0x7c; // quadrant upper right
+		map[L'\u251b'] = 0x7d; // up and left bend
+		map[L'\u2598'] = 0x7e; // quadrant upper right
+		map[L'\u259a'] = 0x7f; // quadrant upper left lower right
+
+		_conversions[format_hash(Format::Pet, SubFormat::UppercaseScreen, Locale::English)] = map;
+	}
+
+	// -----------------------------
+	// VIC20, C16, Plus/4, C64, C128
+	// -----------------------------
 
 	{
 		// fill petascii lowercase

          
@@ 389,6 606,10 @@ StringConversions::StringConversions()
 		_conversions[format_hash(Format::C128, SubFormat::UppercaseScreen, Locale::English)] = map;
 	}
 
+	// ----
+	// ZX80
+	// ----
+
 	{
 		const wchar_t conversions[] = {
 			L'\u0020', 0,

          
@@ 471,6 692,10 @@ StringConversions::StringConversions()
 		add_characters(conversions, map);
 	}
 
+	// ----
+	// ZX81
+	// ----
+
 	{
 		const wchar_t conversions[] = {
 			L'\u0020', 0,

          
M jasm/strings/string_conversions.h +1 -3
@@ 25,9 25,7 @@ public:
 	enum class Format : uint8_t
 	{
 		Pet2001,
-		Pet3000,
-		Pet4000,
-		Pet8000,
+		Pet,
 		Vic20,
 		C16,
 		Plus4,