% \iffalse % % bitpattern.dtx % % This file is part of the bitpattern, a LaTeX package to typeset bit % pattern diagrams. % https://bitbucket.org/bourguet/bitpattern % % Copyright 2005--2015 Jean-Marc Bourguet % % This program is provided under the terms of the LaTeX Project Public % License distributed from CTAN archives in directory % macros/latex/base/lppl.txt. % % Run LaTeX on the file 'bitpattern.ins' to get a .sty to place in % your tex hierarchy. % % Run LaTeX on the file 'bitpattern.dtx' to get a manual. If the % |\OnlyDescription| command is commented out, you get commented % sources in the manual, else you get only the user's manual part. % %<*dtx> \ProvidesFile{bitpattern.dtx} % % \fi % %% \CheckSum{412} % % \title{Bit pattern diagrams} % \author{Jean-Marc Bourguet\\ % \texttt{jm@bourguet.org}} % % \maketitle % \begin{abstract} % The |bitpattern| package is designed to typeset bit patterns as % they may appear in description of data format, hardware registers % or transmission protocols. It covers thus more or less the same % application domain as the package |register| and is somewhat % related to |bytefield|. % % Comparared to |register| the formating is more compact, the % syntax less verbose and |bitpattern| allows to choose between big % endian and little endian bit numbering. But |bitpattern| is less % well adapted to the use of long names for the fields and has no % provision for a reset value. |bytefield| is more adequate to % describe multi-word protocols, while |bitpattern| is more adapted % to describe the intra-word structure of a single word. % \end{abstract} % % \iffalse %<*driver> \documentclass{ltxdoc} \RequirePackage[numberFieldsOnce,bigEndian,numberBitsAbove]% {bitpattern} \renewcommand\descriptionlabel[1]{\hspace{\labelsep}\texttt{#1}} %\OnlyDescription \begin{document} \DocInput{bitpattern.dtx} \end{document} % % \fi % \section{Examples} % % We'll the instruction formats of two processors to describe the % features of |bitpattern|, the DEC PDP-10 and the Intel 8080. % % The PDP-10 was a word-adressable 36-bit computer, something quite % strange to our eyes (it's most familiar feature is probably the % fact that it uses 2's complement) and the reason for which I've % chosen it is that it was the computer on which \TeX{} was first % implemented. % % The PDP-10 has two instruction formats, one used for most of the % instructions: % % \noindent\bitpattern{Op}[9]{AC}[4]IX[4]Y[18]/ % % \noindent and the other used for IO instructions: % % \noindent\bitpattern[numberBitsBelow]{111}[3]{Dev}[7]{IOP}[3]IX[4]Y[18]/ % % As well at putting the bit numbers above or below the field % description, |bitpattern| allows to number all the bits: % % \noindent\bitpattern[numberAllBits]{Op}[9]{AC}[4]IX[4]Y[18]/ % % \noindent or only at the start and end of a field: % % \noindent\bitpattern[numberBitsBelow,numberFieldsTwice]{111}[3]{Dev}[7]{IOP}[3]IX[4]Y[18]/ % % Having a long field like \emph{Y} here may take more place than % wanted. |bitpattern| allows to reduce that: % % \noindent\bitpattern{Op}[9]{AC}[4]IX[4]Y[18][9]/ % % Other ways to avoid overstepping in the margin include splitting % the pattern in two: % % \noindent\bitpattern[bitWidth=1.5em,numberAllBits]{Op}[9]{AC}[4]IX[4]/ \\ % \hspace*{1pt plus 1filll}\bitpattern[numberBitsBelow,startBit=18,bitWidth=1.5em,numberAllBits] Y[18]/ % % \noindent and reducing the width of the cells: % % {\centering\bitpattern[bitWidth=0.8em]{Op}[9]{AC}[4]IX[4]Y[18]/ \par} % % The PDP-10 numbered its bits in the big endian way. That's not the % case of the Intel 8080. The 8080 was an 8-bit computer. Trying to % pack instructions in 8-bit forces to use a lot of formats. One of % them was used for the move instruction, and let's take that % opportunity to start and compact the layout of the bit field by % changing the format of the bit numbers and the field descriptions: % % \renewcommand\bpFormatBitNumber[1]{{\tiny\ttfamily\emph{\strut#1}}} % \renewcommand\bpFormatField[1]{{\scriptsize\ttfamily\strut#1}} % {\centering\bitpattern[littleEndian,startBit=7,numberBitsBelow]{01}[2]{D}[3]{S}[3]/\par} % % % \bpSetTickHeight{1pt} % \newlength{\bpDocExampleHeight} % \settoheight{\bpDocExampleHeight}{{\scriptsize\ttfamily 0}} % \newcommand{\bpDocExampleStrut}{\rule{0pt}{\bpDocExampleHeight}} % \renewcommand\bpFormatField[1]{{\scriptsize\ttfamily\bpDocExampleStrut #1}} % % After that it is possible to still be more compact by removing the % numbers, reducing the height of the ticks and avoiding the provide % the space for ascender and descenders in the field name (obviously % that is possible only with convenient field names). When that's % done, you can put a bit pattern in a paragraph without disturbing % it too much, like this % \bitpattern[noBitNumbers,littleEndian,startBit=7]{01}[2]{D}[3]{S}[3]/. % With some text afterwards to see how the next line is handled. The % result seems quite readable, remark for instance that the baseline % of the field description is aligned with the baseline of the line % in which it is included. % % \section{Interface} % % \subsection{\cmd{\bitpattern}} % % \DescribeMacro{\bitpattern} The |\bitpattern| macro is the macro % which formats the patterns. % % \begin{quote} % \cmd{\bitpattern}\oarg{format}\marg{name}\oarg{size}\oarg{width}\dots\verb+/+ % \end{quote} % % The first optional argument allows to control how the formatting is % made and is the combination of the following keys: % \begin{description} % \item[littleEndian] indicates that bit numbering is little endian, % that is the leftward bit has the biggest number; % \item[bigEndian] indicates that bit numbering is big endian, that % is the leftward bit has the lowest number; % \item[numberBitsAbove] indicates that the bit numbers should be put % above the fields; % \item[numberBitsBelow] indicates that the bit numbers should be put % below the fields; % \item[noBitNumbers] indicates that there should be no bit numbers; % \item[numberFieldsOnce] indicates that the fields should have % only one bit number; % \item[numberFieldsTwice] indicates that the fields should have % two bit numbers; % \item[numberAllBits] indicates that the fields shouldn't have a bit % number indication; % \item[startBit=X] indicates that the number for the leftmost bit % should be $X$; % \item[bitWidth=dimen] indicates that the size taken by a bit should % be \emph{dimen}; % \item[tickHeight=dimen] indicates that the size taken by the small % ticks marking the bits should be \emph{dimen}. % \end{description} % % After the optional argument comes the description of the % fields. Each field is described by its name as a mandatory argument % (which does not have to be included in braces if it takes one % character) followed by two optional arguments giving the size of % the field (1 if omitted) and the width it should take (the same as % its size if it is not specified). % % Field descriptions are ended by a \verb+/+. % % \subsection{Package options} % % The package |bitpattern| accept the following options which set up % the default values for the formatting controls: % \begin{description} % \item[littleEndian] indicates that the default for bit numbering is % little endian, that is the leftward bit has the biggest number; % \item[bigEndian] indicates that the default for bit numbering is % big endian, that is the leftward bit has the lowest number; % \item[numberBitsAbove] indicates that by default the bit numbers % should be put above the fields; % \item[numberBitsBelow] indicates that by default the bit numbers % should be put below the fields; % \item[noBitNumbers] indicates that by default there should be no % bit numbers; % \item[numberFieldsOnce] indicates that by default the fields % should have only one bit number; % \item[numberFieldsTwice] indicates that by default the fields % should have two bit numbers; % \item[numberAllBits] indicates that by default the fields shouldn't % have a bit number indication. % \end{description} % % \subsection{Commands controlling the format} % % \DescribeMacro{\bpLittleEndian} |\bpLittleEndian| changes the % default bit numbering to little endian. % % \DescribeMacro{\bpBigEndian} |\bpBigEndian| changes the default bit % numbering to little endian. % % \DescribeMacro{\bpNumberBitsAbove} |\bpNumberBitsAbove| changes the % default to having the numbering above the fields. % % \DescribeMacro{\bpNumberBitsBelow} |\bpNumberBitsBelow| changes the % default to having the numbering below the fields. % % \DescribeMacro{\bpNoBitNumbers} |\bpNoBitNumbers| changes the % default to having no numbering. % % \DescribeMacro{\bpNumberFieldsOnce} |\bpNumberFieldsOnce| changes the % default to having the numbering done once per field. % % \DescribeMacro{\bpNumberFieldsTwice} |\bpNumberFieldsTwice| changes % the default to having the numbering done twice per field. % % \DescribeMacro{\bpNumberAllBits} |\bpNumberAllBits| changes the % default to having the numbering done for all bits of a field. % % \begin{quote} % \cmd{\bpStartAtBit}\marg{number} % \end{quote} % % \DescribeMacro{\bpStartAtBit} |\bpStartAtBit| gives the default bit % number of the leftmost bit. % % \begin{quote} % \cmd{\bpSetBitWidth}\marg{length} % \end{quote} % % \DescribeMacro{\bpSetBitWidth} |\bpSetBitWidth| gives the default % bit width % % \begin{quote} % \cmd{\bpSetTickHeight}\marg{length} % \end{quote} % % \DescribeMacro{\bpSetTickHeight} |\bpSetTickHeight| gives the % default height for the ticks marking the bits in a multi-bit field. % % \DescribeMacro{\bpFormatField} |\bpFormatField| is a one argument % macro used fo format the field. It can be replaced. Care should % be taken to format all the fields with the same height, so putting % a |\strut| in the replacement is probably in order. % % \DescribeMacro{\bpFormatBitNumber} |\bpFormatBitNumber| is a one % argument macro used fo format the bit numbers. It can be replaced. % Care should be taken to format all the bit numbers with the same % height, so putting a |\strut| in the replacement is perhaps in % order. % % \section{Examples revisited} % % \bpSetTickHeight{2pt} % \renewcommand\bpFormatField[1]{\strut\emph{#1}} % \renewcommand\bpFormatBitNumber[1]{{\tiny\sffamily\strut #1}} % |bitpattern| was loaded by: % \begin{verbatim} % \RequirePackage[numberFieldsOnce,bigEndian,numberBitsAbove]{bitpattern} % \end{verbatim} % \smallskip % \noindent\bitpattern{Op}[9]{AC}[4]IX[4]Y[18]/ % \begin{verbatim} % \bitpattern{Op}[9]{AC}[4]IX[4]Y[18]/ % \end{verbatim} % % \smallskip % \noindent\bitpattern[numberBitsBelow]{111}[3]{Dev}[7]{IOP}[3]IX[4]Y[18]/ % \begin{verbatim} % \bitpattern[numberBitsBelow]{111}[3]{Dev}[7]{IOP}[3]IX[4]Y[18]/ % \end{verbatim} % % \smallskip % \noindent\bitpattern[numberAllBits]{Op}[9]{AC}[4]IX[4]Y[18]/ % \begin{verbatim} % \bitpattern[numberAllBits]{Op}[9]{AC}[4]IX[4]Y[18]/ % \end{verbatim} % % \smallskip % \noindent\bitpattern[numberBitsBelow,numberFieldsTwice]{111}[3]{Dev}[7]{IOP}[3]IX[4]Y[18]/ % \begin{verbatim} % \bitpattern[numberBitsBelow,numberFieldsTwice]% % {111}[3]{Dev}[7]{IOP}[3]IX[4]Y[18]/ % \end{verbatim} % % \smallskip % \noindent\bitpattern[numberBitsBelow,numberFieldsTwice]111{Dev}[7]{IOP}[3]IX[4]Y[18]/ % \begin{verbatim} % \bitpattern[numberBitsBelow,numberFieldsTwice]% % 111{Dev}[7]{IOP}[3]IX[4]Y[18]/ % \end{verbatim} % % \smallskip % \noindent\bitpattern{Op}[9]{AC}[4]IX[4]Y[18][9]/ % \begin{verbatim} % \bitpattern{Op}[9]{AC}[4]IX[4]Y[18][9]/ % \end{verbatim} % % \smallskip % \noindent\bitpattern[bitWidth=1.5em,numberAllBits]{Op}[9]{AC}[4]IX[4]/ \\ % \hspace*{1pt plus 1filll}\bitpattern[numberBitsBelow,startBit=18,bitWidth=1.5em,numberAllBits] Y[18]/ % % This wasn't composed directly by as two bit patterns, using the % possibility of specifying a starting bit. To put a nicer touch, % the width of the cells has been expanded (the default width had an % overlap so small that going into the margin is a better format), % and the numbering was put above the pattern for the first and below % for the second. % \begin{verbatim} % \noindent\bitpattern[bitWidth=1.5em,numberAllBits]{Op}[9]{AC}[4]IX[4]/ \\ % \hspace*{1pt plus 1filll} % \bitpattern[numberBitsBelow,startBit=18,bitWidth=1.5em,numberAllBits] Y[18]/ % \end{verbatim} % % \smallskip % {\centering\bitpattern[bitWidth=0.8em]{Op}[9]{AC}[4]IX[4]Y[18]/ \par} % \begin{verbatim} % {\centering\bitpattern[bitWidth=0.8em]{Op}[9]{AC}[4]IX[4]Y[18]/ \par} % \end{verbatim} % % \smallskip % \renewcommand\bpFormatBitNumber[1]{{\tiny\ttfamily\emph{\strut#1}}} % \renewcommand\bpFormatField[1]{{\scriptsize\ttfamily\strut#1}} % {\centering\bitpattern[littleEndian,startBit=7,numberBitsBelow]{01}[2]{D}[3]{S}[3]/\par} % \begin{verbatim} % \renewcommand\bpFormatBitNumber[1]{{\tiny\ttfamily\emph{\strut#1}}} % \renewcommand\bpFormatField[1]{{\scriptsize\ttfamily\strut#1}} % {\centering\bitpattern[littleEndian,startBit=7,numberBitsBelow]{01}[2]{D}[3]{S}[3]/\par} % \end{verbatim} % % \smallskip % \bpSetTickHeight{1pt} % \renewcommand\bpFormatField[1]{{\scriptsize\ttfamily\bpDocExampleStrut #1}} % {\centering\bitpattern[noBitNumbers,littleEndian,startBit=7]{01}[2]{D}[3]{S}[3]/\par} % This example was made to be as compact as possible. Expanding the % strut a little more vertically wouldn't be unwise. % \begin{verbatim} % \bpSetTickHeight{1pt} % \newlength{\bpDocExampleHeight} % \settoheight{\bpDocExampleHeight}{\scriptsize\ttfamily 0} % \newcommand{\bpDocExampleStrut}{\rule{0pt}{\bpDocExampleHeight}} % \renewcommand\bpFormatBitNumber[1]{{\tiny\ttfamily\emph{\strut#1}}} % \renewcommand\bpFormatField[1]{{\scriptsize\ttfamily\bpDocExampleStrut #1}} % {\centering\bitpattern[noBitNumbers,littleEndian,startBit=7]{01}[2]{D}[3]{S}[3]/\par} % \end{verbatim} % Note that if you put a descender, the formatting is then disturbed: % {\centering\bitpattern[noBitNumbers,littleEndian,startBit=7]{01}[2]{D}[3]{p}[3]/\par} % % \smallskip % It is to be noted that usually one does not change the formatting % for every pattern, so setting the optional argument of % \cs{bitpattern} is rarely used. % \StopEventually{} % % \newpage % \section{Implementation} % % First let's have a standard preamble and indicates the package we % requires. % % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{bitpattern}[2015/12/11 bit pattern diagrams] \RequirePackage{keyval} \RequirePackage{calc} \RequirePackage{multido} % \end{macrocode} % Now we'll declare some new |\if| commands which will be set to % describe the options. % \begin{macrocode} \newif\ifbp@NumberBitsAbove \newif\ifbp@NumberBitsBelow \newif\ifbp@HasBitNumbers \newif\ifbp@NumberFieldTwice \newif\ifbp@NumberAllBits \newif\ifbp@NumberBitsBigEndian % \end{macrocode} % We need a counter to store the starting bit number. We are not % using the \LaTeX{} way because we want to use it locally and not % globally. % \begin{macrocode} \newcount\bp@StartBit % \end{macrocode} % \LaTeX{} length behaves are needed, so use them. % \begin{macrocode} \newlength{\bp@BitWidth} \newlength{\bp@TickHeight} % \end{macrocode} % % First the user level macros allowing to change the default. They % are easy, the just set the |\if|. % \begin{macrocode} \newcommand\bpLittleEndian {\bp@NumberBitsBigEndianfalse} \newcommand\bpBigEndian {\bp@NumberBitsBigEndiantrue} \newcommand\bpNumberBitsAbove {\bp@NumberBitsAbovetrue \bp@NumberBitsBelowfalse} \newcommand\bpNumberBitsBelow {\bp@NumberBitsAbovefalse \bp@NumberBitsBelowtrue} \newcommand\bpNoBitNumbers {\bp@HasBitNumbersfalse} \newcommand\bpNumberFieldsOnce {\bp@HasBitNumberstrue \bp@NumberFieldTwicefalse \bp@NumberAllBitsfalse} \newcommand\bpNumberFieldsTwice {\bp@HasBitNumberstrue \bp@NumberFieldTwicetrue \bp@NumberAllBitsfalse} \newcommand\bpNumberAllBits {\bp@HasBitNumberstrue \bp@NumberFieldTwicetrue \bp@NumberAllBitstrue} % \end{macrocode} % % About as easy, macros setting the counter and the lengths. % \begin{macrocode} \newcommand\bpStartAtBit[1]{\bp@StartBit=#1} \newcommand\bpSetBitWidth[1]{\setlength{\bp@BitWidth}{#1}} \newcommand\bpSetTickHeight[1]{\setlength{\bp@TickHeight}{#1}} % \end{macrocode} % % Now we set up the keyval handling % \begin{macrocode} \define@key{bitpattern}{littleEndian}[true]{\bpLittleEndian} \define@key{bitpattern}{bigEndian}[true]{\bpBigEndian} \define@key{bitpattern}{numberBitsAbove}[true]{\bpNumberBitsAbove} \define@key{bitpattern}{numberBitsBelow}[true]{\bpNumberBitsBelow} \define@key{bitpattern}{noBitNumbers}[true]{\bpNoBitNumbers} \define@key{bitpattern}{numberFieldsOnce}[true]{\bpNumberFieldsOnce} \define@key{bitpattern}{numberFieldsTwice}[true]{\bpNumberFieldsTwice} \define@key{bitpattern}{numberAllBits}[true]{\bpNumberAllBits} \define@key{bitpattern}{startBit}{\bpStartAtBit{#1}} \define@key{bitpattern}{bitWidth}{\bpSetBitWidth{#1}} \define@key{bitpattern}{tickSize}{\bpSetTickHeight{#1}} % \end{macrocode} % % And we can do the same for the package options. % \begin{macrocode} \DeclareOption{littleEndian}{\bpLittleEndian} \DeclareOption{bigEndian}{\bpBigEndian} \DeclareOption{numberBitsAbove}{\bpNumberBitsAbove} \DeclareOption{numberBitsBelow}{\bpNumberBitsBelow} \DeclareOption{noBitNumbers}{\bpNoBitNumbers} \DeclareOption{numberFieldsOnce}{\bpNumberFieldsOnce} \DeclareOption{numberFieldsTwice}{\bpNumberFieldsTwice} \DeclareOption{numberAllBits}{\bpNumberAllBits} % \end{macrocode} % % Set up the default values. % \begin{macrocode} \bpLittleEndian \bpNumberBitsBelow \bpNumberFieldsOnce \AtEndOfPackage{\ifbp@NumberBitsBigEndian \bpStartAtBit{0}\else\bpStartAtBit{7}\fi} \bpSetBitWidth{1em} \bpSetTickHeight{2pt} % \end{macrocode} % % And provide the two formatting commands we are using for the % numbers and the fields. % \begin{macrocode} \providecommand\bpFormatField[1]{\strut\emph{#1}} \providecommand\bpFormatBitNumber[1]{{\tiny\sffamily\strut #1}} % \end{macrocode} % % A few more variables % \begin{macrocode} \newcount\bp@CurBit \newlength{\bp@FieldWidth} \newlength{\bp@RuleWidth}\setlength{\bp@RuleWidth}{0.4pt} \newsavebox{\bp@TickBox} % \end{macrocode} % % Now two wrappers around the public formatting hook which call them % only when the settings are appropriate. % \begin{macrocode} \newcommand\bp@FormatTopBit[1]{\ifbp@HasBitNumbers \ifbp@NumberBitsAbove\bpFormatBitNumber{#1}\fi\fi} \newcommand\bp@FormatBottomBit[1]{\ifbp@HasBitNumbers \ifbp@NumberBitsBelow\bpFormatBitNumber{#1}\fi\fi} % \end{macrocode} % % And an helper to get the rule we want for ticks. % \begin{macrocode} \newcommand\bp@Tick{\rule{\bp@RuleWidth}{\bp@TickHeight}} % \end{macrocode} % % Small utility to get a vbox without additional vertical spacing % \begin{macrocode} \newcommand\bp@vbox[3] {\parbox[#1]{#2}{\lineskip=0pt\lineskiplimit=0pt\baselineskip=0pt\relax#3}} % \end{macrocode} % The function used to put the broken rule when the width is smaller % than the size. % \begin{macrocode} \newcommand\bp@BrokenRuleFill{\dimen0=\bp@RuleWidth\multiply\dimen0 3 \leaders \hrule height \bp@RuleWidth\hfill \xleaders\hbox to \dimen0{\rule{\bp@RuleWidth}{\bp@RuleWidth}\hfill}\hfill \leaders \hrule height \bp@RuleWidth\hfill} % \end{macrocode} % The function used to put the ticks when the width is smaller than % the size. % \begin{macrocode} \newcommand\bp@BrokenTicks {\usebox{\bp@TickBox}\usebox{\bp@TickBox}\hfill\usebox{\bp@TickBox}} % \end{macrocode} % The function used to put the ticks in the other cases. % \begin{macrocode} \newcommand\bp@FillWithTicks {\leaders\hbox to \bp@BitWidth{\usebox{\bp@TickBox}}\hfill} % \end{macrocode} % % The functions putting the rule and the ticks, choosing between the % \emph{broken} and non broken version above. They take two % arguments, the size and the width. % \begin{macrocode} \newcommand\bp@RuleFill[2] {\ifnum #1 = #2 \leaders \hrule height \bp@RuleWidth\hfill \else \bp@BrokenRuleFill \fi} \newcommand\bp@TicksFill[2] {\ifnum #1 = #2 \bp@FillWithTicks \else \bp@BrokenTicks \fi} % \end{macrocode} % Now a macro to put the bit numbers. It is called with two % arguments, the width and the alignment. For broken fiels, % NumberAllBits will be changed to NumberFieldTwice before calling % this. % \begin{macrocode} \newcommand\bp@MakeNumbers[2]{\begingroup\ifbp@NumberAllBits % \end{macrocode} % Numbering all the bits is easy, just pay attention to the % direction. % \begin{macrocode} \mbox{\multido{}{#1}{% \makebox[\bp@BitWidth]{\bpFormatBitNumber{\the\bp@CurBit}}% \advance\bp@CurBit\ifbp@NumberBitsBigEndian 1\else -1\fi}}% \else\ifbp@NumberFieldTwice % \end{macrocode} % Numbering twice per field has to handle the case where the width is % 1. % \begin{macrocode} \mbox{% \makebox[\bp@FieldWidth]% {\makebox[\bp@BitWidth][#2]{\bpFormatBitNumber{\the\bp@CurBit}}% \ifnum #1 > 1 \advance\bp@CurBit\ifbp@NumberBitsBigEndian #1\else -#1\fi \advance\bp@CurBit\ifbp@NumberBitsBigEndian -1\else 1\fi \hfill\makebox[\bp@BitWidth][#2]% {\bpFormatBitNumber{\the\bp@CurBit}}\fi}}% \else % \end{macrocode} % When numbering only once, one has to pay attention to the alignment % so that the value is increased beforehand if needed. % \begin{macrocode} \ifx#2r \ifnum #1 > 1 \advance\bp@CurBit\ifbp@NumberBitsBigEndian #1\else -#1\fi \advance\bp@CurBit\ifbp@NumberBitsBigEndian -1\else 1\fi \fi\fi \makebox[\bp@FieldWidth][#2]{\bpFormatBitNumber{\the\bp@CurBit}}% \fi\fi\endgroup} % \end{macrocode} % Call |bp@MakeNumbers| in an appropriate way for the top numbering % \begin{macrocode} \newcommand\bp@MakeTopNumbers[1]% {\ifbp@HasBitNumbers \ifbp@NumberBitsAbove \bp@MakeNumbers{#1}{l} \else \makebox[\bp@FieldWidth][l]{\hfill}\fi\fi} % \end{macrocode} % Call |bp@MakeNumbers| in an appropriate way for the bottom % numbering % \begin{macrocode} \newcommand\bp@MakeBottomNumbers[1]% {\ifbp@HasBitNumbers \ifbp@NumberBitsBelow \bp@MakeNumbers{#1}{r} \else \makebox[\bp@FieldWidth][r]{\hfill}\fi\fi} % \end{macrocode} % The \cs{bitpattern} is easy, just parse the optional argument in a % group so that the changes are local and do some more intialization. % The hard work is delegated to \cs{bp@FieldIfPresent}. % \begin{macrocode} \newcommand{\bitpattern}[1][]{% \begingroup \setkeys{bitpattern}{#1}% \savebox{\bp@TickBox}[\bp@BitWidth]{\bp@Tick\hfill}% \bp@CurBit=\bp@StartBit% \bp@FieldIfPresent} % \end{macrocode} % \cs{bp@FieldIfPresent} checks if we are done and format a field if % not. % \begin{macrocode} \newcommand{\bp@FieldIfPresent}{\@ifnextchar/{\bp@Done}{\bp@Field}} % \end{macrocode} % \cs{bp@field} checks if there is an optional argument or call % \cs{bp@DoField}. % \begin{macrocode} \newcommand{\bp@Field}[1]% {\@ifnextchar[{\bp@SizedField[#1]}{\bp@DoField[#1][1][1]}} % \end{macrocode} % \cs{bp@field} checks if there is a second optional argument and % ensure that \cs{bp@DoField} is called with all the arguments set % up. % \begin{macrocode} \def\bp@SizedField[#1][#2]% {\@ifnextchar[{\bp@DoField[#1][#2]}{\bp@DoField[#1][#2][#2]}} % \end{macrocode} % First argument is field name, second is size, third is width. Do % some initialization and then format a compact vbox (two are used so % that the baseline is the one of the field names). % \begin{macrocode} \def\bp@DoField[#1][#2][#3]% {\setlength{\bp@FieldWidth}{\bp@BitWidth * #3}% \ifnum #2 > #3 \ifbp@NumberAllBits\bpNumberFieldsTwice\fi\fi \bp@vbox{t}{\bp@FieldWidth}{% \bp@vbox{b}{\bp@FieldWidth}{% \bp@MakeTopNumbers{#2} \makebox[\bp@FieldWidth][s]{\bp@RuleFill{#2}{#3}} \makebox[\bp@FieldWidth][s]{\bp@TicksFill{#2}{#3}} \makebox[\bp@FieldWidth][s]% {\vrule width \bp@RuleWidth\hfil\bpFormatField{#1}\hfil}} \makebox[\bp@FieldWidth][s]{\bp@TicksFill{#2}{#3}} \makebox[\bp@FieldWidth][s]{\bp@RuleFill{#2}{#3}} \bp@MakeBottomNumbers{#2}}% \advance\bp@CurBit\ifbp@NumberBitsBigEndian #2\else -#2\fi% \bp@FieldIfPresent} % \end{macrocode} % Finalize the pattern by putting a file vertical rule. % \begin{macrocode} \def\bp@Done/{\bp@vbox{t}{\bp@RuleWidth}{% \bp@vbox{b}{\bp@RuleWidth}{% \makebox[\bp@RuleWidth]{\bp@FormatTopBit{}\hfill} \makebox[\bp@RuleWidth]{\bp@RuleFill{0}{0}} \makebox[\bp@RuleWidth]{\bp@Tick\hfill} \makebox[\bp@RuleWidth]% {\vrule width \bp@RuleWidth\hfil\bpFormatField{}\hfil}} \makebox[\bp@RuleWidth]{\bp@Tick\hfill} \makebox[\bp@RuleWidth]{\bp@RuleFill{0}{0}} \makebox[\bp@RuleWidth]{\hfill\bp@FormatBottomBit{}}}\endgroup} % \end{macrocode} % We can now process the option of the package and we are done. % \begin{macrocode} \ProcessOptions % \end{macrocode} % % \Finale % \endinput %%% Local Variables: %%% fill-column: 69 %%% End: