;; Implementation of some string functions in ;; assembler. ;; Why - because I want a better dhrystone score :) ;; strcpy is disabled as the C version is almost as good. ;; Just the setup and return is slower. .if 0 ; char *strcpy(char *dest, const char *source) _strcpy:: ;; Fall through to the correct type __strcpy_rrf_s:: ld a,#5 rst 0x08 __strcpy_rrx_s:: ld hl,#2 add hl,sp ld e,(hl) inc hl ld d,(hl) inc hl ld c,(hl) inc hl ld b,(hl) ;; Setup the return value ld l,c ld h,b 1$: ld a,(bc) ld (de),a or a jp NZ,1$ ret ;; Notes on strcpy styles: ;; *de = *hl; hl++; de++; or a; ret z; jp - slower as jp is ;; same cost as conditional jump, so condition on ret is more expensive. ;; *de = *bc; bc++; de++; or a, jp nz - OK ;; Can't use LDI as need to check for end of string. ;; Above also matches the z88dk version. .endif ; void *memcpy(void *dest, const void *source, int count) _memcpy:: ;; Fall through to correct type __memcpy_rrf_s:: ld a,#5 rst 0x08 __memcpy_rrx_s:: ;; Using LDIR ;; LDIR: do; *DE = *HL; HL++; BC--; while BC != 0 ;; All registers are already saved. pop iy ; iy = return address pop de ; de = destination pointer pop hl ; hl = source pointer pop bc ; bc = count push bc push hl push de ld a,b or c jr Z,1$ ldir 1$: pop hl ; return hl = original destination pointer push hl jp (iy) ret ; int strcmp(const char *s1, const char *s2) _strcmp:: ;; Fall through to the correct style ;; Fall through to correct type __strcmp_rrf_s:: ld a,#5 rst 0x08 __strcmp_rrx_s:: ld hl,#2 add hl,sp ld e,(hl) inc hl ld d,(hl) inc hl ld a,(hl) inc hl ld h,(hl) ld l,a 1$: ld a,(de) sub (hl) ;; Normally not taken, so use a jr (12/7) instead of jp (10) jr NZ,2$ ;; A == 0 cp (hl) inc de inc hl ;; Normally taken. Flag from the cp above. jp nz,1$ 2$: ;; Sign extend ld l,a rla sbc a ld h,a ret