diff --git a/Analyser/Static/AppleIIgs/Target.hpp b/Analyser/Static/AppleIIgs/Target.hpp index 0394312d4..a0eb988aa 100644 --- a/Analyser/Static/AppleIIgs/Target.hpp +++ b/Analyser/Static/AppleIIgs/Target.hpp @@ -29,7 +29,7 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl + namespace Apple { namespace Clock { @@ -21,32 +23,36 @@ namespace Clock { */ class ClockStorage { public: - ClockStorage() { - // TODO: this should persist, if possible, rather than - // being default initialised. - constexpr uint8_t default_data[] = { - 0xa8, 0x00, 0x00, 0x00, - 0xcc, 0x0a, 0xcc, 0x0a, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x63, 0x00, - 0x03, 0x88, 0x00, 0x4c - }; - memcpy(data_, default_data, sizeof(default_data)); - memset(&data_[sizeof(default_data)], 0xff, sizeof(data_) - sizeof(default_data)); - } + ClockStorage() {} /*! Advances the clock by 1 second. - The caller should also signal an interrupt. + The caller should also signal an interrupt if applicable. */ void update() { - for(int c = 0; c < 4; ++c) { + for(size_t c = 0; c < 4; ++c) { ++seconds_[c]; if(seconds_[c]) break; } } + /*! + Sets the current [P/B]RAM contents. + */ + template void set_data(const CollectionT &collection) { + set_data(collection.begin(), collection.end()); + } + + template void set_data(IteratorT begin, const IteratorT end) { + size_t c = 0; + while(begin != end && c < 256) { + data_[c] = *begin; + ++begin; + ++c; + } + } + protected: static constexpr uint16_t NoResult = 0x100; static constexpr uint16_t DidComplete = 0x101; @@ -92,7 +98,7 @@ class ClockStorage { case 0x30: // Either a register access or an extended instruction. if(command & 0x08) { - address_ = (command & 0x7) << 5; + address_ = unsigned((command & 0x7) << 5); phase_ = (command & 0x80) ? Phase::SecondAddressByteRead : Phase::SecondAddressByteWrite; return NoResult; } else { @@ -162,10 +168,10 @@ class ClockStorage { private: - uint8_t data_[256]; - uint8_t seconds_[4]; - uint8_t write_protect_; - int address_; + std::array data_{0xff}; + std::array seconds_{}; + uint8_t write_protect_ = 0; + unsigned int address_ = 0; static constexpr int SecondsBuffer = 0x100; static constexpr int RegisterTest = 0x200; @@ -257,7 +263,10 @@ class ParallelClock: public ClockStorage { // A no-op for now. } else { // Write to the RTC. Which in this implementation also sets up a future read. - data_ = uint8_t(perform(data_)); + const auto result = perform(data_); + if(result < 0x100) { + data_ = uint8_t(result); + } } // MAGIC! The transaction took 0 seconds. diff --git a/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp b/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp index 9dc5b56fb..9e56f0f74 100644 --- a/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp +++ b/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp @@ -82,7 +82,7 @@ template class AuxiliaryMemorySwitches { bool read_auxiliary_memory = false; bool write_auxiliary_memory = false; - bool internal_CX_rom = false; + bool internal_CX_rom = true; bool slot_C3_rom = false; bool internal_C8_rom = false; diff --git a/Machines/Apple/AppleIIgs/AppleIIgs.cpp b/Machines/Apple/AppleIIgs/AppleIIgs.cpp index e778457ca..68e315e01 100644 --- a/Machines/Apple/AppleIIgs/AppleIIgs.cpp +++ b/Machines/Apple/AppleIIgs/AppleIIgs.cpp @@ -38,11 +38,40 @@ #include #include +// +// HEAVY WARNING: THIS IS INCOMPLETE AND VERY PROVISIONAL. +// +// You'll notice lots of random bits of debugging code sitting around but commented out. +// Most of this will go when this machine is complete. Please look past the gross ugliness +// of this code's intermediate state if you are able. +// + namespace { constexpr int CLOCK_RATE = 14'318'180; -class MemManagerChecker { +// This is the first result that came up when searching for valid Apple IIgs BRAM states; +// I'm unclear on its provenance. +constexpr uint8_t default_bram[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0d, 0x06, 0x02, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x06, 0x06, 0x00, 0x05, 0x06, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x02, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x96, 0x57, 0x3c, +}; + +/*class MemManagerChecker { int handle_total_ = 0; bool dump_bank(const Apple::IIgs::MemoryMap &memory, const char *name, uint32_t address, bool print, uint32_t must_contain = 0xffffffff) { const auto handles = memory.regions[memory.region_map[0xe117]].read; @@ -149,7 +178,7 @@ class MemManagerChecker { return result; } -}; +};*/ } @@ -187,6 +216,7 @@ class ConcreteMachine: set_clock_rate(double(CLOCK_RATE)); speaker_.set_input_rate(float(CLOCK_RATE) / float(audio_divider)); + clock_.ClockStorage::set_data(std::begin(default_bram), std::end(default_bram)); using Target = Analyser::Static::AppleIIgs::Target; ROM::Name system; @@ -277,6 +307,11 @@ class ConcreteMachine: // std::srand(23); Memory::Fuzz(ram_); + // Prior to ROM03 there's no power-on bit. + if(target.model != Target::Model::ROM03) { + speed_register_ &= ~0x40; + } + // Sync up initial values. memory_.set_speed_register(speed_register_ ^ 0x80); @@ -348,6 +383,23 @@ class ConcreteMachine: static bool log = false; bool is_1Mhz = false; +// if(operation == CPU::WDC65816::BusOperation::ReadOpcode) { +// if(address == 0xfe00d5) { +// printf(""); +// } +// +// printf("%06x a:%04x x:%04x y:%04x s:%04x d:%04x b:%04x\n", +// address, +// m65816_.get_value_of_register(CPU::WDC65816::Register::A), +// m65816_.get_value_of_register(CPU::WDC65816::Register::X), +// m65816_.get_value_of_register(CPU::WDC65816::Register::Y), +//// m65816_.get_value_of_register(CPU::WDC65816::Register::Flags), +// m65816_.get_value_of_register(CPU::WDC65816::Register::StackPointer), +// m65816_.get_value_of_register(CPU::WDC65816::Register::Direct), +// m65816_.get_value_of_register(CPU::WDC65816::Register::DataBank) +// ); +// } + if(operation == CPU::WDC65816::BusOperation::ReadVector && !(memory_.get_shadow_register()&0x40)) { // I think vector pulls always go to ROM? // That's slightly implied in the documentation, and doing so makes GS/OS boot, so... @@ -936,9 +988,9 @@ class ConcreteMachine: // } if(operation == CPU::WDC65816::BusOperation::ReadOpcode) { - if(total > 482342960 && total < 482352960 && address == 0xe10000) { - printf("entry: %llu\n", static_cast(total)); - } +// if(total > 482342960 && total < 482352960 && address == 0xe10000) { +// printf("entry: %llu\n", static_cast(total)); +// } // log |= address == 0xfc144f; // log &= !((address < 0xfc144f) || (address >= 0xfc1490)); @@ -1147,3 +1199,4 @@ Machine *Machine::AppleIIgs(const Analyser::Static::Target *target, const ROMMac } Machine::~Machine() {} + diff --git a/Machines/Apple/AppleIIgs/MemoryMap.hpp b/Machines/Apple/AppleIIgs/MemoryMap.hpp index 59aee99d3..68f6400e0 100644 --- a/Machines/Apple/AppleIIgs/MemoryMap.hpp +++ b/Machines/Apple/AppleIIgs/MemoryMap.hpp @@ -241,7 +241,7 @@ class MemoryMap { friend AuxiliaryMemorySwitches; friend LanguageCardSwitches; - uint8_t shadow_register_ = 0x08; + uint8_t shadow_register_ = 0x00; uint8_t speed_register_ = 0x00; // MARK: - Memory banking. diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 4903055f3..bf9f06e9d 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -49,6 +49,15 @@ namespace { constexpr int CLOCK_RATE = 7833600; + +// Former default PRAM: +// +// 0xa8, 0x00, 0x00, 0x00, +// 0xcc, 0x0a, 0xcc, 0x0a, +// 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x02, 0x63, 0x00, +// 0x03, 0x88, 0x00, 0x4c + } namespace Apple {