mirror of
https://github.com/cc65/cc65.git
synced 2024-08-31 07:29:23 +00:00
158 lines
4.4 KiB
C
158 lines
4.4 KiB
C
/* This is very simplified version of POSIX opendir(), readdir() and closedir() */
|
|
/* for Commodore computers. */
|
|
/* Created by Josef Soucek, 2003 E-mail:josef.soucek@ct.cz */
|
|
|
|
/* Version 0.1 - 21.1.2003 */
|
|
/* Tested with floppy drive and IDE64 devices */
|
|
/* Not tested with messed (buggy) directory listing */
|
|
/* Limits filenames to 16 chars (VICE supports more in directory listing) */
|
|
|
|
|
|
|
|
#include <cbm.h>
|
|
|
|
|
|
|
|
unsigned char __fastcall__ cbm_opendir (unsigned char lfn, unsigned char device)
|
|
{
|
|
unsigned char status;
|
|
if ((status = cbm_open (lfn, device, CBM_READ, "$")) == 0) {
|
|
if (cbm_k_chkin (lfn) == 0) {
|
|
/* Ignore start address */
|
|
cbm_k_basin();
|
|
cbm_k_basin();
|
|
if (cbm_k_readst()) {
|
|
cbm_close(lfn);
|
|
status = 2;
|
|
cbm_k_clrch();
|
|
} else {
|
|
status = 0;
|
|
cbm_k_clrch();
|
|
}
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
unsigned char __fastcall__ cbm_readdir (unsigned char lfn, register struct cbm_dirent* l_dirent)
|
|
{
|
|
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 */
|
|
};
|
|
|
|
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();
|
|
|
|
/* "B" BLOCKS FREE. */
|
|
if (byte == 'b') {
|
|
/* Read until end, careless callers may call us again */
|
|
while (!cbm_k_readst()) {
|
|
cbm_k_basin();
|
|
}
|
|
rv = 2; /* EOF */
|
|
goto ret_val;
|
|
}
|
|
|
|
/* 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()) != '\"') {
|
|
/* prevent endless loop */
|
|
if (cbm_k_readst()) {
|
|
rv = 4;
|
|
goto ret_val;
|
|
}
|
|
|
|
if (i < sizeof (l_dirent->name) - 1) {
|
|
l_dirent->name[i] = byte;
|
|
++i;
|
|
}
|
|
}
|
|
l_dirent->name[i] = '\0';
|
|
|
|
while ((byte = cbm_k_basin()) == ' ') {
|
|
/* prevent endless loop */
|
|
if (cbm_k_readst()) {
|
|
rv = 5;
|
|
goto ret_val;
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
byte = cbm_k_basin();
|
|
|
|
l_dirent->access = (byte == 0x3C)? CBM_A_RO : CBM_A_RW;
|
|
}
|
|
|
|
/* read to end of line */
|
|
while (byte != 0) {
|
|
byte = cbm_k_basin();
|
|
/* prevent endless loop */
|
|
if (cbm_k_readst()) {
|
|
rv = 6;
|
|
goto ret_val;
|
|
}
|
|
}
|
|
|
|
rv = 0;
|
|
goto ret_val;
|
|
}
|
|
}
|
|
|
|
ret_val:
|
|
cbm_k_clrch();
|
|
return rv;
|
|
}
|
|
|
|
|
|
void __fastcall__ cbm_closedir( unsigned char lfn)
|
|
{
|
|
cbm_close(lfn);
|
|
}
|
|
|
|
|