~lb1[Table of contents]
~br[]	~xr[Overview]:   An overview of the tkisem program
~br[]	~xr[Using help]:  A bit about using help 
~br[]	~xr[About Tcl errors]:  They shouldn't happen, but...
~br[]	~xr[The windows]:  A summary of the windows provided by tkisem
~br[]	~xr[Main window]:  A description of the main window
~br[]	~xr[Register window]:  The second most important window
~br[]	~xr[Symbol window]:  Used to view user and supervisor symbols
~br[]	~xr[Breakpoint window]:  Used to set, clear, and view breakpoints
~br[]	~xr[Text display window]:  Used to view your program
~br[]	~xr[Data display window]:  Used to view the data memory
~br[]	~xr[Breakpoints]:  A quick summary of using and setting breakpoints
~br[]	~xr[The devices]:  A brief overview for each of the devices
~br[]	~xr[The rom code]:  A brief description of the tkisem rom code

~br[]ISEM - Instructional Sparc EMulator and tkisem
~br[]Copyright (C) 1993, 1994, 1995, 1996, 2001
~br[]	Department of Computer Science,
~br[]	The University of New Mexico

~lb1[Overview]

Tkisem is Tcl/Tk-based wrapper around the ISEM program.  ISEM is an
instructional SPARC emulator for version 8 of the SPARC definition.
ISEM and tkisem were developed by a collection of students and faculty
in the Computer Science Department at the University of New Mexico.
If you have any problems installing or using this program, send mail
to ~eg[isem@cs.unm.edu].

Tkisem provides a full emulation of the SPARC integer and floating
point units along with a small collection of devices.  The collection
of devices includes a console, an interval timer, a graphics
accelerator, and a UART.  For more information see ~xr[The devices].

When you start tkisem, it starts by loading and
running a supervisor program, called tkisem_rom.  This program
initializes the devices, installs software handlers for the devices,
and installs handlers for various traps, faults, and exceptions.
For more information see ~xr[The rom code].

~lb1[Using help]

At present, there is no serious, genuine, help for tkisem.  Instead,
there is this little file.  It'll have to do for now.  All the help
text is loaded into tkisem the first time any help is requested
and remains loaded thereafter for the duration of the program's
running.

~lb2[Cross references]
~br[]Wherever you see something like, say,
~xr[Overview], or ~xr[Table of contents], you can click left on it
and jump to the corresponding label in the help text.

~lb2[Help buttons]
~br[]In addition, the ~eg[Help] buttons on the various windows in tkisem
operate as if you had clicked on a particular help topic.

~lb2[Disclaimer]
~br[]Note: this help file is still under construction, so there may be
cross-references to things that haven't been written yet.  Clicking on
such an undefined cross-reference (say ~xr[Foo] (try it!))  leaves you
where you are in the help file and puts a "Can't find help label
'Foo'" message in the message line.

~lb1[About Tcl errors]

It is possible to do something that causes a window to pop up with the
label 'Error in Tcl Script'.  This window will contain an error
message, and provide two buttons, one saying 'OK' and one saying 'See
Stack Trace'.  In an ideal world, you shouldn't get this kind of
message.  It means is that tkisem isn't handling an error the way it
should.  Hopefully, you'll be able to figure out what happened and
find a way to continue.  If you find a systematic way to generate one
of these errors, send mail to ~eg[isem@cs.unm.edu] explaining how to
create the error.

~lb1[The windows]

Tkisem provides several windows for viewing the state of the emulated
processor and devices and for controlling the execution of
instructions.  In this section, we give brief overviews for these
windows and offer suggestions on which windows that you should become
familiar with.

The ~xr[Main window] is the window that you get when you start
tkisem.  This window lets you load and execute programs.  It also
includes the console input and output displays.  This is by far the
most important window in tkisem.  You should become familiar with this
window as soon as you start to use tkisem.

The ~xr[Register window] is the second most important window.  This
window displays the values of the registers defined in the integer
unit of the SPARC.  It also shows the next instruction to be executed
and provides a register edit region so you can change the values in
the registers.  You also need to become familiar with this window as
soon as you start to use tkisem.

The ~xr[Symbol window] displays the symbols (labels) defined by the
program loaded in user or supervisor memory.  This window provides
useful information, but is not needed very often.

The ~xr[Breakpoint window] can be used to set, clear, and view
breakpoints.  Like the symbol window, this window provides useful
information, but it is not needed very often.  Moreover, the
information displayed in this window is presented in a better format
in the text display window (unless you have set a lot of breakpoints
and want to review them).

The ~xr[Text display window] is used to view your program.  This
window identifies the instructions that are associated with
breakpoints and the instruction that is pointer to by the program
counter.  As soon as you have become familiar with the main window and
the register window, you should become familiar with this window.

The ~xr[Data display window] can be used to view the data memory for a
program.  This is useful if you want to see how the values stored in
memory are changed as a result of executing instructions.  This window
can be very useful when you are debugging and/or testing programs.

The ~xr[Timer window], the ~xr[UART window], and the ~xr[GX window]
display information related to the interval timer, UART, and gx
devices, respectively..  If you write a program that uses this device,
you will want to become familiar with these windows.

~lb1[Main window]

The main window is the window you get when you start tkisem.  

Our discussion of the main window is broken into two parts:
~br[]	~xr[Main window structure] -- discussing the structure of the
window, and
~br[]	~xr[Main window activities] -- discussing the activities that
can be performed using the main window

~lb2[Main window structure]
~br[]From top to bottom, in sections, the main window contains:
~br[]	a ~xr[Menu bar],
~br[]	a ~xr[Processor state],
~br[]	a ~xr[Load/run section],
~br[]	a ~xr[Message line], 
~br[]	a ~xr[Console output] window, and
~br[]	a ~xr[Console input] window.

~lb3[Menu bar] The menu bar has eight pull down menus: ~eg[File],
~eg[Registers], ~eg[Symbols], ~eg[Breakpoints], ~eg[Memory],
~eg[Devices], ~eg[Options], and ~eg[Help].

~lb[File menu]. Currently, the file menu can only be used to ~eg[Quit] the
program.

~lb[Registers menu].  The register menu is be used to ~eg[Display] the
~xr[Register window].

~lb[Symbols menu].  The symbols menu brings up the user and/or super
~xr[Symbol window].

~lb[Breakpoints menu] The breakpoints menu brings up the user and/or
supervisor ~xr[Breakpoint window].

~lb[Memory menu].  The memory menu brings up the user and/or
supervisor ~xr[Data display window] and/or the
~xr[Text display window].  The text display window is the place to see
your code while it's running!

~lb[Devices menu].  The devices menu brings up the ~xr[Timer window],
the ~xr[UART window], or the ~xr[GX window].

~lb[Options menu].  Currently, the options menu lets you select how
the register names are displayed.  You can have register names
displayed using standard notation (%r), or register window notation
(%g, %o, %l, and %i).

~lb[Help menu].  The help menu brings up this help window.


~lb3[Processor state] The processor state portion of the main window
summarizes the current state of the emulated processor.  This part of
the display is broken into five regions.  From left to right they are:
the processor state, the processor mode, the step and display toggles,
the instruction and memory reference counts, and the file names.

The processor state is indicated by a box labeled ~eg[Proc State].
This box should normally say ~eg[execute] (with a light green
background on color displays).  If you manage to halt the (emulated)
processor, ~eg[Proc State] will say ~eg[error] with a red background.

The processor mode is indicated by a box labeled ~eg[Proc Mode].  This
box is ~eg[super] or ~eg[user] depending on whether the processor is
currently in supervisor mode or user mode.  It displays the same
information as the ~eg[S] bit in the ~eg[PSR] which can be seen in the
~xr[Register window].

The step and display toggles let you control single stepping and the
display updates.  In single stepping, tkisem will stop after each
instruction is executed so you can examine the state of the processor,
registers, or memory.  Each processor mode (supervisor and user) has a
toggle button labeled ~eg[Step].  If the ~eg[Step] toggle is set for
one of the modes, tkisem will single step instructions when the
processor is in this mode.

Display updates take a moderately long time.  As such, tkisem lets you
control if display is updated.  Like single stepping, display updating
is associated with the processor mode.  Display updating is controlled
by the ~eg[Display] buttons, one for each mode.  

If you set single stepping, you will automatically get display
updating for that mode.  You can also set display updating without
setting single stepping.  This lets you "watch" the program as it
runs.  At startup, ~eg[User Step] and ~eg[User Display] are set, since
most of the time you will be programming (and debugging) programs
written for user mode.  If you write supervisor code (see 
~xr[The rom code]), you may want to control single stepping and
display updating for supervisor mode.

The instruction and memory reference counts are next to the step and
display toggles.  This region consists of four counters, a pair of
counters for each of the processor modes.  The first (leftmost)
counter tracks the number instructions that have been executed in this
mode.  The second counts the number of memory references in this mode.
All four counters are cleared whenever you load a file into the user
or supervisor memory.

Finally, the file name section consists of two boxes labeled
~eg[User File] and ~eg[Super File].  These boxes give the names of the
executable files last loaded into the user memory and supervisor
memory of tkisem.

~lb3[Load/run section] The next section of the main window contains a
pair of radio buttons, ~eg[User] and ~eg[Super], two command buttons
~eg[Load] and ~eg[Run], a text entry area, and ~eg[Display frequency]
slider.

The ~eg[User] and ~eg[Super] radio buttons select whether the
~eg[Load] button loads into user memory or supervisor memory.  When
tkisem is first run, a special file ~eg[tkisem_rom] is loaded
into supervisor memory.  After initialization is complete, the load
mode is switched to ~eg[User] to be ready to load your program.

The ~eg[Display frequency] slider determines how often the information
in the various windows is updated while the emulator is running.  It
is initialized to 1, meaning that the windows are updated after every
instruction is executed.  Setting it to a higher value reduces the
frequency of display updates, but allows the emulation to run more
quickly.

~lb3[Message line]  The message line is used by tkisem to display
status messages.  As an example, tkisem displays breakpoint messages
in the message line.

~lb3[Console output]  The console output region displays text
generated by running code.  After the emulator is first started, and
the supervisor initialization code has run, the message 
~eg[Default trap handlers installed] is sent to the console output.

~lb3[Console input]  The console input region displays characters
that can be read by the running program.  You should treat the console
input as a sequential, append-only character device.  Using the
cursor, you can insert characters anywhere you like.  However, if you
insert characters anywhere other than the end of text, things may not
work as expected.  Characters typed in the console input region are
not passed to the running program until you type a newline (carriage
return).

~lb2[Main window activities]
~br[]There are two primary activities that you will perform using the
main window: loading a program and running a program after it's been
loaded. 

~lb3[Loading a program].  To load a user program, take the following
steps:
~br[]	1) Make certain ~eg[User] is checked off;
~br[]	2) Enter the name of the file to load.  (If you didn't use a
~eg[-o] switch when you linked your program with ~eg[isem_ld], the 
name of the program will be ~eg[a.out].)
~br[]	3) Click the ~eg[Load] button.

~lb3[Running a program].  Once you've loaded a program into user or
supervisor memory, you can start it running by clicking the ~eg[Run]
button.  The exact behavior of the emulator when you click the
~eg[Run] button depends on the settings of the user and supervisor
step and display check boxes in the ~xr[Processor state].  

If you set ~eg[Step] toggle, pressing the ~eg[Run] button will execute
a single instruction.  Otherwise, pressing the ~eg[Run] button will
execute many instructions.  While the emulator is executing
instructions, the ~eg[Run] button changes into a ~eg[Stop] button and
can be used to stop execution.  (See also ~xr[Breakpoints]).

~lb1[Register window]

The register window is where all the internal processor state, as
well as the next instruction to be executed, is displayed.  You
probably want to have the register window up visible most of the time.
There will be more help here one of these days maybe.

~lb1[Symbol window]

There are two symbol windows, one for user symbols and another for
supervisor symbols.  The display portion of the symbol window consists
of two columns.  The first column show the name of the symbol, the
second shows the value and region (abs, bss, data, or text) associated
with the symbol.

By default, the symbols are sorted by their names.  By clicking on the
~eg[Value] radio button, you can display the symbols sorted by their
values within each region.  (If two or more symbols are associated
with the same value, only one of the symbols will be displayed.)  To
return to the display where symbols are sorted by name, click on the
~eg[Name] radio button.

~lb1[Breakpoint window]

There are two breakpoint windows, one for user breakpoints and another
for supervisor breakpoints.  The breakpoint windows display
breakpoints in two columns.  The first column shows the label of the
instruction associated with the breakpoint (if the instruction has a
label).  The second column shows the address of the instruction
associated with the breakpoint.

The ~eg[Clear All] button clears all of the breakpoints.  The
~eg[Delete] and ~eg[Add] buttons can be used to delete or add
individual breakpoints.  To add or delete a breakpoint, type the
address or label of the instruction in the entry box to the right of
the ~eg[Add] button and click on the ~eg[Add] or ~eg[Delete] button.

Note: the text display window provides a better interface for adding
and deleting individual breakpoints (see ~xr[Text display window]).

~lb1[Text display window]

The text display windows (one for user memory and another for
supervisor memory) display the instructions in a program.  The window
has a display region and an update region.

The update region is at the bottom of the window and consists of a
button and two entry boxes.  The button is labeled ~eg[Update], the
entry boxes are labeled ~eg[Start] and ~eg[End].  Tkisem initializes
these with its best guess of the program start and program end.  You
can change these values by typing instruction addresses or labels in
these entry boxes.  Clicking the ~eg[Update] button updates the
instructions shown in the text display window.

Displaying the text takes a bit of time, so the instructions for your
program are not shown when you first pop up the text display window.
To see the instructions, click on the ~eg[Update] button.

The display part of the window uses five columns to show  the
instructions of a program.

The first column indicates if the instruction is identified as a
breakpoint (see ~xr[Breakpoints]).  This column also indicates the
next instruction to be executed (i.e., the value of the PC).  If an
instruction is identified as a breakpoint, the symbol 'B' appears in
the first column.  If the instruction is the next instruction to be
executed, the symbol '>' is displayed in the first column.

The second column displays the address of the instruction.  If you
double click on an address, tkisem toggles whether the instruction is
identified as a breakpoint.

The third, forth, and fifth columns display the label, operation, and
operands for the instruction.

The ~eg[Update] button can be used to update the range of instructions
displayed in the text display window.  Tkisem tries to guess where
your program starts and ends.  Usually, tkisem is pretty good about
guessing; however, it is possible that tkisem will not guess
correctly.  To change the range of instructions displayed, you can set
the ~eg[Start] and ~eg[End] entry boxes and click on the ~eg[Update]
button.

~lb1[Data display window]

The data display windows are similar to the text display windows:
there are two data display windows, one for user memory and one for
supervisor memory; data display windows have a display region and an
update region; and the data values are not initially displayed.

The update region of the data display region operates just like the
update region of the text display window.  You can enter addresses or
labels in the ~eg[Start] and ~eg[End] entry boxes and click on the
~eg[Update] button to update the region of memory displayed.

Words of data memory are displayed in three columns.  The first column
shows the address or label of the memory work.  The second shows the
value of the memory word using hexadecimal notation.  The third shows
the value of the memory word in ASCII.

~lb1[Breakpoints]

For short programs, say 20-30 instructions, single stepping through
the instructions in the program is a good way to see how the program
is working and to uncover errors in the logic.  However, when your
programs become a bit larger, say 100 instructions, this process
becomes tedious and error prone -- especially when you know the first
50 instructions are correct.  

While you are debugging a larger program, you may find it useful to
set breakpoints in the code.  When tkisem is not in single stepping
mode (see ~xr[Processor state]), it executes instructions until the
program halts (using ~eg[ta 0]) or it is about to execute an
instruction that has been identified as a breakpoint.

You can set, clear, or examine breakpoints using the 
~xr[Breakpoint window] or the ~xr[Text display window].  As a general
rule, the breakpoint window provides a useful summary of the
breakpoints you have set, but the text display window presents a much
better interface for setting and clearing breakpoints and watching as
instructions are executed. 

Note: Pressing the ~eg[Run] button will always execute at least one
instruction.  You don't have to clear the breakpoint to execute an
instruction that has been identified as a breakpoint.  If you are at
the breakpoint instruction, pressing the ~eg[Run] button will execute
the breakpoint instruction.

~lb1[The devices]

Currently, tkisem supports five devices: 
~br[]	~xr[The GX device],
~br[]	~xr[The console],
~br[]	~xr[The interval timer],
~br[]	~xr[The UART], and
~br[]	~xr[The halt device].

Tkisem was designed to make it relatively easy to new devices.  If you
are interested in adding a new device, drop us a note, we'll be happy
to offer any help we can.

~lb2[Device Addresses]
In many cases, the only piece of information you need is a table of
the addresses used by the devices.  Here is the table.
~br[]	Device		Addresses
~br[]	GX		0x100000--0x10ffff
~br[]	Console		0x110000--0x11ffff
~br[]	Halt		0x120000--0x12ffff
~br[]	Timer		0x130000--0x13ffff
~br[]	UART		0x140000--0x14ffff

~lb2[The GX device]
~br[]The GX device is a simple graphics accelerator.  Reading from any
memory location between 0x100000 and 0x10ffff returns the status of
the GX device: 0 means that the device has not been initialized, 1
means that the device has been initialized and is ready.  

Memory addresses 0x100008 through 0x1000fc are used for arguments to
the gx commands.  Memory location 0x100004 is used for the gx command,
writing a value to this location issues the command (any parameters
needed for the command are taken from memory locations 0x100008
through 0x1000fc).

The gx commands are:
~br[]	command name	command number	parameters
~br[]	GX_OPEN		0	<none>
~br[]	GX_CLOSE		1	<none>
~br[]	GX_COLOR		2	color
~br[]	GX_OP			3	operation
~br[]	GX_LINE			4	x1, y1, x2, y2
~br[]	GX_FILL			5	x, y, w, h
~br[]	GX_BLIT			6	x1, y1, w, h, x2, y2

The ~lb[GX window] shows the graphic display.

~lb2[The console]
~br[]The console provides a single basic, character I/O capabilities.
Writing a character to the console data register causes the character
to be appended to the ~eg[Console output].  Reading a character from
the console data register gets the next character from the console. If
there are no characters available, reading the console data register
returns the value 0xffffffff.

The console data register is mapped into location 0x110000 in both the
user and supervisor address spaces.

~lb2[The halt device]
~br[]For the most part, tkisem tries to present a full emulation of a SPARC
processor and hardware devices.  To this end, all traps, exceptions,
faults, and interrupts are handled by SPARC code.  

The halt device is one of the few concessions tkisem makes to the fact
that it is really a program and not a processor.  When a program reads
from or writes to the halt device, tkisem stops executing
instructions.  In effect, this halts the execution of the program.

The halt device is mapped into location 0x120000 in both the user and
supervisor address spaces.

~lb2[The interval timer]
~br[]The interval timer provides a single register in the user and
supervisor address spaces.  This register is called the timer period
register.  The timer period register establishes the period, measured
in instructions executed, between interrupts.

In addition to the timer period register, the interval timer maintains
an internal count register.  When you write a value to the timer
period register, the count register is initialized to zero.  If the
period is nonzero, the count register is incremented after each
instruction execution.  When the count value is the same as the
period, the count is reset to zero and the timer generates a level 1
interrupt.  The interrupt can be cleared by reading or writing the
timer period register.

The ~lb[Timer window] displays the timer period register, the internal
count register used by the interval timer, and the interrupt status
for the interval timer (0 means no interrupt pending).  In addition to
the displayed values, the ~eg[Set period] button can be used to set
the timer period register.

The timer period register is mapped into location 0x130000 in both the
user and supervisor address spaces.

~lb2[The UART]
~br[]The UART is mapped into addresses 0x140000 and 0x140004 in both
the user and supervisor address spaces.  Reading from memory location
0x140000 returns the status register, clears the ~eg[overrun error],
and clears any pending interrupts.  Writing to memory location
0x140000 updates the control register.  Reading from memory location
0x140004 returns the current contents of the receive register.
Writing to memory location 0x140004 puts the least significant byte of
the value in the transmit register.  The following table summarizes
the UART registers.
~br[]	address		operation		register
~br[]	0X140000	load		status
~br[]	0X140000	store		control
~br[]	0X140004	load		receive
~br[]	0X140004	store		transmit
	
The following table summarizes the bits in the status register:
~br[]	bit	meaning
~br[]	0	transmit register empty
~br[]	1	receive register full
~br[]	2	overrun error
~br[]	3	framing error (always 0)
~br[]	4	parity error (always 0)
~br[]	5	data set ready (always 1)
~br[]	6	unused
~br[]	7	unused
~br[]Only the least significant three bits (transmit register empty,
receive register full, and overrun error) are updated to reflect the
current state of the UART.

The least significant bit of the control register controls whether
transmit interrupts are enabled (a one enables interrupts).  The next
bit controls whether receiver interrupts are enabled.  The remaining
six bits control the transmit and receive rates.

The ~lb[UART window] displays the status, control, transmit, and
receive registers.  In addition to the registers that can be accessed
under program control, the UART window displays several internal
registers and provides controls for the external source (i.e.,
characters that will be received by the UART).

The ~eg[Sending] register holds the value being transmitted and the
~eg[TX count] counts the time (in instructions) until the value is
sent.  When the ~eg[TX count] decrements to zero, the UART copies the
value in the transmit register into the sending register.  If there
was a value in the transmit register, THE UART sets the
~eg[transmit register empty] bit in the UART status register.

The ~eg[Receiving] register holds the value being received and the
~eg[RX count] register counts the time until the value is received.
When the ~eg[RX count] decrements to zero, the UART copies the value
in the receiving register into the receive register and sets the
~eg[receive register full] bit in the UART status register.  If there
was a value in the receive register, the UART also set the
~eg[overrun error] bit in the UART status register.

The ~eg[RX/TX Scale] register is used to scale the transmit/receive
rate in the control register.  When a value is being transmitted or
received the value in the ~eg[TX count] or ~eg[RX count] is calculated
by multiplying the ~eg[TX/RX Scale] by the most significant six bits
in the UART control register.  The ~eg[TX/RX Scale] value can be
changed by entering a new value in the UART window.

The source of characters to be received by the UART can be from the
keyboard, a file, or a "random" file.  The radio buttons in the upper
right of the UART window can be used to set the source of characters
sent to the UART.  Initially, the source is ~eg[disabled].  When the
~eg[keyboard] or ~eg[file] button is selected, the source begins
transmitting characters to the UART.  As soon as the source runs out
of characters, the source is again ~eg[disabled].

Each line in a "random" file consists of a number, followed by '.',
followed by a character (or nothing for a newline).  The number
specifies the time (in instructions) before the character is sent to
the UART.  When the source is a standard file or the keyboard, the
~eg[Source Rate] controls the time between characters sent to the
UART.  The actual source rate is the maximum of the ~eg[Source Rate]
and the receive time computed using the ~eg[TX/RX Scale].  The
~eg[Source count] counts the time (in instructions) until the next
character is sent from the source to the UART.

The UART window also has two text windows.  The upper text window
displays the characters that have been transmitted by the UART.  The
lower text window displays the characters being sent to the UART.

Note, if you choose the keyboard as the source for UART characters,
you should type a few characters into the lower text window *before*
pressing the ~eg[keyboard] radio button.

~lb1[The rom code]

The rom code provides basic system support for user level programs.
This includes support for traps that support program termination and
console I/O, fault handling, exception handling, and interrupt
handling for the devices.

~lb2[Traps]
~br[]The following table summarizes the traps supported by the default
rom code
~br[]	Trap #	Name	Operation
~br[]	0	exit	terminate program
~br[]	1	putc	print the character in %r8 on the console
~br[]	2	getc	get a character from the console, return the character
~br[]			in %r8 -- wait until a character is available
~br[]	3	getc_nb	get a character from the console, return the character
~br[]			in %r8 -- return -1 if no character is available
~br[]	4	putx	print the value in %r8 using hexadecimal notation
~br[]	5	getx	read a hexadecimal number from the console and
~br[]			return the value in %r8
~br[]	6	puts	print the NULL terminated string, whose address is in
~br[]			%r8, on the console

~lb2[Faults]
~br[]The tkisem rom code provides fault handlers for the register
window overflow and underflow faults that may occur when a program
issues ~eg[save] and ~eg[restore] instructions.  Because these faults
are handled by the rom code, tkisem should be able to run just about
any SPARC executable.  Because the rom code is written in SPARC
assembly language, you can see an example of how these faults might be
handled.

~lb2[Exceptions] 
~br[]The tkisem rom code also provides basic support for the
exceptions that may occur during the execution of a program, e.g.,
memory addressing exceptions.  This code prints a message and
terminates the program.  The message includes an indication of the
exception along with the values for the ~eg[PC] and ~eg[nPC].

~lb2[Interrupts]
~br[]The tkisem rom code provides default interrupt handlers for the
devices.  These handlers simply discard the interrupt and, when
possible, disable further interrupts.  These handlers can be used as
starting points for writing more sophisticated interrupt handlers.

~lb2[Extending and modifying the rom code]
~br[]If you want to experiment with the supervisor program (to modify or
extend the existing handlers), you can copy the file ~eg[tkisem_rom.s]
from the directory ~var[libdir].  This code can be assembled using
the ~eg[isem_as] assembler and ~eg[isem_ld] linker used to assemble
and link user programs.  (See the comments in the tkisem_rom.s file
for more information.)
