Added a speed optimization. Makes the code somewhat larger, but is a huge

improvement speedwise.


git-svn-id: svn://svn.cc65.org/cc65/trunk@567 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2000-12-08 11:37:01 +00:00
parent a6682eaeec
commit adabe02bbd

View file

@ -6,12 +6,11 @@
.export __printf .export __printf
.import popax, pushax, pusheax, push1, axlong, axulong .import popax, pushax, pusheax, decsp6, push1, axlong, axulong
.import __ctype .import __ctype
.import _ltoa, _ultoa .import _ltoa, _ultoa
.import _strlower, _strlen .import _strlower, _strlen
.import jmpvec .importzp sp, ptr1, ptr2, tmp1, regbank, sreg
.importzp sp, ptr1, tmp1, regbank, sreg
.macpack generic .macpack generic
@ -21,13 +20,14 @@
ArgList = regbank+0 ; Argument list pointer ArgList = regbank+0 ; Argument list pointer
Format = regbank+2 ; Format string Format = regbank+2 ; Format string
OutData = regbank+4 ; Function parameters OutData = regbank+4 ; Function parameters
; ---------------------------------------------------------------------------- ; ----------------------------------------------------------------------------
; Other zero page cells ; Other zero page cells
Base = ptr1 Base = ptr1
FSave = ptr1
FCount = ptr2
.code .code
@ -59,7 +59,8 @@ Output1:
lda #<CharArg lda #<CharArg
ldx #>CharArg ldx #>CharArg
jsr pushax jsr pushax
jsr push1 jsr push1
CallOutFunc:
jmp (OutFunc) ; fout (OutData, &CharArg, 1) jmp (OutFunc) ; fout (OutData, &CharArg, 1)
; ---------------------------------------------------------------------------- ; ----------------------------------------------------------------------------
@ -145,7 +146,7 @@ ReadInt:
adc ptr1+1 adc ptr1+1
sta ptr1+1 ; * 5 sta ptr1+1 ; * 5
asl ptr1 asl ptr1
rol ptr1+1 ; * 10, assume carry clear rol ptr1+1 ; * 10, assume carry clear
pla pla
adc ptr1 ; Add digit value adc ptr1 ; Add digit value
sta ptr1 sta ptr1
@ -231,7 +232,7 @@ ultoa: sty Base ; Save base
jsr pusheax ; Push value jsr pusheax ; Push value
jsr PushBufPtr ; Push the buffer pointer... jsr PushBufPtr ; Push the buffer pointer...
lda Base ; Restore base lda Base ; Restore base
jmp _ultoa ; ultoa (l, s, base); jmp _ultoa ; ultoa (l, s, base);
; ---------------------------------------------------------------------------- ; ----------------------------------------------------------------------------
@ -274,7 +275,7 @@ Save: lda regbank,y
iny iny
lda (OutData),y lda (OutData),y
sta OutFunc sta OutFunc
iny iny
lda (OutData),y lda (OutData),y
sta OutFunc+1 sta OutFunc+1
@ -282,16 +283,77 @@ Save: lda regbank,y
; Start parsing the format string ; Start parsing the format string
MainLoop: MainLoop:
jsr GetFormatChar ; Get one char, zero in Y lda Format ; Remember current format pointer
tax ; End of format string reached? sta FSave
bne NotDone ; Continue of end not reached lda Format+1
sta FSave+1
ldy #0 ; Index
@L1: lda (Format),y ; Get next char
beq @L2 ; Jump on end of string
cmp #'%' ; Format spec?
beq @L2
iny ; Bump pointer
bne @L1
inc Format+1 ; Bump high byte of pointer
bne @L1 ; Branch always
; Found a '%' character or end of string. Update the Format pointer so it is
; current (points to this character).
@L2: tya ; Low byte of offset
add Format
sta Format
bcc @L3
inc Format+1
; Calculate, how many characters must be output. Beware: This number may
; be zero. A still contains the low byte of the pointer.
@L3: sub FSave
sta FCount
lda Format+1
sbc FSave+1
sta FCount+1
ora FCount ; Is the result zero?
beq @L4 ; Jump if yes
; Output the characters that we have until now. To make the call to out
; faster, build the stack frame by hand (don't use pushax)
jsr decsp6 ; 3 args
ldy #5
lda OutData+1
sta (sp),y
dey
lda OutData
sta (sp),y
dey
lda FSave+1
sta (sp),y
dey
lda FSave
sta (sp),y
dey
lda FCount+1
sta (sp),y
dey
lda FCount
sta (sp),y
jsr CallOutFunc ; Call the output function
; We're back from out(), or we didn't call it. Check for end of string.
@L4: jsr GetFormatChar ; Get one char, zero in Y
tax ; End of format string reached?
bne NotDone ; End not reached
; End of format string reached. Restore the zeropage registers and return. ; End of format string reached. Restore the zeropage registers and return.
ldx #5 ldx #5
Rest: lda RegSave,x Rest: lda RegSave,x
sta regbank,x sta regbank,x
dex dex
bpl Rest bpl Rest
rts rts
@ -301,12 +363,12 @@ Rest: lda RegSave,x
NotDone: NotDone:
cmp #'%' cmp #'%'
bne @L1 bne @L1
lda (Format),y ; Check for "%%" lda (Format),y ; Check for "%%"
cmp #'%' cmp #'%'
bne FormatSpec ; Jump if really a format specifier bne FormatSpec ; Jump if really a format specifier
jsr IncFormatPtr ; Skip the second '%' jsr IncFormatPtr ; Skip the second '%'
@L1: jsr Output1 ; Output the character... @L1: jsr Output1 ; Output the character...
jmp MainLoop ; ...and continue jmp MainLoop ; ...and continue
; We have a real format specifier ; We have a real format specifier
; Format is: %[flags][width][.precision][mod]type ; Format is: %[flags][width][.precision][mod]type