;*****************************************************************************************
; Copyright © [01/26/1999] Scenix Semiconductor, Inc. All rights reserved.
;
; Scenix Semiconductor, Inc. assumes no responsibility or liability for
; the use of this [product, application, software, any of these products].
; Scenix Semiconductor conveys no license, implicitly or otherwise, under
; any intellectual property rights.
; Information contained in this publication regarding (e.g.: application,
; implementation) and the like is intended through suggestion only and may
; be superseded by updates. Scenix Semiconductor makes no representation
; or warranties with respect to the accuracy or use of these information,
; or infringement of patents arising from such use or otherwise.
;*****************************************************************************************
; 
; Filename:     	vp_Sin_Wav_Gen.src
;
; Author:		Nataraj K.
;			Software Engineer
;			Adamya Computing Technologies Pvt. Ltd.,
;
; Revision:		1.1
; Part:			SX28AC datecode 9929AA, SX52BD/PDF datecode A9931AC
; Freq:			50Mhz
; Compiled using:	Parallax SX-Key software v1.19 and SASM 1.43
;
; Date Written:		August 12, 1998
;
; Last Revised:		May 29, 2000
;
; Program Description:
;    This program demonstrates the generation of an artificial SINE wave using the properties
;    of gravity. The sine wave starts at a defined point in time with a defined velocity. The
;    main program loops indefinetely, after initializing some registers. A PWM output outputs
;    the current value of the sine wave. Because of properties inherent in the design of the 
;    Scenix PWM, the resolution of the output SINE wave varies inversely with frequency. 
;
; Interface Pins:
;    RA.0  
;
; Revision History :
;    Version 1.1 as per the standard source code template.
;
;*****************************************************************************************
;
;*****************************************************************************************
; Target SX
; Uncomment one of the following lines to choose the SX18AC,SX20AC,SX28AC,SX48BD/ES,SX48BD,
; SX52BD/ES or SX52BD. For SX52BD/ES, uncomment both the defines,SX48_52 and SX48_52_ES.
;*****************************************************************************************
; SX18_20
; SX28AC
 SX48_52
; SX48_52_ES		

;*****************************************************************************************
; Assembler Used
; Uncomment the following line if using the Parallax SX-Key assembler. SASM assembler
; enabled by default.
;*****************************************************************************************
SX_Key

	;*********************************************************************************
	; Assembler directives:
	;	high speed external osc, turbo mode, 8-level stack, and extended option reg.
	;
	;	SX18/20/28 - 4 pages of program memory and 8 banks of RAM enabled by default.
	;	SX48/52 - 8 pages of program memory and 16 banks of RAM enabled by default.
	;                
	;*********************************************************************************

IFDEF SX_Key 				;SX-Key Directives
      IFDEF	SX18_20			; SX18AC or SX20AC device directives for SX-KEY
			device	SX18L,oschs2,turbo,stackx_optionx
      ENDIF
         IFDEF	SX28AC			; SX28AC device directives for SX_KEY
			device	SX28L,oschs2,turbo,stackx_optionx
         ENDIF
      IFDEF	SX48_52_ES		; SX48BD/ES or SX52BD/ES device directives for SX_KEY
			device	oschs,turbo,stackx,optionx
      ELSE
	 IFDEF	SX48_52			; SX48/52/BD device directives for SX_KEY
			device	oschs2
         ENDIF
      ENDIF
          freq		50_000_000
ELSE					; SASM  Directives
      IFDEF	SX18_20			; SX18AC or SX20AC device directives for SASM
			device	SX18,oschs2,turbo,stackx,optionx
      ENDIF
         IFDEF	SX28AC			; SX28AC device directives for SASM
			device	SX28AC,oschs2,turbo,stackx,optionx
         ENDIF
      IFDEF	SX48_52_ES		; SX48BD/ES or SX52BD/ES device directives for SASM
			device	SX52BD,oschs,turbo,stackx,optionx
      ELSE
	 IFDEF   SX48_52		; SX48BD or SX52BD device directives for SASM
                    	device	SX52BD,oschs2
         ENDIF
      ENDIF
ENDIF
		id	 'SINEWAVE'		; identity given as SINEWAVE
		reset	 resetEntry           	; set reset vector


;****************************************************************************************************
; Watches (For Debug in SX_Key software V.1.0 +)
;****************************************************************************************************
;VP_begin SINEWAVE

      watch   swFreqAccLow,16,uhex               ; 16-bit accumulator to the sine wave
      watch   swFreqCountLow,16,uhex             ; 16-bit count which decides frequency of sine wave
      watch   swSin,8,sdec                       ; The current value of imitation sin wave
      watch   swSinvel,8,sdec                    ; The velocity of sin wave   
      watch   swPwm0,8,udec                      ; current PWM output
      watch   swPwm0Acc,8,udec                   ; PWM accumulator
   
;VP_end

;*****************************************************************************************
; Macros
;*****************************************************************************************

	;*********************************************************************************
	; Macro: _bank
	; Sets the bank appropriately for all revisions of SX.
	;
	; This is required since the bank instruction has only a 3-bit operand, it cannot
	; be used to access all 16 banks of the SX48/52. For this reason FSR.4 (for SX48/52BD/ES)
	; or FSR.7 (SX48/52bd production release) needs to be set appropriately, depending
	; on the bank address being accessed. This macro fixes this.
	;
	; So, instead of using the bank instruction to switch between banks, use _bank instead.
	; 
	;*********************************************************************************
_bank	macro	1
  noexpand
	bank	\1
	IFDEF SX48_52
	  IFDEF SX48_52_ES
	   IF \1 & %00010000		;SX48BD/ES and SX52BD/ES (engineering sample) bank instruction
  expand
		setb	fsr.4		;modifies FSR bits 5,6 and 7. FSR.4 needs to be set by software.
  noexpand
	    ENDIF
	  ELSE
	   IF \1 & %10000000		;SX48BD and SX52BD (production release) bank instruction 
  expand
		setb	fsr.7		;modifies FSR bits 4,5 and 6. FSR.7 needs to be set by software.
  noexpand
	    ELSE
  expand
		clrb	fsr.7
  noexpand
	    ENDIF
	  ENDIF
	ENDIF
	endm

	;*********************************************************************************
	; Macro: _mode
	; Sets the MODE register appropriately for all revisions of SX.
	;
	; This is required since the MODE (or MOV M,#) instruction has only a 4-bit operand. 
	; The SX18/20/28AC use only 4 bits of the MODE register, however the SX48/52BD have 
	; the added ability of reading or writing some of the MODE registers, and therefore use
	; 5-bits of the MODE register. The  MOV M,W instruction modifies all 8-bits of the 
	; MODE register, so this instruction must be used on the SX48/52BD to make sure the MODE
	; register is written with the correct value. This macro fixes this.
	;
	; So, instead of using the MODE or MOV M,# instructions to load the M register, use
	;  _mode instead.
	; 
	;*********************************************************************************
_mode	macro	1
  noexpand
	IFDEF SX48_52
  expand
		mov	w,#\1           ;loads the M register correctly for the SX48BD and SX52BD
		mov	m,w
  noexpand
	ELSE
  expand
		mov	m,#\1    	;loads the M register correctly for the SX18AC, SX20AC
					;and SX28AC
  noexpand
	ENDIF
	endm


        ;****************************************************************************************
        ; INCP/DECP macros for incrementing/decrementing pointers to RAM
        ; used to compensate for incompatibilities between SX28AC and SX52BD
        ;****************************************************************************************

INCP macro 1				; Increments a pointer to RAM
		inc    \1
	IFNDEF	SX48_52
		setb  \1.4		; If SX18 or SX28AC,keep bit 4 of the pointer = 1
	ENDIF				; to jump from $1f to $30,etc
endm

DECP macro 1				; Decrements a pointer to RAM
	IFDEF	SX48_52
		dec    \1
	ELSE
		clrb   \1.4		; If SX18 or SX28AC, forces rollover to next bank
		dec    \1		; if it rolls over. (skips banks with bit 4 = 0)
		setb   \1.4             ; Eg: $30 ---> $20 ---> $1f ---> $1f 
	ENDIF                           ; AND: $31 ---> $21 ---> $20 ---> $30
endm

        ;***********************************************************************************************
        ; Error generating macros
        ; Used to generate an error message if the label is intentionally moved into the second page .
        ; Use for lookup tables.
        ;***********************************************************************************************

tablestart	macro	0		; Generates an error message if code that MUST be in
					; the first half of a page is moved into the second half
	if $ & $100
		ERROR      'Must be located in the first half of a page.'
	endif
endm

tableEnd	macro	0		; Generates an error message if code that MUST be in
					; the first half of a page is moved into the second half

	if $ & $100
		ERROR      'Must be located in the first half of a page.'
	endif
endm


;*****************************************************************************************
; Data Memory address definitions
; These definitions ensure the proper address is used for banks 0 - 7 for 2K SX devices
; (SX18/20/28) and 4K SX devices (SX48/52). 
;*****************************************************************************************
IFDEF SX48_52

global_org	=	$0A
bank0_org	=	$00
bank1_org	=	$10
bank2_org	=	$20
bank3_org	=	$30
bank4_org	=	$40
bank5_org	=	$50
bank6_org	=	$60
bank7_org	=	$70

ELSE

global_org	=	$08
bank0_org	=	$10
bank1_org	=	$30
bank2_org	=	$50
bank3_org	=	$70
bank4_org	=	$90
bank5_org	=	$B0
bank6_org	=	$D0
bank7_org	=	$F0

ENDIF

;*****************************************************************************************
; Equates for common data comm frequencies
;*****************************************************************************************

;VP_begin  SINEWAVE

f697_h          equ             $012    ; 697Hz specified for DTMF Frequency
f697_l          equ             $09d

f770_h          equ             $014    ; 770Hz specified for DTMF Frequency
f770_l          equ             $090      

f852_h          equ             $016    ; 852Hz specified for DTMF Frequency
f852_l          equ             $0c0

f941_h          equ             $019    ; 941Hz specified for DTMF Frequency
f941_l          equ             $021

f1209_h         equ             $020    ; 1209Hz specified for DTMF Frequency
f1209_l         equ             $049      

f1336_h         equ             $023    ; 1336Hz specified for DTMF Frequency
f1336_l         equ             $0ad

f1447_h         equ             $027    ; 1447Hz specified for DTMF Frequency
f1447_l         equ             $071

f1633_h         equ             $02b    ; 1633Hz specified for DTMF Frequency
f1633_l         equ             $09c      

f1300_h         equ             $022    ; 1300Hz Signifies HIGH data in Bell202 Spec
f1300_l         equ             $0b7

f2100_h         equ             $038    ; 2100Hz Signifies LOW data in Bell201 Spec
f2100_l         equ             $015 

;********************************************************************************
; Pin Definition
;********************************************************************************

swPwmPin         equ             ra.0    ; sine wave output pin at port RA.0

;VP_end




;*****************************************************************************************
; Global Register definitions
; NOTE: Global data memory starts at $0A on SX48/52 and $08 on SX18/20/28.
;*****************************************************************************************
		org     global_org

isr_temp	equ	global_org+0	; temp variable used by the ISR

;*****************************************************************************************
; RAM Bank Register definitions
;*****************************************************************************************

	;*********************************************************************************
	; Bank 0
	;*********************************************************************************
               org   bank0_org

bank0        =      $

	;*********************************************************************************
	; Bank 1
	;*********************************************************************************
		org   bank1_org

;VP_begin SINEWAVE

 swSinGenBank    =       $

 swFreqAccLow         ds          1       ; 16-bit accumalator which decides when to increment the sine wave
 swFreqAccHigh        ds          1       ; 16-bit accumalator which decides when to increment the sine wave
 swFreqCountLow       ds          1       ; 16-bit counter which decides which frequency for the sine wave
 swFreqCountHigh      ds          1       ; Freq_count = Frequency * 6.83671552
 swSin                ds          1       ; The current value of the imitation sin wave, 
 swSinvel             ds          1       ; The velocity of the sin wave, changes the amplitude
 swPwm0Acc            ds          1       ; PWM accumulator
 swPwm0               ds          1       ; current PWM output

;VP_end

;VP: ISR Multithreader

 isrMultiplex         ds          1       ; The isrMultiplex register is used to switch to a new execution
                                          ; thread on each pass of the ISR.
 
       ;*********************************************************************************
	; Bank 2
	;*********************************************************************************
		org     bank2_org

bank2		=	$


	;*********************************************************************************
	; Bank 3
	;*********************************************************************************
		org     bank3_org

bank3		=	$

	;*********************************************************************************
	; Bank 4
	;*********************************************************************************
		org     bank4_org

bank4		=	$


	;*********************************************************************************
	; Bank 5
	;*********************************************************************************
		org     bank5_org

bank5		=	$


	;*********************************************************************************
	; Bank 6
	;*********************************************************************************
		org     bank6_org

bank6		=	$


	;*********************************************************************************
	; Bank 7
	;*********************************************************************************
		org     bank7_org

bank7		=	$


IFDEF SX48_52
	;*********************************************************************************
	; Bank 8
	;*********************************************************************************
		org	$80	;bank 8 address on SX52

bank8		=	$


	;*********************************************************************************
	; Bank 9
	;*********************************************************************************
		org	$90	;bank 9 address on SX52

bank9		=	$


	;*********************************************************************************
	; Bank A
	;*********************************************************************************
		org	$A0	;bank A address on SX52BD

bankA		=	$


	;*********************************************************************************
	; Bank B
	;*********************************************************************************
		org	$B0	;bank B address on SX52BD

bankB		=	$


	;*********************************************************************************
	; Bank C
	;*********************************************************************************
		org	$C0	;bank C address on SX52BD

bankC		=	$


	;*********************************************************************************
	; Bank D
	;*********************************************************************************
		org	$D0	;bank D address on SX52BD

bankD		=	$


	;*********************************************************************************
	; Bank E
	;*********************************************************************************
		org	$E0	;bank E address on SX52BD

bankE		=	$


	;*********************************************************************************
	; Bank F
	;*********************************************************************************
		org	$F0	;bank F address on SX52BD

bankF		=	$


ENDIF
        ;*****************************************************************************************
        ; Pin Definitions
        ;*****************************************************************************************

RA_latch	equ	%00000000		;SX18/20/28/48/52 port A latch init;intial value after reset
RA_DDIR		equ	%11111110		;SX18/20/28/48/52 port A DDIR value;0=Output,1=Input
RA_LVL		equ	%11111110		;SX18/20/28/48/52 port A LVL value;0=CMOS,1=TTL
RA_PLP		equ	%00000000		;SX18/20/28/48/52 port A PLP value;0=Enable,1=Disable

RB_latch	equ	%00000000		;SX18/20/28/48/52 port B latch init;intial value affter reset
RB_DDIR		equ	%11111111		;SX18/20/28/48/52 port B DDIR value;0=Output,1=Input
RB_ST		equ	%11111111		;SX18/20/28/48/52 port B ST value;0=Enable,1=Disable
RB_LVL		equ	%00000000		;SX18/20/28/48/52 port B LVL value;0=CMOS,1=TTL
RB_PLP		equ	%00000000		;SX18/20/28/48/52 port B PLP value;0=Enable,1=Disable

RC_latch	equ	%00000000		;SX18/20/28/48/52 port C latch init;intial value affter reset
RC_DDIR		equ	%11111111		;SX18/20/28/48/52 port C DDIR value;0=Output,1=Input
RC_ST		equ	%11111111		;SX18/20/28/48/52 port C ST value;0=Enable,1=Disable
RC_LVL		equ	%00000000		;SX18/20/28/48/52 port C LVL value;0=CMOS,1=TTL
RC_PLP		equ	%00000000		;SX18/20/28/48/52 port C PLP value;0=Enable,1=Disable

IFDEF SX48_52		
RD_latch	equ	%00000000		;SX48/52 port D latch init;intial value affter reset
RD_DDIR		equ	%11111111		;SX48/52 port D DDIR value;0=Output,1=Input
RD_ST		equ	%11111111		;SX48/52 port D ST value;0=Enable,1=Disable
RD_LVL		equ	%00000000		;SX48/52 port D LVL value;0=CMOS,1=TTL
RD_PLP		equ	%00000000		;SX48/52 port D PLP value;0=Enable,1=Disable

RE_latch	equ	%00000000		;SX48/52 port E latch init;intial value affter reset
RE_DDIR		equ	%11111111		;SX48/52 port E DDIR value;0=Output,1=Input
RE_ST		equ	%11111111		;SX48/52 port E ST value;0=Enable,1=Disable
RE_LVL		equ	%00000000		;SX48/52 port E LVL value;0=CMOS,1=TTL
RE_PLP		equ	%00000000		;SX48/52 port E PLP value;0=Enable,1=Disable

ENDIF

        ;*****************************************************************************************
        ; Program Constants
        ;*****************************************************************************************

        int_period          =       163             ; Gives an interrupt period at 50MHz of 3.26us

;----------------------------------------------------------------------------------------------

IFDEF SX48_52
	;*********************************************************************************
	; SX48BD/52BD Mode addresses
	; *On SX48BD/52BD, most registers addressed via mode are read and write, with the
	; exception of CMP and WKPND which do an exchange with W.
	;*********************************************************************************
; Timer (read) addresses
TCPL_R		equ	$00		;Read Timer Capture register low byte
TCPH_R		equ	$01		;Read Timer Capture register high byte
TR2CML_R	equ	$02		;Read Timer R2 low byte
TR2CMH_R	equ	$03		;Read Timer R2 high byte
TR1CML_R	equ	$04		;Read Timer R1 low byte
TR1CMH_R	equ	$05 		;Read Timer R1 high byte
TCNTB_R		equ	$06		;Read Timer control register B
TCNTA_R		equ	$07		;Read Timer control register A

; Exchange addresses
CMP		equ	$08		;Exchange Comparator enable/status register with W
WKPND		equ	$09		;Exchange MIWU/RB Interrupts pending with W

; Port setup (read) addresses
WKED_R		equ	$0A		;Read MIWU/RB Interrupt edge setup, 1 = falling, 0 = rising
WKEN_R		equ	$0B		;Read MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_R		equ	$0C		;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_R		equ	$0D		;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_R		equ	$0E		;Read Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_R		equ	$0F		;Read Port Direction

; Timer (write) addresses
CLR_TMR		equ	$10		;Resets 16-bit Timer
TR2CML_W	equ	$12		;Write Timer R2 low byte
TR2CMH_W	equ	$13		;Write Timer R2 high byte
TR1CML_W	equ	$14		;Write Timer R1 low byte
TR1CMH_W	equ	$15 		;Write Timer R1 high byte
TCNTB_W		equ	$16		;Write Timer control register B
TCNTA_W		equ	$17		;Write Timer control register A

; Port setup (write) addresses
WKED_W		equ	$1A		;Write MIWU/RB Interrupt edge setup, 1 = falling, 0 = rising
WKEN_W		equ	$1B		;Write MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_W		equ	$1C		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_W		equ	$1D		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_W		equ	$1E		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_W		equ	$1F		;Write Port Direction

ELSE

	;****************************************************************************************
	; SX18AC/20AC/28AC Mode addresses
	; *On SX18/20/28, all registers addressed via mode are write only, with the exception of
	; CMP and WKPND which do an exchange with W.
	;****************************************************************************************
; Exchange addresses
CMP		equ	$08		;Exchange Comparator enable/status register with W
WKPND		equ	$09		;Exchange MIWU/RB Interrupts pending with W

; Port setup (read) addresses
WKED_W		equ	$0A		;Write MIWU/RB Interrupt edge setup, 1 = falling, 0 = rising
WKEN_W		equ	$0B		;Write MIWU/RB Interrupt edge setup, 0 = enabled, 1 = disabled
ST_W		equ	$0C		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
LVL_W		equ	$0D		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
PLP_W		equ	$0E		;Write Port Schmitt Trigger setup, 0 = enabled, 1 = disabled
DDIR_W		equ	$0F		;Write Port Direction
ENDIF


;****************************************************************************************************
; Program memory ORG defines
;****************************************************************************************************

INTERRUPT_ORG		equ	$0	; Interrupt must always start at location zero
RESET_ENTRY_ORG		equ	$1FB	; The program will jump here on reset
SUBROUTINES_ORG		equ	$200	; The subroutines are in this location
STRINGS_ORG		equ	$300	; The strings are in the location $300
PAGE3_ORG		equ	$400	; Page 3 is empty
MAIN_PROGRAM_ORG	equ	$600	; The main program is in the lastpage of program memory

;*******************************************************************************************************
;*******************************************************************************************************
		org	INTERRUPT_ORG        ; First location in program memory.
;*******************************************************************************************************

;-------------------------------------------------------------------------------------------------------
; Interrupt Service Routine
;-------------------------------------------------------------------------------------------------------

ISR                                           	; The interrupt service routine....
		mov	w,m			; Save the m register.
		mov	isr_temp,w		;

;********************************************************************************************************
; Interrupt
;
; With a retiw value of -163 and an oscillator frequency of 50MHz, this code runs
; every 3.26us.
;*******************************************************************************************************

;*******************************************************************************************************
PWM_OUTPUT
; This outputs the current value  of pwm0 to the PWM_pin. This generates an analog voltage
; at  PWM_pin after filtering
;*******************************************************************************************************


;VP_begin SINEWAVE
		
		add	swPwm0Acc,swPwm0  	; add the pwm output to the accumulator
		snc
		jmp	:carry         	       	; if there was no carry, then clear the PWM_pin
		clrb	swPwmPin
		jmp	swPwmOut
:carry
		setb	swPwmPin                ; otherwise set the PWM_pin
swPWMOut

;*******************************************************************************************************
sine_generator
; This routine generates a synthetic sine wave with values ranging from -32 to 32.
; Frequency is specified by the counter. 
;*******************************************************************************************************


		_bank	swSinGenBank

		add	swFreqAccLow,swFreqCountLow	; advance sine at frequency
		jnc	:no_carry 			; if lower byte rolls over
		inc	swFreqAccHigh			; carry over to upper byte
		jnz	:no_carry			; if carry causes roll_over
		mov	swFreqAccHigh,swFreqCountHigh	; then add freq counter to accumulator
		jmp	:change_sin
:no_carry
		add	swFreqAccHigh,swFreqCountHigh	; add the upper bytes of the accumulators
		jnc	:no_change
:change_sin
		mov	w,++swSinvel			; if the velocity of sine
		sb	swSin.7				; is positive accelerate
		mov	w,--swSinvel			; it. Otherwise decelerate it.
		mov	swSinvel,w
		add	swSin,w				; add the velocity to sin

		mov	swPwm0,swSin			; mov the value of SIN into the PWM output
		add	swPwm0,#128			; add 128 to put it in the center of the PWM output
:no_change


sin_generator_out

;------------------------------------------------------------------------------------------------------------
;VP:VP Multitasker

                ;--------------------------------------------------------------------------------------------
                ; Virtual Peripheral Multitasker : up to 24 individual threads, each running at the 
                ;                                  (interrupt rate/24). Change the below:
                ;
                ; 	Input variable(s): isr_multiplex: variable used to choose threads
                ; 	Output variable(s): None,executes the next thread
                ; 	Variable(s) affected: isr_multiplex
                ; 	Flag(s) affected: None
                ; 	Program Cycles: 9 cycles (turbo mode)
                ;--------------------------------------------------------------------------------------------
                _bank          isrMultiplex         ;
                inc            isrMultiplex         ; toggle interrupt rate
                mov            w,isrMultiplex       ;
         ; The code between the tableBegin and tableEnd statements MUST be completely within the first
         ; half of a page. The routines it is jumping to must be in the same page as this table.
         tableStart                                 ; Start all tables with this macro
                jmp            pc+w                 ;
                jmp            isrThread1           ;
                jmp            isrThread2           ;
                jmp            isrThread3           ;  
                jmp            isrThread4           ; 
                jmp            isrThread1           ;
                jmp            isrThread5           ;
                jmp            isrThread6           ;  
                jmp            isrThread7           ; 
                jmp            isrThread1           ; 
                jmp            isrThread8           ;
                jmp            isrThread9           ;
                jmp            isrThread10          ;  
                jmp            isrThread1           ; 
                jmp            isrThread11          ; 
                jmp            isrThread12          ;
                jmp            isrThread13          ;
         tableEnd                                   ; End all tables with this macro.   

;----------------------------------------------------------------------------------------------------------
;VP: VP Multitasker
; ISR TASKS
;----------------------------------------------------------------------------------------------------------
isrThread1                                          ; Serviced at ISR rate/4
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution

;----------------------------------------------------------------------------------------------------------
isrThread2                                         ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution

;----------------------------------------------------------------------------------------------------------
isrThread3                                          ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread4                                          ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread5                                          ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread6                                          ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread7                                          ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread8                                          ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread9                                          ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread10                                         ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread11                                         ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread12                                         ; Serviced at ISR rate/16
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
;----------------------------------------------------------------------------------------------------------
isrThread13                                         ; Serviced at ISR rate/16
                                                    ; This thread must reload the isrMultiplex register
  
;----------------------------------------------------------------------------------------------------------

                jmp            isrout               ; 7 cycles until mainline program resumes execution
						    ; This thread must reload the isrMultiplex register
                                                    ; since it is the last one to run in a rotation.
;----------------------------------------------------------------------------------------------------------

                _bank           isrMultiplex
                mov            isrMultiplex,#255    ; reload isrMultiplex so isrThread1 will be run on the
                                                    ; next interrupt.
                jmp            isrout
;----------------------------------------------------------------------------------------------------------

;----------------------------------------------------------------------------------------------------------
isrOut
;************************************************************************************************************

:ISR_DONE
; This is the end of the interrupt service routine. Now load 163 into w and perform a retiw to interrupt
; 163 cycles from the start of this one.
; (3.26us@50MHz)
;**************************************************************************************************************
		mov	w,isr_temp			;Restore the m register.
		mov	m,w				;

		mov	w,#-int_period			; interrupt 163 cycles after this interrupt
		retiw					; return from the interrupt   
;VP_end 

;****************************************************************************************
org 	RESET_ENTRY_ORG
;*****************************************************************************************
	

 resetEntry						; Program starts here on power-up
		page 	_resetEntry
		jmp	_resetEntry
;-----------------------------------------------------------------------------------------

;*****************************************************************************************
org    SUBROUTINES_ORG
;*****************************************************************************************
;  Subroutines
;*****************************************************************************************



;******************************************************************************************
org    STRINGS_ORG     ; This label defines where strings are kept in program space.
;******************************************************************************************

;------------------------------------------------------------------------------------------
; Put String Data Here
;------------------------------------------------------------------------------------------


; Example:
; _hello            dw        13,10,'UART Demo',0


;*******************************************************************************************
org PAGE3_ORG
;*******************************************************************************************

      jmp        $           ; This instruction will cause an assembler error if the source
                             ; code before the org statement inadvertantly crosses a page
                             ; boundary.




;*****************************************************************************************
		org 	MAIN_PROGRAM_ORG
;*****************************************************************************************
;-----------------------------------------------------------------------------------------
; RESET VECTOR
;-----------------------------------------------------------------------------------------
        ;---------------------------------------------------------------------------------
        ; Program execution begins here on power-up or after a reset
        ;---------------------------------------------------------------------------------
_resetEntry

	;*********************************************************************************
	; Initialise all port configuration
	;*********************************************************************************

		_mode	ST_W			;point MODE to write ST register
		mov     w,#RB_ST            	;Setup RB Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rb,w		
		mov     w,#RC_ST            	;Setup RC Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rc,w	
IFDEF SX48_52
		mov     w,#RD_ST            	;Setup RD Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rd,w		
		mov     w,#RE_ST            	;Setup RE Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!re,w		
ENDIF
		_mode	LVL_W			;point MODE to write LVL register
		mov     w,#RA_LVL            	;Setup RA CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!ra,w		 
		mov     w,#RB_LVL            	;Setup RB CMOS or TTL levels, 1 = TTL, 0 = CMOS,  0,1 = TTL, 2..7 = CMOS
		mov	!rb,w		
		mov     w,#RC_LVL            	;Setup RC CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!rc,w	
IFDEF SX48_52
		mov     w,#RD_LVL            	;Setup RD CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!rd,w		
		mov     w,#RE_LVL            	;Setup RE CMOS or TTL levels, 1 = TTL, 0 = CMOS
		mov	!re,w		
ENDIF
		_mode	PLP_W			;point MODE to write PLP register
		mov     w,#RA_PLP            	;Setup RA Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!ra,w		 
		mov     w,#RB_PLP            	;Setup RB Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rb,w		
		mov     w,#RC_PLP            	;Setup RC Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rc,w	
IFDEF SX48_52
		mov     w,#RD_PLP            	;Setup RD Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rd,w		
		mov     w,#RE_PLP            	;Setup RE Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!re,w		
ENDIF
		_mode	DDIR_W			;point MODE to write DDIR register
		mov	w,#RA_DDIR		;Setup RA Direction register, 0 = output, 1 = input		
		mov	!ra,w	
		mov	w,#RB_DDIR		;Setup RB Direction register, 0 = output, 1 = input
		mov	!rb,w			
		mov	w,#RC_DDIR		;Setup RC Direction register, 0 = output, 1 = input
		mov	!rc,w			
IFDEF SX48_52
		mov	w,#RD_DDIR		;Setup RD Direction register, 0 = output, 1 = input
		mov	!rd,w			
		mov	w,#RE_DDIR		;Setup RE Direction register, 0 = output, 1 = input
		mov	!re,w			
ENDIF
		mov     w,#RA_latch          	;Initialize RA data latch
		mov     ra,w		
		mov     w,#RB_latch         	;Initialize RB data latch
		mov     rb,w		
		mov     w,#RC_latch          	;Initialize RC data latch
		mov     rc,w		
IFDEF SX48_52
		mov     w,#RD_latch         	;Initialize RD data latch
		mov     rd,w			
		mov     w,#RE_latch         	;Initialize RE data latch
		mov     re,w			
ENDIF

	;*********************************************************************************
	; Clear all Data RAM locations
	;*********************************************************************************
IFDEF SX48_52   				;SX48/52 RAM clear routine
		mov	w,#$0a			;reset all ram starting at $0A
		mov	fsr,w
:zero_ram	clr	ind			;clear using indirect addressing
		incsz	fsr			;repeat until done
		jmp	:zero_ram

		_bank	bank0			;clear bank 0 registers
		clr	$10
		clr	$11
		clr	$12
		clr	$13
		clr	$14
		clr	$15
		clr	$16
		clr	$17
		clr	$18
		clr	$19
		clr	$1a
		clr	$1b
		clr	$1c
		clr	$1d
		clr	$1e
		clr	$1f

ELSE     					;SX18/20/28 RAM clear routine
		clr	fsr			;reset all ram banks
:zero_ram	sb	fsr.4			;are we on low half of bank?
		setb	fsr.3			;If so, don't touch regs 0-7
		clr	ind			;clear using indirect addressing
		incsz	fsr			;repeat until done
		jmp	:zero_ram
ENDIF

	;*********************************************************************************
	; Initialize program/VP registers
	;*********************************************************************************

	;*********************************************************************************
	; Setup and enable RTCC interrupt, WREG register, RTCC/WDT prescaler
	;*********************************************************************************

RTCC_ON		=	%10000000	;Enables RTCC at address $01 (RTW hi)
					;*WREG at address $01 (RTW lo) by default
RTCC_ID		=	%01000000	;Disables RTCC edge interrupt (RTE_IE hi)
					;*RTCC edge interrupt (RTE_IE lo) enabled by default
RTCC_INC_EXT	=	%00100000	;Sets RTCC increment on RTCC pin transition (RTS hi)
					;*RTCC increment on internal instruction (RTS lo) is default
RTCC_FE		=	%00010000	;Sets RTCC to increment on falling edge (RTE_ES hi)
					;*RTCC to increment on rising edge (RTE_ES lo) is default
RTCC_PS_ON	=	%00000000	;Assigns prescaler to RTCC (PSA lo)
RTCC_PS_OFF	=	%00001000	;Assigns prescaler to RTCC (PSA lo)
PS_000		=	%00000000	;RTCC = 1:2, WDT = 1:1
PS_001		=	%00000001	;RTCC = 1:4, WDT = 1:2
PS_010		=	%00000010	;RTCC = 1:8, WDT = 1:4
PS_011		=	%00000011	;RTCC = 1:16, WDT = 1:8
PS_100		=	%00000100	;RTCC = 1:32, WDT = 1:16
PS_101		=	%00000101	;RTCC = 1:64, WDT = 1:32
PS_110		=	%00000110	;RTCC = 1:128, WDT = 1:64
PS_111		=	%00000111	;RTCC = 1:256, WDT = 1:128


OPTIONSETUP    	equ	RTCC_PS_OFF | PS_111 | RTCC_FE	; the default option setup for this program.
		mov	w,#OPTIONSETUP			; setup option register for RTCC interrupts enabled
		mov	!option,w                       ; and no prescaler.
                jmp     @main

;*****************************************************************************************
; MAIN PROGRAM CODE 
;*****************************************************************************************

	;*********************************************************************************
	; Main
	;*********************************************************************************
main		

;VP_begin SINEWAVE

		_bank	swSinGenBank
		mov	swSin,#32			; init variables. A sine wave starts at 1,
							; A cos wave starts at 0.
		mov	swSinvel,#0

;**************************************************************************************************
; Comment the above two instructions and uncomment the below two instruction to have a sine wave
;**************************************************************************************************
;		mov	swSin,#-4			; use these values for a wave which is                                                        ; 90 degrees out of phase.
;		mov	swSinvel,#-8			; 90 degrees out of phase.
		mov	swFreqCountHigh,#f1300_h
		mov	swFreqCountLow,#f1300_l		; set up variables for 1300 Hz.


	;*********************************************************************************
	; Main Program Loop
	;*********************************************************************************
main_loop
		jmp	main_loop			;do nothing (interrupts will handle the rest)

;VP_end

;**************************************************************************************************
END                   ;End of program code
;**************************************************************************************************
;**************************************************************************************************
;**************************************************************************************************
;**************************************************************************************************