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