diff --git a/include/dirent.h b/include/dirent.h index 11c6edc32..cb3ddc139 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -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); diff --git a/libsrc/cbm/Makefile b/libsrc/cbm/Makefile index c25d06830..c91428a42 100644 --- a/libsrc/cbm/Makefile +++ b/libsrc/cbm/Makefile @@ -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 \ diff --git a/libsrc/cbm/dir.inc b/libsrc/cbm/dir.inc index ffab6c20c..5e2dfc6d6 100644 --- a/libsrc/cbm/dir.inc +++ b/libsrc/cbm/dir.inc @@ -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 diff --git a/libsrc/cbm/rewinddir.s b/libsrc/cbm/rewinddir.s new file mode 100644 index 000000000..d84d08ace --- /dev/null +++ b/libsrc/cbm/rewinddir.s @@ -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 + diff --git a/libsrc/cbm/seekdir.c b/libsrc/cbm/seekdir.c new file mode 100644 index 000000000..0a4fe0781 --- /dev/null +++ b/libsrc/cbm/seekdir.c @@ -0,0 +1,55 @@ +/* + * Ullrich von Bassewitz, 2012-06-03. Based on code by Groepaz. + */ + +#include +#include +#include +#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; + } + } +} + + +