1 /* This is a very simplified version of the POSIX opendir(), */
2 /* readdir(), and closedir() -- for Commodore computers. */
3 /* Created by Josef Soucek, 2003. E-mail: josef.soucek@ct.cz */
5 /* 2003-01-21 -- Version 0.1 */
6 /* 2009-10-10 -- Version 0.3 */
7 /* 2011-04-07 -- Version 0.4, groepaz */
8 /* 2011-04-14 -- Version 0.5, Greg King */
10 /* Tested with floppy-drive and IDE64 devices. */
11 /* Not tested with messed (buggy) directory listings. */
12 /* Limits filenames to 16 chars. (VICE supports more */
13 /* in directory listings). */
21 /* Opens directory listing.
22 ** Returns 0 if openning directory was successful;
23 ** otherwise, an error-code corresponding to cbm_open().
25 unsigned char __fastcall__ cbm_opendir (unsigned char lfn, unsigned char device)
27 if (cbm_open (lfn, device, CBM_READ, "$") == 0) {
28 if ((_oserror = cbm_k_chkin (lfn)) == 0) {
29 /* Ignore start address */
35 _oserror = 4; /* directory cannot be read */
44 /* Reads one directory line into cbm_dirent structure.
45 ** Returns 0 if reading directory-line was successful.
46 ** Returns non-zero if reading directory failed, or no more file-names to read.
47 ** Returns 2 on last line. Then, l_dirent->size = the number of "blocks free."
49 unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_dirent* l_dirent)
51 unsigned char byte, i = 0;
52 unsigned char is_header = 0;
54 static const unsigned char types[] = {
55 CBM_T_CBM, CBM_T_DEL, CBM_T_OTHER, CBM_T_OTHER, /* c d e f */
56 CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, CBM_T_OTHER, /* g h i j */
57 CBM_T_OTHER, CBM_T_LNK, CBM_T_OTHER, CBM_T_OTHER, /* k l m n */
58 CBM_T_OTHER, CBM_T_PRG, CBM_T_OTHER, CBM_T_REL, /* o p q r */
59 CBM_T_SEQ, CBM_T_OTHER, CBM_T_USR, CBM_T_VRP /* s t u v */
62 if (!cbm_k_chkin(lfn)) {
63 if (!cbm_k_readst()) {
64 /* skip 2 bytes, next-BASIC-line pointer */
68 /* File-size or drive/partition number */
69 l_dirent->size = cbm_k_basin() | (cbm_k_basin() << 8);
74 /* "B" BLOCKS FREE. */
76 /* Read until end; careless callers might call us again. */
77 while (!cbm_k_readst()) {
83 /* Reverse-text shows when this is the directory header. */
84 case 0x12: /* RVS_ON */
88 while (byte != '\"') {
89 /* prevent endless loop */
97 while ((byte = cbm_k_basin()) != '\"') {
98 /* prevent endless loop */
104 if (i < sizeof (l_dirent->name) - 1) {
105 l_dirent->name[i] = byte;
109 l_dirent->name[i] = '\0';
112 l_dirent->type = CBM_T_HEADER;
114 /* Get the disk-format code. */
117 l_dirent->access = byte = cbm_k_basin();
121 /* Go to the file-type column. */
122 while ((byte = cbm_k_basin()) == ' ') {
123 /* prevent endless loop */
124 if (cbm_k_readst()) {
130 l_dirent->access = CBM_A_RW;
132 /* "Splat" files shouldn't be read. */
134 l_dirent->access = CBM_A_WO;
135 byte = cbm_k_basin();
138 if (byte >= 'c' && byte < 'c' + sizeof types) {
139 l_dirent->type = types[byte - 'c'];
141 l_dirent->type = CBM_T_OTHER;
144 /* Notice whether it's a directory or a deleted file. */
145 if (cbm_k_basin() == 'i' && byte == 'd') {
146 l_dirent->type = CBM_T_DIR;
150 /* Locked files shouldn't be written. */
151 if ((byte = cbm_k_basin()) == '<') {
152 l_dirent->access = (l_dirent->access == CBM_A_WO)
157 /* Read to the end of the line. */
159 /* prevent endless loop */
160 if (cbm_k_readst()) {
164 byte = cbm_k_basin();
179 void __fastcall__ cbm_closedir (unsigned char lfn)