% Format: LaTeX % $Header: G:\MICROP\56FTWS0\RCS\learnc.tex 1.6 1996/02/26 17:57:01 Nick Exp Nick $ % $Log: learnc.tex $ % Revision 1.6 1996/02/26 17:57:01 Nick % Have fixed spelling. Major problem was no clear double page before % numbering began at chapter 1 again. Went from odd on right to odd on left % with strange results for the side margins. % In frantic, tired efforts to resolve this I removed the use of % booklet.cls and moved stuff from asmprim2.tex to the preamble here. % % Revision 1.5 1996/02/25 18:48:56 Nick % This is a major revision. % It has exercises, solutions, stuff about most that I hoped to % achieve. % % Revision 1.4 1996/02/20 15:46:18 Nick % This is a major revision. I have added much more material, % including exercises with solutions, more diagrams, and have clarified % some explanations. It looks like it is shaping up to become my major % opus for the uear. % % Revision 1.3 1996/02/10 16:41:25 Nick % A significant rearangement. % The info on the parts of the compiler have been moved to the back. % Some changes I noted in the train have been made. % Still quite a long way to go, but we're on the way. % % Revision 1.2 1996/01/31 16:43:01 Nick % This version has all the program examples as floats with a list % of programs. It now needs some practical advice on using the % Quincy interpreter, and some exercises. % % Revision 1.1 1996/01/30 14:40:26 Nick % Initial revision % % Revision 1.3 1995/10/19 21:58:39 Nick % Have added Vincent's examples. % % Turn off special treatment of the vertical bar by lgrind so % tabular environment works. %|- %@- \begin{filecontents}{acro.sty} \ProvidesPackage{acro}[1996/02/19 Abbreviations and acronyms] % Written by Nick Urbanik, % $Header: G:\MICROP\56FTWS0\RCS\learnc.tex 1.6 1996/02/26 17:57:01 Nick Exp Nick $ % $Log: learnc.tex $ % Revision 1.6 1996/02/26 17:57:01 Nick % Have fixed spelling. Major problem was no clear double page before % numbering began at chapter 1 again. Went from odd on right to odd on left % with strange results for the side margins. % In frantic, tired efforts to resolve this I removed the use of % booklet.cls and moved stuff from asmprim2.tex to the preamble here. % % Revision 1.5 1996/02/25 18:48:56 Nick % This is a major revision. % It has exercises, solutions, stuff about most that I hoped to % achieve. % % Revision 1.4 1996/02/20 15:46:18 Nick % This is a major revision. I have added much more material, % including exercises with solutions, more diagrams, and have clarified % some explanations. It looks like it is shaping up to become my major % opus for the uear. % % Revision 1.4 1996/01/24 00:35:39 Nick % Added slanted LEDs, embedded systems and DTMF. % % Revision 1.2 1995/09/14 21:53:41 Nick % This is a merging of my acro.sty at home and that at work. % \RequirePackage{xspace,relsize,scl} \DeclareRobustCommand{\Slash}{{\raisebox{0.3ex}{\relsize{-3}/}}} \DeclareRobustCommand{\leftPar}{{\raisebox{0.1ex}{\relsize{-2}(}}} \DeclareRobustCommand{\rightPar}{{\raisebox{0.1ex}{\relsize{-2})}}} % Make an acro able to work in maths mode, so I can use overline. \DeclareMathAlphabet{\mathsc}{OT1}{cmr}{m}{sc} \DeclareRobustCommand{\acro}[1]{\textsc{\lowercase{#1}}} \DeclareRobustCommand{\acroSl}[1]{\textscl{\lowercase{#1}}} \DeclareRobustCommand{\overbar}[1]% {\ensuremath{\overline{\mathsc{\lowercase{#1}}}}} \providecommand*{\AC}{\acro{AC}\xspace} \providecommand*{\AD}{\acro{A\Slash{}{}D}\xspace} \providecommand*{\ADsl}{\acroSl{A\Slash{}{}D}\xspace} \providecommand*{\ALU}{\acro{ALU}\xspace} \providecommand*{\ANSI}{\acro{ANSI}\xspace} \providecommand*{\ASCII}{\acro{ASCII}\xspace} \providecommand*{\AS}{$\overline{\acro{AS}}$\xspace} \providecommand*{\BASIC}{\acro{BASIC}\xspace} \providecommand*{\BIOS}{\acro{BIOS}\xspace} \providecommand*{\CDROM}{\acro{CDROM}\xspace} \providecommand*{\CMOS}{\acro{CMOS}\xspace} \providecommand*{\CPU}{\acro{CPU}\xspace} \providecommand*{\CRT}{\acro{CRT}\xspace} \providecommand*{\CS}{$\overline{\acro{CS}}$\xspace} \providecommand*{\EEPROM}{\acro{EEPROM}\xspace} \providecommand*{\EPROM}{\acro{EPROM}\xspace} \providecommand*{\DA}{\acro{D\Slash{}{}A}\xspace} \providecommand*{\DAsl}{\acroSl{D\Slash{}{}A}\xspace} \providecommand*{\DC}{\acro{DC}\xspace} \providecommand*{\DIP}{\acro{DIP}\xspace} \providecommand*{\DMA}{\acro{DMA}\xspace} \providecommand*{\DOS}{\acro{DOS}\xspace} \providecommand*{\DMAC}{\acro{DMAC}\xspace} \providecommand*{\DTACK}{$\overline{\acro{DTACK}}$\xspace} \providecommand*{\DTMF}{\acro{DTMF}\xspace} \providecommand*{\DUART}{\acro{DUART}\xspace} \providecommand*{\FIFO}{\acro{FIFO}\xspace} \providecommand*{\FLIGHT}{\acro{FLIGHT-68K}\xspace} \providecommand*{\FLIGHTsl}{\acroSl{FLIGHT-68K}\xspace} \providecommand*{\GNU}{\acro{GNU}\xspace} \providecommand*{\HC}{\acro{HC}\xspace} \providecommand*{\HD}{\acro{HD}\xspace} \providecommand*{\HKTC}{\acro{HKTC\leftPar{}TY\rightPar}\xspace} \providecommand*{\HKTCsl}{\acroSl{HKTC\leftPar{}TY\rightPar}\xspace} \providecommand*{\HLL}{\acro{HLL}\xspace} \providecommand*{\IC}{\acro{IC}\xspace} \providecommand*{\ICE}{\acro{ICE}\xspace} \providecommand*{\IM}{\acro{IM}\xspace} % interrupt mask \DeclareRobustCommand{\IO}{\acro{I\Slash{}{}O}\xspace} \DeclareRobustCommand{\IOsl}{\acroSl{I\Slash{}{}O}\xspace} \providecommand*{\ISA}{\acro{ISA}\xspace} \providecommand*{\ISR}{\acro{ISR}\xspace} \providecommand*{\LAN}{\acro{LAN}\xspace} \providecommand*{\LDS}{\overbar{LDS}\xspace} \providecommand*{\LED}{\acro{LED}\xspace} \providecommand*{\LEDsl}{\acroSl{LED}\xspace} \providecommand*{\LIFO}{\acro{LIFO}\xspace} \providecommand*{\LLL}{\acro{LLL}\xspace} \providecommand*{\LRC}{\acro{LRC}\xspace} \providecommand*{\LSB}{\acro{LSB}\xspace} \providecommand*{\MPU}{\acro{MPU}\xspace} \providecommand*{\NMI}{\acro{NMI}\xspace} \providecommand*{\MSDOS}{\acro{MS-DOS}\xspace} \providecommand*{\MSDOSsl}{\acroSl{MS-DOS}\xspace} \providecommand*{\MSB}{\acro{MSB}\xspace} \providecommand*{\OS}{\acro{O\Slash{}{}S}\xspace} \providecommand*{\OSsl}{\acroSl{O\Slash{}{}S}\xspace} \providecommand*{\PAL}{\acro{PAL}\xspace} \providecommand*{\PC}{\acro{PC}\xspace} \providecommand*{\PCB}{\acro{PCB}\xspace} \providecommand*{\PGA}{\acro{PGA}\xspace} \providecommand*{\PIT}{\acro{PI\Slash{}{}T}\xspace} \providecommand*{\PITsl}{\acroSl{PI\Slash{}{}T}\xspace} \providecommand*{\PLCC}{\acro{PLCC}\xspace} \providecommand*{\PLD}{\acro{PLD}\xspace} \providecommand*{\PROM}{\acro{PROM}\xspace} \providecommand*{\RAM}{\acro{RAM}\xspace} \providecommand*{\RESET}{$\overline{\acro{RESET}}$\xspace} \providecommand*{\ROM}{\acro{ROM}\xspace} \providecommand*{\RTS}{\acro{RTS}\xspace} \providecommand*{\RW}{\acro{R\Slash{}{}\overbar{W}}\xspace} \providecommand*{\TTL}{\acro{TTL}\xspace} \providecommand*{\UDS}{\overbar{UDS}\xspace} \providecommand*{\UNIX}{\acro{UNIX}\xspace} \providecommand*{\VRC}{\acro{VRC}\xspace} \providecommand*{\VSC}{\acro{VSC}\xspace} \providecommand*{\VTC}{\acro{VTC}\xspace} \providecommand*{\es}{embedded system\xspace} \providecommand*{\uc}{microcontroller\xspace} \providecommand*{\Uc}{Microcontroller\xspace} \providecommand*{\up}{microprocessor\xspace} \providecommand*{\Up}{Microprocessor\xspace} \providecommand*{\MPA}{Microprocessor Applications Laboratory\xspace} \providecommand*{\mpa}{microprocessor lab\xspace} % Hex digits in mathematics mode: \providecommand*{\A}{\ensuremath{\mathrm{A}}} \providecommand*{\Bh}{\ensuremath{\mathrm{B}}} \providecommand*{\B}{\ensuremath{\mathrm{B}}} \providecommand*{\C}{\ensuremath{\mathrm{C}}} \providecommand*{\D}{\ensuremath{\mathrm{D}}} \providecommand*{\E}{\ensuremath{\mathrm{E}}} \providecommand*{\F}{\ensuremath{\mathrm{F}}} % for kilobytes: \providecommand*{\Kb}{\mathrm{K}} % megabytes: \providecommand*{\M}{\mathrm{M}} \end{filecontents} \begin{filecontents}{thm.sty} % Modified version of thm.sty by Nick Urbanik, 19-2-96. % Modified to create an exercise like TeXbook. % Select this with \theoremstyle{margin}. \def\FMithmInfo{1995/11/23 v2.2c Theorem extension package (FMi)} %% %% Package `theorem' to use with LaTeX2e %% Copyright (C) 1989-1995 Frank Mittelbach, all rights reserved. \begingroup \makeatletter \@ifundefined{theorem@style}{\input{theorem.sty}}{} \ProvidesFile{thm.sty} [\FMithmInfo] \gdef\th@margin{\normalfont\slshape \def\@begintheorem##1##2{\item [\theorem@headerfont \llap{$\blacktriangleright$}\hskip\labelsep ##1\ ##2]}% \def\@opargbegintheorem##1##2##3{% \item[\theorem@headerfont \llap{$\blacktriangleright$}\hskip\labelsep ##1\ ##2 (##3)]}} \endgroup \endinput \end{filecontents} %@+ \def\BookletBaseClass{book} \documentclass[openany,twoside,a5paper]{book} %\documentclass[openany,twoside]{booklet} %\documentclass[oddleft]{booklet} \usepackage{acro}[1995/02/19] \usepackage{% vmargin,% fancyheadings,% varioref,% rcs,% lgrind,% emlines2,% multicol,% cols,% makeidx,% array,% nbox,% xr,% explanation,% booktabs,% version,% prog,% enumerate,% amstext,% %showkeys,% amssymb,% amsmath,% theorem,% nick,% lastpage,% float,% answers,% verbatim} \setpapersize{A5}% \shiftmargins \setmarginsrb{13mm}% left For a book, the inner. {9mm}% top {20mm}% right For a book, the outer. {10mm}% bottom {12pt}% headheight---increase to stop fancyhead warn {4mm}% headsep {0pt}% footheight {8mm}% footskip \RCS$Revision: 1.6 $ \RCS$Date: 1996/02/26 17:57:01 $ \providecommand{\revision}{ver \RCSRevision{}% ,\hspace{0.8ex} \RCSDate% } \DeclareRobustCommand{\referenceNum}{EE/27/LA/20/95} % 6, 7,..., 21. % Turn off lgrind's special handling of the vertical bar: %|- % For the external references (xr.sty): \externaldocument[asmpv114:]{../56ptws0/asmpv114} \pagestyle{fancyplain} \includeversion{notes} \excludeversion{slides} \includeversion{elecEng} \setlength{\extrarowheight}{1.5pt} % Is this okay? \newcommand*{\clearemptydoublepage}% {\newpage{\pagestyle{empty}\cleardoublepage}} \newcommand*{\headSize}{\scriptsize} \newcommand*{\outerHead}{\textbf{\normalsize\thepage}} \newcommand*{\outerRightFoot}{\tiny\referenceNum} \newcommand*{\outerLeftFoot}{\tiny\revision} \renewcommand*{\chaptermark}[1]{\markboth{#1}{#1}} \renewcommand*{\sectionmark}[1]{\markright{\thesection\ \ #1}} \lhead% [\fancyplain{}{\outerHead}]% {\fancyplain{}{\bfseries\rightmark}} \rhead% [\fancyplain{}{\bfseries\leftmark}]% {\fancyplain{}{\outerHead}} \lfoot[\fancyplain{}{\outerLeftFoot}]{} \rfoot[]{\fancyplain{}{\outerRightFoot}} \cfoot[\fancyplain{}{}]{\fancyplain{}{}} \DeclareRobustCommand{\Lsh}{\textless\!\!\textless} \DeclareRobustCommand{\Rsh}{\textgreater\!\!\textgreater} % \newcommand{\nBox}[2][40mm]{\parbox[c][3\baselineskip][c]{#1}{\centering#2}} % From asmprim.tex: %\renewcommand*{\chaptermark}[1]{\markboth{#1}{#1}} %\renewcommand*{\sectionmark}[1]{\markright{\thesection\ #1}} %\newcommand*{\outerLeftFoot}{\tiny\revision} %\newcommand*{\outerRightFoot}{\tiny\referenceNum} %\lfoot[\fancyplain{}{\outerLeftFoot}]{} %\rfoot[]{\fancyplain{}{\outerRightFoot}} % !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! % Belongs in lect2.dtx! % !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \raggedbottom \newcommand*{\qc}{\textsf{Quincy}\xspace} \providecommand{\DP}{\textsf{MS-DOS Prompt}\xspace} \providecommand{\ed}{\textsf{MS-DOS Editor}\xspace} \providecommand{\hp}{\textsf{HP Real-time C Debugger}\xspace} \providecommand{\te}{\textsf{Terminal}\xspace} \renewcommand{\floatpagefraction}{0.75} % default is .5, to increase % density. \renewcommand*{\bottomfraction}{0.6} % default is 0.3 \renewcommand*{\topfraction}{0.85} % default is 0.7 \renewcommand*{\textfraction}{0.1} % default is 0.2 \floatstyle{ruled} \floatname{program}{Program example} \newfloat{program}{tbhp}{lop}[chapter] \newcommand*{\tableFontSize}{\footnotesize} % Stuff for the title page: \DeclareFontFamily{U}{cminch}{} \DeclareFontShape{U}{cminch}{b}{n} { <72><217><434> cminch }{} \DeclareFixedFont{\cmthreeinch}{U}{cminch}{b}{n}{217} \DeclareFixedFont{\cmfourinch}{U}{cminch}{b}{n}{434} \newcommand*{\HRule}{\rule{\linewidth}{1mm}} \newlength{\embeddedWidth} \settowidth{\embeddedWidth}{\sffamily\Huge\bfseries embedded} \newlength{\cWidth} \newlength{\cHeight} \settowidth{\cWidth}{\cmfourinch\char'103} \settoheight{\cHeight}{\cmfourinch\char'103} \newlength{\cPos} \setlength{\cPos}{0.6\cWidth} \addtolength{\cPos}{-\embeddedWidth} %\title{\raggedleft %\sffamily\Huge\bfseries {\raggedright Learning and using\\[1ex]} %{\cmfourinch\char'103}\hspace*{-0.6\cWidth}\raisebox{0.5\cHeight}[0pt][0pt]{% %\parbox{\embeddedWidth}{in\\embedded\\systems}}\hspace*{\cPos}\mbox{}\\[1ex] %\Large Nick Urbanik\\[1.5ex] %\normalsize example programs by {\large Vincent Hui}\\[6ex] %\normalsize \RCSDate\\[2ex] %Hong Kong Technical College (Tsing Yi)\\[2ex] %Department of Electrical and Communications Engineering %} %\author{} %\date{} %\title{Learning and using C with embedded systems: a laboratory guide for % \emph{Digital Systems and Microprocessors}} %\author{Nick Urbanik \and Vincent Hui\thanks{Vincent Hui contributed most of the % examples in this booklet.}\\[2ex] %Department of Electrical and Communications Engineering\\ %Hong Hong Technical College (Tsing Yi)} %\date{\RCSDate} % The set up for the exercises: \theorembodyfont{\rmfamily} \theoremstyle{margin}% This is my modified thm.sty. \newtheorem{exercise}{Exercise}[chapter] \newtheorem{example}{Example}[chapter] \theoremheaderfont{\scshape} \Newassociation{Solution}{Soln}{exsolns} \renewcommand{\Solnlabel}[1]{\textsc{Solution } #1} \makeindex \newcommand*{\nn}[1]{#1n} % For index entries in footnotes. \renewcommand*{\bibname}{References} \begin{document} \Opensolutionfile{exsolns} \pagenumbering{roman} % \thispagestyle{empty} \vspace*{0pt} {\raggedleft \sffamily\Huge\bfseries {\raggedright Learning and using\\[1ex]} {\cmfourinch\char'103}\hspace*{-0.6\cWidth}\raisebox{0.5\cHeight}[0pt][0pt]{% \parbox{\embeddedWidth}{in\\embedded\\systems}}\hspace*{\cPos}\mbox{}\\[1ex] \Large Nick Urbanik\\[1.5ex] \normalsize example programs by {\large Vincent Hui}\break \vfill \normalsize \RCSDate\\[1.5ex] Hong Kong Technical College (Tsing Yi)\\ Department of Electrical and Communications Engineering\break} %\vspace*{\stretch{1}} \newpage \thispagestyle{empty} \vspace*{\stretch{1}} Copyright \copyright{} 1996 by Nick Urbanik\\ Department of Electrical and Communications Engineering\\ Hong Kong Technical College (Tsing Yi)\\ %@- nicku@iohk.com %@+ For use by the students and staff of the Hong Kong Technical Colleges. This booklet was typeset using \LaTeXe. \vspace*{\stretch{2}} % %\maketitle %\thispagestyle{empty} \tableofcontents \listoffigures \listoftables \listof{program}{Program examples} \clearemptydoublepage %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Introduction} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pagenumbering{arabic} This booklet is intended to help you to write C programs in your laboratory work. It is too small to replace a good text book on C, but I hope that it is a useful reference for you. It also introduces the \qc C interpreter, which you may take home and use on your own computer to practice writing programs in C\e. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{How should you learn the C language?} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \eemph{The best way to learn a computer language is by using it.} Because we use \ANSI C, any \ANSI C compiler or interpreter understands the same keywords. Obtain the \qc C interpreter (see appendix~\vref{sec:qc} and use it to do the exercises and to run the examples in this book. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Practice!} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% There are many examples and exercises in this book which are designed to work with the \qc interpreter or Turbo/Borland C, Microsoft C or almost any other C compiler less than 5 years old. All programming exercises and all examples that do not @#include @ should be run in the microprocessor lab: remember, the door is open to you as much as possible. The lab is available to you for your use \emph{most of the time}. Make use of this! I run the laboratory with an open door policy. That means that whenever I or Henry (the capable laboratory technician) is there, you may come in and make use of the equipment and ask me questions about your laboratory work or about lectures. Work through the exercises I have set you in your workshops. Try any exercises I have provided in this book. Ask questions. You may also ask me any questions you have about C, \Cpp or Pascal\e. If you do not make use of this policy, you are not making proper use of the money you have spent on your tuition fees! \index{open door policy|)} \index{open lab policy|)} \index{lab!open door policy|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Books about C programming} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% There are many books on C programming with \ANSI C; the ones in the references section on page~\pageref{sec:references} are just a tiny selection of what is available in the library. The standard reference book by Kernighan and Ritchie, \cite{kernighan}, is excellent once you are familiar with the language, but in the meantime I suggest books such as that by Al~Stevens, \cite{stevens}, with which the \qc interpreter is provided. Unfortunately, \cite{stevens} assumes a (little) background in programming. The book \cite{perry} may help, but I personally do not like it very much---you may have a different opinion, so have a look at it if you need more help. If you need a book in addition to this one, search through the library for one you like. Please let me know if you find one you like. A useful guide is the \cite{cFaq}. This is available on the network. It may help to buy a book on C; however, I am told that many books which are translations of English language texts have mistakes in translation. If you buy a book in the Chinese language, I suggest that you buy one written directly in the Chinese language by its author, unless you know that the translator is a programmer. For information about assembly language and microprocessors, please refer to the text book, \cite{horvath}, and also the booklet \cite{nickAsm} which is available to all students and staff of this College. For students who are interested in projects using microprocessors and who would like a practical magazine with lots of interesting ideas, it is hard to do better than \cite{cktCellar}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The convention used here for C programs} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Here are some concepts in the C programming language, some of which will be new to you. You will use many of these in your labs. The C language is very much like the Pascal language. I refer often to the Pascal language here, since some students are familiar with Pascal\e. If you do not know the Pascal programming language, then ignore the references to Pascal---it is not necessary to learn Pascal before your learn C\e. In the programs shown in the lecture and lab notes, all \emph{keywords} in the C language are shown in a bold font like this: @while@. All keywords are part of the language and will be found to be common to other \ANSI{}\footnote{\ANSI means American National Standards Institute, and is the organisation which is maintaining a standard which all C compiler manufacturers try hard to make their compilers conform to.} C compilers. You should learn all the keywords of the C programming language. Other variables and names which are not built in to the language are shown in a font like this: @printf()@. Nick Urbanik is often in the lab, and you are welcome to use the computers in the lab to practice your C with the \FLIGHT boards as long as he is there. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Embedded systems} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:embedded} The title of this book includes `embedded systems'. So what is an embedded system? Many people think that desktop \PC{}s running programs such as word processors, spreadsheets or games would be the most common application of microprocessors or computers. However, such a viewpoint is \emph{wrong}---most \up{}s are part of \index{microprocessors}% devices such as washing machines, televisions, remote controllers, pagers, video recorders, motor vehicles, refrigerators, watches and many other devices that you use or see every day. This course is an introduction to \emph{embedded systems}. An \ix{embedded system} is a microprocessor system that is built into a machine---such as a washing machine, a \acro{TV}, a radio or a robot---instead of being a general purpose desktop computer. Because an embedded system usually does not have a large video screen and a big keyboard, we often communicate with an embedded system via a \PC and a \emph{serial cable}. In the laboratory you will use a \PC to communicate through a \emph{serial cable} to a single-board computer \emph{development system}. This \emph{development system} can be used to test and \emph{debug}\footnote{\emph{Debugging}\index{debugging|nn} is the process of finding errors in a system and removing those errors.} software that will run on hardware that you as a system developer design and build. The \ix{development system} is called the \emph{\FLIGHTsl \up board}. The \FLIGHT has a Motorola 68000 microprocessor at its heart. On the \FLIGHT some programs are stored permanently in \ROM{}s\footnote{The word `\ROM' stands for ``read only memory''.}. These programs are called the \emph{monitor firmware}. You will use some of these programs in your first lab session. You can read about them in chapter~4 of \emph{The \FLIGHTsl Users manual}, \cite{flight}, which is available in the laboratory. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{How should I use this book?} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{how to use this book|(} How to use this book: \begin{enumerate} \item Bring it to each lab session \item \begin{enumerate} \item Bring a floppy disk to the laboratory \item Collect the \qc C interpreter\footnote{See section~\vref{sec:howCopyQc} for details of how to obtain the \qc interpreter.} \item take it home or to work \item install it on a \PC \item \emph{use} it: \item read the rest of appendix~\ref{sec:qc} for information about \qc. \item work through the examples \item work through the exercises \begin{itemize} \item look at the solution \emph{after} you have tried to solve the exercise using \qc or a computer in your laboratory \item type the solution into a computer and run it to see what it does \item If it is not clear to you how the program works, \begin{itemize} \item single-step\index{single step} through the program using \qc: use the \textsf{\textbf{R}un$\rightarrow$\textbf{S}tep} command, or press the \meta{F7} key repeatedly. \item Use \textsf{\textbf{D}ebug$\rightarrow$Add a \textbf{w}atch variable}\index{watching variables} to put interesting variables into the watch window so that you can see their value change as you step through the program. \end{itemize} \end{itemize} \end{enumerate} \item Read the sections that your lab sheet refers to \item Use the index and table of contents to locate any topic you need, then read that section. \item It is not necessary for you to read this starting from page 1 and finishing with page \pageref{LastPage}! \end{enumerate} \index{how to use this book|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{The C programming language} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Constant values in C} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:constant} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Constant integer values} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:intConstants} We can write a constant integer value in our programs in decimal, octal or hexadecimal. We can write the value 23$_{10}$ in three different ways, all giving the same result: \begin{center} \begin{tabular}{ll} @23@ & decimal\\ @027@ & octal \\ @0x17@ & hexadecimal \end{tabular} \end{center} Decimal values are the default. We can enter a number in octal by making the first digit zero. So be warned: @027@ $ \ne $ @27@! Hexadecimal values begin with `@0x@'. All of these will be of type @int@ unless we specify otherwise. In each of these cases, an identical value is used by the compiler. If we write a number such as 1, or @0xf@, in C these are both \emph{integers}---that is, on the 68000, they are 32~bits long; on \MSDOS systems---including the \qc interpreter---they are 16~bits long. This means that with our 68000 system, the bit pattern for @0xf@ is: 0000\,0000\,0000\,0000\,0000\,0000\,0000\,1111. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Constant character values} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% A character is written in the C language by putting single quotes `\,\Of{'}\,' around a single character. So the capital letter `A' is represented in C as @'A'@, and the lower case character `h' is represented as @'h'@. C does not make a special distinction between a character and its \ASCII value. Since the \ASCII value of @'A'@ is 41\hex or 65\dec, @'A'@ is equivalent to @0x41@ or @65@. Similarly, @'h'@ is equivalent to @104@ or @0x68@. See appendix~\vref{sec:ascii} for more about \ASCII codes. Do \emph{not} put single quotes around more than one character if you want a string. See the next section. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Constant strings} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% A string is a group of zero or more characters. A string is written in the C language by putting double quotes `\,\Of{"}\,' around the characters. Here are some examples of constant (or ``literal'') strings in C: @"This is a string"@, @"This is another string with a newline\n"@; here is a ``null'' or empty string: @""@ In the C programming language, all strings end with the \acro{NUL} \ASCII character, which has the \ASCII value zero. This means that the string @"A"@ contains \emph{two} characters: the character @'A'@ followed by the \acro{NUL} character. This means that @"A"@ is different from @'A'@\e. \begin{exercise} How many characters are there in the ``null'' string @""@? Write down what these characters are. \begin{Solution} The ``null'' string @""@ contains one character: the \acro{NUL} \ASCII character. \end{Solution} \end{exercise} A string is represented in C as an array of characters. See the section~\vref{sec:arrays} for more information about arrays. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Named constants in C} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% It is usually better to write a name that shows what a number is rather than filling your program with lots of unnamed constant integer numbers. For instance, it is better to write @NUMPATTERNS@ than just the number 8 for two reasons: \begin{itemize} \item Your program is easier to understand, important for a bigger program \item If you later change to a different number of patterns, \eemph{you only need to change your program in one place} instead of looking for all places where you wrote `8' and wondering whether each `8' was the number of patterns (or was it something else?) \end{itemize} Pascal provides the keyword @const@ to declare constants. The same keyword exists in the C language. You may also use the preprocessor to define a constant with @#define@. These two methods both define a constant value: %[ #define NUMPATTERNS 8 const int numPatterns = 8; %] Note that @#define@ does \emph{not} have a semicolon at the end, since it is a command to the preprocessor, while the @const@ant value must be terminated by a semicolon because it is read by the compiler itself. See section~\vref{sec:preprocessor} for more about the preprocessor. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Integral types} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Data processed by a computer is a series of 1s and 0s. It is the \emph{type} of a piece of data that gives it some meaning. Here we look at \emph{integral types}. An integral type describes data that can hold counting numbers, such as 0, 1, 2, 3, \ldots. There are two kinds of integral type: @signed@ and @unsigned@. A @signed@ integral type can hold negative counting numbers as well, such as $\ldots,-4,-3,-2,-1$. Pascal provides the \Kf{integer} and \Kf{char} integral data types. In C, there are corresponding types @int@ and @char@. Each type has a \emph{size}, in bytes. This size depends on the kind of machine the compiler is made for. Each integer type can be @signed@ or @unsigned@. Table~\vref{tab:intSize} shows the name of the type, the size in bytes, and the range of values the type can hold. These are correct for the MC68000 cross compiler used in the lab. Turbo C, the \qc interpreter (and other MS-DOS compilers) use 16-bit @int@ and @unsigned int@ types. \begin{table} \centering %@- { \tableFontSize \begin{tabular}{@{}lcrr@{}} \toprule \bf type & \bf size & \bf minimum value & \bf maximum value \\ \midrule \Kf{char} & 1 & $-2^{7} = -128$ & $2^{7} - 1$ = 127 \\ \Kf{unsigned char} & 1 & 0 & $2^{8} - 1$ = 255 \\ \Kf{short} & 2 & $-2^{15} = -32$\,768 & $2^{15} - 1$ = 32\,767 \\ \Kf{unsigned short}& 2 & 0 & $2^{16} - 1$ = 65\,535 \\ \Kf{int}, \Kf{long}& 4 & $-2^{31}$ = $-$2\,147\,483\,648 & $2^{31} - 1$ = 2\,147\,483\,647 \\ \Kf{unsigned int}, \Kf{unsigned long} & 4 & 0 & $2^{32} - 1$ = 4\,294\,967\,295 \\ \bottomrule \end{tabular} } %@+ \caption{The sizes of different integral types used by our 68000 C~cross-compiler in the laboratory. Note that with \qc and \MSDOS compilers, \Kf{int} and \Kf{unsigned int} are the same size as a \Kf{short}.} \label{tab:intSize} \end{table} \begin{exercise} For each of the following types: \begin{multicols}{2} \raggedcolumns \begin{itemize} \item integer \item an unsigned character \item a short integer \item a character \item an unsigned integer \end{itemize} \end{multicols} \begin{enumerate}[(a)] \item \label{qes:variable}Write a definition of a variable of each type in C. \item How many bits long is each type on the Motorola microprocessor system? \item How many bits long is each type on \MSDOS systems, including \qc? \item Which variable is represented using two's complement? Which is represented by a magnitude only? \item Write a @printf()@ statement to print out the value of each variable declared in~\ref{qes:variable}. \end{enumerate} \begin{Solution} \mbox{}\\ \begin{enumerate}[(a)] \item The sizes shown here are for the 68000 system in the laboratory: %[ int i; /* a long word-sized integer called @i@. */ unsigned char uch; /* a byte-sized variable called @uch@. */ short sh; /* a word-sized variable called @sh@. */ unsigned int ui; /* a long-word sized variable called @ui@. */ char ch; /* a byte-sized variable called @ch@. */ %] Here are three more definitions, of an @unsigned short@, a @long int@ and an @unsigned long int@: %[ unsigned short ush; /* a word-sized variable called @ush@. */ long li; /* a long-word sized variable called @li@ */ unsigned long uli; /* a long-word sized variable called @uli@. */ %] \item For the 68000 system in the laboratory: %@- %\vspace*{0pt}% \begin{tabular}[t]{@{}lccl@{}} %@+ \toprule \bf type & \bf size (bits) & \bf size (bytes) & \bf 2's compl/magnitude \\ \midrule integer & 32 & 4 & 2's complement \\ unsigned char & 8 & 1 & magnitude only \\ short integer & 16 & 2 & 2's complement \\ unsigned integer & 32 & 4 & magnitude only \\ char & 8 & 1 & 2's complement\footnotemark \\ \hline unsigned short integer & 16 & 2 & magnitude only \\ long integer & 32 & 4 & 2's complement \\ unsigned long integer & 32 & 4 & magnitude only \\ \bottomrule \end{tabular}% \footnotetext{However the \Kf{char} type can be unsigned by default in some compilers.} \item For \MSDOS: %@- %\vspace*{0pt}% \begin{tabular}[t]{@{}lccl@{}} %@+ \toprule \bf type & \bf size (bits) & \bf size (bytes) & \bf 2's compl/magnitude \\ \midrule integer & 16 & 2 & 2's complement \\ unsigned char & 8 & 1 & magnitude only \\ short integer & 16 & 2 & 2's complement \\ unsigned integer & 16 & 2 & magnitude only \\ char & 8 & 1 & 2's complement \\ \hline unsigned short integer & 16 & 2 & magnitude only \\ long integer & 32 & 4 & 2's complement \\ unsigned long integer & 32 & 4 & magnitude only \\ \bottomrule \end{tabular} \item See the table above. ``Magnitude only'' means that the computer uses the unsigned value for the number and so can only hold values~$\ge 0$. ``Two's complement'' means that the computer uses the signed value for that number and so can hold a negative value. \item Here is one @printf()@ statement for each variable: %[\medskip printf( "The integer i = %d\n", i ); /* print the single character @uch@: */ printf( "The unsigned character uch = %c\n", uch ); /* print the ASCII value of @uch@, in decimal: */ printf( "The unsigned character uch = %hu\n", uch ); /* print the ASCII value of @uch@, in hexadecimal: */ printf( "The unsigned character uch = %hx\n", uch ); printf( "The short integer sh = %hd\n", sh ); /* print the single character @ch@: */ printf( "The character ch = %c\n", ch ); /* print the ASCII value of @ch@, in decimal: */ printf( "The character ch = %hd\n", ch ); printf( "The unsigned integer ui = %u\n", ui ); /* print the value of @ush@, in decimal: */ printf( "The unsigned short integer ush = %hu\n", ush ); /* print the value of @ush@, in hexadecimal: */ printf( "The unsigned short integer ush = %hx\n", ush ); printf( "The long integer li = %ld\n", li ); /* print the value of @uli@, in decimal: */ printf( "The unsigned long integer uli = %lu\n", uli ); /* print the value of @uli@, in hexadecimal: */ printf( "The unsigned long integer uli = %lx\n", uli ); %]\relax \end{enumerate} \end{Solution} \end{exercise} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Definitions and declarations of integer-type variables} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:declarations} In C, we put the type first when declaring a variable, and put the variable name second. Program example~\vref{prg:definition} gives \emph{definitions} of variables of the types shown in table~\vref{tab:intSize}. \begin{program} %[ char ch; /* byte-sized variable called @ch@. */ unsigned char uch; /* byte-sized variable called @uch@. */ int i; /* 4-byte integer called @i@, 68000, not %%\MSDOS%% */ unsigned int ui; /* 4-byte variable called @ui@, 68000, not %%\MSDOS%% */ long li; /* 4-byte variable called @li@ */ unsigned long uli; /* 4-byte variable called @uli@. */ %] \caption{Definitions of integral-type variables.} \label{prg:definition} \end{program} These definitions are also called \emph{declarations} of the variables. \eemph{An important rule in C is that a function or variable must be declared before it is used.} A program must have exactly one definition for a function or variable that is used. Note that local variables in different blocks are considered different variables, even when they have the same name. See section~\vref{sec:block} for the meaning of ``block''. When a variable is defined, it may also be initialised: %[ int i = 0; %] A declaration may declare several variables at once: %[ int i = 0, j, k = 67; %] Here there are three integer variables defined. @i@ and @k@ were initialised with 0, 67 respectively; @j@ is uninitialised. All three are of type @int@. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The meaning of \Kf{\#include}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:include} The line @#include @ is a command to the \emph{preprocessor}, which is a part of the C compiler. This command means: ``look for the file \texttt{flight.h} in the \emph{include} directory (which is \texttt{f:\bs hpcc68k\bs include}), and put a copy of this file into a copy of the program, just where the @#include@ command appears.'' The result is fed into the rest of the compilation process. All commands beginning with \textbf{@#@} are commands to the preprocessor. The preprocessor also removes all \emph{comments} from your program (see section~\vref{sec:comments} to read about comments). \begin{elecEng} Read section~\vref{sec:preprocessor} for more about the preprocessor and how to look at the output from the preprocessor in the lab. \end{elecEng} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Comments in the C language} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:comments} \index{comments|(} In the C language, comments are written beginning with the symbols @/*@ and end with the symbols @*/@. A comment can be more than one line long. A comment is written for the human reader of a program. A comment has absolutely no effect on what the compiler sees; comments are removed by the preprocessor. \eemph{In the labs, you do not need to type the comments from the lab sheets into the computer.} They are there to help you only. When you write bigger programs of your own, then you should write comments at the beginning of each function explaining what it does. This saves a lot of time when you or someone else wants to change the program a year later. \index{comments|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{C is case sensitive} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{case sensitive|(} \index{capital and lower case letters|(} A variable with the name @SevenSegment@ is different from a variable with the name @sevenSegment@. Capital letters and lower case letters are treated differently. This means that when your program works with a particular variable or function, it should always be written in exactly the same case. For instance, you need to type ``@printf@'' rather than ``@Printf@'' or ``@PRINTF@'' and ``@KEYPAD@'' rather than ``@KeyPad@''. \index{case sensitive|)} \index{capital and lower case letters|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The use of \textmd{\textsf{\textsl{printf}()}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{printf@\Vf{printf}\Of{()}|(} \index{debugging!using \Vf{printf}\Of{()}|(} %@+ As you may now realise, the @printf()@ function is very useful for showing what is happening inside your program. In our work with embedded systems, we use it mainly for \emph{debugging} --- finding logical errors we have made when writing our programs. @printf@ is used to display program output in the terminal window by serial transfer. In particular, @printf()@ is able to show the value of variables. This is often a help when the program does not work in the way we expected. Here we look at ways we can print out the values of some variables. \index{debugging!using \Vf{printf}\Of{()}|)} %@- \index{n@\textbackslash n|(} \index{newline character|(} \index{printf@\Vf{printf}\Of{()}!displaying newline character|(} %@+ Pascal provides @writeln@ when we want to print a newline, and @write@ if we don't want want the output to go onto a new line. In C, the @printf()@ library function can provide a newline wherever you want one. @printf()@ uses the symbol `@\n@' to mean, ``finish the line here and start a new line.'' We call @\n@ the \emph{newline character}. So if we write %[ printf( "Hi -- this is your " ); printf( "microprocessor talking!\n" ); printf( "This is line2.\n" ); %] or %[ printf( "Hi -- this is your microprocessor talking!\nThis is line2.\n" ); %] we will give the same output. \begin{program} %[ /* This is an example of using the @printf()@ library function */ /* These few lines are comments about the program. */ /* The example is written by Vincent & Nick. */ #include int main( void ) { printf( "Hi! How are you?\n" ); printf( "Welcome to this class.\n" ); return 0; } %] When run, the following appears in the terminal window: \begin{verbatim} Hi! How are you? Welcome to this class. \end{verbatim} \caption{An example showing use of \Vf{printf}\Of{()}.} \label{prg:printf} \end{program} Program example~\vref{prg:printfNewline} shows the use of the newline character, @'\n'@. \begin{program} %[ #include int main( void ) { printf( "Hi! \nHow are you?\n" ); printf( "Welcome to \nthis class.\n" ); return 0; } %] The result is: \begin{verbatim} Hi! How are you? Welcome to this class. \end{verbatim} \caption{An example showing use of \Vf{printf}\Of{()} and the newline character, \Of{'}\texttt{\bs{}n}\Of{'}.} \label{prg:printfNewline} %@- \index{printf@\Vf{printf}\Of{()}!examples} %@+ \end{program} \begin{exercise} Write a C program using the Quincy C interpreter to write your own name on the terminal. \begin{Solution} %[ #include int main( void ) { printf( "This is a message from Nick.\n" ); /* Or you could write: */ printf( "%s", "This is a message from Nick.\n" ); /* An alternative is to use @puts()@. Notice that @puts()@ gives a newline. */ puts( "This is a message from Nick." ); return 0; } %] %@- \index{printf@\Vf{printf}\Of{()}!examples} \index{puts@\Vf{puts}\Of{()} library function|(} \index{library function!\Vf{puts}\Of{()}|(} %@+ The library function @puts()@ is also part of the standard library; I have implemented @puts()@ on the 68000 system also. Of course it is also available with \qc. The @puts()@ library function adds a newline character at the end of the string, so I have not put one there in this solution. %@- \index{puts@\Vf{puts}\Of{()} library function|)} \index{library function!\Vf{puts}\Of{()}|)} %@+ \end{Solution} \end{exercise} %@- \index{n@\textbackslash n|)} \index{newline character|)} \index{printf@\Vf{printf}\Of{()}!displaying newline character|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Displaying variables} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% To use @printf()@ to display variables, there are some \emph{formatting characters} that we can use to get the output exactly as we want it. @printf()@ is very general purpose, and it can control the output display format very precisely. Here we look at just a few of the ways of formatting the output. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{Displaying an integer} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{printf@\Vf{printf}\Of{()}!displaying integer|(} %@+ Suppose we have two \emph{integer} variables that were declared as: %[ int fahrenheit; int celsius; %] Then we can print their values like this: %[ printf( "fahrenheit = %d, celsius = %d\n", fahrenheit, celsius ); %] There are three parts to this call to @printf()@. The first part is the \emph{format string}, which is between double quotes (\texttt{"}) and may contain some percent symbols (\texttt{\%}) followed by one or more \emph{format characters}. Here we are using the format character \texttt{d}. For each percent---format character pair, we need to put a value after the format string. The values must be separated by commas. These two other values are shown here, the variables @fahrenheit@ and @celsius@. The format character here is `\texttt{d}' for decimal; the value is shown in decimal. If we want to see it in hexadecimal, we can use the format characters `\texttt{\%x}' instead. The first exercises for workshop~3 show some other examples of displaying integers. Note that these \emph{must} be integer types, \ie @int@ or @unsigned int@. If the number is an @unsigned int@, then the output will be correct if you use either \texttt{\%u} or \texttt{\%x}, otherwise @unsigned@ numbers bigger than 32\,767 will be shown as negative values. %@- \index{printf@\Vf{printf}\Of{()}!displaying integer|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{Displaying a \Kf{short} integer} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{printf@\Vf{printf}\Of{()}!displaying short integer|(} %@+ A sixteen-bit value can be represented by a @short@ or @unsigned short@. We use the letter `\texttt{h}' in front of the `\texttt{d}' or `\texttt{h}' or `\texttt{u}' to indicate that we are using a `half' sized value, \ie a 16-bit value instead of a 32-bit value. If we have a @short@ @int@eger variable defined as: %[ short sh; %] We can display this value on the terminal as: %[ printf( "The value of `sh' is %hd\n", sh ); %] If we have an @unsigned short int@eger defined as: %[ unsigned short ush; %] We can display the unsigned value of @ush@ on the terminal as: %[ printf( "The value of `ush' is %hu\n", ush ); %] Or, if you want to display it in hexadecimal, you can write: %[ printf( "The hexadecimal value of `ush' is %hx\n", ush ); %] %@- \index{printf@\Vf{printf}\Of{()}!displaying short integer|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{Displaying an \Kf{unsigned char}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{printf@\Vf{printf}\Of{()}!displaying unsigned char|(} %@+ Suppose we have an \emph{unsigned character} variable declared as: %[ unsigned char pattern; %] @pattern@ is a variable that can hold eight bits, or a byte. Suppose we use it to to read the keypad like this: %[ pattern = KEYPAD; %] Now we may want to print the numerical value of @pattern@ in hexadecimal. We can do that with: %[ printf( "pattern = %hx\n", pattern ); %] There are two characters used in the format string here: `\texttt{x}' means display an integer in hexadecimal. The letter `\texttt{h}' between the `\texttt{\%}' and the `\texttt{x}' is for ``half''; the value occupies half an integer, \ie a word. But you know that a character is a byte---why does it occupy a word? This is because the character is taken from the \emph{stack} by @printf()@; you will see later that when a character is pushed onto the stack, an extra zero byte is also pushed onto the stack, making a sixteen-bit word. \begin{exercise} Write a C program that defines an initialised character variable, and which displays the signed decimal \ASCII value, the unsigned decimal \ASCII value, the hexadecimal \ASCII value and the character itself. \begin{Solution} %[ #include int main( void ) { unsigned char ch = 129; printf( "The signed value of ch is %hd;", ch ); printf( " the unsigned value is %hu\n", ch ); printf( "The hexadecimal value of ch is %hx;", ch ); printf( " the character value is %c\n", ch, ch ); return 0; } %] The output of this program is: \begin{alltt} The signed value of ch is 129; the unsigned value is 129 The hexadecimal value of ch is 81; the character value is \"u \end{alltt} \end{Solution} \end{exercise} %@- \index{printf@\Vf{printf}\Of{()}!displaying unsigned char|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{Displaying a \Kf{long int}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{printf@\Vf{printf}\Of{()}!displaying long integer|(} %@+ Suppose we have a \emph{long integer} variable declared as: %[ long li; %] We print its value like this: %[ printf( "li = %ld\n", li ); %] There are two characters used in the format string here: `\texttt{d}' means display an integer in decimal. The letter `\texttt{l}' between the `\texttt{\%}' and the `\texttt{d}' is for ``long''; the value is a long integer. %@- \index{printf@\Vf{printf}\Of{()}!displaying long integer|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Displaying a string} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{printf@\Vf{printf}\Of{()}!displaying string|(} %@+ We can display a string with the \texttt{\%s} format characters: %[ printf( "A big hello from %s.\n", "Nick" ); %] This displays the following message on the terminal: \begin{verbatim} A big hello from Nick. \end{verbatim} %@- \index{printf@\Vf{printf}\Of{()}!displaying string|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{A warning about the format characters and \textmd{\textsf{\textsl{printf}()}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% An important thing here is that the format characters must match the size of the variable you want to display, otherwise you may find that some nonsense is displayed on the terminal screen. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{A summary of the format characters} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{printf@\Vf{printf}\Of{()}!displaying variables|(} %@+ For @int@, use \texttt{\%d}. % WARNING! Lgrind gets confused after a \%. % For @unsigned int@ you can use \texttt{\%u} to see the decimal unsigned value and \texttt{\%x} to display the hexadecimal unsigned value. If you use other format characters, you may see a value that has little to do with the number you want to see. For @long@, use \texttt{\%ld}, \texttt{\%lx} or \texttt{\%lu}. For @short@, use \texttt{\%hd}. % Watch out for lgrind after \%. For @unsigned short@, use \texttt{\%hu} to see the decimal unsigned value and \texttt{\%hx} to display the hexadecimal unsigned value. For @char@ use \texttt{\%hd}, \texttt{\%hx} or \texttt{\%hu} to see the number value of the byte (\ie its \ASCII value). To see the character as just a single character instead of its \ASCII value, use \texttt{\%c}. If the number is any @unsigned@ type, then the output will be correct if you use either \texttt{u} or \texttt{x} instead of \texttt{d}, otherwise large @unsigned@ numbers will appear as negative values. \begin{table}[htb] \centering %@- \begin{tabular}{@{}l>{\ttfamily}ll@{}} %@+ \toprule to display & \multicolumn{1}{c}{\makebox[5em][c]{\makebox[0.8\width][r]{\textrm{format characters}}}} & display as \\ \midrule @char@ & \%c & the character itself \\ @char@ & \%hd & signed decimal \ASCII value \\ @char@ & \%hu & unsigned decimal \ASCII value \\ @char@ & \%hx & unsigned hexadecimal \ASCII value \\ @short@ & \%hd & signed decimal value \\ @unsigned short@ & \%hu & unsigned decimal value \\ @unsigned short@ & \%hx & unsigned hexadecimal value \\ @int@ & \%d & signed decimal value \\ @unsigned int@ & \%u & unsigned decimal value \\ @unsigned int@ & \%x & unsigned hexadecimal value \\ @long@ & \%ld & signed decimal value \\ @unsigned long@ & \%lu & unsigned decimal value \\ @unsigned long@ & \%lx & unsigned hexadecimal value \\ string & \%s & display the characters in the string \\ \bottomrule \end{tabular} \caption{The format characters for use with \Vf{printf}\Of{()}.} \label{tab:formatChars} %@- \index{printf@\Vf{printf}\Of{()}!displaying variables|textbf} %@+ \end{table} %@- \index{printf@\Vf{printf}\Of{()}!displaying variables|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Example programs showing the use of \textmd{\textsf{\textsl{printf}()}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{printf@\Vf{printf}\Of{()}!examples|(} %@+ Program example~\vref{pgm:printfInteger} uses @printf()@ to display @int@eger type variables. \begin{program} %[ #include /* This program demonstrates using @printf()@ to display integers */ int main( void ) { int i = 2; int j = 3; printf( "%d and %d", i, j ); printf( "%d and %d", j, i ); return 0; } %] In the terminal window you will see: \begin{verbatim} 2 and 3 3 and 2 \end{verbatim} \caption{A program that uses \Vf{printf}\Of{()} to display integers.} \label{pgm:printfInteger} \end{program} Program example~\vref{prg:integralTypes} defines three variables and displays them on the terminal. \begin{program} %[ #include int main( void ) { int i = -40000; /* On 68000 system only. With %%\qc%%, must */ unsigned int j = 400000; /* use a smaller value. */ short sh = -4000; unsigned short ush = 40000; char c = 'A'; printf( "i = %d, sh = %hd\n", i, sh ); printf( "j = %u, ush = %hu\n", j, ush ); printf( "The character c displayed as a character is `%c'\n", c ); printf( "The ASCII value of c is %hd, and in hex it is %hx", c, c ); return 0; } %] In the terminal window you will see: \begin{verbatim} i = -40000, sh = -4000 j = 400000, ush = 40000 The character c displayed as a character is `A' The ASCII value of c is 65, and in hex it is 41 \end{verbatim} \caption{A program that uses \Vf{printf}\Of{()} to display a few variables of type \Kf{int}, \Kf{unsigned int}, \Kf{unsigned short}, \Kf{char}. If you use \qc, an integer must be in the range $-2^{15}..2^{15} - 1$, and an unsigned integer must be in the range $0..2^{16}-1$.} \label{prg:integralTypes} \end{program} \begin{exercise} Write a C program that: \begin{itemize} \item defines three variables: an @int@, a @short@ and a @char@, and \item initialises these three variables to some value, and \item displays the numerical signed value of each variable on the terminal. \end{itemize} \begin{Solution} %[ #include int main( void ) { int i = 27; short sh = 56; char ch = 'C'; printf( "i = %d, sh = %hd, ch = %hd\n", i, sh, ch ); return 0; } %] \end{Solution} \end{exercise} %@- \index{printf@\Vf{printf}\Of{()}!examples|)} \index{printf@\Vf{printf}\Of{()}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Expressions and operators} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{expressions|(} Al Stevens defines an expression on page~25 of his book \cite{stevens} somewhat like this: \index{expression!definition}% An \emph{expression} is a combination of constants, variables, function calls and operators that, when evaluated, have a value. Program example~\vref{prg:expressions} shows some expressions. Note that @getch()@ is a library function, described in section~\vref{sec:getch}. \begin{program}[h] %[ 1 + 2 3 * 4 - 6 > 7 && 27 < 5 conversionConstant * getch() %] \caption{Some examples of expressions.} \label{prg:expressions} \end{program} \index{operators|(} An \emph{expression} is made of one or more \emph{operations}. The objects of the operation(s) are referred to as \emph{operands}. The operations are represented as \emph{operators}. Operators that act on one operand are called \emph{unary} operators. An \emph{operator} is a symbol, like @*@, @+@, \ldots\ that performs an operation on one or two \emph{operands}. These operands are often numbers or variables. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Expressions and operators---C compared with Pascal} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% C has a large number of operators, more than are available in Pascal. See table \vref{tab:operPas} for a comparison that you may use as a reference. \begin{comment} \begin{figure} \newcommand*{\cm}{,\,\,} \begin{center} \begin{tabular}{|l|c|l|} \hline \multicolumn{1}{|c|}{\em Level} & \multicolumn{1}{c|}{\em Operator} & \multicolumn{1}{c|}{\em Function} \\ \hline 16L & @[]@ & array index \\ 16L & @()@ & function call \\ 16L & @()@ & type construction \\ \hline 15R & @sizeof@ & size in bytes \\ 15R & @++@\cm@--@ & increment, decrement \\ 15R & @~@ & bitwise NOT \\ 15R & @!@ & logical NOT \\ 15R & @+@\cm@-@ & unary plus, minus \\ 15R & @*@\cm@&@ & dereference, address-of \\ 15R & @()@ & type conversion (cast) \\ \hline 13L & @*@\cm@/@\cm\textsf{\%} & multiplicative operators \\ \hline 12L & @+@\cm@-@ & arithmetic operators \\ \hline 11L & @<<@\cm@>>@ & bitwise shift \\ \hline 10L & @<@\cm@<=@\cm@>@\cm@>=@ & relational operators \\ \hline 9L & @==@\cm@!=@ & equality, inequality \\ \hline 8L & @&@ & bitwise AND \\ \hline 7L & @^@ & bitwise exclusive-OR \\ \hline 6L & @|@ & bitwise OR \\ \hline 5L & @&&@ & logical AND \\ \hline 4L & @||@ & logical OR \\ \hline 3L & @?:@ & arithmetic if \\ \hline 2R & @=@\cm@*=@\cm@/=@\cm\textsf{\%=} & assignment operators \\ & \textsf{+=}\cm\textsf{$-$=}\cm@<<=@ & \\ & @>>=@\cm@&=@\cm@|=@\cm@^=@ & \\ \hline 1L & @,@ & comma operator \\ \hline \end{tabular} \end{center} \caption{A comparison between Pascal and \Cpph\ operators} \label{tab:operPas} \end{figure} \end{comment} %@- \begin{figure} \newcommand*{\cm}{,\,\,} \centering \small % For SLIDES only, not NOTES \begin{tabular}[!tbh]{@{}ccl@{}} %@+ \toprule \bf C operator & \bf Turbo Pascal & \multicolumn{1}{c}{\bf What it does} \\[-1ex] & \bf equivalent & \\ \midrule @++@ & & increment \\ @--@ & & decrement \\ @!@ & \Kf{not} & \emph{logical} NOT; Don't confuse with @~@\\ @~@ & \Kf{not} & \emph{bitwise} NOT; Don't confuse with @!@ \\ %@- \textsf{$*$}\cm\textsf{\&} & \textsf{\wHt}\cm\textsf{@} & dereference, address-of \\ %@+ % @()@ & @()@ & type conversion (cast) \\ @/@ & @/@\cm\Kf{div} & division operator \\ \textsf{\%} & \Kf{mod} & modulus operator \\ \textsf{$*$} & \textsf{$*$} & multiplication operator \\ @+@\cm@-@ & @+@\cm@-@ & plus, minus \\ @<<@\cm@>>@ & \Kf{shl}\cm\Kf{shr} & \emph{bitwise} shift \\ @<@\cm@<=@\cm@>@\cm@>=@ & @<@\cm@<=@\cm@>@\cm@>=@ & relational operators \\ @==@\cm@!=@ & @=@\cm@<>@ & test for equality, inequality \\ @&@ & \Kf{and} & \emph{bitwise} AND; Don't confuse with @&&@ \\ @^@ & \Kf{xor} & \emph{bitwise} exclusive OR \\ @|@ & \Kf{or} & \emph{bitwise} OR; Don't confuse with @||@ \\ @&&@ & \Kf{and} & \emph{logical} AND; Don't confuse with @&@ \\ @||@ & \Kf{or} & \emph{logical} OR; Don't confuse with @|@ \\ @=@ & @:=@ & assignment \\ @*=@\cm@/=@\cm\textsf{\%=} & no direct & Compound assignment operators \\ @+=@\cm@-=@\cm@<<=@ & Pascal equivalent & \\ @>>=@\cm@&=@\cm@|=@\cm@^=@ && \\ \bottomrule \end{tabular} \caption{A comparison between Pascal and C operators} \label{tab:operPas} \index{operators|textbf} \end{figure} %@+ Standard Pascal provides few of these operators. Most Pascals---including Turbo Pascal---have non-standard extensions to provide some of these facilities. Note that {\em all\/} C compilers provide {\em all\/} these operators (and more). A complete list of every operator available in the C programming language is given for your reference in appendix~\vref{sec:operators}. Some of these operators you already know. Here we examine some you may be less familiar with. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The assignment operator \textmd{\textsf{=}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{assignment|(}% \index{=|(}% Assignment works in the same way in both C and Pascal\e. \index{assignment!lvalue|(}% \index{lvalue|(}% There must be something that can be assigned to on the left of the assignment operator. This is sometimes called an \emph{lvalue}, because it is on the left. The value at that location will change. This must be a value with an address; it cannot be a constant: %[ 2 = 3; /* No, it won't work --- a constant integer is not an lvalue. */ %] You can think of an lvalue as a \emph{location value}. \index{assignment!lvalue|)} \index{lvalue|)} \index{assignment!rvalue|(}% \index{rvalue|(}% The value on the right \emph{can} be a constant. The value on the right side is sometimes called an \emph{rvalue}, because it is on the right side. You can think of it as a \emph{read} value. It is not changed by the assignment. \index{assignment!rvalue|)}% \index{rvalue|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The assignment operator and \IO} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{io@\IO!memory mapped|(} \index{memory mapped \IO|(} %@+ When we do input and output with the MC68000, we use ordinary assignment statements, since the 68000 has \emph{memory-mapped \IOsl}, as discussed in lectures. With a memory-mapped \IO architecture, we use the same instructions for input and output as we use for ordinary memory access. This does \emph{not} mean that hardware---like a register in a 68230 parallel chip---will behave like a variable. In the lab, the name @KEYPAD@ represents the port~A data register, which is connected to the telephone keypad. Suppose we have a byte-sized variable @pattern@ that we use like this: %[ KEYPAD = 6; /* output to the keypad */ pattern = KEYPAD; /* input from the keypad */ %] Do not expect pattern to now have the value 6! This is because the input operation reads the voltages on the pins, while the output operation changes the contents of the flip-flops in the output register. Chapter~\vref{sec:i/o} discusses input and output in detail. %@- \index{io@\IO!memory mapped|)} \index{memory mapped \IO|)} \index{=|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The compound assignment operators} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{assignment!compound operator|(}% There are some ``shorthand'' assignment operators in C that combine an arithmetic or logical operation with assignment. It is probably easiest to show how they work with examples. Program example~\vref{prg:compound} shows many compound assignment operators. \begin{program}[tbph] \begin{notes} %[ /* This program demonstrates the usage of the compound */ /* assignment operators. */ /* The expression @a += b@ is equivalent to @a = a + b@ */ #include int main( void ) { int i, j, k; i = 2; j = 3; k = 4; i += j; /* like @i = i + j;@ */ printf( "The first result is %d\n", i ); i -= j; /* like @i = i - j;@ */ printf( "The second result is %d\n", i ); i *= j; /* like @i = i * j;@ */ printf( "The third result is %d\n", i); i /= j; /* like @i = i / j;@ */ printf( "The fourth result is %d\n", i ); i %= j; /* like @i = i % j;@ the `@%@' is the modulus operator. */ printf( "The fifth result is %d\n", i ); return 0; } %] \end{notes} \begin{slides} \lgrindfile{compound.lg} \end{slides} If you compile and execute this, you will see these results in the terminal window: \begin{verbatim} The first result is 5 The second result is 2 The third result is 6 The fourth result is 2 The fifth result is 2 \end{verbatim} \caption{This program demonstrates the compound assignment operators.} \label{prg:compound} \end{program} \index{assignment!compound operator|)}% \index{assignment|)}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The relational operators} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Both Pascal and C have relational operators. They compare two values and give a result with the value 1 or 0. They are used mostly in the \meta{condition} of an @if@ statement or of @while@ and @for@ loops. The test for equality, @==@ and the test for ``not equals'', @!=@, use different symbols from Pascal, but do the same kind of job. %@- \index{true@\Vf{true}|(} \index{false@\Vf{false}|(} %@+ The C language does not have a different built-in type for the values @true@ and @false@; instead, any value which is zero is equivalent to the value @false@, while any non-zero value is considered to have the logical value @true@. Read section~\vref{sec:trueFalse} for more about this. %@- \index{true@\Vf{true}|)} \index{false@\Vf{false}|)} %@+ \index{assignment operator!compared with equality operator} \index{equality operator!compared with assignment operator} Take care not to confuse the assignment operator, @=@, with the test for equality, @==@. This is easy to do and can give confusing results. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The increment and decrement operators, \textmd{\textsf{++}} and \textmd{\textsf{$--$}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% In this course, we only use these operators in @for@ loops, although the language allows them to be used anywhere. By itself, ``@++i@' has the same meaning as `@i = i + 1@', and by itself, ``@--i@' has the same meaning as `@i = i - 1@'. Appendix~\vref{sec:operators} shows that the `@++@' and `@--@' operators have a high priority. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The logical operators} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% There are three logical operators, logical AND: @&&@, logical OR: @||@ and logical NOT: @!@. The result of these operations is always either @true@ or @false@. They are often used in in the \meta{condition} of an @if@ statement or of @while@ and @for@ loops. They are equivalent to the Pascal keywords \Kf{and}, \Kf{or} and \Kf{not}. Here is an example, which prints the message if @i@ is negative or greater than ten: %[ if ( i < 0 || i > 10 ) printf( "i is out of range.\n" ); %] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The value of \Vf{true} and \Vf{false}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:trueFalse} %@- \index{conditional tests|(} \index{logical value!\Vf{true}|(} \index{logical value!\Vf{false}|(} \index{true@\Vf{true}|(} \index{false@\Vf{false}|(} %@+ The result of an expression with a relational operator is the Boolean value @true@ or @false@. But C has no special @Boolean@ type; in fact, the result of a logical operation is of type @int@. So what is the integer value of @true@ and @false@? The answer for @false@ is that it has the integer value 0; the expression @1 > 2@ has the integer value zero. So what about @true@? The answer is, ``it depends''. The expression @2 > 1@ has the integer value 1. All expressions using logical operators have the integer value 1 or 0. However, as we shall see later, when we \emph{test} the logical value of an expression with an @if@, @for@, @while@ or @do@ statement, if that expression has the value zero, the test has the result @false@, while if it has a non-zero value, the test has the logical result @true@. In your laboratory work, the names @true@ and @false are used frequently. But these are not special keywords in the language---so where do they come from? They are defined in the header file, \texttt{flight.h}. \begin{exercise} %\renewcommand*{\theenumi}{\alph{enumi}} %\renewcommand*{\labelenumi}{(\theenumi)} Give the integer and logical value of the following logical expressions. \begin{enumerate}[(a)] \item @7 == 6@ \item @5 != 7@ \item @5 < 7@ \item @9 > 0@ \item @5 < 7 && 9 < 0@ \item @5 < 7 || 9 < 0@ \item @10 >= 0 && 30 <= 30 || ! ( 50 < 0 ) && 7 - 3 > 5@ \end{enumerate} \begin{Solution} \mbox{}\\ \begin{enumerate}[(a)] \item @7 == 6@ has the integer value 0, which is the logical value @false@. \item @5 != 7@ has the integer value 1, which is the logical value @true@. \item @5 < 7@ has the integer value 1, which is the logical value @true@. \item @9 > 0@ has the integer value 1, which is the logical value @true@. \item @5 < 7 && 9 < 0@ has the integer value 0, which is the logical value @false@. \item @5 < 7 || 9 < 0@ has the integer value 1, which is the logical value @true@. \item @10 >= 0 && 30 <= 30 || ! ( 50 < 0 ) && 7 - 3 > 5@ \end{enumerate} \end{Solution} \end{exercise} %@- \index{conditional tests|)} \index{logical value!\Vf{true}|)} \index{logical value!\Vf{false}|)} \index{true@\Vf{true}|)} \index{false@\Vf{false}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The bitwise operators and bit patterns} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \emph{Bitwise} operations are often required when programming hardware such as the 68230 parallel chip. In the past, the only way to do such operations was to use assembly language. C provides these operations as a standard part of the language, which makes C especially suited to programming microprocessor systems. Very often, we need to \emph{isolate} some particular bits in a \emph{bit pattern}. A bit pattern is an integral type that we use as a collection of individual bits rather than as a number to do arithmetic with. Bit patterns are also sometimes called \emph{bit vectors}. Examples of bit patterns that you have used in the lab include the values you wrote to the \LED{}s. Individual bits turned individual \LED{}s on and off. In C we usually use a hexadecimal base for bit patterns, as it is easier to see where the individual 1s and 0s are in a hexadecimal value than in a decimal value. We may need to \emph{clear} some particular bits to zero. We need to be able to \emph{set} some particular bits to 1. We sometimes need to find the 1's complement of a bit pattern. You also sometimes need to shift a bit pattern left or right. In C, there is an \emph{operator} for each of these operations. Here you will see five \emph{bitwise} operators. They are called bitwise operators because they work with individual bits. Do \emph{not} confuse the bitwise operators with the logical operators. The logical operators have only two possible results---a value of @true@ or @false@---while the bitwise operators can give a wide range of results. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The C bitwise AND operator, \textmd{\textsf{\&}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:and} %@- \index{bitwise AND operator|(} \index{operator!bitwise AND|(} \index{\&@\Of{\&}|(} \index{AND!bitwise operator|(} \index{clearing individual bits|(} %@+ The bitwise AND operator has the symbol @&@. We usually use it for \emph{clearing} individual bits. As an example, we can represent the binary pattern 1100 0011 1010 0101 in our C program with the hexadecimal number @0xc3a5@. Now let us suppose we have an integer with this bit pattern: @int pattern = 0xc3a5;@ Also suppose we only want the bottom nibble (four bits) because we want to display those four bits on the seven segment display. How do we set all the other bits to zero? The answer is to use the bitwise AND operator: @pattern = pattern & 0x000f;@ This applies the AND operation between each corresponding pair of bits. The symbol `$\land$' is the mathematical symbol for `AND'\e. %@- \hspace{3em}\begin{tabular}{@{}l@{}l} 1100\,0011\,1010\,0101 & \\ 0000\,0000\,0000\,1111 & \hspace{0.5em}$\land$ \\ \cline{1-1} 0000\,0000\,0000\,0101 & \end{tabular} %@+ Note that @0xf@ is the same as @0x000f@, that is, on our 68000 systems, they are both 32-bit numbers. See section~\vref{sec:constant}. So the line @pattern = pattern & 0xf;@ will have the same effect. The result is that @pattern@ now has the value @0x0005@, or 5. You should remember how the AND operation works between single bits from your previous course in logic. Program~\vref{prg:and} shows how to clear bits 0, 1, 2 and 3 of a variable, but leaving all other bits unchanged. \index{bitwise complement operator|(} \index{$\sim$|(} \index{NOT!bitwise operator|(} \index{ones' complement operator|(} Note that on \MSDOS systems, integer constants have a size of 2~bytes, while on our 68000 system, integer constants have a size of 4~bytes. This is discussed in section~\vref{sec:intConstants}. So with Turbo~C or \qc, @~0xf@ = @0xfff0@, while on our 68000 system, @~0xf@ = @0xfffffff0@. It is better (because it is more \emph{portable}\footnote{A \emph{portable} program is one that can be compiled on many different systems without change, or with minimum change.} to write @~0xf@ rather than @0xfffffff0@ or @0xfff0@, since @~0xf@ will work in both systems where an @int@ is 2 bytes and where an @int@ is 4 bytes in length. \index{bitwise complement operator|)} \index{$\sim$|)} \index{NOT!bitwise operator|)} \index{ones' complement operator|)} \begin{program} %[ #include int main( void ) { int pattern = 0x4567; int pattern2 = pattern & ~0xf; printf( "pattern = %x, and pattern & ~0xf = %x.\n", pattern, pattern2 ); return 0; } %] \caption{A program that shows how to use the bitwise AND operator `\Of{\&}' to clear bits 0, 1, 2 and 3 of an integer variable.} \label{prg:and} \end{program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{Using bitwise AND to examine the ROW bits in the keypad} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:keyand} Here is an example relevant to reading a keypad. To understand this better, read section~\vref{sec:keypad} first. It may also help to read your laboratory sheet about keypads. Suppose we have a variable, @pattern@, which is a byte-sized variable into which we read the value from the port connected to the keypad: %[ unsigned char pattern; pattern = KEYPAD; %] Now we want to read the row bits (\ie bits 3 to 6 of port A) and see if they are all 1s or if some of them are not 1. If they are all 1, then no key in the current column was pressed. Otherwise, a key in the current column could have been pressed. The problem is that the other bits could have other values which we are not interested in. How do we find out if a key was pressed? Let me write the bits in the byte @pattern@. The bits in @pattern@ correspond to the bits from port A. \begin{center} \begin{tabular}{l|cccccccc} Bit number & PA$_7$ & PA$_6$ & PA$_5$ & PA$_4$ & PA$_3$ & PA$_2$ & PA$_1$ & PA$_0$ \\ Mask value & 0 & 1 & 1 & 1 & 1 & 0 & 0 & 0 \\ \end{tabular} \end{center} If we bitwise AND @pattern@ with the binary number shown as the ``mask value'' in the table above, then all the other bits in @pattern@ that we are not interested in will be set to zero. The binary number 0111\,1000$_2$ is 78\hex{} in hexadecimal. In C we would write this as @0x78@. To clear bits 0, 1, 2 and 7 of @pattern@, we can write: @pattern = pattern & 0x78;@ Here we call @0x78@ a \emph{bit mask} because we are using it to hide the value of bits 0, 1, 2 and 7. But how do we find out if a key was pressed? Well, @pattern@ will now have the value @0x78@ if bits 3, 4, 5 and 6 are set to 1, so we can test if these bits are all 1 by: %[ if ( pattern == 0x78 ) /* Then no key was pressed in this column */ else /* A key was pressed */ %] The symbol ``@==@'' is a test for ``is equal to''. We can also use the symbol ``@!=@'' to test for ``not equal to''. Pascal provides the symbol \textsf{$<>$} to mean the same thing. %@- \index{bitwise AND operator|)} \index{operator!bitwise AND|)} \index{\&@\Of{\&}|)} \index{AND!bitwise operator|)} \index{clearing individual bits|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The C bitwise OR operator, \textmd{\textsf{\textbar}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{bitwise OR operator|(} \index{operator!bitwise OR|(} \index{\textbar@\Of{\textbar}|(} \index{OR!bitwise operator|(} \index{setting individual bits|(} %@+ The bitwise OR operator has the symbol @|@. We usually use it for \emph{setting} individual bits. Let's see an example. We have a number where we want to set the three bits numbers 4, 5 and 6 in the second nibble but leave all the other bits as they were: @int pattern = 0x45a6;@ If we OR this bit pattern with the pattern @0x0070@, we will set the bits 4, 5 and 6 but leave all the other bits as they were: @pattern = pattern | 0x0070;@ This applies the OR operation between corresponding bits. The symbol `$\lor$' is the mathematical symbol for the OR operator. %@- \hspace{3em}\begin{tabular}{@{}l@{}l} 0100\,0101\,1010\,0110 & \\ 0000\,0000\,0111\,0000 & \hspace{0.5em}$\lor$ \\ \cline{1-1} 0100\,0101\,1111\,0110 & \end{tabular} %@+ The result is that @pattern@ now has the value @0x45f6@. Program~\vref{prg:or} shows the use of the bitwise OR operator. \begin{program} %[ /* The use of the bitwise OR operator */ #include int main( void ) { int i = 0xf; int j = 0x12; int k; k = i | j; printf( "The bitwise OR of 0x%x and 0x%x is: \n", i, j ); printf( "0x%x\n", k ); return 0; } %] The terminal output is: \begin{verbatim} The bitwise OR of 0xf and 0x12 is: 0x1f \end{verbatim} The operation is shown below. The symbol `$\lor$' is the mathematical symbol for the OR operator. \vspace{-0.5ex} \begin{center} \begin{math} %@- \begin{array}{@{}l@{}l} 0000\,1111 & \\ 0001\,0010 & \quad\lor \\ \cline{1-1} 0001\,1111 \end{array} %@+ \end{math} \end{center} \caption{This program shows the use of the bitwise~OR operator, `\Of{$\mathsf{|}$}'.} \label{prg:or} \end{program} %@- \index{bitwise OR operator|)} \index{operator!bitwise OR|)} \index{\textbar@\Of{\textbar}|)} \index{OR!bitwise operator|)} \index{setting individual bits|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \subsubsection{The C bitwise NOT operator, \textmd{\textsf{\~\relax}}} \subsubsection{The C bitwise NOT operator, $\sim$} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{bitwise complement operator|(} \index{operator!bitwise NOT|(} \index{bitwise NOT operator|(} \index{$\sim$|(} \index{NOT!bitwise operator|(} \index{ones' complement operator|(} The bitwise NOT operator has the symbol @~@. We use it to get the ones' complement of an integer number. If we apply the bitwise NOT operator to a number, the bits that had the value `1' are changed to `0', while zero bits are changed to ones. An example: @short pattern = 0x45a6;@ If we apply the NOT operator to this pattern: @pattern = ~pattern;@ each bit is complemented. The symbol `$\lnot$' is the mathematical symbol for `NOT'\e. %@- \hspace{3em}\begin{tabular}{@{}l@{}l} 0100\,0101\,1010\,0110 & \hspace{0.5em}$\lnot$ \\ \cline{1-1} 1011\,1010\,0101\,1001 & \end{tabular} %@+ The result is that @pattern@ now has the value @0xba59@. Another example: On our 68000 system, @~0xf@ has the value @0xfffffff0@, because in our 68000 system, constant values such as @0xf@ are 32-bit integers (See section~\vref{sec:constant}), while with \MSDOS systems @~0xf@ has the value @0xfff0@, since an integer has a size of 16 bits in \MSDOS systems. \index{bitwise complement operator|)} \index{bitwise NOT operator|)} \index{operator!bitwise NOT|)} \index{$\sim$|)} \index{NOT!bitwise operator|)} \index{ones' complement operator|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The C bitwise exclusive-OR operator, \wHt} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{bitwise exclusive-OR operator|(} \index{operator!bitwise exclusive-OR|(} \index{\textasciicircum@\wHt|(} \index{exclusive-OR!bitwise operator|(} \index{toggling individual bits|(} %@+ The bitwise exclusive-OR operator has the symbol @^@. We usually use it for \emph{toggling} individual bits. The word `toggle' \index{toggle!meaning}means we change a `1' bit to a `0' and a `0' to a `1'. Another way to say this is that we can selectively \emph{complement} individual bits. That is different from the complement operator, `@~@', which complements \emph{all} the bits. Let's see an example. We have a number where we want to toggle the three bits numbers 4, 5 and 6 in the second nibble but leave all the other bits as they were: @int pattern = 0x45a6;@ If we exclusive-OR this bit pattern with the pattern @0x0070@, we will toggle the bits 4, 5 and 6 but leave all the other bits as they were: @pattern = pattern ^ 0x0070;@ This applies the exclusive-OR operation between corresponding bits. The symbol `$\oplus$' is the mathematical symbol for the exclusive-OR operator. %@- \hspace{3em}\begin{tabular}{@{}l@{}l} 0100\,0101\,1010\,0110 & \\ 0000\,0000\,0111\,0000 & \hspace{0.5em}$\oplus$ \\ \cline{1-1} 0100\,0101\,1101\,0110 & \end{tabular} %@+ The result is that @pattern@ now has the value @0x45d6@. Program~\vref{prg:xor} shows the use of the bitwise exclusive-OR operator. \begin{program} %[ /* The use of the bitwise exclusive-OR operator */ #include int main( void ) { int i = 0xf; int j = 0x12; int k; k = i ^ j; printf( "The bitwise exclusive-OR of 0x%x and 0x%x is: \n", i, j ); printf( "0x%x\n", k ); return 0; } %] The terminal output is: \begin{verbatim} The bitwise exclusive-OR of 0xf and 0x12 is: 0x1d \end{verbatim} The operation is shown below. The symbol `$\oplus$' is the mathematical symbol for the exclusive-OR operator. \vspace{-0.5ex} \begin{center} \begin{math} %@- \begin{array}{@{}l@{}l} 0000\,1111 & \\ 0001\,0010 & \quad\lor \\ \cline{1-1} 0001\,1101 \end{array} %@+ \end{math} \end{center} \caption{This program shows the use of the bitwise~exclusive-OR operator, `\wHt'.} \label{prg:xor} \end{program} %@- \index{bitwise exclusive-OR operator|)} \index{operator!bitwise exclusive-OR|)} \index{\textasciicircum@\wHt|)} \index{exclusive-OR!bitwise operator|)} \index{toggling individual bits|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The shift operators, \Lsh\ and \Rsh} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{bitwise shift operators|(} \index{operator!bitwise shift|(} \index{\Lsh|(} \index{\Rsh|(} \index{left shift!bitwise operator|(} \index{right shift!bitwise operator|(} \index{shifting bit patterns|(} C provides two \emph{shift operators}, the left shift: @<<@ and the right shift: @>>@. These are useful for accessing individual bits of a bit pattern. They shift the bits of the left operand some number of positions to the left or right. %[ unsigned char bits = 1; /* 0000 0001 */ bits = bits << 1; /* 0000 0010 */ bits = bits << 2; /* 0000 1000 */ bits = bits >> 3; /* 0000 0001 */ %] \index{bitwise shift operators|)} \index{operator!bitwise shift|)} \index{\Lsh|)} \index{\Rsh|)} \index{left shift!bitwise operator|)} \index{right shift!bitwise operator|)} \index{shifting bit patterns|)} \index{operators|)} \index{expressions|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Statements} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:statements} \index{statement!definition}% A \emph{statement} is the smallest unit in a program that can be executed. Each statements is terminated with a semicolon. A statement may consist of one or more expressions. Program \index{statement!examples}% example~\vref{prg:statements} gives examples of six simple statements. Note that the @if@ statement and @while@ statement occupy two program lines each. The other four statements occupy one program line each. The functions @getch()@ and @kbhit()@ are library functions discussed in section~\vref{sec:getch} and section~\vref{sec:kbhit}. You have used the library function @DelayMs()@ before; it is described in section~\vref{sec:delayMs}. \begin{program} %[ ++i; DelayMs( 300 ); j = i + k | m + getch(); if ( kbhit() ) c = getch(); while( ! kbhit() ) ; printf( "A key was pressed on the PC.\n" ); %] \caption{examples of valid statements in C.} \label{prg:statements} \end{program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The null statement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The simplest statement is the empty or null statement: %[ ; /* a null statement */ %] A null statement is sometimes used with a @for@ or @while@ loop. See program example~\vref{prg:delayMs} for an example using a null statement in the @DelayMs()@ function. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Compound statements} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:block} \index{statement!compound|(} A \ix{compound statement} is used often used for the body of a @if@ statement or @while@ or @for@ loops when you need more than a single statement to be executed. A compound statement is a sequence of single statements surrounded by braces `@{@' and `@}@'. The body of a loop is a single statement or compound statement that can be repeated. %[ for ( i = 0; i < 16; ++i ) { WriteSevenSegment( i, false ); DelayMs( 200 ); } %] It is not necessary to terminate a compound statement with a semicolon. Note that @WriteSevenSegment()@ and @DelayMs()@ are library functions, described in sections~\vref{sec:writeSevenSegment} and \vref{sec:delayMs}. \index{block} You may declare local variables at the beginning of any compound statement. Such a compound statement is called a \emph{block}. These variables will be only available inside that block. \index{statement!compound|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{\Kf{if} statement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The syntax of the \Kf{if} statement is: %[ if ( expression ) statement_1; else statement_2; %] If the \Vf{expression} evaluates to a nonzero value, the condition is considered to be true and \Vf{statement\_1} is executed; otherwise, \Vf{statement\_2} is executed. Note that if \Vf{statement\_1} is not a compound statement, it \emph{must} be terminated with a semicolon. This is different from Pascal, where a semicolon there is illegal. The C compiler will report a syntax error if you leave out a semicolon there. The @else@ part is optional: %[ if ( expression ) statement_1; %] A statement may also be another @if@ statement: %[ if ( expr1 ) statement_1; else if ( expr2 ) statement_2; else if ( expr3 ) statement_3; /* more @if@ ... @else if@ statements ... */ else statement_n; %] I recommend using this indentation style for such nested @if@ statements. Note that the @if@ statement is \emph{not} a loop! Program example~\vref{prg:ifMod} shows the use of @if@ and the modulus operator, \Of{\%}. \begin{program} %[ /* Uses an @if@ statement and the modulus operator */ /* This is a program to test if a number is odd or even */ #include int main( void ) { int i, temp; printf( "Input a number using the key pad \n" ); i = GetNum(); /* The function get a number from the key pad */ temp = i % 2; /* Find the remainder */ if ( temp == 1) printf( "The number is odd \n" ); else printf( "The number is even \n" ); return 0; } %] \caption{A program that uses an \Kf{if} statement and the modulus operator, `\Of{\%}'.} \label{prg:ifMod} \end{program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The \Kf{while} statement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{while@\Kf{while} statement|(} \index{statement!\Kf{while}|(} %@+ The syntax of the \Kf{while} statement is: %[ while ( expression ) statement; %] The \Kf{while} loop works like this: \begin{thinEnumerate} \item Evaluate the \Vf{expression}. \item If the \Vf{condition} is true, execute the \Vf{statement}. \item Go back to the first step. \end{thinEnumerate} Program example~\vref{prg:while} uses a @while@ loop: \begin{program} %[ /* A program which calculates %$\dsum\sb{i=1}^k i$% for %$k = 1,\ldots,5$% using a @while@ loop. */ #include int main( void ) { int sum, i; i = 1; sum = 0; printf( " i sum from 1 to i\n" ); printf( " --- ---------------\n" ); while ( i <= 5 ) { sum = sum + i; printf( " %d %d\n", i, sum ); ++i; } return 0; } %] The output in the terminal window is:\label{sec:whileExamp} \begin{verbatim} i sum from 1 to i --- --------------- 1 1 2 3 3 6 4 10 5 15 \end{verbatim} \caption{A program using \Kf{while}.} \label{prg:while} \end{program} %@- \index{while@\Kf{while} statement|)} \index{statement!\Kf{while}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The \Kf{for} statement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{for@\Kf{for} statement|(} \index{statement!\Kf{for}|(} %@+ A \Kf{for} loop is often used for processing fixed length data structures like arrays. The \Cpp\ \Kf{for} loop is more general than the Pascal \Kf{for} loop. %@- \index{expression!in a \Kf{for} statement|(} \index{for@\Kf{for} statement!expressions in|(} %@+ The syntax has the form: %[ for ( init_expression; expression_1; expression_2 ) statement; %] Any of \Vf{init\_expression}, \Vf{expression\_1} or \Vf{expression\_2} can be empty. If all three are empty, we get \textsf{\textbf{for}(;;)}, which is an infinite loop. You could pronounce this ``forever''. \begin{thinItemise} \item \Vf{init\_expression} is an expression. It is usually used to assign to a set of variables. It can be empty, i.e., null. It is executed just once before the loop body is executed. Here are some legal instances of \Vf{init\_expression}: %[ for ( i = 0; ... for ( ; /* null init_expression */ ... for ( lo = 0, hi = max, mid = max / 2; /* three initialisations */ ... %] %for ( char *ptr = GetString(); ... %for ( i = 0, ptr = buf, dbl = 0.0; /* comma operator */ ... \item \Vf{expression\_1} is the loop condition. The \Vf{statement} (the loop body) is executed each time after \Vf{expression\_1} evaluates to true. If \Vf{expression\_1} is empty (null), then it is considered to have the value @true@. Here are some legal instances of \Vf{expression\_1}: %[ for ( ...; index < arraySize; ... ) for ( ...; ptr; ... ) for ( ...; ch = GetNextChar(); ... ) for ( ...; ; /* null expression_1 */ ... ) %] %for ( ...; *st1++ = *st2++; ... ) \item \Vf{expression\_2} is evaluated after each iteration of the loop. It is usually used to modify the variables initialised by \Vf{init\_expression}. Here are some legal instances of \Vf{expression\_2}: %[ for ( ...; ...; ++i ) for ( ...; ...; ++i, --j, ++cnt ) for ( ...; ...; ) /* null expression_2 */ %] %for ( ...; ...; ptr = ptr->next ) \end{thinItemise} Except for the case of an empty \Vf{expression\_1}, and the use of the \Kf{continue} statement (see section~\vref{sec:continue}), shown soon in this lecture, the \Kf{for} statement above is equivalent to the following \Kf{while} loop: %[ init_expression; while ( expression_1 ) { statement; expression_2; } %] %@- \index{expression!in a \Kf{for} statement|)} \index{for@\Kf{for} statement!expressions in|)} %@+ A @for@ loop is useful when a \emph{loop counter} is used. Otherwise, a @while@ loop may be a simpler choice. Really, both types of loop are rather similar, and often it doesn't matter which you use. Program~\vref{prg:for} uses a @for@ loop and is equivalent to program~\vref{prg:while}. \begin{program} %[ #include /* Demonstration of the @for@ loop */ int main( void ) { int sum, i; sum = 0; printf( " i sum from 1 to i\n" ); printf( " --- ---------------\n" ); for ( i = 1 ; i <= 5; ++i ) { sum = sum + i; printf( " %d %d\n", i, sum ); } return 0; } %] The output in the terminal window is the same as the output from the program demonstrating the @while@ loop in section~\vref{sec:whileExamp}. \caption{A program equivalent to \vref{prg:while}, except that it uses a \Kf{for} loop.} \label{prg:for} \end{program} \begin{exercise} \label{ex:forLoopSquare} Write a program that uses a loop to print the square of all the numbers from 10 to 30. The program will use @printf()@. \begin{Solution} Because the program uses @printf()@, we must @#include@ @stdio.h@. %[ #include int main( void ) { int i; for ( i = 10; i <= 30; ++i ) printf ( "%d squared = %d\n", i, i * i ); return 0; } %] \end{Solution} \end{exercise} \begin{exercise} Write a @for@ loop that is equivalent to the following @while@ loop: %[ i = 10; while ( i < 20 ) { SEVEN_SEGMENT = pattern[ SWITCHES & 0xf ]; DelayMs( 200 ); i = i + 1; } %] Note that this loop uses names defined in \texttt{flight.h}, so to test the program you will need to compile it in the laboratory. \begin{Solution} %[ for ( i = 10; i < 20; ++i ) { SEVEN_SEGMENT = pattern[ SWITCHES & 0xf ]; DelayMs( 200 ); } %] \end{Solution} \end{exercise} %@- \index{for@\Kf{for} statement|)} \index{statement!\Kf{for}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The \Kf{do} statement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{do@\Kf{do} statement|(} \index{statement!\Kf{do}|(} %@+ The \Kf{do} loop is used in situations like the Pascal \Kf{repeat} \ldots\ \Kf{until} loop where the body of the loop needs to be executed at least once, perhaps to set up the requirements for the loop control. The syntax of the \Kf{do} loop is: %[ do { statement; } while ( expression ); %] \Vf{statement} is executed before \Vf{expression} is evaluated. If the condition evaluates to false, the \Kf{do} loop terminates. Program~\vref{prg:do} is equivalent to program~\vref{prg:while} and \vref{prg:for}, but it uses a @do@ loop. \begin{program} %[ #include int main( void ) { int sum, i; i = 0; sum = 0; printf( " i sum from 1 to i\n" ); printf( " --- ---------------\n" ); do { sum = sum + i; printf( " %d %d\n", i, sum ); ++i; } while ( i <= 5 ); return 0; } %] \caption{This program uses a \Kf{do} loop, and produces the same output as the \Kf{while} and \Kf{for} loop programs, \vref{prg:while} and \vref{prg:for}.} \label{prg:do} \end{program} \begin{exercise} Write a C program that is equivalent to that given in exercise~\vref{ex:while2For}, but which uses a @do@ loop instead of a @while@ loop. \begin{Solution} %[ #include int main( void ) { int i = 1; do { printf( "i = %d\n", i ); ++i; } while ( i <= 10 ); return 0; } %] \end{Solution} \end{exercise} %@- \index{do@\Kf{do} statement|)} \index{statement!\Kf{do}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Nested loops} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{nested loops|(} \index{loops!nested|(} Loops can be nested inside one another. Program example~\vref{prg:nestedFor} shows how. \begin{program} %[ /* This program demonstrates nested loops */ #include int main( void ) { int i, j, data; for ( i = 1; i <= 5; ++i ) { for ( j = 1; j <= 3; ++j ) { data = i * j; printf( "%d * %d = %d ", i, j, data ); } printf( "\n" ); } return 0; } %] The result is: \begin{verbatim} 1 * 1 = 1 1 * 2 = 2 1 * 3 = 3 2 * 1 = 2 2 * 2 = 4 2 * 3 = 6 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9 4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 \end{verbatim} \caption{A program using two nested \Kf{for} loops.} \label{prg:nestedFor} \end{program} Program~\vref{prg:nestedWhile} is the same program but implemented using two nested @while@ loops. \begin{program} %[ #include int main( void ) { int i, j, data; i = 1; while ( i <= 5 ) { j = 1; while ( j <= 3 ) { data = i * j; printf( "%d * %d = %d ", i, j, data ); ++j; } printf( "\n" ); ++i; } return 0; } %] \caption{A program showing nested \Kf{while} loops. The output in the terminal window is exactly the same as for program~\vref{prg:nestedFor}.} \label{prg:nestedWhile} \end{program} \index{nested loops|)} \index{loops!nested|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The \Kf{break} statement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{break@\Kf{break} statement|(} \index{statement!\Kf{break}|(} %@+ A \Kf{break} statement terminates the smallest enclosing \Kf{while}, \Kf{do}, \Kf{for} or \Kf{switch} statement. Execution resumes at the statement immediately following the terminated statement. \Kf{break} is a very useful statement, missed by some Pascal programmers. This example program shows how the @break@ statement can be used. \begin{program} %[ /* The @break@ statement */ /* Test the key pad */ #include int main( void ) { int i; while ( true ) { printf( "Press '2' on the key pad\n" ); i = GetNum(); if ( i == 2 ) break; } printf ( "The key '2' key is ok." ); return 0; } %] \caption{Using the \Kf{break} statement.} \label{prg:break} \end{program} %@- \index{break@\Kf{break} statement|)} \index{statement!\Kf{break}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The \Kf{continue} statement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:continue} %@- \index{continue@\Kf{continue} statement|(} \index{statement!\Kf{continue}|(} %@+ A \Kf{continue} statement causes the current iteration of the nearest enclosing \Kf{while}, \Kf{for} or \Kf{do} loop to terminate. In \Kf{while} and \Kf{do} loops, execution resumes with the evaluation of the control \Vf{expression}. In \Kf{for} loops, \Kf{continue} causes execution to resume with the evaluation of \Vf{expression\_2}. Unlike the \Kf{break} statement, which terminates the loop, the \Kf{continue} statement terminates only the current iteration. In this example, the telephone keypad in the lab is read continuously. If not all row inputs are high (if not all of the bits 3, 4, 5 and 6 of port A are 1), then a key has been pressed and the keystroke is processed, otherwise the current loop iteration is terminated: %[ while ( ! keyPressed ) { pattern = KEYPAD & 0x78; if ( pattern == 0x78 ) continue; /* terminate this iteration, since no key has been pressed */ /* %%\ldots%% process this keystroke %%\ldots%% */ } %] Program~\vref{prg:continue} shows the use of the @continue@ statement: \begin{program} %[ /* This program calculates 1 + 2 + 3 + 4 + 6 + 7 + 8 + 9. Notice that the sum skips adding 5 because of the @continue@ statement. */ #include int main( void ) { int i; int sum = 0; for ( i = 1 ; i < 10 ; ++i ) { if ( i == 5 ) continue; sum = sum + i; } printf( "The sum is %d.", sum ); return 0; } %] The terminal screen will show: \begin{verbatim} The sum is 40. \end{verbatim} \caption{A program demonstrating the \Kf{continue} statement.} \label{prg:continue} \end{program} %@- \index{continue@\Kf{continue} statement|)} \index{statement!\Kf{continue}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Arrays} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:arrays} \index{arrays|(} \index{lookup table|(} \index{table|(} % In the program in figure~\ref{fig:sevsegprog} on % page~\pageref{fig:sevsegprog}, you have an \emph{array} called % @sevenSegPattern@. What is an array? \textbf{An array is a table which contains a number of things of the same type, such as bit patterns.} The ``things'' in the array are called \emph{elements} of the array. Each element is accessed by a number called an \emph{index} or \emph{subscript}. The first element in the array has the index 0, the next has the index 1, and so on. To access an element, we put the index for that element in square brackets @[ ]@ after the array name. An array is also sometimes called a \emph{lookup table}. An array has a particular \emph{length}. We write the length when we \emph{declare} the array. As an example, here is a declaration for an array of 10 integers: %[ int table[ 10 ] = { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 }; %] This array has been \emph{initialised} with the numbers 5, 10, 15, \ldots 45, 50. The name of this array is @table@. Its length is 10. Notice that there is a semicolon `@;@' after the closing brace. We can access each of these ten elements by \emph{indexing} the array with a number in the range 0~to~9. For example, to find the value of the element 20, which has the index 3, we can find the value of @table[ 3 ]@. If $N$ is the length of the array, then legal indexes are in the range 0 to $N - 1$. Note that the length (here 10) is out of range for legal indexes. The first element in this array is accessed as @table[ 0 ]@. We can assign this value to another variable, or copy it to one of the ports on the parallel chip. %[ /* Create a local integer variable called @tableValue@ and initialise it with the value of the first element in @table@: */ int tableValue = table[ 0 ]; /* @tableValue@ now equals 5. */ %] The index for the element 10 is 1, and we access it as @table[ 1 ]@. Similarly, we access elements 15, 20, 25, 30, 35, 40, 45 and 50 as @table[ 2 ]@, @table[ 3 ]@, @table[ 4 ]@, @table[ 5 ]@, @table[ 6 ]@, @table[ 7 ]@, @table[ 8 ]@ and @table[ 9 ]@, respectively. \begin{exercise} Write a C program that: \begin{itemize} \item defines an array of ten integers \item initialises the array to the values @1..10@ \item adds the contents of the array together in a loop \item prints the sum on the terminal \end{itemize} \begin{Solution} %[ #include int table[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; /* Initialise at compile time. */ int main( void ) { int i, sum = 0; for ( i = 0; i < 10; ++i ) sum = sum + table[ i ]; /* could write: @sum += table[ i ];@ */ printf( "The sum of the numbers is %d\n", sum ); return 0; } %] Here is another solution which assigns the @table[]@ values rather than initialises the array: %[ #include int table[ 10 ]; int main( void ) { int i, sum = 0; for ( i = 0; i < 10; ++i ) table[ i ] = i + 1; /* Assign at run time. */ for ( i = 0; i < 10; ++i ) sum = sum + table[ i ]; printf( "The sum of the numbers is %d\n", sum ); return 0; } %] \end{Solution} \end{exercise} \begin{exercise} Write a program that \begin{itemize} \item Contains the definition of an array of 10 integers \item Initialises the first array element to 1, the second to 2, the third to 3, and so on, so that the last element has the value 10. Use a loop to do this. \item Prints out the contents of the array using a second loop and the @printf()@ function. \end{itemize} \begin{Solution} %[ #include < stdio.h> #define LEN 10 int array[ LEN ]; int main( void ) { int i; for ( i = 0; i < LEN; ++i ) array[ i ] = i + 1; for ( i = 0; i < LEN; ++i ) printf( "array[ %d ] = %d\n", i, array[ i ] ); return 0; } %] \end{Solution} \end{exercise} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Array indexing errors} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The last element in this array is @table[ 9 ]@. It has the value 50. If we index an array with an index that is out of range, then we get an \emph{array indexing error}. The program may still run if it has such an error, but it will give you a number outside of the array if you try to read that value. The result will be unexpected. \emph{\textbf{It is very important that the index to an array be in the range for legal indexes, \ie in the range 0 to $N - 1$, where $N$ is the length of the array.}} How can you make sure an index is in the legal range? If the length of the array is a power of two, such as sixteen, as the length of @sevenSegPattern@ is in workshop 2, we can use the bitwise AND operator to clear the bits that make an index bigger than the length of the array. Program~\vref{prg:niceLed} shows the use of an array as a lookup table. Note that if an array is initialised, it is not necessary fo write the length of the array in the definition of the array. \begin{program} %[ #include int pattern[] = { 0x81, 0x42, 0x24, 0x18, 0x24, 0x42 }; int main( void ) { int i; while ( true ) for ( i = 0; i < 6; ++i ) { LEDS = pattern[ i ]; DelayMs( 100 ); } return 0; } %] It causes the eight \LED{}s on the interface board in the laboratory to light up in this pattern: %@- \begin{tabular}{@{}lc@{}} First: & $\bullet \circ \circ \circ \circ \circ \circ \bullet \mbox{}$ \\ then: & $\circ \bullet \circ \circ \circ \circ \bullet \circ \mbox{}$\\ then: & $\circ \circ \bullet \circ \circ \bullet \circ \circ \mbox{}$\\ then: & $\circ \circ \circ \bullet \bullet \circ \circ \circ \mbox{}$\\ then: & $\circ \circ \bullet \circ \circ \bullet \circ \circ \mbox{}$\\ then: & $\circ \bullet \circ \circ \circ \circ \bullet \circ \mbox{}$ \end{tabular}\\ %@+ and so on, endlessly. \caption{A program to use an array to look up patterns to display on the \LED{}s in the laboratory.} \label{prg:niceLed} \end{program} \index{sort!bubble|(} \index{bubble sort|(} Program~\vref{prg:bsort} is another example which uses a nested @for@ loop to process an array. This is called a \emph{bubble sort}; it is a simple method of sorting an array. To understand this algorithm properly, I suggest you read the beginning of chapter~23 of \cite{perry}. \index{bubble sort|)} \index{sort!bubble|)} \begin{program} %[ /* An example of nested @for@ loops using an array */ #include #define NUM_ITEMS 8 int main( void ) { int i, j, temp; int data[ NUM_ITEMS ] = { 2, 95, 50, 64, 1032, 58, -345, 80 }; for ( i = 0; i < NUM_ITEMS - 1; ++i ) { for ( j = i; j < NUM_ITEMS; ++j ) { if ( data[ j ] > data [ i ] ) { /* swap them: move bigger numbers towards beginning of array */ temp = data [ j ]; data [ j ] = data [ i ]; data [ i ] = temp; } } } printf( "The sorted data is:\n" ); for ( i = 0; i < NUM_ITEMS; ++i ) printf( "%d\n", data[ i ] ); return 0; } %] The terminal will show: \begin{verbatim} The sorted data is: 1032 95 80 64 58 50 2 -345 \end{verbatim} \caption{A program that uses a nested \Kf{for} loop to sort an array. (This is called a \emph{bubble sort}).} \label{prg:bsort} \end{program} \begin{exercise} \label{ex:while2For} Write a C program that is equivalent to the following program, but which uses a @for@ loop instead of a @while@ loop. %[ #include int main( void ) { int i = 0; while ( i < 10 ) { printf( "i = %d\n", i ); ++i; } return 0; } %] \begin{Solution} %[ #include int main( void ) { int i; for ( i = 0; i < 10; ++i ) printf( "i = %d\n", i ); return 0; } %] \end{Solution} \end{exercise} \begin{exercise} There are two array indexing errors in this program. Show where they are and change the program so that all of the elements of the array are accessed without an array indexing error. %[ #include #define NUMPATTERNS 8 unsigned char patterns[ NUMPATTERNS ] = { 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff }; int main( void ) { int i; for ( i = 1; i <= NUMPATTERNS; ++i ) SEVEN_SEGMENT = patterns[ i ]; return 0; } %] \begin{Solution} The problem is that the index for @patterns[]@, which is @i@, takes the values 1,~2,\ldots,9,~10 instead of the values 0,~1,\ldots,8,~9. There is an array indexing error at each end of the array. By starting with the index~1 instead of~0, the first element in the array is missed. More seriously, the last index used by this program causes the computer to access memory past the end of the array. The value that this memory location holds is unknown. To solve this, change the @for@ loop to: %[ for ( i = 0; i < NUMPATTERNS; ++i ) %] Notice that there are \emph{two} changes to this line. There is one other thing about this program: it will display the patterns so quickly on the seven segment display that only the last pattern will be seen. To be able to see all the patterns, it will be necessary to put a delay in the loop. A call to the function @Delay()@ given in question~\vref{ex:delay} will do the job. Alternatively you could put a call to the library function @DelayMs()@ described in section~\vref{sec:delayMs}. The loop would then look something like this: %[ for ( i = 0; i < NUMPATTERNS; ++i ) { SEVEN_SEGMENT = patterns[ i ]; DelayMs( 500 ); } %] \end{Solution} \end{exercise} \index{arrays|)} \index{lookup table|)} \index{table|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Functions} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{functions|(} Pascal provides both functions and procedures. In C, all subroutines are called \emph{functions}. A function is a group of program statements that contain a single idea or algorithm, and that has a name. The function may be called from anywhere in the program, and when it has finished, it returns control to the place immediately after where it was called. Functions are used mainly: \begin{itemize} \item to organise the program into smaller units that each do a simple, well-defined job. This makes a complicated program easier to write and understand. \item to reduce the size of a program since they can be called repeatedly from many different places in the program. \end{itemize} The format of a function \emph{definition} is: %[ return_type FunctionName( parameter_list ) { local_variable_definitions; zero_or_more_statements; } %] A function often \emph{returns} a value, such as the function @min()@ below, which has the value of the smaller of its parameters. The parameters (or arguments) passed to a function where it is called are the {\em actual parameters}. The parameters when referred to from inside the function are the \emph{formal parameters}. In the following example, the formal parameters are @a@ and @b@. The actual parameters are @i@ and @j@. The formal parameters are simply local \emph{copies} of the actual parameters. The example program~\vref{prg:parameters} shows parameters passed to a @min()@ function. \begin{program} %[ int min( int a, int b ) { if ( a < b ) return a; else return b; } int main( void ) { int i = 1, j = 2; int k = min( i, j ); /* @k@ = 1. */ return 0; } %] \caption{A program that shows parameters begin passed to a function.} \label{prg:parameters} \end{program} A \emph{function prototype} is the \emph{declaration} of a function, consisting of the return type, name and parameter list. You may put the same function prototype as many times as you like in a file. The function prototype for the @min()@ function is %[ int min( int a, int b ); %] The best arrangement is to put all function prototypes in header files, and to include them with @#include "..."@ whenever the definitions of those functions are used. Section~\vref{sec:library} shows some library functions together with their prototypes. Look there for more examples of function prototypes. Maintenance of a program with many declarations for each function is more difficult. There should be only one declaration to avoid such problems. As in Pascal, C functions can be called recursively. This means that a function can call itself. \begin{exercise} Write a function @Leds()@ in C that will simulate the eight \LED{}s you used in the laboratory. Your function will take one parameter so that if a bit in the parameter is zero, the character in that position will be a dot `\texttt{.}', and if that bit is a one, the character in that position will be a `\texttt{o}'. Each time your function is called, it will display eight of the characters, either `\texttt{.}' or `\texttt{o}' on one line. The next time it is called, it will display eight characters on the next line. Following is a program that is complete except that it is missing the body of the fucntion @Leds()@. The output of the program follows. %[ #include #define NUMPATTERNS 6 void Leds( unsigned char pattern ) { /* The body of @Leds()@ is missing here: your exercise is to write it. */ } %* unsigned char pattern[ NUMPATTERNS ] = { 0x81, 0x42, 0x24, 0x18, 0x24, 0x42 }; %* int main( void ) { int i, j; for ( j = 0; j < 3; ++j ) for ( i = 0; i < NUMPATTERNS; ++i ) Leds( pattern[ i ] ); return 0; } %] The output on the terminal should look like this: {\scriptsize \begin{verbatim} o......o .o....o. ..o..o.. ...oo... ..o..o.. .o....o. o......o .o....o. ..o..o.. ...oo... ..o..o.. .o....o. o......o .o....o. ..o..o.. ...oo... ..o..o.. .o....o. \end{verbatim} } \begin{Solution} %[ void Leds( unsigned char pattern ) { int i; for ( i = 7; i >= 0; --i ) { if ( pattern & ( 1 << i ) ) printf( "o" ); else printf( "." ); } printf( "\n" ); } %] \end{Solution} \end{exercise} \begin{exercise} \label{ex:sevSeg} Write a function @SevenSegment()@in C that will simulate the seven segment display you use in the laboratory. The function shall take one parameter and shall display a figure on the terminal using the \ASCII characters `\texttt{\_}', `\texttt{\textbar}', the space character, the newline character `\texttt{\textbackslash{}n}' and the `\texttt{.}' character to represent the decimal point. One seven-segment figure will be displayed per line, so that the following program (which is complete except that it is missing the body of the function @SevenSegment()@) will produce the output that is shown after: %[ #include void SevenSegment( unsigned char pattern ) { /* The body of @SevenSegment()@ is missing here: your exercise is to write it. */ } %* unsigned char sevSegPattern[] = { 0x3f, 6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 7, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; %* int main( void ) { int i; unsigned char pattern; for ( i = 0; i < 16; ++i ) { pattern = sevSegPattern[ i ]; SevenSegment( pattern ); } /* Now show with the decimal point on: */ for ( i = 0; i < 16; ++i ) { pattern = sevSegPattern[ i ] | 0x80; SevenSegment( pattern ); } return 0; } %] %|- The output on the terminal should look something like that shown in figure\vref{ex:sevSeg}, although I have used four columns here to save paper, while your program should display each digit on the left side of the terminal window. \begin{figure} \begin{multicols}{4} \scriptsize \begin{verbatim} _ | | |_| | | _ _| |_ _ _| _| |_| | _ |_ _| _ |_ |_| _ | | _ |_| |_| _ |_| _| _ |_| | | |_ |_| _ | |_ _| |_| _ |_ |_ _ |_ | _ | | |_|. | |. _ _| |_ . _ _| _|. |_| |. _ |_ _|. _ |_ |_|. _ | |. _ |_| |_|. _ |_| _|. _ |_| | |. |_ |_|. _ | |_ . _| |_|. _ |_ |_ . _ |_ | . \end{verbatim} \end{multicols} \caption{The output required for the program in exercise~\vref{ex:sevSeg}.} \label{fig:sevSegOutput} \end{figure} Note that you will want to use the bitwise AND operator `@&@' here: the idea is that your function should be able to behave as much like a physical seven segment display as possible. \begin{Solution} Refer to figure~\vref{fig:sevenseg}. %[\medskip #define a 1 #define b 2 #define c 4 #define d 8 #define e 0x10 #define f 0x20 #define g 0x40 #define DP 0x80 void SevenSegment( unsigned char pattern ) { if ( pattern & a ) printf( " _ \n" ); else printf( " \n" ); if ( pattern & f ) printf( "|" ); else printf( " " ); if ( pattern & g ) printf( "_" ); else printf( " " ); if ( pattern & b ) printf( "|\n" ); else printf( " \n" ); if ( pattern & e ) printf( "|" ); else printf( " " ); if ( pattern & d ) printf( "_" ); else printf( " " ); if ( pattern & c ) printf( "|" ); else printf( " " ); if ( pattern & DP ) printf( ".\n" ); else printf( " \n" ); } %]\relax \end{Solution} \end{exercise} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Function return values} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% In Pascal, a function returns a value when you assign a value to the name of the function inside the body of the function. In C, you use the keyword @return@. C functions behave in much the same way as they do in Pascal. A function can return a single item of almost any type. %@- \index{void@\Kf{void}!return type} %@+ A function of return type @void@ is just like a Pascal procedure; it does not return any value. A function with no return type specified is assumed to return @int@. \textbf{\emph{Please do not rely on this\nocorr}}, since it sometimes means that the programmer forgot to write in the return type rather than that @int@ was intended. A function of return type @void@ does not need a @return@ statement. All other functions must @return@ a value. They must have at least one @return@ statement followed by an expression that can be converted to the return type, like @min()@ above. When the @return@ statement is executed, no more statements are executed in the body of the function, even if there are more statements after the @return@ statement. Program example~\vref{prg:silly} shows how @return@ terminates a function. \begin{program} %[ #include int Silly( void ) { int i; return 6; /* Nothing after the @return@ statement will be executed. */ for ( i = 0; i < 20; ++i ) printf( "This will never be executed.\n" ); } int main( void ) { int j = Silly(); printf( "the return value of Silly() is %d\n", j ); return 0; } %] The output on the terminal will be: \begin{verbatim} the return value of Silly() is 6 \end{verbatim} \caption{A program that calls a \Vf{Silly}\Of{()} function that shows how \Kf{return} terminates execution of a function.} \label{prg:silly} \end{program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The return type of \textmd{\textsf{\textit{main}()}}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The @main()@ function is special, in that the return type is required by the \ANSI standard to be of type @int@. The purpose of the return value of @main()@ is to indicate whether an error occurred or if the program was successful. This is used either by the operating system if there is one, or in the case of the \FLIGHT boards to indicate the terminating condition of the program through the terminal program. If the program is successful, the convention is that it returns zero. If there is an error, then @main()@ will return a non-zero error number. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The function parameter list} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{signature of a function} \index{function!signature} The \ix{parameter list} is often called the \emph{signature} of the function, because the parameter list is often used to tell one function from another. %@- \index{void@\Kf{void}!in parameter list} %@+ When we call a function, it must always have a parameter list, even if that list is empty, unlike Pascal. When we define a function where the parameter list contains the single keyword `@void@', it means that function takes no parameters. Every program must contain a @main()@ function. In our course, we put @void@ in @main()@'s parameter list to show that @main()@ has an empty parameter list. Other functions take parameters. Parameters are like the \emph{inputs} to the function. The return value of the function is its \emph{output}. When we \emph{define} a function, we put the type before each parameter and then a \emph{name} for each corresponding parameter. This applies to all parameters in the parameter list when we define the function. The name of each parameter is the name of the \emph{formal parameter}. \index{formal parameter}% \index{function!formal parameter}% The name \emph{formal parameter} is just a term that indicates the name of the parameter when we are \emph{defining} the function. When we \emph{call} a function, we do \emph{not} write the type: we just put the name of the parameter. As mentioned previously, the name of each parameter when we call the function is the name of each \emph{actual parameter}. Note that the name \emph{actual parameter} \index{actual parameter}% \index{function!actual parameter}% is just a term that means the name of the parameter when we \emph{call} the function. Note too that we can just use a constant value as the actual parameter, as in this call to the library function @DelayMS()@: %[ DelayMs( 200 ); /* delay 200 milliseconds. */ %] \index{function!termination|(} When we call a function, the value of the actual parameter is copied into the formal parameter. Formal parameters stop existing when the current execution of the function terminates. Execution of a function terminates either when a @return@ statement is executed in the body of that function, or when execution reaches the last closing brace %{ For brace matching algorithms. `@}@' of the body of the function. \index{function!termination|)} \begin{exercise} \label{ex:delay} The keyword @void@ appears twice in this function @Delay()@. What does it mean in each case? %[ void Delay( void ) { int i; for ( i = 0; i < 100000; ++i ) ; /* Do nothing; just increment the counter. */ } %] \begin{Solution} %@- \index{void@\Kf{void}!return type} %@+ The first @void@ (to the left of the name of the function @Delay@) means that the function @Delay()@ returns no value at all. It also means that we cannot put a @return@ statement in @Delay()@ that returns a value---for example, the compiler would not allow you to put @return 0;@ in the body of the @Delay()@ function. %@- \index{void@\Kf{void}!in parameter list} %@+ The second @void@, the one in the parentheses, means that @Delay()@ takes no parameters. In other words, no additional data is required by the @Delay()@ function to decide what it should do---it delays by looping a \emph{fixed} number of times. \end{Solution} \end{exercise} \begin{exercise} The formula to convert Fahrenheit temperatures to Centigrade is $C = 5 \times (F - 32) \div 9$. Write a function to convert Fahrenheit degrees to Centigrade. The function will take one integer parameter and will return a value of type integer. Write a complete program that calls this function. \begin{Solution} %[ #include int FtoC( int fahrenheit ) { return 5 * ( fahrenheit - 32 ) / 9; } %* int main( void ) { int centigrade; centigrade = FtoC( 75 ); printf( "75 degrees Fahrenheit is %d Centigrade.\n", centigrade ); return 0; } %] \end{Solution} \end{exercise} \begin{exercise} Write a function @Max()@ that takes two integer numbers as parameters and returns the larger of the two. The function will return a value of type @int@. Write a complete program that calls this function. \begin{Solution} %[ #include %* int Max( int a, int b ) { if ( a > b ) return a; else return b; } %* int main( void ) { int i = 40; int k = 54; int biggest; biggest = Max( i, k ); printf( "The biggest of i and k is %d.\n", biggest ); return 0; } %] \end{Solution} \end{exercise} \begin{exercise} This exercise is similar to exercise~\vref{ex:forLoopSquare}, but it requires that you write a function. Write a function @Square()@ that takes one integer parameter $n$ and returns one integer parameter which is the square of the parameter, \ie $n^2$. Write a program that uses this function @Square()@ in a loop to print the square of all the numbers from 10 to 30. The program will use @printf()@. \begin{Solution} Because the program uses @printf()@, we must @#include@ @stdio.h@. %[ #include int Square( int n ) { return n * n; } %* int main( void ) { int i; for ( i = 10; i <= 30; ++i ) printf ( "%d squared = %d\n", i, Square( i ) ); return 0; } %] Notice that we can put a function call anywhere inside another function (such as @main()@ here) where we might use a variable. Compare this solution with that for exercise~\vref{ex:forLoopSquare}. \end{Solution} \end{exercise} \begin{exercise} Write a function @Power()@ that takes two integer numbers and raises the first number to the power of the second. The function can return an @int@ result. Write a complete program that calls this function. Execute your program using \qc or a C compiler. \begin{Solution} Assume that the value of @exp@ is positive or zero. @Power()@ calculates $\Vf{base}^{\Vf{exp}}$. %[ #include int Power( int base, int exp ) { int i, p = 1; for ( i = 0; i < exp; ++i ) p = p * base; return p; } %* int main( void ) { int n = Power( 2, 15 ); printf( "2 to the power of 15 is %d\n", n ); /* @n@ = 32768 */ return 0; } %] \end{Solution} \end{exercise} \index{functions|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Indentation of your programs} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{indentation|(} Notice that all the program examples given to you in lectures and labs are systematically indented and formatted. This makes a program much easier for a human to read. For instance, putting opening and closing braces `@{@' and `@}@' above each other makes it much easier to see if one is missing. Indenting the body of a loop or the body of an @if@ statement makes it much easier to see the flow of the program. There are documents that describe styles of writing programs: one such guide is \cite{IHSG} which is available electronically. A copy is kept in the laboratory. I strongly urge you in your lab work to choose an indentation system and stay with it. A good text editor (such as Emacs or Brief), automatically indents your program as you write it. \index{indentation|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Input and output} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:i/o} %@- \index{port!\IO|(} \index{IO ports@\IO ports|(} %@+ \emph{Input}\index{input} is the transfer of data from outside the computer to inside the computer. \emph{Output}\index{output} is the transfer of data from the computer to the outside world. \begin{itemize} \item \textbf{All input and output takes place through \emph{I/O ports}}. \item An \IO port is a special ``memory'' location \item When the \up reads from an input port, data is transferred from the outside world to the \up \item When the \up writes to an output port, data is transferred from the \up to the outside world. \item An example of an output port is the output port connected to the \LED{}s and the seven segment display. This is port~B data register on the \PIT; we called this @LEDS@ and @SEVEN_SEGMENT@ in our programs. \item An example of an input port is the input port connected to the dip-switches. This is the port~A data register on the \PIT. We called it @SWITCHES@ in our programs.\index{dip switches} \item In our programs, to do output, we put the name of the output port on the \emph{left} side of an assignment statement, e.g., @LEDS = 0xc8;@ \item To do input in our programs, we put the name of the input port anywhere \emph{except} on the left side of an assignment statement, e.g., @j = 47 * SWITCHES;@\index{dip switches} \item The @printf()@ statement causes output; we see a message in the terminal window of the \PC. It gets there by \emph{serial transfer}.\footnote{This is not true for \emph{all} \up systems, since some computers are connected more directly to a video system, such as our \PC{}s.} The serial transfer takes place through the 68681 %@- \index{sixty eight six eight one@68681 \DUART}% \index{DUART@\DUART}% %@+ \DUART. The @printf()@ library function writes to an output port in the \DUART. \item In our assembly language programs, to do \emph{output}, we move the data \emph{to} the port, i.e., the port is the \emph{destination}, e.g., if the A6 register contains the base address of the 68230 parallel chip: \begin{prog} move.b #$c8,leds(a6) \end{prog} \item To do \emph{input} in our assembly language programs, we put the input port as the \emph{source} of an instruction, e.g.,\label{sec:switches(a6)} \begin{prog} add.b switches(a6),d0 \end{prog} \end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{I/O ports and the 68230 parallel interface/\allowbreak{}timer chip} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:ioports} An \IOsl \emph{port} is a special memory location in an input or output hardware interface. An \IO port is a connection between a computer and the outside world. For instance, the keyboard, printer and mouse on a desktop computer all are connected to the \PC through \IO ports. When we read from an input port, we cause input from something outside the computer. Data is transferred from outside to inside the computer through the input port. An input is a special sort of read operation. When we write to an output port, we cause data to be transferred from the computer to hardware that is outside the computer. An output is a special sort of write operation. In a memory-mapped \IO computer, such as the \FLIGHT in our labs, we use ordinary data movement instructions to do input and output, such as \texttt{move} or \texttt{clr}. An input or output port has an ordinary address, like memory. The only difference is that an address decoder selects an \IO chip such as the 68230 \PIT instead of a memory chip. The \IO chip is connected to external hardware so that it may perform input and output. The special memory locations in the 68230 are called registers---they are all listed in table~\vref{tab:registerAddr}. You may read some more about them in the \FLIGHT manual, in chapter 11. You may wish to look at the memory map of the \FLIGHT board, in figure~\vref{fig:memmap}. Here are some examples of input and output operations, as in our lab work. Firstly in C:\index{dip switches} %[ LEDS = 0xf; /* Output: turn on the four %%\LED{}s%% on the right. */ pattern = SWITCHES; /* Input from the dip switches into a variable @pattern@. */ KEYPAD = 0; /* Output zero to the keypad on Port A. */ %] Similar operations can be done in assembly language: \begin{prog} move.b #$f,leds(a6) OUTPUT: Turn on the four \LED{}s on the right. move.b switches(a6),d0 INPUT from the dip switches into D0. clr.b keys(a6) OUTPUT zero to the keypad (port A) \end{prog} The first operation outputs the bit pattern 0000\,1111 to port~B, which is connected to the \LED{}s. This output operation is performed by writing to the port~B data register, which is at address 800013\hex---see tables~\vref{tab:portAddr} and \vref{tab:registerAddr}. The second operation inputs from port~C\index{port!C}, which is connected to the dip switches. This input operation is performed by reading the port~C data register, which is at address 800019\hex---see tables~\vref{tab:portAddr} and \vref{tab:registerAddr}. The third operation sends the data value 0 out of the port~A\index{port!A} data register, which is at the address 800011\hex. The names @LEDS@, @SEVEN_SEGMENT@, @SWITCHES@ and @KEYPAD@ are named constants, defined in the file \texttt{flight.h}. See section~\vref{sec:include} for more about the file \texttt{flight.h}. %@- \index{port!\IO|)} \index{IO ports@\IO ports|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The interface card} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% On the 68000 microprocessor \IO interface card\footnote{I will call the 68000 microprocessor \IO \ix{interface card} the \emph{interface card} from here on.} there are four devices, two for \emph{input} and two for \emph{output}. The input devices are a bank of eight \emph{dip switches}\index{dip-switches} and a telephone \emph{keypad}. The output devices are a set of eight \emph{\LED{}s} (Light Emitting Diodes) and a \emph{seven segment display}. The connections of the devices on the interface board are shown in figure~\vref{fig:portBC}. %@- \index{LEDs@\LED{}s} \index{seven-segment display} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The \FLIGHT \up board} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htb] \centering {% \scriptsize \input{ledsswit.pic}% }% \caption{The connections between the 68000 and the parallel chip on the \FLIGHT \up board, and the connections to port~B and port~C on the interface board.} \label{fig:portBC} \end{figure} Figure~\vref{fig:portBC} shows how the \LED{}s and the seven segment display are connected to port~B, and how the dip-switches are connected to port~C\e. It also shows how the microprocessor is connected to the parallel chip. \index{jumper!selecting \LED{}s or seven-segment|(}% \index{selecting \LED{}s or seven-segment|(}% The jumper, JP1, (also shown in figure~\vref{fig:jump}) selects one of the seven-segment display or the \LED{}s to port~B\e. %@- \index{sixty eight thousand@68000 microprocessor}% \index{microprocessor}% \index{sixty eight six eight one@68681 \DUART}% \index{DUART@\DUART}% %@+ The microprocessor is connected to 16\,KB of \RAM, 32\,KB of \EPROM---which contains the \ix{monitor firmware}---and the 68681 \DUART (serial chip) as well as the 68230 \PIT (parallel chip). See \cite{nickAsm} for more details about the 68000 \up. See also your text book, \cite{horvath}. See the \FLIGHT manual \cite{flight} for more about the \FLIGHT board itself. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Octal tristate buffers on the interface board} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{octal buffer|(} \index{tristate|(} The 244 octal buffers have their outputs the same logical value as the input when the gate \overbar{G} is active, but when the gate is inactive, the outputs are open, or high impedance. We sometimes say the outputs are ``high Z''\e. The jumper, JP1, either activates the gate of the buffers for the \LED{}s or the gate of the buffers for the seven segment display. In this way, either the \LED{}s or the seven-segment display is connected to port~B of the \PIT. \index{octal buffer|)} \index{tristate|)} \index{jumper!selecting \LED{}s or seven-segment|)}% \index{selecting \LED{}s or seven-segment|)}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Address decoder for the 68230 \PIT} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{address decoder|(} Notice the address decoder for the 68230 \PIT. As inputs it takes only three address lines, A$_{23\text{--}21}$, and the address strobe control line, \overbar{AS}, which is the way the microprocessor lets the rest of the computer know that the address on the address lines is valid. The address decoder is connected to the chip select input to the \PIT. This means that when the \up accesses any of the addresses in table~\vref{tab:registerAddr}, the address decoder will be activated and the \PIT will ``wake up'' and listen to the \up's commands. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{Partial address decoding} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{address decoding!partial|(} \index{partial address decoding|(} Notice that there are only five address lines, A$_{5\text{--}1}$, connected directly to the \PIT. This means that 15 address lines, A$_{20\text{--}6}$, are not connected either to the address decoder or to the \PIT. These address lines are ``don't cares'' to the \PIT. It means that the \PIT is activated only depending on the address lines A$_{20\text{--}6}$, regardless of the values of address lines A$_{20\text{--}6}$\e. This is \emph{partial address decoding}. It means that each of the registers in the \PIT can be accessed not only at the addresses shown in table~\vref{tab:registerAddr}, but also at $2^{15} = 32767$ other addresses! The memory map in figure~\vref{fig:memmap} is not strictly accurate. It shows the \PIT registers mapped to addresses 800000\hex to 80003F\hex, only 64 bytes. In fact, the \PIT is mapped to locations 800000\hex to 9FFFFF\hex, occupying two megabytes of address space! Why use partial address decoding: it seems to waste a lot of address space! The reason it is used is because it makes the address decoder much simpler, and so much cheaper. Full address decoding would require a circuit with 19 inputs; here we need a simple circuit circuit that only has four inputs. The full circuit diagram of the \FLIGHT board is shown in appendix~G of \cite{flight}. \begin{exercise} If there are three address lines, A$_{23\text{--}21}$, connected to %@- \index{sixty eight six eight one@68681 \DUART}% \index{DUART@\DUART}% %@+ the address decoder for the 68681 \DUART (serial chip), and four address lines A$_{4\text{--}1}$ connected directly to the \DUART, and the lowest address to which the registers in the \DUART are mapped is A00000\hex, then, as a result of partial address decoding, \begin{enumerate}[(a)] \item What is the highest address at which the \DUART registers are mapped? In other words, what is the highest address at which the chip select of the \DUART will be active? \item How many addresses can each register in the \DUART be accessed at? \end{enumerate} \begin{Solution} \begin{enumerate} \item If there are three address line inputs to the address decoder, A$_{23\text{--}21}$, then a new range of addresses is selected when A$_21$ changes. So the lowest address, A00000\hex is active when A${23}$ = 1, A$_{22}$ = 0 and A$_{21}$ = 1. This three-bit number is 101\bin. When this three-bit number is incremented, then the \DUART will cease to be activated. This will happen when A${23}$ = 1, A$_{22}$ = 1 and A$_{21}$ = 0, which (when all other bits are zero) is C00000\hex. The address one less than this is BFFFFF\hex. That is the highest address at which the chip select of the \DUART will be activated. \item There are 16 address lines, A$_{20\text{--}5}$, that are connected neither directly to the \DUART nor to its address decoder. Therefore there are $2^{16} = 65536$ different addresses for each register in the \DUART. \end{enumerate} \end{Solution} \end{exercise} \index{address decoding!partial|)} \index{partial address decoding|)} \index{address decoder|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The other connections between the 68000 and the \PIT} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{sixty eight thousand@68000 microprocessor|(}% \index{microprocessor|(}% %@+ There are eight data lines connecting the 68000 to the \PIT, so only eight bits can be transferred at once. The \RW %@- \index{rw@\RW, on control bus} %@+ line is high if the \up wants to read from the \PIT, and low if the 68000 wants to write to registers in the \PIT. The \overbar{RESET} input resets the \PIT when the power is turned on or when the \textsf{RESET} button is pressed on the \FLIGHT. The \overbar{DTACK} output from the \PIT tells the \up when the \PIT has finished data transfer, either into or out from a \PIT register.% %@- \index{dtack@\overbar{DTACK}, on control bus} \index{sixty eight thousand@68000 microprocessor|)}% \index{microprocessor|)}% %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The 68230 parallel interface/\allowbreak{}timer chip} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:68230} All these devices are connected to the 68230 parallel interface and timer (\PIT) chip via a 40 wire \emph{ribbon cable}. The \PIT has three \emph{ports}. On this chip, a port is a set of eight pins. Each of these pins can be individually set up as an input or as an output. This is more flexible than the Intel 8255A parallel chip, in which the pins in one port cannot be assigned as inputs and outputs in any order. The \ix{ports} are called port~A, port~B and port~C\e. Some of the pins in port~C\index{port!C} can be used also as inputs and outputs for the timer, and some others as control signals for transfers to and from ports A and B\e. We use port~C as an input port since it is connected to the dip switches. The 68230 \PIT on the \FLIGHT has been given a \emph{base address}\index{base address}% \index{parallel interface/\allowbreak{}timer!base address} of 800\,001\hex. The base address is determined by the design of the \ix{address decoder} for the \PIT. The address decoder is shown as a box in figure~\vref{fig:portBC}. The port~A data register has offset 10\hex from the base address of the \PIT, the port~B data register has offset 12\hex from the base address, while port~C\index{port!C} has offset 18\hex from the base address. This means that port~A is at address $800\,001\hex + 10\hex = 800\,011\hex$, while the port~B data register is at address $800\,001\hex + 12\hex = 800\,013\hex$, while the port~C\index{port!C} data register is at address $800\,001\hex + 18\hex = 800\,019\hex$. See section~\vref{asmpv114:sec:equates} of \cite{nickAsm} for how these constants are defined. See table~\vref{tab:portAddr} for a list of the port addresses. %@- \begin{table}[tbh] \centering \begin{tabular}{@{}llll@{}} \toprule \multicolumn{1}{c}{\textbf{register}} & \textbf{address} & \textbf{offset} & \textbf{name} \\ \midrule Port A data register & 800011\hex & 10\hex & \Vf{KEYPAD} \\ Port C data register & 800019\hex & 18\hex & \Vf{SWITCHES} \\ Port B data register & 800013\hex & 12\hex & {\small\Vf{SEVEN\_SEGMENT}} or \Vf{LEDS} \\ \bottomrule \end{tabular} \caption{The port addresses in the 68230 \PIT and their names we have used in the laboratory.} \label{tab:portAddr} \end{table} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The seven segment display} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The \ix{seven segment display} on the interface board is connected as shown in figure~\vref{fig:portBC}. The least significant bit (\acro{LS}b) of port~B controls segment~a. When bit~0 of port~B is set, and the \index{jumper!selecting \LED{}s or seven-segment}% jumper~JP1 selects the seven-segment display, then segment~a will light up. Figure~\vref{fig:sevenseg} shows which bit of port~B controls which segment. We can access the seven-segment display using the name @SEVEN_SEGMENT@ or @PBDR@, both defined in the header file \texttt{flight.h}. \begin{figure} \centering \input{sevenseg.pic} \vspace{2ex} The names for each segment in the seven segment display \vspace{2.5ex} %@- \begin{tabular}{@{}lcccccccc@{}} %@+ \toprule \textbf{bit number} & 7 & 6 & 5 & 4 & 3 & 2 & 1 & 0 \\ \textbf{segment label} & DP & g & f & e & d & c & b & a \\ \bottomrule \end{tabular} \caption{The bits for each segment in the seven segment display. Note that DP stands for ``decimal point''.} \label{fig:sevenseg} \end{figure} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The dip switches} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{dip switches} On the interface board is a bank of eight small switches, which can be moved with a pen or your fingernail. They are connected to port~C, as shown in figure~\vref{fig:portBC}. We can access them by the name @SWITCHES@ or by the name @PCDR@. These names are defined in the header file \texttt{flight.h}. We can perform input from them into a variable @val@ by a C statement: %[ val = SWITCHES; /* An input operation. */ %] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Register addresses in the 68230 \PIT on the \FLIGHT} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{parallel interface/\allowbreak{}timer!registers|(}% \index{registers!PIT@registers!\PIT|(}% %@+ A 68230 \PIT has 23 separate registers. These occupy 64 memory locations. Individual bits in these registers can be set to control the behaviour of the IC\e. Three of them are the data registers used to communicate with the keyboard, dip-switches and \LED{}s in our lab work. Table~\vref{tab:registerAddr} gives the addresses of the registers in the 68230 on the \FLIGHT. \begin{table} \centering %@- % \begin{tabularx}{\linewidth}{@{}l>{\sffamily\slshape}llcX@{}} \begin{tabularx}{\linewidth}{@{}l>{\sffamily\slshape}llc>{\footnotesize}C@{}} %@+ \toprule \multicolumn{1}{c}{register} & \multicolumn{1}{c}{% \makebox[4em][c]{\normalfont\makebox[0.8\width][r]{abbreviation}}% } & address & offset & name \\ \midrule Port general control register & PGCR & 800001 & 0 & \\ Port service request register & PSRR & 800003 & 2 & \\ Port A data direction register & PADDR & 800005 & 4 & \\ Port B data direction register & PBDDR & 800007 & 6 & \\ Port C data direction register & PCDDR & 800009 & 8 & \\ Port interrupt vector register & PIVR & 80000B & A & \\ Port A control register & PACR & 80000D & C & \\ Port B control register & PBCR & 80000F & E & \\ Port A data register & PADR & 800011 & 10 & \Vf{KEYPAD} \\ Port B data register & PBDR & 800013 & 12 & \Vf{SEVEN\_SEGMENT} or \Vf{LEDS} \\ Port A alternate register & PAAR & 800015 & 14 & \\ Port B alternate register & PBAR & 800017 & 16 & \\ Port C data register & PCDR & 800019 & 18 & \Vf{SWITCHES} \\ Port status register & PSR & 80001B & 1A & \\ Timer control register & TCR & 800021 & 20 & \\ Timer interrupt vector register & TIVR & 800023 & 22 & \\ Counter preload register, high & CPRH & 800027 & 26 & \\ Counter preload register, middle & CPRM & 800029 & 28 & \\ Counter preload register, low & CPRL & 80002B & 2A & \\ Count register, high & CNTRH & 80002F & 2E & \\ Count register, middle & CNTRM & 800031 & 30 & \\ Count register, low & CNTRL & 800033 & 32 & \\ Timer status register & TSR & 800035 & 34 & \\ \bottomrule \end{tabularx} \caption{The addresses of registers in the 68230 \PIT on the \FLIGHT. All addresses and offsets are in hexadecimal.} \label{tab:registerAddr} \end{table} \index{parallel interface/\allowbreak{}timer!registers|)}% %@- \index{registers!PIT@registers!\PIT|)}% %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph{The \PIT has many modes:} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The \PIT is a general purpose parallel and timer chip, and can be set up to work in many different ways. Each of these methods of operation is called a \emph{mode}. There are diagrams showing these modes on pages 1-4 and 1-5 of the data book, \cite{moto68230}. Some ways that the parallel ports can be set up include support for \emph{handshaking} and \emph{interrupts}. We will study these topics later in the course. There are many options within each mode. See pages 3-7 and 3-8 of the data book for a list of all the options. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph{Submode 1X} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:submode1x} \index{parallel interface/\allowbreak{}timer!submode 1x|(}% \index{submode 1x|(}% \index{parallel interface/\allowbreak{}timer!initialising for bit \IO|(}% We have used the \PIT in its simplest mode, where each pin can work as an input or as an output. The Motorola data sheets call this \emph{submode 1X}\e.\footnote{The name `submode 1X' comes from the fact that there are two bits used to determine the submode. The `1X' means that the first bit is a ``don't care'' while the second is a `1'.} Submode~1X is described on page~3-2 of the data book as ``Bit \IO (Pin-Definable Single-Buffered Output or Non-Latched Input).'' On page~3-6 Motorola says: \begin{quote} This submode is intended for applications in which several independent devices must be controlled or monitored. [\ldots] Data read from the data register is the instantaneous value of the pin or what was written to the data register, depending on the contents of the data direction register. \end{quote} In section~\vref{sec:ddr} we will examine the function of the data direction registers. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Initialising the \PIT for bit \IO} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:initPitForBitIO} \index{parallel chip!initialising|(}% %@- \index{sixty eight two thirty@68230!initialising|(}% %@+ Before we use the \PIT, it needs to be set up in the right mode. We do this by writing particular values to some of the registers in the \PIT. How do we know what values to write there? We look in the data book, \cite{moto68230}. Examine pages 3-7 and 3-8 of the data book. I will not explain all the options: we will learn about them later. I will just give you a table (see table~\vref{tab:submode1x}) showing what we want to use in our lab work. \begin{table}[tbh] %@- \begin{tabularx}{\linewidth}{@{}>{\ttfamily}ccccY@{}} %@+ \toprule \normalfont\textbf{register} & \multicolumn{3}{c}{\bfseries bits} & \multicolumn{1}{c}{\bfseries option} \\ \midrule PACR & & 7 & 6 & \textbf{Port A submode} \\ & & 1 & X & Submode 1X \\ \hline PACR & 5 & 4 & 3 & \textbf{H2 control}\\ & 0 & X & X & Input pin---edge sensitive status input, H2S is set on an asserted edge \\ \hline PACR & & & 2 & \textbf{H2 SVCRQ enable} \\ & & & 0 & The H2 interrupt is disabled \\ \hline PACR & & & 1 & \textbf{H1 SVCRQ enable} \\ & & & 0 & The H1 interrupt is disabled \\ \hline PACR & & & 0 & \textbf{H1 Status control} \\ & & & X & H1 is an edge-sensitive status input, H1S is set by an asserted edge of H1\\ \bottomrule \end{tabularx} \caption{The values to be written into individual bits of the port~A control register (\Vf{PACR}) and the port~B control register (\Vf{PBDR}) to put these ports into submode~1X.} \label{tab:submode1x} \end{table} % \vspace{2ex} The arrangement for port~B is the same as for port~A, except that instead of \Vf{PACR} we are writing to the register \Vf{PBCR}, and instead of the handshaking lines H1 and H2, port~B works with the handshaking lines H3 and H4\e. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph{What does it all mean?} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Table~\vref{tab:submode1x} above gives values required to be written to various bits of the \Vf{PACR} register to make the \PIT behave the way we want. The `X's are ``don't cares''. If the constant @SUBMODE_1X@ contains the correct value, we can initialise port~A with the instruction %[ PACR = SUBMODE_1X; %] Or if the name \inst{submode\_1X} has a suitable definition, and the register A6 holds the base address of the parallel chip, we can achieve the same result with: \begin{prog} move.b #submode_1X,PACR(a6) \end{prog} \begin{exercise} What value should we write to the port~A control register to put port~A into submode~1X\e? Give your value in binary and in hexadecimal. \begin{Solution} We can write the value 1000\,0000\bin or 80\hex to the port~A control register. We can do so with this statement: %[ PACR = 0x80; %] Note that there are many other possible answers, as the `X's in table~\vref{tab:submode1x} can be either 1 or 0; they are ``don't cares.'' \end{Solution} \end{exercise} We also want to put port~B into submode~1X. \begin{exercise} What value do we need to write to port~B data register to put port~B into submode~1X? \begin{Solution} We can write the same value as for the previous exercise: 1000\,0000\bin or 80\hex, or any of many other possible values. We can set port~B into submode~1X with: %[ PBCR = 0x80; %] \end{Solution} \end{exercise} What about port~C\e? Port~C\index{port!C} is also multi-purpose, but it shares its function with the timer (the `T' in \PIT stands for \textbf{t}imer), and also with interrupt functions. When port~C is used just as an ordinary parallel port, it behaves like port~A and port~B do when they are in submode~1X\e. There is no need to do anything special to put port~C\index{port!C} into submode~1X. \index{parallel interface/\allowbreak{}timer!submode 1x|)}% \index{submode 1x|)}% \index{parallel interface/\allowbreak{}timer!initialising for bit \IO|)}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{Choosing inputs and outputs: the data direction registers} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:ddr} \index{registers!data direction in \PIT|(}% \index{data direction register|(}% The 68230 \PIT is flexible: you can choose whether individual pins are inputs or outputs. How can you select which pins are inputs and which pins are outputs? The answer is that you write values to the \emph{data direction registers} in the \PIT. There are three data direction registers, one for port~A (\Vf{PADDR}), one for port~B (\Vf{PBDDR}) and one for port~C (\Vf{PCDDR}). If you write a `zero' to bit~0 of the port~A data direction register (\Vf{PADDR}), then bit~0 of port~A will be an input. If you put a `one' there instead, it will be an output. Individual pins can be assigned as inputs or outputs in any order you like. \begin{exercise} If you want bits~0, 1, 2, and 3 to be inputs and bits 4, 5, 6 and 7 to be outputs of port~B, what values should you write to what register? \begin{Solution} We would write the value 1111\,0000\bin to the port~B data direction register with: %[ PBDDR = 0xf0; /* Now bits 3..0 of port B are inputs, 7..4 are outputs */ %] \end{Solution} \end{exercise} \index{registers!data direction in \PIT|)}% \index{data direction register|)}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{Initialising the \PIT for bit \IO: a summary} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The steps in initialising the \PIT are as follows: \begin{enumerate} \item Put port~A and port~B into submode~1X by writing the values shown in table~\vref{tab:submode1x} to the registers \Vf{PACR} and \Vf{PBCR}. \item Select which pins you want to be inputs and which pins you want to be outputs \item For each pin that you want to be an output, put a one into the corresponding bit-position in the \ix{data direction register}. Similarly, put a zero for each pin you want to be an input. \item That's it! You can now read from the input pins and write to the outputs. \end{enumerate} As mentioned in section~\vref{sec:startupCode}, the C compiler automatically calls a function that initialises the 68230 parallel chip before executing the \Vf{main}\Of{()} function. See program example~\vref{prg:startupCode} for this function, just to show that there is no magic here. The file containing this is \texttt{f:\bs hpcc68k\bs env\bs flight\bs src\bs flight.c}. You may examine this and the other files in that directory if you like. \begin{program} %[ #include /* Note: the file %%\texttt{flight.h}%% defines the names for the %%\PIT%% registers as mentioned above, and also the following: @#define SUBMODE_1X 0x80@ @#define ALL_OUTPUTS 0xff@ @#define ALL_INPUTS 0@ @#define COL_MASK 7@ */ %* void InitParallelChip( void ) { PACR = SUBMODE_1X; PBCR = SUBMODE_1X; /* the columns are bits 0, 1 and 2 of port A; want these to be outputs. The other bits are inputs. */ PADDR = COL_MASK; PBDDR = ALL_OUTPUTS; PCDDR = ALL_INPUTS; /* Turn off the seven segment display (or %%\LED{}s%%). */ SEVEN_SEGMENT = 0; } %] \caption{The function \Vf{InitParallelChip}\Of{()}, which is called by the startup code which is executed before \Vf{main}\Of{()} begins. The purpose of \Vf{InitParallelChip}\Of{()} is to initialise the \PIT appropriately for the interface board with the \LED{}s, seven-segment display, dip-switches and $3 \times 4$ telephone keypad.} \label{prg:startupCode} \end{program} \index{parallel chip!initialising|)}% %@- \index{sixty eight two thirty@68230!initialising|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{How the interface card is connected to the parallel chip} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[tbh] \centering \input{jump.pic} \caption{The two settings for the jumper on the interface board} \label{fig:jump} \index{jumper!selecting \LED{}s or seven-segment}% \index{selecting \LED{}s or seven-segment}% \end{figure} \index{jumper!selecting \LED{}s or seven-segment|(}% \index{selecting \LED{}s or seven-segment|(}% The \ix{keypad} is connected to port~A\index{port!A} while the \LED{}s and seven segment display are both connected to port~B\index{port!B}\e. The \LED{}s and \ix{seven-segment display} are selected by \ix{jumper}; please see figure~\vref{fig:jump}. When the jumper is in the upper position across pins 1 and 2, the \LED{}s are selected. When the jumper is across pins 2 and 3, the seven segment display is selected. The dip switches are connected to port~C\index{port!C}\e. \index{jumper!selecting \LED{}s or seven-segment|)}% \index{selecting \LED{}s or seven-segment|)}% When you read from the port~C data register, you read an 8-bit number with one bit for each of the 8 switches in the dip switch. When you write to the port~B data register, the bottom eight bits cause the corresponding \LED to turn on and off, or cause the corresponding segment on the seven-segment display to turn on and off. In both cases, a bit value of `1' means ``on'', a `0' means ``off''. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The keypad} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:keypad} \index{keypad|(}% On the interface board, the keypad is connected to port~A of the 68230 parallel interface/\allowbreak{}timer IC\e. \begin{figure}[tbh] \centering \input{keypad.pic} \caption{The connection of the keypad to the 68230 parallel interface/\allowbreak{}timer chip} \label{fig:keypad} \end{figure} The keypad is connected rather like figure~\vref{fig:keypad}. There is a key in the twelve positions where the vertical wires are shown crossing the horizontal ones. Each key connects the crossing wires when pressed. The columns are set up as outputs while the rows are set up as inputs. When no key is pressed, the row inputs are high. \index{keypad|)}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Scanning the keypad} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{keypad!scanning|(}% There are twelve keys on the keypad but we only have eight pins in one port. If we connected the key switches directly to twelve port pins, we could read the keys directly. But this will not work with a larger keypad or keyboard. Also port pins are too precious to waste---if possible, we would prefer to save them for another purpose. If we have fewer port pins available, it is still possible to read the keypad by \emph{scanning} it. To scan a $3 \times 4$ keypad, we use $3 + 4$ port pins. We can use $n + m$ port pins to scan a $n \times m$ keypad\footnote{The method shown here is not the \emph{only} way to scan a keypad---it is possible to scan $\frac{1}{2} n(n -1)$ keys with $n$ port pins. For instance, it is possible to read 28 keys with 8 port pins---if you are interested, ask the author.}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsubsection{The method} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:readKeyExplain} The idea is that we output a `1' to two of the column outputs to the keypad while outputting a `0' to each column in turn. After the left-most column is set low, we can read each row in turn. Say the key `4' on the keypad has been pressed (see figure~\vref{fig:keypad}). If we read the rows (\ie port inputs PA$_3$ to PA$_6$), then bits PA$_3$, PA$_5$ and PA$_6$ are all `1's, but PA$_4$ is a zero, because the key has connected the line PA$_4$ to PA$_0$ on which we have output a `0'. The resistance between PA$_0$ and ground is much lower than the value of the resistor between PA$_4$ and $\text{V}_{\text{CC}}$, so PA$_4$ will have a voltage close to zero volts. Let's look at the steps in scanning the keypad, from a high level point of view. \begin{itemize} \item For each column: \begin{itemize} \item drive that column low and the others high. \item Read the rows. \item For each row \begin{itemize} \item If that row bit is `0', then have found the key---exit. \item increment the key index \end{itemize} \end{itemize} \item If no key was found, then set key index to \texttt{noKey} \item The key index now has a number from 0 to 11 if a key was pressed, or a value of \texttt{noKey} if no key was pressed. \end{itemize} Let's now look at the steps in greater detail. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %It may help to read %the program in section~\vref{enl4s:sec:readKey} in lab~4, %\emph{Scanning a keypad in MC68000 assembly language}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{nameList}{step 1xx} \item[step 1] Start by initialising the key index number that indicates the current key, the column counter and the column pattern that we will output to the keypad columns \item[step 2] for each column, starting from PA$_0$, drive that column low while driving the other columns high \item[step 3] Read the pattern of bits from the rows, \ie PA$_3$ to PA$_6$. To do this, we read the 8 bits from the keypad port into a register, then \emph{rotate} the 8 bits three times, so that the bit from the top row is in bit position 0, \ie in the LSB (least significant bit) position. \item[step 4] for each row: \begin{nameList}{step 1xxx} \item[step 4a] Rotate the LSB into the carry flag in the \CPU status register. Look up how the \texttt{ror} and \texttt{rol} instructions work in the \FLIGHT manual, your text book or any 68000 reference book. \item[step 4b] check whether the carry flag is low. If it is, then the current key has been pressed. \item[step 4c] if the current key has not been pressed, then increment the key index number and try the next row---go to step 4a. \end{nameList} \item[step 5] Roll the bit pattern for the columns one position left so that we are ready to drive the next column low and the other columns high. \item[step 6] If we have read all the columns, then no key was pressed, so put a special value into the key index register to show that no key has been pressed. \item[step 7] We now have the key number. Use this as an index to look up the value of the key in a lookup table. \end{nameList} This list of steps is called a \emph{task list}. We can also express the algorithm in \emph{pseudocode}\index{pseudocode}. Pseudocode is a mixture of English (or you can use Cantonese if you like!) and some programming language. Here I have combined English with Pascal, since you may have studied Pascal: \label{pag:readkey}% \begin{prog} Algorithm ReadKey: key = 0, col = 2, columnPattern = $FE while col <> -1 do row = 3 keypad = columnPattern rowPattern = keypad roll port A bit 3 into rightmost bit position of rowPattern while row <> -1 do roll LSB of rowPattern into CPU carry flag if carry flag is clear goto found key := key + 1 row := row - 1 roll columnPattern left one position col := col - 1 key := noKey found: \end{prog} I hope that these two ways of showing the algorithm will help you to understand the subroutine \texttt{ReadKey}.% \index{keypad!scanning|)}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %, first introduced in your %lab work in section~\vref{enl4s:sec:readKey} in lab~4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Debouncing the keys} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:debouncing} \index{keypad!debouncing|(}% \index{debouncing a keypad|(}% However, there is more to it than this. We need to deal with a problem called \emph{key bounce}. When any switch opens or closes, it does not do so at only one moment. A closing switch will bounce open again for a very short time, close again, bounce apart again, and so on. This lasts about 10 milliseconds, depending on the type of switch. We need to be able to tell when a key has been pressed once and is bouncing or if it has been pressed more than once. Small amounts of noise can also be interpreted as keystrokes when there are none. There are many solutions to this problem, some using hardware such as a flip-flop or Schmidt trigger, others using software delay loops. We will take the software approach. If a key has been pressed, we can wait a while and see if it is still pressed some ten or twenty milliseconds later. If it is still seen as pressed, we shall say that this is a genuine keystroke. We can use the @DelayMs()@ library function described in section~\vref{sec:delayMs} to create a delay of 20 milliseconds: %[ DelayMs( 20 ); /* Delay 20 milliseconds. */ %] \index{keypad!debouncing|)}% \index{debouncing a keypad|)}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{How to detect if any key has been pressed} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:keyPressed} \index{keypad!detecting key press|(}% To see how to scan a keypad we look here at the first part of the problem: detecting a keystroke. How can we do this? One simple way is to output a low to all the columns (\ie to bits 0, 1 and 2 of the keypad port, port~A). How do we write the pattern which has bits 0, 1 and 2 low? This is 0. To achieve this step, we can write: %[ KEYPAD = 0; /* make all keypad columns low. */ %] or in assembly language, we can write \begin{prog} clr.b keys(a6) output 0 to keypad columns \end{prog} Remember, to \emph{write} to a port register---in other words, to perform output---we put the name of the port on the left side of an assignment statement. In assembly language, we put the port as the destination operand, \ie on the \emph{right} side of the \texttt{move} instruction. We can then read the keypad port. If any of the row bits (\ie bits 3 to 6) are low, then a key has probably been pressed. How can we do this? We can first input from the keypad into a register: %[ pattern = KEYPAD; /* The variable @pattern@ now holds the column bits */ %] If A6 holds the base address of the parallel chip, we could write this in assembly language as \begin{prog} move.b keys(a6),d1 Register D1 contains the column bits \end{prog} Now how can we find out if any of the rows are low? Well, first we need to clear our copy of the bits that are not in the rows, \ie that are not bit 3, 4, 5 or 6. We use the bitwise AND operator `@&@' in the C programming language (or the \texttt{and} assembly language instruction) to clear these bits. We can write %[ pattern = pattern & 0x78; /* clear all bits that are not row bits. */ %] or in assembly language, \begin{prog} andi.b #$78,d1 Clear all the bits that are not row bits \end{prog} Finally, we can compare this value read from the rows with @0x78@. We can tell if a key has been pressed by seeing if these values are the same or different. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % You will use this algorithm in your experimental work in % section~\vref{enl4s:sec:anyKeyPressedProg}, in lab~4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{exercise} What we can say about the number of keys pressed if the value read from the rows is equal to @0x78@?\label{qes:rowtest} \begin{Solution} If the value read from the rows is equal to @0x78@ then we know that \emph{no} key has been pressed, since each row bit is high; none of the keys have connected a row wire to a column wire---we know this because all the columns have been made low, and if the wires contact each other, the corresponding row will be pulled low. \end{Solution} \end{exercise} \index{keypad!detecting key press|)}% \appendix %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{The operators in C and their precedence} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:operators} \index{operators|(} \index{operator!precedence|(} Table~\vref{tab:operatorPrecedence} shows all the operators available in the C programming language. The table also shows the \emph{precedence} of each operator, together with its \emph{associativity}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Operator precedence} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% We learned in school that multiply has a higher priority in arithmetic than plus or minus, so that when we write $3 \times 4 + 7$, we mean $(3 \times 4) + 7$ (which has the value 19), not $3 \times (4 + 7)$ (which has the value 33). This is an accepted rule used in arithmetic. Similarly, the C programming language has priorities for each operator. These are called the \emph{rules of precedence} of the operators. The rules of precedence are part of the \ANSI standard, so you can depend on them remaining as shown in table~\ref{tab:operatorPrecedence}. If you are unsure of the precedence of an operator, it is better to use lots of parentheses in complex expressions (or better still, to break complex expressions down into many simple expressions). The level of precedence of each operator is shown in the left-most column of table~\ref{tab:operatorPrecedence}. The highest precedence is 15; the lowest is 1. Each precedence is shown together with a letter `L' or `R'\e. This is the \emph{associativity} of the operator. Those with the letter `L' are said to be \emph{left associative}, or that they `associate from left to right'. Those with an `R' are said to be \emph{right associative}, or to `associate from right to left'. \begin{table} \setlength{\extrarowheight}{0pt} \newcommand*{\cS}{,\,\,}% comma-space \newcommand*{\opSep}{2ex} \centering %@- \begin{tabular}{@{}lcl@{}} %@+ \toprule %@- \multicolumn{1}{@{}c}{\em Level} & \multicolumn{1}{c}{\em Operator} & \multicolumn{1}{c@{}}{\em Function} \\ %@+ \midrule 15L & @->@\cS@.@ & structure member selectors \\ & @[]@ & array index \\ & @()@ & function call \\ [\opSep] 14R & @sizeof@ & size in bytes \\ & @++@\cS@--@ & increment, decrement \\ & @~@ & bitwise NOT \\ & @!@ & logical NOT \\ & @+@\cS@-@ & unary plus, minus \\ & @*@\cS@&@ & dereference, address-of \\ & @()@ & type conversion (cast) \\ [\opSep] 13L & @*@\cS@/@\cS\textsf{\%} & multiply, divide, modulus \\ [\opSep] 12L & @+@\cS@-@ & arithmetic operators \\ [\opSep] 11L & @<<@\cS@>>@ & bitwise shift \\ [\opSep] 10L & @<@\cS@<=@\cS@>@\cS@>=@ & relational operators \\ [\opSep] 9L & @==@\cS@!=@ & equality, inequality \\ [\opSep] 8L & @&@ & bitwise AND \\ [\opSep] 7L & @^@ & bitwise exclusive-OR \\ [\opSep] 6L & @|@ & bitwise OR \\ [\opSep] 5L & @&&@ & logical AND \\ [\opSep] 4L & @||@ & logical OR \\ [\opSep] 3L & @?:@ & arithmetic if \\ [\opSep] 2R & @=@ & assignment operator \\ & @*=@\cS@/=@\cS\textsf{\%=} & compound assignment operators \\ & \textsf{+=}\cS\textsf{$-$=}\cS@<<=@ & \\ & @>>=@\cS@&=@\cS@|=@\cS@^=@ & \\ [\opSep] 1L & @,@ & comma operator \\ \bottomrule \end{tabular} \caption{A list of all operators provided in the C programming language, showing level of precedence.} \label{tab:operatorPrecedence} \end{table} \begin{exercise} %\renewcommand*{\theenumi}{\alph{enumi}} %\renewcommand*{\labelenumi}{(\theenumi)} \begin{enumerate}[(a)] \item Put parentheses around the following expressions to show the exact order of evaluation of the expression. If possible, write the value of the expressions. \item @3 + 4 * 7 - 2@ \item @2 & 3 | 4 + 7@ \item @1 << 4 + 3@ \item @0x45 | 1 << 3@ \item @4 + 2 << 3 * 2 - 2 | 4 | 3@ \item @++a[ 4 ]@ \item @3 < 4 + 7 - 1 == 7 + 3 * 4@ \item \textsf{a \%= 4 + 5 * 7 \% 8} \end{enumerate} \begin{Solution} In these solutions, the symbol `$\land$' is the mathematical symbol for AND, and the symbol `$\lor$' is the mathematical symbol for OR\e. \begin{enumerate}[(a)] \item @( 3 + ( 4 * 7 ) ) - 2@\\ This expression has the value 29. \item % 2 & 3 = 2 = 0010\bin % 4 + 7 = 11 = 1011\bin % 2 | 11 = 1011\bin = 11 @( 2 & 3 ) | ( 4 + 7 )@\\ This expression has the value \begin{align*} (2 \land 3) \lor (4 + 7) &= 2 \lor 11\\ &= 11. \end{align*} \item @1 << ( 4 + 3 )@\\ This expression equals @1 << 7@ which is $2^7 = 128$. \item @0x45 | ( 1 << 3 )@\\ which is equal to $45\hex \lor 2^3 = 45\hex \lor 8 = 4\D\hex$. \item % 12 11 13 12 6 6 @( ( ( 4 + 2 ) << ( ( 3 * 2 ) - 2 ) ) | 4 ) | 3@ \begin{align*} &\phantom{= \mbox{}\,\,}(((4 + 2) <\!\!< ((3 \times 2) - 2)) \lor 4) \lor 3\\ &=((6 <\!\!< (6 - 2)) \lor 4) \lor 3\\ &=((6 <\!\!< 4) \lor 4) \lor 3\\ &=((6 <\!\!< 4) \lor 4) \lor 3\\ % 6 \times 2^4 \lor 4 \lor 3 % 6 \times 16 \lor 4 \lor 3 % 96 \lor 4 \lor 3 % 0110\bin << 4 = 60\hex &= (60\hex \lor 4) \lor 3\\ &= 64\hex \lor 3\\ &= 67\hex. \end{align*} \item @++( a[ 4 ] )@ % \vspace{1.5ex} \item % 10 12 12 9 12 13 % @3 < 4 + 7 - 1 == 7 + 3 * 4@ @( 3 < ( ( 4 + 7 ) - 1 ) ) == ( 7 + ( 3 * 4 ) )@ \begin{align*} &\phantom{= \mbox{}\,\,}(3 < (( 4 + 7 ) - 1 )) == ( 7 + ( 3 \times 4 ) )\\ &=(3 < (11 - 1)) == ( 7 + 12 )\\ &=(3 < 10) == 19\\ &=1 == 19\\ &= 0 \end{align*} \item % 2 12 13 13 % a \%= 4 + 5 * 7 \% 8 \textsf{a \%= ( 4 + ( ( 5 * 7 ) \% 8 ) )}\\ \textsf{a \%= ( 4 + ( 35 \% 8 ) )}\\ \textsf{a \%= ( 4 + 3 )}\\ \textsf{a \%= 7}\\ which has the same value as \textsf{a = a \% 7}. \end{enumerate} \end{Solution} \end{exercise} \index{operators|)} \index{operator!precedence|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{The \ASCII code for representing characters} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:ascii} Computers represent text as well as numbers. How can a computer use binary numbers to represent the letters of the alphabet, punctuation and all the other symbols we use in a text file? There are a number of different systems. They each use a binary number to represent a character. Some large \acro{IBM} mainframe computers use a system called the \acro{EBCDIC} code. However, all \up systems use the \acroSl{ASCII} code. \ASCII stands for American Standard Code for Information Interchange\e. Each character is represented by a \emph{seven-bit} number. This allows a total of 128 characters. Table~\vref{tab:ascii} shows the \ASCII code. Since 128 characters is not really enough, most computers have extensions to the \ASCII code, but these are not standard, and they may vary from one manufacturer to another. The first 32 \ASCII characters are \emph{control codes}; these are used for such things as making the computer beep (\textsf{BEL}), for serial communications (\textsf{DC1} and \textsf{DC3}), the backspace (\textsf{BS}), for starting a new line (\textsf{LF} and \textsf{CR}), a form feed for starting a new page (\textsf{FF}) and so on. They can often be entered from a keyboard as \meta{Ctrl-a} for \textsf{SOH}, \meta{Ctrl-b} for \textsf{STX}, \meta{Ctrl-c} for \textsf{ETX}, \meta{Ctrl-d} for \textsf{EOT}, and so on up to \meta{Ctrl-z} for \textsf{SUB}\e. Notice that we can convert an upper case letter to a lower case letter by adding 32\dec. \begin{table} %\enlargethispage{4.00369pt} \centering \input{ascii}% \caption{The \ASCII table} \label{tab:ascii} \end{table} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{The memory map of the 68000 system in the laboratory} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Memory is organised in \index{chunks!byte-sized}byte-sized chunks;\footnote{However I have rarely found these chunks% \index{chunks!juicy|nn}% \index{chunks!meaty|nn}% \index{chunks!as preferred by Rover|nn} to be either juicy or meaty, and it seems Rover still prefers his byte-sized chunks straight from the tin.} each chunk is called a \emph{memory location}. Each \ix{memory location} has its own special number, called its \emph{address}. Addresses are usually specified in hexadecimal. In the 68000 system\index{address!range in 68000 system}, \ix{address}es start from 0 and finish at $2^{24} - 1 = \F\F\F\F\F\F\hex$\e. This gives a maximum of more than 16 million possible memory locations. This range of possible addresses is called the \emph{address space}\index{address space}. Not all of these addresses are used;\index{addresses!used in \FLIGHT} in fact, only about $48 \times 2^{10}$ bytes = 48\,K~bytes are actually used. The way that the systems in the laboratory use the \ix{address space} is shown in figure~\vref{fig:memmap}. This organisation is determined by the design of the \ix{address decoder}s for each of these four main devices in the \FLIGHT \up system. \begin{figure}[tbh] \centering \input{memmap.pic} \caption{A \ix{memory map} of the \FLIGHT \up board. M means \ix{megabyte}s; K means \ix{kilobyte}s. $1\M = 2^{20}$; $1\Kb = 2^{10}$.} \label{fig:memmap} \end{figure} Figure~\vref{fig:memmap} shows that there are 16\,K of \RAM (read-write memory), and 32\,K of \ROM containing \ix{monitor firmware}.\index{firmware!monitor} It also shows the addresses in which \IO ports in the 68230 \PIT and in the 68681 %@- \index{sixty eight six eight one@68681 \DUART}% \DUART\index{DUART@\DUART} can be found. The \IO ports in the 68230 \PIT are discussed in section~\vref{sec:ioports}. %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{The compile, assemble and link process} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:compiler} You are familiar with the Edit/Compile/Download/Run procedure that you have used many times---once each time you create and run a program on the \FLIGHT microprocessor board. You should refer to your lab sheets for more information about the procedure for editing, downloading and running a program. So you have used a C compiler often. But what \emph{is} a C compiler? A compiler is a software \emph{translator} that translates a high-level language that microprocessors do not understand to another target language. Usually, the target language is \emph{machine language}, which a \up \emph{does} understand. In our labs, the compiler consists of many programs: it contains a \emph{preprocessor}, a translator from preprocessed code to assembly language, an \emph{assembler} and a linker. There are also some other programs that can be part of the process, such as an \emph{optimiser} and also a listing program. What do all these do? See figure~\vref{fig:compiler} for what happens when you compile the program \meta{prog}\texttt{.c}. \begin{figure} \newcommand*{\swFont}{\normalsize} \centering {\footnotesize \input{compile2.pic} } \caption{The programs involved in compiling the program \protect\meta{prog}\texttt{.c}. Note that the files \protect\meta{prog}\texttt{.i}, \protect\meta{prog}\texttt{.s} are deleted automatically unless you ask the compiler to keep them. Also \protect\meta{prog}\texttt{.lst} will only be created if you ask the compiler to make it.} \label{fig:compiler} \end{figure} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The preprocessor} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:preprocessor} % \errorcontextlines=20\relax The preprocessor takes a C language program, removes all the \emph{comments} (see section~\vref{sec:comments}) and also obeys all the commands in your program that begin with a `\Kf{\#}', such as the commands ``@#include @'' and ``@#define NUMPATTERNS 8@''. You can look at the output from the preprocessor. To look at the output from preprocessing a file \meta{prog}\texttt{.c}, type: \texttt{C:\textbackslash MICROP\textgreater{} cc68k -P \meta{prog}.c} The output is in the file \meta{prog}\texttt{.i}. Try that in the lab with any file containing the line @#include @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The translator (or the main part of the C compiler)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The translator produces assembly language as output. You can read the assembly language output from the compiler. If you are working with a program \meta{prog}\texttt{.c}, you can read the assembler output by typing: \texttt{C:\bs MICROP\textgreater{} cc68k -S \meta{prog}.c} The output will be \meta{prog}\texttt{.s}. You can look at this with the editor. Do this next time you are in the lab. However, you get a more interesting view of your program if you look at the listing file. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The listing file and the map file} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The listing file shows the C language for your source program and the assembly language together. To get a listing file for the program \meta{prog}\texttt{.c}, type: \texttt{C:\textbackslash MICROP{\textgreater} cc68k -Lxi \meta{prog}.c} The listing file is then \meta{prog}\texttt{.lst}. Try this in the lab and have a look at the list file with the editor. The listing file is produced by the listing program. A file \texttt{linkcom.map} is also produced. You may wish to take a look at that also. This is called a \emph{map} file. It shows the address of all the variables and functions in your program. \index{can't open .map!error message|(}% \index{error messages!can't open .map|(}% When you run the compiler, you will get the following error message from the linker if you are successful: \begin{verbatim} Errors: 0, Warnings: 0 CC68K.EXE: can't open .map or aout.lst in the current directory \end{verbatim} \eemph{Ignore this message}; the map file \texttt{linkcom.map} and the listing file \meta{prog}\texttt{.lst} are both created successfully. \index{error messages!can't open .map|)} \index{can't open .map!error message|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The assembler} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The output of the translator is \emph{assembly language}. Assembly language is rather close to the machine language that the microprocessor understands. There is usually one machine language instruction for each assembly language instruction. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Relocatable object file} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The assembler takes the file produced by the translator and converts this into \emph{relocatable} machine code. The result is an \emph{object file}. If you compile \meta{prog}\texttt{.c}, the object file is \emph{\meta{prog}.obj}. Note two things about the object file: \begin{itemize} \item It does not have any absolute memory locations specified. \item It does not contain any library routines, such as @printf()@. \end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The linker} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The final step in the compilation process is linking. A program called the \emph{linker} does two things: \begin{itemize} \item It determines the absolute address that each function and variable will have. \item It adds the startup code and any also any library code you may have used, such as @printf()@. \end{itemize} The result is the file \texttt{aout.abs}. This file contains the machine-language output, in a form called \emph{Motorola S-records}. You can look at the file \texttt{aout.abs} with a text editor, since it is a text file and not a binary file. It is made this way so that it can be conveniently downloaded by serial transfer. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The startup code} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:startupCode} It would seem that your C program should begin execution at the beginning of the @main()@ function. However, it does not---every C compiler provides some \emph{startup code} (usually written in assembly language) which initialises the microcomputer system ready for your program to execute. Such initialisation includes tasks such as giving an initial value to the stack pointer, giving initial values to the interrupt vectors (to be covered in lectures), and various other tasks that may be required for the particular hardware. When you work with a C compiler for an embedded system, you will quite likely need to make minor modifications to the startup code. For example, the stack must be located in physical \RAM, the location of which may vary from one microcomputer system to another. I have added a simple function to the startup code for our system, which initialises the 68230 \PIT and puts it into submode~1x. See section~\vref{sec:submode1x} for more about submode~1x. The function is called @InitParallelChip()@ and is shown in program example~\vref{prg:startupCode}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The library} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:library} A C compiler comes with one or more \emph{library} files. These contain functions that have already been written and compiled by someone else. These library functions extend the basic language, and include such functions as @printf()@ and many others. Many such library functions have been standardised by the \ANSI committee (see section~\vref{sec:ansi}), so all compilers come with these library functions. Whenever we use a library function, we always @#include@ a \emph{header file}, which contains a \emph{declaration} for that function. For instance, whenever we use @printf()@, we always @#include @. See section~\vref{sec:include}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The file \texttt{flight.h}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:flight.h} At the top of all of your programs that use perform input and output through the parallel chip, the 68230 \PIT, you put the line: %[ #include %] This file contains: \begin{itemize} \item the definition of the names @LEDS@, @SWITCHES@, @SEVEN_SEGMENT@, @KEYPAD@ and all the names shown in the `abbreviation' column of table~\vref{tab:registerAddr} which provide a name for all the registers in the \PIT. \item A definition for a @Boolean@ type, and the constant values @true@ and @false@. \item declarations of various functions which I have written to save you time. These include the following functions: @kbhit()@, @getch()@, @DelayMs()@, @WriteSevenSegment()@, @ReadKey()@. I will add to this list as the need arises. \end{itemize} You need to include the header file \texttt{flight.h} whenever you use any of these. Note that these functions are not standard, and so are unlikely to be found on other compilers, although Borland C offers @kbhit()@ and @getch()@. \qc also provides @getch()@. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The library function \Vf{DelayMs}\Of{()}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:delayMs} %@- \index{DelayMs@\Vf{DelayMs}\Of{()}!library function|(} \index{library function!\Vf{DelayMs}\Of{()}|(} %@+ This is a simple function that uses a @for@ loop nested inside a @while@ loop to wait for a number of microseconds to pass by. The function prototype is: %[ void DelayMs( int milliSeconds ); %] We can also call a function prototype a function \emph{declaration}. Program example~\vref{prg:delayMs} gives a definition of @DelayMs()@. \begin{program} %[ void DelayMs( int milliSeconds ) { int i; while ( milliSeconds-- > 0 ) for ( i = 0; i < 193; ++i ) ; /* null statement */ } %] \caption{A definition of \Vf{DelayMs}\Of{()}.} \label{prg:delayMs} \end{program} How did I come up with the magic number 193? I simply used my stopwatch and an iterative guessing process called an interpolation search. To use @DelayMs()@ in a program to wait 300 milliseconds, type a line like this into your program: %[ DelayMs( 300 ); %] %@- \index{DelayMs@\Vf{DelayMs}\Of{()}!library function|)} \index{library function!\Vf{DelayMs}\Of{()}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The library function \Vf{kbhit}\Of{()}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:kbhit} %@- \index{kbhit@\Vf{kbhit}\Of{()}!library function|(} \index{library function!\Vf{kbhit}\Of{()}|(} %@+ The @kbhit()@ library function returns @true@ if a key has been pressed on the terminal keyboard---the keyboard on the \PC compatible computer connected to the \FLIGHT---and @false@ if no key has been pressed. If a key has been pressed, to stop @kbhit()@ from still returning @true@ you need to call @getch()@---see section~\vref{sec:getch}. The function prototype for @kbhit()@ is: %[ int kbhit( void ); %] @kbhit()@ is very useful in loops that you want to terminate when someone presses a key on the \PC. As an example, instead of using the @while@ statement: %[ while ( true ) ... %] in program~\vref{prg:niceLed}, you could use %[ while ( ! kbhit() ) ... %] instead. The program will terminate when you press a key rather than requiring you to press the \acro{RESET} button on the \FLIGHT. The implementation is in assembly language. It calls a \emph{monitor firmware routine} called \inst{inkey}. Such routines are called using \emph{software interrupts}: that is what the \inst{trap} instruction is. Read chapter~5 of the \FLIGHT manual, \cite{flight} for details of the monitor firmware routines. See also section~\vref{asmpv114:sec:trap} in \cite{nickAsm}. The file is \texttt{f:\bs hpcc68k\bs env\bs flight\bs src\bs kbhit.s}; you may read it if you like. The source is shown in program example~\vref{prg:kbhit} for your interest. \begin{program} \begin{prog} * Flight-68k monitor ROM routine to input a character, checking for * break and hold. inkey equ 27 section libc,,c _kbhit trap #11 Call the monitor ROM routine to check dc.w inkey for a waiting character. beq noKey If it is there, moveq #1,d0 show it by returning 1 bra end else noKey moveq #0,d0 return 0 end rts end \end{prog} \caption{The assembly language implementation of \Vf{kbhit}\Of{()}.} \label{prg:kbhit} \end{program} %@- \index{kbhit@\Vf{kbhit}\Of{()}!library function|)} \index{library function!\Vf{kbhit}\Of{()}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The library function \Vf{getch}\Of{()}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:getch} %@- \index{getch@\Vf{getch}\Of{()}!library function|(} \index{library function!\Vf{getch}\Of{()}|(} %@+ The @getch()@ function works rather like @kbhit()@, except that it will not return until a key is pressed. As soon as a key on the \PC terminal is pressed, the function will return with the 7-bit \ASCII code of the key character. Like @kbhit()@, @getch()@ is implemented using a monitor firmware routine which is called with a \inst{trap} instruction. The function prototype of @getch()@ is: %[ int getch( void ); %] The implementation is rather simple and is shown in program example~\vref{prg:getch}. The original file is \texttt{f:\bs hpcc68k\bs env\bs flight\bs src\bs getch.s}. The \inst{getch} monitor firmware routine is described on page~5-10 od \cite{flight}. \begin{program} \begin{prog} * Flight-68k monitor ROM routine to input a character, checking for * break and hold. getch equ 13 section libc,,c _getch trap #11 Call the monitor ROM routine to wait dc.w getch for a character. rts end \end{prog} \caption{The implementation of the library function \Vf{getch}\Of{()}.} \label{prg:getch} \end{program} %@- \index{getch@\Vf{getch}\Of{()}!library function|)} \index{library function!\Vf{getch}\Of{()}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The library function \Vf{WriteSevenSegment}\Of{()}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:writeSevenSegment} %@- \index{WriteSevenSegment@\Vf{WriteSevenSegment}\Of{()}!library function|(} \index{library function!\Vf{WriteSevenSegment}\Of{()}|(} %@- The @WriteSevenSegment()@ function is available for you to write to the seven segment display without having to calculate all the values for the lookup table. The function prototype is %[ void WriteSevenSegment( int number, Boolean showPoint ); %] The bottom four bits of the parameter @number@ are displayed on the seven segment display. If the parameter @showPoint@ is @true@, the decimal point is turned on, otherwise it is turned off. To turn off all seven segments (but not the decimal point: that is controlled by the second parameter), set @number@ to @-1@. The original file is \texttt{f:\bs hpcc68k\bs env\bs flight\bs src\bs sevseg.c}. Program example~\vref{prg:sevseg} shows part of the implementation, but the hexadecimal values are not shown. \begin{program} %[ const unsigned char sevenSegPattern[ 16 ] = { 0x3f, /* 0 */ 0x06, /* 1 */ %=\Line{___\vdots} 0x71 /* f */ }; %* /* Pass -1 to turn off all the seven segments */ void WriteSevenSegment( int number, Boolean showPoint ) { unsigned char pattern = sevenSegPattern[ number & 0xf ]; if ( number == -1 ) pattern = 0; if ( showPoint ) SEVEN_SEGMENT = pattern | 0x80; else SEVEN_SEGMENT = pattern; } %] \caption{The library function \Vf{WriteSevenSegment}\Of{()}.} \label{prg:sevseg} \end{program} %@- \index{WriteSevenSegment@\Vf{WriteSevenSegment}\Of{()}!library function|)} \index{library function!\Vf{WriteSevenSegment}\Of{()}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The library function \Vf{ReadKey}\Of{()}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{ReadKey@\Vf{ReadKey}\Of{()}!library function|(} \index{library function!\Vf{ReadKey}\Of{()}|(} %@+ The library function implements one scan of the $3 \times 4$ telephone keypad on the interface board. The algorithm is described in detail in section~\vref{sec:readKeyExplain}. The value @NOKEYPRESSED@ is defined in the header file \texttt{flight.h}, and is the return value of @ReadKey()@ if no key is pressed, otherwise it will return the values shown in table~\vref{tab:readKeyRetVal}. %@- \begin{table}[h] \centering \begin{tabular}{@{}lcccccccccccc@{}} %@+ \toprule \Vf{ReadKey}\Of{()} return value: & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 \\ Value printed on the key: & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & \# & 0 & $*$ \\ \bottomrule \end{tabular} \caption{The return values of the library function \Vf{ReadKey}\Of{()}.} \label{tab:readKeyRetVal} \end{table} The function prototype for @ReadKey()@ is %[ int ReadKey( void ); %] Program example~\vref{prg:readkey} shows the implementation of @ReadKey()@. \begin{program} %[\medskip #include #define NUMCOLS 3 #define NUMROWS 4 int ReadKey( void ) { int row, col; unsigned char pattern; for ( col = 0; col < NUMCOLS; ++col ) { KEYPAD = ~( 1 << col ); pattern = KEYPAD & 0x78; if ( pattern == 0x78 ) continue; for ( row = 0; row < NUMROWS; ++row ) if ( ( pattern & ( 8 << row ) ) == 0 ) return col + row * NUMCOLS; } return NOKEYPRESSED; } %]\relax \caption{The library function \Vf{ReadKey}\Of{()}. This is an implementation of the algorithm described in section~\vref{sec:readKeyExplain}.} \label{prg:readkey} \end{program} %@- \index{ReadKey@\Vf{ReadKey}\Of{()}!library function|)} \index{library function!\Vf{ReadKey}\Of{()}|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The \textsf{make} program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{make!program|(} In our course, all the C programs have occupied only one file. When you write a larger program for your final year project or in your work, it will be easier to write if you use a number of source files for your program. There is a program called \emph{make} that is very useful for larger programs. It is beyond the scope of this book to explain how to use \textsf{make}; I just want to point out to you that it will be worth learning how to use \textsf{make} for large programs. \index{make!program|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Why C and not assembly language?} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% In this course we use the C language. C is a high level language that has a number of features: \begin{itemize} \label{sec:ansi} \item C has been \emph{standardised}. The American National Standards Institute (\ANSI) has provided a standard for the language that not only covers the basic language, but also includes many library functions, such as @printf()@. \item All C compiler manufacturers work hard to be sure that their compiler is close to the standard. \item The result is that the language is perhaps the most \emph{portable} language available. \item C has good support for low-level access to the hardware of a computer---it was originally designed to implement the UNIX operating system. It is sometimes called a portable assembly language. \item C can easily be mixed with assembly language. \end{itemize} The C language is a high-level language. Once line of C may replace 6 lines of assembly language. However, it takes a programmer about the same time to write a line of assembly language as it does to write a line of C. So a programmer writing in C may produce up to 6 times the amount of code that the same programmer can produce when writing in assembler. This means that many manufacturers will prefer to have their products programmed in C rather than in assembler, since it will cost less and take less time to finish. This is particularly true for larger \emph{embedded} systems. The cost of using C rather than assembly is that a C program will usually translate into more machine language instructions than an equivalent assembly language program. An assembly language program can also be faster than a C program. In small systems where memory is very limited, assembly language may be the only option although the use of assembly language is declining. The usual practice in writing a C program is to write most in C, then to identify the short parts of the program that are executed most often, then re-write those few parts in assembly language, often starting with the assembly language output from the translator. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{The \qc interpreter---get it and use it!} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:qc} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{What is \qc?} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \qc is freely available software that can run \ANSI C programs. It requires very little hard disk space (only 360\,KB). It is an \emph{interpreter}, not a compiler---see the next section. \qc is written by Al~Stevens, a professional programmer who writes the column \emph{C Programming} in \emph{Dr Dobb's Journal}, \cite{drDobbs}. \qc is described in the book \cite{stevens}, available in the library. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{What is an interpreter?} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{interpreter!what is it?|(} To explain what a C interpreter is, we will compare it with a C compiler. A C compiler translates a C source file into a file containing machine language. This file is sometimes called an \emph{executable file}. If this is a cross-compiler, we can download the executable file into the memory of the \up system then execute it. The executable file can run at high speed. The executable file can be run without any further requirement for the C compiler. As an example, the spreadsheet program Excel has been written in C or \Cpp, but you do not need a C or \Cpp compiler to run Excel. A C interpreter, such as \qc, does not produce an executable file. Instead, the interpreter translates the C source file during the process of executing it. The program cannot be run without the interpreter: the translation to machine language is done each time the program is run. %@- There are many interpreters available for many languages. Perhaps \BASIC is the best known interpreted language: every copy of \MSDOS comes with a copy of the \texttt{qbasic} interpreter. There are many other interpreters available. The \MSDOS program \texttt{command.com} itself is a language interpreter; it interprets the \texttt{Bat} language.\footnote{Holy cow, Batman\index{Batman|nn}\e! Do you mean we have been using \index{BatLanguage|nn}Batlanguage all this time without realising it? Yes, Boy Wonder, it's true---now I realise why I like writing \textsf{bat}ch files so much.} Some other well known interpreted languages include \textsf{perl}\index{perl@\textsf{perl}}, \textsf{forth}, \textsf{awk}, \textsf{Java}\index{java@\textsf{Java}}, \textsf{Rexx}, \textsf{sed} and the shell scripting language \textsf{sh} that is part of \UNIX. \index{interpreter!what is it?|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{What can I do with \qc?} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{quincy@\qc!what can it be used for?|(} %@+ If we cannot produce an executable file, and we cannot run a program without the interpreter, what use is the \qc interpreter? The answer is that \qc is very useful for learning C---that is what it was written for. It is also useful for \ix{debugging} programs, since it has good debugging facilities: you can single step through your C programs, statement by statement, and you can set breakpoints to halt the execution of your program at any statement, and you can watch variables change as your program executes. The error messages are also often more helpful: for example, the program \texttt{testc.c} on page~\pageref{pag:testc} will produce the error message \texttt{missing ';'}, which is more clear than the message from the C compilers. You can develop a program using \qc, then compile it with an \ANSI compiler. %@- \index{quincy@\qc!what can it be used for?|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{How to get a copy of \qc} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:howCopyQc} %@- \index{quincy@\qc!obtaining|(} %@+ \qc is freely available to you. To take a copy to your computer at home, work or your friend's house, you need a floppy disk with only 360\,KB of free space. To copy it to a floppy disk, do the following: \begin{enumerate} \item Go to the \MPA, D226 \item Turn on one of the computers \item Select the ``Novell network'' option from the boot menu \item type: \texttt{f:} \meta{Enter} \item Type: \texttt{cd \bs quincy} \meta{Enter} \item Put a formatted floppy disk into the 3\fracSl14'' drive \item Run the batch file \texttt{copyit.bat} by typing: \texttt{copyit} \meta{Enter} \item When disk activity stops, remove your floppy disk \end{enumerate} To install the software on a computer, you need 360~kilobytes of free space on the hard disk. Here is how to install \qc. \begin{enumerate} \item Take the floppy disk home \item Make a directory on your computer by typing \texttt{md \bs qnc} \meta{Enter} \item Change to that directory with \texttt{cd \bs qnc} \meta{Enter} \item Copy the programs from your floppy disk to your computer's hard disk by typing: \texttt{xcopy a:\bs qnc\bs *.* .} \meta{Enter} \end{enumerate} %@- \index{quincy@\qc!obtaining|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Compiler errors: they are there to help you} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% A C compiler performs two main functions: \begin{itemize} \item it translates a C source file to machine language \item it detects syntax errors and shows their location and shows what type of syntax error each one is. \end{itemize} After you write a few C programs you will see some error messages appear when you run the compiler. Many people feel bad when this happens, as if the compiler is telling you that you don't know how to write proper C\e. I have seen some people look with fear at the error messages, then rush back to the editor to change the program at random, hoping that the errors would go away. This is not a good approach. Compiler error messages are your friends: they are there to help you. Here we see how. I am mainly talking about the error messages from the 68000 C cross-compiler system. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{What do I do if there are lots of error messages?} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{error messages!very many|(} \index{error messages!first one most important|(} \index{error messages!pausing|(} If there are many error messages, a good place to start is the first one. Very often, one syntax error causes the compiler to misunderstand parts of the program that follow. The first error message often gives a better clue to problems than some of the error messages that come immediately after. Suppose that there are so many error messages that they roll right off the top of the window?\footnote{It would be nice to redirect them to a file and look at them at leisure. Unfortunately, the programs write to standard error, which (in \MSDOS version 6 and 6.22) I do not know how to redirect. I hope that eventually the compiler manufacturer may reply to my question.} The best I can suggest at present is to press the \meta{Pause} key as soon as the error messages begin to appear. \index{error messages!very many|)} \index{error messages!first one most important|)} \index{error messages!pausing|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Error messages from different parts of the compiler} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The compiler consists of many programs. Each can generate error messages. The preprocessor, the main part of the compiler, and the linker can all give error messages. It may help to read appendix~\vref{sec:compiler}, and particularly to look at figure~\vref{fig:compiler}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Error messages from the preprocessor} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{unknown preprocessor directive|(} \index{error messages!preprocessor|(} The preprocessor deals with: \begin{itemize} \item all lines of your program that begin with @#@ \item all comments---the preprocessor removes these from its output. \end{itemize} Error messages do not give you a copy of the wrong line, but they do give you the line number. For example, the following program \texttt{error.c} has the @#include@ directive spelt wrongly: %[ #inclood int main( void ) { int i, j; for ( i = 0; i < 9; ++i ) j = i; return 0; } %] If you type \begin{verbatim} cc68k error.c \end{verbatim} the preprocessor will provide the following error message: \begin{verbatim} \texttt{error1.c: 1: Unknown preprocessing directive.} \end{verbatim} This indicates that the preprocessor did not understand the preprocessing directive ``@#inclood@''. This message usually means that the name following the `@#@' is spelt wrongly. Notice that the error message \emph{does} tell you where the error is: the `\texttt{1:}' means that the preprocessor found the problem on line~1. \index{unknown preprocessor directive|)} \index{error messages!preprocessor|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Error messages from the main part of the compiler} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{error messages!main part of the compiler|(} Most error and warning messages come from the main part of the compiler. You should find the cause of all \index{error messages!warnings}% \index{warnings}% warning messages as well as error messages. Remember---they are there to help you. Each error and warning message from the main part of the compiler tells you: \begin{itemize} \item the line number where the compiler found something wrong \item the exact location on the line where the compiler found something wrong \item the type of error or warning. \end{itemize} Here we look at a simple example. If you compile the following program (which was called \texttt{testc.c}):\label{pag:testc} %[ int main( void ) { return 0 } %] you will get the following error message: \begin{verbatim} } ^ "testc.c", 4: Syntax error. \end{verbatim} Firstly we have the line in which the compiler discovered the error. On the next line we have a little arrow `\texttt{\textasciicircum}' which shows the exact location in that line at which the compiler discovered the error. On the next line we have: \begin{enumerate} \item name of the file in which the compiler found the error \item next is the line number \item finally we have the nature of the error (but in this case, the message is very general). \end{enumerate} So we know that the compiler found the error when it reached line~4. But here is one important fact about error compiler messages: \index{error messages!occur just \emph{before} where the message indicates}% \eemph{the compiler will indicate a position \underline{after} the actual error}. In other words, you should usually look at the position in the program \emph{at the text just \underline{before} where the compiler indicates an error}. So what is the text just before where the compiler shows where it discovered the error? It is the character 0. Is there something wrong with that? Yes! We know it should be followed by a semicolon, `@;@', as discussed in section~\vref{sec:statements}. Let me say once more: the \emph{first} error message is often the most useful place to start.\index{error messages!first one most important} \index{error messages!main part of the compiler|)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Error messages from the linker} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- \index{unresolved externals@\textsc{unresolved externals}|(} \index{error messages!linker|(} %@+ The final message you see after successful compilation is \begin{verbatim} Errors: 0, Warnings: 0 \end{verbatim} This message comes from the linker. Sometimes you will see this message even after the main part of the compiler displays a warning message! The reason for this contradiction is that the \emph{linker} has no warnings to give. However, the linker can give error messages of its own. If you compile this little program (in the source file \texttt{prog.c}): %[ int main( void ) { Delay(); } %] you will see the following error messages: \begin{verbatim} Delay(); ^ "prog.c", 3: warning- Call of undeclared function 'Delay'. ERROR: (320) UNRESOLVED EXTERNALS: SYMBOL MODULE _Delay prog Errors: 1, Warnings: 0 \end{verbatim} The warning message is from the main part of the compiler; it is warning you because the function @Delay()@ has no declaration. As mentioned before in section~\vref{sec:declarations}, all functions and variables should be declared before they are used. The error message at the end is from the linker. It cannot find any library function @Delay()@ in the library to link with your program. Such an error message usually means that you have misspelled the name of a function or variable. %@- \index{unresolved externals@\textsc{unresolved externals}|)} \index{error messages!linker|)} %@+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Editing, compiling, downloading and running a program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:ecdr} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The program design} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The starting point is your \ix{program design}. I recommend writing the design in \emph{pseudocode}\index{pseudocode}. There is an example of the use of pseudocode on page~\pageref{pag:readkey}. Flow charts\index{flow charts} are also sometimes useful in working out complicated loops and decisions, mainly for assembly language sections of your program. Once you have the design, the rest is easy. This appendix is about how to assemble, download and run a program after you have designed it. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The general procedure for editing, assembling, downloading and running an assembly language program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Remember: for each program, you will always use the same five steps: \begin{multicols}{2} \raggedcolumns \begin{thinItemise} \item edit \item compile \item download \item run \item observe \end{thinItemise} \end{multicols} This is an appendix showing the general procedure for creating and running a program. Here we will call the program \meta{program}\texttt{.c}. Replace all occurrences of ``\meta{program}'' by the name of the program you are writing or working with. \begin{enumerate} \item Before the PC is turned on, be sure that you have an interface card plugged into a Flight-68k \up board, and that power is supplied to the \up board and that the serial connection is made to the PC. \item If you are using the seven-segment display or the LEDs, set the jumper on the interface board to the correct position. See figure~\vref{fig:jump}. \item If you turn on the computer, select \texttt{Novell Network} from the MS-DOS startup menu. \item Log into the Novell network by typing: \verb|f:login guest| \meta{Enter}% \index{network!logging in}% \index{logging into the network} \begin{explanation} The screen will fill with information about which drive letter is mapped to which drive. At the top a message says ``\texttt{You have logged into the TYEE22601 File Server}.'' This indicates that you have logged in successfully. \end{explanation} % The computer should then automatically log you into the Novell % network. \begin{explanation} The network provides access to the Hewlett Packard C cross-compiler. \end{explanation} \item Start up microsoft windows by typing: \texttt{win} \meta{Enter} \end{enumerate} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Editing the program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %@- Here we use the same editor---\ed---as in previous labs. You can also use \textsf{Emacs}\index{emacs@\textsf{Emacs}} or \textsf{Q-edit} if you prefer. %@+ Each program you write needs the format shown in program example~\vref{prg:progTemplate}. Note too that any variable or function you use must be \emph{defined} before it is used. \begin{program} %[ #include /* Define global variables here. */ /* Define your functions here. Each function has a similar format */ /* to @main()@; the local variables come first. */ int main( void ) { /* Define local variables here. */ /* Put the %%\emph{body}%% of your program here */ return 0; } %] \caption{All your programs will have a form similar to this.} \label{prg:progTemplate} \end{program} \begin{enumerate} \item Start the editor \ed by double-clicking on the \ed icon in the window labeled \hp. \begin{explanation} Do \emph{not} start up more than one editor, and do not exit from the editor until the end of this workshop. It is easier and quicker to leave a single copy of the editor, DOS prompt and terminal programs running all the time and to switch between them using \meta{Alt-Tab}, or the mouse. \end{explanation} \item Remember the following points about the C language: \begin{itemize} \item C is case sensitive; type @#include@ not \Kf{\#Include}, etc. \item Each statement must be terminated with a semicolon ``@;@''. \item Do not put a semicolon on the same line as the keyword @if@, because the statement only finishes after the body of the @if@ statement, \ie you should write %[ if ( pattern != 0x78 ) keyPressed = true; %] and \eemph{not:} %[ if ( pattern != 0x78 ); keyPressed = true; %] The @if@ statement above should finish at the end of ``@keyPressed = true;@''. The same thing is true of the @while@ statement. \end{itemize} \item Save your edited program as \meta{program}\texttt{.c} using \meta{Alt-f}\meta{s}. \begin{explanation} Note: the name \emph{must} have \texttt{.c} at the end, otherwise the compile will not succeed. \end{explanation} \end{enumerate} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Compiling your program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{enumerate} \item If you have no \DP window open, open \emph{one}, otherwise switch to the previous \DP window using \meta{Alt-Tab}. \item Compile your program by typing \texttt{cc68k }\meta{program}\texttt{.c}. \begin{explanation} If there are any error messages shown, edit your file again to correct the error, \emph{save} the changed file, then re-compile your program until you get no error messages. Ask for help if you cannot see the reason for the error message. Note that the filename must be in \emph{lower case}, otherwise the compile will not succeed. The compiler produces the file \texttt{aout.abs} which contains \emph{machine language} encoded in \emph{Motorola S-record format}. To find out more about Motorola S-records, see appendix~E of the \emph{Flight-68K User Manual}. You can also look at the file \texttt{aout.abs} with a text editor, since it is a text file. \end{explanation} \end{enumerate} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Downloading the program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{downloading|(}% Downloading a program is sending the assembler output from the \PC to the \FLIGHT board by a serial transfer. I assume here that the output from the assembler was the file \meta{program}\texttt{.bin}. If you are working with a different filename, use that name instead of \meta{program}. \begin{enumerate} \item Start up the \te program by double-clicking once on the \te icon. \begin{explanation} If \te is already running, \emph{do not} start a second \te program running; instead, switch back to the \te program you started earlier with \meta{Alt-Tab}. \end{explanation} \item Press \meta{Enter} two times. \begin{explanation} %@- \index{monitor firmware!prompt}% \index{F prompt@\texttt{F\Gt} prompt!how to get}% %@+ If no \verb|F>| prompt appears, press the RESET button on the \FLIGHT board (not the one on the \PC!) then press \meta{Enter} three times. Call the lecturer or technician if you still get no \verb|F>| prompt. \end{explanation} \item Type \meta{l}\meta{t}. \begin{explanation} There are some programs in the \FLIGHT \EPROM\e.\label{pag:monitor} These programs are called the \emph{monitor} programs. They are also called \emph{firmware} because they remain after the power is turned off. The command \meta{l}\meta{t} is a command to the monitor firmware to be ready to receive a serial stream of characters from the \PC. \end{explanation} \item Press the \meta{Enter} key When prompted with: \verb|ENTER OFFSET ( IF NONE) : | \begin{explanation} \index{downloading!doesn't work}% Many people forget this little step! If you do, the transfer will not work, but all sorts of strange characters may appear on your screen, and perhaps the terminal will beep. \end{explanation} \item Press \meta{Enter} when asked for an offset. \item With the mouse, select the \textsf{Transfers} menu, and from this select the \textsf{Send Text File\ldots} menu item. \item Type \texttt{aout.abs} \meta{Enter} into the dialog box. \end{enumerate} \index{downloading|)}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Running the program} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{enumerate} \item Type \meta{g}\meta{o}, then enter the starting address \texttt{400400}, as always. \end{enumerate} \Closesolutionfile{exsolns} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Solutions to exercises} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{sec:solutions} \Readsolutionfile{exsolns} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \bibliographystyle{is-alpha} \clearpage \addcontentsline{toc}{chapter}{References} \label{sec:references} \bibliography{mc68k} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \clearpage% \addcontentsline{toc}{chapter}{Index} \printindex % INDEXING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \vspace*{\fill} \thispagestyle{plain} \begin{center} Reference: \referenceNum\\[1ex] \tiny \begin{tabularx}{\linewidth}{|l|c|c|X|} \hline \multicolumn{1}{|c|}{Compiled by} & Issue & Date & \multicolumn{1}{c|}{Remark} \\ \hline Nick Urbanik & 1 & \RCSDate & This is a major reworking of workshop 0 for 2501, 2503 and 2504 from 1994/95. I have turned it into a book format and have improved the organisation, and added more useful information, such as extended information on the C language as we use it in our laboratory, information about the freely available \qc interpreter and an index and list of references. I have also included many exercises, all with solutions. \\ \hline \end{tabularx} \end{center} \end{document}