;************************************************************************
;   Filename:      50hz generator (modified sine)                       *
;   Date:          2010-02-19                                           *
;   File Version:  1.0                                                  *
;                                                                       *
;   Author:        Harry Lythall, SM0VPO                                *
;************************************************************************
;   Architecture:  Baseline PIC                                         *
;   Processor:     12F508/509                                           *
;************************************************************************
;   Files required: none                                                *
;************************************************************************
;   Description:    DC/AC generator                                     *
;                                                                       *
;   Toggles GP0 and GP1 at 50Hz in anti-phase                           *
;   2ms delay between GP0=ON and GP1=ON                                 *
;   GP1 and GP2 drive push-pull power MOSFETS > power transformer       *
;   to deliver "modified sinewave".                                     *
;************************************************************************
;   Pin assignments:                                                    *
;       GP0 - out - Toggling                                            *
;       GP1 - out - Toggling in oposition to GP1                        *
;       GP3 - in  - select 1=50Hz 0=60Hz                                *
;************************************************************************

    list        p=12F509      
    #include    <p12F509.inc>

                ; ext reset, no code protect, no watchdog, 4Mhz int clock
    __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC


;***** VARIABLE DEFINITIONS
        UDATA
dc1     res 1                   ; delay loop counters
dc2     res 1


;************************************************************************
RESET   CODE    0x000           	; effective reset vector
        movwf   OSCCAL          	; update OSCCAL with factory cal value 

start	movlw   b'111100'       	; configure GP0 + GP1 as outputs
        tris    GPIO

main	movlw	b'000000'		; set w to all zero
		movwf	GPIO		; write to GP0 + GP1

		movlw	.2		; 2 x 1ms delay
		movwf	dc2		; write to delay register

		btfsc	GPIO,3		; Test GP3 - skip if 0
		call	delay		; GOSUB for 2.00ms
		btfss	GPIO,3		; Test GP3 - skip if 0
		call	delaz		; GOSUB for 1.66ms

		movlw	b'000001'	; set w to 1 in bit0
		movwf	GPIO		; set GP0 high - GP1 low

		movlw	.7		; 7 x 1ms delay
		movwf	dc2		; write to delay register

		btfsc	GPIO,3		; Test GP3 - skip if 0
		call	delay		; GOSUB for 14.00ms
		btfss	GPIO,3		; Test GP3 - skip if 0
		call	delaz		; GOSUB for 11.66ms

		movlw	b'000000'	; set w to all zero
		movwf	GPIO		; write to GP0 + GP1

		movlw	.2		; 2 x 1ms delay
		movwf	dc2		; write to delay register

		btfsc	GPIO,3		; Test GP3 - skip if 0
		call	delay		; GOSUB for 2.00ms
		btfss	GPIO,3		; Test GP3 - skip if 0
		call	delaz		; GOSUB for 1.66ms

		movlw	b'000010'	; set w to 1 in bit1
		movwf	GPIO		; set GP0 low - GP1 high

		movlw	.7		; 2 x 1ms delay
		movwf	dc2		; write to delay register

		btfsc	GPIO,3		; Test GP3 - skip if 0
		call	delay		; GOSUB for 14.00ms
		btfss	GPIO,3		; Test GP3 - skip if 0
		call	delaz		; GOSUB for 11.66ms

		goto	main

;***** Delay loop 50Hz=1ms x dc2
delay	movlw	.221			; 183=60Hz 221=50Hz
        movwf    dc1            	; store it

dly1    nop                     	; 1us delay
		nop			; and another
        decfsz  dc1,f			; repeat if not zero
        goto    dly1
dly2    decfsz  dc2,f
        goto    delay			; reset dc2 and repeat
        retlw	0	            	; return if done

;***** Delay loop 60Hz=833us x dc3
delaz	movlw	.183			; 183=60Hz 221=50Hz
        movwf    dc1            	; store it

dly3    nop                     	; 1us delay
		nop			; and another
        decfsz  dc1,f			; repeat if not zero
        goto    dly3
dly4    decfsz  dc2,f
        goto    delaz			; reset dc2 and repeat
        retlw	0	            	; return if done

        END
