VOGONS


First post, by jewesta

User metadata
Rank Newbie
Rank
Newbie

Hello everyone,

this is a follow-up to my question on how to dump the BIOS of Amstrad XTs.

I ended up using DEBUG to get the dump and now I have one single .bin file (16k). I'm on a Mac and I was looking for an easy way to split the .bin file into two separate Lo/Hi files. Terminal (bash script) came to mind. I'm not a wizard on the shell so I did extensive googling and trial-and-error. This is what I came up with:

#!/bin/bash

# Inspired by:
# https://www.unix.com/shell-programming-and-scripting/130940-split-file-into-chunks-low-high-byte.html

# Splits binary file into low and high. Usage:
# ./bios_split.sh lohi.bin
# Result: lohi_lo.bin lohi_hi.bin

# file name without the path
filename=$(basename -- "$1")
extension="${filename##*.}"
filename="${filename%.*}"

# create a to-ascii + to-binary pipeline and then add "cut -b 1-2" in the middle.
xxd -p -c 2 -u $1 | cut -b 1-2 | xxd -r -p > "${filename}""_lo.""${extension}"
# same as above but start at byte 1 (-s 0x1)
xxd -p -c 2 -u -s 0x1 $1 | cut -b 1-2 | xxd -r -p > "${filename}""_hi.""${extension}"

I could verify that my DEBUG dumps, split into hi/lo, matched some hi/lo dumps I found on the internet. So unless the person dumping these used the same faulty method, this should work.

Now I am looking for a piece of code that does the opposite. Obviously I don't need it in case of my Amstrad dumps because they are already in merged form. But I have a few 286 boards and I would like to create merged versions for these (for readability).

Again, I am not a bash expert. The best I could find was this method:

#!/bin/bash

# Merges low and high bios files into one file. Usage:
# bios_merge lo.bin hi.bin > lohi.bin

exec 3< $1
exec 4< $2

while IFS= read -n 1 -sru 3 Hi
do
IFS= read -n 1 -sru 4 Lo || break
[ ${#Hi} -eq 0 ] && printf "\x0" || printf "%s" "$Hi"
[ ${#Lo} -eq 0 ] && printf "\x0" || printf "%s" "$Lo"
done

exec 3>&-
exec 4>&-

This sort of works and the merged file looks OK at first in a hex editor. But I found that if I compare my original dump to the recombined dump created using this method, the hashes don't match. So there must be something going wrong. I've attached four files: An original DEBUG dump. The hi/lo versions created with the split script in this post. And the recombined version created with the merge script in this post. Both complete dumps look like they are the same, but they are not.

Could someone pleas help me with this?

Thanks

Jens

Attachments

  • Filename
    dumps.zip
    File size
    36.2 KiB
    Downloads
    37 downloads
    File comment
    Amstrad 1512 BIOS files
    File license
    Fair use/fair dealing exception

Reply 1 of 2, by weedeewee

User metadata
Rank l33t
Rank
l33t

probably someone more knowledgeable about macs will chime in...
my crazy idea would be to try romwalk romwak in a dosbox. (dosbox exists for mac right ? )

edit: looking at your dump. the difference is that some bytes which are 00h in the recombined file are 0Ah in the debug file... while the rest is identical. weird
edit2 : 0Ah is LineFeed. something in your script is messing that character up and outputting a 00h for it in stead.
edit3: romwak ffs

Right to repair is fundamental. You own it, you're allowed to fix it.
How To Ask Questions The Smart Way
Do not ask Why !
https://www.vogonswiki.com/index.php/Serial_port

Reply 2 of 2, by jakethompson1

User metadata
Rank Oldbie
Rank
Oldbie

I would just do a C program, like this. You can probably get a shell to work on binary characters like that but to me it'd be an exercise in frustration.

#include <stdio.h>

int main(int argc, char *argv[])
{
FILE *fLow, *fHigh, *fOut;
int c;

if (argc != 4)
{
fputs("usage: merge low.bin high.bin out.bin\n", stderr);
return -1;
}
fLow = fopen(argv[1], "rb");
if (!fLow)
{
perror(argv[1]);
return -1;
}
fHigh = fopen(argv[2], "rb");
if (!fHigh)
{
perror(argv[2]);
return -1;
}
fOut = fopen(argv[3], "rb");
if (fOut)
{
fprintf(stderr, "%s already exists!\n", argv[3]);
return -1;
}
fOut = fopen(argv[3], "wb");
if (!fOut)
{
perror(argv[3]);
return -1;
}

while ((c = getc(fLow)) != EOF)
{
putc(c, fOut);
c = getc(fHigh);
if (c == EOF)
break;
putc(c, fOut);
}
fclose(fLow);
fclose(fHigh);
fclose(fOut);
return 0;
}