/*
 **************************************************************************
 *
 * Network driver interface for netboot bootrom
 *
 * Module:  timer.S86
 * Purpose: Timer access routines
 * Entries: wait10ms
 *
 **************************************************************************
 *
 * Copyright (C) 2003-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: timer.S86,v 1.5 2007/01/06 18:30:48 gkminix Exp $
 *
 */


/*
 **************************************************************************
 *
 * Load assembler macros and other include files.
 *
 */
#include <common.i86>
#include <romconfig.i86>

.file __FILE__
.line __LINE__



/*
 **************************************************************************
 *
 * Definitions to access the PC hardware timer
 *
 */
#define	TIMER_0		0x40		/* Timer 0 port number */
#define	TIMER_MODE	0x43		/* Timer mode port number */

#define	TIMER_TICKS	0x5D3A		/* Number of timer counts for 10 ms */




.line __LINE__
/*
 **************************************************************************
 *
 * Start code segment.
 *
 */
	.text

	.global	wait10ms



/*
 **************************************************************************
 *
 * Wait a number of 10 millisecond intervals
 * Input:  BX     -  Number of intervals to wait
 * Output: None
 * Registers changed: AX, BX
 *
 */
wait10ms:

	pushf
	push	cx

1:	cli
	xor	al,al
	out	TIMER_MODE,al		# write timer 0 count mode
	jcxz	2f			# wait a little bit to avoid a bug
2:	jcxz	3f			# in certain Neptune chipsets
3:	in	al,TIMER_0		# read timer LSB
	mov	cl,al
	in	al,TIMER_0		# read timer MSB
	mov	ch,al
	sti

4:	cli
	xor	al,al
	out	TIMER_MODE,al		# write timer 0 count mode
	jcxz	5f
5:	jcxz	6f
6:	in	al,TIMER_0		# read timer LSB
	mov	ah,al
	in	al,TIMER_0		# read timer MSB
	xchg	ah,al
	sti

	neg	ax
	add	ax,cx			# check if timeout value reached
	cmp	ax,TIMER_TICKS
	jb	4b			# no, read timer again
	dec	bx
	jnz	1b			# check if number of loops reached
	pop	cx
	popf
	ret




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

