cc65/libsrc/common/scanf.s

75 lines
1.8 KiB
ArmAsm

;
; int scanf(const char* Format, ...);
;
; 2000-12-01, Ullrich von Bassewitz
; 2004-12-31, Greg King
;
.export _scanf
.import _stdin, pushax, addysp, _vfscanf
.import sp:zp, ptr1:zp
.macpack generic
; ----------------------------------------------------------------------------
; Code
;
_scanf:
sty ArgSize ; Number of argument bytes passed in .Y
; We are using a (hopefully) clever trick here to reduce code size. On entry,
; the stack pointer points to the last pushed argument of the variable
; argument list. Adding the number of argument bytes, would result in a
; pointer that points _above_ the Format argument.
; Because we have to push stdin anyway, we will do that here, so:
;
; * we will save the subtraction of 2 (__fixargs__) later;
; * we will have the address of the Format argument which needs to
; be pushed next.
lda _stdin
ldx _stdin+1
jsr pushax
; Now, calculate the va_list pointer, which does point to Format.
lda sp
ldx sp+1
add ArgSize
bcc @L1
inx
@L1: sta ptr1
stx ptr1+1
; Push a copy of Format.
ldy #1
lda (ptr1),y
tax
dey
lda (ptr1),y
jsr pushax
; Load va_list [last and __fastcall__ argument to vfscanf()].
lda ptr1
ldx ptr1+1
; Call vfscanf().
jsr _vfscanf
; Clean up the stack. We will return what we got from vfscanf().
ldy ArgSize
jmp addysp
; ----------------------------------------------------------------------------
; Data
;
.bss
ArgSize:
.res 1 ; Number of argument bytes