From: cuz Date: Sat, 23 Nov 2002 17:52:38 +0000 (+0000) Subject: Rewrote _fopen in assembler X-Git-Tag: V2.12.0~2030 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6f198ae131e0a576632de04f8f572fbb1e6055fa;p=cc65 Rewrote _fopen in assembler git-svn-id: svn://svn.cc65.org/cc65/trunk@1607 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/common/.cvsignore b/libsrc/common/.cvsignore index 0939e9b10..46556ea50 100644 --- a/libsrc/common/.cvsignore +++ b/libsrc/common/.cvsignore @@ -1,6 +1,5 @@ *.lst _afailed.s -_fopen.s _hextab.s _scanf.s abort.s diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index a6daff361..94129707b 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -12,7 +12,6 @@ @$(AS) -g -o $@ $(AFLAGS) $< C_OBJS = _afailed.o \ - _fopen.o \ _hextab.o \ _scanf.o \ abort.o \ @@ -56,6 +55,7 @@ C_OBJS = _afailed.o \ S_OBJS = _fdesc.o \ _file.o \ + _fopen.o \ _hadd.o \ _heap.o \ _oserror.o \ diff --git a/libsrc/common/_file.h b/libsrc/common/_file.h index e8ba411a3..f1f9af306 100644 --- a/libsrc/common/_file.h +++ b/libsrc/common/_file.h @@ -34,7 +34,7 @@ extern FILE _filetab [FOPEN_MAX]; -FILE* _fopen (const char* name, const char* mode, FILE* f); +FILE* __fastcall__ _fopen (const char* name, const char* mode, FILE* f); /* Open the specified file and fill the descriptor values into f */ FILE* _fdesc (void); diff --git a/libsrc/common/_fopen.c b/libsrc/common/_fopen.c deleted file mode 100644 index ce6a718ba..000000000 --- a/libsrc/common/_fopen.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * _fopen.c - * - * Ullrich von bassewitz, 17.06.1997 - */ - - - -#include -#include -#include "_file.h" - - - -static unsigned char amode_to_bmode (const char* mode) -/* Convert ASCII mode (like for fopen) to binary mode (for open) */ -{ - unsigned char binmode; - - switch (*mode++) { - case 'w': - binmode = O_WRONLY | O_CREAT | O_TRUNC; - break; - case 'r': - binmode = O_RDONLY; - break; - case 'a': - binmode = O_WRONLY | O_CREAT | O_APPEND; - break; - default: - return 0; /* invalid char */ - } - - while (1) { - switch (*mode++) { - case '+': - /* always to r/w in addition to anything already set */ - binmode |= O_RDWR; - break; - case 'b': - /* currently ignored */ - break; - case '\0': - /* end of mode string reached */ - return binmode; - default: - /* invalid char in mode string */ - return 0; - } - } -} - - - -FILE* _fopen (const char* name, const char* mode, FILE* f) -/* Open the specified file and fill the descriptor values into f */ -{ - int fd; - unsigned char binmode; - - - /* Convert ASCII mode to binary mode */ - if ((binmode = amode_to_bmode (mode)) == 0) { - /* Invalid mode */ - _errno = EINVAL; - return 0; - } - - /* Open the file */ - fd = open (name, binmode); - if (fd == -1) { - /* Error - _oserror is set */ - return 0; - } - - /* Remember fd, mark the file as opened */ - f->f_fd = fd; - f->f_flags = _FOPEN; - - /* Return the file descriptor */ - return f; -} - - - diff --git a/libsrc/common/_fopen.s b/libsrc/common/_fopen.s new file mode 100644 index 000000000..abf67dd21 --- /dev/null +++ b/libsrc/common/_fopen.s @@ -0,0 +1,124 @@ +; +; Ullrich von Bassewitz, 22.11.2002 +; +; FILE* __fastcall__ _fopen (const char* name, const char* mode, FILE* f); +; /* Open the specified file and fill the descriptor values into f */ +; + + .export __fopen + + .import _open + .import pushax, incsp4, return0 + .importzp sp, ptr1 + + + .include "errno.inc" + .include "fcntl.inc" + .include "_file.inc" + + +; ------------------------------------------------------------------------ +; Code + +.proc __fopen + + sta f + stx f+1 ; Save f + +; Get a pointer to the mode string + + ldy #1 + lda (sp),y + sta ptr1+1 + dey + lda (sp),y + sta ptr1 + +; Look at the first character in mode + + ldx #$00 ; Mode will be in X + lda (ptr1),y ; Get first char from mode + cmp #'w' + bne @L1 + ldx #(O_WRONLY | O_CREAT | O_TRUNC) + bne @L3 +@L1: cmp #'r' + bne @L2 + ldx #O_RDONLY + bne @L3 +@L2: cmp #'a' + bne invmode + ldx #(O_WRONLY | O_CREAT | O_APPEND) + +; Look at more chars from the mode string + +@L3: iny ; Next char + beq invmode + lda (ptr1),y + beq modeok ; End of mode string reached + cmp #'+' + bne @L4 + txa + ora #O_RDWR ; Always do r/w in addition to anything else + tax + bne @L3 +@L4: cmp #'b' + beq @L3 ; Binary mode is ignored + +; Invalid mode + +invmode: + lda #EINVAL + sta __errno + lda #0 + sta __errno+1 + tax + jmp incsp4 + +; Mode string successfully parsed. Store the binary mode onto the stack in +; the same place where the mode string pointer was before. The call open() + +modeok: ldy #$00 + txa ; Mode -> A + sta (sp),y + tya + iny + sta (sp),y + ldy #4 ; Size of arguments in bytes + jsr _open ; Will cleanup the stack + +; Check the result of the open() call + + cpx #$FF + bne openok + cmp #$FF + bne openok + jmp return0 ; Failure, errno/_oserror already set + +; Open call succeeded + +openok: ldy f + sty ptr1 + ldy f+1 + sty ptr1+1 + ldy #_FILE_f_fd + sta (ptr1),y ; f->f_fd = fd; + ldy #_FILE_f_flags + lda #_FOPEN + sta (ptr1),y ; f->f_flags = _FOPEN; + +; Return the pointer to the file structure + + lda ptr1 + ldx ptr1+1 + rts + +.endproc + +; ------------------------------------------------------------------------ +; Data + +.bss +f: .res 2 + +