]> git.sur5r.net Git - cc65/commitdiff
Moved most of the file type detection from cbm_dir.c into a new function
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 2 Jun 2012 22:56:14 +0000 (22:56 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 2 Jun 2012 22:56:14 +0000 (22:56 +0000)
called _cbm_filetype().
Added an assembler include file with the file type definitions from cbm.h.
Added a first implementation of readdir() for the CBMs.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5669 b7a2c559-68d2-44c3-8de9-860c34a00d81

asminc/cbm_ftype.inc [new file with mode: 0644]
include/cbm.h
include/dirent.h
libsrc/cbm/Makefile
libsrc/cbm/cbm_dir.c
libsrc/cbm/cbm_ftype.s [new file with mode: 0644]
libsrc/cbm/dir.h
libsrc/cbm/opendir.c
libsrc/cbm/readdir.c [new file with mode: 0644]

diff --git a/asminc/cbm_ftype.inc b/asminc/cbm_ftype.inc
new file mode 100644 (file)
index 0000000..c1f1afc
--- /dev/null
@@ -0,0 +1,33 @@
+;
+; Definitions for CBM file types. From cbm.h
+;
+; Ullrich von Bassewitz, 2012-06-03
+;
+
+; Define bitmapped constants for the table entries
+
+.enum
+        CBM_T_DEL               ; Deleted file
+        CBM_T_SEQ               ; Sequential file
+        CBM_T_PRG               ; Program file
+        CBM_T_USR               ; User file
+        CBM_T_REL               ; Relative file
+        CBM_T_CBM               ; 1581 sub-partition
+        CBM_T_DIR               ; IDE64 and CMD sub-directory
+        CBM_T_LNK               ; IDE64 soft-link
+        CBM_T_VRP               ; Vorpal fast-loadable format
+        CBM_T_OTHER             ; File-type not recognized
+        CBM_T_HEADER            ; Disk header / title 
+.endenum
+
+
+; The following function maps the start character for a file type to 
+; one of the file types above. Note: 'd' will always mapped to CBM_T_DEL.
+; The calling function has to look at the following character to determine
+; if the file type is actually CBM_T_DIR.
+;
+; unsigned char __fastcall__ _cbm_filetype (unsigned char c);
+
+        .global __cbm_filetype
+
+
index 34ab106aec1c53ee694b54e1c2d361fd9bedfcba..d3c96675528d46937045f84d63ebea808e50f0c9 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/* (C) 1998-2012, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -116,7 +116,7 @@ extern char _filetype;          /* Defaults to 'u' */
 #define CH_LIRA                 92
 #define CH_ESC          27
 
-
+                
 
 /*****************************************************************************/
 /*                Definitions for directory reading functions                */
@@ -149,6 +149,14 @@ struct cbm_dirent {
     unsigned char access;
 };
 
+unsigned char __fastcall__ _cbm_filetype (unsigned char c);
+/* Map the start character for a file type to one of the file types above. 
+ * Note: 'd' will always mapped to CBM_T_DEL. The calling function has to 
+ * look at the following character to determine if the file type is actually 
+ * CBM_T_DIR.
+ * This is a function used by the implementation. There is usually no need
+ * to call it from user code.
+ */
 
 
 /*****************************************************************************/
index 7dd79c144c23aac2f071797b1e3fae771685b091..dc3cfc5f831c773aaaade99ae528affa71966d96 100644 (file)
@@ -84,9 +84,9 @@ struct dirent {
 struct dirent {
     char                d_name[16+1];
     unsigned int        d_off;
-    unsigned int        d_reclen;
+    unsigned int        d_blocks;
     unsigned char       d_type;
-                
+
     /* bsd extensions */
     unsigned char       d_namlen;
 };
index a811edac1afaf7a2a70cffe44aaec1246bff080c..66d08522d019beba5b1535b800b4620bc91226be 100644 (file)
@@ -32,7 +32,8 @@ CFLAGS        = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
 C_OBJS =               cbm_dir.o       \
                 cbm_load.o     \
                cbm_save.o      \
-                opendir.o
+                opendir.o       \
+                readdir.o
 
 S_OBJS =       c_acptr.o       \
                c_basin.o       \
@@ -55,6 +56,7 @@ S_OBJS =      c_acptr.o       \
                c_unlsn.o       \
                c_untlk.o       \
                cbm_close.o     \
+                cbm_ftype.o     \
                cbm_open.o      \
                cbm_read.o      \
                cbm_write.o     \
index 0b97e980390a0ba8896958adc6dc38e6f9775229..79d2c205e2dd3fa44276d17092043cebe593d26c 100644 (file)
@@ -51,13 +51,6 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d
     unsigned char byte, i = 0;
     unsigned char is_header = 0;
     unsigned char rv = 1;
-    static const unsigned char types[] = {
-        CBM_T_CBM,   CBM_T_DEL,   CBM_T_OTHER, CBM_T_OTHER, /* c d e f */
-        CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, /* g h i j */
-        CBM_T_OTHER, CBM_T_LNK,   CBM_T_OTHER, CBM_T_OTHER, /* k l m n */
-        CBM_T_OTHER, CBM_T_PRG,   CBM_T_OTHER, CBM_T_REL,   /* o p q r */
-        CBM_T_SEQ,   CBM_T_OTHER, CBM_T_USR,   CBM_T_VRP    /* s t u v */
-    };
 
     if (!cbm_k_chkin(lfn)) {
         if (!cbm_k_readst()) {
@@ -135,11 +128,8 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d
                     byte = cbm_k_basin();
                 }
 
-                if (byte >= 'c' && byte < 'c' + sizeof types) {
-                    l_dirent->type = types[byte - 'c'];
-                } else {
-                    l_dirent->type = CBM_T_OTHER;
-                }
+                /* Determine the file type */
+                l_dirent->type = _cbm_filetype (byte);
 
                /* Notice whether it's a directory or a deleted file. */
                if (cbm_k_basin() == 'i' && byte == 'd') {
diff --git a/libsrc/cbm/cbm_ftype.s b/libsrc/cbm/cbm_ftype.s
new file mode 100644 (file)
index 0000000..862fb72
--- /dev/null
@@ -0,0 +1,71 @@
+;
+; Determine the CBM file type. From cbm_dir.c by Josef Soucek. Moved into an
+; assembler function by Ullrich von Bassewitz 2012-06-03
+;
+; unsigned char __fastcall__ _cbm_filetype (unsigned char c);
+;
+
+        .include "cbm_ftype.inc"
+
+        .macpack generic
+
+
+; --------------------------------------------------------------------------
+; Table with types for a list of start characters
+
+.rodata
+.proc   TypeTable
+        .byte   CBM_T_CBM       ; c
+        .byte   CBM_T_DEL       ; d
+        .byte   CBM_T_OTHER     ; e
+        .byte   CBM_T_OTHER     ; f
+        .byte   CBM_T_OTHER     ; g
+        .byte   CBM_T_OTHER     ; h
+        .byte   CBM_T_OTHER     ; i
+        .byte   CBM_T_OTHER     ; j
+        .byte   CBM_T_OTHER     ; k
+        .byte   CBM_T_LNK       ; l
+        .byte   CBM_T_OTHER     ; m
+        .byte   CBM_T_OTHER     ; n
+        .byte   CBM_T_OTHER     ; o
+        .byte   CBM_T_PRG       ; p
+        .byte   CBM_T_OTHER     ; q
+        .byte   CBM_T_REL       ; r
+        .byte   CBM_T_SEQ       ; s
+        .byte   CBM_T_OTHER     ; t
+        .byte   CBM_T_USR       ; u
+        .byte   CBM_T_VRP       ; v
+.endproc
+
+
+; --------------------------------------------------------------------------
+; Mapper function
+
+.code
+.proc   __cbm_filetype
+
+        ldx     #0              ; Clear high byte
+
+; Check that the given char is in table range
+
+        sec
+        sbc     #'c'
+        bcc     L1
+        cmp     #.sizeof (TypeTable)
+        bge     L1
+
+; Ok, load the type
+
+        tay
+        lda     TypeTable,y
+        rts
+
+; Out of table range, return CBM_T_OTHER
+
+L1:     lda     #CBM_T_OTHER
+        rts
+
+.endproc
+
+
+
index 06081a47ce46ff2db62f3cc62235d6c341e27b95..d7a30518ddc9bc70dc61bf0fda040f13d8cbca8b 100644 (file)
@@ -18,7 +18,7 @@
 
 struct DIR {
     int                fd;             /* File descriptor for directory */
-    unsigned    offs;           /* Current byte offset in directory */
+    unsigned    off           /* Current byte offset in directory */
     char        name[16+1];     /* Name passed to opendir */
 };
 
index c3f6f1440567792c59466cfb8951be325a6a16d0..3f6f76e95fa15ff8f58ad6d3d5f01db3a23ab5fa 100644 (file)
@@ -20,7 +20,7 @@ DIR* __fastcall__ opendir (const char*)
     /* Setup file name and offset */
     d.name[0] = '$';
     d.name[1] = '\0';
-    d.offs    = 0;
+    d.off     = 0;
 
     /* Open the directory on disk for reading */
     d.fd = open (d.name, O_RDONLY);
diff --git a/libsrc/cbm/readdir.c b/libsrc/cbm/readdir.c
new file mode 100644 (file)
index 0000000..10593e2
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Ullrich von Bassewitz, 2012-05-30. Based on code by Groepaz.
+ */
+
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <cbm.h>
+#include "dir.h"
+
+#include <stdio.h>
+
+
+struct dirent* __fastcall__ readdir (register DIR* dir)
+{
+    static struct dirent entry;
+    register unsigned char* b;
+    register unsigned char i;
+    unsigned char count;
+    unsigned char j;
+    unsigned char s;
+    unsigned char buffer[0x40];
+
+
+    /* Remember the directory offset for this entry */
+    entry.d_off = dir->off;
+
+    /* Skip the basic line-link */
+    if (!_dirskip (2, dir)) {
+        /* errno already set */
+        goto exit;
+    }
+    dir->off += 2;
+
+    /* Read the number of blocks */
+    if (read (dir->fd, &entry.d_blocks, sizeof (entry.d_blocks)) !=
+        sizeof (entry.d_blocks)) {
+        goto error;
+    }
+
+    /* Read the next file entry into the buffer */
+    for (count = 0, b = buffer; count < sizeof (buffer); ++count, ++b) {
+        if (read (dir->fd, b, 1) != 1) {
+            /* ### Check for EOF */
+            goto error;
+        }
+        if (*b == '\0') {
+            break;
+        }
+    }
+
+    /* End of directory is reached if the buffer contains "blocks free". It is
+     * sufficient here to check for the leading 'b'. To avoid problems if we're
+     * called again, read until end of directory.
+     */
+    if (count > 0 && buffer[0] == 'b') {
+        while (read (dir->fd, buffer, 1) == 1) ;
+        return 0;
+    }
+
+    /* Bump the directory offset */
+    dir->off += count;
+
+    /* Parse the buffer for the filename and file type */
+    i = 0;
+    j = 0;
+    s = 0;
+    b = buffer;
+    while (i < count) {
+        switch (s) {
+
+            case 0:
+                /* Searching for start of file name */
+                if (*b == '"') {
+                    s = 1;
+                }
+                break;
+
+            case 1:
+                /* Within file name */
+                if (*b == '"') {
+                    entry.d_name[j] = '\0';
+                    entry.d_namlen = j;
+                    s = 2;
+                } else if (j < sizeof (entry.d_name) - 1) {
+                    entry.d_name[j] = *b;
+                    ++j;
+                }
+                break;
+
+            case 2:
+                /* Searching for file type */
+                if (*b != ' ') {
+                    entry.d_type = _cbm_filetype (*b);
+                    if (*b == 'd') {
+                        /* May be DEL or DIR, check next char */
+                        s = 3;
+                    } else {
+                        /* Done */
+                        return &entry;
+                    }
+                }
+                break;
+
+            case 3:
+                /* Distinguish DEL or DIR file type entries */
+                switch (*b) {
+                    case 'e':                                   break;
+                    case 'i': entry.d_type = CBM_T_DIR;         break;
+                    default:  entry.d_type = CBM_T_OTHER;       break;
+                }
+                return &entry;
+        }
+        ++i;
+        ++b;
+    }
+
+    /* Something went wrong - terminating quote not found */
+error:
+    _errno = EIO;
+exit:
+    return 0;
+}
+
+
+