; PAUSE time
; A general-purpose delay routine that puts the PIC into a do-nothing
; loop for a 16-bit number of milliseconds (1 to 65535) at 4 MHz. Requires
; 16 cycles of overhead for call, return and other processing.

	device	pic16c55,xt_osc,wdt_off,protect_off
	reset	start

	org	8
hiB	ds	1	; MSB of time.
lowB	ds	1	; LSB of time.
temp	ds	1	; temporary counter for Pause

; Device data and reset vector
	org	0

start	mov	!rb, #0 	; Output through RB.
	mov	hiB,#3		; Length of delay =
	mov	lowB,#0E8h	; 3E8h (1000 ms @ 4MHz).
	XOR	rb,#255 	; Toggle LED(s).
	call	Pause		; Wait 1 second.
	jmp	start		; Do it again.

; Upon entry, variables hiB and lowB hold the MSB and LSB of the
; number of milliseconds (1 to 65535) to delay.

Pause	NOT	hiB		; Take twos complement
	NOT	lowB		; of the 16-bit counter
	INC	lowB
	snz			; If zero, lowB overflowed,
	inc	hiB		; so carry into hiB.
:load	mov	temp,#248	; Set up for 1-ms loop.
:loop	nop			; Do nothing.
	djnz	temp,:loop	; Do more nothing.
	jmp	$ + 1		; 2-cycle "nop"
	inc	lowB		; lowB = lowB+1.
	snz			; Overflow in lowB?
	incsz	hiB		; Yes: hiB=hiB+1, overflow?.
	jmp	:load		; No overflow: do it all again.
	ret			; Overflow. Return to caller.
