 
Document Body Page Navigation Panel
 Page 1 2 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 © 2000 Scenix
Semiconductor, Inc. All rights reserved. 
www. scenix. com 
User's Manual Virtual Peripheral  
Methodology & Modules  1 
1  Page 2
3 
© 2000 Scenix Semiconductor, Inc. All rights reserved. SX Virtual Peripheral
Methodology & Modules Rev. 1.0 
www. scenix. com 
Revision History 
©2000 Scenix Semiconductor, Inc. All rights reserved. No warranty is
provided and no liability is 
assumed by Scenix Semiconductor with respect to the accuracy of this
documentation or the 
merchantability or fitness of the product for a particular application. No
license of any kind is conveyed 
by Scenix Semiconductor with respect to its intellectual property or that
of others. All information in 
this document is subject to change without notice. 
Scenix Semiconductor products are not authorized for use in life support
systems or under conditions 
where failure of the product would endanger the life or safety of the user,
except when prior written 
approval is obtained from Scenix Semiconductor. 
Scenix and the Scenix logo are trademarks of Scenix Semiconductor,
Inc. 
Virtual Peripheral is a trademark of Scenix Semiconductor, Inc. 
I 2 C is a trademark of Philips Corporation 
Microwire is a trademark of National Semiconductor Corporation 
All other trademarks mentioned in this document are property of their respective
companies. 
Scenix Semiconductor, Inc., 1330 Charleston Road, Mountain View, CA 94043,
USA 
Telephone: +1 650 210 1500, Fax: +1 650 210 8715, Web site: www. scenix.
com, 
E-mail: sales@ scenix. com 
REVISION RELEASE DATE SUMMARY OF CHANGES 
0.998 February 24, 2000 Initial release (Word version) 
1.0 March 24, 2000 Reformatted for distributing the initial draft. 2 
2  Page 3
4 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 3 SX Virtual
Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com 
Contents 
Chapter1 Virtual Peripheral Guidelines 
1.1 Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4 
1.2 Virtual Peripheral Implementation. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .5 
1.3 Structure of an Application with Virtual Peripheral Modules. . . . .
. . . . . . . . . . . . . . . . . . .6 
1.4 RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 
1.5 Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 
1.5.1 Labeling All Sections: RAM, Constants, ISR, Subroutines . . . . . .
. . . . . 8 
1.6 Standardized Directives. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . .8 
1.7 Standard !Option Setup. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . .9 
1.8 Standard Mode Register Setup. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .10 
1.9 Port Access. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10 
1.10 Port Direction. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 
1.11 SX28AC/ SX52BD Compatibility. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .12 
1.12 Lookup Tables (Jump Tables). . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .14 
1.13 Memory Location Dependencies. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .15 
1.14 Page Boundaries. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .16 
1.15 Subroutines in the Second Page of Program Memory. . . . . . . . . .
. . . . . . . . . . . . . . . . . . .16 
1.16 Defining ORG Statements. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .18 
1.17 Main Program. . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19 
1.18 Making Frequency Scalable. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .19 
1.19 Making Virtual Peripheral Modules Look and Act as Modules. . . . . .
. . . . . . . . . . . . . . .21 
1.20 Define the ISR in Locations $0 to $1ff . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .21 
1.21 Worst-Case ISR Cycle Count. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .21 
1.22 Selecting the Interrupt Rate and Oscillator Frequency. . . . . . . .
. . . . . . . . . . . . . . . . . . . .22 
1.23 Saving CPU Bandwidth. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .22 
1.24 Use the Multi-Threaded ISR Template. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .23 
Chapter 2 Source Code Template 
2.1 Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .27 
2.1 Source Code Template. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .27 
Chapter 2 Adding a Virtual Peripheral to the Source Code Template 
3.1 Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48 
3.2 Source Code Template With A Virtual Peripheral Example. . . . . . . .
. . . . . . . . . . . . . . . .48 3 
3  Page 4
5 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 4 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com 
Chapter1 
Virtual Peripheral Guidelines 
1.1 Introduction 
This document describes the formats, conventions, and coding guidelines
for developing Virtual 
Peripheral modules and integrating the modules for an application that uses
the SX communications 
controller. By applying a familiar model consistently across all Virtual
Peripheral modules, we can 
keep the design methodology simple to reduce the development effort. 
Virtual Peripheral concept enables the "software system on a chip" approach.
Virtual Peripheral, a 
software module that replaces a traditional hardware peripheral, takes advantage
of the Scenix 
architecture's high performance and deterministic nature to produce same
results as the hardware 
peripheral with much greater flexibility. 
The speed and flexibility of the Scenix architecture complemented with the
availability of the Virtual 
Peripheral library, simultaneously address a wide range of engineering and
product development 
concerns. They decrease the product development cycle dramatically, shortening
time to production to 
as little as a few days. 
Scenix's time-saving Virtual Peripheral library gives the system designers
a choice of ready-made 
solutions, or a head start on developing their own peripherals. So, with
Virtual Peripheral modules 
handling established functions, design engineers can concentrate on adding
value to other areas of the 
application. 
The concept of Virtual Peripheral combined with in-system re-programmability
provides a powerful 
development platform ideal for the communications industry because of the
numerous and rapidly 
evolving standards and protocols. 
Overall, the concept of Virtual Peripheral provides benefits such as using
a more simple device, 
reduced component count, fast time to market, increased flexibility in design,
customization to your 
application and ultimately overall system cost reduction. 
Some examples of Virtual Peripheral modules are: 
° Communication interfaces such as I 2 C, Microwire
(µ-Wire), SPI, IrDA Stack, UART, and Mo-dem functions 
° Internet Connectivity protocols such as UDP, TCP/ IP stack, HTTP,
SMTP, POP3 
° Frequency generation and measurement 
° PWM/ PDM generation 
° Delta/ Sigma ADC 
° DTMF generation/ detection 
° FFT/ DFT based algorithms 4 
4  Page 5
6 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 5 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.2 Virtual Peripheral Implementation 
The concept of Virtual Peripheral has been around for many years, but
the hardware to make the 
concept practical did not exist until recently when Scenix released the SX
communications controller. 
The SX communication controller is a cost-effective communications controller,
running at up to 100 
MIPS. Although speed is an important feature of the SX communication controller,
its deterministic 
architecture is the essential enabling technology for Virtual Peripheral
implementation. Every 
instruction in the SX is completely deterministic, in the sense that all
instructions execute in a 
predetermined number of clock cycles (1 cycle for all instructions except
branches, which require 3 
cycles) and the interrupt latency is fixed (3 cycles for an internal interrupt,
5 cycles for an external 
interrupt). 
All Virtual Peripheral modules run in the "background" of the main application
software, as part of an 
interrupt service routine. The deterministic nature of the SX communication
controller gives the 
interrupt service routine an exact frequency of execution, and all Virtual
Peripheral modules, whether 
a serial bus interface, a timer, or a DTMF generator, can be based on this
exact, jitter-free frequency. 
Virtual Peripheral modules must run with minimal intervention from the
application software, just as 
though they were hardware peripherals. The application software simply sets
or clears flags, loads a 
few registers, and then lets the Virtual Peripheral modules do the work.
For example, with an A/ D 
Virtual Peripheral, there is no interaction needed from the application software
while the conversion 
is taking place. When the A/ D Virtual Peripheral has finished a conversion,
it can set a flag to indicate 
that the application can take the result. 
The interrupt service routine is set up to be called at an exact timing interval.
For most Virtual 
Peripheral modules, the timing can be arbitrary, as long as the sample rate
is high enough to accomplish 
the desired task. Some Virtual Peripheral modules such as UART needs to run
at specific rates, e. g. 
1200 baud, 115.2 kbaud, etc. To simplify the interrupt service routine code
that performs the UART 
function, the interrupt service routine is called at a rate that is an exact
multiple of the standard UART 
speeds. 
Virtual Peripheral modules for the SX communication controller are usually
designed to run from 
interrupts triggered by the Real-Time Clock/ Counter (RTCC). The RETIW
instruction performs a 
return from interrupt that also adjusts the RTCC to control the exact timing
of the interrupts. In the 
Scenix design methodology, the programmer creates a real-time kernel that
receives the interrupts and 
allocates execution time to the various Virtual Peripheral modules that may
run. 
The main body of the application starts execution at the reset vector,
initializes the system, then falls 
into the main loop. The main loop communicates with the Virtual Peripheral
modules through flags. 
Enable flags signal when a Virtual Peripheral should run, e. g. to request
transmitting a character. Status 
flags indicate when a Virtual Peripheral has completed an operation, e. g.
to acknowledge that the 
character has been transmitted. The main loop does not handle interrupts
directly, that function being 
handled entirely in background by the real-time kernel. 5 
5  Page 6
7 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 6 SX Virtual
Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.3 Structure of an Application with Virtual Peripheral Modules 
Figure1-1 Virtual Peripheral Implementation 
PWM D/ A 
DTMF 
GEN 
DTMF 
Detect 
9600 
UART 
5ms 
Timer 
Enable Flags? 
Status Flags 
Retiw 
ISR Start 
Subroutine1 
Subroutine2 
Subroutines 
. 
. 
Table Data 
Initialization and startup code 
Set Virtual Peripheral Enable 
Flags 
Monitor and Service Virtual 
Peripheral Status Flags 
Main Loop 
Interrupt Service Routine 
Reset Entry Location... SX Starts Executing 
Code from Here 
The Interrupt Service Routine calls Virtual Peripheral that run transparently
to the main program (i. e. in back-ground). 
The ISR is called at a specific frequency and services all of the Virtual
Peripheral modules. 
In this illustration, a PWM D/ A converter is running as a fixed-rate,
high-priority task, and four other tasks 
(DTMF generation, DTMF detection, UART, and timer) are running at lower priority
controlled by enable flags. 
The Virtual Peripheral modules set status flags to indi-cate their status.
The subroutines follow the end of the interrupt service 
The entry point for the application (where the program 
begins running on reset) is before the main loop at the end of the source
code. 
The main loop of the application is located at the end of 
the source code. It sets enable flags to start Virtual Peripherals running
in the Interrupt Service Routine. Virtual 
Peripherals set status flags to indicate completion, such as 
the 5 ms timer expiring. 
Table data like strings can be stored after the subroutines. 
routine. 6 
6  Page 7
8 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 7 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.4 RAM 
Use the following standard label names for global variables in Virtual
Peripherals and applications 
released by Scenix: 
flags0 stores bitwise operators like flags and function-enabling bits
(semaphores). 
isrTemp0 is for use ONLY by the interrupt service routine as a global
register. 
localTemp0 is the temporary register used most often, so routines
that are only nested once can destroy 
this register. It is never guaranteed to retain data from routine to routine.
localTemp1 is used by the second nested level, or when a routine needs
more than one temporary glo-bal 
register. 
localTemp2 follows along the same lines as localTemp1, but is used
even less often by more deeply 
nested routines or as a mainline loop counter, because the other temporary
registers will probably be 
destroyed by the routines called by the mainline. 
The documentation for each subroutine will specify which localTemp register
it destroys, and which 
localTemp registers are destroyed by routines nested below this one. If
additional temporary registers 
are needed, they can be called localTemp3 or flags1, etc. 
Write Virtual Peripheral modules so they make use of no global RAM locations
other than the 
definitions listed above. 
1.5 Labels 
All labels must be kept under two tabs in length. The Hungarian notation
must be used for all labels. 
Example: 
RS232_ receive becomes rs232Receive 
Prefix all RAM locations and constants for a specific Virtual Peripheral
by a standard, truncated 
version of that Virtual Peripheral's name. Example: 
rxByte ds 1 becomes rs232RxByte ds 1 
Left justify all equates and defines, and group all of them into the "Equates
and Definitions" area of 
the source code. 
flags0 equ global_ org+ 0 ; semaphore register reserved 
; for flag bits. 
isrTemp0 equ global_ org+ 1 ; temporary register reserved 
; for use by the interrupt-; 
service routine, ISR Virtual Peripheral 
localTemp0 equ global_ org+ 2 ; temporary register reserved 
; for use by subroutines 
localTemp1 equ global_ org+ 3 ; temporary register reserved 
; for use by subroutines 
localTemp2 equ global_ org+ 4 ; temporary register reserved 
; for use by the main program  7 
7  Page 8
9 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 8 SX Virtual
Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.5.1 Labeling All Sections: RAM, Constants, ISR, Subroutines 
° Each section of the Virtual Peripheral must be clearly labeled
to show which Virtual Peripheral 
it belongs to. This includes RAM allocations, program constants, Virtual
Peripheral (ISR) rou-tines, 
and callable subroutines. 
° The labels should be machine readable, to enable a smart software
tool in the future that can au-tomatically 
cut and paste Virtual Peripheral modules. 
° Start the Virtual Peripheral module with: 
;VP_ begin <moduleVP> 
And end it with: 
;VP_ end ; End cut/ paste <moduleVP> 
1.6 Standardized Directives 
Create a set of standard directives for all Virtual Peripheral modules.
A tradeoff is that some Virtual 
Peripheral modules may become less code-efficient or speed-efficient. 
Standard Directives: 
° OPTIONX enabled 
° STACKX enabled 
° CARRYX disabled -if a routine cannot run without CARRYX (like hard-core
math), the fact 
that CARRYX is necessary must be well documented. 
° TURBO mode 
;VP_ begin RS232Receive 
RS232RxBank 
RS232RxCount 
RS232RxDivide 
RS232RxByte 
= 
ds 
$ 
1 
ds 
ds 
1 
1 
;number of bits received 
;receive timing counter 
;buffer for incoming byte 
; End cut/ paste for RS232Receive ;VP_ end  8 
8  Page 9
10 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 9 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.7 Standard !Option Setup 
° WREG enabled (bit seven of !OPTION = 0, !OPTION = 0xxxxxxxb),
so W is accessible as a file 
register in location $01, rather than RTCC. 
° If possible, a routine that needs to access the RTCC register in location
$01 should set bit 7 of 
!OPTION before executing and, when finished, clear it again to access the
WREG in location 
$01. 
Define the default !option set-up as 
Initialization code for WREG in location $01: 
Routines accessing the RTCC register in location $01: 
After accessing the RTCC register, this routine sets the option register
back to its default state. If an 
exception must be made for speed purposes, it should be well documented that
the routine needs the 
option register set up to allow direct access to the RTCC. 
OPTIONSETUP equ RTCC_ PS_ OFF| PS_ 111 ;! OPTION = 0000111b 
mov 
mov 
jmp 
w,# OPTIONSETUP 
!option, w 
@main 
; setup option register for RTCC interrupts 
; enabled and no prescaler. 
; by setting !option. 7 
mov !option, #( OPTIONSETUP | RTCC_ ON) ; enable direct access of the RTCC
:elsewhere 
; This code accomplishes absolutely 
; nothing, 
mov !rb, RTCC 
; but it accesses the RTCC register jmp :elsewhere 
RTCC, rc 
!option, #OPTIONSETUP 
mov 
mov ; go back to the option register's 
; default.  9 
9  Page 10
11 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 10 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.8 Standard Mode Register Setup 
In mainline (interruptible) code, never assume the value in the mode
register, and always update it 
before using it. 
In the Interrupt Service Routine, routines changing the mode register must
change it back before 
exiting. The isrTemp register can be used to store and restore the previous
state of the mode register. 
Example: 
1.9 Port Access 
To ease integrating multiple Virtual Peripheral modules that all need
access to the same ports, 
° Use pin definitions rather than port definitions. 
° All port accesses should be made through symbolic names. Example:
setb rb. 6 becomes setb LEDPin 
mov w, m 
isrTemp, w 
w,#$ 1f 
m, w 
!rb,# 0 
w, isrTemp 
m, w 
mov 
mov 
mov 
mov 
mov 
mov 
; save mode register in isrTemp 
; restore mode register 
; change port RB to all outputs 
; change mode register  10 
10  Page 11
12 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 11 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.10 Port Direction 
When a Virtual Peripheral must dynamically change a port direction register,
it should do this through 
the use of a port direction buffer. The port direction register stores
the initialized state of the port 
direction register, and any changes made to the port direction register are
made to the buffer first, and 
then the buffer is written to the port direction register. 
If two Virtual Peripheral modules are combined, and both need to dynamically
modify the same port 
direction register, they instead operate on the buffer for that port's direction
register. The buffer is then 
written to the port direction register. Use banked RAM and standardized names
for port direction 
register buffers: 
These rules apply to other special mode-register addressable registers, such
as the pull-up enable 
registers, etc. 
portBufBank equ $ 
RADirBuf 
REDirBuf 
RDDirBuf 
RCDirBuf 
RBDirBuf 
ds 
ds 
ds 
ds 
ds 
1 
1 
1 
1 
1  11 
11  Page 12
13 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 12 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.11 SX28AC/ SX52BD Compatibility 
Use MACROs or IFDEF/ IFNDEF statements to make portions of incompatible
code switch in and out 
for the SX28AC and SX52BD communications controllers. 
Example of using an IFDEF statement for SX18/ 28AC portability to SX52BD
and vice-versa: 
Because the RAM in the SX52BD is stored in contiguous banks, and in the SX28AC
the banks are 
separated by $20, the IFDEF above will conditionally compile the setb
instruction, allowing the pointer 
to memory to skip the non-existent banks in the SX28AC. 
Macros help keep the source code clean. Example of a good macro for incrementing
pointers to RAM: 
; Virtual Peripheral: 62-byte buffer 
; Subroutine: Store W in buffer[ pushIndex++] 
; 
; 
; 
;------------------------------------------------------------------------------
bufferPush 
IFDEF SX28AC 
ENDIF 
IFDEF 
ENDIF 
INPUTS: 
OUTPUTS: 
CHANGES: 
data to store in W 
data to store in buffer[ pushIndex++] 
localTemp1, pushIndex, buffer[ pushIndex] 
mov 
_bank 
mov 
mov 
_bank 
inc 
setb 
retp 
localTemp1, w 
buffer 
fsr, pushIndex 
indf, localTemp1 
buffer 
pushIndex 
pushIndex. 4 ; keep even bank if SX28AC/ 18 
;------------------------------------------------------------------------------
SX18 
setb pushIndex. 4 
;*************************************************************************
; INCP/ DECP macros for incrementing pointers to RAM 
;*************************************************************************
INCP 
endm 
IFNDEF 
ENDIF 
IFDEF 
ELSE 
ENDIF 
DECP 
macro 1 
inc \1 
SX48_ 52 
setb \1.4 
macro 1 
SX48_ 52 
dec \1 
clrb \1.4 
dec \1 
setb \1.4 
endm 
; Increments a pointer to RAM 
; If SX18 or SX28AC, keep bit 4 of the pointer = 1 
; to jump from $1f to $30, etc. 
; Decrements a pointer to RAM 
; If SX18 or SX28AC, forces rollover to next bank 
; Eg: $30 --> $20 --> $1f --> $1f 
; AND: $31 --> $21 --> $20 --> $30 
; if it rolls over (skips banks with bit 4 = 0)  12 
12  Page 13
14 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 13 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
Example of using a macro (INCP) to make the buffering source code easier
to read: 
BANK 0 Locations $10 to $1f 
Because the SX48/ 52 can only access memory locations $10 to $1f directly,
use these locations only 
as a last resort in programs written for the SX18/ 28, for compatibility
with the SX48/ 52. 
Extra RAM in the SX48/ 52 
Because the SX18/ 28 has only half of the RAM of the SX48/ 52, avoid
use of the extra RAM in 
programs written for the SX48/ 52, for compatibility with the SX18/ 28. 
;------------------------------------------------------------------------------
;Virtual Peripheral: 62-byte buffer 
; Subroutine: Store W in buffer[ pushIndex++] 
; 
; 
; 
;------------------------------------------------------------------------------
INPUTS: 
OUTPUTS: 
CHANGES: 
data to store in W 
data stored in buffer[ pushIndex++] 
localTemp1, pushIndex, buffer[ pushIndex] 
bufferPush 
mov 
_bank 
mov 
mov 
_bank 
INCP 
retp 
localTemp1, w 
buffer 
fsr, pushIndex 
indf, localTemp1 
buffer 
pushIndex ; Smart-Increment of the pointer to RAM  13
13  Page 14
15 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 14 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.12 Lookup Tables (Jump Tables) 
Routines should be clearly documented if they need to be completely within
the first half of the page. 
Lookup tables that may be called by the programmer's own program should have
protection against the 
table extending into the second half of a page. This can be done with the
help of macros. By including 
a tableStart and tableEnd definition in the table, these macros will generate
the error message 
"ERROR: Must be located in the first half of a page." if the table becomes
misplaced. 
An assembler may implement this function in the future if these standard
tableStart and tableEnd 
definitions are used. 
This: Becomes this: 
Note that the table must be in same page as the call to that table. 
;*********************************************************************************
;*********************************************************************************
; Error generating macros 
tableStart 
tableEnd 
macro 0 
macro 0 
ERROR 'Must be located in the first half of a page. ' 
ERROR 'Must be located in the first half of a page. ' 
; Generates an error message if code that MUST be in 
; the first half of a page is moved into the second 
; half. 
; Generates an error message if code that MUST be in 
; the first half of a page is moved into the second 
; half. 
IF $ & $100 
ENDIF 
ENDM 
IF $ & $100 
ENDIF 
ENDM 
;******************** 
jmp_ table_ 1 
add 
jmp 
jmp 
jmp 
jmp 
;******************** 
pc, w 
routine_ 1 
routine_ 2 
routine_ 3 
routine_ 4 
;******************** 
jmp_ table_ 1 
; The code between the 
; tableStart 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 
add 
jmp 
jmp 
jmp 
jmp 
tableEnd 
;******************** 
pc, w 
routine_ 1 
routine_ 2 
routine_ 3 
routine_ 4  14 
14  Page 15
16 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 15 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.13 Memory Location Dependencies 
Routines that are program memory location-dependent must be clearly
marked: 
If possible, defines or equates can be used to simplify this process: 
becomes 
Now, as long as the STRINGS_ ORG label precedes the strings, this subroutine
will work properly, 
without regard to where the strings are located. 
For routines with very location-specific data memory definitions, there should
be ample 
documentation to indicate that the data memory cannot be moved around
arbitrarily. Wherever 
possible, location-specific routines should be avoided. 
;**************************************************************************
; Subroutine -Send string pointed to by address in W register 
; 
; 
; INPUTS: 
; 
; 
; OUTPUTS: 
; 
;**************************************************************************
Strings MUST be located completely within program memory space from $300
to $3ff 
w -The address of a null-terminated string in program 
memory 
outputs the string via RS-232 
mov m,# 3 ; move upper nibble of address of strings into m 
mov m,# STRINGS_ ORG>> 8; move upper nibble of address of strings into
m 
;***************************************************************************************
; String Data 
;***************************************************************************************
org ; This label defines where strings are kept in program 
; space. All of the following strings must be within the 
; same 1/ 2 page of program memory for send_ string to work, 
; and they must be preceded by this label. 
_hello dw 13,10, 'V. 23 Transmit (Originate Mode) 2.00', 0 
_FSK dw 13,10, 'Transmitting 75bps FSK >', 0 
STRINGS_ ORG  15 
15  Page 16
17 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 16 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.14 Page Boundaries 
To ensure that several Virtual Peripheral modules, when pasted together,
do not cross a page boundary 
without the programmer's knowledge, put an ORG statement with one instruction
at every page 
boundary. This will generate an error if adding a subroutine moves another
subroutine over a page 
boundary. 
1.15 Subroutines in the Second Page of Program Memory 
If two Virtual Peripheral modules are integrated together, and the
subroutines for each Virtual 
Peripheral are to be placed into the same page, the callable subroutines
from one of the Virtual 
Peripheral modules may need to be moved to the second half of a page. The
problem this poses is that 
labels in the second half of a page can only be jumped to and not called.
The solution is to create a 
jump table for the routines in the second half of the page. Unfortunately,
the compromise is that calling 
a routine through a jump table adds a 3-cycle latency to the subroutine call,
and therefore should only 
be used for routines that are not extremely speed-critical. 
org $0 
org $700 
org $100 
org $200 
Subroutines/ program code... 
org 
org 
etc... 
$400 ; Even though there's no program, 
; put code here to generate an error 
; if the code before it crosses a 
; page boundary 
jmp 
jmp 
$500 
$ 
$  16 
16  Page 17
18 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 17 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
There is no simple way to make this job easier for the integrator, so the
only solution is to provide 
ample documentation and examples on creating jump tables. 
VP1Subroutine2 0x0264 . 
VP1Subroutine3 
0x0296 
. 
0x02c8 
Interrupt Service Routine 
0x0000 
. 
. 
. 
VP1Subroutine1 0x0200 . 
Main Program 0x0038 . 
Page 0 
Page 1 
Virtual Peripheral Module 1 
ORG $200 
VP2Subroutine2 0x023c . 
VP2Subroutine3 
0x0278 
. 
0x02b4 
Interrupt Service Routine 
0x0000 
. 
. 
. 
VP2Subroutine1 0x0200 . 
Main Program 0x00AA . 
Page 0 
Page 1 
Virtual Peripheral Module 2 
ORG $200 
Combo of 
Interrupt Service Routine 
1 & 2 
0x0000 
. 
. 
. 
Main Program 0x00E2 . 
Page 0 
Virtual Peripheral Module 1 & 2 Combo 
ORG $300 
VP1Subroutine2 0x0267 . 
VP1Subroutine3 
0x0299 
. 
0x02cb 
VP1Subroutine1 0x0203 . 
Page 1 
_VP2Subroutine2 0x033c . 
_VP2Subroutine3 
0x0378 
. 
0x03b4 
_VP2Subroutine1 0x0300 . 
Page 1.5 
0x0200 VP2Subroutine1 jmp _VP2Subroutine1 
0x0201 VP2Subroutine2 jmp _VP2Subroutine2 
0x0202 VP2Subroutine3 jmp _VP2Subroutine3 
ORG $200 
ISR's from both Virtual 
Peripherals Combined 
Jump Table created so 
calls to subroutines from 
second VP are possible. 
Subroutines from Virtual 
Peripheral #1 in first half of 
page 1 
Subroutines from Virtual 
Peripheral #2 in second 
half of page 1. 17 
17  Page 18
19 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 18 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.16 Defining ORG Statements 
Place a table of ORG statements at the top of the source code with the
starting addresses of all Virtual 
Peripheral modules. Use symbolic names for these addresses, rather than
hard-coding them as literal 
values. This lends itself to separating the Virtual Peripheral modules into
separate source files and 
creating a linker. Indicate whether each segment is moveable or not. 
Now, instead of using the literal values, use the defined values: 
For smaller Virtual Peripheral modules, just use PAGE2_ ORG, etc. 
Example from included code: 
And: 
UART_ SUBS_ ORG I2C_ SUBS_ ORG 
I2C_ ISR_ ORG 
equ $300 equ 
equ $400 $600 
org UART_ SUBS 
;***************************************************************************************
; Program memory ORG defines 
;***************************************************************************************
INTERRUPT_ ORG 
INTERRUPT_ ORG2 
RESET_ ENTRY_ ORG 
SUBROUTINES_ ORG 
STRINGS_ ORG 
PAGE3_ ORG 
MAIN_ PROGRAM_ ORG 
equ 
equ 
equ 
equ 
equ 
equ 
equ 
$0 
$100 
$1FB 
$200 
$300 
$400 
$600 
; Interrupt must always start at location zero 
; Some more of the ISR is stored in location $100 
; The program will jump here on reset. 
; The subroutines are in this location 
; The strings are in location $300 
; Page 3 is empty 
; The main program is in the last page of program 
; memory. 
;**************************************************************************************
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Interrupt Service Routine 
; Note: The interrupt code must always originate at address $0. 
; 
; Interrupt Frequency = (Cycle Frequency / -( retiw value)) For example:
; With a retiw value of -163 and an oscillator frequency of 50MHz, this 
; code runs every 3.26us. 
; org INTERRUPT_ ORG ; First location in program memory. 
;------------------------------------------------------------------------------
18 
18  Page 19
20 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 19 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.17 Main Program 
Place the main routine at the end of the source code to make it easy
to find. This means that if the first 
page is used for anything other than main program source code, a reset_ entry
must be placed in the 
first page, along with a page instruction and a jump instruction to the beginning
of the main program. 
Example: 
Then, at the start of the main routine on another page: 
1.18 Making Frequency Scalable 
Whenever possible, Virtual Peripheral modules should be written so that
they are scalable to work with 
virtually any interrupt rate. Virtual Peripheral modules that are written
in this way include the A/ D and 
D/ A converters, the timers, FSK and DTMF generation and detection, LCD
interface, and many others. 
Only the resolution or timing constants change as the interrupt rate changes.
Some Virtual Peripheral modules, however, require very specific interrupt
rates. An example of this is 
the UART, which must be run at a 2 n multiple of the desired UART
rate. In this case, it must be made 
very clear to the programmer how to calculate the interrupt rates for all
Virtual Peripheral modules, so 
that a frequency-dependent Virtual Peripheral like the UART can be chosen
as the rate-determining 
factor, and all other Virtual Peripheral modules can have their constants
re-calculated for the chosen 
rate. 
;***************************************************************************************
;***************************************************************************************
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
org 
reset_ entry 
RESET_ ENTRY_ ORG 
page_ reset_ entry 
jmp_ reset_ entry 
; Program starts here on power-up 
;***************************************************************************************
;***************************************************************************************
;***************************************************************************************
;***************************************************************************************
org 
; RESET VECTOR 
MAIN_ PROGRAM_ ORG 
;******************************************************************************
;******************************************************************************
; Program execution begins here on power-up or after a reset 
_reset_ entry 
; program start up source code here 
; 
; 
; 
; 
19200 baud 
baud_ bit 
start_ delay 
int_ period 
= 
= 
= 
4 
16+ 8+ 1 
163 
;for 19200 baud 
; 
;  19 
19  Page 20
21 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 20 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
This type of definition gives the programmer no idea what to do if he wants
to change the interrupt 
rate, while the following definition makes the change much more obvious:
This clears up what the definitions do to the UART speeds, and that the UART
speed is tightly tied in 
to the interrupt rate. If the programmer wants a slower UART, or a slower
interrupt rate, or both, the 
change is more intuitive. 
If possible, let the compiler calculate the constant for the programmer,
as in this example: 
In this example, the constant used to generate a 697 Hz signal is generated
at compile time, as Fs 
changes. If the programmer wants to speed the execution rate of the
frequency-generating Virtual 
Peripheral, he or she can simply change its execution rate in the ISR and
scale the FS constant 
accordingly. 
As long as the execution rates of each of the Virtual Peripheral modules
are multiples of one another, 
they can all use the same retiw value. Unfortunately, the downfall of having
only one jitter-free 
interrupt is that running Virtual Peripheral modules at rates that don't
have a common denominator, 
such as 115 kHz and 250 kHz, is not possible. 
; 
; 
; 
; 
; 
; 
; 
; 
; 
Execution rate/ 16 
Execution rate/ 8 
Execution rate/ 4 
baud_ bit 
start_ delay 
start_ delay 
start_ delay 
baud_ bit 
baud_ bit 
= 
= 
= 
= 
= 
= 
4 
16+ 8+ 1 
3 
8+ 4+ 1 
2 
4+ 2+ 1 
; For a baud rate of FS/ 16 
; For a baud rate of FS/ 8 
; For a baud rate of FS/ 4 
; 
; 
; 
Fs = 9600 
Bits = 65536 
f697_ l 
f697_ h 
; sampling frequency for DTMF detection 
; 2^ 16 is the value of the phase accumulator 
equ 
equ 
(( Bits * 697)/ Fs) & $0ff 
(( Bits * 697)/ Fs) >> 8  20 
20  Page 21
22 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 21 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.19 Making Virtual Peripheral Modules Look and Act as Modules 
° Keep each module short. The entire routine, beginning to
end, should fit in the editor's window 
without scrolling. 
° Indicate whether each ISR routine is variable-length or fixed-length
in its header. 
° Indicate the worst-case cycle time for each ISR routine in its header.
° Use only Scenix mnemonics as defined in the datasheet. 
° Provide only one way in and out of each routine. 
° Callable ISR routines: have a bank instruction for the routine performed
before the call. 
° Maximum ISR call-nesting: two levels, leaving nestable levels for
the mainline program. 
° As a rule, always return with a RETP instruction rather than a RET
instruction (retp restores the 
page bits to the page of the call). 
1.20 Define the ISR in Locations $0 to $1ff. 
Keeps the ISR structure compact and easy to read. Use extra pages only
if necessary. 
1.21 Worst-Case ISR Cycle Count 
The worst case ISR cycle count must not exceed RTCC interval. Exceeding
the interrupt timing will 
cause the communication controller to miss an interrupt, which throws off
the timing of every 
interrupt-driven Virtual Peripheral in the application. 21 
21  Page 22
23 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 22 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.22 Selecting the Interrupt Rate and Oscillator Frequency 
Getting the desired interrupt rate from the desired oscillator frequency
may be one of the most 
confusing parts of designing an interrupt-driven Virtual Peripheral. This
procedure may be used to 
select these parameters. 
1. Choose a desired interrupt frequency (irqFreq) based on the Virtual Peripheral
modules you want 
to run. 
Example: Choose 230.4 kHz for 4 times oversampling on a 57.6 kbps UART 
2. Choose an oscillator frequency (oscFreq.) Higher sample-rate Virtual
Peripheral modules will re-quire 
higher oscillator frequencies. If power is not an issue for your design,
a 50-MHz oscillator 
frequency is a safe bet for almost all Virtual Peripheral modules. 
Example: Choose 50 MHz 
3. Divide your oscillator frequency by your interrupt frequency. This is
your ideal RETIW value. 
° Calculate RETIW value = (oscFreq/ irqFreq) 
° Calculate 50 MHz/ 230.4 kHz = 217.01 
4. Round your RETIW value to the nearest integer value between 0 and 255.
° Round RETIW value to an integer 
° Round to 217 
° If the number exceeds 255, then slow down the RTCC by enabling its
prescaler (reducing its 
time between RTCC increments by an integral power of 2 between 2 and 256),
or choose a 
lower oscillator frequency. If the number is 90 or less, there may not be
enough time to ser-vice 
each interrupt, so increase the oscillator frequency or decrease the interrupt
frequency. 
5. Calculate your actual interrupt frequency to see if it is close enough
to your desired interrupt fre-quency 
by dividing the oscillator frequency by the RETIW value. 
° Actual Frequency = (oscFreq/ RETIWVal * prescaler) 
° Check Actual Frequency = 50,000,000 Hz/ 217 = 230.415 kHz @ 230.4
kHz 
° If the difference between the desired interrupt frequency and the
actual interrupt frequency 
is too much, try recalculating with different oscillator frequencies. 
1.23 Saving CPU Bandwidth 
Instead of running the Virtual Peripheral on every interrupt, try to
write it so it can run on every fourth 
or eighth interrupt. This makes integrating many Virtual Peripheral modules
much less likely to 
overflow the number of cycles available for each interrupt, because the Interrupt
Service Routine need 
only run one thread at a time. 22 
22  Page 23
24 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 23 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
1.24 Use the Multi-Threaded ISR Template 
This method produces a far smaller worst-case cycle time count,
and enables a larger number of Virtual 
Peripheral modules to run simultaneously. It also produces "empty" slots
that future Virtual Peripheral 
modules can occupy. 
1. Start with the multi-threaded ISR template shown on the next page. 
2. Determine how often your tasks need to run. For example, a 9600-baud UART
can run well at a 
sampling rate of only 38400 Hz, so don't run it faster than this. 
3. Place your modules into the threads of the ISR. If a module needs to be
run more often, call it at 
double the rate or at a rate that will meet its requirements. 
4. Split complicated Virtual Peripheral modules into several modules, keeping
the high-speed por-tions 
of the Virtual Peripheral modules as small and quick as possible, and run
the more compli-cated, 
slower processing part of the Virtual Peripheral at a lower rate. 
For example, in the Caller-ID detection program, the zero-cross-timer component
of the Virtual 
Peripheral runs at double the speed of all of the other components, because
it needs high resolution 
timing of the transitions on a pin. The other components of the Caller-ID
Virtual Peripheral run at a 
slower rate, yet take a longer time to run when they are run. It is not necessary
for them to run any 
faster, however, and doing so would increase the amount of CPU bandwidth
used by the FSK detection 
Virtual Peripheral with no added benefit. (See the block diagram of the Caller-ID
detection Interrupt 
Service Routine on the following pages.) 
Because the ISR can now be viewed as a structure, made up of modules, it
is easier for the user to 
increase and decrease the sampling rate by moving the modules around in the
source code. Because 
only a few tasks are called in each interrupt, the flow of each interrupt
is smaller and more easily 
understood. It is much simpler than an interrupt structure made up of many
modules running 
consecutively, each jumping to the next. 23 
23  Page 24
25 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 24 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
Block diagram of a complex application, simplified through the use of a
multi-threaded ISR (14 
simultaneous Virtual Peripheral modules) 
High Priority 
Virtual Peripheral 
12 cycles 
High Priority 
Virtual Peripheral 
6 cycles 
8 Task Switcher 
10 cycles 
Interrupt Start 
3 cycles 
2 Task Switcher 
6 cycles 
Very Low Priority 
Virtual Peripheral 
42 cycles W. C. 
Very Low Priority 
Virtual Peripheral 
Very Low Priority 
Virtual Peripheral 
18 cycles W. C. 
Low Priority 
Virtual Peripheral 
80 cycles 
Medium Priority 
Virtual Peripheral 20 cycles 
2 Task Switcher 
6 cycles 
Low Priority 
Virtual Peripheral 
20 cycles 
Low Priority 
Virtual Peripheral 
10 cycles 
Medium Priority Virtual Peripheral 
50 cycles 
Low Priority 
Virtual Peripheral 
70 cycles 
2 Task Switcher 
6 cycles 
Very Low Priority 
Virtual Peripheral 
40 cycles 
Low Priority 
Virtual Peripheral 
25 cycles 
Interrupt Rate = 306.7kHz 
Time until next interrupt = 163 cycles * 20ns = 3.26us 
Execution Rate = 306.7kHz 
Execution Rate = 306.7kHz 
Execution Rate = 306.7kHz, Cycle count = 31 cycles. 132 cycles remaining
Execution Rate = 38.34kHz Execution Rate = 76.69kHz (called twice per rotation)
Execution Rate = 38.34 kHz 
IRQ 1 IRQ 2 IRQ 3 IRQ 7 IRQ 4 IRQ 8 IRQ 5 IRQ 6 
Return and Add (256 -163) to 
RTCC 
Very Low Priority Virtual Peripheral 
15 cycles W. C. 
35 cycles W. C. 
Cycle 
count 
= 
77 
Cycle 
count 
= 
97 
Cycle 
count 
= 
111 
Cycle 
count 
= 
77 
Cycle 
count 
= 
67 
Cycle 
count 
= 
81 
Cycle 
count 
= 
101 
Cycle 
count 
= 
77 
Cycle 
count 
= 
62 
Worst 
Case 
Cycle 
count 
= 
111 
Execution 
Rate 
= 
38. 
34kHz 
Execution 
Rate 
= 
19. 17kHz 24 
24  Page 25
26 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 25 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
Block diagram of an actual application following this document's guidelines.
(FSK generation with 10 
simultaneous Virtual Peripheral modules) 
7 Task Switcher 
10 cycles 
Interrupt Start 
3 cycles 
4 Task Switcher 
12 cycles 
Interrupt Rate = 306.7kHz 
Time until next interrupt = 163 cycles * 20ns = 3.26us 
Execution Rate = 306.7kHz 
Execution Rate = 306.7kHz, Cycle count = 24 cycles. 132 cycles remaining.
Execution Rate = 38.34kHz 
IRQ 1 IRQ 2 IRQ 8 IRQ 5 IRQ 6 
Worst Case ISR Cycle time = 86 cycles 
Return and add 
(256 -163) to RTCC 
D/ A Conversion pulse Density 
Modulation 
11 Cycles 
7 cycles 
Total Cycles allowed for ISR = 163 
Signal Generation 
(Sine Wave) 
27 cycles 
RS232 Transmit 
23 cycles 
5ms Timer 
9 cycles 
Load D/ A 
Converter with 
Sine Value 4 cycles 
RS232 Receive 
27 cycles 
LED Flasher 
4 cycles 
FSK Transmit 
UART 
25 cycles 
FSK 
Modulator 
22 cycles 
FSK Flow 
Control 
43 cycles 
IRQ 7 
IRQ 4.1 IRQ 4.2 IRQ 4.3 IRQ 4.4 
Execution Rate = 76.69kHz (called twice per rotation) 
IRQ 3 IRQ 4 
Execution Rate = 306.7kHz 
Cycle 
count 
= 
55 
Cycle 
count 
= 
74 
Cycle 
count 
= 
37 
Cycle 
count 
= 
60 
Cycle 
count 
= 
58 
Cycle 
count 
= 
79 
Cycle 
count 
= 
36 
Cycle 
count 
= 
24 
Cycle 
count 
= 
24 
Cycle 
count 
= 
24 25 
25  Page 26
27 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 26 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter1 Virtual Peripheral Guidelines 
Block diagram of the ISR for the Caller-ID detection application. 
7 Task Switcher 
10 cycles 
Interrupt Start 
3 cycles 
4 Task Switcher 
12 cycles 
Interrupt Rate = 306.7kHz 
Time until next interrupt = 163 cycles * 20ns = 3.26us 
Execution Rate = 38.34kHz 
IRQ 1 IRQ 2 IRQ 8 IRQ 5 IRQ 6 
Worst Case ISR Cycle time = 63 + 7 = 70 cycles 
Return and add 
(256 -163) to RTCC 7 cycles 
Total Worst Case Cycles allowed for ISR = 163 
IRQ 7 
IRQ 4.1 IRQ 4.2 IRQ 4.3 IRQ 4.4 
Execution Rate = 76.69kHz 
(called twice per rotation) 
IRQ 3 IRQ 4 
Execution Rate = 306.7kHz 
fskZeroCross Timer fskReceive 5ms Timer 
LED Flasher 
RS232 Transmit 
RS232 Receive 
fskRxProc1 
fskRxProc2 
29 
Cycles 
from 
ISR 
Start 
Worst 
Case 
48 
Cycles 
from 
ISR 
Start 
Worst 
Case 
26 
Cycles 
from 
ISR 
Start 
Worst 
Case 
25 
Cycles 
from 
ISR 
Start 
Worst 
Case 
25 
Cycles 
from 
ISR 
Start 
Worst 
Case 
25 
Cycles 
from 
ISR 
Start 
Worst 
Case 
25 
Cycles 
from 
ISR 
Start 
Worst 
Case 
63 
Cycles 
from 
ISR 
Start 
Worst 
Case 
62 
Cycles 
from 
ISR 
Start 
Worst 
Case 
13 
Cycles 
from 
ISR 
Start 
Worst 
Case 26 
26  Page 27
28 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 27 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com 
Chapter2 
Source Code Template 
2.1 Introduction 
This chapter provides a Virtual Peripheral guideline compliant template.
This template can be used to 
convert non-compliant Virtual Peripheral modules to compliant modules or
develop new Virtual 
Peripheral modules. 
2.2 Source Code Template 
The template includes a skeleton Interrupt Service Routine (ISR) into
which the Virtual Peripheral 
source code can be copied. It also provides the ISR multi-tasker which allows
multiple threads of 
execution in the ISR. It includes initialization code, compiles and run,
but the ISR and the main loop 
are empty. 
;********************************************************************************
; Copyright © [11/ 21/ 1999] Scenix Semiconductor, Inc. All rights reserved.
; 
; Scenix Semiconductor, Inc. assumes no responsibility or liability for 
; the use of this [product, application, software, any of these products].
; Scenix Semiconductor conveys no license, implicitly or otherwise, under
; any intellectual property rights. 
; Information contained in this publication regarding (e. g.: application,
; implementation) and the like is intended through suggestion only and may
; be superseded by updates. Scenix Semiconductor makes no representation
; or warranties with respect to the accuracy or use of these information,
; or infringement of patents arising from such use or otherwise. 
;********************************************************************************
; 
; Filename: vp_ guide_ 1_ 01. src 
; 
; Authors: Chris Fogelklou 
; Applications Engineer 
; Scenix Semiconductor, Inc. 
; 
; Revision: 1.00 
; 
; Part: Put part datecode here. 
; Freq: Put frequency here. 
; 
; Compiled using: Put assemblers/ debuggers/ hardware used here. 
; 
; Date Written: Jan 15, 2000 
;  27 
27  Page 28
29 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 28 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
; Last Revised: Jan 15, 2000 
; 
; Program Description: 
; 
; Put program description here. 
; 
; Interface Pins: 
; 
; Put hardware interface pins here. 
; 
; Revision History: 
; 
; 1.0 Put Revision History here. 
; 
;********************************************************************************
;********************************************************************************
; Target SX 
; Uncomment one of the following lines to choose the SX18AC, SX20AC, SX28AC,
SX48BD/ ES, 
; SX48BD, SX52BD/ ES or SX52BD. For SX48BD/ ES and SX52BD/ ES, uncomment
both defines, 
; SX48_ 52 and SX48_ 52_ ES. 
;********************************************************************************
; SX18_ 20 
; SX28AC 
SX48_ 52 
; SX48_ 52_ ES 
;*************************************************************************
; Assembler Used 
; Uncomment the following line if using the Parallax SX-Key assembler. SASM
assembler 
; enabled by default. 
;***************************************************** 
;SX_ Key 
;***************************************************** 
; Assembler directives: 
; high speed external osc, turbo mode, 8-level stack, and extended option
reg. 
; 
; SX18/ 20/ 28 -4 pages of program memory and 8 banks of RAM enabled by default.
; SX48/ 52 -8 pages of program memory and 16 banks of RAM enabled by default.
; 
;*********************************************************************************
IFDEF SX_ Key ;SX-Key Directives 
IFDEF SX18_ 20 ;SX18AC or SX20AC device directives for SX-Key 
device SX18L, oschs2, turbo, stackx_ optionx 
ENDIF 
IFDEF SX28AC ;SX28AC device directives for SX-Key 
device SX28L, oschs2, turbo, stackx_ optionx 
ENDIF 
IFDEF SX48_ 52_ ES ;SX48BD/ ES or SX52BD/ ES device directives for SX-Key
device oschs, turbo, stackx, optionx 
ELSE 
IFDEF SX48_ 52 ;SX48/ 52/ BD device directives for SX-Key 
device oschs2 
ENDIF 
ENDIF 
freq 50_ 000_ 000 
ELSE ;SASM Directives  28 
28  Page 29
30 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 29 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
IFDEF SX18_ 20 ;SX18AC or SX20AC device directives for SASM 
device SX18, oschs2, turbo, stackx, optionx 
ENDIF 
IFDEF SX28AC ;SX28AC device directives for SASM 
device SX28AC, oschs2, turbo, stackx, optionx 
ENDIF 
IFDEF SX48_ 52_ ES ;SX48BD/ ES or SX52BD/ ES device directives for SASM 
device SX52BD, oschs, turbo, stackx, optionx 
ELSE 
IFDEF SX48_ 52 ;SX48BD or SX52BD device directives for SASM 
device SX52BD, oschs2 
ENDIF 
ENDIF 
ENDIF 
id 'VPG ' 
reset resetEntry ; set reset vector 
;*****************************************************************************************
; Macros
;*****************************************************************************************
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; Virtual Peripheral Guidelines Tip: 
; 
; To support compatibility between source code written for the SX28AC and
the SX52BD, 
; 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. 4
(for SX48/ ; 52BD/ ES) 
; or FSR. 7 (SX48/ 52bd production release) needs to be set appropriately,
depending 
; on the bank address being accessed. This macro fixes this. 
; 
; So, instead of using the bank instruction to switch between banks, use
_bank 
; instead. 
; 
;*********************************************************************************
_bank macro 1 
bank \1 
IFDEF SX48_ 52 
IFDEF SX48_ 52_ ES 
IF \1 & %00010000 ;SX48BD/ ES and SX52BD/ ES (engineering sample) bank
;instruction 
setb fsr. 4 ;modifies FSR bits 5,6 and 7. FSR. 4 needs to be set by ;software.
ENDIF 
ELSE 
IF \1 & %10000000 ;SX48BD and SX52BD (production release) bankinstruc-tion
 29 
29  Page 30
31 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 30 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
setb fsr. 7 ;modifies FSR bits 4,5 and 6. FSR. 7 needs to be set by
;software. 
ELSE 
clrb fsr. 7 
ENDIF 
ENDIF 
ENDIF 
endm 
;*********************************************************************************
; Macros for SX28AC/ 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, 
noexpand ;and SX28AC 
ENDIF 
endm 
;**********************************************************************************
; INCP/ DECP macros for incrementing/ decrementing pointers to RAM 
; used to compensate for incompatibilities between SX28AC and SX52BD 
;**********************************************************************************
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!
; Virtual Peripheral Guidelines Tip: 
; 
; To support compatibility between source code written for the SX28AC and
the SX52BD, 
; use macros. This macro compensates for the fact that RAM banks are
contiguous 
; in the SX52BD, but separated by 0x20 in the SX18/ 28. 
; 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!
INCP macro 1 
inc \1 
IFNDEF SX48_ 52 
setb \1.4 ; If SX18 or SX28AC, keep bit 4 of the pointer = 1 
ENDIF ; to jump from $1f to $30, etc.  30 
30  Page 31
32 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 31 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
endm 
DECP macro 1 
IFDEF SX48_ 52 
dec \1 
ELSE 
clrb \1.4 ; If SX18 or SX28AC, forces rollover to next bank 
dec \1 ; if it rolls over. (Skips banks with bit 4 = 0) 
setb \1.4 ; Eg: $30 --> $20 --> $1f --> $1f 
ENDIF ; AND: $31 --> $21 --> $20 --> $30 
endm 
;**********************************************************************************
; Error generating macros 
; Used to generate an error message if the label is 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 the table crosses a page boundary. 
; 
; Example: 
; lookupTable1 
; add pc, w 
; tableStart 
; retw 0 
; retw 20 
; retw -20 
; retw -40 
; 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  31 
31  Page 32
33 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 32 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
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  32 
32  Page 33
34 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 33 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
;*****************************************************************************************
; 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 
; label isrTemp1 for it. 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
flags0 equ global_ org + 0 ; stores bit-wise operators like flags 
; and function-enabling bits (semaphores) 
;VP: RS232 Receive 
rs232RxFlag equ flags0.0 ;indicates the reception of a bit from the UART
flags1 equ global_ org + 1 ; stores bit-wise operators like flags 
; and function-enabling bits (semaphores) 
localTemp0 equ global_ org + 2 ; temporary storage register 
; Used by first level of nesting 
; Never guaranteed to maintain data 
localTemp1 equ global_ org + 3 ; temporary storage register 
; Used by second level of nesting 
; or when a routine needs more than one 
; temporary global register. 
localTemp2 equ global_ org + 4 ; temporary storage register 
; Used by third level of nesting or by 
; main loop routines that need a loop 
; counter, etc. 
isrTemp0 equ global_ org + 5 ; Interrupt Service Routine's temp register.
; Don't use this register in the mainline. 
;*****************************************************************************************
; 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 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
 33 
33  Page 34
35 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 34 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
; Virtual Peripheral Guidelines Tip: 
; 
; Tip 1: 
; Indicate which Virtual Peripherals a portion of source code or declaration
be 
; longs to with a ;VP: VirtualPeripheralName 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: RS232 Transmit 
; 
; rs232TxBank = $ ;RS232 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 
; rs232TxString ds 1 ;the address of the string to be sent 
; rs232TxByte ds 1 ;semi-temporary serial register 
; 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;VP: ISR Multithreader 
isrMultiplex ds 1 ; The isrMultiplex register is used to switch to a new
; execution thread on each pass of the ISR. 
;*********************************************************************************
; Bank 2 
;*********************************************************************************
org bank2_ org 
bank2 = $ 
;*********************************************************************************
; Bank 3 
;*********************************************************************************
org bank3_ org 
bank3 = $ 
;*********************************************************************************
; Bank 4 
;*********************************************************************************
org bank4_ org 
bank4 = $ 
;*********************************************************************************
; Bank 5 
;*********************************************************************************
org bank5_ org 
bank5 = $  34 
34  Page 35
36 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 35 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
;*********************************************************************************
; Bank 6 
;*********************************************************************************
org bank6_ org 
bank6 = $ 
;*********************************************************************************
; Bank 7 
;*********************************************************************************
org bank7_ org 
bank7 = $ 
IFDEF SX48_ 52 
;*********************************************************************************
; Bank 8 
;*********************************************************************************
org $80 ;bank 8 address on SX52BD 
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 SX52BD 
bank9 = $ 
;*********************************************************************************
; Bank A 
;*********************************************************************************
org $A0 ;bank A address on SX52BD 
bankA = $ 
;*********************************************************************************
; Bank B 
;*********************************************************************************
org $B0 ;bank B address on SX52BD 
bankB = $ 
;*********************************************************************************
; Bank C 
;*********************************************************************************
org $C0 ;bank C address on SX52BD 
bankC = $  35 
35  Page 36
37 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 36 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
;*********************************************************************************
; Bank D 
;*********************************************************************************
org $D0 ;bank D address on SX52BD 
bankD = $ 
;*********************************************************************************
; Bank E 
;*********************************************************************************
org $E0 ;bank E address on SX52BD 
bankE = $ 
;*********************************************************************************
; Bank F 
;*********************************************************************************
org $F0 ;bank F address on SX52BD 
bankF = $ 
ENDIF 
;*********************************************************************************
; Pin Definitions: 
;*********************************************************************************
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; 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 
; -Hungarian Notation 
; -Less that 2 tabs in length 
; -Indicate the Virtual Peripheral the pin is used for 
; -Only use symbolic names to access a pin/ port in the source code. 
; -Example: 
; ; VP: RS232 Transmit 
; rs232TxPin equ ra. 3 
; 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
RA_ latch equ %00000000 ;SX18/ 20/ 28/ 48/ 52 port A latch init 
RA_ DDIR equ %11111111 ;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 %00000000 ;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 %11111111 ;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 %00000000 ;SX18/ 20/ 28/ 48/ 52 port B PLP value 
RC_ latch equ %00000000 ;SX18/ 20/ 28/ 48/ 52 port C latch init 
RC_ DDIR equ %11111111 ;SX18/ 20/ 28/ 48/ 52 port C DDIR value  36
36  Page 37
38 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 37 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
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 %00000000 ;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 %00000000 ;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 %00000000 ;SX48/ 52 port E PLP value 
ENDIF 
;*****************************************************************************************
; 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. 
; -Perform the calculation int_ period = (osc. frequency / interrupt frequency)
; = (50MHz / 307.2kHz) 
; = 162.7604 
; -Round int_ period to the nearest integer: 
; = 163 
; -Now calculate your actual interrupt rate: 
; = osc. frequency / int_ period 
; = 50MHz / 163 
; = 306.748kHz 
; -This interrupt frequency will be the timebase for all of the Virtual 
; Peripherals 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
int_ period = 217 ; Gives an interrupt period at 50MHz of (217 * (1/
50000000) s) = ; 4.34us 
; Which gives an interrupt frequency of (1/ 4.34us) Hz = 230414kHz 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; 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: 5ms Timer 
; TIMER_ DIV_ CONSTequ 192; This constant = timer sample rate/ 200Hz = 192
; 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
 37 
37  Page 38
39 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 38 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
;-------------------------------------------------------------------------------------
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, 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  38 
38  Page 39
40 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 39 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
; 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 
;*****************************************************************************************
; 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
*******************************  39 
39  Page 40
41 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 40 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
org INTERRUPT_ ORG ; First location in program memory. 
;*****************************************************************************************
;------------------------------------------------------------------------------
; Interrupt Service Routine 
;------------------------------------------------------------------------------
; Note: The interrupt code must always originate at address $0. 
; 
; Interrupt Frequency = (Cycle Frequency / -( retiw value)) For example:
; With a retiw value of -163 and an oscillator frequency of 50MHz, this 
; code runs every 3.26us. 
;------------------------------------------------------------------------------
ISR ;3 The interrupt service routine... 
;------------------------------------------------------------------------------
;VP: VP Multitasker 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; Virtual Peripheral Guidelines Tip: 
; -Multi-thread 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 ISR. 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 Multitasker: up to 24 individual threads, each running
at 
; the interrupt rate/ 24. Change the 
; 
; Input variable( s): isr_ multiplex: variable used to choose threads 
; Output variable( s): None, executes the next thread 
; Variable( s) affected: isr_ multiplex 
; Flag( s) affected: None 
; Program Cycles: 9 cycles (turbo mode) 
;------------------------------------------------------------------------------
_bank isrMultiplex ;1 
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 ;3,9 cycles. 
jmp isrThread2 ; 
jmp isrThread3 ; 
jmp isrThread4 ; 
jmp isrThread1 ; 
jmp isrThread5 ; 
jmp isrThread6 ;  40 
40  Page 41
42 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 41 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
jmp isrThread7 ; 
jmp isrThread1 ; 
jmp isrThread8 ; 
jmp isrThread9 ; 
jmp isrThread10 ; 
jmp isrThread1 ; 
jmp isrThread11 ; 
jmp isrThread12 ; 
jmp isrThread13 ; 
tableEnd ; End all tables with this macro. 
;------------------------------------------------------------------------------
;VP: VP Multitasker 
; ISR TASKS 
;------------------------------------------------------------------------------
isrThread1 ; Serviced at ISR rate / 4 
;------------------------------------------------------------------------------
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; Virtual Peripheral Guidelines Tip: 
; The sample rate of this section of code is the isr rate / 4, because it
is jumped 
; to in every 4th entry in the VP Multitaskers table. To increase the 
; sample rate, put more calls to this thread in the Multitasker's jump table.
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread2 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread3 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread4 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread5 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread6 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread7 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread8 ; Serviced at ISR rate / 16  41 
41  Page 42
43 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 42 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread9 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread10 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread11 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread12 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread13 ; Serviced at ISR rate / 16 
; ; This thread must reload the isrMultiplex register 
; since it is the last one to run in a rotation. 
;------------------------------------------------------------------------------
bank isrMultiplex 
mov isrMultiplex,# 255 ; Reload isrMultiplex so isrThread1 will be run 
; on next interrupt. 
jmp isrOut 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
isrOut 
;------------------------------------------------------------------------------
mov w,#-int_ period ;1 ; return and add -int_ period 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 reset_ entry must be placed in the first page,
along 
; with a 'page' instruction and a 'jump' instruction to the beginning of
the 
; main program. 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;------------------------------------------------------------------------------
resetEntry ; Program starts here on power-up 
page _resetEntry  42 
42  Page 43
44 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 43 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
jmp _resetEntry 
;------------------------------------------------------------------------------
;*****************************************************************************************
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; Virtual Peripheral Guidelines Tip: 
; ORG statements should use predefined labels rather than literal values.
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
org SUBROUTINES_ ORG 
;*****************************************************************************************
; Subroutines 
;*****************************************************************************************
;*****************************************************************************************
org STRINGS_ ORG ; This label defines where strings are kept in program space.
;*****************************************************************************************
;------------------------------------------------------------------------------
; Put String Data Here 
;------------------------------------------------------------------------------
; Example: 
;_ hello dw 13,10, 'UART Demo', 0 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; 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. 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
jmp $ ; This instruction will cause an assembler error if the source
code 
; before the org statement inadvertantly crosses a page boundary. 
;*****************************************************************************************
org MAIN_ PROGRAM_ ORG 
;*****************************************************************************************
 43 
43  Page 44
45 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 44 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
;------------------------------------------------------------------------------
; 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 
mov w,# RC_ ST ;Setup RC Schmitt Trigger, 0 = enabled, 1 = disabled 
mov !rc, w 
IFDEF SX48_ 52 
mov w,# RD_ ST ;Setup RD Schmitt Trigger, 0 = enabled, 1 = disabled 
mov !rd, w 
mov w,# RE_ ST ;Setup RE Schmitt Trigger, 0 = enabled, 1 = disabled 
mov !re, w 
ENDIF 
_mode LVL_ W ;point MODE to write LVL register 
mov w,# RA_ LVL ;Setup RA CMOS or TTL levels, 0 = TTL, 1 = CMOS 
mov !ra, w 
mov w,# RB_ LVL ;Setup RB CMOS or TTL levels, 0 = TTL, 1 = CMOS 
mov !rb, w 
mov w,# RC_ LVL ;Setup RC CMOS or TTL levels, 0 = TTL, 1 = CMOS 
mov !rc, w 
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 
_mode PLP_ W ;point MODE to write PLP register 
mov w,# RA_ PLP ;Setup RA Weak Pull-up, 0 = enabled, 1 = disabled 
mov !ra, w 
mov w,# RB_ PLP ;Setup RB Weak Pull-up, 0 = enabled, 1 = disabled 
mov !rb, w 
mov w,# RC_ PLP ;Setup RC Weak Pull-up, 0 = enabled, 1 = disabled 
mov !rc, w 
IFDEF SX48_ 52 
mov w,# RD_ PLP ;Setup RD Weak Pull-up, 0 = enabled, 1 = disabled 
mov !rd, w 
mov w,# RE_ PLP ;Setup RE Weak Pull-up, 0 = enabled, 1 = disabled 
mov !re, w 
ENDIF 
_mode DDIR_ W ;point MODE to write DDIR register 
mov w,# RA_ DDIR ;Setup RA Direction register, 0 = output, 1 = input 
mov !ra, w 
mov w,# RB_ DDIR ;Setup RB Direction register, 0 = output, 1 = input 
mov !rb, w 
mov w,# RC_ DDIR ;Setup RC Direction register, 0 = output, 1 = input 
mov !rc, w 
IFDEF SX48_ 52 
mov w,# RD_ DDIR ;Setup RD Direction register, 0 = output, 1 = input 
mov !rd, w  44 
44  Page 45
46 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 45 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
mov w,# RE_ DDIR ;Setup RE Direction register, 0 = output, 1 = input
mov !re, w 
ENDIF 
mov w,# RA_ latch ;Initialize RA data latch 
mov ra, w 
mov w,# RB_ latch ;Initialize RB data latch 
mov rb, w 
mov w,# RC_ latch ;Initialize RC data latch 
mov rc, w 
IFDEF SX48_ 52 
mov w,# RD_ latch ;Initialize RD data latch 
mov rd, w 
mov w,# RE_ latch ;Initialize RE data latch 
mov re, w 
ENDIF 
;------------------------------------------------------------------------------
; Clear all Data RAM locations 
;------------------------------------------------------------------------------
zeroRam 
IFDEF SX48_ 52 ;SX48/ 52 RAM clear routine 
mov w,#$ 0a ;reset all ram starting at $0A 
mov fsr, w 
:zeroRam clr ind ;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 ;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 ind ;clear using indirect addressing 
incsz fsr ;repeat until done 
jmp :zeroRam 
ENDIF 
;------------------------------------------------------------------------------
; Initialize program/ VP registers 
;------------------------------------------------------------------------------
45 
45  Page 46
47 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 46 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter2 Source Code Template 
;------------------------------------------------------------------------------
; 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 5 set to 1: RTCC increments on internal transitions 
; -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 lo) 
PS_ 000 = %00000000 ;RTCC = 1: 2, WDT = 1: 1 
PS_ 001 = %00000001 ;RTCC = 1: 4, WDT = 1: 2 
PS_ 010 = %00000010 ;RTCC = 1: 8, WDT = 1: 4 
PS_ 011 = %00000011 ;RTCC = 1: 16, WDT = 1: 8 
PS_ 100 = %00000100 ;RTCC = 1: 32, WDT = 1: 16 
PS_ 101 = %00000101 ;RTCC = 1: 64, WDT = 1: 32 
PS_ 110 = %00000110 ;RTCC = 1: 128, WDT = 1: 64 
PS_ 111 = %00000111 ;RTCC = 1: 256, WDT = 1: 128 
OPTIONSETUP equ RTCC_ PS_ OFF| PS_ 111 ; the default option setup for
this program. 
mov w,# OPTIONSETUP ; setup option register for RTCC interrupts enabled 
mov !option, w ; and no prescaler. 
jmp @mainLoop 
;------------------------------------------------------------------------------
; MAIN PROGRAM CODE 
;------------------------------------------------------------------------------
mainLoop 
jmp mainLoop  46 
46  Page 47
48 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 47 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter2 Source Code Template 
;*****************************************************************************************
END ;End of program code 
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
 47 
47  Page 48
49 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 48 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com 
Chapter3 
Adding A Virtual Peripheral to the Source Code Template 
3.1 Introduction 
This chapter shows the interaction between the Virtual Peripheral guideline
compliant template and a 
Virtual Peripheral module. 
3.2 Source Code Template With A Virtual Peripheral Example 
The following source code shows how a UART Virtual Peripheral module
can be added to the source 
code template described. 
;*****************************************************************************************
; Copyright © [11/ 21/ 1999] Scenix Semiconductor, Inc. All rights reserved.
; 
; Scenix Semiconductor, Inc. assumes no responsibility or liability for 
; the use of this [product, application, software, any of these products].
; Scenix Semiconductor conveys no license, implicitly or otherwise, under
; any intellectual property rights. 
; Information contained in this publication regarding (e. g.: application,
; implementation) and the like is intended through suggestion only and may
; be superseded by updates. Scenix Semiconductor makes no representation
; or warranties with respect to the accuracy or use of these information,
; or infringement of patents arising from such use or otherwise. 
;*****************************************************************************************
; 
; Filename: vpg_ UART_ 1_ 0. src 
; 
; Authors: Chris Fogelklou 
; Applications Engineer 
; Scenix Semiconductor, Inc. 
; 
; Revision: 1.00 
; 
; Part: Put part datecode here. 
; Freq: 25MHz 
; 
; Compiled using: Put assemblers/ debuggers/ hardware used here. 
; 
; Date Written: Jan 15, 2000 
; 
; Last Revised: Jan 15, 2000 
;  48 
48  Page 49
50 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 49 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
; Program Description: 
; 
; Virtual Peripherals Guidelines: 
; Example source code, running at 25MHz, with just a transmit 
; and receive UART. The code implements a 9600bps UART in software, 
; and the speed is defineable through equate statements. 
; 
; Interface Pins: 
; 
; rs232RxPin equ ra. 2 ;UART receive input 
; rs232TxPin equ ra. 3 ;UART transmit output 
; 
; Revision History: 
; 
; 1.0 Used the VP Guidelines multi-threaded example and inserted a UART 
; for an example of code that actually works. 
; 
; Put rest of revision history here... 
; 
;*****************************************************************************************
;*****************************************************************************************
; Target SX 
; Uncomment one of the following lines to choose the SX18AC, SX20AC, SX28AC,
SX48BD/ ES, 
; SX48BD, SX52BD/ ES or SX52BD. For SX48BD/ ES and SX52BD/ ES, uncomment
both defines, 
; SX48_ 52 and SX48_ 52_ ES. 
;*****************************************************************************************
;SX18_ 20 
SX28 
;SX48_ 52 
;SX48_ 52_ ES 
;*****************************************************************************************
; Assembler Used 
; Uncomment the following line if using the Parallax SX-Key assembler. SASM
assembler 
; enabled by default. 
;*****************************************************************************************
;SX_ Key 
;*********************************************************************************
; Assembler directives: 
; high speed external osc, turbo mode, 8-level stack, and extended option
reg. 
; 
; SX18/ 20/ 28 -4 pages of program memory and 8 banks of RAM enabled by default.
; SX48/ 52 -8 pages of program memory and 16 banks of RAM enabled by default.
; 
;*********************************************************************************
IFDEF SX_ Key ;SX-Key Directives 
IFDEF SX18_ 20 ;SX18AC or SX20AC device directives for SX-Key 
device SX18L, oschs2, turbo, stackx_ optionx 
ENDIF 
IFDEF SX28 ;SX28AC device directives for SX-Key 
device SX28L, oschs2, turbo, stackx_ optionx 
ENDIF 
IFDEF SX48_ 52_ ES ;SX48BD/ ES or SX52BD/ ES device directives for 
;SX-Key 
device oschs, turbo, stackx, optionx 
ELSE 
IFDEF SX48_ 52 ;SX48/ 52/ BD device directives for SX-Key 
device oschs2  49 
49  Page 50
51 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 50 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
ENDIF 
ENDIF 
freq 25_ 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_ ES ;SX48BD/ ES or SX52BD/ ES device directives for SASM 
device SX52, oschs, turbo, stackx, optionx 
ELSE 
IFDEF SX48_ 52 ;SX48BD or SX52BD device directives for SASM 
device SX52, oschs2 
ENDIF 
ENDIF 
ENDIF 
id 'VPGUART1' 
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. 4
; (for SX48/ 52BD/ ES) or FSR. 7 (SX48/ 52bd production release) needs to
be set 
; appropriately, depending on the bank address being accessed. This macro
fixes this. 
; 
; So, instead of using the bank instruction to switch between banks, use
_bank 
; instead. 
; 
;*********************************************************************************
_bank macro 1 
bank \1 
IFDEF SX48_ 52 
IFDEF SX48_ 52_ ES 
IF \1 & %00010000 ;SX48BD/ ES and SX52BD/ ES (engineering sample) bank
;instruction 
setb fsr. 4 ;modifies FSR bits 5,6 and 7. FSR. 4 needs to be set ;by
software. 
ENDIF 
ELSE 
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.
 50 
50  Page 51
52 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 51 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
ELSE 
clrb fsr. 7 
ENDIF 
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.  51 
51  Page 52
53 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 52 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
; 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
INCP macro 1 
inc \1 
IFNDEF SX48_ 52 
setb \1.4 ; If SX18 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 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 the table crosses a page boundary. 
; 
; Example: 
; lookupTable1 
; add pc, w 
; tableStart 
; retw 0 
; retw 20 
; retw -20 
; retw -40 
; 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 
;*****************************************************************************************
 52 
52  Page 53
54 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 53 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
; 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 label isrTemp1 for it. 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
flags0 equ global_ org + 0 ; stores bit-wise operators like flags 
; and function-enabling bits (semaphores) 
;VP: RS232 Receive 
rs232RxFlag equ flags0.0 ;indicates the reception of a bit from the UART
flags1 equ global_ org + 1 ; stores bit-wise operators like flags 
; and function-enabling bits (semaphores) 
localTemp0 equ global_ org + 2 ; temporary storage register 
; Used by first level of nesting 
; Never guaranteed to maintain data 
localTemp1 equ global_ org + 3 ; temporary storage register 
; Used by second level of nesting 
; or when a routine needs more than one 
; temporary global register. 
localTemp2 equ global_ org + 4 ; temporary storage register  53 
53  Page 54
55 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 54 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
; Used by third level of nesting or by 
; main loop routines that need a loop 
; counter, etc. 
isrTemp0 equ global_ org + 5 ; Interrupt Service Routine's temp register.
; Don't use this register in the mainline. 
;*****************************************************************************************
; 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 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; Virtual Peripheral Guidelines Tip: 
; 
; Tip 1: 
; Indicate which Virtual Peripherals a portion of source code or declaration
; belongs to with a ;VP: VirtualPeripheralName 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: RS232 Transmit 
; 
; rs232TxBank = $ ;RS232 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 
; rs232TxString ds 1 ;the address of the string to be sent 
; rs232TxByte ds 1 ;semi-temporary serial register 
; 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;VP: ISR Multithreader 
isrMultiplex ds 1 ; The isrMultiplex register is used to switch to a 
54 
54  Page 55
56 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 55 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
; new execution thread on each pass of the ISR. 
;VP: 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: RS232 Receive 
rs232RxBank = $ ;UART Receive bank 
rs232RxCount ds 1 ;number of bits received 
rs232RxDivide ds 1 ;receive timing counter 
rs232RxByte ds 1 ;buffer for incoming byte 
rs232Byte ds 1 ;used by serial routines 
;*********************************************************************************
; Bank 2 
;*********************************************************************************
org bank2_ org 
bank2 = $ 
;*********************************************************************************
; Bank 3 
;*********************************************************************************
org bank3_ org 
bank3 = $ 
;*********************************************************************************
; Bank 4 
;*********************************************************************************
org bank4_ org 
bank4 = $ 
;*********************************************************************************
; Bank 5 
;*********************************************************************************
org bank5_ org 
bank5 = $ 
;*********************************************************************************
; Bank 6 
;*********************************************************************************
org bank6_ org 
bank6 = $ 
;*********************************************************************************
; Bank 7 
;*********************************************************************************
org bank7_ org 
bank7 = $  55 
55  Page 56
57 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 56 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
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  56 
56  Page 57
58 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 57 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
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 
; -Hungarian Notation 
; -Less that 2 tabs in length 
; -Indicate the Virtual Peripheral the pin is used for 
; -Only use symbolic names to access a pin/ port in the source code. 
; -Example: 
; ; VP: RS232 Transmit 
; rs232TxPin equ ra. 3 
; 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;VP: RS232 Receive 
rs232RxPin equ ra. 2 ;UART receive input 
;VP: RS232 Transmit 
rs232TxPin equ ra. 3 ;UART transmit output 
RA_ latch equ %00001000 ;SX18/ 20/ 28/ 48/ 52 port A latch init 
RA_ DDIR equ %11110111 ;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 %00001000 ;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 %11111111 ;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 %00000000 ;SX18/ 20/ 28/ 48/ 52 port B PLP value 
RC_ latch equ %00000000 ;SX18/ 20/ 28/ 48/ 52 port C latch init 
RC_ DDIR equ %11111111 ;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 %00000000 ;SX18/ 20/ 28/ 48/ 52 port C PLP value  57 
57  Page 58
59 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 58 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
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 %00000000 ;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 %00000000 ;SX48/ 52 port E PLP value 
ENDIF 
;*****************************************************************************************
; 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. 
; -Perform the calculation int_ period = (osc. frequency / interrupt frequency)
; = (50MHz / 307.2kHz) 
; = 162.7604 
; -Round int_ period to the nearest integer: 
; = 163 
; -Now calculate your actual interrupt rate: 
; = osc. frequency / int_ period 
; = 50MHz / 163 
; = 306.748kHz 
; -This interrupt frequency will be the timebase for all of the Virtual 
; Peripherals 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
int_ period = 108 ; Gives an interrupt period at 50MHz of 
; (108 * (1/ 25000000) s) = 4.32us Which gives 
; an interrupt frequency of 
; (1/ 4.34us) Hz = 231481kHz 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; 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: 5ms Timer 
; TIMER_ DIV_ CONSTequ 192; This constant = timer sample rate/ 200Hz = 192
; 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;VP: RS232 Transmit AND  58 
58  Page 59
60 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 59 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
;VP: RS232 Receive 
UART1_ Fs = 57870 
; Actual calculated ISR frequency / 4. 
; How often is the UART sampled? If it is sampled on 
; every 4th pass of the ISR, so this number is the 
; ISR rate/ 4 this number must be close to the desired 
; UART rate * n. where n must be an even number 
;and preferably >= 4 
; For instance: For 38400bps, use 38400Hz* 4, 38400Hz* 6, ;etc. 
UART1_ Baud = 9600 ; Baud rate is 9600bps 
; *** Uart Divide Rates: These numbers indicate the divide rate for the
UARTs. 
; Example: If the desired UART rate is 19200 and the actual sample 
; rate is 230.4kHz, the divide ratio is 230.4kHz/ 19200Hz = 12 
UART1_ Divide = UART1_ Fs/ UART1_ Baud ; Divide rate constant used by
the program 
UART1_ St_ Delay = UART1_ Divide + (UART1_ Divide/ 2); Start delay constant
used by the program 
;-------------------------------------------------------------------------------------
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  59 
59  Page 60
61 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 60 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
; 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 
;*****************************************************************************************
; 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.  60 
60  Page 61
62 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 61 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
;****************************** 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 = (Cycle Frequency / -( retiw value)) For example:
; With a retiw value of -163 and an oscillator frequency of 50MHz, this 
; code runs every 3.26us. 
;------------------------------------------------------------------------------
ISR ;3 The interrupt service routine... 
;------------------------------------------------------------------------------
;VP: VP Multitasker 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; Virtual Peripheral Guidelines Tip: 
; -Multi-thread 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 ISR. 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 Multitasker: up to 24 individual threads, each running
at 
; the interrupt rate/ 24. Change the 
; 
; Input variable( s): isr_ multiplex: variable used to choose threads 
; Output variable( s): None, executes the next thread 
; Variable( s) affected: isr_ multiplex 
; Flag( s) affected: None  61 
61  Page 62
63 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 62 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
; Program Cycles: 9 cycles (turbo mode) 
;------------------------------------------------------------------------------
_bank isrMultiplex ;1 
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 ;3,9 cycles. isrThread1 runs the UART 
jmp isrThread2 ; 
jmp isrThread3 ; 
jmp isrThread4 ; 
jmp isrThread1 ; Call this thread 4 times/ cycle for an execution ;rate of
ISR_ rate/ 4 
jmp isrThread5 ; 
jmp isrThread6 ; 
jmp isrThread7 ; 
jmp isrThread1 ; 
jmp isrThread8 ; 
jmp isrThread9 ; 
jmp isrThread10 ; 
jmp isrThread1 ; 
jmp isrThread11 ; 
jmp isrThread12 ; 
jmp isrThread13 ; 
tableEnd ; End all tables with this macro. 
;------------------------------------------------------------------------------
;VP: VP Multitasker 
; ISR TASKS 
;------------------------------------------------------------------------------
isrThread1 ; Serviced at ISR rate / 4 
;------------------------------------------------------------------------------
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
; Virtual Peripheral Guidelines Tip: 
; The sample rate of this section of code is the isr rate / 4, because it
is jumped 
; to in every 4th entry in the VP Multitaskers table. To increase the 
; sample rate, put more calls to this thread in the Multitasker's jump table.
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;VP: RS232 Transmit 
;------------------------------------------------------------------------------
; Virtual Peripheral: Universal Asynchronous Receiver Transmitter (UART)
; These routines send and receive RS232 serial data, and are currently 
; configured (though modifications can be made) for the popular 
; "No parity-checking, 8 data bit, 1 stop bit" (N, 8,1) data format. 
; TRANSMITTING: The transmit routine requires the data to be inverted 
; and loaded (tx_ high+ tx_ low) register pair (with the inverted 8 data
bits 
; stored in tx_ high and tx_ low bit 7 set high to act as a start bit). Then
; the number of bits ready for transmission (10= 1 start + 8 data + 1 stop)
; must be loaded into the tx_ count register. As soon as this latter is done,
; the transmit routine immediately begins sending the data. 
; This routine has a varying execution rate and therefore should always be
; placed after any timing-critical virtual peripherals such as timers, 
; adcs, pwms, etc. 
; Note: The transmit and receive routines are independent and either may
be 
; removed, if not needed, to reduce execution time and memory usage, 
62 
62  Page 63
64 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 63 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
; as long as the initial "BANK serial" (common) instruction is kept.
; 
; Input variable( s) : tx_ low (only high bit used), tx_ high, tx_ count
; Variable( s) affected : tx_ divide 
; Program cycles: 17 worst case 
; Variable Length? Yes. 
; 
;------------------------------------------------------------------------------
rs232Transmit 
_bank rs232TxBank ;2 switch to serial register bank 
decsz rs232TxDivide ;1 only execute the transmit routine 
jmp :rs232TxOut ;1 
mov w,# UART1_ Divide ;1 load UART baud rate (50MHz) 
mov rs232TxDivide, w ;1 
test rs232TxCount ;1 are we sending? 
snz ;1 
jmp :rs232TxOut ;1 
:txbit clc ;1 yes, ready stop bit 
rr rs232TxHigh ;1 and shift to next bit 
rr rs232TxLow ;1 
dec rs232TxCount ;1 decrement bit counter 
snb rs232TxLow. 6 ;1 output next bit 
clrb rs232TxPin ;1 
sb rs232TxLow. 6 ;1 
setb rs232TxPin ;1,17 
:rs232TxOut 
;VP: RS232 Receive 
;------------------------------------------------------------------------------
; Virtual Peripheral: Universal Asynchronous Receiver Transmitter (UART)
; These routines send and receive RS232 serial data, and are currently 
; configured (though modifications can be made) for the popular 
; "No parity-checking, 8 data bit, 1 stop bit" (N, 8,1) data format. 
; RECEIVING: The rx_ flag is set high whenever a valid byte of data has been
; received and it is the calling routine's responsibility to reset this flag
; once the incoming data has been collected. 
; Output variable( s) : rx_ flag, rx_ byte 
; Variable( s) affected : tx_ divide, rx_ divide, rx_ count 
; Flag( s) affected : rx_ flag 
; Program cycles: 23 worst case 
; Variable Length? Yes. 
;------------------------------------------------------------------------------
rs232Receive 
_bank rs232RxBank ;2 
sb rs232RxPin ;1 get current rx bit 
clc ;1 
snb rs232RxPin ;1 
stc ;1 
test rs232RxCount ;1 currently receiving byte? 
sz ;1 
jmp :rxbit ;1 if so, jump ahead 
mov w,# 9 ;1 in case start, ready 9 bits 
sc ;1 skip ahead if not start bit 
mov rs232RxCount, w ;1 it is, so renew bit count 
mov w,# UART1_ St_ Delay ;1 ready 1.5 bit periods (50MHz) 
mov rs232RxDivide, w ;1 
:rxbit decsz rs232RxDivide ;1 middle of next bit? 
jmp :rs232RxOut ;1 
mov w,# UART1_ Divide ;1 yes, ready 1 bit period (50MHz)  63 
63  Page 64
65 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 64 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
mov rs232RxDivide, w ;1 
dec rs232RxCount ;1 last bit? 
sz ;1 if not 
rr rs232RxByte ;1 then save bit 
snz ;1 if so, 
setb rs232RxFlag ;1,23 then set flag 
:rs232RxOut ; else, exit 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread2 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread3 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread4 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread5 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread6 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread7 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread8 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread9 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread10 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution  64 
64  Page 65
66 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 65 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
;------------------------------------------------------------------------------
isrThread11 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread12 ; Serviced at ISR rate / 16 
;------------------------------------------------------------------------------
jmp isrOut ;7 cycles until mainline program resumes execution 
;------------------------------------------------------------------------------
isrThread13 ; Serviced at ISR rate / 16 
; ; This thread must reload the isrMultiplex register 
; since it is the last one to run in a rotation. 
;------------------------------------------------------------------------------
bank isrMultiplex 
mov isrMultiplex,# 255 ; Reload isrMultiplex so isrThread1 will be run 
; on next interrupt. 
jmp isrOut 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
isrOut 
;------------------------------------------------------------------------------
mov w,#-int_ period ;1 ; return and add -int_ period 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 reset_ entry must be placed in the first page,
along 
; with a 'page' instruction and a 'jump' instruction to the beginning of
the 
; main program. 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
;------------------------------------------------------------------------------
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  65 
65  Page 66
67 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 66 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
;*****************************************************************************************
; Subroutines 
;*****************************************************************************************
;------------------------------------------------------------------------------
;VP: RS232 Transmit 
; Function: send_ byte 
; Send byte via serial port 
; INPUTS: 
; w -The byte to be sent via RS-232 
; OUTPUTS: 
; outputs the byte via RS-232 
;------------------------------------------------------------------------------
sendByte mov localTemp0, w 
_bank rs232TxBank 
:wait test rs232TxCount ;wait for not busy 
sz 
jmp :wait ; 
not w ;ready bits (inverse logic) 
mov rs232TxHigh, w ;store data byte 
setb rs232TxLow. 7 ;set up start bit 
mov w,# 10 ;1 start + 8 data + 1 stop bit 
mov rs232TxCount, w 
retp ;leave and fix page bits 
;------------------------------------------------------------------------------
;VP: RS232 Transmit 
; Subroutine -Send string pointed to by address in W register 
; INPUTS: 
; w -The address of a null-terminated string in program 
; memory 
; OUTPUTS: 
; outputs the string via. RS-232 
;------------------------------------------------------------------------------
sendString 
_bank rs232TxBank 
mov localTemp1, w ;store string address 
:loop 
mov w,# STRINGS_ ORG>> 8 ;with indirect addressing 
mov m, w 
mov w, localTemp1 ;read next string character 
iread ;using the mode register 
test w ;are we at the last char? 
snz ;if not= 0, skip ahead 
jmp :out ;yes, leave & fix page bits 
call sendByte ;not 0, so send character 
_bank rs232TxBank 
inc localTemp1 ;point to next character 
jmp :loop ;loop until done 
:out mov w,#$ 1F ;reset the mode register 
mov m, w 
retp 
;------------------------------------------------------------------------------
;VP: RS232 Receive 
; Subroutine -Get byte via serial port. 
; INPUTS: 
; -NONE 
; OUTPUTS:  66 
66  Page 67
68 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 67 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
; -received byte in rs232Byte and w register 
;------------------------------------------------------------------------------
getByte jnb rs232RxFlag,$ ;wait till byte is received 
clrb rs232RxFlag ;reset the receive flag 
_bank rs232RxBank ;switch to rs232 bank 
mov rs232Byte, rs232RxByte ;store byte (copy using W) 
retp 
;------------------------------------------------------------------------------
;*****************************************************************************************
org STRINGS_ ORG ; This label defines where strings are kept in program space.
;*****************************************************************************************
;------------------------------------------------------------------------------
; String Data 
;------------------------------------------------------------------------------
;VP: RS232 Transmit 
_hello dw 13,10, 'Yup, The UART works!!! ', 0 
_hitSpace dw 13,10, 'Hit Space... ', 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. 
;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
jmp $ ; This instruction will cause an assembler error if the source
code 
; before the org statement inadvertantly crosses a page boundary. 
;*****************************************************************************************
org MAIN_ PROGRAM_ ORG 
;*****************************************************************************************
 67 
67  Page 68
69 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 68 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
;------------------------------------------------------------------------------
; 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 
mov w,# RC_ ST ;Setup RC Schmitt Trigger, 0 = enabled, 1 = disabled 
mov !rc, w 
IFDEF SX48_ 52 
mov w,# RD_ ST ;Setup RD Schmitt Trigger, 0 = enabled, 1 = disabled 
mov !rd, w 
mov w,# RE_ ST ;Setup RE Schmitt Trigger, 0 = enabled, 1 = disabled 
mov !re, w 
ENDIF 
_mode LVL_ W ;point MODE to write LVL register 
mov w,# RA_ LVL ;Setup RA CMOS or TTL levels, 0 = TTL, 1 = CMOS 
mov !ra, w 
mov w,# RB_ LVL ;Setup RB CMOS or TTL levels, 0 = TTL, 1 = CMOS 
mov !rb, w 
mov w,# RC_ LVL ;Setup RC CMOS or TTL levels, 0 = TTL, 1 = CMOS 
mov !rc, w 
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 
_mode PLP_ W ;point MODE to write PLP register 
mov w,# RA_ PLP ;Setup RA Weak Pull-up, 0 = enabled, 1 = disabled 
mov !ra, w 
mov w,# RB_ PLP ;Setup RB Weak Pull-up, 0 = enabled, 1 = disabled 
mov !rb, w 
mov w,# RC_ PLP ;Setup RC Weak Pull-up, 0 = enabled, 1 = disabled 
mov !rc, w 
IFDEF SX48_ 52 
mov w,# RD_ PLP ;Setup RD Weak Pull-up, 0 = enabled, 1 = disabled 
mov !rd, w 
mov w,# RE_ PLP ;Setup RE Weak Pull-up, 0 = enabled, 1 = disabled 
mov !re, w 
ENDIF 
_mode DDIR_ W ;point MODE to write DDIR register 
mov w,# RA_ DDIR ;Setup RA Direction register, 0 = output, 1 = input 
mov !ra, w 
mov w,# RB_ DDIR ;Setup RB Direction register, 0 = output, 1 = input 
mov !rb, w 
mov w,# RC_ DDIR ;Setup RC Direction register, 0 = output, 1 = input 
mov !rc, w 
IFDEF SX48_ 52 
mov w,# RD_ DDIR ;Setup RD Direction register, 0 = output, 1 = input 
mov !rd, w  68 
68  Page 69
70 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 69 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
mov w,# RE_ DDIR ;Setup RE Direction register, 0 = output, 1 = input
mov !re, w 
ENDIF 
mov w,# RA_ latch ;Initialize RA data latch 
mov ra, w 
mov w,# RB_ latch ;Initialize RB data latch 
mov rb, w 
mov w,# RC_ latch ;Initialize RC data latch 
mov rc, w 
IFDEF SX48_ 52 
mov w,# RD_ latch ;Initialize RD data latch 
mov rd, w 
mov w,# RE_ latch ;Initialize RE data latch 
mov re, w 
ENDIF 
;------------------------------------------------------------------------------
; Clear all Data RAM locations 
;------------------------------------------------------------------------------
zeroRam 
IFDEF SX48_ 52 ;SX48/ 52 RAM clear routine 
mov w,#$ 0a ;reset all ram starting at $0A 
mov fsr, w 
:zeroRam clr ind ;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 ;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 ind ;clear using indirect addressing 
incsz fsr ;repeat until done 
jmp :zeroRam 
ENDIF 
;------------------------------------------------------------------------------
; Initialize program/ VP registers 
;------------------------------------------------------------------------------
bank rs232TxBank ; Select the bank  69 
69  Page 70
71 
© 2000 Scenix Semiconductor, Inc. All rights reserved. 70 SX
Virtual Peripheral Methodology & Modules Rev. 1.0 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
Template 
mov w,# UART1_ Divide ;load initial UART baud rate 
mov rs232TxDivide, w ; 
;------------------------------------------------------------------------------
; 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 5 set to 1: RTCC increments on internal transitions 
; -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 lo) 
PS_ 000 = %00000000 ;RTCC = 1: 2, WDT = 1: 1 
PS_ 001 = %00000001 ;RTCC = 1: 4, WDT = 1: 2 
PS_ 010 = %00000010 ;RTCC = 1: 8, WDT = 1: 4 
PS_ 011 = %00000011 ;RTCC = 1: 16, WDT = 1: 8 
PS_ 100 = %00000100 ;RTCC = 1: 32, WDT = 1: 16 
PS_ 101 = %00000101 ;RTCC = 1: 64, WDT = 1: 32 
PS_ 110 = %00000110 ;RTCC = 1: 128, WDT = 1: 64 
PS_ 111 = %00000111 ;RTCC = 1: 256, WDT = 1: 128 
OPTIONSETUP equ RTCC_ PS_ OFF| PS_ 111 ; the default option setup for
this program. 
mov w,# OPTIONSETUP ; setup option register for RTCC interrupts enabled 
mov !option, w ; and no prescaler. 
jmp @mainLoop 
;------------------------------------------------------------------------------
; MAIN PROGRAM CODE 
;------------------------------------------------------------------------------
mov w,_ hitSpace ; Send prompt to terminal at UART rate 
call @sendString 
mainLoop 
call @getByte 
cjne rs232Byte,# ' ', mainLoop ; just keep looping until user 
; hits the space bar 
mov w,#_ hello ; When space bar hit, send out string.  70 
70  Page 71 
SX Virtual Peripheral Methodology & Modules Rev. 1.0 71 ©
2000 Scenix Semiconductor, Inc. All rights reserved. 
www. scenix. com Chapter3 Adding A Virtual Peripheral to the Source Code
call @sendString 
jmp mainLoop 
;*****************************************************************************************
END ;End of program code 
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
;*****************************************************************************************
 71
1 2 3
4 5 6
7 8 9 
10 11 12
13 14 15
16 17 18
19 
20 21 22
23 24 25
26 27 28
29 
30 31 32
33 34 35
36 37 38
39 
40 41 42
43 44 45
46 47 48
49 
50 51 52
53 54 55
56 57 58
59 
60 61 62
63 64 65
66 67 68
69 
70 71
| file: /Techref/scenix/vpdesignguide.htm, 178KB, , updated: 2002/3/12 13:21, local time: 2025/10/31 03:01, 
 
216.73.216.219,10-1-97-123:LOG IN | 
| ©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.ecomorder.com/techref/scenix/vpdesignguide.htm"> Pages 1--71 from VP.book</A> | 
| Did you find what you needed? | 
| Welcome to ecomorder.com! | 
| Welcome to massmind.ecomorder.com! | 
.