\documentclass[ngerman]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\setcounter{secnumdepth}{0}
\setcounter{tocdepth}{0}

\usepackage{a4}
\usepackage{moreverb}
\usepackage{url}
\usepackage{multicol}

\usepackage{babel}
\makeatother

\begin{document}
\title{Umwandlung von HEX in BCD--Zahl in High--Level--Forth\\Oder: Schlag nach bei forthwiki.}[Umwandlung von HEX in BCD]
\author{Bernd Paysan\and Michael Kalus}
\maketitle

\def\figurename{Listing}

\begin{abstract}
Dieser kleine Beitrag geht auf einen thread in \url{de.comp.lang.forth} zurück. Gleichwohl  etliche Mikroprozessoren eine Instruktion haben, die diese Umwandlung unterstützt, wird  exemplarisch gezeigt, was zu tun ist, wenn eine solche Unterstützung fehlt oder aus Gründen der Portabilität des Forth solche Instruktion gar nicht genutzt werden soll.
\end{abstract}

\begin{multicols}{2}

Ausgangspunkt war die Frage, ob ein minimaler Forthkern für Steuerungen mit einer spartanischer Ausgabe in Hex auskommt, oder ob die Umwandlung in eine andere Zahlenbasis nötig ist, und ob  dann die Division implementiert sein muss. B.\ Paysan zeigte, wie eine dezimale Zahlenausgabe ohne Divison in 
High--Level--Forth gemacht werden kann.  

Nehmen wir ein 32--Bit--PC--Forth als Grundlage. (Bei 64 Bit muss man die Maske halt mit 16ern/8ern/4ern/2ern auffüllen). Ihr findet den Code auch im Forth--Wiki.

\section{\texttt{2*} und \texttt{bcd2*}}
Wenn Du das \verb|bcd2*| in \figurename\ \ref{bcdlisting} durch ein ganz ordinäres \verb|2*| ersetzt, siehst Du, was da eigentlich passiert: Du schiebst die Bits von der einen Zahl in die andere Zahl. Durch das \verb|bcd2*| änderst Du dabei die Codierung der Zahl von binär zu BCD. Wenn man --- wie hier --- den \verb|bcd2*| emulieren muss, ist das kein großer Gewinn gegen die Division, aber wie gesagt: Auf fast allen Controllern ist das nicht nötig, weil die ja so einen BCD--Befehl bereits eingebaut haben. 

\section{Exkurs: Die BCD--Codierung}

Um eine Zahl als BCD--Zahl darzustellen, wird jede dezimale Ziffer (0 bis 9) durch jeweils 4 Bit, also ein Halbbyte (Nibble), im Dualsystem dargestellt ($0000_2$ bis $1001_2$). Die übrigen sechs Werte, die mit 4 Bit darstellbar sind ($1010_2$ bis $1111_2$), stellen keine gültigen BCD--Zahlen dar (Pseudotetraden). Sie werden in manchen Systemen zur Codierung von Vorzeichen, Überträgen oder Kommata verwendet.

Zur Codierung von Zahlen mit mehr als einer Dezimalziffer werden die BCD--Darstellungen der einzelnen Ziffern hintereinander gesetzt (zum Beispiel wird die Zahl 2687 als $0010\; 0110\; 1000\; 0111_2$, beziehungsweise ohne trennende Leerzeichen als $0010011010000111_2$ dargestellt). Mit einem Byte (8 Bit) können also zwei Dezimalziffern dargestellt werden. Werden die 4 Bits einer BCD--Zahl jeweils in den niederwertigen Bits codiert und die restlichen 4 Bits mit Nullen aufgefüllt, so spricht man von einer ungepackten BCD--Zahl. Werden beide Hälften eines Bytes mit je einer BCD--Zahl belegt, so nennt man dies entsprechend eine gepackte BCD--Zahl.
\end{multicols}
\vspace*{-1ex}
Quellen:\\
\hspace*{2ex}Bernd Paysan in \url{de.comp.lang.forth}; Mo 13 Mär.\ 2006 14:30\\
\hspace*{2ex}Wikipedia, \emph{BCD-code}
\hspace*{\fill}mka\\

\begin{figure*}[b]
\begin{quote}
\begin{small}
\begin{listing}{1}
decimal
: hex. ( x -- )  36 emit  base @  swap hex u.  base ! ;
  
: bcd2* ( bcd1 -- bcd2 ) 
  dup $88888888 and 2/ dup 2/ or swap 2* swap + \ forward carry correction 
  dup $88888888 and over $44444444 and 2 pick $22222222 \ BCD correction 
  and 2* or 2* and 2/ dup 2/ or + ; 

: hex>bcd ( u -- bcd ) 
  0 8 cells 0 DO  bcd2* over 0< - swap 2* swap  LOOP  nip ; 

\ test-code:
\ decimal 12345678  hex .s \ Ausgabe: <1> BC614E  ok
\ hex>bcd hex.             \ Ausgabe: $12345678  ok
\
\ decimal 98765432  hex .s \ Ausgabe: <1> 5E30A78  ok
\ hex>bcd hex.             \ Ausgabe: $98765432  ok
\end{listing}
\end{small}
\end{quote}
\caption{\label{bcdlisting}Umwandlung nach BCD}
\end{figure*}


\end{document}
