Skip to main content

Full text of "national :: appNotes :: AN-1099"

See other formats


Creating a Multitasking 
Kernel for the C0P8 
Microcontroller 



INTRODUCTION 

Everyone is familiar with multi-tasking operating systems 
such as Microsoft™ Windows 8 and UNIX®. These systems 
have the advantages of executing several tasks at once al- 
lowing a single CPU to do the job of several. These systems 
however, use very fast and sophisticated computers to run 
optimally. When it comes to the world of microcontrollers 
however, it seems very unlikely that one can take advantage 
of the features and benefits of a multitasking system. This is 
not necessarily true. With a little care and understanding of 
the limits of microcontrollers, a full-featured multitasking ker- 
nel (MTK) can be created. This MTK can allow many sepa- 
rate tasks to share the microcontroller's CPU and on-board 
peripherals and provide the added bonus of reduced time to 
market and lower development cost. In this application note, 
we will discuss the various types of multitasking systems, the 
best choice for a microcontroller, and how to implement an 
MTK in assembly language for the new COP8SGR micro- 
controller — a true system on a chip. 

MULTITASKING SYSTEMS 

The word "Multitasking" or "Multithreading" can have several 
meanings, but they generally refer to performing more than 
one task at a time. In reality, multitasking operating systems 
generally are sharing the CPU among many tasks. This 
sharing is done so fast that it provides the illusion that the 
computer is actually doing more than one thing at a time. 
This sharing technique assumes a single processor. Some 
computers however, actually have many processors in paral- 
lel and the operating system assigns an individual processor 
to each task. In the case of the COP8, there is only the single 
CPU and its peripherals to share among many tasks. This 
requires a mechanism to "switch" which task is actually run- 
ning on the CPU. There are several task-switching methods 
in use today, two of which are "Preemptive" and "Coopera- 
tive". 

The "Preemptive" method shown in Figure 1 allows a task, 
such as calculating the number pi, to execute for some pre- 
determined time. At the end of that time, the operating sys- 
tem or MTK suspends that task's ownership of the computer 
and enables the next task in a queue. The order in the queue 
can often be modified to allow higher priority tasks to get ser- 
vice faster. The problem with preemptive operating systems 
is that they require a great deal of resources for switching 
tasks. Since the task is stopped without warning — and 
usually in the middle of something complex, a complete, 
separate memory stack and variable space must be main- 
tained for each task that is running. This also includes saving 
the address of the last instruction executed, and all the reg- 
ister states before the task was stopped. This is required to 
enable the operating system to restore the previous state of 
the task when it's time to start it again. This typically happens 
about every millisecond, but can happen faster or slower de- 
pending on real-time requirements. A characteristic of this 
type of task switching is that every task gets an equal 
amount of the system's CPU. 



UNIX® is a registered trademark of A T & T Bell Laboratories 
Microsoft™ is a trademark of Microsoft Corporation. 
Windows® is a registered trademark of Microsoft Corporation. 



National Semiconductor 
Application Note 1099 
Richard F. Zarr 
March 1998 



(9 



The "Cooperative" switching method shown in Figure 2 
handles tasks differently. The cooperative operating system 
uses a special understanding between the program task and 
itself to facilitate the sharing of resources. This "understand- 
ing" is as follows. Any task has full access to the CPU re- 
source for as long as it requires, but must return the resource 
within a reasonable amount of time. Each thread must run 
from beginning to end, keeping track of its own state and 
then returning to the operating system. This implies that if 
the task does not return the CPU resource (i.e. gets stuck in 
an infinite loop), the system crashes or locks up. Sound fa- 
miliar? The first versions of Microsoft Windows (Windows 
3.x) used this scheme. If a program locked up, only an inter- 
rupt (such as the familiar ALT-CTRL-DEL sequence) could 
get the operating system's attention. Unix and Windows NT 
however, use a fully preemptive task switching method, 
which is much more robust. 

Which method should be used for a microcontroller? The 
preemptive method is robust, but carries a heavy penalty in 
resources. The cooperative method uses much fewer re- 
sources, but can still lock up. A simple solution is to increase 
the robustness of the cooperative method by adding some of 
the qualities of the preemptive method. We'll call this method 
the "Supervised Cooperative" method and this will be the ba- 
sis for COP8 based MTK. By adding some "watch-dog" fea- 
tures to the operating system, each task thread can be moni- 
tored for its usage of the CPU resource. If a task takes too 
long, it can be stopped and restarted — a nice feature. 

THE SUPERVISED COOPERATIVE MULTITASKING 
KERNEL 

The kernel used in this application note will use the super- 
vised cooperative method of task switching. Since the 
COP8SGR has a watch-dog timer (Timer TO) that is always 
running, an interrupt can be generated periodically to check 
the status of each task. Every 4096 cycle of the instruction 
cycle clock, Timer TO can generate an interrupt. At 10 MHz, 
that is about every 4 milliseconds. By using this "Tick", the 
operating system can "watch" threads execute. If a task is 
stuck, or locked up in a loop due to a coding error or other 
failure, the operating system can recover. Here's how it 
works. Every time a task is switched, a counter is loaded with 
a user selectable value (1-255). This number is the maxi- 
mum task time allowed by the operating system. A zero 
value disables this feature by turning off the timer TO inter- 
rupt. To calculate the worst case time, use the following cal- 
culation: 

Tmax = n * Tcycle * 4096 where n is the value passed 
to osSetMaxTaskTime 

If a task locks up in this example operating system, the OS 
transfers control to the first task loaded — the MAIN task. 
This task should have a message-processing loop to handle 
operating system messages from timers, UARTs, and the 
operating system itself. These messages are passed back to 
the loop in the accumulator on entry. If there are no mes- 



o 

CD 
0> 

f-CH 

d" 

fi) 



&) 
CO 

IQ 
CD 
CD 



CD 

o 
o 

oo 



o 

-i 
o 
o 
o 



o 

cb" 



o 

CO 
CO 



) 1 999 National Semiconductor Corporation AN 1 00833 



www.national.com 



sages for the message loop, the accumulator will be null 
(zero). If a task locks up, the main loop will receive a 
mTaskFailure message. The application can identify the 
task by looking at the 'B' register in the message loop. The 
main task can then restart it without affecting the other run- 
ning tasks. To prevent locking up again, the OS stops the 



failed task. This requires the application to restart it implicitly. 
Task 1 (the first task added) is always the main task. If the 
main task fails, the OS will automatically restart the micro- 
controller since this is a fatal failure. A sample Main Task 
message loop is shown below. 



IFEQ 


A, ImNone 


JP 


MainContinue 


IFEQ 


A, #mTime 


JP 


MainTimer 


IFEQ 


A, #mUART 


JP 


MainUART 


IFEQ 


A, #mTaskFailure 


JP 


MainRestartTask 


inContinue : 



Any messages? 

No, continue with other main activities 

Was it a timer message 

Yes, go service the timer tick. 

Was it a UART message? 

Yes, go service the UART 

Did a task lock up? 

Yes, go fix it 



(Do other main stuff here) 



MainTimer : 

LD A, B 



; Done, return to OS 



holds which timer ticked. 



(Do stuff with timer tick) 

JP MainExit ; Done, return to OS 



MainUART: 

LD A, B 



(Do UART stuff) 



MainExit 



MainRestartTask : 

LD A, B 

IFEQ A, #2 

JSR 

IFEQ 

JSR 



StartTask2 

A, #3 
StartTask3 



'B' holds UART action reguired. 



Done, return to OS 



'B' holds which timer ticked... 

Task 2? 

Yes, Reload data for task 2 and restart it. 

Task 3? 

Yes, Reload data for task 3 and restart it. 



(Continue checking for other failed tasks here) 



MainExit : 
RET 



Return to OS 



SOME CONCEPTS 

We've already discussed the idea of a task or thread, but 
let's review the idea again. A "Task" or "Thread" is a distinct 
piece of code (software) that handles a specific task. This 
task might be scanning a keyboard for input, updating a mul- 
tiplexed display, communicating on a network with other de- 
vices, reading external or internal peripherals for data, and 
much more. The task structure for the supervised coopera- 
tive OS requires the code to execute completely in very few 
passes — that is, very little looping. Loops require time, and 
hog the CPU resource. These tasks look very much like sub- 
routines in that they are called by the OS, execute a function, 
and return back to the OS when completed. While the task is 
running however, no other task can have the CPU resource. 

Another concept is the "Callback". Callbacks are a method of 
dynamically allocating resources such as timers, UARTs or 
other on-board microcontroller peripherals, and providing a 
direct handler for the resource — circumventing the main 
message loop. This concept works like this. A special piece 



of code is written to handle a specific task. This code's ad- 
dress is passed to the operating system as a location to "call" 
when this function is needed. This feature provides the ben- 
efit of not requiring the main task message loop to process 
the interrupt and figure out what happened. The interrupt is 
simply routed directly to the service routine. Callbacks can 
also augment or override a default function, or provide a 
completely new function. Let's examine an example of a call- 
back implementation. 

A timer resource can be dynamically allocated using a call- 
back. The application can specify an interval for a timer, and 
a routine to call when each time tick occurs. The routine is 
"Called Back" after each tick of the timer. The timer can also 
be used once to time a specific event without "looping" to 
burn time. The timer is created using osSetTimer, which 
also assigns a callback routine when the time period ends. 
The callback in turn stops the timer and frees the timer re- 
source using osKillTimer. The callback routine can then 
continue its operation following the time delay. This also illus- 



www.national.com 



trates the idea of a "Resource Pool". The example MTK will 
use this concept to manage the COP8SGR UART and 
TIMER resources. Feel free to modify the MTK to extend this 
idea for handling other resources as well. 

USING THE MULTITASKING KERNEL 

The COP8SGR MTK architecture is shown in Figure 3. The 
COP8SGR has 4 pages of memory, each of which is 128 
bytes long for a total of 51 2 bytes. They are selected by writ- 
ing the page number into the segment register "S". The 
COP8 uses the last 16 bytes of PAGE for registers, so they 
cannot be used for data storage. There is a single stack that 
is located in PAGE 0, however it is available in any page 
when using the POP and PUSH instructions. This is very im- 
portant for this MTK in that the stack is used for passing in- 
formation between the operating system and the application. 



We will use page 1 for the operating system, but any page 
other than zero will work fine. This reserves 1 28 bytes for the 
operating system. The COP8SGR has 3 general purpose 
timers (T1-T3), and a watchdog timer (TO), as well as a full- 
featured UART. The operating system will control access to 
these resources to allow sharing among many threads. 
The initialization routine sets up all the COP8SGR memory 
and internal registers after reset and then calls a user setup 
routine called "INITIALIZE". This is the first routine that gets 
control in the users code. Here the user should setup all the 
tasks that are initially active (more can be created later). This 
is done by pushing information onto the stack and calling the 
osAddTask routine. Here's what the code looks like to add a 
task called "MAIN". 



Initialize : 

LD A, #LOW(Main) 

PUSH A 

LD A, #HIGH(Main) 

PUSH A 

JSR osAddTask 

X A, hMainTask 



Add to task list 
LSB First 

MSB Second 

Go add it . . . 

Save the task handle. 



This should be done for each of the tasks the user needs to 
run. Each time a task gets control, the entry point is always 
the same. In the above example, the entry point was called 
MAIN. Each task is responsible for keeping track of itself and 
using as little time as required to perform its function. Each 



task is in effect "looping" along as the operating system 
passes control to it. Each task also must be started. This en- 
ters the task into the switching queue to await execution. 
This is accomplished as follows. 



LD 
JSR 



A, hMyTask 
osStartTask 



Tell OS which task to start 
Start the task 



At the end of the INITIALIZE routine, the code should start 
the MTK as follows. 

JSR osStart 

This begins the multitasking kernel and begins the task 
switching. An error recovery routine should follow this jump 
subroutine command. If the OS has a fatal error, it will return 
and execute instructions following this call. This allows the 
user to select a method of restarting the processes in the 
case of a catastrophic code failure. This is equivalent to the 
BLUE SCREEN OF DEATH seen on many PCs. 
Once the OS has begun, each task will be executed in turn. 
The entry point for each routine will be the values passed to 
the OS by the osAddTask call. Resource callbacks will be 
executed whenever that resource requires attention — such 
as a received character in the UART RX Buffer. The applica- 
tion can suspend any task by calling osStopTask. Again, 
feel free to modify the MTK code given in this application 
note to add features you may need. 

ALLOCATING RESOURCES 

To acquire a microcontroller resource such as a timer, the 
application code should use the operating system as op- 
posed to using the resource directly. What's the advantage 



of that? Other tasks cannot tell if a particular resource is in 
use, the operating system can. For the case of the on-board 
timers, of which the COP8SGR has 3, the MTK has a special 
operating system routine that requests a timer resource. 
Since all the general purpose timers are identical, it doesn't 
matter which timer a task uses. Therefore, the operating sys- 
tem decides which timer a task will get. This way, if another 
task needed a timer for awhile, and it received timer 1, the 
current task requesting a timer would get timer 2. Timer allo- 
cation (as well as UART and other peripheral allocation) is 
done using "handles". Handles are nothing more than a 
number that indicates which entry in a table belongs to a par- 
ticular task. The handle allows both the task and OS to know 
which items belong to whom. The handle is returned by the 
operating system if the task received the timer (or periph- 
eral). If not, the handle will be NULL or zero. Otherwise it will 
be a number greater than 0. This number must be kept in or- 
der to free the resource when a task has finished using it. For 
instance, to request a timer a task would do the following. 



LD 


A, 


#cPeriodLo 


PUSH 


A 




LD 


A, 


#cPeriodHi 


PUSH 


A 




LD 


A, 


#LOW (MyTimerCallBack) 


PUSH 


A 




LD 


A, 


#HIGH (MyTimerCallBack 


PUSH 


A 




JSR 


OS 


SetTimer 


IFEQ 


A, 


#0 



Setup time period 
Low order first 
followed by high order 

Setup call back 



Go get a timer resource 
Was the resource available? 



www.national.com 



JP 

X 
(Continue) 



GetTimerFailure 
A, hMyTimer 



No, bail and try later 
Yes, save the timer handle 



To release the timer resource after the task is finished with it, 
the code should call the Kill Timer routine as follows. 



LD A, hMyTimer 
JSR osKillTimer 



Free my timer 



This routine will return zero in the accumulator if successful 
and non-zero if it fails. An invalid handle here can cause 
chaos. It may stop and release a timer being used by some 
other task that's critical to the application. Always store 
handles locally to the task. That is, keep a special variable 
that only that task uses for keeping the timer handle. No glo- 
bal variables for handles! 

The timer allocation routine for this MTK is quite simple. It 
only allows for creating callbacks on a periodic basis. The 
general purpose timers in the COP8SGR however, are much 
more sophisticated. They have the ability to perform pulse 
width modulation (PWM) and capture the time between 
events as well. A more sophisticated callback handler would 
allow a mode select a particular timer and setup the timer for 
PWM operation, capture mode, or a periodic time. The rou- 
tines in this application note can easily be expanded to in- 
clude these features. Feel free to experiment and either 
modify these timer resource allocation routines or create 
your own. 

WRITING TASKS 

Obviously, the user of this MTK needs to add application 
specific code to make it useful. The code is basically made 
up of a collection of tasks that the application needs to per- 
form. These tasks, as mentioned earlier, can handle many 



functions such as updating a multiplexed display, or scan- 
ning a keyboard. To write these task follow these simple 
rules. 

1 . Write the task as a subroutine — a single entry and exit 
point. This improves maintainability as well. 

2. Keep tasks specific — perform single operations per 
task. 

3. Avoid loops — The longer a task holds a resource such 
as the CPU, the less efficient the OS becomes. 

4. Use callbacks for timers, UARTs, and other OS sup- 
ported on-board peripherals. 

A sample task that illustrates these points well is multiplexing 
an LED display. This example will use 4 common anode 7 
segment displays. The D PORT of the COP8SGR will be 
used to drive the multiplexed segments directly, and the 
lower 4 F PORT bits will be used to drive PNP transistors to 
supply anode current to the 7 segment displays (8 segments 
including the decimal point). See Figure 4 for the connection 
diagram. A callback from a timer will be used to maintain a 
constant refresh on the display. The period only needs to be 
about 4 mS, which provides a total refresh time of about 16 
milliseconds for 4 digits. This is fast enough that the human 
eye will not see any flickering of the display. The PNP tran- 
sistors require the pin to go low to turn on, so the code in the 
following example deals with these pins as active low or in- 
verted — notice the digit drive table entries are inverted as 
well. 
The variables in RAM for this routine are as follows 



bDigitCount .DSB 1 
bDispBuffer .DSB 4 



Provide 
Provide 



counter to keep track of which digit is in use 
buffer for the characters 



The timer will be assigned in the INITIALIZE routine. 



LD 

PUSH 

LD 

PUSH 

LD 

PUSH 

LD 

PUSH 

JSR 

IFEQ 

JP 

X 



#cRef reshLo 



A, 

A 

A, #cRefreshHi 

A 

A, #LOW(ServiceDisplay 

A 

A, #HIGH (ServiceDisplay) 

A 

osSetTimer 

A, #0 

GetTimerFailure 

A, hRefreshTimer 



(Continue . . . ) 



Setup time period to refresh the display 
Low order first 
followed by high order 

Setup a call back to service the display 



Go get a timer resource for this function 

Was the resource available? 

No, bail and try later 

Yes, save the timer handle 

Continue to initialize other stuff... 



The service routine for refreshing the 7 segment displays 
looks like this. 



ServiceDisplay 






LD 


A, 


PORTFD ; 


OR 


A, 


#X' OF ; 


X 


A, 


PORTFD ; 


LD 


A, 


bDigitCount ; 


ADD 


A, 


bDispBuffer 


X 


A, 


B ; 


LD 


A, 


[B] ; 


XOR 


A, 


#X'FF ; 


X 


A, 


PORTD ; 


LD 


A, 


bDigitCount ; 



Get current value of port F data 

Turn off all digits while updating (active low) 

Write new value to port F data 

Get current digit (0-3) 

Use ' B' to point to buffer 
Get the character to display 
Invert for active low drive 
Write new value 

Get digit count to turn on new digit 



www.national.com 



ADD 


A, DGTable 




Use the count to select the digit table entry 


LAID 






Load the accumulator with the digit data 


AND 


A, PORTFD 




Add what's already on the upper port pins 


X 


A, PORTFD 




Write to F PORT data 


LD 


A, bDigitCount 


Get digit count and update 


INC 


A 




Point to next digit 


IFGT 


A, #cMaxDigits-l 


Check if past last digit 


LD 


A, #0 




Yes, Reload to beginning 


X 


A, bDigitCount 


Save back for next pass 


RET 






Return to OS 


DGTable: 








.DB 


B' 11111110 




Digit 1 


.DB 


B' 11111101 




Digit 2 


.DB 


B' 11111011 




Digit 3 


.DB 


B' 11110111 




Digit 4 


As this above example illustrates, the task uses a callback variable with the scan code for that key. A scan code of OxFF 


from the timer and 


updates a new digit each time the routine could be a no-key-pressed state. An example of this would 


gets called by the operating system. It uses 


a single entry be to use the L PORT of the COP8SGR for 16 keys con- 


and exit point, is brief and handles 


a single function. These nected in a matrix to the port. The lower 4 bits will be the driv- 


rules can be broken with care. Fo 


example, a task could ers (active low) and the upper 4 will be the inputs (pulled-up). 


have a single entry point and multip 


e exit points, however, it When a button is pushed it will short one of 4 lower port pins 


complicates the maintenance of the software 


to one of the upper 4. See Figure 5. The task code would 


Another example task would be to scan a keyboard for a but- '°°k ''^ e ' n ' s - 


ton closure. If a button is pressed, 


the task should load a 


ScanKeys : 








LD 


rRowCount , 


#4 




Scan 4 row (OK for only 4 passes in MTK) 


LD 


bRowSel, #01 




Use memory location for row select. 


LD 


PORTLC, #X 


OF 




Lower 4 bits outputs, upper 4 bits inputs 


LD 


PORTLD, #X 


FF 




Pull upper bits high, Clear driver bits 


LD 


B, #01 






Row to scan 


ScanKeysLoop : 










LD 


A, bRowSel 






Get scan row 


XOR 


A, #X'FF 






Turn on (active low) scan row 


X 


A, PORTLD 






Send to port data 


LD 


A, PORTLP 






Check the pins on port L for change 


XOR 


A, #X'FF 






Reverse the polarity (Famous sci-fi guote) 


AND 


A, #X'F0 






Strip unused bits 


IFGT 


A, #0 






Hit? 


JP 


ScanKeyHit 






Yes, go see which key it was 


LD 


A, bRowSel 






Update the row pointer 


RC 








Clear the carry flag - just in case 


RLC 


A 






Rotate left to next row 


X 


A, bRowSel 






Save it back 


DRSZ 


rRowCount 






Check the next row 


JP 


ScanKeysLoop 




Loop back 


LD 


bScanCode, 


#X'FF 




Scan code for no key pressed. 


JP 


ScanKeysExit 




No keys pressed... return to OS 


ScanKeyHit : 










IFBIT 


4, A 






Column 1? 


LD 


bScanCode, 


#0 




Yes, must 


IFBIT 


5, A 






Column 2? 


LD 


bScanCode, 


#1 




Yes, must 


IFBIT 


6, A 






Column 3? 


LD 


bScanCode, 


#2 




Yes, must 


IFBIT 


7, A 






Column 4? 


LD 


bScanCode, 


#3 




Yes, must 


LD 


A, #4 






Find row 


SUB 


A, rRowCount 




by subtraction 


RC 








Reset the carry flag 


RLC 


A 






Multiply X2 


RLC 


A 






Multiply X2 (X4) 


ADD 


A, bScanCode 




Add to scan code 


X 


A, bScanCode 


; Save it back 



www.national.com 



ScanKeysExit : 

LD 

RET 



PORTED, #X' 00 



Turn off all outputs to port 
Return to OS 



Each time the MTK OS calls this routine, the keyboard is 
scanned. If a key is pressed, its scan code (0-1 5) is returned 
in the bScanCode variable. If not, the NO-KEY-PRESSED 
valued is loaded instead. Note here that the routine com- 
pletes its function in a single call, much like a subroutine 
(which it is in reality — a subroutine of the application code). 
It also uses very little time to scan the entire keyboard. To re- 
duce the time even further, each entry into the routine could 



scan a single row instead of the entire keyboard. This is why 
the current row was kept in a local variable. The changes to 
implement this are quite simple. Instead of looping within the 
task, you simply loop to the exit routine. Also the row counter 
must be preloaded elsewhere, not in the beginning of the 
routine since it is updated each pass of the task. The 
changes would be as follows. 



DRSZ 


rRowCount 


JP 


ScanKeysExit 


LD 


rRowCount, #4 


LD 


bRowSel, #01 


LD 


bScanCode, #X'FF 


JP 


ScanKeysExit 


ScanKeyHit : 




LD 


rRowCount, #4 


LD 


bRowSel, #01 



Check the next row 

Wait for next entry to check next row. . . 

Load new row count for next fresh start 

Use memory location for row select . 

Scan code for no key pressed. 

No keys pressed... return to OS 

Reload the row counter 

Use memory location for row select . 



(CODE THE SAME FROM HERE) 



CONCLUSIONS 

There are many benefits gained by using a multitasking ker- 
nel such as that shown here. Time to market can be reduced 
by creating software tasks that can be used over and over. 
Once the kernel is stable, new applications can be created in 
a very short time. Also, sophisticated applications that re- 
quire many functions to work together and simultaneously 
can be easily implemented. Use the MTK code in this appli- 
cation note as a starting point to add your own handlers or to 
develop your own application. Multitasking on the COP8 has 
never been easier. Enjoy... 

OVERVIEW OF OPERATING SYSTEM ROUTINES 

This section provides an overview of all the MTK operating 
system routines. This includes the routines that are acces- 
sible by the application code as well as those used internally 
by the operating system. All OS routines begin with the lower 
case letters "os". This will make it easy when looking at your 
code to determine if the routine belongs to the application or 
the operating system. These routines are grouped by func- 
tion. 

Routine: osPUSH 

Use: This routine pushes the 'A' register onto the 

OS data stack 
Entry: Accumulator contains data byte to push 

Returns: Accumulator contains original data (Like real 

PUSH) 
Comments: Used for temporary application storage. This 

function provides another stack that can be 

used by the application for holding data. 
Routine: osPOP 

Use: This routine pops data from the OS data stack 

into the 'A' register. 
Entry: (none) 

Returns: Accumulator contains popped data from OS 

data stack 
Comments: Used for temporary application storage. 
Routine: osSetMaxTaskTime 
Use: This routine sets the maximum time any task 



can run (See text). 
Entry: Accumulator holds time selection if greater 

than 0. If zero, function disabled. 
Returns: Accumulator non-zero if successful, zero if 

fails 
Comments: Use this function to increase the robustness of 

the application. Prevents task lock-up. 
Routine: osAddTask 

Use: This routine will add a task entry point to the 

task list. 
Entry: The stack (SP) holds the entry point address. 

Push LSB of the task entry point address first 

and then the MSB. Next call osAddTask. 

Returns: Accumulator returns assigned task number if 

successful, zero if the task was not added. 

Comments: Use this routine to add the tasks to the task 
list. The application must register all task 
threads by calling this routine. 



www.national.com 



Routine: 


osStartTask 


Returns: 


(None) 


Use: 


This routine will start a task thread running. 


Comments: 


(Used by OS only). This routine is used as a 


Entry: 


Accumulator contains the task number to 




safety net in the case a timer or other callback 




start. 




is unassigned and is executed. This will imme- 


Returns: 


Accumulator is zero if successful, non-zero if 




diately return to the OS with no harm done. 




failed. 


Routine: 


osSetTimer 


Comments: 


For a task to execute, this routine must be 


Use: 


This routine Start a timer with a call back rou- 




called. Otherwise, the task is skipped and 




tine. 




never executed. 


Entry: 


Stack has all data pushed on in this order: 


Routine: 


osStopTask 




1. Push LSB of Timer value 


Use: 


This routine will stop a task thread from run- 




2. Push MSB of Timer value 




ning. 




3. Push LSB of call back routine address (0 if 


Entry: 


Accumulator contains the task number to 




main task) 




stop. 




4. Push MSB of call back routine address (0 if 


Returns: 


Accumulator is zero if successful, non-zero if 




main task) 




failed. 


Returns: 


Accumulator holds handle number for timer 


Comments: 


Use this routine to suspend a task from run- 




(1-n) if successful 




ning. 




Accumulator is zero (0) if resource unavail- 


Routine: 


osStart 




able 


Use: 


This routine will start the operating system 


Comments: 


If the callback is set to zero, Task 1 (first task 


Entry: 


(None required) 




added) will get the callback with the accumu- 


Returns: 


(Should not return unless fatal system error) 




lator set to the system message "mTimer", 
and 'B' with the timer handle. This facilitates a 


Comments: 


This routine should be called after all tasks are 




single routine to handle all operating system 




added and started. Following the call to this 




messages. 




routine, the application should contain an er- 
ror handler to restart the system in the case of 


Routine: 


osKillTimer 




a fatal operating system error. This can occur 


Use: 


This routine stops a timer and frees its re- 




if a call is made without the proper number of 




source. 




data values on the stack or other bad things... 


Entry: 


Accumulator contains the non-zero timer 


Routine: 


osMain 




handle. 


Use: 


This routine is the main loop of the kernel. All 


Returns: 


Accumulator is zero if successful, non-zero if 




dispatching of tasks is done from here. Any er- 




failed. 




ror handling is also done here. 


Comments: 


When a task is done using a timer resource, it 


Entry: 


(None required) 




must release this resource by calling this rou- 


Returns: 


(Never unless really bad things have hap- 




tine. 




pened...) 


Routine: 


osSignal 


Comments: 


(Used by OS only) 


Use: 


This routine will move a task to the top of the 


Routine: 


osGetTaskAddress 




queue. 


Use: 


Get Task Address Subroutine 


Entry: 


Accumulator contains the task number to sig- 
nal next. 


Entry: 


Accumulator holds task-1 








Returns: 


Accumulator is zero if successful, non-zero if 


Returns: 


B points to task entry address record 




failed. 


Comments: 


(Used by OS only) 


Comments: 


This is useful in real time conditions when a 


Routine: 


osGetFirstTask 




previous event requires faster service. For ex- 


Use: 


Gets the first running task number (first to 




ample, use this routine in a UART service call- 




start) 




back to move the parser to the top of the list. 


Entry: 


(None) 




It will then be executed next following the cur- 
rent task. 


Returns: 


First running task number (1-n) in 'A' if suc- 
cessful, zero if it fails 


Routine: 


osSetUART 


Comments: 


(Used by OS only) 


Use: 


This routine will capture a UART to a task and 
setup the baud rate, framing, data bits, and 


Routine: 


osGetNextTask 




buffers. 


Use: 


Gets the next running task number (next to 


Entry: 


'A' holds COM channel request (1 = UART 1, 




start) 




2 = UART 2, etc.) 


Entry: 


(None) 




Data is pushed on the stack as follows: 


Returns: 


next running task number (1-n) in 'A' if suc- 
cessful, zero if it fails 




1 . PUSH Configuration Byte (See Tables 1, 2) 






2. PUSH LSB of UART RX Call Back routine 


Comments: 


(Used by OS only) 




3. PUSH MSB of UART RX Call Back routine 


Routine: 


osllnassigned 










Returns: 


If successful, accumulator will return the 


Use: 


Unassigned Callback Idle routine 




handle to the UART (1-n). 


Entry: 


(None) 







www.national.com 



If failure, accumulator will be zero (0). 
Comments: If the callback address is zero (0), Task 1 (first 
task added) will receive the callback with the 
accumulator set to the system message 
mUART and the 'B' with the UART handle. 
This facilitates a single routine to handle all 
operating system messages. 

TABLE 1. UART Configuration Byte 



Bit 


Description 


0-3 


Baud Rate — See BAUD Rate Table 


4 


Data Bits (0=7, 1=8) 


5 


Stop Bits (0=1 , 1 =2) 


6 


Parity (0=none, 1=On) 


7 


Parity Type (0=Odd, 1=Even) 


TABLE 2. Baud Rate Bits 


Bits 3-0 


Baud Rate (Bits per Second) 


0000 


110 


0001 


134.5 


0010 


150 


0011 


300 


0100 


600 


0101 


1200 


0110 


2400 


0111 


4800 


1000 


7200 



Bits 3-0 


Baud Rate (Bits per Second) 


1001 


9600 


1010 


19200 


1011 


Reserved — Defaults to 9600 


1100 


Reserved — Defaults to 9600 


1101 


Reserved — Defaults to 9600 


1110 


Reserved — Defaults to 9600 


1111 


Reserved — Defaults to 9600 



Routine: 
Use: 

Entry: 

Returns: 

Comments: 



Routine: 

Use: 

Entry: 

Returns: 



TASKS 



1 




2 

1 


r 


3 


4 


5 


6 



osUARTSend 

This routine adds a byte to the transmit queue 
of the open UART resource. 
Data byte is on the stack and 'A' holds the 
handle of the open UART resource. 
If successful, returns zero in 'A'. 
If failure, return non-zero in 'A'. 
Use this routine to send data. The transmit 
queue has two pointers — a read and write 
pointer. If the pointers are different, the UART 
transmit routine reads data from the transmit 
queue and updates the read pointer until they 
are the same once again. Once they are the 
same, transmissions stop. 
osKillUART 
Frees a UART resource 
A' holds the handle to the open UART re- 
source 
If successful, returns zero in 'A'. 



SCHEDULER 



:Q: 



T 



CURRENTLY RUNNING TASK 



AN100833-1 

FIGURE 1. Preemptive Multitasking Structure 



www.national.com 



Scheduler 



1 



TASKS 



12 3 4 5 6 



This Task 


Next Task 


1 


2 


2 


3 


3 


4 


4 


5 


5 


6 


6 


1 



FIGURE 2. Cooperative Multitasking Structure 











TASK 








MANAGER 


' 


' 








• 


INITIALIZE 
(USER SETUP) 






SUPERVISOR 
(USES TO) 






1 


' 






USER 

ERROR 

HANDLER 





USER 
TASKS 



RESOURCE 
MANAGER 



B 



FIGURE 3. COP8SGR Multitasking Kernel Architecture 



www.national.com 



C0P8SGR 






\r 




FIGURE 4. Multiplexed 7 Segment Display Task Hookup 



C0P8SGR 



KEYBOARD MATRIX 



AN1 00833-5 

FIGURE 5. Keyboard Scanning Task Hookup 



www.national.com 



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 
ob 
06 
37 
58 
59 
60 
61 
62 
63 
64 
6b 



.TITLE MTK , 'Multi Tasking Kernal' 

FILENAME: MTK88815.ASM 

Multi-Tasking Kernal for simple multithreaded applications 

Copyright (C) 1996, 1997 National Semiconductor Corporation 



CODE 



HISTORY 



Comment 



Code created by Rick Zarr 

Conversion to 888 core (COP8SAC) 

Additions for use with article 

Conversion to COP8SGR 

Additions for Supervised cooperative 

Updates to fix bugs 

Additions to UART functions 



Date 


Version 


6/03/96 


1.00 


2/27/97 


1.10 


8/07/97 


1.20 


1/03/98 


1.30 


1/07/98 


1.40 


1/29/98 


1.41 


2/24/98 


1.50 



Notes : 

A) Naming conventions : 
The following naming methods are used through out this source code . 

; This makes classifying the variables easier when looking through 

; the listing. It also helps prevent association errors since the 

assembler cannot tell you if you've associated an incorrect variable 

with an operation . For example, if you wrote the following: 



LD 



A, xyz 



Get the data in variable xyz 



and you made the mistake that xyz was in effect a constant, the 
assembler would load the location in memory that was pointed to by 
the constant . This means you might get something like this : 



LD 



A, 3 



Get the data in variable xyz 



instead of the intended variable location. This naming convention 
can help prevent this . Here is the same thing using the names . I 
have defined two things, one is the variable name and size and the 
; other is it's default value. They can be named almost the same thing 
helping to keep track of what' s what ! 



LD 
X 



A, CXYZ 
A, bXYZ 



Load the default value for xyz 
Save it into the variable 



Here' s my definitions used in most of the source code I write . 
Feel free to adopt this methodology or create your own . 



P 
pc 



Variable prefix naming conventions : 

ARRAY (Group of bytes. 

BYTE VALUE (Single byte value. 

WORD (Variable defined as DSW. 

FLAG BIT (Bit within byte. 

CONSTANT (ROM defined value 

POINTER (Byte long pointer into RAM. 

POINTER CONSTANT (Pointer into EEPROM. 

REGISTER (CPU register R0-RA 

I/O PIN (I/O pin on COP8 controller 

INPUT PIN (Input pin on COP8 controller 

OUTPUT PIN (Output pin on COP8 controller 



Example : aData) 
Example : bData) 
Example : wTest ) 
Example : fWorking} 
Example : c Value) 
Example : pBuf f er ) 
Example : pcMaxMinV) 
Example : rCounter) 

Example : ioData) 
Example : iSwitch) 
Example: oLEDl) 



. INCLD COP888EG. INC 



Example 888 device for demo of MTK 



CONSTANTS 



www.national.com 



7 




71 




72 




73 




74 


006F 


7 b 


007F 


76 


0001 




0003 


78 


000A 


79 




80 


0060 


31 


0010 


82 


0010 


83 




84 




85 




86 




3 / 





90 


0000 


91 


0001 


92 


0002 


93 


OOOF 


94 




95 


0010 


96 




97 00 


00 



100 




101 




102 




103 




104 




105 




106 




107 


0000 


108 


0008 


109 




110 


0009 


111 


OOOA 


112 


OOOB 


113 


OOOC 


114 


OOOE 


115 


OOOF 


116 




117 


0010 


118 


0003 


119 


0002 


120 


0001 


121 


0000 


122 




123 


0011 


124 


0013 


125 


0015 


126 


0017 


127 


0019 


128 




129 


001B 


130 




131 


001D 


132 


0004 


133 


0005 


134 


0006 



Example 
cConstant - n 



Setup up constants like this 



cTopOfRAM 

cTopOfSysRAM 

cSystemSegment 

cRecSize 

cMaxTasks 

cBaudPrescale 

cCOMlTxBufLen 
cCOMlRxBufLen 



0x6F 

0x7F 

1 

3 

10 

0x60 

16 

16 



Top of RAM for COP87L88EG 

Top of OS RAM for COP87L88EG 

Current system RAM segment 

Size of task records in bytes 

Maximum number of tasks that can be loaded 

UART Prescaler value 6.5 (01100) for 10MHz 
COM1 Transmitter FIFO length 
COM1 Receiver FIFO Length 



OPERATING SYSTEM MESSAGES 



mNone 
mTimer 
mUART 
mTaskFailure 



X' 00 

X' 01 
X' 02 
X'OF 



mUser = X' 10 

.SECT OSRAM, SEG 

VARIABLES 



Idle message 

Timer tick / service 

UART Service 

Task monitor service 

; Beginning of user messages 

; Located in segment 1 of the COP87L88EG 



Example 
wWord 
bByte 



.DSW 
.DSB 



Word format for 16 bit location 
Byte format for 8 bit location 



aStore 




.DSB 


8 , 


pStack 




.DSB 


1 , 


bTask 




.DSB 


1 , 


bTaskNew 




.DSB 


1 , 


bTaskNext 




.DSB 


1 , 


wAddress 




.DSW 


1 , 


bMaxTaskTime 




.DSB 


1 , 


bTaskTime 




.DSB 


1 , 


fStatus 




.DSB 


1 , 


fUART 


= 3 






fTimer3 


= 2 






fTimer2 


= 1 






fTimerl 


= 






wPeriod 




.DSW 


1 , 


wTimerCallBack 




.DSW 


1 , 


wTimerlCallBack 




.DSW 


1 , 


wTimer2CallBack 




.DSW 


1 , 


wTimer3CallBack 




.DSW 


1 , 


wlntCallBack 




.DSW 


1 , 


bUARTSettings 




.DSB 


1 , 


fDataBits 


= 4 






fStopBits 


= 5 






fParitySel 


= 6 







Local store for working with data 
OS Data Stack Pointer 

Currently running task number (1-n) 

Used by OS, Last task number added 

Next active task to switch in 

16 bit address (MSB/LSB) 

Max tick count for task monitor 

Remaining 

Status byte for kernal 
Bit 3: UART 1 in use 



3it 2 

3it 1 
3it 



Timer 3 in use 
Timer 2 in use 
Timer 1 in use 



Work areafor timer period 
Work area for call back 
Timer 1 callback address 
Timer 2 callback address 
Timer 3 callback address 

Hardware interrupt callback 

Current UART settings 
Data bits (0-7, 1-8) 
Stop Bits (0=1, 1-2) 
Parity Select (0-none, l=On) 



www.national.com 



135 




0007 




fParltyType 


= 7 


; Parity Type (0=Odd, l=Even) 


136 


001E 






wUARTRxCallBack : .DSW 


1 ; UART RX Call back address 


137 














138 


0020 






bCOMlRxBuffer 


.DSB 


cCOMlRxBufLen ; Setup buffer for RX 


139 


0030 






pCOMlRxWrite 




.DSB 


1 ; Write pointer to RX buffer 


140 


0031 






pCOMlRxRead 




.DSB 


1 ; Read pointer to RX buffer 


141 


0032 






bCOMlTxBuffer 


.DSB 


cCOMlTxBufLen ; Setup buffer for TX 


142 


0042 






pCOMlTxWrite 




.DSB 


1 ; Write pointer to TX buffer 


143 


0043 






pCOMlTxRead 




.DSB 


1 ; Read pointer to TX buffer 


144 


0044 






bCOMlStatus 




.DSB 


1 ; Status byte for COM1 


145 




0007 




fTxBusy 


= 7 


; Tx FIFO Full 


146 




0006 




f RxBusy 


= 6 


; Rx FIFO Full 


147 














148 










***********) 


**************** 


******************************************** 


149 
















150 












TASK R E C 


ORD STRUCTURE 


151 
















152 










fTaskStatus : .DSB 1 ; Fl 


ags for each task 


153 










f Active 


= ; B 


it : State (0=Stopped, l=Running) 


154 










bAddrLSB 


: .DSB 1 ; Task Address LSB 


155 










bAddrMSB 


: .DSB 1 ; Task Address MSB 


156 
















157 










***********) 


**************** 


******************************************** 


158 


0045 




aTaskRecs : 


.DSB cRecSize * cMaxTasks ; Array of task records 


159 




0000 




f Active 


= 


; Active flag for task 


160 














161 








;***********< 


**** IMPORT 


FUNCTIONS ***************** 


162 








.EXTRN Initialize: ROM ; 


Inializes application code 


163 














164 








;***********< 


**** EXPORT 


FUNCTIONS ***************** 


165 








.PUBLIC 


osStart ; 


Starts the MTK running 


166 








.PUBLIC 


osAddTask ; 


Adds a task to the MTK task list 


167 








.PUBLIC 


osStartTask ; 


Starts a task running 


168 








.PUBLIC 


osStopTask ; 


Stops a task 


169 




.PUBLIC OS 


SetMaxTaskTime 


; Sets the maximum time a task can run before being killed 


170 








.PUBLIC 


osSignal ; 


Moves thread to top of gueue 


171 








.PUBLIC 


osPUSH ; 


PUSHes a byte onto the OS stack from 'A' 


172 








.PUBLIC 


osPOP ; 


POPs a byte from the OS stack to 'A' 


173 




.PUBLIC OS 


SetCommChannel 


; Captures and initializes a communications resource 


174 








.PUBLIC 


osUARTGetChar 


Returns a byte from the UART RX gueue 


175 








.PUBLIC 


osUARTSend ; 


Sends a character to the UART 


176 








.PUBLIC 


osSetTimer ; 


Captures and sets up a timer resource 


177 








.PUBLIC 


osKillTimer ; 


Stops and frees a timer resource 


178 








;*********< 


************** c 


ODE BEGINS ************** 


CODE 


SECTION 










179 








.FORM 


'CODE SECTION' 




180 


0000 






.SECT 


CODE, ROM, ABS 


=0x0000 


181 








; 






182 


0000 


DD6F 


3 


Start: LD 


SP, #cTopOfRAM 


; Top of Stack for COP87L88EG 


183 








; 






184 


0002 






ClearRAM: 






185 


0002 


DFOO 


3 


LD 


S, #0 


; Point to RAM segment 


186 


0004 


9F6F 


2 


LD 


B, #cTopOfRAM 


; Setup pointer into Main RAM 


187 


0006 






ClearRAMLoopl 






188 


0006 


9E00 


2 


LD 


[B], #000 


; Clear RAM location 


189 


0008 


CE 


3 


DRSZ 


B 


; Update counter, skip jump if done 


190 


0009 


FC 


3 


JP 


ClearRAMLoopl 


; Continue until done 


191 


000A 


BC0000 


3 


LD 


000 , #00 


; Clear last location 


192 








; 






193 


000D 


DF01 


3 


LD 


S, #1 


; Point to RAM segment 1 


194 


OOOF 


9F7F 


2 


LD 


B, #cTopOfSysRAM ; Setup pointer into OS RAM 


195 


0011 






ClearRAMLoop2 






196 


0011 


9E00 


2 


LD 


[B], #000 


; Clear RAM location 


197 


0013 


CE 


3 


DRSZ 


B 


; Update counter, skip jump if done 


198 


0014 


FC 


3 


JP 


ClearRAMLoop2 


; Continue until done 


199 


0015 


BC0000 


3 


LD 


000 , #00 


; Clear last location 


200 















13 



www.national.com 



201 
















202 


0018 


BC087F 


3 


R 


LD 


pStack, #cTopOfSysRAM 


; Setup OS Data Stack 


203 








; 








204 


001B 


9F15 


2 


R 


LD 


B, #wTimerlCallBack 


; Initialize callbacks to nil 


205 


001D 


9ACF 


2 


LD [B+] 


, #LOW (osUnassigned) ; to prevent the OS from crashing 


206 


001F 


9A00 


2 


LD [B+] 


, #HIGH (osUnassigned) ; if the timer is active without 


207 


0021 


9ACF 


2 




LD 


[B+] , #LOW (osUnassigned) 




the callback assigned. 


208 


0023 


9A00 


2 




LD 


[B+], #HIGH (osUnassigned 






209 


0025 


9ACF 


2 




LD 


[B+], #LOW (osUnassigned) 






210 


0027 


9A00 


2 




LD 


[B+], #HIGH (osUnassigned 






211 
















212 


0029 


DFOO 


3 




LD 


S, #0 


Point to main user RAM area 


213 
















214 


002B 


9DB9 


3 




LD 


A, RBUF 


Receive and rough characters 


215 


002D 


BCBAOO 


3 




LD 


ENU, #B'00000000 


Clear UART registers 


216 


0030 


BCBBOO 


3 




LD 


ENUR, #B' 00000000 




217 


0033 


BCBCOO 


3 




LD 


ENUI, #B' 00000000 




218 
















219 


0036 


BCEE80 


3 




LD 


CNTRL, #B' 10000000 


Setup timer 1A 


220 


0039 


BCC685 


3 




LD 


T2CNTRL, #B' 10000101 


Setup timer 2A, B 


221 


003C 


BCB685 


3 




LD 


T3CNTRL, #B' 10000101 


Setup timer 3A, B 


222 


003F 


BCE801 


3 




LD 


ICNTRL, #B' 00000001 


Setup timer 0, IB 


223 


0042 


BCEF11 


3 




LD 


PSW, #B'00010001 


Setup PSW, Timer 1A, GIE 


224 
















225 


0045 


ACOOOO 


> 


4 X 


JP 


Initialize 


Go setup tasks 


226 
















227 










*********** 


************************* 


********************************* 


228 
















229 










Multitasking kernal routines 




230 
















231 










*********** 


************************* 


v******************************** 


232 
















233 










Routine 


: osAddTask 




234 










Use: Th 


is routine will add a task entry point to the task list. 


235 
















236 










Entry: 


Stack (SP) holds return address and data. Push LSB first 


237 












and then push MSB of task entry point callback routine. 


238 












Then call osAddTask 




239 










Returns 


: Accumulator returns assigned task number if successful, 


240 












zero if the task was not added. 


241 










Alters : 


' A' , 'B' , and the SP 




242 
















243 










*********** 


************************* 


********************************* 


244 


0048 








OsAddTask: 






245 


0048 


9DFF 


3 




LD 


A, S 


Get current RAM segment 


246 


004A 


DF01 


3 




LD 


S, #1 


Switch to OS data segment 


247 


004C 


9C00 


3 


R 


X 


A, aStore+0 ; Save for later to restore segment 


248 


004E 


9D0A 


3 


R 


LD 


A, bTaskNew 


Update New task counter 


249 


0050 


8A 


1 




INC 


A 


Increment to next one 


250 


0051 


930A 


2 




IFGT 


A, #cMaxTasks 


Check if larger than max task 


251 


0053 


1C 


3 




JP 


osAddTaskError 


yes, Report error 


252 


0054 


9C0A 


3 


R 


X 


A, bTaskNew 


No, save it back 


253 
















254 


0056 


8C 


3 




POP 


A 


Get Return Address MSB 


255 


0057 


9C0D 


3 


R 


X 


A, wAddress+1 


Save in MSB of wAddress 


256 


0059 


8C 


3 




POP 


A 


Get Return Address LSB 


257 


005A 


9C0C 


3 


R 


X 


A, wAddress 


Save in LSBof wAddress 


258 
















259 


005C 


9D0A 


3 


R 


LD 


A, bTaskNew 


Get New Task pointer 


260 


005E 


8B 


1 




DEC 


A 


Correct for reference 


261 


005F 


30A4 


b 




JSR 


osGetTaskAddress 


Get address, pointed to by 'A' 


262 
















263 


0061 


AA 


2 




LD 


A, [B+] ; 


Move past flags byte 


264 


0062 


AA 


2 




LD 


A, [B+] ; 


Move past LSB of callback 


265 


0063 


8C 


3 




POP 


A ; 


Get callback LSB 


266 


0064 


A3 


2 




X 


A, [B-] ; 


Store MSB, increment B 


267 


0065 


8C 


3 




POP 


A ; 


Get callback MSB 



www.national.com 



268 


0066 


A6 


1 




X 


A, [B] 




Store LSB, increment B 


269 


















270 


0067 


9D0C 


3 


R 


LD 


A, wAddress 


; 


Restore return address 


271 


0069 


67 


3 




PUSH 


A 


; 


Start with LSB 


272 


006A 


9D0D 


3 


R 


LD 


A, wAddress+1 


; 




273 


006C 


67 


3 




PUSH 


A 


; 


Now add MSB 


274 


006D 


9D0A 


3 


R 


LD 


A, bTaskNew 


; 


Get the current task number 


275 


006F 


01 


3 




JP 


osAddTaskEnd 


; 


Return handle of task 


276 


0070 






osAddTaskError : 






277 


0070 


64 


1 




CLR 


A 


; 


Report error 


278 


0071 






osAddTaskEnd 








279 


0071 


67 


3 




PUSH 


A 


; 


Save return value 


280 


0072 


9D00 


3 


R 


LD 


A, aStore+0 


; 


Get old segment 


281 


0074 


9CFF 


3 




X 


A, S 


; 


Restore old segment 


282 


0076 


8C 


3 




POP 


A 


; 


Get return value 


283 


0077 


8E 


5 




RET 




; 


Return to calling routine 


284 


















285 


















286 










*********** 


********************* 


**** 


************************* 


287 


















288 










Routine : 


osStartTask 






289 










Use: 


This routine will start 


running a task thread. 


290 


















291 










Entry: 


Accumulator contains 


the 


task number to start . 


292 










Returns : 


Accumulator is zero 


if successful, non-zero if failed. 


293 


















294 










*********** 


********************* 


**** 


********************************* 


295 


0078 








DsStartTask: 








296 


0078 


67 


3 




PUSH 


A 


; 


Save 'A' for now 


297 


0079 


9DFF 


3 




LD 


A, S 


; 


Get current segment 


298 


007B 


DF01 


3 




LD 


S, #1 


; 


Switch to OS RAM Page 


299 


007D 


9C00 


3 


R 


X 


A, aStore+0 


; 


Save old RAM segment 


300 


007F 


8C 


3 




POP 


A 


; 


Get task number off main stack 


301 


0080 


BD0A83 


4 


R 


IFGT 


A, bTaskNew 


; 


Is the task number valid? 


302 


0083 


06 


3 




JP 


osStartTaskError 


; 


No, don't start 


303 


















304 


0084 


8B 


1 




DEC 


A 


; 


Use corrected pointer (p-1) 


305 


0085 


30A4 


5 




JSR 


osGetTaskAddress ; 


Get 


a pointer into the task buffer 


306 


0087 


78 


1 




SBIT 


fActive, [B] 


; 


Set Start Task flag in MSB 


307 


0088 


64 


1 




CLR 


A 


; 


Clear 'A' to signal start 


308 


0089 


02 


3 




JP 


osStartTaskEnd 


; 


End routine 


309 


008A 








DsStartTaskE 


rror : 






310 


008A 


98FF 


2 




LD 


A, #0xFF 


; 


Signal error (non-zero) 


311 


008C 






osStartTaskEnd: 






312 


008C 


67 


3 




PUSH 


A 


; 


Save return value on main stack 


313 


008D 


9D00 


3 


R 


LD 


A, aStore+0 


; 


Get old RAM segment from store 


314 


008F 


9CFF 


3 




X 


A, S 


; 


Restore old RAM segment 


315 


0091 


8C 


3 




POP 


A 


; 


Get return value 


316 


0092 


8E 


5 




RET 




; 


Return to calling task 


317 


















318 










*********** 


********************* 


**** 


********************************* 


319 


















320 










Routine: osStopTask 






321 










Use: 


This routine will 


stop a task thread from running. 


322 


















323 










Entry 


: Accumulator contains 


the task number to stop. 


324 










Returns : 


Accumulator is zero i 


f successful, non-zero if failed. 


325 


















326 










*********** 


********************* 


**** 


********************************* 


327 


0093 








DsStopTask: 








328 


0093 


DF01 


3 




LD 


S, #1 


; 


Switch to OS RAM Page 


329 


0095 


BD0A83 


4 


R 


IFGT 


A, bTaskNew 


; 


Is the task number valid? 


330 


0098 


06 


3 




JP 


osStopTaskError 


; 


No, don't start 


331 


















332 


0099 


8B 


1 




DEC 


A 


; 


Use corrected pointer (p-1) 


333 


009A 


30A4 


5 




JSR 


osGetTaskAddress ; 


Get 


a pointer into the task buffer 


334 


009C 


78 


1 




SBIT 


fActive, [B] 


'" 


Start Task 



15 



www.national.com 



335 


009D 


64 


: 


CLR A 


; Clear 'A' to signal start 


336 


009E 


02 


3 


JP osStopTaskEnd 


; End routine 


337 


009F 




osStopTaskError : 




338 


009F 


98FF 


2 


LD A, #0xFF 


; Signal error (non-zero) 


339 


00A1 




osStopTaskEnd: 




340 


00A1 


DFOO 


3 


LD S, #0 


; Switch back to user RAM area 


341 


00A3 


8E 


b 


RET 


; Return to calling task 


342 












343 








******************************** 


************************************* 


344 












345 








Get Task Address Subroutine 




346 








(Used by OS only) 




347 












348 








osGetTaskAddress : A is task-1, 


B returns address to first entry 


349 












350 








******************************** 


************************************* 


351 


00A4 




osGetTaskAddress : 




352 


00A4 


9CFE 


3 


X A, B 


; Use ' B' to do math 


353 


00A6 


9DFE 


3 


LD A, B 


; Get task pointer back 


354 


00A8 


BDFE84 


4 


ADD A, B 


; Multiply x2 for pointer 


355 


OOAB 


BDFE84 


4 


ADD A, B 


; Multiply x3 for pointer 


356 


OOAE 


9445 


2 R 


ADD A, #aTaskRecs 


; Add base address of record buffer 


357 


OOBO 


9CFE 


3 


X A, B 


; Use ' B' now as pointer 


358 


00B2 


8E 


b 


RET 


; 


359 












360 








******************************** 


************************************* 


361 












362 








Get First and Next running 


Task Subroutine 


363 








(Used by OS only) 




364 












365 




; 


osGetFirstTask : Returns first running task (1-n) in 'A' if successfull 


366 




; 


osGetNextTask : Returns next runnir 


g task (1-n) in 'A' if successfull 


367 












368 








If either call fails, 'A' is zero 


369 












370 








******************************** 


************************************* 


371 


00B3 






DsGetFirstTask: 




372 


00B3 


9800 


2 


LD A, #0 


; First task record 


373 


00B5 


67 


3 


PUSH A 


; Save it on the stack 


374 


00B6 


03 


3 


JP osGetNextTaskLoop 


; go see what' s enabled 


375 


00B7 






ssGetNextTask: 




376 


00B7 


9D09 


3 R 


LD A, bTask ; Current Task+1 (Already incremented) 


377 


00B9 


67 


3 


PUSH A 


; Save it for later 


378 


OOBA 






OsGetNextTaskLoop : 




379 


OOBA 


30A4 


5 


JSR osGetTaskAddress 


; Go get the address of the task 


380 


OOBC 


70 


: 


IFBIT fActive, [B] 


; Active? 


381 


OOBD 


OC 


3 


JP osGetNextTaskHit 


; Yes, we got the next active one 


382 












383 


OOBE 


8C 


3 


POP A 


; Get the old count 


384 


OOBF 


8A 


1 


INC A 


; Update it 


385 


ooco 


BD0A83 


4 R 


IFGT A, bTaskNew 


; Past last one? 


386 


00C3 


64 


1 


CLR A 


; Yes, Start at beginnning 


387 


00C4 


BD0982 


4 R 


IFEQ A, bTask 


; Hit them all? 


388 


00C7 


05 


3 


JP osGetNextTaskError 


; Yes, Nothing is running. Bail. . . 


389 


00C8 


67 


3 


PUSH A 


; Save it for later 


390 


00C9 


FO 


3 


JP osGetNextTaskLoop 


; Try again 


391 












392 


OOCA 






DsGetNextTaskHit : 




393 


OOCA 


8C 


3 


POP A ; 


Get the task count off the stack 


394 


OOCB 


8A 


1 


INC A 


; Adjust task number to 1-n 


395 


OOCC 


01 


3 


JP osGetNextTaskDone 


; 


396 


OOCD 






DsGetNextTaskError: 




397 


OOCD 


64 


1 


CLR A 


; Return invalid handle 


398 


OOCE 






DsGetNextTaskDone : 




399 


OOCE 


8E 


b 


RET 


; Done 


400 












401 








*""""""" ***************** 


************************************* 



www.national.com 



402 








403 








404 








405 








406 






; 


407 






; 


408 








409 








410 


00CF 






411 


OOCF 


8E 




412 








NTEI 


^RUPT 


ROUTINE 


413 








414 








41b 








416 








417 








418 








419 








420 








421 




; 




422 








423 






; 


424 








42b 








426 








4 2'/ 








428 








429 








430 


OOFF 






431 


OOFF 






432 


OOFF 


67 


3 


433 


0100 


9DFE 


3 


434 


0102 


67 


3 


435 


0103 


9DEF 


3 


436 


0105 


67 


3 


4 3'/ 


0106 


9DFF 


3 


438 


0108 


67 


3 


439 


0109 


B4 


b 


440 








441 


010A 






442 


010A 


B5 


1 


443 


010B 


2200 


» 3 


444 








445 


010D 






446 








4 4'/ 








448 








449 








4oC 


010D 


BCCAOO 


3 


451 


0110 


2200 


» 3 


452 








453 


0112 






454 


0112 


BDE8 6D 


4 


4ob 


0115 


DF01 


3 


4o6 


0117 


9D0F 


3 


457 


0119 


8B 


1 


4b8 


011A 


9300 


2 


4b 9 


one 


IF 


3 


460 








461 


011D 


9D09 


3 


462 


011F 


9201 


2 


463 


0121 


2000 


3 


464 








46b 


0123 


8B 


1 


466 


0124 


3 0A4 


b 


467 


0126 


68 


1 



Unassigned Callback Idle routine 
(Used by OS only) 



This routine is used as a safty net incase a timer or other callback 
is unassigned and is executed. This will immediately return to the OS. 



osUnas signed: 

RET 



Do nothing and return 



' INTERRUPT ROUTINE' 



INTERRUPT HANDLER 



NOTES 



This routine is the entry point for all vectors . The VIS instruction 
will find the correct vector for interrupt . It is the responsibility 
; of each service routine to clear the cause of the interrupt . A 
template is used for each of the existing interrupts . The default 
device for this source is the COP8SA family . The interrupts for this 
device are all supported. If this MTK is migrated to another feature 
family device, simply replace the ' ServiceUnused' routine with the 
missing routines. 



.ORG 





xOOFF 


Interrupt : 








PUSH 




A 




LD 




A, 


B 


PUSH 




A 




LD 




A/ 


PSW 


PUSH 




A 




LD 




A, 


S 


PUSH 




A 




VIS 








.********** 


** 


** * 


***** 


ServiceUnused 






RPND 








JP 




Restore 



Force to OxOOFF for interrupt 



Save 'A' 
Save 'B' 



Save 'PSW 

Save segment 

Find interrupt vector 



Incase it's set, clear SW pending 
; Just return 



ServiceWakeup : 



Check which ' L' Port pin caused the interrupt here 



LD 
JP 



WKPND, #0 

Restore 



ServiceTimerTO: 

RBIT T0PND, ICNTRL 



LD 

LD 

DEC 

IFGT 

JP 

LD 

IFEQ 

JMP 

DEC 
JSR 

RBIT 



S, #1 

A, bTaskTime 

A 

A, #0 

ServiceTimerTOExit 

A, bTask 
A, #1 
Start 



; Clear all pending flags 
; Return 



Clear pending flag 
Switch to OS segment 
Decrement task watcher counter 

Did current running task die? 
No, still running 

Did the main message loop die? 



; Yes, restart the microcontroller 
; No, Stop the thread and report it . . . 
A ; Adjust task number to get address 

osGetTaskAddress ; Retrieve the task address. 
fActive, [B] ; Disable the task 



www.national.com 



468 


















469 


0127 


9800 


2 




LD 


A, 


#LOW (Restore) 


; Push return address on stack 


470 


0129 


67 


3 




PUSH 


A 




; 


ill 


012A 


9802 


2 




LD 


A, 


#HIGH (Restore) 


; 


472 


012C 


67 


3 




PUSH 


A 




; 


473 


012D 


9D46 


3 


R 


LD 


A, 


aTaskRecs+1 ; Push address of main task onto stack 


474 


012F 


67 


3 




PUSH 


A 




; 


475 


0130 


9D47 


3 


R 


LD 


A, 


aTaskRecs+2 


; 


476 


0132 


67 


3 




PUSH 


A 




; 


477 


0133 


9D09 


3 


R 


LD 


A, 


bTask 


; Get active task that failed 


478 


0135 


9CFE 


3 




X 


A, 


B 


; Save in 'B' 


479 


0137 


980F 


2 




LD 


A, 


#mTaskFailure 


; Setup message to task 


480 


0139 


DF00 


3 




LD 


S, 


#0 ; Switch to User RAM for call back 


481 


013B 


8E 


b 




RET 






; Call message loop. 


482 


















483 


013C 








ServiceTimer 


TOExit: 




484 


013C 


9C0F 


3 


R 


X 


A, 


bTaskTime 


; Save new count back to RAM 


485 


013E 


2200 > 


3 




JP 


Restore 


; Return 


486 










;*********** 


* ** * 


******************** 


********************************** 


487 


0140 








ServiceTimer 


T1A: 






488 


0140 


BDEF6D 


4 




RBIT 


TPND, PSW 


; Clear Pending flag 


489 


0143 








ServiceTimer 


Tl: 






490 


0143 


DF01 


3 




LD 


S, 


#1 


; Switch to OS RAM page 


491 


0145 


9800 


2 




LD 


A, 


#LOW (Restore 


; Push return address on stack 


492 


0147 


67 


3 




PUSH 


A 






493 


0148 


9802 


2 




LD 


A, 


#HIGH (Restore) 




494 


014A 


67 


3 




PUSH 


A 






495 


014B 


9D15 


3 


R 


LD 


A, 


wTimerlCallBack 


; Push callback address on stack 


496 


014D 


67 


3 




PUSH 


A 






497 


014E 


9D16 


3 


R 


LD 


A, 


wTimerlCallBackt 




498 


0150 


67 


3 




PUSH 


A 




; 


499 


0151 


DFOO 


3 




LD 


S, 


#0 ; Switch to User RAM for call back 


500 


0153 


8E 


b 




RET 




; Gc 


service it, return to RESTORE 


501 


















502 










.*********** 


**** 


******************** 


********************************** 


489 


0143 








ServiceTimer 


Tl: 






490 


0143 


DF01 


3 




LD 


S, 


#1 


Switch to OS RAM page 


503 


0154 








ServiceTimer 


TIB: 






504 


0154 


BDE869 


4 




RBIT 


T1PNDB, ICNTRL ; 


Clear Pending flag 


505 


0157 


EB 


3 




JP 


ServiceTimerTl ; 


Go service call-back 


506 










.*********** 


**** 


******************** 


********************************** 


507 


0158 








ServiceTimer 


T2A: 






508 


0158 


BDC66B 


4 




RBIT 


T2PNDA, T2CNTRL ; 


Clear Pending flag 


509 


015B 








ServiceTimer 


T2 : 






510 


015B 


DF01 


3 




LD 


S, 


#i ; 


Switch to OS RAM page 


511 


015D 


9800 


2 




LD 


A, 


#LOW (Restore) ; 


Push return address on stack 


512 


015F 


67 


3 




PUSH 


A 






513 


0160 


9802 


2 




LD 


A, 


#HIGH (Restore) ; 




514 


0162 


67 


3 




PUSH 


A 






515 


0163 


9D17 


3 


R 


LD 


A, 


wTimer2CallBack ; 


Push callback address on stack 


516 


0165 


67 


3 




PUSH 


A 






517 


0166 


9D18 


3 


R 


LD 


A, 


wTimer2CallBack+l ; 




518 


0168 


67 


3 




PUSH 


A 






519 


0169 


DFOO 


3 




LD 


S, 


#0 ; 


Switch to User RAM for call back 


520 


016B 


8E 


b 




RET 






Go service it, return to RESTORE 


521 










.*********** 


**** 


******************** 


********************************** 


522 


016C 








ServiceTimer 


T2B: 






523 


016C 


BDC669 


4 




RBIT 


T2PNDB, T2CNTRL ; 


Clear Pending flag 


524 


016F 


EB 


3 




JP 


ServiceTimerT2 ; 


Go service call-back 


525 










.*********** 


* ** * 


******************** 


********************************** 


526 


0170 








ServiceTimer 


T3A: 






527 


0170 


BDB66B 


4 




RBIT 


T3PNDA, T3CNTRL ; 


Clear Pending flag 


528 


0173 








ServiceTimer 


T3: 






529 


0173 


DF01 


3 




LD 


S, 


#i ; 


Switch to OS RAM page 


530 


0175 


9800 


2 




LD 


A, 


#LOW (Restore) ; 


Push return address on stack 


531 


0177 


67 


3 




PUSH 


A 






532 


0178 


9802 


2 




LD 


A, 


#HIGH (Restore) ; 





www.national.com 



533 


017A 


67 


3 




PUSH 


A 




534 


017B 


9D19 


3 


R 


LD 


A, wTimer3CallBack 


Push callback address on stack 


535 


017D 


67 


3 




PUSH 


A 




536 


017E 


9D1A 


3 


R 


LD 


A, wTimer3CallBack+l 




537 


0180 


67 


3 




PUSH 


A 




538 


0181 


DFOO 


3 




LD 


S, #0 


Switch to User RAM for call back 


539 


0183 


8E 


5 




RE I 




Go service it, return to RESTORE 


540 










.********** 


*********************************************************** 


541 


0184 








ServiceTimerT3B: 


542 


0184 


BDB669 


4 




RBIT 


T3PNDB, T3CNTRL ; Clear Pending flag 


543 


0187 


EB 


3 




JP 


ServiceTimerT3 ; Go service call-back 


544 










.********** 


*********************************************************** 


545 


0188 








ServiceUART 


_TX: 


546 


0188 


DF01 


3 




LD 


S, #1 ; Switch to OS RAM page 


547 


018A 


9D43 


3 


R 


LD 


A, pCOMlTxRead ; Get the transmit buffer read pointer 


548 


018C 


9CFE 


3 




X 


A, B 


Use 'B' as the pointer 


549 


018E 


AA 


2 




LD 


A, [B+] 


Get the data 


550 


018F 


9CB8 


3 




X 


A, TBUF 


Move to UART Tx register 


551 


0191 


BD446F 


4 


R 


RBIT 


fTxBusy, bCOMlStatus 


Update status, free FIFO 


552 


0194 


9DFE 


3 




LD 


A, B 


Get new pointer back 


553 


0196 


9242 


2 


R 


IFEQ 


A, IbCOMlTxBuf fer+cCOMlTxBufLen ; past buffer end? 


554 


0198 


9832 


2 


R 


LD 


A, IbCOMlTxBuf fer 


Reload start of buffer 


555 


019A 


BD4282 


4 


R 


IFEQ 


A, pCOMlTxWrite 


All data sent? 


556 


019D 


BDBC68 


4 




RBIT 


ETI, ENUI 


Yes, Stop any new interrupts. . . 


557 


01A0 


9C43 


3 


R 


X 


A, pCOMlTxRead 


Save new pointer value 


558 


01A2 


2200 > 


3 




JP 


Restore 


Return 


559 










.********** 


*********************************************************** 


560 


01A4 








ServiceUART 


_RX: 


561 


01A4 


DF01 


3 




LD 


S, #1 


Switch to OS RAM page 


562 


01A6 


9D30 


3 


R 


LD 


A, pCOMlRxWrite 


Get the write pointer 


563 


01A8 


9CFE 


3 




X 


A, B 


Use ' B' as pointer 


564 


01AA 


9DB9 


3 




LD 


A, RBUF 


Get received character 


565 


01AC 


A2 


2 




X 


A, [B+] 


Save into receive buffer 


566 


01AD 


9DFE 


3 




LD 


A, B 


Update pointer 


567 


01AF 


9230 


2 


R 


IFEQ 


A, IbCOMlRxBuf fer+cCOMlRxBufLen; Past end of buffer 


568 


01B1 


9820 


2 


R 


LD 


A, #bCOMlRxBuffer 


Reload start of buffer 


569 


01B3 


9C30 


3 


R 


X 


A, pCOMlRxWrite 


Save pointer 


570 


01B5 


9800 


2 




LD 


A, #LOW (Restore) 


Push returnaddress on stack 


571 


01B7 


67 


3 




PUSH 


A 




572 


01B8 


9802 


2 




LD 


A, #HIGH (Restore) 




573 


01BA 


67 


3 




PUSH 


A 




574 


01BB 


9D1E 


3 


R 


LD 


A, wUARTRxCallBack 


Push callback address on stack 


575 


01BD 


67 


3 




PUSH 


A 




576 


01BE 


9D1F 


3R 


LD 


A, wUARTRxCallBack+1 




577 


01C0 


67 


3 




PUSH 


A 




578 


Old 


DFOO 


3 




LD 


S, #0 


Switch to User RAM for call back 


579 


01C3 


8E 


5 




RET 


; Launch the call back thread to service data 


580 














581 










.********** 


*********************************************************** 


582 


01C4 








ServiceSoft 


ware : 


583 


01C4 


3b 


1 




RPND 




Clear SW interrupt (NMI) flag 


584 


01C5 


8C 


3 




POP 


A 


Clear old return address 


585 


01C6 


8C 


3 




POP 


A 




586 


01C7 


DFOO 


3 




LD 


S, #0 


Point to users RAM space 


587 


01C9 


8E 


5 




RET 




Return to Users osStart Call 


588 














589 










.********** 


*********************************************************** 


590 


01CA 








ServiceMicrowire : 


591 


01CA 


BDE8 6B 


4 




RBIT 


WPND, ICNTRL ; Clear microwire pending flag 


592 


01CD 


2200 > 


3 




JP 


Restore ; Return 


593 










;********** 


*********************************************************** 


594 


01CF 








ServiceExte 


rnal : 


595 


01CF 


BDEF6B 


4 




RBIT 


IPND, PSW ; Clear the external interrupt pending 


596 


01D2 


2200 > 


3 




JP 


Restore ; Return 


597 














598 










.********** 


*********************************************************** 


599 


01E0 








.ORG 


OxOlEO ; Vector table begins at OxOlEO 



19 



www.national.com 



600 


01E0 


010A 




. ADDRW 


ServiceUnused ; 


Default vector (VIS with no interrupt) 


601 


01E2 


010D 




. ADDRW 


ServiceWakeup 




Wakeup vector 


602 


01E4 


0184 




. ADDRW 


ServiceTimerT3B 




Timer 3B vector 


603 


01E6 


0170 




. ADDRW 


ServiceTimerT3A 




Timer 3A vector 


604 


01E8 


016C 




. ADDRW 


ServiceTimerT2B 




Timer 2B vector 


605 


01EA 


0158 




. ADDRW 


ServiceTimerT2 




Timer 2A vector 


606 


01EC 


0188 




. ADDRW 


ServiceUART_TX 




UART Transmit vector 


607 


01EE 


01A4 




. ADDRW 


ServiceUART_RX 




UART Receive vector 


608 


01F0 


010A 




. ADDRW 


ServiceUnused 




(Reserved for future use) 


609 


01F2 


01CA 




. ADDRW 


ServiceMicrowire 




Microwire vector 


610 


01F4 


0154 




. ADDRW 


ServiceTimerTIB 




TimerlB vector 


611 


01F6 


0140 




. ADDRW 


ServiceTimerTIA 




Timer 1A vector 


612 


01F8 


0112 




. ADDRW 


ServiceTimerTO 




Timer vector 


613 


01FA 


01CF 




. ADDRW 


ServiceExternal 




External pin vector 


614 


01FC010A 




. ADDRW 


ServiceUnused 




(Reserved for future use) 


61501FE 01C4 




. ADDRW 


ServiceSof tware 




NMI - Software interrupt 


616 








************ 


***************** 


**************************************** 


617 


0200 




Restore : 






618 














619 


0200 


8C 


3 


POP 


A 




Get old segment 


620 


0201 


9CFF 


3 


X 


A, S 




Restore segment register 


621 


0203 


8C 


3 


POP 


A 




Restore 'PSW' Carry flags 


622 


0204 


BDEF6E 


4 


RBIT 


C, PSW 




Assume no carry 


623 


0207 


6040 


2 


IFBIT 


C, A 




Was there a carry? 


624 


0209 


BDEF7E 


4 


SBIT 


C, PSW 




Yes, set it up again 


625 


020C 


BDEF6F 


4 


RBIT 


HC, PSW 




Assume no half carry 


626 


020F 


6080 


2 


IFBIT 


HC, A 




Was there a half carry? 


627 


0211 


BDEF7F 


4 


SBIT 


HC, PSW 




Yes, set it up again 


628 


0214 


8C 


3 


POP 


A 




Restore 'B' 


629 


0215 


9CFE 


3 


X 


A, B 






630 


0217 


8C 


3 


POP 


A 




Restore 'A' 


631 


0218 


8F 


b 


RETI 






Return from interrupt 


632 














633 








************ 


***************** 


**************************************** 


634 














635 








************ 


***************** 


**************************************** 


636 














637 








Routine 


: osPUSH 




638 






; \ 


Jse: This routine pushes 


the 'A' register onto the OS data stack 


639 








Entry: 


Accumulator contains data byte to push 


640 








Returns 


: Accumulator contains original data (Like real PUSH) 


641 








Comments: Used for user 


temporary storage 


642 














643 








************ 


***************** 


**************************************** 


644 


0219 






3SPUSH: 






645 


0219 


67 


3 


PUSH 


A 




Save 'A' for page switch 


646 


021A 


9DFF 


3 


LD 


A, S 




Get old segment 


647 


021C 


DF01 


3 


LD 


S, #1 




Switch to the OS Segment 


648 


021E 


9C00 


3 R 


X 


A, aStore+0 




Save 


649 


0220 


9DFE 


3 


LD 


A, B 




Save ' B' for now 


650 


0222 


9C01 


3 R 


X 


A, aStore+1 




651 


0224 


9D08 


3 R 


LD 


A, pStack 


; Get the stack pointer 


652 


0226 


9CFE 


3 


X 


A, B 


; Stick it into 'B' for pointer 


653 


0228 


8C 


3 


POP 


A 


; Get the data from the main stack 


654 


0229 


67 


3 


PUSH 


A ; Put it back on the main stack for later 


655 


022A 


A3 


2 


X 


A, [B-] 




Push data, Adjust pointer 


656 


022B 


9DFE 


3 


LD 


A, B 




Save new stack pointer 


657 


022D 


9C08 


3 R 


X 


A, pStack 




in pointer register 


658 


022F 


9D01 


3 R 


LD 


A, aStore+1 




Restore 'B' 


659 


0231 


9CFE 


3 


X 


A, B 






660 


0233 


9D00 


3 R 


LD 


A, aStore+0 




Get old RAM segment 


661 


0235 


9CFF 


3 


X 


A, S 




Restore the old segment 


662 


0237 


8C 


3 


POP 


A ; return original 'A' value (like real PUSH) 


663 


0238 


8E 


b 


RET 




; Go do some more stuff. . . 


664 














665 








************ 


***************** 


**************************************** 


666 















www.national.com 



20 



667 










Routine 


: osPOP 




668 










Use: 


This routine pops data from the OS data stack into 


669 












the 'A' register. 




670 










Entry: 


(none) 




671 










Returns 


: Accumulator contains poped data from OS data stack 


672 










Comments: Used for user temporary storage 


673 
















674 










************ 


********************************************************* 


675 


0239 






osPOP : 






676 


0239 


9DFF 


3 




LD 


A, S 


Get current RAM segment 


677 


023B 


DF01 


3 




LD 


S, #1 


Switch to the OS Segment 


678 


023D 


9C00 


3 


R 


X 


A, aStore+0 


Save for later 


679 


023F 


9DFE 


3 




LD 


A, B 


Save ' B' 


680 


0241 


9C01 


3 


R 


X 


A, aStore+1 


in store+1 


681 


0243 


9D08 


3 


R 


LD 


A, pStack ; Get the current OS Data Stack Pointer 


682 


0245 


927F 


2 




IFEQ 


A, IcTopOfSysRAM 


At the top? 


683 


0247 


OE 


3 




JP 


osPOPError ; Yes, bad news... User screwed up. 


684 


0248 


8A 


1 




INC 


A 


Adjust Stack pointer 


685 


0249 


9C08 


3 


R 


X 


A, pStack 


Save it back 


686 


024B 


9D08 


3 


R 


LD 


A, pStack 


Reloadpointer 


687 


024D 


9CFE 


3 




X 


A, B 


Use 'B' as pointer into RAM 


688 


024F 


AE 


1 




LD 


A, [B] 


Get the data from the stack 


689 


0250 


67 


3 




PUSH 


A 


Save it for return value 


690 


0251 


9D01 


3 


R 


LD 


A, aStore+1 


Restore 'B' 


691 


0253 


9CFE 


3 




X 


A, B 


to original value 


692 


0255 


02 


3 




JP 


osPOPExit 


Done, return 


693 


0256 






osPOPError : 






694 


0256 


64 


1 




CLR 


A ; Put 


'0' on stack for return value 


695 


0257 


67 


3 




PUSH 


A 


Save return value 


696 


0258 






osPOPExlt : 






697 


0258 


9D00 


3 


R 


LD 


A, aStore+0 


Restore user RAM segment 


698 


025A 


9CFF 


3 




X 


A, S 




699 


025C 


8C 


3 




POP 


A 


Return value from OS Stack 


700 


025D 


8E 


5 




RE I 




Go do some more stuff... 


701 
















702 
















703 










************ 


********************************************************* 


704 
















705 










Routine 


: osSetMaxTaskTime 




706 






; 


U 


se: This r 


outine enables the task watcher and sets the time limit. 


707 
















708 




; 




Entr; 


/: Accumulat 


or holds the time constant, if zero function disabled. 


709 
















710 










Returns 


: Accumulatorreturns assigned task number if successful, 


711 












zero if the task was 


not added. 


712 










Alters : 


'A' 




713 
















714 










************ 


********************************************************* 


715 


025E 






c 


isSetMaxTaskT 


ime : 




716 


025E 


DF01 


3 




LD 


S, #1 


Switch to OS segment 


717 


0260 


9200 


2 




IFEQ 


A, #0 


Turn function off? 


718 


0262 


OA 


3 




JP 


osSMTT_Off 


Yes, turn it off, return. 


719 


0263 


9C0E 


3 


R 


X 


A, bMaxTaskTime 


Save max task time 


720 


0265 


9D0E 


3 


R 


LD 


A, bMaxTaskTime 


Get it back 


721 


0267 


9C0F 


3 


R 


X 


A, bTaskTime 


Transfer to register for counter 


722 


0269 


BDE87C 


4 




SBIT 


T0EN, ICNTRL 


Turn on the timer interrupt 


723 


026C 


09 


3 




JP 


osSMTT_Exit 


Done, return 


724 


026D 






c 


isSMTT_Of f : 






725 


026D 


BDE86C 


4 




RBIT 


T0EN, ICNTRL 


Disable the TO interrupt 


726 


0270 


BCOFOO 


3 


R 


LD 


bTaskTime, #0 


Clear registers and counters 


727 


0273 


BCOEOO 


3 


R 


LD 


bMaxTaskTime, #0 




728 


0276 






c 


isSMTT_Exit : 






729 


0276 


DFOO 


3 




LD 


S, #0 


Restore application segment 


730 


0278 


8E 


5 




RE I 




Return 


731 
















732 










************ 


********************** 


t********************************** 


733 

















www.national.com 



734 










Routine 


: osSetTimer 




735 








Use: This 


routine Start a timer 


with a call back routine. If the 


736 








; 


ca 


11 


oack is set to zero 


Task 1 (Main task) will get the 


737 








; 


ca 


11 


with the accumulator set to cmTimer, and 'B' with the 


738 












timer handle. 




739 


















740 










Entry: 


Stack has all data pushed on in this order: 


741 












1) Push LSB of Timer 


value 


742 












2) Push MSB of Timer 


value 


743 








; 


3) 


Push LSB of call back 


routine address (0 if main task} 


744 








; 


4) 


Push MSB of call back 


routine address (0 if main task} 


745 








Returns: Accumulat 


or holds handle number for timer (1-n) if successful 


746 












Accumulator is zero 


(0} if resource unavailable 


747 


















748 










************ 


*** 


******************* 


*********************************** 


749 


0279 






osSetTimer : 








750 


0279 


DF01 


3 




LD 


s, 


#1 


Switch Data RAM segment to OS 


751 


027B 


8C 


3 




POP 


A 




Get MSB of calling routine 


752 


027C 


9C0D 


3 


R 


X 


A, 


wAddress+1 


Save for now 


753 


027E 


8C 


3 




POP 


A 




Get LSB of calling routine 


754 


027F 


9C0C 


3 


R 


X 


A, 


wAddress 


Save for now 


755 


0281 


8C 


3 




POP 


A 




Get MSB of Call Back routine 


756 


0282 


9C14 


3 


R 


X 


A, 


wTimerCallBack+1 


Save for now 


757 


0284 


8C 


3 




POP 


A 




Get LSB of Call Back routine 


758 


0285 


9C13 


3 


R 


X 


A, 


wTimerCallBack 


Save for now 


759 


0287 


8C 


3 




POP 


A 




Get MSB of time period 


760 


0288 


9C12 


3 


R 


X 


A, 


wPeriod+1 


Save for now 


761 


028A 


8C 


3 




POP 


A 




Get LSB of time period 


762 


028B 


9C11 


3 


R 


X 


A 


wPeriod 


Save for now 


763 


028D 


9D0C 


3 


R 


LD 


A, 


wAddress 


Restore the return address 


764 


028F 


67 


3 




PUSH 


A 




Save LSB first 


765 


0290 


9D0D 


3 


R 


LD 


A, 


wAddress+1 




766 


0292 


67 


3 




PUSH 


A 




Save MSB second 


767 


















768 


0293 


64 


1 




CLR 


A 




Clear 'A' 


769 


0294 


9F10 


2 


R 


LD 


B, 


#fStatus 


Find a free timer 


770 


0296 






osSetTimerl : 








771 


0296 


70 


1 




IFBIT 


fT 


imerl, [B] 


Timer 1 free? 


772 


0297 


06 


3 




JP 


OS 


SetTimer2 


No, try timer 2 


773 


0298 


78 


1 




SBIT 


fT 


imerl, [B] 


Capture timer 


774 


0299 


9F15 


2 


R 


LD 


B, 


#wTimerlCallBack 


yes, load and start timer 1 


775 


029B 


9801 


2 




LD 


A, 


#1 




776 


029D 


10 


3 




JP 


OS 


SetTimerStart 




111 


029E 






0sSetTimer2 : 








778 


029E 


71 


1 




IFBIT 


fT 


imer2, [B] 


Timer 2 free? 


779 


029F 


06 


3 




JP 


OS 


SetTimer3 


No, try timer 3 


780 


02A0 


79 


1 




SBIT 


fT 


imer2, [B] 


Capture timer 


781 


02A1 


9F17 


2 


R 


LD 


B, 


#wTimer2CallBack 


yes, load and start timer 2 


782 


02A39802 


2 




LD 


A, 


#2 




783 


02A5 


08 


3 




JP 


OS 


SetTimerStart 




784 


02A6 






osSetTimer3: 








785 


02A6 


72 


1 




IFBIT 


fT 


imer3, [B] 


Timer 2 free? 


786 


02A7 


22FB > 


3 




JP 


OS 


SetTimerExit 


No timers available, sorry... 


787 


02A9 


7A 


1 




SBIT 


fT 


imer3, [B] 


Capture timer 


788 


02AA 


9F17 


2 


R 


LD 


B, 


#wTimer2CallBack 


yes, load and start timer 2 


789 


02 AC 


9802 


2 




LD 


A, 


#2 




790 


















791 


02AE 






osSetTimerStart : 






792 


02AE 


67 


3 




PUSH 


A 




Save timer handle 


793 


02AF 


AO 


1 




RC 






Check if zero 


794 


02B0 


9D13 


3 


R 


LD 


A, 


wTimerCallBack 


Get return address 


795 


02B2 


BD1480 


4 


R 


ADC 


A, 


wTimerCallBack+1 


See if all zeros 


796 


02B5 


88 


1 




:fc 




; if 


zhere was a carry, good address 


797 


02B6 


OA 


3 




jp 


OS 


Set Timer Address 




798 


02B7 


9900 


2 




IFNE 


A, 


#0 


If not zero, also good address 


799 


02B9 


07 


3 




JP 


OS 


Set Timer Address 




800 



















www.national.com 



801 


02BA 


9D46 


3 


R 


LD 


A, 


aTaskRecs+1 ; Point to TASK 1 LSB (Default callback) 


802 


02BC 


A2 


2 




X 


A, 


[B+] 


Save LSB in call back record 


803 


02BD 


9D47 


3 


R 


LD 


A, 


aTaskRecs+2 


Now get MSB 


804 


02BF 


A6 


1 




X 


A, 


[B] 


Save MSB in call back record 


805 


02C0 


06 


3 




JP 


OS 


SetTimerPeriod 


Now go fire it up! 


806 


02C1 






osSetTimerAdd 


ress : 




807 


02C1 


9D13 


3 


R 


LD 


A, 


wTimerCallBack 


Get LSB of call back routine 


808 


02C3 


A2 


2 




X 


A, 


[B+] 


Save in LSB of call back record 


809 


02C4 


9D14 


3 


R 


LD 


A, 


wTimerCallBack+1 


Get MSB of call back routine 


810 


02C6 


A6 


1 




X 


A, 


[B] 


Save in MSB of call back record 


811 


02C7 






osSetTimerPerioc 






812 


02C7 


8C 


3 




POP 


A 




Get timer handle back 


813 


02C8 


67 


3 




PUSH 


A 




Save for later 


814 


















815 


02C9 


9FEA 


2 




LD 


B, 


#TMRlLO 


Point to timer 1 as default 


816 


02CB9202 


2 




IFEQ 


A, 


#2 


Timer 2? 


817 


02CD 


9FC0 


2 




LD 


B, 


#TMR2LO 


Yes, use timer 2 


818 


02CF 


9203 


2 




IFEQ 


A, 


#3 


Timer 3? 


819 


02D1 


9FB0 


2 




LD 


B, 


#TMR3LO 


Yes, use timer 3 


820 


















821 


02D3 


9D11 


3 


R 


LD 


A, 


wPeriod 


Get LSB of period 


822 


02D5 


A2 


2 




X 


A, 


[B+] 


Save it 


823 


02D6 


9D12 


3 


R 


LD 


A, 


wPeriod+1 


Get MSB of period 


824 


02D8 


A2 


2 




X 


A, 


[B+] 


Save it 


825 


02D9 


9D11 


3 


R 


LD 


A, 


wPeriod 


Get LSB of period 


826 


02DB 


A2 


2 




X 


A, 


[B+] 


Save it 


827 


02DC 


9D12 


3 


R 


LD 


A, 


wPeriod+1 


Get MSB of period 


828 


02DE 


A2 


2 




X 


A, 


[B+] 


Save it 


829 


















830 


02DF 


8C 


3 




POP 


A 


; Check if timer 1 (FIX FOR MEM MAP) 


831 


02E0 


67 


3 




PUSH 


A 




memory is scrambled for timer 1 


832 


02E1 


9201 


2 




IFEQ 


A, 


#1 


Timer 1? 


833 


02E3 


9FE6 


2 




LD 


B, 


#TlRBLO 


Yes, fix location 


834 


















835 


02E5 


9D11 


3 


R 


LD 


A, 


wPeriod 


Get LSB of period 


836 


02E7 


A2 


2 




X 


A, 


[B+] 


Save it 


837 


02E8 


9D12 


3 


R 


LD 


A, 


wPeriod+1 


Get MSB of period 


838 


02EA 


A6 


1 




X 


A, 


[B] 


Save it 


839 


















840 


02EB 


8C 


3 




POP 


A 




Get timer handle back 


841 


02EC 


9201 


2 




IFEQ 


A, 


#1 


Start timer 1? 


842 


02EE 


BDEE7C 


4 




SBIT 


T1C0, CNTRL 


Yes, start it up 


843 


02F1 


9202 


2 




IFEQ 


A, 


#2 


Start timer 2? 


844 


02F3 


BDC67C 


4 




SBIT 


T2CO, T2CNTRL 


Yes, start it up 


845 


02F6 


9203 


2 




IFEQ 


A, 


#3 


Start timer 3? 


846 


02F8 


BDB67C 


4 




SBIT 


T3CO, T3CNTRL 


Yes, start it up 


847 


















848 


02FB 






osSetTimerExi 


t : 






849 


02FB 


DF00 


3 




LD 


s, 


#0 ; Switch data RAM segment back to user 


850 


02FD 


8E 


5 




RET 






Return 


851 


















852 










************ 


** * 


****************************************************** 


853 


















854 










Routine 


: osKillTimer 




855 










Use: 


This routine stop a timer and free it. 


856 


















857 










Entry: 


Accumulator contains 


the non-zero timer handle 


858 










Returns 


: Accumulator is zero if successful, non-zero if failed. 


859 


















860 










************ 


*** 


****************************************************** 


861 


02FE 






c 


>sKillTimer: 








862 


02FE 


DF01 


3 




LD 


s, 


#1 


Switch data segment to OS 


863 


0300 


9201 


2 




IFEQ 


A, 


#1 


Kill Timer 1? 


864 


0302 


09 


3 




JP 


OS 


KillTimerl 


Yes, stop it. 


865 


0303 


9202 


2 




IFEQ 


A, 


#2 


Kill Timer 2? 


866 


0305 


OD 


3 




JP 


OS 


KillTimer2 


Yes, stop it. 


867 


0306 


9203 


2 




IFEQ 


A, 


#3 


Kill Timer 3? 



23 



www.national.com 



868 


0308 


11 


3 


JP 


osKillTimer3 


Yes, stop it . 


869 


0309 


98FF 


2 


LD 


A, #0xFF 


Failure, incorrect handle. 


870 


030B 


15 


3 


JP 


osKillTimerExit 


Return 


871 


030C 




osKlllTlmerl : 






872 


030C 


BD1068 


4 R 


RBIT 


fTimerl, fstatus 


Free timer 


873 


030F 


BDEE6C 


4 


RBIT 


T1C0, CNTRL 


Stop the timer 


874 


0312 


0D 


3 


JP 


osKillTimerOK 




875 


0313 




osKlllTlmer2 : 






876 


0313 


BD1069 


4 R 


RBIT 


fTimer2, fstatus 


Free timer 


877 


0316 


BDC66C 


4 


RBIT 


T2CO, T2CNTRL 


Stop the timer 


878 


0319 


06 


3 


JP 


osKillTimerOK 




879 


031A 




osKlllTlmer3 : 






880 


031A 


BD106A 


4 R 


RBIT 


fTimer3, fstatus 


Free timer 


881 


031D 


BDB66C 


4 


RBIT 


T3CO, T3CNTRL 


Stop the timer 


882 


0320 




osKlllTlmerOK 






883 


0320 


64 


1 


CLR 


A 


Report timer dead. . . 


884 


0321 




osKlllTlmerEx 


it: 




885 


0321 


DFOO 


3 


LD 


S, #0 


Switch data segment back to user 


886 


0323 


8E 


5 


RET 




Return 


887 














888 








************ 


********************************************************** 


889 














890 








Routine 


osSignal 




891 








Use: 


This routine will move a task to the top of the queue. 


892 














893 








Entry: 


Accumulator contains 


the task number to signal next. 


894 








Returns 


: Accumulator is zero if successful, non-zero if failed. 


895 














896 








************ 


********************************************************* 


897 


0324 






3sSignal : 






898 


0324 


DF01 


3 


LD 


S, #1 


Switch to OS RAM Page 


899 


0326 


BD0A83 


4 R 


IFGT 


A, bTaskNew 


Is the task number valid? 


900 


0329 


OA 


3 


JP 


osSignalError 


No, don't start 


901 














902 


032A 


8B 


1 


DEC 


A 


Use corrected pointer (p-1} 


903 


032B 


30A4 


5 


JSR 


osGetTaskAddress ; Get 


, a pointer into the task buffer 


904 


032D 


70 


1 


IFBIT 


fActive, [B] 


Check if task running 


905 


032E 


01 


3 


JP 


osSignalOK 


Yes, go move to high priority 


906 


032F 


04 


3 


JP 


osSignalError 


No, Go error out 


907 














908 


0330 






DsSignalOK: 






909 


0330 


9C0B 


3 R 


X 


A, bTaskNext 


Next task goes to top! 


910 


0332 


64 


1 


CLR 


A 


Clear 'A' to signal OK 


911 


0333 


02 


3 


JP 


osSignalEnd 


End routine 


912 


0334 






OsSignalError 






913 


0334 


98FF 


2 


LD 


A, #0xFF 


Signal error (non-zero) 


914 


0336 






3sSignalEnd: 






915 


0336 


DFOO 


3 


LD 


S, #0 


Switch back to user RAM 


916 


0338 


8E 


b 


RET 




Return to calling task 


917 














918 








************ 


********************************************************* 


919 














920 








Routine 


osSetCommChannel 




921 








Use: 


This routine will capture a UART to a task 


922 






; 


and setup the baud rate, framing, data bits, and buffers. 


923 














924 






; e 


itry: 'A' h 


Dlds requested COM chai 


inel (1=UART 1, 2=UART 2, etc.) 


925 










Data is pushed on the 


5 stack as follows: 


926 






; 


* PUSH baud rate (see table 


3 below), data bits, and parity 


927 










* PUSH LSB of UART RI 


i Call Back routine 


928 










* PUSH MSB of UART RI 


i Call Back routine 


929 








Returns 


If successful, returi 


is handle to UART (1-n) in 'A' 


930 










If failure, return zero (0) in 'A' 


931 














932 








Table 1 


76543210 (Setup byte 


for UART - pushed on stack first) 


933 










1 | I | ' ' ' ' - Baud rate: 




934 










I | | ' Data bits 


(0=7, 1=8) 



www.national.com 



935 












|. stop blts ( o=l, 1=2) 


936 












' Parity (0=none, l=On) 


937 












' Parity Type(0=Odd, l=Even) 


938 














939 










Table 


2: Baud Rate (bits 0-3) 


940 














941 












0000 = 110 BPS 


942 












0001 = 134.5 BPS 


943 












0010 = 150 BPS 


944 












0011 = 300 BPS 


945 












0100 = 600 BPS 


946 












0101 = 1200 BPS 


947 












0110 = 2400 BPS 


948 












0111 = 4800 BPS 


949 












1000 = 7200 BPS 


950 












1001 = 9600 BPS 


951 












1010 = 19200 BPS 


952 












1011 = (Reserved*) 


953 












1100 = (Reserved*) 


954 












1101 = (Reserved*) 


955 












1110 = (Reserved*) 


956 












1111 - (Reserved*) 


957 














958 












Note * Defaults to 9600 BPS 


959 














960 










********************************************************************* 


961 


0339 






osSetCommChannel : 


962 


0339 


9DFF 


3 




LD 


A, S ; Save old segment 


963 


033B 


DF01 


3 




LD 


S, #1 ; Switch Data RAM segment to OS 


964 


033D 


9C00 


3 


R 


X 


A, aStore+0 ; Save for later to restore (in OS Segment) 


965 














966 


033F 


8C 


3 




POP 


A 


Get MSB of calling routine 


967 


0340 


9C0D 


3 


R 


X 


A, wAddress+1 


Save for now 


968 


0342 


8C 


3 




POP 


A 


Get LSB of calling routine 


969 


0343 


9C0C 


3 


R 


X 


A, wAddress 


Save for now 


970 


0345 


8C 


3 




POP 


A 


Get MSB of Call Back routine 


971 


0346 


9C1F 


3 


R 


X 


A, wUARTRxCallBack+1 


Save for now 


972 


0348 


8C 


3 




POP 


A 


Get LSB of Call Back routine 


973 


0349 


9C1E 


3 


R 


X 


A, wUARTRxCallBack 


Save for now 


974 


034B 


8C 


3 




POP 


A 


Get MSB of time period 


975 


034C 


9C1D 


3 


R 


X 


A, bUARTSettings 


Save for now 


976 














977 


034E 


9D0C 


3 


R 


LD 


A, wAddress 


Restore the return address 


978 


0350 


67 


3 




PUSH 


A 


Save LSB first 


979 


0351 


9D0D 


3 


R 


LD 


A, wAddress+1 




980 


0353 


67 


3 




PUSH 


A 


Save MSB second 


981 














982 


0354 


BD1073 


4 


R 


IFBIT 


fUART, fStatus ; is UART already in use? 


983 


0357 


23D1 > 


3 




JP 


osSetUARTFail ; Yes, bail out 


984 














985 


0359 


BD107B 


4 


R 


SBIT 


fUART, fStatus 


Take control of UART 


986 


035C 


9D1D 


3 


R 


LD 


A, bUARTSettings 


Setup UART 


987 


035E 


950F 


2 




AND 


A, #0x0F 


Clear unused bits for now 


988 


0360 


AO 


1 




RC 




Multiply by 2 


989 


0361 


A8 


1 




RLC 


A 




990 


0362 


9476 


2 




ADD 


A, #LOW(osBaudTable) 


Get table offset 


991 


0364 


A4 


3 




LAID 




Get first byte 


992 


0365 


9CBD 


3 




X 


A, BAUD 


Put into baud rate register 


993 














994 


0367 


9D1D 


3 


R 


LD 


A, bUARTSettings 


Setup UART 


995 


0369 


950F 


2 




AND 


A, #0x0F 


Clear unused bits for now 


996 


036B 


AO 


1 




RC 




Multiply by 2 


997 


036C 


A8 


1 




RLC 


A 




998 


036D 


9477 


2 




ADD 


A, #LOW (osBaudTable) +1 ; Get table offset+1 


999 


036F 


A4 


3 




LAID 


; Get first byte 


1000 


0370 


9760 


2 




OR 


A, #cBaudPrescale ; Add prescaler value 


1001 


0372 


9CBE 


3 




X 


A, PSR ; Put into Prescaler register 



25 



www.national.com 



1002 


0374 


2396 > 


3 


JP 


osSetUART2 




1003 


0376 




osBaudTable: 






1004 


0376 


6903 




.DW 


873 




110 BPS 


1005 


0378 


CA02 




.DW 


714 




134.5 BPS 


1006 


037A 


8002 




.DW 


640 




150 BPS 


1007 


037C 


3F01 




.DW 


319 




300 BPS 


1008 


037E 


9F00 




.DW 


159 




600 BPS 


1009 


0380 


4F00 




.DW 


79 




1200 BPS 


1010 


0382 


2700 




.DW 


39 




2400 BPS 


1011 


0384 


1300 




.DW 


19 




4800 BPS 


1012 


0386 


0E00 




.DW 


14 




7200 BPS 


1013 


0388 


0900 




.DW 


9 




9600 BPS 


1014 


038A 


0400 




.DW 


4 




19200 BPS 


1015 


038C 


0900 




.DW 


9 




9600 BPS (Just in case) 


1016 


038E 


0900 




.DW 


9 




9600 BPS (Ditto) 


1017 


0390 


0900 




.DW 


9 




9600 BPS (Ditto) 


1018 


0392 


0900 




.DW 


9 




9600 BPS (Ditto) 


1019 


0394 


0900 




.DW 


9 




9600 BPS (Ditto) 


1020 














1021 


0396 




osSetUART2 : 






1022 


0396 


BCBA08 


3 


LD 


ENU, #B' 00001000 




No parity, 7 data bits 


1023 


0399BCBB00 


3 


LD 


ENUR, #B' 00000000 




Clear attention mode 


1024 


039CBCBC20 


3 


LD 


ENUI, #B'00100000 




1 stop bit, TDX pin enabled, 


1025 














Async mode, Int Clks 


1026 


039F 


BDD16B 


4 


RBIT 


3, PORTLC 




RX pin as input 


1027 


03A2 


BDD17A 


4 


SBIT 


2, PORTLC 




TX Pin as output 


1028 


03A5 


9D1D 


3 R 


LD 


A, bUARTSettings 




Get the settings again 


1029 


03A7 


6010 


2 


IFBIT 


fDataBits, A 




7 or 8 data bits? 


1030 


03A9 


BDBA6B 


4 


RBIT 


CHLO, ENU 




8, Set to 8 data bits 


1031 


3 AC 


6020 


2 


IFBIT 


fStopBitS, A 




1 or 2 stop bits 


1032 


3AE 


BDBC7F 


4 


SBIT 


STP2, ENUI 




2, Set to 2 stop bits 


1033 


03B1 


6040 


2 


IFBIT 


fParltySel, A 




Parity? 


1034 


03B3 


BDBA7F 


4 


SBIT 


PEN, ENU 




Yes, turn it on 


1035 


03B6 


6080 


2 


IFBIT 


fParltyType, A 




Odd/Even? 


1036 


03B8 


BDBA7D 


4 


SBIT 


PSEL0, ENU 




Even, set it up. 


1037 














1038 


03BB 


BC4232 


3 R 


LD 


pCOMlTxWrite, tbCOMlTxBuf f er ; Setup Tx Write pointer 


1039 


03BE 


BC4332 


3 R 


LD 


pCOMlTxRead, IbCOMlTxBuffer ; Setup Tx Read pointer 


1040 


03C1 


BC3020 


3 R 


LD 


pCOMlRxWrite, IbCOMlRxBuf fer ; Setup Rx write pointer 


1041 


03C4 


BC3120 


3 R 


LD 


pCOMlRxRead, IbCOMlRxBuffer ; Setup Rx Read pointer 


1042 














1043 


03C7 


9D00 


3 R 


LD 


A, aStore+0 


; Restore old RAM segment 


1044 


03C9 


9CFF 


3 


X 


A, S 


; 


1045 


03CB 


9801 


2 


LD 


A, #1 ; 


Only one UART so return handle-1 


1046 


03CD 


BDBC79 


4 


SBIT 


ERI, ENUI 


; Turn on the receiver interrupt 


1047 


03D0 


05 


3 


JP 


osSetUARTExit 


; Done 


1048 


03D1 




osSetUARTFall : 






1049 


03D1 


9D00 


3 R 


LD 


A, aStore+0 




Restore old RAM segment 


1050 


03D3 


9CFF 


3 


X 


A, S 






1051 


03D5 


64 


1 


CLR 


A 




Returnbad handle value 


1052 


03D6 




osSetUARTExit : 






1053 


03D6 


8E 


5 


RET 




; Return 


1054 














1055 








************* 


******************* 


************************************* 


1056 














1057 








Routine 


: osUARTGetChar 




1058 








Use: 


This routine gets 


Dne character from the receive gueue 


1059 














1060 








Entry: 


'B' holds comm channel handle 


1061 








Returns 


: 'A' hold received 


character 


1062 










'B' is zero if fail, otherwise handle remains. 


1063 










'X' is altered. 




1064 














1065 








************* 


******************* 


************************************* 


1066 


03D7 






jsUARTGetChar : 






1067 


03D7 


9DFF 


3 


LD 


A, S 


; Save old segment 


1068 


03D9 


DF01 


3 


LD 


S, #1 


; Switch Data RAM segment to OS 



www.national.com 



26 



1069 


03DB 


9C00 


3 


R 


X 


A, aStore+0 ; Save 


for later to restore (in OS Segment) 


1070 










; 








1071 


03DD 


9DFE 


3 




LD 


A, B 




Get comm channel handle 


1072 


03DF 


9201 


2 




IFEQ 


A, #1 


Check handle to see if valid UART 


1073 


03E1 


01 


3 




JP 


osUARTRxChl 




UART on channel 1 


1074 


03E2 


18 


3 




JP 


osUARTRxFail 




Not a valid UART 


1075 


03E3 








osUARTRxChl : 








1076 


03E3 


9D31 


3 


R 


LD 


A, pCOMlRxRead 




Get the read pointer 


1077 


03E5 


BD3082 


4 


R 


IFEQ 


A, pCOMlRxWrite 




Any data to receive? 


1078 


03E8 


12 


3 




JP 


osUARTRxFail 




No, bail . . . 


1079 


03E9 


9CFC 


3 




X 


A, X 




Use 'X' as pointer into buffer 


1080 


03EB 


BA 


3 




LD 


A, [X+] 




Get the new character 


1081 


03EC 


67 


3 




PUSH 


A 




Save on stack for now 


1082 


03ED 


9DFC 


3 




LD 


A, X 




Get new pointer value 


1083 


03EF 


9230 


2 


R 


IFEQ 


A, IbCOMlRxBuf fer+cCOMlRxBufLen; Past end of buffer 


1084 


03F1 


9820 


2 


R 


LD 


A, #bCOMlRxBuffer 




Reload start of buffer 


1085 


03F3 


9C31 


3 


R 


X 


A, pCOMlRxRead 




Save pointer 


1086 


03F5 


9D00 


3 


R 


LD 


A, aStore+0 




Restore old RAM segment 


1087 


03F7 


9CFF 


3 




X 


A, S 






1088 


03F9 


8C 


3 




POP 


A 




Get data back 


1089 


03FA 


05 


3 




JP 


osUARTRxExit 




Done 


1090 


03FB 








osUARTRxFail: 








1091 


03FB 


9D00 


3 


R 


LD 


A, aStore+0 




Restore old RAM segment 


1092 


03FD 


9CFF 


3 




X 


A, S 






1093 


03FF 


5F 


1 




LD 


B, #0 




Clear handle 


1094 


0400 








osUARTRxExit : 








1095 


0400 


8E 


5 




RET 






Done . . . 


1096 


















1097 










.******************************** 


************************************* 


1098 


















1099 










; Routine: osUARTSend 






1100 




; 




Use: This routine queues a byte of data for transmission by the UART . 


1101 


















1102 










; Entry: 


'A' holds data byte, 'B' holds comm channel handle 


1103 










; Returns: If successful, returns 


zero 'A' 


1104 












If failure, returncnon 


-zero in 'A' 


1105 










.******************************** 


************************************* 


1106 


0401 








osUARTSend: 








1107 


0401 


67 


3 




PUSH 


A 




Save data 


1108 


0402 


9DFE 


3 




LD 


A, B 




Get comm channel handle 


1109 


0404 


9201 


2 




IFEQ 


A, #1 


Check handle to see if valid UART 


1110 


0406 


02 


3 




JP 


osUARTSendChl 




UART on channel 1 


1111 


0407 


2438 > 


3 




JP 


osUARTSendError 




Not a valid UART 


1112 


0409 








osUARTSendChl 








1113 


0409 


9DFF 


3 




LD 


A, S 


Get 


the current segment register 


1114 


040B 


DF01 


3 




LD 


S, #1 




Switch to OS segment 


1115 


040D 


9C00 


3 


R 


X 


A, aStore+0 




Save for later on OS page 


1116 


040F 


BD4477 


4 


R 


IFBIT 


fTxBusy, bCOMlStatus 


Is transmitter busy? 


1117 


0412 


ID 


3 




JP 


osUARTSendBusy 




Yes, bail out 


1118 


0413 


9D42 


3 


R 


LD 


A, pCOMlTxWrite 




Get the write pointer to COM1 


1119 


0415 


9CFE 


3 




X 


A, B 




Use 'B' to write the data 


1120 


0417 


8C 


3 




POP 


A 


; Get 


, the data byte off the stack 


1121 


0418 


A2 


2 




X 


A, [B+] 




Write into buffer 


1122 


0419 


9DFE 


3 




LD 


A, B 




Get pointer back 


1123 


041B 


9242 


2 


R 


IFEQ 


A, IbCOMlTxBuf fer+ 


2COM1 


rxBufLen ;Past end of buffer? 


1124 


041D 


9832 


2 


R 


LD 


A, IbCOMlTxBuf fer 




Reload at start of buffer 


1125 


041F 


BD4382 


4 


R 


IFEQ 


A, pCOMlTxRead 




Have we overrun the FIFO? 


1126 


0422 


BD447F 


4 


R 


SBIT 


fTxBusy, bCOMlStatus 


Yes, use later for test. 


1127 


0425 


9C42 


3 


R 


X 


A, pCOMlTxWrite ; 


Save 


the new COM1 write pointer 


1128 


0427 


BDBC78 


4 


SBIT ETI, ENUI 


Enable transmitter 


inte 


rrupt (start transmitter) 


1129 


042A 


9D00 


3 


R 


LD 


A, aStore+0 




Get old segment pointer back 


1130 


042C 


9CFF 


3 




X 


A, S 




Return old segment 


1131 


042E 


64 


1 




CLR 


A 




Return with zero (success) 


1132 


042F 


OB 


3 




JP 


osUARTSendExit 




Done, return 


1133 


0430 








osUARTSendBusy : 






1134 


0430 


8C 




3 


POP 


A 




Adjust Stack 


1135 


0431 


9D00 




3 R 


LD 


A, aStore+0 




Get old segment pointer back 



www.national.com 



1136 


0433 


9CFF 


3 


X 


A, S 


Return old segment 


1137 


0435 


98FE 


2 


LD 


A, #X'FE 


Return non-zero value (Busy) 


1138 


0437 


03 


3 


JP 


osUARTSendExit 


Done, return 


1139 


0438 






osUARTSendError 






1140 


0438 


8C 


3 


POP 


A 


Adjust stack pointer 


1141 


0439 


98FF 


2 


LD 


A, #X'FF 


Return non-zero value (Error) 


1142 


043B 






osUARTSendExit : 






1143 


043B 


8E 


5 


RET 




Return 


1144 














1145 










************** 


********************** 


********************************* 


1146 
















1147 










Routine : 


osStart 




1148 










Use: 


This routine will start the MTK Operating System (OS) 


1149 
















1150 










Entry: 


(None required) 




1151 






; 


Returns: Accumulator is zero if successful, non-zero if failed. 


1152 








; 






1153 








.************** 


********************** 


********************************* 


1154 


043C 






osStart : 






1155 


043C 


DF01 


3 


LD 


S, #1 


Switch to OS RAM page 


1156 


043E 


9D0A 


3 


R LD 


A, bTaskNew 


Check if any tasked loaded. 


1157 


0440 


9200 


2 


IFEQ 


A, #0 


Any tasks loaded? 


1158 


0442 


2466 


> 3 


JP 


osStartError 


No, Return with error 


1159 








; 






1160 


0444 


30B3 


5 


JSR 


osGetFirstTask 


Get the first enabled task 


1161 


0446 


9200 


2 


IFEQ 


A, #0 


Anything to run? 


1162 


0448 


ID 


3 


JP 


osStartError 


No, Return with error 


1163 


0449 


9C09 


3 


R X 


A, bTask 


Save in currently running task 


1164 


044B 


30B7 


b 


JSR 


osGetNextTask 


Get the next task number 


1165 


044D 


9200 


2 


IFEQ 


A, #0 


Anything to run next? 


1166 


044F 


16 


3 


JP 


osStartError 


No, Return with error 


1167 


0450 


9C0B 


3 


R X 


A, bTaskNext 


Save in next task variable 


1168 








; 






1169 


0452 


986B 


2 


LD 


A, #LOW(osMain) 


Setup return Address 


1170 


0454 


67 


3 


PUSH 


A 


First LSB 


1171 


0455 


9804 


2 


LD 


A, #HIGH (osMain) 




1172 


0457 


67 


3 


PUSH 


A 


Next MSB 


1173 








; 






1174 


0458 


9D09 


3 


R LD 


A, bTask ; Get first task that's enabled 


1175 


045A 


8B 


1 


DEC 


A 


Yes, get the address 


1176 


045B 


30A4 


5 


JSR 


osGetTaskAddress 


Use to get the next task 


1177 


045D 


AA 


2 


LD 


A, [B+] 


Move past flags, Point to LSB 


1178 


045E 


AA 


2 


LD 


A, [B+] 


Get LSB, Point to MSB 


1179 


045F 


67 


3 


PUSH 


A 


Put LSB on stack first (FILO) 


1180 


0460 


AE 


1 


LD 


A, [B] 


Get MSB, Point at LSB 


1181 


0461 


67 


3 


PUSH 


A 


Put on stack 


1182 














1183 


0462 


BDEF78 


4 


SBIT 


GIE, PSW 




1184 


0465 


02 


3 


JP 


osStartEnd 


Go begin 


1185 


0466 






osStartError : 






1186 


0466 


98FF 


2 


LD 


A, #0xFF 


Make non-zero 


1187 


0468 






osStartEnd: 






1188 


0468 


DFOO 


3 


LD 


S, #0 


Switch back to user RAM 


1189 


4 6A 


8E 


b 


RET 




Start first task (Cool!) 


1190 














1191 










************** 


********************** 


********************************* 


1192 
















1193 










Routine : 


osMain 




1194 




; 




Use: This routine is the main loop of the kernal. All dispatching 


1195 






; 


is done from here. Any error handling is also done here. 


1196 
















1197 










Entry: 


(None required) 




1198 










Returns : 


(Never) 




1199 
















1200 










************** 


********************** 


********************************* 


1201 


046B 






osMain : 






1202 















www.national.com 



28 



1203 










. ** 


********* 


DO ERROR CHECKING HERE *************** 


1204 


















1205 


046B 


DF01 




3 




LD 


s, 


#1 ; Switch to OS data segment 


1206 


046D 


9D0B 




3 


R 


LD 


A, 


bTaskNext ; Get the pointer to the next task 


1207 


046F 


9200 




2 




IFEQ 


A, 


#0 ; Something very bad has happened! 


1208 


0471 


2495 


> 


3 




JP 


osMainExit ; Let the user decide how to fix it . 


1209 


0473 


986B 




2 




LD 


A, 


#LOW(osMain) ; Put return address on stack 


1210 


0475 


67 




3 




PUSH 


A 


; First LSB 


1211 


0476 


9804 




2 




LD 


A/ 


#HIGH (osMain) 


1212 


0478 


67 




3 




PUSH 


A 


; Next MSB 


1213 










; 








1214 


0479 


9D0B 




3 


R 


LD 


A, 


bTaskNext ; Update current task 


1215 


047B 


9C09 




3 


R 


X 


A, 


bTask ; 


1216 


047D 


30B7 




5 




JSR 


OS 


GetNextTask ; Get the next one 


1217 


047F 


9C0B 




3 


R 


X 


A, 


bTaskNext 


1218 


















1219 


0481 


9D09 




3 


R 


LD 


A, 


bTask ; Start next task thread 


1220 


0483 


8B 




1 




DEC 


A 


; Adjust task number for table look-up 


1221 


0484 


30A4 




5 




JSR 


OS 


GetTaskAddress ; Look up task address 


1222 


0486 


70 




1 




IFBIT 


fActive, [B] ; Check to make sure it's still active 


1223 


0487 


08 




3 




JP 


osMainSwitch ; Yes, still active - go switch 


1224 


0488 


30B7 




b 




JSR 


OS 


GetNextTask ; No, find one that is OK to start 


1225 


048A 


9C0B 




3 


R 


X 


A, 


bTaskNext ; Save it 


1226 


048C 


8C 




3 




POP 


A 


; Adjust stack 


1227 


048D 


8C 




3 




POP 


A 


; 


1228 


048E 


246B 


> 


3 




JP 


osMain ; Go test it again 


1229 


0490 








osMainSwitch : 






1230 


0490 


AA 




2 




LD 


A, 


[B+] ; Load 'A' with Flags, point to LSB 


1231 


0491 


AA 




2 




LD 


A, 


[B+] ; Load 'A' with LSB, point to MSB 


1232 


0492 


67 




3 




PUSH 


A 


; Save LSB 


1233 


0493 


AE 




1 




LD 


A, 


[B] ; Load 'A' with MSB 


1234 


0494 


67 




3 




PUSH 


A 


; Save MSB 


1235 


0495 








osMainExit : 






1236 


0495 


DF00 




3 




LD 


s, 


#0 ; Switch to user base RAM data segment 


1237 


0497 


8E 




5 




RET 






1238 










; 


.ENDSECT 


; Section ends here 


1239 


0498 










.END 


Start 


. sect_CODE_l 






3000 Abs 


Null ROM 






ADRSLT . 

-4 
ANYCOP . 








30CC Abs 


Byte 












3000 Abs 


Null 








-64 
















ATTI 
aStc 


J 








3002 Abs 
3000 Rel 


Null 
Byte SEG 






-4 
ire . 








-10" 


24" 


280 


299 313 648 650 658 660 678 680 690 697 964 1043 1049 




106? 


108£ 


1091 


1115 1129 1135 






aTaskRecs 








3045 Rel 


Byte SEG 








-158 




356 




473 


475 


801 


803 


BAUI 


) . . 








30BD Abs 


Byte 






-4 




992 


BUS^ 
bCOt 










3002 Abs 
3020 Rel 


Null 
Byte SEG 






-4 
llRxBuffer 






-138 




5 6'/ 




568 


1040 1041 


1083 1084 


bCOMlStat 


us 






3044 Rel 


Byte SEG 








-144 




551 




1116 


1126 






bCOMlTxBuffer 






3032 Rel 


Byte SEG 








-141 




553 




554 


1038 1039 


1123 1124 


bMaxTaskl 


ime 






300E Rel 


Byte SEG 








-114 




719 




720 


727 






bTask 








3009 Rel 


Byte SEG 








-11C 




376 




387 


461 


4 /7 


1163 1174 1215 1219 


bTaskNew 








300A Rel 


Byte SEG 
259 








-111 




248 




252 


274 


301 329 385 899 1156 


bTaskNext 








300B Rel 


Byte SEG 







29 



www.national.com 



-112 909 1167 1206 1214 
bTaskTime .... 000F Rel Byte SEG 

-115 456 484 721 726 
bUARTSettlngs . . 001D Rel Byte SEG 

-131 975 986 994 1028 

C 0006 Abs Null 

-4 622 623 624 

CHL1 0004 Abs Null 

-4 

CHLO 0003 Abs Null 

-4 1030 

CKO 0007 Abs Null 

-4 

CKX 0001 Abs Null 

-4 

CMP10E 0003 Abs Null 

-4 

CMP1EN 0001 Abs Null 

-4 

CMP1INN 0001 Abs Null 

-4 

CMP1INP 0002 Abs Null 

-4 

CMPIOUT 0003 Abs Null 

-4 

CMP1RD 0002 Abs Null 

-4 

CMP20E 0006 Abs Null 

-4 

CMP2EN 0004 Abs Null 

-4 

CMP 2 INN 00 4 Abs Null 

-4 

CMP2INP 005 Abs Null 

-4 

CMP20UT 0006 Abs Null 

-4 

CMP2RD 0005 Abs Null 

-4 

CMPSL 00B7 Abs Byte 

-4 

CNTRL 0EE Abs Byte 

-4 219 842 873 

COP820 0002 Abs Null 

-64 

COP820CJ 0005 Abs Null 

-64 

COP840 0003 Abs Null 

-64 

COP840CJ 0006 Abs Null 

-64 

COP8620 0007 Abs Null 

-64 

COP8640 0008 Abs Null 

-64 

COP8720 0009 Abs Null 

-64 

COP8780 000A Abs Null 

-64 

COP880 0004 Abs Null 

-64 

COP888BC 001B Abs Null 

-64 

COP888CF 0014 Abs Null 

-64 

COP888CG 0015 Abs Null 

-64 



www.national.com 30 



COP888CL . . 




0016 Abs 


Null 


-64 




COP888CS . . 




0017 Abs 


Null 


-64 




COP888EB . . 




001C Abs 


Null 


-64 




COP888EG . . 




0018 Abs 


Null 


-64 


4 


COP888EK . . 




0019 Abs 


Null 


-64 




COP888EW . . 




001D Abs 


Null 


-64 




COP888FH . . 




001E Abs 


Null 


-64 




COP888GD . . 




001F Abs 


Null 


-64 








COP888GG . . 




0020 Abs 


Null 


-64 




COP888GW . . 




0021 Abs 


Null 


-64 




COP888HG . . 




0022 Abs 


Null 


-64 




COP888KG . . 




0023 Abs 


Null 


-64 




C0P8ACC . . 




001A Abs 


Null 


-64 




C0P8SAA . . 




0024 Abs 


Null 


-64 




COP 8 SAB . . 




0025 Abs 


Null 


-64 




COP 8 SAC . . 




0026 Abs 


Null 


-64 




COP912C . . 




0001 Abs 


Null 


-64 




COP943 . . . 




000B Abs 


Null 


-64 




COPCHIP . . 




0018 Abs 
0002 Abs 


Null 
Null ROM 


-4 
ClearRAM . . 




-184 




ClearRAMLoopl 




0006 Abs 


Null ROM 


-187 


190 






ClearRAMLoop2 




0011 Abs 


Null ROM 


-195 


198 






cBaudP re scale 




0060 Abs 


Null 


-80 


L000 






cCOMlRxBufLen 




0010 Abs 


Null 


-82 


138 


567 


1083 


cCOMlTxBufLen 




0010 Abs 


Null 


-81 


141 


553 


1123 


cMaxTasks 




000A Abs 


Null 


-78 


158 


250 




cRecSize . . 




0003 Abs 


Null 


-77 


158 






cSystemSegment . . 


0001 Abs 


Null 


-76 








GTopOfRAM 




006F Abs 


Null 


-74 


182 


186 




cTopOfSysRAM 




007F Abs 


Null 


-75 


194 


202 


682 


DOE .... 




0007 Abs 


Null 


-4 
ENAD .... 




00CB Abs 


Byte 


-4 
ENI .... 




0001 Abs 
0004 Abs 


Null 
Null 


-4 
ENTI .... 









www.national.com 



ENU 

ENUI 

ENUR 

ERI 

ERR 

ETDX 

ETI 

FE . 


-4 




00BA Abs 

1022 
00BC Abs 

556 
00BB Abs 

1023 

0001 Abs 

0002 Abs 

0005 Abs 

0000 Abs 
1128 

0006 Abs 

0000 Abs 
334 

0004 Abs 

0006 Abs 

0007 Abs 

0006 Abs 

0010 Rel 
872 

0005 Abs 

0000 Abs 
773 

0001 Abs 
780 

0002 Abs 
787 

0007 Abs 
1116 

0003 Abs 
985 

0000 Abs 

0007 Abs 

626 
00E8 Abs 

454 

0002 Abs 

0000 Abs 
0000 Abs 

0003 Abs 
**** Rel 
00FF Abs 

0006 Abs 
0003 Abs 
0000 Abs 
000F Abs 


Byte 
1030 
Byte 
1024 
Byte 

Null 

Null 

Null 

Null 

Null 

Null 
380 

Null 

Null 

Null 

Null 

Byte 
876 

Null 

Null 
872 

Null 
876 

Null 
880 

Null 
1126 
Null 

Null 

Null 
627 

Byte 
504 

Null 

Null 
Null 
Null 
Null 
Null 
Null 
Null 
Null 
Null 


1034 
1032 

467 

SEG 

880 

591 

ROM Ext 
ROM 


1036 
1046 

904 
982 

722 


1128 

1222 
985 

725 


-4 


215 


-4 


217 


-4 


216 


-4 


1046 


-4 




-4 




-4 


556 


fActi-s 

fDatal 

fParit 

fParit 

fRxBuj 

fStati 

fStopE 

fTimei 

fTimei 

fTimei 

fTxBuj 

fUART 

GIE 

HC . 


-4 




-159 
Sits 
-132 

ySel . 
-134 

yType 
-135 


306 
1029 
1033 
1035 


-146 




-117 
Sits 
-133 

-1 . . 


769 

1031 


-121 

-2 . . 


771 


-120 

-3 . . 


7 :'8 


-119 


785 


-145 


551 


-118 


982 


-4 


1183 


ICNTRI 

IEDG 

INT 

INTR 

IPND 

Initic 

Interi 

LPEN 

MSEL 

mNone 

mTaskt 


-4 


625 


-4 


222 


-4 




-4 




-4 




-4 
ilize . 
162 
'upt 

-431 


595 
225 


-4 




-4 




-90 

n ailure 
-93 


479 



www.national.com 32 



mTimer . . . 




0001 


Abs 


Null 








-91 




mUART . . . 




0002 


Abs 


Null 








-92 




mUser . . . 




0010 


Abs 


Null 








-95 




osAddTask 




0048 


Abs 


Null 


ROM 


Pub 




166 


-244 














osAddTaskEnd 




0071 


Abs 


Null 


ROM 






275 


-278 














osAddTaskError . . 


0070 


Abs 


Null 


ROM 






251 


-276 














osBaudTable 




0376 


Abs 


Null 


ROM 






990 


998 


-1003 










osGetFirstTask . . 


00B3 


Abs 


Null 


ROM 






-371 


1160 














osGetNextTask . . 


00B7 


Abs 


Null 


ROM 






-375 


1164 


1216 


1224 








osGetNextTaskDone 


00CE 


Abs 


Null 


ROM 






395 


-398 














osGetNextTaskError 


00CD 


Abs 


Null 


ROM 






388 


-396 














osGetNextTaskHit . 


00CA 


Abs 


Null 


ROM 






381 


-392 














osGetNextTaskLoop 


00BA 


Abs 


Null 


ROM 






374 


-378 


390 










osGetTaskAddress . 


0A4 


Abs 


Null 


ROM 






261 


305 


333 


-351 




379 466 903 1176 1221 


osKillTimer 




02FE 


Abs 


Null 


ROM 


Pub 




177 


-861 














osKillTimerl 




030C 


Abs 


Null 


ROM 






864 


-871 














osKillTlmer2 




0313 


Abs 


Null 


ROM 






866 


-875 














osKillTimer3 




031A 


Abs 


Null 


ROM 






868 


-879 














osKillTimerExit 


0321 


Abs 


Null 


ROM 






870 


-884 














osKillTlmerOK . . 


0320 


Abs 


Null 


ROM 






874 


878 


-882 










osMain . . . 




046B 


Abs 


Null 


ROM 






1169 


1171 


-1201 


1209 


1211 1228 




osMainExit . 




0495 


Abs 


Null 


ROM 






1208 


1235 














osMainSwitch 




0490 


Abs 


Null 


ROM 






1223 


1229 














osPOP . . . 




0239 


Abs 


Null 


ROM 


Pub 




172 


-675 














osPOPError . 




0256 


Abs 


Null 


ROM 






683 


-693 














osPOPExlt 




0258 


Abs 


Null 


ROM 






692 


-696 














osPUSH . . . 




0219 


Abs 


Null 


ROM 


Pub 




171 


-644 














osSMTT_Exlt 




0276 


Abs 


Null 


ROM 






723 


-728 














osSMTT_Off . 




026D 


Abs 


Null 


ROM 






718 


-724 














osSetCommChannel . 


0339 


Abs 


Null 


ROM 


Pub 




173 


-961 














osSetMaxTaskTlme . 


025E 


Abs 


Null 


ROM 


Pub 




169 


-715 














osSetTimer . 




0279 


Abs 


Null 


ROM 


Pub 




176 


-749 














osSetTimerl 




0296 


Abs 


Null 


ROM 






-770 
















osSetTimer2 




029E 


Abs 


Null 


ROM 







33 www.national.com 



772 -777 










osSetTimer3 . . . 


02A6 Abs 


Null 


ROM 




779 -784 










osSetTimerAddress 


02C1 Abs 


Null 


ROM 




797 799 


-806 








osSetTimerExit . . 


02FB Abs 


Null 


ROM 




786 -848 










osSetTimerPeriod . 


02C7 Abs 


Null 


ROM 




805 -811 










os Set Timer St art 


02AE Abs 


Null 


ROM 




776 783 


-791 








osSetUART2 .... 


0396 Abs 


Null 


ROM 




1002 -1021 










OsSetUARTExlt . . 


03D6 Abs 


Null 


ROM 




1047 -1052 










OsSetUARTFall . . 


03D1 Abs 


Null 


ROM 




983 -1048 










osSignal 


0324 Abs 


Null 


ROM Pub 




170 -897 










osSignalEnd . . . 


0336 Abs 


Null 


ROM 




911 -914 










osSignalError . . 


0334 Abs 


Null 


ROM 




900 906 


-912 








osSignalOK .... 


0330 Abs 


Null 


ROM 




905 -908 










osStart 


043C Abs 


Null 


ROM Pub 




165 -1154 










osStartEnd .... 


0468 Abs 


Null 


ROM 




1184 -1187 










osStartError . . . 


0466 Abs 


Null 


ROM 




1158 1162 


1166 


-1185 






osStartTask . . . 


0078 Abs 


Null 


ROM Pub 




167 -295 










osStartTaskEnd . . 


008C Abs 


Null 


ROM 




308 -311 










osStart TaskError . 


008A Abs 


Null 


ROM 




302 -309 










osStopTask .... 


0093 Abs 


Null 


ROM Pub 




168 -327 










osStopTaskEnd . . 


00A1 Abs 


Null 


ROM 




336 -339 










osStopTaskError 


009F Abs 


Null 


ROM 




330 -337 










osUARTGetChar . . 


03D7 Abs 


Null 


ROM Pub 




174 -1066 










OSUARTRxChl . . . 


03E3 Abs 


Null 


ROM 




1073 -1075 










osUARTRxExit . . . 


0400 Abs 


Null 


ROM 




1089 -1094 










OSUARTRxFall . . . 


03FB Abs 


Null 


ROM 




1074 1078 


-1090 








osUARTSend .... 


0401 Abs 


Null 


ROM Pub 




175 -1106 










osUARTSendBusy . . 


0430 Abs 


Null 


ROM 




1117 -1133 










osUARTSendChl . . 


0409 Abs 


Null 


ROM 




1110 -1112 










osUARTSendError 


0438 Abs 


Null 


ROM 




1111 -1139 










osUARTSendExit . . 


043B Abs 


Null 


ROM 




1132 1138 


-1142 








osUnassigned . . . 


00CF Abs 


Null 


ROM 




205 206 


207 


208 


209 21C 


-410 


PE 

-4 
PEN 


0005 Abs 


Null 






0007 Abs 


Null 






-4 1034 











www.national.com 



34 



PORTCC 00D9 Abs Byte 

-4 

PORTCD 00D8 Abs Byte 

-4 

PORTCP OODA Abs Byte 

-4 

PORTD OODC Abs Byte 

-4 

PORTGC 00D5 Abs Byte 

-4 

PORTGD 00D4 Abs Byte 

-4 

PORTGP 00D6 Abs Byte 

-4 

PORTI 00D7 Abs Byte 

-4 

PORTLC 00D1 Abs Byte 

-4 1026 1027 

PORTLD 00D0 Abs Byte 

-4 

PORTLP 00D2 Abs Byte 

-4 

PSELO 0005 Abs Null 

-4 1036 

PSEL1 0006 Abs Null 

-4 

PSR 00BE Abs Byte 

-4 1001 

PSW 00EF Abs Byte 

-4 223 435 488 595 622 624 625 627 1183 

pCOMlRxRead . . . 0031 Rel Byte SEG 

-140 1041 1076 1085 

pCOMlRxWrite . . . 0030 Rel Byte SEG 

-139 562 569 1040 1077 

pCOMlTxRead . . . 0043 Rel Byte SEG 

-143 547 557 1039 1125 

pCOMlTxWrite . . . 0042 Rel Byte SEG 

-142 555 1038 1118 1127 

pStack 0008 Rel Byte SEG 

-108 202 651 657 681 685 686 

RBFL 0001 Abs Null 

-4 

RBIT9 0003 Abs Null 

-4 

RBUF 00B9 Abs Byte 

-4 214 564 

RCVG 0000 Abs Null 

-4 

RDX 0003 Abs Null 

-4 

Restore 0200 Abs Null ROM 

443 451 469 471 485 491 493 511 513 530 532 558 570 572 592 596 
-617 

S 00FF Abs Byte 

-4 185 193 212 245 246 281 297 298 314 328 340 437 455 480 490 

499 510 519 529 538 546 561 578 586 620 646 647 661 676 677 698 

716 729 750 849 862 885 898 915 962 963 1044 1050 1067 1068 1087 1092 

1113 1114 1130 1136 1155 1188 1205 1236 

SO 0000 Abs Null 

-4 

SI 0001 Abs Null 

-4 

SI 0006 Abs Null 

-4 

SIO 00E9 Abs Byte 

-4 

SIOR 00E9 Abs Byte 



35 www.national.com 



-4 






SK 

-4 
SO 

-4 
SSEL 

-4 
STP2 


0005 Abs 


Null 


0004 Abs 


Null 


0004 Abs 


Null 


0007 Abs 


Null 


-4 1032 






STP78 

-4 
ServiceExternal 


0006 Abs 


Null 


01CF Abs 


Null ROM 


-594 613 






ServiceMicrowire . 


01CA Abs 


Null ROM 


-590 609 






ServiceSoftware 


01C4 Abs 


Null ROM 


-582 615 






ServiceTimerTO . . 


0112 Abs 


Null ROM 


-453 612 






ServiceTimerTOExit 


013C Abs 


Null ROM 


459 -483 






ServiceTimerTl . . 


0143 Abs 


Null ROM 


-489 505 






ServiceTimerTl A 


0140 Abs 


Null ROM 


-487 611 






ServiceTimerTIB 


0154 Abs 


Null ROM 


-503 610 






ServiceTimerT2 . . 


015B Abs 


Null ROM 


-509 524 






ServiceTimerT2A 


0158 Abs 


Null ROM 


-507 605 






ServiceTimerT2B 


016C Abs 


Null ROM 


-522 604 






ServiceTimerT3 . . 


0173 Abs 


Null ROM 


-528 543 






ServiceTimerT3A 


0170 Abs 


Null ROM 


-526 603 






ServiceTimerT3B 


0184 Abs 


Null ROM 


-541 602 






ServiceUART_RX . . 


01A4 Abs 


Null ROM 


-560 607 






ServiceUART_TX . . 


0188 Abs 


Null ROM 


-545 606 






ServiceUnused . . 


010A Abs 


Null ROM 


-441 600 


608 


614 


ServiceWakeup . . 


010D Abs 


Null ROM 


-445 601 






Start 


0000 Abs 


Null ROM 


-182 463 


1239 




T0EN 


0004 Abs 


Null 


-4 722 


725 




T0PND 


0005 Abs 


Null 


-4 454 






T1A 

-4 
TIB 

-4 
T1C0 


0003 Abs 


Null 


0002 Abs 


Null 


0004 Abs 


Null 


-4 4 


842 


873 


T1C1 


0005 Abs 


Null 


-4 4 






T1C2 


0006 Abs 


Null 


-4 4 






T1C3 


0007 Abs 


Null 


-4 4 






T1ENB 


0000 Abs 


Null 


-4 







www.national.com 



36 



T1PNDB 0001 Abs Null 

-4 504 
T1RAHI 00ED Abs Byte 

-4 
T1RALO 00EC Abs Byte 

-4 
T1RBHI 00E7 Abs Byte 

-4 
T1RBLO 00E6 Abs Byte 

-4 833 
T2A 0004 Abs Null 

-4 
T2B 0005 Abs Null 

-4 
T2C1 0005 Abs Null 

-4 
T2C2 0006 Abs Null 

-4 
T2C3 0007 Abs Null 

-4 
T2CNTRL 00C6 Abs Byte 

-4 220 508 523 
T2CO 0004 Abs Null 

-4 844 877 
T2ENA 0002 Abs Null 

-4 
T2ENB 0000 Abs Null 

-4 
T2PNDA 0003 Abs Null 

-4 508 
T2PNDB 0001 Abs Null 

-4 523 
T2RAHI 0C3 Abs Byte 

-4 
T2RALO 00C2 Abs Byte 

-4 
T2RBHI 00C5 Abs Byte 

-4 
T2RBLO 00C4 Abs Byte 

-4 
T3A 0006 Abs Null 

-4 
T3B 0007 Abs Null 

-4 
T3C1 0005 Abs Null 

-4 
T3C2 0006 Abs Null 

-4 
T3C3 0007 Abs Null 

-4 
T3CNTRL 00B6 Abs Byte 

-4 221 527 542 
T3CO 0004 Abs Null 

-4 846 881 
T3ENA 0002 Abs Null 

-4 
T3ENB 0000 Abs Null 

-4 
T3PNDA 0003 Abs Null 

-4 527 
T3PNDB 0001 Abs Null 

-4 542 
T3RAHI 00B3 Abs Byte 

-4 
T3RALO 0B2 Abs Byte 

-4 
T3RBHI 0B5 Abs Byte 



37 www.national.com 



T3RBL0 

TBMT 

TBUF 

TCI 

TC2 

TC3 

TDX 

TMR1HI 

TMR1L0 

TMR2HI 

TMR2LO 

TMR3HI 

TMR3LO 

TPND 

TRUN 

WDOUT 

WDSVR 

WEN 

WKEDG 

WKEN 

WKPND 

WPND 

wAddre 

wlntCa 

wPerio 

wTimer 

wTimer 

wTimer 

wTimer 

wUARTR 

XBIT9 

XMTG 

XRCLK 


-4 




00B4 Abs Byte 

0000 Abs Null 
00B8 Abs Byte 
0007 Abs Null 
0006 Abs Null 
0005 Abs Null 

0002 Abs Null 
00EB Abs Byte 
00EA Abs Byte 
00C1 Abs Byte 
00C0 Abs Byte 
00B1 Abs Byte 
00B0 Abs Byte 
0005 Abs Null 

0004 Abs Null 

0001 Abs Null 
00C7 Abs Byte 

0002 Abs Null 
00C8 Abs Byte 
0C9 Abs Byte 

0CA Abs Byte 

0003 Abs Null 

000C Rel Word SEG 

270 272 752 754 763 
001B Rel Word SEG 

0011 Rel Word SEG 

762 821 823 
0015 Rel Word SEG 

495 497 774 
0017 Rel Word SEG 

517 781 788 
0019 Rel Word SEG 

536 
0013 Rel Word SEG 

758 794 795 
001E Rel Word SEG 

576 971 973 

0005 Abs Null 

0001 Abs Null 

0003 Abs Null 


I6j 
825 

807 


967 969 977 
827 835 

809 


979 

837 


-4 




-4 




-4 


550 


-4 




-4 




-4 




-4 




-4 




-4 


815 


-4 




-4 


817 


-4 




-4 


819 


-4 


488 


-4 




-4 




-4 




-4 




-4 




-4 




-4 


450 


-4 


591 


113 255 257 

llBack . . . 

129 

d 


123 760 
ICallBack 

125 204 
2CallBack 

126 515 
3CallBack 

127 534 
CallBack . . 

124 756 
xCallBack 
136 574 


-4 




-4 




-4 





XTCLK 0002 Abs Null 

-4 

**** Errors: 0, Warnings: 

Checksum: 0xF108 

Byte Count: 0x045D (1117) 

Input File: mtk88815.asm 

Output File: mtk88815.obj 

Memory Model: Large 

Chip: 888EG 



39 www.national.com 



o 
o 



o 
o 
o 

5— 

o 



00 
D. 

o 
o 

CD 



CD 

c 

1— 
CD 

c 

CO 

CO 



CO 

c 

re 

i_ 
O 



LIFE SUPPORT POLICY 

NATIONAL'S PRODUCTS ARE NOT AUTHORIZED FOR USE AS CRITICAL COMPONENTS IN LIFE SUPPORT 
DEVICES OR SYSTEMS WITHOUT THE EXPRESS WRITTEN APPROVAL OF THE PRESIDENT OF NATIONAL 
SEMICONDUCTOR CORPORATION. As used herein: 

1 . Life support devices or systems are devices or 2. A critical component is any component of a life support 



systems which, (a) are intended for surgical implant 
into the body, or (b) support or sustain life, and 
whose failure to perform when properly used in 
accordance with instructions for use provided in the 
labeling, can be reasonably expected to result in a 
significant injury to the user. 



device or system whose failure to perform can be 
reasonably expected to cause the failure of the life 
support device or system, or to affect its safety or 
effectiveness. 



O 
O 

o 



t>) 



National Semiconductor 
Corporation 

Americas 

Tel: 1-800-272-9959 
Fax: 1-800-737-7018 
Email: support@nsc.com 



www.national.com 



National Semiconductor 
Europe 

Fax: +49 (0) 1 80-530 85 86 
Email: europe.support@nsc.com 
Deutsch Tel: +49 (0) 1 80-530 85 85 
English Tel: +49 (0) 1 80-532 78 32 
Francais Tel: +49 (0) 1 80-532 93 58 
Italiano Tel: +49 (0) 1 80-534 16 80 



National Semiconductor 
Asia Pacific Customer 
Response Group 

Tel: 65-2544466 
Fax: 65-2504466 
Email: sea.support@nsc.com 



National Semiconductor 
Japan Ltd. 

Tel: 81-3-5639-7560 
Fax: 81-3-5639-7507 



National does not assume any responsibility for use of any circuitry described, no circuit patent licenses are implied and National reserves the right at any time without notice to change said circuitry and specifications.