Hi, As discussed in the thread "Uniform mass storage device discovery and file locations" and as coordinated with Uz I've implemented some new stuff. Here's a brief overview: unsigned char getfirstdevice (void); unsigned char __fastcall__ getnextdevice (unsigned char device); Enumerate the the mass storage devices present and returns their numbers. The numbers should be meaningful to users i.e. for choosing in a list built from the result. On the CBMs the numbers are 8, 9, ... The numbers can be used as parameter to dio_open(). Disk drives are not turned on. char* __fastcall__ getdevicedir (unsigned char device, char* buf, size_t size); Given a device number provides a directory name that can be used as parameter to chdir() in order to access the root directory of the device. The name should be meaningful to users i.e. for choosing in a list built from the result. On the CBMs the names are "8", "9", ... Disk drives are checked for a formatted disk. If there's none the return value is NULL instead of a pointer to the directory name. int __fastcall__ chdir (const char* name); Makes the directory provided the current one. The only directories supported on CBMs are the root directories of the devices named "8", "9", ... Disk drives are checked for a formatted disk. If there's none the return value is -1. char* __fastcall__ getcwd (char* buf, size_t size); Provides the name of the current directory. On CBMs this is just the name given to chdir() (or the default - usually "8"). Important note: Because getcwd() just returns a string cached inside the C library all changes to the current directory have to be made through C library functions which are aware of that cache and update it. Usually the only one doing so is chdir(). Obviously setting the current device by changing the value of _curunit is incompatible with this approach. Therefore _curunit had to be removed so coding like _curunit = 9; has to be replaced with chdir("9"); Sorry for the inconvenience. With this new stuff it is now possible to enumerate (and access) all devices, directories and files in a target-independent way - which was my original goal in thread mentioned above :-) So it's time to say thanks to all who contributed there! I've written a new samples program called 'enumdevdir' that works on (most) CBMs and on the Apple II without any #ifdef. On the latter it processes subdirectories too. Please find its source code below this message. Another more simple target-independent scenario is to ask the user not only for a "File Name" but also for a "File Location" and doing a chdir() to that location before accessing the file. Final remark: I'm very optimistic that the new functions described above can be implemented in a reasonable way on other targets too. The obvious candidate here is the Atari. I'm looking forward to see enumdevdir running there too... Regards, Oliver ======================================== /* * Enumerate devices, directories and files. * * 2012-10-15, Oliver Schmidt (ol.sc@web.de) * */ #include <stdio.h> #include <conio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <device.h> #include <dirent.h> void printdir (char *newdir) { char olddir[FILENAME_MAX]; char curdir[FILENAME_MAX]; DIR *dir; struct dirent *ent; char *subdirs = NULL; unsigned dirnum = 0; unsigned num; getcwd (olddir, sizeof (olddir)); if (chdir (newdir)) { /* If chdir() fails we just print the * directory name - as done for files. */ printf (" Dir %s\n", newdir); return; } /* We call getcwd() in order to print the * absolute pathname for a subdirectory. */ getcwd (curdir, sizeof (curdir)); printf (" Dir %s:\n", curdir); /* Calling opendir() always with "." avoids * fiddling around with pathname separators. */ dir = opendir ("."); while (ent = readdir (dir)) { if (_DE_ISREG (ent->d_type)) { printf (" File %s\n", ent->d_name); continue; } /* We defer handling of subdirectories until we're done with the * current one as several targets don't support other disk i/o * while reading a directory (see cc65 readdir() doc for more). */ if (_DE_ISDIR (ent->d_type)) { subdirs = realloc (subdirs, FILENAME_MAX * (dirnum + 1)); strcpy (subdirs + FILENAME_MAX * dirnum++, ent->d_name); } } closedir (dir); for (num = 0; num < dirnum; ++num) { printdir (subdirs + FILENAME_MAX * num); } free (subdirs); chdir (olddir); } void main (void) { unsigned char device; char devicedir[FILENAME_MAX]; /* Calling getfirstdevice()/getnextdevice() does _not_ turn on the motor * of a drive-type device and does _not_ check for a disk in the drive. */ device = getfirstdevice (); while (device != INVALID_DEVICE) { printf ("Device %d:\n", device); /* Calling getdevicedir() _does_ check for a (formatted) disk in a * floppy-disk-type device and returns NULL if that check fails. */ if (getdevicedir (device, devicedir, sizeof (devicedir))) { printdir (devicedir); } else { printf (" N/A\n"); } device = getnextdevice (device); } cgetc (); } ---------------------------------------------------------------------- To unsubscribe from the list send mail to majordomo@musoftware.de with the string "unsubscribe cc65" in the body(!) of the mail.Received on Thu Oct 18 14:28:33 2012
This archive was generated by hypermail 2.1.8 : 2012-10-18 14:28:36 CEST