        list            p=16F84
        #include        <p16F84.inc>

        __CONFIG        _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC



;**************************************************
;
; (C) Copyright notice
;
; Written by Richard Prinz.
; Copyright 2003 by Richard Prinz.
; OE1RIB Richard.Prinz@MIN.at
;
; Permission to use, copy, and modify this program
; without restriction is hereby granted, as long as
;
; 1) this copyright notice appears in each copy of
;    the program source code and
;
; 2) the source code is not used for commercial
;    purposes.
;
; This program is freely distributable without
; licensing fees and is provided without guarantee
; or warrantee expressed or implied.
;
; This program is -not- in the public domain.
;
;**************************************************



;**************************************************
;
;       Schematic  /  Loop version
;
;**************************************************
;                                                                          
;   16F84             ZN426             CA3140
;   4 MHz             (or discr. R-2R DAC)                
;   +------+          +------+                                           
;   |      |----------|      |          +------+          
;   |      |  B0-B7   |      | analog   |      |                        
;   |      |----------|      |----------|      | fout
;   |      |          |      |          |      |----->                  
;   |      |          |      |          |      |                        
;   |      |          +------+          +------+                        
;   |      |  A2    Key                                                    
;   |      |---------/ -                                                   
;   |      |  A3    LED                                                    
;   |      |-------->|--                                               
;   +------+                                                               



;**************************************************
;
;       Definitions
;
;**************************************************

#define PAGE0           BCF 3,5
#define PAGE1           BSF 3,5
;#define Debug          1



;**************************************************
;
;       Variables
;
;**************************************************

                cblock     0x0C
FREQ_H
FREQ_M
FREQ_L

ACC_H
ACC_M
ACC_L

TEMP

SER
                endc



;**************************************************
;
;       Module Definitions + Variables
;
;**************************************************

#include        "tools.h"



;**************************************************
;
;       M A I N - E N T R Y
;
;**************************************************

                ORG             0x000
Start

                PAGE1

                ; set PORTA
                ; A0 - 
                ; A1 - 
                ; A2 - Key
                ; A3 - Led
                ; A4 - 
                movlw           B'00000100'
                movwf           TRISA

                ; set PORTB
                ; B0 - Data 0 out
                ; B1 - Data 1 out
                ; B2 - Data 2 out
                ; B3 - Data 3 out
                ; B4 - Data 4 out
                ; B5 - Data 5 out
                ; B6 - Data 6 out
                ; B7 - Data 7 out
                movlw           B'00000000'
                movwf           TRISB

                PAGE0

                     
;**************************************************
;
;       Output frequency (using 24 bit accumulator)
;
;   f = deltaPhase * fClock/2^24
;
;   fClock is in this case the CPU clock divided by the
;   number of cycles to output the data ( 32 cycles )
;
;   (the output loop needs between 28 and 32 cycles to
;   output calculate, lookup and the data)
;
;   f = FREQ_H/FREQ_M/FREQ_L * (1000000/28)/16777216
;
;   f = FREQ_H/FREQ_M/FREQ_L * 0.00212874
;
;   fMax (theoretical) = 0.5 * fClock
;
;
;   example frequency words
;
;     1 Hz =     470 (    0x1D6 )
;     3,137255 Hz = 1474 ( 0x5C2 ) SSTV color step
;    10 Hz =    4698 (   0x125A )
;   100 Hz =   46976 (   0xB780 )
;  1000 Hz =  469761 (  0x72B01 )
;  1200 Hz =  563714 (  0x89A02 ) SSTV Sync
;  1500 Hz =  704642 (  0xAC082 ) SSTV Black
;  2300 Hz = 1080451 ( 0x107C83 ) SSTV White
;  3000 Hz = 1409284 ( 0x158104 )

    ; ---- START ----
    ; 1000 Hz
    #define STARTAT_H       0x07
    #define STARTAT_M       0x2B
    #define STARTAT_L       0x01

    ; ---- STEP ----
    ; 100 Hz
    #define STEP_H          0x00
    #define STEP_M          0xB7
    #define STEP_L          0x80

    ; ---- ROLL ----
    ; 3000 Hz
    #define ROLLAT_H        0x15
    #define ROLLAT_M        0x81
    #define ROLLAT_L        0x05

;
;**************************************************



;**************************************************
;
;       Main Loop
;
;**************************************************

                clrf            ACC_H
                clrf            ACC_M
                clrf            ACC_L
                clrf            PORTA
                clrf            PORTB

                ; set START frequency
                call            RollOver

                ; start silent
                goto            SoundOff
            
NCOLoop

IsCmd
                ; is attention high?
                btfsc           PORTA,2                 ; 1 / 2
                goto            ProcessCmd              ; 2

AddFreq
                ; add freq value to phase accumulator
                ; 24bit
                movf            FREQ_L,w                ; 1
                addwf           ACC_L,f                 ; 1

                movf            FREQ_M,w                ; 1
                btfsc           STATUS,C                ; 1 / 2
                incfsz          FREQ_M,w                ; 1 / 2
                addwf           ACC_M,f                 ; 1

                movf            FREQ_H,w                ; 1
                btfsc           STATUS,C                ; 1 / 2
                incfsz          FREQ_H,w                ; 1 / 2
                addwf           ACC_H,f                 ; 1
                
LookupSine
                movf            ACC_H,w                 ; 1
                callEX          SINE_TABLE              ; 2 + 5 in subroutine
                                                        ; + 4 bsf's and bcf's
                                                        ; in callEX macro

Output
                movwf           PORTB                   ; 1
Again
                goto            NCOLoop                 ; 2

                
;**************************************************
;
;       Process commands to NCO
;
;**************************************************

ProcessCmd
                call DebugCmd
                goto NCOLoop

SoundOff
                btfss           PORTA,2
                goto            SoundOff
                goto            ProcessCmd

DebugCmd
                ; just for debuging - key debounce 5ms
                movlw           0x00
                movwf           DELAY_H
                movlw           0x05
                movwf           DELAY_L
                callEX          Delay
                btfss           PORTA,2
                return

KeySettle
                btfsc           PORTA,2
                goto            KeySettle

                ; just for debuging - toggle led at A1
                movlw           B'00001000'
                xorwf           PORTA,f

                ; increment freq by STEP with every key press
                ; 24 bit add
                movlw           STEP_L
                addwf           FREQ_L,f

                movlw           STEP_M
                movwf           TEMP
                btfsc           STATUS,C
                incfsz          TEMP,w
                addwf           FREQ_M,f

                movlw           STEP_H
                movwf           TEMP
                btfsc           STATUS,C
                incfsz          TEMP,w
                addwf           FREQ_H,f
                
                ; check for overrun ar ROLLAT
                ; 24 bit subtract
                movlw           ROLLAT_H
                subwf           FREQ_H,w
                btfss           STATUS,C
                return
                btfss           STATUS,Z
                goto            RollOver

                movlw           ROLLAT_M
                subwf           FREQ_M,w
                btfss           STATUS,C
                return
                btfss           STATUS,Z
                goto            RollOver

                movlw           ROLLAT_L
                subwf           FREQ_L,w
                btfss           STATUS,C
                return
                
RollOver
                ; roll over to START freqency
                movlw           STARTAT_H
                movwf           FREQ_H
                movlw           STARTAT_M
                movwf           FREQ_M
                movlw           STARTAT_L
                movwf           FREQ_L
                
                return


;**************************************************
;
;       SINE Frequency Table with 256 entries
;       copy and paste from SineDDS MatLab script
;
;**************************************************

                ORG             0x1FD
SINE_TABLE
                bsf             PCLATH,1                                ; 1
                bcf             PCLATH,0                                ; 1
                addwf           PCL,f                                   ; 1
                ; each dt is internaly a retlw so 2 cycles              ; 2
                dt              0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95 
                dt              0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae
                dt              0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4
                dt              0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8
                dt              0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8
                dt              0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5
                dt              0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc
                dt              0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff
                dt              0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe
                dt              0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7
                dt              0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec
                dt              0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc
                dt              0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9
                dt              0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3
                dt              0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c
                dt              0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83
                dt              0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a
                dt              0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51
                dt              0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b
                dt              0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27
                dt              0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17
                dt              0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a
                dt              0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03
                dt              0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00
                dt              0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01
                dt              0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08
                dt              0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13
                dt              0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23
                dt              0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36
                dt              0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c
                dt              0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63
                dt              0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c


                     
;**************************************************
;
;       Tool routines
;
;**************************************************

                ORG             0x300              
#include        "tools.asm"



        end


