mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 01:31:42 +00:00
Merge pull request #431 from TomHarte/DiskIIRemap
Shuffles the Disk II ROM at load time into B.A.P. form.
This commit is contained in:
commit
86192b18d1
@ -13,9 +13,9 @@
|
|||||||
using namespace Apple;
|
using namespace Apple;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const uint8_t input_command = 0x1; // i.e. Q6
|
const uint8_t input_command = 0x4; // i.e. Q6
|
||||||
const uint8_t input_mode = 0x2; // i.e. Q7
|
const uint8_t input_mode = 0x8; // i.e. Q7
|
||||||
const uint8_t input_flux = 0x4;
|
const uint8_t input_flux = 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiskII::DiskII() :
|
DiskII::DiskII() :
|
||||||
@ -90,47 +90,24 @@ uint8_t DiskII::get_shift_register() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DiskII::run_for(const Cycles cycles) {
|
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;
|
if(is_sleeping()) return;
|
||||||
|
|
||||||
int integer_cycles = cycles.as_int();
|
int integer_cycles = cycles.as_int();
|
||||||
|
|
||||||
if(!controller_can_sleep_) {
|
if(!controller_can_sleep_) {
|
||||||
while(integer_cycles--) {
|
while(integer_cycles--) {
|
||||||
const int address =
|
const int address = (state_ & 0xf0) | inputs_ | ((shift_register_&0x80) >> 6);
|
||||||
(inputs_ << 2) |
|
|
||||||
((shift_register_&0x80) >> 6) |
|
|
||||||
((state_&0x2) >> 1) |
|
|
||||||
((state_&0x1) << 7) |
|
|
||||||
((state_&0x4) << 4) |
|
|
||||||
((state_&0x8) << 2);
|
|
||||||
inputs_ |= input_flux;
|
inputs_ |= input_flux;
|
||||||
|
state_ = state_machine_[static_cast<std::size_t>(address)];
|
||||||
const uint8_t update = state_machine_[static_cast<std::size_t>(address)];
|
switch(state_ & 0xf) {
|
||||||
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) {
|
|
||||||
case 0x0: shift_register_ = 0; break; // clear
|
case 0x0: shift_register_ = 0; break; // clear
|
||||||
case 0x9: shift_register_ = static_cast<uint8_t>(shift_register_ << 1); break; // shift left, bringing in a zero
|
case 0x9: shift_register_ = static_cast<uint8_t>(shift_register_ << 1); break; // shift left, bringing in a zero
|
||||||
case 0xd: shift_register_ = static_cast<uint8_t>((shift_register_ << 1) | 1); break; // shift left, bringing in a one
|
case 0xd: shift_register_ = static_cast<uint8_t>((shift_register_ << 1) | 1); break; // shift left, bringing in a one
|
||||||
case 0xb: shift_register_ = data_register_; break; // load
|
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);
|
shift_register_ = (shift_register_ >> 1) | (is_write_protected() ? 0x80 : 0x00);
|
||||||
break; // shift right, bringing in write protected status
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,8 +137,47 @@ bool DiskII::is_write_protected() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DiskII::set_state_machine(const std::vector<uint8_t> &state_machine) {
|
void DiskII::set_state_machine(const std::vector<uint8_t> &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<Storage::Disk::Disk> &disk, int drive) {
|
void DiskII::set_disk(const std::shared_ptr<Storage::Disk::Disk> &disk, int drive) {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "../../Storage/Disk/Disk.hpp"
|
#include "../../Storage/Disk/Disk.hpp"
|
||||||
#include "../../Storage/Disk/Drive.hpp"
|
#include "../../Storage/Disk/Drive.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ class DiskII:
|
|||||||
int stepper_position_ = 0;
|
int stepper_position_ = 0;
|
||||||
|
|
||||||
bool is_write_protected();
|
bool is_write_protected();
|
||||||
std::vector<uint8_t> state_machine_;
|
std::array<uint8_t, 256> state_machine_;
|
||||||
Storage::Disk::Drive drives_[2];
|
Storage::Disk::Drive drives_[2];
|
||||||
bool drive_is_sleeping_[2];
|
bool drive_is_sleeping_[2];
|
||||||
bool controller_can_sleep_ = false;
|
bool controller_can_sleep_ = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user