\documentclass[12pt]{article}
\evensidemargin 0.50in \textwidth 5.75in

\topmargin 0in \headsep .325in \textheight 8.25in

\def\myfig#1#2#3{
 \begin{figure}[ht]
 \special{isoscale #1, \the\hsize 3.0 in}
 \vspace{3.0in}
  \caption{#2}
\label{#3}
 \end{figure}
}

\begin{document}
\title{Interrupt Processing}
\date{}
\author{N. Narasimhamurthi}
\maketitle
\section{Objective}
To become familiar with interrupt processing.
\section{Background}
In an earlier lab, you had to generate a 30.52/2 Hz  square wave
signal on PA4 pin. The code for generating the square wave is
given below for your reference. Make sure that you run the program
and verify that you get the square wave before proceeding further.
Also, to understand this lab, you must connect the PA4 pin to a
oscilloscope and see the square waves.

\begin{verbatim}
 ; Various defines go here ...
       ORG $3000 don't forget the $

ME     FCC /Your name/
       FCB 10
       FCC /ECE 372/
       FCB 10
       FCC /Date the program was last changed/
       FCB 10, 10, 4

       ORG $2000 DONT FORGET THE $
       LDX #ME
       JSR OUTSTRG ; MAKE SURE YOU HAVE EQU FOR OUTSTRG

LOOP1

; CLEAR THE FLAG. NO HARM IS DONE IF IT IS ALREADY CLEARED
       LDAA #%10000000
       STAA TFLAG2

;WAIT FOR THE FLAG TO BE SET

LOOP2
      LDAA TFLAG2
      ANDA #%10000000
      BEQ LOOP2

;NOW TOGGLE PA4
      LDAA #%00010000
      EORA PORTA
      STAA PORTA

;DO IT ALL OVER AGAIN
      BRA LOOP1
\end{verbatim}
\section{Interrupts}
If you study the above code, most of the time is spent waiting for
the clock to rollover (the loop at {\tt LOOP2}). This is a lot
like sitting in front of the clock and watching and waiting for
the clock to rollover. Or, for that matter, sitting in front of a
stove and watching and waiting for  kettle to boil, or watching
food being cooked in a microwave oven. A better solution would be
to go about ones job and arrange matters so that one is told when
an event occurs (the clock chimes, the kettle whistles, the
microwave oven sounds an alarm etc.). When we are told that the
event has occurred, we then take appropriate action (turn off the
stove, take food out of the oven etc.). Most of the HC11
interrupts work the same way. In essence this is what happens:
\begin{enumerate}
\item
When an event occurs, a flag is set. For example, the clock
rollover sets the {\tt TOF} flag.
\item
Associated with the flag is a masking bit. The name of the bit is
the same as the flag except the final {\tt F} is replaced by {\tt
I}. The mask associated with {\tt TOF} is {\tt TOI}.
\begin{enumerate}
\item
If the mask is zero, then nothing much happens. The event is
ignored by the interrupt processing structure.
\item
However, if the mask is set, then request for service is
generated.
\begin{enumerate}
\item
The {\bf \tt I} bit in the CCR is a master disable switch. If this
is set (by using the command {\tt SEI}), then the request for
service does not interrupt the computer and is hence ignored.
\item
However if {\tt I} bit is cleared (by using the command {\tt
CLI}), then the CPU is interrupted.
\end{enumerate}
Note: It is extremely important that you have an {\tt SEI} before
any code that can turn on an interrupt and and {\tt CLI} after all
relevant and required initialization is performed.
\end{enumerate}
\item
When a CPU is interrupted, it stops its current task and starts
the service.
\item
When performing the service, you get a completely new set of
registers. So you can not assume that the registers will have any
specific value. Also, when the service terminates, the new set of
registers is destroyed. So you can not assume that the rest of the
code can see what you stored in the register as part of the
service. In fact, the interrupted task would be oblivious to the
fact that a service was provided. The only way it can find out is
if the service modifies some memory location.
\item
The location of the service that is associated with a particular
interrupt is defined by the hardware manufacturer, and is called
the {\em jump vector}. This would be in read only memory and can
not be chanted. The operating system, BUFFALO, sets the start of
the service to a known location and sets aside three bytes at that
location. Your service will start with {\tt JMP} instruction to
the actual code for the service. Your service {\bf must end with
the {\tt RTI} instruction}.

The address of services to three important interrupts is given in
the following table:
\begin{center}
\begin{tabular}{|l|l|}
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
 \hline {\bf Interrupt} & {\bf Service location} \\ \hline
  TOF & \$00D0 \\
  RTIF & \$00EB \\
  OC2F & \$00DC \\ \hline
\end{tabular}
\end{center}
\item
Your service code should, as part of the service, {\em turn off}
the flag that generated the interrupt. If not, the request for
service will still be active and will generate a new service
request as soon as the current service end!
\end{enumerate}
Here is a short checklist for what you should do:
\begin{enumerate}
\item
In your main routine, enable an interrupt by turning on the
associated mask.
\item
Write the service routine. As part of the service make sure you
turn off the flag that generated the interrupt.
\item
Let HC11 know where to find the service. In other words, Link the
service to the request.
\end{enumerate}

With this background, we will modify the square wave generator to
use the interrupt. Here is the complete code with some of the
standard equates left out (you need to have them at the top of the
file!). You should compare this code with the earlier one. In this
code, the main program does nothing really interesting. It just
prints a series of {\tt Z}'s to the screen
\begin{verbatim}
 ; Various defines go here ...
       ORG $3000 don't forget the $

ME     FCC /Your name/
       FCB 10
       FCC /ECE 372/
       FCB 10
       FCC /Date the program was last changed/
       FCB 10, 10, 4

       ORG $2000 DONT FORGET THE $
       LDX #ME
       JSR OUTSTRG ; MAKE SURE YOU HAVE EQU FOR OUTSTRG

LOOP1

; Enable TOF interrupt by setting TOI (bit#7 in TMSK2)
       SEI
       LDAA #%10000000
       STAA TMSK2
       CLI

; Now go about your business of printing Z's
       LDAA #'Z'
LOOP   JSR OUTA
       BRA LOOP

; End of main program

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; INTERRUPT SERVICE

SERVICE

; TOGGLE PA4
      LDAA #%00010000
      EORA PORTA
      STAA PORTA

; TURN OFF THE FLAG!
      LDAA #%10000000
      STAA TFLG2

; END WITH AN RTI
      RTI

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Connect the service to the interrupt ;

     ORG $00D0 ; $00D0 WHERE THE SERVICE STARTS
     JMP SERVICE ; JUMP TO WHERE THE SERVICE CODE ACTUALLY IS
\end{verbatim}

How does this code differ from the previous one? We don't wait for
the clock to rollover. Instead, the main program goes about its
task (in this case not a very interesting one!). Note that
although the service routine uses the  {\bf A} register, this does
not affect the value the main routine has stored in the {\bf A}
register (the character {\tt Z}).
\section{The Real time interrupt}
The real time interrupt, {\tt RTI} (not to be confused with the
{\tt RTI} instruction) acts exactly like the timer overflow
interrupt, except you can control the time between interrupts
using the last two bits (0 and 1) of {\tt PACTL} at location {\tt
\$1026}. If the both the bits are set, the time between the
interrupts is is 32.768 ms, i.e. same as timer overflow. However,
you can decrease the time between the interrupts (increase the
rate) by changing the last two bits as {\tt PACTL} as shown below:
\begin{center}
\begin{tabular}{|l|l|}
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
\hline  {\bf Last two bits of PACTL} &{\bf  Time between interrupts} \\
\hline
  00 & 4.096 ms (244.1 Hz)\\
  01 & 8.192 ms (122 Hz)\\
  10 & 16.384 ms (61 Hz)\\
  11 & 32.768 ms (30.5 Hz) \\ \hline
 \end{tabular}
\end{center}
Thus if we want to use the {\tt RTI} interrupt, we have to change
the above code as shown below. Note the crucial differences:
\begin{verbatim}
 ; Various defines go here ...
       ORG $3000 don't forget the $

ME     FCC /Your name/
       FCB 10
       FCC /ECE 372/
       FCB 10
       FCC /Date the program was last changed/
       FCB 10, 10, 4

       ORG $2000 DONT FORGET THE $
       LDX #ME
       JSR OUTSTRG ; MAKE SURE YOU HAVE EQU FOR OUTSTRG

LOOP1

; Enable RTIF interrupt by setting RTII (bit#6 in TMSK2)
       SEI
       LDAA #%01000000 <= This is different
       STAA TMSK2

       LDAA #%00000011 <= THIS IS NEW
       STAA PACTL

       CLI

; Now go about your business of printing Z's
       LDAA #'Z'
LOOP   JSR OUTA
       BRA LOOP

; End of main program

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; INTERRUPT SERVICE

SERVICE

; TOGGLE PA4
      LDAA #%00010000
      EORA PORTA
      STAA PORTA

; TURN OFF THE FLAG!
      LDAA #%01000000 <= This is different
      STAA TFLG2

; END WITH AN RTI
      RTI

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Connect the service to the interrupt ;

     ORG $00EB ; $00EB0 WHERE THE SERVICE STARTS
     JMP SERVICE ; JUMP TO WHERE THE SERVICE CODE ACTUALLY IS
\end{verbatim}
\subsection{Exercises}
\begin{enumerate}
  \item Modify the above program to generate a 30.5 Hz square wave
  by setting the RTI interrupt rate to 61 Hz.
  \item After you made the modification, toggle PA4 every 61
  interrupts (Hint, set up a counter and initialize it to 61 in
  the main program. In the interrupt service, decrement the
  counter. When the counter reaches zero, toggle the pin and reset
  the counter back to 61). Verify that the signal you generate is
  a 0.5 Hz square wave
  \item Create a simple clock. In addition to toggling the pin,
  increment an 8-bit variable called {\tt TIME}. In the main loop,
  instead of printing {\tt Z}'s, print the variable using {\tt
  OUT1BSP}.
\end{enumerate}
\section{The output compare interrupt}
The HC11 has 5 {\tt OCx} interrupts. These are like alarm clocks.
You set a desired 'alarm' time and when the clock matches the
alarm setting, the {\tt OCxF} flag will be turned on and could
then generate a request for service. Note that if you do not
change the alarm setting, you will still get an interrupt every
32.768 ms. However, having the alarm gives you greater
flexibility. First a code that does not change the alarm setting
and hence generates 30.5 Hz square wave.
\begin{verbatim}
 ; Various defines go here ...
       ORG $3000 don't forget the $

ME     FCC /Your name/
       FCB 10
       FCC /ECE 372/
       FCB 10
       FCC /Date the program was last changed/
       FCB 10, 10, 4

       ORG $2000 DONT FORGET THE $
       LDX #ME
       JSR OUTSTRG ; MAKE SURE YOU HAVE EQU FOR OUTSTRG

LOOP1

; Enable OC2 interrupt by setting OC2I (bit#6 in TMSK1)
       SEI
       LDAA #%01000000 <= This is different
       STAA TMSK1

      CLI

; Now go about your business of printing Z's
       LDAA #'Z'
LOOP   JSR OUTA
       BRA LOOP

; End of main program

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; INTERRUPT SERVICE

SERVICE

; TOGGLE PA4
      LDAA #%00010000
      EORA PORTA
      STAA PORTA

; TURN OFF THE FLAG!
      LDAA #%01000000 <= This is different
      STAA TFLG1

; END WITH AN RTI
      RTI

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Connect the service to the interrupt ;

     ORG $00DC ; $00DC WHERE THE SERVICE STARTS
     JMP SERVICE ; JUMP TO WHERE THE SERVICE CODE ACTUALLY IS
\end{verbatim}
Verify that the above code also generates a 30.5/2 Hz square wave.
Now we can reset the alarm to get a different frequency. For
example, if we modify the service routine as follows, we will get
an interrupt every 2000 clock ticks or every 1 ms for a 0.5 KHz
signal.

\begin{verbatim}
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; INTERRUPT SERVICE

SERVICE

; TOGGLE PA4
      LDAA #%00010000
      EORA PORTA
      STAA PORTA

; TURN OFF THE FLAG!
      LDAA #%01000000
      STAA TFLG1

;set the next interrupt to occur 2000 clock ticks after this

      LDD TOC2 <= This is different
      ADDD #2000
      STD TOC2 <=


; END WITH AN RTI
      RTI
\end{verbatim}
\end{document}
