1
0
mirror of https://github.com/cc65/cc65.git synced 2025-04-08 19:38:55 +00:00

Merge pull request #2587 from colinleroy/rewind-asm-and-fseek-paravirt

Rewrite rewind() in assembly,add lseek() to paravirt
This commit is contained in:
Bob Andrews 2025-01-27 17:18:12 +01:00 committed by GitHub
commit d5cf8ef7ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 195 additions and 28 deletions

View File

@ -1,25 +0,0 @@
/*
** rewind.c
**
** Christian Groessler, 07-Aug-2000
*/
#include <stdio.h>
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void __fastcall__ rewind (FILE* f)
{
fseek(f, 0L, SEEK_SET);
clearerr(f);
}

35
libsrc/common/rewind.s Normal file
View File

@ -0,0 +1,35 @@
;
; Colin Leroy-Mira <colin@colino.net>
;
; 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

View File

@ -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

View File

@ -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,

View File

@ -45,7 +45,7 @@
#define PARAVIRT_BASE 0xFFF2
#define PARAVIRT_BASE 0xFFF1
/* Lowest address used by a paravirtualization hook */
#define PV_PATH_SIZE 1024

View File

@ -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);

73
test/ref/test_fseek.c Normal file
View File

@ -0,0 +1,73 @@
/*
!!DESCRIPTION!! fseek test
!!LICENCE!! Public domain
*/
#include "common.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
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;
}

56
test/ref/test_rewind.c Normal file
View File

@ -0,0 +1,56 @@
/*
!!DESCRIPTION!! rewind test
!!LICENCE!! Public domain
*/
#include "common.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
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;
}