Re: [hatari-devel] Hatari GEMDOS drive volume name |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
- To: hatari-devel@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [hatari-devel] Hatari GEMDOS drive volume name
- From: Uwe Seimet <Uwe.Seimet@xxxxxxxxx>
- Date: Sun, 8 Sep 2024 16:06:21 +0200
- Arc-authentication-results: i=1; strato.com; arc=none; dkim=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1725804385; s=strato-dkim-0002; d=strato.com; h=In-Reply-To:References:Message-ID:Subject:To:From:Date:Cc:Date:From: Subject:Sender; bh=uNGZNfLyf6qxsZvAqxJ/jSeHfStxG37fKDiMagtUrqA=; b=gKTRsNeKYf3v/jQdILpPUwI1HHGwjF9FPP2vVJNSPvE0Fqz5cZdsxvFcoOFKbwgGyT CvPAfiwvuue4/Lt2RJXukFALoN25kmzeEnvcHBR+QGJZRgZBehKO1ZaP4tR5yzf/zgjw BQoFNEGL85nKOA2c8TW50B/DVS46MsoHCjJe3v/dPeD2oHfxv4p7m+y/rcLy6rdDH7k4 IifxJi20OqCE2Rus0P8K0srLg0/ORmM/xJXvjSusB7ic0+fQoXuncj+weoIJK34+3K8N elLiLZamBSIGiZhOyt5pIYDmv9Qk3xm0GUQkNbKH04vfSwRBY7HlIYZDuNQRiJspX89v uIsA==
- Arc-seal: i=1; a=rsa-sha256; t=1725804385; cv=none; d=strato.com; s=strato-dkim-0002; b=EHIMIKnuL1hgqDVNnQwXngRaWSfprYaOpKVHXa1mukXe8y1EXqFwZIeGOHjpvOE0Ka j/+BaeKNaKzuJcZuv5a2DBHQjo7q+tTnGf2rlpojEyJ8BNvzZRZd7iSEAdZrQNyzhRGy sPUCHn0l6ugnKgHEZ5CDOFKsuCPnuZkOgnZGFrLFHOkg208oW7R+GbeuqihmZjFVqszX X+dxm6FOG9Oq4wXHX0VAITvt/6+vN4psHvFU16MKeOcE+KS27EtAuBi7enS80us6DvuC J00AeZy4o5X8zyf1P/g+4jiKsl+Ergm2dUxYR6BM7IJpM32LlnZyw07zvlMAwrpiBQF8 0i0w==
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1725804385; s=strato-dkim-0002; d=seimet.de; h=In-Reply-To:References:Message-ID:Subject:To:From:Date:Cc:Date:From: Subject:Sender; bh=uNGZNfLyf6qxsZvAqxJ/jSeHfStxG37fKDiMagtUrqA=; b=ATlLPG8GdHivmUOG2gZC46qcFdBZpvJh1Rzep2aunzuv9fzNpTQXfevr+f4OFtChiP kQqebtOh65R3jVx9Yc2ADJMzldnXga51fbskiZw0YwPP+K4CDBMWZyFVnd743OKvEI0U Wk0TeN+AX/YrpR2yZyC4DA5TpirL9Y38uOZgECnE+v4kRj+IVFBvB+5Hb9iF3upFzJSs vjUEnF8nNeqDLa0t0dJKRRJr4elAW6NRSHVeEGvYvciWw6xVdHYyVKt2WvEkU0FxdHtg HqGjQm6trIUQ7ZsLYIAQyfcp+kzhnNPCHF0EtfRntQ5CBB17O1KblaXfKUei992M9CQv duUw==
- Dkim-signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1725804385; s=strato-dkim-0003; d=seimet.de; h=In-Reply-To:References:Message-ID:Subject:To:From:Date:Cc:Date:From: Subject:Sender; bh=uNGZNfLyf6qxsZvAqxJ/jSeHfStxG37fKDiMagtUrqA=; b=Fgw5y4dk7CqwWghTy5rCgL107617+wF4RRASwOOV3DeFoe4kMlIphSlyqOEjh1nkEW TleevfeFl3B6zO8j2mDA==
Hi Eero,
Thank you. With this patch my code works as expected.
Best regards
Uwe
> Hi Uwe,
>
> On 8.9.2024 11.45, Uwe Seimet wrote:
> > if(!Fsfirst("C:\*.*", FA_VOLUME)) {
> > DTA *dta = Fgetdta();
> >
> > if(dta->d_attrib == 0x08) {
> > // Unexpected: d_attrib is $00 here, shouldn't it be 0x08?
> > // d_fname is "EMULATED.002"
> > }
> > }
>
> Thanks for reporting!
>
> Fix for that is one-liner, but the attached patch should fix also few
> other GEMDOS HD attribute handling corner-cases I noticed while
> investigating this.
>
> => It's good if you could test that it does not regress anything else
> before I commit it.
>
> (Hatari GEMDOS HD unit test are very basic, as is my setup & manual
> testing, so you're likely to catch things I do not.)
>
>
> Thomas / Nicolas, does the patch look OK?
>
>
> - Eero
> From 75a33df5b164d965540058e35eb6fcc7f3496357 Mon Sep 17 00:00:00 2001
> From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
> Date: Sun, 8 Sep 2024 16:17:01 +0300
> Subject: [PATCH] GEMDOS HD: fixes for attribute handling corner-cases
>
> Instead of using in Fsnext() a (global) attribute value set by
> previous Fsfirst() call, store it to internal DTA entry. This fixes
> case where program first Fgetdata()s multiple DTAs with _different_
> attributes from Fsfirst() calls, and then does Fsnext() calls while
> switching between those earlier acquired DTAs with Fsetdta().
>
> Support volume labels also in case when archive and/or read-only
> attributes are specified, with the new IS_VOLUME_LABEL() macro.
>
> Use correct attribute value also for volume labels returned from Fsfirst().
>
> Improve related code comments & warning messages and update docs.
> ---
> doc/manual.html | 2 ++
> doc/release-notes.txt | 3 +++
> src/gemdos.c | 47 +++++++++++++++++++++--------------
> src/includes/gemdos_defines.h | 3 ++-
> 4 files changed, 35 insertions(+), 20 deletions(-)
>
> diff --git a/doc/manual.html b/doc/manual.html
> index 2e26c4bd..4c137ab9 100644
> --- a/doc/manual.html
> +++ b/doc/manual.html
> @@ -2707,6 +2707,8 @@ have no files.</li>
> handles used with GEMDOS <em>file</em> functions, such as Fwrite() to standard
> output that is redirected to a file. File redirection is NOT supported
> e.g. for GEMDOS Ccon* console functions.</li>
> +<li>Only FsFirst() / FsNext() calls support drive volume labels, other
> +GEMDOS calls return errors when volume label attribute is specified
> <li>Host and emulation have their own clocks, which will drift apart
> after emulation is started, especially when emulation is
> fast-forwarded or paused. Because of this, anything inside emulation
> diff --git a/doc/release-notes.txt b/doc/release-notes.txt
> index e072fafb..17fc1758 100644
> --- a/doc/release-notes.txt
> +++ b/doc/release-notes.txt
> @@ -46,6 +46,9 @@ Emulator improvements:
> - Fix: segfault with negative joystick indexes
> - GEMDOS HD:
> - Fix: Fattrib() call on a directory
> + - Fix: Return attrib for volume labels in FsFirst()
> + - Fix: Fsnext() calls with DTAs having different attribs,
> + where DTA is not from preceeding Fsfirst() but earlier one
> - Fix: Handle additional '*' chars at end of file mask
> - SCC:
> - Fix: invalid channel B file close on uninit
> diff --git a/src/gemdos.c b/src/gemdos.c
> index 8bbf1dc1..7a840fd7 100644
> --- a/src/gemdos.c
> +++ b/src/gemdos.c
> @@ -141,6 +141,7 @@ typedef struct
> char szActualName[MAX_GEMDOS_PATH]; /* used by F_DATIME (0x57) */
> } FILE_HANDLE;
>
> +/* stored FsFirst() information */
> typedef struct
> {
> bool bUsed;
> @@ -148,16 +149,20 @@ typedef struct
> int nentries; /* number of entries in fs directory */
> int centry; /* current entry # */
> struct dirent **found; /* legal files */
> - char path[MAX_GEMDOS_PATH]; /* sfirst path */
> + char path[MAX_GEMDOS_PATH];
> + char dta_attrib;
> } INTERNAL_DTA;
>
> +/* DTA population ignores archive & read-only attributes */
> +#define IGNORED_FILE_ATTRIBS (GEMDOS_FILE_ATTRIB_WRITECLOSE|GEMDOS_FILE_ATTRIB_READONLY)
> +#define IS_VOLUME_LABEL(x) (((x) & ~(IGNORED_FILE_ATTRIBS)) == GEMDOS_FILE_ATTRIB_VOLUME_LABEL)
> +
> static FILE_HANDLE FileHandles[MAX_FILE_HANDLES];
> static INTERNAL_DTA *InternalDTAs;
> static int DTACount; /* Current DTA cache size */
> static uint16_t DTAIndex; /* Circular index into above */
> static uint16_t CurrentDrive; /* Current drive (0=A,1=B,2=C etc...) */
> static uint32_t act_pd; /* Used to get a pointer to the current basepage */
> -static uint16_t nAttrSFirst; /* File attribute for SFirst/Snext */
> static uint32_t CallingPC; /* Program counter from caller */
>
> static uint32_t nSavedPexecParams;
> @@ -287,7 +292,7 @@ static uint8_t GemDOS_ConvertAttribute(mode_t mode, const char *path)
>
> /* TODO, Other attributes:
> * - GEMDOS_FILE_ATTRIB_HIDDEN (file not visible on desktop/fsel)
> - * - GEMDOS_FILE_ATTRIB_ARCHIVE (file written after being backed up)
> + * - GEMDOS_FILE_ATTRIB_WRITECLOSE (arcive bit, file written after being backed up)
> * ?
> */
> return Attrib;
> @@ -299,7 +304,7 @@ static uint8_t GemDOS_ConvertAttribute(mode_t mode, const char *path)
> * Populate the DTA buffer with file info.
> * @return DTA_OK if entry is ok, DTA_SKIP if it should be skipped, DTA_ERR on errors
> */
> -static dta_ret_t PopulateDTA(char *path, struct dirent *file, DTA *pDTA, uint32_t DTA_Gemdos)
> +static dta_ret_t PopulateDTA(INTERNAL_DTA *iDTA, struct dirent *file, DTA *pDTA, uint32_t DTA_Gemdos)
> {
> /* TODO: host file path can be longer than MAX_GEMDOS_PATH */
> char tempstr[MAX_GEMDOS_PATH];
> @@ -307,8 +312,8 @@ static dta_ret_t PopulateDTA(char *path, struct dirent *file, DTA *pDTA, uint32_
> DATETIME DateTime;
> int nFileAttr, nAttrMask;
>
> - if (snprintf(tempstr, sizeof(tempstr), "%s%c%s",
> - path, PATHSEP, file->d_name) >= (int)sizeof(tempstr))
> + if (snprintf(tempstr, sizeof(tempstr), "%s%c%s", iDTA->path,
> + PATHSEP, file->d_name) >= (int)sizeof(tempstr))
> {
> Log_Printf(LOG_ERROR, "PopulateDTA: path is too long.\n");
> return DTA_ERR;
> @@ -327,7 +332,7 @@ static dta_ret_t PopulateDTA(char *path, struct dirent *file, DTA *pDTA, uint32_
>
> /* Check file attributes (check is done according to the Profibuch) */
> nFileAttr = GemDOS_ConvertAttribute(filestat.st_mode, tempstr);
> - nAttrMask = nAttrSFirst|GEMDOS_FILE_ATTRIB_WRITECLOSE|GEMDOS_FILE_ATTRIB_READONLY;
> + nAttrMask = iDTA->dta_attrib | IGNORED_FILE_ATTRIBS;
> if (nFileAttr != 0 && !(nAttrMask & nFileAttr))
> return DTA_SKIP;
>
> @@ -1978,10 +1983,9 @@ static bool GemDOS_Create(uint32_t Params)
> return redirect_to_TOS();
> }
>
> - if (Mode == GEMDOS_FILE_ATTRIB_VOLUME_LABEL)
> + if (IS_VOLUME_LABEL(Mode))
> {
> - Log_Printf(LOG_WARN, "Warning: Hatari doesn't support GEMDOS volume"
> - " label setting\n(for '%s')\n", pszFileName);
> + Log_Printf(LOG_WARN, "volume label creation not supported on GEMDOS HD\n");
> Regs[REG_D0] = GEMDOS_EFILNF; /* File not found */
> return true;
> }
> @@ -2606,9 +2610,9 @@ static bool GemDOS_Fattrib(uint32_t Params)
> GemDOS_CreateHardDriveFileName(nDrive, psFileName,
> sActualFileName, sizeof(sActualFileName));
>
> - if (nAttrib == GEMDOS_FILE_ATTRIB_VOLUME_LABEL)
> + if (IS_VOLUME_LABEL(nAttrib))
> {
> - Log_Printf(LOG_WARN, "Hatari doesn't support GEMDOS volume label setting\n(for '%s')\n", sActualFileName);
> + Log_Printf(LOG_WARN, "volume label Fattrib() not supported on GEMDOS HD\n");
> Regs[REG_D0] = GEMDOS_EFILNF; /* File not found */
> return true;
> }
> @@ -2914,7 +2918,7 @@ static bool GemDOS_SNext(void)
> return false;
> }
>
> - if (nAttrSFirst == GEMDOS_FILE_ATTRIB_VOLUME_LABEL)
> + if (IS_VOLUME_LABEL(pDTA->dta_attrib))
> {
> /* Volume label was given already in Sfirst() */
> Regs[REG_D0] = GEMDOS_ENMFIL;
> @@ -2946,7 +2950,7 @@ static bool GemDOS_SNext(void)
> return true;
> }
>
> - ret = PopulateDTA(InternalDTAs[Index].path,
> + ret = PopulateDTA(&InternalDTAs[Index],
> temp[InternalDTAs[Index].centry++],
> pDTA, DTA_Gemdos);
> } while (ret == DTA_SKIP);
> @@ -2981,17 +2985,18 @@ static bool GemDOS_SFirst(uint32_t Params)
> DTA *pDTA;
> uint32_t DTA_Gemdos;
> uint16_t useidx;
> + uint16_t attrib;
>
> - nAttrSFirst = STMemory_ReadWord(Params+SIZE_LONG);
> + attrib = STMemory_ReadWord(Params+SIZE_LONG);
> pszFileName = STMemory_GetStringPointer(STMemory_ReadLong(Params));
> if (!pszFileName)
> {
> LOG_TRACE(TRACE_OS_GEMDOS, "GEMDOS 0x4E bad Fsfirst(0x%X, 0x%x) at PC 0x%X\n",
> - STMemory_ReadLong(Params), nAttrSFirst, CallingPC);
> + STMemory_ReadLong(Params), attrib, CallingPC);
> return false;
> }
>
> - LOG_TRACE(TRACE_OS_GEMDOS, "GEMDOS 0x4E Fsfirst(\"%s\", 0x%x) at PC 0x%X\n", pszFileName, nAttrSFirst,
> + LOG_TRACE(TRACE_OS_GEMDOS, "GEMDOS 0x4E Fsfirst(\"%s\", 0x%x) at PC 0x%X\n", pszFileName, attrib,
> CallingPC);
>
> Drive = GemDOS_FileName2HardDriveID(pszFileName);
> @@ -3045,13 +3050,17 @@ static bool GemDOS_SFirst(uint32_t Params)
> }
> InternalDTAs[useidx].bUsed = true;
> InternalDTAs[useidx].addr = DTA_Gemdos;
> + InternalDTAs[useidx].dta_attrib = attrib;
>
> - /* Were we looking for the volume label? */
> - if (nAttrSFirst == GEMDOS_FILE_ATTRIB_VOLUME_LABEL)
> + /* volume labels are supported only when no other
> + * other file types are specified in same query
> + */
> + if (IS_VOLUME_LABEL(attrib))
> {
> /* Volume name */
> strcpy(pDTA->dta_name,"EMULATED.001");
> pDTA->dta_name[11] = '0' + Drive;
> + pDTA->dta_attrib = GEMDOS_FILE_ATTRIB_VOLUME_LABEL;
> Regs[REG_D0] = GEMDOS_EOK; /* Got volume */
> return true;
> }
> diff --git a/src/includes/gemdos_defines.h b/src/includes/gemdos_defines.h
> index 53352925..80fcb126 100644
> --- a/src/includes/gemdos_defines.h
> +++ b/src/includes/gemdos_defines.h
> @@ -53,7 +53,8 @@
> #define GEMDOS_FILE_ATTRIB_SYSTEM_FILE 0x04
> #define GEMDOS_FILE_ATTRIB_VOLUME_LABEL 0x08
> #define GEMDOS_FILE_ATTRIB_SUBDIRECTORY 0x10
> -/* file was written and closed correctly (used automatically on gemdos >=0.15) */
> +/* archive bit, file was written and closed correctly
> + * (used automatically on gemdos >=0.15) */
> #define GEMDOS_FILE_ATTRIB_WRITECLOSE 0x20
>
> #endif /* HATARI_GEMDOS_DEFINES_H */
> --
> 2.39.2
>