Implemented rewinddir/seekdir.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5676 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2012-06-03 15:11:32 +00:00
parent 5f43589885
commit c40b54ee6c
5 changed files with 91 additions and 5 deletions

View File

@ -126,6 +126,10 @@ struct dirent* __fastcall__ readdir (DIR* dir);
int __fastcall__ closedir (DIR* dir);
long __fastcall__ telldir (DIR* dir);
void __fastcall__ seekdir (DIR* dir, long offs);
void __fastcall__ rewinddir (DIR* dir);

View File

@ -33,7 +33,8 @@ C_OBJS = cbm_dir.o \
cbm_load.o \
cbm_save.o \
opendir.o \
readdir.o
readdir.o \
seekdir.o
S_OBJS = c_acptr.o \
c_basin.o \
@ -82,6 +83,7 @@ S_OBJS = c_acptr.o \
oserrlist.o \
oserror.o \
read.o \
rewinddir.o \
rwcommon.o \
scratch.o \
sysremove.o \

View File

@ -10,7 +10,7 @@
.struct DIR
fd .word
off .word
off .word
name .byte 16+1
.endstruct
@ -21,10 +21,10 @@
.global _opendir
.global _closedir
.global _readdir
; .global _telldir
; .global _rewinddir
.global _seekdir
.global _telldir
.global _rewinddir
.global __dirread
.global __dirread1
.global __dirskip

25
libsrc/cbm/rewinddir.s Normal file
View File

@ -0,0 +1,25 @@
;
; Ullrich von Bassewitz, 2012-06-03
;
; Based on C code by Groepaz
;
; void __fastcall__ rewinddir (DIR *dir);
;
.include "dir.inc"
.include "zeropage.inc"
.import pushax
.proc _rewinddir
jsr pushax ; Push dir
ldx #0
stx sreg+1
stx sreg
lda #32 ; Pass 32 as offset ...
jmp _seekdir ; ... to seekdir
.endproc

55
libsrc/cbm/seekdir.c Normal file
View File

@ -0,0 +1,55 @@
/*
* Ullrich von Bassewitz, 2012-06-03. Based on code by Groepaz.
*/
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "dir.h"
void __fastcall__ seekdir (register DIR* dir, long offs)
{
unsigned o;
unsigned char count;
unsigned char buf[128];
/* Make sure we have a reasonable value for offs */
if (offs > 0x1000) {
errno = EINVAL;
return;
}
/* Close the directory file descriptor */
close (dir->fd);
/* Reopen it using the old name */
dir->fd = open (dir->name, O_RDONLY);
if (dir->fd < 0) {
/* Oops! */
return;
}
/* Skip until we've reached the target offset in the directory */
o = dir->off = offs;
while (o) {
/* Determine size of next chunk to read */
if (o > sizeof (buf)) {
count = sizeof (buf);
o -= sizeof (buf);
} else {
count = offs;
o = 0;
}
/* Skip */
if (!_dirread (dir, buf, count)) {
return;
}
}
}