diff --git a/Analyser/Static/StaticAnalyser.cpp b/Analyser/Static/StaticAnalyser.cpp index 954e27f03..a08f5039e 100644 --- a/Analyser/Static/StaticAnalyser.cpp +++ b/Analyser/Static/StaticAnalyser.cpp @@ -79,20 +79,20 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform:: std::string extension = file_name.substr(final_dot + 1); std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); -#define Insert(list, class, platforms) \ - list.emplace_back(new Storage::class(file_name));\ +#define Insert(list, class, platforms, ...) \ + list.emplace_back(new Storage::class(__VA_ARGS__));\ potential_platforms |= platforms;\ TargetPlatform::TypeDistinguisher *distinguisher = dynamic_cast(list.back().get());\ if(distinguisher) potential_platforms &= distinguisher->target_platform_type(); -#define TryInsert(list, class, platforms) \ +#define TryInsert(list, class, platforms, ...) \ try {\ - Insert(list, class, platforms) \ + Insert(list, class, platforms, __VA_ARGS__) \ } catch(...) {} #define Format(ext, list, class, platforms) \ if(extension == ext) { \ - TryInsert(list, class, platforms) \ + TryInsert(list, class, platforms, file_name) \ } Format("80", result.tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // 80 @@ -129,17 +129,23 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform:: Format("nib", result.disks, Disk::DiskImageHolder, TargetPlatform::DiskII) // NIB Format("o", result.tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // O Format("p", result.tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // P - Format("po", result.disks, Disk::DiskImageHolder, TargetPlatform::DiskII) // PO + Format("po", result.disks, Disk::DiskImageHolder, TargetPlatform::DiskII) // PO (original Apple II kind) + + // PO (Apple IIgs kind) + if(extension == "po") { + TryInsert(result.disks, Disk::DiskImageHolder, TargetPlatform::AppleIIgs, file_name, Storage::Disk::MacintoshIMG::FixedType::GCR) + } + Format("p81", result.tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // P81 // PRG if(extension == "prg") { // try instantiating as a ROM; failing that accept as a tape try { - Insert(result.cartridges, Cartridge::PRG, TargetPlatform::Commodore) + Insert(result.cartridges, Cartridge::PRG, TargetPlatform::Commodore, file_name) } catch(...) { try { - Insert(result.tapes, Tape::PRG, TargetPlatform::Commodore) + Insert(result.tapes, Tape::PRG, TargetPlatform::Commodore, file_name) } catch(...) {} } } diff --git a/Machines/Apple/AppleIIgs/AppleIIgs.cpp b/Machines/Apple/AppleIIgs/AppleIIgs.cpp index 555567ce5..4c0442447 100644 --- a/Machines/Apple/AppleIIgs/AppleIIgs.cpp +++ b/Machines/Apple/AppleIIgs/AppleIIgs.cpp @@ -43,9 +43,10 @@ namespace IIgs { class ConcreteMachine: public Apple::IIgs::Machine, - public MachineTypes::TimedMachine, - public MachineTypes::ScanProducer, public MachineTypes::AudioProducer, + public MachineTypes::MediaTarget, + public MachineTypes::ScanProducer, + public MachineTypes::TimedMachine, public CPU::MOS6502Esque::BusHandler { public: @@ -117,6 +118,8 @@ class ConcreteMachine: // Sync up initial values. memory_.set_speed_register(speed_register_); + + insert_media(target.media); } void run_for(const Cycles cycles) override { @@ -150,6 +153,15 @@ class ConcreteMachine: return &speaker_; } + // MARK: MediaTarget. + bool insert_media(const Analyser::Static::Media &media) final { + if(!media.disks.empty()) { + drives_[0].set_disk(media.disks[0]); + } + return true; + } + + // MARK: BusHandler. forceinline Cycles perform_bus_operation(const CPU::WDC65816::BusOperation operation, const uint32_t address, uint8_t *const value) { const auto ®ion = MemoryMapRegion(memory_, address); static bool log = false; diff --git a/Storage/Disk/DiskImage/Formats/MacintoshIMG.cpp b/Storage/Disk/DiskImage/Formats/MacintoshIMG.cpp index f0f95807e..510638426 100644 --- a/Storage/Disk/DiskImage/Formats/MacintoshIMG.cpp +++ b/Storage/Disk/DiskImage/Formats/MacintoshIMG.cpp @@ -23,6 +23,16 @@ using namespace Storage::Disk; +MacintoshIMG::MacintoshIMG(const std::string &file_name, FixedType type) : + file_(file_name) { + + switch(type) { + case FixedType::GCR: + construct_raw_gcr(); + break; + } +} + MacintoshIMG::MacintoshIMG(const std::string &file_name) : file_(file_name) { @@ -35,24 +45,11 @@ MacintoshIMG::MacintoshIMG(const std::string &file_name) : // DiskCopy 4.2 format, so there's no ambiguity here. const auto name_length = file_.get8(); if(name_length == 0x4c || !name_length) { - is_diskCopy_file_ = false; - if(file_.stats().st_size != 819200 && file_.stats().st_size != 409600) - throw Error::InvalidFormat; - uint32_t magic_word = file_.get8(); if(!((name_length == 0x4c && magic_word == 0x4b) || (name_length == 0x00 && magic_word == 0x00))) throw Error::InvalidFormat; - file_.seek(0, SEEK_SET); - if(file_.stats().st_size == 819200) { - encoding_ = Encoding::GCR800; - format_ = 0x22; - data_ = file_.read(819200); - } else { - encoding_ = Encoding::GCR400; - format_ = 0x02; - data_ = file_.read(409600); - } + construct_raw_gcr(); } else { // DiskCopy 4.2 it is then: // @@ -123,6 +120,23 @@ MacintoshIMG::MacintoshIMG(const std::string &file_name) : } } +void MacintoshIMG::construct_raw_gcr() { + is_diskCopy_file_ = false; + if(file_.stats().st_size != 819200 && file_.stats().st_size != 409600) + throw Error::InvalidFormat; + + file_.seek(0, SEEK_SET); + if(file_.stats().st_size == 819200) { + encoding_ = Encoding::GCR800; + format_ = 0x22; + data_ = file_.read(819200); + } else { + encoding_ = Encoding::GCR400; + format_ = 0x02; + data_ = file_.read(409600); + } +} + uint32_t MacintoshIMG::checksum(const std::vector &data, size_t bytes_to_skip) { uint32_t result = 0; diff --git a/Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp b/Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp index 51d0cac63..3a2a3d521 100644 --- a/Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp +++ b/Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp @@ -25,12 +25,22 @@ namespace Disk { class MacintoshIMG: public DiskImage { public: /*! - Construct a @c DiskCopy42 containing content from the file with name @c file_name. + Construct a @c MacintoshIMG containing content from the file with name @c file_name. @throws Error::InvalidFormat if this file doesn't appear to be in Disk Copy 4.2 format. */ MacintoshIMG(const std::string &file_name); + enum class FixedType { + GCR + }; + /*! + Constructs a @c MacintoshIMG without attempting to autodetect whether this is a raw + image or a Disk Copy 4.2 image; if GCR is specified and the file size checks out then + it is accepted as a GCR image. + */ + MacintoshIMG(const std::string &file_name, FixedType type); + // implemented to satisfy @c Disk HeadPosition get_maximum_head_position() final; int get_head_count() final; @@ -56,6 +66,7 @@ class MacintoshIMG: public DiskImage { std::mutex buffer_mutex_; uint32_t checksum(const std::vector &, size_t bytes_to_skip = 0); + void construct_raw_gcr(); }; }