mirror of
https://github.com/cc65/cc65.git
synced 2024-12-24 11:31:31 +00:00
99 lines
2.5 KiB
ArmAsm
99 lines
2.5 KiB
ArmAsm
;
|
|
; int __fastcall__ vfscanf (FILE* f, const char* format, va_list ap);
|
|
;
|
|
; 2004-11-27, Ullrich von Bassewitz
|
|
; 2004-12-21, Greg King
|
|
;
|
|
|
|
.export _vfscanf
|
|
.import _fgetc, _ungetc, _ferror
|
|
|
|
.include "zeropage.inc"
|
|
.include "_scanf.inc"
|
|
.include "stdio.inc"
|
|
|
|
|
|
count := ptr3 ; Result of scan
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
; Static scanfdata structure for the _vfscanf routine
|
|
;
|
|
|
|
.data
|
|
d: .addr _fgetc ; GET
|
|
.addr _ungetc ; UNGET
|
|
.addr 0 ; data
|
|
|
|
|
|
; ----------------------------------------------------------------------------
|
|
; int __fastcall__ vfscanf (FILE* f, const char* format, va_list ap)
|
|
; /* Standard C function */
|
|
; {
|
|
; /* Initialize the data struct. We do only need the given file as user data,
|
|
; * because the (getfunc) and (ungetfunc) functions are crafted so that they
|
|
; * match the standard-I/O fgetc() and ungetc().
|
|
; */
|
|
; static struct scanfdata d = {
|
|
; ( getfunc) fgetc,
|
|
; (ungetfunc) ungetc
|
|
; };
|
|
; static int count;
|
|
;
|
|
; d.data = (void*) f;
|
|
;
|
|
; /* Call the internal function */
|
|
; count = _scanf (&d, format, ap);
|
|
;
|
|
; /* And, return the result */
|
|
; return ferror (f) ? EOF : count;
|
|
; }
|
|
;
|
|
; Because _scanf() has the same parameter stack as vfscanf(), with f replaced
|
|
; by &d, we will do exactly that. _scanf() then will clean up the stack.
|
|
; Beware: Since ap is a fastcall parameter, we must not destroy a/x.
|
|
;
|
|
|
|
.code
|
|
_vfscanf:
|
|
pha ; Save low byte of ap
|
|
|
|
; Swap f against &d on the stack, placing f into d.data
|
|
|
|
ldy #2 ; Offset of f on the stack
|
|
lda (sp),y
|
|
sta d + SCANFDATA::DATA
|
|
lda #<d
|
|
sta (sp),y
|
|
|
|
iny ; High byte
|
|
lda (sp),y
|
|
sta d + SCANFDATA::DATA + 1
|
|
lda #>d
|
|
sta (sp),y
|
|
|
|
; Restore the low byte of ap, and call the _scanf function
|
|
|
|
pla
|
|
jsr __scanf
|
|
sta count
|
|
stx count+1
|
|
|
|
; Return -1 if there was a read error during the scan
|
|
|
|
lda d + SCANFDATA::DATA ; Get f
|
|
ldx d + SCANFDATA::DATA+1
|
|
jsr _ferror
|
|
tay
|
|
beq L1
|
|
lda #<EOF
|
|
tax
|
|
rts
|
|
|
|
; Or, return the result of the scan
|
|
|
|
L1: lda count
|
|
ldx count+1
|
|
rts
|
|
|