; The routines contained in this file are taken from
; "tctimer" 1.0 by Richard S. Sadowsky
; (released to the public domain 8/10/88)
; with improvements by Toad Hall and David Kirschbaum (1991).
; The full package is avaliable from Simtel as C/MSEC_12.ZIP.
;
; I have not made any attempts to understand this code.
;
; The public routine _delay is a substitute for
; TCC's delay() function. It is included here to make
; linking against the TCC runtime library unnecessary,
; thereby allowing to compile T3X programs on DOS systems
; without TCC.

	.model	small

	.data
t0l	dw	?
t0h	dw	?
dtl	dw	?
dth	dw	?

	.code
	public	__delay

initializetimer:
	mov	al,34H
	jmp	short Common	;common to return


restoretimer:
	mov	al,36H		;/* outp(0x043,0x036); */
Common:
	mov	dx,43H
	out	dx,al
	jmp	short $+2

	mov	dx,40H		;/* outp(0x040,0x000); */
	xor	ax,ax
	out	dx,al
	jmp	short $+2

	out	dx,al		;/* outp(0x040,0x000); */
	ret

readtimer:
	cli			;/* Disable interrupts */
	mov	dx,020h		;/* Address PIC ocw3   */
	mov	al,00Ah		;/* Ask to read irr    */
	out	dx,al
	mov	al,00h		;/* Latch timer 0 */
	out	043h,al
	in	al,dx		;/* Read irr      */
	mov	di,ax		;/* Save it in DI */
	in	al,040h		;/* Counter --> bx*/
	mov	bl,al		;/* LSB in BL     */
	in	al,040h
	mov	bh,al		;/* MSB in BH     */
	not	bx		;/* Need ascending counter */
	in	al,021h		;/* Read PIC imr  */
	mov	si,ax		;/* Save it in SI */

	mov	al,00FFh	;/* Mask all interrupts */
	out	021h,al
	mov	ax,040h		;/* read low word of time */
	push	es
	mov	es,ax		;/* from BIOS data area   */
	mov	dx,es:[06Ch]	;here's the timer long.hi
	pop	es

	mov	ax,si		;/* Restore imr from SI   */
	out	021h,al

	sti			;/* Enable interrupts */
	mov	ax,di		;/* Retrieve old irr  */
	test	al,001h		;/* Counter hit 0?    */
	jz	Done		;/* Jump if not       */
	cmp	bx,0FFh		;/* Counter > 0x0FF?    */
	ja	Done		;/* Done if so        */
	inc	dx		;/* Else count int req. */
Done:	mov	ax,bx		;/* set function result */

	ret

_delay:
	push	bp
	mov	bp,sp
	push	di
	push	si

	mov	ax,[bp+4]
	mov	cx,1193
	mul	cx
	mov	dtl,ax
	mov	dth,dx
	call	initializetimer
	call	readtimer
	mov	t0l,ax
	mov	t0h,dx
goon:	call	readtimer
	sub	ax,t0l
	sbb	dx,t0h
	cmp	ax,dtl
	jb	goon
	cmp	dx,dth
	jb	goon

	call	restoretimer
	pop	si
	pop	di
	pop	bp
	ret

__delay	PROC FAR
	push	bp
	mov	bp,sp
	mov	ax,[bp+6]
	push	ax
	call	_delay
	pop	ax
	pop	bp
	retf
	ENDP	__delay

	end

