From 18b154e6b1ed76a12f4c5463b73e6956992d3a9e Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 28 Nov 2004 18:45:13 +0000 Subject: [PATCH] Replaced vsscanf by an assembler version git-svn-id: svn://svn.cc65.org/cc65/trunk@3315 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- libsrc/common/.cvsignore | 1 - libsrc/common/Makefile | 4 +- libsrc/common/vsscanf.c | 81 ----------------- libsrc/common/vsscanf.s | 187 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 84 deletions(-) delete mode 100644 libsrc/common/vsscanf.c create mode 100644 libsrc/common/vsscanf.s diff --git a/libsrc/common/.cvsignore b/libsrc/common/.cvsignore index 79e0c359a..b91764795 100644 --- a/libsrc/common/.cvsignore +++ b/libsrc/common/.cvsignore @@ -35,6 +35,5 @@ strtok.s strxfrm.s system.s timezone.s -vsscanf.s diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index 3dcc7ccf8..7a6eeb1b5 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -64,8 +64,7 @@ C_OBJS = _afailed.o \ strxfrm.o \ strtok.o \ system.o \ - timezone.o \ - vsscanf.o + timezone.o S_OBJS = _cwd.o \ @@ -171,6 +170,7 @@ S_OBJS = _cwd.o \ vprintf.o \ vscanf.o \ vsprintf.o \ + vsscanf.o \ zerobss.o diff --git a/libsrc/common/vsscanf.c b/libsrc/common/vsscanf.c deleted file mode 100644 index 68d748c2f..000000000 --- a/libsrc/common/vsscanf.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * vsscanf.c - * - * (C) Copyright 2002 Ullrich von Bassewitz (uz@cc65.org) - * - */ - - - -#include -#include "_scanf.h" - - - -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -struct sscanfdata { - const char* str; /* Pointer to input string */ - unsigned index; /* Read index */ -}; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static int __fastcall__ get (struct sscanfdata* d) -/* Read a character from the input string and return it */ -{ - char C; - if (C = d->str[d->index]) { - /* Increment index only if end not reached */ - ++d->index; - return C; - } else { - return EOF; - } -} - - - -static int __fastcall__ unget (int c, struct sscanfdata* d) -/* Push back a character onto the input stream */ -{ - /* We do assume here that the _scanf routine will not push back anything - * not read, so we can ignore c safely and won't check the index. - */ - --d->index; - return c; -} - - - -int __fastcall__ vsscanf (const char* str, const char* format, va_list ap) -/* Standard C function */ -{ - struct sscanfdata sd; - struct scanfdata d; - - /* Initialize the data structs. The sscanfdata struct will be passed back - * to the get and unget functions by _scanf. - */ - d.get = (getfunc) get; - d.unget = (ungetfunc) unget, - d.data = &sd; - sd.str = str; - sd.index = 0; - - /* Call the internal function and return the result */ - return _scanf (&d, format, ap); -} - - - diff --git a/libsrc/common/vsscanf.s b/libsrc/common/vsscanf.s new file mode 100644 index 000000000..b8c82bef7 --- /dev/null +++ b/libsrc/common/vsscanf.s @@ -0,0 +1,187 @@ +; +; int __fastcall__ vsscanf (const char* str, const char* format, va_list ap); +; /* Standard C function */ +; +; Ullrich von Bassewitz, 2004-11-28 +; + + .export _vsscanf + .import popax, __scanf + .importzp sp, ptr1, ptr2 + + .macpack generic + + +; ---------------------------------------------------------------------------- +; Structure used to pass data to the callback functions + +.struct SSCANFDATA + STR .addr + INDEX .word +.endstruct + + +; ---------------------------------------------------------------------------- +; static int __fastcall__ get (struct sscanfdata* d) +; /* Read a character from the input string and return it */ +; { +; char C; +; if (C = d->str[d->index]) { +; /* Increment index only if end not reached */ +; ++d->index; +; return C; +; } else { +; return EOF; +; } +; } +; + +.code +.proc get + + sta ptr1 + stx ptr1+1 ; Save d + +; Get d->str adding the high byte of index to the pointer, so we can access +; the byte in the string with just the low byte as index + + ldy #SSCANFDATA::STR + lda (ptr1),y + sta ptr2 + iny + lda (ptr1),y + ldy #SSCANFDATA::INDEX+1 + add (ptr1),y + sta ptr2+1 + +; Load the low byte of the index and fetch the byte from the string + + dey ; = SSCANFDATA::INDEX + lda (ptr1),y + tay + lda (ptr2),y + +; Return EOF if we are at the end of the string + + bne L1 + lda #$FF + tax + rts + +; Bump the index (beware: A contains the char we must return) + +L1: tax ; Save return value + tya ; Low byte of index + ldy #SSCANFDATA::INDEX + add #1 + sta (ptr1),y + iny + lda (ptr1),y + adc #$00 + sta (ptr1),y + +; Return the char just read + + txa + ldx #$00 + rts + +.endproc + +; ---------------------------------------------------------------------------- +; static int __fastcall__ unget (int c, struct sscanfdata* d) +; /* Push back a character onto the input stream */ +; { +; /* We do assume here that the _scanf routine will not push back anything +; * not read, so we can ignore c safely and won't check the index. +; */ +; --d->index; +; return c; +; } +; + +.code +.proc unget + + sta ptr1 + stx ptr1+1 ; Save d + +; Decrement the index + + ldy #SSCANFDATA::INDEX + lda (ptr1),y + sub #1 + sta (ptr1),y + iny + lda (ptr1),y + sbc #0 + sta (ptr1),y + +; Return c + + jmp popax + +.endproc + +; ---------------------------------------------------------------------------- +; int __fastcall__ vsscanf (const char* str, const char* format, va_list ap) +; /* Standard C function */ +; { +; struct sscanfdata sd; +; struct scanfdata d; +; +; /* Initialize the data structs. The sscanfdata struct will be passed back +; * to the get and unget functions by _scanf. +; */ +; d.get = (getfunc) get; +; d.unget = (ungetfunc) unget, +; d.data = &sd; +; sd.str = str; +; sd.index = 0; +; +; /* Call the internal function and return the result */ +; return _scanf (&d, format, ap); +; } +; + +.data + +sd: .tag SSCANFDATA + +d: .addr get + .addr unget + .addr sd + +.code +.proc _vsscanf + +; Save the low byte of ap (which is passed in a/x) + + pha + +; Initialize sd and at the same time replace str on the stack by a pointer +; to d + + ldy #2 ; Stack offset of str + lda (sp),y + sta sd + SSCANFDATA::STR + lda #d + sta (sp),y + + lda #$00 + sta sd + SSCANFDATA::INDEX + sta sd + SSCANFDATA::INDEX+1 + +; Restore the low byte of ap and jump to _scanf which will cleanup the stacl + + pla + jmp __scanf + +.endproc + + -- 2.39.5