Author Topic: Swapping bits in bytes in a file  (Read 1615 times)

0 Members and 1 Guest are viewing this topic.

Offline Alex EisenhutTopic starter

  • Super Contributor
  • ***
  • Posts: 3550
  • Country: ca
  • Place text here.
Swapping bits in bytes in a file
« on: January 11, 2020, 04:16:38 pm »
I am working on an old Commodore compatible floppy drive. The manufacturer swapped data bits around on the motherboard so that Commodore ROMs don't work directly.
Is there a utility or something that can read in a binary file, swap two bits around and output the swapped byte into a new file?
Worst case I guess I can do it in Excel if I can get ASCII hex data.
Hoarder of 8-bit Commodore relics and 1960s Tektronix 500-series stuff. Unconventional interior decorator.
 

Offline BrianHG

  • Super Contributor
  • ***
  • Posts: 8275
  • Country: ca
    • LinkedIn
Re: Swapping bits in bytes in a file
« Reply #1 on: January 11, 2020, 05:11:31 pm »
This editor has some pretty bit manipulation capabilities:

https://www.hhdsoftware.com/free-hex-editor

Though I see reverse bits and rotate left and right, cycling through a pattern of these 3 may allow you to achieve the correct bit swapping you require.
 

Offline NiHaoMike

  • Super Contributor
  • ***
  • Posts: 9321
  • Country: us
  • "Don't turn it on - Take it apart!"
    • Facebook Page
Re: Swapping bits in bytes in a file
« Reply #2 on: January 11, 2020, 05:45:21 pm »
It would be trivial to program in Python. Learn how to (make sure the guide you use is Python 3, since Python 2 is obsolete) and you'll wonder why you didn't start learning it earlier.
Cryptocurrency has taught me to love math and at the same time be baffled by it.

Cryptocurrency lesson 0: Altcoins and Bitcoin are not the same thing.
 
The following users thanked this post: WattsThat

Offline Benta

  • Super Contributor
  • ***
  • Posts: 6420
  • Country: de
Re: Swapping bits in bytes in a file
« Reply #3 on: January 11, 2020, 05:47:33 pm »
Wouldn't it be easier to swap the two lines to the ROM on the PCB? (cut 'n jumper).

 
The following users thanked this post: I wanted a rude username

Offline amyk

  • Super Contributor
  • ***
  • Posts: 8526
Re: Swapping bits in bytes in a file
« Reply #4 on: January 11, 2020, 08:48:21 pm »
It's around a dozen lines of C... if you specify how you want the bits to be swapped I can probably write it for you in a few minutes.
 

Online mariush

  • Super Contributor
  • ***
  • Posts: 5170
  • Country: ro
  • .
Re: Swapping bits in bytes in a file
« Reply #5 on: January 11, 2020, 10:24:31 pm »
Here's a php script that does it, just wrote it right now in the last 5 minutes :

Save code below in a folder with the .php extension (paste in notepad, save as and select "All Files" at file type, enter name with .php extension) then put the file you want modified in same folder as input.bin 
Download php from php.net and run  php.exe  c:\path\to\script.php  and it will produce

   $byte = flipbits($byte,0,7);

that line swaps bit 0 with bit 7 ... you can change the 0 and 7 with whatever you want. You can also have consecutive lines (ex swap 0,7 then swap 1,6 ... to have 2 pairs of bits swapped.

Code: [Select]
<?php

//  Opens input.bin , flips bits in every byte and saves to output.bin

function flipbits($value$first$second) {
$bits = array();
$bitstring str_pad(decbin($value),8,'0',STR_PAD_LEFT);
for ($i=0;$i<8;$i++) $bits[$i] = substr($bitstring,$i,1);
$temp $bits[$first];
$bits[$first] = $bits[$second];
$bits[$second] = $temp;
$bitstring '';
for ($i=0;$i<8;$i++) $bitstring .= $bits[$i];
return bindec($bitstring);
}

$input file_get_contents(__DIR__ .'/input.bin');
$h fopen(__DIR__ .'/output.bin','wb');

for (
$i=0;$i<strlen($input);$i++) {
$byte ord(substr($input,$i,1));
// call the function every time you need to flip a bits
// ex flip bit 0 with bit 7
$byte flipbits($byte,0,7);
// repeat as needed

fwrite($h,chr($byte));
}

fclose($h);
echo 
"Done. Saved to output.bin";

?>


 
The following users thanked this post: Alex Eisenhut

Offline Alex EisenhutTopic starter

  • Super Contributor
  • ***
  • Posts: 3550
  • Country: ca
  • Place text here.
Re: Swapping bits in bytes in a file
« Reply #6 on: January 12, 2020, 09:55:20 pm »
Thanks, I have studied the drive more closely and it came in at least two variants, one with 16K of ROM in one chip and the other split across two 8K chips.
I have the two chip version, and splitting the 16K ROM into two 8K images doesn't work.
 It turns out the data bits are scrambled differently across the ROMs in the two chip version.
I'll try that PHP thing soon.
Hoarder of 8-bit Commodore relics and 1960s Tektronix 500-series stuff. Unconventional interior decorator.
 

Offline Alex EisenhutTopic starter

  • Super Contributor
  • ***
  • Posts: 3550
  • Country: ca
  • Place text here.
Re: Swapping bits in bytes in a file
« Reply #7 on: January 12, 2020, 09:57:02 pm »
Wouldn't it be easier to swap the two lines to the ROM on the PCB? (cut 'n jumper).

It might get to that, the PCB actually has solder jumpers already there but I don't know what they do yet. They mixed up the data bits differently across the two ROMs.
Hoarder of 8-bit Commodore relics and 1960s Tektronix 500-series stuff. Unconventional interior decorator.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 7193
  • Country: fi
    • My home page and email address
Re: Swapping bits in bytes in a file
« Reply #8 on: January 12, 2020, 11:05:27 pm »
Here's a quick Python3 skeleton for bit mapping:
Code: [Select]
#!/usr/bin/env python3 -B
# -*- coding: utf-8 -*-
from sys import stdin, stdout, stderr, argv, exit

def bytefilter(source, output, mapping, chunk=2097152):
    while True:
        try:
            data = source.read(chunk)
        except BlockingIOError:
            return

        if len(data) < 1:
            return

        output.write(data.translate(mapping))

def bitremap(byte, form):
    result = 0
    for i in range(0, 8):
        dstbit = 7 - i
        srcbit = int(form[i])
        if (byte & (1 << srcbit)):
            result |= 1 << dstbit
    return result

if __name__ == '__main__':
    if len(argv) != 4:
        stderr.write("\n")
        stderr.write("Usage: %s INPUTFILE OUTPUTFILE BITPATTERN\n" % argv[0])
        stderr.write("\n")
        stderr.write("For no translation, use bitpattern 76543210.\n")
        stderr.write("\n")
        exit(1)

    if len(argv[3]) != 8 or len(argv[3].rstrip("01234567")) != 0:
        stderr.write("%s: Invalid bit pattern.\n" % argv[0])
        exit(1)

    mapping = b''
    for i in range(0, 256):
        mapping += b'%c' % bitremap(i, argv[3])

    try:
        source = open(argv[1], mode='rb')
    except FileNotFoundError:
        stderr.write("%s: No such file.\n" % argv[1])
        exit(1)

    output = open(argv[2], mode='wb')

    bytefilter(source, output, mapping)

Run it without parameters to see usage.  Simply put, it takes an input filename, and output filename, and the 8-digit bit pattern to use.
Normal bit pattern is 76543210.  If you wish to swap the second bit (bit 1) and fourth bit (bit 3), use 76541230.
Essentially, the third parameter tells how the bits in the input bytes are mapped to the output file bytes.

It does not stop you from doing silly things, like 77777701, which uses the highest bit in input bytes for all but the two lowest bits, and swaps those two lowest bits.

The way this Python program works, is by constructing a 256-byte lookup table.  The bitremap() function transforms one numeric value using the form string; it is called once for each possible byte value, to construct the lookup table.  The Python .translate() method does the lookup efficiently.
 
The following users thanked this post: edavid

Offline Alex EisenhutTopic starter

  • Super Contributor
  • ***
  • Posts: 3550
  • Country: ca
  • Place text here.
Re: Swapping bits in bytes in a file
« Reply #9 on: January 13, 2020, 11:57:01 pm »
Looks like I'm not the only one who came across this scrambling problem  :-DD

https://www.commodoreserver.com/PublicDiskDetails.asp?DID=DFF943F2D52D40EE8D73DD950E5F02EB

Someone wrote a scrambler program that runs on the 64... Hilarious.
Hoarder of 8-bit Commodore relics and 1960s Tektronix 500-series stuff. Unconventional interior decorator.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf