From 3cac86deba2a87f2a3e0c2a8b7feaf7cc6087ab0 Mon Sep 17 00:00:00 2001 From: Rob McMullen Date: Thu, 25 Oct 2018 19:51:33 -0700 Subject: [PATCH] Added generic ROM image and set strict checking for Atari cart image types * to be directly recognized as an Atari cart, must have the CART 16-byte header --- atrcopy/cartridge.py | 55 ++++++++++++++++++++++++++++++++++++-------- atrcopy/parsers.py | 24 ++++++++++++++++++- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/atrcopy/cartridge.py b/atrcopy/cartridge.py index 70cba57..8d875ec 100644 --- a/atrcopy/cartridge.py +++ b/atrcopy/cartridge.py @@ -196,11 +196,7 @@ class A8CartHeader: self.possible_types.add(i) -class AtariCartImage(DiskImageBase): - def __init__(self, rawdata, cart_type, filename=""): - self.cart_type = cart_type - DiskImageBase.__init__(self, rawdata, filename) - +class BaseAtariCartImage(DiskImageBase): def __str__(self): return str(self.header) @@ -209,12 +205,10 @@ class AtariCartImage(DiskImageBase): try: self.header = A8CartHeader(data) except errors.InvalidCartHeader: - self.header = A8CartHeader() - self.header.set_type(self.cart_type) + raise errors.InvalidDiskImage("Missing cart header") def strict_check(self): - if self.header.cart_type != self.cart_type: - raise errors.InvalidDiskImage("Cart type doesn't match type defined in header") + raise NotImplementedError def relaxed_check(self): if self.header.cart_type != self.cart_type: @@ -259,6 +253,28 @@ class AtariCartImage(DiskImageBase): return segments +class AtariCartImage(BaseAtariCartImage): + def __init__(self, rawdata, cart_type, filename=""): + self.cart_type = cart_type + DiskImageBase.__init__(self, rawdata, filename) + + def strict_check(self): + if self.header.cart_type != self.cart_type: + raise errors.InvalidDiskImage("Cart type doesn't match type defined in header") + + +class Atari8bitCartImage(BaseAtariCartImage): + def strict_check(self): + if "5200" in self.header.cart_name: + raise errors.InvalidDiskImage("5200 Carts don't work in the home computers.") + + +class Atari5200CartImage(BaseAtariCartImage): + def strict_check(self): + if "5200" not in self.header.cart_name: + raise errors.InvalidDiskImage("Home computer carts don't work in the 5200.") + + def add_cart_header(bytes): header = A8CartHeader(create=True) header.check_size(len(bytes)) @@ -267,3 +283,24 @@ def add_cart_header(bytes): data[0:hlen] = header.to_array() data[hlen:] = bytes return data + + +class RomImage(DiskImageBase): + def __str__(self): + return f"{len(self.rawdata) // 1024}k ROM image" + + def read_header(self): + self.header = A8CartHeader() + + def strict_check(self): + self.check_size() + + def check_size(self): + size = len(self) + if (size & (size - 1)) != 0: + raise errors.InvalidDiskImage("ROM image not a power of 2") + + def parse_segments(self): + r = self.rawdata + s = ObjSegment(r, 0, 0, self.header.main_origin, name="Main Bank") + return [s] diff --git a/atrcopy/parsers.py b/atrcopy/parsers.py index 864f048..b51fb3d 100644 --- a/atrcopy/parsers.py +++ b/atrcopy/parsers.py @@ -4,7 +4,7 @@ from .segments import SegmentData, DefaultSegment from .kboot import KBootImage from .ataridos import AtariDosDiskImage, BootDiskImage, AtariDosFile, XexContainerSegment, AtariDiskImage from .spartados import SpartaDosDiskImage -from .cartridge import AtariCartImage, get_known_carts +from .cartridge import AtariCartImage, Atari8bitCartImage, Atari5200CartImage, get_known_carts, RomImage from .mame import MameZipImage from .dos33 import Dos33DiskImage, ProdosDiskImage, Dos33BinFile from .standard_delivery import StandardDeliveryImage @@ -139,6 +139,21 @@ class AtariCartSegmentParser(SegmentParser): return self.image_type(r, self.cart_type) +class Atari8bitCartParser(SegmentParser): + menu_name = "Atari Home Computer Cartridge" + image_type = Atari8bitCartImage + + +class Atari5200CartParser(SegmentParser): + menu_name = "Atari 5200 Cartridge" + image_type = Atari5200CartImage + + +class RomParser(SegmentParser): + menu_name = "ROM Image" + image_type = RomImage + + class MameZipParser(SegmentParser): menu_name = "MAME ROM Zipfile" image_type = MameZipImage @@ -251,12 +266,17 @@ mime_parsers = { XexSegmentParser, ], "application/vnd.atari8bit.cart": [ + Atari8bitCartParser, ], "application/vnd.atari8bit.5200_cart": [ + Atari5200CartParser, ], "application/vnd.mame_rom": [ MameZipParser, ], + "application/vnd.rom": [ + RomParser, + ], "application/vnd.apple2.dsk": [ Dos33SegmentParser, ProdosSegmentParser, @@ -274,6 +294,7 @@ mime_parse_order = [ "application/vnd.mame_rom", "application/vnd.apple2.dsk", "application/vnd.apple2.bin", + "application/vnd.rom", ] pretty_mime = { @@ -282,6 +303,7 @@ pretty_mime = { "application/vnd.atari8bit.cart": "Atari 8-bit Cartridge", "application/vnd.atari8bit.5200_cart":"Atari 5200 Cartridge", "application/vnd.mame_rom": "MAME", + "application/vnd.rom": "ROM Image", "application/vnd.apple2.dsk": "Apple ][ Disk Image", "application/vnd.apple2.bin": "Apple ][ Binary", }