% \iffalse %% %% File `bitfield.dtx'. %% Copyright (C) 1997-2001 Reuben Thomas (rrt@sc3d.org) %% Copyright (C) 2001 Roland Illig %% This file is distributed under the LaTeX Project Public License, %% and comes with no warranty. %% % %<*dtx> \ProvidesFile{bitfield.dtx} % % \ProvidesFile{bitfield.drv} % \fi % % \iffalse %<*driver> \documentclass{ltxdoc} \usepackage{url,dashbox,bitfield} \begin{document} \DocInput{bitfield.dtx} \end{document} % % \fi % % \GetFileInfo{bitfield.dtx} % \CheckSum{243} % % \MakeShortVerb{\|} % % \changes{v1.00}{1 Mar 97}{First version (unreleased)} % \changes{v1.17}{2 Jun 99}{Dashed boxes, stacks and sub-columns % added; various bugs fixed} % \changes{v1.18}{28 Jul 01}{Made into a doc package; documentation % added. At signs inserted into private macro names. Tidied up some % infelicities.} % \changes{v1.19}{8 Aug 01}{Changed some references to dashbox that % should be to bitfield, and changed ``dashdbox'' refs to ``dashbox'' % to cope with the renaming of that package. Uncommented the commands % starting |\NeedsTeXFormat| so they are copied into the package.} % \changes{v2.00}{12 Dec 01}{Added the option to have a plain label % above the box rather than a rule (thanks to Roland Illig); changed % the bit field commands to take a style string rather than having % variants of the commands, renamed internal and external commands to % start with |bit| rather than |bits|, to avoid confusion. Corrected % description of package in |\ProvidesPackage| (it was using that for % dashbox!). Made the package require calc 4.1b (to avoid a bug in % 4.1a), and the most recent version of dashbox.} % % \title{Bit field diagrams} % \author{Reuben Thomas\\\url{rrt@sc3d.org}\and Roland Illig} % \date{12th December 2001} % \maketitle % % \begin{abstract} % |bitfield| provides an environment and commands for drawing % bit field diagrams, which can be used to describe instruction sets, % object code formats, and other bit field based data structures. % \end{abstract} % % \section{User interface} % % \subsection{Bit field environment} % % \DescribeEnv{bitfield} % Bit field diagrams are drawn in the |bitfield| environment, which % takes two arguments. The first, optional argument gives the width of % a word (default 4in), and the second the number of bits per word. % Each word comprises a number of bit fields, and the words are drawn % as a column. Words are ended by |\\|. % % \DescribeEnv{xbitfield} % The |bitfield| environment is actually written in terms of the % |xbitfield| environment, which has an extra parameter (the second), % giving the left and right margin (the |bitfield| environment uses % |\layersize|). % % \DescribeMacro{\bits} % The basic bit field command is |\bits|. % |\bits[|\textit{style}|]{|\textit{label}|}{|\textit{bits}|}{|\textit{contents}|}| % draws a bit field with the given label, number of bits and contents. % The optional argument gives the bit field style, which is a string of % flag letters. |d| draws the box dashed, useful for indicating % optional structures. and |r| puts the label text in a rule % which spans the box. % % \DescribeMacro{\bitstack} % To indicate plurals, for example, where a particular word or data % structure may be repeated, |\bitstack| can be used, which produces % the appearance of a stack of bit fields. It may only be used once % per word (i.e.\ once per line). % |\bitstack[|\textit{style}|]{|\textit{label}|}{|\textit{bits}|}{|\textit{contents}|}| % draws a stack of width \textit{bits}. The first three arguments are % as for |\bits|. The \textit{contents} will typically be a |\bits| % command; |\bitstack| itself only draws the stack effect. The % enclosed |\bits| should not have a label. % % For technical reasons, the first bit field on each line is % |\fboxrule| narrower than it should be; this should not be % noticeable for typical values of |\fboxrule|. (See % section~\ref{fudge} for the full story.) % % \subsection{Alternatives} % % \DescribeMacro{\bitsub} % Sometimes a data structure may have its bit fields divided in % different ways according to circumstances, or a particular field may % hold one of a small range of values. To show these sorts of % alternatives, you can use |\bitsub|, which produces a sub-column of % bit fields, vertically centred on the current word. % |\bitsub[|\textit{style}|]{|\textit{label}|}{|\textit{bits}|}{|\textit{contents}|}| % makes a sub-column of width \textit{bits}. The first three arguments % are as for |\bits|, and \textit{contents} is the series of bit % fields to go in the column, as if in a |bitfield| environment, % separated by |\\|. % % \DescribeMacro{\bitsubspaced} % |\bitsub| draws the alternative bit fields contiguously; to make % room for a label on each bit field, use |\bitsubspaced|. % |\bitsubspaced| is the same as |\bitsub|, except that the second % argument is omitted; a label can be given as that of the top-most % bit field in the contents. % % \subsection{Helper commands} % % Some other commands are provided to help draw bit field diagrams. % \DescribeMacro{\bitdots} |\bitdots| draws a vertical ellipsis, % like |\vdots|, but centred on the column of words. % \DescribeMacro{\bittext} |\bittext{|\textit{text}|}| allows text % to be inserted between words in a column, adding appropriate % vertical spacing. % % \subsection{Style parameters} % % There are many style parameters that allow the layout of bit field % diagrams to be customised: % % \begin{itemize} % \item[]\hskip-\leftmargin % \DescribeMacro{\bitalign} % |\bitalign| gives the alignment within the |bitfield| % environment; defaults to |\centering|. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitboxsep} % |\bitboxsep| is the width of the left and right margins of the % bit field box; defaults to |\fboxsep|. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitboxdepth} % |\bitboxdepth| is the depth of a bit field box; defaults to % 0.9ex. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitboxheight} % |\bitboxheight| is the height of bit field box; defaults to % 3.2ex. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitskip} % |\bitskip| is the vertical space between words; defaults to % 0.8ex. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitrule} % |\bitrule| is the thickness of the label rule; defaults to % |\fboxrule|. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitlabellift} % |\bitlabellift| is the lift of the label above the top of % the box; defaults to 0.4ex. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitruleheight} % |\bitruleheight| is the height of the label rule above the % baseline (top of the box); defaults to 0.6ex. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitruleendlift} % |\bitruleendlift| is the height of the ends of the label % rule above the baseline; defaults to 0.2ex. % \end{itemize} % \StopEventually{} % % % \section{Example} % % Here is an example showing most of the features of the |bitfield| % package: % % \begin{center} % \begin{bitfield}{32} % \bits{31}{1}{s} % \bits{30 \hfill 23}{8}{eeeeeeee} % \bits{22 \hfill 0}{23}{mmmmmmmmmmmmmmmmmmmmmm} \\ % \end{bitfield} % \end{center} % % \begin{center} % \begin{bitfield}{16} % \bits[r]{sixteen}{16}{16 bits wide}\\ % \bits[d]{}{4}{optional}\bitstack{}{4}{\bits{}{4}{many}}\\ % \bits[r]{}{8}{fixed}% % \bitsubspaced{8}{\bits{}{8}{optional 1}\\\bits{}{8}{optional 2}}\\ % \end{bitfield} % \end{center} % % % \section{Implementation} % % \subsection{Preliminaries} % % Make sure we've got what we need, and announce the package. % % \begin{macrocode} %<*package> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{bitfield}[2001/12/12 v2.00 Bit field diagrams] \RequirePackage{dashbox}[2001/12/11] \RequirePackage{calc}[1998/07/07] \RequirePackage{ifthen} % \end{macrocode} % % \subsection{Style parameters} % % Define and give the default values of the style parameters. % % \begin{macro}{\bitalign} % \begin{macrocode} \newcommand{\bitalign}{\centering} % \end{macrocode} % \end{macro} % \begin{macro}{\bitboxsep} % \begin{macrocode} \newlength{\bitboxsep} \setlength{\bitboxsep}{\fboxsep} % \end{macrocode} % \end{macro} % \begin{macro}{\bitboxdepth} % \begin{macrocode} \newlength{\bitboxdepth} \setlength{\bitboxdepth}{0.9ex} % \end{macrocode} % \end{macro} % \begin{macro}{\bitboxheight} % \begin{macrocode} \newlength{\bitboxheight} \setlength{\bitboxheight}{3.2ex} % \end{macrocode} % \end{macro} % \begin{macro}{\bitskip} % \begin{macrocode} \newlength{\bitskip} \setlength{\bitskip}{0.8ex} % \end{macrocode} % \end{macro} % \begin{macro}{\bitrule} % \begin{macrocode} \newlength{\bitrule} \setlength{\bitrule}{\fboxrule} % \end{macrocode} % \end{macro} % \begin{macro}{\bitlabellift} % \begin{macrocode} \newlength{\bitlabellift} \setlength{\bitlabellift}{0.4ex} % \end{macrocode} % \end{macro} % \begin{macro}{\bitruleheight} % \begin{macrocode} \newlength{\bitruleheight} \setlength{\bitruleheight}{0.6ex} % \end{macrocode} % \end{macro} % \begin{macro}{\bitruleendlift} % \begin{macrocode} \newlength{\bitruleendlift} \setlength{\bitruleendlift}{0.2ex} % \end{macrocode} % \end{macro} % % In addition, define some private variables: % % \begin{itemize} % \item[]\hskip-\leftmargin % \DescribeMacro{\bitw@dth} % |\bitw@dth| is the width of a bit in the current word. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitb@xwidth} % |\bitb@xwidth| is the width of the current field, excluding % margins. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitw@dthwidth} % |\bitw@dthwidth| is the width of the label rule. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitruled@pth} % |\bitruled@pth| is the depth of the label rule, which is % the thickness minus the height. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitrule@ndheight} % |\bitrule@ndheight| is the height of the ends of the rule. % \item[]\hskip-\leftmargin % \DescribeMacro{bitb@xfirst} % |bitb@xfirst| is a boolean that is true when the first bit field % in a word is being set. % \item[]\hskip-\leftmargin % \DescribeMacro{\bitb@x} % |\bitb@x| is a save box used to hold a bitfield while the rule % is being added. % \end{itemize} % % \begin{macro}{\bitw@dth} % \begin{macrocode} \newlength{\bitw@dth} % \end{macrocode} % \end{macro} % \begin{macro}{\bitb@xwidth} % \begin{macrocode} \newlength{\bitb@xwidth} % \end{macrocode} % \end{macro} % \begin{macro}{\bitw@dthwidth} % \begin{macrocode} \newlength{\bitw@dthwidth} % \end{macrocode} % \end{macro} % \begin{macro}{\bitruled@pth} % \begin{macrocode} \newlength{\bitruled@pth} \setlength{\bitruled@pth}{\bitrule-\bitruleheight} % \end{macrocode} % \end{macro} % \begin{macro}{\bitrule@ndheight} % \begin{macrocode} \newlength{\bitrule@ndheight} \setlength{\bitrule@ndheight}% {\bitruleheight*2-\bitrule-\bitruleendlift*2} % \end{macrocode} % \end{macro} % \begin{macro}{bitb@xfirst} % \begin{macrocode} \newboolean{bitb@xfirst} % \end{macrocode} % \end{macro} % \begin{macro}{\bitb@x} % \begin{macrocode} \newsavebox{\bitb@x} % \end{macrocode} % \end{macro} % % \subsection{Internal commands} % % Some internal helper commands are defined first. % % \begin{macro}{\bitdec@destyle} % |\bitdec@destyle| decodes a style string. Three commands are set % up: |\bitb@xcmd|, to draw the box, |\bitst@ckcmd|, to draw a bit % stack box, and |\bitl@belcmd|, to draw a label. % % \begin{macrocode} \newcommand{\bitb@xcmd}{\framebox}% \newcommand{\bitst@ckcmd}{\lbox}% \newcommand{\bitl@belcmd}{\bitl@bel}% \newcommand{\bitdec@destyle}[1]{% % \end{macrocode} % % First, the commands are initialised with their default values. % % \begin{macrocode} \renewcommand{\bitb@xcmd}{\framebox}% \renewcommand{\bitst@ckcmd}{\lbox}% \renewcommand{\bitl@belcmd}{\bitpl@inlabel}% % \end{macrocode} % % The style string is then scanned, and the commands altered % accordingly. The code here is adapted from that for the % picture version of |\makebox|. % % \begin{macrocode} \@tfor\reserved@a :=#1\do{% \if d\reserved@a \renewcommand{\bitb@xcmd}{\dashbox}% \renewcommand{\bitst@ckcmd}{\dlbox}% \else \if r\reserved@a% \renewcommand{\bitl@belcmd}{\bitrulel@bel}% \fi \fi}} % \end{macrocode} % \end{macro} % % \begin{macro}{\bitle@der} % |\bitle@der| produces the middle sections of label rules. % % \begin{macrocode} \newcommand{\bitle@der}{% \cleaders\hrule height \bitruleheight depth \bitruled@pth% \hfill} % \end{macrocode} % \end{macro} % % \begin{macro}{\bitpl@inlabel} % |\bitpl@inlabel| draws a label over a bit field box. The first argument % gives the width of the label, and the second the label text. The % label text is set at |\footnotesize|. % % \begin{macrocode} \newcommand{\bitpl@inlabel}[2]{% \makebox[#1]{\footnotesize #2}} % \end{macrocode} % \end{macro} % % \begin{macro}{\bitrulel@bel} % |\bitrulel@bel| draws a label with a rule. The first argument gives % the width, and the second the text to go in the middle. % % \begin{macrocode} \newcommand{\bitrulel@bel}[2]{% % \end{macrocode} % % The rule is typeset in a box of the given width % % \begin{macrocode} \makebox[#1]{% % \end{macrocode} % % The label text is set at |\footnotesize|; the left-hand end is drawn, % followed by the left-hand horizontal, then a thin space, the % contents, another thin space, the right-hand horizontal, and finally % the right-hand end. % % \begin{macrocode} \footnotesize% \rule[\bitruleendlift]{\bitrule}{\bitrule@ndheight}% \bitle@der\,#2\,\bitle@der% \rule[\bitruleendlift]{\bitrule}{\bitrule@ndheight}}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\bitl@bel} % |\bitl@bel| labels a bit field box. The first, optional, argument % gives an increment to add to the width of the label; this is used % for drawing stacks. The second argument gives the label text; the % third is the width of the box in bits, and the fourth is the box % itself. % % \begin{macrocode} \newcommand{\bitl@bel}[4][0pt]{% % \end{macrocode} % % The bit field box is saved. % % \begin{macrocode} \sbox{\bitb@x}{#4}% % \end{macrocode} % % |\bitw@dthwidth| is calculated from the size of the box; the first % argument, if any, is added to it. % % \begin{macrocode} \setlength{\bitw@dthwidth}{\wd\bitb@x-\bitboxsep*2-\fboxrule*2}% \addtolength{\bitw@dthwidth}{#1}% % \end{macrocode} % % The label is drawn in a zero-width box, so that it takes up no space, % to avoid formatting problems. % % \begin{macrocode} \ifthenelse{\equal{#2}{}}{\relax}{\makebox[0pt][l]{% % \end{macrocode} % % The label is raised by |\bitlabellift|, and the given horizontal % margin is left. % % \begin{macrocode} \raisebox{\ht\bitb@x}{\raisebox{\bitlabellift}{% {\hspace*{\fboxrule}\hspace*{\bitboxsep}% % \end{macrocode} % % The label is drawn. % % \begin{macrocode} \bitl@belcmd{\bitw@dthwidth}{#2}% }}}}}% % \end{macrocode} % % The box is now drawn underneath. % % \begin{macrocode} \usebox{\bitb@x}% }% % \end{macrocode} % \end{macro} % % \begin{macro}{\m@kebits} % |\m@kebits| draws a bit field box. The arguments are the label % text, the number of bits in the field, and the contents of the field. % % \begin{macrocode} \newcommand{\m@kebits}[3]{% % \end{macrocode} % % |\bitb@xwidth| is set; the length is incremented by |\fboxrule| if % this box is not the first on the current line. This is because the % first box has two sides drawn; the rest only have the right-hand % side (subsequent box's left-hand sides overlap with the previous % box's right-hand side). |bitb@xfirst| is set to |false|, as the % next box cannot be the first! % % \begin{macrocode} \setlength{\bitb@xwidth}{\bitw@dth*#2}% \ifthenelse{\boolean{bitb@xfirst}}% {}% {\addtolength{\bitb@xwidth}{\fboxrule}}% \setboolean{bitb@xfirst}{false}% % \end{macrocode} % % |\fboxsep| is locally set to 0pt, and the label and box are drawn. % The contents of the box is centred, and a margin of |\bitboxsep| is % left around it. % % \begin{macrocode} \setlength{\fboxsep}{0pt}% \bitl@bel{#1}{#2}{\bitb@xcmd[\bitb@xwidth]% {\rule[-\bitboxdepth]{0pt}{\bitboxheight}% \hspace*{\bitboxsep}\hfill#3\hfill\hspace*{\bitboxsep}}% % \end{macrocode} % % A negative space is left so that the next box's left-hand side % overlaps with this box's right-hand side. % % \begin{macrocode} \hspace*{-\fboxrule}}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\m@kestack} % |\m@kestack| draws a bit field stack; it takes the same arguments as % |\m@kebits|. % % \begin{macrocode} \newcommand{\m@kestack}[3]{% \setlength{\fboxsep}{0pt}% \bitl@bel[-2\layersize]{#1}{#2}{\bitst@ckcmd{#3\hspace*{\fboxrule}}}% } % \end{macrocode} % \end{macro} % % \subsection{User commands} % % Most of the user commands are just wrappers for the internal % commands. % % \begin{macro}{\bits} % \begin{macrocode} \newcommand{\bits}[4][]{% \bitdec@destyle{#1}% \m@kebits{#2}{#3}{#4}} % \end{macrocode} % \end{macro} % \begin{macro}{\bitstack} % \begin{macrocode} \newcommand{\bitstack}[4][]{% \bitdec@destyle{#1}% \m@kestack{#2}{#3}{#4}} % \end{macrocode} % \end{macro} % % \begin{macro}{\bitsubspaced} % |\bitsubspaced| sets its third argument in an |xbitfield| % environment with 0pt margins and no alignment, and ends with the % same negative kern as |\bits|. % % \begin{macrocode} \newcommand{\bitsubspaced}[3][]{% \bitdec@destyle{#1}% \renewcommand{\bitalign}{\relax}% \begin{xbitfield}[#2\bitw@dth]{0pt}{#2}#3\end{xbitfield}% \hspace*{-\fboxrule}} % \end{macrocode} % \end{macro} % % \label{fudge} % \begin{macro}{\bitsub} % |\bitsub| is written using |\bitsubspaced| by changing |\bitskip| to % $-$|\fboxrule|, so that the boxes overlap vertically in the same way % that bit fields normally do horizontally. Note the extra level of % bracketing so that the |\setlength| has only a local effect. % % \begin{macrocode} \newcommand{\bitsub}[4][]{% {\setlength{\bitskip}{-\fboxrule}% \bitl@bel{#2}{#3}{\bitsubspaced[#1]{#3}{#4}}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\bitdots} % |\bitdots| simply draws a centred vertical ellipsis, 2.5ex high, % centred in a parbox of width |\textwidth|. % % \begin{macrocode} \newcommand{\bitdots}{% \parbox{\textwidth}{% \centering\vbox to 2.5ex{% \cleaders\vbox to 0.8ex{\vfill.\vfill}\vfill}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\bittext} % |\bittext| draws a zero-width rule of the correct height and depth % for a box next to the given text. % % \begin{macrocode} \newcommand{\bittext}[1]{% \rule[-\bitboxdepth]{0pt}{\bitboxheight}#1} % \end{macrocode} % \end{macro} % % \subsection{The environments} % % \begin{environment}{xbitfield} % The |xbitfield| environment provides the innards of the |bitfield| % environment. It provides a little extra customization, by means of % its second argument, which gives the left and right margin. The % other two arguments are as for the |bitfield| environment. % % \begin{macrocode} \newenvironment{xbitfield}[3][4in]% % \end{macrocode} % % First, |\bitw@dth| is calculated. % % \begin{macrocode} {\setlength{\bitw@dth}{(#1-#2*2)/#3}% % \end{macrocode} % % The words are set in a minipage; the alignment is set according to % |\bitalign|, and inter-line spacing is turned off, so that only the % bit field layout parameters affect the result. |\endlinechar| is set % to $-1$ so that blank lines do not start a new paragraph. |\\| is % redefined to set |bitb@xfirst| to |true| as well as ending the % line, and |bitb@xfirst| is set to |true|. % % \begin{macrocode} \begin{minipage}{#1}\bitalign% \offinterlineskip% \endlinechar=-1% \renewcommand{\\}% {\par\vspace{\bitskip}\setboolean{bitb@xfirst}{true}}% \setboolean{bitb@xfirst}{true}% }% % \end{macrocode} % % At the end of the environment, the minipage is closed, and % |bitb@xfirst| is set to |false| in case a |\bits| command is used % outside a |bitfield| environment (though that is not recommended). % \begin{macrocode} {\end{minipage}% \setboolean{bitb@xfirst}{false}} % \end{macrocode} % \end{environment} % % \begin{environment}{bitfield} % The |bitfield| environment simply invokes the |xbitfield| % environment with a margin of |\layersize|. % % \begin{macrocode} \newenvironment{bitfield}[2][4in]% {\begin{xbitfield}[#1]{\layersize}{#2}}% {\end{xbitfield}} % \end{macrocode} % \end{environment}