please dont rip this site

Source Code

;
; Filename:
;		sxohm_src
;
; Authors:
;		Troy Duncan
;		
;		
;
; Revision:
;		0.0.1
;
; Target Part(s):
;		
; 		
;
; Default Oscillator Frequency:
;		50MHz
;
; Assemblers:
;		SXKey28L Version 1.09 for SX18/20/28AC
;		SXKey52 Version 1.19 for SX48/52BD
;		SASM Version 1.45.2
;
; Date Written:
;		April 19, 2002
;
; Program Description:
;
;		
;		
;
; Interface Pins:
;
;       I/O Count:	13
;
;	fgIoPin		equ	ra.0	; 2Khz tone ouput
;				rb.0	; tone input from line
;				rb.1	; tone input from line
;				rb.2	; tone input from line
;				rb.3	; tone input from line
;	pbx0DisconPin	equ	rb.4	; PBX Disconnect
;	ohd0ConPin	equ	rb.5	; On hold device switch
;	pbx1DisconPin	equ	rb.6	; PBX Disconnect
;	ohd1ConPin	equ	rb.7	; On hold device switch
;	
;	pbx2DisconPin	equ	rc.0	; PBX Disconnect
;	ohd2ConPin	equ	rc.1	; On hold device switch
;	pbx3DisconPin	equ	rc.2	; PBX Disconnect
;	ohd3ConPin	equ	rc.3;	; On hold device switch
;
; Revision History:
;
;		
;		       								  
; Virtual Peripherals:
;
;		VP Scheduler
;		VP PWM
;		VP Frequency measurement
;*****************************************************************************************
; Target SX
; Uncomment one of the following lines to choose the SX18AC, SX20AC, SX28AC, 
; SX48BD, or SX52BD.
;*****************************************************************************************
;SX18_20
SX28
;SX48_52

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

;*****************************************************************************************
; Runnable Demo?
; Uncomment the following line to enable the main program, creating a runnable demo
;*****************************************************************************************
DEMO

	;*********************************************************************************
	; 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
;VP_BEGIN: Frequency Measurement
	watch	fmGate,16,udec
	watch   fmFreq0,16,udec
	watch   fmFreq1,16,udec
	watch   fmFreq2,16,udec
	watch   fmFreq3,16,udec
	watch   fmCounter0,16,udec
	watch   fmCounter1,16,udec
	watch   fmCounter2,16,udec
	watch   fmCounter3,16,udec



;VP_END: Frequency Measurement
  IFDEF SX18_20				;SX18AC or SX20AC device directives for SX-Key
		device	SX18L,oschs2,turbo,stackx_optionx
  ENDIF
  IFDEF SX28				;SX28AC device directives for SX-Key		
		device	SX28L,oschs2,turbo,stackx_optionx
  ENDIF
  IFDEF SX48_52				;SX48/52/BD device directives for SX-Key
		device	oschs2
  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 SX28				;SX28AC device directives for SASM
		device	SX28,oschs2,turbo,stackx,optionx
  ENDIF
  IFDEF SX48_52				;SX48BD or SX52BD device directives for SASM
		device	SX52,oschs2
  ENDIF
ENDIF

		id	'DTMFG_13'	; Version = 1.3.2
		reset	resetEntry	; set reset vector

;*****************************************************************************************
; Macros
;*****************************************************************************************
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;
	;	To support compatibility between source code written for the SX28 and the SX52,
	;	use 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.7
	; (SX48/52bd production release) needs to be set appropriately, depending
	; on the bank address being accessed.
	;
	; So, instead of using the bank instruction to switch between banks, use _bank instead.
	; 
	;*********************************************************************************

_bank	macro	1
	bank	\1

	IFDEF SX48_52
	    IF \1 & %10000000		;SX48BD and SX52BD (production release) bank instruction 
		setb	fsr.7		;modifies FSR bits 4,5 and 6. FSR.7 needs to be set by software.
	    ELSE
		clrb	fsr.7
	    ENDIF
	ENDIF
	endm


	;*****************************************************************************************
	; Macros for SX28/52 Compatibility
	;*****************************************************************************************
	;*********************************************************************************
	; 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
	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
  noexpand					;and SX28AC
	ENDIF
	endm

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

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;
	;   	To support compatibility between source code written for the SX28 and the SX52,
	;	use macros.  This macro compensates for the fact that RAM banks are contiguous in
	;	the SX52, but separated by 0x20 in the SX18/28.
	;
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

INCP	macro	1
		inc	\1
	IFNDEF	SX48_52
		setb	\1.4		; If SX18,20 or SX28, keep bit 4 of the pointer = 1
	ENDIF				; to jump from $1f to $30, etc.
endm
		
DECP	macro	1
	IFDEF	SX48_52
		dec	\1
	ELSE
		clrb	\1.4		; If SX18,20 or SX28, 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 unintentionally moved into the 
	; second half of a page.  Use for lookup tables.
	;*****************************************************************************************

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;
	;   	Surround lookup tables with the tableStart and tableEnd macros.  An error will
	;	be generated on assembly if part of the table is in the second half of a page.
	;	
	;	Example:
	;		lookupTable1
	;			add	pc,w	; Add w register to program counter
	;		tableStart
	;			retw	0
	;			retw	4
	;			retw	8
	;			retw	4
	;		tableEnd
	;
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

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
;*****************************************************************************************
; Global Register definitions
; NOTE: Global data memory starts at $0A on SX48/52 and $08 on SX18/20/28.
;*****************************************************************************************

		org	global_org

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;
	;   	Use only these defined label types for global registers.  If an extra temporary 
	;	register is required, adhere to these label types.  For instance, if two temporary
	;	registers are required for the Interrupt Service Routine, use the labels isrTemp0
	;	and isrTemp1.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

flags0		equ	global_org + 0  ; stores bit-wise operators like flags 
					; and function-enabling bits (semaphores)
				
localTemp0	equ	global_org + 1		; Used by Frequency Measurement VP
localTemp1	equ	global_org + 2		; Used by Frequency Measurement VP
localTemp2	equ	global_org + 3	
localTemp3	equ	global_org + 4	
localTemp4	equ	global_org + 5

;VP_BEGIN : Frequency Measurement
fmGate		equ	global_org + 6
;VP_END : Frequency Measurement

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

	;*********************************************************************************
	; Bank 0
	;*********************************************************************************
		org     bank0_org
bank0		=	$

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	; 	- Avoid using bank0 in programs written for SX48/52.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

	;*********************************************************************************
	; Bank 1
	;*********************************************************************************
		org     bank1_org
bank1		=	$
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;
	;	Tip 1:
	;	Indicate which Virtual Peripherals a portion of source code or declaration belongs
	;	to with a ;VP_BEGIN: VirtualPeripheralName and VP_END: comment.
	;
	;	Tip 2:
	;	All RAM location declaration names should be
	;   	- left justified
	;	- less than 2 tabs in length
	;	- written in hungarian notation
	;	- prefixed by a truncated version of the Virtual Peripheral's name
	;	
	;	Examples:
	;
	;	;VP_BEGIN: RS232 Transmit
	;	rs232TxBank	=       $	;UART Transmit bank
	;	rs232TxHigh	ds      1	;hi byte to transmit
	;	rs232TxLow	ds      1	;low byte to transmit
	;	rs232TxCount	ds      1	;number of bits sent
	;	rs232TxDivide	ds      1	;xmit timing (/16) counter
	;	;VP_END: RS232 Transmit
	;
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

;VP_BEGIN: VP Scheduler
isrMultiplex	ds	1	; The isrMultiplex register is used to switch to a new
;VP_END: VP Scheduler		; execution thread on each pass of the ISR.




	;*********************************************************************************
	; Bank 2
	;*********************************************************************************
		org	bank2_org
bank2		=	$

;VP_BEGIN : Fgen
FgenBank	=	$
fgSet		DS	2
fgCnt		DS	2
fgSetLo		=	$58
fgSetHi		=	$59
fgCntLo		=	$5A
fgCntHi		= 	$5B
;VP_END   : Fgen

;VP_BEGIN Frequency Measurement
fmVar2		DS	2
;VP_END Frequency Measurement

	;*********************************************************************************
	; Bank 3
	;*********************************************************************************
		org	bank3_org
bank3		=	$
;VP_BEGIN Frequency Measurement
fmesBank	=	$
fmFreq0		DS	2
fmFreq1		DS	2
fmFreq2		DS	2
fmFreq3		DS	2
fmCounter0	DS	2
fmCounter1	DS	2
fmCounter2	DS	2
fmCounter3	DS	2
;VP_END


	;*********************************************************************************
	; 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		=	$
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	; 	- This extra memory is not available in the SX18/28, so don't use it for Virtual
	;	  Peripherals written for both platforms.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	;*********************************************************************************
	; Bank 9
	;*********************************************************************************
		org	$90	;bank 9 address on SX52
bank9		=	$
	;*********************************************************************************
	; Bank A
	;*********************************************************************************
		org	$A0	;bank A address on SX52
bankA		=	$
	;*********************************************************************************
	; Bank B
	;*********************************************************************************
		org	$B0	;bank B address on SX52
bankB		=	$
	;*********************************************************************************
	; Bank C
	;*********************************************************************************
		org	$C0	;bank C address on SX52
bankC		=	$
	;*********************************************************************************
	; Bank D
	;*********************************************************************************
		org	$D0	;bank D address on SX52
bankD		=	$
	;*********************************************************************************
	; Bank E
	;*********************************************************************************
		org	$E0	;bank E address on SX52
bankE		=	$
	;*********************************************************************************
	; Bank F
	;*********************************************************************************
		org	$F0	;bank F address on SX52
bankF		=	$
ENDIF
	;*********************************************************************************
	; Pin Definitions:
	;*********************************************************************************

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	; 	- Store all initialization constants for the I/O in the same area, so
	;	  pins can be easily moved around.
	;	- Pin definitions should follow the same format guidelines as RAM definitions
	;		- Left justified
	;		- No underscores.  Indicate word separation with capital letters
	;		- Less that 2 tabs in length
	;		- Indicate the Virtual Peripheral the pin is used for
	;		- All pin definitions for a specific VP must have the same prefix
	;	- Only use symbolic names to access a pin/port in the source code.
	;	- Example:
	;		; VP_BEGIN: RS232 Transmit
	;			rs232TxPin	equ	ra.3
	;		; VP_END: RS232 Transmit
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?


     ;VP_BEGIN : Fgen
	 fgIoPin	equ	ra.0
     ;VP_END

    ;VP_BEGIN
	pbx0DisconPin	equ	rb.4
	ohd0ConPin	equ	rb.5
	pbx1DisconPin	equ	rb.6
	ohd1ConPin	equ	rb.7
	
	pbx2DisconPin	equ	rc.0
	ohd2ConPin	equ	rc.1
	pbx3DisconPin	equ	rc.2
	ohd3ConPin	equ	rc.3

    ;VP_END


RA_latch	equ	%00000100		;SX18/20/28/48/52 port A latch init
RA_DDIR		equ	%11111000		;SX18/20/28/48/52 port A DDIR value
RA_LVL		equ	%00000000		;SX18/20/28/48/52 port A LVL value
RA_PLP		equ	%11111111		;SX18/20/28/48/52 port A PLP value

RB_latch	equ	%00000000		;SX18/20/28/48/52 port B latch init
RB_DDIR		equ	%00001111		;SX18/20/28/48/52 port B DDIR value
RB_ST		equ	%11111111		;SX18/20/28/48/52 port B ST value
RB_LVL		equ	%00000000		;SX18/20/28/48/52 port B LVL value
RB_PLP		equ	%11111111		;SX18/20/28/48/52 port B PLP value


IFNDEF	SX18_20	; There is no C port on SX18/20
RC_latch	equ	%00000000		;SX18/20/28/48/52 port C latch init
RC_DDIR		equ	%11100000		;SX18/20/28/48/52 port C DDIR value
RC_ST		equ	%11111111		;SX18/20/28/48/52 port C ST value
RC_LVL		equ	%00000000		;SX18/20/28/48/52 port C LVL value
RC_PLP		equ	%11111111		;SX18/20/28/48/52 port C PLP value

IFDEF SX48_52	;SX48BD/52BD Port initialization values
RD_latch	equ	%00000000		;SX48/52 port D latch init
RD_DDIR		equ	%11111111		;SX48/52 port D DDIR value
RD_ST		equ	%11111111		;SX48/52 port D ST value
RD_LVL		equ	%00000000		;SX48/52 port D LVL value
RD_PLP		equ	%11111111		;SX48/52 port D PLP value

RE_latch	equ	%00000000		;SX48/52 port E latch init
RE_DDIR		equ	%11111111		;SX48/52 port E DDIR value
RE_ST		equ	%11111111		;SX48/52 port E ST value
RE_LVL		equ	%00000000		;SX48/52 port E LVL value
RE_PLP		equ	%11111111		;SX48/52 port E PLP value
ENDIF	;(SX18_20)
ENDIF	;(SX48_52)

;*****************************************************************************************
; Program constants
;*****************************************************************************************

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;	To calculate the interrupt period in cycles:
	;	- First, choose the desired interrupt frequency
	;		- Should be a multiple of each Virtual Peripherals sampling frequency.
	;		- Example:  19200kHz UART sampling rate * 16 = 307.200kHz
	;	- Next, choose the desired oscillator frequency.
	;		- 50MHz, for example.
	;	- Next calculate the 
	;	- Perform the calculation intPeriod = (cyclesPerSecond / interruptFrequency)
	;				  		= (50MHz / 307.2kHz)
	;						= 162.7604
	;	- Round intPeriod to the nearest integer:
	;						= 163
	;	- Now calculate your actual interrupt rate:
	;						= cyclesPerSecond / intPeriod
	;						= 50MHz / 163
	;						= 306.748kHz
	;	- This interrupt frequency will be the timebase for all of the Virtual 
	;	  Peripherals
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

intPeriod	=	125	
				

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;	- Include all calculations for Virtual Peripheral constants for any sample 
	;	  rate.
	;	- Relate all Virtual Peripheral constants to the sample rate of the Virtual
	;	  Peripheral.
	;	- Example:
	;		; VP_BEGIN: 5ms Timer
	;		TIMER_DIV_CONST	equ 192	; This constant = timer sample rate/200Hz = 192
	;		; VP_END: 5ms Timer
	;
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?



;-------------------------------------------------------------------------------------
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, 0 = falling, 1 = 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 Level setup, 0 = CMOS, 1 = TTL
PLP_R		equ	$0E		;Read Port Weak Pullup setup, 0 = enabled, 1 = disabled
DDIR_R		equ	$0F		;Read Port Direction

; Timer (write) addresses
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, 0 = falling, 1 = 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 Level setup, 0 = CMOS, 1 = TTL
PLP_W		equ	$1E		;Write Port Weak Pullup 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, 0 = falling, 1 = 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	;(SX48_52)


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

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	; 	- Place a table at the top of the source with the starting addresses of all of
	;	  the components of the program.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

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 location $300
PAGE3_ORG		equ	$400	; Page 3 is empty
MAIN_PROGRAM_ORG	equ	$600	; The main program is in the last page of program memory.










;****************************** Beginning of program space *******************************
	org	INTERRUPT_ORG			; First location in program memory.
;*****************************************************************************************
;------------------------------------------------------------------------------
; Interrupt Service Routine
;------------------------------------------------------------------------------
; Note: The interrupt code must always originate at address $0.
;
; Interrupt Frequency = OSC Frequency / ((-retiw value)*RTCC Prescaler)  For example:
; With a retiw value of -163, a prescaler of 1, and an oscillator frequency of 50MHz,
; this Interrupt Routine runs every 3.26us.
;------------------------------------------------------------------------------
ISR					;3	The interrupt service routine...

;------------------------------------------------------------------------------
;VP_BEGIN: VP Scheduler

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	; - Schedule tasks in the Interrupt Service Routine
	;	- Produces a FAR smaller worst-case cycle time count, and enables a larger number
	;	  of VP's to run simultaneously.  Also produces "empty" slots that future VP's 
	;	  can be copied and pasted into easily.
	;	- Determine how often your tasks need to run.  (9600bps UART can run well at a 
	;	  sampling rate of only 38400Hz, so don't run it faster than this.)
	;	- Strategically place each "module" into the threads of the Scheduler.  If a 
	;	  module must be run more often, just call it's module at double the rate or
	;	  quadruple the rate, etc.…
	;	- Split complicated Virtual Peripherals into several modules, keeping the 
	;	  high-speed portions of the Virtual Peripherals as small and quick as possible, 
	;	  and run the more complicated, slower processing part of the Virtual Peripheral 
	;	  at a lower rate.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	;------------------------------------------------------------------------------
	; Virtual Peripheral Scheduler:  up to 16 individual threads, each running at
	;				   the interrupt rate/16.  Change the table
	;				   to modify the rate at which each of the threads
	;				   is run.
	;
	;	Input variable(s): 		isrMultiplex: variable used to choose threads
	;	Output variable(s): 		None, executes the next thread
	;	Variable(s) affected: 		isrMultiplex
	;	Flag(s) affected: 		None
	;	Program Cycles:			10 cycles (turbo mode SX52)
	;------------------------------------------------------------------------------
	_bank	isrMultiplex		;1 (2)
	inc	isrMultiplex		;1		; toggle interrupt rates
	mov	w,isrMultiplex		;1
; 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			;3
	jmp	isrThread1		; isrThread1 runs the Frequency Generator
	jmp	isrThread2		; isrThread2 runs the Frequency Measurement VP
	jmp	isrThread3		; isrThread3 called but not in this implementation
	jmp	isrThread4		; isrThread4 called but not in this implementation
	jmp	isrThread13		; isrThread13 called but not in this implementation
	jmp	isrThread5		; -- these are not used. ----
	jmp	isrThread6		;
	jmp	isrThread7		;
	jmp	isrThread8		;
	jmp	isrThread9		;
	jmp	isrThread10		;
	jmp	isrThread11		;
	jmp	isrThread12		;
	jmp	isrThread13		;
	jmp	isrThread13		;
	jmp	isrThread13		;
tableEnd				; End all tables with this macro.
;VP_END: VP Scheduler

;------------------------------------------------------------------------------
;VP_BEGIN: VP Scheduler
; ISR TASKS
;------------------------------------------------------------------------------
isrThread1		; Serviced at ISR rate / 5
;------------------------------------------------------------------------------
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	; 	The sample rate of this section of code is the isr rate / 5, because it is jumped
	;	to in every 4th entry in the VP Schedulers table.  To increase the
	;	sample rate, put more calls to this thread in the Scheduler's jump table.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;VP_BEGIN : Fgen
		_bank	FgenBank
		test	fgCntLo
		sz
		jmp	_x2
		test	fgCntHi
		snz
		jmp	_x1

_x2
		_bank	FgenBank
		mov	w, #1
		sub	fgCntLo, w
		sc
		dec	fgCntHi
		jmp	@fGen1L

_x1
		_bank	FgenBank
		mov	w, fgSet
		mov	fgcnt, w
		mov	w, fgSetHi
		mov     fgCntHi, w
		sb	fgIoPin
		jmp	_x3
		clrb	fgIoPin	
		skip

_x3
		setb	fgIoPin
fGen1L
;VP_END : Fgen


	jmp	isrOut			;7 cycles until mainline program resumes execution
						
;------------------------------------------------------------------------------
isrThread2		; Serviced at ISR rate / 4
;------------------------------------------------------------------------------
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral:
	; 	The VP measures the Frequency on all four ports pins.
	;	
	;	
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?

;VP_BEGIN : Frequency Measurement

		_bank	fmesBank
		test	fmGate
		sz	
		jmp	_fmX2
		test	fmGate+1
		snz
		jmp	_fmX10
_fmX2
		mov	w, #1
		sub	fmGate, w
		sc
		dec	fmGate+1
		jmp	@fmes1L

;--------------------------------------------------------
; Process Counter for Port RB.0 
;--------------------------------------------------------
_fmX10
		_bank	fmesBank
		mov	w, fmCounter0
		mov	fmFreq0, w
		mov	w, fmCounter0+1
		mov	fmFreq0+1, w
		clr	fmCounter0
		clr	fmCounter0+1
		
;--------------------------------------------------------
; Process Counter for Port RB.1 
;--------------------------------------------------------
		_bank	fmesBank
		mov	w, fmCounter1
		mov	fmFreq1, w
		mov	w, fmCounter1+1
		mov	fmFreq1+1, w
		clr	fmCounter1
		clr	fmCounter1+1

;--------------------------------------------------------
; Process Counter for Port RB.2 
;--------------------------------------------------------

		mov	w, fmCounter2
		mov	fmFreq2, w
		mov	w, fmCounter2+1
		mov	fmFreq2+1, w
		clr	fmCounter2
		clr	fmCounter2+1

;--------------------------------------------------------
; Process Counter for Port RB.3 
;--------------------------------------------------------
		mov	w, fmCounter3
		mov	fmFreq3, w
		mov	w, fmCounter3+1
		mov	fmFreq3+1, w
		clr	fmCounter3
		clr	fmCounter3+1

;--------------------------------------------------------
; reload Gate counter
;--------------------------------------------------------
		mov	fmGate, #$10
		mov	fmGate+1, #$27
		sub	fmGate, #1
		sc
		dec	fmGate+1
fmes1L		
	
;VP_END   : Frequency Measurement


;VP_BEGIN : Frequency Measurement

	;-----------------------------------------
	;Check RB PORTS Edge detection status
	;-----------------------------------------
		_bank	fmesBank
		mov	w, m
		mov	localTemp0, w
		clr	w
		mov	m, #9
		mov	!rb, w
		mov	localTemp1, w
		
	; Do Port RB.0
	;-----------------------------------------
		_bank	fmesBank
		sb	LocalTemp1.0
		jmp	fmRb0Done		
		inc	fmCounter0
		snz
		inc	fmCounter0+1
fmRb0Done		
	; Do Port RB.1
	;-----------------------------------------
		_bank   fmesBank
		sb	LocalTemp1.1
		jmp	fmRb1Done		
		inc	fmCounter1
		snz
		inc	fmCounter1+1
fmRb1Done
	; Do Port RB.2
	;-----------------------------------------
		sb	LocalTemp1.2
		jmp	fmRb2Done		
		inc	fmCounter2
		snz
		inc	fmCounter2+1
fmRb2Done
	; Do Port RB.3
	;-----------------------------------------
		sb	LocalTemp1.3
		jmp	fmRb3Done
		inc	fmCounter3
		snz
		inc	fmCounter3+1
fmRb3Done

	;clear pending and reset the mode register
	;-----------------------------------------
		clr	w
		mov	!rb,w
		mov	w, localTemp0
		mov	m, w

;VP_END : Frequency Measurement

	jmp	isrOut			;7 cycles until mainline program resumes execution
	

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

	jmp	isrOut			;7 cycles until mainline program resumes execution

;------------------------------------------------------------------------------
isrThread4		; Serviced at ISR rate / 4
;------------------------------------------------------------------------------

	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
;------------------------------------------------------------------------------

		
;------------------------------------------------------------------------------
;Do timers and return from interrupt.
;------------------------------------------------------------------------------
		

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	; 	The final thread in the ISR Multi-Threader must load the isrMultiplex 
	; 	register with a value of 255, so it will roll-over to 0 on the next ISR.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	bank	isrMultiplex		;1/2
	mov	w,#255			;1 Reload isrMultiplex so isrThread1 will be run
	mov	isrMultiplex,w		;1 on next interrupt.

	jmp	isrOut			;7
;VP_END: VP Scheduler
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
isrOut
;------------------------------------------------------------------------------
	mov	w,#-intPeriod	;1	; return and add -intPeriod to the RTCC
	retiw			;3	; using the retiw instruction.
	
;------------------------------------------------------------------------------


;*****************************************************************************************
org	RESET_ENTRY_ORG
;*****************************************************************************************
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;	The main program operation should be easy to find, so place it at the end of the 
	;	program code.  This means that if the first page is used for anything other than 
	;	main program source code, a resetEntry must be placed in the first page, along 
	;	with a 'page' instruction and a 'jump' instruction to the beginning of the 
	;	main program, wherever that may be.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;------------------------------------------------------------------------------
resetEntry					; Program starts here on power-up
	page	_resetEntry
	jmp	_resetEntry
;------------------------------------------------------------------------------



	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;	ORG statements should use predefined labels rather than literal values.
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
org	SUBROUTINES_ORG

;*****************************************************************************************
; Subroutines
;*****************************************************************************************
sxoh_Switch

	mov	w, fmGate
	mov 	localTemp2 , w
	mov 	w, #1
	mov 	w, localTemp2 -w
	not 	w
	snb 	3.2
	jmp 	label_0001
	mov 	w, #0
	jmp 	label_0002
label_0001
	mov 	w, fmGate+1
	mov 	localTemp2 , w
	mov 	w, #1
	mov 	w, localTemp2 -w
	not 	w
	mov 	w, #1
	sb 	3.2
	clr 	w
label_0002
	and 	w, #255
	snb 	3.2
	jmp 	label_0000
	mov 	w, localTemp3
	mov 	localTemp2 , w
	mov 	w, #245
	mov 	w, localTemp2 -w
	not 	w
	snb 	3.2
	jmp 	label_0004
	mov 	w, #0
	jmp 	label_0005
label_0004
	mov 	w, localTemp3+1
	mov 	localTemp2 , w
	mov 	w, #2
	mov 	w, localTemp2 -w
	not 	w
	mov 	w, #1
	sb 	3.2
	clr 	w
label_0005
	and 	w, #255
	snb 	3.2
	jmp 	label_0003
	_bank	fmVar2
	mov	w, fmVar2
	jmp	pc+w			; selects the current line
	jmp	Line0Cntrl
	jmp	Line1Cntrl
	jmp	Line2Cntrl

; seizes telephone and connect on hold messaging device
;--------------------------------------------------------
	; last line 
	setb 	pbx3DisconPin
	setb	ohd3ConPin
	jmp 	label_0006
Line0Cntrl
	setb 	pbx0DisconPin
	setb	ohd0ConPin
	jmp	label_0006
Line1Cntrl
	setb 	pbx1DisconPin
	setb	ohd1ConPin
	jmp	label_0006
Line2Cntrl
	setb 	pbx2DisconPin
	setb	ohd2ConPin
	jmp	label_0006

; Normalize PBX telephone line state
;---------------------------------------
label_0003
	_bank	fmVar2
	mov	w, fmVar2
	jmp	pc+w			; selects the current line
	jmp	Line00Cntrl
	jmp	Line01Cntrl
	jmp	Line02Cntrl

	clrb 	pbx3DisconPin
	clrb	ohd3ConPin
	jmp	label_0006
Line00Cntrl
	clrb 	pbx0DisconPin
	clrb	ohd0ConPin
	jmp	label_0006
Line01Cntrl
	clrb 	pbx1DisconPin
	clrb	ohd1ConPin
	jmp	label_0006
Line02Cntrl
	clrb 	pbx2DisconPin
	clrb	ohd2ConPin
	jmp	label_0006
label_0006
label_0000
	retp
sxoh_Switch_end

	
;*****************************************************************************************
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

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	; 	- Routines that use location-dependant data, such as in example below, should
	;	  use a LABEL rather than a literal value as their input.  Example:
	;	  instead of
	;		mov     m,#3		 ; move upper nybble of address of strings into m
	;	  use
	;		mov	m,#STRINGS_ORG>>8; move upper nybble of address of strings into m
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?




;*****************************************************************************************
org	PAGE3_ORG
;*****************************************************************************************
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;	To ensure that several Virtual Peripherals, when pasted together, do not cross 
	;	a page boundary without the integrator's knowledge, put an ORG statement and one 
	;	instruction at every page boundary.  This will generate an error if a pasted 
	;	subroutine moves another subroutine to a page boundary.  
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	



;*****************************************************************************************
org	MAIN_PROGRAM_ORG
;*****************************************************************************************



;------------------------------------------------------------------------------
; RESET VECTOR 
;------------------------------------------------------------------------------

	;------------------------------------------------------------------------------
	; Program execution begins here on power-up or after a reset
	;------------------------------------------------------------------------------

_resetEntry
	;------------------------------------------------------------------------------
	; Initialize 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		
IFNDEF 	SX18_20
		mov     w,#RC_ST            	;Setup RC Schmitt Trigger, 0 = enabled, 1 = disabled
		mov	!rc,w	
ENDIF 	;(SX18_20)
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 	;(SX48_52)
		_mode	LVL_W			;point MODE to write LVL register
		mov     w,#RA_LVL            	;Setup RA CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!ra,w		 
		mov     w,#RB_LVL            	;Setup RB CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!rb,w		
IFNDEF 	SX18_20
		mov     w,#RC_LVL            	;Setup RC CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!rc,w	
ENDIF 	;(SX18_20)
IFDEF 	SX48_52
			
		mov     w,#RD_LVL            	;Setup RD CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!rd,w		
		mov     w,#RE_LVL            	;Setup RE CMOS or TTL levels, 0 = TTL, 1 = CMOS
		mov	!re,w		
ENDIF	;(SX48_52)
		_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		
IFNDEF 	SX18_20
		mov     w,#RC_PLP            	;Setup RC Weak Pull-up, 0 = enabled, 1 = disabled
		mov	!rc,w	
ENDIF	;(SX18_20)
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	;(SX48_52)
		_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			
IFNDEF 	SX18_20
		mov	w,#RC_DDIR		;Setup RC Direction register, 0 = output, 1 = input
		mov	!rc,w			
ENDIF	;(SX18_20)
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	;(SX48_52)
		mov     w,#RA_latch          	;Initialize RA data latch
		mov     ra,w		
		mov     w,#RB_latch         	;Initialize RB data latch
		mov     rb,w		
IFNDEF 	SX18_20
		mov     w,#RC_latch          	;Initialize RC data latch
		mov     rc,w		
ENDIF	;(SX18_20)
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	;(SX48_52)


	;------------------------------------------------------------------------------
	; Clear all Data RAM locations
	;------------------------------------------------------------------------------

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

		_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	;(SX48_52)				;SX18/20/28 RAM clear routine
		clr	fsr			;reset all ram banks
:zeroRam	sb	fsr.4			;are we on low half of bank?
		setb	fsr.3			;If so, don't touch regs 0-7
		clr	indf			;clear using indirect addressing
		incsz	fsr			;repeat until done
		jmp	:zeroRam
ENDIF	;(SX48_52)
	;------------------------------------------------------------------------------
	; Initialize program/VP registers
	;------------------------------------------------------------------------------

;VP_BEGIN: Fgen
		;Initialize the frequency Generator
		_bank	FgenBank
		mov	fgSet, #9
		clrb	fgSetHi
		clrb	fgCntLo			; Program starts here on power up
		clrb	fgCntHi
;VP_END: Fgen


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

	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
	; Virtual Peripheral Guidelines Tip:
	;
	;	The suggested default values for the option register are:
	;	- Bit 7 set to 0: location $01 addresses the W register (WREG)
	;	- Bit 3 set to 1: Prescaler assigned to WatchDog Timer
	;
	;	If a routine must change the value of the option register (for example, to access
	;	the RTCC register directly), then it should restore the default value for the 
	;	option register before exiting.
	;
	;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?


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 WDT (PSA hi)
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_ON | RTCC_FE | PS_000 	; the default option setup for this program.
		mov	w, #OPTIONSETUP		; setup option register for RTCC interrupts enabled 
		mov	!option,w		; and prescaler assigned to WDT.
		jmp	@mainLoop

;------------------------------------------------------------------------------
; MAIN PROGRAM CODE 
;------------------------------------------------------------------------------


mainLoop
IFDEF	DEMO
	
loop		
		
		; Process Line 0
		;--------------------------
		_bank	fmVar2
		mov	w,#0
		mov	fmVar2, w

		_bank	fmesBank
		mov     w, fmFreq0
		mov     localTemp3, w
		mov     w, fmFreq0 + 1
		mov     localTemp3 + 1, w
		call    @sxoh_Switch

		; Process Line 1
		;--------------------------
		_bank	fmVar2
		mov	w,#1
		mov	fmVar2, w
		
		_bank	fmesBank
		mov     w, fmFreq1
		mov     localTemp3, w
		mov     w, fmFreq1 + 1
		mov     localTemp3 + 1, w
		call    @sxoh_Switch

		; Process Line 2
		;--------------------------
		_bank	fmVar2
		mov	w,#2
		mov	fmVar2, w
		
		_bank	fmesBank
		mov     w, fmFreq2
		mov     localTemp3, w
		mov     w, fmFreq2 + 1
		mov     localTemp3 + 1, w
		call    @sxoh_Switch

		; Process Line 3
		;--------------------------
		_bank	fmVar2
		mov	w,#3
		mov	fmVar2, w
		
		_bank	fmesBank
		mov     w, fmFreq3
		mov     localTemp3, w
		mov     w, fmFreq3 + 1
		mov     localTemp3 + 1, w
		call    @sxoh_Switch

		jmp	loop			; loop until forever
:ProgDone
		jmp	$			;halt

ENDIF	;(DEMO)
	jmp	mainLoop


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


file: /Techref/scenix/contest/sxohm/sxohm_src.htm, 49KB, , updated: 2002/5/1 17:36, local time: 2024/11/6 00:47, owner: JMN-EFP-786,
TOP NEW HELP FIND: 
18.116.88.128:LOG IN
©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://linistepper.com/techref/scenix/contest/sxohm/sxohm_src.htm"> Source Code</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?