]> git.sur5r.net Git - cc65/commitdiff
Improved cbm_dir routines by Thomas Giesel.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 28 Sep 2009 22:01:58 +0000 (22:01 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 28 Sep 2009 22:01:58 +0000 (22:01 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@4264 b7a2c559-68d2-44c3-8de9-860c34a00d81

include/cbm.h
libsrc/cbm/cbm_dir.c

index ca268993621ce88e892bcd9510ee8dc97e3b63cc..6ba1ef47e12a02fa8708efb3a217d9fada5a2ce1 100644 (file)
@@ -117,15 +117,17 @@ extern unsigned char _filetype;         /* Default 'u' */
 
 
 /* CBM FILE TYPES */
-#define CBM_T_DEL   0
-#define CBM_T_SEQ   1
-#define CBM_T_PRG   2
-#define CBM_T_USR   3
-#define CBM_T_REL   4
-#define CBM_T_CBM   5           /* 1581 sub-partition */
-#define CBM_T_DIR   6           /* IDE64 and CMD sub-directory */
-#define CBM_T_VRP   8           /* Vorpal fast-loadable format */
-#define CBM_T_OTHER 5           /* Other file-types not yet defined */
+#define CBM_T_DEL       0
+#define CBM_T_SEQ       1
+#define CBM_T_PRG       2
+#define CBM_T_USR       3
+#define CBM_T_REL       4
+#define CBM_T_CBM       5       /* 1581 sub-partition */
+#define CBM_T_DIR       6       /* IDE64 and CMD sub-directory */
+#define CBM_T_RESERVED  7       /* Not used, but kept free for compatibility */
+#define CBM_T_VRP       8       /* Vorpal fast-loadable format */
+#define CBM_T_OTHER     9       /* Other file-types not yet defined */
+#define CBM_T_HEADER   10       /* Disk header / title */
 
 /* CBM FILE ACCESS */
 #define CBM_A_RO    1           /* Read only   */
index bedbdaf6ace3e59a0caa08fb97e84c984d15af52..b46df177a816086f4498574e4eeb7b8a8437bb00 100644 (file)
@@ -38,40 +38,62 @@ unsigned char __fastcall__ cbm_opendir (unsigned char lfn, unsigned char device)
 unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_dirent* l_dirent)
 {
     unsigned char byte, i;
-
-    if (cbm_k_chkin (lfn) == 0) {
-        if (cbm_k_readst () == 0) {
-            cbm_k_basin ();                    /* 0x01, 0x01, next basic line */
-            cbm_k_basin ();
-
-            byte = cbm_k_basin();             /* File-size */
-            l_dirent->size = byte | ((cbm_k_basin()) << 8);
+    unsigned char rv;
+    unsigned char is_header;
+    static const unsigned char types[] = { 
+        CBM_T_OTHER, CBM_T_OTHER, CBM_T_CBM,   CBM_T_DIR,   /* a b c d */
+        CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, /* e f g h */
+        CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, /* i j k l */
+        CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, CBM_T_PRG,   /* m n o p */
+        CBM_T_OTHER, CBM_T_REL,   CBM_T_SEQ,   CBM_T_OTHER, /* q r s t */
+        CBM_T_USR,   CBM_T_VRP                              /* u v     */
+    };
+
+    rv = 1;
+    is_header = 0;
+
+    if (!cbm_k_chkin(lfn)) {
+        if (!cbm_k_readst()) {
+            /* skip 2 bytes, next basic line pointer */
+            cbm_k_basin();
+            cbm_k_basin();
+
+            /* File-size */
+            l_dirent->size = cbm_k_basin() | ((cbm_k_basin()) << 8);
 
             byte = cbm_k_basin();
 
-            if (byte == 'b') {                 /* "B" BLOCKS FREE. */
-                while (cbm_k_readst () == 0) { /* Read until end */
-                    cbm_k_basin ();
+            /* "B" BLOCKS FREE. */
+            if (byte == 'b') {
+                /* Read until end, careless callers may call us again */
+                while (!cbm_k_readst()) {
+                    cbm_k_basin();
                 }
-                cbm_k_clrch ();
-                return 2;                       /* END */
+                rv = 2; /* EOF */
+                goto ret_val;
             }
 
-            if (byte != '\"') {
-                while (cbm_k_basin() != '\"') {
-                    if (cbm_k_readst () != 0) {   /* ### Included to prevent */
-                        cbm_k_clrch ();           /* ### Endless loop */
-                        return 3;                 /* ### Should be probably removed */
-                    }                             /* ### */
+            /* reverse text shows that this is the directory header */
+            if (byte == 0x12) { /* RVS_ON */
+                is_header = 1;
+            }
+
+            while (byte != '\"') {
+                byte = cbm_k_basin();
+                /* prevent endless loop */
+                if (cbm_k_readst()) {
+                    rv = 3;
+                    goto ret_val;
                 }
             }
 
             i = 0;
-            while ((byte = cbm_k_basin ()) != '\"') {
-                if (cbm_k_readst () != 0) {     /* ### Included to prevent */
-                    cbm_k_clrch ();             /* ### Endless loop */
-                    return 4;                   /* ### Should be probably removed */
-                }                               /* ### */
+            while ((byte = cbm_k_basin()) != '\"') {
+                /* prevent endless loop */
+                if (cbm_k_readst()) {
+                    rv = 4;
+                    goto ret_val;
+                }
 
                 if (i < sizeof (l_dirent->name) - 1) {
                     l_dirent->name[i] = byte;
@@ -80,61 +102,49 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d
             }
             l_dirent->name[i] = '\0';
 
-            while ((byte=cbm_k_basin ()) == ' ') {
-                if (cbm_k_readst ()) {          /* ### Included to prevent */
-                    cbm_k_clrch ();             /* ### Endless loop */
-                    return 5;                   /* ### Should be probably removed */
-                }                               /* ### */
+            while ((byte = cbm_k_basin()) == ' ') {
+                /* prevent endless loop */
+                if (cbm_k_readst()) {
+                    rv = 5;
+                    goto ret_val;
+                }
             }
 
-            switch (byte) {
-                case 's':
-                    l_dirent->type = CBM_T_SEQ;
-                    break;
-                case 'p':
-                    l_dirent->type = CBM_T_PRG;
-                    break;
-                case 'u':
-                    l_dirent->type = CBM_T_USR;
-                    break;
-                case 'r':
-                    l_dirent->type = CBM_T_REL;
-                    break;
-                case 'c':
-                    l_dirent->type = CBM_T_CBM;
-                    break;
-                case 'd':
-                    l_dirent->type = CBM_T_DIR;
-                    break;
-                case 'v':
-                    l_dirent->type = CBM_T_VRP;
-                    break;
-                default:
+            if (is_header) {
+                l_dirent->type = CBM_T_HEADER;
+            } else {
+                if (byte >= 'a' && byte < 'a' + sizeof(types)) {
+                    l_dirent->type = types[byte - 'a'];
+                } else {
                     l_dirent->type = CBM_T_OTHER;
-            }
+                }
 
-            cbm_k_basin ();
-            cbm_k_basin ();
+                cbm_k_basin();
+                cbm_k_basin();
 
-            byte = cbm_k_basin ();
+                byte = cbm_k_basin();
 
-            l_dirent->access = (byte == 0x3C)? CBM_A_RO : CBM_A_RW;
+                l_dirent->access = (byte == 0x3C)? CBM_A_RO : CBM_A_RW;
+            }
 
-            if (byte != 0) {
-                while (cbm_k_basin() != 0) {
-                    if (cbm_k_readst () != 0) { /* ### Included to prevent */
-                        cbm_k_clrch ();         /* ### Endless loop */
-                        return 6;               /* ### Should be probably removed */
-                    }                           /* ### */
+            /* read to end of line */
+            while (byte != 0) {
+                byte = cbm_k_basin();
+                /* prevent endless loop */
+                if (cbm_k_readst()) {
+                    rv = 6;
+                    goto ret_val;
                 }
             }
 
-            cbm_k_clrch ();
-            return 0;                         /* Line read successfuly */
+            rv = 0;
+            goto ret_val;
         }
     }
-    cbm_k_clrch ();
-    return 1;
+
+ret_val:
+    cbm_k_clrch();
+    return rv;
 }