From eab5f250ad915326a3ffda314246bcc193084342 Mon Sep 17 00:00:00 2001 From: uz Date: Fri, 1 Jun 2012 19:23:34 +0000 Subject: [PATCH] New function _dirskip that allows to skip an amount of bytes from the directory with error check. git-svn-id: svn://svn.cc65.org/cc65/trunk@5668 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- libsrc/cbm/Makefile | 1 + libsrc/cbm/dir.h | 18 ++++++++- libsrc/cbm/dir.inc | 2 +- libsrc/cbm/dir.s | 92 ++++++++++++++++++++++++++++++++++++++++++++ libsrc/cbm/opendir.c | 14 +++---- 5 files changed, 117 insertions(+), 10 deletions(-) create mode 100644 libsrc/cbm/dir.s diff --git a/libsrc/cbm/Makefile b/libsrc/cbm/Makefile index cc8fc7b17..a811edac1 100644 --- a/libsrc/cbm/Makefile +++ b/libsrc/cbm/Makefile @@ -65,6 +65,7 @@ S_OBJS = c_acptr.o \ closedir.o \ ctype.o \ cvline.o \ + dir.o \ diskcmd.o \ exehdr.o \ filedes.o \ diff --git a/libsrc/cbm/dir.h b/libsrc/cbm/dir.h index a1137acfe..06081a47c 100644 --- a/libsrc/cbm/dir.h +++ b/libsrc/cbm/dir.h @@ -1,4 +1,4 @@ -/* +/* * Internal include file, do not use directly. * Written by Ullrich von Bassewitz. Based on code by Groepaz. */ @@ -24,6 +24,22 @@ struct DIR { +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +unsigned char __fastcall__ _dirskip (unsigned char count, struct DIR* dir); +/* Skip bytes from the directory and make sure, errno is set if this isn't + * possible. Return true if anything is ok and false otherwise. For + * simplicity we assume that read will never return less than count if there + * is no error and end-of-file is not reached. + * Note: count must not be more than 254. + */ + + + /* End of dir.h */ #endif diff --git a/libsrc/cbm/dir.inc b/libsrc/cbm/dir.inc index 447b35c8f..3536f87f7 100644 --- a/libsrc/cbm/dir.inc +++ b/libsrc/cbm/dir.inc @@ -23,5 +23,5 @@ .global _readdir .global _telldir .global _rewinddir - + .global __dirskip diff --git a/libsrc/cbm/dir.s b/libsrc/cbm/dir.s new file mode 100644 index 000000000..903e20483 --- /dev/null +++ b/libsrc/cbm/dir.s @@ -0,0 +1,92 @@ +; +; Ullrich von Bassewitz, 2012-06-01 +; +; unsigned char __fastcall__ _dirskip (unsigned char count, struct DIR* dir); +; /* Skip bytes from the directory and make sure, errno is set if this isn't +; * possible. Return true if anything is ok and false otherwise. For +; * simplicity we assume that read will never return less than count if there +; * is no error and end-of-file is not reached. +; * Note: count must not be more than 254. +; */ +; + + .include "dir.inc" + .include "errno.inc" + .include "zeropage.inc" + + .import _read + .import pushax, pushptr1idx + .import subysp, addysp1 + + +.proc __dirskip + + sta ptr1 + stx ptr1+1 ; Save dir + +; Get count and allocate space on the stack + + ldy #0 + lda (sp),y + pha + tay + jsr subysp + +; Save current value of sp + + lda sp + pha + lda sp+1 + pha + +; Push dir->fd + + ldy #DIR::fd+1 + jsr pushptr1idx + +; Push pointer to buffer + + pla + tax + pla + jsr pushax + +; Load count and call read + + pla + pha + ldx #0 + jsr _read + +; Check for errors. In case of errors, errno is already set. + + cpx #$FF + bne L2 + +; read() returned an error + + pla ; Count + tay + lda #0 + tax +L1: jmp addysp1 ; Drop buffer plus count + +; read() was successful, check number of bytes read. We assume that read will +; not return more than count, so X is zero if we come here. + +L2: sta tmp1 + pla ; count + tay + cmp tmp1 + beq L1 ; Drop variables, return count + +; Didn't read enough bytes. This is an error for us, but errno is not set + + lda # #include #include @@ -10,10 +14,8 @@ DIR* __fastcall__ opendir (const char*) { - unsigned char buffer[8+16+1+7]; - int count; - DIR d; DIR* dir = 0; + DIR d; /* Setup file name and offset */ d.name[0] = '$'; @@ -25,8 +27,7 @@ DIR* __fastcall__ opendir (const char*) if (d.fd >= 0) { /* Skip the disk header */ - count = read (d.fd, buffer, sizeof (buffer)); - if (count == sizeof (buffer)) { + if (_dirskip (32, &d)) { /* Allocate memory for the DIR structure returned */ dir = malloc (sizeof (*dir)); @@ -38,9 +39,6 @@ DIR* __fastcall__ opendir (const char*) /* Set an appropriate error code */ errno = ENOMEM; } - } else if (count >= 0) { - /* Short read - need to set an error code */ - errno = EIO; } } -- 2.39.5