Add long long support for printf d/i/u conversions.

At this point, the long long support for the printf and scanf families of functions is complete.
This commit is contained in:
Stephen Heumann 2021-02-10 17:51:23 -06:00
parent 4f9b41938a
commit c185face85
2 changed files with 178 additions and 9 deletions

View File

@ -3772,8 +3772,32 @@ argp equ 7 argument pointer
;
; For signed numbers, if the value is negative, use the sign flag
;
lda ~isLong handle long values
lda ~isLongLong handle long long values
beq sn0
ldy #6
lda [argp],Y
bpl cn0
sec
lda #0
sbc [argp]
sta [argp]
ldy #2
lda #0
sbc [argp],Y
sta [argp],Y
iny
iny
lda #0
sbc [argp],Y
sta [argp],Y
iny
iny
lda #0
sbc [argp],Y
sta [argp],Y
bra sn2
sn0 lda ~isLong handle long values
beq sn0a
ldy #2
lda [argp],Y
bpl cn0
@ -3785,7 +3809,7 @@ argp equ 7 argument pointer
sbc [argp],Y
sta [argp],Y
bra sn2
sn0 lda ~isByte handle (originally) byte-size values
sn0a lda ~isByte handle (originally) byte-size values
beq sn1
lda [argp]
and #$00FF
@ -3807,7 +3831,16 @@ sn2 lda #'-'
; Convert the number to an ASCII string
;
cn0 stz ~hexPrefix don't lead with 0x
lda ~isLong if the value is long then
lda ~isLongLong if the value is long long then
beq cn0a
ldy #6 push a long long value
lda [argp],Y
pha
dey
dey
lda [argp],Y
pha
cn0a lda ~isLong else if the value is long then
beq cn1
ldy #2 push a long value
lda [argp],Y
@ -3825,7 +3858,9 @@ cn2 ph4 #~str push the string addr
ph2 #0 do an unsigned conversion
lda ~isLongLong do the proper conversion
beq cn2a
; TODO actually format 64-bit numbers
pla
jsr ~ULongLong2Dec
bra pd1
cn2a lda ~isLong
beq cn3
_Long2Dec
@ -3967,6 +4002,54 @@ rn3 inc argp
brl ~LeftJustify handle left justification
end
****************************************************************
*
* ~ULongLong2Dec - produce a string from an unsigned long long
*
* Inputs:
* llValue - the unsigned long long value
* strPtr - pointer to string buffer
* strLength - length of string buffer
*
****************************************************************
*
~ULongLong2Dec private
lsub (8:llValue,4:strPtr,2:strLength),0
dec strLength
lb1 ph8 llValue divide by 10
ph8 #10
jsl ~UDIV8
pl8 llValue
pla get the last digit
plx
plx
plx
ora #$30 compute ASCII value for digit
short M store ASCII value
ldy strLength
sta [strPtr],y
long M
dec strLength
bmi ret
lda llValue loop if remaining value is not 0
ora llValue+2
ora llValue+4
ora llValue+6
bne lb1
short M pad with spaces
ldy strLength
lda #' '
lb2 sta [strPtr],y
dey
bpl lb2
long M
ret lret
end
****************************************************************
*
* ~Format_n - return the number of characters printed

View File

@ -858,12 +858,98 @@
mnote "Missing closing '}'",16
mend
macro
&l jlt &bp
&l bge *+5
brl &bp
mend
macro
&l jpl &bp
&l bmi *+5
brl &bp
mend
macro
&l lret &r
&l anop
lclc &len
aif c:&r,.a
lclc &r
&r setc 0
&len setc 0
ago .h
.a
&len amid &r,2,1
aif "&len"=":",.b
&len amid &r,1,2
&r amid &r,4,l:&r-3
ago .c
.b
&len amid &r,1,1
&r amid &r,3,l:&r-2
.c
aif &len<>2,.d
ldy &r
ago .h
.d
aif &len<>4,.e
ldx &r+2
ldy &r
ago .h
.e
aif &len<>10,.g
ldy #&r
ldx #^&r
ago .h
.g
mnote 'Not a valid return length',16
mexit
.h
aif &totallen=0,.i
lda &worklen+1
sta &worklen+&totallen+1
.i
pld
tsc
clc
adc #&worklen+&totallen
tcs
aif &len=0,.j
tya
.j
rts
mend
macro
&l lsub &parms,&work
&l anop
aif c:&work,.a
lclc &work
&work setc 0
.a
gbla &totallen
gbla &worklen
&worklen seta &work
&totallen seta 0
aif c:&parms=0,.e
lclc &len
lclc &p
lcla &i
&i seta c:&parms
.b
&p setc &parms(&i)
&len amid &p,2,1
aif "&len"=":",.c
&len amid &p,1,2
&p amid &p,4,l:&p-3
ago .d
.c
&len amid &p,1,1
&p amid &p,3,l:&p-2
.d
&p equ &totallen+3+&work
&totallen seta &totallen+&len
&i seta &i-1
aif &i,^b
.e
tsc
aif &work=0,.f
sec
sbc #&work
tcs
.f
phd
tcd
mend