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:
parent
501cc4c6c8
commit
18b154e6b1
@ -35,6 +35,5 @@ strtok.s
|
||||
strxfrm.s
|
||||
system.s
|
||||
timezone.s
|
||||
vsscanf.s
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
187
libsrc/common/vsscanf.s
Normal 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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user