Post Reply 
Hand Held Products 71M/M eprom carrier question
09-08-2020, 05:32 PM
Post: #21
RE: Hand Held Products 71M/M eprom carrier question
Richard: I used this program to convert a ROM dump into an intel hex file suitable for burning an EPROM. It is a one-off thing and has no error checking; it hasn't been cleaned up either, but it did the job for me.

/* dmp2hex.c : convert a nibble dump from the HP-71B DUMPROM BASIC program
into an intel HEX format file. Syntax is
$ dmp2hex infile.dmp > outfile.hex

The output is appropriate to burn an EPROM for the
Hand Held Products 71M/M EPROM carrier for the card reader slot.

A rom dump is just the nibbles in the Saturn cpu memory map
in order of increasing address (as returned by PEEK$), in the
form of a text file with 64 characters per line, each character
the ASCII hex digit {0-9, A-F} for each nibble.
But the data in the EPROM differs from this in that the most
significant nibble in each byte is the higher-addressed nible
in the memory map, and also in that the data is negated in the
ROM. Thus, a 16 nibble sequence in a ROM such as

B3DDDDDEE4642513

must be coded in the EPROM like these eight consecutive bytes

C4 22 22 12 B1 B9 AD CE DF

That is, C is the 1-complement of 3, 4 is the 1-complement of B,
2 is the 1-complement of the fourth nibble in the sequence (a D)
and so on.

Carlos E. Murillo-Sanchez 2020-06-15. Just a quick hack
without much error checking.

Version 1.0
*/

#include <stdio.h>
#include <string.h>


unsigned char hex2nibble(unsigned char a)
{ unsigned char b;
if (a >= 48 & a <= 57) {
b = a - 48;
}
else if ( a >= 65 & a <= 70) {
b = a - 55;
}
else if ( a>= 97 & a <= 102 ) {
b = a - 87;
}
else {
fprintf(stderr, "Invalid ASCII character representation of hex value %s\n", a);
}
return b;
}

unsigned char nibble2hex(unsigned char a)
{ unsigned char b;
b = a & 0x0F;
if (b < 10) {
b = b + 0x30;
}
else
{
b = b + 55;
}
return b;
}

int
main (argc, argv, envp)
int argc;
char **argv;
char **envp;
{
char *ifile;
char *program;
FILE *fp;
unsigned char linein[66];
unsigned char nibbles[64];
unsigned char bytes[16];
unsigned char hexnibbles[64];
unsigned char hexbytes[64];
unsigned char tmpchar1, tmpchar2, tmpchar3, tmpchar4;
int lines, i, j, k;

program = strrchr (argv[0], '/');
if (argc < 2) {
printf("\nUsage: %s inputfile.dmp > outputfile.hex\n\n", program);
return 0;
}

fp = fopen(argv[1], "r");
if (fp == 0) {
printf("%s: Could not open %s file for input.\n", program, argv[1]);
return 1;
}

/*count the lines*/
lines = 0;
while (fscanf(fp, "%s", linein) == 1) {
if (strlen(linein) > 0) {
lines++;
}
}
fclose(fp);

/* do actual processing */
fp = fopen(argv[1], "r");

/* First write header of hex file */
printf(":020000040000FA\n");

/* Then write data */
k = 0;
while (fscanf(fp, "%s", linein) == 1) {
/* Convert string of ascii hex values of nibbles into bytes */
for (i=0; i<64; i++) {
nibbles[i] = hex2nibble(linein[i]);
}

/* swap and complement every two nibbles */
for (i=0; i<32; i++) {
tmpchar1 = nibbles[2*i];
tmpchar2 = nibbles[2*i+1];
tmpchar1 = (~tmpchar1) & 0x0F;
tmpchar2 = (~tmpchar2) & 0x0F;
nibbles[2*i] = tmpchar2;
nibbles[2*i+1] = tmpchar1;
}

/* Convert to string of hex values */
for (i=0; i<64; i++) {
hexbytes[i] = nibble2hex(nibbles[i]);
}
/* Output two lines of intel hex file format */
for (i=0; i<2; i++) {
printf(":10");
tmpchar1 = (unsigned char) ((16*k) & 0xFF);
tmpchar1 = tmpchar1 + (unsigned char) ( k / 16);
tmpchar1 = tmpchar1 + 16;
tmpchar2 = (unsigned char) ( k / 16 );
tmpchar3 = nibble2hex(tmpchar2 >> 4);
tmpchar4 = nibble2hex(tmpchar2);
printf("%c%c", tmpchar3, tmpchar4);
tmpchar2 = (unsigned char) ((16*k) & 0xFF);
tmpchar3 = nibble2hex(tmpchar2 >> 4);
tmpchar4 = nibble2hex(tmpchar2);
printf("%c%c", tmpchar3, tmpchar4);
printf("00");

for (j=0; j<16; j++) {
printf("%c%c", hexbytes[32*i+2*j], hexbytes[32*i+2*j+1]);
tmpchar2 = 16*nibbles[32*i+2*j] + nibbles[32*i+2*j+1];
tmpchar1 = tmpchar1 + tmpchar2;
}
tmpchar1 = ~tmpchar1 + 1;
tmpchar2 = tmpchar1 >> 4;
printf("%c%c\n", nibble2hex(tmpchar2), nibble2hex(tmpchar1));
k++;
}
}
printf(":00000001FF\n");
fclose(fp);
return 0;
}
Find all posts by this user
Quote this message in a reply
09-08-2020, 06:54 PM
Post: #22
RE: Hand Held Products 71M/M eprom carrier question
(09-08-2020 01:20 PM)coitboy2000 Wrote:  I thought there may have been an easier way on the PC and one that does not require the forth rom. Can the procedure be done using emu71 ?

Of course there is a simple way, using Emu71. And it's more fun and in the spirit of the HP-71B system :-)

The Intel hex format was commonly used at the time when the EPROM programmers were linked by RS232. Now, most modern programmers accept raw binary files (mine does), I guess this is what you are using too since you spoke about a .bin file coming from Emu71.

In that case, the nibbles are already in the right order in the .bin file, it is just needed to complement the bytes.

The following HP-71B/Emu71 program does it using the DOSLINK device (use ILPer with the HP-71B or Emu71/Win), it reads the input file bytes, complement them and write them back to the output file.
In Emu71/DOS, the DOSLINK input and output files are hardcoded as emu_in.dat and emu_out.dat so copy your source .bin file to emu_in.dat; in ILper you can choose the files.

Code:
10 ! 
20 ! uses COMP$ from STRBOOL or ULIB52 LEXs
30 DIM A$[256]
40 D=DEVADDR(":DOSLINK")
50 CLEAR :D
60 FOR I=1 TO 128
70 DISP I
80 ENTER :D USING "#,256A";A$
90 OUTPUT :D USING "#,256A";COMP$(A$)
100 NEXT I
110 CLEAR :D

If you don't have or don't want to load the STRBOOL or ULIB52 LEX, you can replace the COMP$ keyword with a loop to complement each byte of A$ with something like:
A$[J,J]=CHR$(255-NUM(A$[J,J])
But COMP$ is much faster.

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
09-08-2020, 10:17 PM
Post: #23
RE: Hand Held Products 71M/M eprom carrier question
Thanks everyone. That's 3 different ways to try. I will give them all a go Smile

I made myself an eprom burner using an arduino mega some voltage regulators and transistors and modified some code from the internet for the 27c256. I might try and incorporate the invert and bit flipping.

Cheers

Richard
Find all posts by this user
Quote this message in a reply
09-09-2020, 01:16 AM
Post: #24
RE: Hand Held Products 71M/M eprom carrier question
Wow, several very different options to choose from. Smile

Personally, I like JFG's solution best, because:

- It's 71-based
- It's short, clear and easy to use
- It uses the loop and :DOSLINK to read/update the file in place.

Elegant!

Thanks JFG.

p.s. Also because I can understand this solution; the other 2, not so much without huge amounts of time - not justified for a 1-off.

--Bob Prosperi
Find all posts by this user
Quote this message in a reply
09-09-2020, 03:56 AM
Post: #25
RE: Hand Held Products 71M/M eprom carrier question
(09-08-2020 05:32 PM)Albert Chan Wrote:  > echo 0:B3DDDDDEE4642513 | sed -f swap_flip.sed
0: C4 22 22 12 B1 B9 AD CE

Here is the equivalent Python code.
This work slightly better, and handled 'colon-less' format correctly.

> echo B3DDDDDEE4642513 | python swap_flip.py
C4 22 22 12 B1 B9 AD CE

Code:
import sys, string
flip = string.maketrans('0123456789ABCDEFabcdef','FEDCBA9876543210543210')

for line in sys.stdin:
    i, j = line.find(':'), line.find('  ')
    s = line[i+1:j].translate(flip, ' ')    # flipped hexdigits only
    print line[:i+1], ' '.join(s[i:i-2:-1] for i in range(1-len(s),0,2))
Find all posts by this user
Quote this message in a reply
09-09-2020, 12:12 PM
Post: #26
RE: Hand Held Products 71M/M eprom carrier question
Success!! Thanks everyone. The three methods all work, no surprises. The Sed script is almost "instant".

Richard


Attached File(s) Thumbnail(s)
   
Find all posts by this user
Quote this message in a reply
09-17-2020, 12:16 PM (This post was last modified: 09-19-2020 08:16 AM by coitboy2000.)
Post: #27
RE: Hand Held Products 71M/M eprom carrier question
For anyone einterested, after some experimentation the code below works for me.

Code:

using System;
using System.IO;

namespace ConsoleApp4
{
    class Program
    {
        const string fileName = @"C:\Users\user\Desktop\HP-71B\Eprom Image Files\math2b5.bin";
        const string fileName2 = @"C:\Users\user\Desktop\HP-71B\Eprom Image Files\eprom2.bin";
        static void Main(string[] args)
        {
            byte[] buff = File.ReadAllBytes(fileName);
            var len = (int)buff.Length;
            using (BinaryWriter writer = new BinaryWriter(File.Open(fileName2, FileMode.Create)))
            {
                for (int ix = 0; ix < len; ix ++)
                {   
                    buff[ix] = (byte)(~buff[ix]);
                    int value = buff[ix];
                    value = value ^ 1;
                }
                writer.Write(buff);
            }
        }
    }
}
Find all posts by this user
Quote this message in a reply
09-18-2020, 08:31 AM
Post: #28
RE: Hand Held Products 71M/M eprom carrier question
Would you mind sticking that in "code" tags so that the indentation isn't lost?

There are only 10 types of people in this world. Those who understand binary and those who don't.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)