diff --git a/libsrc/common/rewind.c b/libsrc/common/rewind.c deleted file mode 100644 index 333230b74..000000000 --- a/libsrc/common/rewind.c +++ /dev/null @@ -1,25 +0,0 @@ -/* -** rewind.c -** -** Christian Groessler, 07-Aug-2000 -*/ - - - -#include - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -void __fastcall__ rewind (FILE* f) -{ - fseek(f, 0L, SEEK_SET); - clearerr(f); -} - - diff --git a/libsrc/common/rewind.s b/libsrc/common/rewind.s new file mode 100644 index 000000000..e7013505c --- /dev/null +++ b/libsrc/common/rewind.s @@ -0,0 +1,35 @@ +; +; Colin Leroy-Mira +; +; void __fastcall__ rewind (FILE* f) +; /* Rewind a file */ +; + + .export _rewind + + .import _fseek, _clearerr + .import pushax, pushl0, popax + + .include "stdio.inc" + + +; ------------------------------------------------------------------------ +; Code + +.proc _rewind + + ; Push f twice (once for fseek, once for clearerr later) + jsr pushax + jsr pushax + + ; Push offset (long) zero + jsr pushl0 + + lda #SEEK_SET + jsr _fseek + + ; Clear error + jsr popax + jmp _clearerr + +.endproc diff --git a/libsrc/sim6502/paravirt.s b/libsrc/sim6502/paravirt.s index 3bd40fbe4..b9fc38de5 100644 --- a/libsrc/sim6502/paravirt.s +++ b/libsrc/sim6502/paravirt.s @@ -7,9 +7,10 @@ ; int __fastcall__ write (int fd, const void* buf, unsigned count); ; - .export exit, args, _open, _close, _read, _write + .export exit, args, _open, _close, _read, _write, _lseek .export __sysremove, ___osmaperrno +_lseek := $FFF1 __sysremove := $FFF2 ___osmaperrno := $FFF3 _open := $FFF4 diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 141bcd2bd..4e68a3f0e 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -159,6 +159,30 @@ static void PVArgs (CPURegs* Regs) SetAX (Regs, ArgC); } +/* Match between standard POSIX whence and cc65 whence. */ +static unsigned SEEK_MODE_MATCH[3] = { + SEEK_CUR, + SEEK_END, + SEEK_SET +}; + +static void PVLseek (CPURegs* Regs) +{ + unsigned RetVal; + + unsigned Whence = GetAX (Regs); + unsigned Offset = PopParam (4); + unsigned FD = PopParam (2); + + Print (stderr, 2, "PVLseek ($%04X, $%08X, $%04X (%d))\n", + FD, Offset, Whence, SEEK_MODE_MATCH[Whence]); + + RetVal = lseek(FD, (off_t)Offset, SEEK_MODE_MATCH[Whence]); + Print (stderr, 2, "PVLseek returned %04X\n", RetVal); + + SetAX (Regs, RetVal); +} + static void PVOpen (CPURegs* Regs) @@ -343,6 +367,7 @@ static void PVOSMapErrno (CPURegs* Regs) static const PVFunc Hooks[] = { + PVLseek, PVSysRemove, PVOSMapErrno, PVOpen, diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index f5d74acc8..83c7127a0 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -45,7 +45,7 @@ -#define PARAVIRT_BASE 0xFFF2 +#define PARAVIRT_BASE 0xFFF1 /* Lowest address used by a paravirtualization hook */ #define PV_PATH_SIZE 1024 diff --git a/test/ref/test_fread.c b/test/ref/test_fread.c index 5d180d723..99411ab28 100644 --- a/test/ref/test_fread.c +++ b/test/ref/test_fread.c @@ -1,5 +1,5 @@ /* - !!DESCRIPTION!! fgets test + !!DESCRIPTION!! fread test !!LICENCE!! Public domain */ @@ -51,6 +51,7 @@ int main(int argc,char **argv) if (r == 0) { printf("Error: could not start reading.\n"); + return EXIT_FAILURE; } fwrite(buf, 1, r, stdout); @@ -63,6 +64,7 @@ int main(int argc,char **argv) if (!feof(in)) { printf("We should have EOF!\n"); + return EXIT_FAILURE; } fclose(in); diff --git a/test/ref/test_fseek.c b/test/ref/test_fseek.c new file mode 100644 index 000000000..157d0bdf0 --- /dev/null +++ b/test/ref/test_fseek.c @@ -0,0 +1,73 @@ +/* + !!DESCRIPTION!! fseek test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include +#include +#include +#include +#include +#include + +FILE *in; +char bufA[32]; +char bufB[32]; + +#define INFILE "cf.in" + +int main(int argc,char **argv) +{ + static int r; + + in = fopen(INFILE, "rb"); + if (in == NULL) { + return EXIT_FAILURE; + } + + r = fread(bufA, 1, sizeof(bufA), in); + + if (r == 0) { + printf("Error: could not read.\n"); + return EXIT_FAILURE; + } + fwrite(bufA, 1, r, stdout); + + /* Test SEEK_SET */ + fseek(in, 0, SEEK_SET); + r = fread(bufB, 1, sizeof(bufB), in); + + if (r == 0) { + printf("Error: could not re-read after SEEK_SET.\n"); + return EXIT_FAILURE; + } + fwrite(bufB, 1, r, stdout); + + if (memcmp(bufA, bufB, sizeof(bufA))) { + printf("reads differ.\n"); + return EXIT_FAILURE; + } + + /* Test SEEK_CUR */ + fseek(in, 0, SEEK_SET); + fseek(in, 1, SEEK_CUR); + r = fread(bufB, 1, sizeof(bufB), in); + + if (r == 0) { + printf("Error: could not re-read after SEEK_CUR.\n"); + return EXIT_FAILURE; + } + fwrite(bufB, 1, r, stdout); + + if (memcmp(bufA+1, bufB, sizeof(bufA)-1)) { + printf("reads differ.\n"); + return EXIT_FAILURE; + } + + + fclose(in); + + return 0; +} diff --git a/test/ref/test_rewind.c b/test/ref/test_rewind.c new file mode 100644 index 000000000..d1b361983 --- /dev/null +++ b/test/ref/test_rewind.c @@ -0,0 +1,56 @@ +/* + !!DESCRIPTION!! rewind test + !!LICENCE!! Public domain +*/ + +#include "common.h" + +#include +#include +#include +#include +#include +#include + +FILE *in; +char bufA[32]; +char bufB[32]; + +#define INFILE "cf.in" + +int main(int argc,char **argv) +{ + static int r; + + in = fopen(INFILE, "rb"); + if (in == NULL) { + return EXIT_FAILURE; + } + + r = fread(bufA, 1, sizeof(bufA), in); + + if (r == 0) { + printf("Error: could not read.\n"); + return EXIT_FAILURE; + } + fwrite(bufA, 1, r, stdout); + + rewind(in); + printf("rewind.\n"); + r = fread(bufB, 1, sizeof(bufB), in); + + if (r == 0) { + printf("Error: could not re-read.\n"); + return EXIT_FAILURE; + } + fwrite(bufB, 1, r, stdout); + + fclose(in); + + if (memcmp(bufA, bufB, sizeof(bufA))) { + printf("reads differ.\n"); + return EXIT_FAILURE; + } + + return 0; +}