Fluke 9010a checksum algoirthm

brzezicki

Well-known member
Joined
Nov 6, 2006
Messages
4,536
Reaction score
485
Location
Maryland
I wanted to make a custom tool for myself to do a bunch of things on ROMs including computing the Fluke 9010a signature.

I have been suing KI4SWY's ROM ident page which is awesome, but I wanted to make a tool on my ROM burning machine (which often doesn't have internet access) that could do a bunch of things and needed the fluke algorithm which I could not find ANYWHERE.

I found a post to 2000 which suggested it's simply an XOR across each byte, which it's not (though it does mainly use xors, but not just XORing every byte)

I know KI4SWY must have figured it out, so I emailed him, he kindly pointed me to calcsign and a .net decompiler and suggested it decompile/reverse engineer it, so I did.

anyway I think it's dangerous that this really useful tool (fluke 9010a) not have any documented how it performs the checksum... so here you go.

http://www.paladingrp.com/brianb/fluke_9010a/checksum.txt

it's in perl the main function is doChecksum which takes a perl scalar which should be the string of the ROM to be checksumed, that's the algorithm, the entire program itself is mainly just a perl rewrite of calcsig by the quarterarcade folks, which when ran scans a directory and performs the algorithm on each file in the directory.

anyway I hope this might help someone else in the future and ensure the algorithm stays documented so if anything ever happens to the quarterarcade people or KI4SWY, then the algorithm won't be lost. I know the fluke people have not supported the 9010a for probably 20+ years.

-brian
 
u for sharing this.


Any chance you could outline the algorithm in either pseudocode or plain English? I've even done some programming in Perl and I can't quite follow what's going on there :)
 
u for sharing this.

Any chance you could outline the algorithm in either pseudocode or plain English? I've even done some programming in Perl and I can't quite follow what's going on there :)

sure I will put some more comments in there in the next couple days. I plan to integrate it with a python module that I used for all kinds of things with mame rom zips. but I haven't done much programming besides C in a year and I forgot much of the python syntax so I just wrote it up in perl as I mostly remember PERL syntax just to see if I had it right.

as far as the algorithm goes. I'm not entirely sure why they are doing what they are doing. best I could come up with is that they were just tring to obfuscate the algorithm. (not sure why they didn't use a more "standard" chksum and came up with their own. I have to look at the math to see if I'm missing something obvious but I really have no idea why they choose to do what they did.

-brian
 
Could've been done because of a limitation in memory or system architecture.
 
Could also do with knowing how the sig is calculated for the 68000 pod too if anyone has any ideas then I can update my program too
 
Could also do with knowing how the sig is calculated for the 68000 pod too if anyone has any ideas then I can update my program too

You mean its different for the 68000??? This may answer one of my longest running issues with the Fluke, that I can read from any number of address locations and always get a 100% match with the binary, but the checksum for the entire ROM block always fails.
 
Its certainly different for me and I've tried this across 3 units.
May be something simple like only using one byte from each word but I've no idea really.
 
oh I didn't know it was different than it is for the 68000. weird. possibly because the 68000 is a 16 bit processor, there's a good chance with the math there's some type of overflow that's not being accounted for or maybe there's an endian-ness issue since it is it's 16 bits and it's big endian, where PCs are little endian. actually I'd bet that's exactly it I will have to look into that, since your running the computation on a PC the math will be wrong. also probably would have to skip a byte after each read since your reading 16 bits at a time arther than 8 bits and you don't wnat to read each type twice in overlap the code I use reads only 1 byte at a time, so right there that will be off.

-brian
 
Last edited:
oh I didn't know it was different than it is for the 68000. weird. possibly because the 68000 is a 16 bit processor, there's a good chance with the math there's some type of overflow that's not being accounted for or maybe there's an endian-ness issue since it is it's 16 bits and it's big endian, where PCs are little endian. actually I'd bet that's exactly it I will have to look into that, since your running the computation on a PC the math will be wrong. also probably would have to skip a byte after each read since your reading 16 bits at a time arther than 8 bits and you don't wnat to read each type twice in overlap the code I use reads only 1 byte at a time, so right there that will be off.

-brian

good thinking. ill try byte swapping and seeing if that makes any difference
 
I've been following this with some interest. It's really great that you figured this out.

It took me a dozen or so reads through your code to understand what was going on, but I've got a pretty decent handle on it now. I have a serious case of PTSD (Perl-Traumatic Stress Disorder), so I ported it to Python, using idioms I'm comfortable with in that language. I added some comments explaining what it's doing to generate the checksum and generally made it work like what I think a well-behaved UNIX program should be. As with a lot of my side projects, the code is freely available on GitHub: https://github.com/ieure/flukesig

Brian, during this process, I found a significant performance bug in your implementation. The code to calculate $sig on lines 52-59 is inside the loop over $data, causing it to execute once for every byte of input. Moving it outside that loop improves performance by around 27x and produces identical output.

Whatever code you choose to run, Brian deserves immense credit for reverse engineering this. Thank you again.
 
Have tried a couple of variations with the merged ROMs on calcsig to no avail.

Very interested to see how it pans out, I guess the 68K pod is the only 16 bit pod in general use these days. The guy I found who supplies old test gear in Oz says the only time he can shift 9010 stuff is to arcade or pinball hobbyists so perhaps the issue was never much of an issue as the 8 bit pod sigs worked fine.

Sonewhat intrigued as to how the sigs were intended to be calculated back in the day. They cant always have assumed the repairer would have a working board to get the sigs from. Surely repairers are more likely to have had only a bad board to fix, and access to an EPROM reader. Yet it seems there was no official Fluke calcsig program so I don't know, it would have been a lot more useful if there was an official DOS app to build the sigs with, an odd omission as it would have been an easy thing for them to provide.
 
Last edited:
ieure; said:
I've been following this with some interest. It's really great that you figured this out.

It took me a dozen or so reads through your code to understand what was going on, but I've got a pretty decent handle on it now. I have a serious case of PTSD (Perl-Traumatic Stress Disorder), so I ported it to Python,

hah, that's great. I intended to port it to python as I started using python exclusively for scripting about 2 years ago, but then haven't done really any scripting in the last year so forgot most of the syntactic details and string operators of python, so kicked back to my perl since even though I haven't used it in probably 3 years. I've used it most of my adult life and I could get the code working easier that way.


ieure; said:
Brian, during this process, I found a significant performance bug in your implementation. The code to calculate $sig on lines 52-59 is inside the loop over $data, causing it to execute once for every byte of input. Moving it outside that loop improves performance by around 27x and produces identical output.

great, thanks for the info. I will update that in my code. I thought things seemed pretty slow. thats a great find.

ieure; said:
Whatever code you choose to run, Brian deserves immense credit for reverse engineering this. Thank you again.

thanks for the props. but I didn't really do much honestly, I just used a .net de-compiler that KI4SWY recommended that pretty much shot out c-sharp code then cleaned it up a bit and took care of the side effects that c-like languages can get away with in regards to overflow of data types and put in equivalent statements to make them happen with scripted languages such as perl. Now hopefully we can get that 68000 oddity figured out to complete the work :)
 
I found a post to 2000 which suggested it's simply an XOR across each byte, which it's not (though it does mainly use xors, but not just XORing every byte)

According to the glossary entry for Signature in the 9010A Operator Manual it says..."The ROM signature is obtained by successively dividing the data in ROM by a binary number", might be an over simplification, or could be just plain wrong.
 
Last edited:
hah, that's great. I intended to port it to python as I started using python exclusively for scripting about 2 years ago, but then haven't done really any scripting in the last year so forgot most of the syntactic details and string operators of python, so kicked back to my perl since even though I haven't used it in probably 3 years. I've used it most of my adult life and I could get the code working easier that way.

Yeah, for sure. Whatever it takes to get the job done.

Now hopefully we can get that 68000 oddity figured out to complete the work :)

I don't have access to any of this hardware at all. If someone can send me a file and its correct checksum, though, I can see if I can figure it out. To placate the Mod Gods, I am not asking for a ROM. Any arbitrary file is fine, I just need whatever the correct checksum out of the 9010a would be to go along with it.


According to the glossary entry for Signature in the 9010A Operator Manual it says..."The ROM signature is obtained by successively dividing the data in ROM by a binary number", might be an over simplification, or could be just plain wrong.

Basically wrong. I guess you could call it a gross oversimplification of one step of a multi-part process if you were feeling generous. I added some explanatory comments in my version which I think explain what is going on at a high level, but if there's something that I can clarify, I'd be happy to.
 
I updated my tool with a couple options. It can checksum files inside ZIP archives now, which is extremely convenient when dealing with MAME ROM sets (there's an option to disable it, if you like), and an option to control whether it prints the full path of the files being checksummed or just the bare filename.

Code is in the same place: https://github.com/ieure/flukesig/blob/master/flukesig.py
 
I don't have access to any of this hardware at all. If someone can send me a file and its correct checksum, though, I can see if I can figure it out. To placate the Mod Gods, I am not asking for a ROM. Any arbitrary file is fine, I just need whatever the correct checksum out of the 9010a would be to go along with it.

The merged.bin file attached has a sig of 19F5 when read from the board via a 68000 pod. It is a byte interleave output of two files for the board, I have stepped through a few ROM locations throughout the file and verified the board reads the hi/lo bytes as expected.

The board is known working and the Fluke can run the game via "Run UUT" so am confident it is a valid sig.

I had a look through the code and most of it went over my head I'm afraid, the last thing I programmed in anger was a ZX Spectrum in the very late 80s :)
 

Attachments

  • merged.zip
    56.7 KB · Views: 18
Last edited:
ieure said:
Brian, during this process, I found a significant performance bug in your implementation. The code to calculate $sig on lines 52-59 is inside the loop over $data, causing it to execute once for every byte of input. Moving it outside that loop improves performance by around 27x and produces identical output.

Wow, just changed the code, and huge difference in speed! Thanks for pointing that out.
 
Wow, just changed the code, and huge difference in speed! Thanks for pointing that out.

No problem. It definitely makes a big difference.

The merged.bin file attached has a sig of 19F5 when read from the board via a 68000 pod. It is a byte interleave output of two files for the board, I have stepped through a few ROM locations throughout the file and verified the board reads the hi/lo bytes as expected.

The board is known working and the Fluke can run the game via "Run UUT" so am confident it is a valid sig.

I had a look through the code and most of it went over my head I'm afraid, the last thing I programmed in anger was a ZX Spectrum in the very late 80s :)

Hmm, I poked around with this a bit, and I can't get a correct result. Do you think it would be possible to checksum some specific values? If you write these values into memory somewhere:

0x01 0x02 0x04 0x08

Can you report back the signature for both all four bytes AND the first two bytes only?

If this is just a byte ordering issue, this should clear things up. Worst case, it should indicate whether that is the difference or not.
 
This might just be a crazy thought, but isn't it possible that the algorithm might be in the FLUKES ROM somewhere. Can't remember precisely what CPU it uses internally, but I'm pretty sure it's an Z80. So in theory one could disassemble the code and look for the checksum algorithm?!
 
This might just be a crazy thought, but isn't it possible that the algorithm might be in the FLUKES ROM somewhere. Can't remember precisely what CPU it uses internally, but I'm pretty sure it's an Z80. So in theory one could disassemble the code and look for the checksum algorithm?!

Oh yeah, definitely. I already grabbed a copy of the ROMs with the intention of doing this. It's just that if it is a simple issue, it's a lot easier to take code that is 95% working and fix that than reverse engineer 30 year old ROMs.

So I'll dig around in them if I have to, but I'm pretty rusty on that kind of thing. Haven't gone down that road since I cracked PalmPiot apps in the late 1990s.
 
Back
Top Bottom