Re: [hatari-devel] Setting TOS language / keyboard

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Hi,

On 29.5.2022 21.57, Thomas Huth wrote:
Am Sun, 29 May 2022 12:30:17 +0300
schrieb Eero Tamminen <oak@xxxxxxxxxxxxxx>:
What if I add separate "--country-code" option for setting TOS country
code on non-NVRAM machines?

Honestly, I don't have a real good opinion here. --country-code is maybe
cleaner, but it could also be more confusing to the user if we provide more
and more options. So maybe start with --language and see whether users
complain?

Attached are patches to get NVRAM language default from LANG, and new "--country" option to set country code for NVRAM-less machines + appropriate documentation update.

How does that look like?


	- Eero
From 202a69178edf777d8e5d6013e7ea9af68cf8fc6b Mon Sep 17 00:00:00 2001
From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
Date: Thu, 12 May 2022 21:29:43 +0300
Subject: [PATCH 2/2] Add "--country" option for NVRAM-less machines with
 EmuTOS

Added also option helper function for country codes now that there are
3 options needing it, and split TOS_ShowCountryCodes() off from
TOS_ParseCountryCode() for better option error reporting.

Noted in NVRAM layout option what are potential issues when either
that, or this new option changes TOS keyboard layout.
---
 doc/hatari.1                 | 23 +++++++++++++++++++--
 doc/manual.html              | 24 ++++++++++++++++++++--
 doc/release-notes.txt        |  3 +++
 src/configuration.c          |  2 ++
 src/falcon/nvram.h           |  7 +++++++
 src/includes/configuration.h |  1 +
 src/includes/tos.h           |  3 ++-
 src/options.c                | 40 +++++++++++++++++++++++++-----------
 src/tos.c                    | 32 +++++++++++++++++++++--------
 9 files changed, 109 insertions(+), 26 deletions(-)

diff --git a/doc/hatari.1 b/doc/hatari.1
index 73dff208..44e98395 100644
--- a/doc/hatari.1
+++ b/doc/hatari.1
@@ -65,10 +65,29 @@ files
 Load keyboard mapping from <file>. "Symbolic" mapping will be used as
 fallback for keys not defined there
 .TP
+.B \-\-country <x>
+Set EmuTOS ROM country code on Mega/ST/STe machines lacking NVRAM, 
+when EmuTOS indicates supporting multiple ones.
+
+In 512k EmuTOS images, country code selects the TOS keyboard layout
+and screen refresh (US = 60Hz NTSC, 50Hz PAL otherwise).  In 1024k
+EmuTOS images (coming with Hatari binaries and supporting multiple
+languages), country code selects also TOS language.
+
+Alternatively, one can use "tos-lang-change" tool from EmuTOS project
+to modify country code in the ROM image file itself. That works
+also for TOS v4
+.TP
 .B \-\-layout <x>
 Set NVRAM keyboard layout value. While both TT and Falcon machines
-have NVRAM, only TOS v4 and EmuTOS 1024k ROM versions support multiple
-layouts
+have NVRAM, only TOS v4 and EmuTOS 512k / 1024k ROM versions support
+multiple layouts.
+
+Regardless of whether keyboard layout change is done through the ROM
+country code or NVRAM setting, it may impact your key mappings in
+Hatari key mapping files, Hatari Python UI arguments, or key injection
+in your automation scripts for Hatari debugger, command FIFO or
+hconsole tool
 .TP
 .B \-\-language <x>
 Set NVRAM language value. While both TT and Falcon machines have
diff --git a/doc/manual.html b/doc/manual.html
index 21edac16..6c8f1ebb 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -569,10 +569,30 @@ user configuration files
 <p class="paramdesc">load keyboard mapping from &lt;file&gt;.
 "Symbolic" mapping will be used as fallback for keys not defined there
 </p>
+<p class="parameter">--country &lt;x&gt;</p>
+<p class="paramdesc">
+Set EmuTOS ROM country code on Mega/ST/STe machines lacking NVRAM, 
+when EmuTOS indicates supporting multiple ones.
+</p><p class="paramdesc">
+In 512k EmuTOS images, country code selects the TOS keyboard layout
+and screen refresh (US = 60Hz NTSC, 50Hz PAL otherwise).  In 1024k
+EmuTOS images (coming with Hatari binaries and supporting multiple
+languages), country code selects also TOS language.
+</p><p class="paramdesc">
+Alternatively, one can use "tos-lang-change" tool from EmuTOS project
+to modify country code in the ROM image file itself. That works
+also for TOS v4</p>
 <p class="parameter">--layout &lt;x&gt;</p>
 <p class="paramdesc">Set NVRAM keyboard layout value.
-While both TT and Falcon machines have NVRAM, only TOS v4 and EmuTOS
-1024k ROM versions support multiple layouts</p>
+Set NVRAM keyboard layout value. While both TT and Falcon machines
+have NVRAM, only TOS v4 and EmuTOS 512k / 1024k ROM versions support
+multiple layouts.</p>
+<p class="paramdesc">
+Regardless of whether keyboard layout change is done through the ROM
+country code or NVRAM setting, it may impact your key mappings in
+Hatari key mapping files, Hatari Python UI arguments, or key injection
+in your automation scripts for Hatari debugger, command FIFO or
+hconsole tool</p>
 <p class="parameter">--language &lt;x&gt;</p>
 <p class="paramdesc">Set NVRAM language value.
 While both TT and Falcon machines have NVRAM, only TOS v4 and EmuTOS
diff --git a/doc/release-notes.txt b/doc/release-notes.txt
index 96c3e888..63969798 100644
--- a/doc/release-notes.txt
+++ b/doc/release-notes.txt
@@ -65,6 +65,9 @@ Emulation improvements:
 Emulator improvements:
 - TOS support:
   - Support 1024k EmuTOS images also on TT & Falcon
+  - Add country code option to select EmuTOS language, keyboard
+    layout and screen refresh rate on Mega/ST/STe machines (ones
+    lacking NVRAM)
 - MIDI support:
   - Fix: PortMidi rejects Hatari MIDI events
   - Fix: MIDI IRQ needs to be re-enabled on MIDI device change
diff --git a/src/configuration.c b/src/configuration.c
index f6c9411b..6088142f 100644
--- a/src/configuration.c
+++ b/src/configuration.c
@@ -197,6 +197,7 @@ static const struct Config_Tag configs_Keyboard[] =
 {
 	{ "bDisableKeyRepeat", Bool_Tag, &ConfigureParams.Keyboard.bDisableKeyRepeat },
 	{ "nKeymapType", Int_Tag, &ConfigureParams.Keyboard.nKeymapType },
+	{ "nCountryCode", Int_Tag, &ConfigureParams.Keyboard.nCountryCode },
 	{ "nKbdLayout", Int_Tag, &ConfigureParams.Keyboard.nKbdLayout },
 	{ "nLanguage", Int_Tag, &ConfigureParams.Keyboard.nLanguage },
 	{ "szMappingFileName", String_Tag, ConfigureParams.Keyboard.szMappingFileName },
@@ -626,6 +627,7 @@ void Configuration_SetDefault(void)
 	/* Set defaults for Keyboard */
 	ConfigureParams.Keyboard.bDisableKeyRepeat = false;
 	ConfigureParams.Keyboard.nKeymapType = KEYMAP_SYMBOLIC;
+	ConfigureParams.Keyboard.nCountryCode = TOS_LANG_UNKNOWN;
 	ConfigureParams.Keyboard.nKbdLayout = TOS_LANG_UNKNOWN;
 	ConfigureParams.Keyboard.nLanguage = TOS_LANG_UNKNOWN;
 	strcpy(ConfigureParams.Keyboard.szMappingFileName, "");
diff --git a/src/falcon/nvram.h b/src/falcon/nvram.h
index c7aa2a86..29786f5c 100644
--- a/src/falcon/nvram.h
+++ b/src/falcon/nvram.h
@@ -49,4 +49,11 @@ extern void NvRam_Data_ReadByte(void);
 extern void NvRam_Data_WriteByte(void);
 extern void NvRam_Info(FILE *fp, Uint32 dummy);
 
+/* for tos.c */
+static inline bool NvRam_Present(void)
+{
+	return ConfigureParams.System.nMachineType == MACHINE_TT ||
+	       ConfigureParams.System.nMachineType == MACHINE_FALCON;
+}
+
 #endif /* HATARI_NVRAM_H */
diff --git a/src/includes/configuration.h b/src/includes/configuration.h
index e8130a04..91267398 100644
--- a/src/includes/configuration.h
+++ b/src/includes/configuration.h
@@ -102,6 +102,7 @@ typedef struct
 {
   bool bDisableKeyRepeat;
   KEYMAPTYPE nKeymapType;
+  int nCountryCode;
   int nKbdLayout;
   int nLanguage;
   char szMappingFileName[FILENAME_MAX];
diff --git a/src/includes/tos.h b/src/includes/tos.h
index 9c8904c1..ca873919 100644
--- a/src/includes/tos.h
+++ b/src/includes/tos.h
@@ -52,7 +52,8 @@ extern int TOS_InitImage(void);
 extern void TOS_SetTestPrgName(const char *testprg);
 
 extern int TOS_DefaultLanguage(void);
-extern int TOS_ParseCountryCode(const char *code, const char *info);
+extern int TOS_ParseCountryCode(const char *code);
+extern void TOS_ShowCountryCodes(void);
 extern const char *TOS_LanguageName(int code);
 
 #endif
diff --git a/src/options.c b/src/options.c
index e3a7d857..f8bcf333 100644
--- a/src/options.c
+++ b/src/options.c
@@ -65,6 +65,7 @@ enum {
 	OPT_CONFIRMQUIT,
 	OPT_CONFIGFILE,
 	OPT_KEYMAPFILE,
+	OPT_COUNTRY_CODE,
 	OPT_KBD_LAYOUT,
 	OPT_LANGUAGE,
 	OPT_FASTFORWARD,
@@ -228,10 +229,12 @@ static const opt_t HatariOptions[] = {
 	  "<file>", "Read (additional) configuration values from <file>" },
 	{ OPT_KEYMAPFILE, "-k", "--keymap",
 	  "<file>", "Read (additional) keyboard mappings from <file>" },
+	{ OPT_COUNTRY_CODE, NULL, "--country",
+	  "<x>", "Set country code for multi-code EmuTOS ROM" },
 	{ OPT_KBD_LAYOUT, NULL, "--layout",
-	  "<x>", "Set (TT/Falcon) NVRAM keyboard layout value" },
+	  "<x>", "Set (TT/Falcon) NVRAM keyboard layout" },
 	{ OPT_LANGUAGE, NULL, "--language",
-	  "<x>", "Set (TT/Falcon) NVRAM language value" },
+	  "<x>", "Set (TT/Falcon) NVRAM language" },
 	{ OPT_FASTFORWARD, NULL, "--fast-forward",
 	  "<bool>", "Help skipping stuff on fast machine" },
 	{ OPT_AUTOSTART, NULL, "--auto",
@@ -757,6 +760,23 @@ static bool Opt_Bool(const char *arg, int optid, bool *conf)
 	return Opt_ShowError(optid, orig, "Not a <bool> value");
 }
 
+/**
+ * If 'conf' given, set it to parsed country code value
+ * Return false for any other value, otherwise true
+ */
+static bool Opt_CountryCode(const char *arg, int optid, int *conf)
+{
+	int val = TOS_ParseCountryCode(arg);
+	if (val != TOS_LANG_UNKNOWN)
+	{
+		*conf = val;
+		return true;
+	}
+	Opt_ShowError(optid, arg, "Invalid value");
+	TOS_ShowCountryCodes();
+	return false;
+
+}
 
 /**
  * checks str argument against options of type "--option<digit>".
@@ -2018,20 +2038,16 @@ bool Opt_ParseParameters(int argc, const char * const argv[])
 			ok = Opt_Bool(argv[++i], OPT_MICROPHONE, &ConfigureParams.Sound.bEnableMicrophone);
 			break;
 
+		case OPT_COUNTRY_CODE:
+			ok = Opt_CountryCode(argv[++i], OPT_COUNTRY_CODE, &ConfigureParams.Keyboard.nCountryCode);
+			break;
+
 		case OPT_LANGUAGE:
-			val = TOS_ParseCountryCode(argv[++i], "language");
-			if (val != TOS_LANG_UNKNOWN)
-				ConfigureParams.Keyboard.nLanguage = val;
-			else
-				ok = false;
+			ok = Opt_CountryCode(argv[++i], OPT_LANGUAGE, &ConfigureParams.Keyboard.nLanguage);
 			break;
 
 		case OPT_KBD_LAYOUT:
-			val = TOS_ParseCountryCode(argv[++i], "keyboard layout");
-			if (val != TOS_LANG_UNKNOWN)
-				ConfigureParams.Keyboard.nKbdLayout = val;
-			else
-				ok = false;
+			ok = Opt_CountryCode(argv[++i], OPT_KBD_LAYOUT, &ConfigureParams.Keyboard.nKbdLayout);
 			break;
 
 		case OPT_KEYMAPFILE:
diff --git a/src/tos.c b/src/tos.c
index 74a457ea..cf7dbee3 100644
--- a/src/tos.c
+++ b/src/tos.c
@@ -1103,6 +1103,7 @@ int TOS_InitImage(void)
 {
 	uint8_t *pTosFile = NULL;
 	Uint32 logopatch_addr = 0;
+	Uint16 osconf, countrycode;
 
 	bTosImageLoaded = false;
 
@@ -1179,6 +1180,21 @@ int TOS_InitImage(void)
 		Log_Printf(LOG_DEBUG, "Skipped TOS patches.\n");
 	}
 
+	/* whether to override EmuTOS country code */
+	osconf = STMemory_ReadWord(TosAddress+0x1C);
+	countrycode = osconf >> 1;
+	if (bIsEmuTOS && countrycode == TOS_LANG_ALL && !NvRam_Present() &&
+	    ConfigureParams.Keyboard.nCountryCode != TOS_LANG_UNKNOWN)
+	{
+		countrycode = ConfigureParams.Keyboard.nLanguage;
+		/* low bit: us -> NTSC (0), any other -> PAL (1) */
+		osconf = (countrycode << 1) | (countrycode?1:0);
+		STMemory_WriteWord(TosAddress+0x1C, osconf);
+		Log_Printf(LOG_WARN, "=> EmuTOS country code: %d (%s), %s\n",
+			   countrycode, TOS_LanguageName(countrycode),
+			   (osconf & 1) ? "PAL" : "NTSC");
+	}
+
 	/*
 	 * patch some values into the "Draw logo" patch.
 	 * Needs to be called after final VDI resolution has been determined.
@@ -1252,20 +1268,19 @@ static const struct {
 /**
  * TOS_ValidCountryCode: returns parsed country code if
  * it's recognized, otherwise TOS_LANG_UNKNOWN is returned.
- * If info is set, valid ones are shown in latter case
  */
-int TOS_ParseCountryCode(const char *code, const char *info)
+int TOS_ParseCountryCode(const char *code)
 {
 	for (int i = 0; i < ARRAY_SIZE(countries); i++) {
 		if (strcmp(code, countries[i].code) == 0) {
 			return countries[i].value;
 		}
 	}
-	if (!info) {
-		return TOS_LANG_UNKNOWN;
-	}
-	fprintf(stderr, "Unrecognized %s code '%s'!\n", info, code);
+	return TOS_LANG_UNKNOWN;
+}
 
+void TOS_ShowCountryCodes(void)
+{
 	fprintf(stderr, "\nTOS v4 supports:\n");
 	for (int i = 0; i < ARRAY_SIZE(countries); i++) {
 		if (i == 7)
@@ -1273,7 +1288,6 @@ int TOS_ParseCountryCode(const char *code, const char *info)
 		fprintf(stderr, "- %s : %s\n",
 			countries[i].code, countries[i].name);
 	}
-	return TOS_LANG_UNKNOWN;
 }
 
 /**
@@ -1289,14 +1303,14 @@ int TOS_DefaultLanguage(void)
 
 	len = strlen(lang);
 	if (len == 2)
-		return TOS_ParseCountryCode(lang, NULL);
+		return TOS_ParseCountryCode(lang);
 
 	if (len >= 5 && lang[2] == '_') {
 		char cc[3];
 		cc[0] = tolower(lang[3]);
 		cc[1] = tolower(lang[4]);
 		cc[2] = '\0';
-		return TOS_ParseCountryCode(cc, NULL);
+		return TOS_ParseCountryCode(cc);
 	}
 	return TOS_LANG_UNKNOWN;
 }
-- 
2.30.2

From 8a5a88d864216a9b52c0d84f2e607913265aa8a2 Mon Sep 17 00:00:00 2001
From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
Date: Thu, 12 May 2022 21:45:09 +0300
Subject: [PATCH 1/2] Take NVRAM language default from the LANG environment
 variable

---
 doc/hatari.1          |  2 +-
 doc/manual.html       |  3 ++-
 doc/release-notes.txt |  6 +++---
 src/includes/tos.h    |  1 +
 src/main.c            |  2 ++
 src/tos.c             | 32 ++++++++++++++++++++++++++++++--
 6 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/doc/hatari.1 b/doc/hatari.1
index 89d3ead3..73dff208 100644
--- a/doc/hatari.1
+++ b/doc/hatari.1
@@ -73,7 +73,7 @@ layouts
 .B \-\-language <x>
 Set NVRAM language value. While both TT and Falcon machines have
 NVRAM, only TOS v4 and EmuTOS 1024k ROM versions support multiple
-languages
+languages.  Default is taken from the LANG environment variable
 .TP
 .B \-\-fast\-forward <bool>
 Fast-forward through the boring parts by running emulator at maximum
diff --git a/doc/manual.html b/doc/manual.html
index dfd331f1..21edac16 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -576,7 +576,8 @@ While both TT and Falcon machines have NVRAM, only TOS v4 and EmuTOS
 <p class="parameter">--language &lt;x&gt;</p>
 <p class="paramdesc">Set NVRAM language value.
 While both TT and Falcon machines have NVRAM, only TOS v4 and EmuTOS
-1024k ROM versions support multiple languages</p>
+1024k ROM versions support multiple languages.  Default is taken from
+the LANG environment variable
 <p class="parameter">--fast-forward
 &lt;bool&gt;</p>
 <p class="paramdesc">On fast machine helps skipping (fast
diff --git a/doc/release-notes.txt b/doc/release-notes.txt
index d8db37f4..96c3e888 100644
--- a/doc/release-notes.txt
+++ b/doc/release-notes.txt
@@ -75,11 +75,11 @@ Emulator improvements:
   - The RS232 receiver code has been rewritten to use polling instead
     of using a thread. This should avoid deadlocks on BSD/macOS systems
     when shutting down or reconfiguring the RS232 settings.
-- NVRAM:
-  - Config settings + CLI options to override NVRAM keyboard layout
-    and language values at start
 - TT/Falcon:
   - Increase max TT-RAM amount to 1024 MiB
+  - Separate config + CLI options to override NVRAM language and
+    keyboard layout settings
+  - NVRAM language default is taken from the LANG env variable
 - Falcon:
   - Fix: restore zoom mode correctly when loading snapshots
   - Correct also smaller specified memory amounts to valid ones
diff --git a/src/includes/tos.h b/src/includes/tos.h
index 8a5fce43..9c8904c1 100644
--- a/src/includes/tos.h
+++ b/src/includes/tos.h
@@ -51,6 +51,7 @@ extern void TOS_MemorySnapShot_Capture(bool bSave);
 extern int TOS_InitImage(void);
 extern void TOS_SetTestPrgName(const char *testprg);
 
+extern int TOS_DefaultLanguage(void);
 extern int TOS_ParseCountryCode(const char *code, const char *info);
 extern const char *TOS_LanguageName(int code);
 
diff --git a/src/main.c b/src/main.c
index c1374208..f5c020d4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -839,6 +839,8 @@ static void Main_LoadInitialConfig(void)
 
 	/* Now try the users configuration file */
 	Configuration_Load(NULL);
+	if (ConfigureParams.Keyboard.nLanguage == TOS_LANG_UNKNOWN)
+		ConfigureParams.Keyboard.nLanguage = TOS_DefaultLanguage();
 }
 
 /*-----------------------------------------------------------------------*/
diff --git a/src/tos.c b/src/tos.c
index df0f21bf..74a457ea 100644
--- a/src/tos.c
+++ b/src/tos.c
@@ -1251,8 +1251,8 @@ static const struct {
 
 /**
  * TOS_ValidCountryCode: returns parsed country code if
- * it's recognized, otherwise valid ones are shown and
- * TOS_LANG_UNKNOWN is returned
+ * it's recognized, otherwise TOS_LANG_UNKNOWN is returned.
+ * If info is set, valid ones are shown in latter case
  */
 int TOS_ParseCountryCode(const char *code, const char *info)
 {
@@ -1261,6 +1261,9 @@ int TOS_ParseCountryCode(const char *code, const char *info)
 			return countries[i].value;
 		}
 	}
+	if (!info) {
+		return TOS_LANG_UNKNOWN;
+	}
 	fprintf(stderr, "Unrecognized %s code '%s'!\n", info, code);
 
 	fprintf(stderr, "\nTOS v4 supports:\n");
@@ -1273,6 +1276,31 @@ int TOS_ParseCountryCode(const char *code, const char *info)
 	return TOS_LANG_UNKNOWN;
 }
 
+/**
+ * TOS_DefaultLanguage: return TOS country code matching LANG
+ * environment variable. Supports LANG formats: "uk", "en_UK.*"
+ */
+int TOS_DefaultLanguage(void)
+{
+	int len;
+	const char *lang = getenv("LANG");
+	if (!lang)
+		return TOS_LANG_UNKNOWN;
+
+	len = strlen(lang);
+	if (len == 2)
+		return TOS_ParseCountryCode(lang, NULL);
+
+	if (len >= 5 && lang[2] == '_') {
+		char cc[3];
+		cc[0] = tolower(lang[3]);
+		cc[1] = tolower(lang[4]);
+		cc[2] = '\0';
+		return TOS_ParseCountryCode(cc, NULL);
+	}
+	return TOS_LANG_UNKNOWN;
+}
+
 /**
  * TOS_LanguageName: return name for given country code
  */
-- 
2.30.2



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/