	;; 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

