Optimization of two string functions (size & speed).
This commit is contained in:
parent
97e64c388c
commit
6afcc370ed
3 changed files with 136 additions and 52 deletions
|
@ -1,5 +1,6 @@
|
|||
;
|
||||
; Ullrich von Bassewitz, 31.05.1998
|
||||
; Christian Krueger: 2013-Jul-24, minor optimization
|
||||
;
|
||||
; char* strcat (char* dest, const char* src);
|
||||
;
|
||||
|
@ -12,44 +13,35 @@ _strcat:
|
|||
sta ptr1 ; Save src
|
||||
stx ptr1+1
|
||||
jsr popax ; Get dest
|
||||
sta ptr2
|
||||
stx ptr2+1
|
||||
sta tmp3 ; Remember for function return
|
||||
ldy #0
|
||||
tay
|
||||
lda #0
|
||||
sta ptr2 ; access from page start, y contains low byte
|
||||
stx ptr2+1
|
||||
|
||||
; find end of dest
|
||||
|
||||
sc1: lda (ptr2),y
|
||||
beq sc2
|
||||
findEndOfDest:
|
||||
lda (ptr2),y
|
||||
beq endOfDestFound
|
||||
iny
|
||||
bne sc1
|
||||
bne findEndOfDest
|
||||
inc ptr2+1
|
||||
bne sc1
|
||||
bne findEndOfDest
|
||||
|
||||
; end found, get offset in y into pointer
|
||||
endOfDestFound:
|
||||
sty ptr2 ; advance pointer to last y position
|
||||
ldy #0 ; reset new y-offset
|
||||
|
||||
sc2: tya
|
||||
clc
|
||||
adc ptr2
|
||||
sta ptr2
|
||||
bcc sc3
|
||||
inc ptr2+1
|
||||
|
||||
; copy src
|
||||
|
||||
sc3: ldy #0
|
||||
sc4: lda (ptr1),y
|
||||
copyByte:
|
||||
lda (ptr1),y
|
||||
sta (ptr2),y
|
||||
beq sc5
|
||||
beq done
|
||||
iny
|
||||
bne sc4
|
||||
bne copyByte
|
||||
inc ptr1+1
|
||||
inc ptr2+1
|
||||
bne sc4
|
||||
bne copyByte ; like bra here
|
||||
|
||||
; done, return pointer to dest
|
||||
|
||||
sc5: lda tmp3 ; X does still contain high byte
|
||||
; return pointer to dest
|
||||
done: lda tmp3 ; X does still contain high byte
|
||||
rts
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
;
|
||||
; Ullrich von Bassewitz, 31.05.1998
|
||||
; Christian Krueger, 2013-Aug-04, minor optimization
|
||||
;
|
||||
; const char* strchr (const char* s, int c);
|
||||
;
|
||||
|
@ -9,40 +10,38 @@
|
|||
.importzp ptr1, tmp1
|
||||
|
||||
_strchr:
|
||||
sta tmp1 ; Save c
|
||||
jsr popax ; get s
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
ldy #0
|
||||
sta tmp1 ; Save c
|
||||
jsr popax ; get s
|
||||
tay ; low byte of pointer to y
|
||||
stx ptr1+1
|
||||
lda #0
|
||||
sta ptr1 ; ptr access page wise
|
||||
|
||||
Loop: lda (ptr1),y ; Get next char
|
||||
beq EOS ; Jump on end of string
|
||||
cmp tmp1 ; Found?
|
||||
beq Found ; Jump if yes
|
||||
Loop: lda (ptr1),y ; Get next char
|
||||
beq EOS ; Jump on end of string
|
||||
cmp tmp1 ; Found?
|
||||
beq Found ; Jump if yes
|
||||
iny
|
||||
bne Loop
|
||||
inc ptr1+1
|
||||
bne Loop ; Branch always
|
||||
bne Loop
|
||||
inc ptr1+1
|
||||
bne Loop ; Branch always
|
||||
|
||||
; End of string. Check if we're searching for the terminating zero
|
||||
|
||||
EOS: lda tmp1 ; Get the char we're searching for
|
||||
bne NotFound ; Jump if not searching for terminator
|
||||
EOS:
|
||||
lda tmp1 ; Get the char we're searching for
|
||||
bne NotFound ; Jump if not searching for terminator
|
||||
|
||||
; Found. Calculate pointer to c.
|
||||
; Found. Set pointer to c.
|
||||
|
||||
Found: ldx ptr1+1 ; Load high byte of pointer
|
||||
tya ; Low byte offset
|
||||
clc
|
||||
adc ptr1
|
||||
bcc Found1
|
||||
inx
|
||||
Found1: rts
|
||||
Found:
|
||||
ldx ptr1+1 ; Load high byte of pointer
|
||||
tya ; low byte is in y
|
||||
rts
|
||||
|
||||
; Not found, return NULL
|
||||
|
||||
NotFound:
|
||||
lda #0
|
||||
lda #0
|
||||
tax
|
||||
rts
|
||||
|
||||
|
|
93
testcode/lib/strcat-test.c
Normal file
93
testcode/lib/strcat-test.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SourceStringSize 257 // test correct page passing (>256)
|
||||
|
||||
static char SourceString[SourceStringSize+1]; // +1 room for terminating null
|
||||
static char DestinationString[2*SourceStringSize+1]; // will contain two times the source buffer
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned i,j;
|
||||
char* p;
|
||||
|
||||
/* Print a header */
|
||||
printf ("strcat(): ");
|
||||
|
||||
for (i=0; i < SourceStringSize; ++i)
|
||||
SourceString[i] = (i%128)+1;
|
||||
|
||||
SourceString[i] = 0;
|
||||
|
||||
if (strlen(SourceString) != SourceStringSize)
|
||||
{
|
||||
printf ("Fail: Source string initialization or 'strlen()' problem!\n");
|
||||
printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(SourceString));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Ensure empty destination string */
|
||||
DestinationString[0] = 0;
|
||||
|
||||
if (strlen(DestinationString) != 0)
|
||||
{
|
||||
printf ("Fail: Destination string initialization or 'strlen()' problem!\n");
|
||||
printf ("Expected length: %u but is %u!\n", 0, strlen(DestinationString));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Test concatenation to empty buffer */
|
||||
|
||||
p = strcat(DestinationString, SourceString);
|
||||
|
||||
if (strlen(DestinationString) != SourceStringSize)
|
||||
{
|
||||
printf ("Fail: String concatenation to empty buffer!\n");
|
||||
printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(DestinationString));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Test concatenation to non empty buffer */
|
||||
|
||||
p = strcat(DestinationString, SourceString);
|
||||
|
||||
if (strlen(DestinationString) != 2*SourceStringSize)
|
||||
{
|
||||
printf ("Fail: String concatenation to non-empty buffer!\n");
|
||||
printf ("Expected length: %u but is %u!\n", 2*SourceStringSize, strlen(DestinationString));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Test return value */
|
||||
|
||||
if (p != DestinationString)
|
||||
{
|
||||
printf ("Invalid return value!\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Test contents */
|
||||
|
||||
for(j=0; j <2; ++j)
|
||||
for(i=0; i < SourceStringSize; ++i)
|
||||
{
|
||||
unsigned position = j*SourceStringSize+i;
|
||||
unsigned current = DestinationString[position];
|
||||
unsigned expected = (i%128)+1;
|
||||
if (current != expected)
|
||||
{
|
||||
printf ("Fail: Unexpected destination buffer contents at position %u!\n", position);
|
||||
printf ("Expected %u, but is %u!\n", expected, current);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test passed */
|
||||
printf ("Passed\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue