\documentclass[11pt,a4paper]{article}

% 2006-07-07 EW Adventures-1.tex
% 2006-07-22 EW Adventures-2.tex
% 2006-08-14 EW Adventures-2a.tex
% 2007-01-10 EW Adventures-3.tex
%
% Aufgebessert nachdem ich 'ne Reihe Optimierungen gemacht hatte
% Und dann nochmal komplett umgeräumt!
%

% language support
\usepackage[german]{babel}

%\usepackage[latin1]{inputenc} % can use Umlauts now "u instead of "u
%\usepackage{lmodern} % better fonts
%\usepackage{pslatex} % use native PostScript fonts

\usepackage{url} % \url{} \path{} with correct "hyphenation"
%\usepackage{fancyvrb} % for code examples

% \voffset-10mm
% \pagestyle{empty}
% \pagestyle{plain}
% \pagestyle{headings}
% \renewcommand{\baselinestretch}{1.08}
%\usepackage{xspace}
\parindent=0pt
%\newcommand{\Forth}{\textsc{forth}\xspace}
\begin{document}

\title{Adventures in Forth 3}

\author{Erich W"alde}

\maketitle

\begin{multicols}{2}

  
  \section{Teil 1: Ausgaben auf \texttt{uart0}}
  \label{sec:uart0}

  Der R8C13-Controller hat eine weitere serielle Schnittstelle
  (\texttt{uart0}), die beim Programmieren nicht ben"otigt wird. "Uber diese
  sollen Daten verschickt werden. Die Daten sollen als ASCII-Zeichenkette
  verschickt werden, abgeschlossen mit CR LF. Auf ein Protokoll zum
  Absichern des Datentransports soll an dieser Stelle verzichtet werden. Es
  sind drei Aufgaben zu l"osen:

  \begin{enumerate}\itemsep=0pt\parskip=0pt
  \item Initialisieren der Schnittstelle
  \item Formatieren der zu verschickenden Zeichenkette
  \item Ausgabe der Zeichenkette auf die Schnittstelle
  \end{enumerate}

  
  Um die f"ur \texttt{uart0} wichtigen Register und Einstellungen zu finden,
  habe ich das Datenblatt konsultiert. Die Schnittstelle liegt auf den Pins
  4 und 5 von Port 1.

%----------------------------------------------
\begin{verbatim}
$E1 Constant port1   \ port 1
$E3 Constant pddr1   \ port direction reg. 1

&4  Constant PinTxD0 \ P1.4 is TxD0
&5  Constant PinRxD0 \ P1.5 is RxD0

                     \ uart0
$A0 Constant U0MR    \ mode register
$A4 Constant U0C0    \ control register 0
$A5 Constant U0C1    \ control register 1
&0  Constant TE      \ transmit enable bit
&1  Constant TI      \ transmit buffer empty?
$B0 Constant UCON    \ control register 2
&2  Constant U0RRM   \ receive mode bit
$A1 Constant U0BRG   \ bit rate
$A2 Constant U0TBRL  \ transmit buffer, low
\end{verbatim}

  Die Schnittstelle soll mit 38400 baud, 8 Datenbits, kein Parit"atsbit, 1
  Stopbit und ohne handshake betrieben werden. Die zugeh"origen
  Einstellungen finden sich ebenfalls im Datenblatt. Schwierig ist das
  alles nicht, aber ein wenig Geduld hilft.

%----------------------------------------------
\begin{verbatim}
: uart0-init ( -- )
  PinTxD0 port1 bset \ TxD0 is 1
  PinTxD0 pddr1 bset \ TxD0 is output
  PinRxD0 pddr1 bclr \ RxD0 is input
  $05 U0MR c!        \ 8N1, internal clock
  $00 U0C0 c!        \ clock f1, TxD0 CMOS out,
                     \ . data on falling edge,
                     \ . lsb first
  U0RRM UCON bclr    \ continuous receive OFF
  &32 U0BRG c!       \ 38400 @ 20 MHz
;
\end{verbatim}

  Als N"achstes definieren wir ein Wort, welches ein Zeichen auf
  \texttt{uart0} ausgibt. Zuerst warten wir, bis das letzte Zeichen
  "ubertragen ist, d.h.\ bis das Bit \texttt{TI} gel"oscht wurde. Danach
  schreiben wir das Zeichen in das Senderegister \texttt{U0TBRL}, und sagen
  dem Controller, dass ein neues Zeichen zu verschicken ist, durch Setzen
  des Bits \texttt{TE}.

%----------------------------------------------
\begin{verbatim}
: uart0emit ( n -- )
                     \ transmit buffer empty?
  BEGIN TI U0C1 btst UNTIL
  U0TBRL c!          \ n to transmit buffer
  TE U0C1 bset       \ enable transfer
;
\end{verbatim}

  Dieses Wort l"asst sich jetzt schon einsetzen, um die serielle Verbindung
  zu pr"ufen. \texttt{uart0}, auf der Elektorplatine mit \textit{COM port}
  bezeichnet, wird mit einem Rechner verbunden (es gibt jetzt 2 Kabel vom
  Rechner zur Platine). Ein Programm wie \textit{minicom} oder
  \textit{Hyperterminal} liest dann die Zeichen, die der Kontroller
  verschickt. Wer die ASCII-Tabelle auswendig kann, ist klar im Vorteil:

\begin{verbatim}
Gforth terminal
Press ENTER to get ok from connected device.
Leave with BYE
include adv3_uart0.fs  ok
uart0-init  ok

$48 uart0emit $61 uart0emit $6c uart0emit ok
$6c uart0emit $6f uart0emit $21 uart0emit ok
\end{verbatim}

  Das produziert am \textit{anderen Ende} ein freundliches
 
\begin{verbatim}
Hallo!_
\end{verbatim}

  wobei \texttt{\_} den Cursor bezeichnet. Die gr"o"ste H"urde w"are damit
  geschafft. Allerdings ist es schon ziemlich unpraktisch, eine
  Zeichenkette so umst"andlich auszugeben. Das Wort \texttt{type} ist in
  allen Forths vorhanden und gibt eine Zeichenkette aus. Wenn man ein wenig
  die Dokumentation studiert, dann findet man, dass \texttt{type} zwei
  Argumente auf dem Stapel erwartet: \texttt{(addr n -- )}. \texttt{type}
  erwartet dann eine Zeichenkette der L"ange \texttt{n} an der Adresse
  \texttt{addr}. Ein Wort von der Art wie \texttt{type} k"onnen wir uns
  selbst schreiben:

%----------------------------------------------
\begin{verbatim}
\ send n bytes starting at addr
: uart0type ( addr n -- )
  0 DO               \ do-loop consumes n
    dup I +          \ { consumes copy of addr
    c@ uart0emit     \   get+send byte
  LOOP               \ }
  drop               \ consumes addr
;
\end{verbatim}

  Mit Hilfe des Wortes \texttt{s"} wird die Welt sch"on. \texttt{s"}
  produziert aus dem nachfolgenden Text (abgeschlossen mit \texttt{"}) eine
  Zeichenkette, und legt die Adresse und die L"ange auf den Stapel.
  \texttt{uart0type} benutzt diese Information und

\begin{verbatim}
s" Hallo!" uart0type
\end{verbatim}

  produziert das gleiche freundliche \texttt{Hallo!} wie die "Ubung vorher,
  nur viel bequemer. Ein zus"atzliches Wort \texttt{uart0cr} vereinfacht die
  Sache weiter:

\begin{verbatim}
: uart0cr ( -- )
  $0d uart0emit $0a uart0emit
;
\end{verbatim}

% ====================================================================
  \section{Teil 2: Ausgabeumleitung}
  \label{sec:redir}

  Wenn man auf das Wort \texttt{type} gesto"sen ist und ein wenig in der
  Dokumentation von gforth (auch das Wort \texttt{see} wurde mein Freund)
  und/oder im Buch gelesen hat, dann ist es nicht sehr weit zu sagen: W"are
  doch sch"on, wenn man die gleiche Ausgabe am gforth-terminal, auf
  \texttt{uart0} und auf das LCDisplay benutzen k"onnte. Etwa so:

\begin{verbatim}
: msg s" blabla" ;
: run
  to-lcd msg
  to-uart0 msg
  to-stdout msg
;
\end{verbatim}

  Die kurze Antwort ist: \textit{Man kann}.

  Um dem gleichen Wort verschiedene Aufgaben unterzuschieben benutzt man so
  etwas wie \textit{Zeiger auf Funktionen}. Das haben wir bei
  \texttt{timeup} in der zweiten Folge schon einmal gesehen: Man kann die
  \textit{Ein\-sprung\-a\-dres\-se} eines Wortes in einer Variablen speichern und
  dann mit \texttt{execute} die Ausf"uhrung erreichen. Zur Erinnerung:

\begin{verbatim}
create Jobs ' job.tick , job.sec , ...
...
... DO
  ...
  I cells Jobs + @ execute
  ...
LOOP
\end{verbatim}

  Die Frage hei"st also: kann man mit den Worten \texttt{type} (gib eine
  Zeichenkette aus) und \texttt{emit} (gib ein Zeichen aus) so eine
  Akrobatik veranstalten? Also eigentlich m"usste man ja die Adresse von
  \texttt{type} in einer Variablen speichern und dann alle Worte, die eine
  Ausgabe machen, so umdefinieren, dass sie "uber die Variable auf die
  Worte \texttt{type} und \texttt{emit} zugreifen --- nee, das ist nicht
  sch"on, denn es gibt einige solcher Worte (\texttt{.} \texttt{u.}
  \texttt{d.} \texttt{d.r} \texttt{."} usw.). Da spart man nichts, wenn man
  die alle umschreiben muss.

  Jetzt stellt sich aber g"unstigerweise heraus, dass \texttt{type} selbst
  nur auf ein Wort namens \texttt{(type)} verweist. Das l"asst hoffen.

  Wir basteln uns also drei Variablen, die Zeiger auf die gerade
  ben"otigten Versionen von \texttt{type}, \texttt{emit} und der
  Vollst"andigkeit halber \texttt{cr} beinhalten. 

\begin{verbatim}
Variable 'type  \ pointer to correct "type"
Variable 'emit  \ pointer to correct "emit"
Variable 'cr    \ pointer to correct "cr"
\end{verbatim}
  
  Dann brauchen wir drei Worte, die diesen Variablen die korrekten Werte
  verpassen, falls wir die Ausgaben auf \texttt{lcd}, \texttt{uart0} oder
  das gforth terminal (\texttt{stdout}) umbiegen wollen. Dabei gibt es noch
  eine kleine Schwierigkeit. Normalerweise liefert uns das Wort \texttt{'}
  (\textit{tick}) die Ein\-sprung\-a\-dres\-se des nachfolgenden Wortes --- au"ser
  in einer \texttt{:}-Definition. Dort muss man stattdessen \texttt{[']}
  benutzen. Das liegt daran, dass innerhalb einer \texttt{:}-Definition
  Forth im compile-Modus l"auft. Wir wollen aber nicht \texttt{'}
  einkompiliert haben, sondern das Ergebnis von \texttt{' wort}. Das Wort
  \texttt{[']} schaltet daher den compile-Modus vor"ubergehend aus.

\begin{verbatim}
: to-stdout ( -- )
  ['] (type)    'type !
  ['] (emit)    'emit !
  ['] cr        'cr   !
;
: to-lcd ( -- )
  ['] lcdtype   'type !
  ['] lcdemit   'emit !
  ['] lcdcr     'cr   !
;
: to-uart0 ( -- )
  ['] uart0type 'type !
  ['] uart0emit 'emit !
  ['] uart0cr   'cr   !
;
\end{verbatim}

  Jetzt fehlt noch die Verbindung zwischen den alten Worten und der
  Variablen, die auf die umgeleiteten Worte zeigt.

\begin{verbatim}
: >type ( -- ) 'type @ execute ;
: >emit ( -- ) 'emit @ execute ;
: >cr   ( -- ) 'cr   @ execute ;
\end{verbatim}

  Die Umleitung l"asst sich jetzt aktivieren, indem man \texttt{type} auf
  \texttt{>type} zeigen l"asst. Das Wort \texttt{is} schiebt dem
  nachfolgenden \texttt{type} das Ergebnis von \texttt{['] >type}
  als Adresse der neuen Anweisungen unter.

\begin{verbatim}
: +redir ( -- )
 ['] >type is type \ "type" output redirection
 ['] >emit is emit \ "emit" output redirection
;
: -redir ( -- )
  ['] (type) is type
  ['] (emit) is emit
;
to-stdout   \ default
\end{verbatim}

  Und wie funktioniert das jetzt? Wir schreiben einen kleinen Test. In
  \texttt{init} wird die serielle Schnittstelle \texttt{uart0}
  initialisiert, einmal CR LF verschickt und die Anzeige auf dem LCDisplay
  gel"oscht. Dann wird die Umleitung eingeschaltet.

  \texttt{msg} produziert zwei Zeilen Ausgabe. Man beachte, dass hier nicht
  \texttt{cr}, sondern \texttt{>cr} verwendet wird. Das ist der Preis
  daf"ur, dass \texttt{cr} eben kein Zeiger auf ein anderes Wort ist. Wenn
  man jetzt dem Wort \texttt{cr} mit \texttt{' >cr is cr} etwas anderes zu
  tun unterschiebt, dann verliert man den Zugriff auf die
  Originalanweisungen. Das kann man dann auch nicht mehr zur"ucksetzen. Es
  sieht allerdings so aus, als w"urde \texttt{cr} nur vom Programmierer
  benutzt --- damit bleibt alles unter unserer Kontrolle. Wenn alles
  klappt, dann sieht die Ausgabe so aus:

\begin{verbatim}
cr run-test
String 1  32
String 2   x
\end{verbatim}

  \texttt{run-test} schickt diese Zeichenketten an alle drei
  Ausgabeger"ate: auf das LCDisplay, auf die serielle Schnittstelle und auf
  die Ausgabe im gforth terminal.

\begin{verbatim}
include adv3_uart0.fs
include adv3_redir.fs
: init-test
  uart0-init uart0cr
  lcdpage
  +redir
;
: msg
  ." String 1" $20 s>d4 d.r >cr
  ." String" space ." 2" 3 spaces $78 emit
;
: run-test
  init-test
  to-lcd    msg
  to-uart0  msg
  to-stdout msg
;
\end{verbatim}

  Wirklich sch"on. Man hat Zeiger-auf-Funktionen in der Gegend
  herumgebogen. Aber das geht doch mit \textsc{\$meine\_lieblings\_sprache}
  auch, oddrrr? Vielleicht. Aber in diesem Fall haben wir immerhin zwei
  Funktionen aus der Sprache (\texttt{emit}, \texttt{type}) verbogen ---
  auch wenn das netterweise schon vorbereitet war. Das f"uhrt dazu, dass
  wir die Worte \texttt{.}, \texttt{."}, \texttt{d.r} etc.\ f"ur jede
  Ausgabe einfach weiterverwenden k"onnen, wie wenn das immer so gegangen
  w"are. Zur"uckbiegen geht "ubrigens auch ohne Verluste. Ob das alles in
  \textsc{\$meine\_lieblings\_sprache} immer noch so einfach ist?


  Wenn man vor dem n"achsten \texttt{empty} noch \texttt{-redir} eingibt,
  dann kann man sich auch den Reset sparen. Erg"anzungen, Kommentare,
  Korrekturen sind ausdr"ucklich erw"unscht. Sie erreichen mich unter
  \url{ew.forth@nassur.net}

\section{Referenzen}

\begin{enumerate}
\item \label{Adv1} E. W"alde, Adventures in Forth, Die 4. Dimension 3/2006, Jahrgang 22
\item \label{Adv2} E. W"alde, Adventures in Forth 2, Die 4. Dimension 4/2006, Jahrgang 22
\item \label{r8c-ds} Renesas R8C/13 Datenblatt, siehe \url{www.renesas.com}
\end{enumerate}
\end{multicols}

\section{Listings}

\begin{quote}
\begin{small}
\begin{multicols}{2}
\listinginput[1]{1}{2007-01/adv3_uart0.fs}      % uart0 module
\listinginput[1]{1}{2007-01/adv3_redir.fs}      % uart0 module
\listinginput[1]{1}{2007-01/adv3_redir_test.fs} % uart0 module
\end{multicols}
\end{small}
\end{quote}

\end{document}




