]> git.sur5r.net Git - cc65/blob - libsrc/cbm/cbm_dir.c
Ignore start address in cbm_opendir. Rearrange the code somewhat to make it
[cc65] / libsrc / cbm / cbm_dir.c
1 /* This is very simplified version of POSIX opendir(), readdir() and closedir() */
2 /* for Commodore computers.                                                     */
3 /* Created by Josef Soucek, 2003    E-mail:josef.soucek@ct.cz                   */
4
5 /* Version 0.1 - 21.1.2003 */
6 /* Tested with floppy drive and IDE64 devices                                   */
7 /* Not tested with messed (buggy) directory listing                             */
8 /* Limits filenames to 16 chars (VICE supports more in directory listing)       */
9
10
11
12 #include <cbm.h>
13
14
15
16 unsigned char __fastcall__ cbm_opendir (unsigned char lfn, unsigned
17 char device) {
18     unsigned char status;
19     if ((status = cbm_open (lfn, device, CBM_READ, "$")) == 0) {
20         if (cbm_k_chkin (lfn) == 0) {
21             /* Ignore start address */
22             cbm_k_basin();
23             cbm_k_basin();
24             if (cbm_k_readst()) {
25                 cbm_close(lfn);
26                 status = 2;
27                 cbm_k_clrch();
28             } else {
29                 status = 0;
30                 cbm_k_clrch();
31             }
32         }
33     }
34     return status;
35 }
36
37
38
39 unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_dirent* l_dirent)
40 {
41     unsigned char byte, i;
42     unsigned char rv;
43     unsigned char is_header;
44     static const unsigned char types[] = {
45         CBM_T_OTHER, CBM_T_OTHER, CBM_T_CBM,   CBM_T_DIR,   /* a b c d */
46         CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, /* e f g h */
47         CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, /* i j k l */
48         CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, CBM_T_PRG,   /* m n o p */
49         CBM_T_OTHER, CBM_T_REL,   CBM_T_SEQ,   CBM_T_OTHER, /* q r s t */
50         CBM_T_USR,   CBM_T_VRP                              /* u v     */
51     };
52
53     rv = 1;
54     is_header = 0;
55
56     if (!cbm_k_chkin(lfn)) {
57         if (!cbm_k_readst()) {
58             /* skip 2 bytes, next basic line pointer */
59             cbm_k_basin();
60             cbm_k_basin();
61
62             /* File-size */
63             l_dirent->size = cbm_k_basin() | ((cbm_k_basin()) << 8);
64
65             byte = cbm_k_basin();
66
67             /* "B" BLOCKS FREE. */
68             if (byte == 'b') {
69                 /* Read until end, careless callers may call us again */
70                 while (!cbm_k_readst()) {
71                     cbm_k_basin();
72                 }
73                 rv = 2; /* EOF */
74                 goto ret_val;
75             }
76
77             /* reverse text shows that this is the directory header */
78             if (byte == 0x12) { /* RVS_ON */
79                 is_header = 1;
80             }
81
82             while (byte != '\"') {
83                 byte = cbm_k_basin();
84                 /* prevent endless loop */
85                 if (cbm_k_readst()) {
86                     rv = 3;
87                     goto ret_val;
88                 }
89             }
90
91             i = 0;
92             while ((byte = cbm_k_basin()) != '\"') {
93                 /* prevent endless loop */
94                 if (cbm_k_readst()) {
95                     rv = 4;
96                     goto ret_val;
97                 }
98
99                 if (i < sizeof (l_dirent->name) - 1) {
100                     l_dirent->name[i] = byte;
101                     ++i;
102                 }
103             }
104             l_dirent->name[i] = '\0';
105
106             while ((byte = cbm_k_basin()) == ' ') {
107                 /* prevent endless loop */
108                 if (cbm_k_readst()) {
109                     rv = 5;
110                     goto ret_val;
111                 }
112             }
113
114             if (is_header) {
115                 l_dirent->type = CBM_T_HEADER;
116             } else {
117                 if (byte >= 'a' && byte < 'a' + sizeof(types)) {
118                     l_dirent->type = types[byte - 'a'];
119                 } else {
120                     l_dirent->type = CBM_T_OTHER;
121                 }
122
123                 cbm_k_basin();
124                 cbm_k_basin();
125
126                 byte = cbm_k_basin();
127
128                 l_dirent->access = (byte == 0x3C)? CBM_A_RO : CBM_A_RW;
129             }
130
131             /* read to end of line */
132             while (byte != 0) {
133                 byte = cbm_k_basin();
134                 /* prevent endless loop */
135                 if (cbm_k_readst()) {
136                     rv = 6;
137                     goto ret_val;
138                 }
139             }
140
141             rv = 0;
142             goto ret_val;
143         }
144     }
145
146 ret_val:
147     cbm_k_clrch();
148     return rv;
149 }
150
151
152 void __fastcall__ cbm_closedir( unsigned char lfn)
153 {
154     cbm_close(lfn);
155 }
156
157