diff --git a/Machines/PCCompatible/DMA.hpp b/Machines/PCCompatible/DMA.hpp index 03f310647..c07e5a456 100644 --- a/Machines/PCCompatible/DMA.hpp +++ b/Machines/PCCompatible/DMA.hpp @@ -17,6 +17,8 @@ #include +//extern bool should_log; + namespace PCCompatible { enum class AccessResult { @@ -245,12 +247,19 @@ private: template class DMAPages { public: + int count = 0; + template void set_page(const uint8_t value) { pages_[page_for_index(index)] = value; if(index == 0x00) { log_.info().append("%02x", value); + +// if(value == 0x3c) { +// ++count; +// should_log |= count == 2; +// } } } diff --git a/Machines/PCCompatible/FloppyController.hpp b/Machines/PCCompatible/FloppyController.hpp index 546b21db1..39e304209 100644 --- a/Machines/PCCompatible/FloppyController.hpp +++ b/Machines/PCCompatible/FloppyController.hpp @@ -198,15 +198,12 @@ public: ); drive.raised_interrupt = true; - drive.status = - decoder_.target().drive | uint8_t(Intel::i8272::Status0::SeekEnded); + drive.status = decoder_.target().drive | uint8_t(Intel::i8272::Status0::SeekEnded); drive.ready = drive.has_disk(); pics_.pic[0].template apply_edge<6>(true); } break; case Command::SenseInterruptStatus: { - log_.info().append("Sense interrupt status"); - const auto interruptor = std::find_if( std::begin(drives_), std::end(drives_), @@ -216,12 +213,22 @@ public: ); if(interruptor != std::end(drives_)) { last_seeking_drive_ = interruptor - std::begin(drives_); - interruptor->raised_interrupt = false; - interruptor->status &= ~ 0xc0; } - status_.set_status0(drives_[last_seeking_drive_].status); - results_.serialise(status_, drives_[last_seeking_drive_].track); + auto &drive = drives_[last_seeking_drive_]; + log_.info().append( + "Sense interrupt status; picked drive %d with interrupt status %d", + last_seeking_drive_, + drive.raised_interrupt + ); + status_.set_status0(drive.status); + results_.serialise(status_, drive.track); + + // Clear cause-of-interrupt flags on that drive. + drive.raised_interrupt = false; + drive.status &= ~0xc0; + + // Possibly lower interrupt flag. const bool any_remaining_interrupts = std::accumulate( std::begin(drives_), std::end(drives_), @@ -312,18 +319,18 @@ private: mutable Log::Logger log_; void reset() { -// printf("FDC reset\n"); + log_.info().append("{Reset}"); decoder_.clear(); status_.reset(); // Necessary to pass GlaBIOS' POST test, but: why? // // Cf. INT_13_0_2 and the CMP AL, 11000000B following a CALL FDC_WAIT_SENSE. -// for(int c = 0; c < 4; c++) { -// drives_[c].raised_interrupt = true; -// drives_[c].status = uint8_t(Intel::i8272::Status0::BecameNotReady); -// } -// pics_.pic[0].template apply_edge<6>(true); + for(int c = 0; c < 4; c++) { + drives_[c].raised_interrupt = true; + drives_[c].status = uint8_t(Intel::i8272::Status0::BecameNotReady) | uint8_t(c); + } + pics_.pic[0].template apply_edge<6>(true); using MainStatus = Intel::i8272::MainStatus; status_.set(MainStatus::DataReady, true); diff --git a/Machines/PCCompatible/LinearMemory.hpp b/Machines/PCCompatible/LinearMemory.hpp index bd878d0f6..cd02d3856 100644 --- a/Machines/PCCompatible/LinearMemory.hpp +++ b/Machines/PCCompatible/LinearMemory.hpp @@ -24,6 +24,27 @@ namespace PCCompatible { // TODO: send writes to the ROM area off to nowhere. // TODO: support banked sections for EGA/VGA and possibly EMS purposes. +struct DummyValue { +public: + template + IntT &value() { + if constexpr (std::is_same_v) { + return dummies_.dummy32; + } else if constexpr (std::is_same_v) { + return dummies_.dummy16; + } else if constexpr (std::is_same_v) { + return dummies_.dummy8; + } + } + +private: + union { + uint32_t dummy32; + uint16_t dummy16; + uint8_t dummy8; + } dummies_; +}; + template struct LinearPool { static constexpr size_t MaxAddress = MaxAddressV; @@ -255,7 +276,7 @@ struct LinearMemory: public LinearPool<1 << uint32_t address, uint32_t ) { if(MaxAddress != (1 << 24) && (address & address_mask_) >= MaxAddress) { - return dummy(); + return dummy_.value(); } return *reinterpret_cast(&memory[address & address_mask_]); } @@ -266,14 +287,14 @@ struct LinearMemory: public LinearPool<1 << ) const { static_assert(!is_writeable(type)); if(MaxAddress != (1 << 24) && (address & address_mask_) >= MaxAddress) { - return dummy(); + return dummy_.value(); } return *reinterpret_cast(&memory[address & address_mask_]); } template void write_back() { - dummy() = IntT(~0); + dummy_.value() = IntT(~0); } template @@ -291,16 +312,7 @@ struct LinearMemory: public LinearPool<1 << private: uint32_t address_mask_; - union { - uint32_t dummy32; - uint16_t dummy16; - uint8_t dummy8; - } dummies_; - - template IntT &dummy(); - template<> uint32_t &dummy() { return dummies_.dummy32; } - template<> uint16_t &dummy() { return dummies_.dummy16; } - template<> uint8_t &dummy() { return dummies_.dummy8; } + static DummyValue dummy_; }; } diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index 6560a928f..034370b96 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -943,10 +943,13 @@ public: } // if(decoded_ip_ >= 0x7c00 && decoded_ip_ < 0x7c00 + 1024) { -// if(decoded_ip_ == 0x12d8) { +// if(decoded_ip_ == 0x21d0) { // should_log = true; // } + // Covers DISK_RESET. +// should_log = (decoded_ip_ >= 0x21d0 && decoded_ip_ < 0x221c); + if(should_log) { const auto next = to_string(decoded_, InstructionSet::x86::Model::i8086); static std::string previous;