Skip to content

Commit

Permalink
new input filter : nibble_swap (#62)
Browse files Browse the repository at this point in the history
* input filters: add -Nibble-Swap filter

Simply exchanges upper and lower nibbles of each bytes.

This should only be a few opcodes per byte on most CPUs; probably faster
than a look-up table (e.g. like the bit-reverse filter).
  • Loading branch information
fenugrec authored May 9, 2023
1 parent 56818b9 commit 6fa2523
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 0 deletions.
4 changes: 4 additions & 0 deletions doc/etc/README.man
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,10 @@ minimum
The \f[I]minimum\fP filter may be used to insert the minimum data address
into the data.
.\" ---------- N ---------------------------------------------------------
.\" nibble swap
.TP 8n
\fB\-Nibble_Swap\fP
This filter may be used to swap upper and lower nibbles of each byte.
.\" ---------- O ---------------------------------------------------------
.TP 8n
offset
Expand Down
4 changes: 4 additions & 0 deletions doc/man1/srec_input.1
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,10 @@ The number of bytes defaults to 4.
The same as the \fB\-MINimum_Big_Endian\fP filter,
except the value will be written with the least significant byte first.
.\" ---------- N ---------------------------------------------------------
.\" nibble swap
.TP 8n
\fB\-Nibble_Swap\fP
This filter may be used to swap upper and lower nibbles of each byte.
.\" not
.TP 8n
\fB\-NOT\fP
Expand Down
1 change: 1 addition & 0 deletions srecord/arglex/tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ srecord::arglex_tool::arglex_tool(int argc, char **argv) :
{ "-MsBin", token_msbin, },
{ "-MULTiple", token_multiple, },
{ "-Needham_Hexadecimal", token_needham_hex, },
{ "-Nibble_Swap", token_nibble_swap, },
{ "-NOT", token_not, },
{ "-Not_AUGment", token_crc16_augment_not },
{ "-Not_CONSTant", token_constant_not, },
Expand Down
1 change: 1 addition & 0 deletions srecord/arglex/tool.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ class arglex_tool:
token_msbin,
token_multiple,
token_needham_hex,
token_nibble_swap,
token_not,
token_offset,
token_ohio_scientific,
Expand Down
6 changes: 6 additions & 0 deletions srecord/arglex/tool/input.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
#include <srecord/input/filter/message/fletcher16.h>
#include <srecord/input/filter/message/fletcher32.h>
#include <srecord/input/filter/message/gcrypt.h>
#include <srecord/input/filter/nibble_swap.h>
#include <srecord/input/filter/not.h>
#include <srecord/input/filter/offset.h>
#include <srecord/input/filter/or.h>
Expand Down Expand Up @@ -912,6 +913,11 @@ srecord::arglex_tool::get_input()
}
break;

case token_nibble_swap:
token_next();
ifp = input_filter_nibble_swap::create(ifp);
break;

case token_not:
token_next();
ifp = input_filter_not::create(ifp);
Expand Down
54 changes: 54 additions & 0 deletions srecord/input/filter/nibble_swap.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// Copyright (c) 2023 fenugrec
//
// srecord filter: exchanges upper and lower nibble of each byte,
// e.g. "0xA6" => "0x6A"
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

#include <srecord/input/filter/nibble_swap.h>
#include <srecord/record.h>


srecord::input_filter_nibble_swap::input_filter_nibble_swap(
const srecord::input::pointer &arg
) :
srecord::input_filter(arg)
{
}


srecord::input::pointer
srecord::input_filter_nibble_swap::create(const input::pointer &a_deeper)

{
return pointer(new srecord::input_filter_nibble_swap(a_deeper));
}


bool
srecord::input_filter_nibble_swap::read(srecord::record &record)
{
if (!srecord::input_filter::read(record))
return false;
if (record.get_type() == srecord::record::type_data)
{
for (size_t j = 0; j < record.get_length(); ++j) {
uint8_t tmp = record.get_data(j);
record.set_data(j, ((tmp & 0x0F) << 4) | ((tmp & 0xF0) >> 4));
}
}
return true;
}
84 changes: 84 additions & 0 deletions srecord/input/filter/nibble_swap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// Copyright (c) 2023 fenugrec
//
// srecord filter: exchanges upper and lower nibble of each byte,
// e.g. "0xA6" => "0x6A"
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

#ifndef SRECORD_INPUT_FILTER_NIBBLE_SWAP_H
#define SRECORD_INPUT_FILTER_NIBBLE_SWAP_H

#include <srecord/input/filter.h>

namespace srecord {

/**
* The srecord::input_filter_nibble_swap class is used to represent the
* input state of a filter which swaps upper/lower nibbles of each byte.
*/
class input_filter_nibble_swap:
public input_filter
{
public:
/**
* The destructor.
*/
~input_filter_nibble_swap() override = default;

private:
/**
* The constructor.
*
* @param deeper
* The deeper input to be used as a data source.
*/
input_filter_nibble_swap(const input::pointer &deeper);

public:
/**
* The create class method is used to create new dynamically
* allocated instances of this class.
*
* @param deeper
* The incoming data source to be filtered
*/
static pointer create(const input::pointer &deeper);

protected:
// See base class for documentation.
bool read(record &record) override;

public:
/**
* The default constructor.
*/
input_filter_nibble_swap() = delete;

/**
* The copy constructor.
*/
input_filter_nibble_swap(const input_filter_nibble_swap &) = delete;

/**
* The assignment operator.
*/
input_filter_nibble_swap &operator= \
(const input_filter_nibble_swap &) = delete;
};

};

#endif
1 change: 1 addition & 0 deletions srecord/srecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#include <srecord/input/filter/message/fletcher16.h>
#include <srecord/input/filter/message/fletcher32.h>
#include <srecord/input/filter/message/gcrypt.h>
#include <srecord/input/filter/nibble_swap.h>
#include <srecord/input/filter/not.h>
#include <srecord/input/filter/offset.h>
#include <srecord/input/filter/or.h>
Expand Down
48 changes: 48 additions & 0 deletions test/02/t0269a.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/sh
#
# srecord - manipulate eprom load files
# Copyright (C) 2023 fenugrec
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#

TEST_SUBJECT="nibble swap filter"
. test_prelude.sh

cat > test.in << 'fubar'
S00600004844521B
S1070000F08008552B
S5030001FB
fubar
if test $? -ne 0; then no_result; fi

cat > test.ok << 'fubar'
S00600004844521B
S10700000F0880550C
S5030001FB
fubar
if test $? -ne 0; then no_result; fi

srec_cat test.in -ns -o test.out
if test $? -ne 0; then fail; fi

diff test.ok test.out
if test $? -ne 0; then fail; fi

#
# The things tested here, worked.
# No other guarantees are made.
#
pass

0 comments on commit 6fa2523

Please sign in to comment.