; NAP period (in w)
; Puts the PIC to sleep for a short period of time.
; The length of the nap may be in the range of 0 to 7 and is passed
; to the subroutine in the w register. The length of nap (in seconds) is
; 2^w * 18 ms, as follows:
;	w = 0: nap = 18 ms
;	w = 1: nap = 36 ms
;	w = 2: nap = 72 ms
;	w = 3: nap = 144 ms
;	w = 4: nap = 288 ms
;	w = 5: nap = 576 ms
;	w = 6: nap = 1152 ms
;	w = 7: nap = 2304 ms
; The 18-ms value is very approximate. It is based on a supply
; voltage of 5 Vdc and an operating temperature of 77 degrees F.
; At higher temperatures and lower supply voltages, it can be much
; longer--even double--the nominal 18 ms. Likewise, at lower
; temperatures and higher supply voltages it can fall to half.
; Note that Nap uses one level of the call/return stack.
	
; Device data and reset vector: Note that the watchdog timer is ON.
	device	pic16c55,xt_osc,wdt_on,protect_off
	reset	start
	org	0

Nap	OR	w,#8		; Set option.3 to assign prescaler
	mov	!OPTION,w	; Lower 3 bits are prescale rate.
	sleep			; Go to sleep

start	mov	!rb,#0		; Make RB all outputs for LEDs.
	clr	w		; At the beginning of the program,
	snb	pd		; we set up a Branch-type routine
	OR	w,#1		; to take action based on the
	snb	to		; power-down (pd) and timeout (to)
	OR	w,#2		; bits.

	jmp	pc+w		; | to | pd |
	ret			; | 0	| 0	| wdt wake: return.
	jmp	wdt_fail 	; | 0	| 1	| wdt timeout: handle it.
	jmp	mclr_pin 	; | 1	| 0	| mclr wake: handle it.
	jmp	main		; | 1	| 1	| pwr on: main.

; This code executes when power is first applied to the PIC (after start).
; It's a loop in which the PIC takes a 1.152-second nap, then inverts
; port rb. The result is that LEDs connected to RB flash at the rate of the
; nap period.

main	mov	w,#6		; Set up a 1152-ms nap.
	call	Nap		; Snooze for >1 second.
	XOR	rb,#255 	; Wake up and invert RB.
	jmp	main		; Do it again.

; In an actual application, this code would contain instructions for dealing
; with a reset pulse waking the PIC out of its nap. Here, we have an empty
; routine that just returns to the main loop.

mclr_pin	ret

; In an actual application, this code would contain instructions for dealing
; with a watchdog-timer timeout. Here, we have an empty routine that just
; returns to the main loop.

wdt_fail	ret
