; PULSOUT port, pin, time
; Generates an output pulse in 10-cycle (10 us at 4 MHz) units,
; based on a 16-bit (1 to 65,535) value. The pulse is the reverse
; of the pin's state when pulsout is called. For instance,  if the
; specified pin is initially 1, Pulsout will invert it to make a
; negative-going pulse.

	org	8
hiB	ds	1	; MSB of time.
lowB	ds	1	; LSB of time.
pin	ds	1	; Pin number to pulse (0-7).

temp	ds	1	; Temporary variables for time delay
temp2	ds	1	; between pulses

; Device data and reset vector
	device	pic16c55,xt_osc,wdt_off,protect_off
	reset	start
	org	0
; Table to convert pin number (0-7) into bit mask (00000001b to 10000000b).
Pinz	jmp	pc+w
	retw	1,2,4,8,16,32,64,128

start	mov	!ra, #0 	; All outputs.
	clr	ra		; Start with 0s.
	mov	lowB,#10	; 10 x 10-cycle pulse
	clr	hiB
	mov	pin,#2		; Pin 2.
	mov	w,#0		; of port ra.
	CALL	PULSOUT 	; Pulse pin high for 100 cycles.
	CALL	delay		; Wait a while between pulses.
	jmp	start		; Do it again.

; Upon entry, the desired pin must already be set up as an output.
; The w register contains a number representing the output port (0-2) for
; RA through RC. Variable "pin" contains the pin number (0-7). The variables
; hiB and lowB are the MSB and LSB of the time argument.

PULSOUT mov	fsr,w		; Point to the port number.
	add	fsr,#RA 	; Add offset for port RA.
	mov	w,pin
	CALL	Pinz		; Get bit mask from the table.
	mov	pin,w		; Put the mask into pin
	NOT	hiB		; Take twos complement
	NEG	lowB		; of the 16-bit counter
	snz			; If zero, lowB overflowed,
	inc	hiB		; so carry into hiB.
	XOR	indirect,pin	; Invert the selected pin.

; The main timing loop. Remove the nops for 5-cycle resolution.
:loop	jmp	$+1		; Two-cycle "nop."
	jmp	$+1		; Two-cycle "nop."
	nop
	inc	lowB		; lowB = lowB+1.
	snz			; Overflow in lowB?
	incsz	hiB		; Yes: hiB=hiB+1, watch for overflow.
	jmp	:loop		; If not overflow, do it again.
	XOR	indirect,pin	; Invert pin (back to initial state).
	ret

; Delay routine for demonstration. Not required by Pulsout.

delay	djnz	temp,delay	; Time delay to provide spacing
	djnz	temp2,delay	; between pulses.
	ret

BACK