Improved cbm_dir routines by Thomas Giesel.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4264 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2009-09-28 22:01:58 +00:00
parent 01a11b2dd9
commit d54a1ba3d2
2 changed files with 93 additions and 81 deletions

View File

@@ -124,8 +124,10 @@ extern unsigned char _filetype; /* Default 'u' */
#define CBM_T_REL 4 #define CBM_T_REL 4
#define CBM_T_CBM 5 /* 1581 sub-partition */ #define CBM_T_CBM 5 /* 1581 sub-partition */
#define CBM_T_DIR 6 /* IDE64 and CMD sub-directory */ #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_VRP 8 /* Vorpal fast-loadable format */
#define CBM_T_OTHER 5 /* Other file-types not yet defined */ #define CBM_T_OTHER 9 /* Other file-types not yet defined */
#define CBM_T_HEADER 10 /* Disk header / title */
/* CBM FILE ACCESS */ /* CBM FILE ACCESS */
#define CBM_A_RO 1 /* Read only */ #define CBM_A_RO 1 /* Read only */

View 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 __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_dirent* l_dirent)
{ {
unsigned char byte, i; unsigned char byte, i;
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 */
};
if (cbm_k_chkin (lfn) == 0) { rv = 1;
if (cbm_k_readst () == 0) { is_header = 0;
cbm_k_basin (); /* 0x01, 0x01, next basic line */
if (!cbm_k_chkin(lfn)) {
if (!cbm_k_readst()) {
/* skip 2 bytes, next basic line pointer */
cbm_k_basin();
cbm_k_basin(); cbm_k_basin();
byte = cbm_k_basin(); /* File-size */ /* File-size */
l_dirent->size = byte | ((cbm_k_basin()) << 8); l_dirent->size = cbm_k_basin() | ((cbm_k_basin()) << 8);
byte = cbm_k_basin(); byte = cbm_k_basin();
if (byte == 'b') { /* "B" BLOCKS FREE. */ /* "B" BLOCKS FREE. */
while (cbm_k_readst () == 0) { /* Read until end */ if (byte == 'b') {
/* Read until end, careless callers may call us again */
while (!cbm_k_readst()) {
cbm_k_basin(); cbm_k_basin();
} }
cbm_k_clrch (); rv = 2; /* EOF */
return 2; /* END */ goto ret_val;
} }
if (byte != '\"') { /* reverse text shows that this is the directory header */
while (cbm_k_basin() != '\"') { if (byte == 0x12) { /* RVS_ON */
if (cbm_k_readst () != 0) { /* ### Included to prevent */ is_header = 1;
cbm_k_clrch (); /* ### Endless loop */ }
return 3; /* ### Should be probably removed */
} /* ### */ while (byte != '\"') {
byte = cbm_k_basin();
/* prevent endless loop */
if (cbm_k_readst()) {
rv = 3;
goto ret_val;
} }
} }
i = 0; i = 0;
while ((byte = cbm_k_basin()) != '\"') { while ((byte = cbm_k_basin()) != '\"') {
if (cbm_k_readst () != 0) { /* ### Included to prevent */ /* prevent endless loop */
cbm_k_clrch (); /* ### Endless loop */ if (cbm_k_readst()) {
return 4; /* ### Should be probably removed */ rv = 4;
} /* ### */ goto ret_val;
}
if (i < sizeof (l_dirent->name) - 1) { if (i < sizeof (l_dirent->name) - 1) {
l_dirent->name[i] = byte; l_dirent->name[i] = byte;
@@ -81,35 +103,19 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d
l_dirent->name[i] = '\0'; l_dirent->name[i] = '\0';
while ((byte = cbm_k_basin()) == ' ') { while ((byte = cbm_k_basin()) == ' ') {
if (cbm_k_readst ()) { /* ### Included to prevent */ /* prevent endless loop */
cbm_k_clrch (); /* ### Endless loop */ if (cbm_k_readst()) {
return 5; /* ### Should be probably removed */ rv = 5;
} /* ### */ goto ret_val;
}
} }
switch (byte) { if (is_header) {
case 's': l_dirent->type = CBM_T_HEADER;
l_dirent->type = CBM_T_SEQ; } else {
break; if (byte >= 'a' && byte < 'a' + sizeof(types)) {
case 'p': l_dirent->type = types[byte - 'a'];
l_dirent->type = CBM_T_PRG; } else {
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:
l_dirent->type = CBM_T_OTHER; l_dirent->type = CBM_T_OTHER;
} }
@@ -119,22 +125,26 @@ unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_d
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) { /* read to end of line */
while (cbm_k_basin() != 0) { while (byte != 0) {
if (cbm_k_readst () != 0) { /* ### Included to prevent */ byte = cbm_k_basin();
cbm_k_clrch (); /* ### Endless loop */ /* prevent endless loop */
return 6; /* ### Should be probably removed */ if (cbm_k_readst()) {
} /* ### */ rv = 6;
goto ret_val;
} }
} }
cbm_k_clrch (); rv = 0;
return 0; /* Line read successfuly */ goto ret_val;
} }
} }
ret_val:
cbm_k_clrch(); cbm_k_clrch();
return 1; return rv;
} }