mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2024-11-29 11:51:14 +00:00
Initial recognition of 5200 carts by sha1 signature
This commit is contained in:
parent
9a638fa951
commit
d22f2cdf3f
@ -20,7 +20,7 @@ from .kboot import KBootImage, add_xexboot_header
|
||||
from .segments import SegmentData, SegmentSaver, DefaultSegment, EmptySegment, ObjSegment, RawSectorsSegment, SegmentedFileSegment, user_bit_mask, match_bit_mask, comment_bit_mask, data_style, selected_bit_mask, diff_bit_mask, not_user_bit_mask, interleave_segments, SegmentList, get_style_mask, get_style_bits
|
||||
from .spartados import SpartaDosDiskImage
|
||||
from .cartridge import A8CartHeader, AtariCartImage, RomImage
|
||||
from .parsers import SegmentParser, DefaultSegmentParser, guess_parser_for_mime, guess_parser_for_system, guess_container, iter_parsers, iter_known_segment_parsers, mime_parse_order, parsers_for_filename
|
||||
from .parsers import SegmentParser, DefaultSegmentParser, guess_parser_by_size, guess_parser_for_mime, guess_parser_for_system, guess_container, iter_parsers, iter_known_segment_parsers, mime_parse_order, parsers_for_filename
|
||||
from .magic import guess_detail_for_mime
|
||||
from .utils import to_numpy, text_to_int
|
||||
from .dummy import LocalFilesystem
|
||||
@ -67,18 +67,20 @@ def find_diskimage(filename, verbose=False):
|
||||
if container is not None:
|
||||
data = container.unpacked
|
||||
rawdata = SegmentData(data)
|
||||
for mime in mime_parse_order:
|
||||
if verbose:
|
||||
print("Trying MIME type %s" % mime)
|
||||
parser = guess_parser_for_mime(mime, rawdata, verbose)
|
||||
if parser is None:
|
||||
continue
|
||||
if verbose:
|
||||
print("Found parser %s" % parser.menu_name)
|
||||
mime2 = guess_detail_for_mime(mime, rawdata, parser)
|
||||
if mime != mime2 and verbose:
|
||||
print("Signature match: %s" % mime2)
|
||||
break
|
||||
mime, parser = guess_parser_by_size(rawdata)
|
||||
if parser is None:
|
||||
for mime in mime_parse_order:
|
||||
if verbose:
|
||||
print("Trying MIME type %s" % mime)
|
||||
parser = guess_parser_for_mime(mime, rawdata, verbose)
|
||||
if parser is None:
|
||||
continue
|
||||
if verbose:
|
||||
print("Found parser %s" % parser.menu_name)
|
||||
mime2 = guess_detail_for_mime(mime, rawdata, parser)
|
||||
if mime != mime2 and verbose:
|
||||
print("Signature match: %s" % mime2)
|
||||
break
|
||||
if parser is None:
|
||||
raise errors.UnsupportedDiskImage("Unknown disk image type")
|
||||
else:
|
||||
|
@ -223,6 +223,7 @@ class BaseAtariCartImage(DiskImageBase):
|
||||
# force the header to be the specified cart type
|
||||
self.header = A8CartHeader()
|
||||
self.header.set_type(self.cart_type)
|
||||
self.check_size()
|
||||
|
||||
def check_size(self):
|
||||
if not self.header.valid:
|
||||
@ -289,14 +290,14 @@ class AtariCartImage(BaseAtariCartImage):
|
||||
raise errors.InvalidDiskImage("Cart type doesn't match type defined in header")
|
||||
|
||||
|
||||
class Atari8bitCartImage(BaseAtariCartImage):
|
||||
class Atari8bitCartImage(AtariCartImage):
|
||||
def strict_check(self):
|
||||
if "5200" in self.header.cart_name:
|
||||
raise errors.InvalidDiskImage("5200 Carts don't work in the home computers.")
|
||||
AtariCartImage.strict_check(self)
|
||||
|
||||
|
||||
class Atari5200CartImage(BaseAtariCartImage):
|
||||
class Atari5200CartImage(AtariCartImage):
|
||||
def strict_check(self):
|
||||
if "5200" not in self.header.cart_name:
|
||||
raise errors.InvalidDiskImage("Home computer carts don't work in the 5200.")
|
||||
|
@ -1,3 +1,5 @@
|
||||
import hashlib
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .segments import SegmentData, DefaultSegment
|
||||
@ -12,6 +14,7 @@ from . import errors
|
||||
from .magic import guess_detail_for_mime
|
||||
from . import container
|
||||
from .dcm import DCMContainer
|
||||
from .signatures import sha1_signatures
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
@ -69,6 +72,7 @@ class SegmentParser:
|
||||
self.segments.append(self.container_segment(r, 0, name=self.menu_name))
|
||||
try:
|
||||
log.debug("Trying %s" % self.image_type)
|
||||
log.debug(self.image_type.__mro__)
|
||||
self.image = self.get_image(r)
|
||||
self.check_image()
|
||||
self.image.parse_segments()
|
||||
@ -85,6 +89,7 @@ class SegmentParser:
|
||||
s.reconstruct_raw(new_rawdata)
|
||||
|
||||
def get_image(self, r):
|
||||
log.info(f"checking image type {self.image_type}")
|
||||
return self.image_type(r)
|
||||
|
||||
def check_image(self):
|
||||
@ -142,15 +147,16 @@ class AtariCartSegmentParser(SegmentParser):
|
||||
cart_info = None
|
||||
|
||||
def get_image(self, r):
|
||||
log.info(f"checking cart type {self.cart_type}: {self.image_type}")
|
||||
return self.image_type(r, self.cart_type)
|
||||
|
||||
|
||||
class Atari8bitCartParser(SegmentParser):
|
||||
class Atari8bitCartParser(AtariCartSegmentParser):
|
||||
menu_name = "Atari Home Computer Cartridge"
|
||||
image_type = Atari8bitCartImage
|
||||
|
||||
|
||||
class Atari5200CartParser(SegmentParser):
|
||||
class Atari5200CartParser(AtariCartSegmentParser):
|
||||
menu_name = "Atari 5200 Cartridge"
|
||||
image_type = Atari5200CartImage
|
||||
|
||||
@ -203,6 +209,34 @@ def guess_container(r, verbose=False):
|
||||
return None
|
||||
|
||||
|
||||
def guess_parser_by_size(r, verbose=False):
|
||||
found = None
|
||||
mime = None
|
||||
size = len(r)
|
||||
if size in sha1_signatures:
|
||||
print(r)
|
||||
sha_hash = hashlib.sha1(r.data).hexdigest()
|
||||
log.info(f"{size} in signature database, attempting to match {sha_hash}")
|
||||
try:
|
||||
match = sha1_signatures[size][sha_hash]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
mime = match[0]
|
||||
log.info(f"found match: {match}")
|
||||
parsers = mime_parsers[mime]
|
||||
for parser in parsers:
|
||||
try:
|
||||
found = parser(r, False)
|
||||
break
|
||||
except errors.InvalidSegmentParser as e:
|
||||
if verbose:
|
||||
log.info("parser isn't %s: %s" % (parser.__name__, str(e)))
|
||||
pass
|
||||
if found is None:
|
||||
log.info(f"no matching signature")
|
||||
return mime, found
|
||||
|
||||
def guess_parser_for_mime(mime, r, verbose=False):
|
||||
parsers = mime_parsers[mime]
|
||||
found = None
|
||||
@ -231,12 +265,15 @@ def iter_parsers(r):
|
||||
container = guess_container(r.data)
|
||||
if container is not None:
|
||||
r = SegmentData(container.unpacked)
|
||||
for mime in mime_parse_order:
|
||||
p = guess_parser_for_mime(mime, r)
|
||||
if p is not None:
|
||||
mime = guess_detail_for_mime(mime, r, p)
|
||||
return mime, p
|
||||
return None, None
|
||||
mime, parser = guess_parser_by_size(r)
|
||||
if parser is None:
|
||||
for mime in mime_parse_order:
|
||||
p = guess_parser_for_mime(mime, r)
|
||||
if p is not None:
|
||||
parser = p
|
||||
mime = guess_detail_for_mime(mime, r, p)
|
||||
break
|
||||
return mime, parser
|
||||
|
||||
|
||||
def parsers_for_filename(name):
|
||||
@ -274,7 +311,7 @@ mime_parsers = {
|
||||
"application/vnd.atari8bit.cart": [
|
||||
Atari8bitCartParser,
|
||||
],
|
||||
"application/vnd.atari8bit.5200_cart": [
|
||||
"application/vnd.atari5200.cart": [
|
||||
Atari5200CartParser,
|
||||
],
|
||||
"application/vnd.mame_rom": [
|
||||
@ -296,7 +333,7 @@ mime_parse_order = [
|
||||
"application/vnd.atari8bit.atr",
|
||||
"application/vnd.atari8bit.xex",
|
||||
"application/vnd.atari8bit.cart",
|
||||
"application/vnd.atari8bit.5200_cart",
|
||||
"application/vnd.atari5200.cart",
|
||||
"application/vnd.mame_rom",
|
||||
"application/vnd.apple2.dsk",
|
||||
"application/vnd.apple2.bin",
|
||||
@ -307,7 +344,7 @@ pretty_mime = {
|
||||
"application/vnd.atari8bit.atr": "Atari 8-bit Disk Image",
|
||||
"application/vnd.atari8bit.xex": "Atari 8-bit Executable",
|
||||
"application/vnd.atari8bit.cart": "Atari 8-bit Cartridge",
|
||||
"application/vnd.atari8bit.5200_cart":"Atari 5200 Cartridge",
|
||||
"application/vnd.atari5200.cart": "Atari 5200 Cartridge",
|
||||
"application/vnd.mame_rom": "MAME",
|
||||
"application/vnd.rom": "ROM Image",
|
||||
"application/vnd.apple2.dsk": "Apple ][ Disk Image",
|
||||
@ -320,11 +357,12 @@ for k in sizes:
|
||||
for c in grouped_carts[k]:
|
||||
t = c[0]
|
||||
name = c[1]
|
||||
kclass = type("AtariCartSegmentParser%d" % t, (AtariCartSegmentParser,), {'cart_type': t, 'cart_info': c, 'menu_name': "%s Cartridge" % name})
|
||||
if "5200" in name:
|
||||
key = "application/vnd.atari8bit.5200_cart"
|
||||
key = "application/vnd.atari5200.cart"
|
||||
kclass = type("Atari5200CartSegmentParser%d" % t, (Atari5200CartParser, AtariCartSegmentParser), {'cart_type': t, 'cart_info': c, 'menu_name': "%s Cartridge" % name})
|
||||
else:
|
||||
key = "application/vnd.atari8bit.cart"
|
||||
kclass = type("Atari8bitCartSegmentParser%d" % t, (Atari8bitCartParser, AtariCartSegmentParser), {'cart_type': t, 'cart_info': c, 'menu_name': "%s Cartridge" % name})
|
||||
mime_parsers[key].append(kclass)
|
||||
|
||||
|
||||
|
122
atrcopy/signatures.py
Normal file
122
atrcopy/signatures.py
Normal file
@ -0,0 +1,122 @@
|
||||
sha1_signatures = {
|
||||
2048: {
|
||||
'6ad7a1e8c9fad486fbec9498cb48bf5bc3adc530': ('application/vnd.atari5200.cart', '[BIOS] Atari 5200 (USA)'),
|
||||
},
|
||||
4096: {
|
||||
'5236bc13e4b06d2e16d70b0a0c98588e1726da0c': ('application/vnd.atari5200.cart', 'Boogie (USA) (Demo)'),
|
||||
'a80f876a89a8ceacc71da5d9c02b546970b17730': ('application/vnd.atari5200.cart', 'Kaboom! (USA)'),
|
||||
'f5f9c7f97bf09e5647e808d892b656f3ee1e19e0': ('application/vnd.atari5200.cart', 'Super Breakout (USA)'),
|
||||
'e58e1f257923694dbeb586c860f385e74e460f90': ('application/vnd.atari5200.cart', 'Yellow Submarine (USA) (Demo)'),
|
||||
},
|
||||
8192: {
|
||||
'e64fb1a353c72b87c5483bb88cb3523ea5d37b59': ('application/vnd.atari5200.cart', '5200 Menu (USA) (Proto)'),
|
||||
'18697dd8e640fa1578b3b4ae09af484c14fb8410': ('application/vnd.atari5200.cart', 'Asteroids (USA) (Proto)'),
|
||||
'd3ff99e080985c9c8e25389dfa74835e8c9be508': ('application/vnd.atari5200.cart', "Atari PAM - Pete's Test (USA)"),
|
||||
'af81c400f1af0ee13a24da5e8b642442a0fc9479': ('application/vnd.atari5200.cart', 'Atari PAM System Test (USA) (v1.02)'),
|
||||
'ce9bd3b0847c5e187c3e8f667c8f5ea771c49965': ('application/vnd.atari5200.cart', "Carol Shaw's River Raid (USA)"),
|
||||
'ea7b40ce1106378e1d409cab6634fb2e483ff238': ('application/vnd.atari5200.cart', 'Dreadnaught Factor, The (USA)'),
|
||||
'd9a695757f0494aee92a50ab8a49558745e0cedf': ('application/vnd.atari5200.cart', 'Frogger (USA)'),
|
||||
'0df0d7f11d89e2c5b59cc9f98d67d98e203831aa': ('application/vnd.atari5200.cart', 'Galaxian (USA)'),
|
||||
'80926bb270ea66cb5cacc379de1fc16d8a3d814b': ('application/vnd.atari5200.cart', 'Gorf (USA)'),
|
||||
'c7eb2b4a46a197adfedf33c2ccc17d8424d681c4': ('application/vnd.atari5200.cart', 'K-Razy Shoot-Out (USA)'),
|
||||
'9f31c85a13e919135438590601e33bef11a8df8a': ('application/vnd.atari5200.cart', 'Keystone Kapers (USA)'),
|
||||
'f5512460c6b6d3a1baa0b23adf6a3a37fe308eb3': ('application/vnd.atari5200.cart', 'MegaMania (USA)'),
|
||||
'5c8ec22e131810ccac08066ca96e9944ccfa4ecb': ('application/vnd.atari5200.cart', 'Missile Command (USA)'),
|
||||
'2e7ae57260624d1f5710d445a0936f0c280a6655': ('application/vnd.atari5200.cart', 'Mountain King (USA)'),
|
||||
'002e6f8c7533b03f8041e7f1896589c0ab0e17a6': ('application/vnd.atari5200.cart', "Mr. Do!'s Castle (USA)"),
|
||||
'd1c7dc3de097a4bfab82235acec69a97e6e05f18': ('application/vnd.atari5200.cart', 'Pitfall! (USA)'),
|
||||
'e6966bde5cd4167020c9d21bab613af1648b4d75': ('application/vnd.atari5200.cart', 'Q-bert (USA)'),
|
||||
'cf411db770217b5af5fcfa32725cc587a8b9e710': ('application/vnd.atari5200.cart', 'Space Invaders (USA)'),
|
||||
'bf77048abc36ba2cba5eeeac812802d6a0eba891': ('application/vnd.atari5200.cart', 'Star Wars - Return of the Jedi - Death Star Battle (USA)'),
|
||||
'8205093f5fb1fdf0ccb71d667ea0a3849fb0a0f2': ('application/vnd.atari5200.cart', 'Super Cobra (USA)'),
|
||||
'55da563b4394508c23d866fb1e543262fb45536d': ('application/vnd.atari5200.cart', 'Zenji (USA)'),
|
||||
},
|
||||
16384: {
|
||||
'e18a603b18b85e24f9c938b33b6077a767c1fa9c': ('application/vnd.atari5200.cart', 'A.E. (USA) (Proto)'),
|
||||
'db203973df13b071da46d52fdb078a76f4db428d': ('application/vnd.atari5200.cart', 'Activision Decathlon, The (USA)'),
|
||||
'67e405c37e55dec4071018e8166ab4faf9f21df5': ('application/vnd.atari5200.cart', 'Astro Chase (USA)'),
|
||||
'5cc3b4245faf01c30f77ac20b0b4940f4f8f83d8': ('application/vnd.atari5200.cart', 'Atari PAM Diagnostics (USA) (v2.0)'),
|
||||
'e086e9868aa913e87f94676fd600f003892e73a1': ('application/vnd.atari5200.cart', 'Atari PAM Diagnostics (USA) (v2.3)'),
|
||||
'a339cddfc28477c21c58783d2d3b0cf0f4626ddf': ('application/vnd.atari5200.cart', 'Battlezone (USA) (Proto)'),
|
||||
'b75d555d059ad61992f9f5a234129ecbf9504c35': ('application/vnd.atari5200.cart', 'Beamrider (USA)'),
|
||||
'e56ccc6bf427a832ce00540b02d065a2688260dc': ('application/vnd.atari5200.cart', 'BerZerk (USA)'),
|
||||
'ab3130256d16af09cac8b11749dfaff6aaaa3ea3': ('application/vnd.atari5200.cart', 'Blaster (USA) (Proto)'),
|
||||
'1e1a20c104bf4d55eca0ca1e72dc5dc64fa6b1b5': ('application/vnd.atari5200.cart', 'Blue Print (USA)'),
|
||||
'bc7c81f758dd3e224e42ac8a16c1a12d69aed722': ('application/vnd.atari5200.cart', 'Buck Rogers - Planet of Zoom (USA)'),
|
||||
'eb343b90d3de696e69b1f039d4fb2c6afb0d80c0': ('application/vnd.atari5200.cart', 'Centipede (USA)'),
|
||||
'9f1ee191319ef0261cc7074a81c0e6d6b7464cd2': ('application/vnd.atari5200.cart', 'Choplifter! (USA)'),
|
||||
'e0203c2124127eba2d679be548fa257ecc5b2607': ('application/vnd.atari5200.cart', 'Congo Bongo (USA)'),
|
||||
'fa6d77e6e9afd0ea42fc9f9807932bf9e8fb170e': ('application/vnd.atari5200.cart', 'Countermeasure (USA)'),
|
||||
'b051f0fb2e816787ab6eed0cb008b9f8cc9963dc': ('application/vnd.atari5200.cart', "David Crane's Pitfall II - Lost Caverns (USA)"),
|
||||
'44f6dbf5013a70e646d5c5232981d517069fc449': ('application/vnd.atari5200.cart', 'Defender (USA)'),
|
||||
'387a76ba5912251e2285b7722004ad75e9ede523': ('application/vnd.atari5200.cart', 'Dig Dug (USA)'),
|
||||
'48625af4f3e9fe538dab2a0b463887fc8c6b138d': ('application/vnd.atari5200.cart', 'Final Legacy (USA) (Proto)'),
|
||||
'69dcc8f59ca449f13dc896b4b29b534762d97064': ('application/vnd.atari5200.cart', 'Frisky Tom (USA) (Proto)'),
|
||||
'3d815594cf674694b04bb0ff90bf635d7d402fc2': ('application/vnd.atari5200.cart', 'Frogger II - Threeedeep! (USA)'),
|
||||
'd0d8650eb07d1679004d491360c2c041e37c61cd': ('application/vnd.atari5200.cart', 'Gyruss (USA)'),
|
||||
'd286ecb6793a0dda9c9c68f6355dbe3ade6922f9': ('application/vnd.atari5200.cart', 'H.E.R.O. (USA)'),
|
||||
'ae765943ae8d909b6ca6ff1560ba027adeeaa515': ('application/vnd.atari5200.cart', 'James Bond 007 (USA)'),
|
||||
'0f74125edac90ffd1274a128df2970c239348fb5': ('application/vnd.atari5200.cart', 'Joust (USA)'),
|
||||
'a3e760d09e4dc6053286967576b5b7d42ee2fd38': ('application/vnd.atari5200.cart', 'Jr. Pac-Man (USA) (Proto)'),
|
||||
'fa02ee04cfad90c6ccf9d9b984e3b7b3327fec12': ('application/vnd.atari5200.cart', 'Jungle Hunt (USA)'),
|
||||
'c3dbeed7adc0e282bf76332ab5a3209550e26d02': ('application/vnd.atari5200.cart', 'Kangaroo (USA)'),
|
||||
'4046f60602254a7d86d2a6efd1a330455eaec119': ('application/vnd.atari5200.cart', 'Last Starfighter, The (USA) (Proto)'),
|
||||
'bc4a536616ac45689b3ad790f6b1394ebbd8cc7e': ('application/vnd.atari5200.cart', 'Looney Tunes Hotel (USA) (Proto)'),
|
||||
'32d86a381feff43149b66336dcc4ba2523273228': ('application/vnd.atari5200.cart', 'Meteorites (USA)'),
|
||||
'2f152a857a8a58d602b3c717612d9744423ee495': ('application/vnd.atari5200.cart', 'Microgammon SB (USA) (Proto)'),
|
||||
'1243a8ecfc02a74ae4e1f4fcda38502776f45cb0': ('application/vnd.atari5200.cart', 'Millipede (USA) (Proto)'),
|
||||
'0564b1867a0b570d66dfcbc11adc3e51a2c6f28c': ('application/vnd.atari5200.cart', 'Miner 2049er Starring Bounty Bob (USA)'),
|
||||
'ef4d3ee7b4da2ef79c6f4d0d1833f10c1eb7725e': ('application/vnd.atari5200.cart', 'Miniature Golf (USA) (Proto)'),
|
||||
'7e2a05625598c7e6615f969aa695e64315cd9846': ('application/vnd.atari5200.cart', "Montezuma's Revenge featuring Panama Joe (USA)"),
|
||||
'02dd5b9278c06ae8cbb6dacc094e238fbacf08d2': ('application/vnd.atari5200.cart', 'Moon Patrol (USA)'),
|
||||
'f93d72444d76075273e508555423936530875148': ('application/vnd.atari5200.cart', 'Ms. Pac-Man (USA)'),
|
||||
'ee4b3c6f08aa9fdfab532eec98136306b6923f75': ('application/vnd.atari5200.cart', 'Pac-Man (USA)'),
|
||||
'd504764c5894ee99c0b5e2024cbe833ebba3ab17': ('application/vnd.atari5200.cart', 'Pole Position (USA)'),
|
||||
'e615aaa0c1d56ac83b91f6087970fa708d6433bf': ('application/vnd.atari5200.cart', 'Popeye (USA)'),
|
||||
'786cdf54d1625e0d3ea8814506fdeeba5e4ece48': ('application/vnd.atari5200.cart', 'QIX (USA)'),
|
||||
'17a41c5f9a32f8a71939cfaa0e96807b951aedad': ('application/vnd.atari5200.cart', 'Quest for Quintana Roo (USA)'),
|
||||
'2b43f74db4833272d2048de8fa32b857af8e090f': ('application/vnd.atari5200.cart', 'RealSports Basketball (USA) (82-11-05) (Proto)'),
|
||||
'a0dbd654ed3ba2583ca175a1356924d9529884df': ('application/vnd.atari5200.cart', 'RealSports Football (USA)'),
|
||||
'c911cc914f3923d5aeb1a897e6dc4a551a9a53da': ('application/vnd.atari5200.cart', 'RealSports Soccer (USA)'),
|
||||
'2e6c7472e37926cdfd3d855a4bd37a18fa83d8cf': ('application/vnd.atari5200.cart', 'RealSports Tennis (USA)'),
|
||||
'0a7aaef5b0ede927cea13e724906207e1db48068': ('application/vnd.atari5200.cart', 'Road Runner (USA) (Proto)'),
|
||||
'9175e6daca58102ac8b9729d7b0336cf09977d12': ('application/vnd.atari5200.cart', 'Robotron 2084 (USA)'),
|
||||
'127ed1c31c3e85d10212eee7b9e6d71aef7dd891': ('application/vnd.atari5200.cart', 'Space Dungeon (USA)'),
|
||||
'5ae20e767d9819fe601f3b1ea6d4506ae2f2ceef': ('application/vnd.atari5200.cart', 'Space Shuttle - A Journey Into Space (USA)'),
|
||||
'5f0354d8792d652313e5a0fa5d395e091c801d97': ('application/vnd.atari5200.cart', 'Sport Goofy (USA) (Proto)'),
|
||||
'57dfc22c9805555f957ed51a2dc7bf35ad00c9d9': ('application/vnd.atari5200.cart', 'Star Raiders (USA)'),
|
||||
'19801454ab86f2a5cf691fcd577a71ad2b8dc7d5': ('application/vnd.atari5200.cart', 'Star Trek - Strategic Operations Simulator (USA)'),
|
||||
'ab676ffe054b23bdd43cee2498afefaabbf9355b': ('application/vnd.atari5200.cart', 'Star Wars - The Arcade Game (USA)'),
|
||||
'09d192a3598cdadfb61eceb430b3d5892e40962f': ('application/vnd.atari5200.cart', 'Stargate (USA) (Proto)'),
|
||||
'238cb448555d8bb5c96aa0354718411e8777c613': ('application/vnd.atari5200.cart', 'Super Pac-Man (USA) (Proto)'),
|
||||
'85fcea0a4d4d1f22437801c96229ba96e0f6b711': ('application/vnd.atari5200.cart', 'Tempest (USA) (Proto)'),
|
||||
'9dfbb5d8b77504c66ce3ac4382daf79820393dd8': ('application/vnd.atari5200.cart', 'Track and Field (USA) (Proto)'),
|
||||
'49debdf3c133fde9905d6d9137da5d8dff8d6283': ('application/vnd.atari5200.cart', 'Wizard of Wor (USA)'),
|
||||
'8b5512d3d2a952c99b9377919f0e06481161d81e': ('application/vnd.atari5200.cart', 'Xari Arena (USA) (Proto)'),
|
||||
'18315bec1e62102290feeb77fb290e1266cf5bfc': ('application/vnd.atari5200.cart', 'Zone Ranger (USA)'),
|
||||
},
|
||||
32768: {
|
||||
'1dfd9cb5eb608590c84e14376291f8c02fb1ab93': ('application/vnd.atari5200.cart', 'Ballblazer (USA)'),
|
||||
'510ccb20df2ecdbe7f8373de6a9fc11493e8c3f2': ('application/vnd.atari5200.cart', 'Barroom Baseball (USA) (Proto)'),
|
||||
'9b7ecd444b6239442ef1f54cd8e14c294c064da2': ('application/vnd.atari5200.cart', 'Black Belt (USA) (Proto)'),
|
||||
'c1a56a1fc51e09b1d8e93af40ddd7596847e6164': ('application/vnd.atari5200.cart', 'Castle Blast (USA) (Unl)'),
|
||||
'4e022e101d7346a0a8618018372740e7333b4a36': ('application/vnd.atari5200.cart', 'Castle Crisis (USA) (Unl)'),
|
||||
'f3c32b39580d589799dcead98bb206fbf3df0504': ('application/vnd.atari5200.cart', 'Gremlins (USA)'),
|
||||
'ca7d5d0871be19ca22d01019fd512b5836e3130a': ('application/vnd.atari5200.cart', 'Joust (USA) 32k'),
|
||||
'9547c56e2951e1b3a713b0b99d3edb43c9d3cdd8': ('application/vnd.atari5200.cart', 'Koffi - Yellow Kopter (USA) (Unl)'),
|
||||
'a293b6b06050e11029d97137f2b1b36059567273': ('application/vnd.atari5200.cart', 'Mario Bros. (USA)'),
|
||||
'ff0f1d9ed0ae45e3c81b252f3d0a335e03b0aa4b': ('application/vnd.atari5200.cart', 'Meebzork (USA) (Proto)'),
|
||||
'19ff7622dbbc2915e3e98d8d966340e7e893ff34': ('application/vnd.atari5200.cart', 'Pengo (USA)'),
|
||||
'a94d06739fa19453fa586a836eaacae11fe93989': ('application/vnd.atari5200.cart', 'RealSports Baseball (USA)'),
|
||||
'9b21ac7fec8d556585c6970231318ef1f501b2b5': ('application/vnd.atari5200.cart', 'RealSports Basketball (USA)'),
|
||||
'9edb066a37ca7657979952c946ab89be7926f4f8': ('application/vnd.atari5200.cart', 'RealSports Basketball (USA) (83-10-31) (Proto)'),
|
||||
'9253d7286cf87999474b37df242ba23b4358ef4a': ('application/vnd.atari5200.cart', 'Rescue on Fractalus! (USA)'),
|
||||
'688133761c462d6865bf673ed298b4d828120940': ('application/vnd.atari5200.cart', 'Spitfire (USA) (Proto)'),
|
||||
'6c633de50e6cc0c0c40061cd24e6f78f552a438f': ('application/vnd.atari5200.cart', 'Vanguard (USA)'),
|
||||
'c3cf33216dfa484309b923f21829d040486bc481': ('application/vnd.atari5200.cart', 'Xevious (USA) (Proto)'),
|
||||
'4a4c4a25c8ed1b0ae79ca22684d7d311a564a7b5': ('application/vnd.atari5200.cart', 'Zaxxon (USA)'),
|
||||
},
|
||||
40960: {
|
||||
'cfdd2f8dabb03d8784f336bb0c804270dc3a8a6c': ('application/vnd.atari5200.cart', 'Bounty Bob Strikes Back! (USA)'),
|
||||
},
|
||||
} # end sha1_signatures
|
47
gen-sha.py
Normal file
47
gen-sha.py
Normal file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
import hashlib
|
||||
from collections import defaultdict
|
||||
import pprint
|
||||
|
||||
def parse(filename, mime):
|
||||
data = open(filename, 'rb').read()
|
||||
h = hashlib.sha1(data).hexdigest()
|
||||
name = os.path.basename(os.path.splitext(filename)[0])
|
||||
return len(data), h, name
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
source = "atrcopy/signatures.py"
|
||||
try:
|
||||
with open(source, 'r') as fh:
|
||||
source_text = fh.read()
|
||||
except OSError:
|
||||
source_text = "sha1_signatures = {}"
|
||||
try:
|
||||
exec(source_text)
|
||||
except:
|
||||
raise
|
||||
print(sha1_signatures)
|
||||
mime = sys.argv[1]
|
||||
new_signatures = defaultdict(dict)
|
||||
new_signatures.update(sha1_signatures)
|
||||
for filename in sys.argv[2:]:
|
||||
print(f"parsing {filename}")
|
||||
size, hash_string, name = parse(filename, mime)
|
||||
print(f"{size} {hash_string} {mime} {name}")
|
||||
new_signatures[size][hash_string] = (mime, name)
|
||||
lines = []
|
||||
lines.append("sha1_signatures = {")
|
||||
for k,v in sorted(new_signatures.items()):
|
||||
lines.append(f"{k}: {{")
|
||||
for h,n in sorted(v.items(), key=lambda a:(a[1], a[0])):
|
||||
lines.append(f" '{h}': {n},")
|
||||
lines.append("},")
|
||||
lines.append("} # end sha1_signatures")
|
||||
|
||||
print("\n".join(lines))
|
||||
with open(source, 'w') as fh:
|
||||
fh.write("\n".join(lines))
|
Loading…
Reference in New Issue
Block a user