diff --git a/Components/DiskII/DiskII.cpp b/Components/DiskII/DiskII.cpp index 64bc9c7fd..da897c36c 100644 --- a/Components/DiskII/DiskII.cpp +++ b/Components/DiskII/DiskII.cpp @@ -13,9 +13,9 @@ using namespace Apple; namespace { - const uint8_t input_command = 0x1; // i.e. Q6 - const uint8_t input_mode = 0x2; // i.e. Q7 - const uint8_t input_flux = 0x4; + const uint8_t input_command = 0x4; // i.e. Q6 + const uint8_t input_mode = 0x8; // i.e. Q7 + const uint8_t input_flux = 0x1; } DiskII::DiskII() : @@ -90,47 +90,24 @@ uint8_t DiskII::get_shift_register() { } void DiskII::run_for(const Cycles cycles) { -/* -... address the P6 ROM with an index byte built up as: -+-------+-------+-------+-------+-------+-------+-------+-------+ -| STATE | STATE | STATE | PULSE | Q7 | Q6 | SR | STATE | -| bit 0 | bit 2 | bit 3 | | | | MSB | bit 1 | -+-------+-------+-------+-------+-------+-------+-------+-------+ - 7 6 5 4 3 2 1 0 - -... - -The bytes in the P6 ROM has the high four bits reversed compared to the BAPD charts, so you will have to reverse them after fetching the byte. - -*/ if(is_sleeping()) return; int integer_cycles = cycles.as_int(); if(!controller_can_sleep_) { while(integer_cycles--) { - const int address = - (inputs_ << 2) | - ((shift_register_&0x80) >> 6) | - ((state_&0x2) >> 1) | - ((state_&0x1) << 7) | - ((state_&0x4) << 4) | - ((state_&0x8) << 2); + const int address = (state_ & 0xf0) | inputs_ | ((shift_register_&0x80) >> 6); inputs_ |= input_flux; - - const uint8_t update = state_machine_[static_cast(address)]; - state_ = update >> 4; - state_ = ((state_ & 0x8) ? 0x1 : 0x0) | ((state_ & 0x4) ? 0x2 : 0x0) | ((state_ & 0x2) ? 0x4 : 0x0) | ((state_ & 0x1) ? 0x8 : 0x0); - - uint8_t command = update & 0xf; - switch(command) { + state_ = state_machine_[static_cast(address)]; + switch(state_ & 0xf) { case 0x0: shift_register_ = 0; break; // clear case 0x9: shift_register_ = static_cast(shift_register_ << 1); break; // shift left, bringing in a zero case 0xd: shift_register_ = static_cast((shift_register_ << 1) | 1); break; // shift left, bringing in a one case 0xb: shift_register_ = data_register_; break; // load - case 0xa: + + case 0xa: // shift right, bringing in write protected status shift_register_ = (shift_register_ >> 1) | (is_write_protected() ? 0x80 : 0x00); - break; // shift right, bringing in write protected status + break; default: break; } @@ -160,8 +137,47 @@ bool DiskII::is_write_protected() { } void DiskII::set_state_machine(const std::vector &state_machine) { - state_machine_ = state_machine; - // TODO: shuffle ordering here? + /* + An unadulterated P6 ROM read returns values with an address formed as: + + state b0, state b2, state b3, pulse, Q7, Q6, shift, state b1 + + ... and has the top nibble reflected. Beneath Apple Pro-DOS uses a + different order and several of the online copies are reformatted + into that order. + + So the code below remaps into Beneath Apple Pro-DOS order if the + supplied state machine isn't already in that order. + */ + + if(state_machine[0] != 0x18) { + for(size_t source_address = 0; source_address < 256; ++source_address) { + // Remap into Beneath Apple Pro-DOS address form. + size_t destination_address = + ((source_address&0x80) ? 0x10 : 0x00) | + ((source_address&0x01) ? 0x20 : 0x00) | + ((source_address&0x40) ? 0x40 : 0x00) | + ((source_address&0x20) ? 0x80 : 0x00) | + ((source_address&0x10) ? 0x01 : 0x00) | + ((source_address&0x08) ? 0x08 : 0x00) | + ((source_address&0x04) ? 0x04 : 0x00) | + ((source_address&0x02) ? 0x02 : 0x00); + uint8_t source_value = state_machine[source_address]; + + // Remap into Beneath Apple Pro-DOS value form. + source_value = + ((source_value & 0x80) ? 0x10 : 0x0) | + ((source_value & 0x40) ? 0x20 : 0x0) | + ((source_value & 0x20) ? 0x40 : 0x0) | + ((source_value & 0x10) ? 0x80 : 0x0) | + (source_value & 0x0f); + + // Store. + state_machine_[destination_address] = source_value; + } + } else { + memcpy(&state_machine_[0], &state_machine[0], 128); + } } void DiskII::set_disk(const std::shared_ptr &disk, int drive) { diff --git a/Components/DiskII/DiskII.hpp b/Components/DiskII/DiskII.hpp index 95697e6b8..fd37e9353 100644 --- a/Components/DiskII/DiskII.hpp +++ b/Components/DiskII/DiskII.hpp @@ -15,6 +15,7 @@ #include "../../Storage/Disk/Disk.hpp" #include "../../Storage/Disk/Drive.hpp" +#include #include #include @@ -66,7 +67,7 @@ class DiskII: int stepper_position_ = 0; bool is_write_protected(); - std::vector state_machine_; + std::array state_machine_; Storage::Disk::Drive drives_[2]; bool drive_is_sleeping_[2]; bool controller_can_sleep_ = false;