1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-08 06:25:17 +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
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); ; 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 .export __sysremove, ___osmaperrno
_lseek := $FFF1
__sysremove := $FFF2 __sysremove := $FFF2
___osmaperrno := $FFF3 ___osmaperrno := $FFF3
_open := $FFF4 _open := $FFF4

View File

@@ -159,6 +159,30 @@ static void PVArgs (CPURegs* Regs)
SetAX (Regs, ArgC); 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) static void PVOpen (CPURegs* Regs)
@@ -343,6 +367,7 @@ static void PVOSMapErrno (CPURegs* Regs)
static const PVFunc Hooks[] = { static const PVFunc Hooks[] = {
PVLseek,
PVSysRemove, PVSysRemove,
PVOSMapErrno, PVOSMapErrno,
PVOpen, PVOpen,

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
!!DESCRIPTION!! fgets test !!DESCRIPTION!! fread test
!!LICENCE!! Public domain !!LICENCE!! Public domain
*/ */
@@ -51,6 +51,7 @@ int main(int argc,char **argv)
if (r == 0) { if (r == 0) {
printf("Error: could not start reading.\n"); printf("Error: could not start reading.\n");
return EXIT_FAILURE;
} }
fwrite(buf, 1, r, stdout); fwrite(buf, 1, r, stdout);
@@ -63,6 +64,7 @@ int main(int argc,char **argv)
if (!feof(in)) if (!feof(in))
{ {
printf("We should have EOF!\n"); printf("We should have EOF!\n");
return EXIT_FAILURE;
} }
fclose(in); 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;
}