/*
 * Copyright (C) 1993, 1994 by
 * Digital Equipment Corporation, Maynard, Massachusetts.
 * All rights reserved.
 *
 * This software is furnished under a license and may be used and copied
 * only  in  accordance  of  the  terms  of  such  license  and with the
 * inclusion of the above copyright notice. This software or  any  other
 * copies thereof may not be provided or otherwise made available to any
 * other person.  No title to and  ownership of the  software is  hereby
 * transferred.
 *
 * The information in this software is  subject to change without notice
 * and  should  not  be  construed  as a commitment by Digital Equipment
 * Corporation.
 *
 * Digital assumes no responsibility for the use  or  reliability of its
 * software on equipment which is not supplied by Digital.
 *
 */


/*#include "kxalpha.h"*/
#include "alpha-regdef.h"

#define LEAF_ENTRY(NAME) .text ; .align 4 ; .globl NAME ; .ent NAME, 0 ; NAME: ; .frame sp, 0, ra ; .prologue 0 ;


#define PICIACKADR	0xfffffc0100000000
#define EISABAD		0xfffffc0200000000
#define EISABIO		0xfffffc0300000000
#define EISA_SHIFT	7
#define EISA_BYTE_ADJ	0x80
#define EISA_WORD_ADJ	0x100
#define EISA_LONG_ADJ	0x200
#define HALF_USEC	75
#define ONE_USEC	150


LEAF_ENTRY(flush_i_cache)
	call_pal 0x86			// IMB
	ret	zero, (ra)		// return
	.end	outportb

//++
//
// VOID
// { outportX
//     ULONG port
//     ULONG data
//    )
// X variants are:
//
// 	b - byte    	8 bits
//	w - word       16 bits
//      t - tri-byte   24 bits
//      l - long       32 bits
//
// 
// Routine Description:
//
//     This function uses the 64-bit super-page to write data to a port
//     of the EISA bus for JENSEN. Only AT (ISA) cycles are supported.
//
// Arguments:
//
//    port (a0) - port address on the EISA  to which to write data
//    data (a1) - data to write to the port.
//              
//
// Return Value:
//
//    None.
//
//--


//+
// 	outportb
//--
	LEAF_ENTRY(outportb)
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and 	a0,3,t0			// get byte index from address
	insbl	a1,t0,t5		// put byte in proper position
	and	a0,0x1ffffff,t1		// 25 bit mask
	ldiq	t0,EISABIO		// get EISA IO base address
	sll	t1, 7, a0		// shift 7 for EISA 
	bis	t0,a0,t0		// t0 = address of EISA 
	stl	t5, 0(t0)		// write data to port
	mb				// guarantee write ordering
	ret	zero, (ra)		// return
	.end	outportb


//+
// 	outportw
//--
	LEAF_ENTRY(outportw)
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and 	a0,3,t0			// get byte index from address
	inswl	a1,t0,t5		// put byte in proper position
	and	a0,0x1ffffff,t1		// 25 bit mask
	ldiq	t0,EISABIO		// get EISA IO base address
	or	t0,0x20,t0		// t0 = ffff fc03 0000 0020 - word
	sll	t1, 7, a0		// shift 7 for EISA 
	bis	t0,a0,t0		// t0 = address of EISA 
	stl	t5, 0(t0)		// write data to port
	mb				// guarantee write ordering
	ret	zero, (ra)		// return
	.end	outportw


//+
// 	outportl
//--
	LEAF_ENTRY(outportl)
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and	a0,0x1ffffff,t1		// 25 bit mask
	ldiq	t0,EISABIO		// get EISA IO base address
	or	t0,0x60,t0		// t0 = ffff fc03 0000 0060 - long
	sll	t1, 7, a0		// shift 7 for EISA 
	bis	t0,a0,t0		// t0 = address of EISA 
	stl	a1, 0(t0)		// write data to port
	mb				// guarantee write ordering
	ret	zero, (ra)		// return
	.end	outportl



//+
// 	vgastl
//--
	LEAF_ENTRY(vgastl)
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	sra	a0, 3, t0		// right shift addr by 3
	and	t0, 3, t1		// and addr with 3	
	s8addq  t1, zero, t2		// multiply by 8
	sll 	a1, t2, t3		// left shift data
	sll	a0, 4, t4		// left shift addr by 4
	lda	t0,0xfc00		// t0 = 0000 0000 0000 0c00
	ldah	t0,-1(t0)		// t0 = ffff ffff ffff 0c00
	sll	t0,32,t0		// t0 = ffff fc00 0000 0000
	or 	t0,t4,t4                // make io address
	stl	t3, 0(t4)		// store data
	mb				// guarantee write ordering
	ret	zero, (ra)		// return
	.end	vgastl




//++
//
// ULONG
// inportX(
//     ULONG port
//    )
//
// X variants are:
//
// 	b - byte    	8 bits
//	w - word       16 bits
//      t - tri-byte   24 bits
//      l - long       32 bits
//
// Routine Description:
//
//     This function uses the 64-bit super-page to read data from an EISA
//     port for JENSEN.
//
// Arguments:
//
//    port (a0) - EISA port number.
//
// Return Value:
//
//    data (v0) - the data read and  only the low byte is valid
//
//--

//+
// 	inportb
//--
	LEAF_ENTRY(inportb)

	//
	// generate super-page address of EISA, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and	a0,0x1ffffff,t1		// 25 bit mask
	ldiq	t0,EISABIO		// get EISA IO base address
	sll	t1, 7, t2		// shift 7 for EISA 
	bis	t0,t2,t0		// t0 = address of EISA 
	ldl	v0, 0(t0)		// get EISA IO byte
	and 	a0,0x3,t1		// setup word shift count
	extbl	v0,t1,v0		// put into low byte
  	ret	zero, (ra)		// return 
	.end	inportb


//+
// 	inportw
//--
	LEAF_ENTRY(inportw)
	//
	// generate super-page address of vti, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and	a0,0x1ffffff,t1		// 25 bit mask
	ldiq	t0,EISABIO		// get EISA IO base addr
	or	t0,0x20,t0		// t0 = ffff fc03 0000 0020 - word
	sll	t1, 7, t2		// shift 7 for EISA 
	bis	t0,t2,t0		// t0 = address of EISA 
	ldl	v0, 0(t0)		// load EISA word
	and 	a0,0x3,t1		// setup shift count
	extwl 	v0,t1,v0		// put into low word
	ret	zero, (ra)		// return 
	.end	inportw



//+
// 	inportl
//--
	LEAF_ENTRY(inportl)
	//
	// generate super-page address of vti, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and	a0,0x1ffffff,t1		// 25 bit mask
	ldiq	t0,EISABIO		// get EISA IO base address
	or	t0,0x60,t0		// t0 = ffff fc03 0000 0060
	sll	t1, 7, t2		// shift 7 for EISA 
	bis	t0,t2,t0		// t0 = address of EISA 
	ldl	v0, 0(t0)		// load EISA word
	ret	zero, (ra)		// return 
	.end	inportl


//+
// 	vgaldl
//--
	LEAF_ENTRY(vgaldl)
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	sll	a0, 4, t5		// left shift address by 4
	lda	t0,0xfc00		// t0 = 0000 0000 0000 fc00
	ldah	t0,-1(t0)		// t0 = ffff ffff ffff fc00
	sll	t0,32,t0		// t0 = ffff fc00 0000 0000
	or 	t0,t5,t0                // make io address
	ldl	t4, 0(t0)		// load data
	sra	a0, 3, t1		// right shift addr by 3
	and	t1, 3, t2		// and addr with 3	
	s8addq	t2, zero, t3		// multiply by 8
	srl 	t4, t3, v0		// right shift data
	ret	zero, (ra)		// return
	.end	vgaldl




//+
// 	inIack
//--
	
	LEAF_ENTRY(inIack)
	
	//	
	//	get Iack from pic, need two to get the vector
	//
	ldiq	t0,PICIACKADR
	ldl	v0,0(t0)		// load data
	and	v0,0xff,v0		// make it a byte
	ret	zero, (ra)		// return
	.end	inIack





	LEAF_ENTRY(outmemb)
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and 	a0,3,t0			// get byte index from address
	insbl	a1,t0,t5		// put byte in proper position

	and	a0,0x1ffffff,t1		// 25 bit mask	
	ldiq	t0,EISABAD		// get EISA address

	sll	t1, 7, a0		// shift 7 for EISA 
	bis	t0,a0,t0		// t0 = address of EISA 
	stl	t5, 0(t0)		// write data to port
	ret	zero, (ra)		// return

	.end	outmemb



	LEAF_ENTRY(outmemw)
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and 	a0,3,t0			// get byte index from address
	inswl	a1,t0,t5		// put byte in proper position

	and	a0,0x1ffffff,t1		// 25 bit mask
	
	ldiq	t0,EISABAD		// get EISA address
	or	t0,0x20,t0		// t0 = ffff fc02 0000 0020 - word

	sll	t1, 7, a0		// shift 7 for EISA 
	bis	t0,a0,t0		// t0 = address of EISA 
	stl	t5, 0(t0)		// write data to port
	ret	zero, (ra)		// return

	.end	outmemw




	LEAF_ENTRY(outmeml)
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and	a0,0x1ffffff,t1		// 25 bit mask

	ldiq	t0,EISABAD		// get EISA address
	or	t0,0x60,t0		// t0 = ffff fc02 0000 0060 - long

	sll	t1, 7, a0		// shift 7 for EISA 
	bis	t0,a0,t0		// t0 = address of EISA 
	stl	a1, 0(t0)		// write data to port
	ret	zero, (ra)		// return

	.end	outmeml



	LEAF_ENTRY(outbuffb)

	/*  Arguments:
		a0	address of destination buffer (byte aligned).
        	a1	address of source buffer in memory (byte aligned)
       		a2      Number of bytes to move (Count).	
	*/	
		
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	beq	a2, donewb		// leave if nothing to do

	ldiq	t0,EISABAD		// get EISA address

	and 	a0,3,t3			// get byte index from dst address

	and	a0,0x1ffffff,t1		// 25 bit mask
	sll	t1,EISA_SHIFT,t4	// shift 7 for EISA
   	bis	t0,t4,t0		// t0 = address of EISA 

loopwb:
	ldq_u	t1, 0(a1)		// get src data
	subl	a2, 1, a2		// decrement count
	extbl	t1, a1,t1		// extract byte
	addl	a1, 1, a1		// point ot next src address
	insbl	t1,t3,t1		// insert byte in proper place
	stl	t1, 0(t0)		// write data to EISA memory
	addq    t0,EISA_BYTE_ADJ, t0 	// increment EISA memory pointer
	addl	t3,1,t3			// increment index
	and 	t3,3,t3			// mask off overflow
	bne	a2, loopwb
donewb:
	ret	zero, (ra)		

	.end	outbuffb



	LEAF_ENTRY(outbuffw)

	/*  Arguments:
		a0	address of destination buffer (word aligned), eisa.
        	a1	address of source buffer in memory (word aligned)
       		a2      Number of words to move (Count).	
	*/	
		
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	beq	a2, doneww		// leave if nothing to do

	ldiq	t0,EISABAD		// get EISA address
	or	t0,0x20,t0		// t0 = ffff fc02 0000 0020 - word

	and 	a0,3,t3			// get word index from dst address

	and	a0,0x1ffffff,t1		// 25 bit mask
	sll	t1,EISA_SHIFT,t4	// shift 7 for EISA
   	bis	t0,t4,t0		// t0 = address of EISA 

loopww:
	ldq_u	t1, 0(a1)		// get src data
	subl	a2, 1, a2		// decrement count
	extwl	t1, a1,t1		// extract word
	addl	a1, 2, a1		// point ot next src address
	inswl	t1,t3,t1		// insert in proper place
	stl	t1, 0(t0)		// write data to EISA memory
	addq    t0,EISA_WORD_ADJ, t0 	// increment EISA memory pointer
	addl	t3,2,t3			// increment index
	and 	t3,3,t3			// mask off overflow
	bne	a2, loopww
doneww:
	ret	zero, (ra)		

	.end	outbuffw





	LEAF_ENTRY(outbuffl)

	/*  Arguments:
		a0	address of destination buffer (long aligned), eisa.
        	a1	address of source buffer in memory (long aligned)
       		a2      Number of longs to move (Count).	
	*/	
		
	//
	// generate super-page address of EISA base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	beq	a2, donewl		// leave if nothing to do

	ldiq	t0,EISABAD		// get EISA address
	or	t0,0x60,t0		// t0 = ffff fc02 0000 0060 - long

	and	a0,0x1ffffff,t1		// 25 bit mask
	sll	t1,EISA_SHIFT,t4	// shift 7 for EISA
   	bis	t0,t4,t0		// t0 = address of EISA 

loopwl:
	ldl	t1, 0(a1)		// get src data
	subl	a2, 1, a2		// decrement count
	stl	t1, 0(t0)		// write data to EISA memory
	addl	a1, 4, a1		// point ot next src address
	addq    t0,EISA_LONG_ADJ, t0 	// increment EISA memory pointer
	bne	a2, loopwl
donewl:
	ret	zero, (ra)		

	.end	outbuffw



	LEAF_ENTRY(inmemb)

	//
	// generate super-page address of EISA, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and	a0,0x1ffffff,t1		// 25 bit mask

	ldiq	t0,EISABAD		// get EISA address

	sll	t1, 7, t2		// shift 7 for EISA 
	bis	t0,t2,t0		// t0 = address of EISA 
	ldl	v0, 0(t0)		// get EISA byte

	and 	a0,0x3,t1		// setup word shift count
	extbl	v0,t1,v0		// put into low byte

	ret	zero, (ra)		// return 

	.end	inmemb




	LEAF_ENTRY(inmemw)

	//
	// generate super-page address of EISA, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and	a0,0x1ffffff,t1		// 25 bit mask

	ldiq	t0,EISABAD		// get EISA base addr
	or	t0,0x20,t0		// t0 = ffff fc02 0000 0020 - word

	sll	t1, 7, t2		// shift 7 for EISA 
	bis	t0,t2,t0		// t0 = address of EISA 

	ldl	v0, 0(t0)		// get EISA short

	and	a0,0x3,t1		// setup byte shift count
	extwl 	v0,t1,v0		// put into low word

	ret	zero, (ra)		// return 

	.end	inmemw




	LEAF_ENTRY(inmeml)

	//
	// generate super-page address of EISA, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	and	a0,0x1ffffff,t1		// 25 bit mask

	ldiq	t0,EISABAD		// get EISA base address
	or	t0,0x60,t0              // t0 = ffff fc02 0000 0060 - long

	sll	t1, 7, t2		// shift 7 for EISA 
	bis	t0,t2,t0		// t0 = address of EISA 

	ldl	v0, 0(t0)		// get EISA 4 bytes
	ret	zero, (ra)		// return 

	.end	inmeml




	LEAF_ENTRY(inbuffb)

	/*
	Arguments:
		
	a0	source buffer in eisa bus memory.
        a1	destination buffer in memory.
        a2      Number of bytes to move (Count).
	*/	

	//
	// generate super-page address of EISA, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	beq	a2, donerb		// leave if nothing to do

	ldiq	t0,EISABAD		// get EISA base address

	and 	a0,3,t3			// get byte index from src address

	and	a0,0x1ffffff,t1		// 25 bit mask
	sll	t1, EISA_SHIFT, t4	// shift 7 for EISA 
	bis	t0,t4,t0		// t0 = address of EISA 

looprb:
	ldl	t1, 0(t0)		// get EISA 4 bytes
	subl	a2, 1, a2		// decrement byte count
	extbl	t1, t3, t1		// extract byte
	addq	t0, EISA_BYTE_ADJ, t0 	// increment EISA address
	stb	t1, 0(a1)		// assembler preserves the memory
					// behind the newly stored byte
	addl	a1, 1, a1		// increment memory pointer
	addl	t3, 1, t3		// point to next byte in long
	and	t3, 3, t3		// get new index		 
	bne	a2, looprb
donerb:
	ret	zero, (ra)		// return 

	.end	inbuffb




	LEAF_ENTRY(inbuffw)
	/*
	Arguments:
		
	a0	source buffer in eisa bus memory.
        a1	destination buffer in memory.
        a2      Number of words to move (Count).
	*/	


	//
	// generate super-page address of EISA, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	beq	a2, donerw		// leave if nothing to do

	ldiq	t0,EISABAD		// get EISA base address
	or	t0,0x20,t0              // t0 = ffff fc02 0000 0020 - word


	and 	a0,3,t3			// get byte index from src address

	and	a0,0x1ffffff,t1		// 25 bit mask
	sll	t1, EISA_SHIFT, t4	// shift 7 for EISA 
	bis	t0,t4,t0		// t0 = address of EISA 

looprw:
	ldl	t1, 0(t0)		// get EISA 4 bytes
	subl	a2, 1, a2		// decrement word count
	extwl	t1, t3, t1		// extract word
	addq	t0, EISA_WORD_ADJ, t0 	// increment EISA address
	stw	t1, 0(a1)		// store in dst memory
	addl	a1, 2, a1		// increment memory pointer
	addl	t3, 2, t3		// point to next word in long
	and	t3, 3, t3		// get new index		 
	bne	a2, looprw
donerw:
	ret	zero, (ra)		// return 

	.end	inbuffw



	LEAF_ENTRY(inbuffl)
	/*
	Arguments:
		
	a0	source buffer in eisa bus memory.
        a1	destination buffer in memory.
        a2      Number of longs to move (Count).
	*/	

	//
	// generate super-page address of EISA, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	beq	a2, donerl		// leave if nothing to do

	ldiq	t0,EISABAD		// get EISA base address
	or	t0,0x60,t0              // t0 = ffff fc02 0000 0060 - long

	and	a0,0x1ffffff,t1		// 25 bit mask
	sll	t1, EISA_SHIFT, t4	// shift 7 for EISA 
	bis	t0,t4,t0		// t0 = address of EISA 

looprl:
	ldl	v0, 0(t0)		// get EISA 4 bytes
	subl	a2, 1, a2		// decrement long count
	stl	v0, 0(a1)		// store in dst memory
	addl	a1, 4, a1		// increment memory pointer
	addq	t0, EISA_LONG_ADJ, t0	// increment EISA address
	bne	a2, looprl
donerl:
	ret	zero, (ra)		// return 

	.end	inbuffl



	LEAF_ENTRY(inctl)

	//
	// generate super-page address of EISA, base address
	// upper bits must be sign extension of bit 42
	// va<42:41> = 10 (binary) for super-page address
	//
	lda	t0,0xfc01		// t0 = 0000 0000 0000 fc01
	ldah	t0,-1(t0)		// t0 = ffff ffff ffff fc01
	sll	t0,32,t0		// t0 = ffff fc01 0000 0000
	bis	t0,0xe0000000,t0	// t0 = ffff fc01 e000 0000
	
	ldl	v0, 0(t0)		// get EISA byte
	and	v0,0xff,v0

	ret	zero, (ra)		// return 

	.end	inctl




//++
//
// VOID
// outVti(
//     ULONG port
//     ULONG data
//    )
//
// Routine Description:
//
//     This function uses the 64-bit super-page to write data to a port
//     of the on-board VTI combo chip for JENSEN.
//
// Arguments:
//
//    port (a0) - port number on VTI chip to which to write data
//    data (a1) - data to write to the port, only low byte is significant
//                 to the VTI
//
// Return Value:
//
//    None.
//
//--

	LEAF_ENTRY(outVti)

	//
	// generate super-page address of vti, base address
	// N.B. - upper bits must be sign extension of bit 42
	//   va<42:41> = 10 (binary) for super-page address
	//

	lda	t0, 0xc01c(zero)	// t0 = 0000 0000 0000 c01c
	ldah	t0, -1(t0)		// t0 = ffff ffff ffff c01c
	sll	t0, 28, t0		// t0 = ffff fc01 c000 0000


	//
	// Shift in the port number to generate the port address we
	//	wish to access
	// N.B. - access width is always zero = byte access for VTI
	//

	sll	a0, 9, a0		// a0 << 9
	bis	t0, a0, t0		// t0 = address of VTI port


	//
	// Do the port write, guarantee that subsequent writes (and reads)
	//   are ordered with respect to this write and return to caller
	//

	stl	a1, 0(t0)		// write data to port
	mb				// guarantee write ordering

	ret	zero, (ra)		// return

	.end	outVti



//++
//
// ULONG
// inVti(
//     ULONG port
//    )
//
// Routine Description:
//
//     This function uses the 64-bit super-page to read data from a port
//     of the on-board VTI combo chip for JENSEN.
//
// Arguments:
//
//    port (a0) - port number on VTI chip to which to write data
//
// Return Value:
//
//    data (v0) - the data read from the VTI chip, only the low byte will
//			be valid
//
//--

	LEAF_ENTRY(inVti)

	//
	// generate super-page address of vti, base address
	// N.B. - upper bits must be sign extension of bit 42
	//   va<42:41> = 10 (binary) for super-page address
	//

	lda	t0, 0xc01c(zero)	// t0 = 0000 0000 0000 c01c
	ldah	t0, -1(t0)		// t0 = ffff ffff ffff c01c
	sll	t0, 28, t0		// t0 = ffff fc01 c000 0000


	//
	// Shift in the port number to generate the port address we
	//	wish to access
	// N.B. - access width for VTI is always 0 = byte access
	//

	sll	a0, 9, a0		// a0 << 9
	bis	t0, a0, t0		// t0 = address of VTI port


	//
	// Do the super-page i/o access and return data to caller
	//

	ldl	v0, 0(t0)		// read data from port
	and	v0, 0xff, v0

	ret	zero, (ra)		// return 

	.end	inVti



LEAF_ENTRY(delay_us)
	bis 	zero, ONE_USEC, t1
        rpcc    t0              	/* RCC T0, read cycle counter 	*/

loop0:  rpcc    t2              	/* RCC T2, read cycle counter	*/
        subl    t2, t0, t2      	/* check for wrapping 		*/
        bge     t2, over0      		/* check, and see if negative 	*/

	ornot	t0, zero, t4		/* calculate the offset		*/
	zap	t4, 0xf0, t4
	cmplt	t4, t1, t2
	beq	t2, done0
	subl	t1, t4, t1		/* adjust the counter		*/
	and	zero, t0, t0		/* set t0 to zero		*/

over0:  cmplt   t2, t1, t2      	/* compare these for usec timer */
        bne     t2, loop0       	/* stay in... 			*/
done0:  ret     zero, (ra)
        .end    delay_us



LEAF_ENTRY(delay_500ns)
	bis 	zero, HALF_USEC, t1
        rpcc    t0              	/* RCC T0, read cycle counter 	*/

loop1: 	rpcc    t2              	/* RCC T2, read cycle counter	*/
        subl    t2, t0, t2      	/* check for wrapping 		*/
        bge     t2, over1      		/* check, and see if negative 	*/

	ornot	t0, zero, t4		/* calculate the offset		*/
	zap	t4, 0xf0, t4
	cmplt	t4, t1, t2
	beq	t2, done1
	subl	t1, t4, t1		/* adjust the counter		*/
	and	zero, t0, t0		/* set t0 to zero		*/

over1:	cmplt   t2, t1, t2      	/* compare these for usec timer */
        bne     t2, loop1       	/* stay in... 			*/
done1:  ret     zero, (ra)
        .end    delay_500ns