mirror of
https://github.com/cc65/cc65.git
synced 2024-12-23 04:30:10 +00:00
75 lines
1.8 KiB
ArmAsm
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
|
|
|