/*
 * string.S86  -  string handling routines for netboot boot images
 *
 * Copyright (C) 2002-2007 Gero Kuhlmann   <gero@gkminix.han.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: string.S86,v 1.5 2007/01/06 18:30:51 gkminix Exp $
 *
 *====================================================================
 *
 * These routines are only intended to be called by assembler code. The
 * string manipulation routines for C source code is defined in another
 * file.
 */


#include <common.i86>

.file __FILE__
.line __LINE__



/*
 *====================================================================
 *
 * Start the text segment and define all public entry points
 */

	.text

	.global	strstr
	.global	strlen



/*
 *====================================================================
 *
 * Find a substring in a string.
 * Input:  DS:SI -  Pointer to substring
 *         ES:DI -  Pointer to string
 * Output: ES:DI -  Pointer to substring within string
 *         CX    -  Zero if substring not found, otherwise unchanged
 * Changed registers: AX, CX, DI, ES
 */
strstr:	push	bx
	push	dx
	call	strlen			# DX contains length of substring
	mov	dx,cx			# ES:BX points to string
	mov	bx,di			# DS:SI points to substring

	cld
1:	mov	al,es:[bx]
	or	al,al			# if at end of string we could not find
	jz	2f			# the substring
	mov	di,bx
	mov	cx,dx			# reset substring
	mov	ax,si			# compare substring at current string
	repe	cmpsb			# position
	mov	si,ax
	jz	3f			# found it!
	inc	bx			# compare substring at next char
	jmp	1b

2:	xor	dx,dx			# could not find string
3:	mov	cx,dx			# set return values
	mov	di,bx
	pop	dx
	pop	bx
	ret



/*
 *====================================================================
 *
 * Determine the length of a zero-terminated string.
 * Input:  DS:SI -  Pointer to string
 * Output: CX    -  Length of string
 * Changed registers: AL, CX
 */
strlen: push	si
	xor	cx,cx
	cld
1:	lodsb
	or	al,al
	jz	3f
	cmp	al,0x20			# character should be printable
	jl	2f
	cmp	al,0x7E
	ja	2f
	inc	cx			# count character
	jmp	1b
2:	xor	cx,cx			# return 0 length if string invalid
3:	pop	si
	ret




/*
 *====================================================================
 */
	.end

