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 f3281705e..109fdb847 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -44,7 +44,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_fseek.c b/test/ref/test_fseek.c new file mode 100644 index 000000000..e63dc0c02 --- /dev/null +++ b/test/ref/test_fseek.c @@ -0,0 +1,73 @@ +/* + !!DESCRIPTION!! fgets 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; +}