summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/register
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/register
Initial commit
Diffstat (limited to 'macros/latex/contrib/register')
-rw-r--r--macros/latex/contrib/register/README52
-rw-r--r--macros/latex/contrib/register/Reg_macro.pm498
-rw-r--r--macros/latex/contrib/register/reg_list.pl329
-rw-r--r--macros/latex/contrib/register/register.dtx1376
-rw-r--r--macros/latex/contrib/register/register.ins62
-rw-r--r--macros/latex/contrib/register/register.pdfbin0 -> 178459 bytes
6 files changed, 2317 insertions, 0 deletions
diff --git a/macros/latex/contrib/register/README b/macros/latex/contrib/register/README
new file mode 100644
index 0000000000..f250c7dbc2
--- /dev/null
+++ b/macros/latex/contrib/register/README
@@ -0,0 +1,52 @@
+
+REGISTER
+Hardware register diagrams with field descriptions.
+
+
+Description
+-----------
+
+This package is designed for typesetting the programmable elements in
+digital hardware, i.e., registers. Such registers typically have many
+fields and can be quite wide; they are thus a challenge to typeset in
+a consistent manner. Register is similar in some aspects to the
+bytefield package. Anyone doing hardware documentation using LaTeX
+should examine both packages. Register requires version 2001/07/25 or
+newer of the float package.
+
+An example Perl module and script are provided, to convert the
+register specifications into structures suitable for, say, a
+pre-silicon test environment.
+
+
+Building package
+----------------
+
+tex register.ins <== Produces register.sty (the package proper)
+latex register.dtx <== Produces register.dvi (the documentation)
+latex register.dtx <== Incorporates list of registers into
+ register.dvi
+
+One can substitute pdflatex in the commands above to produce PDF
+directly.
+
+Note that register comes with pre-built documentation. The
+documentation includes some representative examples of package usage.
+
+
+
+Copyright and license
+---------------------
+
+Copyright (C) 2001-2018 Matthew Lovell, lovells@gmail.com
+
+This package may be distributed and/or modified under the conditions
+of the LaTeX Project Public License, either version 1.3 of this
+license or (at your option) any later version. The latest version of
+this license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2006/05/20 or later.
+
diff --git a/macros/latex/contrib/register/Reg_macro.pm b/macros/latex/contrib/register/Reg_macro.pm
new file mode 100644
index 0000000000..5c00bc805e
--- /dev/null
+++ b/macros/latex/contrib/register/Reg_macro.pm
@@ -0,0 +1,498 @@
+###############################################################################
+#
+# File: Reg_macro.pm
+# Description: Module for parsing register macros from LaTeX documentation
+# Author: Matthew Lovell
+# Created: Mon Mar 31 16:50:05 2003
+# Modified: Sat May 19 09:33:20 2018
+# Language: CPerl
+#
+# (C) Copyright 2003, Matthew Lovell, all rights reserved.
+#
+###############################################################################
+
+=pod
+
+=head1 NAME
+
+Reg_macro.pm
+
+=head1 SYNOPSIS
+
+Parses register/CSR information from LaTeX files.
+
+=head1 DESCRIPTION
+
+After searching through a files input/include tree, this module will search
+for all \begin{register} macros. All available information will be parsed
+out of each encountered macro. Parsed information includes:
+
+ register name
+ function
+ offset
+ field names, positions, and widths
+ register reset value
+ register reset mask
+ register write mask
+
+The parsed information can either be used either to produce in-order
+tables for inclusion in documentation or to provide CSR information to
+Phase 1 tools (metacheckers, CSR checkers, etc).
+
+=head1 PUBLIC ROUTINES
+
+ get_tex_files() Recursively follow a file's input/include/import tree
+
+ get_regs() Parse CSR information from a single specified file
+
+ build_reg_hash() Build a multi-level hash, keyed by function and
+ offset, from the specified register information
+
+=head1 SEE ALSO
+
+Any project-specific LaTeX introductory material.
+
+
+=head1 AUTHOR
+
+Matthew Lovell (lovells@gmail.com)
+
+=cut
+
+###############################################################################
+
+package Reg_macro;
+use Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(get_tex_files
+ get_regs
+ build_reg_hash
+ $REG_DEBUG
+ $REG_STRIDE
+ $REG_ERRORS
+ );
+
+use FileHandle;
+use Data::Dumper;
+
+# Debug flag
+$REG_DEBUG = 0;
+
+# How large are registers? Default is 64-bits.
+$REG_STRIDE = hex(0x08);
+
+# Error count
+$REG_ERRORS = 0;
+
+###############################################################################
+# P U B L I C R O U T I N E S #
+###############################################################################
+
+
+
+
+# Read a .tex file line by line, finding all \include or \input
+# commands. Recurse upon encountering one of those, thus making
+# a list of the entire TeX file tree.
+#
+# This subroutine can also be called with an option indicating that
+# all \includegraphics targets should be parsed. With that option,
+# this routine can extract all dependencies for a LaTeX file, which
+# is useful for GNU make.
+#
+# Arguments: filename
+# flag indicating all dependencies should be tracked
+#
+sub get_tex_files {
+ my ($filename, $all_files) = @_;
+
+ # return immediately for some file types
+ if ($filename =~ /\.(eps|pdf|ps|func|error)$/) {
+ print "#INFO Reg_macro Not attempting to read '$filename'\n" if ($REG_DEBUG);
+ return $filename;
+ }
+
+ my $path = dirname($filename);
+
+ # Add .tex if not present
+ if ($filename !~ /\.\w+$/) {
+ $filename .= '.tex';
+ }
+
+ # initialize file list
+ my @file_list = ($filename);
+
+ my $file = new FileHandle "$filename";
+ unless (defined $file) {
+ print STDERR "#ERROR Reg_macro Unable to open '$filename'\n";
+ $REG_ERRORS++;
+ return @file_list;
+ }
+
+ # Allow files to turn off dependency extraction in particular sections,
+ # when desired. This may be useful if a preamble needs to input a file
+ # from the texmf tree, for example.
+ my $dependency_skip = 0;
+
+ while (<$file>) {
+
+ $dependency_skip = 1 if (m/^%% DEPEND OFF/);
+ $dependency_skip = 0 if (m/^%% DEPEND ON/);
+ next if $dependency_skip;
+
+ # Skip over comments.
+ s/^%.*$//; # Remove whole comment lines
+ s/([^\\])%.*$/$1/; # Remove everything after unescaped %'s
+
+
+ # Get all include and input commands
+ my @list = m/\\(?:include|input)\{([\w\/.-]+)\}/g;
+ if ($path ne '' and $path ne '.') {
+ @list = map { $path . "/" . $_ } @list;
+ }
+
+ # Find any import commands
+ if (m|\\import\{([\w\/.-]+)}\{([\w\/.-]+)\}|) {
+ push(@list,$1.$2);
+ }
+
+ # Find ALL files for make dependencies
+ if ($all_files) {
+
+ # Graphics files
+ if (m|\\includegraphics(?:\[.*?\])?\{([\w\/.-]+)\}|) {
+
+ # Add .eps if not present
+ my $gfx_file = $1;
+ if ($gfx_file !~ /\.\w+$/) {
+ $gfx_file .= '.eps';
+ }
+
+ if ($path ne '' and $path ne '.') {
+ $gfx_file = $path . "/" . $gfx_file;
+ }
+
+ push(@list,$gfx_file);
+ }
+
+
+ # project-specific:
+ #
+ # CSR files (just look for the \CSRtable invocation)
+ if (m|\\CSRtable|) {
+ my $func_file;
+ ($func_file = $filename) =~ s/\.tex$/.func/;
+ push(@list, $func_file);
+ }
+
+
+ } # end all_files
+
+ my $subfile;
+ for $subfile (@list) {
+ push(@file_list, get_tex_files($subfile, $all_files));
+ }
+ }
+
+ return @file_list;
+} # get_tex_files
+
+
+
+
+# Read a .tex file line by line, looking for register declarations
+# using the register.sty macro. This subroutine only examines
+# a single file.
+#
+# Arguments: filename
+# reference to array of register information
+#
+sub get_regs {
+ my ($filename, $reg_data) = @_;
+
+ my $file = new FileHandle "$filename";
+
+ # Record the function in which a register resides. Allow this to
+ # be defined for just the first register in a file, then carried
+ # over to all the others.
+ my $function = 0;
+
+ while (<$file>) {
+ # find register definition
+ if ( m/\\begin\{register\}\{[\w\!]+\}\{(.*)\}\{(.*)\}%(.*)$/ ) {
+ my $long_name = $1;
+ my $offset = $2;
+ my $testable = 1;
+ my $short_name = undef;
+
+ my $remainder = $3;
+
+ if ($remainder ne "") {
+ if ($remainder =~ /don\'?t(_| )test/i) { $testable = 0 }
+ if ($remainder =~ /NAME=([\w\\<>\d]+)/i) { $short_name = $1 }
+ if ($remainder =~ /func=(\d)/i) { $function = $1 }
+ if ($remainder =~ /off(?:set)?=([\w-,g]+)/) { $offset = $1 }
+ }
+
+ # get rid of escaped underscores
+ $long_name =~ s/\\_/_/g;
+ $short_name =~ s/\\_/_/g;
+
+ my $width = 0;
+ my $reg = {
+ long_name => $long_name,
+ short_name => $short_name,
+ function => $function,
+ offset => $offset,
+ testable => $testable,
+ fields => []
+ };
+
+
+ # now we need to extract fields. first,
+ # read in rest of the reg macro
+ @wholereg = ();
+ while (<$file>) {
+ push(@wholereg, $_);
+ last if (/\\end\{register\}/);
+ }
+
+
+ # combine lines if nested {}'s do not match
+ for (my $i = 0; $i <= $#wholereg; $i++) {
+ my $open = grep(/\{/, split(//, $wholereg[$i]));
+ my $close = grep(/\}/, split(//, $wholereg[$i]));
+
+ if ($open != $close) {
+ my ($next) = splice(@wholereg, $i+1, 1);
+ $wholereg[$i] .= $next;
+ redo;
+ }
+ }
+
+ foreach (@wholereg) {
+
+ if (m/\\label\{(.*)\}/) {
+ $reg->{label} = $1;
+ }
+
+ # normal register field (reset value specified)
+ if ( m/\\regfield\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*%(.*)$/s ) {
+ my $remain = $5;
+ my $field_name = $1;
+ my $field_len = $2;
+ my $field_start = $3;
+ my $reset = $4; $reset =~ s/^\{//; $reset =~ s/\}$//; $reset =~ s/_//g;
+ my $reset_mask = $testable; # indicates field is deterministic after reset
+ my $write_mask = $testable; # indicates field is modified by regbus writes
+
+
+ if ($field_name =~ m/\{([\w ])\}$/) {
+ $field_name = $1;
+ }
+ $field_name =~ s/\\_/_/g;
+
+
+ if ($remain =~ /read(?:_| )only/i) { $write_mask = 0; }
+ if ($remain =~ /status/i) { $reset_mask = 0; $write_mask = 0; }
+ if ($field_name =~ /reserved/i) { $write_mask = 0; }
+
+
+ if ($field_len > 32) {
+ die "#ERROR Reg_macro Field of greater than 32 bits in $short_name!\n";
+ }
+
+ push(@{$reg->{fields}},
+ {
+ name => $field_name,
+ len => $field_len,
+ start => $field_start,
+ reset => $reset,
+ reset_mask => $reset_mask,
+ write_mask => $write_mask
+ });
+ }
+
+
+ # register field without reset
+ if ( m/\\regfieldb\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*%(.*)$/s ) {
+ my $remain = $4;
+ my $field_name = $1;
+ my $field_len = $2;
+ my $field_start = $3;
+ my $reset_mask = $testable; # indicates field is deterministic after reset
+ my $write_mask = $testable; # indicates field is modified by regbus writes
+
+
+ if ($field_name =~ m/\{([\w ])\}$/) {
+ $field_name = $1;
+ }
+ $field_name =~ s/\\_/_/g;
+
+ if ($remain =~ /read(?:_| )only/i) { $write_mask = 0; }
+ if ($remain =~ /status/i) { $reset_mask = 0; $write_mask = 0; }
+ if ($field_name =~ /reserved/i) { $write_mask = 0; }
+
+ if ($field_len > 32) {
+ die "#ERROR Reg_macro Field of greater than 32 bits in $short_name!\n";
+ }
+
+ push(@{$reg->{fields}},
+ {
+ name => $field_name,
+ len => $field_len,
+ start => $field_start,
+ reset_mask => $reset_mask,
+ write_mask => $write_mask
+ });
+ }
+
+
+ } # end of register macro found
+
+ print Dumper $reg if ($REG_DEBUG);
+ push(@$reg_data, $reg);
+
+ }
+ }
+
+} # get_regs
+
+
+
+# Build a hash of registers, keyed on function and offset. That is,
+# given parsed register information, construct a hash with the
+# following structure
+#
+# $reg_hash { function } { offset }
+#
+# This will enable loops that iterate through registers in offset order
+#
+# Arguments: reference to array of reg information from get_regs
+# Returns: reference to constructed hash
+#
+sub build_reg_hash {
+ my ($reg_array) = @_;
+ my $reg_hash = {};
+
+ my $unknown_count = 0;
+
+ # iterate through all defined registers
+ foreach my $reg (@$reg_array) {
+
+ if ($reg->{offset} =~ m/^(0x[0-9A-F]+)$/i) {
+ # simple offset specified
+ my $offset = $1;
+
+ if (exists $reg_hash->{$reg->{function}}{$offset}) {
+ print STDERR "##ERROR Reg_macro A Collision at offset $offset of function $reg->{function} \n";
+ print STDERR " Existing register: " . $reg_hash->{$reg->{function}}{$offset}{long_name} . "\n";
+ print STDERR " New register: " . $reg->{long_name} . "\n";
+ print STDERR "#END\n";
+ $REG_ERRORS++;
+ }
+
+ $reg_hash->{$reg->{function}}{$offset} = $reg;
+
+ } elsif ($reg->{offset} =~ m/^(0x[0-9A-F]+)\s*-+\s*(0x[0-9A-F]+)/i) {
+
+ # range specified.
+ my $start = hex($1);
+ my $end = hex($2);
+
+ # determine stride
+ my $stride = $REG_STRIDE;
+ if ($reg->{offset} =~ m/,((?:0x)?[0-9A-F]+)/) {
+ $stride = hex($1);
+ }
+
+ my $count = 0;
+ for (my $index = $start; $index <= $end; $index += $stride) {
+
+ my $offset = sprintf("0x%03x",$index);
+
+ if (exists $reg_hash->{$reg->{function}}{$offset}) {
+ print STDERR "##ERROR Reg_macro Collision at offset $offset of function $reg->{function} \n";
+ print STDERR " Existing register: " . $reg_hash->{$reg->{function}}{$offset}{long_name} . "\n";
+ print STDERR " New register: " . $reg->{long_name} . "\n";
+ print STDERR "#END\n";
+ $REG_ERRORS++;
+ }
+
+ # perform any substitutions in long_name
+ my $reg_copy = { %{$reg} };
+ if ($reg_copy->{long_name} =~ m/<n>/) {
+ $reg_copy->{long_name} =~ s/<n>/$count/;
+ } else {
+ $reg_copy->{long_name} .= " $count";
+ }
+
+ # perform any substitutions in short_name
+ if ($reg_copy->{short_name} =~ m/<n>/) {
+ $reg_copy->{short_name} =~ s/<n>/$count/;
+ } else {
+ $reg_copy->{short_name} .= "$count";
+ }
+
+ $reg_hash->{$reg->{function}}{$offset} = $reg_copy;
+ $count++;
+ }
+
+ } else {
+ # unknown offset
+ $reg_hash->{$reg->{function}}{"unk".$unknown_count++} = $reg;
+ print STDERR "#WARNING Reg_macro Register '$reg->{long_name}' has an unknown offset \n";
+ }
+
+ } # end foreach
+
+ return $reg_hash;
+} # build_reg_hash
+
+
+
+# Convert an ASCII string representing a binary number to a true decimal number
+sub bin2dec {
+ return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
+}
+
+# Convert a true number to a binary ASCII string
+sub dec2bin {
+ my $str = unpack("B32", pack("N", shift));
+ return $str;
+}
+
+# Covert an ASCII string representing a hex number to a binary ASCII string;
+sub hex2bin {
+ return unpack("B32", pack("N", hex(shift)));
+}
+
+# Convert an ASCII string representing a binary number to a hex ASCII string;
+sub bin2hex {
+
+ my $Bin = shift(@_);
+ my $Hex;
+
+ # Clean up string and look for errors
+ chomp $Bin;
+
+ if ($Bin =~ m/[^10]/) {
+ print STDERR "#ERROR Reg_macro $Bin is not binary\n";
+ return ("");
+ }
+ return scalar reverse unpack "h*",(pack "b*", scalar reverse $Bin);
+}
+
+
+
+# required by Perl
+1;
+
+## Local Variables:
+## mode: perl
+## End:
+
+
+
+
+
diff --git a/macros/latex/contrib/register/reg_list.pl b/macros/latex/contrib/register/reg_list.pl
new file mode 100644
index 0000000000..16c40cb554
--- /dev/null
+++ b/macros/latex/contrib/register/reg_list.pl
@@ -0,0 +1,329 @@
+#!/usr/bin/env perl
+###############################################################################
+#
+# File: reg_list.pl
+# RCS: $Header: /doc_tools/register/reg_list.pl 1.2 2004/08/16 23:37:07 lovell Exp $
+# Description: Output a table (per function) of CSR's in offset order
+# Author: Matthew Lovell
+# Created: Mon Mar 31 16:50:05 2003
+# Modified: Mon Aug 16 17:36:19 2004
+# Language: CPerl
+#
+# (C) Copyright 2003, Matthew Lovell, all rights reserved.
+#
+###############################################################################
+
+use lib("$ENV{WJ_HOME}/docs/common",
+ "$ENV{WJ_HOME}/docs/common");
+
+use Getopt::Long;
+use FileHandle;
+use Reg_macro;
+
+
+# Parameters controlling execution
+my $params =
+ {
+ file => "", # LaTeX file to parse
+ list => 0, # just list files
+ table => 0, # produce table files
+ Make => 0, # dependency extraction
+ };
+
+
+$DEBUG = 0;
+
+###############################################################################
+# M A I N #
+###############################################################################
+
+# read options and get files from command-line
+get_input_opts($params);
+$REG_DEBUG = 1 if ($DEBUG);
+
+my @files = get_tex_files($params->{file}, $params->{Make});
+
+if ($DEBUG or $params->{list}) {
+ print "\nFile tree\n";
+ print "----------------------------\n";
+ print join("\n",@files) . "\n\n";
+ exit if ($params->{list});
+}
+
+
+#
+# Just output Makefile dependencies and exit
+#
+if ($params->{Make}) {
+ print_depends_list($params->{file},
+ @files);
+ exit(0);
+}
+
+
+#
+# ...otherwise, go on to extract some register information
+#
+
+my @reg_data = ();
+
+for (@files) {
+ get_regs($_,\@reg_data)
+}
+
+my $reg_hash = build_reg_hash(\@reg_data);
+
+if (!$params->{table}) {
+ print_reg_list($reg_hash);
+} else {
+ make_reg_files($params->{file}, $reg_hash);
+}
+
+
+exit($REG_ERRORS);
+
+###############################################################################
+# S U B R O U T I N E S #
+###############################################################################
+
+
+# Print out file dependencies in a format suitable for use by
+# GNU make. Makefile rules should be setup to update this
+# information as necessary.
+#
+# Arguments: .tex filename
+# array of dependencies
+#
+sub print_depends_list {
+ my ($file, @depends) = @_;
+
+ my @setup_files = qw[preamble.sty];
+
+ # separate all .error files
+ my @error_files = grep { $_ =~ /\.error$/ } @depends;
+
+ # separate all .func files
+ my @func_files = grep { $_ =~ /\.func$/ } @depends;
+
+ # ensure output is on STDOUT
+ select STDOUT;
+
+ my $aux_file, $dvi_file, $d_file, $ps_file;
+ ($aux_file = $file) =~ s/\.tex$/.aux/;
+ ($dvi_file = $file) =~ s/\.tex$/.dvi/;
+ ($ps_file = $file) =~ s/\.tex$/.ps/;
+ ($d_file = $file) =~ s/\.tex$/.d/;
+
+
+ print "#\n";
+ print "# Generated dependency file. Do NOT check into HMS !!\n";
+ print "#\n\n";
+
+ # Print out dependency list for the .aux file itself
+ print "$aux_file $dvi_file : \\\n";
+ map { print "\t$_ \\\n" } @setup_files;
+ map { print "\t$_ \\\n" } @error_files;
+ map { print "\t$_ \\\n" } @func_files;
+
+ foreach my $file (@depends) {
+ next if ($file =~ m/\.(?:error|func)$/);
+ next if ($file =~ m/logo\.eps/);
+ print "\t$file \\\n";
+ }
+ print "\n";
+
+
+ # Repeat for the .d file, leaving out unneeded files
+ print "$d_file : \\\n";
+
+ foreach my $file (@depends) {
+ next if ($file =~ m/\.(?:error|func)$/);
+ next if ($file =~ m/\.eps$/);
+ print "\t$file \\\n";
+ }
+ print "\n\n";
+
+
+} # print_depends_list
+
+
+
+# Print out register names in offset order to STDOUT. Used to
+# ensure script is acting correctly.
+#
+# Arguments: reference to hash constructed by build_reg_hash
+#
+sub print_reg_list {
+ my ($reg_hash) = @_;
+
+ my @functions = keys %$reg_hash;
+
+ print "\n";
+ for my $func (sort @functions) {
+
+ print "Function $func Registers\n";
+ print "-" x 80 . "\n";
+
+ for my $offset (sort { hex($a) <=> hex($b) } keys %{$reg_hash->{$func}}) {
+ my $output = "";
+ if ($offset =~ /^unk/) {
+ $output = sprintf(" ? %-50s %-20s",
+ $reg_hash->{$func}{$offset}{long_name},
+ $reg_hash->{$func}{$offset}{short_name}
+ );
+ } else {
+ $output = sprintf("%03x %-50s %-20s",
+ hex($offset),
+ $reg_hash->{$func}{$offset}{long_name},
+ $reg_hash->{$func}{$offset}{short_name}
+ );
+ }
+
+ print "$output\n";
+ }
+
+ print "\n\n";
+ }
+
+} # print_reg_list
+
+
+
+# Output a LaTeX longtable listing registers in each function.
+#
+# Arguments: name of latex file parsed, used as the root for
+# the table files names
+#
+# reference to hash created by build_reg_hash
+#
+sub make_reg_files {
+ my ($orig_file, $reg_hash) = @_;
+
+ my @functions = keys %$reg_hash;
+ for my $func (sort @functions) {
+
+ my $filename = $orig_file =~ s/\.tex$//;
+ $filename = $orig_file . ".func$func";
+
+ my $file = new FileHandle ">$filename";
+ if (!defined $file) {
+ print STDERR "#ERROR reg_list.pl Unable to open $filename for writing!";
+ die;
+ }
+
+ for my $offset (sort { hex($a) <=> hex($b) } keys %{$reg_hash->{$func}}) {
+
+ my $name = $reg_hash->{$func}{$offset}{long_name};
+ if (defined $reg_hash->{$func}{$offset}{short_name}) {
+ $name .= " ($reg_hash->{$func}{$offset}{short_name})";
+ }
+
+ my $pageref = "";
+ if (exists $reg_hash->{$func}{$offset}{label}) {
+ $pageref = '\pageref{' . $reg_hash->{$func}{$offset}{label} . '}';
+ }
+
+ if ($offset =~ /^unk/) {
+ printf $file "\\texttt{?} & %s & %s \\\\\n",
+ $name, $pageref;
+ } else {
+ printf $file "\\texttt{0x%03x} & %s & %s \\\\\n",
+ hex($offset), $name, $pageref;
+ }
+
+ }
+
+ close $file;
+
+ }
+
+
+} # make_reg_files
+
+
+# Retrieve the input parms passed to this script and set the proper
+# options. Some global variables may be set by this subroutine.
+#
+# Arguments: reference to parameters hash
+#
+sub get_input_opts {
+ my ($params) = @_;
+ my $help = 0;
+
+ # Setup for GetOptions
+ $Getopt::Long::autoabbrev = 1;
+ $Getopt::Long::ignorecase = 0;
+ $Getopt::Long::order = $PERMUTE;
+
+ my @optl = ();
+ push(@optl,
+ "help", \$help, # show usage information
+ "debug", \$DEBUG, # show debug information
+ "file=s", \$params->{file}, # LaTeX file to parse
+
+ "list", \$params->{list},
+ "table", \$params->{table},
+ "Make", \$params->{Make},
+ );
+
+ GetOptions(@optl);
+
+ if ($help) {
+ print_usage_and_die();
+ }
+
+ if ($params->{file} eq "") {
+ print "Must specify a LaTeX file. Use --help for usage info.\n";
+ exit(1);
+ }
+
+
+ return;
+} # get_input_opts
+
+
+sub print_usage_and_die {
+ $usage = <<"@@USAGE_INFO";
+Register (CSR) Lister
+
+This script parses all register/CSR diagrams found in a LaTeX document.
+The document can include or import sub-documents; the script will follow
+the tree.
+
+By default, a human-readable list of registers, ordered by offset
+within each function, is printed to STDOUT. If the -table option is
+given, files are written with a similar table formatted for inclusion
+in a LaTeX document. The filenames will have the same root as the
+file specified on the command-line, but with an extension of
+
+ .func<function>
+
+for each non-empty function encountered during parsing.
+
+Usage:
+
+ reg_list.pl -file <.tex file>
+ ( [-table] | [-list] | [-Make] )
+ [-debug] [-help]
+
+
+ <.tex file> LaTeX file to parse
+
+ Mutually exclusive
+ ------------------
+ -table Produce LaTeX table output, no STDOUT output
+ -list Show the file tree of <.tex file>, then quit
+ -Make Produce makefile dependencies for specified LaTeX file
+
+
+ Other options
+ -------------
+ -debug Show parsing debug information
+ -help Print this stuff
+
+
+@@USAGE_INFO
+
+ print $usage;
+ exit(1);
+} # print_usage_and_die
diff --git a/macros/latex/contrib/register/register.dtx b/macros/latex/contrib/register/register.dtx
new file mode 100644
index 0000000000..2c2b41cf6d
--- /dev/null
+++ b/macros/latex/contrib/register/register.dtx
@@ -0,0 +1,1376 @@
+% \iffalse
+%
+% register.dtx
+% Register diagrams with field descriptions
+%
+% Author: Matthew Lovell (lovells@gmail.com)
+% Copyright 2001-2019 by Matthew B. Lovell
+%
+% Run LaTeX on the file `register.ins' to get a .sty-file and
+% then on `register.dtx' to obtain instructions.
+%
+% This program is provided under the terms of the
+% LaTeX Project Public License distributed from CTAN
+% archives in directory macros/latex/base/lppl.txt.
+%
+% This program consists of register.dtx, register.ins,
+% reg_reset.pl, and reg_table.pl.
+%
+%<*dtx>
+\ProvidesFile{register.dtx}
+%</dtx>
+% \fi
+% \CheckSum{785}
+%
+% \def\fileversion{v1.9}
+% \def\filedate{2019/01/01}
+% \title{Register diagrams with field descriptions}
+% \author{Matthew Lovell\\
+% \texttt{lovells@gmail.com}
+% }
+% \date{\filedate}
+% \maketitle
+%
+% \providecommand{\LyX}{L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@}
+%
+% \begin{abstract}
+% The |register| package is designed for typesetting
+% the programmable elements in digital hardware, i.e., registers.
+% Such registers typically have many fields and can be quite wide;
+% they are thus a challenge to typeset in a consistent manner.
+% This package attempts to address such issues. It is similar
+% in some aspects to the |bitfield| package by Reuben Thomas and the
+% |bytefield| package by Scott Pakin.
+% \end{abstract}
+%
+% \StopEventually
+%
+% \iffalse
+%<*driver>
+\documentclass{ltxdoc}
+\RequirePackage{textcomp}
+\RequirePackage[TRflags,TRboxed,color]{register}
+\RequirePackage{amsmath}
+\RequirePackage{amssymb}
+\setlength{\regWidth}{0.98\textwidth}
+\setlength{\TRwidth}{40pt}
+\RecordChanges
+\begin{document}
+ \DocInput{register.dtx}
+% \PrintChanges
+\end{document}
+%</driver>
+% \fi
+%
+% \listofregisters
+%
+%
+% \section{Introduction} \label{sec:background}
+%
+% My group at work designed the memory and I/O controllers for servers
+% and workstations. Historically, our chip documentation was done
+% with FrameMaker or Microsoft Word. While these approaches have
+% various disadvantages, one of the most egregious was register
+% documentation.
+%
+% The recent chips have 64-bit wide control-status registers (CSR)
+% or, more simply, registers. Add the fact that many of these
+% registers have a large number of single-bit fields, and you get a
+% typesetting challenge. The typical solution was to describe such
+% registers using a table, typing field names vertically if space
+% became a problem. For a complicated register, these tables became
+% quite complex and filled a large portion of a page.
+%
+% When we decided to evaluate \LaTeX{} for documentation, we had three
+% goals in mind with respect to registers:
+% \begin{enumerate}
+% \item Create a method of documenting registers which was consistent
+% and easy to read, regardless of the number of fields within a
+% register.
+% \item Automate the creation of lists of registers, both in order
+% of appearance within the text and in memory address order.
+% \item Enable the automatic extraction of documented register reset
+% values in order to verify register functionality in the chip
+% itself.
+% \end{enumerate}
+% The |register| package is my attempt at meeting all three goals. It
+% was first put into use in April 1999; it may be not be
+% pretty to all eyes, but it certainly has proven itself stable.
+%
+% In order to promote \LaTeX{} within our group at the time, we also
+% adopted \LyX{}. The |register| package thus attempts to work well
+% within that environment. All \LyX{}-specific code, however, is
+% controlled via package options.
+%
+% \subsection{Feedback}
+%
+% As |register| is my first \LaTeX{} package, I would welcome
+% feedback regarding problems, new features, or more proper means of
+% implementing existing features. For example, is there an
+% ``official'' method for determining the current font's maximum
+% height and depth (see Section~\ref{sec:reg_fields} for details)? I
+% would also appreciate knowing whether anyone ever actually uses it.
+%
+% It might also be worthwhile to investigate combining |register| with
+% |bitfield| or |bytefield|.
+%
+% \section{Examples}
+
+% Register~\ref{Diagnostic Control} depicts a register with many
+% single-bit fields. Registers such as this stress any scheme of
+% typesetting, since the field names are so much longer than the space
+% available for them within the diagram. By typesetting the field
+% names at an angle, |register| manages to be consistent regardless of
+% the number or width of fields. This rotation, however, means that
+% documents which use |register| must be produced using PostScript.
+%
+% \begin{register}{H}{Diagnostic Control}{0x1F28}^^A NAME=DIAG_CTRL1
+% \label{Diagnostic Control}^^A
+% \regfield{reserved}{1}{63}{0}^^A
+% \regfield{cmp\_ack64}{1}{62}{0}^^A
+% \regfield{cmp\_req64}{1}{61}{0}^^A
+% \regfield{cmp\_devsel}{1}{60}{0}^^A
+% \regfield{cmp\_stop}{1}{59}{0}^^A
+% \regfield{cmp\_trdy}{1}{58}{0}^^A
+% \regfield{cmp\_irdy}{1}{57}{0}^^A
+% \regfield{cmp\_frame}{1}{56}{0}^^A
+% \regfield{reserved}{1}{55}{0}^^A
+% \regfield{mask\_ack64}{1}{54}{0}^^A
+% \regfield{mask\_req64}{1}{53}{0}^^A
+% \regfield{mask\_devsel}{1}{52}{0}^^A
+% \regfield{mask\_stop}{1}{51}{0}^^A
+% \regfield{mask\_trdy}{1}{50}{0}^^A
+% \regfield{mask\_irdy}{1}{49}{0}^^A
+% \regfield{mask\_frame}{1}{48}{0}^^A
+% \regfield{cmp\_cbe}{8}{40}{0}^^A
+% \regfield{mask\_cbe}{8}{32}{0}^^A
+% \reglabel{Reset}^^A
+% \regnewline^^A
+% \regfield{reserved}{1}{31}{0}^^A
+% \regfield{cmp\_arb}{7}{24}{0}^^A
+% \regfield{reserved}{1}{23}{0}^^A
+% \regfield{mask\_arb}{7}{16}{0}^^A
+% \regfield{reserved}{5}{11}{0}^^A
+% \regfield{grp\_en\_cntl}{1}{10}{0}^^A
+% \regfield{grp\_en\_cbe}{1}{9}{0}^^A
+% \regfield{grp\_en\_arb}{1}{8}{0}^^A
+% \regfield{grp\_en\_fifo}{1}{7}{0}^^A
+% \regfield{dly\_frame}{1}{6}{0}^^A
+% \regfield{level\_frame}{1}{5}{0}^^A
+% \regfield{level\_cntl}{1}{4}{0}^^A
+% \regfield{level\_cbe}{1}{3}{0}^^A
+% \regfield{level\_arb}{1}{2}{0}^^A
+% \regfield{hlt\_trg\_on\_1}{1}{1}{0}^^A
+% \regfield{alwys\_cnt\_1}{1}{0}{0}^^A
+% \reglabel{Reset}^^A
+% \regnewline^^A
+% \end{register}
+%
+% Register~\ref{Function Class} is an example of a register one could
+% derive from the PCI specification. It is a miscellaneous register
+% in a PCI card which controls device independent functions. Note the
+% field descriptions which, in this case, are actually part of the
+% float.
+%
+% \begin{register}{htbp}{Function Class}{0x0008}^^A NAME=FC
+% \label{Function Class}^^A
+% \regfield{BIST}{8}{56}{0}^^A READ_ONLY
+% \regfield{Header Type}{8}{48}{0}^^A READ_ONLY
+% \regfield{Latency Timer}{8}{40}{0}^^A
+% \regfield{Line Size}{8}{32}{0}^^A
+% \reglabel{Reset}^^A
+% \regnewline^^A
+% \regfield{Class Code}{24}{8}{{0x060000}}^^A READ_ONLY
+% \regfield{Revision}{8}{0}{{0x10}}^^A READ_ONLY
+% \reglabel{Reset}^^A
+% \regnewline^^A
+% \begin{regdesc}^^A
+%
+% \begin{reglist}[Latency Timer]
+% \item [BIST](Read only) Always returns 0.
+% \item [Header~Type](Read only) Always returns 0.
+% \item [Latency~Timer]PCI Latency Timer value (PCI 2.2 spec, Section 6.2.4).
+% \item [Line~Size]PCI Cache Line Size (PCI 2.2 spec, Section 6.2.4). Valid
+% values are listed below; any other value will be treated as indicating
+% 64 byte cache lines.
+% \begin{description}
+% \item [0010\_0000]128 bytes
+% \item [0001\_0000]64 bytes
+% \end{description}
+% \item [Class~Code](Read only) PCI Class Code (PCI 2.2 spec, Section 6.2.1).
+% Chip identifies itself as a Host bridge.
+% \item [Revision](Read only) Chip revision number. Bits 4--7 provide the major
+% revision number, and bits 0--3 provide the minor
+% revision number.
+% \end{reglist}
+% \end{regdesc}
+% \end{register}
+%
+% A final example is shown in Figure~\ref{fig:regbus_cycle}. This
+% example shows that the register drawing macros don't have to be used
+% solely within a |register| float or environment. With Version~1.8,
+% an unnumbered register environment is also available, using
+% |register*|. Diagrams produced using the starred environment
+% typeset just the register name, omitting the ``Register'' and number
+% prefix.
+%
+% \begin{figure}[H]
+% \begin{center}^^A
+% \regfieldb{write\_en}{1}{15}^^A
+% \regfieldb{reserved}{2}{13}^^A
+% \regfieldb{function}{1}{12}^^A
+% \regfieldb{block}{4}{8}^^A
+% \regfieldb{register}{5}{3}^^A
+% \regfieldb{reserved}{3}{0}^^A
+% \reglabelb{Address phase} \\
+% \regfieldb{reserved}{8}{8}^^A
+% \regfieldb{BE}{8}{0}^^A
+% \reglabelb{BE phase}^^A
+% \end{center}^^A
+% \caption{Address and BE phases for register access}\label{fig:regbus_cycle}
+% \end{figure}
+%
+%
+% \section{User Interface} \label{sec:user}
+%
+% The user interface for register diagrams could be regarded as
+% overly verbose. The main idea behind the parameters was to allow
+% \LaTeX{} \emph{and} accompanying Perl scripts to decipher register
+% fields and reset values. The simplest way to show the interface
+% is via another example. Below is a 64-bit register.
+% \begin{register}{H}{Example}{0x250}^^A name=example
+% \label{example}^^A
+% \regfield{FIFO depth}{6}{58}{{random}}^^A
+% \regfield{Something}{4}{54}{1100}^^A
+% \regfield{Status}{21}{33}{{uninitialized}}^^A
+% \regfield{Enable}{1}{32}{1}^^A
+% \reglabel{Reset}\regnewline^^A
+% \regfield{Counter}{10}{22}{{0x244}}^^A READ_ONLY
+% \regfield{Howdy}{5}{17}{1_1010}^^A
+% \regfield{Control}{1}{16}{-}^^A
+% \regfield{Hardfail}{1}{15}{1}^^A
+% \regfield{Data}{15}{0}{{uninitialized}}^^A
+% \reglabel{Reset}\regnewline^^A
+% \end{register}
+%
+% It was created with the following commands:
+%
+% \begin{verbatim}
+% \begin{register}{H}{Example}{0x250}% name=example
+% \label{example}%
+% \regfield{FIFO depth}{6}{58}{{random}}%
+% \regfield{Something}{4}{54}{1100}%
+% \regfield{Status}{21}{33}{{uninitialized}}%
+% \regfield{Enable}{1}{32}{1}%
+% \reglabel{Reset}\regnewline%
+% \regfield{Counter}{10}{22}{{0x244}}% READ_ONLY
+% \regfield{Howdy}{5}{17}{1_1010}%
+% \regfield{Control}{1}{16}{-}%
+% \regfield{Hardfail}{1}{15}{1}%
+% \regfield{Data}{15}{0}{{uninitialized}}%
+% \reglabel{Reset}%\regnewline%
+% \end{register}
+% \end{verbatim}
+%
+% \begin{macro}{register}
+% \begin{macro}{\listofregisters}
+% The register environment begins with |\begin{register}|. The three
+% parameters to the environment are the float specification (|h|, |H|,
+% |t|, |b|, or |p|); the register name; and the register's offset in
+% memory space. These parameters become the register caption as well
+% as the entry in the list of registers, which is typeset using
+% |\listofregisters|.
+% \end{macro}
+% \end{macro}
+% \hspace*{\MacroIndent}|\begin{register}{|\meta{placement}|}{|^^A
+% \meta{register name}|}{|\meta{register offset}|}|
+%
+% \begin{macro}{\regfield}
+% Each register field is then typeset using |\regfield|. The fields
+% must be specified\footnote{Provided you're a little-endian person!}
+% starting with the most-significant bit. The |\regfield| macro takes
+% four parameters: field name, field length (in bits), starting bit
+% number, and reset value. The reset value, unless you pass it as a
+% single token (see example), will be spread apart to fill up the
+% width of the field. The reset value, since it could be just a
+% very long binary number, can be interrupted with underscores to
+% improve readability.
+% \end{macro}
+% \hspace*{\MacroIndent}|\regfield{|\meta{name}|}{|\meta{length}|}{|^^A
+% \meta{start bit}|}{|\meta{reset value}|}|\\[2pt]
+%
+% Note that the comments that are shown in the code are for the
+% benefit of the helper scripts that accompany the |register|
+% package. Those scripts are quite old and have \emph{not} been
+% updated to be tolerant of the optional color argument that is now
+% supported. However, the general notion of using embedded comments
+% to augment register or field information is still applicable, if
+% one is using this package with the intent of generating HDL code
+% from documentation.
+%
+% \begin{macro}{\regBitWidth}
+% \begin{macro}{\regnewline}
+% \begin{macro}{\reglabel}
+% The macro |\regBitWidth| specifies the maximum number of bits to be
+% typeset on a single line. Once a line has been completed, a new line
+% can be inserted via |\regnewline|. Before starting a new line,
+% however, an appropriate label for the reset value should be typed.
+% This label is generated via |\reglabel|, which takes the string to
+% typeset as a single parameter. The package, via the macro
+% |\regResetName|, assumes that |Reset| will be used in order to set
+% some lengths appropriately; it really only matters for very full
+% lines. In a future version, it may be possible to make
+% |\regResetName| be the default parameter to |\reglabel|.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \hspace*{\MacroIndent}|\reglabel{|\meta{reset label}|}|\\[2pt]
+%
+%
+% As another example, consider Register~\ref{Configuration} below, which has
+% field descriptions as part of the float. This diagram was created
+% with the following code:
+% \begin{verbatim}
+% \begin{register}{htbp}{Configuration}{0x2848}% name=CONFIG
+% \label{Configuration}%
+% \regfield{soft reset perf}{1}{63}{0}% STATUS
+% \regfield{reserved}{30}{33}{0}%
+% \regfield{Test mode}{1}{32}{0}%
+% \reglabel{Reset}\regnewline%
+% \regfield{reserved}{13}{19}{0}%
+% \regfield{\parbox[b]{0pt}{Request Depth}}{7}{12}{1}%
+% \regfield{reserved}{3}{9}{0}%
+% \regfield{line\_2x\_L}{1}{8}{?}% STATUS
+% \regfield{reserved}{1}{7}{0}%
+% \regfield{ill\_cmd\_enable}{1}{6}{0}%
+% \regfield{LPCE}{1}{5}{0}%
+% \regfield{DVI disable}{1}{4}{0}%
+% \regfield{SBA enable}{1}{3}{0}%
+% \regfield{reserved}{2}{1}{0}%
+% \regfield{line\_2x\_enable}{1}{0}{0}% READ_ONLY
+% \reglabel{Reset}\regnewline%
+% \begin{regdesc}\begin{reglist}[Request~Depth]
+% \item [line\_2x\_enable]Setting this bit enables the chip
+% to utilize a second connected data line.
+% \item [SBA~enable]Setting this bit activates the sideband-address port.
+% The SBA port is only useable in a double-line configuration.
+% \item [DVI~disable]Setting this bit \emph{turns off} DVI extraction for
+% DMA requests.
+% \item [LPCE]Line Parity Check Enable.
+% \item [ill\_cmd\_enable]\TR{3}Illegal Command enable.
+% This bit is new for TR3.
+% \item [line\_2x\_L](Read only) Indicates whether this chip is connected
+% to a second data line. When this bit is 0, a second line
+% is available.
+% \item [Request~Depth]Controls number of outstanding DMA requests.
+% \item [Test~mode]Activates data line test mode.
+% \item [soft~reset~perf]\TR{4}Indicates that a soft reset has been
+% performed. This bit is new for TR4.
+% \end{reglist}\end{regdesc}\end{register}
+% \end{verbatim}
+%
+%
+% \begin{register}{htbp}{Configuration}{0x2848}^^A NAME=CONFIG
+% \label{Configuration}^^A
+% \regfield{soft reset perf}{1}{63}{0}^^A STATUS
+% \regfield{reserved}{30}{33}{0}^^A
+% \regfield{Test mode}{1}{32}{0}^^A
+% \reglabel{Reset}\regnewline^^A
+% \regfield{reserved}{13}{19}{0}^^A
+% \regfield{\parbox[b]{0pt}{Request Depth}}{7}{12}{1}^^A
+% \regfield{reserved}{3}{9}{0}^^A
+% \regfield{line\_2x\_L}{1}{8}{?}^^A STATUS
+% \regfield{reserved}{1}{7}{0}^^A
+% \regfield{ill\_cmd\_enable}{1}{6}{0}^^A
+% \regfield{PCE}{1}{5}{0}^^A
+% \regfield{DVI disable}{1}{4}{0}^^A
+% \regfield{SBA enable}{1}{3}{0}^^A
+% \regfield{reserved}{2}{1}{0}^^A
+% \regfield{line\_2x\_enable}{1}{0}{0}^^A READ_ONLY
+% \reglabel{Reset}\regnewline^^A
+%
+% \begin{regdesc}\begin{reglist}[Request~Depth]
+% \item [line\_2x\_enable]Setting this bit enables this chip to utilize a second
+% connected data line.
+% \item [SBA~enable]Setting this bit activates the sideband-address port.
+% The SBA port is only useable in a double-line configuration.
+% \item [DVI~disable]Setting this bit \emph{turns off} DVI extraction for
+% DMA requests.
+% \item [LPCE]Line Parity Check Enable.
+% \item [ill\_cmd\_enable]\TR{3}Illegal OCMD enable.
+% This bit is new for TR3.
+% \item [line\_2x\_L](Read only) Indicates whether this chip is connected
+% to a second data line. When this bit is 0, a second line is available.
+% \item [Request~Depth]Controls number of outstanding DMA requests.
+% \item [Test~mode]Activates data line test mode.
+% \item [soft~reset~perf]\TR{4}Indicates that a soft reset has been
+% performed. This bit is new for TR4.
+% \end{reglist}\end{regdesc}\end{register}
+%
+% \begin{macro}{regdesc}
+% \begin{macro}{reglist}
+% \begin{macro}{lyxlist}
+
+% This example uses the |regdesc| environment, which can either be
+% part of a register float or used standalone. The purpose of
+% |regdesc| is really just to turn on centering and, when the |LyX|
+% package option is specified, redefine the |lyxlist| environment. If
+% one is using \LyX{}, then register field descriptions can be entered
+% using its List type. If one is typing \LaTeX{} directly, just use
+% the |reglist| list definition.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% The |regdesc| and |reglist| environments both take optional
+% arguments. For |regdesc|, the optional argument specifies how wide
+% the register description body should be. The default value is 90\%
+% of |\textwidth|. For |reglist|, the optional argument is the
+% longest field name, which allows the list to be spaced appropriately
+% (like examples given in \emph{The \LaTeX{} Companion}).
+%
+% \begin{macro}{\regfieldb}
+% Finally, if a register with no reset values is desired, one can use
+% the |\regfieldb| macro. It takes the same first three arguments as
+% |\regfield|. Figure~\ref{fig:regbus_cycle} was produced using |\regfieldb|.
+% \end{macro}
+%
+%
+%
+% \subsection{TR Flags}
+%
+% \begin{macro}{\TR}
+% The previous example also shows the TR flags. These marginal notes can
+% be used to denote features that are specific to a particular release
+% of a chip. These macros were created since \LaTeX{}'s |\marginpar|
+% is itself a float; as such it cannot be nested inside other floats.
+% The |\TR| macros thus implement something very similar to the
+% solution for Problem~14.28 in \emph{The \TeX{}book}.
+
+% TR flags are turned on via the |TRflags| package option. If the
+% option is not specified, then the |\TR| macro still exists but is
+% empty. The TR flags are placed inside an |\fbox| if the |TRboxed|
+% package option is specified.
+%
+% For two-sided documents, the TR flags are placed in the outer
+% margins. The placement decision is made by placing labels for each
+% TR flag and then determining even/odd page numbering in a subsequent
+% \LaTeX{} run.
+% \end{macro}
+%
+% \subsection{Background Colors} \label{sec:colors}
+%
+% With Version 1.7, this package also supports an optional |color| package option. If that option
+% is present, then |xcolor| is loaded and the |\regfield| and |\regfieldb| macros support an
+% optional first argument that is used as fill color for the boxes drawn by |\framebox|. Internally,
+% |\colorbox| is used to provide this functionality.
+%
+% Repeating our example from earlier, but with some fill colors specified:
+% \begin{verbatim}
+% \begin{register}{H}{Color Example}{0x250}% name=example
+% \label{colexample}%
+% \regfield{FIFO depth}{6}{58}{{random}}%
+% \regfield[green!30]{Something}{4}{54}{1100}%
+% \regfield[gray!20]{Status}{21}{33}{{uninitialized}}%
+% \regfield{Enable}{1}{32}{1}%
+% \reglabel{Reset}\regnewline%
+% \regfield{Counter}{10}{22}{{0x244}}% READ_ONLY
+% \regfield[red!20]{Howdy}{5}{17}{1_1010}%
+% \regfield{Control}{1}{16}{-}%
+% \regfield[yellow!50]{Hardfail}{1}{15}{1}%
+% \regfield[gray!20]{Data}{15}{0}{{uninitialized}}%
+% \reglabel{Reset}%\regnewline%
+% \end{register}
+% \end{verbatim}
+% now yields the following:
+% \begin{register}{H}{Color Example}{0x250}^^A name=example
+% \label{colexample}^^A
+% \regfield{FIFO depth}{6}{58}{{random}}^^A
+% \regfield[green!30]{Something}{4}{54}{1100}^^A
+% \regfield[gray!20]{Status}{21}{33}{{uninitialized}}^^A
+% \regfield{Enable}{1}{32}{1}^^A
+% \reglabel{Reset}\regnewline^^A
+% \regfield{Counter}{10}{22}{{0x244}}^^A READ_ONLY
+% \regfield[red!20]{Howdy}{5}{17}{1_1010}^^A
+% \regfield{Control}{1}{16}{-}^^A
+% \regfield[yellow!50]{Hardfail}{1}{15}{1}^^A
+% \regfield[gray!20]{Data}{15}{0}{{uninitialized}}^^A
+% \reglabel{Reset}%\regnewline^^A
+% \end{register}
+%
+% \section{Helper Scripts} \label{sec:scripts}
+%
+% A (now old) Perl module and a Perl script are included as part of the
+% |register| package. The module augments the package by
+% providing the ability to parse the register macro information into
+% Perl. This information consists of the parameters used within
+% the macros themselves, as well as the comments which follow. If
+% you examine the last register example, you will notice that some
+% fields specify |READ\_ONLY| or |STATUS| in a comment. The
+% ``directives'' can be used to indicate that particular fields are
+% unaffected by writes or unaffected by reset, respectively.
+%
+% The script, |reg_list.pl|, utilizes the Perl module to produce lists
+% of registers in offset-order or to generate reset value and mask
+% information for each register. The later data can be used in
+% simulation to ensure that registers behave as documented.
+%
+% Users are cautioned that the Perl script, since it is no longer in
+% active use by the author, has not been modified to support the
+% optional color argument for the |regfield| macro.
+%
+% \section{Version History} \label{sec:history}
+%
+% \begin{itemize}
+% \item [\textbf{v0.1}] (1999/03/29) First release
+% \item [\textbf{v0.2}] (2000/01/29) Added regdesc environment, for use under LyX
+% \item [\textbf{v0.21}] (2000/03/12) Fixed minute problem shown in regs with lots of 1-bit fields
+% \item [\textbf{v0.3}] (2000/06/19) Added reglabelb macro, for setting label without a drop
+% \item [\textbf{v0.31}] (2000/07/11) Modified names of lengths used within macros
+% \item [\textbf{v0.32}] (2000/08/02) Modified regdesc env to use regdescsep for vertical separation
+% \item [\textbf{v0.4}] (2001/08/11) Added macros for marginal Tape Release flags
+% \item [\textbf{v0.5}] (2001/08/12) Added package options for handling LyX, hyperref, and TR flags
+% \item [\textbf{v0.6}] (2001/08/19) Moved chapter redefinition into package; improved TR flags
+% \item [\textbf{v1.0}] (2001/09/06) Created .dtx documentation; first public release
+% \item [\textbf{v1.01}] (2003/01/17) Removed automatic label in register diagrams
+% \item [\textbf{v1.1}] (2003/02/15) Changed length manipulation to work with parskip package
+% \item [\textbf{v1.2}] (2003/03/31) Removed requirement to specify register offset
+% \item [\textbf{v1.3}] (2003/11/24) Changed how center is handled within register environment
+% \item [\textbf{v1.4}] (2004/08/16) Now provide a boolean set only in register context
+% \item [\textbf{v1.5}] (2007/03/08) Corrected use of conditionals used in spreading register reset value
+% \item [\textbf{v1.6}] (2011/01/11) Mainmatter correction suggested by Kjetil Oftedal
+% \item [\textbf{v1.6.1}] (2018/05/19) Published with updated email address; no functional changes
+% \item [\textbf{v1.7}] (2018/08/18) Added color option to package, suggested by Marco Stolba
+% \item [\textbf{v1.8}] (2018/11/10) Added unnumbered |register*| environment, suggested and written by Stephan Bauroth
+% \item [\textbf{v1.9}] (2019/01/01) Switched to a re-definable macro to provide default float name and LoR name, suggested by Benyuan Liu.
+% \end{itemize}
+%
+%
+% ^^A -------------------------------------------------------------------------
+% \newpage
+%
+% \section{Implementation} \label{sec:docstrip}
+%
+% \subsection{Identification \& Options} \label{sec:id}
+%
+% The |register| document class can only be used with \LaTeXe, so we make
+% sure that an appropriate message is displayed when another \TeX{}
+% format is used.
+% \begin{macrocode}
+%<*package>\NeedsTeXFormat{LaTeX2e}
+% \end{macrocode}
+%
+% Announce the name and unconditionally load most of the required packages:
+% \begin{macrocode}
+\ProvidesPackage{register} [2019/01/01 v1.9 Register macros with
+hyperref/LyX support]
+
+\RequirePackage{ifthen}[1997/11/02]
+\RequirePackage{graphicx}[1997/06/09]
+\RequirePackage{float}[2001/07/25]
+\RequirePackage{calc}[1998/06/07]
+% \end{macrocode}
+%
+% Declare the package options and some booleans. There are options indicating
+% whether |register| is being used with \LyX{} or |hyperref|. The marginal
+% TR flags can also be turned on or off with an option.
+% \begin{macrocode}
+\DeclareOption{LyX}{\setboolean{RegisterLyX}{true}}
+\DeclareOption{hyperref}{\setboolean{RegisterHyperref}{true}}
+\DeclareOption{TRflags}{\setboolean{RegisterTRFlags}{true}}
+\DeclareOption{TRboxed}{\setboolean{RegisterTRBoxed}{true}}
+\DeclareOption{color}{\setboolean{RegisterColors}{true}}
+
+\DeclareOption*{% Emit a warning for other options
+ \PackageWarning{register}{Unknown option '\CurrentOption'}%
+}
+
+\newboolean{RegisterLyX}
+\newboolean{RegisterHyperref}
+\newboolean{RegisterTRFlags}
+\newboolean{RegisterTRBoxed}
+\newboolean{RegisterColors}
+
+\setboolean{RegisterLyX}{false}
+\setboolean{RegisterHyperref}{false}
+\setboolean{RegisterTRFlags}{false}
+\setboolean{RegisterTRBoxed}{false}
+\setboolean{RegisterColors}{false}
+
+\ProcessOptions\relax % Process package options
+% \end{macrocode}
+%
+%
+% If the |color| package option has been specified, go ahead and
+% load the |xcolor| package as well.
+% \begin{macrocode}
+\ifthenelse{\boolean{RegisterColors}}{\RequirePackage{xcolor}[2007/01/21]}{}
+% \end{macrocode}
+%
+% Next, provide a flag indicating when one is inside a register
+% context. Some users may wish to define macros, for example,
+% which make use of |\marginpar|. Those cannot be used inside
+% of a floating register. So, this flag is provided to
+% provide something to test against.
+% \begin{macrocode}
+\newboolean{RegisterContext}
+\setboolean{RegisterContext}{false}
+% \end{macrocode}
+%
+% \begin{macro}{\regFloatName}
+% \begin{macro}{\regListName}
+% \begin{macro}{\regResetName}
+% Below are some macros that support a little internationalization, expanded
+% upon a suggestion from Benyuan Liu.
+% The |\regFloatName| provides the default string used to label each register diagram.
+% The string with which to label reset values is |\regResetName|.
+% The font size for field names and for the |\regResetName| is controlled by |\regLabelSize|, defined further below.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+\newcommand{\regFloatName}{Register}
+\newcommand{\regListName}{List of Registers}
+\newcommand{\regResetName}{Reset}
+% \end{macrocode}
+
+
+% \subsection{Float Declaration \& Lengths} \label{sec:float}
+%
+% Declare the new register float type and the lengths which the
+% macros will use. The register diagrams tend to look best with
+% the caption at the top of the float. If |\chapter| is defined in
+% the current document class, then the register diagrams will count
+% by chapter, otherwise they will count by section.
+%
+% \begin{macrocode}
+\floatstyle{plaintop} \@ifundefined{chapter}
+{\newfloat{Regfloat}{tbp}{rdf}[section]}
+{\newfloat{Regfloat}{tbp}{rdf}[chapter]}
+\floatname{Regfloat}{\regFloatName}
+% \end{macrocode}
+%
+% \subsection{Style Parameters} \label{sec:style}
+%
+% \begin{macro}{\regWidth}
+% \begin{macro}{\regBitWidth}
+% The |\regWidth| length controls how physically wide the register
+% diagrams are, while |\regBitWidth| specifies how the maximum
+% number of bits per line in the diagram. The default value
+% for |\regWidth| is 95\% of the width of the main text body.
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\regBitSize}
+% \begin{macro}{\regBitFamily}
+% \begin{macro}{\regResetSize}
+% \begin{macro}{\regLabelSize}
+% \begin{macro}{\regLabelFamily}
+% \begin{macro}{\regDescFamily}
+% The |\regBitSize| command controls the font size
+% used for bit values, |\regResetSize| controls the font size used
+% for reset values, and |\regBitFamily| controls which font family
+% is used to denote bit positions.
+% Finally, |\regDescFamily| controls the appearance of field names
+% within register descriptions.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+\newlength{\regWidth}
+\newlength{\regFieldLen}
+\newlength{\regLabelAdjust}
+\newlength{\regResetHeight}
+\newlength{\regResetDepth}
+\newlength{\regResetDrop}
+\newlength{\regDescSkip}
+\newlength{\regRsvdHeight}
+\newlength{\regRsvdDrop}
+\newlength{\regFboxSep}
+\setlength{\regWidth}{0.95\textwidth}
+\newcommand{\regBitWidth}{32}
+\newcommand{\regBitSize}{\tiny}
+\newcommand{\regBitFamily}{\sffamily}
+\newcommand{\regResetSize}{\scriptsize}
+\newcommand{\regLabelSize}{\footnotesize}
+\newcommand{\regLabelFamily}{\rmfamily}
+\newcommand{\regDescFamily}{\bf}
+% \end{macrocode}
+% The lengths below control the vertical spacing between a
+% register diagrams and the register field descriptions. This
+% distance must change when the |\regdesc| is part of the |\Regfloat|
+% or standalone.
+% \begin{macrocode}
+\newlength{\regdescsep}
+\newlength{\oldregdescsep}
+\setlength{\regdescsep}{-\medskipamount}
+
+\newsavebox{\Label}
+\newsavebox{\RotatedLabel}
+\newcounter{upperbit}
+\newcounter{lowerbit}
+% \end{macrocode}
+%
+% \subsection{Register macros} \label{sec:regdesc}
+%
+% \begin{macro}{\reglist}
+% Define a new environment for register field descriptions,
+% beneath a register diagram. These descriptions can indicate what
+% a particular field is used for, whether it is read-only, etc. The
+% field descriptions themselves are in a |\reglist| list environment,
+% unless \LyX{} is being used.
+% \end{macro}
+% \begin{macrocode}
+\newenvironment{reglist}[1][M]
+ {\begin{list}{}
+ {\settowidth{\labelwidth}{\regDescFamily #1}
+ \addtolength{\labelwidth}{\labelsep}
+ \setlength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \addtolength{\leftmargin}{0.5\regDescSkip}
+ \addtolength{\rightmargin}{0.5\regDescSkip}
+ \setlength{\topsep}{0pt}
+ \setlength{\itemsep}{0pt}
+ \setlength{\parsep}{0.5\baselineskip}
+ \renewcommand{\makelabel}[1]{\regDescFamily ##1 \hfill}}}
+ {\end{list}}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\regdesc}
+% Next is the |\regdesc| environment. If \LyX{} is being used,
+% the environment temporarily redefines the |lyxlist| environment, which
+% is what \LyX{} provides as the default list structure. Otherwise,
+% the user is left to use |\reglist|. The redefinition should look very
+% similar to that for |\reglist|.
+%
+% In all cases, |\regdesc| starts by attempting to place a small
+% amount of vertical space between it and the presumed register
+% diagram immediately above it.
+% \end{macro}
+% \begin{macrocode}
+\newenvironment{regdesc}[1][0.90\textwidth]%
+% ---------------------------------------------
+{%
+ \setlength{\regDescSkip}{\textwidth - #1}%
+ \vspace{\regdescsep}%
+\ifthenelse{\boolean{RegisterLyX}}{%
+ \renewenvironment{lyxlist}[1]
+ {\begin{list}{}
+ {\settowidth{\labelwidth}{\regDescFamily ##1}
+ \addtolength{\labelwidth}{\labelsep}
+ \setlength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \addtolength{\leftmargin}{0.5\regDescSkip}
+ \addtolength{\rightmargin}{0.5\regDescSkip}
+ \setlength{\topsep}{0pt}
+ %\setlength{\partopsep}{0pt}
+ \renewcommand{\makelabel}[1]{\regDescFamily ####1 \hfill}}}
+ {\end{list}}}{}%
+ % endif
+ % set spacing appropriately
+ \leftskip 0.5\regDescSkip%
+ \rightskip 0.5\regDescSkip%
+ \parfillskip=\z@ plus 1fil%
+ \parskip=0.5\baselineskip \advance\parskip by 0pt plus 2pt%
+}% end begin{regdesc}
+% --------------------------------------------
+{\vskip\baselineskip}
+% \end{macrocode}
+%
+% \begin{macro}{\regnewline}
+% This command allows a register diagram to be broken into multiple lines
+% \end{macro}
+% \begin{macrocode}
+\newcommand{\regnewline}{\\*}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\register}
+% This environment declares the floating environment in which a
+% register diagram and, optionally, its field descriptions can be
+% typeset. It takes as arguments the float type (h, t, p, H); the
+% register name; and the register offset/address.
+% \end{macro}
+% \begin{macrocode}
+\newenvironment{register}[3]
+{\begin{Regfloat}[#1]%
+ \setlength{\leftskip}{0pt}%
+ \setlength{\oldregdescsep}{\regdescsep}%
+ \setlength{\regdescsep}{0.5\baselineskip}%
+ \setlength{\partopsep}{0pt}%
+ \setlength{\topsep}{0pt}%
+ \setboolean{RegisterContext}{true}%
+ \ifthenelse{\equal{#3}{}}%
+ {\caption[#2]{\textsc{#2}}}% else
+ {\caption[#2]{\textsc{#2} ({#3})}}%
+ \centering}
+{% restore lengths
+ \leftskip\z@%
+ \rightskip\z@%
+ \parfillskip=\z@ plus 1fil%
+ \setlength{\regdescsep}{\oldregdescsep}%
+ \setboolean{RegisterContext}{false}%
+ \end{Regfloat}}
+% \end{macrocode}
+%
+% \begin{macro}{\register*}
+% This register* environment provides for an unnumbered or ``captionless'' register;
+% registers in such an environment are not added to the list of registers.
+% \end{macro}
+% \begin{macrocode}
+\newenvironment{register*}[3]
+{\begin{Regfloat}[#1]%
+ \setlength{\leftskip}{0pt}%
+ \setlength{\oldregdescsep}{\regdescsep}%
+ \setlength{\regdescsep}{0.5\baselineskip}%
+ \setlength{\partopsep}{0pt}%
+ \setlength{\topsep}{0pt}%
+ \setboolean{RegisterContext}{true}%
+ \ifthenelse{\equal{#3}{}}%
+ {\centering\textsc{#2}\\}% else
+ {\centering\textsc{#2} ({#3})\\}%
+ \centering}
+{% restore lengths
+ \leftskip\z@%
+ \rightskip\z@%
+ \parfillskip=\z@ plus 1fil%
+ \setlength{\regdescsep}{\oldregdescsep}%
+ \setboolean{RegisterContext}{false}%
+ \end{Regfloat}}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\regUnderScore}
+% \begin{macro}{\regFiller}
+% \begin{macro}{\regSpread}
+% The next definitions provide a method of spreading out
+% an argument, i.e., placing |\hfill|'s between each character.
+% They can be used to space the reset value of a register field
+% appropriately. Previous versions of these macros used \TeX{}'s
+% conditionals incorrectly.
+%
+% If you are using the |underscore| package, you should
+% \emph{repeat} the definition of |\regUnderScore|, after loading
+% |underscore| in order to observe the changes made by that package.
+% The spreading macros below strive to strip out underscores.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+\def\regUnderScore{_}%
+\def\regFiller#1{\def\regInner{#1}%
+\ifx\regInner\regUnderScore%
+\else%
+\ifnum\count0>0%
+\hfill#1%
+\else#1\fi%
+\fi%
+\advance\count0 by 1%
+}
+\def\regSpread#1{\count0=0{}\regSpreadaux#1\empty}
+\def\regSpreadaux#1#2\empty{\def\aux{#1}%\show#1%
+\ifx\aux\empty%
+\else%
+\def\aux{#2}%
+\regFiller{#1}%
+\ifx\aux\empty%
+\else%
+\regSpreadaux#2\empty%
+\fi\fi}
+% \end{macrocode}
+%
+%
+% \subsubsection{Register fields} \label{sec:reg_fields}
+%
+% Define some internal utility macros which get called repeatedly.
+% These macros figure out some of the dimensions of the current font
+% (is there a better way to do this?), construct and rotate label
+% boxes, and typeset bit positions.
+% \begin{macrocode}
+\newcommand{\setRegLengths}{%
+ % Compute basic width of a single bit
+ \settowidth{\regFieldLen}{\regLabelSize \regResetName}%
+ \setlength{\regFieldLen}{\regWidth - \regFieldLen}%
+ \setlength{\regFieldLen}{\regFieldLen / \regBitWidth}%
+ % Figure out height and depth of reset field in current font
+ % Is there a more ``official'' method to do this?
+ \settodepth{\regResetDepth}{\regResetSize ()jgpq}%
+ \settoheight{\regResetHeight}{\regResetSize ()ABCjkl}%
+ \addtolength{\regResetHeight}{\regResetDepth}%
+ % Compute how far to drop the reset fields down. The value at
+ % the end is effectively the separation between the bit position
+ % box and the reset value box.
+ \setlength{\regResetDrop}{\regResetHeight + 2\fboxsep - 2\fboxrule + 3pt}%
+ % New lengths to support colorbox use, when fboxsep gets set to 0
+ \setlength{\regRsvdDrop}{\regResetDrop + \fboxsep}%
+ \setlength{\regRsvdHeight}{\regResetHeight + 2\fboxsep}%
+ \setlength{\regFboxSep}{\fboxsep}%
+}
+% \end{macrocode}
+% These macros assembly, rotate, and typset the register field name.
+% It is the use of |\rotatebox| below which makes |register| require
+% PostScript processing.
+% \begin{macrocode}
+\newcommand{\regMakeFieldName}[1]{%
+ % Create box to hold label
+ \savebox{\Label}{\regLabelSize\regLabelFamily #1}%
+}
+\newcommand{\regRotateFieldName}{%
+ \savebox{\RotatedLabel}{\rotatebox[origin=lB]{45}{\usebox{\Label}}}%
+ \makebox[0pt][l]{\raisebox{\regResetHeight + \fboxsep + \depth + 1pt}%
+ {\hspace{\regLabelAdjust}\usebox{\RotatedLabel}}}%
+}
+% \end{macrocode}
+% The |\typesetRegBits| macro constructs the frame for a particular
+% register field and sets the starting and ending bit positions
+% within that frame.
+% \begin{macrocode}
+\newcommand{\typesetRegBits}[1]{%
+ \ifthenelse{#1 > 1}%
+ {\framebox[\regFieldLen][c]%
+ {\regBitSize \rule[-1\regResetDepth]{0pt}{\regResetHeight}%
+ \regBitFamily\arabic{upperbit} \hfill \arabic{lowerbit}}}%
+ {\framebox[\regFieldLen][c]%
+ {\regBitSize \rule[-1\regResetDepth]{0pt}{\regResetHeight}%
+ \regBitFamily\arabic{lowerbit}}}%
+}
+% \end{macrocode}
+% This macro constructs a frame, below the bit position frame,
+% displaying the reset (or some other) value for a register field.
+% \begin{macrocode}
+\newcommand{\typesetRegReset}[1]{%
+ % Typeset reset value in a framebox
+ \makebox[0pt][l]{\raisebox{-1\regResetDrop}{\framebox[\regFieldLen][c]%
+ % Place an invisible rule to control the box
+ % surrounding the reset field
+ {\regResetSize \rule[-1\regResetDepth]{0pt}{\regResetHeight}\regSpread{#1}}}}%
+}
+% \end{macrocode}
+%
+%
+%
+% \begin{macro}{\regfieldNoColor}
+% The macros below are the user interface to the register drawing
+% routines. The first of these, |\regfieldNoColor| takes four arguments:
+% the field name, field length (in bits), the starting bit number,
+% and the field's reset value. This is the version of the macro that
+% does not make any use of |\colorbox|.
+% \end{macro}
+% \begin{macrocode}
+\newcommand{\regfieldNoColor}[4]{%
+ % Compute overall field length
+ \setRegLengths%
+ \setlength{\regFieldLen}{#2\regFieldLen + \fboxrule}%
+ % Figure out bit positions
+ \setcounter{lowerbit}{#3}%
+ \setcounter{upperbit}{#3 + #2 - 1}%
+ \regMakeFieldName{#1}%
+ % Figure out how far over to place label, accounting for height
+ \setlength{\regLabelAdjust}{0.5\regFieldLen - 0.707107\ht\Label}%
+ % Now, rotate and type the label
+ \regRotateFieldName%
+ \typesetRegReset{#4}%
+ % Typeset bit positions in a framebox
+ \typesetRegBits{#2}%
+ \hspace{-1\fboxrule}%
+}
+% \end{macrocode}
+%
+%
+%
+% \begin{macro}{\regfieldbNoColor}
+% The |\regfieldbNoColor| macro can be used to construct a register diagram
+% without reset values. It's parameters are thus the same
+% as for |\regfieldNoColor| with the omission of reset value.
+% \end{macro}
+% \begin{macrocode}
+\newcommand{\regfieldbNoColor}[3]{%
+ % Compute overall field length
+ \setRegLengths%
+ \setlength{\regFieldLen}{#2\regFieldLen + \fboxrule}%
+ % Figure out bit positions
+ \setcounter{lowerbit}{#3}%
+ \setcounter{upperbit}{#3 + #2 - 1}%
+ % Create box to hold label
+ \regMakeFieldName{#1}%
+ % Figure out how far over to place label, accounting for height
+ \setlength{\regLabelAdjust}{0.5\regFieldLen - 0.707107\ht\Label}%
+ % Now, rotate and typeset the label
+ \regRotateFieldName%
+ % Typeset bit positions
+ \typesetRegBits{#2}%
+ \hspace{-1\fboxrule}%
+}
+% \end{macrocode}
+%
+% \begin{macro}{\typesetRegColorBits}
+% \begin{macro}{\typesetRegColorReset}
+% \begin{macro}{\regfieldColor}
+% \begin{macro}{\regfieldbColor}
+% Now, we define versions of the same macros that make use of |\colorbox|, taking
+% an additional argument that specifies the fill color to use.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+\ifthenelse{\boolean{RegisterColors}}{%
+\newcommand{\typesetRegColorBits}[2]{%
+ \ifthenelse{#2 > 1}%
+ {\setlength\fboxsep{0pt}%
+ \colorbox{#1}{%
+ \framebox[\regFieldLen][c]%
+ {\regBitSize \rule[-1\regResetDepth - \regFboxSep]{0pt}%
+ {\regResetHeight + 2\regFboxSep}%
+ \regBitFamily\hspace{\regFboxSep}%
+\arabic{upperbit} \hfill \arabic{lowerbit}%
+\hspace{\regFboxSep}}}}%
+ {\setlength\fboxsep{0pt}%
+ \colorbox{#1}{%
+ \framebox[\regFieldLen][c]%
+ {\regBitSize \rule[-1\regResetDepth - \regFboxSep]{0pt}%
+ {\regResetHeight + 2\regFboxSep}%
+ \regBitFamily\arabic{lowerbit}}}}%
+ \setlength\fboxsep{\regFboxSep}%
+}
+\newcommand{\typesetRegColorReset}[2]{%
+ % Typeset reset value in a framebox
+ \makebox[0pt][l]{\raisebox{-1\regRsvdDrop}{%
+ \setlength\fboxsep{0pt}%
+ \colorbox{#1}{\framebox[\regFieldLen][c]%
+ % Place an invisible rule to control the box surrounding the reset field
+ {\regResetSize \rule[-1\regResetDepth]{0pt}{\regRsvdHeight}%
+ \raisebox{\regFboxSep}{\makebox[\regFieldLen]%
+ {\hspace{\regFboxSep}\regSpread{#2}\hspace{\regFboxSep}}}}}%
+}}}
+\newcommand{\regfieldColor}[5]{%
+ % Compute overall field length
+ \setRegLengths%
+ \setlength{\regFieldLen}{#3\regFieldLen + \fboxrule}%
+ % Figure out bit positions
+ \setcounter{lowerbit}{#4}%
+ \setcounter{upperbit}{#4 + #3 - 1}%
+ \regMakeFieldName{#2}%
+ % Figure out how far over to place label, accounting for height
+ \setlength{\regLabelAdjust}{0.5\regFieldLen - 0.707107\ht\Label}%
+ % Now, rotate and type the label
+ \regRotateFieldName%
+ \typesetRegColorReset{#1}{#5}%
+ % Typeset bit positions in a framebox
+ \typesetRegColorBits{#1}{#3}%
+ \hspace{-1\fboxrule}%
+}
+\newcommand{\regfieldbColor}[4]{%
+ % Compute overall field length
+ \setRegLengths%
+ \setlength{\regFieldLen}{#3\regFieldLen + \fboxrule}%
+ % Figure out bit positions
+ \setcounter{lowerbit}{#4}%
+ \setcounter{upperbit}{#4 + #3 - 1}%
+ % Create box to hold label
+ \regMakeFieldName{#2}%
+ % Figure out how far over to place label, accounting for height
+ \setlength{\regLabelAdjust}{0.5\regFieldLen - 0.707107\ht\Label}%
+ % Now, rotate and typeset the label
+ \regRotateFieldName%
+ % Typeset bit positions
+ \typesetRegColorBits{#1}{#3}%
+ \hspace{-1\fboxrule}%
+}
+}{}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\regfield}
+% \begin{macro}{\regfieldb}
+% Next, provide definitions for the |\regfield| and |\regfieldb| macros that are
+% intended for direct use within the register diagrams. These commands just check
+% for the presence of a non-empty optional argument and, based upon that, decide
+% whether to invoke the Color or NoColor variants of the typesetting macros.
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+\ifthenelse{\boolean{RegisterColors}}{
+ \newcommand{\regfield}[5][]{%
+ \ifthenelse{\equal{#1}{}}{%
+ \regfieldNoColor{#2}{#3}{#4}{#5}}%
+ {\regfieldColor{#1}{#2}{#3}{#4}{#5}}}
+ \newcommand{\regfieldb}[4][]{%
+ \ifthenelse{\equal{#1}{}}{%
+ \regfieldbNoColor{#2}{#3}{#4}}%
+ {\regfieldbColor{#1}{#2}{#3}{#4}}}
+}{
+ \newcommand{\regfield}[5][]{%
+ \regfieldNoColor{#2}{#3}{#4}{#5}}%
+ \newcommand{\regfieldb}[4][]{%
+ \regfieldbNoColor{#2}{#3}{#4}}%
+}
+% \end{macrocode}
+%
+% \begin{macro}{\regbits}
+% The |\regbits| macro typesets a register field without
+% showing bit positions. As such, it only takes three
+% parameters: field name, field bit length, and field value.
+% \end{macro}
+% \begin{macrocode}
+\newcommand{\regbits}[3]{%
+ % Compute overall field length
+ \setRegLengths%
+ \setlength{\regFieldLen}{#2\regFieldLen + \fboxrule}%
+ % Figure out bit positions
+ \setcounter{lowerbit}{#3}%
+ \setcounter{upperbit}{#3 + #2 - 1}%
+ % Create box to hold label
+ \regMakeFieldName{#1}%
+ % Figure out how far over to place label, accounting for height
+ \setlength{\regLabelAdjust}{0.5\regFieldLen - 0.707107\ht\Label}%
+ % Now, rotate and typeset the label
+ \regRotateFieldName%
+ % Typeset field value
+ \framebox[\regFieldLen][c]%
+ {\tiny\regSpread{#3}}%
+ \hspace{-1\fboxrule}%
+}
+% \end{macrocode}
+%
+%
+%
+% \begin{macro}{\regspace}
+% \begin{macro}{\reglabel}
+% \begin{macro}{\reglabelb}
+% Finally, define some additional utility macros. An invisible box
+% with the same width as a specified number of bits is typeset by
+% |\regspace|. It takes as its sole parameter the desired
+% bitwidth. The |\reglabel| macro typesets the label for the reset
+% field in register diagrams. Finally, |\reglabelb| performs the
+% same function, but without any drop.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+\newcommand{\regspace}[1]{%
+ % Compute overall field length
+ \setRegLengths%
+ \setlength{\regFieldLen}{#1\regFieldLen + \fboxrule}%
+ \makebox[\regFieldLen]{}%
+}
+
+\newcommand{\reglabel}[1]{%
+ \settowidth{\regFieldLen}{\regLabelSize \regResetName}%
+ \setlength{\regResetDrop}{\regResetDrop + 0.5\fboxsep}%
+ $\,$\raisebox{-1\regResetDrop}{\makebox[\regFieldLen][l]%
+ {\regLabelSize\regBitFamily #1}}%
+}
+
+\newcommand{\reglabelb}[1]{%
+ \settowidth{\regFieldLen}{\regLabelSize \regResetName}%
+ $\,$\raisebox{-0.5\fboxsep}{\makebox[\regFieldLen][l]%
+ {\regLabelSize\regBitFamily #1}}%
+}
+% \end{macrocode}
+%
+%
+%
+% \subsubsection{Hyperref Interface} \label{sec:hyperref}
+%
+% This code helps with the hyperlinks to register floats
+% when producing linked PDF.
+% \begin{macrocode}
+\ifthenelse{\boolean{RegisterHyperref}}{%
+ % Define a counter for the hyperref package. Otherwise,
+ % the hyperlinks to registers don't work correctly
+ \@namedef{theHRegfloat}{\theRegfloat}
+
+ % Define a bookmark level for Regfloats (for hyperref package)
+ \def\toclevel@Regfloat{0}
+}{}
+% \end{macrocode}
+%
+%
+%
+%
+% \subsubsection{List of Registers} \label{sec:list}
+%
+% The code below redefines what the |float| package specifies
+% in order to provide a hook for changing the format of the
+% ToC line for registers.
+% \begin{macrocode}
+\newcommand{\listofregisters}{%
+ \@ifundefined{ext@Regfloat}{\float@error{Regfloat}}{%
+ \@ifundefined{chapter}{\def\@tempa{\section*}}%
+ {\def\@tempa{\chapter*}}%
+ \@tempa{\regListName\@mkboth{\uppercase{\regListName}}%
+ {\uppercase{\regListName}}}%
+ \addcontentsline{toc}{chapter}{\regListName}%
+ \@starttoc{\@nameuse{ext@Regfloat}}}}
+\newcommand\l@Regfloat{\@dottedtocline{1}{1.5em}{2.3em}}
+% \end{macrocode}
+%
+%
+%
+% The |\chapter| command, if present, is also redefined in order
+% to get identical chapter-related spacing in the list of registers
+% as appears in the LoF and LoT. Kjetil Oftedal provided a fix
+% wherein we test that @mainmatter is defined prior to using it.
+% \begin{macrocode}
+\@ifundefined{@mainmatter}{\newif\if@mainmatter \@mainmattertrue}{}
+\@ifundefined{chapter}{}
+{% Adjust chapter definition slightly for Regfloats
+\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
+ \if@mainmatter
+ \refstepcounter{chapter}%
+ \typeout{\@chapapp\space\thechapter.}%
+ \addcontentsline{toc}{chapter}%
+ {\protect\numberline{\thechapter}#1}%
+ \else
+ \addcontentsline{toc}{chapter}{#1}%
+ \fi
+ \else
+ \addcontentsline{toc}{chapter}{#1}%
+ \fi
+ \chaptermark{#1}%
+ \addtocontents{lof}{\protect\addvspace{10\p@}}%
+ \addtocontents{lot}{\protect\addvspace{10\p@}}%
+ \addtocontents{rdf}{\protect\addvspace{10\p@}}% --- Add space ---
+ \if@twocolumn
+ \@topnewpage[\@makechapterhead{#2}]%
+ \else
+ \@makechapterhead{#2}%
+ \@afterheading
+ \fi}
+}
+% \end{macrocode}
+%
+%
+%
+% \subsection{TR flag macros} \label{sec:TRflags}%
+%
+% Define a mechanism for including TR flags in register descriptions,
+% as well as possibly in the main body of the text. One cannot just
+% use |\marginpar|'s within a register description, since they are
+% typically part of a register float. \LaTeX{}'s |\marginpar| command is
+% \emph{also} considered a float, so they cannot be nested.
+%
+% So, we resort to using some lower level \LaTeX{}. This certainly
+% isn't the most elegant way to get the flags, but I think it will
+% work for the majority of cases.
+%
+% The |\TR{x}| command is intended to be placed at the start of
+% a register field description, so that the alignment is
+% obvious on the page. To also get decent alignment in
+% main body text, it is necessary to have a second definition.
+% So, we'll see these commands get redefined inside regdesc,
+% below.
+%
+% The TR flags also decide which page they are on by placing
+% labels and testing the resulting pagenumber. This enables
+% the flags to be placed in the outer margin in two-sided
+% documents.
+%
+% \begin{macro}{\TRfamily}
+% \begin{macro}{\TRwidth}
+% The font family used for the TR flags can be controlled via
+% |\TRfamily|. The width available for TR flags is controlled
+% by |\TRwidth|, which by default is set to |\marginparwidth|.
+% Setting the width may be important if you are using the
+% |TRboxed| package option.
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+% Define a pageref which will work with \isodd
+\newcommand\@GetTRSecondParam{}
+\long\def\@GetTRSecondParam#1#2#3\@nil{#2}
+\newcommand*{\GetTRPageRef}[1]{%
+ \expandafter\expandafter\expandafter\@GetTRSecondParam
+ \csname r@#1\endcsname
+ 0% dummy, if the reference is undefined
+ \@nil
+}
+
+\newcommand{\TRfamily}{\sffamily}
+\newcounter{T@peReleaseTag}
+\newlength{\TRwidth}
+\setlength{\TRwidth}{\marginparwidth}
+\newlength{\T@peReleaseDepth}
+
+% Internal command to form the actual TR margin note.
+\newcommand{\TRwriteout}[1]{%
+ \makebox[\TRwidth][c]{%
+ \raisebox{\T@peReleaseDepth}{%
+ \ifthenelse{\boolean{RegisterTRBoxed}}%
+ {\fbox{\TRfamily #1}}%
+ {\TRfamily #1}}}%
+}
+
+% Internal command to typeset a TR flag in the right margin
+\newcommand{\TRrightlabel}[1]{%
+ % Place a strut in order to set line depth
+ \mbox{}\strut\settodepth{\T@peReleaseDepth}{\strut}%
+ \vadjust{\hspace{\textwidth}\hspace{\marginparsep}%
+ \smash{\rlap{\TRwriteout{#1}}}}}
+
+% Internal command to typeset a TR flag in the left margin
+\ifthenelse{\boolean{@twoside}}{
+ % Two-sided document
+ \newcommand{\TRleftlabel}[1]{%
+ % Place a strut in order to set line depth
+ \mbox{}\strut\settodepth{\T@peReleaseDepth}{\strut}%
+ \vadjust{\smash{\llap{\TRwriteout{#1}}\kern\marginparsep}}}
+}{
+ % Otherwise, the command is the same as rightlabel
+ \newcommand{\TRleftlabel}[1]{%
+ \TRrightlabel{#1}}
+}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\TR}
+% Finally, the user-level command is simply |\TR|.
+% \end{macro}
+% \begin{macrocode}
+\ifthenelse{\boolean{RegisterTRFlags}}{
+\newcommand{\TR}[1]{%
+ \stepcounter{T@peReleaseTag}%
+ \label{TapeReleaseTag-\theT@peReleaseTag}%
+ \ifthenelse{\isodd{\GetTRPageRef{TapeReleaseTag-\theT@peReleaseTag}}}%
+ {\TRrightlabel{TR\hspace{1pt}#1}}%
+ {\TRleftlabel{TR\hspace{1pt}#1}}%
+}}
+{\newcommand{\TR}[1]{}}
+% \end{macrocode}
+%
+% \par
+% Enjoy! Happy documenting.
+%
+%
+% \Finale
+%
+\endinput
+
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+
+%%% Local Variables:
+%%% mode: LaTeX
+%%% End:
+
diff --git a/macros/latex/contrib/register/register.ins b/macros/latex/contrib/register/register.ins
new file mode 100644
index 0000000000..529742dbdb
--- /dev/null
+++ b/macros/latex/contrib/register/register.ins
@@ -0,0 +1,62 @@
+%%
+%% register.ins
+%%
+%% This program is provided under the terms of the
+%% LaTeX Project Public License distributed from CTAN
+%% archives in directory macros/latex/base/lppl.txt.
+%%
+%% This package consists of register.dtx, register.ins, reg_list.pl,
+%% and Reg_macro.pm, as well as the accompanying register.pdf and
+%% README documentation.
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% Author: Matthew Lovell (lovells@gmail.com)
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\batchfile{register.ins}
+\input docstrip
+\def\SimplePackage#1{\generateFile{#1.sty}{t}{\from{#1.dtx}{package}}}
+\preamble
+Hardware register diagrams with field descriptions.
+
+This package may be distributed and/or modified under the conditions
+of the LaTeX Project Public License, either version 1.3 of this
+license or (at your option) any later version. The latest version of
+this license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX version
+2006/05/20 or later.
+
+Author: Matthew Lovell (lovells@gmail.com)
+
+\endpreamble
+
+\Msg{*** Generating the LaTeX2e package file ***}
+\SimplePackage{register}
+
+\Msg{***********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* file into a directory searched by LaTeX. See the FAQ on}
+\Msg{* CTAN at /help/uk-tex-faq for more on this.}
+\Msg{*}
+\Msg{* \space\space register.sty}
+\Msg{*}
+\Msg{* To produce the documented source run the file ending with}
+\Msg{* `.dtx' through LaTeX.}
+\Msg{*}
+\Msg{* Happy TeXing}
+\Msg{***********************************************************}
+
+\endinput
+
+
+%%% Local Variables:
+%%% mode: LaTeX
+%%% End:
diff --git a/macros/latex/contrib/register/register.pdf b/macros/latex/contrib/register/register.pdf
new file mode 100644
index 0000000000..1a0ad7f95c
--- /dev/null
+++ b/macros/latex/contrib/register/register.pdf
Binary files differ