diff --git a/doc/etc/README.man b/doc/etc/README.man index d0600a16..a323039e 100644 --- a/doc/etc/README.man +++ b/doc/etc/README.man @@ -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 diff --git a/doc/man1/srec_input.1 b/doc/man1/srec_input.1 index 67510474..8a624560 100644 --- a/doc/man1/srec_input.1 +++ b/doc/man1/srec_input.1 @@ -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 diff --git a/srecord/arglex/tool.cc b/srecord/arglex/tool.cc index 3c4011ca..4f91ab25 100644 --- a/srecord/arglex/tool.cc +++ b/srecord/arglex/tool.cc @@ -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, }, diff --git a/srecord/arglex/tool.h b/srecord/arglex/tool.h index cacdd8c4..ec575beb 100644 --- a/srecord/arglex/tool.h +++ b/srecord/arglex/tool.h @@ -146,6 +146,7 @@ class arglex_tool: token_msbin, token_multiple, token_needham_hex, + token_nibble_swap, token_not, token_offset, token_ohio_scientific, diff --git a/srecord/arglex/tool/input.cc b/srecord/arglex/tool/input.cc index 7699a8e0..ef4ad153 100644 --- a/srecord/arglex/tool/input.cc +++ b/srecord/arglex/tool/input.cc @@ -83,6 +83,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/srecord/input/filter/nibble_swap.cc b/srecord/input/filter/nibble_swap.cc new file mode 100644 index 00000000..f471de1a --- /dev/null +++ b/srecord/input/filter/nibble_swap.cc @@ -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 . +// + +#include +#include + + +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; +} diff --git a/srecord/input/filter/nibble_swap.h b/srecord/input/filter/nibble_swap.h new file mode 100644 index 00000000..a4fc2433 --- /dev/null +++ b/srecord/input/filter/nibble_swap.h @@ -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 . +// + +#ifndef SRECORD_INPUT_FILTER_NIBBLE_SWAP_H +#define SRECORD_INPUT_FILTER_NIBBLE_SWAP_H + +#include + +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 diff --git a/srecord/srecord.h b/srecord/srecord.h index cb9722ce..29881fe9 100644 --- a/srecord/srecord.h +++ b/srecord/srecord.h @@ -84,6 +84,7 @@ #include #include #include +#include #include #include #include diff --git a/test/02/t0269a.sh b/test/02/t0269a.sh new file mode 100755 index 00000000..a01fe778 --- /dev/null +++ b/test/02/t0269a.sh @@ -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 +# . +# + +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