1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 04:30:10 +00:00

Replaced vsscanf by an assembler version

git-svn-id: svn://svn.cc65.org/cc65/trunk@3315 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2004-11-28 18:45:13 +00:00
parent 501cc4c6c8
commit 18b154e6b1
4 changed files with 189 additions and 84 deletions

View File

@ -35,6 +35,5 @@ strtok.s
strxfrm.s
system.s
timezone.s
vsscanf.s

View File

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

View File

@ -1,81 +0,0 @@
/*
* vsscanf.c
*
* (C) Copyright 2002 Ullrich von Bassewitz (uz@cc65.org)
*
*/
#include <stdio.h>
#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);
}

187
libsrc/common/vsscanf.s Normal file
View File

@ -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
iny
lda (sp),y
sta sd + SSCANFDATA::STR+1
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