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